@drivenets/design-system 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 (242) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/LICENSE +201 -0
  3. package/dist/index.cjs +5394 -0
  4. package/dist/index.css +1 -0
  5. package/dist/index.d.cts +9157 -0
  6. package/dist/index.d.cts.map +1 -0
  7. package/dist/index.d.ts +9157 -0
  8. package/dist/index.d.ts.map +1 -0
  9. package/dist/index.js +5335 -0
  10. package/dist/index.js.map +1 -0
  11. package/package.json +104 -0
  12. package/src/components/ds-alert-banner/ds-alert-banner.module.scss +116 -0
  13. package/src/components/ds-alert-banner/ds-alert-banner.tsx +115 -0
  14. package/src/components/ds-alert-banner/ds-alert-banner.types.tsx +47 -0
  15. package/src/components/ds-alert-banner/index.tsx +2 -0
  16. package/src/components/ds-breadcrumb/ds-breadcrumb.module.scss +99 -0
  17. package/src/components/ds-breadcrumb/ds-breadcrumb.tsx +94 -0
  18. package/src/components/ds-breadcrumb/ds-breadcrumb.types.tsx +32 -0
  19. package/src/components/ds-breadcrumb/index.tsx +2 -0
  20. package/src/components/ds-button/ds-button.tsx +12 -0
  21. package/src/components/ds-button/ds-button.types.ts +6 -0
  22. package/src/components/ds-button/index.ts +2 -0
  23. package/src/components/ds-button/versions/ds-button-legacy/ds-button-legacy.module.scss +257 -0
  24. package/src/components/ds-button/versions/ds-button-legacy/ds-button-legacy.tsx +34 -0
  25. package/src/components/ds-button/versions/ds-button-legacy/ds-button-legacy.types.ts +41 -0
  26. package/src/components/ds-button/versions/ds-button-legacy/index.ts +2 -0
  27. package/src/components/ds-button/versions/ds-button-new/ds-button-new.module.scss +580 -0
  28. package/src/components/ds-button/versions/ds-button-new/ds-button-new.tsx +49 -0
  29. package/src/components/ds-button/versions/ds-button-new/ds-button-new.types.ts +41 -0
  30. package/src/components/ds-button/versions/ds-button-new/index.ts +2 -0
  31. package/src/components/ds-checkbox/ds-checkbox.module.scss +130 -0
  32. package/src/components/ds-checkbox/ds-checkbox.tsx +55 -0
  33. package/src/components/ds-checkbox/ds-checkbox.types.tsx +27 -0
  34. package/src/components/ds-checkbox/index.tsx +2 -0
  35. package/src/components/ds-chip/ds-chip.module.scss +71 -0
  36. package/src/components/ds-chip/ds-chip.tsx +73 -0
  37. package/src/components/ds-chip/ds-chip.types.tsx +46 -0
  38. package/src/components/ds-chip/index.tsx +2 -0
  39. package/src/components/ds-chip-group/ds-chip-group.module.scss +59 -0
  40. package/src/components/ds-chip-group/ds-chip-group.tsx +122 -0
  41. package/src/components/ds-chip-group/ds-chip-group.types.ts +52 -0
  42. package/src/components/ds-chip-group/hooks/use-chip-row-calculation.ts +76 -0
  43. package/src/components/ds-chip-group/index.ts +2 -0
  44. package/src/components/ds-confirmation/ds-confirmation.module.scss +58 -0
  45. package/src/components/ds-confirmation/ds-confirmation.tsx +121 -0
  46. package/src/components/ds-confirmation/ds-confirmation.types.tsx +28 -0
  47. package/src/components/ds-confirmation/index.ts +2 -0
  48. package/src/components/ds-dialog/ds-dialog.module.scss +50 -0
  49. package/src/components/ds-dialog/ds-dialog.tsx +70 -0
  50. package/src/components/ds-dialog/ds-dialog.types.tsx +48 -0
  51. package/src/components/ds-dialog/index.tsx +2 -0
  52. package/src/components/ds-drawer/ds-drawer.module.scss +212 -0
  53. package/src/components/ds-drawer/ds-drawer.tsx +160 -0
  54. package/src/components/ds-drawer/ds-drawer.types.tsx +54 -0
  55. package/src/components/ds-drawer/index.ts +2 -0
  56. package/src/components/ds-dropdown-menu/ds-dropdown-menu.module.scss +123 -0
  57. package/src/components/ds-dropdown-menu/ds-dropdown-menu.tsx +396 -0
  58. package/src/components/ds-dropdown-menu/ds-dropdown-menu.types.tsx +262 -0
  59. package/src/components/ds-dropdown-menu/index.tsx +2 -0
  60. package/src/components/ds-expandable-text-input/ds-expandable-text-input.module.scss +70 -0
  61. package/src/components/ds-expandable-text-input/ds-expandable-text-input.tsx +106 -0
  62. package/src/components/ds-expandable-text-input/ds-expandable-text-input.types.tsx +19 -0
  63. package/src/components/ds-expandable-text-input/index.ts +2 -0
  64. package/src/components/ds-file-upload/components/file-upload/file-upload.module.scss +90 -0
  65. package/src/components/ds-file-upload/components/file-upload/file-upload.tsx +106 -0
  66. package/src/components/ds-file-upload/components/file-upload/file-upload.types.tsx +94 -0
  67. package/src/components/ds-file-upload/components/file-upload/index.ts +2 -0
  68. package/src/components/ds-file-upload/components/file-upload-item/file-upload-item.module.scss +125 -0
  69. package/src/components/ds-file-upload/components/file-upload-item/file-upload-item.tsx +143 -0
  70. package/src/components/ds-file-upload/components/file-upload-item/file-upload-item.types.tsx +26 -0
  71. package/src/components/ds-file-upload/components/file-upload-item/index.ts +2 -0
  72. package/src/components/ds-file-upload/ds-file-upload-api.types.ts +38 -0
  73. package/src/components/ds-file-upload/ds-file-upload.tsx +46 -0
  74. package/src/components/ds-file-upload/ds-file-upload.types.tsx +54 -0
  75. package/src/components/ds-file-upload/errors/file-upload-errors.ts +27 -0
  76. package/src/components/ds-file-upload/hooks/index.ts +2 -0
  77. package/src/components/ds-file-upload/hooks/use-file-upload.ts +350 -0
  78. package/src/components/ds-file-upload/index.ts +7 -0
  79. package/src/components/ds-file-upload/types/accept-types.ts +106 -0
  80. package/src/components/ds-file-upload/utils/accept-utils.ts +25 -0
  81. package/src/components/ds-file-upload/utils/constants.ts +21 -0
  82. package/src/components/ds-file-upload/utils/file-factory.ts +18 -0
  83. package/src/components/ds-file-upload/utils/format-file-size.ts +15 -0
  84. package/src/components/ds-file-upload/utils/generate-helper-text.ts +39 -0
  85. package/src/components/ds-file-upload/utils/get-error-message.ts +17 -0
  86. package/src/components/ds-file-upload/utils/is-file-equal.ts +8 -0
  87. package/src/components/ds-form-control/ds-form-control.module.scss +135 -0
  88. package/src/components/ds-form-control/ds-form-control.tsx +94 -0
  89. package/src/components/ds-form-control/ds-form-control.types.tsx +58 -0
  90. package/src/components/ds-form-control/index.tsx +2 -0
  91. package/src/components/ds-grid/ds-grid.module.scss +0 -0
  92. package/src/components/ds-grid/ds-grid.tsx +43 -0
  93. package/src/components/ds-grid/ds-grid.types.ts +55 -0
  94. package/src/components/ds-grid/index.ts +2 -0
  95. package/src/components/ds-icon/ds-icon.module.scss +25 -0
  96. package/src/components/ds-icon/ds-icon.tsx +33 -0
  97. package/src/components/ds-icon/ds-icon.types.ts +53 -0
  98. package/src/components/ds-icon/index.ts +2 -0
  99. package/src/components/ds-icon/material-icons.ts +6203 -0
  100. package/src/components/ds-modal/ds-modal.module.scss +100 -0
  101. package/src/components/ds-modal/ds-modal.tsx +136 -0
  102. package/src/components/ds-modal/ds-modal.types.tsx +44 -0
  103. package/src/components/ds-modal/index.tsx +2 -0
  104. package/src/components/ds-number-input/ds-number-input.module.scss +15 -0
  105. package/src/components/ds-number-input/ds-number-input.tsx +74 -0
  106. package/src/components/ds-number-input/ds-number-input.types.tsx +76 -0
  107. package/src/components/ds-number-input/index.tsx +2 -0
  108. package/src/components/ds-panel/ds-panel.module.scss +95 -0
  109. package/src/components/ds-panel/ds-panel.tsx +46 -0
  110. package/src/components/ds-panel/ds-panel.types.ts +17 -0
  111. package/src/components/ds-panel/index.tsx +2 -0
  112. package/src/components/ds-password-input/ds-password-input.module.scss +10 -0
  113. package/src/components/ds-password-input/ds-password-input.tsx +67 -0
  114. package/src/components/ds-password-input/ds-password-input.types.tsx +62 -0
  115. package/src/components/ds-password-input/index.tsx +2 -0
  116. package/src/components/ds-popover/ds-popover.module.scss +23 -0
  117. package/src/components/ds-popover/ds-popover.tsx +33 -0
  118. package/src/components/ds-popover/ds-popover.types.tsx +24 -0
  119. package/src/components/ds-popover/index.tsx +2 -0
  120. package/src/components/ds-radio-group/ds-radio-group.module.scss +138 -0
  121. package/src/components/ds-radio-group/ds-radio-group.tsx +115 -0
  122. package/src/components/ds-radio-group/ds-radio-group.types.tsx +93 -0
  123. package/src/components/ds-radio-group/index.tsx +2 -0
  124. package/src/components/ds-select/ds-select.module.scss +66 -0
  125. package/src/components/ds-select/ds-select.tsx +239 -0
  126. package/src/components/ds-select/ds-select.types.tsx +80 -0
  127. package/src/components/ds-select/index.tsx +2 -0
  128. package/src/components/ds-select/select-items-chips.tsx +56 -0
  129. package/src/components/ds-smart-tabs/ds-smart-tabs.module.scss +69 -0
  130. package/src/components/ds-smart-tabs/ds-smart-tabs.tsx +113 -0
  131. package/src/components/ds-smart-tabs/ds-smart-tabs.types.tsx +74 -0
  132. package/src/components/ds-smart-tabs/index.tsx +2 -0
  133. package/src/components/ds-spinner/ds-spinner.module.scss +39 -0
  134. package/src/components/ds-spinner/ds-spinner.tsx +51 -0
  135. package/src/components/ds-spinner/ds-spinner.types.tsx +20 -0
  136. package/src/components/ds-spinner/index.tsx +2 -0
  137. package/src/components/ds-status-badge/ds-status-badge.module.scss +79 -0
  138. package/src/components/ds-status-badge/ds-status-badge.tsx +42 -0
  139. package/src/components/ds-status-badge/ds-status-badge.types.tsx +46 -0
  140. package/src/components/ds-status-badge/index.tsx +2 -0
  141. package/src/components/ds-stepper/components/ds-step-content.tsx +32 -0
  142. package/src/components/ds-stepper/components/ds-step-description.tsx +6 -0
  143. package/src/components/ds-stepper/components/ds-step-label.tsx +6 -0
  144. package/src/components/ds-stepper/components/ds-step-next-button.tsx +13 -0
  145. package/src/components/ds-stepper/components/ds-step.tsx +59 -0
  146. package/src/components/ds-stepper/ds-stepper.module.scss +134 -0
  147. package/src/components/ds-stepper/ds-stepper.tsx +34 -0
  148. package/src/components/ds-stepper/ds-stepper.types.ts +12 -0
  149. package/src/components/ds-stepper/hooks/use-stepper.ts +20 -0
  150. package/src/components/ds-stepper/hooks/use-steps.ts +18 -0
  151. package/src/components/ds-stepper/index.tsx +6 -0
  152. package/src/components/ds-system-status/ds-system-status.module.scss +87 -0
  153. package/src/components/ds-system-status/ds-system-status.tsx +33 -0
  154. package/src/components/ds-system-status/ds-system-status.types.tsx +37 -0
  155. package/src/components/ds-system-status/index.tsx +10 -0
  156. package/src/components/ds-table/components/core-table/core-table.module.scss +32 -0
  157. package/src/components/ds-table/components/core-table/core-table.tsx +83 -0
  158. package/src/components/ds-table/components/core-table/index.ts +1 -0
  159. package/src/components/ds-table/components/ds-table-bulk-actions/ds-table-bulk-actions.module.scss +115 -0
  160. package/src/components/ds-table/components/ds-table-bulk-actions/ds-table-bulk-actions.tsx +70 -0
  161. package/src/components/ds-table/components/ds-table-bulk-actions/ds-table-bulk-actions.types.ts +41 -0
  162. package/src/components/ds-table/components/ds-table-bulk-actions/index.ts +2 -0
  163. package/src/components/ds-table/components/ds-table-cell/ds-table-cell.module.scss +53 -0
  164. package/src/components/ds-table/components/ds-table-cell/ds-table-cell.tsx +95 -0
  165. package/src/components/ds-table/components/ds-table-cell/ds-table-cell.types.ts +67 -0
  166. package/src/components/ds-table/components/ds-table-cell/index.ts +2 -0
  167. package/src/components/ds-table/components/ds-table-header/ds-table-header.module.scss +81 -0
  168. package/src/components/ds-table/components/ds-table-header/ds-table-header.tsx +99 -0
  169. package/src/components/ds-table/components/ds-table-header/ds-table-header.types.ts +11 -0
  170. package/src/components/ds-table/components/ds-table-header/index.ts +2 -0
  171. package/src/components/ds-table/components/ds-table-row/ds-table-row.module.scss +137 -0
  172. package/src/components/ds-table/components/ds-table-row/ds-table-row.tsx +205 -0
  173. package/src/components/ds-table/components/ds-table-row/ds-table-row.types.ts +22 -0
  174. package/src/components/ds-table/components/ds-table-row/index.ts +2 -0
  175. package/src/components/ds-table/context/ds-table-context.tsx +39 -0
  176. package/src/components/ds-table/ds-table.module.scss +60 -0
  177. package/src/components/ds-table/ds-table.tsx +312 -0
  178. package/src/components/ds-table/ds-table.types.ts +377 -0
  179. package/src/components/ds-table/filters/adapters/create-checkbox-filter-adapter.tsx +116 -0
  180. package/src/components/ds-table/filters/adapters/create-dual-range-filter-adapter.tsx +171 -0
  181. package/src/components/ds-table/filters/adapters/create-filter-adapter.ts +131 -0
  182. package/src/components/ds-table/filters/adapters/index.ts +12 -0
  183. package/src/components/ds-table/filters/components/checkbox-filter/checkbox-filter.tsx +43 -0
  184. package/src/components/ds-table/filters/components/checkbox-filter/index.ts +2 -0
  185. package/src/components/ds-table/filters/components/range-filter/index.ts +2 -0
  186. package/src/components/ds-table/filters/components/range-filter/range-filter.module.scss +25 -0
  187. package/src/components/ds-table/filters/components/range-filter/range-filter.tsx +79 -0
  188. package/src/components/ds-table/filters/hooks/index.ts +1 -0
  189. package/src/components/ds-table/filters/hooks/use-table-filters.ts +234 -0
  190. package/src/components/ds-table/filters/index.ts +50 -0
  191. package/src/components/ds-table/filters/types/filter-adapter.types.ts +111 -0
  192. package/src/components/ds-table/hooks/use-drag-and-drop.tsx +107 -0
  193. package/src/components/ds-table/index.ts +4 -0
  194. package/src/components/ds-table/styles/_variables.scss +17 -0
  195. package/src/components/ds-table/styles/shared/ds-table-shared.module.scss +16 -0
  196. package/src/components/ds-table/utils/column-styling.ts +30 -0
  197. package/src/components/ds-table/utils/create-columns-grid-template.ts +23 -0
  198. package/src/components/ds-table/utils/merge-refs.ts +15 -0
  199. package/src/components/ds-table/utils/story-data-generator.ts +91 -0
  200. package/src/components/ds-text-input/ds-text-input.module.scss +27 -0
  201. package/src/components/ds-text-input/ds-text-input.tsx +75 -0
  202. package/src/components/ds-text-input/ds-text-input.types.tsx +110 -0
  203. package/src/components/ds-text-input/index.ts +2 -0
  204. package/src/components/ds-textarea/ds-textarea.module.scss +5 -0
  205. package/src/components/ds-textarea/ds-textarea.tsx +49 -0
  206. package/src/components/ds-textarea/ds-textarea.types.tsx +67 -0
  207. package/src/components/ds-textarea/index.tsx +2 -0
  208. package/src/components/ds-toast/ds-toast-context.tsx +79 -0
  209. package/src/components/ds-toast/ds-toast.module.scss +134 -0
  210. package/src/components/ds-toast/ds-toast.tsx +54 -0
  211. package/src/components/ds-toast/ds-toast.types.tsx +53 -0
  212. package/src/components/ds-toast/index.ts +3 -0
  213. package/src/components/ds-tooltip/ds-tooltip.module.scss +19 -0
  214. package/src/components/ds-tooltip/ds-tooltip.tsx +33 -0
  215. package/src/components/ds-tooltip/ds-tooltip.types.tsx +12 -0
  216. package/src/components/ds-tooltip/index.tsx +2 -0
  217. package/src/components/ds-typography/ds-typography.config.ts +32 -0
  218. package/src/components/ds-typography/ds-typography.module.scss +93 -0
  219. package/src/components/ds-typography/ds-typography.tsx +27 -0
  220. package/src/components/ds-typography/ds-typography.types.tsx +27 -0
  221. package/src/components/ds-typography/index.tsx +2 -0
  222. package/src/components/ds-vertical-tabs/ds-vertical-tabs.module.scss +60 -0
  223. package/src/components/ds-vertical-tabs/ds-vertical-tabs.tsx +80 -0
  224. package/src/components/ds-vertical-tabs/ds-vertical-tabs.types.ts +69 -0
  225. package/src/components/ds-vertical-tabs/index.ts +7 -0
  226. package/src/index.ts +34 -0
  227. package/src/styles/_colors.scss +65 -0
  228. package/src/styles/_grid.scss +111 -0
  229. package/src/styles/_mixin.scss +1 -0
  230. package/src/styles/_reset.scss +38 -0
  231. package/src/styles/_root.scss +390 -0
  232. package/src/styles/_scrollbars.scss +41 -0
  233. package/src/styles/_spacing.scss +47 -0
  234. package/src/styles/_typography.scss +301 -0
  235. package/src/styles/_utilities.scss +33 -0
  236. package/src/styles/_variables.scss +44 -0
  237. package/src/styles/mixins/_bounding-box.scss +53 -0
  238. package/src/styles/mixins/_list.scss +74 -0
  239. package/src/styles/shared/_dropdown.scss +89 -0
  240. package/src/styles/shared/_input.scss +365 -0
  241. package/src/styles/shared/_modal.scss +123 -0
  242. package/src/styles/styles.scss +12 -0
