UNPKG

@awsui/components-react

Version:

AWS UI is a collection of [React](https://reactjs.org/) components that help create intuitive, responsive, and accessible user experiences for web applications. It is developed by Amazon Web Services (AWS). This work is available under the terms of the [A

124 lines (123 loc) • 7.65 kB
import { __assign, __rest } from "tslib"; import React, { useCallback, useRef, useState, useEffect } from 'react'; import styles from './styles.css.js'; import Dropdown from '../internal/components/dropdown'; import Calendar from './calendar'; import { normalizeLocale } from './calendar/utils/locales'; import { getWeekStartByLocale } from 'weekstart'; import { displayToIso, formatDate, isoToDisplay, memoizedDate } from './calendar/utils/date'; import useForwardFocus from '../internal/hooks/forward-focus'; import { fireNonCancelableEvent } from '../internal/events'; import { KeyCode } from '../internal/keycode'; import clsx from 'clsx'; import DateInput from '../internal/components/date-input'; import { getBaseProps } from '../internal/base-component'; import { useFormFieldContext } from '../internal/context/form-field-context'; import checkControlled from '../internal/hooks/check-controlled'; import { useTelemetry } from '../internal/hooks/use-telemetry'; var DatePicker = React.forwardRef(function (_a, ref) { var _b = _a.locale, locale = _b === void 0 ? '' : _b, startOfWeek = _a.startOfWeek, isDateEnabled = _a.isDateEnabled, nextMonthAriaLabel = _a.nextMonthAriaLabel, previousMonthAriaLabel = _a.previousMonthAriaLabel, todayAriaLabel = _a.todayAriaLabel, _c = _a.placeholder, placeholder = _c === void 0 ? '' : _c, _d = _a.value, value = _d === void 0 ? '' : _d, _e = _a.readOnly, readOnly = _e === void 0 ? false : _e, _f = _a.disabled, disabled = _f === void 0 ? false : _f, onBlur = _a.onBlur, _g = _a.autoFocus, autoFocus = _g === void 0 ? false : _g, onChange = _a.onChange, onFocus = _a.onFocus, rest = __rest(_a, ["locale", "startOfWeek", "isDateEnabled", "nextMonthAriaLabel", "previousMonthAriaLabel", "todayAriaLabel", "placeholder", "value", "readOnly", "disabled", "onBlur", "autoFocus", "onChange", "onFocus"]); useTelemetry('DatePicker'); var baseProps = getBaseProps(rest); var formFieldContext = useFormFieldContext(rest); var _h = useState(false), isDropDownOpen = _h[0], setIsDropDownOpen = _h[1]; var _j = useState(false), calendarHasFocus = _j[0], setCalendarHasFocus = _j[1]; var _k = useState(value), inputValue = _k[0], setInputValue = _k[1]; var normalizedLocale = normalizeLocale(locale !== null && locale !== void 0 ? locale : ''); var normalizedStartOfWeek = (typeof startOfWeek === 'number' ? startOfWeek : getWeekStartByLocale(normalizedLocale)); var defaultSelectedDate = inputValue.length >= 10 ? inputValue : null; var _l = useState(defaultSelectedDate), selectedDate = _l[0], setSelectedDate = _l[1]; var defaultDisplayedDate = inputValue.length >= 10 ? inputValue : formatDate(new Date()); var _m = useState(defaultDisplayedDate), displayedDate = _m[0], setDisplayedDate = _m[1]; var _o = useState(null), focusedDate = _o[0], setFocusedDate = _o[1]; var internalInputRef = useRef(null); useForwardFocus(ref, internalInputRef); var onInputKeyDownHandler = useCallback(function (event) { if (event.detail.keyCode === KeyCode.enter) { setIsDropDownOpen(false); } if (event.detail.keyCode === KeyCode.down) { setIsDropDownOpen(true); setCalendarHasFocus(true); } if (event.detail.keyCode === KeyCode.backspace) { setIsDropDownOpen(true); } }, []); var onChangeMonthHandler = useCallback(function (newMonth) { setDisplayedDate(formatDate(newMonth)); setFocusedDate(null); }, []); var onSelectDateHandler = useCallback(function (_a) { var _b; var date = _a.date; var formattedDate = formatDate(date); (_b = internalInputRef.current) === null || _b === void 0 ? void 0 : _b.focus(); setIsDropDownOpen(false); setSelectedDate(formattedDate); setDisplayedDate(formattedDate); setCalendarHasFocus(false); setFocusedDate(null); fireNonCancelableEvent(onChange, { value: formattedDate }); }, [internalInputRef.current]); var onDateFocusHandler = useCallback(function (_a) { var date = _a.date; if (date) { var value_1 = formatDate(date); setFocusedDate(value_1); } }, []); var onDropdownCloseHandler = useCallback(function () { setDisplayedDate(defaultDisplayedDate); setCalendarHasFocus(false); setIsDropDownOpen(false); return fireNonCancelableEvent(onBlur); }, [defaultDisplayedDate]); var onComponentClickHandler = useCallback(function () { if (!isDropDownOpen) { setIsDropDownOpen(true); } }, [isDropDownOpen]); var onWrapperKeyDownHandler = useCallback(function (event) { var _a; if (event.keyCode === KeyCode.escape) { (_a = internalInputRef.current) === null || _a === void 0 ? void 0 : _a.focus(); setIsDropDownOpen(false); } }, []); var onInputChangeHandler = useCallback(function (event) { var isoDateString = displayToIso(event.detail.value); fireNonCancelableEvent(onChange, { value: isoDateString }); }, []); var onInputBlurHandler = useCallback(function () { if (!calendarHasFocus) { setIsDropDownOpen(false); fireNonCancelableEvent(onBlur); } }, [calendarHasFocus]); var onInputFocusHandler = useCallback(function () { setIsDropDownOpen(!isDropDownOpen); fireNonCancelableEvent(onFocus); }, [isDropDownOpen]); useEffect(function () { setInputValue(value); if (value.length >= 4) { setDisplayedDate(value); } if (value.length >= 10) { setSelectedDate(value); } }, [value]); var inputProps = __assign(__assign({}, formFieldContext), rest); var DateInputElement = (React.createElement(DateInput, __assign({}, inputProps, { value: isoToDisplay(inputValue), rightIcon: 'calendar', rightIconVariant: 'subtle', autoComplete: false, disableBrowserAutocorrect: true, disableAutocompleteOnBlur: calendarHasFocus, disabled: disabled, readOnly: readOnly, className: styles['date-picker-input'], onFocus: onInputFocusHandler, onChange: onInputChangeHandler, onBlur: onInputBlurHandler, placeholder: placeholder, ref: internalInputRef, onKeyDown: onInputKeyDownHandler, autoFocus: autoFocus }))); baseProps.className = clsx(baseProps.className, styles.root, styles['date-picker-container']); if (readOnly || disabled) { return React.createElement("div", __assign({}, baseProps), DateInputElement); } checkControlled('DatePicker', 'value', value, 'onChange', onChange); return (React.createElement("div", __assign({}, baseProps, { onClick: onComponentClickHandler, onKeyDown: onWrapperKeyDownHandler }), React.createElement(Dropdown, { stretchWidth: true, stretchHeight: true, open: isDropDownOpen, onDropdownClose: onDropdownCloseHandler, trigger: DateInputElement }, isDropDownOpen && (React.createElement(Calendar, { selectedDate: memoizedDate('value', selectedDate), focusedDate: memoizedDate('focused', focusedDate), displayedDate: memoizedDate('displayed', displayedDate), locale: normalizedLocale, startOfWeek: normalizedStartOfWeek, isDateEnabled: isDateEnabled ? isDateEnabled : function () { return true; }, calendarHasFocus: calendarHasFocus, nextMonthLabel: nextMonthAriaLabel, previousMonthLabel: previousMonthAriaLabel, todayAriaLabel: todayAriaLabel, onChangeMonth: onChangeMonthHandler, onSelectDate: onSelectDateHandler, onFocusDate: onDateFocusHandler }))))); }); export default DatePicker;