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 1667b45c55749..1e51554e6311c 100644 --- a/docs/data/migration/migration-pickers-v7/migration-pickers-v7.md +++ b/docs/data/migration/migration-pickers-v7/migration-pickers-v7.md @@ -501,6 +501,19 @@ This change causes a few breaking changes: The only difference is that `usePickerActionsContext` only contains variables with stable references that won't cause a re-render of your component. ::: +- The component passed to the `layout` slot no longer receives the `rangePosition` and `onRangePositionChange` on range pickers. + You can use the `usePickerRangePositionContext` hook instead: + + ```diff + +import { usePickerRangePositionContext } from '@mui/x-date-pickers-pro/hooks'; + + -const { rangePosition } = props; + +const { rangePosition } = usePickerRangePositionContext(); + + -const { onRangePositionChange } = props; + +const { onRangePositionChange } = usePickerRangePositionContext(); + ``` + ### Slot: `toolbar` - The component passed to the `toolbar` slot no longer receives the `value` prop. @@ -576,6 +589,18 @@ This change causes a few breaking changes: The only difference is that `usePickerActionsContext` only contains variables with stable references that won't cause a re-render of your component. ::: +- The component passed to the `toolbar` slot no longer receives the `rangePosition` and `onRangePositionChange` on range pickers, instead you can use the `usePickerRangePositionContext` hook: + + ```diff + +import { usePickerRangePositionContext } from '@mui/x-date-pickers-pro/hooks'; + + -const { rangePosition } = props; + +const { rangePosition } = usePickerRangePositionContext(); + + -const { onRangePositionChange } = props; + +const { onRangePositionChange } = usePickerRangePositionContext(); + ``` + ### Slot: `tabs` - The component passed to the `tabs` slot no longer receives the `view`, `views` and `onViewChange` props. @@ -594,6 +619,18 @@ This change causes a few breaking changes: +const { onViewChange } = usePickerContext(); ``` +- The component passed to the `tabs` slot no longer receives the `rangePosition` and `onRangePositionChange` on range pickers, instead you can use the `usePickerRangePositionContext` hook: + + ```diff + +import { usePickerRangePositionContext } from '@mui/x-date-pickers-pro/hooks'; + + -const { rangePosition } = props; + +const { rangePosition } = usePickerRangePositionContext(); + + -const { onRangePositionChange } = props; + +const { onRangePositionChange } = usePickerRangePositionContext(); + ``` + ### Slot: `actionBar` - The component passed to the `actionBar` slot no longer receives the `onClear`, `onSetToday`, `onAccept` and `onCancel` props. diff --git a/packages/x-date-pickers-pro/src/DateRangeCalendar/DateRangeCalendar.tsx b/packages/x-date-pickers-pro/src/DateRangeCalendar/DateRangeCalendar.tsx index 3cb6574517771..70d1b0e474c17 100644 --- a/packages/x-date-pickers-pro/src/DateRangeCalendar/DateRangeCalendar.tsx +++ b/packages/x-date-pickers-pro/src/DateRangeCalendar/DateRangeCalendar.tsx @@ -58,6 +58,7 @@ import { PickersRangeCalendarHeader, PickersRangeCalendarHeaderProps, } from '../PickersRangeCalendarHeader'; +import { useNullablePickerRangePositionContext } from '../internals/hooks/useNullablePickerRangePositionContext'; const releaseInfo = getReleaseInfo(); @@ -187,8 +188,8 @@ const DateRangeCalendar = React.forwardRef(function DateRangeCalendar( reduceAnimations, onMonthChange, rangePosition: rangePositionProp, - defaultRangePosition: inDefaultRangePosition, - onRangePositionChange: inOnRangePositionChange, + defaultRangePosition: defaultRangePositionProp, + onRangePositionChange: onRangePositionChangeProp, calendars, currentMonthCalendarPosition = 1, slots, @@ -214,6 +215,8 @@ const DateRangeCalendar = React.forwardRef(function DateRangeCalendar( ...other } = props; + const rangePositionContext = useNullablePickerRangePositionContext(); + const { value, handleValueChange, timezone } = useControlledValueWithTimezone< PickerRangeValue, NonNullable @@ -241,9 +244,9 @@ const DateRangeCalendar = React.forwardRef(function DateRangeCalendar( const id = useId(); const { rangePosition, onRangePositionChange } = useRangePosition({ - rangePosition: rangePositionProp, - defaultRangePosition: inDefaultRangePosition, - onRangePositionChange: inOnRangePositionChange, + rangePosition: rangePositionProp ?? rangePositionContext?.rangePosition, + defaultRangePosition: defaultRangePositionProp, + onRangePositionChange: onRangePositionChangeProp ?? rangePositionContext?.onRangePositionChange, }); const handleDatePositionChange = useEventCallback((position: RangePosition) => { diff --git a/packages/x-date-pickers-pro/src/DateRangePicker/DateRangePickerToolbar.tsx b/packages/x-date-pickers-pro/src/DateRangePicker/DateRangePickerToolbar.tsx index fd42bb70085bd..7654a9268170e 100644 --- a/packages/x-date-pickers-pro/src/DateRangePicker/DateRangePickerToolbar.tsx +++ b/packages/x-date-pickers-pro/src/DateRangePicker/DateRangePickerToolbar.tsx @@ -17,11 +17,11 @@ import { } from '@mui/x-date-pickers/internals'; import { usePickerContext, usePickerTranslations } from '@mui/x-date-pickers/hooks'; import { PickerValidDate } from '@mui/x-date-pickers/models'; -import { UseRangePositionResponse } from '../internals/hooks/useRangePosition'; import { DateRangePickerToolbarClasses, getDateRangePickerToolbarUtilityClass, } from './dateRangePickerToolbarClasses'; +import { usePickerRangePositionContext } from '../hooks'; const useUtilityClasses = (classes: Partial | undefined) => { const slots = { @@ -34,8 +34,7 @@ const useUtilityClasses = (classes: Partial | und export interface DateRangePickerToolbarProps extends ExportedDateRangePickerToolbarProps, - Omit, - Pick {} + Omit {} export interface ExportedDateRangePickerToolbarProps extends ExportedBaseToolbarProps { /** @@ -81,18 +80,12 @@ const DateRangePickerToolbar = React.forwardRef(function DateRangePickerToolbar( const utils = useUtils(); const props = useThemeProps({ props: inProps, name: 'MuiDateRangePickerToolbar' }); - const { - rangePosition, - onRangePositionChange, - toolbarFormat: toolbarFormatProp, - className, - classes: classesProp, - ...other - } = props; + const { toolbarFormat: toolbarFormatProp, className, classes: classesProp, ...other } = props; const { value } = usePickerContext(); const translations = usePickerTranslations(); const ownerState = useToolbarOwnerState(); + const { rangePosition, onRangePositionChange } = usePickerRangePositionContext(); const classes = useUtilityClasses(classesProp); // This can't be a default value when spreading because it breaks the API generation. @@ -148,8 +141,6 @@ DateRangePickerToolbar.propTypes = { * @default `true` for Desktop, `false` for Mobile. */ hidden: PropTypes.bool, - onRangePositionChange: PropTypes.func.isRequired, - rangePosition: PropTypes.oneOf(['end', 'start']).isRequired, /** * The system prop that allows defining system overrides as well as additional CSS styles. */ diff --git a/packages/x-date-pickers-pro/src/DateRangePicker/shared.tsx b/packages/x-date-pickers-pro/src/DateRangePicker/shared.tsx index 091038268e6c9..f27677d53097b 100644 --- a/packages/x-date-pickers-pro/src/DateRangePicker/shared.tsx +++ b/packages/x-date-pickers-pro/src/DateRangePicker/shared.tsx @@ -58,7 +58,7 @@ export interface BaseDateRangePickerProps * If `undefined`, internally defined view will be used. */ viewRenderers?: Partial< - PickerViewRendererLookup, {}> + PickerViewRendererLookup> >; } diff --git a/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePickerTabs.tsx b/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePickerTabs.tsx index 768ba22d70b81..2b83f8a4c4932 100644 --- a/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePickerTabs.tsx +++ b/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePickerTabs.tsx @@ -20,8 +20,8 @@ import { DateTimeRangePickerTabsClasses, getDateTimeRangePickerTabsUtilityClass, } from './dateTimeRangePickerTabsClasses'; -import { UseRangePositionResponse } from '../internals/hooks/useRangePosition'; import { RangePosition } from '../models'; +import { usePickerRangePositionContext } from '../hooks'; type TabValue = 'start-date' | 'start-time' | 'end-date' | 'end-time'; @@ -63,9 +63,7 @@ export interface ExportedDateTimeRangePickerTabsProps extends ExportedBaseTabsPr classes?: Partial; } -export interface DateTimeRangePickerTabsProps - extends ExportedDateTimeRangePickerTabsProps, - Pick {} +export interface DateTimeRangePickerTabsProps extends ExportedDateTimeRangePickerTabsProps {} const useUtilityClasses = (classes: Partial | undefined) => { const slots = { @@ -114,8 +112,6 @@ const DateTimeRangePickerTabs = function DateTimeRangePickerTabs( dateIcon = , timeIcon = , hidden = typeof window === 'undefined' || window.innerHeight < 667, - rangePosition, - onRangePositionChange, className, classes: classesProp, sx, @@ -125,6 +121,8 @@ const DateTimeRangePickerTabs = function DateTimeRangePickerTabs( const { ownerState } = usePickerPrivateContext(); const { view, onViewChange } = usePickerContext(); const classes = useUtilityClasses(classesProp); + const { rangePosition, onRangePositionChange } = usePickerRangePositionContext(); + const value = React.useMemo( () => (view == null ? null : viewToTab(view, rangePosition)), [view, rangePosition], @@ -241,8 +239,6 @@ DateTimeRangePickerTabs.propTypes = { * @default `window.innerHeight < 667` for `DesktopDateTimeRangePicker` and `MobileDateTimeRangePicker` */ hidden: PropTypes.bool, - onRangePositionChange: PropTypes.func.isRequired, - rangePosition: PropTypes.oneOf(['end', 'start']).isRequired, /** * The system prop that allows defining system overrides as well as additional CSS styles. */ diff --git a/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePickerTimeWrapper.tsx b/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePickerTimeWrapper.tsx index a445d9242e3ec..922905a6ac0d5 100644 --- a/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePickerTimeWrapper.tsx +++ b/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePickerTimeWrapper.tsx @@ -7,61 +7,51 @@ import { TimeViewWithMeridiem, BaseClockProps, PickerRangeValue, + PickerViewsRendererProps, } from '@mui/x-date-pickers/internals'; import { PickerValidDate } from '@mui/x-date-pickers/models'; -import { UseRangePositionResponse } from '../internals/hooks/useRangePosition'; import { isRangeValid } from '../internals/utils/date-utils'; import { calculateRangeChange } from '../internals/utils/date-range-manager'; +import { usePickerRangePositionContext } from '../hooks'; export type DateTimeRangePickerTimeWrapperProps< - TView extends TimeViewWithMeridiem, TComponentProps extends DefaultizedProps< - Omit, 'value' | 'defaultValue' | 'onChange'>, + Omit, 'value' | 'defaultValue' | 'onChange'>, 'views' >, -> = Pick & - Omit< - TComponentProps, - 'views' | 'view' | 'onViewChange' | 'value' | 'defaultValue' | 'onChange' - > & { - view: TView; - onViewChange?: (view: TView) => void; - views: readonly TView[]; - value?: PickerRangeValue; - defaultValue?: PickerRangeValue; - onChange?: ( - value: PickerRangeValue, - selectionState: PickerSelectionState, - selectedView: TView, - ) => void; - viewRenderer?: PickerViewRenderer | null; - openTo?: TView; - }; +> = Omit< + TComponentProps, + 'views' | 'view' | 'onViewChange' | 'value' | 'defaultValue' | 'onChange' +> & { + view: TimeViewWithMeridiem; + onViewChange?: (view: TimeViewWithMeridiem) => void; + views: readonly TimeViewWithMeridiem[]; + value?: PickerRangeValue; + defaultValue?: PickerRangeValue; + onChange?: ( + value: PickerRangeValue, + selectionState: PickerSelectionState, + selectedView: TimeViewWithMeridiem, + ) => void; + viewRenderer?: PickerViewRenderer | null; + openTo?: TimeViewWithMeridiem; +}; /** * @ignore - internal component. */ function DateTimeRangePickerTimeWrapper< - TView extends TimeViewWithMeridiem, TComponentProps extends DefaultizedProps< - Omit, 'value' | 'defaultValue' | 'onChange'>, + Omit, 'value' | 'defaultValue' | 'onChange'>, 'views' >, ->(props: DateTimeRangePickerTimeWrapperProps) { +>(props: DateTimeRangePickerTimeWrapperProps) { const utils = useUtils(); - const { - rangePosition, - onRangePositionChange, - viewRenderer, - value, - onChange, - defaultValue, - onViewChange, - views, - className, - ...other - } = props; + const { viewRenderer, value, onChange, defaultValue, onViewChange, views, className, ...other } = + props; + + const { rangePosition, onRangePositionChange } = usePickerRangePositionContext(); if (!viewRenderer) { return null; @@ -73,7 +63,7 @@ function DateTimeRangePickerTimeWrapper< const handleOnChange = ( newDate: PickerValidDate | null, selectionState: PickerSelectionState, - selectedView: TView, + selectedView: TimeViewWithMeridiem, ) => { if (!onChange || !value) { return; @@ -101,7 +91,7 @@ function DateTimeRangePickerTimeWrapper< value: currentValue, onChange: handleOnChange, defaultValue: currentDefaultValue, - }); + } as any as PickerViewsRendererProps); } export { DateTimeRangePickerTimeWrapper }; diff --git a/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePickerToolbar.tsx b/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePickerToolbar.tsx index f0b086455fa50..d421cc99d2359 100644 --- a/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePickerToolbar.tsx +++ b/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePickerToolbar.tsx @@ -17,12 +17,12 @@ import { import { usePickerContext, usePickerTranslations } from '@mui/x-date-pickers/hooks'; import { PickerValidDate } from '@mui/x-date-pickers/models'; import { DateTimePickerToolbar } from '@mui/x-date-pickers/DateTimePicker'; -import { UseRangePositionResponse } from '../internals/hooks/useRangePosition'; import { DateTimeRangePickerToolbarClasses, getDateTimeRangePickerToolbarUtilityClass, } from './dateTimeRangePickerToolbarClasses'; import { calculateRangeChange } from '../internals/utils/date-range-manager'; +import { usePickerRangePositionContext } from '../hooks'; const useUtilityClasses = (classes: Partial | undefined) => { const slots = { @@ -38,7 +38,6 @@ type DateTimeRangeViews = Exclude; export interface DateTimeRangePickerToolbarProps extends BaseToolbarProps, - Pick, ExportedDateTimeRangePickerToolbarProps { ampm?: boolean; } @@ -88,8 +87,6 @@ const DateTimeRangePickerToolbar = React.forwardRef(function DateTimeRangePicker const utils = useUtils(); const { - rangePosition, - onRangePositionChange, className, classes: classesProp, classes: inClasses, @@ -108,6 +105,7 @@ const DateTimeRangePickerToolbar = React.forwardRef(function DateTimeRangePicker >(); const translations = usePickerTranslations(); const ownerState = useToolbarOwnerState(); + const { rangePosition, onRangePositionChange } = usePickerRangePositionContext(); const classes = useUtilityClasses(classesProp); const commonToolbarProps = { @@ -225,8 +223,6 @@ DateTimeRangePickerToolbar.propTypes = { * @default `true` for Desktop, `false` for Mobile. */ hidden: PropTypes.bool, - onRangePositionChange: PropTypes.func.isRequired, - rangePosition: PropTypes.oneOf(['end', 'start']).isRequired, /** * The system prop that allows defining system overrides as well as additional CSS styles. */ diff --git a/packages/x-date-pickers-pro/src/DateTimeRangePicker/shared.tsx b/packages/x-date-pickers-pro/src/DateTimeRangePicker/shared.tsx index 11f4aa361b468..b9a8076df20a5 100644 --- a/packages/x-date-pickers-pro/src/DateTimeRangePicker/shared.tsx +++ b/packages/x-date-pickers-pro/src/DateTimeRangePicker/shared.tsx @@ -76,19 +76,16 @@ export interface BaseDateTimeRangePickerSlotProps toolbar?: ExportedDateTimeRangePickerToolbarProps; } -export type DateTimeRangePickerRenderers< - TView extends DateOrTimeViewWithMeridiem, - TAdditionalProps extends {} = {}, -> = PickerViewRendererLookup< - PickerRangeValue, - TView, - Omit, 'view' | 'slots' | 'slotProps'> & - Omit< - TimeViewRendererProps>, - 'view' | 'slots' | 'slotProps' - > & { view: TView }, - TAdditionalProps ->; +export type DateTimeRangePickerRenderers = + PickerViewRendererLookup< + PickerRangeValue, + TView, + Omit, 'view' | 'slots' | 'slotProps'> & + Omit< + TimeViewRendererProps>, + 'view' | 'slots' | 'slotProps' + > & { view: TView } + >; export interface BaseDateTimeRangePickerProps extends Omit< diff --git a/packages/x-date-pickers-pro/src/DesktopDateRangePicker/DesktopDateRangePicker.tsx b/packages/x-date-pickers-pro/src/DesktopDateRangePicker/DesktopDateRangePicker.tsx index 89c2044978b45..13f7339a81caa 100644 --- a/packages/x-date-pickers-pro/src/DesktopDateRangePicker/DesktopDateRangePicker.tsx +++ b/packages/x-date-pickers-pro/src/DesktopDateRangePicker/DesktopDateRangePicker.tsx @@ -46,7 +46,7 @@ const DesktopDateRangePicker = React.forwardRef(function DesktopDateRangePicker< DesktopDateRangePickerProps >(inProps, 'MuiDesktopDateRangePicker'); - const viewRenderers: PickerViewRendererLookup = { + const viewRenderers: PickerViewRendererLookup = { day: renderDateRangeViewCalendar, ...defaultizedProps.viewRenderers, }; diff --git a/packages/x-date-pickers-pro/src/DesktopDateTimeRangePicker/DesktopDateTimeRangePicker.tsx b/packages/x-date-pickers-pro/src/DesktopDateTimeRangePicker/DesktopDateTimeRangePicker.tsx index fe76558163298..d2a0dd0454c43 100644 --- a/packages/x-date-pickers-pro/src/DesktopDateTimeRangePicker/DesktopDateTimeRangePicker.tsx +++ b/packages/x-date-pickers-pro/src/DesktopDateTimeRangePicker/DesktopDateTimeRangePicker.tsx @@ -1,15 +1,15 @@ 'use client'; import * as React from 'react'; import PropTypes from 'prop-types'; -import { DefaultizedProps } from '@mui/x-internals/types'; import { isDatePickerView, isInternalTimeView, PickerViewRenderer, - PickerViewsRendererProps, resolveDateTimeFormat, useUtils, PickerRangeValue, + PickerViewRendererLookup, + PickerRendererInterceptorProps, } from '@mui/x-date-pickers/internals'; import { extractValidationProps } from '@mui/x-date-pickers/validation'; import { PickerOwnerState } from '@mui/x-date-pickers/models'; @@ -31,47 +31,24 @@ import { DesktopDateTimePickerLayout } from '@mui/x-date-pickers/DesktopDateTime import { rangeValueManager } from '../internals/utils/valueManagers'; import { DesktopDateTimeRangePickerProps } from './DesktopDateTimeRangePicker.types'; import { renderDateRangeViewCalendar } from '../dateRangeViewRenderers'; -import { - useDesktopRangePicker, - UseDesktopRangePickerProps, -} from '../internals/hooks/useDesktopRangePicker'; +import { useDesktopRangePicker } from '../internals/hooks/useDesktopRangePicker'; import { validateDateTimeRange } from '../validation'; import { DateTimeRangePickerView } from '../internals/models'; -import { - DateTimeRangePickerRenderers, - useDateTimeRangePickerDefaultizedProps, -} from '../DateTimeRangePicker/shared'; +import { useDateTimeRangePickerDefaultizedProps } from '../DateTimeRangePicker/shared'; import { MultiInputDateTimeRangeField } from '../MultiInputDateTimeRangeField'; import { DateTimeRangePickerTimeWrapper } from '../DateTimeRangePicker/DateTimeRangePickerTimeWrapper'; import { RANGE_VIEW_HEIGHT } from '../internals/constants/dimensions'; +import { usePickerRangePositionContext } from '../hooks'; -const rendererInterceptor = function rendererInterceptor< - TEnableAccessibleFieldDOMStructure extends boolean, ->( - inViewRenderers: DateTimeRangePickerRenderers, - popperView: DateTimeRangePickerView, - rendererProps: PickerViewsRendererProps< - PickerRangeValue, - DateTimeRangePickerView, - DefaultizedProps< - Omit< - UseDesktopRangePickerProps< - DateTimeRangePickerView, - TEnableAccessibleFieldDOMStructure, - any, - any - >, - 'onChange' | 'sx' | 'className' - >, - 'rangePosition' | 'onRangePositionChange' | 'openTo' - >, - {} - >, +const rendererInterceptor = function RendererInterceptor( + props: PickerRendererInterceptorProps, ) { - const { openTo, rangePosition, ...otherProps } = rendererProps; + const { viewRenderers, popperView, rendererProps } = props; + const { openTo, ...otherProps } = rendererProps; + const { rangePosition } = usePickerRangePositionContext(); + const finalProps = { ...otherProps, - rangePosition, focusedView: null, sx: [ { @@ -88,7 +65,7 @@ const rendererInterceptor = function rendererInterceptor< const isTimeViewActive = isInternalTimeView(popperView); return ( - {inViewRenderers.day?.({ + {viewRenderers.day?.({ ...rendererProps, availableRangePositions: [rangePosition], view: !isTimeViewActive ? popperView : 'day', @@ -102,11 +79,9 @@ const rendererInterceptor = function rendererInterceptor< views={finalProps.views.filter(isInternalTimeView)} openTo={isInternalTimeView(openTo) ? openTo : 'hours'} viewRenderer={ - inViewRenderers[isTimeViewActive ? popperView : 'hours'] as PickerViewRenderer< + viewRenderers[isTimeViewActive ? popperView : 'hours'] as PickerViewRenderer< PickerRangeValue, - DateTimeRangePickerView, - any, - {} + any > } sx={[{ gridColumn: 3 }, ...finalProps.sx]} @@ -146,7 +121,7 @@ const DesktopDateTimeRangePicker = React.forwardRef(function DesktopDateTimeRang ? renderDigitalClockTimeView : renderMultiSectionDigitalClockTimeView; - const viewRenderers: DateTimeRangePickerRenderers = { + const viewRenderers: PickerViewRendererLookup = { day: renderDateRangeViewCalendar, hours: renderTimeView, minutes: renderTimeView, diff --git a/packages/x-date-pickers-pro/src/MobileDateRangePicker/MobileDateRangePicker.tsx b/packages/x-date-pickers-pro/src/MobileDateRangePicker/MobileDateRangePicker.tsx index 979adfea04843..d8f3841c606c0 100644 --- a/packages/x-date-pickers-pro/src/MobileDateRangePicker/MobileDateRangePicker.tsx +++ b/packages/x-date-pickers-pro/src/MobileDateRangePicker/MobileDateRangePicker.tsx @@ -46,7 +46,7 @@ const MobileDateRangePicker = React.forwardRef(function MobileDateRangePicker< MobileDateRangePickerProps >(inProps, 'MuiMobileDateRangePicker'); - const viewRenderers: PickerViewRendererLookup = { + const viewRenderers: PickerViewRendererLookup = { day: renderDateRangeViewCalendar, ...defaultizedProps.viewRenderers, }; diff --git a/packages/x-date-pickers-pro/src/MobileDateTimeRangePicker/MobileDateTimeRangePicker.tsx b/packages/x-date-pickers-pro/src/MobileDateTimeRangePicker/MobileDateTimeRangePicker.tsx index 5bade8b66ee44..65a4e101d1438 100644 --- a/packages/x-date-pickers-pro/src/MobileDateTimeRangePicker/MobileDateTimeRangePicker.tsx +++ b/packages/x-date-pickers-pro/src/MobileDateTimeRangePicker/MobileDateTimeRangePicker.tsx @@ -2,18 +2,18 @@ import * as React from 'react'; import PropTypes from 'prop-types'; import { refType } from '@mui/utils'; -import { DefaultizedProps } from '@mui/x-internals/types'; import { DIALOG_WIDTH, VIEW_HEIGHT, isInternalTimeView, isDatePickerView, PickerViewRenderer, - PickerViewsRendererProps, TimeViewWithMeridiem, resolveDateTimeFormat, useUtils, PickerRangeValue, + PickerViewRendererLookup, + PickerRendererInterceptorProps, } from '@mui/x-date-pickers/internals'; import { extractValidationProps } from '@mui/x-date-pickers/validation'; import { PickerOwnerState } from '@mui/x-date-pickers/models'; @@ -30,44 +30,24 @@ import { digitalClockClasses } from '@mui/x-date-pickers/DigitalClock'; import { rangeValueManager } from '../internals/utils/valueManagers'; import { MobileDateTimeRangePickerProps } from './MobileDateTimeRangePicker.types'; import { renderDateRangeViewCalendar } from '../dateRangeViewRenderers'; -import { - UseMobileRangePickerProps, - useMobileRangePicker, -} from '../internals/hooks/useMobileRangePicker'; +import { useMobileRangePicker } from '../internals/hooks/useMobileRangePicker'; import { validateDateTimeRange } from '../validation'; import { DateTimeRangePickerView } from '../internals/models'; -import { - DateTimeRangePickerRenderers, - useDateTimeRangePickerDefaultizedProps, -} from '../DateTimeRangePicker/shared'; +import { useDateTimeRangePickerDefaultizedProps } from '../DateTimeRangePicker/shared'; import { MultiInputDateTimeRangeField } from '../MultiInputDateTimeRangeField'; import { DateTimeRangePickerTimeWrapper } from '../DateTimeRangePicker/DateTimeRangePickerTimeWrapper'; import { RANGE_VIEW_HEIGHT } from '../internals/constants/dimensions'; +import { usePickerRangePositionContext } from '../hooks'; -const rendererInterceptor = function rendererInterceptor< - TEnableAccessibleFieldDOMStructure extends boolean, ->( - inViewRenderers: DateTimeRangePickerRenderers, - popperView: DateTimeRangePickerView, - rendererProps: PickerViewsRendererProps< - PickerRangeValue, - DateTimeRangePickerView, - DefaultizedProps< - UseMobileRangePickerProps< - DateTimeRangePickerView, - TEnableAccessibleFieldDOMStructure, - any, - any - >, - 'rangePosition' | 'onRangePositionChange' | 'openTo' - >, - {} - >, +const rendererInterceptor = function RendererInterceptor( + props: PickerRendererInterceptorProps, ) { - const { view, openTo, rangePosition, ...otherRendererProps } = rendererProps; + const { viewRenderers, popperView, rendererProps } = props; + const { rangePosition } = usePickerRangePositionContext(); + const { view, openTo, ...otherRendererProps } = rendererProps; + const finalProps = { ...otherRendererProps, - rangePosition, focusedView: null, sx: [ { @@ -94,7 +74,7 @@ const rendererInterceptor = function rendererInterceptor< ], }; const isTimeView = isInternalTimeView(popperView); - const viewRenderer = inViewRenderers[popperView]; + const viewRenderer = viewRenderers[popperView]; if (!viewRenderer) { return null; } @@ -102,9 +82,7 @@ const rendererInterceptor = function rendererInterceptor< return ( - } + viewRenderer={viewRenderer as PickerViewRenderer} view={view && isInternalTimeView(view) ? view : 'hours'} views={finalProps.views as TimeViewWithMeridiem[]} openTo={isInternalTimeView(openTo) ? openTo : 'hours'} @@ -112,7 +90,7 @@ const rendererInterceptor = function rendererInterceptor< ); } // avoiding problem of `props: never` - const typedViewRenderer = viewRenderer as PickerViewRenderer; + const typedViewRenderer = viewRenderer as PickerViewRenderer; return typedViewRenderer({ ...finalProps, @@ -154,7 +132,7 @@ const MobileDateTimeRangePicker = React.forwardRef(function MobileDateTimeRangeP ? renderDigitalClockTimeView : renderMultiSectionDigitalClockTimeView; - const viewRenderers: DateTimeRangePickerRenderers = { + const viewRenderers: PickerViewRendererLookup = { day: renderDateRangeViewCalendar, hours: renderTimeView, minutes: renderTimeView, diff --git a/packages/x-date-pickers-pro/src/StaticDateRangePicker/StaticDateRangePicker.tsx b/packages/x-date-pickers-pro/src/StaticDateRangePicker/StaticDateRangePicker.tsx index ee9f8f61066f7..25e3485ad6dae 100644 --- a/packages/x-date-pickers-pro/src/StaticDateRangePicker/StaticDateRangePicker.tsx +++ b/packages/x-date-pickers-pro/src/StaticDateRangePicker/StaticDateRangePicker.tsx @@ -34,7 +34,7 @@ const StaticDateRangePicker = React.forwardRef(function StaticDateRangePicker( const displayStaticWrapperAs = defaultizedProps.displayStaticWrapperAs ?? 'mobile'; - const viewRenderers: PickerViewRendererLookup = { + const viewRenderers: PickerViewRendererLookup = { day: renderDateRangeViewCalendar, ...defaultizedProps.viewRenderers, }; diff --git a/packages/x-date-pickers-pro/src/dateRangeViewRenderers/dateRangeViewRenderers.tsx b/packages/x-date-pickers-pro/src/dateRangeViewRenderers/dateRangeViewRenderers.tsx index 5feb22ed9312f..0f48f57ddeb7e 100644 --- a/packages/x-date-pickers-pro/src/dateRangeViewRenderers/dateRangeViewRenderers.tsx +++ b/packages/x-date-pickers-pro/src/dateRangeViewRenderers/dateRangeViewRenderers.tsx @@ -3,7 +3,10 @@ import { DateOrTimeViewWithMeridiem } from '@mui/x-date-pickers/internals'; import { DateRangeCalendar, DateRangeCalendarProps } from '../DateRangeCalendar'; export interface DateRangeViewRendererProps - extends Omit { + extends Omit< + DateRangeCalendarProps, + 'views' | 'onRangePositionChange' | 'rangePosition' | 'defaultRangePosition' + > { views: readonly TView[]; } @@ -25,9 +28,6 @@ export const renderDateRangeViewCalendar = ({ shouldDisableDate, reduceAnimations, onMonthChange, - rangePosition, - defaultRangePosition, - onRangePositionChange, calendars, currentMonthCalendarPosition, slots, @@ -65,9 +65,6 @@ export const renderDateRangeViewCalendar = ({ shouldDisableDate={shouldDisableDate} reduceAnimations={reduceAnimations} onMonthChange={onMonthChange} - rangePosition={rangePosition} - defaultRangePosition={defaultRangePosition} - onRangePositionChange={onRangePositionChange} calendars={calendars} currentMonthCalendarPosition={currentMonthCalendarPosition} slots={slots} diff --git a/packages/x-date-pickers-pro/src/hooks/index.ts b/packages/x-date-pickers-pro/src/hooks/index.ts new file mode 100644 index 0000000000000..1a00cfc2ec27b --- /dev/null +++ b/packages/x-date-pickers-pro/src/hooks/index.ts @@ -0,0 +1 @@ +export { usePickerRangePositionContext } from './usePickerRangePositionContext'; diff --git a/packages/x-date-pickers-pro/src/hooks/usePickerRangePositionContext.ts b/packages/x-date-pickers-pro/src/hooks/usePickerRangePositionContext.ts new file mode 100644 index 0000000000000..2d0b42e2276a5 --- /dev/null +++ b/packages/x-date-pickers-pro/src/hooks/usePickerRangePositionContext.ts @@ -0,0 +1,23 @@ +'use client'; +import * as React from 'react'; +import { UseRangePositionResponse } from '../internals/hooks/useRangePosition'; + +export const PickerRangePositionContext = React.createContext( + null, +); + +/** + * Returns information about the range position of the picker that wraps the current component. + */ +export function usePickerRangePositionContext() { + const value = React.useContext(PickerRangePositionContext); + if (value == null) { + throw new Error( + [ + 'MUI X: The `usePickerRangePositionContext` can only be called in components that are used inside a picker component', + ].join('\n'), + ); + } + + return value; +} diff --git a/packages/x-date-pickers-pro/src/index.ts b/packages/x-date-pickers-pro/src/index.ts index 2ebbc0c725419..51211f5603742 100644 --- a/packages/x-date-pickers-pro/src/index.ts +++ b/packages/x-date-pickers-pro/src/index.ts @@ -28,4 +28,5 @@ export * from './MobileDateTimeRangePicker'; export * from './dateRangeViewRenderers'; export * from './models'; +export * from './hooks'; export * from './validation'; diff --git a/packages/x-date-pickers-pro/src/internals/hooks/models/useRangePicker.ts b/packages/x-date-pickers-pro/src/internals/hooks/models/useRangePicker.ts index 1002b2db6766b..9d81732ff6dd0 100644 --- a/packages/x-date-pickers-pro/src/internals/hooks/models/useRangePicker.ts +++ b/packages/x-date-pickers-pro/src/internals/hooks/models/useRangePicker.ts @@ -42,20 +42,18 @@ export interface RangeOnlyPickerProps export interface UseRangePickerProps< TView extends DateOrTimeViewWithMeridiem, TError, - TExternalProps extends UsePickerViewsProps, - TAdditionalViewProps extends {}, + TExternalProps extends UsePickerViewsProps, > extends RangeOnlyPickerProps, - BasePickerProps {} + BasePickerProps {} export interface RangePickerAdditionalViewProps extends Pick {} export interface UseRangePickerParams< TView extends DateOrTimeViewWithMeridiem, - TExternalProps extends UseRangePickerProps, - TAdditionalViewProps extends {}, + TExternalProps extends UseRangePickerProps, > extends Pick< - UsePickerParams, + UsePickerParams, 'valueManager' | 'valueType' | 'validator' | 'rendererInterceptor' > { props: TExternalProps; 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 1f2a2d64da882..beaaefb36f02f 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 @@ -1,22 +1,19 @@ import * as React from 'react'; import useSlotProps from '@mui/utils/useSlotProps'; import { useLicenseVerifier } from '@mui/x-license'; -import { PickersLayout, PickersLayoutSlotProps } from '@mui/x-date-pickers/PickersLayout'; +import { PickersLayout } from '@mui/x-date-pickers/PickersLayout'; import { executeInTheNextEventLoopTick, getActiveElement, usePicker, PickersPopper, - ExportedBaseToolbarProps, DateOrTimeViewWithMeridiem, - ExportedBaseTabsProps, PickerProvider, PickerValue, PickerRangeValue, } from '@mui/x-date-pickers/internals'; import { FieldRef, InferError } from '@mui/x-date-pickers/models'; import { - DesktopRangePickerAdditionalViewProps, UseDesktopRangePickerParams, UseDesktopRangePickerProps, } from './useDesktopRangePicker.types'; @@ -26,6 +23,7 @@ import { } from '../useEnrichedRangePickerFieldProps'; import { getReleaseInfo } from '../../utils/releaseInfo'; import { useRangePosition } from '../useRangePosition'; +import { PickerRangePositionContext } from '../../../hooks/usePickerRangePositionContext'; const releaseInfo = getReleaseInfo(); @@ -75,7 +73,7 @@ export const useDesktopRangePicker = < const initialView = React.useRef(props.openTo ?? null); const fieldType = (slots.field as any).fieldType ?? 'multi-input'; - const { rangePosition, onRangePositionChange } = useRangePosition( + const rangePositionResponse = useRangePosition( props, fieldType === 'single-input' ? singleInputFieldRef : undefined, ); @@ -83,7 +81,7 @@ export const useDesktopRangePicker = < let fieldRef: React.RefObject | FieldRef | null>; if (fieldType === 'single-input') { fieldRef = singleInputFieldRef; - } else if (rangePosition === 'start') { + } else if (rangePositionResponse.rangePosition === 'start') { fieldRef = startFieldRef; } else { fieldRef = endFieldRef; @@ -95,17 +93,13 @@ export const useDesktopRangePicker = < shouldRestoreFocus, fieldProps: pickerFieldProps, ownerState, - } = usePicker({ + } = usePicker({ ...pickerParams, props, variant: 'desktop', autoFocusView: false, fieldRef, localeText, - additionalViewProps: { - rangePosition, - onRangePositionChange, - }, }); React.useEffect(() => { @@ -176,8 +170,6 @@ export const useDesktopRangePicker = < label, localeText, onBlur: handleBlur, - rangePosition, - onRangePositionChange, pickerSlotProps: slotProps, pickerSlots: slots, fieldProps, @@ -191,41 +183,31 @@ export const useDesktopRangePicker = < : undefined, initialView: initialView.current ?? undefined, onViewChange: providerProps.contextValue.onViewChange, + ...rangePositionResponse, }); - const slotPropsForLayout: PickersLayoutSlotProps = { - ...slotProps, - tabs: { - ...slotProps?.tabs, - rangePosition, - onRangePositionChange, - } as ExportedBaseTabsProps, - toolbar: { - ...slotProps?.toolbar, - rangePosition, - onRangePositionChange, - } as ExportedBaseToolbarProps, - }; const Layout = slots?.layout ?? PickersLayout; const renderPicker = () => ( - - - - {renderCurrentView()} - - + + + + + {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 0761f8b4a6715..06494f9d27b4c 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 @@ -6,7 +6,6 @@ import { } from '@mui/x-date-pickers/internals'; import { RangeOnlyPickerProps, - RangePickerAdditionalViewProps, UseRangePickerParams, UseRangePickerProps, UseRangePickerSlotProps, @@ -30,13 +29,8 @@ export interface UseDesktopRangePickerProps< TView extends DateOrTimeViewWithMeridiem, TEnableAccessibleFieldDOMStructure extends boolean, TError, - TExternalProps extends UsePickerViewsProps, -> extends UseRangePickerProps< - TView, - TError, - TExternalProps, - DesktopRangePickerAdditionalViewProps - > { + TExternalProps extends UsePickerViewsProps, +> extends UseRangePickerProps { /** * Overridable component slots. * @default {} @@ -49,8 +43,6 @@ export interface UseDesktopRangePickerProps< slotProps?: UseDesktopRangePickerSlotProps; } -export interface DesktopRangePickerAdditionalViewProps extends RangePickerAdditionalViewProps {} - export interface UseDesktopRangePickerParams< TView extends DateOrTimeViewWithMeridiem, TEnableAccessibleFieldDOMStructure extends boolean, @@ -60,4 +52,4 @@ export interface UseDesktopRangePickerParams< any, TExternalProps >, -> extends UseRangePickerParams {} +> extends UseRangePickerParams {} diff --git a/packages/x-date-pickers-pro/src/internals/hooks/useMobileRangePicker/useMobileRangePicker.tsx b/packages/x-date-pickers-pro/src/internals/hooks/useMobileRangePicker/useMobileRangePicker.tsx index 9fb312014560a..55c6aaa437f1d 100644 --- a/packages/x-date-pickers-pro/src/internals/hooks/useMobileRangePicker/useMobileRangePicker.tsx +++ b/packages/x-date-pickers-pro/src/internals/hooks/useMobileRangePicker/useMobileRangePicker.tsx @@ -1,13 +1,12 @@ import * as React from 'react'; import useSlotProps from '@mui/utils/useSlotProps'; import { useLicenseVerifier } from '@mui/x-license'; -import { PickersLayout, PickersLayoutSlotProps } from '@mui/x-date-pickers/PickersLayout'; +import { PickersLayout } from '@mui/x-date-pickers/PickersLayout'; import { usePicker, PickersModalDialog, ExportedBaseToolbarProps, DateOrTimeViewWithMeridiem, - ExportedBaseTabsProps, PickerProvider, PickerRangeValue, PickerValue, @@ -16,7 +15,6 @@ import { usePickerTranslations } from '@mui/x-date-pickers/hooks'; import { FieldRef, InferError } from '@mui/x-date-pickers/models'; import useId from '@mui/utils/useId'; import { - MobileRangePickerAdditionalViewProps, UseMobileRangePickerParams, UseMobileRangePickerProps, } from './useMobileRangePicker.types'; @@ -26,6 +24,7 @@ import { } from '../useEnrichedRangePickerFieldProps'; import { getReleaseInfo } from '../../utils/releaseInfo'; import { useRangePosition } from '../useRangePosition'; +import { PickerRangePositionContext } from '../../../hooks/usePickerRangePositionContext'; const releaseInfo = getReleaseInfo(); @@ -69,7 +68,7 @@ export const useMobileRangePicker = < const singleInputFieldRef = React.useRef>(null); const fieldType = (slots.field as any).fieldType ?? 'multi-input'; - const { rangePosition, onRangePositionChange } = useRangePosition( + const rangePositionResponse = useRangePosition( props, fieldType === 'single-input' ? singleInputFieldRef : undefined, ); @@ -79,7 +78,7 @@ export const useMobileRangePicker = < let fieldRef: React.Ref | FieldRef>; if (fieldType === 'single-input') { fieldRef = singleInputFieldRef; - } else if (rangePosition === 'start') { + } else if (rangePositionResponse.rangePosition === 'start') { fieldRef = startFieldRef; } else { fieldRef = endFieldRef; @@ -90,17 +89,13 @@ export const useMobileRangePicker = < renderCurrentView, fieldProps: pickerFieldProps, ownerState, - } = usePicker({ + } = usePicker({ ...pickerParams, props, variant: 'mobile', autoFocusView: true, fieldRef, localeText, - additionalViewProps: { - rangePosition, - onRangePositionChange, - }, }); const Field = slots.field; @@ -150,31 +145,15 @@ export const useMobileRangePicker = < disableOpenPicker, label, localeText, - rangePosition, - onRangePositionChange, pickerSlots: slots, pickerSlotProps: innerSlotProps, fieldProps, startFieldRef, endFieldRef, singleInputFieldRef, + ...rangePositionResponse, }); - const slotPropsForLayout: PickersLayoutSlotProps = { - ...innerSlotProps, - tabs: { - ...innerSlotProps?.tabs, - rangePosition, - onRangePositionChange, - } as ExportedBaseTabsProps, - toolbar: { - ...innerSlotProps?.toolbar, - titleId: labelId, - rangePosition, - onRangePositionChange, - } as ExportedBaseToolbarProps, - }; - const Layout = slots?.layout ?? PickersLayout; const finalLocaleText = { @@ -202,6 +181,10 @@ export const useMobileRangePicker = < } const slotProps = { ...innerSlotProps, + toolbar: { + ...innerSlotProps?.toolbar, + titleId: labelId, + } as ExportedBaseToolbarProps, mobilePaper: { 'aria-labelledby': labelledById, ...innerSlotProps?.mobilePaper, @@ -210,12 +193,14 @@ export const useMobileRangePicker = < const renderPicker = () => ( - - - - {renderCurrentView()} - - + + + + + {renderCurrentView()} + + + ); diff --git a/packages/x-date-pickers-pro/src/internals/hooks/useMobileRangePicker/useMobileRangePicker.types.ts b/packages/x-date-pickers-pro/src/internals/hooks/useMobileRangePicker/useMobileRangePicker.types.ts index 3d77b15fdff50..9a9885b243931 100644 --- a/packages/x-date-pickers-pro/src/internals/hooks/useMobileRangePicker/useMobileRangePicker.types.ts +++ b/packages/x-date-pickers-pro/src/internals/hooks/useMobileRangePicker/useMobileRangePicker.types.ts @@ -6,7 +6,6 @@ import { } from '@mui/x-date-pickers/internals'; import { RangeOnlyPickerProps, - RangePickerAdditionalViewProps, UseRangePickerParams, UseRangePickerProps, UseRangePickerSlotProps, @@ -25,8 +24,8 @@ export interface UseMobileRangePickerProps< TView extends DateOrTimeViewWithMeridiem, TEnableAccessibleFieldDOMStructure extends boolean, TError, - TExternalProps extends UsePickerViewsProps, -> extends UseRangePickerProps { + TExternalProps extends UsePickerViewsProps, +> extends UseRangePickerProps { /** * Overridable component slots. * @default {} @@ -39,8 +38,6 @@ export interface UseMobileRangePickerProps< slotProps?: UseMobileRangePickerSlotProps; } -export interface MobileRangePickerAdditionalViewProps extends RangePickerAdditionalViewProps {} - export interface UseMobileRangePickerParams< TView extends DateOrTimeViewWithMeridiem, TEnableAccessibleFieldDOMStructure extends boolean, @@ -50,4 +47,4 @@ export interface UseMobileRangePickerParams< any, TExternalProps >, -> extends UseRangePickerParams {} +> extends UseRangePickerParams {} diff --git a/packages/x-date-pickers-pro/src/internals/hooks/useNullablePickerRangePositionContext.ts b/packages/x-date-pickers-pro/src/internals/hooks/useNullablePickerRangePositionContext.ts new file mode 100644 index 0000000000000..d136b05c0d165 --- /dev/null +++ b/packages/x-date-pickers-pro/src/internals/hooks/useNullablePickerRangePositionContext.ts @@ -0,0 +1,10 @@ +import * as React from 'react'; +import { PickerRangePositionContext } from '../../hooks/usePickerRangePositionContext'; + +/** + * Returns information about the range position of the picker that wraps the current component. + * If no picker wraps the current component, returns `null`. + */ +export function useNullablePickerRangePositionContext() { + return React.useContext(PickerRangePositionContext); +} diff --git a/packages/x-date-pickers-pro/src/internals/hooks/useStaticRangePicker/useStaticRangePicker.tsx b/packages/x-date-pickers-pro/src/internals/hooks/useStaticRangePicker/useStaticRangePicker.tsx index c45e885509152..904e9b3585d17 100644 --- a/packages/x-date-pickers-pro/src/internals/hooks/useStaticRangePicker/useStaticRangePicker.tsx +++ b/packages/x-date-pickers-pro/src/internals/hooks/useStaticRangePicker/useStaticRangePicker.tsx @@ -1,11 +1,10 @@ import * as React from 'react'; import clsx from 'clsx'; import { styled } from '@mui/material/styles'; -import { PickersLayout, PickersLayoutSlotProps } from '@mui/x-date-pickers/PickersLayout'; +import { PickersLayout } from '@mui/x-date-pickers/PickersLayout'; import { usePicker, DIALOG_WIDTH, - ExportedBaseToolbarProps, DateOrTimeViewWithMeridiem, PickerProvider, PickerRangeValue, @@ -15,6 +14,7 @@ import { UseStaticRangePickerProps, } from './useStaticRangePicker.types'; import { useRangePosition } from '../useRangePosition'; +import { PickerRangePositionContext } from '../../../hooks/usePickerRangePositionContext'; const PickerStaticLayout = styled(PickersLayout)(({ theme }) => ({ overflow: 'hidden', @@ -36,54 +36,39 @@ export const useStaticRangePicker = < }: UseStaticRangePickerParams) => { const { localeText, slots, slotProps, className, sx, displayStaticWrapperAs, autoFocus } = props; - const { rangePosition, onRangePositionChange } = useRangePosition(props); + const rangePositionResponse = useRangePosition(props); - const { providerProps, renderCurrentView } = usePicker< - PickerRangeValue, - TView, - TExternalProps, - {} - >({ + const { providerProps, renderCurrentView } = usePicker({ ...pickerParams, props, autoFocusView: autoFocus ?? false, fieldRef: undefined, localeText, - additionalViewProps: { - rangePosition, - onRangePositionChange, - }, variant: displayStaticWrapperAs, }); const Layout = slots?.layout ?? PickerStaticLayout; - const slotPropsForLayout: PickersLayoutSlotProps = { - ...slotProps, - toolbar: { - ...slotProps?.toolbar, - rangePosition, - onRangePositionChange, - } as ExportedBaseToolbarProps, - }; const renderPicker = () => ( - - - {renderCurrentView()} - - + + + + {renderCurrentView()} + + + ); return { renderPicker }; diff --git a/packages/x-date-pickers-pro/src/internals/hooks/useStaticRangePicker/useStaticRangePicker.types.ts b/packages/x-date-pickers-pro/src/internals/hooks/useStaticRangePicker/useStaticRangePicker.types.ts index 8a92b17eefdcc..4fee18e765300 100644 --- a/packages/x-date-pickers-pro/src/internals/hooks/useStaticRangePicker/useStaticRangePicker.types.ts +++ b/packages/x-date-pickers-pro/src/internals/hooks/useStaticRangePicker/useStaticRangePicker.types.ts @@ -26,7 +26,7 @@ export interface UseStaticRangePickerProps< TView extends DateOrTimeViewWithMeridiem, TError, TExternalProps extends UseStaticRangePickerProps, -> extends BasePickerProps, +> extends BasePickerProps, StaticRangeOnlyPickerProps { /** * Overridable components. @@ -44,7 +44,7 @@ export interface UseStaticRangePickerParams< TView extends DateOrTimeViewWithMeridiem, TExternalProps extends UseStaticRangePickerProps, > extends Pick< - UsePickerParams, + UsePickerParams, 'valueManager' | 'valueType' | 'validator' > { props: TExternalProps; diff --git a/packages/x-date-pickers/src/DatePicker/shared.tsx b/packages/x-date-pickers/src/DatePicker/shared.tsx index 6c2e372740f8e..ec1ec6d1ff74c 100644 --- a/packages/x-date-pickers/src/DatePicker/shared.tsx +++ b/packages/x-date-pickers/src/DatePicker/shared.tsx @@ -34,10 +34,11 @@ export interface BaseDatePickerSlotProps extends DateCalendarSlotProps { toolbar?: ExportedDatePickerToolbarProps; } -export type DatePickerViewRenderers< - TView extends DateView, - TAdditionalProps extends {} = {}, -> = PickerViewRendererLookup, TAdditionalProps>; +export type DatePickerViewRenderers = PickerViewRendererLookup< + PickerValue, + TView, + DateViewRendererProps +>; export interface BaseDatePickerProps extends BasePickerInputProps, diff --git a/packages/x-date-pickers/src/DateTimePicker/shared.tsx b/packages/x-date-pickers/src/DateTimePicker/shared.tsx index fef86bebde7ab..1d1fc7dc00fae 100644 --- a/packages/x-date-pickers/src/DateTimePicker/shared.tsx +++ b/packages/x-date-pickers/src/DateTimePicker/shared.tsx @@ -53,19 +53,16 @@ export interface BaseDateTimePickerSlotProps extends DateCalendarSlotProps, Time toolbar?: ExportedDateTimePickerToolbarProps; } -export type DateTimePickerViewRenderers< - TView extends DateOrTimeViewWithMeridiem, - TAdditionalProps extends {} = {}, -> = PickerViewRendererLookup< - PickerValue, - TView, - Omit, 'slots' | 'slotProps'> & - Omit< - TimeViewRendererProps>, - 'slots' | 'slotProps' - >, - TAdditionalProps ->; +export type DateTimePickerViewRenderers = + PickerViewRendererLookup< + PickerValue, + TView, + Omit, 'slots' | 'slotProps'> & + Omit< + TimeViewRendererProps>, + 'slots' | 'slotProps' + > + >; export interface BaseDateTimePickerProps extends BasePickerInputProps, diff --git a/packages/x-date-pickers/src/DesktopDatePicker/DesktopDatePicker.tsx b/packages/x-date-pickers/src/DesktopDatePicker/DesktopDatePicker.tsx index f5f035ca05f00..0f8e8f8816d49 100644 --- a/packages/x-date-pickers/src/DesktopDatePicker/DesktopDatePicker.tsx +++ b/packages/x-date-pickers/src/DesktopDatePicker/DesktopDatePicker.tsx @@ -46,7 +46,7 @@ const DesktopDatePicker = React.forwardRef(function DesktopDatePicker< DesktopDatePickerProps >(inProps, 'MuiDesktopDatePicker'); - const viewRenderers: DatePickerViewRenderers = { + const viewRenderers: DatePickerViewRenderers = { day: renderDateViewCalendar, month: renderDateViewCalendar, year: renderDateViewCalendar, diff --git a/packages/x-date-pickers/src/DesktopDateTimePicker/DesktopDateTimePicker.tsx b/packages/x-date-pickers/src/DesktopDateTimePicker/DesktopDateTimePicker.tsx index 4f14a97c0548b..e1cfbf8deeebc 100644 --- a/packages/x-date-pickers/src/DesktopDateTimePicker/DesktopDateTimePicker.tsx +++ b/packages/x-date-pickers/src/DesktopDateTimePicker/DesktopDateTimePicker.tsx @@ -3,23 +3,18 @@ import * as React from 'react'; import PropTypes from 'prop-types'; import resolveComponentProps from '@mui/utils/resolveComponentProps'; import { refType } from '@mui/utils'; -import { DefaultizedProps } from '@mui/x-internals/types'; import Divider from '@mui/material/Divider'; import { singleItemValueManager } from '../internals/utils/valueManagers'; import { DateTimeField } from '../DateTimeField'; import { DesktopDateTimePickerProps } from './DesktopDateTimePicker.types'; -import { - useDateTimePickerDefaultizedProps, - DateTimePickerViewRenderers, -} from '../DateTimePicker/shared'; +import { useDateTimePickerDefaultizedProps } from '../DateTimePicker/shared'; import { renderDateViewCalendar } from '../dateViewRenderers/dateViewRenderers'; import { usePickerTranslations } from '../hooks/usePickerTranslations'; import { useUtils } from '../internals/hooks/useUtils'; import { validateDateTime, extractValidationProps } from '../validation'; import { DateOrTimeViewWithMeridiem, PickerValue } from '../internals/models'; import { CalendarIcon } from '../icons'; -import { UseDesktopPickerProps, useDesktopPicker } from '../internals/hooks/useDesktopPicker'; -import { PickerViewsRendererProps } from '../internals/hooks/usePicker'; +import { useDesktopPicker } from '../internals/hooks/useDesktopPicker'; import { resolveDateTimeFormat, resolveTimeViewsResponse, @@ -38,33 +33,19 @@ import { import { digitalClockClasses } from '../DigitalClock'; import { DesktopDateTimePickerLayout } from './DesktopDateTimePickerLayout'; import { VIEW_HEIGHT } from '../internals/constants/dimensions'; -import { UsePickerViewsProps } from '../internals/hooks/usePicker/usePickerViews'; +import { + PickerRendererInterceptorProps, + PickerViewRendererLookup, +} from '../internals/hooks/usePicker/usePickerViews'; import { isInternalTimeView } from '../internals/utils/time-utils'; import { isDatePickerView } from '../internals/utils/date-utils'; import { buildGetOpenDialogAriaText } from '../locales/utils/getPickersLocalization'; import { PickerLayoutOwnerState } from '../PickersLayout'; -const rendererInterceptor = function rendererInterceptor< - TView extends DateOrTimeViewWithMeridiem, - TEnableAccessibleFieldDOMStructure extends boolean, ->( - inViewRenderers: DateTimePickerViewRenderers, - popperView: TView, - rendererProps: PickerViewsRendererProps< - PickerValue, - TView, - DefaultizedProps< - UseDesktopPickerProps< - TView, - TEnableAccessibleFieldDOMStructure, - any, - UsePickerViewsProps - >, - 'openTo' - >, - {} - >, +const rendererInterceptor = function RendererInterceptor( + props: PickerRendererInterceptorProps, ) { + const { viewRenderers, popperView, rendererProps } = props; const { openTo, focusedView, timeViewsCount, ...otherProps } = rendererProps; const finalProps = { @@ -83,26 +64,29 @@ const rendererInterceptor = function rendererInterceptor< ], }; const isTimeViewActive = isInternalTimeView(popperView); + const dateView = isTimeViewActive ? 'day' : popperView; + const timeView = isTimeViewActive ? popperView : 'hours'; + return ( - {inViewRenderers[!isTimeViewActive ? popperView : 'day']?.({ + {viewRenderers[dateView]?.({ ...rendererProps, view: !isTimeViewActive ? popperView : 'day', focusedView: focusedView && isDatePickerView(focusedView) ? focusedView : null, views: rendererProps.views.filter(isDatePickerView), sx: [{ gridColumn: 1 }, ...finalProps.sx], - })} + } as any)} {timeViewsCount > 0 && ( - {inViewRenderers[isTimeViewActive ? popperView : 'hours']?.({ + {viewRenderers[timeView]?.({ ...finalProps, view: isTimeViewActive ? popperView : 'hours', focusedView: focusedView && isInternalTimeView(focusedView) ? focusedView : null, openTo: isInternalTimeView(openTo) ? openTo : 'hours', views: rendererProps.views.filter(isInternalTimeView), sx: [{ gridColumn: 3 }, ...finalProps.sx], - })} + } as any)} )} @@ -150,7 +134,7 @@ const DesktopDateTimePicker = React.forwardRef(function DesktopDateTimePicker< ? renderDigitalClockTimeView : renderMultiSectionDigitalClockTimeView; - const viewRenderers: DateTimePickerViewRenderers = { + const viewRenderers: PickerViewRendererLookup = { day: renderDateViewCalendar, month: renderDateViewCalendar, year: renderDateViewCalendar, diff --git a/packages/x-date-pickers/src/DesktopTimePicker/DesktopTimePicker.tsx b/packages/x-date-pickers/src/DesktopTimePicker/DesktopTimePicker.tsx index 75528d45cd42b..62a9eff77998f 100644 --- a/packages/x-date-pickers/src/DesktopTimePicker/DesktopTimePicker.tsx +++ b/packages/x-date-pickers/src/DesktopTimePicker/DesktopTimePicker.tsx @@ -63,7 +63,7 @@ const DesktopTimePicker = React.forwardRef(function DesktopTimePicker< ? renderDigitalClockTimeView : renderMultiSectionDigitalClockTimeView; - const viewRenderers: TimePickerViewRenderers = { + const viewRenderers: TimePickerViewRenderers = { hours: renderTimeView, minutes: renderTimeView, seconds: renderTimeView, diff --git a/packages/x-date-pickers/src/MobileDatePicker/MobileDatePicker.tsx b/packages/x-date-pickers/src/MobileDatePicker/MobileDatePicker.tsx index 90e9db74e87dc..ea6d1f4025415 100644 --- a/packages/x-date-pickers/src/MobileDatePicker/MobileDatePicker.tsx +++ b/packages/x-date-pickers/src/MobileDatePicker/MobileDatePicker.tsx @@ -45,7 +45,7 @@ const MobileDatePicker = React.forwardRef(function MobileDatePicker< MobileDatePickerProps >(inProps, 'MuiMobileDatePicker'); - const viewRenderers: DatePickerViewRenderers = { + const viewRenderers: DatePickerViewRenderers = { day: renderDateViewCalendar, month: renderDateViewCalendar, year: renderDateViewCalendar, diff --git a/packages/x-date-pickers/src/MobileDateTimePicker/MobileDateTimePicker.tsx b/packages/x-date-pickers/src/MobileDateTimePicker/MobileDateTimePicker.tsx index cdc1c91a5abe8..d6be60133594b 100644 --- a/packages/x-date-pickers/src/MobileDateTimePicker/MobileDateTimePicker.tsx +++ b/packages/x-date-pickers/src/MobileDateTimePicker/MobileDateTimePicker.tsx @@ -6,10 +6,7 @@ import { refType } from '@mui/utils'; import { singleItemValueManager } from '../internals/utils/valueManagers'; import { DateTimeField } from '../DateTimeField'; import { MobileDateTimePickerProps } from './MobileDateTimePicker.types'; -import { - DateTimePickerViewRenderers, - useDateTimePickerDefaultizedProps, -} from '../DateTimePicker/shared'; +import { useDateTimePickerDefaultizedProps } from '../DateTimePicker/shared'; import { usePickerTranslations } from '../hooks/usePickerTranslations'; import { useUtils } from '../internals/hooks/useUtils'; import { extractValidationProps, validateDateTime } from '../validation'; @@ -19,6 +16,8 @@ import { renderDateViewCalendar } from '../dateViewRenderers'; import { renderTimeViewClock } from '../timeViewRenderers'; import { resolveDateTimeFormat } from '../internals/utils/date-time-utils'; import { buildGetOpenDialogAriaText } from '../locales/utils/getPickersLocalization'; +import { PickerViewRendererLookup } from '../internals/hooks/usePicker/usePickerViews'; +import { PickerValue } from '../internals/models'; type MobileDateTimePickerComponent = (( props: MobileDateTimePickerProps & @@ -50,7 +49,7 @@ const MobileDateTimePicker = React.forwardRef(function MobileDateTimePicker< MobileDateTimePickerProps >(inProps, 'MuiMobileDateTimePicker'); - const viewRenderers: DateTimePickerViewRenderers = { + const viewRenderers: PickerViewRendererLookup = { day: renderDateViewCalendar, month: renderDateViewCalendar, year: renderDateViewCalendar, diff --git a/packages/x-date-pickers/src/MobileTimePicker/MobileTimePicker.tsx b/packages/x-date-pickers/src/MobileTimePicker/MobileTimePicker.tsx index 4428a5c28a143..1affd7d8f8992 100644 --- a/packages/x-date-pickers/src/MobileTimePicker/MobileTimePicker.tsx +++ b/packages/x-date-pickers/src/MobileTimePicker/MobileTimePicker.tsx @@ -46,7 +46,7 @@ const MobileTimePicker = React.forwardRef(function MobileTimePicker< MobileTimePickerProps >(inProps, 'MuiMobileTimePicker'); - const viewRenderers: TimePickerViewRenderers = { + const viewRenderers: TimePickerViewRenderers = { hours: renderTimeViewClock, minutes: renderTimeViewClock, seconds: renderTimeViewClock, diff --git a/packages/x-date-pickers/src/StaticDatePicker/StaticDatePicker.tsx b/packages/x-date-pickers/src/StaticDatePicker/StaticDatePicker.tsx index d7a5e18afdbb1..bbc70667ebabb 100644 --- a/packages/x-date-pickers/src/StaticDatePicker/StaticDatePicker.tsx +++ b/packages/x-date-pickers/src/StaticDatePicker/StaticDatePicker.tsx @@ -34,7 +34,7 @@ const StaticDatePicker = React.forwardRef(function StaticDatePicker( const displayStaticWrapperAs = defaultizedProps.displayStaticWrapperAs ?? 'mobile'; - const viewRenderers: DatePickerViewRenderers = { + const viewRenderers: DatePickerViewRenderers = { day: renderDateViewCalendar, month: renderDateViewCalendar, year: renderDateViewCalendar, diff --git a/packages/x-date-pickers/src/StaticDateTimePicker/StaticDateTimePicker.tsx b/packages/x-date-pickers/src/StaticDateTimePicker/StaticDateTimePicker.tsx index 301852e0ff4dd..d98faf9bc0a8c 100644 --- a/packages/x-date-pickers/src/StaticDateTimePicker/StaticDateTimePicker.tsx +++ b/packages/x-date-pickers/src/StaticDateTimePicker/StaticDateTimePicker.tsx @@ -2,16 +2,15 @@ import * as React from 'react'; import PropTypes from 'prop-types'; import { StaticDateTimePickerProps } from './StaticDateTimePicker.types'; -import { - DateTimePickerViewRenderers, - useDateTimePickerDefaultizedProps, -} from '../DateTimePicker/shared'; +import { useDateTimePickerDefaultizedProps } from '../DateTimePicker/shared'; import { renderTimeViewClock } from '../timeViewRenderers'; import { renderDateViewCalendar } from '../dateViewRenderers'; import { singleItemValueManager } from '../internals/utils/valueManagers'; import { useStaticPicker } from '../internals/hooks/useStaticPicker'; import { DateOrTimeView } from '../models'; import { validateDateTime } from '../validation'; +import { PickerViewRendererLookup } from '../internals/hooks/usePicker/usePickerViews'; +import { PickerValue } from '../internals/models'; type StaticDateTimePickerComponent = (( props: StaticDateTimePickerProps & React.RefAttributes, @@ -39,7 +38,7 @@ const StaticDateTimePicker = React.forwardRef(function StaticDateTimePicker( const displayStaticWrapperAs = defaultizedProps.displayStaticWrapperAs ?? 'mobile'; const ampmInClock = defaultizedProps.ampmInClock ?? displayStaticWrapperAs === 'desktop'; - const viewRenderers: DateTimePickerViewRenderers = { + const viewRenderers: PickerViewRendererLookup = { day: renderDateViewCalendar, month: renderDateViewCalendar, year: renderDateViewCalendar, diff --git a/packages/x-date-pickers/src/StaticTimePicker/StaticTimePicker.tsx b/packages/x-date-pickers/src/StaticTimePicker/StaticTimePicker.tsx index 44341686e4fef..96aa4f9d44c03 100644 --- a/packages/x-date-pickers/src/StaticTimePicker/StaticTimePicker.tsx +++ b/packages/x-date-pickers/src/StaticTimePicker/StaticTimePicker.tsx @@ -35,7 +35,7 @@ const StaticTimePicker = React.forwardRef(function StaticTimePicker( const displayStaticWrapperAs = defaultizedProps.displayStaticWrapperAs ?? 'mobile'; const ampmInClock = defaultizedProps.ampmInClock ?? displayStaticWrapperAs === 'desktop'; - const viewRenderers: TimePickerViewRenderers = { + const viewRenderers: TimePickerViewRenderers = { hours: renderTimeViewClock, minutes: renderTimeViewClock, seconds: renderTimeViewClock, diff --git a/packages/x-date-pickers/src/TimePicker/shared.tsx b/packages/x-date-pickers/src/TimePicker/shared.tsx index 281caf40c139e..e1aa01bcc75ed 100644 --- a/packages/x-date-pickers/src/TimePicker/shared.tsx +++ b/packages/x-date-pickers/src/TimePicker/shared.tsx @@ -30,14 +30,10 @@ export interface BaseTimePickerSlotProps extends TimeClockSlotProps { toolbar?: ExportedTimePickerToolbarProps; } -export type TimePickerViewRenderers< - TView extends TimeViewWithMeridiem, - TAdditionalProps extends {} = {}, -> = PickerViewRendererLookup< +export type TimePickerViewRenderers = PickerViewRendererLookup< PickerValue, TView, - TimeViewRendererProps>, - TAdditionalProps + TimeViewRendererProps> >; export interface BaseTimePickerProps 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 66b8c6cb0b630..78bfd753ea969 100644 --- a/packages/x-date-pickers/src/internals/hooks/useDesktopPicker/useDesktopPicker.tsx +++ b/packages/x-date-pickers/src/internals/hooks/useDesktopPicker/useDesktopPicker.tsx @@ -66,13 +66,12 @@ export const useDesktopPicker = < shouldRestoreFocus, fieldProps: pickerFieldProps, ownerState, - } = usePicker({ + } = usePicker({ ...pickerParams, props, fieldRef, localeText, autoFocusView: true, - additionalViewProps: {}, variant: 'desktop', }); 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 dc08d3ab261bc..ebbf1116a8141 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 @@ -103,8 +103,8 @@ export interface UseDesktopPickerProps< TView extends DateOrTimeViewWithMeridiem, TEnableAccessibleFieldDOMStructure extends boolean, TError, - TExternalProps extends UsePickerViewsProps, -> extends BasePickerProps, + TExternalProps extends UsePickerViewsProps, +> extends BasePickerProps, MakeRequired { /** * Overridable component slots. @@ -128,7 +128,7 @@ export interface UseDesktopPickerParams< TExternalProps >, > extends Pick< - UsePickerParams, + UsePickerParams, 'valueManager' | 'valueType' | 'validator' | 'rendererInterceptor' > { props: TExternalProps; diff --git a/packages/x-date-pickers/src/internals/hooks/useMobilePicker/useMobilePicker.tsx b/packages/x-date-pickers/src/internals/hooks/useMobilePicker/useMobilePicker.tsx index 7b1babc50a59a..b9acebd6fbfee 100644 --- a/packages/x-date-pickers/src/internals/hooks/useMobilePicker/useMobilePicker.tsx +++ b/packages/x-date-pickers/src/internals/hooks/useMobilePicker/useMobilePicker.tsx @@ -60,13 +60,12 @@ export const useMobilePicker = < renderCurrentView, fieldProps: pickerFieldProps, ownerState, - } = usePicker({ + } = usePicker({ ...pickerParams, props, fieldRef, localeText, autoFocusView: true, - additionalViewProps: {}, variant: 'mobile', }); diff --git a/packages/x-date-pickers/src/internals/hooks/useMobilePicker/useMobilePicker.types.ts b/packages/x-date-pickers/src/internals/hooks/useMobilePicker/useMobilePicker.types.ts index c01b00e785df8..f905d0e670b67 100644 --- a/packages/x-date-pickers/src/internals/hooks/useMobilePicker/useMobilePicker.types.ts +++ b/packages/x-date-pickers/src/internals/hooks/useMobilePicker/useMobilePicker.types.ts @@ -72,8 +72,8 @@ export interface UseMobilePickerProps< TView extends DateOrTimeViewWithMeridiem, TEnableAccessibleFieldDOMStructure extends boolean, TError, - TExternalProps extends UsePickerViewsProps, -> extends BasePickerProps, + TExternalProps extends UsePickerViewsProps, +> extends BasePickerProps, MakeRequired { /** * Overridable component slots. @@ -97,7 +97,7 @@ export interface UseMobilePickerParams< TExternalProps >, > extends Pick< - UsePickerParams, + UsePickerParams, 'valueManager' | 'valueType' | 'validator' > { props: TExternalProps; 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 16daed938d428..2b03fbc3cb073 100644 --- a/packages/x-date-pickers/src/internals/hooks/usePicker/usePicker.ts +++ b/packages/x-date-pickers/src/internals/hooks/usePicker/usePicker.ts @@ -9,20 +9,18 @@ import { usePickerProvider } from './usePickerProvider'; export const usePicker = < TValue extends PickerValidValue, TView extends DateOrTimeViewWithMeridiem, - TExternalProps extends UsePickerProps, - TAdditionalProps extends {}, + TExternalProps extends UsePickerProps, >({ props, valueManager, valueType, variant, - additionalViewProps, validator, autoFocusView, rendererInterceptor, fieldRef, localeText, -}: UsePickerParams): UsePickerResponse< +}: UsePickerParams): UsePickerResponse< TValue, TView, InferError @@ -44,9 +42,8 @@ export const usePicker = < validator, }); - const pickerViewsResponse = usePickerViews({ + const pickerViewsResponse = usePickerViews({ props, - additionalViewProps, autoFocusView, fieldRef, propsFromPickerValue: pickerValueResponse.viewProps, 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 eb966802b7223..c8b0138a48a0e 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 @@ -25,36 +25,33 @@ export interface UsePickerBaseProps< TValue extends PickerValidValue, TView extends DateOrTimeViewWithMeridiem, TError, - TExternalProps extends UsePickerViewsProps, - TAdditionalProps extends {}, + TExternalProps extends UsePickerViewsProps, > extends UsePickerValueBaseProps, - UsePickerViewsBaseProps, + UsePickerViewsBaseProps, UsePickerProviderProps {} export interface UsePickerProps< TValue extends PickerValidValue, TView extends DateOrTimeViewWithMeridiem, TError, - TExternalProps extends UsePickerViewsProps, - TAdditionalProps extends {}, + TExternalProps extends UsePickerViewsProps, > extends UsePickerValueProps, - UsePickerViewsProps, + UsePickerViewsProps, UsePickerProviderProps {} export interface UsePickerParams< TValue extends PickerValidValue, TView extends DateOrTimeViewWithMeridiem, - TExternalProps extends UsePickerProps, - TAdditionalProps extends {}, + TExternalProps extends UsePickerProps, > extends Pick< UsePickerValueParams, 'valueManager' | 'valueType' | 'variant' | 'validator' >, Pick< - UsePickerViewParams, - 'additionalViewProps' | 'autoFocusView' | 'rendererInterceptor' | 'fieldRef' + UsePickerViewParams, + 'autoFocusView' | 'rendererInterceptor' | 'fieldRef' >, - Pick>, 'localeText'> { + Pick>, 'localeText'> { props: TExternalProps; } 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 6cb0bfc5c21df..f907c589f527a 100644 --- a/packages/x-date-pickers/src/internals/hooks/usePicker/usePickerProvider.ts +++ b/packages/x-date-pickers/src/internals/hooks/usePicker/usePickerProvider.ts @@ -142,7 +142,7 @@ export interface UsePickerProviderParameters< TView extends DateOrTimeViewWithMeridiem, TError, > extends Pick, 'localeText'> { - props: UsePickerProps; + props: UsePickerProps; valueManager: PickerValueManager; variant: PickerVariant; paramsFromUsePickerValue: UsePickerValueProviderParams; diff --git a/packages/x-date-pickers/src/internals/hooks/usePicker/usePickerViews.ts b/packages/x-date-pickers/src/internals/hooks/usePicker/usePickerViews.tsx similarity index 80% rename from packages/x-date-pickers/src/internals/hooks/usePicker/usePickerViews.ts rename to packages/x-date-pickers/src/internals/hooks/usePicker/usePickerViews.tsx index 38f7ebd13b7d5..93dc3c32399ce 100644 --- a/packages/x-date-pickers/src/internals/hooks/usePicker/usePickerViews.ts +++ b/packages/x-date-pickers/src/internals/hooks/usePicker/usePickerViews.tsx @@ -14,16 +14,14 @@ import { } from '../../models'; import { FieldRef, PickerValidDate, TimezoneProps } from '../../../models'; -interface PickerViewsRendererBaseExternalProps - extends Omit, 'openTo' | 'viewRenderers'> {} +export interface PickerViewsRendererBaseExternalProps + extends Omit, 'openTo' | 'viewRenderers'> {} export type PickerViewsRendererProps< TValue extends PickerValidValue, TView extends DateOrTimeViewWithMeridiem, - TExternalProps extends PickerViewsRendererBaseExternalProps, - TAdditionalProps extends {}, + TExternalProps extends PickerViewsRendererBaseExternalProps, > = Omit & - TAdditionalProps & Pick, 'value' | 'onChange'> & { view: TView; views: readonly TView[]; @@ -35,21 +33,14 @@ export type PickerViewsRendererProps< export type PickerViewRenderer< TValue extends PickerValidValue, - TView extends DateOrTimeViewWithMeridiem, - TExternalProps extends PickerViewsRendererBaseExternalProps, - TAdditionalProps extends {}, -> = ( - props: PickerViewsRendererProps, -) => React.ReactNode; + TExternalProps extends PickerViewsRendererBaseExternalProps, +> = (props: PickerViewsRendererProps) => React.ReactNode; export type PickerViewRendererLookup< TValue extends PickerValidValue, TView extends DateOrTimeViewWithMeridiem, - TExternalProps extends PickerViewsRendererBaseExternalProps, - TAdditionalProps extends {}, -> = { - [K in TView]: PickerViewRenderer | null; -}; + TExternalProps extends PickerViewsRendererBaseExternalProps, +> = Record | null>; /** * Props used to handle the views that are common to all pickers. @@ -57,15 +48,14 @@ export type PickerViewRendererLookup< export interface UsePickerViewsBaseProps< TValue extends PickerValidValue, TView extends DateOrTimeViewWithMeridiem, - TExternalProps extends UsePickerViewsProps, - TAdditionalProps extends {}, + TExternalProps extends UsePickerViewsProps, > extends Omit, 'onChange' | 'onFocusedViewChange' | 'focusedView'>, TimezoneProps { /** * If `null`, the section will only have field editing. * If `undefined`, internally defined view will be used. */ - viewRenderers: PickerViewRendererLookup; + viewRenderers: PickerViewRendererLookup; /** * If `true`, disable heavy animations. * @default `@media(prefers-reduced-motion: reduce)` || `navigator.userAgent` matches Android <10 or iOS <13 @@ -84,9 +74,8 @@ export interface UsePickerViewsBaseProps< export interface UsePickerViewsProps< TValue extends PickerValidValue, TView extends DateOrTimeViewWithMeridiem, - TExternalProps extends UsePickerViewsProps, - TAdditionalProps extends {}, -> extends UsePickerViewsBaseProps { + TExternalProps extends UsePickerViewsProps, +> extends UsePickerViewsBaseProps { className?: string; sx?: SxProps; } @@ -94,27 +83,33 @@ export interface UsePickerViewsProps< export interface UsePickerViewParams< TValue extends PickerValidValue, TView extends DateOrTimeViewWithMeridiem, - TExternalProps extends UsePickerViewsProps, - TAdditionalProps extends {}, + TExternalProps extends UsePickerViewsProps, > { props: TExternalProps; propsFromPickerValue: UsePickerValueViewsResponse; - additionalViewProps: TAdditionalProps; autoFocusView: boolean; fieldRef?: React.RefObject | FieldRef | null>; /** * A function that intercepts the regular picker rendering. * Can be used to consume the provided `viewRenderers` and render a custom component wrapping them. - * @param {PickerViewRendererLookup} viewRenderers The `viewRenderers` that were provided to the picker component. + * @param {PickerViewRendererLookup} viewRenderers The `viewRenderers` that were provided to the picker component. * @param {TView} popperView The current picker view. * @param {any} rendererProps All the props that are being passed down to the renderer. * @returns {React.ReactNode} A React node that will be rendered instead of the default renderer. */ - rendererInterceptor?: ( - viewRenderers: PickerViewRendererLookup, - popperView: TView, - rendererProps: PickerViewsRendererProps, - ) => React.ReactNode; + rendererInterceptor?: React.JSXElementConstructor< + PickerRendererInterceptorProps + >; +} + +export interface PickerRendererInterceptorProps< + TValue extends PickerValidValue, + TView extends DateOrTimeViewWithMeridiem, + TExternalProps extends UsePickerViewsProps, +> { + viewRenderers: PickerViewRendererLookup; + popperView: TView; + rendererProps: PickerViewsRendererProps; } export interface UsePickerViewsResponse { @@ -155,21 +150,14 @@ export interface UsePickerViewsProviderParams, - TAdditionalProps extends {}, + TExternalProps extends UsePickerViewsProps, >({ props, propsFromPickerValue, - additionalViewProps, autoFocusView, - rendererInterceptor, + rendererInterceptor: RendererInterceptor, fieldRef, -}: UsePickerViewParams< - TValue, - TView, - TExternalProps, - TAdditionalProps ->): UsePickerViewsResponse => { +}: UsePickerViewParams): UsePickerViewsResponse => { const { onChange, value, open, setOpen } = propsFromPickerValue; const { view: inView, views, openTo, onViewChange, viewRenderers, timezone } = props; const { className, sx, ...propsToForwardToView } = props; @@ -296,14 +284,8 @@ export const usePickerViews = < return null; } - const rendererProps: PickerViewsRendererProps< - TValue, - TView, - TExternalProps, - TAdditionalProps - > = { + const rendererProps: PickerViewsRendererProps = { ...propsToForwardToView, - ...additionalViewProps, views, timezone, value, @@ -316,8 +298,14 @@ export const usePickerViews = < timeViewsCount, }; - if (rendererInterceptor) { - return rendererInterceptor(viewRenderers, popperView, rendererProps); + if (RendererInterceptor) { + return ( + + ); } return renderer(rendererProps); diff --git a/packages/x-date-pickers/src/internals/hooks/useStaticPicker/useStaticPicker.tsx b/packages/x-date-pickers/src/internals/hooks/useStaticPicker/useStaticPicker.tsx index d4a97eb5a5a1a..e64a236610c56 100644 --- a/packages/x-date-pickers/src/internals/hooks/useStaticPicker/useStaticPicker.tsx +++ b/packages/x-date-pickers/src/internals/hooks/useStaticPicker/useStaticPicker.tsx @@ -30,12 +30,11 @@ export const useStaticPicker = < }: UseStaticPickerParams) => { const { localeText, slots, slotProps, className, sx, displayStaticWrapperAs, autoFocus } = props; - const { providerProps, renderCurrentView } = usePicker({ + const { providerProps, renderCurrentView } = usePicker({ ...pickerParams, props, autoFocusView: autoFocus ?? false, localeText, - additionalViewProps: {}, variant: displayStaticWrapperAs, }); diff --git a/packages/x-date-pickers/src/internals/hooks/useStaticPicker/useStaticPicker.types.ts b/packages/x-date-pickers/src/internals/hooks/useStaticPicker/useStaticPicker.types.ts index c6c4c52d70c90..e3648605b28b9 100644 --- a/packages/x-date-pickers/src/internals/hooks/useStaticPicker/useStaticPicker.types.ts +++ b/packages/x-date-pickers/src/internals/hooks/useStaticPicker/useStaticPicker.types.ts @@ -34,8 +34,8 @@ export interface StaticOnlyPickerProps { export interface UseStaticPickerProps< TView extends DateOrTimeViewWithMeridiem, TError, - TExternalProps extends UsePickerViewsProps, -> extends BasePickerProps, + TExternalProps extends UsePickerViewsProps, +> extends BasePickerProps, StaticOnlyPickerProps { /** * Overridable component slots. @@ -53,7 +53,7 @@ export interface UseStaticPickerParams< TView extends DateOrTimeViewWithMeridiem, TExternalProps extends UseStaticPickerProps, > extends Pick< - UsePickerParams, + UsePickerParams, 'valueManager' | 'valueType' | 'validator' > { props: TExternalProps; diff --git a/packages/x-date-pickers/src/internals/index.ts b/packages/x-date-pickers/src/internals/index.ts index 17226de88c7f3..28aeb4799b72b 100644 --- a/packages/x-date-pickers/src/internals/index.ts +++ b/packages/x-date-pickers/src/internals/index.ts @@ -81,6 +81,7 @@ export type { } from './hooks/usePicker/usePickerValue.types'; export type { PickerViewRendererLookup, + PickerRendererInterceptorProps, PickerViewRenderer, UsePickerViewsProps, } from './hooks/usePicker/usePickerViews'; diff --git a/packages/x-date-pickers/src/internals/models/props/basePickerProps.tsx b/packages/x-date-pickers/src/internals/models/props/basePickerProps.tsx index c4fef0bdaa157..78beba3a580bb 100644 --- a/packages/x-date-pickers/src/internals/models/props/basePickerProps.tsx +++ b/packages/x-date-pickers/src/internals/models/props/basePickerProps.tsx @@ -16,9 +16,8 @@ export interface BasePickerProps< TValue extends PickerValidValue, TView extends DateOrTimeViewWithMeridiem, TError, - TExternalProps extends UsePickerViewsProps, - TAdditionalProps extends {}, -> extends UsePickerBaseProps { + TExternalProps extends UsePickerViewsProps, +> extends UsePickerBaseProps { className?: string; /** * The system prop that allows defining system overrides as well as additional CSS styles. @@ -39,7 +38,7 @@ export interface BasePickerInputProps< TView extends DateOrTimeViewWithMeridiem, TError, > extends Omit< - MakeOptional, 'openTo' | 'views'>, + MakeOptional, 'openTo' | 'views'>, 'viewRenderers' > {} diff --git a/scripts/x-date-pickers-pro.exports.json b/scripts/x-date-pickers-pro.exports.json index 23d0c71388936..a58b7384bd29a 100644 --- a/scripts/x-date-pickers-pro.exports.json +++ b/scripts/x-date-pickers-pro.exports.json @@ -418,6 +418,7 @@ { "name": "usePickerActionsContext", "kind": "Variable" }, { "name": "usePickerContext", "kind": "Variable" }, { "name": "usePickerLayout", "kind": "ExportAssignment" }, + { "name": "usePickerRangePositionContext", "kind": "Function" }, { "name": "usePickerTranslations", "kind": "Variable" }, { "name": "UseSingleInputDateRangeFieldProps", "kind": "Interface" }, { "name": "UseSingleInputDateTimeRangeFieldProps", "kind": "Interface" },