1 | import { __rest } from "tslib";
|
2 | import * as React from 'react';
|
3 | import { css } from '@patternfly/react-styles';
|
4 | import styles from '@patternfly/react-styles/css/components/DatePicker/date-picker';
|
5 | import buttonStyles from '@patternfly/react-styles/css/components/Button/button';
|
6 | import { TextInput } from '../TextInput/TextInput';
|
7 | import { Popover } from '../Popover/Popover';
|
8 | import { InputGroup } from '../InputGroup/InputGroup';
|
9 | import OutlinedCalendarAltIcon from '@patternfly/react-icons/dist/esm/icons/outlined-calendar-alt-icon';
|
10 | import { CalendarMonth, isValidDate } from '../CalendarMonth';
|
11 | import { useImperativeHandle } from 'react';
|
12 | export const yyyyMMddFormat = (date) => `${date.getFullYear()}-${(date.getMonth() + 1).toString().padStart(2, '0')}-${date
|
13 | .getDate()
|
14 | .toString()
|
15 | .padStart(2, '0')}`;
|
16 | const DatePickerBase = (_a, ref) => {
|
17 | var { className, locale = undefined, dateFormat = yyyyMMddFormat, dateParse = (val) => val.split('-').length === 3 && new Date(`${val}T00:00:00`), isDisabled = false, placeholder = 'YYYY-MM-DD', value: valueProp = '', 'aria-label': ariaLabel = 'Date picker', buttonAriaLabel = 'Toggle date picker', onChange = () => undefined, onBlur = () => undefined, invalidFormatText = 'Invalid date', helperText, appendTo, popoverProps, monthFormat, weekdayFormat, longWeekdayFormat, dayFormat, weekStart, validators = [], rangeStart, style: styleProps = {}, inputProps = {} } = _a, props = __rest(_a, ["className", "locale", "dateFormat", "dateParse", "isDisabled", "placeholder", "value", 'aria-label', "buttonAriaLabel", "onChange", "onBlur", "invalidFormatText", "helperText", "appendTo", "popoverProps", "monthFormat", "weekdayFormat", "longWeekdayFormat", "dayFormat", "weekStart", "validators", "rangeStart", "style", "inputProps"]);
|
18 | const [value, setValue] = React.useState(valueProp);
|
19 | const [valueDate, setValueDate] = React.useState(dateParse(value));
|
20 | const [errorText, setErrorText] = React.useState('');
|
21 | const [popoverOpen, setPopoverOpen] = React.useState(false);
|
22 | const [selectOpen, setSelectOpen] = React.useState(false);
|
23 | const [pristine, setPristine] = React.useState(true);
|
24 | const widthChars = React.useMemo(() => Math.max(dateFormat(new Date()).length, placeholder.length), [dateFormat]);
|
25 | const style = Object.assign({ '--pf-c-date-picker__input--c-form-control--width-chars': widthChars }, styleProps);
|
26 | const buttonRef = React.useRef();
|
27 | React.useEffect(() => {
|
28 | setValue(valueProp);
|
29 | setValueDate(dateParse(valueProp));
|
30 | }, [valueProp]);
|
31 | React.useEffect(() => {
|
32 | setPristine(!value);
|
33 | }, [value]);
|
34 | const setError = (date) => setErrorText(validators.map(validator => validator(date)).join('\n') || '');
|
35 | const onTextInput = (value) => {
|
36 | setValue(value);
|
37 | setErrorText('');
|
38 | const newValueDate = dateParse(value);
|
39 | setValueDate(newValueDate);
|
40 | if (isValidDate(newValueDate)) {
|
41 | onChange(value, new Date(newValueDate));
|
42 | }
|
43 | else {
|
44 | onChange(value);
|
45 | }
|
46 | };
|
47 | const onInputBlur = () => {
|
48 | if (pristine) {
|
49 | return;
|
50 | }
|
51 | const newValueDate = dateParse(value);
|
52 | if (isValidDate(newValueDate)) {
|
53 | onBlur(value, new Date(newValueDate));
|
54 | setError(newValueDate);
|
55 | }
|
56 | else {
|
57 | onBlur(value);
|
58 | setErrorText(invalidFormatText);
|
59 | }
|
60 | };
|
61 | const onDateClick = (newValueDate) => {
|
62 | const newValue = dateFormat(newValueDate);
|
63 | setValue(newValue);
|
64 | setValueDate(newValueDate);
|
65 | setError(newValueDate);
|
66 | setPopoverOpen(false);
|
67 | onChange(newValue, new Date(newValueDate));
|
68 | };
|
69 | const onKeyPress = (ev) => {
|
70 | if (ev.key === 'Enter' && value) {
|
71 | if (isValidDate(valueDate)) {
|
72 | setError(valueDate);
|
73 | }
|
74 | else {
|
75 | setErrorText(invalidFormatText);
|
76 | }
|
77 | }
|
78 | };
|
79 | useImperativeHandle(ref, () => ({
|
80 | setCalendarOpen: (isOpen) => setPopoverOpen(isOpen),
|
81 | toggleCalendar: () => setPopoverOpen(prev => !prev)
|
82 | }), [setPopoverOpen]);
|
83 | return (React.createElement("div", Object.assign({ className: css(styles.datePicker, className), style: style }, props),
|
84 | React.createElement(Popover, Object.assign({ position: "bottom", bodyContent: React.createElement(CalendarMonth, { date: valueDate, onChange: onDateClick, locale: locale,
|
85 |
|
86 | validators: validators.map(validator => (date) => !validator(date)), onSelectToggle: open => setSelectOpen(open), monthFormat: monthFormat, weekdayFormat: weekdayFormat, longWeekdayFormat: longWeekdayFormat, dayFormat: dayFormat, weekStart: weekStart, rangeStart: rangeStart }), showClose: false, isVisible: popoverOpen, shouldClose: (_1, _2, event) => {
|
87 | event = event;
|
88 |
|
89 | if (event.keyCode && event.keyCode === 27 && selectOpen) {
|
90 | return false;
|
91 | }
|
92 |
|
93 | if (buttonRef.current && buttonRef.current.contains(event.target)) {
|
94 | return false;
|
95 | }
|
96 | setPopoverOpen(false);
|
97 | return true;
|
98 | }, withFocusTrap: true, hasNoPadding: true, hasAutoWidth: true, appendTo: appendTo }, popoverProps),
|
99 | React.createElement("div", { className: styles.datePickerInput },
|
100 | React.createElement(InputGroup, null,
|
101 | React.createElement(TextInput, Object.assign({ isDisabled: isDisabled, "aria-label": ariaLabel, placeholder: placeholder, validated: errorText ? 'error' : 'default', value: value, onChange: onTextInput, onBlur: onInputBlur, onKeyPress: onKeyPress }, inputProps)),
|
102 | React.createElement("button", { ref: buttonRef, className: css(buttonStyles.button, buttonStyles.modifiers.control), "aria-label": buttonAriaLabel, type: "button", onClick: () => setPopoverOpen(!popoverOpen), disabled: isDisabled },
|
103 | React.createElement(OutlinedCalendarAltIcon, null))))),
|
104 | helperText && React.createElement("div", { className: styles.datePickerHelperText }, helperText),
|
105 | errorText.trim() && React.createElement("div", { className: css(styles.datePickerHelperText, styles.modifiers.error) }, errorText)));
|
106 | };
|
107 | export const DatePicker = React.forwardRef(DatePickerBase);
|
108 | DatePicker.displayName = 'DatePicker';
|
109 |
|
\ | No newline at end of file |