diff --git a/docs/data/date-pickers/date-picker/examplesConfig.styling.tsx b/docs/data/date-pickers/date-picker/examplesConfig.styling.tsx
index 0e1a6e4e8c4e1..0dcfa75edfdf0 100644
--- a/docs/data/date-pickers/date-picker/examplesConfig.styling.tsx
+++ b/docs/data/date-pickers/date-picker/examplesConfig.styling.tsx
@@ -272,7 +272,7 @@ export const datePickerExamples: PickersSubcomponentType = {
slots: ['root'],
moreInformation: ,
},
- PickersPopper: {
+ PickerPopper: {
examples: {
customTheme: {
type: 'success',
diff --git a/docs/pages/x/api/date-pickers/date-picker.json b/docs/pages/x/api/date-pickers/date-picker.json
index e27298dacae1d..6675d1b94e4f3 100644
--- a/docs/pages/x/api/date-pickers/date-picker.json
+++ b/docs/pages/x/api/date-pickers/date-picker.json
@@ -232,7 +232,7 @@
{
"name": "desktopPaper",
"description": "Custom component for the paper rendered inside the desktop picker's Popper.",
- "default": "PickersPopperPaper",
+ "default": "PickerPopperPaper",
"class": null
},
{
diff --git a/docs/pages/x/api/date-pickers/date-range-picker.json b/docs/pages/x/api/date-pickers/date-range-picker.json
index 9ee6734f43842..2c73f0d253d68 100644
--- a/docs/pages/x/api/date-pickers/date-range-picker.json
+++ b/docs/pages/x/api/date-pickers/date-range-picker.json
@@ -194,7 +194,7 @@
{
"name": "desktopPaper",
"description": "Custom component for the paper rendered inside the desktop picker's Popper.",
- "default": "PickersPopperPaper",
+ "default": "PickerPopperPaper",
"class": null
},
{
diff --git a/docs/pages/x/api/date-pickers/date-time-picker.json b/docs/pages/x/api/date-pickers/date-time-picker.json
index 4f43b0337b63c..55f19a6faa1a4 100644
--- a/docs/pages/x/api/date-pickers/date-time-picker.json
+++ b/docs/pages/x/api/date-pickers/date-time-picker.json
@@ -257,7 +257,7 @@
{
"name": "desktopPaper",
"description": "Custom component for the paper rendered inside the desktop picker's Popper.",
- "default": "PickersPopperPaper",
+ "default": "PickerPopperPaper",
"class": null
},
{
diff --git a/docs/pages/x/api/date-pickers/date-time-range-picker.json b/docs/pages/x/api/date-pickers/date-time-range-picker.json
index 7487f6b6418ea..3031cef327313 100644
--- a/docs/pages/x/api/date-pickers/date-time-range-picker.json
+++ b/docs/pages/x/api/date-pickers/date-time-range-picker.json
@@ -242,7 +242,7 @@
{
"name": "desktopPaper",
"description": "Custom component for the paper rendered inside the desktop picker's Popper.",
- "default": "PickersPopperPaper",
+ "default": "PickerPopperPaper",
"class": null
},
{
diff --git a/docs/pages/x/api/date-pickers/desktop-date-picker.json b/docs/pages/x/api/date-pickers/desktop-date-picker.json
index 22c0208dbcf29..e63dcf9485c05 100644
--- a/docs/pages/x/api/date-pickers/desktop-date-picker.json
+++ b/docs/pages/x/api/date-pickers/desktop-date-picker.json
@@ -225,7 +225,7 @@
{
"name": "desktopPaper",
"description": "Custom component for the paper rendered inside the desktop picker's Popper.",
- "default": "PickersPopperPaper",
+ "default": "PickerPopperPaper",
"class": null
},
{
diff --git a/docs/pages/x/api/date-pickers/desktop-date-range-picker.json b/docs/pages/x/api/date-pickers/desktop-date-range-picker.json
index 76ac2bcbf93d6..a8d2718e436a5 100644
--- a/docs/pages/x/api/date-pickers/desktop-date-range-picker.json
+++ b/docs/pages/x/api/date-pickers/desktop-date-range-picker.json
@@ -187,7 +187,7 @@
{
"name": "desktopPaper",
"description": "Custom component for the paper rendered inside the desktop picker's Popper.",
- "default": "PickersPopperPaper",
+ "default": "PickerPopperPaper",
"class": null
},
{
diff --git a/docs/pages/x/api/date-pickers/desktop-date-time-picker.json b/docs/pages/x/api/date-pickers/desktop-date-time-picker.json
index 2b4133cb7a1ba..3f138c31c104f 100644
--- a/docs/pages/x/api/date-pickers/desktop-date-time-picker.json
+++ b/docs/pages/x/api/date-pickers/desktop-date-time-picker.json
@@ -253,7 +253,7 @@
{
"name": "desktopPaper",
"description": "Custom component for the paper rendered inside the desktop picker's Popper.",
- "default": "PickersPopperPaper",
+ "default": "PickerPopperPaper",
"class": null
},
{
diff --git a/docs/pages/x/api/date-pickers/desktop-date-time-range-picker.json b/docs/pages/x/api/date-pickers/desktop-date-time-range-picker.json
index 0dfa110d2cff3..544fbea695dc6 100644
--- a/docs/pages/x/api/date-pickers/desktop-date-time-range-picker.json
+++ b/docs/pages/x/api/date-pickers/desktop-date-time-range-picker.json
@@ -238,7 +238,7 @@
{
"name": "desktopPaper",
"description": "Custom component for the paper rendered inside the desktop picker's Popper.",
- "default": "PickersPopperPaper",
+ "default": "PickerPopperPaper",
"class": null
},
{
diff --git a/docs/pages/x/api/date-pickers/desktop-time-picker.json b/docs/pages/x/api/date-pickers/desktop-time-picker.json
index 828c2fe408438..3007fb1b8b7a0 100644
--- a/docs/pages/x/api/date-pickers/desktop-time-picker.json
+++ b/docs/pages/x/api/date-pickers/desktop-time-picker.json
@@ -167,7 +167,7 @@
{
"name": "desktopPaper",
"description": "Custom component for the paper rendered inside the desktop picker's Popper.",
- "default": "PickersPopperPaper",
+ "default": "PickerPopperPaper",
"class": null
},
{
diff --git a/docs/pages/x/api/date-pickers/time-picker.json b/docs/pages/x/api/date-pickers/time-picker.json
index af9663e29bc31..4b95d5c0450be 100644
--- a/docs/pages/x/api/date-pickers/time-picker.json
+++ b/docs/pages/x/api/date-pickers/time-picker.json
@@ -171,7 +171,7 @@
{
"name": "desktopPaper",
"description": "Custom component for the paper rendered inside the desktop picker's Popper.",
- "default": "PickersPopperPaper",
+ "default": "PickerPopperPaper",
"class": null
},
{
diff --git a/packages/x-date-pickers-pro/src/DateRangeCalendar/DateRangeCalendar.tsx b/packages/x-date-pickers-pro/src/DateRangeCalendar/DateRangeCalendar.tsx
index 5377d307f330f..def8246aa717b 100644
--- a/packages/x-date-pickers-pro/src/DateRangeCalendar/DateRangeCalendar.tsx
+++ b/packages/x-date-pickers-pro/src/DateRangeCalendar/DateRangeCalendar.tsx
@@ -16,7 +16,7 @@ import {
DayCalendar,
DayCalendarSlots,
DayCalendarSlotProps,
- useDefaultReduceAnimations,
+ useReduceAnimations,
useCalendarState,
useDefaultDates,
useUtils,
@@ -113,17 +113,17 @@ function useDateRangeCalendarDefaultizedProps(
): DateRangeCalendarDefaultizedProps {
const utils = useUtils();
const defaultDates = useDefaultDates();
- const defaultReduceAnimations = useDefaultReduceAnimations();
const themeProps = useThemeProps({
props,
name,
});
+ const reduceAnimations = useReduceAnimations(themeProps.reduceAnimations);
return {
...themeProps,
renderLoading:
themeProps.renderLoading ?? (() => ...),
- reduceAnimations: themeProps.reduceAnimations ?? defaultReduceAnimations,
+ reduceAnimations,
loading: props.loading ?? false,
disablePast: props.disablePast ?? false,
disableFuture: props.disableFuture ?? false,
diff --git a/packages/x-date-pickers-pro/src/internals/hooks/useDesktopRangePicker/useDesktopRangePicker.tsx b/packages/x-date-pickers-pro/src/internals/hooks/useDesktopRangePicker/useDesktopRangePicker.tsx
index 1b6a0c70a0802..49504376f9bd6 100644
--- a/packages/x-date-pickers-pro/src/internals/hooks/useDesktopRangePicker/useDesktopRangePicker.tsx
+++ b/packages/x-date-pickers-pro/src/internals/hooks/useDesktopRangePicker/useDesktopRangePicker.tsx
@@ -6,7 +6,7 @@ import {
executeInTheNextEventLoopTick,
getActiveElement,
usePicker,
- PickersPopper,
+ PickerPopper,
DateOrTimeViewWithMeridiem,
PickerProvider,
PickerValue,
@@ -55,7 +55,6 @@ export const useDesktopRangePicker = <
autoFocus,
disableOpenPicker,
localeText,
- reduceAnimations,
} = props;
const fieldContainerRef = React.useRef(null);
@@ -80,7 +79,7 @@ export const useDesktopRangePicker = <
fieldRef = endFieldRef;
}
- const { providerProps, renderCurrentView, shouldRestoreFocus, ownerState } = usePicker<
+ const { providerProps, renderCurrentView, ownerState } = usePicker<
PickerRangeValue,
TView,
TExternalProps
@@ -185,21 +184,17 @@ export const useDesktopRangePicker = <
-
{renderCurrentView()}
-
+
diff --git a/packages/x-date-pickers-pro/src/internals/hooks/useDesktopRangePicker/useDesktopRangePicker.types.ts b/packages/x-date-pickers-pro/src/internals/hooks/useDesktopRangePicker/useDesktopRangePicker.types.ts
index 06494f9d27b4c..02026727ba11b 100644
--- a/packages/x-date-pickers-pro/src/internals/hooks/useDesktopRangePicker/useDesktopRangePicker.types.ts
+++ b/packages/x-date-pickers-pro/src/internals/hooks/useDesktopRangePicker/useDesktopRangePicker.types.ts
@@ -1,6 +1,6 @@
import {
- PickersPopperSlots,
- PickersPopperSlotProps,
+ PickerPopperSlots,
+ PickerPopperSlotProps,
UsePickerViewsProps,
DateOrTimeViewWithMeridiem,
} from '@mui/x-date-pickers/internals';
@@ -12,11 +12,11 @@ import {
UseRangePickerSlots,
} from '../models/useRangePicker';
-export interface UseDesktopRangePickerSlots extends UseRangePickerSlots, PickersPopperSlots {}
+export interface UseDesktopRangePickerSlots extends UseRangePickerSlots, PickerPopperSlots {}
export interface UseDesktopRangePickerSlotProps
extends UseRangePickerSlotProps,
- PickersPopperSlotProps {}
+ PickerPopperSlotProps {}
export interface DesktopRangeOnlyPickerProps extends RangeOnlyPickerProps {
/**
diff --git a/packages/x-date-pickers/src/DateCalendar/DateCalendar.tsx b/packages/x-date-pickers/src/DateCalendar/DateCalendar.tsx
index beba17c77429a..4445ec018cb4f 100644
--- a/packages/x-date-pickers/src/DateCalendar/DateCalendar.tsx
+++ b/packages/x-date-pickers/src/DateCalendar/DateCalendar.tsx
@@ -24,7 +24,7 @@ import {
mergeDateAndTime,
} from '../internals/utils/date-utils';
import { PickerViewRoot } from '../internals/components/PickerViewRoot';
-import { useDefaultReduceAnimations } from '../internals/hooks/useDefaultReduceAnimations';
+import { useReduceAnimations } from '../internals/hooks/useReduceAnimations';
import { DateCalendarClasses, getDateCalendarUtilityClass } from './dateCalendarClasses';
import { BaseDateValidationProps } from '../internals/models/validation';
import { useControlledValueWithTimezone } from '../internals/hooks/useValueWithTimezone';
@@ -48,11 +48,11 @@ function useDateCalendarDefaultizedProps(
): DateCalendarDefaultizedProps {
const utils = useUtils();
const defaultDates = useDefaultDates();
- const defaultReduceAnimations = useDefaultReduceAnimations();
const themeProps = useThemeProps({
props,
name,
});
+ const reduceAnimations = useReduceAnimations(themeProps.reduceAnimations);
return {
...themeProps,
@@ -61,7 +61,7 @@ function useDateCalendarDefaultizedProps(
disableFuture: themeProps.disableFuture ?? false,
openTo: themeProps.openTo ?? 'day',
views: themeProps.views ?? ['year', 'day'],
- reduceAnimations: themeProps.reduceAnimations ?? defaultReduceAnimations,
+ reduceAnimations,
renderLoading:
themeProps.renderLoading ?? (() => ...),
minDate: applyDefaultDate(utils, themeProps.minDate, defaultDates.minDate),
diff --git a/packages/x-date-pickers/src/internals/components/PickersPopper.tsx b/packages/x-date-pickers/src/internals/components/PickerPopper/PickerPopper.tsx
similarity index 85%
rename from packages/x-date-pickers/src/internals/components/PickersPopper.tsx
rename to packages/x-date-pickers/src/internals/components/PickerPopper/PickerPopper.tsx
index ae5560440a096..91b2fe57ef5cd 100644
--- a/packages/x-date-pickers/src/internals/components/PickersPopper.tsx
+++ b/packages/x-date-pickers/src/internals/components/PickerPopper/PickerPopper.tsx
@@ -20,21 +20,20 @@ import {
import { styled, useThemeProps } from '@mui/material/styles';
import { TransitionProps as MuiTransitionProps } from '@mui/material/transitions';
import { SlotComponentPropsFromProps } from '@mui/x-internals/types';
-import { getPickersPopperUtilityClass, PickersPopperClasses } from './pickersPopperClasses';
-import { getActiveElement } from '../utils/utils';
-import { useDefaultReduceAnimations } from '../hooks/useDefaultReduceAnimations';
-import { usePickerPrivateContext } from '../hooks/usePickerPrivateContext';
-import { PickerOwnerState } from '../../models';
-import { usePickerContext } from '../../hooks';
+import { getPickerPopperUtilityClass, PickerPopperClasses } from './pickerPopperClasses';
+import { getActiveElement } from '../../utils/utils';
+import { usePickerPrivateContext } from '../../hooks/usePickerPrivateContext';
+import { PickerOwnerState } from '../../../models';
+import { usePickerContext } from '../../../hooks';
interface PickerPopperOwnerState extends PickerOwnerState {
popperPlacement: PopperPlacementType;
}
-export interface PickersPopperSlots {
+export interface PickerPopperSlots {
/**
* Custom component for the paper rendered inside the desktop picker's Popper.
- * @default PickersPopperPaper
+ * @default PickerPopperPaper
*/
desktopPaper?: React.JSXElementConstructor;
/**
@@ -54,7 +53,7 @@ export interface PickersPopperSlots {
popper?: React.ElementType;
}
-export interface PickersPopperSlotProps {
+export interface PickerPopperSlotProps {
/**
* Props passed down to the desktop [Paper](https://mui.com/material-ui/api/paper/) component.
*/
@@ -73,45 +72,46 @@ export interface PickersPopperSlotProps {
popper?: SlotComponentPropsFromProps;
}
-export interface PickerPopperProps {
- role: 'tooltip' | 'dialog';
- anchorEl: MuiPopperProps['anchorEl'];
+export interface ExportedPickerPopperProps {
+ /**
+ * Override or extend the styles applied to the component.
+ */
+ classes?: Partial;
/**
- * @default "bottom"
+ * @default "bottom-start"
*/
+ // Never used in the codebase, only here for theme augmentation.
placement?: MuiPopperProps['placement'];
+}
+
+export interface PickerPopperProps extends ExportedPickerPopperProps {
+ role: 'tooltip' | 'dialog';
containerRef?: React.Ref;
children?: React.ReactNode;
onBlur?: () => void;
- slots?: PickersPopperSlots;
- slotProps?: PickersPopperSlotProps;
- /**
- * Override or extend the styles applied to the component.
- */
- classes?: Partial;
- shouldRestoreFocus?: () => boolean;
- reduceAnimations?: boolean;
+ slots?: PickerPopperSlots;
+ slotProps?: PickerPopperSlotProps;
}
-const useUtilityClasses = (classes: Partial | undefined) => {
+const useUtilityClasses = (classes: Partial | undefined) => {
const slots = {
root: ['root'],
paper: ['paper'],
};
- return composeClasses(slots, getPickersPopperUtilityClass, classes);
+ return composeClasses(slots, getPickerPopperUtilityClass, classes);
};
-const PickersPopperRoot = styled(MuiPopper, {
- name: 'MuiPickersPopper',
+const PickerPopperRoot = styled(MuiPopper, {
+ name: 'MuiPickerPopper',
slot: 'Root',
overridesResolver: (_, styles) => styles.root,
})(({ theme }) => ({
zIndex: theme.zIndex.modal,
}));
-const PickersPopperPaper = styled(MuiPaper, {
- name: 'MuiPickersPopper',
+const PickerPopperPaper = styled(MuiPaper, {
+ name: 'MuiPickerPopper',
slot: 'Paper',
overridesResolver: (_, styles) => styles.paper,
})<{
@@ -274,18 +274,18 @@ function useClickAwayListener(
return [nodeRef, handleSynthetic, handleSynthetic];
}
-interface PickersPopperPaperProps {
+interface PickerPopperPaperWrapperProps {
PaperComponent: React.ElementType;
children: React.ReactNode;
ownerState: PickerPopperOwnerState;
paperClasses: string;
onPaperClick: React.MouseEventHandler;
onPaperTouchStart: React.TouchEventHandler;
- paperSlotProps?: PickersPopperSlotProps['desktopPaper'];
+ paperSlotProps?: PickerPopperSlotProps['desktopPaper'];
}
-const PickersPopperPaperWrapper = React.forwardRef(
- (props: PickersPopperPaperProps, ref: React.Ref) => {
+const PickerPopperPaperWrapper = React.forwardRef(
+ (props: PickerPopperPaperWrapperProps, ref: React.Ref) => {
const {
PaperComponent,
ownerState,
@@ -330,24 +330,21 @@ const PickersPopperPaperWrapper = React.forwardRef(
},
);
-export function PickersPopper(inProps: PickerPopperProps) {
- const props = useThemeProps({ props: inProps, name: 'MuiPickersPopper' });
+export function PickerPopper(inProps: PickerPopperProps) {
+ const props = useThemeProps({ props: inProps, name: 'MuiPickerPopper' });
const {
- anchorEl,
children,
containerRef = null,
- shouldRestoreFocus,
onBlur,
role,
- placement = 'bottom',
+ placement = 'bottom-start',
slots,
slotProps,
- reduceAnimations: inReduceAnimations,
classes: classesProp,
} = props;
- const { open } = usePickerContext();
- const { dismissViews } = usePickerPrivateContext();
+ const { open, triggerRef, reduceAnimations } = usePickerContext();
+ const { dismissViews, doesTheCurrentViewHasAnUI } = usePickerPrivateContext();
React.useEffect(() => {
function handleKeyDown(nativeEvent: KeyboardEvent) {
@@ -365,7 +362,7 @@ export function PickersPopper(inProps: PickerPopperProps) {
const lastFocusedElementRef = React.useRef(null);
React.useEffect(() => {
- if (role === 'tooltip' || (shouldRestoreFocus && !shouldRestoreFocus())) {
+ if (role === 'tooltip' || !doesTheCurrentViewHasAnUI()) {
return;
}
@@ -383,7 +380,7 @@ export function PickersPopper(inProps: PickerPopperProps) {
}
});
}
- }, [open, role, shouldRestoreFocus]);
+ }, [open, role, doesTheCurrentViewHasAnUI]);
const [clickAwayRef, onPaperClick, onPaperTouchStart] = useClickAwayListener(
open,
@@ -394,10 +391,11 @@ export function PickersPopper(inProps: PickerPopperProps) {
const handlePaperRef = useForkRef(handleRef, clickAwayRef as React.Ref);
const classes = useUtilityClasses(classesProp);
- const defaultReduceAnimations = useDefaultReduceAnimations();
- const reduceAnimations = inReduceAnimations ?? defaultReduceAnimations;
const { ownerState: pickerOwnerState } = usePickerPrivateContext();
- const ownerState: PickerPopperOwnerState = { ...pickerOwnerState, popperPlacement: placement };
+ const ownerState: PickerPopperOwnerState = {
+ ...pickerOwnerState,
+ popperPlacement: placement,
+ };
const handleKeyDown = (event: React.KeyboardEvent) => {
if (event.key === 'Escape') {
@@ -410,8 +408,8 @@ export function PickersPopper(inProps: PickerPopperProps) {
const Transition = (slots?.desktopTransition ?? reduceAnimations) ? Fade : Grow;
const FocusTrap = slots?.desktopTrapFocus ?? BaseFocusTrap;
- const Paper = slots?.desktopPaper ?? PickersPopperPaper;
- const Popper = slots?.popper ?? PickersPopperRoot;
+ const Paper = slots?.desktopPaper ?? PickerPopperPaper;
+ const Popper = slots?.popper ?? PickerPopperRoot;
const popperProps = useSlotProps({
elementType: Popper,
externalSlotProps: slotProps?.popper,
@@ -419,8 +417,8 @@ export function PickersPopper(inProps: PickerPopperProps) {
transition: true,
role,
open,
- anchorEl,
placement,
+ anchorEl: triggerRef.current,
onKeyDown: handleKeyDown,
},
className: classes.root,
@@ -442,7 +440,7 @@ export function PickersPopper(inProps: PickerPopperProps) {
{...slotProps?.desktopTrapFocus}
>
-
{children}
-
+
)}
diff --git a/packages/x-date-pickers/src/internals/components/PickerPopper/index.ts b/packages/x-date-pickers/src/internals/components/PickerPopper/index.ts
new file mode 100644
index 0000000000000..3119faa5835dc
--- /dev/null
+++ b/packages/x-date-pickers/src/internals/components/PickerPopper/index.ts
@@ -0,0 +1,5 @@
+export { PickerPopper } from './PickerPopper';
+export type { ExportedPickerPopperProps } from './PickerPopper';
+
+export { pickerPopperClasses, getPickerPopperUtilityClass } from './pickerPopperClasses';
+export type { PickerPopperClassKey, PickerPopperClasses } from './pickerPopperClasses';
diff --git a/packages/x-date-pickers/src/internals/components/PickerPopper/pickerPopperClasses.ts b/packages/x-date-pickers/src/internals/components/PickerPopper/pickerPopperClasses.ts
new file mode 100644
index 0000000000000..7718ed7d304fb
--- /dev/null
+++ b/packages/x-date-pickers/src/internals/components/PickerPopper/pickerPopperClasses.ts
@@ -0,0 +1,17 @@
+import generateUtilityClass from '@mui/utils/generateUtilityClass';
+import generateUtilityClasses from '@mui/utils/generateUtilityClasses';
+
+export interface PickerPopperClasses {
+ /** Styles applied to the root element. */
+ root: string;
+ /** Styles applied to the paper element. */
+ paper: string;
+}
+
+export type PickerPopperClassKey = keyof PickerPopperClasses;
+
+export function getPickerPopperUtilityClass(slot: string) {
+ return generateUtilityClass('MuiPickerPopper', slot);
+}
+
+export const pickerPopperClasses = generateUtilityClasses('MuiPickerPopper', ['root', 'paper']);
diff --git a/packages/x-date-pickers/src/internals/components/PickerProvider.tsx b/packages/x-date-pickers/src/internals/components/PickerProvider.tsx
index 30d4aa9be6735..426d972cf1882 100644
--- a/packages/x-date-pickers/src/internals/components/PickerProvider.tsx
+++ b/packages/x-date-pickers/src/internals/components/PickerProvider.tsx
@@ -16,6 +16,7 @@ import type {
import {
UsePickerViewsActionsContextValue,
UsePickerViewsContextValue,
+ UsePickerViewsPrivateContextValue,
} from '../hooks/usePicker/usePickerViews';
import { IsValidValueContext } from '../../hooks/useIsValidValue';
import {
@@ -40,6 +41,8 @@ export const PickerPrivateContext = React.createContext {},
+ hasUIView: true,
+ doesTheCurrentViewHasAnUI: () => true,
});
/**
@@ -118,6 +121,11 @@ export interface PickerContextValue<
* Is always equal to "portrait" if the component you are accessing the context from is not wrapped by a picker.
*/
orientation: PickerOrientation;
+ /**
+ * Whether the heavy animations should be disabled.
+ * @default `@media(prefers-reduced-motion: reduce)` || `navigator.userAgent` matches Android <10 or iOS <13
+ */
+ reduceAnimations?: boolean;
/**
* The ref that should be attached to the element that triggers the Picker opening.
* When using a built-in field component, this property is automatically handled.
@@ -147,7 +155,9 @@ export interface PickerActionsContextValue<
> extends UsePickerValueActionsContextValue,
UsePickerViewsActionsContextValue {}
-export interface PickerPrivateContextValue extends UsePickerValuePrivateContextValue {
+export interface PickerPrivateContextValue
+ extends UsePickerValuePrivateContextValue,
+ UsePickerViewsPrivateContextValue {
/**
* The ownerState of the picker.
*/
diff --git a/packages/x-date-pickers/src/internals/components/pickersPopperClasses.ts b/packages/x-date-pickers/src/internals/components/pickersPopperClasses.ts
deleted file mode 100644
index a1efe667f885a..0000000000000
--- a/packages/x-date-pickers/src/internals/components/pickersPopperClasses.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-import {
- unstable_generateUtilityClass as generateUtilityClass,
- unstable_generateUtilityClasses as generateUtilityClasses,
-} from '@mui/utils';
-
-export interface PickersPopperClasses {
- /** Styles applied to the root element. */
- root: string;
- /** Styles applied to the paper element. */
- paper: string;
-}
-
-export type PickersPopperClassKey = keyof PickersPopperClasses;
-
-export function getPickersPopperUtilityClass(slot: string) {
- return generateUtilityClass('MuiPickersPopper', slot);
-}
-
-export const pickersPopperClasses = generateUtilityClasses('MuiPickersPopper', ['root', 'paper']);
diff --git a/packages/x-date-pickers/src/internals/hooks/useDesktopPicker/useDesktopPicker.tsx b/packages/x-date-pickers/src/internals/hooks/useDesktopPicker/useDesktopPicker.tsx
index 8749e675362ee..15623d589ce1d 100644
--- a/packages/x-date-pickers/src/internals/hooks/useDesktopPicker/useDesktopPicker.tsx
+++ b/packages/x-date-pickers/src/internals/hooks/useDesktopPicker/useDesktopPicker.tsx
@@ -2,7 +2,7 @@ import * as React from 'react';
import useSlotProps from '@mui/utils/useSlotProps';
import useForkRef from '@mui/utils/useForkRef';
import useId from '@mui/utils/useId';
-import { PickersPopper } from '../../components/PickersPopper';
+import { PickerPopper } from '../../components/PickerPopper/PickerPopper';
import { UseDesktopPickerParams, UseDesktopPickerProps } from './useDesktopPicker.types';
import { usePicker } from '../usePicker';
import { PickersLayout } from '../../../PickersLayout';
@@ -41,7 +41,6 @@ export const useDesktopPicker = <
readOnly,
autoFocus,
localeText,
- reduceAnimations,
} = props;
const fieldRef = React.useRef>(null);
@@ -49,7 +48,7 @@ export const useDesktopPicker = <
const labelId = useId();
const isToolbarHidden = innerSlotProps?.toolbar?.hidden ?? false;
- const { providerProps, renderCurrentView, shouldRestoreFocus, ownerState } = usePicker<
+ const { providerProps, renderCurrentView, ownerState } = usePicker<
PickerValue,
TView,
TExternalProps
@@ -115,19 +114,11 @@ export const useDesktopPicker = <
-
+
{renderCurrentView()}
-
+
);
diff --git a/packages/x-date-pickers/src/internals/hooks/useDesktopPicker/useDesktopPicker.types.ts b/packages/x-date-pickers/src/internals/hooks/useDesktopPicker/useDesktopPicker.types.ts
index 58d97811de6cc..8c0c89c419b65 100644
--- a/packages/x-date-pickers/src/internals/hooks/useDesktopPicker/useDesktopPicker.types.ts
+++ b/packages/x-date-pickers/src/internals/hooks/useDesktopPicker/useDesktopPicker.types.ts
@@ -4,7 +4,10 @@ import {
BasePickerProps,
BaseNonRangeNonStaticPickerProps,
} from '../../models/props/basePickerProps';
-import { PickersPopperSlots, PickersPopperSlotProps } from '../../components/PickersPopper';
+import {
+ PickerPopperSlots,
+ PickerPopperSlotProps,
+} from '../../components/PickerPopper/PickerPopper';
import { UsePickerParams } from '../usePicker';
import { PickerFieldSlotProps, PickerOwnerState } from '../../../models';
import {
@@ -23,7 +26,7 @@ import { UsePickerProviderNonStaticProps } from '../usePicker/usePickerProvider'
export interface UseDesktopPickerSlots
extends Pick<
- PickersPopperSlots,
+ PickerPopperSlots,
'desktopPaper' | 'desktopTransition' | 'desktopTrapFocus' | 'popper'
>,
ExportedPickersLayoutSlots,
@@ -41,7 +44,7 @@ export interface UseDesktopPickerSlots
export interface ExportedUseDesktopPickerSlotProps<
TEnableAccessibleFieldDOMStructure extends boolean,
-> extends PickersPopperSlotProps,
+> extends PickerPopperSlotProps,
ExportedPickersLayoutSlotProps,
PickerFieldUISlotPropsFromContext {
field?: SlotComponentPropsFromProps<
diff --git a/packages/x-date-pickers/src/internals/hooks/usePicker/index.ts b/packages/x-date-pickers/src/internals/hooks/usePicker/index.ts
index 3d7591dec661c..fc366eca34028 100644
--- a/packages/x-date-pickers/src/internals/hooks/usePicker/index.ts
+++ b/packages/x-date-pickers/src/internals/hooks/usePicker/index.ts
@@ -1,10 +1,5 @@
export { usePicker } from './usePicker';
-export type {
- UsePickerProps,
- UsePickerBaseProps,
- UsePickerParams,
- UsePickerResponse,
-} from './usePicker.types';
+export type { UsePickerProps, UsePickerBaseProps, UsePickerParams } from './usePicker.types';
export type {
PickerValueManager,
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 a27c1306f22a2..4cbafd7f80590 100644
--- a/packages/x-date-pickers/src/internals/hooks/usePicker/usePicker.ts
+++ b/packages/x-date-pickers/src/internals/hooks/usePicker/usePicker.ts
@@ -1,5 +1,5 @@
import { warnOnce } from '@mui/x-internals/warning';
-import { UsePickerParams, UsePickerProps, UsePickerResponse } from './usePicker.types';
+import { UsePickerParams, UsePickerProps, UsePickerReturnValue } from './usePicker.types';
import { usePickerValue } from './usePickerValue';
import { usePickerViews } from './usePickerViews';
import { DateOrTimeViewWithMeridiem, PickerValidValue } from '../../models';
@@ -19,7 +19,7 @@ export const usePicker = <
rendererInterceptor,
fieldRef,
localeText,
-}: UsePickerParams): UsePickerResponse => {
+}: UsePickerParams): UsePickerReturnValue => {
if (process.env.NODE_ENV !== 'production') {
if ((props as any).renderInput != null) {
warnOnce([
@@ -56,7 +56,6 @@ export const usePicker = <
return {
// Picker views
renderCurrentView: pickerViewsResponse.renderCurrentView,
- shouldRestoreFocus: pickerViewsResponse.shouldRestoreFocus,
// 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 4bf6424a9de93..96f06c6deea11 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
@@ -6,7 +6,6 @@ import {
import {
UsePickerViewsProps,
UsePickerViewParams,
- UsePickerViewsResponse,
UsePickerViewsBaseProps,
} from './usePickerViews';
import { InferError, PickerOwnerState } from '../../../models';
@@ -57,10 +56,8 @@ export interface UsePickerParams<
props: TExternalProps;
}
-export interface UsePickerResponse<
- TValue extends PickerValidValue,
- TView extends DateOrTimeViewWithMeridiem,
-> extends Pick, 'shouldRestoreFocus' | 'renderCurrentView'> {
+export interface UsePickerReturnValue {
ownerState: PickerOwnerState;
+ renderCurrentView: () => React.ReactNode;
providerProps: UsePickerProviderReturnValue;
}
diff --git a/packages/x-date-pickers/src/internals/hooks/usePicker/usePickerProvider.ts b/packages/x-date-pickers/src/internals/hooks/usePicker/usePickerProvider.ts
index efbbae1fb221b..06d1747a12222 100644
--- a/packages/x-date-pickers/src/internals/hooks/usePicker/usePickerProvider.ts
+++ b/packages/x-date-pickers/src/internals/hooks/usePicker/usePickerProvider.ts
@@ -19,6 +19,7 @@ import { useUtils } from '../useUtils';
import { arrayIncludes } from '../../utils/utils';
import { UsePickerViewsProviderParams } from './usePickerViews';
import { PickerFieldPrivateContextValue } from '../useField/useFieldInternalPropsWithDefaults';
+import { useReduceAnimations } from '../useReduceAnimations';
function getOrientation(): PickerOrientation {
if (typeof window === 'undefined') {
@@ -79,6 +80,8 @@ export function usePickerProvider<
const utils = useUtils();
const orientation = usePickerOrientation(paramsFromUsePickerViews.views, props.orientation);
+ const reduceAnimations = useReduceAnimations(props.reduceAnimations);
+
const triggerRef = React.useRef(null);
const ownerState = React.useMemo(
@@ -126,6 +129,7 @@ export function usePickerProvider<
readOnly: props.readOnly ?? false,
variant,
orientation,
+ reduceAnimations,
triggerRef,
triggerStatus,
fieldFormat: props.format ?? '',
@@ -135,6 +139,7 @@ export function usePickerProvider<
paramsFromUsePickerViews.contextValue,
variant,
orientation,
+ reduceAnimations,
props.disabled,
props.readOnly,
triggerRef,
@@ -144,8 +149,16 @@ export function usePickerProvider<
);
const privateContextValue = React.useMemo(
- () => ({ ...paramsFromUsePickerValue.privateContextValue, ownerState }),
- [paramsFromUsePickerValue, ownerState],
+ () => ({
+ ...paramsFromUsePickerValue.privateContextValue,
+ ...paramsFromUsePickerViews.privateContextValue,
+ ownerState,
+ }),
+ [
+ paramsFromUsePickerValue.privateContextValue,
+ paramsFromUsePickerViews.privateContextValue,
+ ownerState,
+ ],
);
const actionsContextValue = React.useMemo(
@@ -205,6 +218,11 @@ export interface UsePickerProviderProps extends FormProps {
* Force rendering in particular orientation.
*/
orientation?: PickerOrientation;
+ /**
+ * If `true`, disable heavy animations.
+ * @default `@media(prefers-reduced-motion: reduce)` || `navigator.userAgent` matches Android <10 or iOS <13
+ */
+ reduceAnimations?: boolean;
}
/**
diff --git a/packages/x-date-pickers/src/internals/hooks/usePicker/usePickerViews.tsx b/packages/x-date-pickers/src/internals/hooks/usePicker/usePickerViews.tsx
index f8769c0109b27..4ab6e368e484d 100644
--- a/packages/x-date-pickers/src/internals/hooks/usePicker/usePickerViews.tsx
+++ b/packages/x-date-pickers/src/internals/hooks/usePicker/usePickerViews.tsx
@@ -56,11 +56,6 @@ export interface UsePickerViewsBaseProps<
* If `undefined`, internally defined view will be used.
*/
viewRenderers: PickerViewRendererLookup;
- /**
- * If `true`, disable heavy animations.
- * @default `@media(prefers-reduced-motion: reduce)` || `navigator.userAgent` matches Android <10 or iOS <13
- */
- reduceAnimations?: boolean;
/**
* The date used to generate the new value when both `value` and `defaultValue` are empty.
* @default The closest valid date-time using the validation props, except callbacks like `shouldDisable<...>`.
@@ -114,7 +109,6 @@ export interface PickerRendererInterceptorProps<
export interface UsePickerViewsResponse {
renderCurrentView: () => React.ReactNode;
- shouldRestoreFocus: () => boolean;
provider: UsePickerViewsProviderParams;
}
@@ -139,11 +133,24 @@ export interface UsePickerViewsContextValue boolean;
+}
+
export interface UsePickerViewsProviderParams {
hasUIView: boolean;
views: readonly TView[];
contextValue: UsePickerViewsContextValue;
actionsContextValue: UsePickerViewsActionsContextValue;
+ privateContextValue: UsePickerViewsPrivateContextValue;
}
/**
@@ -212,7 +219,7 @@ export const usePickerViews = <
);
const currentViewMode = viewModeLookup[view];
- const shouldRestoreFocus = useEventCallback(() => currentViewMode === 'UI');
+ const doesTheCurrentViewHasAnUI = useEventCallback(() => currentViewMode === 'UI');
const [popperView, setPopperView] = React.useState(
currentViewMode === 'UI' ? view : null,
@@ -275,15 +282,20 @@ export const usePickerViews = <
[actionsContextValue, views, popperView],
);
+ const privateContextValue = React.useMemo(
+ () => ({ hasUIView, doesTheCurrentViewHasAnUI }),
+ [hasUIView, doesTheCurrentViewHasAnUI],
+ );
+
const providerParams: UsePickerViewsProviderParams = {
hasUIView,
views,
contextValue,
actionsContextValue,
+ privateContextValue,
};
return {
- shouldRestoreFocus,
provider: providerParams,
renderCurrentView: () => {
if (popperView == null) {
diff --git a/packages/x-date-pickers/src/internals/hooks/useDefaultReduceAnimations.ts b/packages/x-date-pickers/src/internals/hooks/useReduceAnimations.ts
similarity index 83%
rename from packages/x-date-pickers/src/internals/hooks/useDefaultReduceAnimations.ts
rename to packages/x-date-pickers/src/internals/hooks/useReduceAnimations.ts
index 72a400bf4ee58..1c8a174c85908 100644
--- a/packages/x-date-pickers/src/internals/hooks/useDefaultReduceAnimations.ts
+++ b/packages/x-date-pickers/src/internals/hooks/useReduceAnimations.ts
@@ -12,7 +12,12 @@ const iOSVersion =
export const slowAnimationDevices =
(androidVersion && androidVersion < 10) || (iOSVersion && iOSVersion < 13) || false;
-export const useDefaultReduceAnimations = () => {
+export function useReduceAnimations(customReduceAnimations: boolean | undefined) {
const prefersReduced = useMediaQuery(PREFERS_REDUCED_MOTION, { defaultMatches: false });
+
+ if (customReduceAnimations != null) {
+ return customReduceAnimations;
+ }
+
return prefersReduced || slowAnimationDevices;
-};
+}
diff --git a/packages/x-date-pickers/src/internals/index.ts b/packages/x-date-pickers/src/internals/index.ts
index 6d138c66b4d30..429ec8e3f9bd8 100644
--- a/packages/x-date-pickers/src/internals/index.ts
+++ b/packages/x-date-pickers/src/internals/index.ts
@@ -22,8 +22,11 @@ export type {
PickersModalDialogSlots,
PickersModalDialogSlotProps,
} from './components/PickersModalDialog';
-export { PickersPopper } from './components/PickersPopper';
-export type { PickersPopperSlots, PickersPopperSlotProps } from './components/PickersPopper';
+export { PickerPopper } from './components/PickerPopper/PickerPopper';
+export type {
+ PickerPopperSlots,
+ PickerPopperSlotProps,
+} from './components/PickerPopper/PickerPopper';
export { PickersToolbar } from './components/PickersToolbar';
export type { PickersToolbarProps } from './components/PickersToolbar';
export { pickersToolbarClasses } from './components/pickersToolbarClasses';
@@ -51,12 +54,6 @@ export type {
PickersArrowSwitcherClassKey,
PickersArrowSwitcherClasses,
} from './components/PickersArrowSwitcher/pickersArrowSwitcherClasses';
-export type { PickerPopperProps } from './components/PickersPopper';
-export { pickersPopperClasses } from './components/pickersPopperClasses';
-export type {
- PickersPopperClassKey,
- PickersPopperClasses,
-} from './components/pickersPopperClasses';
export { PickersToolbarButton } from './components/PickersToolbarButton';
export { DAY_MARGIN, DIALOG_WIDTH, VIEW_HEIGHT } from './constants/dimensions';
@@ -166,7 +163,7 @@ export {
onSpaceOrEnter,
DEFAULT_DESKTOP_MODE_MEDIA_QUERY,
} from './utils/utils';
-export { useDefaultReduceAnimations } from './hooks/useDefaultReduceAnimations';
+export { useReduceAnimations } from './hooks/useReduceAnimations';
export { applyDefaultViewProps } from './utils/views';
export { DayCalendar } from '../DateCalendar/DayCalendar';
diff --git a/packages/x-date-pickers/src/themeAugmentation/components.d.ts b/packages/x-date-pickers/src/themeAugmentation/components.d.ts
index fe83141400e00..aa2954ed70460 100644
--- a/packages/x-date-pickers/src/themeAugmentation/components.d.ts
+++ b/packages/x-date-pickers/src/themeAugmentation/components.d.ts
@@ -78,9 +78,9 @@ export interface PickerComponents {
defaultProps?: ComponentsProps['MuiPickersFadeTransitionGroup'];
styleOverrides?: ComponentsOverrides['MuiPickersFadeTransitionGroup'];
};
- MuiPickersPopper?: {
- defaultProps?: ComponentsProps['MuiPickersPopper'];
- styleOverrides?: ComponentsOverrides['MuiPickersPopper'];
+ MuiPickerPopper?: {
+ defaultProps?: ComponentsProps['MuiPickerPopper'];
+ styleOverrides?: ComponentsOverrides['MuiPickerPopper'];
};
MuiPickersSlideTransition?: {
defaultProps?: ComponentsProps['MuiPickersSlideTransition'];
diff --git a/packages/x-date-pickers/src/themeAugmentation/overrides.d.ts b/packages/x-date-pickers/src/themeAugmentation/overrides.d.ts
index 2722d0ad6267d..8c69153529f4f 100644
--- a/packages/x-date-pickers/src/themeAugmentation/overrides.d.ts
+++ b/packages/x-date-pickers/src/themeAugmentation/overrides.d.ts
@@ -21,7 +21,7 @@ import { TimePickerToolbarClassKey } from '../TimePicker';
import { DateTimePickerToolbarClassKey, DateTimePickerTabsClassKey } from '../DateTimePicker';
import { PickersArrowSwitcherClassKey } from '../internals/components/PickersArrowSwitcher';
import { PickersToolbarClassKey } from '../internals/components/pickersToolbarClasses';
-import { PickersPopperClassKey } from '../internals/components/pickersPopperClasses';
+import { PickerPopperClassKey } from '../internals/components/PickerPopper';
import { PickersToolbarButtonClassKey } from '../internals/components/pickersToolbarButtonClasses';
import { PickersToolbarTextClassKey } from '../internals/components/pickersToolbarTextClasses';
import { DigitalClockClassKey } from '../DigitalClock';
@@ -58,7 +58,7 @@ export interface PickersComponentNameToClassKey {
MuiPickersDay: PickersDayClassKey;
MuiPickersFadeTransitionGroup: PickersFadeTransitionGroupClassKey;
MuiPickersLayout: PickersLayoutClassKey;
- MuiPickersPopper: PickersPopperClassKey;
+ MuiPickerPopper: PickerPopperClassKey;
MuiPickersSlideTransition: PickersSlideTransitionClassKey;
MuiPickersToolbar: PickersToolbarClassKey;
MuiPickersToolbarButton: PickersToolbarButtonClassKey;
diff --git a/packages/x-date-pickers/src/themeAugmentation/props.d.ts b/packages/x-date-pickers/src/themeAugmentation/props.d.ts
index 11562506ec71c..b7b9ad68d35a8 100644
--- a/packages/x-date-pickers/src/themeAugmentation/props.d.ts
+++ b/packages/x-date-pickers/src/themeAugmentation/props.d.ts
@@ -13,7 +13,7 @@ import { LocalizationProviderProps } from '../LocalizationProvider';
import { PickersLayoutProps } from '../PickersLayout';
import { DayCalendarProps } from '../DateCalendar/DayCalendar';
import { ExportedPickersArrowSwitcherProps } from '../internals/components/PickersArrowSwitcher/PickersArrowSwitcher.types';
-import { PickerPopperProps } from '../internals/components/PickersPopper';
+import { ExportedPickerPopperProps } from '../internals/components/PickerPopper';
import { PickersToolbarProps } from '../internals/components/PickersToolbar';
import { PickersToolbarButtonProps } from '../internals/components/PickersToolbarButton';
import { ExportedPickersToolbarTextProps } from '../internals/components/PickersToolbarText';
@@ -74,7 +74,7 @@ export interface PickersComponentsPropsList {
MuiPickersCalendarHeader: ExportedPickersCalendarHeaderProps;
MuiPickersDay: PickersDayProps;
MuiPickersFadeTransitionGroup: PickersFadeTransitionGroupProps;
- MuiPickersPopper: PickerPopperProps;
+ MuiPickerPopper: ExportedPickerPopperProps;
MuiPickersSlideTransition: ExportedSlideTransitionProps;
MuiPickersToolbar: PickersToolbarProps;
MuiPickersToolbarButton: PickersToolbarButtonProps;
diff --git a/packages/x-date-pickers/src/themeAugmentation/themeAugmentation.spec.ts b/packages/x-date-pickers/src/themeAugmentation/themeAugmentation.spec.ts
index b32594f9dcfc6..e584f4f7e3135 100644
--- a/packages/x-date-pickers/src/themeAugmentation/themeAugmentation.spec.ts
+++ b/packages/x-date-pickers/src/themeAugmentation/themeAugmentation.spec.ts
@@ -15,7 +15,7 @@ import {
import { datePickerToolbarClasses } from '../DatePicker';
import { dateTimePickerToolbarClasses } from '../DateTimePicker';
import { pickersArrowSwitcherClasses } from '../internals/components/PickersArrowSwitcher';
-import { pickersPopperClasses } from '../internals/components/pickersPopperClasses';
+import { pickerPopperClasses } from '../internals/components/PickerPopper';
import { pickersDayClasses } from '../PickersDay';
import { timePickerToolbarClasses } from '../TimePicker';
import { digitalClockClasses } from '../DigitalClock';
@@ -354,20 +354,20 @@ createTheme({
},
},
},
- MuiPickersPopper: {
+ MuiPickerPopper: {
defaultProps: {
placement: 'bottom',
- // @ts-expect-error invalid MuiPickersPopper prop
+ // @ts-expect-error invalid MuiPickerPopper prop
someRandomProp: true,
},
styleOverrides: {
root: {
backgroundColor: 'red',
- [`.${pickersPopperClasses.paper}`]: {
+ [`.${pickerPopperClasses.paper}`]: {
backgroundColor: 'green',
},
},
- // @ts-expect-error invalid MuiPickersPopper class key
+ // @ts-expect-error invalid MuiPickerPopper class key
content: {
backgroundColor: 'blue',
},