@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.
Files changed (142) hide show
  1. package/dist/LICENSE.txt +213 -0
  2. package/dist/cell-types/badge-cell.d.ts +8 -0
  3. package/dist/cell-types/badge-cell.d.ts.map +1 -0
  4. package/dist/cell-types/body-text-cell.d.ts +8 -0
  5. package/dist/cell-types/body-text-cell.d.ts.map +1 -0
  6. package/dist/cell-types/button-cell.d.ts +8 -0
  7. package/dist/cell-types/button-cell.d.ts.map +1 -0
  8. package/dist/cell-types/button-group-cell.d.ts +16 -0
  9. package/dist/cell-types/button-group-cell.d.ts.map +1 -0
  10. package/dist/cell-types/cta-link-cell.d.ts +8 -0
  11. package/dist/cell-types/cta-link-cell.d.ts.map +1 -0
  12. package/dist/cell-types/date-cell.d.ts +8 -0
  13. package/dist/cell-types/date-cell.d.ts.map +1 -0
  14. package/dist/cell-types/empty-cell.d.ts +4 -0
  15. package/dist/cell-types/empty-cell.d.ts.map +1 -0
  16. package/dist/cell-types/error-message-cell.d.ts +8 -0
  17. package/dist/cell-types/error-message-cell.d.ts.map +1 -0
  18. package/dist/cell-types/icon-text-cell.d.ts +8 -0
  19. package/dist/cell-types/icon-text-cell.d.ts.map +1 -0
  20. package/dist/cell-types/lead-text-cell.d.ts +8 -0
  21. package/dist/cell-types/lead-text-cell.d.ts.map +1 -0
  22. package/dist/cell-types/link-cell.d.ts +8 -0
  23. package/dist/cell-types/link-cell.d.ts.map +1 -0
  24. package/dist/cell-types/number-cell.d.ts +8 -0
  25. package/dist/cell-types/number-cell.d.ts.map +1 -0
  26. package/dist/cell-types/row-selection-cell.d.ts +8 -0
  27. package/dist/cell-types/row-selection-cell.d.ts.map +1 -0
  28. package/dist/cell-types/row-toggle-cell.d.ts +8 -0
  29. package/dist/cell-types/row-toggle-cell.d.ts.map +1 -0
  30. package/dist/cell-types/toggle-cell.d.ts +8 -0
  31. package/dist/cell-types/toggle-cell.d.ts.map +1 -0
  32. package/dist/cell-types/warning-message-cell.d.ts +8 -0
  33. package/dist/cell-types/warning-message-cell.d.ts.map +1 -0
  34. package/dist/metadata.js +17 -0
  35. package/dist/story-utils/column-def.d.ts +5 -0
  36. package/dist/story-utils/column-def.d.ts.map +1 -0
  37. package/dist/story-utils/table-data.d.ts +35 -0
  38. package/dist/story-utils/table-data.d.ts.map +1 -0
  39. package/dist/story-utils/use-fetch-table-data-hook.d.ts +11 -0
  40. package/dist/story-utils/use-fetch-table-data-hook.d.ts.map +1 -0
  41. package/dist/styles.css +1 -0
  42. package/dist/table-action-bar.d.ts +26 -0
  43. package/dist/table-action-bar.d.ts.map +1 -0
  44. package/dist/table-body.d.ts +10 -0
  45. package/dist/table-body.d.ts.map +1 -0
  46. package/dist/table-column-header-cell.d.ts +28 -0
  47. package/dist/table-column-header-cell.d.ts.map +1 -0
  48. package/dist/table-export-drawer.d.ts +17 -0
  49. package/dist/table-export-drawer.d.ts.map +1 -0
  50. package/dist/table-header.d.ts +11 -0
  51. package/dist/table-header.d.ts.map +1 -0
  52. package/dist/table-row-cell-skeleton.d.ts +14 -0
  53. package/dist/table-row-cell-skeleton.d.ts.map +1 -0
  54. package/dist/table-row-cell.d.ts +25 -0
  55. package/dist/table-row-cell.d.ts.map +1 -0
  56. package/dist/table-row.d.ts +11 -0
  57. package/dist/table-row.d.ts.map +1 -0
  58. package/dist/table-settings-drawer.d.ts +41 -0
  59. package/dist/table-settings-drawer.d.ts.map +1 -0
  60. package/dist/table-toolbar.d.ts +37 -0
  61. package/dist/table-toolbar.d.ts.map +1 -0
  62. package/dist/table.cjs.js +259 -0
  63. package/dist/table.cjs.js.map +1 -0
  64. package/dist/table.d.ts +20 -0
  65. package/dist/table.d.ts.map +1 -0
  66. package/dist/table.es.js +13585 -0
  67. package/dist/table.es.js.map +1 -0
  68. package/dist/test-utils/column-def.d.ts +6 -0
  69. package/dist/test-utils/column-def.d.ts.map +1 -0
  70. package/dist/test-utils/helpers.d.ts +138 -0
  71. package/dist/test-utils/helpers.d.ts.map +1 -0
  72. package/dist/test-utils/table-data.d.ts +33 -0
  73. package/dist/test-utils/table-data.d.ts.map +1 -0
  74. package/dist/types.d.ts +420 -0
  75. package/dist/types.d.ts.map +1 -0
  76. package/dist/use-screen-size.hook.d.ts +7 -0
  77. package/dist/use-screen-size.hook.d.ts.map +1 -0
  78. package/dist/use-truncated-hook.d.ts +10 -0
  79. package/dist/use-truncated-hook.d.ts.map +1 -0
  80. package/dist/utils/custom-functions.d.ts +9 -0
  81. package/dist/utils/custom-functions.d.ts.map +1 -0
  82. package/dist/utils/unit-conversions.d.ts +19 -0
  83. package/dist/utils/unit-conversions.d.ts.map +1 -0
  84. package/dist/utils/unit-conversions.spec.d.ts +2 -0
  85. package/dist/utils/unit-conversions.spec.d.ts.map +1 -0
  86. package/eslint.config.mjs +2 -0
  87. package/package.json +82 -0
  88. package/src/cell-types/badge-cell.tsx +25 -0
  89. package/src/cell-types/body-text-cell.tsx +54 -0
  90. package/src/cell-types/button-cell.tsx +26 -0
  91. package/src/cell-types/button-group-cell.tsx +54 -0
  92. package/src/cell-types/cta-link-cell.tsx +25 -0
  93. package/src/cell-types/date-cell.tsx +33 -0
  94. package/src/cell-types/empty-cell.tsx +6 -0
  95. package/src/cell-types/error-message-cell.tsx +30 -0
  96. package/src/cell-types/icon-text-cell.tsx +30 -0
  97. package/src/cell-types/lead-text-cell.tsx +19 -0
  98. package/src/cell-types/link-cell.tsx +58 -0
  99. package/src/cell-types/number-cell.tsx +27 -0
  100. package/src/cell-types/row-selection-cell.tsx +22 -0
  101. package/src/cell-types/row-toggle-cell.tsx +23 -0
  102. package/src/cell-types/toggle-cell.tsx +19 -0
  103. package/src/cell-types/warning-message-cell.tsx +30 -0
  104. package/src/global.d.ts +4 -0
  105. package/src/story-utils/column-def.ts +148 -0
  106. package/src/story-utils/table-data.tsx +262 -0
  107. package/src/story-utils/use-fetch-table-data-hook.tsx +30 -0
  108. package/src/table-action-bar.module.scss +106 -0
  109. package/src/table-action-bar.test.tsx +111 -0
  110. package/src/table-action-bar.tsx +104 -0
  111. package/src/table-body.tsx +25 -0
  112. package/src/table-column-header-cell.tsx +305 -0
  113. package/src/table-export-drawer.module.scss +9 -0
  114. package/src/table-export-drawer.test.tsx +75 -0
  115. package/src/table-export-drawer.tsx +59 -0
  116. package/src/table-header.tsx +35 -0
  117. package/src/table-kitchen-sink.test.tsx +1196 -0
  118. package/src/table-row-cell-skeleton.tsx +61 -0
  119. package/src/table-row-cell.test.tsx +360 -0
  120. package/src/table-row-cell.tsx +188 -0
  121. package/src/table-row.tsx +30 -0
  122. package/src/table-settings-drawer.module.scss +25 -0
  123. package/src/table-settings-drawer.test.tsx +350 -0
  124. package/src/table-settings-drawer.tsx +254 -0
  125. package/src/table-toolbar.module.scss +17 -0
  126. package/src/table-toolbar.test.tsx +95 -0
  127. package/src/table-toolbar.tsx +136 -0
  128. package/src/table.module.scss +367 -0
  129. package/src/table.stories.tsx +1246 -0
  130. package/src/table.story.css +11 -0
  131. package/src/table.test.tsx +318 -0
  132. package/src/table.tsx +501 -0
  133. package/src/test-utils/column-def.ts +152 -0
  134. package/src/test-utils/helpers.ts +234 -0
  135. package/src/test-utils/table-data.tsx +318 -0
  136. package/src/types.ts +496 -0
  137. package/src/use-screen-size.hook.ts +23 -0
  138. package/src/use-truncated-hook.tsx +74 -0
  139. package/src/utils/custom-functions.ts +52 -0
  140. package/src/utils/unit-conversions.spec.ts +92 -0
  141. package/src/utils/unit-conversions.ts +30 -0
  142. package/vitest.setup.ts +60 -0
