Skip to content

Commit

Permalink
[pickers] Use renderer interceptor on DateTimePicker (#12441)
Browse files Browse the repository at this point in the history
  • Loading branch information
LukasTy committed Mar 20, 2024
1 parent 2ec11b7 commit abe28f6
Show file tree
Hide file tree
Showing 29 changed files with 394 additions and 402 deletions.
10 changes: 10 additions & 0 deletions docs/data/migration/migration-pickers-v6/migration-pickers-v6.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,20 @@ 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';
import { calculateRangeChange } from '../internals/utils/date-range-manager';

export type DateTimeRangePickerTimeWrapperProps<
TDate extends PickerValidDate,
TView extends DateTimeRangePickerView,
TComponentProps extends Omit<
BaseClockProps<TDate, TimeViewWithMeridiem>,
'value' | 'defaultValue' | 'onChange'
TView extends TimeViewWithMeridiem,
TComponentProps extends DefaultizedProps<
Omit<BaseClockProps<TDate, TView>, 'value' | 'defaultValue' | 'onChange'>,
'views'
>,
> = Pick<UseRangePositionResponse, 'rangePosition' | 'onRangePositionChange'> &
Omit<
Expand All @@ -36,7 +36,7 @@ export type DateTimeRangePickerTimeWrapperProps<
selectionState: PickerSelectionState,
selectedView: TView,
) => void;
viewRenderer?: PickerViewRenderer<DateRange<TDate>, TView, any, TComponentProps> | null;
viewRenderer?: PickerViewRenderer<DateRange<TDate>, TView, TComponentProps, any> | null;
openTo?: TView;
};

Expand All @@ -45,10 +45,10 @@ export type DateTimeRangePickerTimeWrapperProps<
*/
function DateTimeRangePickerTimeWrapper<
TDate extends PickerValidDate,
TView extends DateTimeRangePickerView,
TComponentProps extends Omit<
BaseClockProps<TDate, TimeViewWithMeridiem>,
'value' | 'defaultValue' | 'onChange'
TView extends TimeViewWithMeridiem,
TComponentProps extends DefaultizedProps<
Omit<BaseClockProps<TDate, TView>, 'value' | 'defaultValue' | 'onChange'>,
'views'
>,
>(
props: DateTimeRangePickerTimeWrapperProps<TDate, TView, TComponentProps>,
Expand Down
29 changes: 17 additions & 12 deletions packages/x-date-pickers-pro/src/DateTimeRangePicker/shared.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -73,6 +74,21 @@ export interface BaseDateTimeRangePickerSlotProps<TDate extends PickerValidDate>
toolbar?: ExportedDateTimeRangePickerToolbarProps;
}

export type DateTimeRangePickerRenderers<
TDate extends PickerValidDate,
TView extends DateOrTimeViewWithMeridiem,
TAdditionalProps extends {} = {},
> = PickerViewRendererLookup<
DateRange<TDate>,
TView,
Omit<DateRangeViewRendererProps<TDate, 'day'>, 'view' | 'slots' | 'slotProps'> &
Omit<
TimeViewRendererProps<TimeViewWithMeridiem, BaseClockProps<TDate, TimeViewWithMeridiem>>,
'view' | 'slots' | 'slotProps'
> & { view: TView },
TAdditionalProps
>;

export interface BaseDateTimeRangePickerProps<TDate extends PickerValidDate>
extends Omit<
BasePickerInputProps<
Expand Down Expand Up @@ -105,18 +121,7 @@ export interface BaseDateTimeRangePickerProps<TDate extends PickerValidDate>
* If `null`, the section will only have field editing.
* If `undefined`, internally defined view will be the used.
*/
viewRenderers?: Partial<
PickerViewRendererLookup<
DateRange<TDate>,
DateTimeRangePickerView,
Omit<DateRangeViewRendererProps<TDate, 'day'>, 'view' | 'slots' | 'slotProps'> &
Omit<
TimeViewRendererProps<TimeViewWithMeridiem, BaseClockProps<TDate, TimeViewWithMeridiem>>,
'view' | 'slots' | 'slotProps'
> & { view: DateTimeRangePickerView },
{}
>
>;
viewRenderers?: Partial<DateTimeRangePickerRenderers<TDate, DateTimeRangePickerView>>;
}

