From fc6059a2af9cea0af3e26bf9f1827235b4e436d2 Mon Sep 17 00:00:00 2001 From: Andrew Cherniavskii Date: Mon, 7 Oct 2024 23:26:23 +0200 Subject: [PATCH] [docs] Add collapsible column groups demo (#14818) --- .../column-groups/CollapsibleColumnGroups.js | 123 +++++++++++++++++ .../column-groups/CollapsibleColumnGroups.tsx | 129 ++++++++++++++++++ .../CollapsibleColumnGroups.tsx.preview | 7 + .../data-grid/column-groups/column-groups.md | 6 + 4 files changed, 265 insertions(+) create mode 100644 docs/data/data-grid/column-groups/CollapsibleColumnGroups.js create mode 100644 docs/data/data-grid/column-groups/CollapsibleColumnGroups.tsx create mode 100644 docs/data/data-grid/column-groups/CollapsibleColumnGroups.tsx.preview diff --git a/docs/data/data-grid/column-groups/CollapsibleColumnGroups.js b/docs/data/data-grid/column-groups/CollapsibleColumnGroups.js new file mode 100644 index 000000000000..8d5b2e8f2c57 --- /dev/null +++ b/docs/data/data-grid/column-groups/CollapsibleColumnGroups.js @@ -0,0 +1,123 @@ +import * as React from 'react'; +import { styled } from '@mui/material/styles'; +import Box from '@mui/material/Box'; +import IconButton from '@mui/material/IconButton'; +import { + DataGrid, + gridColumnVisibilityModelSelector, + useGridApiContext, +} from '@mui/x-data-grid'; +import KeyboardArrowRightIcon from '@mui/icons-material/KeyboardArrowRight'; +import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown'; + +const COLLAPSIBLE_COLUMN_GROUPS = { + character: ['lastName', 'age'], + naming: ['lastName'], +}; + +const ColumnGroupRoot = styled('div')({ + overflow: 'hidden', + display: 'flex', + alignItems: 'center', +}); + +const ColumnGroupTitle = styled('span')({ + overflow: 'hidden', + textOverflow: 'ellipsis', +}); + +function CollapsibleHeaderGroup({ groupId, headerName }) { + const apiRef = useGridApiContext(); + const columnVisibilityModel = gridColumnVisibilityModelSelector(apiRef); + + if (!groupId) { + return null; + } + + const isCollapsible = Boolean(COLLAPSIBLE_COLUMN_GROUPS[groupId]); + const isGroupCollapsed = COLLAPSIBLE_COLUMN_GROUPS[groupId].every( + (field) => columnVisibilityModel[field] === false, + ); + + return ( + + {headerName ?? groupId}{' '} + {isCollapsible && ( + { + const newModel = { ...columnVisibilityModel }; + COLLAPSIBLE_COLUMN_GROUPS[groupId].forEach((field) => { + newModel[field] = !!isGroupCollapsed; + }); + apiRef.current.setColumnVisibilityModel(newModel); + }} + > + {isGroupCollapsed ? ( + + ) : ( + + )} + + )} + + ); +} + +const columnGroupingModel = [ + { + groupId: 'Internal', + description: '', + children: [{ field: 'id' }], + }, + { + groupId: 'character', + description: 'Information about the character', + headerName: 'Basic info', + renderHeaderGroup: (params) => { + return ; + }, + children: [ + { + groupId: 'naming', + headerName: 'Names', + renderHeaderGroup: (params) => , + children: [{ field: 'lastName' }, { field: 'firstName' }], + }, + { field: 'age' }, + ], + }, +]; + +const columns = [ + { field: 'id', headerName: 'ID', width: 150 }, + { field: 'firstName', headerName: 'First name', width: 150 }, + { field: 'lastName', headerName: 'Last name', width: 150 }, + { field: 'age', headerName: 'Age', type: 'number', width: 110 }, +]; + +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: 5, lastName: 'Targaryen', firstName: 'Daenerys', age: null }, + { id: 6, lastName: 'Melisandre', firstName: null, age: 150 }, + { id: 7, lastName: 'Clifford', firstName: 'Ferrara', age: 44 }, + { id: 8, lastName: 'Frances', firstName: 'Rossini', age: 36 }, + { id: 9, lastName: 'Roxie', firstName: 'Harvey', age: 65 }, +]; + +export default function CollapsibleColumnGroups() { + return ( + + + + ); +} diff --git a/docs/data/data-grid/column-groups/CollapsibleColumnGroups.tsx b/docs/data/data-grid/column-groups/CollapsibleColumnGroups.tsx new file mode 100644 index 000000000000..34d5659fd2da --- /dev/null +++ b/docs/data/data-grid/column-groups/CollapsibleColumnGroups.tsx @@ -0,0 +1,129 @@ +import * as React from 'react'; +import { styled } from '@mui/material/styles'; +import Box from '@mui/material/Box'; +import IconButton from '@mui/material/IconButton'; +import { + DataGrid, + GridColDef, + GridColumnGroupHeaderParams, + GridColumnGroupingModel, + gridColumnVisibilityModelSelector, + useGridApiContext, +} from '@mui/x-data-grid'; +import KeyboardArrowRightIcon from '@mui/icons-material/KeyboardArrowRight'; +import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown'; + +const COLLAPSIBLE_COLUMN_GROUPS: Record> = { + character: ['lastName', 'age'], + naming: ['lastName'], +}; + +const ColumnGroupRoot = styled('div')({ + overflow: 'hidden', + display: 'flex', + alignItems: 'center', +}); + +const ColumnGroupTitle = styled('span')({ + overflow: 'hidden', + textOverflow: 'ellipsis', +}); + +function CollapsibleHeaderGroup({ + groupId, + headerName, +}: GridColumnGroupHeaderParams) { + const apiRef = useGridApiContext(); + const columnVisibilityModel = gridColumnVisibilityModelSelector(apiRef); + + if (!groupId) { + return null; + } + + const isCollapsible = Boolean(COLLAPSIBLE_COLUMN_GROUPS[groupId]); + const isGroupCollapsed = COLLAPSIBLE_COLUMN_GROUPS[groupId].every( + (field) => columnVisibilityModel[field] === false, + ); + + return ( + + {headerName ?? groupId}{' '} + {isCollapsible && ( + { + const newModel = { ...columnVisibilityModel }; + COLLAPSIBLE_COLUMN_GROUPS[groupId].forEach((field) => { + newModel[field] = !!isGroupCollapsed; + }); + apiRef.current.setColumnVisibilityModel(newModel); + }} + > + {isGroupCollapsed ? ( + + ) : ( + + )} + + )} + + ); +} + +const columnGroupingModel: GridColumnGroupingModel = [ + { + groupId: 'Internal', + description: '', + children: [{ field: 'id' }], + }, + { + groupId: 'character', + description: 'Information about the character', + headerName: 'Basic info', + renderHeaderGroup: (params) => { + return ; + }, + children: [ + { + groupId: 'naming', + headerName: 'Names', + renderHeaderGroup: (params) => , + children: [{ field: 'lastName' }, { field: 'firstName' }], + }, + { field: 'age' }, + ], + }, +]; + +const columns: GridColDef[] = [ + { field: 'id', headerName: 'ID', width: 150 }, + { field: 'firstName', headerName: 'First name', width: 150 }, + { field: 'lastName', headerName: 'Last name', width: 150 }, + { field: 'age', headerName: 'Age', type: 'number', width: 110 }, +]; + +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: 5, lastName: 'Targaryen', firstName: 'Daenerys', age: null }, + { id: 6, lastName: 'Melisandre', firstName: null, age: 150 }, + { id: 7, lastName: 'Clifford', firstName: 'Ferrara', age: 44 }, + { id: 8, lastName: 'Frances', firstName: 'Rossini', age: 36 }, + { id: 9, lastName: 'Roxie', firstName: 'Harvey', age: 65 }, +]; + +export default function CollapsibleColumnGroups() { + return ( + + + + ); +} diff --git a/docs/data/data-grid/column-groups/CollapsibleColumnGroups.tsx.preview b/docs/data/data-grid/column-groups/CollapsibleColumnGroups.tsx.preview new file mode 100644 index 000000000000..296f04ced305 --- /dev/null +++ b/docs/data/data-grid/column-groups/CollapsibleColumnGroups.tsx.preview @@ -0,0 +1,7 @@ + \ No newline at end of file diff --git a/docs/data/data-grid/column-groups/column-groups.md b/docs/data/data-grid/column-groups/column-groups.md index 92df9c0b5e10..35f2c3cdb12c 100644 --- a/docs/data/data-grid/column-groups/column-groups.md +++ b/docs/data/data-grid/column-groups/column-groups.md @@ -74,6 +74,12 @@ In the example below, the `Full name` column group can be divided, but not other {{"demo": "BreakingGroupDemo.js", "disableAd": true, "bg": "inline"}} +## Collapsible column groups + +The demo below uses [`renderHeaderGroup`](/x/react-data-grid/column-groups/#customize-column-group) to add a button to collapse/expand the column group. + +{{"demo": "CollapsibleColumnGroups.js", "bg": "inline"}} + ## Manage group visibility 🚧 The column group should allow to switch between an extended/collapsed view which hide/show some columns.