@@ -0,0 +1,81 @@
1
+ @use '../../../../styles/typography';
2
+ @use '../../styles/variables' as vars;
3
+
4
+ .stickyHeader {
5
+ position: sticky;
6
+ top: 0;
7
+ z-index: 10;
8
+ background-color: var(--color-background);
9
+ }
10
+
11
+ .virtualizedHeader {
12
+ display: grid;
13
+ grid-template-columns: subgrid;
14
+ grid-column: 1 / -1;
15
+ }
16
+
17
+ .headerRow {
18
+ .headerCell {
19
+ border-bottom: 1px solid var(--neutral-6);
20
+
21
+ &.selectColumn {
22
+ width: vars.$select-column-width;
23
+ padding: 0;
24
+ }
25
+ }
26
+
27
+ &.headerRowNoBorder {
28
+ .headerCell {
29
+ border-bottom: none;
30
+ }
31
+ }
32
+ }
33
+
34
+ .headerRowVirtualized {
35
+ display: grid;
36
+ grid-template-columns: subgrid;
37
+ grid-column: 1 / -1;
38
+ align-items: center;
39
+ }
40
+
41
+ .expandColumn {
42
+ width: vars.$expand-column-width;
43
+ }
44
+
45
+ .reorderColumn {
46
+ width: vars.$reorder-column-width;
47
+ }
48
+
49
+ .headerCell {
50
+ @include typography.body-sm-md;
51
+ color: var(--color-font-main);
52
+ text-align: left;
53
+ padding: 0 var(--spacing-standard);
54
+ height: var(--ds-table-header-height);
55
+
56
+ &.sortableHeader {
57
+ cursor: pointer;
58
+ user-select: none;
59
+ }
60
+
61
+ .pageButtonIconContainer {
62
+ display: flex;
63
+ align-items: center;
64
+ justify-content: center;
65
+ width: 24px;
66
+ height: 24px;
67
+
68
+ &.pageButtonIcon {
69
+ color: var(--neutral-4);
70
+ transition: transform 0.2s ease-in-out;
71
+ }
72
+ }
73
+ }
74
+
75
+ .headerSortContainer {
76
+ display: flex;
77
+ align-items: center;
78
+ justify-content: space-between;
79
+ gap: vars.$header-sort-gap;
80
+ height: 100%;
81
+ }
@@ -0,0 +1,99 @@
1
+ import { flexRender } from '@tanstack/react-table';
2
+ import classnames from 'classnames';
3
+ import { DsCheckbox } from '../../../ds-checkbox';
4
+ import { DsIcon } from '../../../ds-icon';
5
+ import { TableHead, TableHeader, TableRow } from '../core-table';
6
+ import styles from './ds-table-header.module.scss';
7
+ import stylesShared from '../../styles/shared/ds-table-shared.module.scss';
8
+ import type { DsTableHeaderProps } from './ds-table-header.types';
9
+ import { useDsTableContext } from '../../context/ds-table-context';
10
+ import { getColumnStyle } from '../../utils/column-styling';
11
+
12
+ const DsTableHeader = <TData,>({ table }: DsTableHeaderProps<TData>) => {
13
+ const { stickyHeader, bordered, expandable, selectable, reorderable, showSelectAllCheckbox, virtualized } =
14
+ useDsTableContext<TData, unknown>();
15
+
16
+ return (
17
+ <TableHeader
18
+ className={classnames(stickyHeader && styles.stickyHeader, virtualized && styles.virtualizedHeader)}
19
+ >
20
+ {table.getHeaderGroups().map((headerGroup) => (
21
+ <TableRow
22
+ key={headerGroup.id}
23
+ className={classnames(
24
+ styles.headerRow,
25
+ !bordered && styles.headerRowNoBorder,
26
+ virtualized && styles.headerRowVirtualized,
27
+ )}
28
+ >
29
+ {selectable && (
30
+ <TableHead className={classnames(styles.headerCell, styles.selectColumn)}>
31
+ {showSelectAllCheckbox && (
32
+ <DsCheckbox
33
+ className={stylesShared.checkboxContainer}
34
+ checked={
35
+ table.getIsAllRowsSelected()
36
+ ? true
37
+ : table.getIsSomeRowsSelected()
38
+ ? 'indeterminate'
39
+ : false
40
+ }
41
+ onClick={(e) => {
42
+ e.stopPropagation();
43
+ const toggleHandler = table.getToggleAllRowsSelectedHandler();
44
+ toggleHandler(e);
45
+ }}
46
+ />
47
+ )}
48
+ </TableHead>
49
+ )}
50
+ {expandable && <TableHead className={classnames(styles.headerCell, styles.expandColumn)} />}
51
+ {reorderable && (
52
+ <TableHead className={classnames(styles.headerCell, styles.reorderColumn)}>Order</TableHead>
53
+ )}
54
+ {headerGroup.headers.map((header, idx) => {
55
+ const isLastColumn = idx === headerGroup.headers.length - 1;
56
+ const headerStyle = getColumnStyle(header.column.getSize(), virtualized, isLastColumn);
57
+
58
+ return (
59
+ <TableHead
60
+ key={header.id}
61
+ className={classnames(styles.headerCell, header.column.getCanSort() && styles.sortableHeader)}
62
+ onClick={header.column.getToggleSortingHandler()}
63
+ style={headerStyle}
64
+ >
65
+ {header.isPlaceholder ? null : (
66
+ <div className={styles.headerSortContainer}>
67
+ <div>{flexRender(header.column.columnDef.header, header.getContext())}</div>
68
+ {header.column.getCanSort() && (
69
+ <div className={styles.pageButtonIconContainer}>
70
+ {{
71
+ asc: (
72
+ <DsIcon
73
+ icon="arrow_drop_up"
74
+ className={classnames(styles.pageButtonIcon, stylesShared.pageButtonIcon)}
75
+ />
76
+ ),
77
+ desc: (
78
+ <DsIcon
79
+ icon="arrow_drop_down"
80
+ className={classnames(styles.pageButtonIcon, stylesShared.pageButtonIcon)}
81
+ />
82
+ ),
83
+ }[header.column.getIsSorted() as string] ?? (
84
+ <div className={classnames(styles.pageButtonIcon, stylesShared.pageButtonIcon)} />
85
+ )}
86
+ </div>
87
+ )}
88
+ </div>
89
+ )}
90
+ </TableHead>
91
+ );
92
+ })}
93
+ </TableRow>
94
+ ))}
95
+ </TableHeader>
96
+ );
97
+ };
98
+
99
+ export default DsTableHeader;
@@ -0,0 +1,11 @@
1
+ import type { Table } from '@tanstack/react-table';
2
+
3
+ /**
4
+ * Props for the table header component
5
+ */
6
+ export interface DsTableHeaderProps<TData> {
7
+ /**
8
+ * The table instance from @tanstack/react-table
9
+ */
10
+ table: Table<TData>;
11
+ }
@@ -0,0 +1,2 @@
1
+ export { default as DsTableHeader } from './ds-table-header';
2
+ export * from './ds-table-header.types';
@@ -0,0 +1,137 @@
1
+ @use '../../../../styles/typography';
2
+ @use '../../styles/variables' as vars;
3
+
4
+ @mixin expanded-row-border($side) {
5
+ $border: 1px solid var(--color-border-action-primary);
6
+
7
+ // Prevent double border with adjacent expanded rows.
8
+ &:not(.expandedRow + &) > td {
9
+ border-#{$side}: $border;
10
+ }
11
+
12
+ & > td:first-child {
13
+ border-inline-start: $border;
14
+ }
15
+
16
+ & > td:last-child {
17
+ border-inline-end: $border;
18
+ }
19
+ }
20
+
21
+ .tableRow {
22
+ &:not(.virtualizedRow) {
23
+ &:not(:last-child) {
24
+ .tableCell {
25
+ border-bottom: vars.$border-width solid var(--color-border-secondary);
26
+ }
27
+ }
28
+
29
+ .cellCheckbox.tableCell {
30
+ padding: 0;
31
+ width: vars.$select-column-width;
32
+ }
33
+ }
34
+
35
+ &.virtualizedRow {
36
+ display: grid;
37
+ grid-template-columns: subgrid;
38
+ grid-column: 1 / -1;
39
+ grid-row: 1;
40
+ align-items: center;
41
+
42
+ &:not(:last-child) {
43
+ border-bottom: vars.$border-width solid var(--color-border-secondary);
44
+ }
45
+
46
+ .tableCell {
47
+ &.cellCheckbox {
48
+ text-align: center;
49
+ padding: 0;
50
+ width: vars.$select-column-width;
51
+ }
52
+ }
53
+ }
54
+
55
+ &:hover {
56
+ background-color: var(--color-background-secondary);
57
+ }
58
+
59
+ &[data-state='selected'] {
60
+ background-color: var(--color-background-selected-weak);
61
+ }
62
+
63
+ &[data-state='active'] {
64
+ background-color: var(--color-background-selected-weak);
65
+ }
66
+
67
+ &.clickableRow {
68
+ cursor: pointer;
69
+ }
70
+
71
+ &.rowNoBorder {
72
+ border-bottom: none;
73
+ }
74
+
75
+ &.expanded {
76
+ @include expanded-row-border('top');
77
+ }
78
+
79
+ &.sizeSmall {
80
+ height: var(--ds-table-row-small);
81
+ }
82
+
83
+ &.sizeMedium {
84
+ height: var(--ds-table-row-medium);
85
+ }
86
+
87
+ &.sizeLarge {
88
+ height: var(--ds-table-row-large);
89
+ }
90
+ }
91
+
92
+ .expandedRow {
93
+ background-color: var(--color-background-secondary);
94
+
95
+ & > td {
96
+ padding: var(--spacing-standard);
97
+ }
98
+
99
+ @include expanded-row-border('bottom');
100
+ }
101
+
102
+ .cellButton {
103
+ width: vars.$expand-column-width;
104
+ }
105
+
106
+ .cellReorder {
107
+ width: vars.$reorder-column-width;
108
+ text-align: center;
109
+
110
+ &.isDragging {
111
+ background: var(--color-background-action);
112
+
113
+ .rowDragHandle {
114
+ color: var(--color-secondary-white);
115
+ }
116
+ }
117
+ }
118
+
119
+ .tableCell {
120
+ @include typography.body-sm-reg;
121
+ vertical-align: middle;
122
+ color: var(--color-font-main);
123
+ padding: 0 var(--spacing-standard);
124
+ }
125
+
126
+ .expandToggleButton {
127
+ background: none;
128
+ border: none;
129
+ padding: 0;
130
+ margin: 0;
131
+ cursor: pointer;
132
+ display: inline-flex;
133
+ align-items: center;
134
+ justify-content: center;
135
+ opacity: 1;
136
+ transition-property: opacity, background-color;
137
+ }
@@ -0,0 +1,205 @@
1
+ import React from 'react';
2
+ import classnames from 'classnames';
3
+ import { useSortable } from '@dnd-kit/sortable';
4
+ import { CSS } from '@dnd-kit/utilities';
5
+ import { DsIcon } from '../../../ds-icon';
6
+ import { DsCheckbox } from '../../../ds-checkbox';
7
+ import { DsButton } from '../../../ds-button';
8
+ import { TableCell, TableRow } from '../core-table';
9
+ import { DsTableCell } from '../ds-table-cell';
10
+ import type { DsTableRowProps } from './ds-table-row.types';
11
+ import styles from './ds-table-row.module.scss';
12
+ import stylesShared from '../../styles/shared/ds-table-shared.module.scss';
13
+ import { useDsTableContext } from '../../context/ds-table-context';
14
+ import { mergeRefs } from '../../utils/merge-refs';
15
+ import { getColumnStyle } from '../../utils/column-styling';
16
+
17
+ interface DsRowDragHandleProps {
18
+ isDragging: boolean;
19
+ attributes: ReturnType<typeof useSortable>['attributes'];
20
+ listeners: ReturnType<typeof useSortable>['listeners'];
21
+ }
22
+
23
+ const DsRowDragHandle = ({ isDragging, attributes, listeners }: DsRowDragHandleProps) => {
24
+ return (
25
+ <TableCell
26
+ className={classnames(styles.tableCell, styles.cellReorder, {
27
+ [styles.isDragging]: isDragging,
28
+ })}
29
+ >
30
+ <DsIcon
31
+ className={styles.rowDragHandle}
32
+ icon={isDragging ? 'drag_indicator' : 'arrow_downward'}
33
+ size={isDragging ? 'medium' : 'small'}
34
+ onClick={(e: React.MouseEvent) => e.stopPropagation()}
35
+ {...attributes}
36
+ {...listeners}
37
+ ></DsIcon>
38
+ </TableCell>
39
+ );
40
+ };
41
+
42
+ const DsTableRow = <TData,>({ ref, row, virtualRow }: DsTableRowProps<TData>) => {
43
+ const {
44
+ expandable,
45
+ expandedRows,
46
+ selectable,
47
+ reorderable,
48
+ onRowClick,
49
+ onRowDoubleClick,
50
+ renderExpandedRow,
51
+ virtualized,
52
+ bordered,
53
+ highlightOnHover,
54
+ rowSize,
55
+ toggleRowExpanded,
56
+ primaryRowActions,
57
+ secondaryRowActions,
58
+ activeRowId,
59
+ } = useDsTableContext<TData, unknown>();
60
+ const isExpanded = expandedRows[row.id];
61
+ const isExpandable = typeof expandable === 'function' ? expandable(row.original) : expandable;
62
+ const isActive = activeRowId === row.id;
63
+
64
+ const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({
65
+ id: row.id,
66
+ disabled: !reorderable,
67
+ });
68
+ const rowStyle: React.CSSProperties =
69
+ virtualRow && virtualized
70
+ ? {
71
+ transform: `translateY(${String(virtualRow.start)}px)`,
72
+ }
73
+ : reorderable
74
+ ? {
75
+ // Convert DND-kit's transform coordinates to CSS transform string
76
+ transform: CSS.Transform.toString(transform),
77
+ transition,
78
+ ...(isDragging
79
+ ? {
80
+ background: 'var(--action-active-light)',
81
+ boxShadow: '0 0 12px 0 rgba(0, 102, 250, 0.60)',
82
+ zIndex: 1,
83
+ }
84
+ : {}),
85
+ position: 'relative',
86
+ }
87
+ : {};
88
+
89
+ return (
90
+ <React.Fragment key={row.id}>
91
+ <TableRow
92
+ ref={mergeRefs(reorderable ? setNodeRef : null, ref)}
93
+ data-state={isActive ? 'active' : row.getIsSelected() ? 'selected' : undefined}
94
+ className={classnames(
95
+ styles.tableRow,
96
+ {
97
+ [styles.sizeSmall]: rowSize === 'small',
98
+ [styles.sizeMedium]: rowSize === 'medium',
99
+ [styles.sizeLarge]: rowSize === 'large',
100
+ },
101
+ virtualized && styles.virtualizedRow,
102
+ onRowClick && styles.clickableRow,
103
+ highlightOnHover && styles.highlightHoverRow,
104
+ !bordered && styles.rowNoBorder,
105
+ isExpanded && styles.expanded,
106
+ )}
107
+ style={rowStyle}
108
+ onClick={() => onRowClick?.(row.original)}
109
+ onDoubleClick={() => onRowDoubleClick?.(row.original)}
110
+ >
111
+ {selectable && (
112
+ <TableCell className={classnames(styles.tableCell, styles.cellCheckbox)}>
113
+ <DsCheckbox
114
+ className={stylesShared.checkboxContainer}
115
+ checked={row.getIsSelected()}
116
+ disabled={!row.getCanSelect()}
117
+ onClick={(e) => {
118
+ e.stopPropagation();
119
+ const toggleHandler = row.getToggleSelectedHandler();
120
+ toggleHandler(e);
121
+ }}
122
+ onDoubleClick={(e: React.MouseEvent) => {
123
+ e.stopPropagation();
124
+ }}
125
+ />
126
+ </TableCell>
127
+ )}
128
+ {expandable && (
129
+ <TableCell className={classnames(styles.tableCell, styles.cellButton)}>
130
+ {isExpandable && (
131
+ <DsButton
132
+ variant={virtualized ? 'ghost' : 'borderless'}
133
+ size="small"
134
+ onClick={(e: React.MouseEvent) => {
135
+ e.stopPropagation();
136
+ toggleRowExpanded(row.id);
137
+ }}
138
+ onDoubleClick={(e: React.MouseEvent) => {
139
+ e.stopPropagation();
140
+ }}
141
+ className={styles.expandToggleButton}
142
+ >
143
+ <DsIcon
144
+ icon={virtualized ? (isExpanded ? 'arrow_drop_down' : 'arrow_right') : 'chevron_right'}
145
+ className={classnames(
146
+ stylesShared.pageButtonIcon,
147
+ !virtualized && isExpanded && 'rotate-90',
148
+ )}
149
+ />
150
+ </DsButton>
151
+ )}
152
+ </TableCell>
153
+ )}
154
+ {reorderable && (
155
+ <DsRowDragHandle isDragging={isDragging} attributes={attributes} listeners={listeners} />
156
+ )}
157
+ {row.getVisibleCells().map((cell, idx) => {
158
+ const isLastColumn = idx === row.getVisibleCells().length - 1;
159
+ const cellStyle = getColumnStyle(cell.column.getSize(), virtualized, isLastColumn);
160
+
161
+ return (
162
+ <TableCell key={cell.id} className={styles.tableCell} style={cellStyle}>
163
+ {isLastColumn ? (
164
+ <DsTableCell
165
+ row={row}
166
+ cell={cell}
167
+ primaryRowActions={primaryRowActions}
168
+ secondaryRowActions={secondaryRowActions}
169
+ />
170
+ ) : (
171
+ <DsTableCell row={row} cell={cell} />
172
+ )}
173
+ </TableCell>
174
+ );
175
+ })}
176
+ </TableRow>
177
+ {isExpanded && renderExpandedRow && (
178
+ <TableRow
179
+ style={
180
+ virtualRow && virtualized
181
+ ? {
182
+ transform: `translateY(${String(virtualRow.start + virtualRow.size)}px)`,
183
+ }
184
+ : undefined
185
+ }
186
+ className={styles.expandedRow}
187
+ >
188
+ <TableCell
189
+ colSpan={
190
+ row.getVisibleCells().length +
191
+ (selectable ? 1 : 0) +
192
+ (isExpandable ? 1 : 0) +
193
+ (reorderable ? 1 : 0)
194
+ }
195
+ className={styles.tableCell}
196
+ >
197
+ {renderExpandedRow(row.original)}
198
+ </TableCell>
199
+ </TableRow>
200
+ )}
201
+ </React.Fragment>
202
+ );
203
+ };
204
+
205
+ export default DsTableRow;
@@ -0,0 +1,22 @@
1
+ import type { Ref } from 'react';
2
+ import type { Row } from '@tanstack/react-table';
3
+ import type { VirtualItem } from '@tanstack/react-virtual';
4
+
5
+ /**
6
+ * Props for the table row component
7
+ */
8
+ export interface DsTableRowProps<TData> {
9
+ /**
10
+ * Ref for the table row
11
+ */
12
+ ref?: Ref<HTMLTableRowElement>;
13
+ /**
14
+ * The row data from the table
15
+ */
16
+ row: Row<TData>;
17
+
18
+ /**
19
+ * Virtual row data for virtualized tables
20
+ */
21
+ virtualRow?: VirtualItem;
22
+ }
@@ -0,0 +1,2 @@
1
+ export { default as DsTableRow } from './ds-table-row';
2
+ export * from './ds-table-row.types';
@@ -0,0 +1,39 @@
1
+ import { createContext, useContext } from 'react';
2
+ import type { DsDataTableProps, DsTableRowSize } from '../ds-table.types';
3
+
4
+ export interface DsTableContextType<TData, TValue> extends Partial<DsDataTableProps<TData, TValue>> {
5
+ /**
6
+ * The expanded rows
7
+ */
8
+ expandedRows: Record<string, boolean>;
9
+ /**
10
+ * Toggle the expanded state of a row
11
+ * @param rowId - The id of the row to toggle
12
+ */
13
+ toggleRowExpanded: (rowId: string) => void;
14
+ /**
15
+ * Whether the table is virtualized
16
+ * @default false
17
+ */
18
+ virtualized?: boolean;
19
+ /**
20
+ * Row size variant
21
+ * @default 'medium'
22
+ */
23
+ rowSize: DsTableRowSize;
24
+ /**
25
+ * ID of the currently active row
26
+ */
27
+ activeRowId?: string | null;
28
+ }
29
+
30
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
31
+ export const DsTableContext = createContext<DsTableContextType<any, any> | null>(null);
32
+
33
+ export const useDsTableContext = <TData, TValue>(): DsTableContextType<TData, TValue> => {
34
+ const context = useContext(DsTableContext);
35
+ if (!context) {
36
+ throw new Error('useDsTableContext must be used within DsTable');
37
+ }
38
+ return context as DsTableContextType<TData, TValue>;
39
+ };
@@ -0,0 +1,60 @@
1
+ @use '../../styles/typography';
2
+ @use '../../styles/utilities' as utils;
3
+ @use './styles/variables' as vars;
4
+
5
+ .container {
6
+ border-radius: vars.$border-radius;
7
+ border-width: vars.$border-width;
8
+ border-style: solid;
9
+ border-color: var(--neutral-6);
10
+ background: var(--color-background);
11
+ }
12
+
13
+ .virtualizedContainer {
14
+ position: relative;
15
+ height: vars.$virtualized-height;
16
+ overflow: auto;
17
+ }
18
+
19
+ .dataTableContainer {
20
+ max-height: 100%;
21
+ overflow: auto;
22
+ }
23
+
24
+ .table {
25
+ width: 100%;
26
+ caption-side: bottom;
27
+ @include typography.p-base;
28
+
29
+ &.tableNoBorder {
30
+ border-collapse: separate;
31
+ border-spacing: 0;
32
+ border: none;
33
+ }
34
+ }
35
+
36
+ .fullWidth {
37
+ width: 100%;
38
+ }
39
+
40
+ .emptyState {
41
+ height: vars.$empty-state-height;
42
+ text-align: center;
43
+ }
44
+
45
+ .emptyStateVirtualized {
46
+ position: absolute;
47
+ inset: 0;
48
+ top: var(--ds-table-header-height);
49
+ }
50
+
51
+ .virtualized {
52
+ display: grid;
53
+ grid-template-columns: var(--ds-table-columns-template);
54
+ }
55
+
56
+ .virtualizedBody {
57
+ display: grid;
58
+ grid-template-columns: subgrid;
59
+ grid-column: 1 / -1;
60
+ }