From 4b6312a22d9fb377ad7f32357957baff38cdfb76 Mon Sep 17 00:00:00 2001 From: klazbaba Date: Tue, 29 Jun 2021 16:03:24 +0100 Subject: [PATCH 001/109] fixed issue with dateutils export --- src/agenda/index.js | 22 +++++++++++---------- src/agenda/reservation-list/index.js | 8 ++++---- src/agenda/reservation-list/reservation.js | 4 ++-- src/calendar-list/index.js | 6 +++--- src/calendar/day/index.js | 4 ++-- src/calendar/index.js | 8 ++++---- src/dateutils.js | 2 +- src/expandableCalendar/Context/Presenter.js | 4 ++-- src/expandableCalendar/agendaList.js | 4 ++-- src/expandableCalendar/index.js | 6 +++--- src/expandableCalendar/week.js | 6 +++--- 11 files changed, 38 insertions(+), 36 deletions(-) diff --git a/src/agenda/index.js b/src/agenda/index.js index d0347350d9..6bb4e6cf59 100644 --- a/src/agenda/index.js +++ b/src/agenda/index.js @@ -8,7 +8,7 @@ import {Text, View, Dimensions, Animated} from 'react-native'; import {extractComponentProps} from '../component-updater'; import {parseDate, xdateToData, toMarkingFormat} from '../interface'; -import dateutils from '../dateutils'; +import {weekDayNames, sameDate, sameMonth} from '../dateutils'; import {AGENDA_CALENDAR_KNOB} from '../testIDs'; import {VelocityTracker} from '../input'; import styleConstructor from './style'; @@ -93,7 +93,7 @@ export default class AgendaView extends Component { } componentDidUpdate(prevProps) { - if (this.props.selected && !dateutils.sameDate(parseDate(this.props.selected), parseDate(prevProps.selected))) { + if (this.props.selected && !sameDate(parseDate(this.props.selected), parseDate(prevProps.selected))) { this.setState({selectedDay: parseDate(this.props.selected)}); } else if (!prevProps.items) { this.loadReservations(this.props); @@ -276,7 +276,7 @@ export default class AgendaView extends Component { onDayChange = day => { const newDate = parseDate(day); - const withAnimation = dateutils.sameMonth(newDate, this.state.selectedDay); + const withAnimation = sameMonth(newDate, this.state.selectedDay); this.calendar.scrollToDay(day, this.calendarOffset(), withAnimation); this.setState({ @@ -329,11 +329,12 @@ export default class AgendaView extends Component { if (!hideKnob) { const knobView = renderKnob ? renderKnob() : ; - knob = !this.state.calendarScrollable || showClosingKnob ? ( - - (this.knob = c)}>{knobView} - - ) : null; + knob = + !this.state.calendarScrollable || showClosingKnob ? ( + + (this.knob = c)}>{knobView} + + ) : null; } return knob; } @@ -352,7 +353,7 @@ export default class AgendaView extends Component { render() { const {firstDay, hideKnob, style, testID} = this.props; - const weekDaysNames = dateutils.weekDayNames(firstDay); + const weekDaysNames = weekDayNames(firstDay); const agendaHeight = this.initialScrollPadPosition(); const weekdaysStyle = [ this.style.weekdays, @@ -398,7 +399,8 @@ export default class AgendaView extends Component { weekdaysStyle.push({height: HEADER_HEIGHT}); } - const openCalendarScrollPadPosition = !hideKnob && this.state.calendarScrollable && this.props.showClosingKnob ? agendaHeight + HEADER_HEIGHT : 0; + const openCalendarScrollPadPosition = + !hideKnob && this.state.calendarScrollable && this.props.showClosingKnob ? agendaHeight + HEADER_HEIGHT : 0; const shouldAllowDragging = !hideKnob && !this.state.calendarScrollable; const scrollPadPosition = (shouldAllowDragging ? HEADER_HEIGHT : openCalendarScrollPadPosition) - KNOB_HEIGHT; const scrollPadStyle = { diff --git a/src/agenda/reservation-list/index.js b/src/agenda/reservation-list/index.js index 253c69f904..cc1b55652f 100644 --- a/src/agenda/reservation-list/index.js +++ b/src/agenda/reservation-list/index.js @@ -6,7 +6,7 @@ import React, {Component} from 'react'; import {FlatList, ActivityIndicator, View} from 'react-native'; import {extractComponentProps} from '../../component-updater'; -import dateutils from '../../dateutils'; +import {sameDate} from '../../dateutils'; import {toMarkingFormat} from '../../interface'; import styleConstructor from './style'; import Reservation from './reservation'; @@ -72,7 +72,7 @@ class ReservationList extends Component { componentDidUpdate(prevProps) { if (prevProps !== this.props) { - if (!dateutils.sameDate(prevProps.topDay, this.props.topDay)) { + if (!sameDate(prevProps.topDay, this.props.topDay)) { this.setState( { reservations: [] @@ -94,7 +94,7 @@ class ReservationList extends Component { updateReservations(props) { const {selectedDay} = props; const reservations = this.getReservations(props); - if (this.list && !dateutils.sameDate(selectedDay, this.selectedDay)) { + if (this.list && !sameDate(selectedDay, this.selectedDay)) { let scrollPosition = 0; for (let i = 0; i < reservations.scrollPosition; i++) { scrollPosition += this.heights[i] || 0; @@ -191,7 +191,7 @@ class ReservationList extends Component { if (!row) return; const day = row.day; - const sameDate = dateutils.sameDate(day, this.selectedDay); + const sameDate = sameDate(day, this.selectedDay); if (!sameDate && this.scrollOver) { this.selectedDay = day.clone(); _.invoke(this.props, 'onDayChange', day.clone()); diff --git a/src/agenda/reservation-list/reservation.js b/src/agenda/reservation-list/reservation.js index b817794494..408141c01d 100644 --- a/src/agenda/reservation-list/reservation.js +++ b/src/agenda/reservation-list/reservation.js @@ -4,7 +4,7 @@ import XDate from 'xdate'; import React, {Component} from 'react'; import {View, Text} from 'react-native'; import {xdateToData} from '../../interface'; -import dateutils from '../../dateutils'; +import {isToday} from '../../dateutils'; import {RESERVATION_DATE} from '../../testIDs'; import styleConstructor from './style'; @@ -59,7 +59,7 @@ class Reservation extends Component { return this.props.renderDay(date ? xdateToData(date) : undefined, item); } - const today = dateutils.isToday(date) ? this.style.today : undefined; + const today = isToday(date) ? this.style.today : undefined; if (date) { return ( diff --git a/src/calendar-list/index.js b/src/calendar-list/index.js index 48fcc35a79..f0273144f6 100644 --- a/src/calendar-list/index.js +++ b/src/calendar-list/index.js @@ -7,7 +7,7 @@ import {FlatList, Platform, Dimensions, View} from 'react-native'; import {extractComponentProps} from '../component-updater'; import {xdateToData, parseDate} from '../interface'; -import dateutils from '../dateutils'; +import {page, sameDate} from '../dateutils'; import {STATIC_HEADER} from '../testIDs'; import styleConstructor from './style'; import Calendar from '../calendar'; @@ -147,10 +147,10 @@ class CalendarList extends Component { if (!horizontal) { let week = 0; - const days = dateutils.page(day, firstDay); + const days = page(day, firstDay); for (let i = 0; i < days.length; i++) { week = Math.floor(i / 7); - if (dateutils.sameDate(days[i], day)) { + if (sameDate(days[i], day)) { scrollAmount += 46 * week; break; } diff --git a/src/calendar/day/index.js b/src/calendar/day/index.js index bdb6019eca..824e79d4be 100644 --- a/src/calendar/day/index.js +++ b/src/calendar/day/index.js @@ -6,7 +6,7 @@ import memoize from 'memoize-one'; import React, {Component} from 'react'; import {shouldUpdate} from '../../component-updater'; -import dateutils from '../../dateutils'; +import {isToday as dateutils_isToday} from '../../dateutils'; import {xdateToData} from '../../interface'; import {SELECT_DATE_SLOT} from '../../testIDs'; import BasicDay from './basic'; @@ -91,7 +91,7 @@ export default class Day extends Component { render() { const {day, marking} = this.props; const date = xdateToData(day); - const isToday = dateutils.isToday(day); + const isToday = dateutils_isToday(day); const Component = this.getDayComponent(); const dayProps = _.omit(this.props, 'day'); const accessibilityLabel = this.getAccessibilityLabel(day, marking, isToday); diff --git a/src/calendar/index.js b/src/calendar/index.js index ee2501f7a1..b0ea3f246a 100644 --- a/src/calendar/index.js +++ b/src/calendar/index.js @@ -7,7 +7,7 @@ import React, {Component} from 'react'; import {View} from 'react-native'; import GestureRecognizer, {swipeDirections} from 'react-native-swipe-gestures'; -import dateutils from '../dateutils'; +import {page, isGTE, isLTE, sameMonth} from '../dateutils'; import {xdateToData, parseDate, toMarkingFormat} from '../interface'; import {getState} from '../day-state-manager'; // import shouldComponentUpdate from './updater'; @@ -111,7 +111,7 @@ class Calendar extends Component { const minDate = parseDate(this.props.minDate); const maxDate = parseDate(this.props.maxDate); - if (!(minDate && !dateutils.isGTE(day, minDate)) && !(maxDate && !dateutils.isLTE(day, maxDate))) { + if (!(minDate && !isGTE(day, minDate)) && !(maxDate && !isLTE(day, maxDate))) { const shouldUpdateMonth = disableMonthChange === undefined || !disableMonthChange; if (shouldUpdateMonth) { @@ -177,7 +177,7 @@ class Calendar extends Component { const {hideExtraDays, markedDates} = this.props; const dayProps = extractComponentProps(Day, this.props); - if (!dateutils.sameMonth(day, this.state.currentMonth) && hideExtraDays) { + if (!sameMonth(day, this.state.currentMonth) && hideExtraDays) { return ; } @@ -217,7 +217,7 @@ class Calendar extends Component { const {currentMonth} = this.state; const {firstDay, showSixWeeks, hideExtraDays} = this.props; const shouldShowSixWeeks = showSixWeeks && !hideExtraDays; - const days = dateutils.page(currentMonth, firstDay, shouldShowSixWeeks); + const days = page(currentMonth, firstDay, shouldShowSixWeeks); const weeks = []; while (days.length) { diff --git a/src/dateutils.js b/src/dateutils.js index 245534745b..19893dd103 100644 --- a/src/dateutils.js +++ b/src/dateutils.js @@ -142,7 +142,7 @@ function getWeekDates(date, firstDay, format) { } } -module.exports = { +export { weekDayNames, sameMonth, sameWeek, diff --git a/src/expandableCalendar/Context/Presenter.js b/src/expandableCalendar/Context/Presenter.js index e293e8a488..2a09f0977b 100644 --- a/src/expandableCalendar/Context/Presenter.js +++ b/src/expandableCalendar/Context/Presenter.js @@ -1,6 +1,6 @@ import _ from 'lodash'; import XDate from 'xdate'; -import dateutils from '../../dateutils'; +import {sameMonth as dateutils_sameMonth} from '../../dateutils'; import {xdateToData, toMarkingFormat} from '../../interface'; const commons = require('../commons'); @@ -44,7 +44,7 @@ class Presenter { }; setDate = (props, date, newDate, updateState, updateSource) => { - const sameMonth = dateutils.sameMonth(XDate(date), XDate(newDate)); + const sameMonth = dateutils_sameMonth(XDate(date), XDate(newDate)); const buttonIcon = this.getButtonIcon(date, props.showTodayButton); updateState(buttonIcon); diff --git a/src/expandableCalendar/agendaList.js b/src/expandableCalendar/agendaList.js index e80de7698a..e554e8d68d 100644 --- a/src/expandableCalendar/agendaList.js +++ b/src/expandableCalendar/agendaList.js @@ -3,7 +3,7 @@ import React, {Component} from 'react'; import {SectionList, Text} from 'react-native'; import PropTypes from 'prop-types'; import XDate from 'xdate'; -import dateutils from '../dateutils'; +import {isToday as dateutils_isToday} from '../dateutils'; import styleConstructor from './style'; import asCalendarConsumer from './asCalendarConsumer'; import {getMoment} from '../momentResolver'; @@ -109,7 +109,7 @@ class AgendaList extends Component { if (markToday) { const todayString = XDate.locales[XDate.defaultLocale].today || commons.todayString; - const isToday = dateutils.isToday(XDate(title)); + const isToday = dateutils_isToday(XDate(title)); sectionTitle = isToday ? `${todayString}, ${sectionTitle}` : sectionTitle; } diff --git a/src/expandableCalendar/index.js b/src/expandableCalendar/index.js index 54f53e2a59..328a3859d0 100644 --- a/src/expandableCalendar/index.js +++ b/src/expandableCalendar/index.js @@ -7,7 +7,7 @@ import React, {Component} from 'react'; import {AccessibilityInfo, PanResponder, Animated, View, Text, Image} from 'react-native'; import {CALENDAR_KNOB} from '../testIDs'; -import dateutils from '../dateutils'; +import {page, weekDayNames} from '../dateutils'; import {parseDate, toMarkingFormat} from '../interface'; import styleConstructor, {HEADER_HEIGHT} from './style'; import CalendarList from '../calendar-list'; @@ -207,7 +207,7 @@ class ExpandableCalendar extends Component { } getNumberOfWeeksInMonth(month) { - const days = dateutils.page(month, this.props.firstDay); + const days = page(month, this.props.firstDay); return days.length / 7; } @@ -406,7 +406,7 @@ class ExpandableCalendar extends Component { renderHeader() { const monthYear = XDate(this.props.context.date).toString('MMMM yyyy'); - const weekDaysNames = dateutils.weekDayNames(this.props.firstDay); + const weekDaysNames = weekDayNames(this.props.firstDay); return ( ; } } From b2c2275183bc0239ef4e1e11be053129e7d7da51 Mon Sep 17 00:00:00 2001 From: klazbaba Date: Wed, 30 Jun 2021 10:35:02 +0100 Subject: [PATCH 002/109] switched to using esmodule export in day-state-manager.js --- src/day-state-manager.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/day-state-manager.js b/src/day-state-manager.js index 97df58f3ab..9fb7abb581 100644 --- a/src/day-state-manager.js +++ b/src/day-state-manager.js @@ -23,6 +23,4 @@ function getState(day, current, props) { return state; } -module.exports = { - getState -}; +export {getState}; From be7b6ae0eadbe90c06ab90eb8c2ea973a1265e04 Mon Sep 17 00:00:00 2001 From: Moe Kanan Date: Thu, 1 Jul 2021 14:11:55 -0500 Subject: [PATCH 003/109] change import to require --- src/dateutils.js | 2 +- src/day-state-manager.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/dateutils.js b/src/dateutils.js index 245534745b..edc1fb1d14 100644 --- a/src/dateutils.js +++ b/src/dateutils.js @@ -1,5 +1,5 @@ const XDate = require('xdate'); -import {parseDate} from './interface'; +const {parseDate} = require('./interface'); function sameMonth(a, b) { return ( diff --git a/src/day-state-manager.js b/src/day-state-manager.js index 97df58f3ab..86676692cb 100644 --- a/src/day-state-manager.js +++ b/src/day-state-manager.js @@ -1,5 +1,5 @@ -import {isToday, isDateNotInTheRange, sameMonth} from './dateutils'; -import {parseDate, toMarkingFormat} from './interface'; +const {isToday, isDateNotInTheRange, sameMonth} = require('./dateutils'); +const {parseDate, toMarkingFormat} = require('./interface'); function getState(day, current, props) { const {minDate, maxDate, disabledByDefault, context} = props; From da5c2944b3e0ce697cbe80a1744652a2403dd29b Mon Sep 17 00:00:00 2001 From: Mendy Date: Mon, 5 Jul 2021 10:32:09 +0300 Subject: [PATCH 004/109] style.js -> style.ts --- src/calendar-list/{style.js => style.ts} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/calendar-list/{style.js => style.ts} (100%) diff --git a/src/calendar-list/style.js b/src/calendar-list/style.ts similarity index 100% rename from src/calendar-list/style.js rename to src/calendar-list/style.ts From ccf657daaa0c528661c22740c79e53e43f039f12 Mon Sep 17 00:00:00 2001 From: Mendy Date: Mon, 5 Jul 2021 10:32:44 +0300 Subject: [PATCH 005/109] item.js -> item.tsx --- src/calendar-list/{item.js => item.tsx} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/calendar-list/{item.js => item.tsx} (100%) diff --git a/src/calendar-list/item.js b/src/calendar-list/item.tsx similarity index 100% rename from src/calendar-list/item.js rename to src/calendar-list/item.tsx From 50a4895b5e6c8ff60f2c24b51017296df2c626e0 Mon Sep 17 00:00:00 2001 From: Mendy Date: Mon, 5 Jul 2021 11:37:41 +0300 Subject: [PATCH 006/109] migrate item to typescript --- src/calendar-list/item.tsx | 40 +++++++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/src/calendar-list/item.tsx b/src/calendar-list/item.tsx index 61781bf90f..d1addff4b8 100644 --- a/src/calendar-list/item.tsx +++ b/src/calendar-list/item.tsx @@ -1,43 +1,51 @@ -import PropTypes from 'prop-types'; import memoize from 'memoize-one'; - import React, {Component} from 'react'; import {Text, View} from 'react-native'; +// @ts-expect-error import {extractComponentProps} from '../component-updater'; -import Calendar from '../calendar'; + +// @ts-expect-error +import Calendar, {CalendarProps} from '../calendar'; import styleConstructor from './style'; -class CalendarListItem extends Component { - static displayName = 'IGNORE'; +export type CalendarListProps = CalendarProps & { + item: any; + calendarWidth: number; + calendarHeight: number; + horizontal: boolean; + theme: any; +} - static propTypes = { - ...Calendar.propTypes, - item: PropTypes.any, - calendarWidth: PropTypes.number, - calendarHeight: PropTypes.number, - horizontal: PropTypes.bool - }; +type CalendarListState = { + hideArrows: boolean; + hideExtraDays: boolean; +} + +class CalendarListItem extends Component { + static displayName = 'IGNORE'; static defaultProps = { hideArrows: true, hideExtraDays: true }; - constructor(props) { + style: any; + + constructor(props: CalendarListProps) { super(props); this.style = styleConstructor(props.theme); } - shouldComponentUpdate(nextProps) { + shouldComponentUpdate(nextProps: CalendarListProps) { const r1 = this.props.item; const r2 = nextProps.item; return r1.toString('yyyy MM') !== r2.toString('yyyy MM') || !!(r2.propbump && r2.propbump !== r1.propbump); } - onPressArrowLeft = (_, month) => { + onPressArrowLeft = (_: any, month: any) => { const {onPressArrowLeft, scrollToMonth} = this.props; const monthClone = month.clone(); @@ -56,7 +64,7 @@ class CalendarListItem extends Component { } }; - onPressArrowRight = (_, month) => { + onPressArrowRight = (_: any, month: any) => { const {onPressArrowRight, scrollToMonth} = this.props; const monthClone = month.clone(); From 5a3fa0f9e08a483a3ced156a30f663c1fb31b44b Mon Sep 17 00:00:00 2001 From: Mendy Date: Mon, 5 Jul 2021 11:37:57 +0300 Subject: [PATCH 007/109] fix typescript error in style --- src/calendar-list/style.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/calendar-list/style.ts b/src/calendar-list/style.ts index 2fce57bb3f..a0b354c949 100644 --- a/src/calendar-list/style.ts +++ b/src/calendar-list/style.ts @@ -1,9 +1,10 @@ import {Platform, StyleSheet} from 'react-native'; +// @ts-expect-error import * as defaultStyle from '../style'; const STYLESHEET_ID = 'stylesheet.calendar-list.main'; -export default function getStyle(theme = {}) { +export default function getStyle(theme: any = {}) { const appStyle = {...defaultStyle, ...theme}; return StyleSheet.create({ flatListContainer: { From c8ffec640c5384c5ab30180535aadeee85989bcb Mon Sep 17 00:00:00 2001 From: Mendy Date: Mon, 5 Jul 2021 11:39:55 +0300 Subject: [PATCH 008/109] index.js -> index.tsx --- src/calendar-list/{index.js => index.tsx} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/calendar-list/{index.js => index.tsx} (100%) diff --git a/src/calendar-list/index.js b/src/calendar-list/index.tsx similarity index 100% rename from src/calendar-list/index.js rename to src/calendar-list/index.tsx From 96427cdaf275cbcb65a69de8bd96015a232580cb Mon Sep 17 00:00:00 2001 From: Mendy Date: Mon, 5 Jul 2021 11:41:03 +0300 Subject: [PATCH 009/109] naming --- src/calendar-list/item.tsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/calendar-list/item.tsx b/src/calendar-list/item.tsx index d1addff4b8..1a00fc7e36 100644 --- a/src/calendar-list/item.tsx +++ b/src/calendar-list/item.tsx @@ -9,7 +9,7 @@ import {extractComponentProps} from '../component-updater'; import Calendar, {CalendarProps} from '../calendar'; import styleConstructor from './style'; -export type CalendarListProps = CalendarProps & { +export type CalendarListItemProps = CalendarProps & { item: any; calendarWidth: number; calendarHeight: number; @@ -17,12 +17,12 @@ export type CalendarListProps = CalendarProps & { theme: any; } -type CalendarListState = { +type CalendarListItemState = { hideArrows: boolean; hideExtraDays: boolean; } -class CalendarListItem extends Component { +class CalendarListItem extends Component { static displayName = 'IGNORE'; static defaultProps = { @@ -32,13 +32,13 @@ class CalendarListItem extends Component { style: any; - constructor(props: CalendarListProps) { + constructor(props: CalendarListItemProps) { super(props); this.style = styleConstructor(props.theme); } - shouldComponentUpdate(nextProps: CalendarListProps) { + shouldComponentUpdate(nextProps: CalendarListItemProps) { const r1 = this.props.item; const r2 = nextProps.item; From 758fbd959635301e0a78add1259420f85c32ffad Mon Sep 17 00:00:00 2001 From: Lidor Dafna Date: Mon, 5 Jul 2021 12:19:25 +0300 Subject: [PATCH 010/109] rename --- src/calendar/day/dot/{index.js => index.tsx} | 0 src/calendar/day/dot/{style.js => style.ts} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename src/calendar/day/dot/{index.js => index.tsx} (100%) rename src/calendar/day/dot/{style.js => style.ts} (100%) diff --git a/src/calendar/day/dot/index.js b/src/calendar/day/dot/index.tsx similarity index 100% rename from src/calendar/day/dot/index.js rename to src/calendar/day/dot/index.tsx diff --git a/src/calendar/day/dot/style.js b/src/calendar/day/dot/style.ts similarity index 100% rename from src/calendar/day/dot/style.js rename to src/calendar/day/dot/style.ts From 64a5c5fd98c3ad5304d22f6c7ca3e803aad1d11e Mon Sep 17 00:00:00 2001 From: Lidor Dafna Date: Mon, 5 Jul 2021 12:33:10 +0300 Subject: [PATCH 011/109] migrate to TS --- src/calendar/day/dot/index.tsx | 25 ++++++++++++------------- src/calendar/day/dot/style.ts | 3 ++- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/calendar/day/dot/index.tsx b/src/calendar/day/dot/index.tsx index 627db933a2..114ac3538d 100644 --- a/src/calendar/day/dot/index.tsx +++ b/src/calendar/day/dot/index.tsx @@ -1,9 +1,17 @@ -import PropTypes from 'prop-types'; import React from 'react'; import {View} from 'react-native'; import styleConstructor from './style'; -const Dot = ({theme, marked, disabled, color, today, selected}) => { +interface DotProps { + theme: Object; + color: String; + marked: Boolean; + selected: Boolean; + disabled: Boolean; + today: Boolean; +} + +const Dot = ({theme, marked, disabled, color, today, selected}: DotProps) => { const style = styleConstructor(theme); const dotStyle = [style.dot]; @@ -26,17 +34,8 @@ const Dot = ({theme, marked, disabled, color, today, selected}) => { dotStyle.push({backgroundColor: color}); } } - - return ; + + return ; }; export default Dot; - -Dot.propTypes = { - theme: PropTypes.object, - color: PropTypes.string, - marked: PropTypes.bool, - selected: PropTypes.bool, - disabled: PropTypes.bool, - today: PropTypes.bool -}; diff --git a/src/calendar/day/dot/style.ts b/src/calendar/day/dot/style.ts index b9d833e3ef..c763926eef 100644 --- a/src/calendar/day/dot/style.ts +++ b/src/calendar/day/dot/style.ts @@ -1,9 +1,10 @@ import {StyleSheet} from 'react-native'; +// @ts-expect-error import * as defaultStyle from '../../../style'; const STYLESHEET_ID = 'stylesheet.dot'; -export default function styleConstructor(theme = {}) { +export default function styleConstructor(theme: any = {}) { const appStyle = {...defaultStyle, ...theme}; return StyleSheet.create({ dot: { From d1f9d342c8aca6fda6b82bd36b86d686979d3f3e Mon Sep 17 00:00:00 2001 From: Lidor Dafna Date: Mon, 5 Jul 2021 14:29:00 +0300 Subject: [PATCH 012/109] rename files --- src/calendar/day/marking/{index.js => index.tsx} | 0 src/calendar/day/marking/{style.js => style.ts} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename src/calendar/day/marking/{index.js => index.tsx} (100%) rename src/calendar/day/marking/{style.js => style.ts} (100%) diff --git a/src/calendar/day/marking/index.js b/src/calendar/day/marking/index.tsx similarity index 100% rename from src/calendar/day/marking/index.js rename to src/calendar/day/marking/index.tsx diff --git a/src/calendar/day/marking/style.js b/src/calendar/day/marking/style.ts similarity index 100% rename from src/calendar/day/marking/style.js rename to src/calendar/day/marking/style.ts From 8dd72533c1f4cfc7bbbfafcecdcfaf08f4645df5 Mon Sep 17 00:00:00 2001 From: Mendy Date: Mon, 5 Jul 2021 15:05:34 +0300 Subject: [PATCH 013/109] XDate typings --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 3d115e3093..a6deecd906 100644 --- a/package.json +++ b/package.json @@ -42,6 +42,7 @@ "@babel/runtime": "^7.12.5", "@types/lodash": "^4.14.170", "@types/react-native": "^0.63.52", + "@types/xdate": "^0.8.32", "@welldone-software/why-did-you-render": "^6.0.3", "babel-eslint": "^10.1.0", "babel-jest": "^26.6.3", From 15acc61ccdfa932e308299500c4757cdc60eff22 Mon Sep 17 00:00:00 2001 From: Mendy Date: Mon, 5 Jul 2021 15:09:44 +0300 Subject: [PATCH 014/109] migrate calendar-list to typescript --- src/calendar-list/index.tsx | 161 ++++++++++++++++++++---------------- 1 file changed, 90 insertions(+), 71 deletions(-) diff --git a/src/calendar-list/index.tsx b/src/calendar-list/index.tsx index 48fcc35a79..eefbcb1d50 100644 --- a/src/calendar-list/index.tsx +++ b/src/calendar-list/index.tsx @@ -1,21 +1,70 @@ import _ from 'lodash'; -import PropTypes from 'prop-types'; import XDate from 'xdate'; import React, {Component} from 'react'; import {FlatList, Platform, Dimensions, View} from 'react-native'; - +// @ts-expect-error import {extractComponentProps} from '../component-updater'; +// @ts-expect-error import {xdateToData, parseDate} from '../interface'; +// @ts-expect-error import dateutils from '../dateutils'; +// @ts-expect-error import {STATIC_HEADER} from '../testIDs'; import styleConstructor from './style'; -import Calendar from '../calendar'; + +// @ts-expect-error +import {CalendarProps} from '../calendar'; import CalendarListItem from './item'; +// @ts-expect-error import CalendarHeader from '../calendar/header/index'; const {width} = Dimensions.get('window'); +export type CalendarListProps = CalendarProps & { + /** Max amount of months allowed to scroll to the past. Default = 50 */ + pastScrollRange: number; + /** Max amount of months allowed to scroll to the future. Default = 50 */ + futureScrollRange: number; + /** Used when calendar scroll is horizontal, default is device width, pagination should be disabled */ + calendarWidth: number; + /** Dynamic calendar height */ + calendarHeight: number; + /** Style for the List item (the calendar) */ + calendarStyle: number | Array | Object; + /** Whether to use static header that will not scroll with the list (horizontal only) */ + staticHeader: boolean; + /** Enable or disable vertical / horizontal scroll indicator. Default = false */ + showScrollIndicator: boolean; + /** Whether to animate the auto month scroll */ + animateScroll: boolean; + /** Enable or disable scrolling of calendar list */ + scrollEnabled: boolean; + /** When true, the calendar list scrolls to top when the status bar is tapped. Default = true */ + scrollsToTop: boolean; + /** Enable or disable paging on scroll */ + pagingEnabled: boolean; + /** Whether the scroll is horizontal */ + horizontal: boolean; + /** Should Keyboard persist taps */ + keyboardShouldPersistTaps: 'never' | 'always' | 'handled'; + /** A custom key extractor for the generated calendar months */ + keyExtractor: (item: any, index: number) => string; + /** How far from the end to trigger the onEndReached callback */ + onEndReachedThreshold: number; + /** Called once when the scroll position gets within onEndReachedThreshold */ + onEndReached: () => void; +}; + +type XDateAndBump = XDate & {propBump?: number} ; + +type CalendarListState = { + rows: Array; + texts: Array; + openDate: XDate; + currentMonth: XDate; +} + /** * @description: Calendar List component for both vertical and horizontal calendars * @extends: Calendar @@ -23,45 +72,9 @@ const {width} = Dimensions.get('window'); * @example: https://github.com/wix/react-native-calendars/blob/master/example/src/screens/calendarsList.js * @gif: https://github.com/wix/react-native-calendars/blob/master/demo/calendar-list.gif */ -class CalendarList extends Component { +class CalendarList extends Component { static displayName = 'CalendarList'; - static propTypes = { - ...Calendar.propTypes, - /** Max amount of months allowed to scroll to the past. Default = 50 */ - pastScrollRange: PropTypes.number, - /** Max amount of months allowed to scroll to the future. Default = 50 */ - futureScrollRange: PropTypes.number, - /** Used when calendar scroll is horizontal, default is device width, pagination should be disabled */ - calendarWidth: PropTypes.number, - /** Dynamic calendar height */ - calendarHeight: PropTypes.number, - /** Style for the List item (the calendar) */ - calendarStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.number, PropTypes.array]), - /** Whether to use static header that will not scroll with the list (horizontal only) */ - staticHeader: PropTypes.bool, - /** Enable or disable vertical / horizontal scroll indicator. Default = false */ - showScrollIndicator: PropTypes.bool, - /** Whether to animate the auto month scroll */ - animateScroll: PropTypes.bool, - /** Enable or disable scrolling of calendar list */ - scrollEnabled: PropTypes.bool, - /** When true, the calendar list scrolls to top when the status bar is tapped. Default = true */ - scrollsToTop: PropTypes.bool, - /** Enable or disable paging on scroll */ - pagingEnabled: PropTypes.bool, - /** Whether the scroll is horizontal */ - horizontal: PropTypes.bool, - /** Should Keyboard persist taps */ - keyboardShouldPersistTaps: PropTypes.oneOf(['never', 'always', 'handled']), - /** A custom key extractor for the generated calendar months */ - keyExtractor: PropTypes.func, - /** How far from the end to trigger the onEndReached callback */ - onEndReachedThreshold: PropTypes.number, - /** Called once when the scroll position gets within onEndReachedThreshold */ - onEndReached: PropTypes.func - }; - static defaultProps = { calendarWidth: width, calendarHeight: 360, @@ -72,21 +85,23 @@ class CalendarList extends Component { scrollsToTop: false, scrollEnabled: true, removeClippedSubviews: Platform.OS === 'android', - keyExtractor: (item, index) => String(index) + keyExtractor: (_: any, index: number) => String(index) + }; + + style: any; + listView: FlatList | undefined | null; + viewabilityConfig = { + itemVisiblePercentThreshold: 20 }; - constructor(props) { + constructor(props: CalendarListProps) { super(props); this.style = styleConstructor(props.theme); - this.viewabilityConfig = { - itemVisiblePercentThreshold: 20 - }; - const rows = []; const texts = []; - const date = parseDate(props.current) || XDate(); + const date = parseDate(props.current) || new XDate(); for (let i = 0; i <= props.pastScrollRange + props.futureScrollRange; i++) { const rangeDate = date.clone().addMonths(i - props.pastScrollRange, true); @@ -114,7 +129,7 @@ class CalendarList extends Component { }; } - componentDidUpdate(prevProps) { + componentDidUpdate(prevProps: CalendarListProps) { const prevCurrent = parseDate(prevProps.current); const current = parseDate(this.props.current); @@ -123,22 +138,24 @@ class CalendarList extends Component { } } - static getDerivedStateFromProps(nextProps, prevState) { - const rowclone = prevState.rows; - const newrows = []; - - for (let i = 0; i < rowclone.length; i++) { - let val = prevState.texts[i]; - if (rowclone[i].getTime) { - val = rowclone[i].clone(); - val.propbump = rowclone[i].propbump ? rowclone[i].propbump + 1 : 1; + static getDerivedStateFromProps(_: CalendarListProps, prevState: CalendarListState) { + const rowClone = prevState.rows; + const newRows = []; + + for (let i = 0; i < rowClone.length; i++) { + let val: XDate | string = prevState.texts[i]; + // @ts-ignore + if (rowClone[i].getTime) { + val = rowClone[i].clone(); + // @ts-ignore + val.propBump = rowClone[i].propBump ? rowClone[i].propBump + 1 : 1; } - newrows.push(val); + newRows.push(val); } - return {rows: newrows}; + return {rows: newRows}; } - scrollToDay(d, offset, animated) { + scrollToDay(d: XDate, offset: number, animated: boolean) { const {horizontal, calendarHeight, calendarWidth, pastScrollRange, firstDay} = this.props; const day = parseDate(d); const diffMonths = Math.round(this.state.openDate.clone().setDate(1).diffMonths(day.clone().setDate(1))); @@ -156,10 +173,10 @@ class CalendarList extends Component { } } } - this.listView.scrollToOffset({offset: scrollAmount, animated}); + this.listView?.scrollToOffset({offset: scrollAmount, animated}); } - scrollToMonth = m => { + scrollToMonth = (m: XDate) => { const {horizontal, calendarHeight, calendarWidth, pastScrollRange, animateScroll = false} = this.props; const month = parseDate(m); const scrollTo = month || this.state.openDate; @@ -167,10 +184,10 @@ class CalendarList extends Component { const size = horizontal ? calendarWidth : calendarHeight; const scrollAmount = size * pastScrollRange + diffMonths * size; - this.listView.scrollToOffset({offset: scrollAmount, animated: animateScroll}); + this.listView?.scrollToOffset({offset: scrollAmount, animated: animateScroll}); }; - getItemLayout = (data, index) => { + getItemLayout = (_: Array | undefined | null, index: number) => { const {horizontal, calendarHeight, calendarWidth} = this.props; return { @@ -180,16 +197,16 @@ class CalendarList extends Component { }; }; - getMonthIndex(month) { + getMonthIndex(month: XDate) { let diffMonths = this.state.openDate.diffMonths(month) + this.props.pastScrollRange; return diffMonths; } - addMonth = count => { + addMonth = (count: number) => { this.updateMonth(this.state.currentMonth.clone().addMonths(count, true)); }; - updateMonth(day, doNotTriggerListeners) { + updateMonth(day: XDate, doNotTriggerListeners = false) { if (day.toString('yyyy MM') === this.state.currentMonth.toString('yyyy MM')) { return; } @@ -206,8 +223,8 @@ class CalendarList extends Component { }); } - onViewableItemsChanged = ({viewableItems}) => { - function rowIsCloseToViewable(index, distance) { + onViewableItemsChanged = ({viewableItems}: any) => { + function rowIsCloseToViewable(index: number, distance: number) { for (let i = 0; i < viewableItems.length; i++) { if (Math.abs(index - parseInt(viewableItems[i].index)) <= distance) { return true; @@ -221,7 +238,7 @@ class CalendarList extends Component { const visibleMonths = []; for (let i = 0; i < rowclone.length; i++) { - let val = rowclone[i]; + let val: XDate | string = rowclone[i]; const rowShouldBeRendered = rowIsCloseToViewable(i, 1); if (rowShouldBeRendered && !rowclone[i].getTime) { @@ -238,12 +255,13 @@ class CalendarList extends Component { _.invoke(this.props, 'onVisibleMonthsChange', visibleMonths); this.setState({ + // @ts-ignore rows: newrows, currentMonth: parseDate(visibleMonths[0]) }); }; - renderItem = ({item}) => { + renderItem = ({item}: any) => { const {calendarStyle, horizontal, calendarWidth, testID, ...others} = this.props; return ( @@ -287,6 +305,7 @@ class CalendarList extends Component { (this.listView = c)} style={[this.style.container, style]} + // @ts-ignore initialListSize={pastScrollRange + futureScrollRange + 1} // ListView deprecated data={this.state.rows} renderItem={this.renderItem} From a132921ada3d711415b9305d5480750abe4f2a3d Mon Sep 17 00:00:00 2001 From: Mendy Date: Mon, 5 Jul 2021 15:10:15 +0300 Subject: [PATCH 015/109] naming --- src/calendar-list/item.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/calendar-list/item.tsx b/src/calendar-list/item.tsx index 1a00fc7e36..54ced1ee5d 100644 --- a/src/calendar-list/item.tsx +++ b/src/calendar-list/item.tsx @@ -42,7 +42,7 @@ class CalendarListItem extends Component { From 96df7d8b2411b22b524dafac5df3ca2e606e19e2 Mon Sep 17 00:00:00 2001 From: Ethan Sharabi Date: Mon, 5 Jul 2021 16:04:21 +0300 Subject: [PATCH 016/109] add a comman to check typescript without building declaration files --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 3d115e3093..729126d0e5 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,7 @@ "scripts": { "build": "xcodebuild -project ios/CalendarsExample.xcodeproj build", "build:ts": "tsc", + "build:dev": "tsc --noEmit", "e2e": "node ./scripts/test-e2e.js --release", "test": "npm run lint && npm run unit && npm run e2e", "unit": "jest", From 41a398fa6535f92a18760f3293377aff1246b8b3 Mon Sep 17 00:00:00 2001 From: Mendy Date: Mon, 5 Jul 2021 16:26:01 +0300 Subject: [PATCH 017/109] Props to be optional --- src/calendar-list/index.tsx | 32 ++++++++++++++++---------------- src/calendar-list/item.tsx | 8 ++++---- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/calendar-list/index.tsx b/src/calendar-list/index.tsx index eefbcb1d50..fd23c97e30 100644 --- a/src/calendar-list/index.tsx +++ b/src/calendar-list/index.tsx @@ -23,37 +23,37 @@ const {width} = Dimensions.get('window'); export type CalendarListProps = CalendarProps & { /** Max amount of months allowed to scroll to the past. Default = 50 */ - pastScrollRange: number; + pastScrollRange?: number; /** Max amount of months allowed to scroll to the future. Default = 50 */ - futureScrollRange: number; + futureScrollRange?: number; /** Used when calendar scroll is horizontal, default is device width, pagination should be disabled */ - calendarWidth: number; + calendarWidth?: number; /** Dynamic calendar height */ - calendarHeight: number; + calendarHeight?: number; /** Style for the List item (the calendar) */ - calendarStyle: number | Array | Object; + calendarStyle?: number | Array | Object; /** Whether to use static header that will not scroll with the list (horizontal only) */ - staticHeader: boolean; + staticHeader?: boolean; /** Enable or disable vertical / horizontal scroll indicator. Default = false */ - showScrollIndicator: boolean; + showScrollIndicator?: boolean; /** Whether to animate the auto month scroll */ - animateScroll: boolean; + animateScroll?: boolean; /** Enable or disable scrolling of calendar list */ - scrollEnabled: boolean; + scrollEnabled?: boolean; /** When true, the calendar list scrolls to top when the status bar is tapped. Default = true */ - scrollsToTop: boolean; + scrollsToTop?: boolean; /** Enable or disable paging on scroll */ - pagingEnabled: boolean; + pagingEnabled?: boolean; /** Whether the scroll is horizontal */ - horizontal: boolean; + horizontal?: boolean; /** Should Keyboard persist taps */ - keyboardShouldPersistTaps: 'never' | 'always' | 'handled'; + keyboardShouldPersistTaps?: 'never' | 'always' | 'handled'; /** A custom key extractor for the generated calendar months */ - keyExtractor: (item: any, index: number) => string; + keyExtractor?: (item: any, index: number) => string; /** How far from the end to trigger the onEndReached callback */ - onEndReachedThreshold: number; + onEndReachedThreshold?: number; /** Called once when the scroll position gets within onEndReachedThreshold */ - onEndReached: () => void; + onEndReached?: () => void; }; type XDateAndBump = XDate & {propBump?: number} ; diff --git a/src/calendar-list/item.tsx b/src/calendar-list/item.tsx index 54ced1ee5d..9729c9d5fc 100644 --- a/src/calendar-list/item.tsx +++ b/src/calendar-list/item.tsx @@ -11,10 +11,10 @@ import styleConstructor from './style'; export type CalendarListItemProps = CalendarProps & { item: any; - calendarWidth: number; - calendarHeight: number; - horizontal: boolean; - theme: any; + calendarWidth?: number; + calendarHeight?: number; + horizontal?: boolean; + theme?: any; } type CalendarListItemState = { From ca082b8422c1103bc4c23b13932db8e710148dc3 Mon Sep 17 00:00:00 2001 From: Lidor Dafna Date: Mon, 5 Jul 2021 16:39:46 +0300 Subject: [PATCH 018/109] migrate to TS --- src/calendar/day/basic/index.tsx | 11 ++- src/calendar/day/marking/index.tsx | 138 +++++++++++++---------------- src/calendar/day/marking/style.ts | 3 +- 3 files changed, 70 insertions(+), 82 deletions(-) diff --git a/src/calendar/day/basic/index.tsx b/src/calendar/day/basic/index.tsx index d68875f0a9..1085c00395 100644 --- a/src/calendar/day/basic/index.tsx +++ b/src/calendar/day/basic/index.tsx @@ -6,15 +6,14 @@ import {TouchableOpacity, Text, View} from 'react-native'; // @ts-expect-error import {shouldUpdate} from '../../../component-updater'; import styleConstructor from './style'; -// @ts-expect-error -import Marking from '../marking'; +import Marking, {MARKING_TYPES} from '../marking'; interface BasicDayProps { state?: 'selected' | 'disabled' | 'today'; /** The marking object */ marking: any; /** Date marking style [simple/period/multi-dot/multi-period]. Default = 'simple' */ - markingType: MarkingTypes; + markingType: MARKING_TYPES; /** Theme object */ theme: Object; /** onPress callback */ @@ -110,15 +109,15 @@ export default class BasicDay extends Component { } isMultiDot() { - return this.props.markingType === Marking.markingTypes.multiDot; + return this.props.markingType === Marking.markingTypes.MULTI_DOT; } isMultiPeriod() { - return this.props.markingType === Marking.markingTypes.multiPeriod; + return this.props.markingType === Marking.markingTypes.MULTI_PERIOD; } isCustom() { - return this.props.markingType === Marking.markingTypes.custom; + return this.props.markingType === Marking.markingTypes.CUSTOM; } getContainerStyle() { diff --git a/src/calendar/day/marking/index.tsx b/src/calendar/day/marking/index.tsx index 3aaf87436e..d811049a6b 100644 --- a/src/calendar/day/marking/index.tsx +++ b/src/calendar/day/marking/index.tsx @@ -1,114 +1,108 @@ -import PropTypes from 'prop-types'; import React, {Component} from 'react'; import {View} from 'react-native'; +// @ts-expect-error import {shouldUpdate, extractComponentProps} from '../../../component-updater'; import styleConstructor from './style'; +// @ts-expect-error import Dot from '../dot'; +export enum MARKING_TYPES { + DOT = 'dot', + MULTI_DOT = 'multi-dot', + PERIOD = 'period', + MULTI_PERIOD = 'multi-period', + CUSTOM = 'custom' +} -const MARKING_TYPES = { - dot: 'dot', - multiDot: 'multi-dot', - period: 'period', - multiPeriod: 'multi-period', - custom: 'custom' -}; - -const DOT = { - key: PropTypes.string, - color: PropTypes.string, - selectedDotColor: PropTypes.string +type DOT = { + key?: string; + color?: string; + selectedDotColor?: string; }; -const PERIOD = { - startingDay: PropTypes.bool, - endingDay: PropTypes.bool, - color: PropTypes.string +type PERIOD = { + startingDay?: boolean; + endingDay?: boolean; + color?: string; }; +interface MarkingProps extends Dot.propTypes { + type?: MARKING_TYPES; + theme?: Object; + selected?: boolean; + marked?: boolean; + today?: boolean; + disabled?: boolean; + disableTouchEvent?: boolean; + activeOpacity?: number; + selectedColor?: string; + selectedTextColor?: string; + dotColor?: string; + //multi-dot + dots?: DOT; + //multi-period + periods?: PERIOD; +} -export default class Marking extends Component { +export default class Marking extends Component { static displayName = 'IGNORE'; - static propTypes = { - ...Dot.propTypes, - type: PropTypes.oneOf(Object.values(MARKING_TYPES)), - theme: PropTypes.object, - selected: PropTypes.bool, - marked: PropTypes.bool, - today: PropTypes.bool, - disabled: PropTypes.bool, - disableTouchEvent: PropTypes.bool, - activeOpacity: PropTypes.number, - selectedColor: PropTypes.string, - selectedTextColor: PropTypes.string, - dotColor: PropTypes.string, - //multi-dot - dots: PropTypes.arrayOf(PropTypes.shape(DOT)), - //multi-period - periods: PropTypes.arrayOf(PropTypes.shape(PERIOD)) - }; - static markingTypes = MARKING_TYPES; + style: any; - constructor(props) { + constructor(props: MarkingProps) { super(props); - + this.style = styleConstructor(props.theme); } - shouldComponentUpdate(nextProps) { + shouldComponentUpdate(nextProps: MarkingProps) { return shouldUpdate(this.props, nextProps, [ - 'type', - 'selected', - 'marked', - 'today', - 'disabled', - 'disableTouchEvent', - 'activeOpacity', - 'selectedColor', - 'selectedTextColor', + 'type', + 'selected', + 'marked', + 'today', + 'disabled', + 'disableTouchEvent', + 'activeOpacity', + 'selectedColor', + 'selectedTextColor', 'dotColor', 'dots', 'periods' ]); } - getItems(items) { + getItems(items: DOT | PERIOD) { const {type} = this.props; - + if (items && Array.isArray(items) && items.length > 0) { // Filter out items so that we process only those which have color property const validItems = items.filter(d => d && d.color); - + return validItems.map((item, index) => { - return type === MARKING_TYPES.multiDot ? this.renderDot(index, item) : this.renderPeriod(index, item); + return type === MARKING_TYPES.MULTI_DOT ? this.renderDot(index, item) : this.renderPeriod(index, item); }); } } renderMarkingByType() { const {type, dots, periods} = this.props; - switch (type) { - case MARKING_TYPES.multiDot: - return this.renderMultiMarkings(this.style.dots, dots); - case MARKING_TYPES.multiPeriod: - return this.renderMultiMarkings(this.style.periods, periods); + case MARKING_TYPES.MULTI_DOT: + return this.renderMultiMarkings(this.style.dots, dots); + case MARKING_TYPES.MULTI_PERIOD: + return this.renderMultiMarkings(this.style.periods, periods); default: return this.renderDot(); } } - renderMultiMarkings(containerStyle, items) { - return ( - - {this.getItems(items)} - - ); + renderMultiMarkings(containerStyle: Object, items: any) { + return {this.getItems(items)}; } - renderPeriod(index, item) { + renderPeriod(index: number, item: any) { const {color, startingDay, endingDay} = item; const style = [ this.style.period, @@ -122,15 +116,15 @@ export default class Marking extends Component { if (endingDay) { style.push(this.style.endingDay); } - return ; + return ; } - renderDot(index, item) { + renderDot(index?: number, item?: any) { const {selected, dotColor} = this.props; const dotProps = extractComponentProps(Dot, this.props); let key = index; let color = dotColor; - + if (item) { if (item.key) { key = item.key; @@ -138,13 +132,7 @@ export default class Marking extends Component { color = selected && item.selectedDotColor ? item.selectedDotColor : item.color; } - return ( - - ); + return ; } render() { diff --git a/src/calendar/day/marking/style.ts b/src/calendar/day/marking/style.ts index 61cbb0e70e..cac220d462 100644 --- a/src/calendar/day/marking/style.ts +++ b/src/calendar/day/marking/style.ts @@ -1,9 +1,10 @@ import {StyleSheet} from 'react-native'; +// @ts-expect-error import * as defaultStyle from '../../style'; const STYLESHEET_ID = 'stylesheet.marking'; -export default function styleConstructor(theme = {}) { +export default function styleConstructor(theme: any = {}) { const appStyle = {...defaultStyle, ...theme}; return StyleSheet.create({ dots: { From 39c64112bbf10bf76ba15a3db4debd3dd8c1a1c0 Mon Sep 17 00:00:00 2001 From: Lidor Dafna Date: Mon, 5 Jul 2021 17:01:32 +0300 Subject: [PATCH 019/109] make props optional --- src/calendar/day/dot/index.tsx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/calendar/day/dot/index.tsx b/src/calendar/day/dot/index.tsx index 114ac3538d..764cf749e9 100644 --- a/src/calendar/day/dot/index.tsx +++ b/src/calendar/day/dot/index.tsx @@ -3,12 +3,12 @@ import {View} from 'react-native'; import styleConstructor from './style'; interface DotProps { - theme: Object; - color: String; - marked: Boolean; - selected: Boolean; - disabled: Boolean; - today: Boolean; + theme?: Object; + color?: String; + marked?: Boolean; + selected?: Boolean; + disabled?: Boolean; + today?: Boolean; } const Dot = ({theme, marked, disabled, color, today, selected}: DotProps) => { From 2aacadf0585c640aebd7a8abe041974261d056f0 Mon Sep 17 00:00:00 2001 From: Lidor Dafna Date: Mon, 5 Jul 2021 17:05:43 +0300 Subject: [PATCH 020/109] rename files --- src/calendar/day/period/{index.js => index.tsx} | 0 src/calendar/day/period/{style.js => style.ts} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename src/calendar/day/period/{index.js => index.tsx} (100%) rename src/calendar/day/period/{style.js => style.ts} (100%) diff --git a/src/calendar/day/period/index.js b/src/calendar/day/period/index.tsx similarity index 100% rename from src/calendar/day/period/index.js rename to src/calendar/day/period/index.tsx diff --git a/src/calendar/day/period/style.js b/src/calendar/day/period/style.ts similarity index 100% rename from src/calendar/day/period/style.js rename to src/calendar/day/period/style.ts From d761dd835024c875ed27a63a2dd0e94b65797c1f Mon Sep 17 00:00:00 2001 From: Lidor Dafna Date: Mon, 5 Jul 2021 17:25:42 +0300 Subject: [PATCH 021/109] rename MarkingTypes --- src/calendar/day/basic/index.tsx | 4 ++-- src/calendar/day/marking/index.tsx | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/calendar/day/basic/index.tsx b/src/calendar/day/basic/index.tsx index 1085c00395..68f2a7955e 100644 --- a/src/calendar/day/basic/index.tsx +++ b/src/calendar/day/basic/index.tsx @@ -6,14 +6,14 @@ import {TouchableOpacity, Text, View} from 'react-native'; // @ts-expect-error import {shouldUpdate} from '../../../component-updater'; import styleConstructor from './style'; -import Marking, {MARKING_TYPES} from '../marking'; +import Marking, {MarkingTypes} from '../marking'; interface BasicDayProps { state?: 'selected' | 'disabled' | 'today'; /** The marking object */ marking: any; /** Date marking style [simple/period/multi-dot/multi-period]. Default = 'simple' */ - markingType: MARKING_TYPES; + markingType: MarkingTypes; /** Theme object */ theme: Object; /** onPress callback */ diff --git a/src/calendar/day/marking/index.tsx b/src/calendar/day/marking/index.tsx index d811049a6b..5510aa7904 100644 --- a/src/calendar/day/marking/index.tsx +++ b/src/calendar/day/marking/index.tsx @@ -6,7 +6,7 @@ import styleConstructor from './style'; // @ts-expect-error import Dot from '../dot'; -export enum MARKING_TYPES { +export enum MarkingTypes { DOT = 'dot', MULTI_DOT = 'multi-dot', PERIOD = 'period', @@ -27,7 +27,7 @@ type PERIOD = { }; interface MarkingProps extends Dot.propTypes { - type?: MARKING_TYPES; + type?: MarkingTypes; theme?: Object; selected?: boolean; marked?: boolean; @@ -47,7 +47,7 @@ interface MarkingProps extends Dot.propTypes { export default class Marking extends Component { static displayName = 'IGNORE'; - static markingTypes = MARKING_TYPES; + static markingTypes = MarkingTypes; style: any; constructor(props: MarkingProps) { @@ -81,7 +81,7 @@ export default class Marking extends Component { const validItems = items.filter(d => d && d.color); return validItems.map((item, index) => { - return type === MARKING_TYPES.MULTI_DOT ? this.renderDot(index, item) : this.renderPeriod(index, item); + return type === MarkingTypes.MULTI_DOT ? this.renderDot(index, item) : this.renderPeriod(index, item); }); } } @@ -89,9 +89,9 @@ export default class Marking extends Component { renderMarkingByType() { const {type, dots, periods} = this.props; switch (type) { - case MARKING_TYPES.MULTI_DOT: + case MarkingTypes.MULTI_DOT: return this.renderMultiMarkings(this.style.dots, dots); - case MARKING_TYPES.MULTI_PERIOD: + case MarkingTypes.MULTI_PERIOD: return this.renderMultiMarkings(this.style.periods, periods); default: return this.renderDot(); From e362ea5643e494e029dfa57f9a33603bbdb778f8 Mon Sep 17 00:00:00 2001 From: Mendy Date: Mon, 5 Jul 2021 17:46:39 +0300 Subject: [PATCH 022/109] js types - for mapping --- src/calendar-list/index.tsx | 39 ++++++++++++++++++++++++++++++++++++- src/calendar-list/item.tsx | 9 +++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/src/calendar-list/index.tsx b/src/calendar-list/index.tsx index fd23c97e30..cbab519eec 100644 --- a/src/calendar-list/index.tsx +++ b/src/calendar-list/index.tsx @@ -1,5 +1,6 @@ import _ from 'lodash'; import XDate from 'xdate'; +import PropTypes from 'prop-types'; import React, {Component} from 'react'; import {FlatList, Platform, Dimensions, View} from 'react-native'; @@ -14,7 +15,7 @@ import {STATIC_HEADER} from '../testIDs'; import styleConstructor from './style'; // @ts-expect-error -import {CalendarProps} from '../calendar'; +import Calendar, {CalendarProps} from '../calendar'; import CalendarListItem from './item'; // @ts-expect-error import CalendarHeader from '../calendar/header/index'; @@ -75,6 +76,42 @@ type CalendarListState = { class CalendarList extends Component { static displayName = 'CalendarList'; + static propTypes = { + ...Calendar.propTypes, + /** Max amount of months allowed to scroll to the past. Default = 50 */ + pastScrollRange: PropTypes.number, + /** Max amount of months allowed to scroll to the future. Default = 50 */ + futureScrollRange: PropTypes.number, + /** Used when calendar scroll is horizontal, default is device width, pagination should be disabled */ + calendarWidth: PropTypes.number, + /** Dynamic calendar height */ + calendarHeight: PropTypes.number, + /** Style for the List item (the calendar) */ + calendarStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.number, PropTypes.array]), + /** Whether to use static header that will not scroll with the list (horizontal only) */ + staticHeader: PropTypes.bool, + /** Enable or disable vertical / horizontal scroll indicator. Default = false */ + showScrollIndicator: PropTypes.bool, + /** Whether to animate the auto month scroll */ + animateScroll: PropTypes.bool, + /** Enable or disable scrolling of calendar list */ + scrollEnabled: PropTypes.bool, + /** When true, the calendar list scrolls to top when the status bar is tapped. Default = true */ + scrollsToTop: PropTypes.bool, + /** Enable or disable paging on scroll */ + pagingEnabled: PropTypes.bool, + /** Whether the scroll is horizontal */ + horizontal: PropTypes.bool, + /** Should Keyboard persist taps */ + keyboardShouldPersistTaps: PropTypes.oneOf(['never', 'always', 'handled']), + /** A custom key extractor for the generated calendar months */ + keyExtractor: PropTypes.func, + /** How far from the end to trigger the onEndReached callback */ + onEndReachedThreshold: PropTypes.number, + /** Called once when the scroll position gets within onEndReachedThreshold */ + onEndReached: PropTypes.func + }; + static defaultProps = { calendarWidth: width, calendarHeight: 360, diff --git a/src/calendar-list/item.tsx b/src/calendar-list/item.tsx index 9729c9d5fc..f40da40ffe 100644 --- a/src/calendar-list/item.tsx +++ b/src/calendar-list/item.tsx @@ -1,6 +1,7 @@ import memoize from 'memoize-one'; import React, {Component} from 'react'; import {Text, View} from 'react-native'; +import PropTypes from 'prop-types'; // @ts-expect-error import {extractComponentProps} from '../component-updater'; @@ -25,6 +26,14 @@ type CalendarListItemState = { class CalendarListItem extends Component { static displayName = 'IGNORE'; + static propTypes = { + ...Calendar.propTypes, + item: PropTypes.any, + calendarWidth: PropTypes.number, + calendarHeight: PropTypes.number, + horizontal: PropTypes.bool + }; + static defaultProps = { hideArrows: true, hideExtraDays: true From df945a7814de5eab2834563fcab78c8973157056 Mon Sep 17 00:00:00 2001 From: Ethan Sharabi Date: Mon, 5 Jul 2021 17:48:36 +0300 Subject: [PATCH 023/109] Fix ts-expect-error --- src/calendar/day/dot/index.tsx | 2 +- src/calendar/day/marking/index.tsx | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/calendar/day/dot/index.tsx b/src/calendar/day/dot/index.tsx index 764cf749e9..d9909b6e48 100644 --- a/src/calendar/day/dot/index.tsx +++ b/src/calendar/day/dot/index.tsx @@ -2,7 +2,7 @@ import React from 'react'; import {View} from 'react-native'; import styleConstructor from './style'; -interface DotProps { +export interface DotProps { theme?: Object; color?: String; marked?: Boolean; diff --git a/src/calendar/day/marking/index.tsx b/src/calendar/day/marking/index.tsx index 5510aa7904..34a98c022e 100644 --- a/src/calendar/day/marking/index.tsx +++ b/src/calendar/day/marking/index.tsx @@ -3,8 +3,7 @@ import {View} from 'react-native'; // @ts-expect-error import {shouldUpdate, extractComponentProps} from '../../../component-updater'; import styleConstructor from './style'; -// @ts-expect-error -import Dot from '../dot'; +import Dot, {DotProps} from '../dot'; export enum MarkingTypes { DOT = 'dot', @@ -26,7 +25,7 @@ type PERIOD = { color?: string; }; -interface MarkingProps extends Dot.propTypes { +interface MarkingProps extends DotProps { type?: MarkingTypes; theme?: Object; selected?: boolean; From 4b6e4c9737b6fdae41825f86b1c95c776aea0a03 Mon Sep 17 00:00:00 2001 From: Lidor Dafna Date: Mon, 5 Jul 2021 18:09:23 +0300 Subject: [PATCH 024/109] migrate to TS --- src/calendar/day/period/index.tsx | 35 ++++++++++++++++++++++--------- src/calendar/day/period/style.ts | 3 ++- 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/src/calendar/day/period/index.tsx b/src/calendar/day/period/index.tsx index ac7cd4b09c..75c9958799 100644 --- a/src/calendar/day/period/index.tsx +++ b/src/calendar/day/period/index.tsx @@ -3,13 +3,25 @@ import PropTypes from 'prop-types'; import React, {Component} from 'react'; import {TouchableWithoutFeedback, Text, View} from 'react-native'; - +// @ts-expect-error import {shouldUpdate} from '../../../component-updater'; +// @ts-expect-error import * as defaultStyle from '../../../style'; import styleConstructor from './style'; import Dot from '../dot'; -export default class PeriodDay extends Component { +interface PeriodDayProps { + state?: 'selected' | 'disabled' | 'today' | ''; + marking?: any; + theme?: Object; + onPress?: (date?: Object) => void; + onLongPress?: (date?: Object) => void; + date?: Object; + accessibilityLabel?: string; + testID?: string; +} + +export default class PeriodDay extends Component{ static displayName = 'IGNORE'; static propTypes = { @@ -20,8 +32,11 @@ export default class PeriodDay extends Component { onLongPress: PropTypes.func, date: PropTypes.object }; + theme: any; + style: any; + markingStyle: any; - constructor(props) { + constructor(props: PeriodDayProps) { super(props); this.theme = {...defaultStyle, ...(props.theme || {})}; @@ -31,14 +46,14 @@ export default class PeriodDay extends Component { } onPress = () => { - this.props.onPress(this.props.date); + this.props.onPress?.(this.props.date); }; onLongPress = () => { - this.props.onLongPress(this.props.date); + this.props.onLongPress?.(this.props.date); }; - shouldComponentUpdate(nextProps) { + shouldComponentUpdate(nextProps: PeriodDayProps) { const newMarkingStyle = this.getDrawingStyle(nextProps.marking); if (!_.isEqual(this.markingStyle, newMarkingStyle)) { this.markingStyle = newMarkingStyle; @@ -48,8 +63,8 @@ export default class PeriodDay extends Component { return shouldUpdate(this.props, nextProps, ['children', 'state', 'marking', 'onPress', 'onLongPress', 'date']); } - getDrawingStyle(marking) { - const defaultStyle = {textStyle: {}, containerStyle: {}}; + getDrawingStyle(marking: any) { + const defaultStyle = {textStyle: {color: undefined}, containerStyle: {}}; if (!marking) { return defaultStyle; @@ -115,8 +130,8 @@ export default class PeriodDay extends Component { const {state, marking} = this.props; const containerStyle = [this.style.base]; const textStyle = [this.style.text]; - let leftFillerStyle = {}; - let rightFillerStyle = {}; + let leftFillerStyle = {backgroundColor: undefined}; + let rightFillerStyle = {backgroundColor: undefined}; let fillerStyle = {}; let fillers; diff --git a/src/calendar/day/period/style.ts b/src/calendar/day/period/style.ts index d62a9b2a55..1597c91328 100644 --- a/src/calendar/day/period/style.ts +++ b/src/calendar/day/period/style.ts @@ -1,11 +1,12 @@ import {StyleSheet} from 'react-native'; +// @ts-expect-error import * as defaultStyle from '../../../style'; const STYLESHEET_ID = 'stylesheet.day.period'; const FILLER_HEIGHT = 34; -export default function styleConstructor(theme={}) { +export default function styleConstructor(theme: any = {}) { const appStyle = {...defaultStyle, ...theme}; return StyleSheet.create({ wrapper: { From c0bcd00f297d3314bba78bac213fb59ee1b8b2a8 Mon Sep 17 00:00:00 2001 From: Lidor Dafna Date: Tue, 6 Jul 2021 08:45:23 +0300 Subject: [PATCH 025/109] rename file --- src/calendar/day/{index.js => index.tsx} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/calendar/day/{index.js => index.tsx} (100%) diff --git a/src/calendar/day/index.js b/src/calendar/day/index.tsx similarity index 100% rename from src/calendar/day/index.js rename to src/calendar/day/index.tsx From 716424f7e970b16c331938419a3a366c2f89586c Mon Sep 17 00:00:00 2001 From: Lidor Dafna Date: Tue, 6 Jul 2021 09:07:52 +0300 Subject: [PATCH 026/109] migrate to TS --- src/calendar/day/basic/index.tsx | 2 +- src/calendar/day/dot/index.tsx | 10 ++++++++++ src/calendar/day/index.tsx | 30 ++++++++++++++++++++---------- 3 files changed, 31 insertions(+), 11 deletions(-) diff --git a/src/calendar/day/basic/index.tsx b/src/calendar/day/basic/index.tsx index 68f2a7955e..fd50587e85 100644 --- a/src/calendar/day/basic/index.tsx +++ b/src/calendar/day/basic/index.tsx @@ -8,7 +8,7 @@ import {shouldUpdate} from '../../../component-updater'; import styleConstructor from './style'; import Marking, {MarkingTypes} from '../marking'; -interface BasicDayProps { +export interface BasicDayProps { state?: 'selected' | 'disabled' | 'today'; /** The marking object */ marking: any; diff --git a/src/calendar/day/dot/index.tsx b/src/calendar/day/dot/index.tsx index d9909b6e48..2dae7d407d 100644 --- a/src/calendar/day/dot/index.tsx +++ b/src/calendar/day/dot/index.tsx @@ -1,3 +1,4 @@ +import PropTypes from 'prop-types'; import React from 'react'; import {View} from 'react-native'; import styleConstructor from './style'; @@ -39,3 +40,12 @@ const Dot = ({theme, marked, disabled, color, today, selected}: DotProps) => { }; export default Dot; + +Dot.propTypes = { + theme: PropTypes.object, + color: PropTypes.string, + marked: PropTypes.bool, + selected: PropTypes.bool, + disabled: PropTypes.bool, + today: PropTypes.bool +}; diff --git a/src/calendar/day/index.tsx b/src/calendar/day/index.tsx index bdb6019eca..34d7d9b197 100644 --- a/src/calendar/day/index.tsx +++ b/src/calendar/day/index.tsx @@ -4,28 +4,38 @@ import XDate from 'xdate'; import memoize from 'memoize-one'; import React, {Component} from 'react'; - +// @ts-expect-error import {shouldUpdate} from '../../component-updater'; +// @ts-expect-error import dateutils from '../../dateutils'; +// @ts-expect-error import {xdateToData} from '../../interface'; +// @ts-expect-error import {SELECT_DATE_SLOT} from '../../testIDs'; -import BasicDay from './basic'; +import BasicDay, {BasicDayProps} from './basic'; import PeriodDay from './period'; -const basicDayProps = _.omit(BasicDay.propTypes, 'date'); +const basicDayPropsTypes = _.omit(BasicDay.propTypes, 'date'); + +interface DayProps extends BasicDayProps { + /** The day to render */ + day?: Date; + /** Provide custom day rendering component */ + dayComponent?: any; +} -export default class Day extends Component { +export default class Day extends Component { static displayName = 'IGNORE'; static propTypes = { - ...basicDayProps, + ...basicDayPropsTypes, /** The day to render */ day: PropTypes.object, /** Provide custom day rendering component */ dayComponent: PropTypes.any }; - shouldComponentUpdate(nextProps) { + shouldComponentUpdate(nextProps: DayProps) { return shouldUpdate(this.props, nextProps, [ 'day', 'dayComponent', @@ -37,7 +47,7 @@ export default class Day extends Component { ]); } - getMarkingLabel(marking) { + getMarkingLabel(marking: any) { let label = ''; if (marking) { @@ -68,8 +78,8 @@ export default class Day extends Component { } getAccessibilityLabel = memoize((day, marking, isToday) => { - const today = XDate.locales[XDate.defaultLocale].today; - const formatAccessibilityLabel = XDate.locales[XDate.defaultLocale].formatAccessibilityLabel; + const today = _.get(XDate, 'locales.[XDate.defaultLocale].today'); + const formatAccessibilityLabel = _.get(XDate, 'locales[XDate.defaultLocale].formatAccessibilityLabel'); const markingLabel = this.getMarkingLabel(marking); if (formatAccessibilityLabel) { @@ -103,7 +113,7 @@ export default class Day extends Component { testID={`${SELECT_DATE_SLOT}-${date.dateString}`} accessibilityLabel={accessibilityLabel} > - {date ? day.getDate() : day} + {date ? day?.getDate() : day} ); } From 5f7f5766791fc77481a858fed03d6e79b744c13c Mon Sep 17 00:00:00 2001 From: Lidor Dafna Date: Tue, 6 Jul 2021 10:00:56 +0300 Subject: [PATCH 027/109] Omit date from BasicDayProps --- src/calendar/day/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/calendar/day/index.tsx b/src/calendar/day/index.tsx index 34d7d9b197..fd4f00430a 100644 --- a/src/calendar/day/index.tsx +++ b/src/calendar/day/index.tsx @@ -17,7 +17,7 @@ import PeriodDay from './period'; const basicDayPropsTypes = _.omit(BasicDay.propTypes, 'date'); -interface DayProps extends BasicDayProps { +interface DayProps extends Omit { /** The day to render */ day?: Date; /** Provide custom day rendering component */ From 28a355077bc639a0c2cd5bd8ac37d00700c81b9e Mon Sep 17 00:00:00 2001 From: Lidor Dafna Date: Tue, 6 Jul 2021 11:16:58 +0300 Subject: [PATCH 028/109] add typescript to eslint configurations --- .eslintrc.js | 4 ++-- package.json | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 846d63f500..120c656787 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -10,7 +10,7 @@ module.exports = { describe: true }, extends: ['eslint:recommended'], - parser: 'babel-eslint', + parser: '@typescript-eslint/parser', parserOptions: { ecmaFeatures: { experimentalObjectRestSpread: true, @@ -18,7 +18,7 @@ module.exports = { }, sourceType: 'module' }, - plugins: ['react', 'react-native', 'jest'], + plugins: ['react', 'react-native', 'jest', '@typescript-eslint'], rules: { 'react-native/no-inline-styles': 1, 'linebreak-style': ['error', 'unix'], diff --git a/package.json b/package.json index a4afd0929f..7d2f300e7e 100644 --- a/package.json +++ b/package.json @@ -45,6 +45,8 @@ "@types/react-native": "^0.63.52", "@types/xdate": "^0.8.32", "@welldone-software/why-did-you-render": "^6.0.3", + "@typescript-eslint/eslint-plugin": "^2.13.0", + "@typescript-eslint/parser": "^2.13.0", "babel-eslint": "^10.1.0", "babel-jest": "^26.6.3", "detox": "^18.0.0", From 7e4ec574bfea5347af2be2149e6c75b9ae1871a5 Mon Sep 17 00:00:00 2001 From: Lidor Dafna Date: Wed, 7 Jul 2021 16:10:48 +0300 Subject: [PATCH 029/109] rename files --- src/calendar/header/{index.js => index.tsx} | 0 src/calendar/header/{style.js => style.ts} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename src/calendar/header/{index.js => index.tsx} (100%) rename src/calendar/header/{style.js => style.ts} (100%) diff --git a/src/calendar/header/index.js b/src/calendar/header/index.tsx similarity index 100% rename from src/calendar/header/index.js rename to src/calendar/header/index.tsx diff --git a/src/calendar/header/style.js b/src/calendar/header/style.ts similarity index 100% rename from src/calendar/header/style.js rename to src/calendar/header/style.ts From bca374fc2e3a23a4a2df8b6c01fb753fd3254819 Mon Sep 17 00:00:00 2001 From: Lidor Dafna Date: Wed, 7 Jul 2021 16:43:30 +0300 Subject: [PATCH 030/109] migrate to TS --- src/calendar-list/index.tsx | 1 - src/calendar/header/index.tsx | 67 +++++++++++++++++++++++++++-------- src/calendar/header/style.ts | 3 +- 3 files changed, 55 insertions(+), 16 deletions(-) diff --git a/src/calendar-list/index.tsx b/src/calendar-list/index.tsx index cbab519eec..65dfec9080 100644 --- a/src/calendar-list/index.tsx +++ b/src/calendar-list/index.tsx @@ -17,7 +17,6 @@ import styleConstructor from './style'; // @ts-expect-error import Calendar, {CalendarProps} from '../calendar'; import CalendarListItem from './item'; -// @ts-expect-error import CalendarHeader from '../calendar/header/index'; const {width} = Dimensions.get('window'); diff --git a/src/calendar/header/index.tsx b/src/calendar/header/index.tsx index d85fe210f2..79af257359 100644 --- a/src/calendar/header/index.tsx +++ b/src/calendar/header/index.tsx @@ -3,10 +3,11 @@ import PropTypes from 'prop-types'; import memoize from 'memoize-one'; import XDate from 'xdate'; -import React, {Component, Fragment} from 'react'; -import {ActivityIndicator, Platform, View, Text, TouchableOpacity, Image} from 'react-native'; - +import React, {Component, Fragment, ReactNode} from 'react'; +import {ActivityIndicator, Platform, View, Text, TouchableOpacity, Image, ColorValue, ViewStyle, AccessibilityActionEvent} from 'react-native'; +// @ts-expect-error import {shouldUpdate} from '../../component-updater'; +// @ts-expect-error import {weekDayNames} from '../../dateutils'; import { CHANGE_MONTH_LEFT_ARROW, @@ -14,10 +15,47 @@ import { HEADER_DAY_NAMES, HEADER_LOADING_INDICATOR, HEADER_MONTH_NAME + // @ts-expect-error } from '../../testIDs'; import styleConstructor from './style'; -class CalendarHeader extends Component { +type Direction = 'left' | 'right'; +interface CalendarHeaderProps { + theme?: any; + firstDay?: number; + displayLoadingIndicator?: boolean; + showWeekNumbers?: boolean; + month?: XDate; + addMonth?: (num: number) => void; + /** Month format in the title. Formatting values: http://arshaw.com/xdate/#Formatting */ + monthFormat?: string; + /** Hide day names. Default = false */ + hideDayNames?: boolean; + /** Hide month navigation arrows. Default = false */ + hideArrows?: boolean; + /** Replace default arrows with custom ones (direction can be 'left' or 'right') */ + renderArrow?: (direction: Direction) => ReactNode; + /** Handler which gets executed when press arrow icon left. It receive a callback can go back month */ + onPressArrowLeft?: (method: () => void, month?: XDate) => void; + /** Handler which gets executed when press arrow icon right. It receive a callback can go next month */ + onPressArrowRight?: (method: () => void, month?: XDate) => void; + /** Disable left arrow. Default = false */ + disableArrowLeft?: boolean; + /** Disable right arrow. Default = false */ + disableArrowRight?: boolean; + /** Apply custom disable color to selected day indexes */ + disabledDaysIndexes?: number[]; + /** Replace default month and year title with custom one. the function receive a date as parameter. */ + renderHeader?: any; + /** Provide aria-level for calendar heading for proper accessibility when used with web (react-native-web) */ + webAriaLevel?: number; + testID?: string; + style?: ViewStyle; + accessibilityElementsHidden?: boolean; + importantForAccessibility?: 'auto' | 'yes' | 'no' | 'no-hide-descendants'; +} + +class CalendarHeader extends Component { static displayName = 'IGNORE'; static propTypes = { @@ -55,15 +93,16 @@ class CalendarHeader extends Component { monthFormat: 'MMMM yyyy', webAriaLevel: 1 }; + style: any; - constructor(props) { + constructor(props: CalendarHeaderProps) { super(props); this.style = styleConstructor(props.theme); } - shouldComponentUpdate(nextProps) { - if (nextProps.month.toString('yyyy MM') !== this.props.month.toString('yyyy MM')) { + shouldComponentUpdate(nextProps: CalendarHeaderProps) { + if (nextProps.month?.toString('yyyy MM') !== this.props.month?.toString('yyyy MM')) { return true; } return shouldUpdate(this.props, nextProps, [ @@ -80,12 +119,12 @@ class CalendarHeader extends Component { addMonth = () => { const {addMonth} = this.props; - addMonth(1); + addMonth?.(1); }; subtractMonth = () => { const {addMonth} = this.props; - addMonth(-1); + addMonth?.(-1); }; onPressLeft = () => { @@ -111,7 +150,7 @@ class CalendarHeader extends Component { renderWeekDays = memoize(weekDaysNames => { const {disabledDaysIndexes} = this.props; - return weekDaysNames.map((day, idx) => { + return weekDaysNames.map((day: any, idx: any) => { const dayStyle = [this.style.dayHeader]; if (_.includes(disabledDaysIndexes, idx)) { @@ -146,13 +185,13 @@ class CalendarHeader extends Component { testID={testID ? `${HEADER_MONTH_NAME}-${testID}` : HEADER_MONTH_NAME} {...webProps} > - {month.toString(monthFormat)} + {month?.toString(monthFormat)} ); }; - renderArrow(direction) { + renderArrow(direction: Direction) { const {hideArrows, disableArrowLeft, disableArrowRight, renderArrow, testID} = this.props; if (hideArrows) { return ; @@ -188,7 +227,7 @@ class CalendarHeader extends Component { if (displayLoadingIndicator) { return ( ); @@ -239,7 +278,7 @@ class CalendarHeader extends Component { ); } - onAccessibilityAction = event => { + onAccessibilityAction = (event: AccessibilityActionEvent) => { switch (event.nativeEvent.actionName) { case 'decrement': this.onPressLeft(); diff --git a/src/calendar/header/style.ts b/src/calendar/header/style.ts index d32f90ce1b..a182733fed 100644 --- a/src/calendar/header/style.ts +++ b/src/calendar/header/style.ts @@ -1,9 +1,10 @@ import {StyleSheet, Platform} from 'react-native'; +// @ts-expect-error import * as defaultStyle from '../../style'; const STYLESHEET_ID = 'stylesheet.calendar.header'; -export default function (theme = {}) { +export default function (theme: any = {}) { const appStyle = {...defaultStyle, ...theme}; return StyleSheet.create({ header: { From 669ce5d56cc321e4f6e5897af6f527f495643700 Mon Sep 17 00:00:00 2001 From: Lidor Dafna Date: Sun, 11 Jul 2021 18:44:23 +0300 Subject: [PATCH 031/109] remove extra dot --- src/calendar/day/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/calendar/day/index.tsx b/src/calendar/day/index.tsx index fd4f00430a..6595953215 100644 --- a/src/calendar/day/index.tsx +++ b/src/calendar/day/index.tsx @@ -78,7 +78,7 @@ export default class Day extends Component { } getAccessibilityLabel = memoize((day, marking, isToday) => { - const today = _.get(XDate, 'locales.[XDate.defaultLocale].today'); + const today = _.get(XDate, 'locales[XDate.defaultLocale].today'); const formatAccessibilityLabel = _.get(XDate, 'locales[XDate.defaultLocale].formatAccessibilityLabel'); const markingLabel = this.getMarkingLabel(marking); From 6aba44f630e962ef1bc0f16d0f0bbb4f89ebae2b Mon Sep 17 00:00:00 2001 From: Lidor Dafna Date: Mon, 12 Jul 2021 10:56:37 +0300 Subject: [PATCH 032/109] fix typings --- src/calendar/header/index.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/calendar/header/index.tsx b/src/calendar/header/index.tsx index 79af257359..55e631acd6 100644 --- a/src/calendar/header/index.tsx +++ b/src/calendar/header/index.tsx @@ -20,7 +20,7 @@ import { import styleConstructor from './style'; type Direction = 'left' | 'right'; -interface CalendarHeaderProps { +export interface CalendarHeaderProps { theme?: any; firstDay?: number; displayLoadingIndicator?: boolean; @@ -46,7 +46,7 @@ interface CalendarHeaderProps { /** Apply custom disable color to selected day indexes */ disabledDaysIndexes?: number[]; /** Replace default month and year title with custom one. the function receive a date as parameter. */ - renderHeader?: any; + renderHeader?: (date?: XDate) => ReactNode; /** Provide aria-level for calendar heading for proper accessibility when used with web (react-native-web) */ webAriaLevel?: number; testID?: string; @@ -150,7 +150,7 @@ class CalendarHeader extends Component { renderWeekDays = memoize(weekDaysNames => { const {disabledDaysIndexes} = this.props; - return weekDaysNames.map((day: any, idx: any) => { + return weekDaysNames.map((day: string, idx: number) => { const dayStyle = [this.style.dayHeader]; if (_.includes(disabledDaysIndexes, idx)) { From 43ba55b243fb1832eb5ae00314008dd24ae1ae0f Mon Sep 17 00:00:00 2001 From: Lidor Dafna Date: Mon, 12 Jul 2021 12:40:21 +0300 Subject: [PATCH 033/109] add marking type --- src/calendar/day/index.tsx | 3 ++- src/calendar/day/marking/index.tsx | 5 ++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/calendar/day/index.tsx b/src/calendar/day/index.tsx index 6595953215..86f9387281 100644 --- a/src/calendar/day/index.tsx +++ b/src/calendar/day/index.tsx @@ -14,6 +14,7 @@ import {xdateToData} from '../../interface'; import {SELECT_DATE_SLOT} from '../../testIDs'; import BasicDay, {BasicDayProps} from './basic'; import PeriodDay from './period'; +import {MarkingProps} from './marking'; const basicDayPropsTypes = _.omit(BasicDay.propTypes, 'date'); @@ -47,7 +48,7 @@ export default class Day extends Component { ]); } - getMarkingLabel(marking: any) { + getMarkingLabel(marking: MarkingProps) { let label = ''; if (marking) { diff --git a/src/calendar/day/marking/index.tsx b/src/calendar/day/marking/index.tsx index 34a98c022e..4ebcbfc2e7 100644 --- a/src/calendar/day/marking/index.tsx +++ b/src/calendar/day/marking/index.tsx @@ -25,7 +25,7 @@ type PERIOD = { color?: string; }; -interface MarkingProps extends DotProps { +export interface MarkingProps extends DotProps { type?: MarkingTypes; theme?: Object; selected?: boolean; @@ -41,6 +41,9 @@ interface MarkingProps extends DotProps { dots?: DOT; //multi-period periods?: PERIOD; + startingDay?: boolean; + endingDay?: boolean; + accessibilityLabel?: string; } export default class Marking extends Component { From 785b07da836a93bd4d2183a82cb47153d0c8bd08 Mon Sep 17 00:00:00 2001 From: Lidor Dafna Date: Mon, 12 Jul 2021 15:11:19 +0300 Subject: [PATCH 034/109] add Theme type in commons/types --- src/calendar-list/item.tsx | 3 ++- src/calendar-list/style.ts | 7 +++---- src/calendar/day/basic/index.tsx | 5 +++-- src/calendar/day/basic/style.ts | 7 +++---- src/calendar/day/dot/index.tsx | 3 ++- src/calendar/day/dot/style.ts | 7 +++---- src/calendar/day/marking/index.tsx | 5 +++-- src/calendar/day/marking/style.ts | 7 +++---- src/calendar/day/period/index.tsx | 10 ++++++---- src/calendar/day/period/style.ts | 7 +++---- src/calendar/header/index.tsx | 7 ++++--- src/calendar/header/style.ts | 7 +++---- src/commons/types.ts | 25 +++++++++++++++++++++++++ 13 files changed, 63 insertions(+), 37 deletions(-) create mode 100644 src/commons/types.ts diff --git a/src/calendar-list/item.tsx b/src/calendar-list/item.tsx index f40da40ffe..fa4b9c4d5f 100644 --- a/src/calendar-list/item.tsx +++ b/src/calendar-list/item.tsx @@ -2,6 +2,7 @@ import memoize from 'memoize-one'; import React, {Component} from 'react'; import {Text, View} from 'react-native'; import PropTypes from 'prop-types'; +import {Theme} from '../commons/types'; // @ts-expect-error import {extractComponentProps} from '../component-updater'; @@ -15,7 +16,7 @@ export type CalendarListItemProps = CalendarProps & { calendarWidth?: number; calendarHeight?: number; horizontal?: boolean; - theme?: any; + theme?: Theme; } type CalendarListItemState = { diff --git a/src/calendar-list/style.ts b/src/calendar-list/style.ts index a0b354c949..d90b8e67de 100644 --- a/src/calendar-list/style.ts +++ b/src/calendar-list/style.ts @@ -1,10 +1,9 @@ import {Platform, StyleSheet} from 'react-native'; // @ts-expect-error import * as defaultStyle from '../style'; +import {Theme} from '../commons/types'; -const STYLESHEET_ID = 'stylesheet.calendar-list.main'; - -export default function getStyle(theme: any = {}) { +export default function getStyle(theme: Theme = {}) { const appStyle = {...defaultStyle, ...theme}; return StyleSheet.create({ flatListContainer: { @@ -36,6 +35,6 @@ export default function getStyle(theme: any = {}) { paddingLeft: 15, paddingRight: 15 }, - ...(theme[STYLESHEET_ID] || {}) + ...(theme.stylesheet?.['calendar-list']?.main || {}) }); } diff --git a/src/calendar/day/basic/index.tsx b/src/calendar/day/basic/index.tsx index 68f2a7955e..483cefded7 100644 --- a/src/calendar/day/basic/index.tsx +++ b/src/calendar/day/basic/index.tsx @@ -7,6 +7,7 @@ import {TouchableOpacity, Text, View} from 'react-native'; import {shouldUpdate} from '../../../component-updater'; import styleConstructor from './style'; import Marking, {MarkingTypes} from '../marking'; +import {Theme} from '../../../commons/types'; interface BasicDayProps { state?: 'selected' | 'disabled' | 'today'; @@ -15,7 +16,7 @@ interface BasicDayProps { /** Date marking style [simple/period/multi-dot/multi-period]. Default = 'simple' */ markingType: MarkingTypes; /** Theme object */ - theme: Object; + theme: Theme; /** onPress callback */ onPress: (date: Object) => void; /** onLongPress callback */ @@ -122,7 +123,7 @@ export default class BasicDay extends Component { getContainerStyle() { const {customStyles, selectedColor} = this.marking; - const style = [this.style.base]; + const style: object[] = [this.style.base]; if (this.isSelected()) { style.push(this.style.selected); diff --git a/src/calendar/day/basic/style.ts b/src/calendar/day/basic/style.ts index a4e3f2822e..de815e5b9f 100644 --- a/src/calendar/day/basic/style.ts +++ b/src/calendar/day/basic/style.ts @@ -1,10 +1,9 @@ import {StyleSheet, Platform} from 'react-native'; // @ts-expect-error import * as defaultStyle from '../../../style'; +import {Theme} from '../../../commons/types'; -const STYLESHEET_ID = 'stylesheet.day.basic'; - -export default function styleConstructor(theme: any = {}) { +export default function styleConstructor(theme: Theme = {}) { const appStyle = {...defaultStyle, ...theme}; return StyleSheet.create({ container: { @@ -66,6 +65,6 @@ export default function styleConstructor(theme: any = {}) { todayDot: { backgroundColor: appStyle.todayDotColor || appStyle.dotColor }, - ...(theme[STYLESHEET_ID] || {}) + ...(theme.stylesheet?.day?.basic || {}) }); } diff --git a/src/calendar/day/dot/index.tsx b/src/calendar/day/dot/index.tsx index d9909b6e48..2f8863c4ea 100644 --- a/src/calendar/day/dot/index.tsx +++ b/src/calendar/day/dot/index.tsx @@ -1,9 +1,10 @@ import React from 'react'; import {View} from 'react-native'; import styleConstructor from './style'; +import {Theme} from '../../../commons/types'; export interface DotProps { - theme?: Object; + theme?: Theme; color?: String; marked?: Boolean; selected?: Boolean; diff --git a/src/calendar/day/dot/style.ts b/src/calendar/day/dot/style.ts index c763926eef..6f13e530f7 100644 --- a/src/calendar/day/dot/style.ts +++ b/src/calendar/day/dot/style.ts @@ -1,10 +1,9 @@ import {StyleSheet} from 'react-native'; // @ts-expect-error import * as defaultStyle from '../../../style'; +import {Theme} from '../../../commons/types'; -const STYLESHEET_ID = 'stylesheet.dot'; - -export default function styleConstructor(theme: any = {}) { +export default function styleConstructor(theme: Theme = {}) { const appStyle = {...defaultStyle, ...theme}; return StyleSheet.create({ dot: { @@ -29,6 +28,6 @@ export default function styleConstructor(theme: any = {}) { todayDot: { backgroundColor: appStyle.todayDotColor || appStyle.dotColor }, - ...(theme[STYLESHEET_ID] || {}) + ...(theme.stylesheet?.dot || {}) }); } diff --git a/src/calendar/day/marking/index.tsx b/src/calendar/day/marking/index.tsx index 34a98c022e..0316eacc6c 100644 --- a/src/calendar/day/marking/index.tsx +++ b/src/calendar/day/marking/index.tsx @@ -4,6 +4,7 @@ import {View} from 'react-native'; import {shouldUpdate, extractComponentProps} from '../../../component-updater'; import styleConstructor from './style'; import Dot, {DotProps} from '../dot'; +import {Theme} from '../../../commons/types'; export enum MarkingTypes { DOT = 'dot', @@ -25,9 +26,9 @@ type PERIOD = { color?: string; }; -interface MarkingProps extends DotProps { +export interface MarkingProps extends DotProps { type?: MarkingTypes; - theme?: Object; + theme?: Theme; selected?: boolean; marked?: boolean; today?: boolean; diff --git a/src/calendar/day/marking/style.ts b/src/calendar/day/marking/style.ts index cac220d462..d1486d33d2 100644 --- a/src/calendar/day/marking/style.ts +++ b/src/calendar/day/marking/style.ts @@ -1,10 +1,9 @@ import {StyleSheet} from 'react-native'; // @ts-expect-error import * as defaultStyle from '../../style'; +import {Theme} from '../../../commons/types'; -const STYLESHEET_ID = 'stylesheet.marking'; - -export default function styleConstructor(theme: any = {}) { +export default function styleConstructor(theme: Theme = {}) { const appStyle = {...defaultStyle, ...theme}; return StyleSheet.create({ dots: { @@ -28,6 +27,6 @@ export default function styleConstructor(theme: any = {}) { borderBottomRightRadius: 2, marginRight: 4 }, - ...(theme[STYLESHEET_ID] || {}) + ...(theme.stylesheet?.marking || {}) }); } diff --git a/src/calendar/day/period/index.tsx b/src/calendar/day/period/index.tsx index 75c9958799..997932aef1 100644 --- a/src/calendar/day/period/index.tsx +++ b/src/calendar/day/period/index.tsx @@ -9,11 +9,13 @@ import {shouldUpdate} from '../../../component-updater'; import * as defaultStyle from '../../../style'; import styleConstructor from './style'; import Dot from '../dot'; +import {Theme} from '../../../commons/types'; + interface PeriodDayProps { state?: 'selected' | 'disabled' | 'today' | ''; marking?: any; - theme?: Object; + theme?: Theme; onPress?: (date?: Object) => void; onLongPress?: (date?: Object) => void; date?: Object; @@ -32,7 +34,7 @@ export default class PeriodDay extends Component{ onLongPress: PropTypes.func, date: PropTypes.object }; - theme: any; + theme: Theme; style: any; markingStyle: any; @@ -130,8 +132,8 @@ export default class PeriodDay extends Component{ const {state, marking} = this.props; const containerStyle = [this.style.base]; const textStyle = [this.style.text]; - let leftFillerStyle = {backgroundColor: undefined}; - let rightFillerStyle = {backgroundColor: undefined}; + let leftFillerStyle: {backgroundColor?: string} = {backgroundColor: undefined}; + let rightFillerStyle: {backgroundColor?: string} = {backgroundColor: undefined}; let fillerStyle = {}; let fillers; diff --git a/src/calendar/day/period/style.ts b/src/calendar/day/period/style.ts index 1597c91328..0cdc403328 100644 --- a/src/calendar/day/period/style.ts +++ b/src/calendar/day/period/style.ts @@ -1,12 +1,11 @@ import {StyleSheet} from 'react-native'; // @ts-expect-error import * as defaultStyle from '../../../style'; +import {Theme} from '../../../commons/types'; - -const STYLESHEET_ID = 'stylesheet.day.period'; const FILLER_HEIGHT = 34; -export default function styleConstructor(theme: any = {}) { +export default function styleConstructor(theme: Theme = {}) { const appStyle = {...defaultStyle, ...theme}; return StyleSheet.create({ wrapper: { @@ -76,6 +75,6 @@ export default function styleConstructor(theme: any = {}) { naText: { color: '#b6c1cd' }, - ...(theme[STYLESHEET_ID] || {}) + ...(theme.stylesheet?.day?.period || {}) }); } diff --git a/src/calendar/header/index.tsx b/src/calendar/header/index.tsx index 55e631acd6..fe20d46d34 100644 --- a/src/calendar/header/index.tsx +++ b/src/calendar/header/index.tsx @@ -4,7 +4,7 @@ import memoize from 'memoize-one'; import XDate from 'xdate'; import React, {Component, Fragment, ReactNode} from 'react'; -import {ActivityIndicator, Platform, View, Text, TouchableOpacity, Image, ColorValue, ViewStyle, AccessibilityActionEvent} from 'react-native'; +import {ActivityIndicator, Platform, View, Text, TouchableOpacity, Image, ViewStyle, AccessibilityActionEvent} from 'react-native'; // @ts-expect-error import {shouldUpdate} from '../../component-updater'; // @ts-expect-error @@ -18,10 +18,11 @@ import { // @ts-expect-error } from '../../testIDs'; import styleConstructor from './style'; +import {Theme} from '../../commons/types'; type Direction = 'left' | 'right'; export interface CalendarHeaderProps { - theme?: any; + theme?: Theme; firstDay?: number; displayLoadingIndicator?: boolean; showWeekNumbers?: boolean; @@ -227,7 +228,7 @@ class CalendarHeader extends Component { if (displayLoadingIndicator) { return ( ); diff --git a/src/calendar/header/style.ts b/src/calendar/header/style.ts index a182733fed..9f5cdec876 100644 --- a/src/calendar/header/style.ts +++ b/src/calendar/header/style.ts @@ -1,10 +1,9 @@ import {StyleSheet, Platform} from 'react-native'; // @ts-expect-error import * as defaultStyle from '../../style'; +import {Theme} from '../../commons/types'; -const STYLESHEET_ID = 'stylesheet.calendar.header'; - -export default function (theme: any = {}) { +export default function (theme: Theme = {}) { const appStyle = {...defaultStyle, ...theme}; return StyleSheet.create({ header: { @@ -59,6 +58,6 @@ export default function (theme: any = {}) { disabledDayHeader: { color: appStyle.textSectionTitleDisabledColor }, - ...(theme[STYLESHEET_ID] || {}) + ...(theme.stylesheet?.calendar?.header || {}) }); } diff --git a/src/commons/types.ts b/src/commons/types.ts new file mode 100644 index 0000000000..552ebe6934 --- /dev/null +++ b/src/commons/types.ts @@ -0,0 +1,25 @@ +import {ColorValue} from 'react-native'; +export interface Theme { + container?: object; + contentStyle?: object; + header?: object; + headerText?: object; + arrowButton?: object; + event?: object; + eventTitle?: object; + eventSummary?: object; + eventTimes?: object; + line?: object; + lineNow?: object; + timeLabel?: object; + todayTextColor?: string; + calendarBackground?: string; + indicatorColor?: ColorValue; + stylesheet?: { + calendar?: {header?: object}; + day?: {basic?: object; period?: object}; + dot?: object; + marking?: object; + 'calendar-list'?: {main?: object}; + }; +} From 02ae5d30102e0a7181382ddcb083dbd7c5649fd9 Mon Sep 17 00:00:00 2001 From: klazbaba Date: Tue, 13 Jul 2021 20:37:42 +0100 Subject: [PATCH 035/109] merged in master --- .eslintrc.js | 4 +- package.json | 4 + src/calendar-list/{index.js => index.tsx} | 124 ++++++++++---- src/calendar-list/{item.js => item.tsx} | 35 ++-- src/calendar-list/{style.js => style.ts} | 3 +- src/calendar/day/basic/index.tsx | 9 +- src/calendar/day/dot/{index.js => index.tsx} | 25 ++- src/calendar/day/dot/{style.js => style.ts} | 3 +- src/calendar/day/marking/index.js | 153 ------------------ src/calendar/day/marking/index.tsx | 140 ++++++++++++++++ .../day/marking/{style.js => style.ts} | 3 +- .../day/period/{index.js => index.tsx} | 35 ++-- .../day/period/{style.js => style.ts} | 3 +- src/dateutils.js | 2 +- src/day-state-manager.js | 4 +- 15 files changed, 313 insertions(+), 234 deletions(-) rename src/calendar-list/{index.js => index.tsx} (73%) rename src/calendar-list/{item.js => item.tsx} (80%) rename src/calendar-list/{style.js => style.ts} (92%) rename src/calendar/day/dot/{index.js => index.tsx} (61%) rename src/calendar/day/dot/{style.js => style.ts} (90%) delete mode 100644 src/calendar/day/marking/index.js create mode 100644 src/calendar/day/marking/index.tsx rename src/calendar/day/marking/{style.js => style.ts} (89%) rename src/calendar/day/period/{index.js => index.tsx} (88%) rename src/calendar/day/period/{style.js => style.ts} (95%) diff --git a/.eslintrc.js b/.eslintrc.js index 846d63f500..120c656787 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -10,7 +10,7 @@ module.exports = { describe: true }, extends: ['eslint:recommended'], - parser: 'babel-eslint', + parser: '@typescript-eslint/parser', parserOptions: { ecmaFeatures: { experimentalObjectRestSpread: true, @@ -18,7 +18,7 @@ module.exports = { }, sourceType: 'module' }, - plugins: ['react', 'react-native', 'jest'], + plugins: ['react', 'react-native', 'jest', '@typescript-eslint'], rules: { 'react-native/no-inline-styles': 1, 'linebreak-style': ['error', 'unix'], diff --git a/package.json b/package.json index 3d115e3093..7d2f300e7e 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,7 @@ "scripts": { "build": "xcodebuild -project ios/CalendarsExample.xcodeproj build", "build:ts": "tsc", + "build:dev": "tsc --noEmit", "e2e": "node ./scripts/test-e2e.js --release", "test": "npm run lint && npm run unit && npm run e2e", "unit": "jest", @@ -42,7 +43,10 @@ "@babel/runtime": "^7.12.5", "@types/lodash": "^4.14.170", "@types/react-native": "^0.63.52", + "@types/xdate": "^0.8.32", "@welldone-software/why-did-you-render": "^6.0.3", + "@typescript-eslint/eslint-plugin": "^2.13.0", + "@typescript-eslint/parser": "^2.13.0", "babel-eslint": "^10.1.0", "babel-jest": "^26.6.3", "detox": "^18.0.0", diff --git a/src/calendar-list/index.js b/src/calendar-list/index.tsx similarity index 73% rename from src/calendar-list/index.js rename to src/calendar-list/index.tsx index f0273144f6..88c027df9f 100644 --- a/src/calendar-list/index.js +++ b/src/calendar-list/index.tsx @@ -1,21 +1,69 @@ import _ from 'lodash'; -import PropTypes from 'prop-types'; import XDate from 'xdate'; +import PropTypes from 'prop-types'; import React, {Component} from 'react'; import {FlatList, Platform, Dimensions, View} from 'react-native'; - +// @ts-expect-error import {extractComponentProps} from '../component-updater'; +// @ts-expect-error import {xdateToData, parseDate} from '../interface'; import {page, sameDate} from '../dateutils'; import {STATIC_HEADER} from '../testIDs'; import styleConstructor from './style'; -import Calendar from '../calendar'; + +// @ts-expect-error +import Calendar, {CalendarProps} from '../calendar'; import CalendarListItem from './item'; +// @ts-expect-error import CalendarHeader from '../calendar/header/index'; const {width} = Dimensions.get('window'); +export type CalendarListProps = CalendarProps & { + /** Max amount of months allowed to scroll to the past. Default = 50 */ + pastScrollRange?: number; + /** Max amount of months allowed to scroll to the future. Default = 50 */ + futureScrollRange?: number; + /** Used when calendar scroll is horizontal, default is device width, pagination should be disabled */ + calendarWidth?: number; + /** Dynamic calendar height */ + calendarHeight?: number; + /** Style for the List item (the calendar) */ + calendarStyle?: number | Array | Object; + /** Whether to use static header that will not scroll with the list (horizontal only) */ + staticHeader?: boolean; + /** Enable or disable vertical / horizontal scroll indicator. Default = false */ + showScrollIndicator?: boolean; + /** Whether to animate the auto month scroll */ + animateScroll?: boolean; + /** Enable or disable scrolling of calendar list */ + scrollEnabled?: boolean; + /** When true, the calendar list scrolls to top when the status bar is tapped. Default = true */ + scrollsToTop?: boolean; + /** Enable or disable paging on scroll */ + pagingEnabled?: boolean; + /** Whether the scroll is horizontal */ + horizontal?: boolean; + /** Should Keyboard persist taps */ + keyboardShouldPersistTaps?: 'never' | 'always' | 'handled'; + /** A custom key extractor for the generated calendar months */ + keyExtractor?: (item: any, index: number) => string; + /** How far from the end to trigger the onEndReached callback */ + onEndReachedThreshold?: number; + /** Called once when the scroll position gets within onEndReachedThreshold */ + onEndReached?: () => void; +}; + +type XDateAndBump = XDate & {propBump?: number}; + +type CalendarListState = { + rows: Array; + texts: Array; + openDate: XDate; + currentMonth: XDate; +}; + /** * @description: Calendar List component for both vertical and horizontal calendars * @extends: Calendar @@ -23,7 +71,7 @@ const {width} = Dimensions.get('window'); * @example: https://github.com/wix/react-native-calendars/blob/master/example/src/screens/calendarsList.js * @gif: https://github.com/wix/react-native-calendars/blob/master/demo/calendar-list.gif */ -class CalendarList extends Component { +class CalendarList extends Component { static displayName = 'CalendarList'; static propTypes = { @@ -72,21 +120,23 @@ class CalendarList extends Component { scrollsToTop: false, scrollEnabled: true, removeClippedSubviews: Platform.OS === 'android', - keyExtractor: (item, index) => String(index) + keyExtractor: (_: any, index: number) => String(index) + }; + + style: any; + listView: FlatList | undefined | null; + viewabilityConfig = { + itemVisiblePercentThreshold: 20 }; - constructor(props) { + constructor(props: CalendarListProps) { super(props); this.style = styleConstructor(props.theme); - this.viewabilityConfig = { - itemVisiblePercentThreshold: 20 - }; - const rows = []; const texts = []; - const date = parseDate(props.current) || XDate(); + const date = parseDate(props.current) || new XDate(); for (let i = 0; i <= props.pastScrollRange + props.futureScrollRange; i++) { const rangeDate = date.clone().addMonths(i - props.pastScrollRange, true); @@ -114,7 +164,7 @@ class CalendarList extends Component { }; } - componentDidUpdate(prevProps) { + componentDidUpdate(prevProps: CalendarListProps) { const prevCurrent = parseDate(prevProps.current); const current = parseDate(this.props.current); @@ -123,22 +173,24 @@ class CalendarList extends Component { } } - static getDerivedStateFromProps(nextProps, prevState) { - const rowclone = prevState.rows; - const newrows = []; - - for (let i = 0; i < rowclone.length; i++) { - let val = prevState.texts[i]; - if (rowclone[i].getTime) { - val = rowclone[i].clone(); - val.propbump = rowclone[i].propbump ? rowclone[i].propbump + 1 : 1; + static getDerivedStateFromProps(_: CalendarListProps, prevState: CalendarListState) { + const rowClone = prevState.rows; + const newRows = []; + + for (let i = 0; i < rowClone.length; i++) { + let val: XDate | string = prevState.texts[i]; + // @ts-ignore + if (rowClone[i].getTime) { + val = rowClone[i].clone(); + // @ts-ignore + val.propBump = rowClone[i].propBump ? rowClone[i].propBump + 1 : 1; } - newrows.push(val); + newRows.push(val); } - return {rows: newrows}; + return {rows: newRows}; } - scrollToDay(d, offset, animated) { + scrollToDay(d: XDate, offset: number, animated: boolean) { const {horizontal, calendarHeight, calendarWidth, pastScrollRange, firstDay} = this.props; const day = parseDate(d); const diffMonths = Math.round(this.state.openDate.clone().setDate(1).diffMonths(day.clone().setDate(1))); @@ -156,10 +208,10 @@ class CalendarList extends Component { } } } - this.listView.scrollToOffset({offset: scrollAmount, animated}); + this.listView?.scrollToOffset({offset: scrollAmount, animated}); } - scrollToMonth = m => { + scrollToMonth = (m: XDate) => { const {horizontal, calendarHeight, calendarWidth, pastScrollRange, animateScroll = false} = this.props; const month = parseDate(m); const scrollTo = month || this.state.openDate; @@ -167,10 +219,10 @@ class CalendarList extends Component { const size = horizontal ? calendarWidth : calendarHeight; const scrollAmount = size * pastScrollRange + diffMonths * size; - this.listView.scrollToOffset({offset: scrollAmount, animated: animateScroll}); + this.listView?.scrollToOffset({offset: scrollAmount, animated: animateScroll}); }; - getItemLayout = (data, index) => { + getItemLayout = (_: Array | undefined | null, index: number) => { const {horizontal, calendarHeight, calendarWidth} = this.props; return { @@ -180,16 +232,16 @@ class CalendarList extends Component { }; }; - getMonthIndex(month) { + getMonthIndex(month: XDate) { let diffMonths = this.state.openDate.diffMonths(month) + this.props.pastScrollRange; return diffMonths; } - addMonth = count => { + addMonth = (count: number) => { this.updateMonth(this.state.currentMonth.clone().addMonths(count, true)); }; - updateMonth(day, doNotTriggerListeners) { + updateMonth(day: XDate, doNotTriggerListeners = false) { if (day.toString('yyyy MM') === this.state.currentMonth.toString('yyyy MM')) { return; } @@ -206,8 +258,8 @@ class CalendarList extends Component { }); } - onViewableItemsChanged = ({viewableItems}) => { - function rowIsCloseToViewable(index, distance) { + onViewableItemsChanged = ({viewableItems}: any) => { + function rowIsCloseToViewable(index: number, distance: number) { for (let i = 0; i < viewableItems.length; i++) { if (Math.abs(index - parseInt(viewableItems[i].index)) <= distance) { return true; @@ -221,7 +273,7 @@ class CalendarList extends Component { const visibleMonths = []; for (let i = 0; i < rowclone.length; i++) { - let val = rowclone[i]; + let val: XDate | string = rowclone[i]; const rowShouldBeRendered = rowIsCloseToViewable(i, 1); if (rowShouldBeRendered && !rowclone[i].getTime) { @@ -238,12 +290,13 @@ class CalendarList extends Component { _.invoke(this.props, 'onVisibleMonthsChange', visibleMonths); this.setState({ + // @ts-ignore rows: newrows, currentMonth: parseDate(visibleMonths[0]) }); }; - renderItem = ({item}) => { + renderItem = ({item}: any) => { const {calendarStyle, horizontal, calendarWidth, testID, ...others} = this.props; return ( @@ -287,6 +340,7 @@ class CalendarList extends Component { (this.listView = c)} style={[this.style.container, style]} + // @ts-ignore initialListSize={pastScrollRange + futureScrollRange + 1} // ListView deprecated data={this.state.rows} renderItem={this.renderItem} diff --git a/src/calendar-list/item.js b/src/calendar-list/item.tsx similarity index 80% rename from src/calendar-list/item.js rename to src/calendar-list/item.tsx index 61781bf90f..f40da40ffe 100644 --- a/src/calendar-list/item.js +++ b/src/calendar-list/item.tsx @@ -1,14 +1,29 @@ -import PropTypes from 'prop-types'; import memoize from 'memoize-one'; - import React, {Component} from 'react'; import {Text, View} from 'react-native'; +import PropTypes from 'prop-types'; +// @ts-expect-error import {extractComponentProps} from '../component-updater'; -import Calendar from '../calendar'; + +// @ts-expect-error +import Calendar, {CalendarProps} from '../calendar'; import styleConstructor from './style'; -class CalendarListItem extends Component { +export type CalendarListItemProps = CalendarProps & { + item: any; + calendarWidth?: number; + calendarHeight?: number; + horizontal?: boolean; + theme?: any; +} + +type CalendarListItemState = { + hideArrows: boolean; + hideExtraDays: boolean; +} + +class CalendarListItem extends Component { static displayName = 'IGNORE'; static propTypes = { @@ -24,20 +39,22 @@ class CalendarListItem extends Component { hideExtraDays: true }; - constructor(props) { + style: any; + + constructor(props: CalendarListItemProps) { super(props); this.style = styleConstructor(props.theme); } - shouldComponentUpdate(nextProps) { + shouldComponentUpdate(nextProps: CalendarListItemProps) { const r1 = this.props.item; const r2 = nextProps.item; - return r1.toString('yyyy MM') !== r2.toString('yyyy MM') || !!(r2.propbump && r2.propbump !== r1.propbump); + return r1.toString('yyyy MM') !== r2.toString('yyyy MM') || !!(r2.propBump && r2.propBump !== r1.propBump); } - onPressArrowLeft = (_, month) => { + onPressArrowLeft = (_: any, month: any) => { const {onPressArrowLeft, scrollToMonth} = this.props; const monthClone = month.clone(); @@ -56,7 +73,7 @@ class CalendarListItem extends Component { } }; - onPressArrowRight = (_, month) => { + onPressArrowRight = (_: any, month: any) => { const {onPressArrowRight, scrollToMonth} = this.props; const monthClone = month.clone(); diff --git a/src/calendar-list/style.js b/src/calendar-list/style.ts similarity index 92% rename from src/calendar-list/style.js rename to src/calendar-list/style.ts index 2fce57bb3f..a0b354c949 100644 --- a/src/calendar-list/style.js +++ b/src/calendar-list/style.ts @@ -1,9 +1,10 @@ import {Platform, StyleSheet} from 'react-native'; +// @ts-expect-error import * as defaultStyle from '../style'; const STYLESHEET_ID = 'stylesheet.calendar-list.main'; -export default function getStyle(theme = {}) { +export default function getStyle(theme: any = {}) { const appStyle = {...defaultStyle, ...theme}; return StyleSheet.create({ flatListContainer: { diff --git a/src/calendar/day/basic/index.tsx b/src/calendar/day/basic/index.tsx index d68875f0a9..68f2a7955e 100644 --- a/src/calendar/day/basic/index.tsx +++ b/src/calendar/day/basic/index.tsx @@ -6,8 +6,7 @@ import {TouchableOpacity, Text, View} from 'react-native'; // @ts-expect-error import {shouldUpdate} from '../../../component-updater'; import styleConstructor from './style'; -// @ts-expect-error -import Marking from '../marking'; +import Marking, {MarkingTypes} from '../marking'; interface BasicDayProps { state?: 'selected' | 'disabled' | 'today'; @@ -110,15 +109,15 @@ export default class BasicDay extends Component { } isMultiDot() { - return this.props.markingType === Marking.markingTypes.multiDot; + return this.props.markingType === Marking.markingTypes.MULTI_DOT; } isMultiPeriod() { - return this.props.markingType === Marking.markingTypes.multiPeriod; + return this.props.markingType === Marking.markingTypes.MULTI_PERIOD; } isCustom() { - return this.props.markingType === Marking.markingTypes.custom; + return this.props.markingType === Marking.markingTypes.CUSTOM; } getContainerStyle() { diff --git a/src/calendar/day/dot/index.js b/src/calendar/day/dot/index.tsx similarity index 61% rename from src/calendar/day/dot/index.js rename to src/calendar/day/dot/index.tsx index 627db933a2..d9909b6e48 100644 --- a/src/calendar/day/dot/index.js +++ b/src/calendar/day/dot/index.tsx @@ -1,9 +1,17 @@ -import PropTypes from 'prop-types'; import React from 'react'; import {View} from 'react-native'; import styleConstructor from './style'; -const Dot = ({theme, marked, disabled, color, today, selected}) => { +export interface DotProps { + theme?: Object; + color?: String; + marked?: Boolean; + selected?: Boolean; + disabled?: Boolean; + today?: Boolean; +} + +const Dot = ({theme, marked, disabled, color, today, selected}: DotProps) => { const style = styleConstructor(theme); const dotStyle = [style.dot]; @@ -26,17 +34,8 @@ const Dot = ({theme, marked, disabled, color, today, selected}) => { dotStyle.push({backgroundColor: color}); } } - - return ; + + return ; }; export default Dot; - -Dot.propTypes = { - theme: PropTypes.object, - color: PropTypes.string, - marked: PropTypes.bool, - selected: PropTypes.bool, - disabled: PropTypes.bool, - today: PropTypes.bool -}; diff --git a/src/calendar/day/dot/style.js b/src/calendar/day/dot/style.ts similarity index 90% rename from src/calendar/day/dot/style.js rename to src/calendar/day/dot/style.ts index b9d833e3ef..c763926eef 100644 --- a/src/calendar/day/dot/style.js +++ b/src/calendar/day/dot/style.ts @@ -1,9 +1,10 @@ import {StyleSheet} from 'react-native'; +// @ts-expect-error import * as defaultStyle from '../../../style'; const STYLESHEET_ID = 'stylesheet.dot'; -export default function styleConstructor(theme = {}) { +export default function styleConstructor(theme: any = {}) { const appStyle = {...defaultStyle, ...theme}; return StyleSheet.create({ dot: { diff --git a/src/calendar/day/marking/index.js b/src/calendar/day/marking/index.js deleted file mode 100644 index 3aaf87436e..0000000000 --- a/src/calendar/day/marking/index.js +++ /dev/null @@ -1,153 +0,0 @@ -import PropTypes from 'prop-types'; -import React, {Component} from 'react'; -import {View} from 'react-native'; -import {shouldUpdate, extractComponentProps} from '../../../component-updater'; -import styleConstructor from './style'; -import Dot from '../dot'; - - -const MARKING_TYPES = { - dot: 'dot', - multiDot: 'multi-dot', - period: 'period', - multiPeriod: 'multi-period', - custom: 'custom' -}; - -const DOT = { - key: PropTypes.string, - color: PropTypes.string, - selectedDotColor: PropTypes.string -}; - -const PERIOD = { - startingDay: PropTypes.bool, - endingDay: PropTypes.bool, - color: PropTypes.string -}; - - -export default class Marking extends Component { - static displayName = 'IGNORE'; - - static propTypes = { - ...Dot.propTypes, - type: PropTypes.oneOf(Object.values(MARKING_TYPES)), - theme: PropTypes.object, - selected: PropTypes.bool, - marked: PropTypes.bool, - today: PropTypes.bool, - disabled: PropTypes.bool, - disableTouchEvent: PropTypes.bool, - activeOpacity: PropTypes.number, - selectedColor: PropTypes.string, - selectedTextColor: PropTypes.string, - dotColor: PropTypes.string, - //multi-dot - dots: PropTypes.arrayOf(PropTypes.shape(DOT)), - //multi-period - periods: PropTypes.arrayOf(PropTypes.shape(PERIOD)) - }; - - static markingTypes = MARKING_TYPES; - - constructor(props) { - super(props); - - this.style = styleConstructor(props.theme); - } - - shouldComponentUpdate(nextProps) { - return shouldUpdate(this.props, nextProps, [ - 'type', - 'selected', - 'marked', - 'today', - 'disabled', - 'disableTouchEvent', - 'activeOpacity', - 'selectedColor', - 'selectedTextColor', - 'dotColor', - 'dots', - 'periods' - ]); - } - - getItems(items) { - const {type} = this.props; - - if (items && Array.isArray(items) && items.length > 0) { - // Filter out items so that we process only those which have color property - const validItems = items.filter(d => d && d.color); - - return validItems.map((item, index) => { - return type === MARKING_TYPES.multiDot ? this.renderDot(index, item) : this.renderPeriod(index, item); - }); - } - } - - renderMarkingByType() { - const {type, dots, periods} = this.props; - - switch (type) { - case MARKING_TYPES.multiDot: - return this.renderMultiMarkings(this.style.dots, dots); - case MARKING_TYPES.multiPeriod: - return this.renderMultiMarkings(this.style.periods, periods); - default: - return this.renderDot(); - } - } - - renderMultiMarkings(containerStyle, items) { - return ( - - {this.getItems(items)} - - ); - } - - renderPeriod(index, item) { - const {color, startingDay, endingDay} = item; - const style = [ - this.style.period, - { - backgroundColor: color - } - ]; - if (startingDay) { - style.push(this.style.startingDay); - } - if (endingDay) { - style.push(this.style.endingDay); - } - return ; - } - - renderDot(index, item) { - const {selected, dotColor} = this.props; - const dotProps = extractComponentProps(Dot, this.props); - let key = index; - let color = dotColor; - - if (item) { - if (item.key) { - key = item.key; - } - color = selected && item.selectedDotColor ? item.selectedDotColor : item.color; - } - - return ( - - ); - } - - render() { - return this.renderMarkingByType(); - } -} diff --git a/src/calendar/day/marking/index.tsx b/src/calendar/day/marking/index.tsx new file mode 100644 index 0000000000..34a98c022e --- /dev/null +++ b/src/calendar/day/marking/index.tsx @@ -0,0 +1,140 @@ +import React, {Component} from 'react'; +import {View} from 'react-native'; +// @ts-expect-error +import {shouldUpdate, extractComponentProps} from '../../../component-updater'; +import styleConstructor from './style'; +import Dot, {DotProps} from '../dot'; + +export enum MarkingTypes { + DOT = 'dot', + MULTI_DOT = 'multi-dot', + PERIOD = 'period', + MULTI_PERIOD = 'multi-period', + CUSTOM = 'custom' +} + +type DOT = { + key?: string; + color?: string; + selectedDotColor?: string; +}; + +type PERIOD = { + startingDay?: boolean; + endingDay?: boolean; + color?: string; +}; + +interface MarkingProps extends DotProps { + type?: MarkingTypes; + theme?: Object; + selected?: boolean; + marked?: boolean; + today?: boolean; + disabled?: boolean; + disableTouchEvent?: boolean; + activeOpacity?: number; + selectedColor?: string; + selectedTextColor?: string; + dotColor?: string; + //multi-dot + dots?: DOT; + //multi-period + periods?: PERIOD; +} + +export default class Marking extends Component { + static displayName = 'IGNORE'; + + static markingTypes = MarkingTypes; + style: any; + + constructor(props: MarkingProps) { + super(props); + + this.style = styleConstructor(props.theme); + } + + shouldComponentUpdate(nextProps: MarkingProps) { + return shouldUpdate(this.props, nextProps, [ + 'type', + 'selected', + 'marked', + 'today', + 'disabled', + 'disableTouchEvent', + 'activeOpacity', + 'selectedColor', + 'selectedTextColor', + 'dotColor', + 'dots', + 'periods' + ]); + } + + getItems(items: DOT | PERIOD) { + const {type} = this.props; + + if (items && Array.isArray(items) && items.length > 0) { + // Filter out items so that we process only those which have color property + const validItems = items.filter(d => d && d.color); + + return validItems.map((item, index) => { + return type === MarkingTypes.MULTI_DOT ? this.renderDot(index, item) : this.renderPeriod(index, item); + }); + } + } + + renderMarkingByType() { + const {type, dots, periods} = this.props; + switch (type) { + case MarkingTypes.MULTI_DOT: + return this.renderMultiMarkings(this.style.dots, dots); + case MarkingTypes.MULTI_PERIOD: + return this.renderMultiMarkings(this.style.periods, periods); + default: + return this.renderDot(); + } + } + + renderMultiMarkings(containerStyle: Object, items: any) { + return {this.getItems(items)}; + } + + renderPeriod(index: number, item: any) { + const {color, startingDay, endingDay} = item; + const style = [ + this.style.period, + { + backgroundColor: color + } + ]; + if (startingDay) { + style.push(this.style.startingDay); + } + if (endingDay) { + style.push(this.style.endingDay); + } + return ; + } + + renderDot(index?: number, item?: any) { + const {selected, dotColor} = this.props; + const dotProps = extractComponentProps(Dot, this.props); + let key = index; + let color = dotColor; + + if (item) { + if (item.key) { + key = item.key; + } + color = selected && item.selectedDotColor ? item.selectedDotColor : item.color; + } + + return ; + } + + render() { + return this.renderMarkingByType(); + } +} diff --git a/src/calendar/day/marking/style.js b/src/calendar/day/marking/style.ts similarity index 89% rename from src/calendar/day/marking/style.js rename to src/calendar/day/marking/style.ts index 61cbb0e70e..cac220d462 100644 --- a/src/calendar/day/marking/style.js +++ b/src/calendar/day/marking/style.ts @@ -1,9 +1,10 @@ import {StyleSheet} from 'react-native'; +// @ts-expect-error import * as defaultStyle from '../../style'; const STYLESHEET_ID = 'stylesheet.marking'; -export default function styleConstructor(theme = {}) { +export default function styleConstructor(theme: any = {}) { const appStyle = {...defaultStyle, ...theme}; return StyleSheet.create({ dots: { diff --git a/src/calendar/day/period/index.js b/src/calendar/day/period/index.tsx similarity index 88% rename from src/calendar/day/period/index.js rename to src/calendar/day/period/index.tsx index ac7cd4b09c..75c9958799 100644 --- a/src/calendar/day/period/index.js +++ b/src/calendar/day/period/index.tsx @@ -3,13 +3,25 @@ import PropTypes from 'prop-types'; import React, {Component} from 'react'; import {TouchableWithoutFeedback, Text, View} from 'react-native'; - +// @ts-expect-error import {shouldUpdate} from '../../../component-updater'; +// @ts-expect-error import * as defaultStyle from '../../../style'; import styleConstructor from './style'; import Dot from '../dot'; -export default class PeriodDay extends Component { +interface PeriodDayProps { + state?: 'selected' | 'disabled' | 'today' | ''; + marking?: any; + theme?: Object; + onPress?: (date?: Object) => void; + onLongPress?: (date?: Object) => void; + date?: Object; + accessibilityLabel?: string; + testID?: string; +} + +export default class PeriodDay extends Component{ static displayName = 'IGNORE'; static propTypes = { @@ -20,8 +32,11 @@ export default class PeriodDay extends Component { onLongPress: PropTypes.func, date: PropTypes.object }; + theme: any; + style: any; + markingStyle: any; - constructor(props) { + constructor(props: PeriodDayProps) { super(props); this.theme = {...defaultStyle, ...(props.theme || {})}; @@ -31,14 +46,14 @@ export default class PeriodDay extends Component { } onPress = () => { - this.props.onPress(this.props.date); + this.props.onPress?.(this.props.date); }; onLongPress = () => { - this.props.onLongPress(this.props.date); + this.props.onLongPress?.(this.props.date); }; - shouldComponentUpdate(nextProps) { + shouldComponentUpdate(nextProps: PeriodDayProps) { const newMarkingStyle = this.getDrawingStyle(nextProps.marking); if (!_.isEqual(this.markingStyle, newMarkingStyle)) { this.markingStyle = newMarkingStyle; @@ -48,8 +63,8 @@ export default class PeriodDay extends Component { return shouldUpdate(this.props, nextProps, ['children', 'state', 'marking', 'onPress', 'onLongPress', 'date']); } - getDrawingStyle(marking) { - const defaultStyle = {textStyle: {}, containerStyle: {}}; + getDrawingStyle(marking: any) { + const defaultStyle = {textStyle: {color: undefined}, containerStyle: {}}; if (!marking) { return defaultStyle; @@ -115,8 +130,8 @@ export default class PeriodDay extends Component { const {state, marking} = this.props; const containerStyle = [this.style.base]; const textStyle = [this.style.text]; - let leftFillerStyle = {}; - let rightFillerStyle = {}; + let leftFillerStyle = {backgroundColor: undefined}; + let rightFillerStyle = {backgroundColor: undefined}; let fillerStyle = {}; let fillers; diff --git a/src/calendar/day/period/style.js b/src/calendar/day/period/style.ts similarity index 95% rename from src/calendar/day/period/style.js rename to src/calendar/day/period/style.ts index d62a9b2a55..1597c91328 100644 --- a/src/calendar/day/period/style.js +++ b/src/calendar/day/period/style.ts @@ -1,11 +1,12 @@ import {StyleSheet} from 'react-native'; +// @ts-expect-error import * as defaultStyle from '../../../style'; const STYLESHEET_ID = 'stylesheet.day.period'; const FILLER_HEIGHT = 34; -export default function styleConstructor(theme={}) { +export default function styleConstructor(theme: any = {}) { const appStyle = {...defaultStyle, ...theme}; return StyleSheet.create({ wrapper: { diff --git a/src/dateutils.js b/src/dateutils.js index 19893dd103..8cf847a352 100644 --- a/src/dateutils.js +++ b/src/dateutils.js @@ -1,5 +1,5 @@ const XDate = require('xdate'); -import {parseDate} from './interface'; +const {parseDate} = require('./interface'); function sameMonth(a, b) { return ( diff --git a/src/day-state-manager.js b/src/day-state-manager.js index 9fb7abb581..8994d976df 100644 --- a/src/day-state-manager.js +++ b/src/day-state-manager.js @@ -1,5 +1,5 @@ -import {isToday, isDateNotInTheRange, sameMonth} from './dateutils'; -import {parseDate, toMarkingFormat} from './interface'; +const {isToday, isDateNotInTheRange, sameMonth} = require('./dateutils'); +const {parseDate, toMarkingFormat} = require('./interface'); function getState(day, current, props) { const {minDate, maxDate, disabledByDefault, context} = props; From e7cd450c3a5ffd359e1785e638db4ea045c83cd1 Mon Sep 17 00:00:00 2001 From: Lidor Dafna Date: Thu, 15 Jul 2021 11:49:18 +0300 Subject: [PATCH 036/109] fix theme typs --- src/calendar/day/period/index.tsx | 9 ++++----- src/calendar/header/index.tsx | 4 ++-- src/commons/types.ts | 27 ++++++++++++++++++++++++++- 3 files changed, 32 insertions(+), 8 deletions(-) diff --git a/src/calendar/day/period/index.tsx b/src/calendar/day/period/index.tsx index 997932aef1..d7dd741ea9 100644 --- a/src/calendar/day/period/index.tsx +++ b/src/calendar/day/period/index.tsx @@ -2,7 +2,7 @@ import _ from 'lodash'; import PropTypes from 'prop-types'; import React, {Component} from 'react'; -import {TouchableWithoutFeedback, Text, View} from 'react-native'; +import {TouchableWithoutFeedback, Text, View, ViewStyle} from 'react-native'; // @ts-expect-error import {shouldUpdate} from '../../../component-updater'; // @ts-expect-error @@ -11,7 +11,6 @@ import styleConstructor from './style'; import Dot from '../dot'; import {Theme} from '../../../commons/types'; - interface PeriodDayProps { state?: 'selected' | 'disabled' | 'today' | ''; marking?: any; @@ -23,7 +22,7 @@ interface PeriodDayProps { testID?: string; } -export default class PeriodDay extends Component{ +export default class PeriodDay extends Component { static displayName = 'IGNORE'; static propTypes = { @@ -132,8 +131,8 @@ export default class PeriodDay extends Component{ const {state, marking} = this.props; const containerStyle = [this.style.base]; const textStyle = [this.style.text]; - let leftFillerStyle: {backgroundColor?: string} = {backgroundColor: undefined}; - let rightFillerStyle: {backgroundColor?: string} = {backgroundColor: undefined}; + let leftFillerStyle: ViewStyle = {backgroundColor: undefined}; + let rightFillerStyle: ViewStyle = {backgroundColor: undefined}; let fillerStyle = {}; let fillers; diff --git a/src/calendar/header/index.tsx b/src/calendar/header/index.tsx index fe20d46d34..acee660cd5 100644 --- a/src/calendar/header/index.tsx +++ b/src/calendar/header/index.tsx @@ -4,7 +4,7 @@ import memoize from 'memoize-one'; import XDate from 'xdate'; import React, {Component, Fragment, ReactNode} from 'react'; -import {ActivityIndicator, Platform, View, Text, TouchableOpacity, Image, ViewStyle, AccessibilityActionEvent} from 'react-native'; +import {ActivityIndicator, Platform, View, Text, TouchableOpacity, Image, ViewStyle, AccessibilityActionEvent, ColorValue} from 'react-native'; // @ts-expect-error import {shouldUpdate} from '../../component-updater'; // @ts-expect-error @@ -228,7 +228,7 @@ class CalendarHeader extends Component { if (displayLoadingIndicator) { return ( ); diff --git a/src/commons/types.ts b/src/commons/types.ts index 552ebe6934..10ccd0fb04 100644 --- a/src/commons/types.ts +++ b/src/commons/types.ts @@ -14,7 +14,7 @@ export interface Theme { timeLabel?: object; todayTextColor?: string; calendarBackground?: string; - indicatorColor?: ColorValue; + indicatorColor?: ColorValue | object; stylesheet?: { calendar?: {header?: object}; day?: {basic?: object; period?: object}; @@ -22,4 +22,29 @@ export interface Theme { marking?: object; 'calendar-list'?: {main?: object}; }; + textSectionTitleColor?: string; + textSectionTitleDisabledColor?: string; + dayTextColor?: string; + selectedDayTextColor?: string; + monthTextColor?: string; + selectedDayBackgroundColor?: string; + arrowColor?: string; + textDisabledColor?: string; + backgroundColor?: string; + dotColor?: string; + selectedDotColor?: string; + disabledArrowColor?: string; + textDayFontFamily?: string; + textMonthFontFamily?: string; + textDayHeaderFontFamily?: string; + textDayFontWeight?: string; + textMonthFontWeight?: string; + textDayHeaderFontWeight?: string; + textDayFontSize?: number; + textMonthFontSize?: number; + textDayHeaderFontSize?: number; + agendaDayTextColor?: string; + agendaDayNumColor?: string; + agendaTodayColor?: string; + agendaKnobColor?: string; } From a970b2da820413c3bad0483110ed4bd3c598e3df Mon Sep 17 00:00:00 2001 From: Lidor Dafna Date: Thu, 15 Jul 2021 12:09:08 +0300 Subject: [PATCH 037/109] add keys to Theme type --- src/commons/types.ts | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/commons/types.ts b/src/commons/types.ts index 10ccd0fb04..b81d6b9b3c 100644 --- a/src/commons/types.ts +++ b/src/commons/types.ts @@ -47,4 +47,24 @@ export interface Theme { agendaDayNumColor?: string; agendaTodayColor?: string; agendaKnobColor?: string; + foregroundColor?: string; + separatorColor?: string; + processedColor?: string; + processingColor?: string; + failedColor?: string; + textSecondaryColor?: string; + textDefaultColor?: string; + textColor?: string; + textLinkColor?: string; + todayButtonFontFamily?: string; + todayButtonFontWeight?: string; + todayButtonFontSize?: number; + textDayStyle?: object; + dotStyle?: object; + arrowStyle?: object; + todayBackgroundColor?: string; + disabledDotColor?: string; + todayDotColor?: string; + todayButtonTextColor?: string; + todayButtonPosition?: string; } From 6b64969ff94f70f9a5af5bfcb22a0694a7732ecc Mon Sep 17 00:00:00 2001 From: vidmantas0010 Date: Thu, 15 Jul 2021 13:43:11 +0300 Subject: [PATCH 038/109] TS/Agenda component --- src/agenda/{index.js => index.tsx} | 136 +++++++++++------- ...orm-style.ios.js => platform-style.ios.ts} | 7 +- .../{platform-style.js => platform-style.ts} | 7 +- .../reservation-list/{index.js => index.tsx} | 118 ++++++++------- .../{reservation.js => reservation.tsx} | 47 +++--- .../reservation-list/{style.js => style.ts} | 2 +- src/agenda/{style.js => style.ts} | 4 +- src/calendar-list/style.ts | 1 - src/calendar/day/basic/style.ts | 1 - src/calendar/day/dot/style.ts | 1 - src/calendar/day/period/index.tsx | 1 - src/calendar/day/period/style.ts | 3 +- src/{style.js => style.ts} | 0 13 files changed, 189 insertions(+), 139 deletions(-) rename src/agenda/{index.js => index.tsx} (79%) rename src/agenda/{platform-style.ios.js => platform-style.ios.ts} (76%) rename src/agenda/{platform-style.js => platform-style.ts} (76%) rename src/agenda/reservation-list/{index.js => index.tsx} (65%) rename src/agenda/reservation-list/{reservation.js => reservation.tsx} (67%) rename src/agenda/reservation-list/{style.js => style.ts} (94%) rename src/agenda/{style.js => style.ts} (94%) rename src/{style.js => style.ts} (100%) diff --git a/src/agenda/index.js b/src/agenda/index.tsx similarity index 79% rename from src/agenda/index.js rename to src/agenda/index.tsx index d0347350d9..909a587b14 100644 --- a/src/agenda/index.js +++ b/src/agenda/index.tsx @@ -1,23 +1,65 @@ import _ from 'lodash'; -import PropTypes from 'prop-types'; import XDate from 'xdate'; import memoize from 'memoize-one'; - import React, {Component} from 'react'; -import {Text, View, Dimensions, Animated} from 'react-native'; - -import {extractComponentProps} from '../component-updater'; +import {Text, View, Dimensions, Animated, ViewStyle} from 'react-native'; +// @ts-expect-error +import {extractComponentProps} from '../component-updater.js'; +// @ts-expect-error import {parseDate, xdateToData, toMarkingFormat} from '../interface'; +// @ts-expect-error import dateutils from '../dateutils'; +// @ts-expect-error import {AGENDA_CALENDAR_KNOB} from '../testIDs'; +// @ts-expect-error import {VelocityTracker} from '../input'; +import CalendarList, {CalendarListProps} from '../calendar-list'; import styleConstructor from './style'; -import CalendarList from '../calendar-list'; -import ReservationList from './reservation-list'; +import ReservationList, {ReservactionListProps} from './reservation-list'; const HEADER_HEIGHT = 104; const KNOB_HEIGHT = 24; +export type AgendaItem = { + name: string; + height: number; +} + +export type AgendaViewProps = CalendarListProps & ReservactionListProps & { + /** agenda container style */ + style?: ViewStyle; + /** the list of items that have to be displayed in agenda. If you want to render item as empty date + the value of date key has to be an empty array []. If there exists no value for date key it is + considered that the date in question is not yet loaded */ + items: AgendaItem[]; + /** callback that gets called when items for a certain month should be loaded (month became visible) */ + loadItemsForMonth?: (data: any) => void; + /** callback that fires when the calendar is opened or closed */ + onCalendarToggled?: (enabled: boolean) => void; + /** callback that gets called on day press */ + onDayPress?: (data: any) => void; + /** callback that gets called when day changes while scrolling agenda list */ + onDaychange?: (data: any) => void; //TODO: Should be renamed 'onDayChange' + /** specify how agenda knob should look like */ + renderKnob?: () => JSX.Element; + /** initially selected day */ + selected: boolean, //TODO: Should be renamed 'selectedDay' + /** Hide knob button. Default = false */ + hideKnob: boolean, + /** When `true` and `hideKnob` prop is `false`, the knob will always be visible and the user will be able to drag the knob up and close the calendar. Default = false */ + showClosingKnob: boolean +} + +type AgendaViewState = { + scrollY: Animated.Value; + calendarIsReady: boolean; + calendarScrollable: boolean; + firstReservationLoad: boolean; + selectedDay: XDate; + topDay: XDate; +} + + /** * @description: Agenda component * @extends: CalendarList @@ -25,37 +67,22 @@ const KNOB_HEIGHT = 24; * @example: https://github.com/wix/react-native-calendars/blob/master/example/src/screens/agenda.js * @gif: https://github.com/wix/react-native-calendars/blob/master/demo/agenda.gif */ -export default class AgendaView extends Component { +export default class AgendaView extends Component { static displayName = 'Agenda'; - - static propTypes = { - ...CalendarList.propTypes, - ...ReservationList.propTypes, - /** agenda container style */ - style: PropTypes.oneOfType([PropTypes.object, PropTypes.array, PropTypes.number]), - /** the list of items that have to be displayed in agenda. If you want to render item as empty date - the value of date key has to be an empty array []. If there exists no value for date key it is - considered that the date in question is not yet loaded */ - items: PropTypes.object, - /** callback that gets called when items for a certain month should be loaded (month became visible) */ - loadItemsForMonth: PropTypes.func, - /** callback that fires when the calendar is opened or closed */ - onCalendarToggled: PropTypes.func, - /** callback that gets called on day press */ - onDayPress: PropTypes.func, - /** callback that gets called when day changes while scrolling agenda list */ - onDaychange: PropTypes.func, //TODO: Should be renamed 'onDayChange' - /** specify how agenda knob should look like */ - renderKnob: PropTypes.func, - /** initially selected day */ - selected: PropTypes.any, //TODO: Should be renamed 'selectedDay' - /** Hide knob button. Default = false */ - hideKnob: PropTypes.bool, - /** When `true` and `hideKnob` prop is `false`, the knob will always be visible and the user will be able to drag the knob up and close the calendar. Default = false */ - showClosingKnob: PropTypes.bool - }; - - constructor(props) { + style: any; + viewHeight: number; + viewWidth: number; + scrollTimeout: any; + headerState: string; + currentMonth: XDate; + knobTracker: any; + _isMounted: boolean | undefined; + scrollPad: any; + calendar: any; + knob: any; + list: any; + + constructor(props: AgendaViewProps) { super(props); this.style = styleConstructor(props.theme); @@ -72,8 +99,8 @@ export default class AgendaView extends Component { calendarIsReady: false, calendarScrollable: false, firstReservationLoad: false, - selectedDay: parseDate(props.selected) || XDate(true), - topDay: parseDate(props.selected) || XDate(true) + selectedDay: parseDate(props.selected) || new XDate(true), + topDay: parseDate(props.selected) || new XDate(true) }; this.currentMonth = this.state.selectedDay.clone(); @@ -92,7 +119,7 @@ export default class AgendaView extends Component { this.state.scrollY.removeAllListeners(); } - componentDidUpdate(prevProps) { + componentDidUpdate(prevProps: AgendaViewProps) { if (this.props.selected && !dateutils.sameDate(parseDate(this.props.selected), parseDate(prevProps.selected))) { this.setState({selectedDay: parseDate(this.props.selected)}); } else if (!prevProps.items) { @@ -100,7 +127,7 @@ export default class AgendaView extends Component { } } - static getDerivedStateFromProps(nextProps) { + static getDerivedStateFromProps(nextProps: AgendaViewProps) { if (nextProps.items) { return {firstReservationLoad: false}; } @@ -116,7 +143,7 @@ export default class AgendaView extends Component { return Math.max(0, this.viewHeight - HEADER_HEIGHT); }; - setScrollPadPosition = (y, animated) => { + setScrollPadPosition = (y: number, animated: boolean) => { if (this.scrollPad.scrollTo) { this.scrollPad.scrollTo({x: 0, y, animated}); } else { @@ -125,7 +152,7 @@ export default class AgendaView extends Component { } }; - toggleCalendarPosition = open => { + toggleCalendarPosition = (open: boolean) => { const maxY = this.initialScrollPadPosition(); this.setScrollPadPosition(open ? 0 : maxY, true); this.enableCalendarScrolling(open); @@ -149,7 +176,7 @@ export default class AgendaView extends Component { this.calendar.scrollToDay(this.state.selectedDay, this.calendarOffset() + 1, true); } - loadReservations(props) { + loadReservations(props: AgendaViewProps) { if ((!props.items || !Object.keys(props.items).length) && !this.state.firstReservationLoad) { this.setState( { @@ -162,11 +189,11 @@ export default class AgendaView extends Component { } } - chooseDayFromCalendar = d => { + chooseDayFromCalendar = (d: any) => { this.chooseDay(d, !this.state.calendarScrollable); }; - chooseDay(d, optimisticScroll) { + chooseDay(d: any, optimisticScroll: boolean) { const day = parseDate(d); this.setState({ @@ -216,7 +243,7 @@ export default class AgendaView extends Component { this.calendar.scrollToDay(this.state.selectedDay.clone(), this.calendarOffset(), false); }; - onLayout = event => { + onLayout = (event: any) => { this.viewHeight = event.nativeEvent.layout.height; this.viewWidth = event.nativeEvent.layout.width; this.forceUpdate(); @@ -247,7 +274,7 @@ export default class AgendaView extends Component { this.knobTracker.reset(); }; - onSnapAfterDrag = e => { + onSnapAfterDrag = (e: any) => { // on Android onTouchEnd is not called if dragging was started this.onTouchEnd(); const currentY = e.nativeEvent.contentOffset.y; @@ -260,7 +287,7 @@ export default class AgendaView extends Component { this.enableCalendarScrolling(snapY === 0); }; - onVisibleMonthsChange = months => { + onVisibleMonthsChange = (months: any[]) => { _.invoke(this.props, 'onVisibleMonthsChange', months); if (this.props.items && !this.state.firstReservationLoad) { @@ -274,7 +301,7 @@ export default class AgendaView extends Component { } }; - onDayChange = day => { + onDayChange = (day: any) => { const newDate = parseDate(day); const withAnimation = dateutils.sameMonth(newDate, this.state.selectedDay); @@ -325,7 +352,7 @@ export default class AgendaView extends Component { renderKnob() { const {showClosingKnob, hideKnob, renderKnob} = this.props; - let knob = ; + let knob: JSX.Element | null = ; if (!hideKnob) { const knobView = renderKnob ? renderKnob() : ; @@ -338,7 +365,7 @@ export default class AgendaView extends Component { return knob; } - renderWeekDaysNames = memoize(weekDaysNames => { + renderWeekDaysNames = memoize((weekDaysNames: string[]) => { return weekDaysNames.map((day, index) => ( {day} @@ -347,6 +374,7 @@ export default class AgendaView extends Component { }); renderWeekNumbersSpace = () => { + // @ts-expect-error return this.props.showWeekNumbers && ; }; @@ -402,7 +430,7 @@ export default class AgendaView extends Component { const shouldAllowDragging = !hideKnob && !this.state.calendarScrollable; const scrollPadPosition = (shouldAllowDragging ? HEADER_HEIGHT : openCalendarScrollPadPosition) - KNOB_HEIGHT; const scrollPadStyle = { - position: 'absolute', + position: 'absolute' as any, width: 80, height: KNOB_HEIGHT, top: scrollPadPosition, @@ -423,7 +451,7 @@ export default class AgendaView extends Component { {this.renderWeekDaysNames(weekDaysNames)} (this.scrollPad = ref)} + ref={(ref: any) => (this.scrollPad = ref)} style={scrollPadStyle} overScrollMode="never" showsHorizontalScrollIndicator={false} diff --git a/src/agenda/platform-style.ios.js b/src/agenda/platform-style.ios.ts similarity index 76% rename from src/agenda/platform-style.ios.js rename to src/agenda/platform-style.ios.ts index 4536518b9c..7c0896ba7f 100644 --- a/src/agenda/platform-style.ios.js +++ b/src/agenda/platform-style.ios.ts @@ -1,4 +1,9 @@ -export default function platformStyles(appStyle) { +interface AppStyle { + agendaKnobColor: string; + calendarBackground: string; +} + +export default function platformStyles(appStyle: AppStyle) { return { knob: { width: 38, diff --git a/src/agenda/platform-style.js b/src/agenda/platform-style.ts similarity index 76% rename from src/agenda/platform-style.js rename to src/agenda/platform-style.ts index 2472544ed1..2076ea402f 100644 --- a/src/agenda/platform-style.js +++ b/src/agenda/platform-style.ts @@ -1,4 +1,9 @@ -export default function platformStyles(appStyle) { +interface AppStyle { + agendaKnobColor: string; + calendarBackground: string; +} + +export default function platformStyles(appStyle: AppStyle) { return { knob: { width: 38, diff --git a/src/agenda/reservation-list/index.js b/src/agenda/reservation-list/index.tsx similarity index 65% rename from src/agenda/reservation-list/index.js rename to src/agenda/reservation-list/index.tsx index 253c69f904..12c725297c 100644 --- a/src/agenda/reservation-list/index.js +++ b/src/agenda/reservation-list/index.tsx @@ -1,58 +1,69 @@ import _ from 'lodash'; -import PropTypes from 'prop-types'; import XDate from 'xdate'; -import React, {Component} from 'react'; -import {FlatList, ActivityIndicator, View} from 'react-native'; - +import {Component} from 'react'; +import {ActivityIndicator, View, FlatList} from 'react-native'; +// @ts-expect-error import {extractComponentProps} from '../../component-updater'; +// @ts-expect-error import dateutils from '../../dateutils'; +// @ts-expect-error import {toMarkingFormat} from '../../interface'; import styleConstructor from './style'; -import Reservation from './reservation'; +import Reservation, {ReservationProps} from './reservation'; + + +export type ReservactionListProps = ReservationProps & { + /** the list of items that have to be displayed in agenda. If you want to render item as empty date + the value of date key kas to be an empty array []. If there exists no value for date key it is + considered that the date in question is not yet loaded */ + reservations: any[]; + selectedDay: XDate; + topDay: XDate; + /** Show items only for the selected day. Default = false */ + showOnlySelectedDayItems: boolean; + /** callback that gets called when day changes while scrolling agenda list */ + onDayChange?: (day: Date) => void; + /** specify what should be rendered instead of ActivityIndicator */ + renderEmptyData: () => JSX.Element; + style?: any; + + /** onScroll ListView event */ + onScroll?: (yOffset: number) => void; + /** Called when the user begins dragging the agenda list **/ + onScrollBeginDrag?: (event: any) => void; + /** Called when the user stops dragging the agenda list **/ + onScrollEndDrag?: (event: any) => void; + /** Called when the momentum scroll starts for the agenda list **/ + onMomentumScrollBegin?: (event: any) => void; + /** Called when the momentum scroll stops for the agenda list **/ + onMomentumScrollEnd?: (event: any) => void; + /** A RefreshControl component, used to provide pull-to-refresh functionality for the ScrollView */ + refreshControl?: any; + /** Set this true while waiting for new data from a refresh */ + refreshing?: boolean, + /** If provided, a standard RefreshControl will be added for "Pull to Refresh" functionality. Make sure to also set the refreshing prop correctly */ + onRefresh?: () => void; +} -class ReservationList extends Component { - static displayName = 'IGNORE'; +interface ReservationsListState { + reservations: any[]; +} - static propTypes = { - ...Reservation.propTypes, - /** the list of items that have to be displayed in agenda. If you want to render item as empty date - the value of date key kas to be an empty array []. If there exists no value for date key it is - considered that the date in question is not yet loaded */ - reservations: PropTypes.object, - selectedDay: PropTypes.instanceOf(XDate), - topDay: PropTypes.instanceOf(XDate), - /** Show items only for the selected day. Default = false */ - showOnlySelectedDayItems: PropTypes.bool, - /** callback that gets called when day changes while scrolling agenda list */ - onDayChange: PropTypes.func, - /** specify what should be rendered instead of ActivityIndicator */ - renderEmptyData: PropTypes.func, - - /** onScroll ListView event */ - onScroll: PropTypes.func, - /** Called when the user begins dragging the agenda list **/ - onScrollBeginDrag: PropTypes.func, - /** Called when the user stops dragging the agenda list **/ - onScrollEndDrag: PropTypes.func, - /** Called when the momentum scroll starts for the agenda list **/ - onMomentumScrollBegin: PropTypes.func, - /** Called when the momentum scroll stops for the agenda list **/ - onMomentumScrollEnd: PropTypes.func, - /** A RefreshControl component, used to provide pull-to-refresh functionality for the ScrollView */ - refreshControl: PropTypes.element, - /** Set this true while waiting for new data from a refresh */ - refreshing: PropTypes.bool, - /** If provided, a standard RefreshControl will be added for "Pull to Refresh" functionality. Make sure to also set the refreshing prop correctly */ - onRefresh: PropTypes.func - }; +class ReservationList extends Component { + static displayName = 'IGNORE'; static defaultProps = { refreshing: false, - selectedDay: XDate(true) + selectedDay: new XDate(true), }; + style: any; + heights: number[]; + selectedDay: XDate; + scrollOver: boolean; + list: any; - constructor(props) { + constructor(props: ReservactionListProps) { super(props); this.style = styleConstructor(props.theme); @@ -70,7 +81,7 @@ class ReservationList extends Component { this.updateDataSource(this.getReservations(this.props).reservations); } - componentDidUpdate(prevProps) { + componentDidUpdate(prevProps: ReservactionListProps) { if (prevProps !== this.props) { if (!dateutils.sameDate(prevProps.topDay, this.props.topDay)) { this.setState( @@ -85,13 +96,13 @@ class ReservationList extends Component { } } - updateDataSource(reservations) { + updateDataSource(reservations: any[]) { this.setState({ reservations }); } - updateReservations(props) { + updateReservations(props: ReservactionListProps) { const {selectedDay} = props; const reservations = this.getReservations(props); if (this.list && !dateutils.sameDate(selectedDay, this.selectedDay)) { @@ -106,11 +117,11 @@ class ReservationList extends Component { this.updateDataSource(reservations.reservations); } - getReservationsForDay(iterator, props) { + getReservationsForDay(iterator: XDate, props: ReservactionListProps) { const day = iterator.clone(); const res = props.reservations[toMarkingFormat(day)]; if (res && res.length) { - return res.map((reservation, i) => { + return res.map((reservation: any, i: number) => { return { reservation, date: i ? false : day, @@ -129,13 +140,13 @@ class ReservationList extends Component { } } - getReservations(props) { + getReservations(props: ReservactionListProps) { const {selectedDay, showOnlySelectedDayItems} = props; if (!props.reservations || !selectedDay) { return {reservations: [], scrollPosition: 0}; } - let reservations = []; + let reservations: any[] = []; if (this.state.reservations && this.state.reservations.length) { const iterator = this.state.reservations[0].day.clone(); @@ -174,7 +185,7 @@ class ReservationList extends Component { return {reservations, scrollPosition}; } - onScroll = event => { + onScroll = (event: any) => { const yOffset = event.nativeEvent.contentOffset.y; _.invoke(this.props, 'onScroll', yOffset); @@ -202,8 +213,8 @@ class ReservationList extends Component { this.scrollOver = true; } - onRowLayoutChange(ind, event) { - this.heights[ind] = event.nativeEvent.layout.height; + onRowLayoutChange(index: number, event: any) { + this.heights[index] = event.nativeEvent.layout.height; } onMoveShouldSetResponderCapture = () => { @@ -211,7 +222,7 @@ class ReservationList extends Component { return false; }; - renderRow = ({item, index}) => { + renderRow = ({item, index}: {item: any, index: number}) => { const reservationProps = extractComponentProps(Reservation, this.props); return ( @@ -221,10 +232,11 @@ class ReservationList extends Component { ); }; - keyExtractor = (item, index) => String(index); + keyExtractor = (_item: any, index: number) => String(index); render() { const {reservations, selectedDay, theme, style} = this.props; + console.log('type reservation', reservations); if (!reservations || !reservations[toMarkingFormat(selectedDay)]) { if (_.isFunction(this.props.renderEmptyData)) { return _.invoke(this.props, 'renderEmptyData'); diff --git a/src/agenda/reservation-list/reservation.js b/src/agenda/reservation-list/reservation.tsx similarity index 67% rename from src/agenda/reservation-list/reservation.js rename to src/agenda/reservation-list/reservation.tsx index b817794494..12ffc8a5cd 100644 --- a/src/agenda/reservation-list/reservation.js +++ b/src/agenda/reservation-list/reservation.tsx @@ -1,37 +1,40 @@ import _ from 'lodash'; -import PropTypes from 'prop-types'; import XDate from 'xdate'; import React, {Component} from 'react'; import {View, Text} from 'react-native'; +// @ts-expect-error import {xdateToData} from '../../interface'; +// @ts-expect-error import dateutils from '../../dateutils'; +// @ts-expect-error import {RESERVATION_DATE} from '../../testIDs'; import styleConstructor from './style'; -class Reservation extends Component { - static displayName = 'IGNORE'; - static propTypes = { - item: PropTypes.any, - /** Specify theme properties to override specific styles for reservation parts. Default = {} */ - theme: PropTypes.object, - /** specify your item comparison function for increased performance */ - rowHasChanged: PropTypes.func, - /** specify how each date should be rendered. day can be undefined if the item is not first in that day */ - renderDay: PropTypes.func, - /** specify how each item should be rendered in agenda */ - renderItem: PropTypes.func, - /** specify how empty date content with no items should be rendered */ - renderEmptyDate: PropTypes.func - }; +export interface ReservationProps { + item: any; + /** Specify theme properties to override specific styles for reservation parts. Default = {} */ + theme: any; + /** specify your item comparison function for increased performance */ + rowHasChanged?: (a: any, b: any) => boolean; + /** specify how each date should be rendered. day can be undefined if the item is not first in that day */ + renderDay?: (date: XDate, item: any) => React.Component; + /** specify how each item should be rendered in agenda */ + renderItem?: (reservation: any, isFirst: boolean) => React.Component; + /** specify how empty date content with no items should be rendered */ + renderEmptyDate?: (date: XDate) => React.Component +} - constructor(props) { - super(props); +class Reservation extends Component { + static displayName = 'IGNORE'; + style; + constructor(props: ReservationProps) { + super(props); this.style = styleConstructor(props.theme); } - shouldComponentUpdate(nextProps) { + shouldComponentUpdate(nextProps: ReservationProps) { const r1 = this.props.item; const r2 = nextProps.item; let changed = true; @@ -54,12 +57,13 @@ class Reservation extends Component { return changed; } - renderDate(date, item) { + renderDate(date: XDate, item: any) { if (_.isFunction(this.props.renderDay)) { return this.props.renderDay(date ? xdateToData(date) : undefined, item); } const today = dateutils.isToday(date) ? this.style.today : undefined; + const dayNames = XDate.locales[XDate.defaultLocale].dayNamesShort; if (date) { return ( @@ -68,7 +72,7 @@ class Reservation extends Component { {date.getDate()} - {XDate.locales[XDate.defaultLocale].dayNamesShort[date.getDay()]} + {dayNames ? dayNames[date.getDay()] : undefined} ); @@ -77,6 +81,7 @@ class Reservation extends Component { } } + render() { const {reservation, date} = this.props.item; let content; diff --git a/src/agenda/reservation-list/style.js b/src/agenda/reservation-list/style.ts similarity index 94% rename from src/agenda/reservation-list/style.js rename to src/agenda/reservation-list/style.ts index d9149730e7..0b24ae0221 100644 --- a/src/agenda/reservation-list/style.js +++ b/src/agenda/reservation-list/style.ts @@ -3,7 +3,7 @@ import * as defaultStyle from '../../style'; const STYLESHEET_ID = 'stylesheet.agenda.list'; -export default function styleConstructor(theme = {}) { +export default function styleConstructor(theme: any = {}) { const appStyle = {...defaultStyle, ...theme}; return StyleSheet.create({ container: { diff --git a/src/agenda/style.js b/src/agenda/style.ts similarity index 94% rename from src/agenda/style.js rename to src/agenda/style.ts index e65d18093f..da27852d76 100644 --- a/src/agenda/style.js +++ b/src/agenda/style.ts @@ -4,13 +4,13 @@ import platformStyles from './platform-style'; const STYLESHEET_ID = 'stylesheet.agenda.main'; -export default function styleConstructor(theme = {}) { +export default function styleConstructor(theme: any = {}) { const appStyle = {...defaultStyle, ...theme}; const {knob, weekdays} = platformStyles(appStyle); return StyleSheet.create({ container: { - flex: 1, + flex: 1, overflow: 'hidden' }, animatedContiner: { diff --git a/src/calendar-list/style.ts b/src/calendar-list/style.ts index a0b354c949..488be202b7 100644 --- a/src/calendar-list/style.ts +++ b/src/calendar-list/style.ts @@ -1,5 +1,4 @@ import {Platform, StyleSheet} from 'react-native'; -// @ts-expect-error import * as defaultStyle from '../style'; const STYLESHEET_ID = 'stylesheet.calendar-list.main'; diff --git a/src/calendar/day/basic/style.ts b/src/calendar/day/basic/style.ts index a4e3f2822e..5a00b23ceb 100644 --- a/src/calendar/day/basic/style.ts +++ b/src/calendar/day/basic/style.ts @@ -1,5 +1,4 @@ import {StyleSheet, Platform} from 'react-native'; -// @ts-expect-error import * as defaultStyle from '../../../style'; const STYLESHEET_ID = 'stylesheet.day.basic'; diff --git a/src/calendar/day/dot/style.ts b/src/calendar/day/dot/style.ts index c763926eef..47c8a826cb 100644 --- a/src/calendar/day/dot/style.ts +++ b/src/calendar/day/dot/style.ts @@ -1,5 +1,4 @@ import {StyleSheet} from 'react-native'; -// @ts-expect-error import * as defaultStyle from '../../../style'; const STYLESHEET_ID = 'stylesheet.dot'; diff --git a/src/calendar/day/period/index.tsx b/src/calendar/day/period/index.tsx index 75c9958799..5a2bbd5cba 100644 --- a/src/calendar/day/period/index.tsx +++ b/src/calendar/day/period/index.tsx @@ -5,7 +5,6 @@ import React, {Component} from 'react'; import {TouchableWithoutFeedback, Text, View} from 'react-native'; // @ts-expect-error import {shouldUpdate} from '../../../component-updater'; -// @ts-expect-error import * as defaultStyle from '../../../style'; import styleConstructor from './style'; import Dot from '../dot'; diff --git a/src/calendar/day/period/style.ts b/src/calendar/day/period/style.ts index 1597c91328..043f51061b 100644 --- a/src/calendar/day/period/style.ts +++ b/src/calendar/day/period/style.ts @@ -1,5 +1,4 @@ import {StyleSheet} from 'react-native'; -// @ts-expect-error import * as defaultStyle from '../../../style'; @@ -57,7 +56,7 @@ export default function styleConstructor(theme: any = {}) { disabledText: { color: appStyle.textDisabledColor }, - + quickAction: { backgroundColor: 'white', borderWidth: 1, diff --git a/src/style.js b/src/style.ts similarity index 100% rename from src/style.js rename to src/style.ts From 30e7dba9355a08b95026cf3a9cb96c9c41eaef8f Mon Sep 17 00:00:00 2001 From: vidmantas0010 Date: Mon, 19 Jul 2021 14:31:14 +0300 Subject: [PATCH 039/109] pr comments fixes --- src/agenda/index.tsx | 79 +++++++++++++++------------ src/agenda/platform-style.ios.ts | 7 +-- src/agenda/platform-style.ts | 10 ++-- src/agenda/reservation-list/index.tsx | 50 +++++++++-------- src/agenda/reservation-list/style.ts | 6 +- src/agenda/style.ts | 6 +- src/commons/types.ts | 5 +- 7 files changed, 86 insertions(+), 77 deletions(-) diff --git a/src/agenda/index.tsx b/src/agenda/index.tsx index 909a587b14..446a74828b 100644 --- a/src/agenda/index.tsx +++ b/src/agenda/index.tsx @@ -1,8 +1,8 @@ import _ from 'lodash'; import XDate from 'xdate'; import memoize from 'memoize-one'; -import React, {Component} from 'react'; -import {Text, View, Dimensions, Animated, ViewStyle} from 'react-native'; +import React, {Component, LegacyRef, RefObject} from 'react'; +import {Text, View, Dimensions, Animated, ViewStyle, LayoutChangeEvent, NativeSyntheticEvent, NativeScrollEvent, StyleSheet} from 'react-native'; // @ts-expect-error import {extractComponentProps} from '../component-updater.js'; // @ts-expect-error @@ -20,18 +20,23 @@ import ReservationList, {ReservactionListProps} from './reservation-list'; const HEADER_HEIGHT = 104; const KNOB_HEIGHT = 24; -export type AgendaItem = { +export type ReservationItemType = { name: string; height: number; + day: XDate; } -export type AgendaViewProps = CalendarListProps & ReservactionListProps & { +export type ReservationsType = { + [date: string]: ReservationItemType[] +} + +export type AgendaProps = CalendarListProps & ReservactionListProps & { /** agenda container style */ style?: ViewStyle; /** the list of items that have to be displayed in agenda. If you want to render item as empty date the value of date key has to be an empty array []. If there exists no value for date key it is considered that the date in question is not yet loaded */ - items: AgendaItem[]; + items: ReservationsType; /** callback that gets called when items for a certain month should be loaded (month became visible) */ loadItemsForMonth?: (data: any) => void; /** callback that fires when the calendar is opened or closed */ @@ -50,7 +55,7 @@ export type AgendaViewProps = CalendarListProps & ReservactionListProps & { showClosingKnob: boolean } -type AgendaViewState = { +type AgendaState = { scrollY: Animated.Value; calendarIsReady: boolean; calendarScrollable: boolean; @@ -67,22 +72,22 @@ type AgendaViewState = { * @example: https://github.com/wix/react-native-calendars/blob/master/example/src/screens/agenda.js * @gif: https://github.com/wix/react-native-calendars/blob/master/demo/agenda.gif */ -export default class AgendaView extends Component { +export default class AgendaView extends Component { static displayName = 'Agenda'; - style: any; - viewHeight: number; - viewWidth: number; - scrollTimeout: any; - headerState: string; - currentMonth: XDate; - knobTracker: any; - _isMounted: boolean | undefined; - scrollPad: any; - calendar: any; - knob: any; - list: any; - - constructor(props: AgendaViewProps) { + private style: {[key: string]: ViewStyle}; + private viewHeight: number; + private viewWidth: number; + private scrollTimeout: any; + private headerState: string; + private currentMonth: XDate; + private knobTracker: any; + private _isMounted: boolean | undefined; + private scrollPad: any; + private calendar: any; + private knob: any; + public list: any; + + constructor(props: AgendaProps) { super(props); this.style = styleConstructor(props.theme); @@ -119,7 +124,7 @@ export default class AgendaView extends Component { - if (this.scrollPad.scrollTo) { + if (this.scrollPad?.scrollTo) { this.scrollPad.scrollTo({x: 0, y, animated}); } else { // Support for RN O.61 (Expo 37) @@ -176,7 +181,7 @@ export default class AgendaView extends Component { + onLayout = (event: LayoutChangeEvent) => { this.viewHeight = event.nativeEvent.layout.height; this.viewWidth = event.nativeEvent.layout.width; this.forceUpdate(); @@ -274,7 +279,7 @@ export default class AgendaView extends Component { + onSnapAfterDrag = (e: NativeSyntheticEvent) => { // on Android onTouchEnd is not called if dragging was started this.onTouchEnd(); const currentY = e.nativeEvent.contentOffset.y; @@ -287,7 +292,7 @@ export default class AgendaView extends Component { + onVisibleMonthsChange = (months: string[]) => { _.invoke(this.props, 'onVisibleMonthsChange', months); if (this.props.items && !this.state.firstReservationLoad) { @@ -429,13 +434,15 @@ export default class AgendaView extends Component @@ -452,7 +459,7 @@ export default class AgendaView extends Component (this.scrollPad = ref)} - style={scrollPadStyle} + style={scrollPadStyle.main} overScrollMode="never" showsHorizontalScrollIndicator={false} showsVerticalScrollIndicator={false} diff --git a/src/agenda/platform-style.ios.ts b/src/agenda/platform-style.ios.ts index 7c0896ba7f..a6ea5a50a0 100644 --- a/src/agenda/platform-style.ios.ts +++ b/src/agenda/platform-style.ios.ts @@ -1,9 +1,6 @@ -interface AppStyle { - agendaKnobColor: string; - calendarBackground: string; -} +import {Theme} from '../commons/types'; -export default function platformStyles(appStyle: AppStyle) { +export default function platformStyles(appStyle: Theme) { return { knob: { width: 38, diff --git a/src/agenda/platform-style.ts b/src/agenda/platform-style.ts index 2076ea402f..d57581de3e 100644 --- a/src/agenda/platform-style.ts +++ b/src/agenda/platform-style.ts @@ -1,9 +1,7 @@ -interface AppStyle { - agendaKnobColor: string; - calendarBackground: string; -} +import {ViewStyle} from 'react-native'; +import {Theme} from '../commons/types'; -export default function platformStyles(appStyle: AppStyle) { +export default function platformStyles(appStyle: Theme) { return { knob: { width: 38, @@ -25,5 +23,5 @@ export default function platformStyles(appStyle: AppStyle) { paddingBottom: 7, backgroundColor: appStyle.calendarBackground } - }; + } as {[key: string]: ViewStyle}; } diff --git a/src/agenda/reservation-list/index.tsx b/src/agenda/reservation-list/index.tsx index 12c725297c..6cfd63211c 100644 --- a/src/agenda/reservation-list/index.tsx +++ b/src/agenda/reservation-list/index.tsx @@ -1,8 +1,8 @@ import _ from 'lodash'; import XDate from 'xdate'; -import {Component} from 'react'; -import {ActivityIndicator, View, FlatList} from 'react-native'; +import React, {Component} from 'react'; +import {ActivityIndicator, View, FlatList, ViewStyle, TextStyle, NativeSyntheticEvent, NativeScrollEvent, LayoutChangeEvent} from 'react-native'; // @ts-expect-error import {extractComponentProps} from '../../component-updater'; // @ts-expect-error @@ -11,13 +11,20 @@ import dateutils from '../../dateutils'; import {toMarkingFormat} from '../../interface'; import styleConstructor from './style'; import Reservation, {ReservationProps} from './reservation'; +import {ReservationItemType, ReservationsType} from 'agenda'; +interface DayReservations { + reservation?: ReservationItemType; + date: XDate | boolean; + day: XDate; +} + export type ReservactionListProps = ReservationProps & { /** the list of items that have to be displayed in agenda. If you want to render item as empty date the value of date key kas to be an empty array []. If there exists no value for date key it is considered that the date in question is not yet loaded */ - reservations: any[]; + reservations: ReservationsType; selectedDay: XDate; topDay: XDate; /** Show items only for the selected day. Default = false */ @@ -26,20 +33,20 @@ export type ReservactionListProps = ReservationProps & { onDayChange?: (day: Date) => void; /** specify what should be rendered instead of ActivityIndicator */ renderEmptyData: () => JSX.Element; - style?: any; + style?: ViewStyle; /** onScroll ListView event */ onScroll?: (yOffset: number) => void; /** Called when the user begins dragging the agenda list **/ - onScrollBeginDrag?: (event: any) => void; + onScrollBeginDrag?: (event: NativeSyntheticEvent) => void; /** Called when the user stops dragging the agenda list **/ - onScrollEndDrag?: (event: any) => void; + onScrollEndDrag?: (event: NativeSyntheticEvent) => void; /** Called when the momentum scroll starts for the agenda list **/ - onMomentumScrollBegin?: (event: any) => void; + onMomentumScrollBegin?: (event: NativeSyntheticEvent) => void; /** Called when the momentum scroll stops for the agenda list **/ - onMomentumScrollEnd?: (event: any) => void; + onMomentumScrollEnd?: (event: NativeSyntheticEvent) => void; /** A RefreshControl component, used to provide pull-to-refresh functionality for the ScrollView */ - refreshControl?: any; + refreshControl?: JSX.Element; /** Set this true while waiting for new data from a refresh */ refreshing?: boolean, /** If provided, a standard RefreshControl will be added for "Pull to Refresh" functionality. Make sure to also set the refreshing prop correctly */ @@ -47,7 +54,7 @@ export type ReservactionListProps = ReservationProps & { } interface ReservationsListState { - reservations: any[]; + reservations: DayReservations[]; } class ReservationList extends Component { @@ -57,11 +64,11 @@ class ReservationList extends Component | null; constructor(props: ReservactionListProps) { super(props); @@ -96,7 +103,7 @@ class ReservationList extends Component { + onScroll = (event: NativeSyntheticEvent) => { const yOffset = event.nativeEvent.contentOffset.y; _.invoke(this.props, 'onScroll', yOffset); @@ -213,7 +220,7 @@ class ReservationList extends Component { + renderRow = ({item, index}: {item: DayReservations, index: number}) => { const reservationProps = extractComponentProps(Reservation, this.props); return ( @@ -232,11 +239,10 @@ class ReservationList extends Component String(index); + keyExtractor = (_item: DayReservations, index: number) => String(index); render() { const {reservations, selectedDay, theme, style} = this.props; - console.log('type reservation', reservations); if (!reservations || !reservations[toMarkingFormat(selectedDay)]) { if (_.isFunction(this.props.renderEmptyData)) { return _.invoke(this.props, 'renderEmptyData'); diff --git a/src/agenda/reservation-list/style.ts b/src/agenda/reservation-list/style.ts index 0b24ae0221..5c4d859dc9 100644 --- a/src/agenda/reservation-list/style.ts +++ b/src/agenda/reservation-list/style.ts @@ -1,9 +1,9 @@ import {StyleSheet} from 'react-native'; import * as defaultStyle from '../../style'; +import {Theme} from '../../commons/types'; -const STYLESHEET_ID = 'stylesheet.agenda.list'; -export default function styleConstructor(theme: any = {}) { +export default function styleConstructor(theme: Theme = {}) { const appStyle = {...defaultStyle, ...theme}; return StyleSheet.create({ container: { @@ -38,6 +38,6 @@ export default function styleConstructor(theme: any = {}) { indicator: { marginTop: 80 }, - ...(theme[STYLESHEET_ID] || {}) + ...(theme.stylesheet?.agenda?.list || {}) }); } diff --git a/src/agenda/style.ts b/src/agenda/style.ts index da27852d76..094fbb7c37 100644 --- a/src/agenda/style.ts +++ b/src/agenda/style.ts @@ -1,10 +1,10 @@ import {StyleSheet} from 'react-native'; import * as defaultStyle from '../style'; import platformStyles from './platform-style'; +import {Theme} from '../commons/types'; -const STYLESHEET_ID = 'stylesheet.agenda.main'; -export default function styleConstructor(theme: any = {}) { +export default function styleConstructor(theme: Theme = {}) { const appStyle = {...defaultStyle, ...theme}; const {knob, weekdays} = platformStyles(appStyle); @@ -48,6 +48,6 @@ export default function styleConstructor(theme: any = {}) { marginTop: 104, backgroundColor: appStyle.backgroundColor }, - ...(theme[STYLESHEET_ID] || {}) + ...(theme.stylesheet?.agenda?.main || {}) }); } diff --git a/src/commons/types.ts b/src/commons/types.ts index b81d6b9b3c..e48492b3cd 100644 --- a/src/commons/types.ts +++ b/src/commons/types.ts @@ -1,4 +1,4 @@ -import {ColorValue} from 'react-native'; +import {ColorValue, TextStyle} from 'react-native'; export interface Theme { container?: object; contentStyle?: object; @@ -21,6 +21,7 @@ export interface Theme { dot?: object; marking?: object; 'calendar-list'?: {main?: object}; + agenda?: {main?: object, list?: object}; }; textSectionTitleColor?: string; textSectionTitleDisabledColor?: string; @@ -39,7 +40,7 @@ export interface Theme { textDayHeaderFontFamily?: string; textDayFontWeight?: string; textMonthFontWeight?: string; - textDayHeaderFontWeight?: string; + textDayHeaderFontWeight?: TextStyle['fontWeight']; textDayFontSize?: number; textMonthFontSize?: number; textDayHeaderFontSize?: number; From 7325aac5db0f10a1b191cfde3c9cfc7a0a7df3a8 Mon Sep 17 00:00:00 2001 From: Inbal Tish Date: Wed, 21 Jul 2021 15:54:42 +0300 Subject: [PATCH 040/109] Calendar - migrate to ts --- .../screens/{calendars.js => calendars.tsx} | 0 src/calendar/day/basic/index.tsx | 18 +-- src/calendar/day/index.tsx | 2 +- src/calendar/header/index.tsx | 10 +- src/calendar/{index.js => index.tsx} | 116 +++++++++++++----- src/calendar/{style.js => style.ts} | 4 +- 6 files changed, 101 insertions(+), 49 deletions(-) rename example/src/screens/{calendars.js => calendars.tsx} (100%) rename src/calendar/{index.js => index.tsx} (71%) rename src/calendar/{style.js => style.ts} (87%) diff --git a/example/src/screens/calendars.js b/example/src/screens/calendars.tsx similarity index 100% rename from example/src/screens/calendars.js rename to example/src/screens/calendars.tsx diff --git a/src/calendar/day/basic/index.tsx b/src/calendar/day/basic/index.tsx index 8561455906..1dada34d17 100644 --- a/src/calendar/day/basic/index.tsx +++ b/src/calendar/day/basic/index.tsx @@ -12,23 +12,23 @@ import {Theme} from '../../../commons/types'; export interface BasicDayProps { state?: 'selected' | 'disabled' | 'today'; /** The marking object */ - marking: any; + marking?: object; /** Date marking style [simple/period/multi-dot/multi-period]. Default = 'simple' */ - markingType: MarkingTypes; + markingType?: MarkingTypes; /** Theme object */ - theme: Theme; + theme?: Theme; /** onPress callback */ - onPress: (date: Object) => void; + onPress?: (date: Date) => void; /** onLongPress callback */ - onLongPress: (date: Object) => void; + onLongPress?: (date: Date) => void; /** The date to return from press callbacks */ - date: Object; + date?: Date; /** Disable all touch events for disabled days. can be override with disableTouchEvent in markedDates*/ - disableAllTouchEventsForDisabledDays: boolean; + disableAllTouchEventsForDisabledDays?: boolean; /** Test ID*/ - testID: string; + testID?: string; /** Accessibility label */ - accessibilityLabel: string; + accessibilityLabel?: string; } export default class BasicDay extends Component { diff --git a/src/calendar/day/index.tsx b/src/calendar/day/index.tsx index 86f9387281..e5c418ce5f 100644 --- a/src/calendar/day/index.tsx +++ b/src/calendar/day/index.tsx @@ -18,7 +18,7 @@ import {MarkingProps} from './marking'; const basicDayPropsTypes = _.omit(BasicDay.propTypes, 'date'); -interface DayProps extends Omit { +export interface DayProps extends Omit { /** The day to render */ day?: Date; /** Provide custom day rendering component */ diff --git a/src/calendar/header/index.tsx b/src/calendar/header/index.tsx index acee660cd5..934ee8a14d 100644 --- a/src/calendar/header/index.tsx +++ b/src/calendar/header/index.tsx @@ -30,9 +30,9 @@ export interface CalendarHeaderProps { addMonth?: (num: number) => void; /** Month format in the title. Formatting values: http://arshaw.com/xdate/#Formatting */ monthFormat?: string; - /** Hide day names. Default = false */ + /** Hide day names */ hideDayNames?: boolean; - /** Hide month navigation arrows. Default = false */ + /** Hide month navigation arrows */ hideArrows?: boolean; /** Replace default arrows with custom ones (direction can be 'left' or 'right') */ renderArrow?: (direction: Direction) => ReactNode; @@ -40,13 +40,13 @@ export interface CalendarHeaderProps { onPressArrowLeft?: (method: () => void, month?: XDate) => void; /** Handler which gets executed when press arrow icon right. It receive a callback can go next month */ onPressArrowRight?: (method: () => void, month?: XDate) => void; - /** Disable left arrow. Default = false */ + /** Disable left arrow */ disableArrowLeft?: boolean; - /** Disable right arrow. Default = false */ + /** Disable right arrow */ disableArrowRight?: boolean; /** Apply custom disable color to selected day indexes */ disabledDaysIndexes?: number[]; - /** Replace default month and year title with custom one. the function receive a date as parameter. */ + /** Replace default month and year title with custom one. the function receive a date as parameter */ renderHeader?: (date?: XDate) => ReactNode; /** Provide aria-level for calendar heading for proper accessibility when used with web (react-native-web) */ webAriaLevel?: number; diff --git a/src/calendar/index.js b/src/calendar/index.tsx similarity index 71% rename from src/calendar/index.js rename to src/calendar/index.tsx index ee2501f7a1..d6225ffaac 100644 --- a/src/calendar/index.js +++ b/src/calendar/index.tsx @@ -3,27 +3,84 @@ import PropTypes from 'prop-types'; import XDate from 'xdate'; import memoize from 'memoize-one'; -import React, {Component} from 'react'; -import {View} from 'react-native'; +import React, {Component, RefObject} from 'react'; +import {View, ViewStyle} from 'react-native'; import GestureRecognizer, {swipeDirections} from 'react-native-swipe-gestures'; +// @ts-expect-error import dateutils from '../dateutils'; +// @ts-expect-error import {xdateToData, parseDate, toMarkingFormat} from '../interface'; +// @ts-expect-error import {getState} from '../day-state-manager'; // import shouldComponentUpdate from './updater'; +// @ts-expect-error import {extractComponentProps} from '../component-updater'; +// @ts-expect-error import {WEEK_NUMBER} from '../testIDs'; import styleConstructor from './style'; -import CalendarHeader from './header'; +import CalendarHeader, {CalendarHeaderProps} from './header'; +import Day, {DayProps} from './day/index'; import BasicDay from './day/basic'; -import Day from './day/index'; +import {Theme} from '../../commons/types'; + +type MarkedDatesType = { + [key: string]: object +} + +export interface CalendarProps extends CalendarHeaderProps, DayProps { + /** Specify theme properties to override specific styles for calendar parts */ + theme?: Theme; + /** Specify style for calendar container element */ + style?: ViewStyle; + /** Initially visible month */ + current?: XDate; + /** Minimum date that can be selected, dates before minDate will be grayed out */ + minDate?: Date; + /** Maximum date that can be selected, dates after maxDate will be grayed out */ + maxDate?: Date; + /** If firstDay=1 week starts from Monday. Note that dayNames and dayNamesShort should still start from Sunday */ + firstDay?: number; + /** Collection of dates that have to be marked */ + markedDates?: MarkedDatesType; + /** Display loading indicator */ + displayLoadingIndicator?: boolean; + /** Show week numbers */ + showWeekNumbers?: boolean; + /** Do not show days of other months in month page */ + hideExtraDays?: boolean; + /** Always show six weeks on each month (only when hideExtraDays = false) */ + showSixWeeks?: boolean; + /** Handler which gets executed on day press */ + onDayPress?: (date: Date) => any; + /** Handler which gets executed on day long press */ + onDayLongPress?: (date: Date) => any; + /** Handler which gets executed when month changes in calendar */ + onMonthChange?: () => void; + /** Handler which gets executed when visible month changes in calendar */ + onVisibleMonthsChange?: () => void; + /** Disables changing month when click on days of other months (when hideExtraDays is false) */ + disableMonthChange?: boolean; + /** Enable the option to swipe between months */ + enableSwipeMonths?: boolean; + /** Disable days by default */ + disabledByDefault?: boolean; + /** Style passed to the header */ + headerStyle?: ViewStyle; + /** Allow rendering of a totally custom header */ + customHeader?: any; +} + +interface CalendarState { + currentMonth: any +} /** * @description: Calendar component * @example: https://github.com/wix/react-native-calendars/blob/master/example/src/screens/calendars.js * @gif: https://github.com/wix/react-native-calendars/blob/master/demo/calendar.gif */ -class Calendar extends Component { +class Calendar extends Component { static displayName = 'Calendar'; static propTypes = { @@ -70,28 +127,21 @@ class Calendar extends Component { /** Allow rendering of a totally custom header */ customHeader: PropTypes.any }; - static defaultProps = { enableSwipeMonths: false }; - constructor(props) { - super(props); - - this.style = styleConstructor(props.theme); - - this.state = { - currentMonth: props.current ? parseDate(props.current) : XDate() - }; - - // this.shouldComponentUpdate = shouldComponentUpdate; - } + state = { + currentMonth: this.props.current ? parseDate(this.props.current) : new XDate() + }; + style = styleConstructor(this.props.theme); + header: RefObject = React.createRef(); - addMonth = count => { - this.updateMonth(this.state.currentMonth.clone().addMonths(count, true)); + addMonth = (count: number) => { + this.updateMonth(this.state.currentMonth.clone().addMonths(count, true), false); }; - updateMonth = (day, doNotTriggerListeners) => { + updateMonth = (day: any, doNotTriggerListeners: boolean) => { if (day.toString('yyyy MM') === this.state.currentMonth.toString('yyyy MM')) { return; } @@ -105,7 +155,7 @@ class Calendar extends Component { }); }; - handleDayInteraction(date, interaction) { + handleDayInteraction(date: any, interaction?: (date: any) => any) { const {disableMonthChange} = this.props; const day = parseDate(date); const minDate = parseDate(this.props.minDate); @@ -115,7 +165,7 @@ class Calendar extends Component { const shouldUpdateMonth = disableMonthChange === undefined || !disableMonthChange; if (shouldUpdateMonth) { - this.updateMonth(day); + this.updateMonth(day, false); } if (interaction) { interaction(xdateToData(day)); @@ -123,17 +173,17 @@ class Calendar extends Component { } } - pressDay = date => { + pressDay = (date: any) => { this.handleDayInteraction(date, this.props.onDayPress); }; - longPressDay = date => { + longPressDay = (date: any) => { this.handleDayInteraction(date, this.props.onDayLongPress); }; - swipeProps = {onSwipe: (direction, state) => this.onSwipe(direction, state)}; + swipeProps = {onSwipe: (direction: string) => this.onSwipe(direction)}; - onSwipe = gestureName => { + onSwipe = (gestureName: string) => { const {SWIPE_UP, SWIPE_DOWN, SWIPE_LEFT, SWIPE_RIGHT} = swipeDirections; switch (gestureName) { @@ -150,11 +200,11 @@ class Calendar extends Component { }; onSwipeLeft = () => { - this.header.onPressRight(); + this.header?.current?.onPressRight(); }; onSwipeRight = () => { - this.header.onPressLeft(); + this.header?.current?.onPressLeft(); }; renderWeekNumber = memoize(weekNumber => { @@ -173,7 +223,7 @@ class Calendar extends Component { ); }); - renderDay(day, id) { + renderDay(day: Date, id: number) { const {hideExtraDays, markedDates} = this.props; const dayProps = extractComponentProps(Day, this.props); @@ -195,10 +245,10 @@ class Calendar extends Component { ); } - renderWeek(days, id) { + renderWeek(days: any, id: number) { const week = []; - days.forEach((day, id2) => { + days.forEach((day: any, id2: number) => { week.push(this.renderDay(day, id2)); }, this); @@ -234,7 +284,7 @@ class Calendar extends Component { if (current) { const lastMonthOfDay = toMarkingFormat(current.clone().addMonths(1, true).setDate(1).addDays(-1)); - if (displayLoadingIndicator && !(markedDates && markedDates[lastMonthOfDay])) { + if (displayLoadingIndicator && !(markedDates?.[lastMonthOfDay])) { indicator = true; } } @@ -248,7 +298,7 @@ class Calendar extends Component { {...headerProps} testID={testID} style={headerStyle} - ref={r => (this.header = r)} + ref={this.header} month={this.state.currentMonth} addMonth={this.addMonth} displayLoadingIndicator={indicator} diff --git a/src/calendar/style.js b/src/calendar/style.ts similarity index 87% rename from src/calendar/style.js rename to src/calendar/style.ts index 7423af0c9d..88f66cdb04 100644 --- a/src/calendar/style.js +++ b/src/calendar/style.ts @@ -1,9 +1,11 @@ import {StyleSheet} from 'react-native'; import * as defaultStyle from '../style'; +import {Theme} from '../../commons/types'; + const STYLESHEET_ID = 'stylesheet.calendar.main'; -export default function getStyle(theme = {}) { +export default function getStyle(theme: Theme = {}) { const appStyle = {...defaultStyle, ...theme}; return StyleSheet.create({ container: { From 105cd4a758cf78b3744c5a2122e72857e914d428 Mon Sep 17 00:00:00 2001 From: Inbal Tish Date: Thu, 22 Jul 2021 08:50:00 +0300 Subject: [PATCH 041/109] Improve typings --- src/calendar/day/basic/index.tsx | 6 +++--- src/calendar/day/marking/index.tsx | 11 +++++++++-- src/calendar/index.tsx | 6 +++--- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/calendar/day/basic/index.tsx b/src/calendar/day/basic/index.tsx index 1dada34d17..26f2fee21b 100644 --- a/src/calendar/day/basic/index.tsx +++ b/src/calendar/day/basic/index.tsx @@ -6,13 +6,13 @@ import {TouchableOpacity, Text, View} from 'react-native'; // @ts-expect-error import {shouldUpdate} from '../../../component-updater'; import styleConstructor from './style'; -import Marking, {MarkingTypes} from '../marking'; +import Marking, {MarkingTypes, MarkingProps} from '../marking'; import {Theme} from '../../../commons/types'; export interface BasicDayProps { state?: 'selected' | 'disabled' | 'today'; /** The marking object */ - marking?: object; + marking?: MarkingProps; /** Date marking style [simple/period/multi-dot/multi-period]. Default = 'simple' */ markingType?: MarkingTypes; /** Theme object */ @@ -48,7 +48,7 @@ export default class BasicDay extends Component { onLongPress: PropTypes.func, /** The date to return from press callbacks */ date: PropTypes.object, - /** Disable all touch events for disabled days. can be override with disableTouchEvent in markedDates*/ + /** Disable all touch events for disabled days. Can be override with disableTouchEvent in markedDates*/ disableAllTouchEventsForDisabledDays: PropTypes.bool }; diff --git a/src/calendar/day/marking/index.tsx b/src/calendar/day/marking/index.tsx index 338f1faf72..683b0ef163 100644 --- a/src/calendar/day/marking/index.tsx +++ b/src/calendar/day/marking/index.tsx @@ -1,5 +1,5 @@ import React, {Component} from 'react'; -import {View} from 'react-native'; +import {View, ViewStyle, TextStyle} from 'react-native'; // @ts-expect-error import {shouldUpdate, extractComponentProps} from '../../../component-updater'; import styleConstructor from './style'; @@ -14,6 +14,11 @@ export enum MarkingTypes { CUSTOM = 'custom' } +type CustomStyle = { + container?: ViewStyle, + text?: TextStyle +} + type DOT = { key?: string; color?: string; @@ -45,14 +50,16 @@ export interface MarkingProps extends DotProps { startingDay?: boolean; endingDay?: boolean; accessibilityLabel?: string; + customStyles?: CustomStyle; } export default class Marking extends Component { static displayName = 'IGNORE'; static markingTypes = MarkingTypes; + style: any; - + constructor(props: MarkingProps) { super(props); diff --git a/src/calendar/index.tsx b/src/calendar/index.tsx index d6225ffaac..917b3edf3e 100644 --- a/src/calendar/index.tsx +++ b/src/calendar/index.tsx @@ -155,7 +155,7 @@ class Calendar extends Component { }); }; - handleDayInteraction(date: any, interaction?: (date: any) => any) { + handleDayInteraction(date: Date, interaction?: (date: Date) => any) { const {disableMonthChange} = this.props; const day = parseDate(date); const minDate = parseDate(this.props.minDate); @@ -173,11 +173,11 @@ class Calendar extends Component { } } - pressDay = (date: any) => { + pressDay = (date: Date) => { this.handleDayInteraction(date, this.props.onDayPress); }; - longPressDay = (date: any) => { + longPressDay = (date: Date) => { this.handleDayInteraction(date, this.props.onDayLongPress); }; From 97df6d2499fe2f2d47fc4d75335e1404b28c37f5 Mon Sep 17 00:00:00 2001 From: Inbal Tish Date: Thu, 22 Jul 2021 09:12:54 +0300 Subject: [PATCH 042/109] removing marking array check --- src/calendar/day/basic/index.tsx | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/calendar/day/basic/index.tsx b/src/calendar/day/basic/index.tsx index 26f2fee21b..031674fc45 100644 --- a/src/calendar/day/basic/index.tsx +++ b/src/calendar/day/basic/index.tsx @@ -75,13 +75,7 @@ export default class BasicDay extends Component { }; get marking() { - let marking = this.props.marking || {}; - if (marking && marking.constructor === Array && marking.length) { - marking = { - marking: true - }; - } - return marking; + return this.props.marking || {}; } shouldDisableTouchEvent() { From c03f671e60a0c25b61ea13795acd6f3f26356214 Mon Sep 17 00:00:00 2001 From: Christophe Hurpeau Date: Thu, 22 Jul 2021 10:37:01 +0200 Subject: [PATCH 043/109] ExpandableCalendar fix onDayPress not working fixes #1102 #1370 --- src/expandableCalendar/index.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/expandableCalendar/index.js b/src/expandableCalendar/index.js index 54f53e2a59..a867a7c496 100644 --- a/src/expandableCalendar/index.js +++ b/src/expandableCalendar/index.js @@ -352,6 +352,10 @@ class ExpandableCalendar extends Component { this.bounceToPosition(this.closedHeight); } }, 0); + + if (this.props.onDayPress) { + this.props.onDayPress(value); + } }; onVisibleMonthsChange = value => { From 71e9dd63ade1a9b8e46cae45997f39f069af8bcc Mon Sep 17 00:00:00 2001 From: Inbal Tish Date: Thu, 22 Jul 2021 12:31:11 +0300 Subject: [PATCH 044/109] fix date type; moving src/style to ts --- example/src/screens/calendars.tsx | 25 +++-------- src/calendar-list/style.ts | 1 - src/calendar/day/basic/style.ts | 1 - src/calendar/day/dot/style.ts | 1 - src/calendar/day/marking/style.ts | 1 - src/calendar/day/period/index.tsx | 69 +++++++++++++++++-------------- src/calendar/day/period/style.ts | 37 ++++++++--------- src/calendar/header/style.ts | 1 - src/{style.js => style.ts} | 0 9 files changed, 61 insertions(+), 75 deletions(-) rename src/{style.js => style.ts} (100%) diff --git a/example/src/screens/calendars.tsx b/example/src/screens/calendars.tsx index c175382da8..04f31059e2 100644 --- a/example/src/screens/calendars.tsx +++ b/example/src/screens/calendars.tsx @@ -19,19 +19,6 @@ const CalendarsScreen = () => { setSelected(day.dateString); }; - const getDisabledDates = (startDate, endDate, daysToDisable) => { - const disabledDates = {}; - const start = XDate(startDate); - const end = XDate(endDate); - - for (let m = XDate(start); m.diffDays(end) <= 0; m.addDays(1)) { - if (_.includes(daysToDisable, m.weekday())) { - disabledDates[m.toString('YYYY-MM-DD')] = {disabled: true}; - } - } - return disabledDates; - }; - const renderCalendarWithSelectableDate = () => { return ( @@ -185,7 +172,6 @@ const CalendarsScreen = () => { { borderBottomRightRadius: 5 } }, - ...getDisabledDates('2012-05-01', '2012-05-30', [0, 6]) + '2012-05-30': {disabled: true, disableTouchEvent: true} + }} + disabledDaysIndexes={[0, 6]} + theme={{ + textSectionTitleDisabledColor: 'grey', + textSectionTitleColor: '#00BBF2' }} /> @@ -257,7 +248,6 @@ const CalendarsScreen = () => { Custom calendar with custom marking type { ); }; - const initialNumToRender = 100; // Workaround for Detox 18 migration bug - return ( {renderSwitch()} {showMarkedDatesExamples && renderMarkedDatesExamples()} diff --git a/src/calendar-list/style.ts b/src/calendar-list/style.ts index d90b8e67de..fc2754f7bf 100644 --- a/src/calendar-list/style.ts +++ b/src/calendar-list/style.ts @@ -1,5 +1,4 @@ import {Platform, StyleSheet} from 'react-native'; -// @ts-expect-error import * as defaultStyle from '../style'; import {Theme} from '../commons/types'; diff --git a/src/calendar/day/basic/style.ts b/src/calendar/day/basic/style.ts index de815e5b9f..1f0a1d5c93 100644 --- a/src/calendar/day/basic/style.ts +++ b/src/calendar/day/basic/style.ts @@ -1,5 +1,4 @@ import {StyleSheet, Platform} from 'react-native'; -// @ts-expect-error import * as defaultStyle from '../../../style'; import {Theme} from '../../../commons/types'; diff --git a/src/calendar/day/dot/style.ts b/src/calendar/day/dot/style.ts index 6f13e530f7..63f93f8fe4 100644 --- a/src/calendar/day/dot/style.ts +++ b/src/calendar/day/dot/style.ts @@ -1,5 +1,4 @@ import {StyleSheet} from 'react-native'; -// @ts-expect-error import * as defaultStyle from '../../../style'; import {Theme} from '../../../commons/types'; diff --git a/src/calendar/day/marking/style.ts b/src/calendar/day/marking/style.ts index d1486d33d2..b268290337 100644 --- a/src/calendar/day/marking/style.ts +++ b/src/calendar/day/marking/style.ts @@ -1,5 +1,4 @@ import {StyleSheet} from 'react-native'; -// @ts-expect-error import * as defaultStyle from '../../style'; import {Theme} from '../../../commons/types'; diff --git a/src/calendar/day/period/index.tsx b/src/calendar/day/period/index.tsx index d7dd741ea9..3584d1190b 100644 --- a/src/calendar/day/period/index.tsx +++ b/src/calendar/day/period/index.tsx @@ -3,21 +3,22 @@ import PropTypes from 'prop-types'; import React, {Component} from 'react'; import {TouchableWithoutFeedback, Text, View, ViewStyle} from 'react-native'; + // @ts-expect-error import {shouldUpdate} from '../../../component-updater'; -// @ts-expect-error import * as defaultStyle from '../../../style'; import styleConstructor from './style'; import Dot from '../dot'; +import {MarkingProps} from '../marking'; import {Theme} from '../../../commons/types'; interface PeriodDayProps { state?: 'selected' | 'disabled' | 'today' | ''; - marking?: any; + marking?: MarkingProps; theme?: Theme; - onPress?: (date?: Object) => void; - onLongPress?: (date?: Object) => void; - date?: Object; + onPress?: (date?: Date) => void; + onLongPress?: (date?: Date) => void; + date?: Date; accessibilityLabel?: string; testID?: string; } @@ -33,6 +34,7 @@ export default class PeriodDay extends Component { onLongPress: PropTypes.func, date: PropTypes.object }; + theme: Theme; style: any; markingStyle: any; @@ -42,8 +44,7 @@ export default class PeriodDay extends Component { this.theme = {...defaultStyle, ...(props.theme || {})}; this.style = styleConstructor(props.theme); - - this.markingStyle = this.getDrawingStyle(props.marking || []); + this.markingStyle = this.getDrawingStyle(props.marking); } onPress = () => { @@ -64,7 +65,8 @@ export default class PeriodDay extends Component { return shouldUpdate(this.props, nextProps, ['children', 'state', 'marking', 'onPress', 'onLongPress', 'date']); } - getDrawingStyle(marking: any) { + // TODO: refactor to use MarkingProps as the type + getDrawingStyle(marking?: any) { const defaultStyle = {textStyle: {color: undefined}, containerStyle: {}}; if (!marking) { @@ -78,30 +80,28 @@ export default class PeriodDay extends Component { } const resultStyle = [marking].reduce((prev, next) => { - if (next.quickAction) { - //??? - if (next.first || next.last) { - prev.containerStyle = this.style.firstQuickAction; - prev.textStyle = this.style.firstQuickActionText; - if (next.endSelected && next.first && !next.last) { - prev.rightFillerStyle = '#c1e4fe'; - } else if (next.endSelected && next.last && !next.first) { - prev.leftFillerStyle = '#c1e4fe'; - } - } else if (!next.endSelected) { - prev.containerStyle = this.style.quickAction; - prev.textStyle = this.style.quickActionText; - } else if (next.endSelected) { - prev.leftFillerStyle = '#c1e4fe'; - prev.rightFillerStyle = '#c1e4fe'; - } - return prev; - } - - if (next.status === 'NotAvailable') { - //??? - prev.textStyle = this.style.naText; - } + // if (next.quickAction) { //??? + // if (next.first || next.last) { + // prev.containerStyle = this.style.firstQuickAction; + // prev.textStyle = this.style.firstQuickActionText; + // if (next.endSelected && next.first && !next.last) { + // prev.rightFillerStyle = '#c1e4fe'; + // } else if (next.endSelected && next.last && !next.first) { + // prev.leftFillerStyle = '#c1e4fe'; + // } + // } else if (!next.endSelected) { + // prev.containerStyle = this.style.quickAction; + // prev.textStyle = this.style.quickActionText; + // } else if (next.endSelected) { + // prev.leftFillerStyle = '#c1e4fe'; + // prev.rightFillerStyle = '#c1e4fe'; + // } + // return prev; + // } + + // if (next.status === 'NotAvailable') { //??? + // prev.textStyle = this.style.naText; + // } const color = next.color; if (next.startingDay) { @@ -123,7 +123,9 @@ export default class PeriodDay extends Component { defaultStyle.containerStyle = marking.customContainerStyle; } return prev; + }, defaultStyle); + return resultStyle; } @@ -136,6 +138,7 @@ export default class PeriodDay extends Component { let fillerStyle = {}; let fillers; + // TODO: refactor - move all styling logic out of render() if (state === 'disabled') { textStyle.push(this.style.disabledText); } else if (state === 'today') { @@ -199,6 +202,7 @@ export default class PeriodDay extends Component { }); } + // TODO: refactor - move all fillers logic out of render() fillers = ( @@ -209,6 +213,7 @@ export default class PeriodDay extends Component { const {theme, accessibilityLabel, testID} = this.props; + // TODO: refactor - allow feedback for unmarked days return ( Date: Thu, 22 Jul 2021 13:06:09 +0300 Subject: [PATCH 045/109] remove unused imports --- example/src/screens/calendars.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/example/src/screens/calendars.tsx b/example/src/screens/calendars.tsx index 04f31059e2..d0a7deb65f 100644 --- a/example/src/screens/calendars.tsx +++ b/example/src/screens/calendars.tsx @@ -1,5 +1,3 @@ -import _ from 'lodash'; -import XDate from 'xdate'; import React, {useState, Fragment} from 'react'; import {StyleSheet, View, ScrollView, Text, TouchableOpacity, Switch} from 'react-native'; import {Calendar} from 'react-native-calendars'; From 9fe24c2012f7f33393425ccda0f30aa0c1bbb666 Mon Sep 17 00:00:00 2001 From: vidmantas0010 Date: Thu, 22 Jul 2021 13:08:43 +0300 Subject: [PATCH 046/109] pr improvement --- src/agenda/index.tsx | 18 +++++++----------- src/agenda/reservation-list/index.tsx | 8 ++++---- src/agenda/reservation-list/reservation.tsx | 13 +++++++------ src/agenda/style.ts | 4 ++++ src/commons/types.ts | 2 +- 5 files changed, 23 insertions(+), 22 deletions(-) diff --git a/src/agenda/index.tsx b/src/agenda/index.tsx index 446a74828b..0d81374877 100644 --- a/src/agenda/index.tsx +++ b/src/agenda/index.tsx @@ -1,7 +1,7 @@ import _ from 'lodash'; import XDate from 'xdate'; import memoize from 'memoize-one'; -import React, {Component, LegacyRef, RefObject} from 'react'; +import React, {Component} from 'react'; import {Text, View, Dimensions, Animated, ViewStyle, LayoutChangeEvent, NativeSyntheticEvent, NativeScrollEvent, StyleSheet} from 'react-native'; // @ts-expect-error import {extractComponentProps} from '../component-updater.js'; @@ -434,15 +434,11 @@ export default class AgendaView extends Component { const openCalendarScrollPadPosition = !hideKnob && this.state.calendarScrollable && this.props.showClosingKnob ? agendaHeight + HEADER_HEIGHT : 0; const shouldAllowDragging = !hideKnob && !this.state.calendarScrollable; const scrollPadPosition = (shouldAllowDragging ? HEADER_HEIGHT : openCalendarScrollPadPosition) - KNOB_HEIGHT; - const scrollPadStyle = StyleSheet.create({ - main: { - position: 'absolute', - width: 80, - height: KNOB_HEIGHT, - top: scrollPadPosition, - left: (this.viewWidth - 80) / 2 - } - }); + const scrollPadStyle = { + height: KNOB_HEIGHT, + top: scrollPadPosition, + left: (this.viewWidth - 80) / 2, + } return ( @@ -459,7 +455,7 @@ export default class AgendaView extends Component { (this.scrollPad = ref)} - style={scrollPadStyle.main} + style={[this.style.scrollPadStyle, scrollPadStyle]} overScrollMode="never" showsHorizontalScrollIndicator={false} showsVerticalScrollIndicator={false} diff --git a/src/agenda/reservation-list/index.tsx b/src/agenda/reservation-list/index.tsx index 6cfd63211c..f2db796797 100644 --- a/src/agenda/reservation-list/index.tsx +++ b/src/agenda/reservation-list/index.tsx @@ -14,9 +14,9 @@ import Reservation, {ReservationProps} from './reservation'; import {ReservationItemType, ReservationsType} from 'agenda'; -interface DayReservations { +export interface DayReservations { reservation?: ReservationItemType; - date: XDate | boolean; + date?: XDate; day: XDate; } @@ -128,10 +128,10 @@ class ReservationList extends Component { + return res.map((reservation: ReservationItemType, i: number) => { return { reservation, - date: i ? false : day, + date: i ? undefined : day, day }; }); diff --git a/src/agenda/reservation-list/reservation.tsx b/src/agenda/reservation-list/reservation.tsx index 12ffc8a5cd..ce4d889463 100644 --- a/src/agenda/reservation-list/reservation.tsx +++ b/src/agenda/reservation-list/reservation.tsx @@ -9,20 +9,21 @@ import dateutils from '../../dateutils'; // @ts-expect-error import {RESERVATION_DATE} from '../../testIDs'; import styleConstructor from './style'; - +import {Theme} from '../../commons/types'; +import {DayReservations} from './index'; export interface ReservationProps { - item: any; + item: DayReservations; /** Specify theme properties to override specific styles for reservation parts. Default = {} */ - theme: any; + theme: Theme; /** specify your item comparison function for increased performance */ rowHasChanged?: (a: any, b: any) => boolean; /** specify how each date should be rendered. day can be undefined if the item is not first in that day */ - renderDay?: (date: XDate, item: any) => React.Component; + renderDay?: (date: XDate, item?: DayReservations) => React.Component; /** specify how each item should be rendered in agenda */ renderItem?: (reservation: any, isFirst: boolean) => React.Component; /** specify how empty date content with no items should be rendered */ - renderEmptyDate?: (date: XDate) => React.Component + renderEmptyDate?: (date?: XDate) => React.Component } class Reservation extends Component { @@ -57,7 +58,7 @@ class Reservation extends Component { return changed; } - renderDate(date: XDate, item: any) { + renderDate(date?: XDate, item?: DayReservations) { if (_.isFunction(this.props.renderDay)) { return this.props.renderDay(date ? xdateToData(date) : undefined, item); } diff --git a/src/agenda/style.ts b/src/agenda/style.ts index 094fbb7c37..8df4e90680 100644 --- a/src/agenda/style.ts +++ b/src/agenda/style.ts @@ -48,6 +48,10 @@ export default function styleConstructor(theme: Theme = {}) { marginTop: 104, backgroundColor: appStyle.backgroundColor }, + scrollPadStyle: { + position: 'absolute', + width: 80, + }, ...(theme.stylesheet?.agenda?.main || {}) }); } diff --git a/src/commons/types.ts b/src/commons/types.ts index e48492b3cd..b955e6ee47 100644 --- a/src/commons/types.ts +++ b/src/commons/types.ts @@ -14,7 +14,7 @@ export interface Theme { timeLabel?: object; todayTextColor?: string; calendarBackground?: string; - indicatorColor?: ColorValue | object; + indicatorColor?: ColorValue; stylesheet?: { calendar?: {header?: object}; day?: {basic?: object; period?: object}; From 3f272a7cfca053e844d5273873922052d9aeee49 Mon Sep 17 00:00:00 2001 From: Inbal Tish Date: Thu, 22 Jul 2021 15:11:29 +0300 Subject: [PATCH 047/109] calendarList fix types --- src/calendar-list/index.tsx | 7 +++---- src/calendar-list/item.tsx | 8 ++++---- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/calendar-list/index.tsx b/src/calendar-list/index.tsx index 65dfec9080..984754cde9 100644 --- a/src/calendar-list/index.tsx +++ b/src/calendar-list/index.tsx @@ -1,9 +1,9 @@ import _ from 'lodash'; -import XDate from 'xdate'; import PropTypes from 'prop-types'; +import XDate from 'xdate'; import React, {Component} from 'react'; -import {FlatList, Platform, Dimensions, View} from 'react-native'; +import {FlatList, Platform, Dimensions, View, ViewStyle} from 'react-native'; // @ts-expect-error import {extractComponentProps} from '../component-updater'; // @ts-expect-error @@ -14,7 +14,6 @@ import dateutils from '../dateutils'; import {STATIC_HEADER} from '../testIDs'; import styleConstructor from './style'; -// @ts-expect-error import Calendar, {CalendarProps} from '../calendar'; import CalendarListItem from './item'; import CalendarHeader from '../calendar/header/index'; @@ -31,7 +30,7 @@ export type CalendarListProps = CalendarProps & { /** Dynamic calendar height */ calendarHeight?: number; /** Style for the List item (the calendar) */ - calendarStyle?: number | Array | Object; + calendarStyle?: ViewStyle; /** Whether to use static header that will not scroll with the list (horizontal only) */ staticHeader?: boolean; /** Enable or disable vertical / horizontal scroll indicator. Default = false */ diff --git a/src/calendar-list/item.tsx b/src/calendar-list/item.tsx index fa4b9c4d5f..ebdc50ceb7 100644 --- a/src/calendar-list/item.tsx +++ b/src/calendar-list/item.tsx @@ -1,13 +1,12 @@ +import PropTypes from 'prop-types'; import memoize from 'memoize-one'; + import React, {Component} from 'react'; import {Text, View} from 'react-native'; -import PropTypes from 'prop-types'; -import {Theme} from '../commons/types'; +import {Theme} from '../commons/types'; // @ts-expect-error import {extractComponentProps} from '../component-updater'; - -// @ts-expect-error import Calendar, {CalendarProps} from '../calendar'; import styleConstructor from './style'; @@ -17,6 +16,7 @@ export type CalendarListItemProps = CalendarProps & { calendarHeight?: number; horizontal?: boolean; theme?: Theme; + scrollToMonth?: (date: XDate) => void } type CalendarListItemState = { From d2e28b33bf3816621e296d369446ecdbd9f6f4fe Mon Sep 17 00:00:00 2001 From: Inbal Tish Date: Thu, 22 Jul 2021 15:20:32 +0300 Subject: [PATCH 048/109] Day - fix types --- src/calendar/day/basic/index.tsx | 2 +- src/calendar/day/dot/index.tsx | 2 +- src/calendar/style.ts | 2 +- src/commons/types.ts | 2 ++ 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/calendar/day/basic/index.tsx b/src/calendar/day/basic/index.tsx index 031674fc45..dda322fe5a 100644 --- a/src/calendar/day/basic/index.tsx +++ b/src/calendar/day/basic/index.tsx @@ -141,7 +141,7 @@ export default class BasicDay extends Component { getTextStyle() { const {customStyles, selectedTextColor} = this.marking; - const style = [this.style.text]; + const style = [this.style.text] as object[]; if (this.isSelected()) { style.push(this.style.selectedText); diff --git a/src/calendar/day/dot/index.tsx b/src/calendar/day/dot/index.tsx index ee9a7af4a7..e89bad91cd 100644 --- a/src/calendar/day/dot/index.tsx +++ b/src/calendar/day/dot/index.tsx @@ -15,7 +15,7 @@ export interface DotProps { const Dot = ({theme, marked, disabled, color, today, selected}: DotProps) => { const style = styleConstructor(theme); - const dotStyle = [style.dot]; + const dotStyle = [style.dot] as object[]; if (marked) { dotStyle.push(style.visibleDot); diff --git a/src/calendar/style.ts b/src/calendar/style.ts index 88f66cdb04..3da7239af3 100644 --- a/src/calendar/style.ts +++ b/src/calendar/style.ts @@ -1,6 +1,6 @@ import {StyleSheet} from 'react-native'; import * as defaultStyle from '../style'; -import {Theme} from '../../commons/types'; +import {Theme} from '../commons/types'; const STYLESHEET_ID = 'stylesheet.calendar.main'; diff --git a/src/commons/types.ts b/src/commons/types.ts index b81d6b9b3c..6a7f1f4596 100644 --- a/src/commons/types.ts +++ b/src/commons/types.ts @@ -67,4 +67,6 @@ export interface Theme { todayDotColor?: string; todayButtonTextColor?: string; todayButtonPosition?: string; + arrowHeight?: number; + arrowWidth?: number; } From 14bab20818a805a03be897fc8183828f367f0bf2 Mon Sep 17 00:00:00 2001 From: Inbal Tish Date: Thu, 22 Jul 2021 15:27:21 +0300 Subject: [PATCH 049/109] Calendar - fix types --- src/calendar/index.tsx | 2 +- src/calendar/style.ts | 5 +---- src/commons/types.ts | 2 +- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/calendar/index.tsx b/src/calendar/index.tsx index 917b3edf3e..61411d2a5e 100644 --- a/src/calendar/index.tsx +++ b/src/calendar/index.tsx @@ -22,7 +22,7 @@ import styleConstructor from './style'; import CalendarHeader, {CalendarHeaderProps} from './header'; import Day, {DayProps} from './day/index'; import BasicDay from './day/basic'; -import {Theme} from '../../commons/types'; +import {Theme} from '../commons/types'; type MarkedDatesType = { diff --git a/src/calendar/style.ts b/src/calendar/style.ts index 3da7239af3..577ab647ab 100644 --- a/src/calendar/style.ts +++ b/src/calendar/style.ts @@ -2,9 +2,6 @@ import {StyleSheet} from 'react-native'; import * as defaultStyle from '../style'; import {Theme} from '../commons/types'; - -const STYLESHEET_ID = 'stylesheet.calendar.main'; - export default function getStyle(theme: Theme = {}) { const appStyle = {...defaultStyle, ...theme}; return StyleSheet.create({ @@ -29,6 +26,6 @@ export default function getStyle(theme: Theme = {}) { flexDirection: 'row', justifyContent: 'space-around' }, - ...(theme[STYLESHEET_ID] || {}) + ...(theme.stylesheet?.calendar?.main || {}) }); } diff --git a/src/commons/types.ts b/src/commons/types.ts index 6a7f1f4596..2f32cc4de2 100644 --- a/src/commons/types.ts +++ b/src/commons/types.ts @@ -16,7 +16,7 @@ export interface Theme { calendarBackground?: string; indicatorColor?: ColorValue | object; stylesheet?: { - calendar?: {header?: object}; + calendar?: {main?: object, header?: object}; day?: {basic?: object; period?: object}; dot?: object; marking?: object; From d4f28bb9f87e01eee901670a2c1e334b1a646642 Mon Sep 17 00:00:00 2001 From: Inbal Tish Date: Thu, 22 Jul 2021 15:46:11 +0300 Subject: [PATCH 050/109] CalendarList - fix types --- src/calendar-list/index.tsx | 37 ++++++++++++++++++++++--------------- src/calendar-list/item.tsx | 1 + 2 files changed, 23 insertions(+), 15 deletions(-) diff --git a/src/calendar-list/index.tsx b/src/calendar-list/index.tsx index 984754cde9..080df27417 100644 --- a/src/calendar-list/index.tsx +++ b/src/calendar-list/index.tsx @@ -3,7 +3,7 @@ import PropTypes from 'prop-types'; import XDate from 'xdate'; import React, {Component} from 'react'; -import {FlatList, Platform, Dimensions, View, ViewStyle} from 'react-native'; +import {FlatList, Platform, Dimensions, View, ViewStyle, LayoutChangeEvent} from 'react-native'; // @ts-expect-error import {extractComponentProps} from '../component-updater'; // @ts-expect-error @@ -53,6 +53,9 @@ export type CalendarListProps = CalendarProps & { onEndReachedThreshold?: number; /** Called once when the scroll position gets within onEndReachedThreshold */ onEndReached?: () => void; + /** onLayout event */ + onLayout?: (event: LayoutChangeEvent) => void; + removeClippedSubviews: boolean; }; type XDateAndBump = XDate & {propBump?: number} ; @@ -137,9 +140,10 @@ class CalendarList extends Component { const rows = []; const texts = []; const date = parseDate(props.current) || new XDate(); + const {pastScrollRange = 50, futureScrollRange = 50} = props; - for (let i = 0; i <= props.pastScrollRange + props.futureScrollRange; i++) { - const rangeDate = date.clone().addMonths(i - props.pastScrollRange, true); + for (let i = 0; i <= pastScrollRange + futureScrollRange; i++) { + const rangeDate = date.clone().addMonths(i - pastScrollRange, true); const rangeDateStr = rangeDate.toString('MMM yyyy'); texts.push(rangeDateStr); /* @@ -147,8 +151,8 @@ class CalendarList extends Component { * If `this.pastScrollRange` is `undefined` it's equal to `false` or 0 in next condition. */ if ( - (props.pastScrollRange - 1 <= i && i <= props.pastScrollRange + 1) || - (!props.pastScrollRange && i <= props.pastScrollRange + 2) + (pastScrollRange - 1 <= i && i <= pastScrollRange + 1) || + (!pastScrollRange && i <= pastScrollRange + 2) ) { rows.push(rangeDate); } else { @@ -191,7 +195,7 @@ class CalendarList extends Component { } scrollToDay(d: XDate, offset: number, animated: boolean) { - const {horizontal, calendarHeight, calendarWidth, pastScrollRange, firstDay} = this.props; + const {horizontal, calendarHeight = 360, calendarWidth = width, pastScrollRange = 50, firstDay} = this.props; const day = parseDate(d); const diffMonths = Math.round(this.state.openDate.clone().setDate(1).diffMonths(day.clone().setDate(1))); const size = horizontal ? calendarWidth : calendarHeight; @@ -212,7 +216,7 @@ class CalendarList extends Component { } scrollToMonth = (m: XDate) => { - const {horizontal, calendarHeight, calendarWidth, pastScrollRange, animateScroll = false} = this.props; + const {horizontal, calendarHeight = 360, calendarWidth = width, pastScrollRange = 50, animateScroll = false} = this.props; const month = parseDate(m); const scrollTo = month || this.state.openDate; let diffMonths = Math.round(this.state.openDate.clone().setDate(1).diffMonths(scrollTo.clone().setDate(1))); @@ -223,17 +227,19 @@ class CalendarList extends Component { }; getItemLayout = (_: Array | undefined | null, index: number) => { - const {horizontal, calendarHeight, calendarWidth} = this.props; + const {horizontal, calendarHeight = 360, calendarWidth = width} = this.props; + const size = horizontal ? calendarWidth : calendarHeight; return { - length: horizontal ? calendarWidth : calendarHeight, - offset: (horizontal ? calendarWidth : calendarHeight) * index, + length: size, + offset: size * index, index }; }; getMonthIndex(month: XDate) { - let diffMonths = this.state.openDate.diffMonths(month) + this.props.pastScrollRange; + const {pastScrollRange = 50} = this.props; + let diffMonths = this.state.openDate.diffMonths(month) + pastScrollRange; return diffMonths; } @@ -275,9 +281,10 @@ class CalendarList extends Component { for (let i = 0; i < rowclone.length; i++) { let val: XDate | string = rowclone[i]; const rowShouldBeRendered = rowIsCloseToViewable(i, 1); + const {pastScrollRange = 50} = this.props; if (rowShouldBeRendered && !rowclone[i].getTime) { - val = this.state.openDate.clone().addMonths(i - this.props.pastScrollRange, true); + val = this.state.openDate.clone().addMonths(i - pastScrollRange, true); } else if (!rowShouldBeRendered) { val = this.state.texts[i]; } @@ -333,7 +340,7 @@ class CalendarList extends Component { } render() { - const {style, pastScrollRange, futureScrollRange, horizontal, showScrollIndicator, testID} = this.props; + const {style, pastScrollRange, futureScrollRange, horizontal, showScrollIndicator} = this.props; return ( @@ -347,10 +354,10 @@ class CalendarList extends Component { getItemLayout={this.getItemLayout} onViewableItemsChanged={this.onViewableItemsChanged} viewabilityConfig={this.viewabilityConfig} - initialScrollIndex={this.state.openDate ? this.getMonthIndex(this.state.openDate) : false} + initialScrollIndex={this.state.openDate ? this.getMonthIndex(this.state.openDate) : undefined} showsVerticalScrollIndicator={showScrollIndicator} showsHorizontalScrollIndicator={horizontal && showScrollIndicator} - testID={testID} + testID={this.props.testID} onLayout={this.props.onLayout} removeClippedSubviews={this.props.removeClippedSubviews} pagingEnabled={this.props.pagingEnabled} diff --git a/src/calendar-list/item.tsx b/src/calendar-list/item.tsx index ebdc50ceb7..4c37d67796 100644 --- a/src/calendar-list/item.tsx +++ b/src/calendar-list/item.tsx @@ -101,6 +101,7 @@ class CalendarListItem extends Component Date: Sun, 1 Aug 2021 10:42:43 +0300 Subject: [PATCH 051/109] space --- src/calendar-list/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/calendar-list/index.tsx b/src/calendar-list/index.tsx index 080df27417..f05993e78c 100644 --- a/src/calendar-list/index.tsx +++ b/src/calendar-list/index.tsx @@ -4,6 +4,7 @@ import XDate from 'xdate'; import React, {Component} from 'react'; import {FlatList, Platform, Dimensions, View, ViewStyle, LayoutChangeEvent} from 'react-native'; + // @ts-expect-error import {extractComponentProps} from '../component-updater'; // @ts-expect-error @@ -13,7 +14,6 @@ import dateutils from '../dateutils'; // @ts-expect-error import {STATIC_HEADER} from '../testIDs'; import styleConstructor from './style'; - import Calendar, {CalendarProps} from '../calendar'; import CalendarListItem from './item'; import CalendarHeader from '../calendar/header/index'; From 1dec5533da10e3655415f35c9cb853246e42ce4e Mon Sep 17 00:00:00 2001 From: Inbal Tish Date: Sun, 1 Aug 2021 12:09:05 +0300 Subject: [PATCH 052/109] CalendarList - moving default values to consts --- src/calendar-list/index.tsx | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/calendar-list/index.tsx b/src/calendar-list/index.tsx index f05993e78c..9ef19e0331 100644 --- a/src/calendar-list/index.tsx +++ b/src/calendar-list/index.tsx @@ -19,6 +19,10 @@ import CalendarListItem from './item'; import CalendarHeader from '../calendar/header/index'; const {width} = Dimensions.get('window'); +const CALENDAR_WIDTH = width; +const CALENDAR_HEIGHT = 360; +const PAST_SCROLL_RANGE = 50; +const FUTURE_SCROLL_RANGE = 50; export type CalendarListProps = CalendarProps & { /** Max amount of months allowed to scroll to the past. Default = 50 */ @@ -114,10 +118,10 @@ class CalendarList extends Component { }; static defaultProps = { - calendarWidth: width, - calendarHeight: 360, - pastScrollRange: 50, - futureScrollRange: 50, + calendarWidth: CALENDAR_WIDTH, + calendarHeight: CALENDAR_HEIGHT, + pastScrollRange: PAST_SCROLL_RANGE, + futureScrollRange: FUTURE_SCROLL_RANGE, showScrollIndicator: false, horizontal: false, scrollsToTop: false, @@ -140,7 +144,7 @@ class CalendarList extends Component { const rows = []; const texts = []; const date = parseDate(props.current) || new XDate(); - const {pastScrollRange = 50, futureScrollRange = 50} = props; + const {pastScrollRange = PAST_SCROLL_RANGE, futureScrollRange = FUTURE_SCROLL_RANGE} = props; for (let i = 0; i <= pastScrollRange + futureScrollRange; i++) { const rangeDate = date.clone().addMonths(i - pastScrollRange, true); @@ -195,7 +199,7 @@ class CalendarList extends Component { } scrollToDay(d: XDate, offset: number, animated: boolean) { - const {horizontal, calendarHeight = 360, calendarWidth = width, pastScrollRange = 50, firstDay} = this.props; + const {horizontal, calendarHeight = CALENDAR_HEIGHT, calendarWidth = CALENDAR_WIDTH, pastScrollRange = PAST_SCROLL_RANGE, firstDay} = this.props; const day = parseDate(d); const diffMonths = Math.round(this.state.openDate.clone().setDate(1).diffMonths(day.clone().setDate(1))); const size = horizontal ? calendarWidth : calendarHeight; @@ -216,7 +220,7 @@ class CalendarList extends Component { } scrollToMonth = (m: XDate) => { - const {horizontal, calendarHeight = 360, calendarWidth = width, pastScrollRange = 50, animateScroll = false} = this.props; + const {horizontal, calendarHeight = CALENDAR_HEIGHT, calendarWidth = CALENDAR_WIDTH, pastScrollRange = PAST_SCROLL_RANGE, animateScroll = false} = this.props; const month = parseDate(m); const scrollTo = month || this.state.openDate; let diffMonths = Math.round(this.state.openDate.clone().setDate(1).diffMonths(scrollTo.clone().setDate(1))); @@ -227,7 +231,7 @@ class CalendarList extends Component { }; getItemLayout = (_: Array | undefined | null, index: number) => { - const {horizontal, calendarHeight = 360, calendarWidth = width} = this.props; + const {horizontal, calendarHeight = CALENDAR_HEIGHT, calendarWidth = CALENDAR_WIDTH} = this.props; const size = horizontal ? calendarWidth : calendarHeight; return { @@ -238,7 +242,7 @@ class CalendarList extends Component { }; getMonthIndex(month: XDate) { - const {pastScrollRange = 50} = this.props; + const {pastScrollRange = PAST_SCROLL_RANGE} = this.props; let diffMonths = this.state.openDate.diffMonths(month) + pastScrollRange; return diffMonths; } @@ -281,7 +285,7 @@ class CalendarList extends Component { for (let i = 0; i < rowclone.length; i++) { let val: XDate | string = rowclone[i]; const rowShouldBeRendered = rowIsCloseToViewable(i, 1); - const {pastScrollRange = 50} = this.props; + const {pastScrollRange = PAST_SCROLL_RANGE} = this.props; if (rowShouldBeRendered && !rowclone[i].getTime) { val = this.state.openDate.clone().addMonths(i - pastScrollRange, true); From 307023b3d616237ba59a25a6d6a76b55b96a18e9 Mon Sep 17 00:00:00 2001 From: Inbal Tish Date: Sun, 1 Aug 2021 12:19:12 +0300 Subject: [PATCH 053/109] add parameter default and change error ignore type --- src/calendar-list/item.tsx | 2 +- src/calendar/index.tsx | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/calendar-list/item.tsx b/src/calendar-list/item.tsx index 4c37d67796..3c18c8a824 100644 --- a/src/calendar-list/item.tsx +++ b/src/calendar-list/item.tsx @@ -101,7 +101,7 @@ class CalendarListItem extends Component { header: RefObject = React.createRef(); addMonth = (count: number) => { - this.updateMonth(this.state.currentMonth.clone().addMonths(count, true), false); + this.updateMonth(this.state.currentMonth.clone().addMonths(count, true)); }; - updateMonth = (day: any, doNotTriggerListeners: boolean) => { + updateMonth = (day: any, doNotTriggerListeners = false) => { if (day.toString('yyyy MM') === this.state.currentMonth.toString('yyyy MM')) { return; } @@ -165,7 +165,7 @@ class Calendar extends Component { const shouldUpdateMonth = disableMonthChange === undefined || !disableMonthChange; if (shouldUpdateMonth) { - this.updateMonth(day, false); + this.updateMonth(day); } if (interaction) { interaction(xdateToData(day)); From 45212a53f92dfea3c1e586e14dc66ddcee2f39f4 Mon Sep 17 00:00:00 2001 From: Inbal Tish Date: Sun, 1 Aug 2021 13:11:15 +0300 Subject: [PATCH 054/109] Calendar - MarkedDatesType fix --- src/calendar/index.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/calendar/index.tsx b/src/calendar/index.tsx index 245eed3398..cae10b7287 100644 --- a/src/calendar/index.tsx +++ b/src/calendar/index.tsx @@ -5,6 +5,7 @@ import memoize from 'memoize-one'; import React, {Component, RefObject} from 'react'; import {View, ViewStyle} from 'react-native'; +// @ts-expect-error import GestureRecognizer, {swipeDirections} from 'react-native-swipe-gestures'; // @ts-expect-error @@ -22,11 +23,12 @@ import styleConstructor from './style'; import CalendarHeader, {CalendarHeaderProps} from './header'; import Day, {DayProps} from './day/index'; import BasicDay from './day/basic'; +import {MarkingProps} from './day/marking'; import {Theme} from '../commons/types'; type MarkedDatesType = { - [key: string]: object + [key: string]: MarkingProps } export interface CalendarProps extends CalendarHeaderProps, DayProps { From d7c632c78f378b7344006041d371c91c6119211c Mon Sep 17 00:00:00 2001 From: Inbal Tish Date: Sun, 1 Aug 2021 13:12:04 +0300 Subject: [PATCH 055/109] Marking - type fix --- src/calendar/day/marking/index.tsx | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/calendar/day/marking/index.tsx b/src/calendar/day/marking/index.tsx index 683b0ef163..afb55eebfb 100644 --- a/src/calendar/day/marking/index.tsx +++ b/src/calendar/day/marking/index.tsx @@ -1,5 +1,8 @@ +import _ from 'lodash'; + import React, {Component} from 'react'; import {View, ViewStyle, TextStyle} from 'react-native'; + // @ts-expect-error import {shouldUpdate, extractComponentProps} from '../../../component-updater'; import styleConstructor from './style'; @@ -21,14 +24,14 @@ type CustomStyle = { type DOT = { key?: string; - color?: string; + color: string; selectedDotColor?: string; }; type PERIOD = { + color: string; startingDay?: boolean; endingDay?: boolean; - color?: string; }; export interface MarkingProps extends DotProps { @@ -44,9 +47,9 @@ export interface MarkingProps extends DotProps { selectedTextColor?: string; dotColor?: string; //multi-dot - dots?: DOT; + dots?: DOT[]; //multi-period - periods?: PERIOD; + periods?: PERIOD[]; startingDay?: boolean; endingDay?: boolean; accessibilityLabel?: string; @@ -83,12 +86,12 @@ export default class Marking extends Component { ]); } - getItems(items: DOT | PERIOD) { + getItems(items?: DOT[] | PERIOD[]) { const {type} = this.props; if (items && Array.isArray(items) && items.length > 0) { // Filter out items so that we process only those which have color property - const validItems = items.filter(d => d && d.color); + const validItems = _.filter(items, function(o: DOT | PERIOD) { return !o.color; }); return validItems.map((item, index) => { return type === MarkingTypes.MULTI_DOT ? this.renderDot(index, item) : this.renderPeriod(index, item); @@ -108,7 +111,7 @@ export default class Marking extends Component { } } - renderMultiMarkings(containerStyle: Object, items: any) { + renderMultiMarkings(containerStyle: Object, items?: DOT[] | PERIOD[]) { return {this.getItems(items)}; } @@ -126,7 +129,7 @@ export default class Marking extends Component { if (endingDay) { style.push(this.style.endingDay); } - return ; + return ; } renderDot(index?: number, item?: any) { From 7e2d4febfc1a18075802e3db6e7950fc9b2a8814 Mon Sep 17 00:00:00 2001 From: Inbal Tish Date: Sun, 1 Aug 2021 13:15:48 +0300 Subject: [PATCH 056/109] d.ts files --- src/calendar-list/index.d.ts | 173 +++++++++++++++++++ src/calendar-list/index.js | 253 ++++++++++++++++++++++++++++ src/calendar-list/item.d.ts | 79 +++++++++ src/calendar-list/item.js | 81 +++++++++ src/calendar-list/style.d.ts | 32 ++++ src/calendar-list/style.js | 37 ++++ src/calendar/day/basic/index.d.ts | 123 ++++++++++++++ src/calendar/day/basic/index.js | 152 +++++++++++++++++ src/calendar/day/basic/style.d.ts | 60 +++++++ src/calendar/day/basic/style.js | 67 ++++++++ src/calendar/day/dot/index.d.ts | 23 +++ src/calendar/day/dot/index.js | 33 ++++ src/calendar/day/dot/style.d.ts | 24 +++ src/calendar/day/dot/style.js | 30 ++++ src/calendar/day/index.d.ts | 31 ++++ src/calendar/day/index.js | 91 ++++++++++ src/calendar/day/marking/index.d.ts | 58 +++++++ src/calendar/day/marking/index.js | 96 +++++++++++ src/calendar/day/marking/style.d.ts | 24 +++ src/calendar/day/marking/style.js | 29 ++++ src/calendar/day/period/index.d.ts | 35 ++++ src/calendar/day/period/index.js | 192 +++++++++++++++++++++ src/calendar/day/period/style.d.ts | 49 ++++++ src/calendar/day/period/style.js | 73 ++++++++ src/calendar/header/index.d.ts | 92 ++++++++++ src/calendar/header/index.js | 184 ++++++++++++++++++++ src/calendar/header/style.d.ts | 50 ++++++ src/calendar/header/style.js | 60 +++++++ src/calendar/index.d.ts | 175 +++++++++++++++++++ src/calendar/index.js | 211 +++++++++++++++++++++++ src/calendar/style.d.ts | 24 +++ src/calendar/style.js | 29 ++++ src/commons/types.d.ts | 80 +++++++++ src/commons/types.js | 1 + src/style.d.ts | 48 ++++++ src/style.js | 48 ++++++ 36 files changed, 2847 insertions(+) create mode 100644 src/calendar-list/index.d.ts create mode 100644 src/calendar-list/index.js create mode 100644 src/calendar-list/item.d.ts create mode 100644 src/calendar-list/item.js create mode 100644 src/calendar-list/style.d.ts create mode 100644 src/calendar-list/style.js create mode 100644 src/calendar/day/basic/index.d.ts create mode 100644 src/calendar/day/basic/index.js create mode 100644 src/calendar/day/basic/style.d.ts create mode 100644 src/calendar/day/basic/style.js create mode 100644 src/calendar/day/dot/index.d.ts create mode 100644 src/calendar/day/dot/index.js create mode 100644 src/calendar/day/dot/style.d.ts create mode 100644 src/calendar/day/dot/style.js create mode 100644 src/calendar/day/index.d.ts create mode 100644 src/calendar/day/index.js create mode 100644 src/calendar/day/marking/index.d.ts create mode 100644 src/calendar/day/marking/index.js create mode 100644 src/calendar/day/marking/style.d.ts create mode 100644 src/calendar/day/marking/style.js create mode 100644 src/calendar/day/period/index.d.ts create mode 100644 src/calendar/day/period/index.js create mode 100644 src/calendar/day/period/style.d.ts create mode 100644 src/calendar/day/period/style.js create mode 100644 src/calendar/header/index.d.ts create mode 100644 src/calendar/header/index.js create mode 100644 src/calendar/header/style.d.ts create mode 100644 src/calendar/header/style.js create mode 100644 src/calendar/index.d.ts create mode 100644 src/calendar/index.js create mode 100644 src/calendar/style.d.ts create mode 100644 src/calendar/style.js create mode 100644 src/commons/types.d.ts create mode 100644 src/commons/types.js create mode 100644 src/style.d.ts create mode 100644 src/style.js diff --git a/src/calendar-list/index.d.ts b/src/calendar-list/index.d.ts new file mode 100644 index 0000000000..87751e2169 --- /dev/null +++ b/src/calendar-list/index.d.ts @@ -0,0 +1,173 @@ +import PropTypes from 'prop-types'; +import XDate from 'xdate'; +import { Component } from 'react'; +import { FlatList, ViewStyle, LayoutChangeEvent } from 'react-native'; +import { CalendarProps } from '../calendar'; +export declare type CalendarListProps = CalendarProps & { + /** Max amount of months allowed to scroll to the past. Default = 50 */ + pastScrollRange?: number; + /** Max amount of months allowed to scroll to the future. Default = 50 */ + futureScrollRange?: number; + /** Used when calendar scroll is horizontal, default is device width, pagination should be disabled */ + calendarWidth?: number; + /** Dynamic calendar height */ + calendarHeight?: number; + /** Style for the List item (the calendar) */ + calendarStyle?: ViewStyle; + /** Whether to use static header that will not scroll with the list (horizontal only) */ + staticHeader?: boolean; + /** Enable or disable vertical / horizontal scroll indicator. Default = false */ + showScrollIndicator?: boolean; + /** Whether to animate the auto month scroll */ + animateScroll?: boolean; + /** Enable or disable scrolling of calendar list */ + scrollEnabled?: boolean; + /** When true, the calendar list scrolls to top when the status bar is tapped. Default = true */ + scrollsToTop?: boolean; + /** Enable or disable paging on scroll */ + pagingEnabled?: boolean; + /** Whether the scroll is horizontal */ + horizontal?: boolean; + /** Should Keyboard persist taps */ + keyboardShouldPersistTaps?: 'never' | 'always' | 'handled'; + /** A custom key extractor for the generated calendar months */ + keyExtractor?: (item: any, index: number) => string; + /** How far from the end to trigger the onEndReached callback */ + onEndReachedThreshold?: number; + /** Called once when the scroll position gets within onEndReachedThreshold */ + onEndReached?: () => void; + /** onLayout event */ + onLayout?: (event: LayoutChangeEvent) => void; + removeClippedSubviews: boolean; +}; +declare type XDateAndBump = XDate & { + propBump?: number; +}; +declare type CalendarListState = { + rows: Array; + texts: Array; + openDate: XDate; + currentMonth: XDate; +}; +/** + * @description: Calendar List component for both vertical and horizontal calendars + * @extends: Calendar + * @extendslink: docs/Calendar + * @example: https://github.com/wix/react-native-calendars/blob/master/example/src/screens/calendarsList.js + * @gif: https://github.com/wix/react-native-calendars/blob/master/demo/calendar-list.gif + */ +declare class CalendarList extends Component { + static displayName: string; + static propTypes: { + /** Max amount of months allowed to scroll to the past. Default = 50 */ + pastScrollRange: PropTypes.Requireable; + /** Max amount of months allowed to scroll to the future. Default = 50 */ + futureScrollRange: PropTypes.Requireable; + /** Used when calendar scroll is horizontal, default is device width, pagination should be disabled */ + calendarWidth: PropTypes.Requireable; + /** Dynamic calendar height */ + calendarHeight: PropTypes.Requireable; + /** Style for the List item (the calendar) */ + calendarStyle: PropTypes.Requireable; + /** Whether to use static header that will not scroll with the list (horizontal only) */ + staticHeader: PropTypes.Requireable; + /** Enable or disable vertical / horizontal scroll indicator. Default = false */ + showScrollIndicator: PropTypes.Requireable; + /** Whether to animate the auto month scroll */ + animateScroll: PropTypes.Requireable; + /** Enable or disable scrolling of calendar list */ + scrollEnabled: PropTypes.Requireable; + /** When true, the calendar list scrolls to top when the status bar is tapped. Default = true */ + scrollsToTop: PropTypes.Requireable; + /** Enable or disable paging on scroll */ + pagingEnabled: PropTypes.Requireable; + /** Whether the scroll is horizontal */ + horizontal: PropTypes.Requireable; + /** Should Keyboard persist taps */ + keyboardShouldPersistTaps: PropTypes.Requireable; + /** A custom key extractor for the generated calendar months */ + keyExtractor: PropTypes.Requireable<(...args: any[]) => any>; + /** How far from the end to trigger the onEndReached callback */ + onEndReachedThreshold: PropTypes.Requireable; + /** Called once when the scroll position gets within onEndReachedThreshold */ + onEndReached: PropTypes.Requireable<(...args: any[]) => any>; + theme: PropTypes.Requireable; + style: PropTypes.Requireable; /** Dynamic calendar height */ + current: PropTypes.Requireable; + minDate: PropTypes.Requireable; /** Whether to use static header that will not scroll with the list (horizontal only) */ + maxDate: PropTypes.Requireable; + firstDay: PropTypes.Requireable; + markedDates: PropTypes.Requireable; + displayLoadingIndicator: PropTypes.Requireable; + showWeekNumbers: PropTypes.Requireable; /** Enable or disable paging on scroll */ + hideExtraDays: PropTypes.Requireable; + showSixWeeks: PropTypes.Requireable; + onDayPress: PropTypes.Requireable<(...args: any[]) => any>; + onDayLongPress: PropTypes.Requireable<(...args: any[]) => any>; + onMonthChange: PropTypes.Requireable<(...args: any[]) => any>; + onVisibleMonthsChange: PropTypes.Requireable<(...args: any[]) => any>; + disableMonthChange: PropTypes.Requireable; + enableSwipeMonths: PropTypes.Requireable; + disabledByDefault: PropTypes.Requireable; + headerStyle: PropTypes.Requireable; + customHeader: PropTypes.Requireable; + day: PropTypes.Requireable; + dayComponent: PropTypes.Requireable; + onLongPress: PropTypes.Requireable<(...args: any[]) => any>; + onPress: PropTypes.Requireable<(...args: any[]) => any>; + state: PropTypes.Requireable; + marking: PropTypes.Requireable; + markingType: PropTypes.Requireable; + disableAllTouchEventsForDisabledDays: PropTypes.Requireable; + month: PropTypes.Requireable; + addMonth: PropTypes.Requireable<(...args: any[]) => any>; + monthFormat: PropTypes.Requireable; + hideDayNames: PropTypes.Requireable; + hideArrows: PropTypes.Requireable; + renderArrow: PropTypes.Requireable<(...args: any[]) => any>; + onPressArrowLeft: PropTypes.Requireable<(...args: any[]) => any>; + onPressArrowRight: PropTypes.Requireable<(...args: any[]) => any>; + disableArrowLeft: PropTypes.Requireable; + disableArrowRight: PropTypes.Requireable; + disabledDaysIndexes: PropTypes.Requireable<(number | null | undefined)[]>; + renderHeader: PropTypes.Requireable; + webAriaLevel: PropTypes.Requireable; + }; + static defaultProps: { + calendarWidth: number; + calendarHeight: number; + pastScrollRange: number; + futureScrollRange: number; + showScrollIndicator: boolean; + horizontal: boolean; + scrollsToTop: boolean; + scrollEnabled: boolean; + removeClippedSubviews: boolean; + keyExtractor: (_: any, index: number) => string; + }; + style: any; + listView: FlatList | undefined | null; + viewabilityConfig: { + itemVisiblePercentThreshold: number; + }; + constructor(props: CalendarListProps); + componentDidUpdate(prevProps: CalendarListProps): void; + static getDerivedStateFromProps(_: CalendarListProps, prevState: CalendarListState): { + rows: (string | XDate)[]; + }; + scrollToDay(d: XDate, offset: number, animated: boolean): void; + scrollToMonth: (m: XDate) => void; + getItemLayout: (_: Array | undefined | null, index: number) => { + length: number; + offset: number; + index: number; + }; + getMonthIndex(month: XDate): number; + addMonth: (count: number) => void; + updateMonth(day: XDate, doNotTriggerListeners?: boolean): void; + onViewableItemsChanged: ({ viewableItems }: any) => void; + renderItem: ({ item }: any) => JSX.Element; + renderStaticHeader(): JSX.Element | undefined; + render(): JSX.Element; +} +export default CalendarList; diff --git a/src/calendar-list/index.js b/src/calendar-list/index.js new file mode 100644 index 0000000000..86e3a8d191 --- /dev/null +++ b/src/calendar-list/index.js @@ -0,0 +1,253 @@ +import _ from 'lodash'; +import PropTypes from 'prop-types'; +import XDate from 'xdate'; +import React, { Component } from 'react'; +import { FlatList, Platform, Dimensions, View } from 'react-native'; +// @ts-expect-error +import { extractComponentProps } from '../component-updater'; +// @ts-expect-error +import { xdateToData, parseDate } from '../interface'; +// @ts-expect-error +import dateutils from '../dateutils'; +// @ts-expect-error +import { STATIC_HEADER } from '../testIDs'; +import styleConstructor from './style'; +import Calendar from '../calendar'; +import CalendarListItem from './item'; +import CalendarHeader from '../calendar/header/index'; +const { width } = Dimensions.get('window'); +const CALENDAR_WIDTH = width; +const CALENDAR_HEIGHT = 360; +const PAST_SCROLL_RANGE = 50; +const FUTURE_SCROLL_RANGE = 50; +/** + * @description: Calendar List component for both vertical and horizontal calendars + * @extends: Calendar + * @extendslink: docs/Calendar + * @example: https://github.com/wix/react-native-calendars/blob/master/example/src/screens/calendarsList.js + * @gif: https://github.com/wix/react-native-calendars/blob/master/demo/calendar-list.gif + */ +class CalendarList extends Component { + static displayName = 'CalendarList'; + static propTypes = { + ...Calendar.propTypes, + /** Max amount of months allowed to scroll to the past. Default = 50 */ + pastScrollRange: PropTypes.number, + /** Max amount of months allowed to scroll to the future. Default = 50 */ + futureScrollRange: PropTypes.number, + /** Used when calendar scroll is horizontal, default is device width, pagination should be disabled */ + calendarWidth: PropTypes.number, + /** Dynamic calendar height */ + calendarHeight: PropTypes.number, + /** Style for the List item (the calendar) */ + calendarStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.number, PropTypes.array]), + /** Whether to use static header that will not scroll with the list (horizontal only) */ + staticHeader: PropTypes.bool, + /** Enable or disable vertical / horizontal scroll indicator. Default = false */ + showScrollIndicator: PropTypes.bool, + /** Whether to animate the auto month scroll */ + animateScroll: PropTypes.bool, + /** Enable or disable scrolling of calendar list */ + scrollEnabled: PropTypes.bool, + /** When true, the calendar list scrolls to top when the status bar is tapped. Default = true */ + scrollsToTop: PropTypes.bool, + /** Enable or disable paging on scroll */ + pagingEnabled: PropTypes.bool, + /** Whether the scroll is horizontal */ + horizontal: PropTypes.bool, + /** Should Keyboard persist taps */ + keyboardShouldPersistTaps: PropTypes.oneOf(['never', 'always', 'handled']), + /** A custom key extractor for the generated calendar months */ + keyExtractor: PropTypes.func, + /** How far from the end to trigger the onEndReached callback */ + onEndReachedThreshold: PropTypes.number, + /** Called once when the scroll position gets within onEndReachedThreshold */ + onEndReached: PropTypes.func + }; + static defaultProps = { + calendarWidth: CALENDAR_WIDTH, + calendarHeight: CALENDAR_HEIGHT, + pastScrollRange: PAST_SCROLL_RANGE, + futureScrollRange: FUTURE_SCROLL_RANGE, + showScrollIndicator: false, + horizontal: false, + scrollsToTop: false, + scrollEnabled: true, + removeClippedSubviews: Platform.OS === 'android', + keyExtractor: (_, index) => String(index) + }; + style; + listView; + viewabilityConfig = { + itemVisiblePercentThreshold: 20 + }; + constructor(props) { + super(props); + this.style = styleConstructor(props.theme); + const rows = []; + const texts = []; + const date = parseDate(props.current) || new XDate(); + const { pastScrollRange = PAST_SCROLL_RANGE, futureScrollRange = FUTURE_SCROLL_RANGE } = props; + for (let i = 0; i <= pastScrollRange + futureScrollRange; i++) { + const rangeDate = date.clone().addMonths(i - pastScrollRange, true); + const rangeDateStr = rangeDate.toString('MMM yyyy'); + texts.push(rangeDateStr); + /* + * This selects range around current shown month [-0, +2] or [-1, +1] month for detail calendar rendering. + * If `this.pastScrollRange` is `undefined` it's equal to `false` or 0 in next condition. + */ + if ((pastScrollRange - 1 <= i && i <= pastScrollRange + 1) || + (!pastScrollRange && i <= pastScrollRange + 2)) { + rows.push(rangeDate); + } + else { + rows.push(rangeDateStr); + } + } + this.state = { + rows, + texts, + openDate: date, + currentMonth: parseDate(props.current) + }; + } + componentDidUpdate(prevProps) { + const prevCurrent = parseDate(prevProps.current); + const current = parseDate(this.props.current); + if (current && prevCurrent && current.getTime() !== prevCurrent.getTime()) { + this.scrollToMonth(current); + } + } + static getDerivedStateFromProps(_, prevState) { + const rowClone = prevState.rows; + const newRows = []; + for (let i = 0; i < rowClone.length; i++) { + let val = prevState.texts[i]; + // @ts-ignore + if (rowClone[i].getTime) { + val = rowClone[i].clone(); + // @ts-ignore + val.propBump = rowClone[i].propBump ? rowClone[i].propBump + 1 : 1; + } + newRows.push(val); + } + return { rows: newRows }; + } + scrollToDay(d, offset, animated) { + const { horizontal, calendarHeight = CALENDAR_HEIGHT, calendarWidth = CALENDAR_WIDTH, pastScrollRange = PAST_SCROLL_RANGE, firstDay } = this.props; + const day = parseDate(d); + const diffMonths = Math.round(this.state.openDate.clone().setDate(1).diffMonths(day.clone().setDate(1))); + const size = horizontal ? calendarWidth : calendarHeight; + let scrollAmount = size * pastScrollRange + diffMonths * size + (offset || 0); + if (!horizontal) { + let week = 0; + const days = dateutils.page(day, firstDay); + for (let i = 0; i < days.length; i++) { + week = Math.floor(i / 7); + if (dateutils.sameDate(days[i], day)) { + scrollAmount += 46 * week; + break; + } + } + } + this.listView?.scrollToOffset({ offset: scrollAmount, animated }); + } + scrollToMonth = (m) => { + const { horizontal, calendarHeight = CALENDAR_HEIGHT, calendarWidth = CALENDAR_WIDTH, pastScrollRange = PAST_SCROLL_RANGE, animateScroll = false } = this.props; + const month = parseDate(m); + const scrollTo = month || this.state.openDate; + let diffMonths = Math.round(this.state.openDate.clone().setDate(1).diffMonths(scrollTo.clone().setDate(1))); + const size = horizontal ? calendarWidth : calendarHeight; + const scrollAmount = size * pastScrollRange + diffMonths * size; + this.listView?.scrollToOffset({ offset: scrollAmount, animated: animateScroll }); + }; + getItemLayout = (_, index) => { + const { horizontal, calendarHeight = CALENDAR_HEIGHT, calendarWidth = CALENDAR_WIDTH } = this.props; + const size = horizontal ? calendarWidth : calendarHeight; + return { + length: size, + offset: size * index, + index + }; + }; + getMonthIndex(month) { + const { pastScrollRange = PAST_SCROLL_RANGE } = this.props; + let diffMonths = this.state.openDate.diffMonths(month) + pastScrollRange; + return diffMonths; + } + addMonth = (count) => { + this.updateMonth(this.state.currentMonth.clone().addMonths(count, true)); + }; + updateMonth(day, doNotTriggerListeners = false) { + if (day.toString('yyyy MM') === this.state.currentMonth.toString('yyyy MM')) { + return; + } + this.setState({ currentMonth: day.clone() }, () => { + this.scrollToMonth(this.state.currentMonth); + if (!doNotTriggerListeners) { + const currMont = this.state.currentMonth.clone(); + _.invoke(this.props, 'onMonthChange', xdateToData(currMont)); + _.invoke(this.props, 'onVisibleMonthsChange', [xdateToData(currMont)]); + } + }); + } + onViewableItemsChanged = ({ viewableItems }) => { + function rowIsCloseToViewable(index, distance) { + for (let i = 0; i < viewableItems.length; i++) { + if (Math.abs(index - parseInt(viewableItems[i].index)) <= distance) { + return true; + } + } + return false; + } + const rowclone = this.state.rows; + const newrows = []; + const visibleMonths = []; + for (let i = 0; i < rowclone.length; i++) { + let val = rowclone[i]; + const rowShouldBeRendered = rowIsCloseToViewable(i, 1); + const { pastScrollRange = PAST_SCROLL_RANGE } = this.props; + if (rowShouldBeRendered && !rowclone[i].getTime) { + val = this.state.openDate.clone().addMonths(i - pastScrollRange, true); + } + else if (!rowShouldBeRendered) { + val = this.state.texts[i]; + } + newrows.push(val); + if (rowIsCloseToViewable(i, 0)) { + visibleMonths.push(xdateToData(val)); + } + } + _.invoke(this.props, 'onVisibleMonthsChange', visibleMonths); + this.setState({ + // @ts-ignore + rows: newrows, + currentMonth: parseDate(visibleMonths[0]) + }); + }; + renderItem = ({ item }) => { + const { calendarStyle, horizontal, calendarWidth, testID, ...others } = this.props; + return (); + }; + renderStaticHeader() { + const { staticHeader, horizontal, headerStyle } = this.props; + const useStaticHeader = staticHeader && horizontal; + const headerProps = extractComponentProps(CalendarHeader, this.props); + if (useStaticHeader) { + return (); + } + } + render() { + const { style, pastScrollRange, futureScrollRange, horizontal, showScrollIndicator } = this.props; + return ( + (this.listView = c)} style={[this.style.container, style]} + // @ts-ignore + initialListSize={pastScrollRange + futureScrollRange + 1} // ListView deprecated + data={this.state.rows} renderItem={this.renderItem} getItemLayout={this.getItemLayout} onViewableItemsChanged={this.onViewableItemsChanged} viewabilityConfig={this.viewabilityConfig} initialScrollIndex={this.state.openDate ? this.getMonthIndex(this.state.openDate) : undefined} showsVerticalScrollIndicator={showScrollIndicator} showsHorizontalScrollIndicator={horizontal && showScrollIndicator} testID={this.props.testID} onLayout={this.props.onLayout} removeClippedSubviews={this.props.removeClippedSubviews} pagingEnabled={this.props.pagingEnabled} scrollEnabled={this.props.scrollEnabled} scrollsToTop={this.props.scrollsToTop} horizontal={this.props.horizontal} keyboardShouldPersistTaps={this.props.keyboardShouldPersistTaps} keyExtractor={this.props.keyExtractor} onEndReachedThreshold={this.props.onEndReachedThreshold} onEndReached={this.props.onEndReached}/> + {this.renderStaticHeader()} + ); + } +} +export default CalendarList; diff --git a/src/calendar-list/item.d.ts b/src/calendar-list/item.d.ts new file mode 100644 index 0000000000..f434e7e40d --- /dev/null +++ b/src/calendar-list/item.d.ts @@ -0,0 +1,79 @@ +/// +import PropTypes from 'prop-types'; +import { Component } from 'react'; +import { Theme } from '../commons/types'; +import { CalendarProps } from '../calendar'; +export declare type CalendarListItemProps = CalendarProps & { + item: any; + calendarWidth?: number; + calendarHeight?: number; + horizontal?: boolean; + theme?: Theme; + scrollToMonth?: (date: XDate) => void; +}; +declare type CalendarListItemState = { + hideArrows: boolean; + hideExtraDays: boolean; +}; +declare class CalendarListItem extends Component { + static displayName: string; + static propTypes: { + item: PropTypes.Requireable; + calendarWidth: PropTypes.Requireable; + calendarHeight: PropTypes.Requireable; + horizontal: PropTypes.Requireable; + theme: PropTypes.Requireable; + style: PropTypes.Requireable; + current: PropTypes.Requireable; + minDate: PropTypes.Requireable; + maxDate: PropTypes.Requireable; + firstDay: PropTypes.Requireable; + markedDates: PropTypes.Requireable; + displayLoadingIndicator: PropTypes.Requireable; + showWeekNumbers: PropTypes.Requireable; + hideExtraDays: PropTypes.Requireable; + showSixWeeks: PropTypes.Requireable; + onDayPress: PropTypes.Requireable<(...args: any[]) => any>; + onDayLongPress: PropTypes.Requireable<(...args: any[]) => any>; + onMonthChange: PropTypes.Requireable<(...args: any[]) => any>; + onVisibleMonthsChange: PropTypes.Requireable<(...args: any[]) => any>; + disableMonthChange: PropTypes.Requireable; + enableSwipeMonths: PropTypes.Requireable; + disabledByDefault: PropTypes.Requireable; + headerStyle: PropTypes.Requireable; + customHeader: PropTypes.Requireable; + day: PropTypes.Requireable; + dayComponent: PropTypes.Requireable; + onLongPress: PropTypes.Requireable<(...args: any[]) => any>; + onPress: PropTypes.Requireable<(...args: any[]) => any>; + state: PropTypes.Requireable; + marking: PropTypes.Requireable; + markingType: PropTypes.Requireable; + disableAllTouchEventsForDisabledDays: PropTypes.Requireable; + month: PropTypes.Requireable; + addMonth: PropTypes.Requireable<(...args: any[]) => any>; + monthFormat: PropTypes.Requireable; + hideDayNames: PropTypes.Requireable; + hideArrows: PropTypes.Requireable; + renderArrow: PropTypes.Requireable<(...args: any[]) => any>; + onPressArrowLeft: PropTypes.Requireable<(...args: any[]) => any>; + onPressArrowRight: PropTypes.Requireable<(...args: any[]) => any>; + disableArrowLeft: PropTypes.Requireable; + disableArrowRight: PropTypes.Requireable; + disabledDaysIndexes: PropTypes.Requireable<(number | null | undefined)[]>; + renderHeader: PropTypes.Requireable; + webAriaLevel: PropTypes.Requireable; + }; + static defaultProps: { + hideArrows: boolean; + hideExtraDays: boolean; + }; + style: any; + constructor(props: CalendarListItemProps); + shouldComponentUpdate(nextProps: CalendarListItemProps): boolean; + onPressArrowLeft: (_: any, month: any) => void; + onPressArrowRight: (_: any, month: any) => void; + getCalendarStyle: (this: any, width: any, height: any, style: any) => any[]; + render(): JSX.Element; +} +export default CalendarListItem; diff --git a/src/calendar-list/item.js b/src/calendar-list/item.js new file mode 100644 index 0000000000..08918de508 --- /dev/null +++ b/src/calendar-list/item.js @@ -0,0 +1,81 @@ +import PropTypes from 'prop-types'; +import memoize from 'memoize-one'; +import React, { Component } from 'react'; +import { Text, View } from 'react-native'; +// @ts-expect-error +import { extractComponentProps } from '../component-updater'; +import Calendar from '../calendar'; +import styleConstructor from './style'; +class CalendarListItem extends Component { + static displayName = 'IGNORE'; + static propTypes = { + ...Calendar.propTypes, + item: PropTypes.any, + calendarWidth: PropTypes.number, + calendarHeight: PropTypes.number, + horizontal: PropTypes.bool + }; + static defaultProps = { + hideArrows: true, + hideExtraDays: true + }; + style; + constructor(props) { + super(props); + this.style = styleConstructor(props.theme); + } + shouldComponentUpdate(nextProps) { + const r1 = this.props.item; + const r2 = nextProps.item; + return r1.toString('yyyy MM') !== r2.toString('yyyy MM') || !!(r2.propBump && r2.propBump !== r1.propBump); + } + onPressArrowLeft = (_, month) => { + const { onPressArrowLeft, scrollToMonth } = this.props; + const monthClone = month.clone(); + if (onPressArrowLeft) { + onPressArrowLeft(_, monthClone); + } + else if (scrollToMonth) { + const currentMonth = monthClone.getMonth(); + monthClone.addMonths(-1); + // Make sure we actually get the previous month, not just 30 days before currentMonth. + while (monthClone.getMonth() === currentMonth) { + monthClone.setDate(monthClone.getDate() - 1); + } + scrollToMonth(monthClone); + } + }; + onPressArrowRight = (_, month) => { + const { onPressArrowRight, scrollToMonth } = this.props; + const monthClone = month.clone(); + if (onPressArrowRight) { + onPressArrowRight(_, monthClone); + } + else if (scrollToMonth) { + monthClone.addMonths(1); + scrollToMonth(monthClone); + } + }; + getCalendarStyle = memoize((width, height, style) => { + return [{ width, height }, this.style.calendar, style]; + }); + render() { + const { item, horizontal, calendarHeight, calendarWidth, testID, style, headerStyle, onPressArrowLeft, onPressArrowRight, + // @ts-expect-error + context } = this.props; + const calendarProps = extractComponentProps(Calendar, this.props); + const calStyle = this.getCalendarStyle(calendarWidth, calendarHeight, style); + if (item.getTime) { + return (); + } + else { + const text = item.toString(); + return ( + + {text} + + ); + } + } +} +export default CalendarListItem; diff --git a/src/calendar-list/style.d.ts b/src/calendar-list/style.d.ts new file mode 100644 index 0000000000..aff133e52b --- /dev/null +++ b/src/calendar-list/style.d.ts @@ -0,0 +1,32 @@ +import { Theme } from '../commons/types'; +export default function getStyle(theme?: Theme): { + flatListContainer: { + flex: number | undefined; + }; + container: { + backgroundColor: string; + }; + placeholder: { + backgroundColor: string; + alignItems: "center"; + justifyContent: "center"; + }; + placeholderText: { + fontSize: number; + fontWeight: "200"; + color: string; + }; + calendar: { + paddingLeft: number; + paddingRight: number; + }; + staticHeader: { + position: "absolute"; + left: number; + right: number; + top: number; + backgroundColor: string; + paddingLeft: number; + paddingRight: number; + }; +}; diff --git a/src/calendar-list/style.js b/src/calendar-list/style.js new file mode 100644 index 0000000000..1f4eb23f59 --- /dev/null +++ b/src/calendar-list/style.js @@ -0,0 +1,37 @@ +import { Platform, StyleSheet } from 'react-native'; +import * as defaultStyle from '../style'; +export default function getStyle(theme = {}) { + const appStyle = { ...defaultStyle, ...theme }; + return StyleSheet.create({ + flatListContainer: { + flex: Platform.OS === 'web' ? 1 : undefined + }, + container: { + backgroundColor: appStyle.calendarBackground + }, + placeholder: { + backgroundColor: appStyle.calendarBackground, + alignItems: 'center', + justifyContent: 'center' + }, + placeholderText: { + fontSize: 30, + fontWeight: '200', + color: appStyle.dayTextColor + }, + calendar: { + paddingLeft: 15, + paddingRight: 15 + }, + staticHeader: { + position: 'absolute', + left: 0, + right: 0, + top: 0, + backgroundColor: appStyle.calendarBackground, + paddingLeft: 15, + paddingRight: 15 + }, + ...(theme.stylesheet?.['calendar-list']?.main || {}) + }); +} diff --git a/src/calendar/day/basic/index.d.ts b/src/calendar/day/basic/index.d.ts new file mode 100644 index 0000000000..220df45f2a --- /dev/null +++ b/src/calendar/day/basic/index.d.ts @@ -0,0 +1,123 @@ +import PropTypes from 'prop-types'; +import { Component } from 'react'; +import { MarkingTypes, MarkingProps } from '../marking'; +import { Theme } from '../../../commons/types'; +export interface BasicDayProps { + state?: 'selected' | 'disabled' | 'today'; + /** The marking object */ + marking?: MarkingProps; + /** Date marking style [simple/period/multi-dot/multi-period]. Default = 'simple' */ + markingType?: MarkingTypes; + /** Theme object */ + theme?: Theme; + /** onPress callback */ + onPress?: (date: Date) => void; + /** onLongPress callback */ + onLongPress?: (date: Date) => void; + /** The date to return from press callbacks */ + date?: Date; + /** Disable all touch events for disabled days. can be override with disableTouchEvent in markedDates*/ + disableAllTouchEventsForDisabledDays?: boolean; + /** Test ID*/ + testID?: string; + /** Accessibility label */ + accessibilityLabel?: string; +} +export default class BasicDay extends Component { + static displayName: string; + static propTypes: { + state: PropTypes.Requireable; + /** The marking object */ + marking: PropTypes.Requireable; + /** Date marking style [simple/period/multi-dot/multi-period]. Default = 'simple' */ + markingType: PropTypes.Requireable; + /** Theme object */ + theme: PropTypes.Requireable; + /** onPress callback */ + onPress: PropTypes.Requireable<(...args: any[]) => any>; + /** onLongPress callback */ + onLongPress: PropTypes.Requireable<(...args: any[]) => any>; + /** The date to return from press callbacks */ + date: PropTypes.Requireable; + /** Disable all touch events for disabled days. Can be override with disableTouchEvent in markedDates*/ + disableAllTouchEventsForDisabledDays: PropTypes.Requireable; + }; + style: { + container: { + alignSelf: "stretch"; + alignItems: "center"; + }; + base: { + width: number; + height: number; + alignItems: "center"; + }; + text: { + marginTop: number; + fontSize: number; + fontFamily: string; + fontWeight: string; + color: string; + backgroundColor: string; + }; + alignedText: { + marginTop: number; + }; + selected: { + backgroundColor: string; + borderRadius: number; + }; + today: { + backgroundColor: string | undefined; + borderRadius: number; + }; + todayText: { + color: string; + }; + selectedText: { + color: string; + }; + disabledText: { + color: string; + }; + dot: { + width: number; + height: number; + marginTop: number; + borderRadius: number; + opacity: number; + }; /** Date marking style [simple/period/multi-dot/multi-period]. Default = 'simple' */ + visibleDot: { + opacity: number; + backgroundColor: string; + }; + selectedDot: { + backgroundColor: string; /** Theme object */ + }; + disabledDot: { + backgroundColor: string; + }; + todayDot: { + backgroundColor: string; + }; + }; + shouldComponentUpdate(nextProps: BasicDayProps): any; + onPress: () => void; + onLongPress: () => void; + get marking(): MarkingProps; + shouldDisableTouchEvent(): boolean; + isSelected(): boolean; + isDisabled(): boolean; + isToday(): boolean; + isMultiDot(): boolean; + isMultiPeriod(): boolean; + isCustom(): boolean; + getContainerStyle(): object[]; + getTextStyle(): object[]; + renderMarking(): JSX.Element; + renderText(): JSX.Element; + renderContent(): JSX.Element; + renderContainer(): JSX.Element; + renderPeriodsContainer(): JSX.Element; + render(): JSX.Element; +} diff --git a/src/calendar/day/basic/index.js b/src/calendar/day/basic/index.js new file mode 100644 index 0000000000..ce85bd97a8 --- /dev/null +++ b/src/calendar/day/basic/index.js @@ -0,0 +1,152 @@ +import _ from 'lodash'; +import PropTypes from 'prop-types'; +import React, { Component, Fragment } from 'react'; +import { TouchableOpacity, Text, View } from 'react-native'; +// @ts-expect-error +import { shouldUpdate } from '../../../component-updater'; +import styleConstructor from './style'; +import Marking from '../marking'; +export default class BasicDay extends Component { + static displayName = 'IGNORE'; + static propTypes = { + state: PropTypes.oneOf(['selected', 'disabled', 'today', '']), + /** The marking object */ + marking: PropTypes.any, + /** Date marking style [simple/period/multi-dot/multi-period]. Default = 'simple' */ + markingType: PropTypes.oneOf(_.values(Marking.markingTypes)), + /** Theme object */ + theme: PropTypes.object, + /** onPress callback */ + onPress: PropTypes.func, + /** onLongPress callback */ + onLongPress: PropTypes.func, + /** The date to return from press callbacks */ + date: PropTypes.object, + /** Disable all touch events for disabled days. Can be override with disableTouchEvent in markedDates*/ + disableAllTouchEventsForDisabledDays: PropTypes.bool + }; + style = styleConstructor(this.props.theme); + shouldComponentUpdate(nextProps) { + return shouldUpdate(this.props, nextProps, [ + 'children', + 'state', + 'markingType', + 'marking', + 'onPress', + 'onLongPress', + 'date' + ]); + } + onPress = () => { + _.invoke(this.props, 'onPress', this.props.date); + }; + onLongPress = () => { + _.invoke(this.props, 'onLongPress', this.props.date); + }; + get marking() { + return this.props.marking || {}; + } + shouldDisableTouchEvent() { + const { disableAllTouchEventsForDisabledDays } = this.props; + const { disableTouchEvent } = this.marking; + let disableTouch = false; + if (typeof disableTouchEvent === 'boolean') { + disableTouch = disableTouchEvent; + } + else if (typeof disableAllTouchEventsForDisabledDays === 'boolean' && this.isDisabled()) { + disableTouch = disableAllTouchEventsForDisabledDays; + } + return disableTouch; + } + isSelected() { + return this.marking.selected || this.props.state === 'selected'; + } + isDisabled() { + return typeof this.marking.disabled !== 'undefined' ? this.marking.disabled : this.props.state === 'disabled'; + } + isToday() { + return this.props.state === 'today'; + } + isMultiDot() { + return this.props.markingType === Marking.markingTypes.MULTI_DOT; + } + isMultiPeriod() { + return this.props.markingType === Marking.markingTypes.MULTI_PERIOD; + } + isCustom() { + return this.props.markingType === Marking.markingTypes.CUSTOM; + } + getContainerStyle() { + const { customStyles, selectedColor } = this.marking; + const style = [this.style.base]; + if (this.isSelected()) { + style.push(this.style.selected); + if (selectedColor) { + style.push({ backgroundColor: selectedColor }); + } + } + else if (this.isToday()) { + style.push(this.style.today); + } + //Custom marking type + if (this.isCustom() && customStyles && customStyles.container) { + if (customStyles.container.borderRadius === undefined) { + customStyles.container.borderRadius = 16; + } + style.push(customStyles.container); + } + return style; + } + getTextStyle() { + const { customStyles, selectedTextColor } = this.marking; + const style = [this.style.text]; + if (this.isSelected()) { + style.push(this.style.selectedText); + if (selectedTextColor) { + style.push({ color: selectedTextColor }); + } + } + else if (this.isDisabled()) { + style.push(this.style.disabledText); + } + else if (this.isToday()) { + style.push(this.style.todayText); + } + //Custom marking type + if (this.isCustom() && customStyles && customStyles.text) { + style.push(customStyles.text); + } + return style; + } + renderMarking() { + const { theme, markingType } = this.props; + const { marked, dotColor, dots, periods } = this.marking; + return (); + } + renderText() { + return ( + {String(this.props.children)} + ); + } + renderContent() { + return ( + {this.renderText()} + {this.renderMarking()} + ); + } + renderContainer() { + const { activeOpacity } = this.marking; + return ( + {this.isMultiPeriod() ? this.renderText() : this.renderContent()} + ); + } + renderPeriodsContainer() { + return ( + {this.renderContainer()} + {this.renderMarking()} + ); + } + render() { + return this.isMultiPeriod() ? this.renderPeriodsContainer() : this.renderContainer(); + } +} diff --git a/src/calendar/day/basic/style.d.ts b/src/calendar/day/basic/style.d.ts new file mode 100644 index 0000000000..8122f992b3 --- /dev/null +++ b/src/calendar/day/basic/style.d.ts @@ -0,0 +1,60 @@ +import { Theme } from '../../../commons/types'; +export default function styleConstructor(theme?: Theme): { + container: { + alignSelf: "stretch"; + alignItems: "center"; + }; + base: { + width: number; + height: number; + alignItems: "center"; + }; + text: { + marginTop: number; + fontSize: number; + fontFamily: string; + fontWeight: string; + color: string; + backgroundColor: string; + }; + alignedText: { + marginTop: number; + }; + selected: { + backgroundColor: string; + borderRadius: number; + }; + today: { + backgroundColor: string | undefined; + borderRadius: number; + }; + todayText: { + color: string; + }; + selectedText: { + color: string; + }; + disabledText: { + color: string; + }; + dot: { + width: number; + height: number; + marginTop: number; + borderRadius: number; + opacity: number; + }; + visibleDot: { + opacity: number; + backgroundColor: string; + }; + selectedDot: { + backgroundColor: string; + }; + disabledDot: { + backgroundColor: string; + }; + todayDot: { + backgroundColor: string; + }; +}; diff --git a/src/calendar/day/basic/style.js b/src/calendar/day/basic/style.js new file mode 100644 index 0000000000..087d8fa262 --- /dev/null +++ b/src/calendar/day/basic/style.js @@ -0,0 +1,67 @@ +import { StyleSheet, Platform } from 'react-native'; +import * as defaultStyle from '../../../style'; +export default function styleConstructor(theme = {}) { + const appStyle = { ...defaultStyle, ...theme }; + return StyleSheet.create({ + container: { + alignSelf: 'stretch', + alignItems: 'center' + }, + base: { + width: 32, + height: 32, + alignItems: 'center' + }, + text: { + marginTop: Platform.OS === 'android' ? 4 : 6, + fontSize: appStyle.textDayFontSize, + fontFamily: appStyle.textDayFontFamily, + fontWeight: appStyle.textDayFontWeight, + color: appStyle.dayTextColor, + backgroundColor: 'rgba(255, 255, 255, 0)', + ...appStyle.textDayStyle + }, + alignedText: { + marginTop: Platform.OS === 'android' ? 4 : 6 + }, + selected: { + backgroundColor: appStyle.selectedDayBackgroundColor, + borderRadius: 16 + }, + today: { + backgroundColor: appStyle.todayBackgroundColor, + borderRadius: 16 + }, + todayText: { + color: appStyle.todayTextColor + }, + selectedText: { + color: appStyle.selectedDayTextColor + }, + disabledText: { + color: appStyle.textDisabledColor + }, + dot: { + width: 4, + height: 4, + marginTop: 1, + borderRadius: 2, + opacity: 0, + ...appStyle.dotStyle + }, + visibleDot: { + opacity: 1, + backgroundColor: appStyle.dotColor + }, + selectedDot: { + backgroundColor: appStyle.selectedDotColor + }, + disabledDot: { + backgroundColor: appStyle.disabledDotColor || appStyle.dotColor + }, + todayDot: { + backgroundColor: appStyle.todayDotColor || appStyle.dotColor + }, + ...(theme.stylesheet?.day?.basic || {}) + }); +} diff --git a/src/calendar/day/dot/index.d.ts b/src/calendar/day/dot/index.d.ts new file mode 100644 index 0000000000..7572c0de13 --- /dev/null +++ b/src/calendar/day/dot/index.d.ts @@ -0,0 +1,23 @@ +/// +import PropTypes from 'prop-types'; +import { Theme } from '../../../commons/types'; +export interface DotProps { + theme?: Theme; + color?: String; + marked?: Boolean; + selected?: Boolean; + disabled?: Boolean; + today?: Boolean; +} +declare const Dot: { + ({ theme, marked, disabled, color, today, selected }: DotProps): JSX.Element; + propTypes: { + theme: PropTypes.Requireable; + color: PropTypes.Requireable; + marked: PropTypes.Requireable; + selected: PropTypes.Requireable; + disabled: PropTypes.Requireable; + today: PropTypes.Requireable; + }; +}; +export default Dot; diff --git a/src/calendar/day/dot/index.js b/src/calendar/day/dot/index.js new file mode 100644 index 0000000000..63e8dc0a67 --- /dev/null +++ b/src/calendar/day/dot/index.js @@ -0,0 +1,33 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import { View } from 'react-native'; +import styleConstructor from './style'; +const Dot = ({ theme, marked, disabled, color, today, selected }) => { + const style = styleConstructor(theme); + const dotStyle = [style.dot]; + if (marked) { + dotStyle.push(style.visibleDot); + if (today) { + dotStyle.push(style.todayDot); + } + if (disabled) { + dotStyle.push(style.disabledDot); + } + if (selected) { + dotStyle.push(style.selectedDot); + } + if (color) { + dotStyle.push({ backgroundColor: color }); + } + } + return ; +}; +export default Dot; +Dot.propTypes = { + theme: PropTypes.object, + color: PropTypes.string, + marked: PropTypes.bool, + selected: PropTypes.bool, + disabled: PropTypes.bool, + today: PropTypes.bool +}; diff --git a/src/calendar/day/dot/style.d.ts b/src/calendar/day/dot/style.d.ts new file mode 100644 index 0000000000..444c11ef99 --- /dev/null +++ b/src/calendar/day/dot/style.d.ts @@ -0,0 +1,24 @@ +import { Theme } from '../../../commons/types'; +export default function styleConstructor(theme?: Theme): { + dot: { + width: number; + height: number; + marginTop: number; + marginHorizontal: number; + borderRadius: number; + opacity: number; + }; + visibleDot: { + opacity: number; + backgroundColor: string; + }; + selectedDot: { + backgroundColor: string; + }; + disabledDot: { + backgroundColor: string; + }; + todayDot: { + backgroundColor: string; + }; +}; diff --git a/src/calendar/day/dot/style.js b/src/calendar/day/dot/style.js new file mode 100644 index 0000000000..02f07fa3d3 --- /dev/null +++ b/src/calendar/day/dot/style.js @@ -0,0 +1,30 @@ +import { StyleSheet } from 'react-native'; +import * as defaultStyle from '../../../style'; +export default function styleConstructor(theme = {}) { + const appStyle = { ...defaultStyle, ...theme }; + return StyleSheet.create({ + dot: { + width: 4, + height: 4, + marginTop: 1, + marginHorizontal: 1, + borderRadius: 2, + opacity: 0, + ...appStyle.dotStyle + }, + visibleDot: { + opacity: 1, + backgroundColor: appStyle.dotColor + }, + selectedDot: { + backgroundColor: appStyle.selectedDotColor + }, + disabledDot: { + backgroundColor: appStyle.disabledDotColor || appStyle.dotColor + }, + todayDot: { + backgroundColor: appStyle.todayDotColor || appStyle.dotColor + }, + ...(theme.stylesheet?.dot || {}) + }); +} diff --git a/src/calendar/day/index.d.ts b/src/calendar/day/index.d.ts new file mode 100644 index 0000000000..f95403c635 --- /dev/null +++ b/src/calendar/day/index.d.ts @@ -0,0 +1,31 @@ +import PropTypes from 'prop-types'; +import { Component } from 'react'; +import { BasicDayProps } from './basic'; +import { MarkingProps } from './marking'; +export interface DayProps extends Omit { + /** The day to render */ + day?: Date; + /** Provide custom day rendering component */ + dayComponent?: any; +} +export default class Day extends Component { + static displayName: string; + static propTypes: { + /** The day to render */ + day: PropTypes.Requireable; + /** Provide custom day rendering component */ + dayComponent: PropTypes.Requireable; + theme: PropTypes.Requireable; + onLongPress: PropTypes.Requireable<(...args: any[]) => any>; + onPress: PropTypes.Requireable<(...args: any[]) => any>; + state: PropTypes.Requireable; + marking: PropTypes.Requireable; + markingType: PropTypes.Requireable; + disableAllTouchEventsForDisabledDays: PropTypes.Requireable; + }; + shouldComponentUpdate(nextProps: DayProps): any; + getMarkingLabel(marking: MarkingProps): string; + getAccessibilityLabel: (this: any, day: any, marking: any, isToday: any) => string; + getDayComponent(): any; + render(): JSX.Element; +} diff --git a/src/calendar/day/index.js b/src/calendar/day/index.js new file mode 100644 index 0000000000..1b8f8ffabe --- /dev/null +++ b/src/calendar/day/index.js @@ -0,0 +1,91 @@ +import _ from 'lodash'; +import PropTypes from 'prop-types'; +import XDate from 'xdate'; +import memoize from 'memoize-one'; +import React, { Component } from 'react'; +// @ts-expect-error +import { shouldUpdate } from '../../component-updater'; +// @ts-expect-error +import dateutils from '../../dateutils'; +// @ts-expect-error +import { xdateToData } from '../../interface'; +// @ts-expect-error +import { SELECT_DATE_SLOT } from '../../testIDs'; +import BasicDay from './basic'; +import PeriodDay from './period'; +const basicDayPropsTypes = _.omit(BasicDay.propTypes, 'date'); +export default class Day extends Component { + static displayName = 'IGNORE'; + static propTypes = { + ...basicDayPropsTypes, + /** The day to render */ + day: PropTypes.object, + /** Provide custom day rendering component */ + dayComponent: PropTypes.any + }; + shouldComponentUpdate(nextProps) { + return shouldUpdate(this.props, nextProps, [ + 'day', + 'dayComponent', + 'state', + 'markingType', + 'marking', + 'onPress', + 'onLongPress' + ]); + } + getMarkingLabel(marking) { + let label = ''; + if (marking) { + if (marking.accessibilityLabel) { + return marking.accessibilityLabel; + } + if (marking.selected) { + label += 'selected '; + if (!marking.marked) { + label += 'You have no entries for this day '; + } + } + if (marking.marked) { + label += 'You have entries for this day '; + } + if (marking.startingDay) { + label += 'period start '; + } + if (marking.endingDay) { + label += 'period end '; + } + if (marking.disabled || marking.disableTouchEvent) { + label += 'disabled '; + } + } + return label; + } + getAccessibilityLabel = memoize((day, marking, isToday) => { + const today = _.get(XDate, 'locales[XDate.defaultLocale].today'); + const formatAccessibilityLabel = _.get(XDate, 'locales[XDate.defaultLocale].formatAccessibilityLabel'); + const markingLabel = this.getMarkingLabel(marking); + if (formatAccessibilityLabel) { + return `${isToday ? today : ''} ${day.toString(formatAccessibilityLabel)} ${markingLabel}`; + } + return `${isToday ? 'today' : ''} ${day.toString('dddd d MMMM yyyy')} ${markingLabel}`; + }); + getDayComponent() { + const { dayComponent, markingType } = this.props; + if (dayComponent) { + return dayComponent; + } + return markingType === 'period' ? PeriodDay : BasicDay; + } + render() { + const { day, marking } = this.props; + const date = xdateToData(day); + const isToday = dateutils.isToday(day); + const Component = this.getDayComponent(); + const dayProps = _.omit(this.props, 'day'); + const accessibilityLabel = this.getAccessibilityLabel(day, marking, isToday); + return ( + {date ? day?.getDate() : day} + ); + } +} diff --git a/src/calendar/day/marking/index.d.ts b/src/calendar/day/marking/index.d.ts new file mode 100644 index 0000000000..53f97eb64e --- /dev/null +++ b/src/calendar/day/marking/index.d.ts @@ -0,0 +1,58 @@ +import { Component } from 'react'; +import { ViewStyle, TextStyle } from 'react-native'; +import { DotProps } from '../dot'; +import { Theme } from '../../../commons/types'; +export declare enum MarkingTypes { + DOT = "dot", + MULTI_DOT = "multi-dot", + PERIOD = "period", + MULTI_PERIOD = "multi-period", + CUSTOM = "custom" +} +declare type CustomStyle = { + container?: ViewStyle; + text?: TextStyle; +}; +declare type DOT = { + key?: string; + color: string; + selectedDotColor?: string; +}; +declare type PERIOD = { + color: string; + startingDay?: boolean; + endingDay?: boolean; +}; +export interface MarkingProps extends DotProps { + type?: MarkingTypes; + theme?: Theme; + selected?: boolean; + marked?: boolean; + today?: boolean; + disabled?: boolean; + disableTouchEvent?: boolean; + activeOpacity?: number; + selectedColor?: string; + selectedTextColor?: string; + dotColor?: string; + dots?: DOT[]; + periods?: PERIOD[]; + startingDay?: boolean; + endingDay?: boolean; + accessibilityLabel?: string; + customStyles?: CustomStyle; +} +export default class Marking extends Component { + static displayName: string; + static markingTypes: typeof MarkingTypes; + style: any; + constructor(props: MarkingProps); + shouldComponentUpdate(nextProps: MarkingProps): any; + getItems(items?: DOT[] | PERIOD[]): JSX.Element[] | undefined; + renderMarkingByType(): JSX.Element; + renderMultiMarkings(containerStyle: Object, items?: DOT[] | PERIOD[]): JSX.Element; + renderPeriod(index: number, item: any): JSX.Element; + renderDot(index?: number, item?: any): JSX.Element; + render(): JSX.Element; +} +export {}; diff --git a/src/calendar/day/marking/index.js b/src/calendar/day/marking/index.js new file mode 100644 index 0000000000..6c208e6fd0 --- /dev/null +++ b/src/calendar/day/marking/index.js @@ -0,0 +1,96 @@ +import _ from 'lodash'; +import React, { Component } from 'react'; +import { View } from 'react-native'; +// @ts-expect-error +import { shouldUpdate, extractComponentProps } from '../../../component-updater'; +import styleConstructor from './style'; +import Dot from '../dot'; +export var MarkingTypes; +(function (MarkingTypes) { + MarkingTypes["DOT"] = "dot"; + MarkingTypes["MULTI_DOT"] = "multi-dot"; + MarkingTypes["PERIOD"] = "period"; + MarkingTypes["MULTI_PERIOD"] = "multi-period"; + MarkingTypes["CUSTOM"] = "custom"; +})(MarkingTypes || (MarkingTypes = {})); +export default class Marking extends Component { + static displayName = 'IGNORE'; + static markingTypes = MarkingTypes; + style; + constructor(props) { + super(props); + this.style = styleConstructor(props.theme); + } + shouldComponentUpdate(nextProps) { + return shouldUpdate(this.props, nextProps, [ + 'type', + 'selected', + 'marked', + 'today', + 'disabled', + 'disableTouchEvent', + 'activeOpacity', + 'selectedColor', + 'selectedTextColor', + 'dotColor', + 'dots', + 'periods' + ]); + } + getItems(items) { + const { type } = this.props; + if (items && Array.isArray(items) && items.length > 0) { + // Filter out items so that we process only those which have color property + const validItems = _.filter(items, function (o) { return !o.color; }); + return validItems.map((item, index) => { + return type === MarkingTypes.MULTI_DOT ? this.renderDot(index, item) : this.renderPeriod(index, item); + }); + } + } + renderMarkingByType() { + const { type, dots, periods } = this.props; + switch (type) { + case MarkingTypes.MULTI_DOT: + return this.renderMultiMarkings(this.style.dots, dots); + case MarkingTypes.MULTI_PERIOD: + return this.renderMultiMarkings(this.style.periods, periods); + default: + return this.renderDot(); + } + } + renderMultiMarkings(containerStyle, items) { + return {this.getItems(items)}; + } + renderPeriod(index, item) { + const { color, startingDay, endingDay } = item; + const style = [ + this.style.period, + { + backgroundColor: color + } + ]; + if (startingDay) { + style.push(this.style.startingDay); + } + if (endingDay) { + style.push(this.style.endingDay); + } + return ; + } + renderDot(index, item) { + const { selected, dotColor } = this.props; + const dotProps = extractComponentProps(Dot, this.props); + let key = index; + let color = dotColor; + if (item) { + if (item.key) { + key = item.key; + } + color = selected && item.selectedDotColor ? item.selectedDotColor : item.color; + } + return ; + } + render() { + return this.renderMarkingByType(); + } +} diff --git a/src/calendar/day/marking/style.d.ts b/src/calendar/day/marking/style.d.ts new file mode 100644 index 0000000000..9feff3efda --- /dev/null +++ b/src/calendar/day/marking/style.d.ts @@ -0,0 +1,24 @@ +import { Theme } from '../../../commons/types'; +export default function styleConstructor(theme?: Theme): { + dots: { + flexDirection: "row"; + }; + periods: { + alignSelf: "stretch"; + }; + period: { + height: number; + marginVertical: number; + backgroundColor: string | undefined; + }; + startingDay: { + borderTopLeftRadius: number; + borderBottomLeftRadius: number; + marginLeft: number; + }; + endingDay: { + borderTopRightRadius: number; + borderBottomRightRadius: number; + marginRight: number; + }; +}; diff --git a/src/calendar/day/marking/style.js b/src/calendar/day/marking/style.js new file mode 100644 index 0000000000..b1eff69e32 --- /dev/null +++ b/src/calendar/day/marking/style.js @@ -0,0 +1,29 @@ +import { StyleSheet } from 'react-native'; +import * as defaultStyle from '../../style'; +export default function styleConstructor(theme = {}) { + const appStyle = { ...defaultStyle, ...theme }; + return StyleSheet.create({ + dots: { + flexDirection: 'row' + }, + periods: { + alignSelf: 'stretch' + }, + period: { + height: 4, + marginVertical: 1, + backgroundColor: appStyle.dotColor + }, + startingDay: { + borderTopLeftRadius: 2, + borderBottomLeftRadius: 2, + marginLeft: 4 + }, + endingDay: { + borderTopRightRadius: 2, + borderBottomRightRadius: 2, + marginRight: 4 + }, + ...(theme.stylesheet?.marking || {}) + }); +} diff --git a/src/calendar/day/period/index.d.ts b/src/calendar/day/period/index.d.ts new file mode 100644 index 0000000000..1e7ddcca70 --- /dev/null +++ b/src/calendar/day/period/index.d.ts @@ -0,0 +1,35 @@ +import PropTypes from 'prop-types'; +import { Component } from 'react'; +import { MarkingProps } from '../marking'; +import { Theme } from '../../../commons/types'; +interface PeriodDayProps { + state?: 'selected' | 'disabled' | 'today' | ''; + marking?: MarkingProps; + theme?: Theme; + onPress?: (date?: Date) => void; + onLongPress?: (date?: Date) => void; + date?: Date; + accessibilityLabel?: string; + testID?: string; +} +export default class PeriodDay extends Component { + static displayName: string; + static propTypes: { + state: PropTypes.Requireable; + marking: PropTypes.Requireable; + theme: PropTypes.Requireable; + onPress: PropTypes.Requireable<(...args: any[]) => any>; + onLongPress: PropTypes.Requireable<(...args: any[]) => any>; + date: PropTypes.Requireable; + }; + theme: Theme; + style: any; + markingStyle: any; + constructor(props: PeriodDayProps); + onPress: () => void; + onLongPress: () => void; + shouldComponentUpdate(nextProps: PeriodDayProps): any; + getDrawingStyle(marking?: any): any; + render(): JSX.Element; +} +export {}; diff --git a/src/calendar/day/period/index.js b/src/calendar/day/period/index.js new file mode 100644 index 0000000000..71a11abe0b --- /dev/null +++ b/src/calendar/day/period/index.js @@ -0,0 +1,192 @@ +import _ from 'lodash'; +import PropTypes from 'prop-types'; +import React, { Component } from 'react'; +import { TouchableWithoutFeedback, Text, View } from 'react-native'; +// @ts-expect-error +import { shouldUpdate } from '../../../component-updater'; +import * as defaultStyle from '../../../style'; +import styleConstructor from './style'; +import Dot from '../dot'; +export default class PeriodDay extends Component { + static displayName = 'IGNORE'; + static propTypes = { + state: PropTypes.oneOf(['selected', 'disabled', 'today', '']), + marking: PropTypes.any, + theme: PropTypes.object, + onPress: PropTypes.func, + onLongPress: PropTypes.func, + date: PropTypes.object + }; + theme; + style; + markingStyle; + constructor(props) { + super(props); + this.theme = { ...defaultStyle, ...(props.theme || {}) }; + this.style = styleConstructor(props.theme); + this.markingStyle = this.getDrawingStyle(props.marking); + } + onPress = () => { + this.props.onPress?.(this.props.date); + }; + onLongPress = () => { + this.props.onLongPress?.(this.props.date); + }; + shouldComponentUpdate(nextProps) { + const newMarkingStyle = this.getDrawingStyle(nextProps.marking); + if (!_.isEqual(this.markingStyle, newMarkingStyle)) { + this.markingStyle = newMarkingStyle; + return true; + } + return shouldUpdate(this.props, nextProps, ['children', 'state', 'marking', 'onPress', 'onLongPress', 'date']); + } + // TODO: refactor to use MarkingProps as the type + getDrawingStyle(marking) { + const defaultStyle = { textStyle: { color: undefined }, containerStyle: {} }; + if (!marking) { + return defaultStyle; + } + if (marking.disabled) { + defaultStyle.textStyle.color = this.style.disabledText.color; + } + else if (marking.selected) { + defaultStyle.textStyle.color = this.style.selectedText.color; + } + const resultStyle = [marking].reduce((prev, next) => { + // if (next.quickAction) { //??? + // if (next.first || next.last) { + // prev.containerStyle = this.style.firstQuickAction; + // prev.textStyle = this.style.firstQuickActionText; + // if (next.endSelected && next.first && !next.last) { + // prev.rightFillerStyle = '#c1e4fe'; + // } else if (next.endSelected && next.last && !next.first) { + // prev.leftFillerStyle = '#c1e4fe'; + // } + // } else if (!next.endSelected) { + // prev.containerStyle = this.style.quickAction; + // prev.textStyle = this.style.quickActionText; + // } else if (next.endSelected) { + // prev.leftFillerStyle = '#c1e4fe'; + // prev.rightFillerStyle = '#c1e4fe'; + // } + // return prev; + // } + // if (next.status === 'NotAvailable') { //??? + // prev.textStyle = this.style.naText; + // } + const color = next.color; + if (next.startingDay) { + prev.startingDay = { color }; + } + if (next.endingDay) { + prev.endingDay = { color }; + } + if (!next.startingDay && !next.endingDay) { + prev.day = { color }; + } + if (next.textColor) { + prev.textStyle.color = next.textColor; + } + if (marking.customTextStyle) { + defaultStyle.textStyle = marking.customTextStyle; + } + if (marking.customContainerStyle) { + defaultStyle.containerStyle = marking.customContainerStyle; + } + return prev; + }, defaultStyle); + return resultStyle; + } + render() { + const { state, marking } = this.props; + const containerStyle = [this.style.base]; + const textStyle = [this.style.text]; + let leftFillerStyle = { backgroundColor: undefined }; + let rightFillerStyle = { backgroundColor: undefined }; + let fillerStyle = {}; + let fillers; + // TODO: refactor - move all styling logic out of render() + if (state === 'disabled') { + textStyle.push(this.style.disabledText); + } + else if (state === 'today') { + containerStyle.push(this.style.today); + textStyle.push(this.style.todayText); + } + if (marking) { + containerStyle.push({ + borderRadius: 17, + overflow: 'hidden' + }); + const flags = this.markingStyle; + if (flags.textStyle) { + textStyle.push(flags.textStyle); + } + if (flags.containerStyle) { + containerStyle.push(flags.containerStyle); + } + if (flags.leftFillerStyle) { + leftFillerStyle.backgroundColor = flags.leftFillerStyle; + } + if (flags.rightFillerStyle) { + rightFillerStyle.backgroundColor = flags.rightFillerStyle; + } + if (flags.startingDay && !flags.endingDay) { + leftFillerStyle = { + backgroundColor: this.theme.calendarBackground + }; + rightFillerStyle = { + backgroundColor: flags.startingDay.color + }; + containerStyle.push({ + backgroundColor: flags.startingDay.color + }); + } + else if (flags.endingDay && !flags.startingDay) { + rightFillerStyle = { + backgroundColor: this.theme.calendarBackground + }; + leftFillerStyle = { + backgroundColor: flags.endingDay.color + }; + containerStyle.push({ + backgroundColor: flags.endingDay.color + }); + } + else if (flags.day) { + leftFillerStyle = { backgroundColor: flags.day.color }; + rightFillerStyle = { backgroundColor: flags.day.color }; + fillerStyle = { backgroundColor: flags.day.color }; + } + else if (flags.endingDay && flags.startingDay) { + rightFillerStyle = { + backgroundColor: this.theme.calendarBackground + }; + leftFillerStyle = { + backgroundColor: this.theme.calendarBackground + }; + containerStyle.push({ + backgroundColor: flags.endingDay.color + }); + } + // TODO: refactor - move all fillers logic out of render() + fillers = ( + + + ); + } + const { theme, accessibilityLabel, testID } = this.props; + // TODO: refactor - allow feedback for unmarked days + return ( + + {fillers} + + + {String(this.props.children)} + + + + + ); + } +} diff --git a/src/calendar/day/period/style.d.ts b/src/calendar/day/period/style.d.ts new file mode 100644 index 0000000000..64b9862e4e --- /dev/null +++ b/src/calendar/day/period/style.d.ts @@ -0,0 +1,49 @@ +import { Theme } from '../../../commons/types'; +export default function styleConstructor(theme?: Theme): { + wrapper: { + alignItems: "center"; + alignSelf: "stretch"; + marginLeft: number; + }; + base: { + width: number; + height: number; + alignItems: "center"; + }; + fillers: { + position: "absolute"; + height: number; + flexDirection: "row"; + left: number; + right: number; + }; + leftFiller: { + height: number; + flex: number; + }; + rightFiller: { + height: number; + flex: number; + }; + text: { + marginTop: number; + fontSize: number; + fontFamily: string; + fontWeight: string; + color: string; + backgroundColor: string; + }; + today: { + backgroundColor: string | undefined; + }; + todayText: { + fontWeight: "500"; + color: string; + }; + selectedText: { + color: string; + }; + disabledText: { + color: string; + }; +}; diff --git a/src/calendar/day/period/style.js b/src/calendar/day/period/style.js new file mode 100644 index 0000000000..0a6e7a272d --- /dev/null +++ b/src/calendar/day/period/style.js @@ -0,0 +1,73 @@ +import { StyleSheet } from 'react-native'; +import * as defaultStyle from '../../../style'; +const FILLER_HEIGHT = 34; +export default function styleConstructor(theme = {}) { + const appStyle = { ...defaultStyle, ...theme }; + return StyleSheet.create({ + wrapper: { + alignItems: 'center', + alignSelf: 'stretch', + marginLeft: -1 + }, + base: { + width: 38, + height: FILLER_HEIGHT, + alignItems: 'center' + }, + fillers: { + position: 'absolute', + height: FILLER_HEIGHT, + flexDirection: 'row', + left: 0, + right: 0 + }, + leftFiller: { + height: FILLER_HEIGHT, + flex: 1 + }, + rightFiller: { + height: FILLER_HEIGHT, + flex: 1 + }, + text: { + marginTop: 7, + fontSize: appStyle.textDayFontSize, + fontFamily: appStyle.textDayFontFamily, + fontWeight: appStyle.textDayFontWeight, + color: appStyle.dayTextColor, + backgroundColor: 'rgba(255, 255, 255, 0)' + }, + today: { + backgroundColor: appStyle.todayBackgroundColor + }, + todayText: { + fontWeight: '500', + color: theme.todayTextColor || appStyle.dayTextColor + }, + selectedText: { + color: appStyle.selectedDayTextColor + }, + disabledText: { + color: appStyle.textDisabledColor + }, + // quickAction: { + // backgroundColor: 'white', + // borderWidth: 1, + // borderColor: '#c1e4fe' + // }, + // quickActionText: { + // marginTop: 6, + // color: appStyle.textColor + // }, + // firstQuickAction: { + // backgroundColor: appStyle.textLinkColor + // }, + // firstQuickActionText: { + // color: 'white' + // }, + // naText: { + // color: '#b6c1cd' + // }, + ...(theme.stylesheet?.day?.period || {}) + }); +} diff --git a/src/calendar/header/index.d.ts b/src/calendar/header/index.d.ts new file mode 100644 index 0000000000..d1704f1086 --- /dev/null +++ b/src/calendar/header/index.d.ts @@ -0,0 +1,92 @@ +import PropTypes from 'prop-types'; +import XDate from 'xdate'; +import React, { Component, ReactNode } from 'react'; +import { ViewStyle, AccessibilityActionEvent } from 'react-native'; +import { Theme } from '../../commons/types'; +declare type Direction = 'left' | 'right'; +export interface CalendarHeaderProps { + theme?: Theme; + firstDay?: number; + displayLoadingIndicator?: boolean; + showWeekNumbers?: boolean; + month?: XDate; + addMonth?: (num: number) => void; + /** Month format in the title. Formatting values: http://arshaw.com/xdate/#Formatting */ + monthFormat?: string; + /** Hide day names */ + hideDayNames?: boolean; + /** Hide month navigation arrows */ + hideArrows?: boolean; + /** Replace default arrows with custom ones (direction can be 'left' or 'right') */ + renderArrow?: (direction: Direction) => ReactNode; + /** Handler which gets executed when press arrow icon left. It receive a callback can go back month */ + onPressArrowLeft?: (method: () => void, month?: XDate) => void; + /** Handler which gets executed when press arrow icon right. It receive a callback can go next month */ + onPressArrowRight?: (method: () => void, month?: XDate) => void; + /** Disable left arrow */ + disableArrowLeft?: boolean; + /** Disable right arrow */ + disableArrowRight?: boolean; + /** Apply custom disable color to selected day indexes */ + disabledDaysIndexes?: number[]; + /** Replace default month and year title with custom one. the function receive a date as parameter */ + renderHeader?: (date?: XDate) => ReactNode; + /** Provide aria-level for calendar heading for proper accessibility when used with web (react-native-web) */ + webAriaLevel?: number; + testID?: string; + style?: ViewStyle; + accessibilityElementsHidden?: boolean; + importantForAccessibility?: 'auto' | 'yes' | 'no' | 'no-hide-descendants'; +} +declare class CalendarHeader extends Component { + static displayName: string; + static propTypes: { + theme: PropTypes.Requireable; + firstDay: PropTypes.Requireable; + displayLoadingIndicator: PropTypes.Requireable; + showWeekNumbers: PropTypes.Requireable; + month: PropTypes.Requireable; + addMonth: PropTypes.Requireable<(...args: any[]) => any>; + /** Month format in the title. Formatting values: http://arshaw.com/xdate/#Formatting */ + monthFormat: PropTypes.Requireable; + /** Hide day names. Default = false */ + hideDayNames: PropTypes.Requireable; + /** Hide month navigation arrows. Default = false */ + hideArrows: PropTypes.Requireable; + /** Replace default arrows with custom ones (direction can be 'left' or 'right') */ + renderArrow: PropTypes.Requireable<(...args: any[]) => any>; + /** Handler which gets executed when press arrow icon left. It receive a callback can go back month */ + onPressArrowLeft: PropTypes.Requireable<(...args: any[]) => any>; + /** Handler which gets executed when press arrow icon right. It receive a callback can go next month */ + onPressArrowRight: PropTypes.Requireable<(...args: any[]) => any>; + /** Disable left arrow. Default = false */ + disableArrowLeft: PropTypes.Requireable; + /** Disable right arrow. Default = false */ + disableArrowRight: PropTypes.Requireable; + /** Apply custom disable color to selected day indexes */ + disabledDaysIndexes: PropTypes.Requireable<(number | null | undefined)[]>; + /** Replace default month and year title with custom one. the function receive a date as parameter. */ + renderHeader: PropTypes.Requireable; + /** Provide aria-level for calendar heading for proper accessibility when used with web (react-native-web) */ + webAriaLevel: PropTypes.Requireable; + }; + static defaultProps: { + monthFormat: string; + webAriaLevel: number; + }; + style: any; + constructor(props: CalendarHeaderProps); + shouldComponentUpdate(nextProps: CalendarHeaderProps): any; + addMonth: () => void; + subtractMonth: () => void; + onPressLeft: () => void; + onPressRight: () => void; + renderWeekDays: (this: any, weekDaysNames: any) => any; + renderHeader: () => React.ReactNode; + renderArrow(direction: Direction): JSX.Element; + renderIndicator(): JSX.Element | undefined; + renderDayNames(): JSX.Element | undefined; + render(): JSX.Element; + onAccessibilityAction: (event: AccessibilityActionEvent) => void; +} +export default CalendarHeader; diff --git a/src/calendar/header/index.js b/src/calendar/header/index.js new file mode 100644 index 0000000000..ef15e17957 --- /dev/null +++ b/src/calendar/header/index.js @@ -0,0 +1,184 @@ +import _ from 'lodash'; +import PropTypes from 'prop-types'; +import memoize from 'memoize-one'; +import XDate from 'xdate'; +import React, { Component, Fragment } from 'react'; +import { ActivityIndicator, Platform, View, Text, TouchableOpacity, Image } from 'react-native'; +// @ts-expect-error +import { shouldUpdate } from '../../component-updater'; +// @ts-expect-error +import { weekDayNames } from '../../dateutils'; +import { CHANGE_MONTH_LEFT_ARROW, CHANGE_MONTH_RIGHT_ARROW, HEADER_DAY_NAMES, HEADER_LOADING_INDICATOR, HEADER_MONTH_NAME +// @ts-expect-error + } from '../../testIDs'; +import styleConstructor from './style'; +class CalendarHeader extends Component { + static displayName = 'IGNORE'; + static propTypes = { + theme: PropTypes.object, + firstDay: PropTypes.number, + displayLoadingIndicator: PropTypes.bool, + showWeekNumbers: PropTypes.bool, + month: PropTypes.instanceOf(XDate), + addMonth: PropTypes.func, + /** Month format in the title. Formatting values: http://arshaw.com/xdate/#Formatting */ + monthFormat: PropTypes.string, + /** Hide day names. Default = false */ + hideDayNames: PropTypes.bool, + /** Hide month navigation arrows. Default = false */ + hideArrows: PropTypes.bool, + /** Replace default arrows with custom ones (direction can be 'left' or 'right') */ + renderArrow: PropTypes.func, + /** Handler which gets executed when press arrow icon left. It receive a callback can go back month */ + onPressArrowLeft: PropTypes.func, + /** Handler which gets executed when press arrow icon right. It receive a callback can go next month */ + onPressArrowRight: PropTypes.func, + /** Disable left arrow. Default = false */ + disableArrowLeft: PropTypes.bool, + /** Disable right arrow. Default = false */ + disableArrowRight: PropTypes.bool, + /** Apply custom disable color to selected day indexes */ + disabledDaysIndexes: PropTypes.arrayOf(PropTypes.number), + /** Replace default month and year title with custom one. the function receive a date as parameter. */ + renderHeader: PropTypes.any, + /** Provide aria-level for calendar heading for proper accessibility when used with web (react-native-web) */ + webAriaLevel: PropTypes.number + }; + static defaultProps = { + monthFormat: 'MMMM yyyy', + webAriaLevel: 1 + }; + style; + constructor(props) { + super(props); + this.style = styleConstructor(props.theme); + } + shouldComponentUpdate(nextProps) { + if (nextProps.month?.toString('yyyy MM') !== this.props.month?.toString('yyyy MM')) { + return true; + } + return shouldUpdate(this.props, nextProps, [ + 'displayLoadingIndicator', + 'hideDayNames', + 'firstDay', + 'showWeekNumbers', + 'monthFormat', + 'renderArrow', + 'disableArrowLeft', + 'disableArrowRight' + ]); + } + addMonth = () => { + const { addMonth } = this.props; + addMonth?.(1); + }; + subtractMonth = () => { + const { addMonth } = this.props; + addMonth?.(-1); + }; + onPressLeft = () => { + const { onPressArrowLeft, month } = this.props; + if (typeof onPressArrowLeft === 'function') { + return onPressArrowLeft(this.subtractMonth, month); + } + return this.subtractMonth(); + }; + onPressRight = () => { + const { onPressArrowRight, month } = this.props; + if (typeof onPressArrowRight === 'function') { + return onPressArrowRight(this.addMonth, month); + } + return this.addMonth(); + }; + renderWeekDays = memoize(weekDaysNames => { + const { disabledDaysIndexes } = this.props; + return weekDaysNames.map((day, idx) => { + const dayStyle = [this.style.dayHeader]; + if (_.includes(disabledDaysIndexes, idx)) { + dayStyle.push(this.style.disabledDayHeader); + } + if (this.style[`dayTextAtIndex${idx}`]) { + dayStyle.push(this.style[`dayTextAtIndex${idx}`]); + } + return ( + {day} + ); + }); + }); + renderHeader = () => { + const { renderHeader, month, monthFormat, testID, webAriaLevel } = this.props; + const webProps = Platform.OS === 'web' ? { 'aria-level': webAriaLevel } : {}; + if (renderHeader) { + return renderHeader(month); + } + return ( + + {month?.toString(monthFormat)} + + ); + }; + renderArrow(direction) { + const { hideArrows, disableArrowLeft, disableArrowRight, renderArrow, testID } = this.props; + if (hideArrows) { + return ; + } + const isLeft = direction === 'left'; + const id = isLeft ? CHANGE_MONTH_LEFT_ARROW : CHANGE_MONTH_RIGHT_ARROW; + const testId = testID ? `${id}-${testID}` : id; + const onPress = isLeft ? this.onPressLeft : this.onPressRight; + const imageSource = isLeft ? require('../img/previous.png') : require('../img/next.png'); + const renderArrowDirection = isLeft ? 'left' : 'right'; + const shouldDisable = isLeft ? disableArrowLeft : disableArrowRight; + return ( + {renderArrow ? (renderArrow(renderArrowDirection)) : ()} + ); + } + renderIndicator() { + const { displayLoadingIndicator, theme, testID } = this.props; + if (displayLoadingIndicator) { + return (); + } + } + renderDayNames() { + const { firstDay, hideDayNames, showWeekNumbers, testID } = this.props; + const weekDaysNames = weekDayNames(firstDay); + if (!hideDayNames) { + return ( + {showWeekNumbers && } + {this.renderWeekDays(weekDaysNames)} + ); + } + } + render() { + const { style, testID } = this.props; + return ( + + {this.renderArrow('left')} + + {this.renderHeader()} + {this.renderIndicator()} + + {this.renderArrow('right')} + + {this.renderDayNames()} + ); + } + onAccessibilityAction = (event) => { + switch (event.nativeEvent.actionName) { + case 'decrement': + this.onPressLeft(); + break; + case 'increment': + this.onPressRight(); + break; + default: + break; + } + }; +} +export default CalendarHeader; diff --git a/src/calendar/header/style.d.ts b/src/calendar/header/style.d.ts new file mode 100644 index 0000000000..38cb95c3c8 --- /dev/null +++ b/src/calendar/header/style.d.ts @@ -0,0 +1,50 @@ +import { Theme } from '../../commons/types'; +export default function (theme?: Theme): { + header: { + flexDirection: "row"; + justifyContent: "space-between"; + paddingLeft: number; + paddingRight: number; + marginTop: number; + alignItems: "center"; + }; + headerContainer: { + flexDirection: "row"; + }; + monthText: { + fontSize: number; + fontFamily: string; + fontWeight: string; + color: string; + margin: number; + }; + arrow: { + padding: number; + }; + arrowImage: { + width?: number | undefined; + height?: number | undefined; + tintColor: string; + }; + disabledArrowImage: { + tintColor: string; + }; + week: { + marginTop: number; + flexDirection: "row"; + justifyContent: "space-around"; + }; + dayHeader: { + marginTop: number; + marginBottom: number; + width: number; + textAlign: "center"; + fontSize: number; + fontFamily: string; + fontWeight: string | undefined; + color: string; + }; + disabledDayHeader: { + color: string; + }; +}; diff --git a/src/calendar/header/style.js b/src/calendar/header/style.js new file mode 100644 index 0000000000..df61cb2611 --- /dev/null +++ b/src/calendar/header/style.js @@ -0,0 +1,60 @@ +import { StyleSheet, Platform } from 'react-native'; +import * as defaultStyle from '../../style'; +export default function (theme = {}) { + const appStyle = { ...defaultStyle, ...theme }; + return StyleSheet.create({ + header: { + flexDirection: 'row', + justifyContent: 'space-between', + paddingLeft: 10, + paddingRight: 10, + marginTop: 6, + alignItems: 'center' + }, + headerContainer: { + flexDirection: 'row' + }, + monthText: { + fontSize: appStyle.textMonthFontSize, + fontFamily: appStyle.textMonthFontFamily, + fontWeight: appStyle.textMonthFontWeight, + color: appStyle.monthTextColor, + margin: 10 + }, + arrow: { + padding: 10, + ...appStyle.arrowStyle + }, + arrowImage: { + tintColor: appStyle.arrowColor, + ...Platform.select({ + web: { + width: appStyle.arrowWidth, + height: appStyle.arrowHeight + } + }) + }, + disabledArrowImage: { + tintColor: appStyle.disabledArrowColor + }, + week: { + marginTop: 7, + flexDirection: 'row', + justifyContent: 'space-around' + }, + dayHeader: { + marginTop: 2, + marginBottom: 7, + width: 32, + textAlign: 'center', + fontSize: appStyle.textDayHeaderFontSize, + fontFamily: appStyle.textDayHeaderFontFamily, + fontWeight: appStyle.textDayHeaderFontWeight, + color: appStyle.textSectionTitleColor + }, + disabledDayHeader: { + color: appStyle.textSectionTitleDisabledColor + }, + ...(theme.stylesheet?.calendar?.header || {}) + }); +} diff --git a/src/calendar/index.d.ts b/src/calendar/index.d.ts new file mode 100644 index 0000000000..a5daaa9ef4 --- /dev/null +++ b/src/calendar/index.d.ts @@ -0,0 +1,175 @@ +import PropTypes from 'prop-types'; +import XDate from 'xdate'; +import { Component, RefObject } from 'react'; +import { ViewStyle } from 'react-native'; +import CalendarHeader, { CalendarHeaderProps } from './header'; +import { DayProps } from './day/index'; +import { MarkingProps } from './day/marking'; +import { Theme } from '../commons/types'; +declare type MarkedDatesType = { + [key: string]: MarkingProps; +}; +export interface CalendarProps extends CalendarHeaderProps, DayProps { + /** Specify theme properties to override specific styles for calendar parts */ + theme?: Theme; + /** Specify style for calendar container element */ + style?: ViewStyle; + /** Initially visible month */ + current?: XDate; + /** Minimum date that can be selected, dates before minDate will be grayed out */ + minDate?: Date; + /** Maximum date that can be selected, dates after maxDate will be grayed out */ + maxDate?: Date; + /** If firstDay=1 week starts from Monday. Note that dayNames and dayNamesShort should still start from Sunday */ + firstDay?: number; + /** Collection of dates that have to be marked */ + markedDates?: MarkedDatesType; + /** Display loading indicator */ + displayLoadingIndicator?: boolean; + /** Show week numbers */ + showWeekNumbers?: boolean; + /** Do not show days of other months in month page */ + hideExtraDays?: boolean; + /** Always show six weeks on each month (only when hideExtraDays = false) */ + showSixWeeks?: boolean; + /** Handler which gets executed on day press */ + onDayPress?: (date: Date) => any; + /** Handler which gets executed on day long press */ + onDayLongPress?: (date: Date) => any; + /** Handler which gets executed when month changes in calendar */ + onMonthChange?: () => void; + /** Handler which gets executed when visible month changes in calendar */ + onVisibleMonthsChange?: () => void; + /** Disables changing month when click on days of other months (when hideExtraDays is false) */ + disableMonthChange?: boolean; + /** Enable the option to swipe between months */ + enableSwipeMonths?: boolean; + /** Disable days by default */ + disabledByDefault?: boolean; + /** Style passed to the header */ + headerStyle?: ViewStyle; + /** Allow rendering of a totally custom header */ + customHeader?: any; +} +interface CalendarState { + currentMonth: any; +} +/** + * @description: Calendar component + * @example: https://github.com/wix/react-native-calendars/blob/master/example/src/screens/calendars.js + * @gif: https://github.com/wix/react-native-calendars/blob/master/demo/calendar.gif + */ +declare class Calendar extends Component { + static displayName: string; + static propTypes: { + /** Specify theme properties to override specific styles for calendar parts. Default = {} */ + theme: PropTypes.Requireable; + /** Specify style for calendar container element. Default = {} */ + style: PropTypes.Requireable; + /** Initially visible month. Default = Date() */ + current: PropTypes.Requireable; + /** Minimum date that can be selected, dates before minDate will be grayed out. Default = undefined */ + minDate: PropTypes.Requireable; + /** Maximum date that can be selected, dates after maxDate will be grayed out. Default = undefined */ + maxDate: PropTypes.Requireable; + /** If firstDay=1 week starts from Monday. Note that dayNames and dayNamesShort should still start from Sunday. */ + firstDay: PropTypes.Requireable; + /** Collection of dates that have to be marked. Default = {} */ + markedDates: PropTypes.Requireable; + /** Display loading indicator. Default = false */ + displayLoadingIndicator: PropTypes.Requireable; + /** Show week numbers. Default = false */ + showWeekNumbers: PropTypes.Requireable; + /** Do not show days of other months in month page. Default = false */ + hideExtraDays: PropTypes.Requireable; + /** Always show six weeks on each month (only when hideExtraDays = false). Default = false */ + showSixWeeks: PropTypes.Requireable; + /** Handler which gets executed on day press. Default = undefined */ + onDayPress: PropTypes.Requireable<(...args: any[]) => any>; + /** Handler which gets executed on day long press. Default = undefined */ + onDayLongPress: PropTypes.Requireable<(...args: any[]) => any>; + /** Handler which gets executed when month changes in calendar. Default = undefined */ + onMonthChange: PropTypes.Requireable<(...args: any[]) => any>; + /** Handler which gets executed when visible month changes in calendar. Default = undefined */ + onVisibleMonthsChange: PropTypes.Requireable<(...args: any[]) => any>; + /** Disables changing month when click on days of other months (when hideExtraDays is false). Default = false */ + disableMonthChange: PropTypes.Requireable; + /** Enable the option to swipe between months. Default: false */ + enableSwipeMonths: PropTypes.Requireable; + /** Disable days by default. Default = false */ + disabledByDefault: PropTypes.Requireable; + /** Style passed to the header */ + headerStyle: PropTypes.Requireable; + /** Allow rendering of a totally custom header */ + customHeader: PropTypes.Requireable; + day: PropTypes.Requireable; + dayComponent: PropTypes.Requireable; + onLongPress: PropTypes.Requireable<(...args: any[]) => any>; + onPress: PropTypes.Requireable<(...args: any[]) => any>; + state: PropTypes.Requireable; + marking: PropTypes.Requireable; + markingType: PropTypes.Requireable; + disableAllTouchEventsForDisabledDays: PropTypes.Requireable; + month: PropTypes.Requireable; + addMonth: PropTypes.Requireable<(...args: any[]) => any>; + monthFormat: PropTypes.Requireable; + hideDayNames: PropTypes.Requireable; + hideArrows: PropTypes.Requireable; + renderArrow: PropTypes.Requireable<(...args: any[]) => any>; + onPressArrowLeft: PropTypes.Requireable<(...args: any[]) => any>; + onPressArrowRight: PropTypes.Requireable<(...args: any[]) => any>; + disableArrowLeft: PropTypes.Requireable; + disableArrowRight: PropTypes.Requireable; + disabledDaysIndexes: PropTypes.Requireable<(number | null | undefined)[]>; + renderHeader: PropTypes.Requireable; + webAriaLevel: PropTypes.Requireable; + }; + static defaultProps: { + enableSwipeMonths: boolean; + }; + state: { + currentMonth: any; + }; + style: { + container: { + paddingLeft: number; + paddingRight: number; + backgroundColor: string; + }; + dayContainer: { + flex: number; + alignItems: "center"; + }; + emptyDayContainer: { + flex: number; + }; + monthView: { + backgroundColor: string; + }; + week: { + marginTop: number; + marginBottom: number; + flexDirection: "row"; + justifyContent: "space-around"; + }; + }; + header: RefObject; + addMonth: (count: number) => void; + updateMonth: (day: any, doNotTriggerListeners?: boolean) => void; + handleDayInteraction(date: Date, interaction?: (date: Date) => any): void; + pressDay: (date: Date) => void; + longPressDay: (date: Date) => void; + swipeProps: { + onSwipe: (direction: string) => void; + }; + onSwipe: (gestureName: string) => void; + onSwipeLeft: () => void; + onSwipeRight: () => void; + renderWeekNumber: (this: any, weekNumber: any) => JSX.Element; + renderDay(day: Date, id: number): JSX.Element; + renderWeek(days: any, id: number): JSX.Element; + renderMonth(): JSX.Element; + renderHeader(): JSX.Element; + render(): JSX.Element; +} +export default Calendar; diff --git a/src/calendar/index.js b/src/calendar/index.js new file mode 100644 index 0000000000..7cdb3eba51 --- /dev/null +++ b/src/calendar/index.js @@ -0,0 +1,211 @@ +import _ from 'lodash'; +import PropTypes from 'prop-types'; +import XDate from 'xdate'; +import memoize from 'memoize-one'; +import React, { Component } from 'react'; +import { View } from 'react-native'; +// @ts-expect-error +import GestureRecognizer, { swipeDirections } from 'react-native-swipe-gestures'; +// @ts-expect-error +import dateutils from '../dateutils'; +// @ts-expect-error +import { xdateToData, parseDate, toMarkingFormat } from '../interface'; +// @ts-expect-error +import { getState } from '../day-state-manager'; +// import shouldComponentUpdate from './updater'; +// @ts-expect-error +import { extractComponentProps } from '../component-updater'; +// @ts-expect-error +import { WEEK_NUMBER } from '../testIDs'; +import styleConstructor from './style'; +import CalendarHeader from './header'; +import Day from './day/index'; +import BasicDay from './day/basic'; +/** + * @description: Calendar component + * @example: https://github.com/wix/react-native-calendars/blob/master/example/src/screens/calendars.js + * @gif: https://github.com/wix/react-native-calendars/blob/master/demo/calendar.gif + */ +class Calendar extends Component { + static displayName = 'Calendar'; + static propTypes = { + ...CalendarHeader.propTypes, + ...Day.propTypes, + /** Specify theme properties to override specific styles for calendar parts. Default = {} */ + theme: PropTypes.object, + /** Specify style for calendar container element. Default = {} */ + style: PropTypes.oneOfType([PropTypes.object, PropTypes.array, PropTypes.number]), + /** Initially visible month. Default = Date() */ + current: PropTypes.any, + /** Minimum date that can be selected, dates before minDate will be grayed out. Default = undefined */ + minDate: PropTypes.any, + /** Maximum date that can be selected, dates after maxDate will be grayed out. Default = undefined */ + maxDate: PropTypes.any, + /** If firstDay=1 week starts from Monday. Note that dayNames and dayNamesShort should still start from Sunday. */ + firstDay: PropTypes.number, + /** Collection of dates that have to be marked. Default = {} */ + markedDates: PropTypes.object, + /** Display loading indicator. Default = false */ + displayLoadingIndicator: PropTypes.bool, + /** Show week numbers. Default = false */ + showWeekNumbers: PropTypes.bool, + /** Do not show days of other months in month page. Default = false */ + hideExtraDays: PropTypes.bool, + /** Always show six weeks on each month (only when hideExtraDays = false). Default = false */ + showSixWeeks: PropTypes.bool, + /** Handler which gets executed on day press. Default = undefined */ + onDayPress: PropTypes.func, + /** Handler which gets executed on day long press. Default = undefined */ + onDayLongPress: PropTypes.func, + /** Handler which gets executed when month changes in calendar. Default = undefined */ + onMonthChange: PropTypes.func, + /** Handler which gets executed when visible month changes in calendar. Default = undefined */ + onVisibleMonthsChange: PropTypes.func, + /** Disables changing month when click on days of other months (when hideExtraDays is false). Default = false */ + disableMonthChange: PropTypes.bool, + /** Enable the option to swipe between months. Default: false */ + enableSwipeMonths: PropTypes.bool, + /** Disable days by default. Default = false */ + disabledByDefault: PropTypes.bool, + /** Style passed to the header */ + headerStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.number, PropTypes.array]), + /** Allow rendering of a totally custom header */ + customHeader: PropTypes.any + }; + static defaultProps = { + enableSwipeMonths: false + }; + state = { + currentMonth: this.props.current ? parseDate(this.props.current) : new XDate() + }; + style = styleConstructor(this.props.theme); + header = React.createRef(); + addMonth = (count) => { + this.updateMonth(this.state.currentMonth.clone().addMonths(count, true)); + }; + updateMonth = (day, doNotTriggerListeners = false) => { + if (day.toString('yyyy MM') === this.state.currentMonth.toString('yyyy MM')) { + return; + } + this.setState({ currentMonth: day.clone() }, () => { + if (!doNotTriggerListeners) { + const currMont = this.state.currentMonth.clone(); + _.invoke(this.props, 'onMonthChange', xdateToData(currMont)); + _.invoke(this.props, 'onVisibleMonthsChange', [xdateToData(currMont)]); + } + }); + }; + handleDayInteraction(date, interaction) { + const { disableMonthChange } = this.props; + const day = parseDate(date); + const minDate = parseDate(this.props.minDate); + const maxDate = parseDate(this.props.maxDate); + if (!(minDate && !dateutils.isGTE(day, minDate)) && !(maxDate && !dateutils.isLTE(day, maxDate))) { + const shouldUpdateMonth = disableMonthChange === undefined || !disableMonthChange; + if (shouldUpdateMonth) { + this.updateMonth(day); + } + if (interaction) { + interaction(xdateToData(day)); + } + } + } + pressDay = (date) => { + this.handleDayInteraction(date, this.props.onDayPress); + }; + longPressDay = (date) => { + this.handleDayInteraction(date, this.props.onDayLongPress); + }; + swipeProps = { onSwipe: (direction) => this.onSwipe(direction) }; + onSwipe = (gestureName) => { + const { SWIPE_UP, SWIPE_DOWN, SWIPE_LEFT, SWIPE_RIGHT } = swipeDirections; + switch (gestureName) { + case SWIPE_UP: + case SWIPE_DOWN: + break; + case SWIPE_LEFT: + this.onSwipeLeft(); + break; + case SWIPE_RIGHT: + this.onSwipeRight(); + break; + } + }; + onSwipeLeft = () => { + this.header?.current?.onPressRight(); + }; + onSwipeRight = () => { + this.header?.current?.onPressLeft(); + }; + renderWeekNumber = memoize(weekNumber => { + return ( + + {weekNumber} + + ); + }); + renderDay(day, id) { + const { hideExtraDays, markedDates } = this.props; + const dayProps = extractComponentProps(Day, this.props); + if (!dateutils.sameMonth(day, this.state.currentMonth) && hideExtraDays) { + return ; + } + return ( + + ); + } + renderWeek(days, id) { + const week = []; + days.forEach((day, id2) => { + week.push(this.renderDay(day, id2)); + }, this); + if (this.props.showWeekNumbers) { + week.unshift(this.renderWeekNumber(days[days.length - 1].getWeek())); + } + return ( + {week} + ); + } + renderMonth() { + const { currentMonth } = this.state; + const { firstDay, showSixWeeks, hideExtraDays } = this.props; + const shouldShowSixWeeks = showSixWeeks && !hideExtraDays; + const days = dateutils.page(currentMonth, firstDay, shouldShowSixWeeks); + const weeks = []; + while (days.length) { + weeks.push(this.renderWeek(days.splice(0, 7), weeks.length)); + } + return {weeks}; + } + renderHeader() { + const { customHeader, headerStyle, displayLoadingIndicator, markedDates, testID } = this.props; + const current = parseDate(this.props.current); + let indicator; + if (current) { + const lastMonthOfDay = toMarkingFormat(current.clone().addMonths(1, true).setDate(1).addDays(-1)); + if (displayLoadingIndicator && !(markedDates?.[lastMonthOfDay])) { + indicator = true; + } + } + const headerProps = extractComponentProps(CalendarHeader, this.props); + const CustomHeader = customHeader; + const HeaderComponent = customHeader ? CustomHeader : CalendarHeader; + return (); + } + render() { + const { enableSwipeMonths, style } = this.props; + const GestureComponent = enableSwipeMonths ? GestureRecognizer : View; + const gestureProps = enableSwipeMonths ? this.swipeProps : undefined; + return ( + + {this.renderHeader()} + {this.renderMonth()} + + ); + } +} +export default Calendar; diff --git a/src/calendar/style.d.ts b/src/calendar/style.d.ts new file mode 100644 index 0000000000..7eede9e14f --- /dev/null +++ b/src/calendar/style.d.ts @@ -0,0 +1,24 @@ +import { Theme } from '../commons/types'; +export default function getStyle(theme?: Theme): { + container: { + paddingLeft: number; + paddingRight: number; + backgroundColor: string; + }; + dayContainer: { + flex: number; + alignItems: "center"; + }; + emptyDayContainer: { + flex: number; + }; + monthView: { + backgroundColor: string; + }; + week: { + marginTop: number; + marginBottom: number; + flexDirection: "row"; + justifyContent: "space-around"; + }; +}; diff --git a/src/calendar/style.js b/src/calendar/style.js new file mode 100644 index 0000000000..9c46c79d1a --- /dev/null +++ b/src/calendar/style.js @@ -0,0 +1,29 @@ +import { StyleSheet } from 'react-native'; +import * as defaultStyle from '../style'; +export default function getStyle(theme = {}) { + const appStyle = { ...defaultStyle, ...theme }; + return StyleSheet.create({ + container: { + paddingLeft: 5, + paddingRight: 5, + backgroundColor: appStyle.calendarBackground + }, + dayContainer: { + flex: 1, + alignItems: 'center' + }, + emptyDayContainer: { + flex: 1 + }, + monthView: { + backgroundColor: appStyle.calendarBackground + }, + week: { + marginTop: 7, + marginBottom: 7, + flexDirection: 'row', + justifyContent: 'space-around' + }, + ...(theme.stylesheet?.calendar?.main || {}) + }); +} diff --git a/src/commons/types.d.ts b/src/commons/types.d.ts new file mode 100644 index 0000000000..87d67cab62 --- /dev/null +++ b/src/commons/types.d.ts @@ -0,0 +1,80 @@ +import { ColorValue } from 'react-native'; +export interface Theme { + container?: object; + contentStyle?: object; + header?: object; + headerText?: object; + arrowButton?: object; + event?: object; + eventTitle?: object; + eventSummary?: object; + eventTimes?: object; + line?: object; + lineNow?: object; + timeLabel?: object; + todayTextColor?: string; + calendarBackground?: string; + indicatorColor?: ColorValue | object; + stylesheet?: { + calendar?: { + main?: object; + header?: object; + }; + day?: { + basic?: object; + period?: object; + }; + dot?: object; + marking?: object; + 'calendar-list'?: { + main?: object; + }; + }; + textSectionTitleColor?: string; + textSectionTitleDisabledColor?: string; + dayTextColor?: string; + selectedDayTextColor?: string; + monthTextColor?: string; + selectedDayBackgroundColor?: string; + arrowColor?: string; + textDisabledColor?: string; + backgroundColor?: string; + dotColor?: string; + selectedDotColor?: string; + disabledArrowColor?: string; + textDayFontFamily?: string; + textMonthFontFamily?: string; + textDayHeaderFontFamily?: string; + textDayFontWeight?: string; + textMonthFontWeight?: string; + textDayHeaderFontWeight?: string; + textDayFontSize?: number; + textMonthFontSize?: number; + textDayHeaderFontSize?: number; + agendaDayTextColor?: string; + agendaDayNumColor?: string; + agendaTodayColor?: string; + agendaKnobColor?: string; + foregroundColor?: string; + separatorColor?: string; + processedColor?: string; + processingColor?: string; + failedColor?: string; + textSecondaryColor?: string; + textDefaultColor?: string; + textColor?: string; + textLinkColor?: string; + todayButtonFontFamily?: string; + todayButtonFontWeight?: string; + todayButtonFontSize?: number; + textDayStyle?: object; + dotStyle?: object; + arrowStyle?: object; + todayBackgroundColor?: string; + disabledDotColor?: string; + todayDotColor?: string; + todayButtonTextColor?: string; + todayButtonPosition?: string; + arrowHeight?: number; + arrowWidth?: number; +} diff --git a/src/commons/types.js b/src/commons/types.js new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/src/commons/types.js @@ -0,0 +1 @@ +export {}; diff --git a/src/style.d.ts b/src/style.d.ts new file mode 100644 index 0000000000..59be29d7db --- /dev/null +++ b/src/style.d.ts @@ -0,0 +1,48 @@ +export declare const foregroundColor = "white"; +export declare const backgroundColor = "#f2F4f5"; +export declare const separatorColor = "#f2F4f5"; +export declare const processedColor = "#a7e0a3"; +export declare const processingColor = "#ffce5c"; +export declare const failedColor = "#f67e7e"; +export declare const textSecondaryColor = "#7a92a5"; +export declare const textDefaultColor = "#2d4150"; +export declare const textColor = "#43515c"; +export declare const textLinkColor = "#00BBF2"; +export declare const textDayFontFamily = "System"; +export declare const textMonthFontFamily = "System"; +export declare const textDayHeaderFontFamily = "System"; +export declare const todayButtonFontFamily = "System"; +export declare const textDayFontWeight = "300"; +export declare const textMonthFontWeight = "300"; +export declare const textDayHeaderFontWeight: undefined; +export declare const todayButtonFontWeight = "600"; +export declare const textDayFontSize = 16; +export declare const textMonthFontSize = 16; +export declare const textDayHeaderFontSize = 13; +export declare const todayButtonFontSize = 14; +export declare const textDayStyle: undefined; +export declare const dotStyle: undefined; +export declare const arrowStyle: undefined; +export declare const calendarBackground = "white"; +export declare const textSectionTitleColor = "#b6c1cd"; +export declare const textSectionTitleDisabledColor = "#d9e1e8"; +export declare const selectedDayBackgroundColor = "#00BBF2"; +export declare const selectedDayTextColor = "white"; +export declare const todayBackgroundColor: undefined; +export declare const todayTextColor = "#00BBF2"; +export declare const dayTextColor = "#2d4150"; +export declare const textDisabledColor = "#d9e1e8"; +export declare const dotColor = "#00BBF2"; +export declare const selectedDotColor = "white"; +export declare const disabledDotColor: undefined; +export declare const todayDotColor: undefined; +export declare const arrowColor = "#00BBF2"; +export declare const disabledArrowColor = "#d9e1e8"; +export declare const monthTextColor = "#2d4150"; +export declare const indicatorColor: undefined; +export declare const agendaDayTextColor = "#7a92a5"; +export declare const agendaDayNumColor = "#7a92a5"; +export declare const agendaTodayColor = "#00BBF2"; +export declare const agendaKnobColor = "#f2F4f5"; +export declare const todayButtonTextColor = "#00BBF2"; +export declare const todayButtonPosition: undefined; diff --git a/src/style.js b/src/style.js new file mode 100644 index 0000000000..a266d05b18 --- /dev/null +++ b/src/style.js @@ -0,0 +1,48 @@ +export const foregroundColor = 'white'; +export const backgroundColor = '#f2F4f5'; // Agenda's reservations bg color +export const separatorColor = '#f2F4f5'; // not in use +export const processedColor = '#a7e0a3'; // not in use +export const processingColor = '#ffce5c'; // not in use +export const failedColor = '#f67e7e'; // not in use +export const textSecondaryColor = '#7a92a5'; // not in use +export const textDefaultColor = '#2d4150'; +export const textColor = '#43515c'; +export const textLinkColor = '#00BBF2'; +export const textDayFontFamily = 'System'; +export const textMonthFontFamily = 'System'; +export const textDayHeaderFontFamily = 'System'; +export const todayButtonFontFamily = 'System'; +export const textDayFontWeight = '300'; +export const textMonthFontWeight = '300'; +export const textDayHeaderFontWeight = undefined; +export const todayButtonFontWeight = '600'; +export const textDayFontSize = 16; +export const textMonthFontSize = 16; +export const textDayHeaderFontSize = 13; +export const todayButtonFontSize = 14; +export const textDayStyle = undefined; +export const dotStyle = undefined; +export const arrowStyle = undefined; +export const calendarBackground = foregroundColor; +export const textSectionTitleColor = '#b6c1cd'; +export const textSectionTitleDisabledColor = '#d9e1e8'; +export const selectedDayBackgroundColor = textLinkColor; +export const selectedDayTextColor = foregroundColor; +export const todayBackgroundColor = undefined; +export const todayTextColor = textLinkColor; +export const dayTextColor = textDefaultColor; +export const textDisabledColor = '#d9e1e8'; +export const dotColor = textLinkColor; +export const selectedDotColor = foregroundColor; +export const disabledDotColor = undefined; +export const todayDotColor = undefined; +export const arrowColor = textLinkColor; +export const disabledArrowColor = '#d9e1e8'; +export const monthTextColor = textDefaultColor; +export const indicatorColor = undefined; // use the default color of React Native ActivityIndicator +export const agendaDayTextColor = '#7a92a5'; +export const agendaDayNumColor = '#7a92a5'; +export const agendaTodayColor = textLinkColor; +export const agendaKnobColor = '#f2F4f5'; +export const todayButtonTextColor = textLinkColor; +export const todayButtonPosition = undefined; // right' / 'left'(default) From 71240d26d756d9bc09c6693898c49ae7c44114e6 Mon Sep 17 00:00:00 2001 From: Inbal Tish Date: Sun, 1 Aug 2021 13:54:51 +0300 Subject: [PATCH 057/109] Revert "d.ts files" This reverts commit 7e2d4febfc1a18075802e3db6e7950fc9b2a8814. --- src/calendar-list/index.d.ts | 173 ------------------- src/calendar-list/index.js | 253 ---------------------------- src/calendar-list/item.d.ts | 79 --------- src/calendar-list/item.js | 81 --------- src/calendar-list/style.d.ts | 32 ---- src/calendar-list/style.js | 37 ---- src/calendar/day/basic/index.d.ts | 123 -------------- src/calendar/day/basic/index.js | 152 ----------------- src/calendar/day/basic/style.d.ts | 60 ------- src/calendar/day/basic/style.js | 67 -------- src/calendar/day/dot/index.d.ts | 23 --- src/calendar/day/dot/index.js | 33 ---- src/calendar/day/dot/style.d.ts | 24 --- src/calendar/day/dot/style.js | 30 ---- src/calendar/day/index.d.ts | 31 ---- src/calendar/day/index.js | 91 ---------- src/calendar/day/marking/index.d.ts | 58 ------- src/calendar/day/marking/index.js | 96 ----------- src/calendar/day/marking/style.d.ts | 24 --- src/calendar/day/marking/style.js | 29 ---- src/calendar/day/period/index.d.ts | 35 ---- src/calendar/day/period/index.js | 192 --------------------- src/calendar/day/period/style.d.ts | 49 ------ src/calendar/day/period/style.js | 73 -------- src/calendar/header/index.d.ts | 92 ---------- src/calendar/header/index.js | 184 -------------------- src/calendar/header/style.d.ts | 50 ------ src/calendar/header/style.js | 60 ------- src/calendar/index.d.ts | 175 ------------------- src/calendar/index.js | 211 ----------------------- src/calendar/style.d.ts | 24 --- src/calendar/style.js | 29 ---- src/commons/types.d.ts | 80 --------- src/commons/types.js | 1 - src/style.d.ts | 48 ------ src/style.js | 48 ------ 36 files changed, 2847 deletions(-) delete mode 100644 src/calendar-list/index.d.ts delete mode 100644 src/calendar-list/index.js delete mode 100644 src/calendar-list/item.d.ts delete mode 100644 src/calendar-list/item.js delete mode 100644 src/calendar-list/style.d.ts delete mode 100644 src/calendar-list/style.js delete mode 100644 src/calendar/day/basic/index.d.ts delete mode 100644 src/calendar/day/basic/index.js delete mode 100644 src/calendar/day/basic/style.d.ts delete mode 100644 src/calendar/day/basic/style.js delete mode 100644 src/calendar/day/dot/index.d.ts delete mode 100644 src/calendar/day/dot/index.js delete mode 100644 src/calendar/day/dot/style.d.ts delete mode 100644 src/calendar/day/dot/style.js delete mode 100644 src/calendar/day/index.d.ts delete mode 100644 src/calendar/day/index.js delete mode 100644 src/calendar/day/marking/index.d.ts delete mode 100644 src/calendar/day/marking/index.js delete mode 100644 src/calendar/day/marking/style.d.ts delete mode 100644 src/calendar/day/marking/style.js delete mode 100644 src/calendar/day/period/index.d.ts delete mode 100644 src/calendar/day/period/index.js delete mode 100644 src/calendar/day/period/style.d.ts delete mode 100644 src/calendar/day/period/style.js delete mode 100644 src/calendar/header/index.d.ts delete mode 100644 src/calendar/header/index.js delete mode 100644 src/calendar/header/style.d.ts delete mode 100644 src/calendar/header/style.js delete mode 100644 src/calendar/index.d.ts delete mode 100644 src/calendar/index.js delete mode 100644 src/calendar/style.d.ts delete mode 100644 src/calendar/style.js delete mode 100644 src/commons/types.d.ts delete mode 100644 src/commons/types.js delete mode 100644 src/style.d.ts delete mode 100644 src/style.js diff --git a/src/calendar-list/index.d.ts b/src/calendar-list/index.d.ts deleted file mode 100644 index 87751e2169..0000000000 --- a/src/calendar-list/index.d.ts +++ /dev/null @@ -1,173 +0,0 @@ -import PropTypes from 'prop-types'; -import XDate from 'xdate'; -import { Component } from 'react'; -import { FlatList, ViewStyle, LayoutChangeEvent } from 'react-native'; -import { CalendarProps } from '../calendar'; -export declare type CalendarListProps = CalendarProps & { - /** Max amount of months allowed to scroll to the past. Default = 50 */ - pastScrollRange?: number; - /** Max amount of months allowed to scroll to the future. Default = 50 */ - futureScrollRange?: number; - /** Used when calendar scroll is horizontal, default is device width, pagination should be disabled */ - calendarWidth?: number; - /** Dynamic calendar height */ - calendarHeight?: number; - /** Style for the List item (the calendar) */ - calendarStyle?: ViewStyle; - /** Whether to use static header that will not scroll with the list (horizontal only) */ - staticHeader?: boolean; - /** Enable or disable vertical / horizontal scroll indicator. Default = false */ - showScrollIndicator?: boolean; - /** Whether to animate the auto month scroll */ - animateScroll?: boolean; - /** Enable or disable scrolling of calendar list */ - scrollEnabled?: boolean; - /** When true, the calendar list scrolls to top when the status bar is tapped. Default = true */ - scrollsToTop?: boolean; - /** Enable or disable paging on scroll */ - pagingEnabled?: boolean; - /** Whether the scroll is horizontal */ - horizontal?: boolean; - /** Should Keyboard persist taps */ - keyboardShouldPersistTaps?: 'never' | 'always' | 'handled'; - /** A custom key extractor for the generated calendar months */ - keyExtractor?: (item: any, index: number) => string; - /** How far from the end to trigger the onEndReached callback */ - onEndReachedThreshold?: number; - /** Called once when the scroll position gets within onEndReachedThreshold */ - onEndReached?: () => void; - /** onLayout event */ - onLayout?: (event: LayoutChangeEvent) => void; - removeClippedSubviews: boolean; -}; -declare type XDateAndBump = XDate & { - propBump?: number; -}; -declare type CalendarListState = { - rows: Array; - texts: Array; - openDate: XDate; - currentMonth: XDate; -}; -/** - * @description: Calendar List component for both vertical and horizontal calendars - * @extends: Calendar - * @extendslink: docs/Calendar - * @example: https://github.com/wix/react-native-calendars/blob/master/example/src/screens/calendarsList.js - * @gif: https://github.com/wix/react-native-calendars/blob/master/demo/calendar-list.gif - */ -declare class CalendarList extends Component { - static displayName: string; - static propTypes: { - /** Max amount of months allowed to scroll to the past. Default = 50 */ - pastScrollRange: PropTypes.Requireable; - /** Max amount of months allowed to scroll to the future. Default = 50 */ - futureScrollRange: PropTypes.Requireable; - /** Used when calendar scroll is horizontal, default is device width, pagination should be disabled */ - calendarWidth: PropTypes.Requireable; - /** Dynamic calendar height */ - calendarHeight: PropTypes.Requireable; - /** Style for the List item (the calendar) */ - calendarStyle: PropTypes.Requireable; - /** Whether to use static header that will not scroll with the list (horizontal only) */ - staticHeader: PropTypes.Requireable; - /** Enable or disable vertical / horizontal scroll indicator. Default = false */ - showScrollIndicator: PropTypes.Requireable; - /** Whether to animate the auto month scroll */ - animateScroll: PropTypes.Requireable; - /** Enable or disable scrolling of calendar list */ - scrollEnabled: PropTypes.Requireable; - /** When true, the calendar list scrolls to top when the status bar is tapped. Default = true */ - scrollsToTop: PropTypes.Requireable; - /** Enable or disable paging on scroll */ - pagingEnabled: PropTypes.Requireable; - /** Whether the scroll is horizontal */ - horizontal: PropTypes.Requireable; - /** Should Keyboard persist taps */ - keyboardShouldPersistTaps: PropTypes.Requireable; - /** A custom key extractor for the generated calendar months */ - keyExtractor: PropTypes.Requireable<(...args: any[]) => any>; - /** How far from the end to trigger the onEndReached callback */ - onEndReachedThreshold: PropTypes.Requireable; - /** Called once when the scroll position gets within onEndReachedThreshold */ - onEndReached: PropTypes.Requireable<(...args: any[]) => any>; - theme: PropTypes.Requireable; - style: PropTypes.Requireable; /** Dynamic calendar height */ - current: PropTypes.Requireable; - minDate: PropTypes.Requireable; /** Whether to use static header that will not scroll with the list (horizontal only) */ - maxDate: PropTypes.Requireable; - firstDay: PropTypes.Requireable; - markedDates: PropTypes.Requireable; - displayLoadingIndicator: PropTypes.Requireable; - showWeekNumbers: PropTypes.Requireable; /** Enable or disable paging on scroll */ - hideExtraDays: PropTypes.Requireable; - showSixWeeks: PropTypes.Requireable; - onDayPress: PropTypes.Requireable<(...args: any[]) => any>; - onDayLongPress: PropTypes.Requireable<(...args: any[]) => any>; - onMonthChange: PropTypes.Requireable<(...args: any[]) => any>; - onVisibleMonthsChange: PropTypes.Requireable<(...args: any[]) => any>; - disableMonthChange: PropTypes.Requireable; - enableSwipeMonths: PropTypes.Requireable; - disabledByDefault: PropTypes.Requireable; - headerStyle: PropTypes.Requireable; - customHeader: PropTypes.Requireable; - day: PropTypes.Requireable; - dayComponent: PropTypes.Requireable; - onLongPress: PropTypes.Requireable<(...args: any[]) => any>; - onPress: PropTypes.Requireable<(...args: any[]) => any>; - state: PropTypes.Requireable; - marking: PropTypes.Requireable; - markingType: PropTypes.Requireable; - disableAllTouchEventsForDisabledDays: PropTypes.Requireable; - month: PropTypes.Requireable; - addMonth: PropTypes.Requireable<(...args: any[]) => any>; - monthFormat: PropTypes.Requireable; - hideDayNames: PropTypes.Requireable; - hideArrows: PropTypes.Requireable; - renderArrow: PropTypes.Requireable<(...args: any[]) => any>; - onPressArrowLeft: PropTypes.Requireable<(...args: any[]) => any>; - onPressArrowRight: PropTypes.Requireable<(...args: any[]) => any>; - disableArrowLeft: PropTypes.Requireable; - disableArrowRight: PropTypes.Requireable; - disabledDaysIndexes: PropTypes.Requireable<(number | null | undefined)[]>; - renderHeader: PropTypes.Requireable; - webAriaLevel: PropTypes.Requireable; - }; - static defaultProps: { - calendarWidth: number; - calendarHeight: number; - pastScrollRange: number; - futureScrollRange: number; - showScrollIndicator: boolean; - horizontal: boolean; - scrollsToTop: boolean; - scrollEnabled: boolean; - removeClippedSubviews: boolean; - keyExtractor: (_: any, index: number) => string; - }; - style: any; - listView: FlatList | undefined | null; - viewabilityConfig: { - itemVisiblePercentThreshold: number; - }; - constructor(props: CalendarListProps); - componentDidUpdate(prevProps: CalendarListProps): void; - static getDerivedStateFromProps(_: CalendarListProps, prevState: CalendarListState): { - rows: (string | XDate)[]; - }; - scrollToDay(d: XDate, offset: number, animated: boolean): void; - scrollToMonth: (m: XDate) => void; - getItemLayout: (_: Array | undefined | null, index: number) => { - length: number; - offset: number; - index: number; - }; - getMonthIndex(month: XDate): number; - addMonth: (count: number) => void; - updateMonth(day: XDate, doNotTriggerListeners?: boolean): void; - onViewableItemsChanged: ({ viewableItems }: any) => void; - renderItem: ({ item }: any) => JSX.Element; - renderStaticHeader(): JSX.Element | undefined; - render(): JSX.Element; -} -export default CalendarList; diff --git a/src/calendar-list/index.js b/src/calendar-list/index.js deleted file mode 100644 index 86e3a8d191..0000000000 --- a/src/calendar-list/index.js +++ /dev/null @@ -1,253 +0,0 @@ -import _ from 'lodash'; -import PropTypes from 'prop-types'; -import XDate from 'xdate'; -import React, { Component } from 'react'; -import { FlatList, Platform, Dimensions, View } from 'react-native'; -// @ts-expect-error -import { extractComponentProps } from '../component-updater'; -// @ts-expect-error -import { xdateToData, parseDate } from '../interface'; -// @ts-expect-error -import dateutils from '../dateutils'; -// @ts-expect-error -import { STATIC_HEADER } from '../testIDs'; -import styleConstructor from './style'; -import Calendar from '../calendar'; -import CalendarListItem from './item'; -import CalendarHeader from '../calendar/header/index'; -const { width } = Dimensions.get('window'); -const CALENDAR_WIDTH = width; -const CALENDAR_HEIGHT = 360; -const PAST_SCROLL_RANGE = 50; -const FUTURE_SCROLL_RANGE = 50; -/** - * @description: Calendar List component for both vertical and horizontal calendars - * @extends: Calendar - * @extendslink: docs/Calendar - * @example: https://github.com/wix/react-native-calendars/blob/master/example/src/screens/calendarsList.js - * @gif: https://github.com/wix/react-native-calendars/blob/master/demo/calendar-list.gif - */ -class CalendarList extends Component { - static displayName = 'CalendarList'; - static propTypes = { - ...Calendar.propTypes, - /** Max amount of months allowed to scroll to the past. Default = 50 */ - pastScrollRange: PropTypes.number, - /** Max amount of months allowed to scroll to the future. Default = 50 */ - futureScrollRange: PropTypes.number, - /** Used when calendar scroll is horizontal, default is device width, pagination should be disabled */ - calendarWidth: PropTypes.number, - /** Dynamic calendar height */ - calendarHeight: PropTypes.number, - /** Style for the List item (the calendar) */ - calendarStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.number, PropTypes.array]), - /** Whether to use static header that will not scroll with the list (horizontal only) */ - staticHeader: PropTypes.bool, - /** Enable or disable vertical / horizontal scroll indicator. Default = false */ - showScrollIndicator: PropTypes.bool, - /** Whether to animate the auto month scroll */ - animateScroll: PropTypes.bool, - /** Enable or disable scrolling of calendar list */ - scrollEnabled: PropTypes.bool, - /** When true, the calendar list scrolls to top when the status bar is tapped. Default = true */ - scrollsToTop: PropTypes.bool, - /** Enable or disable paging on scroll */ - pagingEnabled: PropTypes.bool, - /** Whether the scroll is horizontal */ - horizontal: PropTypes.bool, - /** Should Keyboard persist taps */ - keyboardShouldPersistTaps: PropTypes.oneOf(['never', 'always', 'handled']), - /** A custom key extractor for the generated calendar months */ - keyExtractor: PropTypes.func, - /** How far from the end to trigger the onEndReached callback */ - onEndReachedThreshold: PropTypes.number, - /** Called once when the scroll position gets within onEndReachedThreshold */ - onEndReached: PropTypes.func - }; - static defaultProps = { - calendarWidth: CALENDAR_WIDTH, - calendarHeight: CALENDAR_HEIGHT, - pastScrollRange: PAST_SCROLL_RANGE, - futureScrollRange: FUTURE_SCROLL_RANGE, - showScrollIndicator: false, - horizontal: false, - scrollsToTop: false, - scrollEnabled: true, - removeClippedSubviews: Platform.OS === 'android', - keyExtractor: (_, index) => String(index) - }; - style; - listView; - viewabilityConfig = { - itemVisiblePercentThreshold: 20 - }; - constructor(props) { - super(props); - this.style = styleConstructor(props.theme); - const rows = []; - const texts = []; - const date = parseDate(props.current) || new XDate(); - const { pastScrollRange = PAST_SCROLL_RANGE, futureScrollRange = FUTURE_SCROLL_RANGE } = props; - for (let i = 0; i <= pastScrollRange + futureScrollRange; i++) { - const rangeDate = date.clone().addMonths(i - pastScrollRange, true); - const rangeDateStr = rangeDate.toString('MMM yyyy'); - texts.push(rangeDateStr); - /* - * This selects range around current shown month [-0, +2] or [-1, +1] month for detail calendar rendering. - * If `this.pastScrollRange` is `undefined` it's equal to `false` or 0 in next condition. - */ - if ((pastScrollRange - 1 <= i && i <= pastScrollRange + 1) || - (!pastScrollRange && i <= pastScrollRange + 2)) { - rows.push(rangeDate); - } - else { - rows.push(rangeDateStr); - } - } - this.state = { - rows, - texts, - openDate: date, - currentMonth: parseDate(props.current) - }; - } - componentDidUpdate(prevProps) { - const prevCurrent = parseDate(prevProps.current); - const current = parseDate(this.props.current); - if (current && prevCurrent && current.getTime() !== prevCurrent.getTime()) { - this.scrollToMonth(current); - } - } - static getDerivedStateFromProps(_, prevState) { - const rowClone = prevState.rows; - const newRows = []; - for (let i = 0; i < rowClone.length; i++) { - let val = prevState.texts[i]; - // @ts-ignore - if (rowClone[i].getTime) { - val = rowClone[i].clone(); - // @ts-ignore - val.propBump = rowClone[i].propBump ? rowClone[i].propBump + 1 : 1; - } - newRows.push(val); - } - return { rows: newRows }; - } - scrollToDay(d, offset, animated) { - const { horizontal, calendarHeight = CALENDAR_HEIGHT, calendarWidth = CALENDAR_WIDTH, pastScrollRange = PAST_SCROLL_RANGE, firstDay } = this.props; - const day = parseDate(d); - const diffMonths = Math.round(this.state.openDate.clone().setDate(1).diffMonths(day.clone().setDate(1))); - const size = horizontal ? calendarWidth : calendarHeight; - let scrollAmount = size * pastScrollRange + diffMonths * size + (offset || 0); - if (!horizontal) { - let week = 0; - const days = dateutils.page(day, firstDay); - for (let i = 0; i < days.length; i++) { - week = Math.floor(i / 7); - if (dateutils.sameDate(days[i], day)) { - scrollAmount += 46 * week; - break; - } - } - } - this.listView?.scrollToOffset({ offset: scrollAmount, animated }); - } - scrollToMonth = (m) => { - const { horizontal, calendarHeight = CALENDAR_HEIGHT, calendarWidth = CALENDAR_WIDTH, pastScrollRange = PAST_SCROLL_RANGE, animateScroll = false } = this.props; - const month = parseDate(m); - const scrollTo = month || this.state.openDate; - let diffMonths = Math.round(this.state.openDate.clone().setDate(1).diffMonths(scrollTo.clone().setDate(1))); - const size = horizontal ? calendarWidth : calendarHeight; - const scrollAmount = size * pastScrollRange + diffMonths * size; - this.listView?.scrollToOffset({ offset: scrollAmount, animated: animateScroll }); - }; - getItemLayout = (_, index) => { - const { horizontal, calendarHeight = CALENDAR_HEIGHT, calendarWidth = CALENDAR_WIDTH } = this.props; - const size = horizontal ? calendarWidth : calendarHeight; - return { - length: size, - offset: size * index, - index - }; - }; - getMonthIndex(month) { - const { pastScrollRange = PAST_SCROLL_RANGE } = this.props; - let diffMonths = this.state.openDate.diffMonths(month) + pastScrollRange; - return diffMonths; - } - addMonth = (count) => { - this.updateMonth(this.state.currentMonth.clone().addMonths(count, true)); - }; - updateMonth(day, doNotTriggerListeners = false) { - if (day.toString('yyyy MM') === this.state.currentMonth.toString('yyyy MM')) { - return; - } - this.setState({ currentMonth: day.clone() }, () => { - this.scrollToMonth(this.state.currentMonth); - if (!doNotTriggerListeners) { - const currMont = this.state.currentMonth.clone(); - _.invoke(this.props, 'onMonthChange', xdateToData(currMont)); - _.invoke(this.props, 'onVisibleMonthsChange', [xdateToData(currMont)]); - } - }); - } - onViewableItemsChanged = ({ viewableItems }) => { - function rowIsCloseToViewable(index, distance) { - for (let i = 0; i < viewableItems.length; i++) { - if (Math.abs(index - parseInt(viewableItems[i].index)) <= distance) { - return true; - } - } - return false; - } - const rowclone = this.state.rows; - const newrows = []; - const visibleMonths = []; - for (let i = 0; i < rowclone.length; i++) { - let val = rowclone[i]; - const rowShouldBeRendered = rowIsCloseToViewable(i, 1); - const { pastScrollRange = PAST_SCROLL_RANGE } = this.props; - if (rowShouldBeRendered && !rowclone[i].getTime) { - val = this.state.openDate.clone().addMonths(i - pastScrollRange, true); - } - else if (!rowShouldBeRendered) { - val = this.state.texts[i]; - } - newrows.push(val); - if (rowIsCloseToViewable(i, 0)) { - visibleMonths.push(xdateToData(val)); - } - } - _.invoke(this.props, 'onVisibleMonthsChange', visibleMonths); - this.setState({ - // @ts-ignore - rows: newrows, - currentMonth: parseDate(visibleMonths[0]) - }); - }; - renderItem = ({ item }) => { - const { calendarStyle, horizontal, calendarWidth, testID, ...others } = this.props; - return (); - }; - renderStaticHeader() { - const { staticHeader, horizontal, headerStyle } = this.props; - const useStaticHeader = staticHeader && horizontal; - const headerProps = extractComponentProps(CalendarHeader, this.props); - if (useStaticHeader) { - return (); - } - } - render() { - const { style, pastScrollRange, futureScrollRange, horizontal, showScrollIndicator } = this.props; - return ( - (this.listView = c)} style={[this.style.container, style]} - // @ts-ignore - initialListSize={pastScrollRange + futureScrollRange + 1} // ListView deprecated - data={this.state.rows} renderItem={this.renderItem} getItemLayout={this.getItemLayout} onViewableItemsChanged={this.onViewableItemsChanged} viewabilityConfig={this.viewabilityConfig} initialScrollIndex={this.state.openDate ? this.getMonthIndex(this.state.openDate) : undefined} showsVerticalScrollIndicator={showScrollIndicator} showsHorizontalScrollIndicator={horizontal && showScrollIndicator} testID={this.props.testID} onLayout={this.props.onLayout} removeClippedSubviews={this.props.removeClippedSubviews} pagingEnabled={this.props.pagingEnabled} scrollEnabled={this.props.scrollEnabled} scrollsToTop={this.props.scrollsToTop} horizontal={this.props.horizontal} keyboardShouldPersistTaps={this.props.keyboardShouldPersistTaps} keyExtractor={this.props.keyExtractor} onEndReachedThreshold={this.props.onEndReachedThreshold} onEndReached={this.props.onEndReached}/> - {this.renderStaticHeader()} - ); - } -} -export default CalendarList; diff --git a/src/calendar-list/item.d.ts b/src/calendar-list/item.d.ts deleted file mode 100644 index f434e7e40d..0000000000 --- a/src/calendar-list/item.d.ts +++ /dev/null @@ -1,79 +0,0 @@ -/// -import PropTypes from 'prop-types'; -import { Component } from 'react'; -import { Theme } from '../commons/types'; -import { CalendarProps } from '../calendar'; -export declare type CalendarListItemProps = CalendarProps & { - item: any; - calendarWidth?: number; - calendarHeight?: number; - horizontal?: boolean; - theme?: Theme; - scrollToMonth?: (date: XDate) => void; -}; -declare type CalendarListItemState = { - hideArrows: boolean; - hideExtraDays: boolean; -}; -declare class CalendarListItem extends Component { - static displayName: string; - static propTypes: { - item: PropTypes.Requireable; - calendarWidth: PropTypes.Requireable; - calendarHeight: PropTypes.Requireable; - horizontal: PropTypes.Requireable; - theme: PropTypes.Requireable; - style: PropTypes.Requireable; - current: PropTypes.Requireable; - minDate: PropTypes.Requireable; - maxDate: PropTypes.Requireable; - firstDay: PropTypes.Requireable; - markedDates: PropTypes.Requireable; - displayLoadingIndicator: PropTypes.Requireable; - showWeekNumbers: PropTypes.Requireable; - hideExtraDays: PropTypes.Requireable; - showSixWeeks: PropTypes.Requireable; - onDayPress: PropTypes.Requireable<(...args: any[]) => any>; - onDayLongPress: PropTypes.Requireable<(...args: any[]) => any>; - onMonthChange: PropTypes.Requireable<(...args: any[]) => any>; - onVisibleMonthsChange: PropTypes.Requireable<(...args: any[]) => any>; - disableMonthChange: PropTypes.Requireable; - enableSwipeMonths: PropTypes.Requireable; - disabledByDefault: PropTypes.Requireable; - headerStyle: PropTypes.Requireable; - customHeader: PropTypes.Requireable; - day: PropTypes.Requireable; - dayComponent: PropTypes.Requireable; - onLongPress: PropTypes.Requireable<(...args: any[]) => any>; - onPress: PropTypes.Requireable<(...args: any[]) => any>; - state: PropTypes.Requireable; - marking: PropTypes.Requireable; - markingType: PropTypes.Requireable; - disableAllTouchEventsForDisabledDays: PropTypes.Requireable; - month: PropTypes.Requireable; - addMonth: PropTypes.Requireable<(...args: any[]) => any>; - monthFormat: PropTypes.Requireable; - hideDayNames: PropTypes.Requireable; - hideArrows: PropTypes.Requireable; - renderArrow: PropTypes.Requireable<(...args: any[]) => any>; - onPressArrowLeft: PropTypes.Requireable<(...args: any[]) => any>; - onPressArrowRight: PropTypes.Requireable<(...args: any[]) => any>; - disableArrowLeft: PropTypes.Requireable; - disableArrowRight: PropTypes.Requireable; - disabledDaysIndexes: PropTypes.Requireable<(number | null | undefined)[]>; - renderHeader: PropTypes.Requireable; - webAriaLevel: PropTypes.Requireable; - }; - static defaultProps: { - hideArrows: boolean; - hideExtraDays: boolean; - }; - style: any; - constructor(props: CalendarListItemProps); - shouldComponentUpdate(nextProps: CalendarListItemProps): boolean; - onPressArrowLeft: (_: any, month: any) => void; - onPressArrowRight: (_: any, month: any) => void; - getCalendarStyle: (this: any, width: any, height: any, style: any) => any[]; - render(): JSX.Element; -} -export default CalendarListItem; diff --git a/src/calendar-list/item.js b/src/calendar-list/item.js deleted file mode 100644 index 08918de508..0000000000 --- a/src/calendar-list/item.js +++ /dev/null @@ -1,81 +0,0 @@ -import PropTypes from 'prop-types'; -import memoize from 'memoize-one'; -import React, { Component } from 'react'; -import { Text, View } from 'react-native'; -// @ts-expect-error -import { extractComponentProps } from '../component-updater'; -import Calendar from '../calendar'; -import styleConstructor from './style'; -class CalendarListItem extends Component { - static displayName = 'IGNORE'; - static propTypes = { - ...Calendar.propTypes, - item: PropTypes.any, - calendarWidth: PropTypes.number, - calendarHeight: PropTypes.number, - horizontal: PropTypes.bool - }; - static defaultProps = { - hideArrows: true, - hideExtraDays: true - }; - style; - constructor(props) { - super(props); - this.style = styleConstructor(props.theme); - } - shouldComponentUpdate(nextProps) { - const r1 = this.props.item; - const r2 = nextProps.item; - return r1.toString('yyyy MM') !== r2.toString('yyyy MM') || !!(r2.propBump && r2.propBump !== r1.propBump); - } - onPressArrowLeft = (_, month) => { - const { onPressArrowLeft, scrollToMonth } = this.props; - const monthClone = month.clone(); - if (onPressArrowLeft) { - onPressArrowLeft(_, monthClone); - } - else if (scrollToMonth) { - const currentMonth = monthClone.getMonth(); - monthClone.addMonths(-1); - // Make sure we actually get the previous month, not just 30 days before currentMonth. - while (monthClone.getMonth() === currentMonth) { - monthClone.setDate(monthClone.getDate() - 1); - } - scrollToMonth(monthClone); - } - }; - onPressArrowRight = (_, month) => { - const { onPressArrowRight, scrollToMonth } = this.props; - const monthClone = month.clone(); - if (onPressArrowRight) { - onPressArrowRight(_, monthClone); - } - else if (scrollToMonth) { - monthClone.addMonths(1); - scrollToMonth(monthClone); - } - }; - getCalendarStyle = memoize((width, height, style) => { - return [{ width, height }, this.style.calendar, style]; - }); - render() { - const { item, horizontal, calendarHeight, calendarWidth, testID, style, headerStyle, onPressArrowLeft, onPressArrowRight, - // @ts-expect-error - context } = this.props; - const calendarProps = extractComponentProps(Calendar, this.props); - const calStyle = this.getCalendarStyle(calendarWidth, calendarHeight, style); - if (item.getTime) { - return (); - } - else { - const text = item.toString(); - return ( - - {text} - - ); - } - } -} -export default CalendarListItem; diff --git a/src/calendar-list/style.d.ts b/src/calendar-list/style.d.ts deleted file mode 100644 index aff133e52b..0000000000 --- a/src/calendar-list/style.d.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { Theme } from '../commons/types'; -export default function getStyle(theme?: Theme): { - flatListContainer: { - flex: number | undefined; - }; - container: { - backgroundColor: string; - }; - placeholder: { - backgroundColor: string; - alignItems: "center"; - justifyContent: "center"; - }; - placeholderText: { - fontSize: number; - fontWeight: "200"; - color: string; - }; - calendar: { - paddingLeft: number; - paddingRight: number; - }; - staticHeader: { - position: "absolute"; - left: number; - right: number; - top: number; - backgroundColor: string; - paddingLeft: number; - paddingRight: number; - }; -}; diff --git a/src/calendar-list/style.js b/src/calendar-list/style.js deleted file mode 100644 index 1f4eb23f59..0000000000 --- a/src/calendar-list/style.js +++ /dev/null @@ -1,37 +0,0 @@ -import { Platform, StyleSheet } from 'react-native'; -import * as defaultStyle from '../style'; -export default function getStyle(theme = {}) { - const appStyle = { ...defaultStyle, ...theme }; - return StyleSheet.create({ - flatListContainer: { - flex: Platform.OS === 'web' ? 1 : undefined - }, - container: { - backgroundColor: appStyle.calendarBackground - }, - placeholder: { - backgroundColor: appStyle.calendarBackground, - alignItems: 'center', - justifyContent: 'center' - }, - placeholderText: { - fontSize: 30, - fontWeight: '200', - color: appStyle.dayTextColor - }, - calendar: { - paddingLeft: 15, - paddingRight: 15 - }, - staticHeader: { - position: 'absolute', - left: 0, - right: 0, - top: 0, - backgroundColor: appStyle.calendarBackground, - paddingLeft: 15, - paddingRight: 15 - }, - ...(theme.stylesheet?.['calendar-list']?.main || {}) - }); -} diff --git a/src/calendar/day/basic/index.d.ts b/src/calendar/day/basic/index.d.ts deleted file mode 100644 index 220df45f2a..0000000000 --- a/src/calendar/day/basic/index.d.ts +++ /dev/null @@ -1,123 +0,0 @@ -import PropTypes from 'prop-types'; -import { Component } from 'react'; -import { MarkingTypes, MarkingProps } from '../marking'; -import { Theme } from '../../../commons/types'; -export interface BasicDayProps { - state?: 'selected' | 'disabled' | 'today'; - /** The marking object */ - marking?: MarkingProps; - /** Date marking style [simple/period/multi-dot/multi-period]. Default = 'simple' */ - markingType?: MarkingTypes; - /** Theme object */ - theme?: Theme; - /** onPress callback */ - onPress?: (date: Date) => void; - /** onLongPress callback */ - onLongPress?: (date: Date) => void; - /** The date to return from press callbacks */ - date?: Date; - /** Disable all touch events for disabled days. can be override with disableTouchEvent in markedDates*/ - disableAllTouchEventsForDisabledDays?: boolean; - /** Test ID*/ - testID?: string; - /** Accessibility label */ - accessibilityLabel?: string; -} -export default class BasicDay extends Component { - static displayName: string; - static propTypes: { - state: PropTypes.Requireable; - /** The marking object */ - marking: PropTypes.Requireable; - /** Date marking style [simple/period/multi-dot/multi-period]. Default = 'simple' */ - markingType: PropTypes.Requireable; - /** Theme object */ - theme: PropTypes.Requireable; - /** onPress callback */ - onPress: PropTypes.Requireable<(...args: any[]) => any>; - /** onLongPress callback */ - onLongPress: PropTypes.Requireable<(...args: any[]) => any>; - /** The date to return from press callbacks */ - date: PropTypes.Requireable; - /** Disable all touch events for disabled days. Can be override with disableTouchEvent in markedDates*/ - disableAllTouchEventsForDisabledDays: PropTypes.Requireable; - }; - style: { - container: { - alignSelf: "stretch"; - alignItems: "center"; - }; - base: { - width: number; - height: number; - alignItems: "center"; - }; - text: { - marginTop: number; - fontSize: number; - fontFamily: string; - fontWeight: string; - color: string; - backgroundColor: string; - }; - alignedText: { - marginTop: number; - }; - selected: { - backgroundColor: string; - borderRadius: number; - }; - today: { - backgroundColor: string | undefined; - borderRadius: number; - }; - todayText: { - color: string; - }; - selectedText: { - color: string; - }; - disabledText: { - color: string; - }; - dot: { - width: number; - height: number; - marginTop: number; - borderRadius: number; - opacity: number; - }; /** Date marking style [simple/period/multi-dot/multi-period]. Default = 'simple' */ - visibleDot: { - opacity: number; - backgroundColor: string; - }; - selectedDot: { - backgroundColor: string; /** Theme object */ - }; - disabledDot: { - backgroundColor: string; - }; - todayDot: { - backgroundColor: string; - }; - }; - shouldComponentUpdate(nextProps: BasicDayProps): any; - onPress: () => void; - onLongPress: () => void; - get marking(): MarkingProps; - shouldDisableTouchEvent(): boolean; - isSelected(): boolean; - isDisabled(): boolean; - isToday(): boolean; - isMultiDot(): boolean; - isMultiPeriod(): boolean; - isCustom(): boolean; - getContainerStyle(): object[]; - getTextStyle(): object[]; - renderMarking(): JSX.Element; - renderText(): JSX.Element; - renderContent(): JSX.Element; - renderContainer(): JSX.Element; - renderPeriodsContainer(): JSX.Element; - render(): JSX.Element; -} diff --git a/src/calendar/day/basic/index.js b/src/calendar/day/basic/index.js deleted file mode 100644 index ce85bd97a8..0000000000 --- a/src/calendar/day/basic/index.js +++ /dev/null @@ -1,152 +0,0 @@ -import _ from 'lodash'; -import PropTypes from 'prop-types'; -import React, { Component, Fragment } from 'react'; -import { TouchableOpacity, Text, View } from 'react-native'; -// @ts-expect-error -import { shouldUpdate } from '../../../component-updater'; -import styleConstructor from './style'; -import Marking from '../marking'; -export default class BasicDay extends Component { - static displayName = 'IGNORE'; - static propTypes = { - state: PropTypes.oneOf(['selected', 'disabled', 'today', '']), - /** The marking object */ - marking: PropTypes.any, - /** Date marking style [simple/period/multi-dot/multi-period]. Default = 'simple' */ - markingType: PropTypes.oneOf(_.values(Marking.markingTypes)), - /** Theme object */ - theme: PropTypes.object, - /** onPress callback */ - onPress: PropTypes.func, - /** onLongPress callback */ - onLongPress: PropTypes.func, - /** The date to return from press callbacks */ - date: PropTypes.object, - /** Disable all touch events for disabled days. Can be override with disableTouchEvent in markedDates*/ - disableAllTouchEventsForDisabledDays: PropTypes.bool - }; - style = styleConstructor(this.props.theme); - shouldComponentUpdate(nextProps) { - return shouldUpdate(this.props, nextProps, [ - 'children', - 'state', - 'markingType', - 'marking', - 'onPress', - 'onLongPress', - 'date' - ]); - } - onPress = () => { - _.invoke(this.props, 'onPress', this.props.date); - }; - onLongPress = () => { - _.invoke(this.props, 'onLongPress', this.props.date); - }; - get marking() { - return this.props.marking || {}; - } - shouldDisableTouchEvent() { - const { disableAllTouchEventsForDisabledDays } = this.props; - const { disableTouchEvent } = this.marking; - let disableTouch = false; - if (typeof disableTouchEvent === 'boolean') { - disableTouch = disableTouchEvent; - } - else if (typeof disableAllTouchEventsForDisabledDays === 'boolean' && this.isDisabled()) { - disableTouch = disableAllTouchEventsForDisabledDays; - } - return disableTouch; - } - isSelected() { - return this.marking.selected || this.props.state === 'selected'; - } - isDisabled() { - return typeof this.marking.disabled !== 'undefined' ? this.marking.disabled : this.props.state === 'disabled'; - } - isToday() { - return this.props.state === 'today'; - } - isMultiDot() { - return this.props.markingType === Marking.markingTypes.MULTI_DOT; - } - isMultiPeriod() { - return this.props.markingType === Marking.markingTypes.MULTI_PERIOD; - } - isCustom() { - return this.props.markingType === Marking.markingTypes.CUSTOM; - } - getContainerStyle() { - const { customStyles, selectedColor } = this.marking; - const style = [this.style.base]; - if (this.isSelected()) { - style.push(this.style.selected); - if (selectedColor) { - style.push({ backgroundColor: selectedColor }); - } - } - else if (this.isToday()) { - style.push(this.style.today); - } - //Custom marking type - if (this.isCustom() && customStyles && customStyles.container) { - if (customStyles.container.borderRadius === undefined) { - customStyles.container.borderRadius = 16; - } - style.push(customStyles.container); - } - return style; - } - getTextStyle() { - const { customStyles, selectedTextColor } = this.marking; - const style = [this.style.text]; - if (this.isSelected()) { - style.push(this.style.selectedText); - if (selectedTextColor) { - style.push({ color: selectedTextColor }); - } - } - else if (this.isDisabled()) { - style.push(this.style.disabledText); - } - else if (this.isToday()) { - style.push(this.style.todayText); - } - //Custom marking type - if (this.isCustom() && customStyles && customStyles.text) { - style.push(customStyles.text); - } - return style; - } - renderMarking() { - const { theme, markingType } = this.props; - const { marked, dotColor, dots, periods } = this.marking; - return (); - } - renderText() { - return ( - {String(this.props.children)} - ); - } - renderContent() { - return ( - {this.renderText()} - {this.renderMarking()} - ); - } - renderContainer() { - const { activeOpacity } = this.marking; - return ( - {this.isMultiPeriod() ? this.renderText() : this.renderContent()} - ); - } - renderPeriodsContainer() { - return ( - {this.renderContainer()} - {this.renderMarking()} - ); - } - render() { - return this.isMultiPeriod() ? this.renderPeriodsContainer() : this.renderContainer(); - } -} diff --git a/src/calendar/day/basic/style.d.ts b/src/calendar/day/basic/style.d.ts deleted file mode 100644 index 8122f992b3..0000000000 --- a/src/calendar/day/basic/style.d.ts +++ /dev/null @@ -1,60 +0,0 @@ -import { Theme } from '../../../commons/types'; -export default function styleConstructor(theme?: Theme): { - container: { - alignSelf: "stretch"; - alignItems: "center"; - }; - base: { - width: number; - height: number; - alignItems: "center"; - }; - text: { - marginTop: number; - fontSize: number; - fontFamily: string; - fontWeight: string; - color: string; - backgroundColor: string; - }; - alignedText: { - marginTop: number; - }; - selected: { - backgroundColor: string; - borderRadius: number; - }; - today: { - backgroundColor: string | undefined; - borderRadius: number; - }; - todayText: { - color: string; - }; - selectedText: { - color: string; - }; - disabledText: { - color: string; - }; - dot: { - width: number; - height: number; - marginTop: number; - borderRadius: number; - opacity: number; - }; - visibleDot: { - opacity: number; - backgroundColor: string; - }; - selectedDot: { - backgroundColor: string; - }; - disabledDot: { - backgroundColor: string; - }; - todayDot: { - backgroundColor: string; - }; -}; diff --git a/src/calendar/day/basic/style.js b/src/calendar/day/basic/style.js deleted file mode 100644 index 087d8fa262..0000000000 --- a/src/calendar/day/basic/style.js +++ /dev/null @@ -1,67 +0,0 @@ -import { StyleSheet, Platform } from 'react-native'; -import * as defaultStyle from '../../../style'; -export default function styleConstructor(theme = {}) { - const appStyle = { ...defaultStyle, ...theme }; - return StyleSheet.create({ - container: { - alignSelf: 'stretch', - alignItems: 'center' - }, - base: { - width: 32, - height: 32, - alignItems: 'center' - }, - text: { - marginTop: Platform.OS === 'android' ? 4 : 6, - fontSize: appStyle.textDayFontSize, - fontFamily: appStyle.textDayFontFamily, - fontWeight: appStyle.textDayFontWeight, - color: appStyle.dayTextColor, - backgroundColor: 'rgba(255, 255, 255, 0)', - ...appStyle.textDayStyle - }, - alignedText: { - marginTop: Platform.OS === 'android' ? 4 : 6 - }, - selected: { - backgroundColor: appStyle.selectedDayBackgroundColor, - borderRadius: 16 - }, - today: { - backgroundColor: appStyle.todayBackgroundColor, - borderRadius: 16 - }, - todayText: { - color: appStyle.todayTextColor - }, - selectedText: { - color: appStyle.selectedDayTextColor - }, - disabledText: { - color: appStyle.textDisabledColor - }, - dot: { - width: 4, - height: 4, - marginTop: 1, - borderRadius: 2, - opacity: 0, - ...appStyle.dotStyle - }, - visibleDot: { - opacity: 1, - backgroundColor: appStyle.dotColor - }, - selectedDot: { - backgroundColor: appStyle.selectedDotColor - }, - disabledDot: { - backgroundColor: appStyle.disabledDotColor || appStyle.dotColor - }, - todayDot: { - backgroundColor: appStyle.todayDotColor || appStyle.dotColor - }, - ...(theme.stylesheet?.day?.basic || {}) - }); -} diff --git a/src/calendar/day/dot/index.d.ts b/src/calendar/day/dot/index.d.ts deleted file mode 100644 index 7572c0de13..0000000000 --- a/src/calendar/day/dot/index.d.ts +++ /dev/null @@ -1,23 +0,0 @@ -/// -import PropTypes from 'prop-types'; -import { Theme } from '../../../commons/types'; -export interface DotProps { - theme?: Theme; - color?: String; - marked?: Boolean; - selected?: Boolean; - disabled?: Boolean; - today?: Boolean; -} -declare const Dot: { - ({ theme, marked, disabled, color, today, selected }: DotProps): JSX.Element; - propTypes: { - theme: PropTypes.Requireable; - color: PropTypes.Requireable; - marked: PropTypes.Requireable; - selected: PropTypes.Requireable; - disabled: PropTypes.Requireable; - today: PropTypes.Requireable; - }; -}; -export default Dot; diff --git a/src/calendar/day/dot/index.js b/src/calendar/day/dot/index.js deleted file mode 100644 index 63e8dc0a67..0000000000 --- a/src/calendar/day/dot/index.js +++ /dev/null @@ -1,33 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { View } from 'react-native'; -import styleConstructor from './style'; -const Dot = ({ theme, marked, disabled, color, today, selected }) => { - const style = styleConstructor(theme); - const dotStyle = [style.dot]; - if (marked) { - dotStyle.push(style.visibleDot); - if (today) { - dotStyle.push(style.todayDot); - } - if (disabled) { - dotStyle.push(style.disabledDot); - } - if (selected) { - dotStyle.push(style.selectedDot); - } - if (color) { - dotStyle.push({ backgroundColor: color }); - } - } - return ; -}; -export default Dot; -Dot.propTypes = { - theme: PropTypes.object, - color: PropTypes.string, - marked: PropTypes.bool, - selected: PropTypes.bool, - disabled: PropTypes.bool, - today: PropTypes.bool -}; diff --git a/src/calendar/day/dot/style.d.ts b/src/calendar/day/dot/style.d.ts deleted file mode 100644 index 444c11ef99..0000000000 --- a/src/calendar/day/dot/style.d.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { Theme } from '../../../commons/types'; -export default function styleConstructor(theme?: Theme): { - dot: { - width: number; - height: number; - marginTop: number; - marginHorizontal: number; - borderRadius: number; - opacity: number; - }; - visibleDot: { - opacity: number; - backgroundColor: string; - }; - selectedDot: { - backgroundColor: string; - }; - disabledDot: { - backgroundColor: string; - }; - todayDot: { - backgroundColor: string; - }; -}; diff --git a/src/calendar/day/dot/style.js b/src/calendar/day/dot/style.js deleted file mode 100644 index 02f07fa3d3..0000000000 --- a/src/calendar/day/dot/style.js +++ /dev/null @@ -1,30 +0,0 @@ -import { StyleSheet } from 'react-native'; -import * as defaultStyle from '../../../style'; -export default function styleConstructor(theme = {}) { - const appStyle = { ...defaultStyle, ...theme }; - return StyleSheet.create({ - dot: { - width: 4, - height: 4, - marginTop: 1, - marginHorizontal: 1, - borderRadius: 2, - opacity: 0, - ...appStyle.dotStyle - }, - visibleDot: { - opacity: 1, - backgroundColor: appStyle.dotColor - }, - selectedDot: { - backgroundColor: appStyle.selectedDotColor - }, - disabledDot: { - backgroundColor: appStyle.disabledDotColor || appStyle.dotColor - }, - todayDot: { - backgroundColor: appStyle.todayDotColor || appStyle.dotColor - }, - ...(theme.stylesheet?.dot || {}) - }); -} diff --git a/src/calendar/day/index.d.ts b/src/calendar/day/index.d.ts deleted file mode 100644 index f95403c635..0000000000 --- a/src/calendar/day/index.d.ts +++ /dev/null @@ -1,31 +0,0 @@ -import PropTypes from 'prop-types'; -import { Component } from 'react'; -import { BasicDayProps } from './basic'; -import { MarkingProps } from './marking'; -export interface DayProps extends Omit { - /** The day to render */ - day?: Date; - /** Provide custom day rendering component */ - dayComponent?: any; -} -export default class Day extends Component { - static displayName: string; - static propTypes: { - /** The day to render */ - day: PropTypes.Requireable; - /** Provide custom day rendering component */ - dayComponent: PropTypes.Requireable; - theme: PropTypes.Requireable; - onLongPress: PropTypes.Requireable<(...args: any[]) => any>; - onPress: PropTypes.Requireable<(...args: any[]) => any>; - state: PropTypes.Requireable; - marking: PropTypes.Requireable; - markingType: PropTypes.Requireable; - disableAllTouchEventsForDisabledDays: PropTypes.Requireable; - }; - shouldComponentUpdate(nextProps: DayProps): any; - getMarkingLabel(marking: MarkingProps): string; - getAccessibilityLabel: (this: any, day: any, marking: any, isToday: any) => string; - getDayComponent(): any; - render(): JSX.Element; -} diff --git a/src/calendar/day/index.js b/src/calendar/day/index.js deleted file mode 100644 index 1b8f8ffabe..0000000000 --- a/src/calendar/day/index.js +++ /dev/null @@ -1,91 +0,0 @@ -import _ from 'lodash'; -import PropTypes from 'prop-types'; -import XDate from 'xdate'; -import memoize from 'memoize-one'; -import React, { Component } from 'react'; -// @ts-expect-error -import { shouldUpdate } from '../../component-updater'; -// @ts-expect-error -import dateutils from '../../dateutils'; -// @ts-expect-error -import { xdateToData } from '../../interface'; -// @ts-expect-error -import { SELECT_DATE_SLOT } from '../../testIDs'; -import BasicDay from './basic'; -import PeriodDay from './period'; -const basicDayPropsTypes = _.omit(BasicDay.propTypes, 'date'); -export default class Day extends Component { - static displayName = 'IGNORE'; - static propTypes = { - ...basicDayPropsTypes, - /** The day to render */ - day: PropTypes.object, - /** Provide custom day rendering component */ - dayComponent: PropTypes.any - }; - shouldComponentUpdate(nextProps) { - return shouldUpdate(this.props, nextProps, [ - 'day', - 'dayComponent', - 'state', - 'markingType', - 'marking', - 'onPress', - 'onLongPress' - ]); - } - getMarkingLabel(marking) { - let label = ''; - if (marking) { - if (marking.accessibilityLabel) { - return marking.accessibilityLabel; - } - if (marking.selected) { - label += 'selected '; - if (!marking.marked) { - label += 'You have no entries for this day '; - } - } - if (marking.marked) { - label += 'You have entries for this day '; - } - if (marking.startingDay) { - label += 'period start '; - } - if (marking.endingDay) { - label += 'period end '; - } - if (marking.disabled || marking.disableTouchEvent) { - label += 'disabled '; - } - } - return label; - } - getAccessibilityLabel = memoize((day, marking, isToday) => { - const today = _.get(XDate, 'locales[XDate.defaultLocale].today'); - const formatAccessibilityLabel = _.get(XDate, 'locales[XDate.defaultLocale].formatAccessibilityLabel'); - const markingLabel = this.getMarkingLabel(marking); - if (formatAccessibilityLabel) { - return `${isToday ? today : ''} ${day.toString(formatAccessibilityLabel)} ${markingLabel}`; - } - return `${isToday ? 'today' : ''} ${day.toString('dddd d MMMM yyyy')} ${markingLabel}`; - }); - getDayComponent() { - const { dayComponent, markingType } = this.props; - if (dayComponent) { - return dayComponent; - } - return markingType === 'period' ? PeriodDay : BasicDay; - } - render() { - const { day, marking } = this.props; - const date = xdateToData(day); - const isToday = dateutils.isToday(day); - const Component = this.getDayComponent(); - const dayProps = _.omit(this.props, 'day'); - const accessibilityLabel = this.getAccessibilityLabel(day, marking, isToday); - return ( - {date ? day?.getDate() : day} - ); - } -} diff --git a/src/calendar/day/marking/index.d.ts b/src/calendar/day/marking/index.d.ts deleted file mode 100644 index 53f97eb64e..0000000000 --- a/src/calendar/day/marking/index.d.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { Component } from 'react'; -import { ViewStyle, TextStyle } from 'react-native'; -import { DotProps } from '../dot'; -import { Theme } from '../../../commons/types'; -export declare enum MarkingTypes { - DOT = "dot", - MULTI_DOT = "multi-dot", - PERIOD = "period", - MULTI_PERIOD = "multi-period", - CUSTOM = "custom" -} -declare type CustomStyle = { - container?: ViewStyle; - text?: TextStyle; -}; -declare type DOT = { - key?: string; - color: string; - selectedDotColor?: string; -}; -declare type PERIOD = { - color: string; - startingDay?: boolean; - endingDay?: boolean; -}; -export interface MarkingProps extends DotProps { - type?: MarkingTypes; - theme?: Theme; - selected?: boolean; - marked?: boolean; - today?: boolean; - disabled?: boolean; - disableTouchEvent?: boolean; - activeOpacity?: number; - selectedColor?: string; - selectedTextColor?: string; - dotColor?: string; - dots?: DOT[]; - periods?: PERIOD[]; - startingDay?: boolean; - endingDay?: boolean; - accessibilityLabel?: string; - customStyles?: CustomStyle; -} -export default class Marking extends Component { - static displayName: string; - static markingTypes: typeof MarkingTypes; - style: any; - constructor(props: MarkingProps); - shouldComponentUpdate(nextProps: MarkingProps): any; - getItems(items?: DOT[] | PERIOD[]): JSX.Element[] | undefined; - renderMarkingByType(): JSX.Element; - renderMultiMarkings(containerStyle: Object, items?: DOT[] | PERIOD[]): JSX.Element; - renderPeriod(index: number, item: any): JSX.Element; - renderDot(index?: number, item?: any): JSX.Element; - render(): JSX.Element; -} -export {}; diff --git a/src/calendar/day/marking/index.js b/src/calendar/day/marking/index.js deleted file mode 100644 index 6c208e6fd0..0000000000 --- a/src/calendar/day/marking/index.js +++ /dev/null @@ -1,96 +0,0 @@ -import _ from 'lodash'; -import React, { Component } from 'react'; -import { View } from 'react-native'; -// @ts-expect-error -import { shouldUpdate, extractComponentProps } from '../../../component-updater'; -import styleConstructor from './style'; -import Dot from '../dot'; -export var MarkingTypes; -(function (MarkingTypes) { - MarkingTypes["DOT"] = "dot"; - MarkingTypes["MULTI_DOT"] = "multi-dot"; - MarkingTypes["PERIOD"] = "period"; - MarkingTypes["MULTI_PERIOD"] = "multi-period"; - MarkingTypes["CUSTOM"] = "custom"; -})(MarkingTypes || (MarkingTypes = {})); -export default class Marking extends Component { - static displayName = 'IGNORE'; - static markingTypes = MarkingTypes; - style; - constructor(props) { - super(props); - this.style = styleConstructor(props.theme); - } - shouldComponentUpdate(nextProps) { - return shouldUpdate(this.props, nextProps, [ - 'type', - 'selected', - 'marked', - 'today', - 'disabled', - 'disableTouchEvent', - 'activeOpacity', - 'selectedColor', - 'selectedTextColor', - 'dotColor', - 'dots', - 'periods' - ]); - } - getItems(items) { - const { type } = this.props; - if (items && Array.isArray(items) && items.length > 0) { - // Filter out items so that we process only those which have color property - const validItems = _.filter(items, function (o) { return !o.color; }); - return validItems.map((item, index) => { - return type === MarkingTypes.MULTI_DOT ? this.renderDot(index, item) : this.renderPeriod(index, item); - }); - } - } - renderMarkingByType() { - const { type, dots, periods } = this.props; - switch (type) { - case MarkingTypes.MULTI_DOT: - return this.renderMultiMarkings(this.style.dots, dots); - case MarkingTypes.MULTI_PERIOD: - return this.renderMultiMarkings(this.style.periods, periods); - default: - return this.renderDot(); - } - } - renderMultiMarkings(containerStyle, items) { - return {this.getItems(items)}; - } - renderPeriod(index, item) { - const { color, startingDay, endingDay } = item; - const style = [ - this.style.period, - { - backgroundColor: color - } - ]; - if (startingDay) { - style.push(this.style.startingDay); - } - if (endingDay) { - style.push(this.style.endingDay); - } - return ; - } - renderDot(index, item) { - const { selected, dotColor } = this.props; - const dotProps = extractComponentProps(Dot, this.props); - let key = index; - let color = dotColor; - if (item) { - if (item.key) { - key = item.key; - } - color = selected && item.selectedDotColor ? item.selectedDotColor : item.color; - } - return ; - } - render() { - return this.renderMarkingByType(); - } -} diff --git a/src/calendar/day/marking/style.d.ts b/src/calendar/day/marking/style.d.ts deleted file mode 100644 index 9feff3efda..0000000000 --- a/src/calendar/day/marking/style.d.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { Theme } from '../../../commons/types'; -export default function styleConstructor(theme?: Theme): { - dots: { - flexDirection: "row"; - }; - periods: { - alignSelf: "stretch"; - }; - period: { - height: number; - marginVertical: number; - backgroundColor: string | undefined; - }; - startingDay: { - borderTopLeftRadius: number; - borderBottomLeftRadius: number; - marginLeft: number; - }; - endingDay: { - borderTopRightRadius: number; - borderBottomRightRadius: number; - marginRight: number; - }; -}; diff --git a/src/calendar/day/marking/style.js b/src/calendar/day/marking/style.js deleted file mode 100644 index b1eff69e32..0000000000 --- a/src/calendar/day/marking/style.js +++ /dev/null @@ -1,29 +0,0 @@ -import { StyleSheet } from 'react-native'; -import * as defaultStyle from '../../style'; -export default function styleConstructor(theme = {}) { - const appStyle = { ...defaultStyle, ...theme }; - return StyleSheet.create({ - dots: { - flexDirection: 'row' - }, - periods: { - alignSelf: 'stretch' - }, - period: { - height: 4, - marginVertical: 1, - backgroundColor: appStyle.dotColor - }, - startingDay: { - borderTopLeftRadius: 2, - borderBottomLeftRadius: 2, - marginLeft: 4 - }, - endingDay: { - borderTopRightRadius: 2, - borderBottomRightRadius: 2, - marginRight: 4 - }, - ...(theme.stylesheet?.marking || {}) - }); -} diff --git a/src/calendar/day/period/index.d.ts b/src/calendar/day/period/index.d.ts deleted file mode 100644 index 1e7ddcca70..0000000000 --- a/src/calendar/day/period/index.d.ts +++ /dev/null @@ -1,35 +0,0 @@ -import PropTypes from 'prop-types'; -import { Component } from 'react'; -import { MarkingProps } from '../marking'; -import { Theme } from '../../../commons/types'; -interface PeriodDayProps { - state?: 'selected' | 'disabled' | 'today' | ''; - marking?: MarkingProps; - theme?: Theme; - onPress?: (date?: Date) => void; - onLongPress?: (date?: Date) => void; - date?: Date; - accessibilityLabel?: string; - testID?: string; -} -export default class PeriodDay extends Component { - static displayName: string; - static propTypes: { - state: PropTypes.Requireable; - marking: PropTypes.Requireable; - theme: PropTypes.Requireable; - onPress: PropTypes.Requireable<(...args: any[]) => any>; - onLongPress: PropTypes.Requireable<(...args: any[]) => any>; - date: PropTypes.Requireable; - }; - theme: Theme; - style: any; - markingStyle: any; - constructor(props: PeriodDayProps); - onPress: () => void; - onLongPress: () => void; - shouldComponentUpdate(nextProps: PeriodDayProps): any; - getDrawingStyle(marking?: any): any; - render(): JSX.Element; -} -export {}; diff --git a/src/calendar/day/period/index.js b/src/calendar/day/period/index.js deleted file mode 100644 index 71a11abe0b..0000000000 --- a/src/calendar/day/period/index.js +++ /dev/null @@ -1,192 +0,0 @@ -import _ from 'lodash'; -import PropTypes from 'prop-types'; -import React, { Component } from 'react'; -import { TouchableWithoutFeedback, Text, View } from 'react-native'; -// @ts-expect-error -import { shouldUpdate } from '../../../component-updater'; -import * as defaultStyle from '../../../style'; -import styleConstructor from './style'; -import Dot from '../dot'; -export default class PeriodDay extends Component { - static displayName = 'IGNORE'; - static propTypes = { - state: PropTypes.oneOf(['selected', 'disabled', 'today', '']), - marking: PropTypes.any, - theme: PropTypes.object, - onPress: PropTypes.func, - onLongPress: PropTypes.func, - date: PropTypes.object - }; - theme; - style; - markingStyle; - constructor(props) { - super(props); - this.theme = { ...defaultStyle, ...(props.theme || {}) }; - this.style = styleConstructor(props.theme); - this.markingStyle = this.getDrawingStyle(props.marking); - } - onPress = () => { - this.props.onPress?.(this.props.date); - }; - onLongPress = () => { - this.props.onLongPress?.(this.props.date); - }; - shouldComponentUpdate(nextProps) { - const newMarkingStyle = this.getDrawingStyle(nextProps.marking); - if (!_.isEqual(this.markingStyle, newMarkingStyle)) { - this.markingStyle = newMarkingStyle; - return true; - } - return shouldUpdate(this.props, nextProps, ['children', 'state', 'marking', 'onPress', 'onLongPress', 'date']); - } - // TODO: refactor to use MarkingProps as the type - getDrawingStyle(marking) { - const defaultStyle = { textStyle: { color: undefined }, containerStyle: {} }; - if (!marking) { - return defaultStyle; - } - if (marking.disabled) { - defaultStyle.textStyle.color = this.style.disabledText.color; - } - else if (marking.selected) { - defaultStyle.textStyle.color = this.style.selectedText.color; - } - const resultStyle = [marking].reduce((prev, next) => { - // if (next.quickAction) { //??? - // if (next.first || next.last) { - // prev.containerStyle = this.style.firstQuickAction; - // prev.textStyle = this.style.firstQuickActionText; - // if (next.endSelected && next.first && !next.last) { - // prev.rightFillerStyle = '#c1e4fe'; - // } else if (next.endSelected && next.last && !next.first) { - // prev.leftFillerStyle = '#c1e4fe'; - // } - // } else if (!next.endSelected) { - // prev.containerStyle = this.style.quickAction; - // prev.textStyle = this.style.quickActionText; - // } else if (next.endSelected) { - // prev.leftFillerStyle = '#c1e4fe'; - // prev.rightFillerStyle = '#c1e4fe'; - // } - // return prev; - // } - // if (next.status === 'NotAvailable') { //??? - // prev.textStyle = this.style.naText; - // } - const color = next.color; - if (next.startingDay) { - prev.startingDay = { color }; - } - if (next.endingDay) { - prev.endingDay = { color }; - } - if (!next.startingDay && !next.endingDay) { - prev.day = { color }; - } - if (next.textColor) { - prev.textStyle.color = next.textColor; - } - if (marking.customTextStyle) { - defaultStyle.textStyle = marking.customTextStyle; - } - if (marking.customContainerStyle) { - defaultStyle.containerStyle = marking.customContainerStyle; - } - return prev; - }, defaultStyle); - return resultStyle; - } - render() { - const { state, marking } = this.props; - const containerStyle = [this.style.base]; - const textStyle = [this.style.text]; - let leftFillerStyle = { backgroundColor: undefined }; - let rightFillerStyle = { backgroundColor: undefined }; - let fillerStyle = {}; - let fillers; - // TODO: refactor - move all styling logic out of render() - if (state === 'disabled') { - textStyle.push(this.style.disabledText); - } - else if (state === 'today') { - containerStyle.push(this.style.today); - textStyle.push(this.style.todayText); - } - if (marking) { - containerStyle.push({ - borderRadius: 17, - overflow: 'hidden' - }); - const flags = this.markingStyle; - if (flags.textStyle) { - textStyle.push(flags.textStyle); - } - if (flags.containerStyle) { - containerStyle.push(flags.containerStyle); - } - if (flags.leftFillerStyle) { - leftFillerStyle.backgroundColor = flags.leftFillerStyle; - } - if (flags.rightFillerStyle) { - rightFillerStyle.backgroundColor = flags.rightFillerStyle; - } - if (flags.startingDay && !flags.endingDay) { - leftFillerStyle = { - backgroundColor: this.theme.calendarBackground - }; - rightFillerStyle = { - backgroundColor: flags.startingDay.color - }; - containerStyle.push({ - backgroundColor: flags.startingDay.color - }); - } - else if (flags.endingDay && !flags.startingDay) { - rightFillerStyle = { - backgroundColor: this.theme.calendarBackground - }; - leftFillerStyle = { - backgroundColor: flags.endingDay.color - }; - containerStyle.push({ - backgroundColor: flags.endingDay.color - }); - } - else if (flags.day) { - leftFillerStyle = { backgroundColor: flags.day.color }; - rightFillerStyle = { backgroundColor: flags.day.color }; - fillerStyle = { backgroundColor: flags.day.color }; - } - else if (flags.endingDay && flags.startingDay) { - rightFillerStyle = { - backgroundColor: this.theme.calendarBackground - }; - leftFillerStyle = { - backgroundColor: this.theme.calendarBackground - }; - containerStyle.push({ - backgroundColor: flags.endingDay.color - }); - } - // TODO: refactor - move all fillers logic out of render() - fillers = ( - - - ); - } - const { theme, accessibilityLabel, testID } = this.props; - // TODO: refactor - allow feedback for unmarked days - return ( - - {fillers} - - - {String(this.props.children)} - - - - - ); - } -} diff --git a/src/calendar/day/period/style.d.ts b/src/calendar/day/period/style.d.ts deleted file mode 100644 index 64b9862e4e..0000000000 --- a/src/calendar/day/period/style.d.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { Theme } from '../../../commons/types'; -export default function styleConstructor(theme?: Theme): { - wrapper: { - alignItems: "center"; - alignSelf: "stretch"; - marginLeft: number; - }; - base: { - width: number; - height: number; - alignItems: "center"; - }; - fillers: { - position: "absolute"; - height: number; - flexDirection: "row"; - left: number; - right: number; - }; - leftFiller: { - height: number; - flex: number; - }; - rightFiller: { - height: number; - flex: number; - }; - text: { - marginTop: number; - fontSize: number; - fontFamily: string; - fontWeight: string; - color: string; - backgroundColor: string; - }; - today: { - backgroundColor: string | undefined; - }; - todayText: { - fontWeight: "500"; - color: string; - }; - selectedText: { - color: string; - }; - disabledText: { - color: string; - }; -}; diff --git a/src/calendar/day/period/style.js b/src/calendar/day/period/style.js deleted file mode 100644 index 0a6e7a272d..0000000000 --- a/src/calendar/day/period/style.js +++ /dev/null @@ -1,73 +0,0 @@ -import { StyleSheet } from 'react-native'; -import * as defaultStyle from '../../../style'; -const FILLER_HEIGHT = 34; -export default function styleConstructor(theme = {}) { - const appStyle = { ...defaultStyle, ...theme }; - return StyleSheet.create({ - wrapper: { - alignItems: 'center', - alignSelf: 'stretch', - marginLeft: -1 - }, - base: { - width: 38, - height: FILLER_HEIGHT, - alignItems: 'center' - }, - fillers: { - position: 'absolute', - height: FILLER_HEIGHT, - flexDirection: 'row', - left: 0, - right: 0 - }, - leftFiller: { - height: FILLER_HEIGHT, - flex: 1 - }, - rightFiller: { - height: FILLER_HEIGHT, - flex: 1 - }, - text: { - marginTop: 7, - fontSize: appStyle.textDayFontSize, - fontFamily: appStyle.textDayFontFamily, - fontWeight: appStyle.textDayFontWeight, - color: appStyle.dayTextColor, - backgroundColor: 'rgba(255, 255, 255, 0)' - }, - today: { - backgroundColor: appStyle.todayBackgroundColor - }, - todayText: { - fontWeight: '500', - color: theme.todayTextColor || appStyle.dayTextColor - }, - selectedText: { - color: appStyle.selectedDayTextColor - }, - disabledText: { - color: appStyle.textDisabledColor - }, - // quickAction: { - // backgroundColor: 'white', - // borderWidth: 1, - // borderColor: '#c1e4fe' - // }, - // quickActionText: { - // marginTop: 6, - // color: appStyle.textColor - // }, - // firstQuickAction: { - // backgroundColor: appStyle.textLinkColor - // }, - // firstQuickActionText: { - // color: 'white' - // }, - // naText: { - // color: '#b6c1cd' - // }, - ...(theme.stylesheet?.day?.period || {}) - }); -} diff --git a/src/calendar/header/index.d.ts b/src/calendar/header/index.d.ts deleted file mode 100644 index d1704f1086..0000000000 --- a/src/calendar/header/index.d.ts +++ /dev/null @@ -1,92 +0,0 @@ -import PropTypes from 'prop-types'; -import XDate from 'xdate'; -import React, { Component, ReactNode } from 'react'; -import { ViewStyle, AccessibilityActionEvent } from 'react-native'; -import { Theme } from '../../commons/types'; -declare type Direction = 'left' | 'right'; -export interface CalendarHeaderProps { - theme?: Theme; - firstDay?: number; - displayLoadingIndicator?: boolean; - showWeekNumbers?: boolean; - month?: XDate; - addMonth?: (num: number) => void; - /** Month format in the title. Formatting values: http://arshaw.com/xdate/#Formatting */ - monthFormat?: string; - /** Hide day names */ - hideDayNames?: boolean; - /** Hide month navigation arrows */ - hideArrows?: boolean; - /** Replace default arrows with custom ones (direction can be 'left' or 'right') */ - renderArrow?: (direction: Direction) => ReactNode; - /** Handler which gets executed when press arrow icon left. It receive a callback can go back month */ - onPressArrowLeft?: (method: () => void, month?: XDate) => void; - /** Handler which gets executed when press arrow icon right. It receive a callback can go next month */ - onPressArrowRight?: (method: () => void, month?: XDate) => void; - /** Disable left arrow */ - disableArrowLeft?: boolean; - /** Disable right arrow */ - disableArrowRight?: boolean; - /** Apply custom disable color to selected day indexes */ - disabledDaysIndexes?: number[]; - /** Replace default month and year title with custom one. the function receive a date as parameter */ - renderHeader?: (date?: XDate) => ReactNode; - /** Provide aria-level for calendar heading for proper accessibility when used with web (react-native-web) */ - webAriaLevel?: number; - testID?: string; - style?: ViewStyle; - accessibilityElementsHidden?: boolean; - importantForAccessibility?: 'auto' | 'yes' | 'no' | 'no-hide-descendants'; -} -declare class CalendarHeader extends Component { - static displayName: string; - static propTypes: { - theme: PropTypes.Requireable; - firstDay: PropTypes.Requireable; - displayLoadingIndicator: PropTypes.Requireable; - showWeekNumbers: PropTypes.Requireable; - month: PropTypes.Requireable; - addMonth: PropTypes.Requireable<(...args: any[]) => any>; - /** Month format in the title. Formatting values: http://arshaw.com/xdate/#Formatting */ - monthFormat: PropTypes.Requireable; - /** Hide day names. Default = false */ - hideDayNames: PropTypes.Requireable; - /** Hide month navigation arrows. Default = false */ - hideArrows: PropTypes.Requireable; - /** Replace default arrows with custom ones (direction can be 'left' or 'right') */ - renderArrow: PropTypes.Requireable<(...args: any[]) => any>; - /** Handler which gets executed when press arrow icon left. It receive a callback can go back month */ - onPressArrowLeft: PropTypes.Requireable<(...args: any[]) => any>; - /** Handler which gets executed when press arrow icon right. It receive a callback can go next month */ - onPressArrowRight: PropTypes.Requireable<(...args: any[]) => any>; - /** Disable left arrow. Default = false */ - disableArrowLeft: PropTypes.Requireable; - /** Disable right arrow. Default = false */ - disableArrowRight: PropTypes.Requireable; - /** Apply custom disable color to selected day indexes */ - disabledDaysIndexes: PropTypes.Requireable<(number | null | undefined)[]>; - /** Replace default month and year title with custom one. the function receive a date as parameter. */ - renderHeader: PropTypes.Requireable; - /** Provide aria-level for calendar heading for proper accessibility when used with web (react-native-web) */ - webAriaLevel: PropTypes.Requireable; - }; - static defaultProps: { - monthFormat: string; - webAriaLevel: number; - }; - style: any; - constructor(props: CalendarHeaderProps); - shouldComponentUpdate(nextProps: CalendarHeaderProps): any; - addMonth: () => void; - subtractMonth: () => void; - onPressLeft: () => void; - onPressRight: () => void; - renderWeekDays: (this: any, weekDaysNames: any) => any; - renderHeader: () => React.ReactNode; - renderArrow(direction: Direction): JSX.Element; - renderIndicator(): JSX.Element | undefined; - renderDayNames(): JSX.Element | undefined; - render(): JSX.Element; - onAccessibilityAction: (event: AccessibilityActionEvent) => void; -} -export default CalendarHeader; diff --git a/src/calendar/header/index.js b/src/calendar/header/index.js deleted file mode 100644 index ef15e17957..0000000000 --- a/src/calendar/header/index.js +++ /dev/null @@ -1,184 +0,0 @@ -import _ from 'lodash'; -import PropTypes from 'prop-types'; -import memoize from 'memoize-one'; -import XDate from 'xdate'; -import React, { Component, Fragment } from 'react'; -import { ActivityIndicator, Platform, View, Text, TouchableOpacity, Image } from 'react-native'; -// @ts-expect-error -import { shouldUpdate } from '../../component-updater'; -// @ts-expect-error -import { weekDayNames } from '../../dateutils'; -import { CHANGE_MONTH_LEFT_ARROW, CHANGE_MONTH_RIGHT_ARROW, HEADER_DAY_NAMES, HEADER_LOADING_INDICATOR, HEADER_MONTH_NAME -// @ts-expect-error - } from '../../testIDs'; -import styleConstructor from './style'; -class CalendarHeader extends Component { - static displayName = 'IGNORE'; - static propTypes = { - theme: PropTypes.object, - firstDay: PropTypes.number, - displayLoadingIndicator: PropTypes.bool, - showWeekNumbers: PropTypes.bool, - month: PropTypes.instanceOf(XDate), - addMonth: PropTypes.func, - /** Month format in the title. Formatting values: http://arshaw.com/xdate/#Formatting */ - monthFormat: PropTypes.string, - /** Hide day names. Default = false */ - hideDayNames: PropTypes.bool, - /** Hide month navigation arrows. Default = false */ - hideArrows: PropTypes.bool, - /** Replace default arrows with custom ones (direction can be 'left' or 'right') */ - renderArrow: PropTypes.func, - /** Handler which gets executed when press arrow icon left. It receive a callback can go back month */ - onPressArrowLeft: PropTypes.func, - /** Handler which gets executed when press arrow icon right. It receive a callback can go next month */ - onPressArrowRight: PropTypes.func, - /** Disable left arrow. Default = false */ - disableArrowLeft: PropTypes.bool, - /** Disable right arrow. Default = false */ - disableArrowRight: PropTypes.bool, - /** Apply custom disable color to selected day indexes */ - disabledDaysIndexes: PropTypes.arrayOf(PropTypes.number), - /** Replace default month and year title with custom one. the function receive a date as parameter. */ - renderHeader: PropTypes.any, - /** Provide aria-level for calendar heading for proper accessibility when used with web (react-native-web) */ - webAriaLevel: PropTypes.number - }; - static defaultProps = { - monthFormat: 'MMMM yyyy', - webAriaLevel: 1 - }; - style; - constructor(props) { - super(props); - this.style = styleConstructor(props.theme); - } - shouldComponentUpdate(nextProps) { - if (nextProps.month?.toString('yyyy MM') !== this.props.month?.toString('yyyy MM')) { - return true; - } - return shouldUpdate(this.props, nextProps, [ - 'displayLoadingIndicator', - 'hideDayNames', - 'firstDay', - 'showWeekNumbers', - 'monthFormat', - 'renderArrow', - 'disableArrowLeft', - 'disableArrowRight' - ]); - } - addMonth = () => { - const { addMonth } = this.props; - addMonth?.(1); - }; - subtractMonth = () => { - const { addMonth } = this.props; - addMonth?.(-1); - }; - onPressLeft = () => { - const { onPressArrowLeft, month } = this.props; - if (typeof onPressArrowLeft === 'function') { - return onPressArrowLeft(this.subtractMonth, month); - } - return this.subtractMonth(); - }; - onPressRight = () => { - const { onPressArrowRight, month } = this.props; - if (typeof onPressArrowRight === 'function') { - return onPressArrowRight(this.addMonth, month); - } - return this.addMonth(); - }; - renderWeekDays = memoize(weekDaysNames => { - const { disabledDaysIndexes } = this.props; - return weekDaysNames.map((day, idx) => { - const dayStyle = [this.style.dayHeader]; - if (_.includes(disabledDaysIndexes, idx)) { - dayStyle.push(this.style.disabledDayHeader); - } - if (this.style[`dayTextAtIndex${idx}`]) { - dayStyle.push(this.style[`dayTextAtIndex${idx}`]); - } - return ( - {day} - ); - }); - }); - renderHeader = () => { - const { renderHeader, month, monthFormat, testID, webAriaLevel } = this.props; - const webProps = Platform.OS === 'web' ? { 'aria-level': webAriaLevel } : {}; - if (renderHeader) { - return renderHeader(month); - } - return ( - - {month?.toString(monthFormat)} - - ); - }; - renderArrow(direction) { - const { hideArrows, disableArrowLeft, disableArrowRight, renderArrow, testID } = this.props; - if (hideArrows) { - return ; - } - const isLeft = direction === 'left'; - const id = isLeft ? CHANGE_MONTH_LEFT_ARROW : CHANGE_MONTH_RIGHT_ARROW; - const testId = testID ? `${id}-${testID}` : id; - const onPress = isLeft ? this.onPressLeft : this.onPressRight; - const imageSource = isLeft ? require('../img/previous.png') : require('../img/next.png'); - const renderArrowDirection = isLeft ? 'left' : 'right'; - const shouldDisable = isLeft ? disableArrowLeft : disableArrowRight; - return ( - {renderArrow ? (renderArrow(renderArrowDirection)) : ()} - ); - } - renderIndicator() { - const { displayLoadingIndicator, theme, testID } = this.props; - if (displayLoadingIndicator) { - return (); - } - } - renderDayNames() { - const { firstDay, hideDayNames, showWeekNumbers, testID } = this.props; - const weekDaysNames = weekDayNames(firstDay); - if (!hideDayNames) { - return ( - {showWeekNumbers && } - {this.renderWeekDays(weekDaysNames)} - ); - } - } - render() { - const { style, testID } = this.props; - return ( - - {this.renderArrow('left')} - - {this.renderHeader()} - {this.renderIndicator()} - - {this.renderArrow('right')} - - {this.renderDayNames()} - ); - } - onAccessibilityAction = (event) => { - switch (event.nativeEvent.actionName) { - case 'decrement': - this.onPressLeft(); - break; - case 'increment': - this.onPressRight(); - break; - default: - break; - } - }; -} -export default CalendarHeader; diff --git a/src/calendar/header/style.d.ts b/src/calendar/header/style.d.ts deleted file mode 100644 index 38cb95c3c8..0000000000 --- a/src/calendar/header/style.d.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { Theme } from '../../commons/types'; -export default function (theme?: Theme): { - header: { - flexDirection: "row"; - justifyContent: "space-between"; - paddingLeft: number; - paddingRight: number; - marginTop: number; - alignItems: "center"; - }; - headerContainer: { - flexDirection: "row"; - }; - monthText: { - fontSize: number; - fontFamily: string; - fontWeight: string; - color: string; - margin: number; - }; - arrow: { - padding: number; - }; - arrowImage: { - width?: number | undefined; - height?: number | undefined; - tintColor: string; - }; - disabledArrowImage: { - tintColor: string; - }; - week: { - marginTop: number; - flexDirection: "row"; - justifyContent: "space-around"; - }; - dayHeader: { - marginTop: number; - marginBottom: number; - width: number; - textAlign: "center"; - fontSize: number; - fontFamily: string; - fontWeight: string | undefined; - color: string; - }; - disabledDayHeader: { - color: string; - }; -}; diff --git a/src/calendar/header/style.js b/src/calendar/header/style.js deleted file mode 100644 index df61cb2611..0000000000 --- a/src/calendar/header/style.js +++ /dev/null @@ -1,60 +0,0 @@ -import { StyleSheet, Platform } from 'react-native'; -import * as defaultStyle from '../../style'; -export default function (theme = {}) { - const appStyle = { ...defaultStyle, ...theme }; - return StyleSheet.create({ - header: { - flexDirection: 'row', - justifyContent: 'space-between', - paddingLeft: 10, - paddingRight: 10, - marginTop: 6, - alignItems: 'center' - }, - headerContainer: { - flexDirection: 'row' - }, - monthText: { - fontSize: appStyle.textMonthFontSize, - fontFamily: appStyle.textMonthFontFamily, - fontWeight: appStyle.textMonthFontWeight, - color: appStyle.monthTextColor, - margin: 10 - }, - arrow: { - padding: 10, - ...appStyle.arrowStyle - }, - arrowImage: { - tintColor: appStyle.arrowColor, - ...Platform.select({ - web: { - width: appStyle.arrowWidth, - height: appStyle.arrowHeight - } - }) - }, - disabledArrowImage: { - tintColor: appStyle.disabledArrowColor - }, - week: { - marginTop: 7, - flexDirection: 'row', - justifyContent: 'space-around' - }, - dayHeader: { - marginTop: 2, - marginBottom: 7, - width: 32, - textAlign: 'center', - fontSize: appStyle.textDayHeaderFontSize, - fontFamily: appStyle.textDayHeaderFontFamily, - fontWeight: appStyle.textDayHeaderFontWeight, - color: appStyle.textSectionTitleColor - }, - disabledDayHeader: { - color: appStyle.textSectionTitleDisabledColor - }, - ...(theme.stylesheet?.calendar?.header || {}) - }); -} diff --git a/src/calendar/index.d.ts b/src/calendar/index.d.ts deleted file mode 100644 index a5daaa9ef4..0000000000 --- a/src/calendar/index.d.ts +++ /dev/null @@ -1,175 +0,0 @@ -import PropTypes from 'prop-types'; -import XDate from 'xdate'; -import { Component, RefObject } from 'react'; -import { ViewStyle } from 'react-native'; -import CalendarHeader, { CalendarHeaderProps } from './header'; -import { DayProps } from './day/index'; -import { MarkingProps } from './day/marking'; -import { Theme } from '../commons/types'; -declare type MarkedDatesType = { - [key: string]: MarkingProps; -}; -export interface CalendarProps extends CalendarHeaderProps, DayProps { - /** Specify theme properties to override specific styles for calendar parts */ - theme?: Theme; - /** Specify style for calendar container element */ - style?: ViewStyle; - /** Initially visible month */ - current?: XDate; - /** Minimum date that can be selected, dates before minDate will be grayed out */ - minDate?: Date; - /** Maximum date that can be selected, dates after maxDate will be grayed out */ - maxDate?: Date; - /** If firstDay=1 week starts from Monday. Note that dayNames and dayNamesShort should still start from Sunday */ - firstDay?: number; - /** Collection of dates that have to be marked */ - markedDates?: MarkedDatesType; - /** Display loading indicator */ - displayLoadingIndicator?: boolean; - /** Show week numbers */ - showWeekNumbers?: boolean; - /** Do not show days of other months in month page */ - hideExtraDays?: boolean; - /** Always show six weeks on each month (only when hideExtraDays = false) */ - showSixWeeks?: boolean; - /** Handler which gets executed on day press */ - onDayPress?: (date: Date) => any; - /** Handler which gets executed on day long press */ - onDayLongPress?: (date: Date) => any; - /** Handler which gets executed when month changes in calendar */ - onMonthChange?: () => void; - /** Handler which gets executed when visible month changes in calendar */ - onVisibleMonthsChange?: () => void; - /** Disables changing month when click on days of other months (when hideExtraDays is false) */ - disableMonthChange?: boolean; - /** Enable the option to swipe between months */ - enableSwipeMonths?: boolean; - /** Disable days by default */ - disabledByDefault?: boolean; - /** Style passed to the header */ - headerStyle?: ViewStyle; - /** Allow rendering of a totally custom header */ - customHeader?: any; -} -interface CalendarState { - currentMonth: any; -} -/** - * @description: Calendar component - * @example: https://github.com/wix/react-native-calendars/blob/master/example/src/screens/calendars.js - * @gif: https://github.com/wix/react-native-calendars/blob/master/demo/calendar.gif - */ -declare class Calendar extends Component { - static displayName: string; - static propTypes: { - /** Specify theme properties to override specific styles for calendar parts. Default = {} */ - theme: PropTypes.Requireable; - /** Specify style for calendar container element. Default = {} */ - style: PropTypes.Requireable; - /** Initially visible month. Default = Date() */ - current: PropTypes.Requireable; - /** Minimum date that can be selected, dates before minDate will be grayed out. Default = undefined */ - minDate: PropTypes.Requireable; - /** Maximum date that can be selected, dates after maxDate will be grayed out. Default = undefined */ - maxDate: PropTypes.Requireable; - /** If firstDay=1 week starts from Monday. Note that dayNames and dayNamesShort should still start from Sunday. */ - firstDay: PropTypes.Requireable; - /** Collection of dates that have to be marked. Default = {} */ - markedDates: PropTypes.Requireable; - /** Display loading indicator. Default = false */ - displayLoadingIndicator: PropTypes.Requireable; - /** Show week numbers. Default = false */ - showWeekNumbers: PropTypes.Requireable; - /** Do not show days of other months in month page. Default = false */ - hideExtraDays: PropTypes.Requireable; - /** Always show six weeks on each month (only when hideExtraDays = false). Default = false */ - showSixWeeks: PropTypes.Requireable; - /** Handler which gets executed on day press. Default = undefined */ - onDayPress: PropTypes.Requireable<(...args: any[]) => any>; - /** Handler which gets executed on day long press. Default = undefined */ - onDayLongPress: PropTypes.Requireable<(...args: any[]) => any>; - /** Handler which gets executed when month changes in calendar. Default = undefined */ - onMonthChange: PropTypes.Requireable<(...args: any[]) => any>; - /** Handler which gets executed when visible month changes in calendar. Default = undefined */ - onVisibleMonthsChange: PropTypes.Requireable<(...args: any[]) => any>; - /** Disables changing month when click on days of other months (when hideExtraDays is false). Default = false */ - disableMonthChange: PropTypes.Requireable; - /** Enable the option to swipe between months. Default: false */ - enableSwipeMonths: PropTypes.Requireable; - /** Disable days by default. Default = false */ - disabledByDefault: PropTypes.Requireable; - /** Style passed to the header */ - headerStyle: PropTypes.Requireable; - /** Allow rendering of a totally custom header */ - customHeader: PropTypes.Requireable; - day: PropTypes.Requireable; - dayComponent: PropTypes.Requireable; - onLongPress: PropTypes.Requireable<(...args: any[]) => any>; - onPress: PropTypes.Requireable<(...args: any[]) => any>; - state: PropTypes.Requireable; - marking: PropTypes.Requireable; - markingType: PropTypes.Requireable; - disableAllTouchEventsForDisabledDays: PropTypes.Requireable; - month: PropTypes.Requireable; - addMonth: PropTypes.Requireable<(...args: any[]) => any>; - monthFormat: PropTypes.Requireable; - hideDayNames: PropTypes.Requireable; - hideArrows: PropTypes.Requireable; - renderArrow: PropTypes.Requireable<(...args: any[]) => any>; - onPressArrowLeft: PropTypes.Requireable<(...args: any[]) => any>; - onPressArrowRight: PropTypes.Requireable<(...args: any[]) => any>; - disableArrowLeft: PropTypes.Requireable; - disableArrowRight: PropTypes.Requireable; - disabledDaysIndexes: PropTypes.Requireable<(number | null | undefined)[]>; - renderHeader: PropTypes.Requireable; - webAriaLevel: PropTypes.Requireable; - }; - static defaultProps: { - enableSwipeMonths: boolean; - }; - state: { - currentMonth: any; - }; - style: { - container: { - paddingLeft: number; - paddingRight: number; - backgroundColor: string; - }; - dayContainer: { - flex: number; - alignItems: "center"; - }; - emptyDayContainer: { - flex: number; - }; - monthView: { - backgroundColor: string; - }; - week: { - marginTop: number; - marginBottom: number; - flexDirection: "row"; - justifyContent: "space-around"; - }; - }; - header: RefObject; - addMonth: (count: number) => void; - updateMonth: (day: any, doNotTriggerListeners?: boolean) => void; - handleDayInteraction(date: Date, interaction?: (date: Date) => any): void; - pressDay: (date: Date) => void; - longPressDay: (date: Date) => void; - swipeProps: { - onSwipe: (direction: string) => void; - }; - onSwipe: (gestureName: string) => void; - onSwipeLeft: () => void; - onSwipeRight: () => void; - renderWeekNumber: (this: any, weekNumber: any) => JSX.Element; - renderDay(day: Date, id: number): JSX.Element; - renderWeek(days: any, id: number): JSX.Element; - renderMonth(): JSX.Element; - renderHeader(): JSX.Element; - render(): JSX.Element; -} -export default Calendar; diff --git a/src/calendar/index.js b/src/calendar/index.js deleted file mode 100644 index 7cdb3eba51..0000000000 --- a/src/calendar/index.js +++ /dev/null @@ -1,211 +0,0 @@ -import _ from 'lodash'; -import PropTypes from 'prop-types'; -import XDate from 'xdate'; -import memoize from 'memoize-one'; -import React, { Component } from 'react'; -import { View } from 'react-native'; -// @ts-expect-error -import GestureRecognizer, { swipeDirections } from 'react-native-swipe-gestures'; -// @ts-expect-error -import dateutils from '../dateutils'; -// @ts-expect-error -import { xdateToData, parseDate, toMarkingFormat } from '../interface'; -// @ts-expect-error -import { getState } from '../day-state-manager'; -// import shouldComponentUpdate from './updater'; -// @ts-expect-error -import { extractComponentProps } from '../component-updater'; -// @ts-expect-error -import { WEEK_NUMBER } from '../testIDs'; -import styleConstructor from './style'; -import CalendarHeader from './header'; -import Day from './day/index'; -import BasicDay from './day/basic'; -/** - * @description: Calendar component - * @example: https://github.com/wix/react-native-calendars/blob/master/example/src/screens/calendars.js - * @gif: https://github.com/wix/react-native-calendars/blob/master/demo/calendar.gif - */ -class Calendar extends Component { - static displayName = 'Calendar'; - static propTypes = { - ...CalendarHeader.propTypes, - ...Day.propTypes, - /** Specify theme properties to override specific styles for calendar parts. Default = {} */ - theme: PropTypes.object, - /** Specify style for calendar container element. Default = {} */ - style: PropTypes.oneOfType([PropTypes.object, PropTypes.array, PropTypes.number]), - /** Initially visible month. Default = Date() */ - current: PropTypes.any, - /** Minimum date that can be selected, dates before minDate will be grayed out. Default = undefined */ - minDate: PropTypes.any, - /** Maximum date that can be selected, dates after maxDate will be grayed out. Default = undefined */ - maxDate: PropTypes.any, - /** If firstDay=1 week starts from Monday. Note that dayNames and dayNamesShort should still start from Sunday. */ - firstDay: PropTypes.number, - /** Collection of dates that have to be marked. Default = {} */ - markedDates: PropTypes.object, - /** Display loading indicator. Default = false */ - displayLoadingIndicator: PropTypes.bool, - /** Show week numbers. Default = false */ - showWeekNumbers: PropTypes.bool, - /** Do not show days of other months in month page. Default = false */ - hideExtraDays: PropTypes.bool, - /** Always show six weeks on each month (only when hideExtraDays = false). Default = false */ - showSixWeeks: PropTypes.bool, - /** Handler which gets executed on day press. Default = undefined */ - onDayPress: PropTypes.func, - /** Handler which gets executed on day long press. Default = undefined */ - onDayLongPress: PropTypes.func, - /** Handler which gets executed when month changes in calendar. Default = undefined */ - onMonthChange: PropTypes.func, - /** Handler which gets executed when visible month changes in calendar. Default = undefined */ - onVisibleMonthsChange: PropTypes.func, - /** Disables changing month when click on days of other months (when hideExtraDays is false). Default = false */ - disableMonthChange: PropTypes.bool, - /** Enable the option to swipe between months. Default: false */ - enableSwipeMonths: PropTypes.bool, - /** Disable days by default. Default = false */ - disabledByDefault: PropTypes.bool, - /** Style passed to the header */ - headerStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.number, PropTypes.array]), - /** Allow rendering of a totally custom header */ - customHeader: PropTypes.any - }; - static defaultProps = { - enableSwipeMonths: false - }; - state = { - currentMonth: this.props.current ? parseDate(this.props.current) : new XDate() - }; - style = styleConstructor(this.props.theme); - header = React.createRef(); - addMonth = (count) => { - this.updateMonth(this.state.currentMonth.clone().addMonths(count, true)); - }; - updateMonth = (day, doNotTriggerListeners = false) => { - if (day.toString('yyyy MM') === this.state.currentMonth.toString('yyyy MM')) { - return; - } - this.setState({ currentMonth: day.clone() }, () => { - if (!doNotTriggerListeners) { - const currMont = this.state.currentMonth.clone(); - _.invoke(this.props, 'onMonthChange', xdateToData(currMont)); - _.invoke(this.props, 'onVisibleMonthsChange', [xdateToData(currMont)]); - } - }); - }; - handleDayInteraction(date, interaction) { - const { disableMonthChange } = this.props; - const day = parseDate(date); - const minDate = parseDate(this.props.minDate); - const maxDate = parseDate(this.props.maxDate); - if (!(minDate && !dateutils.isGTE(day, minDate)) && !(maxDate && !dateutils.isLTE(day, maxDate))) { - const shouldUpdateMonth = disableMonthChange === undefined || !disableMonthChange; - if (shouldUpdateMonth) { - this.updateMonth(day); - } - if (interaction) { - interaction(xdateToData(day)); - } - } - } - pressDay = (date) => { - this.handleDayInteraction(date, this.props.onDayPress); - }; - longPressDay = (date) => { - this.handleDayInteraction(date, this.props.onDayLongPress); - }; - swipeProps = { onSwipe: (direction) => this.onSwipe(direction) }; - onSwipe = (gestureName) => { - const { SWIPE_UP, SWIPE_DOWN, SWIPE_LEFT, SWIPE_RIGHT } = swipeDirections; - switch (gestureName) { - case SWIPE_UP: - case SWIPE_DOWN: - break; - case SWIPE_LEFT: - this.onSwipeLeft(); - break; - case SWIPE_RIGHT: - this.onSwipeRight(); - break; - } - }; - onSwipeLeft = () => { - this.header?.current?.onPressRight(); - }; - onSwipeRight = () => { - this.header?.current?.onPressLeft(); - }; - renderWeekNumber = memoize(weekNumber => { - return ( - - {weekNumber} - - ); - }); - renderDay(day, id) { - const { hideExtraDays, markedDates } = this.props; - const dayProps = extractComponentProps(Day, this.props); - if (!dateutils.sameMonth(day, this.state.currentMonth) && hideExtraDays) { - return ; - } - return ( - - ); - } - renderWeek(days, id) { - const week = []; - days.forEach((day, id2) => { - week.push(this.renderDay(day, id2)); - }, this); - if (this.props.showWeekNumbers) { - week.unshift(this.renderWeekNumber(days[days.length - 1].getWeek())); - } - return ( - {week} - ); - } - renderMonth() { - const { currentMonth } = this.state; - const { firstDay, showSixWeeks, hideExtraDays } = this.props; - const shouldShowSixWeeks = showSixWeeks && !hideExtraDays; - const days = dateutils.page(currentMonth, firstDay, shouldShowSixWeeks); - const weeks = []; - while (days.length) { - weeks.push(this.renderWeek(days.splice(0, 7), weeks.length)); - } - return {weeks}; - } - renderHeader() { - const { customHeader, headerStyle, displayLoadingIndicator, markedDates, testID } = this.props; - const current = parseDate(this.props.current); - let indicator; - if (current) { - const lastMonthOfDay = toMarkingFormat(current.clone().addMonths(1, true).setDate(1).addDays(-1)); - if (displayLoadingIndicator && !(markedDates?.[lastMonthOfDay])) { - indicator = true; - } - } - const headerProps = extractComponentProps(CalendarHeader, this.props); - const CustomHeader = customHeader; - const HeaderComponent = customHeader ? CustomHeader : CalendarHeader; - return (); - } - render() { - const { enableSwipeMonths, style } = this.props; - const GestureComponent = enableSwipeMonths ? GestureRecognizer : View; - const gestureProps = enableSwipeMonths ? this.swipeProps : undefined; - return ( - - {this.renderHeader()} - {this.renderMonth()} - - ); - } -} -export default Calendar; diff --git a/src/calendar/style.d.ts b/src/calendar/style.d.ts deleted file mode 100644 index 7eede9e14f..0000000000 --- a/src/calendar/style.d.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { Theme } from '../commons/types'; -export default function getStyle(theme?: Theme): { - container: { - paddingLeft: number; - paddingRight: number; - backgroundColor: string; - }; - dayContainer: { - flex: number; - alignItems: "center"; - }; - emptyDayContainer: { - flex: number; - }; - monthView: { - backgroundColor: string; - }; - week: { - marginTop: number; - marginBottom: number; - flexDirection: "row"; - justifyContent: "space-around"; - }; -}; diff --git a/src/calendar/style.js b/src/calendar/style.js deleted file mode 100644 index 9c46c79d1a..0000000000 --- a/src/calendar/style.js +++ /dev/null @@ -1,29 +0,0 @@ -import { StyleSheet } from 'react-native'; -import * as defaultStyle from '../style'; -export default function getStyle(theme = {}) { - const appStyle = { ...defaultStyle, ...theme }; - return StyleSheet.create({ - container: { - paddingLeft: 5, - paddingRight: 5, - backgroundColor: appStyle.calendarBackground - }, - dayContainer: { - flex: 1, - alignItems: 'center' - }, - emptyDayContainer: { - flex: 1 - }, - monthView: { - backgroundColor: appStyle.calendarBackground - }, - week: { - marginTop: 7, - marginBottom: 7, - flexDirection: 'row', - justifyContent: 'space-around' - }, - ...(theme.stylesheet?.calendar?.main || {}) - }); -} diff --git a/src/commons/types.d.ts b/src/commons/types.d.ts deleted file mode 100644 index 87d67cab62..0000000000 --- a/src/commons/types.d.ts +++ /dev/null @@ -1,80 +0,0 @@ -import { ColorValue } from 'react-native'; -export interface Theme { - container?: object; - contentStyle?: object; - header?: object; - headerText?: object; - arrowButton?: object; - event?: object; - eventTitle?: object; - eventSummary?: object; - eventTimes?: object; - line?: object; - lineNow?: object; - timeLabel?: object; - todayTextColor?: string; - calendarBackground?: string; - indicatorColor?: ColorValue | object; - stylesheet?: { - calendar?: { - main?: object; - header?: object; - }; - day?: { - basic?: object; - period?: object; - }; - dot?: object; - marking?: object; - 'calendar-list'?: { - main?: object; - }; - }; - textSectionTitleColor?: string; - textSectionTitleDisabledColor?: string; - dayTextColor?: string; - selectedDayTextColor?: string; - monthTextColor?: string; - selectedDayBackgroundColor?: string; - arrowColor?: string; - textDisabledColor?: string; - backgroundColor?: string; - dotColor?: string; - selectedDotColor?: string; - disabledArrowColor?: string; - textDayFontFamily?: string; - textMonthFontFamily?: string; - textDayHeaderFontFamily?: string; - textDayFontWeight?: string; - textMonthFontWeight?: string; - textDayHeaderFontWeight?: string; - textDayFontSize?: number; - textMonthFontSize?: number; - textDayHeaderFontSize?: number; - agendaDayTextColor?: string; - agendaDayNumColor?: string; - agendaTodayColor?: string; - agendaKnobColor?: string; - foregroundColor?: string; - separatorColor?: string; - processedColor?: string; - processingColor?: string; - failedColor?: string; - textSecondaryColor?: string; - textDefaultColor?: string; - textColor?: string; - textLinkColor?: string; - todayButtonFontFamily?: string; - todayButtonFontWeight?: string; - todayButtonFontSize?: number; - textDayStyle?: object; - dotStyle?: object; - arrowStyle?: object; - todayBackgroundColor?: string; - disabledDotColor?: string; - todayDotColor?: string; - todayButtonTextColor?: string; - todayButtonPosition?: string; - arrowHeight?: number; - arrowWidth?: number; -} diff --git a/src/commons/types.js b/src/commons/types.js deleted file mode 100644 index cb0ff5c3b5..0000000000 --- a/src/commons/types.js +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/src/style.d.ts b/src/style.d.ts deleted file mode 100644 index 59be29d7db..0000000000 --- a/src/style.d.ts +++ /dev/null @@ -1,48 +0,0 @@ -export declare const foregroundColor = "white"; -export declare const backgroundColor = "#f2F4f5"; -export declare const separatorColor = "#f2F4f5"; -export declare const processedColor = "#a7e0a3"; -export declare const processingColor = "#ffce5c"; -export declare const failedColor = "#f67e7e"; -export declare const textSecondaryColor = "#7a92a5"; -export declare const textDefaultColor = "#2d4150"; -export declare const textColor = "#43515c"; -export declare const textLinkColor = "#00BBF2"; -export declare const textDayFontFamily = "System"; -export declare const textMonthFontFamily = "System"; -export declare const textDayHeaderFontFamily = "System"; -export declare const todayButtonFontFamily = "System"; -export declare const textDayFontWeight = "300"; -export declare const textMonthFontWeight = "300"; -export declare const textDayHeaderFontWeight: undefined; -export declare const todayButtonFontWeight = "600"; -export declare const textDayFontSize = 16; -export declare const textMonthFontSize = 16; -export declare const textDayHeaderFontSize = 13; -export declare const todayButtonFontSize = 14; -export declare const textDayStyle: undefined; -export declare const dotStyle: undefined; -export declare const arrowStyle: undefined; -export declare const calendarBackground = "white"; -export declare const textSectionTitleColor = "#b6c1cd"; -export declare const textSectionTitleDisabledColor = "#d9e1e8"; -export declare const selectedDayBackgroundColor = "#00BBF2"; -export declare const selectedDayTextColor = "white"; -export declare const todayBackgroundColor: undefined; -export declare const todayTextColor = "#00BBF2"; -export declare const dayTextColor = "#2d4150"; -export declare const textDisabledColor = "#d9e1e8"; -export declare const dotColor = "#00BBF2"; -export declare const selectedDotColor = "white"; -export declare const disabledDotColor: undefined; -export declare const todayDotColor: undefined; -export declare const arrowColor = "#00BBF2"; -export declare const disabledArrowColor = "#d9e1e8"; -export declare const monthTextColor = "#2d4150"; -export declare const indicatorColor: undefined; -export declare const agendaDayTextColor = "#7a92a5"; -export declare const agendaDayNumColor = "#7a92a5"; -export declare const agendaTodayColor = "#00BBF2"; -export declare const agendaKnobColor = "#f2F4f5"; -export declare const todayButtonTextColor = "#00BBF2"; -export declare const todayButtonPosition: undefined; diff --git a/src/style.js b/src/style.js deleted file mode 100644 index a266d05b18..0000000000 --- a/src/style.js +++ /dev/null @@ -1,48 +0,0 @@ -export const foregroundColor = 'white'; -export const backgroundColor = '#f2F4f5'; // Agenda's reservations bg color -export const separatorColor = '#f2F4f5'; // not in use -export const processedColor = '#a7e0a3'; // not in use -export const processingColor = '#ffce5c'; // not in use -export const failedColor = '#f67e7e'; // not in use -export const textSecondaryColor = '#7a92a5'; // not in use -export const textDefaultColor = '#2d4150'; -export const textColor = '#43515c'; -export const textLinkColor = '#00BBF2'; -export const textDayFontFamily = 'System'; -export const textMonthFontFamily = 'System'; -export const textDayHeaderFontFamily = 'System'; -export const todayButtonFontFamily = 'System'; -export const textDayFontWeight = '300'; -export const textMonthFontWeight = '300'; -export const textDayHeaderFontWeight = undefined; -export const todayButtonFontWeight = '600'; -export const textDayFontSize = 16; -export const textMonthFontSize = 16; -export const textDayHeaderFontSize = 13; -export const todayButtonFontSize = 14; -export const textDayStyle = undefined; -export const dotStyle = undefined; -export const arrowStyle = undefined; -export const calendarBackground = foregroundColor; -export const textSectionTitleColor = '#b6c1cd'; -export const textSectionTitleDisabledColor = '#d9e1e8'; -export const selectedDayBackgroundColor = textLinkColor; -export const selectedDayTextColor = foregroundColor; -export const todayBackgroundColor = undefined; -export const todayTextColor = textLinkColor; -export const dayTextColor = textDefaultColor; -export const textDisabledColor = '#d9e1e8'; -export const dotColor = textLinkColor; -export const selectedDotColor = foregroundColor; -export const disabledDotColor = undefined; -export const todayDotColor = undefined; -export const arrowColor = textLinkColor; -export const disabledArrowColor = '#d9e1e8'; -export const monthTextColor = textDefaultColor; -export const indicatorColor = undefined; // use the default color of React Native ActivityIndicator -export const agendaDayTextColor = '#7a92a5'; -export const agendaDayNumColor = '#7a92a5'; -export const agendaTodayColor = textLinkColor; -export const agendaKnobColor = '#f2F4f5'; -export const todayButtonTextColor = textLinkColor; -export const todayButtonPosition = undefined; // right' / 'left'(default) From 81e2d3b149c940440e4f9dc647cd91e732b2c9d5 Mon Sep 17 00:00:00 2001 From: Inbal Tish Date: Sun, 1 Aug 2021 14:02:44 +0300 Subject: [PATCH 058/109] restoring prop-types for extractComponentProps function --- src/agenda/index.tsx | 37 ++++++++++++++++++--- src/agenda/reservation-list/index.tsx | 34 +++++++++++++++++++ src/agenda/reservation-list/reservation.tsx | 18 ++++++++++ 3 files changed, 85 insertions(+), 4 deletions(-) diff --git a/src/agenda/index.tsx b/src/agenda/index.tsx index 0d81374877..5c69b3b0f4 100644 --- a/src/agenda/index.tsx +++ b/src/agenda/index.tsx @@ -1,8 +1,10 @@ import _ from 'lodash'; +import PropTypes from 'prop-types'; import XDate from 'xdate'; import memoize from 'memoize-one'; import React, {Component} from 'react'; import {Text, View, Dimensions, Animated, ViewStyle, LayoutChangeEvent, NativeSyntheticEvent, NativeScrollEvent, StyleSheet} from 'react-native'; + // @ts-expect-error import {extractComponentProps} from '../component-updater.js'; // @ts-expect-error @@ -17,6 +19,7 @@ import CalendarList, {CalendarListProps} from '../calendar-list'; import styleConstructor from './style'; import ReservationList, {ReservactionListProps} from './reservation-list'; + const HEADER_HEIGHT = 104; const KNOB_HEIGHT = 24; @@ -64,7 +67,6 @@ type AgendaState = { topDay: XDate; } - /** * @description: Agenda component * @extends: CalendarList @@ -72,8 +74,36 @@ type AgendaState = { * @example: https://github.com/wix/react-native-calendars/blob/master/example/src/screens/agenda.js * @gif: https://github.com/wix/react-native-calendars/blob/master/demo/agenda.gif */ -export default class AgendaView extends Component { +export default class Agenda extends Component { static displayName = 'Agenda'; + + static propTypes = { + ...CalendarList.propTypes, + ...ReservationList.propTypes, + /** agenda container style */ + style: PropTypes.oneOfType([PropTypes.object, PropTypes.array, PropTypes.number]), + /** the list of items that have to be displayed in agenda. If you want to render item as empty date + the value of date key has to be an empty array []. If there exists no value for date key it is + considered that the date in question is not yet loaded */ + items: PropTypes.object, + /** callback that gets called when items for a certain month should be loaded (month became visible) */ + loadItemsForMonth: PropTypes.func, + /** callback that fires when the calendar is opened or closed */ + onCalendarToggled: PropTypes.func, + /** callback that gets called on day press */ + onDayPress: PropTypes.func, + /** callback that gets called when day changes while scrolling agenda list */ + onDaychange: PropTypes.func, //TODO: Should be renamed 'onDayChange' + /** specify how agenda knob should look like */ + renderKnob: PropTypes.func, + /** initially selected day */ + selected: PropTypes.any, //TODO: Should be renamed 'selectedDay' + /** Hide knob button. Default = false */ + hideKnob: PropTypes.bool, + /** When `true` and `hideKnob` prop is `false`, the knob will always be visible and the user will be able to drag the knob up and close the calendar. Default = false */ + showClosingKnob: PropTypes.bool + } + private style: {[key: string]: ViewStyle}; private viewHeight: number; private viewWidth: number; @@ -379,8 +409,7 @@ export default class AgendaView extends Component { }); renderWeekNumbersSpace = () => { - // @ts-expect-error - return this.props.showWeekNumbers && ; + return this.props.showWeekNumbers && ; }; render() { diff --git a/src/agenda/reservation-list/index.tsx b/src/agenda/reservation-list/index.tsx index f2db796797..32f9e0cc15 100644 --- a/src/agenda/reservation-list/index.tsx +++ b/src/agenda/reservation-list/index.tsx @@ -1,4 +1,5 @@ import _ from 'lodash'; +import PropTypes from 'prop-types'; import XDate from 'xdate'; import React, {Component} from 'react'; @@ -60,6 +61,39 @@ interface ReservationsListState { class ReservationList extends Component { static displayName = 'IGNORE'; + static propTypes = { + ...Reservation.propTypes, + /** the list of items that have to be displayed in agenda. If you want to render item as empty date + the value of date key kas to be an empty array []. If there exists no value for date key it is + considered that the date in question is not yet loaded */ + reservations: PropTypes.object, + selectedDay: PropTypes.instanceOf(XDate), + topDay: PropTypes.instanceOf(XDate), + /** Show items only for the selected day. Default = false */ + showOnlySelectedDayItems: PropTypes.bool, + /** callback that gets called when day changes while scrolling agenda list */ + onDayChange: PropTypes.func, + /** specify what should be rendered instead of ActivityIndicator */ + renderEmptyData: PropTypes.func, + + /** onScroll ListView event */ + onScroll: PropTypes.func, + /** Called when the user begins dragging the agenda list **/ + onScrollBeginDrag: PropTypes.func, + /** Called when the user stops dragging the agenda list **/ + onScrollEndDrag: PropTypes.func, + /** Called when the momentum scroll starts for the agenda list **/ + onMomentumScrollBegin: PropTypes.func, + /** Called when the momentum scroll stops for the agenda list **/ + onMomentumScrollEnd: PropTypes.func, + /** A RefreshControl component, used to provide pull-to-refresh functionality for the ScrollView */ + refreshControl: PropTypes.element, + /** Set this true while waiting for new data from a refresh */ + refreshing: PropTypes.bool, + /** If provided, a standard RefreshControl will be added for "Pull to Refresh" functionality. Make sure to also set the refreshing prop correctly */ + onRefresh: PropTypes.func + } + static defaultProps = { refreshing: false, selectedDay: new XDate(true), diff --git a/src/agenda/reservation-list/reservation.tsx b/src/agenda/reservation-list/reservation.tsx index ce4d889463..16aeaef2bb 100644 --- a/src/agenda/reservation-list/reservation.tsx +++ b/src/agenda/reservation-list/reservation.tsx @@ -1,7 +1,10 @@ import _ from 'lodash'; +import PropTypes from 'prop-types'; import XDate from 'xdate'; + import React, {Component} from 'react'; import {View, Text} from 'react-native'; + // @ts-expect-error import {xdateToData} from '../../interface'; // @ts-expect-error @@ -28,6 +31,21 @@ export interface ReservationProps { class Reservation extends Component { static displayName = 'IGNORE'; + + static propTypes = { + item: PropTypes.any, + /** Specify theme properties to override specific styles for reservation parts. Default = {} */ + theme: PropTypes.object, + /** specify your item comparison function for increased performance */ + rowHasChanged: PropTypes.func, + /** specify how each date should be rendered. day can be undefined if the item is not first in that day */ + renderDay: PropTypes.func, + /** specify how each item should be rendered in agenda */ + renderItem: PropTypes.func, + /** specify how empty date content with no items should be rendered */ + renderEmptyDate: PropTypes.func + } + style; constructor(props: ReservationProps) { From e4115c577616f70082148099ec2cac0c31b5c769 Mon Sep 17 00:00:00 2001 From: Inbal Tish Date: Sun, 1 Aug 2021 14:21:44 +0300 Subject: [PATCH 059/109] change const name --- src/agenda/index.tsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/agenda/index.tsx b/src/agenda/index.tsx index 5c69b3b0f4..96c3c2689b 100644 --- a/src/agenda/index.tsx +++ b/src/agenda/index.tsx @@ -111,7 +111,7 @@ export default class Agenda extends Component { private headerState: string; private currentMonth: XDate; private knobTracker: any; - private _isMounted: boolean | undefined; + private isMounted: boolean | undefined; private scrollPad: any; private calendar: any; private knob: any; @@ -145,12 +145,12 @@ export default class Agenda extends Component { } componentDidMount() { - this._isMounted = true; + this.isMounted = true; this.loadReservations(this.props); } componentWillUnmount() { - this._isMounted = false; + this.isMounted = false; this.state.scrollY.removeAllListeners(); } @@ -329,7 +329,7 @@ export default class Agenda extends Component { clearTimeout(this.scrollTimeout); this.scrollTimeout = setTimeout(() => { - if (this._isMounted) { + if (this.isMounted) { _.invoke(this.props, 'loadItemsForMonth', months[0]); } }, 200); @@ -467,7 +467,7 @@ export default class Agenda extends Component { height: KNOB_HEIGHT, top: scrollPadPosition, left: (this.viewWidth - 80) / 2, - } + }; return ( From b1f644669edd7bd8020c825cab6cea7d92600090 Mon Sep 17 00:00:00 2001 From: Inbal Tish Date: Sun, 1 Aug 2021 14:25:09 +0300 Subject: [PATCH 060/109] Revert "change const name" This reverts commit e4115c577616f70082148099ec2cac0c31b5c769. --- src/agenda/index.tsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/agenda/index.tsx b/src/agenda/index.tsx index 96c3c2689b..5c69b3b0f4 100644 --- a/src/agenda/index.tsx +++ b/src/agenda/index.tsx @@ -111,7 +111,7 @@ export default class Agenda extends Component { private headerState: string; private currentMonth: XDate; private knobTracker: any; - private isMounted: boolean | undefined; + private _isMounted: boolean | undefined; private scrollPad: any; private calendar: any; private knob: any; @@ -145,12 +145,12 @@ export default class Agenda extends Component { } componentDidMount() { - this.isMounted = true; + this._isMounted = true; this.loadReservations(this.props); } componentWillUnmount() { - this.isMounted = false; + this._isMounted = false; this.state.scrollY.removeAllListeners(); } @@ -329,7 +329,7 @@ export default class Agenda extends Component { clearTimeout(this.scrollTimeout); this.scrollTimeout = setTimeout(() => { - if (this.isMounted) { + if (this._isMounted) { _.invoke(this.props, 'loadItemsForMonth', months[0]); } }, 200); @@ -467,7 +467,7 @@ export default class Agenda extends Component { height: KNOB_HEIGHT, top: scrollPadPosition, left: (this.viewWidth - 80) / 2, - }; + } return ( From 7db01890414ad639a6dd91480071799242e0fbad Mon Sep 17 00:00:00 2001 From: Inbal Tish Date: Sun, 1 Aug 2021 14:27:11 +0300 Subject: [PATCH 061/109] fix typo --- src/agenda/index.tsx | 7 ++++--- src/agenda/reservation-list/index.tsx | 14 +++++++------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/agenda/index.tsx b/src/agenda/index.tsx index 5c69b3b0f4..d5ca19abcb 100644 --- a/src/agenda/index.tsx +++ b/src/agenda/index.tsx @@ -2,6 +2,7 @@ import _ from 'lodash'; import PropTypes from 'prop-types'; import XDate from 'xdate'; import memoize from 'memoize-one'; + import React, {Component} from 'react'; import {Text, View, Dimensions, Animated, ViewStyle, LayoutChangeEvent, NativeSyntheticEvent, NativeScrollEvent, StyleSheet} from 'react-native'; @@ -17,7 +18,7 @@ import {AGENDA_CALENDAR_KNOB} from '../testIDs'; import {VelocityTracker} from '../input'; import CalendarList, {CalendarListProps} from '../calendar-list'; import styleConstructor from './style'; -import ReservationList, {ReservactionListProps} from './reservation-list'; +import ReservationList, {ReservationListProps} from './reservation-list'; const HEADER_HEIGHT = 104; @@ -33,7 +34,7 @@ export type ReservationsType = { [date: string]: ReservationItemType[] } -export type AgendaProps = CalendarListProps & ReservactionListProps & { +export type AgendaProps = CalendarListProps & ReservationListProps & { /** agenda container style */ style?: ViewStyle; /** the list of items that have to be displayed in agenda. If you want to render item as empty date @@ -467,7 +468,7 @@ export default class Agenda extends Component { height: KNOB_HEIGHT, top: scrollPadPosition, left: (this.viewWidth - 80) / 2, - } + }; return ( diff --git a/src/agenda/reservation-list/index.tsx b/src/agenda/reservation-list/index.tsx index 32f9e0cc15..89ae91b173 100644 --- a/src/agenda/reservation-list/index.tsx +++ b/src/agenda/reservation-list/index.tsx @@ -21,7 +21,7 @@ export interface DayReservations { day: XDate; } -export type ReservactionListProps = ReservationProps & { +export type ReservationListProps = ReservationProps & { /** the list of items that have to be displayed in agenda. If you want to render item as empty date the value of date key kas to be an empty array []. If there exists no value for date key it is considered that the date in question is not yet loaded */ @@ -58,7 +58,7 @@ interface ReservationsListState { reservations: DayReservations[]; } -class ReservationList extends Component { +class ReservationList extends Component { static displayName = 'IGNORE'; static propTypes = { @@ -104,7 +104,7 @@ class ReservationList extends Component | null; - constructor(props: ReservactionListProps) { + constructor(props: ReservationListProps) { super(props); this.style = styleConstructor(props.theme); @@ -122,7 +122,7 @@ class ReservationList extends Component Date: Sun, 1 Aug 2021 14:33:45 +0300 Subject: [PATCH 062/109] remove unused import; use optional chaining --- src/agenda/index.tsx | 6 +++--- src/agenda/reservation-list/index.tsx | 5 +++-- src/agenda/reservation-list/reservation.tsx | 3 ++- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/agenda/index.tsx b/src/agenda/index.tsx index d5ca19abcb..4e19d9f9d8 100644 --- a/src/agenda/index.tsx +++ b/src/agenda/index.tsx @@ -4,7 +4,7 @@ import XDate from 'xdate'; import memoize from 'memoize-one'; import React, {Component} from 'react'; -import {Text, View, Dimensions, Animated, ViewStyle, LayoutChangeEvent, NativeSyntheticEvent, NativeScrollEvent, StyleSheet} from 'react-native'; +import {Text, View, Dimensions, Animated, ViewStyle, LayoutChangeEvent, NativeSyntheticEvent, NativeScrollEvent} from 'react-native'; // @ts-expect-error import {extractComponentProps} from '../component-updater.js'; @@ -388,10 +388,10 @@ export default class Agenda extends Component { renderKnob() { const {showClosingKnob, hideKnob, renderKnob} = this.props; - let knob: JSX.Element | null = ; + let knob: JSX.Element | null = ; if (!hideKnob) { - const knobView = renderKnob ? renderKnob() : ; + const knobView = renderKnob ? renderKnob() : ; knob = !this.state.calendarScrollable || showClosingKnob ? ( (this.knob = c)}>{knobView} diff --git a/src/agenda/reservation-list/index.tsx b/src/agenda/reservation-list/index.tsx index 89ae91b173..af58b5d237 100644 --- a/src/agenda/reservation-list/index.tsx +++ b/src/agenda/reservation-list/index.tsx @@ -4,6 +4,7 @@ import XDate from 'xdate'; import React, {Component} from 'react'; import {ActivityIndicator, View, FlatList, ViewStyle, TextStyle, NativeSyntheticEvent, NativeScrollEvent, LayoutChangeEvent} from 'react-native'; + // @ts-expect-error import {extractComponentProps} from '../../component-updater'; // @ts-expect-error @@ -268,7 +269,7 @@ class ReservationList extends Component - + ); }; @@ -282,7 +283,7 @@ class ReservationList extends Component; + return ; } return ( diff --git a/src/agenda/reservation-list/reservation.tsx b/src/agenda/reservation-list/reservation.tsx index 16aeaef2bb..07d6ac6e35 100644 --- a/src/agenda/reservation-list/reservation.tsx +++ b/src/agenda/reservation-list/reservation.tsx @@ -15,6 +15,7 @@ import styleConstructor from './style'; import {Theme} from '../../commons/types'; import {DayReservations} from './index'; + export interface ReservationProps { item: DayReservations; /** Specify theme properties to override specific styles for reservation parts. Default = {} */ @@ -96,7 +97,7 @@ class Reservation extends Component { ); } else { - return ; + return ; } } From fa07f88e86f97768f43eb3e98b49e362287ee009 Mon Sep 17 00:00:00 2001 From: Inbal Tish Date: Sun, 1 Aug 2021 14:39:14 +0300 Subject: [PATCH 063/109] renaming Agenda demo screen --- example/src/screens/{agenda.js => agenda.tsx} | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) rename example/src/screens/{agenda.js => agenda.tsx} (97%) diff --git a/example/src/screens/agenda.js b/example/src/screens/agenda.tsx similarity index 97% rename from example/src/screens/agenda.js rename to example/src/screens/agenda.tsx index 39841f3214..4fe5d3fb5b 100644 --- a/example/src/screens/agenda.js +++ b/example/src/screens/agenda.tsx @@ -1,17 +1,14 @@ import React, {Component} from 'react'; import {Alert, StyleSheet, Text, View, TouchableOpacity} from 'react-native'; +// @ts-expect-error import {Agenda} from 'react-native-calendars'; const testIDs = require('../testIDs'); export default class AgendaScreen extends Component { - constructor(props) { - super(props); - - this.state = { - items: {} - }; - } + state = { + items: {} + }; render() { return ( From 067f8d32ed3c7feac7f4c660dbf0d70099316fe8 Mon Sep 17 00:00:00 2001 From: Inbal Tish Date: Sun, 1 Aug 2021 15:14:17 +0300 Subject: [PATCH 064/109] migration demo screens --- example/src/screens/agenda.tsx | 1 + example/src/screens/calendars.tsx | 2 ++ example/src/screens/{calendarsList.js => calendarsList.tsx} | 2 ++ .../{horizontalCalendarList.js => horizontalCalendarList.tsx} | 2 ++ 4 files changed, 7 insertions(+) rename example/src/screens/{calendarsList.js => calendarsList.tsx} (98%) rename example/src/screens/{horizontalCalendarList.js => horizontalCalendarList.tsx} (97%) diff --git a/example/src/screens/agenda.tsx b/example/src/screens/agenda.tsx index 4fe5d3fb5b..1e798b0355 100644 --- a/example/src/screens/agenda.tsx +++ b/example/src/screens/agenda.tsx @@ -3,6 +3,7 @@ import {Alert, StyleSheet, Text, View, TouchableOpacity} from 'react-native'; // @ts-expect-error import {Agenda} from 'react-native-calendars'; + const testIDs = require('../testIDs'); export default class AgendaScreen extends Component { diff --git a/example/src/screens/calendars.tsx b/example/src/screens/calendars.tsx index d0a7deb65f..9967b5b3f8 100644 --- a/example/src/screens/calendars.tsx +++ b/example/src/screens/calendars.tsx @@ -1,7 +1,9 @@ import React, {useState, Fragment} from 'react'; import {StyleSheet, View, ScrollView, Text, TouchableOpacity, Switch} from 'react-native'; +// @ts-expect-error import {Calendar} from 'react-native-calendars'; + const testIDs = require('../testIDs'); const INITIAL_DATE = '2020-02-02'; diff --git a/example/src/screens/calendarsList.js b/example/src/screens/calendarsList.tsx similarity index 98% rename from example/src/screens/calendarsList.js rename to example/src/screens/calendarsList.tsx index 747ba5b85d..8bc4652917 100644 --- a/example/src/screens/calendarsList.js +++ b/example/src/screens/calendarsList.tsx @@ -1,7 +1,9 @@ import React, {useState} from 'react'; import {StyleSheet, Text, View} from 'react-native'; +// @ts-expect-error import {CalendarList} from 'react-native-calendars'; + const testIDs = require('../testIDs'); const RANGE = 24; const initialDate = '2020-06-10'; diff --git a/example/src/screens/horizontalCalendarList.js b/example/src/screens/horizontalCalendarList.tsx similarity index 97% rename from example/src/screens/horizontalCalendarList.js rename to example/src/screens/horizontalCalendarList.tsx index a8e5be821f..6a7e2f1d1d 100644 --- a/example/src/screens/horizontalCalendarList.js +++ b/example/src/screens/horizontalCalendarList.tsx @@ -1,6 +1,8 @@ import React, {useState} from 'react'; +// @ts-expect-error import {CalendarList} from 'react-native-calendars'; + const testIDs = require('../testIDs'); const initialDate = '2020-05-16'; From cc431175bc1a925a25d29d20779ccbb029b95e1a Mon Sep 17 00:00:00 2001 From: Inbal Tish Date: Wed, 4 Aug 2021 15:25:47 +0300 Subject: [PATCH 065/109] rn 0.64.2 upgrade --- _editorconfig | 3 + android/app/build.gradle | 6 +- android/app/src/debug/AndroidManifest.xml | 7 +- android/app/src/main/AndroidManifest.xml | 2 - android/app/src/main/res/values/styles.xml | 2 +- android/build.gradle | 7 +- android/gradle.properties | 3 + .../gradle/wrapper/gradle-wrapper.properties | 2 +- android/gradlew | 2 + android/gradlew.bat | 19 +- ios/CalendarsExample-tvOS/Info.plist | 54 -- ios/CalendarsExample-tvOSTests/Info.plist | 24 - .../xcschemes/CalendarsExample-tvOS.xcscheme | 125 ----- .../xcschemes/CalendarsExample.xcscheme | 2 +- ios/CalendarsExample/LaunchScreen.storyboard | 13 +- ios/Podfile | 15 +- ios/Podfile.lock | 462 ++++++++++-------- package.json | 6 +- 18 files changed, 285 insertions(+), 469 deletions(-) create mode 100644 _editorconfig delete mode 100644 ios/CalendarsExample-tvOS/Info.plist delete mode 100644 ios/CalendarsExample-tvOSTests/Info.plist delete mode 100644 ios/CalendarsExample.xcodeproj/xcshareddata/xcschemes/CalendarsExample-tvOS.xcscheme diff --git a/_editorconfig b/_editorconfig new file mode 100644 index 0000000000..7c286132fe --- /dev/null +++ b/_editorconfig @@ -0,0 +1,3 @@ +# Windows files +[*.bat] +end_of_line = crlf diff --git a/android/app/build.gradle b/android/app/build.gradle index 38b2caa588..dabbb7af8b 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -16,9 +16,12 @@ def jscFlavor = 'org.webkit:android-jsc:+' def enableHermes = project.ext.react.get("enableHermes", false) android { + ndkVersion rootProject.ext.ndkVersion + compileSdkVersion rootProject.ext.compileSdkVersion buildToolsVersion rootProject.ext.buildToolsVersion + compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 @@ -65,11 +68,12 @@ android { variant.outputs.each { output -> // For each separate APK per architecture, set a unique version code as described here: // https://developer.android.com/studio/build/configure-apk-splits.html + // Example: versionCode 1 will generate 1001 for armeabi-v7a, 1002 for x86, etc. def versionCodes = ["armeabi-v7a": 1, "x86": 2, "arm64-v8a": 3, "x86_64": 4] def abi = output.getFilter(OutputFile.ABI) if (abi != null) { // null for the universal-debug, universal-release variants output.versionCodeOverride = - versionCodes.get(abi) * 1048576 + defaultConfig.versionCode + defaultConfig.versionCode * 1000 + versionCodes.get(abi) } } } diff --git a/android/app/src/debug/AndroidManifest.xml b/android/app/src/debug/AndroidManifest.xml index fa26aa56e1..b2f3ad9fce 100644 --- a/android/app/src/debug/AndroidManifest.xml +++ b/android/app/src/debug/AndroidManifest.xml @@ -4,5 +4,10 @@ - + + + diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 9f42d5c461..a5510c469a 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -21,7 +21,5 @@ - - diff --git a/android/app/src/main/res/values/styles.xml b/android/app/src/main/res/values/styles.xml index 62fe59fa48..9fab0be743 100644 --- a/android/app/src/main/res/values/styles.xml +++ b/android/app/src/main/res/values/styles.xml @@ -1,7 +1,7 @@ - diff --git a/android/build.gradle b/android/build.gradle index f7c9df5bcb..86a1d881dc 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -2,10 +2,11 @@ buildscript { ext { - buildToolsVersion = "29.0.2" - minSdkVersion = 19 + buildToolsVersion = "29.0.3" + minSdkVersion = 21 compileSdkVersion = 29 targetSdkVersion = 29 + ndkVersion = "20.1.5948944" supportLibVersion = "29.0.0" RNNKotlinVersion = "1.3.72" } @@ -16,7 +17,7 @@ buildscript { mavenCentral() } dependencies { - classpath("com.android.tools.build:gradle:3.5.3") + classpath("com.android.tools.build:gradle:4.1.0") classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.72" // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files diff --git a/android/gradle.properties b/android/gradle.properties index 8b3ac93251..afe59c01dc 100644 --- a/android/gradle.properties +++ b/android/gradle.properties @@ -20,3 +20,6 @@ android.useDeprecatedNdk=true android.useAndroidX=true android.enableJetifier=true + +# Version of flipper SDK to use with React Native +FLIPPER_VERSION=0.75.1 diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties index 7c18f286d6..f014ae30aa 100644 --- a/android/gradle/wrapper/gradle-wrapper.properties +++ b/android/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ #Wed Mar 27 10:33:44 IST 2019 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/android/gradlew b/android/gradlew index 77c906c272..305a24954a 100755 --- a/android/gradlew +++ b/android/gradlew @@ -83,6 +83,7 @@ cd "$SAVED" >&- CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + # Determine the Java command to use to start the JVM. if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then @@ -130,6 +131,7 @@ fi if $cygwin ; then APP_HOME=`cygpath --path --mixed "$APP_HOME"` CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + # We build the pattern for arguments to be converted via cygpath ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` diff --git a/android/gradlew.bat b/android/gradlew.bat index 4cea078860..b9dd3fc046 100644 --- a/android/gradlew.bat +++ b/android/gradlew.bat @@ -43,7 +43,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init +if "%ERRORLEVEL%" == "0" goto execute echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. @@ -57,7 +57,7 @@ goto fail set JAVA_HOME=%JAVA_HOME:"=% set JAVA_EXE=%JAVA_HOME%/bin/java.exe -if exist "%JAVA_EXE%" goto init +if exist "%JAVA_EXE%" goto execute echo. echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% @@ -67,21 +67,9 @@ echo location of your Java installation. goto fail -:init -@rem Get command-line arguments, handling Windowz variants -if not "%OS%" == "Windows_NT" goto win9xME_args if "%@eval[2+2]" == "4" goto 4NT_args -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* goto execute :4NT_args @@ -93,8 +81,9 @@ set CMD_LINE_ARGS=%$ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* :end @rem End local scope for the variables with windows NT shell diff --git a/ios/CalendarsExample-tvOS/Info.plist b/ios/CalendarsExample-tvOS/Info.plist deleted file mode 100644 index 2fb6a11c2c..0000000000 --- a/ios/CalendarsExample-tvOS/Info.plist +++ /dev/null @@ -1,54 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - APPL - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - 1 - LSRequiresIPhoneOS - - UILaunchStoryboardName - LaunchScreen - UIRequiredDeviceCapabilities - - armv7 - - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UIViewControllerBasedStatusBarAppearance - - NSLocationWhenInUseUsageDescription - - NSAppTransportSecurity - - - NSExceptionDomains - - localhost - - NSExceptionAllowsInsecureHTTPLoads - - - - - - diff --git a/ios/CalendarsExample-tvOSTests/Info.plist b/ios/CalendarsExample-tvOSTests/Info.plist deleted file mode 100644 index ba72822e87..0000000000 --- a/ios/CalendarsExample-tvOSTests/Info.plist +++ /dev/null @@ -1,24 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - BNDL - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - 1 - - diff --git a/ios/CalendarsExample.xcodeproj/xcshareddata/xcschemes/CalendarsExample-tvOS.xcscheme b/ios/CalendarsExample.xcodeproj/xcshareddata/xcschemes/CalendarsExample-tvOS.xcscheme deleted file mode 100644 index 1297a5aaa4..0000000000 --- a/ios/CalendarsExample.xcodeproj/xcshareddata/xcschemes/CalendarsExample-tvOS.xcscheme +++ /dev/null @@ -1,125 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ios/CalendarsExample.xcodeproj/xcshareddata/xcschemes/CalendarsExample.xcscheme b/ios/CalendarsExample.xcodeproj/xcshareddata/xcschemes/CalendarsExample.xcscheme index 101d038791..f267e62bf5 100644 --- a/ios/CalendarsExample.xcodeproj/xcshareddata/xcschemes/CalendarsExample.xcscheme +++ b/ios/CalendarsExample.xcodeproj/xcshareddata/xcschemes/CalendarsExample.xcscheme @@ -1,6 +1,6 @@ - - + - - - diff --git a/ios/Podfile b/ios/Podfile index b798280e16..dd26543a26 100644 --- a/ios/Podfile +++ b/ios/Podfile @@ -6,19 +6,14 @@ platform :ios, '10.0' target 'CalendarsExample' do config = use_native_modules! - use_react_native!(:path => config["reactNativePath"]) + use_react_native!( + :path => config[:reactNativePath], + # to enable hermes on iOS, change `false` to `true` and then install pods + :hermes_enabled => false + ) target 'CalendarsExampleTests' do inherit! :search_paths # Pods for testing end end - -target 'CalendarsExample-tvOS' do - # Pods for CalendarsExample-tvOS - - target 'CalendarsExample-tvOSTests' do - inherit! :search_paths - # Pods for testing - end -end diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 25bb957722..8947ebb7d9 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -1,250 +1,272 @@ PODS: - boost-for-react-native (1.63.0) - DoubleConversion (1.1.6) - - FBLazyVector (0.63.4) - - FBReactNativeSpec (0.63.4): - - Folly (= 2020.01.13.00) - - RCTRequired (= 0.63.4) - - RCTTypeSafety (= 0.63.4) - - React-Core (= 0.63.4) - - React-jsi (= 0.63.4) - - ReactCommon/turbomodule/core (= 0.63.4) - - Folly (2020.01.13.00): + - FBLazyVector (0.64.2) + - FBReactNativeSpec (0.64.2): + - RCT-Folly (= 2020.01.13.00) + - RCTRequired (= 0.64.2) + - RCTTypeSafety (= 0.64.2) + - React-Core (= 0.64.2) + - React-jsi (= 0.64.2) + - ReactCommon/turbomodule/core (= 0.64.2) + - glog (0.3.5) + - RCT-Folly (2020.01.13.00): - boost-for-react-native - DoubleConversion - - Folly/Default (= 2020.01.13.00) - glog - - Folly/Default (2020.01.13.00): + - RCT-Folly/Default (= 2020.01.13.00) + - RCT-Folly/Default (2020.01.13.00): - boost-for-react-native - DoubleConversion - glog - - glog (0.3.5) - - RCTRequired (0.63.4) - - RCTTypeSafety (0.63.4): - - FBLazyVector (= 0.63.4) - - Folly (= 2020.01.13.00) - - RCTRequired (= 0.63.4) - - React-Core (= 0.63.4) - - React (0.63.4): - - React-Core (= 0.63.4) - - React-Core/DevSupport (= 0.63.4) - - React-Core/RCTWebSocket (= 0.63.4) - - React-RCTActionSheet (= 0.63.4) - - React-RCTAnimation (= 0.63.4) - - React-RCTBlob (= 0.63.4) - - React-RCTImage (= 0.63.4) - - React-RCTLinking (= 0.63.4) - - React-RCTNetwork (= 0.63.4) - - React-RCTSettings (= 0.63.4) - - React-RCTText (= 0.63.4) - - React-RCTVibration (= 0.63.4) - - React-callinvoker (0.63.4) - - React-Core (0.63.4): - - Folly (= 2020.01.13.00) + - RCTRequired (0.64.2) + - RCTTypeSafety (0.64.2): + - FBLazyVector (= 0.64.2) + - RCT-Folly (= 2020.01.13.00) + - RCTRequired (= 0.64.2) + - React-Core (= 0.64.2) + - React (0.64.2): + - React-Core (= 0.64.2) + - React-Core/DevSupport (= 0.64.2) + - React-Core/RCTWebSocket (= 0.64.2) + - React-RCTActionSheet (= 0.64.2) + - React-RCTAnimation (= 0.64.2) + - React-RCTBlob (= 0.64.2) + - React-RCTImage (= 0.64.2) + - React-RCTLinking (= 0.64.2) + - React-RCTNetwork (= 0.64.2) + - React-RCTSettings (= 0.64.2) + - React-RCTText (= 0.64.2) + - React-RCTVibration (= 0.64.2) + - React-callinvoker (0.64.2) + - React-Core (0.64.2): - glog - - React-Core/Default (= 0.63.4) - - React-cxxreact (= 0.63.4) - - React-jsi (= 0.63.4) - - React-jsiexecutor (= 0.63.4) + - RCT-Folly (= 2020.01.13.00) + - React-Core/Default (= 0.64.2) + - React-cxxreact (= 0.64.2) + - React-jsi (= 0.64.2) + - React-jsiexecutor (= 0.64.2) + - React-perflogger (= 0.64.2) - Yoga - - React-Core/CoreModulesHeaders (0.63.4): - - Folly (= 2020.01.13.00) + - React-Core/CoreModulesHeaders (0.64.2): - glog + - RCT-Folly (= 2020.01.13.00) - React-Core/Default - - React-cxxreact (= 0.63.4) - - React-jsi (= 0.63.4) - - React-jsiexecutor (= 0.63.4) + - React-cxxreact (= 0.64.2) + - React-jsi (= 0.64.2) + - React-jsiexecutor (= 0.64.2) + - React-perflogger (= 0.64.2) - Yoga - - React-Core/Default (0.63.4): - - Folly (= 2020.01.13.00) + - React-Core/Default (0.64.2): - glog - - React-cxxreact (= 0.63.4) - - React-jsi (= 0.63.4) - - React-jsiexecutor (= 0.63.4) + - RCT-Folly (= 2020.01.13.00) + - React-cxxreact (= 0.64.2) + - React-jsi (= 0.64.2) + - React-jsiexecutor (= 0.64.2) + - React-perflogger (= 0.64.2) - Yoga - - React-Core/DevSupport (0.63.4): - - Folly (= 2020.01.13.00) + - React-Core/DevSupport (0.64.2): - glog - - React-Core/Default (= 0.63.4) - - React-Core/RCTWebSocket (= 0.63.4) - - React-cxxreact (= 0.63.4) - - React-jsi (= 0.63.4) - - React-jsiexecutor (= 0.63.4) - - React-jsinspector (= 0.63.4) + - RCT-Folly (= 2020.01.13.00) + - React-Core/Default (= 0.64.2) + - React-Core/RCTWebSocket (= 0.64.2) + - React-cxxreact (= 0.64.2) + - React-jsi (= 0.64.2) + - React-jsiexecutor (= 0.64.2) + - React-jsinspector (= 0.64.2) + - React-perflogger (= 0.64.2) - Yoga - - React-Core/RCTActionSheetHeaders (0.63.4): - - Folly (= 2020.01.13.00) + - React-Core/RCTActionSheetHeaders (0.64.2): - glog + - RCT-Folly (= 2020.01.13.00) - React-Core/Default - - React-cxxreact (= 0.63.4) - - React-jsi (= 0.63.4) - - React-jsiexecutor (= 0.63.4) + - React-cxxreact (= 0.64.2) + - React-jsi (= 0.64.2) + - React-jsiexecutor (= 0.64.2) + - React-perflogger (= 0.64.2) - Yoga - - React-Core/RCTAnimationHeaders (0.63.4): - - Folly (= 2020.01.13.00) + - React-Core/RCTAnimationHeaders (0.64.2): - glog + - RCT-Folly (= 2020.01.13.00) - React-Core/Default - - React-cxxreact (= 0.63.4) - - React-jsi (= 0.63.4) - - React-jsiexecutor (= 0.63.4) + - React-cxxreact (= 0.64.2) + - React-jsi (= 0.64.2) + - React-jsiexecutor (= 0.64.2) + - React-perflogger (= 0.64.2) - Yoga - - React-Core/RCTBlobHeaders (0.63.4): - - Folly (= 2020.01.13.00) + - React-Core/RCTBlobHeaders (0.64.2): - glog + - RCT-Folly (= 2020.01.13.00) - React-Core/Default - - React-cxxreact (= 0.63.4) - - React-jsi (= 0.63.4) - - React-jsiexecutor (= 0.63.4) + - React-cxxreact (= 0.64.2) + - React-jsi (= 0.64.2) + - React-jsiexecutor (= 0.64.2) + - React-perflogger (= 0.64.2) - Yoga - - React-Core/RCTImageHeaders (0.63.4): - - Folly (= 2020.01.13.00) + - React-Core/RCTImageHeaders (0.64.2): - glog + - RCT-Folly (= 2020.01.13.00) - React-Core/Default - - React-cxxreact (= 0.63.4) - - React-jsi (= 0.63.4) - - React-jsiexecutor (= 0.63.4) + - React-cxxreact (= 0.64.2) + - React-jsi (= 0.64.2) + - React-jsiexecutor (= 0.64.2) + - React-perflogger (= 0.64.2) - Yoga - - React-Core/RCTLinkingHeaders (0.63.4): - - Folly (= 2020.01.13.00) + - React-Core/RCTLinkingHeaders (0.64.2): - glog + - RCT-Folly (= 2020.01.13.00) - React-Core/Default - - React-cxxreact (= 0.63.4) - - React-jsi (= 0.63.4) - - React-jsiexecutor (= 0.63.4) + - React-cxxreact (= 0.64.2) + - React-jsi (= 0.64.2) + - React-jsiexecutor (= 0.64.2) + - React-perflogger (= 0.64.2) - Yoga - - React-Core/RCTNetworkHeaders (0.63.4): - - Folly (= 2020.01.13.00) + - React-Core/RCTNetworkHeaders (0.64.2): - glog + - RCT-Folly (= 2020.01.13.00) - React-Core/Default - - React-cxxreact (= 0.63.4) - - React-jsi (= 0.63.4) - - React-jsiexecutor (= 0.63.4) + - React-cxxreact (= 0.64.2) + - React-jsi (= 0.64.2) + - React-jsiexecutor (= 0.64.2) + - React-perflogger (= 0.64.2) - Yoga - - React-Core/RCTSettingsHeaders (0.63.4): - - Folly (= 2020.01.13.00) + - React-Core/RCTSettingsHeaders (0.64.2): - glog + - RCT-Folly (= 2020.01.13.00) - React-Core/Default - - React-cxxreact (= 0.63.4) - - React-jsi (= 0.63.4) - - React-jsiexecutor (= 0.63.4) + - React-cxxreact (= 0.64.2) + - React-jsi (= 0.64.2) + - React-jsiexecutor (= 0.64.2) + - React-perflogger (= 0.64.2) - Yoga - - React-Core/RCTTextHeaders (0.63.4): - - Folly (= 2020.01.13.00) + - React-Core/RCTTextHeaders (0.64.2): - glog + - RCT-Folly (= 2020.01.13.00) - React-Core/Default - - React-cxxreact (= 0.63.4) - - React-jsi (= 0.63.4) - - React-jsiexecutor (= 0.63.4) + - React-cxxreact (= 0.64.2) + - React-jsi (= 0.64.2) + - React-jsiexecutor (= 0.64.2) + - React-perflogger (= 0.64.2) - Yoga - - React-Core/RCTVibrationHeaders (0.63.4): - - Folly (= 2020.01.13.00) + - React-Core/RCTVibrationHeaders (0.64.2): - glog + - RCT-Folly (= 2020.01.13.00) - React-Core/Default - - React-cxxreact (= 0.63.4) - - React-jsi (= 0.63.4) - - React-jsiexecutor (= 0.63.4) + - React-cxxreact (= 0.64.2) + - React-jsi (= 0.64.2) + - React-jsiexecutor (= 0.64.2) + - React-perflogger (= 0.64.2) - Yoga - - React-Core/RCTWebSocket (0.63.4): - - Folly (= 2020.01.13.00) + - React-Core/RCTWebSocket (0.64.2): - glog - - React-Core/Default (= 0.63.4) - - React-cxxreact (= 0.63.4) - - React-jsi (= 0.63.4) - - React-jsiexecutor (= 0.63.4) + - RCT-Folly (= 2020.01.13.00) + - React-Core/Default (= 0.64.2) + - React-cxxreact (= 0.64.2) + - React-jsi (= 0.64.2) + - React-jsiexecutor (= 0.64.2) + - React-perflogger (= 0.64.2) - Yoga - - React-CoreModules (0.63.4): - - FBReactNativeSpec (= 0.63.4) - - Folly (= 2020.01.13.00) - - RCTTypeSafety (= 0.63.4) - - React-Core/CoreModulesHeaders (= 0.63.4) - - React-jsi (= 0.63.4) - - React-RCTImage (= 0.63.4) - - ReactCommon/turbomodule/core (= 0.63.4) - - React-cxxreact (0.63.4): + - React-CoreModules (0.64.2): + - FBReactNativeSpec (= 0.64.2) + - RCT-Folly (= 2020.01.13.00) + - RCTTypeSafety (= 0.64.2) + - React-Core/CoreModulesHeaders (= 0.64.2) + - React-jsi (= 0.64.2) + - React-RCTImage (= 0.64.2) + - ReactCommon/turbomodule/core (= 0.64.2) + - React-cxxreact (0.64.2): - boost-for-react-native (= 1.63.0) - DoubleConversion - - Folly (= 2020.01.13.00) - glog - - React-callinvoker (= 0.63.4) - - React-jsinspector (= 0.63.4) - - React-jsi (0.63.4): + - RCT-Folly (= 2020.01.13.00) + - React-callinvoker (= 0.64.2) + - React-jsi (= 0.64.2) + - React-jsinspector (= 0.64.2) + - React-perflogger (= 0.64.2) + - React-runtimeexecutor (= 0.64.2) + - React-jsi (0.64.2): - boost-for-react-native (= 1.63.0) - DoubleConversion - - Folly (= 2020.01.13.00) - glog - - React-jsi/Default (= 0.63.4) - - React-jsi/Default (0.63.4): + - RCT-Folly (= 2020.01.13.00) + - React-jsi/Default (= 0.64.2) + - React-jsi/Default (0.64.2): - boost-for-react-native (= 1.63.0) - DoubleConversion - - Folly (= 2020.01.13.00) - glog - - React-jsiexecutor (0.63.4): + - RCT-Folly (= 2020.01.13.00) + - React-jsiexecutor (0.64.2): - DoubleConversion - - Folly (= 2020.01.13.00) - glog - - React-cxxreact (= 0.63.4) - - React-jsi (= 0.63.4) - - React-jsinspector (0.63.4) - - React-RCTActionSheet (0.63.4): - - React-Core/RCTActionSheetHeaders (= 0.63.4) - - React-RCTAnimation (0.63.4): - - FBReactNativeSpec (= 0.63.4) - - Folly (= 2020.01.13.00) - - RCTTypeSafety (= 0.63.4) - - React-Core/RCTAnimationHeaders (= 0.63.4) - - React-jsi (= 0.63.4) - - ReactCommon/turbomodule/core (= 0.63.4) - - React-RCTBlob (0.63.4): - - FBReactNativeSpec (= 0.63.4) - - Folly (= 2020.01.13.00) - - React-Core/RCTBlobHeaders (= 0.63.4) - - React-Core/RCTWebSocket (= 0.63.4) - - React-jsi (= 0.63.4) - - React-RCTNetwork (= 0.63.4) - - ReactCommon/turbomodule/core (= 0.63.4) - - React-RCTImage (0.63.4): - - FBReactNativeSpec (= 0.63.4) - - Folly (= 2020.01.13.00) - - RCTTypeSafety (= 0.63.4) - - React-Core/RCTImageHeaders (= 0.63.4) - - React-jsi (= 0.63.4) - - React-RCTNetwork (= 0.63.4) - - ReactCommon/turbomodule/core (= 0.63.4) - - React-RCTLinking (0.63.4): - - FBReactNativeSpec (= 0.63.4) - - React-Core/RCTLinkingHeaders (= 0.63.4) - - React-jsi (= 0.63.4) - - ReactCommon/turbomodule/core (= 0.63.4) - - React-RCTNetwork (0.63.4): - - FBReactNativeSpec (= 0.63.4) - - Folly (= 2020.01.13.00) - - RCTTypeSafety (= 0.63.4) - - React-Core/RCTNetworkHeaders (= 0.63.4) - - React-jsi (= 0.63.4) - - ReactCommon/turbomodule/core (= 0.63.4) - - React-RCTSettings (0.63.4): - - FBReactNativeSpec (= 0.63.4) - - Folly (= 2020.01.13.00) - - RCTTypeSafety (= 0.63.4) - - React-Core/RCTSettingsHeaders (= 0.63.4) - - React-jsi (= 0.63.4) - - ReactCommon/turbomodule/core (= 0.63.4) - - React-RCTText (0.63.4): - - React-Core/RCTTextHeaders (= 0.63.4) - - React-RCTVibration (0.63.4): - - FBReactNativeSpec (= 0.63.4) - - Folly (= 2020.01.13.00) - - React-Core/RCTVibrationHeaders (= 0.63.4) - - React-jsi (= 0.63.4) - - ReactCommon/turbomodule/core (= 0.63.4) - - ReactCommon/turbomodule/core (0.63.4): + - RCT-Folly (= 2020.01.13.00) + - React-cxxreact (= 0.64.2) + - React-jsi (= 0.64.2) + - React-perflogger (= 0.64.2) + - React-jsinspector (0.64.2) + - React-perflogger (0.64.2) + - React-RCTActionSheet (0.64.2): + - React-Core/RCTActionSheetHeaders (= 0.64.2) + - React-RCTAnimation (0.64.2): + - FBReactNativeSpec (= 0.64.2) + - RCT-Folly (= 2020.01.13.00) + - RCTTypeSafety (= 0.64.2) + - React-Core/RCTAnimationHeaders (= 0.64.2) + - React-jsi (= 0.64.2) + - ReactCommon/turbomodule/core (= 0.64.2) + - React-RCTBlob (0.64.2): + - FBReactNativeSpec (= 0.64.2) + - RCT-Folly (= 2020.01.13.00) + - React-Core/RCTBlobHeaders (= 0.64.2) + - React-Core/RCTWebSocket (= 0.64.2) + - React-jsi (= 0.64.2) + - React-RCTNetwork (= 0.64.2) + - ReactCommon/turbomodule/core (= 0.64.2) + - React-RCTImage (0.64.2): + - FBReactNativeSpec (= 0.64.2) + - RCT-Folly (= 2020.01.13.00) + - RCTTypeSafety (= 0.64.2) + - React-Core/RCTImageHeaders (= 0.64.2) + - React-jsi (= 0.64.2) + - React-RCTNetwork (= 0.64.2) + - ReactCommon/turbomodule/core (= 0.64.2) + - React-RCTLinking (0.64.2): + - FBReactNativeSpec (= 0.64.2) + - React-Core/RCTLinkingHeaders (= 0.64.2) + - React-jsi (= 0.64.2) + - ReactCommon/turbomodule/core (= 0.64.2) + - React-RCTNetwork (0.64.2): + - FBReactNativeSpec (= 0.64.2) + - RCT-Folly (= 2020.01.13.00) + - RCTTypeSafety (= 0.64.2) + - React-Core/RCTNetworkHeaders (= 0.64.2) + - React-jsi (= 0.64.2) + - ReactCommon/turbomodule/core (= 0.64.2) + - React-RCTSettings (0.64.2): + - FBReactNativeSpec (= 0.64.2) + - RCT-Folly (= 2020.01.13.00) + - RCTTypeSafety (= 0.64.2) + - React-Core/RCTSettingsHeaders (= 0.64.2) + - React-jsi (= 0.64.2) + - ReactCommon/turbomodule/core (= 0.64.2) + - React-RCTText (0.64.2): + - React-Core/RCTTextHeaders (= 0.64.2) + - React-RCTVibration (0.64.2): + - FBReactNativeSpec (= 0.64.2) + - RCT-Folly (= 2020.01.13.00) + - React-Core/RCTVibrationHeaders (= 0.64.2) + - React-jsi (= 0.64.2) + - ReactCommon/turbomodule/core (= 0.64.2) + - React-runtimeexecutor (0.64.2): + - React-jsi (= 0.64.2) + - ReactCommon/turbomodule/core (0.64.2): - DoubleConversion - - Folly (= 2020.01.13.00) - glog - - React-callinvoker (= 0.63.4) - - React-Core (= 0.63.4) - - React-cxxreact (= 0.63.4) - - React-jsi (= 0.63.4) + - RCT-Folly (= 2020.01.13.00) + - React-callinvoker (= 0.64.2) + - React-Core (= 0.64.2) + - React-cxxreact (= 0.64.2) + - React-jsi (= 0.64.2) + - React-perflogger (= 0.64.2) - ReactNativeNavigation (6.12.2): - React - React-RCTImage @@ -259,9 +281,9 @@ PODS: DEPENDENCIES: - DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`) - FBLazyVector (from `../node_modules/react-native/Libraries/FBLazyVector`) - - FBReactNativeSpec (from `../node_modules/react-native/Libraries/FBReactNativeSpec`) - - Folly (from `../node_modules/react-native/third-party-podspecs/Folly.podspec`) + - FBReactNativeSpec (from `../node_modules/react-native/React/FBReactNativeSpec`) - glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`) + - RCT-Folly (from `../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec`) - RCTRequired (from `../node_modules/react-native/Libraries/RCTRequired`) - RCTTypeSafety (from `../node_modules/react-native/Libraries/TypeSafety`) - React (from `../node_modules/react-native/`) @@ -274,6 +296,7 @@ DEPENDENCIES: - React-jsi (from `../node_modules/react-native/ReactCommon/jsi`) - React-jsiexecutor (from `../node_modules/react-native/ReactCommon/jsiexecutor`) - React-jsinspector (from `../node_modules/react-native/ReactCommon/jsinspector`) + - React-perflogger (from `../node_modules/react-native/ReactCommon/reactperflogger`) - React-RCTActionSheet (from `../node_modules/react-native/Libraries/ActionSheetIOS`) - React-RCTAnimation (from `../node_modules/react-native/Libraries/NativeAnimation`) - React-RCTBlob (from `../node_modules/react-native/Libraries/Blob`) @@ -283,6 +306,7 @@ DEPENDENCIES: - React-RCTSettings (from `../node_modules/react-native/Libraries/Settings`) - React-RCTText (from `../node_modules/react-native/Libraries/Text`) - React-RCTVibration (from `../node_modules/react-native/Libraries/Vibration`) + - React-runtimeexecutor (from `../node_modules/react-native/ReactCommon/runtimeexecutor`) - ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`) - ReactNativeNavigation (from `../node_modules/react-native-navigation`) - Yoga (from `../node_modules/react-native/ReactCommon/yoga`) @@ -297,11 +321,11 @@ EXTERNAL SOURCES: FBLazyVector: :path: "../node_modules/react-native/Libraries/FBLazyVector" FBReactNativeSpec: - :path: "../node_modules/react-native/Libraries/FBReactNativeSpec" - Folly: - :podspec: "../node_modules/react-native/third-party-podspecs/Folly.podspec" + :path: "../node_modules/react-native/React/FBReactNativeSpec" glog: :podspec: "../node_modules/react-native/third-party-podspecs/glog.podspec" + RCT-Folly: + :podspec: "../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec" RCTRequired: :path: "../node_modules/react-native/Libraries/RCTRequired" RCTTypeSafety: @@ -322,6 +346,8 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native/ReactCommon/jsiexecutor" React-jsinspector: :path: "../node_modules/react-native/ReactCommon/jsinspector" + React-perflogger: + :path: "../node_modules/react-native/ReactCommon/reactperflogger" React-RCTActionSheet: :path: "../node_modules/react-native/Libraries/ActionSheetIOS" React-RCTAnimation: @@ -340,6 +366,8 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native/Libraries/Text" React-RCTVibration: :path: "../node_modules/react-native/Libraries/Vibration" + React-runtimeexecutor: + :path: "../node_modules/react-native/ReactCommon/runtimeexecutor" ReactCommon: :path: "../node_modules/react-native/ReactCommon" ReactNativeNavigation: @@ -350,32 +378,34 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c DoubleConversion: cde416483dac037923206447da6e1454df403714 - FBLazyVector: 3bb422f41b18121b71783a905c10e58606f7dc3e - FBReactNativeSpec: f2c97f2529dd79c083355182cc158c9f98f4bd6e - Folly: b73c3869541e86821df3c387eb0af5f65addfab4 + FBLazyVector: e686045572151edef46010a6f819ade377dfeb4b + FBReactNativeSpec: 92869e54fbef651850edc0f8ad2e5e53421f5fbe glog: 40a13f7840415b9a77023fbcae0f1e6f43192af3 - RCTRequired: 082f10cd3f905d6c124597fd1c14f6f2655ff65e - RCTTypeSafety: 8c9c544ecbf20337d069e4ae7fd9a377aadf504b - React: b0a957a2c44da4113b0c4c9853d8387f8e64e615 - React-callinvoker: c3f44dd3cb195b6aa46621fff95ded79d59043fe - React-Core: d3b2a1ac9a2c13c3bcde712d9281fc1c8a5b315b - React-CoreModules: 0581ff36cb797da0943d424f69e7098e43e9be60 - React-cxxreact: c1480d4fda5720086c90df537ee7d285d4c57ac3 - React-jsi: a0418934cf48f25b485631deb27c64dc40fb4c31 - React-jsiexecutor: 93bd528844ad21dc07aab1c67cb10abae6df6949 - React-jsinspector: 58aef7155bc9a9683f5b60b35eccea8722a4f53a - React-RCTActionSheet: 89a0ca9f4a06c1f93c26067af074ccdce0f40336 - React-RCTAnimation: 1bde3ecc0c104c55df246eda516e0deb03c4e49b - React-RCTBlob: a97d378b527740cc667e03ebfa183a75231ab0f0 - React-RCTImage: c1b1f2d3f43a4a528c8946d6092384b5c880d2f0 - React-RCTLinking: 35ae4ab9dc0410d1fcbdce4d7623194a27214fb2 - React-RCTNetwork: 29ec2696f8d8cfff7331fac83d3e893c95ef43ae - React-RCTSettings: 60f0691bba2074ef394f95d4c2265ec284e0a46a - React-RCTText: 5c51df3f08cb9dedc6e790161195d12bac06101c - React-RCTVibration: ae4f914cfe8de7d4de95ae1ea6cc8f6315d73d9d - ReactCommon: 73d79c7039f473b76db6ff7c6b159c478acbbb3b + RCT-Folly: ec7a233ccc97cc556cf7237f0db1ff65b986f27c + RCTRequired: 6d3e854f0e7260a648badd0d44fc364bc9da9728 + RCTTypeSafety: c1f31d19349c6b53085766359caac425926fafaa + React: bda6b6d7ae912de97d7a61aa5c160db24aa2ad69 + React-callinvoker: 9840ea7e8e88ed73d438edb725574820b29b5baa + React-Core: b5e385da7ce5f16a220fc60fd0749eae2c6120f0 + React-CoreModules: 17071a4e2c5239b01585f4aa8070141168ab298f + React-cxxreact: 9be7b6340ed9f7c53e53deca7779f07cd66525ba + React-jsi: 67747b9722f6dab2ffe15b011bcf6b3f2c3f1427 + React-jsiexecutor: 80c46bd381fd06e418e0d4f53672dc1d1945c4c3 + React-jsinspector: cc614ec18a9ca96fd275100c16d74d62ee11f0ae + React-perflogger: 25373e382fed75ce768a443822f07098a15ab737 + React-RCTActionSheet: af7796ba49ffe4ca92e7277a5d992d37203f7da5 + React-RCTAnimation: 6a2e76ab50c6f25b428d81b76a5a45351c4d77aa + React-RCTBlob: 02a2887023e0eed99391b6445b2e23a2a6f9226d + React-RCTImage: ce5bf8e7438f2286d9b646a05d6ab11f38b0323d + React-RCTLinking: ccd20742de14e020cb5f99d5c7e0bf0383aefbd9 + React-RCTNetwork: dfb9d089ab0753e5e5f55fc4b1210858f7245647 + React-RCTSettings: b14aef2d83699e48b410fb7c3ba5b66cd3291ae2 + React-RCTText: 41a2e952dd9adc5caf6fb68ed46b275194d5da5f + React-RCTVibration: 24600e3b1aaa77126989bc58b6747509a1ba14f3 + React-runtimeexecutor: a9904c6d0218fb9f8b19d6dd88607225927668f9 + ReactCommon: 149906e01aa51142707a10665185db879898e966 ReactNativeNavigation: aefc8debafb4a374575adafb44a3352b9d5b618a - Yoga: 4bd86afe9883422a7c4028c00e34790f560923d6 + Yoga: 575c581c63e0d35c9a83f4b46d01d63abc1100ac PODFILE CHECKSUM: a49123e8ee98a70297a33fb5ca1c3b1b1b871165 diff --git a/package.json b/package.json index 7d2f300e7e..81be25aab1 100644 --- a/package.json +++ b/package.json @@ -44,9 +44,9 @@ "@types/lodash": "^4.14.170", "@types/react-native": "^0.63.52", "@types/xdate": "^0.8.32", - "@welldone-software/why-did-you-render": "^6.0.3", "@typescript-eslint/eslint-plugin": "^2.13.0", "@typescript-eslint/parser": "^2.13.0", + "@welldone-software/why-did-you-render": "^6.0.3", "babel-eslint": "^10.1.0", "babel-jest": "^26.6.3", "detox": "^18.0.0", @@ -62,9 +62,9 @@ "metro-react-native-babel-preset": "^0.64.0", "mocha": "^7.1.0", "prettier": "^2.0.5", - "react": "16.13.1", + "react": "17.0.1", "react-component-driver": "^0.10.0", - "react-native": "0.63.4", + "react-native": "0.64.2", "react-native-navigation": "^6.7.1", "react-test-renderer": "^17.0.1", "semver": "5.x.x", From d68ef2b0f1d9644ba13cbe90d683136348b0570e Mon Sep 17 00:00:00 2001 From: Inbal Tish Date: Wed, 4 Aug 2021 15:41:36 +0300 Subject: [PATCH 066/109] jest config - adding 'transformIgnorePatterns' --- package.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/package.json b/package.json index 81be25aab1..6180042ceb 100644 --- a/package.json +++ b/package.json @@ -82,6 +82,9 @@ ], "testMatch": [ "/src/**/?(*.)(spec|test).{js,jsx}" + ], + "transformIgnorePatterns": [ + "node_modules/(?!(@react-native|react-native|react-native-swipe-gestures)/)" ] }, "husky": { From 05fb20f665e88e8a121f01e44b5b808b480a70db Mon Sep 17 00:00:00 2001 From: Inbal Tish Date: Wed, 4 Aug 2021 16:18:00 +0300 Subject: [PATCH 067/109] example project files --- example/.gitattributes | 4 +++- example/metro.config.js | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/example/.gitattributes b/example/.gitattributes index d42ff18354..45a3dcb2a2 100644 --- a/example/.gitattributes +++ b/example/.gitattributes @@ -1 +1,3 @@ -*.pbxproj -text +# Windows files should use crlf line endings +# https://help.github.com/articles/dealing-with-line-endings/ +*.bat text eol=crlf diff --git a/example/metro.config.js b/example/metro.config.js index dd4674dc0f..a9718e189f 100644 --- a/example/metro.config.js +++ b/example/metro.config.js @@ -10,7 +10,7 @@ module.exports = { getTransformOptions: async () => ({ transform: { experimentalImportSupport: false, - inlineRequires: false + inlineRequires: true } }) } From 171b4a6ec23a57ff072c4eda7f5cfb098c3771d5 Mon Sep 17 00:00:00 2001 From: Inbal Tish Date: Thu, 5 Aug 2021 10:50:42 +0300 Subject: [PATCH 068/109] updating .xcodeproj/project.pbxproj --- .../project.pbxproj | 66 ------------------- ios/Podfile.lock | 2 +- 2 files changed, 1 insertion(+), 67 deletions(-) diff --git a/ios/CalendarsExample.xcodeproj/project.pbxproj b/ios/CalendarsExample.xcodeproj/project.pbxproj index ef1e4f1c1b..292f015423 100644 --- a/ios/CalendarsExample.xcodeproj/project.pbxproj +++ b/ios/CalendarsExample.xcodeproj/project.pbxproj @@ -28,8 +28,6 @@ 398EEBBF225A4017004C3591 /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 398EEBBE225A4017004C3591 /* JavaScriptCore.framework */; }; 39CBD92125E3A09900E725A0 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 39CBD92025E3A09900E725A0 /* LaunchScreen.storyboard */; }; 487E5AF35184A2C855EE7D1C /* libPods-CalendarsExampleTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 460013679EC6EF672EE84B6E /* libPods-CalendarsExampleTests.a */; }; - F9B5B8B4570FF18032DEFDE0 /* libPods-CalendarsExample-tvOSTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E3C64726F99E7F45CCED79B2 /* libPods-CalendarsExample-tvOSTests.a */; }; - FA2BCE77335351BEE723EFCF /* libPods-CalendarsExample-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2B2B1D7F212F1999E5CE3C3D /* libPods-CalendarsExample-tvOS.a */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -313,7 +311,6 @@ 13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = CalendarsExample/main.m; sourceTree = ""; }; 146833FF1AC3E56700842450 /* React.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = React.xcodeproj; path = "../node_modules/react-native/React/React.xcodeproj"; sourceTree = ""; }; 247F69DB2483A793006A1A73 /* main.jsbundle */ = {isa = PBXFileReference; lastKnownFileType = text; path = main.jsbundle; sourceTree = ""; }; - 2B2B1D7F212F1999E5CE3C3D /* libPods-CalendarsExample-tvOS.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-CalendarsExample-tvOS.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 2D02E47B1E0B4A5D006451C7 /* CalendarsExample-tvOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "CalendarsExample-tvOS.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 2D02E4901E0B4A5D006451C7 /* CalendarsExample-tvOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "CalendarsExample-tvOSTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 3297F784662D20D095BF1AFB /* Pods-CalendarsExample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CalendarsExample.debug.xcconfig"; path = "Target Support Files/Pods-CalendarsExample/Pods-CalendarsExample.debug.xcconfig"; sourceTree = ""; }; @@ -322,16 +319,11 @@ 460013679EC6EF672EE84B6E /* libPods-CalendarsExampleTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-CalendarsExampleTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 46A23C7C177DC438E0CBB3F9 /* Pods-CalendarsExample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CalendarsExample.release.xcconfig"; path = "Target Support Files/Pods-CalendarsExample/Pods-CalendarsExample.release.xcconfig"; sourceTree = ""; }; 47F7CE6DB1E4FBB453CC30D5 /* libPods-CalendarsExample.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-CalendarsExample.a"; sourceTree = BUILT_PRODUCTS_DIR; }; - 4D983A3CE8EEF4AF708B8019 /* Pods-CalendarsExample-tvOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CalendarsExample-tvOS.release.xcconfig"; path = "Target Support Files/Pods-CalendarsExample-tvOS/Pods-CalendarsExample-tvOS.release.xcconfig"; sourceTree = ""; }; 5E91572D1DD0AC6500FF2AA8 /* RCTAnimation.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTAnimation.xcodeproj; path = "../node_modules/react-native/Libraries/NativeAnimation/RCTAnimation.xcodeproj"; sourceTree = ""; }; 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTLinking.xcodeproj; path = "../node_modules/react-native/Libraries/LinkingIOS/RCTLinking.xcodeproj"; sourceTree = ""; }; 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = "../node_modules/react-native/Libraries/Text/RCTText.xcodeproj"; sourceTree = ""; }; - 982391FF9FB86857A628840C /* Pods-CalendarsExample-tvOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CalendarsExample-tvOS.debug.xcconfig"; path = "Target Support Files/Pods-CalendarsExample-tvOS/Pods-CalendarsExample-tvOS.debug.xcconfig"; sourceTree = ""; }; AC897BA667FD0C3E9D8F0D63 /* Pods-CalendarsExampleTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CalendarsExampleTests.debug.xcconfig"; path = "Target Support Files/Pods-CalendarsExampleTests/Pods-CalendarsExampleTests.debug.xcconfig"; sourceTree = ""; }; - E3C64726F99E7F45CCED79B2 /* libPods-CalendarsExample-tvOSTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-CalendarsExample-tvOSTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; EF4683684367395045561C12 /* Pods-CalendarsExampleTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CalendarsExampleTests.release.xcconfig"; path = "Target Support Files/Pods-CalendarsExampleTests/Pods-CalendarsExampleTests.release.xcconfig"; sourceTree = ""; }; - EF58906124F2602DF92D1079 /* Pods-CalendarsExample-tvOSTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CalendarsExample-tvOSTests.release.xcconfig"; path = "Target Support Files/Pods-CalendarsExample-tvOSTests/Pods-CalendarsExample-tvOSTests.release.xcconfig"; sourceTree = ""; }; - F437D091B67B0F0E9A569F4B /* Pods-CalendarsExample-tvOSTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CalendarsExample-tvOSTests.debug.xcconfig"; path = "Target Support Files/Pods-CalendarsExample-tvOSTests/Pods-CalendarsExample-tvOSTests.debug.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -364,7 +356,6 @@ 2D02E4C61E0B4AEC006451C7 /* libRCTSettings-tvOS.a in Frameworks */, 2D02E4C71E0B4AEC006451C7 /* libRCTText-tvOS.a in Frameworks */, 2D02E4C81E0B4AEC006451C7 /* libRCTWebSocket-tvOS.a in Frameworks */, - FA2BCE77335351BEE723EFCF /* libPods-CalendarsExample-tvOS.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -372,7 +363,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - F9B5B8B4570FF18032DEFDE0 /* libPods-CalendarsExample-tvOSTests.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -500,8 +490,6 @@ children = ( 398EEBBE225A4017004C3591 /* JavaScriptCore.framework */, 47F7CE6DB1E4FBB453CC30D5 /* libPods-CalendarsExample.a */, - 2B2B1D7F212F1999E5CE3C3D /* libPods-CalendarsExample-tvOS.a */, - E3C64726F99E7F45CCED79B2 /* libPods-CalendarsExample-tvOSTests.a */, 460013679EC6EF672EE84B6E /* libPods-CalendarsExampleTests.a */, ); name = Frameworks; @@ -582,10 +570,6 @@ children = ( 3297F784662D20D095BF1AFB /* Pods-CalendarsExample.debug.xcconfig */, 46A23C7C177DC438E0CBB3F9 /* Pods-CalendarsExample.release.xcconfig */, - 982391FF9FB86857A628840C /* Pods-CalendarsExample-tvOS.debug.xcconfig */, - 4D983A3CE8EEF4AF708B8019 /* Pods-CalendarsExample-tvOS.release.xcconfig */, - F437D091B67B0F0E9A569F4B /* Pods-CalendarsExample-tvOSTests.debug.xcconfig */, - EF58906124F2602DF92D1079 /* Pods-CalendarsExample-tvOSTests.release.xcconfig */, AC897BA667FD0C3E9D8F0D63 /* Pods-CalendarsExampleTests.debug.xcconfig */, EF4683684367395045561C12 /* Pods-CalendarsExampleTests.release.xcconfig */, ); @@ -638,7 +622,6 @@ isa = PBXNativeTarget; buildConfigurationList = 2D02E4BA1E0B4A5E006451C7 /* Build configuration list for PBXNativeTarget "CalendarsExample-tvOS" */; buildPhases = ( - C00BF4655178EC17F49C1C9E /* [CP] Check Pods Manifest.lock */, 2D02E4771E0B4A5D006451C7 /* Sources */, 2D02E4781E0B4A5D006451C7 /* Frameworks */, 2D02E4791E0B4A5D006451C7 /* Resources */, @@ -657,7 +640,6 @@ isa = PBXNativeTarget; buildConfigurationList = 2D02E4BB1E0B4A5E006451C7 /* Build configuration list for PBXNativeTarget "CalendarsExample-tvOSTests" */; buildPhases = ( - FD50AB272A3660DC7105C10F /* [CP] Check Pods Manifest.lock */, 2D02E48C1E0B4A5D006451C7 /* Sources */, 2D02E48D1E0B4A5D006451C7 /* Frameworks */, 2D02E48E1E0B4A5D006451C7 /* Resources */, @@ -1142,50 +1124,6 @@ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - C00BF4655178EC17F49C1C9E /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-CalendarsExample-tvOS-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; - FD50AB272A3660DC7105C10F /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-CalendarsExample-tvOSTests-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -1316,7 +1254,6 @@ }; 2D02E4971E0B4A5E006451C7 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 982391FF9FB86857A628840C /* Pods-CalendarsExample-tvOS.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image"; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; @@ -1340,7 +1277,6 @@ }; 2D02E4981E0B4A5E006451C7 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 4D983A3CE8EEF4AF708B8019 /* Pods-CalendarsExample-tvOS.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image"; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; @@ -1364,7 +1300,6 @@ }; 2D02E4991E0B4A5E006451C7 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = F437D091B67B0F0E9A569F4B /* Pods-CalendarsExample-tvOSTests.debug.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CLANG_ANALYZER_NONNULL = YES; @@ -1386,7 +1321,6 @@ }; 2D02E49A1E0B4A5E006451C7 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = EF58906124F2602DF92D1079 /* Pods-CalendarsExample-tvOSTests.release.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CLANG_ANALYZER_NONNULL = YES; diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 8947ebb7d9..9af25240bd 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -407,6 +407,6 @@ SPEC CHECKSUMS: ReactNativeNavigation: aefc8debafb4a374575adafb44a3352b9d5b618a Yoga: 575c581c63e0d35c9a83f4b46d01d63abc1100ac -PODFILE CHECKSUM: a49123e8ee98a70297a33fb5ca1c3b1b1b871165 +PODFILE CHECKSUM: d441a6b04db6a2cce6e0186dd6232f7e6ba9e257 COCOAPODS: 1.10.1 From 5e6a8dda18c2cb1ac6b572ccbe7f96f610a35330 Mon Sep 17 00:00:00 2001 From: Inbal Tish Date: Thu, 5 Aug 2021 13:24:06 +0300 Subject: [PATCH 069/109] RNN upgrade; ios configs --- ios/CalendarsExample.xcodeproj/project.pbxproj | 1 + ios/CalendarsExample/AppDelegate.m | 5 ++--- ios/Podfile | 10 +++++++++- ios/Podfile.lock | 18 +++++++++--------- package.json | 2 +- 5 files changed, 22 insertions(+), 14 deletions(-) diff --git a/ios/CalendarsExample.xcodeproj/project.pbxproj b/ios/CalendarsExample.xcodeproj/project.pbxproj index 292f015423..e5111dad12 100644 --- a/ios/CalendarsExample.xcodeproj/project.pbxproj +++ b/ios/CalendarsExample.xcodeproj/project.pbxproj @@ -1436,6 +1436,7 @@ GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 9.0; MTL_ENABLE_DEBUG_INFO = NO; + ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; VALIDATE_PRODUCT = YES; }; diff --git a/ios/CalendarsExample/AppDelegate.m b/ios/CalendarsExample/AppDelegate.m index 723855e102..f390d53972 100644 --- a/ios/CalendarsExample/AppDelegate.m +++ b/ios/CalendarsExample/AppDelegate.m @@ -8,9 +8,8 @@ @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { - NSURL *jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil]; - [ReactNativeNavigation bootstrap:jsCodeLocation launchOptions:launchOptions]; - + [ReactNativeNavigation bootstrapWithDelegate:self launchOptions:launchOptions]; + // NSURL *jsCodeLocation; //#ifdef DEBUG diff --git a/ios/Podfile b/ios/Podfile index dd26543a26..20ab797e67 100644 --- a/ios/Podfile +++ b/ios/Podfile @@ -1,7 +1,7 @@ require_relative '../node_modules/react-native/scripts/react_native_pods' require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules' -platform :ios, '10.0' +platform :ios, '11.0' target 'CalendarsExample' do config = use_native_modules! @@ -17,3 +17,11 @@ target 'CalendarsExample' do # Pods for testing end end + +post_install do |installer| + installer.pods_project.targets.each do |target| + target.build_configurations.each do |config| + config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '11.0' + end + end + end diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 9af25240bd..0a17f53b84 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -267,13 +267,13 @@ PODS: - React-cxxreact (= 0.64.2) - React-jsi (= 0.64.2) - React-perflogger (= 0.64.2) - - ReactNativeNavigation (6.12.2): - - React + - ReactNativeNavigation (7.6.0): + - React-Core - React-RCTImage - React-RCTText - - ReactNativeNavigation/Core (= 6.12.2) - - ReactNativeNavigation/Core (6.12.2): - - React + - ReactNativeNavigation/Core (= 7.6.0) + - ReactNativeNavigation/Core (7.6.0): + - React-Core - React-RCTImage - React-RCTText - Yoga (1.14.0) @@ -377,10 +377,10 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c - DoubleConversion: cde416483dac037923206447da6e1454df403714 + DoubleConversion: cf9b38bf0b2d048436d9a82ad2abe1404f11e7de FBLazyVector: e686045572151edef46010a6f819ade377dfeb4b FBReactNativeSpec: 92869e54fbef651850edc0f8ad2e5e53421f5fbe - glog: 40a13f7840415b9a77023fbcae0f1e6f43192af3 + glog: 73c2498ac6884b13ede40eda8228cb1eee9d9d62 RCT-Folly: ec7a233ccc97cc556cf7237f0db1ff65b986f27c RCTRequired: 6d3e854f0e7260a648badd0d44fc364bc9da9728 RCTTypeSafety: c1f31d19349c6b53085766359caac425926fafaa @@ -404,9 +404,9 @@ SPEC CHECKSUMS: React-RCTVibration: 24600e3b1aaa77126989bc58b6747509a1ba14f3 React-runtimeexecutor: a9904c6d0218fb9f8b19d6dd88607225927668f9 ReactCommon: 149906e01aa51142707a10665185db879898e966 - ReactNativeNavigation: aefc8debafb4a374575adafb44a3352b9d5b618a + ReactNativeNavigation: 91c082139a6ee8ef7d5c04c70995fdd2e8ababc9 Yoga: 575c581c63e0d35c9a83f4b46d01d63abc1100ac -PODFILE CHECKSUM: d441a6b04db6a2cce6e0186dd6232f7e6ba9e257 +PODFILE CHECKSUM: 18eda97847d2efc053b18d81cc7f0abd0f57db97 COCOAPODS: 1.10.1 diff --git a/package.json b/package.json index 6180042ceb..9f2ca8d3c8 100644 --- a/package.json +++ b/package.json @@ -65,7 +65,7 @@ "react": "17.0.1", "react-component-driver": "^0.10.0", "react-native": "0.64.2", - "react-native-navigation": "^6.7.1", + "react-native-navigation": "7.6.0", "react-test-renderer": "^17.0.1", "semver": "5.x.x", "shell-utils": "1.x.x", From b91682135acc9b6e9e9aff8492365c3fd9b0fa67 Mon Sep 17 00:00:00 2001 From: Inbal Tish Date: Thu, 5 Aug 2021 13:28:12 +0300 Subject: [PATCH 070/109] Revert "RNN upgrade; ios configs" This reverts commit 5e6a8dda18c2cb1ac6b572ccbe7f96f610a35330. --- ios/CalendarsExample.xcodeproj/project.pbxproj | 1 - ios/CalendarsExample/AppDelegate.m | 5 +++-- ios/Podfile | 10 +--------- ios/Podfile.lock | 18 +++++++++--------- package.json | 2 +- 5 files changed, 14 insertions(+), 22 deletions(-) diff --git a/ios/CalendarsExample.xcodeproj/project.pbxproj b/ios/CalendarsExample.xcodeproj/project.pbxproj index e5111dad12..292f015423 100644 --- a/ios/CalendarsExample.xcodeproj/project.pbxproj +++ b/ios/CalendarsExample.xcodeproj/project.pbxproj @@ -1436,7 +1436,6 @@ GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 9.0; MTL_ENABLE_DEBUG_INFO = NO; - ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; VALIDATE_PRODUCT = YES; }; diff --git a/ios/CalendarsExample/AppDelegate.m b/ios/CalendarsExample/AppDelegate.m index f390d53972..723855e102 100644 --- a/ios/CalendarsExample/AppDelegate.m +++ b/ios/CalendarsExample/AppDelegate.m @@ -8,8 +8,9 @@ @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { - [ReactNativeNavigation bootstrapWithDelegate:self launchOptions:launchOptions]; - + NSURL *jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil]; + [ReactNativeNavigation bootstrap:jsCodeLocation launchOptions:launchOptions]; + // NSURL *jsCodeLocation; //#ifdef DEBUG diff --git a/ios/Podfile b/ios/Podfile index 20ab797e67..dd26543a26 100644 --- a/ios/Podfile +++ b/ios/Podfile @@ -1,7 +1,7 @@ require_relative '../node_modules/react-native/scripts/react_native_pods' require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules' -platform :ios, '11.0' +platform :ios, '10.0' target 'CalendarsExample' do config = use_native_modules! @@ -17,11 +17,3 @@ target 'CalendarsExample' do # Pods for testing end end - -post_install do |installer| - installer.pods_project.targets.each do |target| - target.build_configurations.each do |config| - config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '11.0' - end - end - end diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 0a17f53b84..9af25240bd 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -267,13 +267,13 @@ PODS: - React-cxxreact (= 0.64.2) - React-jsi (= 0.64.2) - React-perflogger (= 0.64.2) - - ReactNativeNavigation (7.6.0): - - React-Core + - ReactNativeNavigation (6.12.2): + - React - React-RCTImage - React-RCTText - - ReactNativeNavigation/Core (= 7.6.0) - - ReactNativeNavigation/Core (7.6.0): - - React-Core + - ReactNativeNavigation/Core (= 6.12.2) + - ReactNativeNavigation/Core (6.12.2): + - React - React-RCTImage - React-RCTText - Yoga (1.14.0) @@ -377,10 +377,10 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c - DoubleConversion: cf9b38bf0b2d048436d9a82ad2abe1404f11e7de + DoubleConversion: cde416483dac037923206447da6e1454df403714 FBLazyVector: e686045572151edef46010a6f819ade377dfeb4b FBReactNativeSpec: 92869e54fbef651850edc0f8ad2e5e53421f5fbe - glog: 73c2498ac6884b13ede40eda8228cb1eee9d9d62 + glog: 40a13f7840415b9a77023fbcae0f1e6f43192af3 RCT-Folly: ec7a233ccc97cc556cf7237f0db1ff65b986f27c RCTRequired: 6d3e854f0e7260a648badd0d44fc364bc9da9728 RCTTypeSafety: c1f31d19349c6b53085766359caac425926fafaa @@ -404,9 +404,9 @@ SPEC CHECKSUMS: React-RCTVibration: 24600e3b1aaa77126989bc58b6747509a1ba14f3 React-runtimeexecutor: a9904c6d0218fb9f8b19d6dd88607225927668f9 ReactCommon: 149906e01aa51142707a10665185db879898e966 - ReactNativeNavigation: 91c082139a6ee8ef7d5c04c70995fdd2e8ababc9 + ReactNativeNavigation: aefc8debafb4a374575adafb44a3352b9d5b618a Yoga: 575c581c63e0d35c9a83f4b46d01d63abc1100ac -PODFILE CHECKSUM: 18eda97847d2efc053b18d81cc7f0abd0f57db97 +PODFILE CHECKSUM: d441a6b04db6a2cce6e0186dd6232f7e6ba9e257 COCOAPODS: 1.10.1 diff --git a/package.json b/package.json index 9f2ca8d3c8..6180042ceb 100644 --- a/package.json +++ b/package.json @@ -65,7 +65,7 @@ "react": "17.0.1", "react-component-driver": "^0.10.0", "react-native": "0.64.2", - "react-native-navigation": "7.6.0", + "react-native-navigation": "^6.7.1", "react-test-renderer": "^17.0.1", "semver": "5.x.x", "shell-utils": "1.x.x", From 1f98fd38937bc48f4bbeac2a1668c24d6d8ceb13 Mon Sep 17 00:00:00 2001 From: Inbal Tish Date: Sun, 8 Aug 2021 10:46:45 +0300 Subject: [PATCH 071/109] Adding postinstall.js to scripts - fix detox ios build on CI --- package.json | 3 +- scripts/postinstall.js | 79 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 scripts/postinstall.js diff --git a/package.json b/package.json index 6180042ceb..c593932e9d 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,8 @@ "android": "react-native run-android", "xcode": "open ios/CalendarsExample.xcworkspace/", "clean": "rm package-lock.json && rm -rf ./node_modules && npm i", - "pod-install": "pod install --project-directory=ios" + "pod-install": "pod install --project-directory=ios", + "postinstall": "node ./scripts/postinstall.js" }, "repository": { "type": "git", diff --git a/scripts/postinstall.js b/scripts/postinstall.js new file mode 100644 index 0000000000..2dfb792257 --- /dev/null +++ b/scripts/postinstall.js @@ -0,0 +1,79 @@ +const fs = require('fs-extra'); +const path = require('path'); +const semver = require('semver'); + +const rnVersion = function() { + const rnPackageJson = require('react-native/package.json'); + return rnPackageJson.version; +}(); + +function patchHermesLocationForRN60Android() { + const HERMES_PATH_ROOT = path.join('node_modules', 'hermesvm'); + const HERMES_PATH_RN = path.join('node_modules', 'react-native', 'node_modules', 'hermesvm'); + + const hermesIsInRoot = fs.existsSync(HERMES_PATH_ROOT); + const hermesIsInRN = fs.existsSync(HERMES_PATH_RN); + + if (hermesIsInRoot && !hermesIsInRN) { + console.log(' Applying hermes-vm patch for RN .60...'); + fs.ensureDirSync(path.join(HERMES_PATH_RN, 'android')); + fs.copySync(path.join(HERMES_PATH_ROOT, 'android'), path.join(HERMES_PATH_RN, 'android')); + } else { + console.log(' Skipping hermes-vm patching (not needed):', hermesIsInRoot, hermesIsInRN); + } +} + +/** + * In RN .64, it seems that react-native-codegen - a proprietary code generation plugin, whose + * native code is only available inside react-native's monorepo, has been applied. + * This patch disables it, and that works - as long as RN is used as an .aar dep and + * not built from source. I can't account for the latter; It is likely that with .64 it may not + * be possible to do anymore. If ever needed, one approach to try out is to somehow build the + * plugin ourselves through the react-native monorepo itself (onto a .jar), and then add it as a + * direct plugin dependency into our settings.gradle (https://docs.gradle.org/current/userguide/plugins.html#sec:custom_plugin_repositories). + */ +function overrideReactAndroidGradleForRn64Android() { + const REACT_ANDROID_PATH = path.join('node_modules', 'react-native', 'ReactAndroid'); + const REACT_ANDROID_GRADLE_SCRIPT_PATH = path.join(REACT_ANDROID_PATH, 'build.gradle'); + const REACT_ANDROID_GRADLE_BAK_SCRIPT_PATH = path.join(REACT_ANDROID_PATH, 'build.gradle.bak'); + const PATCH_SCRIPT_PATH = path.join('scripts', 'ReactAndroid_rn64_build.gradle'); + + console.log(' Overriding ReactAndroid\'s build.gradle...'); + try { + fs.renameSync(REACT_ANDROID_GRADLE_SCRIPT_PATH, REACT_ANDROID_GRADLE_BAK_SCRIPT_PATH); + } catch (e) { + console.warn(' Couldn\'t create a backup to original script (skipping)', e); + } + fs.copySync(PATCH_SCRIPT_PATH, REACT_ANDROID_GRADLE_SCRIPT_PATH); +} + +function cleanFindNodeScriptFileForRn64IOS() { + const REACT_SCRIPTS_PATH = path.join('node_modules', 'react-native', 'scripts'); + const REACT_FIND_NODE_SCRIPT_PATH = path.join(REACT_SCRIPTS_PATH, 'find-node.sh'); + + console.log(' Clean content of find-node.sh file..'); + try { + fs.writeFileSync(REACT_FIND_NODE_SCRIPT_PATH, ''); + } catch (e) { + console.warn(' Couldn\'t clean content find-node.sh file', e); + } +} + +function run() { + console.log('Running Detox test-app post-install script...'); + + if (semver.minor(rnVersion) === 60) { + console.log(' Detected RN version .60! Applying necessary patches...'); + patchHermesLocationForRN60Android(); + } + + if (semver.minor(rnVersion) === 64) { + console.log(' Detected RN version .64! Applying necessary patches...'); + overrideReactAndroidGradleForRn64Android(); + cleanFindNodeScriptFileForRn64IOS(); + } + + console.log('Detox test-app post-install script completed!'); +} + +run(); \ No newline at end of file From ad2937db226b581b380c306fd4c539da9a55d2da Mon Sep 17 00:00:00 2001 From: Inbal Tish Date: Sun, 8 Aug 2021 11:02:47 +0300 Subject: [PATCH 072/109] fix postinstall script --- scripts/postinstall.js | 56 +++--------------------------------------- 1 file changed, 4 insertions(+), 52 deletions(-) diff --git a/scripts/postinstall.js b/scripts/postinstall.js index 2dfb792257..b411fc1e27 100644 --- a/scripts/postinstall.js +++ b/scripts/postinstall.js @@ -7,73 +7,25 @@ const rnVersion = function() { return rnPackageJson.version; }(); -function patchHermesLocationForRN60Android() { - const HERMES_PATH_ROOT = path.join('node_modules', 'hermesvm'); - const HERMES_PATH_RN = path.join('node_modules', 'react-native', 'node_modules', 'hermesvm'); - - const hermesIsInRoot = fs.existsSync(HERMES_PATH_ROOT); - const hermesIsInRN = fs.existsSync(HERMES_PATH_RN); - - if (hermesIsInRoot && !hermesIsInRN) { - console.log(' Applying hermes-vm patch for RN .60...'); - fs.ensureDirSync(path.join(HERMES_PATH_RN, 'android')); - fs.copySync(path.join(HERMES_PATH_ROOT, 'android'), path.join(HERMES_PATH_RN, 'android')); - } else { - console.log(' Skipping hermes-vm patching (not needed):', hermesIsInRoot, hermesIsInRN); - } -} - -/** - * In RN .64, it seems that react-native-codegen - a proprietary code generation plugin, whose - * native code is only available inside react-native's monorepo, has been applied. - * This patch disables it, and that works - as long as RN is used as an .aar dep and - * not built from source. I can't account for the latter; It is likely that with .64 it may not - * be possible to do anymore. If ever needed, one approach to try out is to somehow build the - * plugin ourselves through the react-native monorepo itself (onto a .jar), and then add it as a - * direct plugin dependency into our settings.gradle (https://docs.gradle.org/current/userguide/plugins.html#sec:custom_plugin_repositories). - */ -function overrideReactAndroidGradleForRn64Android() { - const REACT_ANDROID_PATH = path.join('node_modules', 'react-native', 'ReactAndroid'); - const REACT_ANDROID_GRADLE_SCRIPT_PATH = path.join(REACT_ANDROID_PATH, 'build.gradle'); - const REACT_ANDROID_GRADLE_BAK_SCRIPT_PATH = path.join(REACT_ANDROID_PATH, 'build.gradle.bak'); - const PATCH_SCRIPT_PATH = path.join('scripts', 'ReactAndroid_rn64_build.gradle'); - - console.log(' Overriding ReactAndroid\'s build.gradle...'); - try { - fs.renameSync(REACT_ANDROID_GRADLE_SCRIPT_PATH, REACT_ANDROID_GRADLE_BAK_SCRIPT_PATH); - } catch (e) { - console.warn(' Couldn\'t create a backup to original script (skipping)', e); - } - fs.copySync(PATCH_SCRIPT_PATH, REACT_ANDROID_GRADLE_SCRIPT_PATH); -} - function cleanFindNodeScriptFileForRn64IOS() { const REACT_SCRIPTS_PATH = path.join('node_modules', 'react-native', 'scripts'); const REACT_FIND_NODE_SCRIPT_PATH = path.join(REACT_SCRIPTS_PATH, 'find-node.sh'); - console.log(' Clean content of find-node.sh file..'); + console.log('Clean content of find-node.sh file..'); try { fs.writeFileSync(REACT_FIND_NODE_SCRIPT_PATH, ''); } catch (e) { - console.warn(' Couldn\'t clean content find-node.sh file', e); + console.warn('Couldn\'t clean content find-node.sh file'); } } function run() { - console.log('Running Detox test-app post-install script...'); - - if (semver.minor(rnVersion) === 60) { - console.log(' Detected RN version .60! Applying necessary patches...'); - patchHermesLocationForRN60Android(); - } + console.log('Running post-install script...'); if (semver.minor(rnVersion) === 64) { - console.log(' Detected RN version .64! Applying necessary patches...'); - overrideReactAndroidGradleForRn64Android(); + console.log('Detected RN version .64! Applying necessary patches...'); cleanFindNodeScriptFileForRn64IOS(); } - - console.log('Detox test-app post-install script completed!'); } run(); \ No newline at end of file From dff4fc1476ca0b900823b7b97e18f0ba646f1753 Mon Sep 17 00:00:00 2001 From: Inbal Tish Date: Sun, 8 Aug 2021 11:37:19 +0300 Subject: [PATCH 073/109] pod lock update --- ios/Podfile.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 25bb957722..3b2eaa954a 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -349,11 +349,11 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c - DoubleConversion: cde416483dac037923206447da6e1454df403714 + DoubleConversion: cf9b38bf0b2d048436d9a82ad2abe1404f11e7de FBLazyVector: 3bb422f41b18121b71783a905c10e58606f7dc3e FBReactNativeSpec: f2c97f2529dd79c083355182cc158c9f98f4bd6e Folly: b73c3869541e86821df3c387eb0af5f65addfab4 - glog: 40a13f7840415b9a77023fbcae0f1e6f43192af3 + glog: 73c2498ac6884b13ede40eda8228cb1eee9d9d62 RCTRequired: 082f10cd3f905d6c124597fd1c14f6f2655ff65e RCTTypeSafety: 8c9c544ecbf20337d069e4ae7fd9a377aadf504b React: b0a957a2c44da4113b0c4c9853d8387f8e64e615 From dbd3882dc1789f6a8d9b74a1fcda0083523fe489 Mon Sep 17 00:00:00 2001 From: Lidor Dafna Date: Sun, 8 Aug 2021 12:14:49 +0300 Subject: [PATCH 074/109] set month only if exists --- src/expandableCalendar/index.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/expandableCalendar/index.js b/src/expandableCalendar/index.js index a867a7c496..9c7afe57c2 100644 --- a/src/expandableCalendar/index.js +++ b/src/expandableCalendar/index.js @@ -352,15 +352,16 @@ class ExpandableCalendar extends Component { this.bounceToPosition(this.closedHeight); } }, 0); - + if (this.props.onDayPress) { this.props.onDayPress(value); } }; onVisibleMonthsChange = value => { - if (this.visibleMonth !== _.first(value).month) { - this.visibleMonth = _.first(value).month; // equivalent to this.getMonth(value[0].dateString) + const month = _.first(value) && _.first(value).month; + if (month && this.visibleMonth !== month) { + this.visibleMonth = month; // equivalent to this.getMonth(value[0].dateString) // for horizontal scroll const {date, updateSource} = this.props.context; From 2af437756598da38ebcfaa4b9a9143ed3ab5c5ab Mon Sep 17 00:00:00 2001 From: Lidor Dafna Date: Sun, 8 Aug 2021 12:21:51 +0300 Subject: [PATCH 075/109] rename files --- src/timeline/{Packer.js => Packer.ts} | 0 src/timeline/{Timeline.js => Timeline.ts} | 0 src/timeline/{style.js => style.ts} | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename src/timeline/{Packer.js => Packer.ts} (100%) rename src/timeline/{Timeline.js => Timeline.ts} (100%) rename src/timeline/{style.js => style.ts} (100%) diff --git a/src/timeline/Packer.js b/src/timeline/Packer.ts similarity index 100% rename from src/timeline/Packer.js rename to src/timeline/Packer.ts diff --git a/src/timeline/Timeline.js b/src/timeline/Timeline.ts similarity index 100% rename from src/timeline/Timeline.js rename to src/timeline/Timeline.ts diff --git a/src/timeline/style.js b/src/timeline/style.ts similarity index 100% rename from src/timeline/style.js rename to src/timeline/style.ts From 263ada387422190ee66baeb689aa5ada426b19d5 Mon Sep 17 00:00:00 2001 From: Lidor Dafna Date: Sun, 8 Aug 2021 12:48:46 +0300 Subject: [PATCH 076/109] rename file --- src/timeline/{Timeline.ts => Timeline.tsx} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/timeline/{Timeline.ts => Timeline.tsx} (100%) diff --git a/src/timeline/Timeline.ts b/src/timeline/Timeline.tsx similarity index 100% rename from src/timeline/Timeline.ts rename to src/timeline/Timeline.tsx From 84ba40c94d9e85bdd8caeaf45c4ad3ad6d5fd617 Mon Sep 17 00:00:00 2001 From: Lidor Dafna Date: Sun, 8 Aug 2021 13:12:59 +0300 Subject: [PATCH 077/109] migrate to TS --- src/agenda/reservation-list/index.tsx | 4 +-- src/commons/types.ts | 4 +-- src/timeline/Packer.ts | 28 ++++++++--------- src/timeline/Timeline.tsx | 45 +++++++++++++++++++++------ src/timeline/style.ts | 8 ++--- 5 files changed, 57 insertions(+), 32 deletions(-) diff --git a/src/agenda/reservation-list/index.tsx b/src/agenda/reservation-list/index.tsx index af58b5d237..a2d7783785 100644 --- a/src/agenda/reservation-list/index.tsx +++ b/src/agenda/reservation-list/index.tsx @@ -3,7 +3,7 @@ import PropTypes from 'prop-types'; import XDate from 'xdate'; import React, {Component} from 'react'; -import {ActivityIndicator, View, FlatList, ViewStyle, TextStyle, NativeSyntheticEvent, NativeScrollEvent, LayoutChangeEvent} from 'react-native'; +import {ActivityIndicator, View, FlatList, ViewStyle, TextStyle, NativeSyntheticEvent, NativeScrollEvent, LayoutChangeEvent, ColorValue} from 'react-native'; // @ts-expect-error import {extractComponentProps} from '../../component-updater'; @@ -283,7 +283,7 @@ class ReservationList extends Component; + return ; } return ( diff --git a/src/commons/types.ts b/src/commons/types.ts index eb6fb75d42..3a09397738 100644 --- a/src/commons/types.ts +++ b/src/commons/types.ts @@ -1,4 +1,4 @@ -import {ColorValue, TextStyle} from 'react-native'; +import {TextStyle} from 'react-native'; export interface Theme { container?: object; contentStyle?: object; @@ -14,7 +14,7 @@ export interface Theme { timeLabel?: object; todayTextColor?: string; calendarBackground?: string; - indicatorColor?: ColorValue; + indicatorColor?: any; stylesheet?: { calendar?: {main?: object, header?: object}; day?: {basic?: object; period?: object}; diff --git a/src/timeline/Packer.ts b/src/timeline/Packer.ts index 9249237438..4f4546f8ba 100644 --- a/src/timeline/Packer.ts +++ b/src/timeline/Packer.ts @@ -3,11 +3,11 @@ import XDate from 'xdate'; const offset = 100; -function buildEvent(column, left, width, dayStart) { - const startTime = XDate(column.start); - const endTime = column.end ? XDate(column.end) : XDate(startTime).addHours(1); +function buildEvent(column: any, left: number, width: number, dayStart: any) { + const startTime = new XDate(column.start); + const endTime = column.end ? new XDate(column.end) : new XDate(startTime).addHours(1); - const dayStartTime = XDate(startTime).clearTime(); + const dayStartTime = new XDate(startTime).clearTime(); column.top = (dayStartTime.diffHours(startTime) - dayStart) * offset; column.height = startTime.diffHours(endTime) * offset; @@ -16,11 +16,11 @@ function buildEvent(column, left, width, dayStart) { return column; } -function collision(a, b) { +function collision(a: any, b: any) { return a.end > b.start && a.start < b.end; } -function expand(ev, column, columns) { +function expand(ev: any, column: any, columns: any) { let colSpan = 1; for (let i = column + 1; i < columns.length; i++) { @@ -37,7 +37,7 @@ function expand(ev, column, columns) { return colSpan; } -function pack(columns, width, calculatedEvents, dayStart) { +function pack(columns: any, width: number, calculatedEvents: any, dayStart: any) { let colLength = columns.length; for (let i = 0; i < colLength; i++) { @@ -52,14 +52,14 @@ function pack(columns, width, calculatedEvents, dayStart) { } } -function populateEvents(events, screenWidth, dayStart) { - let lastEnd; - let columns; - let calculatedEvents = []; +function populateEvents(events: any, screenWidth: number, dayStart: any) { + let lastEnd: any; + let columns: any; + let calculatedEvents: any = []; events = events - .map((ev, index) => ({...ev, index: index})) - .sort(function (a, b) { + .map((ev: any, index: number) => ({...ev, index: index})) + .sort(function (a: any, b: any) { if (a.start < b.start) return -1; if (a.start > b.start) return 1; if (a.end < b.end) return -1; @@ -70,7 +70,7 @@ function populateEvents(events, screenWidth, dayStart) { columns = []; lastEnd = null; - events.forEach(function (ev) { + events.forEach(function (ev: any) { if (lastEnd !== null && ev.start >= lastEnd) { pack(columns, screenWidth, calculatedEvents, dayStart); columns = []; diff --git a/src/timeline/Timeline.tsx b/src/timeline/Timeline.tsx index 6cf8c0df2a..fe8ab7a352 100644 --- a/src/timeline/Timeline.tsx +++ b/src/timeline/Timeline.tsx @@ -2,21 +2,43 @@ import _ from 'lodash'; import PropTypes from 'prop-types'; import XDate from 'xdate'; -import React from 'react'; -import {View, Text, ScrollView, TouchableOpacity, Dimensions} from 'react-native'; +import React, {Component} from 'react'; +import {View, Text, TouchableOpacity, Dimensions, ScrollView} from 'react-native'; import styleConstructor from './style'; import populateEvents from './Packer'; const LEFT_MARGIN = 60 - 1; const TEXT_LINE_HEIGHT = 17; -function range(from, to) { +function range(from: number, to: number) { return Array.from(Array(to), (_, i) => from + i); } let {width: dimensionWidth} = Dimensions.get('window'); -export default class Timeline extends React.PureComponent { +export interface TimelineProps { + start?: number; + end?: number; + eventTapped?: (event: any) => void; + format24h?: boolean; + events: { + start: string; + end: string; + title: string; + summary: string; + color?: string; + }[]; + styles?: any; + scrollToFirst?: boolean; + renderEvent?: (event: any) => JSX.Element; +} + +interface State { + _scrollY: any; + packedEvents: any; +} + +export default class Timeline extends Component { static propTypes = { start: PropTypes.number, end: PropTypes.number, @@ -39,11 +61,14 @@ export default class Timeline extends React.PureComponent { events: [], format24h: true }; + calendarHeight: number; + private _scrollView: any; + style: any; - constructor(props) { + constructor(props: TimelineProps) { super(props); - const {start, end} = this.props; + const {start = 0, end = 0} = this.props; this.calendarHeight = (end - start) * 100; this.style = styleConstructor(props.styles, this.calendarHeight); @@ -59,7 +84,7 @@ export default class Timeline extends React.PureComponent { }; } - componentDidUpdate(prevProps) { + componentDidUpdate(prevProps: TimelineProps) { const width = dimensionWidth - LEFT_MARGIN; const {events: prevEvents, start: prevStart = 0} = prevProps; const {events, start = 0} = this.props; @@ -122,7 +147,7 @@ export default class Timeline extends React.PureComponent { }); } - _onEventTapped(event) { + _onEventTapped(event: any) { if (this.props.eventTapped) { this.props.eventTapped(event); } @@ -130,7 +155,7 @@ export default class Timeline extends React.PureComponent { _renderEvents() { const {packedEvents} = this.state; - let events = packedEvents.map((event, i) => { + let events = packedEvents.map((event: any, i: number) => { const style = { left: event.left, height: event.height, @@ -165,7 +190,7 @@ export default class Timeline extends React.PureComponent { ) : null} {numberOfLines > 2 ? ( - {XDate(event.start).toString(formatTime)} - {XDate(event.end).toString(formatTime)} + {new XDate(event.start).toString(formatTime)} - {new XDate(event.end).toString(formatTime)} ) : null} diff --git a/src/timeline/style.ts b/src/timeline/style.ts index 0d1edc845a..6b7badcda9 100644 --- a/src/timeline/style.ts +++ b/src/timeline/style.ts @@ -1,11 +1,12 @@ // @flow import {Platform, StyleSheet} from 'react-native'; +import {Theme} from '../commons/types'; // const eventPaddingLeft = 4 const leftMargin = 50 - 1; -export default function styleConstructor(theme = {}, calendarHeight) { - let style = { +export default function styleConstructor(theme: Theme = {}, calendarHeight: number) { + return StyleSheet.create({ container: { flex: 1, backgroundColor: '#ffff', @@ -105,6 +106,5 @@ export default function styleConstructor(theme = {}, calendarHeight) { fontWeight: '500', ...theme.timeLabel } - }; - return StyleSheet.create(style); + }); } From 1935898935eee0548611c188fb5875c7974667d4 Mon Sep 17 00:00:00 2001 From: Souvik Ghosh Date: Mon, 9 Aug 2021 00:11:16 +0530 Subject: [PATCH 078/109] agendaList - remove onScrollToIndexFailed --- src/expandableCalendar/agendaList.js | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/expandableCalendar/agendaList.js b/src/expandableCalendar/agendaList.js index e80de7698a..c3c2f9f4f8 100644 --- a/src/expandableCalendar/agendaList.js +++ b/src/expandableCalendar/agendaList.js @@ -163,10 +163,6 @@ class AgendaList extends Component { _.invoke(this.props, 'onMomentumScrollEnd', event); }; - onScrollToIndexFailed = info => { - console.warn('onScrollToIndexFailed info: ', info); - }; - onHeaderLayout = ({nativeEvent}) => { this.sectionHeight = nativeEvent.layout.height; }; @@ -205,7 +201,6 @@ class AgendaList extends Component { onScroll={this.onScroll} onMomentumScrollBegin={this.onMomentumScrollBegin} onMomentumScrollEnd={this.onMomentumScrollEnd} - onScrollToIndexFailed={this.onScrollToIndexFailed} // getItemLayout={this.getItemLayout} // onViewableItemsChanged is not updated when list scrolls!!! /> ); From 7fe7fffa7a1a31e9a77f880c13bb82571b2b02ae Mon Sep 17 00:00:00 2001 From: Inbal Tish Date: Mon, 9 Aug 2021 09:39:46 +0300 Subject: [PATCH 079/109] fix types; move types file out of directory; fix refs --- example/src/screens/timelineCalendar.js | 4 +-- src/agenda/index.tsx | 38 +++++++++------------ src/agenda/platform-style.ios.ts | 2 +- src/agenda/platform-style.ts | 2 +- src/agenda/reservation-list/index.tsx | 7 ++-- src/agenda/reservation-list/reservation.tsx | 2 +- src/agenda/reservation-list/style.ts | 2 +- src/agenda/style.ts | 2 +- src/calendar-list/index.tsx | 8 ++--- src/calendar-list/item.tsx | 2 +- src/calendar-list/style.ts | 2 +- src/calendar/day/basic/index.tsx | 2 +- src/calendar/day/basic/style.ts | 2 +- src/calendar/day/dot/index.tsx | 2 +- src/calendar/day/dot/style.ts | 2 +- src/calendar/day/marking/index.tsx | 2 +- src/calendar/day/marking/style.ts | 2 +- src/calendar/day/period/index.tsx | 2 +- src/calendar/day/period/style.ts | 2 +- src/calendar/header/index.tsx | 2 +- src/calendar/header/style.ts | 2 +- src/calendar/index.tsx | 4 +-- src/calendar/style.ts | 2 +- src/{commons => }/types.ts | 27 +++++++++------ 24 files changed, 63 insertions(+), 61 deletions(-) rename src/{commons => }/types.ts (72%) diff --git a/example/src/screens/timelineCalendar.js b/example/src/screens/timelineCalendar.js index 3217edca66..830f006967 100644 --- a/example/src/screens/timelineCalendar.js +++ b/example/src/screens/timelineCalendar.js @@ -85,13 +85,13 @@ export default class TimelineCalendarScreen extends Component { }; onDateChanged = date => { - // console.warn('ExpandableCalendarScreen onDateChanged: ', date, updateSource); + // console.warn('TimelineCalendarScreen onDateChanged: ', date, updateSource); // fetch and set data for date + week ahead this.setState({currentDate: date}); }; onMonthChange = (/* month, updateSource */) => { - // console.warn('ExpandableCalendarScreen onMonthChange: ', month, updateSource); + // console.warn('TimelineCalendarScreen onMonthChange: ', month, updateSource); }; renderEmptyItem() { diff --git a/src/agenda/index.tsx b/src/agenda/index.tsx index 4e19d9f9d8..db441868c6 100644 --- a/src/agenda/index.tsx +++ b/src/agenda/index.tsx @@ -113,10 +113,10 @@ export default class Agenda extends Component { private currentMonth: XDate; private knobTracker: any; private _isMounted: boolean | undefined; - private scrollPad: any; - private calendar: any; - private knob: any; - public list: any; + private scrollPad: React.RefObject = React.createRef(); + private calendar: React.RefObject = React.createRef(); + private knob: React.RefObject = React.createRef(); + public list: React.RefObject = React.createRef(); constructor(props: AgendaProps) { super(props); @@ -180,11 +180,11 @@ export default class Agenda extends Component { }; setScrollPadPosition = (y: number, animated: boolean) => { - if (this.scrollPad?.scrollTo) { - this.scrollPad.scrollTo({x: 0, y, animated}); + if (this.scrollPad?.current?.scrollTo) { + this.scrollPad.current.scrollTo({x: 0, y, animated}); } else { // Support for RN O.61 (Expo 37) - this.scrollPad.getNode().scrollTo({x: 0, y, animated}); + this.scrollPad?.current?.getNode().scrollTo({x: 0, y, animated}); } }; @@ -209,7 +209,7 @@ export default class Agenda extends Component { // in CalendarList listView, but that might impact performance when scrolling // month list in expanded CalendarList. // Further info https://github.com/facebook/react-native/issues/1831 - this.calendar.scrollToDay(this.state.selectedDay, this.calendarOffset() + 1, true); + this.calendar?.current?.scrollToDay(this.state.selectedDay, this.calendarOffset() + 1, true); } loadReservations(props: AgendaProps) { @@ -246,7 +246,7 @@ export default class Agenda extends Component { } this.setScrollPadPosition(this.initialScrollPadPosition(), true); - this.calendar.scrollToDay(day, this.calendarOffset(), true); + this.calendar?.current?.scrollToDay(day, this.calendarOffset(), true); _.invoke(this.props, 'loadItemsForMonth', xdateToData(day)); _.invoke(this.props, 'onDayPress', xdateToData(day)); @@ -276,7 +276,7 @@ export default class Agenda extends Component { }; onCalendarListLayout = () => { - this.calendar.scrollToDay(this.state.selectedDay.clone(), this.calendarOffset(), false); + this.calendar?.current?.scrollToDay(this.state.selectedDay.clone(), this.calendarOffset(), false); }; onLayout = (event: LayoutChangeEvent) => { @@ -287,15 +287,11 @@ export default class Agenda extends Component { onTouchStart = () => { this.headerState = 'touched'; - if (this.knob) { - this.knob.setNativeProps({style: {opacity: 0.5}}); - } + this.knob?.current?.setNativeProps({style: {opacity: 0.5}}); }; onTouchEnd = () => { - if (this.knob) { - this.knob.setNativeProps({style: {opacity: 1}}); - } + this.knob?.current?.setNativeProps({style: {opacity: 1}}); if (this.headerState === 'touched') { const isOpen = this.state.calendarScrollable; @@ -341,7 +337,7 @@ export default class Agenda extends Component { const newDate = parseDate(day); const withAnimation = dateutils.sameMonth(newDate, this.state.selectedDay); - this.calendar.scrollToDay(day, this.calendarOffset(), withAnimation); + this.calendar?.current?.scrollToDay(day, this.calendarOffset(), withAnimation); this.setState({ selectedDay: newDate }); @@ -355,7 +351,7 @@ export default class Agenda extends Component { return ( (this.list = c)} + ref={this.list} reservations={this.props.items} selectedDay={this.state.selectedDay} topDay={this.state.topDay} @@ -373,7 +369,7 @@ export default class Agenda extends Component { return ( (this.calendar = c)} + ref={this.calendar} current={this.currentMonth} markedDates={this.generateMarkings(this.state.selectedDay, markedDates, items)} calendarWidth={this.viewWidth} @@ -394,7 +390,7 @@ export default class Agenda extends Component { const knobView = renderKnob ? renderKnob() : ; knob = !this.state.calendarScrollable || showClosingKnob ? ( - (this.knob = c)}>{knobView} + {knobView} ) : null; } @@ -484,7 +480,7 @@ export default class Agenda extends Component { {this.renderWeekDaysNames(weekDaysNames)} (this.scrollPad = ref)} + ref={this.scrollPad} style={[this.style.scrollPadStyle, scrollPadStyle]} overScrollMode="never" showsHorizontalScrollIndicator={false} diff --git a/src/agenda/platform-style.ios.ts b/src/agenda/platform-style.ios.ts index a6ea5a50a0..cca46a7e01 100644 --- a/src/agenda/platform-style.ios.ts +++ b/src/agenda/platform-style.ios.ts @@ -1,4 +1,4 @@ -import {Theme} from '../commons/types'; +import {Theme} from '../types'; export default function platformStyles(appStyle: Theme) { return { diff --git a/src/agenda/platform-style.ts b/src/agenda/platform-style.ts index d57581de3e..92fe497a4a 100644 --- a/src/agenda/platform-style.ts +++ b/src/agenda/platform-style.ts @@ -1,5 +1,5 @@ import {ViewStyle} from 'react-native'; -import {Theme} from '../commons/types'; +import {Theme} from '../types'; export default function platformStyles(appStyle: Theme) { return { diff --git a/src/agenda/reservation-list/index.tsx b/src/agenda/reservation-list/index.tsx index af58b5d237..b940c3d0a0 100644 --- a/src/agenda/reservation-list/index.tsx +++ b/src/agenda/reservation-list/index.tsx @@ -103,7 +103,8 @@ class ReservationList extends Component | null; + private list: React.RefObject = React.createRef(); + constructor(props: ReservationListProps) { super(props); @@ -153,7 +154,7 @@ class ReservationList extends Component (this.list = c)} + ref={this.list} style={style} contentContainerStyle={this.style.content} data={this.state.reservations} diff --git a/src/agenda/reservation-list/reservation.tsx b/src/agenda/reservation-list/reservation.tsx index 07d6ac6e35..44aab03817 100644 --- a/src/agenda/reservation-list/reservation.tsx +++ b/src/agenda/reservation-list/reservation.tsx @@ -12,7 +12,7 @@ import dateutils from '../../dateutils'; // @ts-expect-error import {RESERVATION_DATE} from '../../testIDs'; import styleConstructor from './style'; -import {Theme} from '../../commons/types'; +import {Theme} from '../../types'; import {DayReservations} from './index'; diff --git a/src/agenda/reservation-list/style.ts b/src/agenda/reservation-list/style.ts index 5c4d859dc9..0e0dfd916d 100644 --- a/src/agenda/reservation-list/style.ts +++ b/src/agenda/reservation-list/style.ts @@ -1,6 +1,6 @@ import {StyleSheet} from 'react-native'; import * as defaultStyle from '../../style'; -import {Theme} from '../../commons/types'; +import {Theme} from '../../types'; export default function styleConstructor(theme: Theme = {}) { diff --git a/src/agenda/style.ts b/src/agenda/style.ts index 8df4e90680..6ac9b1c631 100644 --- a/src/agenda/style.ts +++ b/src/agenda/style.ts @@ -1,7 +1,7 @@ import {StyleSheet} from 'react-native'; import * as defaultStyle from '../style'; import platformStyles from './platform-style'; -import {Theme} from '../commons/types'; +import {Theme} from '../types'; export default function styleConstructor(theme: Theme = {}) { diff --git a/src/calendar-list/index.tsx b/src/calendar-list/index.tsx index 9ef19e0331..e431b81f70 100644 --- a/src/calendar-list/index.tsx +++ b/src/calendar-list/index.tsx @@ -131,7 +131,7 @@ class CalendarList extends Component { }; style: any; - listView: FlatList | undefined | null; + list: React.RefObject = React.createRef(); viewabilityConfig = { itemVisiblePercentThreshold: 20 }; @@ -216,7 +216,7 @@ class CalendarList extends Component { } } } - this.listView?.scrollToOffset({offset: scrollAmount, animated}); + this.list?.current?.scrollToOffset({offset: scrollAmount, animated}); } scrollToMonth = (m: XDate) => { @@ -227,7 +227,7 @@ class CalendarList extends Component { const size = horizontal ? calendarWidth : calendarHeight; const scrollAmount = size * pastScrollRange + diffMonths * size; - this.listView?.scrollToOffset({offset: scrollAmount, animated: animateScroll}); + this.list?.current?.scrollToOffset({offset: scrollAmount, animated: animateScroll}); }; getItemLayout = (_: Array | undefined | null, index: number) => { @@ -349,7 +349,7 @@ class CalendarList extends Component { return ( (this.listView = c)} + ref={this.list} style={[this.style.container, style]} // @ts-ignore initialListSize={pastScrollRange + futureScrollRange + 1} // ListView deprecated diff --git a/src/calendar-list/item.tsx b/src/calendar-list/item.tsx index 3c18c8a824..9b6a2ea1c1 100644 --- a/src/calendar-list/item.tsx +++ b/src/calendar-list/item.tsx @@ -4,7 +4,7 @@ import memoize from 'memoize-one'; import React, {Component} from 'react'; import {Text, View} from 'react-native'; -import {Theme} from '../commons/types'; +import {Theme} from '../types'; // @ts-expect-error import {extractComponentProps} from '../component-updater'; import Calendar, {CalendarProps} from '../calendar'; diff --git a/src/calendar-list/style.ts b/src/calendar-list/style.ts index fc2754f7bf..b229646b5c 100644 --- a/src/calendar-list/style.ts +++ b/src/calendar-list/style.ts @@ -1,6 +1,6 @@ import {Platform, StyleSheet} from 'react-native'; import * as defaultStyle from '../style'; -import {Theme} from '../commons/types'; +import {Theme} from '../types'; export default function getStyle(theme: Theme = {}) { const appStyle = {...defaultStyle, ...theme}; diff --git a/src/calendar/day/basic/index.tsx b/src/calendar/day/basic/index.tsx index dda322fe5a..2c3f3716f1 100644 --- a/src/calendar/day/basic/index.tsx +++ b/src/calendar/day/basic/index.tsx @@ -7,7 +7,7 @@ import {TouchableOpacity, Text, View} from 'react-native'; import {shouldUpdate} from '../../../component-updater'; import styleConstructor from './style'; import Marking, {MarkingTypes, MarkingProps} from '../marking'; -import {Theme} from '../../../commons/types'; +import {Theme} from '../../../types'; export interface BasicDayProps { state?: 'selected' | 'disabled' | 'today'; diff --git a/src/calendar/day/basic/style.ts b/src/calendar/day/basic/style.ts index 1f0a1d5c93..380f1721b4 100644 --- a/src/calendar/day/basic/style.ts +++ b/src/calendar/day/basic/style.ts @@ -1,6 +1,6 @@ import {StyleSheet, Platform} from 'react-native'; import * as defaultStyle from '../../../style'; -import {Theme} from '../../../commons/types'; +import {Theme} from '../../../types'; export default function styleConstructor(theme: Theme = {}) { const appStyle = {...defaultStyle, ...theme}; diff --git a/src/calendar/day/dot/index.tsx b/src/calendar/day/dot/index.tsx index e89bad91cd..927de00d1e 100644 --- a/src/calendar/day/dot/index.tsx +++ b/src/calendar/day/dot/index.tsx @@ -2,7 +2,7 @@ import PropTypes from 'prop-types'; import React from 'react'; import {View} from 'react-native'; import styleConstructor from './style'; -import {Theme} from '../../../commons/types'; +import {Theme} from '../../../types'; export interface DotProps { theme?: Theme; diff --git a/src/calendar/day/dot/style.ts b/src/calendar/day/dot/style.ts index 63f93f8fe4..4326d40664 100644 --- a/src/calendar/day/dot/style.ts +++ b/src/calendar/day/dot/style.ts @@ -1,6 +1,6 @@ import {StyleSheet} from 'react-native'; import * as defaultStyle from '../../../style'; -import {Theme} from '../../../commons/types'; +import {Theme} from '../../../types'; export default function styleConstructor(theme: Theme = {}) { const appStyle = {...defaultStyle, ...theme}; diff --git a/src/calendar/day/marking/index.tsx b/src/calendar/day/marking/index.tsx index afb55eebfb..c4b869854f 100644 --- a/src/calendar/day/marking/index.tsx +++ b/src/calendar/day/marking/index.tsx @@ -7,7 +7,7 @@ import {View, ViewStyle, TextStyle} from 'react-native'; import {shouldUpdate, extractComponentProps} from '../../../component-updater'; import styleConstructor from './style'; import Dot, {DotProps} from '../dot'; -import {Theme} from '../../../commons/types'; +import {Theme} from '../../../types'; export enum MarkingTypes { DOT = 'dot', diff --git a/src/calendar/day/marking/style.ts b/src/calendar/day/marking/style.ts index b268290337..b0b15bd14d 100644 --- a/src/calendar/day/marking/style.ts +++ b/src/calendar/day/marking/style.ts @@ -1,6 +1,6 @@ import {StyleSheet} from 'react-native'; import * as defaultStyle from '../../style'; -import {Theme} from '../../../commons/types'; +import {Theme} from '../../../types'; export default function styleConstructor(theme: Theme = {}) { const appStyle = {...defaultStyle, ...theme}; diff --git a/src/calendar/day/period/index.tsx b/src/calendar/day/period/index.tsx index 3584d1190b..becc0ff052 100644 --- a/src/calendar/day/period/index.tsx +++ b/src/calendar/day/period/index.tsx @@ -10,7 +10,7 @@ import * as defaultStyle from '../../../style'; import styleConstructor from './style'; import Dot from '../dot'; import {MarkingProps} from '../marking'; -import {Theme} from '../../../commons/types'; +import {Theme} from '../../../types'; interface PeriodDayProps { state?: 'selected' | 'disabled' | 'today' | ''; diff --git a/src/calendar/day/period/style.ts b/src/calendar/day/period/style.ts index 1d0ee09e4f..5f06b9a2cc 100644 --- a/src/calendar/day/period/style.ts +++ b/src/calendar/day/period/style.ts @@ -1,6 +1,6 @@ import {StyleSheet} from 'react-native'; import * as defaultStyle from '../../../style'; -import {Theme} from '../../../commons/types'; +import {Theme} from '../../../types'; const FILLER_HEIGHT = 34; diff --git a/src/calendar/header/index.tsx b/src/calendar/header/index.tsx index 934ee8a14d..9f5e73a5db 100644 --- a/src/calendar/header/index.tsx +++ b/src/calendar/header/index.tsx @@ -18,7 +18,7 @@ import { // @ts-expect-error } from '../../testIDs'; import styleConstructor from './style'; -import {Theme} from '../../commons/types'; +import {Theme} from '../../types'; type Direction = 'left' | 'right'; export interface CalendarHeaderProps { diff --git a/src/calendar/header/style.ts b/src/calendar/header/style.ts index 86e7a64993..495dd8cdfa 100644 --- a/src/calendar/header/style.ts +++ b/src/calendar/header/style.ts @@ -1,6 +1,6 @@ import {StyleSheet, Platform} from 'react-native'; import * as defaultStyle from '../../style'; -import {Theme} from '../../commons/types'; +import {Theme} from '../../types'; export default function (theme: Theme = {}) { const appStyle = {...defaultStyle, ...theme}; diff --git a/src/calendar/index.tsx b/src/calendar/index.tsx index cae10b7287..47f791403b 100644 --- a/src/calendar/index.tsx +++ b/src/calendar/index.tsx @@ -24,7 +24,7 @@ import CalendarHeader, {CalendarHeaderProps} from './header'; import Day, {DayProps} from './day/index'; import BasicDay from './day/basic'; import {MarkingProps} from './day/marking'; -import {Theme} from '../commons/types'; +import {Theme} from '../types'; type MarkedDatesType = { @@ -59,7 +59,7 @@ export interface CalendarProps extends CalendarHeaderProps, DayProps { /** Handler which gets executed on day long press */ onDayLongPress?: (date: Date) => any; /** Handler which gets executed when month changes in calendar */ - onMonthChange?: () => void; + onMonthChange?: () => object; /** Handler which gets executed when visible month changes in calendar */ onVisibleMonthsChange?: () => void; /** Disables changing month when click on days of other months (when hideExtraDays is false) */ diff --git a/src/calendar/style.ts b/src/calendar/style.ts index 577ab647ab..08c8061a68 100644 --- a/src/calendar/style.ts +++ b/src/calendar/style.ts @@ -1,6 +1,6 @@ import {StyleSheet} from 'react-native'; import * as defaultStyle from '../style'; -import {Theme} from '../commons/types'; +import {Theme} from '../types'; export default function getStyle(theme: Theme = {}) { const appStyle = {...defaultStyle, ...theme}; diff --git a/src/commons/types.ts b/src/types.ts similarity index 72% rename from src/commons/types.ts rename to src/types.ts index eb6fb75d42..08e500c4fe 100644 --- a/src/commons/types.ts +++ b/src/types.ts @@ -1,7 +1,10 @@ -import {ColorValue, TextStyle} from 'react-native'; +import {ColorValue, ViewStyle, TextStyle} from 'react-native'; +import {UPDATE_SOURCES} from './expandableCalendar/commons'; + + export interface Theme { container?: object; - contentStyle?: object; + contentStyle?: ViewStyle; header?: object; headerText?: object; arrowButton?: object; @@ -22,6 +25,7 @@ export interface Theme { marking?: object; 'calendar-list'?: {main?: object}; agenda?: {main?: object, list?: object}; + expandable?: {main?: object} }; textSectionTitleColor?: string; textSectionTitleDisabledColor?: string; @@ -35,11 +39,11 @@ export interface Theme { dotColor?: string; selectedDotColor?: string; disabledArrowColor?: string; - textDayFontFamily?: string; - textMonthFontFamily?: string; - textDayHeaderFontFamily?: string; - textDayFontWeight?: string; - textMonthFontWeight?: string; + textDayFontFamily?: TextStyle['fontFamily']; + textMonthFontFamily?: TextStyle['fontFamily']; + textDayHeaderFontFamily?: TextStyle['fontFamily']; + textDayFontWeight?: TextStyle['fontWeight']; + textMonthFontWeight?: TextStyle['fontWeight']; textDayHeaderFontWeight?: TextStyle['fontWeight']; textDayFontSize?: number; textMonthFontSize?: number; @@ -57,12 +61,12 @@ export interface Theme { textDefaultColor?: string; textColor?: string; textLinkColor?: string; - todayButtonFontFamily?: string; - todayButtonFontWeight?: string; + todayButtonFontFamily?: TextStyle['fontFamily']; + todayButtonFontWeight?: TextStyle['fontWeight']; todayButtonFontSize?: number; - textDayStyle?: object; + textDayStyle?: TextStyle; dotStyle?: object; - arrowStyle?: object; + arrowStyle?: ViewStyle; todayBackgroundColor?: string; disabledDotColor?: string; todayDotColor?: string; @@ -71,3 +75,4 @@ export interface Theme { arrowHeight?: number; arrowWidth?: number; } +export type UpdateSource = keyof typeof UPDATE_SOURCES; From 64e9110ab68265434f2e591c4080ad14243d2320 Mon Sep 17 00:00:00 2001 From: Inbal Tish Date: Mon, 9 Aug 2021 10:11:15 +0300 Subject: [PATCH 080/109] Adding `DateData` type (returns from interface.xdatetodata function) --- src/agenda/index.tsx | 5 +++-- src/calendar/index.tsx | 8 ++++---- src/types.ts | 10 +++++++++- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/agenda/index.tsx b/src/agenda/index.tsx index db441868c6..ba68d7d882 100644 --- a/src/agenda/index.tsx +++ b/src/agenda/index.tsx @@ -15,9 +15,10 @@ import dateutils from '../dateutils'; // @ts-expect-error import {AGENDA_CALENDAR_KNOB} from '../testIDs'; // @ts-expect-error +import {DateData} from '../types'; import {VelocityTracker} from '../input'; -import CalendarList, {CalendarListProps} from '../calendar-list'; import styleConstructor from './style'; +import CalendarList, {CalendarListProps} from '../calendar-list'; import ReservationList, {ReservationListProps} from './reservation-list'; @@ -42,7 +43,7 @@ export type AgendaProps = CalendarListProps & ReservationListProps & { considered that the date in question is not yet loaded */ items: ReservationsType; /** callback that gets called when items for a certain month should be loaded (month became visible) */ - loadItemsForMonth?: (data: any) => void; + loadItemsForMonth?: (data: any) => DateData; /** callback that fires when the calendar is opened or closed */ onCalendarToggled?: (enabled: boolean) => void; /** callback that gets called on day press */ diff --git a/src/calendar/index.tsx b/src/calendar/index.tsx index 47f791403b..091bf2983f 100644 --- a/src/calendar/index.tsx +++ b/src/calendar/index.tsx @@ -24,7 +24,7 @@ import CalendarHeader, {CalendarHeaderProps} from './header'; import Day, {DayProps} from './day/index'; import BasicDay from './day/basic'; import {MarkingProps} from './day/marking'; -import {Theme} from '../types'; +import {Theme, DateData} from '../types'; type MarkedDatesType = { @@ -59,9 +59,9 @@ export interface CalendarProps extends CalendarHeaderProps, DayProps { /** Handler which gets executed on day long press */ onDayLongPress?: (date: Date) => any; /** Handler which gets executed when month changes in calendar */ - onMonthChange?: () => object; + onMonthChange?: () => DateData; /** Handler which gets executed when visible month changes in calendar */ - onVisibleMonthsChange?: () => void; + onVisibleMonthsChange?: () => DateData[]; /** Disables changing month when click on days of other months (when hideExtraDays is false) */ disableMonthChange?: boolean; /** Enable the option to swipe between months */ @@ -157,7 +157,7 @@ class Calendar extends Component { }); }; - handleDayInteraction(date: Date, interaction?: (date: Date) => any) { + handleDayInteraction(date: Date, interaction?: (date: Date) => DateData) { const {disableMonthChange} = this.props; const day = parseDate(date); const minDate = parseDate(this.props.minDate); diff --git a/src/types.ts b/src/types.ts index 08e500c4fe..23b306debe 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,7 +1,16 @@ +import { string } from 'prop-types'; import {ColorValue, ViewStyle, TextStyle} from 'react-native'; import {UPDATE_SOURCES} from './expandableCalendar/commons'; +export type UpdateSource = keyof typeof UPDATE_SOURCES; +export type DateData = { + year: number, + month: number, + day: number, + timestamp: number, + dateString: string +} export interface Theme { container?: object; contentStyle?: ViewStyle; @@ -75,4 +84,3 @@ export interface Theme { arrowHeight?: number; arrowWidth?: number; } -export type UpdateSource = keyof typeof UPDATE_SOURCES; From cb9db2c770aade358844b182b93b0c8021cfdff9 Mon Sep 17 00:00:00 2001 From: Lidor Dafna Date: Mon, 9 Aug 2021 12:00:48 +0300 Subject: [PATCH 081/109] support inactive state for day --- example/src/screens/calendars.tsx | 7 +++++++ src/calendar/day/basic/index.tsx | 21 +++++++++++++++++---- src/calendar/day/basic/style.ts | 3 +++ src/calendar/day/marking/index.tsx | 1 + src/commons/types.ts | 1 + src/style.ts | 1 + 6 files changed, 30 insertions(+), 4 deletions(-) diff --git a/example/src/screens/calendars.tsx b/example/src/screens/calendars.tsx index 9967b5b3f8..598066d60b 100644 --- a/example/src/screens/calendars.tsx +++ b/example/src/screens/calendars.tsx @@ -24,6 +24,7 @@ const CalendarsScreen = () => { Calendar with selectable date { disableTouchEvent: true, selectedColor: 'orange', selectedTextColor: 'red' + }, + '2020-02-10': { + inactive: true + }, + '2020-02-11': { + inactive: true } }} /> diff --git a/src/calendar/day/basic/index.tsx b/src/calendar/day/basic/index.tsx index dda322fe5a..a1beabea6c 100644 --- a/src/calendar/day/basic/index.tsx +++ b/src/calendar/day/basic/index.tsx @@ -10,7 +10,7 @@ import Marking, {MarkingTypes, MarkingProps} from '../marking'; import {Theme} from '../../../commons/types'; export interface BasicDayProps { - state?: 'selected' | 'disabled' | 'today'; + state?: 'selected' | 'disabled' | 'inactive' | 'today'; /** The marking object */ marking?: MarkingProps; /** Date marking style [simple/period/multi-dot/multi-period]. Default = 'simple' */ @@ -25,6 +25,8 @@ export interface BasicDayProps { date?: Date; /** Disable all touch events for disabled days. can be override with disableTouchEvent in markedDates*/ disableAllTouchEventsForDisabledDays?: boolean; + /** Disable all touch events for inactive days. can be override with disableTouchEvent in markedDates*/ + disableAllTouchEventsForInactiveDays?: boolean; /** Test ID*/ testID?: string; /** Accessibility label */ @@ -35,7 +37,7 @@ export default class BasicDay extends Component { static displayName = 'IGNORE'; static propTypes = { - state: PropTypes.oneOf(['selected', 'disabled', 'today', '']), + state: PropTypes.oneOf(['selected', 'disabled', 'inactive', 'today', '']), /** The marking object */ marking: PropTypes.any, /** Date marking style [simple/period/multi-dot/multi-period]. Default = 'simple' */ @@ -49,7 +51,10 @@ export default class BasicDay extends Component { /** The date to return from press callbacks */ date: PropTypes.object, /** Disable all touch events for disabled days. Can be override with disableTouchEvent in markedDates*/ - disableAllTouchEventsForDisabledDays: PropTypes.bool + disableAllTouchEventsForDisabledDays: PropTypes.bool, + /** Disable all touch events for inactive days. can be override with disableTouchEvent in markedDates*/ + disableAllTouchEventsForInactiveDays: PropTypes.bool + }; style = styleConstructor(this.props.theme); @@ -79,7 +84,7 @@ export default class BasicDay extends Component { } shouldDisableTouchEvent() { - const {disableAllTouchEventsForDisabledDays} = this.props; + const {disableAllTouchEventsForDisabledDays, disableAllTouchEventsForInactiveDays} = this.props; const {disableTouchEvent} = this.marking; let disableTouch = false; @@ -87,6 +92,8 @@ export default class BasicDay extends Component { disableTouch = disableTouchEvent; } else if (typeof disableAllTouchEventsForDisabledDays === 'boolean' && this.isDisabled()) { disableTouch = disableAllTouchEventsForDisabledDays; + } else if (typeof disableAllTouchEventsForInactiveDays === 'boolean' && this.isInactive()) { + disableTouch = disableAllTouchEventsForInactiveDays; } return disableTouch; } @@ -99,6 +106,10 @@ export default class BasicDay extends Component { return typeof this.marking.disabled !== 'undefined' ? this.marking.disabled : this.props.state === 'disabled'; } + isInactive() { + return this.marking?.inactive; + } + isToday() { return this.props.state === 'today'; } @@ -152,6 +163,8 @@ export default class BasicDay extends Component { style.push(this.style.disabledText); } else if (this.isToday()) { style.push(this.style.todayText); + } else if (this.isInactive()) { + style.push(this.style.inactiveText); } //Custom marking type diff --git a/src/calendar/day/basic/style.ts b/src/calendar/day/basic/style.ts index 1f0a1d5c93..ff955a2e7f 100644 --- a/src/calendar/day/basic/style.ts +++ b/src/calendar/day/basic/style.ts @@ -43,6 +43,9 @@ export default function styleConstructor(theme: Theme = {}) { disabledText: { color: appStyle.textDisabledColor }, + inactiveText: { + color: appStyle.textInactiveColor + }, dot: { width: 4, height: 4, diff --git a/src/calendar/day/marking/index.tsx b/src/calendar/day/marking/index.tsx index afb55eebfb..eae1035c67 100644 --- a/src/calendar/day/marking/index.tsx +++ b/src/calendar/day/marking/index.tsx @@ -41,6 +41,7 @@ export interface MarkingProps extends DotProps { marked?: boolean; today?: boolean; disabled?: boolean; + inactive?: boolean; disableTouchEvent?: boolean; activeOpacity?: number; selectedColor?: string; diff --git a/src/commons/types.ts b/src/commons/types.ts index eb6fb75d42..fb54252e7a 100644 --- a/src/commons/types.ts +++ b/src/commons/types.ts @@ -31,6 +31,7 @@ export interface Theme { selectedDayBackgroundColor?: string; arrowColor?: string; textDisabledColor?: string; + textInactiveColor?: string; backgroundColor?: string; dotColor?: string; selectedDotColor?: string; diff --git a/src/style.ts b/src/style.ts index a1db8eb256..f46b85e6e0 100644 --- a/src/style.ts +++ b/src/style.ts @@ -39,6 +39,7 @@ export const todayBackgroundColor = undefined; export const todayTextColor = textLinkColor; export const dayTextColor = textDefaultColor; export const textDisabledColor = '#d9e1e8'; +export const textInactiveColor = '#d9e1e8'; export const dotColor = textLinkColor; export const selectedDotColor = foregroundColor; export const disabledDotColor = undefined; From 72ce59c0b5d6f9eac03830a49ab40ed268806c4a Mon Sep 17 00:00:00 2001 From: Inbal Tish Date: Mon, 9 Aug 2021 13:00:48 +0300 Subject: [PATCH 082/109] fix style type --- src/agenda/index.tsx | 10 ++++------ src/agenda/reservation-list/index.tsx | 4 ++-- src/calendar-list/index.tsx | 17 +++++++++-------- src/calendar/header/index.tsx | 13 +++++++------ src/calendar/index.tsx | 8 ++++---- 5 files changed, 26 insertions(+), 26 deletions(-) diff --git a/src/agenda/index.tsx b/src/agenda/index.tsx index ba68d7d882..344402dde0 100644 --- a/src/agenda/index.tsx +++ b/src/agenda/index.tsx @@ -4,7 +4,7 @@ import XDate from 'xdate'; import memoize from 'memoize-one'; import React, {Component} from 'react'; -import {Text, View, Dimensions, Animated, ViewStyle, LayoutChangeEvent, NativeSyntheticEvent, NativeScrollEvent} from 'react-native'; +import {Text, View, Dimensions, Animated, StyleProp, ViewStyle, LayoutChangeEvent, NativeSyntheticEvent, NativeScrollEvent} from 'react-native'; // @ts-expect-error import {extractComponentProps} from '../component-updater.js'; @@ -36,8 +36,6 @@ export type ReservationsType = { } export type AgendaProps = CalendarListProps & ReservationListProps & { - /** agenda container style */ - style?: ViewStyle; /** the list of items that have to be displayed in agenda. If you want to render item as empty date the value of date key has to be an empty array []. If there exists no value for date key it is considered that the date in question is not yet loaded */ @@ -47,9 +45,9 @@ export type AgendaProps = CalendarListProps & ReservationListProps & { /** callback that fires when the calendar is opened or closed */ onCalendarToggled?: (enabled: boolean) => void; /** callback that gets called on day press */ - onDayPress?: (data: any) => void; + onDayPress?: (data: any) => DateData; /** callback that gets called when day changes while scrolling agenda list */ - onDaychange?: (data: any) => void; //TODO: Should be renamed 'onDayChange' + onDayChange?: (data: any) => void; /** specify how agenda knob should look like */ renderKnob?: () => JSX.Element; /** initially selected day */ @@ -95,7 +93,7 @@ export default class Agenda extends Component { /** callback that gets called on day press */ onDayPress: PropTypes.func, /** callback that gets called when day changes while scrolling agenda list */ - onDaychange: PropTypes.func, //TODO: Should be renamed 'onDayChange' + onDayChange: PropTypes.func, /** specify how agenda knob should look like */ renderKnob: PropTypes.func, /** initially selected day */ diff --git a/src/agenda/reservation-list/index.tsx b/src/agenda/reservation-list/index.tsx index b940c3d0a0..4663753ffc 100644 --- a/src/agenda/reservation-list/index.tsx +++ b/src/agenda/reservation-list/index.tsx @@ -3,7 +3,7 @@ import PropTypes from 'prop-types'; import XDate from 'xdate'; import React, {Component} from 'react'; -import {ActivityIndicator, View, FlatList, ViewStyle, TextStyle, NativeSyntheticEvent, NativeScrollEvent, LayoutChangeEvent} from 'react-native'; +import {ActivityIndicator, View, FlatList, StyleProp, ViewStyle, TextStyle, NativeSyntheticEvent, NativeScrollEvent, LayoutChangeEvent} from 'react-native'; // @ts-expect-error import {extractComponentProps} from '../../component-updater'; @@ -35,7 +35,7 @@ export type ReservationListProps = ReservationProps & { onDayChange?: (day: Date) => void; /** specify what should be rendered instead of ActivityIndicator */ renderEmptyData: () => JSX.Element; - style?: ViewStyle; + style?: StyleProp; /** onScroll ListView event */ onScroll?: (yOffset: number) => void; diff --git a/src/calendar-list/index.tsx b/src/calendar-list/index.tsx index e431b81f70..9aaeeb9d69 100644 --- a/src/calendar-list/index.tsx +++ b/src/calendar-list/index.tsx @@ -3,7 +3,7 @@ import PropTypes from 'prop-types'; import XDate from 'xdate'; import React, {Component} from 'react'; -import {FlatList, Platform, Dimensions, View, ViewStyle, LayoutChangeEvent} from 'react-native'; +import {FlatList, Platform, Dimensions, View, ViewStyle, LayoutChangeEvent, FlatListProps} from 'react-native'; // @ts-expect-error import {extractComponentProps} from '../component-updater'; @@ -24,7 +24,7 @@ const CALENDAR_HEIGHT = 360; const PAST_SCROLL_RANGE = 50; const FUTURE_SCROLL_RANGE = 50; -export type CalendarListProps = CalendarProps & { +interface Props extends CalendarProps, FlatListProps { /** Max amount of months allowed to scroll to the past. Default = 50 */ pastScrollRange?: number; /** Max amount of months allowed to scroll to the future. Default = 50 */ @@ -60,11 +60,12 @@ export type CalendarListProps = CalendarProps & { /** onLayout event */ onLayout?: (event: LayoutChangeEvent) => void; removeClippedSubviews: boolean; -}; +} +export type CalendarListProps = Props; type XDateAndBump = XDate & {propBump?: number} ; -type CalendarListState = { +type State = { rows: Array; texts: Array; openDate: XDate; @@ -78,7 +79,7 @@ type CalendarListState = { * @example: https://github.com/wix/react-native-calendars/blob/master/example/src/screens/calendarsList.js * @gif: https://github.com/wix/react-native-calendars/blob/master/demo/calendar-list.gif */ -class CalendarList extends Component { +class CalendarList extends Component { static displayName = 'CalendarList'; static propTypes = { @@ -136,7 +137,7 @@ class CalendarList extends Component { itemVisiblePercentThreshold: 20 }; - constructor(props: CalendarListProps) { + constructor(props: Props) { super(props); this.style = styleConstructor(props.theme); @@ -172,7 +173,7 @@ class CalendarList extends Component { }; } - componentDidUpdate(prevProps: CalendarListProps) { + componentDidUpdate(prevProps: Props) { const prevCurrent = parseDate(prevProps.current); const current = parseDate(this.props.current); @@ -181,7 +182,7 @@ class CalendarList extends Component { } } - static getDerivedStateFromProps(_: CalendarListProps, prevState: CalendarListState) { + static getDerivedStateFromProps(_: Props, prevState: State) { const rowClone = prevState.rows; const newRows = []; diff --git a/src/calendar/header/index.tsx b/src/calendar/header/index.tsx index 9f5e73a5db..2248e7d012 100644 --- a/src/calendar/header/index.tsx +++ b/src/calendar/header/index.tsx @@ -4,7 +4,7 @@ import memoize from 'memoize-one'; import XDate from 'xdate'; import React, {Component, Fragment, ReactNode} from 'react'; -import {ActivityIndicator, Platform, View, Text, TouchableOpacity, Image, ViewStyle, AccessibilityActionEvent, ColorValue} from 'react-native'; +import {ActivityIndicator, Platform, View, Text, TouchableOpacity, Image, StyleProp, ViewStyle, AccessibilityActionEvent, ColorValue} from 'react-native'; // @ts-expect-error import {shouldUpdate} from '../../component-updater'; // @ts-expect-error @@ -21,7 +21,7 @@ import styleConstructor from './style'; import {Theme} from '../../types'; type Direction = 'left' | 'right'; -export interface CalendarHeaderProps { +interface Props { theme?: Theme; firstDay?: number; displayLoadingIndicator?: boolean; @@ -51,12 +51,13 @@ export interface CalendarHeaderProps { /** Provide aria-level for calendar heading for proper accessibility when used with web (react-native-web) */ webAriaLevel?: number; testID?: string; - style?: ViewStyle; + style?: StyleProp; accessibilityElementsHidden?: boolean; importantForAccessibility?: 'auto' | 'yes' | 'no' | 'no-hide-descendants'; } +export type CalendarHeaderProps = Props; -class CalendarHeader extends Component { +class CalendarHeader extends Component { static displayName = 'IGNORE'; static propTypes = { @@ -96,13 +97,13 @@ class CalendarHeader extends Component { }; style: any; - constructor(props: CalendarHeaderProps) { + constructor(props: Props) { super(props); this.style = styleConstructor(props.theme); } - shouldComponentUpdate(nextProps: CalendarHeaderProps) { + shouldComponentUpdate(nextProps: Props) { if (nextProps.month?.toString('yyyy MM') !== this.props.month?.toString('yyyy MM')) { return true; } diff --git a/src/calendar/index.tsx b/src/calendar/index.tsx index 091bf2983f..dc967cb8a4 100644 --- a/src/calendar/index.tsx +++ b/src/calendar/index.tsx @@ -4,7 +4,7 @@ import XDate from 'xdate'; import memoize from 'memoize-one'; import React, {Component, RefObject} from 'react'; -import {View, ViewStyle} from 'react-native'; +import {View, ViewStyle, StyleProp} from 'react-native'; // @ts-expect-error import GestureRecognizer, {swipeDirections} from 'react-native-swipe-gestures'; @@ -19,12 +19,12 @@ import {getState} from '../day-state-manager'; import {extractComponentProps} from '../component-updater'; // @ts-expect-error import {WEEK_NUMBER} from '../testIDs'; +import {Theme, DateData} from '../types'; import styleConstructor from './style'; import CalendarHeader, {CalendarHeaderProps} from './header'; import Day, {DayProps} from './day/index'; import BasicDay from './day/basic'; import {MarkingProps} from './day/marking'; -import {Theme, DateData} from '../types'; type MarkedDatesType = { @@ -35,7 +35,7 @@ export interface CalendarProps extends CalendarHeaderProps, DayProps { /** Specify theme properties to override specific styles for calendar parts */ theme?: Theme; /** Specify style for calendar container element */ - style?: ViewStyle; + style?: StyleProp; /** Initially visible month */ current?: XDate; /** Minimum date that can be selected, dates before minDate will be grayed out */ @@ -55,7 +55,7 @@ export interface CalendarProps extends CalendarHeaderProps, DayProps { /** Always show six weeks on each month (only when hideExtraDays = false) */ showSixWeeks?: boolean; /** Handler which gets executed on day press */ - onDayPress?: (date: Date) => any; + onDayPress?: (date: Date) => DateData; /** Handler which gets executed on day long press */ onDayLongPress?: (date: Date) => any; /** Handler which gets executed when month changes in calendar */ From c7f27a80f39f4d63a5c9ba47b290f9540ee03f64 Mon Sep 17 00:00:00 2001 From: Inbal Tish Date: Mon, 9 Aug 2021 13:14:38 +0300 Subject: [PATCH 083/109] fix comment --- src/agenda/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/agenda/index.tsx b/src/agenda/index.tsx index 344402dde0..21e551814d 100644 --- a/src/agenda/index.tsx +++ b/src/agenda/index.tsx @@ -15,8 +15,8 @@ import dateutils from '../dateutils'; // @ts-expect-error import {AGENDA_CALENDAR_KNOB} from '../testIDs'; // @ts-expect-error -import {DateData} from '../types'; import {VelocityTracker} from '../input'; +import {DateData} from '../types'; import styleConstructor from './style'; import CalendarList, {CalendarListProps} from '../calendar-list'; import ReservationList, {ReservationListProps} from './reservation-list'; From c22a08aa6653701bf1eb852efca5a3028f67caa6 Mon Sep 17 00:00:00 2001 From: Lidor Dafna Date: Mon, 9 Aug 2021 13:26:19 +0300 Subject: [PATCH 084/109] Add example with inactive days --- example/src/screens/calendars.tsx | 35 ++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/example/src/screens/calendars.tsx b/example/src/screens/calendars.tsx index 598066d60b..59722dd9d6 100644 --- a/example/src/screens/calendars.tsx +++ b/example/src/screens/calendars.tsx @@ -3,7 +3,6 @@ import {StyleSheet, View, ScrollView, Text, TouchableOpacity, Switch} from 'reac // @ts-expect-error import {Calendar} from 'react-native-calendars'; - const testIDs = require('../testIDs'); const INITIAL_DATE = '2020-02-02'; @@ -24,7 +23,6 @@ const CalendarsScreen = () => { Calendar with selectable date { disableTouchEvent: true, selectedColor: 'orange', selectedTextColor: 'red' - }, - '2020-02-10': { - inactive: true - }, - '2020-02-11': { - inactive: true } }} /> @@ -390,6 +382,27 @@ const CalendarsScreen = () => { ); }; + const renderCalendarWithInactiveDays = () => { + return ( + + Calendar with inactive days + + + ); + }; + const renderMarkedDatesExamples = () => { return ( @@ -411,6 +424,7 @@ const CalendarsScreen = () => { {renderCalendarWithMinAndMaxDates()} {renderCalendarWithCustomDay()} {renderCalendarWithCustomHeader()} + {renderCalendarWithInactiveDays()} ); }; @@ -430,10 +444,7 @@ const CalendarsScreen = () => { }; return ( - + {renderSwitch()} {showMarkedDatesExamples && renderMarkedDatesExamples()} {!showMarkedDatesExamples && renderExamples()} From 61b43373f6067468d4eade191949e496b06cb11c Mon Sep 17 00:00:00 2001 From: Inbal Tish Date: Mon, 9 Aug 2021 13:42:45 +0300 Subject: [PATCH 085/109] fix for BasicDay onPress and components' `onDayPress` --- src/agenda/index.tsx | 2 +- src/calendar/day/basic/index.tsx | 5 +++-- src/calendar/index.tsx | 6 +++--- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/agenda/index.tsx b/src/agenda/index.tsx index 21e551814d..6694ce5940 100644 --- a/src/agenda/index.tsx +++ b/src/agenda/index.tsx @@ -45,7 +45,7 @@ export type AgendaProps = CalendarListProps & ReservationListProps & { /** callback that fires when the calendar is opened or closed */ onCalendarToggled?: (enabled: boolean) => void; /** callback that gets called on day press */ - onDayPress?: (data: any) => DateData; + onDayPress?: (data: DateData) => void; /** callback that gets called when day changes while scrolling agenda list */ onDayChange?: (data: any) => void; /** specify how agenda knob should look like */ diff --git a/src/calendar/day/basic/index.tsx b/src/calendar/day/basic/index.tsx index 2c3f3716f1..b20c3ce247 100644 --- a/src/calendar/day/basic/index.tsx +++ b/src/calendar/day/basic/index.tsx @@ -3,11 +3,12 @@ import PropTypes from 'prop-types'; import React, {Component, Fragment} from 'react'; import {TouchableOpacity, Text, View} from 'react-native'; + +import {Theme, DateData} from '../../../types'; // @ts-expect-error import {shouldUpdate} from '../../../component-updater'; import styleConstructor from './style'; import Marking, {MarkingTypes, MarkingProps} from '../marking'; -import {Theme} from '../../../types'; export interface BasicDayProps { state?: 'selected' | 'disabled' | 'today'; @@ -18,7 +19,7 @@ export interface BasicDayProps { /** Theme object */ theme?: Theme; /** onPress callback */ - onPress?: (date: Date) => void; + onPress?: (date: DateData) => void; /** onLongPress callback */ onLongPress?: (date: Date) => void; /** The date to return from press callbacks */ diff --git a/src/calendar/index.tsx b/src/calendar/index.tsx index dc967cb8a4..ae1ce6c592 100644 --- a/src/calendar/index.tsx +++ b/src/calendar/index.tsx @@ -55,9 +55,9 @@ export interface CalendarProps extends CalendarHeaderProps, DayProps { /** Always show six weeks on each month (only when hideExtraDays = false) */ showSixWeeks?: boolean; /** Handler which gets executed on day press */ - onDayPress?: (date: Date) => DateData; + onDayPress?: (date: DateData) => void; /** Handler which gets executed on day long press */ - onDayLongPress?: (date: Date) => any; + onDayLongPress?: (date: DateData) => void; /** Handler which gets executed when month changes in calendar */ onMonthChange?: () => DateData; /** Handler which gets executed when visible month changes in calendar */ @@ -157,7 +157,7 @@ class Calendar extends Component { }); }; - handleDayInteraction(date: Date, interaction?: (date: Date) => DateData) { + handleDayInteraction(date: Date, interaction?: (date: DateData) => void) { const {disableMonthChange} = this.props; const day = parseDate(date); const minDate = parseDate(this.props.minDate); From 9f31a535fca352be0fb48f48cf7c901d7a9eee3c Mon Sep 17 00:00:00 2001 From: Lidor Dafna Date: Mon, 9 Aug 2021 14:10:17 +0300 Subject: [PATCH 086/109] Fix bug in marking + update weekCalendar screen name --- example/src/screens/menu.js | 2 +- src/calendar/day/marking/index.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/example/src/screens/menu.js b/example/src/screens/menu.js index a5fc1fe7b0..9069c70406 100644 --- a/example/src/screens/menu.js +++ b/example/src/screens/menu.js @@ -65,7 +65,7 @@ export default class MenuScreen extends Component { options: { topBar: { title: { - text: screen + text: props?.weekView ? 'WeekCalendar' : screen }, backButton: { accessibilityLabel: 'back', diff --git a/src/calendar/day/marking/index.tsx b/src/calendar/day/marking/index.tsx index afb55eebfb..fdfafa615b 100644 --- a/src/calendar/day/marking/index.tsx +++ b/src/calendar/day/marking/index.tsx @@ -91,7 +91,7 @@ export default class Marking extends Component { if (items && Array.isArray(items) && items.length > 0) { // Filter out items so that we process only those which have color property - const validItems = _.filter(items, function(o: DOT | PERIOD) { return !o.color; }); + const validItems = _.filter(items, function(o: DOT | PERIOD) { return o.color; }); return validItems.map((item, index) => { return type === MarkingTypes.MULTI_DOT ? this.renderDot(index, item) : this.renderPeriod(index, item); From 9dc7e28cf739e22ea93967167c7d136ec13a49e0 Mon Sep 17 00:00:00 2001 From: Inbal Tish Date: Mon, 9 Aug 2021 14:32:41 +0300 Subject: [PATCH 087/109] moving Direction to types --- src/calendar/header/index.tsx | 3 +-- src/types.ts | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/calendar/header/index.tsx b/src/calendar/header/index.tsx index 2248e7d012..9a8e620905 100644 --- a/src/calendar/header/index.tsx +++ b/src/calendar/header/index.tsx @@ -18,9 +18,8 @@ import { // @ts-expect-error } from '../../testIDs'; import styleConstructor from './style'; -import {Theme} from '../../types'; +import {Theme, Direction} from '../../types'; -type Direction = 'left' | 'right'; interface Props { theme?: Theme; firstDay?: number; diff --git a/src/types.ts b/src/types.ts index 23b306debe..f526f4c47a 100644 --- a/src/types.ts +++ b/src/types.ts @@ -2,7 +2,7 @@ import { string } from 'prop-types'; import {ColorValue, ViewStyle, TextStyle} from 'react-native'; import {UPDATE_SOURCES} from './expandableCalendar/commons'; - +export type Direction = 'left' | 'right'; export type UpdateSource = keyof typeof UPDATE_SOURCES; export type DateData = { year: number, From fe650ce4778a9e3dbe7f29fdf209299847ccee1f Mon Sep 17 00:00:00 2001 From: Inbal Tish Date: Mon, 9 Aug 2021 14:38:13 +0300 Subject: [PATCH 088/109] fix `onVisibleMonthsChange` type --- src/agenda/index.tsx | 2 +- src/calendar/index.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/agenda/index.tsx b/src/agenda/index.tsx index 6694ce5940..638caca7f6 100644 --- a/src/agenda/index.tsx +++ b/src/agenda/index.tsx @@ -318,7 +318,7 @@ export default class Agenda extends Component { this.enableCalendarScrolling(snapY === 0); }; - onVisibleMonthsChange = (months: string[]) => { + onVisibleMonthsChange = (months: DateData[]) => { _.invoke(this.props, 'onVisibleMonthsChange', months); if (this.props.items && !this.state.firstReservationLoad) { diff --git a/src/calendar/index.tsx b/src/calendar/index.tsx index ae1ce6c592..0ec1cf2a00 100644 --- a/src/calendar/index.tsx +++ b/src/calendar/index.tsx @@ -61,7 +61,7 @@ export interface CalendarProps extends CalendarHeaderProps, DayProps { /** Handler which gets executed when month changes in calendar */ onMonthChange?: () => DateData; /** Handler which gets executed when visible month changes in calendar */ - onVisibleMonthsChange?: () => DateData[]; + onVisibleMonthsChange?: (months: DateData[]) => void; /** Disables changing month when click on days of other months (when hideExtraDays is false) */ disableMonthChange?: boolean; /** Enable the option to swipe between months */ From 7c218db0d5181ec6b684a5942a9bf79385531eac Mon Sep 17 00:00:00 2001 From: Inbal Tish Date: Mon, 9 Aug 2021 15:26:03 +0300 Subject: [PATCH 089/109] fix ts errors --- src/agenda/index.tsx | 2 +- src/types.ts | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/agenda/index.tsx b/src/agenda/index.tsx index 638caca7f6..bb0695a465 100644 --- a/src/agenda/index.tsx +++ b/src/agenda/index.tsx @@ -4,7 +4,7 @@ import XDate from 'xdate'; import memoize from 'memoize-one'; import React, {Component} from 'react'; -import {Text, View, Dimensions, Animated, StyleProp, ViewStyle, LayoutChangeEvent, NativeSyntheticEvent, NativeScrollEvent} from 'react-native'; +import {Text, View, Dimensions, Animated, ViewStyle, LayoutChangeEvent, NativeSyntheticEvent, NativeScrollEvent} from 'react-native'; // @ts-expect-error import {extractComponentProps} from '../component-updater.js'; diff --git a/src/types.ts b/src/types.ts index f526f4c47a..a1cf01d86b 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,7 +1,8 @@ -import { string } from 'prop-types'; import {ColorValue, ViewStyle, TextStyle} from 'react-native'; +// @ts-expect-error import {UPDATE_SOURCES} from './expandableCalendar/commons'; + export type Direction = 'left' | 'right'; export type UpdateSource = keyof typeof UPDATE_SOURCES; export type DateData = { From f857c3acd5755acb881c45347f3c4c04ad072398 Mon Sep 17 00:00:00 2001 From: Inbal Tish Date: Mon, 9 Aug 2021 16:37:34 +0300 Subject: [PATCH 090/109] podfile.lock --- ios/Podfile.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 9af25240bd..de19a258ed 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -377,10 +377,10 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c - DoubleConversion: cde416483dac037923206447da6e1454df403714 + DoubleConversion: cf9b38bf0b2d048436d9a82ad2abe1404f11e7de FBLazyVector: e686045572151edef46010a6f819ade377dfeb4b FBReactNativeSpec: 92869e54fbef651850edc0f8ad2e5e53421f5fbe - glog: 40a13f7840415b9a77023fbcae0f1e6f43192af3 + glog: 73c2498ac6884b13ede40eda8228cb1eee9d9d62 RCT-Folly: ec7a233ccc97cc556cf7237f0db1ff65b986f27c RCTRequired: 6d3e854f0e7260a648badd0d44fc364bc9da9728 RCTTypeSafety: c1f31d19349c6b53085766359caac425926fafaa From 57fbfbf056b78128c04949d57bc9906fd87b4b6d Mon Sep 17 00:00:00 2001 From: Souvik Ghosh Date: Tue, 10 Aug 2021 12:14:16 +0530 Subject: [PATCH 091/109] add onScrollToIndexFailed callback --- src/expandableCalendar/agendaList.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/expandableCalendar/agendaList.js b/src/expandableCalendar/agendaList.js index c3c2f9f4f8..610a4108ea 100644 --- a/src/expandableCalendar/agendaList.js +++ b/src/expandableCalendar/agendaList.js @@ -163,6 +163,12 @@ class AgendaList extends Component { _.invoke(this.props, 'onMomentumScrollEnd', event); }; + onScrollToIndexFailed = info => { + if (this.props.onScrollToIndexFailed) { + this.props.onScrollToIndexFailed(info); + } + }; + onHeaderLayout = ({nativeEvent}) => { this.sectionHeight = nativeEvent.layout.height; }; @@ -201,6 +207,7 @@ class AgendaList extends Component { onScroll={this.onScroll} onMomentumScrollBegin={this.onMomentumScrollBegin} onMomentumScrollEnd={this.onMomentumScrollEnd} + onScrollToIndexFailed={this.onScrollToIndexFailed} // getItemLayout={this.getItemLayout} // onViewableItemsChanged is not updated when list scrolls!!! /> ); From d221bd941cfab281a4484555ab8a9464e5408350 Mon Sep 17 00:00:00 2001 From: Souvik Ghosh Date: Tue, 10 Aug 2021 12:23:30 +0530 Subject: [PATCH 092/109] add console.warn --- src/expandableCalendar/agendaList.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/expandableCalendar/agendaList.js b/src/expandableCalendar/agendaList.js index 610a4108ea..a9109d85ed 100644 --- a/src/expandableCalendar/agendaList.js +++ b/src/expandableCalendar/agendaList.js @@ -166,6 +166,8 @@ class AgendaList extends Component { onScrollToIndexFailed = info => { if (this.props.onScrollToIndexFailed) { this.props.onScrollToIndexFailed(info); + } else { + console.warn('onScrollToIndexFailed info: ', info); } }; From 94fd761d18674a47899fe23fd358fa2fbabeb711 Mon Sep 17 00:00:00 2001 From: Inbal Tish Date: Tue, 10 Aug 2021 12:11:26 +0300 Subject: [PATCH 093/109] fix imports ts errors with // @ts-expect-error --- src/agenda/reservation-list/index.tsx | 3 +++ src/agenda/reservation-list/reservation.tsx | 3 +++ src/calendar-list/index.tsx | 3 +++ src/calendar/day/index.tsx | 4 ++++ src/calendar/index.tsx | 2 ++ 5 files changed, 15 insertions(+) diff --git a/src/agenda/reservation-list/index.tsx b/src/agenda/reservation-list/index.tsx index de43dfd1c8..eb3fbb52c9 100644 --- a/src/agenda/reservation-list/index.tsx +++ b/src/agenda/reservation-list/index.tsx @@ -7,12 +7,15 @@ import {ActivityIndicator, View, FlatList, StyleProp, ViewStyle, TextStyle, Nati // @ts-expect-error import {extractComponentProps} from '../../component-updater'; +// @ts-expect-error import {sameDate} from '../../dateutils'; +// @ts-expect-error import {toMarkingFormat} from '../../interface'; import styleConstructor from './style'; import Reservation, {ReservationProps} from './reservation'; import {ReservationItemType, ReservationsType} from 'agenda'; + export interface DayReservations { reservation?: ReservationItemType; date?: XDate; diff --git a/src/agenda/reservation-list/reservation.tsx b/src/agenda/reservation-list/reservation.tsx index acb8f8f039..047b9ad27b 100644 --- a/src/agenda/reservation-list/reservation.tsx +++ b/src/agenda/reservation-list/reservation.tsx @@ -7,12 +7,15 @@ import {View, Text} from 'react-native'; // @ts-expect-error import {xdateToData} from '../../interface'; +// @ts-expect-error import {isToday} from '../../dateutils'; +// @ts-expect-error import {RESERVATION_DATE} from '../../testIDs'; import styleConstructor from './style'; import {Theme} from '../../types'; import {DayReservations} from './index'; + export interface ReservationProps { item: DayReservations; /** Specify theme properties to override specific styles for reservation parts. Default = {} */ diff --git a/src/calendar-list/index.tsx b/src/calendar-list/index.tsx index 1120e94391..726a1c3a51 100644 --- a/src/calendar-list/index.tsx +++ b/src/calendar-list/index.tsx @@ -9,13 +9,16 @@ import {FlatList, Platform, Dimensions, View, ViewStyle, LayoutChangeEvent, Flat import {extractComponentProps} from '../component-updater'; // @ts-expect-error import {xdateToData, parseDate} from '../interface'; +// @ts-expect-error import {page, sameDate} from '../dateutils'; +// @ts-expect-error import {STATIC_HEADER} from '../testIDs'; import styleConstructor from './style'; import Calendar, {CalendarProps} from '../calendar'; import CalendarListItem from './item'; import CalendarHeader from '../calendar/header/index'; + const {width} = Dimensions.get('window'); const CALENDAR_WIDTH = width; const CALENDAR_HEIGHT = 360; diff --git a/src/calendar/day/index.tsx b/src/calendar/day/index.tsx index 6c475e7ebb..f1777d0fdd 100644 --- a/src/calendar/day/index.tsx +++ b/src/calendar/day/index.tsx @@ -4,9 +4,12 @@ import XDate from 'xdate'; import memoize from 'memoize-one'; import React, {Component} from 'react'; + // @ts-expect-error import {shouldUpdate} from '../../component-updater'; +// @ts-expect-error import {isToday as dateutils_isToday} from '../../dateutils'; +// @ts-expect-error import {xdateToData} from '../../interface'; // @ts-expect-error import {SELECT_DATE_SLOT} from '../../testIDs'; @@ -14,6 +17,7 @@ import BasicDay, {BasicDayProps} from './basic'; import PeriodDay from './period'; import {MarkingProps} from './marking'; + const basicDayPropsTypes = _.omit(BasicDay.propTypes, 'date'); export interface DayProps extends Omit { diff --git a/src/calendar/index.tsx b/src/calendar/index.tsx index 69047bd0cd..9d72e0b665 100644 --- a/src/calendar/index.tsx +++ b/src/calendar/index.tsx @@ -8,7 +8,9 @@ import {View, ViewStyle, StyleProp} from 'react-native'; // @ts-expect-error import GestureRecognizer, {swipeDirections} from 'react-native-swipe-gestures'; +// @ts-expect-error import {page, isGTE, isLTE, sameMonth} from '../dateutils'; +// @ts-expect-error import {xdateToData, parseDate, toMarkingFormat} from '../interface'; // @ts-expect-error import {getState} from '../day-state-manager'; From 1354056261ed30fd74b35971370155cfb1130108 Mon Sep 17 00:00:00 2001 From: Inbal Tish Date: Tue, 10 Aug 2021 15:33:48 +0300 Subject: [PATCH 094/109] ExpandableCalendar to ts --- ...ableCalendar.js => expandableCalendar.tsx} | 16 +- .../Context/Presenter.spec.js | 26 +- .../Context/{Presenter.js => Presenter.ts} | 43 +-- .../Context/{Provider.js => Provider.tsx} | 83 +++--- .../Context/{index.js => index.ts} | 0 .../WeekCalendar/{index.js => index.tsx} | 81 +++--- .../WeekCalendar/presenter.spec.js | 6 +- .../{presenter.js => presenter.ts} | 73 ++--- .../{agendaList.js => agendaList.tsx} | 158 ++++++----- ...ndarConsumer.js => asCalendarConsumer.tsx} | 15 +- .../{commons.js => commons.ts} | 19 +- .../{index.js => index.tsx} | 263 +++++++++++------- src/expandableCalendar/{style.js => style.ts} | 7 +- src/expandableCalendar/{week.js => week.tsx} | 30 +- src/types.ts | 1 - 15 files changed, 491 insertions(+), 330 deletions(-) rename example/src/screens/{expandableCalendar.js => expandableCalendar.tsx} (96%) rename src/expandableCalendar/Context/{Presenter.js => Presenter.ts} (58%) rename src/expandableCalendar/Context/{Provider.js => Provider.tsx} (66%) rename src/expandableCalendar/Context/{index.js => index.ts} (100%) rename src/expandableCalendar/WeekCalendar/{index.js => index.tsx} (76%) rename src/expandableCalendar/WeekCalendar/{presenter.js => presenter.ts} (61%) rename src/expandableCalendar/{agendaList.js => agendaList.tsx} (60%) rename src/expandableCalendar/{asCalendarConsumer.js => asCalendarConsumer.tsx} (51%) rename src/expandableCalendar/{commons.js => commons.ts} (69%) rename src/expandableCalendar/{index.js => index.tsx} (64%) rename src/expandableCalendar/{style.js => style.ts} (96%) rename src/expandableCalendar/{week.js => week.tsx} (81%) diff --git a/example/src/screens/expandableCalendar.js b/example/src/screens/expandableCalendar.tsx similarity index 96% rename from example/src/screens/expandableCalendar.js rename to example/src/screens/expandableCalendar.tsx index 485f334f32..c2e95b2fa3 100644 --- a/example/src/screens/expandableCalendar.js +++ b/example/src/screens/expandableCalendar.tsx @@ -1,8 +1,10 @@ import _ from 'lodash'; import React, {Component, useCallback} from 'react'; import {Platform, StyleSheet, Alert, View, Text, TouchableOpacity, Button} from 'react-native'; +// @ts-expect-error import {ExpandableCalendar, AgendaList, CalendarProvider, WeekCalendar} from 'react-native-calendars'; + const testIDs = require('../testIDs'); const today = new Date().toISOString().split('T')[0]; @@ -128,7 +130,11 @@ function getTheme() { const leftArrowIcon = require('../img/previous.png'); const rightArrowIcon = require('../img/next.png'); -export default class ExpandableCalendarScreen extends Component { +interface Props { + weekView?: boolean +} + +export default class ExpandableCalendarScreen extends Component { marked = getMarkedDates(ITEMS); theme = getTheme(); todayBtnTheme = { @@ -144,7 +150,7 @@ export default class ExpandableCalendarScreen extends Component { // console.warn('ExpandableCalendarScreen onMonthChange: ', month, updateSource); }; - renderItem = ({item}) => { + renderItem = ({item}: any) => { return ; }; @@ -191,7 +197,11 @@ export default class ExpandableCalendarScreen extends Component { } } -const AgendaItem = React.memo(function AgendaItem(props) { +interface ItemProps { + item: any +} + +const AgendaItem = React.memo(function AgendaItem(props: ItemProps) { // console.warn('item rendered', Date.now()); const {item} = props; diff --git a/src/expandableCalendar/Context/Presenter.spec.js b/src/expandableCalendar/Context/Presenter.spec.js index b2f7bf5d73..555a9910f6 100644 --- a/src/expandableCalendar/Context/Presenter.spec.js +++ b/src/expandableCalendar/Context/Presenter.spec.js @@ -3,22 +3,18 @@ import XDate from 'xdate'; import {UPDATE_SOURCES} from '../commons'; import {toMarkingFormat} from '../../interface'; + describe('Context provider tests', () => { const makeUUT = () => { return new Presenter(); }; const pastDate = '2021-04-04'; - const futureDate = '2050-04-04'; - const today1 = XDate(); - const today2 = new Date(); - const todayDate = toMarkingFormat(XDate()); - - const updateSource = UPDATE_SOURCES.CALENDAR_INIT; + const updateSources = UPDATE_SOURCES.CALENDAR_INIT; describe('isPastDate function tests', () => { it('Expect to get true while passing a past date', () => { @@ -35,7 +31,6 @@ describe('Context provider tests', () => { describe('Button Icon test', () => { it('Expect to get down button on past date', () => { const {getButtonIcon} = makeUUT(); - const imageUp = '../../../src/img/up.png'; const imageDown = '../../../src/img/down.png'; @@ -62,12 +57,12 @@ describe('Context provider tests', () => { const {setDate} = makeUUT(); const date = '2021-01-01'; const sameMonthDate = '2021-01-20'; - const props = {onDateChanged, onMonthChange, showTodayButton: false}; - setDate(props, date, sameMonthDate, updateState, updateSource); + + setDate(props, date, sameMonthDate, updateState, updateSources); expect(updateState).toBeCalled(); - expect(onDateChanged).toBeCalledWith(date, updateSource); + expect(onDateChanged).toBeCalledWith(date, updateSources); expect(onMonthChange).not.toBeCalled(); }); @@ -75,12 +70,12 @@ describe('Context provider tests', () => { const {setDate} = makeUUT(); const date = '2021-01-01'; const differentMonth = '2021-02-20'; - const props = {onDateChanged, onMonthChange, showTodayButton: false}; - setDate(props, date, differentMonth, updateState, updateSource); + + setDate(props, date, differentMonth, updateState, updateSources); expect(updateState).toBeCalled(); - expect(onDateChanged).toBeCalledWith(date, updateSource); + expect(onDateChanged).toBeCalledWith(date, updateSources); expect(onMonthChange).toBeCalled(); }); }); @@ -138,8 +133,8 @@ describe('Context provider tests', () => { it("Expect animation value to be top position when today's date passed", () => { const {getPositionAnimation} = makeUUT(); const TOP_POSITION = 65; - const {tension, friction, useNativeDriver} = getPositionAnimation(todayDate, 10); + expect(tension).toEqual(30); expect(friction).toEqual(8); expect(useNativeDriver).toBe(true); @@ -159,8 +154,8 @@ describe('Context provider tests', () => { it('Expect opacity animation value', () => { const {getOpacityAnimation} = makeUUT(); const disabledOpacity = 0.5; - let data = getOpacityAnimation({disabledOpacity}, true); + expect(data.toValue).toBe(0.5); data = getOpacityAnimation({disabledOpacity}, false); @@ -174,7 +169,6 @@ describe('Context provider tests', () => { describe('onTodayPressed tests', () => { it("Expect return value to be XDate today's date", () => { const {getTodayDate} = makeUUT(); - expect(getTodayDate()).toEqual(todayDate); }); }); diff --git a/src/expandableCalendar/Context/Presenter.js b/src/expandableCalendar/Context/Presenter.ts similarity index 58% rename from src/expandableCalendar/Context/Presenter.js rename to src/expandableCalendar/Context/Presenter.ts index 2a09f0977b..723ebe762b 100644 --- a/src/expandableCalendar/Context/Presenter.js +++ b/src/expandableCalendar/Context/Presenter.ts @@ -1,15 +1,21 @@ import _ from 'lodash'; import XDate from 'xdate'; -import {sameMonth as dateutils_sameMonth} from '../../dateutils'; + +// @ts-expect-error +import {sameMonth} from '../../dateutils'; +// @ts-expect-error import {xdateToData, toMarkingFormat} from '../../interface'; +import {CalendarContextProviderProps} from './Provider'; +import {UpdateSource} from '../../types'; + const commons = require('../commons'); const TOP_POSITION = 65; class Presenter { - _isPastDate(date) { - const today = XDate(); - const d = XDate(date); + _isPastDate(date: Date) { + const today = new XDate(); + const d = new XDate(date); if (today.getFullYear() > d.getFullYear()) { return true; @@ -35,7 +41,7 @@ class Presenter { return require('../../img/up.png'); }; - getButtonIcon = (date, showTodayButton = true) => { + getButtonIcon = (date: Date, showTodayButton = true) => { if (!showTodayButton) { return undefined; } @@ -43,40 +49,40 @@ class Presenter { return icon; }; - setDate = (props, date, newDate, updateState, updateSource) => { - const sameMonth = dateutils_sameMonth(XDate(date), XDate(newDate)); + setDate = (props: CalendarContextProviderProps, date: Date, newDate: Date, updateState: (buttonIcon: any) => any, updateSource: UpdateSource) => { + const isSameMonth = sameMonth(new XDate(date), new XDate(newDate)); const buttonIcon = this.getButtonIcon(date, props.showTodayButton); updateState(buttonIcon); _.invoke(props, 'onDateChanged', date, updateSource); - if (!sameMonth) { - _.invoke(props, 'onMonthChange', xdateToData(XDate(date)), updateSource); + if (!isSameMonth) { + _.invoke(props, 'onMonthChange', xdateToData(new XDate(date)), updateSource); } }; - setDisabled = (showTodayButton, newDisabledValue, oldDisabledValue, updateState) => { + setDisabled = (showTodayButton: boolean, newDisabledValue: boolean, oldDisabledValue: boolean, updateState: (disabled: boolean) => void) => { if (!showTodayButton || newDisabledValue === oldDisabledValue) { return; } updateState(newDisabledValue); }; - shouldAnimateTodayButton = props => { + shouldAnimateTodayButton = (props: CalendarContextProviderProps) => { return props.showTodayButton; }; - _isToday = date => { - const today = toMarkingFormat(XDate()); + _isToday = (date: Date) => { + const today = toMarkingFormat(new XDate()); return today === date; }; getTodayDate = () => { - return toMarkingFormat(XDate()); + return toMarkingFormat(new XDate()); }; - getPositionAnimation = (date, todayBottomMargin) => { + getPositionAnimation = (date: Date, todayBottomMargin = 0) => { const toValue = this._isToday(date) ? TOP_POSITION : -todayBottomMargin || -TOP_POSITION; return { toValue, @@ -86,19 +92,20 @@ class Presenter { }; }; - shouldAnimateOpacity = props => { + shouldAnimateOpacity = (props: CalendarContextProviderProps) => { return props.disabledOpacity; }; - getOpacityAnimation = (props, disabled) => { + getOpacityAnimation = (props: CalendarContextProviderProps, disabled: boolean) => { return { - toValue: disabled ? props.disabledOpacity : 1, + toValue: disabled ? props.disabledOpacity || 0 : 1, duration: 500, useNativeDriver: true }; }; getTodayFormatted = () => { + // @ts-expect-error const todayString = XDate.locales[XDate.defaultLocale].today || commons.todayString; const today = todayString.charAt(0).toUpperCase() + todayString.slice(1); return today; diff --git a/src/expandableCalendar/Context/Provider.js b/src/expandableCalendar/Context/Provider.tsx similarity index 66% rename from src/expandableCalendar/Context/Provider.js rename to src/expandableCalendar/Context/Provider.tsx index 31512a42a9..0dcce9bf2f 100644 --- a/src/expandableCalendar/Context/Provider.js +++ b/src/expandableCalendar/Context/Provider.tsx @@ -1,21 +1,46 @@ -import React, {Component} from 'react'; -import {StyleSheet, Animated, TouchableOpacity, View} from 'react-native'; import PropTypes from 'prop-types'; import XDate from 'xdate'; + +import React, {Component} from 'react'; +import {StyleSheet, Animated, TouchableOpacity, View, StyleProp, ViewStyle} from 'react-native'; + +// @ts-expect-error +import {toMarkingFormat} from '../../interface'; +import {Theme, UpdateSource, DateData} from '../../types'; import styleConstructor from '../style'; import CalendarContext from '.'; import Presenter from './Presenter'; -import {toMarkingFormat} from '../../interface'; + const commons = require('../commons'); -const UPDATE_SOURCES = commons.UPDATE_SOURCES; +const updateSources = commons.UPDATE_SOURCES; const TOP_POSITION = 65; +interface Props { + /** Initial date in 'yyyy-MM-dd' format. Default = Date() */ + date: Date; + /** Callback for date change event */ + onDateChanged?: () => Date, + /** Callback for month change event */ + onMonthChange?: () => DateData, + /** Whether to show the today button */ + showTodayButton?: boolean; + /** Today button's top position */ + todayBottomMargin?: number; + /** Today button's style */ + todayButtonStyle?: ViewStyle; + /** The opacity for the disabled today button (0-1) */ + disabledOpacity?: number; + style?: StyleProp; + theme?: Theme; +} +export type CalendarContextProviderProps = Props; + /** * @description: Calendar context provider component * @example: https://github.com/wix/react-native-calendars/blob/master/example/src/screens/expandableCalendar.js */ -class CalendarProvider extends Component { +class CalendarProvider extends Component { static displayName = 'CalendarProvider'; static propTypes = { @@ -35,26 +60,22 @@ class CalendarProvider extends Component { disabledOpacity: PropTypes.number }; - constructor(props) { - super(props); - this.style = styleConstructor(props.theme); - this.presenter = new Presenter(); - const {showTodayButton} = props; - - this.state = { - prevDate: this.props.date || toMarkingFormat(XDate()), - date: this.props.date || toMarkingFormat(XDate()), - updateSource: UPDATE_SOURCES.CALENDAR_INIT, - buttonY: new Animated.Value(-props.todayBottomMargin || -TOP_POSITION), - buttonIcon: this.presenter.getButtonIcon(props.date, showTodayButton), - disabled: false, - opacity: new Animated.Value(1) - }; - } + style = styleConstructor(this.props.theme); + presenter = new Presenter(); + + state = { + prevDate: this.props.date || toMarkingFormat(new XDate()), + date: this.props.date || toMarkingFormat(new XDate()), + updateSource: updateSources.CALENDAR_INIT, + buttonY: new Animated.Value(this.props.todayBottomMargin ? -this.props.todayBottomMargin : -TOP_POSITION), + buttonIcon: this.presenter.getButtonIcon(this.props.date, this.props.showTodayButton), + disabled: false, + opacity: new Animated.Value(1) + }; - componentDidUpdate(prevProps) { + componentDidUpdate(prevProps: Props) { if (prevProps.date !== this.props.date) { - this.setDate(this.props.date, UPDATE_SOURCES.PROP_UPDATE); + this.setDate(this.props.date, updateSources.PROP_UPDATE); } } @@ -68,10 +89,10 @@ class CalendarProvider extends Component { }; }; - setDate = (date, updateSource) => { + setDate = (date: Date, updateSource: UpdateSource) => { const {setDate} = this.presenter; - const updateState = buttonIcon => { + const updateState = (buttonIcon: any) => { this.setState({date, prevDate: this.state.date, updateSource, buttonIcon}, () => { this.animateTodayButton(date); }); @@ -80,11 +101,11 @@ class CalendarProvider extends Component { setDate(this.props, date, this.state.date, updateState, updateSource); }; - setDisabled = disabled => { + setDisabled = (disabled: boolean) => { const {setDisabled} = this.presenter; - const {showTodayButton} = this.props; + const {showTodayButton = false} = this.props; - const updateState = disabled => { + const updateState = (disabled: boolean) => { this.setState({disabled}); this.animateOpacity(disabled); }; @@ -92,7 +113,7 @@ class CalendarProvider extends Component { setDisabled(showTodayButton, disabled, this.state.disabled, updateState); }; - animateTodayButton(date) { + animateTodayButton(date: Date) { const {shouldAnimateTodayButton, getPositionAnimation} = this.presenter; if (shouldAnimateTodayButton(this.props)) { @@ -104,7 +125,7 @@ class CalendarProvider extends Component { } } - animateOpacity(disabled) { + animateOpacity(disabled: boolean) { const {shouldAnimateOpacity, getOpacityAnimation} = this.presenter; if (shouldAnimateOpacity(this.props)) { @@ -118,7 +139,7 @@ class CalendarProvider extends Component { onTodayPress = () => { const today = this.presenter.getTodayDate(); - this.setDate(today, UPDATE_SOURCES.TODAY_PRESS); + this.setDate(today, updateSources.TODAY_PRESS); }; renderTodayButton() { diff --git a/src/expandableCalendar/Context/index.js b/src/expandableCalendar/Context/index.ts similarity index 100% rename from src/expandableCalendar/Context/index.js rename to src/expandableCalendar/Context/index.ts diff --git a/src/expandableCalendar/WeekCalendar/index.js b/src/expandableCalendar/WeekCalendar/index.tsx similarity index 76% rename from src/expandableCalendar/WeekCalendar/index.js rename to src/expandableCalendar/WeekCalendar/index.tsx index 23a8a4416d..f56b48db4f 100644 --- a/src/expandableCalendar/WeekCalendar/index.js +++ b/src/expandableCalendar/WeekCalendar/index.tsx @@ -1,30 +1,48 @@ import memoize from 'memoize-one'; import PropTypes from 'prop-types'; import XDate from 'xdate'; +import {Map} from 'immutable'; import React, {Component} from 'react'; -import {FlatList, View, Text} from 'react-native'; -import {Map} from 'immutable'; +import {FlatList, View, Text, NativeSyntheticEvent, NativeScrollEvent} from 'react-native'; +// @ts-expect-error import {extractComponentProps} from '../../component-updater'; +// @ts-expect-error import {weekDayNames} from '../../dateutils'; +// @ts-expect-error import {toMarkingFormat} from '../../interface'; +import {DateData} from '../../types'; import styleConstructor from '../style'; import asCalendarConsumer from '../asCalendarConsumer'; -import CalendarList from '../../calendar-list'; +import CalendarList, {CalendarListProps} from '../../calendar-list'; import Week from '../week'; import Presenter from './presenter'; + const commons = require('../commons'); const NUMBER_OF_PAGES = 2; // must be a positive number const applyAndroidRtlFix = commons.isAndroid && commons.isRTL; +interface Props extends CalendarListProps { + /** whether to have shadow/elevation for the calendar */ + allowShadow?: boolean; + /** whether to hide the names of the week days */ + hideDayNames?: boolean; + context?: any; +} +export type WeekCalendarProps = Props; + +interface State { + items: Date[] +} + /** * @description: Week calendar component * @note: Should be wrapped with 'CalendarProvider' * @example: https://github.com/wix/react-native-calendars/blob/master/example/src/screens/expandableCalendar.js */ -class WeekCalendar extends Component { +class WeekCalendar extends Component { static displayName = 'WeekCalendar'; static propTypes = { @@ -42,23 +60,17 @@ class WeekCalendar extends Component { allowShadow: true }; - constructor(props) { - super(props); + style = styleConstructor(this.props.theme); + presenter = new Presenter(); + page = NUMBER_OF_PAGES; + // On Android+RTL there's an initial scroll that cause issues + firstAndroidRTLScrollIgnored = !applyAndroidRtlFix; - this.style = styleConstructor(props.theme); - - this.presenter = new Presenter(props); - this.list = React.createRef(); - this.page = NUMBER_OF_PAGES; - // On Android+RTL there's an initial scroll that cause issues - this.firstAndroidRTLScrollIgnored = !applyAndroidRtlFix; - - this.state = { - items: this.presenter.getDatesArray(this.props) - }; - } + state: State = { + items: this.presenter.getDatesArray(this.props) + }; - componentDidUpdate(prevProps) { + componentDidUpdate(prevProps: Props) { const {context} = this.props; const {shouldComponentUpdate, getDatesArray, scrollToIndex} = this.presenter; @@ -81,9 +93,9 @@ class WeekCalendar extends Component { return array; } - getDate(weekIndex) { - const {current, context, firstDay} = this.props; - const d = XDate(current || context.date); + getDate(weekIndex: number) { + const {current, context, firstDay = 0} = this.props; + const d = new XDate(current || context.date); // get the first day of the week as date (for the on scroll mark) let dayOfTheWeek = d.getDay(); if (dayOfTheWeek < firstDay && firstDay > 0) { @@ -100,21 +112,18 @@ class WeekCalendar extends Component { return [{width}, style]; }); - onDayPress = value => { - this.presenter.onDayPressed(this.props.context, value); + onDayPress = (value: DateData) => { + this.presenter.onDayPress(this.props.context, value); }; - onScroll = ({ - nativeEvent: { - contentOffset: {x} - } - }) => { + onScroll = (event: NativeSyntheticEvent) => { + const x = event.nativeEvent.contentOffset.x; const {onScroll} = this.presenter; const {context} = this.props; const {items} = this.state; const {containerWidth, page} = this; - const updateState = (newData, newPage) => { + const updateState = (newData: Date[], newPage: number) => { this.page = newPage; this.setState({items: [...newData]}); }; @@ -126,7 +135,7 @@ class WeekCalendar extends Component { const {items} = this.state; const {onMomentumScrollEnd} = this.presenter; - const updateItems = items => { + const updateItems = (items: Date[]) => { setTimeout(() => { this.setState({items: [...items]}); }, 100); @@ -135,7 +144,7 @@ class WeekCalendar extends Component { onMomentumScrollEnd({items, props: this.props, page: this.page, updateItems}); }; - renderItem = ({item}) => { + renderItem = ({item}: any) => { const {style, onDayPress, markedDates, firstDay, ...others} = extractComponentProps(Week, this.props); const {context} = this.props; @@ -156,7 +165,7 @@ class WeekCalendar extends Component { ); }; - getItemLayout = (data, index) => { + getItemLayout = (_: any, index: number) => { return { length: this.containerWidth, offset: this.containerWidth * index, @@ -164,13 +173,13 @@ class WeekCalendar extends Component { }; }; - keyExtractor = (item, index) => index.toString(); + keyExtractor = (_: Date, index: number) => index.toString(); renderWeekDaysNames = memoize(weekDaysNames => { - return weekDaysNames.map((day, idx) => ( + return weekDaysNames.map((day: Date, index: number) => ( { }); describe('Event - onDatePressed', () => { - it('onDayPressed', () => { + it('onDayPress', () => { const setDate = jest.fn(); const context = {date: '2021-02-02', setDate}; - const {onDayPressed} = makeUUT({context}); + const {onDayPress} = makeUUT({context}); - onDayPressed(context, {dateString: '2021-01-22'}); + onDayPress(context, {dateString: '2021-01-22'}); expect(setDate).toBeCalledWith('2021-01-22', UPDATE_SOURCES.DAY_PRESS); }); }); diff --git a/src/expandableCalendar/WeekCalendar/presenter.js b/src/expandableCalendar/WeekCalendar/presenter.ts similarity index 61% rename from src/expandableCalendar/WeekCalendar/presenter.js rename to src/expandableCalendar/WeekCalendar/presenter.ts index a60930424b..a07d929d96 100644 --- a/src/expandableCalendar/WeekCalendar/presenter.js +++ b/src/expandableCalendar/WeekCalendar/presenter.ts @@ -1,37 +1,42 @@ import _ from 'lodash'; +import XDate from 'xdate'; + import React from 'react'; + +// @ts-expect-error import {sameWeek} from '../../dateutils'; -const commons = require('../commons'); -import XDate from 'xdate'; +// @ts-expect-error import {toMarkingFormat} from '../../interface'; +import {DateData} from '../../types'; +import {WeekCalendarProps} from './index'; -const UPDATE_SOURCES = commons.UPDATE_SOURCES; + +const commons = require('../commons'); +const updateSources = commons.UPDATE_SOURCES; // must be a positive number const NUMBER_OF_PAGES = 2; class Presenter { - constructor() { - this.list = React.createRef(); - this._applyAndroidRtlFix = commons.isAndroid && commons.isRTL; - // On Android+RTL there's an initial scroll that cause issues - this._firstAndroidRTLScrollIgnored = !this._applyAndroidRtlFix; - } - scrollToIndex = animated => { - this.list.current.scrollToIndex({animated, index: NUMBER_OF_PAGES}); + private _applyAndroidRtlFix = commons.isAndroid && commons.isRTL; + // On Android+RTL there's an initial scroll that cause issues + private _firstAndroidRTLScrollIgnored = !this._applyAndroidRtlFix; + public list: React.RefObject = React.createRef(); + + scrollToIndex = (animated: boolean) => { + this.list?.current?.scrollToIndex({animated, index: NUMBER_OF_PAGES}); }; - isSameWeek = (date, prevDate, firstDay) => { + isSameWeek = (date: Date, prevDate: Date, firstDay: number) => { return sameWeek(date, prevDate, firstDay); }; // Events - - onDayPressed = (context, value) => { - _.invoke(context, 'setDate', value.dateString, UPDATE_SOURCES.DAY_PRESS); + onDayPress = (context: any, value: DateData) => { + _.invoke(context, 'setDate', value.dateString, updateSources.DAY_PRESS); }; - onScroll = ({context, updateState, x, page, items, width}) => { + onScroll = ({context, updateState, x, page, items, width}: any) => { if (!this._firstAndroidRTLScrollIgnored) { this._firstAndroidRTLScrollIgnored = true; return; @@ -40,14 +45,14 @@ class Presenter { x = this._getX(x, items?.length, width); const newPage = this._getNewPage(x, width); - if (this._shouldUpdateState(page)) { - _.invoke(context, 'setDate', items[newPage], UPDATE_SOURCES.WEEK_SCROLL); + if (this._shouldUpdateState(page, newPage)) { + _.invoke(context, 'setDate', items[newPage], updateSources.WEEK_SCROLL); const data = this._getItemsForPage(page, items); updateState(data, newPage); } }; - onMomentumScrollEnd = ({items, props, page, updateItems}) => { + onMomentumScrollEnd = ({items, props, page, updateItems}: any) => { if (this._isFirstPage(page) || this._isLastPage(page, items)) { this.scrollToIndex(false); @@ -63,16 +68,16 @@ class Presenter { } }; - shouldComponentUpdate = (context, prevContext) => { + shouldComponentUpdate = (context: any, prevContext: any) => { const {date, updateSource} = context; return ( date !== prevContext.date && - updateSource !== UPDATE_SOURCES.WEEK_SCROLL + updateSource !== updateSources.WEEK_SCROLL ); }; - getDate({current, context, firstDay}, weekIndex) { - const d = XDate(current || context.date); + getDate({current, context, firstDay = 0}: WeekCalendarProps, weekIndex: number) { + const d = new XDate(current || context.date); // get the first day of the week as date (for the on scroll mark) let dayOfTheWeek = d.getDay(); if (dayOfTheWeek < firstDay && firstDay > 0) { @@ -85,7 +90,7 @@ class Presenter { return toMarkingFormat(newDate); } - getDatesArray = args => { + getDatesArray = (args: WeekCalendarProps) => { const array = []; for (let index = -NUMBER_OF_PAGES; index <= NUMBER_OF_PAGES; index++) { const d = this.getDate(args, index); @@ -94,11 +99,11 @@ class Presenter { return array; }; - _shouldUpdateState = (page, newPage) => { + _shouldUpdateState = (page: number, newPage: number) => { return page !== newPage; }; - _getX = (x, itemsCount, containerWidth) => { + _getX = (x: number, itemsCount: number, containerWidth: number) => { if (this._applyAndroidRtlFix) { const numberOfPages = itemsCount - 1; const overallWidth = numberOfPages * containerWidth; @@ -107,47 +112,47 @@ class Presenter { return x; }; - _getNewPage = (x, containerWidth) => { + _getNewPage = (x: number, containerWidth: number) => { return Math.round(x / containerWidth); }; - _isFirstPage = page => { + _isFirstPage = (page: number) => { return page === 0; }; - _isLastPage = (page, items) => { + _isLastPage = (page: number, items: Date[]) => { return page === items.length - 1; }; - _getNexPageItems = items => { + _getNexPageItems = (items: Date[]) => { return items.map((_, i) => { const index = i <= NUMBER_OF_PAGES ? i + NUMBER_OF_PAGES : i; return items[index]; }); }; - _getFirstPageItems = items => { + _getFirstPageItems = (items: Date[]) => { return items.map((_, i) => { const index = i >= NUMBER_OF_PAGES ? i - NUMBER_OF_PAGES : i; return items[index]; }); }; - _mergeArraysFromEnd = (items, newArray) => { + _mergeArraysFromEnd = (items: Date[], newArray: Date[]) => { for (let i = NUMBER_OF_PAGES + 1; i < items.length; i++) { items[i] = newArray[i]; } return items; }; - _mergeArraysFromTop = (items, newArray) => { + _mergeArraysFromTop = (items: Date[], newArray: Date[]) => { for (let i = 0; i < NUMBER_OF_PAGES; i++) { items[i] = newArray[i]; } return items; }; - _getItemsForPage = (page, items) => { + _getItemsForPage = (page: number, items: Date[]) => { if (this._isLastPage(page, items)) { return this._getNexPageItems(items); } else if (this._isFirstPage(page)) { diff --git a/src/expandableCalendar/agendaList.js b/src/expandableCalendar/agendaList.tsx similarity index 60% rename from src/expandableCalendar/agendaList.js rename to src/expandableCalendar/agendaList.tsx index d09a050ba1..7236f32f04 100644 --- a/src/expandableCalendar/agendaList.js +++ b/src/expandableCalendar/agendaList.tsx @@ -1,15 +1,44 @@ import _ from 'lodash'; -import React, {Component} from 'react'; -import {SectionList, Text} from 'react-native'; import PropTypes from 'prop-types'; import XDate from 'xdate'; -import {isToday as dateutils_isToday} from '../dateutils'; + +import React, {Component} from 'react'; +import {Text, SectionList, SectionListProps, DefaultSectionT, SectionListData, ViewStyle, NativeSyntheticEvent, NativeScrollEvent, LayoutChangeEvent, ViewToken} from 'react-native'; + +// @ts-expect-error +import {isToday} from '../dateutils'; +// @ts-expect-error +import {getMoment} from '../momentResolver'; +import {Theme} from '../types'; import styleConstructor from './style'; import asCalendarConsumer from './asCalendarConsumer'; -import {getMoment} from '../momentResolver'; + const commons = require('./commons'); -const UPDATE_SOURCES = commons.UPDATE_SOURCES; +const updateSources = commons.UPDATE_SOURCES; + +interface Props extends SectionListProps { + /** day format in section title. Formatting values: http://arshaw.com/xdate/#Formatting */ + dayFormat?: string; + /** a function to custom format the section header's title */ + dayFormatter?: (arg0: string) => string; + /** whether to use moment.js for date string formatting + * (remember to pass 'dayFormat' with appropriate format, like 'dddd, MMM D') */ + useMoment?: boolean; + /** whether to mark today's title with the "Today, ..." string. Default = true */ + markToday?: boolean; + /** style passed to the section view */ + sectionStyle?: ViewStyle; + /** whether to block the date change in calendar (and calendar context provider) when agenda scrolls */ + avoidDateUpdates?: boolean; + /** offset scroll to section */ + viewOffset?: number; + theme?: Theme; + context?: any; +} +export type AgendaListProps = Props; + +interface State {} /** * @description: AgendaList component @@ -17,11 +46,11 @@ const UPDATE_SOURCES = commons.UPDATE_SOURCES; * @extends: SectionList * @example: https://github.com/wix/react-native-calendars/blob/master/example/src/screens/expandableCalendar.js */ -class AgendaList extends Component { +class AgendaList extends Component { static displayName = 'AgendaList'; static propTypes = { - ...SectionList.propTypes, + // ...SectionList.propTypes, /** day format in section title. Formatting values: http://arshaw.com/xdate/#Formatting */ dayFormat: PropTypes.string, /** a function to custom format the section header's title */ @@ -43,54 +72,54 @@ class AgendaList extends Component { markToday: true }; - constructor(props) { - super(props); - this.style = styleConstructor(props.theme); - - this._topSection = _.get(props, 'sections[0].title'); - this.didScroll = false; - this.sectionScroll = false; - - this.viewabilityConfig = { - itemVisiblePercentThreshold: 20 // 50 means if 50% of the item is visible - }; - this.list = React.createRef(); - } - - getSectionIndex(date) { - let i; - _.map(this.props.sections, (section, index) => { - // NOTE: sections titles should match current date format!!! - if (section.title === date) { - i = index; - return; - } - }); - return i; - } + style = styleConstructor(this.props.theme); + _topSection = _.get(this.props, 'sections[0].title'); + didScroll = false; + sectionScroll = false; + viewabilityConfig = { + itemVisiblePercentThreshold: 20 // 50 means if 50% of the item is visible + }; + list: React.RefObject = React.createRef(); + sectionHeight = 0; componentDidMount() { const {date} = this.props.context; if (date !== this._topSection) { setTimeout(() => { const sectionIndex = this.getSectionIndex(date); - this.scrollToSection(sectionIndex); + if (sectionIndex) { + this.scrollToSection(sectionIndex); + } }, 500); } } - componentDidUpdate(prevProps) { + componentDidUpdate(prevProps: Props) { const {updateSource, date} = this.props.context; if (date !== prevProps.context.date) { // NOTE: on first init data should set first section to the current date!!! - if (updateSource !== UPDATE_SOURCES.LIST_DRAG && updateSource !== UPDATE_SOURCES.CALENDAR_INIT) { + if (updateSource !== updateSources.LIST_DRAG && updateSource !== updateSources.CALENDAR_INIT) { const sectionIndex = this.getSectionIndex(date); - this.scrollToSection(sectionIndex); + if (sectionIndex) { + this.scrollToSection(sectionIndex); + } } } } - getSectionTitle(title) { + getSectionIndex(date: Date) { + let i; + _.map(this.props.sections, (section, index) => { + // NOTE: sections titles should match current date format!!! + if (section.title === date) { + i = index; + return; + } + }); + return i; + } + + getSectionTitle(title: string) { if (!title) return; const {dayFormatter, dayFormat, useMoment, markToday} = this.props; @@ -103,81 +132,84 @@ class AgendaList extends Component { const moment = getMoment(); sectionTitle = moment(title).format(dayFormat); } else { - sectionTitle = XDate(title).toString(dayFormat); + sectionTitle = new XDate(title).toString(dayFormat); } } if (markToday) { + // @ts-expect-error const todayString = XDate.locales[XDate.defaultLocale].today || commons.todayString; - const isToday = dateutils_isToday(XDate(title)); - sectionTitle = isToday ? `${todayString}, ${sectionTitle}` : sectionTitle; + const today = isToday(new XDate(title)); + sectionTitle = today ? `${todayString}, ${sectionTitle}` : sectionTitle; } return sectionTitle; } - scrollToSection(sectionIndex) { - if (this.list.current && sectionIndex !== undefined) { + scrollToSection(sectionIndex: number) { + if (this.list?.current && sectionIndex !== undefined) { + const {sections, viewOffset = 0} = this.props; this.sectionScroll = true; // to avoid setDate() in onViewableItemsChanged - this._topSection = this.props.sections[sectionIndex].title; + this._topSection = sections[sectionIndex].title; this.list.current.scrollToLocation({ animated: true, sectionIndex: sectionIndex, itemIndex: 0, viewPosition: 0, // position at the top - viewOffset: (commons.isAndroid ? this.sectionHeight : 0) + this.props.viewOffset + viewOffset: (commons.isAndroid ? this.sectionHeight : 0) + viewOffset }); } } - onViewableItemsChanged = ({viewableItems}) => { - if (viewableItems && !this.sectionScroll) { - const topSection = _.get(viewableItems[0], 'section.title'); + onViewableItemsChanged = ((info: {viewableItems: Array; changed: Array}) => { + if (info?.viewableItems && !this.sectionScroll) { + const topSection = _.get(info?.viewableItems[0], 'section.title'); if (topSection && topSection !== this._topSection) { this._topSection = topSection; if (this.didScroll && !this.props.avoidDateUpdates) { // to avoid setDate() on first load (while setting the initial context.date value) - _.invoke(this.props.context, 'setDate', this._topSection, UPDATE_SOURCES.LIST_DRAG); + _.invoke(this.props.context, 'setDate', this._topSection, updateSources.LIST_DRAG); } } } - }; + }); - onScroll = event => { + onScroll = (event: NativeSyntheticEvent) => { if (!this.didScroll) { this.didScroll = true; } _.invoke(this.props, 'onScroll', event); }; - onMomentumScrollBegin = event => { + onMomentumScrollBegin = (event: NativeSyntheticEvent) => { _.invoke(this.props.context, 'setDisabled', true); _.invoke(this.props, 'onMomentumScrollBegin', event); }; - onMomentumScrollEnd = event => { + onMomentumScrollEnd = (event: NativeSyntheticEvent) => { // when list momentum ends AND when scrollToSection scroll ends this.sectionScroll = false; _.invoke(this.props.context, 'setDisabled', false); _.invoke(this.props, 'onMomentumScrollEnd', event); }; - onScrollToIndexFailed = info => { - if (this.props.onScrollToIndexFailed) { - this.props.onScrollToIndexFailed(info); - } else { - console.warn('onScrollToIndexFailed info: ', info); - } + onScrollToIndexFailed = (info: { + index: number; + highestMeasuredFrameIndex: number; + averageItemLength: number; +}) => { + console.warn('onScrollToIndexFailed info: ', info); }; - onHeaderLayout = ({nativeEvent}) => { - this.sectionHeight = nativeEvent.layout.height; + onHeaderLayout = (event: LayoutChangeEvent) => { + this.sectionHeight = event.nativeEvent.layout.height; }; - renderSectionHeader = ({section: {title}}) => { + renderSectionHeader = (info: {section: SectionListData}) => { const {renderSectionHeader, sectionStyle} = this.props; - + const title = info?.section?.title; + if (renderSectionHeader) { return renderSectionHeader(title); } @@ -189,7 +221,7 @@ class AgendaList extends Component { ); }; - keyExtractor = (item, index) => { + keyExtractor = (item: any, index: number) => { const {keyExtractor} = this.props; return _.isFunction(keyExtractor) ? keyExtractor(item, index) : String(index); }; diff --git a/src/expandableCalendar/asCalendarConsumer.js b/src/expandableCalendar/asCalendarConsumer.tsx similarity index 51% rename from src/expandableCalendar/asCalendarConsumer.js rename to src/expandableCalendar/asCalendarConsumer.tsx index 3daaad2335..2d21ab9544 100644 --- a/src/expandableCalendar/asCalendarConsumer.js +++ b/src/expandableCalendar/asCalendarConsumer.tsx @@ -1,13 +1,22 @@ -import React, {Component} from 'react'; +import React, {Component, Ref} from 'react'; +// @ts-expect-error import hoistNonReactStatic from 'hoist-non-react-statics'; import CalendarContext from './Context'; -function asCalendarConsumer(WrappedComponent) { + +function asCalendarConsumer(WrappedComponent: React.ComponentType): React.ComponentClass { + class CalendarConsumer extends Component { + contentRef: any; + + saveRef = (r: Ref>) => { + this.contentRef = r; + }; + render() { return ( - {context => (this.contentRef = r)} context={context} {...this.props} />} + {context => } ); } diff --git a/src/expandableCalendar/commons.js b/src/expandableCalendar/commons.ts similarity index 69% rename from src/expandableCalendar/commons.js rename to src/expandableCalendar/commons.ts index 438bab2fdf..606fc6718e 100644 --- a/src/expandableCalendar/commons.js +++ b/src/expandableCalendar/commons.ts @@ -8,15 +8,16 @@ export const isIos = Platform.OS === 'ios'; export const screenWidth = width; export const screenHeight = height; export const screenAspectRatio = screenWidth < screenHeight ? screenHeight / screenWidth : screenWidth / screenHeight; +// @ts-expect-error export const isTablet = Platform.isPad || (screenAspectRatio < 1.6 && Math.max(screenWidth, screenHeight) >= 900); export const todayString = 'today'; -export const UPDATE_SOURCES = { - CALENDAR_INIT: 'calendarInit', - TODAY_PRESS: 'todayPress', - LIST_DRAG: 'listDrag', - DAY_PRESS: 'dayPress', - PAGE_SCROLL: 'pageScroll', - WEEK_SCROLL: 'weekScroll', - PROP_UPDATE: 'propUpdate' -}; +export enum UPDATE_SOURCES { + CALENDAR_INIT = 'calendarInit', + TODAY_PRESS = 'todayPress', + LIST_DRAG = 'listDrag', + DAY_PRESS = 'dayPress', + PAGE_SCROLL = 'pageScroll', + WEEK_SCROLL = 'weekScroll', + PROP_UPDATE = 'propUpdate' +} diff --git a/src/expandableCalendar/index.js b/src/expandableCalendar/index.tsx similarity index 64% rename from src/expandableCalendar/index.js rename to src/expandableCalendar/index.tsx index 7f9eaf23d1..ebb2cef719 100644 --- a/src/expandableCalendar/index.js +++ b/src/expandableCalendar/index.tsx @@ -4,24 +4,29 @@ import memoize from 'memoize-one'; import XDate from 'xdate'; import React, {Component} from 'react'; -import {AccessibilityInfo, PanResponder, Animated, View, Text, Image} from 'react-native'; +import {AccessibilityInfo, PanResponder, Animated, View, ViewStyle, Text, Image, ImageSourcePropType, PanResponderInstance, GestureResponderEvent, PanResponderGestureState} from 'react-native'; +// @ts-expect-error import {CALENDAR_KNOB} from '../testIDs'; +// @ts-expect-error import {page, weekDayNames} from '../dateutils'; +// @ts-expect-error import {parseDate, toMarkingFormat} from '../interface'; +import {Theme, DateData, Direction} from 'types'; import styleConstructor, {HEADER_HEIGHT} from './style'; -import CalendarList from '../calendar-list'; +import CalendarList, {CalendarListProps} from '../calendar-list'; import Calendar from '../calendar'; import asCalendarConsumer from './asCalendarConsumer'; import WeekCalendar from './WeekCalendar'; import Week from './week'; + const commons = require('./commons'); -const UPDATE_SOURCES = commons.UPDATE_SOURCES; -const POSITIONS = { - CLOSED: 'closed', - OPEN: 'open' -}; +const updateSources = commons.UPDATE_SOURCES; +enum Positions { + CLOSED = 'closed', + OPEN = 'open' +} const SPEED = 20; const BOUNCINESS = 6; const CLOSED_HEIGHT = 120; // header + 1 week @@ -29,6 +34,41 @@ const WEEK_HEIGHT = 46; const KNOB_CONTAINER_HEIGHT = 20; const DAY_NAMES_PADDING = 24; const PAN_GESTURE_THRESHOLD = 30; +const LEFT_ARROW = require('../calendar/img/previous.png'); +const RIGHT_ARROW = require('../calendar/img/next.png'); + + +export interface Props extends CalendarListProps { + /** the initial position of the calendar ('open' or 'closed') */ + initialPosition?: Positions; + /** callback that fires when the calendar is opened or closed */ + onCalendarToggled?: () => boolean; + /** an option to disable the pan gesture and disable the opening and closing of the calendar (initialPosition will persist)*/ + disablePan?: boolean; + /** whether to hide the knob */ + hideKnob?: boolean; + /** source for the left arrow image */ + leftArrowImageSource?: ImageSourcePropType; + /** source for the right arrow image */ + rightArrowImageSource?: ImageSourcePropType; + /** whether to have shadow/elevation for the calendar */ + allowShadow?: boolean; + /** whether to disable the week scroll in closed position */ + disableWeekScroll?: boolean; + /** a threshold for opening the calendar with the pan gesture */ + openThreshold?: number; + /** a threshold for closing the calendar with the pan gesture */ + closeThreshold?: number; + context?: any; +} +export type ExpandableCalendarProps = Props; + +interface State { + deltaY: Animated.Value; + headerDeltaY: Animated.Value; + position: Positions; + screenReaderEnabled: boolean; +} /** * @description: Expandable calendar component @@ -37,13 +77,13 @@ const PAN_GESTURE_THRESHOLD = 30; * @extendslink: docs/CalendarList * @example: https://github.com/wix/react-native-calendars/blob/master/example/src/screens/expandableCalendar.js */ -class ExpandableCalendar extends Component { +class ExpandableCalendar extends Component { static displayName = 'ExpandableCalendar'; static propTypes = { ...CalendarList.propTypes, /** the initial position of the calendar ('open' or 'closed') */ - initialPosition: PropTypes.oneOf(_.values(POSITIONS)), + initialPosition: PropTypes.oneOf(_.values(Positions)), /** callback that fires when the calendar is opened or closed */ onCalendarToggled: PropTypes.func, /** an option to disable the pan gesture and disable the opening and closing of the calendar (initialPosition will persist)*/ @@ -66,50 +106,74 @@ class ExpandableCalendar extends Component { static defaultProps = { horizontal: true, - initialPosition: POSITIONS.CLOSED, + initialPosition: Positions.CLOSED, firstDay: 0, - leftArrowImageSource: require('../calendar/img/previous.png'), - rightArrowImageSource: require('../calendar/img/next.png'), + leftArrowImageSource: LEFT_ARROW, + rightArrowImageSource: RIGHT_ARROW, allowShadow: true, openThreshold: PAN_GESTURE_THRESHOLD, closeThreshold: PAN_GESTURE_THRESHOLD }; - static positions = POSITIONS; + static positions = Positions; - constructor(props) { + style = styleConstructor(this.props.theme); + panResponder: PanResponderInstance; + closedHeight: number; + numberOfWeeks: number; + openHeight: number; + _height: number; + _wrapperStyles: { + style: ViewStyle; + } + _headerStyles: { + style: ViewStyle; + }; + _weekCalendarStyles: { + style: ViewStyle; + }; + visibleMonth: any; + initialDate: XDate; + headerStyleOverride: Theme; + header: React.RefObject = React.createRef(); + wrapper: React.RefObject = React.createRef(); + calendar: React.RefObject = React.createRef(); + weekCalendar: React.RefObject = React.createRef(); + + constructor(props: Props) { super(props); - - this.style = styleConstructor(props.theme); + this.closedHeight = CLOSED_HEIGHT + (props.hideKnob ? 0 : KNOB_CONTAINER_HEIGHT); - this.numberOfWeeks = this.getNumberOfWeeksInMonth(XDate(this.props.context.date)); + this.numberOfWeeks = this.getNumberOfWeeksInMonth(new XDate(this.props.context.date)); this.openHeight = this.getOpenHeight(); - const startHeight = props.initialPosition === POSITIONS.CLOSED ? this.closedHeight : this.openHeight; + const startHeight = props.initialPosition === Positions.CLOSED ? this.closedHeight : this.openHeight; this._height = startHeight; this._wrapperStyles = {style: {height: startHeight}}; - this._headerStyles = {style: {top: props.initialPosition === POSITIONS.CLOSED ? 0 : -HEADER_HEIGHT}}; + this._headerStyles = {style: {top: props.initialPosition === Positions.CLOSED ? 0 : -HEADER_HEIGHT}}; this._weekCalendarStyles = {style: {}}; - this.wrapper = undefined; - this.calendar = undefined; this.visibleMonth = this.getMonth(this.props.context.date); - this.initialDate = props.context.date; // should be set only once!!! + this.initialDate = new XDate(props.context.date); // should be set only once!!! this.headerStyleOverride = { - 'stylesheet.calendar.header': { - week: { - marginTop: 7, - marginBottom: -4, // reduce space between dayNames and first line of dates - flexDirection: 'row', - justifyContent: 'space-around' + stylesheet: { + calendar: { + header: { + week: { + marginTop: 7, + marginBottom: -4, // reduce space between dayNames and first line of dates + flexDirection: 'row', + justifyContent: 'space-around' + } + } } } }; this.state = { deltaY: new Animated.Value(startHeight), - headerDeltaY: new Animated.Value(props.initialPosition === POSITIONS.CLOSED ? 0 : -HEADER_HEIGHT), - position: props.initialPosition, + headerDeltaY: new Animated.Value(props.initialPosition === Positions.CLOSED ? 0 : -HEADER_HEIGHT), + position: props.initialPosition || Positions.CLOSED, screenReaderEnabled: false }; @@ -133,7 +197,7 @@ class ExpandableCalendar extends Component { } } - componentDidUpdate(prevProps) { + componentDidUpdate(prevProps: Props) { const {date} = this.props.context; if (date !== prevProps.context.date) { // date was changed from AgendaList, arrows or scroll @@ -141,41 +205,40 @@ class ExpandableCalendar extends Component { } } - handleScreenReaderStatus = screenReaderEnabled => { + handleScreenReaderStatus = (screenReaderEnabled: any) => { this.setState({screenReaderEnabled}); }; updateNativeStyles() { - this.wrapper?.setNativeProps(this._wrapperStyles); + this.wrapper?.current?.setNativeProps(this._wrapperStyles); + if (!this.props.horizontal) { - this.header && this.header.setNativeProps(this._headerStyles); + this.header?.current?.setNativeProps(this._headerStyles); } else { - this.weekCalendar && this.weekCalendar.setNativeProps(this._weekCalendarStyles); + this.weekCalendar?.current?.setNativeProps(this._weekCalendarStyles); } } /** Scroll */ - scrollToDate(date) { - if (this.calendar) { - if (!this.props.horizontal) { - this.calendar.scrollToDay(XDate(date), 0, true); - } else if (this.getMonth(date) !== this.visibleMonth) { - // don't scroll if the month is already visible - this.calendar.scrollToMonth(XDate(date)); - } + scrollToDate(date: Date) { + if (!this.props.horizontal) { + this.calendar?.current?.scrollToDay(new XDate(date), 0, true); + } else if (this.getMonth(date) !== this.visibleMonth) { + // don't scroll if the month is already visible + this.calendar?.current?.scrollToMonth(new XDate(date)); } } - scrollPage(next) { + scrollPage(next: boolean) { if (this.props.horizontal) { const d = parseDate(this.props.context.date); - if (this.state.position === POSITIONS.OPEN) { + if (this.state.position === Positions.OPEN) { d.setDate(1); d.addMonths(next ? 1 : -1); } else { - const {firstDay} = this.props; + const {firstDay = 0} = this.props; let dayOfTheWeek = d.getDay(); if (dayOfTheWeek < firstDay && firstDay > 0) { dayOfTheWeek = 7 + dayOfTheWeek; @@ -183,7 +246,7 @@ class ExpandableCalendar extends Component { const firstDayOfWeek = (next ? 7 : -7) - dayOfTheWeek + firstDay; d.addDays(firstDayOfWeek); } - _.invoke(this.props.context, 'setDate', toMarkingFormat(d), UPDATE_SOURCES.PAGE_SCROLL); + _.invoke(this.props.context, 'setDate', toMarkingFormat(d), updateSources.PAGE_SCROLL); } } @@ -195,18 +258,18 @@ class ExpandableCalendar extends Component { return CLOSED_HEIGHT + WEEK_HEIGHT * (this.numberOfWeeks - 1) + (this.props.hideKnob ? 12 : KNOB_CONTAINER_HEIGHT); } - getYear(date) { - const d = XDate(date); + getYear(date: Date) { + const d = new XDate(date); return d.getFullYear(); } - getMonth(date) { - const d = XDate(date); + getMonth(date: Date) { + const d = new XDate(date); // getMonth() returns the month of the year (0-11). Value is zero-index, meaning Jan=0, Feb=1, Mar=2, etc. return d.getMonth() + 1; } - getNumberOfWeeksInMonth(month) { + getNumberOfWeeksInMonth(month: XDate) { const days = page(month, this.props.firstDay); return days.length / 7; } @@ -218,36 +281,38 @@ class ExpandableCalendar extends Component { return this.props.hideArrows || false; } - isLaterDate(date1, date2) { - if (date1.year > this.getYear(date2)) { - return true; - } - if (date1.year === this.getYear(date2)) { - if (date1.month > this.getMonth(date2)) { + isLaterDate(date1?: DateData, date2?: Date) { + if (date1 && date2) { + if (date1.year > this.getYear(date2)) { return true; } + if (date1.year === this.getYear(date2)) { + if (date1.month > this.getMonth(date2)) { + return true; + } + } } return false; } /** Pan Gesture */ - handleMoveShouldSetPanResponder = (e, gestureState) => { + handleMoveShouldSetPanResponder = (_: GestureResponderEvent, gestureState: PanResponderGestureState) => { if (this.props.disablePan) { return false; } - if (!this.props.horizontal && this.state.position === POSITIONS.OPEN) { + if (!this.props.horizontal && this.state.position === Positions.OPEN) { // disable pan detection when vertical calendar is open to allow calendar scroll return false; } - if (this.state.position === POSITIONS.CLOSED && gestureState.dy < 0) { + if (this.state.position === Positions.CLOSED && gestureState.dy < 0) { // disable pan detection to limit to closed height return false; } return gestureState.dy > 5 || gestureState.dy < -5; }; handlePanResponderGrant = () => {}; - handlePanResponderMove = (e, gestureState) => { + handlePanResponderMove = (_: GestureResponderEvent, gestureState: PanResponderGestureState) => { // limit min height to closed height this._wrapperStyles.style.height = Math.max(this.closedHeight, this._height + gestureState.dy); @@ -256,7 +321,7 @@ class ExpandableCalendar extends Component { this._headerStyles.style.top = Math.min(Math.max(-gestureState.dy, -HEADER_HEIGHT), 0); } else { // horizontal Week view - if (this.state.position === POSITIONS.CLOSED) { + if (this.state.position === Positions.CLOSED) { this._weekCalendarStyles.style.opacity = Math.min(1, Math.max(1 - gestureState.dy / 100, 0)); } } @@ -264,18 +329,18 @@ class ExpandableCalendar extends Component { this.updateNativeStyles(); }; handlePanResponderEnd = () => { - this._height = this._wrapperStyles.style.height; + this._height = Number(this._wrapperStyles.style.height); this.bounceToPosition(); }; /** Animated */ - bounceToPosition(toValue) { + bounceToPosition(toValue = 0) { if (!this.props.disablePan) { const {deltaY, position} = this.state; - const {openThreshold, closeThreshold} = this.props; + const {openThreshold = PAN_GESTURE_THRESHOLD, closeThreshold = PAN_GESTURE_THRESHOLD} = this.props; const threshold = - position === POSITIONS.OPEN ? this.openHeight - closeThreshold : this.closedHeight + openThreshold; + position === Positions.OPEN ? this.openHeight - closeThreshold : this.closedHeight + openThreshold; let isOpen = this._height >= threshold; const newValue = isOpen ? this.openHeight : this.closedHeight; @@ -299,26 +364,26 @@ class ExpandableCalendar extends Component { } } - onAnimatedFinished = ({finished}) => { - if (finished) { + onAnimatedFinished = (result: {finished: boolean}) => { + if (result?.finished) { // this.setPosition(); } }; setPosition() { const isClosed = this._height === this.closedHeight; - this.setState({position: isClosed ? POSITIONS.CLOSED : POSITIONS.OPEN}); + this.setState({position: isClosed ? Positions.CLOSED : Positions.OPEN}); } - resetWeekCalendarOpacity(isOpen) { + resetWeekCalendarOpacity(isOpen: boolean) { this._weekCalendarStyles.style.opacity = isOpen ? 0 : 1; this.updateNativeStyles(); } - closeHeader(isOpen) { + closeHeader(isOpen: boolean) { const {headerDeltaY} = this.state; - headerDeltaY.setValue(this._headerStyles.style.top); // set the start position for the animated value + headerDeltaY.setValue(Number(this._headerStyles.style.top)); // set the start position for the animated value if (!this.props.horizontal && !isOpen) { Animated.spring(headerDeltaY, { @@ -342,13 +407,13 @@ class ExpandableCalendar extends Component { this.scrollPage(true); }; - onDayPress = value => { + onDayPress = (value: DateData) => { // {year: 2019, month: 4, day: 22, timestamp: 1555977600000, dateString: "2019-04-23"} - _.invoke(this.props.context, 'setDate', value.dateString, UPDATE_SOURCES.DAY_PRESS); + _.invoke(this.props.context, 'setDate', value.dateString, updateSources.DAY_PRESS); setTimeout(() => { // to allows setDate to be completed - if (this.state.position === POSITIONS.OPEN) { + if (this.state.position === Positions.OPEN) { this.bounceToPosition(this.closedHeight); } }, 0); @@ -358,15 +423,14 @@ class ExpandableCalendar extends Component { } }; - onVisibleMonthsChange = value => { - const month = _.first(value) && _.first(value).month; - if (month && this.visibleMonth !== month) { - this.visibleMonth = month; // equivalent to this.getMonth(value[0].dateString) + onVisibleMonthsChange = (value: DateData[]) => { + if (this.visibleMonth !== _.first(value)?.month) { + this.visibleMonth = _.first(value)?.month; // equivalent to this.getMonth(value[0].dateString) // for horizontal scroll const {date, updateSource} = this.props.context; - if (this.visibleMonth !== this.getMonth(date) && updateSource !== UPDATE_SOURCES.DAY_PRESS) { + if (this.visibleMonth !== this.getMonth(date) && updateSource !== updateSources.DAY_PRESS) { const next = this.isLaterDate(_.first(value), date); this.scrollPage(next); } @@ -378,7 +442,7 @@ class ExpandableCalendar extends Component { if (numberOfWeeks !== this.numberOfWeeks) { this.numberOfWeeks = numberOfWeeks; this.openHeight = this.getOpenHeight(); - if (this.state.position === POSITIONS.OPEN) { + if (this.state.position === Positions.OPEN) { this.bounceToPosition(this.openHeight); } } @@ -400,7 +464,7 @@ class ExpandableCalendar extends Component { renderWeekDaysNames = memoize((weekDaysNames, calendarStyle) => { return ( - {weekDaysNames.map((day, index) => ( + {weekDaysNames.map((day: string, index: number) => ( {day} @@ -410,12 +474,12 @@ class ExpandableCalendar extends Component { }); renderHeader() { - const monthYear = XDate(this.props.context.date).toString('MMMM yyyy'); + const monthYear = new XDate(this.props.context.date).toString('MMMM yyyy'); const weekDaysNames = weekDayNames(this.props.firstDay); return ( (this.header = e)} + ref={this.header} style={[this.style.header, {height: HEADER_HEIGHT, top: this.state.headerDeltaY}]} pointerEvents={'none'} > @@ -431,19 +495,20 @@ class ExpandableCalendar extends Component { const {position} = this.state; const {disableWeekScroll} = this.props; const WeekComponent = disableWeekScroll ? Week : WeekCalendar; - + const weekCalendarProps = disableWeekScroll ? undefined : {allowShadow: false}; + return ( (this.weekCalendar = e)} - style={[this.style.weekContainer, position === POSITIONS.OPEN ? this.style.hidden : this.style.visible]} - pointerEvents={position === POSITIONS.CLOSED ? 'auto' : 'none'} + ref={this.weekCalendar} + style={[this.style.weekContainer, position === Positions.OPEN ? this.style.hidden : this.style.visible]} + pointerEvents={position === Positions.CLOSED ? 'auto' : 'none'} > { - if (_.isFunction(this.props.renderArrow)) { - return this.props.renderArrow(direction); + renderArrow = (direction: Direction) => { + const {renderArrow, rightArrowImageSource = RIGHT_ARROW, leftArrowImageSource = LEFT_ARROW, testID} = this.props; + + if (_.isFunction(renderArrow)) { + return renderArrow(direction); } return ( ); }; @@ -478,7 +545,7 @@ class ExpandableCalendar extends Component { render() { const {style, hideKnob, horizontal, allowShadow, theme, ...others} = this.props; const {deltaY, position, screenReaderEnabled} = this.state; - const isOpen = position === POSITIONS.OPEN; + const isOpen = position === Positions.OPEN; const themeObject = Object.assign(this.headerStyleOverride, theme); return ( @@ -493,13 +560,13 @@ class ExpandableCalendar extends Component { renderArrow={this.renderArrow} /> ) : ( - (this.wrapper = e)} style={{height: deltaY}} {...this.panResponder.panHandlers}> + (this.calendar = r)} + ref={this.calendar} current={this.initialDate} onDayPress={this.onDayPress} onVisibleMonthsChange={this.onVisibleMonthsChange} diff --git a/src/expandableCalendar/style.js b/src/expandableCalendar/style.ts similarity index 96% rename from src/expandableCalendar/style.js rename to src/expandableCalendar/style.ts index 2e13abf923..4b6aa65dce 100644 --- a/src/expandableCalendar/style.js +++ b/src/expandableCalendar/style.ts @@ -1,11 +1,12 @@ import {StyleSheet, Platform} from 'react-native'; import * as defaultStyle from '../style'; +import {Theme} from '../types'; + const commons = require('./commons'); -const STYLESHEET_ID = 'stylesheet.expandable.main'; export const HEADER_HEIGHT = 68; -export default function styleConstructor(theme = {}) { +export default function styleConstructor(theme: Theme = {}) { const appStyle = {...defaultStyle, ...theme}; return StyleSheet.create({ @@ -170,6 +171,6 @@ export default function styleConstructor(theme = {}) { marginLeft: appStyle.todayButtonPosition === 'right' ? 7 : undefined, marginRight: appStyle.todayButtonPosition === 'right' ? undefined : 7 }, - ...(theme[STYLESHEET_ID] || {}) + ...(theme?.stylesheet?.expandable?.main || {}) }); } diff --git a/src/expandableCalendar/week.js b/src/expandableCalendar/week.tsx similarity index 81% rename from src/expandableCalendar/week.js rename to src/expandableCalendar/week.tsx index 4b669aed3b..be5a697992 100644 --- a/src/expandableCalendar/week.js +++ b/src/expandableCalendar/week.tsx @@ -3,31 +3,37 @@ import PropTypes from 'prop-types'; import React, {PureComponent} from 'react'; import {View} from 'react-native'; +// @ts-expect-error import {getWeekDates, sameMonth} from '../dateutils'; +// @ts-expect-error import {parseDate, toMarkingFormat} from '../interface'; +// @ts-expect-error import {getState} from '../day-state-manager'; +// @ts-expect-error import {extractComponentProps} from '../component-updater'; import styleConstructor from './style'; -import Calendar from '../calendar'; +import Calendar, {CalendarProps} from '../calendar'; import Day from '../calendar/day/index'; // import BasicDay from '../calendar/day/basic'; -class Week extends PureComponent { + +interface Props extends CalendarProps { + current: XDate +} +export type WeekProps = Props; + + +class Week extends PureComponent { static displayName = 'IGNORE'; static propTypes = { ...Calendar.propTypes, - /** the current date */ current: PropTypes.any }; - constructor(props) { - super(props); - - this.style = styleConstructor(props.theme); - } + style = styleConstructor(this.props.theme); - getWeek(date) { + getWeek(date: XDate) { return getWeekDates(date, this.props.firstDay); } @@ -35,7 +41,7 @@ class Week extends PureComponent { // return {weekNumber}; // } - renderDay(day, id) { + renderDay(day: XDate, id: number) { const {current, hideExtraDays, markedDates} = this.props; const dayProps = extractComponentProps(Day, this.props); @@ -63,10 +69,10 @@ class Week extends PureComponent { render() { const {current} = this.props; const dates = this.getWeek(current); - const week = []; + const week: any[] = []; if (dates) { - dates.forEach((day, id) => { + dates.forEach((day: XDate, id: number) => { week.push(this.renderDay(day, id)); }, this); } diff --git a/src/types.ts b/src/types.ts index a1cf01d86b..fb54c6167b 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,5 +1,4 @@ import {ColorValue, ViewStyle, TextStyle} from 'react-native'; -// @ts-expect-error import {UPDATE_SOURCES} from './expandableCalendar/commons'; From c356813e0ec3062920c69206ee90f00ebaf92e31 Mon Sep 17 00:00:00 2001 From: Inbal Tish Date: Tue, 10 Aug 2021 16:19:26 +0300 Subject: [PATCH 095/109] fix master merge --- src/expandableCalendar/agendaList.tsx | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/expandableCalendar/agendaList.tsx b/src/expandableCalendar/agendaList.tsx index 7236f32f04..ffcce54f50 100644 --- a/src/expandableCalendar/agendaList.tsx +++ b/src/expandableCalendar/agendaList.tsx @@ -38,15 +38,13 @@ interface Props extends SectionListProps { } export type AgendaListProps = Props; -interface State {} - /** * @description: AgendaList component * @note: Should be wrapped with 'CalendarProvider' * @extends: SectionList * @example: https://github.com/wix/react-native-calendars/blob/master/example/src/screens/expandableCalendar.js */ -class AgendaList extends Component { +class AgendaList extends Component { static displayName = 'AgendaList'; static propTypes = { @@ -199,7 +197,11 @@ class AgendaList extends Component { highestMeasuredFrameIndex: number; averageItemLength: number; }) => { - console.warn('onScrollToIndexFailed info: ', info); + if (this.props.onScrollToIndexFailed) { + this.props.onScrollToIndexFailed(info); + } else { + console.warn('onScrollToIndexFailed info: ', info); + } }; onHeaderLayout = (event: LayoutChangeEvent) => { From 559d4717c1e7372fea7ce3d0d82934f90606b7c7 Mon Sep 17 00:00:00 2001 From: Lidor Dafna Date: Tue, 10 Aug 2021 16:35:30 +0300 Subject: [PATCH 096/109] support marking for inactive days --- src/calendar/day/dot/index.tsx | 8 +++++++- src/calendar/day/dot/style.ts | 3 +++ src/calendar/day/marking/index.tsx | 1 + src/style.ts | 1 + src/types.ts | 1 + 5 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/calendar/day/dot/index.tsx b/src/calendar/day/dot/index.tsx index 927de00d1e..600946f7f8 100644 --- a/src/calendar/day/dot/index.tsx +++ b/src/calendar/day/dot/index.tsx @@ -10,10 +10,11 @@ export interface DotProps { marked?: Boolean; selected?: Boolean; disabled?: Boolean; + inactive?: Boolean; today?: Boolean; } -const Dot = ({theme, marked, disabled, color, today, selected}: DotProps) => { +const Dot = ({theme, marked, disabled, inactive, color, today, selected}: DotProps) => { const style = styleConstructor(theme); const dotStyle = [style.dot] as object[]; @@ -28,6 +29,10 @@ const Dot = ({theme, marked, disabled, color, today, selected}: DotProps) => { dotStyle.push(style.disabledDot); } + if (inactive) { + dotStyle.push(style.inactiveDot); + } + if (selected) { dotStyle.push(style.selectedDot); } @@ -48,5 +53,6 @@ Dot.propTypes = { marked: PropTypes.bool, selected: PropTypes.bool, disabled: PropTypes.bool, + inactive: PropTypes.bool, today: PropTypes.bool }; diff --git a/src/calendar/day/dot/style.ts b/src/calendar/day/dot/style.ts index 4326d40664..7c9082f599 100644 --- a/src/calendar/day/dot/style.ts +++ b/src/calendar/day/dot/style.ts @@ -24,6 +24,9 @@ export default function styleConstructor(theme: Theme = {}) { disabledDot: { backgroundColor: appStyle.disabledDotColor || appStyle.dotColor }, + inactiveDot: { + backgroundColor: appStyle.inactiveDotColor || appStyle.dotColor + }, todayDot: { backgroundColor: appStyle.todayDotColor || appStyle.dotColor }, diff --git a/src/calendar/day/marking/index.tsx b/src/calendar/day/marking/index.tsx index c2d092489c..36ece46a72 100644 --- a/src/calendar/day/marking/index.tsx +++ b/src/calendar/day/marking/index.tsx @@ -77,6 +77,7 @@ export default class Marking extends Component { 'marked', 'today', 'disabled', + 'inactive', 'disableTouchEvent', 'activeOpacity', 'selectedColor', diff --git a/src/style.ts b/src/style.ts index f46b85e6e0..5eb49dc004 100644 --- a/src/style.ts +++ b/src/style.ts @@ -43,6 +43,7 @@ export const textInactiveColor = '#d9e1e8'; export const dotColor = textLinkColor; export const selectedDotColor = foregroundColor; export const disabledDotColor = undefined; +export const inactiveDotColor = undefined; export const todayDotColor = undefined; export const arrowColor = textLinkColor; export const disabledArrowColor = '#d9e1e8'; diff --git a/src/types.ts b/src/types.ts index bdd1906411..5f26343d78 100644 --- a/src/types.ts +++ b/src/types.ts @@ -80,6 +80,7 @@ export interface Theme { arrowStyle?: ViewStyle; todayBackgroundColor?: string; disabledDotColor?: string; + inactiveDotColor?: string; todayDotColor?: string; todayButtonTextColor?: string; todayButtonPosition?: string; From a02bdeb585a530131b08caaceb80fb236c420f21 Mon Sep 17 00:00:00 2001 From: Lidor Dafna Date: Wed, 11 Aug 2021 13:35:41 +0300 Subject: [PATCH 097/109] pass inactive to Marking --- src/calendar/day/basic/index.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/calendar/day/basic/index.tsx b/src/calendar/day/basic/index.tsx index 85b2b83bfa..f40bb2b0d1 100644 --- a/src/calendar/day/basic/index.tsx +++ b/src/calendar/day/basic/index.tsx @@ -187,6 +187,7 @@ export default class BasicDay extends Component { marked={this.isMultiDot() ? true : marked} selected={this.isSelected()} disabled={this.isDisabled()} + inactive={this.isInactive()} today={this.isToday()} dotColor={dotColor} dots={dots} From 7ab81d6798bc54b3c2d200c54908dd7676f283e8 Mon Sep 17 00:00:00 2001 From: Lidor Dafna Date: Wed, 11 Aug 2021 13:47:39 +0300 Subject: [PATCH 098/109] add markings for 'inactive' state --- src/calendar/day/basic/index.tsx | 4 ++-- src/calendar/day/period/index.tsx | 10 +++++++--- src/calendar/day/period/style.ts | 5 ++++- src/types.ts | 2 ++ 4 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/calendar/day/basic/index.tsx b/src/calendar/day/basic/index.tsx index f40bb2b0d1..bee891f5c1 100644 --- a/src/calendar/day/basic/index.tsx +++ b/src/calendar/day/basic/index.tsx @@ -4,14 +4,14 @@ import PropTypes from 'prop-types'; import React, {Component, Fragment} from 'react'; import {TouchableOpacity, Text, View} from 'react-native'; -import {Theme, DateData} from '../../../types'; +import {Theme, DateData, DayState} from '../../../types'; // @ts-expect-error import {shouldUpdate} from '../../../component-updater'; import styleConstructor from './style'; import Marking, {MarkingTypes, MarkingProps} from '../marking'; export interface BasicDayProps { - state?: 'selected' | 'disabled' | 'inactive' | 'today'; + state?: DayState; /** The marking object */ marking?: MarkingProps; /** Date marking style [simple/period/multi-dot/multi-period]. Default = 'simple' */ diff --git a/src/calendar/day/period/index.tsx b/src/calendar/day/period/index.tsx index becc0ff052..757ed2b591 100644 --- a/src/calendar/day/period/index.tsx +++ b/src/calendar/day/period/index.tsx @@ -10,10 +10,10 @@ import * as defaultStyle from '../../../style'; import styleConstructor from './style'; import Dot from '../dot'; import {MarkingProps} from '../marking'; -import {Theme} from '../../../types'; +import {Theme, DayState} from '../../../types'; interface PeriodDayProps { - state?: 'selected' | 'disabled' | 'today' | ''; + state?: DayState; marking?: MarkingProps; theme?: Theme; onPress?: (date?: Date) => void; @@ -27,7 +27,7 @@ export default class PeriodDay extends Component { static displayName = 'IGNORE'; static propTypes = { - state: PropTypes.oneOf(['selected', 'disabled', 'today', '']), + state: PropTypes.oneOf(['selected', 'disabled', 'inactive', 'today', '']), marking: PropTypes.any, theme: PropTypes.object, onPress: PropTypes.func, @@ -75,6 +75,8 @@ export default class PeriodDay extends Component { if (marking.disabled) { defaultStyle.textStyle.color = this.style.disabledText.color; + } else if (marking.inactive) { + defaultStyle.textStyle.color = this.style.inactiveText.color; } else if (marking.selected) { defaultStyle.textStyle.color = this.style.selectedText.color; } @@ -141,6 +143,8 @@ export default class PeriodDay extends Component { // TODO: refactor - move all styling logic out of render() if (state === 'disabled') { textStyle.push(this.style.disabledText); + } else if (state === 'inactive') { + textStyle.push(this.style.inactiveText); } else if (state === 'today') { containerStyle.push(this.style.today); textStyle.push(this.style.todayText); diff --git a/src/calendar/day/period/style.ts b/src/calendar/day/period/style.ts index 5f06b9a2cc..7da6efdeb6 100644 --- a/src/calendar/day/period/style.ts +++ b/src/calendar/day/period/style.ts @@ -55,7 +55,10 @@ export default function styleConstructor(theme: Theme = {}) { disabledText: { color: appStyle.textDisabledColor }, - + inactiveText: { + color: appStyle.textInactiveColor + }, + // quickAction: { // backgroundColor: 'white', // borderWidth: 1, diff --git a/src/types.ts b/src/types.ts index 5f26343d78..7d0d73704d 100644 --- a/src/types.ts +++ b/src/types.ts @@ -12,6 +12,8 @@ export type DateData = { timestamp: number, dateString: string } +export type DayState = 'selected' | 'disabled' | 'inactive' | 'today' | ''; + export interface Theme { container?: object; contentStyle?: ViewStyle; From f16adc65bba0f5764e5b2c90d44f0b9e5e10ca20 Mon Sep 17 00:00:00 2001 From: Inbal Tish <33805983+Inbal-Tish@users.noreply.github.com> Date: Wed, 11 Aug 2021 14:46:18 +0300 Subject: [PATCH 099/109] Update src/expandableCalendar/Context/Presenter.ts Co-authored-by: Mendy Edri --- src/expandableCalendar/Context/Presenter.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/expandableCalendar/Context/Presenter.ts b/src/expandableCalendar/Context/Presenter.ts index 723ebe762b..e9766d7002 100644 --- a/src/expandableCalendar/Context/Presenter.ts +++ b/src/expandableCalendar/Context/Presenter.ts @@ -49,7 +49,7 @@ class Presenter { return icon; }; - setDate = (props: CalendarContextProviderProps, date: Date, newDate: Date, updateState: (buttonIcon: any) => any, updateSource: UpdateSource) => { + setDate = (props: CalendarContextProviderProps, date: Date, newDate: Date, updateState: (buttonIcon: any) => void, updateSource: UpdateSource) => { const isSameMonth = sameMonth(new XDate(date), new XDate(newDate)); const buttonIcon = this.getButtonIcon(date, props.showTodayButton); From 987a140ed982dce4614d3de2fddf7f04df036731 Mon Sep 17 00:00:00 2001 From: Inbal Tish Date: Wed, 11 Aug 2021 14:58:13 +0300 Subject: [PATCH 100/109] pr comments fix --- src/expandableCalendar/Context/Presenter.spec.js | 4 ++-- src/expandableCalendar/Context/Provider.tsx | 2 +- src/expandableCalendar/WeekCalendar/presenter.spec.js | 8 ++++---- src/expandableCalendar/WeekCalendar/presenter.ts | 2 +- src/expandableCalendar/agendaList.tsx | 2 +- src/expandableCalendar/commons.ts | 7 +++---- src/expandableCalendar/index.tsx | 2 +- src/types.ts | 4 ++-- 8 files changed, 15 insertions(+), 16 deletions(-) diff --git a/src/expandableCalendar/Context/Presenter.spec.js b/src/expandableCalendar/Context/Presenter.spec.js index 555a9910f6..f4c054e9e6 100644 --- a/src/expandableCalendar/Context/Presenter.spec.js +++ b/src/expandableCalendar/Context/Presenter.spec.js @@ -1,6 +1,6 @@ const {default: Presenter} = require('./Presenter'); import XDate from 'xdate'; -import {UPDATE_SOURCES} from '../commons'; +import {UpdateSources} from '../commons'; import {toMarkingFormat} from '../../interface'; @@ -14,7 +14,7 @@ describe('Context provider tests', () => { const today1 = XDate(); const today2 = new Date(); const todayDate = toMarkingFormat(XDate()); - const updateSources = UPDATE_SOURCES.CALENDAR_INIT; + const updateSources = UpdateSources.CALENDAR_INIT; describe('isPastDate function tests', () => { it('Expect to get true while passing a past date', () => { diff --git a/src/expandableCalendar/Context/Provider.tsx b/src/expandableCalendar/Context/Provider.tsx index 0dcce9bf2f..99d96a9a9a 100644 --- a/src/expandableCalendar/Context/Provider.tsx +++ b/src/expandableCalendar/Context/Provider.tsx @@ -13,7 +13,7 @@ import Presenter from './Presenter'; const commons = require('../commons'); -const updateSources = commons.UPDATE_SOURCES; +const updateSources = commons.UpdateSources; const TOP_POSITION = 65; interface Props { diff --git a/src/expandableCalendar/WeekCalendar/presenter.spec.js b/src/expandableCalendar/WeekCalendar/presenter.spec.js index f106891dd0..31922aa561 100644 --- a/src/expandableCalendar/WeekCalendar/presenter.spec.js +++ b/src/expandableCalendar/WeekCalendar/presenter.spec.js @@ -1,4 +1,4 @@ -const {UPDATE_SOURCES} = require('../commons'); +const {UpdateSources} = require('../commons'); const {default: Presenter} = require('./presenter'); describe('WeekCalendar presenter tests', () => { @@ -17,7 +17,7 @@ describe('WeekCalendar presenter tests', () => { prevDate: '2021-01-13' }; - const makeContext = (datesInWeek = twoDaysSameWeek, updateSource = UPDATE_SOURCES.WEEK_SCROLL) => { + const makeContext = (datesInWeek = twoDaysSameWeek, updateSource = UpdateSources.WEEK_SCROLL) => { return { ...datesInWeek, updateSource @@ -59,7 +59,7 @@ describe('WeekCalendar presenter tests', () => { }); it('Expect component to update when dates are not in the same week', () => { - const context = makeContext(twoDaysDifferentWeek, UPDATE_SOURCES.PAGE_SCROLL); + const context = makeContext(twoDaysDifferentWeek, UpdateSources.PAGE_SCROLL); const prevContext = makeContext(twoSomeDays); const {shouldComponentUpdate} = makeUUT(); const shouldUpdate = shouldComponentUpdate(context, prevContext); @@ -145,7 +145,7 @@ describe('WeekCalendar presenter tests', () => { const {onDayPress} = makeUUT({context}); onDayPress(context, {dateString: '2021-01-22'}); - expect(setDate).toBeCalledWith('2021-01-22', UPDATE_SOURCES.DAY_PRESS); + expect(setDate).toBeCalledWith('2021-01-22', UpdateSources.DAY_PRESS); }); }); diff --git a/src/expandableCalendar/WeekCalendar/presenter.ts b/src/expandableCalendar/WeekCalendar/presenter.ts index a07d929d96..879627d1ed 100644 --- a/src/expandableCalendar/WeekCalendar/presenter.ts +++ b/src/expandableCalendar/WeekCalendar/presenter.ts @@ -12,7 +12,7 @@ import {WeekCalendarProps} from './index'; const commons = require('../commons'); -const updateSources = commons.UPDATE_SOURCES; +const updateSources = commons.UpdateSources; // must be a positive number const NUMBER_OF_PAGES = 2; diff --git a/src/expandableCalendar/agendaList.tsx b/src/expandableCalendar/agendaList.tsx index ffcce54f50..a54ed3e5bc 100644 --- a/src/expandableCalendar/agendaList.tsx +++ b/src/expandableCalendar/agendaList.tsx @@ -15,7 +15,7 @@ import asCalendarConsumer from './asCalendarConsumer'; const commons = require('./commons'); -const updateSources = commons.UPDATE_SOURCES; +const updateSources = commons.UpdateSources; interface Props extends SectionListProps { /** day format in section title. Formatting values: http://arshaw.com/xdate/#Formatting */ diff --git a/src/expandableCalendar/commons.ts b/src/expandableCalendar/commons.ts index 606fc6718e..36a6151ff1 100644 --- a/src/expandableCalendar/commons.ts +++ b/src/expandableCalendar/commons.ts @@ -1,4 +1,4 @@ -import {Platform, Dimensions, I18nManager} from 'react-native'; +import {Platform, Dimensions, I18nManager, PlatformIOSStatic} from 'react-native'; const {height, width} = Dimensions.get('window'); @@ -8,11 +8,10 @@ export const isIos = Platform.OS === 'ios'; export const screenWidth = width; export const screenHeight = height; export const screenAspectRatio = screenWidth < screenHeight ? screenHeight / screenWidth : screenWidth / screenHeight; -// @ts-expect-error -export const isTablet = Platform.isPad || (screenAspectRatio < 1.6 && Math.max(screenWidth, screenHeight) >= 900); +export const isTablet = (Platform as PlatformIOSStatic).isPad || (screenAspectRatio < 1.6 && Math.max(screenWidth, screenHeight) >= 900); export const todayString = 'today'; -export enum UPDATE_SOURCES { +export enum UpdateSources { CALENDAR_INIT = 'calendarInit', TODAY_PRESS = 'todayPress', LIST_DRAG = 'listDrag', diff --git a/src/expandableCalendar/index.tsx b/src/expandableCalendar/index.tsx index ebb2cef719..8b98b939a7 100644 --- a/src/expandableCalendar/index.tsx +++ b/src/expandableCalendar/index.tsx @@ -22,7 +22,7 @@ import Week from './week'; const commons = require('./commons'); -const updateSources = commons.UPDATE_SOURCES; +const updateSources = commons.UpdateSources; enum Positions { CLOSED = 'closed', OPEN = 'open' diff --git a/src/types.ts b/src/types.ts index fb54c6167b..305a7b2206 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,9 +1,9 @@ import {ColorValue, ViewStyle, TextStyle} from 'react-native'; -import {UPDATE_SOURCES} from './expandableCalendar/commons'; +import {UpdateSources} from './expandableCalendar/commons'; export type Direction = 'left' | 'right'; -export type UpdateSource = keyof typeof UPDATE_SOURCES; +export type UpdateSource = keyof typeof UpdateSources; export type DateData = { year: number, month: number, From 8c8272c0a092c0ee66d43efb8dedadfec704d8fe Mon Sep 17 00:00:00 2001 From: Inbal Tish <33805983+Inbal-Tish@users.noreply.github.com> Date: Wed, 11 Aug 2021 14:59:34 +0300 Subject: [PATCH 101/109] Update src/expandableCalendar/Context/Presenter.ts Co-authored-by: Mendy Edri --- src/expandableCalendar/Context/Presenter.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/expandableCalendar/Context/Presenter.ts b/src/expandableCalendar/Context/Presenter.ts index e9766d7002..c5e9223e67 100644 --- a/src/expandableCalendar/Context/Presenter.ts +++ b/src/expandableCalendar/Context/Presenter.ts @@ -96,7 +96,7 @@ class Presenter { return props.disabledOpacity; }; - getOpacityAnimation = (props: CalendarContextProviderProps, disabled: boolean) => { + getOpacityAnimation = ({disabledOpacity = 0}: CalendarContextProviderProps, disabled: boolean) => { return { toValue: disabled ? props.disabledOpacity || 0 : 1, duration: 500, From f47f35491066bfb5fa87eec943a20b289c1de815 Mon Sep 17 00:00:00 2001 From: Inbal Tish <33805983+Inbal-Tish@users.noreply.github.com> Date: Wed, 11 Aug 2021 15:04:46 +0300 Subject: [PATCH 102/109] Update src/expandableCalendar/Context/Presenter.ts Co-authored-by: Mendy Edri --- src/expandableCalendar/Context/Presenter.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/expandableCalendar/Context/Presenter.ts b/src/expandableCalendar/Context/Presenter.ts index c5e9223e67..56c51679b2 100644 --- a/src/expandableCalendar/Context/Presenter.ts +++ b/src/expandableCalendar/Context/Presenter.ts @@ -98,7 +98,7 @@ class Presenter { getOpacityAnimation = ({disabledOpacity = 0}: CalendarContextProviderProps, disabled: boolean) => { return { - toValue: disabled ? props.disabledOpacity || 0 : 1, + toValue: disabled ? disabledOpacity : 1, duration: 500, useNativeDriver: true }; From 8d9d5e799b7a2b4a6895f97b17e1f401d55b31a1 Mon Sep 17 00:00:00 2001 From: Lidor Dafna Date: Wed, 11 Aug 2021 16:15:23 +0300 Subject: [PATCH 103/109] ts fixes --- src/timeline/style.ts | 2 +- src/types.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/timeline/style.ts b/src/timeline/style.ts index 6b7badcda9..f32aa37cd9 100644 --- a/src/timeline/style.ts +++ b/src/timeline/style.ts @@ -1,6 +1,6 @@ // @flow import {Platform, StyleSheet} from 'react-native'; -import {Theme} from '../commons/types'; +import {Theme} from '../types'; // const eventPaddingLeft = 4 const leftMargin = 50 - 1; diff --git a/src/types.ts b/src/types.ts index b6d01a5863..9839781ede 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,4 +1,4 @@ -import {ColorValue, ViewStyle, TextStyle} from 'react-native'; +import {ViewStyle, TextStyle} from 'react-native'; import {UpdateSources} from './expandableCalendar/commons'; From 6c4f8767aaec92eee3df099ba5126c0e3358660f Mon Sep 17 00:00:00 2001 From: Inbal Tish Date: Sun, 22 Aug 2021 13:17:54 +0300 Subject: [PATCH 104/109] Fix types --- src/timeline/Packer.ts | 20 +++++++++-------- src/timeline/Timeline.tsx | 46 +++++++++++++++++++++++---------------- src/types.ts | 2 +- 3 files changed, 39 insertions(+), 29 deletions(-) diff --git a/src/timeline/Packer.ts b/src/timeline/Packer.ts index 4f4546f8ba..a15da2d128 100644 --- a/src/timeline/Packer.ts +++ b/src/timeline/Packer.ts @@ -1,9 +1,11 @@ // @flow import XDate from 'xdate'; +import {Event} from './Timeline'; + const offset = 100; -function buildEvent(column: any, left: number, width: number, dayStart: any) { +function buildEvent(column: any, left: number, width: number, dayStart: number) { const startTime = new XDate(column.start); const endTime = column.end ? new XDate(column.end) : new XDate(startTime).addHours(1); @@ -16,11 +18,11 @@ function buildEvent(column: any, left: number, width: number, dayStart: any) { return column; } -function collision(a: any, b: any) { +function collision(a: Event, b: Event) { return a.end > b.start && a.start < b.end; } -function expand(ev: any, column: any, columns: any) { +function expand(ev: Event, column: any, columns: any) { let colSpan = 1; for (let i = column + 1; i < columns.length; i++) { @@ -37,7 +39,7 @@ function expand(ev: any, column: any, columns: any) { return colSpan; } -function pack(columns: any, width: number, calculatedEvents: any, dayStart: any) { +function pack(columns: any, width: number, calculatedEvents: Event[], dayStart: number) { let colLength = columns.length; for (let i = 0; i < colLength; i++) { @@ -52,14 +54,14 @@ function pack(columns: any, width: number, calculatedEvents: any, dayStart: any) } } -function populateEvents(events: any, screenWidth: number, dayStart: any) { +function populateEvents(events: Event[], screenWidth: number, dayStart: number) { let lastEnd: any; let columns: any; - let calculatedEvents: any = []; + let calculatedEvents: Event[] = []; events = events - .map((ev: any, index: number) => ({...ev, index: index})) - .sort(function (a: any, b: any) { + .map((ev: Event, index: number) => ({...ev, index: index})) + .sort(function (a: Event, b: Event) { if (a.start < b.start) return -1; if (a.start > b.start) return 1; if (a.end < b.end) return -1; @@ -70,7 +72,7 @@ function populateEvents(events: any, screenWidth: number, dayStart: any) { columns = []; lastEnd = null; - events.forEach(function (ev: any) { + events.forEach(function (ev: Event) { if (lastEnd !== null && ev.start >= lastEnd) { pack(columns, screenWidth, calculatedEvents, dayStart); columns = []; diff --git a/src/timeline/Timeline.tsx b/src/timeline/Timeline.tsx index fe8ab7a352..83a9c01d8d 100644 --- a/src/timeline/Timeline.tsx +++ b/src/timeline/Timeline.tsx @@ -2,11 +2,15 @@ import _ from 'lodash'; import PropTypes from 'prop-types'; import XDate from 'xdate'; + import React, {Component} from 'react'; -import {View, Text, TouchableOpacity, Dimensions, ScrollView} from 'react-native'; +import {View, Text, TouchableOpacity, Dimensions, ScrollView, TextStyle, ViewStyle} from 'react-native'; + +import {Theme} from '../types'; import styleConstructor from './style'; import populateEvents from './Packer'; + const LEFT_MARGIN = 60 - 1; const TEXT_LINE_HEIGHT = 17; @@ -16,25 +20,28 @@ function range(from: number, to: number) { let {width: dimensionWidth} = Dimensions.get('window'); +export type Event = { + start: string; + end: string; + title: string; + summary: string; + color?: string; +}; + export interface TimelineProps { start?: number; end?: number; - eventTapped?: (event: any) => void; + eventTapped?: (event: Event) => void; format24h?: boolean; - events: { - start: string; - end: string; - title: string; - summary: string; - color?: string; - }[]; - styles?: any; + events: Event[]; + styles?: Theme; //TODO: deprecate (prop renamed 'theme', as in the other components). + theme?: Theme; scrollToFirst?: boolean; - renderEvent?: (event: any) => JSX.Element; + renderEvent?: (event: Event) => JSX.Element; } interface State { - _scrollY: any; + _scrollY: number; packedEvents: any; } @@ -61,9 +68,10 @@ export default class Timeline extends Component { events: [], format24h: true }; + + private scrollView: React.RefObject = React.createRef(); + style: {[key: string]: ViewStyle | TextStyle}; calendarHeight: number; - private _scrollView: any; - style: any; constructor(props: TimelineProps) { super(props); @@ -71,7 +79,7 @@ export default class Timeline extends Component { const {start = 0, end = 0} = this.props; this.calendarHeight = (end - start) * 100; - this.style = styleConstructor(props.styles, this.calendarHeight); + this.style = styleConstructor(props.theme || props.styles, this.calendarHeight); const width = dimensionWidth - LEFT_MARGIN; const packedEvents = populateEvents(props.events, width, start); @@ -102,8 +110,8 @@ export default class Timeline extends Component { scrollToFirst() { setTimeout(() => { - if (this.state && this.state._scrollY && this._scrollView) { - this._scrollView.scrollTo({ + if (this.state && this.state._scrollY && this.scrollView) { + this.scrollView?.current?.scrollTo({ x: 0, y: this.state._scrollY, animated: true @@ -147,7 +155,7 @@ export default class Timeline extends Component { }); } - _onEventTapped(event: any) { + _onEventTapped(event: Event) { if (this.props.eventTapped) { this.props.eventTapped(event); } @@ -209,7 +217,7 @@ export default class Timeline extends Component { render() { return ( (this._scrollView = ref)} + ref={this.scrollView} contentContainerStyle={[this.style.contentStyle, {width: dimensionWidth}]} > {this._renderLines()} diff --git a/src/types.ts b/src/types.ts index 9839781ede..08b1770aee 100644 --- a/src/types.ts +++ b/src/types.ts @@ -28,7 +28,7 @@ export interface Theme { timeLabel?: object; todayTextColor?: string; calendarBackground?: string; - indicatorColor?: any; + indicatorColor?: string; stylesheet?: { calendar?: {main?: object, header?: object}; day?: {basic?: object; period?: object}; From 514fa0932b863d5a270ef78559c78e70dedda1cb Mon Sep 17 00:00:00 2001 From: Inbal Tish Date: Sun, 22 Aug 2021 13:40:46 +0300 Subject: [PATCH 105/109] migrating example screen --- example/src/screens/timelineCalendar.js | 254 ----------------------- example/src/screens/timelineCalendar.tsx | 122 +++++++++++ 2 files changed, 122 insertions(+), 254 deletions(-) delete mode 100644 example/src/screens/timelineCalendar.js create mode 100644 example/src/screens/timelineCalendar.tsx diff --git a/example/src/screens/timelineCalendar.js b/example/src/screens/timelineCalendar.js deleted file mode 100644 index 830f006967..0000000000 --- a/example/src/screens/timelineCalendar.js +++ /dev/null @@ -1,254 +0,0 @@ -import _ from 'lodash'; -import XDate from 'xdate'; -import React, {Component} from 'react'; -import {Platform, StyleSheet, View, Text, TouchableOpacity, Button} from 'react-native'; -import {ExpandableCalendar, Timeline, CalendarProvider} from 'react-native-calendars'; -import {sameDate} from '../../../src/dateutils'; - -const EVENTS = [ - { - start: '2017-09-06 22:30:00', - end: '2017-09-06 23:30:00', - title: 'Dr. Mariana Joseph', - summary: '3412 Piedmont Rd NE, GA 3032', - color: '#e6add8' - }, - { - start: '2017-09-07 00:30:00', - end: '2017-09-07 01:30:00', - title: 'Visit Grand Mother', - summary: 'Visit Grand Mother and bring some fruits.', - color: '#ade6d8' - }, - { - start: '2017-09-07 02:30:00', - end: '2017-09-07 03:20:00', - title: 'Meeting with Prof. Behjet Zuhaira', - summary: 'Meeting with Prof. Behjet at 130 in her office.', - color: '#e6add8' - }, - { - start: '2017-09-07 04:10:00', - end: '2017-09-07 04:40:00', - title: 'Tea Time with Dr. Hasan', - summary: 'Tea Time with Dr. Hasan, Talk about Project' - }, - { - start: '2017-09-07 01:05:00', - end: '2017-09-07 01:35:00', - title: 'Dr. Mariana Joseph', - summary: '3412 Piedmont Rd NE, GA 3032' - }, - { - start: '2017-09-07 14:30:00', - end: '2017-09-07 16:30:00', - title: 'Meeting Some Friends in ARMED', - summary: 'Arsalan, Hasnaat, Talha, Waleed, Bilal', - color: '#d8ade6' - }, - { - start: '2017-09-08 01:40:00', - end: '2017-09-08 02:25:00', - title: 'Meet Sir Khurram Iqbal', - summary: 'Computer Science Dept. Comsats Islamabad', - color: '#e6bcad' - }, - { - start: '2017-09-08 04:10:00', - end: '2017-09-08 04:40:00', - title: 'Tea Time with Colleagues', - summary: 'WeRplay' - }, - { - start: '2017-09-08 00:45:00', - end: '2017-09-08 01:45:00', - title: 'Lets Play Apex Legends', - summary: 'with Boys at Work' - }, - { - start: '2017-09-08 11:30:00', - end: '2017-09-08 12:30:00', - title: 'Dr. Mariana Joseph', - summary: '3412 Piedmont Rd NE, GA 3032' - }, - { - start: '2017-09-10 12:10:00', - end: '2017-09-10 13:45:00', - title: 'Merge Request to React Native Calendards', - summary: 'Merge Timeline Calendar to React Native Calendars' - } -]; - -export default class TimelineCalendarScreen extends Component { - state = { - currentDate: '2017-09-07' - }; - - onDateChanged = date => { - // console.warn('TimelineCalendarScreen onDateChanged: ', date, updateSource); - // fetch and set data for date + week ahead - this.setState({currentDate: date}); - }; - - onMonthChange = (/* month, updateSource */) => { - // console.warn('TimelineCalendarScreen onMonthChange: ', month, updateSource); - }; - - renderEmptyItem() { - return ( - - No Events Planned - - ); - } - - renderItem = ({item}) => { - if (_.isEmpty(item)) { - return this.renderEmptyItem(); - } - - return ( - - - {item.hour} - {item.duration} - - {item.title} - -