Skip to content

Commit 9a8aa05

Browse files
[pickers] Use usePickerContext() and usePickerActionsContext() to get the actions in the actionBar slot and in internal components (#15843)
Signed-off-by: Flavien DELANGLE <[email protected]> Co-authored-by: Michel Engelen <[email protected]>
1 parent 878a538 commit 9a8aa05

32 files changed

+377
-311
lines changed

docs/data/date-pickers/custom-components/ActionBarComponent.js

+11-6
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,16 @@ import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
99
import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
1010
import { StaticDatePicker } from '@mui/x-date-pickers/StaticDatePicker';
1111

12-
import { usePickerTranslations } from '@mui/x-date-pickers/hooks';
12+
import {
13+
usePickerActionsContext,
14+
usePickerTranslations,
15+
} from '@mui/x-date-pickers/hooks';
1316

1417
function CustomActionBar(props) {
15-
const { onAccept, onClear, onCancel, onSetToday, actions, className } = props;
18+
const { actions, className } = props;
1619
const translations = usePickerTranslations();
20+
const { clearValue, setValueToToday, acceptValueChanges, cancelValueChanges } =
21+
usePickerActionsContext();
1722
const [anchorEl, setAnchorEl] = React.useState(null);
1823
const open = Boolean(anchorEl);
1924
const id = useId();
@@ -28,7 +33,7 @@ function CustomActionBar(props) {
2833
return (
2934
<MenuItem
3035
onClick={() => {
31-
onClear();
36+
clearValue();
3237
setAnchorEl(null);
3338
}}
3439
key={actionType}
@@ -42,7 +47,7 @@ function CustomActionBar(props) {
4247
<MenuItem
4348
onClick={() => {
4449
setAnchorEl(null);
45-
onCancel();
50+
cancelValueChanges();
4651
}}
4752
key={actionType}
4853
>
@@ -55,7 +60,7 @@ function CustomActionBar(props) {
5560
<MenuItem
5661
onClick={() => {
5762
setAnchorEl(null);
58-
onAccept();
63+
acceptValueChanges();
5964
}}
6065
key={actionType}
6166
>
@@ -68,7 +73,7 @@ function CustomActionBar(props) {
6873
<MenuItem
6974
onClick={() => {
7075
setAnchorEl(null);
71-
onSetToday();
76+
setValueToToday();
7277
}}
7378
key={actionType}
7479
>

docs/data/date-pickers/custom-components/ActionBarComponent.tsx

+11-6
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,16 @@ import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
99
import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
1010
import { StaticDatePicker } from '@mui/x-date-pickers/StaticDatePicker';
1111
import { PickersActionBarProps } from '@mui/x-date-pickers/PickersActionBar';
12-
import { usePickerTranslations } from '@mui/x-date-pickers/hooks';
12+
import {
13+
usePickerActionsContext,
14+
usePickerTranslations,
15+
} from '@mui/x-date-pickers/hooks';
1316

1417
function CustomActionBar(props: PickersActionBarProps) {
15-
const { onAccept, onClear, onCancel, onSetToday, actions, className } = props;
18+
const { actions, className } = props;
1619
const translations = usePickerTranslations();
20+
const { clearValue, setValueToToday, acceptValueChanges, cancelValueChanges } =
21+
usePickerActionsContext();
1722
const [anchorEl, setAnchorEl] = React.useState<HTMLButtonElement | null>(null);
1823
const open = Boolean(anchorEl);
1924
const id = useId();
@@ -28,7 +33,7 @@ function CustomActionBar(props: PickersActionBarProps) {
2833
return (
2934
<MenuItem
3035
onClick={() => {
31-
onClear();
36+
clearValue();
3237
setAnchorEl(null);
3338
}}
3439
key={actionType}
@@ -41,7 +46,7 @@ function CustomActionBar(props: PickersActionBarProps) {
4146
<MenuItem
4247
onClick={() => {
4348
setAnchorEl(null);
44-
onCancel();
49+
cancelValueChanges();
4550
}}
4651
key={actionType}
4752
>
@@ -53,7 +58,7 @@ function CustomActionBar(props: PickersActionBarProps) {
5358
<MenuItem
5459
onClick={() => {
5560
setAnchorEl(null);
56-
onAccept();
61+
acceptValueChanges();
5762
}}
5863
key={actionType}
5964
>
@@ -65,7 +70,7 @@ function CustomActionBar(props: PickersActionBarProps) {
6570
<MenuItem
6671
onClick={() => {
6772
setAnchorEl(null);
68-
onSetToday();
73+
setValueToToday();
6974
}}
7075
key={actionType}
7176
>

docs/data/date-pickers/custom-layout/AddComponent.js

+11-7
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import ListItemText from '@mui/material/ListItemText';
88
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
99
import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
1010
import { StaticDatePicker } from '@mui/x-date-pickers/StaticDatePicker';
11-
1211
import RestaurantIcon from '@mui/icons-material/Restaurant';
1312
import {
1413
usePickerLayout,
@@ -17,17 +16,22 @@ import {
1716
PickersLayoutContentWrapper,
1817
} from '@mui/x-date-pickers/PickersLayout';
1918

19+
import { usePickerActionsContext } from '@mui/x-date-pickers/hooks';
20+
2021
function ActionList(props) {
21-
const { onAccept, onClear, onCancel, onSetToday } = props;
22+
const { className } = props;
23+
const { clearValue, setValueToToday, acceptValueChanges, cancelValueChanges } =
24+
usePickerActionsContext();
25+
2226
const actions = [
23-
{ text: 'Accept', method: onAccept },
24-
{ text: 'Clear', method: onClear },
25-
{ text: 'Cancel', method: onCancel },
26-
{ text: 'Today', method: onSetToday },
27+
{ text: 'Accept', method: acceptValueChanges },
28+
{ text: 'Clear', method: clearValue },
29+
{ text: 'Cancel', method: cancelValueChanges },
30+
{ text: 'Today', method: setValueToToday },
2731
];
2832

2933
return (
30-
<List>
34+
<List className={className}>
3135
{actions.map(({ text, method }) => (
3236
<ListItem key={text} disablePadding>
3337
<ListItemButton onClick={method}>

docs/data/date-pickers/custom-layout/AddComponent.tsx

+12-7
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import ListItemText from '@mui/material/ListItemText';
88
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
99
import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
1010
import { StaticDatePicker } from '@mui/x-date-pickers/StaticDatePicker';
11-
import { PickersActionBarProps } from '@mui/x-date-pickers/PickersActionBar';
1211
import RestaurantIcon from '@mui/icons-material/Restaurant';
1312
import {
1413
PickersLayoutProps,
@@ -18,17 +17,23 @@ import {
1817
PickersLayoutContentWrapper,
1918
} from '@mui/x-date-pickers/PickersLayout';
2019
import { DateView } from '@mui/x-date-pickers/models';
20+
import { PickersActionBarProps } from '@mui/x-date-pickers/PickersActionBar';
21+
import { usePickerActionsContext } from '@mui/x-date-pickers/hooks';
2122

2223
function ActionList(props: PickersActionBarProps) {
23-
const { onAccept, onClear, onCancel, onSetToday } = props;
24+
const { className } = props;
25+
const { clearValue, setValueToToday, acceptValueChanges, cancelValueChanges } =
26+
usePickerActionsContext();
27+
2428
const actions = [
25-
{ text: 'Accept', method: onAccept },
26-
{ text: 'Clear', method: onClear },
27-
{ text: 'Cancel', method: onCancel },
28-
{ text: 'Today', method: onSetToday },
29+
{ text: 'Accept', method: acceptValueChanges },
30+
{ text: 'Clear', method: clearValue },
31+
{ text: 'Cancel', method: cancelValueChanges },
32+
{ text: 'Today', method: setValueToToday },
2933
];
34+
3035
return (
31-
<List>
36+
<List className={className}>
3237
{actions.map(({ text, method }) => (
3338
<ListItem key={text} disablePadding>
3439
<ListItemButton onClick={method}>

docs/data/date-pickers/custom-layout/MovingActions.js

+10-5
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,18 @@ import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
88
import { pickersLayoutClasses } from '@mui/x-date-pickers/PickersLayout';
99
import { StaticDatePicker } from '@mui/x-date-pickers/StaticDatePicker';
1010

11+
import { usePickerActionsContext } from '@mui/x-date-pickers/hooks';
12+
1113
function ActionList(props) {
12-
const { onAccept, onClear, onCancel, onSetToday, className } = props;
14+
const { className } = props;
15+
const { clearValue, setValueToToday, acceptValueChanges, cancelValueChanges } =
16+
usePickerActionsContext();
17+
1318
const actions = [
14-
{ text: 'Accept', method: onAccept },
15-
{ text: 'Clear', method: onClear },
16-
{ text: 'Cancel', method: onCancel },
17-
{ text: 'Today', method: onSetToday },
19+
{ text: 'Accept', method: acceptValueChanges },
20+
{ text: 'Clear', method: clearValue },
21+
{ text: 'Cancel', method: cancelValueChanges },
22+
{ text: 'Today', method: setValueToToday },
1823
];
1924

2025
return (

docs/data/date-pickers/custom-layout/MovingActions.tsx

+10-5
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,20 @@ import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
88
import { pickersLayoutClasses } from '@mui/x-date-pickers/PickersLayout';
99
import { StaticDatePicker } from '@mui/x-date-pickers/StaticDatePicker';
1010
import { PickersActionBarProps } from '@mui/x-date-pickers/PickersActionBar';
11+
import { usePickerActionsContext } from '@mui/x-date-pickers/hooks';
1112

1213
function ActionList(props: PickersActionBarProps) {
13-
const { onAccept, onClear, onCancel, onSetToday, className } = props;
14+
const { className } = props;
15+
const { clearValue, setValueToToday, acceptValueChanges, cancelValueChanges } =
16+
usePickerActionsContext();
17+
1418
const actions = [
15-
{ text: 'Accept', method: onAccept },
16-
{ text: 'Clear', method: onClear },
17-
{ text: 'Cancel', method: onCancel },
18-
{ text: 'Today', method: onSetToday },
19+
{ text: 'Accept', method: acceptValueChanges },
20+
{ text: 'Clear', method: clearValue },
21+
{ text: 'Cancel', method: cancelValueChanges },
22+
{ text: 'Today', method: setValueToToday },
1923
];
24+
2025
return (
2126
// Propagate the className such that CSS selectors can be applied
2227
<List className={className}>

docs/data/migration/migration-pickers-v7/migration-pickers-v7.md

+71-1
Original file line numberDiff line numberDiff line change
@@ -393,7 +393,7 @@ This change causes a few breaking changes:
393393
}
394394
```
395395

396-
- The component passed to the `layout` slot no longer receives an `orientation` and the `isLandscape` props, instead you can use the `usePickerContext` hook:
396+
- The component passed to the `layout` slot no longer receives the `orientation` and `isLandscape` props, instead you can use the `usePickerContext` hook:
397397

398398
```diff
399399
-console.log(props.orientation);
@@ -415,6 +415,51 @@ This change causes a few breaking changes:
415415
+console.log(variant);
416416
```
417417

418+
- 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:
419+
420+
```diff
421+
+import { usePickerActionsContext } from '@mui/x-date-pickers/hooks';
422+
423+
-const { onClear } = props;
424+
+const { clearValue } = usePickerActionsContext();
425+
426+
-const { onSetToday } = props;
427+
+const { setValueToToday } = usePickerActionsContext();
428+
429+
-const { onAccept } = props;
430+
+const { acceptValueChanges } = usePickerActionsContext();
431+
432+
-const { onCancel } = props;
433+
+const { cancelValueChanges } = usePickerActionsContext();
434+
435+
-const { onOpen } = props;
436+
+const { setOpen } = usePickerActionsContext();
437+
+const onOpen = event => {
438+
+ event.preventDefault();
439+
+ setOpen(true);
440+
+}
441+
442+
-props.onClose();
443+
+const { setOpen } = usePickerActionsContext();
444+
+const onClose = event => {
445+
+ event.preventDefault();
446+
+ setOpen(false);
447+
+}
448+
449+
// This contains a small behavior change.
450+
// If the picker is not controlled and has a default value,
451+
// opening it and calling `acceptValueChanges` without any change will call `onAccept` with the default value.
452+
// Whereas before, opening it and calling `onDimiss` without any change would not have called `onAccept`.
453+
-const { onDismiss } = props;
454+
+const { acceptValueChanges } = usePickerActionsContext();
455+
+const onDismiss = acceptValueChanges
456+
```
457+
458+
:::success
459+
The `usePickerContext` also contain all the actions returned by `usePickerActionsContext`.
460+
The only difference is that `usePickerActionsContext` only contains variables with stable references that won't cause a re-render of your component.
461+
:::
462+
418463
### Slot: `toolbar`
419464

420465
- The component passed to the `toolbar` slot no longer receives a `disabled` prop, instead you can use the `usePickerContext` hook:
@@ -435,6 +480,31 @@ This change causes a few breaking changes:
435480
+console.log(readOnly);
436481
```
437482

483+
### Slot: `actionBar`
484+
485+
- 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:
486+
487+
```diff
488+
+import { usePickerActionsContext } from '@mui/x-date-pickers/hooks';
489+
490+
-const { onClear } = props;
491+
+const { clearValue } = usePickerActionsContext();
492+
493+
-const { onSetToday } = props;
494+
+const { setValueToToday } = usePickerActionsContext();
495+
496+
-const { onAccept } = props;
497+
+const { acceptValueChanges } = usePickerActionsContext();
498+
499+
-const { onCancel } = props;
500+
+const { cancelValueChanges } = usePickerActionsContext();
501+
```
502+
503+
:::success
504+
The `usePickerContext` also contain all the actions returned by `usePickerActionsContext`.
505+
The only difference is that `usePickerActionsContext` only contains variables with stable references that won't cause a re-render of your component.
506+
:::
507+
438508
## Renamed variables and types
439509

440510
The following variables and types have been renamed to have a coherent `Picker` / `Pickers` prefix:

packages/x-date-pickers-pro/src/internals/hooks/useDesktopRangePicker/useDesktopRangePicker.tsx

+5-7
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,6 @@ export const useDesktopRangePicker = <
9090
}
9191

9292
const {
93-
open,
94-
actions,
9593
layoutProps,
9694
providerProps,
9795
renderCurrentView,
@@ -127,7 +125,8 @@ export const useDesktopRangePicker = <
127125
return;
128126
}
129127

130-
actions.onDismiss();
128+
// This direct access to `providerProps` will go away once the range fields stop having their views in a tooltip.
129+
providerProps.privateContextValue.dismissViews();
131130
});
132131
};
133132

@@ -170,8 +169,9 @@ export const useDesktopRangePicker = <
170169
>({
171170
variant: 'desktop',
172171
fieldType,
173-
open,
174-
actions,
172+
// These direct access to `providerProps` will go away once the range fields handle the picker opening
173+
open: providerProps.contextValue.open,
174+
setOpen: providerProps.contextValue.setOpen,
175175
readOnly,
176176
disableOpenPicker,
177177
label,
@@ -215,8 +215,6 @@ export const useDesktopRangePicker = <
215215
containerRef={popperRef}
216216
anchorEl={anchorRef.current}
217217
onBlur={handleBlur}
218-
{...actions}
219-
open={open}
220218
slots={slots}
221219
slotProps={slotProps}
222220
shouldRestoreFocus={shouldRestoreFocus}

0 commit comments

Comments
 (0)