diff --git a/.circleci/config.yml b/.circleci/config.yml index a5685e260757..dba93579ac67 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -13,6 +13,14 @@ parameters: description: The name of the workflow to run type: string default: pipeline + with-material-ui-6: + description: Use material-ui v6 for additional checks and tests + type: boolean + default: false + with-react-version: + description: The version of react to be used for the additional tests + type: string + default: stable e2e-base-url: description: The base url for running end-to-end test type: string @@ -90,11 +98,10 @@ commands: git --no-pager diff HEAD - when: - condition: - equal: [material-ui-v6, << pipeline.parameters.workflow >>] + condition: << pipeline.parameters.with-material-ui-6 >> steps: - run: - name: Install @mui/material@next + name: Install @mui/material v6 command: pnpm use-material-ui-v6 jobs: @@ -349,50 +356,38 @@ workflows: requires: - checkout - react-next: + additional-tests: when: - equal: [react-next, << pipeline.parameters.workflow >>] - # triggers: - # - schedule: - # cron: '0 0 * * *' - # filters: - # branches: - # only: - # - master + and: + - equal: [additional, << pipeline.parameters.workflow >>] + - or: + - equal: [true, << pipeline.parameters.with-material-ui-6 >>] + - not: + equal: ['stable', << pipeline.parameters.with-react-version >>] jobs: - test_unit: <<: *default-context - react-version: next - name: test_unit-react@next + name: test_unit_additional + react-version: << pipeline.parameters.with-react-version >> - test_browser: <<: *default-context - react-version: next - name: test_browser-react@next + name: test_browser_additional + react-version: << pipeline.parameters.with-react-version >> - test_regressions: <<: *default-context - react-version: next - name: test_regressions-react@next + name: test_regressions_additional + react-version: << pipeline.parameters.with-react-version >> - test_e2e: <<: *default-context - react-version: next - name: test_e2e-react@next + name: test_e2e_additional + react-version: << pipeline.parameters.with-react-version >> - material-ui-v6: + additional-checks: when: - equal: [material-ui-v6, << pipeline.parameters.workflow >>] + and: + - equal: [additional, << pipeline.parameters.workflow >>] + - equal: [true, << pipeline.parameters.with-material-ui-6 >>] jobs: - - test_unit: - <<: *default-context - name: test_unit-material@next - - test_browser: - <<: *default-context - name: test_browser-material@next - - test_regressions: - <<: *default-context - name: test_regressions-material@next - - test_e2e: - <<: *default-context - name: test_e2e-material@next - test_types: <<: *default-context - name: test_types-material@next + name: test_types_additional diff --git a/CHANGELOG.md b/CHANGELOG.md index ccd831351ce0..73e31d660cbd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,148 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## v8.0.0-alpha.1 + +_Nov 22, 2024_ + +We'd like to offer a big thanks to the 16 contributors who made this release possible. Here are some highlights āœØ: + +- šŸ”§ Refactor Tooltip customisation for charts ā€” [Learn more](https://next.mui.com/x/react-charts/tooltip/#overriding-content). +- āš›ļø React 19 support +- šŸŒ Improve Chinese, Spanish, and Swedish locale on the Data Grid component +- šŸž Bugfixes +- šŸ“š Documentation improvements + +### Breaking change + +Special thanks go out to the community contributors who have helped make this release possible: +@CarlosLopezLg, @headironc, @hendrikpeilke, @k-rajat19, @lhilgert9, @viktormelin. +Following are all team members who have contributed to this release: +@alexfauquette, @arthurbalduini, @cherniavskii, @flaviendelangle, @JCQuintas, @LukasTy, @MBilalShafi, @oliviertassinari, @KenanYusuf, @arminmeh. + + + +### Data Grid + +#### `@mui/x-data-grid@v8.0.0-alpha.1` + +- [DataGrid] React 19 support (#15342) @arminmeh +- [DataGrid] Add prop to override search input props in `GridColumnsManagement` (#15347) @k-rajat19 +- [DataGrid] Add test coverage for issues fixed in #15184 (#15282) @MBilalShafi +- [DataGrid] Change default loading overlay variants (#15504) @KenanYusuf +- [DataGrid] Fix last separator not being hidden when grid is scrollable (#15543) @KenanYusuf +- [DataGrid] Fix right column group header border with virtualization (#15470) @hendrikpeilke +- [DataGrid] Fix row-spanning in combination with column-pinning (#15368) @lhilgert9 +- [l10n] Improve Chinese (zh-CN) locale (#15365) @headironc +- [l10n] Improve Spanish (es-ES) locale (#15369) @CarlosLopezLg +- [l10n] Improve Swedish (sv-SE) locale (#15371) @viktormelin + +#### `@mui/x-data-grid-pro@v8.0.0-alpha.1` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan') + +Same changes as in `@mui/x-data-grid@v8.0.0-alpha.1`. + +#### `@mui/x-data-grid-premium@v8.0.0-alpha.1` [![premium](https://mui.com/r/x-premium-svg)](https://mui.com/r/x-premium-svg-link 'Premium plan') + +Same changes as in `@mui/x-data-grid-pro@v8.0.0-alpha.1`, plus: + +- [DataGridPremium] Prompt input control (#15401) @arminmeh + +### Date and Time Pickers + +#### Breaking change + +- The `FieldValueType` type has been renamed to `PickerValueType` ā€” [Learn more](https://next.mui.com/x/migration/migration-pickers-v7/#renamed-variables). +- The `toolbar` and `layout` slots no longer receive the `disabled` and `readOnly` props ā€” [Learn more](https://next.mui.com/x/migration/migration-pickers-v7/#slots-breaking-changes). + +#### `@mui/x-date-pickers@v8.0.0-alpha.1` + +- [fields] Fix focus management with new DOM structure (#15475) @flaviendelangle +- [pickers] React 19 support (#15342) @arminmeh +- [pickers] Add new properties to `PickerOwnerState` and `PickerContextValue` (#15415) @flaviendelangle +- [pickers] Always use `props.value` when it changes (#15490) @flaviendelangle +- [pickers] Ensure internal value timezone is updated (#15435) @LukasTy +- [pickers] Fix unused code in `` component (#15515) @LukasTy +- [pickers] Remove `FieldValueType` in favor of `PickerValueType` (#15259) @arthurbalduini +- [pickers] Remove the form props from the layout and the toolbar slots (#15492) @flaviendelangle +- [pickers] Use `props.referenceDate` timezone when `props.value` and `props.defaultValue` are not defined (#15532) @flaviendelangle +- [TimePicker] Prevent mouse events after `touchend` event (#15346) @arthurbalduini + +#### `@mui/x-date-pickers-pro@v8.0.0-alpha.1` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan') + +Same changes as in `@mui/x-date-pickers@v8.0.0-alpha.1`, plus: + +- [DateTimeRangePicker] Use time in `referenceDate` when selecting date (#15429) @LukasTy + +### Charts + +#### Breaking change + +- The DX of the Tooltip customization has been refactored + - The `tooltip` prop has been removed in favor of `slotProps.tooltip` for consistency. + - The `popper`, `axisContent`, and `itemContent` slots have been removed in favor of the `tooltip` slot which overrides the entire tooltip. + - To override the tooltip content, use the `useItemTooltip` or `useAxisTooltip` hook to get the data, and wrap your component in `ChartsTooltipContainer` to follow the pointer position. + - To override the tooltip placement, use the `ChartsItemTooltipContent` or `ChartsItemTooltipContent` to get default data and place them in your custom tooltip. + +- The library now uses the SVG `filter` attribute instead of `d3-color` for color manipulation. + - This modification impacts the `LinePlot`, `AreaPlot`, and `BarPlot` components. + If you've customized the `fill` of those elements, you might need to override it by using the CSS `filter`. + - The `theme.styleOverride` is removed for `MuiLineElement`, `MuiAreaElement`, and `MuiBarElement` to improve performance. + You can still target those elements by using the `MuiLinePlot`, `MuiAreaPlot`, and `MuiBarPlot` and target the appropriate classes `lineElementClasses.root`, `areaElementClasses.root`, `barElementClasses.root` + +- Removed the `resolveSizeBeforeRender` prop from all chart components ā€” [Learn more](https://next.mui.com/x/migration/migration-charts-v7/#remove-resolvesizebeforerender-prop). +- Removed `width` and `height` props from the `ChartsSurface` component. +- Removed the `viewport` prop from all charts. + +#### `@mui/x-charts@v8.0.0-alpha.1` + +- [charts] React 19 support (#15342) @arminmeh +- [charts] Decouple `` and `` (#15375) @JCQuintas +- [charts] Fix Scatter Chart tooltip wrong defaults (#15537) @JCQuintas +- [charts] Fix key generation for the `` component (#15463) @alexfauquette +- [charts] Improve `` to split the received ref (#15424) @JCQuintas +- [charts] Move interaction state in store (#15426) @alexfauquette +- [charts] Refactor Tooltip customisation (#15154) @alexfauquette +- [charts] Remove intrinsic size requirement (#15471) @JCQuintas +- [charts] Replace `d3-color` with CSS filter for highlight (#15084) @alexfauquette +- [charts] Split `` into `` and `` (#15417) @JCQuintas + +#### `@mui/x-charts-pro@v8.0.0-alpha.1` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan') + +Same changes as in `@mui/x-charts@v8.0.0-alpha.1`. + +### Tree View + +#### Breaking changes + +- The Tree Item component can no longer use `publicAPI` methods in the `render` because they are now memoized ā€” [Learn more](https://next.mui.com/x/migration/migration-tree-view-v7/#stop-using-publicapi-methods-in-the-render). + +#### `@mui/x-tree-view@v8.0.0-alpha.1` + +- [TreeView] React 19 support (#15342) @arminmeh +- [TreeView] Do not re-render every Tree Item when the Rich Tree View re-renders (introduce selectors) (#14210) @flaviendelangle +- [TreeView] Remove `treeId` from the item context (#15542) @flaviendelangle +- [TreeView] Remove state mutation in `moveItemInTree()` (#15539) @flaviendelangle +- [TreeItem] Correct the typing of `slotProps.groupTransition` (#15534) @flaviendelangle + +### Docs + +- [docs] Fix some migration typos (#15422) @LukasTy +- [docs] Fix typo in migration guide (#15508) @flaviendelangle +- [docs] Fix 301 redirection in docs @oliviertassinari +- [docs] Polish Server-side data section (#15330) @oliviertassinari +- [docs] Use loading state in the demos (#15512) @cherniavskii + +### Core + +- [core] Keep OpenSSF badge up-to-date @oliviertassinari +- [code-infra] Add `'DensitySelectorGrid'` to time-sensitive argos tests (#15425) @JCQuintas +- [code-infra] Add documentation to internal types (#15540) @JCQuintas +- [code-infra] Prevent relative imports across packages (#15437) @JCQuintas +- [code-infra] Update renovate config to merge `action` pins (#15462) @LukasTy +- [docs-infra] Fix version tooltip (#15468) @alexfauquette +- [docs-infra] Transpile `.ts` demo files (#15345) @KenanYusuf +- [infra] Remove cherry-pick issue write permission (#15456) @oliviertassinari + ## 8.0.0-alpha.0 MUIĀ X v8 Alpha is live @@ -196,6 +338,82 @@ Same changes as in `@mui/x-charts@8.0.0-alpha.0`. - [release] v8 preparation (#15054) @michelengelen - [test] Fix advanced list view regression test snapshot (#15260) @KenanYusuf +## v7.22.3 + +_Nov 21, 2024_ + +We'd like to offer a big thanks to the 10 contributors who made this release possible. Here are some highlights āœØ: + +- šŸ“Š Charts Pro get stable. The [zoom](https://mui.com/x/react-charts/zoom-and-pan/) and [Heatmap](https://mui.com/x/react-charts/heatmap/) are now stable. +- šŸŒ Improve Chinese, Spanish, Swedish, and Turkish locales on the Data Grid +- šŸž Bugfixes + +Special thanks go out to the community contributors who have helped make this release possible: +@CarlosLopezLg, @headironc, @viktormelin, @qerkules, @DungTiger, @hendrikpeilke, @k-rajat19. +Following are all team members who have contributed to this release: +@alexfauquette, @LukasTy, @MBilalShafi, @flaviendelangle. + + + +### Data Grid + +#### `@mui/x-data-grid@7.22.3` + +- [DataGrid] Add prop to override search input props in `GridColumnsManagement` (#15476) @k-rajat19 +- [DataGrid] Add test coverage for issues fixed in #15184 @MBilalShafi +- [DataGrid] Fix memoized selectors with arguments (#15336) @MBilalShafi +- [DataGrid] Fix right column group header border with virtualization (#15503) @hendrikpeilke +- [DataGrid] Pass reason to `onPaginationModelChange` (#15402) @DungTiger +- [DataGrid] Set default overlay height in flex parent layout (#15535) @cherniavskii +- [l10n] Improve Chinese (zh-CN) locale (#15365) @headironc +- [l10n] Improve Spanish (es-ES) locale (#15369) @CarlosLopezLg +- [l10n] Improve Swedish (sv-SE) locale (#15371) @viktormelin +- [l10n] Improve Turkish (tr-TR) locale (#15414) @qerkules + +#### `@mui/x-data-grid-pro@7.22.3` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan') + +Same changes as in `@mui/x-data-grid@7.22.3`. + +#### `@mui/x-data-grid-premium@7.22.3` [![premium](https://mui.com/r/x-premium-svg)](https://mui.com/r/x-premium-svg-link 'Premium plan') + +Same changes as in `@mui/x-data-grid-pro@7.22.3`. + +### Date and Time Pickers + +#### `@mui/x-date-pickers@7.22.3` + +- [pickers] Always use `props.value` when it changes (#15500) @flaviendelangle +- [pickers] Ensure internal value timezone is updated (#15491) @LukasTy +- [pickers] Fix `DateTimeRangePicker` error when using format without time (#15341) @fxnoob +- [pickers] Fix unused code in `PickersToolbar` component (#15525) @LukasTy + +#### `@mui/x-date-pickers-pro@7.22.3` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan') + +Same changes as in `@mui/x-date-pickers@7.22.3`, plus: + +- [DateTimeRangePicker] Use time in `referenceDate` when selecting date (#15431) @LukasTy + +### Charts + +#### `@mui/x-charts@7.22.3` + +No changes since `@mui/x-charts@7.22.2`. + +#### `@mui/x-charts-pro@7.22.3` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan') + +- [charts-pro] Fix missing typeOverload (#15400) @alexfauquette + +### Docs + +- [docs] Add `PickersPopper` component to customization playground (#15397) @LukasTy +- [docs] Add `next` version links (#15423) @LukasTy +- [docs] Use the `loading` state in the demos (#15538) @cherniavskii +- [docs] Add data caching to lazy loaded detail panel demo (#15506) @cherniavskii + +- [code-infra] Tentative fix for Argos flaky screenshot tests (#15399) @JCQuintas +- [docs-infra] Transpile `.ts` demo files (#15421) @KenanYusuf +- [core] Clarify release version bump strategy (#15536) @cherniavskii + ## 7.22.2 _Nov 8, 2024_ diff --git a/docs/data/charts/getting-started/getting-started.md b/docs/data/charts/getting-started/getting-started.md index bfac2ba84414..7efdf925eebf 100644 --- a/docs/data/charts/getting-started/getting-started.md +++ b/docs/data/charts/getting-started/getting-started.md @@ -41,8 +41,8 @@ yarn add @mui/material @emotion/react @emotion/styled ```json "peerDependencies": { - "react": "^17.0.0 || ^18.0.0", - "react-dom": "^17.0.0 || ^18.0.0" + "react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" }, ``` diff --git a/docs/data/data-grid/custom-columns/cell-renderers/rating.tsx b/docs/data/data-grid/custom-columns/cell-renderers/rating.tsx index 9eb9c68ce767..56160cf6caf6 100644 --- a/docs/data/data-grid/custom-columns/cell-renderers/rating.tsx +++ b/docs/data/data-grid/custom-columns/cell-renderers/rating.tsx @@ -46,7 +46,7 @@ function EditRating(props: GridRenderEditCellParams) { changedThroughKeyboard.current = false; }; - const handleRef = (element: HTMLElement | undefined) => { + const handleRef = (element: HTMLElement | null) => { if (element) { if (value !== 0) { element.querySelector(`input[value="${value}"]`)!.focus(); diff --git a/docs/data/data-grid/getting-started/getting-started.md b/docs/data/data-grid/getting-started/getting-started.md index 2b77ca3b6ee8..a7e2494e3083 100644 --- a/docs/data/data-grid/getting-started/getting-started.md +++ b/docs/data/data-grid/getting-started/getting-started.md @@ -35,8 +35,8 @@ Please note that [react](https://www.npmjs.com/package/react) and [react-dom](ht ```json "peerDependencies": { - "react": "^17.0.0 || ^18.0.0", - "react-dom": "^17.0.0 || ^18.0.0" + "react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" }, ``` diff --git a/docs/data/data-grid/localization/data.json b/docs/data/data-grid/localization/data.json index f7718fbf0daf..8ce145a0b640 100644 --- a/docs/data/data-grid/localization/data.json +++ b/docs/data/data-grid/localization/data.json @@ -195,7 +195,7 @@ "languageTag": "pt-PT", "importName": "ptPT", "localeName": "Portuguese", - "missingKeysCount": 11, + "missingKeysCount": 0, "totalKeysCount": 133, "githubLink": "https://github.com/mui/mui-x/blob/master/packages/x-data-grid/src/locales/ptPT.ts" }, @@ -203,7 +203,7 @@ "languageTag": "pt-BR", "importName": "ptBR", "localeName": "Portuguese (Brazil)", - "missingKeysCount": 11, + "missingKeysCount": 0, "totalKeysCount": 133, "githubLink": "https://github.com/mui/mui-x/blob/master/packages/x-data-grid/src/locales/ptBR.ts" }, @@ -235,7 +235,7 @@ "languageTag": "es-ES", "importName": "esES", "localeName": "Spanish", - "missingKeysCount": 11, + "missingKeysCount": 0, "totalKeysCount": 133, "githubLink": "https://github.com/mui/mui-x/blob/master/packages/x-data-grid/src/locales/esES.ts" }, diff --git a/docs/data/date-pickers/getting-started/getting-started.md b/docs/data/date-pickers/getting-started/getting-started.md index e57e07a9de80..c3a703efd7b4 100644 --- a/docs/data/date-pickers/getting-started/getting-started.md +++ b/docs/data/date-pickers/getting-started/getting-started.md @@ -58,8 +58,8 @@ yarn add @mui/material @emotion/react @emotion/styled ```json "peerDependencies": { - "react": "^17.0.0 || ^18.0.0", - "react-dom": "^17.0.0 || ^18.0.0" + "react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" }, ``` diff --git a/docs/data/tree-view/getting-started/getting-started.md b/docs/data/tree-view/getting-started/getting-started.md index 6acc9e5382c1..bc146ab1f18f 100644 --- a/docs/data/tree-view/getting-started/getting-started.md +++ b/docs/data/tree-view/getting-started/getting-started.md @@ -44,8 +44,8 @@ Please note that [react](https://www.npmjs.com/package/react) and [react-dom](ht ```json "peerDependencies": { - "react": "^17.0.0 || ^18.0.0", - "react-dom": "^17.0.0 || ^18.0.0" + "react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" }, ``` diff --git a/package.json b/package.json index 0d18c62a5494..31622c265acb 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "version": "8.0.0-alpha.0", + "version": "8.0.0-alpha.1", "private": true, "scripts": { "preinstall": "npx only-allow pnpm", diff --git a/packages/x-charts-pro/README.md b/packages/x-charts-pro/README.md index 4e4c99c2e35a..05616ba80e2b 100644 --- a/packages/x-charts-pro/README.md +++ b/packages/x-charts-pro/README.md @@ -16,8 +16,8 @@ This component has the following peer dependencies that you need to install as w ```json "peerDependencies": { "@mui/material": "^5.15.14 || ^6.0.0", - "react": "^17.0.0 || ^18.0.0", - "react-dom": "^17.0.0 || ^18.0.0" + "react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" }, ``` diff --git a/packages/x-charts-pro/package.json b/packages/x-charts-pro/package.json index d3df0c0605b3..dd390c17b556 100644 --- a/packages/x-charts-pro/package.json +++ b/packages/x-charts-pro/package.json @@ -1,6 +1,6 @@ { "name": "@mui/x-charts-pro", - "version": "8.0.0-alpha.0", + "version": "8.0.0-alpha.1", "description": "The Pro plan edition of the Charts components (MUI X).", "author": "MUI Team", "main": "src/index.ts", @@ -55,8 +55,8 @@ "@emotion/styled": "^11.8.1", "@mui/material": "^5.15.14 || ^6.0.0", "@mui/system": "^5.15.14 || ^6.0.0", - "react": "^17.0.0 || ^18.0.0", - "react-dom": "^17.0.0 || ^18.0.0" + "react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" }, "peerDependenciesMeta": { "@emotion/react": { diff --git a/packages/x-charts-vendor/package.json b/packages/x-charts-vendor/package.json index fc967be2d8ed..962c4c18b577 100644 --- a/packages/x-charts-vendor/package.json +++ b/packages/x-charts-vendor/package.json @@ -1,6 +1,6 @@ { "name": "@mui/x-charts-vendor", - "version": "8.0.0-alpha.0", + "version": "8.0.0-alpha.1", "description": "Vendored dependencies for MUI X Charts", "author": "MUI Team", "keywords": [ diff --git a/packages/x-charts/README.md b/packages/x-charts/README.md index cda7ac8e591e..7eafec7d9e44 100644 --- a/packages/x-charts/README.md +++ b/packages/x-charts/README.md @@ -16,8 +16,8 @@ This component has the following peer dependencies that you need to install as w ```json "peerDependencies": { "@mui/material": "^5.15.14 || ^6.0.0", - "react": "^17.0.0 || ^18.0.0", - "react-dom": "^17.0.0 || ^18.0.0" + "react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" }, ``` diff --git a/packages/x-charts/package.json b/packages/x-charts/package.json index 94f595857921..874f0c9dca67 100644 --- a/packages/x-charts/package.json +++ b/packages/x-charts/package.json @@ -1,6 +1,6 @@ { "name": "@mui/x-charts", - "version": "8.0.0-alpha.0", + "version": "8.0.0-alpha.1", "description": "The community edition of the Charts components (MUI X).", "author": "MUI Team", "main": "src/index.js", @@ -55,8 +55,8 @@ "@emotion/styled": "^11.8.1", "@mui/material": "^5.15.14 || ^6.0.0", "@mui/system": "^5.15.14 || ^6.0.0", - "react": "^17.0.0 || ^18.0.0", - "react-dom": "^17.0.0 || ^18.0.0" + "react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" }, "peerDependenciesMeta": { "@emotion/react": { diff --git a/packages/x-charts/src/context/AnimationProvider/useSkipAnimation.test.tsx b/packages/x-charts/src/context/AnimationProvider/useSkipAnimation.test.tsx index 997cdbd30429..bb0f82706104 100644 --- a/packages/x-charts/src/context/AnimationProvider/useSkipAnimation.test.tsx +++ b/packages/x-charts/src/context/AnimationProvider/useSkipAnimation.test.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; import { expect } from 'chai'; -import { ErrorBoundary, createRenderer, screen } from '@mui/internal-test-utils'; +import { ErrorBoundary, createRenderer, screen, reactMajor } from '@mui/internal-test-utils'; import { useSkipAnimation } from './useSkipAnimation'; import { AnimationProvider } from './AnimationProvider'; @@ -37,17 +37,22 @@ describe('useSkipAnimation', () => { const errorRef = React.createRef(); + const errorMessage1 = 'MUI X: Could not find the animation ref context.'; + const errorMessage2 = + 'It looks like you rendered your component outside of a ChartsContainer parent component.'; + const errorMessage3 = 'The above error occurred in the component:'; + const expextedError = + reactMajor < 19 + ? [errorMessage1, errorMessage2, errorMessage3] + : `${errorMessage1}\n${errorMessage2}`; + expect(() => render( , ), - ).toErrorDev([ - 'MUI X: Could not find the animation ref context.', - 'It looks like you rendered your component outside of a ChartsContainer parent component.', - 'The above error occurred in the component:', - ]); + ).toErrorDev(expextedError); expect((errorRef.current as any).errors).to.have.length(1); expect((errorRef.current as any).errors[0].toString()).to.include( diff --git a/packages/x-charts/src/context/HighlightedProvider/useHighlighted.test.tsx b/packages/x-charts/src/context/HighlightedProvider/useHighlighted.test.tsx index 29337e8d7191..fb17106413fd 100644 --- a/packages/x-charts/src/context/HighlightedProvider/useHighlighted.test.tsx +++ b/packages/x-charts/src/context/HighlightedProvider/useHighlighted.test.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; import { expect } from 'chai'; -import { ErrorBoundary, createRenderer, screen } from '@mui/internal-test-utils'; +import { ErrorBoundary, createRenderer, screen, reactMajor } from '@mui/internal-test-utils'; import { useHighlighted } from './useHighlighted'; import { HighlightedProvider } from './HighlightedProvider'; import { SeriesProvider } from '../SeriesProvider'; @@ -23,17 +23,22 @@ describe('useHighlighted', () => { const errorRef = React.createRef(); + const errorMessage1 = 'MUI X: Could not find the highlighted ref context.'; + const errorMessage2 = + 'It looks like you rendered your component outside of a ChartsContainer parent component.'; + const errorMessage3 = 'The above error occurred in the component:'; + const expextedError = + reactMajor < 19 + ? [errorMessage1, errorMessage2, errorMessage3] + : `${errorMessage1}\n${errorMessage2}`; + expect(() => render( , ), - ).toErrorDev([ - 'MUI X: Could not find the highlighted ref context.', - 'It looks like you rendered your component outside of a ChartsContainer parent component.', - 'The above error occurred in the component:', - ]); + ).toErrorDev(expextedError); expect((errorRef.current as any).errors).to.have.length(1); expect((errorRef.current as any).errors[0].toString()).to.include( diff --git a/packages/x-charts/src/hooks/useSeries.test.tsx b/packages/x-charts/src/hooks/useSeries.test.tsx index 4bbe16ff5cb6..8bc52cb6c2e3 100644 --- a/packages/x-charts/src/hooks/useSeries.test.tsx +++ b/packages/x-charts/src/hooks/useSeries.test.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; import { expect } from 'chai'; -import { ErrorBoundary, createRenderer, screen } from '@mui/internal-test-utils'; +import { ErrorBoundary, createRenderer, reactMajor, screen } from '@mui/internal-test-utils'; import { useSeries } from './useSeries'; import { SeriesProvider } from '../context/SeriesProvider'; import { PluginProvider } from '../internals'; @@ -22,17 +22,22 @@ describe('useSeries', () => { const errorRef = React.createRef(); + const errorMessage1 = 'MUI X: Could not find the series ref context.'; + const errorMessage2 = + 'It looks like you rendered your component outside of a ChartsContainer parent component.'; + const errorMessage3 = 'The above error occurred in the component:'; + const expextedError = + reactMajor < 19 + ? [errorMessage1, errorMessage2, errorMessage3] + : `${errorMessage1}\n${errorMessage2}`; + expect(() => render( , ), - ).toErrorDev([ - 'MUI X: Could not find the series ref context.', - 'It looks like you rendered your component outside of a ChartsContainer parent component.', - 'The above error occurred in the component:', - ]); + ).toErrorDev(expextedError); expect((errorRef.current as any).errors).to.have.length(1); expect((errorRef.current as any).errors[0].toString()).to.include( diff --git a/packages/x-charts/src/hooks/useSvgRef.test.tsx b/packages/x-charts/src/hooks/useSvgRef.test.tsx index e6d16c2beab9..d03aca479c9d 100644 --- a/packages/x-charts/src/hooks/useSvgRef.test.tsx +++ b/packages/x-charts/src/hooks/useSvgRef.test.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; import { expect } from 'chai'; -import { ErrorBoundary, createRenderer, screen } from '@mui/internal-test-utils'; +import { ErrorBoundary, createRenderer, reactMajor, screen } from '@mui/internal-test-utils'; import { useSvgRef } from './useSvgRef'; import { SvgRefProvider, useSurfaceRef } from '../context/SvgRefProvider'; @@ -30,17 +30,22 @@ describe('useSvgRef', () => { const errorRef = React.createRef(); + const errorMessage1 = 'MUI X: Could not find the svg ref context.'; + const errorMessage2 = + 'It looks like you rendered your component outside of a ChartsContainer parent component.'; + const errorMessage3 = 'The above error occurred in the component:'; + const expextedError = + reactMajor < 19 + ? [errorMessage1, errorMessage2, errorMessage3] + : `${errorMessage1}\n${errorMessage2}`; + expect(() => render( , ), - ).toErrorDev([ - 'MUI X: Could not find the svg ref context.', - 'It looks like you rendered your component outside of a ChartsContainer parent component.', - 'The above error occurred in the component:', - ]); + ).toErrorDev(expextedError); expect((errorRef.current as any).errors).to.have.length(1); expect((errorRef.current as any).errors[0].toString()).to.include( diff --git a/packages/x-codemod/package.json b/packages/x-codemod/package.json index 44a02429be2f..76e4e92fa12d 100644 --- a/packages/x-codemod/package.json +++ b/packages/x-codemod/package.json @@ -1,6 +1,6 @@ { "name": "@mui/x-codemod", - "version": "8.0.0-alpha.0", + "version": "8.0.0-alpha.1", "bin": "./codemod.js", "private": false, "author": "MUI Team", diff --git a/packages/x-data-grid-generator/package.json b/packages/x-data-grid-generator/package.json index 54385f60af06..f70df7751dec 100644 --- a/packages/x-data-grid-generator/package.json +++ b/packages/x-data-grid-generator/package.json @@ -1,6 +1,6 @@ { "name": "@mui/x-data-grid-generator", - "version": "8.0.0-alpha.0", + "version": "8.0.0-alpha.1", "description": "Generate fake data for demo purposes only.", "author": "MUI Team", "main": "src/index.ts", @@ -50,7 +50,7 @@ "@emotion/styled": "^11.8.1", "@mui/icons-material": "^5.4.1 || ^6.0.0", "@mui/material": "^5.15.14 || ^6.0.0", - "react": "^17.0.0 || ^18.0.0" + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" }, "peerDependenciesMeta": { "@emotion/react": { diff --git a/packages/x-data-grid-generator/src/renderer/renderEditRating.tsx b/packages/x-data-grid-generator/src/renderer/renderEditRating.tsx index 4caf314b9a85..fcd8aa855c50 100644 --- a/packages/x-data-grid-generator/src/renderer/renderEditRating.tsx +++ b/packages/x-data-grid-generator/src/renderer/renderEditRating.tsx @@ -18,7 +18,7 @@ function EditRating(props: GridRenderEditCellParams) { changedThroughKeyboard.current = false; }; - const handleRef = (element: HTMLElement | undefined) => { + const handleRef = (element: HTMLElement | null) => { if (element) { if (value !== 0) { element.querySelector(`input[value="${value}"]`)!.focus(); diff --git a/packages/x-data-grid-premium/README.md b/packages/x-data-grid-premium/README.md index cdb502174687..21ba5482e3c4 100644 --- a/packages/x-data-grid-premium/README.md +++ b/packages/x-data-grid-premium/README.md @@ -16,8 +16,8 @@ This component has the following peer dependencies that you need to install as w ```json "peerDependencies": { "@mui/material": "^5.15.14 || ^6.0.0", - "react": "^17.0.0 || ^18.0.0", - "react-dom": "^17.0.0 || ^18.0.0" + "react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" }, ``` diff --git a/packages/x-data-grid-premium/package.json b/packages/x-data-grid-premium/package.json index 2c0c7c86f30a..a74e53962972 100644 --- a/packages/x-data-grid-premium/package.json +++ b/packages/x-data-grid-premium/package.json @@ -1,6 +1,6 @@ { "name": "@mui/x-data-grid-premium", - "version": "8.0.0-alpha.0", + "version": "8.0.0-alpha.1", "description": "The Premium plan edition of the Data Grid Components (MUI X).", "author": "MUI Team", "main": "src/index.ts", @@ -60,8 +60,8 @@ "@emotion/styled": "^11.8.1", "@mui/material": "^5.15.14 || ^6.0.0", "@mui/system": "^5.15.14 || ^6.0.0", - "react": "^17.0.0 || ^18.0.0", - "react-dom": "^17.0.0 || ^18.0.0" + "react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" }, "peerDependenciesMeta": { "@emotion/react": { diff --git a/packages/x-data-grid-premium/src/tests/rowGrouping.DataGridPremium.test.tsx b/packages/x-data-grid-premium/src/tests/rowGrouping.DataGridPremium.test.tsx index 9f60eb3694cf..f956007843f7 100644 --- a/packages/x-data-grid-premium/src/tests/rowGrouping.DataGridPremium.test.tsx +++ b/packages/x-data-grid-premium/src/tests/rowGrouping.DataGridPremium.test.tsx @@ -1,5 +1,12 @@ import * as React from 'react'; -import { createRenderer, fireEvent, screen, act, waitFor } from '@mui/internal-test-utils'; +import { + createRenderer, + fireEvent, + screen, + act, + waitFor, + reactMajor, +} from '@mui/internal-test-utils'; import { microtasks, getColumnHeaderCell, @@ -666,7 +673,7 @@ describe(' - Row grouping', () => { isGroupExpandedByDefault={isGroupExpandedByDefault} />, ); - expect(isGroupExpandedByDefault.callCount).to.equal(12); // Should not be called on leaves + expect(isGroupExpandedByDefault.callCount).to.equal(reactMajor >= 19 ? 6 : 12); // Should not be called on leaves const { childrenExpanded, ...node } = apiRef.current.state.rows.tree.A as GridGroupNode; const callForNodeA = isGroupExpandedByDefault .getCalls() diff --git a/packages/x-data-grid-pro/README.md b/packages/x-data-grid-pro/README.md index 8f230f5d7d25..4a63af61c3ae 100644 --- a/packages/x-data-grid-pro/README.md +++ b/packages/x-data-grid-pro/README.md @@ -16,8 +16,8 @@ This component has the following peer dependencies that you need to install as w ```json "peerDependencies": { "@mui/material": "^5.15.14 || ^6.0.0", - "react": "^17.0.0 || ^18.0.0", - "react-dom": "^17.0.0 || ^18.0.0" + "react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" }, ``` diff --git a/packages/x-data-grid-pro/package.json b/packages/x-data-grid-pro/package.json index eeb1118bb410..69c790264a4d 100644 --- a/packages/x-data-grid-pro/package.json +++ b/packages/x-data-grid-pro/package.json @@ -1,6 +1,6 @@ { "name": "@mui/x-data-grid-pro", - "version": "8.0.0-alpha.0", + "version": "8.0.0-alpha.1", "description": "The Pro plan edition of the Data Grid components (MUI X).", "author": "MUI Team", "main": "src/index.ts", @@ -58,8 +58,8 @@ "@emotion/styled": "^11.8.1", "@mui/material": "^5.15.14 || ^6.0.0", "@mui/system": "^5.15.14 || ^6.0.0", - "react": "^17.0.0 || ^18.0.0", - "react-dom": "^17.0.0 || ^18.0.0" + "react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" }, "peerDependenciesMeta": { "@emotion/react": { diff --git a/packages/x-data-grid-pro/src/tests/detailPanel.DataGridPro.test.tsx b/packages/x-data-grid-pro/src/tests/detailPanel.DataGridPro.test.tsx index b8e38ff9df4a..115a7b69feeb 100644 --- a/packages/x-data-grid-pro/src/tests/detailPanel.DataGridPro.test.tsx +++ b/packages/x-data-grid-pro/src/tests/detailPanel.DataGridPro.test.tsx @@ -11,7 +11,14 @@ import { GRID_DETAIL_PANEL_TOGGLE_FIELD, } from '@mui/x-data-grid-pro'; import { useBasicDemoData } from '@mui/x-data-grid-generator'; -import { createRenderer, fireEvent, screen, waitFor, act } from '@mui/internal-test-utils'; +import { + createRenderer, + fireEvent, + screen, + waitFor, + act, + reactMajor, +} from '@mui/internal-test-utils'; import { $, $$, grid, getRow, getCell, getColumnValues, microtasks } from 'test/utils/helperFn'; import { fireUserEvent } from 'test/utils/fireUserEvent'; @@ -311,12 +318,18 @@ describe(' - Detail panel', () => { // + 2x during state initialization (StrictMode) // + 2x when sortedRowsSet is fired // + 2x when sortedRowsSet is fired (StrictMode) = 8x - expect(getDetailPanelContent.callCount).to.equal(8); + // Because of https://react.dev/blog/2024/04/25/react-19-upgrade-guide#strict-mode-improvements + // from React 19 it is: + // 2x during state initialization + // + 2x when sortedRowsSet is fired + const expectedCallCount = reactMajor >= 19 ? 4 : 8; + + expect(getDetailPanelContent.callCount).to.equal(expectedCallCount); fireEvent.click(screen.getByRole('button', { name: 'Expand' })); - expect(getDetailPanelContent.callCount).to.equal(8); + expect(getDetailPanelContent.callCount).to.equal(expectedCallCount); fireEvent.click(screen.getByRole('button', { name: /next page/i })); - expect(getDetailPanelContent.callCount).to.equal(8); + expect(getDetailPanelContent.callCount).to.equal(expectedCallCount); const getDetailPanelContent2 = spy(() =>
Detail
); setProps({ getDetailPanelContent: getDetailPanelContent2 }); @@ -342,16 +355,23 @@ describe(' - Detail panel', () => { initialState={{ pagination: { paginationModel: { pageSize: 1 } } }} />, ); + // 2x during state initialization // + 2x during state initialization (StrictMode) // + 2x when sortedRowsSet is fired // + 2x when sortedRowsSet is fired (StrictMode) = 8x - expect(getDetailPanelHeight.callCount).to.equal(8); + // Because of https://react.dev/blog/2024/04/25/react-19-upgrade-guide#strict-mode-improvements + // from React 19 it is: + // 2x during state initialization + // + 2x when sortedRowsSet is fired + const expectedCallCount = reactMajor >= 19 ? 4 : 8; + + expect(getDetailPanelHeight.callCount).to.equal(expectedCallCount); fireEvent.click(screen.getByRole('button', { name: 'Expand' })); - expect(getDetailPanelHeight.callCount).to.equal(8); + expect(getDetailPanelHeight.callCount).to.equal(expectedCallCount); fireEvent.click(screen.getByRole('button', { name: /next page/i })); - expect(getDetailPanelHeight.callCount).to.equal(8); + expect(getDetailPanelHeight.callCount).to.equal(expectedCallCount); const getDetailPanelHeight2 = spy(() => 200); setProps({ getDetailPanelHeight: getDetailPanelHeight2 }); @@ -413,7 +433,13 @@ describe(' - Detail panel', () => { // + 1x during state initialization (StrictMode) // + 1x when sortedRowsSet is fired // + 1x when sortedRowsSet is fired (StrictMode) = 4x - expect(getDetailPanelHeight.callCount).to.equal(4); + // Because of https://react.dev/blog/2024/04/25/react-19-upgrade-guide#strict-mode-improvements + // from React 19 it is: + // 1x during state initialization + // + 1x when sortedRowsSet is fired + const expectedCallCount = reactMajor >= 19 ? 2 : 4; + + expect(getDetailPanelHeight.callCount).to.equal(expectedCallCount); expect(getDetailPanelHeight.lastCall.args[0].id).to.equal(0); }); @@ -478,8 +504,8 @@ describe(' - Detail panel', () => { it('should not reuse detail panel components', () => { let counter = 0; function DetailPanel() { - const [number] = React.useState((counter += 1)); - return
{number}
; + counter += 1; + return
{counter}
; } const { setProps } = render( } detailPanelExpandedRowIds={[0]} />, diff --git a/packages/x-data-grid-pro/src/tests/infiniteLoader.DataGridPro.test.tsx b/packages/x-data-grid-pro/src/tests/infiniteLoader.DataGridPro.test.tsx index 350aa89568c4..5f8b9422490b 100644 --- a/packages/x-data-grid-pro/src/tests/infiniteLoader.DataGridPro.test.tsx +++ b/packages/x-data-grid-pro/src/tests/infiniteLoader.DataGridPro.test.tsx @@ -108,7 +108,6 @@ describe(' - Infnite loader', () => { const [loading, setLoading] = React.useState(false); const handleRowsScrollEnd = React.useCallback(async () => { setLoading(true); - await sleep(50); setRows((prevRows) => { const lastRowId = prevRows[prevRows.length - 1].id; const nextRow = getRow(lastRowId + 1); @@ -137,45 +136,20 @@ describe(' - Infnite loader', () => { // 1 initial row // 5 rows loaded one by one through `onRowsScrollEnd` callback - expect(getColumnValues(0)).to.deep.equal(['0']); + const multiplier = 2; // `setRows` is called twice for each `handleRowsScrollEnd` call await waitFor(() => { - expect(getRow.callCount).to.equal(1); - }); - await waitFor(() => { - expect(getColumnValues(0)).to.deep.equal(['0', '1']); - }); - - await waitFor(() => { - expect(getRow.callCount).to.equal(2); - }); - await waitFor(() => { - expect(getColumnValues(0)).to.deep.equal(['0', '1', '2']); - }); - - await waitFor(() => { - expect(getRow.callCount).to.equal(3); - }); - await waitFor(() => { - expect(getColumnValues(0)).to.deep.equal(['0', '1', '2', '3']); + expect(getRow.callCount).to.equal(5 * multiplier); }); - await waitFor(() => { - expect(getRow.callCount).to.equal(4); - }); - await waitFor(() => { - expect(getColumnValues(0)).to.deep.equal(['0', '1', '2', '3', '4']); - }); + const getRowCalls = getRow.getCalls(); + for (let callIndex = 0; callIndex < getRowCalls.length; callIndex += multiplier) { + const call = getRowCalls[callIndex]; + expect(call.returnValue?.id).to.equal(callIndex / multiplier + 1); + } - await waitFor(() => { - expect(getRow.callCount).to.equal(5); - }); await waitFor(() => { expect(getColumnValues(0)).to.deep.equal(['0', '1', '2', '3', '4', '5']); }); - - await sleep(200); - // should not load more rows because the threshold is not reached - expect(getRow.callCount).to.equal(5); }); it('should not observe intersections with the rows pinned to the bottom', async function test() { diff --git a/packages/x-data-grid-pro/src/tests/treeData.DataGridPro.test.tsx b/packages/x-data-grid-pro/src/tests/treeData.DataGridPro.test.tsx index 61a722c634f8..8ba96004f225 100644 --- a/packages/x-data-grid-pro/src/tests/treeData.DataGridPro.test.tsx +++ b/packages/x-data-grid-pro/src/tests/treeData.DataGridPro.test.tsx @@ -1,4 +1,4 @@ -import { createRenderer, fireEvent, screen, act } from '@mui/internal-test-utils'; +import { createRenderer, fireEvent, screen, act, reactMajor } from '@mui/internal-test-utils'; import { getCell, getColumnHeaderCell, @@ -286,7 +286,7 @@ describe(' - Tree data', () => { const isGroupExpandedByDefault = spy((node: GridGroupNode) => node.id === 'A'); render(); - expect(isGroupExpandedByDefault.callCount).to.equal(8); // Should not be called on leaves + expect(isGroupExpandedByDefault.callCount).to.equal(reactMajor >= 19 ? 4 : 8); // Should not be called on leaves const { childrenExpanded, children, childrenFromPath, ...node } = apiRef.current.state.rows .tree.A as GridGroupNode; const callForNodeA = isGroupExpandedByDefault diff --git a/packages/x-data-grid/README.md b/packages/x-data-grid/README.md index e8af2fbf99ab..fab185d4804f 100644 --- a/packages/x-data-grid/README.md +++ b/packages/x-data-grid/README.md @@ -16,8 +16,8 @@ This component has the following peer dependencies that you need to install as w ```json "peerDependencies": { "@mui/material": "^5.15.14 || ^6.0.0", - "react": "^17.0.0 || ^18.0.0", - "react-dom": "^17.0.0 || ^18.0.0" + "react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" }, ``` diff --git a/packages/x-data-grid/package.json b/packages/x-data-grid/package.json index a2bceebaa950..7bdd01078ad4 100644 --- a/packages/x-data-grid/package.json +++ b/packages/x-data-grid/package.json @@ -1,6 +1,6 @@ { "name": "@mui/x-data-grid", - "version": "8.0.0-alpha.0", + "version": "8.0.0-alpha.1", "description": "The Community plan edition of the Data Grid components (MUI X).", "author": "MUI Team", "main": "src/index.ts", @@ -59,8 +59,8 @@ "@emotion/styled": "^11.8.1", "@mui/material": "^5.15.14 || ^6.0.0", "@mui/system": "^5.15.14 || ^6.0.0", - "react": "^17.0.0 || ^18.0.0", - "react-dom": "^17.0.0 || ^18.0.0" + "react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" }, "peerDependenciesMeta": { "@emotion/react": { diff --git a/packages/x-data-grid/src/hooks/utils/useGridApiEventHandler.test.tsx b/packages/x-data-grid/src/hooks/utils/useGridApiEventHandler.test.tsx index 1ee0bd2c105f..35df8e23d954 100644 --- a/packages/x-data-grid/src/hooks/utils/useGridApiEventHandler.test.tsx +++ b/packages/x-data-grid/src/hooks/utils/useGridApiEventHandler.test.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; import { spy } from 'sinon'; import { expect } from 'chai'; -import { createRenderer } from '@mui/internal-test-utils'; +import { createRenderer, reactMajor } from '@mui/internal-test-utils'; import { sleep } from 'test/utils/helperFn'; import { createUseGridApiEventHandler } from './useGridApiEventHandler'; import { FinalizationRegistryBasedCleanupTracking } from '../../utils/cleanupTracking/FinalizationRegistryBasedCleanupTracking'; @@ -42,14 +42,17 @@ describe('useGridApiEventHandler', () => { // which makes 2 event listeners to be registered. Since the second render is never // committed (to simulate a trashed render in React 18), the effects also don't run, so we're // unable to unsubscribe the last listener using the cleanup function. - expect(apiRef.current.subscribeEvent.callCount).to.equal(3); + // Since React 19, StrictMode works differently + // https://react.dev/blog/2024/04/25/react-19-upgrade-guide#strict-mode-improvements + const expectedCallCount = reactMajor >= 19 ? 1 : 3; + expect(apiRef.current.subscribeEvent.callCount).to.equal(expectedCallCount); unmount(); global.gc(); // Triggers garbage collector await sleep(50); // Ensure that both event listeners were unsubscribed - expect(unsubscribe.callCount).to.equal(3); + expect(unsubscribe.callCount).to.equal(expectedCallCount); }); }); @@ -74,13 +77,16 @@ describe('useGridApiEventHandler', () => { // which makes 2 event listeners to be registered. Since the second render is never // committed (to simulate a trashed render in React 18), the effects also don't run, so we're // unable to unsubscribe the last listener using the cleanup function. - expect(apiRef.current.subscribeEvent.callCount).to.equal(3); + // Since React 19, StrictMode works differently + // https://react.dev/blog/2024/04/25/react-19-upgrade-guide#strict-mode-improvements + const expectedCallCount = reactMajor >= 19 ? 1 : 3; + expect(apiRef.current.subscribeEvent.callCount).to.equal(expectedCallCount); unmount(); await sleep(60); - // Ensure that both event listeners were unsubscribed - expect(unsubscribe.callCount).to.equal(3); + // Ensure that all event listeners were unsubscribed + expect(unsubscribe.callCount).to.equal(expectedCallCount); }); }); }); diff --git a/packages/x-data-grid/src/joy/joySlots.tsx b/packages/x-data-grid/src/joy/joySlots.tsx index a5645d892066..a4baffb0dabf 100644 --- a/packages/x-data-grid/src/joy/joySlots.tsx +++ b/packages/x-data-grid/src/joy/joySlots.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; import { SxProps } from '@mui/system'; import { ColorPaletteProp, Theme, VariantProp } from '@mui/joy/styles'; -import JoyBadge from '@mui/joy/Badge'; +import JoyBadge, { BadgeOrigin } from '@mui/joy/Badge'; import JoyCheckbox from '@mui/joy/Checkbox'; import JoyDivider from '@mui/joy/Divider'; import JoyInput from '@mui/joy/Input'; @@ -72,10 +72,15 @@ function convertVariant>( - ({ slotProps, variant, color, sx, ...props }, ref) => { + ({ slotProps, variant, color, sx, anchorOrigin, ...props }, ref) => { return ( } diff --git a/packages/x-data-grid/src/locales/esES.ts b/packages/x-data-grid/src/locales/esES.ts index 25ee23998fba..f4cecbda13d3 100644 --- a/packages/x-data-grid/src/locales/esES.ts +++ b/packages/x-data-grid/src/locales/esES.ts @@ -32,16 +32,17 @@ const esESGrid: Partial = { toolbarQuickFilterDeleteIconLabel: 'Limpiar', // Prompt toolbar field - // toolbarPromptControlPlaceholder: 'Type a promptā€¦', - // toolbarPromptControlWithRecordingPlaceholder: 'Type or record a promptā€¦', - // toolbarPromptControlRecordingPlaceholder: 'Listening for promptā€¦', - // toolbarPromptControlLabel: 'Prompt input', - // toolbarPromptControlDeleteIconLabel: 'Clear', - // toolbarPromptControlRecordButtonDefaultLabel: 'Record', - // toolbarPromptControlRecordButtonActiveLabel: 'Stop recording', - // toolbarPromptControlSendActionLabel: 'Send', - // toolbarPromptControlSendActionAriaLabel: 'Send prompt', - // toolbarPromptControlErrorMessage: 'An error occurred while processing the request. Please try again with a different prompt.', + toolbarPromptControlPlaceholder: 'Escriba un promptā€¦', + toolbarPromptControlWithRecordingPlaceholder: 'Escriba o grabe un promptā€¦', + toolbarPromptControlRecordingPlaceholder: 'Esperando por un promptā€¦', + toolbarPromptControlLabel: 'Introduzca un prompt', + toolbarPromptControlDeleteIconLabel: 'Limpiar', + toolbarPromptControlRecordButtonDefaultLabel: 'Grabar', + toolbarPromptControlRecordButtonActiveLabel: 'Parar de grabar', + toolbarPromptControlSendActionLabel: 'Enviar', + toolbarPromptControlSendActionAriaLabel: 'Enviar prompt', + toolbarPromptControlErrorMessage: + 'OcurriĆ³ un error mientras se procesaba la peticiĆ³n. Por favor, intente de nuevo con otro prompt.', // Export selector toolbar button text toolbarExport: 'Exportar', @@ -55,7 +56,7 @@ const esESGrid: Partial = { columnsManagementNoColumns: 'Sin columnas', columnsManagementShowHideAllText: 'Mostrar/Ocultar todas', columnsManagementReset: 'Restablecer', - // columnsManagementDeleteIconLabel: 'Clear', + columnsManagementDeleteIconLabel: 'Limpiar', // Filter panel text filterPanelAddFilter: 'Agregar filtro', diff --git a/packages/x-data-grid/src/locales/ptBR.ts b/packages/x-data-grid/src/locales/ptBR.ts index df742838bff8..d514af7e0460 100644 --- a/packages/x-data-grid/src/locales/ptBR.ts +++ b/packages/x-data-grid/src/locales/ptBR.ts @@ -32,16 +32,17 @@ const ptBRGrid: Partial = { toolbarQuickFilterDeleteIconLabel: 'Limpar', // Prompt toolbar field - // toolbarPromptControlPlaceholder: 'Type a promptā€¦', - // toolbarPromptControlWithRecordingPlaceholder: 'Type or record a promptā€¦', - // toolbarPromptControlRecordingPlaceholder: 'Listening for promptā€¦', - // toolbarPromptControlLabel: 'Prompt input', - // toolbarPromptControlDeleteIconLabel: 'Clear', - // toolbarPromptControlRecordButtonDefaultLabel: 'Record', - // toolbarPromptControlRecordButtonActiveLabel: 'Stop recording', - // toolbarPromptControlSendActionLabel: 'Send', - // toolbarPromptControlSendActionAriaLabel: 'Send prompt', - // toolbarPromptControlErrorMessage: 'An error occurred while processing the request. Please try again with a different prompt.', + toolbarPromptControlPlaceholder: 'Digite um promptā€¦', + toolbarPromptControlWithRecordingPlaceholder: 'Digite ou grave um promptā€¦', + toolbarPromptControlRecordingPlaceholder: 'Ouvindo o promptā€¦', + toolbarPromptControlLabel: 'Entrada de prompt', + toolbarPromptControlDeleteIconLabel: 'Limpar', + toolbarPromptControlRecordButtonDefaultLabel: 'Gravar', + toolbarPromptControlRecordButtonActiveLabel: 'Parar gravaĆ§Ć£o', + toolbarPromptControlSendActionLabel: 'Enviar', + toolbarPromptControlSendActionAriaLabel: 'Enviar prompt', + toolbarPromptControlErrorMessage: + 'Ocorreu um erro ao processar a solicitaĆ§Ć£o. Por favor, tente novamente com um prompt diferente.', // Export selector toolbar button text toolbarExport: 'Exportar', @@ -55,7 +56,7 @@ const ptBRGrid: Partial = { columnsManagementNoColumns: 'Nenhuma coluna', columnsManagementShowHideAllText: 'Mostrar/Ocultar Todas', columnsManagementReset: 'Redefinir', - // columnsManagementDeleteIconLabel: 'Clear', + columnsManagementDeleteIconLabel: 'Limpar', // Filter panel text filterPanelAddFilter: 'Adicionar filtro', diff --git a/packages/x-data-grid/src/locales/ptPT.ts b/packages/x-data-grid/src/locales/ptPT.ts index ee6f9ae387f3..af84bf334302 100644 --- a/packages/x-data-grid/src/locales/ptPT.ts +++ b/packages/x-data-grid/src/locales/ptPT.ts @@ -32,16 +32,17 @@ const ptPTGrid: Partial = { toolbarQuickFilterDeleteIconLabel: 'Claro', // Prompt toolbar field - // toolbarPromptControlPlaceholder: 'Type a promptā€¦', - // toolbarPromptControlWithRecordingPlaceholder: 'Type or record a promptā€¦', - // toolbarPromptControlRecordingPlaceholder: 'Listening for promptā€¦', - // toolbarPromptControlLabel: 'Prompt input', - // toolbarPromptControlDeleteIconLabel: 'Clear', - // toolbarPromptControlRecordButtonDefaultLabel: 'Record', - // toolbarPromptControlRecordButtonActiveLabel: 'Stop recording', - // toolbarPromptControlSendActionLabel: 'Send', - // toolbarPromptControlSendActionAriaLabel: 'Send prompt', - // toolbarPromptControlErrorMessage: 'An error occurred while processing the request. Please try again with a different prompt.', + toolbarPromptControlPlaceholder: 'Digite um promptā€¦', + toolbarPromptControlWithRecordingPlaceholder: 'Digite ou grave um promptā€¦', + toolbarPromptControlRecordingPlaceholder: 'Ouvindo o promptā€¦', + toolbarPromptControlLabel: 'Entrada de prompt', + toolbarPromptControlDeleteIconLabel: 'Limpar', + toolbarPromptControlRecordButtonDefaultLabel: 'Gravar', + toolbarPromptControlRecordButtonActiveLabel: 'Parar gravaĆ§Ć£o', + toolbarPromptControlSendActionLabel: 'Enviar', + toolbarPromptControlSendActionAriaLabel: 'Enviar prompt', + toolbarPromptControlErrorMessage: + 'Ocorreu um erro ao processar a solicitaĆ§Ć£o. Por favor, tente novamente com um prompt diferente.', // Export selector toolbar button text toolbarExport: 'Exportar', @@ -55,7 +56,7 @@ const ptPTGrid: Partial = { columnsManagementNoColumns: 'Sem colunas', columnsManagementShowHideAllText: 'Mostrar/Ocultar Todas', columnsManagementReset: 'Repor', - // columnsManagementDeleteIconLabel: 'Clear', + columnsManagementDeleteIconLabel: 'Limpar', // Filter panel text filterPanelAddFilter: 'Adicionar filtro', diff --git a/packages/x-data-grid/src/tests/layout.DataGrid.test.tsx b/packages/x-data-grid/src/tests/layout.DataGrid.test.tsx index f92b82e0dc2f..cd4d6d324bb5 100644 --- a/packages/x-data-grid/src/tests/layout.DataGrid.test.tsx +++ b/packages/x-data-grid/src/tests/layout.DataGrid.test.tsx @@ -1,5 +1,11 @@ import * as React from 'react'; -import { createRenderer, screen, ErrorBoundary, waitFor } from '@mui/internal-test-utils'; +import { + createRenderer, + screen, + ErrorBoundary, + waitFor, + reactMajor, +} from '@mui/internal-test-utils'; import { stub, spy } from 'sinon'; import { expect } from 'chai'; import { @@ -960,8 +966,9 @@ describe(' - Layout & warnings', () => { ); }).toErrorDev([ 'The Data Grid component requires all rows to have a unique `id` property', - 'The Data Grid component requires all rows to have a unique `id` property', - 'The above error occurred in the component', + reactMajor < 19 && + 'The Data Grid component requires all rows to have a unique `id` property', + reactMajor < 19 && 'The above error occurred in the component', ]); expect((errorRef.current as any).errors).to.have.length(1); expect((errorRef.current as any).errors[0].toString()).to.include( @@ -1283,8 +1290,8 @@ describe(' - Layout & warnings', () => { , ); }).toErrorDev([ - 'Warning: Encountered two children with the same key, `id`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted ā€” the behavior is unsupported and could change in a future version.', - 'Warning: Encountered two children with the same key, `id`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted ā€” the behavior is unsupported and could change in a future version.', + 'Encountered two children with the same key, `id`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted ā€” the behavior is unsupported and could change in a future version.', + 'Encountered two children with the same key, `id`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted ā€” the behavior is unsupported and could change in a future version.', ]); }); diff --git a/packages/x-data-grid/src/tests/pagination.DataGrid.test.tsx b/packages/x-data-grid/src/tests/pagination.DataGrid.test.tsx index 94421d70f768..002a0d18ccad 100644 --- a/packages/x-data-grid/src/tests/pagination.DataGrid.test.tsx +++ b/packages/x-data-grid/src/tests/pagination.DataGrid.test.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; import { spy, stub, SinonStub, SinonSpy } from 'sinon'; import { expect } from 'chai'; -import { createRenderer, fireEvent, screen, waitFor } from '@mui/internal-test-utils'; +import { createRenderer, fireEvent, reactMajor, screen, waitFor } from '@mui/internal-test-utils'; import { DataGrid, DataGridProps, @@ -324,7 +324,8 @@ describe(' - Pagination', () => { ); }).toWarnDev([ `MUI X: The page size \`${pageSize}\` is not present in the \`pageSizeOptions\``, - `MUI X: The page size \`${pageSize}\` is not present in the \`pageSizeOptions\``, + reactMajor < 19 && + `MUI X: The page size \`${pageSize}\` is not present in the \`pageSizeOptions\``, ]); }); @@ -352,7 +353,8 @@ describe(' - Pagination', () => { render(); }).toWarnDev([ `MUI X: The page size \`${pageSize}\` is not present in the \`pageSizeOptions\``, - `MUI X: The page size \`${pageSize}\` is not present in the \`pageSizeOptions\``, + reactMajor < 19 && + `MUI X: The page size \`${pageSize}\` is not present in the \`pageSizeOptions\``, ]); }); @@ -361,7 +363,7 @@ describe(' - Pagination', () => { render(); }).toWarnDev([ `MUI X: The page size \`100\` is not present in the \`pageSizeOptions\``, - `MUI X: The page size \`100\` is not present in the \`pageSizeOptions\``, + reactMajor < 19 && `MUI X: The page size \`100\` is not present in the \`pageSizeOptions\``, ]); }); diff --git a/packages/x-data-grid/src/tests/quickFiltering.DataGrid.test.tsx b/packages/x-data-grid/src/tests/quickFiltering.DataGrid.test.tsx index 44d608d5602f..8f1153174c38 100644 --- a/packages/x-data-grid/src/tests/quickFiltering.DataGrid.test.tsx +++ b/packages/x-data-grid/src/tests/quickFiltering.DataGrid.test.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import { createRenderer, screen, fireEvent } from '@mui/internal-test-utils'; +import { createRenderer, screen, fireEvent, reactMajor } from '@mui/internal-test-utils'; import { expect } from 'chai'; import { spy } from 'sinon'; import { @@ -313,18 +313,21 @@ describe(' - Quick filter', () => { />, ); + // Because of https://react.dev/blog/2024/04/25/react-19-upgrade-guide#strict-mode-improvements + const initialCallCount = reactMajor >= 19 ? 1 : 2; + expect(getColumnValues(0)).to.deep.equal(['1']); - expect(getApplyQuickFilterFnSpy.callCount).to.equal(2); + expect(getApplyQuickFilterFnSpy.callCount).to.equal(initialCallCount); setProps({ columnVisibilityModel: { brand: false } }); clock.runToLast(); expect(getColumnValues(0)).to.deep.equal([]); - expect(getApplyQuickFilterFnSpy.callCount).to.equal(3); + expect(getApplyQuickFilterFnSpy.callCount).to.equal(initialCallCount + 1); setProps({ columnVisibilityModel: { brand: true } }); clock.runToLast(); expect(getColumnValues(0)).to.deep.equal(['1']); - expect(getApplyQuickFilterFnSpy.callCount).to.equal(4); + expect(getApplyQuickFilterFnSpy.callCount).to.equal(initialCallCount + 2); }); it('should not apply filters on column visibility change when quickFilterExcludeHiddenColumns=true but no quick filter values', () => { @@ -380,18 +383,21 @@ describe(' - Quick filter', () => { />, ); + // Because of https://react.dev/blog/2024/04/25/react-19-upgrade-guide#strict-mode-improvements + const initialCallCount = reactMajor >= 19 ? 1 : 2; + expect(getColumnValues(0)).to.deep.equal(['1']); - expect(getApplyQuickFilterFnSpy.callCount).to.equal(2); + expect(getApplyQuickFilterFnSpy.callCount).to.equal(initialCallCount); setProps({ columnVisibilityModel: { brand: false } }); clock.runToLast(); expect(getColumnValues(0)).to.deep.equal(['1']); - expect(getApplyQuickFilterFnSpy.callCount).to.equal(2); + expect(getApplyQuickFilterFnSpy.callCount).to.equal(initialCallCount); setProps({ columnVisibilityModel: { brand: true } }); clock.runToLast(); expect(getColumnValues(0)).to.deep.equal(['1']); - expect(getApplyQuickFilterFnSpy.callCount).to.equal(2); + expect(getApplyQuickFilterFnSpy.callCount).to.equal(initialCallCount); }); }); diff --git a/packages/x-data-grid/src/tests/rows.DataGrid.test.tsx b/packages/x-data-grid/src/tests/rows.DataGrid.test.tsx index 4d222603334b..771ee43a173d 100644 --- a/packages/x-data-grid/src/tests/rows.DataGrid.test.tsx +++ b/packages/x-data-grid/src/tests/rows.DataGrid.test.tsx @@ -6,6 +6,7 @@ import { act, ErrorBoundary, waitFor, + reactMajor, } from '@mui/internal-test-utils'; import clsx from 'clsx'; import { expect } from 'chai'; @@ -254,8 +255,8 @@ describe(' - Rows', () => { ); }).toErrorDev([ 'MUI X: Missing the `getActions` property in the `GridColDef`.', - 'MUI X: Missing the `getActions` property in the `GridColDef`.', - 'The above error occurred in the component', + reactMajor < 19 && 'MUI X: Missing the `getActions` property in the `GridColDef`.', + reactMajor < 19 && 'The above error occurred in the component', ]); }); diff --git a/packages/x-data-grid/src/tests/slots.DataGrid.test.tsx b/packages/x-data-grid/src/tests/slots.DataGrid.test.tsx index 0aa832db0d5f..055f24b47059 100644 --- a/packages/x-data-grid/src/tests/slots.DataGrid.test.tsx +++ b/packages/x-data-grid/src/tests/slots.DataGrid.test.tsx @@ -1,5 +1,11 @@ import * as React from 'react'; -import { createRenderer, ErrorBoundary, fireEvent, screen } from '@mui/internal-test-utils'; +import { + createRenderer, + ErrorBoundary, + fireEvent, + reactMajor, + screen, +} from '@mui/internal-test-utils'; import { expect } from 'chai'; import { spy } from 'sinon'; import { DataGrid, DataGridProps, GridOverlay } from '@mui/x-data-grid'; @@ -169,8 +175,9 @@ describe(' - Slots', () => { ); }).toErrorDev([ 'MUI X: useGridRootProps should only be used inside the DataGrid, DataGridPro or DataGridPremium component.', - 'MUI X: useGridRootProps should only be used inside the DataGrid, DataGridPro or DataGridPremium component.', - 'The above error occurred in the component', + reactMajor < 19 && + 'MUI X: useGridRootProps should only be used inside the DataGrid, DataGridPro or DataGridPremium component.', + reactMajor < 19 && 'The above error occurred in the component', ]); }); diff --git a/packages/x-date-pickers-pro/README.md b/packages/x-date-pickers-pro/README.md index 5e6e0bd885c1..7aa6eabaaba4 100644 --- a/packages/x-date-pickers-pro/README.md +++ b/packages/x-date-pickers-pro/README.md @@ -35,8 +35,8 @@ This component has the following peer dependencies that you need to install as w ```json "peerDependencies": { "@mui/material": "^5.15.14 || ^6.0.0", - "react": "^17.0.0 || ^18.0.0", - "react-dom": "^17.0.0 || ^18.0.0" + "react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" }, ``` diff --git a/packages/x-date-pickers-pro/package.json b/packages/x-date-pickers-pro/package.json index 61be276118ab..7ea584efa229 100644 --- a/packages/x-date-pickers-pro/package.json +++ b/packages/x-date-pickers-pro/package.json @@ -1,6 +1,6 @@ { "name": "@mui/x-date-pickers-pro", - "version": "8.0.0-alpha.0", + "version": "8.0.0-alpha.1", "description": "The Pro plan edition of the Date and Time Picker components (MUI X).", "author": "MUI Team", "main": "src/index.ts", @@ -63,8 +63,8 @@ "moment": "^2.29.4", "moment-hijri": "^2.1.2 || ^3.0.0", "moment-jalaali": "^0.7.4 || ^0.8.0 || ^0.9.0 || ^0.10.0", - "react": "^17.0.0 || ^18.0.0", - "react-dom": "^17.0.0 || ^18.0.0" + "react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" }, "peerDependenciesMeta": { "@emotion/react": { diff --git a/packages/x-date-pickers-pro/src/MobileDateRangePicker/tests/describes.MobileDateRangePicker.test.tsx b/packages/x-date-pickers-pro/src/MobileDateRangePicker/tests/describes.MobileDateRangePicker.test.tsx index 981bd8819f28..3d5b9c2013bc 100644 --- a/packages/x-date-pickers-pro/src/MobileDateRangePicker/tests/describes.MobileDateRangePicker.test.tsx +++ b/packages/x-date-pickers-pro/src/MobileDateRangePicker/tests/describes.MobileDateRangePicker.test.tsx @@ -87,9 +87,9 @@ describe(' - Describes', () => { } fireEvent.click( - screen.getAllByRole('gridcell', { + screen.getByRole('gridcell', { name: adapterToUse.getDate(newValue[setEndDate ? 1 : 0]).toString(), - })[0], + }), ); // Close the picker diff --git a/packages/x-date-pickers-pro/src/internals/hooks/useEnrichedRangePickerFieldProps.ts b/packages/x-date-pickers-pro/src/internals/hooks/useEnrichedRangePickerFieldProps.ts index 311e018ce3c0..17ffbc770c21 100644 --- a/packages/x-date-pickers-pro/src/internals/hooks/useEnrichedRangePickerFieldProps.ts +++ b/packages/x-date-pickers-pro/src/internals/hooks/useEnrichedRangePickerFieldProps.ts @@ -173,7 +173,7 @@ const useMultiInputFieldSlotProps = < const previousRangePosition = React.useRef(rangePosition); React.useEffect(() => { - if (!open) { + if (!open || variant === 'mobile') { return; } @@ -191,7 +191,7 @@ const useMultiInputFieldSlotProps = < previousRangePosition.current === rangePosition ? currentView : 0, ); previousRangePosition.current = rangePosition; - }, [rangePosition, open, currentView, startFieldRef, endFieldRef]); + }, [rangePosition, open, currentView, startFieldRef, endFieldRef, variant]); const openRangeStartSelection: React.UIEventHandler = (event) => { event.stopPropagation(); @@ -345,7 +345,7 @@ const useSingleInputFieldSlotProps = < const handleFieldRef = useForkRef(fieldProps.unstableFieldRef, startFieldRef, endFieldRef); React.useEffect(() => { - if (!open || !startFieldRef.current) { + if (!open || !startFieldRef.current || variant === 'mobile') { return; } @@ -362,7 +362,7 @@ const useSingleInputFieldSlotProps = < : sections.lastIndexOf(currentView); startFieldRef.current?.focusField(newSelectedSection); } - }, [rangePosition, open, currentView, startFieldRef]); + }, [rangePosition, open, currentView, startFieldRef, variant]); const updateRangePosition = () => { if (!startFieldRef.current?.isFieldFocused()) { diff --git a/packages/x-date-pickers/README.md b/packages/x-date-pickers/README.md index b66cfe572b1a..c070227afa4a 100644 --- a/packages/x-date-pickers/README.md +++ b/packages/x-date-pickers/README.md @@ -35,8 +35,8 @@ This component has the following peer dependencies that you need to install as w ```json "peerDependencies": { "@mui/material": "^5.15.14 || ^6.0.0", - "react": "^17.0.0 || ^18.0.0", - "react-dom": "^17.0.0 || ^18.0.0" + "react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" }, ``` diff --git a/packages/x-date-pickers/package.json b/packages/x-date-pickers/package.json index 7fc7cbf92d8e..8683eaf1569d 100644 --- a/packages/x-date-pickers/package.json +++ b/packages/x-date-pickers/package.json @@ -1,6 +1,6 @@ { "name": "@mui/x-date-pickers", - "version": "8.0.0-alpha.0", + "version": "8.0.0-alpha.1", "description": "The community edition of the Date and Time Picker components (MUI X).", "author": "MUI Team", "main": "src/index.ts", @@ -65,8 +65,8 @@ "moment": "^2.29.4", "moment-hijri": "^2.1.2 || ^3.0.0", "moment-jalaali": "^0.7.4 || ^0.8.0 || ^0.9.0 || ^0.10.0", - "react": "^17.0.0 || ^18.0.0", - "react-dom": "^17.0.0 || ^18.0.0" + "react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" }, "peerDependenciesMeta": { "@emotion/react": { diff --git a/packages/x-date-pickers/src/locales/nlNL.ts b/packages/x-date-pickers/src/locales/nlNL.ts index a8f167718b2c..18de679b02f4 100644 --- a/packages/x-date-pickers/src/locales/nlNL.ts +++ b/packages/x-date-pickers/src/locales/nlNL.ts @@ -25,10 +25,10 @@ const nlNLPickers: Partial = { // DateRange labels start: 'Start', end: 'Einde', - startDate: 'Start datum', - startTime: 'Start tijd', - endDate: 'Eind datum', - endTime: 'Eind tijd', + startDate: 'Startdatum', + startTime: 'Starttijd', + endDate: 'Einddatum', + endTime: 'Eindtijd', // Action bar cancelButtonLabel: 'Annuleren', @@ -70,11 +70,11 @@ const nlNLPickers: Partial = { dateTableLabel: 'kies datum', // Field section placeholders - fieldYearPlaceholder: (params) => 'Y'.repeat(params.digitAmount), + fieldYearPlaceholder: (params) => 'J'.repeat(params.digitAmount), fieldMonthPlaceholder: (params) => (params.contentType === 'letter' ? 'MMMM' : 'MM'), fieldDayPlaceholder: () => 'DD', fieldWeekDayPlaceholder: (params) => (params.contentType === 'letter' ? 'EEEE' : 'EE'), - fieldHoursPlaceholder: () => 'hh', + fieldHoursPlaceholder: () => 'uu', fieldMinutesPlaceholder: () => 'mm', fieldSecondsPlaceholder: () => 'ss', fieldMeridiemPlaceholder: () => 'aa', @@ -90,7 +90,7 @@ const nlNLPickers: Partial = { meridiem: 'Middag', // Common - empty: 'Legen', + empty: 'Leeg', }; export const nlNL = getPickersLocalization(nlNLPickers); diff --git a/packages/x-internals/package.json b/packages/x-internals/package.json index da0d9307e5ee..3ed76021fadc 100644 --- a/packages/x-internals/package.json +++ b/packages/x-internals/package.json @@ -1,6 +1,6 @@ { "name": "@mui/x-internals", - "version": "8.0.0-alpha.0", + "version": "8.0.0-alpha.1", "description": "Utility functions for the MUI X packages (internal use only).", "author": "MUI Team", "license": "MIT", @@ -45,7 +45,7 @@ "@mui/utils": "^5.16.6 || ^6.0.0" }, "peerDependencies": { - "react": "^17.0.0 || ^18.0.0" + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" }, "devDependencies": { "@mui/internal-test-utils": "^1.0.21", diff --git a/packages/x-license/package.json b/packages/x-license/package.json index 8e7c67cef294..e6d702347272 100644 --- a/packages/x-license/package.json +++ b/packages/x-license/package.json @@ -1,6 +1,6 @@ { "name": "@mui/x-license", - "version": "8.0.0-alpha.0", + "version": "8.0.0-alpha.1", "description": "MUI X License verification", "author": "MUI Team", "main": "src/index.ts", @@ -38,7 +38,7 @@ "@mui/utils": "^5.16.6 || ^6.0.0" }, "peerDependencies": { - "react": "^17.0.0 || ^18.0.0" + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" }, "devDependencies": { "@mui/internal-test-utils": "^1.0.21", diff --git a/packages/x-license/src/useLicenseVerifier/useLicenseVerifier.test.tsx b/packages/x-license/src/useLicenseVerifier/useLicenseVerifier.test.tsx index 7605292c6acd..1cfd9ab49dd6 100644 --- a/packages/x-license/src/useLicenseVerifier/useLicenseVerifier.test.tsx +++ b/packages/x-license/src/useLicenseVerifier/useLicenseVerifier.test.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; import { expect } from 'chai'; -import { createRenderer, screen } from '@mui/internal-test-utils'; +import { createRenderer, ErrorBoundary, reactMajor, screen } from '@mui/internal-test-utils'; import { useLicenseVerifier, LicenseInfo, @@ -94,19 +94,20 @@ describe('useLicenseVerifier', function test() { }); LicenseInfo.setLicenseKey(expiredLicenseKey); - let actualErrorMsg; + const errorRef = React.createRef(); + expect(() => { - try { - render(); - } catch (error: any) { - actualErrorMsg = error.message; - } + render( + + + , + ); }).to.toErrorDev([ 'MUI X: Expired license key', - 'MUI X: Expired license key', - 'The above error occurred in the component', + reactMajor < 19 && 'MUI X: Expired license key', + reactMajor < 19 && 'The above error occurred in the component', ]); - expect(actualErrorMsg).to.match(/MUI X: Expired license key/); + expect((errorRef.current as any).errors[0].toString()).to.match(/MUI X: Expired license key/); }); it('should throw if the license is not covering charts and tree-view', () => { diff --git a/packages/x-tree-view-pro/README.md b/packages/x-tree-view-pro/README.md index b9177bb79f5f..3a7069bf7545 100644 --- a/packages/x-tree-view-pro/README.md +++ b/packages/x-tree-view-pro/README.md @@ -16,8 +16,8 @@ This component has the following peer dependencies that you need to install as w ```json "peerDependencies": { "@mui/material": "^5.15.14 || ^6.0.0", - "react": "^17.0.0 || ^18.0.0", - "react-dom": "^17.0.0 || ^18.0.0" + "react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" }, ``` diff --git a/packages/x-tree-view-pro/package.json b/packages/x-tree-view-pro/package.json index f02df842b6f4..aec8767f29bb 100644 --- a/packages/x-tree-view-pro/package.json +++ b/packages/x-tree-view-pro/package.json @@ -1,6 +1,6 @@ { "name": "@mui/x-tree-view-pro", - "version": "8.0.0-alpha.0", + "version": "8.0.0-alpha.1", "description": "The Pro plan edition of the Tree View components (MUI X).", "author": "MUI Team", "main": "src/index.ts", @@ -60,8 +60,8 @@ "@emotion/styled": "^11.8.1", "@mui/material": "^5.15.14 || ^6.0.0", "@mui/system": "^5.15.14 || ^6.0.0", - "react": "^17.0.0 || ^18.0.0", - "react-dom": "^17.0.0 || ^18.0.0" + "react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" }, "peerDependenciesMeta": { "@emotion/react": { diff --git a/packages/x-tree-view/README.md b/packages/x-tree-view/README.md index 6b16d4b1273f..54023a0abf6e 100644 --- a/packages/x-tree-view/README.md +++ b/packages/x-tree-view/README.md @@ -16,8 +16,8 @@ This component has the following peer dependencies that you need to install as w ```json "peerDependencies": { "@mui/material": "^5.15.14 || ^6.0.0", - "react": "^17.0.0 || ^18.0.0", - "react-dom": "^17.0.0 || ^18.0.0" + "react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" }, ``` diff --git a/packages/x-tree-view/package.json b/packages/x-tree-view/package.json index 251a35830562..80b3589a8738 100644 --- a/packages/x-tree-view/package.json +++ b/packages/x-tree-view/package.json @@ -1,6 +1,6 @@ { "name": "@mui/x-tree-view", - "version": "8.0.0-alpha.0", + "version": "8.0.0-alpha.1", "description": "The community edition of the Tree View components (MUI X).", "author": "MUI Team", "main": "src/index.ts", @@ -58,8 +58,8 @@ "@emotion/styled": "^11.8.1", "@mui/material": "^5.15.14 || ^6.0.0", "@mui/system": "^5.15.14 || ^6.0.0", - "react": "^17.0.0 || ^18.0.0", - "react-dom": "^17.0.0 || ^18.0.0" + "react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" }, "peerDependenciesMeta": { "@emotion/react": { diff --git a/packages/x-tree-view/src/internals/plugins/useTreeViewFocus/useTreeViewFocus.ts b/packages/x-tree-view/src/internals/plugins/useTreeViewFocus/useTreeViewFocus.ts index 7cbc8d042cd7..fc2c5a40eebf 100644 --- a/packages/x-tree-view/src/internals/plugins/useTreeViewFocus/useTreeViewFocus.ts +++ b/packages/x-tree-view/src/internals/plugins/useTreeViewFocus/useTreeViewFocus.ts @@ -1,6 +1,5 @@ import * as React from 'react'; import useEventCallback from '@mui/utils/useEventCallback'; -import useEnhancedEffect from '@mui/utils/useEnhancedEffect'; import { EventHandlers } from '@mui/utils'; import { TreeViewPlugin } from '../../models'; import { UseTreeViewFocusSignature } from './useTreeViewFocus.types'; @@ -24,7 +23,7 @@ export const useTreeViewFocus: TreeViewPlugin = ({ store, models, }) => { - useEnhancedEffect(() => { + React.useEffect(() => { let defaultFocusableItemId = convertSelectedItemsToArray(models.selectedItems.value).find( (itemId) => { if (!selectorCanItemBeFocused(store.value, itemId)) { diff --git a/packages/x-tree-view/src/internals/plugins/useTreeViewItems/useTreeViewItems.test.tsx b/packages/x-tree-view/src/internals/plugins/useTreeViewItems/useTreeViewItems.test.tsx index 1256f01c37e0..625a54a3a8c1 100644 --- a/packages/x-tree-view/src/internals/plugins/useTreeViewItems/useTreeViewItems.test.tsx +++ b/packages/x-tree-view/src/internals/plugins/useTreeViewItems/useTreeViewItems.test.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; import { expect } from 'chai'; import { spy } from 'sinon'; -import { fireEvent } from '@mui/internal-test-utils'; +import { fireEvent, reactMajor } from '@mui/internal-test-utils'; import { describeTreeView } from 'test/utils/tree-view/describeTreeView'; import { UseTreeViewExpansionSignature, @@ -29,17 +29,20 @@ describeTreeView< ).toErrorDev([ 'Encountered two children with the same key, `1`', 'MUI X: The Tree View component requires all items to have a unique `id` property.', - 'MUI X: The Tree View component requires all items to have a unique `id` property.', - `The above error occurred in the component`, - `The above error occurred in the component`, + reactMajor < 19 && + 'MUI X: The Tree View component requires all items to have a unique `id` property.', + reactMajor < 19 && `The above error occurred in the component`, + reactMajor < 19 && `The above error occurred in the component`, ]); } else { expect(() => render({ items: [{ id: '1' }, { id: '1' }], withErrorBoundary: true }), ).toErrorDev([ 'MUI X: The Tree View component requires all items to have a unique `id` property.', - 'MUI X: The Tree View component requires all items to have a unique `id` property.', - `The above error occurred in the component`, + reactMajor < 19 && + 'MUI X: The Tree View component requires all items to have a unique `id` property.', + reactMajor < 19 && + `The above error occurred in the component`, ]); } }); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a4ef6cec0d1a..1f99814099c9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -764,10 +764,10 @@ importers: specifier: ^15.8.1 version: 15.8.1 react: - specifier: ^17.0.0 || ^18.0.0 + specifier: ^17.0.0 || ^18.0.0 || ^19.0.0 version: 18.3.1 react-dom: - specifier: ^17.0.0 || ^18.0.0 + specifier: ^17.0.0 || ^18.0.0 || ^19.0.0 version: 18.3.1(react@18.3.1) reselect: specifier: ^5.1.1 @@ -844,10 +844,10 @@ importers: specifier: ^15.8.1 version: 15.8.1 react: - specifier: ^17.0.0 || ^18.0.0 + specifier: ^17.0.0 || ^18.0.0 || ^19.0.0 version: 18.3.1 react-dom: - specifier: ^17.0.0 || ^18.0.0 + specifier: ^17.0.0 || ^18.0.0 || ^19.0.0 version: 18.3.1(react@18.3.1) devDependencies: '@mui/material': @@ -1017,10 +1017,10 @@ importers: specifier: ^15.8.1 version: 15.8.1 react: - specifier: ^17.0.0 || ^18.0.0 + specifier: ^17.0.0 || ^18.0.0 || ^19.0.0 version: 18.3.1 react-dom: - specifier: ^17.0.0 || ^18.0.0 + specifier: ^17.0.0 || ^18.0.0 || ^19.0.0 version: 18.3.1(react@18.3.1) reselect: specifier: ^5.1.1 @@ -1073,7 +1073,7 @@ importers: specifier: ^11.0.2 version: 11.0.2 react: - specifier: ^17.0.0 || ^18.0.0 + specifier: ^17.0.0 || ^18.0.0 || ^19.0.0 version: 18.3.1 devDependencies: '@mui/icons-material': @@ -1129,10 +1129,10 @@ importers: specifier: ^15.8.1 version: 15.8.1 react: - specifier: ^17.0.0 || ^18.0.0 + specifier: ^17.0.0 || ^18.0.0 || ^19.0.0 version: 18.3.1 react-dom: - specifier: ^17.0.0 || ^18.0.0 + specifier: ^17.0.0 || ^18.0.0 || ^19.0.0 version: 18.3.1(react@18.3.1) reselect: specifier: ^5.1.1 @@ -1191,10 +1191,10 @@ importers: specifier: ^15.8.1 version: 15.8.1 react: - specifier: ^17.0.0 || ^18.0.0 + specifier: ^17.0.0 || ^18.0.0 || ^19.0.0 version: 18.3.1 react-dom: - specifier: ^17.0.0 || ^18.0.0 + specifier: ^17.0.0 || ^18.0.0 || ^19.0.0 version: 18.3.1(react@18.3.1) reselect: specifier: ^5.1.1 @@ -1244,10 +1244,10 @@ importers: specifier: ^15.8.1 version: 15.8.1 react: - specifier: ^17.0.0 || ^18.0.0 + specifier: ^17.0.0 || ^18.0.0 || ^19.0.0 version: 18.3.1 react-dom: - specifier: ^17.0.0 || ^18.0.0 + specifier: ^17.0.0 || ^18.0.0 || ^19.0.0 version: 18.3.1(react@18.3.1) react-transition-group: specifier: ^4.4.5 @@ -1339,10 +1339,10 @@ importers: specifier: ^15.8.1 version: 15.8.1 react: - specifier: ^17.0.0 || ^18.0.0 + specifier: ^17.0.0 || ^18.0.0 || ^19.0.0 version: 18.3.1 react-dom: - specifier: ^17.0.0 || ^18.0.0 + specifier: ^17.0.0 || ^18.0.0 || ^19.0.0 version: 18.3.1(react@18.3.1) react-transition-group: specifier: ^4.4.5 @@ -1392,7 +1392,7 @@ importers: specifier: ^5.16.6 || ^6.0.0 version: 5.16.6(@types/react@18.3.12)(react@18.3.1) react: - specifier: ^17.0.0 || ^18.0.0 + specifier: ^17.0.0 || ^18.0.0 || ^19.0.0 version: 18.3.1 devDependencies: '@mui/internal-test-utils': @@ -1412,7 +1412,7 @@ importers: specifier: ^5.16.6 || ^6.0.0 version: 5.16.6(@types/react@18.3.12)(react@18.3.1) react: - specifier: ^17.0.0 || ^18.0.0 + specifier: ^17.0.0 || ^18.0.0 || ^19.0.0 version: 18.3.1 devDependencies: '@mui/internal-test-utils': @@ -1450,10 +1450,10 @@ importers: specifier: ^15.8.1 version: 15.8.1 react: - specifier: ^17.0.0 || ^18.0.0 + specifier: ^17.0.0 || ^18.0.0 || ^19.0.0 version: 18.3.1 react-dom: - specifier: ^17.0.0 || ^18.0.0 + specifier: ^17.0.0 || ^18.0.0 || ^19.0.0 version: 18.3.1(react@18.3.1) react-transition-group: specifier: ^4.4.5 @@ -1518,10 +1518,10 @@ importers: specifier: ^15.8.1 version: 15.8.1 react: - specifier: ^17.0.0 || ^18.0.0 + specifier: ^17.0.0 || ^18.0.0 || ^19.0.0 version: 18.3.1 react-dom: - specifier: ^17.0.0 || ^18.0.0 + specifier: ^17.0.0 || ^18.0.0 || ^19.0.0 version: 18.3.1(react@18.3.1) react-transition-group: specifier: ^4.4.5 diff --git a/scripts/releaseChangelog.mjs b/scripts/releaseChangelog.mjs index 209304695b1c..b7c47b24b268 100644 --- a/scripts/releaseChangelog.mjs +++ b/scripts/releaseChangelog.mjs @@ -221,6 +221,7 @@ async function main(argv) { break; case 'TreeView': case 'tree view': + case 'TreeItem': treeViewCommits.push(commitItem); break; case 'docs': @@ -360,7 +361,7 @@ ${logChangelogSection(pickersProCommits)}${pickersProCommits.length > 0 ? '\n' : ${logChangelogSection(chartsCommits) || `No changes since \`@mui/x-charts@${lastRelease}\`.`} -#### \`@mui/x-charts-pro@__VERSION-ALPHA__\` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan') +#### \`@mui/x-charts-pro@__VERSION__\` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan') Same changes as in \`@mui/x-charts@__VERSION__\`${chartsProCommits.length > 0 ? ', plus:\n' : '.'} ${logChangelogSection(chartsProCommits)}${chartsProCommits.length > 0 ? '\n' : ''} diff --git a/scripts/useMaterialUIv6.mjs b/scripts/useMaterialUIv6.mjs index 07f2aed4e3ab..abc2fe55845b 100644 --- a/scripts/useMaterialUIv6.mjs +++ b/scripts/useMaterialUIv6.mjs @@ -9,6 +9,9 @@ const pnpmUpdate = childProcess.spawnSync( '@mui/system@6.x', '@mui/icons-material@6.x', '@mui/utils@6.x', + '@mui/material-nextjs@6.x', + '@mui/styles@6.x', + '@mui/lab@latest', ], { shell: true, diff --git a/test/README.md b/test/README.md index 5bb982bb61ca..594badd07c28 100644 --- a/test/README.md +++ b/test/README.md @@ -12,57 +12,43 @@ Possible values for `version`: - a tag on npm, for example `next`, `experimental` or `latest` - an older version, for example `^17.0.0` -### CI +## Testing multiple versions of MaterialĀ UI + +Currently, we use `@mui/material` v5 in the MUIĀ X repo and all tests are run against it. +But MUIĀ X packages are compatible with v5 and v6. +You can run the tests against `@mui/material` v6 by running the following command: -#### `next` version +`pnpm use-material-ui-v6` -For `react@next` specifically, there's a `react-next` workflow in our CircleCI pipeline that you can trigger in CircleCI on the PR you want to test: +## CI -1. Go to https://app.circleci.com/pipelines/github/mui/mui-x?branch=pull/PR_NUMBER and replace `PR_NUMBER` with the PR number you want to test. -2. Click `Trigger Pipeline` button. -3. Expand `Add parameters (optional)` and add the following parameter: +To execute additional jobs for custom versions of React/MaterialĀ UI, you can use an `additional` workflow. In combination with `with-react-version` and/or `with-material-ui-6` parameters, it executes those jobs with dependency versions different from the main `pipeline` workflow. - | Parameter type | Name | Value | - | :------------- | :--------- | :----------- | - | `string` | `workflow` | `react-next` | +| Parameter type | Name | Value | +| :------------- | :------------------- | :------------------- | +| `string` | `workflow` | `additional` | +| `string` | `with-react-version` | `` | +| `boolean` | `with-material-ui-6` | `true` or `false` | +1. Go to https://app.circleci.com/pipelines/github/mui/mui-x?branch=pull/PR_NUMBER and replace `PR_NUMBER` with the PR number you want to test. +2. Click `Trigger Pipeline` button. +3. Go to the `Parameters` section and update the `workflow` parameter in combination with the version parameter(s). + You can leave the rest of the parameters with their default values. 4. Click `Trigger Pipeline` button. -#### Other versions +![CircleCI workflow](./circleci-workflow.png) + +### API -You can pass the same `version` to our CircleCI pipeline as well: +You can pass the same to our CircleCI pipeline through API as well: -With the following API request we're triggering a run of the default workflow in -PR #24289 for `react@next` +With the following API request we're triggering a run of the `additional` workflow in +PR #24289 for `react@rc` and `@mui/material-ui@6` ```bash curl --request POST \ --url https://circleci.com/api/v2/project/gh/mui/mui-x/pipeline \ --header 'content-type: application/json' \ --header 'Circle-Token: $CIRCLE_TOKEN' \ - --data-raw '{"branch":"pull/24289/head","parameters":{"react-version":"next"}}' + --data-raw '{"branch":"pull/24289/head","parameters":{"workflow":"additional","with-react-version":"rc","with-material-ui-6":true}}' ``` - -## Testing multiple versions of MaterialĀ UI - -Currently, we use `@mui/material` v5 in the MUIĀ X repo and all tests are run against it. -But MUIĀ X packages are compatible with v5 and v6. -You can run the tests against `@mui/material` v6 by running the following command: - -`pnpm use-material-ui-v6` - -### CI - -There's a `material-ui-v6` workflow in our CircleCI pipeline that you can trigger in CircleCI on the PR you want to test: - -1. Go to https://app.circleci.com/pipelines/github/mui/mui-x?branch=pull/PR_NUMBER and replace `PR_NUMBER` with the PR number you want to test. -2. Click `Trigger Pipeline` button. -3. Expand `Add parameters (optional)` and add the following parameter: - - | Parameter type | Name | Value | - | :------------- | :--------- | :--------------- | - | `string` | `workflow` | `material-ui-v6` | - -4. Click `Trigger Pipeline` button. - -![CircleCI workflow](./circleci-workflow.png) diff --git a/test/circleci-workflow.png b/test/circleci-workflow.png index de549e5eef46..a7db4008e51e 100644 Binary files a/test/circleci-workflow.png and b/test/circleci-workflow.png differ