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] Remove utils and value params from translations #14986

Merged
Show file tree
Hide file tree
Changes from 4 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
285 changes: 285 additions & 0 deletions docs/data/migration/migration-pickers-v7/migration-pickers-v7.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,285 @@
---
productId: x-date-pickers
---

# Migration from v7 to v8

<p class="description">This guide describes the changes needed to migrate the Date and Time Pickers from v7 to v8.</p>

## Introduction

This is a reference guide for upgrading `@mui/x-date-pickers` from v7 to v8.

## Start using the new release

In `package.json`, change the version of the date pickers package to `^8.0.0`.

```diff
-"@mui/x-date-pickers": "7.x.x",
+"@mui/x-date-pickers": "^8.0.0",
```

Since `v8` is a major release, it contains changes that affect the public API.
These changes were done for consistency, improved stability and to make room for new features.
Described below are the steps needed to migrate from v7 to v8.

## Run codemods

The `preset-safe` codemod will automatically adjust the bulk of your code to account for breaking changes in v8. You can run `v8.0.0/pickers/preset-safe` targeting only Date and Time Pickers or `v8.0.0/preset-safe` to target the other packages as well.

Check warning on line 28 in docs/data/migration/migration-pickers-v7/migration-pickers-v7.md

View workflow job for this annotation

GitHub Actions / runner / vale

[vale] reported by reviewdog 🐶 [Google.Will] Avoid using 'will'. Raw Output: {"message": "[Google.Will] Avoid using 'will'.", "location": {"path": "docs/data/migration/migration-pickers-v7/migration-pickers-v7.md", "range": {"start": {"line": 28, "column": 27}}}, "severity": "WARNING"}

You can either run it on a specific file, folder, or your entire codebase when choosing the `<path>` argument.

<!-- #default-branch-switch -->

```bash
// Date and Time Pickers specific
npx @mui/x-codemod@latest v8.0.0/pickers/preset-safe <path>

// Target the other packages as well
npx @mui/x-codemod@latest v8.0.0/preset-safe <path>
```

