diff --git a/.github/workflows/cherry-pick-next-to-master.yml b/.github/workflows/cherry-pick-next-to-master.yml new file mode 100644 index 000000000000..da951ace5606 --- /dev/null +++ b/.github/workflows/cherry-pick-next-to-master.yml @@ -0,0 +1,29 @@ +on: + pull_request: + branches: + - next + types: ['closed'] + +jobs: + cherry_pick_to_master: + runs-on: ubuntu-latest + name: Cherry pick into master + permissions: + pull-requests: write + contents: write + if: ${{ contains(github.event.pull_request.labels.*.name, 'needs cherry-pick') && github.event.pull_request.merged == true }} + steps: + - name: Checkout + uses: actions/checkout@v2 + with: + fetch-depth: 0 + - name: Cherry pick and create the new PR + uses: carloscastrojumo/github-cherry-pick-action@v1.0.9 + with: + branch: master + token: ${{ secrets.GITHUB_TOKEN }} + body: 'Cherry-pick of #{old_pull_request_id}' + labels: | + cherry-pick +env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 6a406fb413bc..dec81885392e 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -19,7 +19,7 @@ jobs: uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@407ffafae6a767df3e0230c3df91b6443ae8df75 # v2.22.8 + uses: github/codeql-action/init@c0d1daa7f7e14667747d73a7dbbe8c074bc8bfe2 # v2.22.9 with: languages: typescript # If you wish to specify custom queries, you can do so here or in a config file. @@ -29,4 +29,4 @@ jobs: # Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs # queries: security-extended,security-and-quality - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@407ffafae6a767df3e0230c3df91b6443ae8df75 # v2.22.8 + uses: github/codeql-action/analyze@c0d1daa7f7e14667747d73a7dbbe8c074bc8bfe2 # v2.22.9 diff --git a/.github/workflows/no-response.yml b/.github/workflows/no-response.yml index 3664edfcc0f8..aabc9edc6f07 100644 --- a/.github/workflows/no-response.yml +++ b/.github/workflows/no-response.yml @@ -1,8 +1,10 @@ name: No Response -# Both `issue_comment` and `scheduled` event types are required for this Action +# `issues`.`closed`, `issue_comment`.`created`, and `scheduled` event types are required for this Action # to work properly. on: + issues: + types: [closed] issue_comment: types: [created] schedule: @@ -18,7 +20,7 @@ jobs: contents: read issues: write steps: - - uses: MBilalShafi/no-response-add-label@6291e5d1a4eaffe530b2ec434991f258641a8599 + - uses: MBilalShafi/no-response-add-label@629add01d7b6f8e120811f978c42703736098947 with: token: ${{ secrets.GITHUB_TOKEN }} # Number of days of inactivity before an Issue is closed for lack of response diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml index 0d232eeb27ab..5d385d300ee4 100644 --- a/.github/workflows/scorecards.yml +++ b/.github/workflows/scorecards.yml @@ -44,6 +44,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: Upload to code-scanning - uses: github/codeql-action/upload-sarif@407ffafae6a767df3e0230c3df91b6443ae8df75 # v2.22.8 + uses: github/codeql-action/upload-sarif@c0d1daa7f7e14667747d73a7dbbe8c074bc8bfe2 # v2.22.9 with: sarif_file: results.sarif diff --git a/CHANGELOG.md b/CHANGELOG.md index e0d427541a15..0ad2c8ced567 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,167 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## 7.0.0-alpha.5 + +_Dec 14, 2023_ + +We'd like to offer a big thanks to the 9 contributors who made this release possible. Here are some highlights ✨: + +- 💫 New recipe added for the Data Grid +- 🌍 Improve Swedish (sv-SE) and Urdu (ur-PK) locales on the Data Grid +- 🐞 Bugfixes + +### Data Grid + +#### Breaking changes + +- The `instanceId` prop is now required for state selectors. + This prop is used to distinguish between multiple Data Grid instances on the same page. + See [migration docs](https://next.mui.com/x/migration/migration-data-grid-v6/#instanceid-prop-is-required-for-state-selectors) for more details. + +#### `@mui/x-data-grid@7.0.0-alpha.5` + +- [DataGrid] Make `instanceId` required for state selectors (#11395) @cherniavskii +- [DataGrid] Recipe for grouped rows autosizing (#11401) @michelengelen +- [l10n] Improve Swedish (sv-SE) locale (#11373) @fredrikcarlbom +- [l10n] Improve Urdu (ur-PK) locale (#11400) @MBilalShafi + +#### `@mui/x-data-grid-pro@7.0.0-alpha.5` [![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-alpha.5`. + +#### `@mui/x-data-grid-premium@7.0.0-alpha.5` [![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-alpha.5`. + +### Date Pickers + +#### Breaking changes + +- The slot interfaces got renamed to match with `@mui/base` naming. +The `SlotsComponent` suffix has been replaced with `Slots` and `SlotsComponentsProps` with `SlotProps`. + + ```diff + - DateCalendarSlotsComponent + + DateCalendarSlots + - DateCalendarSlotsComponentsProps + + DateCalendarSlotProps + ``` + +- Move `inputRef` inside the props passed to the field hooks + + 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); + ``` + + If you are using a multi input range field hook, the same applies to `startInputRef` and `endInputRef` params + + ```diff + - const { inputRef: startInputRef, ...otherStartTextFieldProps } = startTextFieldProps + - const { inputRef: endInputRef, ...otherEndTextFieldProps } = endTextFieldProps + + const fieldResponse = useMultiInputDateRangeField({ + sharedProps, + - startTextFieldProps: otherStartTextFieldProps, + - endTextFieldProps: otherEndTextFieldProps, + - startInputRef + - endInputRef, + + startTextFieldProps, + + endTextFieldProps + }); + ``` + +- Rename the ref returned by the field hooks to `inputRef` + + When used with the v6 TextField approach (where the input is an `` HTML element), the field hooks return a ref that needs to be passed to the `` element. + This ref was previously named `ref` and has been renamed `inputRef` for extra clarity. + + ```diff + const fieldResponse = useDateField(props); + + - return + + return + ``` + + If you are using a multi input range field hook, the same applies to the ref in the `startDate` and `endDate` objects + + ```diff + const fieldResponse = useDateField(props); + + return ( +
+ - + + + + - + + +
+ ) + ``` + +- Restructure the API of `useClearableField` + + The `useClearableField` hook API has been simplified to now take a `props` parameter instead of a `fieldProps`, `InputProps`, `clearable`, `onClear`, `slots` and `slotProps` parameters. + + You should now be able to directly pass the returned value from your field hook (e.g: `useDateField`) to `useClearableField` + + ```diff + const fieldResponse = useDateField(props); + + - const { InputProps, onClear, clearable, slots, slotProps, ...otherFieldProps } = fieldResponse + - const { InputProps: ProcessedInputProps, fieldProps: processedFieldProps } = useClearableField({ + - fieldProps: otherFieldProps, + - InputProps, + - clearable, + - onClear, + - slots, + - slotProps, + - }); + - + - return + + + const processedFieldProps = useClearableField(fieldResponse); + + + + return + ``` + +#### `@mui/x-date-pickers@7.0.0-alpha.5` + +- [fields] Support empty sections (#10307) @flaviendelangle +- [pickers] Fix field types to avoid error on latest `@types/react` version (#11397) @LukasTy +- [pickers] Remove all relative imports to the internals index file (#11375) @flaviendelangle +- [pickers] Rename slots interfaces (#11339) @alexfauquette +- [pickers] Simplify the API of the field hooks (#11371) @flaviendelangle +- [pickers] Support name prop (#11025) @gitstart + +#### `@mui/x-date-pickers-pro@7.0.0-alpha.5` [![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-alpha.5`, plus: + +- [DateRangePicker] Fix `autoFocus` behavior (#11273) @kealjones-wk + +### Charts / `@mui/x-charts@7.0.0-alpha.5` + +- [charts] Fix size overflow (#11385) @alexfauquette + +### `@mui/x-codemod@7.0.0-alpha.5` + +- [codemod] Add `cellSelection` codemod and update migration guide (#11353) @MBilalShafi + +### Docs + +- [docs] Respect GoT books (@janoma) (#11387) @alexfauquette + +### Core + +- [core] Automate cherry-pick of PRs from `next` -> `master` (#11382) @MBilalShafi +- [github] Update `no-response` workflow (#11369) @MBilalShafi +- [test] Fix flaky screenshots (#11388) @cherniavskii + ## 7.0.0-alpha.4 _Dec 8, 2023_ @@ -949,6 +1110,48 @@ Here is an example of the renaming for the `` component. - [core] Update release instructions as per v7 configuration (#10962) @MBilalShafi - [license] Correctly throw errors (#10924) @oliviertassinari +## 6.18.5 + +_Dec 14, 2023_ + +We'd like to offer a big thanks to the 7 contributors who made this release possible. Here are some highlights ✨: + +- 🌍 Improve Swedish (sv-SE) and Urdu (ur-PK) locales on the Data Grid +- 🐞 Bugfixes + +### Data Grid + +#### `@mui/x-data-grid@6.18.5` + +- [l10n] Improve Swedish (sv-SE) locale (#11379) @fredrikcarlbom +- [l10n] Improve Urdu (ur-PK) locale for data grid (#11409) @MBilalShafi + +#### `@mui/x-data-grid-pro@6.18.5` [![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@6.18.5`. + +#### `@mui/x-data-grid-premium@6.18.5` [![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@6.18.5`. + +### Date Pickers + +#### `@mui/x-date-pickers@6.18.5` + +- [pickers] Fix field types to avoid error on latest `@types/react` version (#11398) @LukasTy +- [pickers] Support name prop (#11380) @gitstart + +#### `@mui/x-date-pickers-pro@6.18.5` [![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@6.18.5`, plus: + +- [DateRangePicker] Fix `autoFocus` behavior (#11376) @kealjones-wk + +### Docs + +- [docs] Respect GoT books (#11294) @janoma +- [test] Fix flaky screenshots (#11391) @cherniavskii + ## 6.18.4 _Dec 8, 2023_ diff --git a/docs/data/charts/styling/MarginNoSnap.js b/docs/data/charts/styling/MarginNoSnap.js index edd531d9b5d5..a3d650272b81 100644 --- a/docs/data/charts/styling/MarginNoSnap.js +++ b/docs/data/charts/styling/MarginNoSnap.js @@ -17,26 +17,27 @@ export default function MarginNoSnap() { componentName="Margin demos" data={data} renderDemo={(props) => ( - +
+ +
)} getCode={({ props }) => { return [ diff --git a/docs/data/data-grid/column-dimensions/ColumnAutosizingGroupedRows.js b/docs/data/data-grid/column-dimensions/ColumnAutosizingGroupedRows.js new file mode 100644 index 000000000000..f3f84feeb385 --- /dev/null +++ b/docs/data/data-grid/column-dimensions/ColumnAutosizingGroupedRows.js @@ -0,0 +1,41 @@ +import * as React from 'react'; +import { + DataGridPremium, + useGridApiRef, + useKeepGroupedColumnsHidden, +} from '@mui/x-data-grid-premium'; +import { useMovieData } from '@mui/x-data-grid-generator'; + +export default function ColumnAutosizingGroupedRows() { + const data = useMovieData(); + const apiRef = useGridApiRef(); + + const columns = React.useMemo(() => { + return data.columns.map((col) => ({ ...col, width: 50 })); + }, [data.columns]); + + const initialState = useKeepGroupedColumnsHidden({ + apiRef, + initialState: { rowGrouping: { model: ['company'] } }, + }); + + React.useEffect(() => { + return apiRef.current.subscribeEvent('rowExpansionChange', (params) => { + if (params.childrenExpanded) { + apiRef.current.autosizeColumns({ includeOutliers: true }); + } + }); + }, [apiRef]); + + return ( +
+ +
+ ); +} diff --git a/docs/data/data-grid/column-dimensions/ColumnAutosizingGroupedRows.tsx b/docs/data/data-grid/column-dimensions/ColumnAutosizingGroupedRows.tsx new file mode 100644 index 000000000000..f3f84feeb385 --- /dev/null +++ b/docs/data/data-grid/column-dimensions/ColumnAutosizingGroupedRows.tsx @@ -0,0 +1,41 @@ +import * as React from 'react'; +import { + DataGridPremium, + useGridApiRef, + useKeepGroupedColumnsHidden, +} from '@mui/x-data-grid-premium'; +import { useMovieData } from '@mui/x-data-grid-generator'; + +export default function ColumnAutosizingGroupedRows() { + const data = useMovieData(); + const apiRef = useGridApiRef(); + + const columns = React.useMemo(() => { + return data.columns.map((col) => ({ ...col, width: 50 })); + }, [data.columns]); + + const initialState = useKeepGroupedColumnsHidden({ + apiRef, + initialState: { rowGrouping: { model: ['company'] } }, + }); + + React.useEffect(() => { + return apiRef.current.subscribeEvent('rowExpansionChange', (params) => { + if (params.childrenExpanded) { + apiRef.current.autosizeColumns({ includeOutliers: true }); + } + }); + }, [apiRef]); + + return ( +
+ +
+ ); +} diff --git a/docs/data/data-grid/column-dimensions/ColumnAutosizingGroupedRows.tsx.preview b/docs/data/data-grid/column-dimensions/ColumnAutosizingGroupedRows.tsx.preview new file mode 100644 index 000000000000..e43fd3af6d85 --- /dev/null +++ b/docs/data/data-grid/column-dimensions/ColumnAutosizingGroupedRows.tsx.preview @@ -0,0 +1,7 @@ + \ No newline at end of file diff --git a/docs/data/data-grid/column-dimensions/column-dimensions.md b/docs/data/data-grid/column-dimensions/column-dimensions.md index c2d518212974..40e4f001494a 100644 --- a/docs/data/data-grid/column-dimensions/column-dimensions.md +++ b/docs/data/data-grid/column-dimensions/column-dimensions.md @@ -113,6 +113,13 @@ Column autosizing is compatible with the [Dynamic row height](/x/react-data-grid When autosizing columns with long content, consider setting the `maxWidth` for the column to avoid it becoming too wide. ::: +### Autosizing with grouped rows [](/x/introduction/licensing/#premium-plan 'Premium plan') + +When using [row grouping](/x/react-data-grid/row-grouping/) you can utilize the `autosizeColumns` method to adjust the column width of the expanded rows dynamically. +The demo below shows how you can subscribe to the `rowExpansionChange` event. The provided handler function then calls the `autosizeColumns` method from the gridApi. + +{{"demo": "ColumnAutosizingGroupedRows.js", "disableAd": true, "bg": "inline"}} + ## API - [DataGrid](/x/api/data-grid/data-grid/) diff --git a/docs/data/data-grid/column-groups/BasicGroupingDemo.js b/docs/data/data-grid/column-groups/BasicGroupingDemo.js index dd26c98b8c27..eb5c5a6d614d 100644 --- a/docs/data/data-grid/column-groups/BasicGroupingDemo.js +++ b/docs/data/data-grid/column-groups/BasicGroupingDemo.js @@ -22,10 +22,10 @@ const columns = [ ]; const rows = [ - { id: 1, lastName: 'Snow', firstName: 'Jon', age: 35 }, - { id: 2, lastName: 'Lannister', firstName: 'Cersei', age: 42 }, - { id: 3, lastName: 'Lannister', firstName: 'Jaime', age: 45 }, - { id: 4, lastName: 'Stark', firstName: 'Arya', age: 16 }, + { id: 1, lastName: 'Snow', firstName: 'Jon', age: 14 }, + { id: 2, lastName: 'Lannister', firstName: 'Cersei', age: 31 }, + { id: 3, lastName: 'Lannister', firstName: 'Jaime', age: 31 }, + { id: 4, lastName: 'Stark', firstName: 'Arya', age: 11 }, { id: 5, lastName: 'Targaryen', firstName: 'Daenerys', age: null }, { id: 6, lastName: 'Melisandre', firstName: null, age: 150 }, { id: 7, lastName: 'Clifford', firstName: 'Ferrara', age: 44 }, diff --git a/docs/data/data-grid/column-groups/BasicGroupingDemo.tsx b/docs/data/data-grid/column-groups/BasicGroupingDemo.tsx index ea48cee7d62a..feee6c65142b 100644 --- a/docs/data/data-grid/column-groups/BasicGroupingDemo.tsx +++ b/docs/data/data-grid/column-groups/BasicGroupingDemo.tsx @@ -22,10 +22,10 @@ const columns: GridColDef[] = [ ]; const rows = [ - { id: 1, lastName: 'Snow', firstName: 'Jon', age: 35 }, - { id: 2, lastName: 'Lannister', firstName: 'Cersei', age: 42 }, - { id: 3, lastName: 'Lannister', firstName: 'Jaime', age: 45 }, - { id: 4, lastName: 'Stark', firstName: 'Arya', age: 16 }, + { id: 1, lastName: 'Snow', firstName: 'Jon', age: 14 }, + { id: 2, lastName: 'Lannister', firstName: 'Cersei', age: 31 }, + { id: 3, lastName: 'Lannister', firstName: 'Jaime', age: 31 }, + { id: 4, lastName: 'Stark', firstName: 'Arya', age: 11 }, { id: 5, lastName: 'Targaryen', firstName: 'Daenerys', age: null }, { id: 6, lastName: 'Melisandre', firstName: null, age: 150 }, { id: 7, lastName: 'Clifford', firstName: 'Ferrara', age: 44 }, diff --git a/docs/data/data-grid/column-groups/BreakingGroupDemo.js b/docs/data/data-grid/column-groups/BreakingGroupDemo.js index dfa82ee6d36c..5126b37198a0 100644 --- a/docs/data/data-grid/column-groups/BreakingGroupDemo.js +++ b/docs/data/data-grid/column-groups/BreakingGroupDemo.js @@ -23,10 +23,10 @@ const columns = [ ]; const rows = [ - { id: 1, isAdmin: false, lastName: 'Snow', firstName: 'Jon', age: 35 }, - { id: 2, isAdmin: true, lastName: 'Lannister', firstName: 'Cersei', age: 42 }, - { id: 3, isAdmin: false, lastName: 'Lannister', firstName: 'Jaime', age: 45 }, - { id: 4, isAdmin: false, lastName: 'Stark', firstName: 'Arya', age: 16 }, + { id: 1, isAdmin: false, lastName: 'Snow', firstName: 'Jon', age: 14 }, + { id: 2, isAdmin: true, lastName: 'Lannister', firstName: 'Cersei', age: 31 }, + { id: 3, isAdmin: false, lastName: 'Lannister', firstName: 'Jaime', age: 31 }, + { id: 4, isAdmin: false, lastName: 'Stark', firstName: 'Arya', age: 11 }, { id: 5, isAdmin: true, lastName: 'Targaryen', firstName: 'Daenerys', age: null }, { id: 6, isAdmin: true, lastName: 'Melisandre', firstName: null, age: 150 }, { id: 7, isAdmin: false, lastName: 'Clifford', firstName: 'Ferrara', age: 44 }, diff --git a/docs/data/data-grid/column-groups/BreakingGroupDemo.tsx b/docs/data/data-grid/column-groups/BreakingGroupDemo.tsx index 6dc30426474e..b4a3dded91fc 100644 --- a/docs/data/data-grid/column-groups/BreakingGroupDemo.tsx +++ b/docs/data/data-grid/column-groups/BreakingGroupDemo.tsx @@ -27,10 +27,10 @@ const columns: GridColDef[] = [ ]; const rows = [ - { id: 1, isAdmin: false, lastName: 'Snow', firstName: 'Jon', age: 35 }, - { id: 2, isAdmin: true, lastName: 'Lannister', firstName: 'Cersei', age: 42 }, - { id: 3, isAdmin: false, lastName: 'Lannister', firstName: 'Jaime', age: 45 }, - { id: 4, isAdmin: false, lastName: 'Stark', firstName: 'Arya', age: 16 }, + { id: 1, isAdmin: false, lastName: 'Snow', firstName: 'Jon', age: 14 }, + { id: 2, isAdmin: true, lastName: 'Lannister', firstName: 'Cersei', age: 31 }, + { id: 3, isAdmin: false, lastName: 'Lannister', firstName: 'Jaime', age: 31 }, + { id: 4, isAdmin: false, lastName: 'Stark', firstName: 'Arya', age: 11 }, { id: 5, isAdmin: true, lastName: 'Targaryen', firstName: 'Daenerys', age: null }, { id: 6, isAdmin: true, lastName: 'Melisandre', firstName: null, age: 150 }, { id: 7, isAdmin: false, lastName: 'Clifford', firstName: 'Ferrara', age: 44 }, diff --git a/docs/data/data-grid/column-groups/CustomizationDemo.js b/docs/data/data-grid/column-groups/CustomizationDemo.js index 7563dcac951f..c15c4bf960e6 100644 --- a/docs/data/data-grid/column-groups/CustomizationDemo.js +++ b/docs/data/data-grid/column-groups/CustomizationDemo.js @@ -26,10 +26,10 @@ const columns = [ ]; const rows = [ - { id: 1, lastName: 'Snow', firstName: 'Jon', age: 35 }, - { id: 2, lastName: 'Lannister', firstName: 'Cersei', age: 42 }, - { id: 3, lastName: 'Lannister', firstName: 'Jaime', age: 45 }, - { id: 4, lastName: 'Stark', firstName: 'Arya', age: 16 }, + { id: 1, lastName: 'Snow', firstName: 'Jon', age: 14 }, + { id: 2, lastName: 'Lannister', firstName: 'Cersei', age: 31 }, + { id: 3, lastName: 'Lannister', firstName: 'Jaime', age: 31 }, + { id: 4, lastName: 'Stark', firstName: 'Arya', age: 11 }, { id: 5, lastName: 'Targaryen', firstName: 'Daenerys', age: null }, { id: 6, lastName: 'Melisandre', firstName: null, age: 150 }, { id: 7, lastName: 'Clifford', firstName: 'Ferrara', age: 44 }, diff --git a/docs/data/data-grid/column-groups/CustomizationDemo.tsx b/docs/data/data-grid/column-groups/CustomizationDemo.tsx index 91449b0ea05e..66fca6d67c55 100644 --- a/docs/data/data-grid/column-groups/CustomizationDemo.tsx +++ b/docs/data/data-grid/column-groups/CustomizationDemo.tsx @@ -31,10 +31,10 @@ const columns: GridColDef[] = [ ]; const rows = [ - { id: 1, lastName: 'Snow', firstName: 'Jon', age: 35 }, - { id: 2, lastName: 'Lannister', firstName: 'Cersei', age: 42 }, - { id: 3, lastName: 'Lannister', firstName: 'Jaime', age: 45 }, - { id: 4, lastName: 'Stark', firstName: 'Arya', age: 16 }, + { id: 1, lastName: 'Snow', firstName: 'Jon', age: 14 }, + { id: 2, lastName: 'Lannister', firstName: 'Cersei', age: 31 }, + { id: 3, lastName: 'Lannister', firstName: 'Jaime', age: 31 }, + { id: 4, lastName: 'Stark', firstName: 'Arya', age: 11 }, { id: 5, lastName: 'Targaryen', firstName: 'Daenerys', age: null }, { id: 6, lastName: 'Melisandre', firstName: null, age: 150 }, { id: 7, lastName: 'Clifford', firstName: 'Ferrara', age: 44 }, diff --git a/docs/data/data-grid/localization/data.json b/docs/data/data-grid/localization/data.json index 75402033fb9c..ac1854c7edb8 100644 --- a/docs/data/data-grid/localization/data.json +++ b/docs/data/data-grid/localization/data.json @@ -203,7 +203,7 @@ "languageTag": "sv-SE", "importName": "svSE", "localeName": "Swedish", - "missingKeysCount": 25, + "missingKeysCount": 0, "totalKeysCount": 119, "githubLink": "https://github.com/mui/mui-x/blob/master/packages/grid/x-data-grid/src/locales/svSE.ts" }, @@ -227,7 +227,7 @@ "languageTag": "ur-PK", "importName": "urPK", "localeName": "Urdu (Pakistan)", - "missingKeysCount": 26, + "missingKeysCount": 0, "totalKeysCount": 119, "githubLink": "https://github.com/mui/mui-x/blob/master/packages/grid/x-data-grid/src/locales/urPK.ts" }, diff --git a/docs/data/data-grid/overview/DataGridDemo.js b/docs/data/data-grid/overview/DataGridDemo.js index 69f5a01e8a55..7987b9fdb00f 100644 --- a/docs/data/data-grid/overview/DataGridDemo.js +++ b/docs/data/data-grid/overview/DataGridDemo.js @@ -35,10 +35,10 @@ const columns = [ ]; const rows = [ - { id: 1, lastName: 'Snow', firstName: 'Jon', age: 35 }, - { id: 2, lastName: 'Lannister', firstName: 'Cersei', age: 42 }, - { id: 3, lastName: 'Lannister', firstName: 'Jaime', age: 45 }, - { id: 4, lastName: 'Stark', firstName: 'Arya', age: 16 }, + { id: 1, lastName: 'Snow', firstName: 'Jon', age: 14 }, + { id: 2, lastName: 'Lannister', firstName: 'Cersei', age: 31 }, + { id: 3, lastName: 'Lannister', firstName: 'Jaime', age: 31 }, + { id: 4, lastName: 'Stark', firstName: 'Arya', age: 11 }, { id: 5, lastName: 'Targaryen', firstName: 'Daenerys', age: null }, { id: 6, lastName: 'Melisandre', firstName: null, age: 150 }, { id: 7, lastName: 'Clifford', firstName: 'Ferrara', age: 44 }, diff --git a/docs/data/data-grid/overview/DataGridDemo.tsx b/docs/data/data-grid/overview/DataGridDemo.tsx index 440116610a23..5e5f83286274 100644 --- a/docs/data/data-grid/overview/DataGridDemo.tsx +++ b/docs/data/data-grid/overview/DataGridDemo.tsx @@ -35,10 +35,10 @@ const columns: GridColDef[] = [ ]; const rows = [ - { id: 1, lastName: 'Snow', firstName: 'Jon', age: 35 }, - { id: 2, lastName: 'Lannister', firstName: 'Cersei', age: 42 }, - { id: 3, lastName: 'Lannister', firstName: 'Jaime', age: 45 }, - { id: 4, lastName: 'Stark', firstName: 'Arya', age: 16 }, + { id: 1, lastName: 'Snow', firstName: 'Jon', age: 14 }, + { id: 2, lastName: 'Lannister', firstName: 'Cersei', age: 31 }, + { id: 3, lastName: 'Lannister', firstName: 'Jaime', age: 31 }, + { id: 4, lastName: 'Stark', firstName: 'Arya', age: 11 }, { id: 5, lastName: 'Targaryen', firstName: 'Daenerys', age: null }, { id: 6, lastName: 'Melisandre', firstName: null, age: 150 }, { id: 7, lastName: 'Clifford', firstName: 'Ferrara', age: 44 }, diff --git a/docs/data/data-grid/row-selection/ControlledSelectionServerPaginationGrid.js b/docs/data/data-grid/row-selection/ControlledSelectionServerPaginationGrid.js index 8f1d97c04a5e..3a6540ab8bb9 100644 --- a/docs/data/data-grid/row-selection/ControlledSelectionServerPaginationGrid.js +++ b/docs/data/data-grid/row-selection/ControlledSelectionServerPaginationGrid.js @@ -1,12 +1,12 @@ import * as React from 'react'; import { DataGrid } from '@mui/x-data-grid'; -import { useDemoData } from '@mui/x-data-grid-generator'; +import { useDemoData, randomInt } from '@mui/x-data-grid-generator'; function loadServerRows(page, data) { return new Promise((resolve) => { setTimeout(() => { resolve(data.rows.slice(page * 5, (page + 1) * 5)); - }, Math.random() * 500 + 100); // simulate network latency + }, randomInt(100, 600)); // simulate network latency }); } diff --git a/docs/data/data-grid/row-selection/ControlledSelectionServerPaginationGrid.tsx b/docs/data/data-grid/row-selection/ControlledSelectionServerPaginationGrid.tsx index a401a1263b4f..9cd691a34f7e 100644 --- a/docs/data/data-grid/row-selection/ControlledSelectionServerPaginationGrid.tsx +++ b/docs/data/data-grid/row-selection/ControlledSelectionServerPaginationGrid.tsx @@ -1,12 +1,12 @@ import * as React from 'react'; import { DataGrid, GridRowsProp, GridRowSelectionModel } from '@mui/x-data-grid'; -import { GridDemoData, useDemoData } from '@mui/x-data-grid-generator'; +import { GridDemoData, useDemoData, randomInt } from '@mui/x-data-grid-generator'; function loadServerRows(page: number, data: GridDemoData): Promise { return new Promise((resolve) => { setTimeout(() => { resolve(data.rows.slice(page * 5, (page + 1) * 5)); - }, Math.random() * 500 + 100); // simulate network latency + }, randomInt(100, 600)); // simulate network latency }); } diff --git a/docs/data/data-grid/row-updates/InfiniteLoadingGrid.js b/docs/data/data-grid/row-updates/InfiniteLoadingGrid.js index 616446081e3d..1d4910848972 100644 --- a/docs/data/data-grid/row-updates/InfiniteLoadingGrid.js +++ b/docs/data/data-grid/row-updates/InfiniteLoadingGrid.js @@ -4,6 +4,7 @@ import { useDemoData, getRealGridData, getCommodityColumns, + randomInt, } from '@mui/x-data-grid-generator'; import LinearProgress from '@mui/material/LinearProgress'; @@ -31,7 +32,7 @@ export default function InfiniteLoadingGrid() { setLoading(true); const newData = await getRealGridData(newRowLength, getCommodityColumns()); // Simulate network throttle - await sleep(Math.random() * 500 + 100); + await sleep(randomInt(100, 600)); if (mounted.current) { setLoading(false); diff --git a/docs/data/data-grid/row-updates/InfiniteLoadingGrid.tsx b/docs/data/data-grid/row-updates/InfiniteLoadingGrid.tsx index bf1c14ea0980..f25f0c832f9b 100644 --- a/docs/data/data-grid/row-updates/InfiniteLoadingGrid.tsx +++ b/docs/data/data-grid/row-updates/InfiniteLoadingGrid.tsx @@ -4,6 +4,7 @@ import { useDemoData, getRealGridData, getCommodityColumns, + randomInt, } from '@mui/x-data-grid-generator'; import LinearProgress from '@mui/material/LinearProgress'; @@ -31,7 +32,7 @@ export default function InfiniteLoadingGrid() { setLoading(true); const newData = await getRealGridData(newRowLength, getCommodityColumns()); // Simulate network throttle - await sleep(Math.random() * 500 + 100); + await sleep(randomInt(100, 600)); if (mounted.current) { setLoading(false); diff --git a/docs/data/date-pickers-component-api-pages.ts b/docs/data/date-pickers-component-api-pages.ts index 91448100bee3..561cfe661526 100644 --- a/docs/data/date-pickers-component-api-pages.ts +++ b/docs/data/date-pickers-component-api-pages.ts @@ -64,6 +64,7 @@ export default [ { pathname: '/x/api/date-pickers/pickers-calendar-header', title: 'PickersCalendarHeader' }, { pathname: '/x/api/date-pickers/pickers-day', title: 'PickersDay' }, { pathname: '/x/api/date-pickers/pickers-layout', title: 'PickersLayout' }, + { pathname: '/x/api/date-pickers/pickers-section-list', title: 'PickersSectionList' }, { pathname: '/x/api/date-pickers/pickers-shortcuts', title: 'PickersShortcuts' }, { pathname: '/x/api/date-pickers/single-input-date-range-field', diff --git a/docs/data/date-pickers/custom-components/ArrowSwitcherComponentProps.tsx b/docs/data/date-pickers/custom-components/ArrowSwitcherComponentProps.tsx index 712ada0e0610..daccbeb96c9b 100644 --- a/docs/data/date-pickers/custom-components/ArrowSwitcherComponentProps.tsx +++ b/docs/data/date-pickers/custom-components/ArrowSwitcherComponentProps.tsx @@ -7,13 +7,10 @@ import Box from '@mui/material/Box'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DateCalendar } from '@mui/x-date-pickers/DateCalendar'; -import { - TimeClock, - TimeClockSlotsComponentsProps, -} from '@mui/x-date-pickers/TimeClock'; +import { TimeClock, TimeClockSlotProps } from '@mui/x-date-pickers/TimeClock'; import { DateRangeCalendar } from '@mui/x-date-pickers-pro/DateRangeCalendar'; -const slotProps: TimeClockSlotsComponentsProps = { +const slotProps: TimeClockSlotProps = { leftArrowIcon: { fontSize: 'large' }, rightArrowIcon: { fontSize: 'large' }, previousIconButton: { diff --git a/docs/data/date-pickers/custom-field/PickerWithBrowserField.js b/docs/data/date-pickers/custom-field/PickerWithBrowserField.js index a350cec68181..b5a8aa1a476a 100644 --- a/docs/data/date-pickers/custom-field/PickerWithBrowserField.js +++ b/docs/data/date-pickers/custom-field/PickerWithBrowserField.js @@ -6,7 +6,6 @@ import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { DatePicker } from '@mui/x-date-pickers/DatePicker'; import { unstable_useDateField as useDateField } from '@mui/x-date-pickers/DateField'; - import { useClearableField } from '@mui/x-date-pickers/hooks'; const BrowserField = React.forwardRef((props, ref) => { @@ -40,36 +39,18 @@ const BrowserField = React.forwardRef((props, ref) => { }); const BrowserDateField = React.forwardRef((props, ref) => { - const { inputRef: externalInputRef, slots, slotProps, ...textFieldProps } = props; + const { slots, slotProps, ...textFieldProps } = props; - const { - onClear, - clearable, - ref: inputRef, - ...fieldProps - } = useDateField({ - props: textFieldProps, - inputRef: externalInputRef, - }); + const fieldResponse = useDateField(textFieldProps); /* If you don't need a clear button, you can skip the use of this hook */ - const { InputProps: ProcessedInputProps, fieldProps: processedFieldProps } = - useClearableField({ - onClear, - clearable, - fieldProps, - InputProps: fieldProps.InputProps, - slots, - slotProps, - }); - return ( - - ); + const processedFieldProps = useClearableField({ + ...fieldResponse, + slots, + slotProps, + }); + + return ; }); const BrowserDatePicker = React.forwardRef((props, ref) => { @@ -77,7 +58,7 @@ const BrowserDatePicker = React.forwardRef((props, ref) => { ); }); diff --git a/docs/data/date-pickers/custom-field/PickerWithBrowserField.tsx b/docs/data/date-pickers/custom-field/PickerWithBrowserField.tsx index 700beb54cedb..7b1269ab72c9 100644 --- a/docs/data/date-pickers/custom-field/PickerWithBrowserField.tsx +++ b/docs/data/date-pickers/custom-field/PickerWithBrowserField.tsx @@ -9,10 +9,6 @@ import { unstable_useDateField as useDateField, UseDateFieldProps, } from '@mui/x-date-pickers/DateField'; -import { - DateFieldSlotsComponent, - DateFieldSlotsComponentsProps, -} from '@mui/x-date-pickers/DateField/DateField.types'; import { useClearableField } from '@mui/x-date-pickers/hooks'; import { BaseSingleInputFieldProps, @@ -82,46 +78,18 @@ interface BrowserDateFieldProps const BrowserDateField = React.forwardRef( (props: BrowserDateFieldProps, ref: React.Ref) => { - const { - inputRef: externalInputRef, + const { slots, slotProps, ...textFieldProps } = props; + + const fieldResponse = useDateField(textFieldProps); + + /* If you don't need a clear button, you can skip the use of this hook */ + const processedFieldProps = useClearableField({ + ...fieldResponse, slots, slotProps, - ...textFieldProps - } = props; - - const { - onClear, - clearable, - ref: inputRef, - ...fieldProps - } = useDateField({ - props: textFieldProps, - inputRef: externalInputRef, }); - /* If you don't need a clear button, you can skip the use of this hook */ - const { InputProps: ProcessedInputProps, fieldProps: processedFieldProps } = - useClearableField< - {}, - typeof textFieldProps.InputProps, - DateFieldSlotsComponent, - DateFieldSlotsComponentsProps - >({ - onClear, - clearable, - fieldProps, - InputProps: fieldProps.InputProps, - slots, - slotProps, - }); - return ( - - ); + return ; }, ); @@ -131,7 +99,7 @@ const BrowserDatePicker = React.forwardRef( ); }, diff --git a/docs/data/date-pickers/custom-field/PickerWithJoyField.js b/docs/data/date-pickers/custom-field/PickerWithJoyField.js index b195500b8b7d..c685d14d25b9 100644 --- a/docs/data/date-pickers/custom-field/PickerWithJoyField.js +++ b/docs/data/date-pickers/custom-field/PickerWithJoyField.js @@ -18,7 +18,6 @@ import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { DatePicker } from '@mui/x-date-pickers/DatePicker'; import { unstable_useDateField as useDateField } from '@mui/x-date-pickers/DateField'; - import { useClearableField } from '@mui/x-date-pickers/hooks'; const joyTheme = extendJoyTheme(); @@ -33,6 +32,7 @@ const JoyField = React.forwardRef((props, ref) => { endDecorator, startDecorator, slotProps, + inputRef, ...other } = props; @@ -62,6 +62,7 @@ const JoyField = React.forwardRef((props, ref) => { slotProps={{ ...slotProps, root: { ...slotProps?.root, ref: containerRef }, + input: { ...slotProps?.input, ref: inputRef }, }} {...other} /> @@ -70,41 +71,18 @@ const JoyField = React.forwardRef((props, ref) => { }); const JoyDateField = React.forwardRef((props, ref) => { - const { inputRef: externalInputRef, slots, slotProps, ...textFieldProps } = props; + const { slots, slotProps, ...textFieldProps } = props; - const { - onClear, - clearable, - ref: inputRef, - ...fieldProps - } = useDateField({ - props: textFieldProps, - inputRef: externalInputRef, - }); + const fieldResponse = useDateField(textFieldProps); /* If you don't need a clear button, you can skip the use of this hook */ - const { InputProps: ProcessedInputProps, fieldProps: processedFieldProps } = - useClearableField({ - onClear, - clearable, - fieldProps, - InputProps: fieldProps.InputProps, - slots, - slotProps, - }); + const processedFieldProps = useClearableField({ + ...fieldResponse, + slots, + slotProps, + }); - return ( - - ); + return ; }); const JoyDatePicker = React.forwardRef((props, ref) => { @@ -112,7 +90,7 @@ const JoyDatePicker = React.forwardRef((props, ref) => { ; InputProps?: { ref?: React.Ref; endAdornment?: React.ReactNode; @@ -59,6 +56,7 @@ const JoyField = React.forwardRef( endDecorator, startDecorator, slotProps, + inputRef, ...other } = props; @@ -88,6 +86,7 @@ const JoyField = React.forwardRef( slotProps={{ ...slotProps, root: { ...slotProps?.root, ref: containerRef }, + input: { ...slotProps?.input, ref: inputRef }, }} {...other} /> @@ -107,51 +106,18 @@ interface JoyDateFieldProps const JoyDateField = React.forwardRef( (props: JoyDateFieldProps, ref: React.Ref) => { - const { - inputRef: externalInputRef, - slots, - slotProps, - ...textFieldProps - } = props; + const { slots, slotProps, ...textFieldProps } = props; - const { - onClear, - clearable, - ref: inputRef, - ...fieldProps - } = useDateField({ - props: textFieldProps, - inputRef: externalInputRef, - }); + const fieldResponse = useDateField(textFieldProps); /* If you don't need a clear button, you can skip the use of this hook */ - const { InputProps: ProcessedInputProps, fieldProps: processedFieldProps } = - useClearableField< - {}, - typeof textFieldProps.InputProps, - DateFieldSlotsComponent, - DateFieldSlotsComponentsProps - >({ - onClear, - clearable, - fieldProps, - InputProps: fieldProps.InputProps, - slots, - slotProps, - }); + const processedFieldProps = useClearableField({ + ...fieldResponse, + slots, + slotProps, + }); - return ( - - ); + return ; }, ); @@ -161,7 +127,7 @@ const JoyDatePicker = React.forwardRef( { className, } = props; - const { inputRef: startInputRef, ...startTextFieldProps } = useSlotProps({ + const startTextFieldProps = useSlotProps({ elementType: 'input', externalSlotProps: slotProps?.textField, ownerState: { ...props, position: 'start' }, }); - const { inputRef: endInputRef, ...endTextFieldProps } = useSlotProps({ + const endTextFieldProps = useSlotProps({ elementType: 'input', externalSlotProps: slotProps?.textField, ownerState: { ...props, position: 'end' }, }); - const { - startDate: { ref: startRef, ...startDateProps }, - endDate: { ref: endRef, ...endDateProps }, - } = useMultiInputDateRangeField({ + const fieldResponse = useMultiInputDateRangeField({ sharedProps: { value, defaultValue, @@ -93,8 +90,6 @@ const BrowserMultiInputDateRangeField = React.forwardRef((props, ref) => { }, startTextFieldProps, endTextFieldProps, - startInputRef, - endInputRef, }); return ( @@ -105,9 +100,9 @@ const BrowserMultiInputDateRangeField = React.forwardRef((props, ref) => { overflow="auto" className={className} > - + - + ); }); @@ -117,7 +112,7 @@ const BrowserDateRangePicker = React.forwardRef((props, ref) => { ); }); diff --git a/docs/data/date-pickers/custom-field/RangePickerWithBrowserField.tsx b/docs/data/date-pickers/custom-field/RangePickerWithBrowserField.tsx index b5cf357624ba..2bdd06ef5d0c 100644 --- a/docs/data/date-pickers/custom-field/RangePickerWithBrowserField.tsx +++ b/docs/data/date-pickers/custom-field/RangePickerWithBrowserField.tsx @@ -105,22 +105,22 @@ const BrowserMultiInputDateRangeField = React.forwardRef( className, } = props; - const { inputRef: startInputRef, ...startTextFieldProps } = useSlotProps({ + const startTextFieldProps = useSlotProps({ elementType: 'input', externalSlotProps: slotProps?.textField, ownerState: { ...props, position: 'start' }, }) as MultiInputFieldSlotTextFieldProps; - const { inputRef: endInputRef, ...endTextFieldProps } = useSlotProps({ + const endTextFieldProps = useSlotProps({ elementType: 'input', externalSlotProps: slotProps?.textField, ownerState: { ...props, position: 'end' }, }) as MultiInputFieldSlotTextFieldProps; - const { - startDate: { ref: startRef, ...startDateProps }, - endDate: { ref: endRef, ...endDateProps }, - } = useMultiInputDateRangeField({ + const fieldResponse = useMultiInputDateRangeField< + Dayjs, + MultiInputFieldSlotTextFieldProps + >({ sharedProps: { value, defaultValue, @@ -139,8 +139,6 @@ const BrowserMultiInputDateRangeField = React.forwardRef( }, startTextFieldProps, endTextFieldProps, - startInputRef, - endInputRef, }); return ( @@ -151,9 +149,9 @@ const BrowserMultiInputDateRangeField = React.forwardRef( overflow="auto" className={className} > - + - + ); }, @@ -165,7 +163,7 @@ const BrowserDateRangePicker = React.forwardRef( ); }, diff --git a/docs/data/date-pickers/custom-field/RangePickerWithJoyField.js b/docs/data/date-pickers/custom-field/RangePickerWithJoyField.js index 26cb65d1b035..200b4229807e 100644 --- a/docs/data/date-pickers/custom-field/RangePickerWithJoyField.js +++ b/docs/data/date-pickers/custom-field/RangePickerWithJoyField.js @@ -34,6 +34,7 @@ const JoyField = React.forwardRef((props, ref) => { endDecorator, startDecorator, slotProps, + inputRef, ...other } = props; @@ -58,6 +59,7 @@ const JoyField = React.forwardRef((props, ref) => { slotProps={{ ...slotProps, root: { ...slotProps?.root, ref: containerRef }, + input: { ...slotProps?.input, ref: inputRef }, }} {...other} /> @@ -118,22 +120,19 @@ const JoyMultiInputDateRangeField = React.forwardRef((props, ref) => { className, } = props; - const { inputRef: startInputRef, ...startTextFieldProps } = useSlotProps({ + const startTextFieldProps = useSlotProps({ elementType: FormControl, externalSlotProps: slotProps?.textField, ownerState: { ...props, position: 'start' }, }); - const { inputRef: endInputRef, ...endTextFieldProps } = useSlotProps({ + const endTextFieldProps = useSlotProps({ elementType: FormControl, externalSlotProps: slotProps?.textField, ownerState: { ...props, position: 'end' }, }); - const { - startDate: { ref: startRef, ...startDateProps }, - endDate: { ref: endRef, ...endDateProps }, - } = useMultiInputDateRangeField({ + const fieldResponse = useMultiInputDateRangeField({ sharedProps: { value, defaultValue, @@ -152,29 +151,13 @@ const JoyMultiInputDateRangeField = React.forwardRef((props, ref) => { }, startTextFieldProps, endTextFieldProps, - startInputRef, - endInputRef, }); return ( - + - + ); }); diff --git a/docs/data/date-pickers/custom-field/RangePickerWithJoyField.tsx b/docs/data/date-pickers/custom-field/RangePickerWithJoyField.tsx index a5506efdaff7..bf1c1bdd5ca8 100644 --- a/docs/data/date-pickers/custom-field/RangePickerWithJoyField.tsx +++ b/docs/data/date-pickers/custom-field/RangePickerWithJoyField.tsx @@ -38,6 +38,7 @@ const joyTheme = extendJoyTheme(); interface JoyFieldProps extends InputProps { label?: React.ReactNode; + inputRef?: React.Ref; InputProps?: { ref?: React.Ref; endAdornment?: React.ReactNode; @@ -59,6 +60,7 @@ const JoyField = React.forwardRef( endDecorator, startDecorator, slotProps, + inputRef, ...other } = props; @@ -83,6 +85,7 @@ const JoyField = React.forwardRef( slotProps={{ ...slotProps, root: { ...slotProps?.root, ref: containerRef }, + input: { ...slotProps?.input, ref: inputRef }, }} {...other} /> @@ -158,22 +161,22 @@ const JoyMultiInputDateRangeField = React.forwardRef( className, } = props; - const { inputRef: startInputRef, ...startTextFieldProps } = useSlotProps({ + const startTextFieldProps = useSlotProps({ elementType: FormControl, externalSlotProps: slotProps?.textField, ownerState: { ...props, position: 'start' }, }) as MultiInputFieldSlotTextFieldProps; - const { inputRef: endInputRef, ...endTextFieldProps } = useSlotProps({ + const endTextFieldProps = useSlotProps({ elementType: FormControl, externalSlotProps: slotProps?.textField, ownerState: { ...props, position: 'end' }, }) as MultiInputFieldSlotTextFieldProps; - const { - startDate: { ref: startRef, ...startDateProps }, - endDate: { ref: endRef, ...endDateProps }, - } = useMultiInputDateRangeField({ + const fieldResponse = useMultiInputDateRangeField< + Dayjs, + MultiInputFieldSlotTextFieldProps + >({ sharedProps: { value, defaultValue, @@ -192,29 +195,13 @@ const JoyMultiInputDateRangeField = React.forwardRef( }, startTextFieldProps, endTextFieldProps, - startInputRef, - endInputRef, }); return ( - + - + ); }, diff --git a/docs/data/date-pickers/custom-field/RangePickerWithSingleInputBrowserField.js b/docs/data/date-pickers/custom-field/RangePickerWithSingleInputBrowserField.js index b7971dde7bbb..a3f68577c858 100644 --- a/docs/data/date-pickers/custom-field/RangePickerWithSingleInputBrowserField.js +++ b/docs/data/date-pickers/custom-field/RangePickerWithSingleInputBrowserField.js @@ -45,42 +45,32 @@ const BrowserField = React.forwardRef((props, ref) => { const BrowserSingleInputDateRangeField = React.forwardRef((props, ref) => { const { slots, slotProps, onAdornmentClick, ...other } = props; - const { inputRef: externalInputRef, ...textFieldProps } = useSlotProps({ + const textFieldProps = useSlotProps({ elementType: 'input', externalSlotProps: slotProps?.textField, externalForwardedProps: other, ownerState: props, }); - const { - ref: inputRef, - onClear, - clearable, - ...fieldProps - } = useSingleInputDateRangeField({ - props: textFieldProps, - inputRef: externalInputRef, - }); + textFieldProps.InputProps = { + ...textFieldProps.InputProps, + endAdornment: ( + + + + + + ), + }; + + const fieldResponse = useSingleInputDateRangeField(textFieldProps); /* If you don't need a clear button, you can skip the use of this hook */ - const { InputProps: ProcessedInputProps, fieldProps: processedFieldProps } = - useClearableField({ - onClear, - clearable, - fieldProps, - InputProps: { - ...fieldProps.InputProps, - endAdornment: ( - - - - - - ), - }, - slots, - slotProps, - }); + const processedFieldProps = useClearableField({ + ...fieldResponse, + slots, + slotProps, + }); return ( { style={{ minWidth: 300, }} - inputRef={inputRef} - InputProps={{ ...ProcessedInputProps }} /> ); }); @@ -113,12 +101,12 @@ const BrowserSingleInputDateRangePicker = React.forwardRef((props, ref) => { open={isOpen} onClose={handleClose} onOpen={handleOpen} - slots={{ field: BrowserSingleInputDateRangeField }} + slots={{ ...props.slots, field: BrowserSingleInputDateRangeField }} slotProps={{ - ...props?.slotProps, + ...props.slotProps, field: { onAdornmentClick: toggleOpen, - ...props?.slotProps?.field, + ...props.slotProps?.field, }, }} /> diff --git a/docs/data/date-pickers/custom-field/RangePickerWithSingleInputBrowserField.tsx b/docs/data/date-pickers/custom-field/RangePickerWithSingleInputBrowserField.tsx index 68c03dfa4d3f..4d23c0c14222 100644 --- a/docs/data/date-pickers/custom-field/RangePickerWithSingleInputBrowserField.tsx +++ b/docs/data/date-pickers/custom-field/RangePickerWithSingleInputBrowserField.tsx @@ -17,10 +17,6 @@ import { SingleInputDateRangeFieldProps, } from '@mui/x-date-pickers-pro/SingleInputDateRangeField'; import { useClearableField } from '@mui/x-date-pickers/hooks'; -import type { - SingleInputDateRangeFieldSlotsComponent, - SingleInputDateRangeFieldSlotsComponentsProps, -} from '@mui/x-date-pickers-pro/SingleInputDateRangeField/SingleInputDateRangeField.types'; interface BrowserFieldProps extends Omit, 'size'> { @@ -89,50 +85,34 @@ const BrowserSingleInputDateRangeField = React.forwardRef( (props: BrowserSingleInputDateRangeFieldProps, ref: React.Ref) => { const { slots, slotProps, onAdornmentClick, ...other } = props; - const { - inputRef: externalInputRef, - ...textFieldProps - }: SingleInputDateRangeFieldProps = useSlotProps({ + const textFieldProps: SingleInputDateRangeFieldProps = useSlotProps({ elementType: 'input', externalSlotProps: slotProps?.textField, externalForwardedProps: other, ownerState: props as any, }); - const { - ref: inputRef, - onClear, - clearable, - ...fieldProps - } = useSingleInputDateRangeField({ - props: textFieldProps, - inputRef: externalInputRef, - }); + textFieldProps.InputProps = { + ...textFieldProps.InputProps, + endAdornment: ( + + + + + + ), + }; + + const fieldResponse = useSingleInputDateRangeField( + textFieldProps, + ); /* If you don't need a clear button, you can skip the use of this hook */ - const { InputProps: ProcessedInputProps, fieldProps: processedFieldProps } = - useClearableField< - {}, - typeof textFieldProps.InputProps, - SingleInputDateRangeFieldSlotsComponent, - SingleInputDateRangeFieldSlotsComponentsProps - >({ - onClear, - clearable, - fieldProps, - InputProps: { - ...fieldProps.InputProps, - endAdornment: ( - - - - - - ), - }, - slots, - slotProps, - }); + const processedFieldProps = useClearableField({ + ...fieldResponse, + slots, + slotProps, + }); return ( ); }, @@ -167,12 +145,12 @@ const BrowserSingleInputDateRangePicker = React.forwardRef( open={isOpen} onClose={handleClose} onOpen={handleOpen} - slots={{ field: BrowserSingleInputDateRangeField }} + slots={{ ...props.slots, field: BrowserSingleInputDateRangeField }} slotProps={{ - ...props?.slotProps, + ...props.slotProps, field: { onAdornmentClick: toggleOpen, - ...props?.slotProps?.field, + ...props.slotProps?.field, } as any, }} /> diff --git a/docs/data/date-pickers/custom-field/RangePickerWithSingleInputJoyField.js b/docs/data/date-pickers/custom-field/RangePickerWithSingleInputJoyField.js index 02299b65247e..1c8d0719826e 100644 --- a/docs/data/date-pickers/custom-field/RangePickerWithSingleInputJoyField.js +++ b/docs/data/date-pickers/custom-field/RangePickerWithSingleInputJoyField.js @@ -34,6 +34,7 @@ const JoyField = React.forwardRef((props, ref) => { endDecorator, startDecorator, slotProps, + inputRef, ...other } = props; @@ -58,6 +59,7 @@ const JoyField = React.forwardRef((props, ref) => { slotProps={{ ...slotProps, root: { ...slotProps?.root, ref: containerRef }, + input: { ...slotProps?.input, ref: inputRef }, }} {...other} /> @@ -68,43 +70,26 @@ const JoyField = React.forwardRef((props, ref) => { const JoySingleInputDateRangeField = React.forwardRef((props, ref) => { const { slots, slotProps, onAdornmentClick, ...other } = props; - const { inputRef: externalInputRef, ...textFieldProps } = useSlotProps({ + const textFieldProps = useSlotProps({ elementType: FormControl, externalSlotProps: slotProps?.textField, externalForwardedProps: other, ownerState: props, }); - const { - onClear, - clearable, - ref: inputRef, - ...fieldProps - } = useSingleInputDateRangeField({ - props: textFieldProps, - inputRef: externalInputRef, - }); + const fieldResponse = useSingleInputDateRangeField(textFieldProps); /* If you don't need a clear button, you can skip the use of this hook */ - const { InputProps: ProcessedInputProps, fieldProps: processedFieldProps } = - useClearableField({ - onClear, - clearable, - fieldProps, - InputProps: fieldProps.InputProps, - slots: { ...slots, clearButton: IconButton }, - slotProps: { ...slotProps, clearIcon: { color: 'action' } }, - }); + const processedFieldProps = useClearableField({ + ...fieldResponse, + slots, + slotProps, + }); return ( { } - InputProps={{ ...ProcessedInputProps }} /> ); }); @@ -142,11 +126,11 @@ const JoySingleInputDateRangePicker = React.forwardRef((props, ref) => { open={isOpen} onClose={handleClose} onOpen={handleOpen} - slots={{ field: JoySingleInputDateRangeField }} + slots={{ ...props.slots, field: JoySingleInputDateRangeField }} slotProps={{ - ...props?.slotProps, + ...props.slotProps, field: { - ...props?.slotProps?.field, + ...props.slotProps?.field, onAdornmentClick: toggleOpen, }, }} diff --git a/docs/data/date-pickers/custom-field/RangePickerWithSingleInputJoyField.tsx b/docs/data/date-pickers/custom-field/RangePickerWithSingleInputJoyField.tsx index 8f7f9554f589..817129b9a458 100644 --- a/docs/data/date-pickers/custom-field/RangePickerWithSingleInputJoyField.tsx +++ b/docs/data/date-pickers/custom-field/RangePickerWithSingleInputJoyField.tsx @@ -28,15 +28,12 @@ import { SingleInputDateRangeFieldProps, } from '@mui/x-date-pickers-pro/SingleInputDateRangeField'; import { useClearableField } from '@mui/x-date-pickers/hooks'; -import type { - SingleInputDateRangeFieldSlotsComponent, - SingleInputDateRangeFieldSlotsComponentsProps, -} from '@mui/x-date-pickers-pro/SingleInputDateRangeField/SingleInputDateRangeField.types'; const joyTheme = extendJoyTheme(); interface JoyFieldProps extends InputProps { label?: React.ReactNode; + inputRef?: React.Ref; InputProps?: { ref?: React.Ref; endAdornment?: React.ReactNode; @@ -58,6 +55,7 @@ const JoyField = React.forwardRef( endDecorator, startDecorator, slotProps, + inputRef, ...other } = props; @@ -82,6 +80,7 @@ const JoyField = React.forwardRef( slotProps={{ ...slotProps, root: { ...slotProps?.root, ref: containerRef }, + input: { ...slotProps?.input, ref: inputRef }, }} {...other} /> @@ -103,10 +102,7 @@ const JoySingleInputDateRangeField = React.forwardRef( (props: JoySingleInputDateRangeFieldProps, ref: React.Ref) => { const { slots, slotProps, onAdornmentClick, ...other } = props; - const { - inputRef: externalInputRef, - ...textFieldProps - }: SingleInputDateRangeFieldProps< + const textFieldProps: SingleInputDateRangeFieldProps< Dayjs, JoyFieldProps & { inputRef: React.Ref } > = useSlotProps({ @@ -116,41 +112,21 @@ const JoySingleInputDateRangeField = React.forwardRef( ownerState: props as any, }); - const { - onClear, - clearable, - ref: inputRef, - ...fieldProps - } = useSingleInputDateRangeField({ - props: textFieldProps, - inputRef: externalInputRef, - }); + const fieldResponse = useSingleInputDateRangeField( + textFieldProps, + ); /* If you don't need a clear button, you can skip the use of this hook */ - const { InputProps: ProcessedInputProps, fieldProps: processedFieldProps } = - useClearableField< - {}, - typeof textFieldProps.InputProps, - SingleInputDateRangeFieldSlotsComponent, - SingleInputDateRangeFieldSlotsComponentsProps - >({ - onClear, - clearable, - fieldProps, - InputProps: fieldProps.InputProps, - slots: { ...slots, clearButton: IconButton }, - slotProps: { ...slotProps, clearIcon: { color: 'action' } }, - }); + const processedFieldProps = useClearableField({ + ...fieldResponse, + slots, + slotProps, + }); return ( } - InputProps={{ ...ProcessedInputProps }} /> ); }, @@ -190,11 +165,11 @@ const JoySingleInputDateRangePicker = React.forwardRef( open={isOpen} onClose={handleClose} onOpen={handleOpen} - slots={{ field: JoySingleInputDateRangeField }} + slots={{ ...props.slots, field: JoySingleInputDateRangeField }} slotProps={{ - ...props?.slotProps, + ...props.slotProps, field: { - ...props?.slotProps?.field, + ...props.slotProps?.field, onAdornmentClick: toggleOpen, } as any, }} diff --git a/docs/data/date-pickers/date-picker/FormPropsDatePickers.js b/docs/data/date-pickers/date-picker/FormPropsDatePickers.js index 02c45ffc520c..d71e69ac5477 100644 --- a/docs/data/date-pickers/date-picker/FormPropsDatePickers.js +++ b/docs/data/date-pickers/date-picker/FormPropsDatePickers.js @@ -10,6 +10,7 @@ export default function FormPropsDatePickers() { + ); diff --git a/docs/data/date-pickers/date-picker/FormPropsDatePickers.tsx b/docs/data/date-pickers/date-picker/FormPropsDatePickers.tsx index 02c45ffc520c..d71e69ac5477 100644 --- a/docs/data/date-pickers/date-picker/FormPropsDatePickers.tsx +++ b/docs/data/date-pickers/date-picker/FormPropsDatePickers.tsx @@ -10,6 +10,7 @@ export default function FormPropsDatePickers() { + ); diff --git a/docs/data/date-pickers/date-picker/FormPropsDatePickers.tsx.preview b/docs/data/date-pickers/date-picker/FormPropsDatePickers.tsx.preview index 5cf60293ff0f..c77ca96450dc 100644 --- a/docs/data/date-pickers/date-picker/FormPropsDatePickers.tsx.preview +++ b/docs/data/date-pickers/date-picker/FormPropsDatePickers.tsx.preview @@ -1,2 +1,3 @@ - \ No newline at end of file + + \ No newline at end of file diff --git a/docs/data/date-pickers/date-time-picker/FormPropsDateTimePickers.js b/docs/data/date-pickers/date-time-picker/FormPropsDateTimePickers.js index 6e25c07e6969..5f0e4e489b92 100644 --- a/docs/data/date-pickers/date-time-picker/FormPropsDateTimePickers.js +++ b/docs/data/date-pickers/date-time-picker/FormPropsDateTimePickers.js @@ -10,6 +10,7 @@ export default function FormPropsDateTimePickers() { + ); diff --git a/docs/data/date-pickers/date-time-picker/FormPropsDateTimePickers.tsx b/docs/data/date-pickers/date-time-picker/FormPropsDateTimePickers.tsx index 6e25c07e6969..5f0e4e489b92 100644 --- a/docs/data/date-pickers/date-time-picker/FormPropsDateTimePickers.tsx +++ b/docs/data/date-pickers/date-time-picker/FormPropsDateTimePickers.tsx @@ -10,6 +10,7 @@ export default function FormPropsDateTimePickers() { + ); diff --git a/docs/data/date-pickers/date-time-picker/FormPropsDateTimePickers.tsx.preview b/docs/data/date-pickers/date-time-picker/FormPropsDateTimePickers.tsx.preview index 742759be4385..8a29c7f09893 100644 --- a/docs/data/date-pickers/date-time-picker/FormPropsDateTimePickers.tsx.preview +++ b/docs/data/date-pickers/date-time-picker/FormPropsDateTimePickers.tsx.preview @@ -1,2 +1,3 @@ - \ No newline at end of file + + \ No newline at end of file diff --git a/docs/data/date-pickers/time-picker/FormPropsTimePickers.js b/docs/data/date-pickers/time-picker/FormPropsTimePickers.js index e4a32de82a78..948647fa9395 100644 --- a/docs/data/date-pickers/time-picker/FormPropsTimePickers.js +++ b/docs/data/date-pickers/time-picker/FormPropsTimePickers.js @@ -10,6 +10,7 @@ export default function FormPropsTimePickers() { + ); diff --git a/docs/data/date-pickers/time-picker/FormPropsTimePickers.tsx b/docs/data/date-pickers/time-picker/FormPropsTimePickers.tsx index e4a32de82a78..948647fa9395 100644 --- a/docs/data/date-pickers/time-picker/FormPropsTimePickers.tsx +++ b/docs/data/date-pickers/time-picker/FormPropsTimePickers.tsx @@ -10,6 +10,7 @@ export default function FormPropsTimePickers() { + ); diff --git a/docs/data/date-pickers/time-picker/FormPropsTimePickers.tsx.preview b/docs/data/date-pickers/time-picker/FormPropsTimePickers.tsx.preview index e8d900736b33..02a34bd0c0c7 100644 --- a/docs/data/date-pickers/time-picker/FormPropsTimePickers.tsx.preview +++ b/docs/data/date-pickers/time-picker/FormPropsTimePickers.tsx.preview @@ -1,2 +1,3 @@ - \ No newline at end of file + + \ No newline at end of file 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 e9c94bdf0dcf..fd5f2221b27f 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 @@ -25,31 +25,27 @@ Since v7 is a major release, it contains changes that affect the public API. These changes were done for consistency, improved stability and to make room for new features. Described below are the steps needed to migrate from v6 to v7. - +::: ## Breaking changes @@ -82,9 +78,18 @@ Below are described the steps you need to make to migrate from v6 to v7. - The deprecated props `components` and `componentsProps` have been removed. Use `slots` and `slotProps` instead. See [components section](/x/react-data-grid/components/) for more details. - The `slots.preferencesPanel` slot and the `slotProps.preferencesPanel` prop were removed. Use `slots.panel` and `slotProps.panel` instead. - +- Some selectors now require passing `instanceId` as a second argument: + ```diff + - gridColumnFieldsSelector(apiRef.current.state); + + gridColumnFieldsSelector(apiRef.current.state, apiRef.current.instanceId); + ``` + However, it's preferable to pass the `apiRef` as the first argument instead: + ```js + gridColumnFieldsSelector(apiRef); + ``` + See [Direct state access](/x/react-data-grid/state/#direct-selector-access) for more info.