UNPKG

wix-style-react

Version:
532 lines (530 loc) • 21.2 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); exports.__esModule = true; exports.default = void 0; var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties")); var _react = _interopRequireDefault(require("react")); var _propTypes = _interopRequireDefault(require("prop-types")); var _isSameDay = _interopRequireDefault(require("date-fns/isSameDay")); var _setYear = _interopRequireDefault(require("date-fns/setYear")); var _setMonth = _interopRequireDefault(require("date-fns/setMonth")); var _setDate = _interopRequireDefault(require("date-fns/setDate")); var _Popover = _interopRequireDefault(require("../Popover")); var _Calendar = _interopRequireDefault(require("../Calendar")); var _DateInput = _interopRequireDefault(require("./DateInput")); var _PopoverCommon = require("../common/PropTypes/PopoverCommon"); var _DatePickerSt = require("./DatePicker.st.css"); var _constants = require("./constants"); var _context = require("../WixStyleReactEnvironmentProvider/context"); var _wixDesignSystemsLocaleUtils = require("wix-design-systems-locale-utils"); var _excluded = ["onFocus"]; var _jsxFileName = "/home/builduser/work/a9c1ac8876d5057c/packages/wix-style-react/dist/cjs/DatePicker/DatePicker.js"; function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } /** * DatePicker component */ class DatePicker extends _react.default.PureComponent { constructor(props) { var _this; super(props); _this = this; this.componentDidUpdate = prevProps => { var { value: prevValue } = prevProps; var { value: newValue } = this.props; if (newValue !== prevValue) { if (newValue) { if (newValue !== this.state.value) { this.setState({ inputValue: newValue }); } this._saveNewValue(newValue); return; } var value = this._transformDate(new Date(), prevValue); return this.setState({ inputValue: null, value }); } }; this._openCalendar = () => { if (!this.state.isOpen && !this.props.readOnly && this.state.shouldOpenCalendar) { return this.setState({ isOpen: true, value: this.props.value || new Date() }, () => { var _this$props$onOpen, _this$props; (_this$props$onOpen = (_this$props = this.props).onOpen) == null || _this$props$onOpen.call(_this$props); }); } if (!this.state.shouldOpenCalendar) { return this.setState({ shouldOpenCalendar: true }); } }; this.openCalendar = this._openCalendar; this._closeCalendar = function () { var shouldOpenCalendar = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true; var shouldFocusInput = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; _this.setState({ isOpen: false, autoFocus: false, shouldOpenCalendar }, () => { _this.props.onClose == null || _this.props.onClose(); if (shouldFocusInput) { var _this$state$inputRef; (_this$state$inputRef = _this.state.inputRef) == null || _this$state$inputRef.focus(); } }); }; this._handleInputChange = _ref => { var { dateVal } = _ref; this._saveNewValue(dateVal); }; this._transformDate = (value, oldValue) => [[value.getFullYear(), _setYear.default], [value.getMonth(), _setMonth.default], [value.getDate(), _setDate.default]].reduce((_value, _ref2) => { var [datePart, setter] = _ref2; return setter(_value, datePart); }, oldValue); this._saveNewValue = function (value) { var modifiers = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; if (modifiers.disabled) { return; } var oldValue = _this.props.value || new Date(new Date().setHours(0, 0, 0, 0)); var newValue = _this._transformDate(value, oldValue); if (!(0, _isSameDay.default)(value, _this.props.value)) { _this.setState({ value: newValue }, () => _this.props.onChange(newValue)); } }; this._filterDate = date => date < _constants.MAX_DATE && this.props.filterDate(date); this._handleKeyDown = (event, newDate) => { if (!this.state.isOpen) { this._openCalendar(); } switch (event.key) { case 'Tab': case 'Escape': { this._closeCalendar(); return; } case 'Enter': { event.preventDefault(); if (newDate) { var transformedDate = this._transformDate(newDate, new Date(new Date().setHours(0, 0, 0, 0))); this.setState({ value: transformedDate, inputValue: transformedDate }, () => this.props.onChange(transformedDate)); } this._closeCalendar(); return; } case 'ArrowUp': case 'ArrowDown': { event.preventDefault(); this.setState({ autoFocus: true }); return; } default: return; } }; this._handleCalendarKeyDown = event => { switch (event.key) { case 'Escape': { event.stopPropagation(); this._closeCalendar(false, true); return; } default: return; } }; this._handleChange = (value, modifiers) => { this.setState({ inputValue: value, isOpen: !this.props.shouldCloseOnSelect || false, shouldOpenCalendar: !this.props.shouldCloseOnSelect || false }); this._saveNewValue(value, modifiers); }; this._handleRef = ref => { this.setState({ inputRef: ref }); }; this._handleInputFocus = event => { if (!event.isTrusted) { return; } this._openCalendar(); this.setState({ autoFocus: false }, () => { var _this$state$inputRef2, _this$props$inputProp; (_this$state$inputRef2 = this.state.inputRef) == null || _this$state$inputRef2.focus(); (_this$props$inputProp = this.props.inputProps) == null || _this$props$inputProp.onFocus == null || _this$props$inputProp.onFocus(event); }); }; this._renderInput = () => { var { inputDataHook, disabled, placeholderText, readOnly, status, statusMessage, customInput, inputProps = {}, size, clearButton, onClear, disableKeyboardType, dateStyle, validate, onValidate, excludePastDates, clearButtonTooltipContent, clearButtonTooltipProps } = this.props; var { onFocus } = inputProps, inputPropsRest = (0, _objectWithoutProperties2.default)(inputProps, _excluded); return /*#__PURE__*/_react.default.createElement(_DateInput.default, (0, _extends2.default)({ dataHook: inputDataHook, className: _DatePickerSt.classes.input, value: this.state.inputValue, onInputClicked: this._openCalendar, disabled: disabled, readOnly: readOnly, placeholder: placeholderText, onFocus: this._handleInputFocus, onKeyDown: this._handleKeyDown, tabIndex: 0, status: status, statusMessage: statusMessage, autoSelect: false, customInput: customInput, locale: this._getLocale(), dateStyle: dateStyle, size: size, clearButton: clearButton, onClear: onClear, onChange: this._handleInputChange, disableEditing: disableKeyboardType, validate: validate, onValidate: onValidate, excludePastDates: excludePastDates, clearButtonTooltipContent: clearButtonTooltipContent, clearButtonTooltipProps: clearButtonTooltipProps, inputRef: this._handleRef, focusOnClearClick: true }, customInput ? customInput.props : {}, inputPropsRest, { __self: this, __source: { fileName: _jsxFileName, lineNumber: 246, columnNumber: 7 } })); }; this.state = { value: props.value || new Date(), isOpen: props.initialOpen && !props.disabled, inputValue: props.value, autoFocus: false, shouldOpenCalendar: true }; } _getLocale() { return this.props.locale || this.context.locale || 'en'; } render() { var { className, showMonthDropdown, showYearDropdown, excludePastDates, rtl, shouldCloseOnSelect, width, calendarDataHook, twoMonths, zIndex, dataHook, popoverProps, firstDayOfWeek, leftArrowAriaLabel, leftArrowAriaLabelledBy, rightArrowAriaLabel, rightArrowAriaLabelledBy, monthDropdownAriaLabel, monthDropdownAriaLabelledBy, yearDropdownAriaLabel, yearDropdownAriaLabelledBy, disableKeyboardType, dateIndication, disabled } = this.props; var { isOpen, value } = this.state; var popoverUpdatedProps = _objectSpread({ placement: rtl ? 'top-end' : 'top-start' }, popoverProps); var calendarProps = { dataHook: _constants.dataHooks.datePickerCalendar, className: _DatePickerSt.classes.calendar, locale: this._getLocale(), showMonthDropdown, showYearDropdown, filterDate: this._filterDate, excludePastDates, rtl, onChange: this._handleChange, onClose: () => this._closeCalendar(false), value, shouldCloseOnSelect, numOfMonths: twoMonths ? 2 : 1, firstDayOfWeek, leftArrowAriaLabel, leftArrowAriaLabelledBy, rightArrowAriaLabel, rightArrowAriaLabelledBy, monthDropdownAriaLabel, monthDropdownAriaLabelledBy, yearDropdownAriaLabel, yearDropdownAriaLabelledBy, dateIndication, autoFocus: this.state.autoFocus || false, containFocus: true, onKeyDown: this._handleCalendarKeyDown }; return /*#__PURE__*/_react.default.createElement("div", { className: (0, _DatePickerSt.st)(_DatePickerSt.classes.root, { disableKeyboardType, disabled }, className), "data-hook": dataHook, style: { width }, __self: this, __source: { fileName: _jsxFileName, lineNumber: 346, columnNumber: 7 } }, /*#__PURE__*/_react.default.createElement(_Popover.default, (0, _extends2.default)({ className: _DatePickerSt.classes.popover, dataHook: _constants.dataHooks.datePickerPopover, onClickOutside: () => this._closeCalendar(false), appendTo: "parent", shown: isOpen, zIndex: zIndex, tabIndex: -1 }, popoverUpdatedProps, { __self: this, __source: { fileName: _jsxFileName, lineNumber: 355, columnNumber: 9 } }), /*#__PURE__*/_react.default.createElement(_Popover.default.Element, { __self: this, __source: { fileName: _jsxFileName, lineNumber: 365, columnNumber: 11 } }, /*#__PURE__*/_react.default.createElement("div", { className: _DatePickerSt.classes.inputContainer, "data-hook": _constants.dataHooks.datePickerInputContainer, __self: this, __source: { fileName: _jsxFileName, lineNumber: 366, columnNumber: 13 } }, this._renderInput())), /*#__PURE__*/_react.default.createElement(_Popover.default.Content, { __self: this, __source: { fileName: _jsxFileName, lineNumber: 373, columnNumber: 11 } }, /*#__PURE__*/_react.default.createElement("div", { "data-hook": calendarDataHook, __self: this, __source: { fileName: _jsxFileName, lineNumber: 374, columnNumber: 13 } }, /*#__PURE__*/_react.default.createElement(_Calendar.default, (0, _extends2.default)({}, calendarProps, { __self: this, __source: { fileName: _jsxFileName, lineNumber: 375, columnNumber: 15 } })))))); } } exports.default = DatePicker; DatePicker.displayName = 'DatePicker'; DatePicker.defaultProps = { filterDate: () => true, rtl: false, width: '150px', zIndex: 1, disabled: false, inputDataHook: _constants.dataHooks.datePickerInput, popoverProps: { zIndex: 1 }, disableKeyboardType: false, onChange: () => {}, dateStyle: 'short', shouldCloseOnSelect: true }; DatePicker.contextType = _context.WixStyleReactEnvironmentContext; DatePicker.propTypes = { /** Specify a single CSS class name to be appended to the root element */ className: _propTypes.default.string, /** Applies as data-hook HTML attribute that can be used in the tests */ dataHook: _propTypes.default.string, /** Focus selected day automatically when component mounts or updates */ autoFocus: _propTypes.default.bool, /** Override a field with a custom input element. If you only need to pass custom props to the `<Input/>`, then use `inputProps` instead. */ customInput: _propTypes.default.node, /** Allows you to pass default Input component properties */ inputProps: _propTypes.default.object, /** ##### Add an indication under a specific date. Function returns the indication node of a specific date or null if this day doesn't have an indication. * - `param` {date: Date, isSelected: boolean } * - `date` - a date * - `isSelected` - whether this date is the selected date * - `return` {React.node} - the indication node of a specific date or null if this day doesn't have an indication. */ dateIndication: _propTypes.default.func, /** Specify date picker instance locale */ locale: _propTypes.default.oneOf(_wixDesignSystemsLocaleUtils.SupportedWixLocales), /** Sets date format of locale */ dateStyle: _propTypes.default.oneOf(['short', 'medium']), /** Specify whether a field should be disabled or not */ disabled: _propTypes.default.bool, /** Specify whether past dates should be selectable or not */ excludePastDates: _propTypes.default.bool, /** * ##### Specify selectable dates: * * `param` {Date} `date` - a date to check * * `return` {boolean} - true if `date` should be selectable, false otherwise */ filterDate: _propTypes.default.func, /** Applies a data-hook HTML attribute for date picker input */ inputDataHook: _propTypes.default.string, /** Applies a data-hook HTML attribute for date picker calendar view */ calendarDataHook: _propTypes.default.string, /** Defines a placeholder of the field */ placeholderText: _propTypes.default.string, /** Specify whether RTL mode is enabled or not. When true, the keyboard navigation will be changed, meaning pressing on the right arrow will navigate to the previous day, and pressing on the left arrow will navigate to the next day. */ rtl: _propTypes.default.bool, /** Defines the selected date */ value: _propTypes.default.object, /** Specify whether the calendar will be initially visible or not */ initialOpen: _propTypes.default.bool, /** Controls the status of a field */ status: _propTypes.default.oneOf(['error', 'warning', 'loading']), /** Defines the status message to be displayed on status icon hover. If not given or empty, the tooltip won’t be shown. */ statusMessage: _propTypes.default.node, /** Sets the width of picker input in pixels or percentage */ width: _propTypes.default.oneOfType([_propTypes.default.number, _propTypes.default.string]), /** Set a desired z-index for date picker popover */ zIndex: _propTypes.default.number, /** Allows you to pass popover properties. The default placement value depends on the rtl prop - would be 'top-start' when rtl=false and 'top-end' in case of rtl=ture. */ popoverProps: _propTypes.default.shape(_PopoverCommon.PopoverCommonProps), /** Specify the starting day of a week, allowing only from 0 to 6 (Sunday to Saturday). The default value is 1 which means Monday. */ firstDayOfWeek: _propTypes.default.oneOf([0, 1, 2, 3, 4, 5, 6]), /** Specifies the size of the input */ size: _propTypes.default.oneOf(['small', 'medium', 'large']), /** Specify whether date picker input is readOnly or not */ readOnly: _propTypes.default.bool, /** Sets today's date. The today indication is added automatically according to the user timezone but in some cases, we need the ability to add the today indication based on the business timezone. */ today: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.instanceOf(Date)]), /** Display a clear button (x) on a non-empty field */ clearButton: _propTypes.default.bool, /** Provides a callback function when day in selected in the calendar */ onChange: _propTypes.default.func.isRequired, /** Displays clear button (X) on a non-empty input and calls callback with no arguments */ onClear: _propTypes.default.func, /** Defines a callback function that is called whenever a user presses escape, clicks outside of the element or a date is selected and `shouldCloseOnSelect` is set. Receives an event as a first argument. */ onClose: _propTypes.default.func, /** Defines a callback function which is called when date picker is opened. */ onOpen: _propTypes.default.func, /** Defines a callback function that is called with the date of the first day of the month whenever the user selects a month in the calendar */ onMonthChange: _propTypes.default.func, /** Disable typing the in the input. When true, choosing a date is possible only by picking from the calendar. Default: false. */ disableKeyboardType: _propTypes.default.bool, /** Displays a selectable yearDropdown */ showYearDropdown: _propTypes.default.bool, /** Displays a selectable monthDropdown */ showMonthDropdown: _propTypes.default.bool, /** Specify whether the calendar closes on day selection */ shouldCloseOnSelect: _propTypes.default.bool, /** Defines a string value that labels the months dropdown in calendar header */ monthDropdownAriaLabel: _propTypes.default.string, /** Identifies the element that labels the months dropdown in calendar header */ monthDropdownAriaLabelledBy: _propTypes.default.string, /** Defines a string value that labels the years dropdown in calendar header */ yearDropdownAriaLabel: _propTypes.default.string, /** Identifies the element that labels the years dropdown in calendar header */ yearDropdownAriaLabelledBy: _propTypes.default.string, /** Defines a string value that labels the left arrow in calendar header */ leftArrowAriaLabel: _propTypes.default.string, /** Identifies the element that labels the left arrow in calendar header */ leftArrowAriaLabelledBy: _propTypes.default.string, /** Defines a string value that labels the right arrow in calendar header */ rightArrowAriaLabel: _propTypes.default.string, /** Identifies the element that labels the right arrow in calendar header */ rightArrowAriaLabelledBy: _propTypes.default.string, /** Enables internal input validation */ validate: _propTypes.default.bool, /** Defines a callback function which is called on cases when date is validated. * - {validationType: 'outOfBoundsError' | 'formatError' | 'valid', format: string, value: string } * - `validationType` - type 'formatError' is set when validated date is in the wrong date format * - type 'outOfBoundsError' is set when 'excludePastDates' is true and date input is before today * - type 'valid' is set when entered date is valid * - `format` - is set to valid date format * - `value` - is set to current input value */ onValidate: _propTypes.default.func, /** When provided, hover will display a tooltip */ clearButtonTooltipContent: _propTypes.default.node, /** Tooltip props */ clearButtonTooltipProps: _propTypes.default.node }; //# sourceMappingURL=DatePicker.js.map