@drivenets/design-system 0.17.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.
Files changed (94) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/dist/index.cjs +1727 -701
  3. package/dist/index.d.cts +115 -52
  4. package/dist/index.d.cts.map +1 -1
  5. package/dist/index.d.ts +115 -52
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +1729 -705
  8. package/dist/index.js.map +1 -1
  9. package/dist/index.min.css +1 -1
  10. package/package.json +2 -2
  11. package/src/components/ds-alert-banner/ds-alert-banner-global.figma.ts +49 -0
  12. package/src/components/ds-alert-banner/ds-alert-banner.figma.ts +51 -0
  13. package/src/components/ds-autocomplete/ds-autocomplete.module.scss +15 -4
  14. package/src/components/ds-autocomplete/ds-autocomplete.tsx +10 -3
  15. package/src/components/ds-autocomplete/ds-autocomplete.types.ts +8 -0
  16. package/src/components/ds-button-v3/ds-button-v3.figma.ts +5 -3
  17. package/src/components/ds-button-v3/ds-button-v3.module.scss +84 -17
  18. package/src/components/ds-button-v3/ds-button-v3.tsx +2 -0
  19. package/src/components/ds-button-v3/ds-button-v3.types.ts +11 -2
  20. package/src/components/ds-button-v3/ds-button-v4.figma.ts +121 -0
  21. package/src/components/ds-comment-bubble/ds-comment-bubble.figma.ts +52 -0
  22. package/src/components/ds-comment-card/ds-comment-card.figma.ts +36 -0
  23. package/src/components/ds-comment-indicator/ds-comment-indicator.figma.ts +32 -0
  24. package/src/components/ds-comments-drawer/ds-comments-drawer.figma.ts +19 -0
  25. package/src/components/ds-select/ds-select.figma.ts +2 -1
  26. package/src/components/ds-select/ds-select.tsx +6 -1
  27. package/src/components/ds-select/ds-select.types.ts +2 -1
  28. package/src/components/ds-slider/ds-slider.figma.ts +29 -0
  29. package/src/components/ds-slider/ds-slider.module.scss +104 -0
  30. package/src/components/ds-slider/ds-slider.tsx +118 -0
  31. package/src/components/ds-slider/ds-slider.types.ts +102 -0
  32. package/src/components/ds-slider/ds-slider.utils.ts +14 -0
  33. package/src/components/ds-slider/index.ts +11 -0
  34. package/src/components/ds-smart-tabs/figma/ds-smart-tabs-tab.figma.ts +83 -0
  35. package/src/components/ds-smart-tabs/figma/ds-smart-tabs.figma.ts +23 -0
  36. package/src/components/ds-table/components/ds-table-group-header-cell/ds-table-group-header-cell.module.scss +5 -1
  37. package/src/components/ds-table/components/ds-table-group-header-cell/ds-table-group-header-cell.tsx +15 -3
  38. package/src/components/ds-table/components/ds-table-header/ds-table-header.module.scss +15 -1
  39. package/src/components/ds-table/components/ds-table-header/ds-table-header.tsx +29 -6
  40. package/src/components/ds-table/components/ds-table-resize-handle/ds-table-resize-handle.module.scss +23 -0
  41. package/src/components/ds-table/components/ds-table-resize-handle/ds-table-resize-handle.tsx +218 -0
  42. package/src/components/ds-table/components/ds-table-resize-handle/ds-table-resize-handle.types.ts +14 -0
  43. package/src/components/ds-table/components/ds-table-resize-handle/index.ts +1 -0
  44. package/src/components/ds-table/components/ds-table-resize-overlay/ds-table-resize-overlay.module.scss +18 -0
  45. package/src/components/ds-table/components/ds-table-resize-overlay/ds-table-resize-overlay.tsx +16 -0
  46. package/src/components/ds-table/components/ds-table-resize-overlay/ds-table-resize-overlay.types.ts +13 -0
  47. package/src/components/ds-table/components/ds-table-resize-overlay/index.ts +1 -0
  48. package/src/components/ds-table/components/ds-table-row/ds-table-row.module.scss +1 -1
  49. package/src/components/ds-table/components/ds-table-row/ds-table-row.tsx +9 -2
  50. package/src/components/ds-table/components/ds-table-row-virtualized/ds-table-row-virtualized.module.scss +2 -1
  51. package/src/components/ds-table/components/ds-table-row-virtualized/ds-table-row-virtualized.tsx +9 -2
  52. package/src/components/ds-table/components/edit/cell-editors/ds-table-edit-cell-checkbox.tsx +2 -2
  53. package/src/components/ds-table/components/edit/cell-editors/ds-table-edit-cell-date.tsx +2 -1
  54. package/src/components/ds-table/components/edit/cell-editors/ds-table-edit-cell-number.tsx +2 -1
  55. package/src/components/ds-table/components/edit/cell-editors/ds-table-edit-cell-select.tsx +2 -1
  56. package/src/components/ds-table/components/edit/cell-editors/ds-table-edit-cell-text.tsx +2 -1
  57. package/src/components/ds-table/components/edit/ds-table-editing-cell/ds-table-editing-cell.tsx +12 -3
  58. package/src/components/ds-table/context/ds-table-context.tsx +208 -0
  59. package/src/components/ds-table/ds-table-defaults.ts +42 -0
  60. package/src/components/ds-table/ds-table.module.scss +4 -1
  61. package/src/components/ds-table/ds-table.tsx +139 -214
  62. package/src/components/ds-table/ds-table.types.ts +53 -47
  63. package/src/components/ds-table/grouping/utils/column-group.ts +7 -5
  64. package/src/components/ds-table/hooks/use-cell-editor.ts +5 -1
  65. package/src/components/ds-table/hooks/use-column-resize.ts +385 -0
  66. package/src/components/ds-table/hooks/use-editing-state.ts +190 -0
  67. package/src/components/ds-table/index.ts +1 -0
  68. package/src/components/ds-table/styles/_variables.scss +2 -1
  69. package/src/components/ds-table/utils/column-size-meta.augmentation.ts +16 -0
  70. package/src/components/ds-table/utils/column-size.ts +213 -10
  71. package/src/components/ds-table/utils/column-size.unit.test.ts +213 -0
  72. package/src/components/ds-table/utils/constants.ts +28 -0
  73. package/src/components/ds-table/utils/frozen-body.ts +33 -0
  74. package/src/components/ds-table/utils/frozen-body.unit.test.ts +44 -0
  75. package/src/components/ds-table/utils/table-api.ts +42 -0
  76. package/src/components/ds-table/utils/table-api.unit.test.ts +82 -0
  77. package/src/components/ds-table/utils/table-columns.tsx +119 -0
  78. package/src/components/ds-table/utils/table-columns.unit.test.ts +199 -0
  79. package/src/components/ds-tag/ds-tag.figma.ts +51 -0
  80. package/src/components/ds-tag-filter/ds-tag-filter.figma.ts +16 -0
  81. package/src/components/ds-text-input/ds-input-field-v02.figma.ts +29 -4
  82. package/src/components/ds-text-input/ds-text-input.figma.ts +3 -2
  83. package/src/components/ds-text-input/ds-text-input.tsx +1 -0
  84. package/src/components/ds-text-input/ds-text-input.types.ts +1 -1
  85. package/src/components/ds-tree/ds-tree.figma.ts +54 -0
  86. package/src/components/ds-workspace-layout/ds-workspace-layout.figma.ts +99 -0
  87. package/src/components/ds-workspace-layout/ds-workspace-layout.module.scss +1 -8
  88. package/src/index.ts +1 -0
  89. package/src/styles/_gradients.scss +19 -0
  90. package/src/styles/_root.scss +39 -15
  91. package/src/styles/_typography.scss +1 -0
  92. package/src/styles/shared/_input.scss +10 -0
  93. package/src/styles/styles.scss +1 -0
  94. 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