:::info
If you want to run the transformers one by one, check out the transformers included in the [preset-safe codemod for pickers](https://github.com/mui/mui-x/blob/HEAD/packages/x-codemod/README.md#preset-safe-for-pickers-v800) for more details.
:::

Breaking changes that are handled by this codemod are denoted by a ✅ emoji in the table of contents on the right side of the screen.

If you have already applied the `v8.0.0/pickers/preset-safe` (or `v8.0.0/preset-safe`) codemod, then you should not need to take any further action on these items.

All other changes must be handled manually.

:::warning
Not all use cases are covered by codemods. In some scenarios, like props spreading, cross-file dependencies, etc., the changes are not properly identified and therefore must be handled manually.

For example, if a codemod tries to rename a prop, but this prop is hidden with the spread operator, it won't be transformed as expected.

```tsx
<DatePicker {...pickerProps} />
```

After running the codemods, make sure to test your application and that you don't have any console errors.

Feel free to [open an issue](https://github.com/mui/mui-x/issues/new/choose) for support if you need help to proceed with your migration.
:::

## New DOM structure for the field
arthurbalduini marked this conversation as resolved.
Show resolved Hide resolved

Before version `v8.x`, the fields' DOM structure consisted of an `<input />`, which held the whole value for the component,
but unfortunately presents a few limitations in terms of accessibility when managing multiple section values.

Starting with version `v8.x`, all the field and picker components come with a new DOM structure that allows the field component to set aria attributes on individual sections, providing a far better experience with screen readers.

### Fallback to the non-accessible DOM structure

```tsx
<DateField enableAccessibleFieldDOMStructure={false} />
<DatePicker enableAccessibleFieldDOMStructure={false} />
<DateRangePicker enableAccessibleFieldDOMStructure={false} />
```

### Migrate `slotProps.field`

When using `slotProps.field` to pass props to your field component,
the field consumes some props (e.g: `shouldRespectLeadingZeros`) and forwards the rest to the `TextField`.

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

Both components below will respect the leading zeroes on digit sections:

Check warning on line 88 in docs/data/migration/migration-pickers-v7/migration-pickers-v7.md

View workflow job for this annotation

GitHub Actions / runner / vale

[vale] reported by reviewdog 🐶 [Google.Will] Avoid using 'will'. Raw Output: {"message": "[Google.Will] Avoid using 'will'.", "location": {"path": "docs/data/migration/migration-pickers-v7/migration-pickers-v7.md", "range": {"start": {"line": 88, "column": 25}}}, "severity": "WARNING"}

```js
<DatePicker
slotProps={{ field: { shouldRespectLeadingZeros: true } }}
enableAccessibleFieldDOMStructure={false}
/>
<DatePicker
slotProps={{ field: { shouldRespectLeadingZeros: true } }}
/>
```

- For the props forwarded to the `TextField`,
you can have a look at the next section to see how the migration impact them.

Both components below will render a small size UI:

```js
<DatePicker
slotProps={{ field: { size: 'small' } }}
enableAccessibleFieldDOMStructure={false}
/>
<DatePicker
slotProps={{ field: { size: 'small' } }}
/>
```

### Migrate `slotProps.textField`

If you are passing props to `slotProps.textField`,
these props will now be received by `PickersTextField` and should keep working the same way as before.

Check warning on line 118 in docs/data/migration/migration-pickers-v7/migration-pickers-v7.md

View workflow job for this annotation

GitHub Actions / runner / vale

[vale] reported by reviewdog 🐶 [Google.Will] Avoid using 'will'. Raw Output: {"message": "[Google.Will] Avoid using 'will'.", "location": {"path": "docs/data/migration/migration-pickers-v7/migration-pickers-v7.md", "range": {"start": {"line": 118, "column": 13}}}, "severity": "WARNING"}

Both components below will render a small size UI:

Check warning on line 120 in docs/data/migration/migration-pickers-v7/migration-pickers-v7.md

View workflow job for this annotation

GitHub Actions / runner / vale

[vale] reported by reviewdog 🐶 [Google.Will] Avoid using 'will'. Raw Output: {"message": "[Google.Will] Avoid using 'will'.", "location": {"path": "docs/data/migration/migration-pickers-v7/migration-pickers-v7.md", "range": {"start": {"line": 120, "column": 23}}}, "severity": "WARNING"}

```js
<DatePicker
slotProps={{ textField: { size: 'small' } }}
enableAccessibleFieldDOMStructure={false}
/>
<DatePicker
slotProps={{ textField: { size: 'small' } }}
/>
```

:::info
If you are passing `inputProps` to `slotProps.textField`,
these props will now be passed to the hidden `<input />` element.

Check warning on line 134 in docs/data/migration/migration-pickers-v7/migration-pickers-v7.md

View workflow job for this annotation

GitHub Actions / runner / vale

[vale] reported by reviewdog 🐶 [Google.Will] Avoid using 'will'. Raw Output: {"message": "[Google.Will] Avoid using 'will'.", "location": {"path": "docs/data/migration/migration-pickers-v7/migration-pickers-v7.md", "range": {"start": {"line": 134, "column": 13}}}, "severity": "WARNING"}
:::

### Migrate `slots.field`

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.
This new component will need to use the `PickersSectionList` component instead of an `<input />` HTML element.

Check warning on line 140 in docs/data/migration/migration-pickers-v7/migration-pickers-v7.md

View workflow job for this annotation

GitHub Actions / runner / vale

[vale] reported by reviewdog 🐶 [Google.Will] Avoid using 'will'. Raw Output: {"message": "[Google.Will] Avoid using 'will'.", "location": {"path": "docs/data/migration/migration-pickers-v7/migration-pickers-v7.md", "range": {"start": {"line": 140, "column": 20}}}, "severity": "WARNING"}

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

:::info
If your custom field was used to create a Joy UI design component,
you may want to wait a few weeks for the release of an out-of-the-box Joy `PickersTextField` component instead of implementing it yourself.
:::

### Migrate `slots.textField`

If you are passing a custom `TextField` component to your fields and pickers,
you need to create a new one that is using the accessible DOM structure.

You can have a look at the second demo of the [Wrapping PickersTextField](/x/react-date-pickers/custom-field/#wrapping-pickerstextfield) to have a concrete example.

:::info
If your custom `TextField` was used to apply a totally different input that did not use `@mui/material/TextField`,
please consider having a look at the [Using a custom input](/x/react-date-pickers/custom-field/#using-a-custom-input) section which uses `slots.field`.
This approach can be more appropriate for deeper changes.
:::

### Migrate the theme

If you are using the theme to customize `MuiTextField`,
you need to pass the same config to `MuiPickersTextField`:

```js
const theme = createTheme({
components: {
MuiTextField: {
defaultProps: {
variant: 'outlined',
},
styleOverrides: {
root: {
'& .MuiInputLabel-outlined.Mui-focused': {
color: 'red',
},
},
},
},
MuiPickersTextField: {
defaultProps: {
variant: 'outlined',
},
styleOverrides: {
root: {
'& .MuiInputLabel-outlined.Mui-focused': {
color: 'red',
},
},
},
},
},
});
```

If you are using the theme to customize `MuiInput`, `MuiOutlinedInput` or `MuiFilledInput`,
you need to pass the same config to `MuiPickersInput`, `MuiPickersOutlinedInput` or `MuiPickersFilledInput`:

```js
const theme = createTheme({
components: {
// Replace with `MuiOutlinedInput` or `MuiFilledInput` if needed
MuiInput: {
defaultProps: {
margin: 'dense',
},
styleOverrides: {
root: {
color: 'red',
},
},
},
// Replace with `MuiPickersOutlinedInput` or `MuiPickersFilledInput` if needed
MuiPickersInput: {
defaultProps: {
margin: 'dense',
},
styleOverrides: {
root: {
color: 'red',
},
},
},
},
});
```

If you are using the theme to customize `MuiInputBase`,
you need to pass the same config to `MuiPickersInputBase`:

```js
const theme = createTheme({
components: {
MuiInputBase: {
defaultProps: {
margin: 'dense',
},
styleOverrides: {
root: {
color: 'red',
},
},
},
MuiPickersInputBase: {
defaultProps: {
margin: 'dense',
},
styleOverrides: {
root: {
color: 'red',
},
},
},
},
});
```

## Deprecated parameters used on translation keys functions
arthurbalduini marked this conversation as resolved.
Show resolved Hide resolved

If you are using a Picker with controlled value and views and you need to compose some of the following translation keys: `openDatePickerDialogue`, `openTimePickerDialogue`, or `clockLabelText`, after upgrading to v8 you only need to pass the formatted value and the time view (only for `clockLabelText`):
arthurbalduini marked this conversation as resolved.
Show resolved Hide resolved

```js
const translations = useTranslations();

const openDatePickerDialogue = translations.openDatePickerDialogue(
value == null ? null : value.format('MM/DD/YYY'),
);
const openTimePickerDialogue = translations.openTimePickerDialogue(
value == null ? null : value.format('HH:mm:ss'),
);
const clockLabelText = translations.clockLabelText(
view,
value == null ? null : value.format('HH:mm:ss'),
);
```

Also the following types and interfaces no longer receive a generic type parameter:
arthurbalduini marked this conversation as resolved.
Show resolved Hide resolved

- `PickersComponentAgnosticLocaleText`
- `PickersInputComponentLocaleText`
- `PickersInputLocaleText`
- `PickersLocaleText`
- `PickersTranslationKeys`
12 changes: 11 additions & 1 deletion docs/data/pages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -531,9 +531,19 @@ const pages: MuiPage[] = [
pathname: '/x/migration-group',
title: 'Migration',
children: [
{
pathname: '/x/migration-v8',
subheader: 'Upgrade to v8',
children: [
{
pathname: '/x/migration/migration-pickers-v7',
title: 'Breaking changes: Date and Time Pickers',
},
],
},
{
pathname: '/x/migration-v7',
subheader: 'Upgrade to v7',
title: 'Upgrade to v7',
children: [
{ pathname: '/x/migration/migration-data-grid-v6', title: 'Breaking changes: Data Grid' },
{
Expand Down
7 changes: 7 additions & 0 deletions docs/pages/x/migration/migration-pickers-v7.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import * as React from 'react';
import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs';
import * as pageProps from 'docsx/data/migration/migration-pickers-v7/migration-pickers-v7.md?muiMarkdown';

export default function Page() {
return <MarkdownDocs {...pageProps} />;
}
4 changes: 2 additions & 2 deletions packages/x-date-pickers-pro/src/DateRangePicker/shared.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ export interface BaseDateRangePickerProps<TDate extends PickerValidDate>
type UseDateRangePickerDefaultizedProps<
TDate extends PickerValidDate,
Props extends BaseDateRangePickerProps<TDate>,
> = LocalizedComponent<TDate, DefaultizedProps<Props, keyof BaseDateValidationProps<TDate>>>;
> = LocalizedComponent<DefaultizedProps<Props, keyof BaseDateValidationProps<TDate>>>;

export function useDateRangePickerDefaultizedProps<
TDate extends PickerValidDate,
Expand All @@ -81,7 +81,7 @@ export function useDateRangePickerDefaultizedProps<
name,
});

const localeText = React.useMemo<PickersInputLocaleText<TDate> | undefined>(() => {
const localeText = React.useMemo<PickersInputLocaleText | undefined>(() => {
if (themeProps.localeText?.toolbarTitle == null) {
return themeProps.localeText;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,6 @@ type UseDateTimeRangePickerDefaultizedProps<
TDate extends PickerValidDate,
Props extends BaseDateTimeRangePickerProps<TDate>,
> = LocalizedComponent<
TDate,
Omit<DefaultizedProps<Props, 'openTo' | 'ampm' | keyof BaseDateValidationProps<TDate>>, 'views'>
> & {
shouldRenderTimeInASingleColumn: boolean;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ export interface UseEnrichedRangePickerFieldPropsParams<
disableOpenPicker?: boolean;
onBlur?: () => void;
label?: React.ReactNode;
localeText: PickersInputLocaleText<TDate> | undefined;
localeText: PickersInputLocaleText | undefined;
pickerSlotProps: RangePickerFieldSlotProps<TDate, TEnableAccessibleFieldDOMStructure> | undefined;
pickerSlots: RangePickerFieldSlots | undefined;
fieldProps: RangePickerPropsForFieldSlot<
Expand Down
3 changes: 1 addition & 2 deletions packages/x-date-pickers/src/DatePicker/shared.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@ type UseDatePickerDefaultizedProps<
TDate extends PickerValidDate,
Props extends BaseDatePickerProps<TDate>,
> = LocalizedComponent<
TDate,
DefaultizedProps<Props, 'views' | 'openTo' | keyof BaseDateValidationProps<TDate>>
>;

Expand All @@ -86,7 +85,7 @@ export function useDatePickerDefaultizedProps<
name,
});

const localeText = React.useMemo<PickersInputLocaleText<TDate> | undefined>(() => {
const localeText = React.useMemo<PickersInputLocaleText | undefined>(() => {
if (themeProps.localeText?.toolbarTitle == null) {
return themeProps.localeText;
}
Expand Down
3 changes: 1 addition & 2 deletions packages/x-date-pickers/src/DateTimePicker/shared.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,6 @@ type UseDateTimePickerDefaultizedProps<
TView extends DateOrTimeViewWithMeridiem,
Props extends BaseDateTimePickerProps<TDate, TView>,
> = LocalizedComponent<
TDate,
DefaultizedProps<
Props,
| 'views'
Expand All @@ -138,7 +137,7 @@ export function useDateTimePickerDefaultizedProps<

const ampm = themeProps.ampm ?? utils.is12HourCycleInCurrentLocale();

const localeText = React.useMemo<PickersInputLocaleText<TDate> | undefined>(() => {
const localeText = React.useMemo<PickersInputLocaleText | undefined>(() => {
if (themeProps.localeText?.toolbarTitle == null) {
return themeProps.localeText;
}
Expand Down
Loading
Loading