@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
JavaScript
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;