From fe70330f3176e496446e97bd26bf6087b9db0ee6 Mon Sep 17 00:00:00 2001 From: Andrew Holloway Date: Tue, 27 Aug 2024 09:50:45 -0500 Subject: [PATCH 1/6] feat(DataTable): introduce 1.0 component - new component for complex data-based table content - add in the documentation for props - add in types, layouts, and test - add in snapshots - make use of newly-added tokens --- .storybook/data/tokens.json | 1 + .storybook/preview.tsx | 1 + src/components/DataTable/DataTable.module.css | 66 + .../DataTable/DataTable.stories.tsx | 223 ++++ src/components/DataTable/DataTable.test.ts | 7 + src/components/DataTable/DataTable.tsx | 193 +++ .../__snapshots__/DataTable.test.ts.snap | 1059 +++++++++++++++++ src/components/DataTable/index.ts | 1 + src/design-tokens/primitives.json | 5 + src/index.ts | 1 + src/tokens-dist/css/variables.css | 1 + src/tokens-dist/json/variables-nested.json | 1 + 12 files changed, 1559 insertions(+) create mode 100644 src/components/DataTable/DataTable.module.css create mode 100644 src/components/DataTable/DataTable.stories.tsx create mode 100644 src/components/DataTable/DataTable.test.ts create mode 100644 src/components/DataTable/DataTable.tsx create mode 100644 src/components/DataTable/__snapshots__/DataTable.test.ts.snap create mode 100644 src/components/DataTable/index.ts diff --git a/.storybook/data/tokens.json b/.storybook/data/tokens.json index 3910b55aa..034fba7b8 100644 --- a/.storybook/data/tokens.json +++ b/.storybook/data/tokens.json @@ -811,6 +811,7 @@ "eds-size-20": "160", "eds-size-24": "192", "eds-size-32": "256", + "eds-size-34": "272", "eds-size-40": "320", "eds-size-base-unit": "8", "eds-size-half": "4", diff --git a/.storybook/preview.tsx b/.storybook/preview.tsx index ccd9cc76a..6afd608e5 100644 --- a/.storybook/preview.tsx +++ b/.storybook/preview.tsx @@ -84,6 +84,7 @@ export const parameters: Preview['parameters'] = { ...createInitialReleaseConfig('1.2'), ...createInitialReleaseConfig('1.1'), ...createInitialReleaseConfig('1.0'), + ...createCurrentReleaseConfig('1.0'), ...createCurrentReleaseConfig('1.3'), ...createCurrentReleaseConfig('2.0'), ...createCurrentReleaseConfig('2.1'), diff --git a/src/components/DataTable/DataTable.module.css b/src/components/DataTable/DataTable.module.css new file mode 100644 index 000000000..dd2170c2e --- /dev/null +++ b/src/components/DataTable/DataTable.module.css @@ -0,0 +1,66 @@ +/*------------------------------------*\ + # DATA TABLE +\*------------------------------------*/ + +/** + * DataTable + */ + + /* Visible table caption */ +.data-table__caption-container { + display: flex; + align-items: flex-end; + flex-wrap: wrap; + justify-content: space-between; + gap: calc(var(--eds-size-3) / 16 * 1rem) calc(var(--eds-size-6) / 16 * 1rem); + + text-align: start; + margin: 0 calc(var(--eds-size-3) / 16 * 1rem) calc(var(--eds-size-4) / 16 * 1rem); +} + +.data-table__caption-text { + flex-grow: 1; +} + +/* Invisible table caption (a11y) */ +.data-table__aria-caption { + display: none; +} + +.data-table__caption { + caption-side: top; + font: var(--eds-theme-typography-headline-md-bold); +} + +.data-table__subcaption { + font: var(--eds-theme-typography-headline-sm); +} + +.data-table__table { + border: 1px solid; + width: 100%; + + .data-table__caption + &, + .data-table__subcaption + & { + margin-top: calc(var(--eds-size-4) / 16 * 1rem); + } +} + +.data-table__search { + width: calc(var(--eds-size-34) / 16 * 1rem); +} + +/** + * Color Tokens + */ +.data-table { + display: block; + + .data-table__caption { + color: var(--eds-theme-color-text-utility-default-primary); + } + + .data-table__subcaption { + color: var(--eds-theme-color-text-utility-default-secondary); + } +} diff --git a/src/components/DataTable/DataTable.stories.tsx b/src/components/DataTable/DataTable.stories.tsx new file mode 100644 index 000000000..38c077a98 --- /dev/null +++ b/src/components/DataTable/DataTable.stories.tsx @@ -0,0 +1,223 @@ +import { BADGE } from '@geometricpanda/storybook-addon-badges'; +import type { StoryObj, Meta } from '@storybook/react'; +import React from 'react'; + +import { DataTable } from './DataTable'; +import { chromaticViewports } from '../../util/viewports'; +import Button from '../Button'; +import Menu from '../Menu'; + +export default { + title: 'Components/DataTable', + component: DataTable, + parameters: { + badges: [BADGE.BETA, 'intro-1.0', 'current-1.0'], + chromatic: { + viewports: [ + chromaticViewports.ipadMini, + chromaticViewports.chromebook, + chromaticViewports.googlePixel2, + ], + }, + }, + argTypes: { + actions: { + control: false, + }, + }, + args: { + children: ( + + + + + + +
TODO: Table rows/cells Here
+ ), + }, +} as Meta; + +type Args = React.ComponentProps; + +export const Default: StoryObj = { + args: {}, +}; + +export const WithBasicCaption: StoryObj = { + args: { + caption: 'Fruits of the world', + }, +}; + +export const WithFullCaption: StoryObj = { + args: { + caption: 'Fruits of the world', + subcaption: "Aren't they all so delicious?", + }, +}; + +export const WithSearch: StoryObj = { + args: { + caption: 'Fruits of the world', + subcaption: "Aren't they all so delicious?", + onSearchChange: () => {}, + }, +}; + +export const WithOnlyActions: StoryObj = { + args: { + actions: ( + + + + + + + ), + }, +}; + +export const WithLongCaption: StoryObj = { + args: { + caption: + 'This is a really long title that really should not be this long and it just keeps going and going and going', + subcaption: 'Seriously, who let this happen?', + onSearchChange: () => {}, + actions: ( + + + + + + + + + + + +
+ TODO: Table rows/cells Here +
+ +`; + +exports[` TableB story renders snapshot 1`] = ` +
+
+
+ + +
+ +
+
+ + + +
+
+
+ + + + + + +
+ TODO: Table rows/cells Here +
+
+`; + +exports[` TableC story renders snapshot 1`] = ` +
+
+
+ + +
+ +
+
+ + + +
+
+
+ + + + + + +
+ TODO: Table rows/cells Here +
+
+`; + +exports[` TableD story renders snapshot 1`] = ` +
+
+
+ + +
+ +
+
+ + + +
+
+
+ + + + + + +
+ TODO: Table rows/cells Here +
+
+`; + +exports[` WithBasicCaption story renders snapshot 1`] = ` +
+
+
+ +
+
+ + + + + + +
+ TODO: Table rows/cells Here +
+
+`; + +exports[` WithFullCaption story renders snapshot 1`] = ` +
+
+
+ + +
+
+ + + + + + +
+ TODO: Table rows/cells Here +
+
+`; + +exports[` WithLongCaption story renders snapshot 1`] = ` +
+
+
+ + +
+ +
+
+ + + +
+
+
+ + + + + + +
+ TODO: Table rows/cells Here +
+
+`; + +exports[` WithOnlyActions story renders snapshot 1`] = ` +
+
+
+
+ + + +
+
+
+ + + + + + +
+ TODO: Table rows/cells Here +
+
+`; + +exports[` WithSearch story renders snapshot 1`] = ` +
+
+
+ + +
+ +
+ + + + + + +
+ TODO: Table rows/cells Here +
+
+`; + +exports[` WithSearchAndActions story renders snapshot 1`] = ` +
+
+
+ + +
+ +
+
+ + + +
+
+
+ + + + + + +
+ TODO: Table rows/cells Here +
+
+`; + +exports[` WithSearchAndCustomActions story renders snapshot 1`] = ` +
+
+
+ + +
+ +
+
+ + + +
+
+
+ + + + + + +
+ TODO: Table rows/cells Here +
+
+`; diff --git a/src/components/DataTable/index.ts b/src/components/DataTable/index.ts new file mode 100644 index 000000000..cadb02a9a --- /dev/null +++ b/src/components/DataTable/index.ts @@ -0,0 +1 @@ +export { DataTable as default } from './DataTable'; diff --git a/src/design-tokens/primitives.json b/src/design-tokens/primitives.json index b6e1733d5..8a9f7d5af 100644 --- a/src/design-tokens/primitives.json +++ b/src/design-tokens/primitives.json @@ -655,6 +655,11 @@ "group": "size", "comment": "Relative EMs (rem)" }, + "34": { + "value": "272", + "group": "size", + "comment": "Relative EMs (rem)" + }, "40": { "value": "320", "group": "size", diff --git a/src/index.ts b/src/index.ts index 47b2912b0..e8703047d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -29,6 +29,7 @@ export { default as Button } from './components/Button'; export { default as ButtonGroup } from './components/ButtonGroup'; export { default as Card } from './components/Card'; export { default as Checkbox } from './components/Checkbox'; +export { default as DataTable } from './components/DataTable'; export { default as FieldLabel } from './components/FieldLabel'; export { default as FieldNote } from './components/FieldNote'; export { default as Fieldset } from './components/Fieldset'; diff --git a/src/tokens-dist/css/variables.css b/src/tokens-dist/css/variables.css index 4778c90d2..229db7bf8 100644 --- a/src/tokens-dist/css/variables.css +++ b/src/tokens-dist/css/variables.css @@ -13,6 +13,7 @@ --eds-size-half: 4; /* Relative EMs (rem) */ --eds-size-base-unit: 8; /* Relative EMs (rem) @deprecated This should not be used in code or design. It will be removed in a future version of EDS. */ --eds-size-40: 320; /* Relative EMs (rem) */ + --eds-size-34: 272; /* Relative EMs (rem) */ --eds-size-32: 256; /* Relative EMs (rem) */ --eds-size-24: 192; /* Relative EMs (rem) */ --eds-size-20: 160; /* Relative EMs (rem) */ diff --git a/src/tokens-dist/json/variables-nested.json b/src/tokens-dist/json/variables-nested.json index a7af61bb3..ed6350f8b 100644 --- a/src/tokens-dist/json/variables-nested.json +++ b/src/tokens-dist/json/variables-nested.json @@ -1465,6 +1465,7 @@ "20": "160", "24": "192", "32": "256", + "34": "272", "40": "320", "base-unit": "8", "half": "4", From bf77dd25dc4ba9168ff02cbc4701e9bee94c7719 Mon Sep 17 00:00:00 2001 From: Andrew Holloway Date: Fri, 6 Sep 2024 09:35:02 -0500 Subject: [PATCH 2/6] feat(DataTable): implement TanStack Table (#2055) - use tanstack as basis for table implementation - add in relevant stories for styles - add in snapshots for tests --- package.json | 1 + src/components/DataTable/DataTable.module.css | 140 +- .../DataTable/DataTable.stories.tsx | 506 +- src/components/DataTable/DataTable.tsx | 328 +- .../__snapshots__/DataTable.test.ts.snap | 5272 +++++++++++++++-- src/components/DataTable/index.ts | 5 + src/components/PopoverContainer/index.ts | 2 +- src/components/Table/Table.tsx | 1 + src/index.ts | 3 +- src/util/variant-types.ts | 18 +- yarn.lock | 20 + 11 files changed, 5753 insertions(+), 543 deletions(-) diff --git a/package.json b/package.json index 55646f140..9cbe343b5 100644 --- a/package.json +++ b/package.json @@ -90,6 +90,7 @@ "dependencies": { "@headlessui/react": "^1.7.19", "@popperjs/core": "^2.11.8", + "@tanstack/react-table": "^8.20.5", "@tippyjs/react": "^4.2.6", "chalk": "^4.1.2", "clsx": "^2.1.1", diff --git a/src/components/DataTable/DataTable.module.css b/src/components/DataTable/DataTable.module.css index dd2170c2e..8318d1172 100644 --- a/src/components/DataTable/DataTable.module.css +++ b/src/components/DataTable/DataTable.module.css @@ -2,11 +2,8 @@ # DATA TABLE \*------------------------------------*/ -/** - * DataTable - */ - /* Visible table caption */ + /* TODO-AH: make it so that we have the search bar and actions wrap together instead of separately */ .data-table__caption-container { display: flex; align-items: flex-end; @@ -15,7 +12,7 @@ gap: calc(var(--eds-size-3) / 16 * 1rem) calc(var(--eds-size-6) / 16 * 1rem); text-align: start; - margin: 0 calc(var(--eds-size-3) / 16 * 1rem) calc(var(--eds-size-4) / 16 * 1rem); + margin: 0 calc(var(--eds-size-3) / 16 * 1rem) calc(var(--eds-size-4) / 16 * 1rem); } .data-table__caption-text { @@ -37,9 +34,15 @@ } .data-table__table { - border: 1px solid; + table-layout: fixed; width: 100%; + /* add class instead of tag for styles? */ + th, td { + padding: 0; + vertical-align: top; + } + .data-table__caption + &, .data-table__subcaption + & { margin-top: calc(var(--eds-size-4) / 16 * 1rem); @@ -50,11 +53,116 @@ width: calc(var(--eds-size-34) / 16 * 1rem); } +.data-table--tableStyle-border { + border: calc(var(--eds-border-width-sm) * 1px) solid; +} + +.data-table__cell-text { + text-align: start; + + .data-table__cell--alignment-leading & { + text-align: start; + } + + .data-table__cell--alignment-trailing & { + text-align: end; + } +} + +.data-table__cell--alignment-leading { + justify-content: flex-start; +} + +.data-table__cell--alignment-trailing { + justify-content: flex-end; +} + +.data-table__cell-sublabel { + display: block; + font: var(--eds-theme-typography-body-sm); +} + +.data-table__header-cell { + display: flex; + gap: calc(var(--eds-size-1) / 16 * 1rem); + align-items: flex-start; + font: var(--eds-theme-typography-title-md); + + .data-table--size-sm & { + font: var(--eds-theme-typography-title-sm); + /* TODO(bug): we want to use top-/bottom-padding of 5px (instead of 4px) to give overall height divisible by 8 (32px) */ + 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); + } + + .data-cell__cell--icon { + margin-top: calc(var(--eds-size-1) / 16 * 1rem); + flex-shrink: 0; + + .data-table--size-sm & { + margin-top: calc(var(--eds-size-half) / 16 * 1rem); + } + } +} + +.data-table__cell { + display: flex; + gap: calc(var(--eds-size-1) / 16 * 1rem); + align-items: flex-start; + font: var(--eds-theme-typography-body-md); + + .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); + } + + .data-cell__cell--icon { + margin-top: calc(var(--eds-size-half) / 16 * 1rem); + flex-shrink: 0; + } +} + +.data-table__row { + .data-table--rowStyle-lined & { + border-bottom: calc(var(--eds-border-width-sm) * 1px) solid; + } + + .data-table--rowStyle-striped &:nth-child(even) { + background-color: var(--eds-theme-color-background-table-row-stripe-2); + } + + .data-table--rowStyle-striped &:nth-child(odd) { + background-color: var(--eds-theme-color-background-table-row-stripe-1); + } +} + +.data-table__header-row { + border-bottom: calc(var(--eds-border-width-sm) * 1px) solid; + position: sticky; + top: 0; +} + /** * Color Tokens */ .data-table { display: block; + position: relative; + + .data-table__table { + background-color: var(--eds-theme-color-background-utility-base-1); + + th { + background-color: var(--eds-theme-color-background-utility-base-1); + } + } .data-table__caption { color: var(--eds-theme-color-text-utility-default-primary); @@ -63,4 +171,24 @@ .data-table__subcaption { color: var(--eds-theme-color-text-utility-default-secondary); } + + .data-table--tableStyle-border, .data-table__header-row { + border-color: var(--eds-theme-color-border-utility-default-low-emphasis); + } + + .data-table__header-cell { + color: var(--eds-theme-color-text-utility-default-primary); + } + + .data-table__cell { + color: var(--eds-theme-color-text-utility-default-primary); + } + + .data-table--rowStyle-lined { + color: var(--eds-theme-color-border-utility-default-low-emphasis); + } + + .data-table__cell-sublabel, .data-table__header-cell-sublabel { + color: var(--eds-theme-color-text-utility-default-secondary); + } } diff --git a/src/components/DataTable/DataTable.stories.tsx b/src/components/DataTable/DataTable.stories.tsx index 38c077a98..65ea2d30c 100644 --- a/src/components/DataTable/DataTable.stories.tsx +++ b/src/components/DataTable/DataTable.stories.tsx @@ -1,15 +1,35 @@ import { BADGE } from '@geometricpanda/storybook-addon-badges'; import type { StoryObj, Meta } from '@storybook/react'; + import React from 'react'; -import { DataTable } from './DataTable'; +import { + DataTable, + DataTableTable, + DataTableDataCell, + DataTableHeaderCell, + DataTableRow, + DataTableHeader, + type DataTableProps, +} from './DataTable'; + +// We import all of the utilities from tanstack here, and this can contain other custom utilities +import { Button, Menu, Checkbox, DataTableUtils } from '../..'; + import { chromaticViewports } from '../../util/viewports'; -import Button from '../Button'; -import Menu from '../Menu'; export default { title: 'Components/DataTable', component: DataTable, + // TODO(bug): generate documentation argTypes for sub-components + // @see https://storybook.js.org/docs/writing-stories/stories-for-multiple-components + subcomponents: { + 'DataTable.Table': DataTableTable, + 'DataTable.Row': DataTableRow, + 'DataTable.Header': DataTableHeader, + 'DataTable.HeaderCell': DataTableHeaderCell, + 'DataTable.DataCell': DataTableDataCell, + }, parameters: { badges: [BADGE.BETA, 'intro-1.0', 'current-1.0'], chromatic: { @@ -24,34 +44,421 @@ export default { actions: { control: false, }, + children: { + control: false, + }, + }, +} as Meta; + +type Args = DataTableProps; + +// Specifying an example data type for the rows of a table +type Person = { + firstName: string; + lastName: string; + age: number; + visits: number; + progress: number; +}; + +// Specifying the example (static) data for the table to use with tanstack primitives +const defaultData: Person[] = [ + { + firstName: 'Joe', + lastName: 'Dirte', + age: 45, + visits: 20, + progress: 10, + }, + { + firstName: 'Tandy', + lastName: 'Miller', + age: 40, + visits: 40, + progress: 80, + }, + { + firstName: 'Tanner', + lastName: 'Lindsey', + age: 24, + visits: 100, + progress: 50, + }, + { + firstName: 'Joe', + lastName: 'Dirte', + age: 45, + visits: 20, + progress: 10, + }, + { + firstName: 'Tandy', + lastName: 'Miller', + age: 40, + visits: 40, + progress: 80, + }, + { + firstName: 'Tanner', + lastName: 'Lindsey', + age: 24, + visits: 100, + progress: 50, + }, + { + firstName: 'Joe', + lastName: 'Dirte', + age: 45, + visits: 20, + progress: 10, }, + { + firstName: 'Tandy', + lastName: 'Miller', + age: 40, + visits: 40, + progress: 80, + }, + { + firstName: 'Tanner', + lastName: 'Lindsey', + age: 24, + visits: 100, + progress: 50, + }, + { + firstName: 'Joe', + lastName: 'Dirte', + age: 45, + visits: 20, + progress: 10, + }, + { + firstName: 'Tandy', + lastName: 'Miller', + age: 40, + visits: 40, + progress: 80, + }, + { + firstName: 'Tanner', + lastName: 'Lindsey', + age: 24, + visits: 100, + progress: 50, + }, +]; + +// We generate a helper object to generate the display columns and use the type for the structure +const columnHelper = DataTableUtils.createColumnHelper(); + +// TODO: how to make the data type apply the correct alignment and other UI props +const columns = [ + 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()} + + ), + }), +]; + +/** + * Using the hooks provided by Tanstack's Table, you can control the dimensions and contents of the table. + * + * When specifying the cells, you can use `className` to control content controls like truncation or other customizations. + */ +export const Default: StoryObj = { + args: { + caption: 'Test table', + subcaption: 'Additional Subcaption', + }, + render: (args) => { + // eslint-disable-next-line react-hooks/rules-of-hooks + const table = DataTableUtils.useReactTable({ + data: defaultData, + columns, + getCoreRowModel: DataTableUtils.getCoreRowModel(), + }); + + return ; + }, +}; + +export const TableStyleBorder: StoryObj = { + args: { + tableStyle: 'border', + }, + render: (args) => { + // eslint-disable-next-line react-hooks/rules-of-hooks + const [data] = React.useState(() => [...defaultData]); + + // eslint-disable-next-line react-hooks/rules-of-hooks + const table = DataTableUtils.useReactTable({ + data, + columns, + getCoreRowModel: DataTableUtils.getCoreRowModel(), + }); + + return ; + }, +}; + +/** + * When using table size small, we have less padding on the cells and header + * + * **Note**: using `sublabel`s when `size` = `'sm'` is not allowed. + */ +export const TableSizeSm: StoryObj = { + args: { + tableStyle: 'border', + size: 'sm', + }, + render: (args) => { + // eslint-disable-next-line react-hooks/rules-of-hooks + const table = DataTableUtils.useReactTable({ + data: defaultData, + columns, + getCoreRowModel: DataTableUtils.getCoreRowModel(), + }); + + return ; + }, +}; + +export const RowStyleLined: StoryObj = { + args: { + tableStyle: 'border', + rowStyle: 'lined', + }, + render: (args) => { + // eslint-disable-next-line react-hooks/rules-of-hooks + const table = DataTableUtils.useReactTable({ + data: defaultData, + columns, + getCoreRowModel: DataTableUtils.getCoreRowModel(), + }); + + return ; + }, +}; + +// TODO-AH: hook up style for selected row +// TODO-AH: hook up isInteractive +/** + * Implementation example of how to build selectable rows. + * + * For more information: https://tanstack.com/table/latest/docs/framework/react/examples/row-selection + */ +export const Selectable: StoryObj = { + args: { + caption: 'Test table', + subcaption: 'Additional Subcaption', + }, + render: (args) => { + // eslint-disable-next-line react-hooks/rules-of-hooks + const [rowSelection, setRowSelection] = React.useState({}); + + // 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 ; + }, +}; + +export const DefaultWithCustomTable: StoryObj = { args: { children: ( - +
TODO: Table rows/cells HereTODO: Custom table rows/cells here
), }, -} as Meta; - -type Args = React.ComponentProps; - -export const Default: StoryObj = { - args: {}, }; export const WithBasicCaption: StoryObj = { args: { + ...DefaultWithCustomTable.args, caption: 'Fruits of the world', }, }; export const WithFullCaption: StoryObj = { + ...DefaultWithCustomTable, args: { + ...DefaultWithCustomTable.args, caption: 'Fruits of the world', subcaption: "Aren't they all so delicious?", }, @@ -59,6 +466,7 @@ export const WithFullCaption: StoryObj = { export const WithSearch: StoryObj = { args: { + ...DefaultWithCustomTable.args, caption: 'Fruits of the world', subcaption: "Aren't they all so delicious?", onSearchChange: () => {}, @@ -67,6 +475,7 @@ export const WithSearch: StoryObj = { export const WithOnlyActions: StoryObj = { args: { + ...DefaultWithCustomTable.args, actions: (