UNPKG

@material-ui/lab

Version:

Material-UI Lab - Incubator for Material-UI React components.

183 lines (165 loc) 5.18 kB
import * as React from 'react'; import PropTypes from 'prop-types'; import { createStyles, withStyles, useTheme } from '@material-ui/core/styles'; import clsx from 'clsx'; import PickersYear from './PickersYear'; import { useUtils, useNow } from '../internal/pickers/hooks/useUtils'; import { findClosestEnabledDate } from '../internal/pickers/date-utils'; import { WrapperVariantContext } from '../internal/pickers/wrappers/WrapperVariantContext'; import { useGlobalKeyDown, keycode as keys } from '../internal/pickers/hooks/useKeyDown'; export const styles = createStyles({ root: { display: 'flex', flexDirection: 'row', flexWrap: 'wrap', overflowY: 'auto', height: '100%', margin: '0 4px' } }); /** * @ignore - do not document. */ const YearPicker = /*#__PURE__*/React.forwardRef(function YearPicker(props, ref) { const { allowKeyboardControl, classes, className, date, disableFuture, disablePast, isDateDisabled, maxDate, minDate, onChange, onFocusedDayChange, onYearChange, shouldDisableYear } = props; const now = useNow(); const theme = useTheme(); const utils = useUtils(); const selectedDate = date || now; const currentYear = utils.getYear(selectedDate); const wrapperVariant = React.useContext(WrapperVariantContext); const selectedYearRef = React.useRef(null); const [focusedYear, setFocusedYear] = React.useState(currentYear); const handleYearSelection = React.useCallback((year, isFinish = 'finish') => { const submitDate = newDate => { onChange(newDate, isFinish); if (onFocusedDayChange) { onFocusedDayChange(newDate || now); } if (onYearChange) { onYearChange(newDate); } }; const newDate = utils.setYear(selectedDate, year); if (isDateDisabled(newDate)) { const closestEnabledDate = findClosestEnabledDate({ utils, date: newDate, minDate, maxDate, disablePast: Boolean(disablePast), disableFuture: Boolean(disableFuture), shouldDisableDate: isDateDisabled }); submitDate(closestEnabledDate || now); } else { submitDate(newDate); } }, [utils, now, selectedDate, isDateDisabled, onChange, onFocusedDayChange, onYearChange, minDate, maxDate, disablePast, disableFuture]); const focusYear = React.useCallback(year => { if (!isDateDisabled(utils.setYear(selectedDate, year))) { setFocusedYear(year); } }, [selectedDate, isDateDisabled, utils]); const yearsInRow = wrapperVariant === 'desktop' ? 4 : 3; const nowFocusedYear = focusedYear || currentYear; useGlobalKeyDown(Boolean(allowKeyboardControl), { [keys.ArrowUp]: () => focusYear(nowFocusedYear - yearsInRow), [keys.ArrowDown]: () => focusYear(nowFocusedYear + yearsInRow), [keys.ArrowLeft]: () => focusYear(nowFocusedYear + (theme.direction === 'ltr' ? -1 : 1)), [keys.ArrowRight]: () => focusYear(nowFocusedYear + (theme.direction === 'ltr' ? 1 : -1)) }); return /*#__PURE__*/React.createElement("div", { ref: ref, className: clsx(classes.root, className) }, utils.getYearRange(minDate, maxDate).map(year => { const yearNumber = utils.getYear(year); const selected = yearNumber === currentYear; return /*#__PURE__*/React.createElement(PickersYear, { key: utils.format(year, 'year'), selected: selected, value: yearNumber, onSelect: handleYearSelection, allowKeyboardControl: allowKeyboardControl, focused: yearNumber === focusedYear, ref: selected ? selectedYearRef : undefined, disabled: disablePast && utils.isBeforeYear(year, now) || disableFuture && utils.isAfterYear(year, now) || shouldDisableYear && shouldDisableYear(year) }, utils.format(year, 'year')); })); }); YearPicker.propTypes = { // ----------------------------- Warning -------------------------------- // | These PropTypes are generated from the TypeScript type definitions | // | To update them edit TypeScript types and run "yarn proptypes" | // ---------------------------------------------------------------------- /** * @ignore */ allowKeyboardControl: PropTypes.bool, /** * @ignore */ classes: PropTypes.object.isRequired, /** * @ignore */ className: PropTypes.string, /** * @ignore */ date: PropTypes.any, /** * @ignore */ disableFuture: PropTypes.bool, /** * @ignore */ disablePast: PropTypes.bool, /** * @ignore */ isDateDisabled: PropTypes.func.isRequired, /** * @ignore */ maxDate: PropTypes.any.isRequired, /** * @ignore */ minDate: PropTypes.any.isRequired, /** * @ignore */ onChange: PropTypes.func.isRequired, /** * @ignore */ onFocusedDayChange: PropTypes.func, /** * Callback firing on year change @DateIOType. */ onYearChange: PropTypes.func, /** * Disable specific years dynamically. * Works like `shouldDisableDate` but for year selection view. @DateIOType. */ shouldDisableYear: PropTypes.func }; export default withStyles(styles, { name: 'MuiPickersYearSelection' })(YearPicker);