@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.
- package/CHANGELOG.md +27 -0
- package/dist/index.cjs +12394 -8354
- package/dist/index.d.cts +806 -118
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +806 -118
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12376 -8357
- package/dist/index.js.map +1 -1
- package/dist/index.min.css +1 -1
- package/package.json +25 -23
- package/src/components/ds-autocomplete/ds-autocomplete.module.scss +2 -1
- package/src/components/ds-autocomplete/ds-autocomplete.tsx +47 -40
- package/src/components/ds-autocomplete/ds-autocomplete.types.tsx +37 -14
- package/src/components/ds-button/versions/ds-button-new/ds-button-new.module.scss +3 -7
- package/src/components/ds-comment-bubble/components/ds-comment-thread/ds-comment-thread.module.scss +62 -0
- package/src/components/ds-comment-bubble/components/ds-comment-thread/ds-comment-thread.tsx +83 -0
- package/src/components/ds-comment-bubble/components/ds-comment-thread/ds-comment-thread.types.ts +12 -0
- package/src/components/ds-comment-bubble/components/ds-comment-thread/index.ts +2 -0
- package/src/components/ds-comment-bubble/components/ds-thread-item/ds-thread-item.module.scss +149 -0
- package/src/components/ds-comment-bubble/components/ds-thread-item/ds-thread-item.tsx +147 -0
- package/src/components/ds-comment-bubble/components/ds-thread-item/ds-thread-item.types.ts +15 -0
- package/src/components/ds-comment-bubble/components/ds-thread-item/index.ts +2 -0
- package/src/components/ds-comment-bubble/ds-comment-bubble.module.scss +298 -0
- package/src/components/ds-comment-bubble/ds-comment-bubble.tsx +241 -0
- package/src/components/ds-comment-bubble/ds-comment-bubble.types.ts +27 -0
- package/src/components/ds-comment-bubble/hooks/index.ts +3 -0
- package/src/components/ds-comment-bubble/hooks/use-auto-resize.ts +17 -0
- package/src/components/ds-comment-bubble/hooks/use-click-outside.ts +22 -0
- package/src/components/ds-comment-bubble/hooks/use-scroll-overflow.ts +27 -0
- package/src/components/ds-comment-bubble/index.ts +6 -0
- package/src/components/ds-comment-card/ds-comment-card.module.scss +162 -0
- package/src/components/ds-comment-card/ds-comment-card.tsx +171 -0
- package/src/components/ds-comment-card/ds-comment-card.types.ts +45 -0
- package/src/components/ds-comment-card/index.ts +2 -0
- package/src/components/ds-comment-indicator/ds-comment-indicator.module.scss +65 -0
- package/src/components/ds-comment-indicator/ds-comment-indicator.tsx +48 -0
- package/src/components/ds-comment-indicator/ds-comment-indicator.types.ts +13 -0
- package/src/components/ds-comment-indicator/index.ts +2 -0
- package/src/components/ds-comments-drawer/comments-filters.test.ts +483 -0
- package/src/components/ds-comments-drawer/comments-filters.ts +134 -0
- package/src/components/ds-comments-drawer/comments-filters.types.ts +14 -0
- package/src/components/ds-comments-drawer/components/comments-filter-modal/comments-filter-modal.module.scss +92 -0
- package/src/components/ds-comments-drawer/components/comments-filter-modal/comments-filter-modal.tsx +219 -0
- package/src/components/ds-comments-drawer/components/comments-filter-modal/comments-filter-modal.types.ts +12 -0
- package/src/components/ds-comments-drawer/components/comments-filter-modal/index.ts +2 -0
- package/src/components/ds-comments-drawer/ds-comments-drawer.module.scss +67 -0
- package/src/components/ds-comments-drawer/ds-comments-drawer.tsx +215 -0
- package/src/components/ds-comments-drawer/ds-comments-drawer.types.ts +23 -0
- package/src/components/ds-comments-drawer/index.ts +3 -0
- package/src/components/ds-dropdown-menu/ds-dropdown-menu.tsx +2 -0
- package/src/components/ds-expandable-text-input/ds-expandable-text-input.tsx +8 -4
- package/src/components/ds-file-upload/types/accept-types.ts +0 -1
- package/src/components/ds-filter-status-icon/ds-filter-status-icon.module.scss +19 -0
- package/src/components/ds-filter-status-icon/ds-filter-status-icon.tsx +35 -0
- package/src/components/ds-filter-status-icon/ds-filter-status-icon.types.ts +31 -0
- package/src/components/ds-filter-status-icon/index.ts +3 -0
- package/src/components/ds-icon/custom-icons/index.ts +10 -0
- package/src/components/ds-icon/custom-icons/special-failed.tsx +16 -0
- package/src/components/ds-icon/custom-icons/special-paused.tsx +16 -0
- package/src/components/ds-icon/custom-icons/special-running.tsx +16 -0
- package/src/components/ds-icon/custom-icons/special-warning.tsx +16 -0
- package/src/components/ds-panel/ds-panel.module.scss +3 -3
- package/src/components/ds-progress-arc/ds-progress-arc.module.scss +57 -0
- package/src/components/ds-progress-arc/ds-progress-arc.tsx +111 -0
- package/src/components/ds-progress-arc/ds-progress-arc.types.ts +34 -0
- package/src/components/ds-progress-arc/index.ts +3 -0
- package/src/components/ds-progress-arc/utils.test.ts +79 -0
- package/src/components/ds-progress-arc/utils.ts +61 -0
- package/src/components/ds-progress-donut/ds-progress-donut.module.scss +67 -0
- package/src/components/ds-progress-donut/ds-progress-donut.tsx +83 -0
- package/src/components/ds-progress-donut/ds-progress-donut.types.ts +38 -0
- package/src/components/ds-progress-donut/index.ts +2 -0
- package/src/components/ds-progress-donut/utils.ts +1 -0
- package/src/components/ds-progress-linear/ds-progress-linear.module.scss +100 -0
- package/src/components/ds-progress-linear/ds-progress-linear.tsx +107 -0
- package/src/components/ds-progress-linear/ds-progress-linear.types.ts +72 -0
- package/src/components/ds-progress-linear/index.ts +2 -0
- package/src/components/ds-progress-linear/utils.test.ts +70 -0
- package/src/components/ds-progress-linear/utils.ts +7 -0
- package/src/components/ds-radio-group/ds-radio-group.tsx +2 -0
- package/src/components/ds-select/ds-select.tsx +2 -1
- package/src/components/ds-select/ds-select.types.tsx +7 -0
- package/src/components/ds-stepper/components/ds-step.tsx +1 -1
- package/src/components/ds-stepper/ds-stepper.module.scss +16 -2
- package/src/components/ds-stepper/ds-stepper.tsx +3 -1
- package/src/components/ds-table/components/ds-table-body-virtualized/ds-table-body-virtualized.module.scss +9 -0
- package/src/components/ds-table/components/ds-table-body-virtualized/ds-table-body-virtualized.tsx +137 -0
- package/src/components/ds-table/components/ds-table-body-virtualized/ds-table-body-virtualized.types.ts +22 -0
- package/src/components/ds-table/components/ds-table-body-virtualized/index.ts +2 -0
- package/src/components/ds-table/components/ds-table-cell/ds-table-cell.module.scss +3 -1
- package/src/components/ds-table/components/ds-table-header/ds-table-header.module.scss +7 -10
- package/src/components/ds-table/components/ds-table-header/ds-table-header.tsx +3 -4
- package/src/components/ds-table/components/ds-table-row/ds-table-row.module.scss +13 -53
- package/src/components/ds-table/components/ds-table-row/ds-table-row.tsx +32 -85
- package/src/components/ds-table/components/ds-table-row/ds-table-row.types.ts +0 -6
- package/src/components/ds-table/components/ds-table-row-expandable-cell/ds-table-row-expandable-cell.module.scss +10 -0
- package/src/components/ds-table/components/ds-table-row-expandable-cell/ds-table-row-expandable-cell.tsx +45 -0
- package/src/components/ds-table/components/ds-table-row-expandable-cell/ds-table-row-expandable-cell.types.ts +7 -0
- package/src/components/ds-table/components/ds-table-row-expandable-cell/index.ts +2 -0
- package/src/components/ds-table/components/ds-table-row-selectable-cell/ds-table-row-selectable-cell.module.scss +6 -0
- package/src/components/ds-table/components/ds-table-row-selectable-cell/ds-table-row-selectable-cell.tsx +30 -0
- package/src/components/ds-table/components/ds-table-row-selectable-cell/ds-table-row-selectable-cell.types.ts +6 -0
- package/src/components/ds-table/components/ds-table-row-selectable-cell/index.ts +2 -0
- package/src/components/ds-table/components/ds-table-row-virtualized/ds-table-row-virtualized.module.scss +80 -0
- package/src/components/ds-table/components/ds-table-row-virtualized/ds-table-row-virtualized.tsx +95 -0
- package/src/components/ds-table/components/ds-table-row-virtualized/ds-table-row-virtualized.types.ts +11 -0
- package/src/components/ds-table/components/ds-table-row-virtualized/index.ts +2 -0
- package/src/components/ds-table/context/ds-table-context.tsx +0 -9
- package/src/components/ds-table/ds-table.module.scss +4 -17
- package/src/components/ds-table/ds-table.tsx +44 -77
- package/src/components/ds-table/ds-table.types.ts +57 -12
- package/src/components/ds-table/index.ts +1 -0
- package/src/components/ds-table/styles/_mixins.scss +15 -0
- package/src/components/ds-table/styles/_variables.scss +2 -2
- package/src/components/ds-table/utils/{column-styling.ts → column-size.ts} +4 -14
- package/src/components/ds-table/utils/constants.ts +4 -0
- package/src/components/ds-tag/index.tsx +1 -0
- package/src/components/ds-tag-filter/ds-tag-filter.module.scss +13 -15
- package/src/components/ds-tag-filter/ds-tag-filter.tsx +38 -72
- package/src/components/ds-tag-filter/ds-tag-filter.types.ts +2 -3
- package/src/components/ds-tag-filter/hooks/use-tag-overflow-calculation.ts +12 -62
- package/src/components/ds-tag-filter/utils.test.ts +2 -108
- package/src/components/ds-tag-filter/utils.ts +2 -12
- package/src/components/ds-tree/ds-tree.module.scss +283 -0
- package/src/components/ds-tree/ds-tree.tsx +172 -0
- package/src/components/ds-tree/ds-tree.types.ts +83 -0
- package/src/components/ds-tree/ds-tree.utils.ts +11 -0
- package/src/components/ds-tree/index.ts +3 -0
- package/src/index.ts +9 -0
- package/src/utils/format-relative-time.test.ts +74 -0
- package/src/utils/format-relative-time.ts +52 -0
- package/src/utils/numbers.test.ts +24 -0
- package/src/utils/numbers.ts +1 -0
- package/src/components/ds-table/utils/create-columns-grid-template.ts +0 -23
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
@use '../../../../styles/typography';
|
|
2
|
+
@use '../../styles/variables' as vars;
|
|
3
|
+
@use '../../styles/mixins' as table-mixins;
|
|
4
|
+
|
|
5
|
+
.row {
|
|
6
|
+
display: flex;
|
|
7
|
+
position: absolute;
|
|
8
|
+
width: 100%;
|
|
9
|
+
|
|
10
|
+
&:hover {
|
|
11
|
+
background-color: var(--color-background-secondary);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
&[data-state='selected'] {
|
|
15
|
+
background-color: var(--color-background-selected-weak);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
&[data-state='active'] {
|
|
19
|
+
background-color: var(--color-background-selected-weak);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
&:not(:last-child):not(.expandedRowContent) {
|
|
23
|
+
> td {
|
|
24
|
+
border-bottom: vars.$border-width solid var(--color-border-secondary);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
&.clickableRow {
|
|
29
|
+
cursor: pointer;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
&.rowNoBorder {
|
|
33
|
+
border-bottom: none;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
&:not(.expandedRowContent) {
|
|
37
|
+
&.expanded {
|
|
38
|
+
@include table-mixins.expanded-row-border('top');
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
&.sizeSmall {
|
|
42
|
+
height: var(--ds-table-row-small);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
&.sizeMedium {
|
|
46
|
+
height: var(--ds-table-row-medium);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
&.sizeLarge {
|
|
50
|
+
height: var(--ds-table-row-large);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.cell,
|
|
56
|
+
.selectableCell,
|
|
57
|
+
.expandableCell {
|
|
58
|
+
display: flex;
|
|
59
|
+
align-items: center;
|
|
60
|
+
@include typography.body-sm-reg;
|
|
61
|
+
color: var(--color-font-main);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.cell {
|
|
65
|
+
padding: 0 var(--spacing-standard);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
.expandedRowContent {
|
|
69
|
+
background-color: var(--color-background-secondary);
|
|
70
|
+
|
|
71
|
+
& > td {
|
|
72
|
+
display: flex;
|
|
73
|
+
flex-direction: column;
|
|
74
|
+
flex: 1;
|
|
75
|
+
padding: var(--spacing-standard);
|
|
76
|
+
background-color: var(--color-background-secondary);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
@include table-mixins.expanded-row-border('bottom');
|
|
80
|
+
}
|
package/src/components/ds-table/components/ds-table-row-virtualized/ds-table-row-virtualized.tsx
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import classnames from 'classnames';
|
|
2
|
+
import styles from './ds-table-row-virtualized.module.scss';
|
|
3
|
+
import { useDsTableContext } from '../../context/ds-table-context';
|
|
4
|
+
import { getColumnSizeStyle } from '../../utils/column-size';
|
|
5
|
+
import { TableCell, TableRow } from '../core-table';
|
|
6
|
+
import { DsTableRowSelectableCell } from '../ds-table-row-selectable-cell';
|
|
7
|
+
import { DsTableRowExpandableCell } from '../ds-table-row-expandable-cell';
|
|
8
|
+
import type { DsTableRowVirtualizedProps } from './ds-table-row-virtualized.types';
|
|
9
|
+
import { DsTableCell } from '../ds-table-cell';
|
|
10
|
+
|
|
11
|
+
export const DsTableRowVirtualized = <TData,>({
|
|
12
|
+
row,
|
|
13
|
+
rowsMapRef,
|
|
14
|
+
rowHeightsMapRef,
|
|
15
|
+
rowVirtualizer,
|
|
16
|
+
virtualRow,
|
|
17
|
+
isExpandedRowContent,
|
|
18
|
+
}: DsTableRowVirtualizedProps<TData>) => {
|
|
19
|
+
const {
|
|
20
|
+
selectable,
|
|
21
|
+
expandable,
|
|
22
|
+
bordered,
|
|
23
|
+
rowSize,
|
|
24
|
+
activeRowId,
|
|
25
|
+
primaryRowActions,
|
|
26
|
+
secondaryRowActions,
|
|
27
|
+
renderExpandedRow,
|
|
28
|
+
onRowClick,
|
|
29
|
+
onRowDoubleClick,
|
|
30
|
+
} = useDsTableContext<TData, unknown>();
|
|
31
|
+
const isExpanded = row.getIsExpanded();
|
|
32
|
+
const isActive = activeRowId === row.id;
|
|
33
|
+
|
|
34
|
+
return (
|
|
35
|
+
<TableRow
|
|
36
|
+
data-index={virtualRow.index}
|
|
37
|
+
ref={(row) => {
|
|
38
|
+
const key = String(virtualRow.key);
|
|
39
|
+
|
|
40
|
+
if (row) {
|
|
41
|
+
rowVirtualizer.measureElement(row); // measure dynamic row height
|
|
42
|
+
rowsMapRef.current.set(key, row); // store ref for virtualizer to apply scrolling transforms
|
|
43
|
+
|
|
44
|
+
const height = row.getBoundingClientRect().height;
|
|
45
|
+
rowHeightsMapRef.current.set(key, height); // store height for virtualizer to estimate size
|
|
46
|
+
} else {
|
|
47
|
+
rowsMapRef.current.delete(key);
|
|
48
|
+
}
|
|
49
|
+
}}
|
|
50
|
+
data-state={isActive ? 'active' : row.getIsSelected() ? 'selected' : undefined}
|
|
51
|
+
className={classnames(
|
|
52
|
+
styles.row,
|
|
53
|
+
{
|
|
54
|
+
[styles.sizeSmall]: rowSize === 'small',
|
|
55
|
+
[styles.sizeMedium]: rowSize === 'medium',
|
|
56
|
+
[styles.sizeLarge]: rowSize === 'large',
|
|
57
|
+
},
|
|
58
|
+
isExpandedRowContent && styles.expandedRowContent,
|
|
59
|
+
onRowClick && styles.clickableRow,
|
|
60
|
+
!bordered && styles.rowNoBorder,
|
|
61
|
+
isExpanded && styles.expanded,
|
|
62
|
+
)}
|
|
63
|
+
onClick={isExpandedRowContent ? undefined : () => onRowClick?.(row.original)}
|
|
64
|
+
onDoubleClick={isExpandedRowContent ? undefined : () => onRowDoubleClick?.(row.original)}
|
|
65
|
+
>
|
|
66
|
+
{isExpandedRowContent ? (
|
|
67
|
+
<TableCell>{renderExpandedRow?.(row.original)}</TableCell>
|
|
68
|
+
) : (
|
|
69
|
+
<>
|
|
70
|
+
{selectable && <DsTableRowSelectableCell row={row} className={styles.selectableCell} />}
|
|
71
|
+
{expandable && <DsTableRowExpandableCell row={row} className={styles.expandableCell} />}
|
|
72
|
+
{row.getVisibleCells().map((cell, idx) => {
|
|
73
|
+
const isLastColumn = idx === row.getVisibleCells().length - 1;
|
|
74
|
+
const cellStyle = getColumnSizeStyle(cell.column.getSize(), true);
|
|
75
|
+
|
|
76
|
+
return (
|
|
77
|
+
<TableCell key={cell.id} style={cellStyle} className={styles.cell}>
|
|
78
|
+
{isLastColumn ? (
|
|
79
|
+
<DsTableCell
|
|
80
|
+
row={row}
|
|
81
|
+
cell={cell}
|
|
82
|
+
primaryRowActions={primaryRowActions}
|
|
83
|
+
secondaryRowActions={secondaryRowActions}
|
|
84
|
+
/>
|
|
85
|
+
) : (
|
|
86
|
+
<DsTableCell row={row} cell={cell} />
|
|
87
|
+
)}
|
|
88
|
+
</TableCell>
|
|
89
|
+
);
|
|
90
|
+
})}
|
|
91
|
+
</>
|
|
92
|
+
)}
|
|
93
|
+
</TableRow>
|
|
94
|
+
);
|
|
95
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type Row } from '@tanstack/react-table';
|
|
2
|
+
import { type VirtualItem, type Virtualizer } from '@tanstack/react-virtual';
|
|
3
|
+
|
|
4
|
+
export interface DsTableRowVirtualizedProps<TData> {
|
|
5
|
+
row: Row<TData>;
|
|
6
|
+
rowsMapRef: React.RefObject<Map<string, HTMLTableRowElement>>;
|
|
7
|
+
rowHeightsMapRef: React.RefObject<Map<string, number>>;
|
|
8
|
+
rowVirtualizer: Virtualizer<HTMLDivElement, HTMLTableRowElement>;
|
|
9
|
+
virtualRow: VirtualItem;
|
|
10
|
+
isExpandedRowContent?: boolean;
|
|
11
|
+
}
|
|
@@ -2,15 +2,6 @@ import { createContext, useContext } from 'react';
|
|
|
2
2
|
import type { DsDataTableProps, DsTableRowSize } from '../ds-table.types';
|
|
3
3
|
|
|
4
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
5
|
/**
|
|
15
6
|
* Whether the table is virtualized
|
|
16
7
|
* @default false
|
|
@@ -10,12 +10,6 @@
|
|
|
10
10
|
background: var(--color-background);
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
.virtualizedContainer {
|
|
14
|
-
position: relative;
|
|
15
|
-
height: vars.$virtualized-height;
|
|
16
|
-
overflow: auto;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
13
|
.dataTableContainer {
|
|
20
14
|
max-height: 100%;
|
|
21
15
|
overflow: auto;
|
|
@@ -42,19 +36,12 @@
|
|
|
42
36
|
text-align: center;
|
|
43
37
|
}
|
|
44
38
|
|
|
45
|
-
.emptyStateVirtualized {
|
|
46
|
-
position: absolute;
|
|
47
|
-
inset: 0;
|
|
48
|
-
top: var(--ds-table-header-height);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
39
|
.virtualized {
|
|
52
40
|
display: grid;
|
|
53
|
-
grid-template-columns: var(--ds-table-columns-template);
|
|
54
41
|
}
|
|
55
42
|
|
|
56
|
-
.
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
43
|
+
.virtualizedContainer {
|
|
44
|
+
position: relative;
|
|
45
|
+
height: vars.$virtualized-height;
|
|
46
|
+
overflow: auto;
|
|
60
47
|
}
|
|
@@ -10,7 +10,6 @@ import {
|
|
|
10
10
|
useReactTable,
|
|
11
11
|
type VisibilityState,
|
|
12
12
|
} from '@tanstack/react-table';
|
|
13
|
-
import { useVirtualizer, type VirtualItem } from '@tanstack/react-virtual';
|
|
14
13
|
import classnames from 'classnames';
|
|
15
14
|
import { Table, TableBody, TableCell, TableRow } from './components/core-table';
|
|
16
15
|
import { DsTableBulkActions } from './components/ds-table-bulk-actions';
|
|
@@ -20,7 +19,8 @@ import type { DsDataTableProps, DsTableRowSize } from './ds-table.types';
|
|
|
20
19
|
import { DsTableRow } from './components/ds-table-row';
|
|
21
20
|
import { useDragAndDrop } from './hooks/use-drag-and-drop';
|
|
22
21
|
import { type DsTableContextType, DsTableContext } from './context/ds-table-context';
|
|
23
|
-
import {
|
|
22
|
+
import { DsTableBodyVirtualized } from './components/ds-table-body-virtualized';
|
|
23
|
+
import { EMPTY_TABLE_STATE_TEXT } from './utils/constants';
|
|
24
24
|
|
|
25
25
|
// Row size to pixel height mapping (matches CSS variables)
|
|
26
26
|
const ROW_SIZE_HEIGHT_MAP: Record<DsTableRowSize, number> = {
|
|
@@ -69,7 +69,6 @@ const DsTable = <TData extends { id: string }, TValue>({
|
|
|
69
69
|
const [internalColumnFilters, setInternalColumnFilters] = React.useState<ColumnFiltersState>([]);
|
|
70
70
|
const [internalColumnVisibility, setInternalColumnVisibility] = React.useState<VisibilityState>({});
|
|
71
71
|
const [rowSelection, setRowSelection] = React.useState<RowSelectionState>({});
|
|
72
|
-
const [expandedRows, setExpandedRows] = React.useState<Record<string, boolean>>({});
|
|
73
72
|
|
|
74
73
|
const { DragWrapper, SortableWrapper } = useDragAndDrop<TData>({
|
|
75
74
|
isDragEnabled: reorderable && !virtualized,
|
|
@@ -129,9 +128,9 @@ const DsTable = <TData extends { id: string }, TValue>({
|
|
|
129
128
|
getCoreRowModel: getCoreRowModel(),
|
|
130
129
|
onSortingChange: handleSortingChange,
|
|
131
130
|
getSortedRowModel: getSortedRowModel(),
|
|
132
|
-
onColumnFiltersChange: handleColumnFiltersChange,
|
|
131
|
+
onColumnFiltersChange: handleColumnFiltersChange, // TODO: looks like this is not used, since filters are handled from the outside
|
|
133
132
|
getFilteredRowModel: getFilteredRowModel(),
|
|
134
|
-
onColumnVisibilityChange: handleColumnVisibilityChange,
|
|
133
|
+
onColumnVisibilityChange: handleColumnVisibilityChange, // TODO: looks like this is not used, since visibility is handled from the outside
|
|
135
134
|
onRowSelectionChange: handleRowSelectionChange,
|
|
136
135
|
getRowId: (row) => row.id,
|
|
137
136
|
state: {
|
|
@@ -166,51 +165,39 @@ const DsTable = <TData extends { id: string }, TValue>({
|
|
|
166
165
|
getSelectedRows: () => {
|
|
167
166
|
return table.getFilteredSelectedRowModel().rows.map((r) => r.original);
|
|
168
167
|
},
|
|
168
|
+
expandRow: (rowId: string) => {
|
|
169
|
+
table.getRow(rowId).toggleExpanded(true);
|
|
170
|
+
},
|
|
171
|
+
collapseRow: (rowId: string) => {
|
|
172
|
+
table.getRow(rowId).toggleExpanded(false);
|
|
173
|
+
},
|
|
174
|
+
expandAllRows: () => {
|
|
175
|
+
table.toggleAllRowsExpanded(true);
|
|
176
|
+
},
|
|
177
|
+
collapseAllRows: () => {
|
|
178
|
+
table.toggleAllRowsExpanded(false);
|
|
179
|
+
},
|
|
180
|
+
expandRows: (rowIds: string[]) => {
|
|
181
|
+
const expansion: Record<string, boolean> = {};
|
|
182
|
+
rowIds.forEach((id) => (expansion[id] = true));
|
|
183
|
+
table.setExpanded(expansion);
|
|
184
|
+
},
|
|
169
185
|
}),
|
|
170
186
|
[table],
|
|
171
187
|
);
|
|
172
188
|
|
|
173
189
|
const { rows, rowsById } = table.getRowModel();
|
|
174
190
|
|
|
175
|
-
const
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
const viewportHeight = instance.scrollElement?.clientHeight;
|
|
186
|
-
|
|
187
|
-
if (viewportHeight) {
|
|
188
|
-
onScroll({ scrollOffset, totalContentHeight, viewportHeight });
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
},
|
|
192
|
-
});
|
|
193
|
-
|
|
194
|
-
const toggleRowExpanded = (rowId: string) => {
|
|
195
|
-
setExpandedRows((prev) => ({
|
|
196
|
-
...prev,
|
|
197
|
-
[rowId]: !prev[rowId],
|
|
198
|
-
}));
|
|
199
|
-
};
|
|
200
|
-
|
|
201
|
-
const renderEmptyState = () =>
|
|
202
|
-
virtualized ? (
|
|
203
|
-
<div className={styles.emptyStateVirtualized}>{emptyState || 'No results.'}</div>
|
|
204
|
-
) : (
|
|
205
|
-
<TableRow>
|
|
206
|
-
<TableCell
|
|
207
|
-
colSpan={columns.length + (expandable ? 1 : 0) + (selectable ? 1 : 0)}
|
|
208
|
-
className={styles.emptyState}
|
|
209
|
-
>
|
|
210
|
-
{emptyState || 'No results.'}
|
|
211
|
-
</TableCell>
|
|
212
|
-
</TableRow>
|
|
213
|
-
);
|
|
191
|
+
const renderEmptyState = () => (
|
|
192
|
+
<TableRow>
|
|
193
|
+
<TableCell
|
|
194
|
+
colSpan={columns.length + (expandable ? 1 : 0) + (selectable ? 1 : 0)}
|
|
195
|
+
className={styles.emptyState}
|
|
196
|
+
>
|
|
197
|
+
{emptyState || EMPTY_TABLE_STATE_TEXT}
|
|
198
|
+
</TableCell>
|
|
199
|
+
</TableRow>
|
|
200
|
+
);
|
|
214
201
|
|
|
215
202
|
const selectedRows = Object.entries(rowSelection)
|
|
216
203
|
.filter(([, selected]) => selected)
|
|
@@ -232,8 +219,6 @@ const DsTable = <TData extends { id: string }, TValue>({
|
|
|
232
219
|
secondaryRowActions,
|
|
233
220
|
renderExpandedRow,
|
|
234
221
|
virtualized,
|
|
235
|
-
expandedRows,
|
|
236
|
-
toggleRowExpanded,
|
|
237
222
|
activeRowId,
|
|
238
223
|
};
|
|
239
224
|
|
|
@@ -250,16 +235,6 @@ const DsTable = <TData extends { id: string }, TValue>({
|
|
|
250
235
|
>
|
|
251
236
|
<DragWrapper>
|
|
252
237
|
<Table
|
|
253
|
-
style={
|
|
254
|
-
virtualized
|
|
255
|
-
? ({
|
|
256
|
-
'--ds-table-columns-template': createColumnsGridTemplate({
|
|
257
|
-
columns,
|
|
258
|
-
selectable: !!selectable,
|
|
259
|
-
}),
|
|
260
|
-
} as React.CSSProperties)
|
|
261
|
-
: undefined
|
|
262
|
-
}
|
|
263
238
|
className={classnames(
|
|
264
239
|
fullWidth && styles.fullWidth,
|
|
265
240
|
!bordered && styles.tableNoBorder,
|
|
@@ -267,32 +242,24 @@ const DsTable = <TData extends { id: string }, TValue>({
|
|
|
267
242
|
)}
|
|
268
243
|
>
|
|
269
244
|
<DsTableHeader table={table} />
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
return <DsTableRow key={row.id} row={row} virtualRow={virtualRow} />;
|
|
284
|
-
})
|
|
285
|
-
) : (
|
|
286
|
-
renderEmptyState()
|
|
287
|
-
)
|
|
288
|
-
) : (
|
|
245
|
+
{virtualized ? (
|
|
246
|
+
<DsTableBodyVirtualized
|
|
247
|
+
table={table}
|
|
248
|
+
tableContainerRef={tableContainerRef}
|
|
249
|
+
emptyState={emptyState}
|
|
250
|
+
estimateSize={virtualizedOptions?.estimateSize || ROW_SIZE_HEIGHT_MAP[rowSize]}
|
|
251
|
+
overscan={virtualizedOptions?.overscan}
|
|
252
|
+
onScroll={onScroll}
|
|
253
|
+
/>
|
|
254
|
+
) : (
|
|
255
|
+
<TableBody>
|
|
289
256
|
<SortableWrapper>
|
|
290
257
|
{rows.length
|
|
291
258
|
? rows.map((row) => <DsTableRow key={row.id} row={row} />)
|
|
292
259
|
: renderEmptyState()}
|
|
293
260
|
</SortableWrapper>
|
|
294
|
-
|
|
295
|
-
|
|
261
|
+
</TableBody>
|
|
262
|
+
)}
|
|
296
263
|
</Table>
|
|
297
264
|
</DragWrapper>
|
|
298
265
|
</div>
|
|
@@ -8,24 +8,13 @@ import type {
|
|
|
8
8
|
} from '@tanstack/react-table';
|
|
9
9
|
import type { IconType } from '../ds-icon';
|
|
10
10
|
import type { RowAction, SecondaryRowAction } from './components/ds-table-cell';
|
|
11
|
+
import type { ScrollParams } from './components/ds-table-body-virtualized';
|
|
11
12
|
|
|
12
13
|
/**
|
|
13
14
|
* Row size variants based on Figma design specifications
|
|
14
15
|
*/
|
|
15
16
|
export type DsTableRowSize = 'small' | 'medium' | 'large';
|
|
16
17
|
|
|
17
|
-
/**
|
|
18
|
-
* Parameters passed to the onScroll callback in virtualized tables.
|
|
19
|
-
*/
|
|
20
|
-
export interface ScrollParams {
|
|
21
|
-
/** The current vertical scroll position from the top of the scrollable content (in pixels) */
|
|
22
|
-
scrollOffset: number;
|
|
23
|
-
/** The total height of all content in the virtualized table (in pixels) */
|
|
24
|
-
totalContentHeight: number;
|
|
25
|
-
/** The visible height of the table container (in pixels) */
|
|
26
|
-
viewportHeight: number;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
18
|
/**
|
|
30
19
|
* API for programmatically controlling a DsTable component.
|
|
31
20
|
* This interface provides methods to interact with the table's selection, sorting, filtering, and pagination features.
|
|
@@ -117,6 +106,62 @@ export interface DsTableApi<TData> {
|
|
|
117
106
|
* ```
|
|
118
107
|
*/
|
|
119
108
|
getSelectedRows: () => TData[];
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Expands a single row by its ID.
|
|
112
|
+
*
|
|
113
|
+
* @param rowId - The unique identifier of the row to expand
|
|
114
|
+
*
|
|
115
|
+
* @example
|
|
116
|
+
* ```tsx
|
|
117
|
+
* tableRef.current?.expandRow('user-123');
|
|
118
|
+
* ```
|
|
119
|
+
*/
|
|
120
|
+
expandRow: (rowId: string) => void;
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Collapses a single row by its ID.
|
|
124
|
+
*
|
|
125
|
+
* @param rowId - The unique identifier of the row to collapse
|
|
126
|
+
*
|
|
127
|
+
* @example
|
|
128
|
+
* ```tsx
|
|
129
|
+
* tableRef.current?.collapseRow('user-123');
|
|
130
|
+
* ```
|
|
131
|
+
*/
|
|
132
|
+
collapseRow: (rowId: string) => void;
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Expands all rows in the table.
|
|
136
|
+
*
|
|
137
|
+
* @example
|
|
138
|
+
* ```tsx
|
|
139
|
+
* tableRef.current?.expandAllRows();
|
|
140
|
+
* ```
|
|
141
|
+
*/
|
|
142
|
+
expandAllRows: () => void;
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Collapses all rows in the table.
|
|
146
|
+
*
|
|
147
|
+
* @example
|
|
148
|
+
* ```tsx
|
|
149
|
+
* tableRef.current?.collapseAllRows();
|
|
150
|
+
* ```
|
|
151
|
+
*/
|
|
152
|
+
collapseAllRows: () => void;
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Expands multiple rows by their IDs.
|
|
156
|
+
*
|
|
157
|
+
* @param rowIds - Array of unique identifiers for the rows to expand
|
|
158
|
+
*
|
|
159
|
+
* @example
|
|
160
|
+
* ```tsx
|
|
161
|
+
* tableRef.current?.expandRows(['user-1', 'user-2', 'user-3']);
|
|
162
|
+
* ```
|
|
163
|
+
*/
|
|
164
|
+
expandRows: (rowIds: string[]) => void;
|
|
120
165
|
}
|
|
121
166
|
|
|
122
167
|
/**
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
@mixin expanded-row-border($side) {
|
|
2
|
+
$border: 1px solid var(--color-border-action-primary);
|
|
3
|
+
|
|
4
|
+
&:not(.expandedRow + &) > td {
|
|
5
|
+
border-#{$side}: $border;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
& > td:first-child {
|
|
9
|
+
border-inline-start: $border;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
& > td:last-child {
|
|
13
|
+
border-inline-end: $border;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
$border-radius: 4px;
|
|
2
2
|
$border-width: 1px;
|
|
3
3
|
$virtualized-height: 600px;
|
|
4
|
-
$expand-column-width:
|
|
5
|
-
$select-column-width:
|
|
4
|
+
$expand-column-width: 36px;
|
|
5
|
+
$select-column-width: 36px;
|
|
6
6
|
$reorder-column-width: 60px;
|
|
7
7
|
$container-margin-vertical: 1rem;
|
|
8
8
|
$filter-input-gap: 0.5rem;
|
|
@@ -6,25 +6,15 @@ import { defaultColumnSizing } from '@tanstack/react-table';
|
|
|
6
6
|
*
|
|
7
7
|
* @param columnSize - The size of the column
|
|
8
8
|
* @param virtualized - Whether the table is virtualized
|
|
9
|
-
* @param isLastColumn - Whether this is the last column in the row
|
|
10
9
|
* @returns Style object or undefined if no custom styling is needed
|
|
11
10
|
*/
|
|
12
|
-
export const
|
|
13
|
-
columnSize: number,
|
|
14
|
-
virtualized?: boolean,
|
|
15
|
-
isLastColumn: boolean = false,
|
|
16
|
-
): CSSProperties | undefined => {
|
|
11
|
+
export const getColumnSizeStyle = (columnSize: number, virtualized?: boolean): CSSProperties | undefined => {
|
|
17
12
|
const hasCustomSize = columnSize !== defaultColumnSizing.size;
|
|
18
|
-
if (
|
|
19
|
-
return
|
|
13
|
+
if (hasCustomSize) {
|
|
14
|
+
return { width: columnSize };
|
|
20
15
|
}
|
|
21
16
|
|
|
22
17
|
if (virtualized) {
|
|
23
|
-
return {
|
|
24
|
-
flexBasis: `${String(columnSize)}px`,
|
|
25
|
-
flexGrow: isLastColumn ? 1 : 0,
|
|
26
|
-
};
|
|
18
|
+
return { flex: 1 };
|
|
27
19
|
}
|
|
28
|
-
|
|
29
|
-
return { width: columnSize };
|
|
30
20
|
};
|
|
@@ -6,7 +6,6 @@
|
|
|
6
6
|
background: var(--color-background-selected-weak);
|
|
7
7
|
border: 1px solid var(--color-outline-weak);
|
|
8
8
|
border-radius: var(--spacing-3xs);
|
|
9
|
-
max-height: 88px; // hardcoded value required in the design
|
|
10
9
|
overflow: hidden;
|
|
11
10
|
|
|
12
11
|
&.expanded {
|
|
@@ -14,7 +13,7 @@
|
|
|
14
13
|
}
|
|
15
14
|
}
|
|
16
15
|
|
|
17
|
-
.
|
|
16
|
+
.header {
|
|
18
17
|
display: flex;
|
|
19
18
|
align-items: center;
|
|
20
19
|
width: 100%;
|
|
@@ -22,7 +21,15 @@
|
|
|
22
21
|
flex-shrink: 0;
|
|
23
22
|
}
|
|
24
23
|
|
|
25
|
-
.
|
|
24
|
+
.headerActions {
|
|
25
|
+
display: flex;
|
|
26
|
+
align-items: center;
|
|
27
|
+
gap: var(--spacing-xs);
|
|
28
|
+
flex-shrink: 0;
|
|
29
|
+
margin-left: auto;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.tagsArea {
|
|
26
33
|
display: flex;
|
|
27
34
|
align-items: center;
|
|
28
35
|
width: 100%;
|
|
@@ -36,35 +43,26 @@
|
|
|
36
43
|
flex-shrink: 0;
|
|
37
44
|
}
|
|
38
45
|
|
|
39
|
-
.expandTag {
|
|
40
|
-
cursor: pointer;
|
|
41
|
-
flex-shrink: 0;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
46
|
.itemCheckbox {
|
|
45
47
|
display: flex;
|
|
46
48
|
align-items: center;
|
|
47
49
|
}
|
|
48
50
|
|
|
49
|
-
.
|
|
51
|
+
.ghostButtonContent {
|
|
52
|
+
// TODO: remove once migrated 1.2 button to the ghost with transparent bg
|
|
50
53
|
background: transparent !important;
|
|
51
54
|
}
|
|
52
55
|
|
|
53
|
-
.
|
|
54
|
-
margin-left: auto;
|
|
56
|
+
.actionButton {
|
|
55
57
|
padding: 0;
|
|
56
58
|
flex-shrink: 0;
|
|
57
59
|
}
|
|
58
60
|
|
|
59
|
-
// Hidden container for measuring element widths
|
|
60
|
-
// Must render all elements to get accurate measurements
|
|
61
61
|
.measurementContainer {
|
|
62
62
|
pointer-events: none;
|
|
63
63
|
display: flex;
|
|
64
64
|
align-items: center;
|
|
65
65
|
gap: var(--spacing-xs);
|
|
66
|
-
|
|
67
|
-
// Ensure it doesn't affect layout
|
|
68
66
|
height: 0;
|
|
69
67
|
overflow: hidden;
|
|
70
68
|
position: absolute;
|