diff --git a/docs/data/date-pickers/custom-components/custom-components.md b/docs/data/date-pickers/custom-components/custom-components.md
index e05e9c6e808ab..ab573ddf7a56f 100644
--- a/docs/data/date-pickers/custom-components/custom-components.md
+++ b/docs/data/date-pickers/custom-components/custom-components.md
@@ -34,8 +34,8 @@ You can override the actions displayed by passing the `actions` prop to the `act
actions: ['clear'],
},
// The actions will be different between desktop and mobile
- actionBar: ({ wrapperVariant }) => ({
- actions: wrapperVariant === 'desktop' ? [] : ['clear'],
+ actionBar: ({ variant }) => ({
+ actions: variant === 'desktop' ? [] : ['clear'],
}),
}}
/>
diff --git a/docs/data/date-pickers/custom-layout/AddComponent.js b/docs/data/date-pickers/custom-layout/AddComponent.js
index d6e0d1db8b6fe..0e904ef3d2889 100644
--- a/docs/data/date-pickers/custom-layout/AddComponent.js
+++ b/docs/data/date-pickers/custom-layout/AddComponent.js
@@ -58,11 +58,11 @@ function RestaurantHeader() {
}
function CustomLayout(props) {
- const { toolbar, tabs, content, actionBar } = usePickerLayout(props);
+ const { toolbar, tabs, content, actionBar, ownerState } = usePickerLayout(props);
return (
{toolbar}
{actionBar}
-
+
{tabs}
{content}
diff --git a/docs/data/date-pickers/custom-layout/AddComponent.tsx b/docs/data/date-pickers/custom-layout/AddComponent.tsx
index 2584a13756edf..9fc41c2b0666b 100644
--- a/docs/data/date-pickers/custom-layout/AddComponent.tsx
+++ b/docs/data/date-pickers/custom-layout/AddComponent.tsx
@@ -59,11 +59,11 @@ function RestaurantHeader() {
}
function CustomLayout(props: PickersLayoutProps) {
- const { toolbar, tabs, content, actionBar } = usePickerLayout(props);
+ const { toolbar, tabs, content, actionBar, ownerState } = usePickerLayout(props);
return (
) {
{toolbar}
{actionBar}
-
+
{tabs}
{content}
diff --git a/docs/data/date-pickers/custom-layout/custom-layout.md b/docs/data/date-pickers/custom-layout/custom-layout.md
index ca327aaa57b69..0125630db5b10 100644
--- a/docs/data/date-pickers/custom-layout/custom-layout.md
+++ b/docs/data/date-pickers/custom-layout/custom-layout.md
@@ -86,14 +86,17 @@ import {
} from '@mui/x-date-pickers/PickersLayout';
function MyCustomLayout(props) {
- const { toolbar, tabs, content, actionBar } = usePickerLayout(props);
+ const { toolbar, tabs, content, actionBar, ownerState } = usePickerLayout(props);
// Put the action bar before the content
return (
-
+
{toolbar}
{actionBar}
-
+
{tabs}
{content}
diff --git a/docs/data/migration/migration-pickers-v5/MobileKeyboardView.js b/docs/data/migration/migration-pickers-v5/MobileKeyboardView.js
index 95819b45ed99f..c2810ae4c1e2f 100644
--- a/docs/data/migration/migration-pickers-v5/MobileKeyboardView.js
+++ b/docs/data/migration/migration-pickers-v5/MobileKeyboardView.js
@@ -1,100 +1,16 @@
import * as React from 'react';
-import Box from '@mui/material/Box';
-import Stack from '@mui/material/Stack';
-import IconButton from '@mui/material/IconButton';
-import ModeEditIcon from '@mui/icons-material/ModeEdit';
-import CalendarMonthIcon from '@mui/icons-material/CalendarMonth';
-import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
-import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
-
-import {
- pickersLayoutClasses,
- PickersLayoutContentWrapper,
- PickersLayoutRoot,
- usePickerLayout,
-} from '@mui/x-date-pickers/PickersLayout';
-import { MobileDatePicker } from '@mui/x-date-pickers/MobileDatePicker';
-import { DateField } from '@mui/x-date-pickers/DateField';
-import { DatePickerToolbar } from '@mui/x-date-pickers/DatePicker';
-
-function LayoutWithKeyboardView(props) {
- const { value, onChange } = props;
- const [showKeyboardView, setShowKeyboardView] = React.useState(false);
-
- const { toolbar, tabs, content, actionBar } = usePickerLayout({
- ...props,
- slotProps: {
- ...props.slotProps,
- toolbar: {
- ...props.slotProps?.toolbar,
- // @ts-ignore
- showKeyboardViewSwitch: props.wrapperVariant === 'mobile',
- showKeyboardView,
- setShowKeyboardView,
- },
- },
- });
-
- return (
-
- {toolbar}
- {actionBar}
-
- {tabs}
- {showKeyboardView ? (
-
-
-
- ) : (
- content
- )}
-
-
- );
-}
-
-function ToolbarWithKeyboardViewSwitch(props) {
- const { showKeyboardViewSwitch, showKeyboardView, setShowKeyboardView, ...other } =
- props;
-
- if (showKeyboardViewSwitch) {
- return (
-
-
- setShowKeyboardView((prev) => !prev)}
- >
- {showKeyboardView ? : }
-
-
- );
- }
-
- return ;
-}
export default function MobileKeyboardView() {
return (
-
-
-
+
);
}
diff --git a/docs/data/migration/migration-pickers-v5/MobileKeyboardView.tsx b/docs/data/migration/migration-pickers-v5/MobileKeyboardView.tsx
deleted file mode 100644
index 97a25bbfc0363..0000000000000
--- a/docs/data/migration/migration-pickers-v5/MobileKeyboardView.tsx
+++ /dev/null
@@ -1,110 +0,0 @@
-import * as React from 'react';
-import { Dayjs } from 'dayjs';
-import Box from '@mui/material/Box';
-import Stack from '@mui/material/Stack';
-import IconButton from '@mui/material/IconButton';
-import ModeEditIcon from '@mui/icons-material/ModeEdit';
-import CalendarMonthIcon from '@mui/icons-material/CalendarMonth';
-import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
-import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
-import { DateView } from '@mui/x-date-pickers/models';
-import {
- pickersLayoutClasses,
- PickersLayoutContentWrapper,
- PickersLayoutRoot,
- PickersLayoutProps,
- usePickerLayout,
-} from '@mui/x-date-pickers/PickersLayout';
-import { MobileDatePicker } from '@mui/x-date-pickers/MobileDatePicker';
-import { DateField } from '@mui/x-date-pickers/DateField';
-import {
- DatePickerToolbar,
- DatePickerToolbarProps,
-} from '@mui/x-date-pickers/DatePicker';
-
-function LayoutWithKeyboardView(props: PickersLayoutProps) {
- const { value, onChange } = props;
- const [showKeyboardView, setShowKeyboardView] = React.useState(false);
-
- const { toolbar, tabs, content, actionBar } = usePickerLayout({
- ...props,
- slotProps: {
- ...props.slotProps,
- toolbar: {
- ...props.slotProps?.toolbar,
- // @ts-ignore
- showKeyboardViewSwitch: props.wrapperVariant === 'mobile',
- showKeyboardView,
- setShowKeyboardView,
- },
- },
- });
-
- return (
-
- {toolbar}
- {actionBar}
-
- {tabs}
- {showKeyboardView ? (
-
-
-
- ) : (
- content
- )}
-
-
- );
-}
-
-function ToolbarWithKeyboardViewSwitch(
- props: DatePickerToolbarProps & {
- showKeyboardViewSwitch?: boolean;
- showKeyboardView?: boolean;
- setShowKeyboardView?: React.Dispatch>;
- },
-) {
- const { showKeyboardViewSwitch, showKeyboardView, setShowKeyboardView, ...other } =
- props;
-
- if (showKeyboardViewSwitch) {
- return (
-
-
- setShowKeyboardView!((prev) => !prev)}
- >
- {showKeyboardView ? : }
-
-
- );
- }
-
- return ;
-}
-export default function MobileKeyboardView() {
- return (
-
-
-
- );
-}
diff --git a/docs/data/migration/migration-pickers-v5/MobileKeyboardView.tsx.preview b/docs/data/migration/migration-pickers-v5/MobileKeyboardView.tsx.preview
deleted file mode 100644
index 590d8472a0686..0000000000000
--- a/docs/data/migration/migration-pickers-v5/MobileKeyboardView.tsx.preview
+++ /dev/null
@@ -1,6 +0,0 @@
-
\ No newline at end of file
diff --git a/docs/data/migration/migration-pickers-v5/migration-pickers-v5.md b/docs/data/migration/migration-pickers-v5/migration-pickers-v5.md
index eb49f8db9948e..5158e716d5954 100644
--- a/docs/data/migration/migration-pickers-v5/migration-pickers-v5.md
+++ b/docs/data/migration/migration-pickers-v5/migration-pickers-v5.md
@@ -172,7 +172,7 @@ The picker components no longer have a keyboard view to render the input inside
- If you want to keep the old keyboard view, you can pass a custom `Layout` component slot to re-introduce the keyboard view.
-{{"demo": "MobileKeyboardView.js", "defaultCodeOpen": false}}
+{{"demo": "MobileKeyboardView.js", "hideToolbar": true, "bg": true}}
:::info
At some point, the mobile pickers should have a prop allowing to have an editable field without opening the modal.
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 7bf73fde6c0ca..e078caa090c20 100644
--- a/docs/data/migration/migration-pickers-v7/migration-pickers-v7.md
+++ b/docs/data/migration/migration-pickers-v7/migration-pickers-v7.md
@@ -258,6 +258,22 @@ const theme = createTheme({
### Slot: `layout`
+- The `` and `` components must now receive the `ownerState` returned by `usePickerLayout` instead of their props:
+
+ ```diff
+ -const { toolbar, tabs, content, actionBar } = usePickerLayout(props);
+ +const { toolbar, tabs, content, actionBar, ownerState } = usePickerLayout(props);
+
+ return (
+ -
+ +
+ -
+ +
+
+
+ );
+ ```
+
- The component passed to the `layout` slot no longer receives a `disabled` prop, instead you can use the `usePickerContext` hook:
```diff
@@ -276,6 +292,39 @@ const theme = createTheme({
+console.log(readOnly);
```
+- The component passed to the `layout` slot no longer receives an `isRtl` prop. If you need to access this information, you can use the `useRtl` hook from `@mui/system`:
+
+ ```diff
+ +import { useRtl } from '@mui/system/RtlProvider';
+ function CustomLayout(props) {
+ - console.log(props.isRtl);
+ + const isRtl = useRtl();
+ + console.log(isRtl);
+ }
+ ```
+
+- The component passed to the `layout` slot no longer receives an `orientation` and the `isLandscape` props, instead you can use the `usePickerContext` hook:
+
+ ```diff
+ -console.log(props.orientation);
+ +import { usePickerContext } from '@mui/x-date-pickers/hooks';
+ +const { orientation } = usePickerContext();
+ +console.log(orientation);
+ -console.log(props.isLandscape);
+ +import { usePickerContext } from '@mui/x-date-pickers/hooks';
+ +const { orientation } = usePickerContext();
+ +console.log(orientation === 'landscape');
+ ```
+
+- The component passed to the `layout` slot no longer receives a `wrapperVariant` prop, instead you can use the `usePickerContext` hook:
+
+ ```diff
+ -console.log(props.wrapperVariant);
+ +import { usePickerContext } from '@mui/x-date-pickers/hooks';
+ +const { variant } = usePickerContext();
+ +console.log(variant);
+ ```
+
### Slot: `toolbar`
- The component passed to the `toolbar` slot no longer receives a `disabled` prop, instead you can use the `usePickerContext` hook:
diff --git a/docs/pages/x/api/date-pickers/pickers-layout.json b/docs/pages/x/api/date-pickers/pickers-layout.json
index e75869f624a4f..56c29a639e392 100644
--- a/docs/pages/x/api/date-pickers/pickers-layout.json
+++ b/docs/pages/x/api/date-pickers/pickers-layout.json
@@ -1,10 +1,6 @@
{
"props": {
- "isRtl": { "type": { "name": "bool" }, "required": true },
"classes": { "type": { "name": "object" }, "additionalInfo": { "cssApi": true } },
- "orientation": {
- "type": { "name": "enum", "description": "'landscape'
| 'portrait'" }
- },
"slotProps": { "type": { "name": "object" }, "default": "{}" },
"slots": {
"type": { "name": "object" },
diff --git a/docs/src/modules/components/overview/mainDemo/Clock.tsx b/docs/src/modules/components/overview/mainDemo/Clock.tsx
index 6ca16f44532e0..1b574dede42c1 100644
--- a/docs/src/modules/components/overview/mainDemo/Clock.tsx
+++ b/docs/src/modules/components/overview/mainDemo/Clock.tsx
@@ -32,11 +32,14 @@ const StyledLayout = styled(PickersLayoutRoot)({
});
function CustomLayout(props: PickersLayoutProps) {
- const { actionBar, content, toolbar } = usePickerLayout(props);
+ const { actionBar, content, toolbar, ownerState } = usePickerLayout(props);
return (
-
+
{toolbar}
-
+
{content}
{actionBar}
diff --git a/docs/src/modules/components/overview/mainDemo/DateRangeWithShortcuts.tsx b/docs/src/modules/components/overview/mainDemo/DateRangeWithShortcuts.tsx
index c8a9df4ce611c..1df001d638f38 100644
--- a/docs/src/modules/components/overview/mainDemo/DateRangeWithShortcuts.tsx
+++ b/docs/src/modules/components/overview/mainDemo/DateRangeWithShortcuts.tsx
@@ -60,11 +60,11 @@ interface CustomLayoutProps extends PickersLayoutProps, 'day'>
}
function CustomLayout(props: CustomLayoutProps) {
const { isHorizontal, ...other } = props;
- const { tabs, content, shortcuts } = usePickerLayout(other);
+ const { tabs, content, shortcuts, ownerState } = usePickerLayout(other);
return (
{shortcuts}
-
+
{tabs}
{content}
diff --git a/docs/src/modules/components/overview/mainDemo/DigitalClock.tsx b/docs/src/modules/components/overview/mainDemo/DigitalClock.tsx
index b6959d39ed3f4..7f09eedfee04a 100644
--- a/docs/src/modules/components/overview/mainDemo/DigitalClock.tsx
+++ b/docs/src/modules/components/overview/mainDemo/DigitalClock.tsx
@@ -25,10 +25,13 @@ const StyledLayout = styled(PickersLayoutRoot)({
});
function CustomLayout(props: PickersLayoutProps) {
- const { actionBar, content } = usePickerLayout(props);
+ const { actionBar, content, ownerState } = usePickerLayout(props);
return (
-
-
+
+
{content}
{actionBar}
diff --git a/docs/translations/api-docs/date-pickers/pickers-layout/pickers-layout.json b/docs/translations/api-docs/date-pickers/pickers-layout/pickers-layout.json
index 57a28904a850c..95c79d94d495a 100644
--- a/docs/translations/api-docs/date-pickers/pickers-layout/pickers-layout.json
+++ b/docs/translations/api-docs/date-pickers/pickers-layout/pickers-layout.json
@@ -2,10 +2,6 @@
"componentDescription": "",
"propDescriptions": {
"classes": { "description": "Override or extend the styles applied to the component." },
- "isRtl": {
- "description": "true
if the application is in right-to-left direction."
- },
- "orientation": { "description": "Force rendering in particular orientation." },
"slotProps": { "description": "The props used for each component slot." },
"slots": { "description": "Overridable component slots." },
"sx": {
diff --git a/packages/x-date-pickers/src/DesktopDateTimePicker/DesktopDateTimePickerLayout.tsx b/packages/x-date-pickers/src/DesktopDateTimePicker/DesktopDateTimePickerLayout.tsx
index 6747b1a308b5e..6f4b75e7ecb88 100644
--- a/packages/x-date-pickers/src/DesktopDateTimePicker/DesktopDateTimePickerLayout.tsx
+++ b/packages/x-date-pickers/src/DesktopDateTimePicker/DesktopDateTimePickerLayout.tsx
@@ -1,7 +1,6 @@
import * as React from 'react';
import PropTypes from 'prop-types';
import clsx from 'clsx';
-import { useRtl } from '@mui/system/RtlProvider';
import Divider from '@mui/material/Divider';
import {
PickersLayoutContentWrapper,
@@ -11,6 +10,7 @@ import {
usePickerLayout,
} from '../PickersLayout';
import { DateOrTimeViewWithMeridiem } from '../internals/models/common';
+import { usePickerContext } from '../hooks/usePickerContext';
type DesktopDateTimePickerLayoutComponent = ((
props: PickersLayoutProps & React.RefAttributes,
@@ -23,11 +23,10 @@ const DesktopDateTimePickerLayout = React.forwardRef(function DesktopDateTimePic
TValue,
TView extends DateOrTimeViewWithMeridiem,
>(props: PickersLayoutProps, ref: React.Ref) {
- const isRtl = useRtl();
- const { toolbar, tabs, content, actionBar, shortcuts } = usePickerLayout(props);
- const { sx, className, isLandscape, classes } = props;
+ const { toolbar, tabs, content, actionBar, shortcuts, ownerState } = usePickerLayout(props);
+ const { orientation } = usePickerContext();
+ const { sx, className, classes } = props;
const isActionBarVisible = actionBar && (actionBar.props.actions?.length ?? 0) > 0;
- const ownerState = { ...props, isRtl };
return (
- {isLandscape ? shortcuts : toolbar}
- {isLandscape ? toolbar : shortcuts}
+ {orientation === 'landscape' ? shortcuts : toolbar}
+ {orientation === 'landscape' ? toolbar : shortcuts}
{content}
@@ -68,11 +68,6 @@ DesktopDateTimePickerLayout.propTypes = {
*/
classes: PropTypes.object,
className: PropTypes.string,
- isLandscape: PropTypes.bool.isRequired,
- /**
- * `true` if the application is in right-to-left direction.
- */
- isRtl: PropTypes.bool.isRequired,
isValid: PropTypes.func.isRequired,
onAccept: PropTypes.func.isRequired,
onCancel: PropTypes.func.isRequired,
@@ -84,10 +79,6 @@ DesktopDateTimePickerLayout.propTypes = {
onSelectShortcut: PropTypes.func.isRequired,
onSetToday: PropTypes.func.isRequired,
onViewChange: PropTypes.func.isRequired,
- /**
- * Force rendering in particular orientation.
- */
- orientation: PropTypes.oneOf(['landscape', 'portrait']),
/**
* The props used for each component slot.
* @default {}
@@ -111,7 +102,6 @@ DesktopDateTimePickerLayout.propTypes = {
views: PropTypes.arrayOf(
PropTypes.oneOf(['day', 'hours', 'meridiem', 'minutes', 'month', 'seconds', 'year']).isRequired,
).isRequired,
- wrapperVariant: PropTypes.oneOf(['desktop', 'mobile']),
} as any;
export { DesktopDateTimePickerLayout };
diff --git a/packages/x-date-pickers/src/PickersLayout/PickersLayout.tsx b/packages/x-date-pickers/src/PickersLayout/PickersLayout.tsx
index 7725cea5e8e5c..dcb977d1b3ab8 100644
--- a/packages/x-date-pickers/src/PickersLayout/PickersLayout.tsx
+++ b/packages/x-date-pickers/src/PickersLayout/PickersLayout.tsx
@@ -4,15 +4,23 @@ import PropTypes from 'prop-types';
import clsx from 'clsx';
import { styled, useThemeProps } from '@mui/material/styles';
import composeClasses from '@mui/utils/composeClasses';
-import { PickersLayoutProps } from './PickersLayout.types';
-import { pickersLayoutClasses, getPickersLayoutUtilityClass } from './pickersLayoutClasses';
+import { PickerLayoutOwnerState, PickersLayoutProps } from './PickersLayout.types';
+import {
+ pickersLayoutClasses,
+ getPickersLayoutUtilityClass,
+ PickersLayoutClasses,
+} from './pickersLayoutClasses';
import usePickerLayout from './usePickerLayout';
import { DateOrTimeViewWithMeridiem } from '../internals/models';
+import { usePickerContext } from '../hooks/usePickerContext';
-const useUtilityClasses = (ownerState: PickersLayoutProps) => {
- const { isLandscape, classes } = ownerState;
+const useUtilityClasses = (
+ classes: Partial | undefined,
+ ownerState: PickerLayoutOwnerState,
+) => {
+ const { pickerOrientation } = ownerState;
const slots = {
- root: ['root', isLandscape && 'landscape'],
+ root: ['root', pickerOrientation === 'landscape' && 'landscape'],
contentWrapper: ['contentWrapper'],
};
@@ -23,14 +31,14 @@ export const PickersLayoutRoot = styled('div', {
name: 'MuiPickersLayout',
slot: 'Root',
overridesResolver: (props, styles) => styles.root,
-})<{ ownerState: PickersLayoutProps }>({
+})<{ ownerState: PickerLayoutOwnerState }>({
display: 'grid',
gridAutoColumns: 'max-content auto max-content',
gridAutoRows: 'max-content auto max-content',
[`& .${pickersLayoutClasses.actionBar}`]: { gridColumn: '1 / 4', gridRow: 3 },
variants: [
{
- props: { isLandscape: true },
+ props: { pickerOrientation: 'landscape' },
style: {
[`& .${pickersLayoutClasses.toolbar}`]: {
gridColumn: 1,
@@ -40,7 +48,7 @@ export const PickersLayoutRoot = styled('div', {
},
},
{
- props: { isLandscape: true, isRtl: true },
+ props: { pickerOrientation: 'landscape', isRtl: true },
style: {
[`& .${pickersLayoutClasses.toolbar}`]: {
gridColumn: 3,
@@ -48,7 +56,7 @@ export const PickersLayoutRoot = styled('div', {
},
},
{
- props: { isLandscape: false },
+ props: { pickerOrientation: 'portrait' },
style: {
[`& .${pickersLayoutClasses.toolbar}`]: { gridColumn: '2 / 4', gridRow: 1 },
[`& .${pickersLayoutClasses.shortcuts}`]: {
@@ -58,7 +66,7 @@ export const PickersLayoutRoot = styled('div', {
},
},
{
- props: { isLandscape: false, isRtl: true },
+ props: { pickerOrientation: 'portrait', isRtl: true },
style: {
[`& .${pickersLayoutClasses.shortcuts}`]: {
gridColumn: 3,
@@ -72,7 +80,7 @@ export const PickersLayoutContentWrapper = styled('div', {
name: 'MuiPickersLayout',
slot: 'ContentWrapper',
overridesResolver: (props, styles) => styles.contentWrapper,
-})({
+})<{ ownerState: PickerLayoutOwnerState }>({
gridColumn: 2,
gridRow: 2,
display: 'flex',
@@ -98,22 +106,23 @@ const PickersLayout = React.forwardRef(function PickersLayout<
>(inProps: PickersLayoutProps, ref: React.Ref) {
const props = useThemeProps({ props: inProps, name: 'MuiPickersLayout' });
- const { toolbar, content, tabs, actionBar, shortcuts } = usePickerLayout(props);
- const { sx, className, isLandscape, wrapperVariant } = props;
+ const { toolbar, content, tabs, actionBar, shortcuts, ownerState } = usePickerLayout(props);
+ const { orientation, variant } = usePickerContext();
+ const { sx, className, classes: classesProp } = props;
- const classes = useUtilityClasses(props);
+ const classes = useUtilityClasses(classesProp, ownerState);
return (
- {isLandscape ? shortcuts : toolbar}
- {isLandscape ? toolbar : shortcuts}
-
- {wrapperVariant === 'desktop' ? (
+ {orientation === 'landscape' ? shortcuts : toolbar}
+ {orientation === 'landscape' ? toolbar : shortcuts}
+
+ {variant === 'desktop' ? (
{content}
{tabs}
@@ -141,11 +150,6 @@ PickersLayout.propTypes = {
*/
classes: PropTypes.object,
className: PropTypes.string,
- isLandscape: PropTypes.bool.isRequired,
- /**
- * `true` if the application is in right-to-left direction.
- */
- isRtl: PropTypes.bool.isRequired,
isValid: PropTypes.func.isRequired,
onAccept: PropTypes.func.isRequired,
onCancel: PropTypes.func.isRequired,
@@ -157,10 +161,6 @@ PickersLayout.propTypes = {
onSelectShortcut: PropTypes.func.isRequired,
onSetToday: PropTypes.func.isRequired,
onViewChange: PropTypes.func.isRequired,
- /**
- * Force rendering in particular orientation.
- */
- orientation: PropTypes.oneOf(['landscape', 'portrait']),
/**
* The props used for each component slot.
* @default {}
@@ -184,7 +184,6 @@ PickersLayout.propTypes = {
views: PropTypes.arrayOf(
PropTypes.oneOf(['day', 'hours', 'meridiem', 'minutes', 'month', 'seconds', 'year']).isRequired,
).isRequired,
- wrapperVariant: PropTypes.oneOf(['desktop', 'mobile']),
} as any;
export { PickersLayout };
diff --git a/packages/x-date-pickers/src/PickersLayout/PickersLayout.types.ts b/packages/x-date-pickers/src/PickersLayout/PickersLayout.types.ts
index f35f7ff6755d3..bb2b12ba329b0 100644
--- a/packages/x-date-pickers/src/PickersLayout/PickersLayout.types.ts
+++ b/packages/x-date-pickers/src/PickersLayout/PickersLayout.types.ts
@@ -4,15 +4,16 @@ import { SlotComponentProps } from '@mui/utils';
import { PickersActionBar, PickersActionBarProps } from '../PickersActionBar';
import { BaseToolbarProps, ExportedBaseToolbarProps } from '../internals/models/props/toolbar';
import { BaseTabsProps, ExportedBaseTabsProps } from '../internals/models/props/tabs';
-import { UsePickerLayoutPropsResponseLayoutProps } from '../internals/hooks/usePicker/usePickerLayoutProps';
import { PickersLayoutClasses } from './pickersLayoutClasses';
-import { DateOrTimeViewWithMeridiem, PickerVariant } from '../internals/models/common';
+import { DateOrTimeViewWithMeridiem } from '../internals/models/common';
import { PickersShortcutsProps } from '../PickersShortcuts';
import {
ExportedPickersShortcutProps,
PickersShortcuts,
} from '../PickersShortcuts/PickersShortcuts';
import { PickerOwnerState } from '../models';
+import { UsePickerViewsLayoutResponse } from '../internals/hooks/usePicker/usePickerViews';
+import { UsePickerValueLayoutResponse } from '../internals/hooks/usePicker/usePickerValue.types';
export interface ExportedPickersLayoutSlots {
/**
@@ -35,8 +36,11 @@ export interface ExportedPickersLayoutSlots {
@@ -80,7 +84,8 @@ export interface PickersLayoutSlotProps
- extends Omit, 'value'> {
+ extends UsePickerViewsLayoutResponse,
+ Omit, 'value'> {
value?: TValue;
className?: string;
children?: React.ReactNode;
@@ -102,10 +107,6 @@ export interface PickersLayoutProps;
- /**
- * `true` if the application is in right-to-left direction.
- */
- isRtl: boolean;
}
export interface SubComponents {
diff --git a/packages/x-date-pickers/src/PickersLayout/usePickerLayout.tsx b/packages/x-date-pickers/src/PickersLayout/usePickerLayout.tsx
index 66c54565a34c3..ae978ffe1a0ea 100644
--- a/packages/x-date-pickers/src/PickersLayout/usePickerLayout.tsx
+++ b/packages/x-date-pickers/src/PickersLayout/usePickerLayout.tsx
@@ -2,6 +2,7 @@
import * as React from 'react';
import useSlotProps from '@mui/utils/useSlotProps';
import composeClasses from '@mui/utils/composeClasses';
+import { useRtl } from '@mui/system/RtlProvider';
import { PickersActionBar, PickersActionBarAction } from '../PickersActionBar';
import { PickerLayoutOwnerState, PickersLayoutProps, SubComponents } from './PickersLayout.types';
import { getPickersLayoutUtilityClass, PickersLayoutClasses } from './pickersLayoutClasses';
@@ -9,6 +10,7 @@ import { PickersShortcuts } from '../PickersShortcuts';
import { BaseToolbarProps } from '../internals/models/props/toolbar';
import { DateOrTimeViewWithMeridiem } from '../internals/models';
import { usePickerPrivateContext } from '../internals/hooks/usePickerPrivateContext';
+import { usePickerContext } from '../hooks';
function toolbarHasView(
toolbarProps: BaseToolbarProps | any,
@@ -20,9 +22,9 @@ const useUtilityClasses = (
classes: Partial | undefined,
ownerState: PickerLayoutOwnerState,
) => {
- const { isLandscape } = ownerState;
+ const { pickerOrientation } = ownerState;
const slots = {
- root: ['root', isLandscape && 'landscape'],
+ root: ['root', pickerOrientation === 'landscape' && 'landscape'],
contentWrapper: ['contentWrapper'],
toolbar: ['toolbar'],
actionBar: ['actionBar'],
@@ -38,15 +40,19 @@ interface PickersLayoutPropsWithValueRequired {
value: TValue;
}
-interface UsePickerLayoutResponse extends SubComponents {}
+
+interface UsePickerLayoutResponse extends SubComponents {
+ ownerState: PickerLayoutOwnerState;
+}
const usePickerLayout = (
props: PickersLayoutProps,
): UsePickerLayoutResponse => {
- const { ownerState: pickersOwnerState } = usePickerPrivateContext();
+ const { ownerState: pickerOwnerState } = usePickerPrivateContext();
+ const { variant, orientation } = usePickerContext();
+ const isRtl = useRtl();
const {
- wrapperVariant,
onAccept,
onClear,
onCancel,
@@ -58,7 +64,6 @@ const usePickerLayout = (
onChange,
onSelectShortcut,
isValid,
- isLandscape,
children,
slots,
slotProps,
@@ -69,11 +74,7 @@ const usePickerLayout = (
// - For range pickers value: [PickerValidDate | null, PickerValidDate | null]
} = props as PickersLayoutPropsWithValueRequired;
- const ownerState: PickerLayoutOwnerState = {
- ...pickersOwnerState,
- wrapperVariant,
- isLandscape,
- };
+ const ownerState: PickerLayoutOwnerState = { ...pickerOwnerState, isRtl };
const classes = useUtilityClasses(classesProp, ownerState);
// Action bar
@@ -86,8 +87,7 @@ const usePickerLayout = (
onClear,
onCancel,
onSetToday,
- actions:
- wrapperVariant === 'desktop' ? [] : (['cancel', 'accept'] as PickersActionBarAction[]),
+ actions: variant === 'desktop' ? [] : (['cancel', 'accept'] as PickersActionBarAction[]),
},
className: classes.actionBar,
ownerState,
@@ -100,7 +100,7 @@ const usePickerLayout = (
elementType: Toolbar!,
externalSlotProps: slotProps?.toolbar,
additionalProps: {
- isLandscape,
+ isLandscape: orientation === 'landscape', // Will be removed in a follow up PR?
onChange,
value,
view,
@@ -129,7 +129,7 @@ const usePickerLayout = (
externalSlotProps: slotProps?.shortcuts,
additionalProps: {
isValid,
- isLandscape,
+ isLandscape: orientation === 'landscape', // Will be removed in a follow up PR?
onChange: onSelectShortcut,
},
className: classes.shortcuts,
@@ -143,6 +143,7 @@ const usePickerLayout = (
tabs,
actionBar,
shortcuts,
+ ownerState,
};
};
diff --git a/packages/x-date-pickers/src/internals/hooks/useIsLandscape.tsx b/packages/x-date-pickers/src/internals/hooks/useIsLandscape.tsx
deleted file mode 100644
index 200bb74b7cd23..0000000000000
--- a/packages/x-date-pickers/src/internals/hooks/useIsLandscape.tsx
+++ /dev/null
@@ -1,48 +0,0 @@
-import * as React from 'react';
-import { unstable_useEnhancedEffect as useEnhancedEffect } from '@mui/utils';
-import { arrayIncludes } from '../utils/utils';
-import { DateOrTimeViewWithMeridiem } from '../models';
-
-type Orientation = 'portrait' | 'landscape';
-
-function getOrientation(): Orientation {
- if (typeof window === 'undefined') {
- return 'portrait';
- }
-
- if (window.screen && window.screen.orientation && window.screen.orientation.angle) {
- return Math.abs(window.screen.orientation.angle) === 90 ? 'landscape' : 'portrait';
- }
-
- // Support IOS safari
- if (window.orientation) {
- return Math.abs(Number(window.orientation)) === 90 ? 'landscape' : 'portrait';
- }
-
- return 'portrait';
-}
-
-export const useIsLandscape = (
- views: readonly DateOrTimeViewWithMeridiem[],
- customOrientation: Orientation | undefined,
-): boolean => {
- const [orientation, setOrientation] = React.useState(getOrientation);
-
- useEnhancedEffect(() => {
- const eventHandler = () => {
- setOrientation(getOrientation());
- };
- window.addEventListener('orientationchange', eventHandler);
- return () => {
- window.removeEventListener('orientationchange', eventHandler);
- };
- }, []);
-
- if (arrayIncludes(views, ['hours', 'minutes', 'seconds'])) {
- // could not display 13:34:44 in landscape mode
- return false;
- }
-
- const orientationToUse = customOrientation || orientation;
- return orientationToUse === 'landscape';
-};
diff --git a/packages/x-date-pickers/src/internals/hooks/usePicker/usePicker.ts b/packages/x-date-pickers/src/internals/hooks/usePicker/usePicker.ts
index 828d8b9df9c76..441295d6a64c6 100644
--- a/packages/x-date-pickers/src/internals/hooks/usePicker/usePicker.ts
+++ b/packages/x-date-pickers/src/internals/hooks/usePicker/usePicker.ts
@@ -2,7 +2,6 @@ import { warnOnce } from '@mui/x-internals/warning';
import { UsePickerParams, UsePickerProps, UsePickerResponse } from './usePicker.types';
import { usePickerValue } from './usePickerValue';
import { usePickerViews } from './usePickerViews';
-import { usePickerLayoutProps } from './usePickerLayoutProps';
import { FieldSection, InferError } from '../../../models';
import { DateOrTimeViewWithMeridiem } from '../../models';
import { usePickerProvider } from './usePickerProvider';
@@ -62,13 +61,6 @@ export const usePicker = <
rendererInterceptor,
});
- const pickerLayoutResponse = usePickerLayoutProps({
- props,
- variant,
- propsFromPickerValue: pickerValueResponse.layoutProps,
- propsFromPickerViews: pickerViewsResponse.layoutProps,
- });
-
const providerProps = usePickerProvider({
props,
pickerValueResponse,
@@ -90,7 +82,10 @@ export const usePicker = <
shouldRestoreFocus: pickerViewsResponse.shouldRestoreFocus,
// Picker layout
- layoutProps: pickerLayoutResponse.layoutProps,
+ layoutProps: {
+ ...pickerViewsResponse.layoutProps,
+ ...pickerValueResponse.layoutProps,
+ },
// Picker provider
providerProps,
diff --git a/packages/x-date-pickers/src/internals/hooks/usePicker/usePicker.types.ts b/packages/x-date-pickers/src/internals/hooks/usePicker/usePicker.types.ts
index a2c252d807d4c..176ba741efc1b 100644
--- a/packages/x-date-pickers/src/internals/hooks/usePicker/usePicker.types.ts
+++ b/packages/x-date-pickers/src/internals/hooks/usePicker/usePicker.types.ts
@@ -10,7 +10,6 @@ import {
UsePickerViewsResponse,
UsePickerViewsBaseProps,
} from './usePickerViews';
-import { UsePickerLayoutPropsResponse } from './usePickerLayoutProps';
import { FieldSection, PickerOwnerState } from '../../../models';
import { DateOrTimeViewWithMeridiem } from '../../models';
import {
@@ -66,8 +65,9 @@ export interface UsePickerResponse<
TSection extends FieldSection,
TError,
> extends Omit, 'viewProps' | 'layoutProps'>,
- Omit, 'layoutProps' | 'views'>,
- UsePickerLayoutPropsResponse {
+ Omit, 'layoutProps' | 'views'> {
ownerState: PickerOwnerState;
providerProps: UsePickerProviderReturnValue;
+ layoutProps: UsePickerValueResponse['layoutProps'] &
+ UsePickerViewsResponse['layoutProps'];
}
diff --git a/packages/x-date-pickers/src/internals/hooks/usePicker/usePickerLayoutProps.ts b/packages/x-date-pickers/src/internals/hooks/usePicker/usePickerLayoutProps.ts
deleted file mode 100644
index b110bc0f0b603..0000000000000
--- a/packages/x-date-pickers/src/internals/hooks/usePicker/usePickerLayoutProps.ts
+++ /dev/null
@@ -1,62 +0,0 @@
-import { useRtl } from '@mui/system/RtlProvider';
-import { useIsLandscape } from '../useIsLandscape';
-import { UsePickerValueLayoutResponse } from './usePickerValue.types';
-import { UsePickerViewsLayoutResponse } from './usePickerViews';
-import { DateOrTimeViewWithMeridiem, PickerVariant } from '../../models/common';
-
-/**
- * Props used to create the layout of the views.
- */
-interface UsePickerLayoutProps {
- /**
- * Force rendering in particular orientation.
- */
- orientation?: 'portrait' | 'landscape';
-}
-
-export interface UsePickerLayoutPropsResponseLayoutProps<
- TValue,
- TView extends DateOrTimeViewWithMeridiem,
-> extends UsePickerValueLayoutResponse,
- UsePickerViewsLayoutResponse,
- UsePickerLayoutProps {
- isLandscape: boolean;
- isRtl: boolean;
- wrapperVariant: PickerVariant;
- isValid: (value: TValue) => boolean;
-}
-
-export interface UsePickerLayoutPropsResponse {
- layoutProps: UsePickerLayoutPropsResponseLayoutProps;
-}
-
-export interface UsePickerLayoutPropsParams {
- props: UsePickerLayoutProps;
- propsFromPickerValue: UsePickerValueLayoutResponse;
- propsFromPickerViews: UsePickerViewsLayoutResponse;
- variant: PickerVariant;
-}
-
-/**
- * Prepare the props for the view layout (managed by `PickersLayout`)
- */
-export const usePickerLayoutProps = ({
- props,
- propsFromPickerValue,
- propsFromPickerViews,
- variant,
-}: UsePickerLayoutPropsParams): UsePickerLayoutPropsResponse => {
- const { orientation } = props;
- const isLandscape = useIsLandscape(propsFromPickerViews.views, orientation);
- const isRtl = useRtl();
-
- const layoutProps: UsePickerLayoutPropsResponseLayoutProps = {
- ...propsFromPickerViews,
- ...propsFromPickerValue,
- isLandscape,
- isRtl,
- wrapperVariant: variant,
- };
-
- return { layoutProps };
-};