From 617bcdaf5b1ece13ca0d2551deb4249a64dbc139 Mon Sep 17 00:00:00 2001 From: Nora <72460825+noraleonte@users.noreply.github.com> Date: Wed, 20 Mar 2024 20:54:37 +0200 Subject: [PATCH 01/55] [core] Update prettier script to use `master` branch (#12522) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 896c4ac9af1b2..d23ef5331d661 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "eslint:ci": "eslint . --report-unused-disable-directives --ext .js,.ts,.tsx --max-warnings 0", "markdownlint": "markdownlint-cli2 \"**/*.md\"", "postinstall": "patch-package", - "prettier": "pretty-quick --branch next --ignore-path .eslintignore", + "prettier": "pretty-quick --branch master --ignore-path .eslintignore", "prettier:all": "prettier --write . --ignore-path .eslintignore", "proptypes": "cross-env BABEL_ENV=development babel-node -i \"/node_modules/(?!@mui)/\" -x .ts,.tsx,.js ./docs/scripts/generateProptypes.ts", "size:snapshot": "node --max-old-space-size=2048 ./scripts/sizeSnapshot/create", From 428065579e16b9361204023df6292f2b4cb999b4 Mon Sep 17 00:00:00 2001 From: Lukas Date: Thu, 21 Mar 2024 12:07:58 +0200 Subject: [PATCH 02/55] [core] Update supported browsers (browserlistrc) (#12521) --- .browserslistrc | 81 +++++++++++++++++++++++++++++++++++-------------- yarn.lock | 6 ++-- 2 files changed, 62 insertions(+), 25 deletions(-) diff --git a/.browserslistrc b/.browserslistrc index 729c34746e4b3..92f902fcf61b1 100644 --- a/.browserslistrc +++ b/.browserslistrc @@ -7,34 +7,71 @@ node 14 # Default/Fallback -# `npx browserslist --mobile-to-desktop "> 0.5%, last 2 versions, Firefox ESR, not dead, not IE 11"` when the last major is released. - -# Manually downgrading to ios_saf 12.4 for iPhone 6 and webpack 4 support. +# Explicit safari versions are here based on the agreed terms in: https://github.com/mui/material-ui/issues/40958#issuecomment-1953215043 +# Run before a major release: `npx browserslist@latest --update-db && npx browserslist --mobile-to-desktop "> 0.5%, last 2 versions, Firefox ESR, not dead, safari >= 15.4, iOS >= 15.4"`. +# Update the versions in the `stable` section with the output result. +# Reference PR: https://github.com/mui/mui-x/pull/12521. # On update, sync references where "#stable-snapshot" is mentioned in the codebase. [stable] -and_chr 91 -and_ff 89 -and_qq 10.4 -and_uc 12.12 -android 91 -baidu 7.12 -chrome 90 -edge 91 -firefox 78 - -# 12.4 but 12.2-12.5 are treated equally in caniuse-lite. - -# Though caniuse-lite does not supporting finding an exact version in a range which is why `12.4` would result in "Unknown version 12.4 of ios_saf" - -ios_saf 12.2 +and_chr 122 +and_chr 121 +and_ff 123 +and_ff 122 +and_qq 14.9 +and_uc 15.5 +android 122 +android 121 +chrome 122 +chrome 121 +chrome 120 +chrome 119 +chrome 109 +edge 122 +edge 121 +firefox 123 +firefox 122 +firefox 115 +ios_saf 17.4 +ios_saf 17.3 +ios_saf 17.2 +ios_saf 17.1 +ios_saf 17.0 +ios_saf 16.6-16.7 +ios_saf 16.5 +ios_saf 16.4 +ios_saf 16.3 +ios_saf 16.2 +ios_saf 16.1 +ios_saf 16.0 +ios_saf 15.6-15.8 +ios_saf 15.5 +ios_saf 15.4 +kaios 3.0-3.1 kaios 2.5 op_mini all -op_mob 73 -opera 76 -safari 14 -samsung 13.0 +op_mob 80 +opera 108 +opera 107 +opera 106 +safari 17.4 +safari 17.3 +safari 17.2 +safari 17.1 +safari 17.0 +safari 16.6 +safari 16.5 +safari 16.4 +safari 16.3 +safari 16.2 +safari 16.1 +safari 16.0 +safari 15.6 +safari 15.5 +safari 15.4 +samsung 23 +samsung 22 # snapshot of `npx browserslist "maintained node versions"` diff --git a/yarn.lock b/yarn.lock index 572f5f7489679..f0779977e1a45 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5074,9 +5074,9 @@ camelize@^1.0.0: integrity sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ== caniuse-lite@^1.0.30001579, caniuse-lite@^1.0.30001587, caniuse-lite@^1.0.30001591: - version "1.0.30001591" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001591.tgz#16745e50263edc9f395895a7cd468b9f3767cf33" - integrity sha512-PCzRMei/vXjJyL5mJtzNiUCKP59dm8Apqc3PH8gJkMnMXZGox93RbE76jHsmLwmIo6/3nsYIpJtx0O7u5PqFuQ== + version "1.0.30001599" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001599.tgz#571cf4f3f1506df9bf41fcbb6d10d5d017817bce" + integrity sha512-LRAQHZ4yT1+f9LemSMeqdMpMxZcc4RMWdj4tiFe3G8tNkWK+E58g+/tzotb5cU6TbcVJLr4fySiAW7XmxQvZQA== chai-dom@^1.12.0: version "1.12.0" From fb7e03e91958c49f69249d37a73d2c4a2e8387e6 Mon Sep 17 00:00:00 2001 From: sai chand <60743144+sai6855@users.noreply.github.com> Date: Thu, 21 Mar 2024 18:11:15 +0530 Subject: [PATCH 03/55] [DataGridPremium] Fix boolean cell not rendered in group rows (#12492) Co-authored-by: Andrew Cherniavskyi --- .../tests/rowGrouping.DataGridPremium.test.tsx | 16 ++++++++++++++++ .../src/components/cell/GridBooleanCell.tsx | 10 ++++++---- 2 files changed, 22 insertions(+), 4 deletions(-) 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 601df54088683..9dc6dc7eef7ce 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 @@ -163,6 +163,22 @@ describe(' - Row grouping', () => { expect(getColumnValues(0)).to.deep.equal(['Cat A (3)', '', '', '', 'Cat B (2)', '', '']); }); + it('should display icon on auto-generated row', () => { + render( + ({ ...row, isFilled: false }))} + />, + ); + + expect(screen.getByTestId('CloseIcon')).toBeVisible(); + }); + it('should respect the grouping criteria with colDef.groupable = false', () => { render( { return composeClasses(slots, getDataGridUtilityClass, classes); }; -interface GridBooleanCellProps - extends GridRenderCellParams, - Omit {} +interface GridBooleanCellProps extends GridRenderCellParams, Omit { + hideDescendantCount?: boolean; +} function GridBooleanCellRaw(props: GridBooleanCellProps) { const { @@ -40,6 +40,7 @@ function GridBooleanCellRaw(props: GridBooleanCellProps) { isEditable, hasFocus, tabIndex, + hideDescendantCount, ...other } = props; @@ -108,6 +109,7 @@ GridBooleanCellRaw.propTypes = { * If true, the cell is the active element. */ hasFocus: PropTypes.bool.isRequired, + hideDescendantCount: PropTypes.bool, /** * The grid row id. */ @@ -140,7 +142,7 @@ const GridBooleanCell = React.memo(GridBooleanCellRaw); export { GridBooleanCell }; export const renderBooleanCell: GridColDef['renderCell'] = (params: GridBooleanCellProps) => { - if (isAutoGeneratedRow(params.rowNode)) { + if (params.field !== '__row_group_by_columns_group__' && isAutoGeneratedRow(params.rowNode)) { return ''; } From dcb8721de38019e9ac712797d29ec8ec6530d3d0 Mon Sep 17 00:00:00 2001 From: Lukas Date: Thu, 21 Mar 2024 17:19:50 +0200 Subject: [PATCH 04/55] [DateTimeRangePicker] Fix views behavior regression (#12529) --- .../src/MobileDateTimeRangePicker/MobileDateTimeRangePicker.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/x-date-pickers-pro/src/MobileDateTimeRangePicker/MobileDateTimeRangePicker.tsx b/packages/x-date-pickers-pro/src/MobileDateTimeRangePicker/MobileDateTimeRangePicker.tsx index c794c6f7a4ec5..ce0f3684164ab 100644 --- a/packages/x-date-pickers-pro/src/MobileDateTimeRangePicker/MobileDateTimeRangePicker.tsx +++ b/packages/x-date-pickers-pro/src/MobileDateTimeRangePicker/MobileDateTimeRangePicker.tsx @@ -105,7 +105,7 @@ const rendererInterceptor = function rendererInterceptor< viewRenderer as PickerViewRenderer, TimeViewWithMeridiem, any, {}> } view={view && isInternalTimeView(view) ? view : 'hours'} - views={finalProps.views.filter(isInternalTimeView)} + views={finalProps.views as TimeViewWithMeridiem[]} openTo={isInternalTimeView(openTo) ? openTo : 'hours'} /> ); From 2916fb15d4df24868bdccb0d3cbc8a8ef10cb0e1 Mon Sep 17 00:00:00 2001 From: Andrew Cherniavskii Date: Thu, 21 Mar 2024 16:34:32 +0100 Subject: [PATCH 05/55] [docs] Update "What's new in MUI X" page (#12527) --- docs/src/modules/components/WhatsNewLayout.js | 38 +++++++++++++------ 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/docs/src/modules/components/WhatsNewLayout.js b/docs/src/modules/components/WhatsNewLayout.js index 9ed6e778bc59f..d2df9ca9e718b 100644 --- a/docs/src/modules/components/WhatsNewLayout.js +++ b/docs/src/modules/components/WhatsNewLayout.js @@ -18,31 +18,47 @@ import TimelineOppositeContent from '@mui/lab/TimelineOppositeContent'; const entries = [ { - title: 'MUI X v7.0.0-beta.0', + title: 'MUI X v7.0.0', description: 'Featuring new components and multiple enhancements for both developers and end-users.', - date: new Date(2024, 0, 29), - url: 'https://mui.com/blog/mui-x-v7-beta/', + date: new Date(2024, 2, 21), + url: 'https://mui.com/blog/mui-x-v7/', highlightList: [ { - title: 'Data Grid - Sticky headers', - url: 'https://mui.com/blog/mui-x-v7-beta/#sticky-headers', + title: 'Data Grid – Column resizing on the Community plan', + url: 'https://mui.com/blog/mui-x-v7/#column-resizing-on-the-community-plan', }, { - title: 'Data Grid - Columns management panel', - url: 'https://mui.com/blog/mui-x-v7-beta/#improved-columns-panel-design', + title: 'Data Grid – Sticky headers and improved scrolling performance', + url: 'https://mui.com/blog/mui-x-v7/#sticky-headers-and-improved-scrolling-performance', + }, + { + title: 'Data Grid – Improved columns panel design', + url: 'https://mui.com/blog/mui-x-v7/#improved-columns-panel-design', + }, + { + title: 'Data Grid – New stable features', + url: 'https://mui.com/blog/mui-x-v7/#new-stable-features', }, { title: 'Rich Tree View', - url: 'https://mui.com/blog/mui-x-v7-beta/#richtreeview', + url: 'https://mui.com/blog/mui-x-v7/#rich-tree-view', + }, + { + title: 'Charts - Gauge charts', + url: 'https://mui.com/blog/mui-x-v7/#gauge-charts', + }, + { + title: 'Charts - Reference line', + url: 'https://mui.com/blog/mui-x-v7/#reference-line', }, { title: 'Date Time Range Picker', - url: 'https://mui.com/blog/mui-x-v7-beta/#date-time-range-picker', + url: 'https://mui.com/blog/mui-x-v7/#date-time-range-picker', }, { - title: 'Charts - Reference line ', - url: 'https://mui.com/blog/mui-x-v7-beta/#reference-line', + title: 'Support for date-fns v3', + url: 'https://mui.com/blog/mui-x-v7/#support-for-date-fns-v3', }, ], }, From 2e5fbb325fb290c53e3d53043d70bc2e36f8d8b3 Mon Sep 17 00:00:00 2001 From: Nora <72460825+noraleonte@users.noreply.github.com> Date: Fri, 22 Mar 2024 13:32:30 +0200 Subject: [PATCH 06/55] v7.0.0 (#12523) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Nora <72460825+noraleonte@users.noreply.github.com> Co-authored-by: Andrew Cherniavskyi Co-authored-by: Bilal Shafi Co-authored-by: Flavien DELANGLE Co-authored-by: Lukas Co-authored-by: José Rodolfo Freitas --- CHANGELOG.md | 185 +++++++++++++++++- package.json | 2 +- packages/x-charts/package.json | 2 +- packages/x-codemod/package.json | 2 +- packages/x-data-grid-generator/package.json | 4 +- packages/x-data-grid-premium/package.json | 8 +- .../rowGrouping.DataGridPremium.test.tsx | 2 +- packages/x-data-grid-pro/package.json | 6 +- packages/x-data-grid/package.json | 2 +- packages/x-date-pickers-pro/package.json | 6 +- packages/x-date-pickers/package.json | 2 +- packages/x-license/package.json | 2 +- packages/x-tree-view/package.json | 2 +- 13 files changed, 204 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b0499f734d2dc..e885ff6e1e0f2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,189 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## v7.0.0 + +_Mar 22, 2024_ + +We're excited to [announce the first v7 stable release](https://mui.com/blog/mui-x-v7/)! 🎉🚀 + +This is now the officially supported major version, where we'll keep rolling out new features, bug fixes, and improvements. +Migration guides are available with a complete list of the breaking changes: + +- [Data Grid](https://mui.com/x/migration/migration-data-grid-v6/) +- [Date and Time Pickers](https://mui.com/x/migration/migration-pickers-v6/) +- [Tree View](https://mui.com/x/migration/migration-tree-view-v6/) +- [Charts](https://mui.com/x/migration/migration-charts-v6/) + +We'd like to offer a big thanks to the 12 contributors who made this release possible. Here are some highlights ✨: + +- 🚀 Improve the usage of custom `viewRenderers` on `DateTimePicker` (#12441) @LukasTy +- ✨ Set focus on the focused Tree Item instead of the Tree View (#12226) @flaviendelangle +- 🕹️ Support controlled `density` for the Data Grid (#12332) @MBilalShafi +- 🎁 Dynamic virtualization range for the Data Grid (#12353) @romgrk +- 🐞 Bugfixes +- 📚 Documentation improvements + +### Data Grid + +#### Breaking changes + +- The `density` is a [controlled prop](https://mui.com/x/react-data-grid/accessibility/#set-the-density-programmatically) now, if you were previously passing the `density` prop to the Data Grid, you will need to do one of the following: + + 1. Move it to the `initialState.density` to initialize it. + + ```diff + + ``` + + 2. Move it to the state and use `onDensityChange` callback to update the `density` prop accordingly for it to work as expected. + + ```diff + + const [density, setDensity] = React.useState('compact'); + setDensity(newDensity)} + /> + ``` + +- The selector `gridDensityValueSelector` was removed, use the `gridDensitySelector` instead. + +- The props `rowBuffer` and `columnBuffer` were renamed to `rowBufferPx` and `columnBufferPx`. + Their value is now a pixel value rather than a number of items. Their default value is now `150`. + +- The props `rowThreshold` and `columnThreshold` have been removed. + If you had the `rowThreshold` prop set to `0` to force new rows to be rendered more often – this is no longer necessary. + +#### `@mui/x-data-grid@7.0.0` + +- [DataGrid] Allow to control the grid density (#12332) @MBilalShafi +- [DataGrid] Dynamic virtualization range (#12353) @romgrk +- [DataGrid] Fix `ElementType` usage (#12479) @cherniavskii +- [DataGrid] Fix cell value formatting on copy (#12357) @sai6855 +- [DataGrid] Fix checkbox selection is keeping selection when filtering (#11751) @g1mishra +- [DataGrid] Make `rows` an optional prop (#12478) @MBilalShafi + +#### `@mui/x-data-grid-pro@7.0.0` [![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.0.0`. + +#### `@mui/x-data-grid-premium@7.0.0` [![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.0.0`, plus: + +- [DataGridPremium] Add support for confirmation before clipboard paste (#12225) @cherniavskii +- [DataGridPremium] Fix single grouping column sorting (#9679) @cherniavskii +- [DataGridPremium] Fix boolean cell not rendered in group rows (#12492) @sai6855 + +### Date and Time Pickers + +#### Breaking changes + +- The `DesktopDateTimePicker` view rendering has been optimized by using the same technique as for `DesktopDateTimeRangePicker`. + - The `dateTimeViewRenderers` have been removed in favor of reusing existing time view renderers (`renderTimeViewClock`, `renderDigitalClockTimeView` and `renderMultiSectionDigitalClockTimeView`) and date view renderer (`renderDateViewCalendar`). + - Passing `renderTimeViewClock` to time view renderers will no longer revert to the old behavior of rendering only date or time view. + +#### `@mui/x-date-pickers@7.0.0` + +- [fields] Allow to override the separator between the start and the end date in all range fields (#12174) @flaviendelangle +- [fields] Support format without separator (#12489) @flaviendelangle +- [pickers] Use renderer interceptor on `DesktopDateTimePicker` (#12441) @LukasTy + +#### `@mui/x-date-pickers-pro@7.0.0` [![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.0.0`, plus: + +- [DateTimeRangePicker] Add component `JSDoc` (#12518) @LukasTy +- [DateTimeRangePicker] Fix views behavior regression (#12529) @LukasTy + +### Charts + +#### `@mui/x-charts@7.0.0` + +- [charts] Fix small typo in `CartesianContextProvider` (#12461) @Janpot + +### Tree View + +#### Breaking changes + +- The required `nodeId` prop used by the `TreeItem` has been renamed to `itemId` for consistency: + +```diff + +- ++ + +``` + +- The focus is now applied to the Tree Item root element instead of the Tree View root element. + + This change will allow new features that require the focus to be on the Tree Item, + like the drag and drop reordering of items. + It also solves several issues with focus management, + like the inability to scroll to the focused item when a lot of items are rendered. + + This will mostly impact how you write tests to interact with the Tree View: + + For example, if you were writing a test with `react-testing-library`, here is what the changes could look like: + + ```diff + it('test example on first item', () => { + - const { getByRole } = render( + + const { getAllByRole } = render( + + + + + ); + + - const tree = getByRole('tree'); + + const firstTreeItem = getAllByRole('treeitem')[0]; + act(() => { + - tree.focus(); + + firstTreeItem.focus(); + }); + - fireEvent.keyDown(tree, { key: 'ArrowDown' }); + + fireEvent.keyDown(firstTreeItem, { key: 'ArrowDown' }); + }) + ``` + +#### `@mui/x-tree-view@7.0.0` + +- [TreeView] Rename `nodeId` to `itemId` (#12418) @noraleonte +- [TreeView] Set focus on the focused Tree Item instead of the Tree View (#12226) @flaviendelangle +- [TreeView] Update JSDoc of the `ContentComponent` prop to avoid using the word "node" (#12476) @flaviendelangle + +### `@mui/x-codemod@7.0.0` + +- [codemod] Add a codemod and update the grid migration guide (#12488) @MBilalShafi + +### Docs + +- [docs] Finalize migration guide (#12501) @noraleonte +- [docs] Fix nested cells alignment in the popular features demo (#12450) @cherniavskii +- [docs] Fix some Vale errors (#12469) @oliviertassinari +- [docs] Remove mentions of pre release (#12513) @noraleonte +- [docs] Update branch name and tags (#12498) @cherniavskii +- [docs] Update links to v6 (#12496) @cherniavskii +- [docs] Update links to v7 docs (#12500) @noraleonte +- [docs] Update supported versions (#12508) @joserodolfofreitas +- [docs] Update "What's new in MUI X" page #12527 @cherniavskii + +### Core + +- [core] Bump `@mui/material` peer dependency for all packages (#12516) @LukasTy +- [core] Fix `no-restricted-imports` ESLint rule not working for Data Grid packages (#12477) @cherniavskii +- [core] Lower the frequency of `no-response` action runs (#12491) @michaldudak +- [core] Remove leftover `legacy` `browserlistrc` entry (#12415) @LukasTy +- [core] Update NPM tag (#12511) @cherniavskii +- [core] Update supported browsers (browserlistrc) (#12521) @LukasTy +- [core] Use Circle CI context @oliviertassinari +- [license] Fix grammar on expired license error message (#12460) @joserodolfofreitas + ## 7.0.0-beta.7 _Mar 14, 2024_ @@ -324,7 +507,7 @@ Same changes as in `@mui/x-data-grid-pro@7.0.0-beta.4`. - The headless field hooks (e.g.: `useDateField`) now returns a new prop called `enableAccessibleFieldDOMStructure`. This property is utilized to determine whether the anticipated UI is constructed using an accessible DOM structure. Learn more about this new [accessible DOM structure](/x/react-date-pickers/fields/#accessible-dom-structure). - When building a custom UI, you are most-likely only supporting one DOM structure, so you can remove `enableAccessibleFieldDOMStructure` before it is passed to the DOM: + When building a custom UI, you are most-likely only supporting one DOM structure, so you can remove `enableAccessibleFieldDOMStructure` before it is passed to the DOM: ```diff function MyCustomTextField(props) { diff --git a/package.json b/package.json index d23ef5331d661..e0d3d46d991bc 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "version": "7.0.0-beta.7", + "version": "7.0.0", "private": true, "scripts": { "start": "yarn && yarn docs:dev", diff --git a/packages/x-charts/package.json b/packages/x-charts/package.json index a28ffc10cabbb..0dac51e3288b8 100644 --- a/packages/x-charts/package.json +++ b/packages/x-charts/package.json @@ -1,6 +1,6 @@ { "name": "@mui/x-charts", - "version": "7.0.0-beta.7", + "version": "7.0.0", "description": "The community edition of the charts components (MUI X).", "author": "MUI Team", "main": "./src/index.js", diff --git a/packages/x-codemod/package.json b/packages/x-codemod/package.json index 3eaba12224cf4..bb8b208b0492e 100644 --- a/packages/x-codemod/package.json +++ b/packages/x-codemod/package.json @@ -1,6 +1,6 @@ { "name": "@mui/x-codemod", - "version": "7.0.0-beta.7", + "version": "7.0.0", "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 507376edc4177..0d1d90500c688 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": "7.0.0-beta.7", + "version": "7.0.0", "description": "Generate fake data for demo purposes only.", "author": "MUI Team", "main": "src/index.ts", @@ -34,7 +34,7 @@ "dependencies": { "@babel/runtime": "^7.24.0", "@mui/base": "^5.0.0-beta.40", - "@mui/x-data-grid-premium": "7.0.0-beta.7", + "@mui/x-data-grid-premium": "7.0.0", "chance": "^1.1.11", "clsx": "^2.1.0", "lru-cache": "^7.18.3" diff --git a/packages/x-data-grid-premium/package.json b/packages/x-data-grid-premium/package.json index daf04247a6cf0..48ebefe940c26 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": "7.0.0-beta.7", + "version": "7.0.0", "description": "The Premium plan edition of the data grid component (MUI X).", "author": "MUI Team", "main": "src/index.ts", @@ -45,9 +45,9 @@ "@babel/runtime": "^7.24.0", "@mui/system": "^5.15.14", "@mui/utils": "^5.15.14", - "@mui/x-data-grid": "7.0.0-beta.7", - "@mui/x-data-grid-pro": "7.0.0-beta.7", - "@mui/x-license": "7.0.0-beta.6", + "@mui/x-data-grid": "7.0.0", + "@mui/x-data-grid-pro": "7.0.0", + "@mui/x-license": "7.0.0", "@types/format-util": "^1.0.4", "clsx": "^2.1.0", "exceljs": "^4.4.0", 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 9dc6dc7eef7ce..c7bf4608de881 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 @@ -172,7 +172,7 @@ describe(' - Row grouping', () => { }, }} columns={[...baselineProps.columns, { field: 'isFilled', type: 'boolean' }]} - rows={baselineProps.rows.map((row) => ({ ...row, isFilled: false }))} + rows={baselineProps.rows?.map((row) => ({ ...row, isFilled: false }))} />, ); diff --git a/packages/x-data-grid-pro/package.json b/packages/x-data-grid-pro/package.json index d9ea31031cad4..24b27a4ebb194 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": "7.0.0-beta.7", + "version": "7.0.0", "description": "The Pro plan edition of the data grid component (MUI X).", "author": "MUI Team", "main": "src/index.ts", @@ -45,8 +45,8 @@ "@babel/runtime": "^7.24.0", "@mui/system": "^5.15.14", "@mui/utils": "^5.15.14", - "@mui/x-data-grid": "7.0.0-beta.7", - "@mui/x-license": "7.0.0-beta.6", + "@mui/x-data-grid": "7.0.0", + "@mui/x-license": "7.0.0", "@types/format-util": "^1.0.4", "clsx": "^2.1.0", "prop-types": "^15.8.1", diff --git a/packages/x-data-grid/package.json b/packages/x-data-grid/package.json index ff003e22d0bf8..00b3f3c8a3d85 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": "7.0.0-beta.7", + "version": "7.0.0", "description": "The community edition of the data grid component (MUI X).", "author": "MUI Team", "main": "src/index.ts", diff --git a/packages/x-date-pickers-pro/package.json b/packages/x-date-pickers-pro/package.json index fe442d22e5cd7..effd9cda07e0f 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": "7.0.0-beta.7", + "version": "7.0.0", "description": "The commercial edition of the date picker components (MUI X).", "author": "MUI Team", "main": "src/index.ts", @@ -45,8 +45,8 @@ "@mui/base": "^5.0.0-beta.40", "@mui/system": "^5.15.14", "@mui/utils": "^5.15.14", - "@mui/x-date-pickers": "7.0.0-beta.7", - "@mui/x-license": "7.0.0-beta.6", + "@mui/x-date-pickers": "7.0.0", + "@mui/x-license": "7.0.0", "clsx": "^2.1.0", "prop-types": "^15.8.1", "react-transition-group": "^4.4.5" diff --git a/packages/x-date-pickers/package.json b/packages/x-date-pickers/package.json index 267014fdbc1d3..7746d0ab63b6b 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": "7.0.0-beta.7", + "version": "7.0.0", "description": "The community edition of the date picker components (MUI X).", "author": "MUI Team", "main": "src/index.ts", diff --git a/packages/x-license/package.json b/packages/x-license/package.json index 87851acac3a19..0fb6503bafe39 100644 --- a/packages/x-license/package.json +++ b/packages/x-license/package.json @@ -1,6 +1,6 @@ { "name": "@mui/x-license", - "version": "7.0.0-beta.6", + "version": "7.0.0", "description": "MUI X License verification", "author": "MUI Team", "main": "src/index.ts", diff --git a/packages/x-tree-view/package.json b/packages/x-tree-view/package.json index 7e738ab9394b1..0e99bd3721ffb 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": "7.0.0-beta.7", + "version": "7.0.0", "description": "The community edition of the tree view components (MUI X).", "author": "MUI Team", "main": "src/index.ts", From 2722f3ddfbb08a00870c533aed0170f201d6c185 Mon Sep 17 00:00:00 2001 From: Lukas Date: Fri, 22 Mar 2024 14:18:53 +0200 Subject: [PATCH 07/55] [docs] Sync static images from core repository (#12525) --- .../static/branding/product-advanced-dark.svg | 25 +++ .../branding/product-advanced-light.svg | 1 + .../static/branding/product-core-dark.svg | 1 + .../static/branding/product-core-light.svg | 1 + .../branding/product-designkits-dark.svg | 1 + .../branding/product-designkits-light.svg | 1 + .../branding/product-templates-dark.svg | 1 + .../branding/product-templates-light.svg | 1 + .../static/branding/product-toolpad-dark.svg | 1 + .../static/branding/product-toolpad-light.svg | 1 + docs/public/static/sponsors/marblism-dark.svg | 1 + .../public/static/sponsors/marblism-light.svg | 1 + .../static/sponsors/marblism-rectangular.svg | 148 ++++++++++++++++++ .../static/sponsors/marblism-square.svg | 1 + .../public/static/sponsors/octopus-square.svg | 1 + 15 files changed, 186 insertions(+) create mode 100644 docs/public/static/branding/product-advanced-dark.svg create mode 100644 docs/public/static/branding/product-advanced-light.svg create mode 100644 docs/public/static/branding/product-core-dark.svg create mode 100644 docs/public/static/branding/product-core-light.svg create mode 100644 docs/public/static/branding/product-designkits-dark.svg create mode 100644 docs/public/static/branding/product-designkits-light.svg create mode 100644 docs/public/static/branding/product-templates-dark.svg create mode 100644 docs/public/static/branding/product-templates-light.svg create mode 100644 docs/public/static/branding/product-toolpad-dark.svg create mode 100644 docs/public/static/branding/product-toolpad-light.svg create mode 100644 docs/public/static/sponsors/marblism-dark.svg create mode 100644 docs/public/static/sponsors/marblism-light.svg create mode 100644 docs/public/static/sponsors/marblism-rectangular.svg create mode 100644 docs/public/static/sponsors/marblism-square.svg create mode 100644 docs/public/static/sponsors/octopus-square.svg diff --git a/docs/public/static/branding/product-advanced-dark.svg b/docs/public/static/branding/product-advanced-dark.svg new file mode 100644 index 0000000000000..0518c815d329c --- /dev/null +++ b/docs/public/static/branding/product-advanced-dark.svg @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/public/static/branding/product-advanced-light.svg b/docs/public/static/branding/product-advanced-light.svg new file mode 100644 index 0000000000000..deed2209c8095 --- /dev/null +++ b/docs/public/static/branding/product-advanced-light.svg @@ -0,0 +1 @@ + diff --git a/docs/public/static/branding/product-core-dark.svg b/docs/public/static/branding/product-core-dark.svg new file mode 100644 index 0000000000000..559c337f6d71b --- /dev/null +++ b/docs/public/static/branding/product-core-dark.svg @@ -0,0 +1 @@ + diff --git a/docs/public/static/branding/product-core-light.svg b/docs/public/static/branding/product-core-light.svg new file mode 100644 index 0000000000000..3e78a586ce9ae --- /dev/null +++ b/docs/public/static/branding/product-core-light.svg @@ -0,0 +1 @@ + diff --git a/docs/public/static/branding/product-designkits-dark.svg b/docs/public/static/branding/product-designkits-dark.svg new file mode 100644 index 0000000000000..34a5d628f225b --- /dev/null +++ b/docs/public/static/branding/product-designkits-dark.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/public/static/branding/product-designkits-light.svg b/docs/public/static/branding/product-designkits-light.svg new file mode 100644 index 0000000000000..4e642fac75327 --- /dev/null +++ b/docs/public/static/branding/product-designkits-light.svg @@ -0,0 +1 @@ + diff --git a/docs/public/static/branding/product-templates-dark.svg b/docs/public/static/branding/product-templates-dark.svg new file mode 100644 index 0000000000000..42622104ac6f3 --- /dev/null +++ b/docs/public/static/branding/product-templates-dark.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/public/static/branding/product-templates-light.svg b/docs/public/static/branding/product-templates-light.svg new file mode 100644 index 0000000000000..23ad7bddf755a --- /dev/null +++ b/docs/public/static/branding/product-templates-light.svg @@ -0,0 +1 @@ + diff --git a/docs/public/static/branding/product-toolpad-dark.svg b/docs/public/static/branding/product-toolpad-dark.svg new file mode 100644 index 0000000000000..f30e2fb4285a9 --- /dev/null +++ b/docs/public/static/branding/product-toolpad-dark.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/public/static/branding/product-toolpad-light.svg b/docs/public/static/branding/product-toolpad-light.svg new file mode 100644 index 0000000000000..8af9515f7c8ab --- /dev/null +++ b/docs/public/static/branding/product-toolpad-light.svg @@ -0,0 +1 @@ + diff --git a/docs/public/static/sponsors/marblism-dark.svg b/docs/public/static/sponsors/marblism-dark.svg new file mode 100644 index 0000000000000..383b35a994f82 --- /dev/null +++ b/docs/public/static/sponsors/marblism-dark.svg @@ -0,0 +1 @@ + diff --git a/docs/public/static/sponsors/marblism-light.svg b/docs/public/static/sponsors/marblism-light.svg new file mode 100644 index 0000000000000..1a704531a53eb --- /dev/null +++ b/docs/public/static/sponsors/marblism-light.svg @@ -0,0 +1 @@ + diff --git a/docs/public/static/sponsors/marblism-rectangular.svg b/docs/public/static/sponsors/marblism-rectangular.svg new file mode 100644 index 0000000000000..4c7d3db29660a --- /dev/null +++ b/docs/public/static/sponsors/marblism-rectangular.svg @@ -0,0 +1,148 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/public/static/sponsors/marblism-square.svg b/docs/public/static/sponsors/marblism-square.svg new file mode 100644 index 0000000000000..81b03e27ffdbd --- /dev/null +++ b/docs/public/static/sponsors/marblism-square.svg @@ -0,0 +1 @@ + diff --git a/docs/public/static/sponsors/octopus-square.svg b/docs/public/static/sponsors/octopus-square.svg new file mode 100644 index 0000000000000..721e4ed65b1d6 --- /dev/null +++ b/docs/public/static/sponsors/octopus-square.svg @@ -0,0 +1 @@ + From ec57ad791eaa67d9dc4808ab633e9d3034b638e1 Mon Sep 17 00:00:00 2001 From: Lukas Date: Fri, 22 Mar 2024 14:19:05 +0200 Subject: [PATCH 08/55] [core] Include `DateTimeRangePicker` tag in `releaseChangelog` (#12526) --- scripts/releaseChangelog.mjs | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/releaseChangelog.mjs b/scripts/releaseChangelog.mjs index 01152512c8b63..595630d7b093c 100644 --- a/scripts/releaseChangelog.mjs +++ b/scripts/releaseChangelog.mjs @@ -164,6 +164,7 @@ async function main(argv) { pickersCommits.push(commitItem); break; case 'DateRangePicker': + case 'DateTimeRangePicker': pickersProCommits.push(commitItem); break; case 'charts': From 02867d1781d19e09b2b628b32a17a3b2332e435e Mon Sep 17 00:00:00 2001 From: Flavien DELANGLE Date: Fri, 22 Mar 2024 13:41:45 +0100 Subject: [PATCH 09/55] [docs] Add example to add a second icon next to the field's opening button (#12524) --- .../AddWarningIconWhenInvalid.js | 42 ++++++++++++++++ .../AddWarningIconWhenInvalid.tsx | 43 +++++++++++++++++ .../AddWarningIconWhenInvalid.tsx.preview | 10 ++++ .../AddWarningIconWhenInvalidRange.js | 47 ++++++++++++++++++ .../AddWarningIconWhenInvalidRange.tsx | 48 +++++++++++++++++++ .../custom-opening-button.md | 12 +++++ 6 files changed, 202 insertions(+) create mode 100644 docs/data/date-pickers/custom-opening-button/AddWarningIconWhenInvalid.js create mode 100644 docs/data/date-pickers/custom-opening-button/AddWarningIconWhenInvalid.tsx create mode 100644 docs/data/date-pickers/custom-opening-button/AddWarningIconWhenInvalid.tsx.preview create mode 100644 docs/data/date-pickers/custom-opening-button/AddWarningIconWhenInvalidRange.js create mode 100644 docs/data/date-pickers/custom-opening-button/AddWarningIconWhenInvalidRange.tsx diff --git a/docs/data/date-pickers/custom-opening-button/AddWarningIconWhenInvalid.js b/docs/data/date-pickers/custom-opening-button/AddWarningIconWhenInvalid.js new file mode 100644 index 0000000000000..45751705f59dd --- /dev/null +++ b/docs/data/date-pickers/custom-opening-button/AddWarningIconWhenInvalid.js @@ -0,0 +1,42 @@ +import * as React from 'react'; +import dayjs from 'dayjs'; +import InputAdornment from '@mui/material/InputAdornment'; +import PriorityHighIcon from '@mui/icons-material/PriorityHigh'; +import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; +import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; +import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; +import { DatePicker } from '@mui/x-date-pickers/DatePicker'; + +function CustomInputAdornment(props) { + const { hasError, children, sx, ...other } = props; + return ( + + + {children} + + ); +} + +export default function AddWarningIconWhenInvalid() { + const [error, setError] = React.useState(null); + + return ( + + + + + + ); +} diff --git a/docs/data/date-pickers/custom-opening-button/AddWarningIconWhenInvalid.tsx b/docs/data/date-pickers/custom-opening-button/AddWarningIconWhenInvalid.tsx new file mode 100644 index 0000000000000..9fda0784aff81 --- /dev/null +++ b/docs/data/date-pickers/custom-opening-button/AddWarningIconWhenInvalid.tsx @@ -0,0 +1,43 @@ +import * as React from 'react'; +import dayjs from 'dayjs'; +import InputAdornment, { InputAdornmentProps } from '@mui/material/InputAdornment'; +import PriorityHighIcon from '@mui/icons-material/PriorityHigh'; +import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; +import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; +import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; +import { DatePicker } from '@mui/x-date-pickers/DatePicker'; +import { DateValidationError } from '@mui/x-date-pickers/models'; + +function CustomInputAdornment(props: InputAdornmentProps & { hasError?: boolean }) { + const { hasError, children, sx, ...other } = props; + return ( + + + {children} + + ); +} + +export default function AddWarningIconWhenInvalid() { + const [error, setError] = React.useState(null); + + return ( + + + + + + ); +} diff --git a/docs/data/date-pickers/custom-opening-button/AddWarningIconWhenInvalid.tsx.preview b/docs/data/date-pickers/custom-opening-button/AddWarningIconWhenInvalid.tsx.preview new file mode 100644 index 0000000000000..fcaed745b3d23 --- /dev/null +++ b/docs/data/date-pickers/custom-opening-button/AddWarningIconWhenInvalid.tsx.preview @@ -0,0 +1,10 @@ + \ No newline at end of file diff --git a/docs/data/date-pickers/custom-opening-button/AddWarningIconWhenInvalidRange.js b/docs/data/date-pickers/custom-opening-button/AddWarningIconWhenInvalidRange.js new file mode 100644 index 0000000000000..bf53aa2044b73 --- /dev/null +++ b/docs/data/date-pickers/custom-opening-button/AddWarningIconWhenInvalidRange.js @@ -0,0 +1,47 @@ +import * as React from 'react'; +import dayjs from 'dayjs'; +import InputAdornment from '@mui/material/InputAdornment'; +import PriorityHighIcon from '@mui/icons-material/PriorityHigh'; +import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; +import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; +import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; +import { DateRangePicker } from '@mui/x-date-pickers-pro/DateRangePicker'; + +function CustomInputAdornment(props) { + const { hasError, children, sx, ...other } = props; + return ( + + + {children} + + ); +} + +export default function AddWarningIconWhenInvalidRange() { + const [error, setError] = React.useState([null, null]); + + return ( + + + ({ + InputProps: { + endAdornment: ( + + ), + }, + }), + }} + /> + + + ); +} diff --git a/docs/data/date-pickers/custom-opening-button/AddWarningIconWhenInvalidRange.tsx b/docs/data/date-pickers/custom-opening-button/AddWarningIconWhenInvalidRange.tsx new file mode 100644 index 0000000000000..d9fa4ffdfd780 --- /dev/null +++ b/docs/data/date-pickers/custom-opening-button/AddWarningIconWhenInvalidRange.tsx @@ -0,0 +1,48 @@ +import * as React from 'react'; +import dayjs from 'dayjs'; +import InputAdornment, { InputAdornmentProps } from '@mui/material/InputAdornment'; +import PriorityHighIcon from '@mui/icons-material/PriorityHigh'; +import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; +import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; +import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; +import { DateRangePicker } from '@mui/x-date-pickers-pro/DateRangePicker'; +import { DateRangeValidationError } from '@mui/x-date-pickers-pro/models'; + +function CustomInputAdornment(props: InputAdornmentProps & { hasError?: boolean }) { + const { hasError, children, sx, ...other } = props; + return ( + + + {children} + + ); +} + +export default function AddWarningIconWhenInvalidRange() { + const [error, setError] = React.useState([null, null]); + + return ( + + + ({ + InputProps: { + endAdornment: ( + + ), + }, + }), + }} + /> + + + ); +} diff --git a/docs/data/date-pickers/custom-opening-button/custom-opening-button.md b/docs/data/date-pickers/custom-opening-button/custom-opening-button.md index 08a8d486a5c7e..4dadc61d97e02 100644 --- a/docs/data/date-pickers/custom-opening-button/custom-opening-button.md +++ b/docs/data/date-pickers/custom-opening-button/custom-opening-button.md @@ -34,3 +34,15 @@ If you want to track the opening of the picker, you should use the `onOpen` / `o ``` ::: + +## Add an icon next to the opening button + +If you want to add an icon next to the opening button, you can use the `inputAdornment` slot. +In the example below, the warning icon will be visible anytime the current value is invalid: + +{{"demo": "AddWarningIconWhenInvalid.js"}} + +To add the same behavior to a picker that do not have an input adornment (e.g: Date Range Picker), +you need to use the `textField` slot to add one: + +{{"demo": "AddWarningIconWhenInvalidRange.js"}} From 6b72f371eedb6ec455e2f338e06f276584305ae5 Mon Sep 17 00:00:00 2001 From: Andrew Cherniavskii Date: Fri, 22 Mar 2024 15:18:33 +0100 Subject: [PATCH 10/55] [core] Upgrade monorepo (#12536) --- yarn.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yarn.lock b/yarn.lock index f0779977e1a45..423740868a855 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2018,7 +2018,7 @@ "@mui/monorepo@https://github.com/mui/material-ui.git#master": version "5.15.14" - resolved "https://github.com/mui/material-ui.git#9585d28317c90f2c71ab88dd5ae37638bb64ad82" + resolved "https://github.com/mui/material-ui.git#39fe215ce8bb1ed215e9a274f63b979714876e61" dependencies: "@googleapis/sheets" "^5.0.5" "@netlify/functions" "^2.6.0" From 7f4d0ba90cefa10b8ec54657f7ce6f1ab9bec693 Mon Sep 17 00:00:00 2001 From: Antonio Mancini Date: Mon, 25 Mar 2024 10:51:43 +0100 Subject: [PATCH 11/55] [l10n] Improve Italian (it-IT) locale (#12549) Signed-off-by: Antonio Mancini Co-authored-by: Antonio --- docs/data/date-pickers/localization/data.json | 2 +- packages/x-date-pickers/src/locales/itIT.ts | 30 +++++++++---------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/docs/data/date-pickers/localization/data.json b/docs/data/date-pickers/localization/data.json index 52aa6c3832b94..97b551653c669 100644 --- a/docs/data/date-pickers/localization/data.json +++ b/docs/data/date-pickers/localization/data.json @@ -123,7 +123,7 @@ "languageTag": "it-IT", "importName": "itIT", "localeName": "Italian", - "missingKeysCount": 15, + "missingKeysCount": 0, "totalKeysCount": 50, "githubLink": "https://github.com/mui/mui-x/blob/master/packages/x-date-pickers/src/locales/itIT.ts" }, diff --git a/packages/x-date-pickers/src/locales/itIT.ts b/packages/x-date-pickers/src/locales/itIT.ts index f263d30bd621c..46e19c0b96b1e 100644 --- a/packages/x-date-pickers/src/locales/itIT.ts +++ b/packages/x-date-pickers/src/locales/itIT.ts @@ -25,10 +25,10 @@ const itITPickers: Partial> = { // DateRange labels start: 'Inizio', end: 'Fine', - // startDate: 'Start date', - // startTime: 'Start time', - // endDate: 'End date', - // endTime: 'End time', + startDate: 'Data di inizio', + startTime: 'Ora di inizio', + endDate: 'Data di fine', + endTime: 'Ora di fine', // Action bar cancelButtonLabel: 'Cancellare', @@ -67,7 +67,7 @@ const itITPickers: Partial> = { value !== null && utils.isValid(value) ? `Scegli l'ora, l'ora selezionata è ${utils.format(value, 'fullTime')}` : "Scegli l'ora", - // fieldClearLabel: 'Clear value', + fieldClearLabel: 'Cancella valore', // Table labels timeTableLabel: "scegli un'ora", @@ -77,24 +77,24 @@ const itITPickers: Partial> = { fieldYearPlaceholder: (params) => 'A'.repeat(params.digitAmount), fieldMonthPlaceholder: (params) => (params.contentType === 'letter' ? 'MMMM' : 'MM'), fieldDayPlaceholder: () => 'GG', - // fieldWeekDayPlaceholder: params => params.contentType === 'letter' ? 'EEEE' : 'EE', + fieldWeekDayPlaceholder: (params) => (params.contentType === 'letter' ? 'GGGG' : 'GG'), fieldHoursPlaceholder: () => 'hh', fieldMinutesPlaceholder: () => 'mm', fieldSecondsPlaceholder: () => 'ss', fieldMeridiemPlaceholder: () => 'aa', // View names - // year: 'Year', - // month: 'Month', - // day: 'Day', - // weekDay: 'Week day', - // hours: 'Hours', - // minutes: 'Minutes', - // seconds: 'Seconds', - // meridiem: 'Meridiem', + year: 'Anno', + month: 'Mese', + day: 'Giorno', + weekDay: 'Giorno della settimana', + hours: 'Ore', + minutes: 'Minuti', + seconds: 'Secondi', + meridiem: 'Meridiano', // Common - // empty: 'Empty', + empty: 'Vuoto', }; export const itIT = getPickersLocalization(itITPickers); From 1d2d0530ba88f487ae75c43f5cd5ce7a8b4324e6 Mon Sep 17 00:00:00 2001 From: Lukas Date: Mon, 25 Mar 2024 12:07:10 +0200 Subject: [PATCH 12/55] [core] Fix `l10n` script on Windows (#12550) --- scripts/l10n.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/scripts/l10n.ts b/scripts/l10n.ts index 50a8db8786507..d65107ab6c25e 100644 --- a/scripts/l10n.ts +++ b/scripts/l10n.ts @@ -442,7 +442,10 @@ async function run(argv: yargs.ArgumentsCamelCase) { } if (!missingTranslations[localeCode][packageInfo.key]) { missingTranslations[localeCode][packageInfo.key] = { - path: localePath.replace(workspaceRoot, '').slice(1), // Remove leading slash + // prettier-ignore + path: localePath + .replace(workspaceRoot, '').slice(1) // Remove leading slash + .split(path.sep).join('/'), // Ensure the path is using forward slashes even on Windows machines missingKeys: [], }; } From 6968393d1a78924b3085a30bd59bb0ec9f3ee841 Mon Sep 17 00:00:00 2001 From: Flavien DELANGLE Date: Mon, 25 Mar 2024 14:05:15 +0100 Subject: [PATCH 13/55] [TreeView] Do not use outdated version of the state to compute new label first char in `RichTreeView` (#12512) --- .../useTreeViewFocus/useTreeViewFocus.ts | 12 +++-- .../useTreeViewJSXNodes.tsx | 2 + .../useTreeViewKeyboardNavigation.test.tsx | 53 +++++++++++++++++++ .../useTreeViewKeyboardNavigation.ts | 20 +++---- .../useTreeViewNodes/useTreeViewNodes.ts | 13 +++++ .../useTreeViewNodes.types.ts | 11 ++++ 6 files changed, 93 insertions(+), 18 deletions(-) create mode 100644 packages/x-tree-view/src/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.test.tsx 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 68d3337ec9378..72c756902d675 100644 --- a/packages/x-tree-view/src/internals/plugins/useTreeViewFocus/useTreeViewFocus.ts +++ b/packages/x-tree-view/src/internals/plugins/useTreeViewFocus/useTreeViewFocus.ts @@ -107,11 +107,13 @@ export const useTreeViewFocus: TreeViewPlugin = ({ } const node = instance.getNode(state.focusedNodeId); - const itemElement = document.getElementById( - instance.getTreeItemId(state.focusedNodeId, node.idAttribute), - ); - if (itemElement) { - itemElement.blur(); + if (node) { + const itemElement = document.getElementById( + instance.getTreeItemId(state.focusedNodeId, node.idAttribute), + ); + if (itemElement) { + itemElement.blur(); + } } setFocusedItemId(null); diff --git a/packages/x-tree-view/src/internals/plugins/useTreeViewJSXNodes/useTreeViewJSXNodes.tsx b/packages/x-tree-view/src/internals/plugins/useTreeViewJSXNodes/useTreeViewJSXNodes.tsx index 7ac7809b31e26..1ad50070711e4 100644 --- a/packages/x-tree-view/src/internals/plugins/useTreeViewJSXNodes/useTreeViewJSXNodes.tsx +++ b/packages/x-tree-view/src/internals/plugins/useTreeViewJSXNodes/useTreeViewJSXNodes.tsx @@ -18,6 +18,8 @@ export const useTreeViewJSXNodes: TreeViewPlugin = instance, setState, }) => { + instance.preventItemUpdates(); + const insertJSXNode = useEventCallback((node: TreeViewNode) => { setState((prevState) => { if (prevState.nodes.nodeMap[node.id] != null) { diff --git a/packages/x-tree-view/src/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.test.tsx b/packages/x-tree-view/src/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.test.tsx new file mode 100644 index 0000000000000..970bed10f7210 --- /dev/null +++ b/packages/x-tree-view/src/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.test.tsx @@ -0,0 +1,53 @@ +import * as React from 'react'; +import { expect } from 'chai'; +import { act, createRenderer, fireEvent } from '@mui-internal/test-utils'; +import { RichTreeView } from '@mui/x-tree-view/RichTreeView'; + +describe('useTreeViewKeyboardNavigation', () => { + const { render } = createRenderer(); + + it('should work after adding / removing items', () => { + const { getByRole, setProps } = render( + , + ); + + act(() => { + getByRole('treeitem', { name: 'one' }).focus(); + }); + + fireEvent.keyDown(getByRole('treeitem', { name: 'one' }), { key: 'f' }); + expect(getByRole('treeitem', { name: 'four' })).toHaveFocus(); + + setProps({ + items: [ + { id: 'one', label: 'one' }, + { id: 'two', label: 'two' }, + { id: 'three', label: 'three' }, + ], + }); + expect(getByRole('treeitem', { name: 'one' })).toHaveFocus(); + + fireEvent.keyDown(getByRole('treeitem', { name: 'one' }), { key: 't' }); + expect(getByRole('treeitem', { name: 'two' })).toHaveFocus(); + + setProps({ + items: [ + { id: 'one', label: 'one' }, + { id: 'two', label: 'two' }, + { id: 'three', label: 'three' }, + { id: 'four', label: 'four' }, + ], + }); + expect(getByRole('treeitem', { name: 'two' })).toHaveFocus(); + + fireEvent.keyDown(getByRole('treeitem', { name: 'two' }), { key: 'f' }); + expect(getByRole('treeitem', { name: 'four' })).toHaveFocus(); + }); +}); diff --git a/packages/x-tree-view/src/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.ts b/packages/x-tree-view/src/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.ts index 762573b4dada2..344cc4a5532b9 100644 --- a/packages/x-tree-view/src/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.ts +++ b/packages/x-tree-view/src/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.ts @@ -1,7 +1,7 @@ import * as React from 'react'; import { useTheme } from '@mui/material/styles'; import useEventCallback from '@mui/utils/useEventCallback'; -import { TreeViewPlugin } from '../../models'; +import { TreeViewNode, TreeViewPlugin } from '../../models'; import { getFirstNode, getLastNode, @@ -13,7 +13,6 @@ import { TreeViewFirstCharMap, UseTreeViewKeyboardNavigationSignature, } from './useTreeViewKeyboardNavigation.types'; -import { TreeViewBaseItem } from '../../../models'; import { MuiCancellableEvent } from '../../models/MuiCancellableEvent'; function isPrintableCharacter(string: string) { @@ -31,36 +30,31 @@ function findNextFirstChar(firstChars: string[], startIndex: number, char: strin export const useTreeViewKeyboardNavigation: TreeViewPlugin< UseTreeViewKeyboardNavigationSignature -> = ({ instance, params }) => { +> = ({ instance, params, state }) => { const theme = useTheme(); const isRTL = theme.direction === 'rtl'; const firstCharMap = React.useRef({}); - const hasFirstCharMapBeenUpdatedImperatively = React.useRef(false); const updateFirstCharMap = useEventCallback( (callback: (firstCharMap: TreeViewFirstCharMap) => TreeViewFirstCharMap) => { - hasFirstCharMapBeenUpdatedImperatively.current = true; firstCharMap.current = callback(firstCharMap.current); }, ); React.useEffect(() => { - if (hasFirstCharMapBeenUpdatedImperatively.current) { + if (instance.areItemUpdatesPrevented()) { return; } const newFirstCharMap: { [itemId: string]: string } = {}; - const processItem = (item: TreeViewBaseItem) => { - const getItemId = params.getItemId; - const itemId = getItemId ? getItemId(item) : (item as { id: string }).id; - newFirstCharMap[itemId] = instance.getNode(itemId).label!.substring(0, 1).toLowerCase(); - item.children?.forEach(processItem); + const processItem = (node: TreeViewNode) => { + newFirstCharMap[node.id] = node.label!.substring(0, 1).toLowerCase(); }; - params.items.forEach(processItem); + Object.values(state.nodes.nodeMap).forEach(processItem); firstCharMap.current = newFirstCharMap; - }, [params.items, params.getItemId, instance]); + }, [state.nodes.nodeMap, params.getItemId, instance]); const getFirstMatchingItem = (itemId: string, firstChar: string) => { let start: number; diff --git a/packages/x-tree-view/src/internals/plugins/useTreeViewNodes/useTreeViewNodes.ts b/packages/x-tree-view/src/internals/plugins/useTreeViewNodes/useTreeViewNodes.ts index 39a63d0281d8e..01f133f5b9c60 100644 --- a/packages/x-tree-view/src/internals/plugins/useTreeViewNodes/useTreeViewNodes.ts +++ b/packages/x-tree-view/src/internals/plugins/useTreeViewNodes/useTreeViewNodes.ts @@ -155,7 +155,18 @@ export const useTreeViewNodes: TreeViewPlugin = ({ return childrenIds; }; + const areItemUpdatesPreventedRef = React.useRef(false); + const preventItemUpdates = React.useCallback(() => { + areItemUpdatesPreventedRef.current = true; + }, []); + + const areItemUpdatesPrevented = React.useCallback(() => areItemUpdatesPreventedRef.current, []); + React.useEffect(() => { + if (instance.areItemUpdatesPrevented()) { + return; + } + setState((prevState) => { const newState = updateNodesState({ items: params.items, @@ -205,6 +216,8 @@ export const useTreeViewNodes: TreeViewPlugin = ({ getChildrenIds, getNavigableChildrenIds, isNodeDisabled, + preventItemUpdates, + areItemUpdatesPrevented, }); populatePublicAPI(publicAPI, { diff --git a/packages/x-tree-view/src/internals/plugins/useTreeViewNodes/useTreeViewNodes.types.ts b/packages/x-tree-view/src/internals/plugins/useTreeViewNodes/useTreeViewNodes.types.ts index 55a5bc1c52c95..352cf93605ff2 100644 --- a/packages/x-tree-view/src/internals/plugins/useTreeViewNodes/useTreeViewNodes.types.ts +++ b/packages/x-tree-view/src/internals/plugins/useTreeViewNodes/useTreeViewNodes.types.ts @@ -15,6 +15,17 @@ export interface UseTreeViewNodesInstance { getChildrenIds: (itemId: string | null) => string[]; getNavigableChildrenIds: (itemId: string | null) => string[]; isNodeDisabled: (itemId: string | null) => itemId is string; + /** + * Freeze any future update to the state based on the `items` prop. + * This is useful when `useTreeViewJSXNodes` is used to avoid having conflicting sources of truth. + */ + preventItemUpdates: () => void; + /** + * Check if the updates to the state based on the `items` prop are prevented. + * This is useful when `useTreeViewJSXNodes` is used to avoid having conflicting sources of truth. + * @returns {boolean} `true` if the updates to the state based on the `items` prop are prevented. + */ + areItemUpdatesPrevented: () => boolean; } export interface UseTreeViewNodesPublicAPI From 48677e475e985770a87b3e12eb3710fca640dbe4 Mon Sep 17 00:00:00 2001 From: Andrew Cherniavskii Date: Mon, 25 Mar 2024 14:24:14 +0100 Subject: [PATCH 14/55] [docs] Reduce noize in migration docs side navigation (#12552) --- docs/data/pages.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/data/pages.ts b/docs/data/pages.ts index 5ca6c1bd5d8f4..1adde55b0238c 100644 --- a/docs/data/pages.ts +++ b/docs/data/pages.ts @@ -537,7 +537,7 @@ const pages: MuiPage[] = [ }, { pathname: '/x/migration-v6', - subheader: 'Upgrade to v6', + title: 'Upgrade to v6', children: [ { pathname: '/x/migration/migration-data-grid-v5', title: 'Breaking changes: Data Grid' }, { @@ -552,7 +552,7 @@ const pages: MuiPage[] = [ }, { pathname: '/x/migration-earlier', - subheader: 'Earlier versions', + title: 'Earlier versions', children: [ { pathname: '/x/migration/migration-pickers-lab', From 655153081636d0e64c06497481daad3b52bfb5af Mon Sep 17 00:00:00 2001 From: Rom Grk Date: Mon, 25 Mar 2024 10:45:16 -0400 Subject: [PATCH 15/55] [DataGrid] Fix bug in suspense (#12553) --- .../src/components/columnHeaders/GridColumnHeaderItem.tsx | 4 +++- .../components/columnHeaders/GridGenericColumnHeaderItem.tsx | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/x-data-grid/src/components/columnHeaders/GridColumnHeaderItem.tsx b/packages/x-data-grid/src/components/columnHeaders/GridColumnHeaderItem.tsx index da14c18250aec..671f546d60179 100644 --- a/packages/x-data-grid/src/components/columnHeaders/GridColumnHeaderItem.tsx +++ b/packages/x-data-grid/src/components/columnHeaders/GridColumnHeaderItem.tsx @@ -258,7 +258,9 @@ function GridColumnHeaderItem(props: GridColumnHeaderItemProps) { const focusableElement = headerCellRef.current!.querySelector('[tabindex="0"]'); const elementToFocus = focusableElement || headerCellRef.current; elementToFocus?.focus(); - apiRef.current.columnHeadersContainerRef!.current!.scrollLeft = 0; + if (apiRef.current.columnHeadersContainerRef?.current) { + apiRef.current.columnHeadersContainerRef.current.scrollLeft = 0; + } } }, [apiRef, hasFocus]); diff --git a/packages/x-data-grid/src/components/columnHeaders/GridGenericColumnHeaderItem.tsx b/packages/x-data-grid/src/components/columnHeaders/GridGenericColumnHeaderItem.tsx index 8f45f8176d4a9..7b1111733f9e4 100644 --- a/packages/x-data-grid/src/components/columnHeaders/GridGenericColumnHeaderItem.tsx +++ b/packages/x-data-grid/src/components/columnHeaders/GridGenericColumnHeaderItem.tsx @@ -97,7 +97,9 @@ const GridGenericColumnHeaderItem = React.forwardRef(function GridGenericColumnH const focusableElement = headerCellRef.current!.querySelector('[tabindex="0"]'); const elementToFocus = focusableElement || headerCellRef.current; elementToFocus?.focus(); - apiRef.current.columnHeadersContainerRef!.current!.scrollLeft = 0; + if (apiRef.current.columnHeadersContainerRef?.current) { + apiRef.current.columnHeadersContainerRef.current.scrollLeft = 0; + } } }, [apiRef, hasFocus]); From 0e1dce4afeaf0146e1260fdf71ffc78d582ca28d Mon Sep 17 00:00:00 2001 From: Rom Grk Date: Mon, 25 Mar 2024 13:15:47 -0400 Subject: [PATCH 16/55] [docs] Add missing note to Data Grid migration guide (#12557) --- .../migration/migration-data-grid-v6/migration-data-grid-v6.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/data/migration/migration-data-grid-v6/migration-data-grid-v6.md b/docs/data/migration/migration-data-grid-v6/migration-data-grid-v6.md index 7a1f588a5eb87..3ed538523b733 100644 --- a/docs/data/migration/migration-data-grid-v6/migration-data-grid-v6.md +++ b/docs/data/migration/migration-data-grid-v6/migration-data-grid-v6.md @@ -510,6 +510,8 @@ See the [Direct state access](/x/react-data-grid/state/#direct-selector-access) - The `columnHeadersInner`, `columnHeadersInner--scrollable`, and `columnHeaderDropZone` classes were removed since the inner wrapper was removed in our effort to simplify the DOM structure and improve accessibility. - The `pinnedColumnHeaders`, `pinnedColumnHeaders--left`, and `pinnedColumnHeaders--right` classes were removed along with the element they were applied to. The pinned column headers now use `position: 'sticky'` and are rendered in the same row element as the regular column headers. +- The column headers and pinned section now require an explicit color. By default, the MUI `theme.palette.background.default` color will be used. To customize it, see https://mui.com/material-ui/customization/palette/#customization + We will be adding a new color name to the palette for additional customization, read [#12443](https://github.com/mui/mui-x/issues/12443) for more details. ### Changes to the public API From 00ad17b3f707e28126b1fa0a99339ba7f981da18 Mon Sep 17 00:00:00 2001 From: Diogo Parente <66437099+diogoparente@users.noreply.github.com> Date: Tue, 26 Mar 2024 06:20:19 +0000 Subject: [PATCH 17/55] [docs] Fix small typo (#12558) --- docs/data/pages.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/data/pages.ts b/docs/data/pages.ts index 1adde55b0238c..c53b315baa2f9 100644 --- a/docs/data/pages.ts +++ b/docs/data/pages.ts @@ -383,7 +383,7 @@ const pages: MuiPage[] = [ { pathname: '/x/react-date-pickers/custom-layout' }, { pathname: '/x/react-date-pickers/custom-field' }, { pathname: '/x/react-date-pickers/custom-opening-button' }, - { pathname: '/x/react-date-pickers/playground', title: 'Customziation playground' }, + { pathname: '/x/react-date-pickers/playground', title: 'Customization playground' }, ], }, ], From 6034acf255b6d36898ae71073613bfe093c1c68f Mon Sep 17 00:00:00 2001 From: samchiu90 <51096971+samchiu90@users.noreply.github.com> Date: Tue, 26 Mar 2024 14:21:57 +0800 Subject: [PATCH 18/55] [l10n] Improve Chinese (Hong Kong) (zh-HK) locale (#12547) Co-authored-by: Sam Chiu <341975@haeco.com> Co-authored-by: Lukas --- docs/data/date-pickers/localization/data.json | 2 +- packages/x-date-pickers/src/locales/zhHK.ts | 26 +++++++++---------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/docs/data/date-pickers/localization/data.json b/docs/data/date-pickers/localization/data.json index 97b551653c669..30db1a184762c 100644 --- a/docs/data/date-pickers/localization/data.json +++ b/docs/data/date-pickers/localization/data.json @@ -27,7 +27,7 @@ "languageTag": "zh-HK", "importName": "zhHK", "localeName": "Chinese (Hong Kong)", - "missingKeysCount": 14, + "missingKeysCount": 1, "totalKeysCount": 50, "githubLink": "https://github.com/mui/mui-x/blob/master/packages/x-date-pickers/src/locales/zhHK.ts" }, diff --git a/packages/x-date-pickers/src/locales/zhHK.ts b/packages/x-date-pickers/src/locales/zhHK.ts index dc1fc08f07924..73f30fe05cb6c 100644 --- a/packages/x-date-pickers/src/locales/zhHK.ts +++ b/packages/x-date-pickers/src/locales/zhHK.ts @@ -23,10 +23,10 @@ const zhHKPickers: Partial> = { // DateRange labels start: '開始', end: '結束', - // startDate: 'Start date', - // startTime: 'Start time', - // endDate: 'End date', - // endTime: 'End time', + startDate: '開始日期', + startTime: '開始時間', + endDate: '結束日期', + endTime: '結束時間', // Action bar cancelButtonLabel: '取消', @@ -82,17 +82,17 @@ const zhHKPickers: Partial> = { fieldMeridiemPlaceholder: () => 'aa', // View names - // year: 'Year', - // month: 'Month', - // day: 'Day', - // weekDay: 'Week day', - // hours: 'Hours', - // minutes: 'Minutes', - // seconds: 'Seconds', - // meridiem: 'Meridiem', + year: '年', + month: '月', + day: '日', + weekDay: '星期', + hours: '小時', + minutes: '分鐘', + seconds: '秒', + meridiem: '子午線', // Common - // empty: 'Empty', + empty: '空值', }; export const zhHK = getPickersLocalization(zhHKPickers); From 7f86c76db4d06bf04d6106ea8a6c6e6f8a887664 Mon Sep 17 00:00:00 2001 From: Flavien DELANGLE Date: Tue, 26 Mar 2024 09:41:12 +0100 Subject: [PATCH 19/55] [pickers] Prepare compatibility with `@mui/zero-runtime` (stop using `ownerState` in `styled`) (#12003) --- .../date-pickers/date-range-picker-day.json | 1 + .../date-range-picker-day.json | 3 + .../DateRangePickerDay/DateRangePickerDay.tsx | 135 ++++++++---- .../DateTimeRangePickerToolbar.tsx | 39 +++- .../src/DatePicker/DatePickerToolbar.tsx | 15 +- .../DateTimePicker/DateTimePickerToolbar.tsx | 122 +++++++---- .../DayCalendarSkeleton.tsx | 13 +- .../src/DigitalClock/DigitalClock.tsx | 16 +- .../src/MonthCalendar/PickersMonth.tsx | 7 +- .../MultiSectionDigitalClockSection.tsx | 14 +- .../PickersCalendarHeader.tsx | 17 +- .../src/PickersDay/PickersDay.tsx | 39 ++-- .../src/PickersLayout/PickersLayout.tsx | 36 ++-- .../PickersFilledInput/PickersFilledInput.tsx | 204 +++++++++++------- .../PickersInput/PickersInput.tsx | 129 ++++++----- .../PickersInputBase/PickersInputBase.tsx | 72 +++++-- .../PickersInputBase.types.ts | 7 + .../PickersOutlinedInput/Outline.tsx | 83 +++---- .../PickersOutlinedInput.tsx | 37 +++- .../x-date-pickers/src/TimeClock/Clock.tsx | 55 +++-- .../src/TimeClock/ClockNumber.tsx | 15 +- .../src/TimeClock/ClockPointer.tsx | 26 ++- .../src/TimePicker/TimePickerToolbar.tsx | 34 +-- .../src/YearCalendar/PickersYear.tsx | 7 +- .../PickersArrowSwitcher.tsx | 13 +- .../internals/components/PickersPopper.tsx | 16 +- .../internals/components/PickersToolbar.tsx | 47 ++-- 27 files changed, 791 insertions(+), 411 deletions(-) diff --git a/docs/pages/x/api/date-pickers/date-range-picker-day.json b/docs/pages/x/api/date-pickers/date-range-picker-day.json index fc19b9e50ec6d..fa57a2557f2b8 100644 --- a/docs/pages/x/api/date-pickers/date-range-picker-day.json +++ b/docs/pages/x/api/date-pickers/date-range-picker-day.json @@ -23,6 +23,7 @@ "disableMargin": { "type": { "name": "bool" }, "default": "false" }, "disableRipple": { "type": { "name": "bool" }, "default": "false" }, "disableTouchRipple": { "type": { "name": "bool" }, "default": "false" }, + "draggable": { "type": { "name": "bool" }, "default": "false" }, "focusRipple": { "type": { "name": "bool" }, "default": "false" }, "focusVisibleClassName": { "type": { "name": "string" } }, "isVisuallySelected": { "type": { "name": "bool" } }, diff --git a/docs/translations/api-docs/date-pickers/date-range-picker-day/date-range-picker-day.json b/docs/translations/api-docs/date-pickers/date-range-picker-day/date-range-picker-day.json index d24a2914f43b5..56e31a43dd71b 100644 --- a/docs/translations/api-docs/date-pickers/date-range-picker-day/date-range-picker-day.json +++ b/docs/translations/api-docs/date-pickers/date-range-picker-day/date-range-picker-day.json @@ -22,6 +22,9 @@ "disableTouchRipple": { "description": "If true, the touch ripple effect is disabled." }, + "draggable": { + "description": "If true, the day can be dragged to change the current date range." + }, "focusRipple": { "description": "If true, the base button will have a keyboard focus ripple." }, diff --git a/packages/x-date-pickers-pro/src/DateRangePickerDay/DateRangePickerDay.tsx b/packages/x-date-pickers-pro/src/DateRangePickerDay/DateRangePickerDay.tsx index 29c0be8863b86..95ca252d165ca 100644 --- a/packages/x-date-pickers-pro/src/DateRangePickerDay/DateRangePickerDay.tsx +++ b/packages/x-date-pickers-pro/src/DateRangePickerDay/DateRangePickerDay.tsx @@ -50,6 +50,11 @@ export interface DateRangePickerDayProps * Indicates if the day should be visually selected. */ isVisuallySelected?: boolean; + /** + * If `true`, the day can be dragged to change the current date range. + * @default false + */ + draggable?: boolean; } type OwnerState = DateRangePickerDayProps & { @@ -154,10 +159,11 @@ const DateRangePickerDayRoot = styled('div', { }, styles.root, ], -})<{ ownerState: OwnerState }>(({ theme, ownerState }) => - ownerState.isHiddenDayFiller - ? {} - : { +})<{ ownerState: OwnerState }>(({ theme }) => ({ + variants: [ + { + props: { isHiddenDayFiller: false }, + style: { [`&:first-of-type .${dateRangePickerDayClasses.rangeIntervalDayPreview}`]: { ...startBorderStyle, borderLeftColor: (theme.vars || theme).palette.divider, @@ -166,25 +172,44 @@ const DateRangePickerDayRoot = styled('div', { ...endBorderStyle, borderRightColor: (theme.vars || theme).palette.divider, }, - ...(ownerState.isHighlighting && { - borderRadius: 0, - color: (theme.vars || theme).palette.primary.contrastText, - backgroundColor: theme.vars - ? `rgba(${theme.vars.palette.primary.mainChannel} / ${theme.vars.palette.action.focusOpacity})` - : alpha(theme.palette.primary.main, theme.palette.action.focusOpacity), - '&:first-of-type': startBorderStyle, - '&:last-of-type': endBorderStyle, - }), - ...((ownerState.isStartOfHighlighting || ownerState.isFirstVisibleCell) && { - ...startBorderStyle, - paddingLeft: 0, - }), - ...((ownerState.isEndOfHighlighting || ownerState.isLastVisibleCell) && { - ...endBorderStyle, - paddingRight: 0, - }), }, -); + }, + { + props: { isHiddenDayFiller: false, isHighlighting: true }, + style: { + borderRadius: 0, + color: (theme.vars || theme).palette.primary.contrastText, + backgroundColor: theme.vars + ? `rgba(${theme.vars.palette.primary.mainChannel} / ${theme.vars.palette.action.focusOpacity})` + : alpha(theme.palette.primary.main, theme.palette.action.focusOpacity), + '&:first-of-type': startBorderStyle, + '&:last-of-type': endBorderStyle, + }, + }, + { + props: ({ + ownerState: { isHiddenDayFiller, isStartOfHighlighting, isFirstVisibleCell }, + }: { + ownerState: OwnerState; + }) => !isHiddenDayFiller && (isStartOfHighlighting || isFirstVisibleCell), + style: { + ...startBorderStyle, + paddingLeft: 0, + }, + }, + { + props: ({ + ownerState: { isHiddenDayFiller, isEndOfHighlighting, isLastVisibleCell }, + }: { + ownerState: OwnerState; + }) => !isHiddenDayFiller && (isEndOfHighlighting || isLastVisibleCell), + style: { + ...endBorderStyle, + paddingRight: 0, + }, + }, + ], +})); DateRangePickerDayRoot.propTypes = { // ----------------------------- Warning -------------------------------- @@ -209,24 +234,42 @@ const DateRangePickerDayRangeIntervalPreview = styled('div', { }, styles.rangeIntervalPreview, ], -})<{ ownerState: OwnerState }>(({ theme, ownerState }) => ({ +})<{ ownerState: OwnerState }>(({ theme }) => ({ // replace default day component margin with transparent border to avoid jumping on preview border: '2px solid transparent', - ...(ownerState.isPreviewing && - !ownerState.isHiddenDayFiller && { - borderRadius: 0, - border: `2px dashed ${(theme.vars || theme).palette.divider}`, - borderLeftColor: 'transparent', - borderRightColor: 'transparent', - ...((ownerState.isStartOfPreviewing || ownerState.isFirstVisibleCell) && { + variants: [ + { + props: { isPreviewing: true, isHiddenDayFiller: false }, + style: { + borderRadius: 0, + border: `2px dashed ${(theme.vars || theme).palette.divider}`, + borderLeftColor: 'transparent', + borderRightColor: 'transparent', + }, + }, + { + props: ({ + ownerState: { isPreviewing, isHiddenDayFiller, isStartOfPreviewing, isFirstVisibleCell }, + }: { + ownerState: OwnerState; + }) => isPreviewing && !isHiddenDayFiller && (isStartOfPreviewing || isFirstVisibleCell), + style: { borderLeftColor: (theme.vars || theme).palette.divider, ...startBorderStyle, - }), - ...((ownerState.isEndOfPreviewing || ownerState.isLastVisibleCell) && { + }, + }, + { + props: ({ + ownerState: { isPreviewing, isHiddenDayFiller, isEndOfPreviewing, isLastVisibleCell }, + }: { + ownerState: OwnerState; + }) => isPreviewing && !isHiddenDayFiller && (isEndOfPreviewing || isLastVisibleCell), + style: { borderRightColor: (theme.vars || theme).palette.divider, ...endBorderStyle, - }), - }), + }, + }, + ], })); DateRangePickerDayRangeIntervalPreview.propTypes = { @@ -248,19 +291,22 @@ const DateRangePickerDayDay = styled(PickersDay, { ], })<{ ownerState: OwnerState; -}>(({ ownerState }) => ({ +}>({ // Required to overlap preview border transform: 'scale(1.1)', '& > *': { transform: 'scale(0.9)', }, - ...(ownerState.draggable && { - cursor: 'grab', - }), - ...(ownerState.draggable && { - touchAction: 'none', - }), -})) as unknown as ( + variants: [ + { + props: { draggable: true }, + style: { + cursor: 'grab', + touchAction: 'none', + }, + }, + ], +}) as unknown as ( props: PickersDayProps & { ownerState: OwnerState }, ) => React.JSX.Element; @@ -405,6 +451,11 @@ DateRangePickerDayRaw.propTypes = { * @default false */ disableTouchRipple: PropTypes.bool, + /** + * If `true`, the day can be dragged to change the current date range. + * @default false + */ + draggable: PropTypes.bool, /** * If `true`, the base button will have a keyboard focus ripple. * @default false diff --git a/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePickerToolbar.tsx b/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePickerToolbar.tsx index 32fbf3ec18ba1..4d4c6155c38ee 100644 --- a/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePickerToolbar.tsx +++ b/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePickerToolbar.tsx @@ -76,24 +76,43 @@ const DateTimeRangePickerToolbarStart = styled(DateTimePickerToolbar, { name: 'MuiDateTimeRangePickerToolbar', slot: 'StartToolbar', overridesResolver: (_, styles) => styles.startToolbar, -})>(({ ownerState }) => ({ +})>({ borderBottom: 'none', - ...(ownerState?.toolbarVariant !== 'desktop' - ? { + variants: [ + { + props: ({ toolbarVariant }: DateTimeRangePickerStartOrEndToolbarProps) => + toolbarVariant !== 'desktop', + style: { padding: '12px 8px 0 12px', - } - : { + }, + }, + { + props: { toolbarVariant: 'desktop' }, + style: { paddingBottom: 0, - }), -})) as DateTimeRangePickerStartOrEndToolbarComponent; + }, + }, + ], +}) as DateTimeRangePickerStartOrEndToolbarComponent; const DateTimeRangePickerToolbarEnd = styled(DateTimePickerToolbar, { name: 'MuiDateTimeRangePickerToolbar', slot: 'EndToolbar', overridesResolver: (_, styles) => styles.endToolbar, -})>(({ ownerState }) => ({ - padding: ownerState?.toolbarVariant !== 'desktop' ? '12px 8px 12px 12px' : undefined, -})) as DateTimeRangePickerStartOrEndToolbarComponent; +})>({ + variants: [ + { + props: ({ + ownerState: { toolbarVariant }, + }: { + ownerState: DateTimeRangePickerStartOrEndToolbarProps; + }) => toolbarVariant !== 'desktop', + style: { + padding: '12px 8px 12px 12px', + }, + }, + ], +}) as DateTimeRangePickerStartOrEndToolbarComponent; const DateTimeRangePickerToolbar = React.forwardRef(function DateTimeRangePickerToolbar< TDate extends PickerValidDate, diff --git a/packages/x-date-pickers/src/DatePicker/DatePickerToolbar.tsx b/packages/x-date-pickers/src/DatePicker/DatePickerToolbar.tsx index 820e0f5ed83a0..9e0dbdba817dc 100644 --- a/packages/x-date-pickers/src/DatePicker/DatePickerToolbar.tsx +++ b/packages/x-date-pickers/src/DatePicker/DatePickerToolbar.tsx @@ -45,11 +45,16 @@ const DatePickerToolbarTitle = styled(Typography, { name: 'MuiDatePickerToolbar', slot: 'Title', overridesResolver: (_, styles) => styles.title, -})<{ ownerState: DatePickerToolbarProps }>(({ ownerState }) => ({ - ...(ownerState.isLandscape && { - margin: 'auto 16px auto auto', - }), -})); +})<{ ownerState: DatePickerToolbarProps }>({ + variants: [ + { + props: { isLandscape: true }, + style: { + margin: 'auto 16px auto auto', + }, + }, + ], +}); type DatePickerToolbarComponent = (( props: DatePickerToolbarProps & React.RefAttributes, diff --git a/packages/x-date-pickers/src/DateTimePicker/DateTimePickerToolbar.tsx b/packages/x-date-pickers/src/DateTimePicker/DateTimePickerToolbar.tsx index f100e3fbe33b7..21593a3f60819 100644 --- a/packages/x-date-pickers/src/DateTimePicker/DateTimePickerToolbar.tsx +++ b/packages/x-date-pickers/src/DateTimePicker/DateTimePickerToolbar.tsx @@ -60,25 +60,36 @@ const DateTimePickerToolbarRoot = styled(PickersToolbar, { name: 'MuiDateTimePickerToolbar', slot: 'Root', overridesResolver: (props, styles) => styles.root, -})<{ ownerState: DateTimePickerToolbarProps }>(({ theme, ownerState }) => ({ - paddingLeft: ownerState.toolbarVariant === 'desktop' && !ownerState.isLandscape ? 24 : 16, - paddingRight: ownerState.toolbarVariant === 'desktop' && !ownerState.isLandscape ? 0 : 16, - borderBottom: - ownerState.toolbarVariant === 'desktop' - ? `1px solid ${(theme.vars || theme).palette.divider}` - : undefined, - borderRight: - ownerState.toolbarVariant === 'desktop' && ownerState.isLandscape - ? `1px solid ${(theme.vars || theme).palette.divider}` - : undefined, +})<{ ownerState: DateTimePickerToolbarProps }>(({ theme }) => ({ + paddingLeft: 16, + paddingRight: 16, justifyContent: 'space-around', position: 'relative', - ...(ownerState.toolbarVariant === 'desktop' && { - [`& .${pickersToolbarClasses.content} .${pickersToolbarTextClasses.selected}`]: { - color: (theme.vars || theme).palette.primary.main, - fontWeight: theme.typography.fontWeightBold, + variants: [ + { + props: { toolbarVariant: 'desktop' }, + style: { + borderBottom: `1px solid ${(theme.vars || theme).palette.divider}`, + [`& .${pickersToolbarClasses.content} .${pickersToolbarTextClasses.selected}`]: { + color: (theme.vars || theme).palette.primary.main, + fontWeight: theme.typography.fontWeightBold, + }, + }, }, - }), + { + props: { toolbarVariant: 'desktop', isLandscape: true }, + style: { + borderRight: `1px solid ${(theme.vars || theme).palette.divider}`, + }, + }, + { + props: { toolbarVariant: 'desktop', isLandscape: false }, + style: { + paddingLeft: 24, + paddingRight: 0, + }, + }, + ], })); DateTimePickerToolbarRoot.propTypes = { @@ -117,22 +128,33 @@ const DateTimePickerToolbarTimeContainer = styled('div', { name: 'MuiDateTimePickerToolbar', slot: 'TimeContainer', overridesResolver: (props, styles) => styles.timeContainer, -})<{ ownerState: DateTimePickerToolbarProps }>(({ theme, ownerState }) => { - const direction = - ownerState.isLandscape && ownerState.toolbarVariant !== 'desktop' ? 'column' : 'row'; +})<{ ownerState: DateTimePickerToolbarProps }>(({ theme }) => { return { display: 'flex', - flexDirection: direction, - ...(ownerState.toolbarVariant === 'desktop' && { - ...(!ownerState.isLandscape && { - gap: 9, - marginRight: 4, - alignSelf: 'flex-end', - }), - }), + flexDirection: 'row', ...(theme.direction === 'rtl' && { - flexDirection: `${direction}-reverse`, + flexDirection: 'row-reverse', }), + variants: [ + { + props: ({ isLandscape, toolbarVariant }: DateTimePickerToolbarProps) => + isLandscape && toolbarVariant !== 'desktop', + style: { + flexDirection: 'column', + ...(theme.direction === 'rtl' && { + flexDirection: 'column-reverse', + }), + }, + }, + { + props: { toolbarVariant: 'desktop', isLandscape: false }, + style: { + gap: 9, + marginRight: 4, + alignSelf: 'flex-end', + }, + }, + ], }; }); @@ -140,12 +162,17 @@ const DateTimePickerToolbarTimeDigitsContainer = styled('div', { name: 'MuiDateTimePickerToolbar', slot: 'TimeDigitsContainer', overridesResolver: (props, styles) => styles.timeDigitsContainer, -})<{ ownerState: DateTimePickerToolbarProps }>(({ theme, ownerState }) => ({ +})<{ ownerState: DateTimePickerToolbarProps }>(({ theme }) => ({ display: 'flex', - ...(ownerState.toolbarVariant === 'desktop' && { gap: 1.5 }), ...(theme.direction === 'rtl' && { flexDirection: 'row-reverse', }), + variants: [ + { + props: { toolbarVariant: 'desktop' }, + style: { gap: 1.5 }, + }, + ], })); DateTimePickerToolbarTimeContainer.propTypes = { @@ -168,10 +195,18 @@ const DateTimePickerToolbarSeparator = styled(PickersToolbarText, { overridesResolver: (props, styles) => styles.separator, })<{ ownerState: DateTimePickerToolbarProps; -}>(({ ownerState }) => ({ - margin: ownerState.toolbarVariant === 'desktop' ? 0 : '0 4px 0 2px', +}>({ + margin: '0 4px 0 2px', cursor: 'default', -})); + variants: [ + { + props: { toolbarVariant: 'desktop' }, + style: { + margin: 0, + }, + }, + ], +}); // Taken from TimePickerToolbar const DateTimePickerToolbarAmPmSelection = styled('div', { @@ -184,21 +219,26 @@ const DateTimePickerToolbarAmPmSelection = styled('div', { ], })<{ ownerState: DateTimePickerToolbarProps; -}>(({ ownerState }) => ({ +}>({ display: 'flex', flexDirection: 'column', marginRight: 'auto', marginLeft: 12, - ...(ownerState.isLandscape && { - margin: '4px 0 auto', - flexDirection: 'row', - justifyContent: 'space-around', - width: '100%', - }), [`& .${dateTimePickerToolbarClasses.ampmLabel}`]: { fontSize: 17, }, -})); + variants: [ + { + props: { isLandscape: true }, + style: { + margin: '4px 0 auto', + flexDirection: 'row', + justifyContent: 'space-around', + width: '100%', + }, + }, + ], +}); /** * Demos: diff --git a/packages/x-date-pickers/src/DayCalendarSkeleton/DayCalendarSkeleton.tsx b/packages/x-date-pickers/src/DayCalendarSkeleton/DayCalendarSkeleton.tsx index cca99858f8aea..1af619f65904d 100644 --- a/packages/x-date-pickers/src/DayCalendarSkeleton/DayCalendarSkeleton.tsx +++ b/packages/x-date-pickers/src/DayCalendarSkeleton/DayCalendarSkeleton.tsx @@ -58,12 +58,15 @@ const DayCalendarSkeletonDay = styled(Skeleton, { name: 'MuiDayCalendarSkeleton', slot: 'DaySkeleton', overridesResolver: (props, styles) => styles.daySkeleton, -})<{ ownerState: { day: number } }>(({ ownerState }) => ({ +})<{ ownerState: { day: number } }>({ margin: `0 ${DAY_MARGIN}px`, - ...(ownerState.day === 0 && { - visibility: 'hidden', - }), -})); + variants: [ + { + props: { day: 0 }, + style: { visibility: 'hidden' }, + }, + ], +}); DayCalendarSkeletonDay.propTypes = { // ----------------------------- Warning -------------------------------- diff --git a/packages/x-date-pickers/src/DigitalClock/DigitalClock.tsx b/packages/x-date-pickers/src/DigitalClock/DigitalClock.tsx index e3824be369071..19b45e4c99a2e 100644 --- a/packages/x-date-pickers/src/DigitalClock/DigitalClock.tsx +++ b/packages/x-date-pickers/src/DigitalClock/DigitalClock.tsx @@ -35,14 +35,24 @@ const DigitalClockRoot = styled(PickerViewRoot, { name: 'MuiDigitalClock', slot: 'Root', overridesResolver: (props, styles) => styles.root, -})<{ ownerState: DigitalClockProps & { alreadyRendered: boolean } }>(({ ownerState }) => ({ +})<{ ownerState: DigitalClockProps & { alreadyRendered: boolean } }>({ overflowY: 'auto', width: '100%', '@media (prefers-reduced-motion: no-preference)': { - scrollBehavior: ownerState.alreadyRendered ? 'smooth' : 'auto', + scrollBehavior: 'auto', }, maxHeight: DIGITAL_CLOCK_VIEW_HEIGHT, -})); + variants: [ + { + props: { alreadyRendered: true }, + style: { + '@media (prefers-reduced-motion: no-preference)': { + scrollBehavior: 'smooth', + }, + }, + }, + ], +}); const DigitalClockList = styled(MenuList, { name: 'MuiDigitalClock', diff --git a/packages/x-date-pickers/src/MonthCalendar/PickersMonth.tsx b/packages/x-date-pickers/src/MonthCalendar/PickersMonth.tsx index bbb4bcb1db97b..daae053f66c4d 100644 --- a/packages/x-date-pickers/src/MonthCalendar/PickersMonth.tsx +++ b/packages/x-date-pickers/src/MonthCalendar/PickersMonth.tsx @@ -47,12 +47,13 @@ const PickersMonthRoot = styled('div', { overridesResolver: (_, styles) => [styles.root], })<{ ownerState: PickersMonthProps; -}>(({ ownerState }) => ({ - flexBasis: ownerState.monthsPerRow === 3 ? '33.3%' : '25%', +}>({ display: 'flex', alignItems: 'center', justifyContent: 'center', -})); + flexBasis: '33.3%', + variants: [{ props: { monthsPerRow: 4 }, style: { flexBasis: '25%' } }], +}); const PickersMonthButton = styled('button', { name: 'MuiPickersMonth', diff --git a/packages/x-date-pickers/src/MultiSectionDigitalClock/MultiSectionDigitalClockSection.tsx b/packages/x-date-pickers/src/MultiSectionDigitalClock/MultiSectionDigitalClockSection.tsx index ced9449549135..cbc6a60df7a0b 100644 --- a/packages/x-date-pickers/src/MultiSectionDigitalClock/MultiSectionDigitalClockSection.tsx +++ b/packages/x-date-pickers/src/MultiSectionDigitalClock/MultiSectionDigitalClockSection.tsx @@ -53,13 +53,13 @@ const MultiSectionDigitalClockSectionRoot = styled(MenuList, { slot: 'Root', overridesResolver: (_, styles) => styles.root, })<{ ownerState: MultiSectionDigitalClockSectionProps & { alreadyRendered: boolean } }>( - ({ theme, ownerState }) => ({ + ({ theme }) => ({ maxHeight: DIGITAL_CLOCK_VIEW_HEIGHT, width: 56, padding: 0, overflow: 'hidden', '@media (prefers-reduced-motion: no-preference)': { - scrollBehavior: ownerState.alreadyRendered ? 'smooth' : 'auto', + scrollBehavior: 'auto', }, '@media (pointer: fine)': { '&:hover': { @@ -78,6 +78,16 @@ const MultiSectionDigitalClockSectionRoot = styled(MenuList, { // subtracting the height of one item, extra margin and borders to make sure the max height is correct height: 'calc(100% - 40px - 6px)', }, + variants: [ + { + props: { alreadyRendered: true }, + style: { + '@media (prefers-reduced-motion: no-preference)': { + scrollBehavior: 'smooth', + }, + }, + }, + ], }), ); diff --git a/packages/x-date-pickers/src/PickersCalendarHeader/PickersCalendarHeader.tsx b/packages/x-date-pickers/src/PickersCalendarHeader/PickersCalendarHeader.tsx index a18d69b4540f5..e7bbfe369dc55 100644 --- a/packages/x-date-pickers/src/PickersCalendarHeader/PickersCalendarHeader.tsx +++ b/packages/x-date-pickers/src/PickersCalendarHeader/PickersCalendarHeader.tsx @@ -87,14 +87,19 @@ const PickersCalendarHeaderSwitchViewButton = styled(IconButton, { overridesResolver: (_, styles) => styles.switchViewButton, })<{ ownerState: PickersCalendarHeaderOwnerState; -}>(({ ownerState }) => ({ +}>({ marginRight: 'auto', - ...(ownerState.view === 'year' && { - [`.${pickersCalendarHeaderClasses.switchViewIcon}`]: { - transform: 'rotate(180deg)', + variants: [ + { + props: { view: 'year' }, + style: { + [`.${pickersCalendarHeaderClasses.switchViewIcon}`]: { + transform: 'rotate(180deg)', + }, + }, }, - }), -})); + ], +}); const PickersCalendarHeaderSwitchViewIcon = styled(ArrowDropDownIcon, { name: 'MuiPickersCalendarHeader', diff --git a/packages/x-date-pickers/src/PickersDay/PickersDay.tsx b/packages/x-date-pickers/src/PickersDay/PickersDay.tsx index b0ed7b3ac0eb7..a614588756fd6 100644 --- a/packages/x-date-pickers/src/PickersDay/PickersDay.tsx +++ b/packages/x-date-pickers/src/PickersDay/PickersDay.tsx @@ -127,7 +127,7 @@ const useUtilityClasses = (ownerState: PickersDayProps) => { return composeClasses(slots, getPickersDayUtilityClass, classes); }; -const styleArg = ({ theme, ownerState }: { theme: Theme; ownerState: OwnerState }) => ({ +const styleArg = ({ theme }: { theme: Theme }) => ({ ...theme.typography.caption, width: DAY_SIZE, height: DAY_SIZE, @@ -170,19 +170,28 @@ const styleArg = ({ theme, ownerState }: { theme: Theme; ownerState: OwnerState [`&.${pickersDayClasses.disabled}&.${pickersDayClasses.selected}`]: { opacity: 0.6, }, - ...(!ownerState.disableMargin && { - margin: `0 ${DAY_MARGIN}px`, - }), - ...(ownerState.outsideCurrentMonth && - ownerState.showDaysOutsideCurrentMonth && { - color: (theme.vars || theme).palette.text.secondary, - }), - ...(!ownerState.disableHighlightToday && - ownerState.today && { - [`&:not(.${pickersDayClasses.selected})`]: { - border: `1px solid ${(theme.vars || theme).palette.text.secondary}`, + variants: [ + { + props: { disableMargin: false }, + style: { + margin: `0 ${DAY_MARGIN}px`, }, - }), + }, + { + props: { outsideCurrentMonth: true, showDaysOutsideCurrentMonth: true }, + style: { + color: (theme.vars || theme).palette.text.secondary, + }, + }, + { + props: { disableHighlightToday: false, today: true }, + style: { + [`&:not(.${pickersDayClasses.selected})`]: { + border: `1px solid ${(theme.vars || theme).palette.text.secondary}`, + }, + }, + }, + ], }); const overridesResolver = ( @@ -213,8 +222,8 @@ const PickersDayFiller = styled('div', { name: 'MuiPickersDay', slot: 'Root', overridesResolver, -})<{ ownerState: OwnerState }>(({ theme, ownerState }) => ({ - ...styleArg({ theme, ownerState }), +})<{ ownerState: OwnerState }>(({ theme }) => ({ + ...styleArg({ theme }), // visibility: 'hidden' does not work here as it hides the element from screen readers as well opacity: 0, pointerEvents: 'none', diff --git a/packages/x-date-pickers/src/PickersLayout/PickersLayout.tsx b/packages/x-date-pickers/src/PickersLayout/PickersLayout.tsx index ac97bf691f5d1..0937bce1cb7f7 100644 --- a/packages/x-date-pickers/src/PickersLayout/PickersLayout.tsx +++ b/packages/x-date-pickers/src/PickersLayout/PickersLayout.tsx @@ -23,23 +23,33 @@ const PickersLayoutRoot = styled('div', { name: 'MuiPickersLayout', slot: 'Root', overridesResolver: (props, styles) => styles.root, -})<{ ownerState: { isLandscape: boolean } }>(({ theme, ownerState }) => ({ +})<{ ownerState: { isLandscape: boolean } }>(({ theme }) => ({ display: 'grid', gridAutoColumns: 'max-content auto max-content', gridAutoRows: 'max-content auto max-content', - [`& .${pickersLayoutClasses.toolbar}`]: ownerState.isLandscape - ? { - gridColumn: theme.direction === 'rtl' ? 3 : 1, - gridRow: '2 / 3', - } - : { gridColumn: '2 / 4', gridRow: 1 }, - [`.${pickersLayoutClasses.shortcuts}`]: ownerState.isLandscape - ? { gridColumn: '2 / 4', gridRow: 1 } - : { - gridColumn: theme.direction === 'rtl' ? 3 : 1, - gridRow: '2 / 3', - }, [`& .${pickersLayoutClasses.actionBar}`]: { gridColumn: '1 / 4', gridRow: 3 }, + variants: [ + { + props: { isLandscape: true }, + style: { + [`& .${pickersLayoutClasses.toolbar}`]: { + gridColumn: theme.direction === 'rtl' ? 3 : 1, + gridRow: '2 / 3', + }, + [`.${pickersLayoutClasses.shortcuts}`]: { gridColumn: '2 / 4', gridRow: 1 }, + }, + }, + { + props: { isLandscape: false }, + style: { + [`& .${pickersLayoutClasses.toolbar}`]: { gridColumn: '2 / 4', gridRow: 1 }, + [`& .${pickersLayoutClasses.shortcuts}`]: { + gridColumn: theme.direction === 'rtl' ? 3 : 1, + gridRow: '2 / 3', + }, + }, + }, + ], })); PickersLayoutRoot.propTypes = { diff --git a/packages/x-date-pickers/src/PickersTextField/PickersFilledInput/PickersFilledInput.tsx b/packages/x-date-pickers/src/PickersTextField/PickersFilledInput/PickersFilledInput.tsx index 95d9343c5893f..e86c0556e22d6 100644 --- a/packages/x-date-pickers/src/PickersTextField/PickersFilledInput/PickersFilledInput.tsx +++ b/packages/x-date-pickers/src/PickersTextField/PickersFilledInput/PickersFilledInput.tsx @@ -2,6 +2,7 @@ import * as React from 'react'; import PropTypes from 'prop-types'; import { FormControlState, useFormControl } from '@mui/material/FormControl'; import { styled, useThemeProps } from '@mui/material/styles'; +import { shouldForwardProp } from '@mui/system'; import { refType } from '@mui/utils'; import composeClasses from '@mui/utils/composeClasses'; import { @@ -23,7 +24,8 @@ const PickersFilledInputRoot = styled(PickersInputBaseRoot, { name: 'MuiPickersFilledInput', slot: 'Root', overridesResolver: (props, styles) => styles.root, -})<{ ownerState: OwnerStateType }>(({ theme, ownerState }) => { + shouldForwardProp: (prop) => shouldForwardProp(prop) && prop !== 'disableUnderline', +})<{ ownerState: OwnerStateType }>(({ theme }) => { const light = theme.palette.mode === 'light'; const bottomLineColor = light ? 'rgba(0, 0, 0, 0.42)' : 'rgba(255, 255, 255, 0.7)'; const backgroundColor = light ? 'rgba(0, 0, 0, 0.06)' : 'rgba(255, 255, 255, 0.09)'; @@ -51,65 +53,85 @@ const PickersFilledInputRoot = styled(PickersInputBaseRoot, { [`&.${pickersFilledInputClasses.disabled}`]: { backgroundColor: theme.vars ? theme.vars.palette.FilledInput.disabledBg : disabledBackground, }, - ...(!ownerState.disableUnderline && { - '&::after': { - borderBottom: `2px solid ${ - (theme.vars || theme).palette[ownerState.color || 'primary']?.main - }`, - left: 0, - bottom: 0, - // Doing the other way around crash on IE11 "''" https://github.com/cssinjs/jss/issues/242 - content: '""', - position: 'absolute', - right: 0, - transform: 'scaleX(0)', - transition: theme.transitions.create('transform', { - duration: theme.transitions.duration.shorter, - easing: theme.transitions.easing.easeOut, - }), - pointerEvents: 'none', // Transparent to the hover style. - }, - [`&.${pickersFilledInputClasses.focused}:after`]: { - // translateX(0) is a workaround for Safari transform scale bug - // See https://github.com/mui/material-ui/issues/31766 - transform: 'scaleX(1) translateX(0)', - }, - [`&.${pickersFilledInputClasses.error}`]: { - '&:before, &:after': { - borderBottomColor: (theme.vars || theme).palette.error.main, + variants: [ + ...Object.keys((theme.vars ?? theme).palette) + // @ts-ignore + .filter((key) => (theme.vars ?? theme).palette[key].main) + .map((color) => ({ + props: { color, disableUnderline: false }, + style: { + '&::after': { + // @ts-ignore + borderBottom: `2px solid ${(theme.vars || theme).palette[color]?.main}`, + }, + }, + })), + { + props: { disableUnderline: false }, + style: { + '&::after': { + left: 0, + bottom: 0, + // Doing the other way around crash on IE11 "''" https://github.com/cssinjs/jss/issues/242 + content: '""', + position: 'absolute', + right: 0, + transform: 'scaleX(0)', + transition: theme.transitions.create('transform', { + duration: theme.transitions.duration.shorter, + easing: theme.transitions.easing.easeOut, + }), + pointerEvents: 'none', // Transparent to the hover style. + }, + [`&.${pickersFilledInputClasses.focused}:after`]: { + // translateX(0) is a workaround for Safari transform scale bug + // See https://github.com/mui/material-ui/issues/31766 + transform: 'scaleX(1) translateX(0)', + }, + [`&.${pickersFilledInputClasses.error}`]: { + '&:before, &:after': { + borderBottomColor: (theme.vars || theme).palette.error.main, + }, + }, + '&::before': { + borderBottom: `1px solid ${ + theme.vars + ? `rgba(${theme.vars.palette.common.onBackgroundChannel} / ${theme.vars.opacity.inputUnderline})` + : bottomLineColor + }`, + left: 0, + bottom: 0, + // Doing the other way around crash on IE11 "''" https://github.com/cssinjs/jss/issues/242 + content: '"\\00a0"', + position: 'absolute', + right: 0, + transition: theme.transitions.create('border-bottom-color', { + duration: theme.transitions.duration.shorter, + }), + pointerEvents: 'none', // Transparent to the hover style. + }, + [`&:hover:not(.${pickersFilledInputClasses.disabled}, .${pickersFilledInputClasses.error}):before`]: + { + borderBottom: `1px solid ${(theme.vars || theme).palette.text.primary}`, + }, + [`&.${pickersFilledInputClasses.disabled}:before`]: { + borderBottomStyle: 'dotted', + }, }, }, - '&::before': { - borderBottom: `1px solid ${ - theme.vars - ? `rgba(${theme.vars.palette.common.onBackgroundChannel} / ${theme.vars.opacity.inputUnderline})` - : bottomLineColor - }`, - left: 0, - bottom: 0, - // Doing the other way around crash on IE11 "''" https://github.com/cssinjs/jss/issues/242 - content: '"\\00a0"', - position: 'absolute', - right: 0, - transition: theme.transitions.create('border-bottom-color', { - duration: theme.transitions.duration.shorter, - }), - pointerEvents: 'none', // Transparent to the hover style. + { + props: ({ startAdornment }: OwnerStateType) => !!startAdornment, + style: { + paddingLeft: 12, + }, }, - [`&:hover:not(.${pickersFilledInputClasses.disabled}, .${pickersFilledInputClasses.error}):before`]: - { - borderBottom: `1px solid ${(theme.vars || theme).palette.text.primary}`, + { + props: ({ endAdornment }: OwnerStateType) => !!endAdornment, + style: { + paddingRight: 12, }, - [`&.${pickersFilledInputClasses.disabled}:before`]: { - borderBottomStyle: 'dotted', }, - }), - ...(ownerState.startAdornment && { - paddingLeft: 12, - }), - ...(ownerState.endAdornment && { - paddingRight: 12, - }), + ], }; }); @@ -117,31 +139,47 @@ const PickersFilledSectionsContainer = styled(PickersInputBaseSectionsContainer, name: 'MuiPickersFilledInput', slot: 'sectionsContainer', overridesResolver: (props, styles) => styles.sectionsContainer, -})<{ ownerState: OwnerStateType }>(({ ownerState }) => ({ +})<{ ownerState: OwnerStateType }>({ paddingTop: 25, paddingRight: 12, paddingBottom: 8, paddingLeft: 12, - ...(ownerState.size === 'small' && { - paddingTop: 21, - paddingBottom: 4, - }), - ...(ownerState.startAdornment && { - paddingLeft: 0, - }), - ...(ownerState.endAdornment && { - paddingRight: 0, - }), - ...(ownerState.hiddenLabel && { - paddingTop: 16, - paddingBottom: 17, - }), - ...(ownerState.hiddenLabel && - ownerState.size === 'small' && { - paddingTop: 8, - paddingBottom: 9, - }), -})); + variants: [ + { + props: { size: 'small' }, + style: { + paddingTop: 21, + paddingBottom: 4, + }, + }, + { + props: ({ startAdornment }: OwnerStateType) => !!startAdornment, + style: { + paddingLeft: 0, + }, + }, + { + props: ({ endAdornment }: OwnerStateType) => !!endAdornment, + style: { + paddingRight: 0, + }, + }, + { + props: { hiddenLabel: true }, + style: { + paddingTop: 16, + paddingBottom: 17, + }, + }, + { + props: { hiddenLabel: true, size: 'small' }, + style: { + paddingTop: 8, + paddingBottom: 9, + }, + }, + ], +}); const useUtilityClasses = (ownerState: OwnerStateType) => { const { classes, disableUnderline } = ownerState; @@ -175,7 +213,13 @@ const PickersFilledInput = React.forwardRef(function PickersFilledInput( name: 'MuiPickersFilledInput', }); - const { label, autoFocus, ownerState: ownerStateProp, ...other } = props; + const { + label, + autoFocus, + disableUnderline = false, + ownerState: ownerStateProp, + ...other + } = props; const muiFormControl = useFormControl(); @@ -190,6 +234,7 @@ const PickersFilledInput = React.forwardRef(function PickersFilledInput( return ( styles.root, -})<{ ownerState: OwnerStateType }>(({ theme, ownerState }) => { +})<{ ownerState: OwnerStateType }>(({ theme }) => { const light = theme.palette.mode === 'light'; let bottomLineColor = light ? 'rgba(0, 0, 0, 0.42)' : 'rgba(255, 255, 255, 0.7)'; if (theme.vars) { @@ -26,58 +26,73 @@ const PickersInputRoot = styled(PickersInputBaseRoot, { 'label + &': { marginTop: 16, }, - ...(!ownerState.disableUnderline && { - '&::after': { - background: 'red', + variants: [ + ...Object.keys((theme.vars ?? theme).palette) // @ts-ignore - borderBottom: `2px solid ${(theme.vars || theme).palette[ownerState.color].main}`, - left: 0, - bottom: 0, - // Doing the other way around crash on IE11 "''" https://github.com/cssinjs/jss/issues/242 - content: '""', - position: 'absolute', - right: 0, - transform: 'scaleX(0)', - transition: theme.transitions.create('transform', { - duration: theme.transitions.duration.shorter, - easing: theme.transitions.easing.easeOut, - }), - pointerEvents: 'none', // Transparent to the hover style. - }, - [`&.${pickersInputClasses.focused}:after`]: { - // translateX(0) is a workaround for Safari transform scale bug - // See https://github.com/mui/material-ui/issues/31766 - transform: 'scaleX(1) translateX(0)', - }, - [`&.${pickersInputClasses.error}`]: { - '&:before, &:after': { - borderBottomColor: (theme.vars || theme).palette.error.main, - }, - }, - '&::before': { - borderBottom: `1px solid ${bottomLineColor}`, - left: 0, - bottom: 0, - // Doing the other way around crash on IE11 "''" https://github.com/cssinjs/jss/issues/242 - content: '"\\00a0"', - position: 'absolute', - right: 0, - transition: theme.transitions.create('border-bottom-color', { - duration: theme.transitions.duration.shorter, - }), - pointerEvents: 'none', // Transparent to the hover style. - }, - [`&:hover:not(.${pickersInputClasses.disabled}, .${pickersInputClasses.error}):before`]: { - borderBottom: `2px solid ${(theme.vars || theme).palette.text.primary}`, - // Reset on touch devices, it doesn't add specificity - '@media (hover: none)': { - borderBottom: `1px solid ${bottomLineColor}`, + .filter((key) => (theme.vars ?? theme).palette[key].main) + .map((color) => ({ + props: { color }, + style: { + '&::after': { + // @ts-ignore + borderBottom: `2px solid ${(theme.vars || theme).palette[color].main}`, + }, + }, + })), + { + props: { disableUnderline: false }, + style: { + '&::after': { + background: 'red', + left: 0, + bottom: 0, + // Doing the other way around crash on IE11 "''" https://github.com/cssinjs/jss/issues/242 + content: '""', + position: 'absolute', + right: 0, + transform: 'scaleX(0)', + transition: theme.transitions.create('transform', { + duration: theme.transitions.duration.shorter, + easing: theme.transitions.easing.easeOut, + }), + pointerEvents: 'none', // Transparent to the hover style. + }, + [`&.${pickersInputClasses.focused}:after`]: { + // translateX(0) is a workaround for Safari transform scale bug + // See https://github.com/mui/material-ui/issues/31766 + transform: 'scaleX(1) translateX(0)', + }, + [`&.${pickersInputClasses.error}`]: { + '&:before, &:after': { + borderBottomColor: (theme.vars || theme).palette.error.main, + }, + }, + '&::before': { + borderBottom: `1px solid ${bottomLineColor}`, + left: 0, + bottom: 0, + // Doing the other way around crash on IE11 "''" https://github.com/cssinjs/jss/issues/242 + content: '"\\00a0"', + position: 'absolute', + right: 0, + transition: theme.transitions.create('border-bottom-color', { + duration: theme.transitions.duration.shorter, + }), + pointerEvents: 'none', // Transparent to the hover style. + }, + [`&:hover:not(.${pickersInputClasses.disabled}, .${pickersInputClasses.error}):before`]: { + borderBottom: `2px solid ${(theme.vars || theme).palette.text.primary}`, + // Reset on touch devices, it doesn't add specificity + '@media (hover: none)': { + borderBottom: `1px solid ${bottomLineColor}`, + }, + }, + [`&.${pickersInputClasses.disabled}:before`]: { + borderBottomStyle: 'dotted', + }, }, }, - [`&.${pickersInputClasses.disabled}:before`]: { - borderBottomStyle: 'dotted', - }, - }), + ], }; }); @@ -113,7 +128,13 @@ const PickersInput = React.forwardRef(function PickersInput( name: 'MuiPickersInput', }); - const { label, autoFocus, ownerState: ownerStateProp, ...other } = props; + const { + label, + autoFocus, + disableUnderline = false, + ownerState: ownerStateProp, + ...other + } = props; const muiFormControl = useFormControl(); @@ -121,6 +142,7 @@ const PickersInput = React.forwardRef(function PickersInput( ...props, ...ownerStateProp, ...muiFormControl, + disableUnderline, color: muiFormControl?.color || 'primary', }; const classes = useUtilityClasses(ownerState); @@ -198,6 +220,11 @@ PickersInput.propTypes = { }), }), ]), + /** + * The props used for each component slot. + * @default {} + */ + slotProps: PropTypes.object, /** * The components used for each slot inside. * diff --git a/packages/x-date-pickers/src/PickersTextField/PickersInputBase/PickersInputBase.tsx b/packages/x-date-pickers/src/PickersTextField/PickersInputBase/PickersInputBase.tsx index 6d37ff7186417..1ec0341917be3 100644 --- a/packages/x-date-pickers/src/PickersTextField/PickersInputBase/PickersInputBase.tsx +++ b/packages/x-date-pickers/src/PickersTextField/PickersInputBase/PickersInputBase.tsx @@ -6,6 +6,7 @@ import useForkRef from '@mui/utils/useForkRef'; import { refType } from '@mui/utils'; import composeClasses from '@mui/utils/composeClasses'; import capitalize from '@mui/utils/capitalize'; +import { useSlotProps } from '@mui/base/utils'; import visuallyHidden from '@mui/utils/visuallyHidden'; import { pickersInputBaseClasses, @@ -26,7 +27,7 @@ export const PickersInputBaseRoot = styled('div', { name: 'MuiPickersInputBase', slot: 'Root', overridesResolver: (props, styles) => styles.root, -})<{ ownerState: OwnerStateType }>(({ theme, ownerState }) => ({ +})<{ ownerState: OwnerStateType }>(({ theme }) => ({ ...theme.typography.body1, color: (theme.vars || theme).palette.text.primary, cursor: 'text', @@ -37,16 +38,19 @@ export const PickersInputBaseRoot = styled('div', { position: 'relative', boxSizing: 'border-box', // Prevent padding issue with fullWidth. letterSpacing: `${round(0.15 / 16)}em`, - ...(ownerState.fullWidth && { - width: '100%', - }), + variants: [ + { + props: { fullWidth: true }, + style: { width: '100%' }, + }, + ], })); export const PickersInputBaseSectionsContainer = styled(PickersSectionListRoot, { name: 'MuiPickersInputBase', slot: 'SectionsContainer', overridesResolver: (props, styles) => styles.sectionsContainer, -})<{ ownerState: OwnerStateType }>(({ theme, ownerState }) => ({ +})<{ ownerState: OwnerStateType }>(({ theme }) => ({ padding: '4px 0 5px', fontFamily: theme.typography.fontFamily, fontSize: 'inherit', @@ -59,22 +63,34 @@ export const PickersInputBaseSectionsContainer = styled(PickersSectionListRoot, letterSpacing: 'inherit', // Baseline behavior width: '182px', - ...(ownerState.size === 'small' && { - paddingTop: 1, - }), ...(theme.direction === 'rtl' && { textAlign: 'right /*! @noflip */' as any }), - ...(!(ownerState.adornedStart || ownerState.focused || ownerState.filled) && { - color: 'currentColor', - ...(ownerState.label == null && - (theme.vars + variants: [ + { + props: { size: 'small' }, + style: { + paddingTop: 1, + }, + }, + { + props: { adornedStart: false, focused: false, filled: false }, + style: { + color: 'currentColor', + opacity: 0, + }, + }, + { + // Can't use the object notation because label can be null or undefined + props: ({ adornedStart, focused, filled, label }: OwnerStateType) => + !adornedStart && !focused && !filled && label == null, + style: theme.vars ? { opacity: theme.vars.opacity.inputPlaceholder, } : { opacity: theme.palette.mode === 'light' ? 0.42 : 0.5, - })), - ...(ownerState.label != null && { opacity: 0 }), - }), + }, + }, + ], })); const PickersInputBaseSection = styled(PickersSectionListSection, { @@ -185,6 +201,7 @@ const PickersInputBase = React.forwardRef(function PickersInputBase( startAdornment, renderSuffix, slots, + slotProps, contentEditable, tabIndex, onInput, @@ -247,16 +264,22 @@ const PickersInputBase = React.forwardRef(function PickersInputBase( const classes = useUtilityClasses(ownerState); const InputRoot = slots?.root || PickersInputBaseRoot; + const inputRootProps = useSlotProps({ + elementType: InputRoot, + externalSlotProps: slotProps?.root, + externalForwardedProps: other, + additionalProps: { + 'aria-invalid': muiFormControl.error, + ref: handleRootRef, + }, + className: classes.root, + ownerState, + }); + const InputSectionsContainer = slots?.input || PickersInputBaseSectionsContainer; return ( - + {startAdornment} ({ fontSize: 'inherit', })); -const OutlineLegend = styled('legend')<{ ownerState: any }>(({ ownerState, theme }) => ({ +const OutlineLegend = styled('legend')<{ ownerState: any }>(({ theme }) => ({ float: 'unset', // Fix conflict with bootstrap width: 'auto', // Fix conflict with bootstrap overflow: 'hidden', // Fix Horizontal scroll when label too long - ...(!ownerState.withLabel && { - padding: 0, - lineHeight: '11px', // sync with `height` in `legend` styles - transition: theme.transitions.create('width', { - duration: 150, - easing: theme.transitions.easing.easeOut, - }), - }), - ...(ownerState.withLabel && { - display: 'block', // Fix conflict with normalize.css and sanitize.css - padding: 0, - height: 11, // sync with `lineHeight` in `legend` styles - fontSize: '0.75em', - visibility: 'hidden', - maxWidth: 0.01, - transition: theme.transitions.create('max-width', { - duration: 50, - easing: theme.transitions.easing.easeOut, - }), - whiteSpace: 'nowrap', - '& > span': { - paddingLeft: 5, - paddingRight: 5, - display: 'inline-block', - opacity: 0, - visibility: 'visible', + variants: [ + { + props: { withLabel: false }, + style: { + padding: 0, + lineHeight: '11px', // sync with `height` in `legend` styles + transition: theme.transitions.create('width', { + duration: 150, + easing: theme.transitions.easing.easeOut, + }), + }, }, - ...(ownerState.notched && { - maxWidth: '100%', - transition: theme.transitions.create('max-width', { - duration: 100, - easing: theme.transitions.easing.easeOut, - delay: 50, - }), - }), - }), + { + props: { withLabel: true }, + style: { + display: 'block', // Fix conflict with normalize.css and sanitize.css + padding: 0, + height: 11, // sync with `lineHeight` in `legend` styles + fontSize: '0.75em', + visibility: 'hidden', + maxWidth: 0.01, + transition: theme.transitions.create('max-width', { + duration: 50, + easing: theme.transitions.easing.easeOut, + }), + whiteSpace: 'nowrap', + '& > span': { + paddingLeft: 5, + paddingRight: 5, + display: 'inline-block', + opacity: 0, + visibility: 'visible', + }, + }, + }, + { + props: { withLabel: true, notched: true }, + style: { + maxWidth: '100%', + transition: theme.transitions.create('max-width', { + duration: 100, + easing: theme.transitions.easing.easeOut, + delay: 50, + }), + }, + }, + ], })); /** diff --git a/packages/x-date-pickers/src/PickersTextField/PickersOutlinedInput/PickersOutlinedInput.tsx b/packages/x-date-pickers/src/PickersTextField/PickersOutlinedInput/PickersOutlinedInput.tsx index 2cca79b9691a6..2dbcec6510a9a 100644 --- a/packages/x-date-pickers/src/PickersTextField/PickersOutlinedInput/PickersOutlinedInput.tsx +++ b/packages/x-date-pickers/src/PickersTextField/PickersOutlinedInput/PickersOutlinedInput.tsx @@ -23,7 +23,7 @@ const PickersOutlinedInputRoot = styled(PickersInputBaseRoot, { name: 'MuiPickersOutlinedInput', slot: 'Root', overridesResolver: (props, styles) => styles.root, -})<{ ownerState: OwnerStateType }>(({ theme, ownerState }) => { +})<{ ownerState: OwnerStateType }>(({ theme }) => { const borderColor = theme.palette.mode === 'light' ? 'rgba(0, 0, 0, 0.23)' : 'rgba(255, 255, 255, 0.23)'; return { @@ -42,8 +42,6 @@ const PickersOutlinedInputRoot = styled(PickersInputBaseRoot, { }, [`&.${pickersOutlinedInputClasses.focused} .${pickersOutlinedInputClasses.notchedOutline}`]: { borderStyle: 'solid', - // @ts-ignore - borderColor: (theme.vars || theme).palette[ownerState.color].main, borderWidth: 2, }, [`&.${pickersOutlinedInputClasses.disabled}`]: { @@ -57,6 +55,19 @@ const PickersOutlinedInputRoot = styled(PickersInputBaseRoot, { [`&.${pickersOutlinedInputClasses.error} .${pickersOutlinedInputClasses.notchedOutline}`]: { borderColor: (theme.vars || theme).palette.error.main, }, + variants: Object.keys((theme.vars ?? theme).palette) + // @ts-ignore + .filter((key) => (theme.vars ?? theme).palette[key].main) + .map((color) => ({ + props: { color }, + style: { + [`&.${pickersOutlinedInputClasses.focused}:not(.${pickersOutlinedInputClasses.error}) .${pickersOutlinedInputClasses.notchedOutline}`]: + { + // @ts-ignore + borderColor: (theme.vars || theme).palette[color].main, + }, + }, + })), }; }); @@ -64,12 +75,17 @@ const PickersOutlinedInputSectionsContainer = styled(PickersInputBaseSectionsCon name: 'MuiPickersOutlinedInput', slot: 'SectionsContainer', overridesResolver: (props, styles) => styles.sectionsContainer, -})<{ ownerState: OwnerStateType }>(({ ownerState }) => ({ +})<{ ownerState: OwnerStateType }>({ padding: '16.5px 0', - ...(ownerState.size === 'small' && { - padding: '8.5px 0', - }), -})); + variants: [ + { + props: { size: 'small' }, + style: { + padding: '8.5px 0', + }, + }, + ], +}); const useUtilityClasses = (ownerState: OwnerStateType) => { const { classes } = ownerState; @@ -207,6 +223,11 @@ PickersOutlinedInput.propTypes = { }), }), ]), + /** + * The props used for each component slot. + * @default {} + */ + slotProps: PropTypes.object, /** * The components used for each slot inside. * diff --git a/packages/x-date-pickers/src/TimeClock/Clock.tsx b/packages/x-date-pickers/src/TimeClock/Clock.tsx index 8b15624405619..23a583f9dd71a 100644 --- a/packages/x-date-pickers/src/TimeClock/Clock.tsx +++ b/packages/x-date-pickers/src/TimeClock/Clock.tsx @@ -104,7 +104,7 @@ const ClockSquareMask = styled('div', { name: 'MuiClock', slot: 'SquareMask', overridesResolver: (_, styles) => styles.squareMask, -})<{ ownerState: ClockSquareMaskOwnerState }>(({ ownerState }) => ({ +})<{ ownerState: ClockSquareMaskOwnerState }>({ width: '100%', height: '100%', position: 'absolute', @@ -113,9 +113,10 @@ const ClockSquareMask = styled('div', { // Disable scroll capabilities. touchAction: 'none', userSelect: 'none', - ...(ownerState.disabled - ? {} - : { + variants: [ + { + props: { disabled: false }, + style: { '@media (pointer: fine)': { cursor: 'pointer', borderRadius: '50%', @@ -123,8 +124,10 @@ const ClockSquareMask = styled('div', { '&:active': { cursor: 'move', }, - }), -})); + }, + }, + ], +}); const ClockPin = styled('div', { name: 'MuiClock', @@ -145,7 +148,7 @@ const ClockAmButton = styled(IconButton, { name: 'MuiClock', slot: 'AmButton', overridesResolver: (_, styles) => styles.amButton, -})<{ ownerState: ClockProps }>(({ theme, ownerState }) => ({ +})<{ ownerState: ClockProps }>(({ theme }) => ({ zIndex: 1, position: 'absolute', bottom: 8, @@ -153,20 +156,25 @@ const ClockAmButton = styled(IconButton, { paddingLeft: 4, paddingRight: 4, width: CLOCK_HOUR_WIDTH, - ...(ownerState.meridiemMode === 'am' && { - backgroundColor: (theme.vars || theme).palette.primary.main, - color: (theme.vars || theme).palette.primary.contrastText, - '&:hover': { - backgroundColor: (theme.vars || theme).palette.primary.light, + variants: [ + { + props: { meridiemMode: 'am' }, + style: { + backgroundColor: (theme.vars || theme).palette.primary.main, + color: (theme.vars || theme).palette.primary.contrastText, + '&:hover': { + backgroundColor: (theme.vars || theme).palette.primary.light, + }, + }, }, - }), + ], })); const ClockPmButton = styled(IconButton, { name: 'MuiClock', slot: 'PmButton', overridesResolver: (_, styles) => styles.pmButton, -})<{ ownerState: ClockProps }>(({ theme, ownerState }) => ({ +})<{ ownerState: ClockProps }>(({ theme }) => ({ zIndex: 1, position: 'absolute', bottom: 8, @@ -174,13 +182,18 @@ const ClockPmButton = styled(IconButton, { paddingLeft: 4, paddingRight: 4, width: CLOCK_HOUR_WIDTH, - ...(ownerState.meridiemMode === 'pm' && { - backgroundColor: (theme.vars || theme).palette.primary.main, - color: (theme.vars || theme).palette.primary.contrastText, - '&:hover': { - backgroundColor: (theme.vars || theme).palette.primary.light, + variants: [ + { + props: { meridiemMode: 'pm' }, + style: { + backgroundColor: (theme.vars || theme).palette.primary.main, + color: (theme.vars || theme).palette.primary.contrastText, + '&:hover': { + backgroundColor: (theme.vars || theme).palette.primary.light, + }, + }, }, - }), + ], })); const ClockMeridiemText = styled(Typography, { @@ -212,7 +225,7 @@ export function Clock(inProps: ClockProps) selectedId, type, viewValue, - disabled, + disabled = false, readOnly, className, } = props; diff --git a/packages/x-date-pickers/src/TimeClock/ClockNumber.tsx b/packages/x-date-pickers/src/TimeClock/ClockNumber.tsx index 90b48c09b5ba1..bab778903644d 100644 --- a/packages/x-date-pickers/src/TimeClock/ClockNumber.tsx +++ b/packages/x-date-pickers/src/TimeClock/ClockNumber.tsx @@ -40,7 +40,7 @@ const ClockNumberRoot = styled('span', { { [`&.${clockNumberClasses.disabled}`]: styles.disabled }, { [`&.${clockNumberClasses.selected}`]: styles.selected }, ], -})<{ ownerState: ClockNumberProps }>(({ theme, ownerState }) => ({ +})<{ ownerState: ClockNumberProps }>(({ theme }) => ({ height: CLOCK_HOUR_WIDTH, width: CLOCK_HOUR_WIDTH, position: 'absolute', @@ -61,10 +61,15 @@ const ClockNumberRoot = styled('span', { pointerEvents: 'none', color: (theme.vars || theme).palette.text.disabled, }, - ...(ownerState.inner && { - ...theme.typography.body2, - color: (theme.vars || theme).palette.text.secondary, - }), + variants: [ + { + props: { inner: true }, + style: { + ...theme.typography.body2, + color: (theme.vars || theme).palette.text.secondary, + }, + }, + ], })); /** diff --git a/packages/x-date-pickers/src/TimeClock/ClockPointer.tsx b/packages/x-date-pickers/src/TimeClock/ClockPointer.tsx index a77c40b32736c..735b228846ec7 100644 --- a/packages/x-date-pickers/src/TimeClock/ClockPointer.tsx +++ b/packages/x-date-pickers/src/TimeClock/ClockPointer.tsx @@ -34,16 +34,21 @@ const ClockPointerRoot = styled('div', { overridesResolver: (_, styles) => styles.root, })<{ ownerState: ClockPointerProps & ClockPointerState; -}>(({ theme, ownerState }) => ({ +}>(({ theme }) => ({ width: 2, backgroundColor: (theme.vars || theme).palette.primary.main, position: 'absolute', left: 'calc(50% - 1px)', bottom: '50%', transformOrigin: 'center bottom 0px', - ...(ownerState.shouldAnimate && { - transition: theme.transitions.create(['transform', 'height']), - }), + variants: [ + { + props: { shouldAnimate: true }, + style: { + transition: theme.transitions.create(['transform', 'height']), + }, + }, + ], })); const ClockPointerThumb = styled('div', { @@ -52,7 +57,7 @@ const ClockPointerThumb = styled('div', { overridesResolver: (_, styles) => styles.thumb, })<{ ownerState: ClockPointerProps & ClockPointerState; -}>(({ theme, ownerState }) => ({ +}>(({ theme }) => ({ width: 4, height: 4, backgroundColor: (theme.vars || theme).palette.primary.contrastText, @@ -62,9 +67,14 @@ const ClockPointerThumb = styled('div', { left: `calc(50% - ${CLOCK_HOUR_WIDTH / 2}px)`, border: `${(CLOCK_HOUR_WIDTH - 4) / 2}px solid ${(theme.vars || theme).palette.primary.main}`, boxSizing: 'content-box', - ...(ownerState.hasSelected && { - backgroundColor: (theme.vars || theme).palette.primary.main, - }), + variants: [ + { + props: { hasSelected: true }, + style: { + backgroundColor: (theme.vars || theme).palette.primary.main, + }, + }, + ], })); /** diff --git a/packages/x-date-pickers/src/TimePicker/TimePickerToolbar.tsx b/packages/x-date-pickers/src/TimePicker/TimePickerToolbar.tsx index ba4fd2c6e61f0..ff2bf30ac5fd9 100644 --- a/packages/x-date-pickers/src/TimePicker/TimePickerToolbar.tsx +++ b/packages/x-date-pickers/src/TimePicker/TimePickerToolbar.tsx @@ -81,16 +81,21 @@ const TimePickerToolbarHourMinuteLabel = styled('div', { ], })<{ ownerState: TimePickerToolbarProps; -}>(({ theme, ownerState }) => ({ +}>(({ theme }) => ({ display: 'flex', justifyContent: 'flex-end', alignItems: 'flex-end', - ...(ownerState.isLandscape && { - marginTop: 'auto', - }), ...(theme.direction === 'rtl' && { flexDirection: 'row-reverse', }), + variants: [ + { + props: { isLandscape: true }, + style: { + marginTop: 'auto', + }, + }, + ], })); TimePickerToolbarHourMinuteLabel.propTypes = { @@ -117,21 +122,26 @@ const TimePickerToolbarAmPmSelection = styled('div', { ], })<{ ownerState: TimePickerToolbarProps; -}>(({ ownerState }) => ({ +}>({ display: 'flex', flexDirection: 'column', marginRight: 'auto', marginLeft: 12, - ...(ownerState.isLandscape && { - margin: '4px 0 auto', - flexDirection: 'row', - justifyContent: 'space-around', - flexBasis: '100%', - }), [`& .${timePickerToolbarClasses.ampmLabel}`]: { fontSize: 17, }, -})); + variants: [ + { + props: { isLandscape: true }, + style: { + margin: '4px 0 auto', + flexDirection: 'row', + justifyContent: 'space-around', + flexBasis: '100%', + }, + }, + ], +}); TimePickerToolbarAmPmSelection.propTypes = { // ----------------------------- Warning -------------------------------- diff --git a/packages/x-date-pickers/src/YearCalendar/PickersYear.tsx b/packages/x-date-pickers/src/YearCalendar/PickersYear.tsx index 8dce10be09ffb..cc8248d37797f 100644 --- a/packages/x-date-pickers/src/YearCalendar/PickersYear.tsx +++ b/packages/x-date-pickers/src/YearCalendar/PickersYear.tsx @@ -43,12 +43,13 @@ const PickersYearRoot = styled('div', { name: 'MuiPickersYear', slot: 'Root', overridesResolver: (_, styles) => [styles.root], -})<{ ownerState: PickersYearProps }>(({ ownerState }) => ({ - flexBasis: ownerState.yearsPerRow === 3 ? '33.3%' : '25%', +})<{ ownerState: PickersYearProps }>({ display: 'flex', alignItems: 'center', justifyContent: 'center', -})); + flexBasis: '33.3%', + variants: [{ props: { yearsPerRow: 4 }, style: { flexBasis: '25%' } }], +}); const PickersYearButton = styled('button', { name: 'MuiPickersYear', diff --git a/packages/x-date-pickers/src/internals/components/PickersArrowSwitcher/PickersArrowSwitcher.tsx b/packages/x-date-pickers/src/internals/components/PickersArrowSwitcher/PickersArrowSwitcher.tsx index 926e68a1c0331..6ade141f2f380 100644 --- a/packages/x-date-pickers/src/internals/components/PickersArrowSwitcher/PickersArrowSwitcher.tsx +++ b/packages/x-date-pickers/src/internals/components/PickersArrowSwitcher/PickersArrowSwitcher.tsx @@ -38,11 +38,14 @@ const PickersArrowSwitcherButton = styled(IconButton, { overridesResolver: (props, styles) => styles.button, })<{ ownerState: PickersArrowSwitcherProps; -}>(({ ownerState }) => ({ - ...(ownerState.hidden && { - visibility: 'hidden', - }), -})); +}>({ + variants: [ + { + props: { hidden: true }, + style: { visibility: 'hidden' }, + }, + ], +}); const useUtilityClasses = (ownerState: PickersArrowSwitcherOwnerState) => { const { classes } = ownerState; diff --git a/packages/x-date-pickers/src/internals/components/PickersPopper.tsx b/packages/x-date-pickers/src/internals/components/PickersPopper.tsx index 5e472471459b5..6ad3bdedcdfbe 100644 --- a/packages/x-date-pickers/src/internals/components/PickersPopper.tsx +++ b/packages/x-date-pickers/src/internals/components/PickersPopper.tsx @@ -112,13 +112,19 @@ const PickersPopperPaper = styled(MuiPaper, { overridesResolver: (_, styles) => styles.paper, })<{ ownerState: PickersPopperOwnerState; -}>(({ ownerState }) => ({ +}>({ outline: 0, transformOrigin: 'top center', - ...(ownerState.placement.includes('top') && { - transformOrigin: 'bottom center', - }), -})); + variants: [ + { + props: ({ placement }: PickersPopperOwnerState) => + ['top', 'top-start', 'top-end'].includes(placement), + style: { + transformOrigin: 'bottom center', + }, + }, + ], +}); function clickedRootScrollbar(event: MouseEvent, doc: Document) { return ( diff --git a/packages/x-date-pickers/src/internals/components/PickersToolbar.tsx b/packages/x-date-pickers/src/internals/components/PickersToolbar.tsx index 97b41ca9b0f46..780756015029f 100644 --- a/packages/x-date-pickers/src/internals/components/PickersToolbar.tsx +++ b/packages/x-date-pickers/src/internals/components/PickersToolbar.tsx @@ -32,19 +32,24 @@ const PickersToolbarRoot = styled('div', { overridesResolver: (props, styles) => styles.root, })<{ ownerState: PickersToolbarProps; -}>(({ theme, ownerState }) => ({ +}>(({ theme }) => ({ display: 'flex', flexDirection: 'column', alignItems: 'flex-start', justifyContent: 'space-between', padding: theme.spacing(2, 3), - ...(ownerState.isLandscape && { - height: 'auto', - maxWidth: 160, - padding: 16, - justifyContent: 'flex-start', - flexWrap: 'wrap', - }), + variants: [ + { + props: { isLandscape: true }, + style: { + height: 'auto', + maxWidth: 160, + padding: 16, + justifyContent: 'flex-start', + flexWrap: 'wrap', + }, + }, + ], })); const PickersToolbarContent = styled('div', { @@ -53,15 +58,31 @@ const PickersToolbarContent = styled('div', { overridesResolver: (props, styles) => styles.content, })<{ ownerState: PickersToolbarProps; -}>(({ ownerState }) => ({ +}>({ display: 'flex', flexWrap: 'wrap', width: '100%', - justifyContent: ownerState.isLandscape ? 'flex-start' : 'space-between', - flexDirection: ownerState.isLandscape ? ownerState.landscapeDirection ?? 'column' : 'row', flex: 1, - alignItems: ownerState.isLandscape ? 'flex-start' : 'center', -})); + justifyContent: 'space-between', + alignItems: 'center', + flexDirection: 'row', + variants: [ + { + props: { isLandscape: true }, + style: { + justifyContent: 'flex-start', + alignItems: 'flex-start', + flexDirection: 'column', + }, + }, + { + props: { isLandscape: true, landscapeDirection: 'row' }, + style: { + flexDirection: 'row', + }, + }, + ], +}); type PickersToolbarComponent = (( props: React.PropsWithChildren> & From 2ac14fd98fabe93663297512e2b219d329b384d9 Mon Sep 17 00:00:00 2001 From: Rom Grk Date: Tue, 26 Mar 2024 08:51:29 -0400 Subject: [PATCH 20/55] [DataGrid] Add `resizeThrottleMs` prop (#12556) --- .../x/api/data-grid/data-grid-premium.json | 1 + docs/pages/x/api/data-grid/data-grid-pro.json | 1 + docs/pages/x/api/data-grid/data-grid.json | 1 + .../data-grid-premium/data-grid-premium.json | 1 + .../data-grid-pro/data-grid-pro.json | 1 + .../data-grid/data-grid/data-grid.json | 1 + .../src/DataGridPremium/DataGridPremium.tsx | 5 ++++ .../src/DataGridPro/DataGridPro.tsx | 5 ++++ .../x-data-grid/src/DataGrid/DataGrid.tsx | 5 ++++ .../src/DataGrid/useDataGridProps.ts | 1 + .../features/dimensions/useGridDimensions.ts | 8 ++++-- .../src/models/props/DataGridProps.ts | 5 ++++ packages/x-data-grid/src/utils/throttle.ts | 27 +++++++++++++++++++ 13 files changed, 60 insertions(+), 2 deletions(-) create mode 100644 packages/x-data-grid/src/utils/throttle.ts diff --git a/docs/pages/x/api/data-grid/data-grid-premium.json b/docs/pages/x/api/data-grid/data-grid-premium.json index 9ce3955ee724f..83f0ee5347236 100644 --- a/docs/pages/x/api/data-grid/data-grid-premium.json +++ b/docs/pages/x/api/data-grid/data-grid-premium.json @@ -548,6 +548,7 @@ "returned": "Promise | R" } }, + "resizeThrottleMs": { "type": { "name": "number" }, "default": "60" }, "rowBufferPx": { "type": { "name": "number" }, "default": "150" }, "rowCount": { "type": { "name": "number" } }, "rowGroupingColumnMode": { diff --git a/docs/pages/x/api/data-grid/data-grid-pro.json b/docs/pages/x/api/data-grid/data-grid-pro.json index f85d38ad71488..2de559b314519 100644 --- a/docs/pages/x/api/data-grid/data-grid-pro.json +++ b/docs/pages/x/api/data-grid/data-grid-pro.json @@ -491,6 +491,7 @@ "returned": "Promise | R" } }, + "resizeThrottleMs": { "type": { "name": "number" }, "default": "60" }, "rowBufferPx": { "type": { "name": "number" }, "default": "150" }, "rowCount": { "type": { "name": "number" } }, "rowHeight": { "type": { "name": "number" }, "default": "52" }, diff --git a/docs/pages/x/api/data-grid/data-grid.json b/docs/pages/x/api/data-grid/data-grid.json index ac8d1f022003d..4ca488287bf53 100644 --- a/docs/pages/x/api/data-grid/data-grid.json +++ b/docs/pages/x/api/data-grid/data-grid.json @@ -408,6 +408,7 @@ "returned": "Promise | R" } }, + "resizeThrottleMs": { "type": { "name": "number" }, "default": "60" }, "rowBufferPx": { "type": { "name": "number" }, "default": "150" }, "rowCount": { "type": { "name": "number" } }, "rowHeight": { "type": { "name": "number" }, "default": "52" }, diff --git a/docs/translations/api-docs/data-grid/data-grid-premium/data-grid-premium.json b/docs/translations/api-docs/data-grid/data-grid-premium/data-grid-premium.json index 43e271be77231..e4650258c7454 100644 --- a/docs/translations/api-docs/data-grid/data-grid-premium/data-grid-premium.json +++ b/docs/translations/api-docs/data-grid/data-grid-premium/data-grid-premium.json @@ -575,6 +575,7 @@ "Promise | R": "The final values to update the row." } }, + "resizeThrottleMs": { "description": "The milliseconds throttle delay for resizing the grid." }, "rowBufferPx": { "description": "Row region in pixels to render before/after the viewport" }, "rowCount": { "description": "Set the total number of rows, if it is different from the length of the value rows prop. If some rows have children (for instance in the tree data), this number represents the amount of top level rows." diff --git a/docs/translations/api-docs/data-grid/data-grid-pro/data-grid-pro.json b/docs/translations/api-docs/data-grid/data-grid-pro/data-grid-pro.json index 714f0c82153de..44babc11d7944 100644 --- a/docs/translations/api-docs/data-grid/data-grid-pro/data-grid-pro.json +++ b/docs/translations/api-docs/data-grid/data-grid-pro/data-grid-pro.json @@ -521,6 +521,7 @@ "Promise | R": "The final values to update the row." } }, + "resizeThrottleMs": { "description": "The milliseconds throttle delay for resizing the grid." }, "rowBufferPx": { "description": "Row region in pixels to render before/after the viewport" }, "rowCount": { "description": "Set the total number of rows, if it is different from the length of the value rows prop. If some rows have children (for instance in the tree data), this number represents the amount of top level rows." diff --git a/docs/translations/api-docs/data-grid/data-grid/data-grid.json b/docs/translations/api-docs/data-grid/data-grid/data-grid.json index 18b8f9aee4f18..957595b1a9a8c 100644 --- a/docs/translations/api-docs/data-grid/data-grid/data-grid.json +++ b/docs/translations/api-docs/data-grid/data-grid/data-grid.json @@ -424,6 +424,7 @@ "Promise | R": "The final values to update the row." } }, + "resizeThrottleMs": { "description": "The milliseconds throttle delay for resizing the grid." }, "rowBufferPx": { "description": "Row region in pixels to render before/after the viewport" }, "rowCount": { "description": "Set the total number of rows, if it is different from the length of the value rows prop. If some rows have children (for instance in the tree data), this number represents the amount of top level rows." diff --git a/packages/x-data-grid-premium/src/DataGridPremium/DataGridPremium.tsx b/packages/x-data-grid-premium/src/DataGridPremium/DataGridPremium.tsx index 80010e177699b..3b808b7999c80 100644 --- a/packages/x-data-grid-premium/src/DataGridPremium/DataGridPremium.tsx +++ b/packages/x-data-grid-premium/src/DataGridPremium/DataGridPremium.tsx @@ -883,6 +883,11 @@ DataGridPremiumRaw.propTypes = { * @returns {Promise | R} The final values to update the row. */ processRowUpdate: PropTypes.func, + /** + * The milliseconds throttle delay for resizing the grid. + * @default 60 + */ + resizeThrottleMs: PropTypes.number, /** * Row region in pixels to render before/after the viewport * @default 150 diff --git a/packages/x-data-grid-pro/src/DataGridPro/DataGridPro.tsx b/packages/x-data-grid-pro/src/DataGridPro/DataGridPro.tsx index 5ee1b16e5ca0d..1b9dce1dbcf41 100644 --- a/packages/x-data-grid-pro/src/DataGridPro/DataGridPro.tsx +++ b/packages/x-data-grid-pro/src/DataGridPro/DataGridPro.tsx @@ -785,6 +785,11 @@ DataGridProRaw.propTypes = { * @returns {Promise | R} The final values to update the row. */ processRowUpdate: PropTypes.func, + /** + * The milliseconds throttle delay for resizing the grid. + * @default 60 + */ + resizeThrottleMs: PropTypes.number, /** * Row region in pixels to render before/after the viewport * @default 150 diff --git a/packages/x-data-grid/src/DataGrid/DataGrid.tsx b/packages/x-data-grid/src/DataGrid/DataGrid.tsx index 3ae35b0118937..8742dd514ba65 100644 --- a/packages/x-data-grid/src/DataGrid/DataGrid.tsx +++ b/packages/x-data-grid/src/DataGrid/DataGrid.tsx @@ -652,6 +652,11 @@ DataGridRaw.propTypes = { * @returns {Promise | R} The final values to update the row. */ processRowUpdate: PropTypes.func, + /** + * The milliseconds throttle delay for resizing the grid. + * @default 60 + */ + resizeThrottleMs: PropTypes.number, /** * Row region in pixels to render before/after the viewport * @default 150 diff --git a/packages/x-data-grid/src/DataGrid/useDataGridProps.ts b/packages/x-data-grid/src/DataGrid/useDataGridProps.ts index 3423bb66f36d9..89ace1f6d061d 100644 --- a/packages/x-data-grid/src/DataGrid/useDataGridProps.ts +++ b/packages/x-data-grid/src/DataGrid/useDataGridProps.ts @@ -60,6 +60,7 @@ export const DATA_GRID_PROPS_DEFAULT_VALUES: DataGridPropsWithDefaultValues = { pagination: false, paginationMode: 'client', rowHeight: 52, + resizeThrottleMs: 60, pageSizeOptions: [25, 50, 100], rowSpacingType: 'margin', showCellVerticalBorder: false, diff --git a/packages/x-data-grid/src/hooks/features/dimensions/useGridDimensions.ts b/packages/x-data-grid/src/hooks/features/dimensions/useGridDimensions.ts index fbe44ed1036bd..86c21a6195dc8 100644 --- a/packages/x-data-grid/src/hooks/features/dimensions/useGridDimensions.ts +++ b/packages/x-data-grid/src/hooks/features/dimensions/useGridDimensions.ts @@ -1,6 +1,5 @@ import * as React from 'react'; import { - unstable_debounce as debounce, unstable_ownerDocument as ownerDocument, unstable_useEnhancedEffect as useEnhancedEffect, unstable_useEventCallback as useEventCallback, @@ -14,6 +13,7 @@ import { useGridApiOptionHandler, } from '../../utils/useGridApiEventHandler'; import { useGridApiMethod } from '../../utils/useGridApiMethod'; +import { throttle } from '../../../utils/throttle'; import { useGridLogger } from '../../utils/useGridLogger'; import { DataGridProcessedProps } from '../../../models/props/DataGridProps'; import { GridDimensions, GridDimensionsApi, GridDimensionsPrivateApi } from './gridDimensionsApi'; @@ -40,6 +40,7 @@ type RootProps = Pick< | 'autoHeight' | 'getRowHeight' | 'rowHeight' + | 'resizeThrottleMs' | 'columnHeaderHeight' >; @@ -95,7 +96,10 @@ export function useGridDimensions( const rightPinnedWidth = pinnedColumns.right.reduce((w, col) => w + col.computedWidth, 0); const [savedSize, setSavedSize] = React.useState(); - const debouncedSetSavedSize = React.useMemo(() => debounce(setSavedSize, 60), []); + const debouncedSetSavedSize = React.useMemo( + () => throttle(setSavedSize, props.resizeThrottleMs), + [props.resizeThrottleMs], + ); const previousSize = React.useRef(); const getRootDimensions = () => apiRef.current.state.dimensions; diff --git a/packages/x-data-grid/src/models/props/DataGridProps.ts b/packages/x-data-grid/src/models/props/DataGridProps.ts index b21d37e1a123f..de6ed4566803a 100644 --- a/packages/x-data-grid/src/models/props/DataGridProps.ts +++ b/packages/x-data-grid/src/models/props/DataGridProps.ts @@ -142,6 +142,11 @@ export interface DataGridPropsWithDefaultValues any>(func: T, wait = 166) { + let timeout: ReturnType | undefined; + let lastArgs: Parameters; + + const later = () => { + timeout = undefined; + func(...lastArgs); + }; + + function throttled(...args: Parameters) { + lastArgs = args; + if (timeout === undefined) { + timeout = setTimeout(later, wait); + } + } + + throttled.clear = () => { + clearTimeout(timeout); + timeout = undefined; + }; + + return throttled as T & Cancelable; +} From 5e99aa1f008c2e81543404c66df38835c3d8f27b Mon Sep 17 00:00:00 2001 From: Andrew Cherniavskii Date: Tue, 26 Mar 2024 18:10:17 +0100 Subject: [PATCH 21/55] [DataGrid] Do not publish `rowEditStop` event if row has fields with errors (#11383) --- .../src/tests/rowEditing.DataGridPro.test.tsx | 58 +++++++++++++++++++ .../features/editing/useGridRowEditing.ts | 27 ++++++--- 2 files changed, 77 insertions(+), 8 deletions(-) diff --git a/packages/x-data-grid-pro/src/tests/rowEditing.DataGridPro.test.tsx b/packages/x-data-grid-pro/src/tests/rowEditing.DataGridPro.test.tsx index 6904e424877cf..2f67660728258 100644 --- a/packages/x-data-grid-pro/src/tests/rowEditing.DataGridPro.test.tsx +++ b/packages/x-data-grid-pro/src/tests/rowEditing.DataGridPro.test.tsx @@ -971,6 +971,26 @@ describe(' - Row editing', () => { expect(listener.lastCall.args[0].reason).to.equal('rowFocusOut'); }); + it(`should not publish 'rowEditStop' if field has error`, async () => { + column1Props.preProcessEditCellProps = ({ props }: GridPreProcessEditCellProps) => ({ + ...props, + error: true, + }); + render(); + const listener = spy(); + apiRef.current.subscribeEvent('rowEditStop', listener); + const cell = getCell(0, 1); + fireEvent.doubleClick(cell); + await act(() => + apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: 'USD GBP' }), + ); + expect(listener.callCount).to.equal(0); + + userEvent.mousePress(getCell(1, 1)); + clock.runToLast(); + expect(listener.callCount).to.equal(0); + }); + it('should call stopRowEditMode with ignoreModifications=false and no cellToFocusAfter', () => { render(); const spiedStopRowEditMode = spyApi(apiRef.current, 'stopRowEditMode'); @@ -1014,6 +1034,25 @@ describe(' - Row editing', () => { expect(listener.lastCall.args[0].reason).to.equal('escapeKeyDown'); }); + it(`should publish 'rowEditStop' even if field has error`, async () => { + column1Props.preProcessEditCellProps = ({ props }: GridPreProcessEditCellProps) => ({ + ...props, + error: true, + }); + render(); + const listener = spy(); + apiRef.current.subscribeEvent('rowEditStop', listener); + const cell = getCell(0, 1); + fireEvent.doubleClick(cell); + await act(() => + apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: 'USD GBP' }), + ); + expect(listener.callCount).to.equal(0); + + fireEvent.keyDown(cell.querySelector('input')!, { key: 'Escape' }); + expect(listener.lastCall.args[0].reason).to.equal('escapeKeyDown'); + }); + it('should call stopRowEditMode with ignoreModifications=true', () => { render(); const spiedStopRowEditMode = spyApi(apiRef.current, 'stopRowEditMode'); @@ -1044,6 +1083,25 @@ describe(' - Row editing', () => { expect(listener.lastCall.args[0].reason).to.equal('enterKeyDown'); }); + it(`should not publish 'rowEditStop' if field has error`, async () => { + column1Props.preProcessEditCellProps = ({ props }: GridPreProcessEditCellProps) => ({ + ...props, + error: true, + }); + render(); + const listener = spy(); + apiRef.current.subscribeEvent('rowEditStop', listener); + const cell = getCell(0, 1); + fireEvent.doubleClick(cell); + await act(() => + apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: 'USD GBP' }), + ); + expect(listener.callCount).to.equal(0); + + fireEvent.keyDown(cell.querySelector('input')!, { key: 'Enter' }); + expect(listener.callCount).to.equal(0); + }); + it('should call stopRowEditMode with ignoreModifications=false and cellToFocusAfter=below', () => { render(); const spiedStopRowEditMode = spyApi(apiRef.current, 'stopRowEditMode'); diff --git a/packages/x-data-grid/src/hooks/features/editing/useGridRowEditing.ts b/packages/x-data-grid/src/hooks/features/editing/useGridRowEditing.ts index 5fe365be8a4e9..ce2e3d5ffd84b 100644 --- a/packages/x-data-grid/src/hooks/features/editing/useGridRowEditing.ts +++ b/packages/x-data-grid/src/hooks/features/editing/useGridRowEditing.ts @@ -110,6 +110,14 @@ export const useGridRowEditing = ( [apiRef], ); + const hasFieldsWithErrors = React.useCallback( + (rowId: GridRowId) => { + const editingState = gridEditRowsStateSelector(apiRef.current.state); + return Object.values(editingState[rowId]).some((fieldProps) => fieldProps.error); + }, + [apiRef], + ); + const handleCellDoubleClick = React.useCallback>( (params, event) => { if (!params.isEditable) { @@ -159,8 +167,12 @@ export const useGridRowEditing = ( return; } + if (hasFieldsWithErrors(params.id)) { + return; + } + const rowParams = apiRef.current.getRowParams(params.id); - const newParams = { + const newParams: GridRowEditStopParams = { ...rowParams, field: params.field, reason: GridRowEditStopReasons.rowFocusOut, @@ -169,7 +181,7 @@ export const useGridRowEditing = ( } }); }, - [apiRef], + [apiRef, hasFieldsWithErrors], ); React.useEffect(() => { @@ -223,6 +235,9 @@ export const useGridRowEditing = ( } if (reason) { + if (reason !== GridRowEditStopReasons.escapeKeyDown && hasFieldsWithErrors(params.id)) { + return; + } const newParams: GridRowEditStopParams = { ...apiRef.current.getRowParams(params.id), reason, @@ -264,7 +279,7 @@ export const useGridRowEditing = ( } } }, - [apiRef], + [apiRef, hasFieldsWithErrors], ); const handleRowEditStart = React.useCallback>( @@ -487,11 +502,7 @@ export const useGridRowEditing = ( return; } - const hasSomeFieldWithError = Object.values(editingState[id]).some( - (fieldProps) => fieldProps.error, - ); - - if (hasSomeFieldWithError) { + if (hasFieldsWithErrors(id)) { prevRowModesModel.current[id].mode = GridRowModes.Edit; // Revert the mode in the rowModesModel prop back to "edit" updateRowInRowModesModel(id, { mode: GridRowModes.Edit }); From e97b715c45139689e4f98da04993d1f00c01cbe5 Mon Sep 17 00:00:00 2001 From: Rishi556 Date: Wed, 27 Mar 2024 04:51:22 -0500 Subject: [PATCH 22/55] [charts] Fix tooltip causing crash on data change (#12571) Signed-off-by: Rishi556 --- .../src/ChartsTooltip/DefaultChartsItemTooltipContent.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/x-charts/src/ChartsTooltip/DefaultChartsItemTooltipContent.tsx b/packages/x-charts/src/ChartsTooltip/DefaultChartsItemTooltipContent.tsx index a2587dc0bbba2..4cb6774720c1f 100644 --- a/packages/x-charts/src/ChartsTooltip/DefaultChartsItemTooltipContent.tsx +++ b/packages/x-charts/src/ChartsTooltip/DefaultChartsItemTooltipContent.tsx @@ -17,7 +17,7 @@ function DefaultChartsItemTooltipContent Date: Wed, 27 Mar 2024 14:09:53 +0100 Subject: [PATCH 23/55] [docs] Chart title for SEO (#12545) --- docs/data/charts/getting-started/getting-started.md | 1 - docs/data/charts/overview/overview.md | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/data/charts/getting-started/getting-started.md b/docs/data/charts/getting-started/getting-started.md index 86abdd2fddfc4..edf2a310d677f 100644 --- a/docs/data/charts/getting-started/getting-started.md +++ b/docs/data/charts/getting-started/getting-started.md @@ -1,5 +1,4 @@ --- -title: React Chart library - Getting started productId: x-charts githubLabel: 'component: charts' packageName: '@mui/x-charts' diff --git a/docs/data/charts/overview/overview.md b/docs/data/charts/overview/overview.md index e3347418beb63..809be9b9a09cc 100644 --- a/docs/data/charts/overview/overview.md +++ b/docs/data/charts/overview/overview.md @@ -1,5 +1,5 @@ --- -title: React Chart library +title: React Charts productId: x-charts githubLabel: 'component: charts' packageName: '@mui/x-charts' From 121a8ed555d2b60ace8bb627048c9afeef702ddd Mon Sep 17 00:00:00 2001 From: Josiah Hawkins <94198149+jhawkins11@users.noreply.github.com> Date: Thu, 28 Mar 2024 01:48:26 -0500 Subject: [PATCH 24/55] [DataGrid] Fix missing class name in the `GridToolbarQuickFilter` component (#12484) Co-authored-by: Rom Grk --- .../toolbar/GridToolbarQuickFilter.tsx | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/packages/x-data-grid/src/components/toolbar/GridToolbarQuickFilter.tsx b/packages/x-data-grid/src/components/toolbar/GridToolbarQuickFilter.tsx index a5ceb6edcf4b9..31c0425dbd11b 100644 --- a/packages/x-data-grid/src/components/toolbar/GridToolbarQuickFilter.tsx +++ b/packages/x-data-grid/src/components/toolbar/GridToolbarQuickFilter.tsx @@ -1,8 +1,11 @@ import * as React from 'react'; +import clsx from 'clsx'; import PropTypes from 'prop-types'; import TextField, { TextFieldProps } from '@mui/material/TextField'; import { styled } from '@mui/material/styles'; import { unstable_debounce as debounce } from '@mui/utils'; +import composeClasses from '@mui/utils/composeClasses'; +import { getDataGridUtilityClass } from '../../constants'; import { useGridApiContext } from '../../hooks/utils/useGridApiContext'; import { useGridRootProps } from '../../hooks/utils/useGridRootProps'; import { useGridSelector } from '../../hooks/utils/useGridSelector'; @@ -13,6 +16,16 @@ import { isDeepEqual } from '../../utils/utils'; type OwnerState = DataGridProcessedProps; +const useUtilityClasses = (ownerState: OwnerState) => { + const { classes } = ownerState; + + const slots = { + root: ['toolbarQuickFilter'], + }; + + return composeClasses(slots, getDataGridUtilityClass, classes); +}; + const GridToolbarQuickFilterRoot = styled(TextField, { name: 'MuiDataGrid', slot: 'ToolbarQuickFilter', @@ -74,12 +87,14 @@ export type GridToolbarQuickFilterProps = TextFieldProps & { function GridToolbarQuickFilter(props: GridToolbarQuickFilterProps) { const apiRef = useGridApiContext(); const rootProps = useGridRootProps(); + const classes = useUtilityClasses(rootProps); const quickFilterValues = useGridSelector(apiRef, gridQuickFilterValuesSelector); const { quickFilterParser = defaultSearchValueParser, quickFilterFormatter = defaultSearchValueFormatter, debounceMs = rootProps.filterDebounceMs, + className, ...other } = props; @@ -138,6 +153,7 @@ function GridToolbarQuickFilter(props: GridToolbarQuickFilterProps) { variant="standard" value={searchValue} onChange={handleSearchValueChange} + className={clsx(className, classes.root)} placeholder={apiRef.current.getLocaleText('toolbarQuickFilterPlaceholder')} aria-label={apiRef.current.getLocaleText('toolbarQuickFilterLabel')} type="search" From dcb658239c22e58cf06f05defae2eee944379c1f Mon Sep 17 00:00:00 2001 From: Lukas Date: Thu, 28 Mar 2024 11:09:48 +0200 Subject: [PATCH 25/55] [fields] Fix input refocusing after clearing a value (#12587) --- .../tests/selection.DateField.test.tsx | 2 +- .../src/internals/hooks/useField/useField.ts | 6 ++- .../DatePicker/BasicDesktopDatePicker.tsx | 1 + .../DatePicker/BasicDesktopDatePickerV6.tsx | 16 ++++++++ test/e2e/index.test.ts | 38 +++++++++++++++++-- 5 files changed, 57 insertions(+), 6 deletions(-) create mode 100644 test/e2e/fixtures/DatePicker/BasicDesktopDatePickerV6.tsx diff --git a/packages/x-date-pickers/src/DateField/tests/selection.DateField.test.tsx b/packages/x-date-pickers/src/DateField/tests/selection.DateField.test.tsx index 80a08a1ba58f9..833bbdca11698 100644 --- a/packages/x-date-pickers/src/DateField/tests/selection.DateField.test.tsx +++ b/packages/x-date-pickers/src/DateField/tests/selection.DateField.test.tsx @@ -184,7 +184,7 @@ describe(' - Selection', () => { }); it('should select all sections with start separator', () => { - // Test with v6 input + // Test with v7 input const v7Response = renderWithProps({ enableAccessibleFieldDOMStructure: true, format: `- ${adapterToUse.formats.year}`, diff --git a/packages/x-date-pickers/src/internals/hooks/useField/useField.ts b/packages/x-date-pickers/src/internals/hooks/useField/useField.ts index e6c4ab482d389..405cdf2f98856 100644 --- a/packages/x-date-pickers/src/internals/hooks/useField/useField.ts +++ b/packages/x-date-pickers/src/internals/hooks/useField/useField.ts @@ -275,10 +275,12 @@ export const useField = < event.preventDefault(); onClear?.(event, ...(args as [])); clearValue(); - setSelectedSections(sectionOrder.startIndex); - if (!interactions.isFieldFocused) { + if (!interactions.isFieldFocused()) { + // setSelectedSections is called internally interactions.focusField(0); + } else { + setSelectedSections(sectionOrder.startIndex); } }); diff --git a/test/e2e/fixtures/DatePicker/BasicDesktopDatePicker.tsx b/test/e2e/fixtures/DatePicker/BasicDesktopDatePicker.tsx index 34cae29ab091a..992dd6244777d 100644 --- a/test/e2e/fixtures/DatePicker/BasicDesktopDatePicker.tsx +++ b/test/e2e/fixtures/DatePicker/BasicDesktopDatePicker.tsx @@ -10,6 +10,7 @@ export default function BasicDesktopDatePicker() { enableAccessibleFieldDOMStructure label="Desktop Date Picker" className="test-date-picker" + slotProps={{ field: { clearable: true } }} /> ); diff --git a/test/e2e/fixtures/DatePicker/BasicDesktopDatePickerV6.tsx b/test/e2e/fixtures/DatePicker/BasicDesktopDatePickerV6.tsx new file mode 100644 index 0000000000000..f94f56265f815 --- /dev/null +++ b/test/e2e/fixtures/DatePicker/BasicDesktopDatePickerV6.tsx @@ -0,0 +1,16 @@ +import * as React from 'react'; +import { DesktopDatePicker } from '@mui/x-date-pickers/DesktopDatePicker'; +import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; +import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; + +export default function BasicDesktopDatePickerV6() { + return ( + + + + ); +} diff --git a/test/e2e/index.test.ts b/test/e2e/index.test.ts index c0c2000ff89dc..5da95c6441d98 100644 --- a/test/e2e/index.test.ts +++ b/test/e2e/index.test.ts @@ -563,9 +563,9 @@ async function initializeEnvironment( await page.locator(`.${pickersSectionListClasses.root}`).click(); await input.fill('02/12/2020'); - expect(await page.getByRole('button').getAttribute('aria-label')).to.equal( - 'Choose date, selected date is Feb 12, 2020', - ); + expect( + await page.getByRole('button', { name: /Choose date/ }).getAttribute('aria-label'), + ).to.equal('Choose date, selected date is Feb 12, 2020'); }); it('should allow pasting a section', async () => { @@ -612,6 +612,38 @@ async function initializeEnvironment( await monthSection.press('2'); expect(await input.inputValue()).to.equal('02/11/2022'); }); + + it('should focus the first field section after clearing a value', async () => { + await renderFixture('DatePicker/BasicDesktopDatePicker'); + + const monthSection = page.getByRole('spinbutton', { name: 'Month' }); + await monthSection.press('2'); + await page.getByRole('button', { name: 'Clear value' }).click(); + + expect(await page.evaluate(() => document.activeElement?.textContent)).to.equal('MM'); + }); + + it('should focus the first field section after clearing a value in v6 input', async () => { + await renderFixture('DatePicker/BasicDesktopDatePickerV6'); + + await page.getByRole('textbox').fill('2'); + await page.getByRole('button', { name: 'Clear value' }).click(); + + // firefox does not support document.getSelection().toString() on input elements + if (browserType.name() === 'firefox') { + expect( + await page.evaluate(() => { + return ( + document.activeElement?.tagName === 'INPUT' && + // only focused input has value set + (document.activeElement as HTMLInputElement)?.value === 'MM/DD/YYYY' + ); + }), + ).to.equal(true); + } else { + expect(await page.evaluate(() => document.getSelection()?.toString())).to.equal('MM'); + } + }); }); describe('', () => { From 8644e2a46b971890238fd675b54fb00bd13c507e Mon Sep 17 00:00:00 2001 From: Nora <72460825+noraleonte@users.noreply.github.com> Date: Thu, 28 Mar 2024 11:29:23 +0200 Subject: [PATCH 26/55] [TreeView] Clean the usage of the term "item" and "node" in the internal API (#12449) --- .../headless/LogExpandedItems.js | 8 +- .../headless/LogExpandedItems.tsx | 10 +-- .../pages/x/api/tree-view/rich-tree-view.json | 6 +- .../x/api/tree-view/simple-tree-view.json | 6 +- docs/pages/x/api/tree-view/tree-item-2.json | 8 +- docs/pages/x/api/tree-view/tree-item.json | 2 +- docs/pages/x/api/tree-view/tree-view.json | 6 +- .../rich-tree-view/rich-tree-view.json | 6 +- .../simple-tree-view/simple-tree-view.json | 6 +- .../tree-view/tree-item-2/tree-item-2.json | 8 +- .../tree-view/tree-item/tree-item.json | 2 +- .../tree-view/tree-view/tree-view.json | 6 +- .../src/RichTreeView/RichTreeView.tsx | 10 +-- .../SimpleTreeView/SimpleTreeView.plugins.ts | 4 +- .../src/TreeItem/TreeItem.test.tsx | 88 +++++++++---------- .../x-tree-view/src/TreeItem/TreeItem.tsx | 8 +- .../src/TreeItem/treeItemClasses.ts | 2 +- .../src/TreeItem/useTreeItemState.ts | 18 ++-- .../src/TreeItem2Icon/TreeItem2Icon.types.ts | 8 +- .../useTreeItem2Utils/useTreeItem2Utils.tsx | 16 ++-- .../TreeViewProvider/DescendantProvider.tsx | 2 +- packages/x-tree-view/src/internals/index.ts | 4 +- .../src/internals/plugins/defaultPlugins.ts | 6 +- .../useTreeViewExpansion.ts | 18 ++-- .../useTreeViewExpansion.types.ts | 10 +-- .../useTreeViewFocus/useTreeViewFocus.ts | 68 +++++++------- .../useTreeViewFocus.types.ts | 12 +-- .../useTreeViewIcons.types.ts | 12 +-- .../useTreeViewId/useTreeViewId.types.ts | 2 +- .../plugins/useTreeViewItems/index.ts | 6 ++ .../useTreeViewItems.test.tsx} | 2 +- .../useTreeViewItems.ts} | 86 +++++++++--------- .../useTreeViewItems.types.ts} | 48 +++++----- .../plugins/useTreeViewJSXItems/index.ts | 6 ++ .../useTreeViewJSXItems.tsx} | 52 +++++------ .../useTreeViewJSXItems.types.ts | 20 +++++ .../plugins/useTreeViewJSXNodes/index.ts | 6 -- .../useTreeViewJSXNodes.types.ts | 20 ----- .../useTreeViewKeyboardNavigation.ts | 76 ++++++++-------- .../useTreeViewKeyboardNavigation.types.ts | 4 +- .../plugins/useTreeViewNodes/index.ts | 6 -- .../useTreeViewSelection.ts | 70 +++++++-------- .../useTreeViewSelection.types.ts | 12 +-- .../useTreeViewSelection.utils.ts | 14 +-- .../useTreeView/useTreeView.utils.ts | 38 ++++---- 45 files changed, 414 insertions(+), 414 deletions(-) create mode 100644 packages/x-tree-view/src/internals/plugins/useTreeViewItems/index.ts rename packages/x-tree-view/src/internals/plugins/{useTreeViewNodes/useTreeViewNodes.test.tsx => useTreeViewItems/useTreeViewItems.test.tsx} (98%) rename packages/x-tree-view/src/internals/plugins/{useTreeViewNodes/useTreeViewNodes.ts => useTreeViewItems/useTreeViewItems.ts} (74%) rename packages/x-tree-view/src/internals/plugins/{useTreeViewNodes/useTreeViewNodes.types.ts => useTreeViewItems/useTreeViewItems.types.ts} (67%) create mode 100644 packages/x-tree-view/src/internals/plugins/useTreeViewJSXItems/index.ts rename packages/x-tree-view/src/internals/plugins/{useTreeViewJSXNodes/useTreeViewJSXNodes.tsx => useTreeViewJSXItems/useTreeViewJSXItems.tsx} (73%) create mode 100644 packages/x-tree-view/src/internals/plugins/useTreeViewJSXItems/useTreeViewJSXItems.types.ts delete mode 100644 packages/x-tree-view/src/internals/plugins/useTreeViewJSXNodes/index.ts delete mode 100644 packages/x-tree-view/src/internals/plugins/useTreeViewJSXNodes/useTreeViewJSXNodes.types.ts delete mode 100644 packages/x-tree-view/src/internals/plugins/useTreeViewNodes/index.ts diff --git a/docs/data/tree-view/rich-tree-view/headless/LogExpandedItems.js b/docs/data/tree-view/rich-tree-view/headless/LogExpandedItems.js index fbccfb57e3c21..a9b775cd40e24 100644 --- a/docs/data/tree-view/rich-tree-view/headless/LogExpandedItems.js +++ b/docs/data/tree-view/rich-tree-view/headless/LogExpandedItems.js @@ -55,12 +55,12 @@ function TreeView(inProps) { ownerState, }); - const nodesToRender = instance.getNodesToRender(); + const itemsToRender = instance.getItemsToRender(); - const renderNode = ({ children: itemChildren, ...itemProps }) => { + const renderItem = ({ children: itemChildren, ...itemProps }) => { return ( - {itemChildren?.map(renderNode)} + {itemChildren?.map(renderItem)} ); }; @@ -68,7 +68,7 @@ function TreeView(inProps) { return ( - {nodesToRender.map(renderNode)} + {itemsToRender.map(renderItem)} ); diff --git a/docs/data/tree-view/rich-tree-view/headless/LogExpandedItems.tsx b/docs/data/tree-view/rich-tree-view/headless/LogExpandedItems.tsx index c8decec9b3ca6..67d52862b7cac 100644 --- a/docs/data/tree-view/rich-tree-view/headless/LogExpandedItems.tsx +++ b/docs/data/tree-view/rich-tree-view/headless/LogExpandedItems.tsx @@ -104,15 +104,15 @@ function TreeView( ownerState, }); - const nodesToRender = instance.getNodesToRender(); + const itemsToRender = instance.getItemsToRender(); - const renderNode = ({ + const renderItem = ({ children: itemChildren, ...itemProps - }: ReturnType[number]) => { + }: ReturnType[number]) => { return ( - {itemChildren?.map(renderNode)} + {itemChildren?.map(renderItem)} ); }; @@ -120,7 +120,7 @@ function TreeView( return ( - {nodesToRender.map(renderNode)} + {itemsToRender.map(renderItem)} ); diff --git a/docs/pages/x/api/tree-view/rich-tree-view.json b/docs/pages/x/api/tree-view/rich-tree-view.json index 181ae591f91cd..bb5084be29720 100644 --- a/docs/pages/x/api/tree-view/rich-tree-view.json +++ b/docs/pages/x/api/tree-view/rich-tree-view.json @@ -110,17 +110,17 @@ }, { "name": "collapseIcon", - "description": "The default icon used to collapse the node.", + "description": "The default icon used to collapse the item.", "class": null }, { "name": "expandIcon", - "description": "The default icon used to expand the node.", + "description": "The default icon used to expand the item.", "class": null }, { "name": "endIcon", - "description": "The default icon displayed next to an end node.\nThis is applied to all tree nodes and can be overridden by the TreeItem `icon` slot prop.", + "description": "The default icon displayed next to an end item.\nThis is applied to all tree items and can be overridden by the TreeItem `icon` slot prop.", "class": null } ], diff --git a/docs/pages/x/api/tree-view/simple-tree-view.json b/docs/pages/x/api/tree-view/simple-tree-view.json index 5957aad770567..0a4bd4f7b2da1 100644 --- a/docs/pages/x/api/tree-view/simple-tree-view.json +++ b/docs/pages/x/api/tree-view/simple-tree-view.json @@ -75,17 +75,17 @@ }, { "name": "collapseIcon", - "description": "The default icon used to collapse the node.", + "description": "The default icon used to collapse the item.", "class": null }, { "name": "expandIcon", - "description": "The default icon used to expand the node.", + "description": "The default icon used to expand the item.", "class": null }, { "name": "endIcon", - "description": "The default icon displayed next to an end node.\nThis is applied to all tree nodes and can be overridden by the TreeItem `icon` slot prop.", + "description": "The default icon displayed next to an end item.\nThis is applied to all tree items and can be overridden by the TreeItem `icon` slot prop.", "class": null } ], diff --git a/docs/pages/x/api/tree-view/tree-item-2.json b/docs/pages/x/api/tree-view/tree-item-2.json index 82e77380feb4c..e15c84a4b0efc 100644 --- a/docs/pages/x/api/tree-view/tree-item-2.json +++ b/docs/pages/x/api/tree-view/tree-item-2.json @@ -50,12 +50,12 @@ "default": "TreeItem2Label", "class": "MuiTreeItem2-label" }, - { "name": "collapseIcon", "description": "The icon used to collapse the node.", "class": null }, - { "name": "expandIcon", "description": "The icon used to expand the node.", "class": null }, - { "name": "endIcon", "description": "The icon displayed next to an end node.", "class": null }, + { "name": "collapseIcon", "description": "The icon used to collapse the item.", "class": null }, + { "name": "expandIcon", "description": "The icon used to expand the item.", "class": null }, + { "name": "endIcon", "description": "The icon displayed next to an end item.", "class": null }, { "name": "icon", - "description": "The icon to display next to the tree node's label.", + "description": "The icon to display next to the tree item's label.", "class": null } ], diff --git a/docs/pages/x/api/tree-view/tree-item.json b/docs/pages/x/api/tree-view/tree-item.json index e51cc365b7d30..58a3c04e4ff85 100644 --- a/docs/pages/x/api/tree-view/tree-item.json +++ b/docs/pages/x/api/tree-view/tree-item.json @@ -74,7 +74,7 @@ { "key": "iconContainer", "className": "MuiTreeItem-iconContainer", - "description": "Styles applied to the tree node icon.", + "description": "Styles applied to the tree item icon.", "isGlobal": false }, { diff --git a/docs/pages/x/api/tree-view/tree-view.json b/docs/pages/x/api/tree-view/tree-view.json index fae8965650e99..28823f6d6bf72 100644 --- a/docs/pages/x/api/tree-view/tree-view.json +++ b/docs/pages/x/api/tree-view/tree-view.json @@ -75,17 +75,17 @@ }, { "name": "collapseIcon", - "description": "The default icon used to collapse the node.", + "description": "The default icon used to collapse the item.", "class": null }, { "name": "expandIcon", - "description": "The default icon used to expand the node.", + "description": "The default icon used to expand the item.", "class": null }, { "name": "endIcon", - "description": "The default icon displayed next to an end node.\nThis is applied to all tree nodes and can be overridden by the TreeItem `icon` slot prop.", + "description": "The default icon displayed next to an end item.\nThis is applied to all tree items and can be overridden by the TreeItem `icon` slot prop.", "class": null } ], diff --git a/docs/translations/api-docs/tree-view/rich-tree-view/rich-tree-view.json b/docs/translations/api-docs/tree-view/rich-tree-view/rich-tree-view.json index 14b1089423573..4f113ec528dd0 100644 --- a/docs/translations/api-docs/tree-view/rich-tree-view/rich-tree-view.json +++ b/docs/translations/api-docs/tree-view/rich-tree-view/rich-tree-view.json @@ -88,9 +88,9 @@ }, "classDescriptions": {}, "slotDescriptions": { - "collapseIcon": "The default icon used to collapse the node.", - "endIcon": "The default icon displayed next to an end node. This is applied to all tree nodes and can be overridden by the TreeItem icon slot prop.", - "expandIcon": "The default icon used to expand the node.", + "collapseIcon": "The default icon used to collapse the item.", + "endIcon": "The default icon displayed next to an end item. This is applied to all tree items and can be overridden by the TreeItem icon slot prop.", + "expandIcon": "The default icon used to expand the item.", "item": "Custom component for the item.", "root": "Element rendered at the root." } diff --git a/docs/translations/api-docs/tree-view/simple-tree-view/simple-tree-view.json b/docs/translations/api-docs/tree-view/simple-tree-view/simple-tree-view.json index 24f8592c31a09..4a7aca190f6eb 100644 --- a/docs/translations/api-docs/tree-view/simple-tree-view/simple-tree-view.json +++ b/docs/translations/api-docs/tree-view/simple-tree-view/simple-tree-view.json @@ -74,9 +74,9 @@ }, "classDescriptions": {}, "slotDescriptions": { - "collapseIcon": "The default icon used to collapse the node.", - "endIcon": "The default icon displayed next to an end node. This is applied to all tree nodes and can be overridden by the TreeItem icon slot prop.", - "expandIcon": "The default icon used to expand the node.", + "collapseIcon": "The default icon used to collapse the item.", + "endIcon": "The default icon displayed next to an end item. This is applied to all tree items and can be overridden by the TreeItem icon slot prop.", + "expandIcon": "The default icon used to expand the item.", "root": "Element rendered at the root." } } diff --git a/docs/translations/api-docs/tree-view/tree-item-2/tree-item-2.json b/docs/translations/api-docs/tree-view/tree-item-2/tree-item-2.json index 2278abc442beb..43ff882ed936a 100644 --- a/docs/translations/api-docs/tree-view/tree-item-2/tree-item-2.json +++ b/docs/translations/api-docs/tree-view/tree-item-2/tree-item-2.json @@ -36,12 +36,12 @@ } }, "slotDescriptions": { - "collapseIcon": "The icon used to collapse the node.", + "collapseIcon": "The icon used to collapse the item.", "content": "The component that renders the content of the item. (e.g.: everything related to this item, not to its children).", - "endIcon": "The icon displayed next to an end node.", - "expandIcon": "The icon used to expand the node.", + "endIcon": "The icon displayed next to an end item.", + "expandIcon": "The icon used to expand the item.", "groupTransition": "The component that renders the children of the item.", - "icon": "The icon to display next to the tree node's label.", + "icon": "The icon to display next to the tree item's label.", "iconContainer": "The component that renders the icon.", "label": "The component that renders the item label.", "root": "The component that renders the root." diff --git a/docs/translations/api-docs/tree-view/tree-item/tree-item.json b/docs/translations/api-docs/tree-view/tree-item/tree-item.json index e1cf3bc289491..edf4ebca118f6 100644 --- a/docs/translations/api-docs/tree-view/tree-item/tree-item.json +++ b/docs/translations/api-docs/tree-view/tree-item/tree-item.json @@ -42,7 +42,7 @@ }, "iconContainer": { "description": "Styles applied to {{nodeName}}.", - "nodeName": "the tree node icon" + "nodeName": "the tree item icon" }, "label": { "description": "Styles applied to {{nodeName}}.", "nodeName": "the label element" }, "root": { "description": "Styles applied to the root element." }, diff --git a/docs/translations/api-docs/tree-view/tree-view/tree-view.json b/docs/translations/api-docs/tree-view/tree-view/tree-view.json index c6d01a54bd44e..d96dc4b910ffd 100644 --- a/docs/translations/api-docs/tree-view/tree-view/tree-view.json +++ b/docs/translations/api-docs/tree-view/tree-view/tree-view.json @@ -74,9 +74,9 @@ }, "classDescriptions": {}, "slotDescriptions": { - "collapseIcon": "The default icon used to collapse the node.", - "endIcon": "The default icon displayed next to an end node. This is applied to all tree nodes and can be overridden by the TreeItem icon slot prop.", - "expandIcon": "The default icon used to expand the node.", + "collapseIcon": "The default icon used to collapse the item.", + "endIcon": "The default icon displayed next to an end item. This is applied to all tree items and can be overridden by the TreeItem icon slot prop.", + "expandIcon": "The default icon used to expand the item.", "root": "Element rendered at the root." } } diff --git a/packages/x-tree-view/src/RichTreeView/RichTreeView.tsx b/packages/x-tree-view/src/RichTreeView/RichTreeView.tsx index 051e56a30c5d8..f0d469068892b 100644 --- a/packages/x-tree-view/src/RichTreeView/RichTreeView.tsx +++ b/packages/x-tree-view/src/RichTreeView/RichTreeView.tsx @@ -112,14 +112,14 @@ const RichTreeView = React.forwardRef(function RichTreeView< ownerState: props as RichTreeViewProps, }); - const nodesToRender = instance.getNodesToRender(); + const itemsToRender = instance.getItemsToRender(); - const renderNode = ({ + const renderItem = ({ label, itemId, id, children, - }: ReturnType[number]) => { + }: ReturnType[number]) => { return ( - {children?.map(renderNode)} + {children?.map(renderItem)} ); }; return ( - {nodesToRender.map(renderNode)} + {itemsToRender.map(renderItem)} ); }) as TreeViewComponent; diff --git a/packages/x-tree-view/src/SimpleTreeView/SimpleTreeView.plugins.ts b/packages/x-tree-view/src/SimpleTreeView/SimpleTreeView.plugins.ts index b239a326ff95d..7d2cabef636fe 100644 --- a/packages/x-tree-view/src/SimpleTreeView/SimpleTreeView.plugins.ts +++ b/packages/x-tree-view/src/SimpleTreeView/SimpleTreeView.plugins.ts @@ -4,12 +4,12 @@ import { DefaultTreeViewPluginSlotProps, DefaultTreeViewPluginSlots, } from '../internals/plugins/defaultPlugins'; -import { useTreeViewJSXNodes } from '../internals/plugins/useTreeViewJSXNodes'; +import { useTreeViewJSXItems } from '../internals/plugins/useTreeViewJSXItems'; import { ConvertPluginsIntoSignatures } from '../internals/models'; export const SIMPLE_TREE_VIEW_PLUGINS = [ ...DEFAULT_TREE_VIEW_PLUGINS, - useTreeViewJSXNodes, + useTreeViewJSXItems, ] as const; export type SimpleTreeViewPlugins = ConvertPluginsIntoSignatures; diff --git a/packages/x-tree-view/src/TreeItem/TreeItem.test.tsx b/packages/x-tree-view/src/TreeItem/TreeItem.test.tsx index 92ee6764f4ed8..4b1fe9226b925 100644 --- a/packages/x-tree-view/src/TreeItem/TreeItem.test.tsx +++ b/packages/x-tree-view/src/TreeItem/TreeItem.test.tsx @@ -12,11 +12,11 @@ import { describeConformance } from 'test/utils/describeConformance'; const TEST_TREE_VIEW_CONTEXT_VALUE: TreeViewContextValue = { instance: { - isNodeExpandable: () => false, - isNodeExpanded: () => false, - isNodeFocused: () => false, - isNodeSelected: () => false, - isNodeDisabled: (itemId: string | null): itemId is string => !!itemId, + isItemExpandable: () => false, + isItemExpanded: () => false, + isItemFocused: () => false, + isItemSelected: () => false, + isItemDisabled: (itemId: string | null): itemId is string => !!itemId, getTreeItemId: () => '', mapFirstCharFromJSX: () => () => {}, canItemBeTabbed: () => false, @@ -43,18 +43,18 @@ describe('', () => { describeConformance(, () => ({ classes, inheritComponent: 'li', - wrapMount: (mount) => (node: React.ReactNode) => { + wrapMount: (mount) => (item: React.ReactNode) => { const wrapper = mount( - {node} + {item} , ); return wrapper.childAt(0); }, - render: (node) => { + render: (item) => { return render( - {node} + {item} , ); }, @@ -403,7 +403,7 @@ describe('', () => { }); describe('when an item receives focus', () => { - it('should focus the first node if none of the nodes are selected before the tree receives focus', () => { + it('should focus the first item if none of the items are selected before the tree receives focus', () => { const { getByTestId, queryAllByRole } = render( @@ -441,7 +441,7 @@ describe('', () => { expect(getByTestId('two')).toHaveFocus(); }); - it('should work when focused node is removed', () => { + it('should work when focused item is removed', () => { let removeActiveItem; // a TreeItem which can remove from the tree by calling `removeActiveItem` function ControlledTreeItem(props) { @@ -480,7 +480,7 @@ describe('', () => { describe('Navigation', () => { describe('right arrow interaction', () => { - it('should open the node and not move the focus if focus is on a closed node', () => { + it('should open the item and not move the focus if focus is on a closed item', () => { const { getByTestId } = render( @@ -500,7 +500,7 @@ describe('', () => { expect(getByTestId('one')).toHaveFocus(); }); - it('should move focus to the first child if focus is on an open node', () => { + it('should move focus to the first child if focus is on an open item', () => { const { getByTestId } = render( @@ -562,7 +562,7 @@ describe('', () => { expect(getByTestId('one')).toHaveFocus(); }); - it("should move focus to the item's parent item if focus is on a child node that is an end item", () => { + it("should move focus to the item's parent item if focus is on a child item that is an end item", () => { const { getByTestId } = render( @@ -584,7 +584,7 @@ describe('', () => { expect(getByTestId('one')).to.have.attribute('aria-expanded', 'true'); }); - it("should move focus to the node's parent node if focus is on a child node that is closed", () => { + it("should move focus to the item's parent item if focus is on a child item that is closed", () => { const { getByTestId } = render( @@ -609,7 +609,7 @@ describe('', () => { expect(getByTestId('one')).to.have.attribute('aria-expanded', 'true'); }); - it('should do nothing if focus is on a root node that is closed', () => { + it('should do nothing if focus is on a root item that is closed', () => { const { getByTestId } = render( @@ -627,7 +627,7 @@ describe('', () => { expect(getByTestId('one')).toHaveFocus(); }); - it('should do nothing if focus is on a root node that is an end node', () => { + it('should do nothing if focus is on a root item that is an end item', () => { const { getByTestId } = render( @@ -644,7 +644,7 @@ describe('', () => { }); describe('down arrow interaction', () => { - it('moves focus to a sibling node', () => { + it('moves focus to a sibling item', () => { const { getByTestId } = render( @@ -745,7 +745,7 @@ describe('', () => { }); describe('up arrow interaction', () => { - it('moves focus to a sibling node', () => { + it('moves focus to a sibling item', () => { const { getByTestId } = render( @@ -811,7 +811,7 @@ describe('', () => { }); describe('home key interaction', () => { - it('moves focus to the first node in the tree', () => { + it('moves focus to the first item in the tree', () => { const { getByTestId } = render( @@ -834,7 +834,7 @@ describe('', () => { }); describe('end key interaction', () => { - it('moves focus to the last node in the tree without expanded items', () => { + it('moves focus to the last item in the tree without expanded items', () => { const { getByTestId } = render( @@ -855,7 +855,7 @@ describe('', () => { expect(getByTestId('four')).toHaveFocus(); }); - it('moves focus to the last node in the tree with expanded items', () => { + it('moves focus to the last item in the tree with expanded items', () => { const { getByTestId } = render( @@ -882,7 +882,7 @@ describe('', () => { }); describe('type-ahead functionality', () => { - it('moves focus to the next node with a name that starts with the typed character', () => { + it('moves focus to the next item with a name that starts with the typed character', () => { const { getByTestId } = render( @@ -911,7 +911,7 @@ describe('', () => { expect(getByTestId('one')).toHaveFocus(); }); - it('moves focus to the next node with the same starting character', () => { + it('moves focus to the next item with the same starting character', () => { const { getByTestId } = render( @@ -1048,7 +1048,7 @@ describe('', () => { describe('Expansion', () => { describe('enter key interaction', () => { - it('expands a node with children', () => { + it('expands an item with children', () => { const { getByTestId } = render( @@ -1068,7 +1068,7 @@ describe('', () => { expect(getByTestId('one')).to.have.attribute('aria-expanded', 'true'); }); - it('collapses a node with children', () => { + it('collapses an item with children', () => { const { getByTestId } = render( @@ -1094,7 +1094,7 @@ describe('', () => { describe('Single Selection', () => { describe('keyboard', () => { - it('should select a node when space is pressed', () => { + it('should select an item when space is pressed', () => { const { getByTestId } = render( @@ -1112,7 +1112,7 @@ describe('', () => { expect(getByTestId('one')).to.have.attribute('aria-selected', 'true'); }); - it('should not deselect a node when space is pressed on a selected node', () => { + it('should not deselect an item when space is pressed on a selected item', () => { const { getByTestId } = render( @@ -1131,7 +1131,7 @@ describe('', () => { expect(getByTestId('one')).to.have.attribute('aria-selected', 'true'); }); - it('should not select a node when space is pressed and disableSelection', () => { + it('should not select an node when space is pressed and disableSelection', () => { const { getByTestId } = render( @@ -1146,7 +1146,7 @@ describe('', () => { expect(getByTestId('one')).not.to.have.attribute('aria-selected'); }); - it('should select a node when Enter is pressed and the node is not selected', () => { + it('should select an item when Enter is pressed and the item is not selected', () => { const { getByTestId } = render( @@ -1161,7 +1161,7 @@ describe('', () => { expect(getByTestId('one')).to.have.attribute('aria-selected'); }); - it('should not un-select a node when Enter is pressed and the node is selected', () => { + it('should not un-select an item when Enter is pressed and the item is selected', () => { const { getByTestId } = render( @@ -1178,7 +1178,7 @@ describe('', () => { }); describe('mouse', () => { - it('should select a node when click', () => { + it('should select an item when click', () => { const { getByText, getByTestId } = render( @@ -1190,7 +1190,7 @@ describe('', () => { expect(getByTestId('one')).to.have.attribute('aria-selected', 'true'); }); - it('should not deselect a node when clicking a selected node', () => { + it('should not deselect an item when clicking a selected item', () => { const { getByText, getByTestId } = render( @@ -1202,7 +1202,7 @@ describe('', () => { expect(getByTestId('one')).to.have.attribute('aria-selected', 'true'); }); - it('should not select a node when click and disableSelection', () => { + it('should not select an item when click and disableSelection', () => { const { getByText, getByTestId } = render( @@ -1217,8 +1217,8 @@ describe('', () => { describe('Multi Selection', () => { describe('deselection', () => { - describe('mouse behavior when multiple nodes are selected', () => { - it('clicking a selected node holding ctrl should deselect the node', () => { + describe('mouse behavior when multiple items are selected', () => { + it('clicking a selected item holding ctrl should deselect the item', () => { const { getByText, getByTestId } = render( @@ -1233,7 +1233,7 @@ describe('', () => { expect(getByTestId('two')).to.have.attribute('aria-selected', 'true'); }); - it('clicking a selected node holding meta should deselect the node', () => { + it('clicking a selected item holding meta should deselect the item', () => { const { getByText, getByTestId } = render( @@ -1249,8 +1249,8 @@ describe('', () => { }); }); - describe('mouse behavior when one node is selected', () => { - it('clicking a selected node shout not deselect the node', () => { + describe('mouse behavior when one item is selected', () => { + it('clicking a selected item shout not deselect the item', () => { const { getByText, getByTestId } = render( @@ -1798,7 +1798,7 @@ describe('', () => { expect(getByTestId('one')).not.to.have.attribute('aria-selected'); }); - it('should prevent node triggering start of range selection', () => { + it('should prevent item triggering start of range selection', () => { const { getByText, getByTestId } = render( @@ -1816,7 +1816,7 @@ describe('', () => { expect(getByTestId('four')).to.have.attribute('aria-selected', 'false'); }); - it('should prevent node being selected as part of range selection', () => { + it('should prevent item being selected as part of range selection', () => { const { getByText, getByTestId } = render( @@ -1834,7 +1834,7 @@ describe('', () => { expect(getByTestId('four')).to.have.attribute('aria-selected', 'true'); }); - it('should prevent node triggering end of range selection', () => { + it('should prevent item triggering end of range selection', () => { const { getByText, getByTestId } = render( @@ -1870,7 +1870,7 @@ describe('', () => { expect(getByTestId('one')).not.to.have.attribute('aria-selected'); }); - it('should not prevent next node being range selected by keyboard', () => { + it('should not prevent next item being range selected by keyboard', () => { const { getByTestId } = render( @@ -1910,7 +1910,7 @@ describe('', () => { }); describe('`disabledItemsFocusable={false}`', () => { - it('should select the next non disabled node by keyboard + arrow down', () => { + it('should select the next non disabled item by keyboard + arrow down', () => { const { getByTestId } = render( diff --git a/packages/x-tree-view/src/TreeItem/TreeItem.tsx b/packages/x-tree-view/src/TreeItem/TreeItem.tsx index bfa635fd4f3c1..7dd7ba75dcf94 100644 --- a/packages/x-tree-view/src/TreeItem/TreeItem.tsx +++ b/packages/x-tree-view/src/TreeItem/TreeItem.tsx @@ -201,10 +201,10 @@ export const TreeItem = React.forwardRef(function TreeItem( return Boolean(reactChildren); }; const expandable = isExpandable(children); - const expanded = instance.isNodeExpanded(itemId); - const focused = instance.isNodeFocused(itemId); - const selected = instance.isNodeSelected(itemId); - const disabled = instance.isNodeDisabled(itemId); + const expanded = instance.isItemExpanded(itemId); + const focused = instance.isItemFocused(itemId); + const selected = instance.isItemSelected(itemId); + const disabled = instance.isItemDisabled(itemId); const ownerState: TreeItemOwnerState = { ...props, diff --git a/packages/x-tree-view/src/TreeItem/treeItemClasses.ts b/packages/x-tree-view/src/TreeItem/treeItemClasses.ts index bbbd77f44ccb4..b5cab9b9719d1 100644 --- a/packages/x-tree-view/src/TreeItem/treeItemClasses.ts +++ b/packages/x-tree-view/src/TreeItem/treeItemClasses.ts @@ -16,7 +16,7 @@ export interface TreeItemClasses { focused: string; /** State class applied to the element when disabled. */ disabled: string; - /** Styles applied to the tree node icon. */ + /** Styles applied to the tree item icon. */ iconContainer: string; /** Styles applied to the label element. */ label: string; diff --git a/packages/x-tree-view/src/TreeItem/useTreeItemState.ts b/packages/x-tree-view/src/TreeItem/useTreeItemState.ts index 41085c0109882..0c2442d3ec15c 100644 --- a/packages/x-tree-view/src/TreeItem/useTreeItemState.ts +++ b/packages/x-tree-view/src/TreeItem/useTreeItemState.ts @@ -8,11 +8,11 @@ export function useTreeItemState(itemId: string) { selection: { multiSelect }, } = useTreeViewContext(); - const expandable = instance.isNodeExpandable(itemId); - const expanded = instance.isNodeExpanded(itemId); - const focused = instance.isNodeFocused(itemId); - const selected = instance.isNodeSelected(itemId); - const disabled = instance.isNodeDisabled(itemId); + const expandable = instance.isItemExpandable(itemId); + const expanded = instance.isItemExpanded(itemId); + const focused = instance.isItemFocused(itemId); + const selected = instance.isItemSelected(itemId); + const disabled = instance.isItemDisabled(itemId); const handleExpansion = (event: React.MouseEvent) => { if (!disabled) { @@ -23,8 +23,8 @@ export function useTreeItemState(itemId: string) { const multiple = multiSelect && (event.shiftKey || event.ctrlKey || event.metaKey); // If already expanded and trying to toggle selection don't close - if (expandable && !(multiple && instance.isNodeExpanded(itemId))) { - instance.toggleNodeExpansion(event, itemId); + if (expandable && !(multiple && instance.isItemExpanded(itemId))) { + instance.toggleItemExpansion(event, itemId); } } }; @@ -41,10 +41,10 @@ export function useTreeItemState(itemId: string) { if (event.shiftKey) { instance.selectRange(event, { end: itemId }); } else { - instance.selectNode(event, itemId, true); + instance.selectItem(event, itemId, true); } } else { - instance.selectNode(event, itemId); + instance.selectItem(event, itemId); } } }; diff --git a/packages/x-tree-view/src/TreeItem2Icon/TreeItem2Icon.types.ts b/packages/x-tree-view/src/TreeItem2Icon/TreeItem2Icon.types.ts index e3af78d0820d9..eca8d8da6012e 100644 --- a/packages/x-tree-view/src/TreeItem2Icon/TreeItem2Icon.types.ts +++ b/packages/x-tree-view/src/TreeItem2Icon/TreeItem2Icon.types.ts @@ -4,19 +4,19 @@ import { UseTreeItem2Status } from '../useTreeItem2'; export interface TreeItem2IconSlots { /** - * The icon used to collapse the node. + * The icon used to collapse the item. */ collapseIcon?: React.ElementType; /** - * The icon used to expand the node. + * The icon used to expand the item. */ expandIcon?: React.ElementType; /** - * The icon displayed next to an end node. + * The icon displayed next to an end item. */ endIcon?: React.ElementType; /** - * The icon to display next to the tree node's label. + * The icon to display next to the tree item's label. */ icon?: React.ElementType; } diff --git a/packages/x-tree-view/src/hooks/useTreeItem2Utils/useTreeItem2Utils.tsx b/packages/x-tree-view/src/hooks/useTreeItem2Utils/useTreeItem2Utils.tsx index 020f82748e12b..87ed49fff4dc0 100644 --- a/packages/x-tree-view/src/hooks/useTreeItem2Utils/useTreeItem2Utils.tsx +++ b/packages/x-tree-view/src/hooks/useTreeItem2Utils/useTreeItem2Utils.tsx @@ -27,10 +27,10 @@ export const useTreeItem2Utils = ({ const status: UseTreeItem2Status = { expandable: Boolean(Array.isArray(children) ? children.length : children), - expanded: instance.isNodeExpanded(itemId), - focused: instance.isNodeFocused(itemId), - selected: instance.isNodeSelected(itemId), - disabled: instance.isNodeDisabled(itemId), + expanded: instance.isItemExpanded(itemId), + focused: instance.isItemFocused(itemId), + selected: instance.isItemSelected(itemId), + disabled: instance.isItemDisabled(itemId), }; const handleExpansion = (event: React.MouseEvent) => { @@ -45,8 +45,8 @@ export const useTreeItem2Utils = ({ const multiple = multiSelect && (event.shiftKey || event.ctrlKey || event.metaKey); // If already expanded and trying to toggle selection don't close - if (status.expandable && !(multiple && instance.isNodeExpanded(itemId))) { - instance.toggleNodeExpansion(event, itemId); + if (status.expandable && !(multiple && instance.isItemExpanded(itemId))) { + instance.toggleItemExpansion(event, itemId); } }; @@ -65,10 +65,10 @@ export const useTreeItem2Utils = ({ if (event.shiftKey) { instance.selectRange(event, { end: itemId }); } else { - instance.selectNode(event, itemId, true); + instance.selectItem(event, itemId, true); } } else { - instance.selectNode(event, itemId); + instance.selectItem(event, itemId); } }; diff --git a/packages/x-tree-view/src/internals/TreeViewProvider/DescendantProvider.tsx b/packages/x-tree-view/src/internals/TreeViewProvider/DescendantProvider.tsx index f7cf84eb66701..7e145beaeac9d 100644 --- a/packages/x-tree-view/src/internals/TreeViewProvider/DescendantProvider.tsx +++ b/packages/x-tree-view/src/internals/TreeViewProvider/DescendantProvider.tsx @@ -50,7 +50,7 @@ const noop = () => {}; * We use this for focus management, keyboard navigation, and typeahead * functionality for some components. * - * The hook accepts the element node + * The hook accepts the element item * * Our main goals with this are: * 1) maximum composability, diff --git a/packages/x-tree-view/src/internals/index.ts b/packages/x-tree-view/src/internals/index.ts index 9ae35c05e9d7c..13f393a2a829f 100644 --- a/packages/x-tree-view/src/internals/index.ts +++ b/packages/x-tree-view/src/internals/index.ts @@ -16,7 +16,7 @@ export type { UseTreeViewFocusSignature } from './plugins/useTreeViewFocus'; export type { UseTreeViewKeyboardNavigationSignature } from './plugins/useTreeViewKeyboardNavigation'; export type { UseTreeViewIdSignature } from './plugins/useTreeViewId'; export type { UseTreeViewIconsSignature } from './plugins/useTreeViewIcons'; -export type { UseTreeViewNodesSignature } from './plugins/useTreeViewNodes'; -export type { UseTreeViewJSXNodesSignature } from './plugins/useTreeViewJSXNodes'; +export type { UseTreeViewItemsSignature } from './plugins/useTreeViewItems'; +export type { UseTreeViewJSXItemsSignature } from './plugins/useTreeViewJSXItems'; export { extractPluginParamsFromProps } from './utils/extractPluginParamsFromProps'; diff --git a/packages/x-tree-view/src/internals/plugins/defaultPlugins.ts b/packages/x-tree-view/src/internals/plugins/defaultPlugins.ts index c0c92e6bff0d0..f737c5dcc8c9b 100644 --- a/packages/x-tree-view/src/internals/plugins/defaultPlugins.ts +++ b/packages/x-tree-view/src/internals/plugins/defaultPlugins.ts @@ -1,5 +1,5 @@ import { useTreeViewId, UseTreeViewIdParameters } from './useTreeViewId'; -import { useTreeViewNodes, UseTreeViewNodesParameters } from './useTreeViewNodes'; +import { useTreeViewItems, UseTreeViewItemsParameters } from './useTreeViewItems'; import { useTreeViewExpansion, UseTreeViewExpansionParameters } from './useTreeViewExpansion'; import { useTreeViewSelection, UseTreeViewSelectionParameters } from './useTreeViewSelection'; import { useTreeViewFocus, UseTreeViewFocusParameters } from './useTreeViewFocus'; @@ -9,7 +9,7 @@ import { ConvertPluginsIntoSignatures, MergePluginsProperty } from '../models'; export const DEFAULT_TREE_VIEW_PLUGINS = [ useTreeViewId, - useTreeViewNodes, + useTreeViewItems, useTreeViewExpansion, useTreeViewSelection, useTreeViewFocus, @@ -29,7 +29,7 @@ export type DefaultTreeViewPluginSlotProps = MergePluginsProperty< // We can't infer this type from the plugin, otherwise we would lose the generics. export interface DefaultTreeViewPluginParameters extends UseTreeViewIdParameters, - UseTreeViewNodesParameters, + UseTreeViewItemsParameters, UseTreeViewExpansionParameters, UseTreeViewFocusParameters, UseTreeViewSelectionParameters, diff --git a/packages/x-tree-view/src/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.ts b/packages/x-tree-view/src/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.ts index c97d903ed1165..7fa1d771b5a4a 100644 --- a/packages/x-tree-view/src/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.ts +++ b/packages/x-tree-view/src/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.ts @@ -14,7 +14,7 @@ export const useTreeViewExpansion: TreeViewPlugin models.expandedItems.setControlledValue(value); }; - const isNodeExpanded = React.useCallback( + const isItemExpanded = React.useCallback( (itemId: string) => { return Array.isArray(models.expandedItems.value) ? models.expandedItems.value.indexOf(itemId) !== -1 @@ -23,12 +23,12 @@ export const useTreeViewExpansion: TreeViewPlugin [models.expandedItems.value], ); - const isNodeExpandable = React.useCallback( + const isItemExpandable = React.useCallback( (itemId: string) => !!instance.getNode(itemId)?.expandable, [instance], ); - const toggleNodeExpansion = useEventCallback( + const toggleItemExpansion = useEventCallback( (event: React.SyntheticEvent, itemId: string | null) => { if (itemId == null) { return; @@ -56,7 +56,7 @@ export const useTreeViewExpansion: TreeViewPlugin const siblings = instance.getChildrenIds(node.parentId); const diff = siblings.filter( - (child) => instance.isNodeExpandable(child) && !instance.isNodeExpanded(child), + (child) => instance.isItemExpandable(child) && !instance.isItemExpanded(child), ); const newExpanded = models.expandedItems.value.concat(diff); @@ -73,9 +73,9 @@ export const useTreeViewExpansion: TreeViewPlugin }; populateInstance(instance, { - isNodeExpanded, - isNodeExpandable, - toggleNodeExpansion, + isItemExpanded, + isItemExpandable, + toggleItemExpansion, expandAllSiblings, }); }; @@ -86,11 +86,11 @@ useTreeViewExpansion.models = { }, }; -const DEFAULT_EXPANDED_NODES: string[] = []; +const DEFAULT_EXPANDED_ITEMS: string[] = []; useTreeViewExpansion.getDefaultizedParams = (params) => ({ ...params, - defaultExpandedItems: params.defaultExpandedItems ?? DEFAULT_EXPANDED_NODES, + defaultExpandedItems: params.defaultExpandedItems ?? DEFAULT_EXPANDED_ITEMS, }); useTreeViewExpansion.params = { diff --git a/packages/x-tree-view/src/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.types.ts b/packages/x-tree-view/src/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.types.ts index 1a66b9dd86fd0..9f261541492a6 100644 --- a/packages/x-tree-view/src/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.types.ts +++ b/packages/x-tree-view/src/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.types.ts @@ -1,11 +1,11 @@ import * as React from 'react'; import { DefaultizedProps, TreeViewPluginSignature } from '../../models'; -import { UseTreeViewNodesSignature } from '../useTreeViewNodes'; +import { UseTreeViewItemsSignature } from '../useTreeViewItems'; export interface UseTreeViewExpansionInstance { - isNodeExpanded: (itemId: string) => boolean; - isNodeExpandable: (itemId: string) => boolean; - toggleNodeExpansion: (event: React.SyntheticEvent, value: string) => void; + isItemExpanded: (itemId: string) => boolean; + isItemExpandable: (itemId: string) => boolean; + toggleItemExpansion: (event: React.SyntheticEvent, value: string) => void; expandAllSiblings: (event: React.KeyboardEvent, itemId: string) => void; } @@ -50,5 +50,5 @@ export type UseTreeViewExpansionSignature = TreeViewPluginSignature<{ defaultizedParams: UseTreeViewExpansionDefaultizedParameters; instance: UseTreeViewExpansionInstance; modelNames: 'expandedItems'; - dependantPlugins: [UseTreeViewNodesSignature]; + dependantPlugins: [UseTreeViewItemsSignature]; }>; 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 72c756902d675..eab87b06ba785 100644 --- a/packages/x-tree-view/src/internals/plugins/useTreeViewFocus/useTreeViewFocus.ts +++ b/packages/x-tree-view/src/internals/plugins/useTreeViewFocus/useTreeViewFocus.ts @@ -14,7 +14,7 @@ const useTabbableItemId = ( ) => { const isItemVisible = (itemId: string) => { const node = instance.getNode(itemId); - return node && (node.parentId == null || instance.isNodeExpanded(node.parentId)); + return node && (node.parentId == null || instance.isItemExpanded(node.parentId)); }; let tabbableItemId: string | null | undefined; @@ -43,9 +43,9 @@ export const useTreeViewFocus: TreeViewPlugin = ({ const tabbableItemId = useTabbableItemId(instance, models.selectedItems.value); const setFocusedItemId = useEventCallback((itemId: React.SetStateAction) => { - const cleanItemId = typeof itemId === 'function' ? itemId(state.focusedNodeId) : itemId; - if (state.focusedNodeId !== cleanItemId) { - setState((prevState) => ({ ...prevState, focusedNodeId: cleanItemId })); + const cleanItemId = typeof itemId === 'function' ? itemId(state.focusedItemId) : itemId; + if (state.focusedItemId !== cleanItemId) { + setState((prevState) => ({ ...prevState, focusedItemId: cleanItemId })); } }); @@ -56,14 +56,14 @@ export const useTreeViewFocus: TreeViewPlugin = ({ [rootRef], ); - const isNodeFocused = React.useCallback( - (itemId: string) => state.focusedNodeId === itemId && isTreeViewFocused(), - [state.focusedNodeId, isTreeViewFocused], + const isItemFocused = React.useCallback( + (itemId: string) => state.focusedItemId === itemId && isTreeViewFocused(), + [state.focusedItemId, isTreeViewFocused], ); - const isNodeVisible = (itemId: string) => { + const isItemVisible = (itemId: string) => { const node = instance.getNode(itemId); - return node && (node.parentId == null || instance.isNodeExpanded(node.parentId)); + return node && (node.parentId == null || instance.isItemExpanded(node.parentId)); }; const innerFocusItem = (event: React.SyntheticEvent | null, itemId: string) => { @@ -79,37 +79,37 @@ export const useTreeViewFocus: TreeViewPlugin = ({ } }; - const focusItem = useEventCallback((event: React.SyntheticEvent, nodeId: string) => { - // If we receive a nodeId, and it is visible, the focus will be set to it - if (isNodeVisible(nodeId)) { - innerFocusItem(event, nodeId); + const focusItem = useEventCallback((event: React.SyntheticEvent, itemId: string) => { + // If we receive an itemId, and it is visible, the focus will be set to it + if (isItemVisible(itemId)) { + innerFocusItem(event, itemId); } }); - const focusDefaultNode = useEventCallback((event: React.SyntheticEvent | null) => { - let nodeToFocusId: string | null | undefined; + const focusDefaultItem = useEventCallback((event: React.SyntheticEvent | null) => { + let itemToFocusId: string | null | undefined; if (Array.isArray(models.selectedItems.value)) { - nodeToFocusId = models.selectedItems.value.find(isNodeVisible); - } else if (models.selectedItems.value != null && isNodeVisible(models.selectedItems.value)) { - nodeToFocusId = models.selectedItems.value; + itemToFocusId = models.selectedItems.value.find(isItemVisible); + } else if (models.selectedItems.value != null && isItemVisible(models.selectedItems.value)) { + itemToFocusId = models.selectedItems.value; } - if (nodeToFocusId == null) { - nodeToFocusId = instance.getNavigableChildrenIds(null)[0]; + if (itemToFocusId == null) { + itemToFocusId = instance.getNavigableChildrenIds(null)[0]; } - innerFocusItem(event, nodeToFocusId); + innerFocusItem(event, itemToFocusId); }); const removeFocusedItem = useEventCallback(() => { - if (state.focusedNodeId == null) { + if (state.focusedItemId == null) { return; } - const node = instance.getNode(state.focusedNodeId); + const node = instance.getNode(state.focusedItemId); if (node) { const itemElement = document.getElementById( - instance.getTreeItemId(state.focusedNodeId, node.idAttribute), + instance.getTreeItemId(state.focusedItemId, node.idAttribute), ); if (itemElement) { itemElement.blur(); @@ -122,10 +122,10 @@ export const useTreeViewFocus: TreeViewPlugin = ({ const canItemBeTabbed = (itemId: string) => itemId === tabbableItemId; populateInstance(instance, { - isNodeFocused, + isItemFocused, canItemBeTabbed, focusItem, - focusDefaultNode, + focusDefaultItem, removeFocusedItem, }); @@ -133,9 +133,9 @@ export const useTreeViewFocus: TreeViewPlugin = ({ focusItem, }); - useInstanceEventHandler(instance, 'removeNode', ({ id }) => { - if (state.focusedNodeId === id) { - instance.focusDefaultNode(null); + useInstanceEventHandler(instance, 'removeItem', ({ id }) => { + if (state.focusedItemId === id) { + instance.focusDefaultItem(null); } }); @@ -144,13 +144,13 @@ export const useTreeViewFocus: TreeViewPlugin = ({ otherHandlers.onFocus?.(event); // if the event bubbled (which is React specific) we don't want to steal focus if (event.target === event.currentTarget) { - instance.focusDefaultNode(event); + instance.focusDefaultItem(event); } }; - const focusedNode = instance.getNode(state.focusedNodeId!); - const activeDescendant = focusedNode - ? instance.getTreeItemId(focusedNode.id, focusedNode.idAttribute) + const focusedItem = instance.getNode(state.focusedItemId!); + const activeDescendant = focusedItem + ? instance.getTreeItemId(focusedItem.id, focusedItem.idAttribute) : null; return { @@ -161,7 +161,7 @@ export const useTreeViewFocus: TreeViewPlugin = ({ }; }; -useTreeViewFocus.getInitialState = () => ({ focusedNodeId: null }); +useTreeViewFocus.getInitialState = () => ({ focusedItemId: null }); useTreeViewFocus.params = { onItemFocus: true, diff --git a/packages/x-tree-view/src/internals/plugins/useTreeViewFocus/useTreeViewFocus.types.ts b/packages/x-tree-view/src/internals/plugins/useTreeViewFocus/useTreeViewFocus.types.ts index 2b9fe5f6f1e66..1a5e571f1317a 100644 --- a/packages/x-tree-view/src/internals/plugins/useTreeViewFocus/useTreeViewFocus.types.ts +++ b/packages/x-tree-view/src/internals/plugins/useTreeViewFocus/useTreeViewFocus.types.ts @@ -1,15 +1,15 @@ import * as React from 'react'; import { TreeViewPluginSignature } from '../../models'; import { UseTreeViewIdSignature } from '../useTreeViewId/useTreeViewId.types'; -import type { UseTreeViewNodesSignature } from '../useTreeViewNodes'; +import type { UseTreeViewItemsSignature } from '../useTreeViewItems'; import type { UseTreeViewSelectionSignature } from '../useTreeViewSelection'; import { UseTreeViewExpansionSignature } from '../useTreeViewExpansion'; export interface UseTreeViewFocusInstance { - isNodeFocused: (itemId: string) => boolean; + isItemFocused: (itemId: string) => boolean; canItemBeTabbed: (itemId: string) => boolean; - focusItem: (event: React.SyntheticEvent, nodeId: string) => void; - focusDefaultNode: (event: React.SyntheticEvent | null) => void; + focusItem: (event: React.SyntheticEvent, itemId: string) => void; + focusDefaultItem: (event: React.SyntheticEvent | null) => void; removeFocusedItem: () => void; } @@ -28,7 +28,7 @@ export interface UseTreeViewFocusParameters { export type UseTreeViewFocusDefaultizedParameters = UseTreeViewFocusParameters; export interface UseTreeViewFocusState { - focusedNodeId: string | null; + focusedItemId: string | null; } export type UseTreeViewFocusSignature = TreeViewPluginSignature<{ @@ -39,7 +39,7 @@ export type UseTreeViewFocusSignature = TreeViewPluginSignature<{ state: UseTreeViewFocusState; dependantPlugins: [ UseTreeViewIdSignature, - UseTreeViewNodesSignature, + UseTreeViewItemsSignature, UseTreeViewSelectionSignature, UseTreeViewExpansionSignature, ]; diff --git a/packages/x-tree-view/src/internals/plugins/useTreeViewIcons/useTreeViewIcons.types.ts b/packages/x-tree-view/src/internals/plugins/useTreeViewIcons/useTreeViewIcons.types.ts index 8090beb113c32..0ceb50b8fe3e2 100644 --- a/packages/x-tree-view/src/internals/plugins/useTreeViewIcons/useTreeViewIcons.types.ts +++ b/packages/x-tree-view/src/internals/plugins/useTreeViewIcons/useTreeViewIcons.types.ts @@ -1,7 +1,7 @@ import * as React from 'react'; import { SlotComponentProps } from '@mui/base/utils'; import { TreeViewPluginSignature } from '../../models'; -import { UseTreeViewNodesSignature } from '../useTreeViewNodes'; +import { UseTreeViewItemsSignature } from '../useTreeViewItems'; import { UseTreeViewSelectionSignature } from '../useTreeViewSelection'; export interface UseTreeViewIconsParameters {} @@ -10,16 +10,16 @@ export type UseTreeViewIconsDefaultizedParameters = UseTreeViewIconsParameters; interface UseTreeViewIconsSlots { /** - * The default icon used to collapse the node. + * The default icon used to collapse the item. */ collapseIcon?: React.ElementType; /** - * The default icon used to expand the node. + * The default icon used to expand the item. */ expandIcon?: React.ElementType; /** - * The default icon displayed next to an end node. - * This is applied to all tree nodes and can be overridden by the TreeItem `icon` slot prop. + * The default icon displayed next to an end item. + * This is applied to all tree items and can be overridden by the TreeItem `icon` slot prop. */ endIcon?: React.ElementType; } @@ -43,5 +43,5 @@ export type UseTreeViewIconsSignature = TreeViewPluginSignature<{ contextValue: UseTreeViewIconsContextValue; slots: UseTreeViewIconsSlots; slotProps: UseTreeViewIconsSlotProps; - dependantPlugins: [UseTreeViewNodesSignature, UseTreeViewSelectionSignature]; + dependantPlugins: [UseTreeViewItemsSignature, UseTreeViewSelectionSignature]; }>; diff --git a/packages/x-tree-view/src/internals/plugins/useTreeViewId/useTreeViewId.types.ts b/packages/x-tree-view/src/internals/plugins/useTreeViewId/useTreeViewId.types.ts index e7b84528bfe45..649405e2bb679 100644 --- a/packages/x-tree-view/src/internals/plugins/useTreeViewId/useTreeViewId.types.ts +++ b/packages/x-tree-view/src/internals/plugins/useTreeViewId/useTreeViewId.types.ts @@ -15,7 +15,7 @@ export interface UseTreeViewIdParameters { export type UseTreeViewIdDefaultizedParameters = UseTreeViewIdParameters; export interface UseTreeViewIdState { - focusedNodeId: string | null; + focusedItemId: string | null; } export type UseTreeViewIdSignature = TreeViewPluginSignature<{ diff --git a/packages/x-tree-view/src/internals/plugins/useTreeViewItems/index.ts b/packages/x-tree-view/src/internals/plugins/useTreeViewItems/index.ts new file mode 100644 index 0000000000000..63c1a5d694cea --- /dev/null +++ b/packages/x-tree-view/src/internals/plugins/useTreeViewItems/index.ts @@ -0,0 +1,6 @@ +export { useTreeViewItems } from './useTreeViewItems'; +export type { + UseTreeViewItemsSignature, + UseTreeViewItemsParameters, + UseTreeViewItemsDefaultizedParameters, +} from './useTreeViewItems.types'; diff --git a/packages/x-tree-view/src/internals/plugins/useTreeViewNodes/useTreeViewNodes.test.tsx b/packages/x-tree-view/src/internals/plugins/useTreeViewItems/useTreeViewItems.test.tsx similarity index 98% rename from packages/x-tree-view/src/internals/plugins/useTreeViewNodes/useTreeViewNodes.test.tsx rename to packages/x-tree-view/src/internals/plugins/useTreeViewItems/useTreeViewItems.test.tsx index 28f3e2b1f398f..e1f098e05799e 100644 --- a/packages/x-tree-view/src/internals/plugins/useTreeViewNodes/useTreeViewNodes.test.tsx +++ b/packages/x-tree-view/src/internals/plugins/useTreeViewItems/useTreeViewItems.test.tsx @@ -5,7 +5,7 @@ import { RichTreeView } from '@mui/x-tree-view/RichTreeView'; import { SimpleTreeView } from '@mui/x-tree-view/SimpleTreeView'; import { TreeItem } from '@mui/x-tree-view/TreeItem'; -describe('useTreeViewNodes', () => { +describe('useTreeViewItems', () => { const { render } = createRenderer(); it('should throw an error when two items have the same ID (items prop approach)', function test() { diff --git a/packages/x-tree-view/src/internals/plugins/useTreeViewNodes/useTreeViewNodes.ts b/packages/x-tree-view/src/internals/plugins/useTreeViewItems/useTreeViewItems.ts similarity index 74% rename from packages/x-tree-view/src/internals/plugins/useTreeViewNodes/useTreeViewNodes.ts rename to packages/x-tree-view/src/internals/plugins/useTreeViewItems/useTreeViewItems.ts index 01f133f5b9c60..045e6e849065d 100644 --- a/packages/x-tree-view/src/internals/plugins/useTreeViewNodes/useTreeViewNodes.ts +++ b/packages/x-tree-view/src/internals/plugins/useTreeViewItems/useTreeViewItems.ts @@ -2,25 +2,25 @@ import * as React from 'react'; import { TreeViewPlugin } from '../../models'; import { populateInstance, populatePublicAPI } from '../../useTreeView/useTreeView.utils'; import { - UseTreeViewNodesSignature, - UseTreeViewNodesDefaultizedParameters, + UseTreeViewItemsSignature, + UseTreeViewItemsDefaultizedParameters, TreeViewNodeMap, TreeViewItemIdAndChildren, - UseTreeViewNodesState, + UseTreeViewItemsState, TreeViewItemMap, -} from './useTreeViewNodes.types'; +} from './useTreeViewItems.types'; import { publishTreeViewEvent } from '../../utils/publishTreeViewEvent'; import { TreeViewBaseItem } from '../../../models'; -const updateNodesState = ({ +const updateItemsState = ({ items, isItemDisabled, getItemLabel, getItemId, }: Pick< - UseTreeViewNodesDefaultizedParameters, + UseTreeViewItemsDefaultizedParameters, 'items' | 'isItemDisabled' | 'getItemLabel' | 'getItemId' ->): UseTreeViewNodesState['nodes'] => { +>): UseTreeViewItemsState['items'] => { const nodeMap: TreeViewNodeMap = {}; const itemMap: TreeViewItemMap = {}; @@ -91,7 +91,7 @@ const updateNodesState = ({ }; }; -export const useTreeViewNodes: TreeViewPlugin = ({ +export const useTreeViewItems: TreeViewPlugin = ({ instance, publicAPI, params, @@ -99,35 +99,35 @@ export const useTreeViewNodes: TreeViewPlugin = ({ setState, }) => { const getNode = React.useCallback( - (itemId: string) => state.nodes.nodeMap[itemId], - [state.nodes.nodeMap], + (itemId: string) => state.items.nodeMap[itemId], + [state.items.nodeMap], ); const getItem = React.useCallback( - (itemId: string) => state.nodes.itemMap[itemId], - [state.nodes.itemMap], + (itemId: string) => state.items.itemMap[itemId], + [state.items.itemMap], ); - const isNodeDisabled = React.useCallback( + const isItemDisabled = React.useCallback( (itemId: string | null): itemId is string => { if (itemId == null) { return false; } - let item = instance.getNode(itemId); + let node = instance.getNode(itemId); - // This can be called before the item has been added to the node map. - if (!item) { + // This can be called before the item has been added to the item map. + if (!node) { return false; } - if (item.disabled) { + if (node.disabled) { return true; } - while (item.parentId != null) { - item = instance.getNode(item.parentId); - if (item.disabled) { + while (node.parentId != null) { + node = instance.getNode(node.parentId); + if (node.disabled) { return true; } } @@ -139,18 +139,18 @@ export const useTreeViewNodes: TreeViewPlugin = ({ const getChildrenIds = React.useCallback( (itemId: string | null) => - Object.values(state.nodes.nodeMap) + Object.values(state.items.nodeMap) .filter((item) => item.parentId === itemId) .sort((a, b) => a.index - b.index) .map((child) => child.id), - [state.nodes.nodeMap], + [state.items.nodeMap], ); const getNavigableChildrenIds = (itemId: string | null) => { let childrenIds = instance.getChildrenIds(itemId); if (!params.disabledItemsFocusable) { - childrenIds = childrenIds.filter((item) => !instance.isNodeDisabled(item)); + childrenIds = childrenIds.filter((item) => !instance.isItemDisabled(item)); } return childrenIds; }; @@ -168,20 +168,20 @@ export const useTreeViewNodes: TreeViewPlugin = ({ } setState((prevState) => { - const newState = updateNodesState({ + const newState = updateItemsState({ items: params.items, isItemDisabled: params.isItemDisabled, getItemId: params.getItemId, getItemLabel: params.getItemLabel, }); - Object.values(prevState.nodes.nodeMap).forEach((node) => { - if (!newState.nodeMap[node.id]) { - publishTreeViewEvent(instance, 'removeNode', { id: node.id }); + Object.values(prevState.items.nodeMap).forEach((item) => { + if (!newState.nodeMap[item.id]) { + publishTreeViewEvent(instance, 'removeItem', { id: item.id }); } }); - return { ...prevState, nodes: newState }; + return { ...prevState, items: newState }; }); }, [ instance, @@ -192,35 +192,35 @@ export const useTreeViewNodes: TreeViewPlugin = ({ params.getItemLabel, ]); - const getNodesToRender = () => { + const getItemsToRender = () => { const getPropsFromItemId = ({ id, children, - }: TreeViewItemIdAndChildren): ReturnType[number] => { - const node = state.nodes.nodeMap[id]; + }: TreeViewItemIdAndChildren): ReturnType[number] => { + const item = state.items.nodeMap[id]; return { - label: node.label!, - itemId: node.id, - id: node.idAttribute, + label: item.label!, + itemId: item.id, + id: item.idAttribute, children: children?.map(getPropsFromItemId), }; }; - return state.nodes.nodeTree.map(getPropsFromItemId); + return state.items.nodeTree.map(getPropsFromItemId); }; - populateInstance(instance, { + populateInstance(instance, { getNode, getItem, - getNodesToRender, + getItemsToRender, getChildrenIds, getNavigableChildrenIds, - isNodeDisabled, + isItemDisabled, preventItemUpdates, areItemUpdatesPrevented, }); - populatePublicAPI(publicAPI, { + populatePublicAPI(publicAPI, { getItem, }); @@ -229,8 +229,8 @@ export const useTreeViewNodes: TreeViewPlugin = ({ }; }; -useTreeViewNodes.getInitialState = (params) => ({ - nodes: updateNodesState({ +useTreeViewItems.getInitialState = (params) => ({ + items: updateItemsState({ items: params.items, isItemDisabled: params.isItemDisabled, getItemId: params.getItemId, @@ -238,12 +238,12 @@ useTreeViewNodes.getInitialState = (params) => ({ }), }); -useTreeViewNodes.getDefaultizedParams = (params) => ({ +useTreeViewItems.getDefaultizedParams = (params) => ({ ...params, disabledItemsFocusable: params.disabledItemsFocusable ?? false, }); -useTreeViewNodes.params = { +useTreeViewItems.params = { disabledItemsFocusable: true, items: true, isItemDisabled: true, diff --git a/packages/x-tree-view/src/internals/plugins/useTreeViewNodes/useTreeViewNodes.types.ts b/packages/x-tree-view/src/internals/plugins/useTreeViewItems/useTreeViewItems.types.ts similarity index 67% rename from packages/x-tree-view/src/internals/plugins/useTreeViewNodes/useTreeViewNodes.types.ts rename to packages/x-tree-view/src/internals/plugins/useTreeViewItems/useTreeViewItems.types.ts index 352cf93605ff2..37e704219cab1 100644 --- a/packages/x-tree-view/src/internals/plugins/useTreeViewNodes/useTreeViewNodes.types.ts +++ b/packages/x-tree-view/src/internals/plugins/useTreeViewItems/useTreeViewItems.types.ts @@ -1,20 +1,20 @@ import { TreeViewNode, DefaultizedProps, TreeViewPluginSignature } from '../../models'; import { TreeViewItemId } from '../../../models'; -interface TreeViewNodeProps { +interface TreeViewItemProps { label: string; itemId: string; id: string | undefined; - children?: TreeViewNodeProps[]; + children?: TreeViewItemProps[]; } -export interface UseTreeViewNodesInstance { +export interface UseTreeViewItemsInstance { getNode: (itemId: string) => TreeViewNode; getItem: (itemId: string) => R; - getNodesToRender: () => TreeViewNodeProps[]; + getItemsToRender: () => TreeViewItemProps[]; getChildrenIds: (itemId: string | null) => string[]; getNavigableChildrenIds: (itemId: string | null) => string[]; - isNodeDisabled: (itemId: string | null) => itemId is string; + isItemDisabled: (itemId: string | null) => itemId is string; /** * Freeze any future update to the state based on the `items` prop. * This is useful when `useTreeViewJSXNodes` is used to avoid having conflicting sources of truth. @@ -28,10 +28,10 @@ export interface UseTreeViewNodesInstance { areItemUpdatesPrevented: () => boolean; } -export interface UseTreeViewNodesPublicAPI - extends Pick, 'getItem'> {} +export interface UseTreeViewItemsPublicAPI + extends Pick, 'getItem'> {} -export interface UseTreeViewNodesParameters { +export interface UseTreeViewItemsParameters { /** * If `true`, will allow focus on disabled items. * @default false @@ -65,13 +65,13 @@ export interface UseTreeViewNodesParameters { getItemId?: (item: R) => TreeViewItemId; } -export type UseTreeViewNodesDefaultizedParameters = DefaultizedProps< - UseTreeViewNodesParameters, +export type UseTreeViewItemsDefaultizedParameters = DefaultizedProps< + UseTreeViewItemsParameters, 'disabledItemsFocusable' >; -interface UseTreeViewNodesEventLookup { - removeNode: { +interface UseTreeViewItemsEventLookup { + removeItem: { params: { id: string }; }; } @@ -81,25 +81,25 @@ export interface TreeViewItemIdAndChildren { children?: TreeViewItemIdAndChildren[]; } -export interface UseTreeViewNodesState { - nodes: { +export interface UseTreeViewItemsState { + items: { nodeTree: TreeViewItemIdAndChildren[]; nodeMap: TreeViewNodeMap; itemMap: TreeViewItemMap; }; } -interface UseTreeViewNodesContextValue - extends Pick, 'disabledItemsFocusable'> {} +interface UseTreeViewItemsContextValue + extends Pick, 'disabledItemsFocusable'> {} -export type UseTreeViewNodesSignature = TreeViewPluginSignature<{ - params: UseTreeViewNodesParameters; - defaultizedParams: UseTreeViewNodesDefaultizedParameters; - instance: UseTreeViewNodesInstance; - publicAPI: UseTreeViewNodesPublicAPI; - events: UseTreeViewNodesEventLookup; - state: UseTreeViewNodesState; - contextValue: UseTreeViewNodesContextValue; +export type UseTreeViewItemsSignature = TreeViewPluginSignature<{ + params: UseTreeViewItemsParameters; + defaultizedParams: UseTreeViewItemsDefaultizedParameters; + instance: UseTreeViewItemsInstance; + publicAPI: UseTreeViewItemsPublicAPI; + events: UseTreeViewItemsEventLookup; + state: UseTreeViewItemsState; + contextValue: UseTreeViewItemsContextValue; }>; export type TreeViewNodeMap = { [itemId: string]: TreeViewNode }; diff --git a/packages/x-tree-view/src/internals/plugins/useTreeViewJSXItems/index.ts b/packages/x-tree-view/src/internals/plugins/useTreeViewJSXItems/index.ts new file mode 100644 index 0000000000000..1eff39d296b7f --- /dev/null +++ b/packages/x-tree-view/src/internals/plugins/useTreeViewJSXItems/index.ts @@ -0,0 +1,6 @@ +export { useTreeViewJSXItems } from './useTreeViewJSXItems'; +export type { + UseTreeViewJSXItemsSignature, + UseTreeViewItemsParameters, + UseTreeViewItemsDefaultizedParameters, +} from './useTreeViewJSXItems.types'; diff --git a/packages/x-tree-view/src/internals/plugins/useTreeViewJSXNodes/useTreeViewJSXNodes.tsx b/packages/x-tree-view/src/internals/plugins/useTreeViewJSXItems/useTreeViewJSXItems.tsx similarity index 73% rename from packages/x-tree-view/src/internals/plugins/useTreeViewJSXNodes/useTreeViewJSXNodes.tsx rename to packages/x-tree-view/src/internals/plugins/useTreeViewJSXItems/useTreeViewJSXItems.tsx index 1ad50070711e4..30101b6c94519 100644 --- a/packages/x-tree-view/src/internals/plugins/useTreeViewJSXNodes/useTreeViewJSXNodes.tsx +++ b/packages/x-tree-view/src/internals/plugins/useTreeViewJSXItems/useTreeViewJSXItems.tsx @@ -3,7 +3,7 @@ import useEventCallback from '@mui/utils/useEventCallback'; import useForkRef from '@mui/utils/useForkRef'; import { TreeViewItemPlugin, TreeViewNode, TreeViewPlugin } from '../../models'; import { populateInstance } from '../../useTreeView/useTreeView.utils'; -import { UseTreeViewJSXNodesSignature } from './useTreeViewJSXNodes.types'; +import { UseTreeViewJSXItemsSignature } from './useTreeViewJSXItems.types'; import { publishTreeViewEvent } from '../../utils/publishTreeViewEvent'; import { useTreeViewContext } from '../../TreeViewProvider/useTreeViewContext'; import { @@ -14,52 +14,52 @@ import { import type { TreeItemProps } from '../../../TreeItem'; import type { TreeItem2Props } from '../../../TreeItem2'; -export const useTreeViewJSXNodes: TreeViewPlugin = ({ +export const useTreeViewJSXItems: TreeViewPlugin = ({ instance, setState, }) => { instance.preventItemUpdates(); - const insertJSXNode = useEventCallback((node: TreeViewNode) => { + const insertJSXItem = useEventCallback((item: TreeViewNode) => { setState((prevState) => { - if (prevState.nodes.nodeMap[node.id] != null) { + if (prevState.items.nodeMap[item.id] != null) { throw new Error( [ 'MUI X: The Tree View component requires all items to have a unique `id` property.', 'Alternatively, you can use the `getItemId` prop to specify a custom id for each item.', - `Tow items were provided with the same id in the \`items\` prop: "${node.id}"`, + `Tow items were provided with the same id in the \`items\` prop: "${item.id}"`, ].join('\n'), ); } return { ...prevState, - nodes: { - ...prevState.nodes, - nodeMap: { ...prevState.nodes.nodeMap, [node.id]: node }, + items: { + ...prevState.items, + nodeMap: { ...prevState.items.nodeMap, [item.id]: item }, // For `SimpleTreeView`, we don't have a proper `item` object, so we create a very basic one. - itemMap: { ...prevState.nodes.itemMap, [node.id]: { id: node.id, label: node.label } }, + itemMap: { ...prevState.items.itemMap, [item.id]: { id: item.id, label: item.label } }, }, }; }); }); - const removeJSXNode = useEventCallback((itemId: string) => { + const removeJSXItem = useEventCallback((itemId: string) => { setState((prevState) => { - const newNodeMap = { ...prevState.nodes.nodeMap }; - const newItemMap = { ...prevState.nodes.itemMap }; + const newNodeMap = { ...prevState.items.nodeMap }; + const newItemMap = { ...prevState.items.itemMap }; delete newNodeMap[itemId]; delete newItemMap[itemId]; return { ...prevState, - nodes: { - ...prevState.nodes, + items: { + ...prevState.items, nodeMap: newNodeMap, itemMap: newItemMap, }, }; }); - publishTreeViewEvent(instance, 'removeNode', { id: itemId }); + publishTreeViewEvent(instance, 'removeItem', { id: itemId }); }); const mapFirstCharFromJSX = useEventCallback((itemId: string, firstChar: string) => { @@ -77,21 +77,21 @@ export const useTreeViewJSXNodes: TreeViewPlugin = }; }); - populateInstance(instance, { - insertJSXNode, - removeJSXNode, + populateInstance(instance, { + insertJSXItem, + removeJSXItem, mapFirstCharFromJSX, }); }; -const useTreeViewJSXNodesItemPlugin: TreeViewItemPlugin = ({ +const useTreeViewJSXItemsItemPlugin: TreeViewItemPlugin = ({ props, rootRef, contentRef, }) => { const { children, disabled = false, label, itemId, id } = props; - const { instance } = useTreeViewContext<[UseTreeViewJSXNodesSignature]>(); + const { instance } = useTreeViewContext<[UseTreeViewJSXItemsSignature]>(); const isExpandable = (reactChildren: React.ReactNode) => { if (Array.isArray(reactChildren)) { @@ -119,9 +119,9 @@ const useTreeViewJSXNodesItemPlugin: TreeViewItemPlugin { - // On the first render a node's index will be -1. We want to wait for the real index. + // On the first render a item's index will be -1. We want to wait for the real index. if (index !== -1) { - instance.insertJSXNode({ + instance.insertJSXItem({ id: itemId, idAttribute: id, index, @@ -130,7 +130,7 @@ const useTreeViewJSXNodesItemPlugin: TreeViewItemPlugin instance.removeJSXNode(itemId); + return () => instance.removeJSXItem(itemId); } return undefined; @@ -152,10 +152,10 @@ const useTreeViewJSXNodesItemPlugin: TreeViewItemPlugin ( +useTreeViewJSXItems.wrapItem = ({ children, itemId }) => ( {children} ); -useTreeViewJSXNodes.params = {}; +useTreeViewJSXItems.params = {}; diff --git a/packages/x-tree-view/src/internals/plugins/useTreeViewJSXItems/useTreeViewJSXItems.types.ts b/packages/x-tree-view/src/internals/plugins/useTreeViewJSXItems/useTreeViewJSXItems.types.ts new file mode 100644 index 0000000000000..c219453ac6da3 --- /dev/null +++ b/packages/x-tree-view/src/internals/plugins/useTreeViewJSXItems/useTreeViewJSXItems.types.ts @@ -0,0 +1,20 @@ +import { TreeViewNode, TreeViewPluginSignature } from '../../models'; +import { UseTreeViewItemsSignature } from '../useTreeViewItems'; +import { UseTreeViewKeyboardNavigationSignature } from '../useTreeViewKeyboardNavigation'; + +export interface UseTreeViewItemsInstance { + insertJSXItem: (item: TreeViewNode) => void; + removeJSXItem: (itemId: string) => void; + mapFirstCharFromJSX: (itemId: string, firstChar: string) => () => void; +} + +export interface UseTreeViewItemsParameters {} + +export interface UseTreeViewItemsDefaultizedParameters {} + +export type UseTreeViewJSXItemsSignature = TreeViewPluginSignature<{ + params: UseTreeViewItemsParameters; + defaultizedParams: UseTreeViewItemsDefaultizedParameters; + instance: UseTreeViewItemsInstance; + dependantPlugins: [UseTreeViewItemsSignature, UseTreeViewKeyboardNavigationSignature]; +}>; diff --git a/packages/x-tree-view/src/internals/plugins/useTreeViewJSXNodes/index.ts b/packages/x-tree-view/src/internals/plugins/useTreeViewJSXNodes/index.ts deleted file mode 100644 index 2aeb78d6ca7a8..0000000000000 --- a/packages/x-tree-view/src/internals/plugins/useTreeViewJSXNodes/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -export { useTreeViewJSXNodes } from './useTreeViewJSXNodes'; -export type { - UseTreeViewJSXNodesSignature, - UseTreeViewNodesParameters, - UseTreeViewNodesDefaultizedParameters, -} from './useTreeViewJSXNodes.types'; diff --git a/packages/x-tree-view/src/internals/plugins/useTreeViewJSXNodes/useTreeViewJSXNodes.types.ts b/packages/x-tree-view/src/internals/plugins/useTreeViewJSXNodes/useTreeViewJSXNodes.types.ts deleted file mode 100644 index 7567e90b10c44..0000000000000 --- a/packages/x-tree-view/src/internals/plugins/useTreeViewJSXNodes/useTreeViewJSXNodes.types.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { TreeViewNode, TreeViewPluginSignature } from '../../models'; -import { UseTreeViewNodesSignature } from '../useTreeViewNodes'; -import { UseTreeViewKeyboardNavigationSignature } from '../useTreeViewKeyboardNavigation'; - -export interface UseTreeViewNodesInstance { - insertJSXNode: (node: TreeViewNode) => void; - removeJSXNode: (itemId: string) => void; - mapFirstCharFromJSX: (itemId: string, firstChar: string) => () => void; -} - -export interface UseTreeViewNodesParameters {} - -export interface UseTreeViewNodesDefaultizedParameters {} - -export type UseTreeViewJSXNodesSignature = TreeViewPluginSignature<{ - params: UseTreeViewNodesParameters; - defaultizedParams: UseTreeViewNodesDefaultizedParameters; - instance: UseTreeViewNodesInstance; - dependantPlugins: [UseTreeViewNodesSignature, UseTreeViewKeyboardNavigationSignature]; -}>; diff --git a/packages/x-tree-view/src/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.ts b/packages/x-tree-view/src/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.ts index 344cc4a5532b9..42f4878904617 100644 --- a/packages/x-tree-view/src/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.ts +++ b/packages/x-tree-view/src/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.ts @@ -3,10 +3,10 @@ import { useTheme } from '@mui/material/styles'; import useEventCallback from '@mui/utils/useEventCallback'; import { TreeViewNode, TreeViewPlugin } from '../../models'; import { - getFirstNode, - getLastNode, - getNextNode, - getPreviousNode, + getFirstItem, + getLastItem, + getNextItem, + getPreviousItem, populateInstance, } from '../../useTreeView/useTreeView.utils'; import { @@ -52,9 +52,9 @@ export const useTreeViewKeyboardNavigation: TreeViewPlugin< newFirstCharMap[node.id] = node.label!.substring(0, 1).toLowerCase(); }; - Object.values(state.nodes.nodeMap).forEach(processItem); + Object.values(state.items.nodeMap).forEach(processItem); firstCharMap.current = newFirstCharMap; - }, [state.nodes.nodeMap, params.getItemId, instance]); + }, [state.items.nodeMap, params.getItemId, instance]); const getFirstMatchingItem = (itemId: string, firstChar: string) => { let start: number; @@ -66,10 +66,10 @@ export const useTreeViewKeyboardNavigation: TreeViewPlugin< // This really only works since the ids are strings Object.keys(firstCharMap.current).forEach((mapItemId) => { const map = instance.getNode(mapItemId); - const visible = map.parentId ? instance.isNodeExpanded(map.parentId) : true; + const visible = map.parentId ? instance.isItemExpanded(map.parentId) : true; const shouldBeSkipped = params.disabledItemsFocusable ? false - : instance.isNodeDisabled(mapItemId); + : instance.isItemDisabled(mapItemId); if (visible && !shouldBeSkipped) { firstCharIds.push(mapItemId); @@ -100,10 +100,10 @@ export const useTreeViewKeyboardNavigation: TreeViewPlugin< }; const canToggleItemSelection = (itemId: string) => - !params.disableSelection && !instance.isNodeDisabled(itemId); + !params.disableSelection && !instance.isItemDisabled(itemId); const canToggleItemExpansion = (itemId: string) => { - return !instance.isNodeDisabled(itemId) && instance.isNodeExpandable(itemId); + return !instance.isItemDisabled(itemId) && instance.isItemExpandable(itemId); }; // ARIA specification: https://www.w3.org/WAI/ARIA/apg/patterns/treeview/#keyboardinteraction @@ -124,31 +124,31 @@ export const useTreeViewKeyboardNavigation: TreeViewPlugin< // eslint-disable-next-line default-case switch (true) { - // Select the node when pressing "Space" + // Select the item when pressing "Space" case key === ' ' && canToggleItemSelection(itemId): { event.preventDefault(); if (params.multiSelect && event.shiftKey) { instance.selectRange(event, { end: itemId }); } else if (params.multiSelect) { - instance.selectNode(event, itemId, true); + instance.selectItem(event, itemId, true); } else { - instance.selectNode(event, itemId); + instance.selectItem(event, itemId); } break; } - // If the focused node has children, we expand it. - // If the focused node has no children, we select it. + // If the focused item has children, we expand it. + // If the focused item has no children, we select it. case key === 'Enter': { if (canToggleItemExpansion(itemId)) { - instance.toggleNodeExpansion(event, itemId); + instance.toggleItemExpansion(event, itemId); event.preventDefault(); } else if (canToggleItemSelection(itemId)) { if (params.multiSelect) { event.preventDefault(); - instance.selectNode(event, itemId, true); - } else if (!instance.isNodeSelected(itemId)) { - instance.selectNode(event, itemId); + instance.selectItem(event, itemId, true); + } else if (!instance.isItemSelected(itemId)) { + instance.selectItem(event, itemId); event.preventDefault(); } } @@ -158,7 +158,7 @@ export const useTreeViewKeyboardNavigation: TreeViewPlugin< // Focus the next focusable item case key === 'ArrowDown': { - const nextItem = getNextNode(instance, itemId); + const nextItem = getNextItem(instance, itemId); if (nextItem) { event.preventDefault(); instance.focusItem(event, nextItem); @@ -182,7 +182,7 @@ export const useTreeViewKeyboardNavigation: TreeViewPlugin< // Focuses the previous focusable item case key === 'ArrowUp': { - const previousItem = getPreviousNode(instance, itemId); + const previousItem = getPreviousItem(instance, itemId); if (previousItem) { event.preventDefault(); instance.focusItem(event, previousItem); @@ -207,14 +207,14 @@ export const useTreeViewKeyboardNavigation: TreeViewPlugin< // If the focused item is expanded, we move the focus to its first child // If the focused item is collapsed and has children, we expand it case (key === 'ArrowRight' && !isRTL) || (key === 'ArrowLeft' && isRTL): { - if (instance.isNodeExpanded(itemId)) { - const nextNodeId = getNextNode(instance, itemId); - if (nextNodeId) { - instance.focusItem(event, nextNodeId); + if (instance.isItemExpanded(itemId)) { + const nextItemId = getNextItem(instance, itemId); + if (nextItemId) { + instance.focusItem(event, nextItemId); event.preventDefault(); } } else if (canToggleItemExpansion(itemId)) { - instance.toggleNodeExpansion(event, itemId); + instance.toggleItemExpansion(event, itemId); event.preventDefault(); } @@ -224,8 +224,8 @@ export const useTreeViewKeyboardNavigation: TreeViewPlugin< // If the focused item is expanded, we collapse it // If the focused item is collapsed and has a parent, we move the focus to this parent case (key === 'ArrowLeft' && !isRTL) || (key === 'ArrowRight' && isRTL): { - if (canToggleItemExpansion(itemId) && instance.isNodeExpanded(itemId)) { - instance.toggleNodeExpansion(event, itemId); + if (canToggleItemExpansion(itemId) && instance.isItemExpanded(itemId)) { + instance.toggleItemExpansion(event, itemId); event.preventDefault(); } else { const parent = instance.getNode(itemId).parentId; @@ -238,12 +238,12 @@ export const useTreeViewKeyboardNavigation: TreeViewPlugin< break; } - // Focuses the first node in the tree + // Focuses the first item in the tree case key === 'Home': { - instance.focusItem(event, getFirstNode(instance)); + instance.focusItem(event, getFirstItem(instance)); // Multi select behavior when pressing Ctrl + Shift + Home - // Selects the focused node and all nodes up to the first node. + // Selects the focused item and all items up to the first item. if (canToggleItemSelection(itemId) && params.multiSelect && ctrlPressed && event.shiftKey) { instance.rangeSelectToFirst(event, itemId); } @@ -254,7 +254,7 @@ export const useTreeViewKeyboardNavigation: TreeViewPlugin< // Focuses the last item in the tree case key === 'End': { - instance.focusItem(event, getLastNode(instance)); + instance.focusItem(event, getLastItem(instance)); // Multi select behavior when pressing Ctrl + Shirt + End // Selects the focused item and all the items down to the last item. @@ -274,11 +274,11 @@ export const useTreeViewKeyboardNavigation: TreeViewPlugin< } // Multi select behavior when pressing Ctrl + a - // Selects all the nodes + // Selects all the items case key === 'a' && ctrlPressed && params.multiSelect && !params.disableSelection: { instance.selectRange(event, { - start: getFirstNode(instance), - end: getLastNode(instance), + start: getFirstItem(instance), + end: getLastItem(instance), }); event.preventDefault(); break; @@ -287,9 +287,9 @@ export const useTreeViewKeyboardNavigation: TreeViewPlugin< // Type-ahead // TODO: Support typing multiple characters case !ctrlPressed && !event.shiftKey && isPrintableCharacter(key): { - const matchingNode = getFirstMatchingItem(itemId, key); - if (matchingNode != null) { - instance.focusItem(event, matchingNode); + const matchingItem = getFirstMatchingItem(itemId, key); + if (matchingItem != null) { + instance.focusItem(event, matchingItem); event.preventDefault(); } break; diff --git a/packages/x-tree-view/src/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.types.ts b/packages/x-tree-view/src/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.types.ts index 729b8a875c47f..053eeaaf43e66 100644 --- a/packages/x-tree-view/src/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.types.ts +++ b/packages/x-tree-view/src/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.types.ts @@ -1,6 +1,6 @@ import * as React from 'react'; import { TreeViewPluginSignature } from '../../models'; -import { UseTreeViewNodesSignature } from '../useTreeViewNodes'; +import { UseTreeViewItemsSignature } from '../useTreeViewItems'; import { UseTreeViewSelectionSignature } from '../useTreeViewSelection'; import { UseTreeViewFocusSignature } from '../useTreeViewFocus'; import { UseTreeViewExpansionSignature } from '../useTreeViewExpansion'; @@ -17,7 +17,7 @@ export interface UseTreeViewKeyboardNavigationInstance { export type UseTreeViewKeyboardNavigationSignature = TreeViewPluginSignature<{ instance: UseTreeViewKeyboardNavigationInstance; dependantPlugins: [ - UseTreeViewNodesSignature, + UseTreeViewItemsSignature, UseTreeViewSelectionSignature, UseTreeViewFocusSignature, UseTreeViewExpansionSignature, diff --git a/packages/x-tree-view/src/internals/plugins/useTreeViewNodes/index.ts b/packages/x-tree-view/src/internals/plugins/useTreeViewNodes/index.ts deleted file mode 100644 index 35b6c06d11a60..0000000000000 --- a/packages/x-tree-view/src/internals/plugins/useTreeViewNodes/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -export { useTreeViewNodes } from './useTreeViewNodes'; -export type { - UseTreeViewNodesSignature, - UseTreeViewNodesParameters, - UseTreeViewNodesDefaultizedParameters, -} from './useTreeViewNodes.types'; diff --git a/packages/x-tree-view/src/internals/plugins/useTreeViewSelection/useTreeViewSelection.ts b/packages/x-tree-view/src/internals/plugins/useTreeViewSelection/useTreeViewSelection.ts index c382816220cb2..28a570228c6e5 100644 --- a/packages/x-tree-view/src/internals/plugins/useTreeViewSelection/useTreeViewSelection.ts +++ b/packages/x-tree-view/src/internals/plugins/useTreeViewSelection/useTreeViewSelection.ts @@ -2,9 +2,9 @@ import * as React from 'react'; import { TreeViewPlugin, TreeViewItemRange } from '../../models'; import { populateInstance, - getNextNode, - getFirstNode, - getLastNode, + getNextItem, + getFirstItem, + getLastItem, } from '../../useTreeView/useTreeView.utils'; import { UseTreeViewSelectionSignature } from './useTreeViewSelection.types'; import { findOrderInTremauxTree } from './useTreeViewSelection.utils'; @@ -14,7 +14,7 @@ export const useTreeViewSelection: TreeViewPlugin params, models, }) => { - const lastSelectedNode = React.useRef(null); + const lastSelectedItem = React.useRef(null); const lastSelectionWasRange = React.useRef(false); const currentRangeSelection = React.useRef([]); @@ -25,7 +25,7 @@ export const useTreeViewSelection: TreeViewPlugin if (params.onItemSelectionToggle) { if (params.multiSelect) { const addedItems = (newSelectedItems as string[]).filter( - (itemId) => !instance.isNodeSelected(itemId), + (itemId) => !instance.isItemSelected(itemId), ); const removedItems = (models.selectedItems.value as string[]).filter( (itemId) => !(newSelectedItems as string[]).includes(itemId), @@ -55,12 +55,12 @@ export const useTreeViewSelection: TreeViewPlugin models.selectedItems.setControlledValue(newSelectedItems); }; - const isNodeSelected = (itemId: string) => + const isItemSelected = (itemId: string) => Array.isArray(models.selectedItems.value) ? models.selectedItems.value.indexOf(itemId) !== -1 : models.selectedItems.value === itemId; - const selectNode = (event: React.SyntheticEvent, itemId: string, multiple = false) => { + const selectItem = (event: React.SyntheticEvent, itemId: string, multiple = false) => { if (params.disableSelection) { return; } @@ -80,28 +80,28 @@ export const useTreeViewSelection: TreeViewPlugin const newSelected = params.multiSelect ? [itemId] : itemId; setSelectedItems(event, newSelected); } - lastSelectedNode.current = itemId; + lastSelectedItem.current = itemId; lastSelectionWasRange.current = false; currentRangeSelection.current = []; }; - const getNodesInRange = (nodeAId: string, nodeBId: string) => { - const [first, last] = findOrderInTremauxTree(instance, nodeAId, nodeBId); - const nodes = [first]; + const getItemsInRange = (itemAId: string, itemBId: string) => { + const [first, last] = findOrderInTremauxTree(instance, itemAId, itemBId); + const items = [first]; let current = first; while (current !== last) { - current = getNextNode(instance, current)!; - nodes.push(current); + current = getNextItem(instance, current)!; + items.push(current); } - return nodes; + return items; }; - const handleRangeArrowSelect = (event: React.SyntheticEvent, nodes: TreeViewItemRange) => { + const handleRangeArrowSelect = (event: React.SyntheticEvent, items: TreeViewItemRange) => { let base = (models.selectedItems.value as string[]).slice(); - const { start, next, current } = nodes; + const { start, next, current } = items; if (!next || !current) { return; @@ -130,29 +130,29 @@ export const useTreeViewSelection: TreeViewPlugin const handleRangeSelect = ( event: React.SyntheticEvent, - nodes: { start: string; end: string }, + items: { start: string; end: string }, ) => { let base = (models.selectedItems.value as string[]).slice(); - const { start, end } = nodes; - // If last selection was a range selection ignore nodes that were selected. + const { start, end } = items; + // If last selection was a range selection ignore items that were selected. if (lastSelectionWasRange.current) { base = base.filter((id) => currentRangeSelection.current.indexOf(id) === -1); } - let range = getNodesInRange(start, end); - range = range.filter((node) => !instance.isNodeDisabled(node)); + let range = getItemsInRange(start, end); + range = range.filter((item) => !instance.isItemDisabled(item)); currentRangeSelection.current = range; let newSelected = base.concat(range); newSelected = newSelected.filter((id, i) => newSelected.indexOf(id) === i); setSelectedItems(event, newSelected); }; - const selectRange = (event: React.SyntheticEvent, nodes: TreeViewItemRange, stacked = false) => { + const selectRange = (event: React.SyntheticEvent, items: TreeViewItemRange, stacked = false) => { if (params.disableSelection) { return; } - const { start = lastSelectedNode.current, end, current } = nodes; + const { start = lastSelectedItem.current, end, current } = items; if (stacked) { handleRangeArrowSelect(event, { start, next: end, current }); } else if (start != null && end != null) { @@ -162,34 +162,34 @@ export const useTreeViewSelection: TreeViewPlugin }; const rangeSelectToFirst = (event: React.KeyboardEvent, itemId: string) => { - if (!lastSelectedNode.current) { - lastSelectedNode.current = itemId; + if (!lastSelectedItem.current) { + lastSelectedItem.current = itemId; } - const start = lastSelectionWasRange.current ? lastSelectedNode.current : itemId; + const start = lastSelectionWasRange.current ? lastSelectedItem.current : itemId; instance.selectRange(event, { start, - end: getFirstNode(instance), + end: getFirstItem(instance), }); }; const rangeSelectToLast = (event: React.KeyboardEvent, itemId: string) => { - if (!lastSelectedNode.current) { - lastSelectedNode.current = itemId; + if (!lastSelectedItem.current) { + lastSelectedItem.current = itemId; } - const start = lastSelectionWasRange.current ? lastSelectedNode.current : itemId; + const start = lastSelectionWasRange.current ? lastSelectedItem.current : itemId; instance.selectRange(event, { start, - end: getLastNode(instance), + end: getLastItem(instance), }); }; populateInstance(instance, { - isNodeSelected, - selectNode, + isItemSelected, + selectItem, selectRange, rangeSelectToLast, rangeSelectToFirst, @@ -213,14 +213,14 @@ useTreeViewSelection.models = { }, }; -const DEFAULT_SELECTED_NODES: string[] = []; +const DEFAULT_SELECTED_ITEMS: string[] = []; useTreeViewSelection.getDefaultizedParams = (params) => ({ ...params, disableSelection: params.disableSelection ?? false, multiSelect: params.multiSelect ?? false, defaultSelectedItems: - params.defaultSelectedItems ?? (params.multiSelect ? DEFAULT_SELECTED_NODES : null), + params.defaultSelectedItems ?? (params.multiSelect ? DEFAULT_SELECTED_ITEMS : null), }); useTreeViewSelection.params = { diff --git a/packages/x-tree-view/src/internals/plugins/useTreeViewSelection/useTreeViewSelection.types.ts b/packages/x-tree-view/src/internals/plugins/useTreeViewSelection/useTreeViewSelection.types.ts index 37d6324909cee..474a7b8f82e44 100644 --- a/packages/x-tree-view/src/internals/plugins/useTreeViewSelection/useTreeViewSelection.types.ts +++ b/packages/x-tree-view/src/internals/plugins/useTreeViewSelection/useTreeViewSelection.types.ts @@ -1,12 +1,12 @@ import * as React from 'react'; import type { DefaultizedProps, TreeViewItemRange, TreeViewPluginSignature } from '../../models'; -import { UseTreeViewNodesSignature } from '../useTreeViewNodes'; +import { UseTreeViewItemsSignature } from '../useTreeViewItems'; import { UseTreeViewExpansionSignature } from '../useTreeViewExpansion'; export interface UseTreeViewSelectionInstance { - isNodeSelected: (itemId: string) => boolean; - selectNode: (event: React.SyntheticEvent, itemId: string, multiple?: boolean) => void; - selectRange: (event: React.SyntheticEvent, nodes: TreeViewItemRange, stacked?: boolean) => void; + isItemSelected: (itemId: string) => boolean; + selectItem: (event: React.SyntheticEvent, itemId: string, multiple?: boolean) => void; + selectRange: (event: React.SyntheticEvent, items: TreeViewItemRange, stacked?: boolean) => void; rangeSelectToFirst: (event: React.KeyboardEvent, itemId: string) => void; rangeSelectToLast: (event: React.KeyboardEvent, itemId: string) => void; } @@ -76,8 +76,8 @@ export type UseTreeViewSelectionSignature = TreeViewPluginSignature<{ contextValue: UseTreeViewSelectionContextValue; modelNames: 'selectedItems'; dependantPlugins: [ - UseTreeViewNodesSignature, + UseTreeViewItemsSignature, UseTreeViewExpansionSignature, - UseTreeViewNodesSignature, + UseTreeViewItemsSignature, ]; }>; diff --git a/packages/x-tree-view/src/internals/plugins/useTreeViewSelection/useTreeViewSelection.utils.ts b/packages/x-tree-view/src/internals/plugins/useTreeViewSelection/useTreeViewSelection.utils.ts index 7bfd556d6ba98..48553f5c6471b 100644 --- a/packages/x-tree-view/src/internals/plugins/useTreeViewSelection/useTreeViewSelection.utils.ts +++ b/packages/x-tree-view/src/internals/plugins/useTreeViewSelection/useTreeViewSelection.utils.ts @@ -1,22 +1,22 @@ import { TreeViewInstance } from '../../models'; -import { UseTreeViewNodesSignature } from '../useTreeViewNodes'; +import { UseTreeViewItemsSignature } from '../useTreeViewItems'; /** * This is used to determine the start and end of a selection range so - * we can get the nodes between the two border nodes. + * we can get the items between the two border items. * - * It finds the nodes' common ancestor using + * It finds the items' common ancestor using * a naive implementation of a lowest common ancestor algorithm * (https://en.wikipedia.org/wiki/Lowest_common_ancestor). - * Then compares the ancestor's 2 children that are ancestors of nodeA and NodeB - * so we can compare their indexes to work out which node comes first in a depth first search. + * Then compares the ancestor's 2 children that are ancestors of itemA and ItemB + * so we can compare their indexes to work out which item comes first in a depth first search. * (https://en.wikipedia.org/wiki/Depth-first_search) * - * Another way to put it is which node is shallower in a trémaux tree + * Another way to put it is which item is shallower in a trémaux tree * https://en.wikipedia.org/wiki/Tr%C3%A9maux_tree */ export const findOrderInTremauxTree = ( - instance: TreeViewInstance<[UseTreeViewNodesSignature]>, + instance: TreeViewInstance<[UseTreeViewItemsSignature]>, nodeAId: string, nodeBId: string, ) => { diff --git a/packages/x-tree-view/src/internals/useTreeView/useTreeView.utils.ts b/packages/x-tree-view/src/internals/useTreeView/useTreeView.utils.ts index 6e374cb568bb5..8e8bffed2986c 100644 --- a/packages/x-tree-view/src/internals/useTreeView/useTreeView.utils.ts +++ b/packages/x-tree-view/src/internals/useTreeView/useTreeView.utils.ts @@ -5,23 +5,23 @@ import { TreeViewUsedPublicAPI, } from '../models'; import type { UseTreeViewExpansionSignature } from '../plugins/useTreeViewExpansion'; -import type { UseTreeViewNodesSignature } from '../plugins/useTreeViewNodes'; +import type { UseTreeViewItemsSignature } from '../plugins/useTreeViewItems'; -export const getPreviousNode = ( - instance: TreeViewInstance<[UseTreeViewNodesSignature, UseTreeViewExpansionSignature]>, +export const getPreviousItem = ( + instance: TreeViewInstance<[UseTreeViewItemsSignature, UseTreeViewExpansionSignature]>, itemId: string, ) => { - const item = instance.getNode(itemId); - const siblings = instance.getNavigableChildrenIds(item.parentId); + const node = instance.getNode(itemId); + const siblings = instance.getNavigableChildrenIds(node.parentId); const itemIndex = siblings.indexOf(itemId); if (itemIndex === 0) { - return item.parentId; + return node.parentId; } let currentItem: string = siblings[itemIndex - 1]; while ( - instance.isNodeExpanded(currentItem) && + instance.isItemExpanded(currentItem) && instance.getNavigableChildrenIds(currentItem).length > 0 ) { currentItem = instance.getNavigableChildrenIds(currentItem).pop()!; @@ -30,44 +30,44 @@ export const getPreviousNode = ( return currentItem; }; -export const getNextNode = ( - instance: TreeViewInstance<[UseTreeViewExpansionSignature, UseTreeViewNodesSignature]>, +export const getNextItem = ( + instance: TreeViewInstance<[UseTreeViewExpansionSignature, UseTreeViewItemsSignature]>, itemId: string, ) => { // If expanded get first child - if (instance.isNodeExpanded(itemId) && instance.getNavigableChildrenIds(itemId).length > 0) { + if (instance.isItemExpanded(itemId) && instance.getNavigableChildrenIds(itemId).length > 0) { return instance.getNavigableChildrenIds(itemId)[0]; } - let item = instance.getNode(itemId); - while (item != null) { + let node = instance.getNode(itemId); + while (node != null) { // Try to get next sibling - const siblings = instance.getNavigableChildrenIds(item.parentId); - const nextSibling = siblings[siblings.indexOf(item.id) + 1]; + const siblings = instance.getNavigableChildrenIds(node.parentId); + const nextSibling = siblings[siblings.indexOf(node.id) + 1]; if (nextSibling) { return nextSibling; } // If the sibling does not exist, go up a level to the parent and try again. - item = instance.getNode(item.parentId!); + node = instance.getNode(node.parentId!); } return null; }; -export const getLastNode = ( - instance: TreeViewInstance<[UseTreeViewExpansionSignature, UseTreeViewNodesSignature]>, +export const getLastItem = ( + instance: TreeViewInstance<[UseTreeViewExpansionSignature, UseTreeViewItemsSignature]>, ) => { let lastItem = instance.getNavigableChildrenIds(null).pop()!; - while (instance.isNodeExpanded(lastItem)) { + while (instance.isItemExpanded(lastItem)) { lastItem = instance.getNavigableChildrenIds(lastItem).pop()!; } return lastItem; }; -export const getFirstNode = (instance: TreeViewInstance<[UseTreeViewNodesSignature]>) => +export const getFirstItem = (instance: TreeViewInstance<[UseTreeViewItemsSignature]>) => instance.getNavigableChildrenIds(null)[0]; export const populateInstance = ( From 3341a1ac6c2383d79aeb54ad1d383865798070ee Mon Sep 17 00:00:00 2001 From: Flavien DELANGLE Date: Thu, 28 Mar 2024 11:46:45 +0100 Subject: [PATCH 27/55] [fields] Fix placeholder override (#12589) --- .../tests/field.DesktopDatePicker.test.tsx | 53 +++++++++++++++++++ .../hooks/useField/useField.types.ts | 1 + .../hooks/useField/useFieldV6TextField.ts | 36 +++++++++---- 3 files changed, 80 insertions(+), 10 deletions(-) diff --git a/packages/x-date-pickers/src/DesktopDatePicker/tests/field.DesktopDatePicker.test.tsx b/packages/x-date-pickers/src/DesktopDatePicker/tests/field.DesktopDatePicker.test.tsx index 44097f0832b19..e485c71da98f0 100644 --- a/packages/x-date-pickers/src/DesktopDatePicker/tests/field.DesktopDatePicker.test.tsx +++ b/packages/x-date-pickers/src/DesktopDatePicker/tests/field.DesktopDatePicker.test.tsx @@ -100,6 +100,59 @@ describe(' - Field', () => { }); }); + describe('slots: field', () => { + const { render, clock } = createPickerRenderer({ + clock: 'fake', + clockConfig: new Date('2018-01-01T10:05:05.000'), + }); + const { renderWithProps } = buildFieldInteractions({ + clock, + render, + Component: DesktopDatePicker, + }); + + it('should allow to override the placeholder (v6 only)', () => { + renderWithProps({ + enableAccessibleFieldDOMStructure: false, + slotProps: { + field: { + // @ts-ignore + placeholder: 'Custom placeholder', + }, + }, + }); + + const input = getTextbox(); + expectFieldPlaceholderV6(input, 'Custom placeholder'); + }); + }); + + describe('slots: textField', () => { + const { render, clock } = createPickerRenderer({ + clock: 'fake', + clockConfig: new Date('2018-01-01T10:05:05.000'), + }); + const { renderWithProps } = buildFieldInteractions({ + clock, + render, + Component: DesktopDatePicker, + }); + + it('should allow to override the placeholder (v6 only)', () => { + renderWithProps({ + enableAccessibleFieldDOMStructure: false, + slotProps: { + textField: { + placeholder: 'Custom placeholder', + }, + }, + }); + + const input = getTextbox(); + expectFieldPlaceholderV6(input, 'Custom placeholder'); + }); + }); + describeAdapters('Timezone', DesktopDatePicker, ({ adapter, renderWithProps }) => { it('should clear the selected section when all sections are completed when using timezones', () => { const v7Response = renderWithProps( diff --git a/packages/x-date-pickers/src/internals/hooks/useField/useField.types.ts b/packages/x-date-pickers/src/internals/hooks/useField/useField.types.ts index 4d82ca28b4ad3..d60d89b6efc0d 100644 --- a/packages/x-date-pickers/src/internals/hooks/useField/useField.types.ts +++ b/packages/x-date-pickers/src/internals/hooks/useField/useField.types.ts @@ -170,6 +170,7 @@ export interface UseFieldV6ForwardedProps { onClick?: React.MouseEventHandler; onFocus?: () => void; onPaste?: React.ClipboardEventHandler; + placeholder?: string; } interface UseFieldV6AdditionalProps diff --git a/packages/x-date-pickers/src/internals/hooks/useField/useFieldV6TextField.ts b/packages/x-date-pickers/src/internals/hooks/useField/useFieldV6TextField.ts index 6c666fa22dddb..4f8c89d11f415 100644 --- a/packages/x-date-pickers/src/internals/hooks/useField/useFieldV6TextField.ts +++ b/packages/x-date-pickers/src/internals/hooks/useField/useFieldV6TextField.ts @@ -80,7 +80,14 @@ export const useFieldV6TextField: UseFieldTextField = (params) => { const focusTimeoutRef = React.useRef>(); const { - forwardedProps: { onFocus, onClick, onPaste, onBlur, inputRef: inputRefProp }, + forwardedProps: { + onFocus, + onClick, + onPaste, + onBlur, + inputRef: inputRefProp, + placeholder: inPlaceholder, + }, internalProps: { readOnly = false }, parsedSelectedSections, activeSectionIndex, @@ -381,15 +388,24 @@ export const useFieldV6TextField: UseFieldTextField = (params) => { applyCharacterEditing({ keyPressed, sectionIndex: activeSectionIndex }); }); - const placeholder = React.useMemo( - () => - fieldValueManager.getV6InputValueFromSections( - getSectionsFromValue(valueManager.emptyValue), - localizedDigits, - isRTL, - ), - [fieldValueManager, getSectionsFromValue, valueManager.emptyValue, localizedDigits, isRTL], - ); + const placeholder = React.useMemo(() => { + if (inPlaceholder) { + return inPlaceholder; + } + + return fieldValueManager.getV6InputValueFromSections( + getSectionsFromValue(valueManager.emptyValue), + localizedDigits, + isRTL, + ); + }, [ + inPlaceholder, + fieldValueManager, + getSectionsFromValue, + valueManager.emptyValue, + localizedDigits, + isRTL, + ]); const valueStr = React.useMemo( () => From 2a405a8df6d6843c42ebd22c2df23088efd51e64 Mon Sep 17 00:00:00 2001 From: Lukas Date: Thu, 28 Mar 2024 16:12:20 +0200 Subject: [PATCH 28/55] [DateRangePicker] Fix selection behavior with single input field when readonly (#12593) --- .../tests/DesktopDateRangePicker.test.tsx | 29 ++++++++++++ .../hooks/useEnrichedRangePickerFieldProps.ts | 2 +- .../hooks/useField/useFieldV6TextField.ts | 1 - ...ReadonlyDesktopDateRangePickerSingleV6.tsx | 16 +++++++ ...ReadonlyDesktopDateRangePickerSingleV7.tsx | 17 +++++++ test/e2e/index.test.ts | 46 +++++++++++++++++++ 6 files changed, 109 insertions(+), 2 deletions(-) create mode 100644 test/e2e/fixtures/DatePicker/ReadonlyDesktopDateRangePickerSingleV6.tsx create mode 100644 test/e2e/fixtures/DatePicker/ReadonlyDesktopDateRangePickerSingleV7.tsx diff --git a/packages/x-date-pickers-pro/src/DesktopDateRangePicker/tests/DesktopDateRangePicker.test.tsx b/packages/x-date-pickers-pro/src/DesktopDateRangePicker/tests/DesktopDateRangePicker.test.tsx index d0238aae4a5eb..0fef25da00a60 100644 --- a/packages/x-date-pickers-pro/src/DesktopDateRangePicker/tests/DesktopDateRangePicker.test.tsx +++ b/packages/x-date-pickers-pro/src/DesktopDateRangePicker/tests/DesktopDateRangePicker.test.tsx @@ -5,12 +5,14 @@ import { screen, fireEvent, userEvent, act, getByRole } from '@mui-internal/test import { createTheme, ThemeProvider } from '@mui/material/styles'; import { DesktopDateRangePicker } from '@mui/x-date-pickers-pro/DesktopDateRangePicker'; import { DateRange, LocalizationProvider } from '@mui/x-date-pickers-pro'; +import { SingleInputDateRangeField } from '@mui/x-date-pickers-pro/SingleInputDateRangeField'; import { createPickerRenderer, adapterToUse, AdapterClassToUse, openPicker, getFieldSectionsContainer, + getTextbox, } from 'test/utils/pickers'; const isJSDOM = /jsdom/.test(window.navigator.userAgent); @@ -87,6 +89,33 @@ describe('', () => { expect(screen.queryByText('Fim')).not.to.equal(null); }); + describe('Field slot: SingleInputDateRangeField', () => { + it('should add focused class to the field when it is focused', () => { + // test v7 behavior + const response = render( + , + ); + + const sectionsContainer = getFieldSectionsContainer(); + act(() => sectionsContainer.focus()); + + expect(sectionsContainer.parentElement).to.have.class('Mui-focused'); + + response.unmount(); + + // test v6 behavior + render(); + + const input = getTextbox(); + act(() => input.focus()); + + expect(input.parentElement).to.have.class('Mui-focused'); + }); + }); + describe('Component slot: Popper', () => { it('should forward onClick and onTouchStart', () => { const handleClick = spy(); 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 cba1ca9319b0c..c9f7d22249b06 100644 --- a/packages/x-date-pickers-pro/src/internals/hooks/useEnrichedRangePickerFieldProps.ts +++ b/packages/x-date-pickers-pro/src/internals/hooks/useEnrichedRangePickerFieldProps.ts @@ -431,7 +431,7 @@ const useSingleInputFieldSlotProps = < ref: anchorRef, ...fieldProps?.InputProps, }, - focused: open, + focused: open ? true : undefined, ...(labelId != null && { id: labelId }), ...(wrapperVariant === 'mobile' && { readOnly: true }), // registering `onClick` listener on the root element as well to correctly handle cases where user is clicking on `label` diff --git a/packages/x-date-pickers/src/internals/hooks/useField/useFieldV6TextField.ts b/packages/x-date-pickers/src/internals/hooks/useField/useFieldV6TextField.ts index 4f8c89d11f415..5547dc9a047ad 100644 --- a/packages/x-date-pickers/src/internals/hooks/useField/useFieldV6TextField.ts +++ b/packages/x-date-pickers/src/internals/hooks/useField/useFieldV6TextField.ts @@ -196,7 +196,6 @@ export const useFieldV6TextField: UseFieldTextField = (params) => { const syncSelectionFromDOM = () => { if (readOnly) { - setSelectedSections(null); return; } const browserStartIndex = inputRef.current!.selectionStart ?? 0; diff --git a/test/e2e/fixtures/DatePicker/ReadonlyDesktopDateRangePickerSingleV6.tsx b/test/e2e/fixtures/DatePicker/ReadonlyDesktopDateRangePickerSingleV6.tsx new file mode 100644 index 0000000000000..816f5326c3780 --- /dev/null +++ b/test/e2e/fixtures/DatePicker/ReadonlyDesktopDateRangePickerSingleV6.tsx @@ -0,0 +1,16 @@ +import * as React from 'react'; +import { DateRangePicker } from '@mui/x-date-pickers-pro/DateRangePicker'; +import { SingleInputDateRangeField } from '@mui/x-date-pickers-pro/SingleInputDateRangeField'; +import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; +import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; + +export default function ReadonlyDesktopDateRangePickerSingleV6() { + return ( + + + + ); +} diff --git a/test/e2e/fixtures/DatePicker/ReadonlyDesktopDateRangePickerSingleV7.tsx b/test/e2e/fixtures/DatePicker/ReadonlyDesktopDateRangePickerSingleV7.tsx new file mode 100644 index 0000000000000..7666930168004 --- /dev/null +++ b/test/e2e/fixtures/DatePicker/ReadonlyDesktopDateRangePickerSingleV7.tsx @@ -0,0 +1,17 @@ +import * as React from 'react'; +import { DateRangePicker } from '@mui/x-date-pickers-pro/DateRangePicker'; +import { SingleInputDateRangeField } from '@mui/x-date-pickers-pro/SingleInputDateRangeField'; +import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; +import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; + +export default function ReadonlyDesktopDateRangePickerSingleV7() { + return ( + + + + ); +} diff --git a/test/e2e/index.test.ts b/test/e2e/index.test.ts index 5da95c6441d98..97357460b8670 100644 --- a/test/e2e/index.test.ts +++ b/test/e2e/index.test.ts @@ -803,6 +803,52 @@ async function initializeEnvironment( await page.waitForSelector('[role="tooltip"]', { state: 'detached' }); }); + + it('should have the same selection process when "readOnly" with single input v7 field', async () => { + // firefox in CI is not happy with this test + if (browserType.name() === 'firefox') { + return; + } + + await renderFixture('DatePicker/ReadonlyDesktopDateRangePickerSingleV7'); + + await page.locator(`.${pickersSectionListClasses.root}`).first().click(); + + // assert that the tooltip has been opened + await page.waitForSelector('[role="tooltip"]', { state: 'attached' }); + + await page.getByRole('gridcell', { name: '11' }).first().click(); + await page.getByRole('gridcell', { name: '13' }).first().click(); + + // assert that the tooltip closes after selection is complete + await page.waitForSelector('[role="tooltip"]', { state: 'detached' }); + + expect(await page.getByRole('textbox', { includeHidden: true }).inputValue()).to.equal( + '04/11/2022 – 04/13/2022', + ); + }); + + it('should have the same selection process when "readOnly" with single input v6 field', async () => { + // firefox in CI is not happy with this test + if (browserType.name() === 'firefox') { + return; + } + + await renderFixture('DatePicker/ReadonlyDesktopDateRangePickerSingleV6'); + + await page.getByRole('textbox').click(); + + // assert that the tooltip has been opened + await page.waitForSelector('[role="tooltip"]', { state: 'attached' }); + + await page.getByRole('gridcell', { name: '11' }).first().click(); + await page.getByRole('gridcell', { name: '13' }).first().click(); + + // assert that the tooltip closes after selection is complete + await page.waitForSelector('[role="tooltip"]', { state: 'detached' }); + + expect(await page.getByRole('textbox').inputValue()).to.equal('04/11/2022 – 04/13/2022'); + }); }); }); }); From 774ef0f98b5e2b74499a63aad879efbafd52c372 Mon Sep 17 00:00:00 2001 From: Bilal Shafi Date: Thu, 28 Mar 2024 19:39:07 +0500 Subject: [PATCH 29/55] [docs] Improve codemod related documentation (#12582) --- .../migration-data-grid-v6.md | 6 ++-- .../migration-pickers-v6.md | 8 +++-- packages/x-codemod/README.md | 34 +++++++++---------- 3 files changed, 26 insertions(+), 22 deletions(-) diff --git a/docs/data/migration/migration-data-grid-v6/migration-data-grid-v6.md b/docs/data/migration/migration-data-grid-v6/migration-data-grid-v6.md index 3ed538523b733..30679a6217f12 100644 --- a/docs/data/migration/migration-data-grid-v6/migration-data-grid-v6.md +++ b/docs/data/migration/migration-data-grid-v6/migration-data-grid-v6.md @@ -57,12 +57,14 @@ You can run `v7.0.0/data-grid/preset-safe` targeting only Data Grid or `v7.0.0/p You can either run it on a specific file, folder, or your entire codebase when choosing the `` argument. + + ```bash // Data Grid specific -npx @mui/x-codemod v7.0.0/data-grid/preset-safe +npx @mui/x-codemod@latest v7.0.0/data-grid/preset-safe // Target other MUI X components as well -npx @mui/x-codemod v7.0.0/preset-safe +npx @mui/x-codemod@latest v7.0.0/preset-safe ``` :::info diff --git a/docs/data/migration/migration-pickers-v6/migration-pickers-v6.md b/docs/data/migration/migration-pickers-v6/migration-pickers-v6.md index 456e79dc53d48..035c24bfb82f5 100644 --- a/docs/data/migration/migration-pickers-v6/migration-pickers-v6.md +++ b/docs/data/migration/migration-pickers-v6/migration-pickers-v6.md @@ -52,12 +52,14 @@ The `preset-safe` codemod will automatically adjust the bulk of your code to acc You can either run it on a specific file, folder, or your entire codebase when choosing the `` argument. + + ```bash // Date and Time Pickers specific -npx @mui/x-codemod v7.0.0/pickers/preset-safe +npx @mui/x-codemod@latest v7.0.0/pickers/preset-safe // Target Data Grid as well -npx @mui/x-codemod v7.0.0/preset-safe +npx @mui/x-codemod@latest v7.0.0/preset-safe ``` :::info @@ -105,7 +107,7 @@ And are removed from the v7. If not already done, this modification can be handled by the codemod ```bash -npx @mui/x-codemod v7.0.0/pickers/ +npx @mui/x-codemod@latest v7.0.0/pickers/ ``` Take a look at [the RFC](https://github.com/mui/material-ui/issues/33416) for more information. diff --git a/packages/x-codemod/README.md b/packages/x-codemod/README.md index 3a9ac6e08276c..5b9c53d476d44 100644 --- a/packages/x-codemod/README.md +++ b/packages/x-codemod/README.md @@ -13,7 +13,7 @@ This repository contains a collection of codemod scripts based for use with ```bash -npx @mui/x-codemod +npx @mui/x-codemod@latest Applies a `@mui/x-codemod` to the specified paths @@ -29,8 +29,8 @@ Options: --jscodeshift Pass options directly to jscodeshift [array] Examples: - npx @mui/x-codemod v6.0.0/preset-safe src - npx @mui/x-codemod v6.0.0/component-rename-prop src -- + npx @mui/x-codemod@latest v7.0.0/preset-safe src + npx @mui/x-codemod@latest v6.0.0/component-rename-prop src -- --component=DataGrid --from=prop --to=newProp ``` @@ -40,9 +40,9 @@ To pass more options directly to jscodeshift, use `--jscodeshift=...`. For examp ```bash // single option -npx @mui/x-codemod --jscodeshift=--run-in-band +npx @mui/x-codemod@latest --jscodeshift=--run-in-band // multiple options -npx @mui/x-codemod --jscodeshift=--cpus=1 --jscodeshift=--print --jscodeshift=--dry --jscodeshift=--verbose=2 +npx @mui/x-codemod@latest --jscodeshift=--cpus=1 --jscodeshift=--print --jscodeshift=--dry --jscodeshift=--verbose=2 ``` See all available options [here](https://github.com/facebook/jscodeshift#usage-cli). @@ -53,7 +53,7 @@ Options to [recast](https://github.com/benjamn/recast)'s printer can be provided through jscodeshift's `printOptions` command line argument ```bash -npx @mui/x-codemod --jscodeshift="--printOptions='{\"quote\":\"double\"}'" +npx @mui/x-codemod@latest --jscodeshift="--printOptions='{\"quote\":\"double\"}'" ``` ## v7.0.0 @@ -66,7 +66,7 @@ It runs codemods for both Data Grid and Date and Time Pickers packages. To run codemods for a specific package, refer to the respective section. ```bash -npx @mui/x-codemod v7.0.0/preset-safe +npx @mui/x-codemod@latest v7.0.0/preset-safe ``` The corresponding sub-sections are listed below @@ -82,7 +82,7 @@ The corresponding sub-sections are listed below The `preset-safe` codemods for pickers. ```bash -npx @mui/x-codemod v7.0.0/pickers/preset-safe +npx @mui/x-codemod@latest v7.0.0/pickers/preset-safe ``` The list includes these transformers @@ -108,7 +108,7 @@ This change only affects Date and Time Picker components. ``` ```bash -npx @mui/x-codemod v7.0.0/pickers/rename-components-to-slots +npx @mui/x-codemod@latest v7.0.0/pickers/rename-components-to-slots ``` #### `rename-default-calendar-month-to-reference-date` @@ -121,7 +121,7 @@ Replace the `defaultCalendarMonth` prop with the `referenceDate` prop. ``` ```bash -npx @mui/x-codemod v7.0.0/pickers/rename-default-calendar-month-to-reference-date +npx @mui/x-codemod@latest v7.0.0/pickers/rename-default-calendar-month-to-reference-date ``` #### `rename-day-picker-classes` @@ -134,7 +134,7 @@ Rename the `dayPickerClasses` variable to `dayCalendarClasses`. ``` ```bash -npx @mui/x-codemod v7.0.0/pickers/rename-day-picker-classes +npx @mui/x-codemod@latest v7.0.0/pickers/rename-day-picker-classes ``` #### `rename-slots-types` @@ -149,7 +149,7 @@ Replace types suffix `SlotsComponent` by `Slots` and `SlotsComponentsProps` by ` ``` ```bash -npx @mui/x-codemod v7.0.0/pickers/rename-slots-types +npx @mui/x-codemod@latest v7.0.0/pickers/rename-slots-types ``` ### Data Grid codemods @@ -159,7 +159,7 @@ npx @mui/x-codemod v7.0.0/pickers/rename-slots-types The `preset-safe` codemods for data grid. ```bash -npx @mui/x-codemod v7.0.0/data-grid/preset-safe +npx @mui/x-codemod@latest v7.0.0/data-grid/preset-safe ``` The list includes these transformers @@ -184,7 +184,7 @@ This change only affects Data Grid components. ``` ```bash -npx @mui/x-codemod v7.0.0/data-grid/rename-components-to-slots +npx @mui/x-codemod@latest v7.0.0/data-grid/rename-components-to-slots ``` #### `rename-cell-selection-props` @@ -203,7 +203,7 @@ Rename props related to `cellSelection` feature. ``` ```bash -npx @mui/x-codemod v7.0.0/data-grid/rename-cell-selection-props +npx @mui/x-codemod@latest v7.0.0/data-grid/rename-cell-selection-props ``` #### `remove-stabilized-v7-experimentalFeatures` @@ -222,7 +222,7 @@ Remove feature flags for stabilized `experimentalFeatures`. ``` ```bash -npx @mui/x-codemod@next v7.0.0/data-grid/remove-stabilized-experimentalFeatures +npx @mui/x-codemod@latest v7.0.0/data-grid/remove-stabilized-experimentalFeatures ``` ### Tree View codemods @@ -232,7 +232,7 @@ npx @mui/x-codemod@next v7.0.0/data-grid/remove-stabilized-experimentalFeatures The `preset-safe` codemods for tree view. ```bash -npx @mui/x-codemod v7.0.0/tree-view/preset-safe +npx @mui/x-codemod@latest v7.0.0/tree-view/preset-safe ``` The list includes these transformers From 91c4e2c7fa498d4fbb5f33f42fbeca6aeb107b62 Mon Sep 17 00:00:00 2001 From: Michel Engelen <32863416+michelengelen@users.noreply.github.com> Date: Thu, 28 Mar 2024 17:05:32 +0100 Subject: [PATCH 30/55] v7.1.0 (#12588) Signed-off-by: Michel Engelen <32863416+michelengelen@users.noreply.github.com> Co-authored-by: Flavien DELANGLE Co-authored-by: Lukas Co-authored-by: Bilal Shafi --- CHANGELOG.md | 71 +++++++++++++++++++++ package.json | 2 +- packages/x-charts/package.json | 2 +- packages/x-data-grid-generator/package.json | 2 +- packages/x-data-grid-premium/package.json | 6 +- packages/x-data-grid-pro/package.json | 4 +- packages/x-data-grid/package.json | 2 +- packages/x-date-pickers-pro/package.json | 4 +- packages/x-date-pickers/package.json | 2 +- packages/x-tree-view/package.json | 2 +- 10 files changed, 84 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e885ff6e1e0f2..20431eaeb0da0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,77 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## 7.1.0 + +_Mar 28, 2024_ + +We'd like to offer a big thanks to the 10 contributors who made this release possible. Here are some highlights ✨: + +- 🚀 Add `resizeThrottleMs` prop (#12556) @romgrk +- 🌍 Improve Chinese (Hong Kong) (zh-HK) and Italian (it-IT) locale on the Pickers +- 🐞 Bugfixes +- 📚 Documentation improvements + +### Data Grid + +#### `@mui/x-data-grid@7.1.0` + +- [DataGrid] Add `resizeThrottleMs` prop (#12556) @romgrk +- [DataGrid] Do not publish `rowEditStop` event if row has fields with errors (#11383) @cherniavskii +- [DataGrid] Fix bug in suspense (#12553) @romgrk +- [DataGrid] Fix missing class name in the `GridToolbarQuickFilter` component (#12484) @jhawkins11 + +#### `@mui/x-data-grid-pro@7.1.0` [![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.1.0`. + +#### `@mui/x-data-grid-premium@7.1.0` [![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.1.0`. + +### Date and Time Pickers + +#### `@mui/x-date-pickers@7.1.0` + +- [fields] Fix placeholder override (#12589) @flaviendelangle +- [l10n] Improve Chinese (Hong Kong) (zh-HK) locale (#12547) @samchiu90 +- [l10n] Improve Italian (it-IT) locale (#12549) @antomanc +- [pickers] Prepare compatibility with `@mui/zero-runtime` (stop using `ownerState` in `styled`) (#12003) @flaviendelangle + +#### `@mui/x-date-pickers-pro@7.1.0` [![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.1.0`, plus: + +- [DateRangePicker] Fix selection behavior with single input field when `readOnly` (#12593) @LukasTy + +### Charts + +#### `@mui/x-charts@7.1.0` + +- [charts] Fix tooltip causing crash on data change (#12571) @Rishi556 + +### Tree View + +#### `@mui/x-tree-view@7.1.0` + +- [TreeView] Do not use outdated version of the state to compute new label first char in `RichTreeView` (#12512) @flaviendelangle + +### Docs + +- [docs] Add example to add a second icon next to the field's opening button (#12524) @flaviendelangle +- [docs] Add missing note to Data Grid migration guide (#12557) @romgrk +- [docs] Fix Charts title for SEO (#12545) @oliviertassinari +- [docs] Fix small typo (#12558) @diogoparente +- [docs] Improve codemod related documentation (#12582) @MBilalShafi +- [docs] Reduce noise in migration docs side navigation (#12552) @cherniavskii +- [docs] Sync static images from core repository (#12525) @LukasTy + +### Core + +- [core] Fix `l10n` script on Windows (#12550) @LukasTy +- [core] Include `DateTimeRangePicker` tag in `releaseChangelog` (#12526) @LukasTy +- [core] Upgrade monorepo (#12536) @cherniavskii + ## v7.0.0 _Mar 22, 2024_ diff --git a/package.json b/package.json index e0d3d46d991bc..59865fcf1ee8b 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "version": "7.0.0", + "version": "7.1.0", "private": true, "scripts": { "start": "yarn && yarn docs:dev", diff --git a/packages/x-charts/package.json b/packages/x-charts/package.json index 0dac51e3288b8..10834c1fb58b9 100644 --- a/packages/x-charts/package.json +++ b/packages/x-charts/package.json @@ -1,6 +1,6 @@ { "name": "@mui/x-charts", - "version": "7.0.0", + "version": "7.1.0", "description": "The community edition of the charts components (MUI X).", "author": "MUI Team", "main": "./src/index.js", diff --git a/packages/x-data-grid-generator/package.json b/packages/x-data-grid-generator/package.json index 0d1d90500c688..b08bfd399600d 100644 --- a/packages/x-data-grid-generator/package.json +++ b/packages/x-data-grid-generator/package.json @@ -34,7 +34,7 @@ "dependencies": { "@babel/runtime": "^7.24.0", "@mui/base": "^5.0.0-beta.40", - "@mui/x-data-grid-premium": "7.0.0", + "@mui/x-data-grid-premium": "7.1.0", "chance": "^1.1.11", "clsx": "^2.1.0", "lru-cache": "^7.18.3" diff --git a/packages/x-data-grid-premium/package.json b/packages/x-data-grid-premium/package.json index 48ebefe940c26..2885218e39a56 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": "7.0.0", + "version": "7.1.0", "description": "The Premium plan edition of the data grid component (MUI X).", "author": "MUI Team", "main": "src/index.ts", @@ -45,8 +45,8 @@ "@babel/runtime": "^7.24.0", "@mui/system": "^5.15.14", "@mui/utils": "^5.15.14", - "@mui/x-data-grid": "7.0.0", - "@mui/x-data-grid-pro": "7.0.0", + "@mui/x-data-grid": "7.1.0", + "@mui/x-data-grid-pro": "7.1.0", "@mui/x-license": "7.0.0", "@types/format-util": "^1.0.4", "clsx": "^2.1.0", diff --git a/packages/x-data-grid-pro/package.json b/packages/x-data-grid-pro/package.json index 24b27a4ebb194..0fca8b43f4c4a 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": "7.0.0", + "version": "7.1.0", "description": "The Pro plan edition of the data grid component (MUI X).", "author": "MUI Team", "main": "src/index.ts", @@ -45,7 +45,7 @@ "@babel/runtime": "^7.24.0", "@mui/system": "^5.15.14", "@mui/utils": "^5.15.14", - "@mui/x-data-grid": "7.0.0", + "@mui/x-data-grid": "7.1.0", "@mui/x-license": "7.0.0", "@types/format-util": "^1.0.4", "clsx": "^2.1.0", diff --git a/packages/x-data-grid/package.json b/packages/x-data-grid/package.json index 00b3f3c8a3d85..6dac6546e6662 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": "7.0.0", + "version": "7.1.0", "description": "The community edition of the data grid component (MUI X).", "author": "MUI Team", "main": "src/index.ts", diff --git a/packages/x-date-pickers-pro/package.json b/packages/x-date-pickers-pro/package.json index effd9cda07e0f..e3a1e0c951960 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": "7.0.0", + "version": "7.1.0", "description": "The commercial edition of the date picker components (MUI X).", "author": "MUI Team", "main": "src/index.ts", @@ -45,7 +45,7 @@ "@mui/base": "^5.0.0-beta.40", "@mui/system": "^5.15.14", "@mui/utils": "^5.15.14", - "@mui/x-date-pickers": "7.0.0", + "@mui/x-date-pickers": "7.1.0", "@mui/x-license": "7.0.0", "clsx": "^2.1.0", "prop-types": "^15.8.1", diff --git a/packages/x-date-pickers/package.json b/packages/x-date-pickers/package.json index 7746d0ab63b6b..4e7f731b83199 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": "7.0.0", + "version": "7.1.0", "description": "The community edition of the date picker components (MUI X).", "author": "MUI Team", "main": "src/index.ts", diff --git a/packages/x-tree-view/package.json b/packages/x-tree-view/package.json index 0e99bd3721ffb..3e742b593dba9 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": "7.0.0", + "version": "7.1.0", "description": "The community edition of the tree view components (MUI X).", "author": "MUI Team", "main": "src/index.ts", From b591c46fed735fa39b6ddba2d0a6ea4c1c4cba33 Mon Sep 17 00:00:00 2001 From: Alexandre Fauquette <45398769+alexfauquette@users.noreply.github.com> Date: Thu, 28 Mar 2024 19:53:51 +0100 Subject: [PATCH 31/55] [charts] Fix `ticInterval` usage for y-axis (#12592) --- packages/x-charts/src/ChartsYAxis/ChartsYAxis.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/x-charts/src/ChartsYAxis/ChartsYAxis.tsx b/packages/x-charts/src/ChartsYAxis/ChartsYAxis.tsx index 440f95913839d..e74ad4ab9ccac 100644 --- a/packages/x-charts/src/ChartsYAxis/ChartsYAxis.tsx +++ b/packages/x-charts/src/ChartsYAxis/ChartsYAxis.tsx @@ -68,6 +68,7 @@ function ChartsYAxis(inProps: ChartsYAxisProps) { slotProps, tickPlacement, tickLabelPlacement, + tickInterval, } = defaultizedProps; const theme = useTheme(); @@ -83,6 +84,7 @@ function ChartsYAxis(inProps: ChartsYAxisProps) { valueFormatter, tickPlacement, tickLabelPlacement, + tickInterval, }); const positionSign = position === 'right' ? 1 : -1; From 7e2d2ece8ff55fc9f2c18c801268e36f3ddd4783 Mon Sep 17 00:00:00 2001 From: Lukas Date: Fri, 29 Mar 2024 10:38:25 +0200 Subject: [PATCH 32/55] [core] Remove explicit `express` package (#12602) --- docs/package.json | 1 - yarn.lock | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/package.json b/docs/package.json index 3f427728648ff..ec7054e9d6f91 100644 --- a/docs/package.json +++ b/docs/package.json @@ -57,7 +57,6 @@ "dayjs": "^1.11.10", "doctrine": "^3.0.0", "exceljs": "^4.4.0", - "express": "^4.18.3", "fg-loadcss": "^3.1.0", "fs-extra": "^11.2.0", "lodash": "^4.17.21", diff --git a/yarn.lock b/yarn.lock index 423740868a855..cf72918bf0d4c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7280,7 +7280,7 @@ exponential-backoff@^3.1.1: resolved "https://registry.yarnpkg.com/exponential-backoff/-/exponential-backoff-3.1.1.tgz#64ac7526fe341ab18a39016cd22c787d01e00bf6" integrity sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw== -express@^4.16.4, express@^4.18.3: +express@^4.16.4: version "4.18.3" resolved "https://registry.yarnpkg.com/express/-/express-4.18.3.tgz#6870746f3ff904dee1819b82e4b51509afffb0d4" integrity sha512-6VyCijWQ+9O7WuVMTRBTl+cjNNIzD5cY5mQ1WM8r/LEkI2u8EYpOotESNwzNlyCn3g+dmjKYI6BmNneSr/FSRw== From 28da4cade4bd0c470b1d88c1eb7118e1fb3a8f50 Mon Sep 17 00:00:00 2001 From: Alexandre Fauquette <45398769+alexfauquette@users.noreply.github.com> Date: Fri, 29 Mar 2024 11:59:09 +0100 Subject: [PATCH 33/55] [docs] Move data grid interfaces to standard API page layout (#12016) Co-authored-by: Andrew Cherniavskyi --- .../x/api/data-grid/grid-actions-col-def.js | 27 +- .../x/api/data-grid/grid-actions-col-def.json | 99 ++++ .../x/api/data-grid/grid-actions-col-def.md | 71 --- .../data-grid/grid-aggregation-function.js | 27 +- .../data-grid/grid-aggregation-function.json | 33 ++ .../data-grid/grid-aggregation-function.md | 29 -- docs/pages/x/api/data-grid/grid-api.js | 27 +- docs/pages/x/api/data-grid/grid-api.json | 493 ++++++++++++++++++ docs/pages/x/api/data-grid/grid-api.md | 149 ------ .../pages/x/api/data-grid/grid-cell-params.js | 27 +- .../x/api/data-grid/grid-cell-params.json | 21 + .../pages/x/api/data-grid/grid-cell-params.md | 29 -- docs/pages/x/api/data-grid/grid-col-def.js | 27 +- docs/pages/x/api/data-grid/grid-col-def.json | 93 ++++ docs/pages/x/api/data-grid/grid-col-def.md | 70 --- .../api/data-grid/grid-csv-export-options.js | 27 +- .../data-grid/grid-csv-export-options.json | 21 + .../api/data-grid/grid-csv-export-options.md | 35 -- .../data-grid/grid-excel-export-options.js | 27 +- .../data-grid/grid-excel-export-options.json | 47 ++ .../data-grid/grid-excel-export-options.md | 34 -- .../api/data-grid/grid-export-state-params.js | 27 +- .../data-grid/grid-export-state-params.json | 12 + .../api/data-grid/grid-export-state-params.md | 28 - .../pages/x/api/data-grid/grid-filter-item.js | 27 +- .../x/api/data-grid/grid-filter-item.json | 15 + .../pages/x/api/data-grid/grid-filter-item.md | 31 -- .../x/api/data-grid/grid-filter-model.js | 27 +- .../x/api/data-grid/grid-filter-model.json | 22 + .../x/api/data-grid/grid-filter-model.md | 32 -- .../x/api/data-grid/grid-filter-operator.js | 27 +- .../x/api/data-grid/grid-filter-operator.json | 24 + .../x/api/data-grid/grid-filter-operator.md | 35 -- .../data-grid/grid-print-export-options.js | 27 +- .../data-grid/grid-print-export-options.json | 23 + .../data-grid/grid-print-export-options.md | 37 -- .../data-grid/grid-row-class-name-params.js | 27 +- .../data-grid/grid-row-class-name-params.json | 17 + .../data-grid/grid-row-class-name-params.md | 33 -- docs/pages/x/api/data-grid/grid-row-params.js | 27 +- .../x/api/data-grid/grid-row-params.json | 14 + docs/pages/x/api/data-grid/grid-row-params.md | 30 -- .../api/data-grid/grid-row-spacing-params.js | 27 +- .../data-grid/grid-row-spacing-params.json | 16 + .../api/data-grid/grid-row-spacing-params.md | 32 -- .../data-grid/grid-single-select-col-def.js | 27 +- .../data-grid/grid-single-select-col-def.json | 104 ++++ .../data-grid/grid-single-select-col-def.md | 73 --- .../api/buildInterfacesDocumentation.ts | 237 +++++---- docs/scripts/api/utils.ts | 6 +- .../modules/components/InterfaceApiPage.js | 184 +++++++ .../data-grid/grid-actions-col-def.json | 95 ++++ .../data-grid/grid-aggregation-function.json | 23 + .../api-docs/data-grid/grid-api.json | 257 +++++++++ .../api-docs/data-grid/grid-cell-params.json | 18 + .../api-docs/data-grid/grid-col-def.json | 94 ++++ .../data-grid/grid-csv-export-options.json | 25 + .../data-grid/grid-excel-export-options.json | 32 ++ .../data-grid/grid-export-state-params.json | 8 + .../api-docs/data-grid/grid-filter-item.json | 13 + .../api-docs/data-grid/grid-filter-model.json | 16 + .../data-grid/grid-filter-operator.json | 25 + .../data-grid/grid-print-export-options.json | 29 ++ .../data-grid/grid-row-class-name-params.json | 13 + .../api-docs/data-grid/grid-row-params.json | 8 + .../data-grid/grid-row-spacing-params.json | 12 + .../data-grid/grid-single-select-col-def.json | 101 ++++ 67 files changed, 2499 insertions(+), 931 deletions(-) create mode 100644 docs/pages/x/api/data-grid/grid-actions-col-def.json delete mode 100644 docs/pages/x/api/data-grid/grid-actions-col-def.md create mode 100644 docs/pages/x/api/data-grid/grid-aggregation-function.json delete mode 100644 docs/pages/x/api/data-grid/grid-aggregation-function.md create mode 100644 docs/pages/x/api/data-grid/grid-api.json delete mode 100644 docs/pages/x/api/data-grid/grid-api.md create mode 100644 docs/pages/x/api/data-grid/grid-cell-params.json delete mode 100644 docs/pages/x/api/data-grid/grid-cell-params.md create mode 100644 docs/pages/x/api/data-grid/grid-col-def.json delete mode 100644 docs/pages/x/api/data-grid/grid-col-def.md create mode 100644 docs/pages/x/api/data-grid/grid-csv-export-options.json delete mode 100644 docs/pages/x/api/data-grid/grid-csv-export-options.md create mode 100644 docs/pages/x/api/data-grid/grid-excel-export-options.json delete mode 100644 docs/pages/x/api/data-grid/grid-excel-export-options.md create mode 100644 docs/pages/x/api/data-grid/grid-export-state-params.json delete mode 100644 docs/pages/x/api/data-grid/grid-export-state-params.md create mode 100644 docs/pages/x/api/data-grid/grid-filter-item.json delete mode 100644 docs/pages/x/api/data-grid/grid-filter-item.md create mode 100644 docs/pages/x/api/data-grid/grid-filter-model.json delete mode 100644 docs/pages/x/api/data-grid/grid-filter-model.md create mode 100644 docs/pages/x/api/data-grid/grid-filter-operator.json delete mode 100644 docs/pages/x/api/data-grid/grid-filter-operator.md create mode 100644 docs/pages/x/api/data-grid/grid-print-export-options.json delete mode 100644 docs/pages/x/api/data-grid/grid-print-export-options.md create mode 100644 docs/pages/x/api/data-grid/grid-row-class-name-params.json delete mode 100644 docs/pages/x/api/data-grid/grid-row-class-name-params.md create mode 100644 docs/pages/x/api/data-grid/grid-row-params.json delete mode 100644 docs/pages/x/api/data-grid/grid-row-params.md create mode 100644 docs/pages/x/api/data-grid/grid-row-spacing-params.json delete mode 100644 docs/pages/x/api/data-grid/grid-row-spacing-params.md create mode 100644 docs/pages/x/api/data-grid/grid-single-select-col-def.json delete mode 100644 docs/pages/x/api/data-grid/grid-single-select-col-def.md create mode 100644 docs/src/modules/components/InterfaceApiPage.js create mode 100644 docs/translations/api-docs/data-grid/grid-actions-col-def.json create mode 100644 docs/translations/api-docs/data-grid/grid-aggregation-function.json create mode 100644 docs/translations/api-docs/data-grid/grid-api.json create mode 100644 docs/translations/api-docs/data-grid/grid-cell-params.json create mode 100644 docs/translations/api-docs/data-grid/grid-col-def.json create mode 100644 docs/translations/api-docs/data-grid/grid-csv-export-options.json create mode 100644 docs/translations/api-docs/data-grid/grid-excel-export-options.json create mode 100644 docs/translations/api-docs/data-grid/grid-export-state-params.json create mode 100644 docs/translations/api-docs/data-grid/grid-filter-item.json create mode 100644 docs/translations/api-docs/data-grid/grid-filter-model.json create mode 100644 docs/translations/api-docs/data-grid/grid-filter-operator.json create mode 100644 docs/translations/api-docs/data-grid/grid-print-export-options.json create mode 100644 docs/translations/api-docs/data-grid/grid-row-class-name-params.json create mode 100644 docs/translations/api-docs/data-grid/grid-row-params.json create mode 100644 docs/translations/api-docs/data-grid/grid-row-spacing-params.json create mode 100644 docs/translations/api-docs/data-grid/grid-single-select-col-def.json diff --git a/docs/pages/x/api/data-grid/grid-actions-col-def.js b/docs/pages/x/api/data-grid/grid-actions-col-def.js index 7ca29be5152ee..94781bd891182 100644 --- a/docs/pages/x/api/data-grid/grid-actions-col-def.js +++ b/docs/pages/x/api/data-grid/grid-actions-col-def.js @@ -1,7 +1,26 @@ import * as React from 'react'; -import MarkdownDocs from '@mui/monorepo/docs/src/modules/components/MarkdownDocs'; -import * as pageProps from './grid-actions-col-def.md?muiMarkdown'; +import InterfaceApiPage from 'docsx/src/modules/components/InterfaceApiPage'; +import layoutConfig from 'docsx/src/modules/utils/dataGridLayoutConfig'; +import mapApiPageTranslations from 'docs/src/modules/utils/mapApiPageTranslations'; +import jsonPageContent from './grid-actions-col-def.json'; -export default function Page() { - return ; +export default function Page(props) { + const { descriptions, pageContent } = props; + return ( + + ); } + +Page.getInitialProps = () => { + const req = require.context( + 'docsx/translations/api-docs/data-grid/', + false, + /\.\/grid-actions-col-def.*.json$/, + ); + const descriptions = mapApiPageTranslations(req); + + return { + descriptions, + pageContent: jsonPageContent, + }; +}; diff --git a/docs/pages/x/api/data-grid/grid-actions-col-def.json b/docs/pages/x/api/data-grid/grid-actions-col-def.json new file mode 100644 index 0000000000000..ca909eb5cbaae --- /dev/null +++ b/docs/pages/x/api/data-grid/grid-actions-col-def.json @@ -0,0 +1,99 @@ +{ + "name": "GridActionsColDef", + "imports": [ + "import { GridActionsColDef } from '@mui/x-data-grid-premium'", + "import { GridActionsColDef } from '@mui/x-data-grid-pro'", + "import { GridActionsColDef } from '@mui/x-data-grid'" + ], + "demos": "", + "properties": { + "field": { "type": { "description": "string" }, "required": true }, + "getActions": { + "type": { + "description": "(params: GridRowParams<R>) => React.ReactElement<GridActionsCellItemProps>[]" + }, + "required": true + }, + "type": { "type": { "description": "'actions'" }, "default": "'actions'", "required": true }, + "aggregable": { + "type": { "description": "boolean" }, + "default": "true", + "isPremiumPlan": true + }, + "align": { "type": { "description": "GridAlignment" } }, + "availableAggregationFunctions": { + "type": { "description": "string[]" }, + "isPremiumPlan": true + }, + "cellClassName": { "type": { "description": "GridCellClassNamePropType<R, V>" } }, + "colSpan": { + "type": { "description": "number | GridColSpanFn<R, V, F>" }, + "default": "1" + }, + "description": { "type": { "description": "string" } }, + "disableColumnMenu": { "type": { "description": "boolean" }, "default": "false" }, + "disableExport": { "type": { "description": "boolean" }, "default": "false" }, + "disableReorder": { "type": { "description": "boolean" }, "default": "false" }, + "display": { "type": { "description": "'text' | 'flex'" } }, + "editable": { "type": { "description": "boolean" }, "default": "false" }, + "filterable": { "type": { "description": "boolean" }, "default": "true" }, + "filterOperators": { "type": { "description": "GridFilterOperator<R, V, F>[]" } }, + "flex": { "type": { "description": "number" } }, + "getApplyQuickFilterFn": { "type": { "description": "GetApplyQuickFilterFn<R, V>" } }, + "getSortComparator": { + "type": { + "description": "(sortDirection: GridSortDirection) => GridComparatorFn<V> | undefined" + } + }, + "groupable": { "type": { "description": "boolean" }, "default": "true" }, + "groupingValueGetter": { + "type": { "description": "GridGroupingValueGetter<R>" }, + "isPremiumPlan": true + }, + "headerAlign": { "type": { "description": "GridAlignment" } }, + "headerClassName": { "type": { "description": "GridColumnHeaderClassNamePropType" } }, + "headerName": { "type": { "description": "string" } }, + "hideable": { "type": { "description": "boolean" }, "default": "true" }, + "hideSortIcons": { "type": { "description": "boolean" }, "default": "false" }, + "maxWidth": { "type": { "description": "number" }, "default": "Infinity" }, + "minWidth": { "type": { "description": "number" }, "default": "50" }, + "pastedValueParser": { + "type": { "description": "GridPastedValueParser<R, V, F>" }, + "isPremiumPlan": true + }, + "pinnable": { "type": { "description": "boolean" }, "default": "true" }, + "preProcessEditCellProps": { + "type": { + "description": "(params: GridPreProcessEditCellProps) => GridEditCellProps | Promise<GridEditCellProps>" + } + }, + "renderCell": { + "type": { + "description": "(params: GridRenderCellParams<R, V, F>) => React.ReactNode" + } + }, + "renderEditCell": { + "type": { + "description": "(params: GridRenderEditCellParams<R, V, F>) => React.ReactNode" + } + }, + "renderHeader": { + "type": { + "description": "(params: GridColumnHeaderParams<R, V, F>) => React.ReactNode" + } + }, + "renderHeaderFilter": { + "type": { "description": "(params: GridRenderHeaderFilterProps) => React.ReactNode" }, + "isProPlan": true + }, + "resizable": { "type": { "description": "boolean" }, "default": "true" }, + "sortable": { "type": { "description": "boolean" }, "default": "true" }, + "sortComparator": { "type": { "description": "GridComparatorFn<V>" } }, + "sortingOrder": { "type": { "description": "GridSortDirection[]" } }, + "valueFormatter": { "type": { "description": "GridValueFormatter<R, V, F>" } }, + "valueGetter": { "type": { "description": "GridValueGetter<R, V, F>" } }, + "valueParser": { "type": { "description": "GridValueParser<R, V, F>" } }, + "valueSetter": { "type": { "description": "GridValueSetter<R, V, F>" } }, + "width": { "type": { "description": "number" }, "default": "100" } + } +} diff --git a/docs/pages/x/api/data-grid/grid-actions-col-def.md b/docs/pages/x/api/data-grid/grid-actions-col-def.md deleted file mode 100644 index e1f9daf908f4f..0000000000000 --- a/docs/pages/x/api/data-grid/grid-actions-col-def.md +++ /dev/null @@ -1,71 +0,0 @@ -# GridActionsColDef Interface - -

Column Definition interface used for columns with the `actions` type.

- -## Demos - -:::info -For examples and details on the usage, check the following pages: - -- [Special column properties](/x/react-data-grid/column-definition/#special-properties) - -::: - -## Import - -```js -import { GridActionsColDef } from '@mui/x-data-grid-premium'; -// or -import { GridActionsColDef } from '@mui/x-data-grid-pro'; -// or -import { GridActionsColDef } from '@mui/x-data-grid'; -``` - -## Properties - -| Name | Type | Default | Description | -| :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------- | :------------------------------------------ | :----------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| aggregable? [](/x/introduction/licensing/#premium-plan) | boolean | true | If `true`, the cells of the column can be aggregated based. | -| align? | GridAlignment | | Allows to align the column values in cells. | -| availableAggregationFunctions? [](/x/introduction/licensing/#premium-plan) | string[] | | Limit the aggregation function usable on this column.
By default, the column will have all the aggregation functions that are compatible with its type. | -| cellClassName? | GridCellClassNamePropType<R, V> | | Class name that will be added in cells for that column. | -| colSpan? | number \| GridColSpanFn<R, V, F> | 1 | Number of columns a cell should span. | -| description? | string | | The description of the column rendered as tooltip if the column header name is not fully displayed. | -| disableColumnMenu? | boolean | false | If `true`, the column menu is disabled for this column. | -| disableExport? | boolean | false | If `true`, this column will not be included in exports. | -| disableReorder? | boolean | false | If `true`, this column cannot be reordered. | -| display? | 'text' \| 'flex' | | Display mode for the cell:
- 'text': For text-based cells (default)
- 'flex': For cells with HTMLElement children | -| editable? | boolean | false | If `true`, the cells of the column are editable. | -| field | string | | The column identifier. It's used to map with GridRowModel values. | -| filterable? | boolean | true | If `true`, the column is filterable. | -| filterOperators? | GridFilterOperator<R, V, F>[] | | Allows setting the filter operators for this column. | -| flex? | number | | If set, it indicates that a column has fluid width. Range [0, ∞). | -| getActions | (params: GridRowParams<R>) => React.ReactElement<GridActionsCellItemProps>[] | | Function that returns the actions to be shown. | -| getApplyQuickFilterFn? | GetApplyQuickFilterFn<R, V> | | The callback that generates a filtering function for a given quick filter value.
This function can return `null` to skip filtering for this value and column. | -| getSortComparator? | (sortDirection: GridSortDirection) => GridComparatorFn<V> \| undefined | | Allows to use a different comparator function depending on the sort direction.
Takes precedence over `sortComparator`. | -| groupable? | boolean | true | If `true`, the rows can be grouped based on this column values (pro-plan only).
Only available in DataGridPremium. | -| groupingValueGetter? [](/x/introduction/licensing/#premium-plan) | GridGroupingValueGetter<R> | | Function that transforms a complex cell value into a key that be used for grouping the rows. | -| headerAlign? | GridAlignment | | Header cell element alignment. | -| headerClassName? | GridColumnHeaderClassNamePropType | | Class name that will be added in the column header cell. | -| headerName? | string | | The title of the column rendered in the column header cell. | -| hideable? | boolean | true | If `false`, removes the buttons for hiding this column. | -| hideSortIcons? | boolean | false | Toggle the visibility of the sort icons. | -| maxWidth? | number | Infinity | Sets the maximum width of a column. | -| minWidth? | number | 50 | Sets the minimum width of a column. | -| pastedValueParser? [](/x/introduction/licensing/#premium-plan) | GridPastedValueParser<R, V, F> | | Function that takes the clipboard-pasted value and converts it to a value used internally. | -| pinnable? | boolean | true | If `false`, the menu items for column pinning menu will not be rendered.
Only available in DataGridPro. | -| preProcessEditCellProps? | (params: GridPreProcessEditCellProps) => GridEditCellProps \| Promise<GridEditCellProps> | | Callback fired when the edit props of the cell changes.
It allows to process the props that saved into the state. | -| renderCell? | (params: GridRenderCellParams<R, V, F>) => React.ReactNode | | Allows to override the component rendered as cell for this column. | -| renderEditCell? | (params: GridRenderEditCellParams<R, V, F>) => React.ReactNode | | Allows to override the component rendered in edit cell mode for this column. | -| renderHeader? | (params: GridColumnHeaderParams<R, V, F>) => React.ReactNode | | Allows to render a component in the column header cell. | -| renderHeaderFilter? [](/x/introduction/licensing/#pro-plan) | (params: GridRenderHeaderFilterProps) => React.ReactNode | | Allows to render a component in the column header filter cell. | -| resizable? | boolean | true | If `true`, the column is resizable. | -| sortable? | boolean | true | If `true`, the column is sortable. | -| sortComparator? | GridComparatorFn<V> | | A comparator function used to sort rows. | -| sortingOrder? | GridSortDirection[] | | The order of the sorting sequence. | -| type | 'actions' | 'actions' | The type of the column. | -| valueFormatter? | GridValueFormatter<R, V, F> | | Function that allows to apply a formatter before rendering its value. | -| valueGetter? | GridValueGetter<R, V, F> | | Function that allows to get a specific data instead of field to render in the cell. | -| valueParser? | GridValueParser<R, V, F> | | Function that takes the user-entered value and converts it to a value used internally. | -| valueSetter? | GridValueSetter<R, V, F> | | Function that allows to customize how the entered value is stored in the row.
It only works with cell/row editing. | -| width? | number | 100 | Set the width of the column. | diff --git a/docs/pages/x/api/data-grid/grid-aggregation-function.js b/docs/pages/x/api/data-grid/grid-aggregation-function.js index c2255c2117caf..3cf533597da16 100644 --- a/docs/pages/x/api/data-grid/grid-aggregation-function.js +++ b/docs/pages/x/api/data-grid/grid-aggregation-function.js @@ -1,7 +1,26 @@ import * as React from 'react'; -import MarkdownDocs from '@mui/monorepo/docs/src/modules/components/MarkdownDocs'; -import * as pageProps from './grid-aggregation-function.md?muiMarkdown'; +import InterfaceApiPage from 'docsx/src/modules/components/InterfaceApiPage'; +import layoutConfig from 'docsx/src/modules/utils/dataGridLayoutConfig'; +import mapApiPageTranslations from 'docs/src/modules/utils/mapApiPageTranslations'; +import jsonPageContent from './grid-aggregation-function.json'; -export default function Page() { - return ; +export default function Page(props) { + const { descriptions, pageContent } = props; + return ( + + ); } + +Page.getInitialProps = () => { + const req = require.context( + 'docsx/translations/api-docs/data-grid/', + false, + /\.\/grid-aggregation-function.*.json$/, + ); + const descriptions = mapApiPageTranslations(req); + + return { + descriptions, + pageContent: jsonPageContent, + }; +}; diff --git a/docs/pages/x/api/data-grid/grid-aggregation-function.json b/docs/pages/x/api/data-grid/grid-aggregation-function.json new file mode 100644 index 0000000000000..e4209cf783dd3 --- /dev/null +++ b/docs/pages/x/api/data-grid/grid-aggregation-function.json @@ -0,0 +1,33 @@ +{ + "name": "GridAggregationFunction", + "imports": ["import { GridAggregationFunction } from '@mui/x-data-grid-premium'"], + "demos": "", + "properties": { + "apply": { + "type": { + "description": "(params: GridAggregationParams<V>) => AV | null | undefined" + }, + "required": true, + "isPremiumPlan": true + }, + "columnTypes": { "type": { "description": "string[]" }, "isPremiumPlan": true }, + "getCellValue": { + "type": { "description": "(params: GridAggregationGetCellValueParams) => V" }, + "isPremiumPlan": true + }, + "hasCellUnit": { + "type": { "description": "boolean" }, + "default": "`true`", + "isPremiumPlan": true + }, + "label": { + "type": { "description": "string" }, + "default": "`apiRef.current.getLocaleText('aggregationFunctionLabel{capitalize(name)})`", + "isPremiumPlan": true + }, + "valueFormatter": { + "type": { "description": "(params: GridValueFormatterParams<AV>) => FAV" }, + "isPremiumPlan": true + } + } +} diff --git a/docs/pages/x/api/data-grid/grid-aggregation-function.md b/docs/pages/x/api/data-grid/grid-aggregation-function.md deleted file mode 100644 index 6500040e6ddaf..0000000000000 --- a/docs/pages/x/api/data-grid/grid-aggregation-function.md +++ /dev/null @@ -1,29 +0,0 @@ -# GridAggregationFunction Interface - -

Grid aggregation function definition interface.

- -## Demos - -:::info -For examples and details on the usage, check the following pages: - -- [Aggregation functions](/x/react-data-grid/aggregation/#aggregation-functions) - -::: - -## Import - -```js -import { GridAggregationFunction } from '@mui/x-data-grid-premium'; -``` - -## Properties - -| Name | Type | Default | Description | -| :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :---------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------ | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| apply [](/x/introduction/licensing/#premium-plan) | (params: GridAggregationParams<V>) => AV \| null \| undefined | | Function that takes the current cell values and generates the aggregated value. | -| columnTypes? [](/x/introduction/licensing/#premium-plan) | string[] | | Column types supported by this aggregation function.
If not defined, all types are supported (in most cases this property should be defined). | -| getCellValue? [](/x/introduction/licensing/#premium-plan) | (params: GridAggregationGetCellValueParams) => V | | Function that allows to transform the value of the cell passed to the aggregation function applier.
Useful for aggregating data from multiple row fields. | -| hasCellUnit? [](/x/introduction/licensing/#premium-plan) | boolean | `true` | Indicates if the aggregated value have the same unit as the cells used to generate it.
It can be used to apply a custom cell renderer only if the aggregated value has the same unit. | -| label? [](/x/introduction/licensing/#premium-plan) | string | `apiRef.current.getLocaleText('aggregationFunctionLabel{capitalize(name)})` | Label of the aggregation function.
Will be used to add a label on the footer of the grouping column when this aggregation function is the only one being used. | -| valueFormatter? [](/x/introduction/licensing/#premium-plan) | (params: GridValueFormatterParams<AV>) => FAV | | Function that allows to apply a formatter to the aggregated value.
If not defined, the grid will use the formatter of the column. | diff --git a/docs/pages/x/api/data-grid/grid-api.js b/docs/pages/x/api/data-grid/grid-api.js index 3ec62f326b405..b79184bd8dcba 100644 --- a/docs/pages/x/api/data-grid/grid-api.js +++ b/docs/pages/x/api/data-grid/grid-api.js @@ -1,7 +1,26 @@ import * as React from 'react'; -import MarkdownDocs from '@mui/monorepo/docs/src/modules/components/MarkdownDocs'; -import * as pageProps from './grid-api.md?muiMarkdown'; +import InterfaceApiPage from 'docsx/src/modules/components/InterfaceApiPage'; +import layoutConfig from 'docsx/src/modules/utils/dataGridLayoutConfig'; +import mapApiPageTranslations from 'docs/src/modules/utils/mapApiPageTranslations'; +import jsonPageContent from './grid-api.json'; -export default function Page() { - return ; +export default function Page(props) { + const { descriptions, pageContent } = props; + return ( + + ); } + +Page.getInitialProps = () => { + const req = require.context( + 'docsx/translations/api-docs/data-grid/', + false, + /\.\/grid-api.*.json$/, + ); + const descriptions = mapApiPageTranslations(req); + + return { + descriptions, + pageContent: jsonPageContent, + }; +}; diff --git a/docs/pages/x/api/data-grid/grid-api.json b/docs/pages/x/api/data-grid/grid-api.json new file mode 100644 index 0000000000000..4acb3f3986bb8 --- /dev/null +++ b/docs/pages/x/api/data-grid/grid-api.json @@ -0,0 +1,493 @@ +{ + "name": "GridApi", + "imports": [ + "import { GridApi } from '@mui/x-data-grid-premium'", + "import { GridApi } from '@mui/x-data-grid-pro'", + "import { GridApi } from '@mui/x-data-grid'" + ], + "demos": "", + "properties": { + "addRowGroupingCriteria": { + "type": { + "description": "(groupingCriteriaField: string, groupingIndex?: number) => void" + }, + "required": true, + "isPremiumPlan": true + }, + "applySorting": { "type": { "description": "() => void" }, "required": true }, + "autosizeColumns": { + "type": { "description": "(options?: GridAutosizeOptions) => Promise<void>" }, + "required": true + }, + "deleteFilterItem": { + "type": { "description": "(item: GridFilterItem) => void" }, + "required": true + }, + "exportDataAsCsv": { + "type": { "description": "(options?: GridCsvExportOptions) => void" }, + "required": true + }, + "exportDataAsExcel": { + "type": { "description": "(options?: GridExcelExportOptions) => Promise<void>" }, + "required": true, + "isPremiumPlan": true + }, + "exportDataAsPrint": { + "type": { "description": "(options?: GridPrintExportOptions) => void" }, + "required": true + }, + "exportState": { + "type": { "description": "(params?: GridExportStateParams) => InitialState" }, + "required": true + }, + "forceUpdate": { "type": { "description": "() => void" }, "required": true }, + "getAllColumns": { "type": { "description": "() => GridStateColDef[]" }, "required": true }, + "getAllGroupDetails": { + "type": { "description": "() => GridColumnGroupLookup" }, + "required": true + }, + "getAllRowIds": { "type": { "description": "() => GridRowId[]" }, "required": true }, + "getCellElement": { + "type": { "description": "(id: GridRowId, field: string) => HTMLDivElement | null" }, + "required": true + }, + "getCellMode": { + "type": { "description": "(id: GridRowId, field: string) => GridCellMode" }, + "required": true + }, + "getCellParams": { + "type": { + "description": "<R extends GridValidRowModel = any, V = unknown, F = V, N extends GridTreeNode = GridTreeNode>(id: GridRowId, field: string) => GridCellParams<R, V, F, N>" + }, + "required": true + }, + "getCellSelectionModel": { + "type": { "description": "() => GridCellSelectionModel" }, + "required": true, + "isPremiumPlan": true + }, + "getCellValue": { + "type": { + "description": "<V extends any = any>(id: GridRowId, field: string) => V" + }, + "required": true + }, + "getColumn": { + "type": { "description": "(field: string) => GridStateColDef" }, + "required": true + }, + "getColumnGroupPath": { + "type": { "description": "(field: string) => GridColumnGroup['groupId'][]" }, + "required": true + }, + "getColumnHeaderElement": { + "type": { "description": "(field: string) => HTMLDivElement | null" }, + "required": true + }, + "getColumnHeaderParams": { + "type": { "description": "(field: string) => GridColumnHeaderParams" }, + "required": true + }, + "getColumnIndex": { + "type": { "description": "(field: string, useVisibleColumns?: boolean) => number" }, + "required": true + }, + "getColumnIndexRelativeToVisibleColumns": { + "type": { "description": "(field: string) => number" }, + "required": true + }, + "getColumnPosition": { + "type": { "description": "(field: string) => number" }, + "required": true + }, + "getDataAsCsv": { + "type": { "description": "(options?: GridCsvExportOptions) => string" }, + "required": true + }, + "getDataAsExcel": { + "type": { + "description": "(options?: GridExcelExportOptions) => Promise<Excel.Workbook> | null" + }, + "required": true, + "isPremiumPlan": true + }, + "getExpandedDetailPanels": { + "type": { "description": "() => GridRowId[]" }, + "required": true, + "isProPlan": true + }, + "getLocaleText": { + "type": { + "description": "<T extends GridTranslationKeys>(key: T) => GridLocaleText[T]" + }, + "required": true + }, + "getPinnedColumns": { + "type": { "description": "() => GridPinnedColumnFields" }, + "required": true, + "isProPlan": true + }, + "getRootDimensions": { "type": { "description": "() => GridDimensions" }, "required": true }, + "getRow": { + "type": { + "description": "<R extends GridValidRowModel = any>(id: GridRowId) => R | null" + }, + "required": true + }, + "getRowElement": { + "type": { "description": "(id: GridRowId) => HTMLDivElement | null" }, + "required": true + }, + "getRowGroupChildren": { + "type": { "description": "(params: GridRowGroupChildrenGetterParams) => GridRowId[]" }, + "required": true, + "isProPlan": true + }, + "getRowId": { + "type": { + "description": "<R extends GridValidRowModel = any>(row: R) => GridRowId" + }, + "required": true + }, + "getRowIdFromRowIndex": { + "type": { "description": "(index: number) => GridRowId" }, + "required": true + }, + "getRowIndexRelativeToVisibleRows": { + "type": { "description": "(id: GridRowId) => number" }, + "required": true + }, + "getRowMode": { + "type": { "description": "(id: GridRowId) => GridRowMode" }, + "required": true + }, + "getRowModels": { + "type": { "description": "() => Map<GridRowId, GridRowModel>" }, + "required": true + }, + "getRowNode": { + "type": { "description": "<N extends GridTreeNode>(id: GridRowId) => N | null" }, + "required": true + }, + "getRowParams": { + "type": { "description": "(id: GridRowId) => GridRowParams" }, + "required": true + }, + "getRowsCount": { "type": { "description": "() => number" }, "required": true }, + "getRowWithUpdatedValues": { + "type": { "description": "(id: GridRowId, field: string) => GridRowModel" }, + "required": true + }, + "getScrollPosition": { + "type": { "description": "() => GridScrollParams" }, + "required": true + }, + "getSelectedCellsAsArray": { + "type": { "description": "() => GridCellCoordinates[]" }, + "required": true, + "isPremiumPlan": true + }, + "getSelectedRows": { + "type": { "description": "() => Map<GridRowId, GridRowModel>" }, + "required": true + }, + "getSortedRowIds": { "type": { "description": "() => GridRowId[]" }, "required": true }, + "getSortedRows": { "type": { "description": "() => GridRowModel[]" }, "required": true }, + "getSortModel": { "type": { "description": "() => GridSortModel" }, "required": true }, + "getVisibleColumns": { + "type": { "description": "() => GridStateColDef[]" }, + "required": true + }, + "hideColumnMenu": { "type": { "description": "() => void" }, "required": true }, + "hideFilterPanel": { "type": { "description": "() => void" }, "required": true }, + "hideHeaderFilterMenu": { "type": { "description": "() => void" }, "required": true }, + "hidePreferences": { "type": { "description": "() => void" }, "required": true }, + "ignoreDiacritics": { + "type": { "description": "DataGridProcessedProps['ignoreDiacritics']" }, + "required": true + }, + "isCellEditable": { + "type": { "description": "(params: GridCellParams) => boolean" }, + "required": true + }, + "isCellSelected": { + "type": { "description": "(id: GridRowId, field: GridColDef['field']) => boolean" }, + "required": true, + "isPremiumPlan": true + }, + "isColumnPinned": { + "type": { "description": "(field: string) => GridPinnedColumnPosition | false" }, + "required": true, + "isProPlan": true + }, + "isRowSelectable": { + "type": { "description": "(id: GridRowId) => boolean" }, + "required": true + }, + "isRowSelected": { + "type": { "description": "(id: GridRowId) => boolean" }, + "required": true + }, + "pinColumn": { + "type": { "description": "(field: string, side: GridPinnedColumnPosition) => void" }, + "required": true, + "isProPlan": true + }, + "publishEvent": { "type": { "description": "GridEventPublisher" }, "required": true }, + "removeRowGroupingCriteria": { + "type": { "description": "(groupingCriteriaField: string) => void" }, + "required": true, + "isPremiumPlan": true + }, + "resetRowHeights": { "type": { "description": "() => void" }, "required": true }, + "resize": { "type": { "description": "() => void" }, "required": true }, + "restoreState": { + "type": { "description": "(stateToRestore: InitialState) => void" }, + "required": true + }, + "scroll": { + "type": { "description": "(params: Partial<GridScrollParams>) => void" }, + "required": true + }, + "scrollToIndexes": { + "type": { "description": "(params: Partial<GridCellIndexCoordinates>) => boolean" }, + "required": true + }, + "selectCellRange": { + "type": { + "description": "(start: GridCellCoordinates, end: GridCellCoordinates, keepOtherSelected?: boolean) => void" + }, + "required": true, + "isPremiumPlan": true + }, + "selectRow": { + "type": { + "description": "(id: GridRowId, isSelected?: boolean, resetSelection?: boolean) => void" + }, + "required": true + }, + "selectRowRange": { + "type": { + "description": "(range: { startId: GridRowId; endId: GridRowId }, isSelected?: boolean, resetSelection?: boolean) => void" + }, + "required": true, + "isProPlan": true + }, + "selectRows": { + "type": { + "description": "(ids: GridRowId[], isSelected?: boolean, resetSelection?: boolean) => void" + }, + "required": true, + "isProPlan": true + }, + "setAggregationModel": { + "type": { "description": "(model: GridAggregationModel) => void" }, + "required": true, + "isPremiumPlan": true + }, + "setCellFocus": { + "type": { "description": "(id: GridRowId, field: string) => void" }, + "required": true + }, + "setCellSelectionModel": { + "type": { "description": "(newModel: GridCellSelectionModel) => void" }, + "required": true, + "isPremiumPlan": true + }, + "setColumnHeaderFilterFocus": { + "type": { "description": "(field: string, event?: MuiBaseEvent) => void" }, + "required": true + }, + "setColumnHeaderFocus": { + "type": { "description": "(field: string, event?: MuiBaseEvent) => void" }, + "required": true + }, + "setColumnIndex": { + "type": { "description": "(field: string, targetIndexPosition: number) => void" }, + "required": true, + "isProPlan": true + }, + "setColumnVisibility": { + "type": { "description": "(field: string, isVisible: boolean) => void" }, + "required": true + }, + "setColumnVisibilityModel": { + "type": { "description": "(model: GridColumnVisibilityModel) => void" }, + "required": true + }, + "setColumnWidth": { + "type": { "description": "(field: string, width: number) => void" }, + "required": true + }, + "setDensity": { + "type": { "description": "(density: GridDensity) => void" }, + "required": true + }, + "setEditCellValue": { + "type": { + "description": "(params: GridEditCellValueParams, event?: MuiBaseEvent) => Promise<boolean> | void" + }, + "required": true + }, + "setExpandedDetailPanels": { + "type": { "description": "(ids: GridRowId[]) => void" }, + "required": true, + "isProPlan": true + }, + "setFilterLogicOperator": { + "type": { "description": "(operator: GridLogicOperator) => void" }, + "required": true + }, + "setFilterModel": { + "type": { + "description": "(model: GridFilterModel, reason?: GridControlledStateReasonLookup['filter']) => void" + }, + "required": true + }, + "setPage": { "type": { "description": "(page: number) => void" }, "required": true }, + "setPageSize": { "type": { "description": "(pageSize: number) => void" }, "required": true }, + "setPaginationModel": { + "type": { "description": "(model: GridPaginationModel) => void" }, + "required": true + }, + "setPinnedColumns": { + "type": { "description": "(pinnedColumns: GridPinnedColumnFields) => void" }, + "required": true, + "isProPlan": true + }, + "setQuickFilterValues": { + "type": { "description": "(values: any[]) => void" }, + "required": true + }, + "setRowChildrenExpansion": { + "type": { "description": "(id: GridRowId, isExpanded: boolean) => void" }, + "required": true, + "isProPlan": true + }, + "setRowCount": { "type": { "description": "(rowCount: number) => void" }, "required": true }, + "setRowGroupingCriteriaIndex": { + "type": { + "description": "(groupingCriteriaField: string, groupingIndex: number) => void" + }, + "required": true, + "isPremiumPlan": true + }, + "setRowGroupingModel": { + "type": { "description": "(model: GridRowGroupingModel) => void" }, + "required": true, + "isPremiumPlan": true + }, + "setRowIndex": { + "type": { "description": "(rowId: GridRowId, targetIndex: number) => void" }, + "required": true, + "isProPlan": true + }, + "setRows": { "type": { "description": "(rows: GridRowModel[]) => void" }, "required": true }, + "setRowSelectionModel": { + "type": { "description": "(rowIds: GridRowId[]) => void" }, + "required": true + }, + "setSortModel": { + "type": { "description": "(model: GridSortModel) => void" }, + "required": true + }, + "showColumnMenu": { "type": { "description": "(field: string) => void" }, "required": true }, + "showFilterPanel": { + "type": { + "description": "(targetColumnField?: string, panelId?: string, labelId?: string) => void" + }, + "required": true + }, + "showHeaderFilterMenu": { + "type": { "description": "(field: GridColDef['field']) => void" }, + "required": true + }, + "showPreferences": { + "type": { + "description": "(newValue: GridPreferencePanelsValue, panelId?: string, labelId?: string) => void" + }, + "required": true + }, + "sortColumn": { + "type": { + "description": "(field: GridColDef['field'], direction?: GridSortDirection, allowMultipleSorting?: boolean) => void" + }, + "required": true + }, + "startCellEditMode": { + "type": { "description": "(params: GridStartCellEditModeParams) => void" }, + "required": true + }, + "startHeaderFilterEditMode": { + "type": { "description": "(field: GridColDef['field']) => void" }, + "required": true + }, + "startRowEditMode": { + "type": { "description": "(params: GridStartRowEditModeParams) => void" }, + "required": true + }, + "state": { "type": { "description": "State" }, "required": true }, + "stopCellEditMode": { + "type": { "description": "(params: GridStopCellEditModeParams) => void" }, + "required": true + }, + "stopHeaderFilterEditMode": { "type": { "description": "() => void" }, "required": true }, + "stopRowEditMode": { + "type": { "description": "(params: GridStopRowEditModeParams) => void" }, + "required": true + }, + "subscribeEvent": { + "type": { + "description": "<E extends GridEvents>(event: E, handler: GridEventListener<E>, options?: EventListenerOptions) => () => void" + }, + "required": true + }, + "toggleColumnMenu": { + "type": { "description": "(field: string) => void" }, + "required": true + }, + "toggleDetailPanel": { + "type": { "description": "(id: GridRowId) => void" }, + "required": true, + "isProPlan": true + }, + "unpinColumn": { + "type": { "description": "(field: string) => void" }, + "required": true, + "isProPlan": true + }, + "unstable_replaceRows": { + "type": { "description": "(firstRowToReplace: number, newRows: GridRowModel[]) => void" }, + "required": true + }, + "unstable_setColumnVirtualization": { + "type": { "description": "(enabled: boolean) => void" }, + "required": true + }, + "unstable_setPinnedRows": { + "type": { "description": "(pinnedRows?: GridPinnedRowsProp) => void" }, + "required": true, + "isProPlan": true + }, + "unstable_setVirtualization": { + "type": { "description": "(enabled: boolean) => void" }, + "required": true + }, + "updateColumns": { + "type": { "description": "(cols: GridColDef[]) => void" }, + "required": true + }, + "updateRows": { + "type": { "description": "(updates: GridRowModelUpdate[]) => void" }, + "required": true + }, + "upsertFilterItem": { + "type": { "description": "(item: GridFilterItem) => void" }, + "required": true + }, + "upsertFilterItems": { + "type": { "description": "(items: GridFilterItem[]) => void" }, + "required": true + } + } +} diff --git a/docs/pages/x/api/data-grid/grid-api.md b/docs/pages/x/api/data-grid/grid-api.md deleted file mode 100644 index cf6a2bdbf7de8..0000000000000 --- a/docs/pages/x/api/data-grid/grid-api.md +++ /dev/null @@ -1,149 +0,0 @@ -# GridApi Interface - -

The full grid API.

- -## Demos - -:::info -For examples and details on the usage, check the following pages: - -- [API object](/x/react-data-grid/api-object/) - -::: - -## Import - -```js -import { GridApi } from '@mui/x-data-grid-premium'; -// or -import { GridApi } from '@mui/x-data-grid-pro'; -// or -import { GridApi } from '@mui/x-data-grid'; -``` - -## Properties - -| Name | Type | Description | -| :------------------------------------------------------------------------------------------------------------------------------------------------------------ | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| addRowGroupingCriteria [](/x/introduction/licensing/#premium-plan) | (groupingCriteriaField: string, groupingIndex?: number) => void | Adds the field to the row grouping model. | -| applySorting | () => void | Applies the current sort model to the rows. | -| autosizeColumns | (options?: GridAutosizeOptions) => Promise<void> | Auto-size the columns of the grid based on the cells' content and the space available. | -| deleteFilterItem | (item: GridFilterItem) => void | Deletes a [GridFilterItem](/x/api/data-grid/grid-filter-item/). | -| exportDataAsCsv | (options?: GridCsvExportOptions) => void | Downloads and exports a CSV of the grid's data. | -| exportDataAsExcel [](/x/introduction/licensing/#premium-plan) | (options?: GridExcelExportOptions) => Promise<void> | Downloads and exports an Excel file of the grid's data. | -| exportDataAsPrint | (options?: GridPrintExportOptions) => void | Print the grid's data. | -| exportState | (params?: GridExportStateParams) => InitialState | Generates a serializable object containing the exportable parts of the DataGrid state.
These values can then be passed to the `initialState` prop or injected using the `restoreState` method. | -| forceUpdate | () => void | Forces the grid to rerender. It's often used after a state update. | -| getAllColumns | () => GridStateColDef[] | Returns an array of [GridColDef](/x/api/data-grid/grid-col-def/) containing all the column definitions. | -| getAllGroupDetails | () => GridColumnGroupLookup | Returns the column group lookup. | -| getAllRowIds | () => GridRowId[] | Gets the list of row ids. | -| getCellElement | (id: GridRowId, field: string) => HTMLDivElement \| null | Gets the underlying DOM element for a cell at the given `id` and `field`. | -| getCellMode | (id: GridRowId, field: string) => GridCellMode | Gets the mode of a cell. | -| getCellParams | <R extends GridValidRowModel = any, V = unknown, F = V, N extends GridTreeNode = GridTreeNode>(id: GridRowId, field: string) => GridCellParams<R, V, F, N> | Gets the [GridCellParams](/x/api/data-grid/grid-cell-params/) object that is passed as argument in events. | -| getCellSelectionModel [](/x/introduction/licensing/#premium-plan) | () => GridCellSelectionModel | Returns an object containing the selection state of the cells.
The keys of the object correpond to the row IDs.
The value of each key is another object whose keys are the fields and values are the selection state. | -| getCellValue | <V extends any = any>(id: GridRowId, field: string) => V | Gets the value of a cell at the given `id` and `field`. | -| getColumn | (field: string) => GridStateColDef | Returns the [GridColDef](/x/api/data-grid/grid-col-def/) for the given `field`. | -| getColumnGroupPath | (field: string) => GridColumnGroup['groupId'][] | Returns the id of the groups leading to the requested column.
The array is ordered by increasing depth (the last element is the direct parent of the column). | -| getColumnHeaderElement | (field: string) => HTMLDivElement \| null | Gets the underlying DOM element for the column header with the given `field`. | -| getColumnHeaderParams | (field: string) => GridColumnHeaderParams | Gets the GridColumnHeaderParams object that is passed as argument in events. | -| getColumnIndex | (field: string, useVisibleColumns?: boolean) => number | Returns the index position of a column. By default, only the visible columns are considered.
Pass `false` to `useVisibleColumns` to consider all columns. | -| getColumnIndexRelativeToVisibleColumns | (field: string) => number | Gets the index of a column relative to the columns that are reachable by scroll. | -| getColumnPosition | (field: string) => number | Returns the left-position of a column relative to the inner border of the grid. | -| getDataAsCsv | (options?: GridCsvExportOptions) => string | Returns the grid data as a CSV string.
This method is used internally by `exportDataAsCsv`. | -| getDataAsExcel [](/x/introduction/licensing/#premium-plan) | (options?: GridExcelExportOptions) => Promise<Excel.Workbook> \| null | Returns the grid data as an exceljs workbook.
This method is used internally by `exportDataAsExcel`. | -| getExpandedDetailPanels [](/x/introduction/licensing/#pro-plan) | () => GridRowId[] | Returns the rows whose detail panel is open. | -| getLocaleText | <T extends GridTranslationKeys>(key: T) => GridLocaleText[T] | Returns the translation for the `key`. | -| getPinnedColumns [](/x/introduction/licensing/#pro-plan) | () => GridPinnedColumnFields | Returns which columns are pinned. | -| getRootDimensions | () => GridDimensions | Returns the dimensions of the grid | -| getRow | <R extends GridValidRowModel = any>(id: GridRowId) => R \| null | Gets the row data with a given id. | -| getRowElement | (id: GridRowId) => HTMLDivElement \| null | Gets the underlying DOM element for a row at the given `id`. | -| getRowGroupChildren [](/x/introduction/licensing/#pro-plan) | (params: GridRowGroupChildrenGetterParams) => GridRowId[] | Gets the rows of a grouping criteria.
Only contains the rows provided to the grid, not the rows automatically generated by it. | -| getRowId | <R extends GridValidRowModel = any>(row: R) => GridRowId | Gets the ID of a row given its data. | -| getRowIdFromRowIndex | (index: number) => GridRowId | Gets the `GridRowId` of a row at a specific index.
The index is based on the sorted but unfiltered row list. | -| getRowIndexRelativeToVisibleRows | (id: GridRowId) => number | Gets the index of a row relative to the rows that are reachable by scroll. | -| getRowMode | (id: GridRowId) => GridRowMode | Gets the mode of a row. | -| getRowModels | () => Map<GridRowId, GridRowModel> | Gets the full set of rows as Map<GridRowId, GridRowModel>. | -| getRowNode | <N extends GridTreeNode>(id: GridRowId) => N \| null | Gets the row node from the internal tree structure. | -| getRowParams | (id: GridRowId) => GridRowParams | Gets the [GridRowParams](/x/api/data-grid/grid-row-params/) object that is passed as argument in events. | -| getRowsCount | () => number | Gets the total number of rows in the grid. | -| getRowWithUpdatedValues | (id: GridRowId, field: string) => GridRowModel | Returns the row with the values that were set by editing the cells.
In row editing, `field` is ignored and all fields are considered. | -| getScrollPosition | () => GridScrollParams | Returns the current scroll position. | -| getSelectedCellsAsArray [](/x/introduction/licensing/#premium-plan) | () => GridCellCoordinates[] | Returns an array containing only the selected cells.
Each item is an object with the ID and field of the cell. | -| getSelectedRows | () => Map<GridRowId, GridRowModel> | Returns an array of the selected rows. | -| getSortedRowIds | () => GridRowId[] | Returns all row ids sorted according to the active sort model. | -| getSortedRows | () => GridRowModel[] | Returns all rows sorted according to the active sort model. | -| getSortModel | () => GridSortModel | Returns the sort model currently applied to the grid. | -| getVisibleColumns | () => GridStateColDef[] | Returns the currently visible columns. | -| hideColumnMenu | () => void | Hides the column menu that is open. | -| hideFilterPanel | () => void | Hides the filter panel. | -| hideHeaderFilterMenu | () => void | Hides the header filter menu. | -| hidePreferences | () => void | Hides the preferences panel. | -| ignoreDiacritics | DataGridProcessedProps['ignoreDiacritics'] | Returns the value of the `ignoreDiacritics` prop. | -| isCellEditable | (params: GridCellParams) => boolean | Controls if a cell is editable. | -| isCellSelected [](/x/introduction/licensing/#premium-plan) | (id: GridRowId, field: GridColDef['field']) => boolean | Determines if a cell is selected or not. | -| isColumnPinned [](/x/introduction/licensing/#pro-plan) | (field: string) => GridPinnedColumnPosition \| false | Returns which side a column is pinned to. | -| isRowSelectable | (id: GridRowId) => boolean | Determines if a row can be selected or not. | -| isRowSelected | (id: GridRowId) => boolean | Determines if a row is selected or not. | -| pinColumn [](/x/introduction/licensing/#pro-plan) | (field: string, side: GridPinnedColumnPosition) => void | Pins a column to the left or right side of the grid. | -| publishEvent | GridEventPublisher | Emits an event. | -| removeRowGroupingCriteria [](/x/introduction/licensing/#premium-plan) | (groupingCriteriaField: string) => void | Remove the field from the row grouping model. | -| resetRowHeights | () => void | Forces the recalculation of the heights of all rows. | -| resize | () => void | Triggers a resize of the component and recalculation of width and height. | -| restoreState | (stateToRestore: InitialState) => void | Inject the given values into the state of the DataGrid. | -| scroll | (params: Partial<GridScrollParams>) => void | Triggers the viewport to scroll to the given positions (in pixels). | -| scrollToIndexes | (params: Partial<GridCellIndexCoordinates>) => boolean | Triggers the viewport to scroll to the cell at indexes given by `params`.
Returns `true` if the grid had to scroll to reach the target. | -| selectCellRange [](/x/introduction/licensing/#premium-plan) | (start: GridCellCoordinates, end: GridCellCoordinates, keepOtherSelected?: boolean) => void | Selects all cells that are inside the range given by `start` and `end` coordinates. | -| selectRow | (id: GridRowId, isSelected?: boolean, resetSelection?: boolean) => void | Change the selection state of a row. | -| selectRowRange [](/x/introduction/licensing/#pro-plan) | (range: { startId: GridRowId; endId: GridRowId }, isSelected?: boolean, resetSelection?: boolean) => void | Change the selection state of all the selectable rows in a range. | -| selectRows [](/x/introduction/licensing/#pro-plan) | (ids: GridRowId[], isSelected?: boolean, resetSelection?: boolean) => void | Change the selection state of multiple rows. | -| setAggregationModel [](/x/introduction/licensing/#premium-plan) | (model: GridAggregationModel) => void | Sets the aggregation model to the one given by `model`. | -| setCellFocus | (id: GridRowId, field: string) => void | Sets the focus to the cell at the given `id` and `field`. | -| setCellSelectionModel [](/x/introduction/licensing/#premium-plan) | (newModel: GridCellSelectionModel) => void | Updates the selected cells to be those passed to the `newModel` argument.
Any cell already selected will be unselected. | -| setColumnHeaderFilterFocus | (field: string, event?: MuiBaseEvent) => void | Sets the focus to the column header filter at the given `field`. | -| setColumnHeaderFocus | (field: string, event?: MuiBaseEvent) => void | Sets the focus to the column header at the given `field`. | -| setColumnIndex [](/x/introduction/licensing/#pro-plan) | (field: string, targetIndexPosition: number) => void | Moves a column from its original position to the position given by `targetIndexPosition`. | -| setColumnVisibility | (field: string, isVisible: boolean) => void | Changes the visibility of the column referred by `field`. | -| setColumnVisibilityModel | (model: GridColumnVisibilityModel) => void | Sets the column visibility model to the one given by `model`. | -| setColumnWidth | (field: string, width: number) => void | Updates the width of a column. | -| setDensity | (density: GridDensity) => void | Sets the density of the grid. | -| setEditCellValue | (params: GridEditCellValueParams, event?: MuiBaseEvent) => Promise<boolean> \| void | Sets the value of the edit cell.
Commonly used inside the edit cell component. | -| setExpandedDetailPanels [](/x/introduction/licensing/#pro-plan) | (ids: GridRowId[]) => void | Changes which rows to expand the detail panel. | -| setFilterLogicOperator | (operator: GridLogicOperator) => void | Changes the GridLogicOperator used to connect the filters. | -| setFilterModel | (model: GridFilterModel, reason?: GridControlledStateReasonLookup['filter']) => void | Sets the filter model to the one given by `model`. | -| setPage | (page: number) => void | Sets the displayed page to the value given by `page`. | -| setPageSize | (pageSize: number) => void | Sets the number of displayed rows to the value given by `pageSize`. | -| setPaginationModel | (model: GridPaginationModel) => void | Sets the `paginationModel` to a new value. | -| setPinnedColumns [](/x/introduction/licensing/#pro-plan) | (pinnedColumns: GridPinnedColumnFields) => void | Changes the pinned columns. | -| setQuickFilterValues | (values: any[]) => void | Set the quick filter values to the one given by `values` | -| setRowChildrenExpansion [](/x/introduction/licensing/#pro-plan) | (id: GridRowId, isExpanded: boolean) => void | Expand or collapse a row children. | -| setRowCount | (rowCount: number) => void | Sets the `rowCount` to a new value. | -| setRowGroupingCriteriaIndex [](/x/introduction/licensing/#premium-plan) | (groupingCriteriaField: string, groupingIndex: number) => void | Sets the grouping index of a grouping criteria. | -| setRowGroupingModel [](/x/introduction/licensing/#premium-plan) | (model: GridRowGroupingModel) => void | Sets the columns to use as grouping criteria. | -| setRowIndex [](/x/introduction/licensing/#pro-plan) | (rowId: GridRowId, targetIndex: number) => void | Moves a row from its original position to the position given by `targetIndex`. | -| setRows | (rows: GridRowModel[]) => void | Sets a new set of rows. | -| setRowSelectionModel | (rowIds: GridRowId[]) => void | Updates the selected rows to be those passed to the `rowIds` argument.
Any row already selected will be unselected. | -| setSortModel | (model: GridSortModel) => void | Updates the sort model and triggers the sorting of rows. | -| showColumnMenu | (field: string) => void | Display the column menu under the `field` column. | -| showFilterPanel | (targetColumnField?: string, panelId?: string, labelId?: string) => void | Shows the filter panel. If `targetColumnField` is given, a filter for this field is also added. | -| showHeaderFilterMenu | (field: GridColDef['field']) => void | Opens the header filter menu for the given field. | -| showPreferences | (newValue: GridPreferencePanelsValue, panelId?: string, labelId?: string) => void | Displays the preferences panel. The `newValue` argument controls the content of the panel. | -| sortColumn | (field: GridColDef['field'], direction?: GridSortDirection, allowMultipleSorting?: boolean) => void | Sorts a column. | -| startCellEditMode | (params: GridStartCellEditModeParams) => void | Puts the cell corresponding to the given row id and field into edit mode. | -| startHeaderFilterEditMode | (field: GridColDef['field']) => void | Puts the cell corresponding to the given row id and field into edit mode. | -| startRowEditMode | (params: GridStartRowEditModeParams) => void | Puts the row corresponding to the given id into edit mode. | -| state | State | Property that contains the whole state of the grid. | -| stopCellEditMode | (params: GridStopCellEditModeParams) => void | Puts the cell corresponding to the given row id and field into view mode and updates the original row with the new value stored.
If `params.ignoreModifications` is `true` it will discard the modifications made. | -| stopHeaderFilterEditMode | () => void | Stops the edit mode for the current field. | -| stopRowEditMode | (params: GridStopRowEditModeParams) => void | Puts the row corresponding to the given id and into view mode and updates the original row with the new values stored.
If `params.ignoreModifications` is `true` it will discard the modifications made. | -| subscribeEvent | <E extends GridEvents>(event: E, handler: GridEventListener<E>, options?: EventListenerOptions) => () => void | Registers a handler for an event. | -| toggleColumnMenu | (field: string) => void | Toggles the column menu under the `field` column. | -| toggleDetailPanel [](/x/introduction/licensing/#pro-plan) | (id: GridRowId) => void | Expands or collapses the detail panel of a row. | -| unpinColumn [](/x/introduction/licensing/#pro-plan) | (field: string) => void | Unpins a column. | -| unstable_replaceRows | (firstRowToReplace: number, newRows: GridRowModel[]) => void | Replace a set of rows with new rows. | -| unstable_setColumnVirtualization | (enabled: boolean) => void | Enable/disable column virtualization. | -| unstable_setPinnedRows [](/x/introduction/licensing/#pro-plan) | (pinnedRows?: GridPinnedRowsProp) => void | Changes the pinned rows. | -| unstable_setVirtualization | (enabled: boolean) => void | Enable/disable virtualization. | -| updateColumns | (cols: GridColDef[]) => void | Updates the definition of multiple columns at the same time. | -| updateRows | (updates: GridRowModelUpdate[]) => void | Allows to update, insert and delete rows. | -| upsertFilterItem | (item: GridFilterItem) => void | Updates or inserts a [GridFilterItem](/x/api/data-grid/grid-filter-item/). | -| upsertFilterItems | (items: GridFilterItem[]) => void | Updates or inserts many [GridFilterItem](/x/api/data-grid/grid-filter-item/). | diff --git a/docs/pages/x/api/data-grid/grid-cell-params.js b/docs/pages/x/api/data-grid/grid-cell-params.js index aa00cd5368325..cd53f73a76ff5 100644 --- a/docs/pages/x/api/data-grid/grid-cell-params.js +++ b/docs/pages/x/api/data-grid/grid-cell-params.js @@ -1,7 +1,26 @@ import * as React from 'react'; -import MarkdownDocs from '@mui/monorepo/docs/src/modules/components/MarkdownDocs'; -import * as pageProps from './grid-cell-params.md?muiMarkdown'; +import InterfaceApiPage from 'docsx/src/modules/components/InterfaceApiPage'; +import layoutConfig from 'docsx/src/modules/utils/dataGridLayoutConfig'; +import mapApiPageTranslations from 'docs/src/modules/utils/mapApiPageTranslations'; +import jsonPageContent from './grid-cell-params.json'; -export default function Page() { - return ; +export default function Page(props) { + const { descriptions, pageContent } = props; + return ( + + ); } + +Page.getInitialProps = () => { + const req = require.context( + 'docsx/translations/api-docs/data-grid/', + false, + /\.\/grid-cell-params.*.json$/, + ); + const descriptions = mapApiPageTranslations(req); + + return { + descriptions, + pageContent: jsonPageContent, + }; +}; diff --git a/docs/pages/x/api/data-grid/grid-cell-params.json b/docs/pages/x/api/data-grid/grid-cell-params.json new file mode 100644 index 0000000000000..ff6ddfd6dd02d --- /dev/null +++ b/docs/pages/x/api/data-grid/grid-cell-params.json @@ -0,0 +1,21 @@ +{ + "name": "GridCellParams", + "imports": [ + "import { GridCellParams } from '@mui/x-data-grid-premium'", + "import { GridCellParams } from '@mui/x-data-grid-pro'", + "import { GridCellParams } from '@mui/x-data-grid'" + ], + "properties": { + "cellMode": { "type": { "description": "GridCellMode" }, "required": true }, + "colDef": { "type": { "description": "GridStateColDef" }, "required": true }, + "field": { "type": { "description": "string" }, "required": true }, + "hasFocus": { "type": { "description": "boolean" }, "required": true }, + "id": { "type": { "description": "GridRowId" }, "required": true }, + "row": { "type": { "description": "GridRowModel<R>" }, "required": true }, + "rowNode": { "type": { "description": "N" }, "required": true }, + "tabIndex": { "type": { "description": "0 | -1" }, "required": true }, + "formattedValue": { "type": { "description": "F | undefined" } }, + "isEditable": { "type": { "description": "boolean" } }, + "value": { "type": { "description": "V | undefined" } } + } +} diff --git a/docs/pages/x/api/data-grid/grid-cell-params.md b/docs/pages/x/api/data-grid/grid-cell-params.md deleted file mode 100644 index abafc29de75ff..0000000000000 --- a/docs/pages/x/api/data-grid/grid-cell-params.md +++ /dev/null @@ -1,29 +0,0 @@ -# GridCellParams Interface - -

Object passed as parameter in the column GridColDef cell renderer.

- -## Import - -```js -import { GridCellParams } from '@mui/x-data-grid-premium'; -// or -import { GridCellParams } from '@mui/x-data-grid-pro'; -// or -import { GridCellParams } from '@mui/x-data-grid'; -``` - -## Properties - -| Name | Type | Description | -| :----------------------------------------------------------------------------------------------- | :--------------------------------------------------- | :---------------------------------------------------------------------------------------------------- | -| cellMode | GridCellMode | The mode of the cell. | -| colDef | GridStateColDef | The column of the row that the current cell belongs to. | -| field | string | The column field of the cell that triggered the event. | -| formattedValue? | F \| undefined | The cell value formatted with the column valueFormatter. | -| hasFocus | boolean | If true, the cell is the active element. | -| id | GridRowId | The grid row id. | -| isEditable? | boolean | If true, the cell is editable. | -| row | GridRowModel<R> | The row model of the row that the current cell belongs to. | -| rowNode | N | The node of the row that the current cell belongs to. | -| tabIndex | 0 \| -1 | the tabIndex value. | -| value? | V \| undefined | The cell value.
If the column has `valueGetter`, use `params.row` to directly access the fields. | diff --git a/docs/pages/x/api/data-grid/grid-col-def.js b/docs/pages/x/api/data-grid/grid-col-def.js index 01c423562290e..ffdbb477ddcb8 100644 --- a/docs/pages/x/api/data-grid/grid-col-def.js +++ b/docs/pages/x/api/data-grid/grid-col-def.js @@ -1,7 +1,26 @@ import * as React from 'react'; -import MarkdownDocs from '@mui/monorepo/docs/src/modules/components/MarkdownDocs'; -import * as pageProps from './grid-col-def.md?muiMarkdown'; +import InterfaceApiPage from 'docsx/src/modules/components/InterfaceApiPage'; +import layoutConfig from 'docsx/src/modules/utils/dataGridLayoutConfig'; +import mapApiPageTranslations from 'docs/src/modules/utils/mapApiPageTranslations'; +import jsonPageContent from './grid-col-def.json'; -export default function Page() { - return ; +export default function Page(props) { + const { descriptions, pageContent } = props; + return ( + + ); } + +Page.getInitialProps = () => { + const req = require.context( + 'docsx/translations/api-docs/data-grid/', + false, + /\.\/grid-col-def.*.json$/, + ); + const descriptions = mapApiPageTranslations(req); + + return { + descriptions, + pageContent: jsonPageContent, + }; +}; diff --git a/docs/pages/x/api/data-grid/grid-col-def.json b/docs/pages/x/api/data-grid/grid-col-def.json new file mode 100644 index 0000000000000..6173cc8c314e2 --- /dev/null +++ b/docs/pages/x/api/data-grid/grid-col-def.json @@ -0,0 +1,93 @@ +{ + "name": "GridColDef", + "imports": [ + "import { GridColDef } from '@mui/x-data-grid-premium'", + "import { GridColDef } from '@mui/x-data-grid-pro'", + "import { GridColDef } from '@mui/x-data-grid'" + ], + "demos": "", + "properties": { + "field": { "type": { "description": "string" }, "required": true }, + "aggregable": { + "type": { "description": "boolean" }, + "default": "true", + "isPremiumPlan": true + }, + "align": { "type": { "description": "GridAlignment" } }, + "availableAggregationFunctions": { + "type": { "description": "string[]" }, + "isPremiumPlan": true + }, + "cellClassName": { "type": { "description": "GridCellClassNamePropType<R, V>" } }, + "colSpan": { + "type": { "description": "number | GridColSpanFn<R, V, F>" }, + "default": "1" + }, + "description": { "type": { "description": "string" } }, + "disableColumnMenu": { "type": { "description": "boolean" }, "default": "false" }, + "disableExport": { "type": { "description": "boolean" }, "default": "false" }, + "disableReorder": { "type": { "description": "boolean" }, "default": "false" }, + "display": { "type": { "description": "'text' | 'flex'" } }, + "editable": { "type": { "description": "boolean" }, "default": "false" }, + "filterable": { "type": { "description": "boolean" }, "default": "true" }, + "filterOperators": { "type": { "description": "GridFilterOperator<R, V, F>[]" } }, + "flex": { "type": { "description": "number" } }, + "getApplyQuickFilterFn": { "type": { "description": "GetApplyQuickFilterFn<R, V>" } }, + "getSortComparator": { + "type": { + "description": "(sortDirection: GridSortDirection) => GridComparatorFn<V> | undefined" + } + }, + "groupable": { "type": { "description": "boolean" }, "default": "true" }, + "groupingValueGetter": { + "type": { "description": "GridGroupingValueGetter<R>" }, + "isPremiumPlan": true + }, + "headerAlign": { "type": { "description": "GridAlignment" } }, + "headerClassName": { "type": { "description": "GridColumnHeaderClassNamePropType" } }, + "headerName": { "type": { "description": "string" } }, + "hideable": { "type": { "description": "boolean" }, "default": "true" }, + "hideSortIcons": { "type": { "description": "boolean" }, "default": "false" }, + "maxWidth": { "type": { "description": "number" }, "default": "Infinity" }, + "minWidth": { "type": { "description": "number" }, "default": "50" }, + "pastedValueParser": { + "type": { "description": "GridPastedValueParser<R, V, F>" }, + "isPremiumPlan": true + }, + "pinnable": { "type": { "description": "boolean" }, "default": "true" }, + "preProcessEditCellProps": { + "type": { + "description": "(params: GridPreProcessEditCellProps) => GridEditCellProps | Promise<GridEditCellProps>" + } + }, + "renderCell": { + "type": { + "description": "(params: GridRenderCellParams<R, V, F>) => React.ReactNode" + } + }, + "renderEditCell": { + "type": { + "description": "(params: GridRenderEditCellParams<R, V, F>) => React.ReactNode" + } + }, + "renderHeader": { + "type": { + "description": "(params: GridColumnHeaderParams<R, V, F>) => React.ReactNode" + } + }, + "renderHeaderFilter": { + "type": { "description": "(params: GridRenderHeaderFilterProps) => React.ReactNode" }, + "isProPlan": true + }, + "resizable": { "type": { "description": "boolean" }, "default": "true" }, + "sortable": { "type": { "description": "boolean" }, "default": "true" }, + "sortComparator": { "type": { "description": "GridComparatorFn<V>" } }, + "sortingOrder": { "type": { "description": "GridSortDirection[]" } }, + "type": { "type": { "description": "GridColType" }, "default": "'singleSelect'" }, + "valueFormatter": { "type": { "description": "GridValueFormatter<R, V, F>" } }, + "valueGetter": { "type": { "description": "GridValueGetter<R, V, F>" } }, + "valueParser": { "type": { "description": "GridValueParser<R, V, F>" } }, + "valueSetter": { "type": { "description": "GridValueSetter<R, V, F>" } }, + "width": { "type": { "description": "number" }, "default": "100" } + } +} diff --git a/docs/pages/x/api/data-grid/grid-col-def.md b/docs/pages/x/api/data-grid/grid-col-def.md deleted file mode 100644 index b8927910ff2e4..0000000000000 --- a/docs/pages/x/api/data-grid/grid-col-def.md +++ /dev/null @@ -1,70 +0,0 @@ -# GridColDef Interface - -

Column Definition interface.

- -## Demos - -:::info -For examples and details on the usage, check the following pages: - -- [Column definition](/x/react-data-grid/column-definition/) - -::: - -## Import - -```js -import { GridColDef } from '@mui/x-data-grid-premium'; -// or -import { GridColDef } from '@mui/x-data-grid-pro'; -// or -import { GridColDef } from '@mui/x-data-grid'; -``` - -## Properties - -| Name | Type | Default | Description | -| :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------- | :----------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| aggregable? [](/x/introduction/licensing/#premium-plan) | boolean | true | If `true`, the cells of the column can be aggregated based. | -| align? | GridAlignment | | Allows to align the column values in cells. | -| availableAggregationFunctions? [](/x/introduction/licensing/#premium-plan) | string[] | | Limit the aggregation function usable on this column.
By default, the column will have all the aggregation functions that are compatible with its type. | -| cellClassName? | GridCellClassNamePropType<R, V> | | Class name that will be added in cells for that column. | -| colSpan? | number \| GridColSpanFn<R, V, F> | 1 | Number of columns a cell should span. | -| description? | string | | The description of the column rendered as tooltip if the column header name is not fully displayed. | -| disableColumnMenu? | boolean | false | If `true`, the column menu is disabled for this column. | -| disableExport? | boolean | false | If `true`, this column will not be included in exports. | -| disableReorder? | boolean | false | If `true`, this column cannot be reordered. | -| display? | 'text' \| 'flex' | | Display mode for the cell:
- 'text': For text-based cells (default)
- 'flex': For cells with HTMLElement children | -| editable? | boolean | false | If `true`, the cells of the column are editable. | -| field | string | | The column identifier. It's used to map with GridRowModel values. | -| filterable? | boolean | true | If `true`, the column is filterable. | -| filterOperators? | GridFilterOperator<R, V, F>[] | | Allows setting the filter operators for this column. | -| flex? | number | | If set, it indicates that a column has fluid width. Range [0, ∞). | -| getApplyQuickFilterFn? | GetApplyQuickFilterFn<R, V> | | The callback that generates a filtering function for a given quick filter value.
This function can return `null` to skip filtering for this value and column. | -| getSortComparator? | (sortDirection: GridSortDirection) => GridComparatorFn<V> \| undefined | | Allows to use a different comparator function depending on the sort direction.
Takes precedence over `sortComparator`. | -| groupable? | boolean | true | If `true`, the rows can be grouped based on this column values (pro-plan only).
Only available in DataGridPremium. | -| groupingValueGetter? [](/x/introduction/licensing/#premium-plan) | GridGroupingValueGetter<R> | | Function that transforms a complex cell value into a key that be used for grouping the rows. | -| headerAlign? | GridAlignment | | Header cell element alignment. | -| headerClassName? | GridColumnHeaderClassNamePropType | | Class name that will be added in the column header cell. | -| headerName? | string | | The title of the column rendered in the column header cell. | -| hideable? | boolean | true | If `false`, removes the buttons for hiding this column. | -| hideSortIcons? | boolean | false | Toggle the visibility of the sort icons. | -| maxWidth? | number | Infinity | Sets the maximum width of a column. | -| minWidth? | number | 50 | Sets the minimum width of a column. | -| pastedValueParser? [](/x/introduction/licensing/#premium-plan) | GridPastedValueParser<R, V, F> | | Function that takes the clipboard-pasted value and converts it to a value used internally. | -| pinnable? | boolean | true | If `false`, the menu items for column pinning menu will not be rendered.
Only available in DataGridPro. | -| preProcessEditCellProps? | (params: GridPreProcessEditCellProps) => GridEditCellProps \| Promise<GridEditCellProps> | | Callback fired when the edit props of the cell changes.
It allows to process the props that saved into the state. | -| renderCell? | (params: GridRenderCellParams<R, V, F>) => React.ReactNode | | Allows to override the component rendered as cell for this column. | -| renderEditCell? | (params: GridRenderEditCellParams<R, V, F>) => React.ReactNode | | Allows to override the component rendered in edit cell mode for this column. | -| renderHeader? | (params: GridColumnHeaderParams<R, V, F>) => React.ReactNode | | Allows to render a component in the column header cell. | -| renderHeaderFilter? [](/x/introduction/licensing/#pro-plan) | (params: GridRenderHeaderFilterProps) => React.ReactNode | | Allows to render a component in the column header filter cell. | -| resizable? | boolean | true | If `true`, the column is resizable. | -| sortable? | boolean | true | If `true`, the column is sortable. | -| sortComparator? | GridComparatorFn<V> | | A comparator function used to sort rows. | -| sortingOrder? | GridSortDirection[] | | The order of the sorting sequence. | -| type? | GridColType | 'singleSelect' | The type of the column. | -| valueFormatter? | GridValueFormatter<R, V, F> | | Function that allows to apply a formatter before rendering its value. | -| valueGetter? | GridValueGetter<R, V, F> | | Function that allows to get a specific data instead of field to render in the cell. | -| valueParser? | GridValueParser<R, V, F> | | Function that takes the user-entered value and converts it to a value used internally. | -| valueSetter? | GridValueSetter<R, V, F> | | Function that allows to customize how the entered value is stored in the row.
It only works with cell/row editing. | -| width? | number | 100 | Set the width of the column. | diff --git a/docs/pages/x/api/data-grid/grid-csv-export-options.js b/docs/pages/x/api/data-grid/grid-csv-export-options.js index 6063630516517..782c8b7cbb967 100644 --- a/docs/pages/x/api/data-grid/grid-csv-export-options.js +++ b/docs/pages/x/api/data-grid/grid-csv-export-options.js @@ -1,7 +1,26 @@ import * as React from 'react'; -import MarkdownDocs from '@mui/monorepo/docs/src/modules/components/MarkdownDocs'; -import * as pageProps from './grid-csv-export-options.md?muiMarkdown'; +import InterfaceApiPage from 'docsx/src/modules/components/InterfaceApiPage'; +import layoutConfig from 'docsx/src/modules/utils/dataGridLayoutConfig'; +import mapApiPageTranslations from 'docs/src/modules/utils/mapApiPageTranslations'; +import jsonPageContent from './grid-csv-export-options.json'; -export default function Page() { - return ; +export default function Page(props) { + const { descriptions, pageContent } = props; + return ( + + ); } + +Page.getInitialProps = () => { + const req = require.context( + 'docsx/translations/api-docs/data-grid/', + false, + /\.\/grid-csv-export-options.*.json$/, + ); + const descriptions = mapApiPageTranslations(req); + + return { + descriptions, + pageContent: jsonPageContent, + }; +}; diff --git a/docs/pages/x/api/data-grid/grid-csv-export-options.json b/docs/pages/x/api/data-grid/grid-csv-export-options.json new file mode 100644 index 0000000000000..c8ec2874beb75 --- /dev/null +++ b/docs/pages/x/api/data-grid/grid-csv-export-options.json @@ -0,0 +1,21 @@ +{ + "name": "GridCsvExportOptions", + "imports": [ + "import { GridCsvExportOptions } from '@mui/x-data-grid-premium'", + "import { GridCsvExportOptions } from '@mui/x-data-grid-pro'", + "import { GridCsvExportOptions } from '@mui/x-data-grid'" + ], + "demos": "", + "properties": { + "allColumns": { "type": { "description": "boolean" }, "default": "false" }, + "delimiter": { "type": { "description": "string" }, "default": "','" }, + "fields": { "type": { "description": "string[]" } }, + "fileName": { "type": { "description": "string" }, "default": "`document.title`" }, + "getRowsToExport": { + "type": { "description": "(params: GridCsvGetRowsToExportParams) => GridRowId[]" } + }, + "includeColumnGroupsHeaders": { "type": { "description": "boolean" }, "default": "true" }, + "includeHeaders": { "type": { "description": "boolean" }, "default": "true" }, + "utf8WithBom": { "type": { "description": "boolean" }, "default": "false" } + } +} diff --git a/docs/pages/x/api/data-grid/grid-csv-export-options.md b/docs/pages/x/api/data-grid/grid-csv-export-options.md deleted file mode 100644 index e862ab57a9b36..0000000000000 --- a/docs/pages/x/api/data-grid/grid-csv-export-options.md +++ /dev/null @@ -1,35 +0,0 @@ -# GridCsvExportOptions Interface - -

The options to apply on the CSV export.

- -## Demos - -:::info -For examples and details on the usage, check the following pages: - -- [CSV export](/x/react-data-grid/export/#csv-export) - -::: - -## Import - -```js -import { GridCsvExportOptions } from '@mui/x-data-grid-premium'; -// or -import { GridCsvExportOptions } from '@mui/x-data-grid-pro'; -// or -import { GridCsvExportOptions } from '@mui/x-data-grid'; -``` - -## Properties - -| Name | Type | Default | Description | -| :----------------------------------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------- | :------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| allColumns? | boolean | false | If `true`, the hidden columns will also be exported. | -| delimiter? | string | ',' | The character used to separate fields. | -| fields? | string[] | | The columns exported.
This should only be used if you want to restrict the columns exports. | -| fileName? | string | `document.title` | The string used as the file name. | -| getRowsToExport? | (params: GridCsvGetRowsToExportParams) => GridRowId[] | | Function that returns the list of row ids to export on the order they should be exported. | -| includeColumnGroupsHeaders? | boolean | true | If `true`, the CSV will include the column groups. | -| includeHeaders? | boolean | true | If `true`, the CSV will include the column headers and column groups.
Use `includeColumnGroupsHeaders` to control whether the column groups are included. | -| utf8WithBom? | boolean | false | If `true`, the UTF-8 Byte Order Mark (BOM) prefixes the exported file.
This can allow Excel to automatically detect file encoding as UTF-8. | diff --git a/docs/pages/x/api/data-grid/grid-excel-export-options.js b/docs/pages/x/api/data-grid/grid-excel-export-options.js index 8807a36df2fe3..53b29b9b03b68 100644 --- a/docs/pages/x/api/data-grid/grid-excel-export-options.js +++ b/docs/pages/x/api/data-grid/grid-excel-export-options.js @@ -1,7 +1,26 @@ import * as React from 'react'; -import MarkdownDocs from '@mui/monorepo/docs/src/modules/components/MarkdownDocs'; -import * as pageProps from './grid-excel-export-options.md?muiMarkdown'; +import InterfaceApiPage from 'docsx/src/modules/components/InterfaceApiPage'; +import layoutConfig from 'docsx/src/modules/utils/dataGridLayoutConfig'; +import mapApiPageTranslations from 'docs/src/modules/utils/mapApiPageTranslations'; +import jsonPageContent from './grid-excel-export-options.json'; -export default function Page() { - return ; +export default function Page(props) { + const { descriptions, pageContent } = props; + return ( + + ); } + +Page.getInitialProps = () => { + const req = require.context( + 'docsx/translations/api-docs/data-grid/', + false, + /\.\/grid-excel-export-options.*.json$/, + ); + const descriptions = mapApiPageTranslations(req); + + return { + descriptions, + pageContent: jsonPageContent, + }; +}; diff --git a/docs/pages/x/api/data-grid/grid-excel-export-options.json b/docs/pages/x/api/data-grid/grid-excel-export-options.json new file mode 100644 index 0000000000000..8df7897c3fd4d --- /dev/null +++ b/docs/pages/x/api/data-grid/grid-excel-export-options.json @@ -0,0 +1,47 @@ +{ + "name": "GridExcelExportOptions", + "imports": ["import { GridExcelExportOptions } from '@mui/x-data-grid-premium'"], + "demos": "", + "properties": { + "allColumns": { + "type": { "description": "boolean" }, + "default": "false", + "isPremiumPlan": true + }, + "columnsStyles": { "type": { "description": "ColumnsStylesInterface" }, "isPremiumPlan": true }, + "exceljsPostProcess": { + "type": { + "description": "(processInput: GridExceljsProcessInput) => Promise<void>" + }, + "isPremiumPlan": true + }, + "exceljsPreProcess": { + "type": { + "description": "(processInput: GridExceljsProcessInput) => Promise<void>" + }, + "isPremiumPlan": true + }, + "fields": { "type": { "description": "string[]" }, "isPremiumPlan": true }, + "fileName": { + "type": { "description": "string" }, + "default": "`document.title`", + "isPremiumPlan": true + }, + "getRowsToExport": { + "type": { "description": "(params: GridGetRowsToExportParams<Api>) => GridRowId[]" }, + "isPremiumPlan": true + }, + "includeColumnGroupsHeaders": { + "type": { "description": "boolean" }, + "default": "true", + "isPremiumPlan": true + }, + "includeHeaders": { + "type": { "description": "boolean" }, + "default": "true", + "isPremiumPlan": true + }, + "valueOptionsSheetName": { "type": { "description": "string" }, "isPremiumPlan": true }, + "worker": { "type": { "description": "() => Worker" }, "isPremiumPlan": true } + } +} diff --git a/docs/pages/x/api/data-grid/grid-excel-export-options.md b/docs/pages/x/api/data-grid/grid-excel-export-options.md deleted file mode 100644 index ee4f465bcffa9..0000000000000 --- a/docs/pages/x/api/data-grid/grid-excel-export-options.md +++ /dev/null @@ -1,34 +0,0 @@ -# GridExcelExportOptions Interface - -

The options to apply on the Excel export.

- -## Demos - -:::info -For examples and details on the usage, check the following pages: - -- [Excel export](/x/react-data-grid/export/#excel-export) - -::: - -## Import - -```js -import { GridExcelExportOptions } from '@mui/x-data-grid-premium'; -``` - -## Properties - -| Name | Type | Default | Description | -| :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :----------------------------------------------------------------------------------------------- | :------------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| allColumns? [](/x/introduction/licensing/#premium-plan) | boolean | false | If `true`, the hidden columns will also be exported. | -| columnsStyles? [](/x/introduction/licensing/#premium-plan) | ColumnsStylesInterface | | Object mapping column field to Exceljs style | -| exceljsPostProcess? [](/x/introduction/licensing/#premium-plan) | (processInput: GridExceljsProcessInput) => Promise<void> | | Method called after adding the rows to the workbook.
Not supported when `worker` is set.
To use with web workers, use the option in `setupExcelExportWebWorker`. | -| exceljsPreProcess? [](/x/introduction/licensing/#premium-plan) | (processInput: GridExceljsProcessInput) => Promise<void> | | Method called before adding the rows to the workbook.
Not supported when `worker` is set.
To use with web workers, use the option in `setupExcelExportWebWorker`. | -| fields? [](/x/introduction/licensing/#premium-plan) | string[] | | The columns exported.
This should only be used if you want to restrict the columns exports. | -| fileName? [](/x/introduction/licensing/#premium-plan) | string | `document.title` | The string used as the file name. | -| getRowsToExport? [](/x/introduction/licensing/#premium-plan) | (params: GridGetRowsToExportParams<Api>) => GridRowId[] | | Function that returns the list of row ids to export on the order they should be exported. | -| includeColumnGroupsHeaders? [](/x/introduction/licensing/#premium-plan) | boolean | true | If `true`, the headers of the column groups will be added into the file. | -| includeHeaders? [](/x/introduction/licensing/#premium-plan) | boolean | true | If `true`, the first row of the file will include the headers of the grid. | -| valueOptionsSheetName? [](/x/introduction/licensing/#premium-plan) | string | | Name given to the worksheet containing the columns valueOptions.
valueOptions are added to this worksheet if they are provided as an array. | -| worker? [](/x/introduction/licensing/#premium-plan) | () => Worker | | Function to return the Worker instance to be called. | diff --git a/docs/pages/x/api/data-grid/grid-export-state-params.js b/docs/pages/x/api/data-grid/grid-export-state-params.js index e1f093bdb24ec..2aed47dee2a54 100644 --- a/docs/pages/x/api/data-grid/grid-export-state-params.js +++ b/docs/pages/x/api/data-grid/grid-export-state-params.js @@ -1,7 +1,26 @@ import * as React from 'react'; -import MarkdownDocs from '@mui/monorepo/docs/src/modules/components/MarkdownDocs'; -import * as pageProps from './grid-export-state-params.md?muiMarkdown'; +import InterfaceApiPage from 'docsx/src/modules/components/InterfaceApiPage'; +import layoutConfig from 'docsx/src/modules/utils/dataGridLayoutConfig'; +import mapApiPageTranslations from 'docs/src/modules/utils/mapApiPageTranslations'; +import jsonPageContent from './grid-export-state-params.json'; -export default function Page() { - return ; +export default function Page(props) { + const { descriptions, pageContent } = props; + return ( + + ); } + +Page.getInitialProps = () => { + const req = require.context( + 'docsx/translations/api-docs/data-grid/', + false, + /\.\/grid-export-state-params.*.json$/, + ); + const descriptions = mapApiPageTranslations(req); + + return { + descriptions, + pageContent: jsonPageContent, + }; +}; diff --git a/docs/pages/x/api/data-grid/grid-export-state-params.json b/docs/pages/x/api/data-grid/grid-export-state-params.json new file mode 100644 index 0000000000000..5c34d3ef7b1dd --- /dev/null +++ b/docs/pages/x/api/data-grid/grid-export-state-params.json @@ -0,0 +1,12 @@ +{ + "name": "GridExportStateParams", + "imports": [ + "import { GridExportStateParams } from '@mui/x-data-grid-premium'", + "import { GridExportStateParams } from '@mui/x-data-grid-pro'", + "import { GridExportStateParams } from '@mui/x-data-grid'" + ], + "demos": "", + "properties": { + "exportOnlyDirtyModels": { "type": { "description": "boolean" }, "default": "false" } + } +} diff --git a/docs/pages/x/api/data-grid/grid-export-state-params.md b/docs/pages/x/api/data-grid/grid-export-state-params.md deleted file mode 100644 index 7ac92feb158df..0000000000000 --- a/docs/pages/x/api/data-grid/grid-export-state-params.md +++ /dev/null @@ -1,28 +0,0 @@ -# GridExportStateParams Interface - -

Object passed as parameter in the `exportState()` grid API method.

- -## Demos - -:::info -For examples and details on the usage, check the following pages: - -- [Restore state with `apiRef`](/x/react-data-grid/state/#restore-the-state-with-apiref) - -::: - -## Import - -```js -import { GridExportStateParams } from '@mui/x-data-grid-premium'; -// or -import { GridExportStateParams } from '@mui/x-data-grid-pro'; -// or -import { GridExportStateParams } from '@mui/x-data-grid'; -``` - -## Properties - -| Name | Type | Default | Description | -| :------------------------------------------------------------------------------------------------------ | :------------------------------------- | :-------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| exportOnlyDirtyModels? | boolean | false | By default, the grid exports all the models.
You can switch this property to `true` to only exports models that are either controlled, initialized or modified.
For instance, with this property, if you don't control or initialize the `filterModel` and you did not apply any filter, the model won't be exported.
Note that the column dimensions are not a model. The grid only exports the dimensions of the modified columns even when `exportOnlyDirtyModels` is false. | diff --git a/docs/pages/x/api/data-grid/grid-filter-item.js b/docs/pages/x/api/data-grid/grid-filter-item.js index 0e496ac37ad72..de27ba795f3f9 100644 --- a/docs/pages/x/api/data-grid/grid-filter-item.js +++ b/docs/pages/x/api/data-grid/grid-filter-item.js @@ -1,7 +1,26 @@ import * as React from 'react'; -import MarkdownDocs from '@mui/monorepo/docs/src/modules/components/MarkdownDocs'; -import * as pageProps from './grid-filter-item.md?muiMarkdown'; +import InterfaceApiPage from 'docsx/src/modules/components/InterfaceApiPage'; +import layoutConfig from 'docsx/src/modules/utils/dataGridLayoutConfig'; +import mapApiPageTranslations from 'docs/src/modules/utils/mapApiPageTranslations'; +import jsonPageContent from './grid-filter-item.json'; -export default function Page() { - return ; +export default function Page(props) { + const { descriptions, pageContent } = props; + return ( + + ); } + +Page.getInitialProps = () => { + const req = require.context( + 'docsx/translations/api-docs/data-grid/', + false, + /\.\/grid-filter-item.*.json$/, + ); + const descriptions = mapApiPageTranslations(req); + + return { + descriptions, + pageContent: jsonPageContent, + }; +}; diff --git a/docs/pages/x/api/data-grid/grid-filter-item.json b/docs/pages/x/api/data-grid/grid-filter-item.json new file mode 100644 index 0000000000000..85bb433433096 --- /dev/null +++ b/docs/pages/x/api/data-grid/grid-filter-item.json @@ -0,0 +1,15 @@ +{ + "name": "GridFilterItem", + "imports": [ + "import { GridFilterItem } from '@mui/x-data-grid-premium'", + "import { GridFilterItem } from '@mui/x-data-grid-pro'", + "import { GridFilterItem } from '@mui/x-data-grid'" + ], + "demos": "", + "properties": { + "field": { "type": { "description": "string" }, "required": true }, + "operator": { "type": { "description": "string" }, "required": true }, + "id": { "type": { "description": "number | string" } }, + "value": { "type": { "description": "any" } } + } +} diff --git a/docs/pages/x/api/data-grid/grid-filter-item.md b/docs/pages/x/api/data-grid/grid-filter-item.md deleted file mode 100644 index 0f9ccd97bfd73..0000000000000 --- a/docs/pages/x/api/data-grid/grid-filter-item.md +++ /dev/null @@ -1,31 +0,0 @@ -# GridFilterItem Interface - -

Filter item definition interface.

- -## Demos - -:::info -For examples and details on the usage, check the following pages: - -- [Custom filter operator](/x/react-data-grid/filtering/customization/#create-a-custom-operator) - -::: - -## Import - -```js -import { GridFilterItem } from '@mui/x-data-grid-premium'; -// or -import { GridFilterItem } from '@mui/x-data-grid-pro'; -// or -import { GridFilterItem } from '@mui/x-data-grid'; -``` - -## Properties - -| Name | Type | Description | -| :-------------------------------------------------------------------------------------- | :---------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------- | -| field | string | The column from which we want to filter the rows. | -| id? | number \| string | Must be unique.
Only useful when the model contains several items. | -| operator | string | The name of the operator we want to apply. | -| value? | any | The filtering value.
The operator filtering function will decide for each row if the row values is correct compared to this value. | diff --git a/docs/pages/x/api/data-grid/grid-filter-model.js b/docs/pages/x/api/data-grid/grid-filter-model.js index 4e4fb6f1cfe42..391130de78314 100644 --- a/docs/pages/x/api/data-grid/grid-filter-model.js +++ b/docs/pages/x/api/data-grid/grid-filter-model.js @@ -1,7 +1,26 @@ import * as React from 'react'; -import MarkdownDocs from '@mui/monorepo/docs/src/modules/components/MarkdownDocs'; -import * as pageProps from './grid-filter-model.md?muiMarkdown'; +import InterfaceApiPage from 'docsx/src/modules/components/InterfaceApiPage'; +import layoutConfig from 'docsx/src/modules/utils/dataGridLayoutConfig'; +import mapApiPageTranslations from 'docs/src/modules/utils/mapApiPageTranslations'; +import jsonPageContent from './grid-filter-model.json'; -export default function Page() { - return ; +export default function Page(props) { + const { descriptions, pageContent } = props; + return ( + + ); } + +Page.getInitialProps = () => { + const req = require.context( + 'docsx/translations/api-docs/data-grid/', + false, + /\.\/grid-filter-model.*.json$/, + ); + const descriptions = mapApiPageTranslations(req); + + return { + descriptions, + pageContent: jsonPageContent, + }; +}; diff --git a/docs/pages/x/api/data-grid/grid-filter-model.json b/docs/pages/x/api/data-grid/grid-filter-model.json new file mode 100644 index 0000000000000..c67155f35a6b7 --- /dev/null +++ b/docs/pages/x/api/data-grid/grid-filter-model.json @@ -0,0 +1,22 @@ +{ + "name": "GridFilterModel", + "imports": [ + "import { GridFilterModel } from '@mui/x-data-grid-premium'", + "import { GridFilterModel } from '@mui/x-data-grid-pro'", + "import { GridFilterModel } from '@mui/x-data-grid'" + ], + "demos": "", + "properties": { + "items": { "type": { "description": "GridFilterItem[]" }, "default": "[]", "required": true }, + "logicOperator": { + "type": { "description": "GridLogicOperator" }, + "default": "`GridLogicOperator.And`" + }, + "quickFilterExcludeHiddenColumns": { "type": { "description": "boolean" }, "default": "true" }, + "quickFilterLogicOperator": { + "type": { "description": "GridLogicOperator" }, + "default": "`GridLogicOperator.And`" + }, + "quickFilterValues": { "type": { "description": "any[]" }, "default": "`[]`" } + } +} diff --git a/docs/pages/x/api/data-grid/grid-filter-model.md b/docs/pages/x/api/data-grid/grid-filter-model.md deleted file mode 100644 index 621d3039abc61..0000000000000 --- a/docs/pages/x/api/data-grid/grid-filter-model.md +++ /dev/null @@ -1,32 +0,0 @@ -# GridFilterModel Interface - -

Model describing the filters to apply to the grid.

- -## Demos - -:::info -For examples and details on the usage, check the following pages: - -- [Pass filters to the grid](/x/react-data-grid/filtering/#pass-filters-to-the-data-grid) - -::: - -## Import - -```js -import { GridFilterModel } from '@mui/x-data-grid-premium'; -// or -import { GridFilterModel } from '@mui/x-data-grid-pro'; -// or -import { GridFilterModel } from '@mui/x-data-grid'; -``` - -## Properties - -| Name | Type | Default | Description | -| :---------------------------------------------------------------------------------------------------------------- | :----------------------------------------------- | :-------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------- | -| items | GridFilterItem[] | [] | | -| logicOperator? | GridLogicOperator | `GridLogicOperator.And` | - `GridLogicOperator.And`: the row must pass all the filter items.
- `GridLogicOperator.Or`: the row must pass at least on filter item. | -| quickFilterExcludeHiddenColumns? | boolean | true | If `false`, the quick filter will also consider cell values from hidden columns. | -| quickFilterLogicOperator? | GridLogicOperator | `GridLogicOperator.And` | - `GridLogicOperator.And`: the row must pass all the values.
- `GridLogicOperator.Or`: the row must pass at least one value. | -| quickFilterValues? | any[] | `[]` | values used to quick filter rows | diff --git a/docs/pages/x/api/data-grid/grid-filter-operator.js b/docs/pages/x/api/data-grid/grid-filter-operator.js index 6f8a943208801..a9e1bb931eb7e 100644 --- a/docs/pages/x/api/data-grid/grid-filter-operator.js +++ b/docs/pages/x/api/data-grid/grid-filter-operator.js @@ -1,7 +1,26 @@ import * as React from 'react'; -import MarkdownDocs from '@mui/monorepo/docs/src/modules/components/MarkdownDocs'; -import * as pageProps from './grid-filter-operator.md?muiMarkdown'; +import InterfaceApiPage from 'docsx/src/modules/components/InterfaceApiPage'; +import layoutConfig from 'docsx/src/modules/utils/dataGridLayoutConfig'; +import mapApiPageTranslations from 'docs/src/modules/utils/mapApiPageTranslations'; +import jsonPageContent from './grid-filter-operator.json'; -export default function Page() { - return ; +export default function Page(props) { + const { descriptions, pageContent } = props; + return ( + + ); } + +Page.getInitialProps = () => { + const req = require.context( + 'docsx/translations/api-docs/data-grid/', + false, + /\.\/grid-filter-operator.*.json$/, + ); + const descriptions = mapApiPageTranslations(req); + + return { + descriptions, + pageContent: jsonPageContent, + }; +}; diff --git a/docs/pages/x/api/data-grid/grid-filter-operator.json b/docs/pages/x/api/data-grid/grid-filter-operator.json new file mode 100644 index 0000000000000..bde12a0cc644e --- /dev/null +++ b/docs/pages/x/api/data-grid/grid-filter-operator.json @@ -0,0 +1,24 @@ +{ + "name": "GridFilterOperator", + "imports": [ + "import { GridFilterOperator } from '@mui/x-data-grid-premium'", + "import { GridFilterOperator } from '@mui/x-data-grid-pro'", + "import { GridFilterOperator } from '@mui/x-data-grid'" + ], + "demos": "", + "properties": { + "getApplyFilterFn": { + "type": { "description": "GetApplyFilterFn<R, V, F>" }, + "required": true + }, + "value": { "type": { "description": "string" }, "required": true }, + "getValueAsString": { + "type": { "description": "(value: GridFilterItem['value']) => string" } + }, + "headerLabel": { "type": { "description": "string" } }, + "InputComponent": { "type": { "description": "React.JSXElementConstructor<any>" } }, + "InputComponentProps": { "type": { "description": "Record<string, any>" } }, + "label": { "type": { "description": "string" } }, + "requiresFilterValue": { "type": { "description": "boolean" }, "default": "true" } + } +} diff --git a/docs/pages/x/api/data-grid/grid-filter-operator.md b/docs/pages/x/api/data-grid/grid-filter-operator.md deleted file mode 100644 index 9cdcdb86d29cf..0000000000000 --- a/docs/pages/x/api/data-grid/grid-filter-operator.md +++ /dev/null @@ -1,35 +0,0 @@ -# GridFilterOperator Interface - -

Filter operator definition interface.

- -## Demos - -:::info -For examples and details on the usage, check the following pages: - -- [Custom filter operator](/x/react-data-grid/filtering/customization/#create-a-custom-operator) - -::: - -## Import - -```js -import { GridFilterOperator } from '@mui/x-data-grid-premium'; -// or -import { GridFilterOperator } from '@mui/x-data-grid-pro'; -// or -import { GridFilterOperator } from '@mui/x-data-grid'; -``` - -## Properties - -| Name | Type | Default | Description | -| :---------------------------------------------------------------------------------------------------- | :--------------------------------------------------------------------------- | :------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| getApplyFilterFn | GetApplyFilterFn<R, V, F> | | The callback that generates a filtering function for a given filter item and column.
This function can return `null` to skip filtering for this item and column. | -| getValueAsString? | (value: GridFilterItem['value']) => string | | Converts the value of a filter item to a human-readable form. | -| headerLabel? | string | | The label of the filter shown in header filter row. | -| InputComponent? | React.JSXElementConstructor<any> | | The input component to render in the filter panel for this filter operator. | -| InputComponentProps? | Record<string, any> | | The props to pass to the input component in the filter panel for this filter operator. | -| label? | string | | The label of the filter operator. | -| requiresFilterValue? | boolean | true | If `false`, filter operator doesn't require user-entered value to work.
Usually should be set to `false` for filter operators that don't have `InputComponent` (for example `isEmpty`) | -| value | string | | The name of the filter operator.
It will be matched with the `operator` property of the filter items. | diff --git a/docs/pages/x/api/data-grid/grid-print-export-options.js b/docs/pages/x/api/data-grid/grid-print-export-options.js index bf0ba5f8800d0..60999a722589b 100644 --- a/docs/pages/x/api/data-grid/grid-print-export-options.js +++ b/docs/pages/x/api/data-grid/grid-print-export-options.js @@ -1,7 +1,26 @@ import * as React from 'react'; -import MarkdownDocs from '@mui/monorepo/docs/src/modules/components/MarkdownDocs'; -import * as pageProps from './grid-print-export-options.md?muiMarkdown'; +import InterfaceApiPage from 'docsx/src/modules/components/InterfaceApiPage'; +import layoutConfig from 'docsx/src/modules/utils/dataGridLayoutConfig'; +import mapApiPageTranslations from 'docs/src/modules/utils/mapApiPageTranslations'; +import jsonPageContent from './grid-print-export-options.json'; -export default function Page() { - return ; +export default function Page(props) { + const { descriptions, pageContent } = props; + return ( + + ); } + +Page.getInitialProps = () => { + const req = require.context( + 'docsx/translations/api-docs/data-grid/', + false, + /\.\/grid-print-export-options.*.json$/, + ); + const descriptions = mapApiPageTranslations(req); + + return { + descriptions, + pageContent: jsonPageContent, + }; +}; diff --git a/docs/pages/x/api/data-grid/grid-print-export-options.json b/docs/pages/x/api/data-grid/grid-print-export-options.json new file mode 100644 index 0000000000000..6d19c1df3ffc0 --- /dev/null +++ b/docs/pages/x/api/data-grid/grid-print-export-options.json @@ -0,0 +1,23 @@ +{ + "name": "GridPrintExportOptions", + "imports": [ + "import { GridPrintExportOptions } from '@mui/x-data-grid-premium'", + "import { GridPrintExportOptions } from '@mui/x-data-grid-pro'", + "import { GridPrintExportOptions } from '@mui/x-data-grid'" + ], + "demos": "", + "properties": { + "allColumns": { "type": { "description": "boolean" }, "default": "false" }, + "bodyClassName": { "type": { "description": "string" } }, + "copyStyles": { "type": { "description": "boolean" }, "default": "true" }, + "fields": { "type": { "description": "string[]" } }, + "fileName": { "type": { "description": "string" }, "default": "The title of the page." }, + "getRowsToExport": { + "type": { "description": "(params: GridPrintGetRowsToExportParams) => GridRowId[]" } + }, + "hideFooter": { "type": { "description": "boolean" }, "default": "false" }, + "hideToolbar": { "type": { "description": "boolean" }, "default": "false" }, + "includeCheckboxes": { "type": { "description": "boolean" }, "default": "false" }, + "pageStyle": { "type": { "description": "string | Function" } } + } +} diff --git a/docs/pages/x/api/data-grid/grid-print-export-options.md b/docs/pages/x/api/data-grid/grid-print-export-options.md deleted file mode 100644 index 2106c9ec94a18..0000000000000 --- a/docs/pages/x/api/data-grid/grid-print-export-options.md +++ /dev/null @@ -1,37 +0,0 @@ -# GridPrintExportOptions Interface - -

The options to apply on the Print export.

- -## Demos - -:::info -For examples and details on the usage, check the following pages: - -- [Print export](/x/react-data-grid/export/#print-export) - -::: - -## Import - -```js -import { GridPrintExportOptions } from '@mui/x-data-grid-premium'; -// or -import { GridPrintExportOptions } from '@mui/x-data-grid-pro'; -// or -import { GridPrintExportOptions } from '@mui/x-data-grid'; -``` - -## Properties - -| Name | Type | Default | Description | -| :-------------------------------------------------------------------------------------------------- | :---------------------------------------------------------------------------------------- | :------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------- | -| allColumns? | boolean | false | If `true`, the hidden columns will also be exported. | -| bodyClassName? | string | | One or more classes passed to the print window. | -| copyStyles? | boolean | true | If `false`, all <style> and <link type="stylesheet" /> tags from the <head> will not be copied
to the print window. | -| fields? | string[] | | The columns exported.
This should only be used if you want to restrict the columns exports. | -| fileName? | string | The title of the page. | The value to be used as the print window title. | -| getRowsToExport? | (params: GridPrintGetRowsToExportParams) => GridRowId[] | | Function that returns the list of row ids to export in the order they should be exported. | -| hideFooter? | boolean | false | If `true`, the footer is removed for when printing. | -| hideToolbar? | boolean | false | If `true`, the toolbar is removed for when printing. | -| includeCheckboxes? | boolean | false | If `true`, the selection checkboxes will be included when printing. | -| pageStyle? | string \| Function | | Provide Print specific styles to the print window. | diff --git a/docs/pages/x/api/data-grid/grid-row-class-name-params.js b/docs/pages/x/api/data-grid/grid-row-class-name-params.js index 02f1a861f343f..5fac145126d24 100644 --- a/docs/pages/x/api/data-grid/grid-row-class-name-params.js +++ b/docs/pages/x/api/data-grid/grid-row-class-name-params.js @@ -1,7 +1,26 @@ import * as React from 'react'; -import MarkdownDocs from '@mui/monorepo/docs/src/modules/components/MarkdownDocs'; -import * as pageProps from './grid-row-class-name-params.md?muiMarkdown'; +import InterfaceApiPage from 'docsx/src/modules/components/InterfaceApiPage'; +import layoutConfig from 'docsx/src/modules/utils/dataGridLayoutConfig'; +import mapApiPageTranslations from 'docs/src/modules/utils/mapApiPageTranslations'; +import jsonPageContent from './grid-row-class-name-params.json'; -export default function Page() { - return ; +export default function Page(props) { + const { descriptions, pageContent } = props; + return ( + + ); } + +Page.getInitialProps = () => { + const req = require.context( + 'docsx/translations/api-docs/data-grid/', + false, + /\.\/grid-row-class-name-params.*.json$/, + ); + const descriptions = mapApiPageTranslations(req); + + return { + descriptions, + pageContent: jsonPageContent, + }; +}; diff --git a/docs/pages/x/api/data-grid/grid-row-class-name-params.json b/docs/pages/x/api/data-grid/grid-row-class-name-params.json new file mode 100644 index 0000000000000..a465debda6d70 --- /dev/null +++ b/docs/pages/x/api/data-grid/grid-row-class-name-params.json @@ -0,0 +1,17 @@ +{ + "name": "GridRowClassNameParams", + "imports": [ + "import { GridRowClassNameParams } from '@mui/x-data-grid-premium'", + "import { GridRowClassNameParams } from '@mui/x-data-grid-pro'", + "import { GridRowClassNameParams } from '@mui/x-data-grid'" + ], + "demos": "", + "properties": { + "columns": { "type": { "description": "GridColDef[]" }, "required": true }, + "id": { "type": { "description": "GridRowId" }, "required": true }, + "indexRelativeToCurrentPage": { "type": { "description": "number" }, "required": true }, + "isFirstVisible": { "type": { "description": "boolean" }, "required": true }, + "isLastVisible": { "type": { "description": "boolean" }, "required": true }, + "row": { "type": { "description": "R" }, "required": true } + } +} diff --git a/docs/pages/x/api/data-grid/grid-row-class-name-params.md b/docs/pages/x/api/data-grid/grid-row-class-name-params.md deleted file mode 100644 index 9016971bce36d..0000000000000 --- a/docs/pages/x/api/data-grid/grid-row-class-name-params.md +++ /dev/null @@ -1,33 +0,0 @@ -# GridRowClassNameParams Interface - -

Object passed as parameter in the row `getRowClassName` callback prop.

- -## Demos - -:::info -For examples and details on the usage, check the following pages: - -- [Styling rows](/x/react-data-grid/style/#styling-rows) - -::: - -## Import - -```js -import { GridRowClassNameParams } from '@mui/x-data-grid-premium'; -// or -import { GridRowClassNameParams } from '@mui/x-data-grid-pro'; -// or -import { GridRowClassNameParams } from '@mui/x-data-grid'; -``` - -## Properties - -| Name | Type | Description | -| :-------------------------------------------------------- | :------------------------------------------ | :---------------------------------------------------------------------------------------------------------------------------- | -| columns | GridColDef[] | All grid columns. | -| id | GridRowId | The grid row id. | -| indexRelativeToCurrentPage | number | Index of the row in the current page.
If the pagination is disabled, it will be the index relative to all filtered rows. | -| isFirstVisible | boolean | Whether this row is the first visible or not. | -| isLastVisible | boolean | Whether this row is the last visible or not. | -| row | R | The row model of the row that the current cell belongs to. | diff --git a/docs/pages/x/api/data-grid/grid-row-params.js b/docs/pages/x/api/data-grid/grid-row-params.js index e963d9494bf6f..9742086b972e6 100644 --- a/docs/pages/x/api/data-grid/grid-row-params.js +++ b/docs/pages/x/api/data-grid/grid-row-params.js @@ -1,7 +1,26 @@ import * as React from 'react'; -import MarkdownDocs from '@mui/monorepo/docs/src/modules/components/MarkdownDocs'; -import * as pageProps from './grid-row-params.md?muiMarkdown'; +import InterfaceApiPage from 'docsx/src/modules/components/InterfaceApiPage'; +import layoutConfig from 'docsx/src/modules/utils/dataGridLayoutConfig'; +import mapApiPageTranslations from 'docs/src/modules/utils/mapApiPageTranslations'; +import jsonPageContent from './grid-row-params.json'; -export default function Page() { - return ; +export default function Page(props) { + const { descriptions, pageContent } = props; + return ( + + ); } + +Page.getInitialProps = () => { + const req = require.context( + 'docsx/translations/api-docs/data-grid/', + false, + /\.\/grid-row-params.*.json$/, + ); + const descriptions = mapApiPageTranslations(req); + + return { + descriptions, + pageContent: jsonPageContent, + }; +}; diff --git a/docs/pages/x/api/data-grid/grid-row-params.json b/docs/pages/x/api/data-grid/grid-row-params.json new file mode 100644 index 0000000000000..1231121600c42 --- /dev/null +++ b/docs/pages/x/api/data-grid/grid-row-params.json @@ -0,0 +1,14 @@ +{ + "name": "GridRowParams", + "imports": [ + "import { GridRowParams } from '@mui/x-data-grid-premium'", + "import { GridRowParams } from '@mui/x-data-grid-pro'", + "import { GridRowParams } from '@mui/x-data-grid'" + ], + "demos": "", + "properties": { + "columns": { "type": { "description": "GridColDef[]" }, "required": true }, + "id": { "type": { "description": "GridRowId" }, "required": true }, + "row": { "type": { "description": "R" }, "required": true } + } +} diff --git a/docs/pages/x/api/data-grid/grid-row-params.md b/docs/pages/x/api/data-grid/grid-row-params.md deleted file mode 100644 index f6ed198f4ae25..0000000000000 --- a/docs/pages/x/api/data-grid/grid-row-params.md +++ /dev/null @@ -1,30 +0,0 @@ -# GridRowParams Interface - -

Object passed as parameter in the row callbacks.

- -## Demos - -:::info -For examples and details on the usage, check the following pages: - -- [Master detail](/x/react-data-grid/master-detail/) - -::: - -## Import - -```js -import { GridRowParams } from '@mui/x-data-grid-premium'; -// or -import { GridRowParams } from '@mui/x-data-grid-pro'; -// or -import { GridRowParams } from '@mui/x-data-grid'; -``` - -## Properties - -| Name | Type | Description | -| :------------------------------------- | :------------------------------------------ | :--------------------------------------------------------- | -| columns | GridColDef[] | All grid columns. | -| id | GridRowId | The grid row id. | -| row | R | The row model of the row that the current cell belongs to. | diff --git a/docs/pages/x/api/data-grid/grid-row-spacing-params.js b/docs/pages/x/api/data-grid/grid-row-spacing-params.js index 4e3be6c537597..2547f839fc7f9 100644 --- a/docs/pages/x/api/data-grid/grid-row-spacing-params.js +++ b/docs/pages/x/api/data-grid/grid-row-spacing-params.js @@ -1,7 +1,26 @@ import * as React from 'react'; -import MarkdownDocs from '@mui/monorepo/docs/src/modules/components/MarkdownDocs'; -import * as pageProps from './grid-row-spacing-params.md?muiMarkdown'; +import InterfaceApiPage from 'docsx/src/modules/components/InterfaceApiPage'; +import layoutConfig from 'docsx/src/modules/utils/dataGridLayoutConfig'; +import mapApiPageTranslations from 'docs/src/modules/utils/mapApiPageTranslations'; +import jsonPageContent from './grid-row-spacing-params.json'; -export default function Page() { - return ; +export default function Page(props) { + const { descriptions, pageContent } = props; + return ( + + ); } + +Page.getInitialProps = () => { + const req = require.context( + 'docsx/translations/api-docs/data-grid/', + false, + /\.\/grid-row-spacing-params.*.json$/, + ); + const descriptions = mapApiPageTranslations(req); + + return { + descriptions, + pageContent: jsonPageContent, + }; +}; diff --git a/docs/pages/x/api/data-grid/grid-row-spacing-params.json b/docs/pages/x/api/data-grid/grid-row-spacing-params.json new file mode 100644 index 0000000000000..72cd33c599de6 --- /dev/null +++ b/docs/pages/x/api/data-grid/grid-row-spacing-params.json @@ -0,0 +1,16 @@ +{ + "name": "GridRowSpacingParams", + "imports": [ + "import { GridRowSpacingParams } from '@mui/x-data-grid-premium'", + "import { GridRowSpacingParams } from '@mui/x-data-grid-pro'", + "import { GridRowSpacingParams } from '@mui/x-data-grid'" + ], + "demos": "", + "properties": { + "id": { "type": { "description": "GridRowId" }, "required": true }, + "indexRelativeToCurrentPage": { "type": { "description": "number" }, "required": true }, + "isFirstVisible": { "type": { "description": "boolean" }, "required": true }, + "isLastVisible": { "type": { "description": "boolean" }, "required": true }, + "model": { "type": { "description": "R" }, "required": true } + } +} diff --git a/docs/pages/x/api/data-grid/grid-row-spacing-params.md b/docs/pages/x/api/data-grid/grid-row-spacing-params.md deleted file mode 100644 index e62d1975949ae..0000000000000 --- a/docs/pages/x/api/data-grid/grid-row-spacing-params.md +++ /dev/null @@ -1,32 +0,0 @@ -# GridRowSpacingParams Interface - -

Object passed as parameter in the row `getRowSpacing` callback prop.

- -## Demos - -:::info -For examples and details on the usage, check the following pages: - -- [Row spacing](/x/react-data-grid/row-height/#row-spacing) - -::: - -## Import - -```js -import { GridRowSpacingParams } from '@mui/x-data-grid-premium'; -// or -import { GridRowSpacingParams } from '@mui/x-data-grid-pro'; -// or -import { GridRowSpacingParams } from '@mui/x-data-grid'; -``` - -## Properties - -| Name | Type | Description | -| :-------------------------------------------------------- | :--------------------------------------- | :---------------------------------------------------------------------------------------------------------------------------- | -| id | GridRowId | The row id. | -| indexRelativeToCurrentPage | number | Index of the row in the current page.
If the pagination is disabled, it will be the index relative to all filtered rows. | -| isFirstVisible | boolean | Whether this row is the first visible or not. | -| isLastVisible | boolean | Whether this row is the last visible or not. | -| model | R | The row model. | diff --git a/docs/pages/x/api/data-grid/grid-single-select-col-def.js b/docs/pages/x/api/data-grid/grid-single-select-col-def.js index bb9fedb9b8798..77a3ef72e58ee 100644 --- a/docs/pages/x/api/data-grid/grid-single-select-col-def.js +++ b/docs/pages/x/api/data-grid/grid-single-select-col-def.js @@ -1,7 +1,26 @@ import * as React from 'react'; -import MarkdownDocs from '@mui/monorepo/docs/src/modules/components/MarkdownDocs'; -import * as pageProps from './grid-single-select-col-def.md?muiMarkdown'; +import InterfaceApiPage from 'docsx/src/modules/components/InterfaceApiPage'; +import layoutConfig from 'docsx/src/modules/utils/dataGridLayoutConfig'; +import mapApiPageTranslations from 'docs/src/modules/utils/mapApiPageTranslations'; +import jsonPageContent from './grid-single-select-col-def.json'; -export default function Page() { - return ; +export default function Page(props) { + const { descriptions, pageContent } = props; + return ( + + ); } + +Page.getInitialProps = () => { + const req = require.context( + 'docsx/translations/api-docs/data-grid/', + false, + /\.\/grid-single-select-col-def.*.json$/, + ); + const descriptions = mapApiPageTranslations(req); + + return { + descriptions, + pageContent: jsonPageContent, + }; +}; diff --git a/docs/pages/x/api/data-grid/grid-single-select-col-def.json b/docs/pages/x/api/data-grid/grid-single-select-col-def.json new file mode 100644 index 0000000000000..2e62dcbf36e98 --- /dev/null +++ b/docs/pages/x/api/data-grid/grid-single-select-col-def.json @@ -0,0 +1,104 @@ +{ + "name": "GridSingleSelectColDef", + "imports": [ + "import { GridSingleSelectColDef } from '@mui/x-data-grid-premium'", + "import { GridSingleSelectColDef } from '@mui/x-data-grid-pro'", + "import { GridSingleSelectColDef } from '@mui/x-data-grid'" + ], + "demos": "", + "properties": { + "field": { "type": { "description": "string" }, "required": true }, + "type": { + "type": { "description": "'singleSelect'" }, + "default": "'singleSelect'", + "required": true + }, + "aggregable": { + "type": { "description": "boolean" }, + "default": "true", + "isPremiumPlan": true + }, + "align": { "type": { "description": "GridAlignment" } }, + "availableAggregationFunctions": { + "type": { "description": "string[]" }, + "isPremiumPlan": true + }, + "cellClassName": { "type": { "description": "GridCellClassNamePropType<R, V>" } }, + "colSpan": { + "type": { "description": "number | GridColSpanFn<R, V, F>" }, + "default": "1" + }, + "description": { "type": { "description": "string" } }, + "disableColumnMenu": { "type": { "description": "boolean" }, "default": "false" }, + "disableExport": { "type": { "description": "boolean" }, "default": "false" }, + "disableReorder": { "type": { "description": "boolean" }, "default": "false" }, + "display": { "type": { "description": "'text' | 'flex'" } }, + "editable": { "type": { "description": "boolean" }, "default": "false" }, + "filterable": { "type": { "description": "boolean" }, "default": "true" }, + "filterOperators": { "type": { "description": "GridFilterOperator<R, V, F>[]" } }, + "flex": { "type": { "description": "number" } }, + "getApplyQuickFilterFn": { "type": { "description": "GetApplyQuickFilterFn<R, V>" } }, + "getOptionLabel": { "type": { "description": "(value: ValueOptions) => string" } }, + "getOptionValue": { "type": { "description": "(value: ValueOptions) => any" } }, + "getSortComparator": { + "type": { + "description": "(sortDirection: GridSortDirection) => GridComparatorFn<V> | undefined" + } + }, + "groupable": { "type": { "description": "boolean" }, "default": "true" }, + "groupingValueGetter": { + "type": { "description": "GridGroupingValueGetter<R>" }, + "isPremiumPlan": true + }, + "headerAlign": { "type": { "description": "GridAlignment" } }, + "headerClassName": { "type": { "description": "GridColumnHeaderClassNamePropType" } }, + "headerName": { "type": { "description": "string" } }, + "hideable": { "type": { "description": "boolean" }, "default": "true" }, + "hideSortIcons": { "type": { "description": "boolean" }, "default": "false" }, + "maxWidth": { "type": { "description": "number" }, "default": "Infinity" }, + "minWidth": { "type": { "description": "number" }, "default": "50" }, + "pastedValueParser": { + "type": { "description": "GridPastedValueParser<R, V, F>" }, + "isPremiumPlan": true + }, + "pinnable": { "type": { "description": "boolean" }, "default": "true" }, + "preProcessEditCellProps": { + "type": { + "description": "(params: GridPreProcessEditCellProps) => GridEditCellProps | Promise<GridEditCellProps>" + } + }, + "renderCell": { + "type": { + "description": "(params: GridRenderCellParams<R, V, F>) => React.ReactNode" + } + }, + "renderEditCell": { + "type": { + "description": "(params: GridRenderEditCellParams<R, V, F>) => React.ReactNode" + } + }, + "renderHeader": { + "type": { + "description": "(params: GridColumnHeaderParams<R, V, F>) => React.ReactNode" + } + }, + "renderHeaderFilter": { + "type": { "description": "(params: GridRenderHeaderFilterProps) => React.ReactNode" }, + "isProPlan": true + }, + "resizable": { "type": { "description": "boolean" }, "default": "true" }, + "sortable": { "type": { "description": "boolean" }, "default": "true" }, + "sortComparator": { "type": { "description": "GridComparatorFn<V>" } }, + "sortingOrder": { "type": { "description": "GridSortDirection[]" } }, + "valueFormatter": { "type": { "description": "GridValueFormatter<R, V, F>" } }, + "valueGetter": { "type": { "description": "GridValueGetter<R, V, F>" } }, + "valueOptions": { + "type": { + "description": "Array<ValueOptions> | ((params: GridValueOptionsParams<R>) => Array<ValueOptions>)" + } + }, + "valueParser": { "type": { "description": "GridValueParser<R, V, F>" } }, + "valueSetter": { "type": { "description": "GridValueSetter<R, V, F>" } }, + "width": { "type": { "description": "number" }, "default": "100" } + } +} diff --git a/docs/pages/x/api/data-grid/grid-single-select-col-def.md b/docs/pages/x/api/data-grid/grid-single-select-col-def.md deleted file mode 100644 index b42076119a95d..0000000000000 --- a/docs/pages/x/api/data-grid/grid-single-select-col-def.md +++ /dev/null @@ -1,73 +0,0 @@ -# GridSingleSelectColDef Interface - -

Column Definition interface used for columns with the `singleSelect` type.

- -## Demos - -:::info -For examples and details on the usage, check the following pages: - -- [Special column properties](/x/react-data-grid/column-definition/#special-properties) - -::: - -## Import - -```js -import { GridSingleSelectColDef } from '@mui/x-data-grid-premium'; -// or -import { GridSingleSelectColDef } from '@mui/x-data-grid-pro'; -// or -import { GridSingleSelectColDef } from '@mui/x-data-grid'; -``` - -## Properties - -| Name | Type | Default | Description | -| :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------- | :----------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| aggregable? [](/x/introduction/licensing/#premium-plan) | boolean | true | If `true`, the cells of the column can be aggregated based. | -| align? | GridAlignment | | Allows to align the column values in cells. | -| availableAggregationFunctions? [](/x/introduction/licensing/#premium-plan) | string[] | | Limit the aggregation function usable on this column.
By default, the column will have all the aggregation functions that are compatible with its type. | -| cellClassName? | GridCellClassNamePropType<R, V> | | Class name that will be added in cells for that column. | -| colSpan? | number \| GridColSpanFn<R, V, F> | 1 | Number of columns a cell should span. | -| description? | string | | The description of the column rendered as tooltip if the column header name is not fully displayed. | -| disableColumnMenu? | boolean | false | If `true`, the column menu is disabled for this column. | -| disableExport? | boolean | false | If `true`, this column will not be included in exports. | -| disableReorder? | boolean | false | If `true`, this column cannot be reordered. | -| display? | 'text' \| 'flex' | | Display mode for the cell:
- 'text': For text-based cells (default)
- 'flex': For cells with HTMLElement children | -| editable? | boolean | false | If `true`, the cells of the column are editable. | -| field | string | | The column identifier. It's used to map with GridRowModel values. | -| filterable? | boolean | true | If `true`, the column is filterable. | -| filterOperators? | GridFilterOperator<R, V, F>[] | | Allows setting the filter operators for this column. | -| flex? | number | | If set, it indicates that a column has fluid width. Range [0, ∞). | -| getApplyQuickFilterFn? | GetApplyQuickFilterFn<R, V> | | The callback that generates a filtering function for a given quick filter value.
This function can return `null` to skip filtering for this value and column. | -| getOptionLabel? | (value: ValueOptions) => string | | Used to determine the label displayed for a given value option. | -| getOptionValue? | (value: ValueOptions) => any | | Used to determine the value used for a value option. | -| getSortComparator? | (sortDirection: GridSortDirection) => GridComparatorFn<V> \| undefined | | Allows to use a different comparator function depending on the sort direction.
Takes precedence over `sortComparator`. | -| groupable? | boolean | true | If `true`, the rows can be grouped based on this column values (pro-plan only).
Only available in DataGridPremium. | -| groupingValueGetter? [](/x/introduction/licensing/#premium-plan) | GridGroupingValueGetter<R> | | Function that transforms a complex cell value into a key that be used for grouping the rows. | -| headerAlign? | GridAlignment | | Header cell element alignment. | -| headerClassName? | GridColumnHeaderClassNamePropType | | Class name that will be added in the column header cell. | -| headerName? | string | | The title of the column rendered in the column header cell. | -| hideable? | boolean | true | If `false`, removes the buttons for hiding this column. | -| hideSortIcons? | boolean | false | Toggle the visibility of the sort icons. | -| maxWidth? | number | Infinity | Sets the maximum width of a column. | -| minWidth? | number | 50 | Sets the minimum width of a column. | -| pastedValueParser? [](/x/introduction/licensing/#premium-plan) | GridPastedValueParser<R, V, F> | | Function that takes the clipboard-pasted value and converts it to a value used internally. | -| pinnable? | boolean | true | If `false`, the menu items for column pinning menu will not be rendered.
Only available in DataGridPro. | -| preProcessEditCellProps? | (params: GridPreProcessEditCellProps) => GridEditCellProps \| Promise<GridEditCellProps> | | Callback fired when the edit props of the cell changes.
It allows to process the props that saved into the state. | -| renderCell? | (params: GridRenderCellParams<R, V, F>) => React.ReactNode | | Allows to override the component rendered as cell for this column. | -| renderEditCell? | (params: GridRenderEditCellParams<R, V, F>) => React.ReactNode | | Allows to override the component rendered in edit cell mode for this column. | -| renderHeader? | (params: GridColumnHeaderParams<R, V, F>) => React.ReactNode | | Allows to render a component in the column header cell. | -| renderHeaderFilter? [](/x/introduction/licensing/#pro-plan) | (params: GridRenderHeaderFilterProps) => React.ReactNode | | Allows to render a component in the column header filter cell. | -| resizable? | boolean | true | If `true`, the column is resizable. | -| sortable? | boolean | true | If `true`, the column is sortable. | -| sortComparator? | GridComparatorFn<V> | | A comparator function used to sort rows. | -| sortingOrder? | GridSortDirection[] | | The order of the sorting sequence. | -| type | 'singleSelect' | 'singleSelect' | The type of the column. | -| valueFormatter? | GridValueFormatter<R, V, F> | | Function that allows to apply a formatter before rendering its value. | -| valueGetter? | GridValueGetter<R, V, F> | | Function that allows to get a specific data instead of field to render in the cell. | -| valueOptions? | Array<ValueOptions> \| ((params: GridValueOptionsParams<R>) => Array<ValueOptions>) | | To be used in combination with `type: 'singleSelect'`. This is an array (or a function returning an array) of the possible cell values and labels. | -| valueParser? | GridValueParser<R, V, F> | | Function that takes the user-entered value and converts it to a value used internally. | -| valueSetter? | GridValueSetter<R, V, F> | | Function that allows to customize how the entered value is stored in the row.
It only works with cell/row editing. | -| width? | number | 100 | Set the width of the column. | diff --git a/docs/scripts/api/buildInterfacesDocumentation.ts b/docs/scripts/api/buildInterfacesDocumentation.ts index fe5d16a3bf28a..e994cba656c04 100644 --- a/docs/scripts/api/buildInterfacesDocumentation.ts +++ b/docs/scripts/api/buildInterfacesDocumentation.ts @@ -1,10 +1,9 @@ import * as ts from 'typescript'; -import * as prettier from 'prettier'; +import { EOL } from 'os'; import kebabCase from 'lodash/kebabCase'; import path from 'path'; import { renderMarkdown } from '@mui/monorepo/packages/markdown'; import { - escapeCell, getSymbolDescription, getSymbolJSDocTags, linkify, @@ -12,6 +11,7 @@ import { writePrettifiedFile, resolveExportSpecifier, DocumentedInterfaces, + escapeCell, } from './utils'; import { XTypeScriptProjects, @@ -31,7 +31,7 @@ interface ParsedProperty { name: string; description: string; tags: { [tagName: string]: ts.JSDocTagInfo }; - isOptional: boolean; + required: boolean; typeStr: string; /** * Name of the projects on which the interface has this property @@ -39,6 +39,10 @@ interface ParsedProperty { projects: XProjectNames[]; } +const translationPagesDirectory = 'docs/translations/api-docs/data-grid'; +const importTranslationPagesDirectory = 'docsx/translations/api-docs/data-grid'; +const apiPagesDirectory = path.join(process.cwd(), `docs/pages/x/api/data-grid`); + const GRID_API_INTERFACES_WITH_DEDICATED_PAGES = [ 'GridCellSelectionApi', 'GridColumnPinningApi', @@ -93,7 +97,7 @@ const parseProperty = async ( name: propertySymbol.name, description: getSymbolDescription(propertySymbol, project), tags: getSymbolJSDocTags(propertySymbol), - isOptional: !!propertySymbol.declarations?.find(ts.isPropertySignature)?.questionToken, + required: !propertySymbol.declarations?.find(ts.isPropertySignature)?.questionToken, typeStr: await stringifySymbol(propertySymbol, project), projects: [project.name], }); @@ -173,123 +177,55 @@ const parseInterfaceSymbol = async ( return parsedInterface; }; -function generateMarkdownFromProperties( - object: ParsedObject, - documentedInterfaces: DocumentedInterfaces, -) { - const hasDefaultValue = object.properties.some((property) => { - return property.tags.default; - }); - - const headers = hasDefaultValue - ? ` -| Name | Type | Default | Description | -|:-----|:-----|:--------|:------------|` - : ` -| Name | Type | Description | -|:-----|:-----|:------------|`; - - let text = `${headers}\n`; - - object.properties.forEach((property) => { - const defaultValue = property.tags.default?.text?.[0].text; - - let planImg: string; - if (property.projects.includes('x-data-grid')) { - planImg = ''; - } else if (property.projects.includes('x-data-grid-pro')) { - planImg = - ' [](/x/introduction/licensing/#pro-plan)'; - } else if (property.projects.includes('x-data-grid-premium')) { - planImg = - ' [](/x/introduction/licensing/#premium-plan)'; - } else { - throw new Error(`No valid plan found for ${property.name} property in ${object.name}`); - } - - const formattedName = property.isOptional - ? `${property.name}?${planImg}` - : `${property.name}${planImg}`; - - const formattedType = `${escapeCell(property.typeStr)}`; - - const formattedDefaultValue = - defaultValue == null ? '' : `${escapeCell(defaultValue)}`; - - const formattedDescription = escapeCell( - linkify(property.description, documentedInterfaces, 'markdown'), - ); - - if (hasDefaultValue) { - text += `| ${formattedName} | ${formattedType} | ${formattedDefaultValue} | ${formattedDescription} |\n`; - } else { - text += `| ${formattedName} | ${formattedType} | ${formattedDescription} |\n`; - } - }); - - return text; +function getPlanLevel(property: ParsedProperty) { + if (property.projects.includes('x-data-grid')) { + return ''; + } + if (property.projects.includes('x-data-grid-pro')) { + return 'pro'; + } + if (property.projects.includes('x-data-grid-premium')) { + return 'premium'; + } + throw new Error(`No valid plan found for ${property.name} property`); } -async function generateImportStatement(objects: ParsedObject[], projects: XTypeScriptProjects) { - let imports = '```js\n'; +function getDefaultValue(property: ParsedProperty) { + const defaultValue = property.tags.default?.text?.[0].text; + if (defaultValue === undefined) { + return defaultValue; + } + return escapeCell(defaultValue); +} +function generateImportStatement(object: ParsedObject, projects: XTypeScriptProjects) { const projectImports = Array.from(projects.values()) .map((project) => { - const objectsInProject = objects.filter((object) => { - return !!project.exports[object.name]; - }); - - if (objectsInProject.length === 0) { + if (!project.exports[object.name]) { return null; } - return `import {${objectsInProject.map((object) => object.name)}} from '@mui/${ - project.name - }'`; + return `import { ${object.name} } from '@mui/${project.name}'`; }) .filter((el): el is string => !!el) // Display the imports from the pro packages above imports from the community packages .sort((a, b) => b.length - a.length); - - imports += await prettier.format(projectImports.join('\n// or\n'), { - singleQuote: true, - semi: false, - trailingComma: 'none', - parser: 'typescript', - }); - imports += '\n```'; - - return imports; + return projectImports; } -async function generateMarkdown( - object: ParsedObject, - projects: XTypeScriptProjects, - documentedInterfaces: DocumentedInterfaces, -) { - const demos = object.tags.demos; - const description = linkify(object.description, documentedInterfaces, 'html'); - const imports = await generateImportStatement([object], projects); - - let text = `# ${object.name} Interface\n`; - text += `

${description}

\n\n`; - - if (demos && demos.text && demos.text.length > 0) { - text += '## Demos\n\n'; - text += ':::info\n'; - text += 'For examples and details on the usage, check the following pages:\n\n'; - demos.text.forEach((demoLink) => { - text += demoLink.text; - }); - text += '\n\n:::\n\n'; +function extractDemos(tagInfo: ts.JSDocTagInfo): { demos?: string } { + if (!tagInfo || !tagInfo.text) { + return {}; } + const demos = tagInfo.text + .map(({ text }) => text.matchAll(/\[(.*)\]\((.*)\)/g).next().value) + .map(([, text, url]) => `
  • ${text}
  • `); - text += '## Import\n\n'; - text += `${imports}\n\n`; - text += '## Properties\n\n'; - text += `${generateMarkdownFromProperties(object, documentedInterfaces)}`; + if (demos.length === 0) { + return {}; + } - return text; + return { demos: `
      ${demos.join('\n')}
    ` }; } interface BuildInterfacesDocumentationOptions { @@ -356,26 +292,99 @@ export default async function buildInterfacesDocumentation( // eslint-disable-next-line no-console console.log('Built JSON file for', parsedInterface.name); } else { + const content = { + name: parsedInterface.name, + imports: generateImportStatement(parsedInterface, projects), + ...extractDemos(parsedInterface.tags.demos), + properties: {}, + }; + + const translations = { + interfaceDescription: renderMarkdown( + linkify(escapeCell(parsedInterface.description || ''), documentedInterfaces, 'html'), + ), + propertiesDescriptions: {}, + }; + + parsedInterface.properties + .map((property) => ({ + name: property.name, + description: renderMarkdown( + linkify(escapeCell(property.description), documentedInterfaces, 'html'), + ), + type: { description: escapeCell(property.typeStr) }, + default: getDefaultValue(property), + planLevel: getPlanLevel(property), + required: property.required, + })) + .sort((a, b) => { + if ((a.required && b.required) || (!a.required && !b.required)) { + return a.name.localeCompare(b.name); + } + if (a.required) { + return -1; + } + return 1; + }) + .forEach(({ name, description, type, default: defaultValue, required, planLevel }) => { + content.properties[name] = { type }; + if (defaultValue) { + content.properties[name].default = defaultValue; + } + if (required) { + content.properties[name].required = required; + } + if (planLevel === 'pro') { + content.properties[name].isProPlan = true; + } + if (planLevel === 'premium') { + content.properties[name].isPremiumPlan = true; + } + translations.propertiesDescriptions[name] = { description }; + }); + // eslint-disable-next-line no-await-in-loop - const markdown = await generateMarkdown(parsedInterface, projects, documentedInterfaces); + await writePrettifiedFile( + path.resolve(apiPagesDirectory, `${slug}.json`), + JSON.stringify(content), + project, + ); + // eslint-disable-next-line no-await-in-loop await writePrettifiedFile( - path.resolve(apiPagesFolder, project.documentationFolderName, `${slug}.md`), - markdown, + path.resolve(translationPagesDirectory, `${slug}.json`), + JSON.stringify(translations), project, ); // eslint-disable-next-line no-await-in-loop await writePrettifiedFile( - path.resolve(apiPagesFolder, project.documentationFolderName, `${slug}.js`), + path.resolve(apiPagesDirectory, `${slug}.js`), `import * as React from 'react'; - import MarkdownDocs from '@mui/monorepo/docs/src/modules/components/MarkdownDocs'; - import * as pageProps from './${slug}.md?muiMarkdown'; - - export default function Page() { - return ; + import InterfaceApiPage from 'docsx/src/modules/components/InterfaceApiPage'; + import layoutConfig from 'docsx/src/modules/utils/dataGridLayoutConfig'; + import mapApiPageTranslations from 'docs/src/modules/utils/mapApiPageTranslations'; + import jsonPageContent from './${slug}.json'; + + export default function Page(props) { + const { descriptions, pageContent } = props; + return ; } - `, + + Page.getInitialProps = () => { + const req = require.context( + '${importTranslationPagesDirectory}/', + false, + /\\.\\/${slug}.*.json$/, + ); + const descriptions = mapApiPageTranslations(req); + + return { + descriptions, + pageContent: jsonPageContent, + }; + }; + `.replace(/\r?\n/g, EOL), project, ); diff --git a/docs/scripts/api/utils.ts b/docs/scripts/api/utils.ts index ddb5f560a1fa4..7f060a3805e52 100644 --- a/docs/scripts/api/utils.ts +++ b/docs/scripts/api/utils.ts @@ -26,11 +26,7 @@ export function getJsdocDefaultValue(jsdoc: Annotation) { } export function escapeCell(value: string) { - return value - .replace(//g, '>') - .replace(/\|/g, '\\|') - .replace(/\r?\n/g, '
    '); + return value.replace(//g, '>').replace(/\r?\n/g, '
    '); } export const formatType = async (rawType: string) => { diff --git a/docs/src/modules/components/InterfaceApiPage.js b/docs/src/modules/components/InterfaceApiPage.js new file mode 100644 index 0000000000000..a2b02e6f82916 --- /dev/null +++ b/docs/src/modules/components/InterfaceApiPage.js @@ -0,0 +1,184 @@ +/* eslint-disable react/no-danger */ +import * as React from 'react'; +import PropTypes from 'prop-types'; +import { exactProp } from '@mui/utils'; +import Typography from '@mui/material/Typography'; +import Alert from '@mui/material/Alert'; +import VerifiedRoundedIcon from '@mui/icons-material/VerifiedRounded'; +import { alpha } from '@mui/material/styles'; +import { useTranslate, useUserLanguage } from 'docs/src/modules/utils/i18n'; +import HighlightedCode from 'docs/src/modules/components/HighlightedCode'; +import MarkdownElement from 'docs/src/modules/components/MarkdownElement'; +import AppLayoutDocs from 'docs/src/modules/components/AppLayoutDocs'; +import PropertiesSection from 'docs/src/modules/components/ApiPage/sections/PropertiesSection'; +import { DEFAULT_API_LAYOUT_STORAGE_KEYS } from 'docs/src/modules/components/ApiPage/sections/ToggleDisplayOption'; + +export function getTranslatedHeader(t, header) { + const translations = { + demos: t('api-docs.demos'), + import: t('api-docs.import'), + }; + + // TODO Drop runtime type-checking once we type-check this file + if (!translations.hasOwnProperty(header)) { + throw new TypeError( + `Unable to translate header '${header}'. Did you mean one of '${Object.keys( + translations, + ).join("', '")}'`, + ); + } + + return translations[header] || header; +} + +function Heading(props) { + const { hash, level: Level = 'h2' } = props; + const t = useTranslate(); + + return ( + + {getTranslatedHeader(t, hash)} + + + + + + + ); +} + +Heading.propTypes = { + hash: PropTypes.string.isRequired, + level: PropTypes.string, +}; + +export default function ApiPage(props) { + const { + descriptions, + pageContent, + defaultLayout = 'expanded', + layoutStorageKey = DEFAULT_API_LAYOUT_STORAGE_KEYS, + } = props; + const t = useTranslate(); + const userLanguage = useUserLanguage(); + + const { demos, filename = '', properties } = pageContent; + + const { componentDescription, propertiesDescriptions, interfaceDescription } = + descriptions[userLanguage]; + const description = t('api-docs.pageDescription').replace(/{{name}}/, pageContent.name); + + // Prefer linking the .tsx or .d.ts for the "Edit this page" link. + const apiSourceLocation = filename.replace('.js', '.d.ts'); + + return ( + + +

    {pageContent.name} API

    + + + {demos && ( + } + sx={[ + (theme) => ({ + mt: 1.5, + pt: 1, + px: 2, + pb: 0, + fontSize: theme.typography.pxToRem(16), + backgroundColor: (theme.vars || theme).palette.success[50], + borderColor: (theme.vars || theme).palette.success[100], + '& * p': { + mb: 1, + }, + '& * a': { + fontWeight: theme.typography.fontWeightMedium, + color: (theme.vars || theme).palette.success[900], + textDecorationColor: alpha(theme.palette.success[600], 0.3), + }, + ...theme.applyDarkStyles({ + '& * a': { + color: (theme.vars || theme).palette.success[100], + textDecorationColor: alpha(theme.palette.success[100], 0.3), + }, + backgroundColor: alpha(theme.palette.success[700], 0.15), + borderColor: alpha(theme.palette.success[600], 0.3), + }), + }), + ]} + > + For examples and details on the usage, check the following pages:

    + ${demos}`, + }} + /> +
    + )} + + + + {componentDescription ? ( + +
    +
    + +
    + ) : null} + +
    + + + + + +
    + ); +} + +ApiPage.propTypes = { + defaultLayout: PropTypes.oneOf(['collapsed', 'expanded', 'table']), + descriptions: PropTypes.object.isRequired, + layoutStorageKey: PropTypes.shape({ + props: PropTypes.string, + }), + pageContent: PropTypes.object.isRequired, +}; + +if (process.env.NODE_ENV !== 'production') { + ApiPage.propTypes = exactProp(ApiPage.propTypes); +} diff --git a/docs/translations/api-docs/data-grid/grid-actions-col-def.json b/docs/translations/api-docs/data-grid/grid-actions-col-def.json new file mode 100644 index 0000000000000..087bee3376cce --- /dev/null +++ b/docs/translations/api-docs/data-grid/grid-actions-col-def.json @@ -0,0 +1,95 @@ +{ + "interfaceDescription": "Column Definition interface used for columns with the actions type.", + "propertiesDescriptions": { + "field": { + "description": "The column identifier. It's used to map with GridRowModel values." + }, + "getActions": { "description": "Function that returns the actions to be shown." }, + "type": { "description": "The type of the column." }, + "aggregable": { + "description": "If true, the cells of the column can be aggregated based." + }, + "align": { "description": "Allows to align the column values in cells." }, + "availableAggregationFunctions": { + "description": "Limit the aggregation function usable on this column.
    By default, the column will have all the aggregation functions that are compatible with its type." + }, + "cellClassName": { "description": "Class name that will be added in cells for that column." }, + "colSpan": { "description": "Number of columns a cell should span." }, + "description": { + "description": "The description of the column rendered as tooltip if the column header name is not fully displayed." + }, + "disableColumnMenu": { + "description": "If true, the column menu is disabled for this column." + }, + "disableExport": { + "description": "If true, this column will not be included in exports." + }, + "disableReorder": { "description": "If true, this column cannot be reordered." }, + "display": { + "description": "Display mode for the cell:
    - 'text': For text-based cells (default)
    - 'flex': For cells with HTMLElement children" + }, + "editable": { "description": "If true, the cells of the column are editable." }, + "filterable": { "description": "If true, the column is filterable." }, + "filterOperators": { "description": "Allows setting the filter operators for this column." }, + "flex": { "description": "If set, it indicates that a column has fluid width. Range [0, ∞)." }, + "getApplyQuickFilterFn": { + "description": "The callback that generates a filtering function for a given quick filter value.
    This function can return null to skip filtering for this value and column." + }, + "getSortComparator": { + "description": "Allows to use a different comparator function depending on the sort direction.
    Takes precedence over sortComparator." + }, + "groupable": { + "description": "If true, the rows can be grouped based on this column values (pro-plan only).
    Only available in DataGridPremium." + }, + "groupingValueGetter": { + "description": "Function that transforms a complex cell value into a key that be used for grouping the rows." + }, + "headerAlign": { "description": "Header cell element alignment." }, + "headerClassName": { + "description": "Class name that will be added in the column header cell." + }, + "headerName": { "description": "The title of the column rendered in the column header cell." }, + "hideable": { + "description": "If false, removes the buttons for hiding this column." + }, + "hideSortIcons": { "description": "Toggle the visibility of the sort icons." }, + "maxWidth": { "description": "Sets the maximum width of a column." }, + "minWidth": { "description": "Sets the minimum width of a column." }, + "pastedValueParser": { + "description": "Function that takes the clipboard-pasted value and converts it to a value used internally." + }, + "pinnable": { + "description": "If false, the menu items for column pinning menu will not be rendered.
    Only available in DataGridPro." + }, + "preProcessEditCellProps": { + "description": "Callback fired when the edit props of the cell changes.
    It allows to process the props that saved into the state." + }, + "renderCell": { + "description": "Allows to override the component rendered as cell for this column." + }, + "renderEditCell": { + "description": "Allows to override the component rendered in edit cell mode for this column." + }, + "renderHeader": { "description": "Allows to render a component in the column header cell." }, + "renderHeaderFilter": { + "description": "Allows to render a component in the column header filter cell." + }, + "resizable": { "description": "If true, the column is resizable." }, + "sortable": { "description": "If true, the column is sortable." }, + "sortComparator": { "description": "A comparator function used to sort rows." }, + "sortingOrder": { "description": "The order of the sorting sequence." }, + "valueFormatter": { + "description": "Function that allows to apply a formatter before rendering its value." + }, + "valueGetter": { + "description": "Function that allows to get a specific data instead of field to render in the cell." + }, + "valueParser": { + "description": "Function that takes the user-entered value and converts it to a value used internally." + }, + "valueSetter": { + "description": "Function that allows to customize how the entered value is stored in the row.
    It only works with cell/row editing." + }, + "width": { "description": "Set the width of the column." } + } +} diff --git a/docs/translations/api-docs/data-grid/grid-aggregation-function.json b/docs/translations/api-docs/data-grid/grid-aggregation-function.json new file mode 100644 index 0000000000000..4a5bee820d1e9 --- /dev/null +++ b/docs/translations/api-docs/data-grid/grid-aggregation-function.json @@ -0,0 +1,23 @@ +{ + "interfaceDescription": "Grid aggregation function definition interface.", + "propertiesDescriptions": { + "apply": { + "description": "Function that takes the current cell values and generates the aggregated value." + }, + "columnTypes": { + "description": "Column types supported by this aggregation function.
    If not defined, all types are supported (in most cases this property should be defined)." + }, + "getCellValue": { + "description": "Function that allows to transform the value of the cell passed to the aggregation function applier.
    Useful for aggregating data from multiple row fields." + }, + "hasCellUnit": { + "description": "Indicates if the aggregated value have the same unit as the cells used to generate it.
    It can be used to apply a custom cell renderer only if the aggregated value has the same unit." + }, + "label": { + "description": "Label of the aggregation function.
    Will be used to add a label on the footer of the grouping column when this aggregation function is the only one being used." + }, + "valueFormatter": { + "description": "Function that allows to apply a formatter to the aggregated value.
    If not defined, the grid will use the formatter of the column." + } + } +} diff --git a/docs/translations/api-docs/data-grid/grid-api.json b/docs/translations/api-docs/data-grid/grid-api.json new file mode 100644 index 0000000000000..ba27c6f79b3ac --- /dev/null +++ b/docs/translations/api-docs/data-grid/grid-api.json @@ -0,0 +1,257 @@ +{ + "interfaceDescription": "The full grid API.", + "propertiesDescriptions": { + "addRowGroupingCriteria": { "description": "Adds the field to the row grouping model." }, + "applySorting": { "description": "Applies the current sort model to the rows." }, + "autosizeColumns": { + "description": "Auto-size the columns of the grid based on the cells' content and the space available." + }, + "deleteFilterItem": { + "description": "Deletes a GridFilterItem." + }, + "exportDataAsCsv": { "description": "Downloads and exports a CSV of the grid's data." }, + "exportDataAsExcel": { + "description": "Downloads and exports an Excel file of the grid's data." + }, + "exportDataAsPrint": { "description": "Print the grid's data." }, + "exportState": { + "description": "Generates a serializable object containing the exportable parts of the DataGrid state.
    These values can then be passed to the initialState prop or injected using the restoreState method." + }, + "forceUpdate": { + "description": "Forces the grid to rerender. It's often used after a state update." + }, + "getAllColumns": { + "description": "Returns an array of GridColDef containing all the column definitions." + }, + "getAllGroupDetails": { "description": "Returns the column group lookup." }, + "getAllRowIds": { "description": "Gets the list of row ids." }, + "getCellElement": { + "description": "Gets the underlying DOM element for a cell at the given id and field." + }, + "getCellMode": { "description": "Gets the mode of a cell." }, + "getCellParams": { + "description": "Gets the GridCellParams object that is passed as argument in events." + }, + "getCellSelectionModel": { + "description": "Returns an object containing the selection state of the cells.
    The keys of the object correpond to the row IDs.
    The value of each key is another object whose keys are the fields and values are the selection state." + }, + "getCellValue": { + "description": "Gets the value of a cell at the given id and field." + }, + "getColumn": { + "description": "Returns the GridColDef for the given field." + }, + "getColumnGroupPath": { + "description": "Returns the id of the groups leading to the requested column.
    The array is ordered by increasing depth (the last element is the direct parent of the column)." + }, + "getColumnHeaderElement": { + "description": "Gets the underlying DOM element for the column header with the given field." + }, + "getColumnHeaderParams": { + "description": "Gets the GridColumnHeaderParams object that is passed as argument in events." + }, + "getColumnIndex": { + "description": "Returns the index position of a column. By default, only the visible columns are considered.
    Pass false to useVisibleColumns to consider all columns." + }, + "getColumnIndexRelativeToVisibleColumns": { + "description": "Gets the index of a column relative to the columns that are reachable by scroll." + }, + "getColumnPosition": { + "description": "Returns the left-position of a column relative to the inner border of the grid." + }, + "getDataAsCsv": { + "description": "Returns the grid data as a CSV string.
    This method is used internally by exportDataAsCsv." + }, + "getDataAsExcel": { + "description": "Returns the grid data as an exceljs workbook.
    This method is used internally by exportDataAsExcel." + }, + "getExpandedDetailPanels": { "description": "Returns the rows whose detail panel is open." }, + "getLocaleText": { "description": "Returns the translation for the key." }, + "getPinnedColumns": { "description": "Returns which columns are pinned." }, + "getRootDimensions": { "description": "Returns the dimensions of the grid" }, + "getRow": { "description": "Gets the row data with a given id." }, + "getRowElement": { + "description": "Gets the underlying DOM element for a row at the given id." + }, + "getRowGroupChildren": { + "description": "Gets the rows of a grouping criteria.
    Only contains the rows provided to the grid, not the rows automatically generated by it." + }, + "getRowId": { "description": "Gets the ID of a row given its data." }, + "getRowIdFromRowIndex": { + "description": "Gets the GridRowId of a row at a specific index.
    The index is based on the sorted but unfiltered row list." + }, + "getRowIndexRelativeToVisibleRows": { + "description": "Gets the index of a row relative to the rows that are reachable by scroll." + }, + "getRowMode": { "description": "Gets the mode of a row." }, + "getRowModels": { + "description": "Gets the full set of rows as Map<GridRowId, GridRowModel>." + }, + "getRowNode": { "description": "Gets the row node from the internal tree structure." }, + "getRowParams": { + "description": "Gets the GridRowParams object that is passed as argument in events." + }, + "getRowsCount": { "description": "Gets the total number of rows in the grid." }, + "getRowWithUpdatedValues": { + "description": "Returns the row with the values that were set by editing the cells.
    In row editing, field is ignored and all fields are considered." + }, + "getScrollPosition": { "description": "Returns the current scroll position." }, + "getSelectedCellsAsArray": { + "description": "Returns an array containing only the selected cells.
    Each item is an object with the ID and field of the cell." + }, + "getSelectedRows": { "description": "Returns an array of the selected rows." }, + "getSortedRowIds": { + "description": "Returns all row ids sorted according to the active sort model." + }, + "getSortedRows": { + "description": "Returns all rows sorted according to the active sort model." + }, + "getSortModel": { "description": "Returns the sort model currently applied to the grid." }, + "getVisibleColumns": { "description": "Returns the currently visible columns." }, + "hideColumnMenu": { "description": "Hides the column menu that is open." }, + "hideFilterPanel": { "description": "Hides the filter panel." }, + "hideHeaderFilterMenu": { "description": "Hides the header filter menu." }, + "hidePreferences": { "description": "Hides the preferences panel." }, + "ignoreDiacritics": { + "description": "Returns the value of the ignoreDiacritics prop." + }, + "isCellEditable": { "description": "Controls if a cell is editable." }, + "isCellSelected": { "description": "Determines if a cell is selected or not." }, + "isColumnPinned": { "description": "Returns which side a column is pinned to." }, + "isRowSelectable": { "description": "Determines if a row can be selected or not." }, + "isRowSelected": { "description": "Determines if a row is selected or not." }, + "pinColumn": { "description": "Pins a column to the left or right side of the grid." }, + "publishEvent": { "description": "Emits an event." }, + "removeRowGroupingCriteria": { "description": "Remove the field from the row grouping model." }, + "resetRowHeights": { "description": "Forces the recalculation of the heights of all rows." }, + "resize": { + "description": "Triggers a resize of the component and recalculation of width and height." + }, + "restoreState": { "description": "Inject the given values into the state of the DataGrid." }, + "scroll": { + "description": "Triggers the viewport to scroll to the given positions (in pixels)." + }, + "scrollToIndexes": { + "description": "Triggers the viewport to scroll to the cell at indexes given by params.
    Returns true if the grid had to scroll to reach the target." + }, + "selectCellRange": { + "description": "Selects all cells that are inside the range given by start and end coordinates." + }, + "selectRow": { "description": "Change the selection state of a row." }, + "selectRowRange": { + "description": "Change the selection state of all the selectable rows in a range." + }, + "selectRows": { "description": "Change the selection state of multiple rows." }, + "setAggregationModel": { + "description": "Sets the aggregation model to the one given by model." + }, + "setCellFocus": { + "description": "Sets the focus to the cell at the given id and field." + }, + "setCellSelectionModel": { + "description": "Updates the selected cells to be those passed to the newModel argument.
    Any cell already selected will be unselected." + }, + "setColumnHeaderFilterFocus": { + "description": "Sets the focus to the column header filter at the given field." + }, + "setColumnHeaderFocus": { + "description": "Sets the focus to the column header at the given field." + }, + "setColumnIndex": { + "description": "Moves a column from its original position to the position given by targetIndexPosition." + }, + "setColumnVisibility": { + "description": "Changes the visibility of the column referred by field." + }, + "setColumnVisibilityModel": { + "description": "Sets the column visibility model to the one given by model." + }, + "setColumnWidth": { "description": "Updates the width of a column." }, + "setDensity": { "description": "Sets the density of the grid." }, + "setEditCellValue": { + "description": "Sets the value of the edit cell.
    Commonly used inside the edit cell component." + }, + "setExpandedDetailPanels": { "description": "Changes which rows to expand the detail panel." }, + "setFilterLogicOperator": { + "description": "Changes the GridLogicOperator used to connect the filters." + }, + "setFilterModel": { + "description": "Sets the filter model to the one given by model." + }, + "setPage": { + "description": "Sets the displayed page to the value given by page." + }, + "setPageSize": { + "description": "Sets the number of displayed rows to the value given by pageSize." + }, + "setPaginationModel": { + "description": "Sets the paginationModel to a new value." + }, + "setPinnedColumns": { "description": "Changes the pinned columns." }, + "setQuickFilterValues": { + "description": "Set the quick filter values to the one given by values" + }, + "setRowChildrenExpansion": { "description": "Expand or collapse a row children." }, + "setRowCount": { "description": "Sets the rowCount to a new value." }, + "setRowGroupingCriteriaIndex": { + "description": "Sets the grouping index of a grouping criteria." + }, + "setRowGroupingModel": { "description": "Sets the columns to use as grouping criteria." }, + "setRowIndex": { + "description": "Moves a row from its original position to the position given by targetIndex." + }, + "setRows": { "description": "Sets a new set of rows." }, + "setRowSelectionModel": { + "description": "Updates the selected rows to be those passed to the rowIds argument.
    Any row already selected will be unselected." + }, + "setSortModel": { "description": "Updates the sort model and triggers the sorting of rows." }, + "showColumnMenu": { + "description": "Display the column menu under the field column." + }, + "showFilterPanel": { + "description": "Shows the filter panel. If targetColumnField is given, a filter for this field is also added." + }, + "showHeaderFilterMenu": { "description": "Opens the header filter menu for the given field." }, + "showPreferences": { + "description": "Displays the preferences panel. The newValue argument controls the content of the panel." + }, + "sortColumn": { "description": "Sorts a column." }, + "startCellEditMode": { + "description": "Puts the cell corresponding to the given row id and field into edit mode." + }, + "startHeaderFilterEditMode": { + "description": "Puts the cell corresponding to the given row id and field into edit mode." + }, + "startRowEditMode": { + "description": "Puts the row corresponding to the given id into edit mode." + }, + "state": { "description": "Property that contains the whole state of the grid." }, + "stopCellEditMode": { + "description": "Puts the cell corresponding to the given row id and field into view mode and updates the original row with the new value stored.
    If params.ignoreModifications is true it will discard the modifications made." + }, + "stopHeaderFilterEditMode": { "description": "Stops the edit mode for the current field." }, + "stopRowEditMode": { + "description": "Puts the row corresponding to the given id and into view mode and updates the original row with the new values stored.
    If params.ignoreModifications is true it will discard the modifications made." + }, + "subscribeEvent": { "description": "Registers a handler for an event." }, + "toggleColumnMenu": { + "description": "Toggles the column menu under the field column." + }, + "toggleDetailPanel": { "description": "Expands or collapses the detail panel of a row." }, + "unpinColumn": { "description": "Unpins a column." }, + "unstable_replaceRows": { "description": "Replace a set of rows with new rows." }, + "unstable_setColumnVirtualization": { "description": "Enable/disable column virtualization." }, + "unstable_setPinnedRows": { "description": "Changes the pinned rows." }, + "unstable_setVirtualization": { "description": "Enable/disable virtualization." }, + "updateColumns": { + "description": "Updates the definition of multiple columns at the same time." + }, + "updateRows": { "description": "Allows to update, insert and delete rows." }, + "upsertFilterItem": { + "description": "Updates or inserts a GridFilterItem." + }, + "upsertFilterItems": { + "description": "Updates or inserts many GridFilterItem." + } + } +} diff --git a/docs/translations/api-docs/data-grid/grid-cell-params.json b/docs/translations/api-docs/data-grid/grid-cell-params.json new file mode 100644 index 0000000000000..39d3bbcc36617 --- /dev/null +++ b/docs/translations/api-docs/data-grid/grid-cell-params.json @@ -0,0 +1,18 @@ +{ + "interfaceDescription": "Object passed as parameter in the column GridColDef cell renderer.", + "propertiesDescriptions": { + "cellMode": { "description": "The mode of the cell." }, + "colDef": { "description": "The column of the row that the current cell belongs to." }, + "field": { "description": "The column field of the cell that triggered the event." }, + "hasFocus": { "description": "If true, the cell is the active element." }, + "id": { "description": "The grid row id." }, + "row": { "description": "The row model of the row that the current cell belongs to." }, + "rowNode": { "description": "The node of the row that the current cell belongs to." }, + "tabIndex": { "description": "the tabIndex value." }, + "formattedValue": { "description": "The cell value formatted with the column valueFormatter." }, + "isEditable": { "description": "If true, the cell is editable." }, + "value": { + "description": "The cell value.
    If the column has valueGetter, use params.row to directly access the fields." + } + } +} diff --git a/docs/translations/api-docs/data-grid/grid-col-def.json b/docs/translations/api-docs/data-grid/grid-col-def.json new file mode 100644 index 0000000000000..15b648e0809e1 --- /dev/null +++ b/docs/translations/api-docs/data-grid/grid-col-def.json @@ -0,0 +1,94 @@ +{ + "interfaceDescription": "Column Definition interface.", + "propertiesDescriptions": { + "field": { + "description": "The column identifier. It's used to map with GridRowModel values." + }, + "aggregable": { + "description": "If true, the cells of the column can be aggregated based." + }, + "align": { "description": "Allows to align the column values in cells." }, + "availableAggregationFunctions": { + "description": "Limit the aggregation function usable on this column.
    By default, the column will have all the aggregation functions that are compatible with its type." + }, + "cellClassName": { "description": "Class name that will be added in cells for that column." }, + "colSpan": { "description": "Number of columns a cell should span." }, + "description": { + "description": "The description of the column rendered as tooltip if the column header name is not fully displayed." + }, + "disableColumnMenu": { + "description": "If true, the column menu is disabled for this column." + }, + "disableExport": { + "description": "If true, this column will not be included in exports." + }, + "disableReorder": { "description": "If true, this column cannot be reordered." }, + "display": { + "description": "Display mode for the cell:
    - 'text': For text-based cells (default)
    - 'flex': For cells with HTMLElement children" + }, + "editable": { "description": "If true, the cells of the column are editable." }, + "filterable": { "description": "If true, the column is filterable." }, + "filterOperators": { "description": "Allows setting the filter operators for this column." }, + "flex": { "description": "If set, it indicates that a column has fluid width. Range [0, ∞)." }, + "getApplyQuickFilterFn": { + "description": "The callback that generates a filtering function for a given quick filter value.
    This function can return null to skip filtering for this value and column." + }, + "getSortComparator": { + "description": "Allows to use a different comparator function depending on the sort direction.
    Takes precedence over sortComparator." + }, + "groupable": { + "description": "If true, the rows can be grouped based on this column values (pro-plan only).
    Only available in DataGridPremium." + }, + "groupingValueGetter": { + "description": "Function that transforms a complex cell value into a key that be used for grouping the rows." + }, + "headerAlign": { "description": "Header cell element alignment." }, + "headerClassName": { + "description": "Class name that will be added in the column header cell." + }, + "headerName": { "description": "The title of the column rendered in the column header cell." }, + "hideable": { + "description": "If false, removes the buttons for hiding this column." + }, + "hideSortIcons": { "description": "Toggle the visibility of the sort icons." }, + "maxWidth": { "description": "Sets the maximum width of a column." }, + "minWidth": { "description": "Sets the minimum width of a column." }, + "pastedValueParser": { + "description": "Function that takes the clipboard-pasted value and converts it to a value used internally." + }, + "pinnable": { + "description": "If false, the menu items for column pinning menu will not be rendered.
    Only available in DataGridPro." + }, + "preProcessEditCellProps": { + "description": "Callback fired when the edit props of the cell changes.
    It allows to process the props that saved into the state." + }, + "renderCell": { + "description": "Allows to override the component rendered as cell for this column." + }, + "renderEditCell": { + "description": "Allows to override the component rendered in edit cell mode for this column." + }, + "renderHeader": { "description": "Allows to render a component in the column header cell." }, + "renderHeaderFilter": { + "description": "Allows to render a component in the column header filter cell." + }, + "resizable": { "description": "If true, the column is resizable." }, + "sortable": { "description": "If true, the column is sortable." }, + "sortComparator": { "description": "A comparator function used to sort rows." }, + "sortingOrder": { "description": "The order of the sorting sequence." }, + "type": { "description": "The type of the column." }, + "valueFormatter": { + "description": "Function that allows to apply a formatter before rendering its value." + }, + "valueGetter": { + "description": "Function that allows to get a specific data instead of field to render in the cell." + }, + "valueParser": { + "description": "Function that takes the user-entered value and converts it to a value used internally." + }, + "valueSetter": { + "description": "Function that allows to customize how the entered value is stored in the row.
    It only works with cell/row editing." + }, + "width": { "description": "Set the width of the column." } + } +} diff --git a/docs/translations/api-docs/data-grid/grid-csv-export-options.json b/docs/translations/api-docs/data-grid/grid-csv-export-options.json new file mode 100644 index 0000000000000..dfcea88f04e02 --- /dev/null +++ b/docs/translations/api-docs/data-grid/grid-csv-export-options.json @@ -0,0 +1,25 @@ +{ + "interfaceDescription": "The options to apply on the CSV export.", + "propertiesDescriptions": { + "allColumns": { + "description": "If true, the hidden columns will also be exported." + }, + "delimiter": { "description": "The character used to separate fields." }, + "fields": { + "description": "The columns exported.
    This should only be used if you want to restrict the columns exports." + }, + "fileName": { "description": "The string used as the file name." }, + "getRowsToExport": { + "description": "Function that returns the list of row ids to export on the order they should be exported." + }, + "includeColumnGroupsHeaders": { + "description": "If true, the CSV will include the column groups." + }, + "includeHeaders": { + "description": "If true, the CSV will include the column headers and column groups.
    Use includeColumnGroupsHeaders to control whether the column groups are included." + }, + "utf8WithBom": { + "description": "If true, the UTF-8 Byte Order Mark (BOM) prefixes the exported file.
    This can allow Excel to automatically detect file encoding as UTF-8." + } + } +} diff --git a/docs/translations/api-docs/data-grid/grid-excel-export-options.json b/docs/translations/api-docs/data-grid/grid-excel-export-options.json new file mode 100644 index 0000000000000..f05570b1eaff7 --- /dev/null +++ b/docs/translations/api-docs/data-grid/grid-excel-export-options.json @@ -0,0 +1,32 @@ +{ + "interfaceDescription": "The options to apply on the Excel export.", + "propertiesDescriptions": { + "allColumns": { + "description": "If true, the hidden columns will also be exported." + }, + "columnsStyles": { "description": "Object mapping column field to Exceljs style" }, + "exceljsPostProcess": { + "description": "Method called after adding the rows to the workbook.
    Not supported when worker is set.
    To use with web workers, use the option in setupExcelExportWebWorker." + }, + "exceljsPreProcess": { + "description": "Method called before adding the rows to the workbook.
    Not supported when worker is set.
    To use with web workers, use the option in setupExcelExportWebWorker." + }, + "fields": { + "description": "The columns exported.
    This should only be used if you want to restrict the columns exports." + }, + "fileName": { "description": "The string used as the file name." }, + "getRowsToExport": { + "description": "Function that returns the list of row ids to export on the order they should be exported." + }, + "includeColumnGroupsHeaders": { + "description": "If true, the headers of the column groups will be added into the file." + }, + "includeHeaders": { + "description": "If true, the first row of the file will include the headers of the grid." + }, + "valueOptionsSheetName": { + "description": "Name given to the worksheet containing the columns valueOptions.
    valueOptions are added to this worksheet if they are provided as an array." + }, + "worker": { "description": "Function to return the Worker instance to be called." } + } +} diff --git a/docs/translations/api-docs/data-grid/grid-export-state-params.json b/docs/translations/api-docs/data-grid/grid-export-state-params.json new file mode 100644 index 0000000000000..752dbbf778934 --- /dev/null +++ b/docs/translations/api-docs/data-grid/grid-export-state-params.json @@ -0,0 +1,8 @@ +{ + "interfaceDescription": "Object passed as parameter in the exportState() grid API method.", + "propertiesDescriptions": { + "exportOnlyDirtyModels": { + "description": "By default, the grid exports all the models.
    You can switch this property to true to only exports models that are either controlled, initialized or modified.
    For instance, with this property, if you don't control or initialize the filterModel and you did not apply any filter, the model won't be exported.
    Note that the column dimensions are not a model. The grid only exports the dimensions of the modified columns even when exportOnlyDirtyModels is false." + } + } +} diff --git a/docs/translations/api-docs/data-grid/grid-filter-item.json b/docs/translations/api-docs/data-grid/grid-filter-item.json new file mode 100644 index 0000000000000..68a0d9cafdd1f --- /dev/null +++ b/docs/translations/api-docs/data-grid/grid-filter-item.json @@ -0,0 +1,13 @@ +{ + "interfaceDescription": "Filter item definition interface.", + "propertiesDescriptions": { + "field": { "description": "The column from which we want to filter the rows." }, + "operator": { "description": "The name of the operator we want to apply." }, + "id": { + "description": "Must be unique.
    Only useful when the model contains several items." + }, + "value": { + "description": "The filtering value.
    The operator filtering function will decide for each row if the row values is correct compared to this value." + } + } +} diff --git a/docs/translations/api-docs/data-grid/grid-filter-model.json b/docs/translations/api-docs/data-grid/grid-filter-model.json new file mode 100644 index 0000000000000..32f3d45af4806 --- /dev/null +++ b/docs/translations/api-docs/data-grid/grid-filter-model.json @@ -0,0 +1,16 @@ +{ + "interfaceDescription": "Model describing the filters to apply to the grid.", + "propertiesDescriptions": { + "items": { "description": "" }, + "logicOperator": { + "description": "- GridLogicOperator.And: the row must pass all the filter items.
    - GridLogicOperator.Or: the row must pass at least on filter item." + }, + "quickFilterExcludeHiddenColumns": { + "description": "If false, the quick filter will also consider cell values from hidden columns." + }, + "quickFilterLogicOperator": { + "description": "- GridLogicOperator.And: the row must pass all the values.
    - GridLogicOperator.Or: the row must pass at least one value." + }, + "quickFilterValues": { "description": "values used to quick filter rows" } + } +} diff --git a/docs/translations/api-docs/data-grid/grid-filter-operator.json b/docs/translations/api-docs/data-grid/grid-filter-operator.json new file mode 100644 index 0000000000000..38d966ab5a97b --- /dev/null +++ b/docs/translations/api-docs/data-grid/grid-filter-operator.json @@ -0,0 +1,25 @@ +{ + "interfaceDescription": "Filter operator definition interface.", + "propertiesDescriptions": { + "getApplyFilterFn": { + "description": "The callback that generates a filtering function for a given filter item and column.
    This function can return null to skip filtering for this item and column." + }, + "value": { + "description": "The name of the filter operator.
    It will be matched with the operator property of the filter items." + }, + "getValueAsString": { + "description": "Converts the value of a filter item to a human-readable form." + }, + "headerLabel": { "description": "The label of the filter shown in header filter row." }, + "InputComponent": { + "description": "The input component to render in the filter panel for this filter operator." + }, + "InputComponentProps": { + "description": "The props to pass to the input component in the filter panel for this filter operator." + }, + "label": { "description": "The label of the filter operator." }, + "requiresFilterValue": { + "description": "If false, filter operator doesn't require user-entered value to work.
    Usually should be set to false for filter operators that don't have InputComponent (for example isEmpty)" + } + } +} diff --git a/docs/translations/api-docs/data-grid/grid-print-export-options.json b/docs/translations/api-docs/data-grid/grid-print-export-options.json new file mode 100644 index 0000000000000..cee7cee030e42 --- /dev/null +++ b/docs/translations/api-docs/data-grid/grid-print-export-options.json @@ -0,0 +1,29 @@ +{ + "interfaceDescription": "The options to apply on the Print export.", + "propertiesDescriptions": { + "allColumns": { + "description": "If true, the hidden columns will also be exported." + }, + "bodyClassName": { "description": "One or more classes passed to the print window." }, + "copyStyles": { + "description": "If false, all <style> and <link type="stylesheet" /> tags from the <head> will not be copied
    to the print window." + }, + "fields": { + "description": "The columns exported.
    This should only be used if you want to restrict the columns exports." + }, + "fileName": { "description": "The value to be used as the print window title." }, + "getRowsToExport": { + "description": "Function that returns the list of row ids to export in the order they should be exported." + }, + "hideFooter": { + "description": "If true, the footer is removed for when printing." + }, + "hideToolbar": { + "description": "If true, the toolbar is removed for when printing." + }, + "includeCheckboxes": { + "description": "If true, the selection checkboxes will be included when printing." + }, + "pageStyle": { "description": "Provide Print specific styles to the print window." } + } +} diff --git a/docs/translations/api-docs/data-grid/grid-row-class-name-params.json b/docs/translations/api-docs/data-grid/grid-row-class-name-params.json new file mode 100644 index 0000000000000..e3f7e4f1b6ed9 --- /dev/null +++ b/docs/translations/api-docs/data-grid/grid-row-class-name-params.json @@ -0,0 +1,13 @@ +{ + "interfaceDescription": "Object passed as parameter in the row getRowClassName callback prop.", + "propertiesDescriptions": { + "columns": { "description": "All grid columns." }, + "id": { "description": "The grid row id." }, + "indexRelativeToCurrentPage": { + "description": "Index of the row in the current page.
    If the pagination is disabled, it will be the index relative to all filtered rows." + }, + "isFirstVisible": { "description": "Whether this row is the first visible or not." }, + "isLastVisible": { "description": "Whether this row is the last visible or not." }, + "row": { "description": "The row model of the row that the current cell belongs to." } + } +} diff --git a/docs/translations/api-docs/data-grid/grid-row-params.json b/docs/translations/api-docs/data-grid/grid-row-params.json new file mode 100644 index 0000000000000..b50741df1a320 --- /dev/null +++ b/docs/translations/api-docs/data-grid/grid-row-params.json @@ -0,0 +1,8 @@ +{ + "interfaceDescription": "Object passed as parameter in the row callbacks.", + "propertiesDescriptions": { + "columns": { "description": "All grid columns." }, + "id": { "description": "The grid row id." }, + "row": { "description": "The row model of the row that the current cell belongs to." } + } +} diff --git a/docs/translations/api-docs/data-grid/grid-row-spacing-params.json b/docs/translations/api-docs/data-grid/grid-row-spacing-params.json new file mode 100644 index 0000000000000..d2b53254082b9 --- /dev/null +++ b/docs/translations/api-docs/data-grid/grid-row-spacing-params.json @@ -0,0 +1,12 @@ +{ + "interfaceDescription": "Object passed as parameter in the row getRowSpacing callback prop.", + "propertiesDescriptions": { + "id": { "description": "The row id." }, + "indexRelativeToCurrentPage": { + "description": "Index of the row in the current page.
    If the pagination is disabled, it will be the index relative to all filtered rows." + }, + "isFirstVisible": { "description": "Whether this row is the first visible or not." }, + "isLastVisible": { "description": "Whether this row is the last visible or not." }, + "model": { "description": "The row model." } + } +} diff --git a/docs/translations/api-docs/data-grid/grid-single-select-col-def.json b/docs/translations/api-docs/data-grid/grid-single-select-col-def.json new file mode 100644 index 0000000000000..fdd0720fd1a26 --- /dev/null +++ b/docs/translations/api-docs/data-grid/grid-single-select-col-def.json @@ -0,0 +1,101 @@ +{ + "interfaceDescription": "Column Definition interface used for columns with the singleSelect type.", + "propertiesDescriptions": { + "field": { + "description": "The column identifier. It's used to map with GridRowModel values." + }, + "type": { "description": "The type of the column." }, + "aggregable": { + "description": "If true, the cells of the column can be aggregated based." + }, + "align": { "description": "Allows to align the column values in cells." }, + "availableAggregationFunctions": { + "description": "Limit the aggregation function usable on this column.
    By default, the column will have all the aggregation functions that are compatible with its type." + }, + "cellClassName": { "description": "Class name that will be added in cells for that column." }, + "colSpan": { "description": "Number of columns a cell should span." }, + "description": { + "description": "The description of the column rendered as tooltip if the column header name is not fully displayed." + }, + "disableColumnMenu": { + "description": "If true, the column menu is disabled for this column." + }, + "disableExport": { + "description": "If true, this column will not be included in exports." + }, + "disableReorder": { "description": "If true, this column cannot be reordered." }, + "display": { + "description": "Display mode for the cell:
    - 'text': For text-based cells (default)
    - 'flex': For cells with HTMLElement children" + }, + "editable": { "description": "If true, the cells of the column are editable." }, + "filterable": { "description": "If true, the column is filterable." }, + "filterOperators": { "description": "Allows setting the filter operators for this column." }, + "flex": { "description": "If set, it indicates that a column has fluid width. Range [0, ∞)." }, + "getApplyQuickFilterFn": { + "description": "The callback that generates a filtering function for a given quick filter value.
    This function can return null to skip filtering for this value and column." + }, + "getOptionLabel": { + "description": "Used to determine the label displayed for a given value option." + }, + "getOptionValue": { "description": "Used to determine the value used for a value option." }, + "getSortComparator": { + "description": "Allows to use a different comparator function depending on the sort direction.
    Takes precedence over sortComparator." + }, + "groupable": { + "description": "If true, the rows can be grouped based on this column values (pro-plan only).
    Only available in DataGridPremium." + }, + "groupingValueGetter": { + "description": "Function that transforms a complex cell value into a key that be used for grouping the rows." + }, + "headerAlign": { "description": "Header cell element alignment." }, + "headerClassName": { + "description": "Class name that will be added in the column header cell." + }, + "headerName": { "description": "The title of the column rendered in the column header cell." }, + "hideable": { + "description": "If false, removes the buttons for hiding this column." + }, + "hideSortIcons": { "description": "Toggle the visibility of the sort icons." }, + "maxWidth": { "description": "Sets the maximum width of a column." }, + "minWidth": { "description": "Sets the minimum width of a column." }, + "pastedValueParser": { + "description": "Function that takes the clipboard-pasted value and converts it to a value used internally." + }, + "pinnable": { + "description": "If false, the menu items for column pinning menu will not be rendered.
    Only available in DataGridPro." + }, + "preProcessEditCellProps": { + "description": "Callback fired when the edit props of the cell changes.
    It allows to process the props that saved into the state." + }, + "renderCell": { + "description": "Allows to override the component rendered as cell for this column." + }, + "renderEditCell": { + "description": "Allows to override the component rendered in edit cell mode for this column." + }, + "renderHeader": { "description": "Allows to render a component in the column header cell." }, + "renderHeaderFilter": { + "description": "Allows to render a component in the column header filter cell." + }, + "resizable": { "description": "If true, the column is resizable." }, + "sortable": { "description": "If true, the column is sortable." }, + "sortComparator": { "description": "A comparator function used to sort rows." }, + "sortingOrder": { "description": "The order of the sorting sequence." }, + "valueFormatter": { + "description": "Function that allows to apply a formatter before rendering its value." + }, + "valueGetter": { + "description": "Function that allows to get a specific data instead of field to render in the cell." + }, + "valueOptions": { + "description": "To be used in combination with type: 'singleSelect'. This is an array (or a function returning an array) of the possible cell values and labels." + }, + "valueParser": { + "description": "Function that takes the user-entered value and converts it to a value used internally." + }, + "valueSetter": { + "description": "Function that allows to customize how the entered value is stored in the row.
    It only works with cell/row editing." + }, + "width": { "description": "Set the width of the column." } + } +} From fdaafd163b030b36b5fce82e8396b44a422f01dc Mon Sep 17 00:00:00 2001 From: Lukas Date: Fri, 29 Mar 2024 14:06:49 +0200 Subject: [PATCH 34/55] [DateTimeRangePicker] Fix selection on same day (#12604) --- .../tests/DesktopDateTimeRangePicker.test.tsx | 35 +++++++++++++++++-- .../utils/date-range-manager.test.ts | 9 +++++ .../src/internals/utils/date-range-manager.ts | 2 +- 3 files changed, 43 insertions(+), 3 deletions(-) diff --git a/packages/x-date-pickers-pro/src/DesktopDateTimeRangePicker/tests/DesktopDateTimeRangePicker.test.tsx b/packages/x-date-pickers-pro/src/DesktopDateTimeRangePicker/tests/DesktopDateTimeRangePicker.test.tsx index 793d2a6682d92..d487a34c78de9 100644 --- a/packages/x-date-pickers-pro/src/DesktopDateTimeRangePicker/tests/DesktopDateTimeRangePicker.test.tsx +++ b/packages/x-date-pickers-pro/src/DesktopDateTimeRangePicker/tests/DesktopDateTimeRangePicker.test.tsx @@ -1,7 +1,13 @@ import * as React from 'react'; import { expect } from 'chai'; -import { screen } from '@mui-internal/test-utils'; -import { createPickerRenderer, adapterToUse } from 'test/utils/pickers'; +import { screen, userEvent } from '@mui-internal/test-utils'; +import { + createPickerRenderer, + adapterToUse, + openPicker, + getFieldSectionsContainer, + expectFieldValueV7, +} from 'test/utils/pickers'; import { DesktopDateTimeRangePicker } from '../DesktopDateTimeRangePicker'; describe('', () => { @@ -10,6 +16,31 @@ describe('', () => { clockConfig: new Date(2018, 0, 10, 10, 16, 0), }); + describe('value selection', () => { + it('should allow to select range within the same day', () => { + render(); + + openPicker({ type: 'date-time-range', variant: 'desktop', initialFocus: 'start' }); + + // select start date range + userEvent.mousePress(screen.getByRole('gridcell', { name: '11' })); + userEvent.mousePress(screen.getByRole('option', { name: '4 hours' })); + userEvent.mousePress(screen.getByRole('option', { name: '5 minutes' })); + userEvent.mousePress(screen.getByRole('option', { name: 'PM' })); + + // select end date range on the same day + userEvent.mousePress(screen.getByRole('gridcell', { name: '11' })); + userEvent.mousePress(screen.getByRole('option', { name: '5 hours' })); + userEvent.mousePress(screen.getByRole('option', { name: '10 minutes' })); + userEvent.mousePress(screen.getByRole('option', { name: 'PM' })); + + const startSectionsContainer = getFieldSectionsContainer(0); + const endSectionsContainer = getFieldSectionsContainer(1); + expect(expectFieldValueV7(startSectionsContainer, '01/11/2018 04:05 PM')); + expect(expectFieldValueV7(endSectionsContainer, '01/11/2018 05:10 PM')); + }); + }); + describe('disabled dates', () => { it('should respect the "disablePast" prop', () => { render(); diff --git a/packages/x-date-pickers-pro/src/internals/utils/date-range-manager.test.ts b/packages/x-date-pickers-pro/src/internals/utils/date-range-manager.test.ts index 2cfd3857d3f9d..1b49f7b99c605 100644 --- a/packages/x-date-pickers-pro/src/internals/utils/date-range-manager.test.ts +++ b/packages/x-date-pickers-pro/src/internals/utils/date-range-manager.test.ts @@ -4,6 +4,7 @@ import { calculateRangeChange, calculateRangePreview } from './date-range-manage import { DateRange } from '../../models'; const start2018 = adapterToUse.date('2018-01-01'); +const start2018At4PM = adapterToUse.date('2018-01-01T16:00:00'); const mid2018 = adapterToUse.date('2018-07-01'); const end2019 = adapterToUse.date('2019-01-01'); @@ -88,6 +89,14 @@ describe('date-range-manager', () => { allowRangeFlip: true, expectedNextSelection: 'end' as const, }, + { + range: [start2018At4PM, null], + rangePosition: 'end' as const, + newDate: start2018, + expectedRange: [start2018At4PM, start2018], + allowRangeFlip: false, + expectedNextSelection: 'start' as const, + }, ].forEach( ({ range, rangePosition, newDate, expectedRange, allowRangeFlip, expectedNextSelection }) => { it(`calculateRangeChange should return ${expectedRange} when selecting ${rangePosition} of ${range} with user input ${newDate}`, () => { diff --git a/packages/x-date-pickers-pro/src/internals/utils/date-range-manager.ts b/packages/x-date-pickers-pro/src/internals/utils/date-range-manager.ts index bc3eb99ca75cc..94d5d02e0eb06 100644 --- a/packages/x-date-pickers-pro/src/internals/utils/date-range-manager.ts +++ b/packages/x-date-pickers-pro/src/internals/utils/date-range-manager.ts @@ -53,7 +53,7 @@ export function calculateRangeChange({ const truthyResult: CalculateRangeChangeResponse = allowRangeFlip ? { nextSelection: 'end', newRange: [selectedDate, start!] } : { nextSelection: 'end', newRange: [selectedDate, null] }; - return Boolean(start) && utils.isBefore(selectedDate!, start!) + return Boolean(start) && utils.isBeforeDay(selectedDate!, start!) ? truthyResult : { nextSelection: 'start', newRange: [start, selectedDate] }; } From 81c84523addd8c77e6a798de2c08b8365db1483f Mon Sep 17 00:00:00 2001 From: Olivier Tassinari Date: Fri, 29 Mar 2024 13:43:13 +0100 Subject: [PATCH 35/55] =?UTF-8?q?[docs]=20Match=20IE=2011=20spacing=20with?= =?UTF-8?q?=20Material=C2=A0UI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 6 +++--- .../migration/migration-charts-v6/migration-charts-v6.md | 6 +++--- .../migration-data-grid-v6/migration-data-grid-v6.md | 6 +++--- .../migration/migration-pickers-v6/migration-pickers-v6.md | 6 +++--- .../migration-tree-view-v6/migration-tree-view-v6.md | 6 +++--- 5 files changed, 15 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 20431eaeb0da0..8fc6680381a88 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -530,13 +530,13 @@ We'd like to offer a big thanks to the 10 contributors who made this release pos - 🎁 Introduce a new DOM structure for the field components that provides a better accessibility - 🚀 Simplify Data Grid DOM structure for improved performance (#12013) @romgrk -- 🕥 The support for IE11 has been removed (#12151) @flaviendelangle +- 🕥 The support for IE 11 has been removed (#12151) @flaviendelangle - 🐞 Bugfixes - 📚 Documentation improvements ### Breaking changes -- The support for IE11 has been removed from all MUI X packages. The `legacy` bundle that used to support old browsers like IE11 is no longer included. +- The support for IE 11 has been removed from all MUI X packages. The `legacy` bundle that used to support old browsers like IE 11 is no longer included. ### Data Grid @@ -641,7 +641,7 @@ These components are no longer exported from `@mui/x-charts`: ### Tree View / `@mui/x-tree-view@7.0.0-beta.4` -- [TreeView] Stop using custom `findIndex` to support IE11 (#12129) @flaviendelangle +- [TreeView] Stop using custom `findIndex` to support IE 11 (#12129) @flaviendelangle ### Docs diff --git a/docs/data/migration/migration-charts-v6/migration-charts-v6.md b/docs/data/migration/migration-charts-v6/migration-charts-v6.md index e274f55159cba..aab269714266d 100644 --- a/docs/data/migration/migration-charts-v6/migration-charts-v6.md +++ b/docs/data/migration/migration-charts-v6/migration-charts-v6.md @@ -34,11 +34,11 @@ These changes were done for consistency, improved stability and to make room for ### Drop the legacy bundle -The support for IE11 has been removed from all MUI X packages. -The `legacy` bundle that used to support old browsers like IE11 is no longer included. +The support for IE 11 has been removed from all MUI X packages. +The `legacy` bundle that used to support old browsers like IE 11 is no longer included. :::info -If you need support for IE11, you will need to keep using the latest version of the `v6` release. +If you need support for IE 11, you will need to keep using the latest version of the `v6` release. ::: ### Renaming diff --git a/docs/data/migration/migration-data-grid-v6/migration-data-grid-v6.md b/docs/data/migration/migration-data-grid-v6/migration-data-grid-v6.md index 30679a6217f12..79eebfc473ff0 100644 --- a/docs/data/migration/migration-data-grid-v6/migration-data-grid-v6.md +++ b/docs/data/migration/migration-data-grid-v6/migration-data-grid-v6.md @@ -99,11 +99,11 @@ Below are described the steps you need to make to migrate from v6 to v7. ### Drop the legacy bundle -The support for IE11 has been removed from all MUI X packages. -The `legacy` bundle that used to support old browsers like IE11 is no longer included. +The support for IE 11 has been removed from all MUI X packages. +The `legacy` bundle that used to support old browsers like IE 11 is no longer included. :::info -If you need support for IE11, you will need to keep using the latest version of the `v6` release. +If you need support for IE 11, you will need to keep using the latest version of the `v6` release. ::: ### DOM changes diff --git a/docs/data/migration/migration-pickers-v6/migration-pickers-v6.md b/docs/data/migration/migration-pickers-v6/migration-pickers-v6.md index 035c24bfb82f5..e8c8cf78dd5ee 100644 --- a/docs/data/migration/migration-pickers-v6/migration-pickers-v6.md +++ b/docs/data/migration/migration-pickers-v6/migration-pickers-v6.md @@ -88,11 +88,11 @@ Feel free to [open an issue](https://github.com/mui/mui-x/issues/new/choose) for ## Drop the legacy bundle -The support for IE11 has been removed from all MUI X packages. -The `legacy` bundle that used to support old browsers like IE11 is no longer included. +The support for IE 11 has been removed from all MUI X packages. +The `legacy` bundle that used to support old browsers like IE 11 is no longer included. :::info -If you need support for IE11, you will need to keep using the latest version of the `v6` release. +If you need support for IE 11, you will need to keep using the latest version of the `v6` release. ::: ## Component slots diff --git a/docs/data/migration/migration-tree-view-v6/migration-tree-view-v6.md b/docs/data/migration/migration-tree-view-v6/migration-tree-view-v6.md index ba4f3df4b1129..1a468abb26331 100644 --- a/docs/data/migration/migration-tree-view-v6/migration-tree-view-v6.md +++ b/docs/data/migration/migration-tree-view-v6/migration-tree-view-v6.md @@ -33,11 +33,11 @@ These changes were done for consistency, improved stability and to make room for ### Drop the legacy bundle -The support for IE11 has been removed from all MUI X packages. -The `legacy` bundle that used to support old browsers like IE11 is no longer included. +The support for IE 11 has been removed from all MUI X packages. +The `legacy` bundle that used to support old browsers like IE 11 is no longer included. :::info -If you need support for IE11, you will need to keep using the latest version of the `v6` release. +If you need support for IE 11, you will need to keep using the latest version of the `v6` release. ::: ### ✅ Rename `nodeId` to `itemId` From 608bb36cd5727cde7b800d5d8852286873aa41cd Mon Sep 17 00:00:00 2001 From: Olivier Tassinari Date: Fri, 29 Mar 2024 13:48:53 +0100 Subject: [PATCH 36/55] [docs] Fix formatting and typo on migration guide --- .../migration-data-grid-v6.md | 72 ++++++++++--------- .../migration-pickers-v6.md | 11 +-- 2 files changed, 43 insertions(+), 40 deletions(-) diff --git a/docs/data/migration/migration-data-grid-v6/migration-data-grid-v6.md b/docs/data/migration/migration-data-grid-v6/migration-data-grid-v6.md index 79eebfc473ff0..328ada32ec59d 100644 --- a/docs/data/migration/migration-data-grid-v6/migration-data-grid-v6.md +++ b/docs/data/migration/migration-data-grid-v6/migration-data-grid-v6.md @@ -18,8 +18,10 @@ In `package.json`, change the version of the data grid package to `^7.0.0`. ```diff -"@mui/x-data-grid": "6.x.x", +"@mui/x-data-grid": "^7.0.0", + -"@mui/x-data-grid-pro": "6.x.x", +"@mui/x-data-grid-pro": "^7.0.0", + -"@mui/x-data-grid-premium": "6.x.x", +"@mui/x-data-grid-premium": "^7.0.0", ``` @@ -166,8 +168,8 @@ Here's the list of affected features, column definition flags and props to disab Some selectors now require passing `instanceId` as a second argument: ```diff -- gridColumnFieldsSelector(apiRef.current.state); -+ gridColumnFieldsSelector(apiRef.current.state, apiRef.current.instanceId); +-gridColumnFieldsSelector(apiRef.current.state); ++gridColumnFieldsSelector(apiRef.current.state, apiRef.current.instanceId); ``` However, it's preferable to pass the `apiRef` as the first argument instead: @@ -205,9 +207,9 @@ See the [Direct state access](/x/react-data-grid/state/#direct-selector-access) - The type `GridPinnedPosition` has been renamed to `GridPinnedColumnPosition`. -- The column grouping API methods `getColumnGroupPath` and `getAllGroupDetails` are not anymore prefixed with `unstable_`. +- The column grouping API methods `getColumnGroupPath` and `getAllGroupDetails` are no longer prefixed with `unstable_`. -- The column grouping selectors `gridFocusColumnGroupHeaderSelector` and `gridTabIndexColumnGroupHeaderSelector` are not anymore prefixed with `unstable_`. +- The column grouping selectors `gridFocusColumnGroupHeaderSelector` and `gridTabIndexColumnGroupHeaderSelector` are no longer prefixed with `unstable_`. - The columns management component has been redesigned and the component is extracted from the `ColumnsPanel` which now only serves as a wrapper to display the component over the headers as a panel. As a result, a new slot `columnsManagement`, and corresponding prop `slotProps.columnsManagement` have been introduced. The props corresponding to the columns management component which were previously passed to the prop `slotProps.columnsPanel` should now be passed to `slotProps.columnsManagement`. `slotProps.columnsPanel` could still be used to override props corresponding to the `Panel` component used in `ColumnsPanel` which uses [`Popper`](/material-ui/react-popper/) component under the hood. @@ -228,83 +230,83 @@ See the [Direct state access](/x/react-data-grid/state/#direct-selector-access) - The signature of `GridColDef['valueGetter']` has been changed for performance reasons: ```diff - - valueGetter: ({ value, row }) => value, - + valueGetter: (value, row, column, apiRef) => value, + -valueGetter: ({ value, row }) => value, + +valueGetter: (value, row, column, apiRef) => value, ``` The `GridValueGetterParams` interface has been removed: ```diff - - const customValueGetter = (params: GridValueGetterParams) => params.row.budget; - + const customValueGetter: GridValueGetterFn = (value, row) => row.budget; + -const customValueGetter = (params: GridValueGetterParams) => params.row.budget; + +const customValueGetter: GridValueGetterFn = (value, row) => row.budget; ``` - The signature of `GridColDef['valueFormatter']` has been changed for performance reasons: ```diff - - valueFormatter: ({ value }) => value, - + valueFormatter: (value, row, column, apiRef) => value, + -valueFormatter: ({ value }) => value, + + alueFormatter: (value, row, column, apiRef) => value, ``` The `GridValueFormatterParams` interface has been removed: ```diff - - const gridDateFormatter = ({ value, field, id }: GridValueFormatterParams) => value.toLocaleDateString(); - + const gridDateFormatter: GridValueFormatter = (value: Date) => value.toLocaleDateString(); + -const gridDateFormatter = ({ value, field, id }: GridValueFormatterParams) => value.toLocaleDateString(); + +const gridDateFormatter: GridValueFormatter = (value: Date) => value.toLocaleDateString(); ``` - The signature of `GridColDef['valueSetter']` has been changed for performance reasons: ```diff - - valueSetter: (params) => { - - const [firstName, lastName] = params.value!.toString().split(' '); - - return { ...params.row, firstName, lastName }; - - } - + valueSetter: (value, row) => { - + const [firstName, lastName] = value!.toString().split(' '); - + return { ...row, firstName, lastName }; + -valueSetter: (params) => { + - const [firstName, lastName] = params.value!.toString().split(' '); + - return { ...params.row, firstName, lastName }; + -} + +valueSetter: (value, row) => { + + const [firstName, lastName] = value!.toString().split(' '); + + return { ...row, firstName, lastName }; +} ``` The `GridValueSetterParams` interface has been removed: ```diff - - const setFullName = (params: GridValueSetterParams) => { - - const [firstName, lastName] = params.value!.toString().split(' '); - - return { ...params.row, firstName, lastName }; - - }; - + const setFullName: GridValueSetter = (value, row) => { - + const [firstName, lastName] = value!.toString().split(' '); - + return { ...row, firstName, lastName }; - + } + -const setFullName = (params: GridValueSetterParams) => { + - const [firstName, lastName] = params.value!.toString().split(' '); + - return { ...params.row, firstName, lastName }; + -}; + +const setFullName: GridValueSetter = (value, row) => { + + const [firstName, lastName] = value!.toString().split(' '); + + return { ...row, firstName, lastName }; + +} ``` - The signature of `GridColDef['valueParser']` has been changed for performance reasons: ```diff - - valueParser: (value, params: GridCellParams) => value.toLowerCase(), - + valueParser: (value, row, column, apiRef) => value.toLowerCase(), + -valueParser: (value, params: GridCellParams) => value.toLowerCase(), + +valueParser: (value, row, column, apiRef) => value.toLowerCase(), ``` - The signature of `GridColDef['colSpan']` has been changed for performance reasons: ```diff - - colSpan: ({ row, field, value }: GridCellParams) => (row.id === 'total' ? 2 : 1), - + colSpan: (value, row, column, apiRef) => (row.id === 'total' ? 2 : 1), + -colSpan: ({ row, field, value }: GridCellParams) => (row.id === 'total' ? 2 : 1), + +colSpan: (value, row, column, apiRef) => (row.id === 'total' ? 2 : 1), ``` - The signature of `GridColDef['pastedValueParser']` has been changed for performance reasons: ```diff - - pastedValueParser: (value, params) => new Date(value), - + pastedValueParser: (value, row, column, apiRef) => new Date(value), + -pastedValueParser: (value, params) => new Date(value), + +pastedValueParser: (value, row, column, apiRef) => new Date(value), ``` - The signature of `GridColDef['groupingValueGetter']` has been changed for performance reasons: ```diff - - groupingValueGetter: (params) => params.value.name, - + groupingValueGetter: (value: { name: string }) => value.name, + -groupingValueGetter: (params) => params.value.name, + +groupingValueGetter: (value: { name: string }) => value.name, ``` ### Density diff --git a/docs/data/migration/migration-pickers-v6/migration-pickers-v6.md b/docs/data/migration/migration-pickers-v6/migration-pickers-v6.md index e8c8cf78dd5ee..eac5ac7a0046a 100644 --- a/docs/data/migration/migration-pickers-v6/migration-pickers-v6.md +++ b/docs/data/migration/migration-pickers-v6/migration-pickers-v6.md @@ -294,7 +294,7 @@ To keep the same behavior, you can replace it by `hasLeadingZerosInFormat` ### Headless fields :::success -The following breaking changes only impacts you if you are using hooks like `useDateField` to build a custom UI. +The following breaking changes only impact you if you are using hooks like `useDateField` to build a custom UI. If you are just using the regular field components, then you can safely skip this section. ::: @@ -304,9 +304,9 @@ If you are just using the regular field components, then you can safely skip thi The field hooks now only receive the props instead of an object containing both the props and the `inputRef`. ```diff -- const { inputRef, ...otherProps } = props -- const fieldResponse = useDateField({ props: otherProps, inputRef }); -+ const fieldResponse = useDateField(props); +-const { inputRef, ...otherProps } = props +-const fieldResponse = useDateField({ props: otherProps, inputRef }); ++const fieldResponse = useDateField(props); ``` If you are using a multi input range field hook, the same applies to `startInputRef` and `endInputRef` params @@ -408,7 +408,8 @@ When building a custom UI, you are most-likely only supporting one DOM structure function MyCustomField(props) { const fieldResponse = useDateField({ ...props, -+ // If you only support one DOM structure, we advise you to hardcode it here to avoid unwanted switches in your application ++ // If you only support one DOM structure, we advise you to hardcode it ++ // here to avoid unwanted switches in your application. + enableAccessibleFieldDOMStructure: false, }); From 96d2b5b3f713374919bf5655f4d66f679280c5b7 Mon Sep 17 00:00:00 2001 From: Olivier Tassinari Date: Fri, 29 Mar 2024 14:05:35 +0100 Subject: [PATCH 37/55] [docs] Fix formatting in changelog --- .../migration-tree-view-v6.md | 27 +++++++++---------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/docs/data/migration/migration-tree-view-v6/migration-tree-view-v6.md b/docs/data/migration/migration-tree-view-v6/migration-tree-view-v6.md index 1a468abb26331..4a368c1dc098e 100644 --- a/docs/data/migration/migration-tree-view-v6/migration-tree-view-v6.md +++ b/docs/data/migration/migration-tree-view-v6/migration-tree-view-v6.md @@ -46,28 +46,27 @@ The required `nodeId` prop used by the `TreeItem` has been renamed to `itemId` f ```diff -- -+ +- ++ ``` The same change has been applied to the and `ContentComponent` prop: ```diff - const CustomContent = React.forwardRef((props, ref) => { + const CustomContent = React.forwardRef((props, ref) => { - const id = props.nodeId; + const id = props.itemId; + // Render some UI + }); - // Render some UI - }); - - function App() { - return ( - - - - ) - } + function App() { + return ( + + + + ) + } ``` ### ✅ Use `SimpleTreeView` instead of `TreeView` @@ -305,8 +304,8 @@ you need to use the new `groupTransition` slot on this component: itemId="1" label="Item 1" - TransitionComponent={Fade} -+ slots={{ groupTransition: Fade }} - TransitionProps={{ timeout: 600 }} ++ slots={{ groupTransition: Fade }} + slotProps={{ groupTransition: { timeout: 600 } }} />
    From 7a3a8892970135d4f41951379ac5dbc58ae9fc25 Mon Sep 17 00:00:00 2001 From: Flavien DELANGLE Date: Fri, 29 Mar 2024 14:40:58 +0100 Subject: [PATCH 38/55] [Tree View] Create pro package (#12240) --- .codesandbox/ci.json | 3 +- .eslintrc.js | 2 + babel.config.js | 1 + docs/babel.config.js | 1 + docs/scripts/createXTypeScriptProjects.ts | 22 +++++- packages/x-charts/package.json | 2 +- packages/x-data-grid-premium/README.md | 2 +- packages/x-data-grid-premium/package.json | 2 +- packages/x-data-grid-pro/README.md | 2 +- packages/x-data-grid-pro/package.json | 2 +- packages/x-data-grid/README.md | 2 +- packages/x-data-grid/package.json | 2 +- packages/x-date-pickers-pro/README.md | 2 +- packages/x-date-pickers-pro/package.json | 2 +- packages/x-date-pickers/README.md | 2 +- packages/x-date-pickers/package.json | 2 +- packages/x-tree-view-pro/LICENSE | 11 +++ packages/x-tree-view-pro/README.md | 26 +++++++ packages/x-tree-view-pro/package.json | 70 +++++++++++++++++++ packages/x-tree-view-pro/src/index.ts | 1 + packages/x-tree-view-pro/tsconfig.build.json | 19 +++++ packages/x-tree-view-pro/tsconfig.json | 13 ++++ packages/x-tree-view/README.md | 2 +- packages/x-tree-view/package.json | 2 +- .../treeViewSettings/getComponentInfo.ts | 2 +- tsconfig.json | 2 + webpackBaseConfig.js | 1 + 27 files changed, 184 insertions(+), 16 deletions(-) create mode 100644 packages/x-tree-view-pro/LICENSE create mode 100644 packages/x-tree-view-pro/README.md create mode 100644 packages/x-tree-view-pro/package.json create mode 100644 packages/x-tree-view-pro/src/index.ts create mode 100644 packages/x-tree-view-pro/tsconfig.build.json create mode 100644 packages/x-tree-view-pro/tsconfig.json diff --git a/.codesandbox/ci.json b/.codesandbox/ci.json index e08318b0ba92c..cadf03b4f49f2 100644 --- a/.codesandbox/ci.json +++ b/.codesandbox/ci.json @@ -22,7 +22,8 @@ "@mui/x-date-pickers": "packages/x-date-pickers/build", "@mui/x-date-pickers-pro": "packages/x-date-pickers-pro/build", "@mui/x-charts": "packages/x-charts/build", - "@mui/x-tree-view": "packages/x-tree-view/build" + "@mui/x-tree-view": "packages/x-tree-view/build", + "@mui/x-tree-view-pro": "packages/x-tree-view-pro/build" }, "sandboxes": ["/bug-reproductions/x-data-grid"], "silent": true diff --git a/.eslintrc.js b/.eslintrc.js index 99d1462f8f7d4..c2de50d965d78 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -163,6 +163,8 @@ module.exports = { buildPackageRestrictedImports('@mui/x-data-grid-generator', 'x-data-grid-generator'), buildPackageRestrictedImports('@mui/x-pickers', 'x-pickers'), buildPackageRestrictedImports('@mui/x-pickers-pro', 'x-pickers-pro'), + buildPackageRestrictedImports('@mui/x-tree-view', 'x-tree-view'), + buildPackageRestrictedImports('@mui/x-tree-view-pro', 'x-tree-view-pro'), buildPackageRestrictedImports('@mui/x-license', 'x-license'), ], }; diff --git a/babel.config.js b/babel.config.js index e57e327f19eea..cffee2bfde9e9 100644 --- a/babel.config.js +++ b/babel.config.js @@ -16,6 +16,7 @@ const defaultAlias = { '@mui/x-date-pickers-pro': resolveAliasPath('./packages/x-date-pickers-pro/src'), '@mui/x-charts': resolveAliasPath('./packages/x-charts/src'), '@mui/x-tree-view': resolveAliasPath('./packages/x-tree-view/src'), + '@mui/x-tree-view-pro': resolveAliasPath('./packages/x-tree-view-pro/src'), '@mui/material-nextjs': '@mui/monorepo/packages/mui-material-nextjs/src', '@mui-internal/api-docs-builder': resolveAliasPath( './node_modules/@mui/monorepo/packages/api-docs-builder', diff --git a/docs/babel.config.js b/docs/babel.config.js index 4523a10447b15..939795a4f573d 100644 --- a/docs/babel.config.js +++ b/docs/babel.config.js @@ -10,6 +10,7 @@ const alias = { '@mui/x-date-pickers-pro': '../packages/x-date-pickers-pro/src', '@mui/x-charts': '../packages/x-charts/src', '@mui/x-tree-view': '../packages/x-tree-view/src', + '@mui/x-tree-view-pro': '../packages/x-tree-view-pro/src', '@mui/x-license': '../packages/x-license/src', '@mui/docs': '../node_modules/@mui/monorepo/packages/mui-docs/src', '@mui/monorepo': '../node_modules/@mui/monorepo', diff --git a/docs/scripts/createXTypeScriptProjects.ts b/docs/scripts/createXTypeScriptProjects.ts index b5bc86f9850a1..a997d7689b421 100644 --- a/docs/scripts/createXTypeScriptProjects.ts +++ b/docs/scripts/createXTypeScriptProjects.ts @@ -37,7 +37,8 @@ export type XProjectNames = | 'x-date-pickers' | 'x-date-pickers-pro' | 'x-charts' - | 'x-tree-view'; + | 'x-tree-view' + | 'x-tree-view-pro'; export type XTypeScriptProjects = Map; @@ -264,5 +265,24 @@ export const createXTypeScriptProjects = () => { }), ); + // TODO x-tree-view-pro uncomment when making the package public + // projects.set( + // 'x-tree-view-pro', + // createXTypeScriptProject({ + // name: 'x-tree-view-pro', + // rootPath: path.join(workspaceRoot, 'packages/x-tree-view-pro'), + // entryPointPath: 'src/index.ts', + // documentationFolderName: 'tree-view', + // getComponentsWithPropTypes: getComponentPaths({ + // folders: ['src'], + // includeUnstableComponents: true, + // }), + // getComponentsWithApiDoc: getComponentPaths({ + // folders: ['src'], + // includeUnstableComponents: true, + // }), + // }), + // ); + return projects; }; diff --git a/packages/x-charts/package.json b/packages/x-charts/package.json index 10834c1fb58b9..2538e10728530 100644 --- a/packages/x-charts/package.json +++ b/packages/x-charts/package.json @@ -1,7 +1,7 @@ { "name": "@mui/x-charts", "version": "7.1.0", - "description": "The community edition of the charts components (MUI X).", + "description": "The community edition of the Charts components (MUI X).", "author": "MUI Team", "main": "./src/index.js", "license": "MIT", diff --git a/packages/x-data-grid-premium/README.md b/packages/x-data-grid-premium/README.md index 34036ebef3d5a..c8527da8ec8b6 100644 --- a/packages/x-data-grid-premium/README.md +++ b/packages/x-data-grid-premium/README.md @@ -1,6 +1,6 @@ # MUI X Data Grid Premium -This package is the Premium plan edition of the data grid component. +This package is the Premium plan edition of the Data Grid components. It's part of [MUI X](https://mui.com/x/), an open-core extension of MUI Core, with advanced components. ## Installation diff --git a/packages/x-data-grid-premium/package.json b/packages/x-data-grid-premium/package.json index 2885218e39a56..21a3a670cd7b5 100644 --- a/packages/x-data-grid-premium/package.json +++ b/packages/x-data-grid-premium/package.json @@ -1,7 +1,7 @@ { "name": "@mui/x-data-grid-premium", "version": "7.1.0", - "description": "The Premium plan edition of the data grid component (MUI X).", + "description": "The Premium plan edition of the Data Grid Components (MUI X).", "author": "MUI Team", "main": "src/index.ts", "license": "SEE LICENSE IN LICENSE", diff --git a/packages/x-data-grid-pro/README.md b/packages/x-data-grid-pro/README.md index 5f3ae959ca011..25a3704effd43 100644 --- a/packages/x-data-grid-pro/README.md +++ b/packages/x-data-grid-pro/README.md @@ -1,6 +1,6 @@ # MUI X Data Grid Pro -This package is the Pro plan edition of the data grid component. +This package is the Pro plan edition of the Data Grid component. It's part of [MUI X](https://mui.com/x/), an open-core extension of MUI Core, with advanced components. ## Installation diff --git a/packages/x-data-grid-pro/package.json b/packages/x-data-grid-pro/package.json index 0fca8b43f4c4a..cb657f877a220 100644 --- a/packages/x-data-grid-pro/package.json +++ b/packages/x-data-grid-pro/package.json @@ -1,7 +1,7 @@ { "name": "@mui/x-data-grid-pro", "version": "7.1.0", - "description": "The Pro plan edition of the data grid component (MUI X).", + "description": "The Pro plan edition of the Data Grid components (MUI X).", "author": "MUI Team", "main": "src/index.ts", "license": "SEE LICENSE IN LICENSE", diff --git a/packages/x-data-grid/README.md b/packages/x-data-grid/README.md index ceb7180a626f3..25de6af92b191 100644 --- a/packages/x-data-grid/README.md +++ b/packages/x-data-grid/README.md @@ -1,6 +1,6 @@ # MUI X Data Grid -This package is the Community plan edition of the data grid component. +This package is the Community plan edition of the Data Grid components. It's part of [MUI X](https://mui.com/x/), an open-core extension of MUI Core, with advanced components. ## Installation diff --git a/packages/x-data-grid/package.json b/packages/x-data-grid/package.json index 6dac6546e6662..328047af2423d 100644 --- a/packages/x-data-grid/package.json +++ b/packages/x-data-grid/package.json @@ -1,7 +1,7 @@ { "name": "@mui/x-data-grid", "version": "7.1.0", - "description": "The community edition of the data grid component (MUI X).", + "description": "The Community plan edition of the Data Grid components (MUI X).", "author": "MUI Team", "main": "src/index.ts", "license": "MIT", diff --git a/packages/x-date-pickers-pro/README.md b/packages/x-date-pickers-pro/README.md index cfd0faf15fa0c..8a5f497bc1aaa 100644 --- a/packages/x-date-pickers-pro/README.md +++ b/packages/x-date-pickers-pro/README.md @@ -1,6 +1,6 @@ # MUI X Date Pickers Pro -This package is the commercial edition of the date and time picker components. +This package is the Pro plan edition of the Date and Time Picker Components. It's part of [MUI X](https://mui.com/x/), an open-core extension of MUI Core, with advanced components. ## Installation diff --git a/packages/x-date-pickers-pro/package.json b/packages/x-date-pickers-pro/package.json index e3a1e0c951960..d19dd4687345b 100644 --- a/packages/x-date-pickers-pro/package.json +++ b/packages/x-date-pickers-pro/package.json @@ -1,7 +1,7 @@ { "name": "@mui/x-date-pickers-pro", "version": "7.1.0", - "description": "The commercial edition of the date picker components (MUI X).", + "description": "The Pro plan edition of the Date and Time Picker components (MUI X).", "author": "MUI Team", "main": "src/index.ts", "license": "SEE LICENSE IN LICENSE", diff --git a/packages/x-date-pickers/README.md b/packages/x-date-pickers/README.md index 1bbd97b617314..aa2376eac454f 100644 --- a/packages/x-date-pickers/README.md +++ b/packages/x-date-pickers/README.md @@ -1,6 +1,6 @@ # MUI X Date Pickers -This package is the community edition of the date and time picker components. +This package is the Community plan edition of the Date and Time Picker components. It's part of [MUI X](https://mui.com/x/), an open-core extension of MUI Core, with advanced components. ## Installation diff --git a/packages/x-date-pickers/package.json b/packages/x-date-pickers/package.json index 4e7f731b83199..4a02d63182b37 100644 --- a/packages/x-date-pickers/package.json +++ b/packages/x-date-pickers/package.json @@ -1,7 +1,7 @@ { "name": "@mui/x-date-pickers", "version": "7.1.0", - "description": "The community edition of the date picker components (MUI X).", + "description": "The community edition of the Date and Time Picker components (MUI X).", "author": "MUI Team", "main": "src/index.ts", "license": "MIT", diff --git a/packages/x-tree-view-pro/LICENSE b/packages/x-tree-view-pro/LICENSE new file mode 100644 index 0000000000000..bda47bde65477 --- /dev/null +++ b/packages/x-tree-view-pro/LICENSE @@ -0,0 +1,11 @@ +Commercial License + +Copyright (c) 2020 Material-UI SAS + +MUI X Pro (https://mui.com/pricing/) is commercial software. You MUST agree to the +End User License Agreement (EULA: https://mui.com/r/x-license-eula) to be able to +use the software. + +This means that you either need to purchase a commercial license at +https://mui.com/r/x-get-license?scope=pro or be eligible for the Evaluation (trial) +licenses detailed at https://mui.com/r/x-license-trial. diff --git a/packages/x-tree-view-pro/README.md b/packages/x-tree-view-pro/README.md new file mode 100644 index 0000000000000..7f48bdf17d354 --- /dev/null +++ b/packages/x-tree-view-pro/README.md @@ -0,0 +1,26 @@ +# MUI X Tree View + +This package is the Pro plan edition of the Tree View components. +It's part of [MUI X](https://mui.com/x/), an open-core extension of MUI Core, with advanced components. + +## Installation + +Install the package in your project directory with: + +```bash +npm install @mui/x-tree-view-pro +``` + +This component has the following peer dependencies that you will need to install as well. + +```json +"peerDependencies": { + "@mui/material": "^5.15.0", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" +}, +``` + +## Documentation + +Visit [https://mui.com/x/react-tree-view/](https://mui.com/x/react-tree-view/) to view the full documentation. diff --git a/packages/x-tree-view-pro/package.json b/packages/x-tree-view-pro/package.json new file mode 100644 index 0000000000000..1f463cbdd5312 --- /dev/null +++ b/packages/x-tree-view-pro/package.json @@ -0,0 +1,70 @@ +{ + "name": "@mui/x-tree-view-pro", + "version": "7.0.1", + "private": true, + "description": "The Pro plan edition of the Tree View components (MUI X).", + "author": "MUI Team", + "main": "src/index.ts", + "license": "SEE LICENSE IN LICENSE", + "bugs": { + "url": "https://github.com/mui/mui-x/issues" + }, + "homepage": "https://mui.com/x/react-tree-view/", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "sideEffects": false, + "publishConfig": { + "access": "public" + }, + "keywords": [ + "react", + "react-component", + "mui", + "mui-x", + "material-ui", + "material design", + "treeview" + ], + "scripts": { + "typescript": "tsc -p tsconfig.json", + "build": "yarn build:modern && yarn build:node && yarn build:stable && yarn build:types && yarn build:copy-files ", + "build:modern": "node ../../scripts/build.mjs modern", + "build:node": "node ../../scripts/build.mjs node", + "build:stable": "node ../../scripts/build.mjs stable", + "build:copy-files": "node ../../scripts/copyFiles.mjs", + "build:types": "node ../../scripts/buildTypes.mjs", + "prebuild": "rimraf build tsconfig.build.tsbuildinfo" + }, + "repository": { + "type": "git", + "url": "https://github.com/mui/mui-x.git", + "directory": "packages/x-tree-view-pro" + }, + "dependencies": { + "@babel/runtime": "^7.24.0", + "@mui/base": "^5.0.0-beta.40", + "@mui/system": "^5.15.14", + "@mui/utils": "^5.15.14", + "@mui/x-license": "7.0.0", + "@mui/x-tree-view-pro": "7.0.1", + "@types/react-transition-group": "^4.4.10", + "clsx": "^2.1.0", + "prop-types": "^15.8.1", + "react-transition-group": "^4.4.5" + }, + "peerDependencies": { + "@emotion/react": "^11.9.0", + "@emotion/styled": "^11.8.1", + "@mui/material": "^5.15.14", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" + }, + "setupFiles": [ + "/src/setupTests.js" + ], + "engines": { + "node": ">=14.0.0" + } +} diff --git a/packages/x-tree-view-pro/src/index.ts b/packages/x-tree-view-pro/src/index.ts new file mode 100644 index 0000000000000..a6b680db412a3 --- /dev/null +++ b/packages/x-tree-view-pro/src/index.ts @@ -0,0 +1 @@ +export * from '@mui/x-tree-view'; diff --git a/packages/x-tree-view-pro/tsconfig.build.json b/packages/x-tree-view-pro/tsconfig.build.json new file mode 100644 index 0000000000000..58dc0f54afd0a --- /dev/null +++ b/packages/x-tree-view-pro/tsconfig.build.json @@ -0,0 +1,19 @@ +{ + // This config is for emitting declarations (.d.ts) only + // Actual .ts source files are transpiled via babel + "extends": "./tsconfig.json", + "compilerOptions": { + "composite": true, + "declaration": true, + "noEmit": false, + "emitDeclarationOnly": true, + "outDir": "build", + "rootDir": "./src" + }, + "references": [ + { "path": "../x-tree-view/tsconfig.build.json" }, + { "path": "../x-license/tsconfig.build.json" } + ], + "include": ["src/**/*.ts*", "../../node_modules/@mui/material/themeCssVarsAugmentation"], + "exclude": ["src/**/*.spec.ts*", "src/**/*.test.ts*", "src/tests/**/*"] +} diff --git a/packages/x-tree-view-pro/tsconfig.json b/packages/x-tree-view-pro/tsconfig.json new file mode 100644 index 0000000000000..b615deabf7972 --- /dev/null +++ b/packages/x-tree-view-pro/tsconfig.json @@ -0,0 +1,13 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "types": ["react", "mocha", "node"], + "noImplicitAny": false + }, + "include": [ + "src/**/*", + "../../test/utils/addChaiAssertions.ts", + "../../node_modules/@mui/monorepo/packages/test-utils/src/initMatchers.ts", + "../../node_modules/@mui/material/themeCssVarsAugmentation" + ] +} diff --git a/packages/x-tree-view/README.md b/packages/x-tree-view/README.md index 370fb4971362d..567adb406dfb2 100644 --- a/packages/x-tree-view/README.md +++ b/packages/x-tree-view/README.md @@ -1,6 +1,6 @@ # MUI X Tree View -This package is the community edition of the tree view components. +This package is the Community plan edition of the Tree View components. It's part of [MUI X](https://mui.com/x/), an open-core extension of MUI Core, with advanced components. ## Installation diff --git a/packages/x-tree-view/package.json b/packages/x-tree-view/package.json index 3e742b593dba9..00f469bfc5f3f 100644 --- a/packages/x-tree-view/package.json +++ b/packages/x-tree-view/package.json @@ -1,7 +1,7 @@ { "name": "@mui/x-tree-view", "version": "7.1.0", - "description": "The community edition of the tree view components (MUI X).", + "description": "The community edition of the Tree View components (MUI X).", "author": "MUI Team", "main": "src/index.ts", "license": "MIT", diff --git a/scripts/buildApiDocs/treeViewSettings/getComponentInfo.ts b/scripts/buildApiDocs/treeViewSettings/getComponentInfo.ts index a26a5287af449..395c5ed628228 100644 --- a/scripts/buildApiDocs/treeViewSettings/getComponentInfo.ts +++ b/scripts/buildApiDocs/treeViewSettings/getComponentInfo.ts @@ -75,7 +75,7 @@ export function getComponentImports(name: string, filename: string) { const reExportPackage = [rootImportPath]; - // TODO: uncomment when releasing the pro package + // TODO x-tree-view-pro uncomment when making the package public // if (rootImportPath === '@mui/x-tree-view') { // reExportPackage.push('@mui/x-tree-view-pro'); // } diff --git a/tsconfig.json b/tsconfig.json index 941074723d1c6..60fb7c569b555 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -24,6 +24,8 @@ "@mui/x-charts/*": ["./packages/x-charts/src/*"], "@mui/x-tree-view": ["./packages/x-tree-view/src"], "@mui/x-tree-view/*": ["./packages/x-tree-view/src/*"], + "@mui/x-tree-view-pro": ["./packages/x-tree-view-pro/src"], + "@mui/x-tree-view-pro/*": ["./packages/x-tree-view-pro/src/*"], "@mui/x-license": ["./packages/x-license/src"], "@mui/x-license/*": ["./packages/x-license/src/*"], "@mui-internal/test-utils": ["./node_modules/@mui/monorepo/packages/test-utils/src"], diff --git a/webpackBaseConfig.js b/webpackBaseConfig.js index 6549bda5c809e..d881a90743e72 100644 --- a/webpackBaseConfig.js +++ b/webpackBaseConfig.js @@ -16,6 +16,7 @@ module.exports = { '@mui/x-date-pickers-pro': path.resolve(__dirname, './packages/x-date-pickers-pro/src'), '@mui/x-charts': path.resolve(__dirname, './packages/x-charts/src'), '@mui/x-tree-view': path.resolve(__dirname, './packages/x-tree-view/src'), + '@mui/x-tree-view-pro': path.resolve(__dirname, './packages/x-tree-view-pro/src'), '@mui/x-license': path.resolve(__dirname, './packages/x-license/src'), '@mui/material-nextjs': path.resolve( __dirname, From 5cbb05649f55f0eb53662dcdd398020ca8ad93aa Mon Sep 17 00:00:00 2001 From: Rom Grk Date: Fri, 29 Mar 2024 10:31:28 -0400 Subject: [PATCH 39/55] [DataGrid] Fix RTL mode (#12583) --- .../virtualization/GridTopContainer.tsx | 1 + .../virtualization/useGridVirtualScroller.tsx | 19 ++++- .../data-grid/DataGridRTLVirtualization.js | 80 +++++++++++++++++++ test/regressions/index.js | 35 ++++++-- 4 files changed, 127 insertions(+), 8 deletions(-) create mode 100644 test/regressions/data-grid/DataGridRTLVirtualization.js diff --git a/packages/x-data-grid/src/components/virtualization/GridTopContainer.tsx b/packages/x-data-grid/src/components/virtualization/GridTopContainer.tsx index 03873c05f5604..88603b41c344d 100644 --- a/packages/x-data-grid/src/components/virtualization/GridTopContainer.tsx +++ b/packages/x-data-grid/src/components/virtualization/GridTopContainer.tsx @@ -21,6 +21,7 @@ const Element = styled('div')({ zIndex: 5, bottom: 0, left: 0, + right: 0, height: 1, width: 'var(--DataGrid-rowWidth)', backgroundColor: 'var(--DataGrid-rowBorderColor)', diff --git a/packages/x-data-grid/src/hooks/features/virtualization/useGridVirtualScroller.tsx b/packages/x-data-grid/src/hooks/features/virtualization/useGridVirtualScroller.tsx index 8ed66d64e1ae8..2fc1b43d1f097 100644 --- a/packages/x-data-grid/src/hooks/features/virtualization/useGridVirtualScroller.tsx +++ b/packages/x-data-grid/src/hooks/features/virtualization/useGridVirtualScroller.tsx @@ -67,6 +67,7 @@ const EMPTY_SCROLL_POSITION = { top: 0, left: 0 }; export const EMPTY_DETAIL_PANELS = Object.freeze(new Map()); const createScrollCache = ( + mode: 'ltr' | 'rtl', rowBufferPx: number, columnBufferPx: number, verticalBuffer: number, @@ -74,6 +75,7 @@ const createScrollCache = ( ) => ({ direction: ScrollDirection.NONE, buffer: bufferForDirection( + mode, ScrollDirection.NONE, rowBufferPx, columnBufferPx, @@ -139,6 +141,7 @@ export const useGridVirtualScroller = () => { const frozenContext = React.useRef(undefined); const scrollCache = useLazyRef(() => createScrollCache( + theme.direction, rootProps.rowBufferPx, rootProps.columnBufferPx, dimensions.rowHeight * 15, @@ -243,6 +246,7 @@ export const useGridVirtualScroller = () => { scrollCache.direction = direction; scrollCache.buffer = bufferForDirection( + theme.direction, direction, rootProps.rowBufferPx, rootProps.columnBufferPx, @@ -938,7 +942,7 @@ export function computeOffsetLeft( factor * (columnPositions[renderContext.firstColumnIndex] ?? 0) - (columnPositions[pinnedLeftLength] ?? 0); - return left; + return Math.abs(left); } function directionForDelta(dx: number, dy: number) { @@ -963,12 +967,25 @@ function directionForDelta(dx: number, dy: number) { } function bufferForDirection( + mode: 'ltr' | 'rtl', direction: ScrollDirection, rowBufferPx: number, columnBufferPx: number, verticalBuffer: number, horizontalBuffer: number, ) { + if (mode === 'rtl') { + switch (direction) { + case ScrollDirection.LEFT: + direction = ScrollDirection.RIGHT; + break; + case ScrollDirection.RIGHT: + direction = ScrollDirection.LEFT; + break; + default: + } + } + switch (direction) { case ScrollDirection.NONE: return { diff --git a/test/regressions/data-grid/DataGridRTLVirtualization.js b/test/regressions/data-grid/DataGridRTLVirtualization.js new file mode 100644 index 0000000000000..9920f1036ada5 --- /dev/null +++ b/test/regressions/data-grid/DataGridRTLVirtualization.js @@ -0,0 +1,80 @@ +import * as React from 'react'; +import { prefixer } from 'stylis'; +import rtlPlugin from 'stylis-plugin-rtl'; +import { useGridApiRef, DataGrid } from '@mui/x-data-grid'; +import { arSD } from '@mui/x-data-grid/locales'; +import createCache from '@emotion/cache'; +import { CacheProvider } from '@emotion/react'; +import { createTheme, ThemeProvider, useTheme } from '@mui/material/styles'; + +// Create rtl cache +const cacheRtl = createCache({ + key: 'data-grid-rtl-demo', + stylisPlugins: [prefixer, rtlPlugin], +}); + +const columns = [ + { + field: 'id', + headerName: 'تعريف', + width: 150, + }, + { + field: 'name', + headerName: 'اسم', + width: 150, + }, + { + field: 'age', + headerName: 'عمر', + valueGetter: (value) => `${value} سنوات`, + width: 150, + }, + { + field: 'occupation', + headerName: 'المهنة', + width: 150, + }, + { + field: 'gender', + headerName: 'جنس', + width: 150, + }, +]; + +const rows = [ + { id: 1, name: 'سارہ', age: 35, occupation: 'معلم', gender: 'أنثى' }, + { id: 2, name: 'زید', age: 42, occupation: 'مهندس', gender: 'ذكر' }, + { id: 3, name: 'علی', age: 33, occupation: 'محاسب', gender: 'ذكر' }, + { id: 4, name: 'فاطمہ', age: 25, occupation: 'معلم', gender: 'أنثى' }, + { id: 5, name: 'ایندریو', age: 65, occupation: 'مهندس', gender: 'ذكر' }, +]; + +export default function DataGridRTLVirtualization() { + const apiRef = useGridApiRef(); + const existingTheme = useTheme(); + const theme = React.useMemo( + () => + createTheme({}, arSD, existingTheme, { + direction: 'rtl', + }), + [existingTheme], + ); + React.useEffect(() => { + Promise.resolve().then(() => { + const scroller = apiRef.current.rootElementRef.current.querySelector( + '.MuiDataGrid-virtualScroller', + ); + scroller.scrollLeft = -Math.abs(scroller.scrollWidth - scroller.clientWidth); + }); + }, [apiRef]); + return ( + + +
    + +
    +
    +
    + ); +} diff --git a/test/regressions/index.js b/test/regressions/index.js index 2c621503bd037..c66587dd075bb 100644 --- a/test/regressions/index.js +++ b/test/regressions/index.js @@ -56,31 +56,50 @@ function excludeTest(suite, name) { }); } +const tests = []; + // Also use some of the demos to avoid code duplication. const requireDocs = require.context('docsx/data', true, /\.js$/); -const tests = requireDocs.keys().reduce((res, path) => { +requireDocs.keys().forEach((path) => { const [name, ...suiteArray] = path.replace('./', '').replace('.js', '').split('/').reverse(); const suite = `docs-${suiteArray.reverse().join('-')}`; if (excludeTest(suite, name)) { - return res; + return; } // TODO: Why does webpack include a key for the absolute and relative path? // We just want the relative path if (!path.startsWith('./')) { - return res; + return; } - res.push({ + tests.push({ path, suite, name, case: requireDocs(path).default, }); +}); + +const requireRegressions = require.context('./data-grid', true, /\.js$/); +requireRegressions.keys().forEach((path) => { + // "./DataGridRTLVirtualization.js" + // "test/regressions/data-grid/DataGridRTLVirtualization.js" + if (!path.startsWith('./')) { + return; + } + + const name = path.replace('./', '').replace('.js', ''); + const suite = `test-regressions-data-grid`; - return res; -}, []); + tests.push({ + path, + suite, + name, + case: requireRegressions(path).default, + }); +}); clock.restore(); @@ -130,7 +149,9 @@ function App() { return null; } - const isDataGridTest = path.indexOf('/docs-data-grid') === 0; + const isDataGridTest = + path.indexOf('/docs-data-grid') === 0 || + path.indexOf('test-regressions-data-grid') !== -1; return ( Date: Fri, 29 Mar 2024 16:56:02 +0200 Subject: [PATCH 40/55] [core] Bump monorepo (#12608) --- package.json | 2 +- yarn.lock | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 59865fcf1ee8b..4313c40a232e9 100644 --- a/package.json +++ b/package.json @@ -86,7 +86,7 @@ "@mnajdova/enzyme-adapter-react-18": "^0.2.0", "@mui/icons-material": "^5.15.14", "@mui/material": "^5.15.14", - "@mui/monorepo": "https://github.com/mui/material-ui.git#master", + "@mui/monorepo": "https://github.com/mui/material-ui.git#next", "@mui/utils": "^5.15.14", "@next/eslint-plugin-next": "14.0.4", "@octokit/plugin-retry": "^6.0.1", diff --git a/yarn.lock b/yarn.lock index cf72918bf0d4c..bcc36cc35cc4e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2016,9 +2016,9 @@ react-is "^18.2.0" react-transition-group "^4.4.5" -"@mui/monorepo@https://github.com/mui/material-ui.git#master": - version "5.15.14" - resolved "https://github.com/mui/material-ui.git#39fe215ce8bb1ed215e9a274f63b979714876e61" +"@mui/monorepo@https://github.com/mui/material-ui.git#next": + version "6.0.0-alpha.0" + resolved "https://github.com/mui/material-ui.git#e1d94d5ce097815bcd738352e69bb43ce03bd266" dependencies: "@googleapis/sheets" "^5.0.5" "@netlify/functions" "^2.6.0" From 50d6b0fcdca8aea123aac272c5857ce6105daa3b Mon Sep 17 00:00:00 2001 From: "ms.safari" <30653927+misafari@users.noreply.github.com> Date: Tue, 2 Apr 2024 03:48:34 -0400 Subject: [PATCH 41/55] [l10n] Improve Persian (fa-IR) locale (#12632) Signed-off-by: ms.safari <30653927+misafari@users.noreply.github.com> Co-authored-by: Lukas --- docs/data/date-pickers/localization/data.json | 2 +- packages/x-date-pickers/src/locales/faIR.ts | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/data/date-pickers/localization/data.json b/docs/data/date-pickers/localization/data.json index 30db1a184762c..458f563e77d92 100644 --- a/docs/data/date-pickers/localization/data.json +++ b/docs/data/date-pickers/localization/data.json @@ -171,7 +171,7 @@ "languageTag": "fa-IR", "importName": "faIR", "localeName": "Persian", - "missingKeysCount": 14, + "missingKeysCount": 8, "totalKeysCount": 50, "githubLink": "https://github.com/mui/mui-x/blob/master/packages/x-date-pickers/src/locales/faIR.ts" }, diff --git a/packages/x-date-pickers/src/locales/faIR.ts b/packages/x-date-pickers/src/locales/faIR.ts index af88184b909d3..7f76f3fd6846d 100644 --- a/packages/x-date-pickers/src/locales/faIR.ts +++ b/packages/x-date-pickers/src/locales/faIR.ts @@ -84,13 +84,13 @@ const faIRPickers: Partial> = { fieldMeridiemPlaceholder: () => 'aa', // View names - // year: 'Year', - // month: 'Month', - // day: 'Day', + year: 'سال', + month: 'ماه', + day: 'روز', // weekDay: 'Week day', - // hours: 'Hours', - // minutes: 'Minutes', - // seconds: 'Seconds', + hours: 'ساعت ها', + minutes: 'دقیقه ها', + seconds: 'ثانیه ها', // meridiem: 'Meridiem', // Common From fec89a8a67bf9ed6d9eb09a98e3224341fb60448 Mon Sep 17 00:00:00 2001 From: Flavien DELANGLE Date: Tue, 2 Apr 2024 10:07:13 +0200 Subject: [PATCH 42/55] [core] Introduce `describeTreeView` to run test on `SimpleTreeView` and `RichTreeView`, using `TreeItem` and `TreeItem2` + migrate expansion tests (#12428) --- .../SimpleTreeView/SimpleTreeView.test.tsx | 85 ----- .../src/TreeItem/TreeItem.test.tsx | 12 - .../src/internals/models/plugin.ts | 4 +- .../useTreeViewExpansion.test.tsx | 304 ++++++++++++++++++ .../useTreeView/useTreeViewModels.ts | 2 +- .../describeTreeView/describeTreeView.tsx | 235 ++++++++++++++ .../describeTreeView.types.ts | 84 +++++ .../utils/tree-view/describeTreeView/index.ts | 1 + 8 files changed, 627 insertions(+), 100 deletions(-) create mode 100644 packages/x-tree-view/src/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.test.tsx create mode 100644 test/utils/tree-view/describeTreeView/describeTreeView.tsx create mode 100644 test/utils/tree-view/describeTreeView/describeTreeView.types.ts create mode 100644 test/utils/tree-view/describeTreeView/index.ts diff --git a/packages/x-tree-view/src/SimpleTreeView/SimpleTreeView.test.tsx b/packages/x-tree-view/src/SimpleTreeView/SimpleTreeView.test.tsx index ee134b0e87a23..6891bdc740b00 100644 --- a/packages/x-tree-view/src/SimpleTreeView/SimpleTreeView.test.tsx +++ b/packages/x-tree-view/src/SimpleTreeView/SimpleTreeView.test.tsx @@ -22,20 +22,6 @@ describe('', () => { })); describe('warnings', () => { - it('should warn when switching from controlled to uncontrolled of the expandedItems prop', () => { - const { setProps } = render( - - - , - ); - - expect(() => { - setProps({ expandedItems: undefined }); - }).toErrorDev( - 'MUI X: A component is changing the controlled expandedItems state of TreeView to be uncontrolled.', - ); - }); - it('should warn when switching from controlled to uncontrolled of the selectedItems prop', () => { const { setProps } = render( @@ -159,41 +145,6 @@ describe('', () => { expect(getByTestId('one')).to.have.attribute('aria-selected'); }); - it('should be able to be controlled with the expandedItems prop', () => { - function MyComponent() { - const [expandedState, setExpandedState] = React.useState([]); - const onExpandedItemsChange = (event, items) => { - setExpandedState(items); - }; - return ( - - - - - - ); - } - - const { getByTestId, getByText } = render(); - - expect(getByTestId('one')).to.have.attribute('aria-expanded', 'false'); - - fireEvent.click(getByText('one')); - act(() => { - getByTestId('one').focus(); - }); - - expect(getByTestId('one')).to.have.attribute('aria-expanded', 'true'); - - fireEvent.click(getByText('one')); - - expect(getByTestId('one')).to.have.attribute('aria-expanded', 'false'); - - fireEvent.keyDown(getByTestId('one'), { key: '*' }); - - expect(getByTestId('one')).to.have.attribute('aria-expanded', 'true'); - }); - it('should be able to be controlled with the selectedItems prop and singleSelect', () => { function MyComponent() { const [selectedState, setSelectedState] = React.useState(null); @@ -362,42 +313,6 @@ describe('', () => { }); }); - describe('onExpandedItemsChange', () => { - it('should be called when a parent item label is clicked', () => { - const onExpandedItemsChange = spy(); - - const { getByText } = render( - - - - - , - ); - - fireEvent.click(getByText('outer')); - - expect(onExpandedItemsChange.callCount).to.equal(1); - expect(onExpandedItemsChange.args[0][1]).to.deep.equal(['1']); - }); - - it('should be called when a parent item icon is clicked', () => { - const onExpandedItemsChange = spy(); - - const { getByTestId } = render( - -
    }} itemId="1" label="outer"> - - - , - ); - - fireEvent.click(getByTestId('icon')); - - expect(onExpandedItemsChange.callCount).to.equal(1); - expect(onExpandedItemsChange.args[0][1]).to.deep.equal(['1']); - }); - }); - describe('useTreeViewFocus', () => { it('should set tabIndex={0} on the selected item', () => { const { getByTestId } = render( diff --git a/packages/x-tree-view/src/TreeItem/TreeItem.test.tsx b/packages/x-tree-view/src/TreeItem/TreeItem.test.tsx index 4b1fe9226b925..5ce12562dc86b 100644 --- a/packages/x-tree-view/src/TreeItem/TreeItem.test.tsx +++ b/packages/x-tree-view/src/TreeItem/TreeItem.test.tsx @@ -301,18 +301,6 @@ describe('', () => { expect(getByTestId('test')).to.have.attribute('aria-expanded', 'false'); }); - it('should have the attribute `aria-expanded={true}` if expanded', () => { - const { getByTestId } = render( - - - - - , - ); - - expect(getByTestId('test')).to.have.attribute('aria-expanded', 'true'); - }); - it('should not have the attribute `aria-expanded` if no children are present', () => { const { getByTestId } = render( diff --git a/packages/x-tree-view/src/internals/models/plugin.ts b/packages/x-tree-view/src/internals/models/plugin.ts index 0587d6b19e2c6..e8d1b497c6132 100644 --- a/packages/x-tree-view/src/internals/models/plugin.ts +++ b/packages/x-tree-view/src/internals/models/plugin.ts @@ -85,8 +85,8 @@ type TreeViewUsedPlugins = [ ...TSignature['dependantPlugins'], ]; -type TreeViewUsedParams = TSignature['params'] & - MergePluginsProperty, 'params'>; +export type TreeViewUsedParams = + TSignature['params'] & MergePluginsProperty, 'params'>; type TreeViewUsedDefaultizedParams = TSignature['defaultizedParams'] & diff --git a/packages/x-tree-view/src/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.test.tsx b/packages/x-tree-view/src/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.test.tsx new file mode 100644 index 0000000000000..fcc5bad1dd9bd --- /dev/null +++ b/packages/x-tree-view/src/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.test.tsx @@ -0,0 +1,304 @@ +import { expect } from 'chai'; +import { spy } from 'sinon'; +import { describeTreeView } from 'test/utils/tree-view/describeTreeView'; +import { UseTreeViewExpansionSignature } from '@mui/x-tree-view/internals'; +import { act, fireEvent } from '@mui-internal/test-utils'; +import { + TreeItem2, + TreeItem2Props, + UseTreeItem2ContentSlotOwnProps, + useTreeItem2Utils, +} from '@mui/x-tree-view'; +import * as React from 'react'; + +/** + * All tests related to keyboard navigation (e.g.: expanding using "Enter" and "ArrowRight") + * are located in the `useTreeViewKeyboardNavigation.test.tsx` file. + */ +describeTreeView( + 'useTreeViewExpansion plugin', + ({ render, setup }) => { + describe('model props (expandedItems, defaultExpandedItems, onExpandedItemsChange)', () => { + it('should not expand items when no default state and no control state are defined', () => { + const response = render({ + items: [{ id: '1', children: [{ id: '1.1' }] }, { id: '2' }], + }); + + expect(response.isItemExpanded('1')).to.equal(false); + expect(response.getAllItemRoots()).to.have.length(2); + }); + + it('should use the default state when defined', () => { + const response = render({ + items: [{ id: '1', children: [{ id: '1.1' }] }, { id: '2' }], + defaultExpandedItems: ['1'], + }); + + expect(response.isItemExpanded('1')).to.equal(true); + expect(response.getAllItemRoots()).to.have.length(3); + }); + + it('should use the control state when defined', () => { + const response = render({ + items: [{ id: '1', children: [{ id: '1.1' }] }, { id: '2' }], + expandedItems: ['1'], + }); + + expect(response.isItemExpanded('1')).to.equal(true); + expect(response.getItemRoot('1.1')).toBeVisible(); + }); + + it('should use the control state upon the default state when both are defined', () => { + const response = render({ + items: [{ id: '1', children: [{ id: '1.1' }] }, { id: '2' }], + expandedItems: ['1'], + defaultExpandedItems: ['2'], + }); + + expect(response.isItemExpanded('1')).to.equal(true); + }); + + it('should react to control state update', () => { + const response = render({ + items: [{ id: '1', children: [{ id: '1.1' }] }], + expandedItems: [], + }); + + response.setProps({ expandedItems: ['1'] }); + expect(response.isItemExpanded('1')).to.equal(true); + }); + + it('should call the onExpandedItemsChange callback when the model is updated (add expanded item to empty list)', () => { + const onExpandedItemsChange = spy(); + + const response = render({ + items: [{ id: '1', children: [{ id: '1.1' }] }], + onExpandedItemsChange, + }); + + fireEvent.click(response.getItemContent('1')); + act(() => { + response.getRoot().focus(); + }); + + expect(onExpandedItemsChange.callCount).to.equal(1); + expect(onExpandedItemsChange.lastCall.args[1]).to.deep.equal(['1']); + }); + + it('should call the onExpandedItemsChange callback when the model is updated (add expanded item no non-empty list)', () => { + const onExpandedItemsChange = spy(); + + const response = render({ + items: [ + { id: '1', children: [{ id: '1.1' }] }, + { id: '2', children: [{ id: '2.1' }] }, + ], + onExpandedItemsChange, + defaultExpandedItems: ['1'], + }); + + fireEvent.click(response.getItemContent('2')); + act(() => { + response.getRoot().focus(); + }); + + expect(onExpandedItemsChange.callCount).to.equal(1); + expect(onExpandedItemsChange.lastCall.args[1]).to.deep.equal(['2', '1']); + }); + + it('should call the onExpandedItemsChange callback when the model is updated (remove expanded item)', () => { + const onExpandedItemsChange = spy(); + + const response = render({ + items: [ + { id: '1', children: [{ id: '1.1' }] }, + { id: '2', children: [{ id: '2.1' }] }, + ], + onExpandedItemsChange, + defaultExpandedItems: ['1'], + }); + + fireEvent.click(response.getItemContent('1')); + act(() => { + response.getRoot().focus(); + }); + + expect(onExpandedItemsChange.callCount).to.equal(1); + expect(onExpandedItemsChange.lastCall.args[1]).to.deep.equal([]); + }); + + it('should warn when switching from controlled to uncontrolled', () => { + const response = render({ + items: [{ id: '1' }], + expandedItems: [], + }); + + expect(() => { + response.setProps({ expandedItems: undefined }); + }).toErrorDev( + 'MUI X: A component is changing the controlled expandedItems state of TreeView to be uncontrolled.', + ); + }); + + it('should warn and not react to update when updating the default state', () => { + const response = render({ + items: [{ id: '1', children: [{ id: '1.1' }] }, { id: '2' }], + defaultExpandedItems: ['1'], + }); + + expect(() => { + response.setProps({ defaultExpandedItems: ['2'] }); + expect(response.isItemExpanded('1')).to.equal(true); + expect(response.isItemExpanded('2')).to.equal(false); + }).toErrorDev( + 'MUI X: A component is changing the default expandedItems state of an uncontrolled TreeView after being initialized. To suppress this warning opt to use a controlled TreeView.', + ); + }); + }); + + describe('click interactions', () => { + it('should expand collapsed item when clicking on an item content', () => { + const response = render({ + items: [{ id: '1', children: [{ id: '1.1' }] }, { id: '2' }], + }); + + expect(response.isItemExpanded('1')).to.equal(false); + fireEvent.click(response.getItemContent('1')); + expect(response.isItemExpanded('1')).to.equal(true); + }); + + it('should collapse expanded item when clicking on an item content', () => { + const response = render({ + items: [{ id: '1', children: [{ id: '1.1' }] }, { id: '2' }], + defaultExpandedItems: ['1'], + }); + + expect(response.isItemExpanded('1')).to.equal(true); + fireEvent.click(response.getItemContent('1')); + expect(response.isItemExpanded('1')).to.equal(false); + }); + + it('should not expand collapsed item when clicking on a disabled item content', () => { + const response = render({ + items: [{ id: '1', disabled: true, children: [{ id: '1.1' }] }, { id: '2' }], + }); + + expect(response.isItemExpanded('1')).to.equal(false); + fireEvent.click(response.getItemContent('1')); + expect(response.isItemExpanded('1')).to.equal(false); + }); + + it('should not collapse expanded item when clicking on a disabled item', () => { + const response = render({ + items: [{ id: '1', disabled: true, children: [{ id: '1.1' }] }, { id: '2' }], + defaultExpandedItems: ['1'], + }); + + expect(response.isItemExpanded('1')).to.equal(true); + fireEvent.click(response.getItemContent('1')); + expect(response.isItemExpanded('1')).to.equal(true); + }); + + it('should expand collapsed item when clicking on an item label', () => { + const response = render({ + items: [{ id: '1', children: [{ id: '1.1' }] }, { id: '2' }], + }); + + expect(response.isItemExpanded('1')).to.equal(false); + fireEvent.click(response.getItemLabel('1')); + expect(response.isItemExpanded('1')).to.equal(true); + }); + + it('should expand collapsed item when clicking on an item icon container', () => { + const response = render({ + items: [{ id: '1', children: [{ id: '1.1' }] }, { id: '2' }], + }); + + expect(response.isItemExpanded('1')).to.equal(false); + fireEvent.click(response.getItemIconContainer('1')); + expect(response.isItemExpanded('1')).to.equal(true); + }); + + it('should be able to limit the expansion to the icon', function test() { + // This test is not relevant for the TreeItem component. + // We could create the equivalent test for it, + // but it's not worth the effort given the complexity of the old behavior override. + if (!setup.includes('TreeItem2')) { + this.skip(); + } + + const CustomTreeItem = React.forwardRef(function MyTreeItem( + props: TreeItem2Props, + ref: React.Ref, + ) { + const { interactions } = useTreeItem2Utils({ + itemId: props.itemId, + children: props.children, + }); + + const handleContentClick: UseTreeItem2ContentSlotOwnProps['onClick'] = (event) => { + event.defaultMuiPrevented = true; + interactions.handleSelection(event); + }; + + const handleIconContainerClick = (event: React.MouseEvent) => { + interactions.handleExpansion(event); + }; + + return ( + + ); + }); + + const response = render({ + items: [{ id: '1', children: [{ id: '1.1' }] }, { id: '2' }], + slots: { item: CustomTreeItem }, + }); + + expect(response.isItemExpanded('1')).to.equal(false); + fireEvent.click(response.getItemContent('1')); + expect(response.isItemExpanded('1')).to.equal(false); + fireEvent.click(response.getItemIconContainer('1')); + expect(response.isItemExpanded('1')).to.equal(true); + }); + }); + + describe('onItemExpansionToggle prop', () => { + it('should call the onItemExpansionToggle callback when expanding an item', () => { + const onItemExpansionToggle = spy(); + + const response = render({ + items: [{ id: '1', children: [{ id: '1.1' }] }], + onItemExpansionToggle, + }); + + fireEvent.click(response.getItemContent('1')); + expect(onItemExpansionToggle.callCount).to.equal(1); + expect(onItemExpansionToggle.lastCall.args[1]).to.equal('1'); + expect(onItemExpansionToggle.lastCall.args[2]).to.equal(true); + }); + + it('should call the onItemExpansionToggle callback when collapsing an item', () => { + const onItemExpansionToggle = spy(); + + const response = render({ + items: [{ id: '1', children: [{ id: '1.1' }] }], + defaultExpandedItems: ['1'], + onItemExpansionToggle, + }); + + fireEvent.click(response.getItemContent('1')); + expect(onItemExpansionToggle.callCount).to.equal(1); + expect(onItemExpansionToggle.lastCall.args[1]).to.equal('1'); + expect(onItemExpansionToggle.lastCall.args[2]).to.equal(false); + }); + }); + }, +); diff --git a/packages/x-tree-view/src/internals/useTreeView/useTreeViewModels.ts b/packages/x-tree-view/src/internals/useTreeView/useTreeViewModels.ts index efd1dc3164787..1d6bb801ed3b3 100644 --- a/packages/x-tree-view/src/internals/useTreeView/useTreeViewModels.ts +++ b/packages/x-tree-view/src/internals/useTreeView/useTreeViewModels.ts @@ -106,7 +106,7 @@ export const useTreeViewModels = < ].join('\n'), ); } - }, [JSON.stringify(defaultValue)]); + }, [JSON.stringify(newDefaultValue)]); }); } /* eslint-enable react-hooks/rules-of-hooks, react-hooks/exhaustive-deps */ diff --git a/test/utils/tree-view/describeTreeView/describeTreeView.tsx b/test/utils/tree-view/describeTreeView/describeTreeView.tsx new file mode 100644 index 0000000000000..39eb00ad72ba0 --- /dev/null +++ b/test/utils/tree-view/describeTreeView/describeTreeView.tsx @@ -0,0 +1,235 @@ +import * as React from 'react'; +import createDescribe from '@mui-internal/test-utils/createDescribe'; +import { createRenderer } from '@mui-internal/test-utils'; +import { RichTreeView } from '@mui/x-tree-view/RichTreeView'; +import { SimpleTreeView } from '@mui/x-tree-view/SimpleTreeView'; +import { TreeItem, treeItemClasses } from '@mui/x-tree-view/TreeItem'; +import { TreeItem2 } from '@mui/x-tree-view/TreeItem2'; +import { TreeViewAnyPluginSignature } from '@mui/x-tree-view/internals/models'; +import { MuiRenderResult } from '@mui-internal/test-utils/createRenderer'; +import { + DescribeTreeViewTestRunner, + DescribeTreeViewRenderer, + DescribeTreeViewRendererReturnValue, + DescribeTreeViewItem, +} from './describeTreeView.types'; + +const innerDescribeTreeView = ( + message: string, + testRunner: DescribeTreeViewTestRunner, +): void => { + const { render } = createRenderer(); + + const getUtils = ( + result: MuiRenderResult, + ): Omit, 'setProps'> => { + const getRoot = () => result.getByRole('tree'); + + const getAllItemRoots = () => result.queryAllByRole('treeitem'); + + const getItemRoot = (id: string) => result.getByTestId(id); + + const getItemContent = (id: string) => + getItemRoot(id).querySelector(`.${treeItemClasses.content}`)!; + + const getItemLabel = (id: string) => + getItemRoot(id).querySelector(`.${treeItemClasses.label}`)!; + + const getItemIconContainer = (id: string) => + getItemRoot(id).querySelector(`.${treeItemClasses.iconContainer}`)!; + + const isItemExpanded = (id: string) => getItemRoot(id).getAttribute('aria-expanded') === 'true'; + + return { + getRoot, + getAllItemRoots, + getItemRoot, + getItemContent, + getItemLabel, + getItemIconContainer, + isItemExpanded, + }; + }; + + describe(message, () => { + describe('RichTreeView + TreeItem', () => { + const renderRichTreeView: DescribeTreeViewRenderer = ({ + items: rawItems, + slotProps, + ...other + }) => { + const items = rawItems as readonly DescribeTreeViewItem[]; + const result = render( + + ({ + ...slotProps?.item, + 'data-testid': ownerState.itemId, + }) as any, + }} + getItemLabel={(item) => item.label ?? item.id} + isItemDisabled={(item) => !!item.disabled} + {...other} + />, + ); + + return { + setProps: result.setProps, + ...getUtils(result), + }; + }; + + testRunner({ render: renderRichTreeView, setup: 'RichTreeView + TreeItem' }); + }); + + describe('RichTreeView + TreeItem2', () => { + const renderRichTreeView: DescribeTreeViewRenderer = ({ + items: rawItems, + slots, + slotProps, + ...other + }) => { + const items = rawItems as readonly DescribeTreeViewItem[]; + const result = render( + + ({ + ...slotProps?.item, + 'data-testid': ownerState.itemId, + }) as any, + }} + getItemLabel={(item) => item.label ?? item.id} + isItemDisabled={(item) => !!item.disabled} + {...other} + />, + ); + + return { + setProps: result.setProps, + ...getUtils(result), + }; + }; + + testRunner({ render: renderRichTreeView, setup: 'RichTreeView + TreeItem2' }); + }); + + describe('SimpleTreeView + TreeItem', () => { + const renderSimpleTreeView: DescribeTreeViewRenderer = ({ + items: rawItems, + slots, + ...other + }) => { + const items = rawItems as readonly DescribeTreeViewItem[]; + const Item = slots?.item ?? TreeItem; + + const renderItem = (item: DescribeTreeViewItem) => ( + + {item.children?.map(renderItem)} + + ); + + const result = render( + + {items.map(renderItem)} + , + ); + + return { + setProps: result.setProps, + ...getUtils(result), + }; + }; + + testRunner({ render: renderSimpleTreeView, setup: 'SimpleTreeView + TreeItem' }); + }); + + describe('SimpleTreeView + TreeItem2', () => { + const renderSimpleTreeView: DescribeTreeViewRenderer = ({ + items: rawItems, + slots, + ...other + }) => { + const items = rawItems as readonly DescribeTreeViewItem[]; + const Item = slots?.item ?? TreeItem2; + const renderItem = (item: DescribeTreeViewItem) => ( + + {item.children?.map(renderItem)} + + ); + + const result = render( + + {items.map(renderItem)} + , + ); + + return { + setProps: result.setProps, + ...getUtils(result), + }; + }; + + testRunner({ render: renderSimpleTreeView, setup: 'SimpleTreeView + TreeItem2' }); + }); + }); +}; + +type Params = [ + string, + DescribeTreeViewTestRunner, +]; + +type DescribeTreeView = { +

    (...args: Params

    ): void; + skip:

    (...args: Params

    ) => void; + only:

    (...args: Params

    ) => void; +}; + +/** + * Describe tests for the Tree View that will be executed with the following setups: + * - RichTreeView + TreeItem + * - RichTreeView + TreeItem2 + * - SimpleTreeView + TreeItem + * - SimpleTreeView + TreeItem2 + * + * Is used as follows: + * + * ``` + * describeTreeView('Title of the suite', ({ render }) => { + * it('should do something', () => { + * const { getItemRoot } = render({ + * items: [{ id: '1', children: [{ id: '1.1' }] }], + * defaultExpandedItems: ['1'], + * }); + * }); + * }); + * ``` + * + * Several things to note: + * - The `render` function takes an array of items, even for `SimpleTreeView` + * - Except for `items`, all the other properties passed to `render` will be forwarded to the Tree View as props + * - If an item has no label, its `id` will be used as the label + */ +export const describeTreeView = createDescribe( + 'describeTreeView', + innerDescribeTreeView, +) as DescribeTreeView; diff --git a/test/utils/tree-view/describeTreeView/describeTreeView.types.ts b/test/utils/tree-view/describeTreeView/describeTreeView.types.ts new file mode 100644 index 0000000000000..9c5f3d59dba8f --- /dev/null +++ b/test/utils/tree-view/describeTreeView/describeTreeView.types.ts @@ -0,0 +1,84 @@ +import * as React from 'react'; +import { TreeViewAnyPluginSignature, TreeViewUsedParams } from '@mui/x-tree-view/internals/models'; +import { TreeItemProps } from '@mui/x-tree-view/TreeItem'; +import { TreeItem2Props } from '@mui/x-tree-view/TreeItem2'; + +export type DescribeTreeViewTestRunner = ( + params: DescribeTreeViewTestRunnerParams, +) => void; + +export interface DescribeTreeViewRendererReturnValue { + /** + * Passes new props to the Tree View. + * @param {Partial>} props A subset of the props accepted by the Tree View. + */ + setProps: (props: Partial>) => void; + /** + * Returns the `root` slot of the Tree View. + * @returns {HTMLElement} `root` slot of the Tree View. + */ + getRoot: () => HTMLElement; + /** + * Returns the `root` slot of all the items. + * @returns {HTMLElement[]} List of the `root` slot of all the items. + */ + getAllItemRoots: () => HTMLElement[]; + /** + * Returns the `root` slot of the item with the given id. + * @param {string} id The id of the item to retrieve. + * @returns {HTMLElement} `root` slot of the item with the given id. + */ + getItemRoot: (id: string) => HTMLElement; + /** + * Returns the `content` slot of the item with the given id. + * @param {string} id The id of the item to retrieve. + * @returns {HTMLElement} `content` slot of the item with the given id. + */ + getItemContent: (id: string) => HTMLElement; + /** + * Returns the `label` slot of the item with the given id. + * @param {string} id The id of the item to retrieve. + * @returns {HTMLElement} `label` slot of the item with the given id. + */ + getItemLabel: (id: string) => HTMLElement; + /** + * Returns the `iconContainer` slot of the item with the given id. + * @param {string} id The id of the item to retrieve. + * @returns {HTMLElement} `iconContainer` slot of the item with the given id. + */ + getItemIconContainer: (id: string) => HTMLElement; + /** + * Checks if an item is expanded. + * Uses the `aria-expanded` attribute to check the expansion. + * @param {string} id The id of the item to check. + * @returns {boolean} `true` if the item is expanded, `false` otherwise. + */ + isItemExpanded: (id: string) => boolean; +} + +export type DescribeTreeViewRenderer = < + R extends DescribeTreeViewItem, +>( + params: { + items: readonly R[]; + } & Omit, 'slots' | 'slotProps'> & { + slots?: TreeViewUsedParams['slots'] & { item?: React.ElementType }; + slotProps?: TreeViewUsedParams['slots'] & { item?: TreeItemProps | TreeItem2Props }; + }, +) => DescribeTreeViewRendererReturnValue; + +interface DescribeTreeViewTestRunnerParams { + render: DescribeTreeViewRenderer; + setup: + | 'SimpleTreeView + TreeItem' + | 'SimpleTreeView + TreeItem2' + | 'RichTreeView + TreeItem' + | 'RichTreeView + TreeItem2'; +} + +export interface DescribeTreeViewItem { + id: string; + label?: string; + disabled?: boolean; + children?: readonly DescribeTreeViewItem[]; +} diff --git a/test/utils/tree-view/describeTreeView/index.ts b/test/utils/tree-view/describeTreeView/index.ts new file mode 100644 index 0000000000000..5eba1f6c91652 --- /dev/null +++ b/test/utils/tree-view/describeTreeView/index.ts @@ -0,0 +1 @@ +export { describeTreeView } from './describeTreeView'; From 90d6d68296af37778332c2dbc4a71237f42e78bd Mon Sep 17 00:00:00 2001 From: Alissa Tung Date: Tue, 2 Apr 2024 16:08:44 +0800 Subject: [PATCH 43/55] [TreeView] Fix typo in errors (#12623) Signed-off-by: alissa-tung --- .../src/internals/plugins/useTreeViewItems/useTreeViewItems.ts | 2 +- .../plugins/useTreeViewJSXItems/useTreeViewJSXItems.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/x-tree-view/src/internals/plugins/useTreeViewItems/useTreeViewItems.ts b/packages/x-tree-view/src/internals/plugins/useTreeViewItems/useTreeViewItems.ts index 045e6e849065d..d8ea2faaacf5c 100644 --- a/packages/x-tree-view/src/internals/plugins/useTreeViewItems/useTreeViewItems.ts +++ b/packages/x-tree-view/src/internals/plugins/useTreeViewItems/useTreeViewItems.ts @@ -47,7 +47,7 @@ const updateItemsState = ({ [ 'MUI X: The Tree View component requires all items to have a unique `id` property.', 'Alternatively, you can use the `getItemId` prop to specify a custom id for each item.', - `Tow items were provided with the same id in the \`items\` prop: "${id}"`, + `Two items were provided with the same id in the \`items\` prop: "${id}"`, ].join('\n'), ); } diff --git a/packages/x-tree-view/src/internals/plugins/useTreeViewJSXItems/useTreeViewJSXItems.tsx b/packages/x-tree-view/src/internals/plugins/useTreeViewJSXItems/useTreeViewJSXItems.tsx index 30101b6c94519..2eaeaa552f660 100644 --- a/packages/x-tree-view/src/internals/plugins/useTreeViewJSXItems/useTreeViewJSXItems.tsx +++ b/packages/x-tree-view/src/internals/plugins/useTreeViewJSXItems/useTreeViewJSXItems.tsx @@ -27,7 +27,7 @@ export const useTreeViewJSXItems: TreeViewPlugin = [ 'MUI X: The Tree View component requires all items to have a unique `id` property.', 'Alternatively, you can use the `getItemId` prop to specify a custom id for each item.', - `Tow items were provided with the same id in the \`items\` prop: "${item.id}"`, + `Two items were provided with the same id in the \`items\` prop: "${item.id}"`, ].join('\n'), ); } From 4802a152add50974db2e49d389059456c8d0a3ce Mon Sep 17 00:00:00 2001 From: Alex Kobylansky <57197177+alexkobylansky@users.noreply.github.com> Date: Tue, 2 Apr 2024 11:15:42 +0300 Subject: [PATCH 44/55] [l10n] Improve Ukrainian (uk-UA) locale (#12627) Signed-off-by: Alex Kobylansky <57197177+alexkobylansky@users.noreply.github.com> Co-authored-by: Lukas --- docs/data/date-pickers/localization/data.json | 2 +- packages/x-date-pickers/src/locales/ukUA.ts | 28 +++++++++---------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/docs/data/date-pickers/localization/data.json b/docs/data/date-pickers/localization/data.json index 458f563e77d92..ba14dcc31ed5f 100644 --- a/docs/data/date-pickers/localization/data.json +++ b/docs/data/date-pickers/localization/data.json @@ -243,7 +243,7 @@ "languageTag": "uk-UA", "importName": "ukUA", "localeName": "Ukrainian", - "missingKeysCount": 14, + "missingKeysCount": 0, "totalKeysCount": 50, "githubLink": "https://github.com/mui/mui-x/blob/master/packages/x-date-pickers/src/locales/ukUA.ts" }, diff --git a/packages/x-date-pickers/src/locales/ukUA.ts b/packages/x-date-pickers/src/locales/ukUA.ts index bb53b6e26fcc9..2742d5dad70a1 100644 --- a/packages/x-date-pickers/src/locales/ukUA.ts +++ b/packages/x-date-pickers/src/locales/ukUA.ts @@ -25,10 +25,10 @@ const ukUAPickers: Partial> = { // DateRange labels start: 'Початок', end: 'Кінець', - // startDate: 'Start date', - // startTime: 'Start time', - // endDate: 'End date', - // endTime: 'End time', + startDate: 'День початку', + startTime: 'Час початку', + endDate: 'День закінчення', + endTime: 'Час закінчення', // Action bar cancelButtonLabel: 'Відміна', @@ -67,7 +67,7 @@ const ukUAPickers: Partial> = { value !== null && utils.isValid(value) ? `Оберіть час, обраний час ${utils.format(value, 'fullTime')}` : 'Оберіть час', - // fieldClearLabel: 'Clear value', + fieldClearLabel: 'Очистити дані', // Table labels timeTableLabel: 'оберіть час', @@ -84,17 +84,17 @@ const ukUAPickers: Partial> = { fieldMeridiemPlaceholder: () => 'aa', // View names - // year: 'Year', - // month: 'Month', - // day: 'Day', - // weekDay: 'Week day', - // hours: 'Hours', - // minutes: 'Minutes', - // seconds: 'Seconds', - // meridiem: 'Meridiem', + year: 'Рік', + month: 'Місяць', + day: 'День', + weekDay: 'День тижня', + hours: 'Годин', + minutes: 'Хвилин', + seconds: 'Секунд', + meridiem: 'Меридіем', // Common - // empty: 'Empty', + empty: 'Порожній', }; export const ukUA = getPickersLocalization(ukUAPickers); From 30909bfed35a7536e1e51f8cfea10041a5691be5 Mon Sep 17 00:00:00 2001 From: Josh Kelley Date: Tue, 2 Apr 2024 07:28:29 -0400 Subject: [PATCH 45/55] [docs] Fix grammar in TreeView migration doc (#12615) Signed-off-by: Josh Kelley --- .../migration/migration-tree-view-v6/migration-tree-view-v6.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/data/migration/migration-tree-view-v6/migration-tree-view-v6.md b/docs/data/migration/migration-tree-view-v6/migration-tree-view-v6.md index 4a368c1dc098e..965b06fc43df0 100644 --- a/docs/data/migration/migration-tree-view-v6/migration-tree-view-v6.md +++ b/docs/data/migration/migration-tree-view-v6/migration-tree-view-v6.md @@ -51,7 +51,7 @@ The required `nodeId` prop used by the `TreeItem` has been renamed to `itemId` f ``` -The same change has been applied to the and `ContentComponent` prop: +The same change has been applied to the `ContentComponent` prop: ```diff const CustomContent = React.forwardRef((props, ref) => { From fb445704d07aaa7e180f5d518199e59b698b92dd Mon Sep 17 00:00:00 2001 From: Lukas Date: Tue, 2 Apr 2024 14:52:12 +0300 Subject: [PATCH 46/55] [fields] Fix `readOnly` behavior (#12609) --- .../src/internals/hooks/useField/useFieldV6TextField.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/x-date-pickers/src/internals/hooks/useField/useFieldV6TextField.ts b/packages/x-date-pickers/src/internals/hooks/useField/useFieldV6TextField.ts index 5547dc9a047ad..90ecb24fe6ff7 100644 --- a/packages/x-date-pickers/src/internals/hooks/useField/useFieldV6TextField.ts +++ b/packages/x-date-pickers/src/internals/hooks/useField/useFieldV6TextField.ts @@ -171,7 +171,8 @@ export const useFieldV6TextField: UseFieldTextField = (params) => { getActiveSectionIndexFromDOM: () => { const browserStartIndex = inputRef.current!.selectionStart ?? 0; const browserEndIndex = inputRef.current!.selectionEnd ?? 0; - if (browserStartIndex === 0 && browserEndIndex === 0) { + const isInputReadOnly = !!inputRef.current?.readOnly; + if ((browserStartIndex === 0 && browserEndIndex === 0) || isInputReadOnly) { return null; } @@ -196,6 +197,7 @@ export const useFieldV6TextField: UseFieldTextField = (params) => { const syncSelectionFromDOM = () => { if (readOnly) { + setSelectedSections(null); return; } const browserStartIndex = inputRef.current!.selectionStart ?? 0; From d50147efd66ceb9222f0c3d5cd7720dabb070115 Mon Sep 17 00:00:00 2001 From: Flavien DELANGLE Date: Tue, 2 Apr 2024 16:08:50 +0200 Subject: [PATCH 47/55] [docs] Fix typo in getItemId prop description (#12637) --- .../api-docs/tree-view/rich-tree-view/rich-tree-view.json | 2 +- packages/x-tree-view/src/RichTreeView/RichTreeView.tsx | 2 +- .../plugins/useTreeViewItems/useTreeViewItems.types.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/translations/api-docs/tree-view/rich-tree-view/rich-tree-view.json b/docs/translations/api-docs/tree-view/rich-tree-view/rich-tree-view.json index 4f113ec528dd0..8e73109f8685b 100644 --- a/docs/translations/api-docs/tree-view/rich-tree-view/rich-tree-view.json +++ b/docs/translations/api-docs/tree-view/rich-tree-view/rich-tree-view.json @@ -19,7 +19,7 @@ "description": "Expanded item ids. Used when the item's expansion is controlled." }, "getItemId": { - "description": "Used to determine the string label for a given item.", + "description": "Used to determine the id of a given item.", "typeDescriptions": { "item": "The item to check.", "string": "The id of the item." } }, "getItemLabel": { diff --git a/packages/x-tree-view/src/RichTreeView/RichTreeView.tsx b/packages/x-tree-view/src/RichTreeView/RichTreeView.tsx index f0d469068892b..5983e1697daff 100644 --- a/packages/x-tree-view/src/RichTreeView/RichTreeView.tsx +++ b/packages/x-tree-view/src/RichTreeView/RichTreeView.tsx @@ -188,7 +188,7 @@ RichTreeView.propTypes = { */ expandedItems: PropTypes.arrayOf(PropTypes.string), /** - * Used to determine the string label for a given item. + * Used to determine the id of a given item. * * @template R * @param {R} item The item to check. diff --git a/packages/x-tree-view/src/internals/plugins/useTreeViewItems/useTreeViewItems.types.ts b/packages/x-tree-view/src/internals/plugins/useTreeViewItems/useTreeViewItems.types.ts index 37e704219cab1..5b20682d1a9b7 100644 --- a/packages/x-tree-view/src/internals/plugins/useTreeViewItems/useTreeViewItems.types.ts +++ b/packages/x-tree-view/src/internals/plugins/useTreeViewItems/useTreeViewItems.types.ts @@ -55,7 +55,7 @@ export interface UseTreeViewItemsParameters { */ getItemLabel?: (item: R) => string; /** - * Used to determine the string label for a given item. + * Used to determine the id of a given item. * * @template R * @param {R} item The item to check. From 2791237f51cc4a11582932b98a20f0eadd00c878 Mon Sep 17 00:00:00 2001 From: cnHealth <158763580+cnHealth@users.noreply.github.com> Date: Tue, 2 Apr 2024 11:45:47 -0300 Subject: [PATCH 48/55] [l10n] Improve Portuguese (pt-BR) locale (#12613) Signed-off-by: cnHealth <158763580+cnHealth@users.noreply.github.com> Signed-off-by: Lukas Co-authored-by: Lukas --- docs/data/date-pickers/localization/data.json | 2 +- packages/x-date-pickers/src/locales/ptBR.ts | 26 +++++++++---------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/docs/data/date-pickers/localization/data.json b/docs/data/date-pickers/localization/data.json index ba14dcc31ed5f..fced02554cba0 100644 --- a/docs/data/date-pickers/localization/data.json +++ b/docs/data/date-pickers/localization/data.json @@ -187,7 +187,7 @@ "languageTag": "pt-BR", "importName": "ptBR", "localeName": "Portuguese (Brazil)", - "missingKeysCount": 14, + "missingKeysCount": 1, "totalKeysCount": 50, "githubLink": "https://github.com/mui/mui-x/blob/master/packages/x-date-pickers/src/locales/ptBR.ts" }, diff --git a/packages/x-date-pickers/src/locales/ptBR.ts b/packages/x-date-pickers/src/locales/ptBR.ts index 14b54dd8ca793..0e6385db76286 100644 --- a/packages/x-date-pickers/src/locales/ptBR.ts +++ b/packages/x-date-pickers/src/locales/ptBR.ts @@ -25,10 +25,10 @@ const ptBRPickers: Partial> = { // DateRange labels start: 'Início', end: 'Fim', - // startDate: 'Start date', - // startTime: 'Start time', - // endDate: 'End date', - // endTime: 'End time', + startDate: 'Data de início', + startTime: 'Hora de início', + endDate: 'Data de Término', + endTime: 'Hora de Término', // Action bar cancelButtonLabel: 'Cancelar', @@ -84,17 +84,17 @@ const ptBRPickers: Partial> = { fieldMeridiemPlaceholder: () => 'aa', // View names - // year: 'Year', - // month: 'Month', - // day: 'Day', - // weekDay: 'Week day', - // hours: 'Hours', - // minutes: 'Minutes', - // seconds: 'Seconds', - // meridiem: 'Meridiem', + year: 'Ano', + month: 'Mês', + day: 'Dia', + weekDay: 'Dia da Semana', + hours: 'Horas', + minutes: 'Minutos', + seconds: 'Segundos', + meridiem: 'Meio dia', // Common - // empty: 'Empty', + empty: 'Vazio', }; export const ptBR = getPickersLocalization(ptBRPickers); From 83fd4efacac03c2088be5cec3d1c93af7e4edc7d Mon Sep 17 00:00:00 2001 From: Lukas Date: Wed, 3 Apr 2024 10:29:41 +0300 Subject: [PATCH 49/55] [docs] Remove `day` from the default `dayOfWeekFormatter` function params (#12644) --- docs/pages/x/api/date-pickers/date-calendar.json | 2 +- docs/pages/x/api/date-pickers/date-picker.json | 2 +- docs/pages/x/api/date-pickers/date-range-calendar.json | 2 +- docs/pages/x/api/date-pickers/date-range-picker.json | 2 +- docs/pages/x/api/date-pickers/date-time-picker.json | 2 +- docs/pages/x/api/date-pickers/date-time-range-picker.json | 2 +- docs/pages/x/api/date-pickers/desktop-date-picker.json | 2 +- docs/pages/x/api/date-pickers/desktop-date-range-picker.json | 2 +- docs/pages/x/api/date-pickers/desktop-date-time-picker.json | 2 +- .../x/api/date-pickers/desktop-date-time-range-picker.json | 2 +- docs/pages/x/api/date-pickers/mobile-date-picker.json | 2 +- docs/pages/x/api/date-pickers/mobile-date-range-picker.json | 2 +- docs/pages/x/api/date-pickers/mobile-date-time-picker.json | 2 +- .../pages/x/api/date-pickers/mobile-date-time-range-picker.json | 2 +- docs/pages/x/api/date-pickers/static-date-picker.json | 2 +- docs/pages/x/api/date-pickers/static-date-range-picker.json | 2 +- docs/pages/x/api/date-pickers/static-date-time-picker.json | 2 +- .../src/DateRangeCalendar/DateRangeCalendar.tsx | 2 +- .../x-date-pickers-pro/src/DateRangePicker/DateRangePicker.tsx | 2 +- .../src/DateTimeRangePicker/DateTimeRangePicker.tsx | 2 +- .../src/DesktopDateRangePicker/DesktopDateRangePicker.tsx | 2 +- .../DesktopDateTimeRangePicker/DesktopDateTimeRangePicker.tsx | 2 +- .../src/MobileDateRangePicker/MobileDateRangePicker.tsx | 2 +- .../src/MobileDateTimeRangePicker/MobileDateTimeRangePicker.tsx | 2 +- .../src/StaticDateRangePicker/StaticDateRangePicker.tsx | 2 +- packages/x-date-pickers/src/DateCalendar/DateCalendar.tsx | 2 +- packages/x-date-pickers/src/DateCalendar/DayCalendar.tsx | 2 +- packages/x-date-pickers/src/DatePicker/DatePicker.tsx | 2 +- packages/x-date-pickers/src/DateTimePicker/DateTimePicker.tsx | 2 +- .../x-date-pickers/src/DesktopDatePicker/DesktopDatePicker.tsx | 2 +- .../src/DesktopDateTimePicker/DesktopDateTimePicker.tsx | 2 +- .../x-date-pickers/src/MobileDatePicker/MobileDatePicker.tsx | 2 +- .../src/MobileDateTimePicker/MobileDateTimePicker.tsx | 2 +- .../x-date-pickers/src/StaticDatePicker/StaticDatePicker.tsx | 2 +- .../src/StaticDateTimePicker/StaticDateTimePicker.tsx | 2 +- 35 files changed, 35 insertions(+), 35 deletions(-) diff --git a/docs/pages/x/api/date-pickers/date-calendar.json b/docs/pages/x/api/date-pickers/date-calendar.json index 72f1cd7957199..68c507d55288a 100644 --- a/docs/pages/x/api/date-pickers/date-calendar.json +++ b/docs/pages/x/api/date-pickers/date-calendar.json @@ -4,7 +4,7 @@ "classes": { "type": { "name": "object" }, "additionalInfo": { "cssApi": true } }, "dayOfWeekFormatter": { "type": { "name": "func" }, - "default": "(_day: string, date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase()", + "default": "(date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase()", "signature": { "type": "function(date: TDate) => string", "describedArgs": ["date"], diff --git a/docs/pages/x/api/date-pickers/date-picker.json b/docs/pages/x/api/date-pickers/date-picker.json index c615567fe8291..ea40f5ecb500c 100644 --- a/docs/pages/x/api/date-pickers/date-picker.json +++ b/docs/pages/x/api/date-pickers/date-picker.json @@ -7,7 +7,7 @@ }, "dayOfWeekFormatter": { "type": { "name": "func" }, - "default": "(_day: string, date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase()", + "default": "(date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase()", "signature": { "type": "function(date: TDate) => string", "describedArgs": ["date"], diff --git a/docs/pages/x/api/date-pickers/date-range-calendar.json b/docs/pages/x/api/date-pickers/date-range-calendar.json index 0c0a1d51c6b5c..70821cf053e2a 100644 --- a/docs/pages/x/api/date-pickers/date-range-calendar.json +++ b/docs/pages/x/api/date-pickers/date-range-calendar.json @@ -16,7 +16,7 @@ }, "dayOfWeekFormatter": { "type": { "name": "func" }, - "default": "(_day: string, date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase()", + "default": "(date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase()", "signature": { "type": "function(date: TDate) => string", "describedArgs": ["date"], diff --git a/docs/pages/x/api/date-pickers/date-range-picker.json b/docs/pages/x/api/date-pickers/date-range-picker.json index 99612ca1ca76e..9f44960cf2794 100644 --- a/docs/pages/x/api/date-pickers/date-range-picker.json +++ b/docs/pages/x/api/date-pickers/date-range-picker.json @@ -15,7 +15,7 @@ }, "dayOfWeekFormatter": { "type": { "name": "func" }, - "default": "(_day: string, date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase()", + "default": "(date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase()", "signature": { "type": "function(date: TDate) => string", "describedArgs": ["date"], diff --git a/docs/pages/x/api/date-pickers/date-time-picker.json b/docs/pages/x/api/date-pickers/date-time-picker.json index 1588c746f832d..a95659e8955ee 100644 --- a/docs/pages/x/api/date-pickers/date-time-picker.json +++ b/docs/pages/x/api/date-pickers/date-time-picker.json @@ -9,7 +9,7 @@ }, "dayOfWeekFormatter": { "type": { "name": "func" }, - "default": "(_day: string, date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase()", + "default": "(date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase()", "signature": { "type": "function(date: TDate) => string", "describedArgs": ["date"], diff --git a/docs/pages/x/api/date-pickers/date-time-range-picker.json b/docs/pages/x/api/date-pickers/date-time-range-picker.json index 1c8645cf410ed..c176e8c1e00e9 100644 --- a/docs/pages/x/api/date-pickers/date-time-range-picker.json +++ b/docs/pages/x/api/date-pickers/date-time-range-picker.json @@ -16,7 +16,7 @@ }, "dayOfWeekFormatter": { "type": { "name": "func" }, - "default": "(_day: string, date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase()", + "default": "(date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase()", "signature": { "type": "function(date: TDate) => string", "describedArgs": ["date"], diff --git a/docs/pages/x/api/date-pickers/desktop-date-picker.json b/docs/pages/x/api/date-pickers/desktop-date-picker.json index 8054ed48893cc..a444cde654f37 100644 --- a/docs/pages/x/api/date-pickers/desktop-date-picker.json +++ b/docs/pages/x/api/date-pickers/desktop-date-picker.json @@ -7,7 +7,7 @@ }, "dayOfWeekFormatter": { "type": { "name": "func" }, - "default": "(_day: string, date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase()", + "default": "(date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase()", "signature": { "type": "function(date: TDate) => string", "describedArgs": ["date"], diff --git a/docs/pages/x/api/date-pickers/desktop-date-range-picker.json b/docs/pages/x/api/date-pickers/desktop-date-range-picker.json index 56ef916cd278e..de5d83a3570f2 100644 --- a/docs/pages/x/api/date-pickers/desktop-date-range-picker.json +++ b/docs/pages/x/api/date-pickers/desktop-date-range-picker.json @@ -15,7 +15,7 @@ }, "dayOfWeekFormatter": { "type": { "name": "func" }, - "default": "(_day: string, date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase()", + "default": "(date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase()", "signature": { "type": "function(date: TDate) => string", "describedArgs": ["date"], diff --git a/docs/pages/x/api/date-pickers/desktop-date-time-picker.json b/docs/pages/x/api/date-pickers/desktop-date-time-picker.json index bdc527c14f28d..85b246eb27e6c 100644 --- a/docs/pages/x/api/date-pickers/desktop-date-time-picker.json +++ b/docs/pages/x/api/date-pickers/desktop-date-time-picker.json @@ -9,7 +9,7 @@ }, "dayOfWeekFormatter": { "type": { "name": "func" }, - "default": "(_day: string, date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase()", + "default": "(date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase()", "signature": { "type": "function(date: TDate) => string", "describedArgs": ["date"], diff --git a/docs/pages/x/api/date-pickers/desktop-date-time-range-picker.json b/docs/pages/x/api/date-pickers/desktop-date-time-range-picker.json index e17818a31797f..3a3612e730a4a 100644 --- a/docs/pages/x/api/date-pickers/desktop-date-time-range-picker.json +++ b/docs/pages/x/api/date-pickers/desktop-date-time-range-picker.json @@ -16,7 +16,7 @@ }, "dayOfWeekFormatter": { "type": { "name": "func" }, - "default": "(_day: string, date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase()", + "default": "(date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase()", "signature": { "type": "function(date: TDate) => string", "describedArgs": ["date"], diff --git a/docs/pages/x/api/date-pickers/mobile-date-picker.json b/docs/pages/x/api/date-pickers/mobile-date-picker.json index 9c2d12c3887c0..ef656fc6dcee5 100644 --- a/docs/pages/x/api/date-pickers/mobile-date-picker.json +++ b/docs/pages/x/api/date-pickers/mobile-date-picker.json @@ -7,7 +7,7 @@ }, "dayOfWeekFormatter": { "type": { "name": "func" }, - "default": "(_day: string, date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase()", + "default": "(date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase()", "signature": { "type": "function(date: TDate) => string", "describedArgs": ["date"], diff --git a/docs/pages/x/api/date-pickers/mobile-date-range-picker.json b/docs/pages/x/api/date-pickers/mobile-date-range-picker.json index 4e4b02c80de7f..8bdc9753d9b96 100644 --- a/docs/pages/x/api/date-pickers/mobile-date-range-picker.json +++ b/docs/pages/x/api/date-pickers/mobile-date-range-picker.json @@ -11,7 +11,7 @@ }, "dayOfWeekFormatter": { "type": { "name": "func" }, - "default": "(_day: string, date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase()", + "default": "(date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase()", "signature": { "type": "function(date: TDate) => string", "describedArgs": ["date"], diff --git a/docs/pages/x/api/date-pickers/mobile-date-time-picker.json b/docs/pages/x/api/date-pickers/mobile-date-time-picker.json index a31d556420df3..6e53b200352f1 100644 --- a/docs/pages/x/api/date-pickers/mobile-date-time-picker.json +++ b/docs/pages/x/api/date-pickers/mobile-date-time-picker.json @@ -9,7 +9,7 @@ }, "dayOfWeekFormatter": { "type": { "name": "func" }, - "default": "(_day: string, date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase()", + "default": "(date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase()", "signature": { "type": "function(date: TDate) => string", "describedArgs": ["date"], diff --git a/docs/pages/x/api/date-pickers/mobile-date-time-range-picker.json b/docs/pages/x/api/date-pickers/mobile-date-time-range-picker.json index 2b82a772e23a6..3ec3f5b6d941d 100644 --- a/docs/pages/x/api/date-pickers/mobile-date-time-range-picker.json +++ b/docs/pages/x/api/date-pickers/mobile-date-time-range-picker.json @@ -12,7 +12,7 @@ }, "dayOfWeekFormatter": { "type": { "name": "func" }, - "default": "(_day: string, date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase()", + "default": "(date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase()", "signature": { "type": "function(date: TDate) => string", "describedArgs": ["date"], diff --git a/docs/pages/x/api/date-pickers/static-date-picker.json b/docs/pages/x/api/date-pickers/static-date-picker.json index 07823b0be25c8..a392f5a1d6dc3 100644 --- a/docs/pages/x/api/date-pickers/static-date-picker.json +++ b/docs/pages/x/api/date-pickers/static-date-picker.json @@ -3,7 +3,7 @@ "autoFocus": { "type": { "name": "bool" } }, "dayOfWeekFormatter": { "type": { "name": "func" }, - "default": "(_day: string, date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase()", + "default": "(date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase()", "signature": { "type": "function(date: TDate) => string", "describedArgs": ["date"], diff --git a/docs/pages/x/api/date-pickers/static-date-range-picker.json b/docs/pages/x/api/date-pickers/static-date-range-picker.json index e4c0366f38fd2..25ac2072a6710 100644 --- a/docs/pages/x/api/date-pickers/static-date-range-picker.json +++ b/docs/pages/x/api/date-pickers/static-date-range-picker.json @@ -11,7 +11,7 @@ }, "dayOfWeekFormatter": { "type": { "name": "func" }, - "default": "(_day: string, date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase()", + "default": "(date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase()", "signature": { "type": "function(date: TDate) => string", "describedArgs": ["date"], diff --git a/docs/pages/x/api/date-pickers/static-date-time-picker.json b/docs/pages/x/api/date-pickers/static-date-time-picker.json index 90e73442433fc..1d05b51bb020a 100644 --- a/docs/pages/x/api/date-pickers/static-date-time-picker.json +++ b/docs/pages/x/api/date-pickers/static-date-time-picker.json @@ -5,7 +5,7 @@ "autoFocus": { "type": { "name": "bool" } }, "dayOfWeekFormatter": { "type": { "name": "func" }, - "default": "(_day: string, date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase()", + "default": "(date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase()", "signature": { "type": "function(date: TDate) => string", "describedArgs": ["date"], diff --git a/packages/x-date-pickers-pro/src/DateRangeCalendar/DateRangeCalendar.tsx b/packages/x-date-pickers-pro/src/DateRangeCalendar/DateRangeCalendar.tsx index 328bd4358a57d..3bab7b2bfbdea 100644 --- a/packages/x-date-pickers-pro/src/DateRangeCalendar/DateRangeCalendar.tsx +++ b/packages/x-date-pickers-pro/src/DateRangeCalendar/DateRangeCalendar.tsx @@ -623,7 +623,7 @@ DateRangeCalendar.propTypes = { * Formats the day of week displayed in the calendar header. * @param {TDate} date The date of the day of week provided by the adapter. * @returns {string} The name to display. - * @default (_day: string, date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase() + * @default (date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase() */ dayOfWeekFormatter: PropTypes.func, /** diff --git a/packages/x-date-pickers-pro/src/DateRangePicker/DateRangePicker.tsx b/packages/x-date-pickers-pro/src/DateRangePicker/DateRangePicker.tsx index 679515dd3ab2a..6d48492f955f9 100644 --- a/packages/x-date-pickers-pro/src/DateRangePicker/DateRangePicker.tsx +++ b/packages/x-date-pickers-pro/src/DateRangePicker/DateRangePicker.tsx @@ -79,7 +79,7 @@ DateRangePicker.propTypes = { * Formats the day of week displayed in the calendar header. * @param {TDate} date The date of the day of week provided by the adapter. * @returns {string} The name to display. - * @default (_day: string, date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase() + * @default (date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase() */ dayOfWeekFormatter: PropTypes.func, /** diff --git a/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePicker.tsx b/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePicker.tsx index b0cb8e230c46c..e015a0972a387 100644 --- a/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePicker.tsx +++ b/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePicker.tsx @@ -84,7 +84,7 @@ DateTimeRangePicker.propTypes = { * Formats the day of week displayed in the calendar header. * @param {TDate} date The date of the day of week provided by the adapter. * @returns {string} The name to display. - * @default (_day: string, date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase() + * @default (date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase() */ dayOfWeekFormatter: PropTypes.func, /** diff --git a/packages/x-date-pickers-pro/src/DesktopDateRangePicker/DesktopDateRangePicker.tsx b/packages/x-date-pickers-pro/src/DesktopDateRangePicker/DesktopDateRangePicker.tsx index c3ae2ac5605da..83f7274a8e5bf 100644 --- a/packages/x-date-pickers-pro/src/DesktopDateRangePicker/DesktopDateRangePicker.tsx +++ b/packages/x-date-pickers-pro/src/DesktopDateRangePicker/DesktopDateRangePicker.tsx @@ -120,7 +120,7 @@ DesktopDateRangePicker.propTypes = { * Formats the day of week displayed in the calendar header. * @param {TDate} date The date of the day of week provided by the adapter. * @returns {string} The name to display. - * @default (_day: string, date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase() + * @default (date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase() */ dayOfWeekFormatter: PropTypes.func, /** diff --git a/packages/x-date-pickers-pro/src/DesktopDateTimeRangePicker/DesktopDateTimeRangePicker.tsx b/packages/x-date-pickers-pro/src/DesktopDateTimeRangePicker/DesktopDateTimeRangePicker.tsx index 89b24bee7f248..8f90fa61d321c 100644 --- a/packages/x-date-pickers-pro/src/DesktopDateTimeRangePicker/DesktopDateTimeRangePicker.tsx +++ b/packages/x-date-pickers-pro/src/DesktopDateTimeRangePicker/DesktopDateTimeRangePicker.tsx @@ -252,7 +252,7 @@ DesktopDateTimeRangePicker.propTypes = { * Formats the day of week displayed in the calendar header. * @param {TDate} date The date of the day of week provided by the adapter. * @returns {string} The name to display. - * @default (_day: string, date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase() + * @default (date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase() */ dayOfWeekFormatter: PropTypes.func, /** diff --git a/packages/x-date-pickers-pro/src/MobileDateRangePicker/MobileDateRangePicker.tsx b/packages/x-date-pickers-pro/src/MobileDateRangePicker/MobileDateRangePicker.tsx index c65509df1c359..5dfa0b6ed65c9 100644 --- a/packages/x-date-pickers-pro/src/MobileDateRangePicker/MobileDateRangePicker.tsx +++ b/packages/x-date-pickers-pro/src/MobileDateRangePicker/MobileDateRangePicker.tsx @@ -116,7 +116,7 @@ MobileDateRangePicker.propTypes = { * Formats the day of week displayed in the calendar header. * @param {TDate} date The date of the day of week provided by the adapter. * @returns {string} The name to display. - * @default (_day: string, date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase() + * @default (date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase() */ dayOfWeekFormatter: PropTypes.func, /** diff --git a/packages/x-date-pickers-pro/src/MobileDateTimeRangePicker/MobileDateTimeRangePicker.tsx b/packages/x-date-pickers-pro/src/MobileDateTimeRangePicker/MobileDateTimeRangePicker.tsx index ce0f3684164ab..f6a0beb025cc5 100644 --- a/packages/x-date-pickers-pro/src/MobileDateTimeRangePicker/MobileDateTimeRangePicker.tsx +++ b/packages/x-date-pickers-pro/src/MobileDateTimeRangePicker/MobileDateTimeRangePicker.tsx @@ -244,7 +244,7 @@ MobileDateTimeRangePicker.propTypes = { * Formats the day of week displayed in the calendar header. * @param {TDate} date The date of the day of week provided by the adapter. * @returns {string} The name to display. - * @default (_day: string, date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase() + * @default (date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase() */ dayOfWeekFormatter: PropTypes.func, /** diff --git a/packages/x-date-pickers-pro/src/StaticDateRangePicker/StaticDateRangePicker.tsx b/packages/x-date-pickers-pro/src/StaticDateRangePicker/StaticDateRangePicker.tsx index bb3c4aa34ed7d..5d099a3323281 100644 --- a/packages/x-date-pickers-pro/src/StaticDateRangePicker/StaticDateRangePicker.tsx +++ b/packages/x-date-pickers-pro/src/StaticDateRangePicker/StaticDateRangePicker.tsx @@ -94,7 +94,7 @@ StaticDateRangePicker.propTypes = { * Formats the day of week displayed in the calendar header. * @param {TDate} date The date of the day of week provided by the adapter. * @returns {string} The name to display. - * @default (_day: string, date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase() + * @default (date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase() */ dayOfWeekFormatter: PropTypes.func, /** diff --git a/packages/x-date-pickers/src/DateCalendar/DateCalendar.tsx b/packages/x-date-pickers/src/DateCalendar/DateCalendar.tsx index b14728935e28f..95df734302d8c 100644 --- a/packages/x-date-pickers/src/DateCalendar/DateCalendar.tsx +++ b/packages/x-date-pickers/src/DateCalendar/DateCalendar.tsx @@ -425,7 +425,7 @@ DateCalendar.propTypes = { * Formats the day of week displayed in the calendar header. * @param {TDate} date The date of the day of week provided by the adapter. * @returns {string} The name to display. - * @default (_day: string, date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase() + * @default (date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase() */ dayOfWeekFormatter: PropTypes.func, /** diff --git a/packages/x-date-pickers/src/DateCalendar/DayCalendar.tsx b/packages/x-date-pickers/src/DateCalendar/DayCalendar.tsx index a16854f0e499b..de6365bc00afc 100644 --- a/packages/x-date-pickers/src/DateCalendar/DayCalendar.tsx +++ b/packages/x-date-pickers/src/DateCalendar/DayCalendar.tsx @@ -64,7 +64,7 @@ export interface ExportedDayCalendarProps * Formats the day of week displayed in the calendar header. * @param {TDate} date The date of the day of week provided by the adapter. * @returns {string} The name to display. - * @default (_day: string, date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase() + * @default (date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase() */ dayOfWeekFormatter?: (date: TDate) => string; /** diff --git a/packages/x-date-pickers/src/DatePicker/DatePicker.tsx b/packages/x-date-pickers/src/DatePicker/DatePicker.tsx index 65f36dbf7537a..0fb35eb2fa6d0 100644 --- a/packages/x-date-pickers/src/DatePicker/DatePicker.tsx +++ b/packages/x-date-pickers/src/DatePicker/DatePicker.tsx @@ -70,7 +70,7 @@ DatePicker.propTypes = { * Formats the day of week displayed in the calendar header. * @param {TDate} date The date of the day of week provided by the adapter. * @returns {string} The name to display. - * @default (_day: string, date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase() + * @default (date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase() */ dayOfWeekFormatter: PropTypes.func, /** diff --git a/packages/x-date-pickers/src/DateTimePicker/DateTimePicker.tsx b/packages/x-date-pickers/src/DateTimePicker/DateTimePicker.tsx index 68edc264b00fb..67d50cb407428 100644 --- a/packages/x-date-pickers/src/DateTimePicker/DateTimePicker.tsx +++ b/packages/x-date-pickers/src/DateTimePicker/DateTimePicker.tsx @@ -80,7 +80,7 @@ DateTimePicker.propTypes = { * Formats the day of week displayed in the calendar header. * @param {TDate} date The date of the day of week provided by the adapter. * @returns {string} The name to display. - * @default (_day: string, date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase() + * @default (date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase() */ dayOfWeekFormatter: PropTypes.func, /** diff --git a/packages/x-date-pickers/src/DesktopDatePicker/DesktopDatePicker.tsx b/packages/x-date-pickers/src/DesktopDatePicker/DesktopDatePicker.tsx index aaeb03f1eebaf..741ba0caf36d0 100644 --- a/packages/x-date-pickers/src/DesktopDatePicker/DesktopDatePicker.tsx +++ b/packages/x-date-pickers/src/DesktopDatePicker/DesktopDatePicker.tsx @@ -120,7 +120,7 @@ DesktopDatePicker.propTypes = { * Formats the day of week displayed in the calendar header. * @param {TDate} date The date of the day of week provided by the adapter. * @returns {string} The name to display. - * @default (_day: string, date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase() + * @default (date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase() */ dayOfWeekFormatter: PropTypes.func, /** diff --git a/packages/x-date-pickers/src/DesktopDateTimePicker/DesktopDateTimePicker.tsx b/packages/x-date-pickers/src/DesktopDateTimePicker/DesktopDateTimePicker.tsx index 7233ff2ad4bec..f20cf6d44c8f0 100644 --- a/packages/x-date-pickers/src/DesktopDateTimePicker/DesktopDateTimePicker.tsx +++ b/packages/x-date-pickers/src/DesktopDateTimePicker/DesktopDateTimePicker.tsx @@ -265,7 +265,7 @@ DesktopDateTimePicker.propTypes = { * Formats the day of week displayed in the calendar header. * @param {TDate} date The date of the day of week provided by the adapter. * @returns {string} The name to display. - * @default (_day: string, date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase() + * @default (date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase() */ dayOfWeekFormatter: PropTypes.func, /** diff --git a/packages/x-date-pickers/src/MobileDatePicker/MobileDatePicker.tsx b/packages/x-date-pickers/src/MobileDatePicker/MobileDatePicker.tsx index 25a5fd739b7f1..eb6084ac6dd78 100644 --- a/packages/x-date-pickers/src/MobileDatePicker/MobileDatePicker.tsx +++ b/packages/x-date-pickers/src/MobileDatePicker/MobileDatePicker.tsx @@ -117,7 +117,7 @@ MobileDatePicker.propTypes = { * Formats the day of week displayed in the calendar header. * @param {TDate} date The date of the day of week provided by the adapter. * @returns {string} The name to display. - * @default (_day: string, date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase() + * @default (date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase() */ dayOfWeekFormatter: PropTypes.func, /** diff --git a/packages/x-date-pickers/src/MobileDateTimePicker/MobileDateTimePicker.tsx b/packages/x-date-pickers/src/MobileDateTimePicker/MobileDateTimePicker.tsx index 3489751741c5c..204b2218b393b 100644 --- a/packages/x-date-pickers/src/MobileDateTimePicker/MobileDateTimePicker.tsx +++ b/packages/x-date-pickers/src/MobileDateTimePicker/MobileDateTimePicker.tsx @@ -142,7 +142,7 @@ MobileDateTimePicker.propTypes = { * Formats the day of week displayed in the calendar header. * @param {TDate} date The date of the day of week provided by the adapter. * @returns {string} The name to display. - * @default (_day: string, date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase() + * @default (date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase() */ dayOfWeekFormatter: PropTypes.func, /** diff --git a/packages/x-date-pickers/src/StaticDatePicker/StaticDatePicker.tsx b/packages/x-date-pickers/src/StaticDatePicker/StaticDatePicker.tsx index cb5fb76cb9c34..a079d4cedb3dd 100644 --- a/packages/x-date-pickers/src/StaticDatePicker/StaticDatePicker.tsx +++ b/packages/x-date-pickers/src/StaticDatePicker/StaticDatePicker.tsx @@ -83,7 +83,7 @@ StaticDatePicker.propTypes = { * Formats the day of week displayed in the calendar header. * @param {TDate} date The date of the day of week provided by the adapter. * @returns {string} The name to display. - * @default (_day: string, date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase() + * @default (date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase() */ dayOfWeekFormatter: PropTypes.func, /** diff --git a/packages/x-date-pickers/src/StaticDateTimePicker/StaticDateTimePicker.tsx b/packages/x-date-pickers/src/StaticDateTimePicker/StaticDateTimePicker.tsx index caa6285fbee99..ef875b3b8bec1 100644 --- a/packages/x-date-pickers/src/StaticDateTimePicker/StaticDateTimePicker.tsx +++ b/packages/x-date-pickers/src/StaticDateTimePicker/StaticDateTimePicker.tsx @@ -107,7 +107,7 @@ StaticDateTimePicker.propTypes = { * Formats the day of week displayed in the calendar header. * @param {TDate} date The date of the day of week provided by the adapter. * @returns {string} The name to display. - * @default (_day: string, date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase() + * @default (date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase() */ dayOfWeekFormatter: PropTypes.func, /** From d6e6c75fdb8a2473e2b21a067275c2a4c73ce9f4 Mon Sep 17 00:00:00 2001 From: Lukas Date: Wed, 3 Apr 2024 10:50:44 +0300 Subject: [PATCH 50/55] [core] Use PR labels to identify the package a `l10n` PR belongs to (#12639) --- scripts/releaseChangelog.mjs | 43 +++++++++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 3 deletions(-) diff --git a/scripts/releaseChangelog.mjs b/scripts/releaseChangelog.mjs index 595630d7b093c..ebfd37789ef10 100644 --- a/scripts/releaseChangelog.mjs +++ b/scripts/releaseChangelog.mjs @@ -42,6 +42,23 @@ async function findLatestTaggedVersion(octokit) { return data[0].name.trim(); } +function resolvePackageByLabels(labels) { + let resolvedPackage = null; + labels.forEach((label) => { + switch (label.name) { + case 'component: data grid': + resolvedPackage = 'DataGrid'; + break; + case 'component: pickers': + resolvedPackage = 'pickers'; + break; + default: + break; + } + }); + return resolvedPackage; +} + async function main(argv) { const { githubToken, lastRelease: lastReleaseInput, release } = argv; @@ -89,6 +106,7 @@ async function main(argv) { // Fetch all the pull Request and check if there is a section named changelog const changeLogMessages = []; + const prsLabelsMap = {}; await Promise.all( commitsItems.map(async (commitsItem) => { const searchPullRequestId = commitsItem.commit.message.match(/\(#([0-9]+)\)/); @@ -97,13 +115,15 @@ async function main(argv) { } const { - data: { body: bodyMessage }, + data: { body: bodyMessage, labels }, } = await octokit.request('GET /repos/{owner}/{repo}/pulls/{pull_number}', { owner: GIT_ORGANIZATION, repo: GIT_REPO, pull_number: Number(searchPullRequestId[1]), }); + prsLabelsMap[commitsItem.sha] = labels; + if (!bodyMessage) { return; } @@ -146,8 +166,6 @@ async function main(argv) { const tag = parseTags(commitItem.commit.message); switch (tag) { case 'DataGrid': - case 'l10n': - case '118n': dataGridCommits.push(commitItem); break; case 'DataGridPro': @@ -182,6 +200,25 @@ async function main(argv) { case 'codemod': codemodCommits.push(commitItem); break; + case 'l10n': + case '118n': { + const prLabels = prsLabelsMap[commitItem.sha]; + const resolvedPackage = resolvePackageByLabels(prLabels); + if (resolvedPackage) { + switch (resolvedPackage) { + case 'DataGrid': + dataGridCommits.push(commitItem); + break; + case 'pickers': + pickersCommits.push(commitItem); + break; + default: + coreCommits.push(commitItem); + break; + } + } + break; + } default: otherCommits.push(commitItem); break; From cfd228d2ba73f91a4c5f98f919f5f4162b398cfd Mon Sep 17 00:00:00 2001 From: eddine zeroual <48633360+alp-ex@users.noreply.github.com> Date: Wed, 3 Apr 2024 09:58:06 +0200 Subject: [PATCH 51/55] [docs] Fix missing closing props in `PieShapeNoSnap` demo (#12636) Signed-off-by: eddine zeroual <48633360+alp-ex@users.noreply.github.com> --- docs/data/charts/pie/PieShapeNoSnap.js | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/data/charts/pie/PieShapeNoSnap.js b/docs/data/charts/pie/PieShapeNoSnap.js index 8640c4d17ddc8..9952d0c2a3fed 100644 --- a/docs/data/charts/pie/PieShapeNoSnap.js +++ b/docs/data/charts/pie/PieShapeNoSnap.js @@ -52,6 +52,7 @@ export default function PieShapeNoSnap() { ` cx: ${props.cx},`, ` cy: ${props.cy},`, ` }`, + ` ]}`, '/>', ].join('\n'); }} From 3d86411074f2fe291d42edfa4b930f9baa951f62 Mon Sep 17 00:00:00 2001 From: Alexandre Fauquette <45398769+alexfauquette@users.noreply.github.com> Date: Wed, 3 Apr 2024 10:01:52 +0200 Subject: [PATCH 52/55] [docs] Remove ` around @default values (#12158) --- docs/pages/x/api/data-grid/data-grid-premium.json | 2 +- docs/pages/x/api/data-grid/grid-aggregation-function.json | 4 ++-- docs/pages/x/api/data-grid/grid-csv-export-options.json | 2 +- docs/pages/x/api/data-grid/grid-excel-export-options.json | 2 +- docs/pages/x/api/data-grid/grid-filter-model.json | 6 +++--- docs/pages/x/api/date-pickers/date-field.json | 2 +- docs/pages/x/api/date-pickers/date-time-field.json | 4 ++-- docs/pages/x/api/date-pickers/date-time-picker.json | 2 +- docs/pages/x/api/date-pickers/date-time-range-picker.json | 2 +- docs/pages/x/api/date-pickers/desktop-date-time-picker.json | 2 +- .../x/api/date-pickers/desktop-date-time-range-picker.json | 2 +- docs/pages/x/api/date-pickers/desktop-time-picker.json | 2 +- docs/pages/x/api/date-pickers/digital-clock.json | 2 +- docs/pages/x/api/date-pickers/mobile-date-time-picker.json | 2 +- .../x/api/date-pickers/mobile-date-time-range-picker.json | 2 +- docs/pages/x/api/date-pickers/mobile-time-picker.json | 2 +- .../x/api/date-pickers/multi-input-date-range-field.json | 2 +- .../api/date-pickers/multi-input-date-time-range-field.json | 4 ++-- .../x/api/date-pickers/multi-input-time-range-field.json | 4 ++-- .../x/api/date-pickers/multi-section-digital-clock.json | 2 +- docs/pages/x/api/date-pickers/pickers-shortcuts.json | 2 +- .../x/api/date-pickers/single-input-date-range-field.json | 2 +- .../date-pickers/single-input-date-time-range-field.json | 4 ++-- .../x/api/date-pickers/single-input-time-range-field.json | 4 ++-- docs/pages/x/api/date-pickers/static-date-time-picker.json | 2 +- docs/pages/x/api/date-pickers/static-time-picker.json | 2 +- docs/pages/x/api/date-pickers/time-clock.json | 2 +- docs/pages/x/api/date-pickers/time-field.json | 4 ++-- docs/pages/x/api/date-pickers/time-picker.json | 2 +- docs/pages/x/api/tree-view/rich-tree-view.json | 4 ++-- .../src/DataGridPremium/DataGridPremium.tsx | 4 ++-- .../hooks/features/aggregation/gridAggregationInterfaces.ts | 4 ++-- .../x-data-grid-premium/src/models/dataGridPremiumProps.ts | 4 ++-- packages/x-data-grid/src/models/gridExport.ts | 4 ++-- packages/x-data-grid/src/models/gridFilterModel.ts | 6 +++--- .../src/DateTimeRangePicker/DateTimeRangePicker.tsx | 2 +- .../DesktopDateTimeRangePicker.tsx | 2 +- .../MobileDateTimeRangePicker/MobileDateTimeRangePicker.tsx | 2 +- .../MultiInputDateRangeField/MultiInputDateRangeField.tsx | 2 +- .../MultiInputDateTimeRangeField.tsx | 4 ++-- .../MultiInputTimeRangeField/MultiInputTimeRangeField.tsx | 4 ++-- .../SingleInputDateRangeField/SingleInputDateRangeField.tsx | 2 +- .../SingleInputDateTimeRangeField.tsx | 4 ++-- .../SingleInputTimeRangeField/SingleInputTimeRangeField.tsx | 4 ++-- .../src/internals/models/dateTimeRange.ts | 2 +- .../x-date-pickers-pro/src/internals/models/timeRange.ts | 2 +- packages/x-date-pickers/src/DateField/DateField.tsx | 2 +- packages/x-date-pickers/src/DateTimeField/DateTimeField.tsx | 4 ++-- .../x-date-pickers/src/DateTimeField/DateTimeField.types.ts | 2 +- .../x-date-pickers/src/DateTimePicker/DateTimePicker.tsx | 2 +- .../src/DesktopDateTimePicker/DesktopDateTimePicker.tsx | 2 +- .../src/DesktopTimePicker/DesktopTimePicker.tsx | 2 +- packages/x-date-pickers/src/DigitalClock/DigitalClock.tsx | 2 +- .../src/MobileDateTimePicker/MobileDateTimePicker.tsx | 2 +- .../src/MobileTimePicker/MobileTimePicker.tsx | 2 +- .../MultiSectionDigitalClock/MultiSectionDigitalClock.tsx | 2 +- .../src/PickersShortcuts/PickersShortcuts.tsx | 4 ++-- .../src/StaticDateTimePicker/StaticDateTimePicker.tsx | 2 +- .../src/StaticTimePicker/StaticTimePicker.tsx | 2 +- packages/x-date-pickers/src/TimeClock/TimeClock.tsx | 2 +- packages/x-date-pickers/src/TimeField/TimeField.tsx | 4 ++-- packages/x-date-pickers/src/TimeField/TimeField.types.ts | 2 +- packages/x-date-pickers/src/TimePicker/TimePicker.tsx | 2 +- .../src/internals/hooks/useField/useField.types.ts | 2 +- packages/x-date-pickers/src/internals/models/props/clock.ts | 2 +- packages/x-tree-view/src/RichTreeView/RichTreeView.tsx | 4 ++-- .../plugins/useTreeViewItems/useTreeViewItems.types.ts | 4 ++-- 67 files changed, 92 insertions(+), 92 deletions(-) diff --git a/docs/pages/x/api/data-grid/data-grid-premium.json b/docs/pages/x/api/data-grid/data-grid-premium.json index 83f0ee5347236..56215024f0274 100644 --- a/docs/pages/x/api/data-grid/data-grid-premium.json +++ b/docs/pages/x/api/data-grid/data-grid-premium.json @@ -89,7 +89,7 @@ }, "getAggregationPosition": { "type": { "name": "func" }, - "default": "`(groupNode) => groupNode == null ? 'footer' : 'inline'`", + "default": "(groupNode) => groupNode == null ? 'footer' : 'inline'", "signature": { "type": "function(groupNode: GridGroupNode) => GridAggregationPosition | null", "describedArgs": ["groupNode"], diff --git a/docs/pages/x/api/data-grid/grid-aggregation-function.json b/docs/pages/x/api/data-grid/grid-aggregation-function.json index e4209cf783dd3..0f876a7766f6e 100644 --- a/docs/pages/x/api/data-grid/grid-aggregation-function.json +++ b/docs/pages/x/api/data-grid/grid-aggregation-function.json @@ -17,12 +17,12 @@ }, "hasCellUnit": { "type": { "description": "boolean" }, - "default": "`true`", + "default": "true", "isPremiumPlan": true }, "label": { "type": { "description": "string" }, - "default": "`apiRef.current.getLocaleText('aggregationFunctionLabel{capitalize(name)})`", + "default": "apiRef.current.getLocaleText('aggregationFunctionLabel{capitalize(name)})", "isPremiumPlan": true }, "valueFormatter": { diff --git a/docs/pages/x/api/data-grid/grid-csv-export-options.json b/docs/pages/x/api/data-grid/grid-csv-export-options.json index c8ec2874beb75..5d2236f5eb6f4 100644 --- a/docs/pages/x/api/data-grid/grid-csv-export-options.json +++ b/docs/pages/x/api/data-grid/grid-csv-export-options.json @@ -10,7 +10,7 @@ "allColumns": { "type": { "description": "boolean" }, "default": "false" }, "delimiter": { "type": { "description": "string" }, "default": "','" }, "fields": { "type": { "description": "string[]" } }, - "fileName": { "type": { "description": "string" }, "default": "`document.title`" }, + "fileName": { "type": { "description": "string" }, "default": "document.title" }, "getRowsToExport": { "type": { "description": "(params: GridCsvGetRowsToExportParams) => GridRowId[]" } }, diff --git a/docs/pages/x/api/data-grid/grid-excel-export-options.json b/docs/pages/x/api/data-grid/grid-excel-export-options.json index 8df7897c3fd4d..ed0fd0297e1d5 100644 --- a/docs/pages/x/api/data-grid/grid-excel-export-options.json +++ b/docs/pages/x/api/data-grid/grid-excel-export-options.json @@ -24,7 +24,7 @@ "fields": { "type": { "description": "string[]" }, "isPremiumPlan": true }, "fileName": { "type": { "description": "string" }, - "default": "`document.title`", + "default": "document.title", "isPremiumPlan": true }, "getRowsToExport": { diff --git a/docs/pages/x/api/data-grid/grid-filter-model.json b/docs/pages/x/api/data-grid/grid-filter-model.json index c67155f35a6b7..ac53f00f89792 100644 --- a/docs/pages/x/api/data-grid/grid-filter-model.json +++ b/docs/pages/x/api/data-grid/grid-filter-model.json @@ -10,13 +10,13 @@ "items": { "type": { "description": "GridFilterItem[]" }, "default": "[]", "required": true }, "logicOperator": { "type": { "description": "GridLogicOperator" }, - "default": "`GridLogicOperator.And`" + "default": "GridLogicOperator.And" }, "quickFilterExcludeHiddenColumns": { "type": { "description": "boolean" }, "default": "true" }, "quickFilterLogicOperator": { "type": { "description": "GridLogicOperator" }, - "default": "`GridLogicOperator.And`" + "default": "GridLogicOperator.And" }, - "quickFilterValues": { "type": { "description": "any[]" }, "default": "`[]`" } + "quickFilterValues": { "type": { "description": "any[]" }, "default": "[]" } } } diff --git a/docs/pages/x/api/date-pickers/date-field.json b/docs/pages/x/api/date-pickers/date-field.json index 61aff54380b49..00657063137c4 100644 --- a/docs/pages/x/api/date-pickers/date-field.json +++ b/docs/pages/x/api/date-pickers/date-field.json @@ -97,7 +97,7 @@ "returned": "boolean" } }, - "shouldRespectLeadingZeros": { "type": { "name": "bool" }, "default": "`false`" }, + "shouldRespectLeadingZeros": { "type": { "name": "bool" }, "default": "false" }, "size": { "type": { "name": "enum", "description": "'medium'
    | 'small'" } }, "slotProps": { "type": { "name": "object" }, "default": "{}" }, "slots": { diff --git a/docs/pages/x/api/date-pickers/date-time-field.json b/docs/pages/x/api/date-pickers/date-time-field.json index c7778236192ff..11e89eb31c848 100644 --- a/docs/pages/x/api/date-pickers/date-time-field.json +++ b/docs/pages/x/api/date-pickers/date-time-field.json @@ -1,6 +1,6 @@ { "props": { - "ampm": { "type": { "name": "bool" }, "default": "`utils.is12HourCycleInCurrentLocale()`" }, + "ampm": { "type": { "name": "bool" }, "default": "utils.is12HourCycleInCurrentLocale()" }, "autoFocus": { "type": { "name": "bool" }, "default": "false" }, "clearable": { "type": { "name": "bool" }, "default": "false" }, "color": { @@ -112,7 +112,7 @@ "returned": "boolean" } }, - "shouldRespectLeadingZeros": { "type": { "name": "bool" }, "default": "`false`" }, + "shouldRespectLeadingZeros": { "type": { "name": "bool" }, "default": "false" }, "size": { "type": { "name": "enum", "description": "'medium'
    | 'small'" } }, "slotProps": { "type": { "name": "object" }, "default": "{}" }, "slots": { diff --git a/docs/pages/x/api/date-pickers/date-time-picker.json b/docs/pages/x/api/date-pickers/date-time-picker.json index a95659e8955ee..34a2663633231 100644 --- a/docs/pages/x/api/date-pickers/date-time-picker.json +++ b/docs/pages/x/api/date-pickers/date-time-picker.json @@ -1,6 +1,6 @@ { "props": { - "ampm": { "type": { "name": "bool" }, "default": "`utils.is12HourCycleInCurrentLocale()`" }, + "ampm": { "type": { "name": "bool" }, "default": "utils.is12HourCycleInCurrentLocale()" }, "ampmInClock": { "type": { "name": "bool" }, "default": "true on desktop, false on mobile" }, "autoFocus": { "type": { "name": "bool" } }, "closeOnSelect": { diff --git a/docs/pages/x/api/date-pickers/date-time-range-picker.json b/docs/pages/x/api/date-pickers/date-time-range-picker.json index c176e8c1e00e9..c6c14a88228ad 100644 --- a/docs/pages/x/api/date-pickers/date-time-range-picker.json +++ b/docs/pages/x/api/date-pickers/date-time-range-picker.json @@ -1,6 +1,6 @@ { "props": { - "ampm": { "type": { "name": "bool" }, "default": "`utils.is12HourCycleInCurrentLocale()`" }, + "ampm": { "type": { "name": "bool" }, "default": "utils.is12HourCycleInCurrentLocale()" }, "autoFocus": { "type": { "name": "bool" } }, "calendars": { "type": { "name": "enum", "description": "1
    | 2
    | 3" }, diff --git a/docs/pages/x/api/date-pickers/desktop-date-time-picker.json b/docs/pages/x/api/date-pickers/desktop-date-time-picker.json index 85b246eb27e6c..ab048c18a4229 100644 --- a/docs/pages/x/api/date-pickers/desktop-date-time-picker.json +++ b/docs/pages/x/api/date-pickers/desktop-date-time-picker.json @@ -1,6 +1,6 @@ { "props": { - "ampm": { "type": { "name": "bool" }, "default": "`utils.is12HourCycleInCurrentLocale()`" }, + "ampm": { "type": { "name": "bool" }, "default": "utils.is12HourCycleInCurrentLocale()" }, "ampmInClock": { "type": { "name": "bool" }, "default": "true on desktop, false on mobile" }, "autoFocus": { "type": { "name": "bool" } }, "closeOnSelect": { diff --git a/docs/pages/x/api/date-pickers/desktop-date-time-range-picker.json b/docs/pages/x/api/date-pickers/desktop-date-time-range-picker.json index 3a3612e730a4a..c163702ae0b5b 100644 --- a/docs/pages/x/api/date-pickers/desktop-date-time-range-picker.json +++ b/docs/pages/x/api/date-pickers/desktop-date-time-range-picker.json @@ -1,6 +1,6 @@ { "props": { - "ampm": { "type": { "name": "bool" }, "default": "`utils.is12HourCycleInCurrentLocale()`" }, + "ampm": { "type": { "name": "bool" }, "default": "utils.is12HourCycleInCurrentLocale()" }, "autoFocus": { "type": { "name": "bool" } }, "calendars": { "type": { "name": "enum", "description": "1
    | 2
    | 3" }, diff --git a/docs/pages/x/api/date-pickers/desktop-time-picker.json b/docs/pages/x/api/date-pickers/desktop-time-picker.json index 3437b5b664ee0..a138a9baf6d61 100644 --- a/docs/pages/x/api/date-pickers/desktop-time-picker.json +++ b/docs/pages/x/api/date-pickers/desktop-time-picker.json @@ -1,6 +1,6 @@ { "props": { - "ampm": { "type": { "name": "bool" }, "default": "`utils.is12HourCycleInCurrentLocale()`" }, + "ampm": { "type": { "name": "bool" }, "default": "utils.is12HourCycleInCurrentLocale()" }, "ampmInClock": { "type": { "name": "bool" }, "default": "true on desktop, false on mobile" }, "autoFocus": { "type": { "name": "bool" } }, "closeOnSelect": { diff --git a/docs/pages/x/api/date-pickers/digital-clock.json b/docs/pages/x/api/date-pickers/digital-clock.json index ab41bb11244ee..00035a5cb3fa1 100644 --- a/docs/pages/x/api/date-pickers/digital-clock.json +++ b/docs/pages/x/api/date-pickers/digital-clock.json @@ -1,6 +1,6 @@ { "props": { - "ampm": { "type": { "name": "bool" }, "default": "`utils.is12HourCycleInCurrentLocale()`" }, + "ampm": { "type": { "name": "bool" }, "default": "utils.is12HourCycleInCurrentLocale()" }, "autoFocus": { "type": { "name": "bool" } }, "classes": { "type": { "name": "object" }, "additionalInfo": { "cssApi": true } }, "defaultValue": { "type": { "name": "object" } }, diff --git a/docs/pages/x/api/date-pickers/mobile-date-time-picker.json b/docs/pages/x/api/date-pickers/mobile-date-time-picker.json index 6e53b200352f1..f304519adf060 100644 --- a/docs/pages/x/api/date-pickers/mobile-date-time-picker.json +++ b/docs/pages/x/api/date-pickers/mobile-date-time-picker.json @@ -1,6 +1,6 @@ { "props": { - "ampm": { "type": { "name": "bool" }, "default": "`utils.is12HourCycleInCurrentLocale()`" }, + "ampm": { "type": { "name": "bool" }, "default": "utils.is12HourCycleInCurrentLocale()" }, "ampmInClock": { "type": { "name": "bool" }, "default": "true on desktop, false on mobile" }, "autoFocus": { "type": { "name": "bool" } }, "closeOnSelect": { diff --git a/docs/pages/x/api/date-pickers/mobile-date-time-range-picker.json b/docs/pages/x/api/date-pickers/mobile-date-time-range-picker.json index 3ec3f5b6d941d..ac9fd6985343f 100644 --- a/docs/pages/x/api/date-pickers/mobile-date-time-range-picker.json +++ b/docs/pages/x/api/date-pickers/mobile-date-time-range-picker.json @@ -1,6 +1,6 @@ { "props": { - "ampm": { "type": { "name": "bool" }, "default": "`utils.is12HourCycleInCurrentLocale()`" }, + "ampm": { "type": { "name": "bool" }, "default": "utils.is12HourCycleInCurrentLocale()" }, "autoFocus": { "type": { "name": "bool" } }, "closeOnSelect": { "type": { "name": "bool" }, diff --git a/docs/pages/x/api/date-pickers/mobile-time-picker.json b/docs/pages/x/api/date-pickers/mobile-time-picker.json index c1cc22aecfafd..6285dff74f334 100644 --- a/docs/pages/x/api/date-pickers/mobile-time-picker.json +++ b/docs/pages/x/api/date-pickers/mobile-time-picker.json @@ -1,6 +1,6 @@ { "props": { - "ampm": { "type": { "name": "bool" }, "default": "`utils.is12HourCycleInCurrentLocale()`" }, + "ampm": { "type": { "name": "bool" }, "default": "utils.is12HourCycleInCurrentLocale()" }, "ampmInClock": { "type": { "name": "bool" }, "default": "true on desktop, false on mobile" }, "autoFocus": { "type": { "name": "bool" } }, "closeOnSelect": { diff --git a/docs/pages/x/api/date-pickers/multi-input-date-range-field.json b/docs/pages/x/api/date-pickers/multi-input-date-range-field.json index 6ac27db9ea703..dc806e89a2fbc 100644 --- a/docs/pages/x/api/date-pickers/multi-input-date-range-field.json +++ b/docs/pages/x/api/date-pickers/multi-input-date-range-field.json @@ -62,7 +62,7 @@ "returned": "boolean" } }, - "shouldRespectLeadingZeros": { "type": { "name": "bool" }, "default": "`false`" }, + "shouldRespectLeadingZeros": { "type": { "name": "bool" }, "default": "false" }, "slotProps": { "type": { "name": "object" }, "default": "{}" }, "slots": { "type": { "name": "object" }, diff --git a/docs/pages/x/api/date-pickers/multi-input-date-time-range-field.json b/docs/pages/x/api/date-pickers/multi-input-date-time-range-field.json index 82462976a3f1f..aff38085ab820 100644 --- a/docs/pages/x/api/date-pickers/multi-input-date-time-range-field.json +++ b/docs/pages/x/api/date-pickers/multi-input-date-time-range-field.json @@ -1,6 +1,6 @@ { "props": { - "ampm": { "type": { "name": "bool" }, "default": "`utils.is12HourCycleInCurrentLocale()`" }, + "ampm": { "type": { "name": "bool" }, "default": "utils.is12HourCycleInCurrentLocale()" }, "autoFocus": { "type": { "name": "bool" } }, "classes": { "type": { "name": "object" }, "additionalInfo": { "cssApi": true } }, "dateSeparator": { "type": { "name": "string" }, "default": "\"–\"" }, @@ -77,7 +77,7 @@ "returned": "boolean" } }, - "shouldRespectLeadingZeros": { "type": { "name": "bool" }, "default": "`false`" }, + "shouldRespectLeadingZeros": { "type": { "name": "bool" }, "default": "false" }, "slotProps": { "type": { "name": "object" }, "default": "{}" }, "slots": { "type": { "name": "object" }, diff --git a/docs/pages/x/api/date-pickers/multi-input-time-range-field.json b/docs/pages/x/api/date-pickers/multi-input-time-range-field.json index 9119c6dcc2818..18f649b447086 100644 --- a/docs/pages/x/api/date-pickers/multi-input-time-range-field.json +++ b/docs/pages/x/api/date-pickers/multi-input-time-range-field.json @@ -1,6 +1,6 @@ { "props": { - "ampm": { "type": { "name": "bool" }, "default": "`utils.is12HourCycleInCurrentLocale()`" }, + "ampm": { "type": { "name": "bool" }, "default": "utils.is12HourCycleInCurrentLocale()" }, "autoFocus": { "type": { "name": "bool" } }, "classes": { "type": { "name": "object" }, "additionalInfo": { "cssApi": true } }, "dateSeparator": { "type": { "name": "string" }, "default": "\"–\"" }, @@ -65,7 +65,7 @@ "returned": "boolean" } }, - "shouldRespectLeadingZeros": { "type": { "name": "bool" }, "default": "`false`" }, + "shouldRespectLeadingZeros": { "type": { "name": "bool" }, "default": "false" }, "slotProps": { "type": { "name": "object" }, "default": "{}" }, "slots": { "type": { "name": "object" }, diff --git a/docs/pages/x/api/date-pickers/multi-section-digital-clock.json b/docs/pages/x/api/date-pickers/multi-section-digital-clock.json index 792a65ce1208b..e40d8718fb9fc 100644 --- a/docs/pages/x/api/date-pickers/multi-section-digital-clock.json +++ b/docs/pages/x/api/date-pickers/multi-section-digital-clock.json @@ -1,6 +1,6 @@ { "props": { - "ampm": { "type": { "name": "bool" }, "default": "`utils.is12HourCycleInCurrentLocale()`" }, + "ampm": { "type": { "name": "bool" }, "default": "utils.is12HourCycleInCurrentLocale()" }, "autoFocus": { "type": { "name": "bool" } }, "classes": { "type": { "name": "object" }, "additionalInfo": { "cssApi": true } }, "defaultValue": { "type": { "name": "object" } }, diff --git a/docs/pages/x/api/date-pickers/pickers-shortcuts.json b/docs/pages/x/api/date-pickers/pickers-shortcuts.json index 956f5970d01b4..dd402f9066e1c 100644 --- a/docs/pages/x/api/date-pickers/pickers-shortcuts.json +++ b/docs/pages/x/api/date-pickers/pickers-shortcuts.json @@ -11,7 +11,7 @@ "name": "arrayOf", "description": "Array<{ getValue: func, label: string }>" }, - "default": "`[]`" + "default": "[]" }, "subheader": { "type": { "name": "node" } }, "sx": { diff --git a/docs/pages/x/api/date-pickers/single-input-date-range-field.json b/docs/pages/x/api/date-pickers/single-input-date-range-field.json index 697d60d0ef899..72430d7a6cae8 100644 --- a/docs/pages/x/api/date-pickers/single-input-date-range-field.json +++ b/docs/pages/x/api/date-pickers/single-input-date-range-field.json @@ -82,7 +82,7 @@ "returned": "boolean" } }, - "shouldRespectLeadingZeros": { "type": { "name": "bool" }, "default": "`false`" }, + "shouldRespectLeadingZeros": { "type": { "name": "bool" }, "default": "false" }, "size": { "type": { "name": "enum", "description": "'medium'
    | 'small'" } }, "slotProps": { "type": { "name": "object" }, "default": "{}" }, "slots": { diff --git a/docs/pages/x/api/date-pickers/single-input-date-time-range-field.json b/docs/pages/x/api/date-pickers/single-input-date-time-range-field.json index 3fe2a80977788..fd040876b0a83 100644 --- a/docs/pages/x/api/date-pickers/single-input-date-time-range-field.json +++ b/docs/pages/x/api/date-pickers/single-input-date-time-range-field.json @@ -1,6 +1,6 @@ { "props": { - "ampm": { "type": { "name": "bool" }, "default": "`utils.is12HourCycleInCurrentLocale()`" }, + "ampm": { "type": { "name": "bool" }, "default": "utils.is12HourCycleInCurrentLocale()" }, "autoFocus": { "type": { "name": "bool" }, "default": "false" }, "clearable": { "type": { "name": "bool" }, "default": "false" }, "color": { @@ -97,7 +97,7 @@ "returned": "boolean" } }, - "shouldRespectLeadingZeros": { "type": { "name": "bool" }, "default": "`false`" }, + "shouldRespectLeadingZeros": { "type": { "name": "bool" }, "default": "false" }, "size": { "type": { "name": "enum", "description": "'medium'
    | 'small'" } }, "slotProps": { "type": { "name": "object" }, "default": "{}" }, "slots": { diff --git a/docs/pages/x/api/date-pickers/single-input-time-range-field.json b/docs/pages/x/api/date-pickers/single-input-time-range-field.json index d04206f9390c6..7a72192da87ac 100644 --- a/docs/pages/x/api/date-pickers/single-input-time-range-field.json +++ b/docs/pages/x/api/date-pickers/single-input-time-range-field.json @@ -1,6 +1,6 @@ { "props": { - "ampm": { "type": { "name": "bool" }, "default": "`utils.is12HourCycleInCurrentLocale()`" }, + "ampm": { "type": { "name": "bool" }, "default": "utils.is12HourCycleInCurrentLocale()" }, "autoFocus": { "type": { "name": "bool" }, "default": "false" }, "clearable": { "type": { "name": "bool" }, "default": "false" }, "color": { @@ -85,7 +85,7 @@ "returned": "boolean" } }, - "shouldRespectLeadingZeros": { "type": { "name": "bool" }, "default": "`false`" }, + "shouldRespectLeadingZeros": { "type": { "name": "bool" }, "default": "false" }, "size": { "type": { "name": "enum", "description": "'medium'
    | 'small'" } }, "slotProps": { "type": { "name": "object" }, "default": "{}" }, "slots": { diff --git a/docs/pages/x/api/date-pickers/static-date-time-picker.json b/docs/pages/x/api/date-pickers/static-date-time-picker.json index 1d05b51bb020a..49ea3c3c11650 100644 --- a/docs/pages/x/api/date-pickers/static-date-time-picker.json +++ b/docs/pages/x/api/date-pickers/static-date-time-picker.json @@ -1,6 +1,6 @@ { "props": { - "ampm": { "type": { "name": "bool" }, "default": "`utils.is12HourCycleInCurrentLocale()`" }, + "ampm": { "type": { "name": "bool" }, "default": "utils.is12HourCycleInCurrentLocale()" }, "ampmInClock": { "type": { "name": "bool" }, "default": "true on desktop, false on mobile" }, "autoFocus": { "type": { "name": "bool" } }, "dayOfWeekFormatter": { diff --git a/docs/pages/x/api/date-pickers/static-time-picker.json b/docs/pages/x/api/date-pickers/static-time-picker.json index 5cf72df9cbf49..0af386a2e7b7b 100644 --- a/docs/pages/x/api/date-pickers/static-time-picker.json +++ b/docs/pages/x/api/date-pickers/static-time-picker.json @@ -1,6 +1,6 @@ { "props": { - "ampm": { "type": { "name": "bool" }, "default": "`utils.is12HourCycleInCurrentLocale()`" }, + "ampm": { "type": { "name": "bool" }, "default": "utils.is12HourCycleInCurrentLocale()" }, "ampmInClock": { "type": { "name": "bool" }, "default": "true on desktop, false on mobile" }, "autoFocus": { "type": { "name": "bool" } }, "defaultValue": { "type": { "name": "object" } }, diff --git a/docs/pages/x/api/date-pickers/time-clock.json b/docs/pages/x/api/date-pickers/time-clock.json index f569a5c964f98..04615850d520b 100644 --- a/docs/pages/x/api/date-pickers/time-clock.json +++ b/docs/pages/x/api/date-pickers/time-clock.json @@ -1,6 +1,6 @@ { "props": { - "ampm": { "type": { "name": "bool" }, "default": "`utils.is12HourCycleInCurrentLocale()`" }, + "ampm": { "type": { "name": "bool" }, "default": "utils.is12HourCycleInCurrentLocale()" }, "ampmInClock": { "type": { "name": "bool" }, "default": "false" }, "autoFocus": { "type": { "name": "bool" } }, "classes": { "type": { "name": "object" }, "additionalInfo": { "cssApi": true } }, diff --git a/docs/pages/x/api/date-pickers/time-field.json b/docs/pages/x/api/date-pickers/time-field.json index 641529f95fd4f..db81673b337d5 100644 --- a/docs/pages/x/api/date-pickers/time-field.json +++ b/docs/pages/x/api/date-pickers/time-field.json @@ -1,6 +1,6 @@ { "props": { - "ampm": { "type": { "name": "bool" }, "default": "`utils.is12HourCycleInCurrentLocale()`" }, + "ampm": { "type": { "name": "bool" }, "default": "utils.is12HourCycleInCurrentLocale()" }, "autoFocus": { "type": { "name": "bool" }, "default": "false" }, "clearable": { "type": { "name": "bool" }, "default": "false" }, "color": { @@ -84,7 +84,7 @@ "returned": "boolean" } }, - "shouldRespectLeadingZeros": { "type": { "name": "bool" }, "default": "`false`" }, + "shouldRespectLeadingZeros": { "type": { "name": "bool" }, "default": "false" }, "size": { "type": { "name": "enum", "description": "'medium'
    | 'small'" } }, "slotProps": { "type": { "name": "object" }, "default": "{}" }, "slots": { diff --git a/docs/pages/x/api/date-pickers/time-picker.json b/docs/pages/x/api/date-pickers/time-picker.json index 1fd742141aa65..10cfe474c86f6 100644 --- a/docs/pages/x/api/date-pickers/time-picker.json +++ b/docs/pages/x/api/date-pickers/time-picker.json @@ -1,6 +1,6 @@ { "props": { - "ampm": { "type": { "name": "bool" }, "default": "`utils.is12HourCycleInCurrentLocale()`" }, + "ampm": { "type": { "name": "bool" }, "default": "utils.is12HourCycleInCurrentLocale()" }, "ampmInClock": { "type": { "name": "bool" }, "default": "true on desktop, false on mobile" }, "autoFocus": { "type": { "name": "bool" } }, "closeOnSelect": { diff --git a/docs/pages/x/api/tree-view/rich-tree-view.json b/docs/pages/x/api/tree-view/rich-tree-view.json index bb5084be29720..8ec57fbf2e91e 100644 --- a/docs/pages/x/api/tree-view/rich-tree-view.json +++ b/docs/pages/x/api/tree-view/rich-tree-view.json @@ -14,7 +14,7 @@ "expandedItems": { "type": { "name": "arrayOf", "description": "Array<string>" } }, "getItemId": { "type": { "name": "func" }, - "default": "`(item) => item.id`", + "default": "(item) => item.id", "signature": { "type": "function(item: R) => string", "describedArgs": ["item"], @@ -23,7 +23,7 @@ }, "getItemLabel": { "type": { "name": "func" }, - "default": "`(item) => item.label`", + "default": "(item) => item.label", "signature": { "type": "function(item: R) => string", "describedArgs": ["item"], diff --git a/packages/x-data-grid-premium/src/DataGridPremium/DataGridPremium.tsx b/packages/x-data-grid-premium/src/DataGridPremium/DataGridPremium.tsx index 3b808b7999c80..1f3caece0f9aa 100644 --- a/packages/x-data-grid-premium/src/DataGridPremium/DataGridPremium.tsx +++ b/packages/x-data-grid-premium/src/DataGridPremium/DataGridPremium.tsx @@ -357,7 +357,7 @@ DataGridPremiumRaw.propTypes = { * Determines the position of an aggregated value. * @param {GridGroupNode} groupNode The current group. * @returns {GridAggregationPosition | null} Position of the aggregated value (if `null`, the group isn't aggregated). - * @default `(groupNode) => groupNode == null ? 'footer' : 'inline'` + * @default (groupNode) => groupNode == null ? 'footer' : 'inline' */ getAggregationPosition: PropTypes.func, /** @@ -1011,7 +1011,7 @@ DataGridPremiumRaw.propTypes = { * The function is used to split the pasted text into rows and cells. * @param {string} text The text pasted from the clipboard. * @returns {string[][] | null} A 2D array of strings. The first dimension is the rows, the second dimension is the columns. - * @default `(pastedText) => { const text = pastedText.replace(/\r?\n$/, ''); return text.split(/\r\n|\n|\r/).map((row) => row.split('\t')); }` + * @default (pastedText) => { const text = pastedText.replace(/\r?\n$/, ''); return text.split(/\r\n|\n|\r/).map((row) => row.split('\t')); } */ splitClipboardPastedText: PropTypes.func, /** diff --git a/packages/x-data-grid-premium/src/hooks/features/aggregation/gridAggregationInterfaces.ts b/packages/x-data-grid-premium/src/hooks/features/aggregation/gridAggregationInterfaces.ts index 1abf73791fd6a..03be19423308c 100644 --- a/packages/x-data-grid-premium/src/hooks/features/aggregation/gridAggregationInterfaces.ts +++ b/packages/x-data-grid-premium/src/hooks/features/aggregation/gridAggregationInterfaces.ts @@ -50,7 +50,7 @@ export interface GridAggregationFunction { /** * Label of the aggregation function. * Will be used to add a label on the footer of the grouping column when this aggregation function is the only one being used. - * @default `apiRef.current.getLocaleText('aggregationFunctionLabel{capitalize(name)})` + * @default apiRef.current.getLocaleText('aggregationFunctionLabel{capitalize(name)}) */ label?: string; /** @@ -69,7 +69,7 @@ export interface GridAggregationFunction { /** * Indicates if the aggregated value have the same unit as the cells used to generate it. * It can be used to apply a custom cell renderer only if the aggregated value has the same unit. - * @default `true` + * @default true */ hasCellUnit?: boolean; /** diff --git a/packages/x-data-grid-premium/src/models/dataGridPremiumProps.ts b/packages/x-data-grid-premium/src/models/dataGridPremiumProps.ts index ebba8956e3239..329ce6cea0923 100644 --- a/packages/x-data-grid-premium/src/models/dataGridPremiumProps.ts +++ b/packages/x-data-grid-premium/src/models/dataGridPremiumProps.ts @@ -103,7 +103,7 @@ export interface DataGridPremiumPropsWithDefaultValue groupNode == null ? 'footer' : 'inline'` + * @default (groupNode) => groupNode == null ? 'footer' : 'inline' */ getAggregationPosition: (groupNode: GridGroupNode) => GridAggregationPosition | null; /** @@ -115,7 +115,7 @@ export interface DataGridPremiumPropsWithDefaultValue { const text = pastedText.replace(/\r?\n$/, ''); return text.split(/\r\n|\n|\r/).map((row) => row.split('\t')); }` + * @default (pastedText) => { const text = pastedText.replace(/\r?\n$/, ''); return text.split(/\r\n|\n|\r/).map((row) => row.split('\t')); } */ splitClipboardPastedText: (text: string) => string[][] | null; } diff --git a/packages/x-data-grid/src/models/gridExport.ts b/packages/x-data-grid/src/models/gridExport.ts index 1b0366be669a5..07aea49676c11 100644 --- a/packages/x-data-grid/src/models/gridExport.ts +++ b/packages/x-data-grid/src/models/gridExport.ts @@ -26,7 +26,7 @@ export interface GridFileExportOptions { /** * 12h/24h view for hour selection clock. - * @default `utils.is12HourCycleInCurrentLocale()` + * @default utils.is12HourCycleInCurrentLocale() */ ampm?: boolean; } diff --git a/packages/x-date-pickers-pro/src/internals/models/timeRange.ts b/packages/x-date-pickers-pro/src/internals/models/timeRange.ts index 2ef5443f3da3b..010182c831147 100644 --- a/packages/x-date-pickers-pro/src/internals/models/timeRange.ts +++ b/packages/x-date-pickers-pro/src/internals/models/timeRange.ts @@ -33,7 +33,7 @@ export interface UseTimeRangeFieldProps< BaseTimeValidationProps { /** * 12h/24h view for hour selection clock. - * @default `utils.is12HourCycleInCurrentLocale()` + * @default utils.is12HourCycleInCurrentLocale() */ ampm?: boolean; } diff --git a/packages/x-date-pickers/src/DateField/DateField.tsx b/packages/x-date-pickers/src/DateField/DateField.tsx index 131d6f5ed9874..9683b0cefba71 100644 --- a/packages/x-date-pickers/src/DateField/DateField.tsx +++ b/packages/x-date-pickers/src/DateField/DateField.tsx @@ -309,7 +309,7 @@ DateField.propTypes = { * Warning n°3: When used in strict mode, dayjs and moment require to respect the leading zeros. * This mean that when using `shouldRespectLeadingZeros={false}`, if you retrieve the value directly from the input (not listening to `onChange`) and your format contains tokens without leading zeros, the value will not be parsed by your library. * - * @default `false` + * @default false */ shouldRespectLeadingZeros: PropTypes.bool, /** diff --git a/packages/x-date-pickers/src/DateTimeField/DateTimeField.tsx b/packages/x-date-pickers/src/DateTimeField/DateTimeField.tsx index 7f9cf35580d1f..43e6a93586640 100644 --- a/packages/x-date-pickers/src/DateTimeField/DateTimeField.tsx +++ b/packages/x-date-pickers/src/DateTimeField/DateTimeField.tsx @@ -85,7 +85,7 @@ DateTimeField.propTypes = { // ---------------------------------------------------------------------- /** * 12h/24h view for hour selection clock. - * @default `utils.is12HourCycleInCurrentLocale()` + * @default utils.is12HourCycleInCurrentLocale() */ ampm: PropTypes.bool, /** @@ -350,7 +350,7 @@ DateTimeField.propTypes = { * Warning n°3: When used in strict mode, dayjs and moment require to respect the leading zeros. * This mean that when using `shouldRespectLeadingZeros={false}`, if you retrieve the value directly from the input (not listening to `onChange`) and your format contains tokens without leading zeros, the value will not be parsed by your library. * - * @default `false` + * @default false */ shouldRespectLeadingZeros: PropTypes.bool, /** diff --git a/packages/x-date-pickers/src/DateTimeField/DateTimeField.types.ts b/packages/x-date-pickers/src/DateTimeField/DateTimeField.types.ts index 771dc16d121bc..4f6301f55c08c 100644 --- a/packages/x-date-pickers/src/DateTimeField/DateTimeField.types.ts +++ b/packages/x-date-pickers/src/DateTimeField/DateTimeField.types.ts @@ -47,7 +47,7 @@ export interface UseDateTimeFieldProps< ExportedUseClearableFieldProps { /** * 12h/24h view for hour selection clock. - * @default `utils.is12HourCycleInCurrentLocale()` + * @default utils.is12HourCycleInCurrentLocale() */ ampm?: boolean; } diff --git a/packages/x-date-pickers/src/DateTimePicker/DateTimePicker.tsx b/packages/x-date-pickers/src/DateTimePicker/DateTimePicker.tsx index 67d50cb407428..43d1ca2b9dff6 100644 --- a/packages/x-date-pickers/src/DateTimePicker/DateTimePicker.tsx +++ b/packages/x-date-pickers/src/DateTimePicker/DateTimePicker.tsx @@ -55,7 +55,7 @@ DateTimePicker.propTypes = { // ---------------------------------------------------------------------- /** * 12h/24h view for hour selection clock. - * @default `utils.is12HourCycleInCurrentLocale()` + * @default utils.is12HourCycleInCurrentLocale() */ ampm: PropTypes.bool, /** diff --git a/packages/x-date-pickers/src/DesktopDateTimePicker/DesktopDateTimePicker.tsx b/packages/x-date-pickers/src/DesktopDateTimePicker/DesktopDateTimePicker.tsx index f20cf6d44c8f0..5b3c2977bab40 100644 --- a/packages/x-date-pickers/src/DesktopDateTimePicker/DesktopDateTimePicker.tsx +++ b/packages/x-date-pickers/src/DesktopDateTimePicker/DesktopDateTimePicker.tsx @@ -240,7 +240,7 @@ DesktopDateTimePicker.propTypes = { // ---------------------------------------------------------------------- /** * 12h/24h view for hour selection clock. - * @default `utils.is12HourCycleInCurrentLocale()` + * @default utils.is12HourCycleInCurrentLocale() */ ampm: PropTypes.bool, /** diff --git a/packages/x-date-pickers/src/DesktopTimePicker/DesktopTimePicker.tsx b/packages/x-date-pickers/src/DesktopTimePicker/DesktopTimePicker.tsx index 23ff47e661578..656455d8f9d47 100644 --- a/packages/x-date-pickers/src/DesktopTimePicker/DesktopTimePicker.tsx +++ b/packages/x-date-pickers/src/DesktopTimePicker/DesktopTimePicker.tsx @@ -143,7 +143,7 @@ DesktopTimePicker.propTypes = { // ---------------------------------------------------------------------- /** * 12h/24h view for hour selection clock. - * @default `utils.is12HourCycleInCurrentLocale()` + * @default utils.is12HourCycleInCurrentLocale() */ ampm: PropTypes.bool, /** diff --git a/packages/x-date-pickers/src/DigitalClock/DigitalClock.tsx b/packages/x-date-pickers/src/DigitalClock/DigitalClock.tsx index 19b45e4c99a2e..482ec398ac38b 100644 --- a/packages/x-date-pickers/src/DigitalClock/DigitalClock.tsx +++ b/packages/x-date-pickers/src/DigitalClock/DigitalClock.tsx @@ -343,7 +343,7 @@ DigitalClock.propTypes = { // ---------------------------------------------------------------------- /** * 12h/24h view for hour selection clock. - * @default `utils.is12HourCycleInCurrentLocale()` + * @default utils.is12HourCycleInCurrentLocale() */ ampm: PropTypes.bool, /** diff --git a/packages/x-date-pickers/src/MobileDateTimePicker/MobileDateTimePicker.tsx b/packages/x-date-pickers/src/MobileDateTimePicker/MobileDateTimePicker.tsx index 204b2218b393b..0f88dd08f014d 100644 --- a/packages/x-date-pickers/src/MobileDateTimePicker/MobileDateTimePicker.tsx +++ b/packages/x-date-pickers/src/MobileDateTimePicker/MobileDateTimePicker.tsx @@ -117,7 +117,7 @@ MobileDateTimePicker.propTypes = { // ---------------------------------------------------------------------- /** * 12h/24h view for hour selection clock. - * @default `utils.is12HourCycleInCurrentLocale()` + * @default utils.is12HourCycleInCurrentLocale() */ ampm: PropTypes.bool, /** diff --git a/packages/x-date-pickers/src/MobileTimePicker/MobileTimePicker.tsx b/packages/x-date-pickers/src/MobileTimePicker/MobileTimePicker.tsx index 3483b970f4054..c27094adc47c3 100644 --- a/packages/x-date-pickers/src/MobileTimePicker/MobileTimePicker.tsx +++ b/packages/x-date-pickers/src/MobileTimePicker/MobileTimePicker.tsx @@ -106,7 +106,7 @@ MobileTimePicker.propTypes = { // ---------------------------------------------------------------------- /** * 12h/24h view for hour selection clock. - * @default `utils.is12HourCycleInCurrentLocale()` + * @default utils.is12HourCycleInCurrentLocale() */ ampm: PropTypes.bool, /** diff --git a/packages/x-date-pickers/src/MultiSectionDigitalClock/MultiSectionDigitalClock.tsx b/packages/x-date-pickers/src/MultiSectionDigitalClock/MultiSectionDigitalClock.tsx index 5c309e3f02e48..aed9518b528f9 100644 --- a/packages/x-date-pickers/src/MultiSectionDigitalClock/MultiSectionDigitalClock.tsx +++ b/packages/x-date-pickers/src/MultiSectionDigitalClock/MultiSectionDigitalClock.tsx @@ -435,7 +435,7 @@ MultiSectionDigitalClock.propTypes = { // ---------------------------------------------------------------------- /** * 12h/24h view for hour selection clock. - * @default `utils.is12HourCycleInCurrentLocale()` + * @default utils.is12HourCycleInCurrentLocale() */ ampm: PropTypes.bool, /** diff --git a/packages/x-date-pickers/src/PickersShortcuts/PickersShortcuts.tsx b/packages/x-date-pickers/src/PickersShortcuts/PickersShortcuts.tsx index 2c43c8c8ed72f..85d88255963bb 100644 --- a/packages/x-date-pickers/src/PickersShortcuts/PickersShortcuts.tsx +++ b/packages/x-date-pickers/src/PickersShortcuts/PickersShortcuts.tsx @@ -22,7 +22,7 @@ export interface ExportedPickersShortcutProps extends Omit[]; /** @@ -127,7 +127,7 @@ PickersShortcuts.propTypes = { /** * Ordered array of shortcuts to display. * If empty, does not display the shortcuts. - * @default `[]` + * @default [] */ items: PropTypes.arrayOf( PropTypes.shape({ diff --git a/packages/x-date-pickers/src/StaticDateTimePicker/StaticDateTimePicker.tsx b/packages/x-date-pickers/src/StaticDateTimePicker/StaticDateTimePicker.tsx index ef875b3b8bec1..48133682a595f 100644 --- a/packages/x-date-pickers/src/StaticDateTimePicker/StaticDateTimePicker.tsx +++ b/packages/x-date-pickers/src/StaticDateTimePicker/StaticDateTimePicker.tsx @@ -87,7 +87,7 @@ StaticDateTimePicker.propTypes = { // ---------------------------------------------------------------------- /** * 12h/24h view for hour selection clock. - * @default `utils.is12HourCycleInCurrentLocale()` + * @default utils.is12HourCycleInCurrentLocale() */ ampm: PropTypes.bool, /** diff --git a/packages/x-date-pickers/src/StaticTimePicker/StaticTimePicker.tsx b/packages/x-date-pickers/src/StaticTimePicker/StaticTimePicker.tsx index a8084a3eba7b0..d68b76d9029f9 100644 --- a/packages/x-date-pickers/src/StaticTimePicker/StaticTimePicker.tsx +++ b/packages/x-date-pickers/src/StaticTimePicker/StaticTimePicker.tsx @@ -76,7 +76,7 @@ StaticTimePicker.propTypes = { // ---------------------------------------------------------------------- /** * 12h/24h view for hour selection clock. - * @default `utils.is12HourCycleInCurrentLocale()` + * @default utils.is12HourCycleInCurrentLocale() */ ampm: PropTypes.bool, /** diff --git a/packages/x-date-pickers/src/TimeClock/TimeClock.tsx b/packages/x-date-pickers/src/TimeClock/TimeClock.tsx index 2e2e4186fe2da..d184ffd59879f 100644 --- a/packages/x-date-pickers/src/TimeClock/TimeClock.tsx +++ b/packages/x-date-pickers/src/TimeClock/TimeClock.tsx @@ -393,7 +393,7 @@ TimeClock.propTypes = { // ---------------------------------------------------------------------- /** * 12h/24h view for hour selection clock. - * @default `utils.is12HourCycleInCurrentLocale()` + * @default utils.is12HourCycleInCurrentLocale() */ ampm: PropTypes.bool, /** diff --git a/packages/x-date-pickers/src/TimeField/TimeField.tsx b/packages/x-date-pickers/src/TimeField/TimeField.tsx index a5040b544960d..36d86491800fb 100644 --- a/packages/x-date-pickers/src/TimeField/TimeField.tsx +++ b/packages/x-date-pickers/src/TimeField/TimeField.tsx @@ -85,7 +85,7 @@ TimeField.propTypes = { // ---------------------------------------------------------------------- /** * 12h/24h view for hour selection clock. - * @default `utils.is12HourCycleInCurrentLocale()` + * @default utils.is12HourCycleInCurrentLocale() */ ampm: PropTypes.bool, /** @@ -310,7 +310,7 @@ TimeField.propTypes = { * Warning n°3: When used in strict mode, dayjs and moment require to respect the leading zeros. * This mean that when using `shouldRespectLeadingZeros={false}`, if you retrieve the value directly from the input (not listening to `onChange`) and your format contains tokens without leading zeros, the value will not be parsed by your library. * - * @default `false` + * @default false */ shouldRespectLeadingZeros: PropTypes.bool, /** diff --git a/packages/x-date-pickers/src/TimeField/TimeField.types.ts b/packages/x-date-pickers/src/TimeField/TimeField.types.ts index 28addb35bdb52..0633093cf7f5a 100644 --- a/packages/x-date-pickers/src/TimeField/TimeField.types.ts +++ b/packages/x-date-pickers/src/TimeField/TimeField.types.ts @@ -34,7 +34,7 @@ export interface UseTimeFieldProps< ExportedUseClearableFieldProps { /** * 12h/24h view for hour selection clock. - * @default `utils.is12HourCycleInCurrentLocale()` + * @default utils.is12HourCycleInCurrentLocale() */ ampm?: boolean; } diff --git a/packages/x-date-pickers/src/TimePicker/TimePicker.tsx b/packages/x-date-pickers/src/TimePicker/TimePicker.tsx index 6ffd875c38f9c..9d734dd9ef2c5 100644 --- a/packages/x-date-pickers/src/TimePicker/TimePicker.tsx +++ b/packages/x-date-pickers/src/TimePicker/TimePicker.tsx @@ -55,7 +55,7 @@ TimePicker.propTypes = { // ---------------------------------------------------------------------- /** * 12h/24h view for hour selection clock. - * @default `utils.is12HourCycleInCurrentLocale()` + * @default utils.is12HourCycleInCurrentLocale() */ ampm: PropTypes.bool, /** diff --git a/packages/x-date-pickers/src/internals/hooks/useField/useField.types.ts b/packages/x-date-pickers/src/internals/hooks/useField/useField.types.ts index d60d89b6efc0d..3b05171787ce3 100644 --- a/packages/x-date-pickers/src/internals/hooks/useField/useField.types.ts +++ b/packages/x-date-pickers/src/internals/hooks/useField/useField.types.ts @@ -106,7 +106,7 @@ export interface UseFieldInternalProps< * Warning n°3: When used in strict mode, dayjs and moment require to respect the leading zeros. * This mean that when using `shouldRespectLeadingZeros={false}`, if you retrieve the value directly from the input (not listening to `onChange`) and your format contains tokens without leading zeros, the value will not be parsed by your library. * - * @default `false` + * @default false */ shouldRespectLeadingZeros?: boolean; /** diff --git a/packages/x-date-pickers/src/internals/models/props/clock.ts b/packages/x-date-pickers/src/internals/models/props/clock.ts index ff5fa599f6cdb..41ac81136ae4d 100644 --- a/packages/x-date-pickers/src/internals/models/props/clock.ts +++ b/packages/x-date-pickers/src/internals/models/props/clock.ts @@ -12,7 +12,7 @@ export interface ExportedBaseClockProps TimezoneProps { /** * 12h/24h view for hour selection clock. - * @default `utils.is12HourCycleInCurrentLocale()` + * @default utils.is12HourCycleInCurrentLocale() */ ampm?: boolean; } diff --git a/packages/x-tree-view/src/RichTreeView/RichTreeView.tsx b/packages/x-tree-view/src/RichTreeView/RichTreeView.tsx index 5983e1697daff..b2f700eb14ab2 100644 --- a/packages/x-tree-view/src/RichTreeView/RichTreeView.tsx +++ b/packages/x-tree-view/src/RichTreeView/RichTreeView.tsx @@ -193,7 +193,7 @@ RichTreeView.propTypes = { * @template R * @param {R} item The item to check. * @returns {string} The id of the item. - * @default `(item) => item.id` + * @default (item) => item.id */ getItemId: PropTypes.func, /** @@ -202,7 +202,7 @@ RichTreeView.propTypes = { * @template R * @param {R} item The item to check. * @returns {string} The label of the item. - * @default `(item) => item.label` + * @default (item) => item.label */ getItemLabel: PropTypes.func, /** diff --git a/packages/x-tree-view/src/internals/plugins/useTreeViewItems/useTreeViewItems.types.ts b/packages/x-tree-view/src/internals/plugins/useTreeViewItems/useTreeViewItems.types.ts index 5b20682d1a9b7..465f6bbbd0707 100644 --- a/packages/x-tree-view/src/internals/plugins/useTreeViewItems/useTreeViewItems.types.ts +++ b/packages/x-tree-view/src/internals/plugins/useTreeViewItems/useTreeViewItems.types.ts @@ -51,7 +51,7 @@ export interface UseTreeViewItemsParameters { * @template R * @param {R} item The item to check. * @returns {string} The label of the item. - * @default `(item) => item.label` + * @default (item) => item.label */ getItemLabel?: (item: R) => string; /** @@ -60,7 +60,7 @@ export interface UseTreeViewItemsParameters { * @template R * @param {R} item The item to check. * @returns {string} The id of the item. - * @default `(item) => item.id` + * @default (item) => item.id */ getItemId?: (item: R) => TreeViewItemId; } From 9bb62f3d56b402f1028014af46e59dd3286a5307 Mon Sep 17 00:00:00 2001 From: amirhosseinzf <99012444+amirhosseinzf@users.noreply.github.com> Date: Wed, 3 Apr 2024 13:20:57 +0330 Subject: [PATCH 53/55] [l10n] Improve Persian (fa-IR) locale (#12630) Signed-off-by: amirhosseinzf <99012444+amirhosseinzf@users.noreply.github.com> Co-authored-by: alexandre --- docs/data/data-grid/localization/data.json | 2 +- packages/x-data-grid/src/locales/faIR.ts | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/data/data-grid/localization/data.json b/docs/data/data-grid/localization/data.json index 3ee05aff82c5c..482b226e0651d 100644 --- a/docs/data/data-grid/localization/data.json +++ b/docs/data/data-grid/localization/data.json @@ -163,7 +163,7 @@ "languageTag": "fa-IR", "importName": "faIR", "localeName": "Persian", - "missingKeysCount": 3, + "missingKeysCount": 0, "totalKeysCount": 117, "githubLink": "https://github.com/mui/mui-x/blob/master/packages/x-data-grid/src/locales/faIR.ts" }, diff --git a/packages/x-data-grid/src/locales/faIR.ts b/packages/x-data-grid/src/locales/faIR.ts index cf5c2e72ff4c4..0f1b6e15f6d31 100644 --- a/packages/x-data-grid/src/locales/faIR.ts +++ b/packages/x-data-grid/src/locales/faIR.ts @@ -39,9 +39,9 @@ const faIRGrid: Partial = { toolbarExportExcel: 'دانلود به صورت اکسل', // Columns management text - // columnsManagementSearchTitle: 'Search', - // columnsManagementNoColumns: 'No columns', - // columnsManagementShowHideAllText: 'Show/Hide All', + columnsManagementSearchTitle: 'جستجو', + columnsManagementNoColumns: 'بدون سطر', + columnsManagementShowHideAllText: 'نمایش/مخفی کردن همه', // Filter panel text filterPanelAddFilter: 'افزودن فیلتر', From a5d834636de66890c600c2c9d5d67a0b35b9b831 Mon Sep 17 00:00:00 2001 From: hugoalkimim Date: Wed, 3 Apr 2024 06:51:26 -0300 Subject: [PATCH 54/55] [l10n] Improve Portuguese (pt-BR) locale (#12618) Signed-off-by: hugoalkimim Co-authored-by: Bilal Shafi --- docs/data/data-grid/localization/data.json | 2 +- packages/x-data-grid/src/locales/ptBR.ts | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/data/data-grid/localization/data.json b/docs/data/data-grid/localization/data.json index 482b226e0651d..5e95d5bb5290e 100644 --- a/docs/data/data-grid/localization/data.json +++ b/docs/data/data-grid/localization/data.json @@ -187,7 +187,7 @@ "languageTag": "pt-BR", "importName": "ptBR", "localeName": "Portuguese (Brazil)", - "missingKeysCount": 3, + "missingKeysCount": 0, "totalKeysCount": 117, "githubLink": "https://github.com/mui/mui-x/blob/master/packages/x-data-grid/src/locales/ptBR.ts" }, diff --git a/packages/x-data-grid/src/locales/ptBR.ts b/packages/x-data-grid/src/locales/ptBR.ts index 5a50fefb19161..1a6e603141d87 100644 --- a/packages/x-data-grid/src/locales/ptBR.ts +++ b/packages/x-data-grid/src/locales/ptBR.ts @@ -39,9 +39,9 @@ const ptBRGrid: Partial = { toolbarExportExcel: 'Baixar como Excel', // Columns management text - // columnsManagementSearchTitle: 'Search', - // columnsManagementNoColumns: 'No columns', - // columnsManagementShowHideAllText: 'Show/Hide All', + columnsManagementSearchTitle: 'Buscar', + columnsManagementNoColumns: 'Nenhuma coluna', + columnsManagementShowHideAllText: 'Mostrar/Ocultar Todas', // Filter panel text filterPanelAddFilter: 'Adicionar filtro', From e12acf2bf65e0627b52ebed4cc0af8df06285f1a Mon Sep 17 00:00:00 2001 From: Flavien DELANGLE Date: Wed, 3 Apr 2024 13:46:00 +0200 Subject: [PATCH 55/55] [docs] Use `TreeItem2` for icon expansion example on `RichTreeView` (#12563) --- .../customization/IconExpansionTreeView.js | 77 +++++----------- .../customization/IconExpansionTreeView.tsx | 87 +++++-------------- .../IconExpansionTreeView.tsx.preview | 2 +- 3 files changed, 46 insertions(+), 120 deletions(-) diff --git a/docs/data/tree-view/rich-tree-view/customization/IconExpansionTreeView.js b/docs/data/tree-view/rich-tree-view/customization/IconExpansionTreeView.js index 4c28c6cd280b0..fd33b99985c1a 100644 --- a/docs/data/tree-view/rich-tree-view/customization/IconExpansionTreeView.js +++ b/docs/data/tree-view/rich-tree-view/customization/IconExpansionTreeView.js @@ -1,9 +1,9 @@ import * as React from 'react'; -import clsx from 'clsx'; -import Typography from '@mui/material/Typography'; import Box from '@mui/material/Box'; import { RichTreeView } from '@mui/x-tree-view/RichTreeView'; -import { useTreeItemState } from '@mui/x-tree-view/TreeItem'; +import { useTreeItem2Utils } from '@mui/x-tree-view/hooks/useTreeItem2Utils'; + +import { TreeItem2 } from '@mui/x-tree-view/TreeItem2'; const ITEMS = [ { @@ -25,65 +25,30 @@ const ITEMS = [ }, ]; -const CustomContent = React.forwardRef(function CustomContent(props, ref) { - const { - classes, - className, - label, - itemId, - icon: iconProp, - expansionIcon, - displayIcon, - } = props; - - const { - disabled, - expanded, - selected, - focused, - handleExpansion, - handleSelection, - preventSelection, - } = useTreeItemState(itemId); - - const icon = iconProp || expansionIcon || displayIcon; - - const handleMouseDown = (event) => { - preventSelection(event); - }; +const CustomTreeItem = React.forwardRef(function MyTreeItem(props, ref) { + const { interactions } = useTreeItem2Utils({ + itemId: props.itemId, + children: props.children, + }); - const handleExpansionClick = (event) => { - handleExpansion(event); + const handleContentClick = (event) => { + event.defaultMuiPrevented = true; + interactions.handleSelection(event); }; - const handleSelectionClick = (event) => { - handleSelection(event); + const handleIconContainerClick = (event) => { + interactions.handleExpansion(event); }; return ( - // eslint-disable-next-line jsx-a11y/no-static-element-interactions -

    - {/* eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions */} -
    - {icon} -
    - - {label} - -
    + slotProps={{ + content: { onClick: handleContentClick }, + iconContainer: { onClick: handleIconContainerClick }, + }} + /> ); }); @@ -93,7 +58,7 @@ export default function IconExpansionTreeView() { ); diff --git a/docs/data/tree-view/rich-tree-view/customization/IconExpansionTreeView.tsx b/docs/data/tree-view/rich-tree-view/customization/IconExpansionTreeView.tsx index 2847daf70967a..9564b8d24b23f 100644 --- a/docs/data/tree-view/rich-tree-view/customization/IconExpansionTreeView.tsx +++ b/docs/data/tree-view/rich-tree-view/customization/IconExpansionTreeView.tsx @@ -1,9 +1,9 @@ import * as React from 'react'; -import clsx from 'clsx'; -import Typography from '@mui/material/Typography'; import Box from '@mui/material/Box'; import { RichTreeView } from '@mui/x-tree-view/RichTreeView'; -import { useTreeItemState, TreeItemContentProps } from '@mui/x-tree-view/TreeItem'; +import { useTreeItem2Utils } from '@mui/x-tree-view/hooks/useTreeItem2Utils'; +import { UseTreeItem2ContentSlotOwnProps } from '@mui/x-tree-view/useTreeItem2'; +import { TreeItem2, TreeItem2Props } from '@mui/x-tree-view/TreeItem2'; import { TreeViewBaseItem } from '@mui/x-tree-view/models'; const ITEMS: TreeViewBaseItem[] = [ @@ -26,72 +26,33 @@ const ITEMS: TreeViewBaseItem[] = [ }, ]; -const CustomContent = React.forwardRef(function CustomContent( - props: TreeItemContentProps, - ref, +const CustomTreeItem = React.forwardRef(function MyTreeItem( + props: TreeItem2Props, + ref: React.Ref, ) { - const { - classes, - className, - label, - itemId, - icon: iconProp, - expansionIcon, - displayIcon, - } = props; + const { interactions } = useTreeItem2Utils({ + itemId: props.itemId, + children: props.children, + }); - const { - disabled, - expanded, - selected, - focused, - handleExpansion, - handleSelection, - preventSelection, - } = useTreeItemState(itemId); - - const icon = iconProp || expansionIcon || displayIcon; - - const handleMouseDown = (event: React.MouseEvent) => { - preventSelection(event); - }; - - const handleExpansionClick = ( - event: React.MouseEvent, - ) => { - handleExpansion(event); + const handleContentClick: UseTreeItem2ContentSlotOwnProps['onClick'] = (event) => { + event.defaultMuiPrevented = true; + interactions.handleSelection(event); }; - const handleSelectionClick = ( - event: React.MouseEvent, - ) => { - handleSelection(event); + const handleIconContainerClick = (event: React.MouseEvent) => { + interactions.handleExpansion(event); }; return ( - // eslint-disable-next-line jsx-a11y/no-static-element-interactions -
    } - > - {/* eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions */} -
    - {icon} -
    - - {label} - -
    + ); }); @@ -101,7 +62,7 @@ export default function IconExpansionTreeView() { ); diff --git a/docs/data/tree-view/rich-tree-view/customization/IconExpansionTreeView.tsx.preview b/docs/data/tree-view/rich-tree-view/customization/IconExpansionTreeView.tsx.preview index 9a621283b2c07..ea2163196d7a6 100644 --- a/docs/data/tree-view/rich-tree-view/customization/IconExpansionTreeView.tsx.preview +++ b/docs/data/tree-view/rich-tree-view/customization/IconExpansionTreeView.tsx.preview @@ -1,5 +1,5 @@ \ No newline at end of file