UNPKG

@dnb/eufemia

Version:

DNB Eufemia Design System UI Library

414 lines (413 loc) 16.9 kB
"use strict"; "use client"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _react = _interopRequireWildcard(require("react")); var _classnames = _interopRequireDefault(require("classnames")); var _componentHelper = require("../../shared/component-helper.js"); var _AlignmentHelper2 = _interopRequireDefault(require("../../shared/AlignmentHelper.js")); var _SpacingHelper = require("../space/SpacingHelper.js"); var _SkeletonHelper = require("../skeleton/SkeletonHelper.js"); var _Context = _interopRequireDefault(require("../../shared/Context.js")); var _Suffix = _interopRequireDefault(require("../../shared/helpers/Suffix.js")); var _FormLabel = _interopRequireDefault(require("../form-label/FormLabel.js")); var _FormStatus = _interopRequireDefault(require("../form-status/FormStatus.js")); var _DatePickerProvider = _interopRequireDefault(require("./DatePickerProvider.js")); var _DatePickerRange = _interopRequireDefault(require("./DatePickerRange.js")); var _DatePickerInput = _interopRequireDefault(require("./DatePickerInput.js")); var _DatePickerAddon = _interopRequireDefault(require("./DatePickerAddon.js")); var _DatePickerFooter = _interopRequireDefault(require("./DatePickerFooter.js")); var _filterValidProps = require("../../shared/helpers/filterValidProps.js"); var _index = require("../../shared/index.js"); var _withSnakeCaseProps = require("../../shared/helpers/withSnakeCaseProps.js"); var _Popover = _interopRequireDefault(require("../popover/Popover.js")); var _DateFormatUtils = require("../date-format/DateFormatUtils.js"); var _useId = _interopRequireDefault(require("../../shared/helpers/useId.js")); var _AlignmentHelper; function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); } function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); } const defaultProps = { hideNavigation: false, hideDays: false, onlyMonth: false, hideLastWeek: false, disableAutofocus: false, enableKeyboardNav: false, showInput: false, inline: false, resetDate: true, range: false, link: false, sync: true, statusState: 'error', opened: false, noAnimation: false, direction: 'auto', skipPortal: false, yearNavigation: false }; function DatePicker(externalProps) { const props = { ...defaultProps, ...externalProps }; const { preventClose, onHide, onShow, onSubmit, onCancel, onReset, noAnimation, showInput, inline, alignPicker, showSubmitButton, showCancelButton, range, hideDays, hideNavigation, correctInvalidDate, opened: openedProp, endDate: endDateProp } = (0, _withSnakeCaseProps.convertSnakeCaseProps)(props); const [opened, setOpened] = (0, _react.useState)(inline ? true : openedProp); const [hidden, setHidden] = (0, _react.useState)(inline ? false : !opened); const [dates, setDates] = (0, _react.useState)({}); const context = (0, _react.useContext)(_Context.default); const blurDelay = 201; const id = (0, _useId.default)(props.id); const innerRef = (0, _react.useRef)(); const submitButtonRef = (0, _react.useRef)(); const getReturnObject = (0, _react.useRef)(); const hideTimeout = (0, _react.useRef)(); const calendarContainerRef = (0, _react.useRef)(null); const translation = (0, _index.useTranslation)().DatePicker; const focusCalendarTable = (0, _react.useCallback)(() => { var _calendarContainerRef; return (_calendarContainerRef = calendarContainerRef.current) === null || _calendarContainerRef === void 0 ? void 0 : _calendarContainerRef.querySelector('table'); }, []); if (correctInvalidDate) { (0, _componentHelper.warn)(`Use 'Field.Date' instead, for built in validation (https://eufemia.dnb.no/uilib/extensions/forms/feature-fields/Date/#date-limit-validation).`); } if (endDateProp && !range) { (0, _componentHelper.warn)(`The DatePicker got a "endDate". You have to set range={true} as well!.`); } const hidePicker = (0, _react.useCallback)(args => { if (preventClose) { return; } if (args && args.event && args.event.persist) { args.event.persist(); } setOpened(false); hideTimeout.current = setTimeout(() => { setHidden(true); onHide === null || onHide === void 0 || onHide({ ...getReturnObject.current(args) }); if (args !== null && args !== void 0 && args['focusOnHide']) { try { submitButtonRef.current.focus({ preventScroll: true }); } catch (e) { (0, _componentHelper.warn)(e); } } }, noAnimation ? 1 : blurDelay); }, [noAnimation, preventClose, onHide]); const showPicker = (0, _react.useCallback)(event => { if (hideTimeout.current) { clearTimeout(hideTimeout.current); } setOpened(true); setHidden(false); onShow === null || onShow === void 0 || onShow({ ...getReturnObject.current(event) }); }, [onShow]); (0, _react.useEffect)(() => { if (openedProp && !inline) { showPicker(); } }, [openedProp, showPicker, inline]); const onPickerChange = (0, _react.useCallback)(({ hidePicker: shouldHidePicker = true, ...args }) => { if (shouldHidePicker && !showSubmitButton && !showCancelButton) { hidePicker({ focusOnHide: true }); } setDates({ startDate: args.startDate, endDate: args.endDate }); }, [hidePicker, showSubmitButton, showCancelButton]); const onSubmitHandler = (0, _react.useCallback)(event => { if (opened) { hidePicker(event); onSubmit === null || onSubmit === void 0 || onSubmit({ ...getReturnObject.current({ event }) }); } else { showPicker(event); } }, [opened, hidePicker, showPicker, onSubmit]); const onCancelHandler = (0, _react.useCallback)(event => { hidePicker(); onCancel === null || onCancel === void 0 || onCancel({ ...getReturnObject.current(event) }); }, [hidePicker, onCancel]); const onResetHandler = (0, _react.useCallback)(event => { hidePicker(); onReset === null || onReset === void 0 || onReset({ ...getReturnObject.current(event) }); }, [hidePicker, onReset]); const togglePicker = (0, _react.useCallback)(args => { !opened ? showPicker(args) : hidePicker(args); }, [opened, showPicker, hidePicker]); const extendedProps = (0, _componentHelper.extendPropsWithContext)(props, defaultProps, { skeleton: context === null || context === void 0 ? void 0 : context.skeleton }, (0, _withSnakeCaseProps.convertSnakeCaseProps)(context.getTranslation(props).DatePicker), (0, _filterValidProps.pickFormElementProps)(context === null || context === void 0 ? void 0 : context.FormRow), (0, _withSnakeCaseProps.convertSnakeCaseProps)((0, _filterValidProps.pickFormElementProps)(context === null || context === void 0 ? void 0 : context.formElement)), context.DatePicker); const { label, title, labelDirection, labelSrOnly, onlyMonth, hideLastWeek, disableAutofocus, firstDay, resetDate, link, sync, inputElement, addonElement, shortcuts, disabled, stretch, skeleton, size, status, statusState, statusProps, statusNoAnimation, globalStatus, suffix, maskOrder, maskPlaceholder, submitButtonText, cancelButtonText, resetButtonText, showResetButton, className, tooltip, skipPortal, labelAlignment, ...restProps } = extendedProps; const attributes = (0, _react.useMemo)(() => filterOutNonAttributes(restProps), [restProps]); const showStatus = (0, _componentHelper.getStatusState)(status); const pickerParams = {}; if (showStatus || suffix) { pickerParams['aria-describedby'] = (0, _componentHelper.combineDescribedBy)(pickerParams, showStatus ? id + '-status' : null, suffix ? id + '-suffix' : null); } const submitParams = { ['aria-expanded']: opened, ref: submitButtonRef, tabIndex: extendedProps.tabIndex, tooltip }; const selectedDateTitle = (0, _react.useMemo)(() => { const { selectedDate, selectedDateRange } = translation; const { startDate, endDate } = dates; if (!startDate) { return ''; } const options = { locale: context.locale, options: { dateStyle: 'full' } }; return range && endDate ? selectedDateRange.replace(/%s/, (0, _DateFormatUtils.formatDateRange)({ startDate, endDate }, options)) : selectedDate.replace(/%s/, (0, _DateFormatUtils.formatDate)(startDate, options)); }, [range, translation, dates, context.locale]); const mainParams = { className: (0, _classnames.default)("dnb-date-picker dnb-form-component", (0, _SpacingHelper.createSpacingClasses)(props), className, status && `dnb-date-picker__status--${statusState}`, labelDirection && `dnb-date-picker--${labelDirection}`, opened && 'dnb-date-picker--opened', hidden && 'dnb-date-picker--hidden', showInput && 'dnb-date-picker--show-input', inline && 'dnb-date-picker--inline', label && labelAlignment === 'right' && 'dnb-date-picker__input--label-alignment-right', stretch && `dnb-date-picker--stretch`, size && `dnb-date-picker--${size}`), lang: context.locale }; const containerClassNames = (0, _classnames.default)('dnb-date-picker__container', ((inline ? false : range) || showSubmitButton || showCancelButton || showResetButton) && 'dnb-date-picker__container--show-footer', opened ? 'dnb-date-picker__container--opened' : 'dnb-date-picker__container--closed', hidden && 'dnb-date-picker__container--hidden', showInput && 'dnb-date-picker__container--show-input', size && `dnb-date-picker--${size}`); const remainingDOMProps = (0, _componentHelper.validateDOMAttributes)(props, attributes); const remainingSubmitProps = (0, _componentHelper.validateDOMAttributes)(null, submitParams); const remainingPickerProps = (0, _componentHelper.validateDOMAttributes)(null, (0, _SkeletonHelper.skeletonDOMAttributes)(pickerParams, skeleton, context)); return _react.default.createElement(_DatePickerProvider.default, _extends({}, props, { attributes: remainingDOMProps, setReturnObject: fn => getReturnObject.current = fn, hidePicker: hidePicker }), _react.default.createElement("span", mainParams, label && _react.default.createElement(_FormLabel.default, { id: id + '-label', forId: id, text: label, labelDirection: labelDirection, srOnly: labelSrOnly, disabled: disabled, skeleton: skeleton }), _react.default.createElement("span", _extends({ className: "dnb-date-picker__inner", ref: innerRef }, remainingPickerProps), _AlignmentHelper || (_AlignmentHelper = _react.default.createElement(_AlignmentHelper2.default, null)), _react.default.createElement(_FormStatus.default, _extends({ show: showStatus, id: id + '-form-status', globalStatus: globalStatus, label: String(label), text_id: id + '-status', width_selector: id + '-shell', text: status, state: statusState, no_animation: statusNoAnimation, skeleton: skeleton }, statusProps)), _react.default.createElement("span", { className: "dnb-date-picker__row" }, inline ? _react.default.createElement("span", { className: containerClassNames, ref: calendarContainerRef }, _react.default.createElement(_DatePickerRange.default, { id: id, firstDayOfWeek: firstDay, resetDate: resetDate, isRange: range, isLink: link, isSync: sync, hideDays: hideDays, hideNavigation: hideNavigation, onlyMonth: onlyMonth, hideNextMonthWeek: hideLastWeek, onPickerChange: onPickerChange, locale: context.locale }), (addonElement || shortcuts) && _react.default.createElement(_DatePickerAddon.default, { renderElement: addonElement, shortcuts: shortcuts }), _react.default.createElement(_DatePickerFooter.default, { isRange: inline ? false : range, onSubmit: onSubmitHandler, onCancel: onCancelHandler, onReset: onResetHandler, submitButtonText: submitButtonText, cancelButtonText: cancelButtonText, resetButtonText: resetButtonText })) : _react.default.createElement("span", { className: "dnb-date-picker__shell", id: `${id}-shell` }, _react.default.createElement(_DatePickerInput.default, _extends({ id: id, title: title, disabled: disabled, stretch: stretch, skeleton: skeleton, maskOrder: maskOrder, maskPlaceholder: maskPlaceholder, isRange: range, showInput: showInput, selectedDateTitle: selectedDateTitle, inputElement: inputElement, opened: opened, hidden: hidden, size: size, status: status ? 'error' : null, statusState: statusState, lang: context.locale }, attributes, { submitAttributes: remainingSubmitProps, onSubmit: togglePicker }, statusProps)), _react.default.createElement(_Popover.default, { open: opened, targetElement: { verticalRef: submitButtonRef, horizontalRef: innerRef }, noAnimation: noAnimation, skipPortal: skipPortal, keepInDOM: !hidden, focusOnOpen: !disableAutofocus, focusOnOpenElement: focusCalendarTable, alignOnTarget: alignPicker === 'right' || stretch ? 'right' : 'left', horizontalOffset: showInput ? 8 : -8, placement: props.direction === 'auto' ? 'bottom' : props.direction, onOpenChange: isOpen => !isOpen && hidePicker(), hideCloseButton: true, hideOutline: true, preventClose: preventClose, triggerOffset: 0, arrowEdgeOffset: 4, noInnerSpace: true, noMaxWidth: true, portalRootClass: "dnb-date-picker__portal", arrowPosition: alignPicker === 'right' ? 'right' : 'left', arrowPositionSelector: `#${id}` }, _react.default.createElement("span", { className: containerClassNames, ref: calendarContainerRef }, _react.default.createElement(_DatePickerRange.default, { id: id, firstDayOfWeek: firstDay, resetDate: resetDate, isRange: range, isLink: link, isSync: sync, hideDays: hideDays, hideNavigation: hideNavigation, onlyMonth: onlyMonth, hideNextMonthWeek: hideLastWeek, onPickerChange: onPickerChange, locale: context.locale }), (addonElement || shortcuts) && _react.default.createElement(_DatePickerAddon.default, { renderElement: addonElement, shortcuts: shortcuts }), _react.default.createElement(_DatePickerFooter.default, { isRange: inline ? false : range, onSubmit: onSubmitHandler, onCancel: onCancelHandler, onReset: onResetHandler, submitButtonText: submitButtonText, cancelButtonText: cancelButtonText, resetButtonText: resetButtonText })))), suffix && _react.default.createElement(_Suffix.default, { className: "dnb-date-picker__suffix", id: id + '-suffix', context: props }, suffix))), _react.default.createElement("p", { className: "dnb-sr-only", "aria-live": "assertive" }, selectedDateTitle))); } const NonAttributes = ['locale', 'id', 'month', 'date', 'startDate', 'endDate', 'minDate', 'maxDate', 'enableKeyboardNav', 'hideNavigation', 'returnFormat', 'dateFormat', 'hideDays', 'correctInvalidDate', 'opened', 'direction', 'range', 'showInput', 'inline', 'noAnimation', 'onDaysRender', 'onShow', 'onType', 'onHide', 'showSubmitButton', 'showCancelButton', 'selectedDate', 'selectedMonth', 'selectedYear', 'nextMonth', 'nextYear', 'openPickerText', 'placeholderCharacters', 'prevMonth', 'prevYear', 'endMonth', 'startMonth', 'alignPicker', 'preventClose', 'selectedDateRange', 'yearNavigation']; function filterOutNonAttributes(props) { return Object.keys(props).reduce((attributes, key) => { if (!NonAttributes.includes(key)) { attributes[key] = props[key]; } return attributes; }, {}); } var _default = exports.default = DatePicker; DatePicker._supportsSpacingProps = true; //# sourceMappingURL=DatePicker.js.map