diff --git a/docs/data/date-pickers/custom-field/BrowserV7MultiInputRangeField.js b/docs/data/date-pickers/custom-field/BrowserV7MultiInputRangeField.js
index 7743be94934f5..60e4a63bdef1d 100644
--- a/docs/data/date-pickers/custom-field/BrowserV7MultiInputRangeField.js
+++ b/docs/data/date-pickers/custom-field/BrowserV7MultiInputRangeField.js
@@ -5,8 +5,10 @@ import { styled } from '@mui/material/styles';
import Stack from '@mui/material/Stack';
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
+import { useSplitFieldProps } from '@mui/x-date-pickers/hooks';
import { DateRangePicker } from '@mui/x-date-pickers-pro/DateRangePicker';
-import { unstable_useMultiInputDateRangeField as useMultiInputDateRangeField } from '@mui/x-date-pickers-pro/MultiInputDateRangeField';
+import { useDateRangeManager } from '@mui/x-date-pickers-pro/managers';
+import { unstable_useMultiInputRangeField as useMultiInputRangeField } from '@mui/x-date-pickers-pro/hooks';
import { Unstable_PickersSectionList as PickersSectionList } from '@mui/x-date-pickers/PickersSectionList';
const BrowserFieldRoot = styled('div', { name: 'BrowserField', slot: 'Root' })({
@@ -78,18 +80,9 @@ const BrowserTextField = React.forwardRef((props, ref) => {
});
const BrowserMultiInputDateRangeField = React.forwardRef((props, ref) => {
- const {
- slotProps,
- readOnly,
- shouldDisableDate,
- minDate,
- maxDate,
- disableFuture,
- disablePast,
- className,
- unstableStartFieldRef,
- unstableEndFieldRef,
- } = props;
+ const manager = useDateRangeManager();
+ const { internalProps, forwardedProps } = useSplitFieldProps(props, 'date');
+ const { slotProps, ownerState, ...otherForwardedProps } = forwardedProps;
const startTextFieldProps = useSlotProps({
elementType: 'input',
@@ -103,48 +96,24 @@ const BrowserMultiInputDateRangeField = React.forwardRef((props, ref) => {
ownerState: { position: 'end' },
});
- const fieldResponse = useMultiInputDateRangeField({
- sharedProps: {
- readOnly,
- shouldDisableDate,
- minDate,
- maxDate,
- disableFuture,
- disablePast,
- enableAccessibleFieldDOMStructure: true,
- },
- startTextFieldProps,
- endTextFieldProps,
- unstableStartFieldRef,
- unstableEndFieldRef,
+ const fieldResponse = useMultiInputRangeField({
+ manager,
+ internalProps,
+ startForwardedProps: startTextFieldProps,
+ endForwardedProps: endTextFieldProps,
});
- const {
- // The multi input range field do not support clearable and onClear
- onClear: onClearStartDate,
- clearable: isStartDateClearable,
- openPickerAriaLabel: openPickerStartDateAriaLabel,
- ...startDateProps
- } = fieldResponse.startDate;
- const {
- // The multi input range field do not support clearable and onClear
- onClear: onClearEndDate,
- clearable: isEndDateClearable,
- openPickerAriaLabel: openPickerEndDateAriaLabel,
- ...endDateProps
- } = fieldResponse.endDate;
-
return (
-
- –
-
+
+ –
+
);
});
diff --git a/docs/data/date-pickers/custom-field/BrowserV7MultiInputRangeField.tsx b/docs/data/date-pickers/custom-field/BrowserV7MultiInputRangeField.tsx
index b5c605dc0ac8f..8cfaa4b356a58 100644
--- a/docs/data/date-pickers/custom-field/BrowserV7MultiInputRangeField.tsx
+++ b/docs/data/date-pickers/custom-field/BrowserV7MultiInputRangeField.tsx
@@ -5,12 +5,14 @@ import { styled } from '@mui/material/styles';
import Stack from '@mui/material/Stack';
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
+import { useSplitFieldProps } from '@mui/x-date-pickers/hooks';
import {
DateRangePicker,
DateRangePickerFieldProps,
DateRangePickerProps,
} from '@mui/x-date-pickers-pro/DateRangePicker';
-import { unstable_useMultiInputDateRangeField as useMultiInputDateRangeField } from '@mui/x-date-pickers-pro/MultiInputDateRangeField';
+import { useDateRangeManager } from '@mui/x-date-pickers-pro/managers';
+import { unstable_useMultiInputRangeField as useMultiInputRangeField } from '@mui/x-date-pickers-pro/hooks';
import { Unstable_PickersSectionList as PickersSectionList } from '@mui/x-date-pickers/PickersSectionList';
import {
MultiInputFieldSlotTextFieldProps,
@@ -118,18 +120,9 @@ type BrowserMultiInputDateRangeFieldComponent = ((
const BrowserMultiInputDateRangeField = React.forwardRef(
(props: BrowserMultiInputDateRangeFieldProps, ref: React.Ref) => {
- const {
- slotProps,
- readOnly,
- shouldDisableDate,
- minDate,
- maxDate,
- disableFuture,
- disablePast,
- className,
- unstableStartFieldRef,
- unstableEndFieldRef,
- } = props;
+ const manager = useDateRangeManager();
+ const { internalProps, forwardedProps } = useSplitFieldProps(props, 'date');
+ const { slotProps, ownerState, ...otherForwardedProps } = forwardedProps;
const startTextFieldProps = useSlotProps({
elementType: 'input',
@@ -143,51 +136,24 @@ const BrowserMultiInputDateRangeField = React.forwardRef(
ownerState: { position: 'end' } as any,
}) as MultiInputFieldSlotTextFieldProps;
- const fieldResponse = useMultiInputDateRangeField<
- true,
- MultiInputFieldSlotTextFieldProps
- >({
- sharedProps: {
- readOnly,
- shouldDisableDate,
- minDate,
- maxDate,
- disableFuture,
- disablePast,
- enableAccessibleFieldDOMStructure: true,
- },
- startTextFieldProps,
- endTextFieldProps,
- unstableStartFieldRef,
- unstableEndFieldRef,
+ const fieldResponse = useMultiInputRangeField({
+ manager,
+ internalProps,
+ startForwardedProps: startTextFieldProps,
+ endForwardedProps: endTextFieldProps,
});
- const {
- // The multi input range field do not support clearable and onClear
- onClear: onClearStartDate,
- clearable: isStartDateClearable,
- openPickerAriaLabel: openPickerStartDateAriaLabel,
- ...startDateProps
- } = fieldResponse.startDate;
- const {
- // The multi input range field do not support clearable and onClear
- onClear: onClearEndDate,
- clearable: isEndDateClearable,
- openPickerAriaLabel: openPickerEndDateAriaLabel,
- ...endDateProps
- } = fieldResponse.endDate;
-
return (
-
- –
-
+
+ –
+
);
},
diff --git a/docs/data/date-pickers/custom-field/JoyV6MultiInputRangeField.js b/docs/data/date-pickers/custom-field/JoyV6MultiInputRangeField.js
index 6adab583bfa13..118af0a126d91 100644
--- a/docs/data/date-pickers/custom-field/JoyV6MultiInputRangeField.js
+++ b/docs/data/date-pickers/custom-field/JoyV6MultiInputRangeField.js
@@ -8,7 +8,6 @@ import useSlotProps from '@mui/utils/useSlotProps';
import {
extendTheme as extendJoyTheme,
useColorScheme,
- styled,
CssVarsProvider,
THEME_ID,
} from '@mui/joy/styles';
@@ -18,9 +17,11 @@ import FormControl from '@mui/joy/FormControl';
import FormLabel from '@mui/joy/FormLabel';
import Typography from '@mui/joy/Typography';
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
+import { useSplitFieldProps } from '@mui/x-date-pickers/hooks';
import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
import { DateRangePicker } from '@mui/x-date-pickers-pro/DateRangePicker';
-import { unstable_useMultiInputDateRangeField as useMultiInputDateRangeField } from '@mui/x-date-pickers-pro/MultiInputDateRangeField';
+import { useDateRangeManager } from '@mui/x-date-pickers-pro/managers';
+import { unstable_useMultiInputRangeField as useMultiInputRangeField } from '@mui/x-date-pickers-pro/hooks';
const joyTheme = extendJoyTheme();
@@ -68,102 +69,47 @@ const JoyField = React.forwardRef((props, ref) => {
);
});
-const MultiInputJoyDateRangeFieldRoot = styled(
- React.forwardRef((props, ref) => (
-
- )),
- {
- name: 'MuiMultiInputDateRangeField',
- slot: 'Root',
- overridesResolver: (props, styles) => styles.root,
- },
-)({});
-
-const MultiInputJoyDateRangeFieldSeparator = styled(
- (props) => (
-
- {/* Ensure that the separator is correctly aligned */}
-
- {props.children ?? ' – '}
-
- ),
- {
- name: 'MuiMultiInputDateRangeField',
- slot: 'Separator',
- overridesResolver: (props, styles) => styles.separator,
- },
-)({ marginTop: '25px' });
-
const JoyMultiInputDateRangeField = React.forwardRef((props, ref) => {
- const {
- slotProps,
- readOnly,
- shouldDisableDate,
- minDate,
- maxDate,
- disableFuture,
- disablePast,
- className,
- unstableStartFieldRef,
- unstableEndFieldRef,
- } = props;
+ const manager = useDateRangeManager({
+ enableAccessibleFieldDOMStructure: false,
+ });
+ const { internalProps, forwardedProps } = useSplitFieldProps(props, 'date');
+ const { slotProps, ownerState, ...otherForwardedProps } = forwardedProps;
const startTextFieldProps = useSlotProps({
- elementType: FormControl,
+ elementType: 'input',
externalSlotProps: slotProps?.textField,
ownerState: { position: 'start' },
});
const endTextFieldProps = useSlotProps({
- elementType: FormControl,
+ elementType: 'input',
externalSlotProps: slotProps?.textField,
ownerState: { position: 'end' },
});
- const fieldResponse = useMultiInputDateRangeField({
- sharedProps: {
- readOnly,
- shouldDisableDate,
- minDate,
- maxDate,
- disableFuture,
- disablePast,
- enableAccessibleFieldDOMStructure: false,
- },
- startTextFieldProps,
- endTextFieldProps,
- unstableStartFieldRef,
- unstableEndFieldRef,
+ const fieldResponse = useMultiInputRangeField({
+ manager,
+ internalProps: { ...internalProps, enableAccessibleFieldDOMStructure: false },
+ startForwardedProps: startTextFieldProps,
+ endForwardedProps: endTextFieldProps,
});
- const {
- // The multi input range field do not support clearable, onClear and openPickerAriaLabel
- onClear: onClearStartDate,
- clearable: isStartDateClearable,
- openPickerAriaLabel: openPickerStartDateAriaLabel,
- ...startDateProps
- } = fieldResponse.startDate;
- const {
- // The multi input range field do not support clearable, onClear and openPickerAriaLabel
- onClear: onClearEndDate,
- clearable: isEndDateClearable,
- openPickerAriaLabel: openPickerEndDateAriaLabel,
- ...endDateProps
- } = fieldResponse.endDate;
-
return (
-
-
-
-
-
+
+
+
+ {' – '}
+
+
+
);
});
diff --git a/docs/data/date-pickers/custom-field/JoyV6MultiInputRangeField.tsx b/docs/data/date-pickers/custom-field/JoyV6MultiInputRangeField.tsx
index 9f5cbc60eff72..3add953616aa4 100644
--- a/docs/data/date-pickers/custom-field/JoyV6MultiInputRangeField.tsx
+++ b/docs/data/date-pickers/custom-field/JoyV6MultiInputRangeField.tsx
@@ -8,23 +8,24 @@ import useSlotProps from '@mui/utils/useSlotProps';
import {
extendTheme as extendJoyTheme,
useColorScheme,
- styled,
CssVarsProvider,
THEME_ID,
} from '@mui/joy/styles';
import Input, { InputProps } from '@mui/joy/Input';
-import Stack, { StackProps } from '@mui/joy/Stack';
+import Stack from '@mui/joy/Stack';
import FormControl from '@mui/joy/FormControl';
import FormLabel from '@mui/joy/FormLabel';
-import Typography, { TypographyProps } from '@mui/joy/Typography';
+import Typography from '@mui/joy/Typography';
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
+import { useSplitFieldProps } from '@mui/x-date-pickers/hooks';
import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
import {
DateRangePicker,
DateRangePickerFieldProps,
DateRangePickerProps,
} from '@mui/x-date-pickers-pro/DateRangePicker';
-import { unstable_useMultiInputDateRangeField as useMultiInputDateRangeField } from '@mui/x-date-pickers-pro/MultiInputDateRangeField';
+import { useDateRangeManager } from '@mui/x-date-pickers-pro/managers';
+import { unstable_useMultiInputRangeField as useMultiInputRangeField } from '@mui/x-date-pickers-pro/hooks';
import {
MultiInputFieldRefs,
MultiInputFieldSlotTextFieldProps,
@@ -94,39 +95,6 @@ const JoyField = React.forwardRef(
},
) as JoyFieldComponent;
-const MultiInputJoyDateRangeFieldRoot = styled(
- React.forwardRef((props: StackProps, ref: React.Ref) => (
-
- )),
- {
- name: 'MuiMultiInputDateRangeField',
- slot: 'Root',
- overridesResolver: (props, styles) => styles.root,
- },
-)({});
-
-const MultiInputJoyDateRangeFieldSeparator = styled(
- (props: TypographyProps) => (
-
- {/* Ensure that the separator is correctly aligned */}
-
- {props.children ?? ' – '}
-
- ),
- {
- name: 'MuiMultiInputDateRangeField',
- slot: 'Separator',
- overridesResolver: (props, styles) => styles.separator,
- },
-)({ marginTop: '25px' });
-
interface JoyMultiInputDateRangeFieldProps
extends Omit<
DateRangePickerFieldProps,
@@ -144,71 +112,46 @@ type JoyMultiInputDateRangeFieldComponent = ((
const JoyMultiInputDateRangeField = React.forwardRef(
(props: JoyMultiInputDateRangeFieldProps, ref: React.Ref) => {
- const {
- slotProps,
- readOnly,
- shouldDisableDate,
- minDate,
- maxDate,
- disableFuture,
- disablePast,
- className,
- unstableStartFieldRef,
- unstableEndFieldRef,
- } = props;
+ const manager = useDateRangeManager({
+ enableAccessibleFieldDOMStructure: false,
+ });
+ const { internalProps, forwardedProps } = useSplitFieldProps(props, 'date');
+ const { slotProps, ownerState, ...otherForwardedProps } = forwardedProps;
const startTextFieldProps = useSlotProps({
- elementType: FormControl,
+ elementType: 'input',
externalSlotProps: slotProps?.textField,
ownerState: { position: 'start' } as any,
}) as MultiInputFieldSlotTextFieldProps;
const endTextFieldProps = useSlotProps({
- elementType: FormControl,
+ elementType: 'input',
externalSlotProps: slotProps?.textField,
ownerState: { position: 'end' } as any,
}) as MultiInputFieldSlotTextFieldProps;
- const fieldResponse = useMultiInputDateRangeField<
- false,
- MultiInputFieldSlotTextFieldProps
- >({
- sharedProps: {
- readOnly,
- shouldDisableDate,
- minDate,
- maxDate,
- disableFuture,
- disablePast,
- enableAccessibleFieldDOMStructure: false,
- },
- startTextFieldProps,
- endTextFieldProps,
- unstableStartFieldRef,
- unstableEndFieldRef,
+ const fieldResponse = useMultiInputRangeField({
+ manager,
+ internalProps: { ...internalProps, enableAccessibleFieldDOMStructure: false },
+ startForwardedProps: startTextFieldProps,
+ endForwardedProps: endTextFieldProps,
});
- const {
- // The multi input range field do not support clearable, onClear and openPickerAriaLabel
- onClear: onClearStartDate,
- clearable: isStartDateClearable,
- openPickerAriaLabel: openPickerStartDateAriaLabel,
- ...startDateProps
- } = fieldResponse.startDate;
- const {
- // The multi input range field do not support clearable, onClear and openPickerAriaLabel
- onClear: onClearEndDate,
- clearable: isEndDateClearable,
- openPickerAriaLabel: openPickerEndDateAriaLabel,
- ...endDateProps
- } = fieldResponse.endDate;
-
return (
-
-
-
-
-
+
+
+
+ {' – '}
+
+
+
);
},
) as JoyMultiInputDateRangeFieldComponent;
diff --git a/docs/data/migration/migration-pickers-v7/migration-pickers-v7.md b/docs/data/migration/migration-pickers-v7/migration-pickers-v7.md
index d8b17b13012ec..d84acfee829ff 100644
--- a/docs/data/migration/migration-pickers-v7/migration-pickers-v7.md
+++ b/docs/data/migration/migration-pickers-v7/migration-pickers-v7.md
@@ -944,6 +944,161 @@ The following variables and types have been renamed to have a coherent `Picker`
## Hooks breaking changes
+### `useMultiInputDateRangeField`
+
+This hook has been removed in favor of the new `useMultiInputRangeField` hook with an improved DX:
+
+```diff
+ import useSlotProps from '@mui/utils/useSlotProps';
+-import { unstable_useMultiInputDateRangeField as useMultiInputDateRangeField } from '@mui/x-date-pickers-pro/MultiInputDateRangeField';
++import { useDateRangeManager } from '@mui/x-date-pickers-pro/managers';
++import { unstable_useMultiInputRangeField as useMultiInputRangeField } from '@mui/x-date-pickers-pro/hooks';
+ import { useSplitFieldProps } from '@mui/x-date-pickers/hooks';
+
+ const DateRangeField(props) {
+ const { internalProps, forwardedProps } = useSplitFieldProps(props, 'date');
+ const { slotProps, slots } = forwardedProps;
+
+ const startTextFieldProps = useSlotProps({
+ elementType: 'input',
+ externalSlotProps: slotProps?.textField,
+ ownerState: { ...props, position: 'start' },
+ });
+
+ const endTextFieldProps = useSlotProps({
+ elementType: 'input',
+ externalSlotProps: slotProps?.textField,
+ ownerState: { ...props, position: 'end' },
+ });
+
+- const fieldResponse = useMultiInputDateRangeField({
+- sharedProps: internalProps,
+- startTextFieldProps,
+- endTextFieldProps,
+- unstableStartFieldRef: internalProps.unstableStartFieldRef,
+- unstableEndFieldRef: internalProps.unstableEndFieldRef,
+- });
+
++ const manager = useDateRangeManager(props);
++ const fieldResponse = useMultiInputRangeField({
++ manager,
++ internalProps,
++ startForwardedProps: startTextFieldProps,
++ endForwardedProps: endTextFieldProps,
++ });
+
+ return ( /** Your UI */ )
+ }
+```
+
+:::success
+The associated types have also been removed. [Learn how to migrate them](/x/migration/migration-pickers-v7/#removed-types).
+:::
+
+### `useMultiInputTimeRangeField`
+
+This hook has been removed in favor of the new `useMultiInputRangeField` hook with an improved DX:
+
+```diff
+ import useSlotProps from '@mui/utils/useSlotProps';
+-import { unstable_useMultiInputTimeRangeField as useMultiInputTimeRangeField } from '@mui/x-date-pickers-pro/MultiInputTimeRangeField';
++import { useTimeRangeManager } from '@mui/x-date-pickers-pro/managers';
++import { unstable_useMultiInputRangeField as useMultiInputRangeField } from '@mui/x-date-pickers-pro/hooks';
+ import { useSplitFieldProps } from '@mui/x-date-pickers/hooks';
+
+ const DateRangeField(props) {
+ const { internalProps, forwardedProps } = useSplitFieldProps(props, 'time');
+ const { slotProps, slots } = forwardedProps;
+
+ const startTextFieldProps = useSlotProps({
+ elementType: 'input',
+ externalSlotProps: slotProps?.textField,
+ ownerState: { ...props, position: 'start' },
+ });
+
+ const endTextFieldProps = useSlotProps({
+ elementType: 'input',
+ externalSlotProps: slotProps?.textField,
+ ownerState: { ...props, position: 'end' },
+ });
+
+
+- const fieldResponse = useMultiInputTimeRangeField({
+- sharedProps: internalProps,
+- startTextFieldProps,
+- endTextFieldProps,
+- unstableStartFieldRef: internalProps.unstableStartFieldRef,
+- unstableEndFieldRef: internalProps.unstableEndFieldRef,
+- });
+
++ const manager = useTimeRangeManager(props);
++ const fieldResponse = useMultiInputRangeField({
++ manager,
++ internalProps,
++ startForwardedProps: startTextFieldProps,
++ endForwardedProps: endTextFieldProps,
++ });
+
+ return ( /** Your UI */ )
+ }
+```
+
+:::success
+The associated types have also been removed. [Learn how to migrate them](/x/migration/migration-pickers-v7/#removed-types).
+:::
+
+### `useMultiInputDateTimeRangeField`
+
+This hook has been removed in favor of the new `useMultiInputRangeField` hook with an improved DX:
+
+```diff
+ import useSlotProps from '@mui/utils/useSlotProps';
+-import { unstable_useMultiInputDateTimeRangeField as useMultiInputDateTimeRangeField } from '@mui/x-date-pickers-pro/MultiInputDateTimeRangeField';
++import { useDateTimeRangeManager } from '@mui/x-date-pickers-pro/managers';
++import { unstable_useMultiInputRangeField as useMultiInputRangeField } from '@mui/x-date-pickers-pro/hooks';
+ import { useSplitFieldProps } from '@mui/x-date-pickers/hooks';
+
+ const DateRangeField(props) {
+ const { internalProps, forwardedProps } = useSplitFieldProps(props, 'date-time');
+ const { slotProps, slots } = forwardedProps;
+
+ const startTextFieldProps = useSlotProps({
+ elementType: 'input',
+ externalSlotProps: slotProps?.textField,
+ ownerState: { ...props, position: 'start' },
+ });
+
+ const endTextFieldProps = useSlotProps({
+ elementType: 'input',
+ externalSlotProps: slotProps?.textField,
+ ownerState: { ...props, position: 'end' },
+ });
+
+
+- const fieldResponse = useMultiInputDateTimeRangeField({
+- sharedProps: internalProps,
+- startTextFieldProps,
+- endTextFieldProps,
+- unstableStartFieldRef: internalProps.unstableStartFieldRef,
+- unstableEndFieldRef: internalProps.unstableEndFieldRef,
+- });
+
++ const manager = useDateTimeRangeManager(props);
++ const fieldResponse = useMultiInputRangeField({
++ manager,
++ internalProps,
++ startForwardedProps: startTextFieldProps,
++ endForwardedProps: endTextFieldProps,
++ });
+
+ return ( /** Your UI */ )
+ }
+```
+
+:::success
+The associated types have also been removed. [Learn how to migrate them](/x/migration/migration-pickers-v7/#removed-types).
+:::
+
### `usePickerContext`
- The `onOpen` and `onClose` methods have been replaced with a single `setOpen` method.
@@ -1088,6 +1243,135 @@ If you were using them, you need to replace them with the following code:
UseDateTimeFieldProps;
```
+- `UseDateRangeFieldProps`
+
+ ```ts
+ import { DateRangeManagerFieldInternalProps } from '@mui/x-date-pickers-pro/managers';
+
+ interface UseDateRangeFieldProps<
+ TEnableAccessibleFieldDOMStructure extends boolean,
+ > extends Omit<
+ DateRangeManagerFieldInternalProps,
+ 'unstableFieldRef'
+ > {}
+ ```
+
+- `UseMultiInputDateRangeFieldProps`
+
+ ```ts
+ import { DateRangeManagerFieldInternalProps } from '@mui/x-date-pickers-pro/managers';
+ import { MultiInputFieldRefs } from '@mui/x-date-pickers-pro/models';
+
+ interface UseMultiInputDateRangeFieldProps<
+ TEnableAccessibleFieldDOMStructure extends boolean,
+ > extends DateRangeManagerFieldInternalProps,
+ MultiInputFieldRefs {}
+ ```
+
+- `UseMultiInputDateRangeFieldComponentProps`
+
+ ```ts
+ import { DateRangeManagerFieldInternalProps } from '@mui/x-date-pickers-pro/managers';
+ import { MultiInputFieldRefs } from '@mui/x-date-pickers-pro/models';
+
+ type UseMultiInputDateRangeFieldComponentProps<
+ TEnableAccessibleFieldDOMStructure extends boolean,
+ TChildProps extends {},
+ > = Omit<
+ TChildProps,
+ | keyof DateRangeManagerFieldInternalProps
+ | keyof MultiInputFieldRefs
+ > &
+ DateRangeManagerFieldInternalProps &
+ MultiInputFieldRefs;
+ ```
+
+- `UseMultiInputTimeRangeFieldProps`
+
+ ```ts
+ import { TimeRangeManagerFieldInternalProps } from '@mui/x-date-pickers-pro/managers';
+ import { MultiInputFieldRefs } from '@mui/x-date-pickers-pro/models';
+
+ interface UseMultiInputTimeRangeFieldProps<
+ TEnableAccessibleFieldDOMStructure extends boolean,
+ > extends TimeRangeManagerFieldInternalProps,
+ MultiInputFieldRefs {}
+ ```
+
+- `UseMultiInputTimeRangeFieldComponentProps`
+
+ ```ts
+ import { TimeRangeManagerFieldInternalProps } from '@mui/x-date-pickers-pro/managers';
+ import { MultiInputFieldRefs } from '@mui/x-date-pickers-pro/models';
+
+ type UseMultiInputTimeRangeFieldComponentProps<
+ TEnableAccessibleFieldDOMStructure extends boolean,
+ TChildProps extends {},
+ > = Omit<
+ TChildProps,
+ | keyof TimeRangeManagerFieldInternalProps
+ | keyof MultiInputFieldRefs
+ > &
+ TimeRangeManagerFieldInternalProps &
+ MultiInputFieldRefs;
+ ```
+
+- `UseMultiInputDateTimeRangeFieldProps`
+
+ ```ts
+ import { DateTimeRangeManagerFieldInternalProps } from '@mui/x-date-pickers-pro/managers';
+ import { MultiInputFieldRefs } from '@mui/x-date-pickers-pro/models';
+
+ interface UseMultiInputDateTimeRangeFieldProps<
+ TEnableAccessibleFieldDOMStructure extends boolean,
+ > extends DateTimeRangeManagerFieldInternalProps,
+ MultiInputFieldRefs {}
+ ```
+
+- `UseMultiInputDateTimeRangeFieldComponentProps`
+
+ ```ts
+ import { DateTimeRangeManagerFieldInternalProps } from '@mui/x-date-pickers-pro/managers';
+ import { MultiInputFieldRefs } from '@mui/x-date-pickers-pro/models';
+
+ type UseMultiInputDateTimeRangeFieldComponentProps<
+ TEnableAccessibleFieldDOMStructure extends boolean,
+ TChildProps extends {},
+ > = Omit<
+ TChildProps,
+ | keyof DateTimeRangeManagerFieldInternalProps
+ | keyof MultiInputFieldRefs
+ > &
+ DateTimeRangeManagerFieldInternalProps &
+ MultiInputFieldRefs;
+ ```
+
+- `MultiInputRangeFieldClasses`
+
+ ```ts
+ // If you were using MultiInputRangeFieldClasses for a date range field.
+ import { MultiInputDateRangeFieldClasses } from '@mui/x-date-pickers-pro/MultiInputDateRangeField';
+
+ // If you were using MultiInputRangeFieldClasses for a time range field.
+ import { MultiInputTimeRangeFieldClasses } from '@mui/x-date-pickers-pro/MultiInputTimeRangeField';
+
+ // If you were using MultiInputRangeFieldClasses for a date time range field.
+ import { MultiInputDateTimeRangeFieldClasses } from '@mui/x-date-pickers-pro/MultiInputDateTimeRangeField';
+ ```
+
+- `MultiInputRangeFieldClassKey`
+
+ ```ts
+ // If you were using MultiInputRangeFieldClassKey for a date range field.
+ import { MultiInputRangeFieldClassKey } from '@mui/x-date-pickers-pro/MultiInputDateRangeField';
+
+ // If you were using MultiInputRangeFieldClassKey for a time range field.
+ import { MultiInputRangeFieldClassKey } from '@mui/x-date-pickers-pro/MultiInputTimeRangeField';
+
+ // If you were using MultiInputRangeFieldClassKey for a date time range field.
+ import { MultiInputRangeFieldClassKey } from '@mui/x-date-pickers-pro/MultiInputDateTimeRangeField';
+ ```
+
- `BaseSingleInputFieldProps`
- If you are building a custom field for a Date Picker:
diff --git a/docs/pages/x/api/date-pickers/multi-input-date-range-field.json b/docs/pages/x/api/date-pickers/multi-input-date-range-field.json
index d9e6f2cbf77d5..94aabd8466a8d 100644
--- a/docs/pages/x/api/date-pickers/multi-input-date-range-field.json
+++ b/docs/pages/x/api/date-pickers/multi-input-date-range-field.json
@@ -1,6 +1,6 @@
{
"props": {
- "autoFocus": { "type": { "name": "bool" } },
+ "autoFocus": { "type": { "name": "bool" }, "default": "false" },
"classes": { "type": { "name": "object" }, "additionalInfo": { "cssApi": true } },
"dateSeparator": { "type": { "name": "string" }, "default": "\"–\"" },
"defaultValue": { "type": { "name": "arrayOf", "description": "Array<object>" } },
@@ -99,20 +99,27 @@
"import { MultiInputDateRangeField } from '@mui/x-date-pickers-pro/MultiInputDateRangeField';",
"import { MultiInputDateRangeField } from '@mui/x-date-pickers-pro';"
],
- "classes": [
+ "slots": [
{
- "key": "root",
- "className": "MuiMultiInputDateRangeField-root",
- "description": "Styles applied to the root element.",
- "isGlobal": false
+ "name": "root",
+ "description": "Element rendered at the root.",
+ "default": "MultiInputRangeFieldRoot",
+ "class": "MuiMultiInputDateRangeField-root"
},
{
- "key": "separator",
- "className": "MuiMultiInputDateRangeField-separator",
- "description": "Styles applied to the separator element.",
- "isGlobal": false
+ "name": "separator",
+ "description": "Element rendered between the two inputs.",
+ "default": "MultiInputRangeFieldSeparator",
+ "class": "MuiMultiInputDateRangeField-separator"
+ },
+ {
+ "name": "textField",
+ "description": "Form control with an input to render a date.\nIt is rendered twice: once for the start date and once for the end date.",
+ "default": ", or from '@mui/material' if `enableAccessibleFieldDOMStructure` is `false`.",
+ "class": null
}
],
+ "classes": [],
"spread": true,
"themeDefaultProps": true,
"muiName": "MuiMultiInputDateRangeField",
diff --git a/docs/pages/x/api/date-pickers/multi-input-date-time-range-field.json b/docs/pages/x/api/date-pickers/multi-input-date-time-range-field.json
index 783e9b93b4674..4bafe16e5ecab 100644
--- a/docs/pages/x/api/date-pickers/multi-input-date-time-range-field.json
+++ b/docs/pages/x/api/date-pickers/multi-input-date-time-range-field.json
@@ -1,7 +1,7 @@
{
"props": {
"ampm": { "type": { "name": "bool" }, "default": "utils.is12HourCycleInCurrentLocale()" },
- "autoFocus": { "type": { "name": "bool" } },
+ "autoFocus": { "type": { "name": "bool" }, "default": "false" },
"classes": { "type": { "name": "object" }, "additionalInfo": { "cssApi": true } },
"dateSeparator": { "type": { "name": "string" }, "default": "\"–\"" },
"defaultValue": { "type": { "name": "arrayOf", "description": "Array<object>" } },
@@ -114,20 +114,27 @@
"import { MultiInputDateTimeRangeField } from '@mui/x-date-pickers-pro/MultiInputDateTimeRangeField';",
"import { MultiInputDateTimeRangeField } from '@mui/x-date-pickers-pro';"
],
- "classes": [
+ "slots": [
{
- "key": "root",
- "className": "MuiMultiInputDateTimeRangeField-root",
- "description": "Styles applied to the root element.",
- "isGlobal": false
+ "name": "root",
+ "description": "Element rendered at the root.",
+ "default": "MultiInputRangeFieldRoot",
+ "class": "MuiMultiInputDateTimeRangeField-root"
},
{
- "key": "separator",
- "className": "MuiMultiInputDateTimeRangeField-separator",
- "description": "Styles applied to the separator element.",
- "isGlobal": false
+ "name": "separator",
+ "description": "Element rendered between the two inputs.",
+ "default": "MultiInputRangeFieldSeparator",
+ "class": "MuiMultiInputDateTimeRangeField-separator"
+ },
+ {
+ "name": "textField",
+ "description": "Form control with an input to render a date.\nIt is rendered twice: once for the start date and once for the end date.",
+ "default": ", or from '@mui/material' if `enableAccessibleFieldDOMStructure` is `false`.",
+ "class": null
}
],
+ "classes": [],
"spread": true,
"themeDefaultProps": true,
"muiName": "MuiMultiInputDateTimeRangeField",
diff --git a/docs/pages/x/api/date-pickers/multi-input-time-range-field.json b/docs/pages/x/api/date-pickers/multi-input-time-range-field.json
index 120e10742bd03..46e2ae2b0931a 100644
--- a/docs/pages/x/api/date-pickers/multi-input-time-range-field.json
+++ b/docs/pages/x/api/date-pickers/multi-input-time-range-field.json
@@ -1,7 +1,7 @@
{
"props": {
"ampm": { "type": { "name": "bool" }, "default": "utils.is12HourCycleInCurrentLocale()" },
- "autoFocus": { "type": { "name": "bool" } },
+ "autoFocus": { "type": { "name": "bool" }, "default": "false" },
"classes": { "type": { "name": "object" }, "additionalInfo": { "cssApi": true } },
"dateSeparator": { "type": { "name": "string" }, "default": "\"–\"" },
"defaultValue": { "type": { "name": "arrayOf", "description": "Array<object>" } },
@@ -102,20 +102,27 @@
"import { MultiInputTimeRangeField } from '@mui/x-date-pickers-pro/MultiInputTimeRangeField';",
"import { MultiInputTimeRangeField } from '@mui/x-date-pickers-pro';"
],
- "classes": [
+ "slots": [
{
- "key": "root",
- "className": "MuiMultiInputTimeRangeField-root",
- "description": "Styles applied to the root element.",
- "isGlobal": false
+ "name": "root",
+ "description": "Element rendered at the root.",
+ "default": "MultiInputRangeFieldRoot",
+ "class": "MuiMultiInputTimeRangeField-root"
},
{
- "key": "separator",
- "className": "MuiMultiInputTimeRangeField-separator",
- "description": "Styles applied to the separator element.",
- "isGlobal": false
+ "name": "separator",
+ "description": "Element rendered between the two inputs.",
+ "default": "MultiInputRangeFieldSeparator",
+ "class": "MuiMultiInputTimeRangeField-separator"
+ },
+ {
+ "name": "textField",
+ "description": "Form control with an input to render a date.\nIt is rendered twice: once for the start date and once for the end date.",
+ "default": ", or from '@mui/material' if `enableAccessibleFieldDOMStructure` is `false`.",
+ "class": null
}
],
+ "classes": [],
"spread": true,
"themeDefaultProps": true,
"muiName": "MuiMultiInputTimeRangeField",
diff --git a/docs/scripts/generateProptypes.ts b/docs/scripts/generateProptypes.ts
index d45ba1f6af788..f8e9440a4ab03 100644
--- a/docs/scripts/generateProptypes.ts
+++ b/docs/scripts/generateProptypes.ts
@@ -76,6 +76,7 @@ async function generateProptypes(project: XTypeScriptProject, sourceFile: string
'rightAxis',
'plugins',
'seriesConfig',
+ 'manager',
];
if (propsToNotResolve.includes(name)) {
return false;
diff --git a/docs/translations/api-docs/date-pickers/multi-input-date-range-field/multi-input-date-range-field.json b/docs/translations/api-docs/date-pickers/multi-input-date-range-field/multi-input-date-range-field.json
index 40cc9e7558110..e9da20d620141 100644
--- a/docs/translations/api-docs/date-pickers/multi-input-date-range-field/multi-input-date-range-field.json
+++ b/docs/translations/api-docs/date-pickers/multi-input-date-range-field/multi-input-date-range-field.json
@@ -81,11 +81,10 @@
},
"value": { "description": "The selected value. Used when the component is controlled." }
},
- "classDescriptions": {
- "root": { "description": "Styles applied to the root element." },
- "separator": {
- "description": "Styles applied to {{nodeName}}.",
- "nodeName": "the separator element"
- }
+ "classDescriptions": {},
+ "slotDescriptions": {
+ "root": "Element rendered at the root.",
+ "separator": "Element rendered between the two inputs.",
+ "textField": "Form control with an input to render a date. It is rendered twice: once for the start date and once for the end date."
}
}
diff --git a/docs/translations/api-docs/date-pickers/multi-input-date-time-range-field/multi-input-date-time-range-field.json b/docs/translations/api-docs/date-pickers/multi-input-date-time-range-field/multi-input-date-time-range-field.json
index 161927c19e224..02085db56e97a 100644
--- a/docs/translations/api-docs/date-pickers/multi-input-date-time-range-field/multi-input-date-time-range-field.json
+++ b/docs/translations/api-docs/date-pickers/multi-input-date-time-range-field/multi-input-date-time-range-field.json
@@ -106,11 +106,10 @@
},
"value": { "description": "The selected value. Used when the component is controlled." }
},
- "classDescriptions": {
- "root": { "description": "Styles applied to the root element." },
- "separator": {
- "description": "Styles applied to {{nodeName}}.",
- "nodeName": "the separator element"
- }
+ "classDescriptions": {},
+ "slotDescriptions": {
+ "root": "Element rendered at the root.",
+ "separator": "Element rendered between the two inputs.",
+ "textField": "Form control with an input to render a date. It is rendered twice: once for the start date and once for the end date."
}
}
diff --git a/docs/translations/api-docs/date-pickers/multi-input-time-range-field/multi-input-time-range-field.json b/docs/translations/api-docs/date-pickers/multi-input-time-range-field/multi-input-time-range-field.json
index 107711c75d708..896550c640a83 100644
--- a/docs/translations/api-docs/date-pickers/multi-input-time-range-field/multi-input-time-range-field.json
+++ b/docs/translations/api-docs/date-pickers/multi-input-time-range-field/multi-input-time-range-field.json
@@ -76,7 +76,7 @@
"description": "If true
, the format will respect the leading zeroes (for example on dayjs, the format M/D/YYYY
will render 8/16/2018
) If false
, the format will always add leading zeroes (for example on dayjs, the format M/D/YYYY
will render 08/16/2018
)
Warning n°1: Luxon is not able to respect the leading zeroes when using macro tokens (for example "DD"), so shouldRespectLeadingZeros={true}
might lead to inconsistencies when using AdapterLuxon
.
Warning n°2: When shouldRespectLeadingZeros={true}
, the field will add an invisible character on the sections containing a single digit to make sure onChange
is fired. If you need to get the clean value from the input, you can remove this character using input.value.replace(/\\u200e/g, '')
.
Warning n°3: When used in strict mode, dayjs and moment require to respect the leading zeros. This mean that when using shouldRespectLeadingZeros={false}
, if you retrieve the value directly from the input (not listening to onChange
) and your format contains tokens without leading zeros, the value will not be parsed by your library."
},
"slotProps": { "description": "The props used for each component slot." },
- "slots": { "description": "Overridable slots." },
+ "slots": { "description": "Overridable component slots." },
"spacing": { "description": "Defines the space between immediate children." },
"sx": {
"description": "The system prop, which allows defining system overrides as well as additional CSS styles."
@@ -90,11 +90,10 @@
},
"value": { "description": "The selected value. Used when the component is controlled." }
},
- "classDescriptions": {
- "root": { "description": "Styles applied to the root element." },
- "separator": {
- "description": "Styles applied to {{nodeName}}.",
- "nodeName": "the separator element"
- }
+ "classDescriptions": {},
+ "slotDescriptions": {
+ "root": "Element rendered at the root.",
+ "separator": "Element rendered between the two inputs.",
+ "textField": "Form control with an input to render a date. It is rendered twice: once for the start date and once for the end date."
}
}
diff --git a/packages/x-date-pickers-pro/src/MultiInputDateRangeField/MultiInputDateRangeField.tsx b/packages/x-date-pickers-pro/src/MultiInputDateRangeField/MultiInputDateRangeField.tsx
index 6d58b8a4bb59b..706ab5665adca 100644
--- a/packages/x-date-pickers-pro/src/MultiInputDateRangeField/MultiInputDateRangeField.tsx
+++ b/packages/x-date-pickers-pro/src/MultiInputDateRangeField/MultiInputDateRangeField.tsx
@@ -1,62 +1,27 @@
'use client';
import * as React from 'react';
import PropTypes from 'prop-types';
-import clsx from 'clsx';
-import Stack, { StackProps } from '@mui/material/Stack';
-import MuiTextField from '@mui/material/TextField';
-import Typography from '@mui/material/Typography';
-import { styled, useThemeProps } from '@mui/material/styles';
-import useSlotProps from '@mui/utils/useSlotProps';
+import { useDateRangeManager, UseDateRangeManagerReturnValue } from '../managers';
import {
- unstable_composeClasses as composeClasses,
- unstable_generateUtilityClass as generateUtilityClass,
- unstable_generateUtilityClasses as generateUtilityClasses,
-} from '@mui/utils';
-import { cleanFieldResponse, useFieldOwnerState } from '@mui/x-date-pickers/internals';
-import { useSplitFieldProps } from '@mui/x-date-pickers/hooks';
-import { PickersTextField } from '@mui/x-date-pickers/PickersTextField';
+ // The alias is needed to have the doc gen working.
+ createMultiInputRangeField as createMultiInputDateRangeField,
+ MultiInputRangeFieldProps,
+} from '../internals/utils/createMultiInputRangeField';
import {
- MultiInputDateRangeFieldProps,
- MultiInputDateRangeFieldSlotProps,
-} from './MultiInputDateRangeField.types';
-import { useMultiInputDateRangeField } from '../internals/hooks/useMultiInputRangeField/useMultiInputDateRangeField';
-import { MultiInputRangeFieldClasses, RangePosition } from '../models';
+ getMultiInputDateRangeFieldUtilityClass,
+ MultiInputDateRangeFieldClasses,
+} from './multiInputDateRangeFieldClasses';
-export const multiInputDateRangeFieldClasses: MultiInputRangeFieldClasses = generateUtilityClasses(
- 'MuiMultiInputDateRangeField',
- ['root', 'separator'],
-);
-
-export const getMultiInputDateRangeFieldUtilityClass = (slot: string) =>
- generateUtilityClass('MuiMultiInputDateRangeField', slot);
-
-const useUtilityClasses = (classes: Partial | undefined) => {
- const slots = {
- root: ['root'],
- separator: ['separator'],
- };
-
- return composeClasses(slots, getMultiInputDateRangeFieldUtilityClass, classes);
-};
-
-const MultiInputDateRangeFieldRoot = styled(
- React.forwardRef((props: StackProps, ref: React.Ref) => (
-
- )),
- {
- name: 'MuiMultiInputDateRangeField',
- slot: 'Root',
- overridesResolver: (props, styles) => styles.root,
- },
-)({});
-
-const MultiInputDateRangeFieldSeparator = styled(Typography, {
- name: 'MuiMultiInputDateRangeField',
- slot: 'Separator',
- overridesResolver: (props, styles) => styles.separator,
-})({
- lineHeight: '1.4375em', // 23px
-});
+export interface MultiInputDateRangeFieldProps
+ extends MultiInputRangeFieldProps<
+ UseDateRangeManagerReturnValue
+ > {
+ // We need to redefine the classes here, otherwise we don't have the doc generation.
+ /**
+ * Override or extend the styles applied to the component.
+ */
+ classes?: Partial;
+}
type MultiInputDateRangeFieldComponent = (<
TEnableAccessibleFieldDOMStructure extends boolean = true,
@@ -75,107 +40,10 @@ type MultiInputDateRangeFieldComponent = (<
*
* - [MultiInputDateRangeField API](https://mui.com/x/api/multi-input-date-range-field/)
*/
-const MultiInputDateRangeField = React.forwardRef(function MultiInputDateRangeField<
- TEnableAccessibleFieldDOMStructure extends boolean = true,
->(
- inProps: MultiInputDateRangeFieldProps,
- ref: React.Ref,
-) {
- const themeProps = useThemeProps({
- props: inProps,
- name: 'MuiMultiInputDateRangeField',
- });
-
- const { internalProps, forwardedProps } = useSplitFieldProps(themeProps, 'date');
-
- const {
- slots,
- slotProps,
- unstableStartFieldRef,
- unstableEndFieldRef,
- className,
- classes: classesProp,
- ...otherForwardedProps
- } = forwardedProps;
-
- const ownerState = useFieldOwnerState(internalProps);
- const classes = useUtilityClasses(classesProp);
-
- const Root = slots?.root ?? MultiInputDateRangeFieldRoot;
- const rootProps = useSlotProps({
- elementType: Root,
- externalSlotProps: slotProps?.root,
- externalForwardedProps: otherForwardedProps,
- additionalProps: {
- ref,
- },
- ownerState,
- className: clsx(className, classes.root),
- });
-
- const startTextFieldProps = useSlotProps<
- typeof PickersTextField,
- MultiInputDateRangeFieldSlotProps['textField'],
- {},
- MultiInputDateRangeFieldProps & {
- position: RangePosition;
- }
- >({
- elementType: PickersTextField,
- externalSlotProps: slotProps?.textField,
- ownerState: { ...ownerState, position: 'start' },
- });
- const endTextFieldProps = useSlotProps<
- typeof PickersTextField,
- MultiInputDateRangeFieldSlotProps['textField'],
- {},
- MultiInputDateRangeFieldProps & {
- position: RangePosition;
- }
- >({
- elementType: PickersTextField,
- externalSlotProps: slotProps?.textField,
- ownerState: { ...ownerState, position: 'end' },
- });
-
- const Separator = slots?.separator ?? MultiInputDateRangeFieldSeparator;
- const separatorProps = useSlotProps({
- elementType: Separator,
- externalSlotProps: slotProps?.separator,
- additionalProps: {
- children: ` ${internalProps.dateSeparator ?? '–'} `,
- },
- ownerState,
- className: classes.separator,
- });
-
- const fieldResponse = useMultiInputDateRangeField<
- TEnableAccessibleFieldDOMStructure,
- typeof startTextFieldProps
- >({
- sharedProps: internalProps,
- startTextFieldProps,
- endTextFieldProps,
- unstableStartFieldRef,
- unstableEndFieldRef,
- });
-
- const { textFieldProps: startDateProps } = cleanFieldResponse(fieldResponse.startDate);
- const { textFieldProps: endDateProps } = cleanFieldResponse(fieldResponse.endDate);
-
- const TextField =
- slots?.textField ??
- (fieldResponse.startDate.enableAccessibleFieldDOMStructure === false
- ? MuiTextField
- : PickersTextField);
-
- return (
-
-
-
-
-
- );
+const MultiInputDateRangeField = createMultiInputDateRangeField({
+ name: 'MuiMultiInputDateRangeField',
+ getUtilityClass: getMultiInputDateRangeFieldUtilityClass,
+ useManager: useDateRangeManager,
}) as MultiInputDateRangeFieldComponent;
MultiInputDateRangeField.propTypes = {
@@ -185,6 +53,7 @@ MultiInputDateRangeField.propTypes = {
// ----------------------------------------------------------------------
/**
* If `true`, the `input` element is focused during the first mount.
+ * @default false
*/
autoFocus: PropTypes.bool,
/**
diff --git a/packages/x-date-pickers-pro/src/MultiInputDateRangeField/MultiInputDateRangeField.types.ts b/packages/x-date-pickers-pro/src/MultiInputDateRangeField/MultiInputDateRangeField.types.ts
deleted file mode 100644
index 6565d64012de7..0000000000000
--- a/packages/x-date-pickers-pro/src/MultiInputDateRangeField/MultiInputDateRangeField.types.ts
+++ /dev/null
@@ -1,90 +0,0 @@
-import * as React from 'react';
-import type { TypographyProps } from '@mui/material/Typography';
-import type { StackProps } from '@mui/material/Stack';
-import type { TextFieldProps } from '@mui/material/TextField';
-import { FieldOwnerState } from '@mui/x-date-pickers/models';
-import { SlotComponentPropsFromProps } from '@mui/x-internals/types';
-import { PickersTextFieldProps } from '@mui/x-date-pickers/PickersTextField';
-import { UseMultiInputRangeFieldParams } from '../internals/hooks/useMultiInputRangeField/useMultiInputRangeField.types';
-import {
- MultiInputFieldRefs,
- MultiInputRangeFieldClasses,
- RangePosition,
- UseDateRangeFieldProps,
-} from '../models';
-
-export type UseMultiInputDateRangeFieldParams<
- TEnableAccessibleFieldDOMStructure extends boolean,
- TTextFieldSlotProps extends {},
-> = UseMultiInputRangeFieldParams<
- UseMultiInputDateRangeFieldProps,
- TTextFieldSlotProps
->;
-
-export interface UseMultiInputDateRangeFieldProps<
- TEnableAccessibleFieldDOMStructure extends boolean,
-> extends Omit<
- UseDateRangeFieldProps,
- 'unstableFieldRef' | 'clearable' | 'onClear'
- >,
- MultiInputFieldRefs {}
-
-export type UseMultiInputDateRangeFieldComponentProps<
- TEnableAccessibleFieldDOMStructure extends boolean,
- TChildProps extends {},
-> = Omit> &
- UseMultiInputDateRangeFieldProps;
-
-export interface MultiInputDateRangeFieldProps<
- TEnableAccessibleFieldDOMStructure extends boolean = true,
-> extends UseMultiInputDateRangeFieldComponentProps<
- TEnableAccessibleFieldDOMStructure,
- Omit
- > {
- autoFocus?: boolean;
- /**
- * Override or extend the styles applied to the component.
- */
- classes?: Partial;
- /**
- * Overridable component slots.
- * @default {}
- */
- slots?: MultiInputDateRangeFieldSlots;
- /**
- * The props used for each component slot.
- * @default {}
- */
- slotProps?: MultiInputDateRangeFieldSlotProps;
-}
-
-export interface MultiInputDateRangeFieldSlots {
- /**
- * Element rendered at the root.
- * @default MultiInputDateRangeFieldRoot
- */
- root?: React.ElementType;
- /**
- * Form control with an input to render a date.
- * It is rendered twice: once for the start date and once for the end date.
- * @default , or from '@mui/material' if `enableAccessibleFieldDOMStructure` is `false`.
- */
- textField?: React.ElementType;
- /**
- * Element rendered between the two inputs.
- * @default MultiInputDateRangeFieldSeparator
- */
- separator?: React.ElementType;
-}
-
-export interface MultiInputDateRangeFieldSlotProps {
- root?: SlotComponentPropsFromProps;
- textField?: SlotComponentPropsFromProps<
- PickersTextFieldProps | TextFieldProps,
- {},
- FieldOwnerState & {
- position: RangePosition;
- }
- >;
- separator?: SlotComponentPropsFromProps;
-}
diff --git a/packages/x-date-pickers-pro/src/MultiInputDateRangeField/index.ts b/packages/x-date-pickers-pro/src/MultiInputDateRangeField/index.ts
index ac481ccd21139..28ae5b71ccc12 100644
--- a/packages/x-date-pickers-pro/src/MultiInputDateRangeField/index.ts
+++ b/packages/x-date-pickers-pro/src/MultiInputDateRangeField/index.ts
@@ -1,11 +1,16 @@
+export { MultiInputDateRangeField } from './MultiInputDateRangeField';
+export type { MultiInputDateRangeFieldProps } from './MultiInputDateRangeField';
+
export {
- MultiInputDateRangeField,
- getMultiInputDateRangeFieldUtilityClass,
multiInputDateRangeFieldClasses,
-} from './MultiInputDateRangeField';
-export { useMultiInputDateRangeField as unstable_useMultiInputDateRangeField } from '../internals/hooks/useMultiInputRangeField/useMultiInputDateRangeField';
+ getMultiInputDateRangeFieldUtilityClass,
+} from './multiInputDateRangeFieldClasses';
+export type {
+ MultiInputDateRangeFieldClassKey,
+ MultiInputDateRangeFieldClasses,
+} from './multiInputDateRangeFieldClasses';
+
export type {
- UseMultiInputDateRangeFieldProps,
- UseMultiInputDateRangeFieldComponentProps,
- MultiInputDateRangeFieldProps,
-} from './MultiInputDateRangeField.types';
+ MultiInputRangeFieldSlots as MultiInputDateRangeFieldSlots,
+ MultiInputRangeFieldSlotProps as MultiInputDateRangeFieldSlotProps,
+} from '../internals/utils/createMultiInputRangeField';
diff --git a/packages/x-date-pickers-pro/src/MultiInputDateRangeField/multiInputDateRangeFieldClasses.ts b/packages/x-date-pickers-pro/src/MultiInputDateRangeField/multiInputDateRangeFieldClasses.ts
new file mode 100644
index 0000000000000..8fe3e372bb87c
--- /dev/null
+++ b/packages/x-date-pickers-pro/src/MultiInputDateRangeField/multiInputDateRangeFieldClasses.ts
@@ -0,0 +1,15 @@
+import generateUtilityClass from '@mui/utils/generateUtilityClass';
+import generateUtilityClasses from '@mui/utils/generateUtilityClasses';
+import { MultiInputRangeFieldClasses } from '../internals/utils/createMultiInputRangeField';
+
+export interface MultiInputDateRangeFieldClasses extends MultiInputRangeFieldClasses {}
+
+export type MultiInputDateRangeFieldClassKey = keyof MultiInputRangeFieldClasses;
+
+export const multiInputDateRangeFieldClasses: MultiInputRangeFieldClasses = generateUtilityClasses(
+ 'MuiMultiInputDateRangeField',
+ ['root', 'separator'],
+);
+
+export const getMultiInputDateRangeFieldUtilityClass = (slot: string) =>
+ generateUtilityClass('MuiMultiInputDateRangeField', slot);
diff --git a/packages/x-date-pickers-pro/src/MultiInputDateTimeRangeField/MultiInputDateTimeRangeField.tsx b/packages/x-date-pickers-pro/src/MultiInputDateTimeRangeField/MultiInputDateTimeRangeField.tsx
index d74e569613ef4..e524f8e4fbf02 100644
--- a/packages/x-date-pickers-pro/src/MultiInputDateTimeRangeField/MultiInputDateTimeRangeField.tsx
+++ b/packages/x-date-pickers-pro/src/MultiInputDateTimeRangeField/MultiInputDateTimeRangeField.tsx
@@ -1,60 +1,28 @@
'use client';
import * as React from 'react';
import PropTypes from 'prop-types';
-import clsx from 'clsx';
-import Stack, { StackProps } from '@mui/material/Stack';
-import MuiTextField from '@mui/material/TextField';
-import Typography from '@mui/material/Typography';
-import { styled, useThemeProps } from '@mui/material/styles';
-import useSlotProps from '@mui/utils/useSlotProps';
+import { useDateTimeRangeManager, UseDateTimeRangeManagerReturnValue } from '../managers';
import {
- unstable_composeClasses as composeClasses,
- unstable_generateUtilityClass as generateUtilityClass,
- unstable_generateUtilityClasses as generateUtilityClasses,
-} from '@mui/utils';
-import { cleanFieldResponse, useFieldOwnerState } from '@mui/x-date-pickers/internals';
-import { useSplitFieldProps } from '@mui/x-date-pickers/hooks';
-import { PickersTextField } from '@mui/x-date-pickers/PickersTextField';
+ // The alias is needed to have the doc gen working.
+ createMultiInputRangeField as createMultiInputDateTimeRangeField,
+ MultiInputRangeFieldProps,
+} from '../internals/utils/createMultiInputRangeField';
import {
- MultiInputDateTimeRangeFieldProps,
- MultiInputDateTimeRangeFieldSlotProps,
-} from './MultiInputDateTimeRangeField.types';
-import { useMultiInputDateTimeRangeField } from '../internals/hooks/useMultiInputRangeField/useMultiInputDateTimeRangeField';
-import { MultiInputRangeFieldClasses, RangePosition } from '../models';
+ getMultiInputDateTimeRangeFieldUtilityClass,
+ MultiInputDateTimeRangeFieldClasses,
+} from './multiInputDateTimeRangeFieldClasses';
-export const multiInputDateTimeRangeFieldClasses: MultiInputRangeFieldClasses =
- generateUtilityClasses('MuiMultiInputDateTimeRangeField', ['root', 'separator']);
-
-export const getMultiInputDateTimeRangeFieldUtilityClass = (slot: string) =>
- generateUtilityClass('MuiMultiInputDateTimeRangeField', slot);
-
-const useUtilityClasses = (classes: Partial | undefined) => {
- const slots = {
- root: ['root'],
- separator: ['separator'],
- };
-
- return composeClasses(slots, getMultiInputDateTimeRangeFieldUtilityClass, classes);
-};
-
-const MultiInputDateTimeRangeFieldRoot = styled(
- React.forwardRef((props: StackProps, ref: React.Ref) => (
-
- )),
- {
- name: 'MuiMultiInputDateTimeRangeField',
- slot: 'Root',
- overridesResolver: (props, styles) => styles.root,
- },
-)({});
-
-const MultiInputDateTimeRangeFieldSeparator = styled(Typography, {
- name: 'MuiMultiInputDateTimeRangeField',
- slot: 'Separator',
- overridesResolver: (props, styles) => styles.separator,
-})({
- lineHeight: '1.4375em', // 23px
-});
+export interface MultiInputDateTimeRangeFieldProps<
+ TEnableAccessibleFieldDOMStructure extends boolean,
+> extends MultiInputRangeFieldProps<
+ UseDateTimeRangeManagerReturnValue
+ > {
+ // We need to redefine the classes here, otherwise we don't have the doc generation.
+ /**
+ * Override or extend the styles applied to the component.
+ */
+ classes?: Partial;
+}
type MultiInputDateTimeRangeFieldComponent = (<
TEnableAccessibleFieldDOMStructure extends boolean = true,
@@ -73,107 +41,10 @@ type MultiInputDateTimeRangeFieldComponent = (<
*
* - [MultiInputDateTimeRangeField API](https://mui.com/x/api/multi-input-date-time-range-field/)
*/
-const MultiInputDateTimeRangeField = React.forwardRef(function MultiInputDateTimeRangeField<
- TEnableAccessibleFieldDOMStructure extends boolean = true,
->(
- inProps: MultiInputDateTimeRangeFieldProps,
- ref: React.Ref,
-) {
- const themeProps = useThemeProps({
- props: inProps,
- name: 'MuiMultiInputDateTimeRangeField',
- });
-
- const { internalProps, forwardedProps } = useSplitFieldProps(themeProps, 'date-time');
-
- const {
- slots,
- slotProps,
- unstableStartFieldRef,
- unstableEndFieldRef,
- className,
- classes: classesProp,
- ...otherForwardedProps
- } = forwardedProps;
-
- const ownerState = useFieldOwnerState(themeProps);
- const classes = useUtilityClasses(classesProp);
-
- const Root = slots?.root ?? MultiInputDateTimeRangeFieldRoot;
- const rootProps = useSlotProps({
- elementType: Root,
- externalSlotProps: slotProps?.root,
- externalForwardedProps: otherForwardedProps,
- additionalProps: {
- ref,
- },
- ownerState,
- className: clsx(className, classes.root),
- });
-
- const startTextFieldProps = useSlotProps<
- typeof PickersTextField,
- MultiInputDateTimeRangeFieldSlotProps['textField'],
- {},
- MultiInputDateTimeRangeFieldProps & {
- position: RangePosition;
- }
- >({
- elementType: PickersTextField,
- externalSlotProps: slotProps?.textField,
- ownerState: { ...ownerState, position: 'start' },
- });
- const endTextFieldProps = useSlotProps<
- typeof PickersTextField,
- MultiInputDateTimeRangeFieldSlotProps['textField'],
- {},
- MultiInputDateTimeRangeFieldProps & {
- position: RangePosition;
- }
- >({
- elementType: PickersTextField,
- externalSlotProps: slotProps?.textField,
- ownerState: { ...ownerState, position: 'end' },
- });
-
- const Separator = slots?.separator ?? MultiInputDateTimeRangeFieldSeparator;
- const separatorProps = useSlotProps({
- elementType: Separator,
- externalSlotProps: slotProps?.separator,
- additionalProps: {
- children: ` ${internalProps.dateSeparator ?? '–'} `,
- },
- ownerState,
- className: classes.separator,
- });
-
- const fieldResponse = useMultiInputDateTimeRangeField<
- TEnableAccessibleFieldDOMStructure,
- typeof startTextFieldProps
- >({
- sharedProps: internalProps,
- startTextFieldProps,
- endTextFieldProps,
- unstableStartFieldRef,
- unstableEndFieldRef,
- });
-
- const { textFieldProps: startDateProps } = cleanFieldResponse(fieldResponse.startDate);
- const { textFieldProps: endDateProps } = cleanFieldResponse(fieldResponse.endDate);
-
- const TextField =
- slots?.textField ??
- (fieldResponse.startDate.enableAccessibleFieldDOMStructure === false
- ? MuiTextField
- : PickersTextField);
-
- return (
-
-
-
-
-
- );
+const MultiInputDateTimeRangeField = createMultiInputDateTimeRangeField({
+ name: 'MuiMultiInputDateTimeRangeField',
+ getUtilityClass: getMultiInputDateTimeRangeFieldUtilityClass,
+ useManager: useDateTimeRangeManager,
}) as MultiInputDateTimeRangeFieldComponent;
MultiInputDateTimeRangeField.propTypes = {
@@ -188,6 +59,7 @@ MultiInputDateTimeRangeField.propTypes = {
ampm: PropTypes.bool,
/**
* If `true`, the `input` element is focused during the first mount.
+ * @default false
*/
autoFocus: PropTypes.bool,
/**
diff --git a/packages/x-date-pickers-pro/src/MultiInputDateTimeRangeField/MultiInputDateTimeRangeField.types.ts b/packages/x-date-pickers-pro/src/MultiInputDateTimeRangeField/MultiInputDateTimeRangeField.types.ts
deleted file mode 100644
index 51675345af78b..0000000000000
--- a/packages/x-date-pickers-pro/src/MultiInputDateTimeRangeField/MultiInputDateTimeRangeField.types.ts
+++ /dev/null
@@ -1,89 +0,0 @@
-import * as React from 'react';
-import type { TypographyProps } from '@mui/material/Typography';
-import type { StackProps } from '@mui/material/Stack';
-import type { TextFieldProps } from '@mui/material/TextField';
-import { FieldOwnerState } from '@mui/x-date-pickers/models';
-import { SlotComponentPropsFromProps } from '@mui/x-internals/types';
-import { PickersTextFieldProps } from '@mui/x-date-pickers/PickersTextField';
-import { UseDateTimeRangeFieldProps } from '../internals/models/dateTimeRange';
-import { UseMultiInputRangeFieldParams } from '../internals/hooks/useMultiInputRangeField/useMultiInputRangeField.types';
-import { MultiInputFieldRefs, MultiInputRangeFieldClasses, RangePosition } from '../models';
-
-export type UseMultiInputDateTimeRangeFieldParams<
- TEnableAccessibleFieldDOMStructure extends boolean,
- TTextFieldSlotProps extends {},
-> = UseMultiInputRangeFieldParams<
- UseMultiInputDateTimeRangeFieldProps,
- TTextFieldSlotProps
->;
-
-export interface UseMultiInputDateTimeRangeFieldProps<
- TEnableAccessibleFieldDOMStructure extends boolean,
-> extends Omit<
- UseDateTimeRangeFieldProps,
- 'unstableFieldRef' | 'clearable' | 'onClear'
- >,
- MultiInputFieldRefs {}
-
-export type UseMultiInputDateTimeRangeFieldComponentProps<
- TEnableAccessibleFieldDOMStructure extends boolean,
- TChildProps extends {},
-> = Omit<
- TChildProps,
- keyof UseMultiInputDateTimeRangeFieldProps
-> &
- UseMultiInputDateTimeRangeFieldProps;
-
-export interface MultiInputDateTimeRangeFieldProps<
- TEnableAccessibleFieldDOMStructure extends boolean = true,
-> extends UseMultiInputDateTimeRangeFieldComponentProps<
- TEnableAccessibleFieldDOMStructure,
- Omit
- > {
- autoFocus?: boolean;
- /**
- * Override or extend the styles applied to the component.
- */
- classes?: Partial;
- /**
- * Overridable component slots.
- * @default {}
- */
- slots?: MultiInputDateTimeRangeFieldSlots;
- /**
- * The props used for each component slot.
- * @default {}
- */
- slotProps?: MultiInputDateTimeRangeFieldSlotProps;
-}
-
-export interface MultiInputDateTimeRangeFieldSlots {
- /**
- * Element rendered at the root.
- * @default MultiInputDateTimeRangeFieldRoot
- */
- root?: React.ElementType;
- /**
- * Form control with an input to render a date and time.
- * It is rendered twice: once for the start date time and once for the end date time.
- * @default TextField from '@mui/material' or PickersTextField if `enableAccessibleFieldDOMStructure` is `true`.
- */
- textField?: React.ElementType;
- /**
- * Element rendered between the two inputs.
- * @default MultiInputDateTimeRangeFieldSeparator
- */
- separator?: React.ElementType;
-}
-
-export interface MultiInputDateTimeRangeFieldSlotProps {
- root?: SlotComponentPropsFromProps;
- textField?: SlotComponentPropsFromProps<
- PickersTextFieldProps | TextFieldProps,
- {},
- FieldOwnerState & {
- position: RangePosition;
- }
- >;
- separator?: SlotComponentPropsFromProps;
-}
diff --git a/packages/x-date-pickers-pro/src/MultiInputDateTimeRangeField/index.ts b/packages/x-date-pickers-pro/src/MultiInputDateTimeRangeField/index.ts
index 829bda46788e9..35c2a5a9b0613 100644
--- a/packages/x-date-pickers-pro/src/MultiInputDateTimeRangeField/index.ts
+++ b/packages/x-date-pickers-pro/src/MultiInputDateTimeRangeField/index.ts
@@ -1,11 +1,16 @@
+export { MultiInputDateTimeRangeField } from './MultiInputDateTimeRangeField';
+export type { MultiInputDateTimeRangeFieldProps } from './MultiInputDateTimeRangeField';
+
export {
- MultiInputDateTimeRangeField,
- getMultiInputDateTimeRangeFieldUtilityClass,
multiInputDateTimeRangeFieldClasses,
-} from './MultiInputDateTimeRangeField';
-export { useMultiInputDateTimeRangeField as unstable_useMultiInputDateTimeRangeField } from '../internals/hooks/useMultiInputRangeField/useMultiInputDateTimeRangeField';
+ getMultiInputDateTimeRangeFieldUtilityClass,
+} from './multiInputDateTimeRangeFieldClasses';
+export type {
+ MultiInputDateTimeRangeFieldClassKey,
+ MultiInputDateTimeRangeFieldClasses,
+} from './multiInputDateTimeRangeFieldClasses';
+
export type {
- UseMultiInputDateTimeRangeFieldProps,
- UseMultiInputDateTimeRangeFieldComponentProps,
- MultiInputDateTimeRangeFieldProps,
-} from './MultiInputDateTimeRangeField.types';
+ MultiInputRangeFieldSlots as MultiInputDateTimeRangeFieldSlots,
+ MultiInputRangeFieldSlotProps as MultiInputDateTimeRangeFieldSlotProps,
+} from '../internals/utils/createMultiInputRangeField';
diff --git a/packages/x-date-pickers-pro/src/MultiInputDateTimeRangeField/multiInputDateTimeRangeFieldClasses.ts b/packages/x-date-pickers-pro/src/MultiInputDateTimeRangeField/multiInputDateTimeRangeFieldClasses.ts
new file mode 100644
index 0000000000000..d05a7de8eac5f
--- /dev/null
+++ b/packages/x-date-pickers-pro/src/MultiInputDateTimeRangeField/multiInputDateTimeRangeFieldClasses.ts
@@ -0,0 +1,13 @@
+import generateUtilityClass from '@mui/utils/generateUtilityClass';
+import generateUtilityClasses from '@mui/utils/generateUtilityClasses';
+import { MultiInputRangeFieldClasses } from '../internals/utils/createMultiInputRangeField';
+
+export interface MultiInputDateTimeRangeFieldClasses extends MultiInputRangeFieldClasses {}
+
+export type MultiInputDateTimeRangeFieldClassKey = keyof MultiInputRangeFieldClasses;
+
+export const multiInputDateTimeRangeFieldClasses: MultiInputRangeFieldClasses =
+ generateUtilityClasses('MuiMultiInputDateTimeRangeField', ['root', 'separator']);
+
+export const getMultiInputDateTimeRangeFieldUtilityClass = (slot: string) =>
+ generateUtilityClass('MuiMultiInputDateTimeRangeField', slot);
diff --git a/packages/x-date-pickers-pro/src/MultiInputTimeRangeField/MultiInputTimeRangeField.tsx b/packages/x-date-pickers-pro/src/MultiInputTimeRangeField/MultiInputTimeRangeField.tsx
index f71baf65aac82..49d4fb104ffd3 100644
--- a/packages/x-date-pickers-pro/src/MultiInputTimeRangeField/MultiInputTimeRangeField.tsx
+++ b/packages/x-date-pickers-pro/src/MultiInputTimeRangeField/MultiInputTimeRangeField.tsx
@@ -1,62 +1,27 @@
'use client';
import * as React from 'react';
import PropTypes from 'prop-types';
-import { clsx } from 'clsx';
-import Stack, { StackProps } from '@mui/material/Stack';
-import MuiTextField from '@mui/material/TextField';
-import Typography from '@mui/material/Typography';
-import { styled, useThemeProps } from '@mui/material/styles';
-import useSlotProps from '@mui/utils/useSlotProps';
+import { useTimeRangeManager, UseTimeRangeManagerReturnValue } from '../managers';
import {
- unstable_composeClasses as composeClasses,
- unstable_generateUtilityClass as generateUtilityClass,
- unstable_generateUtilityClasses as generateUtilityClasses,
-} from '@mui/utils';
-import { cleanFieldResponse, useFieldOwnerState } from '@mui/x-date-pickers/internals';
-import { useSplitFieldProps } from '@mui/x-date-pickers/hooks';
-import { PickersTextField } from '@mui/x-date-pickers/PickersTextField';
+ // The alias is needed to have the doc gen working.
+ createMultiInputRangeField as createMultiInputTimeRangeField,
+ MultiInputRangeFieldProps,
+} from '../internals/utils/createMultiInputRangeField';
import {
- MultiInputTimeRangeFieldProps,
- MultiInputTimeRangeFieldSlotProps,
-} from './MultiInputTimeRangeField.types';
-import { useMultiInputTimeRangeField } from '../internals/hooks/useMultiInputRangeField/useMultiInputTimeRangeField';
-import { MultiInputRangeFieldClasses, RangePosition } from '../models';
+ getMultiInputTimeRangeFieldUtilityClass,
+ MultiInputTimeRangeFieldClasses,
+} from './multiInputTimeRangeFieldClasses';
-export const multiInputTimeRangeFieldClasses: MultiInputRangeFieldClasses = generateUtilityClasses(
- 'MuiMultiInputTimeRangeField',
- ['root', 'separator'],
-);
-
-export const getMultiInputTimeRangeFieldUtilityClass = (slot: string) =>
- generateUtilityClass('MuiMultiInputTimeRangeField', slot);
-
-const useUtilityClasses = (classes: Partial | undefined) => {
- const slots = {
- root: ['root'],
- separator: ['separator'],
- };
-
- return composeClasses(slots, getMultiInputTimeRangeFieldUtilityClass, classes);
-};
-
-const MultiInputTimeRangeFieldRoot = styled(
- React.forwardRef((props: StackProps, ref: React.Ref) => (
-
- )),
- {
- name: 'MuiMultiInputTimeRangeField',
- slot: 'Root',
- overridesResolver: (props, styles) => styles.root,
- },
-)({});
-
-const MultiInputTimeRangeFieldSeparator = styled(Typography, {
- name: 'MuiMultiInputTimeRangeField',
- slot: 'Separator',
- overridesResolver: (props, styles) => styles.separator,
-})({
- lineHeight: '1.4375em', // 23px
-});
+export interface MultiInputTimeRangeFieldProps
+ extends MultiInputRangeFieldProps<
+ UseTimeRangeManagerReturnValue
+ > {
+ // We need to redefine the classes here, otherwise we don't have the doc generation.
+ /**
+ * Override or extend the styles applied to the component.
+ */
+ classes?: Partial;
+}
type MultiInputTimeRangeFieldComponent = (<
TEnableAccessibleFieldDOMStructure extends boolean = true,
@@ -75,108 +40,10 @@ type MultiInputTimeRangeFieldComponent = (<
*
* - [MultiInputTimeRangeField API](https://mui.com/x/api/multi-input-time-range-field/)
*/
-const MultiInputTimeRangeField = React.forwardRef(function MultiInputTimeRangeField<
- TEnableAccessibleFieldDOMStructure extends boolean = true,
->(
- inProps: MultiInputTimeRangeFieldProps,
- ref: React.Ref,
-) {
- const themeProps = useThemeProps({
- props: inProps,
- name: 'MuiMultiInputTimeRangeField',
- });
-
- const { internalProps, forwardedProps } = useSplitFieldProps(themeProps, 'time');
-
- const {
- slots,
- slotProps,
- unstableStartFieldRef,
- unstableEndFieldRef,
- className,
- classes: classesProp,
- ...otherForwardedProps
- } = forwardedProps;
-
- const ownerState = useFieldOwnerState(themeProps);
- const classes = useUtilityClasses(classesProp);
-
- const Root = slots?.root ?? MultiInputTimeRangeFieldRoot;
- const rootProps = useSlotProps({
- elementType: Root,
- externalSlotProps: slotProps?.root,
- externalForwardedProps: otherForwardedProps,
- additionalProps: {
- ref,
- },
- ownerState,
- className: clsx(className, classes.root),
- });
-
- const startTextFieldProps = useSlotProps<
- typeof PickersTextField,
- MultiInputTimeRangeFieldSlotProps['textField'],
- {},
- MultiInputTimeRangeFieldProps & {
- position: RangePosition;
- }
- >({
- elementType: PickersTextField,
- externalSlotProps: slotProps?.textField,
- ownerState: { ...ownerState, position: 'start' },
- });
-
- const endTextFieldProps = useSlotProps<
- typeof PickersTextField,
- MultiInputTimeRangeFieldSlotProps['textField'],
- {},
- MultiInputTimeRangeFieldProps & {
- position: RangePosition;
- }
- >({
- elementType: PickersTextField,
- externalSlotProps: slotProps?.textField,
- ownerState: { ...ownerState, position: 'end' },
- });
-
- const Separator = slots?.separator ?? MultiInputTimeRangeFieldSeparator;
- const separatorProps = useSlotProps({
- elementType: Separator,
- externalSlotProps: slotProps?.separator,
- additionalProps: {
- children: ` ${internalProps.dateSeparator ?? '–'} `,
- },
- ownerState,
- className: classes.separator,
- });
-
- const fieldResponse = useMultiInputTimeRangeField<
- TEnableAccessibleFieldDOMStructure,
- typeof startTextFieldProps
- >({
- sharedProps: internalProps,
- startTextFieldProps,
- endTextFieldProps,
- unstableStartFieldRef,
- unstableEndFieldRef,
- });
-
- const { textFieldProps: startDateProps } = cleanFieldResponse(fieldResponse.startDate);
- const { textFieldProps: endDateProps } = cleanFieldResponse(fieldResponse.endDate);
-
- const TextField =
- slots?.textField ??
- (fieldResponse.startDate.enableAccessibleFieldDOMStructure === false
- ? MuiTextField
- : PickersTextField);
-
- return (
-
-
-
-
-
- );
+const MultiInputTimeRangeField = createMultiInputTimeRangeField({
+ name: 'MuiMultiInputTimeRangeField',
+ getUtilityClass: getMultiInputTimeRangeFieldUtilityClass,
+ useManager: useTimeRangeManager,
}) as MultiInputTimeRangeFieldComponent;
MultiInputTimeRangeField.propTypes = {
@@ -191,6 +58,7 @@ MultiInputTimeRangeField.propTypes = {
ampm: PropTypes.bool,
/**
* If `true`, the `input` element is focused during the first mount.
+ * @default false
*/
autoFocus: PropTypes.bool,
/**
@@ -359,7 +227,7 @@ MultiInputTimeRangeField.propTypes = {
*/
slotProps: PropTypes.object,
/**
- * Overridable slots.
+ * Overridable component slots.
* @default {}
*/
slots: PropTypes.object,
diff --git a/packages/x-date-pickers-pro/src/MultiInputTimeRangeField/MultiInputTimeRangeField.types.ts b/packages/x-date-pickers-pro/src/MultiInputTimeRangeField/MultiInputTimeRangeField.types.ts
deleted file mode 100644
index 08708712d12de..0000000000000
--- a/packages/x-date-pickers-pro/src/MultiInputTimeRangeField/MultiInputTimeRangeField.types.ts
+++ /dev/null
@@ -1,86 +0,0 @@
-import * as React from 'react';
-import type { TypographyProps } from '@mui/material/Typography';
-import type { StackProps } from '@mui/material/Stack';
-import type { TextFieldProps } from '@mui/material/TextField';
-import { FieldOwnerState } from '@mui/x-date-pickers/models';
-import { SlotComponentPropsFromProps } from '@mui/x-internals/types';
-import { PickersTextFieldProps } from '@mui/x-date-pickers/PickersTextField';
-import { UseTimeRangeFieldProps } from '../internals/models/timeRange';
-import { UseMultiInputRangeFieldParams } from '../internals/hooks/useMultiInputRangeField/useMultiInputRangeField.types';
-import { MultiInputFieldRefs, MultiInputRangeFieldClasses, RangePosition } from '../models';
-
-export type UseMultiInputTimeRangeFieldParams<
- TEnableAccessibleFieldDOMStructure extends boolean,
- TTextFieldSlotProps extends {},
-> = UseMultiInputRangeFieldParams<
- UseMultiInputTimeRangeFieldProps,
- TTextFieldSlotProps
->;
-
-export interface UseMultiInputTimeRangeFieldProps<
- TEnableAccessibleFieldDOMStructure extends boolean,
-> extends Omit<
- UseTimeRangeFieldProps,
- 'unstableFieldRef' | 'clearable' | 'onClear'
- >,
- MultiInputFieldRefs {}
-
-export type UseMultiInputTimeRangeFieldComponentProps<
- TEnableAccessibleFieldDOMStructure extends boolean,
- TChildProps extends {},
-> = Omit> &
- UseMultiInputTimeRangeFieldProps;
-
-export interface MultiInputTimeRangeFieldProps<
- TEnableAccessibleFieldDOMStructure extends boolean = true,
-> extends UseMultiInputTimeRangeFieldComponentProps<
- TEnableAccessibleFieldDOMStructure,
- Omit
- > {
- autoFocus?: boolean;
- /**
- * Override or extend the styles applied to the component.
- */
- classes?: Partial;
- /**
- * Overridable slots.
- * @default {}
- */
- slots?: MultiInputTimeRangeFieldSlots;
- /**
- * The props used for each component slot.
- * @default {}
- */
- slotProps?: MultiInputTimeRangeFieldSlotProps;
-}
-
-export interface MultiInputTimeRangeFieldSlots {
- /**
- * Element rendered at the root.
- * @default MultiInputTimeRangeFieldRoot
- */
- root?: React.ElementType;
- /**
- * Form control with an input to render a time.
- * It is rendered twice: once for the start time and once for the end time.
- * @default TextField from '@mui/material' or PickersTextField if `enableAccessibleFieldDOMStructure` is `true`.
- */
- textField?: React.ElementType;
- /**
- * Element rendered between the two inputs.
- * @default MultiInputTimeRangeFieldSeparator
- */
- separator?: React.ElementType;
-}
-
-export interface MultiInputTimeRangeFieldSlotProps {
- root?: SlotComponentPropsFromProps;
- textField?: SlotComponentPropsFromProps<
- PickersTextFieldProps | TextFieldProps,
- {},
- FieldOwnerState & {
- position: RangePosition;
- }
- >;
- separator?: SlotComponentPropsFromProps;
-}
diff --git a/packages/x-date-pickers-pro/src/MultiInputTimeRangeField/index.ts b/packages/x-date-pickers-pro/src/MultiInputTimeRangeField/index.ts
index d1d7744242ee1..6099c1f5878d8 100644
--- a/packages/x-date-pickers-pro/src/MultiInputTimeRangeField/index.ts
+++ b/packages/x-date-pickers-pro/src/MultiInputTimeRangeField/index.ts
@@ -1,11 +1,16 @@
+export { MultiInputTimeRangeField } from './MultiInputTimeRangeField';
+export type { MultiInputTimeRangeFieldProps } from './MultiInputTimeRangeField';
+
export {
- MultiInputTimeRangeField,
- getMultiInputTimeRangeFieldUtilityClass,
multiInputTimeRangeFieldClasses,
-} from './MultiInputTimeRangeField';
-export { useMultiInputTimeRangeField as unstable_useMultiInputTimeRangeField } from '../internals/hooks/useMultiInputRangeField/useMultiInputTimeRangeField';
+ getMultiInputTimeRangeFieldUtilityClass,
+} from './multiInputTimeRangeFieldClasses';
+export type {
+ MultiInputTimeRangeFieldClassKey,
+ MultiInputTimeRangeFieldClasses,
+} from './multiInputTimeRangeFieldClasses';
+
export type {
- UseMultiInputTimeRangeFieldProps,
- UseMultiInputTimeRangeFieldComponentProps,
- MultiInputTimeRangeFieldProps,
-} from './MultiInputTimeRangeField.types';
+ MultiInputRangeFieldSlots as MultiInputTimeRangeFieldSlots,
+ MultiInputRangeFieldSlotProps as MultiInputTimeRangeFieldSlotProps,
+} from '../internals/utils/createMultiInputRangeField';
diff --git a/packages/x-date-pickers-pro/src/MultiInputTimeRangeField/multiInputTimeRangeFieldClasses.ts b/packages/x-date-pickers-pro/src/MultiInputTimeRangeField/multiInputTimeRangeFieldClasses.ts
new file mode 100644
index 0000000000000..bf15c75ec7fde
--- /dev/null
+++ b/packages/x-date-pickers-pro/src/MultiInputTimeRangeField/multiInputTimeRangeFieldClasses.ts
@@ -0,0 +1,15 @@
+import generateUtilityClass from '@mui/utils/generateUtilityClass';
+import generateUtilityClasses from '@mui/utils/generateUtilityClasses';
+import { MultiInputRangeFieldClasses } from '../internals/utils/createMultiInputRangeField';
+
+export interface MultiInputTimeRangeFieldClasses extends MultiInputRangeFieldClasses {}
+
+export type MultiInputTimeRangeFieldClassKey = keyof MultiInputRangeFieldClasses;
+
+export const multiInputTimeRangeFieldClasses: MultiInputRangeFieldClasses = generateUtilityClasses(
+ 'MuiMultiInputTimeRangeField',
+ ['root', 'separator'],
+);
+
+export const getMultiInputTimeRangeFieldUtilityClass = (slot: string) =>
+ generateUtilityClass('MuiMultiInputTimeRangeField', slot);
diff --git a/packages/x-date-pickers-pro/src/SingleInputDateRangeField/SingleInputDateRangeField.types.ts b/packages/x-date-pickers-pro/src/SingleInputDateRangeField/SingleInputDateRangeField.types.ts
index 7828b1643c3c0..efbcdf224df24 100644
--- a/packages/x-date-pickers-pro/src/SingleInputDateRangeField/SingleInputDateRangeField.types.ts
+++ b/packages/x-date-pickers-pro/src/SingleInputDateRangeField/SingleInputDateRangeField.types.ts
@@ -1,24 +1,14 @@
import {
- PickerRangeValue,
- UseFieldInternalProps,
ExportedPickerFieldUIProps,
PickerFieldUISlots,
PickerFieldUISlotProps,
} from '@mui/x-date-pickers/internals';
import { BuiltInFieldTextFieldProps } from '@mui/x-date-pickers/models';
-import type { DateRangeValidationError, UseDateRangeFieldProps } from '../models';
+import { DateRangeManagerFieldInternalProps } from '../managers/useDateRangeManager';
export interface UseSingleInputDateRangeFieldProps<
TEnableAccessibleFieldDOMStructure extends boolean,
-> extends UseDateRangeFieldProps,
- Pick<
- UseFieldInternalProps<
- PickerRangeValue,
- TEnableAccessibleFieldDOMStructure,
- DateRangeValidationError
- >,
- 'unstableFieldRef'
- >,
+> extends DateRangeManagerFieldInternalProps,
// TODO v8: Remove once the range fields open with a button.
Omit {}
diff --git a/packages/x-date-pickers-pro/src/SingleInputDateTimeRangeField/SingleInputDateTimeRangeField.types.ts b/packages/x-date-pickers-pro/src/SingleInputDateTimeRangeField/SingleInputDateTimeRangeField.types.ts
index d7f51a40420b5..576a1b9c59d08 100644
--- a/packages/x-date-pickers-pro/src/SingleInputDateTimeRangeField/SingleInputDateTimeRangeField.types.ts
+++ b/packages/x-date-pickers-pro/src/SingleInputDateTimeRangeField/SingleInputDateTimeRangeField.types.ts
@@ -2,24 +2,13 @@ import {
ExportedPickerFieldUIProps,
PickerFieldUISlots,
PickerFieldUISlotProps,
- PickerRangeValue,
- UseFieldInternalProps,
} from '@mui/x-date-pickers/internals';
import { BuiltInFieldTextFieldProps } from '@mui/x-date-pickers/models';
-import { UseDateTimeRangeFieldProps } from '../internals/models';
-import { DateTimeRangeValidationError } from '../models';
+import { DateTimeRangeManagerFieldInternalProps } from '../managers/useDateTimeRangeManager';
export interface UseSingleInputDateTimeRangeFieldProps<
TEnableAccessibleFieldDOMStructure extends boolean,
-> extends UseDateTimeRangeFieldProps,
- Pick<
- UseFieldInternalProps<
- PickerRangeValue,
- TEnableAccessibleFieldDOMStructure,
- DateTimeRangeValidationError
- >,
- 'unstableFieldRef'
- >,
+> extends DateTimeRangeManagerFieldInternalProps,
// TODO v8: Remove once the range fields open with a button.
Omit {}
diff --git a/packages/x-date-pickers-pro/src/SingleInputTimeRangeField/SingleInputTimeRangeField.types.ts b/packages/x-date-pickers-pro/src/SingleInputTimeRangeField/SingleInputTimeRangeField.types.ts
index 56fcb66f9b5f9..ae1a386ea7d4a 100644
--- a/packages/x-date-pickers-pro/src/SingleInputTimeRangeField/SingleInputTimeRangeField.types.ts
+++ b/packages/x-date-pickers-pro/src/SingleInputTimeRangeField/SingleInputTimeRangeField.types.ts
@@ -2,24 +2,13 @@ import {
ExportedPickerFieldUIProps,
PickerFieldUISlots,
PickerFieldUISlotProps,
- PickerRangeValue,
- UseFieldInternalProps,
} from '@mui/x-date-pickers/internals';
import { BuiltInFieldTextFieldProps } from '@mui/x-date-pickers/models';
-import { UseTimeRangeFieldProps } from '../internals/models';
-import { TimeRangeValidationError } from '../models';
+import { TimeRangeManagerFieldInternalProps } from '../managers/useTimeRangeManager';
export interface UseSingleInputTimeRangeFieldProps<
TEnableAccessibleFieldDOMStructure extends boolean,
-> extends UseTimeRangeFieldProps,
- Pick<
- UseFieldInternalProps<
- PickerRangeValue,
- TEnableAccessibleFieldDOMStructure,
- TimeRangeValidationError
- >,
- 'unstableFieldRef'
- >,
+> extends TimeRangeManagerFieldInternalProps,
// TODO v8: Remove once the range fields open with a button.
Omit {}
diff --git a/packages/x-date-pickers-pro/src/hooks/index.ts b/packages/x-date-pickers-pro/src/hooks/index.ts
index 1a00cfc2ec27b..9ac0fdf9beb14 100644
--- a/packages/x-date-pickers-pro/src/hooks/index.ts
+++ b/packages/x-date-pickers-pro/src/hooks/index.ts
@@ -1 +1,2 @@
export { usePickerRangePositionContext } from './usePickerRangePositionContext';
+export { useMultiInputRangeField as unstable_useMultiInputRangeField } from './useMultiInputRangeField';
diff --git a/packages/x-date-pickers-pro/src/hooks/useMultiInputRangeField/index.ts b/packages/x-date-pickers-pro/src/hooks/useMultiInputRangeField/index.ts
new file mode 100644
index 0000000000000..d1c290e53e6d8
--- /dev/null
+++ b/packages/x-date-pickers-pro/src/hooks/useMultiInputRangeField/index.ts
@@ -0,0 +1 @@
+export { useMultiInputRangeField } from './useMultiInputRangeField';
diff --git a/packages/x-date-pickers-pro/src/hooks/useMultiInputRangeField/useMultiInputRangeField.ts b/packages/x-date-pickers-pro/src/hooks/useMultiInputRangeField/useMultiInputRangeField.ts
new file mode 100644
index 0000000000000..a7517a9a0d74e
--- /dev/null
+++ b/packages/x-date-pickers-pro/src/hooks/useMultiInputRangeField/useMultiInputRangeField.ts
@@ -0,0 +1,199 @@
+'use client';
+import useEventCallback from '@mui/utils/useEventCallback';
+import {
+ FieldChangeHandler,
+ FieldChangeHandlerContext,
+ PickerManagerEnableAccessibleFieldDOMStructure,
+ PickerManagerError,
+ PickerManagerFieldInternalProps,
+ PickerRangeValue,
+ PickerValue,
+ useControlledValueWithTimezone,
+ useFieldInternalPropsWithDefaults,
+ UseFieldResponse,
+} from '@mui/x-date-pickers/internals';
+import { useValidation } from '@mui/x-date-pickers/validation';
+import { useMultiInputRangeFieldTextFieldProps } from './useMultiInputRangeFieldTextFieldProps';
+import { useMultiInputRangeFieldSelectedSections } from './useMultiInputRangeFieldSelectedSections';
+import { PickerAnyRangeManager } from '../../internals/models/managers';
+
+/**
+ * Basic example:
+ *
+ * ```tsx
+ * import Box from '@mui/material/Box';
+ * import { useSplitFieldProps } from '@mui/x-date-pickers/hooks';
+ * import { PickersTextField } from '@mui/x-date-pickers/PickersTextField';
+ * import { useDateRangeManager } from '@mui/x-date-pickers-pro/managers';
+ *
+ * function MultiInputField(props) {
+ * const manager = useDateRangeManager();
+ * const { internalProps, forwardedProps } = useSplitFieldProps(props, 'date');
+ * const { startDate, endDate } = useMultiInputRangeField({
+ * manager,
+ * internalProps,
+ * startForwardedProps: forwardedProps,
+ * endForwardedProps: forwardedProps,
+ * });
+ *
+ * return (
+ *
+ *
+ * {' – '}
+ *
+ *
+ * );
+ * }
+ * ```
+ *
+ * @param {UseMultiInputRangeFieldParameters} parameters The parameters of the hook.
+ * @param {TManager} parameters.manager The manager of the field.
+ * @param {PickerManagerFieldInternalProps} parameters.internalProps The internal props of the field.
+ * @param {TForwardedProps} parameters.startForwardedProps The forwarded props of the start field.
+ * @param {TForwardedProps} parameters.endForwardedProps The forwarded props of the end field.
+ * @returns {UseMultiInputRangeFieldReturnValue} The props to pass to the start and the end components.
+ */
+export function useMultiInputRangeField<
+ TManager extends PickerAnyRangeManager,
+ TForwardedProps extends { [key: string]: any },
+>(
+ parameters: UseMultiInputRangeFieldParameters,
+): UseMultiInputRangeFieldReturnValue {
+ type TError = PickerManagerError;
+
+ const { manager, internalProps, startForwardedProps, endForwardedProps } = parameters;
+
+ const internalPropsWithDefaults = useFieldInternalPropsWithDefaults({
+ manager,
+ internalProps,
+ });
+
+ const {
+ value: valueProp,
+ defaultValue,
+ format,
+ formatDensity,
+ shouldRespectLeadingZeros,
+ onChange,
+ disabled,
+ readOnly,
+ selectedSections,
+ onSelectedSectionsChange,
+ timezone: timezoneProp,
+ enableAccessibleFieldDOMStructure,
+ autoFocus,
+ referenceDate,
+ unstableStartFieldRef,
+ unstableEndFieldRef,
+ } = internalPropsWithDefaults;
+
+ const { value, handleValueChange, timezone } = useControlledValueWithTimezone({
+ name: 'useMultiInputRangeField',
+ timezone: timezoneProp,
+ value: valueProp,
+ defaultValue,
+ referenceDate,
+ onChange,
+ valueManager: manager.internal_valueManager,
+ });
+
+ const { validationError, getValidationErrorForNewValue } = useValidation({
+ props: internalPropsWithDefaults,
+ value,
+ timezone,
+ validator: manager.validator,
+ onError: internalPropsWithDefaults.onError,
+ });
+
+ const buildChangeHandler = (index: 0 | 1): FieldChangeHandler => {
+ return (newSingleValue, rawContext) => {
+ const newRange: PickerRangeValue =
+ index === 0 ? [newSingleValue, value[1]] : [value[0], newSingleValue];
+
+ const context: FieldChangeHandlerContext = {
+ ...rawContext,
+ validationError: getValidationErrorForNewValue(newRange),
+ };
+
+ handleValueChange(newRange, context);
+ };
+ };
+
+ const handleStartDateChange = useEventCallback(buildChangeHandler(0));
+ const handleEndDateChange = useEventCallback(buildChangeHandler(1));
+
+ const selectedSectionsResponse = useMultiInputRangeFieldSelectedSections({
+ selectedSections,
+ onSelectedSectionsChange,
+ unstableStartFieldRef,
+ unstableEndFieldRef,
+ });
+
+ const sharedProps = {
+ disabled,
+ readOnly,
+ timezone,
+ format,
+ formatDensity,
+ shouldRespectLeadingZeros,
+ enableAccessibleFieldDOMStructure,
+ };
+
+ const startDateProps = useMultiInputRangeFieldTextFieldProps({
+ valueType: manager.valueType,
+ fieldProps: {
+ error: !!validationError[0],
+ ...startForwardedProps,
+ ...selectedSectionsResponse.start,
+ ...sharedProps,
+ value: valueProp === undefined ? undefined : valueProp[0],
+ defaultValue: defaultValue === undefined ? undefined : defaultValue[0],
+ onChange: handleStartDateChange,
+ autoFocus, // Do not add on end field.
+ },
+ });
+
+ const endDateProps = useMultiInputRangeFieldTextFieldProps({
+ valueType: manager.valueType,
+ fieldProps: {
+ error: !!validationError[1],
+ ...endForwardedProps,
+ ...selectedSectionsResponse.end,
+ ...sharedProps,
+ value: valueProp === undefined ? undefined : valueProp[1],
+ defaultValue: defaultValue === undefined ? undefined : defaultValue[1],
+ onChange: handleEndDateChange,
+ },
+ });
+
+ return {
+ startDate: startDateProps,
+ endDate: endDateProps,
+ enableAccessibleFieldDOMStructure,
+ };
+}
+
+interface UseMultiInputRangeFieldParameters<
+ TManager extends PickerAnyRangeManager,
+ TForwardedProps extends {},
+> {
+ manager: TManager;
+ internalProps: PickerManagerFieldInternalProps;
+ startForwardedProps: TForwardedProps;
+ endForwardedProps: TForwardedProps;
+}
+
+interface UseMultiInputRangeFieldReturnValue<
+ TManager extends PickerAnyRangeManager,
+ TForwardedProps extends {},
+> {
+ startDate: Omit<
+ UseFieldResponse, TForwardedProps>,
+ 'clearable' | 'onClear'
+ >;
+ endDate: Omit<
+ UseFieldResponse, TForwardedProps>,
+ 'clearable' | 'onClear'
+ >;
+ enableAccessibleFieldDOMStructure: PickerManagerEnableAccessibleFieldDOMStructure;
+}
diff --git a/packages/x-date-pickers-pro/src/internals/hooks/useMultiInputFieldSelectedSections.ts b/packages/x-date-pickers-pro/src/hooks/useMultiInputRangeField/useMultiInputRangeFieldSelectedSections.ts
similarity index 68%
rename from packages/x-date-pickers-pro/src/internals/hooks/useMultiInputFieldSelectedSections.ts
rename to packages/x-date-pickers-pro/src/hooks/useMultiInputRangeField/useMultiInputRangeFieldSelectedSections.ts
index 59956a8c633b1..1d66461f7e622 100644
--- a/packages/x-date-pickers-pro/src/internals/hooks/useMultiInputFieldSelectedSections.ts
+++ b/packages/x-date-pickers-pro/src/hooks/useMultiInputRangeField/useMultiInputRangeFieldSelectedSections.ts
@@ -1,3 +1,4 @@
+'use client';
import * as React from 'react';
import useForkRef from '@mui/utils/useForkRef';
import useEventCallback from '@mui/utils/useEventCallback';
@@ -7,15 +8,14 @@ import {
UseFieldInternalProps,
} from '@mui/x-date-pickers/internals';
import { FieldRef, FieldSelectedSections } from '@mui/x-date-pickers/models';
+import { MultiInputFieldRefs } from '../../models';
-interface UseMultiInputFieldSelectedSectionsParams
+interface UseMultiInputRangeFieldSelectedSectionsParameters
extends Pick<
- UseFieldInternalProps,
- 'selectedSections' | 'onSelectedSectionsChange'
- > {
- unstableStartFieldRef?: React.Ref>;
- unstableEndFieldRef?: React.Ref>;
-}
+ UseFieldInternalProps,
+ 'selectedSections' | 'onSelectedSectionsChange'
+ >,
+ MultiInputFieldRefs {}
interface UseMultiInputFieldSelectedSectionsResponseItem {
unstableFieldRef?: React.Ref>;
@@ -28,14 +28,14 @@ interface UseMultiInputFieldSelectedSectionsResponse {
end: UseMultiInputFieldSelectedSectionsResponseItem;
}
-export const useMultiInputFieldSelectedSections = (
- params: UseMultiInputFieldSelectedSectionsParams,
+export const useMultiInputRangeFieldSelectedSections = (
+ parameters: UseMultiInputRangeFieldSelectedSectionsParameters,
): UseMultiInputFieldSelectedSectionsResponse => {
const unstableEndFieldRef = React.useRef>(null);
- const handleUnstableEndFieldRef = useForkRef(params.unstableEndFieldRef, unstableEndFieldRef);
+ const handleUnstableEndFieldRef = useForkRef(parameters.unstableEndFieldRef, unstableEndFieldRef);
const [startSelectedSection, setStartSelectedSection] = React.useState(
- params.selectedSections ?? null,
+ parameters.selectedSections ?? null,
);
const [endSelectedSection, setEndSelectedSection] = React.useState(null);
@@ -51,7 +51,7 @@ export const useMultiInputFieldSelectedSections = (
(newSelectedSections: FieldSelectedSections) => {
setStartSelectedSection(newSelectedSections);
if (getActiveField() === 'start') {
- params.onSelectedSectionsChange?.(newSelectedSections);
+ parameters.onSelectedSectionsChange?.(newSelectedSections);
}
},
);
@@ -60,7 +60,7 @@ export const useMultiInputFieldSelectedSections = (
(newSelectedSections: FieldSelectedSections) => {
setEndSelectedSection(newSelectedSections);
if (getActiveField() === 'end') {
- params.onSelectedSectionsChange?.(newSelectedSections);
+ parameters.onSelectedSectionsChange?.(newSelectedSections);
}
},
);
@@ -69,18 +69,18 @@ export const useMultiInputFieldSelectedSections = (
return {
start: {
- unstableFieldRef: params.unstableStartFieldRef,
+ unstableFieldRef: parameters.unstableStartFieldRef,
selectedSections:
- activeField === 'start' && params.selectedSections !== undefined
- ? params.selectedSections
+ activeField === 'start' && parameters.selectedSections !== undefined
+ ? parameters.selectedSections
: startSelectedSection,
onSelectedSectionsChange: handleStartSelectedSectionChange,
},
end: {
unstableFieldRef: handleUnstableEndFieldRef,
selectedSections:
- activeField === 'end' && params.selectedSections !== undefined
- ? params.selectedSections
+ activeField === 'end' && parameters.selectedSections !== undefined
+ ? parameters.selectedSections
: endSelectedSection,
onSelectedSectionsChange: handleEndSelectedSectionChange,
},
diff --git a/packages/x-date-pickers-pro/src/hooks/useMultiInputRangeField/useMultiInputRangeFieldTextFieldProps.ts b/packages/x-date-pickers-pro/src/hooks/useMultiInputRangeField/useMultiInputRangeFieldTextFieldProps.ts
new file mode 100644
index 0000000000000..9886629d185a2
--- /dev/null
+++ b/packages/x-date-pickers-pro/src/hooks/useMultiInputRangeField/useMultiInputRangeFieldTextFieldProps.ts
@@ -0,0 +1,105 @@
+import {
+ useDateManager,
+ UseDateManagerReturnValue,
+ useDateTimeManager,
+ UseDateTimeManagerReturnValue,
+ useTimeManager,
+ UseTimeManagerReturnValue,
+} from '@mui/x-date-pickers/managers';
+import { useSplitFieldProps } from '@mui/x-date-pickers/hooks';
+import { PickerValueType } from '@mui/x-date-pickers/models';
+import {
+ PickerAnyManager,
+ PickerManagerEnableAccessibleFieldDOMStructure,
+ PickerManagerFieldInternalProps,
+ PickerValue,
+ useField,
+ useFieldInternalPropsWithDefaults,
+ UseFieldResponse,
+} from '@mui/x-date-pickers/internals';
+import { PickerAnyRangeManager } from '../../internals/models/managers';
+import {
+ UseDateRangeManagerReturnValue,
+ UseDateTimeRangeManagerReturnValue,
+ UseTimeRangeManagerReturnValue,
+} from '../../managers';
+
+/**
+ * @ignore - internal hook.
+ */
+export function useMultiInputRangeFieldTextFieldProps<
+ TManager extends PickerAnyRangeManager,
+ TForwardedProps extends { [key: string]: any },
+>(parameters: UseMultiInputRangeFieldTextFieldProps) {
+ type TEnableAccessibleFieldDOMStructure =
+ PickerManagerEnableAccessibleFieldDOMStructure;
+
+ const { fieldProps, valueType } = parameters;
+
+ let useManager: ({
+ enableAccessibleFieldDOMStructure,
+ }: {
+ enableAccessibleFieldDOMStructure: boolean | undefined;
+ }) => PickerAnyManager;
+ switch (valueType) {
+ case 'date': {
+ useManager = useDateManager;
+ break;
+ }
+ case 'time': {
+ useManager = useTimeManager;
+ break;
+ }
+ case 'date-time': {
+ useManager = useDateTimeManager;
+ break;
+ }
+ default: {
+ throw new Error(`Unknown valueType: ${valueType}`);
+ }
+ }
+
+ const manager = useManager({
+ enableAccessibleFieldDOMStructure: fieldProps.enableAccessibleFieldDOMStructure,
+ });
+
+ const { forwardedProps, internalProps } = useSplitFieldProps(fieldProps, 'date');
+ const internalPropsWithDefaults = useFieldInternalPropsWithDefaults({
+ manager,
+ internalProps,
+ });
+
+ const { clearable, onClear, ...fieldResponse } = useField<
+ PickerValue,
+ TEnableAccessibleFieldDOMStructure,
+ typeof forwardedProps,
+ typeof internalPropsWithDefaults
+ >({
+ forwardedProps,
+ internalProps: internalPropsWithDefaults,
+ valueManager: manager.internal_valueManager,
+ fieldValueManager: manager.internal_fieldValueManager,
+ validator: manager.validator,
+ valueType: manager.valueType,
+ // TODO v8: Add a real aria label before moving the opening logic to the field on range pickers.
+ getOpenPickerButtonAriaLabel: () => '',
+ }) as UseFieldResponse;
+
+ return fieldResponse;
+}
+
+interface UseMultiInputRangeFieldTextFieldProps {
+ valueType: PickerValueType;
+ fieldProps: PickerManagerFieldInternalProps>;
+}
+
+type GetDerivedManager =
+ TManager extends UseDateRangeManagerReturnValue
+ ? UseDateManagerReturnValue
+ : TManager extends UseTimeRangeManagerReturnValue
+ ? UseTimeManagerReturnValue
+ : TManager extends UseDateTimeRangeManagerReturnValue<
+ infer TEnableAccessibleFieldDOMStructure
+ >
+ ? UseDateTimeManagerReturnValue
+ : never;
diff --git a/packages/x-date-pickers-pro/src/internals/hooks/useMultiInputRangeField/useMultiInputDateRangeField.ts b/packages/x-date-pickers-pro/src/internals/hooks/useMultiInputRangeField/useMultiInputDateRangeField.ts
deleted file mode 100644
index e2b0b8483f184..0000000000000
--- a/packages/x-date-pickers-pro/src/internals/hooks/useMultiInputRangeField/useMultiInputDateRangeField.ts
+++ /dev/null
@@ -1,149 +0,0 @@
-import useEventCallback from '@mui/utils/useEventCallback';
-import { unstable_useDateField as useDateField } from '@mui/x-date-pickers/DateField';
-import {
- FieldChangeHandler,
- FieldChangeHandlerContext,
- PickerRangeValue,
- PickerValue,
- UseFieldResponse,
- useControlledValueWithTimezone,
- useFieldInternalPropsWithDefaults,
-} from '@mui/x-date-pickers/internals';
-import { useValidation } from '@mui/x-date-pickers/validation';
-import { DateValidationError } from '@mui/x-date-pickers/models';
-import { UseMultiInputDateRangeFieldParams } from '../../../MultiInputDateRangeField/MultiInputDateRangeField.types';
-import { validateDateRange } from '../../../validation';
-import { rangeValueManager } from '../../utils/valueManagers';
-import type { UseMultiInputRangeFieldResponse } from './useMultiInputRangeField.types';
-import { DateRangeValidationError } from '../../../models';
-import { useMultiInputFieldSelectedSections } from '../useMultiInputFieldSelectedSections';
-import { useDateRangeManager } from '../../../managers';
-
-export const useMultiInputDateRangeField = <
- TEnableAccessibleFieldDOMStructure extends boolean,
- TTextFieldSlotProps extends {},
->({
- sharedProps,
- startTextFieldProps,
- unstableStartFieldRef,
- endTextFieldProps,
- unstableEndFieldRef,
-}: UseMultiInputDateRangeFieldParams<
- TEnableAccessibleFieldDOMStructure,
- TTextFieldSlotProps
->): UseMultiInputRangeFieldResponse => {
- const manager = useDateRangeManager(sharedProps);
- const sharedPropsWithDefaults = useFieldInternalPropsWithDefaults({
- manager,
- internalProps: sharedProps,
- });
-
- const {
- value: valueProp,
- defaultValue,
- referenceDate,
- format,
- formatDensity,
- shouldRespectLeadingZeros,
- onChange,
- disabled,
- readOnly,
- selectedSections,
- onSelectedSectionsChange,
- timezone: timezoneProp,
- enableAccessibleFieldDOMStructure,
- autoFocus,
- } = sharedPropsWithDefaults;
-
- const { value, handleValueChange, timezone } = useControlledValueWithTimezone({
- name: 'useMultiInputDateRangeField',
- timezone: timezoneProp,
- value: valueProp,
- defaultValue,
- referenceDate,
- onChange,
- valueManager: rangeValueManager,
- });
-
- const { validationError, getValidationErrorForNewValue } = useValidation({
- props: sharedPropsWithDefaults,
- value,
- timezone,
- validator: validateDateRange,
- onError: sharedPropsWithDefaults.onError,
- });
-
- // TODO: Maybe export utility from `useField` instead of copy/pasting the logic
- const buildChangeHandler = (
- index: 0 | 1,
- ): FieldChangeHandler => {
- return (newDate, rawContext) => {
- const newDateRange: PickerRangeValue =
- index === 0 ? [newDate, value[1]] : [value[0], newDate];
-
- const context: FieldChangeHandlerContext = {
- ...rawContext,
- validationError: getValidationErrorForNewValue(newDateRange),
- };
-
- handleValueChange(newDateRange, context);
- };
- };
-
- const handleStartDateChange = useEventCallback(buildChangeHandler(0));
- const handleEndDateChange = useEventCallback(buildChangeHandler(1));
-
- const selectedSectionsResponse = useMultiInputFieldSelectedSections({
- selectedSections,
- onSelectedSectionsChange,
- unstableStartFieldRef,
- unstableEndFieldRef,
- });
-
- const startFieldProps = {
- error: !!validationError[0],
- ...startTextFieldProps,
- ...selectedSectionsResponse.start,
- disabled,
- readOnly,
- format,
- formatDensity,
- shouldRespectLeadingZeros,
- timezone,
- value: valueProp === undefined ? undefined : valueProp[0],
- defaultValue: defaultValue === undefined ? undefined : defaultValue[0],
- onChange: handleStartDateChange,
- enableAccessibleFieldDOMStructure,
- autoFocus, // Do not add on end field.
- };
-
- const endFieldProps = {
- error: !!validationError[1],
- ...endTextFieldProps,
- ...selectedSectionsResponse.end,
- format,
- formatDensity,
- shouldRespectLeadingZeros,
- disabled,
- readOnly,
- timezone,
- value: valueProp === undefined ? undefined : valueProp[1],
- defaultValue: defaultValue === undefined ? undefined : defaultValue[1],
- onChange: handleEndDateChange,
- enableAccessibleFieldDOMStructure,
- };
-
- const startDateResponse = useDateField<
- TEnableAccessibleFieldDOMStructure,
- typeof startFieldProps
- >(startFieldProps) as UseFieldResponse;
-
- const endDateResponse = useDateField(
- endFieldProps,
- ) as UseFieldResponse;
-
- return {
- startDate: startDateResponse,
- endDate: endDateResponse,
- };
-};
diff --git a/packages/x-date-pickers-pro/src/internals/hooks/useMultiInputRangeField/useMultiInputDateTimeRangeField.ts b/packages/x-date-pickers-pro/src/internals/hooks/useMultiInputRangeField/useMultiInputDateTimeRangeField.ts
deleted file mode 100644
index 840ef757f2e9e..0000000000000
--- a/packages/x-date-pickers-pro/src/internals/hooks/useMultiInputRangeField/useMultiInputDateTimeRangeField.ts
+++ /dev/null
@@ -1,150 +0,0 @@
-import useEventCallback from '@mui/utils/useEventCallback';
-import { unstable_useDateTimeField as useDateTimeField } from '@mui/x-date-pickers/DateTimeField';
-import {
- FieldChangeHandler,
- FieldChangeHandlerContext,
- PickerRangeValue,
- PickerValue,
- UseFieldResponse,
- useControlledValueWithTimezone,
- useFieldInternalPropsWithDefaults,
-} from '@mui/x-date-pickers/internals';
-import { useValidation } from '@mui/x-date-pickers/validation';
-import { DateTimeValidationError } from '@mui/x-date-pickers/models';
-import { UseMultiInputDateTimeRangeFieldParams } from '../../../MultiInputDateTimeRangeField/MultiInputDateTimeRangeField.types';
-import { validateDateTimeRange } from '../../../validation';
-import { rangeValueManager } from '../../utils/valueManagers';
-import type { UseMultiInputRangeFieldResponse } from './useMultiInputRangeField.types';
-import { DateTimeRangeValidationError } from '../../../models';
-import { useMultiInputFieldSelectedSections } from '../useMultiInputFieldSelectedSections';
-import { useDateTimeRangeManager } from '../../../managers';
-
-export const useMultiInputDateTimeRangeField = <
- TEnableAccessibleFieldDOMStructure extends boolean,
- TTextFieldSlotProps extends {},
->({
- sharedProps,
- startTextFieldProps,
- unstableStartFieldRef,
- endTextFieldProps,
- unstableEndFieldRef,
-}: UseMultiInputDateTimeRangeFieldParams<
- TEnableAccessibleFieldDOMStructure,
- TTextFieldSlotProps
->): UseMultiInputRangeFieldResponse => {
- const manager = useDateTimeRangeManager(sharedProps);
- const sharedPropsWithDefaults = useFieldInternalPropsWithDefaults({
- manager,
- internalProps: sharedProps,
- });
-
- const {
- value: valueProp,
- defaultValue,
- referenceDate,
- format,
- formatDensity,
- shouldRespectLeadingZeros,
- onChange,
- disabled,
- readOnly,
- selectedSections,
- onSelectedSectionsChange,
- timezone: timezoneProp,
- enableAccessibleFieldDOMStructure,
- autoFocus,
- } = sharedPropsWithDefaults;
-
- const { value, handleValueChange, timezone } = useControlledValueWithTimezone({
- name: 'useMultiInputDateTimeRangeField',
- timezone: timezoneProp,
- value: valueProp,
- defaultValue,
- referenceDate,
- onChange,
- valueManager: rangeValueManager,
- });
-
- const { validationError, getValidationErrorForNewValue } = useValidation({
- props: sharedPropsWithDefaults,
- value,
- timezone,
- validator: validateDateTimeRange,
- onError: sharedPropsWithDefaults.onError,
- });
-
- // TODO: Maybe export utility from `useField` instead of copy/pasting the logic
- const buildChangeHandler = (
- index: 0 | 1,
- ): FieldChangeHandler => {
- return (newDate, rawContext) => {
- const newDateRange: PickerRangeValue =
- index === 0 ? [newDate, value[1]] : [value[0], newDate];
-
- const context: FieldChangeHandlerContext = {
- ...rawContext,
- validationError: getValidationErrorForNewValue(newDateRange),
- };
-
- handleValueChange(newDateRange, context);
- };
- };
-
- const handleStartDateChange = useEventCallback(buildChangeHandler(0));
- const handleEndDateChange = useEventCallback(buildChangeHandler(1));
-
- const selectedSectionsResponse = useMultiInputFieldSelectedSections({
- selectedSections,
- onSelectedSectionsChange,
- unstableStartFieldRef,
- unstableEndFieldRef,
- });
-
- const startFieldProps = {
- error: !!validationError[0],
- ...startTextFieldProps,
- ...selectedSectionsResponse.start,
- disabled,
- readOnly,
- format,
- formatDensity,
- shouldRespectLeadingZeros,
- timezone,
- value: valueProp === undefined ? undefined : valueProp[0],
- defaultValue: defaultValue === undefined ? undefined : defaultValue[0],
- onChange: handleStartDateChange,
- enableAccessibleFieldDOMStructure,
- autoFocus, // Do not add on end field.
- };
-
- const endFieldProps = {
- error: !!validationError[1],
- ...endTextFieldProps,
- ...selectedSectionsResponse.end,
- format,
- formatDensity,
- shouldRespectLeadingZeros,
- disabled,
- readOnly,
- timezone,
- value: valueProp === undefined ? undefined : valueProp[1],
- defaultValue: defaultValue === undefined ? undefined : defaultValue[1],
- onChange: handleEndDateChange,
- enableAccessibleFieldDOMStructure,
- };
-
- const startDateResponse = useDateTimeField<
- TEnableAccessibleFieldDOMStructure,
- typeof startFieldProps
- >(startFieldProps) as UseFieldResponse;
-
- const endDateResponse = useDateTimeField<
- TEnableAccessibleFieldDOMStructure,
- typeof endFieldProps
- >(endFieldProps) as UseFieldResponse;
-
- return {
- startDate: startDateResponse,
- endDate: endDateResponse,
- };
-};
diff --git a/packages/x-date-pickers-pro/src/internals/hooks/useMultiInputRangeField/useMultiInputRangeField.types.ts b/packages/x-date-pickers-pro/src/internals/hooks/useMultiInputRangeField/useMultiInputRangeField.types.ts
deleted file mode 100644
index b2a961644c39a..0000000000000
--- a/packages/x-date-pickers-pro/src/internals/hooks/useMultiInputRangeField/useMultiInputRangeField.types.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-import { UseFieldResponse } from '@mui/x-date-pickers/internals';
-import { MultiInputFieldRefs } from '../../../models';
-
-export interface UseMultiInputRangeFieldParams<
- TSharedProps extends {},
- TTextFieldSlotProps extends {},
-> extends MultiInputFieldRefs {
- sharedProps: TSharedProps;
- startTextFieldProps: TTextFieldSlotProps;
- endTextFieldProps: TTextFieldSlotProps;
-}
-
-export interface UseMultiInputRangeFieldResponse<
- TEnableAccessibleFieldDOMStructure extends boolean,
- TForwardedProps extends {},
-> {
- startDate: UseFieldResponse;
- endDate: UseFieldResponse;
-}
diff --git a/packages/x-date-pickers-pro/src/internals/hooks/useMultiInputRangeField/useMultiInputTimeRangeField.ts b/packages/x-date-pickers-pro/src/internals/hooks/useMultiInputRangeField/useMultiInputTimeRangeField.ts
deleted file mode 100644
index 33c54bae45ae1..0000000000000
--- a/packages/x-date-pickers-pro/src/internals/hooks/useMultiInputRangeField/useMultiInputTimeRangeField.ts
+++ /dev/null
@@ -1,149 +0,0 @@
-import useEventCallback from '@mui/utils/useEventCallback';
-import { unstable_useTimeField as useTimeField } from '@mui/x-date-pickers/TimeField';
-import {
- FieldChangeHandler,
- FieldChangeHandlerContext,
- PickerRangeValue,
- PickerValue,
- UseFieldResponse,
- useControlledValueWithTimezone,
- useFieldInternalPropsWithDefaults,
-} from '@mui/x-date-pickers/internals';
-import { useValidation } from '@mui/x-date-pickers/validation';
-import { TimeValidationError } from '@mui/x-date-pickers/models';
-import { UseMultiInputTimeRangeFieldParams } from '../../../MultiInputTimeRangeField/MultiInputTimeRangeField.types';
-import { validateTimeRange } from '../../../validation';
-import { rangeValueManager } from '../../utils/valueManagers';
-import type { UseMultiInputRangeFieldResponse } from './useMultiInputRangeField.types';
-import { TimeRangeValidationError } from '../../../models';
-import { useMultiInputFieldSelectedSections } from '../useMultiInputFieldSelectedSections';
-import { useTimeRangeManager } from '../../../managers';
-
-export const useMultiInputTimeRangeField = <
- TEnableAccessibleFieldDOMStructure extends boolean,
- TTextFieldSlotProps extends {},
->({
- sharedProps,
- startTextFieldProps,
- unstableStartFieldRef,
- endTextFieldProps,
- unstableEndFieldRef,
-}: UseMultiInputTimeRangeFieldParams<
- TEnableAccessibleFieldDOMStructure,
- TTextFieldSlotProps
->): UseMultiInputRangeFieldResponse => {
- const manager = useTimeRangeManager(sharedProps);
- const sharedPropsWithDefaults = useFieldInternalPropsWithDefaults({
- manager,
- internalProps: sharedProps,
- });
-
- const {
- value: valueProp,
- defaultValue,
- referenceDate,
- format,
- formatDensity,
- shouldRespectLeadingZeros,
- onChange,
- disabled,
- readOnly,
- selectedSections,
- onSelectedSectionsChange,
- timezone: timezoneProp,
- enableAccessibleFieldDOMStructure,
- autoFocus,
- } = sharedPropsWithDefaults;
-
- const { value, handleValueChange, timezone } = useControlledValueWithTimezone({
- name: 'useMultiInputTimeRangeField',
- timezone: timezoneProp,
- value: valueProp,
- defaultValue,
- onChange,
- valueManager: rangeValueManager,
- referenceDate,
- });
-
- const { validationError, getValidationErrorForNewValue } = useValidation({
- props: sharedPropsWithDefaults,
- value,
- timezone,
- validator: validateTimeRange,
- onError: sharedPropsWithDefaults.onError,
- });
-
- // TODO: Maybe export utility from `useField` instead of copy/pasting the logic
- const buildChangeHandler = (
- index: 0 | 1,
- ): FieldChangeHandler => {
- return (newDate, rawContext) => {
- const newDateRange: PickerRangeValue =
- index === 0 ? [newDate, value[1]] : [value[0], newDate];
-
- const context: FieldChangeHandlerContext = {
- ...rawContext,
- validationError: getValidationErrorForNewValue(newDateRange),
- };
-
- handleValueChange(newDateRange, context);
- };
- };
-
- const handleStartDateChange = useEventCallback(buildChangeHandler(0));
- const handleEndDateChange = useEventCallback(buildChangeHandler(1));
-
- const selectedSectionsResponse = useMultiInputFieldSelectedSections({
- selectedSections,
- onSelectedSectionsChange,
- unstableStartFieldRef,
- unstableEndFieldRef,
- });
-
- const startFieldProps = {
- error: !!validationError[0],
- ...startTextFieldProps,
- ...selectedSectionsResponse.start,
- disabled,
- readOnly,
- format,
- formatDensity,
- shouldRespectLeadingZeros,
- timezone,
- value: valueProp === undefined ? undefined : valueProp[0],
- defaultValue: defaultValue === undefined ? undefined : defaultValue[0],
- onChange: handleStartDateChange,
- enableAccessibleFieldDOMStructure,
- autoFocus, // Do not add on end field.
- };
-
- const endFieldProps = {
- error: !!validationError[1],
- ...endTextFieldProps,
- ...selectedSectionsResponse.end,
- format,
- formatDensity,
- shouldRespectLeadingZeros,
- disabled,
- readOnly,
- timezone,
- value: valueProp === undefined ? undefined : valueProp[1],
- defaultValue: defaultValue === undefined ? undefined : defaultValue[1],
- onChange: handleEndDateChange,
- enableAccessibleFieldDOMStructure,
- };
-
- const startDateResponse = useTimeField<
- TEnableAccessibleFieldDOMStructure,
- typeof startFieldProps
- >(startFieldProps) as UseFieldResponse;
-
- const endDateResponse = useTimeField(
- endFieldProps,
- ) as UseFieldResponse;
-
- return {
- startDate: startDateResponse,
- endDate: endDateResponse,
- };
-};
diff --git a/packages/x-date-pickers-pro/src/internals/models/dateTimeRange.ts b/packages/x-date-pickers-pro/src/internals/models/dateTimeRange.ts
index dddac7c0a86bc..989dc2d7e49af 100644
--- a/packages/x-date-pickers-pro/src/internals/models/dateTimeRange.ts
+++ b/packages/x-date-pickers-pro/src/internals/models/dateTimeRange.ts
@@ -1,28 +1,4 @@
-import { MakeOptional } from '@mui/x-internals/types';
-import {
- UseFieldInternalProps,
- DateOrTimeViewWithMeridiem,
- AmPmProps,
- PickerRangeValue,
-} from '@mui/x-date-pickers/internals';
-import { DateTimeRangeValidationError, RangeFieldSeparatorProps } from '../../models';
-import { ExportedValidateDateTimeRangeProps } from '../../validation/validateDateTimeRange';
-
-export interface UseDateTimeRangeFieldProps
- extends MakeOptional<
- Omit<
- UseFieldInternalProps<
- PickerRangeValue,
- TEnableAccessibleFieldDOMStructure,
- DateTimeRangeValidationError
- >,
- 'unstableFieldRef'
- >,
- 'format'
- >,
- RangeFieldSeparatorProps,
- ExportedValidateDateTimeRangeProps,
- AmPmProps {}
+import { DateOrTimeViewWithMeridiem } from '@mui/x-date-pickers/internals';
export type DateTimeRangePickerView = Exclude;
diff --git a/packages/x-date-pickers-pro/src/internals/models/index.ts b/packages/x-date-pickers-pro/src/internals/models/index.ts
index 58cda92f0c10d..e53e96818e04a 100644
--- a/packages/x-date-pickers-pro/src/internals/models/index.ts
+++ b/packages/x-date-pickers-pro/src/internals/models/index.ts
@@ -1,4 +1,3 @@
export * from './dateRange';
export * from './dateTimeRange';
-export * from './timeRange';
export * from './rangePickerProps';
diff --git a/packages/x-date-pickers-pro/src/internals/models/managers.ts b/packages/x-date-pickers-pro/src/internals/models/managers.ts
new file mode 100644
index 0000000000000..74ac8a47c5350
--- /dev/null
+++ b/packages/x-date-pickers-pro/src/internals/models/managers.ts
@@ -0,0 +1,4 @@
+import { PickerRangeValue } from '@mui/x-date-pickers/internals';
+import { PickerManager } from '@mui/x-date-pickers/models';
+
+export type PickerAnyRangeManager = PickerManager;
diff --git a/packages/x-date-pickers-pro/src/internals/models/timeRange.ts b/packages/x-date-pickers-pro/src/internals/models/timeRange.ts
deleted file mode 100644
index 171ad2c8c7cdb..0000000000000
--- a/packages/x-date-pickers-pro/src/internals/models/timeRange.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-import { MakeOptional } from '@mui/x-internals/types';
-import { UseFieldInternalProps, AmPmProps, PickerRangeValue } from '@mui/x-date-pickers/internals';
-import { TimeRangeValidationError, RangeFieldSeparatorProps } from '../../models';
-import type { ExportedValidateTimeRangeProps } from '../../validation/validateTimeRange';
-
-export interface UseTimeRangeFieldProps
- extends MakeOptional<
- Omit<
- UseFieldInternalProps<
- PickerRangeValue,
- TEnableAccessibleFieldDOMStructure,
- TimeRangeValidationError
- >,
- 'unstableFieldRef'
- >,
- 'format'
- >,
- RangeFieldSeparatorProps,
- ExportedValidateTimeRangeProps,
- AmPmProps {}
diff --git a/packages/x-date-pickers-pro/src/internals/utils/createMultiInputRangeField/createMultiInputRangeField.tsx b/packages/x-date-pickers-pro/src/internals/utils/createMultiInputRangeField/createMultiInputRangeField.tsx
new file mode 100644
index 0000000000000..f25b62d655624
--- /dev/null
+++ b/packages/x-date-pickers-pro/src/internals/utils/createMultiInputRangeField/createMultiInputRangeField.tsx
@@ -0,0 +1,139 @@
+'use client';
+import * as React from 'react';
+import clsx from 'clsx';
+import Stack, { StackProps } from '@mui/material/Stack';
+import MuiTextField from '@mui/material/TextField';
+import Typography from '@mui/material/Typography';
+import { styled, useThemeProps } from '@mui/material/styles';
+import composeClasses from '@mui/utils/composeClasses';
+import useSlotProps from '@mui/utils/useSlotProps';
+import { cleanFieldResponse, useFieldOwnerState } from '@mui/x-date-pickers/internals';
+import { useSplitFieldProps } from '@mui/x-date-pickers/hooks';
+import { PickersTextField } from '@mui/x-date-pickers/PickersTextField';
+import {
+ CreateMultiInputRangeFieldParameters,
+ CreateMultiInputRangeFieldReturnValue,
+ MultiInputRangeFieldProps,
+} from './createMultiInputRangeField.types';
+import { useMultiInputRangeField } from '../../../hooks/useMultiInputRangeField';
+import { PickerAnyRangeManager } from '../../models/managers';
+
+export function createMultiInputRangeField({
+ useManager,
+ name,
+ getUtilityClass,
+}: CreateMultiInputRangeFieldParameters): CreateMultiInputRangeFieldReturnValue {
+ const useUtilityClasses = (classes: MultiInputRangeFieldProps['classes']) => {
+ const slots = {
+ root: ['root'],
+ separator: ['separator'],
+ };
+
+ return composeClasses(slots, getUtilityClass, classes);
+ };
+
+ const MultiInputRangeFieldRoot = styled(
+ React.forwardRef((props: StackProps, ref: React.Ref) => (
+
+ )),
+ {
+ name,
+ slot: 'Root',
+ overridesResolver: (props, styles) => styles.root,
+ },
+ )({});
+
+ const MultiInputRangeFieldSeparator = styled(Typography, {
+ name,
+ slot: 'Separator',
+ overridesResolver: (props, styles) => styles.separator,
+ })({
+ lineHeight: '1.4375em', // 23px
+ });
+
+ const MultiInputRangeField = React.forwardRef(function MultiInputRangeField(
+ props: MultiInputRangeFieldProps,
+ ref: React.Ref,
+ ) {
+ const themeProps = useThemeProps({
+ props,
+ // eslint-disable-next-line material-ui/mui-name-matches-component-name
+ name,
+ });
+
+ const manager = useManager({
+ enableAccessibleFieldDOMStructure: props.enableAccessibleFieldDOMStructure,
+ dateSeparator: props.dateSeparator,
+ });
+ const { internalProps, forwardedProps } = useSplitFieldProps(themeProps, manager.valueType);
+
+ const {
+ slots,
+ slotProps,
+ className,
+ classes: classesProp,
+ ...otherForwardedProps
+ } = forwardedProps;
+
+ const classes = useUtilityClasses(classesProp);
+ const ownerState = useFieldOwnerState(internalProps as any);
+
+ const Root = slots?.root ?? MultiInputRangeFieldRoot;
+ const rootProps = useSlotProps({
+ elementType: Root,
+ externalSlotProps: slotProps?.root,
+ externalForwardedProps: otherForwardedProps,
+ additionalProps: { ref },
+ ownerState,
+ className: clsx(className, classes.root),
+ });
+
+ const startTextFieldProps = useSlotProps({
+ elementType: PickersTextField,
+ externalSlotProps: slotProps?.textField,
+ ownerState: { ...ownerState, position: 'start' },
+ });
+ const endTextFieldProps = useSlotProps({
+ elementType: PickersTextField,
+ externalSlotProps: slotProps?.textField,
+ ownerState: { ...ownerState, position: 'end' },
+ });
+
+ const { startDate, endDate, enableAccessibleFieldDOMStructure } = useMultiInputRangeField({
+ manager,
+ internalProps,
+ startForwardedProps: startTextFieldProps,
+ endForwardedProps: endTextFieldProps,
+ });
+
+ const Separator = slots?.separator ?? MultiInputRangeFieldSeparator;
+ const separatorProps = useSlotProps({
+ elementType: Separator,
+ externalSlotProps: slotProps?.separator,
+ additionalProps: {
+ children: internalProps.dateSeparator ?? '–',
+ },
+ ownerState,
+ className: classes.separator,
+ });
+
+ const { textFieldProps: startDateProps } = cleanFieldResponse(startDate);
+ const { textFieldProps: endDateProps } = cleanFieldResponse(endDate);
+
+ const TextField =
+ slots?.textField ??
+ (enableAccessibleFieldDOMStructure === false ? MuiTextField : PickersTextField);
+
+ return (
+
+
+
+
+
+ );
+ } as any) as any;
+
+ MultiInputRangeField.fieldType = 'multi-input';
+
+ return MultiInputRangeField;
+}
diff --git a/packages/x-date-pickers-pro/src/internals/utils/createMultiInputRangeField/createMultiInputRangeField.types.ts b/packages/x-date-pickers-pro/src/internals/utils/createMultiInputRangeField/createMultiInputRangeField.types.ts
new file mode 100644
index 0000000000000..fbffbb8f9328a
--- /dev/null
+++ b/packages/x-date-pickers-pro/src/internals/utils/createMultiInputRangeField/createMultiInputRangeField.types.ts
@@ -0,0 +1,96 @@
+import type { TypographyProps } from '@mui/material/Typography';
+import type { StackProps } from '@mui/material/Stack';
+import type { TextFieldProps } from '@mui/material/TextField';
+import { SlotComponentPropsFromProps } from '@mui/x-internals/types';
+import { PickersTextFieldProps } from '@mui/x-date-pickers/PickersTextField';
+import { FieldOwnerState } from '@mui/x-date-pickers/models';
+import {
+ PickerManagerEnableAccessibleFieldDOMStructure,
+ PickerManagerFieldInternalProps,
+} from '@mui/x-date-pickers/internals';
+import {
+ FieldType,
+ MultiInputFieldRefs,
+ RangeFieldSeparatorProps,
+ RangePosition,
+} from '../../../models';
+import { PickerAnyRangeManager } from '../../models/managers';
+
+export type MultiInputRangeFieldProps =
+ MultiInputFieldRefs &
+ RangeFieldSeparatorProps &
+ Omit, 'unstableFieldRef' | 'clearable' | 'onClear'> &
+ Omit> & {
+ /**
+ * If `true`, the field is focused during the first mount.
+ * @default false
+ */
+ autoFocus?: boolean;
+ className?: string;
+ /**
+ * Override or extend the styles applied to the component.
+ */
+ classes?: Partial;
+ /**
+ * Overridable component slots.
+ * @default {}
+ */
+ slots?: MultiInputRangeFieldSlots;
+ /**
+ * The props used for each component slot.
+ * @default {}
+ */
+ slotProps?: MultiInputRangeFieldSlotProps;
+ };
+
+export interface MultiInputRangeFieldSlots {
+ /**
+ * Element rendered at the root.
+ * @default MultiInputRangeFieldRoot
+ */
+ root?: React.ElementType;
+ /**
+ * Form control with an input to render a date.
+ * It is rendered twice: once for the start date and once for the end date.
+ * @default , or from '@mui/material' if `enableAccessibleFieldDOMStructure` is `false`.
+ */
+ textField?: React.ElementType;
+ /**
+ * Element rendered between the two inputs.
+ * @default MultiInputRangeFieldSeparator
+ */
+ separator?: React.ElementType;
+}
+
+export interface MultiInputRangeFieldSlotProps {
+ root?: SlotComponentPropsFromProps;
+ textField?: SlotComponentPropsFromProps<
+ PickersTextFieldProps | TextFieldProps,
+ {},
+ FieldOwnerState & {
+ position: RangePosition;
+ }
+ >;
+ separator?: SlotComponentPropsFromProps;
+}
+
+export interface MultiInputRangeFieldClasses {
+ /** Styles applied to the root element. */
+ root: string;
+ /** Styles applied to the separator element. */
+ separator: string;
+}
+
+export interface CreateMultiInputRangeFieldParameters {
+ name: string;
+ getUtilityClass: (slot: string) => string;
+ useManager: (
+ params: RangeFieldSeparatorProps & {
+ enableAccessibleFieldDOMStructure: PickerManagerEnableAccessibleFieldDOMStructure;
+ },
+ ) => TManager;
+}
+
+export type CreateMultiInputRangeFieldReturnValue = ((
+ props: MultiInputRangeFieldProps & React.RefAttributes,
+) => React.JSX.Element) & { fieldType?: FieldType };
diff --git a/packages/x-date-pickers-pro/src/internals/utils/createMultiInputRangeField/index.ts b/packages/x-date-pickers-pro/src/internals/utils/createMultiInputRangeField/index.ts
new file mode 100644
index 0000000000000..0fde2f8501e65
--- /dev/null
+++ b/packages/x-date-pickers-pro/src/internals/utils/createMultiInputRangeField/index.ts
@@ -0,0 +1,9 @@
+export { createMultiInputRangeField } from './createMultiInputRangeField';
+export type {
+ MultiInputRangeFieldProps,
+ MultiInputRangeFieldSlots,
+ MultiInputRangeFieldSlotProps,
+ MultiInputRangeFieldClasses,
+} from './createMultiInputRangeField.types';
+
+export { useMultiInputRangeField as unstable_useMultiInputRangeField } from '../../../hooks/useMultiInputRangeField/useMultiInputRangeField';
diff --git a/packages/x-date-pickers-pro/src/managers/index.ts b/packages/x-date-pickers-pro/src/managers/index.ts
index 07a939c8a1be5..b5f8aa4f35d27 100644
--- a/packages/x-date-pickers-pro/src/managers/index.ts
+++ b/packages/x-date-pickers-pro/src/managers/index.ts
@@ -2,16 +2,19 @@ export { useDateRangeManager } from './useDateRangeManager';
export type {
UseDateRangeManagerReturnValue,
UseDateRangeManagerParameters,
+ DateRangeManagerFieldInternalProps,
} from './useDateRangeManager';
export { useTimeRangeManager } from './useTimeRangeManager';
export type {
UseTimeRangeManagerReturnValue,
UseTimeRangeManagerParameters,
+ TimeRangeManagerFieldInternalProps,
} from './useTimeRangeManager';
export { useDateTimeRangeManager } from './useDateTimeRangeManager';
export type {
UseDateTimeRangeManagerReturnValue,
UseDateTimeRangeManagerParameters,
+ DateTimeRangeManagerFieldInternalProps,
} from './useDateTimeRangeManager';
diff --git a/packages/x-date-pickers-pro/src/managers/useDateRangeManager.ts b/packages/x-date-pickers-pro/src/managers/useDateRangeManager.ts
index 4e08aeaee8301..02a5dc432e4ae 100644
--- a/packages/x-date-pickers-pro/src/managers/useDateRangeManager.ts
+++ b/packages/x-date-pickers-pro/src/managers/useDateRangeManager.ts
@@ -55,8 +55,9 @@ export type UseDateRangeManagerReturnValue
>;
-interface DateRangeManagerFieldInternalProps
- extends MakeOptional<
+export interface DateRangeManagerFieldInternalProps<
+ TEnableAccessibleFieldDOMStructure extends boolean,
+> extends MakeOptional<
UseFieldInternalProps<
PickerRangeValue,
TEnableAccessibleFieldDOMStructure,
diff --git a/packages/x-date-pickers-pro/src/managers/useDateTimeRangeManager.ts b/packages/x-date-pickers-pro/src/managers/useDateTimeRangeManager.ts
index dd99267e4f869..b1beb5e12b903 100644
--- a/packages/x-date-pickers-pro/src/managers/useDateTimeRangeManager.ts
+++ b/packages/x-date-pickers-pro/src/managers/useDateTimeRangeManager.ts
@@ -57,8 +57,9 @@ export type UseDateTimeRangeManagerReturnValue
>;
-interface DateTimeRangeManagerFieldInternalProps
- extends MakeOptional<
+export interface DateTimeRangeManagerFieldInternalProps<
+ TEnableAccessibleFieldDOMStructure extends boolean,
+> extends MakeOptional<
UseFieldInternalProps<
PickerRangeValue,
TEnableAccessibleFieldDOMStructure,
diff --git a/packages/x-date-pickers-pro/src/managers/useTimeRangeManager.ts b/packages/x-date-pickers-pro/src/managers/useTimeRangeManager.ts
index 4563793170fec..72a582f2f01c4 100644
--- a/packages/x-date-pickers-pro/src/managers/useTimeRangeManager.ts
+++ b/packages/x-date-pickers-pro/src/managers/useTimeRangeManager.ts
@@ -56,8 +56,9 @@ export type UseTimeRangeManagerReturnValue
>;
-interface TimeRangeManagerFieldInternalProps
- extends MakeOptional<
+export interface TimeRangeManagerFieldInternalProps<
+ TEnableAccessibleFieldDOMStructure extends boolean,
+> extends MakeOptional<
UseFieldInternalProps<
PickerRangeValue,
TEnableAccessibleFieldDOMStructure,
diff --git a/packages/x-date-pickers-pro/src/models/dateRange.ts b/packages/x-date-pickers-pro/src/models/dateRange.ts
deleted file mode 100644
index 0e29e30990cc1..0000000000000
--- a/packages/x-date-pickers-pro/src/models/dateRange.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-import { MakeOptional } from '@mui/x-internals/types';
-import { PickerRangeValue, UseFieldInternalProps } from '@mui/x-date-pickers/internals';
-import { RangeFieldSeparatorProps } from './fields';
-import { DateRangeValidationError } from './validation';
-import type { ExportedValidateDateRangeProps } from '../validation/validateDateRange';
-
-export interface UseDateRangeFieldProps
- extends MakeOptional<
- Omit<
- UseFieldInternalProps<
- PickerRangeValue,
- TEnableAccessibleFieldDOMStructure,
- DateRangeValidationError
- >,
- 'unstableFieldRef'
- >,
- 'format'
- >,
- RangeFieldSeparatorProps,
- ExportedValidateDateRangeProps {}
diff --git a/packages/x-date-pickers-pro/src/models/index.ts b/packages/x-date-pickers-pro/src/models/index.ts
index f3b7d852521cc..13f5f47a95c70 100644
--- a/packages/x-date-pickers-pro/src/models/index.ts
+++ b/packages/x-date-pickers-pro/src/models/index.ts
@@ -1,7 +1,5 @@
-export * from './dateRange';
export * from './fields';
export * from './range';
export * from './validation';
-export * from './multiInputRangeFieldClasses';
export type { RangePosition } from '@mui/x-date-pickers/internals';
diff --git a/packages/x-date-pickers-pro/src/models/multiInputRangeFieldClasses.ts b/packages/x-date-pickers-pro/src/models/multiInputRangeFieldClasses.ts
deleted file mode 100644
index 6fd1999a0bd74..0000000000000
--- a/packages/x-date-pickers-pro/src/models/multiInputRangeFieldClasses.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-export interface MultiInputRangeFieldClasses {
- /** Styles applied to the root element. */
- root: string;
- /** Styles applied to the separator element. */
- separator: string;
-}
-
-export type MultiInputRangeFieldClassKey = keyof MultiInputRangeFieldClasses;
diff --git a/packages/x-date-pickers-pro/src/themeAugmentation/overrides.d.ts b/packages/x-date-pickers-pro/src/themeAugmentation/overrides.d.ts
index 8b53b859f7c33..5c894cf2c3aab 100644
--- a/packages/x-date-pickers-pro/src/themeAugmentation/overrides.d.ts
+++ b/packages/x-date-pickers-pro/src/themeAugmentation/overrides.d.ts
@@ -1,11 +1,13 @@
import { DateRangePickerDayClassKey } from '../DateRangePickerDay';
import { DateRangeCalendarClassKey } from '../DateRangeCalendar';
import { DateRangePickerToolbarClassKey } from '../DateRangePicker';
-import { MultiInputRangeFieldClassKey } from '../models';
import {
DateTimeRangePickerTabsClassKey,
DateTimeRangePickerToolbarClassKey,
} from '../DateTimeRangePicker';
+import { MultiInputDateRangeFieldClassKey } from '../MultiInputDateRangeField';
+import { MultiInputDateTimeRangeFieldClassKey } from '../MultiInputDateTimeRangeField';
+import { MultiInputTimeRangeFieldClassKey } from '../MultiInputTimeRangeField';
// prettier-ignore
export interface PickersProComponentNameToClassKey {
@@ -17,9 +19,9 @@ export interface PickersProComponentNameToClassKey {
MuiDateTimeRangePickerToolbar: DateTimeRangePickerToolbarClassKey;
// Multi input range fields
- MuiMultiInputDateRangeField: MultiInputRangeFieldClassKey;
- MuiMultiInputDateTimeRangeField: MultiInputRangeFieldClassKey;
- MuiMultiInputTimeRangeField: MultiInputRangeFieldClassKey;
+ MuiMultiInputDateRangeField: MultiInputDateRangeFieldClassKey;
+ MuiMultiInputDateTimeRangeField: MultiInputDateTimeRangeFieldClassKey;
+ MuiMultiInputTimeRangeField: MultiInputTimeRangeFieldClassKey;
}
declare module '@mui/material/styles' {
diff --git a/packages/x-date-pickers-pro/src/themeAugmentation/props.d.ts b/packages/x-date-pickers-pro/src/themeAugmentation/props.d.ts
index c2254363c7acd..51ad2f83c479b 100644
--- a/packages/x-date-pickers-pro/src/themeAugmentation/props.d.ts
+++ b/packages/x-date-pickers-pro/src/themeAugmentation/props.d.ts
@@ -1,14 +1,14 @@
import { DateRangePickerDayProps } from '../DateRangePickerDay';
-import { MultiInputDateRangeFieldProps } from '../MultiInputDateRangeField/MultiInputDateRangeField.types';
-import { SingleInputDateRangeFieldProps } from '../SingleInputDateRangeField/SingleInputDateRangeField.types';
import { DateRangeCalendarProps } from '../DateRangeCalendar';
import { DateRangePickerProps } from '../DateRangePicker';
import { ExportedDateRangePickerToolbarProps } from '../DateRangePicker/DateRangePickerToolbar';
import { DesktopDateRangePickerProps } from '../DesktopDateRangePicker';
import { MobileDateRangePickerProps } from '../MobileDateRangePicker';
import { StaticDateRangePickerProps } from '../StaticDateRangePicker';
+import { MultiInputDateRangeFieldProps } from '../MultiInputDateRangeField';
import { MultiInputDateTimeRangeFieldProps } from '../MultiInputDateTimeRangeField';
import { MultiInputTimeRangeFieldProps } from '../MultiInputTimeRangeField';
+import { SingleInputDateRangeFieldProps } from '../SingleInputDateRangeField';
import { SingleInputDateTimeRangeFieldProps } from '../SingleInputDateTimeRangeField';
import { SingleInputTimeRangeFieldProps } from '../SingleInputTimeRangeField';
import { DateTimeRangePickerProps } from '../DateTimeRangePicker';
diff --git a/packages/x-date-pickers/src/hooks/useSplitFieldProps.ts b/packages/x-date-pickers/src/hooks/useSplitFieldProps.ts
index 7e1ca2953b58d..e256af657f3bc 100644
--- a/packages/x-date-pickers/src/hooks/useSplitFieldProps.ts
+++ b/packages/x-date-pickers/src/hooks/useSplitFieldProps.ts
@@ -20,10 +20,13 @@ const SHARED_FIELD_INTERNAL_PROP_NAMES = [
'selectedSections',
'onSelectedSectionsChange',
'unstableFieldRef',
+ 'unstableStartFieldRef',
+ 'unstableEndFieldRef',
'enableAccessibleFieldDOMStructure',
'disabled',
'readOnly',
'dateSeparator',
+ 'autoFocus',
] as const;
type InternalPropNames =
@@ -37,7 +40,7 @@ type InternalPropNames =
* - `internalProps` which are used by the various hooks called by the field component.
* - `forwardedProps` which are passed to the underlying component.
* Note that some forwarded props might be used by the hooks as well.
- * For instance, hooks like `useDateField` need props like `autoFocus` to know how to behave.
+ * For instance, hooks like `useDateField` need props like `onKeyDown` to merge the default event handler and the one provided by the application.
* @template TProps, TValueType
* @param {TProps} props The props received by the field component.
* @param {TValueType} valueType The type of the field value ('date', 'time', or 'date-time').
@@ -51,7 +54,7 @@ export const useSplitFieldProps = <
) => {
return React.useMemo(() => {
const forwardedProps = { ...props } as Omit>;
- const internalProps = {} as Pick>;
+ const internalProps = {} as ExtractInternalProps;
const extractProp = (propName: string) => {
if (forwardedProps.hasOwnProperty(propName)) {
@@ -76,3 +79,12 @@ export const useSplitFieldProps = <
return { forwardedProps, internalProps };
}, [props, valueType]);
};
+
+/**
+ * Extract the internal props from the props received by the field component.
+ * This makes sure that the internal props not defined in the props are not present in the result.
+ */
+type ExtractInternalProps<
+ TValueType extends PickerValueType,
+ TProps extends { [key in InternalPropNames]?: any },
+> = { [K in keyof TProps]: K extends InternalPropNames ? TProps[K] : never };
diff --git a/packages/x-date-pickers/src/internals/components/PickerFieldUI.tsx b/packages/x-date-pickers/src/internals/components/PickerFieldUI.tsx
index 3f78963434412..dd09ac31ff41b 100644
--- a/packages/x-date-pickers/src/internals/components/PickerFieldUI.tsx
+++ b/packages/x-date-pickers/src/internals/components/PickerFieldUI.tsx
@@ -6,7 +6,7 @@ import MuiIconButton, { IconButtonProps } from '@mui/material/IconButton';
import MuiInputAdornment, { InputAdornmentProps } from '@mui/material/InputAdornment';
import { SvgIconProps } from '@mui/material/SvgIcon';
import useSlotProps from '@mui/utils/useSlotProps';
-import { SlotComponentPropsFromProps } from '@mui/x-internals/types';
+import { MakeOptional, SlotComponentPropsFromProps } from '@mui/x-internals/types';
import { FieldOwnerState } from '../../models';
import { useFieldOwnerState, UseFieldOwnerStateParameters } from '../hooks/useFieldOwnerState';
import { usePickerTranslations } from '../../hooks';
@@ -16,7 +16,10 @@ import type { UseFieldResponse } from '../hooks/useField';
import { PickersTextField, PickersTextFieldProps } from '../../PickersTextField';
export const cleanFieldResponse = <
- TFieldResponse extends UseFieldResponse,
+ TFieldResponse extends MakeOptional<
+ UseFieldResponse,
+ 'onClear' | 'clearable'
+ >,
>({
enableAccessibleFieldDOMStructure,
...fieldResponse
diff --git a/packages/x-date-pickers/src/internals/hooks/useField/useField.ts b/packages/x-date-pickers/src/internals/hooks/useField/useField.ts
index 3f92bef606d7b..20c19b1e83602 100644
--- a/packages/x-date-pickers/src/internals/hooks/useField/useField.ts
+++ b/packages/x-date-pickers/src/internals/hooks/useField/useField.ts
@@ -47,6 +47,7 @@ export const useField = <
enableAccessibleFieldDOMStructure = true,
disabled = false,
readOnly = false,
+ autoFocus = false,
},
forwardedProps: { onKeyDown, error, clearable, onClear },
fieldValueManager,
@@ -289,6 +290,7 @@ export const useField = <
const commonAdditionalProps: UseFieldCommonAdditionalProps = {
disabled,
readOnly,
+ autoFocus,
openPickerAriaLabel,
};
diff --git a/packages/x-date-pickers/src/internals/hooks/useField/useField.types.ts b/packages/x-date-pickers/src/internals/hooks/useField/useField.types.ts
index 2b9dbd7d3598c..f9cc1c0856f72 100644
--- a/packages/x-date-pickers/src/internals/hooks/useField/useField.types.ts
+++ b/packages/x-date-pickers/src/internals/hooks/useField/useField.types.ts
@@ -126,7 +126,9 @@ export interface UseFieldInternalProps<
}
export interface UseFieldCommonAdditionalProps
- extends Required, 'disabled' | 'readOnly'>> {
+ extends Required<
+ Pick, 'disabled' | 'readOnly' | 'autoFocus'>
+ > {
/**
* The aria label to set on the button that opens the picker.
*/
@@ -166,7 +168,6 @@ interface UseFieldV6AdditionalProps
export interface UseFieldV7ForwardedProps {
focused?: boolean;
- autoFocus?: boolean;
sectionListRef?: React.Ref;
onBlur?: () => void;
onClick?: React.MouseEventHandler;
diff --git a/packages/x-date-pickers/src/internals/hooks/useField/useFieldV7TextField.ts b/packages/x-date-pickers/src/internals/hooks/useField/useFieldV7TextField.ts
index 0a54c6bef5dc5..806cc8e6cabb4 100644
--- a/packages/x-date-pickers/src/internals/hooks/useField/useFieldV7TextField.ts
+++ b/packages/x-date-pickers/src/internals/hooks/useField/useFieldV7TextField.ts
@@ -16,7 +16,7 @@ import { useUtils } from '../useUtils';
export const useFieldV7TextField: UseFieldTextField = (params) => {
const {
- internalProps: { disabled, readOnly = false },
+ internalProps: { disabled, readOnly = false, autoFocus = false },
forwardedProps: {
sectionListRef: inSectionListRef,
onBlur,
@@ -25,7 +25,6 @@ export const useFieldV7TextField: UseFieldTextField = (params) => {
onInput,
onPaste,
focused: focusedProp,
- autoFocus = false,
},
fieldValueManager,
applyCharacterEditing,
diff --git a/packages/x-date-pickers/src/internals/index.ts b/packages/x-date-pickers/src/internals/index.ts
index 85394bf31fdd6..6d138c66b4d30 100644
--- a/packages/x-date-pickers/src/internals/index.ts
+++ b/packages/x-date-pickers/src/internals/index.ts
@@ -114,6 +114,12 @@ export type { ExportedUseViewsOptions, UseViewsOptions } from './hooks/useViews'
export { useViews } from './hooks/useViews';
export { usePreviousMonthDisabled, useNextMonthDisabled } from './hooks/date-helpers-hooks';
+export type {
+ PickerAnyManager,
+ PickerManagerFieldInternalProps,
+ PickerManagerEnableAccessibleFieldDOMStructure,
+ PickerManagerError,
+} from './models/manager';
export type { RangePosition } from './models/pickers';
export type { BaseSingleInputFieldProps, FieldRangeSection } from './models/fields';
export type { BasePickerProps, BasePickerInputProps } from './models/props/basePickerProps';
diff --git a/packages/x-date-pickers/src/internals/models/manager.ts b/packages/x-date-pickers/src/internals/models/manager.ts
index 135e3177648f5..13842fa8468b1 100644
--- a/packages/x-date-pickers/src/internals/models/manager.ts
+++ b/packages/x-date-pickers/src/internals/models/manager.ts
@@ -30,3 +30,6 @@ export type PickerManagerFieldInternalProps =
export type PickerManagerFieldInternalPropsWithDefaults =
PickerManagerProperties['fieldInternalPropsWithDefaults'];
+
+export type PickerManagerEnableAccessibleFieldDOMStructure =
+ PickerManagerProperties['enableAccessibleFieldDOMStructure'];
diff --git a/packages/x-date-pickers/src/managers/index.ts b/packages/x-date-pickers/src/managers/index.ts
index 085026d5225fa..d8f86861b7968 100644
--- a/packages/x-date-pickers/src/managers/index.ts
+++ b/packages/x-date-pickers/src/managers/index.ts
@@ -1,11 +1,20 @@
export { useDateManager } from './useDateManager';
-export type { UseDateManagerReturnValue, UseDateManagerParameters } from './useDateManager';
+export type {
+ UseDateManagerReturnValue,
+ UseDateManagerParameters,
+ DateManagerFieldInternalProps,
+} from './useDateManager';
export { useTimeManager } from './useTimeManager';
-export type { UseTimeManagerReturnValue, UseTimeManagerParameters } from './useTimeManager';
+export type {
+ UseTimeManagerReturnValue,
+ UseTimeManagerParameters,
+ TimeManagerFieldInternalProps,
+} from './useTimeManager';
export { useDateTimeManager } from './useDateTimeManager';
export type {
UseDateTimeManagerReturnValue,
UseDateTimeManagerParameters,
+ DateTimeManagerFieldInternalProps,
} from './useDateTimeManager';
diff --git a/packages/x-date-pickers/src/managers/useDateManager.ts b/packages/x-date-pickers/src/managers/useDateManager.ts
index b99686fbd4d85..415187e9dac8c 100644
--- a/packages/x-date-pickers/src/managers/useDateManager.ts
+++ b/packages/x-date-pickers/src/managers/useDateManager.ts
@@ -74,7 +74,7 @@ export type UseDateManagerReturnValue
>;
-interface DateManagerFieldInternalProps
+export interface DateManagerFieldInternalProps
extends MakeOptional<
UseFieldInternalProps,
'format'
diff --git a/packages/x-date-pickers/src/managers/useDateTimeManager.ts b/packages/x-date-pickers/src/managers/useDateTimeManager.ts
index dc8b37c307152..282ea55e2dad0 100644
--- a/packages/x-date-pickers/src/managers/useDateTimeManager.ts
+++ b/packages/x-date-pickers/src/managers/useDateTimeManager.ts
@@ -92,8 +92,9 @@ export type UseDateTimeManagerReturnValue
>;
-interface DateTimeManagerFieldInternalProps
- extends MakeOptional<
+export interface DateTimeManagerFieldInternalProps<
+ TEnableAccessibleFieldDOMStructure extends boolean,
+> extends MakeOptional<
UseFieldInternalProps<
PickerValue,
TEnableAccessibleFieldDOMStructure,
diff --git a/packages/x-date-pickers/src/managers/useTimeManager.ts b/packages/x-date-pickers/src/managers/useTimeManager.ts
index 5ce9df999af2c..10acbeb24d153 100644
--- a/packages/x-date-pickers/src/managers/useTimeManager.ts
+++ b/packages/x-date-pickers/src/managers/useTimeManager.ts
@@ -74,7 +74,7 @@ export type UseTimeManagerReturnValue
>;
-interface TimeManagerFieldInternalProps
+export interface TimeManagerFieldInternalProps
extends MakeOptional<
UseFieldInternalProps,
'format'
diff --git a/scripts/x-date-pickers-pro.exports.json b/scripts/x-date-pickers-pro.exports.json
index 7ac4157713712..9b2c60de65c17 100644
--- a/scripts/x-date-pickers-pro.exports.json
+++ b/scripts/x-date-pickers-pro.exports.json
@@ -32,6 +32,7 @@
{ "name": "DateCalendarSlots", "kind": "Interface" },
{ "name": "DateField", "kind": "Variable" },
{ "name": "DateFieldProps", "kind": "TypeAlias" },
+ { "name": "DateManagerFieldInternalProps", "kind": "Interface" },
{ "name": "DateOrTimeView", "kind": "TypeAlias" },
{ "name": "DatePicker", "kind": "Variable" },
{ "name": "DatePickerFieldProps", "kind": "TypeAlias" },
@@ -52,6 +53,7 @@
{ "name": "DateRangeCalendarSlotProps", "kind": "Interface" },
{ "name": "DateRangeCalendarSlots", "kind": "Interface" },
{ "name": "DateRangeIcon", "kind": "Variable" },
+ { "name": "DateRangeManagerFieldInternalProps", "kind": "Interface" },
{ "name": "DateRangePicker", "kind": "Variable" },
{ "name": "DateRangePickerDay", "kind": "Variable" },
{ "name": "dateRangePickerDayClasses", "kind": "Variable" },
@@ -71,6 +73,7 @@
{ "name": "DateRangeViewRendererProps", "kind": "Interface" },
{ "name": "DateTimeField", "kind": "Variable" },
{ "name": "DateTimeFieldProps", "kind": "TypeAlias" },
+ { "name": "DateTimeManagerFieldInternalProps", "kind": "Interface" },
{ "name": "DateTimePicker", "kind": "Variable" },
{ "name": "DateTimePickerFieldProps", "kind": "TypeAlias" },
{ "name": "DateTimePickerProps", "kind": "Interface" },
@@ -86,6 +89,7 @@
{ "name": "DateTimePickerToolbarClasses", "kind": "Interface" },
{ "name": "DateTimePickerToolbarClassKey", "kind": "TypeAlias" },
{ "name": "DateTimePickerToolbarProps", "kind": "Interface" },
+ { "name": "DateTimeRangeManagerFieldInternalProps", "kind": "Interface" },
{ "name": "DateTimeRangePicker", "kind": "Variable" },
{ "name": "DateTimeRangePickerFieldProps", "kind": "TypeAlias" },
{ "name": "DateTimeRangePickerProps", "kind": "Interface" },
@@ -221,18 +225,28 @@
{ "name": "MuiPickersAdapterContext", "kind": "Variable" },
{ "name": "MultiInputDateRangeField", "kind": "Variable" },
{ "name": "multiInputDateRangeFieldClasses", "kind": "Variable" },
+ { "name": "MultiInputDateRangeFieldClasses", "kind": "Interface" },
+ { "name": "MultiInputDateRangeFieldClassKey", "kind": "TypeAlias" },
{ "name": "MultiInputDateRangeFieldProps", "kind": "Interface" },
+ { "name": "MultiInputDateRangeFieldSlotProps", "kind": "Interface" },
+ { "name": "MultiInputDateRangeFieldSlots", "kind": "Interface" },
{ "name": "MultiInputDateTimeRangeField", "kind": "Variable" },
{ "name": "multiInputDateTimeRangeFieldClasses", "kind": "Variable" },
+ { "name": "MultiInputDateTimeRangeFieldClasses", "kind": "Interface" },
+ { "name": "MultiInputDateTimeRangeFieldClassKey", "kind": "TypeAlias" },
{ "name": "MultiInputDateTimeRangeFieldProps", "kind": "Interface" },
+ { "name": "MultiInputDateTimeRangeFieldSlotProps", "kind": "Interface" },
+ { "name": "MultiInputDateTimeRangeFieldSlots", "kind": "Interface" },
{ "name": "MultiInputFieldRefs", "kind": "Interface" },
{ "name": "MultiInputFieldSlotRootProps", "kind": "Interface" },
{ "name": "MultiInputFieldSlotTextFieldProps", "kind": "Interface" },
- { "name": "MultiInputRangeFieldClasses", "kind": "Interface" },
- { "name": "MultiInputRangeFieldClassKey", "kind": "TypeAlias" },
{ "name": "MultiInputTimeRangeField", "kind": "Variable" },
{ "name": "multiInputTimeRangeFieldClasses", "kind": "Variable" },
+ { "name": "MultiInputTimeRangeFieldClasses", "kind": "Interface" },
+ { "name": "MultiInputTimeRangeFieldClassKey", "kind": "TypeAlias" },
{ "name": "MultiInputTimeRangeFieldProps", "kind": "Interface" },
+ { "name": "MultiInputTimeRangeFieldSlotProps", "kind": "Interface" },
+ { "name": "MultiInputTimeRangeFieldSlots", "kind": "Interface" },
{ "name": "MultiSectionDigitalClock", "kind": "Variable" },
{ "name": "multiSectionDigitalClockClasses", "kind": "Variable" },
{ "name": "MultiSectionDigitalClockClasses", "kind": "Interface" },
@@ -371,6 +385,7 @@
{ "name": "TimeField", "kind": "Variable" },
{ "name": "TimeFieldProps", "kind": "TypeAlias" },
{ "name": "TimeIcon", "kind": "Variable" },
+ { "name": "TimeManagerFieldInternalProps", "kind": "Interface" },
{ "name": "TimePicker", "kind": "Variable" },
{ "name": "TimePickerFieldProps", "kind": "TypeAlias" },
{ "name": "TimePickerProps", "kind": "Interface" },
@@ -381,6 +396,7 @@
{ "name": "TimePickerToolbarClasses", "kind": "Interface" },
{ "name": "TimePickerToolbarClassKey", "kind": "TypeAlias" },
{ "name": "TimePickerToolbarProps", "kind": "Interface" },
+ { "name": "TimeRangeManagerFieldInternalProps", "kind": "Interface" },
{ "name": "TimeRangeValidationError", "kind": "TypeAlias" },
{ "name": "TimeStepOptions", "kind": "Interface" },
{ "name": "TimeValidationError", "kind": "TypeAlias" },
@@ -394,9 +410,7 @@
{ "name": "Unstable_PickersSectionListSectionSeparator", "kind": "Variable" },
{ "name": "unstable_useDateField", "kind": "Variable" },
{ "name": "unstable_useDateTimeField", "kind": "Variable" },
- { "name": "unstable_useMultiInputDateRangeField", "kind": "Variable" },
- { "name": "unstable_useMultiInputDateTimeRangeField", "kind": "Variable" },
- { "name": "unstable_useMultiInputTimeRangeField", "kind": "Variable" },
+ { "name": "unstable_useMultiInputRangeField", "kind": "Function" },
{ "name": "unstable_useSingleInputDateRangeField", "kind": "Variable" },
{ "name": "unstable_useSingleInputDateTimeRangeField", "kind": "Variable" },
{ "name": "unstable_useSingleInputTimeRangeField", "kind": "Variable" },
@@ -409,7 +423,6 @@
{ "name": "useDateManager", "kind": "Function" },
{ "name": "UseDateManagerParameters", "kind": "Interface" },
{ "name": "UseDateManagerReturnValue", "kind": "TypeAlias" },
- { "name": "UseDateRangeFieldProps", "kind": "Interface" },
{ "name": "useDateRangeManager", "kind": "Function" },
{ "name": "UseDateRangeManagerParameters", "kind": "Interface" },
{ "name": "UseDateRangeManagerReturnValue", "kind": "TypeAlias" },
@@ -421,12 +434,6 @@
{ "name": "UseDateTimeRangeManagerParameters", "kind": "Interface" },
{ "name": "UseDateTimeRangeManagerReturnValue", "kind": "TypeAlias" },
{ "name": "useIsValidValue", "kind": "Function" },
- { "name": "UseMultiInputDateRangeFieldComponentProps", "kind": "TypeAlias" },
- { "name": "UseMultiInputDateRangeFieldProps", "kind": "Interface" },
- { "name": "UseMultiInputDateTimeRangeFieldComponentProps", "kind": "TypeAlias" },
- { "name": "UseMultiInputDateTimeRangeFieldProps", "kind": "Interface" },
- { "name": "UseMultiInputTimeRangeFieldComponentProps", "kind": "TypeAlias" },
- { "name": "UseMultiInputTimeRangeFieldProps", "kind": "Interface" },
{ "name": "useParsedFormat", "kind": "Variable" },
{ "name": "usePickerActionsContext", "kind": "Variable" },
{ "name": "usePickerContext", "kind": "Variable" },
diff --git a/scripts/x-date-pickers.exports.json b/scripts/x-date-pickers.exports.json
index f39968054d183..08c260e8a3783 100644
--- a/scripts/x-date-pickers.exports.json
+++ b/scripts/x-date-pickers.exports.json
@@ -31,6 +31,7 @@
{ "name": "DateCalendarSlots", "kind": "Interface" },
{ "name": "DateField", "kind": "Variable" },
{ "name": "DateFieldProps", "kind": "TypeAlias" },
+ { "name": "DateManagerFieldInternalProps", "kind": "Interface" },
{ "name": "DateOrTimeView", "kind": "TypeAlias" },
{ "name": "DatePicker", "kind": "Variable" },
{ "name": "DatePickerFieldProps", "kind": "TypeAlias" },
@@ -45,6 +46,7 @@
{ "name": "DateRangeIcon", "kind": "Variable" },
{ "name": "DateTimeField", "kind": "Variable" },
{ "name": "DateTimeFieldProps", "kind": "TypeAlias" },
+ { "name": "DateTimeManagerFieldInternalProps", "kind": "Interface" },
{ "name": "DateTimePicker", "kind": "Variable" },
{ "name": "DateTimePickerFieldProps", "kind": "TypeAlias" },
{ "name": "DateTimePickerProps", "kind": "Interface" },
@@ -271,6 +273,7 @@
{ "name": "TimeField", "kind": "Variable" },
{ "name": "TimeFieldProps", "kind": "TypeAlias" },
{ "name": "TimeIcon", "kind": "Variable" },
+ { "name": "TimeManagerFieldInternalProps", "kind": "Interface" },
{ "name": "TimePicker", "kind": "Variable" },
{ "name": "TimePickerFieldProps", "kind": "TypeAlias" },
{ "name": "TimePickerProps", "kind": "Interface" },