UNPKG

@mui/x-date-pickers

Version:

The community edition of the Date and Time Picker components (MUI X).

357 lines (355 loc) 13.8 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.YearCalendar = void 0; var _objectWithoutPropertiesLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutPropertiesLoose")); var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var React = _interopRequireWildcard(require("react")); var _propTypes = _interopRequireDefault(require("prop-types")); var _clsx = _interopRequireDefault(require("clsx")); var _system = require("@mui/system"); var _styles = require("@mui/material/styles"); var _utils = require("@mui/utils"); var _PickersYear = require("./PickersYear"); var _useUtils = require("../internals/hooks/useUtils"); var _yearCalendarClasses = require("./yearCalendarClasses"); var _dateUtils = require("../internals/utils/date-utils"); var _valueManagers = require("../internals/utils/valueManagers"); var _getDefaultReferenceDate = require("../internals/utils/getDefaultReferenceDate"); var _useValueWithTimezone = require("../internals/hooks/useValueWithTimezone"); var _dimensions = require("../internals/constants/dimensions"); var _jsxRuntime = require("react/jsx-runtime"); const _excluded = ["autoFocus", "className", "value", "defaultValue", "referenceDate", "disabled", "disableFuture", "disablePast", "maxDate", "minDate", "onChange", "readOnly", "shouldDisableYear", "disableHighlightToday", "onYearFocus", "hasFocus", "onFocusedViewChange", "yearsPerRow", "timezone", "gridLabelId"]; function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } const useUtilityClasses = ownerState => { const { classes } = ownerState; const slots = { root: ['root'] }; return (0, _utils.unstable_composeClasses)(slots, _yearCalendarClasses.getYearCalendarUtilityClass, classes); }; function useYearCalendarDefaultizedProps(props, name) { const utils = (0, _useUtils.useUtils)(); const defaultDates = (0, _useUtils.useDefaultDates)(); const themeProps = (0, _styles.useThemeProps)({ props, name }); return (0, _extends2.default)({ disablePast: false, disableFuture: false }, themeProps, { yearsPerRow: themeProps.yearsPerRow ?? 3, minDate: (0, _dateUtils.applyDefaultDate)(utils, themeProps.minDate, defaultDates.minDate), maxDate: (0, _dateUtils.applyDefaultDate)(utils, themeProps.maxDate, defaultDates.maxDate) }); } const YearCalendarRoot = (0, _styles.styled)('div', { name: 'MuiYearCalendar', slot: 'Root', overridesResolver: (props, styles) => styles.root })({ display: 'flex', flexDirection: 'row', flexWrap: 'wrap', overflowY: 'auto', height: '100%', padding: '0 4px', width: _dimensions.DIALOG_WIDTH, maxHeight: _dimensions.MAX_CALENDAR_HEIGHT, // avoid padding increasing width over defined boxSizing: 'border-box', position: 'relative' }); /** * Demos: * * - [DateCalendar](https://mui.com/x/react-date-pickers/date-calendar/) * * API: * * - [YearCalendar API](https://mui.com/x/api/date-pickers/year-calendar/) */ const YearCalendar = exports.YearCalendar = /*#__PURE__*/React.forwardRef(function YearCalendar(inProps, ref) { const props = useYearCalendarDefaultizedProps(inProps, 'MuiYearCalendar'); const { autoFocus, className, value: valueProp, defaultValue, referenceDate: referenceDateProp, disabled, disableFuture, disablePast, maxDate, minDate, onChange, readOnly, shouldDisableYear, onYearFocus, hasFocus, onFocusedViewChange, yearsPerRow, timezone: timezoneProp, gridLabelId } = props, other = (0, _objectWithoutPropertiesLoose2.default)(props, _excluded); const { value, handleValueChange, timezone } = (0, _useValueWithTimezone.useControlledValueWithTimezone)({ name: 'YearCalendar', timezone: timezoneProp, value: valueProp, defaultValue, onChange: onChange, valueManager: _valueManagers.singleItemValueManager }); const now = (0, _useUtils.useNow)(timezone); const theme = (0, _system.useTheme)(); const utils = (0, _useUtils.useUtils)(); const referenceDate = React.useMemo(() => _valueManagers.singleItemValueManager.getInitialReferenceValue({ value, utils, props, timezone, referenceDate: referenceDateProp, granularity: _getDefaultReferenceDate.SECTION_TYPE_GRANULARITY.year }), [] // eslint-disable-line react-hooks/exhaustive-deps ); const ownerState = props; const classes = useUtilityClasses(ownerState); const todayYear = React.useMemo(() => utils.getYear(now), [utils, now]); const selectedYear = React.useMemo(() => { if (value != null) { return utils.getYear(value); } return null; }, [value, utils]); const [focusedYear, setFocusedYear] = React.useState(() => selectedYear || utils.getYear(referenceDate)); const [internalHasFocus, setInternalHasFocus] = (0, _utils.unstable_useControlled)({ name: 'YearCalendar', state: 'hasFocus', controlled: hasFocus, default: autoFocus ?? false }); const changeHasFocus = (0, _utils.unstable_useEventCallback)(newHasFocus => { setInternalHasFocus(newHasFocus); if (onFocusedViewChange) { onFocusedViewChange(newHasFocus); } }); const isYearDisabled = React.useCallback(dateToValidate => { if (disablePast && utils.isBeforeYear(dateToValidate, now)) { return true; } if (disableFuture && utils.isAfterYear(dateToValidate, now)) { return true; } if (minDate && utils.isBeforeYear(dateToValidate, minDate)) { return true; } if (maxDate && utils.isAfterYear(dateToValidate, maxDate)) { return true; } if (!shouldDisableYear) { return false; } const yearToValidate = utils.startOfYear(dateToValidate); return shouldDisableYear(yearToValidate); }, [disableFuture, disablePast, maxDate, minDate, now, shouldDisableYear, utils]); const handleYearSelection = (0, _utils.unstable_useEventCallback)((event, year) => { if (readOnly) { return; } const newDate = utils.setYear(value ?? referenceDate, year); handleValueChange(newDate); }); const focusYear = (0, _utils.unstable_useEventCallback)(year => { if (!isYearDisabled(utils.setYear(value ?? referenceDate, year))) { setFocusedYear(year); changeHasFocus(true); onYearFocus?.(year); } }); React.useEffect(() => { setFocusedYear(prevFocusedYear => selectedYear !== null && prevFocusedYear !== selectedYear ? selectedYear : prevFocusedYear); }, [selectedYear]); const handleKeyDown = (0, _utils.unstable_useEventCallback)((event, year) => { switch (event.key) { case 'ArrowUp': focusYear(year - yearsPerRow); event.preventDefault(); break; case 'ArrowDown': focusYear(year + yearsPerRow); event.preventDefault(); break; case 'ArrowLeft': focusYear(year + (theme.direction === 'ltr' ? -1 : 1)); event.preventDefault(); break; case 'ArrowRight': focusYear(year + (theme.direction === 'ltr' ? 1 : -1)); event.preventDefault(); break; default: break; } }); const handleYearFocus = (0, _utils.unstable_useEventCallback)((event, year) => { focusYear(year); }); const handleYearBlur = (0, _utils.unstable_useEventCallback)((event, year) => { if (focusedYear === year) { changeHasFocus(false); } }); const scrollerRef = React.useRef(null); const handleRef = (0, _utils.unstable_useForkRef)(ref, scrollerRef); React.useEffect(() => { if (autoFocus || scrollerRef.current === null) { return; } const tabbableButton = scrollerRef.current.querySelector('[tabindex="0"]'); if (!tabbableButton) { return; } // Taken from useScroll in x-data-grid, but vertically centered const offsetHeight = tabbableButton.offsetHeight; const offsetTop = tabbableButton.offsetTop; const clientHeight = scrollerRef.current.clientHeight; const scrollTop = scrollerRef.current.scrollTop; const elementBottom = offsetTop + offsetHeight; if (offsetHeight > clientHeight || offsetTop < scrollTop) { // Button already visible return; } scrollerRef.current.scrollTop = elementBottom - clientHeight / 2 - offsetHeight / 2; }, [autoFocus]); return /*#__PURE__*/(0, _jsxRuntime.jsx)(YearCalendarRoot, (0, _extends2.default)({ ref: handleRef, className: (0, _clsx.default)(classes.root, className), ownerState: ownerState, role: "radiogroup", "aria-labelledby": gridLabelId }, other, { children: utils.getYearRange([minDate, maxDate]).map(year => { const yearNumber = utils.getYear(year); const isSelected = yearNumber === selectedYear; const isDisabled = disabled || isYearDisabled(year); return /*#__PURE__*/(0, _jsxRuntime.jsx)(_PickersYear.PickersYear, { selected: isSelected, value: yearNumber, onClick: handleYearSelection, onKeyDown: handleKeyDown, autoFocus: internalHasFocus && yearNumber === focusedYear, disabled: isDisabled, tabIndex: yearNumber === focusedYear ? 0 : -1, onFocus: handleYearFocus, onBlur: handleYearBlur, "aria-current": todayYear === yearNumber ? 'date' : undefined, yearsPerRow: yearsPerRow, children: utils.format(year, 'year') }, utils.format(year, 'year')); }) })); }); process.env.NODE_ENV !== "production" ? YearCalendar.propTypes = { // ----------------------------- Warning -------------------------------- // | These PropTypes are generated from the TypeScript type definitions | // | To update them edit the TypeScript types and run "yarn proptypes" | // ---------------------------------------------------------------------- autoFocus: _propTypes.default.bool, /** * Override or extend the styles applied to the component. */ classes: _propTypes.default.object, className: _propTypes.default.string, /** * The default selected value. * Used when the component is not controlled. */ defaultValue: _propTypes.default.object, /** * If `true` picker is disabled */ disabled: _propTypes.default.bool, /** * If `true`, disable values after the current date for date components, time for time components and both for date time components. * @default false */ disableFuture: _propTypes.default.bool, /** * If `true`, today's date is rendering without highlighting with circle. * @default false */ disableHighlightToday: _propTypes.default.bool, /** * If `true`, disable values before the current date for date components, time for time components and both for date time components. * @default false */ disablePast: _propTypes.default.bool, gridLabelId: _propTypes.default.string, hasFocus: _propTypes.default.bool, /** * Maximal selectable date. */ maxDate: _propTypes.default.object, /** * Minimal selectable date. */ minDate: _propTypes.default.object, /** * Callback fired when the value changes. * @template TDate * @param {TDate} value The new value. */ onChange: _propTypes.default.func, onFocusedViewChange: _propTypes.default.func, onYearFocus: _propTypes.default.func, /** * If `true` picker is readonly */ readOnly: _propTypes.default.bool, /** * The date used to generate the new value when both `value` and `defaultValue` are empty. * @default The closest valid year using the validation props, except callbacks such as `shouldDisableYear`. */ referenceDate: _propTypes.default.object, /** * Disable specific year. * @template TDate * @param {TDate} year The year to test. * @returns {boolean} If `true`, the year will be disabled. */ shouldDisableYear: _propTypes.default.func, /** * The system prop that allows defining system overrides as well as additional CSS styles. */ sx: _propTypes.default.oneOfType([_propTypes.default.arrayOf(_propTypes.default.oneOfType([_propTypes.default.func, _propTypes.default.object, _propTypes.default.bool])), _propTypes.default.func, _propTypes.default.object]), /** * Choose which timezone to use for the value. * Example: "default", "system", "UTC", "America/New_York". * If you pass values from other timezones to some props, they will be converted to this timezone before being used. * @see See the {@link https://mui.com/x/react-date-pickers/timezone/ timezones documentation} for more details. * @default The timezone of the `value` or `defaultValue` prop is defined, 'default' otherwise. */ timezone: _propTypes.default.string, /** * The selected value. * Used when the component is controlled. */ value: _propTypes.default.object, /** * Years rendered per row. * @default 3 */ yearsPerRow: _propTypes.default.oneOf([3, 4]) } : void 0;