Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[pickers] Use usePickerContext() and usePickerActionsContext() instead of passing props to the shortcuts and toolbar slots #15948

Merged
merged 3 commits into from
Dec 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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:
flaviendelangle marked this conversation as resolved.
Show resolved Hide resolved

```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 equals `null`.
// the new value equals 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:
flaviendelangle marked this conversation as resolved.
Show resolved Hide resolved

```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 @@ -462,6 +476,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 @@ -471,6 +497,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.
michelengelen marked this conversation as resolved.
Show resolved Hide resolved
flaviendelangle marked this conversation as resolved.
Show resolved Hide resolved
-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 @@ -483,7 +522,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 `toolbar` 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 @@ -498,9 +547,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 @@ -517,7 +585,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 @@ -540,6 +609,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:
flaviendelangle marked this conversation as resolved.
Show resolved Hide resolved

```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:
flaviendelangle marked this conversation as resolved.
Show resolved Hide resolved

```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 @@ -586,7 +693,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 @@ -596,6 +703,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 @@ -292,8 +292,8 @@ const DateRangeCalendar = React.forwardRef(function DateRangeCalendar(
// This makes sure that `isWithinRange` works with any time in the start and end day.
const valueDayRange = React.useMemo<PickerRangeValue>(
() => [
value[0] == null || !utils.isValid(value[0]) ? value[0] : utils.startOfDay(value[0]),
value[1] == null || !utils.isValid(value[1]) ? value[1] : utils.endOfDay(value[1]),
!utils.isValid(value[0]) ? value[0] : utils.startOfDay(value[0]),
!utils.isValid(value[1]) ? value[1] : utils.endOfDay(value[1]),
],
[value, utils],
);
Expand Down Expand Up @@ -386,7 +386,7 @@ const DateRangeCalendar = React.forwardRef(function DateRangeCalendar(
const prevValue = React.useRef<PickerRangeValue | null>(null);
React.useEffect(() => {
const date = rangePosition === 'start' ? value[0] : value[1];
if (!date || !utils.isValid(date)) {
if (!utils.isValid(date)) {
return;
}

Expand Down
Loading
Loading