@mui/x-date-pickers 8.0.0-beta.1 → 8.0.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (114) hide show
  1. package/CHANGELOG.md +94 -0
  2. package/DateCalendar/DateCalendar.js +4 -8
  3. package/DateCalendar/DayCalendar.js +2 -2
  4. package/DatePicker/shared.js +3 -9
  5. package/DateTimePicker/shared.js +3 -13
  6. package/MonthCalendar/MonthCalendar.js +4 -9
  7. package/PickersSectionList/PickersSectionList.d.ts +1 -1
  8. package/PickersSectionList/PickersSectionList.types.d.ts +2 -6
  9. package/TimePicker/shared.js +3 -3
  10. package/YearCalendar/YearCalendar.js +4 -10
  11. package/esm/DateCalendar/DateCalendar.js +6 -10
  12. package/esm/DateCalendar/DayCalendar.js +2 -2
  13. package/esm/DatePicker/shared.js +3 -9
  14. package/esm/DateTimePicker/shared.js +4 -14
  15. package/esm/MonthCalendar/MonthCalendar.js +6 -11
  16. package/esm/PickersSectionList/PickersSectionList.d.ts +1 -1
  17. package/esm/PickersSectionList/PickersSectionList.types.d.ts +2 -6
  18. package/esm/TimePicker/shared.js +3 -3
  19. package/esm/YearCalendar/YearCalendar.js +5 -11
  20. package/esm/index.js +1 -1
  21. package/esm/internals/hooks/useField/syncSelectionToDOM.d.ts +9 -0
  22. package/esm/internals/hooks/useField/syncSelectionToDOM.js +50 -0
  23. package/esm/internals/hooks/useField/useField.types.d.ts +8 -1
  24. package/esm/internals/hooks/useField/useField.utils.d.ts +1 -3
  25. package/esm/internals/hooks/useField/useField.utils.js +0 -57
  26. package/esm/internals/hooks/useField/useFieldHiddenInputProps.d.ts +20 -0
  27. package/esm/internals/hooks/useField/useFieldHiddenInputProps.js +31 -0
  28. package/esm/internals/hooks/useField/useFieldInternalPropsWithDefaults.js +8 -10
  29. package/esm/internals/hooks/useField/useFieldRootHandleKeyDown.js +1 -0
  30. package/esm/internals/hooks/useField/useFieldRootProps.d.ts +32 -0
  31. package/esm/internals/hooks/useField/useFieldRootProps.js +150 -0
  32. package/esm/internals/hooks/useField/useFieldSectionContainerProps.d.ts +15 -0
  33. package/esm/internals/hooks/useField/useFieldSectionContainerProps.js +29 -0
  34. package/esm/internals/hooks/useField/useFieldSectionContentProps.d.ts +23 -0
  35. package/esm/internals/hooks/useField/useFieldSectionContentProps.js +226 -0
  36. package/esm/internals/hooks/useField/useFieldV7TextField.js +76 -307
  37. package/esm/internals/index.d.ts +4 -4
  38. package/esm/internals/index.js +3 -3
  39. package/esm/locales/deDE.js +2 -3
  40. package/esm/managers/useDateManager.d.ts +4 -13
  41. package/esm/managers/useDateManager.js +18 -28
  42. package/esm/managers/useDateTimeManager.d.ts +4 -13
  43. package/esm/managers/useDateTimeManager.js +23 -33
  44. package/esm/managers/useTimeManager.d.ts +4 -13
  45. package/esm/managers/useTimeManager.js +14 -24
  46. package/esm/models/manager.d.ts +3 -8
  47. package/esm/validation/validateDate.js +3 -4
  48. package/index.js +1 -1
  49. package/internals/hooks/useField/syncSelectionToDOM.d.ts +9 -0
  50. package/internals/hooks/useField/syncSelectionToDOM.js +56 -0
  51. package/internals/hooks/useField/useField.types.d.ts +8 -1
  52. package/internals/hooks/useField/useField.utils.d.ts +1 -3
  53. package/internals/hooks/useField/useField.utils.js +2 -61
  54. package/internals/hooks/useField/useFieldHiddenInputProps.d.ts +20 -0
  55. package/internals/hooks/useField/useFieldHiddenInputProps.js +39 -0
  56. package/internals/hooks/useField/useFieldInternalPropsWithDefaults.js +8 -10
  57. package/internals/hooks/useField/useFieldRootHandleKeyDown.js +1 -0
  58. package/internals/hooks/useField/useFieldRootProps.d.ts +32 -0
  59. package/internals/hooks/useField/useFieldRootProps.js +156 -0
  60. package/internals/hooks/useField/useFieldSectionContainerProps.d.ts +15 -0
  61. package/internals/hooks/useField/useFieldSectionContainerProps.js +37 -0
  62. package/internals/hooks/useField/useFieldSectionContentProps.d.ts +23 -0
  63. package/internals/hooks/useField/useFieldSectionContentProps.js +234 -0
  64. package/internals/hooks/useField/useFieldV7TextField.js +75 -306
  65. package/internals/index.d.ts +4 -4
  66. package/internals/index.js +18 -18
  67. package/locales/deDE.js +2 -3
  68. package/managers/useDateManager.d.ts +4 -13
  69. package/managers/useDateManager.js +18 -28
  70. package/managers/useDateTimeManager.d.ts +4 -13
  71. package/managers/useDateTimeManager.js +23 -33
  72. package/managers/useTimeManager.d.ts +4 -13
  73. package/managers/useTimeManager.js +15 -25
  74. package/models/manager.d.ts +3 -8
  75. package/modern/DateCalendar/DateCalendar.js +6 -10
  76. package/modern/DateCalendar/DayCalendar.js +2 -2
  77. package/modern/DatePicker/shared.js +3 -9
  78. package/modern/DateTimePicker/shared.js +4 -14
  79. package/modern/MonthCalendar/MonthCalendar.js +6 -11
  80. package/modern/PickersSectionList/PickersSectionList.d.ts +1 -1
  81. package/modern/PickersSectionList/PickersSectionList.types.d.ts +2 -6
  82. package/modern/TimePicker/shared.js +3 -3
  83. package/modern/YearCalendar/YearCalendar.js +5 -11
  84. package/modern/index.js +1 -1
  85. package/modern/internals/hooks/useField/syncSelectionToDOM.d.ts +9 -0
  86. package/modern/internals/hooks/useField/syncSelectionToDOM.js +50 -0
  87. package/modern/internals/hooks/useField/useField.types.d.ts +8 -1
  88. package/modern/internals/hooks/useField/useField.utils.d.ts +1 -3
  89. package/modern/internals/hooks/useField/useField.utils.js +0 -57
  90. package/modern/internals/hooks/useField/useFieldHiddenInputProps.d.ts +20 -0
  91. package/modern/internals/hooks/useField/useFieldHiddenInputProps.js +31 -0
  92. package/modern/internals/hooks/useField/useFieldInternalPropsWithDefaults.js +8 -10
  93. package/modern/internals/hooks/useField/useFieldRootHandleKeyDown.js +1 -0
  94. package/modern/internals/hooks/useField/useFieldRootProps.d.ts +32 -0
  95. package/modern/internals/hooks/useField/useFieldRootProps.js +150 -0
  96. package/modern/internals/hooks/useField/useFieldSectionContainerProps.d.ts +15 -0
  97. package/modern/internals/hooks/useField/useFieldSectionContainerProps.js +29 -0
  98. package/modern/internals/hooks/useField/useFieldSectionContentProps.d.ts +23 -0
  99. package/modern/internals/hooks/useField/useFieldSectionContentProps.js +226 -0
  100. package/modern/internals/hooks/useField/useFieldV7TextField.js +76 -307
  101. package/modern/internals/index.d.ts +4 -4
  102. package/modern/internals/index.js +3 -3
  103. package/modern/locales/deDE.js +2 -3
  104. package/modern/managers/useDateManager.d.ts +4 -13
  105. package/modern/managers/useDateManager.js +18 -28
  106. package/modern/managers/useDateTimeManager.d.ts +4 -13
  107. package/modern/managers/useDateTimeManager.js +23 -33
  108. package/modern/managers/useTimeManager.d.ts +4 -13
  109. package/modern/managers/useTimeManager.js +14 -24
  110. package/modern/models/manager.d.ts +3 -8
  111. package/modern/validation/validateDate.js +3 -4
  112. package/package.json +2 -2
  113. package/tsconfig.build.tsbuildinfo +1 -1
  114. package/validation/validateDate.js +3 -4
