Skip to content

Commit

Permalink
[pickers] Remove the last props passed to the layout slot
Browse files Browse the repository at this point in the history
  • Loading branch information
flaviendelangle committed Dec 20, 2024
1 parent 38eabdb commit bfb0786
Show file tree
Hide file tree
Showing 42 changed files with 460 additions and 355 deletions.
8 changes: 3 additions & 5 deletions docs/data/date-pickers/shortcuts/ChangeImportance.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,8 @@ import Stack from '@mui/material/Stack';
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
import { DatePicker } from '@mui/x-date-pickers/DatePicker';
import {
PickersShortcutsItem,
PickerShortcutChangeImportance,
} from '@mui/x-date-pickers/PickersShortcuts';
import { PickersShortcutsItem } from '@mui/x-date-pickers/PickersShortcuts';
import { PickerChangeImportance } from '@mui/x-date-pickers/models';
import ToggleButtonGroup from '@mui/material/ToggleButtonGroup';
import ToggleButton from '@mui/material/ToggleButton';

Expand Down Expand Up @@ -80,7 +78,7 @@ const shortcutsItems: PickersShortcutsItem<Dayjs | null>[] = [

export default function ChangeImportance() {
const [changeImportance, setChangeImportance] =
React.useState<PickerShortcutChangeImportance>('accept');
React.useState<PickerChangeImportance>('accept');

return (
<LocalizationProvider dateAdapter={AdapterDayjs}>
Expand Down
8 changes: 6 additions & 2 deletions docs/data/date-pickers/shortcuts/CustomizedRangeShortcuts.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
import { StaticDateRangePicker } from '@mui/x-date-pickers-pro/StaticDateRangePicker';

import { useIsValidValue, usePickerContext } from '@mui/x-date-pickers/hooks';

const shortcutsItems = [
{
label: 'This Week',
Expand Down Expand Up @@ -51,7 +53,9 @@ const shortcutsItems = [
];

function CustomRangeShortcuts(props) {
const { items, onChange, isValid, changeImportance = 'accept' } = props;
const { items, changeImportance = 'accept' } = props;
const isValid = useIsValidValue();
const { setValue } = usePickerContext();

if (items == null || items.length === 0) {
return null;
Expand All @@ -63,7 +67,7 @@ function CustomRangeShortcuts(props) {
return {
label: item.label,
onClick: () => {
onChange(newValue, changeImportance, item);
setValue(newValue, { changeImportance, shortcut: item });
},
disabled: !isValid(newValue),
};
Expand Down
7 changes: 5 additions & 2 deletions docs/data/date-pickers/shortcuts/CustomizedRangeShortcuts.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
PickersShortcutsProps,
} from '@mui/x-date-pickers/PickersShortcuts';
import { DateRange } from '@mui/x-date-pickers-pro/models';
import { useIsValidValue, usePickerContext } from '@mui/x-date-pickers/hooks';

const shortcutsItems: PickersShortcutsItem<DateRange<Dayjs>>[] = [
{
Expand Down Expand Up @@ -56,7 +57,9 @@ const shortcutsItems: PickersShortcutsItem<DateRange<Dayjs>>[] = [
];

function CustomRangeShortcuts(props: PickersShortcutsProps<DateRange<Dayjs>>) {
const { items, onChange, isValid, changeImportance = 'accept' } = props;
const { items, changeImportance = 'accept' } = props;
const isValid = useIsValidValue<DateRange<Dayjs>>();
const { setValue } = usePickerContext<DateRange<Dayjs>>();

if (items == null || items.length === 0) {
return null;
Expand All @@ -68,7 +71,7 @@ function CustomRangeShortcuts(props: PickersShortcutsProps<DateRange<Dayjs>>) {
return {
label: item.label,
onClick: () => {
onChange(newValue, changeImportance, item);
setValue(newValue, { changeImportance, shortcut: item });
},
disabled: !isValid(newValue),
};
Expand Down
133 changes: 125 additions & 8 deletions docs/data/migration/migration-pickers-v7/migration-pickers-v7.md
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,19 @@ This change causes a few breaking changes:
);
```

- The component passed to the `layout` slot no longer receives the `value` prop, instead you can use the `usePickerContext` hook:

```diff
+import { usePickerContext } from '@mui/x-date-pickers/hooks';

// This contains a small behavior change.
// If the picker receives an invalid date,
// the old value would equal `null`.
// the new value would equal the invalid date received.
-const { value } = props;
+const { value } = usePickerContext();
```

- The component passed to the `layout` slot no longer receives the `disabled` and `readOnly` props, instead you can use the `usePickerContext` hook:

```diff
Expand All @@ -376,7 +389,7 @@ This change causes a few breaking changes:
+const { readOnly } = usePickerContext();
```

- The component passed to the `layout` slot no longer receives an `isRtl` prop. If you need to access this information, you can use the `useRtl` hook from `@mui/system`:
- The component passed to the `layout` slot no longer receives the `isRtl` prop. If you need to access this information, you can use the `useRtl` hook from `@mui/system`:

```diff
+import { useRtl } from '@mui/system/RtlProvider';
Expand All @@ -398,7 +411,7 @@ This change causes a few breaking changes:
+const isLandscape = orientation === 'landscape';
```

- The component passed to the `layout` slot no longer receives a `wrapperVariant` prop, instead you can use the `usePickerContext` hook:
- The component passed to the `layout` slot no longer receives the `wrapperVariant` prop, instead you can use the `usePickerContext` hook:

```diff
+import { usePickerContext } from '@mui/x-date-pickers/hooks';
Expand All @@ -422,7 +435,8 @@ This change causes a few breaking changes:
+const { onViewChange } = usePickerContext();
```

- The component passed to the `layout` slot no longer receives the `onClear`, `onSetToday`, `onAccept`, `onCancel`, `onOpen`, `onClose` and `onDismiss` props, instead you can use the `usePickerActionsContext` or the `usePickerContext` hooks:
- The component passed to the `layout` slot no longer receives the `onClear`, `onSetToday`, `onAccept`, `onCancel`, `onOpen`, `onClose` `onDismiss`, `onChange` and `onSelectShortcut` props.
You can use the `usePickerActionsContext` or the `usePickerContext` hooks instead:

```diff
+import { usePickerActionsContext } from '@mui/x-date-pickers/hooks';
Expand All @@ -446,7 +460,7 @@ This change causes a few breaking changes:
+ setOpen(true);
+}

-props.onClose();
-const { onClose } = props;
+const { setOpen } = usePickerActionsContext();
+const onClose = event => {
+ event.preventDefault();
Expand All @@ -460,6 +474,18 @@ This change causes a few breaking changes:
-const { onDismiss } = props;
+const { acceptValueChanges } = usePickerActionsContext();
+const onDismiss = acceptValueChanges

-const { onChange } = props;
-onChange(dayjs(), 'partial');
-onChange(dayjs(), 'finish');
+const { setValue } = usePickerActionsContext();
+setValue(dayjs(), { changeImportance: 'set' });
+setValue(dayjs(), { changeImportance: 'accept' });

-const { onSelectShortcut } = props;
-onSelectShortcut(dayjs(), 'accept', myShortcut);
+const { setValue } = usePickerActionsContext();
+setValue(dayjs(), { changeImportance: 'accept', shortcut: myShortcut });
```

:::success
Expand All @@ -469,6 +495,19 @@ This change causes a few breaking changes:

### Slot: `toolbar`

- The component passed to the `toolbar` slot no longer receives the `value` prop, instead you can use the `usePickerContext` hook:

```diff
+import { usePickerContext } from '@mui/x-date-pickers/hooks';

// This contains a small behavior change.
// If the picker receives an invalid date,
// the old value would equal `null`.
// the new value would equal the invalid date received.
-const { value } = props;
+const { value } = usePickerContext();
```

- The component passed to the `toolbar` slot no longer receives the `disabled` and `readOnly` props, instead you can use the `usePickerContext` hook:

```diff
Expand All @@ -481,7 +520,17 @@ This change causes a few breaking changes:
+const { readOnly } = usePickerContext();
```

- The component passed to the `toolbar` slot no longer receives a `view`, `views` and `onViewChange` props, instead you can use the `usePickerContext` hook:
- The component passed to the `layout` slot no longer receives the `isLandscape` prop, instead you can use the `usePickerContext` hook:

```diff
+import { usePickerContext } from '@mui/x-date-pickers/hooks';

-const { isLandscape } = props;
+const { orientation } = usePickerContext();
+const isLandscape = orientation === 'landscape';
```

- The component passed to the `toolbar` slot no longer receives the `view`, `views` and `onViewChange` props, instead you can use the `usePickerContext` hook:

```diff
+import { usePickerContext } from '@mui/x-date-pickers/hooks';
Expand All @@ -496,9 +545,28 @@ This change causes a few breaking changes:
+const { onViewChange } = usePickerContext();
```

- The component passed to the `toolbar` slot no longer receives the `onChange` prop.
You can use the `usePickerActionsContext` or the `usePickerContext` hooks instead:

```diff
+import { usePickerActionsContext } from '@mui/x-date-pickers/hooks';

-const { onChange } = props;
-onChange(dayjs(), 'partial');
-onChange(dayjs(), 'finish');
+const { setValue } = usePickerActionsContext();
+setValue(dayjs(), { changeImportance: 'set' });
+setValue(dayjs(), { changeImportance: 'accept' });
```

:::success
The `usePickerContext` also contain all the actions returned by `usePickerActionsContext`.
The only difference is that `usePickerActionsContext` only contains variables with stable references that won't cause a re-render of your component.
:::

### Slot: `tabs`

- The component passed to the `tabs` slot no longer receives a `view`, `views` and `onViewChange` props, instead you can use the `usePickerContext` hook:
- The component passed to the `tabs` slot no longer receives the `view`, `views` and `onViewChange` props, instead you can use the `usePickerContext` hook:

```diff
+import { usePickerContext } from '@mui/x-date-pickers/hooks';
Expand All @@ -515,7 +583,8 @@ This change causes a few breaking changes:

### Slot: `actionBar`

- The component passed to the `actionBar` slot no longer receives the `onClear`, `onSetToday`, `onAccept` and `onCancel` props. You can use the `usePickerActionsContext` or the `usePickerContext` hooks instead:
- The component passed to the `actionBar` slot no longer receives the `onClear`, `onSetToday`, `onAccept` and `onCancel` props.
You can use the `usePickerActionsContext` or the `usePickerContext` hooks instead:

```diff
+import { usePickerActionsContext } from '@mui/x-date-pickers/hooks';
Expand All @@ -538,6 +607,44 @@ 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.
:::

### Slot: `shortcuts`

- The component passed to the `shortcuts` slot no longer receives the `isLandscape` prop, instead you can use the `usePickerContext` hook:

```diff
+import { usePickerContext } from '@mui/x-date-pickers/hooks';

-const { isLandscape } = props;
+const { orientation } = usePickerContext();
+const isLandscape = orientation === 'landscape';
```

- The component passed to the `shortcuts` slot no longer receives the `onChange` prop.
You can use the `usePickerActionsContext` or the `usePickerContext` hooks instead:

```diff
-const { onChange } = props;
-onChange(dayjs(), 'accept', myShortcut);
+const { setValue } = usePickerActionsContext();
+setValue(dayjs(), { changeImportance: 'accept', shortcut: myShortcut });
```

:::success
The `usePickerContext` also contain all the actions returned by `usePickerActionsContext`.
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 `shortcuts` slot no longer receives the `isValid` prop, instead you can use the `useIsValidValue` hook:

```diff
+import { useIsValidValue } from '@mui/x-date-pickers/hooks';

-const { isValid } = props;
-const isTodayValid = isValid(dayjs());
+const isValidValue = useIsValidValue();
+const isTodayValid = isValidValue(dayjs());
```

## Renamed variables and types

The following variables and types have been renamed to have a coherent `Picker` / `Pickers` prefix:
Expand Down Expand Up @@ -584,7 +691,7 @@ The following variables and types have been renamed to have a coherent `Picker`
+import { PickerValueType } from '@mui/x-date-pickers-pro';
```

- `RangeFieldSection`
- `RangeFieldSection`

```diff
-import { RangeFieldSection } from '@mui/x-date-pickers-pro/models';
Expand All @@ -594,6 +701,16 @@ The following variables and types have been renamed to have a coherent `Picker`
+import { FieldRangeSection } from '@mui/x-date-pickers-pro';
```

- `PickerShortcutChangeImportance`

```diff
-import { PickerShortcutChangeImportance } from '@mui/x-date-pickers/PickersShortcuts';
-import { PickerShortcutChangeImportance } from '@mui/x-date-pickers';

+import { PickerChangeImportance } from '@mui/x-date-pickers/models';
+import { PickerChangeImportance } from '@mui/x-date-pickers';
```

## Hooks breaking changes

### `usePickerContext`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ import {
PickerToolbarOwnerState,
useToolbarOwnerState,
} from '@mui/x-date-pickers/internals';
import { usePickerTranslations } from '@mui/x-date-pickers/hooks';
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,
Expand All @@ -33,7 +34,7 @@ const useUtilityClasses = (classes: Partial<DateRangePickerToolbarClasses> | und

export interface DateRangePickerToolbarProps
extends ExportedDateRangePickerToolbarProps,
Omit<BaseToolbarProps<PickerRangeValue>, 'onChange' | 'isLandscape'>,
Omit<BaseToolbarProps, 'onChange' | 'isLandscape'>,
Pick<UseRangePositionResponse, 'rangePosition' | 'onRangePositionChange'> {}

export interface ExportedDateRangePickerToolbarProps extends ExportedBaseToolbarProps {
Expand Down Expand Up @@ -81,47 +82,49 @@ const DateRangePickerToolbar = React.forwardRef(function DateRangePickerToolbar(
const props = useThemeProps({ props: inProps, name: 'MuiDateRangePickerToolbar' });

const {
value: [start, end],
rangePosition,
onRangePositionChange,
toolbarFormat,
toolbarFormat: toolbarFormatProp,
className,
classes: classesProp,
...other
} = props;

const { value } = usePickerContext<PickerRangeValue>();
const translations = usePickerTranslations();
const ownerState = useToolbarOwnerState();
const classes = useUtilityClasses(classesProp);

const startDateValue = start
? utils.formatByString(start, toolbarFormat || utils.formats.shortDate)
: translations.start;
// This can't be a default value when spreading because it breaks the API generation.
const toolbarFormat = toolbarFormatProp ?? utils.formats.shortDate;

const endDateValue = end
? utils.formatByString(end, toolbarFormat || utils.formats.shortDate)
: translations.end;
const formatDate = (date: PickerValidDate | null, fallback: string) => {
if (date == null || !utils.isValid(date)) {
return fallback;
}

return utils.formatByString(date, toolbarFormat);
};

return (
<DateRangePickerToolbarRoot
{...other}
toolbarTitle={translations.dateRangePickerToolbarTitle}
isLandscape={false}
className={clsx(classes.root, className)}
ownerState={ownerState}
ref={ref}
>
<DateRangePickerToolbarContainer className={classes.container}>
<PickersToolbarButton
variant={start !== null ? 'h5' : 'h6'}
value={startDateValue}
variant={value[0] == null ? 'h6' : 'h5'}
value={formatDate(value[0], translations.start)}
selected={rangePosition === 'start'}
onClick={() => onRangePositionChange('start')}
/>
<Typography variant="h5">&nbsp;{'–'}&nbsp;</Typography>
<PickersToolbarButton
variant={end !== null ? 'h5' : 'h6'}
value={endDateValue}
variant={value[1] == null ? 'h6' : 'h5'}
value={formatDate(value[1], translations.end)}
selected={rangePosition === 'end'}
onClick={() => onRangePositionChange('end')}
/>
Expand Down Expand Up @@ -165,7 +168,6 @@ DateRangePickerToolbar.propTypes = {
* @default "––"
*/
toolbarPlaceholder: PropTypes.node,
value: PropTypes.arrayOf(PropTypes.object).isRequired,
} as any;

export { DateRangePickerToolbar };
Loading

0 comments on commit bfb0786

Please sign in to comment.