type UseDateTimeRangePickerDefaultizedProps<
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -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';
Expand All @@ -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<DateRange<TDate>, DateTimeRangePickerView, any, any>,
inViewRenderers: DateTimeRangePickerRenderers<TDate, DateTimeRangePickerView, any>,
popperView: DateTimeRangePickerView,
rendererProps: DefaultizedProps<
Omit<
UseDesktopRangePickerProps<
TDate,
DateTimeRangePickerView,
TEnableAccessibleFieldDOMStructure,
any,
any
rendererProps: PickerViewsRendererProps<
DateRange<TDate>,
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);
Expand All @@ -88,6 +96,7 @@ const rendererInterceptor = function rendererInterceptor<
<DateTimeRangePickerTimeWrapper
{...finalProps}
view={isTimeViewActive ? popperView : 'hours'}
views={finalProps.views.filter(isInternalTimeView)}
openTo={isInternalTimeView(openTo) ? openTo : 'hours'}
viewRenderer={
inViewRenderers[isTimeViewActive ? popperView : 'hours'] as PickerViewRenderer<
Expand Down Expand Up @@ -127,12 +136,7 @@ const DesktopDateTimeRangePicker = React.forwardRef(function DesktopDateTimeRang
? renderDigitalClockTimeView
: renderMultiSectionDigitalClockTimeView;

const viewRenderers: PickerViewRendererLookup<
DateRange<TDate>,
DateTimeRangePickerView,
any,
{}
> = {
const viewRenderers: DateTimeRangePickerRenderers<TDate, DateTimeRangePickerView, any> = {
day: renderDateRangeViewCalendar,
hours: renderTimeView,
minutes: renderTimeView,
Expand All @@ -159,7 +163,7 @@ const DesktopDateTimeRangePicker = React.forwardRef(function DesktopDateTimeRang
calendars: defaultizedProps.calendars ?? 1,
slots: {
field: MultiInputDateTimeRangeField,
layout: DesktopDateTimeRangePickerLayout,
layout: DesktopDateTimePickerLayout,
...defaultizedProps.slots,
},
slotProps: {
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -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';
Expand All @@ -41,23 +45,25 @@ const rendererInterceptor = function rendererInterceptor<
TDate extends PickerValidDate,
TEnableAccessibleFieldDOMStructure extends boolean,
>(
inViewRenderers: PickerViewRendererLookup<DateRange<TDate>, DateTimeRangePickerView, any, any>,
inViewRenderers: DateTimeRangePickerRenderers<TDate, DateTimeRangePickerView, any>,
popperView: DateTimeRangePickerView,
rendererProps: DefaultizedProps<
Omit<
rendererProps: PickerViewsRendererProps<
DateRange<TDate>,
DateTimeRangePickerView,
DefaultizedProps<
UseMobileRangePickerProps<
TDate,
DateTimeRangePickerView,
TEnableAccessibleFieldDOMStructure,
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,
Expand All @@ -84,7 +90,6 @@ const rendererInterceptor = function rendererInterceptor<
maxHeight: RANGE_VIEW_HEIGHT - 1,
},
},
...(Array.isArray(sx) ? sx : [sx]),
],
};
const isTimeView = isInternalTimeView(popperView);
Expand All @@ -97,15 +102,16 @@ const rendererInterceptor = function rendererInterceptor<
<DateTimeRangePickerTimeWrapper
{...finalProps}
viewRenderer={
viewRenderer as PickerViewRenderer<DateRange<TDate>, DateTimeRangePickerView, any, {}>
viewRenderer as PickerViewRenderer<DateRange<TDate>, 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<DateRange<TDate>, 'day', any, {}>;
const typedViewRenderer = viewRenderer as PickerViewRenderer<DateRange<TDate>, 'day', any, any>;

return typedViewRenderer({
...finalProps,
Expand Down Expand Up @@ -141,12 +147,7 @@ const MobileDateTimeRangePicker = React.forwardRef(function MobileDateTimeRangeP
? renderDigitalClockTimeView
: renderMultiSectionDigitalClockTimeView;

const viewRenderers: PickerViewRendererLookup<
DateRange<TDate>,
DateTimeRangePickerView,
any,
{}
> = {
const viewRenderers: DateTimeRangePickerRenderers<TDate, DateTimeRangePickerView, any> = {
day: renderDateRangeViewCalendar,
hours: renderTimeView,
minutes: renderTimeView,
Expand Down

0 comments on commit abe28f6

Please sign in to comment.