@@ -4,12 +4,14 @@ import { useThemeProps } from '@mui/material/styles';
4
4
  import { useUtils } from "../internals/hooks/useUtils.js";
5
5
  import { TimePickerToolbar } from "./TimePickerToolbar.js";
6
6
  import { applyDefaultViewProps } from "../internals/utils/views.js";
7
+ import { useApplyDefaultValuesToTimeValidationProps } from "../managers/useTimeManager.js";
7
8
  export function useTimePickerDefaultizedProps(props, name) {
8
9
  const utils = useUtils();
9
10
  const themeProps = useThemeProps({
10
11
  props,
11
12
  name
12
13
  });
14
+ const validationProps = useApplyDefaultValuesToTimeValidationProps(themeProps);
13
15
  const ampm = themeProps.ampm ?? utils.is12HourCycleInCurrentLocale();
14
16
  const localeText = React.useMemo(() => {
15
17
  if (themeProps.localeText?.toolbarTitle == null) {
@@ -19,7 +21,7 @@ export function useTimePickerDefaultizedProps(props, name) {
19
21
  timePickerToolbarTitle: themeProps.localeText.toolbarTitle
20
22
  });
21
23
  }, [themeProps.localeText]);
22
- return _extends({}, themeProps, {
24
+ return _extends({}, themeProps, validationProps, {
23
25
  ampm,
24
26
  localeText
25
27
  }, applyDefaultViewProps({
@@ -28,8 +30,6 @@ export function useTimePickerDefaultizedProps(props, name) {
28
30
  defaultViews: ['hours', 'minutes'],
29
31
  defaultOpenTo: 'hours'
30
32
  }), {
31
- disableFuture: themeProps.disableFuture ?? false,
32
- disablePast: themeProps.disablePast ?? false,
33
33
  slots: _extends({
34
34
  toolbar: TimePickerToolbar
35
35
  }, themeProps.slots),
@@ -11,14 +11,14 @@ import { shouldForwardProp } from '@mui/system/createStyled';
11
11
  import { styled, useThemeProps } from '@mui/material/styles';
12
12
  import { unstable_useForkRef as useForkRef, unstable_composeClasses as composeClasses, unstable_useControlled as useControlled, unstable_useEventCallback as useEventCallback } from '@mui/utils';
13
13
  import { YearCalendarButton } from "./YearCalendarButton.js";
14
- import { useUtils, useNow, useDefaultDates } from "../internals/hooks/useUtils.js";
14
+ import { useUtils, useNow } from "../internals/hooks/useUtils.js";
15
15
  import { getYearCalendarUtilityClass } from "./yearCalendarClasses.js";
16
- import { applyDefaultDate } from "../internals/utils/date-utils.js";
17
16
  import { singleItemValueManager } from "../internals/utils/valueManagers.js";
18
17
  import { SECTION_TYPE_GRANULARITY } from "../internals/utils/getDefaultReferenceDate.js";
19
18
  import { useControlledValue } from "../internals/hooks/useControlledValue.js";
20
19
  import { DIALOG_WIDTH, MAX_CALENDAR_HEIGHT } from "../internals/constants/dimensions.js";
21
20
  import { usePickerPrivateContext } from "../internals/hooks/usePickerPrivateContext.js";
21
+ import { useApplyDefaultValuesToDateValidationProps } from "../managers/useDateManager.js";
22
22
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
23
23
  const useUtilityClasses = classes => {
24
24
  const slots = {
@@ -27,20 +27,14 @@ const useUtilityClasses = classes => {
27
27
  return composeClasses(slots, getYearCalendarUtilityClass, classes);
28
28
  };
29
29
  function useYearCalendarDefaultizedProps(props, name) {
30
- const utils = useUtils();
31
- const defaultDates = useDefaultDates();
32
30
  const themeProps = useThemeProps({
33
31
  props,
34
32
  name
35
33
  });
36
- return _extends({
37
- disablePast: false,
38
- disableFuture: false
39
- }, themeProps, {
34
+ const validationProps = useApplyDefaultValuesToDateValidationProps(themeProps);
35
+ return _extends({}, themeProps, validationProps, {
40
36
  yearsPerRow: themeProps.yearsPerRow ?? 3,
41
- yearsOrder: themeProps.yearsOrder ?? 'asc',
42
- minDate: applyDefaultDate(utils, themeProps.minDate, defaultDates.minDate),
43
- maxDate: applyDefaultDate(utils, themeProps.maxDate, defaultDates.maxDate)
37
+ yearsOrder: themeProps.yearsOrder ?? 'asc'
44
38
  });
45
39
  }
46
40
  const YearCalendarRoot = styled('div', {
package/esm/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @mui/x-date-pickers v8.0.0-beta.1
2
+ * @mui/x-date-pickers v8.0.0-beta.2
3
3
  *
4
4
  * @license MIT
5
5
  * This source code is licensed under the MIT license found in the
@@ -0,0 +1,9 @@
1
+ import { PickerValidValue } from "../../models/index.js";
2
+ import { UseFieldDOMGetters } from "./useField.types.js";
3
+ import { UseFieldStateReturnValue } from "./useFieldState.js";
4
+ export declare function syncSelectionToDOM<TValue extends PickerValidValue>(parameters: SyncSelectionToDOMParameters<TValue>): void;
5
+ export interface SyncSelectionToDOMParameters<TValue extends PickerValidValue> {
6
+ domGetters: UseFieldDOMGetters;
7
+ stateResponse: UseFieldStateReturnValue<TValue>;
8
+ focused: boolean;
9
+ }
@@ -0,0 +1,50 @@
1
+ import { getActiveElement } from "../../utils/utils.js";
2
+ export function syncSelectionToDOM(parameters) {
3
+ const {
4
+ focused,
5
+ domGetters,
6
+ stateResponse: {
7
+ // States and derived states
8
+ parsedSelectedSections,
9
+ state
10
+ }
11
+ } = parameters;
12
+ if (!domGetters.isReady()) {
13
+ return;
14
+ }
15
+ const selection = document.getSelection();
16
+ if (!selection) {
17
+ return;
18
+ }
19
+ if (parsedSelectedSections == null) {
20
+ // If the selection contains an element inside the field, we reset it.
21
+ if (selection.rangeCount > 0 && domGetters.getRoot().contains(selection.getRangeAt(0).startContainer)) {
22
+ selection.removeAllRanges();
23
+ }
24
+ if (focused) {
25
+ domGetters.getRoot().blur();
26
+ }
27
+ return;
28
+ }
29
+
30
+ // On multi input range pickers we want to update selection range only for the active input
31
+ if (!domGetters.getRoot().contains(getActiveElement(document))) {
32
+ return;
33
+ }
34
+ const range = new window.Range();
35
+ let target;
36
+ if (parsedSelectedSections === 'all') {
37
+ target = domGetters.getRoot();
38
+ } else {
39
+ const section = state.sections[parsedSelectedSections];
40
+ if (section.type === 'empty') {
41
+ target = domGetters.getSectionContainer(parsedSelectedSections);
42
+ } else {
43
+ target = domGetters.getSectionContent(parsedSelectedSections);
44
+ }
45
+ }
46
+ range.selectNodeContents(target);
47
+ target.focus();
48
+ selection.removeAllRanges();
49
+ selection.addRange(range);
50
+ }
@@ -1,7 +1,7 @@
1
1
  import * as React from 'react';
2
2
  import { FieldSectionType, FieldSection, FieldSelectedSections, MuiPickersAdapter, TimezoneProps, FieldSectionContentType, PickerValidDate, FieldRef, OnErrorProps, InferFieldSection, PickerManager, PickerValueType } from "../../../models/index.js";
3
3
  import { InternalPropNames } from "../../../hooks/useSplitFieldProps.js";
4
- import { PickersSectionElement, PickersSectionListRef } from "../../../PickersSectionList/index.js";
4
+ import type { PickersSectionElement, PickersSectionListRef } from '../../../PickersSectionList';
5
5
  import { FormProps, InferNonNullablePickerValue, PickerValidValue } from "../../models/index.js";
6
6
  export interface UseFieldParameters<TValue extends PickerValidValue, TEnableAccessibleFieldDOMStructure extends boolean, TError, TValidationProps extends {}, TProps extends UseFieldProps<TEnableAccessibleFieldDOMStructure>> {
7
7
  manager: PickerManager<TValue, TEnableAccessibleFieldDOMStructure, TError, TValidationProps, any>;
@@ -319,4 +319,11 @@ export interface CharacterEditingQuery {
319
319
  export type UseFieldProps<TEnableAccessibleFieldDOMStructure extends boolean> = UseFieldForwardedProps<TEnableAccessibleFieldDOMStructure> & {
320
320
  enableAccessibleFieldDOMStructure?: boolean;
321
321
  };
322
+ export interface UseFieldDOMGetters {
323
+ isReady: () => boolean;
324
+ getRoot: () => HTMLElement;
325
+ getSectionContainer: (sectionIndex: number) => HTMLElement;
326
+ getSectionContent: (sectionIndex: number) => HTMLElement;
327
+ getSectionIndexFromDOMElement: (element: Element | null | undefined) => number | null;
328
+ }
322
329
  export {};
@@ -33,6 +33,4 @@ export declare const validateSections: <TValue extends PickerValidValue>(section
33
33
  export declare const mergeDateIntoReferenceDate: (utils: MuiPickersAdapter, dateToTransferFrom: PickerValidDate, sections: FieldSection[], referenceDate: PickerValidDate, shouldLimitToEditedSections: boolean) => PickerValidDate;
34
34
  export declare const isAndroid: () => boolean;
35
35
  export declare const getSectionOrder: (sections: FieldSection[], shouldApplyRTL: boolean) => SectionOrdering;
36
- export declare const parseSelectedSections: (selectedSections: FieldSelectedSections, sections: FieldSection[]) => FieldParsedSelectedSections;
37
- export declare const getSectionValueText: (section: FieldSection, utils: MuiPickersAdapter) => string | undefined;
38
- export declare const getSectionValueNow: (section: FieldSection, utils: MuiPickersAdapter) => number | undefined;
36
+ export declare const parseSelectedSections: (selectedSections: FieldSelectedSections, sections: FieldSection[]) => FieldParsedSelectedSections;
@@ -493,61 +493,4 @@ export const parseSelectedSections = (selectedSections, sections) => {
493
493
  return index === -1 ? null : index;
494
494
  }
495
495
  return selectedSections;
496
- };
497
- export const getSectionValueText = (section, utils) => {
498
- if (!section.value) {
499
- return undefined;
500
- }
501
- switch (section.type) {
502
- case 'month':
503
- {
504
- if (section.contentType === 'digit') {
505
- return utils.format(utils.setMonth(utils.date(), Number(section.value) - 1), 'month');
506
- }
507
- const parsedDate = utils.parse(section.value, section.format);
508
- return parsedDate ? utils.format(parsedDate, 'month') : undefined;
509
- }
510
- case 'day':
511
- return section.contentType === 'digit' ? utils.format(utils.setDate(utils.startOfYear(utils.date()), Number(section.value)), 'dayOfMonthFull') : section.value;
512
- case 'weekDay':
513
- // TODO: improve by providing the label of the week day
514
- return undefined;
515
- default:
516
- return undefined;
517
- }
518
- };
519
- export const getSectionValueNow = (section, utils) => {
520
- if (!section.value) {
521
- return undefined;
522
- }
523
- switch (section.type) {
524
- case 'weekDay':
525
- {
526
- if (section.contentType === 'letter') {
527
- // TODO: improve by resolving the week day number from a letter week day
528
- return undefined;
529
- }
530
- return Number(section.value);
531
- }
532
- case 'meridiem':
533
- {
534
- const parsedDate = utils.parse(`01:00 ${section.value}`, `${utils.formats.hours12h}:${utils.formats.minutes} ${section.format}`);
535
- if (parsedDate) {
536
- return utils.getHours(parsedDate) >= 12 ? 1 : 0;
537
- }
538
- return undefined;
539
- }
540
- case 'day':
541
- return section.contentType === 'digit-with-letter' ? parseInt(section.value, 10) : Number(section.value);
542
- case 'month':
543
- {
544
- if (section.contentType === 'digit') {
545
- return Number(section.value);
546
- }
547
- const parsedDate = utils.parse(section.value, section.format);
548
- return parsedDate ? utils.getMonth(parsedDate) + 1 : undefined;
549
- }
550
- default:
551
- return section.contentType !== 'letter' ? Number(section.value) : undefined;
552
- }
553
496
  };
@@ -0,0 +1,20 @@
1
+ import * as React from 'react';
2
+ import { PickerManager } from "../../../models/index.js";
3
+ import { UseFieldStateReturnValue } from "./useFieldState.js";
4
+ /**
5
+ * Generate the props to pass to the hidden input element of the field.
6
+ * It is not used by the non-accessible DOM structure (with an <input /> element for editing).
7
+ * It should be used in the MUI accessible DOM structure and the Base UI implementation.
8
+ * @param {UseFieldHiddenInputPropsParameters} parameters The parameters of the hook.
9
+ * @returns {UseFieldHiddenInputPropsReturnValue} The props to forward to the hidden input element of the field.
10
+ */
11
+ export declare function useFieldHiddenInputProps(parameters: UseFieldHiddenInputPropsParameters): UseFieldHiddenInputPropsReturnValue;
12
+ interface UseFieldHiddenInputPropsParameters {
13
+ manager: PickerManager<any, any, any, any, any>;
14
+ stateResponse: UseFieldStateReturnValue<any>;
15
+ }
16
+ interface UseFieldHiddenInputPropsReturnValue {
17
+ value: string;
18
+ onChange: React.ChangeEventHandler<HTMLInputElement>;
19
+ }
20
+ export {};
@@ -0,0 +1,31 @@
1
+ import * as React from 'react';
2
+ import useEventCallback from '@mui/utils/useEventCallback';
3
+ /**
4
+ * Generate the props to pass to the hidden input element of the field.
5
+ * It is not used by the non-accessible DOM structure (with an <input /> element for editing).
6
+ * It should be used in the MUI accessible DOM structure and the Base UI implementation.
7
+ * @param {UseFieldHiddenInputPropsParameters} parameters The parameters of the hook.
8
+ * @returns {UseFieldHiddenInputPropsReturnValue} The props to forward to the hidden input element of the field.
9
+ */
10
+ export function useFieldHiddenInputProps(parameters) {
11
+ const {
12
+ manager: {
13
+ internal_fieldValueManager: fieldValueManager
14
+ },
15
+ stateResponse: {
16
+ // States and derived states
17
+ areAllSectionsEmpty,
18
+ state,
19
+ // Methods to update the states
20
+ updateValueFromValueStr
21
+ }
22
+ } = parameters;
23
+ const handleChange = useEventCallback(event => {
24
+ updateValueFromValueStr(event.target.value);
25
+ });
26
+ const valueStr = React.useMemo(() => areAllSectionsEmpty ? '' : fieldValueManager.getV7HiddenInputValueFromSections(state.sections), [areAllSectionsEmpty, state.sections, fieldValueManager]);
27
+ return {
28
+ value: valueStr,
29
+ onChange: handleChange
30
+ };
31
+ }
@@ -1,7 +1,6 @@
1
1
  import _extends from "@babel/runtime/helpers/esm/extends";
2
2
  import * as React from 'react';
3
3
  import useForkRef from '@mui/utils/useForkRef';
4
- import { useLocalizationContext } from "../useUtils.js";
5
4
  import { useNullablePickerContext } from "../useNullablePickerContext.js";
6
5
  import { useNullableFieldPrivateContext } from "../useNullableFieldPrivateContext.js";
7
6
 
@@ -12,11 +11,12 @@ import { useNullableFieldPrivateContext } from "../useNullableFieldPrivateContex
12
11
  */
13
12
  export function useFieldInternalPropsWithDefaults(parameters) {
14
13
  const {
15
- manager,
14
+ manager: {
15
+ internal_useApplyDefaultValuesToFieldInternalProps: useApplyDefaultValuesToFieldInternalProps
16
+ },
16
17
  internalProps,
17
18
  skipContextFieldRefAssignment
18
19
  } = parameters;
19
- const localizationContext = useLocalizationContext();
20
20
  const pickerContext = useNullablePickerContext();
21
21
  const fieldPrivateContext = useNullableFieldPrivateContext();
22
22
  const handleFieldRef = useForkRef(internalProps.unstableFieldRef, skipContextFieldRefAssignment ? null : fieldPrivateContext?.fieldRef);
@@ -27,12 +27,11 @@ export function useFieldInternalPropsWithDefaults(parameters) {
27
27
  shouldClose: false
28
28
  });
29
29
  }, [setValue]);
30
- return React.useMemo(() => {
31
- let internalPropsWithDefaultsFromContext = internalProps;
30
+ const internalPropsWithDefaultsFromContext = React.useMemo(() => {
32
31
  // If one of the context is null,
33
32
  // Then the field is used as a standalone component and the other context will be null as well.
34
33
  if (fieldPrivateContext != null && pickerContext != null) {
35
- internalPropsWithDefaultsFromContext = _extends({
34
+ return _extends({
36
35
  value: pickerContext.value,
37
36
  onChange: handleChangeFromPicker,
38
37
  timezone: pickerContext.timezone,
@@ -48,8 +47,7 @@ export function useFieldInternalPropsWithDefaults(parameters) {
48
47
  unstableFieldRef: handleFieldRef
49
48
  }, internalProps);
50
49
  }
51
- return manager.internal_applyDefaultsToFieldInternalProps(_extends({}, localizationContext, {
52
- internalProps: internalPropsWithDefaultsFromContext
53
- }));
54
- }, [manager, localizationContext, pickerContext, fieldPrivateContext, internalProps, handleChangeFromPicker, handleFieldRef]);
50
+ return internalProps;
51
+ }, [pickerContext, fieldPrivateContext, internalProps, handleChangeFromPicker, handleFieldRef]);
52
+ return useApplyDefaultValuesToFieldInternalProps(internalPropsWithDefaultsFromContext);
55
53
  }
@@ -37,6 +37,7 @@ export function useFieldRootHandleKeyDown(parameters) {
37
37
  if (disabled) {
38
38
  return;
39
39
  }
40
+
40
41
  // eslint-disable-next-line default-case
41
42
  switch (true) {
42
43
  // Select all
@@ -0,0 +1,32 @@
1
+ import { PickerManager } from "../../../models/index.js";
2
+ import { UseFieldDOMGetters, UseFieldInternalProps } from "./useField.types.js";
3
+ import { UseFieldStateReturnValue } from "./useFieldState.js";
4
+ import { UseFieldCharacterEditingReturnValue } from "./useFieldCharacterEditing.js";
5
+ /**
6
+ * Generate the props to pass to the root element of the field.
7
+ * It is not used by the non-accessible DOM structure (with an <input /> element for editing).
8
+ * It should be used in the MUI accessible DOM structure and the Base UI implementation.
9
+ * @param {UseFieldRootPropsParameters} parameters The parameters of the hook.
10
+ * @returns {UseFieldRootPropsReturnValue} The props to forward to the root element of the field.
11
+ */
12
+ export declare function useFieldRootProps(parameters: UseFieldRootPropsParameters): UseFieldRootPropsReturnValue;
13
+ interface UseFieldRootPropsParameters {
14
+ manager: PickerManager<any, any, any, any, any>;
15
+ stateResponse: UseFieldStateReturnValue<any>;
16
+ applyCharacterEditing: UseFieldCharacterEditingReturnValue;
17
+ internalPropsWithDefaults: UseFieldInternalProps<any, any, any>;
18
+ domGetters: UseFieldDOMGetters;
19
+ focused: boolean;
20
+ setFocused: (focused: boolean) => void;
21
+ }
22
+ interface UseFieldRootPropsReturnValue {
23
+ onKeyDown: React.KeyboardEventHandler<HTMLDivElement>;
24
+ onBlur: React.FocusEventHandler<HTMLDivElement>;
25
+ onFocus: React.FocusEventHandler<HTMLDivElement>;
26
+ onClick: React.MouseEventHandler<HTMLDivElement>;
27
+ onPaste: React.ClipboardEventHandler<HTMLDivElement>;
28
+ onInput: React.FormEventHandler<HTMLDivElement>;
29
+ contentEditable: boolean;
30
+ tabIndex: number;
31
+ }
32
+ export {};
@@ -0,0 +1,150 @@
1
+ import useEventCallback from '@mui/utils/useEventCallback';
2
+ import useTimeout from '@mui/utils/useTimeout';
3
+ import { useFieldRootHandleKeyDown } from "./useFieldRootHandleKeyDown.js";
4
+ import { getActiveElement } from "../../utils/utils.js";
5
+ import { syncSelectionToDOM } from "./syncSelectionToDOM.js";
6
+
7
+ /**
8
+ * Generate the props to pass to the root element of the field.
9
+ * It is not used by the non-accessible DOM structure (with an <input /> element for editing).
10
+ * It should be used in the MUI accessible DOM structure and the Base UI implementation.
11
+ * @param {UseFieldRootPropsParameters} parameters The parameters of the hook.
12
+ * @returns {UseFieldRootPropsReturnValue} The props to forward to the root element of the field.
13
+ */
14
+ export function useFieldRootProps(parameters) {
15
+ const {
16
+ manager,
17
+ focused,
18
+ setFocused,
19
+ domGetters,
20
+ stateResponse,
21
+ applyCharacterEditing,
22
+ internalPropsWithDefaults,
23
+ stateResponse: {
24
+ // States and derived states
25
+ parsedSelectedSections,
26
+ sectionOrder,
27
+ state,
28
+ // Methods to update the states
29
+ clearValue,
30
+ setCharacterQuery,
31
+ setSelectedSections,
32
+ updateValueFromValueStr
33
+ },
34
+ internalPropsWithDefaults: {
35
+ readOnly = false
36
+ }
37
+ } = parameters;
38
+
39
+ // TODO: Inline onContainerKeyDown once the old DOM structure is removed
40
+ const handleKeyDown = useFieldRootHandleKeyDown({
41
+ manager,
42
+ internalPropsWithDefaults,
43
+ stateResponse
44
+ });
45
+ const containerClickTimeout = useTimeout();
46
+ const handleClick = useEventCallback(event => {
47
+ if (!domGetters.isReady()) {
48
+ return;
49
+ }
50
+ setFocused(true);
51
+ if (parsedSelectedSections === 'all') {
52
+ containerClickTimeout.start(0, () => {
53
+ const cursorPosition = document.getSelection().getRangeAt(0).startOffset;
54
+ if (cursorPosition === 0) {
55
+ setSelectedSections(sectionOrder.startIndex);
56
+ return;
57
+ }
58
+ let sectionIndex = 0;
59
+ let cursorOnStartOfSection = 0;
60
+ while (cursorOnStartOfSection < cursorPosition && sectionIndex < state.sections.length) {
61
+ const section = state.sections[sectionIndex];
62
+ sectionIndex += 1;
63
+ cursorOnStartOfSection += `${section.startSeparator}${section.value || section.placeholder}${section.endSeparator}`.length;
64
+ }
65
+ setSelectedSections(sectionIndex - 1);
66
+ });
67
+ } else if (!focused) {
68
+ setFocused(true);
69
+ setSelectedSections(sectionOrder.startIndex);
70
+ } else {
71
+ const hasClickedOnASection = domGetters.getRoot().contains(event.target);
72
+ if (!hasClickedOnASection) {
73
+ setSelectedSections(sectionOrder.startIndex);
74
+ }
75
+ }
76
+ });
77
+ const handleInput = useEventCallback(event => {
78
+ if (!domGetters.isReady() || parsedSelectedSections !== 'all') {
79
+ return;
80
+ }
81
+ const target = event.target;
82
+ const keyPressed = target.textContent ?? '';
83
+ domGetters.getRoot().innerHTML = state.sections.map(section => `${section.startSeparator}${section.value || section.placeholder}${section.endSeparator}`).join('');
84
+ syncSelectionToDOM({
85
+ focused,
86
+ domGetters,
87
+ stateResponse
88
+ });
89
+ if (keyPressed.length === 0 || keyPressed.charCodeAt(0) === 10) {
90
+ clearValue();
91
+ setSelectedSections('all');
92
+ } else if (keyPressed.length > 1) {
93
+ updateValueFromValueStr(keyPressed);
94
+ } else {
95
+ if (parsedSelectedSections === 'all') {
96
+ setSelectedSections(0);
97
+ }
98
+ applyCharacterEditing({
99
+ keyPressed,
100
+ sectionIndex: 0
101
+ });
102
+ }
103
+ });
104
+ const handlePaste = useEventCallback(event => {
105
+ if (readOnly || parsedSelectedSections !== 'all') {
106
+ event.preventDefault();
107
+ return;
108
+ }
109
+ const pastedValue = event.clipboardData.getData('text');
110
+ event.preventDefault();
111
+ setCharacterQuery(null);
112
+ updateValueFromValueStr(pastedValue);
113
+ });
114
+ const handleFocus = useEventCallback(() => {
115
+ if (focused || !domGetters.isReady()) {
116
+ return;
117
+ }
118
+ const activeElement = getActiveElement(document);
119
+ setFocused(true);
120
+ const isFocusInsideASection = domGetters.getSectionIndexFromDOMElement(activeElement) != null;
121
+ if (!isFocusInsideASection) {
122
+ setSelectedSections(sectionOrder.startIndex);
123
+ }
124
+ });
125
+ const handleBlur = useEventCallback(() => {
126
+ setTimeout(() => {
127
+ if (!domGetters.isReady()) {
128
+ return;
129
+ }
130
+ const activeElement = getActiveElement(document);
131
+ const shouldBlur = !domGetters.getRoot().contains(activeElement);
132
+ if (shouldBlur) {
133
+ setFocused(false);
134
+ setSelectedSections(null);
135
+ }
136
+ });
137
+ });
138
+ return {
139
+ // Event handlers
140
+ onKeyDown: handleKeyDown,
141
+ onBlur: handleBlur,
142
+ onFocus: handleFocus,
143
+ onClick: handleClick,
144
+ onPaste: handlePaste,
145
+ onInput: handleInput,
146
+ // Other
147
+ contentEditable: parsedSelectedSections === 'all',
148
+ tabIndex: parsedSelectedSections === 0 ? -1 : 0 // TODO: Try to set to undefined when there is a section selected.
149
+ };
150
+ }
@@ -0,0 +1,15 @@
1
+ import * as React from 'react';
2
+ import { UseFieldStateReturnValue } from "./useFieldState.js";
3
+ /**
4
+ * Generate the props to pass to the container element of each section of the field.
5
+ * It is not used by the non-accessible DOM structure (with an <input /> element for editing).
6
+ * It should be used in the MUI accessible DOM structure and the Base UI implementation.
7
+ * @param {UseFieldRootPropsParameters} parameters The parameters of the hook.
8
+ * @returns {UseFieldRootPropsReturnValue} The props to forward to the container element of each section of the field.
9
+ */
10
+ export declare function useFieldSectionContainerProps(parameters: UseFieldSectionContainerPropsParameters): UseFieldSectionContainerPropsReturnValue;
11
+ interface UseFieldSectionContainerPropsParameters {
12
+ stateResponse: UseFieldStateReturnValue<any>;
13
+ }
14
+ type UseFieldSectionContainerPropsReturnValue = (sectionIndex: number) => React.HTMLAttributes<HTMLSpanElement>;
15
+ export {};
@@ -0,0 +1,29 @@
1
+ import * as React from 'react';
2
+ import useEventCallback from '@mui/utils/useEventCallback';
3
+ /**
4
+ * Generate the props to pass to the container element of each section of the field.
5
+ * It is not used by the non-accessible DOM structure (with an <input /> element for editing).
6
+ * It should be used in the MUI accessible DOM structure and the Base UI implementation.
7
+ * @param {UseFieldRootPropsParameters} parameters The parameters of the hook.
8
+ * @returns {UseFieldRootPropsReturnValue} The props to forward to the container element of each section of the field.
9
+ */
10
+ export function useFieldSectionContainerProps(parameters) {
11
+ const {
12
+ stateResponse: {
13
+ // Methods to update the states
14
+ setSelectedSections
15
+ }
16
+ } = parameters;
17
+ const createHandleClick = useEventCallback(sectionIndex => event => {
18
+ // The click event on the clear button would propagate to the input, trigger this handler and result in a wrong section selection.
19
+ // We avoid this by checking if the call to this function is actually intended, or a side effect.
20
+ if (event.isDefaultPrevented()) {
21
+ return;
22
+ }
23
+ setSelectedSections(sectionIndex);
24
+ });
25
+ return React.useCallback(sectionIndex => ({
26
+ 'data-sectionindex': sectionIndex,
27
+ onClick: createHandleClick(sectionIndex)
28
+ }), [createHandleClick]);
29
+ }
@@ -0,0 +1,23 @@
1
+ import * as React from 'react';
2
+ import { UseFieldStateReturnValue } from "./useFieldState.js";
3
+ import { FieldSection, PickerManager } from "../../../models/index.js";
4
+ import { UseFieldDOMGetters, UseFieldInternalProps } from "./useField.types.js";
5
+ import { UseFieldCharacterEditingReturnValue } from "./useFieldCharacterEditing.js";
6
+ /**
7
+ * Generate the props to pass to the content element of each section of the field.
8
+ * It is not used by the non-accessible DOM structure (with an <input /> element for editing).
9
+ * It should be used in the MUI accessible DOM structure and the Base UI implementation.
10
+ * @param {UseFieldRootPropsParameters} parameters The parameters of the hook.
11
+ * @returns {UseFieldRootPropsReturnValue} The props to forward to the content element of each section of the field.
12
+ */
13
+ export declare function useFieldSectionContentProps(parameters: UseFieldSectionContentPropsParameters): UseFieldSectionContentPropsReturnValue;
14
+ interface UseFieldSectionContentPropsParameters {
15
+ manager: PickerManager<any, any, any, any, any>;
16
+ stateResponse: UseFieldStateReturnValue<any>;
17
+ applyCharacterEditing: UseFieldCharacterEditingReturnValue;
18
+ internalPropsWithDefaults: UseFieldInternalProps<any, any, any>;
19
+ domGetters: UseFieldDOMGetters;
20
+ focused: boolean;
21
+ }
22
+ type UseFieldSectionContentPropsReturnValue = (section: FieldSection, sectionIndex: number) => React.HTMLAttributes<HTMLSpanElement>;
23
+ export {};