+ });
@@ -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 = { component: 'DsTextInput', fcMember: 'TextInput', size: true, readOnly: true };
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: { component: 'DsSelect', fcMember: 'Select', invalid: true, data: 'options={[]} value=""' },
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: { component: 'DsAutocomplete', invalid: true, data: 'options={[]}' },
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
- info.size && size === 'small' ? 'size="small"' : '',
98
+ sizeAttr,
74
99
  info.data ?? '',
75
100
  disabled ? 'disabled' : '',
76
101
  info.readOnly && readOnly ? 'readOnly' : '',
@@ -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: 'default',
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 sizeAttr = size === 'small' ? 'size="small"' : '';
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';
@@ -35,6 +35,7 @@ const DsTextInput: FC<DsTextInputProps> = ({
35
35
  {
36
36
  [styles.small]: size === 'small',
37
37
  [styles.default]: size === 'default',
38
+ [styles.large]: size === 'large',
38
39
  },
39
40
  className,
40
41
  );
@@ -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 {
@@ -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;
@@ -0,0 +1,99 @@
1
+ // url=https://www.figma.com/design/nha3m67y7S57cHCSuQO2gp/DAP-Design-System-1.2?node-id=32960-46399
2
+ // source=https://github.com/drivenets/design-system/tree/main/packages/design-system/src/components/ds-workspace-layout
3
+ // component=DsWorkspaceLayout.Header
4
+ //
5
+ // Maps Part_workspace-header_v02 / DAP_workspace-header_v02. Figma `Type` selects the
6
+ // example Header composition; Figma `Status` is ignored (badge always shown).
7
+ // Layout divs are structural only — consumers supply their own header chrome CSS.
8
+ import figma from 'figma';
9
+
10
+ const instance = figma.selectedInstance;
11
+
12
+ const type =
13
+ instance.getEnum('Type', {
14
+ draft: 'draft',
15
+ pending: 'pending',
16
+ running: 'running',
17
+ }) ?? 'draft';
18
+
19
+ const draftHeader = figma.code`<DsWorkspaceLayout.Header>
20
+ {/* left / center / right — style with consumer CSS (flex row) */}
21
+ <div>
22
+ <DsButtonV3 variant="secondary" color="light" size="small" icon="close">
23
+ Close
24
+ </DsButtonV3>
25
+ </div>
26
+ <div>
27
+ <DsTypography variant="body-sm-reg">Untitled Project -23-May-2024 04:47 PM</DsTypography>
28
+ <DsIcon icon="info" size="tiny" />
29
+ <DsStatusBadgeV2 phase="temporary" label="Draft" size="small" />
30
+ </div>
31
+ <div>
32
+ <DsButtonV3 variant="secondary" color="light" size="small">
33
+ Discard
34
+ </DsButtonV3>
35
+ <DsButtonV3 variant="primary" color="light" size="small">
36
+ Save project
37
+ </DsButtonV3>
38
+ <DsButtonV3 variant="tertiary" color="light" size="small" icon="more_vert" aria-label="More actions" />
39
+ </div>
40
+ </DsWorkspaceLayout.Header>`;
41
+
42
+ const pendingHeader = figma.code`<DsWorkspaceLayout.Header>
43
+ {/* left / center / right — style with consumer CSS (flex row) */}
44
+ <div>
45
+ <DsButtonV3 variant="secondary" color="light" size="small" icon="close">
46
+ Close
47
+ </DsButtonV3>
48
+ </div>
49
+ <div>
50
+ <DsTypography variant="body-sm-reg">Untitled Project -23-May-2024 04:47 PM</DsTypography>
51
+ <DsIcon icon="info" size="tiny" />
52
+ <DsStatusBadgeV2 phase="pending" label="Pending" size="small" />
53
+ </div>
54
+ <div>
55
+ <DsButtonV3 variant="secondary" color="light" size="small">
56
+ Discard
57
+ </DsButtonV3>
58
+ <DsButtonV3 variant="primary" color="light" size="small">
59
+ Save project
60
+ </DsButtonV3>
61
+ <DsButtonV3 variant="tertiary" color="light" size="small" icon="more_vert" aria-label="More actions" />
62
+ </div>
63
+ </DsWorkspaceLayout.Header>`;
64
+
65
+ const runningHeader = figma.code`<DsWorkspaceLayout.Header>
66
+ {/* left / center / right — style with consumer CSS (flex row) */}
67
+ <div>
68
+ <DsButtonV3 variant="secondary" color="light" size="small" icon="close">
69
+ Close
70
+ </DsButtonV3>
71
+ <DsButtonV3 variant="secondary" color="light" size="small" icon="keyboard_double_arrow_left">
72
+ Previous
73
+ </DsButtonV3>
74
+ <DsButtonV3 variant="secondary" color="light" size="small">
75
+ Next
76
+ </DsButtonV3>
77
+ </div>
78
+ <div>
79
+ <DsTypography variant="body-sm-reg">Untitled Project -23-May-2024 04:47 PM</DsTypography>
80
+ <DsIcon icon="info" size="tiny" />
81
+ <DsStatusBadgeV2 phase="execution" label="Running" size="small" />
82
+ </div>
83
+ <div>
84
+ <DsIcon icon="history_2" size="small" />
85
+ <DsTypography variant="body-sm-reg">Last update: 2d ago</DsTypography>
86
+ <DsButtonV3 variant="tertiary" color="light" size="small" icon="more_vert" aria-label="More actions" />
87
+ </div>
88
+ </DsWorkspaceLayout.Header>`;
89
+
90
+ const example = type === 'pending' ? pendingHeader : type === 'running' ? runningHeader : draftHeader;
91
+
92
+ export default {
93
+ example,
94
+ imports: [
95
+ "import { DsWorkspaceLayout, DsButtonV3, DsTypography, DsIcon, DsStatusBadgeV2 } from '@drivenets/design-system';",
96
+ ],
97
+ id: 'ds-workspace-layout-header',
98
+ metadata: { nestable: true },
99
+ } satisfies figma.Template;
@@ -1,12 +1,5 @@
1
1
  .root {
2
2
  --ds-workspace-layout-header-height: 54px;
3
- --ds-workspace-layout-header-gradient: radial-gradient(
4
- ellipse at left bottom,
5
- rgba(1, 75, 253, 1) 0%,
6
- rgba(10, 60, 194, 1) 78%,
7
- rgba(16, 51, 160, 1) 89%,
8
- rgba(21, 42, 126, 1) 100%
9
- );
10
3
  --ds-workspace-layout-side-menu-collapsed-width: 60px;
11
4
  --ds-workspace-layout-side-menu-expanded-width: 256px;
12
5
  --ds-workspace-layout-side-menu-padding-top: 28px;
@@ -33,7 +26,7 @@
33
26
  flex-shrink: 0;
34
27
  height: var(--ds-workspace-layout-header-height);
35
28
  padding: 0 var(--sm) 0 var(--lg);
36
- background: var(--ds-workspace-layout-header-gradient);
29
+ background: var(--blue-grad-workspace-header);
37
30
  color: var(--font-on-action);
38
31
  overflow: clip;
39
32
  }
package/src/index.ts CHANGED
@@ -45,6 +45,7 @@ export * from './components/ds-segment-group';
45
45
  export * from './components/ds-select';
46
46
  export * from './components/ds-site-node';
47
47
  export * from './components/ds-skeleton';
48
+ export * from './components/ds-slider';
48
49
  export * from './components/ds-smart-tabs';
49
50
  export * from './components/ds-spinner';
50
51
  export * from './components/ds-split-button';