stupa-pdf-api/frontend/node_modules/@mui/x-date-pickers/internals/hooks/useField/useFieldState.js

280 lines
11 KiB
JavaScript

import _extends from "@babel/runtime/helpers/esm/extends";
import * as React from 'react';
import useControlled from '@mui/utils/useControlled';
import { useTheme } from '@mui/material/styles';
import { useUtils, useLocaleText, useLocalizationContext } from '../useUtils';
import { addPositionPropertiesToSections, splitFormatIntoSections, mergeDateIntoReferenceDate, getSectionsBoundaries, validateSections, getDateFromDateSections } from './useField.utils';
import { useValueWithTimezone } from '../useValueWithTimezone';
import { getSectionTypeGranularity } from '../../utils/getDefaultReferenceDate';
export const useFieldState = params => {
const utils = useUtils();
const localeText = useLocaleText();
const adapter = useLocalizationContext();
const theme = useTheme();
const isRTL = theme.direction === 'rtl';
const {
valueManager,
fieldValueManager,
valueType,
validator,
internalProps,
internalProps: {
value: valueProp,
defaultValue,
referenceDate: referenceDateProp,
onChange,
format,
formatDensity = 'dense',
selectedSections: selectedSectionsProp,
onSelectedSectionsChange,
shouldRespectLeadingZeros = false,
timezone: timezoneProp
}
} = params;
const {
timezone,
value: valueFromTheOutside,
handleValueChange
} = useValueWithTimezone({
timezone: timezoneProp,
value: valueProp,
defaultValue,
onChange,
valueManager
});
const sectionsValueBoundaries = React.useMemo(() => getSectionsBoundaries(utils, timezone), [utils, timezone]);
const getSectionsFromValue = React.useCallback((value, fallbackSections = null) => fieldValueManager.getSectionsFromValue(utils, value, fallbackSections, isRTL, date => splitFormatIntoSections(utils, timezone, localeText, format, date, formatDensity, shouldRespectLeadingZeros, isRTL)), [fieldValueManager, format, localeText, isRTL, shouldRespectLeadingZeros, utils, formatDensity, timezone]);
const placeholder = React.useMemo(() => fieldValueManager.getValueStrFromSections(getSectionsFromValue(valueManager.emptyValue), isRTL), [fieldValueManager, getSectionsFromValue, valueManager.emptyValue, isRTL]);
const [state, setState] = React.useState(() => {
const sections = getSectionsFromValue(valueFromTheOutside);
validateSections(sections, valueType);
const stateWithoutReferenceDate = {
sections,
value: valueFromTheOutside,
referenceValue: valueManager.emptyValue,
tempValueStrAndroid: null
};
const granularity = getSectionTypeGranularity(sections);
const referenceValue = valueManager.getInitialReferenceValue({
referenceDate: referenceDateProp,
value: valueFromTheOutside,
utils,
props: internalProps,
granularity,
timezone
});
return _extends({}, stateWithoutReferenceDate, {
referenceValue
});
});
const [selectedSections, innerSetSelectedSections] = useControlled({
controlled: selectedSectionsProp,
default: null,
name: 'useField',
state: 'selectedSectionIndexes'
});
const setSelectedSections = newSelectedSections => {
innerSetSelectedSections(newSelectedSections);
onSelectedSectionsChange == null || onSelectedSectionsChange(newSelectedSections);
setState(prevState => _extends({}, prevState, {
selectedSectionQuery: null
}));
};
const selectedSectionIndexes = React.useMemo(() => {
if (selectedSections == null) {
return null;
}
if (selectedSections === 'all') {
return {
startIndex: 0,
endIndex: state.sections.length - 1,
shouldSelectBoundarySelectors: true
};
}
if (typeof selectedSections === 'number') {
return {
startIndex: selectedSections,
endIndex: selectedSections
};
}
if (typeof selectedSections === 'string') {
const selectedSectionIndex = state.sections.findIndex(section => section.type === selectedSections);
return {
startIndex: selectedSectionIndex,
endIndex: selectedSectionIndex
};
}
return selectedSections;
}, [selectedSections, state.sections]);
const publishValue = ({
value,
referenceValue,
sections
}) => {
setState(prevState => _extends({}, prevState, {
sections,
value,
referenceValue,
tempValueStrAndroid: null
}));
if (valueManager.areValuesEqual(utils, state.value, value)) {
return;
}
const context = {
validationError: validator({
adapter,
value,
props: _extends({}, internalProps, {
value,
timezone
})
})
};
handleValueChange(value, context);
};
const setSectionValue = (sectionIndex, newSectionValue) => {
const newSections = [...state.sections];
newSections[sectionIndex] = _extends({}, newSections[sectionIndex], {
value: newSectionValue,
modified: true
});
return addPositionPropertiesToSections(newSections, isRTL);
};
const clearValue = () => {
publishValue({
value: valueManager.emptyValue,
referenceValue: state.referenceValue,
sections: getSectionsFromValue(valueManager.emptyValue)
});
};
const clearActiveSection = () => {
if (selectedSectionIndexes == null) {
return;
}
const activeSection = state.sections[selectedSectionIndexes.startIndex];
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(selectedSectionIndexes.startIndex, '');
const newActiveDate = hasNoOtherNonEmptySections ? null : utils.date(new Date(''));
const newValues = activeDateManager.getNewValuesFromNewActiveDate(newActiveDate);
if ((newActiveDate != null && !utils.isValid(newActiveDate)) !== (activeDateManager.date != null && !utils.isValid(activeDateManager.date))) {
publishValue(_extends({}, newValues, {
sections: newSections
}));
} else {
setState(prevState => _extends({}, prevState, newValues, {
sections: newSections,
tempValueStrAndroid: null
}));
}
};
const updateValueFromValueStr = valueStr => {
const parseDateStr = (dateStr, referenceDate) => {
const date = utils.parse(dateStr, format);
if (date == null || !utils.isValid(date)) {
return null;
}
const sections = splitFormatIntoSections(utils, timezone, localeText, format, date, formatDensity, shouldRespectLeadingZeros, isRTL);
return mergeDateIntoReferenceDate(utils, timezone, 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 && selectedSectionIndexes && selectedSectionIndexes.startIndex < state.sections.length - 1) {
setSelectedSections(selectedSectionIndexes.startIndex + 1);
} else if (selectedSectionIndexes && selectedSectionIndexes.startIndex !== selectedSectionIndexes.endIndex) {
setSelectedSections(selectedSectionIndexes.startIndex);
}
/**
* 2. Try to build a valid date from the new section value
*/
const activeDateManager = fieldValueManager.getActiveDateManager(utils, state, activeSection);
const newSections = setSectionValue(selectedSectionIndexes.startIndex, newSectionValue);
const newActiveDateSections = activeDateManager.getSections(newSections);
const newActiveDate = getDateFromDateSections(utils, newActiveDateSections);
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 = mergeDateIntoReferenceDate(utils, timezone, 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(_extends({}, values, {
sections: newSections
}));
}
return setState(prevState => _extends({}, prevState, values, {
sections: newSections,
tempValueStrAndroid: null
}));
};
const setTempAndroidValueStr = tempValueStrAndroid => setState(prev => _extends({}, prev, {
tempValueStrAndroid
}));
React.useEffect(() => {
const sections = getSectionsFromValue(state.value);
validateSections(sections, valueType);
setState(prevState => _extends({}, prevState, {
sections
}));
}, [format, utils.locale]); // eslint-disable-line react-hooks/exhaustive-deps
React.useEffect(() => {
let shouldUpdate = false;
if (!valueManager.areValuesEqual(utils, state.value, valueFromTheOutside)) {
shouldUpdate = true;
} else {
shouldUpdate = valueManager.getTimezone(utils, state.value) !== valueManager.getTimezone(utils, valueFromTheOutside);
}
if (shouldUpdate) {
setState(prevState => _extends({}, prevState, {
value: valueFromTheOutside,
referenceValue: fieldValueManager.updateReferenceValue(utils, valueFromTheOutside, prevState.referenceValue),
sections: getSectionsFromValue(valueFromTheOutside)
}));
}
}, [valueFromTheOutside]); // eslint-disable-line react-hooks/exhaustive-deps
return {
state,
selectedSectionIndexes,
setSelectedSections,
clearValue,
clearActiveSection,
updateSectionValue,
updateValueFromValueStr,
setTempAndroidValueStr,
sectionsValueBoundaries,
placeholder,
timezone
};
};