UNPKG

6.63 kBJavaScriptView Raw
1import { __rest } from "tslib";
2import * as React from 'react';
3import { css } from '@patternfly/react-styles';
4import styles from '@patternfly/react-styles/css/components/DatePicker/date-picker';
5import buttonStyles from '@patternfly/react-styles/css/components/Button/button';
6import { TextInput } from '../TextInput/TextInput';
7import { Popover } from '../Popover/Popover';
8import { InputGroup } from '../InputGroup/InputGroup';
9import OutlinedCalendarAltIcon from '@patternfly/react-icons/dist/esm/icons/outlined-calendar-alt-icon';
10import { CalendarMonth, isValidDate } from '../CalendarMonth';
11import { useImperativeHandle } from 'react';
12export const yyyyMMddFormat = (date) => `${date.getFullYear()}-${(date.getMonth() + 1).toString().padStart(2, '0')}-${date
13 .getDate()
14 .toString()
15 .padStart(2, '0')}`;
16const 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 // Use truthy values of strings
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 // Let the select menu close
89 if (event.keyCode && event.keyCode === 27 && selectOpen) {
90 return false;
91 }
92 // Let our button handle toggling
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};
107export const DatePicker = React.forwardRef(DatePickerBase);
108DatePicker.displayName = 'DatePicker';
109//# sourceMappingURL=DatePicker.js.map
\No newline at end of file