diff --git a/.istanbul.yml b/.istanbul.yml
index 906b0d0971..2c38c40b53 100644
--- a/.istanbul.yml
+++ b/.istanbul.yml
@@ -7,6 +7,7 @@ instrumentation:
"public/**",
"test/**",
"coverage/**",
+ "src/defaultPhrases.js"
]
check:
global:
diff --git a/src/components/DateRangePicker.jsx b/src/components/DateRangePicker.jsx
index 5c738756bf..67c77ec3ab 100644
--- a/src/components/DateRangePicker.jsx
+++ b/src/components/DateRangePicker.jsx
@@ -7,6 +7,8 @@ import Portal from 'react-portal';
import { forbidExtraProps } from 'airbnb-prop-types';
import { addEventListener, removeEventListener } from 'consolidated-events';
+import { DateRangePickerPhrases } from '../defaultPhrases';
+
import OutsideClickHandler from './OutsideClickHandler';
import getResponsiveContainerStyles from '../utils/getResponsiveContainerStyles';
@@ -77,10 +79,7 @@ const defaultProps = {
// internationalization
displayFormat: () => moment.localeData().longDateFormat('L'),
monthFormat: 'MMMM YYYY',
- phrases: {
- closeDatePicker: 'Close',
- clearDates: 'Clear Dates',
- },
+ phrases: DateRangePickerPhrases,
};
export default class DateRangePicker extends React.Component {
diff --git a/src/components/DateRangePickerInput.jsx b/src/components/DateRangePickerInput.jsx
index 55353b62e0..c3c12a57fa 100644
--- a/src/components/DateRangePickerInput.jsx
+++ b/src/components/DateRangePickerInput.jsx
@@ -2,6 +2,9 @@ import React, { PropTypes } from 'react';
import { forbidExtraProps } from 'airbnb-prop-types';
import cx from 'classnames';
+import { DateRangePickerInputPhrases } from '../defaultPhrases';
+import getPhrasePropTypes from '../utils/getPhrasePropTypes';
+
import DateInput from './DateInput';
import RightArrow from '../svg/arrow-right.svg';
import CloseButton from '../svg/close.svg';
@@ -41,9 +44,7 @@ const propTypes = forbidExtraProps({
customArrowIcon: PropTypes.node,
// i18n
- phrases: PropTypes.shape({
- clearDates: PropTypes.node,
- }),
+ phrases: PropTypes.shape(getPhrasePropTypes(DateRangePickerInputPhrases)),
});
const defaultProps = {
@@ -76,9 +77,7 @@ const defaultProps = {
customArrowIcon: null,
// i18n
- phrases: {
- clearDates: 'Clear Dates',
- },
+ phrases: DateRangePickerInputPhrases,
};
export default class DateRangePickerInput extends React.Component {
@@ -145,13 +144,16 @@ export default class DateRangePickerInput extends React.Component {
})}
>
{(showDefaultInputIcon || customInputIcon !== null) &&
-
{inputIcon}
-
+
}
+
{!isVerticalScrollable &&
@@ -80,6 +91,7 @@ export default function DayPickerNavigation(props) {
}
diff --git a/src/components/DayPickerRangeController.jsx b/src/components/DayPickerRangeController.jsx
index 39dab68bee..160a191120 100644
--- a/src/components/DayPickerRangeController.jsx
+++ b/src/components/DayPickerRangeController.jsx
@@ -3,6 +3,9 @@ import momentPropTypes from 'react-moment-proptypes';
import { forbidExtraProps } from 'airbnb-prop-types';
import moment from 'moment';
+import { DayPickerPhrases } from '../defaultPhrases';
+import getPhrasePropTypes from '../utils/getPhrasePropTypes';
+
import isTouchDevice from '../utils/isTouchDevice';
import isInclusivelyAfterDay from '../utils/isInclusivelyAfterDay';
@@ -51,6 +54,7 @@ const propTypes = forbidExtraProps({
// i18n
monthFormat: PropTypes.string,
+ phrases: PropTypes.shape(getPhrasePropTypes(DayPickerPhrases)),
});
const defaultProps = {
@@ -86,6 +90,7 @@ const defaultProps = {
// i18n
monthFormat: 'MMMM YYYY',
+ phrases: DayPickerPhrases,
};
export default class DayPickerRangeController extends React.Component {
diff --git a/src/components/SingleDatePicker.jsx b/src/components/SingleDatePicker.jsx
index 942f217afd..b068a43e73 100644
--- a/src/components/SingleDatePicker.jsx
+++ b/src/components/SingleDatePicker.jsx
@@ -5,6 +5,8 @@ import Portal from 'react-portal';
import { forbidExtraProps } from 'airbnb-prop-types';
import { addEventListener, removeEventListener } from 'consolidated-events';
+import { SingleDatePickerPhrases } from '../defaultPhrases';
+
import OutsideClickHandler from './OutsideClickHandler';
import toMomentObject from '../utils/toMomentObject';
import toLocalizedDateString from '../utils/toLocalizedDateString';
@@ -70,10 +72,7 @@ const defaultProps = {
// internationalization props
displayFormat: () => moment.localeData().longDateFormat('L'),
monthFormat: 'MMMM YYYY',
- phrases: {
- closeDatePicker: 'Close',
- clearDate: 'Clear Date',
- },
+ phrases: SingleDatePickerPhrases,
};
export default class SingleDatePicker extends React.Component {
diff --git a/src/components/SingleDatePickerInput.jsx b/src/components/SingleDatePickerInput.jsx
index d45bffbd0f..958e44a5ec 100644
--- a/src/components/SingleDatePickerInput.jsx
+++ b/src/components/SingleDatePickerInput.jsx
@@ -2,6 +2,9 @@ import React, { PropTypes } from 'react';
import { forbidExtraProps } from 'airbnb-prop-types';
import cx from 'classnames';
+import { SingleDatePickerInputPhrases } from '../defaultPhrases';
+import getPhrasePropTypes from '../utils/getPhrasePropTypes';
+
import DateInput from './DateInput';
import CloseButton from '../svg/close.svg';
@@ -24,9 +27,7 @@ const propTypes = forbidExtraProps({
onKeyDownTab: PropTypes.func,
// i18n
- phrases: PropTypes.shape({
- clearDate: PropTypes.node,
- }),
+ phrases: PropTypes.shape(getPhrasePropTypes(SingleDatePickerInputPhrases)),
});
const defaultProps = {
@@ -47,9 +48,7 @@ const defaultProps = {
onKeyDownTab() {},
// i18n
- phrases: {
- clearDate: 'Clear Date',
- },
+ phrases: SingleDatePickerInputPhrases,
};
export default class SingleDatePickerInput extends React.Component {
@@ -122,13 +121,11 @@ export default class SingleDatePickerInput extends React.Component {
'SingleDatePickerInput__clear-date--hide': !displayValue,
'SingleDatePickerInput__clear-date--hover': isClearDateHovered,
})}
+ aria-label={phrases.clearDate}
onMouseEnter={this.onClearDateMouseEnter}
onMouseLeave={this.onClearDateMouseLeave}
onClick={onClearDate}
>
-
- {phrases.clearDate}
-
}
diff --git a/src/defaultPhrases.js b/src/defaultPhrases.js
new file mode 100644
index 0000000000..f572af5ce5
--- /dev/null
+++ b/src/defaultPhrases.js
@@ -0,0 +1,49 @@
+const closeDatePicker = 'Close';
+const focusStartDate = 'Focus on start date';
+const clearDate = 'Clear Date';
+const clearDates = 'Clear Dates';
+const jumpToPrevMonth = 'Jump to previous month';
+const jumpToNextMonth = 'Jump to next month';
+
+export default {
+ closeDatePicker,
+ focusStartDate,
+ clearDate,
+ clearDates,
+ jumpToPrevMonth,
+ jumpToNextMonth,
+};
+
+export const DateRangePickerPhrases = {
+ closeDatePicker,
+ clearDates,
+ focusStartDate,
+ jumpToPrevMonth,
+ jumpToNextMonth,
+};
+
+export const DateRangePickerInputPhrases = {
+ focusStartDate,
+ clearDates,
+};
+
+export const SingleDatePickerPhrases = {
+ closeDatePicker,
+ clearDate,
+ jumpToPrevMonth,
+ jumpToNextMonth,
+};
+
+export const SingleDatePickerInputPhrases = {
+ clearDate,
+};
+
+export const DayPickerPhrases = {
+ jumpToPrevMonth,
+ jumpToNextMonth,
+};
+
+export const DayPickerNavigationPhrases = {
+ jumpToPrevMonth,
+ jumpToNextMonth,
+};
diff --git a/src/shapes/DateRangePickerShape.js b/src/shapes/DateRangePickerShape.js
index c3d86a5bf1..cdd811e118 100644
--- a/src/shapes/DateRangePickerShape.js
+++ b/src/shapes/DateRangePickerShape.js
@@ -1,6 +1,9 @@
import { PropTypes } from 'react';
import momentPropTypes from 'react-moment-proptypes';
+import { DateRangePickerPhrases } from '../defaultPhrases';
+import getPhrasePropTypes from '../utils/getPhrasePropTypes';
+
import FocusedInputShape from '../shapes/FocusedInputShape';
import OrientationShape from '../shapes/OrientationShape';
import anchorDirectionShape from '../shapes/AnchorDirectionShape';
@@ -55,8 +58,5 @@ export default {
// internationalization props
displayFormat: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),
monthFormat: PropTypes.string,
- phrases: PropTypes.shape({
- closeDatePicker: PropTypes.node,
- clearDates: PropTypes.node,
- }),
+ phrases: PropTypes.shape(getPhrasePropTypes(DateRangePickerPhrases)),
};
diff --git a/src/shapes/SingleDatePickerShape.js b/src/shapes/SingleDatePickerShape.js
index e2fe4635b8..394fc64607 100644
--- a/src/shapes/SingleDatePickerShape.js
+++ b/src/shapes/SingleDatePickerShape.js
@@ -1,6 +1,9 @@
import { PropTypes } from 'react';
import momentPropTypes from 'react-moment-proptypes';
+import { SingleDatePickerPhrases } from '../defaultPhrases';
+import getPhrasePropTypes from '../utils/getPhrasePropTypes';
+
import OrientationShape from '../shapes/OrientationShape';
import anchorDirectionShape from '../shapes/AnchorDirectionShape';
@@ -47,7 +50,5 @@ export default {
// internationalization props
displayFormat: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),
monthFormat: PropTypes.string,
- phrases: PropTypes.shape({
- closeDatePicker: PropTypes.node,
- }),
+ phrases: PropTypes.shape(getPhrasePropTypes(SingleDatePickerPhrases)),
};
diff --git a/src/utils/getPhrasePropTypes.js b/src/utils/getPhrasePropTypes.js
new file mode 100644
index 0000000000..afa6054e7c
--- /dev/null
+++ b/src/utils/getPhrasePropTypes.js
@@ -0,0 +1,6 @@
+import { PropTypes } from 'react';
+
+export default function getPhrasePropTypes(defaultPhrases) {
+ return Object.keys(defaultPhrases)
+ .reduce((phrases, key) => ({ ...phrases, [key]: PropTypes.node }), {});
+}
diff --git a/test/utils/getPhrasePropTypes_spec.js b/test/utils/getPhrasePropTypes_spec.js
new file mode 100644
index 0000000000..b9f0776875
--- /dev/null
+++ b/test/utils/getPhrasePropTypes_spec.js
@@ -0,0 +1,26 @@
+import { expect } from 'chai';
+import { PropTypes } from 'react';
+
+import getPhrasePropTypes from '../../src/utils/getPhrasePropTypes';
+
+const PhraseObject = {
+ foo: 'x',
+ bar: 'y',
+ baz: 'z',
+};
+
+describe('#getPhrasePropTypes', () => {
+ it('contains each key from the original object', () => {
+ const propTypes = getPhrasePropTypes(PhraseObject);
+ Object.keys(PhraseObject).forEach((key) => {
+ expect(Object.keys(propTypes).filter(type => type === key).length).to.not.equal(0);
+ });
+ });
+
+ it('each value is equal to PropTypes.node', () => {
+ const propTypes = getPhrasePropTypes(PhraseObject);
+ Object.values(propTypes).forEach((value) => {
+ expect(value).to.equal(PropTypes.node);
+ });
+ });
+});