@drivenets/design-system 0.16.0 → 0.18.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 +31 -0
- package/dist/index.cjs +1893 -824
- package/dist/index.d.cts +363 -247
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +363 -247
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1896 -829
- package/dist/index.js.map +1 -1
- package/dist/index.min.css +1 -1
- package/package.json +25 -25
- package/src/components/ds-alert-banner/ds-alert-banner-global.figma.ts +49 -0
- package/src/components/ds-alert-banner/ds-alert-banner.figma.ts +51 -0
- package/src/components/ds-alert-banner/ds-alert-banner.tsx +7 -6
- package/src/components/ds-autocomplete/ds-autocomplete.figma.ts +2 -2
- package/src/components/ds-autocomplete/ds-autocomplete.module.scss +15 -4
- package/src/components/ds-autocomplete/ds-autocomplete.tsx +10 -3
- package/src/components/ds-autocomplete/ds-autocomplete.types.ts +8 -0
- package/src/components/ds-avatar/ds-avatar.figma.ts +2 -2
- package/src/components/ds-avatar-group/ds-avatar-group.figma.ts +2 -2
- package/src/components/ds-breadcrumb/ds-breadcrumb.figma.ts +2 -2
- package/src/components/ds-button-v3/ds-button-v3.figma.ts +7 -5
- package/src/components/ds-button-v3/ds-button-v3.module.scss +84 -17
- package/src/components/ds-button-v3/ds-button-v3.tsx +2 -0
- package/src/components/ds-button-v3/ds-button-v3.types.ts +11 -2
- package/src/components/ds-button-v3/ds-button-v4.figma.ts +121 -0
- package/src/components/ds-card/figma/ds-card-content.figma.ts +2 -2
- package/src/components/ds-card/figma/ds-card-footer.figma.ts +2 -2
- package/src/components/ds-card/figma/ds-card-header.figma.ts +2 -2
- package/src/components/ds-card/figma/ds-card.figma.ts +2 -2
- package/src/components/ds-catalog-layout/ds-catalog-layout.figma.ts +51 -0
- package/src/components/ds-catalog-layout/ds-catalog-layout.tsx +9 -8
- package/src/components/ds-checkbox/ds-checkbox-level-2.figma.ts +2 -2
- package/src/components/ds-checkbox/ds-checkbox.figma.ts +2 -2
- package/src/components/ds-checkbox-group/ds-checkbox-group.figma.ts +2 -2
- package/src/components/ds-comment-bubble/ds-comment-bubble.figma.ts +52 -0
- package/src/components/ds-comment-card/ds-comment-card.figma.ts +36 -0
- package/src/components/ds-comment-indicator/ds-comment-indicator.figma.ts +32 -0
- package/src/components/ds-comments-drawer/components/comments-filter-modal/index.ts +0 -1
- package/src/components/ds-comments-drawer/ds-comments-drawer.figma.ts +19 -0
- package/src/components/ds-confirmation/ds-confirmation.tsx +13 -11
- package/src/components/ds-date-picker/ds-date-picker.figma.ts +2 -2
- package/src/components/ds-divider/ds-divider.figma.ts +2 -2
- package/src/components/ds-drawer/ds-drawer.tsx +11 -10
- package/src/components/ds-drawer/figma/ds-drawer-content.figma.ts +2 -2
- package/src/components/ds-drawer/figma/ds-drawer-footer.figma.ts +2 -2
- package/src/components/ds-drawer/figma/ds-drawer-header.figma.ts +2 -2
- package/src/components/ds-drawer/figma/ds-drawer.figma.ts +2 -2
- package/src/components/ds-dropdown-menu/figma/ds-dropdown-menu-footer.figma.ts +2 -2
- package/src/components/ds-dropdown-menu/figma/ds-dropdown-menu-group.figma.ts +2 -2
- package/src/components/ds-dropdown-menu/figma/ds-dropdown-menu-item.figma.ts +2 -2
- package/src/components/ds-dropdown-menu/figma/ds-dropdown-menu-separator.figma.ts +2 -2
- package/src/components/ds-dropdown-menu/figma/ds-dropdown-menu.figma.ts +2 -2
- package/src/components/ds-expandable-text-input/ds-expandable-text-input.figma.ts +2 -2
- package/src/components/ds-file-upload/components/file-upload-item/index.ts +0 -1
- package/src/components/ds-file-upload/ds-file-upload.figma.ts +2 -2
- package/src/components/ds-filter-status-icon/ds-filter-status-icon.figma.ts +2 -2
- package/src/components/ds-form-control/ds-form-control.figma.ts +2 -2
- package/src/components/ds-form-control/ds-form-control.tsx +15 -13
- package/src/components/ds-icon/figma/ds-icon-material.figma.batch.ts +1 -1
- package/src/components/ds-icon/figma/ds-icon-special.figma.batch.ts +1 -1
- package/src/components/ds-key-value-pair/ds-key-value-pair.figma.ts +2 -2
- package/src/components/ds-loader/ds-loader.figma.ts +2 -2
- package/src/components/ds-modal/ds-modal.tsx +10 -9
- package/src/components/ds-modal/figma/ds-modal-content.figma.ts +2 -2
- package/src/components/ds-modal/figma/ds-modal-footer.figma.ts +2 -2
- package/src/components/ds-modal/figma/ds-modal-header.figma.ts +2 -2
- package/src/components/ds-modal/figma/ds-modal.figma.ts +2 -2
- package/src/components/ds-number-input/ds-number-input.tsx +1 -0
- package/src/components/ds-panel/ds-panel.figma.ts +2 -2
- package/src/components/ds-popover/figma/ds-popover-content-item.figma.ts +2 -2
- package/src/components/ds-popover/figma/ds-popover-content.figma.ts +2 -2
- package/src/components/ds-popover/figma/ds-popover-footer.figma.ts +2 -2
- package/src/components/ds-popover/figma/ds-popover-header.figma.ts +2 -2
- package/src/components/ds-popover/figma/ds-popover.figma.ts +2 -2
- package/src/components/ds-progress-arc/ds-progress-arc.figma.ts +2 -2
- package/src/components/ds-progress-donut/ds-progress-donut.figma.ts +2 -2
- package/src/components/ds-progress-linear/ds-progress-linear.figma.ts +2 -2
- package/src/components/ds-progress-task-bar/ds-progress-task-bar.figma.ts +2 -2
- package/src/components/ds-radio-group/figma/ds-radio-group-item.figma.ts +2 -2
- package/src/components/ds-radio-group/figma/ds-radio-group.figma.ts +2 -2
- package/src/components/ds-segment-group/figma/ds-segment-group-item.figma.ts +2 -2
- package/src/components/ds-segment-group/figma/ds-segment-group.figma.ts +2 -2
- package/src/components/ds-select/ds-select.figma.ts +4 -3
- package/src/components/ds-select/ds-select.tsx +6 -1
- package/src/components/ds-select/ds-select.types.ts +2 -1
- package/src/components/ds-site-node/ds-site-node.figma.ts +2 -2
- package/src/components/ds-slider/ds-slider.figma.ts +29 -0
- package/src/components/ds-slider/ds-slider.module.scss +104 -0
- package/src/components/ds-slider/ds-slider.tsx +118 -0
- package/src/components/ds-slider/ds-slider.types.ts +102 -0
- package/src/components/ds-slider/ds-slider.utils.ts +14 -0
- package/src/components/ds-slider/index.ts +11 -0
- package/src/components/ds-smart-tabs/ds-smart-tabs.tsx +5 -4
- package/src/components/ds-smart-tabs/figma/ds-smart-tabs-tab.figma.ts +83 -0
- package/src/components/ds-smart-tabs/figma/ds-smart-tabs.figma.ts +23 -0
- package/src/components/ds-spinner/ds-spinner.figma.ts +2 -2
- package/src/components/ds-split-button/ds-split-button.figma.ts +2 -2
- package/src/components/ds-status-badge-v2/ds-status-badge-v2.figma.ts +2 -2
- package/src/components/ds-stepper/ds-stepper.figma.ts +2 -2
- package/src/components/ds-table/components/ds-table-group-header-cell/ds-table-group-header-cell.module.scss +5 -1
- package/src/components/ds-table/components/ds-table-group-header-cell/ds-table-group-header-cell.tsx +15 -3
- package/src/components/ds-table/components/ds-table-group-header-cell/index.ts +0 -1
- package/src/components/ds-table/components/ds-table-header/ds-table-header.module.scss +17 -3
- package/src/components/ds-table/components/ds-table-header/ds-table-header.tsx +30 -9
- package/src/components/ds-table/components/ds-table-resize-handle/ds-table-resize-handle.module.scss +23 -0
- package/src/components/ds-table/components/ds-table-resize-handle/ds-table-resize-handle.tsx +218 -0
- package/src/components/ds-table/components/ds-table-resize-handle/ds-table-resize-handle.types.ts +14 -0
- package/src/components/ds-table/components/ds-table-resize-handle/index.ts +1 -0
- package/src/components/ds-table/components/ds-table-resize-overlay/ds-table-resize-overlay.module.scss +18 -0
- package/src/components/ds-table/components/ds-table-resize-overlay/ds-table-resize-overlay.tsx +16 -0
- package/src/components/ds-table/components/ds-table-resize-overlay/ds-table-resize-overlay.types.ts +13 -0
- package/src/components/ds-table/components/ds-table-resize-overlay/index.ts +1 -0
- package/src/components/ds-table/components/ds-table-row/ds-table-row.module.scss +1 -1
- package/src/components/ds-table/components/ds-table-row/ds-table-row.tsx +9 -2
- package/src/components/ds-table/components/ds-table-row-virtualized/ds-table-row-virtualized.module.scss +2 -1
- package/src/components/ds-table/components/ds-table-row-virtualized/ds-table-row-virtualized.tsx +9 -2
- package/src/components/ds-table/components/edit/cell-editors/ds-table-edit-cell-checkbox.tsx +2 -2
- package/src/components/ds-table/components/edit/cell-editors/ds-table-edit-cell-date.tsx +2 -1
- package/src/components/ds-table/components/edit/cell-editors/ds-table-edit-cell-number.tsx +2 -1
- package/src/components/ds-table/components/edit/cell-editors/ds-table-edit-cell-select.tsx +2 -1
- package/src/components/ds-table/components/edit/cell-editors/ds-table-edit-cell-text.tsx +2 -1
- package/src/components/ds-table/components/edit/ds-table-editing-cell/ds-table-editing-cell.tsx +12 -3
- package/src/components/ds-table/context/ds-table-context.tsx +208 -0
- package/src/components/ds-table/ds-table-defaults.ts +42 -0
- package/src/components/ds-table/ds-table.module.scss +19 -1
- package/src/components/ds-table/ds-table.tsx +163 -235
- package/src/components/ds-table/ds-table.types.ts +59 -47
- package/src/components/ds-table/figma/ds-table-expandable.figma.ts +2 -2
- package/src/components/ds-table/figma/ds-table.figma.ts +2 -2
- package/src/components/ds-table/grouping/utils/column-group.ts +7 -5
- package/src/components/ds-table/hooks/use-cell-editor.ts +5 -1
- package/src/components/ds-table/hooks/use-column-resize.ts +385 -0
- package/src/components/ds-table/hooks/use-editing-state.ts +190 -0
- package/src/components/ds-table/index.ts +1 -0
- package/src/components/ds-table/styles/_variables.scss +2 -1
- package/src/components/ds-table/utils/column-size-meta.augmentation.ts +16 -0
- package/src/components/ds-table/utils/column-size.ts +213 -10
- package/src/components/ds-table/utils/column-size.unit.test.ts +213 -0
- package/src/components/ds-table/utils/constants.ts +28 -0
- package/src/components/ds-table/utils/frozen-body.ts +33 -0
- package/src/components/ds-table/utils/frozen-body.unit.test.ts +44 -0
- package/src/components/ds-table/utils/table-api.ts +42 -0
- package/src/components/ds-table/utils/table-api.unit.test.ts +82 -0
- package/src/components/ds-table/utils/table-columns.tsx +119 -0
- package/src/components/ds-table/utils/table-columns.unit.test.ts +199 -0
- package/src/components/ds-tabs/figma/ds-tabs-tab-vertical.figma.ts +2 -2
- package/src/components/ds-tabs/figma/ds-tabs-tab.figma.ts +2 -2
- package/src/components/ds-tabs/figma/ds-tabs-vertical.figma.ts +2 -2
- package/src/components/ds-tabs/figma/ds-tabs.figma.ts +2 -2
- package/src/components/ds-tag/ds-tag.figma.ts +51 -0
- package/src/components/ds-tag-filter/ds-tag-filter.figma.ts +16 -0
- package/src/components/ds-text-input/ds-input-field-v02.figma.ts +31 -6
- package/src/components/ds-text-input/ds-text-input.figma.ts +5 -4
- package/src/components/ds-text-input/ds-text-input.tsx +1 -0
- package/src/components/ds-text-input/ds-text-input.types.ts +1 -1
- package/src/components/ds-time-picker/ds-time-picker.figma.ts +2 -2
- package/src/components/ds-toast/ds-toast.figma.ts +3 -3
- package/src/components/ds-toggle/ds-toggle.figma.ts +2 -2
- package/src/components/ds-tooltip/ds-tooltip.figma.ts +2 -2
- package/src/components/ds-tree/ds-tree.figma.ts +54 -0
- package/src/components/ds-tree/ds-tree.module.scss +2 -2
- package/src/components/ds-tree/ds-tree.tsx +6 -0
- package/src/components/ds-tree/ds-tree.types.ts +16 -0
- package/src/components/ds-typography/ds-typography.figma.ts +2 -2
- package/src/components/ds-user-card/ds-user-card.figma.ts +2 -2
- package/src/components/ds-vertical-tabs/ds-vertical-tabs.tsx +13 -6
- package/src/components/ds-workspace-layout/ds-workspace-layout.figma.ts +99 -0
- package/src/components/ds-workspace-layout/ds-workspace-layout.module.scss +1 -8
- package/src/components/ds-workspace-layout/ds-workspace-layout.tsx +11 -10
- package/src/index.ts +1 -0
- package/src/styles/_gradients.scss +19 -0
- package/src/styles/_root.scss +39 -15
- package/src/styles/_typography.scss +1 -0
- package/src/styles/shared/_input.scss +10 -0
- package/src/styles/styles.scss +1 -0
- package/src/components/ds-table/context/ds-table-context.ts +0 -112
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import type { ColumnDef } from '@tanstack/react-table';
|
|
2
|
+
import { DsSkeletonText } from '../../ds-skeleton';
|
|
3
|
+
import { DsTableHeaderSelectableCell } from '../components/ds-table-header-selectable-cell';
|
|
4
|
+
import { DsTableRowExpandableCell } from '../components/ds-table-row-expandable-cell';
|
|
5
|
+
import { DsTableRowSelectableCell } from '../components/ds-table-row-selectable-cell';
|
|
6
|
+
import {
|
|
7
|
+
EXPANDER_COLUMN_ID,
|
|
8
|
+
EXPANDER_COLUMN_WIDTH,
|
|
9
|
+
REORDER_COLUMN_ID,
|
|
10
|
+
REORDER_COLUMN_WIDTH,
|
|
11
|
+
SELECT_COLUMN_ID,
|
|
12
|
+
SELECT_COLUMN_WIDTH,
|
|
13
|
+
SKELETON_ROW_COUNT,
|
|
14
|
+
} from './constants';
|
|
15
|
+
|
|
16
|
+
export type GetAugmentedColumnsOptions = {
|
|
17
|
+
selectable: boolean;
|
|
18
|
+
expandable: boolean;
|
|
19
|
+
reorderable: boolean;
|
|
20
|
+
virtualized: boolean;
|
|
21
|
+
showSelectAllCheckbox: boolean;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const EXPLICIT_SIZE_META = { hasExplicitSize: true } as const;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Clones leaf defs that authored `size` so `meta.hasExplicitSize` survives
|
|
28
|
+
* TanStack’s default-size merge. Group defs are cloned only to recurse;
|
|
29
|
+
* unsized leaves are returned as-is.
|
|
30
|
+
*/
|
|
31
|
+
const stampExplicitSize = <TData, TValue>(columns: ColumnDef<TData, TValue>[]): ColumnDef<TData, TValue>[] =>
|
|
32
|
+
columns.map((column) => {
|
|
33
|
+
if ('columns' in column && column.columns) {
|
|
34
|
+
return { ...column, columns: stampExplicitSize(column.columns) };
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (column.size === undefined) {
|
|
38
|
+
return column;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return { ...column, meta: { ...column.meta, ...EXPLICIT_SIZE_META } };
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Prepends the builtin select / expander / reorder columns when those features
|
|
46
|
+
* are on. Reorder is omitted for virtualized tables. Unshift order yields
|
|
47
|
+
* visual order: reorder, expander, select, then consumer columns.
|
|
48
|
+
*/
|
|
49
|
+
export const getAugmentedColumns = <TData, TValue>(
|
|
50
|
+
columns: ColumnDef<TData, TValue>[],
|
|
51
|
+
{ selectable, expandable, reorderable, virtualized, showSelectAllCheckbox }: GetAugmentedColumnsOptions,
|
|
52
|
+
): ColumnDef<TData, TValue>[] => {
|
|
53
|
+
const augmentedColumns: ColumnDef<TData, TValue>[] = stampExplicitSize(columns);
|
|
54
|
+
|
|
55
|
+
if (selectable) {
|
|
56
|
+
augmentedColumns.unshift({
|
|
57
|
+
id: SELECT_COLUMN_ID,
|
|
58
|
+
size: SELECT_COLUMN_WIDTH,
|
|
59
|
+
// Pin min/max to the fixed width: `enableResizing: false` blocks the
|
|
60
|
+
// handle but not the table-wide resize `minSize`, which would otherwise
|
|
61
|
+
// stretch this column.
|
|
62
|
+
minSize: SELECT_COLUMN_WIDTH,
|
|
63
|
+
maxSize: SELECT_COLUMN_WIDTH,
|
|
64
|
+
enableSorting: false,
|
|
65
|
+
enableResizing: false,
|
|
66
|
+
meta: EXPLICIT_SIZE_META,
|
|
67
|
+
header: ({ table }) => (showSelectAllCheckbox ? <DsTableHeaderSelectableCell table={table} /> : null),
|
|
68
|
+
cell: ({ row }) => <DsTableRowSelectableCell row={row} />,
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (expandable) {
|
|
73
|
+
augmentedColumns.unshift({
|
|
74
|
+
id: EXPANDER_COLUMN_ID,
|
|
75
|
+
size: EXPANDER_COLUMN_WIDTH,
|
|
76
|
+
minSize: EXPANDER_COLUMN_WIDTH,
|
|
77
|
+
maxSize: EXPANDER_COLUMN_WIDTH,
|
|
78
|
+
enableSorting: false,
|
|
79
|
+
enableResizing: false,
|
|
80
|
+
meta: EXPLICIT_SIZE_META,
|
|
81
|
+
header: () => null,
|
|
82
|
+
cell: ({ row }) => (row.getCanExpand() ? <DsTableRowExpandableCell row={row} /> : null),
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (reorderable && !virtualized) {
|
|
87
|
+
// Cell is rendered inline by DsTableRow when it encounters REORDER_COLUMN_ID,
|
|
88
|
+
// since the drag handle needs row-level useSortable state.
|
|
89
|
+
augmentedColumns.unshift({
|
|
90
|
+
id: REORDER_COLUMN_ID,
|
|
91
|
+
size: REORDER_COLUMN_WIDTH,
|
|
92
|
+
minSize: REORDER_COLUMN_WIDTH,
|
|
93
|
+
maxSize: REORDER_COLUMN_WIDTH,
|
|
94
|
+
enableSorting: false,
|
|
95
|
+
enableResizing: false,
|
|
96
|
+
meta: EXPLICIT_SIZE_META,
|
|
97
|
+
header: 'Order',
|
|
98
|
+
cell: () => null,
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
return augmentedColumns;
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Replaces each leaf `cell` with `loadingCell` (or a default text skeleton).
|
|
107
|
+
* Group columns are cloned with the same transform applied to their children.
|
|
108
|
+
*/
|
|
109
|
+
export const toSkeletonColumns = <TData, TValue>(
|
|
110
|
+
columns: ColumnDef<TData, TValue>[],
|
|
111
|
+
): ColumnDef<TData, TValue>[] =>
|
|
112
|
+
columns.map((column) =>
|
|
113
|
+
'columns' in column && column.columns
|
|
114
|
+
? { ...column, columns: toSkeletonColumns(column.columns) }
|
|
115
|
+
: { ...column, cell: column.loadingCell ?? (() => <DsSkeletonText width="60%" />) },
|
|
116
|
+
);
|
|
117
|
+
|
|
118
|
+
export const createSkeletonRows = <TData extends { id: string }>(): TData[] =>
|
|
119
|
+
Array.from({ length: SKELETON_ROW_COUNT }, (_, i) => ({ id: `ds-table-skeleton-${String(i)}` }) as TData);
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import type { ColumnDef } from '@tanstack/react-table';
|
|
3
|
+
import { createSkeletonRows, getAugmentedColumns, toSkeletonColumns } from './table-columns';
|
|
4
|
+
import {
|
|
5
|
+
EXPANDER_COLUMN_ID,
|
|
6
|
+
EXPANDER_COLUMN_WIDTH,
|
|
7
|
+
REORDER_COLUMN_ID,
|
|
8
|
+
REORDER_COLUMN_WIDTH,
|
|
9
|
+
SELECT_COLUMN_ID,
|
|
10
|
+
SELECT_COLUMN_WIDTH,
|
|
11
|
+
SKELETON_ROW_COUNT,
|
|
12
|
+
} from './constants';
|
|
13
|
+
|
|
14
|
+
type Row = { id: string; name?: string };
|
|
15
|
+
|
|
16
|
+
const nameColumn: ColumnDef<Row> = { id: 'name', accessorKey: 'name' };
|
|
17
|
+
|
|
18
|
+
const noFeatures = {
|
|
19
|
+
selectable: false,
|
|
20
|
+
expandable: false,
|
|
21
|
+
reorderable: false,
|
|
22
|
+
virtualized: false,
|
|
23
|
+
showSelectAllCheckbox: true,
|
|
24
|
+
} as const;
|
|
25
|
+
|
|
26
|
+
const columnIds = (columns: ColumnDef<Row>[]) => columns.map((column) => column.id);
|
|
27
|
+
|
|
28
|
+
describe('getAugmentedColumns', () => {
|
|
29
|
+
it('returns consumer columns unchanged when no features are on', () => {
|
|
30
|
+
expect(columnIds(getAugmentedColumns([nameColumn], noFeatures))).toEqual(['name']);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it('prepends builtins in visual order: reorder, expander, select, then consumer columns', () => {
|
|
34
|
+
expect(
|
|
35
|
+
columnIds(
|
|
36
|
+
getAugmentedColumns([nameColumn], {
|
|
37
|
+
...noFeatures,
|
|
38
|
+
selectable: true,
|
|
39
|
+
expandable: true,
|
|
40
|
+
reorderable: true,
|
|
41
|
+
}),
|
|
42
|
+
),
|
|
43
|
+
).toEqual([REORDER_COLUMN_ID, EXPANDER_COLUMN_ID, SELECT_COLUMN_ID, 'name']);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it('omits select and expander when those flags are falsy', () => {
|
|
47
|
+
expect(columnIds(getAugmentedColumns([nameColumn], { ...noFeatures, reorderable: true }))).toEqual([
|
|
48
|
+
REORDER_COLUMN_ID,
|
|
49
|
+
'name',
|
|
50
|
+
]);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
it('omits reorder when the table is virtualized', () => {
|
|
54
|
+
expect(
|
|
55
|
+
columnIds(
|
|
56
|
+
getAugmentedColumns([nameColumn], {
|
|
57
|
+
...noFeatures,
|
|
58
|
+
selectable: true,
|
|
59
|
+
expandable: true,
|
|
60
|
+
reorderable: true,
|
|
61
|
+
virtualized: true,
|
|
62
|
+
}),
|
|
63
|
+
),
|
|
64
|
+
).toEqual([EXPANDER_COLUMN_ID, SELECT_COLUMN_ID, 'name']);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it('disables sorting and resizing on builtin columns', () => {
|
|
68
|
+
const columns = getAugmentedColumns([nameColumn], {
|
|
69
|
+
...noFeatures,
|
|
70
|
+
selectable: true,
|
|
71
|
+
expandable: true,
|
|
72
|
+
reorderable: true,
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
for (const column of columns.slice(0, 3)) {
|
|
76
|
+
expect(column.enableSorting).toBe(false);
|
|
77
|
+
expect(column.enableResizing).toBe(false);
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
it('pins builtin column min/max to their fixed width so the resize minimum cannot stretch them', () => {
|
|
82
|
+
const columns = getAugmentedColumns([nameColumn], {
|
|
83
|
+
...noFeatures,
|
|
84
|
+
selectable: true,
|
|
85
|
+
expandable: true,
|
|
86
|
+
reorderable: true,
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
const boundsById = new Map(columns.map((column) => [column.id, column]));
|
|
90
|
+
|
|
91
|
+
for (const [id, width] of [
|
|
92
|
+
[SELECT_COLUMN_ID, SELECT_COLUMN_WIDTH],
|
|
93
|
+
[EXPANDER_COLUMN_ID, EXPANDER_COLUMN_WIDTH],
|
|
94
|
+
[REORDER_COLUMN_ID, REORDER_COLUMN_WIDTH],
|
|
95
|
+
] as const) {
|
|
96
|
+
const column = boundsById.get(id);
|
|
97
|
+
expect(column?.size).toBe(width);
|
|
98
|
+
expect(column?.minSize).toBe(width);
|
|
99
|
+
expect(column?.maxSize).toBe(width);
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
it('stamps hasExplicitSize on authored leaves and builtins, not on unsized leaves', () => {
|
|
104
|
+
const columns = getAugmentedColumns(
|
|
105
|
+
[
|
|
106
|
+
{ id: 'name', accessorKey: 'name', size: 150 },
|
|
107
|
+
{ id: 'age', accessorKey: 'age' },
|
|
108
|
+
],
|
|
109
|
+
{
|
|
110
|
+
...noFeatures,
|
|
111
|
+
selectable: true,
|
|
112
|
+
expandable: true,
|
|
113
|
+
reorderable: true,
|
|
114
|
+
},
|
|
115
|
+
);
|
|
116
|
+
const byId = new Map(columns.map((column) => [column.id, column]));
|
|
117
|
+
|
|
118
|
+
expect(byId.get('name')?.meta?.hasExplicitSize).toBe(true);
|
|
119
|
+
expect(byId.get('age')?.meta?.hasExplicitSize).toBeUndefined();
|
|
120
|
+
expect(byId.get(SELECT_COLUMN_ID)?.meta?.hasExplicitSize).toBe(true);
|
|
121
|
+
expect(byId.get(EXPANDER_COLUMN_ID)?.meta?.hasExplicitSize).toBe(true);
|
|
122
|
+
expect(byId.get(REORDER_COLUMN_ID)?.meta?.hasExplicitSize).toBe(true);
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
it('stamps hasExplicitSize on nested authored leaves and preserves group meta', () => {
|
|
126
|
+
const columns = getAugmentedColumns(
|
|
127
|
+
[
|
|
128
|
+
{
|
|
129
|
+
id: 'identity',
|
|
130
|
+
header: 'Identity',
|
|
131
|
+
meta: { group: { collapsible: true } },
|
|
132
|
+
columns: [{ id: 'firstName', size: 150 }, { id: 'lastName' }],
|
|
133
|
+
},
|
|
134
|
+
],
|
|
135
|
+
noFeatures,
|
|
136
|
+
);
|
|
137
|
+
const group = columns[0];
|
|
138
|
+
const nested = group && 'columns' in group ? group.columns : undefined;
|
|
139
|
+
|
|
140
|
+
expect(group?.meta?.group).toEqual({ collapsible: true });
|
|
141
|
+
expect(nested?.[0]?.meta?.hasExplicitSize).toBe(true);
|
|
142
|
+
expect(nested?.[1]?.meta?.hasExplicitSize).toBeUndefined();
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
it('does not mutate the caller’s column defs', () => {
|
|
146
|
+
const leaf: ColumnDef<Row> = { id: 'name', accessorKey: 'name', size: 150 };
|
|
147
|
+
|
|
148
|
+
getAugmentedColumns([leaf], noFeatures);
|
|
149
|
+
|
|
150
|
+
expect(leaf.meta).toBeUndefined();
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
describe('toSkeletonColumns', () => {
|
|
155
|
+
it('replaces a leaf cell with loadingCell when provided', () => {
|
|
156
|
+
const loadingCell = () => 'loading';
|
|
157
|
+
const result = toSkeletonColumns<Row, unknown>([{ id: 'name', cell: () => 'name', loadingCell }])[0];
|
|
158
|
+
|
|
159
|
+
expect(result?.cell).toBe(loadingCell);
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
it('replaces a leaf cell with a default skeleton when loadingCell is omitted', () => {
|
|
163
|
+
const originalCell = () => 'name';
|
|
164
|
+
const result = toSkeletonColumns<Row, unknown>([{ id: 'name', cell: originalCell }])[0];
|
|
165
|
+
|
|
166
|
+
expect(result?.cell).not.toBe(originalCell);
|
|
167
|
+
expect(result?.cell).toBeTypeOf('function');
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
it('recurses into group columns', () => {
|
|
171
|
+
const loadingCell = () => 'loading';
|
|
172
|
+
const leafCell = () => 'leaf';
|
|
173
|
+
const group = toSkeletonColumns<Row, unknown>([
|
|
174
|
+
{
|
|
175
|
+
id: 'group',
|
|
176
|
+
columns: [
|
|
177
|
+
{ id: 'a', cell: leafCell },
|
|
178
|
+
{ id: 'b', cell: leafCell, loadingCell },
|
|
179
|
+
],
|
|
180
|
+
},
|
|
181
|
+
])[0];
|
|
182
|
+
|
|
183
|
+
const nested = group && 'columns' in group ? group.columns : undefined;
|
|
184
|
+
|
|
185
|
+
expect(nested?.[0]?.cell).not.toBe(leafCell);
|
|
186
|
+
expect(nested?.[1]?.cell).toBe(loadingCell);
|
|
187
|
+
});
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
describe('createSkeletonRows', () => {
|
|
191
|
+
it('returns placeholder rows with stable skeleton ids', () => {
|
|
192
|
+
const rows = createSkeletonRows<Row>();
|
|
193
|
+
|
|
194
|
+
expect(rows).toHaveLength(SKELETON_ROW_COUNT);
|
|
195
|
+
expect(rows.map((row) => row.id)).toEqual(
|
|
196
|
+
Array.from({ length: SKELETON_ROW_COUNT }, (_, i) => `ds-table-skeleton-${String(i)}`),
|
|
197
|
+
);
|
|
198
|
+
});
|
|
199
|
+
});
|
|
@@ -72,7 +72,7 @@ const attrs = [`value="${value}"`, `label="${label}"`, icon ? `icon="${icon}"` :
|
|
|
72
72
|
|
|
73
73
|
export default {
|
|
74
74
|
example: figma.code`<DsTabs.Tab ${attrs} />`,
|
|
75
|
-
imports: ["import { DsTabs } from '@drivenets/design-system'"],
|
|
75
|
+
imports: ["import { DsTabs } from '@drivenets/design-system';"],
|
|
76
76
|
id: 'ds-tabs-tab-vertical',
|
|
77
77
|
metadata: { nestable: true },
|
|
78
|
-
};
|
|
78
|
+
} satisfies figma.Template;
|
|
@@ -83,7 +83,7 @@ const attrs = [
|
|
|
83
83
|
|
|
84
84
|
export default {
|
|
85
85
|
example: figma.code`<DsTabs.Tab ${attrs} />`,
|
|
86
|
-
imports: ["import { DsTabs } from '@drivenets/design-system'"],
|
|
86
|
+
imports: ["import { DsTabs } from '@drivenets/design-system';"],
|
|
87
87
|
id: 'ds-tabs-tab',
|
|
88
88
|
metadata: { nestable: true },
|
|
89
|
-
};
|
|
89
|
+
} satisfies figma.Template;
|
|
@@ -25,7 +25,7 @@ export default {
|
|
|
25
25
|
<DsTabs.List>${tabs}</DsTabs.List>
|
|
26
26
|
{/* Add a <DsTabs.Content value="..."> panel for each tab */}
|
|
27
27
|
</DsTabs.Root>`,
|
|
28
|
-
imports: ["import { DsTabs } from '@drivenets/design-system'"],
|
|
28
|
+
imports: ["import { DsTabs } from '@drivenets/design-system';"],
|
|
29
29
|
id: 'ds-tabs-vertical',
|
|
30
30
|
metadata: { nestable: false },
|
|
31
|
-
};
|
|
31
|
+
} satisfies figma.Template;
|
|
@@ -23,7 +23,7 @@ export default {
|
|
|
23
23
|
<DsTabs.List>${tabs}</DsTabs.List>
|
|
24
24
|
{/* Add a <DsTabs.Content value="..."> panel for each tab */}
|
|
25
25
|
</DsTabs.Root>`,
|
|
26
|
-
imports: ["import { DsTabs } from '@drivenets/design-system'"],
|
|
26
|
+
imports: ["import { DsTabs } from '@drivenets/design-system';"],
|
|
27
27
|
id: 'ds-tabs',
|
|
28
28
|
metadata: { nestable: false },
|
|
29
|
-
};
|
|
29
|
+
} satisfies figma.Template;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
// url=https://www.figma.com/design/nha3m67y7S57cHCSuQO2gp/DAP-Design-System-1.2?node-id=36566-107407
|
|
2
|
+
// source=https://github.com/drivenets/design-system/tree/main/packages/design-system/src/components/ds-tag
|
|
3
|
+
// component=DsTag
|
|
4
|
+
//
|
|
5
|
+
// Figma "Type" maps to code `variant`, "Size" to `size`, "State" to the `selected`/`disabled`
|
|
6
|
+
// booleans (hover/focus are interaction states with no code prop). Figma's `Type=include-exclude`
|
|
7
|
+
// is a single variant backed by an internal, non-exposed include/exclude sub-toggle, so it can
|
|
8
|
+
// only be surfaced as one code value — it maps to `variant="include"`; switch to `variant="exclude"`
|
|
9
|
+
// for the exclude case. `label` is content, pulled from the tag text when present, otherwise a
|
|
10
|
+
// placeholder; `value` (required only for `key-value`) is emitted as a placeholder.
|
|
11
|
+
import figma from 'figma';
|
|
12
|
+
|
|
13
|
+
const instance = figma.selectedInstance;
|
|
14
|
+
|
|
15
|
+
const variant =
|
|
16
|
+
instance.getEnum('Type', {
|
|
17
|
+
default: 'default',
|
|
18
|
+
'include-exclude': 'include',
|
|
19
|
+
'key-value': 'key-value',
|
|
20
|
+
}) ?? 'default';
|
|
21
|
+
|
|
22
|
+
const size = instance.getEnum('Size', { medium: 'medium', small: 'small' }) ?? 'medium';
|
|
23
|
+
|
|
24
|
+
const state = instance.getEnum('State', {
|
|
25
|
+
default: 'default',
|
|
26
|
+
hover: 'hover',
|
|
27
|
+
focus: 'focus',
|
|
28
|
+
selected: 'selected',
|
|
29
|
+
disabled: 'disabled',
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
const labelNode = instance.findText('Tag-name', { traverseInstances: true });
|
|
33
|
+
const label = labelNode.type === 'TEXT' ? labelNode.textContent : 'Label';
|
|
34
|
+
|
|
35
|
+
const attrs = [
|
|
36
|
+
`label="${label}"`,
|
|
37
|
+
variant !== 'default' ? `variant="${variant}"` : '',
|
|
38
|
+
variant === 'key-value' ? 'value="Value"' : '',
|
|
39
|
+
size === 'small' ? 'size="small"' : '',
|
|
40
|
+
state === 'selected' ? 'selected' : '',
|
|
41
|
+
state === 'disabled' ? 'disabled' : '',
|
|
42
|
+
]
|
|
43
|
+
.filter(Boolean)
|
|
44
|
+
.join(' ');
|
|
45
|
+
|
|
46
|
+
export default {
|
|
47
|
+
example: figma.code`<DsTag ${attrs} />`,
|
|
48
|
+
imports: ["import { DsTag } from '@drivenets/design-system';"],
|
|
49
|
+
id: 'ds-tag',
|
|
50
|
+
metadata: { nestable: true },
|
|
51
|
+
} satisfies figma.Template;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// url=https://www.figma.com/design/nha3m67y7S57cHCSuQO2gp/DAP-Design-System-1.2?node-id=40298-1117
|
|
2
|
+
// source=https://github.com/drivenets/design-system/tree/main/packages/design-system/src/components/ds-tag-filter
|
|
3
|
+
// component=DsTagFilter
|
|
4
|
+
//
|
|
5
|
+
// Figma's `Type` variant (less/all) maps to the component's internal `expanded` state (driven by
|
|
6
|
+
// useTagOverflowCalculation, surfaced only via `onExpand`) — there is no settable code prop, so it
|
|
7
|
+
// is intentionally not represented. `items` is content, not derivable from Figma, so a placeholder
|
|
8
|
+
// array is emitted for the developer to fill in.
|
|
9
|
+
import figma from 'figma';
|
|
10
|
+
|
|
11
|
+
export default {
|
|
12
|
+
example: figma.code`<DsTagFilter items={[{ id: '1', label: 'Status: Active' }, { id: '2', label: 'Version: 1.0.0' }]} />`,
|
|
13
|
+
imports: ["import { DsTagFilter } from '@drivenets/design-system';"],
|
|
14
|
+
id: 'ds-tag-filter',
|
|
15
|
+
metadata: { nestable: true },
|
|
16
|
+
} satisfies figma.Template;
|
|
@@ -7,27 +7,49 @@ interface FieldInfo {
|
|
|
7
7
|
component: string;
|
|
8
8
|
fcMember?: string;
|
|
9
9
|
size?: boolean;
|
|
10
|
+
large?: boolean;
|
|
10
11
|
readOnly?: boolean;
|
|
11
12
|
invalid?: boolean;
|
|
12
13
|
data?: string;
|
|
13
14
|
}
|
|
14
15
|
|
|
15
|
-
const textInfo: FieldInfo = {
|
|
16
|
+
const textInfo: FieldInfo = {
|
|
17
|
+
component: 'DsTextInput',
|
|
18
|
+
fcMember: 'TextInput',
|
|
19
|
+
size: true,
|
|
20
|
+
large: true,
|
|
21
|
+
readOnly: true,
|
|
22
|
+
};
|
|
16
23
|
|
|
17
24
|
const registry: Record<string, FieldInfo> = {
|
|
18
25
|
text: textInfo,
|
|
19
26
|
textArea: { component: 'DsTextarea', fcMember: 'Textarea' },
|
|
20
27
|
number: { component: 'DsNumberInput', fcMember: 'NumberInput', size: true, readOnly: true },
|
|
21
28
|
password: { component: 'DsPasswordInput', fcMember: 'PasswordInput', size: true, readOnly: true },
|
|
22
|
-
select: {
|
|
29
|
+
select: {
|
|
30
|
+
component: 'DsSelect',
|
|
31
|
+
fcMember: 'Select',
|
|
32
|
+
size: true,
|
|
33
|
+
large: true,
|
|
34
|
+
invalid: true,
|
|
35
|
+
data: 'options={[]} value=""',
|
|
36
|
+
},
|
|
23
37
|
date: { component: 'DsDateInput', fcMember: 'DateInput' },
|
|
24
38
|
time: { component: 'DsTimePicker', fcMember: 'TimePicker' },
|
|
25
39
|
autocompleteSearch: {
|
|
26
40
|
component: 'DsAutocomplete',
|
|
41
|
+
size: true,
|
|
42
|
+
large: true,
|
|
27
43
|
invalid: true,
|
|
28
44
|
data: 'options={[]} showTrigger={false}',
|
|
29
45
|
},
|
|
30
|
-
autocompleteCombobox: {
|
|
46
|
+
autocompleteCombobox: {
|
|
47
|
+
component: 'DsAutocomplete',
|
|
48
|
+
size: true,
|
|
49
|
+
large: true,
|
|
50
|
+
invalid: true,
|
|
51
|
+
data: 'options={[]}',
|
|
52
|
+
},
|
|
31
53
|
};
|
|
32
54
|
|
|
33
55
|
const instance = figma.selectedInstance;
|
|
@@ -69,8 +91,11 @@ const disabled = state === 'disabled';
|
|
|
69
91
|
const readOnly = state === 'readOnly';
|
|
70
92
|
const error = state === 'error';
|
|
71
93
|
|
|
94
|
+
const sizeAttr =
|
|
95
|
+
info.size && size === 'small' ? 'size="small"' : info.large && size === 'large' ? 'size="large"' : '';
|
|
96
|
+
|
|
72
97
|
const attrs = [
|
|
73
|
-
|
|
98
|
+
sizeAttr,
|
|
74
99
|
info.data ?? '',
|
|
75
100
|
disabled ? 'disabled' : '',
|
|
76
101
|
info.readOnly && readOnly ? 'readOnly' : '',
|
|
@@ -81,7 +106,7 @@ const attrs = [
|
|
|
81
106
|
|
|
82
107
|
export default {
|
|
83
108
|
example: figma.code`<${info.component} ${attrs} />`,
|
|
84
|
-
imports: [`import { ${info.component} } from '@drivenets/design-system'
|
|
109
|
+
imports: [`import { ${info.component} } from '@drivenets/design-system';`],
|
|
85
110
|
id: 'ds-input-field-v02',
|
|
86
111
|
metadata: { nestable: true, props: { fcMember: info.fcMember, fcProps: attrs } },
|
|
87
|
-
};
|
|
112
|
+
} satisfies figma.Template;
|
|
@@ -22,7 +22,7 @@ const type = instance.getEnum('Type', {
|
|
|
22
22
|
const size = instance.getEnum('Size', {
|
|
23
23
|
Small: 'small',
|
|
24
24
|
Default: 'default',
|
|
25
|
-
Large: '
|
|
25
|
+
Large: 'large',
|
|
26
26
|
});
|
|
27
27
|
|
|
28
28
|
const state = instance.getEnum('State', {
|
|
@@ -36,7 +36,8 @@ const state = instance.getEnum('State', {
|
|
|
36
36
|
const disabled = state === 'disabled';
|
|
37
37
|
const readOnly = type === 'readOnly' || state === 'readOnly';
|
|
38
38
|
|
|
39
|
-
const
|
|
39
|
+
const isTextType = type !== 'number' && type !== 'password';
|
|
40
|
+
const sizeAttr = size === 'small' ? 'size="small"' : size === 'large' && isTextType ? 'size="large"' : '';
|
|
40
41
|
|
|
41
42
|
const componentName =
|
|
42
43
|
type === 'number' ? 'DsNumberInput' : type === 'password' ? 'DsPasswordInput' : 'DsTextInput';
|
|
@@ -54,7 +55,7 @@ export default {
|
|
|
54
55
|
: type === 'password'
|
|
55
56
|
? figma.code`<DsPasswordInput ${sizeAttr} ${disabled ? 'disabled' : ''} />`
|
|
56
57
|
: figma.code`<DsTextInput ${sizeAttr} ${disabled ? 'disabled' : ''} ${readOnly ? 'readOnly' : ''} />`,
|
|
57
|
-
imports: [`import { ${componentName} } from '@drivenets/design-system'
|
|
58
|
+
imports: [`import { ${componentName} } from '@drivenets/design-system';`],
|
|
58
59
|
id: 'ds-text-input',
|
|
59
60
|
metadata: { nestable: true, props: { fcMember, fcProps } },
|
|
60
|
-
};
|
|
61
|
+
} satisfies figma.Template;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ComponentType } from 'react';
|
|
2
2
|
import type React from 'react';
|
|
3
3
|
|
|
4
|
-
export const textInputSizes = ['small', 'default'] as const;
|
|
4
|
+
export const textInputSizes = ['small', 'default', 'large'] as const;
|
|
5
5
|
export type TextInputSize = (typeof textInputSizes)[number];
|
|
6
6
|
|
|
7
7
|
export interface DsTextInputProps {
|
|
@@ -12,7 +12,7 @@ export default {
|
|
|
12
12
|
example: figma.code`const [value, setValue] = useState<Date | null>(null);
|
|
13
13
|
|
|
14
14
|
<DsTimePicker value={value} onChange={setValue} placeholder="hh:mm AM/PM" />`,
|
|
15
|
-
imports: ["import {
|
|
15
|
+
imports: ["import { DsTimePicker } from '@drivenets/design-system';", "import { useState } from 'react';"],
|
|
16
16
|
id: 'ds-time-picker',
|
|
17
17
|
metadata: { nestable: true, props: { fcMember: 'TimePicker', fcProps: '' } },
|
|
18
|
-
};
|
|
18
|
+
} satisfies figma.Template;
|
|
@@ -26,9 +26,9 @@ createToast({
|
|
|
26
26
|
description: 'Description',${actionsLine}
|
|
27
27
|
});`,
|
|
28
28
|
imports: [
|
|
29
|
-
"import { useToaster } from '@drivenets/design-system'",
|
|
30
|
-
"import { DsButtonV3 } from '@drivenets/design-system'",
|
|
29
|
+
"import { useToaster } from '@drivenets/design-system';",
|
|
30
|
+
"import { DsButtonV3 } from '@drivenets/design-system';",
|
|
31
31
|
],
|
|
32
32
|
id: 'ds-toast',
|
|
33
33
|
metadata: { nestable: false },
|
|
34
|
-
};
|
|
34
|
+
} satisfies figma.Template;
|
|
@@ -33,7 +33,7 @@ const attrs = [
|
|
|
33
33
|
|
|
34
34
|
export default {
|
|
35
35
|
example: figma.code`<DsToggle ${attrs} />`,
|
|
36
|
-
imports: ["import { DsToggle } from '@drivenets/design-system'"],
|
|
36
|
+
imports: ["import { DsToggle } from '@drivenets/design-system';"],
|
|
37
37
|
id: 'ds-toggle',
|
|
38
38
|
metadata: { nestable: true },
|
|
39
|
-
};
|
|
39
|
+
} satisfies figma.Template;
|
|
@@ -10,7 +10,7 @@ const content = labelNode.type === 'TEXT' ? labelNode.textContent : 'Tooltip tex
|
|
|
10
10
|
|
|
11
11
|
export default {
|
|
12
12
|
example: figma.code`<DsTooltip content="${content}">{/* trigger element */}</DsTooltip>`,
|
|
13
|
-
imports: ["import { DsTooltip } from '@drivenets/design-system'"],
|
|
13
|
+
imports: ["import { DsTooltip } from '@drivenets/design-system';"],
|
|
14
14
|
id: 'ds-tooltip',
|
|
15
15
|
metadata: { nestable: false },
|
|
16
|
-
};
|
|
16
|
+
} satisfies figma.Template;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
// url=https://www.figma.com/design/nha3m67y7S57cHCSuQO2gp/DAP-Design-System-1.2?node-id=34873-157787
|
|
2
|
+
// source=https://github.com/drivenets/design-system/tree/main/packages/design-system/src/components/ds-tree
|
|
3
|
+
// component=DsTree
|
|
4
|
+
//
|
|
5
|
+
// `DsTreeV2` is the collection-driven tree. Figma models the branch/item sub-parts
|
|
6
|
+
// (branch-control, branch-text, item-text, indicators, indent guide) as separate
|
|
7
|
+
// components and exposes `side nav` / `map` / `workflows` preview presets via
|
|
8
|
+
// `Property 1`, but code never hand-assembles those parts: it composes `DsTree.Root`
|
|
9
|
+
// with a `createDsTreeCollection` data source and one recursive `DsTree.NodeProvider`
|
|
10
|
+
// renderer. The snippet is the canonical usage referenced by the Storybook docs.
|
|
11
|
+
import figma from 'figma';
|
|
12
|
+
|
|
13
|
+
export default {
|
|
14
|
+
example: figma.code`const collection = createDsTreeCollection([
|
|
15
|
+
{
|
|
16
|
+
id: 'network',
|
|
17
|
+
name: 'Network',
|
|
18
|
+
children: [
|
|
19
|
+
{ id: 'routers', name: 'Routers', children: [{ id: 'router-1', name: 'Router Alpha' }] },
|
|
20
|
+
{ id: 'firewall-1', name: 'Firewall Primary' },
|
|
21
|
+
],
|
|
22
|
+
},
|
|
23
|
+
{ id: 'monitoring', name: 'Monitoring', children: [{ id: 'alerts', name: 'Alerts' }] },
|
|
24
|
+
]);
|
|
25
|
+
|
|
26
|
+
<DsTree.Root collection={collection} defaultExpandedValue={['network']}>
|
|
27
|
+
<DsTree.Tree>
|
|
28
|
+
{collection.rootNode.children?.map((node, index) => (
|
|
29
|
+
<DsTree.NodeProvider key={node.id} node={node} indexPath={[index]}>
|
|
30
|
+
{node.children ? (
|
|
31
|
+
<DsTree.Branch>
|
|
32
|
+
<DsTree.BranchControl>
|
|
33
|
+
<DsTree.BranchIndicator />
|
|
34
|
+
<DsTree.BranchText>{node.name}</DsTree.BranchText>
|
|
35
|
+
</DsTree.BranchControl>
|
|
36
|
+
<DsTree.BranchContent>
|
|
37
|
+
<DsTree.BranchIndentGuide />
|
|
38
|
+
{/* recurse over node.children with another DsTree.NodeProvider */}
|
|
39
|
+
</DsTree.BranchContent>
|
|
40
|
+
</DsTree.Branch>
|
|
41
|
+
) : (
|
|
42
|
+
<DsTree.Item>
|
|
43
|
+
<DsTree.ItemIndicator />
|
|
44
|
+
<DsTree.ItemText>{node.name}</DsTree.ItemText>
|
|
45
|
+
</DsTree.Item>
|
|
46
|
+
)}
|
|
47
|
+
</DsTree.NodeProvider>
|
|
48
|
+
))}
|
|
49
|
+
</DsTree.Tree>
|
|
50
|
+
</DsTree.Root>`,
|
|
51
|
+
imports: ["import { DsTree, createDsTreeCollection } from '@drivenets/design-system';"],
|
|
52
|
+
id: 'ds-tree',
|
|
53
|
+
metadata: { nestable: false },
|
|
54
|
+
} satisfies figma.Template;
|