@mui/x-date-pickers
Version:
The community edition of the Date and Time Picker components (MUI X).
233 lines (225 loc) • 9.3 kB
JavaScript
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.useField = void 0;
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
var React = _interopRequireWildcard(require("react"));
var _useEnhancedEffect = _interopRequireDefault(require("@mui/utils/useEnhancedEffect"));
var _useEventCallback = _interopRequireDefault(require("@mui/utils/useEventCallback"));
var _styles = require("@mui/material/styles");
var _useValidation = require("../useValidation");
var _useUtils = require("../useUtils");
var _useField = require("./useField.utils");
var _useFieldState = require("./useFieldState");
var _useFieldCharacterEditing = require("./useFieldCharacterEditing");
var _useFieldV7TextField = require("./useFieldV7TextField");
var _useFieldV6TextField = require("./useFieldV6TextField");
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 useField = params => {
const utils = (0, _useUtils.useUtils)();
const {
internalProps,
internalProps: {
unstableFieldRef,
minutesStep,
enableAccessibleFieldDOMStructure = false,
disabled = false,
readOnly = false
},
forwardedProps: {
onKeyDown,
error,
clearable,
onClear
},
fieldValueManager,
valueManager,
validator
} = params;
const theme = (0, _styles.useTheme)();
const isRTL = theme.direction === 'rtl';
const stateResponse = (0, _useFieldState.useFieldState)(params);
const {
state,
activeSectionIndex,
parsedSelectedSections,
setSelectedSections,
clearValue,
clearActiveSection,
updateSectionValue,
setTempAndroidValueStr,
sectionsValueBoundaries,
localizedDigits,
timezone
} = stateResponse;
const characterEditingResponse = (0, _useFieldCharacterEditing.useFieldCharacterEditing)({
sections: state.sections,
updateSectionValue,
sectionsValueBoundaries,
localizedDigits,
setTempAndroidValueStr,
timezone
});
const {
resetCharacterQuery
} = characterEditingResponse;
const areAllSectionsEmpty = valueManager.areValuesEqual(utils, state.value, valueManager.emptyValue);
const useFieldTextField = enableAccessibleFieldDOMStructure ? _useFieldV7TextField.useFieldV7TextField : _useFieldV6TextField.useFieldV6TextField;
const sectionOrder = React.useMemo(() => (0, _useField.getSectionOrder)(state.sections, isRTL && !enableAccessibleFieldDOMStructure), [state.sections, isRTL, enableAccessibleFieldDOMStructure]);
const {
returnedValue,
interactions
} = useFieldTextField((0, _extends2.default)({}, params, stateResponse, characterEditingResponse, {
areAllSectionsEmpty,
sectionOrder
}));
const handleContainerKeyDown = (0, _useEventCallback.default)(event => {
onKeyDown?.(event);
// eslint-disable-next-line default-case
switch (true) {
// Select all
case (event.ctrlKey || event.metaKey) && event.key.toLowerCase() === 'a' && !event.shiftKey && !event.altKey:
{
// prevent default to make sure that the next line "select all" while updating
// the internal state at the same time.
event.preventDefault();
setSelectedSections('all');
break;
}
case event.key === 'Enter':
{
event.preventDefault();
break;
}
// Move selection to next section
case event.key === 'ArrowRight':
{
event.preventDefault();
if (parsedSelectedSections == null) {
setSelectedSections(sectionOrder.startIndex);
} else if (parsedSelectedSections === 'all') {
setSelectedSections(sectionOrder.endIndex);
} else {
const nextSectionIndex = sectionOrder.neighbors[parsedSelectedSections].rightIndex;
if (nextSectionIndex !== null) {
setSelectedSections(nextSectionIndex);
}
}
break;
}
// Move selection to previous section
case event.key === 'ArrowLeft':
{
event.preventDefault();
if (parsedSelectedSections == null) {
setSelectedSections(sectionOrder.endIndex);
} else if (parsedSelectedSections === 'all') {
setSelectedSections(sectionOrder.startIndex);
} else {
const nextSectionIndex = sectionOrder.neighbors[parsedSelectedSections].leftIndex;
if (nextSectionIndex !== null) {
setSelectedSections(nextSectionIndex);
}
}
break;
}
// Reset the value of the selected section
case event.key === 'Delete':
{
event.preventDefault();
if (readOnly) {
break;
}
if (parsedSelectedSections == null || parsedSelectedSections === 'all') {
clearValue();
} else {
clearActiveSection();
}
resetCharacterQuery();
break;
}
// Increment / decrement the selected section value
case ['ArrowUp', 'ArrowDown', 'Home', 'End', 'PageUp', 'PageDown'].includes(event.key):
{
event.preventDefault();
if (readOnly || activeSectionIndex == null) {
break;
}
const activeSection = state.sections[activeSectionIndex];
const activeDateManager = fieldValueManager.getActiveDateManager(utils, state, activeSection);
const newSectionValue = (0, _useField.adjustSectionValue)(utils, timezone, activeSection, event.key, sectionsValueBoundaries, localizedDigits, activeDateManager.date, {
minutesStep
});
updateSectionValue({
activeSection,
newSectionValue,
shouldGoToNextSection: false
});
break;
}
}
});
(0, _useEnhancedEffect.default)(() => {
interactions.syncSelectionToDOM();
});
const validationError = (0, _useValidation.useValidation)((0, _extends2.default)({}, internalProps, {
value: state.value,
timezone
}), validator, valueManager.isSameError, valueManager.defaultErrorState);
const inputError = React.useMemo(() => {
// only override when `error` is undefined.
// in case of multi input fields, the `error` value is provided externally and will always be defined.
if (error !== undefined) {
return error;
}
return valueManager.hasError(validationError);
}, [valueManager, validationError, error]);
React.useEffect(() => {
if (!inputError && activeSectionIndex == null) {
resetCharacterQuery();
}
}, [state.referenceValue, activeSectionIndex, inputError]); // eslint-disable-line react-hooks/exhaustive-deps
// If `tempValueStrAndroid` is still defined for some section when running `useEffect`,
// Then `onChange` has only been called once, which means the user pressed `Backspace` to reset the section.
// This causes a small flickering on Android,
// But we can't use `useEnhancedEffect` which is always called before the second `onChange` call and then would cause false positives.
React.useEffect(() => {
if (state.tempValueStrAndroid != null && activeSectionIndex != null) {
resetCharacterQuery();
clearActiveSection();
}
}, [state.sections]); // eslint-disable-line react-hooks/exhaustive-deps
React.useImperativeHandle(unstableFieldRef, () => ({
getSections: () => state.sections,
getActiveSectionIndex: interactions.getActiveSectionIndexFromDOM,
setSelectedSections: interactions.setSelectedSections,
focusField: interactions.focusField,
isFieldFocused: interactions.isFieldFocused
}));
const handleClearValue = (0, _useEventCallback.default)((event, ...args) => {
event.preventDefault();
onClear?.(event, ...args);
clearValue();
if (!interactions.isFieldFocused()) {
// setSelectedSections is called internally
interactions.focusField(0);
} else {
setSelectedSections(sectionOrder.startIndex);
}
});
const commonForwardedProps = {
onKeyDown: handleContainerKeyDown,
onClear: handleClearValue,
error: inputError,
clearable: Boolean(clearable && !areAllSectionsEmpty && !readOnly && !disabled)
};
const commonAdditionalProps = {
disabled,
readOnly
};
return (0, _extends2.default)({}, params.forwardedProps, commonForwardedProps, commonAdditionalProps, returnedValue);
};
exports.useField = useField;
;