diff --git a/CHANGELOG.md b/CHANGELOG.md
index df079fc9dffd..80650ca0926e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2902,7 +2902,8 @@ Same changes as in `@mui/x-data-grid-pro@7.0.0-beta.4`.
```
- The headless field hooks (e.g.: `useDateField`) now returns a new prop called `enableAccessibleFieldDOMStructure`.
- This property is utilized to determine whether the anticipated UI is constructed using an accessible DOM structure. Learn more about this new [accessible DOM structure](/x/react-date-pickers/fields/#accessible-dom-structure).
+ This property is utilized to determine whether the anticipated UI is constructed using an accessible DOM structure.
+ Learn more about this new accessible DOM structure in the [v8 migration guide](https://next.mui.com/x/migration/migration-pickers-v7/#new-dom-structure-for-the-field).
When building a custom UI, you are most-likely only supporting one DOM structure, so you can remove `enableAccessibleFieldDOMStructure` before it is passed to the DOM:
diff --git a/docs/.link-check-errors.txt b/docs/.link-check-errors.txt
index 6ecc503cc78a..0438fa82a091 100644
--- a/docs/.link-check-errors.txt
+++ b/docs/.link-check-errors.txt
@@ -1,2 +1,3 @@
Broken links found by `docs:link-check` that exist:
+- https://mui.com/x/react-date-pickers/fields/#accessible-dom-structure
diff --git a/docs/data/date-pickers/custom-field/BrowserV6Field.js b/docs/data/date-pickers/custom-field/BrowserV6Field.js
deleted file mode 100644
index 63be3f56e884..000000000000
--- a/docs/data/date-pickers/custom-field/BrowserV6Field.js
+++ /dev/null
@@ -1,90 +0,0 @@
-import * as React from 'react';
-
-import { unstable_useForkRef as useForkRef } from '@mui/utils';
-import Box from '@mui/material/Box';
-import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
-import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
-import { DatePicker } from '@mui/x-date-pickers/DatePicker';
-import { unstable_useDateField as useDateField } from '@mui/x-date-pickers/DateField';
-import { useClearableField } from '@mui/x-date-pickers/hooks';
-
-const BrowserField = React.forwardRef((props, ref) => {
- const {
- // Should be ignored
- enableAccessibleFieldDOMStructure,
- disabled,
- id,
- label,
- inputRef,
- InputProps: { ref: containerRef, startAdornment, endAdornment } = {},
- // extracting `error`, 'focused', and `ownerState` as `input` does not support those props
- error,
- focused,
- ownerState,
- sx,
- ...other
- } = props;
-
- const handleRef = useForkRef(containerRef, ref);
-
- return (
-
- {startAdornment}
-
- {endAdornment}
-
- );
-});
-
-const BrowserDateField = React.forwardRef((props, ref) => {
- const { slots, slotProps, ...textFieldProps } = props;
-
- const fieldResponse = useDateField({
- ...textFieldProps,
- enableAccessibleFieldDOMStructure: false,
- });
-
- /* If you don't need a clear button, you can skip the use of this hook */
- const processedFieldProps = useClearableField({
- ...fieldResponse,
- slots,
- slotProps,
- });
-
- return ;
-});
-
-const BrowserDatePicker = React.forwardRef((props, ref) => {
- return (
-
- );
-});
-
-export default function BrowserV6Field() {
- return (
-
-
-
- );
-}
diff --git a/docs/data/date-pickers/custom-field/BrowserV6Field.tsx b/docs/data/date-pickers/custom-field/BrowserV6Field.tsx
deleted file mode 100644
index 49138cd42863..000000000000
--- a/docs/data/date-pickers/custom-field/BrowserV6Field.tsx
+++ /dev/null
@@ -1,135 +0,0 @@
-import * as React from 'react';
-import { Dayjs } from 'dayjs';
-import { unstable_useForkRef as useForkRef } from '@mui/utils';
-import Box from '@mui/material/Box';
-import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
-import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
-import { DatePicker, DatePickerProps } from '@mui/x-date-pickers/DatePicker';
-import {
- unstable_useDateField as useDateField,
- UseDateFieldProps,
-} from '@mui/x-date-pickers/DateField';
-import { useClearableField } from '@mui/x-date-pickers/hooks';
-import {
- BaseSingleInputFieldProps,
- DateValidationError,
- FieldSection,
-} from '@mui/x-date-pickers/models';
-
-interface BrowserFieldProps
- extends Omit, 'size'> {
- label?: React.ReactNode;
- inputRef?: React.Ref;
- InputProps?: {
- ref?: React.Ref;
- endAdornment?: React.ReactNode;
- startAdornment?: React.ReactNode;
- };
- error?: boolean;
- focused?: boolean;
- ownerState?: any;
- sx?: any;
- enableAccessibleFieldDOMStructure: boolean;
-}
-
-type BrowserFieldComponent = ((
- props: BrowserFieldProps & React.RefAttributes,
-) => React.JSX.Element) & { propTypes?: any };
-
-const BrowserField = React.forwardRef(
- (props: BrowserFieldProps, ref: React.Ref) => {
- const {
- // Should be ignored
- enableAccessibleFieldDOMStructure,
-
- disabled,
- id,
- label,
- inputRef,
- InputProps: { ref: containerRef, startAdornment, endAdornment } = {},
- // extracting `error`, 'focused', and `ownerState` as `input` does not support those props
- error,
- focused,
- ownerState,
- sx,
- ...other
- } = props;
-
- const handleRef = useForkRef(containerRef, ref);
-
- return (
-
- {startAdornment}
-
- {endAdornment}
-
- );
- },
-) as BrowserFieldComponent;
-
-interface BrowserDateFieldProps
- extends UseDateFieldProps,
- BaseSingleInputFieldProps<
- Dayjs | null,
- Dayjs,
- FieldSection,
- false,
- DateValidationError
- > {}
-
-const BrowserDateField = React.forwardRef(
- (props: BrowserDateFieldProps, ref: React.Ref) => {
- const { slots, slotProps, ...textFieldProps } = props;
-
- const fieldResponse = useDateField({
- ...textFieldProps,
- enableAccessibleFieldDOMStructure: false,
- });
-
- /* If you don't need a clear button, you can skip the use of this hook */
- const processedFieldProps = useClearableField({
- ...fieldResponse,
- slots,
- slotProps,
- });
-
- return ;
- },
-);
-
-const BrowserDatePicker = React.forwardRef(
- (props: DatePickerProps, ref: React.Ref) => {
- return (
-
- ref={ref}
- {...props}
- slots={{ ...props.slots, field: BrowserDateField }}
- />
- );
- },
-);
-
-export default function BrowserV6Field() {
- return (
-
-
-
- );
-}
diff --git a/docs/data/date-pickers/custom-field/BrowserV6Field.tsx.preview b/docs/data/date-pickers/custom-field/BrowserV6Field.tsx.preview
deleted file mode 100644
index 0bb9e399d3cb..000000000000
--- a/docs/data/date-pickers/custom-field/BrowserV6Field.tsx.preview
+++ /dev/null
@@ -1,5 +0,0 @@
-
\ No newline at end of file
diff --git a/docs/data/date-pickers/custom-field/BrowserV6MultiInputRangeField.js b/docs/data/date-pickers/custom-field/BrowserV6MultiInputRangeField.js
deleted file mode 100644
index 5421fd0d4348..000000000000
--- a/docs/data/date-pickers/custom-field/BrowserV6MultiInputRangeField.js
+++ /dev/null
@@ -1,140 +0,0 @@
-import * as React from 'react';
-
-import { unstable_useForkRef as useForkRef } from '@mui/utils';
-import useSlotProps from '@mui/utils/useSlotProps';
-import Box from '@mui/material/Box';
-import Stack from '@mui/material/Stack';
-import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
-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';
-
-const BrowserField = React.forwardRef((props, ref) => {
- const {
- // Should be ignored
- enableAccessibleFieldDOMStructure,
- disabled,
- id,
- label,
- inputRef,
- InputProps: { ref: containerRef, startAdornment, endAdornment } = {},
- // extracting `error`, 'focused', and `ownerState` as `input` does not support those props
- error,
- focused,
- ownerState,
- sx,
- ...other
- } = props;
-
- const handleRef = useForkRef(containerRef, ref);
-
- return (
-
- {startAdornment}
-
- {endAdornment}
-
- );
-});
-
-const BrowserMultiInputDateRangeField = React.forwardRef((props, ref) => {
- const {
- slotProps,
- value,
- defaultValue,
- format,
- onChange,
- readOnly,
- disabled,
- onError,
- shouldDisableDate,
- minDate,
- maxDate,
- disableFuture,
- disablePast,
- selectedSections,
- onSelectedSectionsChange,
- className,
- unstableStartFieldRef,
- unstableEndFieldRef,
- } = props;
-
- 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: {
- value,
- defaultValue,
- format,
- onChange,
- readOnly,
- disabled,
- onError,
- shouldDisableDate,
- minDate,
- maxDate,
- disableFuture,
- disablePast,
- selectedSections,
- onSelectedSectionsChange,
- enableAccessibleFieldDOMStructure: false,
- },
- startTextFieldProps,
- endTextFieldProps,
- unstableStartFieldRef,
- unstableEndFieldRef,
- });
-
- return (
-
-
- —
-
-
- );
-});
-
-const BrowserDateRangePicker = React.forwardRef((props, ref) => {
- return (
-
- );
-});
-
-export default function BrowserV6MultiInputRangeField() {
- return (
-
-
-
- );
-}
diff --git a/docs/data/date-pickers/custom-field/BrowserV6MultiInputRangeField.tsx b/docs/data/date-pickers/custom-field/BrowserV6MultiInputRangeField.tsx
deleted file mode 100644
index b52029d14cde..000000000000
--- a/docs/data/date-pickers/custom-field/BrowserV6MultiInputRangeField.tsx
+++ /dev/null
@@ -1,196 +0,0 @@
-import * as React from 'react';
-import { Dayjs } from 'dayjs';
-import { unstable_useForkRef as useForkRef } from '@mui/utils';
-import useSlotProps from '@mui/utils/useSlotProps';
-import Box from '@mui/material/Box';
-import Stack from '@mui/material/Stack';
-import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
-import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
-import {
- DateRangePicker,
- DateRangePickerProps,
-} from '@mui/x-date-pickers-pro/DateRangePicker';
-import { unstable_useMultiInputDateRangeField as useMultiInputDateRangeField } from '@mui/x-date-pickers-pro/MultiInputDateRangeField';
-import {
- BaseMultiInputFieldProps,
- DateRange,
- DateRangeValidationError,
- MultiInputFieldSlotTextFieldProps,
- RangeFieldSection,
- UseDateRangeFieldProps,
-} from '@mui/x-date-pickers-pro/models';
-
-interface BrowserFieldProps
- extends Omit, 'size'> {
- label?: React.ReactNode;
- inputRef?: React.Ref;
- InputProps?: {
- ref?: React.Ref;
- endAdornment?: React.ReactNode;
- startAdornment?: React.ReactNode;
- };
- error?: boolean;
- focused?: boolean;
- ownerState?: any;
- sx?: any;
- enableAccessibleFieldDOMStructure: boolean;
-}
-
-type BrowserFieldComponent = ((
- props: BrowserFieldProps & React.RefAttributes,
-) => React.JSX.Element) & { propTypes?: any };
-
-const BrowserField = React.forwardRef(
- (props: BrowserFieldProps, ref: React.Ref) => {
- const {
- // Should be ignored
- enableAccessibleFieldDOMStructure,
-
- disabled,
- id,
- label,
- inputRef,
- InputProps: { ref: containerRef, startAdornment, endAdornment } = {},
- // extracting `error`, 'focused', and `ownerState` as `input` does not support those props
- error,
- focused,
- ownerState,
- sx,
- ...other
- } = props;
-
- const handleRef = useForkRef(containerRef, ref);
-
- return (
-
- {startAdornment}
-
- {endAdornment}
-
- );
- },
-) as BrowserFieldComponent;
-
-interface BrowserMultiInputDateRangeFieldProps
- extends UseDateRangeFieldProps,
- BaseMultiInputFieldProps<
- DateRange,
- Dayjs,
- RangeFieldSection,
- false,
- DateRangeValidationError
- > {}
-
-type BrowserMultiInputDateRangeFieldComponent = ((
- props: BrowserMultiInputDateRangeFieldProps & React.RefAttributes,
-) => React.JSX.Element) & { propTypes?: any };
-
-const BrowserMultiInputDateRangeField = React.forwardRef(
- (props: BrowserMultiInputDateRangeFieldProps, ref: React.Ref) => {
- const {
- slotProps,
- value,
- defaultValue,
- format,
- onChange,
- readOnly,
- disabled,
- onError,
- shouldDisableDate,
- minDate,
- maxDate,
- disableFuture,
- disablePast,
- selectedSections,
- onSelectedSectionsChange,
- className,
- unstableStartFieldRef,
- unstableEndFieldRef,
- } = props;
-
- const startTextFieldProps = useSlotProps({
- elementType: 'input',
- externalSlotProps: slotProps?.textField,
- ownerState: { ...props, position: 'start' },
- }) as MultiInputFieldSlotTextFieldProps;
-
- const endTextFieldProps = useSlotProps({
- elementType: 'input',
- externalSlotProps: slotProps?.textField,
- ownerState: { ...props, position: 'end' },
- }) as MultiInputFieldSlotTextFieldProps;
-
- const fieldResponse = useMultiInputDateRangeField<
- Dayjs,
- false,
- MultiInputFieldSlotTextFieldProps
- >({
- sharedProps: {
- value,
- defaultValue,
- format,
- onChange,
- readOnly,
- disabled,
- onError,
- shouldDisableDate,
- minDate,
- maxDate,
- disableFuture,
- disablePast,
- selectedSections,
- onSelectedSectionsChange,
- enableAccessibleFieldDOMStructure: false,
- },
- startTextFieldProps,
- endTextFieldProps,
- unstableStartFieldRef,
- unstableEndFieldRef,
- });
-
- return (
-
-
- —
-
-
- );
- },
-) as BrowserMultiInputDateRangeFieldComponent;
-
-const BrowserDateRangePicker = React.forwardRef(
- (props: DateRangePickerProps, ref: React.Ref) => {
- return (
-
- );
- },
-);
-
-export default function BrowserV6MultiInputRangeField() {
- return (
-
-
-
- );
-}
diff --git a/docs/data/date-pickers/custom-field/BrowserV6MultiInputRangeField.tsx.preview b/docs/data/date-pickers/custom-field/BrowserV6MultiInputRangeField.tsx.preview
deleted file mode 100644
index d797406fa999..000000000000
--- a/docs/data/date-pickers/custom-field/BrowserV6MultiInputRangeField.tsx.preview
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/docs/data/date-pickers/custom-field/BrowserV6SingleInputRangeField.js b/docs/data/date-pickers/custom-field/BrowserV6SingleInputRangeField.js
deleted file mode 100644
index 311029bbc6fa..000000000000
--- a/docs/data/date-pickers/custom-field/BrowserV6SingleInputRangeField.js
+++ /dev/null
@@ -1,137 +0,0 @@
-import * as React from 'react';
-
-import { unstable_useForkRef as useForkRef } from '@mui/utils';
-import useSlotProps from '@mui/utils/useSlotProps';
-import Box from '@mui/material/Box';
-import IconButton from '@mui/material/IconButton';
-import InputAdornment from '@mui/material/InputAdornment';
-import { DateRangeIcon } from '@mui/x-date-pickers/icons';
-import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
-import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
-import { DateRangePicker } from '@mui/x-date-pickers-pro/DateRangePicker';
-import { unstable_useSingleInputDateRangeField as useSingleInputDateRangeField } from '@mui/x-date-pickers-pro/SingleInputDateRangeField';
-import { useClearableField } from '@mui/x-date-pickers/hooks';
-
-const BrowserField = React.forwardRef((props, ref) => {
- const {
- // Should be ignored
- enableAccessibleFieldDOMStructure,
- disabled,
- id,
- label,
- inputRef,
- InputProps: { ref: containerRef, startAdornment, endAdornment } = {},
- // extracting `error`, 'focused', and `ownerState` as `input` does not support those props
- error,
- focused,
- ownerState,
- sx,
- ...other
- } = props;
-
- const handleRef = useForkRef(containerRef, ref);
-
- return (
-
- {startAdornment}
-
- {endAdornment}
-
- );
-});
-
-const BrowserSingleInputDateRangeField = React.forwardRef((props, ref) => {
- const { slots, slotProps, onAdornmentClick, ...other } = props;
-
- const textFieldProps = useSlotProps({
- elementType: 'input',
- externalSlotProps: slotProps?.textField,
- externalForwardedProps: other,
- ownerState: props,
- });
-
- textFieldProps.InputProps = {
- ...textFieldProps.InputProps,
- endAdornment: (
-
-
-
-
-
- ),
- };
-
- const fieldResponse = useSingleInputDateRangeField({
- ...textFieldProps,
- enableAccessibleFieldDOMStructure: false,
- });
-
- /* If you don't need a clear button, you can skip the use of this hook */
- const processedFieldProps = useClearableField({
- ...fieldResponse,
- slots,
- slotProps,
- });
-
- return (
-
- );
-});
-
-BrowserSingleInputDateRangeField.fieldType = 'single-input';
-
-const BrowserSingleInputDateRangePicker = React.forwardRef((props, ref) => {
- const [isOpen, setIsOpen] = React.useState(false);
-
- const toggleOpen = () => setIsOpen((currentOpen) => !currentOpen);
-
- const handleOpen = () => setIsOpen(true);
-
- const handleClose = () => setIsOpen(false);
-
- return (
-
- );
-});
-
-export default function BrowserV6SingleInputRangeField() {
- return (
-
-
-
- );
-}
diff --git a/docs/data/date-pickers/custom-field/BrowserV6SingleInputRangeField.tsx b/docs/data/date-pickers/custom-field/BrowserV6SingleInputRangeField.tsx
deleted file mode 100644
index 6db84b3f6c57..000000000000
--- a/docs/data/date-pickers/custom-field/BrowserV6SingleInputRangeField.tsx
+++ /dev/null
@@ -1,196 +0,0 @@
-import * as React from 'react';
-import { Dayjs } from 'dayjs';
-import { unstable_useForkRef as useForkRef } from '@mui/utils';
-import useSlotProps from '@mui/utils/useSlotProps';
-import Box from '@mui/material/Box';
-import IconButton from '@mui/material/IconButton';
-import InputAdornment from '@mui/material/InputAdornment';
-import { DateRangeIcon } from '@mui/x-date-pickers/icons';
-import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
-import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
-import {
- DateRangePicker,
- DateRangePickerProps,
-} from '@mui/x-date-pickers-pro/DateRangePicker';
-import {
- unstable_useSingleInputDateRangeField as useSingleInputDateRangeField,
- SingleInputDateRangeFieldProps,
- UseSingleInputDateRangeFieldProps,
-} from '@mui/x-date-pickers-pro/SingleInputDateRangeField';
-import { useClearableField } from '@mui/x-date-pickers/hooks';
-import { BaseSingleInputFieldProps } from '@mui/x-date-pickers/models';
-import {
- DateRangeValidationError,
- RangeFieldSection,
- DateRange,
- FieldType,
-} from '@mui/x-date-pickers-pro/models';
-
-interface BrowserFieldProps
- extends Omit, 'size'> {
- label?: React.ReactNode;
- inputRef?: React.Ref;
- InputProps?: {
- ref?: React.Ref;
- endAdornment?: React.ReactNode;
- startAdornment?: React.ReactNode;
- };
- error?: boolean;
- focused?: boolean;
- ownerState?: any;
- sx?: any;
- enableAccessibleFieldDOMStructure: boolean;
-}
-
-type BrowserFieldComponent = ((
- props: BrowserFieldProps & React.RefAttributes,
-) => React.JSX.Element) & { propTypes?: any };
-
-const BrowserField = React.forwardRef(
- (props: BrowserFieldProps, ref: React.Ref) => {
- const {
- // Should be ignored
- enableAccessibleFieldDOMStructure,
-
- disabled,
- id,
- label,
- inputRef,
- InputProps: { ref: containerRef, startAdornment, endAdornment } = {},
- // extracting `error`, 'focused', and `ownerState` as `input` does not support those props
- error,
- focused,
- ownerState,
- sx,
- ...other
- } = props;
-
- const handleRef = useForkRef(containerRef, ref);
-
- return (
-
- {startAdornment}
-
- {endAdornment}
-
- );
- },
-) as BrowserFieldComponent;
-
-interface BrowserSingleInputDateRangeFieldProps
- extends UseSingleInputDateRangeFieldProps,
- BaseSingleInputFieldProps<
- DateRange,
- Dayjs,
- RangeFieldSection,
- false,
- DateRangeValidationError
- > {
- onAdornmentClick?: () => void;
-}
-
-type BrowserSingleInputDateRangeFieldComponent = ((
- props: BrowserSingleInputDateRangeFieldProps & React.RefAttributes,
-) => React.JSX.Element) & { fieldType?: FieldType };
-
-const BrowserSingleInputDateRangeField = React.forwardRef(
- (props: BrowserSingleInputDateRangeFieldProps, ref: React.Ref) => {
- const { slots, slotProps, onAdornmentClick, ...other } = props;
-
- const textFieldProps: SingleInputDateRangeFieldProps =
- useSlotProps({
- elementType: 'input',
- externalSlotProps: slotProps?.textField,
- externalForwardedProps: other,
- ownerState: props as any,
- });
-
- textFieldProps.InputProps = {
- ...textFieldProps.InputProps,
- endAdornment: (
-
-
-
-
-
- ),
- };
-
- const fieldResponse = useSingleInputDateRangeField<
- Dayjs,
- false,
- typeof textFieldProps
- >({ ...textFieldProps, enableAccessibleFieldDOMStructure: false });
-
- /* If you don't need a clear button, you can skip the use of this hook */
- const processedFieldProps = useClearableField({
- ...fieldResponse,
- slots,
- slotProps,
- });
-
- return (
-
- );
- },
-) as BrowserSingleInputDateRangeFieldComponent;
-
-BrowserSingleInputDateRangeField.fieldType = 'single-input';
-
-const BrowserSingleInputDateRangePicker = React.forwardRef(
- (props: DateRangePickerProps, ref: React.Ref) => {
- const [isOpen, setIsOpen] = React.useState(false);
-
- const toggleOpen = () => setIsOpen((currentOpen) => !currentOpen);
-
- const handleOpen = () => setIsOpen(true);
-
- const handleClose = () => setIsOpen(false);
-
- return (
-
- );
- },
-);
-
-export default function BrowserV6SingleInputRangeField() {
- return (
-
-
-
- );
-}
diff --git a/docs/data/date-pickers/custom-field/BrowserV6SingleInputRangeField.tsx.preview b/docs/data/date-pickers/custom-field/BrowserV6SingleInputRangeField.tsx.preview
deleted file mode 100644
index bcaf8043948f..000000000000
--- a/docs/data/date-pickers/custom-field/BrowserV6SingleInputRangeField.tsx.preview
+++ /dev/null
@@ -1,5 +0,0 @@
-
\ No newline at end of file
diff --git a/docs/data/date-pickers/custom-field/BrowserV7MultiInputRangeField.tsx b/docs/data/date-pickers/custom-field/BrowserV7MultiInputRangeField.tsx
index c4ef19f2f15b..b45092eb35ef 100644
--- a/docs/data/date-pickers/custom-field/BrowserV7MultiInputRangeField.tsx
+++ b/docs/data/date-pickers/custom-field/BrowserV7MultiInputRangeField.tsx
@@ -201,7 +201,7 @@ const BrowserMultiInputDateRangeField = React.forwardRef(
) as BrowserMultiInputDateRangeFieldComponent;
const BrowserDateRangePicker = React.forwardRef(
- (props: DateRangePickerProps, ref: React.Ref) => {
+ (props: DateRangePickerProps, ref: React.Ref) => {
return (
-
-
+
+
);
diff --git a/docs/data/date-pickers/custom-field/MaterialV6Field.tsx b/docs/data/date-pickers/custom-field/MaterialV6Field.tsx
index 35d4e0ca73ea..98a5d2d58c27 100644
--- a/docs/data/date-pickers/custom-field/MaterialV6Field.tsx
+++ b/docs/data/date-pickers/custom-field/MaterialV6Field.tsx
@@ -9,8 +9,8 @@ export default function MaterialV6Field() {
return (
-
-
+
+
);
diff --git a/docs/data/date-pickers/custom-field/MaterialV6Field.tsx.preview b/docs/data/date-pickers/custom-field/MaterialV6Field.tsx.preview
index 027cb7beacfa..9041ed886d8b 100644
--- a/docs/data/date-pickers/custom-field/MaterialV6Field.tsx.preview
+++ b/docs/data/date-pickers/custom-field/MaterialV6Field.tsx.preview
@@ -1,2 +1,2 @@
-
-
\ No newline at end of file
+
+
\ No newline at end of file
diff --git a/docs/data/date-pickers/custom-field/MaterialV6FieldWrapped.js b/docs/data/date-pickers/custom-field/MaterialV6FieldWrapped.js
deleted file mode 100644
index df1b5053a745..000000000000
--- a/docs/data/date-pickers/custom-field/MaterialV6FieldWrapped.js
+++ /dev/null
@@ -1,22 +0,0 @@
-import * as React from 'react';
-import MuiTextField from '@mui/material/TextField';
-import { DemoContainer } from '@mui/x-date-pickers/internals/demo';
-import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
-import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
-import { DateField } from '@mui/x-date-pickers/DateField';
-import { DatePicker } from '@mui/x-date-pickers/DatePicker';
-
-const TextField = React.forwardRef((props, ref) => (
-
-));
-
-export default function MaterialV6FieldWrapped() {
- return (
-
-
-
-
-
-
- );
-}
diff --git a/docs/data/date-pickers/custom-field/MaterialV6FieldWrapped.tsx b/docs/data/date-pickers/custom-field/MaterialV6FieldWrapped.tsx
deleted file mode 100644
index 0c90908a7d4b..000000000000
--- a/docs/data/date-pickers/custom-field/MaterialV6FieldWrapped.tsx
+++ /dev/null
@@ -1,24 +0,0 @@
-import * as React from 'react';
-import MuiTextField, { TextFieldProps } from '@mui/material/TextField';
-import { DemoContainer } from '@mui/x-date-pickers/internals/demo';
-import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
-import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
-import { DateField } from '@mui/x-date-pickers/DateField';
-import { DatePicker } from '@mui/x-date-pickers/DatePicker';
-
-const TextField = React.forwardRef(
- (props: TextFieldProps, ref: React.Ref) => (
-
- ),
-);
-
-export default function MaterialV6FieldWrapped() {
- return (
-
-
-
-
-
-
- );
-}
diff --git a/docs/data/date-pickers/custom-field/MaterialV6FieldWrapped.tsx.preview b/docs/data/date-pickers/custom-field/MaterialV6FieldWrapped.tsx.preview
deleted file mode 100644
index cd5ff731abbc..000000000000
--- a/docs/data/date-pickers/custom-field/MaterialV6FieldWrapped.tsx.preview
+++ /dev/null
@@ -1,2 +0,0 @@
-
-
\ No newline at end of file
diff --git a/docs/data/date-pickers/custom-field/MaterialV7Field.js b/docs/data/date-pickers/custom-field/MaterialV7Field.js
deleted file mode 100644
index 07ba449750d6..000000000000
--- a/docs/data/date-pickers/custom-field/MaterialV7Field.js
+++ /dev/null
@@ -1,17 +0,0 @@
-import * as React from 'react';
-import { DemoContainer } from '@mui/x-date-pickers/internals/demo';
-import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
-import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
-import { DatePicker } from '@mui/x-date-pickers/DatePicker';
-import { DateField } from '@mui/x-date-pickers/DateField';
-
-export default function MaterialV7Field() {
- return (
-
-
-
-
-
-
- );
-}
diff --git a/docs/data/date-pickers/custom-field/MaterialV7Field.tsx b/docs/data/date-pickers/custom-field/MaterialV7Field.tsx
deleted file mode 100644
index 07ba449750d6..000000000000
--- a/docs/data/date-pickers/custom-field/MaterialV7Field.tsx
+++ /dev/null
@@ -1,17 +0,0 @@
-import * as React from 'react';
-import { DemoContainer } from '@mui/x-date-pickers/internals/demo';
-import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
-import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
-import { DatePicker } from '@mui/x-date-pickers/DatePicker';
-import { DateField } from '@mui/x-date-pickers/DateField';
-
-export default function MaterialV7Field() {
- return (
-
-
-
-
-
-
- );
-}
diff --git a/docs/data/date-pickers/custom-field/MaterialV7Field.tsx.preview b/docs/data/date-pickers/custom-field/MaterialV7Field.tsx.preview
deleted file mode 100644
index 9708ed359729..000000000000
--- a/docs/data/date-pickers/custom-field/MaterialV7Field.tsx.preview
+++ /dev/null
@@ -1,2 +0,0 @@
-
-
\ No newline at end of file
diff --git a/docs/data/date-pickers/custom-field/MaterialV7FieldWrapped.js b/docs/data/date-pickers/custom-field/MaterialV7FieldWrapped.js
index d125a8479b5c..22560a3bcc80 100644
--- a/docs/data/date-pickers/custom-field/MaterialV7FieldWrapped.js
+++ b/docs/data/date-pickers/custom-field/MaterialV7FieldWrapped.js
@@ -14,14 +14,8 @@ export default function MaterialV7FieldWrapped() {
return (
-
-
+
+
);
diff --git a/docs/data/date-pickers/custom-field/MaterialV7FieldWrapped.tsx b/docs/data/date-pickers/custom-field/MaterialV7FieldWrapped.tsx
index 82e06da7316b..d054e12c04de 100644
--- a/docs/data/date-pickers/custom-field/MaterialV7FieldWrapped.tsx
+++ b/docs/data/date-pickers/custom-field/MaterialV7FieldWrapped.tsx
@@ -19,14 +19,8 @@ export default function MaterialV7FieldWrapped() {
return (
-
-
+
+
);
diff --git a/docs/data/date-pickers/custom-field/MaterialV7FieldWrapped.tsx.preview b/docs/data/date-pickers/custom-field/MaterialV7FieldWrapped.tsx.preview
index 17535291f5f3..a31c9c5bc351 100644
--- a/docs/data/date-pickers/custom-field/MaterialV7FieldWrapped.tsx.preview
+++ b/docs/data/date-pickers/custom-field/MaterialV7FieldWrapped.tsx.preview
@@ -1,8 +1,2 @@
-
-
\ No newline at end of file
+
+
\ No newline at end of file
diff --git a/docs/data/date-pickers/custom-field/PickerWithAutocompleteField.tsx b/docs/data/date-pickers/custom-field/PickerWithAutocompleteField.tsx
index 1aac33d076c0..92e99e278e87 100644
--- a/docs/data/date-pickers/custom-field/PickerWithAutocompleteField.tsx
+++ b/docs/data/date-pickers/custom-field/PickerWithAutocompleteField.tsx
@@ -14,12 +14,12 @@ import {
} from '@mui/x-date-pickers/models';
interface AutoCompleteFieldProps
- extends UseDateFieldProps,
+ extends UseDateFieldProps,
BaseSingleInputFieldProps<
Dayjs | null,
Dayjs,
FieldSection,
- false,
+ true,
DateValidationError
> {
/**
diff --git a/docs/data/date-pickers/custom-field/PickerWithButtonField.tsx b/docs/data/date-pickers/custom-field/PickerWithButtonField.tsx
index aa09717fb29c..8acbab77d7c4 100644
--- a/docs/data/date-pickers/custom-field/PickerWithButtonField.tsx
+++ b/docs/data/date-pickers/custom-field/PickerWithButtonField.tsx
@@ -12,12 +12,12 @@ import {
} from '@mui/x-date-pickers/models';
interface ButtonFieldProps
- extends UseDateFieldProps,
+ extends UseDateFieldProps,
BaseSingleInputFieldProps<
Dayjs | null,
Dayjs,
FieldSection,
- false,
+ true,
DateValidationError
> {
setOpen?: React.Dispatch>;
diff --git a/docs/data/date-pickers/custom-field/custom-behavior/ReadOnlyMaterialTextField.tsx b/docs/data/date-pickers/custom-field/custom-behavior/ReadOnlyMaterialTextField.tsx
index c9cdc16eae4e..04223bd73a6e 100644
--- a/docs/data/date-pickers/custom-field/custom-behavior/ReadOnlyMaterialTextField.tsx
+++ b/docs/data/date-pickers/custom-field/custom-behavior/ReadOnlyMaterialTextField.tsx
@@ -16,7 +16,7 @@ import {
} from '@mui/x-date-pickers/hooks';
import { CalendarIcon } from '@mui/x-date-pickers/icons';
-function ReadOnlyDateField(props: DatePickerFieldProps) {
+function ReadOnlyDateField(props: DatePickerFieldProps) {
const { internalProps, forwardedProps } = useSplitFieldProps(props, 'date');
const { value, timezone, format } = internalProps;
const { InputProps, slotProps, slots, ...other } = forwardedProps;
diff --git a/docs/data/date-pickers/custom-field/custom-field.md b/docs/data/date-pickers/custom-field/custom-field.md
index 4f5b5f782fb3..36417d5bde6e 100644
--- a/docs/data/date-pickers/custom-field/custom-field.md
+++ b/docs/data/date-pickers/custom-field/custom-field.md
@@ -66,30 +66,9 @@ Setting `formatDensity` to `"spacious"` will add a space before and after each `
{{"demo": "FieldFormatDensity.js"}}
-## Usage with Material UI
+## With Material UI
-### Using Material `TextField`
-
-You can import the `TextField` component to create custom wrappers:
-
-{{"demo": "MaterialV6FieldWrapped.js"}}
-
-:::success
-This approach is only recommended if you need complex customizations on your `TextField`,
-or if you already have a wrapper also used outside the Date and Time Pickers.
-
-If you just need to set some default props, you can use [the `slotProps` prop](/x/react-date-pickers/custom-field/#customize-the-textfield).
-:::
-
-### Using Material `PickersTextField`
-
-Pass the `enableAccessibleFieldDOMStructure` to any Field or Picker component to enable the accessible DOM structure:
-
-{{"demo": "MaterialV7Field.js"}}
-
-:::success
-Learn more about the [accessible DOM structure](/x/react-date-pickers/fields/#accessible-dom-structure).
-:::
+### Wrapping `PickersTextField`
You can import the `PickersTextField` component to create custom wrappers:
@@ -101,55 +80,50 @@ This approach is only recommended if you need complex customizations on your `Pi
If you just need to set some default props, you can use [the `slotProps` prop](/x/react-date-pickers/custom-field/#customize-the-textfield).
:::
-## Usage with Joy UI
+### Using Material `TextField`
-### Using Joy `Input`
+Pass the `enableAccessibleFieldDOMStructure={false}` to any Field or Picker component to use an `` for the editing instead of the new accessible DOM structure:
-You can use the [Joy UI](https://mui.com/joy-ui/getting-started/) components instead of the Material UI ones:
+{{"demo": "MaterialV6Field.js"}}
-:::info
-A higher-level solution for _Joy UI_ will be provided in the near future for even simpler usage.
+:::warning
+The non-accessible DOM structure will be deprecated in a follow up minor version and remove in `v9.x`.
+If you are unable to migrate for some reason, please open an issue to describe what is missing from the new DOM structure so that we can improve it before dropping the old one.
:::
-{{"demo": "JoyV6Field.js", "defaultCodeOpen": false}}
+## With another Design System
-{{"demo": "JoyV6SingleInputRangeField.js", "defaultCodeOpen": false}}
-
-{{"demo": "JoyV6MultiInputRangeField.js", "defaultCodeOpen": false}}
-
-### Using Joy `PickersTextField`
+### Using a custom input
:::warning
-This component is not available yet.
+You will need to use a component that supports the `sx` prop as a wrapper for your input
+to be able to benefit from the **hover** and **focus** behavior of the clear button.
+You will have access to the `clearable` and `onClear` props using native HTML elements,
+but the on **focus** and **hover** behavior depends on styles applied via the `sx` prop.
:::
-## Usage with an unstyled input
-
-### Using the browser input
-
-{{"demo": "BrowserV6Field.js", "defaultCodeOpen": false}}
+{{"demo": "BrowserV7Field.js", "defaultCodeOpen": false}}
-{{"demo": "BrowserV6SingleInputRangeField.js", "defaultCodeOpen": false}}
+{{"demo": "BrowserV7SingleInputRangeField.js", "defaultCodeOpen": false}}
-{{"demo": "BrowserV6MultiInputRangeField.js", "defaultCodeOpen": false}}
+{{"demo": "BrowserV7MultiInputRangeField.js", "defaultCodeOpen": false}}
-:::warning
-You will need to use a component that supports the `sx` prop as a wrapper for your input, in order to be able to benefit from the **hover** and **focus** behavior of the clear button. You will have access to the `clearable` and `onClear` props using native HTML elements, but the on **focus** and **hover** behavior depends on styles applied via the `sx` prop.
-:::
+### Using Joy UI
-### Using custom `PickersTextField`
+You can use the [Joy UI](https://mui.com/joy-ui/getting-started/) components instead of the Material UI ones:
-:::success
-Learn more about the accessible DOM structure and its difference compared to the current one on the [dedicated doc section](/x/react-date-pickers/fields/#accessible-dom-structure).
-:::
+{{"demo": "JoyV6Field.js", "defaultCodeOpen": false}}
-{{"demo": "BrowserV7Field.js", "defaultCodeOpen": false}}
+{{"demo": "JoyV6SingleInputRangeField.js", "defaultCodeOpen": false}}
-{{"demo": "BrowserV7SingleInputRangeField.js", "defaultCodeOpen": false}}
+{{"demo": "JoyV6MultiInputRangeField.js", "defaultCodeOpen": false}}
-{{"demo": "BrowserV7MultiInputRangeField.js", "defaultCodeOpen": false}}
+:::warning
+All the Joy UI examples use the non-accessible DOM structure.
+The new accessible DOM structure will become compatible with Joy UI in the future.
+:::
-## Usage with another UI
+## With a custom editing experience
### Using an `Autocomplete`
@@ -184,22 +158,22 @@ On the examples below, you can see that the typing of the props received by a cu
```tsx
interface JoyDateFieldProps
- extends UseDateFieldProps, // The headless field props
+ extends UseDateFieldProps, // The headless field props
BaseSingleInputFieldProps<
Dayjs | null,
Dayjs,
FieldSection,
- false, // `true` for `enableAccessibleFieldDOMStructure`
+ true, // `false` for `enableAccessibleFieldDOMStructure={false}`
DateValidationError
> {} // The DOM field props
interface JoyDateTimeFieldProps
- extends UseDateTimeFieldProps, // The headless field props
+ extends UseDateTimeFieldProps, // The headless field props
BaseSingleInputFieldProps<
Dayjs | null,
Dayjs,
FieldSection,
- false, // `true` for `enableAccessibleFieldDOMStructure`
+ true, // `false` for `enableAccessibleFieldDOMStructure={false}`
DateTimeValidationError
> {} // The DOM field props
```
diff --git a/docs/data/date-pickers/fields/BasicV7DOMStructure.js b/docs/data/date-pickers/fields/BasicV7DOMStructure.js
index 1f32eca967da..62c0924c3c90 100644
--- a/docs/data/date-pickers/fields/BasicV7DOMStructure.js
+++ b/docs/data/date-pickers/fields/BasicV7DOMStructure.js
@@ -8,7 +8,7 @@ export default function BasicV7DOMStructure() {
return (
-
+
);
diff --git a/docs/data/date-pickers/fields/BasicV7DOMStructure.tsx b/docs/data/date-pickers/fields/BasicV7DOMStructure.tsx
index 1f32eca967da..62c0924c3c90 100644
--- a/docs/data/date-pickers/fields/BasicV7DOMStructure.tsx
+++ b/docs/data/date-pickers/fields/BasicV7DOMStructure.tsx
@@ -8,7 +8,7 @@ export default function BasicV7DOMStructure() {
return (
-
+
);
diff --git a/docs/data/date-pickers/fields/BasicV7DOMStructure.tsx.preview b/docs/data/date-pickers/fields/BasicV7DOMStructure.tsx.preview
index f33bc6c8fdc7..2dc079345c09 100644
--- a/docs/data/date-pickers/fields/BasicV7DOMStructure.tsx.preview
+++ b/docs/data/date-pickers/fields/BasicV7DOMStructure.tsx.preview
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/docs/data/date-pickers/fields/fields.md b/docs/data/date-pickers/fields/fields.md
index 5f54b1411f66..9bd7260fff46 100644
--- a/docs/data/date-pickers/fields/fields.md
+++ b/docs/data/date-pickers/fields/fields.md
@@ -25,201 +25,6 @@ All fields to edit a range are available in a single input version and in a mult
{{"demo": "DateRangeFieldExamples.js", "defaultCodeOpen": false}}
-## Accessible DOM structure
-
-By default, the fields' DOM structure consists of an ``, which holds the whole value for the component, but unfortunately presents a few limitations in terms of accessibility when managing multiple section values.
-
-From v7 version, you can opt-in for a new and experimental DOM structure on any field or picker component using the `enableAccessibleFieldDOMStructure` prop.
-
-```tsx
-
-
-
-```
-
-This new feature allows the field component to set aria attributes on individual sections, providing a far better experience with screen readers.
-
-{{"demo": "BasicV7DOMStructure.js", "defaultCodeOpen": false }}
-
-### Usage with `slotProps.field`
-
-When using `slotProps.field` to pass props to your field component,
-the field consumes some props (e.g: `shouldRespectLeadingZeros`) and forwards the rest to the `TextField`.
-
-- For the props consumed by the field, the behavior should remain exactly the same with both DOM structures.
-
- Both components below will respect the leading zeroes on digit sections:
-
- ```js
-
-
- ```
-
-- For the props forwarded to the `TextField`,
- you can have a look at the next section to see how the migration impact them.
-
- Both components below will render a small size UI:
-
- ```js
-
-
- ```
-
-### Usage with `slotProps.textField`
-
-If you are passing props to `slotProps.textField`,
-these props will now be received by `PickersTextField` and should keep working the same way as before.
-
-Both components below will render a small size UI:
-
-```js
-
-
-```
-
-:::info
-If you are passing `inputProps` to `slotProps.textField`,
-these props will now be passed to the hidden `` element.
-:::
-
-### Usage with `slots.field`
-
-If you are passing a custom field component to your pickers, you need to create a new one that is using the accessible DOM structure.
-This new component will need to use the `PickersSectionList` component instead of an `` HTML element.
-
-You can have a look at the [custom PickersTextField](/x/react-date-pickers/custom-field/#using-custom-pickerstextfield) to have a concrete example.
-
-:::info
-If your custom field was used to create a Joy UI design component,
-you may want to wait a few weeks for the release of an out-of-the-box Joy `PickersTextField` component instead of implementing it yourself.
-:::
-
-### Usage with `slots.textField`
-
-If you are passing a custom `TextField` component to your fields and pickers,
-you need to create a new one that is using the accessible DOM structure.
-
-You can have a look at the second demo of the [Material PickersTextField section](/x/react-date-pickers/custom-field/#using-material-pickerstextfield) to have a concrete example.
-
-:::info
-If your custom `TextField` was used to apply a totally different input that did not use `@mui/material/TextField`,
-please consider having a look at the [custom PickersTextField](/x/react-date-pickers/custom-field/#using-custom-pickerstextfield) section which uses `slots.field`.
-This approach can be more appropriate for deeper changes.
-:::
-
-### Usage with theme
-
-If you are using the theme to customize `MuiTextField`,
-you need to pass the same config to `MuiPickersTextField`:
-
-```js
-const theme = createTheme({
- components: {
- MuiTextField: {
- defaultProps: {
- variant: 'outlined',
- },
- styleOverrides: {
- root: {
- '& .MuiInputLabel-outlined.Mui-focused': {
- color: 'red',
- },
- },
- },
- },
- MuiPickersTextField: {
- defaultProps: {
- variant: 'outlined',
- },
- styleOverrides: {
- root: {
- '& .MuiInputLabel-outlined.Mui-focused': {
- color: 'red',
- },
- },
- },
- },
- },
-});
-```
-
-If you are using the theme to customize `MuiInput`, `MuiOutlinedInput` or `MuiFilledInput`,
-you need to pass the same config to `MuiPickersInput`, `MuiPickersOutlinedInput` or `MuiPickersFilledInput`:
-
-```js
-const theme = createTheme({
- components: {
- // Replace with `MuiOutlinedInput` or `MuiFilledInput` if needed
- MuiInput: {
- defaultProps: {
- margin: 'dense',
- },
- styleOverrides: {
- root: {
- color: 'red',
- },
- },
- },
- // Replace with `MuiPickersOutlinedInput` or `MuiPickersFilledInput` if needed
- MuiPickersInput: {
- defaultProps: {
- margin: 'dense',
- },
- styleOverrides: {
- root: {
- color: 'red',
- },
- },
- },
- },
-});
-```
-
-If you are using the theme to customize `MuiInputBase`,
-you need to pass the same config to `MuiPickersInputBase`:
-
-```js
-const theme = createTheme({
- components: {
- MuiInputBase: {
- defaultProps: {
- margin: 'dense',
- },
- styleOverrides: {
- root: {
- color: 'red',
- },
- },
- },
- MuiPickersInputBase: {
- defaultProps: {
- margin: 'dense',
- },
- styleOverrides: {
- root: {
- color: 'red',
- },
- },
- },
- },
-});
-```
-
## Advanced
### What is a section?
diff --git a/docs/data/migration/migration-pickers-v6/migration-pickers-v6.md b/docs/data/migration/migration-pickers-v6/migration-pickers-v6.md
index 787bbefb3182..ab73ca9e1900 100644
--- a/docs/data/migration/migration-pickers-v6/migration-pickers-v6.md
+++ b/docs/data/migration/migration-pickers-v6/migration-pickers-v6.md
@@ -440,7 +440,7 @@ The headless field hooks (e.g.: `useDateField`) now return a new prop called `en
This is used to know if the current UI expected is built using the accessible DOM structure or not.
:::info
-See [Fields—Accessible DOM structure](/x/react-date-pickers/fields/#accessible-dom-structure) for more details.
+See [Migration from v7 to v8—New DOM structure for the field](/x/migration/migration-pickers-v7/#new-dom-structure-for-the-field) for more details.
:::
When building a custom UI, you are most-likely only supporting one DOM structure, so you can remove `enableAccessibleFieldDOMStructure` before it is passed to the DOM:
diff --git a/docs/data/migration/migration-pickers-v7/migration-pickers-v7.md b/docs/data/migration/migration-pickers-v7/migration-pickers-v7.md
new file mode 100644
index 000000000000..1647dae16ac6
--- /dev/null
+++ b/docs/data/migration/migration-pickers-v7/migration-pickers-v7.md
@@ -0,0 +1,258 @@
+---
+productId: x-date-pickers
+---
+
+# Migration from v7 to v8
+
+
This guide describes the changes needed to migrate the Date and Time Pickers from v7 to v8.
+
+## Introduction
+
+This is a reference guide for upgrading `@mui/x-date-pickers` from v7 to v8.
+
+## Start using the new release
+
+In `package.json`, change the version of the date pickers package to `^8.0.0`.
+
+```diff
+-"@mui/x-date-pickers": "7.x.x",
++"@mui/x-date-pickers": "^8.0.0",
+```
+
+Since `v8` is a major release, it contains changes that affect the public API.
+These changes were done for consistency, improved stability and to make room for new features.
+Described below are the steps needed to migrate from v7 to v8.
+
+## Run codemods
+
+The `preset-safe` codemod will automatically adjust the bulk of your code to account for breaking changes in v8. You can run `v8.0.0/pickers/preset-safe` targeting only Date and Time Pickers or `v8.0.0/preset-safe` to target the other packages as well.
+
+You can either run it on a specific file, folder, or your entire codebase when choosing the `` argument.
+
+
+
+```bash
+// Date and Time Pickers specific
+npx @mui/x-codemod@latest v8.0.0/pickers/preset-safe
+
+// Target the other packages as well
+npx @mui/x-codemod@latest v8.0.0/preset-safe
+```
+
+:::info
+If you want to run the transformers one by one, check out the transformers included in the [preset-safe codemod for pickers](https://github.com/mui/mui-x/blob/HEAD/packages/x-codemod/README.md#preset-safe-for-pickers-v800) for more details.
+:::
+
+Breaking changes that are handled by this codemod are denoted by a ✅ emoji in the table of contents on the right side of the screen.
+
+If you have already applied the `v8.0.0/pickers/preset-safe` (or `v8.0.0/preset-safe`) codemod, then you should not need to take any further action on these items.
+
+All other changes must be handled manually.
+
+:::warning
+Not all use cases are covered by codemods. In some scenarios, like props spreading, cross-file dependencies, etc., the changes are not properly identified and therefore must be handled manually.
+
+For example, if a codemod tries to rename a prop, but this prop is hidden with the spread operator, it won't be transformed as expected.
+
+```tsx
+
+```
+
+After running the codemods, make sure to test your application and that you don't have any console errors.
+
+Feel free to [open an issue](https://github.com/mui/mui-x/issues/new/choose) for support if you need help to proceed with your migration.
+:::
+
+## New DOM structure for the field
+
+Before version `v8.x`, the fields' DOM structure consisted of an ``, which held the whole value for the component,
+but unfortunately presents a few limitations in terms of accessibility when managing multiple section values.
+
+Starting with version `v8.x`, all the field and picker components come with a new DOM structure that allows the field component to set aria attributes on individual sections, providing a far better experience with screen readers.
+
+### Fallback to the non-accessible DOM structure
+
+```tsx
+
+
+
+```
+
+### Migrate `slotProps.field`
+
+When using `slotProps.field` to pass props to your field component,
+the field consumes some props (e.g: `shouldRespectLeadingZeros`) and forwards the rest to the `TextField`.
+
+- For the props consumed by the field, the behavior should remain exactly the same with both DOM structures.
+
+ Both components below will respect the leading zeroes on digit sections:
+
+ ```js
+
+
+ ```
+
+- For the props forwarded to the `TextField`,
+ you can have a look at the next section to see how the migration impact them.
+
+ Both components below will render a small size UI:
+
+ ```js
+
+
+ ```
+
+### Migrate `slotProps.textField`
+
+If you are passing props to `slotProps.textField`,
+these props will now be received by `PickersTextField` and should keep working the same way as before.
+
+Both components below will render a small size UI:
+
+```js
+
+
+```
+
+:::info
+If you are passing `inputProps` to `slotProps.textField`,
+these props will now be passed to the hidden `` element.
+:::
+
+### Migrate `slots.field`
+
+If you are passing a custom field component to your pickers, you need to create a new one that is using the accessible DOM structure.
+This new component will need to use the `PickersSectionList` component instead of an `` HTML element.
+
+You can have a look at the [Using a custom input](/x/react-date-pickers/custom-field/#using-a-custom-input) to have a concrete example.
+
+:::info
+If your custom field was used to create a Joy UI design component,
+you may want to wait a few weeks for the release of an out-of-the-box Joy `PickersTextField` component instead of implementing it yourself.
+:::
+
+### Migrate `slots.textField`
+
+If you are passing a custom `TextField` component to your fields and pickers,
+you need to create a new one that is using the accessible DOM structure.
+
+You can have a look at the second demo of the [Wrapping PickersTextField](/x/react-date-pickers/custom-field/#wrapping-pickerstextfield) to have a concrete example.
+
+:::info
+If your custom `TextField` was used to apply a totally different input that did not use `@mui/material/TextField`,
+please consider having a look at the [Using a custom input](/x/react-date-pickers/custom-field/#using-a-custom-input) section which uses `slots.field`.
+This approach can be more appropriate for deeper changes.
+:::
+
+### Migrate the theme
+
+If you are using the theme to customize `MuiTextField`,
+you need to pass the same config to `MuiPickersTextField`:
+
+```js
+const theme = createTheme({
+ components: {
+ MuiTextField: {
+ defaultProps: {
+ variant: 'outlined',
+ },
+ styleOverrides: {
+ root: {
+ '& .MuiInputLabel-outlined.Mui-focused': {
+ color: 'red',
+ },
+ },
+ },
+ },
+ MuiPickersTextField: {
+ defaultProps: {
+ variant: 'outlined',
+ },
+ styleOverrides: {
+ root: {
+ '& .MuiInputLabel-outlined.Mui-focused': {
+ color: 'red',
+ },
+ },
+ },
+ },
+ },
+});
+```
+
+If you are using the theme to customize `MuiInput`, `MuiOutlinedInput` or `MuiFilledInput`,
+you need to pass the same config to `MuiPickersInput`, `MuiPickersOutlinedInput` or `MuiPickersFilledInput`:
+
+```js
+const theme = createTheme({
+ components: {
+ // Replace with `MuiOutlinedInput` or `MuiFilledInput` if needed
+ MuiInput: {
+ defaultProps: {
+ margin: 'dense',
+ },
+ styleOverrides: {
+ root: {
+ color: 'red',
+ },
+ },
+ },
+ // Replace with `MuiPickersOutlinedInput` or `MuiPickersFilledInput` if needed
+ MuiPickersInput: {
+ defaultProps: {
+ margin: 'dense',
+ },
+ styleOverrides: {
+ root: {
+ color: 'red',
+ },
+ },
+ },
+ },
+});
+```
+
+If you are using the theme to customize `MuiInputBase`,
+you need to pass the same config to `MuiPickersInputBase`:
+
+```js
+const theme = createTheme({
+ components: {
+ MuiInputBase: {
+ defaultProps: {
+ margin: 'dense',
+ },
+ styleOverrides: {
+ root: {
+ color: 'red',
+ },
+ },
+ },
+ MuiPickersInputBase: {
+ defaultProps: {
+ margin: 'dense',
+ },
+ styleOverrides: {
+ root: {
+ color: 'red',
+ },
+ },
+ },
+ },
+});
+```
diff --git a/docs/data/pages.ts b/docs/data/pages.ts
index b952b8a5b722..883180a608eb 100644
--- a/docs/data/pages.ts
+++ b/docs/data/pages.ts
@@ -537,9 +537,19 @@ const pages: MuiPage[] = [
pathname: '/x/migration-group',
title: 'Migration',
children: [
+ {
+ pathname: '/x/migration-v8',
+ subheader: 'Upgrade to v8',
+ children: [
+ {
+ pathname: '/x/migration/migration-pickers-v7',
+ title: 'Breaking changes: Date and Time Pickers',
+ },
+ ],
+ },
{
pathname: '/x/migration-v7',
- subheader: 'Upgrade to v7',
+ title: 'Upgrade to v7',
children: [
{ pathname: '/x/migration/migration-data-grid-v6', title: 'Breaking changes: Data Grid' },
{
diff --git a/docs/pages/x/migration/migration-pickers-v7.js b/docs/pages/x/migration/migration-pickers-v7.js
new file mode 100644
index 000000000000..24de8699a05f
--- /dev/null
+++ b/docs/pages/x/migration/migration-pickers-v7.js
@@ -0,0 +1,7 @@
+import * as React from 'react';
+import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs';
+import * as pageProps from 'docsx/data/migration/migration-pickers-v7/migration-pickers-v7.md?muiMarkdown';
+
+export default function Page() {
+ return ;
+}
diff --git a/docs/src/modules/components/overview/Keyboard.tsx b/docs/src/modules/components/overview/Keyboard.tsx
index 2d0a141601f0..1f4beb6a6746 100644
--- a/docs/src/modules/components/overview/Keyboard.tsx
+++ b/docs/src/modules/components/overview/Keyboard.tsx
@@ -487,7 +487,6 @@ export default function Keyboard() {
onKeyUp={() => {
setSelectedKey(null);
}}
- enableAccessibleFieldDOMStructure
onSelectedSectionsChange={(newSelectedSection) => {
selectedSection.current = newSelectedSection;
}}
diff --git a/docs/src/modules/components/overview/mainDemo/PickerButton.tsx b/docs/src/modules/components/overview/mainDemo/PickerButton.tsx
index 0dc82b364e0f..27b6857feed5 100644
--- a/docs/src/modules/components/overview/mainDemo/PickerButton.tsx
+++ b/docs/src/modules/components/overview/mainDemo/PickerButton.tsx
@@ -12,8 +12,8 @@ import {
} from '@mui/x-date-pickers/models';
interface ButtonFieldProps
- extends UseDateFieldProps,
- BaseSingleInputFieldProps {
+ extends UseDateFieldProps,
+ BaseSingleInputFieldProps {
setOpen?: React.Dispatch>;
}
diff --git a/packages/x-date-pickers-pro/src/DateRangePicker/DateRangePicker.test.tsx b/packages/x-date-pickers-pro/src/DateRangePicker/DateRangePicker.test.tsx
index 2d6094f4db18..7aa94997646b 100644
--- a/packages/x-date-pickers-pro/src/DateRangePicker/DateRangePicker.test.tsx
+++ b/packages/x-date-pickers-pro/src/DateRangePicker/DateRangePicker.test.tsx
@@ -22,7 +22,7 @@ describe('', () => {
});
it('should not open mobile picker dialog when clicked on input', () => {
- // Test with v7 input
+ // Test with accessible DOM structure
const { unmount } = renderWithProps({ enableAccessibleFieldDOMStructure: true });
fireEvent.click(getFieldInputRoot());
clock.runToLast();
@@ -32,7 +32,7 @@ describe('', () => {
unmount();
- // Test with v6 input
+ // Test with non-accessible DOM structure
renderWithProps({ enableAccessibleFieldDOMStructure: false });
fireEvent.click(screen.getAllByRole('textbox')[0]);
clock.runToLast();
@@ -45,7 +45,7 @@ describe('', () => {
const originalMatchMedia = window.matchMedia;
window.matchMedia = stubMatchMedia(false);
- render();
+ render();
fireEvent.click(getFieldInputRoot());
clock.runToLast();
diff --git a/packages/x-date-pickers-pro/src/DateRangePicker/DateRangePicker.tsx b/packages/x-date-pickers-pro/src/DateRangePicker/DateRangePicker.tsx
index c6a5c6e350c8..cc96fb4d9bbe 100644
--- a/packages/x-date-pickers-pro/src/DateRangePicker/DateRangePicker.tsx
+++ b/packages/x-date-pickers-pro/src/DateRangePicker/DateRangePicker.tsx
@@ -11,7 +11,7 @@ import { DateRangePickerProps } from './DateRangePicker.types';
type DatePickerComponent = (<
TDate extends PickerValidDate,
- TEnableAccessibleFieldDOMStructure extends boolean = false,
+ TEnableAccessibleFieldDOMStructure extends boolean = true,
>(
props: DateRangePickerProps &
React.RefAttributes,
@@ -29,7 +29,7 @@ type DatePickerComponent = (<
*/
const DateRangePicker = React.forwardRef(function DateRangePicker<
TDate extends PickerValidDate,
- TEnableAccessibleFieldDOMStructure extends boolean = false,
+ TEnableAccessibleFieldDOMStructure extends boolean = true,
>(
inProps: DateRangePickerProps,
ref: React.Ref,
@@ -140,7 +140,7 @@ DateRangePicker.propTypes = {
*/
displayWeekNumber: PropTypes.bool,
/**
- * @default false
+ * @default true
*/
enableAccessibleFieldDOMStructure: PropTypes.any,
/**
diff --git a/packages/x-date-pickers-pro/src/DateRangePicker/DateRangePicker.types.ts b/packages/x-date-pickers-pro/src/DateRangePicker/DateRangePicker.types.ts
index cc56765af366..95cd8b8a6b63 100644
--- a/packages/x-date-pickers-pro/src/DateRangePicker/DateRangePicker.types.ts
+++ b/packages/x-date-pickers-pro/src/DateRangePicker/DateRangePicker.types.ts
@@ -22,7 +22,7 @@ export interface DateRangePickerSlotProps<
export interface DateRangePickerProps<
TDate extends PickerValidDate,
- TEnableAccessibleFieldDOMStructure extends boolean = false,
+ TEnableAccessibleFieldDOMStructure extends boolean = true,
> extends DesktopDateRangePickerProps,
MobileDateRangePickerProps {
/**
diff --git a/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePicker.tsx b/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePicker.tsx
index 64a1316f3b78..53837bb78ad5 100644
--- a/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePicker.tsx
+++ b/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePicker.tsx
@@ -11,7 +11,7 @@ import { MobileDateTimeRangePicker } from '../MobileDateTimeRangePicker';
type DateTimeRangePickerComponent = (<
TDate extends PickerValidDate,
- TEnableAccessibleFieldDOMStructure extends boolean = false,
+ TEnableAccessibleFieldDOMStructure extends boolean = true,
>(
props: DateTimeRangePickerProps &
React.RefAttributes,
@@ -29,7 +29,7 @@ type DateTimeRangePickerComponent = (<
*/
const DateTimeRangePicker = React.forwardRef(function DateTimeRangePicker<
TDate extends PickerValidDate,
- TEnableAccessibleFieldDOMStructure extends boolean = false,
+ TEnableAccessibleFieldDOMStructure extends boolean = true,
>(
inProps: DateTimeRangePickerProps,
ref: React.Ref,
@@ -150,7 +150,7 @@ DateTimeRangePicker.propTypes = {
*/
displayWeekNumber: PropTypes.bool,
/**
- * @default false
+ * @default true
*/
enableAccessibleFieldDOMStructure: PropTypes.any,
/**
diff --git a/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePicker.types.ts b/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePicker.types.ts
index 109b4715c963..aaa9942d7bf1 100644
--- a/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePicker.types.ts
+++ b/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePicker.types.ts
@@ -22,7 +22,7 @@ export interface DateTimeRangePickerSlotProps<
export interface DateTimeRangePickerProps<
TDate extends PickerValidDate,
- TEnableAccessibleFieldDOMStructure extends boolean = false,
+ TEnableAccessibleFieldDOMStructure extends boolean = true,
> extends DesktopDateTimeRangePickerProps,
MobileDateTimeRangePickerProps {
/**
diff --git a/packages/x-date-pickers-pro/src/DesktopDateRangePicker/DesktopDateRangePicker.tsx b/packages/x-date-pickers-pro/src/DesktopDateRangePicker/DesktopDateRangePicker.tsx
index 984548ad2a1b..efae31fdc727 100644
--- a/packages/x-date-pickers-pro/src/DesktopDateRangePicker/DesktopDateRangePicker.tsx
+++ b/packages/x-date-pickers-pro/src/DesktopDateRangePicker/DesktopDateRangePicker.tsx
@@ -17,7 +17,7 @@ import { DateRange } from '../models';
type DesktopDateRangePickerComponent = (<
TDate extends PickerValidDate,
- TEnableAccessibleFieldDOMStructure extends boolean = false,
+ TEnableAccessibleFieldDOMStructure extends boolean = true,
>(
props: DesktopDateRangePickerProps &
React.RefAttributes,
@@ -35,7 +35,7 @@ type DesktopDateRangePickerComponent = (<
*/
const DesktopDateRangePicker = React.forwardRef(function DesktopDateRangePicker<
TDate extends PickerValidDate,
- TEnableAccessibleFieldDOMStructure extends boolean = false,
+ TEnableAccessibleFieldDOMStructure extends boolean = true,
>(
inProps: DesktopDateRangePickerProps,
ref: React.Ref,
@@ -176,7 +176,7 @@ DesktopDateRangePicker.propTypes = {
*/
displayWeekNumber: PropTypes.bool,
/**
- * @default false
+ * @default true
*/
enableAccessibleFieldDOMStructure: PropTypes.any,
/**
diff --git a/packages/x-date-pickers-pro/src/DesktopDateRangePicker/DesktopDateRangePicker.types.ts b/packages/x-date-pickers-pro/src/DesktopDateRangePicker/DesktopDateRangePicker.types.ts
index 8c96020fd9fa..b08f4d5e5382 100644
--- a/packages/x-date-pickers-pro/src/DesktopDateRangePicker/DesktopDateRangePicker.types.ts
+++ b/packages/x-date-pickers-pro/src/DesktopDateRangePicker/DesktopDateRangePicker.types.ts
@@ -26,7 +26,7 @@ export interface DesktopDateRangePickerSlotProps<
export interface DesktopDateRangePickerProps<
TDate extends PickerValidDate,
- TEnableAccessibleFieldDOMStructure extends boolean = false,
+ TEnableAccessibleFieldDOMStructure extends boolean = true,
> extends BaseDateRangePickerProps,
DesktopRangeOnlyPickerProps {
/**
diff --git a/packages/x-date-pickers-pro/src/DesktopDateRangePicker/tests/DesktopDateRangePicker.test.tsx b/packages/x-date-pickers-pro/src/DesktopDateRangePicker/tests/DesktopDateRangePicker.test.tsx
index 8ec961707343..7febfb5df6bb 100644
--- a/packages/x-date-pickers-pro/src/DesktopDateRangePicker/tests/DesktopDateRangePicker.test.tsx
+++ b/packages/x-date-pickers-pro/src/DesktopDateRangePicker/tests/DesktopDateRangePicker.test.tsx
@@ -30,7 +30,6 @@ describe('', () => {
it('should scroll current month to the active selection when focusing appropriate field', () => {
render(
,
@@ -49,10 +48,7 @@ describe('', () => {
it(`should not crash when opening picker with invalid date value`, () => {
render(
- ,
+ ,
);
openPicker({ type: 'date-range', variant: 'desktop', initialFocus: 'start' });
@@ -74,7 +70,6 @@ describe('', () => {
', () => {
describe('Field slot: SingleInputDateRangeField', () => {
it('should add focused class to the field when it is focused', () => {
- // test v7 behavior
+ // Test with accessible DOM structure
const { unmount } = render(
- ,
+ ,
);
const sectionsContainer = getFieldSectionsContainer();
@@ -107,8 +99,13 @@ describe('', () => {
unmount();
- // test v6 behavior
- render();
+ // Test with non-accessible DOM structure
+ render(
+ ,
+ );
const input = getTextbox();
act(() => input.focus());
@@ -117,20 +114,22 @@ describe('', () => {
});
it('should render the input with a given `name` when `SingleInputDateRangeField` is used', () => {
- // Test with v7 input
+ // Test with accessible DOM structure
const { unmount } = render(
- ,
+ ,
);
expect(screen.getByRole('textbox', { hidden: true }).name).to.equal('test');
unmount();
- // Test with v6 input
- render();
+ // Test with non-accessible DOM structure
+ render(
+ ,
+ );
expect(screen.getByRole('textbox').name).to.equal('test');
});
});
@@ -141,7 +140,6 @@ describe('', () => {
const handleTouchStart = spy();
render(
', () => {
it('should open when clicking the start input', () => {
const onOpen = spy();
- render();
+ render();
openPicker({ type: 'date-range', variant: 'desktop', initialFocus: 'start' });
@@ -178,7 +176,7 @@ describe('', () => {
it('should open when clicking the end input', () => {
const onOpen = spy();
- render();
+ render();
openPicker({ type: 'date-range', variant: 'desktop', initialFocus: 'end' });
@@ -190,7 +188,7 @@ describe('', () => {
it(`should open when pressing "${key}" in the start input`, () => {
const onOpen = spy();
- render();
+ render();
const startInput = getFieldSectionsContainer();
act(() => startInput.focus());
@@ -206,7 +204,7 @@ describe('', () => {
it(`should open when pressing "${key}" in the end input`, () => {
const onOpen = spy();
- render();
+ render();
const endInput = getFieldSectionsContainer(1);
act(() => endInput.focus());
@@ -229,7 +227,6 @@ describe('', () => {
render(
', () => {
render(
', () => {
render(
', () => {
render(
', () => {
render(