Skip to content

Commit

Permalink
Clean up prop types definitions for top-level components
Browse files Browse the repository at this point in the history
- Make `onDate(s)Change` and `onFocusChange` required
- Sort `DateRangePicker`, `SingleDatePicker`, `DayPicker` by category with comments
- Use `forbidExtraProps` on all components
- Add propTypes and defaultProps to the examples so that information shows up in the info addon
  • Loading branch information
Maja Wichrowska committed Feb 16, 2017
1 parent 3e534c8 commit 064c5af
Show file tree
Hide file tree
Showing 18 changed files with 609 additions and 173 deletions.
65 changes: 65 additions & 0 deletions examples/DateRangePickerWrapper.jsx
@@ -1,7 +1,69 @@
import React from 'react';
import moment from 'moment';
import omit from 'lodash.omit';

import DateRangePicker from '../src/components/DateRangePicker';

import DateRangePickerShape from '../src/shapes/DateRangePickerShape';
import { START_DATE, END_DATE, HORIZONTAL_ORIENTATION, ANCHOR_LEFT } from '../constants';
import isInclusivelyAfterDay from '../src/utils/isInclusivelyAfterDay';

const propTypes = omit(DateRangePickerShape, [
'startDate',
'endDate',
'onDatesChange',
'focusedInput',
'onFocusChange',
]);

const defaultProps = {
// input related props
startDateId: START_DATE,
startDatePlaceholderText: 'Start Date',
endDateId: END_DATE,
endDatePlaceholderText: 'End Date',
disabled: false,
required: false,
screenReaderInputMessage: '',
showClearDates: false,
showDefaultInputIcon: false,
customInputIcon: null,
customArrowIcon: null,

// calendar presentation and interaction related props
orientation: HORIZONTAL_ORIENTATION,
anchorDirection: ANCHOR_LEFT,
horizontalMargin: 0,
withPortal: false,
withFullScreenPortal: false,
initialVisibleMonth: null,
numberOfMonths: 2,
keepOpenOnDateSelect: false,
reopenPickerOnClearDates: false,

// navigation related props
navPrev: null,
navNext: null,
onPrevMonthClick() {},
onNextMonthClick() {},

// day presentation and interaction related props
renderDay: null,
minimumNights: 1,
enableOutsideDays: false,
isDayBlocked: () => false,
isOutsideRange: day => !isInclusivelyAfterDay(day, moment()),
isDayHighlighted: () => false,

// internationalization
displayFormat: () => moment.localeData().longDateFormat('L'),
monthFormat: 'MMMM YYYY',
phrases: {
closeDatePicker: 'Close',
clearDates: 'Clear Dates',
},
};

