Skip to content

Commit

Permalink
[pickers] Add explicit interfaces for components slots and components…
Browse files Browse the repository at this point in the history
… slots props (#4589)
  • Loading branch information
flaviendelangle authored Apr 26, 2022
1 parent dc71bd7 commit ebb0e3b
Show file tree
Hide file tree
Showing 15 changed files with 189 additions and 116 deletions.
4 changes: 2 additions & 2 deletions docs/pages/x/api/date-pickers/static-date-range-picker.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@
"leftArrowButtonText": { "type": { "name": "string" } },
"loading": { "type": { "name": "bool" } },
"mask": { "type": { "name": "string" }, "default": "'__/__/____'" },
"maxDate": { "type": { "name": "any" } },
"minDate": { "type": { "name": "any" } },
"maxDate": { "type": { "name": "any" }, "default": "defaultMaxDate" },
"minDate": { "type": { "name": "any" }, "default": "defaultMinDate" },
"onAccept": { "type": { "name": "func" } },
"onClose": { "type": { "name": "func" } },
"onError": { "type": { "name": "func" } },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,11 @@ import {
import { isRangeValid } from '../internal/utils/date-utils';
import { calculateRangeChange } from './date-range-manager';
import { DateRangePickerToolbar } from './DateRangePickerToolbar';
import { DateRangePickerViewMobile } from './DateRangePickerViewMobile';
import {
DateRangePickerViewMobile,
DateRangePickerViewMobileSlotsComponent,
DateRangePickerViewMobileSlotsComponentsProps,
} from './DateRangePickerViewMobile';
import { DateRangePickerInput, DateRangeInputProps } from './DateRangePickerInput';
import {
DateRangePickerViewDesktop,
Expand All @@ -30,10 +34,27 @@ import { getReleaseInfo } from '../internal/utils/releaseInfo';

const releaseInfo = getReleaseInfo();

export interface DateRangePickerViewSlotsComponent
extends DateRangePickerViewMobileSlotsComponent {}

export interface DateRangePickerViewSlotsComponentsProps
extends DateRangePickerViewMobileSlotsComponentsProps {}

export interface ExportedDateRangePickerViewProps<TDate>
extends ExportedDesktopDateRangeCalendarProps<TDate>,
Omit<ExportedCalendarPickerProps<TDate>, 'onYearChange' | 'renderDay'>,
Omit<BasePickerProps<RangeInput<TDate>, DateRange<TDate>>, 'value' | 'onChange'> {
/**
* The components used for each slot.
* Either a string to use an HTML element or a component.
* @default {}
*/
components?: Partial<DateRangePickerViewSlotsComponent>;
/**
* The props used for each slot inside.
* @default {}
*/
componentsProps?: Partial<DateRangePickerViewSlotsComponentsProps>;
/**
* If `true`, after selecting `start` date calendar will not automatically switch to the month of `end` date.
* @default false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,21 @@ import {
ExportedDateValidationProps,
DayPicker,
PickersCalendarProps,
PickersCalendarHeaderSlotsComponent,
PickersCalendarHeaderSlotsComponentsProps,
} from '@mui/x-date-pickers/internals';
import { doNothing } from '../internal/utils/utils';
import { DateRange } from '../internal/models/dateRange';
import { DateRangePickerDay } from '../DateRangePickerDay';
import { ExportedDesktopDateRangeCalendarProps } from './DateRangePickerViewDesktop';
import { isWithinRange, isStartOfRange, isEndOfRange } from '../internal/utils/date-utils';

export interface DateRangePickerViewMobileSlotsComponent
extends PickersCalendarHeaderSlotsComponent {}

export interface DateRangePickerViewMobileSlotsComponentsProps
extends PickersCalendarHeaderSlotsComponentsProps {}

export interface ExportedMobileDateRangeCalendarProps<TDate>
extends Pick<ExportedDesktopDateRangeCalendarProps<TDate>, 'renderDay'> {}

Expand All @@ -22,6 +30,17 @@ interface DesktopDateRangeCalendarProps<TDate>
Omit<PickersCalendarProps<TDate>, 'date' | 'renderDay' | 'onFocusedDayChange'>,
ExportedDateValidationProps<TDate>,
ExportedCalendarHeaderProps<TDate> {
/**
* The components used for each slot.
* Either a string to use an HTML element or a component.
* @default {}
*/
components?: Partial<DateRangePickerViewMobileSlotsComponent>;
/**
* The props used for each slot inside.
* @default {}
*/
componentsProps?: Partial<DateRangePickerViewMobileSlotsComponentsProps>;
date: DateRange<TDate>;
changeMonth: (date: TDate) => void;
}
Expand Down
19 changes: 15 additions & 4 deletions packages/x-date-pickers-pro/src/DateRangePicker/shared.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,23 @@
import * as React from 'react';
import { useDefaultDates, useUtils, ValidationProps } from '@mui/x-date-pickers/internals';
import {
DateInputSlotsComponent,
useDefaultDates,
useUtils,
ValidationProps,
} from '@mui/x-date-pickers/internals';
import { useThemeProps } from '@mui/material/styles';
import { ExportedDateRangePickerViewProps } from './DateRangePickerView';
import {
DateRangePickerViewSlotsComponent,
ExportedDateRangePickerViewProps,
} from './DateRangePickerView';
import { DateRangeValidationError } from '../internal/hooks/validation/useDateRangeValidation';
import { DateRange, RangeInput } from '../internal/models';
import { ExportedDateRangePickerInputProps } from './DateRangePickerInput';

interface DateRangePickerSlotsComponent
extends DateRangePickerViewSlotsComponent,
DateInputSlotsComponent {}

export interface BaseDateRangePickerProps<TDate>
extends ExportedDateRangePickerViewProps<TDate>,
ValidationProps<DateRangeValidationError, RangeInput<TDate>>,
Expand All @@ -15,8 +27,7 @@ export interface BaseDateRangePickerProps<TDate>
* Either a string to use an HTML element or a component.
* @default {}
*/
components?: ExportedDateRangePickerViewProps<TDate>['components'] &
ExportedDateRangePickerInputProps['components'];
components?: Partial<DateRangePickerSlotsComponent>;
/**
* Text for end input label and toolbar placeholder.
* @default 'End'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,72 +7,18 @@ import {
PickerStaticWrapperProps,
useDefaultDates,
useUtils,
ValidationProps,
usePickerState,
PickerStateValueManager,
} from '@mui/x-date-pickers/internals';
import { RangeInput, DateRange } from '../internal/models/dateRange';
import {
DateRangeValidationError,
useDateRangeValidation,
} from '../internal/hooks/validation/useDateRangeValidation';
import {
DateRangePickerView,
ExportedDateRangePickerViewProps,
} from '../DateRangePicker/DateRangePickerView';
import { ExportedDateRangePickerInputProps } from '../DateRangePicker/DateRangePickerInput';
import { useDateRangeValidation } from '../internal/hooks/validation/useDateRangeValidation';
import { DateRangePickerView } from '../DateRangePicker/DateRangePickerView';
import { parseRangeInputValue } from '../internal/utils/date-utils';
import { getReleaseInfo } from '../internal/utils/releaseInfo';
import { BaseDateRangePickerProps } from '../DateRangePicker/shared';

const releaseInfo = getReleaseInfo();

interface BaseDateRangePickerProps<TDate>
extends ExportedDateRangePickerViewProps<TDate>,
ValidationProps<DateRangeValidationError, RangeInput<TDate>>,
ExportedDateRangePickerInputProps {
/**
* The components used for each slot.
* Either a string to use an HTML element or a component.
* @default {}
*/
components?: ExportedDateRangePickerViewProps<TDate>['components'] &
ExportedDateRangePickerInputProps['components'];
/**
* Text for end input label and toolbar placeholder.
* @default 'End'
*/
endText?: React.ReactNode;
/**
* Custom mask. Can be used to override generate from format. (e.g. `__/__/____ __:__` or `__/__/____ __:__ _M`).
* @default '__/__/____'
*/
mask?: ExportedDateRangePickerInputProps['mask'];
/**
* Min selectable date. @DateIOType
*/
minDate?: TDate;
/**
* Max selectable date. @DateIOType
*/
maxDate?: TDate;
/**
* Callback fired when the value (the selected date range) changes @DateIOType.
* @template TDate
* @param {DateRange<TDate>} date The new parsed date range.
* @param {string} keyboardInputValue The current value of the keyboard input.
*/
onChange: (date: DateRange<TDate>, keyboardInputValue?: string) => void;
/**
* Text for start input label and toolbar placeholder.
* @default 'Start'
*/
startText?: React.ReactNode;
/**
* The value of the date range picker.
*/
value: RangeInput<TDate>;
}

const rangePickerValueManager: PickerStateValueManager<any, any> = {
emptyValue: [null, null],
parseInput: parseRangeInputValue,
Expand Down Expand Up @@ -320,10 +266,12 @@ StaticDateRangePicker.propTypes = {
mask: PropTypes.string,
/**
* Max selectable date. @DateIOType
* @default defaultMaxDate
*/
maxDate: PropTypes.any,
/**
* Min selectable date. @DateIOType
* @default defaultMinDate
*/
minDate: PropTypes.any,
/**
Expand Down
23 changes: 22 additions & 1 deletion packages/x-date-pickers/src/CalendarPicker/CalendarPicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,41 @@ import { useDefaultDates, useUtils } from '../internals/hooks/useUtils';
import { PickersFadeTransitionGroup } from './PickersFadeTransitionGroup';
import { DayPicker, ExportedCalendarProps } from './DayPicker';
import { PickerOnChangeFn, useViews } from '../internals/hooks/useViews';
import { PickersCalendarHeader, ExportedCalendarHeaderProps } from './PickersCalendarHeader';
import {
PickersCalendarHeader,
ExportedCalendarHeaderProps,
PickersCalendarHeaderSlotsComponent,
PickersCalendarHeaderSlotsComponentsProps,
} from './PickersCalendarHeader';
import { YearPicker, ExportedYearPickerProps } from '../YearPicker/YearPicker';
import { findClosestEnabledDate } from '../internals/utils/date-utils';
import { CalendarPickerView } from '../internals/models';
import { PickerViewRoot } from '../internals/components/PickerViewRoot';
import { defaultReduceAnimations } from '../internals/utils/defaultReduceAnimations';
import { CalendarPickerClasses, getCalendarPickerUtilityClass } from './calendarPickerClasses';

export interface CalendarPickerSlotsComponent extends PickersCalendarHeaderSlotsComponent {}

export interface CalendarPickerSlotsComponentsProps
extends PickersCalendarHeaderSlotsComponentsProps {}

export interface CalendarPickerProps<TDate>
extends ExportedCalendarProps<TDate>,
ExportedYearPickerProps<TDate>,
ExportedCalendarHeaderProps<TDate> {
className?: string;
classes?: Partial<CalendarPickerClasses>;
/**
* The components used for each slot.
* Either a string to use an HTML element or a component.
* @default {}
*/
components?: Partial<CalendarPickerSlotsComponent>;
/**
* The props used for each slot inside.
* @default {}
*/
componentsProps?: Partial<CalendarPickerSlotsComponentsProps>;
date: TDate | null;
/**
* Default calendar month displayed when `value={null}`.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import { ArrowDropDown } from '../internals/components/icons';
import {
PickersArrowSwitcher,
ExportedArrowSwitcherProps,
PickersArrowSwitcherSlotsComponent,
PickersArrowSwitcherSlotsComponentsProps,
} from '../internals/components/PickersArrowSwitcher';
import {
usePreviousMonthDisabled,
Expand All @@ -19,15 +21,23 @@ import { CalendarPickerView } from '../internals/models';

export type ExportedCalendarHeaderProps<TDate> = Pick<
PickersCalendarHeaderProps<TDate>,
| 'components'
| 'componentsProps'
| 'getViewSwitchingButtonText'
| 'leftArrowButtonText'
| 'rightArrowButtonText'
'getViewSwitchingButtonText' | 'leftArrowButtonText' | 'rightArrowButtonText'
>;

export interface PickersCalendarHeaderSlotsComponent extends PickersArrowSwitcherSlotsComponent {
SwitchViewButton: React.ElementType;
SwitchViewIcon: React.ElementType;
}

// We keep the interface to allow module augmentation
export interface PickersCalendarHeaderComponentsPropsOverrides {}

export interface PickersCalendarHeaderSlotsComponentsProps
extends PickersArrowSwitcherSlotsComponentsProps {
switchViewButton: React.ComponentPropsWithRef<typeof IconButton> &
PickersCalendarHeaderComponentsPropsOverrides;
}

export interface PickersCalendarHeaderProps<TDate>
extends ExportedArrowSwitcherProps,
Omit<ExportedDateValidationProps<TDate>, 'shouldDisableDate'> {
Expand All @@ -36,18 +46,12 @@ export interface PickersCalendarHeaderProps<TDate>
* Either a string to use an HTML element or a component.
* @default {}
*/
components?: ExportedArrowSwitcherProps['components'] & {
SwitchViewButton?: React.ElementType;
SwitchViewIcon?: React.ElementType;
};
components?: Partial<PickersCalendarHeaderSlotsComponent>;
/**
* The props used for each slot inside.
* @default {}
*/
componentsProps?: ExportedArrowSwitcherProps['componentsProps'] & {
switchViewButton?: React.ComponentPropsWithRef<typeof IconButton> &
PickersCalendarHeaderComponentsPropsOverrides;
};
componentsProps?: Partial<PickersCalendarHeaderSlotsComponentsProps>;
currentMonth: TDate;
disabled?: boolean;
views: readonly CalendarPickerView[];
Expand Down
31 changes: 17 additions & 14 deletions packages/x-date-pickers/src/ClockPicker/ClockPicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ import { ClockPickerView, MuiPickersAdapter } from '../internals/models';
import { getClockPickerUtilityClass, ClockPickerClasses } from './clockPickerClasses';
import { PickerViewRoot } from '../internals/components/PickerViewRoot';

export interface ClockPickerComponentsPropsOverrides {}

const useUtilityClasses = (ownerState: ClockPickerProps<any>) => {
const { classes } = ownerState;
const slots = {
Expand Down Expand Up @@ -69,6 +67,21 @@ export interface ExportedClockPickerProps<TDate> extends ExportedTimeValidationP
) => string;
}

export interface ClockPickerSlotsComponent {
LeftArrowButton: React.ElementType;
LeftArrowIcon: React.ElementType;
RightArrowButton: React.ElementType;
RightArrowIcon: React.ElementType;
}

// We keep the interface to allow module augmentation
export interface ClockPickerComponentsPropsOverrides {}

export interface ClockPickerSlotsComponentsProps {
leftArrowButton: React.SVGAttributes<SVGSVGElement> & ClockPickerComponentsPropsOverrides;
rightArrowButton: React.SVGAttributes<SVGSVGElement> & ClockPickerComponentsPropsOverrides;
}

export interface ClockPickerProps<TDate> extends ExportedClockPickerProps<TDate> {
className?: string;
/**
Expand All @@ -83,21 +96,11 @@ export interface ClockPickerProps<TDate> extends ExportedClockPickerProps<TDate>
* The components used for each slot.
* Either a string to use an HTML element or a component.
*/
components?: {
LeftArrowButton?: React.ElementType;
LeftArrowIcon?: React.ElementType;
RightArrowButton?: React.ElementType;
RightArrowIcon?: React.ElementType;
};

components?: Partial<ClockPickerSlotsComponent>;
/**
* The props used for each slot inside.
*/
componentsProps?: {
leftArrowButton?: React.SVGAttributes<SVGSVGElement> & ClockPickerComponentsPropsOverrides;
rightArrowButton?: React.SVGAttributes<SVGSVGElement> & ClockPickerComponentsPropsOverrides;
};

componentsProps?: Partial<ClockPickerSlotsComponentsProps>;
/**
* Selected date @DateIOType.
*/
Expand Down
Loading

0 comments on commit ebb0e3b

Please sign in to comment.