@drivenets/design-system 0.6.1 → 0.7.0

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 (134) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/dist/index.cjs +12394 -8354
  3. package/dist/index.d.cts +806 -118
  4. package/dist/index.d.cts.map +1 -1
  5. package/dist/index.d.ts +806 -118
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +12376 -8357
  8. package/dist/index.js.map +1 -1
  9. package/dist/index.min.css +1 -1
  10. package/package.json +25 -23
  11. package/src/components/ds-autocomplete/ds-autocomplete.module.scss +2 -1
  12. package/src/components/ds-autocomplete/ds-autocomplete.tsx +47 -40
  13. package/src/components/ds-autocomplete/ds-autocomplete.types.tsx +37 -14
  14. package/src/components/ds-button/versions/ds-button-new/ds-button-new.module.scss +3 -7
  15. package/src/components/ds-comment-bubble/components/ds-comment-thread/ds-comment-thread.module.scss +62 -0
  16. package/src/components/ds-comment-bubble/components/ds-comment-thread/ds-comment-thread.tsx +83 -0
  17. package/src/components/ds-comment-bubble/components/ds-comment-thread/ds-comment-thread.types.ts +12 -0
  18. package/src/components/ds-comment-bubble/components/ds-comment-thread/index.ts +2 -0
  19. package/src/components/ds-comment-bubble/components/ds-thread-item/ds-thread-item.module.scss +149 -0
  20. package/src/components/ds-comment-bubble/components/ds-thread-item/ds-thread-item.tsx +147 -0
  21. package/src/components/ds-comment-bubble/components/ds-thread-item/ds-thread-item.types.ts +15 -0
  22. package/src/components/ds-comment-bubble/components/ds-thread-item/index.ts +2 -0
  23. package/src/components/ds-comment-bubble/ds-comment-bubble.module.scss +298 -0
  24. package/src/components/ds-comment-bubble/ds-comment-bubble.tsx +241 -0
  25. package/src/components/ds-comment-bubble/ds-comment-bubble.types.ts +27 -0
  26. package/src/components/ds-comment-bubble/hooks/index.ts +3 -0
  27. package/src/components/ds-comment-bubble/hooks/use-auto-resize.ts +17 -0
  28. package/src/components/ds-comment-bubble/hooks/use-click-outside.ts +22 -0
  29. package/src/components/ds-comment-bubble/hooks/use-scroll-overflow.ts +27 -0
  30. package/src/components/ds-comment-bubble/index.ts +6 -0
  31. package/src/components/ds-comment-card/ds-comment-card.module.scss +162 -0
  32. package/src/components/ds-comment-card/ds-comment-card.tsx +171 -0
  33. package/src/components/ds-comment-card/ds-comment-card.types.ts +45 -0
  34. package/src/components/ds-comment-card/index.ts +2 -0
  35. package/src/components/ds-comment-indicator/ds-comment-indicator.module.scss +65 -0
  36. package/src/components/ds-comment-indicator/ds-comment-indicator.tsx +48 -0
  37. package/src/components/ds-comment-indicator/ds-comment-indicator.types.ts +13 -0
  38. package/src/components/ds-comment-indicator/index.ts +2 -0
  39. package/src/components/ds-comments-drawer/comments-filters.test.ts +483 -0
  40. package/src/components/ds-comments-drawer/comments-filters.ts +134 -0
  41. package/src/components/ds-comments-drawer/comments-filters.types.ts +14 -0
  42. package/src/components/ds-comments-drawer/components/comments-filter-modal/comments-filter-modal.module.scss +92 -0
  43. package/src/components/ds-comments-drawer/components/comments-filter-modal/comments-filter-modal.tsx +219 -0
  44. package/src/components/ds-comments-drawer/components/comments-filter-modal/comments-filter-modal.types.ts +12 -0
  45. package/src/components/ds-comments-drawer/components/comments-filter-modal/index.ts +2 -0
  46. package/src/components/ds-comments-drawer/ds-comments-drawer.module.scss +67 -0
  47. package/src/components/ds-comments-drawer/ds-comments-drawer.tsx +215 -0
  48. package/src/components/ds-comments-drawer/ds-comments-drawer.types.ts +23 -0
  49. package/src/components/ds-comments-drawer/index.ts +3 -0
  50. package/src/components/ds-dropdown-menu/ds-dropdown-menu.tsx +2 -0
  51. package/src/components/ds-expandable-text-input/ds-expandable-text-input.tsx +8 -4
  52. package/src/components/ds-file-upload/types/accept-types.ts +0 -1
  53. package/src/components/ds-filter-status-icon/ds-filter-status-icon.module.scss +19 -0
  54. package/src/components/ds-filter-status-icon/ds-filter-status-icon.tsx +35 -0
  55. package/src/components/ds-filter-status-icon/ds-filter-status-icon.types.ts +31 -0
  56. package/src/components/ds-filter-status-icon/index.ts +3 -0
  57. package/src/components/ds-icon/custom-icons/index.ts +10 -0
  58. package/src/components/ds-icon/custom-icons/special-failed.tsx +16 -0
  59. package/src/components/ds-icon/custom-icons/special-paused.tsx +16 -0
  60. package/src/components/ds-icon/custom-icons/special-running.tsx +16 -0
  61. package/src/components/ds-icon/custom-icons/special-warning.tsx +16 -0
  62. package/src/components/ds-panel/ds-panel.module.scss +3 -3
  63. package/src/components/ds-progress-arc/ds-progress-arc.module.scss +57 -0
  64. package/src/components/ds-progress-arc/ds-progress-arc.tsx +111 -0
  65. package/src/components/ds-progress-arc/ds-progress-arc.types.ts +34 -0
  66. package/src/components/ds-progress-arc/index.ts +3 -0
  67. package/src/components/ds-progress-arc/utils.test.ts +79 -0
  68. package/src/components/ds-progress-arc/utils.ts +61 -0
  69. package/src/components/ds-progress-donut/ds-progress-donut.module.scss +67 -0
  70. package/src/components/ds-progress-donut/ds-progress-donut.tsx +83 -0
  71. package/src/components/ds-progress-donut/ds-progress-donut.types.ts +38 -0
  72. package/src/components/ds-progress-donut/index.ts +2 -0
  73. package/src/components/ds-progress-donut/utils.ts +1 -0
  74. package/src/components/ds-progress-linear/ds-progress-linear.module.scss +100 -0
  75. package/src/components/ds-progress-linear/ds-progress-linear.tsx +107 -0
  76. package/src/components/ds-progress-linear/ds-progress-linear.types.ts +72 -0
  77. package/src/components/ds-progress-linear/index.ts +2 -0
  78. package/src/components/ds-progress-linear/utils.test.ts +70 -0
  79. package/src/components/ds-progress-linear/utils.ts +7 -0
  80. package/src/components/ds-radio-group/ds-radio-group.tsx +2 -0
  81. package/src/components/ds-select/ds-select.tsx +2 -1
  82. package/src/components/ds-select/ds-select.types.tsx +7 -0
  83. package/src/components/ds-stepper/components/ds-step.tsx +1 -1
  84. package/src/components/ds-stepper/ds-stepper.module.scss +16 -2
  85. package/src/components/ds-stepper/ds-stepper.tsx +3 -1
  86. package/src/components/ds-table/components/ds-table-body-virtualized/ds-table-body-virtualized.module.scss +9 -0
  87. package/src/components/ds-table/components/ds-table-body-virtualized/ds-table-body-virtualized.tsx +137 -0
  88. package/src/components/ds-table/components/ds-table-body-virtualized/ds-table-body-virtualized.types.ts +22 -0
  89. package/src/components/ds-table/components/ds-table-body-virtualized/index.ts +2 -0
  90. package/src/components/ds-table/components/ds-table-cell/ds-table-cell.module.scss +3 -1
  91. package/src/components/ds-table/components/ds-table-header/ds-table-header.module.scss +7 -10
  92. package/src/components/ds-table/components/ds-table-header/ds-table-header.tsx +3 -4
  93. package/src/components/ds-table/components/ds-table-row/ds-table-row.module.scss +13 -53
  94. package/src/components/ds-table/components/ds-table-row/ds-table-row.tsx +32 -85
  95. package/src/components/ds-table/components/ds-table-row/ds-table-row.types.ts +0 -6
  96. package/src/components/ds-table/components/ds-table-row-expandable-cell/ds-table-row-expandable-cell.module.scss +10 -0
  97. package/src/components/ds-table/components/ds-table-row-expandable-cell/ds-table-row-expandable-cell.tsx +45 -0
  98. package/src/components/ds-table/components/ds-table-row-expandable-cell/ds-table-row-expandable-cell.types.ts +7 -0
  99. package/src/components/ds-table/components/ds-table-row-expandable-cell/index.ts +2 -0
  100. package/src/components/ds-table/components/ds-table-row-selectable-cell/ds-table-row-selectable-cell.module.scss +6 -0
  101. package/src/components/ds-table/components/ds-table-row-selectable-cell/ds-table-row-selectable-cell.tsx +30 -0
  102. package/src/components/ds-table/components/ds-table-row-selectable-cell/ds-table-row-selectable-cell.types.ts +6 -0
  103. package/src/components/ds-table/components/ds-table-row-selectable-cell/index.ts +2 -0
  104. package/src/components/ds-table/components/ds-table-row-virtualized/ds-table-row-virtualized.module.scss +80 -0
  105. package/src/components/ds-table/components/ds-table-row-virtualized/ds-table-row-virtualized.tsx +95 -0
  106. package/src/components/ds-table/components/ds-table-row-virtualized/ds-table-row-virtualized.types.ts +11 -0
  107. package/src/components/ds-table/components/ds-table-row-virtualized/index.ts +2 -0
  108. package/src/components/ds-table/context/ds-table-context.tsx +0 -9
  109. package/src/components/ds-table/ds-table.module.scss +4 -17
  110. package/src/components/ds-table/ds-table.tsx +44 -77
  111. package/src/components/ds-table/ds-table.types.ts +57 -12
  112. package/src/components/ds-table/index.ts +1 -0
  113. package/src/components/ds-table/styles/_mixins.scss +15 -0
  114. package/src/components/ds-table/styles/_variables.scss +2 -2
  115. package/src/components/ds-table/utils/{column-styling.ts → column-size.ts} +4 -14
  116. package/src/components/ds-table/utils/constants.ts +4 -0
  117. package/src/components/ds-tag/index.tsx +1 -0
  118. package/src/components/ds-tag-filter/ds-tag-filter.module.scss +13 -15
  119. package/src/components/ds-tag-filter/ds-tag-filter.tsx +38 -72
  120. package/src/components/ds-tag-filter/ds-tag-filter.types.ts +2 -3
  121. package/src/components/ds-tag-filter/hooks/use-tag-overflow-calculation.ts +12 -62
  122. package/src/components/ds-tag-filter/utils.test.ts +2 -108
  123. package/src/components/ds-tag-filter/utils.ts +2 -12
  124. package/src/components/ds-tree/ds-tree.module.scss +283 -0
  125. package/src/components/ds-tree/ds-tree.tsx +172 -0
  126. package/src/components/ds-tree/ds-tree.types.ts +83 -0
  127. package/src/components/ds-tree/ds-tree.utils.ts +11 -0
  128. package/src/components/ds-tree/index.ts +3 -0
  129. package/src/index.ts +9 -0
  130. package/src/utils/format-relative-time.test.ts +74 -0
  131. package/src/utils/format-relative-time.ts +52 -0
  132. package/src/utils/numbers.test.ts +24 -0
  133. package/src/utils/numbers.ts +1 -0
  134. package/src/components/ds-table/utils/create-columns-grid-template.ts +0 -23