class DateRangePickerWrapper extends React.Component {
constructor(props) {
super(props);
Expand Down Expand Up @@ -40,4 +102,7 @@ class DateRangePickerWrapper extends React.Component {
}
}

DateRangePickerWrapper.propTypes = propTypes;
DateRangePickerWrapper.defaultProps = defaultProps;

export default DateRangePickerWrapper;
58 changes: 58 additions & 0 deletions examples/SingleDatePickerWrapper.jsx
@@ -1,7 +1,62 @@
import React from 'react';
import moment from 'moment';
import omit from 'lodash.omit';

import SingleDatePicker from '../src/components/SingleDatePicker';

import SingleDatePickerShape from '../src/shapes/SingleDatePickerShape';
import { HORIZONTAL_ORIENTATION, ANCHOR_LEFT } from '../constants';
import isInclusivelyAfterDay from '../src/utils/isInclusivelyAfterDay';

const propTypes = omit(SingleDatePickerShape, [
'date',
'onDateChange',
'focused',
'onFocusChange',
]);

const defaultProps = {
// input related props
id: 'date',
placeholder: 'Date',
disabled: false,
required: false,
screenReaderInputMessage: '',
showClearDate: false,

// calendar presentation and interaction related props
orientation: HORIZONTAL_ORIENTATION,
anchorDirection: ANCHOR_LEFT,
horizontalMargin: 0,
withPortal: false,
withFullScreenPortal: false,
initialVisibleMonth: null,
numberOfMonths: 2,
keepOpenOnDateSelect: false,
reopenPickerOnClearDate: false,

// navigation related props
navPrev: null,
navNext: null,
onPrevMonthClick() {},
onNextMonthClick() {},

// day presentation and interaction related props
renderDay: null,
enableOutsideDays: false,
isDayBlocked: () => false,
isOutsideRange: day => !isInclusivelyAfterDay(day, moment()),
isDayHighlighted: () => {},

// internationalization props
displayFormat: () => moment.localeData().longDateFormat('L'),
monthFormat: 'MMMM YYYY',
phrases: {
closeDatePicker: 'Close',
clearDate: 'Clear Date',
},
};

class SingleDatePickerWrapper extends React.Component {
constructor(props) {
super(props);
Expand Down Expand Up @@ -38,4 +93,7 @@ class SingleDatePickerWrapper extends React.Component {
}
}

SingleDatePickerWrapper.propTypes = propTypes;
SingleDatePickerWrapper.defaultProps = defaultProps;

export default SingleDatePickerWrapper;
1 change: 1 addition & 0 deletions package.json
Expand Up @@ -75,6 +75,7 @@
"karma-mocha": "^1.3.0",
"karma-sinon": "^1.0.5",
"karma-webpack": "^2.0.1",
"lodash.omit": "^4.5.0",
"mocha": "^3.2.0",
"mocha-wrap": "^2.1.0",
"moment": "^2.17.1",
Expand Down
5 changes: 3 additions & 2 deletions src/components/CalendarDay.jsx
@@ -1,18 +1,19 @@
import React, { PropTypes } from 'react';
import shallowCompare from 'react-addons-shallow-compare';
import momentPropTypes from 'react-moment-proptypes';
import { forbidExtraProps } from 'airbnb-prop-types';
import moment from 'moment';
import cx from 'classnames';

const propTypes = {
const propTypes = forbidExtraProps({
day: momentPropTypes.momentObj,
isOutsideDay: PropTypes.bool,
modifiers: PropTypes.object,
onDayClick: PropTypes.func,
onDayMouseEnter: PropTypes.func,
onDayMouseLeave: PropTypes.func,
renderDay: PropTypes.func,
};
});

const defaultProps = {
day: moment(),
Expand Down
5 changes: 3 additions & 2 deletions src/components/CalendarMonth.jsx
Expand Up @@ -3,6 +3,7 @@
import React, { PropTypes } from 'react';
import shallowCompare from 'react-addons-shallow-compare';
import momentPropTypes from 'react-moment-proptypes';
import { forbidExtraProps } from 'airbnb-prop-types';
import moment from 'moment';
import cx from 'classnames';

Expand All @@ -18,7 +19,7 @@ import {
VERTICAL_SCROLLABLE,
} from '../../constants';

const propTypes = {
const propTypes = forbidExtraProps({
month: momentPropTypes.momentObj,
isVisible: PropTypes.bool,
enableOutsideDays: PropTypes.bool,
Expand All @@ -31,7 +32,7 @@ const propTypes = {

// i18n
monthFormat: PropTypes.string,
};
});

const defaultProps = {
month: moment(),
Expand Down
5 changes: 3 additions & 2 deletions src/components/CalendarMonthGrid.jsx
@@ -1,6 +1,7 @@
import React, { PropTypes } from 'react';
import shallowCompare from 'react-addons-shallow-compare';
import momentPropTypes from 'react-moment-proptypes';
import { forbidExtraProps } from 'airbnb-prop-types';
import moment from 'moment';
import cx from 'classnames';
import { addEventListener, removeEventListener } from 'consolidated-events';
Expand All @@ -18,7 +19,7 @@ import {
VERTICAL_SCROLLABLE,
} from '../../constants';

const propTypes = {
const propTypes = forbidExtraProps({
enableOutsideDays: PropTypes.bool,
firstVisibleMonthIndex: PropTypes.number,
initialMonth: momentPropTypes.momentObj,
Expand All @@ -35,7 +36,7 @@ const propTypes = {

// i18n
monthFormat: PropTypes.string,
};
});

const defaultProps = {
enableOutsideDays: false,
Expand Down
5 changes: 3 additions & 2 deletions src/components/DateInput.jsx
@@ -1,9 +1,10 @@
import React, { PropTypes } from 'react';
import { forbidExtraProps } from 'airbnb-prop-types';
import cx from 'classnames';

import isTouchDevice from '../utils/isTouchDevice';

const propTypes = {
const propTypes = forbidExtraProps({
id: PropTypes.string.isRequired,
placeholder: PropTypes.string, // also used as label
displayValue: PropTypes.string,
Expand All @@ -18,7 +19,7 @@ const propTypes = {
onFocus: PropTypes.func,
onKeyDownShiftTab: PropTypes.func,
onKeyDownTab: PropTypes.func,
};
});

const defaultProps = {
placeholder: 'Select Date',
Expand Down
44 changes: 25 additions & 19 deletions src/components/DateRangePicker.jsx
Expand Up @@ -30,42 +30,50 @@ import {
const propTypes = DateRangePickerShape;

const defaultProps = {
// required props for a functional interactive DateRangePicker
startDate: null,
endDate: null,
focusedInput: null,

// input related props
startDateId: START_DATE,
startDatePlaceholderText: 'Start Date',
endDateId: END_DATE,
focusedInput: null,
endDatePlaceholderText: 'End Date',
disabled: false,
required: false,
screenReaderInputMessage: '',
minimumNights: 1,
isDayBlocked: () => false,
isDayHighlighted: () => false,
isOutsideRange: day => !isInclusivelyAfterDay(day, moment()),
enableOutsideDays: false,
numberOfMonths: 2,
showClearDates: false,
showDefaultInputIcon: false,
customInputIcon: null,
customArrowIcon: null,
disabled: false,
required: false,
reopenPickerOnClearDates: false,
keepOpenOnDateSelect: false,
initialVisibleMonth: null,
navPrev: null,
navNext: null,

// calendar presentation and interaction related props
orientation: HORIZONTAL_ORIENTATION,
anchorDirection: ANCHOR_LEFT,
horizontalMargin: 0,
withPortal: false,
withFullScreenPortal: false,
initialVisibleMonth: null,
numberOfMonths: 2,
keepOpenOnDateSelect: false,
reopenPickerOnClearDates: false,

onDatesChange() {},
onFocusChange() {},
// navigation related props
navPrev: null,
navNext: null,
onPrevMonthClick() {},
onNextMonthClick() {},

// day presentation and interaction related props
renderDay: null,
minimumNights: 1,
enableOutsideDays: false,
isDayBlocked: () => false,
isOutsideRange: day => !isInclusivelyAfterDay(day, moment()),
isDayHighlighted: () => false,

// i18n
// internationalization
displayFormat: () => moment.localeData().longDateFormat('L'),
monthFormat: 'MMMM YYYY',
phrases: {
Expand Down Expand Up @@ -296,7 +304,6 @@ export default class DateRangePicker extends React.Component {
keepOpenOnDateSelect,
onDatesChange,
onFocusChange,
renderDay,
} = this.props;

const onOutsideClick = (!withPortal && !withFullScreenPortal) ? this.onOutsideClick : undefined;
Expand Down Expand Up @@ -327,7 +334,6 @@ export default class DateRangePicker extends React.Component {
withFullScreenPortal={withFullScreenPortal}
onDatesChange={onDatesChange}
onFocusChange={onFocusChange}
renderDay={renderDay}
phrases={phrases}
screenReaderMessage={screenReaderInputMessage}
/>
Expand Down
5 changes: 3 additions & 2 deletions src/components/DateRangePickerInput.jsx
@@ -1,4 +1,5 @@
import React, { PropTypes } from 'react';
import { forbidExtraProps } from 'airbnb-prop-types';
import cx from 'classnames';

import DateInput from './DateInput';
Expand All @@ -8,7 +9,7 @@ import CalendarIcon from '../svg/calendar.svg';

import { START_DATE, END_DATE } from '../../constants';

const propTypes = {
const propTypes = forbidExtraProps({
startDateId: PropTypes.string,
startDatePlaceholderText: PropTypes.string,
screenReaderMessage: PropTypes.string,
Expand Down Expand Up @@ -43,7 +44,7 @@ const propTypes = {
phrases: PropTypes.shape({
clearDates: PropTypes.node,
}),
};
});

const defaultProps = {
startDateId: START_DATE,
Expand Down
5 changes: 3 additions & 2 deletions src/components/DateRangePickerInputController.jsx
Expand Up @@ -2,6 +2,7 @@ import React, { PropTypes } from 'react';
import moment from 'moment';

import momentPropTypes from 'react-moment-proptypes';
import { forbidExtraProps } from 'airbnb-prop-types';

import DateRangePickerInput from './DateRangePickerInput';

Expand All @@ -14,7 +15,7 @@ import isInclusivelyBeforeDay from '../utils/isInclusivelyBeforeDay';

import { START_DATE, END_DATE } from '../../constants';

const propTypes = {
const propTypes = forbidExtraProps({
startDate: momentPropTypes.momentObj,
startDateId: PropTypes.string,
startDatePlaceholderText: PropTypes.string,
Expand Down Expand Up @@ -48,7 +49,7 @@ const propTypes = {
phrases: PropTypes.shape({
clearDates: PropTypes.node,
}),
};
});

const defaultProps = {
startDate: null,
Expand Down

0 comments on commit 064c5af

Please sign in to comment.