UNPKG

@adaptabletools/adaptable-cjs

Version:

Powerful data-agnostic HTML5 AG Grid extension which provides advanced, cutting-edge functionality to meet all DataGrid requirements

154 lines (153 loc) 8.63 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Datepicker = void 0; const tslib_1 = require("tslib"); const React = tslib_1.__importStar(require("react")); const OverlayTrigger_1 = tslib_1.__importDefault(require("../OverlayTrigger")); const react_1 = require("react"); const useProperty_1 = tslib_1.__importDefault(require("../utils/useProperty")); const FieldWrap_1 = tslib_1.__importDefault(require("../FieldWrap")); const SimpleButton_1 = tslib_1.__importDefault(require("../SimpleButton")); const rebass_1 = require("rebass"); const FormatHelper_1 = require("../../Utilities/Helpers/FormatHelper"); const DatepickerContext_1 = require("./DatepickerContext"); const react_day_picker_1 = require("react-day-picker"); const AdaptableDateInlineInput_1 = require("../../View/Components/AdaptableInput/AdaptableDateInlineInput"); const date_fns_1 = require("date-fns"); const Select_1 = require("../Select"); const onDatePickerDropdownKeyDown = (e) => { if (e.key === 'Escape' || e.key === 'Enter') { e.stopPropagation(); } }; const DatePickerComponents = { YearsDropdown: (props) => { const onChange = (0, react_1.useCallback)((value) => { props.onChange?.({ target: { value, }, }); }, [props.onChange]); return (React.createElement(Select_1.Select, { onKeyDown: onDatePickerDropdownKeyDown, value: props.value, onChange: onChange, options: props.options })); }, MonthsDropdown: (props) => { const onChange = (0, react_1.useCallback)((value) => { props.onChange?.({ target: { value, }, }); }, [props.onChange]); return (React.createElement(Select_1.Select, { onKeyDown: onDatePickerDropdownKeyDown, value: `${props.value}`, onChange: onChange, options: props.options.map((option) => { return { label: option.label, value: `${option.value}`, }; }) })); }, }; const DatepickerOverlay = ({ onHide, children, onKeyDown, onMouseDown, overlayDOMRef, }) => { const domRef = React.useRef(null); return (React.createElement("div", { className: "ab-Datepicker-Overlay", tabIndex: -1, ref: (el) => { domRef.current = el; overlayDOMRef.current = el; }, onKeyDown: onKeyDown, onMouseDown: onMouseDown, onBlur: (e) => { const { relatedTarget } = e; const node = domRef.current; // relatedTarget is the newly focused element as a result of this blur event // so we close the overlay when the newly focused element is outside the overlay if (relatedTarget == null || !node.contains?.(relatedTarget)) { onHide(); } } }, children)); }; const END_MONTH = (0, date_fns_1.endOfYear)((0, date_fns_1.addYears)(new Date(), 10)); const START_MONTH = (0, date_fns_1.startOfYear)((0, date_fns_1.addYears)(new Date(), -50)); exports.Datepicker = React.forwardRef((props, ref) => { const { dateProps, required, disabled, style, placeholder, showWeekNumber, showOutsideDays, value: _, defaultValue: __, onChange: ___, datepickerButtons, showClearButton, autoFocus, ...boxProps } = props; const datepickerContext = (0, DatepickerContext_1.useDatepickerContext)(); let [value, setValue] = (0, useProperty_1.default)(props, 'value', undefined, { onChange: props.onChange, }); (0, react_1.useEffect)(() => { // when value is reset, also reset the month to the current month if (!value) { setMonth(new Date()); } }, [!!value]); const [month, setMonth] = (0, react_1.useState)(value ?? new Date()); const updateValue = (value) => { setValue(value); setMonth(value ?? new Date()); }; const inputValue = (0, FormatHelper_1.DateFormatter)(value, { Pattern: dateProps.format }) ?? ''; const [visible, doSetVisible] = (0, react_1.useState)(false); const setVisible = (visible, keyboardEventKey) => { doSetVisible(visible); if (!visible) { datepickerContext?.onHide?.(keyboardEventKey); } else { datepickerContext?.onShow?.(); } }; const clearValue = () => { updateValue(undefined); }; const renderButton = (label, onClick) => (React.createElement(SimpleButton_1.default, { onClick: onClick, margin: '2px' }, label)); const todayDate = new Date(); const footerButtonsMap = { clear: renderButton('Clear', () => clearValue()), close: renderButton('Close', () => setVisible(false)), today: renderButton('Today', () => updateValue(todayDate)), tomorrow: renderButton('Tomorrow', () => updateValue((0, date_fns_1.addDays)(todayDate, 1))), yesterday: renderButton('Yesterday', () => updateValue((0, date_fns_1.addDays)(todayDate, -1))), nextWorkday: renderButton('Next Workday', () => updateValue((0, date_fns_1.addBusinessDays)(todayDate, 1))), prevWorkday: renderButton('Prev Workday', () => updateValue((0, date_fns_1.addBusinessDays)(todayDate, -1))), '-': React.createElement("div", { style: { flex: '1 1 1%' } }), '|': React.createElement("hr", { style: { width: '100%', height: 0, margin: 0, border: 'none' } }), }; const footerButtons = datepickerButtons.map((buttonKey, index) => React.cloneElement(footerButtonsMap[buttonKey], { key: index })); const clearButton = showClearButton !== false ? (React.createElement(SimpleButton_1.default, { "data-name": "clear", variant: "text", tooltip: "Clear", iconSize: 20, padding: 0, icon: "close", onMouseDown: (e) => { e.preventDefault(); clearValue(); }, accessLevel: 'Full' })) : null; const calendarButton = (React.createElement(SimpleButton_1.default, { disabled: disabled, variant: "text", icon: "calendar", tooltip: "Date", iconSize: 20, px: 0, py: 0, onClick: () => setVisible(true) })); const overlayDOMRef = (0, react_1.useRef)(null); return (React.createElement(rebass_1.Flex, null, React.createElement(OverlayTrigger_1.default, { visible: visible, render: () => (React.createElement(DatepickerOverlay, { overlayDOMRef: overlayDOMRef, onMouseDown: props.onMouseDown, onHide: () => setVisible(false), onKeyDown: (e) => { if (e.key === 'Escape' || e.key === 'Enter') { setVisible(false, e.key); } } }, React.createElement(react_day_picker_1.DayPicker, { fixedWeeks: true, autoFocus: autoFocus ?? true, showWeekNumber: showWeekNumber, showOutsideDays: showOutsideDays, mode: "single", captionLayout: "dropdown", month: isNaN(+month) ? new Date() : month, selected: value, onMonthChange: setMonth, onSelect: updateValue, startMonth: START_MONTH, endMonth: END_MONTH, components: DatePickerComponents, footer: React.createElement(rebass_1.Flex, { justifyContent: "space-between", mt: 2, flexWrap: 'wrap' }, footerButtons) }))) }, React.createElement(FieldWrap_1.default, { ...boxProps, style: { borderRadius: style?.borderRadius, width: style?.width, maxWidth: style?.maxWidth, border: style?.border, }, className: "ab-Datepicker", onFocus: () => { if (!visible) { setVisible(true); } }, onBlur: (e) => { const { relatedTarget } = e; const overlayDOMNode = overlayDOMRef.current; if ((overlayDOMNode && relatedTarget == overlayDOMNode) || overlayDOMNode?.contains(relatedTarget)) { return; } setVisible(false); } }, React.createElement(AdaptableDateInlineInput_1.AdaptableDateInlineInput, { ref: ref, value: inputValue, // We do not want to show the format when the date-picker is visible placeholder: placeholder ?? '', onChange: (value) => { const date = new Date(value); if ((0, date_fns_1.isValid)(date)) { updateValue(date); } }, style: style, disabled: disabled }), !!inputValue ? clearButton : null, calendarButton)))); });