@@ -0,0 +1,137 @@
1
+ import { type Row } from '@tanstack/react-table';
2
+ import { useVirtualizer, type Virtualizer } from '@tanstack/react-virtual';
3
+ import { useLayoutEffect, useRef } from 'react';
4
+ import styles from './ds-table-body-virtualized.module.scss';
5
+ import { DsTableRowVirtualized } from '../ds-table-row-virtualized';
6
+ import type { DsTableBodyVirtualizedProps } from './ds-table-body-virtualized.types';
7
+ import { TableBody } from '../core-table';
8
+ import { EMPTY_TABLE_STATE_TEXT } from '../../utils/constants';
9
+
10
+ export const DsTableBodyVirtualized = <TData,>({
11
+ table,
12
+ tableContainerRef,
13
+ emptyState,
14
+ estimateSize,
15
+ overscan,
16
+ onScroll,
17
+ }: DsTableBodyVirtualizedProps<TData>) => {
18
+ const rowsMapRef = useRef<Map<string, HTMLTableRowElement>>(new Map());
19
+ const rowHeightsMapRef = useRef<Map<string, number>>(new Map());
20
+
21
+ const { rows } = table.getRowModel();
22
+
23
+ const rowsAndExpandedRowContent = rows.flatMap((row) =>
24
+ row.getIsExpanded() ? [{ row }, { row, isExpandedRowContent: true }] : [{ row }],
25
+ );
26
+
27
+ const getItemKey = (index: number) => {
28
+ const item = rowsAndExpandedRowContent[index];
29
+ return item ? `${item.row.id}${item.isExpandedRowContent ? '-expanded-content' : ''}` : String(index);
30
+ };
31
+
32
+ const rowVirtualizer = useVirtualizer<HTMLDivElement, HTMLTableRowElement>({
33
+ count: rowsAndExpandedRowContent.length,
34
+ estimateSize: (index) => {
35
+ const cachedHeight = rowHeightsMapRef.current.get(getItemKey(index));
36
+ return cachedHeight || estimateSize;
37
+ }, // estimate row height for accurate scrollbar dragging
38
+ getItemKey,
39
+ getScrollElement: () => tableContainerRef.current,
40
+ // measure dynamic row height, except in firefox because it measures table border height incorrectly
41
+ measureElement:
42
+ typeof window !== 'undefined' && navigator.userAgent.indexOf('Firefox') === -1
43
+ ? (element) => element.getBoundingClientRect().height
44
+ : undefined,
45
+ overscan: overscan ?? 5,
46
+ onChange: (instance, sync) => {
47
+ requestAnimationFrame(() => {
48
+ instance.getVirtualItems().forEach((virtualRow) => {
49
+ const row = rowsMapRef.current.get(String(virtualRow.key));
50
+ if (!row) {
51
+ return;
52
+ }
53
+
54
+ row.style.transform = `translateY(${virtualRow.start.toString()}px)`;
55
+ });
56
+ });
57
+
58
+ if (sync && onScroll) {
59
+ const scrollOffset = instance.scrollOffset || 0;
60
+ const totalContentHeight = instance.getTotalSize();
61
+ const viewportHeight = instance.scrollElement?.clientHeight;
62
+
63
+ if (viewportHeight) {
64
+ onScroll({ scrollOffset, totalContentHeight, viewportHeight });
65
+ }
66
+ }
67
+ },
68
+ });
69
+
70
+ useLayoutEffect(() => {
71
+ rowVirtualizer.measure();
72
+ // eslint-disable-next-line react-hooks/exhaustive-deps
73
+ }, [table.getState()]);
74
+
75
+ return (
76
+ <DsTableBody
77
+ rowsMapRef={rowsMapRef}
78
+ rowHeightsMapRef={rowHeightsMapRef}
79
+ rowVirtualizer={rowVirtualizer}
80
+ rowsAndExpandedRowContent={rowsAndExpandedRowContent}
81
+ emptyState={emptyState}
82
+ />
83
+ );
84
+ };
85
+
86
+ interface DsTableBodyProps<TData> {
87
+ rowVirtualizer: Virtualizer<HTMLDivElement, HTMLTableRowElement>;
88
+ rowsMapRef: React.RefObject<Map<string, HTMLTableRowElement>>;
89
+ rowHeightsMapRef: React.RefObject<Map<string, number>>;
90
+ rowsAndExpandedRowContent: {
91
+ row: Row<TData>;
92
+ isExpandedRowContent?: boolean;
93
+ }[];
94
+ emptyState?: React.ReactNode;
95
+ }
96
+
97
+ function DsTableBody<TData>({
98
+ rowVirtualizer,
99
+ rowsMapRef,
100
+ rowHeightsMapRef,
101
+ rowsAndExpandedRowContent,
102
+ emptyState,
103
+ }: DsTableBodyProps<TData>) {
104
+ const virtualRows = rowVirtualizer.getVirtualItems();
105
+
106
+ return (
107
+ <TableBody
108
+ className={styles.body}
109
+ style={{
110
+ height: `${rowVirtualizer.getTotalSize().toString()}px`, // tells scrollbar how big the table is
111
+ }}
112
+ >
113
+ {virtualRows.length > 0 ? (
114
+ virtualRows.map((virtualRow) => {
115
+ const row = rowsAndExpandedRowContent[virtualRow.index];
116
+ if (!row) {
117
+ return null;
118
+ }
119
+
120
+ return (
121
+ <DsTableRowVirtualized
122
+ key={virtualRow.key}
123
+ row={row.row}
124
+ isExpandedRowContent={row.isExpandedRowContent}
125
+ rowsMapRef={rowsMapRef}
126
+ rowHeightsMapRef={rowHeightsMapRef}
127
+ rowVirtualizer={rowVirtualizer}
128
+ virtualRow={virtualRow}
129
+ />
130
+ );
131
+ })
132
+ ) : (
133
+ <div className={styles.emptyState}>{emptyState || EMPTY_TABLE_STATE_TEXT}</div>
134
+ )}
135
+ </TableBody>
136
+ );
137
+ }
@@ -0,0 +1,22 @@
1
+ import type { Table } from '@tanstack/react-table';
2
+
3
+ export interface DsTableBodyVirtualizedProps<TData> {
4
+ table: Table<TData>;
5
+ tableContainerRef: React.RefObject<HTMLDivElement | null>;
6
+ emptyState?: React.ReactNode;
7
+ estimateSize: number;
8
+ overscan?: number;
9
+ onScroll?: (params: ScrollParams) => void;
10
+ }
11
+
12
+ /**
13
+ * Parameters passed to the onScroll callback in virtualized tables.
14
+ */
15
+ export interface ScrollParams {
16
+ /** The current vertical scroll position from the top of the scrollable content (in pixels) */
17
+ scrollOffset: number;
18
+ /** The total height of all content in the virtualized table (in pixels) */
19
+ totalContentHeight: number;
20
+ /** The visible height of the table container (in pixels) */
21
+ viewportHeight: number;
22
+ }
@@ -0,0 +1,2 @@
1
+ export * from './ds-table-body-virtualized';
2
+ export * from './ds-table-body-virtualized.types';
@@ -29,9 +29,11 @@
29
29
  justify-content: center;
