Skip to content

Commit 88224af

Browse files
authored
Merge pull request #1695 from wix/feat/Calendar_initialDate
Calendar - add 'initialDate' prop
2 parents 4b8a0b2 + ab7e590 commit 88224af

File tree

2 files changed

+31
-9
lines changed

2 files changed

+31
-9
lines changed

src/calendar/index.spec.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,13 @@ describe('Calendar', () => {
3939
expect(drv.getDays()).toEqual(expectedDays);
4040
});
4141

42+
it('should render month from `initialDate` prop date', () => {
43+
const expectedDays = getDaysArray(1, 31);
44+
expectedDays.push(...getDaysArray(1, 4)); // April days
45+
const drv = new CalendarDriver().withDefaultProps({initialDate: '2020-03-01'}).render();
46+
expect(drv.getDays()).toEqual(expectedDays);
47+
});
48+
4249
it('should render calendar with week numbers with `showWeekNumbers={true}` prop', () => {
4350
const drv = new CalendarDriver().withDefaultProps({showWeekNumbers: true}).render();
4451
expect(drv.getWeekNumbers()).toEqual(['14', '15', '16', '17', '18']);

src/calendar/index.tsx

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,9 @@ export interface CalendarProps extends CalendarHeaderProps, DayProps {
3131
/** Specify style for calendar container element */
3232
style?: StyleProp<ViewStyle>;
3333
/** Initially visible month */
34-
current?: string;
34+
current?: string; // TODO: migrate to 'initialDate'
35+
/** Initially visible month. If changed will initialize the calendar to this value */
36+
initialDate?: string;
3537
/** Minimum date that can be selected, dates before minDate will be grayed out */
3638
minDate?: string;
3739
/** Maximum date that can be selected, dates after maxDate will be grayed out */
@@ -71,6 +73,7 @@ export interface CalendarProps extends CalendarHeaderProps, DayProps {
7173
}
7274

7375
interface CalendarState {
76+
prevInitialDate?: string;
7477
currentMonth: any;
7578
}
7679
/**
@@ -89,11 +92,13 @@ class Calendar extends Component<CalendarProps, CalendarState> {
8992
/** Specify style for calendar container element. Default = {} */
9093
style: PropTypes.oneOfType([PropTypes.object, PropTypes.array, PropTypes.number]),
9194
/** Initially visible month in 'yyyy-MM-dd' format. Default = now */
92-
current: PropTypes.any,
95+
current: PropTypes.string,
96+
/** Initially visible month. If changed will initialize the calendar to this value */
97+
initialDate: PropTypes.string,
9398
/** Minimum date that can be selected, dates before minDate will be grayed out. Default = undefined */
94-
minDate: PropTypes.any,
99+
minDate: PropTypes.string,
95100
/** Maximum date that can be selected, dates after maxDate will be grayed out. Default = undefined */
96-
maxDate: PropTypes.any,
101+
maxDate: PropTypes.string,
97102
/** If firstDay=1 week starts from Monday. Note that dayNames and dayNamesShort should still start from Sunday. */
98103
firstDay: PropTypes.number,
99104
/** Collection of dates that have to be marked. Default = {} */
@@ -132,11 +137,23 @@ class Calendar extends Component<CalendarProps, CalendarState> {
132137
};
133138

134139
state = {
135-
currentMonth: this.props.current ? parseDate(this.props.current) : new XDate()
140+
prevInitialDate: this.props.initialDate,
141+
currentMonth: this.props.current || this.props.initialDate ?
142+
parseDate(this.props.current || this.props.initialDate) : new XDate()
136143
};
137144
style = styleConstructor(this.props.theme);
138145
header: React.RefObject<CalendarHeader> = React.createRef();
139146

147+
static getDerivedStateFromProps(nextProps: CalendarProps, prevState: CalendarState) {
148+
if (nextProps?.initialDate && nextProps?.initialDate !== prevState.prevInitialDate) {
149+
return {
150+
prevInitialDate: nextProps.initialDate,
151+
currentMonth: parseDate(nextProps.initialDate)
152+
};
153+
}
154+
return null;
155+
}
156+
140157
addMonth = (count: number) => {
141158
this.updateMonth(this.state.currentMonth.clone().addMonths(count, true));
142159
};
@@ -145,7 +162,6 @@ class Calendar extends Component<CalendarProps, CalendarState> {
145162
if (day.toString('yyyy MM') === this.state.currentMonth.toString('yyyy MM')) {
146163
return;
147164
}
148-
149165
this.setState({currentMonth: day.clone()}, () => {
150166
const currMont = this.state.currentMonth.clone();
151167
this.props.onMonthChange?.(xdateToData(currMont));
@@ -279,11 +295,10 @@ class Calendar extends Component<CalendarProps, CalendarState> {
279295

280296
renderHeader() {
281297
const {customHeader, headerStyle, displayLoadingIndicator, markedDates, testID} = this.props;
282-
const current = parseDate(this.props.current);
283298
let indicator;
284299

285-
if (current) {
286-
const lastMonthOfDay = toMarkingFormat(current.clone().addMonths(1, true).setDate(1).addDays(-1));
300+
if (this.state.currentMonth) {
301+
const lastMonthOfDay = toMarkingFormat(this.state.currentMonth.clone().addMonths(1, true).setDate(1).addDays(-1));
287302
if (displayLoadingIndicator && !markedDates?.[lastMonthOfDay]) {
288303
indicator = true;
289304
}

0 commit comments

Comments
 (0)