@purpurds/table 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/LICENSE.txt +213 -0
- package/dist/cell-types/badge-cell.d.ts +8 -0
- package/dist/cell-types/badge-cell.d.ts.map +1 -0
- package/dist/cell-types/body-text-cell.d.ts +8 -0
- package/dist/cell-types/body-text-cell.d.ts.map +1 -0
- package/dist/cell-types/button-cell.d.ts +8 -0
- package/dist/cell-types/button-cell.d.ts.map +1 -0
- package/dist/cell-types/button-group-cell.d.ts +16 -0
- package/dist/cell-types/button-group-cell.d.ts.map +1 -0
- package/dist/cell-types/cta-link-cell.d.ts +8 -0
- package/dist/cell-types/cta-link-cell.d.ts.map +1 -0
- package/dist/cell-types/date-cell.d.ts +8 -0
- package/dist/cell-types/date-cell.d.ts.map +1 -0
- package/dist/cell-types/empty-cell.d.ts +4 -0
- package/dist/cell-types/empty-cell.d.ts.map +1 -0
- package/dist/cell-types/error-message-cell.d.ts +8 -0
- package/dist/cell-types/error-message-cell.d.ts.map +1 -0
- package/dist/cell-types/icon-text-cell.d.ts +8 -0
- package/dist/cell-types/icon-text-cell.d.ts.map +1 -0
- package/dist/cell-types/lead-text-cell.d.ts +8 -0
- package/dist/cell-types/lead-text-cell.d.ts.map +1 -0
- package/dist/cell-types/link-cell.d.ts +8 -0
- package/dist/cell-types/link-cell.d.ts.map +1 -0
- package/dist/cell-types/number-cell.d.ts +8 -0
- package/dist/cell-types/number-cell.d.ts.map +1 -0
- package/dist/cell-types/row-selection-cell.d.ts +8 -0
- package/dist/cell-types/row-selection-cell.d.ts.map +1 -0
- package/dist/cell-types/row-toggle-cell.d.ts +8 -0
- package/dist/cell-types/row-toggle-cell.d.ts.map +1 -0
- package/dist/cell-types/toggle-cell.d.ts +8 -0
- package/dist/cell-types/toggle-cell.d.ts.map +1 -0
- package/dist/cell-types/warning-message-cell.d.ts +8 -0
- package/dist/cell-types/warning-message-cell.d.ts.map +1 -0
- package/dist/metadata.js +17 -0
- package/dist/story-utils/column-def.d.ts +5 -0
- package/dist/story-utils/column-def.d.ts.map +1 -0
- package/dist/story-utils/table-data.d.ts +35 -0
- package/dist/story-utils/table-data.d.ts.map +1 -0
- package/dist/story-utils/use-fetch-table-data-hook.d.ts +11 -0
- package/dist/story-utils/use-fetch-table-data-hook.d.ts.map +1 -0
- package/dist/styles.css +1 -0
- package/dist/table-action-bar.d.ts +26 -0
- package/dist/table-action-bar.d.ts.map +1 -0
- package/dist/table-body.d.ts +10 -0
- package/dist/table-body.d.ts.map +1 -0
- package/dist/table-column-header-cell.d.ts +28 -0
- package/dist/table-column-header-cell.d.ts.map +1 -0
- package/dist/table-export-drawer.d.ts +17 -0
- package/dist/table-export-drawer.d.ts.map +1 -0
- package/dist/table-header.d.ts +11 -0
- package/dist/table-header.d.ts.map +1 -0
- package/dist/table-row-cell-skeleton.d.ts +14 -0
- package/dist/table-row-cell-skeleton.d.ts.map +1 -0
- package/dist/table-row-cell.d.ts +25 -0
- package/dist/table-row-cell.d.ts.map +1 -0
- package/dist/table-row.d.ts +11 -0
- package/dist/table-row.d.ts.map +1 -0
- package/dist/table-settings-drawer.d.ts +41 -0
- package/dist/table-settings-drawer.d.ts.map +1 -0
- package/dist/table-toolbar.d.ts +37 -0
- package/dist/table-toolbar.d.ts.map +1 -0
- package/dist/table.cjs.js +259 -0
- package/dist/table.cjs.js.map +1 -0
- package/dist/table.d.ts +20 -0
- package/dist/table.d.ts.map +1 -0
- package/dist/table.es.js +13585 -0
- package/dist/table.es.js.map +1 -0
- package/dist/test-utils/column-def.d.ts +6 -0
- package/dist/test-utils/column-def.d.ts.map +1 -0
- package/dist/test-utils/helpers.d.ts +138 -0
- package/dist/test-utils/helpers.d.ts.map +1 -0
- package/dist/test-utils/table-data.d.ts +33 -0
- package/dist/test-utils/table-data.d.ts.map +1 -0
- package/dist/types.d.ts +420 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/use-screen-size.hook.d.ts +7 -0
- package/dist/use-screen-size.hook.d.ts.map +1 -0
- package/dist/use-truncated-hook.d.ts +10 -0
- package/dist/use-truncated-hook.d.ts.map +1 -0
- package/dist/utils/custom-functions.d.ts +9 -0
- package/dist/utils/custom-functions.d.ts.map +1 -0
- package/dist/utils/unit-conversions.d.ts +19 -0
- package/dist/utils/unit-conversions.d.ts.map +1 -0
- package/dist/utils/unit-conversions.spec.d.ts +2 -0
- package/dist/utils/unit-conversions.spec.d.ts.map +1 -0
- package/eslint.config.mjs +2 -0
- package/package.json +82 -0
- package/src/cell-types/badge-cell.tsx +25 -0
- package/src/cell-types/body-text-cell.tsx +54 -0
- package/src/cell-types/button-cell.tsx +26 -0
- package/src/cell-types/button-group-cell.tsx +54 -0
- package/src/cell-types/cta-link-cell.tsx +25 -0
- package/src/cell-types/date-cell.tsx +33 -0
- package/src/cell-types/empty-cell.tsx +6 -0
- package/src/cell-types/error-message-cell.tsx +30 -0
- package/src/cell-types/icon-text-cell.tsx +30 -0
- package/src/cell-types/lead-text-cell.tsx +19 -0
- package/src/cell-types/link-cell.tsx +58 -0
- package/src/cell-types/number-cell.tsx +27 -0
- package/src/cell-types/row-selection-cell.tsx +22 -0
- package/src/cell-types/row-toggle-cell.tsx +23 -0
- package/src/cell-types/toggle-cell.tsx +19 -0
- package/src/cell-types/warning-message-cell.tsx +30 -0
- package/src/global.d.ts +4 -0
- package/src/story-utils/column-def.ts +148 -0
- package/src/story-utils/table-data.tsx +262 -0
- package/src/story-utils/use-fetch-table-data-hook.tsx +30 -0
- package/src/table-action-bar.module.scss +106 -0
- package/src/table-action-bar.test.tsx +111 -0
- package/src/table-action-bar.tsx +104 -0
- package/src/table-body.tsx +25 -0
- package/src/table-column-header-cell.tsx +305 -0
- package/src/table-export-drawer.module.scss +9 -0
- package/src/table-export-drawer.test.tsx +75 -0
- package/src/table-export-drawer.tsx +59 -0
- package/src/table-header.tsx +35 -0
- package/src/table-kitchen-sink.test.tsx +1196 -0
- package/src/table-row-cell-skeleton.tsx +61 -0
- package/src/table-row-cell.test.tsx +360 -0
- package/src/table-row-cell.tsx +188 -0
- package/src/table-row.tsx +30 -0
- package/src/table-settings-drawer.module.scss +25 -0
- package/src/table-settings-drawer.test.tsx +350 -0
- package/src/table-settings-drawer.tsx +254 -0
- package/src/table-toolbar.module.scss +17 -0
- package/src/table-toolbar.test.tsx +95 -0
- package/src/table-toolbar.tsx +136 -0
- package/src/table.module.scss +367 -0
- package/src/table.stories.tsx +1246 -0
- package/src/table.story.css +11 -0
- package/src/table.test.tsx +318 -0
- package/src/table.tsx +501 -0
- package/src/test-utils/column-def.ts +152 -0
- package/src/test-utils/helpers.ts +234 -0
- package/src/test-utils/table-data.tsx +318 -0
- package/src/types.ts +496 -0
- package/src/use-screen-size.hook.ts +23 -0
- package/src/use-truncated-hook.tsx +74 -0
- package/src/utils/custom-functions.ts +52 -0
- package/src/utils/unit-conversions.spec.ts +92 -0
- package/src/utils/unit-conversions.ts +30 -0
- package/vitest.setup.ts +60 -0
|
@@ -0,0 +1,1246 @@
|
|
|
1
|
+
/* eslint-disable react-hooks/rules-of-hooks */
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
import React, { useEffect, useState } from "react";
|
|
6
|
+
import { Grid } from "@purpurds/grid";
|
|
7
|
+
import { IllustrativeIconSearchQuestionDuocolor } from "@purpurds/illustrative-icon/search-question-duocolor";
|
|
8
|
+
import { Pagination, PaginationProps } from "@purpurds/pagination";
|
|
9
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
10
|
+
import c from "classnames";
|
|
11
|
+
|
|
12
|
+
import "./table.story.css";
|
|
13
|
+
import "@purpurds/autocomplete/styles";
|
|
14
|
+
import "@purpurds/badge/styles";
|
|
15
|
+
import "@purpurds/button/styles";
|
|
16
|
+
import "@purpurds/checkbox/styles";
|
|
17
|
+
import "@purpurds/cta-link/styles";
|
|
18
|
+
import "@purpurds/drawer/styles";
|
|
19
|
+
import "@purpurds/grid/styles";
|
|
20
|
+
import "@purpurds/icon/styles";
|
|
21
|
+
import "@purpurds/label/styles";
|
|
22
|
+
import "@purpurds/link/styles";
|
|
23
|
+
import "@purpurds/listbox/styles";
|
|
24
|
+
import "@purpurds/pagination/styles";
|
|
25
|
+
import "@purpurds/paragraph/styles";
|
|
26
|
+
import "@purpurds/select/styles";
|
|
27
|
+
import "@purpurds/skeleton/styles";
|
|
28
|
+
import "@purpurds/text-field/styles";
|
|
29
|
+
import "@purpurds/toggle/styles";
|
|
30
|
+
import "@purpurds/tooltip/styles";
|
|
31
|
+
import { columnDef, simpleColumnDef } from "./story-utils/column-def";
|
|
32
|
+
import {
|
|
33
|
+
generateLargeTableData,
|
|
34
|
+
SimpleTableData,
|
|
35
|
+
simpleTableData,
|
|
36
|
+
TableData,
|
|
37
|
+
} from "./story-utils/table-data";
|
|
38
|
+
import { useFetchTableData } from "./story-utils/use-fetch-table-data-hook";
|
|
39
|
+
import type {
|
|
40
|
+
ColumnFiltersState,
|
|
41
|
+
PaginationState,
|
|
42
|
+
RowSelectionState,
|
|
43
|
+
VisibilityState,
|
|
44
|
+
} from "./table";
|
|
45
|
+
import { Table } from "./table";
|
|
46
|
+
|
|
47
|
+
const meta = {
|
|
48
|
+
title: "Components/Table",
|
|
49
|
+
component: Table,
|
|
50
|
+
parameters: {
|
|
51
|
+
controls: { expanded: true },
|
|
52
|
+
docs: {
|
|
53
|
+
description: {
|
|
54
|
+
component: `
|
|
55
|
+
<Markdown>
|
|
56
|
+
The Table component is built upon the powerful [TanStack Table](https://tanstack.com/table/v8) library, which provides a robust foundation for handling tabular data. This implementation extends TanStack Table with additional features and customizations specific to our design system.
|
|
57
|
+
|
|
58
|
+
## Features
|
|
59
|
+
|
|
60
|
+
### Core Functionality
|
|
61
|
+
- **Data Display**: Present tabular data with customizable columns
|
|
62
|
+
- **Responsive Design**: Adapts to different screen sizes
|
|
63
|
+
- **Variants**: Primary (default) and secondary styling options
|
|
64
|
+
- **Expandable**: Can expand to take full screen/container width
|
|
65
|
+
- **Sticky Headers**: Column headers can remain visible while scrolling
|
|
66
|
+
|
|
67
|
+
### Optional Features
|
|
68
|
+
- **Sorting**: Enable column sorting with customizable aria labels
|
|
69
|
+
- **Filtering**: Add column-specific filtering capabilities
|
|
70
|
+
- **Row Selection**: Allow users to select rows with checkboxes (multi-select) or radio buttons (single-select)
|
|
71
|
+
- **Pagination**: Paginate large datasets using the built-in pagination component
|
|
72
|
+
- **Toolbar**: Access table utilities like export, expand, and settings
|
|
73
|
+
- **Action Bar**: Provide action buttons for selected rows (requires enableActionBar={true})
|
|
74
|
+
- **Empty State**: Custom content for empty tables
|
|
75
|
+
- **Loading State**: Skeleton loading indication with customizable row count
|
|
76
|
+
|
|
77
|
+
For more details on the core functionality provided by TanStack Table, refer to their [official documentation](https://tanstack.com/table/v8/docs/overview).
|
|
78
|
+
</Markdown>
|
|
79
|
+
`,
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
argTypes: {
|
|
84
|
+
enableFilters: {
|
|
85
|
+
control: "boolean",
|
|
86
|
+
description: "Enables filtering functionality",
|
|
87
|
+
},
|
|
88
|
+
enableSorting: {
|
|
89
|
+
control: "boolean",
|
|
90
|
+
description: "Enables sorting functionality",
|
|
91
|
+
},
|
|
92
|
+
sortingAriaLabels: {
|
|
93
|
+
control: "object",
|
|
94
|
+
description: "Aria labels for sorting",
|
|
95
|
+
if: { arg: "enableSorting", truthy: true },
|
|
96
|
+
},
|
|
97
|
+
enableActionBar: {
|
|
98
|
+
control: "boolean",
|
|
99
|
+
description: "Enables action bar",
|
|
100
|
+
},
|
|
101
|
+
actionbarCopy: {
|
|
102
|
+
control: "object",
|
|
103
|
+
description: "Copy for action bar",
|
|
104
|
+
if: { arg: "enableActionBar", truthy: true },
|
|
105
|
+
},
|
|
106
|
+
enableRowSelection: {
|
|
107
|
+
control: "boolean",
|
|
108
|
+
description: "Enables row selection",
|
|
109
|
+
},
|
|
110
|
+
enableMultiRowSelection: {
|
|
111
|
+
control: "boolean",
|
|
112
|
+
description:
|
|
113
|
+
"Enables multiple row selection (checkboxes). If set to false, radio buttons will be used for single selection.",
|
|
114
|
+
if: { arg: "enableRowSelection", truthy: true },
|
|
115
|
+
},
|
|
116
|
+
rowSelectionAriaLabels: {
|
|
117
|
+
control: "object",
|
|
118
|
+
description: "Copy for row selection",
|
|
119
|
+
},
|
|
120
|
+
enableToolbar: {
|
|
121
|
+
control: "boolean",
|
|
122
|
+
description: "Enables toolbar",
|
|
123
|
+
},
|
|
124
|
+
toolbarCopy: {
|
|
125
|
+
control: "object",
|
|
126
|
+
description: "Copy for toolbar",
|
|
127
|
+
if: { arg: "enableToolbar", truthy: true },
|
|
128
|
+
},
|
|
129
|
+
settingsDrawerCopy: {
|
|
130
|
+
control: "object",
|
|
131
|
+
description: "Copy for settings drawer",
|
|
132
|
+
if: { arg: "enableToolbar", truthy: true },
|
|
133
|
+
},
|
|
134
|
+
exportFormats: {
|
|
135
|
+
control: "select",
|
|
136
|
+
options: ["string", "array"],
|
|
137
|
+
mapping: {
|
|
138
|
+
string: "csv",
|
|
139
|
+
array: ["csv", "xlsx"],
|
|
140
|
+
},
|
|
141
|
+
description: "Export formats for the table",
|
|
142
|
+
},
|
|
143
|
+
exportDrawerCopy: {
|
|
144
|
+
control: "object",
|
|
145
|
+
description: "Copy for exports drawer",
|
|
146
|
+
if: { arg: "exportFormats", neq: "string" },
|
|
147
|
+
},
|
|
148
|
+
loading: {
|
|
149
|
+
control: "boolean",
|
|
150
|
+
description: "Loading state for the table",
|
|
151
|
+
},
|
|
152
|
+
variant: {
|
|
153
|
+
control: "select",
|
|
154
|
+
options: ["primary", "secondary"],
|
|
155
|
+
description: "Style variant for the table",
|
|
156
|
+
},
|
|
157
|
+
},
|
|
158
|
+
} satisfies Meta<typeof Table<TableData>>;
|
|
159
|
+
|
|
160
|
+
export default meta;
|
|
161
|
+
type StoryTableData = StoryObj<typeof Table<TableData>>;
|
|
162
|
+
type StorySimpleTableData = StoryObj<typeof Table<SimpleTableData>>;
|
|
163
|
+
|
|
164
|
+
// Generated data for examples
|
|
165
|
+
const generatedTableData = generateLargeTableData(100);
|
|
166
|
+
|
|
167
|
+
// Common components & props for stories
|
|
168
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
169
|
+
const renderTableContainer = (args: any, children: React.ReactNode) => {
|
|
170
|
+
return (
|
|
171
|
+
<div
|
|
172
|
+
style={{
|
|
173
|
+
paddingTop: "2rem",
|
|
174
|
+
paddingBottom: "5rem",
|
|
175
|
+
overflowY: "hidden",
|
|
176
|
+
backgroundColor:
|
|
177
|
+
args.variant === "secondary" ? "transparent" : "var(--purpur-color-background-secondary)",
|
|
178
|
+
}}
|
|
179
|
+
>
|
|
180
|
+
<Grid containerClassName={c({ ["escape-grid"]: args.isExpanded })}>{children}</Grid>
|
|
181
|
+
</div>
|
|
182
|
+
);
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
// Common props used across stories
|
|
186
|
+
const commonSortingAriaLabels = {
|
|
187
|
+
desc: "Sort descending",
|
|
188
|
+
asc: "Sort ascending",
|
|
189
|
+
default: "Sort column",
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
const commonActionbarCopy = {
|
|
193
|
+
buttons: {
|
|
194
|
+
cancel: "Cancel selection",
|
|
195
|
+
primary: "Primary button",
|
|
196
|
+
secondary: "Secondary button",
|
|
197
|
+
toggleSelected: "Show only selected rows",
|
|
198
|
+
},
|
|
199
|
+
selectedRowsCount: {
|
|
200
|
+
of: "of",
|
|
201
|
+
selected: "selected",
|
|
202
|
+
},
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
const commonToolbarCopy = {
|
|
206
|
+
buttons: {
|
|
207
|
+
export: "Export",
|
|
208
|
+
expand: "Expand",
|
|
209
|
+
settings: "Settings",
|
|
210
|
+
clearFilters: "Clear filters",
|
|
211
|
+
},
|
|
212
|
+
ariaLabels: {
|
|
213
|
+
clearFilters: "Clear all filters",
|
|
214
|
+
expand: "Expand the table",
|
|
215
|
+
export: "Open export drawer",
|
|
216
|
+
settings: "Open settings drawer",
|
|
217
|
+
},
|
|
218
|
+
rowCount: {
|
|
219
|
+
showing: "Showing",
|
|
220
|
+
of: "of",
|
|
221
|
+
rows: "rows",
|
|
222
|
+
},
|
|
223
|
+
};
|
|
224
|
+
|
|
225
|
+
const commonSettingsDrawerCopy = {
|
|
226
|
+
title: "Table settings",
|
|
227
|
+
generalSettings: {
|
|
228
|
+
header: "General settings",
|
|
229
|
+
toggles: {
|
|
230
|
+
showFilters: "Show Filters",
|
|
231
|
+
lockFirstcolumn: "Lock first column",
|
|
232
|
+
stickyHeader: "Sticky header",
|
|
233
|
+
rowSelection: "Row selection",
|
|
234
|
+
},
|
|
235
|
+
},
|
|
236
|
+
visibleColumns: {
|
|
237
|
+
header: "Visible columns",
|
|
238
|
+
},
|
|
239
|
+
buttons: {
|
|
240
|
+
closeDrawer: "Close drawer",
|
|
241
|
+
resetSettings: "Reset settings",
|
|
242
|
+
},
|
|
243
|
+
};
|
|
244
|
+
|
|
245
|
+
const commonExportDrawerCopy = {
|
|
246
|
+
title: "Export table",
|
|
247
|
+
bodyText: "Choose the format you want to export the table in.",
|
|
248
|
+
closeButtonText: "Close drawer",
|
|
249
|
+
link: "Export as",
|
|
250
|
+
};
|
|
251
|
+
|
|
252
|
+
const commonRowSelectionAriaLabels = {
|
|
253
|
+
header: "Select all rows",
|
|
254
|
+
row: "Select row",
|
|
255
|
+
};
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* Showcase demonstrates a fully-featured Table with all available functionality enabled.
|
|
259
|
+
*/
|
|
260
|
+
export const Showcase: StoryTableData = {
|
|
261
|
+
args: {
|
|
262
|
+
variant: "primary",
|
|
263
|
+
enableActionBar: true,
|
|
264
|
+
enableFilters: true,
|
|
265
|
+
enableSorting: true,
|
|
266
|
+
enableToolbar: true,
|
|
267
|
+
enableRowSelection: true,
|
|
268
|
+
enableMultiRowSelection: true,
|
|
269
|
+
exportFormats: ["csv", "xlsx"],
|
|
270
|
+
actionbarCopy: commonActionbarCopy,
|
|
271
|
+
exportDrawerCopy: commonExportDrawerCopy,
|
|
272
|
+
settingsDrawerCopy: commonSettingsDrawerCopy,
|
|
273
|
+
sortingAriaLabels: commonSortingAriaLabels,
|
|
274
|
+
onToggleExpand: () => {},
|
|
275
|
+
toolbarCopy: commonToolbarCopy,
|
|
276
|
+
rowSelectionAriaLabels: commonRowSelectionAriaLabels,
|
|
277
|
+
data: generatedTableData,
|
|
278
|
+
columns: columnDef,
|
|
279
|
+
loading: true,
|
|
280
|
+
},
|
|
281
|
+
parameters: {
|
|
282
|
+
docs: {
|
|
283
|
+
description: {
|
|
284
|
+
story: `
|
|
285
|
+
This example showcases a fully-featured Table with all available functionality enabled:
|
|
286
|
+
|
|
287
|
+
- **Row Selection**: Allows users to select multiple rows with checkboxes
|
|
288
|
+
- **Sorting**: Enables column sorting by clicking column headers
|
|
289
|
+
- **Filtering**: Provides column-specific filtering options
|
|
290
|
+
- **Toolbar**: Includes export, expand, and settings controls
|
|
291
|
+
- **Action Bar**: Shows when rows are selected with primary/secondary action buttons
|
|
292
|
+
- **Expandable Layout**: Demonstrates the table expansion capability
|
|
293
|
+
- **Pagination**: Shows how to integrate with the Pagination component
|
|
294
|
+
|
|
295
|
+
This example uses client-side data handling where all data is loaded at once and the table
|
|
296
|
+
manages filtering, sorting and pagination internally.
|
|
297
|
+
`,
|
|
298
|
+
},
|
|
299
|
+
},
|
|
300
|
+
},
|
|
301
|
+
render: (args) => {
|
|
302
|
+
const [pagination, setPagination] = useState<PaginationState>({
|
|
303
|
+
pageIndex: 0,
|
|
304
|
+
pageSize: 10,
|
|
305
|
+
});
|
|
306
|
+
const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([]);
|
|
307
|
+
const [rowSelection, setRowSelection] = useState<RowSelectionState>({});
|
|
308
|
+
const [columnVisibility, setColumnVisibility] = useState<VisibilityState>({});
|
|
309
|
+
|
|
310
|
+
const [displayData, setDisplayData] = useState(args.data);
|
|
311
|
+
const [rowCount, setRowCount] = useState(args.data.length);
|
|
312
|
+
|
|
313
|
+
const [showOnlySelectedRows, setShowOnlySelectedRows] = useState(false);
|
|
314
|
+
|
|
315
|
+
const [tableExpanded, setTableExpanded] = useState(false);
|
|
316
|
+
|
|
317
|
+
useEffect(() => {
|
|
318
|
+
if (showOnlySelectedRows) {
|
|
319
|
+
const selectedRows = Object.keys(rowSelection).filter(
|
|
320
|
+
(key) => (rowSelection as Record<string, unknown>)[key]
|
|
321
|
+
);
|
|
322
|
+
const filteredData = args.data.filter((row) => selectedRows.includes(`${row.id}`));
|
|
323
|
+
setDisplayData(filteredData);
|
|
324
|
+
} else {
|
|
325
|
+
setDisplayData(args.data);
|
|
326
|
+
}
|
|
327
|
+
}, [showOnlySelectedRows, rowSelection, args.data]);
|
|
328
|
+
|
|
329
|
+
const handlePrimaryButtonClick = () => {
|
|
330
|
+
console.log("Primary button clicked.", rowSelection);
|
|
331
|
+
};
|
|
332
|
+
|
|
333
|
+
const defaultArgs: PaginationProps = {
|
|
334
|
+
onPageChange: (page) => {
|
|
335
|
+
setPagination({
|
|
336
|
+
pageIndex: page.currentPage - 1,
|
|
337
|
+
pageSize: page.pageSize,
|
|
338
|
+
});
|
|
339
|
+
},
|
|
340
|
+
totalItems: rowCount,
|
|
341
|
+
availablePageSizes: [5, 10, 50],
|
|
342
|
+
currentPage: pagination.pageIndex + 1,
|
|
343
|
+
pageSize: pagination.pageSize,
|
|
344
|
+
pageSizeLabel: "Items per page",
|
|
345
|
+
nextButtonAriaLabel: "Go to next page",
|
|
346
|
+
nextButtonText: "Next",
|
|
347
|
+
outOfLabel: "of",
|
|
348
|
+
pageSelectorListBoxLabel: "Select a page",
|
|
349
|
+
pageSelectorNoOptionsText: "Page does not exist",
|
|
350
|
+
previousButtonAriaLabel: "Go to previous page",
|
|
351
|
+
previousButtonText: "Previous",
|
|
352
|
+
stepNumberPrefix: "Go to page",
|
|
353
|
+
};
|
|
354
|
+
|
|
355
|
+
return renderTableContainer(
|
|
356
|
+
{ ...args, isExpanded: tableExpanded },
|
|
357
|
+
/* @ts-expect-error Props are incompatible. Storybook issue after adding argTypes. */
|
|
358
|
+
<Table
|
|
359
|
+
className={c("table-max-height")}
|
|
360
|
+
enableSorting={args.enableSorting}
|
|
361
|
+
enableActionBar={args.enableActionBar}
|
|
362
|
+
variant={args.variant}
|
|
363
|
+
columns={args.columns}
|
|
364
|
+
data={displayData}
|
|
365
|
+
enableRowSelection={args.enableRowSelection}
|
|
366
|
+
enableMultiRowSelection={args.enableMultiRowSelection}
|
|
367
|
+
state={{ pagination, rowSelection, columnFilters, columnVisibility }}
|
|
368
|
+
exportFormats={args.exportFormats}
|
|
369
|
+
onExportData={args.exportFormats ? (e) => console.log("Export data", e) : undefined}
|
|
370
|
+
actionbarCopy={args.enableActionBar ? args.actionbarCopy : undefined}
|
|
371
|
+
sortingAriaLabels={args.enableSorting ? args.sortingAriaLabels : undefined}
|
|
372
|
+
settingsDrawerCopy={args.settingsDrawerCopy}
|
|
373
|
+
exportDrawerCopy={args.exportFormats ? args.exportDrawerCopy : undefined}
|
|
374
|
+
toolbarCopy={args.toolbarCopy}
|
|
375
|
+
enableFilters={args.enableFilters}
|
|
376
|
+
enableToolbar={args.enableToolbar}
|
|
377
|
+
loading={args.loading}
|
|
378
|
+
onToggleExpand={() => setTableExpanded((prev) => !prev)}
|
|
379
|
+
paginationComponent={<Pagination {...defaultArgs} />}
|
|
380
|
+
onRowsCountChange={setRowCount}
|
|
381
|
+
onColumnVisibilityChange={setColumnVisibility}
|
|
382
|
+
setShowOnlySelectedRows={setShowOnlySelectedRows}
|
|
383
|
+
showOnlySelectedRows={showOnlySelectedRows}
|
|
384
|
+
onRowSelectionChange={setRowSelection}
|
|
385
|
+
onColumnFiltersChange={setColumnFilters}
|
|
386
|
+
getRowId={(row: TableData) => `${row.id}`}
|
|
387
|
+
actionBarTotalRowCount={args.data.length}
|
|
388
|
+
onPaginationChange={setPagination}
|
|
389
|
+
onPrimaryButtonClick={handlePrimaryButtonClick}
|
|
390
|
+
onSecondaryButtonClick={() => console.log("Secondary button clicked")}
|
|
391
|
+
rowSelectionAriaLabels={args.rowSelectionAriaLabels}
|
|
392
|
+
/>
|
|
393
|
+
);
|
|
394
|
+
},
|
|
395
|
+
};
|
|
396
|
+
|
|
397
|
+
/**
|
|
398
|
+
* BaseTable shows a simple table with minimal configuration.
|
|
399
|
+
*/
|
|
400
|
+
export const BaseTable: StorySimpleTableData = {
|
|
401
|
+
args: {
|
|
402
|
+
variant: "primary",
|
|
403
|
+
},
|
|
404
|
+
parameters: {
|
|
405
|
+
docs: {
|
|
406
|
+
description: {
|
|
407
|
+
story: `
|
|
408
|
+
This example shows a basic Table with minimal configuration. It demonstrates the core
|
|
409
|
+
functionality without any advanced features like filtering, sorting, pagination, or row selection.
|
|
410
|
+
|
|
411
|
+
### How to enable this feature:
|
|
412
|
+
- Just provide the minimum required props: \`columns\` and \`data\`
|
|
413
|
+
|
|
414
|
+
### Key points:
|
|
415
|
+
- Basic column configuration with different cell types (leadText, bodyText, link)
|
|
416
|
+
- Simple data display with fixed width columns
|
|
417
|
+
- Default styling and behavior
|
|
418
|
+
`,
|
|
419
|
+
},
|
|
420
|
+
},
|
|
421
|
+
},
|
|
422
|
+
render: (args) => {
|
|
423
|
+
return renderTableContainer(
|
|
424
|
+
args,
|
|
425
|
+
<Table
|
|
426
|
+
variant={args.variant}
|
|
427
|
+
columns={simpleColumnDef}
|
|
428
|
+
data={simpleTableData}
|
|
429
|
+
enableSorting={false}
|
|
430
|
+
enableRowSelection={false}
|
|
431
|
+
enableToolbar={false}
|
|
432
|
+
enableActionBar={false}
|
|
433
|
+
/>
|
|
434
|
+
);
|
|
435
|
+
},
|
|
436
|
+
};
|
|
437
|
+
|
|
438
|
+
/**
|
|
439
|
+
* Demonstrates sorting functionality in the Table.
|
|
440
|
+
*/
|
|
441
|
+
export const SortingFeature: StorySimpleTableData = {
|
|
442
|
+
args: {
|
|
443
|
+
variant: "primary",
|
|
444
|
+
enableSorting: true,
|
|
445
|
+
sortingAriaLabels: commonSortingAriaLabels,
|
|
446
|
+
},
|
|
447
|
+
parameters: {
|
|
448
|
+
docs: {
|
|
449
|
+
description: {
|
|
450
|
+
story: `
|
|
451
|
+
This example demonstrates how to enable column sorting functionality in the Table.
|
|
452
|
+
|
|
453
|
+
### How to enable this feature:
|
|
454
|
+
\`\`\`jsx
|
|
455
|
+
<Table
|
|
456
|
+
enableSorting={true}
|
|
457
|
+
sortingAriaLabels={{
|
|
458
|
+
desc: "Sort descending",
|
|
459
|
+
asc: "Sort ascending",
|
|
460
|
+
default: "Sort column"
|
|
461
|
+
}}
|
|
462
|
+
...other props
|
|
463
|
+
/>
|
|
464
|
+
\`\`\`
|
|
465
|
+
|
|
466
|
+
### Key points:
|
|
467
|
+
- Click on column headers to sort the data
|
|
468
|
+
- Includes accessibility labels for sorting states
|
|
469
|
+
- Supports ascending and descending sorting
|
|
470
|
+
- When the table has sorted data, a visual indicator appears in the column header
|
|
471
|
+
`,
|
|
472
|
+
},
|
|
473
|
+
},
|
|
474
|
+
},
|
|
475
|
+
render: (args) => {
|
|
476
|
+
// Use simpleTableData instead of generatedTableData
|
|
477
|
+
return renderTableContainer(
|
|
478
|
+
args,
|
|
479
|
+
<Table
|
|
480
|
+
variant={args.variant}
|
|
481
|
+
columns={simpleColumnDef}
|
|
482
|
+
data={simpleTableData}
|
|
483
|
+
enableRowSelection={false}
|
|
484
|
+
enableToolbar={false}
|
|
485
|
+
enableActionBar={false}
|
|
486
|
+
{...(args.enableSorting
|
|
487
|
+
? {
|
|
488
|
+
enableSorting: true,
|
|
489
|
+
sortingAriaLabels: args.sortingAriaLabels,
|
|
490
|
+
}
|
|
491
|
+
: {
|
|
492
|
+
enableSorting: false,
|
|
493
|
+
})}
|
|
494
|
+
/>
|
|
495
|
+
);
|
|
496
|
+
},
|
|
497
|
+
};
|
|
498
|
+
|
|
499
|
+
/**
|
|
500
|
+
* Demonstrates filtering functionality in the Table.
|
|
501
|
+
*/
|
|
502
|
+
export const FilteringFeature: StorySimpleTableData = {
|
|
503
|
+
args: {
|
|
504
|
+
variant: "primary",
|
|
505
|
+
enableFilters: true,
|
|
506
|
+
},
|
|
507
|
+
parameters: {
|
|
508
|
+
docs: {
|
|
509
|
+
description: {
|
|
510
|
+
story: `
|
|
511
|
+
This example demonstrates column filtering functionality in the Table.
|
|
512
|
+
|
|
513
|
+
### How to enable this feature:
|
|
514
|
+
\`\`\`jsx
|
|
515
|
+
<Table
|
|
516
|
+
enableFilters={true}
|
|
517
|
+
...other props
|
|
518
|
+
/>
|
|
519
|
+
\`\`\`
|
|
520
|
+
|
|
521
|
+
### Key points:
|
|
522
|
+
- Filter inputs appear below column headers
|
|
523
|
+
- Provides real-time filtering as users type
|
|
524
|
+
- Each column can have its own filter
|
|
525
|
+
`,
|
|
526
|
+
},
|
|
527
|
+
},
|
|
528
|
+
},
|
|
529
|
+
render: (args) => {
|
|
530
|
+
const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([]);
|
|
531
|
+
|
|
532
|
+
return renderTableContainer(
|
|
533
|
+
args,
|
|
534
|
+
<Table
|
|
535
|
+
variant={args.variant}
|
|
536
|
+
columns={simpleColumnDef}
|
|
537
|
+
data={simpleTableData}
|
|
538
|
+
enableFilters={args.enableFilters}
|
|
539
|
+
enableSorting={false}
|
|
540
|
+
enableRowSelection={false}
|
|
541
|
+
enableToolbar={false}
|
|
542
|
+
enableActionBar={false}
|
|
543
|
+
state={{ columnFilters }}
|
|
544
|
+
onColumnFiltersChange={setColumnFilters}
|
|
545
|
+
/>
|
|
546
|
+
);
|
|
547
|
+
},
|
|
548
|
+
};
|
|
549
|
+
|
|
550
|
+
/**
|
|
551
|
+
* Demonstrates row selection with checkboxes (multi-select) in the Table.
|
|
552
|
+
*/
|
|
553
|
+
export const RowSelectionMulti: StorySimpleTableData = {
|
|
554
|
+
args: {
|
|
555
|
+
variant: "primary",
|
|
556
|
+
enableRowSelection: true,
|
|
557
|
+
enableMultiRowSelection: true,
|
|
558
|
+
rowSelectionAriaLabels: commonRowSelectionAriaLabels,
|
|
559
|
+
},
|
|
560
|
+
parameters: {
|
|
561
|
+
docs: {
|
|
562
|
+
description: {
|
|
563
|
+
story: `
|
|
564
|
+
This example demonstrates multi-row selection functionality with checkboxes.
|
|
565
|
+
|
|
566
|
+
### How to enable this feature:
|
|
567
|
+
\`\`\`jsx
|
|
568
|
+
<Table
|
|
569
|
+
enableRowSelection={true}
|
|
570
|
+
enableMultiRowSelection={true}
|
|
571
|
+
rowSelectionAriaLabels={{
|
|
572
|
+
header: "Select all rows",
|
|
573
|
+
row: "Select row"
|
|
574
|
+
}}
|
|
575
|
+
state={{ rowSelection }}
|
|
576
|
+
onRowSelectionChange={setRowSelection}
|
|
577
|
+
...other props
|
|
578
|
+
/>
|
|
579
|
+
\`\`\`
|
|
580
|
+
|
|
581
|
+
### Key points:
|
|
582
|
+
- Adds checkboxes to each row and in the header
|
|
583
|
+
- Header checkbox functions as a "select all" control
|
|
584
|
+
- Selected rows are highlighted
|
|
585
|
+
- Row selection state can be controlled externally
|
|
586
|
+
- Accessible with proper ARIA labels
|
|
587
|
+
`,
|
|
588
|
+
},
|
|
589
|
+
},
|
|
590
|
+
},
|
|
591
|
+
render: (args) => {
|
|
592
|
+
const [rowSelection, setRowSelection] = useState<RowSelectionState>({});
|
|
593
|
+
const [showOnlySelectedRows, setShowOnlySelectedRows] = useState(false);
|
|
594
|
+
|
|
595
|
+
return renderTableContainer(
|
|
596
|
+
args,
|
|
597
|
+
<Table
|
|
598
|
+
variant={args.variant}
|
|
599
|
+
columns={simpleColumnDef}
|
|
600
|
+
data={simpleTableData}
|
|
601
|
+
state={{ rowSelection }}
|
|
602
|
+
enableRowSelection={true}
|
|
603
|
+
enableMultiRowSelection={true}
|
|
604
|
+
rowSelectionAriaLabels={commonRowSelectionAriaLabels}
|
|
605
|
+
onRowSelectionChange={setRowSelection}
|
|
606
|
+
showOnlySelectedRows={showOnlySelectedRows}
|
|
607
|
+
setShowOnlySelectedRows={setShowOnlySelectedRows}
|
|
608
|
+
/>
|
|
609
|
+
);
|
|
610
|
+
},
|
|
611
|
+
};
|
|
612
|
+
|
|
613
|
+
/**
|
|
614
|
+
* Demonstrates row selection with radio buttons (single-select) in the Table.
|
|
615
|
+
*/
|
|
616
|
+
export const RowSelectionSingle: StorySimpleTableData = {
|
|
617
|
+
args: {
|
|
618
|
+
variant: "primary",
|
|
619
|
+
enableRowSelection: true,
|
|
620
|
+
enableMultiRowSelection: false,
|
|
621
|
+
rowSelectionAriaLabels: commonRowSelectionAriaLabels,
|
|
622
|
+
},
|
|
623
|
+
parameters: {
|
|
624
|
+
docs: {
|
|
625
|
+
description: {
|
|
626
|
+
story: `
|
|
627
|
+
This example demonstrates single-row selection functionality with radio buttons.
|
|
628
|
+
|
|
629
|
+
### How to enable this feature:
|
|
630
|
+
\`\`\`jsx
|
|
631
|
+
<Table
|
|
632
|
+
enableRowSelection={true}
|
|
633
|
+
enableMultiRowSelection={false}
|
|
634
|
+
rowSelectionAriaLabels={{
|
|
635
|
+
header: "Select all rows",
|
|
636
|
+
row: "Select row"
|
|
637
|
+
}}
|
|
638
|
+
state={{ rowSelection }}
|
|
639
|
+
onRowSelectionChange={setRowSelection}
|
|
640
|
+
...other props
|
|
641
|
+
/>
|
|
642
|
+
\`\`\`
|
|
643
|
+
|
|
644
|
+
### Key points:
|
|
645
|
+
- Adds radio buttons to each row (instead of checkboxes)
|
|
646
|
+
- Only one row can be selected at a time
|
|
647
|
+
- Selected rows are highlighted
|
|
648
|
+
- Accessible with proper ARIA labels
|
|
649
|
+
`,
|
|
650
|
+
},
|
|
651
|
+
},
|
|
652
|
+
},
|
|
653
|
+
render: (args) => {
|
|
654
|
+
const [rowSelection, setRowSelection] = useState<RowSelectionState>({});
|
|
655
|
+
const [showOnlySelectedRows, setShowOnlySelectedRows] = useState(false);
|
|
656
|
+
|
|
657
|
+
return renderTableContainer(
|
|
658
|
+
args,
|
|
659
|
+
<Table
|
|
660
|
+
variant={args.variant}
|
|
661
|
+
columns={simpleColumnDef}
|
|
662
|
+
data={simpleTableData}
|
|
663
|
+
enableRowSelection={true}
|
|
664
|
+
enableSorting={false}
|
|
665
|
+
enableToolbar={false}
|
|
666
|
+
enableActionBar={false}
|
|
667
|
+
enableMultiRowSelection={false}
|
|
668
|
+
rowSelectionAriaLabels={commonRowSelectionAriaLabels}
|
|
669
|
+
state={{ rowSelection }}
|
|
670
|
+
onRowSelectionChange={setRowSelection}
|
|
671
|
+
getRowId={(row: SimpleTableData) => `${row.id}`}
|
|
672
|
+
showOnlySelectedRows={showOnlySelectedRows}
|
|
673
|
+
setShowOnlySelectedRows={setShowOnlySelectedRows}
|
|
674
|
+
/>
|
|
675
|
+
);
|
|
676
|
+
},
|
|
677
|
+
};
|
|
678
|
+
|
|
679
|
+
/**
|
|
680
|
+
* Demonstrates pagination in the Table.
|
|
681
|
+
*/
|
|
682
|
+
export const PaginationFeature: StoryTableData = {
|
|
683
|
+
args: {
|
|
684
|
+
variant: "primary",
|
|
685
|
+
},
|
|
686
|
+
parameters: {
|
|
687
|
+
docs: {
|
|
688
|
+
description: {
|
|
689
|
+
story: `
|
|
690
|
+
This example demonstrates pagination functionality in the Table.
|
|
691
|
+
|
|
692
|
+
### How to enable this feature:
|
|
693
|
+
\`\`\`jsx
|
|
694
|
+
<Table
|
|
695
|
+
paginationComponent={<Pagination {...paginationProps} />}
|
|
696
|
+
state={{ pagination }}
|
|
697
|
+
onPaginationChange={setPagination}
|
|
698
|
+
...other props
|
|
699
|
+
/>
|
|
700
|
+
\`\`\`
|
|
701
|
+
|
|
702
|
+
### Key points:
|
|
703
|
+
- Displays data in manageable chunks
|
|
704
|
+
- Use \`paginationComponent\` prop to provide a Pagination component
|
|
705
|
+
- The table automatically connects to the pagination controls
|
|
706
|
+
- Supports page size selection
|
|
707
|
+
- Store pagination state in your component's state
|
|
708
|
+
`,
|
|
709
|
+
},
|
|
710
|
+
},
|
|
711
|
+
},
|
|
712
|
+
render: (args) => {
|
|
713
|
+
const [pagination, setPagination] = useState<PaginationState>({
|
|
714
|
+
pageIndex: 0,
|
|
715
|
+
pageSize: 5,
|
|
716
|
+
});
|
|
717
|
+
|
|
718
|
+
const paginationProps: PaginationProps = {
|
|
719
|
+
onPageChange: (page) => {
|
|
720
|
+
setPagination({
|
|
721
|
+
pageIndex: page.currentPage - 1,
|
|
722
|
+
pageSize: page.pageSize,
|
|
723
|
+
});
|
|
724
|
+
},
|
|
725
|
+
totalItems: generatedTableData.length,
|
|
726
|
+
availablePageSizes: [5, 10, 20],
|
|
727
|
+
currentPage: pagination.pageIndex + 1,
|
|
728
|
+
pageSize: pagination.pageSize,
|
|
729
|
+
pageSizeLabel: "Items per page",
|
|
730
|
+
nextButtonAriaLabel: "Go to next page",
|
|
731
|
+
nextButtonText: "Next",
|
|
732
|
+
outOfLabel: "of",
|
|
733
|
+
pageSelectorListBoxLabel: "Select a page",
|
|
734
|
+
pageSelectorNoOptionsText: "Page does not exist",
|
|
735
|
+
previousButtonAriaLabel: "Go to previous page",
|
|
736
|
+
previousButtonText: "Previous",
|
|
737
|
+
stepNumberPrefix: "Go to page",
|
|
738
|
+
};
|
|
739
|
+
|
|
740
|
+
return renderTableContainer(
|
|
741
|
+
args,
|
|
742
|
+
<Table
|
|
743
|
+
variant={args.variant}
|
|
744
|
+
columns={columnDef}
|
|
745
|
+
data={generatedTableData}
|
|
746
|
+
enableSorting={false}
|
|
747
|
+
enableRowSelection={false}
|
|
748
|
+
enableToolbar={false}
|
|
749
|
+
enableActionBar={false}
|
|
750
|
+
state={{ pagination }}
|
|
751
|
+
onPaginationChange={setPagination}
|
|
752
|
+
paginationComponent={<Pagination {...paginationProps} />}
|
|
753
|
+
/>
|
|
754
|
+
);
|
|
755
|
+
},
|
|
756
|
+
};
|
|
757
|
+
|
|
758
|
+
/**
|
|
759
|
+
* Demonstrates the toolbar feature in the Table.
|
|
760
|
+
*/
|
|
761
|
+
export const ToolbarFeature: StorySimpleTableData = {
|
|
762
|
+
args: {
|
|
763
|
+
variant: "primary",
|
|
764
|
+
enableToolbar: true,
|
|
765
|
+
enableFilters: true,
|
|
766
|
+
toolbarCopy: commonToolbarCopy,
|
|
767
|
+
settingsDrawerCopy: commonSettingsDrawerCopy,
|
|
768
|
+
exportFormats: ["csv", "xlsx"],
|
|
769
|
+
exportDrawerCopy: commonExportDrawerCopy,
|
|
770
|
+
},
|
|
771
|
+
parameters: {
|
|
772
|
+
docs: {
|
|
773
|
+
description: {
|
|
774
|
+
story: `
|
|
775
|
+
This example demonstrates the toolbar functionality in the Table.
|
|
776
|
+
|
|
777
|
+
### How to enable this feature:
|
|
778
|
+
\`\`\`jsx
|
|
779
|
+
<Table
|
|
780
|
+
enableToolbar={true}
|
|
781
|
+
toolbarCopy={{...}} // Text content for toolbar buttons
|
|
782
|
+
settingsDrawerCopy={{...}} // Text content for settings drawer
|
|
783
|
+
exportFormats={["csv", "xlsx"]} // Optional export formats
|
|
784
|
+
exportDrawerCopy={{...}} // Text content for export drawer
|
|
785
|
+
onToggleExpand={handleToggleExpand}
|
|
786
|
+
onExportData={handleExport}
|
|
787
|
+
...other props
|
|
788
|
+
/>
|
|
789
|
+
\`\`\`
|
|
790
|
+
|
|
791
|
+
### Key points:
|
|
792
|
+
- Provides controls for table management
|
|
793
|
+
- Features can include:
|
|
794
|
+
- Export functionality (CSV, Excel)
|
|
795
|
+
- Table expansion
|
|
796
|
+
- Settings management (column visibility, sticky headers, etc.)
|
|
797
|
+
- Filter clearing
|
|
798
|
+
- Displays row count information
|
|
799
|
+
`,
|
|
800
|
+
},
|
|
801
|
+
},
|
|
802
|
+
},
|
|
803
|
+
render: (args) => {
|
|
804
|
+
const [tableExpanded, setTableExpanded] = useState(false);
|
|
805
|
+
const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([]);
|
|
806
|
+
const [columnVisibility, setColumnVisibility] = useState<VisibilityState>({});
|
|
807
|
+
|
|
808
|
+
return renderTableContainer(
|
|
809
|
+
{ ...args, isExpanded: tableExpanded },
|
|
810
|
+
<Table
|
|
811
|
+
variant={args.variant}
|
|
812
|
+
columns={simpleColumnDef}
|
|
813
|
+
data={simpleTableData}
|
|
814
|
+
enableToolbar={true}
|
|
815
|
+
enableSorting={false}
|
|
816
|
+
enableRowSelection={false}
|
|
817
|
+
enableActionBar={false}
|
|
818
|
+
enableFilters={true}
|
|
819
|
+
toolbarCopy={commonToolbarCopy}
|
|
820
|
+
settingsDrawerCopy={commonSettingsDrawerCopy}
|
|
821
|
+
exportFormats={["csv", "xlsx"]}
|
|
822
|
+
exportDrawerCopy={commonExportDrawerCopy}
|
|
823
|
+
onToggleExpand={() => setTableExpanded((prev) => !prev)}
|
|
824
|
+
onExportData={(format) => console.log(`Exporting in ${format} format`)}
|
|
825
|
+
state={{ columnFilters, columnVisibility }}
|
|
826
|
+
onColumnFiltersChange={setColumnFilters}
|
|
827
|
+
onColumnVisibilityChange={setColumnVisibility}
|
|
828
|
+
/>
|
|
829
|
+
);
|
|
830
|
+
},
|
|
831
|
+
};
|
|
832
|
+
|
|
833
|
+
/**
|
|
834
|
+
* Demonstrates the action bar feature for selected rows in the Table.
|
|
835
|
+
*/
|
|
836
|
+
export const ActionBarFeature: StoryTableData = {
|
|
837
|
+
args: {
|
|
838
|
+
variant: "primary",
|
|
839
|
+
enableRowSelection: true,
|
|
840
|
+
enableMultiRowSelection: true,
|
|
841
|
+
enableActionBar: true,
|
|
842
|
+
actionbarCopy: commonActionbarCopy,
|
|
843
|
+
rowSelectionAriaLabels: commonRowSelectionAriaLabels,
|
|
844
|
+
},
|
|
845
|
+
parameters: {
|
|
846
|
+
docs: {
|
|
847
|
+
description: {
|
|
848
|
+
story: `
|
|
849
|
+
This example demonstrates the action bar for selected rows.
|
|
850
|
+
|
|
851
|
+
### How to enable this feature:
|
|
852
|
+
\`\`\`jsx
|
|
853
|
+
<Table
|
|
854
|
+
enableActionBar={true}
|
|
855
|
+
enableRowSelection={true}
|
|
856
|
+
actionbarCopy={{...}}
|
|
857
|
+
actionBarTotalRowCount={totalRowCount}
|
|
858
|
+
onPrimaryButtonClick={handlePrimaryAction}
|
|
859
|
+
onSecondaryButtonClick={handleSecondaryAction}
|
|
860
|
+
...other props
|
|
861
|
+
/>
|
|
862
|
+
\`\`\`
|
|
863
|
+
|
|
864
|
+
### Key points:
|
|
865
|
+
- Appears when rows are selected
|
|
866
|
+
- Shows count of selected rows
|
|
867
|
+
- Provides primary and secondary action buttons
|
|
868
|
+
- Allows filtering to show only selected rows
|
|
869
|
+
- Includes a cancel selection button
|
|
870
|
+
`,
|
|
871
|
+
},
|
|
872
|
+
},
|
|
873
|
+
},
|
|
874
|
+
render: (args) => {
|
|
875
|
+
const [rowSelection, setRowSelection] = useState<RowSelectionState>({});
|
|
876
|
+
const [showOnlySelectedRows, setShowOnlySelectedRows] = useState(false);
|
|
877
|
+
const [displayData, setDisplayData] = useState(simpleTableData);
|
|
878
|
+
|
|
879
|
+
const totalRowCount = simpleTableData.length;
|
|
880
|
+
|
|
881
|
+
useEffect(() => {
|
|
882
|
+
if (showOnlySelectedRows) {
|
|
883
|
+
const selectedRows = Object.keys(rowSelection).filter(
|
|
884
|
+
(key) => (rowSelection as Record<string, unknown>)[key]
|
|
885
|
+
);
|
|
886
|
+
const filteredData = simpleTableData.filter((row) => selectedRows.includes(`${row.id}`));
|
|
887
|
+
setDisplayData(filteredData);
|
|
888
|
+
} else {
|
|
889
|
+
setDisplayData(simpleTableData);
|
|
890
|
+
}
|
|
891
|
+
}, [showOnlySelectedRows, rowSelection]);
|
|
892
|
+
|
|
893
|
+
const handlePrimaryButtonClick = () => {
|
|
894
|
+
console.log("Primary action on selected rows", rowSelection);
|
|
895
|
+
};
|
|
896
|
+
|
|
897
|
+
const handleSecondaryButtonClick = () => {
|
|
898
|
+
console.log("Secondary action on selected rows", rowSelection);
|
|
899
|
+
};
|
|
900
|
+
|
|
901
|
+
return renderTableContainer(
|
|
902
|
+
args,
|
|
903
|
+
<Table<SimpleTableData>
|
|
904
|
+
variant={args.variant}
|
|
905
|
+
columns={simpleColumnDef}
|
|
906
|
+
data={displayData}
|
|
907
|
+
enableRowSelection={true}
|
|
908
|
+
enableActionBar={true}
|
|
909
|
+
enableToolbar={false}
|
|
910
|
+
enableSorting={false}
|
|
911
|
+
enableMultiRowSelection={true}
|
|
912
|
+
actionbarCopy={commonActionbarCopy}
|
|
913
|
+
rowSelectionAriaLabels={commonRowSelectionAriaLabels}
|
|
914
|
+
state={{ rowSelection }}
|
|
915
|
+
onRowSelectionChange={setRowSelection}
|
|
916
|
+
getRowId={(row: SimpleTableData) => `${row.id}`}
|
|
917
|
+
actionBarTotalRowCount={totalRowCount}
|
|
918
|
+
showOnlySelectedRows={showOnlySelectedRows}
|
|
919
|
+
setShowOnlySelectedRows={setShowOnlySelectedRows}
|
|
920
|
+
onPrimaryButtonClick={handlePrimaryButtonClick}
|
|
921
|
+
onSecondaryButtonClick={handleSecondaryButtonClick}
|
|
922
|
+
/>
|
|
923
|
+
);
|
|
924
|
+
},
|
|
925
|
+
};
|
|
926
|
+
|
|
927
|
+
/**
|
|
928
|
+
* Demonstrates empty state configuration in the Table.
|
|
929
|
+
*/
|
|
930
|
+
export const EmptyTable: StoryTableData = {
|
|
931
|
+
args: {
|
|
932
|
+
variant: "primary",
|
|
933
|
+
emptyTableCopy: {
|
|
934
|
+
title: "Title empty table",
|
|
935
|
+
description: "Body text explaining why the table is empty and what the user can do.",
|
|
936
|
+
},
|
|
937
|
+
emptyTableHeadingTag: "h2",
|
|
938
|
+
},
|
|
939
|
+
parameters: {
|
|
940
|
+
docs: {
|
|
941
|
+
description: {
|
|
942
|
+
story: `
|
|
943
|
+
This example demonstrates how to configure the Table to display a custom empty state
|
|
944
|
+
when there is no data to show.
|
|
945
|
+
|
|
946
|
+
### How to enable this feature:
|
|
947
|
+
\`\`\`jsx
|
|
948
|
+
<Table
|
|
949
|
+
emptyTableCopy={{
|
|
950
|
+
title: "No data found",
|
|
951
|
+
description: "There are no items to display."
|
|
952
|
+
}}
|
|
953
|
+
emptyTableHeadingTag="h2"
|
|
954
|
+
emptyTableIcon={<YourCustomIcon />}
|
|
955
|
+
...other props
|
|
956
|
+
/>
|
|
957
|
+
\`\`\`
|
|
958
|
+
|
|
959
|
+
### Key points:
|
|
960
|
+
- Custom empty state messaging with title and description
|
|
961
|
+
- Visual element (icon) to enhance the empty state
|
|
962
|
+
- Custom heading tag specification for accessibility
|
|
963
|
+
- Proper layout and styling of empty state content
|
|
964
|
+
`,
|
|
965
|
+
},
|
|
966
|
+
},
|
|
967
|
+
},
|
|
968
|
+
render: (args) => {
|
|
969
|
+
const tableData: SimpleTableData[] = [];
|
|
970
|
+
|
|
971
|
+
const emptyTableProps = {
|
|
972
|
+
emptyTableCopy: {
|
|
973
|
+
title: args.emptyTableCopy?.title || "No data found",
|
|
974
|
+
description: args.emptyTableCopy?.description || "There are no items to display.",
|
|
975
|
+
},
|
|
976
|
+
emptyTableHeadingTag: args.emptyTableHeadingTag || "h2",
|
|
977
|
+
};
|
|
978
|
+
|
|
979
|
+
return renderTableContainer(
|
|
980
|
+
args,
|
|
981
|
+
<Table
|
|
982
|
+
variant={args.variant}
|
|
983
|
+
columns={simpleColumnDef}
|
|
984
|
+
data={tableData}
|
|
985
|
+
enableSorting={false}
|
|
986
|
+
enableRowSelection={false}
|
|
987
|
+
enableToolbar={false}
|
|
988
|
+
enableActionBar={false}
|
|
989
|
+
emptyTableCopy={emptyTableProps.emptyTableCopy}
|
|
990
|
+
emptyTableHeadingTag={emptyTableProps.emptyTableHeadingTag}
|
|
991
|
+
emptyTableIcon={<IllustrativeIconSearchQuestionDuocolor />}
|
|
992
|
+
/>
|
|
993
|
+
);
|
|
994
|
+
},
|
|
995
|
+
};
|
|
996
|
+
|
|
997
|
+
/**
|
|
998
|
+
* Demonstrates loading state in the Table.
|
|
999
|
+
*/
|
|
1000
|
+
export const LoadingTable: StorySimpleTableData = {
|
|
1001
|
+
args: {
|
|
1002
|
+
variant: "primary",
|
|
1003
|
+
loading: true,
|
|
1004
|
+
skeletonRows: 5,
|
|
1005
|
+
},
|
|
1006
|
+
parameters: {
|
|
1007
|
+
docs: {
|
|
1008
|
+
description: {
|
|
1009
|
+
story: `
|
|
1010
|
+
This example demonstrates the loading state of the Table component.
|
|
1011
|
+
|
|
1012
|
+
### How to enable this feature:
|
|
1013
|
+
\`\`\`jsx
|
|
1014
|
+
<Table
|
|
1015
|
+
loading={true}
|
|
1016
|
+
skeletonRows={5}
|
|
1017
|
+
...other props
|
|
1018
|
+
/>
|
|
1019
|
+
\`\`\`
|
|
1020
|
+
|
|
1021
|
+
### Key points:
|
|
1022
|
+
- Loading skeleton animation for rows and cells
|
|
1023
|
+
- Configurable number of skeleton rows with the \`skeletonRows\` prop
|
|
1024
|
+
- Visual indication to users that content is loading
|
|
1025
|
+
- Proper styling that maintains table structure during loading
|
|
1026
|
+
`,
|
|
1027
|
+
},
|
|
1028
|
+
},
|
|
1029
|
+
},
|
|
1030
|
+
render: (args) => {
|
|
1031
|
+
const loading = Boolean(args.loading);
|
|
1032
|
+
|
|
1033
|
+
return renderTableContainer(
|
|
1034
|
+
args,
|
|
1035
|
+
<Table
|
|
1036
|
+
variant={args.variant}
|
|
1037
|
+
columns={simpleColumnDef}
|
|
1038
|
+
data={simpleTableData}
|
|
1039
|
+
enableSorting={false}
|
|
1040
|
+
enableRowSelection={false}
|
|
1041
|
+
enableMultiRowSelection={false}
|
|
1042
|
+
enableToolbar={false}
|
|
1043
|
+
enableActionBar={false}
|
|
1044
|
+
loading={loading}
|
|
1045
|
+
skeletonRows={args.skeletonRows || 5}
|
|
1046
|
+
/>
|
|
1047
|
+
);
|
|
1048
|
+
},
|
|
1049
|
+
};
|
|
1050
|
+
|
|
1051
|
+
/**
|
|
1052
|
+
* Demonstrates server-side data handling for the Table.
|
|
1053
|
+
*/
|
|
1054
|
+
export const ServerDataHandlingTable: StoryTableData = {
|
|
1055
|
+
args: {
|
|
1056
|
+
variant: "primary",
|
|
1057
|
+
enableActionBar: true,
|
|
1058
|
+
enableFilters: true,
|
|
1059
|
+
enableSorting: true,
|
|
1060
|
+
enableToolbar: true,
|
|
1061
|
+
enableRowSelection: true,
|
|
1062
|
+
enableMultiRowSelection: true,
|
|
1063
|
+
exportFormats: ["csv", "xlsx"],
|
|
1064
|
+
actionbarCopy: commonActionbarCopy,
|
|
1065
|
+
exportDrawerCopy: commonExportDrawerCopy,
|
|
1066
|
+
settingsDrawerCopy: commonSettingsDrawerCopy,
|
|
1067
|
+
sortingAriaLabels: commonSortingAriaLabels,
|
|
1068
|
+
toolbarCopy: commonToolbarCopy,
|
|
1069
|
+
rowSelectionAriaLabels: commonRowSelectionAriaLabels,
|
|
1070
|
+
manualPagination: true,
|
|
1071
|
+
manualSorting: true,
|
|
1072
|
+
manualFiltering: true,
|
|
1073
|
+
columns: columnDef,
|
|
1074
|
+
},
|
|
1075
|
+
parameters: {
|
|
1076
|
+
docs: {
|
|
1077
|
+
description: {
|
|
1078
|
+
story: `
|
|
1079
|
+
This example demonstrates how to implement server-side data handling where pagination,
|
|
1080
|
+
sorting, and filtering are managed by a server API instead of in the browser.
|
|
1081
|
+
|
|
1082
|
+
### How to enable this feature:
|
|
1083
|
+
\`\`\`jsx
|
|
1084
|
+
<Table
|
|
1085
|
+
manualPagination={true}
|
|
1086
|
+
manualSorting={true}
|
|
1087
|
+
manualFiltering={true}
|
|
1088
|
+
onPaginationChange={fetchPageData}
|
|
1089
|
+
onColumnFiltersChange={applyFilters}
|
|
1090
|
+
...other props
|
|
1091
|
+
/>
|
|
1092
|
+
\`\`\`
|
|
1093
|
+
|
|
1094
|
+
### Key points:
|
|
1095
|
+
- Set \`manualPagination\`, \`manualSorting\`, and \`manualFiltering\` to true
|
|
1096
|
+
- Implement handlers for change events to fetch new data from server
|
|
1097
|
+
- Display correct total row count via \`toolbarTotalRowCount\`
|
|
1098
|
+
- Maintain row selection with server-side pagination
|
|
1099
|
+
- Handle state updates to trigger appropriate refetching of data
|
|
1100
|
+
`,
|
|
1101
|
+
},
|
|
1102
|
+
},
|
|
1103
|
+
},
|
|
1104
|
+
render: (args) => {
|
|
1105
|
+
const [pagination, setPagination] = useState<PaginationState>({
|
|
1106
|
+
pageIndex: 0,
|
|
1107
|
+
pageSize: 10,
|
|
1108
|
+
});
|
|
1109
|
+
const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([]);
|
|
1110
|
+
const [rowSelection, setRowSelection] = useState<RowSelectionState>({});
|
|
1111
|
+
const [columnVisibility, setColumnVisibility] = useState<VisibilityState>({});
|
|
1112
|
+
|
|
1113
|
+
const [tableExpanded, setTableExpanded] = useState(false);
|
|
1114
|
+
const [displayData, setDisplayData] = useState<TableData[]>([]);
|
|
1115
|
+
const [showOnlySelectedRows, setShowOnlySelectedRows] = useState(false);
|
|
1116
|
+
const [totalRowCount, setTotalRowCount] = useState(0);
|
|
1117
|
+
const [tableDataRowCount, setTableDataRowCount] = useState(0);
|
|
1118
|
+
|
|
1119
|
+
useEffect(() => {
|
|
1120
|
+
console.log({ rowSelection });
|
|
1121
|
+
|
|
1122
|
+
if (showOnlySelectedRows) {
|
|
1123
|
+
const selectedRows = Object.keys(rowSelection).filter(
|
|
1124
|
+
(key) => (rowSelection as Record<string, unknown>)[key]
|
|
1125
|
+
);
|
|
1126
|
+
const response = useFetchTableData({ selectedRows, pagination });
|
|
1127
|
+
|
|
1128
|
+
setDisplayData(response.data);
|
|
1129
|
+
setTableDataRowCount(response.totalRowCount);
|
|
1130
|
+
} else {
|
|
1131
|
+
const response = useFetchTableData({ pagination });
|
|
1132
|
+
setDisplayData(response.data);
|
|
1133
|
+
setTotalRowCount(response.totalRowCount);
|
|
1134
|
+
setTableDataRowCount(response.totalRowCount);
|
|
1135
|
+
}
|
|
1136
|
+
}, [showOnlySelectedRows, rowSelection, pagination]);
|
|
1137
|
+
|
|
1138
|
+
const paginationProps: PaginationProps = {
|
|
1139
|
+
onPageChange: (page) => {
|
|
1140
|
+
setPagination({
|
|
1141
|
+
pageIndex: page.currentPage - 1,
|
|
1142
|
+
pageSize: page.pageSize,
|
|
1143
|
+
});
|
|
1144
|
+
},
|
|
1145
|
+
totalItems: tableDataRowCount,
|
|
1146
|
+
availablePageSizes: [5, 10, 50],
|
|
1147
|
+
currentPage: pagination.pageIndex + 1,
|
|
1148
|
+
pageSize: pagination.pageSize,
|
|
1149
|
+
pageSizeLabel: "Items per page",
|
|
1150
|
+
nextButtonAriaLabel: "Go to next page",
|
|
1151
|
+
nextButtonText: "Next",
|
|
1152
|
+
outOfLabel: "of",
|
|
1153
|
+
pageSelectorListBoxLabel: "Select a page",
|
|
1154
|
+
pageSelectorNoOptionsText: "Page does not exist",
|
|
1155
|
+
previousButtonAriaLabel: "Go to previous page",
|
|
1156
|
+
previousButtonText: "Previous",
|
|
1157
|
+
stepNumberPrefix: "Go to page",
|
|
1158
|
+
};
|
|
1159
|
+
|
|
1160
|
+
return renderTableContainer(
|
|
1161
|
+
{ ...args, isExpanded: tableExpanded },
|
|
1162
|
+
/* @ts-expect-error Props are incompatible. Storybook issue after adding argTypes. */
|
|
1163
|
+
<Table
|
|
1164
|
+
className={c("table-max-height")}
|
|
1165
|
+
enableSorting={true}
|
|
1166
|
+
enableActionBar={true}
|
|
1167
|
+
variant={args.variant}
|
|
1168
|
+
columns={args.columns}
|
|
1169
|
+
data={displayData}
|
|
1170
|
+
enableRowSelection={true}
|
|
1171
|
+
enableToolbar={true}
|
|
1172
|
+
loading={false}
|
|
1173
|
+
state={{ pagination, rowSelection, columnFilters, columnVisibility }}
|
|
1174
|
+
exportFormats={args.exportFormats}
|
|
1175
|
+
onExportData={(e) => console.log("Export data", e)}
|
|
1176
|
+
actionbarCopy={args.actionbarCopy}
|
|
1177
|
+
sortingAriaLabels={args.sortingAriaLabels}
|
|
1178
|
+
settingsDrawerCopy={args.settingsDrawerCopy}
|
|
1179
|
+
exportDrawerCopy={args.exportDrawerCopy}
|
|
1180
|
+
toolbarCopy={args.toolbarCopy}
|
|
1181
|
+
enableFilters={args.enableFilters}
|
|
1182
|
+
enableMultiRowSelection={args.enableMultiRowSelection || true}
|
|
1183
|
+
onToggleExpand={() => setTableExpanded((prev) => !prev)}
|
|
1184
|
+
paginationComponent={<Pagination {...paginationProps} />}
|
|
1185
|
+
onColumnVisibilityChange={setColumnVisibility}
|
|
1186
|
+
setShowOnlySelectedRows={setShowOnlySelectedRows}
|
|
1187
|
+
showOnlySelectedRows={showOnlySelectedRows}
|
|
1188
|
+
onRowSelectionChange={setRowSelection}
|
|
1189
|
+
onColumnFiltersChange={setColumnFilters}
|
|
1190
|
+
getRowId={(row: TableData) => `${row.id}`}
|
|
1191
|
+
actionBarTotalRowCount={totalRowCount}
|
|
1192
|
+
toolbarTotalRowCount={tableDataRowCount}
|
|
1193
|
+
onPaginationChange={setPagination}
|
|
1194
|
+
onPrimaryButtonClick={() => console.log("Primary button clicked.", rowSelection)}
|
|
1195
|
+
onSecondaryButtonClick={() => console.log("Secondary button clicked", rowSelection)}
|
|
1196
|
+
rowSelectionAriaLabels={args.rowSelectionAriaLabels}
|
|
1197
|
+
manualPagination={args.manualPagination || true}
|
|
1198
|
+
manualSorting={args.manualSorting || true}
|
|
1199
|
+
manualFiltering={args.manualFiltering || true}
|
|
1200
|
+
/>
|
|
1201
|
+
);
|
|
1202
|
+
},
|
|
1203
|
+
};
|
|
1204
|
+
|
|
1205
|
+
/**
|
|
1206
|
+
* Demonstrates the secondary variant for the Table.
|
|
1207
|
+
*/
|
|
1208
|
+
export const SecondaryVariant: StoryTableData = {
|
|
1209
|
+
args: {
|
|
1210
|
+
variant: "secondary",
|
|
1211
|
+
},
|
|
1212
|
+
parameters: {
|
|
1213
|
+
docs: {
|
|
1214
|
+
description: {
|
|
1215
|
+
story: `
|
|
1216
|
+
This example demonstrates the secondary visual variant of the Table.
|
|
1217
|
+
|
|
1218
|
+
### How to enable this feature:
|
|
1219
|
+
\`\`\`jsx
|
|
1220
|
+
<Table
|
|
1221
|
+
variant="secondary"
|
|
1222
|
+
...other props
|
|
1223
|
+
/>
|
|
1224
|
+
\`\`\`
|
|
1225
|
+
|
|
1226
|
+
### Key points:
|
|
1227
|
+
- Use the primary (white) Table on secondary (gray) backgrounds and vice versa.
|
|
1228
|
+
`,
|
|
1229
|
+
},
|
|
1230
|
+
},
|
|
1231
|
+
},
|
|
1232
|
+
render: (args) => {
|
|
1233
|
+
return renderTableContainer(
|
|
1234
|
+
args,
|
|
1235
|
+
<Table
|
|
1236
|
+
variant={args.variant}
|
|
1237
|
+
columns={columnDef}
|
|
1238
|
+
data={generatedTableData.slice(0, 5)}
|
|
1239
|
+
enableSorting={false}
|
|
1240
|
+
enableRowSelection={false}
|
|
1241
|
+
enableToolbar={false}
|
|
1242
|
+
enableActionBar={false}
|
|
1243
|
+
/>
|
|
1244
|
+
);
|
|
1245
|
+
},
|
|
1246
|
+
};
|