30
30
  width: 36px;
31
31
  height: 36px;
32
+ border: none;
32
33
  border-radius: 50%;
33
34
  background: none;
34
35
  cursor: pointer;
36
+ outline: none;
35
37
  transition: background 0.15s;
36
38
  color: var(--color-icon-secondary);
37
39
 
@@ -42,7 +44,7 @@
42
44
  }
43
45
 
44
46
  &:hover,
45
- &:focus-within {
47
+ &[data-state='open'] {
46
48
  background: var(--color-background-action-hover-weak);
47
49
  color: var(--color-font-action);
48
50
  }
@@ -10,8 +10,6 @@
10
10
 
11
11
  .virtualizedHeader {
12
12
  display: grid;
13
- grid-template-columns: subgrid;
14
- grid-column: 1 / -1;
15
13
  }
16
14
 
17
15
  .headerRow {
@@ -32,20 +30,19 @@
32
30
  }
33
31
 
34
32
  .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;
33
+ display: flex;
34
+ width: 100%;
43
35
  }
44
36
 
45
37
  .reorderColumn {
46
38
  width: vars.$reorder-column-width;
47
39
  }
48
40
 
41
+ .expandColumn {
42
+ width: vars.$expand-column-width;
43
+ padding: 0;
44
+ }
45
+
49
46
  .headerCell {
50
47
  @include typography.body-sm-md;
51
48
  color: var(--color-font-main);
@@ -7,7 +7,7 @@ import styles from './ds-table-header.module.scss';
7
7
  import stylesShared from '../../styles/shared/ds-table-shared.module.scss';
8
8
  import type { DsTableHeaderProps } from './ds-table-header.types';
9
9
  import { useDsTableContext } from '../../context/ds-table-context';
10
- import { getColumnStyle } from '../../utils/column-styling';
10
+ import { getColumnSizeStyle } from '../../utils/column-size';
11
11
 
12
12
  const DsTableHeader = <TData,>({ table }: DsTableHeaderProps<TData>) => {
13
13
  const { stickyHeader, bordered, expandable, selectable, reorderable, showSelectAllCheckbox, virtualized } =
@@ -51,9 +51,8 @@ const DsTableHeader = <TData,>({ table }: DsTableHeaderProps<TData>) => {
51
51
  {reorderable && (
52
52
  <TableHead className={classnames(styles.headerCell, styles.reorderColumn)}>Order</TableHead>
53
53
  )}
54
- {headerGroup.headers.map((header, idx) => {
55
- const isLastColumn = idx === headerGroup.headers.length - 1;
56
- const headerStyle = getColumnStyle(header.column.getSize(), virtualized, isLastColumn);
54
+ {headerGroup.headers.map((header) => {
55
+ const headerStyle = getColumnSizeStyle(header.column.getSize(), virtualized);
57
56
 
58
57
  return (
59
58
  <TableHead
@@ -1,55 +1,14 @@
1
1
  @use '../../../../styles/typography';
2
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
- }
3
+ @use '../../styles/mixins' as table-mixins;
20
4
 
21
5
  .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) {
6
+ &:not(:last-child) {
7
+ .tableCell,
8
+ .selectableCell,
9
+ .expandableCell {
43
10
  border-bottom: vars.$border-width solid var(--color-border-secondary);
44
11
  }
45
-
46
- .tableCell {
47
- &.cellCheckbox {
48
- text-align: center;
49
- padding: 0;
50
- width: vars.$select-column-width;
51
- }
52
- }
53
12
  }
54
13
 
55
14
  &:hover {
@@ -73,7 +32,7 @@
73
32
  }
74
33
 
75
34
  &.expanded {
76
- @include expanded-row-border('top');
35
+ @include table-mixins.expanded-row-border('top');
77
36
  }
78
37
 
79
38
  &.sizeSmall {
@@ -96,11 +55,7 @@
96
55
  padding: var(--spacing-standard);
97
56
  }
98
57
 
99
- @include expanded-row-border('bottom');
100
- }
101
-
102
- .cellButton {
103
- width: vars.$expand-column-width;
58
+ @include table-mixins.expanded-row-border('bottom');
104
59
  }
105
60
 
106
61
  .cellReorder {
@@ -116,10 +71,15 @@
116
71
  }
117
72
  }
118
73
 
119
- .tableCell {
74
+ .tableCell,
75
+ .selectableCell,
76
+ .expandableCell {
120
77
  @include typography.body-sm-reg;
121
78
  vertical-align: middle;
122
79
  color: var(--color-font-main);
80
+ }
81
+
82
+ .tableCell {
123
83
  padding: 0 var(--spacing-standard);
124
84
  }
125
85
 
@@ -1,18 +1,17 @@
1
- import React from 'react';
1
+ import type React from 'react';
2
2
  import classnames from 'classnames';
3
3
  import { useSortable } from '@dnd-kit/sortable';
4
4
  import { CSS } from '@dnd-kit/utilities';
5
5
  import { DsIcon } from '../../../ds-icon';
6
- import { DsCheckbox } from '../../../ds-checkbox';
7
- import { DsButton } from '../../../ds-button';
8
6
  import { TableCell, TableRow } from '../core-table';
9
7
  import { DsTableCell } from '../ds-table-cell';
8
+ import { DsTableRowSelectableCell } from '../ds-table-row-selectable-cell';
9
+ import { DsTableRowExpandableCell } from '../ds-table-row-expandable-cell';
10
10
  import type { DsTableRowProps } from './ds-table-row.types';
11
11
  import styles from './ds-table-row.module.scss';
12
- import stylesShared from '../../styles/shared/ds-table-shared.module.scss';
13
12
  import { useDsTableContext } from '../../context/ds-table-context';
14
13
  import { mergeRefs } from '../../utils/merge-refs';
15
- import { getColumnStyle } from '../../utils/column-styling';
14
+ import { getColumnSizeStyle } from '../../utils/column-size';
16
15
 
17
16
  interface DsRowDragHandleProps {
18
17
  isDragging: boolean;
@@ -39,24 +38,21 @@ const DsRowDragHandle = ({ isDragging, attributes, listeners }: DsRowDragHandleP
39
38
  );
40
39
  };
41
40
 
42
- const DsTableRow = <TData,>({ ref, row, virtualRow }: DsTableRowProps<TData>) => {
41
+ const DsTableRow = <TData,>({ ref, row }: DsTableRowProps<TData>) => {
43
42
  const {
44
43
  expandable,
45
- expandedRows,
46
44
  selectable,
47
45
  reorderable,
48
46
  onRowClick,
49
47
  onRowDoubleClick,
50
48
  renderExpandedRow,
51
- virtualized,
52
49
  bordered,
53
50
  rowSize,
54
- toggleRowExpanded,
55
51
  primaryRowActions,
56
52
  secondaryRowActions,
57
53
  activeRowId,
58
54
  } = useDsTableContext<TData, unknown>();
59
- const isExpanded = expandedRows[row.id];
55
+ const isExpanded = row.getIsExpanded();
60
56
  const isExpandable = typeof expandable === 'function' ? expandable(row.original) : expandable;
61
57
  const isActive = activeRowId === row.id;
62
58
 
@@ -64,29 +60,24 @@ const DsTableRow = <TData,>({ ref, row, virtualRow }: DsTableRowProps<TData>) =>
64
60
  id: row.id,
65
61
  disabled: !reorderable,
66
62
  });
67
- const rowStyle: React.CSSProperties =
68
- virtualRow && virtualized
69
- ? {
70
- transform: `translateY(${String(virtualRow.start)}px)`,
71
- }
72
- : reorderable
73
- ? {
74
- // Convert DND-kit's transform coordinates to CSS transform string
75
- transform: CSS.Transform.toString(transform),
76
- transition,
77
- ...(isDragging
78
- ? {
79
- background: 'var(--action-active-light)',
80
- boxShadow: '0 0 12px 0 rgba(0, 102, 250, 0.60)',
81
- zIndex: 1,
82
- }
83
- : {}),
84
- position: 'relative',
85
- }
86
- : {};
63
+ const rowStyle: React.CSSProperties = reorderable
64
+ ? {
65
+ // Convert DND-kit's transform coordinates to CSS transform string
66
+ transform: CSS.Transform.toString(transform),
67
+ transition,
68
+ ...(isDragging
69
+ ? {
70
+ background: 'var(--action-active-light)',
71
+ boxShadow: '0 0 12px 0 rgba(0, 102, 250, 0.60)',
72
+ zIndex: 1,
73
+ }
74
+ : {}),
75
+ position: 'relative',
76
+ }
77
+ : {};
87
78
 
88
79
  return (
89
- <React.Fragment key={row.id}>
80
+ <>
90
81
  <TableRow
91
82
  ref={mergeRefs(reorderable ? setNodeRef : null, ref)}
92
83
  data-state={isActive ? 'active' : row.getIsSelected() ? 'selected' : undefined}
@@ -97,7 +88,6 @@ const DsTableRow = <TData,>({ ref, row, virtualRow }: DsTableRowProps<TData>) =>
97
88
  [styles.sizeMedium]: rowSize === 'medium',
98
89
  [styles.sizeLarge]: rowSize === 'large',
99
90
  },
100
- virtualized && styles.virtualizedRow,
101
91
  onRowClick && styles.clickableRow,
102
92
  !bordered && styles.rowNoBorder,
103
93
  isExpanded && styles.expanded,
@@ -106,55 +96,20 @@ const DsTableRow = <TData,>({ ref, row, virtualRow }: DsTableRowProps<TData>) =>
106
96
  onClick={() => onRowClick?.(row.original)}
107
97
  onDoubleClick={() => onRowDoubleClick?.(row.original)}
108
98
  >
109
- {selectable && (
110
- <TableCell className={classnames(styles.tableCell, styles.cellCheckbox)}>
111
- <DsCheckbox
112
- className={stylesShared.checkboxContainer}
113
- checked={row.getIsSelected()}
114
- disabled={!row.getCanSelect()}
115
- onClick={(e) => {
116
- e.stopPropagation();
117
- const toggleHandler = row.getToggleSelectedHandler();
118
- toggleHandler(e);
119
- }}
120
- onDoubleClick={(e: React.MouseEvent) => {
121
- e.stopPropagation();
122
- }}
123
- />
124
- </TableCell>
125
- )}
99
+ {selectable && <DsTableRowSelectableCell row={row} className={styles.selectableCell} />}
126
100
  {expandable && (
127
- <TableCell className={classnames(styles.tableCell, styles.cellButton)}>
128
- {isExpandable && (
129
- <DsButton
130
- variant={virtualized ? 'ghost' : 'borderless'}
131
- size="small"
132
- onClick={(e: React.MouseEvent) => {
133
- e.stopPropagation();
134
- toggleRowExpanded(row.id);
135
- }}
136
- onDoubleClick={(e: React.MouseEvent) => {
137
- e.stopPropagation();
138
- }}
139
- className={styles.expandToggleButton}
140
- >
141
- <DsIcon
142
- icon={virtualized ? (isExpanded ? 'arrow_drop_down' : 'arrow_right') : 'chevron_right'}
143
- className={classnames(
144
- stylesShared.pageButtonIcon,
145
- !virtualized && isExpanded && 'rotate-90',
146
- )}
147
- />
148
- </DsButton>
149
- )}
150
- </TableCell>
101
+ <DsTableRowExpandableCell
102
+ row={row}
103
+ className={styles.expandableCell}
104
+ buttonClassName={styles.expandToggleButton}
105
+ />
151
106
  )}
152
107
  {reorderable && (
153
108
  <DsRowDragHandle isDragging={isDragging} attributes={attributes} listeners={listeners} />
154
109
  )}
155
110
  {row.getVisibleCells().map((cell, idx) => {
156
111
  const isLastColumn = idx === row.getVisibleCells().length - 1;
157
- const cellStyle = getColumnStyle(cell.column.getSize(), virtualized, isLastColumn);
112
+ const cellStyle = getColumnSizeStyle(cell.column.getSize());
158
113
 
159
114
  return (
160
115
  <TableCell key={cell.id} className={styles.tableCell} style={cellStyle}>
@@ -172,17 +127,9 @@ const DsTableRow = <TData,>({ ref, row, virtualRow }: DsTableRowProps<TData>) =>
172
127
  );
173
128
  })}
174
129
  </TableRow>
130
+
175
131
  {isExpanded && renderExpandedRow && (
176
- <TableRow
177
- style={
178
- virtualRow && virtualized
179
- ? {
180
- transform: `translateY(${String(virtualRow.start + virtualRow.size)}px)`,
181
- }
182
- : undefined
183
- }
184
- className={styles.expandedRow}
185
- >
132
+ <TableRow className={styles.expandedRow}>
186
133
  <TableCell
187
134
  colSpan={
188
135
  row.getVisibleCells().length +
@@ -196,7 +143,7 @@ const DsTableRow = <TData,>({ ref, row, virtualRow }: DsTableRowProps<TData>) =>
196
143
  </TableCell>
197
144
  </TableRow>
198
145
  )}
199
- </React.Fragment>
146
+ </>
200
147
  );
201
148
  };
202
149
 
@@ -1,6 +1,5 @@
1
1
  import type { Ref } from 'react';
2
2
  import type { Row } from '@tanstack/react-table';
3
- import type { VirtualItem } from '@tanstack/react-virtual';
4
3
 
5
4
  /**
6
5
  * Props for the table row component
@@ -14,9 +13,4 @@ export interface DsTableRowProps<TData> {
14
13
  * The row data from the table
15
14
  */
16
15
  row: Row<TData>;
17
-
18
- /**
19
- * Virtual row data for virtualized tables
20
- */
21
- virtualRow?: VirtualItem;
22
16
  }
@@ -0,0 +1,10 @@
1
+ @use '../../styles/variables' as vars;
2
+
3
+ .cell {
4
+ width: vars.$expand-column-width;
5
+ padding: 0;
6
+ }
7
+
8
+ .button {
9
+ margin: auto;
10
+ }
@@ -0,0 +1,45 @@
1
+ import type React from 'react';
2
+ import classnames from 'classnames';
3
+ import { TableCell } from '../core-table';
4
+ import { DsButton } from '../../../ds-button';
5
+ import { DsIcon } from '../../../ds-icon';
6
+ import stylesShared from '../../styles/shared/ds-table-shared.module.scss';
7
+ import { useDsTableContext } from '../../context/ds-table-context';
8
+ import type { DsTableRowExpandableCellProps } from './ds-table-row-expandable-cell.types';
9
+ import styles from './ds-table-row-expandable-cell.module.scss';
10
+
11
+ export const DsTableRowExpandableCell = <TData,>({
12
+ row,
13
+ className,
14
+ buttonClassName,
15
+ }: DsTableRowExpandableCellProps<TData>) => {
16
+ const { expandable } = useDsTableContext<TData, unknown>();
17
+ const isExpanded = row.getIsExpanded();
18
+ const isExpandable = typeof expandable === 'function' ? expandable(row.original) : expandable;
19
+
20
+ return (
21
+ <TableCell className={classnames(styles.cell, className)}>
22
+ {isExpandable && (
23
+ <DsButton
24
+ design="v1.2"
25
+ buttonType="tertiary"
26
+ size="small"
27
+ className={classnames(styles.button, buttonClassName)}
28
+ onClick={(e: React.MouseEvent) => {
29
+ e.stopPropagation();
30
+ row.toggleExpanded();
31
+ }}
32
+ onDoubleClick={(e: React.MouseEvent) => {
33
+ e.stopPropagation();
34
+ }}
35
+ >
36
+ <DsIcon
37
+ icon="chevron_right"
38
+ size="small"
39
+ className={classnames(stylesShared.pageButtonIcon, isExpanded && 'rotate-90')}
40
+ />
41
+ </DsButton>
42
+ )}
43
+ </TableCell>
44
+ );
45
+ };
@@ -0,0 +1,7 @@
1
+ import type { Row } from '@tanstack/react-table';
2
+
3
+ export interface DsTableRowExpandableCellProps<TData> {
4
+ row: Row<TData>;
5
+ className?: string;
6
+ buttonClassName?: string;
7
+ }
@@ -0,0 +1,2 @@
1
+ export * from './ds-table-row-expandable-cell';
2
+ export * from './ds-table-row-expandable-cell.types';
@@ -0,0 +1,6 @@
1
+ @use '../../styles/variables' as vars;
2
+
3
+ .cell {
4
+ width: vars.$select-column-width;
5
+ padding: 0;
6
+ }
@@ -0,0 +1,30 @@
1
+ import type React from 'react';
2
+ import { TableCell } from '../core-table';
3
+ import { DsCheckbox } from '../../../ds-checkbox';
4
+ import stylesShared from '../../styles/shared/ds-table-shared.module.scss';
5
+ import type { DsTableRowSelectableCellProps } from './ds-table-row-selectable-cell.types';
6
+ import classnames from 'classnames';
7
+ import styles from './ds-table-row-selectable-cell.module.scss';
8
+
9
+ export const DsTableRowSelectableCell = <TData,>({
10
+ row,
11
+ className,
12
+ }: DsTableRowSelectableCellProps<TData>) => {
13
+ return (
14
+ <TableCell className={classnames(styles.cell, className)}>
15
+ <DsCheckbox
16
+ className={stylesShared.checkboxContainer}
17
+ checked={row.getIsSelected()}
18
+ disabled={!row.getCanSelect()}
19
+ onClick={(e) => {
20
+ e.stopPropagation();
21
+ const toggleHandler = row.getToggleSelectedHandler();
22
+ toggleHandler(e);
23
+ }}
24
+ onDoubleClick={(e: React.MouseEvent) => {
25
+ e.stopPropagation();
26
+ }}
27
+ />
28
+ </TableCell>
29
+ );
30
+ };
@@ -0,0 +1,6 @@
1
+ import type { Row } from '@tanstack/react-table';
2
+
3
+ export interface DsTableRowSelectableCellProps<TData> {
4
+ row: Row<TData>;
5
+ className?: string;
6
+ }
@@ -0,0 +1,2 @@
1
+ export * from './ds-table-row-selectable-cell';
2
+ export * from './ds-table-row-selectable-cell.types';