diff --git a/docs/data/migration/migration-pickers-v6/migration-pickers-v6.md b/docs/data/migration/migration-pickers-v6/migration-pickers-v6.md index 7ebe82d1279d..456e79dc53d4 100644 --- a/docs/data/migration/migration-pickers-v6/migration-pickers-v6.md +++ b/docs/data/migration/migration-pickers-v6/migration-pickers-v6.md @@ -526,6 +526,16 @@ Before v7, it was possible to import locales from the package root (that is `imp +import { frFR } from '@mui/x-date-pickers/locales'; ``` +## Remove `dateTimeViewRenderers` export + +The `dateTimeViewRenderers` export has been removed in favor of reusing existing time view renderers (`renderTimeViewClock`, `renderDigitalClockTimeView` and `renderMultiSectionDigitalClockTimeView`) and date view renderer (`renderDateViewCalendar`) to render the `DesktopDateTimePicker`. + +If you were relying on this import, you can refer to the implementation of the `DesktopDateTimePicker` to see how to combine the renderers yourself. + +:::info +The additional side-effect of this change is that passing `renderTimeViewClock` to time view renderers will no longer revert to the old behavior of rendering only date or time view. +::: + ## Adapters internal changes :::success diff --git a/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePickerTimeWrapper.tsx b/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePickerTimeWrapper.tsx index 9bc3597b7927..e8f096ffcef5 100644 --- a/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePickerTimeWrapper.tsx +++ b/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePickerTimeWrapper.tsx @@ -6,9 +6,9 @@ import { useUtils, TimeViewWithMeridiem, BaseClockProps, + DefaultizedProps, } from '@mui/x-date-pickers/internals'; import { PickerValidDate } from '@mui/x-date-pickers/models'; -import { DateTimeRangePickerView } from '../internals/models'; import { DateRange } from '../models'; import { UseRangePositionResponse } from '../internals/hooks/useRangePosition'; import { isRangeValid } from '../internals/utils/date-utils'; @@ -16,10 +16,10 @@ import { calculateRangeChange } from '../internals/utils/date-range-manager'; export type DateTimeRangePickerTimeWrapperProps< TDate extends PickerValidDate, - TView extends DateTimeRangePickerView, - TComponentProps extends Omit< - BaseClockProps, - 'value' | 'defaultValue' | 'onChange' + TView extends TimeViewWithMeridiem, + TComponentProps extends DefaultizedProps< + Omit, 'value' | 'defaultValue' | 'onChange'>, + 'views' >, > = Pick & Omit< @@ -36,7 +36,7 @@ export type DateTimeRangePickerTimeWrapperProps< selectionState: PickerSelectionState, selectedView: TView, ) => void; - viewRenderer?: PickerViewRenderer, TView, any, TComponentProps> | null; + viewRenderer?: PickerViewRenderer, TView, TComponentProps, any> | null; openTo?: TView; }; @@ -45,10 +45,10 @@ export type DateTimeRangePickerTimeWrapperProps< */ function DateTimeRangePickerTimeWrapper< TDate extends PickerValidDate, - TView extends DateTimeRangePickerView, - TComponentProps extends Omit< - BaseClockProps, - 'value' | 'defaultValue' | 'onChange' + TView extends TimeViewWithMeridiem, + TComponentProps extends DefaultizedProps< + Omit, 'value' | 'defaultValue' | 'onChange'>, + 'views' >, >( props: DateTimeRangePickerTimeWrapperProps, diff --git a/packages/x-date-pickers-pro/src/DateTimeRangePicker/shared.tsx b/packages/x-date-pickers-pro/src/DateTimeRangePicker/shared.tsx index cbbaa6102347..34d53e01ead6 100644 --- a/packages/x-date-pickers-pro/src/DateTimeRangePicker/shared.tsx +++ b/packages/x-date-pickers-pro/src/DateTimeRangePicker/shared.tsx @@ -16,6 +16,7 @@ import { resolveTimeViewsResponse, UseViewsOptions, DateTimeValidationProps, + DateOrTimeViewWithMeridiem, } from '@mui/x-date-pickers/internals'; import { PickerValidDate } from '@mui/x-date-pickers/models'; import { TimeViewRendererProps } from '@mui/x-date-pickers/timeViewRenderers'; @@ -73,6 +74,21 @@ export interface BaseDateTimeRangePickerSlotProps toolbar?: ExportedDateTimeRangePickerToolbarProps; } +export type DateTimeRangePickerRenderers< + TDate extends PickerValidDate, + TView extends DateOrTimeViewWithMeridiem, + TAdditionalProps extends {} = {}, +> = PickerViewRendererLookup< + DateRange, + TView, + Omit, 'view' | 'slots' | 'slotProps'> & + Omit< + TimeViewRendererProps>, + 'view' | 'slots' | 'slotProps' + > & { view: TView }, + TAdditionalProps +>; + export interface BaseDateTimeRangePickerProps extends Omit< BasePickerInputProps< @@ -105,18 +121,7 @@ export interface BaseDateTimeRangePickerProps * If `null`, the section will only have field editing. * If `undefined`, internally defined view will be the used. */ - viewRenderers?: Partial< - PickerViewRendererLookup< - DateRange, - DateTimeRangePickerView, - Omit, 'view' | 'slots' | 'slotProps'> & - Omit< - TimeViewRendererProps>, - 'view' | 'slots' | 'slotProps' - > & { view: DateTimeRangePickerView }, - {} - > - >; + viewRenderers?: Partial>; } type UseDateTimeRangePickerDefaultizedProps< diff --git a/packages/x-date-pickers-pro/src/DesktopDateTimeRangePicker/DesktopDateTimeRangePicker.tsx b/packages/x-date-pickers-pro/src/DesktopDateTimeRangePicker/DesktopDateTimeRangePicker.tsx index 0d6c6fa6d85c..f7cb2705a017 100644 --- a/packages/x-date-pickers-pro/src/DesktopDateTimeRangePicker/DesktopDateTimeRangePicker.tsx +++ b/packages/x-date-pickers-pro/src/DesktopDateTimeRangePicker/DesktopDateTimeRangePicker.tsx @@ -6,7 +6,7 @@ import { isDatePickerView, isInternalTimeView, PickerViewRenderer, - PickerViewRendererLookup, + PickerViewsRendererProps, } from '@mui/x-date-pickers/internals'; import { PickerValidDate } from '@mui/x-date-pickers/models'; import { resolveComponentProps } from '@mui/base/utils'; @@ -22,6 +22,7 @@ import { import Divider from '@mui/material/Divider'; import { digitalClockClasses } from '@mui/x-date-pickers/DigitalClock'; import type { PickersActionBarAction } from '@mui/x-date-pickers/PickersActionBar'; +import { DesktopDateTimePickerLayout } from '@mui/x-date-pickers/DesktopDateTimePicker'; import { rangeValueManager } from '../internals/utils/valueManagers'; import { DesktopDateTimeRangePickerProps } from './DesktopDateTimeRangePicker.types'; import { renderDateRangeViewCalendar } from '../dateRangeViewRenderers'; @@ -32,47 +33,54 @@ import { import { validateDateTimeRange } from '../internals/utils/validation/validateDateTimeRange'; import { DateTimeRangePickerView } from '../internals/models'; import { DateRange } from '../models'; -import { useDateTimeRangePickerDefaultizedProps } from '../DateTimeRangePicker/shared'; +import { + DateTimeRangePickerRenderers, + useDateTimeRangePickerDefaultizedProps, +} from '../DateTimeRangePicker/shared'; import { MultiInputDateTimeRangeField } from '../MultiInputDateTimeRangeField'; import { DateTimeRangePickerTimeWrapper } from '../DateTimeRangePicker/DateTimeRangePickerTimeWrapper'; import { RANGE_VIEW_HEIGHT } from '../internals/constants/dimensions'; -import { DesktopDateTimeRangePickerLayout } from './DesktopDateTimeRangePickerLayout'; const rendererInterceptor = function rendererInterceptor< TDate extends PickerValidDate, TEnableAccessibleFieldDOMStructure extends boolean, >( - inViewRenderers: PickerViewRendererLookup, DateTimeRangePickerView, any, any>, + inViewRenderers: DateTimeRangePickerRenderers, popperView: DateTimeRangePickerView, - rendererProps: DefaultizedProps< - Omit< - UseDesktopRangePickerProps< - TDate, - DateTimeRangePickerView, - TEnableAccessibleFieldDOMStructure, - any, - any + rendererProps: PickerViewsRendererProps< + DateRange, + DateTimeRangePickerView, + DefaultizedProps< + Omit< + UseDesktopRangePickerProps< + TDate, + DateTimeRangePickerView, + TEnableAccessibleFieldDOMStructure, + any, + any + >, + 'onChange' | 'sx' | 'className' >, - 'onChange' + 'rangePosition' | 'onRangePositionChange' | 'openTo' >, - 'rangePosition' | 'onRangePositionChange' | 'openTo' + {} >, ) { - const { openTo, rangePosition, sx, ...otherProps } = rendererProps; + const { openTo, rangePosition, ...otherProps } = rendererProps; const finalProps = { ...otherProps, rangePosition, focusedView: null, sx: [ { - borderBottom: 0, - width: 'auto', + [`&.${multiSectionDigitalClockClasses.root}`]: { + borderBottom: 0, + }, [`&.${multiSectionDigitalClockClasses.root}, .${multiSectionDigitalClockSectionClasses.root}, &.${digitalClockClasses.root}`]: { maxHeight: RANGE_VIEW_HEIGHT, }, }, - ...(Array.isArray(sx) ? sx : [sx]), ], }; const isTimeViewActive = isInternalTimeView(popperView); @@ -88,6 +96,7 @@ const rendererInterceptor = function rendererInterceptor< , - DateTimeRangePickerView, - any, - {} - > = { + const viewRenderers: DateTimeRangePickerRenderers = { day: renderDateRangeViewCalendar, hours: renderTimeView, minutes: renderTimeView, @@ -159,7 +163,7 @@ const DesktopDateTimeRangePicker = React.forwardRef(function DesktopDateTimeRang calendars: defaultizedProps.calendars ?? 1, slots: { field: MultiInputDateTimeRangeField, - layout: DesktopDateTimeRangePickerLayout, + layout: DesktopDateTimePickerLayout, ...defaultizedProps.slots, }, slotProps: { diff --git a/packages/x-date-pickers-pro/src/DesktopDateTimeRangePicker/DesktopDateTimeRangePickerLayout.tsx b/packages/x-date-pickers-pro/src/DesktopDateTimeRangePicker/DesktopDateTimeRangePickerLayout.tsx deleted file mode 100644 index 37d9dc97df20..000000000000 --- a/packages/x-date-pickers-pro/src/DesktopDateTimeRangePicker/DesktopDateTimeRangePickerLayout.tsx +++ /dev/null @@ -1,51 +0,0 @@ -import * as React from 'react'; -import clsx from 'clsx'; -import Divider from '@mui/material/Divider'; -import { - PickersLayoutContentWrapper, - PickersLayoutProps, - PickersLayoutRoot, - pickersLayoutClasses, - usePickerLayout, -} from '@mui/x-date-pickers/PickersLayout'; -import { PickerValidDate } from '@mui/x-date-pickers/models'; -import { DateRange } from '../models'; -import { DateTimeRangePickerView } from '../internals/models/dateTimeRange'; - -/** - * @ignore - internal component. - */ -export function DesktopDateTimeRangePickerLayout( - props: PickersLayoutProps, TDate, DateTimeRangePickerView>, -) { - const { toolbar, tabs, content, actionBar, shortcuts } = usePickerLayout(props); - const { sx, className, isLandscape, ref } = props; - const isActionBarVisible = actionBar && (actionBar.props.actions?.length ?? 0) > 0; - - return ( - - {isLandscape ? shortcuts : toolbar} - {isLandscape ? toolbar : shortcuts} - - {content} - - {isActionBarVisible && } - {tabs} - {actionBar} - - ); -} diff --git a/packages/x-date-pickers-pro/src/MobileDateTimeRangePicker/MobileDateTimeRangePicker.tsx b/packages/x-date-pickers-pro/src/MobileDateTimeRangePicker/MobileDateTimeRangePicker.tsx index 4bce95d92d91..cfb21de64f79 100644 --- a/packages/x-date-pickers-pro/src/MobileDateTimeRangePicker/MobileDateTimeRangePicker.tsx +++ b/packages/x-date-pickers-pro/src/MobileDateTimeRangePicker/MobileDateTimeRangePicker.tsx @@ -6,10 +6,11 @@ import { VIEW_HEIGHT, extractValidationProps, isInternalTimeView, - PickerViewRendererLookup, isDatePickerView, PickerViewRenderer, DefaultizedProps, + PickerViewsRendererProps, + TimeViewWithMeridiem, } from '@mui/x-date-pickers/internals'; import { PickerValidDate } from '@mui/x-date-pickers/models'; import { resolveComponentProps } from '@mui/base/utils'; @@ -32,7 +33,10 @@ import { import { validateDateTimeRange } from '../internals/utils/validation/validateDateTimeRange'; import { DateTimeRangePickerView } from '../internals/models'; import { DateRange } from '../models'; -import { useDateTimeRangePickerDefaultizedProps } from '../DateTimeRangePicker/shared'; +import { + DateTimeRangePickerRenderers, + useDateTimeRangePickerDefaultizedProps, +} from '../DateTimeRangePicker/shared'; import { MultiInputDateTimeRangeField } from '../MultiInputDateTimeRangeField'; import { DateTimeRangePickerTimeWrapper } from '../DateTimeRangePicker/DateTimeRangePickerTimeWrapper'; import { RANGE_VIEW_HEIGHT } from '../internals/constants/dimensions'; @@ -41,10 +45,12 @@ const rendererInterceptor = function rendererInterceptor< TDate extends PickerValidDate, TEnableAccessibleFieldDOMStructure extends boolean, >( - inViewRenderers: PickerViewRendererLookup, DateTimeRangePickerView, any, any>, + inViewRenderers: DateTimeRangePickerRenderers, popperView: DateTimeRangePickerView, - rendererProps: DefaultizedProps< - Omit< + rendererProps: PickerViewsRendererProps< + DateRange, + DateTimeRangePickerView, + DefaultizedProps< UseMobileRangePickerProps< TDate, DateTimeRangePickerView, @@ -52,12 +58,12 @@ const rendererInterceptor = function rendererInterceptor< any, any >, - 'onChange' + 'rangePosition' | 'onRangePositionChange' | 'openTo' >, - 'rangePosition' | 'onRangePositionChange' | 'openTo' + {} >, ) { - const { view, openTo, rangePosition, sx, ...otherRendererProps } = rendererProps; + const { view, openTo, rangePosition, ...otherRendererProps } = rendererProps; const finalProps = { ...otherRendererProps, rangePosition, @@ -84,7 +90,6 @@ const rendererInterceptor = function rendererInterceptor< maxHeight: RANGE_VIEW_HEIGHT - 1, }, }, - ...(Array.isArray(sx) ? sx : [sx]), ], }; const isTimeView = isInternalTimeView(popperView); @@ -97,15 +102,16 @@ const rendererInterceptor = function rendererInterceptor< , DateTimeRangePickerView, any, {}> + viewRenderer as PickerViewRenderer, TimeViewWithMeridiem, any, {}> } view={view && isInternalTimeView(view) ? view : 'hours'} + views={finalProps.views.filter(isInternalTimeView)} openTo={isInternalTimeView(openTo) ? openTo : 'hours'} /> ); } // avoiding problem of `props: never` - const typedViewRenderer = viewRenderer as PickerViewRenderer, 'day', any, {}>; + const typedViewRenderer = viewRenderer as PickerViewRenderer, 'day', any, any>; return typedViewRenderer({ ...finalProps, @@ -141,12 +147,7 @@ const MobileDateTimeRangePicker = React.forwardRef(function MobileDateTimeRangeP ? renderDigitalClockTimeView : renderMultiSectionDigitalClockTimeView; - const viewRenderers: PickerViewRendererLookup< - DateRange, - DateTimeRangePickerView, - any, - {} - > = { + const viewRenderers: DateTimeRangePickerRenderers = { day: renderDateRangeViewCalendar, hours: renderTimeView, minutes: renderTimeView, diff --git a/packages/x-date-pickers/src/DatePicker/shared.tsx b/packages/x-date-pickers/src/DatePicker/shared.tsx index 6618e5b31c73..8bbbffc21c19 100644 --- a/packages/x-date-pickers/src/DatePicker/shared.tsx +++ b/packages/x-date-pickers/src/DatePicker/shared.tsx @@ -35,6 +35,17 @@ export interface BaseDatePickerSlotProps toolbar?: ExportedDatePickerToolbarProps; } +export type DatePickerViewRenderers< + TDate extends PickerValidDate, + TView extends DateView, + TAdditionalProps extends {} = {}, +> = PickerViewRendererLookup< + TDate | null, + TView, + DateViewRendererProps, + TAdditionalProps +>; + export interface BaseDatePickerProps extends BasePickerInputProps, ExportedDateCalendarProps { @@ -53,9 +64,7 @@ export interface BaseDatePickerProps * If `null`, the section will only have field editing. * If `undefined`, internally defined view will be the used. */ - viewRenderers?: Partial< - PickerViewRendererLookup, {}> - >; + viewRenderers?: Partial>; } type UseDatePickerDefaultizedProps< diff --git a/packages/x-date-pickers/src/DateTimePicker/shared.tsx b/packages/x-date-pickers/src/DateTimePicker/shared.tsx index feb1531a6787..0caf3dad3d42 100644 --- a/packages/x-date-pickers/src/DateTimePicker/shared.tsx +++ b/packages/x-date-pickers/src/DateTimePicker/shared.tsx @@ -62,6 +62,21 @@ export interface BaseDateTimePickerSlotProps toolbar?: ExportedDateTimePickerToolbarProps; } +export type DateTimePickerViewRenderers< + TDate extends PickerValidDate, + TView extends DateOrTimeViewWithMeridiem, + TAdditionalProps extends {} = {}, +> = PickerViewRendererLookup< + TDate | null, + TView, + Omit, 'slots' | 'slotProps'> & + Omit< + TimeViewRendererProps>, + 'slots' | 'slotProps' + >, + TAdditionalProps +>; + export interface BaseDateTimePickerProps< TDate extends PickerValidDate, TView extends DateOrTimeViewWithMeridiem, @@ -89,15 +104,7 @@ export interface BaseDateTimePickerProps< * If `null`, the section will only have field editing. * If `undefined`, internally defined view will be the used. */ - viewRenderers?: Partial< - PickerViewRendererLookup< - TDate | null, - TView, - DateViewRendererProps & - TimeViewRendererProps>, - {} - > - >; + viewRenderers?: Partial>; } type UseDateTimePickerDefaultizedProps< diff --git a/packages/x-date-pickers/src/DesktopDatePicker/DesktopDatePicker.tsx b/packages/x-date-pickers/src/DesktopDatePicker/DesktopDatePicker.tsx index 9f75443212d8..aaeb03f1eeba 100644 --- a/packages/x-date-pickers/src/DesktopDatePicker/DesktopDatePicker.tsx +++ b/packages/x-date-pickers/src/DesktopDatePicker/DesktopDatePicker.tsx @@ -4,7 +4,7 @@ import { resolveComponentProps } from '@mui/base/utils'; import { refType } from '@mui/utils'; import { singleItemValueManager } from '../internals/utils/valueManagers'; import { DesktopDatePickerProps } from './DesktopDatePicker.types'; -import { useDatePickerDefaultizedProps } from '../DatePicker/shared'; +import { DatePickerViewRenderers, useDatePickerDefaultizedProps } from '../DatePicker/shared'; import { useLocaleText, useUtils } from '../internals/hooks/useUtils'; import { validateDate } from '../internals/utils/validation/validateDate'; import { DateView, PickerValidDate } from '../models'; @@ -13,7 +13,6 @@ import { CalendarIcon } from '../icons'; import { DateField } from '../DateField'; import { extractValidationProps } from '../internals/utils/validation/extractValidationProps'; import { renderDateViewCalendar } from '../dateViewRenderers'; -import { PickerViewRendererLookup } from '../internals/hooks/usePicker/usePickerViews'; import { resolveDateFormat } from '../internals/utils/date-utils'; type DesktopDatePickerComponent = (< @@ -50,7 +49,7 @@ const DesktopDatePicker = React.forwardRef(function DesktopDatePicker< DesktopDatePickerProps >(inProps, 'MuiDesktopDatePicker'); - const viewRenderers: PickerViewRendererLookup = { + 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 785d032f92a3..7233ff2ad4be 100644 --- a/packages/x-date-pickers/src/DesktopDateTimePicker/DesktopDateTimePicker.tsx +++ b/packages/x-date-pickers/src/DesktopDateTimePicker/DesktopDateTimePicker.tsx @@ -2,25 +2,110 @@ import * as React from 'react'; import PropTypes from 'prop-types'; import { resolveComponentProps } from '@mui/base/utils'; import { refType } from '@mui/utils'; +import Divider from '@mui/material/Divider'; import { singleItemValueManager } from '../internals/utils/valueManagers'; import { DateTimeField } from '../DateTimeField'; import { DesktopDateTimePickerProps } from './DesktopDateTimePicker.types'; -import { useDateTimePickerDefaultizedProps } from '../DateTimePicker/shared'; +import { + useDateTimePickerDefaultizedProps, + DateTimePickerViewRenderers, +} from '../DateTimePicker/shared'; import { renderDateViewCalendar } from '../dateViewRenderers/dateViewRenderers'; -import { renderDesktopDateTimeView } from '../dateTimeViewRenderers'; import { useLocaleText, useUtils } from '../internals/hooks/useUtils'; import { validateDateTime } from '../internals/utils/validation/validateDateTime'; import { DateOrTimeViewWithMeridiem } from '../internals/models'; import { CalendarIcon } from '../icons'; -import { useDesktopPicker } from '../internals/hooks/useDesktopPicker'; +import { UseDesktopPickerProps, useDesktopPicker } from '../internals/hooks/useDesktopPicker'; import { extractValidationProps } from '../internals/utils/validation/extractValidationProps'; -import { PickerViewRendererLookup } from '../internals/hooks/usePicker/usePickerViews'; +import { PickerViewsRendererProps } from '../internals/hooks/usePicker'; import { resolveDateTimeFormat, resolveTimeViewsResponse, } from '../internals/utils/date-time-utils'; import { PickersActionBarAction } from '../PickersActionBar'; import { PickerValidDate } from '../models'; +import { + renderDigitalClockTimeView, + renderMultiSectionDigitalClockTimeView, +} from '../timeViewRenderers'; +import { + DefaultizedProps, + UsePickerViewsProps, + VIEW_HEIGHT, + isDatePickerView, + isInternalTimeView, +} from '../internals'; +import { + multiSectionDigitalClockClasses, + multiSectionDigitalClockSectionClasses, +} from '../MultiSectionDigitalClock'; +import { digitalClockClasses } from '../DigitalClock'; +import { DesktopDateTimePickerLayout } from './DesktopDateTimePickerLayout'; + +const rendererInterceptor = function rendererInterceptor< + TDate extends PickerValidDate, + TView extends DateOrTimeViewWithMeridiem, + TEnableAccessibleFieldDOMStructure extends boolean, +>( + inViewRenderers: DateTimePickerViewRenderers, + popperView: TView, + rendererProps: PickerViewsRendererProps< + TDate | null, + TView, + DefaultizedProps< + UseDesktopPickerProps< + TDate, + TView, + TEnableAccessibleFieldDOMStructure, + any, + UsePickerViewsProps + >, + 'openTo' + >, + {} + >, +) { + const { openTo, focusedView, timeViewsCount, ...otherProps } = rendererProps; + + const finalProps = { + ...otherProps, + focusedView: null, + sx: [ + { + [`&.${multiSectionDigitalClockClasses.root}`]: { + borderBottom: 0, + }, + [`&.${multiSectionDigitalClockClasses.root}, .${multiSectionDigitalClockSectionClasses.root}, &.${digitalClockClasses.root}`]: + { + maxHeight: VIEW_HEIGHT, + }, + }, + ], + }; + const isTimeViewActive = isInternalTimeView(popperView); + return ( + + {inViewRenderers[!isTimeViewActive ? popperView : 'day']?.({ + ...rendererProps, + view: !isTimeViewActive ? popperView : 'day', + focusedView: focusedView && isDatePickerView(focusedView) ? focusedView : null, + views: rendererProps.views.filter(isDatePickerView), + })} + {timeViewsCount > 0 && ( + + + {inViewRenderers[isTimeViewActive ? popperView : 'hours']?.({ + ...finalProps, + view: isTimeViewActive ? popperView : 'hours', + focusedView: focusedView && isInternalTimeView(focusedView) ? focusedView : null, + openTo: isInternalTimeView(openTo) ? openTo : 'hours', + views: rendererProps.views.filter(isInternalTimeView), + })} + + )} + + ); +}; type DesktopDateTimePickerComponent = (< TDate extends PickerValidDate, @@ -60,37 +145,34 @@ const DesktopDateTimePicker = React.forwardRef(function DesktopDateTimePicker< const { shouldRenderTimeInASingleColumn, thresholdToRenderTimeInASingleColumn, - views, + views: resolvedViews, timeSteps, } = resolveTimeViewsResponse(defaultizedProps); - const shouldUseNewRenderer = - !defaultizedProps.viewRenderers || Object.keys(defaultizedProps.viewRenderers).length === 0; - const viewRenderers: PickerViewRendererLookup = - // we can only ensure the expected two-column layout if none of the renderers are overridden - shouldUseNewRenderer - ? { - day: renderDesktopDateTimeView, - month: renderDesktopDateTimeView, - year: renderDesktopDateTimeView, - hours: renderDesktopDateTimeView, - minutes: renderDesktopDateTimeView, - seconds: renderDesktopDateTimeView, - meridiem: renderDesktopDateTimeView, - } - : { - day: renderDateViewCalendar, - month: renderDateViewCalendar, - year: renderDateViewCalendar, - hours: null, - minutes: null, - seconds: null, - meridiem: null, - ...defaultizedProps.viewRenderers, - }; + const renderTimeView = shouldRenderTimeInASingleColumn + ? renderDigitalClockTimeView + : renderMultiSectionDigitalClockTimeView; + + const viewRenderers: DateTimePickerViewRenderers = { + day: renderDateViewCalendar, + month: renderDateViewCalendar, + year: renderDateViewCalendar, + hours: renderTimeView, + minutes: renderTimeView, + seconds: renderTimeView, + meridiem: renderTimeView, + ...defaultizedProps.viewRenderers, + }; const ampmInClock = defaultizedProps.ampmInClock ?? true; - // add "accept" action only when the new date time view renderers are used - const actionBarActions: PickersActionBarAction[] = shouldUseNewRenderer ? ['accept'] : []; + // Need to avoid adding the `meridiem` view when unexpected renderer is specified + const shouldHoursRendererContainMeridiemView = + viewRenderers.hours?.name === renderMultiSectionDigitalClockTimeView.name; + const views = !shouldHoursRendererContainMeridiemView + ? resolvedViews.filter((view) => view !== 'meridiem') + : resolvedViews; + const actionBarActions: PickersActionBarAction[] = shouldRenderTimeInASingleColumn + ? [] + : ['accept']; // Props with the default values specific to the desktop variant const props = { @@ -105,6 +187,7 @@ const DesktopDateTimePicker = React.forwardRef(function DesktopDateTimePicker< shouldRenderTimeInASingleColumn, slots: { field: DateTimeField, + layout: DesktopDateTimePickerLayout, openPickerIcon: CalendarIcon, ...defaultizedProps.slots, }, @@ -118,17 +201,17 @@ const DesktopDateTimePicker = React.forwardRef(function DesktopDateTimePicker< toolbar: { hidden: true, ampmInClock, - toolbarVariant: shouldUseNewRenderer ? 'desktop' : 'mobile', + toolbarVariant: 'desktop', ...defaultizedProps.slotProps?.toolbar, }, tabs: { hidden: true, ...defaultizedProps.slotProps?.tabs, }, - actionBar: { + actionBar: (ownerState: any) => ({ actions: actionBarActions, - ...defaultizedProps.slotProps?.actionBar, - }, + ...resolveComponentProps(defaultizedProps.slotProps?.actionBar, ownerState), + }), }, }; @@ -144,6 +227,7 @@ const DesktopDateTimePicker = React.forwardRef(function DesktopDateTimePicker< getOpenDialogAriaText: props.localeText?.openDatePickerDialogue ?? localeText.openDatePickerDialogue, validator: validateDateTime, + rendererInterceptor, }); return renderPicker(); diff --git a/packages/x-date-pickers/src/DesktopDateTimePicker/DesktopDateTimePickerLayout.tsx b/packages/x-date-pickers/src/DesktopDateTimePicker/DesktopDateTimePickerLayout.tsx new file mode 100644 index 000000000000..f027e7d0afd6 --- /dev/null +++ b/packages/x-date-pickers/src/DesktopDateTimePicker/DesktopDateTimePickerLayout.tsx @@ -0,0 +1,110 @@ +import * as React from 'react'; +import PropTypes from 'prop-types'; +import clsx from 'clsx'; +import Divider from '@mui/material/Divider'; +import { + PickersLayoutContentWrapper, + PickersLayoutProps, + PickersLayoutRoot, + pickersLayoutClasses, + usePickerLayout, +} from '../PickersLayout'; +import { PickerValidDate } from '../models'; +import { DateOrTimeViewWithMeridiem } from '../internals'; + +/** + * @ignore - internal component. + */ +function DesktopDateTimePickerLayout< + TValue, + TDate extends PickerValidDate, + TView extends DateOrTimeViewWithMeridiem, +>(props: PickersLayoutProps) { + const { toolbar, tabs, content, actionBar, shortcuts } = usePickerLayout(props); + const { sx, className, isLandscape, ref } = props; + const isActionBarVisible = actionBar && (actionBar.props.actions?.length ?? 0) > 0; + + return ( + + {isLandscape ? shortcuts : toolbar} + {isLandscape ? toolbar : shortcuts} + + {content} + {tabs} + {isActionBarVisible && } + + {actionBar} + + ); +} + +DesktopDateTimePickerLayout.propTypes = { + // ----------------------------- Warning -------------------------------- + // | These PropTypes are generated from the TypeScript type definitions | + // | To update them edit the TypeScript types and run "yarn proptypes" | + // ---------------------------------------------------------------------- + children: PropTypes.node, + /** + * Override or extend the styles applied to the component. + */ + classes: PropTypes.object, + className: PropTypes.string, + disabled: PropTypes.bool, + isLandscape: PropTypes.bool.isRequired, + isValid: PropTypes.func.isRequired, + onAccept: PropTypes.func.isRequired, + onCancel: PropTypes.func.isRequired, + onChange: PropTypes.func.isRequired, + onClear: PropTypes.func.isRequired, + onClose: PropTypes.func.isRequired, + onDismiss: PropTypes.func.isRequired, + onOpen: PropTypes.func.isRequired, + onSelectShortcut: PropTypes.func.isRequired, + onSetToday: PropTypes.func.isRequired, + onViewChange: PropTypes.func.isRequired, + /** + * Force rendering in particular orientation. + */ + orientation: PropTypes.oneOf(['landscape', 'portrait']), + readOnly: PropTypes.bool, + /** + * The props used for each component slot. + * @default {} + */ + slotProps: PropTypes.object, + /** + * Overridable component slots. + * @default {} + */ + slots: PropTypes.object, + /** + * The system prop that allows defining system overrides as well as additional CSS styles. + */ + sx: PropTypes.oneOfType([ + PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), + PropTypes.func, + PropTypes.object, + ]), + value: PropTypes.any, + view: PropTypes.oneOf(['day', 'hours', 'meridiem', 'minutes', 'month', 'seconds', 'year']), + views: PropTypes.arrayOf( + PropTypes.oneOf(['day', 'hours', 'meridiem', 'minutes', 'month', 'seconds', 'year']).isRequired, + ).isRequired, + wrapperVariant: PropTypes.oneOf(['desktop', 'mobile']), +} as any; + +export { DesktopDateTimePickerLayout }; diff --git a/packages/x-date-pickers/src/DesktopDateTimePicker/index.ts b/packages/x-date-pickers/src/DesktopDateTimePicker/index.ts index 14c12f407e93..9e0b14855796 100644 --- a/packages/x-date-pickers/src/DesktopDateTimePicker/index.ts +++ b/packages/x-date-pickers/src/DesktopDateTimePicker/index.ts @@ -1,4 +1,5 @@ export { DesktopDateTimePicker } from './DesktopDateTimePicker'; +export { DesktopDateTimePickerLayout } from './DesktopDateTimePickerLayout'; export type { DesktopDateTimePickerProps, DesktopDateTimePickerSlots, diff --git a/packages/x-date-pickers/src/DesktopTimePicker/DesktopTimePicker.tsx b/packages/x-date-pickers/src/DesktopTimePicker/DesktopTimePicker.tsx index 74c3edefa738..23ff47e66157 100644 --- a/packages/x-date-pickers/src/DesktopTimePicker/DesktopTimePicker.tsx +++ b/packages/x-date-pickers/src/DesktopTimePicker/DesktopTimePicker.tsx @@ -5,13 +5,12 @@ import { refType } from '@mui/utils'; import { singleItemValueManager } from '../internals/utils/valueManagers'; import { TimeField } from '../TimeField'; import { DesktopTimePickerProps } from './DesktopTimePicker.types'; -import { useTimePickerDefaultizedProps } from '../TimePicker/shared'; +import { TimePickerViewRenderers, useTimePickerDefaultizedProps } from '../TimePicker/shared'; import { useLocaleText, useUtils } from '../internals/hooks/useUtils'; import { validateTime } from '../internals/utils/validation/validateTime'; import { ClockIcon } from '../icons'; import { useDesktopPicker } from '../internals/hooks/useDesktopPicker'; import { extractValidationProps } from '../internals/utils/validation/extractValidationProps'; -import { PickerViewRendererLookup } from '../internals/hooks/usePicker/usePickerViews'; import { renderDigitalClockTimeView, renderMultiSectionDigitalClockTimeView, @@ -67,7 +66,7 @@ const DesktopTimePicker = React.forwardRef(function DesktopTimePicker< ? renderDigitalClockTimeView : renderMultiSectionDigitalClockTimeView; - const viewRenderers: PickerViewRendererLookup = { + 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 24a8915df648..25a5fd739b7f 100644 --- a/packages/x-date-pickers/src/MobileDatePicker/MobileDatePicker.tsx +++ b/packages/x-date-pickers/src/MobileDatePicker/MobileDatePicker.tsx @@ -4,10 +4,9 @@ import { resolveComponentProps } from '@mui/base/utils'; import { refType } from '@mui/utils'; import { useMobilePicker } from '../internals/hooks/useMobilePicker'; import { MobileDatePickerProps } from './MobileDatePicker.types'; -import { useDatePickerDefaultizedProps } from '../DatePicker/shared'; +import { DatePickerViewRenderers, useDatePickerDefaultizedProps } from '../DatePicker/shared'; import { useUtils, useLocaleText } from '../internals/hooks/useUtils'; import { validateDate } from '../internals/utils/validation/validateDate'; -import { PickerViewRendererLookup } from '../internals/hooks/usePicker/usePickerViews'; import { DateView, PickerValidDate } from '../models'; import { DateField } from '../DateField'; import { extractValidationProps } from '../internals/utils/validation/extractValidationProps'; @@ -49,7 +48,7 @@ const MobileDatePicker = React.forwardRef(function MobileDatePicker< MobileDatePickerProps >(inProps, 'MuiMobileDatePicker'); - const viewRenderers: PickerViewRendererLookup = { + 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 4291fcc31893..3489751741c5 100644 --- a/packages/x-date-pickers/src/MobileDateTimePicker/MobileDateTimePicker.tsx +++ b/packages/x-date-pickers/src/MobileDateTimePicker/MobileDateTimePicker.tsx @@ -5,10 +5,12 @@ import { refType } from '@mui/utils'; import { singleItemValueManager } from '../internals/utils/valueManagers'; import { DateTimeField } from '../DateTimeField'; import { MobileDateTimePickerProps } from './MobileDateTimePicker.types'; -import { useDateTimePickerDefaultizedProps } from '../DateTimePicker/shared'; +import { + DateTimePickerViewRenderers, + useDateTimePickerDefaultizedProps, +} from '../DateTimePicker/shared'; import { useLocaleText, useUtils } from '../internals/hooks/useUtils'; import { validateDateTime } from '../internals/utils/validation/validateDateTime'; -import { PickerViewRendererLookup } from '../internals/hooks/usePicker/usePickerViews'; import { DateOrTimeView, PickerValidDate } from '../models'; import { useMobilePicker } from '../internals/hooks/useMobilePicker'; import { extractValidationProps } from '../internals/utils/validation/extractValidationProps'; @@ -51,7 +53,7 @@ const MobileDateTimePicker = React.forwardRef(function MobileDateTimePicker< MobileDateTimePickerProps >(inProps, 'MuiMobileDateTimePicker'); - const viewRenderers: PickerViewRendererLookup = { + const viewRenderers: DateTimePickerViewRenderers = { 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 7ade9bc78f68..3483b970f405 100644 --- a/packages/x-date-pickers/src/MobileTimePicker/MobileTimePicker.tsx +++ b/packages/x-date-pickers/src/MobileTimePicker/MobileTimePicker.tsx @@ -5,9 +5,8 @@ import { refType } from '@mui/utils'; import { singleItemValueManager } from '../internals/utils/valueManagers'; import { TimeField } from '../TimeField'; import { MobileTimePickerProps } from './MobileTimePicker.types'; -import { useTimePickerDefaultizedProps } from '../TimePicker/shared'; +import { TimePickerViewRenderers, useTimePickerDefaultizedProps } from '../TimePicker/shared'; import { useLocaleText, useUtils } from '../internals/hooks/useUtils'; -import { PickerViewRendererLookup } from '../internals/hooks/usePicker/usePickerViews'; import { validateTime } from '../internals/utils/validation/validateTime'; import { PickerValidDate, TimeView } from '../models'; import { useMobilePicker } from '../internals/hooks/useMobilePicker'; @@ -50,7 +49,7 @@ const MobileTimePicker = React.forwardRef(function MobileTimePicker< MobileTimePickerProps >(inProps, 'MuiMobileTimePicker'); - const viewRenderers: PickerViewRendererLookup = { + 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 b0e540e89879..cb5fb76cb9c3 100644 --- a/packages/x-date-pickers/src/StaticDatePicker/StaticDatePicker.tsx +++ b/packages/x-date-pickers/src/StaticDatePicker/StaticDatePicker.tsx @@ -1,13 +1,12 @@ import * as React from 'react'; import PropTypes from 'prop-types'; import { StaticDatePickerProps } from './StaticDatePicker.types'; -import { useDatePickerDefaultizedProps } from '../DatePicker/shared'; +import { DatePickerViewRenderers, useDatePickerDefaultizedProps } from '../DatePicker/shared'; import { renderDateViewCalendar } from '../dateViewRenderers'; import { useStaticPicker } from '../internals/hooks/useStaticPicker'; import { validateDate } from '../internals/utils/validation/validateDate'; import { DateView, PickerValidDate } from '../models'; import { singleItemValueManager } from '../internals/utils/valueManagers'; -import { PickerViewRendererLookup } from '../internals/hooks/usePicker/usePickerViews'; type StaticDatePickerComponent = (( props: StaticDatePickerProps & React.RefAttributes, @@ -34,7 +33,7 @@ const StaticDatePicker = React.forwardRef(function StaticDatePicker = { + 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 1262583a39fe..caa6285fbee9 100644 --- a/packages/x-date-pickers/src/StaticDateTimePicker/StaticDateTimePicker.tsx +++ b/packages/x-date-pickers/src/StaticDateTimePicker/StaticDateTimePicker.tsx @@ -1,14 +1,16 @@ import * as React from 'react'; import PropTypes from 'prop-types'; import { StaticDateTimePickerProps } from './StaticDateTimePicker.types'; -import { useDateTimePickerDefaultizedProps } from '../DateTimePicker/shared'; +import { + DateTimePickerViewRenderers, + 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, PickerValidDate } from '../models'; import { validateDateTime } from '../internals/utils/validation/validateDateTime'; -import { PickerViewRendererLookup } from '../internals/hooks/usePicker/usePickerViews'; type StaticDateTimePickerComponent = (( props: StaticDateTimePickerProps & React.RefAttributes, @@ -36,7 +38,7 @@ const StaticDateTimePicker = React.forwardRef(function StaticDateTimePicker< const displayStaticWrapperAs = defaultizedProps.displayStaticWrapperAs ?? 'mobile'; const ampmInClock = defaultizedProps.ampmInClock ?? displayStaticWrapperAs === 'desktop'; - const viewRenderers: PickerViewRendererLookup = { + const viewRenderers: DateTimePickerViewRenderers = { 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 aaf03d7301f1..a8084a3eba7b 100644 --- a/packages/x-date-pickers/src/StaticTimePicker/StaticTimePicker.tsx +++ b/packages/x-date-pickers/src/StaticTimePicker/StaticTimePicker.tsx @@ -2,12 +2,11 @@ import * as React from 'react'; import PropTypes from 'prop-types'; import { PickerValidDate, TimeView } from '../models'; import { StaticTimePickerProps } from './StaticTimePicker.types'; -import { useTimePickerDefaultizedProps } from '../TimePicker/shared'; +import { TimePickerViewRenderers, useTimePickerDefaultizedProps } from '../TimePicker/shared'; import { renderTimeViewClock } from '../timeViewRenderers'; import { singleItemValueManager } from '../internals/utils/valueManagers'; import { useStaticPicker } from '../internals/hooks/useStaticPicker'; import { validateTime } from '../internals/utils/validation/validateTime'; -import { PickerViewRendererLookup } from '../internals/hooks/usePicker/usePickerViews'; type StaticTimePickerComponent = (( props: StaticTimePickerProps & React.RefAttributes, @@ -36,7 +35,7 @@ const StaticTimePicker = React.forwardRef(function StaticTimePicker = { + 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 763948a3398a..5827164ec17f 100644 --- a/packages/x-date-pickers/src/TimePicker/shared.tsx +++ b/packages/x-date-pickers/src/TimePicker/shared.tsx @@ -30,6 +30,17 @@ export interface BaseTimePickerSlotProps extends TimeClockSlotProps { toolbar?: ExportedTimePickerToolbarProps; } +export type TimePickerViewRenderers< + TDate extends PickerValidDate, + TView extends TimeViewWithMeridiem, + TAdditionalProps extends {} = {}, +> = PickerViewRendererLookup< + TDate | null, + TView, + TimeViewRendererProps>, + TAdditionalProps +>; + export interface BaseTimePickerProps< TDate extends PickerValidDate, TView extends TimeViewWithMeridiem, @@ -55,14 +66,7 @@ export interface BaseTimePickerProps< * If `null`, the section will only have field editing. * If `undefined`, internally defined view will be the used. */ - viewRenderers?: Partial< - PickerViewRendererLookup< - TDate | null, - TView, - TimeViewRendererProps>, - {} - > - >; + viewRenderers?: Partial>; } type UseTimePickerDefaultizedProps< diff --git a/packages/x-date-pickers/src/dateTimeViewRenderers/dateTimeViewRenderers.tsx b/packages/x-date-pickers/src/dateTimeViewRenderers/dateTimeViewRenderers.tsx deleted file mode 100644 index 80ea74129e60..000000000000 --- a/packages/x-date-pickers/src/dateTimeViewRenderers/dateTimeViewRenderers.tsx +++ /dev/null @@ -1,199 +0,0 @@ -import * as React from 'react'; -import Divider from '@mui/material/Divider'; -import { resolveComponentProps } from '@mui/base/utils'; -import { DateCalendar, DateCalendarProps } from '../DateCalendar'; -import { DateOrTimeViewWithMeridiem } from '../internals/models'; -import { - MultiSectionDigitalClockProps, - multiSectionDigitalClockSectionClasses, -} from '../MultiSectionDigitalClock'; -import { DateTimeViewWrapper } from '../internals/components/DateTimeViewWrapper'; -import { isInternalTimeView } from '../internals/utils/time-utils'; -import { isDatePickerView } from '../internals/utils/date-utils'; -import type { DateTimePickerProps } from '../DateTimePicker/DateTimePicker.types'; -import { - renderDigitalClockTimeView, - renderMultiSectionDigitalClockTimeView, -} from '../timeViewRenderers'; -import { digitalClockClasses } from '../DigitalClock'; -import { VIEW_HEIGHT } from '../internals/constants/dimensions'; -import { PickerValidDate } from '../models'; - -export interface DateTimeViewRendererProps - extends Omit< - DateCalendarProps & MultiSectionDigitalClockProps, - 'views' | 'openTo' | 'view' | 'onViewChange' | 'focusedView' | 'slots' | 'slotProps' - >, - Pick, 'slots' | 'slotProps'> { - view: DateOrTimeViewWithMeridiem; - onViewChange?: (view: DateOrTimeViewWithMeridiem) => void; - views: readonly DateOrTimeViewWithMeridiem[]; - focusedView: DateOrTimeViewWithMeridiem | null; - timeViewsCount: number; - shouldRenderTimeInASingleColumn: boolean; -} - -export const renderDesktopDateTimeView = ({ - view, - onViewChange, - views, - focusedView, - onFocusedViewChange, - value, - defaultValue, - referenceDate, - onChange, - className, - classes, - disableFuture, - disablePast, - minDate, - minTime, - maxDate, - maxTime, - shouldDisableDate, - shouldDisableMonth, - shouldDisableYear, - shouldDisableTime, - reduceAnimations, - minutesStep, - ampm, - onMonthChange, - monthsPerRow, - onYearChange, - yearsPerRow, - slots, - slotProps, - loading, - renderLoading, - disableHighlightToday, - readOnly, - disabled, - showDaysOutsideCurrentMonth, - dayOfWeekFormatter, - sx, - autoFocus, - fixedWeekNumber, - displayWeekNumber, - timezone, - disableIgnoringDatePartForTimeValidation, - timeSteps, - skipDisabled, - timeViewsCount, - shouldRenderTimeInASingleColumn, -}: DateTimeViewRendererProps) => { - const isActionBarVisible = !!resolveComponentProps(slotProps?.actionBar, {} as any)?.actions - ?.length; - const commonTimeProps = { - view: isInternalTimeView(view) ? view : 'hours', - onViewChange, - focusedView: focusedView && isInternalTimeView(focusedView) ? focusedView : null, - onFocusedViewChange, - views: views.filter(isInternalTimeView), - value, - defaultValue, - referenceDate, - onChange, - className, - classes, - disableFuture, - disablePast, - minTime, - maxTime, - shouldDisableTime, - minutesStep, - ampm, - slots, - slotProps, - readOnly, - disabled, - autoFocus, - disableIgnoringDatePartForTimeValidation, - timeSteps, - skipDisabled, - timezone, - }; - return ( - - - - {timeViewsCount > 0 && ( - - - {shouldRenderTimeInASingleColumn - ? renderDigitalClockTimeView({ - ...commonTimeProps, - view: 'hours', - views: ['hours'], - focusedView: focusedView && isInternalTimeView(focusedView) ? 'hours' : null, - sx: [ - { - width: 'auto', - [`&.${digitalClockClasses.root}`]: { - maxHeight: VIEW_HEIGHT, - }, - }, - ...(Array.isArray(sx) ? sx : [sx]), - ], - }) - : renderMultiSectionDigitalClockTimeView({ - ...commonTimeProps, - view: isInternalTimeView(view) ? view : 'hours', - views: views.filter(isInternalTimeView), - focusedView: focusedView && isInternalTimeView(focusedView) ? focusedView : null, - sx: [ - { - borderBottom: 0, - width: 'auto', - [`.${multiSectionDigitalClockSectionClasses.root}`]: { - maxHeight: '100%', - }, - }, - ...(Array.isArray(sx) ? sx : [sx]), - ], - })} - - )} - - {isActionBarVisible && } - - ); -}; diff --git a/packages/x-date-pickers/src/dateTimeViewRenderers/index.ts b/packages/x-date-pickers/src/dateTimeViewRenderers/index.ts deleted file mode 100644 index d909595c47ae..000000000000 --- a/packages/x-date-pickers/src/dateTimeViewRenderers/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { renderDesktopDateTimeView } from './dateTimeViewRenderers'; -export type { DateTimeViewRendererProps } from './dateTimeViewRenderers'; diff --git a/packages/x-date-pickers/src/internals/hooks/useDesktopPicker/index.ts b/packages/x-date-pickers/src/internals/hooks/useDesktopPicker/index.ts index bd512bb5889c..900a371d65da 100644 --- a/packages/x-date-pickers/src/internals/hooks/useDesktopPicker/index.ts +++ b/packages/x-date-pickers/src/internals/hooks/useDesktopPicker/index.ts @@ -4,4 +4,5 @@ export type { UseDesktopPickerSlotProps, ExportedUseDesktopPickerSlotProps, DesktopOnlyPickerProps, + UseDesktopPickerProps, } from './useDesktopPicker.types'; 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 77890a2a5242..76ae02864952 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 @@ -116,7 +116,7 @@ export interface UseDesktopPickerProps< TView extends DateOrTimeViewWithMeridiem, TEnableAccessibleFieldDOMStructure extends boolean, TError, - TExternalProps extends UsePickerViewsProps, + TExternalProps extends UsePickerViewsProps, > extends BasePickerProps, DesktopOnlyPickerProps { /** @@ -144,7 +144,7 @@ export interface UseDesktopPickerParams< >, > extends Pick< UsePickerParams, - 'valueManager' | 'valueType' | 'validator' + 'valueManager' | 'valueType' | 'validator' | 'rendererInterceptor' > { props: TExternalProps; getOpenDialogAriaText: (date: TDate | null, utils: MuiPickersAdapter) => string; 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 35b2cea89287..3d7591dec661 100644 --- a/packages/x-date-pickers/src/internals/hooks/usePicker/index.ts +++ b/packages/x-date-pickers/src/internals/hooks/usePicker/index.ts @@ -11,3 +11,5 @@ export type { PickerSelectionState, UsePickerValueFieldResponse, } from './usePickerValue.types'; + +export type { PickerViewsRendererProps } from './usePickerViews'; diff --git a/packages/x-date-pickers/src/internals/hooks/usePicker/usePickerViews.ts b/packages/x-date-pickers/src/internals/hooks/usePicker/usePickerViews.ts index 3e82c54bb598..1b77420f2299 100644 --- a/packages/x-date-pickers/src/internals/hooks/usePicker/usePickerViews.ts +++ b/packages/x-date-pickers/src/internals/hooks/usePicker/usePickerViews.ts @@ -17,13 +17,15 @@ export type PickerViewsRendererProps< TView extends DateOrTimeViewWithMeridiem, TExternalProps extends PickerViewsRendererBaseExternalProps, TAdditionalProps extends {}, -> = TExternalProps & +> = Omit & TAdditionalProps & UsePickerValueViewsResponse & { view: TView; views: readonly TView[]; focusedView: TView | null; onFocusedViewChange: (viewToFocus: TView, hasFocus: boolean) => void; + showViewSwitcher: boolean; + timeViewsCount: number; }; export type PickerViewRenderer< @@ -133,9 +135,7 @@ export interface UsePickerViewParams< rendererInterceptor?: ( viewRenderers: PickerViewRendererLookup, popperView: TView, - rendererProps: Omit & - TAdditionalProps & - UsePickerValueViewsResponse, + rendererProps: PickerViewsRendererProps, ) => React.ReactNode; } @@ -303,7 +303,12 @@ export const usePickerViews = < return null; } - const rendererProps = { + const rendererProps: PickerViewsRendererProps< + TValue, + TView, + TExternalProps, + TAdditionalProps + > = { ...propsToForwardToView, ...additionalViewProps, ...propsFromPickerValue, diff --git a/packages/x-date-pickers/src/internals/index.ts b/packages/x-date-pickers/src/internals/index.ts index 116ab1c3aade..5eafbf5d1962 100644 --- a/packages/x-date-pickers/src/internals/index.ts +++ b/packages/x-date-pickers/src/internals/index.ts @@ -70,6 +70,7 @@ export type { UsePickerParams, UsePickerProps, UsePickerValueFieldResponse, + PickerViewsRendererProps, } from './hooks/usePicker'; export type { UsePickerValueNonStaticProps, diff --git a/scripts/x-date-pickers-pro.exports.json b/scripts/x-date-pickers-pro.exports.json index 69101c17aabd..689039bc8595 100644 --- a/scripts/x-date-pickers-pro.exports.json +++ b/scripts/x-date-pickers-pro.exports.json @@ -122,6 +122,7 @@ { "name": "DesktopDateRangePickerSlotProps", "kind": "Interface" }, { "name": "DesktopDateRangePickerSlots", "kind": "Interface" }, { "name": "DesktopDateTimePicker", "kind": "Variable" }, + { "name": "DesktopDateTimePickerLayout", "kind": "Function" }, { "name": "DesktopDateTimePickerProps", "kind": "Interface" }, { "name": "DesktopDateTimePickerSlotProps", "kind": "Interface" }, { "name": "DesktopDateTimePickerSlots", "kind": "Interface" }, diff --git a/scripts/x-date-pickers.exports.json b/scripts/x-date-pickers.exports.json index 689f731411c0..63ae47de5f99 100644 --- a/scripts/x-date-pickers.exports.json +++ b/scripts/x-date-pickers.exports.json @@ -77,6 +77,7 @@ { "name": "DesktopDatePickerSlotProps", "kind": "Interface" }, { "name": "DesktopDatePickerSlots", "kind": "Interface" }, { "name": "DesktopDateTimePicker", "kind": "Variable" }, + { "name": "DesktopDateTimePickerLayout", "kind": "Function" }, { "name": "DesktopDateTimePickerProps", "kind": "Interface" }, { "name": "DesktopDateTimePickerSlotProps", "kind": "Interface" }, { "name": "DesktopDateTimePickerSlots", "kind": "Interface" },