From f009f0b4eb76e986b4fc016360454146e614ac08 Mon Sep 17 00:00:00 2001 From: Khoa Nguyen Date: Sat, 6 Jan 2024 11:37:29 +0700 Subject: [PATCH 1/9] example: feat column grouping with single column --- .../features/ColumnGrouping.stories.tsx | 96 ++++++++++++++++++- 1 file changed, 95 insertions(+), 1 deletion(-) diff --git a/packages/material-react-table/stories/features/ColumnGrouping.stories.tsx b/packages/material-react-table/stories/features/ColumnGrouping.stories.tsx index 9fde8034d..d92ae0a0a 100644 --- a/packages/material-react-table/stories/features/ColumnGrouping.stories.tsx +++ b/packages/material-react-table/stories/features/ColumnGrouping.stories.tsx @@ -1,4 +1,7 @@ -import { useEffect, useMemo, useState } from 'react'; +import { type ReactNode, useEffect, useMemo, useState } from 'react'; +import IconButton from '@mui/material/IconButton'; +import Stack from '@mui/material/Stack'; +import Typography from '@mui/material/Typography'; import { type MRT_Column, type MRT_ColumnDef, @@ -281,3 +284,94 @@ export const GroupingAndDraggingWithSomeDisabledGrouping = () => { /> ); }; + +export const GroupingWithSingleColumn = () => { + const _columns = useMemo[]>( + () => [ + { + AggregatedCell: ({ row, table }) => { + const { + options: { + icons: { ExpandMoreIcon }, + }, + } = table; + + if (!row.groupingColumnId || !row.groupingValue) { + return null; + } + + return ( + + row.toggleExpanded(!row.getIsExpanded())} + size="small" + > + + + {row.groupingValue as ReactNode} + + ); + }, + accessorKey: 'group', + columnDefType: 'display', + header: 'Group', + muiTableBodyCellProps: ({ row }) => { + return { + sx: { + justifyContent: 'left', + pl: `calc(${row.depth * 16}px)`, + textAlign: 'left', + }, + }; + }, + visibleInShowHideMenu: false, + }, + { + accessorKey: 'firstName', + header: 'First Name', + }, + { + accessorKey: 'lastName', + header: 'Last Name', + }, + { + accessorKey: 'gender', + header: 'Gender', + }, + { + accessorKey: 'city', + header: 'City', + }, + { + accessorKey: 'state', + header: 'State', + }, + ], + [], + ); + + return ( + + ); +}; From 1295f8b5851438ad0ba4a47f7b355549f277368e Mon Sep 17 00:00:00 2001 From: Khoa Nguyen Date: Sat, 6 Jan 2024 11:53:37 +0700 Subject: [PATCH 2/9] add: add background color by depth --- .../stories/features/ColumnGrouping.stories.tsx | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/packages/material-react-table/stories/features/ColumnGrouping.stories.tsx b/packages/material-react-table/stories/features/ColumnGrouping.stories.tsx index d92ae0a0a..ea8f2b6a1 100644 --- a/packages/material-react-table/stories/features/ColumnGrouping.stories.tsx +++ b/packages/material-react-table/stories/features/ColumnGrouping.stories.tsx @@ -5,6 +5,7 @@ import Typography from '@mui/material/Typography'; import { type MRT_Column, type MRT_ColumnDef, + type MRT_Row, MaterialReactTable, } from '../../src'; import { faker } from '@faker-js/faker'; @@ -372,6 +373,18 @@ export const GroupingWithSingleColumn = () => { density: 'compact', grouping: ['gender', 'state'], }} + muiTableBodyRowProps={({ row }) => { + return { + sx: { + bgcolor: + row.groupingColumnId === 'gender' + ? 'darkgreen' + : row.groupingColumnId === 'state' + ? 'slategrey' + : 'inherit', + }, + }; + }} /> ); }; From f90dae54cf4e6737f79bc6863974b4bfc4ccb3d9 Mon Sep 17 00:00:00 2001 From: Khoa Nguyen Date: Sat, 6 Jan 2024 14:17:29 +0700 Subject: [PATCH 3/9] feat: implement grouping with single group column --- .../src/hooks/useMRT_DisplayColumns.tsx | 27 ++++++++++-- packages/material-react-table/src/types.ts | 1 + .../features/ColumnGrouping.stories.tsx | 44 +++++++++++++++++++ 3 files changed, 68 insertions(+), 4 deletions(-) diff --git a/packages/material-react-table/src/hooks/useMRT_DisplayColumns.tsx b/packages/material-react-table/src/hooks/useMRT_DisplayColumns.tsx index 9926b880c..9b74d5407 100644 --- a/packages/material-react-table/src/hooks/useMRT_DisplayColumns.tsx +++ b/packages/material-react-table/src/hooks/useMRT_DisplayColumns.tsx @@ -56,6 +56,7 @@ export const useMRT_DisplayColumns = ( tableOptions.enableEditing, tableOptions.enableExpandAll, tableOptions.enableExpanding, + tableOptions.enableGroupingSingleColumn, tableOptions.enableGrouping, tableOptions.enableRowActions, tableOptions.enableRowDragging, @@ -158,10 +159,28 @@ function makeRowExpandColumn( showExpandColumn(tableOptions, tableOptions.state?.grouping ?? grouping) ) { return { - Cell: ({ row, table }) => , - Header: tableOptions.enableExpandAll - ? ({ table }) => - : undefined, + Cell: ({ row, table }) => { + return ( + <> + + {tableOptions?.enableGroupingSingleColumn && + tableOptions?.groupedColumnMode === 'remove' && + row.groupingValue} + + ); + }, + Header: ({ table }) => { + return ( + <> + {tableOptions.enableExpandAll && ( + + )} + {tableOptions?.enableGroupingSingleColumn && + tableOptions?.groupedColumnMode === 'remove' && + 'Group'} + + ); + }, ...defaultDisplayColumnProps(tableOptions, id, 'expand'), }; } diff --git a/packages/material-react-table/src/types.ts b/packages/material-react-table/src/types.ts index 31f150d37..159a9d1a1 100644 --- a/packages/material-react-table/src/types.ts +++ b/packages/material-react-table/src/types.ts @@ -808,6 +808,7 @@ export type MRT_TableOptions = Omit< enableFullScreenToggle?: boolean; enableGlobalFilterModes?: boolean; enableGlobalFilterRankedResults?: boolean; + enableGroupingSingleColumn?: boolean; enablePagination?: boolean; enableRowActions?: boolean; enableRowDragging?: boolean; diff --git a/packages/material-react-table/stories/features/ColumnGrouping.stories.tsx b/packages/material-react-table/stories/features/ColumnGrouping.stories.tsx index ea8f2b6a1..7009bf542 100644 --- a/packages/material-react-table/stories/features/ColumnGrouping.stories.tsx +++ b/packages/material-react-table/stories/features/ColumnGrouping.stories.tsx @@ -388,3 +388,47 @@ export const GroupingWithSingleColumn = () => { /> ); }; + +export const GroupingWithSingleColumnTest = () => { + const _columns = useMemo[]>( + () => [ + { + accessorKey: 'firstName', + header: 'First Name', + }, + { + accessorKey: 'lastName', + header: 'Last Name', + }, + { + accessorKey: 'gender', + header: 'Gender', + }, + { + accessorKey: 'city', + header: 'City', + }, + { + accessorKey: 'state', + header: 'State', + }, + ], + [], + ); + + return ( + + ); +}; From ec5fd0dcb44da5c181aa6d2afb7e3c7bf038e87e Mon Sep 17 00:00:00 2001 From: Khoa Nguyen Date: Sat, 6 Jan 2024 14:51:06 +0700 Subject: [PATCH 4/9] feat: add showOpenedGroup props --- .../src/hooks/useMRT_DisplayColumns.tsx | 7 +++++++ packages/material-react-table/src/types.ts | 1 + .../stories/features/ColumnGrouping.stories.tsx | 1 + 3 files changed, 9 insertions(+) diff --git a/packages/material-react-table/src/hooks/useMRT_DisplayColumns.tsx b/packages/material-react-table/src/hooks/useMRT_DisplayColumns.tsx index 9b74d5407..e3c755013 100644 --- a/packages/material-react-table/src/hooks/useMRT_DisplayColumns.tsx +++ b/packages/material-react-table/src/hooks/useMRT_DisplayColumns.tsx @@ -166,6 +166,13 @@ function makeRowExpandColumn( {tableOptions?.enableGroupingSingleColumn && tableOptions?.groupedColumnMode === 'remove' && row.groupingValue} + {tableOptions?.enableGroupingSingleColumn && + tableOptions?.groupedColumnMode === 'remove' && + tableOptions?.showOpenedGroup && + !row.getCanExpand() && + row.original?.[ + table.getState().grouping[table.getState().grouping.length - 1] + ]} ); }, diff --git a/packages/material-react-table/src/types.ts b/packages/material-react-table/src/types.ts index 159a9d1a1..0b77adba8 100644 --- a/packages/material-react-table/src/types.ts +++ b/packages/material-react-table/src/types.ts @@ -1203,5 +1203,6 @@ export type MRT_TableOptions = Omit< /** * Manage state externally any way you want, then pass it back into MRT. */ + showOpenedGroup?: boolean; state?: Partial>; }; diff --git a/packages/material-react-table/stories/features/ColumnGrouping.stories.tsx b/packages/material-react-table/stories/features/ColumnGrouping.stories.tsx index 7009bf542..9fe3153c6 100644 --- a/packages/material-react-table/stories/features/ColumnGrouping.stories.tsx +++ b/packages/material-react-table/stories/features/ColumnGrouping.stories.tsx @@ -429,6 +429,7 @@ export const GroupingWithSingleColumnTest = () => { density: 'compact', grouping: ['gender', 'state'], }} + showOpenedGroup /> ); }; From 4c22020e55040e567e000d24cea13f9e481a484f Mon Sep 17 00:00:00 2001 From: Khoa Nguyen Date: Sat, 6 Jan 2024 15:03:50 +0700 Subject: [PATCH 5/9] feat: add addColumnToLeafNode state --- .../material-react-table/src/hooks/useMRT_DisplayColumns.tsx | 5 ++++- packages/material-react-table/src/types.ts | 1 + .../stories/features/ColumnGrouping.stories.tsx | 1 + 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/material-react-table/src/hooks/useMRT_DisplayColumns.tsx b/packages/material-react-table/src/hooks/useMRT_DisplayColumns.tsx index e3c755013..fb3387972 100644 --- a/packages/material-react-table/src/hooks/useMRT_DisplayColumns.tsx +++ b/packages/material-react-table/src/hooks/useMRT_DisplayColumns.tsx @@ -171,7 +171,10 @@ function makeRowExpandColumn( tableOptions?.showOpenedGroup && !row.getCanExpand() && row.original?.[ - table.getState().grouping[table.getState().grouping.length - 1] + table.getState().addColumnToLeafNode ?? + table.getState().grouping[ + table.getState().grouping.length - 1 + ] ]} ); diff --git a/packages/material-react-table/src/types.ts b/packages/material-react-table/src/types.ts index 0b77adba8..3b6c20b77 100644 --- a/packages/material-react-table/src/types.ts +++ b/packages/material-react-table/src/types.ts @@ -338,6 +338,7 @@ export type MRT_DefinedTableOptions = }; export type MRT_TableState = TableState & { + addColumnToLeafNode?: string; columnFilterFns: MRT_ColumnFilterFnsState; creatingRow: MRT_Row | null; density: MRT_DensityState; diff --git a/packages/material-react-table/stories/features/ColumnGrouping.stories.tsx b/packages/material-react-table/stories/features/ColumnGrouping.stories.tsx index 9fe3153c6..aa8bd3683 100644 --- a/packages/material-react-table/stories/features/ColumnGrouping.stories.tsx +++ b/packages/material-react-table/stories/features/ColumnGrouping.stories.tsx @@ -426,6 +426,7 @@ export const GroupingWithSingleColumnTest = () => { enableGroupingSingleColumn groupedColumnMode="remove" initialState={{ + addColumnToLeafNode: 'firstName', density: 'compact', grouping: ['gender', 'state'], }} From 01ba7cf14a4e9c65311339c80c08d4090dd6add1 Mon Sep 17 00:00:00 2001 From: Khoa Nguyen Date: Sat, 6 Jan 2024 15:16:43 +0700 Subject: [PATCH 6/9] feat: add subRows length --- .../src/hooks/useMRT_DisplayColumns.tsx | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/packages/material-react-table/src/hooks/useMRT_DisplayColumns.tsx b/packages/material-react-table/src/hooks/useMRT_DisplayColumns.tsx index fb3387972..fc21924bc 100644 --- a/packages/material-react-table/src/hooks/useMRT_DisplayColumns.tsx +++ b/packages/material-react-table/src/hooks/useMRT_DisplayColumns.tsx @@ -160,14 +160,18 @@ function makeRowExpandColumn( ) { return { Cell: ({ row, table }) => { + const isGroupedSingleColumn = + tableOptions?.enableGroupingSingleColumn && + tableOptions?.groupedColumnMode === 'remove'; + return ( <> - {tableOptions?.enableGroupingSingleColumn && - tableOptions?.groupedColumnMode === 'remove' && - row.groupingValue} - {tableOptions?.enableGroupingSingleColumn && - tableOptions?.groupedColumnMode === 'remove' && + {isGroupedSingleColumn && row.groupingValue} + {isGroupedSingleColumn && row.getCanExpand() && ( + <> ({row.subRows?.length}) + )} + {isGroupedSingleColumn && tableOptions?.showOpenedGroup && !row.getCanExpand() && row.original?.[ From 81184597d3e14102b176d3cc8c52d0394ae82c1d Mon Sep 17 00:00:00 2001 From: Khoa Nguyen Date: Sat, 6 Jan 2024 16:06:47 +0700 Subject: [PATCH 7/9] feat: add column name follow by addColumnToLeafNode, and example in storybook --- .../src/hooks/useMRT_DisplayColumns.tsx | 8 +- .../features/ColumnGrouping.stories.tsx | 128 ++++++++++-------- 2 files changed, 78 insertions(+), 58 deletions(-) diff --git a/packages/material-react-table/src/hooks/useMRT_DisplayColumns.tsx b/packages/material-react-table/src/hooks/useMRT_DisplayColumns.tsx index fc21924bc..a7f336ba0 100644 --- a/packages/material-react-table/src/hooks/useMRT_DisplayColumns.tsx +++ b/packages/material-react-table/src/hooks/useMRT_DisplayColumns.tsx @@ -190,8 +190,12 @@ function makeRowExpandColumn( )} {tableOptions?.enableGroupingSingleColumn && - tableOptions?.groupedColumnMode === 'remove' && - 'Group'} + tableOptions?.groupedColumnMode === 'remove' + ? table.getState().addColumnToLeafNode + ? table.getColumn?.(table.getState().addColumnToLeafNode ?? '') + ?.columnDef?.header + : 'Group' /* Add key localization */ + : undefined} ); }, diff --git a/packages/material-react-table/stories/features/ColumnGrouping.stories.tsx b/packages/material-react-table/stories/features/ColumnGrouping.stories.tsx index aa8bd3683..bbf190122 100644 --- a/packages/material-react-table/stories/features/ColumnGrouping.stories.tsx +++ b/packages/material-react-table/stories/features/ColumnGrouping.stories.tsx @@ -290,47 +290,53 @@ export const GroupingWithSingleColumn = () => { const _columns = useMemo[]>( () => [ { - AggregatedCell: ({ row, table }) => { - const { - options: { - icons: { ExpandMoreIcon }, - }, - } = table; - - if (!row.groupingColumnId || !row.groupingValue) { - return null; - } + accessorKey: 'firstName', + header: 'First Name', + }, + { + accessorKey: 'lastName', + header: 'Last Name', + }, + { + accessorKey: 'gender', + header: 'Gender', + }, + { + accessorKey: 'city', + header: 'City', + }, + { + accessorKey: 'state', + header: 'State', + }, + ], + [], + ); - return ( - - row.toggleExpanded(!row.getIsExpanded())} - size="small" - > - - - {row.groupingValue as ReactNode} - - ); - }, - accessorKey: 'group', - columnDefType: 'display', - header: 'Group', - muiTableBodyCellProps: ({ row }) => { - return { - sx: { - justifyContent: 'left', - pl: `calc(${row.depth * 16}px)`, - textAlign: 'left', - }, - }; + return ( + + ); +}; + +export const GroupingWithSingleColumnWithShowOpenedGroup = () => { + const _columns = useMemo[]>( + () => [ { accessorKey: 'firstName', header: 'First Name', @@ -361,35 +367,25 @@ export const GroupingWithSingleColumn = () => { data={data} displayColumnDefOptions={{ 'mrt-row-expand': { - enableHiding: false, visibleInShowHideMenu: false, }, }} enableColumnDragging enableGrouping + enableGroupingSingleColumn groupedColumnMode="remove" initialState={{ - columnVisibility: { 'mrt-row-expand': false }, + addColumnToLeafNode: 'city', + columnVisibility: { city: false }, density: 'compact', grouping: ['gender', 'state'], }} - muiTableBodyRowProps={({ row }) => { - return { - sx: { - bgcolor: - row.groupingColumnId === 'gender' - ? 'darkgreen' - : row.groupingColumnId === 'state' - ? 'slategrey' - : 'inherit', - }, - }; - }} + showOpenedGroup /> ); }; -export const GroupingWithSingleColumnTest = () => { +export const GroupingWithSingleColumnWithRowVirtualization = () => { const _columns = useMemo[]>( () => [ { @@ -420,16 +416,36 @@ export const GroupingWithSingleColumnTest = () => { { + return { + sx: { + bgcolor: + row.depth === 0 + ? 'darkgreen' + : row.depth === 1 + ? 'slategrey' + : 'inherit', + }, + }; + }} + muiTableContainerProps={{ sx: { maxHeight: 600 } }} showOpenedGroup /> ); From d7cd6802e885b1e61c265ec80fbbb0c1db7da015 Mon Sep 17 00:00:00 2001 From: Khoa Nguyen Date: Sat, 6 Jan 2024 16:32:46 +0700 Subject: [PATCH 8/9] docs: add new props in tableOptions, stateOptions --- .../components/prop-tables/stateOptions.ts | 9 ++++++++ .../components/prop-tables/tableOptions.ts | 22 +++++++++++++++++++ .../src/hooks/useMRT_DisplayColumns.tsx | 2 ++ packages/material-react-table/src/types.ts | 2 +- 4 files changed, 34 insertions(+), 1 deletion(-) diff --git a/apps/material-react-table-docs/components/prop-tables/stateOptions.ts b/apps/material-react-table-docs/components/prop-tables/stateOptions.ts index f2de34e5a..434243d6c 100644 --- a/apps/material-react-table-docs/components/prop-tables/stateOptions.ts +++ b/apps/material-react-table-docs/components/prop-tables/stateOptions.ts @@ -11,6 +11,15 @@ export type StateOption = { }; export const stateOptions: StateOption[] = [ + { + defaultValue: '', + description: 'a variable will be used to render the leaf node.', + link: '', + linkText: '', + source: 'MRT', + stateOption: 'addColumnToLeafNode', + type: 'string', + }, { defaultValue: '', description: 'a variable representing the currently creating row', diff --git a/apps/material-react-table-docs/components/prop-tables/tableOptions.ts b/apps/material-react-table-docs/components/prop-tables/tableOptions.ts index f93c71a3c..eab782268 100644 --- a/apps/material-react-table-docs/components/prop-tables/tableOptions.ts +++ b/apps/material-react-table-docs/components/prop-tables/tableOptions.ts @@ -357,6 +357,17 @@ export const tableOptions: TableOption[] = [ source: 'MRT', type: 'boolean', }, + { + tableOption: 'enableGroupingSingleColumn', + defaultValue: '', + description: + 'Single group column is automatically added by the grid containing all row groups under a single row group hierarchy.', + link: '', + linkText: '', + required: false, + source: 'MRT', + type: 'boolean', + }, { tableOption: 'enableFacetedValues', defaultValue: 'true', @@ -2060,6 +2071,17 @@ export const tableOptions: TableOption[] = [ source: 'TanStack Table', type: 'Record', }, + { + tableOption: 'showOpenedGroup', + defaultValue: '', + description: + 'This option will show the name of the opened group inside the group column.', + link: '', + linkText: '', + required: false, + source: 'MRT', + type: 'boolean', + }, { tableOption: 'state', defaultValue: '', diff --git a/packages/material-react-table/src/hooks/useMRT_DisplayColumns.tsx b/packages/material-react-table/src/hooks/useMRT_DisplayColumns.tsx index a7f336ba0..93a777995 100644 --- a/packages/material-react-table/src/hooks/useMRT_DisplayColumns.tsx +++ b/packages/material-react-table/src/hooks/useMRT_DisplayColumns.tsx @@ -69,8 +69,10 @@ export const useMRT_DisplayColumns = ( tableOptions.renderDetailPanel, tableOptions.renderRowActionMenuItems, tableOptions.renderRowActions, + tableOptions.state?.addColumnToLeafNode, tableOptions.state?.columnOrder, tableOptions.state?.grouping, + tableOptions.showOpenedGroup, ], ); }; diff --git a/packages/material-react-table/src/types.ts b/packages/material-react-table/src/types.ts index 3b6c20b77..1ede2ef9e 100644 --- a/packages/material-react-table/src/types.ts +++ b/packages/material-react-table/src/types.ts @@ -1201,9 +1201,9 @@ export type MRT_TableOptions = Omit< }) => Partial>) | Partial>; selectAllMode?: 'all' | 'page'; + showOpenedGroup?: boolean; /** * Manage state externally any way you want, then pass it back into MRT. */ - showOpenedGroup?: boolean; state?: Partial>; }; From 7aa7ab628aa7b1b6ae48f5ec73e433a0550c411a Mon Sep 17 00:00:00 2001 From: Khoa Nguyen Date: Sat, 6 Jan 2024 20:23:02 +0700 Subject: [PATCH 9/9] refactor: refactor get arr grouping --- .../src/hooks/useMRT_DisplayColumns.tsx | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/material-react-table/src/hooks/useMRT_DisplayColumns.tsx b/packages/material-react-table/src/hooks/useMRT_DisplayColumns.tsx index 93a777995..415742186 100644 --- a/packages/material-react-table/src/hooks/useMRT_DisplayColumns.tsx +++ b/packages/material-react-table/src/hooks/useMRT_DisplayColumns.tsx @@ -160,12 +160,12 @@ function makeRowExpandColumn( order.includes(id) && showExpandColumn(tableOptions, tableOptions.state?.grouping ?? grouping) ) { + const arrGrouping = tableOptions.state?.grouping ?? grouping; return { Cell: ({ row, table }) => { const isGroupedSingleColumn = tableOptions?.enableGroupingSingleColumn && tableOptions?.groupedColumnMode === 'remove'; - return ( <> @@ -178,9 +178,7 @@ function makeRowExpandColumn( !row.getCanExpand() && row.original?.[ table.getState().addColumnToLeafNode ?? - table.getState().grouping[ - table.getState().grouping.length - 1 - ] + arrGrouping[arrGrouping.length - 1] ]} );