diff --git a/src/components/DataTable/DataTable.module.css b/src/components/DataTable/DataTable.module.css index 3bbd10210..9a86c2f44 100644 --- a/src/components/DataTable/DataTable.module.css +++ b/src/components/DataTable/DataTable.module.css @@ -5,7 +5,7 @@ /* Visible table caption */ /* TODO-AH: make it so that we have the search bar and actions wrap together instead of separately */ /* TODO-AH: implement showing of shadow below sticky headers and column */ -/* TODO-AH: handle caption padding syncing with table cell padding using size */ +/* - https://stackoverflow.com/questions/38122751/positionsticky-adding-style-when-the-element-detaches-from-normal-flow */ .data-table__caption-container { display: flex; align-items: flex-end; @@ -166,6 +166,23 @@ top: 0; } +.data-table__group-row { + font: var(--eds-theme-typography-body-md); + pointer-events: none; + + .data-table--size-sm & { + font: var(--eds-theme-typography-body-sm); + padding: calc(var(--eds-size-half) / 16 * 1rem) + calc(var(--eds-size-1) / 16 * 1rem); + } + + .data-table--size-md & { + padding: calc(var(--eds-size-2) / 16 * 1rem) + calc(var(--eds-size-3) / 16 * 1rem); + } + +} + /** * Color Tokens */ @@ -203,7 +220,6 @@ } } - .data-table { display: block; position: relative; @@ -262,4 +278,9 @@ z-index: 1; } } + + .data-table__group-row { + color: var(--eds-theme-color-text-utility-default-primary); + background-color: var(--eds-theme-color-background-utility-interactive-low-emphasis); + } } diff --git a/src/components/DataTable/DataTable.stories.tsx b/src/components/DataTable/DataTable.stories.tsx index fd3959cf4..c9298a641 100644 --- a/src/components/DataTable/DataTable.stories.tsx +++ b/src/components/DataTable/DataTable.stories.tsx @@ -433,9 +433,156 @@ export const Selectable: StoryObj = { }, }; +/** + * Implementation example of how to build selectable rows. + * + * For more information: https://tanstack.com/table/latest/docs/framework/react/examples/row-selection + */ +export const VerticalDivider: StoryObj = { + args: { + caption: 'Test table', + subcaption: 'Additional Subcaption', + isInteractive: true, + }, + render: (args) => { + // eslint-disable-next-line react-hooks/rules-of-hooks + const [rowSelection, setRowSelection] = React.useState({}); // TODO: demonstrate one is selected + + // TODO(docs): Why must `any` be passed as second type param to avoid `unknown`? + // eslint-disable-next-line react-hooks/rules-of-hooks + const selectableColumns = React.useMemo< + DataTableUtils.ColumnDef[] + >( + () => [ + { + id: 'select', + header: ({ table }) => ( + + + + ), + cell: ({ row }) => ( + + + + ), + // Widths can be set on header cells (using pixels) + // More information: https://tanstack.com/table/latest/docs/guide/column-sizing#column-widths + // TODO(design): what is the column size for the selectable column + size: 32, + }, + columnHelper.accessor('firstName', { + header: () => ( + + First Name + + ), + cell: (info) => ( + + {info.getValue()} + + ), + }), + columnHelper.accessor((row) => row.lastName, { + id: 'lastName', + header: () => ( + + Last Name + + ), + cell: (info) => ( + + {info.getValue()} + + ), + }), + columnHelper.accessor('age', { + header: () => ( + + Age + + ), + cell: (info) => ( + + {info.renderValue()} + + ), + }), + columnHelper.accessor('visits', { + header: () => ( + + Visits + + ), + cell: (info) => ( + + {info.renderValue()} + + ), + }), + columnHelper.accessor('progress', { + header: () => ( + + Profile Progress + + ), + cell: (info) => ( + = 80 ? 'Complete' : 'Incomplete' + } + > + {info.renderValue()} + + ), + }), + ], + [], + ); + // eslint-disable-next-line react-hooks/rules-of-hooks + const table = DataTableUtils.useReactTable({ + data: defaultData, + columns: selectableColumns, + state: { + rowSelection, + }, + enableRowSelection: true, + onRowSelectionChange: setRowSelection, + getCoreRowModel: DataTableUtils.getCoreRowModel(), + }); + + return ; + }, +}; + // TODO-AH: Sticky column pinning (https://tanstack.com/table/latest/docs/framework/react/examples/column-pinning-sticky) // TODO-AH: GroupBy example https://tanstack.com/table/latest/docs/framework/react/examples/grouping -// TODO-AH: Column Border example (hasHorizontalDivider) export const DefaultWithCustomTable: StoryObj = { args: { diff --git a/src/components/DataTable/DataTable.tsx b/src/components/DataTable/DataTable.tsx index 1b7229f58..15ed4f70f 100644 --- a/src/components/DataTable/DataTable.tsx +++ b/src/components/DataTable/DataTable.tsx @@ -11,6 +11,8 @@ import InputField from '../InputField'; import styles from './DataTable.module.css'; +// TODO-AH: extend elements with underlying HTML props? + export type DataTableProps = EDSBase & { // Component API /** @@ -235,6 +237,7 @@ export function DataTable({ isSelected={row.getIsSelected()} key={row.id} > + {/* TODO-AH: somehow insert group by rows */} {row.getVisibleCells().map((cell) => ( {flexRender(cell.column.columnDef.cell, cell.getContext())} @@ -416,6 +419,14 @@ export const DataTableRow = ({ ); }; +export const DataTableGroupRow = ({ title }: { title: string }) => { + return ( + + {title} + + ); +}; + /** * For future development */ diff --git a/src/components/DataTable/__snapshots__/DataTable.test.ts.snap b/src/components/DataTable/__snapshots__/DataTable.test.ts.snap index 58c9a032e..c49a9bf93 100644 --- a/src/components/DataTable/__snapshots__/DataTable.test.ts.snap +++ b/src/components/DataTable/__snapshots__/DataTable.test.ts.snap @@ -4952,6 +4952,1383 @@ exports[` TableStyleBorder story renders snapshot 1`] = ` `; +exports[` VerticalDivider story renders snapshot 1`] = ` +
+
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Test table: Additional Subcaption +
+
+
+
+ +
+
+
+
+
+
+ +
+ First Name + + Given Name + +
+
+
+
+
+ Last Name + + Surname + +
+
+
+
+
+ Age +
+
+
+
+
+ Visits +
+
+
+
+
+ Profile Progress + + "Complete" is > 80% + +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+ Joe +
+
+
+
+
+ Dirte +
+
+
+
+
+ 45 +
+
+
+
+
+ 20 +
+
+
+
+
+ 10 + + Incomplete + +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+ Tandy +
+
+
+
+
+ Miller +
+
+
+
+
+ 40 +
+
+
+
+
+ 40 +
+
+
+
+
+ 80 + + Complete + +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+ Tanner +
+
+
+
+
+ Lindsey +
+
+
+
+
+ 24 +
+
+
+
+
+ 100 +
+
+
+
+
+ 50 + + Incomplete + +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+ Joe +
+
+
+
+
+ Dirte +
+
+
+
+
+ 45 +
+
+
+
+
+ 20 +
+
+
+
+
+ 10 + + Incomplete + +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+ Tandy +
+
+
+
+
+ Miller +
+
+
+
+
+ 40 +
+
+
+
+
+ 40 +
+
+
+
+
+ 80 + + Complete + +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+ Tanner +
+
+
+
+
+ Lindsey +
+
+
+
+
+ 24 +
+
+
+
+
+ 100 +
+
+
+
+
+ 50 + + Incomplete + +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+ Joe +
+
+
+
+
+ Dirte +
+
+
+
+
+ 45 +
+
+
+
+
+ 20 +
+
+
+
+
+ 10 + + Incomplete + +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+ Tandy +
+
+
+
+
+ Miller +
+
+
+
+
+ 40 +
+
+
+
+
+ 40 +
+
+
+
+
+ 80 + + Complete + +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+ Tanner +
+
+
+
+
+ Lindsey +
+
+
+
+
+ 24 +
+
+
+
+
+ 100 +
+
+
+
+
+ 50 + + Incomplete + +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+ Joe +
+
+
+
+
+ Dirte +
+
+
+
+
+ 45 +
+
+
+
+
+ 20 +
+
+
+
+
+ 10 + + Incomplete + +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+ Tandy +
+
+
+
+
+ Miller +
+
+
+
+
+ 40 +
+
+
+
+
+ 40 +
+
+
+
+
+ 80 + + Complete + +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+ Tanner +
+
+
+
+
+ Lindsey +
+
+
+
+
+ 24 +
+
+
+
+
+ 100 +
+
+
+
+
+ 50 + + Incomplete + +
+
+
+
+`; + exports[` WithBasicCaption story renders snapshot 1`] = `
WithLongCaption story renders snapshot 1`] = ` aria-label="search" class="input input-field__input--leading-icon" disabled="" - id=":rl:" + id=":r12:" placeholder="Search..." type="search" /> @@ -5228,7 +6605,7 @@ exports[` WithSearch story renders snapshot 1`] = ` aria-label="search" class="input input-field__input--leading-icon" disabled="" - id=":rd:" + id=":rq:" placeholder="Search..." type="search" /> @@ -5303,7 +6680,7 @@ exports[` WithSearchAndActions story renders snapshot 1`] = ` aria-label="search" class="input input-field__input--leading-icon" disabled="" - id=":rf:" + id=":rs:" placeholder="Search..." type="search" /> @@ -5415,7 +6792,7 @@ exports[` WithSearchAndCustomActions story renders snapshot 1`] = ` aria-label="search" class="input input-field__input--leading-icon" disabled="" - id=":rh:" + id=":ru:" placeholder="Search..." type="search" /> @@ -5504,7 +6881,7 @@ exports[` WithSearchAndCustomActions story renders snapshot 1`] = ` aria-label="show more actions" class="button button--layout-icon-only button--secondary button--lg button--variant-default" data-headlessui-state="" - id="headlessui-menu-button-:rj:" + id="headlessui-menu-button-:r10:" type="button" >