@drivenets/design-system 0.11.1 → 0.12.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 +14 -0
- package/dist/index.cjs +360 -130
- package/dist/index.d.cts +167 -2
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +167 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +357 -131
- package/dist/index.js.map +1 -1
- package/dist/index.min.css +1 -1
- package/package.json +2 -1
- package/src/components/ds-autocomplete/ds-autocomplete.module.scss +1 -1
- package/src/components/ds-dropdown-menu/ds-dropdown-menu.module.scss +5 -0
- package/src/components/ds-key-value-pair/ds-key-value-pair.module.scss +0 -5
- package/src/components/ds-status-badge/ds-status-badge.types.ts +15 -0
- package/src/components/ds-status-badge-v2/ds-status-badge-v2.module.scss +109 -0
- package/src/components/ds-status-badge-v2/ds-status-badge-v2.tsx +77 -0
- package/src/components/ds-status-badge-v2/ds-status-badge-v2.types.ts +79 -0
- package/src/components/ds-status-badge-v2/ds-status-badge-v2.unit.test.ts +25 -0
- package/src/components/ds-status-badge-v2/index.ts +13 -0
- package/src/components/ds-status-badge-v2/phase-config.ts +15 -0
- package/src/components/ds-table/components/ds-table-body-virtualized/ds-table-body-virtualized.tsx +16 -8
- package/src/components/ds-table/components/ds-table-body-virtualized/ds-table-body-virtualized.types.ts +61 -0
- package/src/components/ds-table/components/ds-table-body-virtualized/use-infinite-scroll.ts +54 -0
- package/src/components/ds-table/components/ds-table-header/ds-table-header.module.scss +4 -9
- package/src/components/ds-table/components/ds-table-header/ds-table-header.tsx +12 -26
- package/src/components/ds-table/components/ds-table-header-selectable-cell/ds-table-header-selectable-cell.tsx +22 -0
- package/src/components/ds-table/components/ds-table-header-selectable-cell/ds-table-header-selectable-cell.types.ts +9 -0
- package/src/components/ds-table/components/ds-table-header-selectable-cell/index.ts +2 -0
- package/src/components/ds-table/components/ds-table-row/ds-table-row.module.scss +4 -9
- package/src/components/ds-table/components/ds-table-row/ds-table-row.tsx +20 -15
- package/src/components/ds-table/components/ds-table-row-selectable-cell/ds-table-row-selectable-cell.tsx +9 -18
- package/src/components/ds-table/components/ds-table-row-selectable-cell/ds-table-row-selectable-cell.types.ts +2 -11
- package/src/components/ds-table/components/ds-table-row-virtualized/ds-table-row-virtualized.module.scss +3 -6
- package/src/components/ds-table/components/ds-table-row-virtualized/ds-table-row-virtualized.tsx +2 -6
- package/src/components/ds-table/ds-table.tsx +57 -17
- package/src/components/ds-table/ds-table.types.ts +27 -1
- package/src/components/ds-table/styles/_variables.scss +0 -1
- package/src/components/ds-table/styles/shared/ds-table-shared.module.scss +1 -0
- package/src/components/ds-table/utils/constants.ts +21 -0
- package/src/index.ts +1 -0
- package/src/styles/shared/_dropdown.scss +1 -1
- package/src/components/ds-table/components/ds-table-row-selectable-cell/ds-table-row-selectable-cell.module.scss +0 -6
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { flexRender } from '@tanstack/react-table';
|
|
2
2
|
import classnames from 'classnames';
|
|
3
|
-
import { DsCheckbox } from '../../../ds-checkbox';
|
|
4
3
|
import { DsIcon } from '../../../ds-icon';
|
|
5
4
|
import { TableHead, TableHeader, TableRow } from '../core-table';
|
|
6
5
|
import styles from './ds-table-header.module.scss';
|
|
@@ -8,10 +7,11 @@ import stylesShared from '../../styles/shared/ds-table-shared.module.scss';
|
|
|
8
7
|
import type { DsTableHeaderProps } from './ds-table-header.types';
|
|
9
8
|
import { useDsTableContext } from '../../context/ds-table-context';
|
|
10
9
|
import { getColumnSizeStyle } from '../../utils/column-size';
|
|
10
|
+
import { SELECT_COLUMN_ID } from '../../utils/constants';
|
|
11
|
+
import { DsStack } from '../../../ds-stack';
|
|
11
12
|
|
|
12
13
|
const DsTableHeader = <TData,>({ table }: DsTableHeaderProps<TData>) => {
|
|
13
|
-
const { stickyHeader, bordered,
|
|
14
|
-
useDsTableContext<TData, unknown>();
|
|
14
|
+
const { stickyHeader, bordered, virtualized } = useDsTableContext<TData, unknown>();
|
|
15
15
|
|
|
16
16
|
return (
|
|
17
17
|
<TableHeader
|
|
@@ -26,41 +26,27 @@ const DsTableHeader = <TData,>({ table }: DsTableHeaderProps<TData>) => {
|
|
|
26
26
|
virtualized && styles.headerRowVirtualized,
|
|
27
27
|
)}
|
|
28
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
|
-
onCheckedChange={(checked) => table.toggleAllRowsSelected(!!checked)}
|
|
42
|
-
onClick={(e) => e.stopPropagation()}
|
|
43
|
-
/>
|
|
44
|
-
)}
|
|
45
|
-
</TableHead>
|
|
46
|
-
)}
|
|
47
|
-
{reorderable && (
|
|
48
|
-
<TableHead className={classnames(styles.headerCell, styles.reorderColumn)}>Order</TableHead>
|
|
49
|
-
)}
|
|
50
29
|
{headerGroup.headers.map((header) => {
|
|
51
30
|
const headerStyle = getColumnSizeStyle(header.column.getSize(), virtualized);
|
|
52
31
|
const canSort = header.column.getCanSort();
|
|
32
|
+
const isSelectColumn = header.column.id === SELECT_COLUMN_ID;
|
|
53
33
|
|
|
54
34
|
return (
|
|
55
35
|
<TableHead
|
|
56
36
|
key={header.id}
|
|
57
|
-
className={classnames(
|
|
37
|
+
className={classnames(
|
|
38
|
+
styles.headerCell,
|
|
39
|
+
canSort && styles.sortableHeader,
|
|
40
|
+
isSelectColumn && styles.selectHeaderCell,
|
|
41
|
+
)}
|
|
58
42
|
onClick={header.column.getToggleSortingHandler()}
|
|
59
43
|
style={headerStyle}
|
|
60
44
|
>
|
|
61
45
|
{header.isPlaceholder ? null : (
|
|
62
46
|
<div className={styles.headerSortContainer}>
|
|
63
|
-
<
|
|
47
|
+
<DsStack direction="column" justifyContent="center" width="100%">
|
|
48
|
+
{flexRender(header.column.columnDef.header, header.getContext())}
|
|
49
|
+
</DsStack>
|
|
64
50
|
{canSort && (
|
|
65
51
|
<div className={styles.pageButtonIconContainer}>
|
|
66
52
|
{{
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type React from 'react';
|
|
2
|
+
import { DsCheckbox } from '../../../ds-checkbox';
|
|
3
|
+
import stylesShared from '../../styles/shared/ds-table-shared.module.scss';
|
|
4
|
+
import type { DsTableHeaderSelectableCellProps } from './ds-table-header-selectable-cell.types';
|
|
5
|
+
|
|
6
|
+
export const DsTableHeaderSelectableCell = <TData,>({ table }: DsTableHeaderSelectableCellProps<TData>) => {
|
|
7
|
+
const checked = table.getIsAllRowsSelected()
|
|
8
|
+
? true
|
|
9
|
+
: table.getIsSomeRowsSelected()
|
|
10
|
+
? 'indeterminate'
|
|
11
|
+
: false;
|
|
12
|
+
|
|
13
|
+
return (
|
|
14
|
+
<DsCheckbox
|
|
15
|
+
className={stylesShared.checkboxContainer}
|
|
16
|
+
checked={checked}
|
|
17
|
+
onCheckedChange={(nextChecked) => table.toggleAllRowsSelected(!!nextChecked)}
|
|
18
|
+
onClick={(e) => e.stopPropagation()}
|
|
19
|
+
onDoubleClick={(e: React.MouseEvent) => e.stopPropagation()}
|
|
20
|
+
/>
|
|
21
|
+
);
|
|
22
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Table } from '@tanstack/react-table';
|
|
2
|
+
|
|
3
|
+
export interface DsTableHeaderSelectableCellProps<TData> {
|
|
4
|
+
/**
|
|
5
|
+
* TanStack Table instance for the table. Used to read the aggregate
|
|
6
|
+
* selection state and toggle selection across all rows.
|
|
7
|
+
*/
|
|
8
|
+
table: Table<TData>;
|
|
9
|
+
}
|
|
@@ -4,9 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
.tableRow {
|
|
6
6
|
&:not(:last-child) {
|
|
7
|
-
.tableCell
|
|
8
|
-
.selectableCell,
|
|
9
|
-
.expandableCell {
|
|
7
|
+
.tableCell {
|
|
10
8
|
border-bottom: vars.$border-width solid var(--border-secondary);
|
|
11
9
|
}
|
|
12
10
|
}
|
|
@@ -71,18 +69,15 @@
|
|
|
71
69
|
}
|
|
72
70
|
}
|
|
73
71
|
|
|
74
|
-
.tableCell
|
|
75
|
-
.selectableCell {
|
|
72
|
+
.tableCell {
|
|
76
73
|
@include typography.body-sm-reg;
|
|
77
74
|
vertical-align: middle;
|
|
78
75
|
color: var(--font-main);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
.tableCell {
|
|
82
76
|
padding: 0 var(--standard);
|
|
83
77
|
}
|
|
84
78
|
|
|
85
|
-
.expandableCell
|
|
79
|
+
.expandableCell,
|
|
80
|
+
.selectableCell {
|
|
86
81
|
padding: 0;
|
|
87
82
|
text-align: center;
|
|
88
83
|
}
|
|
@@ -5,26 +5,27 @@ import { CSS } from '@dnd-kit/utilities';
|
|
|
5
5
|
import { DsIcon } from '../../../ds-icon';
|
|
6
6
|
import { TableCell, TableRow } from '../core-table';
|
|
7
7
|
import { DsTableCell } from '../ds-table-cell';
|
|
8
|
-
import { DsTableRowSelectableCell } from '../ds-table-row-selectable-cell';
|
|
9
8
|
import type { DsTableRowProps } from './ds-table-row.types';
|
|
10
9
|
import styles from './ds-table-row.module.scss';
|
|
11
10
|
import { useDsTableContext } from '../../context/ds-table-context';
|
|
12
11
|
import { mergeRefs } from '../../../../utils/merge-refs';
|
|
13
12
|
import { getColumnSizeStyle } from '../../utils/column-size';
|
|
14
|
-
import { EXPANDER_COLUMN_ID } from '../../utils/constants';
|
|
13
|
+
import { EXPANDER_COLUMN_ID, REORDER_COLUMN_ID, SELECT_COLUMN_ID } from '../../utils/constants';
|
|
15
14
|
|
|
16
15
|
interface DsRowDragHandleProps {
|
|
17
16
|
isDragging: boolean;
|
|
18
17
|
attributes: ReturnType<typeof useSortable>['attributes'];
|
|
19
18
|
listeners: ReturnType<typeof useSortable>['listeners'];
|
|
19
|
+
style?: React.CSSProperties;
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
const DsRowDragHandle = ({ isDragging, attributes, listeners }: DsRowDragHandleProps) => {
|
|
22
|
+
const DsRowDragHandle = ({ isDragging, attributes, listeners, style }: DsRowDragHandleProps) => {
|
|
23
23
|
return (
|
|
24
24
|
<TableCell
|
|
25
25
|
className={classnames(styles.tableCell, styles.cellReorder, {
|
|
26
26
|
[styles.isDragging]: isDragging,
|
|
27
27
|
})}
|
|
28
|
+
style={style}
|
|
28
29
|
>
|
|
29
30
|
<DsIcon
|
|
30
31
|
className={styles.rowDragHandle}
|
|
@@ -40,7 +41,6 @@ const DsRowDragHandle = ({ isDragging, attributes, listeners }: DsRowDragHandleP
|
|
|
40
41
|
|
|
41
42
|
const DsTableRow = <TData,>({ ref, row, isSelected }: DsTableRowProps<TData>) => {
|
|
42
43
|
const {
|
|
43
|
-
selectable,
|
|
44
44
|
reorderable,
|
|
45
45
|
onRowClick,
|
|
46
46
|
onRowDoubleClick,
|
|
@@ -94,22 +94,30 @@ const DsTableRow = <TData,>({ ref, row, isSelected }: DsTableRowProps<TData>) =>
|
|
|
94
94
|
onClick={() => onRowClick?.(row.original)}
|
|
95
95
|
onDoubleClick={() => onRowDoubleClick?.(row.original)}
|
|
96
96
|
>
|
|
97
|
-
{selectable && (
|
|
98
|
-
<DsTableRowSelectableCell row={row} isSelected={isSelected} className={styles.selectableCell} />
|
|
99
|
-
)}
|
|
100
|
-
{reorderable && (
|
|
101
|
-
<DsRowDragHandle isDragging={isDragging} attributes={attributes} listeners={listeners} />
|
|
102
|
-
)}
|
|
103
97
|
{row.getVisibleCells().map((cell, idx) => {
|
|
104
|
-
const isLastColumn = idx === row.getVisibleCells().length - 1;
|
|
105
98
|
const cellStyle = getColumnSizeStyle(cell.column.getSize());
|
|
106
99
|
|
|
100
|
+
if (cell.column.id === REORDER_COLUMN_ID) {
|
|
101
|
+
return (
|
|
102
|
+
<DsRowDragHandle
|
|
103
|
+
key={cell.id}
|
|
104
|
+
isDragging={isDragging}
|
|
105
|
+
attributes={attributes}
|
|
106
|
+
listeners={listeners}
|
|
107
|
+
style={cellStyle}
|
|
108
|
+
/>
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const isLastColumn = idx === row.getVisibleCells().length - 1;
|
|
113
|
+
|
|
107
114
|
return (
|
|
108
115
|
<TableCell
|
|
109
116
|
key={cell.id}
|
|
110
117
|
className={classnames(
|
|
111
118
|
styles.tableCell,
|
|
112
119
|
cell.column.id === EXPANDER_COLUMN_ID && styles.expandableCell,
|
|
120
|
+
cell.column.id === SELECT_COLUMN_ID && styles.selectableCell,
|
|
113
121
|
)}
|
|
114
122
|
style={cellStyle}
|
|
115
123
|
>
|
|
@@ -130,10 +138,7 @@ const DsTableRow = <TData,>({ ref, row, isSelected }: DsTableRowProps<TData>) =>
|
|
|
130
138
|
|
|
131
139
|
{isExpanded && renderExpandedRow && (
|
|
132
140
|
<TableRow className={styles.expandedRow}>
|
|
133
|
-
<TableCell
|
|
134
|
-
colSpan={row.getVisibleCells().length + (selectable ? 1 : 0) + (reorderable ? 1 : 0)}
|
|
135
|
-
className={styles.tableCell}
|
|
136
|
-
>
|
|
141
|
+
<TableCell colSpan={row.getVisibleCells().length} className={styles.tableCell}>
|
|
137
142
|
{renderExpandedRow(row.original)}
|
|
138
143
|
</TableCell>
|
|
139
144
|
</TableRow>
|
|
@@ -1,26 +1,17 @@
|
|
|
1
1
|
import type React from 'react';
|
|
2
|
-
import { TableCell } from '../core-table';
|
|
3
2
|
import { DsCheckbox } from '../../../ds-checkbox';
|
|
4
3
|
import stylesShared from '../../styles/shared/ds-table-shared.module.scss';
|
|
5
4
|
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
5
|
|
|
9
|
-
export const DsTableRowSelectableCell = <TData,>({
|
|
10
|
-
row,
|
|
11
|
-
isSelected,
|
|
12
|
-
className,
|
|
13
|
-
}: DsTableRowSelectableCellProps<TData>) => {
|
|
6
|
+
export const DsTableRowSelectableCell = <TData,>({ row }: DsTableRowSelectableCellProps<TData>) => {
|
|
14
7
|
return (
|
|
15
|
-
<
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
/>
|
|
24
|
-
</TableCell>
|
|
8
|
+
<DsCheckbox
|
|
9
|
+
className={stylesShared.checkboxContainer}
|
|
10
|
+
checked={row.getIsSelected()}
|
|
11
|
+
disabled={!row.getCanSelect()}
|
|
12
|
+
onCheckedChange={(checked) => row.toggleSelected(!!checked)}
|
|
13
|
+
onClick={(e) => e.stopPropagation()}
|
|
14
|
+
onDoubleClick={(e: React.MouseEvent) => e.stopPropagation()}
|
|
15
|
+
/>
|
|
25
16
|
);
|
|
26
17
|
};
|
|
@@ -2,17 +2,8 @@ import type { Row } from '@tanstack/react-table';
|
|
|
2
2
|
|
|
3
3
|
export interface DsTableRowSelectableCellProps<TData> {
|
|
4
4
|
/**
|
|
5
|
-
* TanStack Table row model for the parent row. Used to
|
|
6
|
-
* selection state when the checkbox is clicked.
|
|
5
|
+
* TanStack Table row model for the parent row. Used to read the row's
|
|
6
|
+
* selection state and toggle it when the checkbox is clicked.
|
|
7
7
|
*/
|
|
8
8
|
row: Row<TData>;
|
|
9
|
-
/**
|
|
10
|
-
* Whether the parent row is currently selected. Drives the checkbox's
|
|
11
|
-
* checked state.
|
|
12
|
-
*/
|
|
13
|
-
isSelected: boolean;
|
|
14
|
-
/**
|
|
15
|
-
* Additional CSS class name applied to the cell element.
|
|
16
|
-
*/
|
|
17
|
-
className?: string;
|
|
18
9
|
}
|
|
@@ -52,19 +52,16 @@
|
|
|
52
52
|
}
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
-
.cell
|
|
56
|
-
.selectableCell {
|
|
55
|
+
.cell {
|
|
57
56
|
display: flex;
|
|
58
57
|
align-items: center;
|
|
59
58
|
@include typography.body-sm-reg;
|
|
60
59
|
color: var(--font-main);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
.cell {
|
|
64
60
|
padding: 0 var(--standard);
|
|
65
61
|
}
|
|
66
62
|
|
|
67
|
-
.expandableCell
|
|
63
|
+
.expandableCell,
|
|
64
|
+
.selectableCell {
|
|
68
65
|
padding: 0;
|
|
69
66
|
justify-content: center;
|
|
70
67
|
}
|
package/src/components/ds-table/components/ds-table-row-virtualized/ds-table-row-virtualized.tsx
CHANGED
|
@@ -3,10 +3,9 @@ import styles from './ds-table-row-virtualized.module.scss';
|
|
|
3
3
|
import { useDsTableContext } from '../../context/ds-table-context';
|
|
4
4
|
import { getColumnSizeStyle } from '../../utils/column-size';
|
|
5
5
|
import { TableCell, TableRow } from '../core-table';
|
|
6
|
-
import { DsTableRowSelectableCell } from '../ds-table-row-selectable-cell';
|
|
7
6
|
import type { DsTableRowVirtualizedProps } from './ds-table-row-virtualized.types';
|
|
8
7
|
import { DsTableCell } from '../ds-table-cell';
|
|
9
|
-
import { EXPANDER_COLUMN_ID } from '../../utils/constants';
|
|
8
|
+
import { EXPANDER_COLUMN_ID, SELECT_COLUMN_ID } from '../../utils/constants';
|
|
10
9
|
|
|
11
10
|
export const DsTableRowVirtualized = <TData,>({
|
|
12
11
|
row,
|
|
@@ -18,7 +17,6 @@ export const DsTableRowVirtualized = <TData,>({
|
|
|
18
17
|
isExpandedRowContent,
|
|
19
18
|
}: DsTableRowVirtualizedProps<TData>) => {
|
|
20
19
|
const {
|
|
21
|
-
selectable,
|
|
22
20
|
bordered,
|
|
23
21
|
rowSize,
|
|
24
22
|
activeRowId,
|
|
@@ -67,9 +65,6 @@ export const DsTableRowVirtualized = <TData,>({
|
|
|
67
65
|
<TableCell>{renderExpandedRow?.(row.original)}</TableCell>
|
|
68
66
|
) : (
|
|
69
67
|
<>
|
|
70
|
-
{selectable && (
|
|
71
|
-
<DsTableRowSelectableCell row={row} isSelected={isSelected} className={styles.selectableCell} />
|
|
72
|
-
)}
|
|
73
68
|
{row.getVisibleCells().map((cell, idx) => {
|
|
74
69
|
const isLastColumn = idx === row.getVisibleCells().length - 1;
|
|
75
70
|
const cellStyle = getColumnSizeStyle(cell.column.getSize(), true);
|
|
@@ -81,6 +76,7 @@ export const DsTableRowVirtualized = <TData,>({
|
|
|
81
76
|
className={classnames(
|
|
82
77
|
styles.cell,
|
|
83
78
|
cell.column.id === EXPANDER_COLUMN_ID && styles.expandableCell,
|
|
79
|
+
cell.column.id === SELECT_COLUMN_ID && styles.selectableCell,
|
|
84
80
|
)}
|
|
85
81
|
>
|
|
86
82
|
{isLastColumn ? (
|
|
@@ -20,10 +20,20 @@ import styles from './ds-table.module.scss';
|
|
|
20
20
|
import type { DsDataTableProps, DsTableRowSize } from './ds-table.types';
|
|
21
21
|
import { DsTableRow } from './components/ds-table-row';
|
|
22
22
|
import { DsTableRowExpandableCell } from './components/ds-table-row-expandable-cell';
|
|
23
|
+
import { DsTableRowSelectableCell } from './components/ds-table-row-selectable-cell';
|
|
24
|
+
import { DsTableHeaderSelectableCell } from './components/ds-table-header-selectable-cell';
|
|
23
25
|
import { useDragAndDrop } from './hooks/use-drag-and-drop';
|
|
24
26
|
import { type DsTableContextType, DsTableContext } from './context/ds-table-context';
|
|
25
27
|
import { DsTableBodyVirtualized } from './components/ds-table-body-virtualized';
|
|
26
|
-
import {
|
|
28
|
+
import {
|
|
29
|
+
EMPTY_TABLE_STATE_TEXT,
|
|
30
|
+
EXPANDER_COLUMN_ID,
|
|
31
|
+
EXPANDER_COLUMN_WIDTH,
|
|
32
|
+
REORDER_COLUMN_ID,
|
|
33
|
+
REORDER_COLUMN_WIDTH,
|
|
34
|
+
SELECT_COLUMN_ID,
|
|
35
|
+
SELECT_COLUMN_WIDTH,
|
|
36
|
+
} from './utils/constants';
|
|
27
37
|
|
|
28
38
|
// Row size to pixel height mapping (matches CSS variables)
|
|
29
39
|
const ROW_SIZE_HEIGHT_MAP: Record<DsTableRowSize, number> = {
|
|
@@ -66,6 +76,7 @@ const DsTable = <TData extends { id: string }, TValue>({
|
|
|
66
76
|
columnVisibility: externalColumnVisibility,
|
|
67
77
|
onColumnVisibilityChange,
|
|
68
78
|
activeRowId,
|
|
79
|
+
infiniteScroll,
|
|
69
80
|
}: DsDataTableProps<TData, TValue>) => {
|
|
70
81
|
const [data, setData] = React.useState(tableData);
|
|
71
82
|
const [sorting, setSorting] = React.useState<SortingState>([]);
|
|
@@ -125,22 +136,53 @@ const DsTable = <TData extends { id: string }, TValue>({
|
|
|
125
136
|
onSelectionChange?.(newRowSelection);
|
|
126
137
|
};
|
|
127
138
|
|
|
139
|
+
const hasExpanderColumn = !!expandable;
|
|
140
|
+
const hasSelectColumn = !!selectable;
|
|
141
|
+
const hasReorderColumn = reorderable && !virtualized;
|
|
142
|
+
|
|
128
143
|
const columns = useMemo<ColumnDef<TData, TValue>[]>(() => {
|
|
129
|
-
|
|
130
|
-
|
|
144
|
+
const augmentedColumns: ColumnDef<TData, TValue>[] = [...columnsProp];
|
|
145
|
+
|
|
146
|
+
if (hasSelectColumn) {
|
|
147
|
+
const selectColumn: ColumnDef<TData, TValue> = {
|
|
148
|
+
id: SELECT_COLUMN_ID,
|
|
149
|
+
size: SELECT_COLUMN_WIDTH,
|
|
150
|
+
enableSorting: false,
|
|
151
|
+
enableResizing: false,
|
|
152
|
+
header: ({ table }) => (showSelectAllCheckbox ? <DsTableHeaderSelectableCell table={table} /> : null),
|
|
153
|
+
cell: ({ row }) => <DsTableRowSelectableCell row={row} />,
|
|
154
|
+
};
|
|
155
|
+
augmentedColumns.unshift(selectColumn);
|
|
131
156
|
}
|
|
132
157
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
158
|
+
if (hasExpanderColumn) {
|
|
159
|
+
const expanderColumn: ColumnDef<TData, TValue> = {
|
|
160
|
+
id: EXPANDER_COLUMN_ID,
|
|
161
|
+
size: EXPANDER_COLUMN_WIDTH,
|
|
162
|
+
enableSorting: false,
|
|
163
|
+
enableResizing: false,
|
|
164
|
+
header: () => null,
|
|
165
|
+
cell: ({ row }) => (row.getCanExpand() ? <DsTableRowExpandableCell row={row} /> : null),
|
|
166
|
+
};
|
|
167
|
+
augmentedColumns.unshift(expanderColumn);
|
|
168
|
+
}
|
|
141
169
|
|
|
142
|
-
|
|
143
|
-
|
|
170
|
+
if (hasReorderColumn) {
|
|
171
|
+
// Cell is rendered inline by DsTableRow when it encounters REORDER_COLUMN_ID,
|
|
172
|
+
// since the drag handle needs row-level useSortable state.
|
|
173
|
+
const reorderColumn: ColumnDef<TData, TValue> = {
|
|
174
|
+
id: REORDER_COLUMN_ID,
|
|
175
|
+
size: REORDER_COLUMN_WIDTH,
|
|
176
|
+
enableSorting: false,
|
|
177
|
+
enableResizing: false,
|
|
178
|
+
header: 'Order',
|
|
179
|
+
cell: () => null,
|
|
180
|
+
};
|
|
181
|
+
augmentedColumns.unshift(reorderColumn);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
return augmentedColumns;
|
|
185
|
+
}, [columnsProp, hasExpanderColumn, hasReorderColumn, hasSelectColumn, showSelectAllCheckbox]);
|
|
144
186
|
|
|
145
187
|
const table = useReactTable({
|
|
146
188
|
data: reorderable ? data : tableData,
|
|
@@ -212,10 +254,7 @@ const DsTable = <TData extends { id: string }, TValue>({
|
|
|
212
254
|
|
|
213
255
|
const renderEmptyState = () => (
|
|
214
256
|
<TableRow>
|
|
215
|
-
<TableCell
|
|
216
|
-
colSpan={columns.length + (selectable ? 1 : 0) + (reorderable ? 1 : 0)}
|
|
217
|
-
className={styles.emptyState}
|
|
218
|
-
>
|
|
257
|
+
<TableCell colSpan={columns.length} className={styles.emptyState}>
|
|
219
258
|
{emptyState || EMPTY_TABLE_STATE_TEXT}
|
|
220
259
|
</TableCell>
|
|
221
260
|
</TableRow>
|
|
@@ -276,6 +315,7 @@ const DsTable = <TData extends { id: string }, TValue>({
|
|
|
276
315
|
overscan={virtualizedOptions?.overscan}
|
|
277
316
|
onScroll={onScroll}
|
|
278
317
|
rowSelection={rowSelection}
|
|
318
|
+
infiniteScroll={infiniteScroll}
|
|
279
319
|
/>
|
|
280
320
|
) : (
|
|
281
321
|
<TableBody>
|
|
@@ -8,7 +8,7 @@ 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
|
+
import type { InfiniteScrollConfig, ScrollParams } from './components/ds-table-body-virtualized';
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* Row size variants based on Figma design specifications
|
|
@@ -164,6 +164,8 @@ export interface DsTableApi<TData> {
|
|
|
164
164
|
expandRows: (rowIds: string[]) => void;
|
|
165
165
|
}
|
|
166
166
|
|
|
167
|
+
export type { InfiniteScrollConfig } from './components/ds-table-body-virtualized';
|
|
168
|
+
|
|
167
169
|
/**
|
|
168
170
|
* Represents a bulk action that can be performed on multiple selected rows
|
|
169
171
|
*/
|
|
@@ -357,6 +359,30 @@ export interface DsDataTableProps<TData, TValue> {
|
|
|
357
359
|
*/
|
|
358
360
|
onScroll?: (params: ScrollParams) => void;
|
|
359
361
|
|
|
362
|
+
/**
|
|
363
|
+
* Configures infinite scroll for the virtualized table. The Table owns viewport/scroll
|
|
364
|
+
* detection and the auto-fill loop; the consumer owns fetching, pagination state,
|
|
365
|
+
* error handling, and retry.
|
|
366
|
+
*
|
|
367
|
+
* Only takes effect when `virtualized` is `true`. Passing this prop without
|
|
368
|
+
* `virtualized` is ignored.
|
|
369
|
+
*
|
|
370
|
+
* @example
|
|
371
|
+
* ```tsx
|
|
372
|
+
* <DsTable
|
|
373
|
+
* virtualized
|
|
374
|
+
* data={rows}
|
|
375
|
+
* columns={columns}
|
|
376
|
+
* infiniteScroll={{
|
|
377
|
+
* hasMore,
|
|
378
|
+
* isLoadingMore,
|
|
379
|
+
* onLoadMore: fetchNextPage,
|
|
380
|
+
* }}
|
|
381
|
+
* />
|
|
382
|
+
* ```
|
|
383
|
+
*/
|
|
384
|
+
infiniteScroll?: InfiniteScrollConfig;
|
|
385
|
+
|
|
360
386
|
/**
|
|
361
387
|
* Actions to be shown in the bulk actions
|
|
362
388
|
*/
|
|
@@ -12,3 +12,24 @@ export const EXPANDER_COLUMN_ID = 'expander';
|
|
|
12
12
|
* Width (in px) of the expander column.
|
|
13
13
|
*/
|
|
14
14
|
export const EXPANDER_COLUMN_WIDTH = 36;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Column id used for the synthetic selection column injected when `selectable` is set.
|
|
18
|
+
*/
|
|
19
|
+
export const SELECT_COLUMN_ID = 'select';
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Width (in px) of the selection column.
|
|
23
|
+
*/
|
|
24
|
+
export const SELECT_COLUMN_WIDTH = 36;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Column id used for the synthetic reorder column injected when `reorderable` is set
|
|
28
|
+
* (non-virtualized tables only).
|
|
29
|
+
*/
|
|
30
|
+
export const REORDER_COLUMN_ID = 'reorder';
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Width (in px) of the reorder column.
|
|
34
|
+
*/
|
|
35
|
+
export const REORDER_COLUMN_WIDTH = 60;
|
package/src/index.ts
CHANGED
|
@@ -47,6 +47,7 @@ export * from './components/ds-spinner';
|
|
|
47
47
|
export * from './components/ds-split-button';
|
|
48
48
|
export * from './components/ds-stack';
|
|
49
49
|
export * from './components/ds-status-badge';
|
|
50
|
+
export * from './components/ds-status-badge-v2';
|
|
50
51
|
export * from './components/ds-stepper';
|
|
51
52
|
export * from './components/ds-system-status';
|
|
52
53
|
export * from './components/ds-table';
|
|
@@ -64,7 +64,7 @@ $dropdown-z-index: 9999;
|
|
|
64
64
|
gap: 10px;
|
|
65
65
|
color: var(--font-main);
|
|
66
66
|
font-size: var(--body-font-size-sm);
|
|
67
|
-
padding: var(--xs);
|
|
67
|
+
padding: var(--xs) var(--sm) var(--xs) var(--xs);
|
|
68
68
|
border-radius: 2px;
|
|
69
69
|
border-left: 2px solid transparent;
|
|
70
70
|
cursor: pointer;
|