react-date-picker
Advanced tools
Comparing version 7.4.0 to 7.5.0
@@ -161,20 +161,24 @@ "use strict"; | ||
var isValidInput = function isValidInput(element) { | ||
return element.tagName === 'INPUT' && element.type === 'number'; | ||
}; | ||
var findPreviousInput = function findPreviousInput(element) { | ||
var previousElement = element.previousElementSibling; // Divider between inputs | ||
var previousElement = element; | ||
if (!previousElement) { | ||
return null; | ||
} | ||
do { | ||
previousElement = previousElement.previousElementSibling; | ||
} while (previousElement && !isValidInput(previousElement)); | ||
return previousElement.previousElementSibling; // Actual input | ||
return previousElement; | ||
}; | ||
var findNextInput = function findNextInput(element) { | ||
var nextElement = element.nextElementSibling; // Divider between inputs | ||
var nextElement = element; | ||
if (!nextElement) { | ||
return null; | ||
} | ||
do { | ||
nextElement = nextElement.nextElementSibling; | ||
} while (nextElement && !isValidInput(nextElement)); | ||
return nextElement.nextElementSibling; // Actual input | ||
return nextElement; | ||
}; | ||
@@ -187,3 +191,5 @@ | ||
var _renderCustomInputs = function renderCustomInputs(placeholder, elementFunctions) { | ||
var pattern = new RegExp(Object.keys(elementFunctions).join('|'), 'gi'); | ||
var pattern = new RegExp(Object.keys(elementFunctions).map(function (el) { | ||
return "".concat(el, "+"); | ||
}).join('|'), 'g'); | ||
var matches = placeholder.match(pattern); | ||
@@ -197,5 +203,9 @@ return placeholder.split(pattern).reduce(function (arr, element, index) { | ||
var res = [].concat(_toConsumableArray(arr), [divider]); | ||
var currentMatch = matches && matches[index]; | ||
if (matches && matches[index]) { | ||
res.push(elementFunctions[matches[index]]()); | ||
if (currentMatch) { | ||
var renderFunction = elementFunctions[currentMatch] || elementFunctions[Object.keys(elementFunctions).find(function (elementFunction) { | ||
return currentMatch.match(elementFunction); | ||
})]; | ||
res.push(renderFunction(currentMatch)); | ||
} | ||
@@ -234,7 +244,3 @@ | ||
// Wrapper was directly clicked | ||
var _event$target$childre = _slicedToArray(event.target.children, 2), | ||
/* nativeInput */ | ||
firstInput = _event$target$childre[1]; | ||
var firstInput = event.target.children[1]; | ||
focus(firstInput); | ||
@@ -333,6 +339,4 @@ } | ||
_defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "renderDay", function () { | ||
var _this$props = _this.props, | ||
maxDetail = _this$props.maxDetail, | ||
showLeadingZeros = _this$props.showLeadingZeros; | ||
_defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "renderDay", function (currentMatch) { | ||
var showLeadingZeros = _this.props.showLeadingZeros; | ||
var _this$state = _this.state, | ||
@@ -342,8 +346,13 @@ value = _this$state.day, | ||
year = _this$state.year; | ||
if (currentMatch && currentMatch.length > 2) { | ||
throw new Error("Unsupported token: ".concat(currentMatch)); | ||
} | ||
var showLeadingZerosFromFormat = currentMatch && currentMatch.length === 2; | ||
return _react.default.createElement(_DayInput.default, _extends({ | ||
key: "day" | ||
}, _this.commonInputProps, { | ||
maxDetail: maxDetail, | ||
month: month, | ||
showLeadingZeros: showLeadingZeros, | ||
showLeadingZeros: showLeadingZerosFromFormat || showLeadingZeros, | ||
value: value, | ||
@@ -354,14 +363,17 @@ year: year | ||
_defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "renderMonth", function () { | ||
var _this$props2 = _this.props, | ||
maxDetail = _this$props2.maxDetail, | ||
showLeadingZeros = _this$props2.showLeadingZeros; | ||
_defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "renderMonth", function (currentMatch) { | ||
var showLeadingZeros = _this.props.showLeadingZeros; | ||
var _this$state2 = _this.state, | ||
value = _this$state2.month, | ||
year = _this$state2.year; | ||
if (currentMatch && currentMatch.length > 2) { | ||
throw new Error("Unsupported token: ".concat(currentMatch)); | ||
} | ||
var showLeadingZerosFromFormat = currentMatch && currentMatch.length === 2; | ||
return _react.default.createElement(_MonthInput.default, _extends({ | ||
key: "month" | ||
}, _this.commonInputProps, { | ||
maxDetail: maxDetail, | ||
showLeadingZeros: showLeadingZeros, | ||
showLeadingZeros: showLeadingZerosFromFormat || showLeadingZeros, | ||
value: value, | ||
@@ -392,7 +404,7 @@ year: year | ||
value: function getProcessedValue(value) { | ||
var _this$props3 = this.props, | ||
minDate = _this$props3.minDate, | ||
maxDate = _this$props3.maxDate, | ||
maxDetail = _this$props3.maxDetail, | ||
returnValue = _this$props3.returnValue; | ||
var _this$props = this.props, | ||
minDate = _this$props.minDate, | ||
maxDate = _this$props.maxDate, | ||
maxDetail = _this$props.maxDetail, | ||
returnValue = _this$props.returnValue; | ||
@@ -418,5 +430,5 @@ switch (returnValue) { | ||
var elementFunctions = { | ||
day: this.renderDay, | ||
month: this.renderMonth, | ||
year: this.renderYear | ||
d: this.renderDay, | ||
M: this.renderMonth, | ||
y: this.renderYear | ||
}; | ||
@@ -428,9 +440,9 @@ return _renderCustomInputs(placeholder, elementFunctions); | ||
value: function renderNativeInput() { | ||
var _this$props4 = this.props, | ||
disabled = _this$props4.disabled, | ||
maxDate = _this$props4.maxDate, | ||
minDate = _this$props4.minDate, | ||
name = _this$props4.name, | ||
required = _this$props4.required, | ||
value = _this$props4.value; | ||
var _this$props2 = this.props, | ||
disabled = _this$props2.disabled, | ||
maxDate = _this$props2.maxDate, | ||
minDate = _this$props2.minDate, | ||
name = _this$props2.name, | ||
required = _this$props2.required, | ||
value = _this$props2.value; | ||
return _react.default.createElement(_NativeInput.default, { | ||
@@ -461,5 +473,5 @@ key: "date", | ||
get: function get() { | ||
var _this$props5 = this.props, | ||
locale = _this$props5.locale, | ||
maxDetail = _this$props5.maxDetail; | ||
var _this$props3 = this.props, | ||
locale = _this$props3.locale, | ||
maxDetail = _this$props3.maxDetail; | ||
var options = { | ||
@@ -492,4 +504,3 @@ year: 'numeric' | ||
get: function get() { | ||
var date = new Date(2017, 11, 11); | ||
return this.formatDate(date).match(/[^0-9]/)[0]; | ||
return this.placeholder.match(/[^0-9a-z]/i)[0]; | ||
} | ||
@@ -499,2 +510,8 @@ }, { | ||
get: function get() { | ||
var format = this.props.format; | ||
if (format) { | ||
return format; | ||
} | ||
var year = 2017; | ||
@@ -504,3 +521,3 @@ var monthIndex = 11; | ||
var date = new Date(year, monthIndex, day); | ||
return this.formatDate(date).replace(this.formatNumber(year), 'year').replace(this.formatNumber(monthIndex + 1), 'month').replace(this.formatNumber(day), 'day'); | ||
return this.formatDate(date).replace(this.formatNumber(year), 'y').replace(this.formatNumber(monthIndex + 1), 'M').replace(this.formatNumber(day), 'd'); | ||
} | ||
@@ -512,9 +529,9 @@ }, { | ||
var _this$props6 = this.props, | ||
className = _this$props6.className, | ||
disabled = _this$props6.disabled, | ||
isCalendarOpen = _this$props6.isCalendarOpen, | ||
maxDate = _this$props6.maxDate, | ||
minDate = _this$props6.minDate, | ||
required = _this$props6.required; | ||
var _this$props4 = this.props, | ||
className = _this$props4.className, | ||
disabled = _this$props4.disabled, | ||
isCalendarOpen = _this$props4.isCalendarOpen, | ||
maxDate = _this$props4.maxDate, | ||
minDate = _this$props4.minDate, | ||
required = _this$props4.required; | ||
return { | ||
@@ -609,4 +626,4 @@ className: className, | ||
onChange: _propTypes.default.func, | ||
required: _propTypes.default.bool, | ||
returnValue: _propTypes.default.oneOf(['start', 'end', 'range']), | ||
required: _propTypes.default.bool, | ||
showLeadingZeros: _propTypes.default.bool, | ||
@@ -613,0 +630,0 @@ value: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.instanceOf(Date)]) |
@@ -12,3 +12,3 @@ "use strict"; | ||
var _mergeClassNames = _interopRequireDefault(require("merge-class-names")); | ||
var _Input = _interopRequireDefault(require("./Input")); | ||
@@ -27,2 +27,8 @@ var _dates = require("../shared/dates"); | ||
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } | ||
function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; } | ||
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; } | ||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | ||
@@ -44,6 +50,2 @@ | ||
var select = function select(element) { | ||
return element && element.select(); | ||
}; | ||
var DayInput = | ||
@@ -65,46 +67,15 @@ /*#__PURE__*/ | ||
minDay = this.minDay; | ||
var _this$props = this.props, | ||
className = _this$props.className, | ||
disabled = _this$props.disabled, | ||
itemRef = _this$props.itemRef, | ||
value = _this$props.value, | ||
onChange = _this$props.onChange, | ||
onKeyDown = _this$props.onKeyDown, | ||
required = _this$props.required, | ||
showLeadingZeros = _this$props.showLeadingZeros; | ||
var name = 'day'; | ||
var hasLeadingZero = showLeadingZeros && value !== null && value < 10; | ||
return [hasLeadingZero && _react.default.createElement("span", { | ||
key: "leadingZero", | ||
className: "".concat(className, "__leadingZero") | ||
}, "0"), _react.default.createElement("input", { | ||
key: "day", | ||
autoComplete: "off", | ||
className: (0, _mergeClassNames.default)("".concat(className, "__input"), "".concat(className, "__day"), hasLeadingZero && "".concat(className, "__input--hasLeadingZero")), | ||
disabled: disabled, | ||
name: name, | ||
maxDate = _this$props.maxDate, | ||
minDate = _this$props.minDate, | ||
month = _this$props.month, | ||
year = _this$props.year, | ||
otherProps = _objectWithoutProperties(_this$props, ["maxDate", "minDate", "month", "year"]); | ||
return _react.default.createElement(_Input.default, _extends({ | ||
name: "day", | ||
max: maxDay, | ||
min: minDay, | ||
onChange: onChange, | ||
onFocus: function onFocus(event) { | ||
return select(event.target); | ||
}, | ||
onKeyDown: onKeyDown, | ||
onKeyUp: function onKeyUp(event) { | ||
return (0, _utils.updateInputWidth)(event.target); | ||
}, | ||
placeholder: "--", | ||
ref: function ref(_ref) { | ||
if (_ref) { | ||
(0, _utils.updateInputWidth)(_ref); | ||
} | ||
if (itemRef) { | ||
itemRef(_ref, name); | ||
} | ||
}, | ||
required: required, | ||
type: "number", | ||
value: value !== null ? value : '' | ||
})]; | ||
min: minDay | ||
}, otherProps)); | ||
} | ||
@@ -111,0 +82,0 @@ }, { |
@@ -12,3 +12,3 @@ "use strict"; | ||
var _mergeClassNames = _interopRequireDefault(require("merge-class-names")); | ||
var _Input = _interopRequireDefault(require("./Input")); | ||
@@ -27,2 +27,8 @@ var _dates = require("../shared/dates"); | ||
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } | ||
function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; } | ||
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; } | ||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | ||
@@ -44,6 +50,2 @@ | ||
var select = function select(element) { | ||
return element && element.select(); | ||
}; | ||
var MonthInput = | ||
@@ -65,46 +67,14 @@ /*#__PURE__*/ | ||
minMonth = this.minMonth; | ||
var _this$props = this.props, | ||
className = _this$props.className, | ||
disabled = _this$props.disabled, | ||
itemRef = _this$props.itemRef, | ||
value = _this$props.value, | ||
onChange = _this$props.onChange, | ||
onKeyDown = _this$props.onKeyDown, | ||
required = _this$props.required, | ||
showLeadingZeros = _this$props.showLeadingZeros; | ||
var name = 'month'; | ||
var hasLeadingZero = showLeadingZeros && value !== null && value < 10; | ||
return [hasLeadingZero && _react.default.createElement("span", { | ||
key: "leadingZero", | ||
className: "".concat(className, "__leadingZero") | ||
}, "0"), _react.default.createElement("input", { | ||
key: "month", | ||
autoComplete: "off", | ||
className: (0, _mergeClassNames.default)("".concat(className, "__input"), "".concat(className, "__month"), hasLeadingZero && "".concat(className, "__input--hasLeadingZero")), | ||
disabled: disabled, | ||
name: name, | ||
maxDate = _this$props.maxDate, | ||
minDate = _this$props.minDate, | ||
year = _this$props.year, | ||
otherProps = _objectWithoutProperties(_this$props, ["maxDate", "minDate", "year"]); | ||
return _react.default.createElement(_Input.default, _extends({ | ||
name: "month", | ||
max: maxMonth, | ||
min: minMonth, | ||
onChange: onChange, | ||
onFocus: function onFocus(event) { | ||
return select(event.target); | ||
}, | ||
onKeyDown: onKeyDown, | ||
onKeyUp: function onKeyUp(event) { | ||
return (0, _utils.updateInputWidth)(event.target); | ||
}, | ||
placeholder: "--", | ||
ref: function ref(_ref) { | ||
if (_ref) { | ||
(0, _utils.updateInputWidth)(_ref); | ||
} | ||
if (itemRef) { | ||
itemRef(_ref, name); | ||
} | ||
}, | ||
type: "number", | ||
required: required, | ||
value: value !== null ? value : '' | ||
})]; | ||
min: minMonth | ||
}, otherProps)); | ||
} | ||
@@ -111,0 +81,0 @@ }, { |
@@ -12,3 +12,3 @@ "use strict"; | ||
var _mergeClassNames = _interopRequireDefault(require("merge-class-names")); | ||
var _Input = _interopRequireDefault(require("./Input")); | ||
@@ -27,2 +27,8 @@ var _dates = require("../shared/dates"); | ||
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } | ||
function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; } | ||
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; } | ||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | ||
@@ -44,6 +50,2 @@ | ||
var select = function select(element) { | ||
return element && element.select(); | ||
}; | ||
var YearInput = | ||
@@ -66,41 +68,16 @@ /*#__PURE__*/ | ||
yearStep = this.yearStep; | ||
var _this$props = this.props, | ||
className = _this$props.className, | ||
disabled = _this$props.disabled, | ||
itemRef = _this$props.itemRef, | ||
value = _this$props.value, | ||
onChange = _this$props.onChange, | ||
onKeyDown = _this$props.onKeyDown, | ||
required = _this$props.required; | ||
var name = 'year'; | ||
return _react.default.createElement("input", { | ||
autoComplete: "off", | ||
className: (0, _mergeClassNames.default)("".concat(className, "__input"), "".concat(className, "__year")), | ||
disabled: disabled, | ||
name: name, | ||
maxDate = _this$props.maxDate, | ||
minDate = _this$props.minDate, | ||
valueType = _this$props.valueType, | ||
otherProps = _objectWithoutProperties(_this$props, ["maxDate", "minDate", "valueType"]); | ||
return _react.default.createElement(_Input.default, _extends({ | ||
name: "year", | ||
max: maxYear, | ||
min: minYear, | ||
onChange: onChange, | ||
onFocus: function onFocus(event) { | ||
return select(event.target); | ||
}, | ||
onKeyDown: onKeyDown, | ||
onKeyUp: function onKeyUp(event) { | ||
return (0, _utils.updateInputWidth)(event.target); | ||
}, | ||
placeholder: "----", | ||
ref: function ref(_ref) { | ||
if (_ref) { | ||
(0, _utils.updateInputWidth)(_ref); | ||
} | ||
if (itemRef) { | ||
itemRef(_ref, name); | ||
} | ||
}, | ||
required: required, | ||
step: yearStep, | ||
type: "number", | ||
value: value !== null ? value : '' | ||
}); | ||
step: yearStep | ||
}, otherProps)); | ||
} | ||
@@ -107,0 +84,0 @@ }, { |
@@ -193,2 +193,3 @@ "use strict"; | ||
disabled = _this$props3.disabled, | ||
format = _this$props3.format, | ||
locale = _this$props3.locale, | ||
@@ -214,2 +215,3 @@ maxDate = _this$props3.maxDate, | ||
disabled: disabled, | ||
format: format, | ||
locale: locale, | ||
@@ -372,6 +374,8 @@ isCalendarOpen: isOpen, | ||
name: _propTypes.default.string, | ||
onCalendarClose: _propTypes.default.func, | ||
onCalendarOpen: _propTypes.default.func, | ||
required: _propTypes.default.bool, | ||
returnValue: _propTypes.default.oneOf(['start', 'end', 'range']), | ||
required: _propTypes.default.bool, | ||
showLeadingZeros: _propTypes.default.bool | ||
}); | ||
(0, _reactLifecyclesCompat.polyfill)(DatePicker); |
{ | ||
"name": "react-date-picker", | ||
"version": "7.4.0", | ||
"version": "7.5.0", | ||
"description": "A date picker for your React app.", | ||
@@ -29,2 +29,5 @@ "main": "dist/entry.js", | ||
"!**/src/entry.nostyle.js" | ||
], | ||
"testPathIgnorePatterns": [ | ||
"utils.js" | ||
] | ||
@@ -31,0 +34,0 @@ }, |
@@ -102,2 +102,3 @@ [![npm](https://img.shields.io/npm/v/react-date-picker.svg)](https://www.npmjs.com/package/react-date-picker) ![downloads](https://img.shields.io/npm/dt/react-date-picker.svg) ![build](https://img.shields.io/travis/wojtekmaj/react-date-picker/master.svg) ![dependencies](https://img.shields.io/david/wojtekmaj/react-date-picker.svg) ![dev dependencies](https://img.shields.io/david/dev/wojtekmaj/react-date-picker.svg) [![tested with jest](https://img.shields.io/badge/tested_with-jest-99424f.svg)](https://github.com/facebook/jest) | ||
|disabled|Defines whether the date picker should be disabled. Defaults to false.|`true`| | ||
|format|Defines input format based on [Unicode Technical Standard #35](https://www.unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table). Supported values are: `y`, `M`, `MM`, `d`, `dd`.|`"y-MM-dd"`| | ||
|isOpen|Defines whether the calendar should be opened. Defaults to false.|`true`| | ||
@@ -104,0 +105,0 @@ |locale|Defines which locale should be used by the date picker and the calendar. Can be any [IETF language tag](https://en.wikipedia.org/wiki/IETF_language_tag). Defaults to user's browser settings.|`"hu-HU"`| |
@@ -6,4 +6,18 @@ import React from 'react'; | ||
import { muteConsole, restoreConsole } from './utils'; | ||
/* eslint-disable comma-dangle */ | ||
const hasFullICU = (() => { | ||
try { | ||
const date = new Date(2018, 0, 1, 21); | ||
const formatter = new Intl.DateTimeFormat('de-DE', { hour: 'numeric' }); | ||
return formatter.format(date) === '21'; | ||
} catch (err) { | ||
return false; | ||
} | ||
})(); | ||
const itIfFullICU = hasFullICU ? it : it.skip; | ||
const keyCodes = { | ||
@@ -99,2 +113,22 @@ ArrowLeft: 37, | ||
itIfFullICU('shows a given date in all inputs correctly (de-DE locale)', () => { | ||
const date = new Date(2017, 8, 30); | ||
const component = mount( | ||
<DateInput | ||
{...defaultProps} | ||
locale="de-DE" | ||
value={date} | ||
/> | ||
); | ||
const nativeInput = component.find('input[type="date"]'); | ||
const customInputs = component.find('input[type="number"]'); | ||
expect(nativeInput.getDOMNode().value).toBe('2017-09-30'); | ||
expect(customInputs.at(0).getDOMNode().value).toBe('2017'); | ||
expect(customInputs.at(1).getDOMNode().value).toBe('9'); | ||
expect(customInputs.at(2).getDOMNode().value).toBe('30'); | ||
}); | ||
it('shows empty value in all inputs correctly', () => { | ||
@@ -150,2 +184,163 @@ const component = mount( | ||
itIfFullICU('renders custom inputs in a proper order (de-DE locale)', () => { | ||
const component = mount( | ||
<DateInput | ||
{...defaultProps} | ||
locale="de-DE" | ||
/> | ||
); | ||
const customInputs = component.find('input[type="number"]'); | ||
expect(customInputs.at(0).prop('name')).toBe('year'); | ||
expect(customInputs.at(1).prop('name')).toBe('month'); | ||
expect(customInputs.at(2).prop('name')).toBe('day'); | ||
}); | ||
describe('renders custom inputs in a proper order given format', () => { | ||
it('renders "y" properly', () => { | ||
const component = mount( | ||
<DateInput | ||
{...defaultProps} | ||
format="y" | ||
/> | ||
); | ||
const componentInput = component.find('YearInput'); | ||
const customInputs = component.find('input[type="number"]'); | ||
expect(componentInput).toHaveLength(1); | ||
expect(customInputs).toHaveLength(1); | ||
}); | ||
it('renders "yyyy" properly', () => { | ||
const component = mount( | ||
<DateInput | ||
{...defaultProps} | ||
format="yyyy" | ||
/> | ||
); | ||
const componentInput = component.find('YearInput'); | ||
const customInputs = component.find('input[type="number"]'); | ||
expect(componentInput).toHaveLength(1); | ||
expect(customInputs).toHaveLength(1); | ||
}); | ||
it('renders "M" properly', () => { | ||
const component = mount( | ||
<DateInput | ||
{...defaultProps} | ||
format="M" | ||
/> | ||
); | ||
const componentInput = component.find('MonthInput'); | ||
const customInputs = component.find('input[type="number"]'); | ||
expect(componentInput).toHaveLength(1); | ||
expect(customInputs).toHaveLength(1); | ||
}); | ||
it('renders "MM" properly', () => { | ||
const component = mount( | ||
<DateInput | ||
{...defaultProps} | ||
format="MM" | ||
/> | ||
); | ||
const componentInput = component.find('MonthInput'); | ||
const customInputs = component.find('input[type="number"]'); | ||
expect(componentInput).toHaveLength(1); | ||
expect(customInputs).toHaveLength(1); | ||
expect(componentInput.prop('showLeadingZeros')).toBeTruthy(); | ||
}); | ||
it('throws error for "MMM"', () => { | ||
muteConsole(); | ||
const renderComponent = () => mount( | ||
<DateInput | ||
{...defaultProps} | ||
format="MMM" | ||
/> | ||
); | ||
expect(renderComponent).toThrow('Unsupported token: MMM'); | ||
restoreConsole(); | ||
}); | ||
it('renders "d" properly', () => { | ||
const component = mount( | ||
<DateInput | ||
{...defaultProps} | ||
format="d" | ||
/> | ||
); | ||
const componentInput = component.find('DayInput'); | ||
const customInputs = component.find('input[type="number"]'); | ||
expect(componentInput).toHaveLength(1); | ||
expect(customInputs).toHaveLength(1); | ||
}); | ||
it('renders "dd" properly', () => { | ||
const component = mount( | ||
<DateInput | ||
{...defaultProps} | ||
format="dd" | ||
/> | ||
); | ||
const componentInput = component.find('DayInput'); | ||
const customInputs = component.find('input[type="number"]'); | ||
expect(componentInput).toHaveLength(1); | ||
expect(customInputs).toHaveLength(1); | ||
expect(componentInput.prop('showLeadingZeros')).toBeTruthy(); | ||
}); | ||
it('throws error for "ddd"', () => { | ||
muteConsole(); | ||
const renderComponent = () => mount( | ||
<DateInput | ||
{...defaultProps} | ||
format="ddd" | ||
/> | ||
); | ||
expect(renderComponent).toThrow('Unsupported token: ddd'); | ||
restoreConsole(); | ||
}); | ||
it('renders "yyyy-MM-dd" properly', () => { | ||
const component = mount( | ||
<DateInput | ||
{...defaultProps} | ||
format="yyyy-MM-d" | ||
/> | ||
); | ||
const monthInput = component.find('MonthInput'); | ||
const dayInput = component.find('DayInput'); | ||
const customInputs = component.find('input[type="number"]'); | ||
expect(monthInput).toHaveLength(1); | ||
expect(dayInput).toHaveLength(1); | ||
expect(customInputs).toHaveLength(3); | ||
expect(customInputs.at(0).prop('name')).toBe('year'); | ||
expect(customInputs.at(1).prop('name')).toBe('month'); | ||
expect(customInputs.at(2).prop('name')).toBe('day'); | ||
expect(monthInput.prop('showLeadingZeros')).toBeTruthy(); | ||
expect(dayInput.prop('showLeadingZeros')).toBeFalsy(); | ||
}); | ||
}); | ||
it('renders proper input separators', () => { | ||
@@ -152,0 +347,0 @@ const component = mount( |
@@ -203,2 +203,41 @@ import React from 'react'; | ||
}); | ||
it('closes Calendar when calling internal onChange', () => { | ||
const component = mount( | ||
<DatePicker isOpen /> | ||
); | ||
const { onChange } = component.instance(); | ||
onChange(new Date()); | ||
expect(component.state('isOpen')).toBe(false); | ||
}); | ||
it('does not close Calendar when calling internal onChange with closeCalendar = false', () => { | ||
const component = mount( | ||
<DatePicker isOpen /> | ||
); | ||
const { onChange } = component.instance(); | ||
onChange(new Date(), false); | ||
expect(component.state('isOpen')).toBe(true); | ||
}); | ||
it('calls onChange callback when calling internal onChange', () => { | ||
const nextValue = new Date(2019, 0, 1); | ||
const onChange = jest.fn(); | ||
const component = mount( | ||
<DatePicker onChange={onChange} /> | ||
); | ||
const { onChange: onChangeInternal } = component.instance(); | ||
onChangeInternal(nextValue); | ||
expect(onChange).toHaveBeenCalledWith(nextValue); | ||
}); | ||
}); |
@@ -113,16 +113,18 @@ import React, { PureComponent } from 'react'; | ||
const isValidInput = element => element.tagName === 'INPUT' && element.type === 'number'; | ||
const findPreviousInput = (element) => { | ||
const previousElement = element.previousElementSibling; // Divider between inputs | ||
if (!previousElement) { | ||
return null; | ||
} | ||
return previousElement.previousElementSibling; // Actual input | ||
let previousElement = element; | ||
do { | ||
previousElement = previousElement.previousElementSibling; | ||
} while (previousElement && !isValidInput(previousElement)); | ||
return previousElement; | ||
}; | ||
const findNextInput = (element) => { | ||
const nextElement = element.nextElementSibling; // Divider between inputs | ||
if (!nextElement) { | ||
return null; | ||
} | ||
return nextElement.nextElementSibling; // Actual input | ||
let nextElement = element; | ||
do { | ||
nextElement = nextElement.nextElementSibling; | ||
} while (nextElement && !isValidInput(nextElement)); | ||
return nextElement; | ||
}; | ||
@@ -133,4 +135,7 @@ | ||
const renderCustomInputs = (placeholder, elementFunctions) => { | ||
const pattern = new RegExp(Object.keys(elementFunctions).join('|'), 'gi'); | ||
const pattern = new RegExp( | ||
Object.keys(elementFunctions).map(el => `${el}+`).join('|'), 'g', | ||
); | ||
const matches = placeholder.match(pattern); | ||
return placeholder.split(pattern) | ||
@@ -145,4 +150,12 @@ .reduce((arr, element, index) => { | ||
const res = [...arr, divider]; | ||
if (matches && matches[index]) { | ||
res.push(elementFunctions[matches[index]]()); | ||
const currentMatch = matches && matches[index]; | ||
if (currentMatch) { | ||
const renderFunction = ( | ||
elementFunctions[currentMatch] | ||
|| elementFunctions[ | ||
Object.keys(elementFunctions) | ||
.find(elementFunction => currentMatch.match(elementFunction)) | ||
] | ||
); | ||
res.push(renderFunction(currentMatch)); | ||
} | ||
@@ -251,8 +264,12 @@ return res; | ||
get divider() { | ||
const date = new Date(2017, 11, 11); | ||
return this.formatDate(date).match(/[^0-9]/)[0]; | ||
return this.placeholder.match(/[^0-9a-z]/i)[0]; | ||
} | ||
get placeholder() { | ||
const { format } = this.props; | ||
if (format) { | ||
return format; | ||
} | ||
const year = 2017; | ||
@@ -266,5 +283,5 @@ const monthIndex = 11; | ||
this.formatDate(date) | ||
.replace(this.formatNumber(year), 'year') | ||
.replace(this.formatNumber(monthIndex + 1), 'month') | ||
.replace(this.formatNumber(day), 'day') | ||
.replace(this.formatNumber(year), 'y') | ||
.replace(this.formatNumber(monthIndex + 1), 'M') | ||
.replace(this.formatNumber(day), 'd') | ||
); | ||
@@ -308,3 +325,3 @@ } | ||
// Wrapper was directly clicked | ||
const [/* nativeInput */, firstInput] = event.target.children; | ||
const firstInput = event.target.children[1]; | ||
focus(firstInput); | ||
@@ -405,6 +422,12 @@ } | ||
renderDay = () => { | ||
const { maxDetail, showLeadingZeros } = this.props; | ||
renderDay = (currentMatch) => { | ||
const { showLeadingZeros } = this.props; | ||
const { day: value, month, year } = this.state; | ||
if (currentMatch && currentMatch.length > 2) { | ||
throw new Error(`Unsupported token: ${currentMatch}`); | ||
} | ||
const showLeadingZerosFromFormat = currentMatch && currentMatch.length === 2; | ||
return ( | ||
@@ -414,5 +437,4 @@ <DayInput | ||
{...this.commonInputProps} | ||
maxDetail={maxDetail} | ||
month={month} | ||
showLeadingZeros={showLeadingZeros} | ||
showLeadingZeros={showLeadingZerosFromFormat || showLeadingZeros} | ||
value={value} | ||
@@ -424,6 +446,12 @@ year={year} | ||
renderMonth = () => { | ||
const { maxDetail, showLeadingZeros } = this.props; | ||
renderMonth = (currentMatch) => { | ||
const { showLeadingZeros } = this.props; | ||
const { month: value, year } = this.state; | ||
if (currentMatch && currentMatch.length > 2) { | ||
throw new Error(`Unsupported token: ${currentMatch}`); | ||
} | ||
const showLeadingZerosFromFormat = currentMatch && currentMatch.length === 2; | ||
return ( | ||
@@ -433,4 +461,3 @@ <MonthInput | ||
{...this.commonInputProps} | ||
maxDetail={maxDetail} | ||
showLeadingZeros={showLeadingZeros} | ||
showLeadingZeros={showLeadingZerosFromFormat || showLeadingZeros} | ||
value={value} | ||
@@ -458,5 +485,5 @@ year={year} | ||
const elementFunctions = { | ||
day: this.renderDay, | ||
month: this.renderMonth, | ||
year: this.renderYear, | ||
d: this.renderDay, | ||
M: this.renderMonth, | ||
y: this.renderYear, | ||
}; | ||
@@ -524,4 +551,4 @@ | ||
onChange: PropTypes.func, | ||
required: PropTypes.bool, | ||
returnValue: PropTypes.oneOf(['start', 'end', 'range']), | ||
required: PropTypes.bool, | ||
showLeadingZeros: PropTypes.bool, | ||
@@ -528,0 +555,0 @@ value: PropTypes.oneOfType([ |
import React, { PureComponent } from 'react'; | ||
import PropTypes from 'prop-types'; | ||
import mergeClassNames from 'merge-class-names'; | ||
import Input from './Input'; | ||
import { | ||
@@ -12,6 +13,4 @@ getDay, | ||
import { isMaxDate, isMinDate } from '../shared/propTypes'; | ||
import { min, max, updateInputWidth } from '../shared/utils'; | ||
import { min, max } from '../shared/utils'; | ||
const select = element => element && element.select(); | ||
export default class DayInput extends PureComponent { | ||
@@ -46,41 +45,17 @@ get currentMonthMaxDays() { | ||
const { | ||
className, disabled, itemRef, value, onChange, onKeyDown, required, showLeadingZeros, | ||
maxDate, | ||
minDate, | ||
month, | ||
year, | ||
...otherProps | ||
} = this.props; | ||
const name = 'day'; | ||
const hasLeadingZero = showLeadingZeros && value !== null && value < 10; | ||
return [ | ||
(hasLeadingZero && <span key="leadingZero" className={`${className}__leadingZero`}>0</span>), | ||
<input | ||
key="day" | ||
autoComplete="off" | ||
className={mergeClassNames( | ||
`${className}__input`, | ||
`${className}__day`, | ||
hasLeadingZero && `${className}__input--hasLeadingZero`, | ||
)} | ||
disabled={disabled} | ||
name={name} | ||
return ( | ||
<Input | ||
name="day" | ||
max={maxDay} | ||
min={minDay} | ||
onChange={onChange} | ||
onFocus={event => select(event.target)} | ||
onKeyDown={onKeyDown} | ||
onKeyUp={event => updateInputWidth(event.target)} | ||
placeholder="--" | ||
ref={(ref) => { | ||
if (ref) { | ||
updateInputWidth(ref); | ||
} | ||
if (itemRef) { | ||
itemRef(ref, name); | ||
} | ||
}} | ||
required={required} | ||
type="number" | ||
value={value !== null ? value : ''} | ||
/>, | ||
]; | ||
{...otherProps} | ||
/> | ||
); | ||
} | ||
@@ -87,0 +62,0 @@ } |
import React, { PureComponent } from 'react'; | ||
import PropTypes from 'prop-types'; | ||
import mergeClassNames from 'merge-class-names'; | ||
import { | ||
getMonth, | ||
getYear, | ||
} from '../shared/dates'; | ||
import Input from './Input'; | ||
import { getMonth, getYear } from '../shared/dates'; | ||
import { isMaxDate, isMinDate } from '../shared/propTypes'; | ||
import { min, max, updateInputWidth } from '../shared/utils'; | ||
import { min, max } from '../shared/utils'; | ||
const select = element => element && element.select(); | ||
export default class MonthInput extends PureComponent { | ||
@@ -28,41 +24,16 @@ get maxMonth() { | ||
const { | ||
className, disabled, itemRef, value, onChange, onKeyDown, required, showLeadingZeros, | ||
maxDate, | ||
minDate, | ||
year, | ||
...otherProps | ||
} = this.props; | ||
const name = 'month'; | ||
const hasLeadingZero = showLeadingZeros && value !== null && value < 10; | ||
return [ | ||
(hasLeadingZero && <span key="leadingZero" className={`${className}__leadingZero`}>0</span>), | ||
<input | ||
key="month" | ||
autoComplete="off" | ||
className={mergeClassNames( | ||
`${className}__input`, | ||
`${className}__month`, | ||
hasLeadingZero && `${className}__input--hasLeadingZero`, | ||
)} | ||
disabled={disabled} | ||
name={name} | ||
return ( | ||
<Input | ||
name="month" | ||
max={maxMonth} | ||
min={minMonth} | ||
onChange={onChange} | ||
onFocus={event => select(event.target)} | ||
onKeyDown={onKeyDown} | ||
onKeyUp={event => updateInputWidth(event.target)} | ||
placeholder="--" | ||
ref={(ref) => { | ||
if (ref) { | ||
updateInputWidth(ref); | ||
} | ||
if (itemRef) { | ||
itemRef(ref, name); | ||
} | ||
}} | ||
type="number" | ||
required={required} | ||
value={value !== null ? value : ''} | ||
/>, | ||
]; | ||
{...otherProps} | ||
/> | ||
); | ||
} | ||
@@ -69,0 +40,0 @@ } |
import React, { PureComponent } from 'react'; | ||
import PropTypes from 'prop-types'; | ||
import mergeClassNames from 'merge-class-names'; | ||
import { | ||
getYear, | ||
} from '../shared/dates'; | ||
import Input from './Input'; | ||
import { getYear } from '../shared/dates'; | ||
import { isMaxDate, isMinDate, isValueType } from '../shared/propTypes'; | ||
import { max, min, updateInputWidth } from '../shared/utils'; | ||
import { max, min } from '../shared/utils'; | ||
const select = element => element && element.select(); | ||
export default class YearInput extends PureComponent { | ||
@@ -30,2 +27,3 @@ get maxYear() { | ||
} | ||
return 1; | ||
@@ -37,36 +35,16 @@ } | ||
const { | ||
className, disabled, itemRef, value, onChange, onKeyDown, required, | ||
maxDate, | ||
minDate, | ||
valueType, | ||
...otherProps | ||
} = this.props; | ||
const name = 'year'; | ||
return ( | ||
<input | ||
autoComplete="off" | ||
className={mergeClassNames( | ||
`${className}__input`, | ||
`${className}__year`, | ||
)} | ||
disabled={disabled} | ||
name={name} | ||
<Input | ||
name="year" | ||
max={maxYear} | ||
min={minYear} | ||
onChange={onChange} | ||
onFocus={event => select(event.target)} | ||
onKeyDown={onKeyDown} | ||
onKeyUp={event => updateInputWidth(event.target)} | ||
placeholder="----" | ||
ref={(ref) => { | ||
if (ref) { | ||
updateInputWidth(ref); | ||
} | ||
if (itemRef) { | ||
itemRef(ref, name); | ||
} | ||
}} | ||
required={required} | ||
step={yearStep} | ||
type="number" | ||
value={value !== null ? value : ''} | ||
{...otherProps} | ||
/> | ||
@@ -73,0 +51,0 @@ ); |
@@ -112,2 +112,3 @@ import React, { PureComponent } from 'react'; | ||
disabled, | ||
format, | ||
locale, | ||
@@ -132,2 +133,3 @@ maxDate, | ||
disabled={disabled} | ||
format={format} | ||
locale={locale} | ||
@@ -273,4 +275,6 @@ isCalendarOpen={isOpen} | ||
name: PropTypes.string, | ||
onCalendarClose: PropTypes.func, | ||
onCalendarOpen: PropTypes.func, | ||
required: PropTypes.bool, | ||
returnValue: PropTypes.oneOf(['start', 'end', 'range']), | ||
required: PropTypes.bool, | ||
showLeadingZeros: PropTypes.bool, | ||
@@ -277,0 +281,0 @@ }; |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
158355
42
3764
160