From 3f1859417d2679e62a12d547ab2e60c1e6c75098 Mon Sep 17 00:00:00 2001 From: Michel Engelen <32863416+michelengelen@users.noreply.github.com> Date: Wed, 3 Apr 2024 15:34:09 +0200 Subject: [PATCH 01/11] [support-infra] Add release announcement to GitHub workflows (#11867) Signed-off-by: Michel Engelen <32863416+michelengelen@users.noreply.github.com> Co-authored-by: Olivier Tassinari --- .../discord-release-announcement.yaml | 20 +++++++++++++++++++ scripts/README.md | 6 +++++- scripts/releaseChangelog.mjs | 2 ++ 3 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/discord-release-announcement.yaml diff --git a/.github/workflows/discord-release-announcement.yaml b/.github/workflows/discord-release-announcement.yaml new file mode 100644 index 000000000000..11360a820d9d --- /dev/null +++ b/.github/workflows/discord-release-announcement.yaml @@ -0,0 +1,20 @@ +name: Discord Release Announcement + +on: + release: + types: [prereleased, published] + +permissions: {} + +jobs: + delimiter-test: + runs-on: ubuntu-latest + name: Send message to discord + steps: + - name: parse and send message + uses: michelengelen/discord-message-action@02af30a15955ecf718049bc33b0efabf6f626e0b + with: + webhook-url: ${{ secrets.DISCORD_WEBHOOK_URL }} + username: MUI Releases + avatar-url: 'https://raw.githubusercontent.com/mui/material-ui/master/docs/public/static/logo.png' + separator: '' diff --git a/scripts/README.md b/scripts/README.md index 677fec421dd6..1efcf952832e 100644 --- a/scripts/README.md +++ b/scripts/README.md @@ -23,7 +23,11 @@ yarn release:changelog --release The branch to release (default: master) ``` -You can also provide the GitHub token by setting `process.env.GITHUB_TOKEN` variable. +> :warning: the script will add a separator string in form of a comment like this right after the highlights: +> `` +> This string needs to stay where it gets inserted for the automated discord announcement to work. + +You can also provide the github token by setting `process.env.GITHUB_TOKEN` variable. In case of a problem, another method to generate the changelog is available at the end of this page. diff --git a/scripts/releaseChangelog.mjs b/scripts/releaseChangelog.mjs index 01152512c8b6..cd77b2514ecc 100644 --- a/scripts/releaseChangelog.mjs +++ b/scripts/releaseChangelog.mjs @@ -227,6 +227,8 @@ We'd like to offer a big thanks to the ${ TODO INSERT HIGHLIGHTS ${changeLogMessages.length > 0 ? '\n\n' : ''}${changeLogMessages.join('\n')} + + ### Data Grid #### \`@mui/x-data-grid@__VERSION__\` From dd20afe2668c15eb9f350ab171137c4f64931273 Mon Sep 17 00:00:00 2001 From: Gene Arch Date: Wed, 17 Apr 2024 21:48:55 -0500 Subject: [PATCH 02/11] export GridAggregationParams for use with custom aggregators (#12822) Signed-off-by: Gene Arch Co-authored-by: Rom Grk --- .../src/hooks/features/aggregation/gridAggregationInterfaces.ts | 2 +- scripts/x-data-grid-premium.exports.json | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) 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 1abf73791fd6..9839408fe3ea 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 @@ -82,7 +82,7 @@ export interface GridAggregationFunction { getCellValue?: (params: GridAggregationGetCellValueParams) => V; } -interface GridAggregationParams { +export interface GridAggregationParams { values: (V | undefined)[]; groupId: GridRowId; field: GridColDef['field']; diff --git a/scripts/x-data-grid-premium.exports.json b/scripts/x-data-grid-premium.exports.json index 5641efdd4b4c..68ec1b10b653 100644 --- a/scripts/x-data-grid-premium.exports.json +++ b/scripts/x-data-grid-premium.exports.json @@ -94,6 +94,7 @@ { "name": "gridAggregationLookupSelector", "kind": "Variable" }, { "name": "GridAggregationModel", "kind": "TypeAlias" }, { "name": "gridAggregationModelSelector", "kind": "Variable" }, + { "name": "GridAggregationParams", "kind": "Interface" }, { "name": "GridAggregationPosition", "kind": "TypeAlias" }, { "name": "GridAggregationRule", "kind": "Interface" }, { "name": "GridAggregationRules", "kind": "TypeAlias" }, From 564b296a51025bb881f660c7aeef263cbab59f6e Mon Sep 17 00:00:00 2001 From: delangle Date: Mon, 13 May 2024 11:02:42 +0200 Subject: [PATCH 03/11] [docs] Improve Tree View selection doc --- .../tree-view/accessibility/accessibility.md | 5 +++ .../selection/SingleSelectTreeView.js | 41 ++++++++++++++++++ .../selection/SingleSelectTreeView.tsx | 42 +++++++++++++++++++ .../SingleSelectTreeView.tsx.preview | 1 + .../rich-tree-view/selection/selection.md | 22 +++++++++- 5 files changed, 110 insertions(+), 1 deletion(-) create mode 100644 docs/data/tree-view/rich-tree-view/selection/SingleSelectTreeView.js create mode 100644 docs/data/tree-view/rich-tree-view/selection/SingleSelectTreeView.tsx create mode 100644 docs/data/tree-view/rich-tree-view/selection/SingleSelectTreeView.tsx.preview diff --git a/docs/data/tree-view/accessibility/accessibility.md b/docs/data/tree-view/accessibility/accessibility.md index 7f53c06af65c..341b6fec4ccb 100644 --- a/docs/data/tree-view/accessibility/accessibility.md +++ b/docs/data/tree-view/accessibility/accessibility.md @@ -61,6 +61,11 @@ When a single-select tree receives focus: - If none of the items are selected when the tree receives focus, focus is set on the first item. - If an item is selected before the tree receives focus, focus is set on the selected item. +| Keys | Description | +| ---------------------------: | :----------------------------------------------------------- | +| Space | Selects the focused item. | +| Enter | Selects the focused item if the item does not have children. | + ### On multi-select trees When a multi-select tree receives focus: diff --git a/docs/data/tree-view/rich-tree-view/selection/SingleSelectTreeView.js b/docs/data/tree-view/rich-tree-view/selection/SingleSelectTreeView.js new file mode 100644 index 000000000000..60caf9c53586 --- /dev/null +++ b/docs/data/tree-view/rich-tree-view/selection/SingleSelectTreeView.js @@ -0,0 +1,41 @@ +import * as React from 'react'; +import Box from '@mui/material/Box'; +import { RichTreeView } from '@mui/x-tree-view/RichTreeView'; + +const MUI_X_PRODUCTS = [ + { + id: 'grid', + label: 'Data Grid', + children: [ + { id: 'grid-community', label: '@mui/x-data-grid' }, + { id: 'grid-pro', label: '@mui/x-data-grid-pro' }, + { id: 'grid-premium', label: '@mui/x-data-grid-premium' }, + ], + }, + { + id: 'pickers', + label: 'Date and Time Pickers', + children: [ + { id: 'pickers-community', label: '@mui/x-date-pickers' }, + { id: 'pickers-pro', label: '@mui/x-date-pickers-pro' }, + ], + }, + { + id: 'charts', + label: 'Charts', + children: [{ id: 'charts-community', label: '@mui/x-charts' }], + }, + { + id: 'tree-view', + label: 'Tree View', + children: [{ id: 'tree-view-community', label: '@mui/x-tree-view' }], + }, +]; + +export default function SingleSelectTreeView() { + return ( + + + + ); +} diff --git a/docs/data/tree-view/rich-tree-view/selection/SingleSelectTreeView.tsx b/docs/data/tree-view/rich-tree-view/selection/SingleSelectTreeView.tsx new file mode 100644 index 000000000000..fbd000d8af63 --- /dev/null +++ b/docs/data/tree-view/rich-tree-view/selection/SingleSelectTreeView.tsx @@ -0,0 +1,42 @@ +import * as React from 'react'; +import Box from '@mui/material/Box'; +import { RichTreeView } from '@mui/x-tree-view/RichTreeView'; +import { TreeViewBaseItem } from '@mui/x-tree-view/models'; + +const MUI_X_PRODUCTS: TreeViewBaseItem[] = [ + { + id: 'grid', + label: 'Data Grid', + children: [ + { id: 'grid-community', label: '@mui/x-data-grid' }, + { id: 'grid-pro', label: '@mui/x-data-grid-pro' }, + { id: 'grid-premium', label: '@mui/x-data-grid-premium' }, + ], + }, + { + id: 'pickers', + label: 'Date and Time Pickers', + children: [ + { id: 'pickers-community', label: '@mui/x-date-pickers' }, + { id: 'pickers-pro', label: '@mui/x-date-pickers-pro' }, + ], + }, + { + id: 'charts', + label: 'Charts', + children: [{ id: 'charts-community', label: '@mui/x-charts' }], + }, + { + id: 'tree-view', + label: 'Tree View', + children: [{ id: 'tree-view-community', label: '@mui/x-tree-view' }], + }, +]; + +export default function SingleSelectTreeView() { + return ( + + + + ); +} diff --git a/docs/data/tree-view/rich-tree-view/selection/SingleSelectTreeView.tsx.preview b/docs/data/tree-view/rich-tree-view/selection/SingleSelectTreeView.tsx.preview new file mode 100644 index 000000000000..19ab6390267f --- /dev/null +++ b/docs/data/tree-view/rich-tree-view/selection/SingleSelectTreeView.tsx.preview @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/data/tree-view/rich-tree-view/selection/selection.md b/docs/data/tree-view/rich-tree-view/selection/selection.md index 929d048d5377..f5b2be86c065 100644 --- a/docs/data/tree-view/rich-tree-view/selection/selection.md +++ b/docs/data/tree-view/rich-tree-view/selection/selection.md @@ -11,12 +11,32 @@ waiAria: https://www.w3.org/WAI/ARIA/apg/patterns/treeview/

Handle how users can select items.

+## Single selection + +By default, the Tree View allows selecting a single item. + +{{"demo": "SingleSelectTreeView.js"}} + +:::success +When the Tree View uses single selection, you can select an item by clicking it, +or using the [keyboard shortcuts](/x/react-tree-view/accessibility/#on-single-select-trees). +::: + ## Multi selection -The Tree View also supports multi-selection: +Use the `multiSelect` prop to enable multi-selection. {{"demo": "MultiSelectTreeView.js"}} +:::success +When the Tree View uses multi selection, you can select multiple items using the mouse in two ways: + +- To select multiple independent items, hold Ctrl (or Enter on macOS) and click the items. +- To select a range of items, clock on the first item of the range, then hold the Shift key while clicking on the last item of the range. + +You can also use the [keyboard shortcuts](/x/react-tree-view/accessibility/#on-multi-select-trees) to select items. +::: + ## Disable selection Use the `disableSelection` prop if you don't want your items to be selectable: From 58042d3223ca28f1169df7dd6c04ac2348b90abc Mon Sep 17 00:00:00 2001 From: delangle Date: Mon, 13 May 2024 11:06:14 +0200 Subject: [PATCH 04/11] Fix --- docs/data/tree-view/rich-tree-view/selection/selection.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/data/tree-view/rich-tree-view/selection/selection.md b/docs/data/tree-view/rich-tree-view/selection/selection.md index f5b2be86c065..3024bf421fa4 100644 --- a/docs/data/tree-view/rich-tree-view/selection/selection.md +++ b/docs/data/tree-view/rich-tree-view/selection/selection.md @@ -32,7 +32,7 @@ Use the `multiSelect` prop to enable multi-selection. When the Tree View uses multi selection, you can select multiple items using the mouse in two ways: - To select multiple independent items, hold Ctrl (or Enter on macOS) and click the items. -- To select a range of items, clock on the first item of the range, then hold the Shift key while clicking on the last item of the range. +- To select a range of items, click on the first item of the range, then hold the Shift key while clicking on the last item of the range. You can also use the [keyboard shortcuts](/x/react-tree-view/accessibility/#on-multi-select-trees) to select items. ::: From 96ca9047061b41585f1633a514bbf242656d2273 Mon Sep 17 00:00:00 2001 From: delangle Date: Mon, 13 May 2024 11:17:34 +0200 Subject: [PATCH 05/11] Work --- .../rich-tree-view/selection/selection.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/docs/data/tree-view/rich-tree-view/selection/selection.md b/docs/data/tree-view/rich-tree-view/selection/selection.md index 3024bf421fa4..7b533754f037 100644 --- a/docs/data/tree-view/rich-tree-view/selection/selection.md +++ b/docs/data/tree-view/rich-tree-view/selection/selection.md @@ -74,3 +74,17 @@ Learn more about the _Controlled and uncontrolled_ pattern in the [React documen Use the `onItemSelectionToggle` prop if you want to react to an item selection change: {{"demo": "TrackItemSelectionToggle.js"}} + +## Parent / children selection relationship + +Automatically select an item when all of its children are selected and automatically select all children when the parent is selected. + +:::warning +This feature isn't implemented yet. It's coming. + +👍 Upvote [issue #12883](https://github.com/mui/mui-x/issues/4821) if you want to see it land faster. + +Don't hesitate to leave a comment on the same issue to influence what gets built. +Especially if you already have a use case for this component, +or if you are facing a pain point with your current solution. +::: From 610164e000f8f66e914a41c6992858f1f20653ff Mon Sep 17 00:00:00 2001 From: Flavien DELANGLE Date: Thu, 16 May 2024 13:50:25 +0200 Subject: [PATCH 06/11] Update docs/data/tree-view/rich-tree-view/selection/selection.md Co-authored-by: Nora <72460825+noraleonte@users.noreply.github.com> Signed-off-by: Flavien DELANGLE --- docs/data/tree-view/rich-tree-view/selection/selection.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/data/tree-view/rich-tree-view/selection/selection.md b/docs/data/tree-view/rich-tree-view/selection/selection.md index 7b533754f037..66d97f0e56fe 100644 --- a/docs/data/tree-view/rich-tree-view/selection/selection.md +++ b/docs/data/tree-view/rich-tree-view/selection/selection.md @@ -31,7 +31,7 @@ Use the `multiSelect` prop to enable multi-selection. :::success When the Tree View uses multi selection, you can select multiple items using the mouse in two ways: -- To select multiple independent items, hold Ctrl (or Enter on macOS) and click the items. +- To select multiple independent items, hold Ctrl (or ⌘ Command on macOS) and click the items. - To select a range of items, click on the first item of the range, then hold the Shift key while clicking on the last item of the range. You can also use the [keyboard shortcuts](/x/react-tree-view/accessibility/#on-multi-select-trees) to select items. From 147b6f1db78d2ab77c7facb970d132c252a47102 Mon Sep 17 00:00:00 2001 From: delangle Date: Mon, 20 May 2024 08:50:17 +0200 Subject: [PATCH 07/11] Add doc example --- .../ParentChildrenSelectionRelationship.js | 99 +++++++++++++++++++ .../ParentChildrenSelectionRelationship.tsx | 99 +++++++++++++++++++ ...tChildrenSelectionRelationship.tsx.preview | 9 ++ .../rich-tree-view/selection/selection.md | 6 ++ 4 files changed, 213 insertions(+) create mode 100644 docs/data/tree-view/rich-tree-view/selection/ParentChildrenSelectionRelationship.js create mode 100644 docs/data/tree-view/rich-tree-view/selection/ParentChildrenSelectionRelationship.tsx create mode 100644 docs/data/tree-view/rich-tree-view/selection/ParentChildrenSelectionRelationship.tsx.preview diff --git a/docs/data/tree-view/rich-tree-view/selection/ParentChildrenSelectionRelationship.js b/docs/data/tree-view/rich-tree-view/selection/ParentChildrenSelectionRelationship.js new file mode 100644 index 000000000000..056b2d2cb4bd --- /dev/null +++ b/docs/data/tree-view/rich-tree-view/selection/ParentChildrenSelectionRelationship.js @@ -0,0 +1,99 @@ +import * as React from 'react'; +import Box from '@mui/material/Box'; +import { RichTreeView } from '@mui/x-tree-view/RichTreeView'; + +import { useTreeViewApiRef } from '@mui/x-tree-view/hooks'; + +const MUI_X_PRODUCTS = [ + { + id: 'grid', + label: 'Data Grid', + children: [ + { id: 'grid-community', label: '@mui/x-data-grid' }, + { id: 'grid-pro', label: '@mui/x-data-grid-pro' }, + { id: 'grid-premium', label: '@mui/x-data-grid-premium' }, + ], + }, + { + id: 'pickers', + label: 'Date and Time Pickers', + children: [ + { id: 'pickers-community', label: '@mui/x-date-pickers' }, + { id: 'pickers-pro', label: '@mui/x-date-pickers-pro' }, + ], + }, + { + id: 'charts', + label: 'Charts', + children: [{ id: 'charts-community', label: '@mui/x-charts' }], + }, + { + id: 'tree-view', + label: 'Tree View', + children: [{ id: 'tree-view-community', label: '@mui/x-tree-view' }], + }, +]; + +function getItemDescendantsIds(item) { + const ids = []; + item.children?.forEach((child) => { + ids.push(child.id); + ids.push(...getItemDescendantsIds(child)); + }); + + return ids; +} + +export default function ParentChildrenSelectionRelationship() { + const [selectedItems, setSelectedItems] = React.useState([]); + const toggledItemRef = React.useRef({}); + const apiRef = useTreeViewApiRef(); + + const handleItemSelectionToggle = (event, itemId, isSelected) => { + toggledItemRef.current[itemId] = isSelected; + }; + + const handleSelectedItemsChange = (event, newSelectedItems) => { + setSelectedItems(newSelectedItems); + + // Select / unselect the children of the toggled item + const itemsToSelect = []; + const itemsToUnSelect = {}; + Object.entries(toggledItemRef.current).forEach(([itemId, isSelected]) => { + const item = apiRef.current.getItem(itemId); + if (isSelected) { + itemsToSelect.push(...getItemDescendantsIds(item)); + } else { + getItemDescendantsIds(item).forEach((descendantId) => { + itemsToUnSelect[descendantId] = true; + }); + } + }); + + const newSelectedItemsWithChildren = Array.from( + new Set( + [...newSelectedItems, ...itemsToSelect].filter( + (itemId) => !itemsToUnSelect[itemId], + ), + ), + ); + + setSelectedItems(newSelectedItemsWithChildren); + + toggledItemRef.current = {}; + }; + + return ( + + + + ); +} diff --git a/docs/data/tree-view/rich-tree-view/selection/ParentChildrenSelectionRelationship.tsx b/docs/data/tree-view/rich-tree-view/selection/ParentChildrenSelectionRelationship.tsx new file mode 100644 index 000000000000..709113d855bf --- /dev/null +++ b/docs/data/tree-view/rich-tree-view/selection/ParentChildrenSelectionRelationship.tsx @@ -0,0 +1,99 @@ +import * as React from 'react'; +import Box from '@mui/material/Box'; +import { RichTreeView } from '@mui/x-tree-view/RichTreeView'; +import { TreeViewBaseItem } from '@mui/x-tree-view/models'; +import {useTreeViewApiRef} from "@mui/x-tree-view/hooks"; + +const MUI_X_PRODUCTS: TreeViewBaseItem[] = [ + { + id: 'grid', + label: 'Data Grid', + children: [ + { id: 'grid-community', label: '@mui/x-data-grid' }, + { id: 'grid-pro', label: '@mui/x-data-grid-pro' }, + { id: 'grid-premium', label: '@mui/x-data-grid-premium' }, + ], + }, + { + id: 'pickers', + label: 'Date and Time Pickers', + children: [ + { id: 'pickers-community', label: '@mui/x-date-pickers' }, + { id: 'pickers-pro', label: '@mui/x-date-pickers-pro' }, + ], + }, + { + id: 'charts', + label: 'Charts', + children: [{ id: 'charts-community', label: '@mui/x-charts' }], + }, + { + id: 'tree-view', + label: 'Tree View', + children: [{ id: 'tree-view-community', label: '@mui/x-tree-view' }], + }, +]; + +function getItemDescendantsIds (item: TreeViewBaseItem) { + const ids: string[] = [] + item.children?.forEach(child => { + ids.push(child.id) + ids.push(...getItemDescendantsIds(child)) + }) + + return ids; +} + +export default function ParentChildrenSelectionRelationship() { + const [selectedItems, setSelectedItems] = React.useState([]); + const toggledItemRef = React.useRef<{ [itemId: string]: boolean}>({}) + const apiRef = useTreeViewApiRef() + + const handleItemSelectionToggle = ( + event: React.SyntheticEvent, + itemId: string, + isSelected: boolean, + ) => { + toggledItemRef.current[itemId] = isSelected + }; + + const handleSelectedItemsChange = ( + event: React.SyntheticEvent, + newSelectedItems: string[]) => { + setSelectedItems(newSelectedItems) + + // Select / unselect the children of the toggled item + const itemsToSelect: string[] = []; + const itemsToUnSelect: { [itemId: string]: boolean } = {}; + Object.entries(toggledItemRef.current).forEach(([itemId, isSelected]) => { + const item = apiRef.current!.getItem(itemId) + if (isSelected) { + itemsToSelect.push(...getItemDescendantsIds(item)) + } else { + getItemDescendantsIds(item).forEach(descendantId => { + itemsToUnSelect[descendantId] = true + }) + } + }) + + const newSelectedItemsWithChildren = Array.from(new Set([...newSelectedItems, ...itemsToSelect].filter(itemId => !itemsToUnSelect[itemId]))) + + setSelectedItems(newSelectedItemsWithChildren) + + toggledItemRef.current = {} + } + + return ( + + + + ); +} diff --git a/docs/data/tree-view/rich-tree-view/selection/ParentChildrenSelectionRelationship.tsx.preview b/docs/data/tree-view/rich-tree-view/selection/ParentChildrenSelectionRelationship.tsx.preview new file mode 100644 index 000000000000..a6b4733fc73e --- /dev/null +++ b/docs/data/tree-view/rich-tree-view/selection/ParentChildrenSelectionRelationship.tsx.preview @@ -0,0 +1,9 @@ + \ No newline at end of file diff --git a/docs/data/tree-view/rich-tree-view/selection/selection.md b/docs/data/tree-view/rich-tree-view/selection/selection.md index 7b533754f037..3a005c3d6317 100644 --- a/docs/data/tree-view/rich-tree-view/selection/selection.md +++ b/docs/data/tree-view/rich-tree-view/selection/selection.md @@ -88,3 +88,9 @@ Don't hesitate to leave a comment on the same issue to influence what gets built Especially if you already have a use case for this component, or if you are facing a pain point with your current solution. ::: + +If you cannot wait for the official implementation, +you can create your own custom solution using the `selectedItems`, +`onSelectedItemsChange` and `onItemSelectionToggle` props: + +{{"demo": "ParentChildrenSelectionRelationship.js"}} From 0e0444b32d1c1989649add91d48ad6443b76f433 Mon Sep 17 00:00:00 2001 From: delangle Date: Mon, 20 May 2024 08:53:25 +0200 Subject: [PATCH 08/11] Fix --- .../ParentChildrenSelectionRelationship.tsx | 165 +++++++++--------- .../rich-tree-view/selection/selection.md | 2 +- .../aggregation/gridAggregationInterfaces.ts | 2 +- scripts/README.md | 2 +- scripts/x-data-grid-premium.exports.json | 1 - 5 files changed, 89 insertions(+), 83 deletions(-) diff --git a/docs/data/tree-view/rich-tree-view/selection/ParentChildrenSelectionRelationship.tsx b/docs/data/tree-view/rich-tree-view/selection/ParentChildrenSelectionRelationship.tsx index 709113d855bf..c7ed6099696e 100644 --- a/docs/data/tree-view/rich-tree-view/selection/ParentChildrenSelectionRelationship.tsx +++ b/docs/data/tree-view/rich-tree-view/selection/ParentChildrenSelectionRelationship.tsx @@ -2,98 +2,105 @@ import * as React from 'react'; import Box from '@mui/material/Box'; import { RichTreeView } from '@mui/x-tree-view/RichTreeView'; import { TreeViewBaseItem } from '@mui/x-tree-view/models'; -import {useTreeViewApiRef} from "@mui/x-tree-view/hooks"; +import { useTreeViewApiRef } from '@mui/x-tree-view/hooks'; const MUI_X_PRODUCTS: TreeViewBaseItem[] = [ - { - id: 'grid', - label: 'Data Grid', - children: [ - { id: 'grid-community', label: '@mui/x-data-grid' }, - { id: 'grid-pro', label: '@mui/x-data-grid-pro' }, - { id: 'grid-premium', label: '@mui/x-data-grid-premium' }, - ], - }, - { - id: 'pickers', - label: 'Date and Time Pickers', - children: [ - { id: 'pickers-community', label: '@mui/x-date-pickers' }, - { id: 'pickers-pro', label: '@mui/x-date-pickers-pro' }, - ], - }, - { - id: 'charts', - label: 'Charts', - children: [{ id: 'charts-community', label: '@mui/x-charts' }], - }, - { - id: 'tree-view', - label: 'Tree View', - children: [{ id: 'tree-view-community', label: '@mui/x-tree-view' }], - }, + { + id: 'grid', + label: 'Data Grid', + children: [ + { id: 'grid-community', label: '@mui/x-data-grid' }, + { id: 'grid-pro', label: '@mui/x-data-grid-pro' }, + { id: 'grid-premium', label: '@mui/x-data-grid-premium' }, + ], + }, + { + id: 'pickers', + label: 'Date and Time Pickers', + children: [ + { id: 'pickers-community', label: '@mui/x-date-pickers' }, + { id: 'pickers-pro', label: '@mui/x-date-pickers-pro' }, + ], + }, + { + id: 'charts', + label: 'Charts', + children: [{ id: 'charts-community', label: '@mui/x-charts' }], + }, + { + id: 'tree-view', + label: 'Tree View', + children: [{ id: 'tree-view-community', label: '@mui/x-tree-view' }], + }, ]; -function getItemDescendantsIds (item: TreeViewBaseItem) { - const ids: string[] = [] - item.children?.forEach(child => { - ids.push(child.id) - ids.push(...getItemDescendantsIds(child)) - }) +function getItemDescendantsIds(item: TreeViewBaseItem) { + const ids: string[] = []; + item.children?.forEach((child) => { + ids.push(child.id); + ids.push(...getItemDescendantsIds(child)); + }); - return ids; + return ids; } export default function ParentChildrenSelectionRelationship() { - const [selectedItems, setSelectedItems] = React.useState([]); - const toggledItemRef = React.useRef<{ [itemId: string]: boolean}>({}) - const apiRef = useTreeViewApiRef() + const [selectedItems, setSelectedItems] = React.useState([]); + const toggledItemRef = React.useRef<{ [itemId: string]: boolean }>({}); + const apiRef = useTreeViewApiRef(); - const handleItemSelectionToggle = ( - event: React.SyntheticEvent, - itemId: string, - isSelected: boolean, - ) => { - toggledItemRef.current[itemId] = isSelected - }; + const handleItemSelectionToggle = ( + event: React.SyntheticEvent, + itemId: string, + isSelected: boolean, + ) => { + toggledItemRef.current[itemId] = isSelected; + }; - const handleSelectedItemsChange = ( - event: React.SyntheticEvent, - newSelectedItems: string[]) => { - setSelectedItems(newSelectedItems) + const handleSelectedItemsChange = ( + event: React.SyntheticEvent, + newSelectedItems: string[], + ) => { + setSelectedItems(newSelectedItems); - // Select / unselect the children of the toggled item - const itemsToSelect: string[] = []; - const itemsToUnSelect: { [itemId: string]: boolean } = {}; - Object.entries(toggledItemRef.current).forEach(([itemId, isSelected]) => { - const item = apiRef.current!.getItem(itemId) - if (isSelected) { - itemsToSelect.push(...getItemDescendantsIds(item)) - } else { - getItemDescendantsIds(item).forEach(descendantId => { - itemsToUnSelect[descendantId] = true - }) - } - }) + // Select / unselect the children of the toggled item + const itemsToSelect: string[] = []; + const itemsToUnSelect: { [itemId: string]: boolean } = {}; + Object.entries(toggledItemRef.current).forEach(([itemId, isSelected]) => { + const item = apiRef.current!.getItem(itemId); + if (isSelected) { + itemsToSelect.push(...getItemDescendantsIds(item)); + } else { + getItemDescendantsIds(item).forEach((descendantId) => { + itemsToUnSelect[descendantId] = true; + }); + } + }); - const newSelectedItemsWithChildren = Array.from(new Set([...newSelectedItems, ...itemsToSelect].filter(itemId => !itemsToUnSelect[itemId]))) + const newSelectedItemsWithChildren = Array.from( + new Set( + [...newSelectedItems, ...itemsToSelect].filter( + (itemId) => !itemsToUnSelect[itemId], + ), + ), + ); - setSelectedItems(newSelectedItemsWithChildren) + setSelectedItems(newSelectedItemsWithChildren); - toggledItemRef.current = {} - } + toggledItemRef.current = {}; + }; - return ( - - - - ); + return ( + + + + ); } diff --git a/docs/data/tree-view/rich-tree-view/selection/selection.md b/docs/data/tree-view/rich-tree-view/selection/selection.md index 5c7d31a1f532..d58f37d61b5d 100644 --- a/docs/data/tree-view/rich-tree-view/selection/selection.md +++ b/docs/data/tree-view/rich-tree-view/selection/selection.md @@ -89,7 +89,7 @@ Especially if you already have a use case for this component, or if you are facing a pain point with your current solution. ::: -If you cannot wait for the official implementation, +If you cannot wait for the official implementation, you can create your own custom solution using the `selectedItems`, `onSelectedItemsChange` and `onItemSelectionToggle` props: 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 212bdef1a008..82ecbce2fc1c 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 @@ -74,7 +74,7 @@ export interface GridAggregationFunction { getCellValue?: (params: GridAggregationGetCellValueParams) => V; } -export interface GridAggregationParams { +interface GridAggregationParams { values: (V | undefined)[]; groupId: GridRowId; field: GridColDef['field']; diff --git a/scripts/README.md b/scripts/README.md index 66cf01e5c209..930642d967a5 100644 --- a/scripts/README.md +++ b/scripts/README.md @@ -30,7 +30,7 @@ pnpm release:changelog > `` > This string needs to stay where it gets inserted for the automated discord announcement to work. -You can also provide the github token by setting `process.env.GITHUB_TOKEN` variable. +You can also provide the GitHub token by setting `process.env.GITHUB_TOKEN` variable. In case of a problem, another method to generate the changelog is available at the end of this page. diff --git a/scripts/x-data-grid-premium.exports.json b/scripts/x-data-grid-premium.exports.json index b3de7ed13349..9723176f8754 100644 --- a/scripts/x-data-grid-premium.exports.json +++ b/scripts/x-data-grid-premium.exports.json @@ -94,7 +94,6 @@ { "name": "gridAggregationLookupSelector", "kind": "Variable" }, { "name": "GridAggregationModel", "kind": "TypeAlias" }, { "name": "gridAggregationModelSelector", "kind": "Variable" }, - { "name": "GridAggregationParams", "kind": "Interface" }, { "name": "GridAggregationPosition", "kind": "TypeAlias" }, { "name": "GridAggregationRule", "kind": "Interface" }, { "name": "GridAggregationRules", "kind": "TypeAlias" }, From 2aee68efcf2338a3a0af5dbfac55ba90772641a3 Mon Sep 17 00:00:00 2001 From: delangle Date: Mon, 20 May 2024 09:01:48 +0200 Subject: [PATCH 09/11] Fix --- ...ParentChildrenSelectionRelationship.tsx.preview | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/data/tree-view/rich-tree-view/selection/ParentChildrenSelectionRelationship.tsx.preview b/docs/data/tree-view/rich-tree-view/selection/ParentChildrenSelectionRelationship.tsx.preview index a6b4733fc73e..6fa38db9c231 100644 --- a/docs/data/tree-view/rich-tree-view/selection/ParentChildrenSelectionRelationship.tsx.preview +++ b/docs/data/tree-view/rich-tree-view/selection/ParentChildrenSelectionRelationship.tsx.preview @@ -1,9 +1,9 @@ \ No newline at end of file From f2916523c040b0e3211a627acdd7acaea838e49a Mon Sep 17 00:00:00 2001 From: delangle Date: Mon, 20 May 2024 09:18:35 +0200 Subject: [PATCH 10/11] Add SimpleTreeView doc --- .../selection/SIngleSelectionTreeView.js | 41 ++++++++++++++++++ .../selection/SIngleSelectionTreeView.tsx | 42 +++++++++++++++++++ .../SIngleSelectionTreeView.tsx.preview | 1 + .../simple-tree-view/selection/selection.md | 22 +++++++++- 4 files changed, 105 insertions(+), 1 deletion(-) create mode 100644 docs/data/tree-view/simple-tree-view/selection/SIngleSelectionTreeView.js create mode 100644 docs/data/tree-view/simple-tree-view/selection/SIngleSelectionTreeView.tsx create mode 100644 docs/data/tree-view/simple-tree-view/selection/SIngleSelectionTreeView.tsx.preview diff --git a/docs/data/tree-view/simple-tree-view/selection/SIngleSelectionTreeView.js b/docs/data/tree-view/simple-tree-view/selection/SIngleSelectionTreeView.js new file mode 100644 index 000000000000..60caf9c53586 --- /dev/null +++ b/docs/data/tree-view/simple-tree-view/selection/SIngleSelectionTreeView.js @@ -0,0 +1,41 @@ +import * as React from 'react'; +import Box from '@mui/material/Box'; +import { RichTreeView } from '@mui/x-tree-view/RichTreeView'; + +const MUI_X_PRODUCTS = [ + { + id: 'grid', + label: 'Data Grid', + children: [ + { id: 'grid-community', label: '@mui/x-data-grid' }, + { id: 'grid-pro', label: '@mui/x-data-grid-pro' }, + { id: 'grid-premium', label: '@mui/x-data-grid-premium' }, + ], + }, + { + id: 'pickers', + label: 'Date and Time Pickers', + children: [ + { id: 'pickers-community', label: '@mui/x-date-pickers' }, + { id: 'pickers-pro', label: '@mui/x-date-pickers-pro' }, + ], + }, + { + id: 'charts', + label: 'Charts', + children: [{ id: 'charts-community', label: '@mui/x-charts' }], + }, + { + id: 'tree-view', + label: 'Tree View', + children: [{ id: 'tree-view-community', label: '@mui/x-tree-view' }], + }, +]; + +export default function SingleSelectTreeView() { + return ( + + + + ); +} diff --git a/docs/data/tree-view/simple-tree-view/selection/SIngleSelectionTreeView.tsx b/docs/data/tree-view/simple-tree-view/selection/SIngleSelectionTreeView.tsx new file mode 100644 index 000000000000..fbd000d8af63 --- /dev/null +++ b/docs/data/tree-view/simple-tree-view/selection/SIngleSelectionTreeView.tsx @@ -0,0 +1,42 @@ +import * as React from 'react'; +import Box from '@mui/material/Box'; +import { RichTreeView } from '@mui/x-tree-view/RichTreeView'; +import { TreeViewBaseItem } from '@mui/x-tree-view/models'; + +const MUI_X_PRODUCTS: TreeViewBaseItem[] = [ + { + id: 'grid', + label: 'Data Grid', + children: [ + { id: 'grid-community', label: '@mui/x-data-grid' }, + { id: 'grid-pro', label: '@mui/x-data-grid-pro' }, + { id: 'grid-premium', label: '@mui/x-data-grid-premium' }, + ], + }, + { + id: 'pickers', + label: 'Date and Time Pickers', + children: [ + { id: 'pickers-community', label: '@mui/x-date-pickers' }, + { id: 'pickers-pro', label: '@mui/x-date-pickers-pro' }, + ], + }, + { + id: 'charts', + label: 'Charts', + children: [{ id: 'charts-community', label: '@mui/x-charts' }], + }, + { + id: 'tree-view', + label: 'Tree View', + children: [{ id: 'tree-view-community', label: '@mui/x-tree-view' }], + }, +]; + +export default function SingleSelectTreeView() { + return ( + + + + ); +} diff --git a/docs/data/tree-view/simple-tree-view/selection/SIngleSelectionTreeView.tsx.preview b/docs/data/tree-view/simple-tree-view/selection/SIngleSelectionTreeView.tsx.preview new file mode 100644 index 000000000000..19ab6390267f --- /dev/null +++ b/docs/data/tree-view/simple-tree-view/selection/SIngleSelectionTreeView.tsx.preview @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/data/tree-view/simple-tree-view/selection/selection.md b/docs/data/tree-view/simple-tree-view/selection/selection.md index 18337196bec7..434a4284a0a2 100644 --- a/docs/data/tree-view/simple-tree-view/selection/selection.md +++ b/docs/data/tree-view/simple-tree-view/selection/selection.md @@ -11,12 +11,32 @@ waiAria: https://www.w3.org/WAI/ARIA/apg/patterns/treeview/

Learn how to enable item selection for the Tree View component.

+## Single selection + +By default, the Tree View allows selecting a single item. + +{{"demo": "SingleSelectTreeView.js"}} + +:::success +When the Tree View uses single selection, you can select an item by clicking it, +or using the [keyboard shortcuts](/x/react-tree-view/accessibility/#on-single-select-trees). +::: + ## Multi selection -Apply the `multiSelect` prop on the Tree View to let users select multiple items. +Use the `multiSelect` prop to enable multi-selection. {{"demo": "MultiSelectTreeView.js"}} +:::success +When the Tree View uses multi selection, you can select multiple items using the mouse in two ways: + +- To select multiple independent items, hold Ctrl (or ⌘ Command on macOS) and click the items. +- To select a range of items, click on the first item of the range, then hold the Shift key while clicking on the last item of the range. + +You can also use the [keyboard shortcuts](/x/react-tree-view/accessibility/#on-multi-select-trees) to select items. +::: + ## Disable selection Use the `disableSelection` prop if you don't want your items to be selectable: From 2578e97c7c0a918a93cfcc087fcc23179232df86 Mon Sep 17 00:00:00 2001 From: delangle Date: Mon, 20 May 2024 09:25:22 +0200 Subject: [PATCH 11/11] Fix --- .../{SIngleSelectionTreeView.js => SingleSelectTreeView.js} | 0 .../{SIngleSelectionTreeView.tsx => SingleSelectTreeView.tsx} | 0 ...ctionTreeView.tsx.preview => SingleSelectTreeView.tsx.preview} | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename docs/data/tree-view/simple-tree-view/selection/{SIngleSelectionTreeView.js => SingleSelectTreeView.js} (100%) rename docs/data/tree-view/simple-tree-view/selection/{SIngleSelectionTreeView.tsx => SingleSelectTreeView.tsx} (100%) rename docs/data/tree-view/simple-tree-view/selection/{SIngleSelectionTreeView.tsx.preview => SingleSelectTreeView.tsx.preview} (100%) diff --git a/docs/data/tree-view/simple-tree-view/selection/SIngleSelectionTreeView.js b/docs/data/tree-view/simple-tree-view/selection/SingleSelectTreeView.js similarity index 100% rename from docs/data/tree-view/simple-tree-view/selection/SIngleSelectionTreeView.js rename to docs/data/tree-view/simple-tree-view/selection/SingleSelectTreeView.js diff --git a/docs/data/tree-view/simple-tree-view/selection/SIngleSelectionTreeView.tsx b/docs/data/tree-view/simple-tree-view/selection/SingleSelectTreeView.tsx similarity index 100% rename from docs/data/tree-view/simple-tree-view/selection/SIngleSelectionTreeView.tsx rename to docs/data/tree-view/simple-tree-view/selection/SingleSelectTreeView.tsx diff --git a/docs/data/tree-view/simple-tree-view/selection/SIngleSelectionTreeView.tsx.preview b/docs/data/tree-view/simple-tree-view/selection/SingleSelectTreeView.tsx.preview similarity index 100% rename from docs/data/tree-view/simple-tree-view/selection/SIngleSelectionTreeView.tsx.preview rename to docs/data/tree-view/simple-tree-view/selection/SingleSelectTreeView.tsx.preview