Skip to content

Commit b850e86

Browse files
flaviendelanglenoraleonteLukasTy
authored
[docs] Add migration guide for the picker's ownerState changes (#17151)
Signed-off-by: Flavien DELANGLE <[email protected]> Co-authored-by: Nora <[email protected]> Co-authored-by: Lukas Tyla <[email protected]>
1 parent 794b3bc commit b850e86

File tree

1 file changed

+66
-13
lines changed

1 file changed

+66
-13
lines changed

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

Lines changed: 66 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ the field consumes some props (for example `shouldRespectLeadingZeros`) and forw
142142

143143
- For the props consumed by the field, the behavior should remain exactly the same with both DOM structures.
144144

145-
Both components below will respect the leading zeroes on digit sections:
145+
Both components below respect the leading zeroes on digit sections:
146146

147147
```js
148148
<DatePicker
@@ -157,7 +157,7 @@ the field consumes some props (for example `shouldRespectLeadingZeros`) and forw
157157
- For the props forwarded to the `TextField`,
158158
you can have a look at the next section to see how the migration impact them.
159159

160-
Both components below will render a small size UI:
160+
Both components below render a small size UI:
161161

162162
```js
163163
<DatePicker
@@ -172,9 +172,9 @@ the field consumes some props (for example `shouldRespectLeadingZeros`) and forw
172172
#### Migrate `slotProps.textField`
173173

174174
If you are passing props to `slotProps.textField`,
175-
these props will now be received by `PickersTextField` and should keep working the same way as before.
175+
the `PickersTextField` component now receives these props and should keep working the same as before.
176176

177-
Both components below will render a small size UI:
177+
Both components below render a small size UI:
178178

179179
```js
180180
<DatePicker
@@ -188,13 +188,13 @@ Both components below will render a small size UI:
188188

189189
:::info
190190
If you are passing `inputProps` to `slotProps.textField`,
191-
these props will now be passed to the hidden `<input />` element.
191+
these props are now passed to the hidden `<input />` element.
192192
:::
193193

194194
#### Migrate `slots.field`
195195

196196
If you are passing a custom field component to your pickers, you need to create a new one that is using the accessible DOM structure.
197-
This new component will need to use the `PickersSectionList` component instead of an `<input />` HTML element.
197+
This new component needs to use the `PickersSectionList` component instead of an `<input />` HTML element.
198198

199199
You can have a look at the [Using a custom input](/x/react-date-pickers/custom-field/#using-a-custom-input) section to have a concrete example.
200200

@@ -309,6 +309,59 @@ const theme = createTheme({
309309
});
310310
```
311311

312+
### Clean the `ownerState`
313+
314+
The `ownerState` is an object describing the current state of a given component to let you do more advanced customization.
315+
It is used in two different APIs:
316+
317+
1. In the theme's `styleOverrides`, the `ownerState` is passed to the function that returns the style:
318+
319+
```ts
320+
const theme = createTheme({
321+
components: {
322+
MuiDateCalendar: {
323+
styleOverrides: {
324+
root: ({ ownerState }) => ({
325+
/** Style based on the ownerState */
326+
}),
327+
},
328+
},
329+
},
330+
});
331+
```
332+
333+
2. In the `slotProps`, the `ownerState` is passed to the function that returns the custom props:
334+
335+
```tsx
336+
<DatePicker
337+
slotProps={{
338+
actionBar: (ownerState) => ({
339+
/** Props based on the ownerState */
340+
}),
341+
}}
342+
/>
343+
```
344+
345+
Before version `v8.x`, the `ownerState` contained every prop of the component, plus some additional internal states if needed.
346+
This presented a few problems:
347+
348+
- It was hard to know which ancestor defines the `ownerState` and therefore which props it contains (is the `actionBar` slot handled by `DatePicker`, by `DesktopDatePicker` or by `PickerLayout`?).
349+
350+
- Many properties of the `ownerState` were not intended for public use, which complicated the evolution of the codebase. All the props received by an internal component became part of the public API, and consequently, any changes to them would have resulted in a breaking change.
351+
352+
- Some properties that would have been useful for customizing a component were not present if the component was not using them by default. For example, if the built-in styles for the `actionBar` didn't need to know if the picker is disabled, then the `ownerState` of the `actionBar` didn't contain this information.
353+
354+
- The naming of the props made it difficult to understand which element they applied to. If the `ownerState` of the `monthButton` slot contained `disabled`, it was hard to establish whether the disabled state applied to the `monthButton` or the Picker itself.
355+
356+
To solve these issues, the `ownerState` has been reworked.
357+
Every component's `ownerState` contains a shared set of properties describing the state of the picker it is in (`isPickerValueEmpty`, `isPickerOpen`, `isPickerDisabled`, `isPickerReadOnly`, `pickerVariant` and `pickerOrientation`).
358+
Some component's `ownerState` contain additional properties describing their own state (`isMonthDisabled` for the month button, `toolbarOrientation` for the toolbar, `isDaySelected` for the day button, etc.).
359+
360+
:::success
361+
Most of the properties needed to properly customize your component should be present in the `ownerState`.
362+
If you need some property that is currently not included, please [open an issue](https://github.com/mui/mui-x/issues/new/choose) in the MUI X repository.
363+
:::
364+
312365
### ⏩ Field editing on mobile Pickers
313366

314367
The field is now editable if rendered inside a mobile Picker.
@@ -379,8 +432,8 @@ This change causes a few breaking changes:
379432
```diff
380433
const theme = createTheme({
381434
components: {
382-
- PickersMonth: {
383-
+ MonthCalendar: {
435+
- MuiPickersMonth: {
436+
+ MuiMonthCalendar: {
384437
styleOverrides: {
385438
- monthButton: {
386439
+ button: {
@@ -420,8 +473,8 @@ This change causes a few breaking changes:
420473
```diff
421474
const theme = createTheme({
422475
components: {
423-
- PickersYear: {
424-
+ YearCalendar: {
476+
- MuiPickersYear: {
477+
+ MuiYearCalendar: {
425478
styleOverrides: {
426479
- yearButton: {
427480
+ button: {
@@ -824,10 +877,10 @@ If the updated values do not fit your use case, you can [override them](/x/react
824877

825878
// This contains a small behavior change.
826879
// If the picker is not controlled and has a default value,
827-
// opening it and calling `acceptValueChanges` without any change will call `onAccept`
880+
// opening it and calling `acceptValueChanges` without any change calls `onAccept`
828881
// with the default value.
829-
// Whereas before, opening it and calling `onDimiss` without any change would
830-
// not have called `onAccept`.
882+
// Whereas before, opening it and calling `onDimiss` without any change
883+
// did not call `onAccept`.
831884
-const { onDismiss } = props;
832885
+const { acceptValueChanges } = usePickerActionsContext();
833886
+const onDismiss = acceptValueChanges

0 commit comments

Comments
 (0)