UNPKG

@mui/x-date-pickers

Version:

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

276 lines (270 loc) 10.6 kB
"use strict"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default; Object.defineProperty(exports, "__esModule", { value: true }); exports.useFieldState = void 0; var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var React = _interopRequireWildcard(require("react")); var _useControlled = _interopRequireDefault(require("@mui/utils/useControlled")); var _RtlProvider = require("@mui/system/RtlProvider"); var _usePickersTranslations = require("../../../hooks/usePickersTranslations"); var _useUtils = require("../useUtils"); var _useField = require("./useField.utils"); var _buildSectionsFromFormat = require("./buildSectionsFromFormat"); var _useValueWithTimezone = require("../useValueWithTimezone"); var _getDefaultReferenceDate = require("../../utils/getDefaultReferenceDate"); const useFieldState = params => { const utils = (0, _useUtils.useUtils)(); const translations = (0, _usePickersTranslations.usePickersTranslations)(); const adapter = (0, _useUtils.useLocalizationContext)(); const isRtl = (0, _RtlProvider.useRtl)(); const { valueManager, fieldValueManager, valueType, validator, internalProps, internalProps: { value: valueProp, defaultValue, referenceDate: referenceDateProp, onChange, format, formatDensity = 'dense', selectedSections: selectedSectionsProp, onSelectedSectionsChange, shouldRespectLeadingZeros = false, timezone: timezoneProp, enableAccessibleFieldDOMStructure = false } } = params; const { timezone, value: valueFromTheOutside, handleValueChange } = (0, _useValueWithTimezone.useValueWithTimezone)({ timezone: timezoneProp, value: valueProp, defaultValue, referenceDate: referenceDateProp, onChange, valueManager }); const localizedDigits = React.useMemo(() => (0, _useField.getLocalizedDigits)(utils), [utils]); const sectionsValueBoundaries = React.useMemo(() => (0, _useField.getSectionsBoundaries)(utils, localizedDigits, timezone), [utils, localizedDigits, timezone]); const getSectionsFromValue = React.useCallback((value, fallbackSections = null) => fieldValueManager.getSectionsFromValue(utils, value, fallbackSections, date => (0, _buildSectionsFromFormat.buildSectionsFromFormat)({ utils, localeText: translations, localizedDigits, format, date, formatDensity, shouldRespectLeadingZeros, enableAccessibleFieldDOMStructure, isRtl })), [fieldValueManager, format, translations, localizedDigits, isRtl, shouldRespectLeadingZeros, utils, formatDensity, enableAccessibleFieldDOMStructure]); const [state, setState] = React.useState(() => { const sections = getSectionsFromValue(valueFromTheOutside); (0, _useField.validateSections)(sections, valueType); const stateWithoutReferenceDate = { sections, value: valueFromTheOutside, referenceValue: valueManager.emptyValue, tempValueStrAndroid: null }; const granularity = (0, _getDefaultReferenceDate.getSectionTypeGranularity)(sections); const referenceValue = valueManager.getInitialReferenceValue({ referenceDate: referenceDateProp, value: valueFromTheOutside, utils, props: internalProps, granularity, timezone }); return (0, _extends2.default)({}, stateWithoutReferenceDate, { referenceValue }); }); const [selectedSections, innerSetSelectedSections] = (0, _useControlled.default)({ controlled: selectedSectionsProp, default: null, name: 'useField', state: 'selectedSections' }); const setSelectedSections = newSelectedSections => { innerSetSelectedSections(newSelectedSections); onSelectedSectionsChange?.(newSelectedSections); }; const parsedSelectedSections = React.useMemo(() => (0, _useField.parseSelectedSections)(selectedSections, state.sections), [selectedSections, state.sections]); const activeSectionIndex = parsedSelectedSections === 'all' ? 0 : parsedSelectedSections; const publishValue = ({ value, referenceValue, sections }) => { setState(prevState => (0, _extends2.default)({}, prevState, { sections, value, referenceValue, tempValueStrAndroid: null })); if (valueManager.areValuesEqual(utils, state.value, value)) { return; } const context = { validationError: validator({ adapter, value, timezone, props: internalProps }) }; handleValueChange(value, context); }; const setSectionValue = (sectionIndex, newSectionValue) => { const newSections = [...state.sections]; newSections[sectionIndex] = (0, _extends2.default)({}, newSections[sectionIndex], { value: newSectionValue, modified: true }); return newSections; }; const clearValue = () => { publishValue({ value: valueManager.emptyValue, referenceValue: state.referenceValue, sections: getSectionsFromValue(valueManager.emptyValue) }); }; const clearActiveSection = () => { if (activeSectionIndex == null) { return; } const activeSection = state.sections[activeSectionIndex]; const activeDateManager = fieldValueManager.getActiveDateManager(utils, state, activeSection); const nonEmptySectionCountBefore = activeDateManager.getSections(state.sections).filter(section => section.value !== '').length; const hasNoOtherNonEmptySections = nonEmptySectionCountBefore === (activeSection.value === '' ? 0 : 1); const newSections = setSectionValue(activeSectionIndex, ''); const newActiveDate = hasNoOtherNonEmptySections ? null : utils.getInvalidDate(); const newValues = activeDateManager.getNewValuesFromNewActiveDate(newActiveDate); publishValue((0, _extends2.default)({}, newValues, { sections: newSections })); }; const updateValueFromValueStr = valueStr => { const parseDateStr = (dateStr, referenceDate) => { const date = utils.parse(dateStr, format); if (date == null || !utils.isValid(date)) { return null; } const sections = (0, _buildSectionsFromFormat.buildSectionsFromFormat)({ utils, localeText: translations, localizedDigits, format, date, formatDensity, shouldRespectLeadingZeros, enableAccessibleFieldDOMStructure, isRtl }); return (0, _useField.mergeDateIntoReferenceDate)(utils, date, sections, referenceDate, false); }; const newValue = fieldValueManager.parseValueStr(valueStr, state.referenceValue, parseDateStr); const newReferenceValue = fieldValueManager.updateReferenceValue(utils, newValue, state.referenceValue); publishValue({ value: newValue, referenceValue: newReferenceValue, sections: getSectionsFromValue(newValue, state.sections) }); }; const updateSectionValue = ({ activeSection, newSectionValue, shouldGoToNextSection }) => { /** * 1. Decide which section should be focused */ if (shouldGoToNextSection && activeSectionIndex < state.sections.length - 1) { setSelectedSections(activeSectionIndex + 1); } /** * 2. Try to build a valid date from the new section value */ const activeDateManager = fieldValueManager.getActiveDateManager(utils, state, activeSection); const newSections = setSectionValue(activeSectionIndex, newSectionValue); const newActiveDateSections = activeDateManager.getSections(newSections); const newActiveDate = (0, _useField.getDateFromDateSections)(utils, newActiveDateSections, localizedDigits); let values; let shouldPublish; /** * If the new date is valid, * Then we merge the value of the modified sections into the reference date. * This makes sure that we don't lose some information of the initial date (like the time on a date field). */ if (newActiveDate != null && utils.isValid(newActiveDate)) { const mergedDate = (0, _useField.mergeDateIntoReferenceDate)(utils, newActiveDate, newActiveDateSections, activeDateManager.referenceDate, true); values = activeDateManager.getNewValuesFromNewActiveDate(mergedDate); shouldPublish = true; } else { values = activeDateManager.getNewValuesFromNewActiveDate(newActiveDate); shouldPublish = (newActiveDate != null && !utils.isValid(newActiveDate)) !== (activeDateManager.date != null && !utils.isValid(activeDateManager.date)); } /** * Publish or update the internal state with the new value and sections. */ if (shouldPublish) { return publishValue((0, _extends2.default)({}, values, { sections: newSections })); } return setState(prevState => (0, _extends2.default)({}, prevState, values, { sections: newSections, tempValueStrAndroid: null })); }; const setTempAndroidValueStr = tempValueStrAndroid => setState(prev => (0, _extends2.default)({}, prev, { tempValueStrAndroid })); React.useEffect(() => { const sections = getSectionsFromValue(state.value); (0, _useField.validateSections)(sections, valueType); setState(prevState => (0, _extends2.default)({}, prevState, { sections })); }, [format, utils.locale, isRtl]); // eslint-disable-line react-hooks/exhaustive-deps React.useEffect(() => { let shouldUpdate; if (!valueManager.areValuesEqual(utils, state.value, valueFromTheOutside)) { shouldUpdate = true; } else { shouldUpdate = valueManager.getTimezone(utils, state.value) !== valueManager.getTimezone(utils, valueFromTheOutside); } if (shouldUpdate) { setState(prevState => (0, _extends2.default)({}, prevState, { value: valueFromTheOutside, referenceValue: fieldValueManager.updateReferenceValue(utils, valueFromTheOutside, prevState.referenceValue), sections: getSectionsFromValue(valueFromTheOutside) })); } }, [valueFromTheOutside]); // eslint-disable-line react-hooks/exhaustive-deps return { state, activeSectionIndex, parsedSelectedSections, setSelectedSections, clearValue, clearActiveSection, updateSectionValue, updateValueFromValueStr, setTempAndroidValueStr, getSectionsFromValue, sectionsValueBoundaries, localizedDigits, timezone }; }; exports.useFieldState = useFieldState;