package/src/types.ts ADDED
@@ -0,0 +1,496 @@
1
+ import { HeadingTagType } from "@purpurds/heading";
2
+ import type { SelectProps } from "@purpurds/select";
3
+ import type { Cell, FilterFn, Row, RowData, SortingFn } from "@tanstack/react-table";
4
+
5
+ import { TableActionBarCopyProps } from "./table-action-bar";
6
+ import type { FilterVariants, SortingAriaLabels } from "./table-column-header-cell";
7
+ import { TableExportDrawerCopyProps } from "./table-export-drawer";
8
+ import { TableSettingsDrawerCopyProps } from "./table-settings-drawer";
9
+
10
+ export type CellType =
11
+ | "badge"
12
+ | "bodyText"
13
+ | "button"
14
+ | "buttonGroup"
15
+ | "ctaLink"
16
+ | "date"
17
+ | "empty"
18
+ | "errorAlertMessage"
19
+ | "iconText"
20
+ | "leadText"
21
+ | "link"
22
+ | "number"
23
+ | "rowSelection"
24
+ | "rowToggle"
25
+ | "toggle"
26
+ | "warningAlertMessage";
27
+
28
+ declare module "@tanstack/react-table" {
29
+ // Allows us to define custom properties for our columns
30
+ // All declarations of ColumnMeta must have identical type parameters.
31
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
32
+ interface ColumnMeta<TData extends RowData, TValue> {
33
+ /**
34
+ * Represents the variant of the filter applied to a column.
35
+ * - "string": A text-based filter.
36
+ * - "select": A dropdown-based filter.
37
+ */
38
+ filterVariant?: FilterVariants;
39
+
40
+ /**
41
+ * Placeholder text for the filter input.
42
+ */
43
+ filterPlaceholder?: string;
44
+
45
+ /**
46
+ * ARIA label for the filter input, used for accessibility.
47
+ */
48
+ filterAriaLabel?: string;
49
+
50
+ /**
51
+ * A key used to filter the column data when the data is an object.
52
+ * This is useful for custom filtering logic on a specific key within the object.
53
+ * Required when using the `filterOnFilterKey` filterFn.
54
+ */
55
+ filterKey?: string;
56
+
57
+ /**
58
+ * Represents the type of cell in a table row.
59
+ * This determines the behavior and rendering of the cell.
60
+ * - "badge": Displays status, category, or label with visual emphasis, allowing users to differentiate data at a glance without cluttering the table.
61
+ * - "bodyText": Displays all types of textual information.
62
+ * - "button": A single button for performing row-specific actions directly within a table cell, such as edit, delete, or download. Button can be any variant.
63
+ * - "buttonGroup": Similar to the standalone button, but used when multiple actions are needed for a row, grouped together for better organization. Typically placed in the last column. Buttons can be any variants.
64
+ * - "ctaLink": Allowing users to navigate to external or internal resources.
65
+ * - "date": Displays date and time in a consistent format, with the option to toggle the time visibility on or off. Visibility is controlled through the 'showTime' attribute in the meta. Please provide the date in ISO format.
66
+ * - "empty": Used when a cell has no data or when the data is not applicable.
67
+ * - "errorAlertMessage": Displays validation or data-related errors, typically with a brief description to help users identify the issue.
68
+ * - "iconText": A visual symbol that represents contextual information, enhancing readability by conveying meaning at a glance without the need for text. The ext is optional but recommended to use for further clarity.
69
+ * - "leadText": Highlights key information, like a primary identifier, to ensure it stands out in the table. Typically used in the first column.
70
+ * - "link": Enables users to navigate to external or internal resources. It has lower importance and is less intrusive than a CTA link.
71
+ * - "number": Numeric data that isn't related to size should be left-aligned, such as phone numbers or order numbers. Numeric data related to size should be right-aligned for easier scanning, helping users quickly differentiate between values such as prices. Alignment is controlled through the 'numberCellAlignment' attribute in the meta.
72
+ * - "rowSelection":
73
+ * - "toggle": Lets users enable or disable a setting or option directly within a table cell.
74
+ * - "warningAlertMessage": Highlights a potential issue with the data, often accompanied by a brief description to guide users on the necessary action.
75
+ *
76
+ * If you want a custom cell type then leave this undefined and create a custom cell component using the cell attribute in the columnDef.
77
+ */
78
+ cellType?: CellType;
79
+
80
+ /**
81
+ * Alignment for number cells. Defaults to "left" if not specified.
82
+ */
83
+ numberCellAlignment?: "left" | "right";
84
+
85
+ /**
86
+ * Properties for the select dropdown used in the filter.
87
+ * Required when filterVariant is "select".
88
+ */
89
+ selectProps?: SelectProps;
90
+
91
+ /**
92
+ * Callback function triggered when a button cell is clicked.
93
+ * Only applicable when cellType is "button".
94
+ */
95
+ onClick?: (cell: Cell<TData, unknown> & { buttonId?: string }) => void;
96
+
97
+ /**
98
+ * Determines whether to show the time in a date cell.
99
+ * Enabled by default when cellType is "date".
100
+ */
101
+ showTime?: boolean;
102
+
103
+ /**
104
+ * Aria labels for row selection checkboxes.
105
+ * Used for accessibility purposes.
106
+ */
107
+ rowSelectionAriaLabels?: {
108
+ header: string;
109
+ row: string;
110
+ };
111
+ }
112
+
113
+ interface FilterFns {
114
+ /**
115
+ * A custom filter function that filters data based on a specified key.
116
+ * Useful for advanced filtering scenarios.
117
+ * Requires the `filterKey` property in the column's meta.
118
+ */
119
+ filterOnFilterKey: FilterFn<unknown>;
120
+ }
121
+
122
+ interface SortingFns {
123
+ /**
124
+ * A custom sorting function that sorts badge column based on the badge variant.
125
+ */
126
+ sortOnBadgeVariant: SortingFn<unknown>;
127
+
128
+ /**
129
+ * A custom sorting function that sorts badge column based on the badge value.
130
+ */
131
+ sortOnBadgeValue: SortingFn<unknown>;
132
+ }
133
+ }
134
+
135
+ /**
136
+ * Props for enabling and configuring the action bar in a data table component.
137
+ */
138
+ export type WithActionBarProps = {
139
+ /**
140
+ * Configuration for the action bar copy, such as labels and messages.
141
+ */
142
+ actionbarCopy: TableActionBarCopyProps;
143
+
144
+ /**
145
+ * Flag to enable the action bar functionality.
146
+ */
147
+ enableActionBar: true;
148
+
149
+ /**
150
+ * The total number of rows in the data table, displayed in the action bar.
151
+ */
152
+ actionBarTotalRowCount: number;
153
+
154
+ /**
155
+ * Callback function triggered when the primary button in the action bar is clicked.
156
+ */
157
+ onPrimaryButtonClick: () => void;
158
+
159
+ /**
160
+ * Optional callback function triggered when the secondary button in the action bar is clicked.
161
+ */
162
+ onSecondaryButtonClick?: () => void;
163
+ };
164
+
165
+ export type WithoutActionBarProps = {
166
+ actionbarCopy?: never;
167
+ enableActionBar?: false | undefined;
168
+ actionBarTotalRowCount?: never;
169
+ onPrimaryButtonClick?: never;
170
+ onSecondaryButtonClick?: never;
171
+ };
172
+
173
+ /**
174
+ * Props for displaying an empty table state in a data table component.
175
+ */
176
+ export type WithEmptyTableProps = {
177
+ /**
178
+ * Copy for the empty table state, such as title and description.
179
+ */
180
+ emptyTableCopy: {
181
+ title: string;
182
+ description: string;
183
+ };
184
+
185
+ /**
186
+ * The heading tag to use for the empty table title.
187
+ */
188
+ emptyTableHeadingTag: HeadingTagType;
189
+
190
+ /**
191
+ * Icon to display in the empty table state.
192
+ */
193
+ emptyTableIcon: React.ReactNode;
194
+ };
195
+
196
+ export type WithoutEmptyTableProps = {
197
+ emptyTableCopy?: never;
198
+ emptyTableHeadingTag?: never;
199
+ emptyTableIcon?: never;
200
+ };
201
+
202
+ /**
203
+ * Props for enabling a loading state in a data table component.
204
+ */
205
+ export type WithLoadingProps = {
206
+ /**
207
+ * Flag to enable the loading state.
208
+ */
209
+ loading: boolean;
210
+
211
+ /**
212
+ * The number of skeleton rows to display while loading.
213
+ */
214
+ skeletonRows: number;
215
+ };
216
+
217
+ export type WithoutLoadingProps = {
218
+ loading?: never;
219
+ skeletonRows?: never;
220
+ };
221
+
222
+ /**
223
+ * Props for enabling row selection functionality in a data table component.
224
+ */
225
+ export type WithRowSelectionProps<TData> = {
226
+ /**
227
+ * Flag to enable row selection functionality.
228
+ */
229
+ enableRowSelection: true | ((row: Row<TData>) => boolean);
230
+
231
+ /**
232
+ * ARIA labels for row selection checkboxes, used for accessibility.
233
+ */
234
+ rowSelectionAriaLabels: {
235
+ header: string;
236
+ row: string;
237
+ };
238
+
239
+ /**
240
+ * showOnlySelectedRows - Flag to filter the table to show only selected rows.
241
+ */
242
+ showOnlySelectedRows: boolean;
243
+
244
+ /**
245
+ * setShowOnlySelectedRows - Function to update the showOnlySelectedRows state.
246
+ */
247
+ setShowOnlySelectedRows: React.Dispatch<React.SetStateAction<boolean>>;
248
+ };
249
+
250
+ export type WithoutRowSelectionProps = {
251
+ enableRowSelection?: false | undefined;
252
+ rowSelectionAriaLabels?: never;
253
+ showOnlySelectedRows?: never;
254
+ setShowOnlySelectedRows?: never;
255
+ };
256
+
257
+ /**
258
+ * Props for enabling sorting functionality in a data table component.
259
+ */
260
+ export type WithSortingProps = {
261
+ /**
262
+ * Flag to enable sorting functionality.
263
+ */
264
+ enableSorting: true;
265
+
266
+ /**
267
+ * ARIA labels for sorting controls, used for accessibility.
268
+ */
269
+ sortingAriaLabels: SortingAriaLabels;
270
+ };
271
+
272
+ export type WithoutSortingProps = {
273
+ enableSorting?: false | undefined;
274
+ sortingAriaLabels?: never;
275
+ };
276
+
277
+ /**
278
+ * Represents the properties for a data table component with a toolbar.
279
+ * This type is used when the toolbar is enabled and provides additional
280
+ * functionality such as exporting data, toggling table expansion, and displaying
281
+ * settings.
282
+ */
283
+ export type WithToolbarProps = {
284
+ /**
285
+ * Indicates whether the toolbar is enabled.
286
+ */
287
+ enableToolbar: true;
288
+
289
+ // /**
290
+ // * Optional properties for customizing the toolbar copy.
291
+ // */
292
+ toolbarCopy?: {
293
+ rowCount?: {
294
+ showing: string;
295
+ of: string;
296
+ rows: string;
297
+ };
298
+ };
299
+
300
+ /**
301
+ * The total number of rows to display in the toolbar.
302
+ * This is used when handling data on the server side.
303
+ */
304
+ toolbarTotalRowCount?: number;
305
+ } & (WithFiltersProps | WithoutFiltersProps) &
306
+ (WithSettingsDrawerProps | WithoutSettingsDrawerProps) &
307
+ ((WithExportDrawerProps | WithSingleExportFormatProps) | WithoutExportProps) &
308
+ (WithExpandButtonProps | WithoutExpandButtonProps);
309
+
310
+ export type WithoutToolbarProps = {
311
+ /**
312
+ * Indicates whether the toolbar is enabled.
313
+ */
314
+ enableToolbar?: false | undefined;
315
+ exportFormats?: never;
316
+ onExportData?: never;
317
+ onToggleExpand?: never;
318
+ settingsDrawerCopy?: never;
319
+ toolbarCopy?: never;
320
+ toolbarTotalRowCount?: never;
321
+ exportDrawerCopy?: never;
322
+ };
323
+
324
+ type WithFiltersProps = {
325
+ enableFilters: true;
326
+ /**
327
+ * Optional properties for customizing the filter copy.
328
+ */
329
+ toolbarCopy: {
330
+ buttons: {
331
+ clearFilters: string;
332
+ };
333
+ ariaLabels: {
334
+ clearFilters: string;
335
+ };
336
+ };
337
+ };
338
+
339
+ /**
340
+ * Props for enabling an expand button in a data table component.
341
+ */
342
+ type WithExpandButtonProps = {
343
+ /**
344
+ * Callback function triggered when toggling the expansion state of rows.
345
+ */
346
+ onToggleExpand: () => void;
347
+
348
+ /**
349
+ * Copy for the toolbar buttons related to expanding rows.
350
+ */
351
+ toolbarCopy: {
352
+ buttons: {
353
+ expand: string;
354
+ };
355
+ ariaLabels: {
356
+ expand: string;
357
+ };
358
+ };
359
+ };
360
+
361
+ /**
362
+ * Props for enabling an export drawer in a data table component.
363
+ */
364
+ type WithExportDrawerProps = {
365
+ /**
366
+ * The formats in which the data can be exported.
367
+ */
368
+ exportFormats: string[];
369
+
370
+ /**
371
+ * Copy for the export drawer, such as labels and messages.
372
+ */
373
+ exportDrawerCopy: TableExportDrawerCopyProps;
374
+
375
+ /**
376
+ * Callback function triggered when exporting data.
377
+ * @param format - The format in which the data should be exported.
378
+ */
379
+ onExportData: (format: string) => void;
380
+
381
+ /**
382
+ * Copy for the toolbar buttons and ARIA labels related to exporting.
383
+ */
384
+ toolbarCopy: {
385
+ buttons: {
386
+ export: string;
387
+ };
388
+ ariaLabels: {
389
+ export: string;
390
+ };
391
+ };
392
+ };
393
+
394
+ type WithoutExportProps = {
395
+ exportFormats?: never;
396
+ exportDrawerCopy?: never;
397
+ onExportData?: never;
398
+ toolbarCopy?: {
399
+ buttons: {
400
+ export?: never;
401
+ };
402
+ ariaLabels?: {
403
+ export?: never;
404
+ };
405
+ };
406
+ };
407
+
408
+ type WithoutExpandButtonProps = {
409
+ onToggleExpand?: never;
410
+ toolbarCopy?: {
411
+ buttons?: {
412
+ expand?: never;
413
+ };
414
+ ariaLabels?: {
415
+ expand?: never;
416
+ };
417
+ };
418
+ };
419
+
420
+ type WithoutFiltersProps = {
421
+ enableFilters?: false | undefined;
422
+ /**
423
+ * Optional properties for customizing the filter copy.
424
+ */
425
+ toolbarCopy?: {
426
+ buttons?: {
427
+ clearFilters?: never;
428
+ };
429
+ ariaLabels?: {
430
+ clearFilters?: never;
431
+ };
432
+ };
433
+ };
434
+
435
+ /**
436
+ * Props for enabling a settings drawer in a data table component.
437
+ */
438
+ type WithSettingsDrawerProps = {
439
+ /**
440
+ * Optional properties for customizing the settings drawer copy.
441
+ */
442
+ settingsDrawerCopy: TableSettingsDrawerCopyProps;
443
+ toolbarCopy: {
444
+ buttons: {
445
+ settings: string;
446
+ };
447
+ ariaLabels: {
448
+ settings: string;
449
+ };
450
+ };
451
+ };
452
+
453
+ /**
454
+ * Props for enabling a single export format in a data table component.
455
+ */
456
+ type WithSingleExportFormatProps = {
457
+ /**
458
+ * The format in which the data should be exported.
459
+ */
460
+ exportFormats: string;
461
+
462
+ /**
463
+ * Callback function triggered when exporting data.
464
+ * @param format - The format in which the data should be exported.
465
+ */
466
+ onExportData: (format: string) => void;
467
+
468
+ /**
469
+ * Copy for the toolbar buttons and ARIA labels related to exporting.
470
+ */
471
+ toolbarCopy: {
472
+ buttons: {
473
+ export: string;
474
+ };
475
+ ariaLabels: {
476
+ export: string;
477
+ };
478
+ };
479
+
480
+ exportDrawerCopy?: never;
481
+ };
482
+
483
+ type WithoutSettingsDrawerProps = {
484
+ /**
485
+ * Optional properties for customizing the settings drawer copy.
486
+ */
487
+ settingsDrawerCopy?: undefined;
488
+ toolbarCopy?: {
489
+ buttons?: {
490
+ settings?: undefined;
491
+ };
492
+ ariaLabels?: {
493
+ settings?: undefined;
494
+ };
495
+ };
496
+ };
@@ -0,0 +1,23 @@
1
+ import { useLayoutEffect, useState } from "react";
2
+ import { purpurBreakpointRelativeLg } from "@purpurds/tokens";
3
+
4
+ export const SCREEN_MEDIA_QUERY = {
5
+ MAX_LG: `(max-width: ${purpurBreakpointRelativeLg})`,
6
+ } as const;
7
+
8
+ export const useScreenSize = () => {
9
+ const [isLgOrSmaller, setIsLgOrSmaller] = useState(false);
10
+
11
+ useLayoutEffect(() => {
12
+ const maxMediumScreen = window.matchMedia(SCREEN_MEDIA_QUERY.MAX_LG);
13
+ function updateSize() {
14
+ setIsLgOrSmaller(maxMediumScreen.matches);
15
+ }
16
+
17
+ window.addEventListener("resize", updateSize);
18
+ updateSize();
19
+ return () => window.removeEventListener("resize", updateSize);
20
+ }, []);
21
+
22
+ return { isLgOrSmaller };
23
+ };
@@ -0,0 +1,74 @@
1
+ import { useEffect, useRef, useState } from "react";
2
+ import { Cell, RowData } from "@tanstack/react-table";
3
+
4
+ const useTruncatedTooltip = <TData extends RowData>(cell: Cell<TData, unknown> | undefined) => {
5
+ const divRef = useRef<HTMLParagraphElement>(null);
6
+ const [isTruncated, setIsTruncated] = useState(false);
7
+ const timeoutIdRef = useRef<NodeJS.Timeout | undefined>(undefined);
8
+ const [showPopover, setShowPopover] = useState(false);
9
+
10
+ const debounce = (func: (...args: unknown[]) => void, delay: number) => {
11
+ let timeoutId: NodeJS.Timeout;
12
+ const debouncedFunction = (...args: unknown[]) => {
13
+ clearTimeout(timeoutId);
14
+ timeoutId = setTimeout(() => func.apply(this, args), delay);
15
+ };
16
+ return {
17
+ debouncedFunction,
18
+ get timeoutId() {
19
+ return timeoutId;
20
+ },
21
+ };
22
+ };
23
+
24
+ useEffect(() => {
25
+ if (!cell) {
26
+ return;
27
+ }
28
+
29
+ const { debouncedFunction: checkTruncation, timeoutId } = debounce(() => {
30
+ if (divRef.current && cell) {
31
+ const pEl = divRef.current.querySelector("p");
32
+ if (pEl) {
33
+ setIsTruncated(pEl.scrollWidth > cell.column.getSize());
34
+ }
35
+ }
36
+ }, 100); // Adjust debounce delay as needed
37
+
38
+ checkTruncation();
39
+ timeoutIdRef.current = timeoutId;
40
+
41
+ return () => {
42
+ clearTimeout(timeoutIdRef.current);
43
+ };
44
+ }, [cell]);
45
+
46
+ useEffect(() => {
47
+ if (divRef.current && cell) {
48
+ if (divRef.current.textContent) {
49
+ const pEl = divRef.current.querySelector("p");
50
+ if (pEl) {
51
+ setIsTruncated(pEl.scrollWidth > cell.column.getSize());
52
+ }
53
+ const aEl = divRef.current.querySelector("a");
54
+ if (aEl) {
55
+ setIsTruncated(aEl.scrollWidth > cell.column.getSize());
56
+ }
57
+ }
58
+ }
59
+ }, [divRef, cell, isTruncated]);
60
+
61
+ const onMouseEnter = () => {
62
+ if (isTruncated) {
63
+ setShowPopover(true);
64
+ }
65
+ };
66
+
67
+ const onMouseLeave = () => {
68
+ setShowPopover(false);
69
+ };
70
+
71
+ return { divRef, onMouseEnter, onMouseLeave, showPopover };
72
+ };
73
+
74
+ export default useTruncatedTooltip;
@@ -0,0 +1,52 @@
1
+ import { BadgeVariant } from "@purpurds/badge";
2
+ import { Row } from "@tanstack/react-table";
3
+
4
+ export const filterOnFilterKey = <TData>(
5
+ row: Row<TData>,
6
+ columnId: string,
7
+ filterValue: {
8
+ filterKey: string;
9
+ value: string;
10
+ }
11
+ ): boolean => {
12
+ const { filterKey, value } = filterValue;
13
+ const cellValue = row.getValue<Record<string, unknown>>(columnId);
14
+ return value === "" || cellValue[filterKey] === value;
15
+ };
16
+
17
+ export const sortOnBadgeVariant = <TData>(
18
+ row1: Row<TData>,
19
+ row0: Row<TData>,
20
+ columnId: string
21
+ ): number => {
22
+ const row0Value = row0.getValue(columnId) as {
23
+ variant: BadgeVariant;
24
+ children: React.ReactNode;
25
+ };
26
+ const row1Value = row1.getValue(columnId) as {
27
+ variant: BadgeVariant;
28
+ children: React.ReactNode;
29
+ };
30
+
31
+ return row1Value.variant.localeCompare(row0Value.variant);
32
+ };
33
+
34
+ export const sortOnBadgeValue = <TData>(
35
+ row1: Row<TData>,
36
+ row0: Row<TData>,
37
+ columnId: string
38
+ ): number => {
39
+ const row0Value = row0.getValue(columnId) as {
40
+ variant: BadgeVariant;
41
+ children: React.ReactNode;
42
+ };
43
+ const row1Value = row1.getValue(columnId) as {
44
+ variant: BadgeVariant;
45
+ children: React.ReactNode;
46
+ };
47
+
48
+ const row0String = row0Value.children as string;
49
+ const row1String = row1Value.children as string;
50
+
51
+ return row1String.localeCompare(row0String);
52
+ };