@drivenets/design-system 0.9.0 → 0.10.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 (95) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/dist/index.cjs +1076 -600
  3. package/dist/index.d.cts +1988 -528
  4. package/dist/index.d.cts.map +1 -1
  5. package/dist/index.d.ts +1991 -531
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +1083 -609
  8. package/dist/index.js.map +1 -1
  9. package/dist/index.min.css +1 -1
  10. package/package.json +16 -17
  11. package/src/components/ds-breadcrumb/ds-breadcrumb.types.ts +40 -6
  12. package/src/components/ds-button/ds-button.types.ts +13 -2
  13. package/src/components/ds-button-v3/ds-button-v3.module.scss +108 -109
  14. package/src/components/ds-button-v3/ds-button-v3.tsx +2 -2
  15. package/src/components/ds-button-v3/ds-button-v3.types.ts +19 -3
  16. package/src/components/ds-button-v3/index.ts +5 -1
  17. package/src/components/ds-card/ds-card.types.ts +3 -1
  18. package/src/components/ds-checkbox/ds-checkbox.module.scss +106 -123
  19. package/src/components/ds-checkbox/ds-checkbox.tsx +24 -35
  20. package/src/components/ds-checkbox/ds-checkbox.types.ts +12 -11
  21. package/src/components/ds-checkbox-group/ds-checkbox-group.module.scss +13 -0
  22. package/src/components/ds-checkbox-group/ds-checkbox-group.tsx +20 -0
  23. package/src/components/ds-checkbox-group/ds-checkbox-group.types.ts +8 -0
  24. package/src/components/ds-checkbox-group/hooks/index.ts +6 -0
  25. package/src/components/ds-checkbox-group/hooks/use-checkbox-select-all.ts +65 -0
  26. package/src/components/ds-checkbox-group/index.ts +3 -0
  27. package/src/components/ds-comment-bubble/components/ds-comment-thread/ds-comment-thread.types.ts +26 -0
  28. package/src/components/ds-comment-bubble/components/ds-thread-item/ds-thread-item.types.ts +38 -0
  29. package/src/components/ds-comment-bubble/ds-comment-bubble.types.ts +78 -0
  30. package/src/components/ds-comment-card/ds-comment-card.module.scss +2 -2
  31. package/src/components/ds-comment-card/ds-comment-card.types.ts +114 -0
  32. package/src/components/ds-comment-indicator/ds-comment-indicator.types.ts +26 -0
  33. package/src/components/ds-comments-drawer/comments-filters.types.ts +33 -0
  34. package/src/components/ds-comments-drawer/components/comments-filter-modal/comments-filter-modal.types.ts +37 -1
  35. package/src/components/ds-comments-drawer/ds-comments-drawer.types.ts +64 -0
  36. package/src/components/ds-date-input/ds-date-input.types.ts +23 -0
  37. package/src/components/ds-date-picker/ds-date-picker.tsx +3 -0
  38. package/src/components/ds-date-picker/ds-date-picker.types.ts +20 -0
  39. package/src/components/ds-date-range-picker/ds-date-range-picker.types.ts +28 -0
  40. package/src/components/ds-dialog/ds-dialog.types.ts +10 -1
  41. package/src/components/ds-dropdown-menu/ds-dropdown-menu.types.ts +24 -0
  42. package/src/components/ds-file-upload/components/file-upload/file-upload.types.ts +1 -0
  43. package/src/components/ds-file-upload/ds-file-upload-api.types.ts +55 -0
  44. package/src/components/ds-form-control/ds-form-control.types.ts +3 -0
  45. package/src/components/ds-grid/ds-grid.tsx +29 -12
  46. package/src/components/ds-grid/ds-grid.types.ts +16 -13
  47. package/src/components/ds-grid/index.ts +10 -2
  48. package/src/components/ds-icon/custom-icons/index.ts +2 -0
  49. package/src/components/ds-icon/custom-icons/special-leading-icon.tsx +11 -0
  50. package/src/components/ds-icon/ds-icon.tsx +10 -4
  51. package/src/components/ds-icon/ds-icon.types.ts +30 -0
  52. package/src/components/ds-key-value-pair/ds-key-value-pair.types.ts +12 -2
  53. package/src/components/ds-modal/ds-modal.types.ts +16 -0
  54. package/src/components/ds-panel/ds-panel.types.ts +39 -0
  55. package/src/components/ds-radio-group/ds-radio-group.module.scss +58 -56
  56. package/src/components/ds-radio-group/ds-radio-group.tsx +35 -28
  57. package/src/components/ds-radio-group/ds-radio-group.types.ts +38 -7
  58. package/src/components/ds-segment-group/ds-segment-group.types.ts +17 -0
  59. package/src/components/ds-select/ds-select.types.ts +32 -0
  60. package/src/components/ds-split-button/ds-split-button.module.scss +7 -7
  61. package/src/components/ds-split-button/ds-split-button.types.ts +28 -0
  62. package/src/components/ds-stack/ds-stack.types.ts +23 -0
  63. package/src/components/ds-stepper/ds-stepper.types.ts +34 -1
  64. package/src/components/ds-table/components/ds-table-body-virtualized/ds-table-body-virtualized.types.ts +27 -0
  65. package/src/components/ds-table/components/ds-table-cell/ds-table-cell.tsx +7 -4
  66. package/src/components/ds-table/components/ds-table-cell/ds-table-cell.types.ts +6 -0
  67. package/src/components/ds-table/components/ds-table-row-expandable-cell/ds-table-row-expandable-cell.types.ts +10 -0
  68. package/src/components/ds-table/components/ds-table-row-selectable-cell/ds-table-row-selectable-cell.types.ts +11 -0
  69. package/src/components/ds-table/components/ds-table-row-virtualized/ds-table-row-virtualized.types.ts +27 -0
  70. package/src/components/ds-table/filters/types/filter-adapter.types.ts +6 -0
  71. package/src/components/ds-tag/ds-tag.types.ts +6 -0
  72. package/src/components/ds-tag-filter/ds-tag-filter.types.ts +16 -0
  73. package/src/components/ds-text-input/ds-text-input.types.ts +3 -0
  74. package/src/components/ds-time-picker/components/time-item/time-item.types.ts +19 -0
  75. package/src/components/ds-time-picker/components/time-scroller/time-scroller.types.ts +29 -0
  76. package/src/components/ds-time-picker/ds-time-picker.module.scss +7 -0
  77. package/src/components/ds-time-picker/ds-time-picker.tsx +8 -1
  78. package/src/components/ds-time-picker/ds-time-picker.types.ts +80 -0
  79. package/src/components/ds-tooltip/ds-tooltip.types.ts +6 -0
  80. package/src/components/ds-tree/ds-tree.types.ts +86 -4
  81. package/src/components/ds-typography/ds-typography.config.ts +46 -27
  82. package/src/components/ds-typography/ds-typography.tsx +22 -7
  83. package/src/components/ds-typography/ds-typography.types.ts +15 -4
  84. package/src/components/ds-workspace/ds-workspace.module.scss +55 -0
  85. package/src/components/ds-workspace/ds-workspace.tsx +37 -0
  86. package/src/components/ds-workspace/ds-workspace.types.ts +17 -0
  87. package/src/components/ds-workspace/index.ts +8 -0
  88. package/src/index.ts +2 -0
  89. package/src/styles/_grid.scss +7 -3
  90. package/src/styles/_mixin.scss +2 -2
  91. package/src/styles/_root_new.scss +449 -0
  92. package/src/styles/_scrollbars.scss +6 -1
  93. package/src/styles/shared/_input.scss +0 -2
  94. package/src/styles/styles.scss +1 -0
  95. package/src/styles/_root_updated.scss +0 -593
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@drivenets/design-system",
3
- "version": "0.9.0",
3
+ "version": "0.10.0",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "types": "./dist/index.d.cts",
@@ -36,24 +36,21 @@
36
36
  "directory": "/packages/design-system"
37
37
  },
38
38
  "dependencies": {
39
- "@ark-ui/react": "^5.34.1",
39
+ "@ark-ui/react": "^5.36.1",
40
40
  "@dnd-kit/core": "^6.3.1",
41
41
  "@dnd-kit/modifiers": "^9.0.0",
42
42
  "@dnd-kit/sortable": "^10.0.0",
43
43
  "@dnd-kit/utilities": "^3.2.2",
44
- "@radix-ui/react-checkbox": "^1.3.3",
45
44
  "@radix-ui/react-collapsible": "^1.1.12",
46
45
  "@radix-ui/react-dialog": "^1.1.15",
47
46
  "@radix-ui/react-dropdown-menu": "^2.1.16",
48
47
  "@radix-ui/react-popover": "^1.1.15",
49
- "@radix-ui/react-radio-group": "^1.3.8",
50
- "@radix-ui/react-slot": "^1.2.4",
51
48
  "@radix-ui/react-tooltip": "^1.2.8",
52
49
  "@radix-ui/react-visually-hidden": "^1.2.4",
53
50
  "@tanstack/react-table": "^8.21.3",
54
- "@tanstack/react-virtual": "^3.13.23",
55
- "@zag-js/react": "^1.37.0",
56
- "@zag-js/steps": "^1.37.0",
51
+ "@tanstack/react-virtual": "^3.13.24",
52
+ "@zag-js/react": "^1.40.0",
53
+ "@zag-js/steps": "^1.40.0",
57
54
  "classnames": "^2.5.1",
58
55
  "csstype": "^3.2.3"
59
56
  },
@@ -79,9 +76,10 @@
79
76
  "@types/eslint-plugin-jsx-a11y": "^6.10.1",
80
77
  "@types/react": "^19.2.14",
81
78
  "@types/react-dom": "^19.2.3",
79
+ "@typescript/native-preview": "7.0.0-dev.20260426.1",
82
80
  "@vitejs/plugin-react": "^6.0.1",
83
81
  "@vitest/browser-playwright": "^4.1.0",
84
- "@vitest/coverage-v8": "^4.1.0",
82
+ "@vitest/coverage-v8": "^4.1.5",
85
83
  "babel-plugin-react-compiler": "^1.0.0",
86
84
  "eslint": "^10.0.1",
87
85
  "eslint-plugin-jsx-a11y": "^6.10.2",
@@ -94,27 +92,29 @@
94
92
  "react": "^19.2.4",
95
93
  "react-dom": "^19.2.4",
96
94
  "react-hook-form": "^7.71.2",
95
+ "remark-gfm": "^4.0.1",
97
96
  "sass-embedded": "^1.97.3",
98
97
  "storybook": "^10.2.19",
99
- "tsdown": "^0.21.6",
98
+ "tsdown": "^0.21.10",
100
99
  "typed-scss-modules": "^8.1.1",
101
- "typescript": "^5.9.3",
100
+ "typescript": "^6.0.3",
102
101
  "typescript-plugin-css-modules": "^5.2.0",
103
102
  "vite": "8.0.5",
104
- "vitest": "^4.1.0",
103
+ "vitest": "^4.1.5",
105
104
  "vitest-browser-react": "^2.1.0",
106
105
  "zod": "^4.3.6",
107
106
  "@drivenets/eslint-plugin-internal": "0.0.0",
108
- "@drivenets/vite-plugin-design-system": "0.0.7"
107
+ "@drivenets/vite-plugin-design-system": "0.0.8"
109
108
  },
110
109
  "scripts": {
110
+ "start": "storybook dev -p 6006",
111
111
  "install:playwright": "pnpm exec playwright install chromium --with-deps",
112
112
  "lint": "pnpm generate-scss-dts && eslint --max-warnings=0 ${ESLINT_ARGS-} .; EXIT_CODE=$?; rm -rf .scss-dts; exit $EXIT_CODE",
113
113
  "//": "ESLINT_ARGS is used to pass arguments to eslint. We're using it so we don't need to duplicate the lint script.",
114
114
  "lint:fix": "ESLINT_ARGS=--fix pnpm lint",
115
- "typecheck": "pnpm generate-scss-dts && tsc; EXIT_CODE=$?; rm -rf .scss-dts; exit $EXIT_CODE",
115
+ "lint:build": "publint && attw --pack",
116
+ "typecheck": "pnpm generate-scss-dts && tsgo; EXIT_CODE=$?; rm -rf .scss-dts; exit $EXIT_CODE",
116
117
  "generate-scss-dts": "typed-scss-modules ./src -o ./.scss-dts --nameFormat all --exportType default > /dev/null 2>&1",
117
- "storybook": "storybook dev -p 6006",
118
118
  "test": "vitest --project=\"!requires-build\"",
119
119
  "test:coverage": "pnpm test --coverage",
120
120
  "test:unit": "vitest --project=unit",
@@ -122,7 +122,6 @@
122
122
  "test:requires-build": "vitest --project=requires-build",
123
123
  "build": "tsdown",
124
124
  "build:watch": "pnpm build --watch",
125
- "build:storybook": "storybook build",
126
- "build:lint": "publint && attw --pack"
125
+ "build:storybook": "storybook build"
127
126
  }
128
127
  }
@@ -2,31 +2,65 @@ import type { IconType } from '../ds-icon';
2
2
 
3
3
  export type DsBreadcrumbItem =
4
4
  | {
5
+ /**
6
+ * Renders the item as a direct navigation link to `href`.
7
+ */
5
8
  type: 'link';
9
+ /**
10
+ * Visible text for the breadcrumb segment
11
+ */
6
12
  label: string;
13
+ /**
14
+ * Destination URL navigated to when the segment is clicked
15
+ */
7
16
  href: string;
17
+ /**
18
+ * Optional icon rendered before the label
19
+ */
8
20
  icon?: IconType;
9
21
  }
10
22
  | {
23
+ /**
24
+ * Renders the item as a dropdown trigger that reveals sibling destinations.
25
+ */
11
26
  type: 'dropdown';
27
+ /**
28
+ * Visible text for the dropdown trigger
29
+ */
12
30
  label: string;
13
- options: { label: string; href: string }[];
31
+ /**
32
+ * Sibling destinations shown in the dropdown. Each option navigates to its
33
+ * `href` when selected.
34
+ */
35
+ options: {
36
+ /**
37
+ * Visible text for the dropdown option
38
+ */
39
+ label: string;
40
+ /**
41
+ * Destination URL navigated to when the option is selected
42
+ */
43
+ href: string;
44
+ }[];
45
+ /**
46
+ * Optional icon rendered before the label
47
+ */
14
48
  icon?: IconType;
15
49
  };
16
50
 
17
51
  export interface DsBreadcrumbProps {
18
52
  /**
19
- * The items to be displayed in the breadcrumb
53
+ * Ordered breadcrumb segments rendered left-to-right. The last item is typically
54
+ * the current page.
20
55
  */
21
56
  items: DsBreadcrumbItem[];
22
57
  /**
23
- * The event handler to be called when an option is selected
24
- *
25
- * @param href
58
+ * Called when the user activates any link segment or picks a destination from a
59
+ * dropdown segment. Receives the selected `href`.
26
60
  */
27
61
  onSelect?: (href: string) => void;
28
62
  /**
29
- * Additional CSS class name to be applied to the breadcrumb
63
+ * Additional CSS class name applied to the breadcrumb root
30
64
  */
31
65
  className?: string;
32
66
  }
@@ -2,5 +2,16 @@ import type { DsButtonProps as DsButtonLegacyProps } from './versions/ds-button-
2
2
  import type { DsButtonProps as DsButtonNewProps } from './versions/ds-button-new/ds-button-new.types';
3
3
 
4
4
  export type DsButtonUnifiedProps =
5
- | (DsButtonLegacyProps & { design?: undefined | 'legacy' })
6
- | (DsButtonNewProps & { design: 'v1.2' });
5
+ | (DsButtonLegacyProps & {
6
+ /**
7
+ * Selects the legacy button implementation. Accepts `DsButtonLegacyProps`.
8
+ * Omit or pass `'legacy'` to opt into this branch.
9
+ */
10
+ design?: undefined | 'legacy';
11
+ })
12
+ | (DsButtonNewProps & {
13
+ /**
14
+ * Selects the new (v1.2) button implementation. Accepts `DsButtonNewProps`.
15
+ */
16
+ design: 'v1.2';
17
+ });
@@ -1,4 +1,3 @@
1
- @use '../../styles/root_updated';
2
1
  @use '../../styles/shared/button' as button;
3
2
 
4
3
  $height-large: 40px;
@@ -98,294 +97,294 @@ $focus-ring-width: 2px;
98
97
  }
99
98
 
100
99
  .root[data-color='default'][data-variant='primary'] {
101
- background-color: var(--background-background-primary);
102
- color: var(--font-font-on-action);
100
+ background-color: var(--background-primary);
101
+ color: var(--font-on-action);
103
102
  border-color: transparent;
104
103
 
105
104
  &:hover:not(:disabled):not(:active):not([data-selected='true']) {
106
- background-color: var(--background-background-primary-hover);
105
+ background-color: var(--background-primary-hover);
107
106
  }
108
107
 
109
108
  &:active:not(:disabled) {
110
- background-color: var(--background-background-primary-selected);
109
+ background-color: var(--background-primary-selected);
111
110
  }
112
111
 
113
112
  &:focus-visible {
114
- @include focus-ring(var(--border-border-action-primary));
113
+ @include focus-ring(var(--border-action-primary));
115
114
 
116
- background-color: var(--background-background-primary-hover);
117
- border-color: var(--border-border-inverse);
115
+ background-color: var(--background-primary-hover);
116
+ border-color: var(--border-inverse);
118
117
  }
119
118
 
120
119
  &[data-selected='true'] {
121
- background-color: var(--background-background-primary-selected);
120
+ background-color: var(--background-primary-selected);
122
121
  }
123
122
 
124
123
  &:disabled:not([data-loading]) {
125
- background-color: var(--background-background-disable);
126
- color: var(--font-font-on-action);
124
+ background-color: var(--background-disable);
125
+ color: var(--font-on-action);
127
126
  }
128
127
  }
129
128
 
130
129
  .root[data-color='default'][data-variant='secondary'] {
131
- background-color: var(--background-background-action-secondary);
132
- color: var(--font-font-main);
133
- border-color: var(--border-border);
130
+ background-color: var(--background-action-secondary);
131
+ color: var(--font-main);
132
+ border-color: var(--border);
134
133
 
135
134
  &:hover:not(:disabled):not(:active):not([data-selected='true']) {
136
- background-color: var(--background-background-secondary-hover);
137
- color: var(--font-font-action-secondary);
138
- border-color: var(--border-border-secondary-hover);
135
+ background-color: var(--background-secondary-hover);
136
+ color: var(--font-action-secondary);
137
+ border-color: var(--border-secondary-hover);
139
138
  }
140
139
 
141
140
  &:active:not(:disabled) {
142
- background-color: var(--background-background-action-secondary-hover);
143
- color: var(--font-font-action-secondary);
144
- border-color: var(--border-border-secondary-hover);
141
+ background-color: var(--background-action-secondary-hover);
142
+ color: var(--font-action-secondary);
143
+ border-color: var(--border-secondary-hover);
145
144
  }
146
145
 
147
146
  &:focus-visible {
148
- @include focus-ring(var(--border-border-action-primary-hover));
147
+ @include focus-ring(var(--border-action-primary-hover));
149
148
 
150
- background-color: var(--background-background-secondary-hover);
151
- border-color: var(--border-border-inverse);
152
- color: var(--font-font-action-secondary);
149
+ background-color: var(--background-secondary-hover);
150
+ border-color: var(--border-inverse);
151
+ color: var(--font-action-secondary);
153
152
  }
154
153
 
155
154
  &[data-selected='true'] {
156
- background-color: var(--background-background-action-secondary-hover);
157
- color: var(--font-font-action-secondary);
158
- border-color: var(--border-border-secondary-hover);
155
+ background-color: var(--background-action-secondary-hover);
156
+ color: var(--font-action-secondary);
157
+ border-color: var(--border-secondary-hover);
159
158
  }
160
159
 
161
160
  &:disabled:not([data-loading]) {
162
- background-color: var(--background-background-action-secondary);
163
- color: var(--font-font-disabled);
164
- border-color: var(--border-border-disabled);
161
+ background-color: var(--background-action-secondary);
162
+ color: var(--font-disabled);
163
+ border-color: var(--border-disabled);
165
164
  }
166
165
  }
167
166
 
168
167
  .root[data-color='default'][data-variant='tertiary'] {
169
168
  background-color: transparent;
170
- color: var(--font-font-main);
169
+ color: var(--font-main);
171
170
  border-color: transparent;
172
171
 
173
172
  &:hover:not(:disabled):not(:active):not([data-selected='true']) {
174
- background-color: var(--background-background-secondary-hover);
175
- color: var(--font-font-action-secondary);
173
+ background-color: var(--background-secondary-hover);
174
+ color: var(--font-action-secondary);
176
175
  }
177
176
 
178
177
  &:active:not(:disabled) {
179
- background-color: var(--background-background-action-secondary-hover);
180
- color: var(--font-font-action-secondary);
178
+ background-color: var(--background-action-secondary-hover);
179
+ color: var(--font-action-secondary);
181
180
  }
182
181
 
183
182
  &:focus-visible {
184
- @include focus-ring(var(--border-border-action-primary-hover));
183
+ @include focus-ring(var(--border-action-primary-hover));
185
184
 
186
- background-color: var(--background-background-secondary-hover);
187
- border-color: var(--border-border-inverse);
188
- color: var(--font-font-action-secondary);
185
+ background-color: var(--background-secondary-hover);
186
+ border-color: var(--border-inverse);
187
+ color: var(--font-action-secondary);
189
188
  }
190
189
 
191
190
  &[data-selected='true'] {
192
- background-color: var(--background-background-action-secondary-hover);
193
- color: var(--font-font-action-secondary);
191
+ background-color: var(--background-action-secondary-hover);
192
+ color: var(--font-action-secondary);
194
193
  }
195
194
 
196
195
  &:disabled:not([data-loading]) {
197
196
  background-color: transparent;
198
- color: var(--font-font-disabled);
197
+ color: var(--font-disabled);
199
198
  }
200
199
  }
201
200
 
202
- .root[data-color='negative'][data-variant='primary'] {
203
- background-color: var(--background-background-negative);
204
- color: var(--font-font-on-action);
201
+ .root[data-color='error'][data-variant='primary'] {
202
+ background-color: var(--background-error);
203
+ color: var(--font-on-action);
205
204
  border-color: transparent;
206
205
 
207
206
  &:hover:not(:disabled):not(:active):not([data-selected='true']) {
208
- background-color: var(--background-background-negative-hover);
207
+ background-color: var(--background-error-hover);
209
208
  }
210
209
 
211
210
  &:active:not(:disabled) {
212
- background-color: var(--background-background-negative-selected);
211
+ background-color: var(--background-error-selected);
213
212
  }
214
213
 
215
214
  &:focus-visible {
216
- @include focus-ring(var(--border-border-negative));
215
+ @include focus-ring(var(--border-error));
217
216
 
218
- background-color: var(--background-background-negative-hover);
219
- border-color: var(--border-border-inverse);
217
+ background-color: var(--background-error-hover);
218
+ border-color: var(--border-inverse);
220
219
  }
221
220
 
222
221
  &[data-selected='true'] {
223
- background-color: var(--background-background-negative-selected);
222
+ background-color: var(--background-error-selected);
224
223
  }
225
224
 
226
225
  &:disabled:not([data-loading]) {
227
- background-color: var(--background-background-disable);
228
- color: var(--font-font-on-action);
226
+ background-color: var(--background-disable);
227
+ color: var(--font-on-action);
229
228
  }
230
229
  }
231
230
 
232
- .root[data-color='negative'][data-variant='secondary'] {
233
- background-color: var(--background-background-action-secondary);
234
- color: var(--font-font-negative);
235
- border-color: var(--border-border-negative);
231
+ .root[data-color='error'][data-variant='secondary'] {
232
+ background-color: var(--background-action-secondary);
233
+ color: var(--font-error);
234
+ border-color: var(--border-error);
236
235
 
237
236
  &:hover:not(:disabled):not(:active):not([data-selected='true']) {
238
- background-color: var(--background-background-negative-secondary-hover);
239
- border-color: var(--border-border-negative-hover);
237
+ background-color: var(--background-error-secondary-hover);
238
+ border-color: var(--border-error-hover);
240
239
  }
241
240
 
242
241
  &:active:not(:disabled) {
243
- background-color: var(--background-background-negative-secondary-selected);
244
- border-color: var(--border-border-negative-hover);
242
+ background-color: var(--background-error-secondary-selected);
243
+ border-color: var(--border-error-hover);
245
244
  }
246
245
 
247
246
  &:focus-visible {
248
- @include focus-ring(var(--border-border-negative));
247
+ @include focus-ring(var(--border-error));
249
248
 
250
- background-color: var(--background-background-negative-secondary-hover);
251
- border-color: var(--border-border-inverse);
249
+ background-color: var(--background-error-secondary-hover);
250
+ border-color: var(--border-inverse);
252
251
  }
253
252
 
254
253
  &[data-selected='true'] {
255
- background-color: var(--background-background-negative-secondary-selected);
256
- border-color: var(--border-border-negative-hover);
254
+ background-color: var(--background-error-secondary-selected);
255
+ border-color: var(--border-error-hover);
257
256
  }
258
257
 
259
258
  &:disabled:not([data-loading]) {
260
- background-color: var(--background-background-action-secondary);
261
- color: var(--font-font-disabled);
262
- border-color: var(--border-border-disabled);
259
+ background-color: var(--background-action-secondary);
260
+ color: var(--font-disabled);
261
+ border-color: var(--border-disabled);
263
262
  }
264
263
  }
265
264
 
266
- .root[data-color='negative'][data-variant='tertiary'] {
265
+ .root[data-color='error'][data-variant='tertiary'] {
267
266
  background-color: transparent;
268
- color: var(--font-font-negative);
267
+ color: var(--font-error);
269
268
  border-color: transparent;
270
269
 
271
270
  &:hover:not(:disabled):not(:active):not([data-selected='true']) {
272
- background-color: var(--background-background-negative-secondary-hover);
271
+ background-color: var(--background-error-secondary-hover);
273
272
  }
274
273
 
275
274
  &:active:not(:disabled) {
276
- background-color: var(--background-background-negative-secondary-selected);
275
+ background-color: var(--background-error-secondary-selected);
277
276
  }
278
277
 
279
278
  &:focus-visible {
280
- @include focus-ring(var(--border-border-negative));
279
+ @include focus-ring(var(--border-error));
281
280
 
282
- background-color: var(--background-background-negative-secondary-hover);
283
- border-color: var(--border-border-inverse);
281
+ background-color: var(--background-error-secondary-hover);
282
+ border-color: var(--border-inverse);
284
283
  }
285
284
 
286
285
  &[data-selected='true'] {
287
- background-color: var(--background-background-negative-secondary-selected);
286
+ background-color: var(--background-error-secondary-selected);
288
287
  }
289
288
 
290
289
  &:disabled:not([data-loading]) {
291
290
  background-color: transparent;
292
- color: var(--font-font-disabled);
291
+ color: var(--font-disabled);
293
292
  }
294
293
  }
295
294
 
296
295
  .root[data-color='light'][data-variant='primary'] {
297
- background-color: var(--background-background-ondark-primary);
298
- color: var(--font-font-on-action);
296
+ background-color: var(--background-ondark-primary);
297
+ color: var(--font-on-action);
299
298
  border-color: transparent;
300
299
 
301
300
  &:hover:not(:disabled):not(:active):not([data-selected='true']) {
302
- background-color: var(--background-background-ondark-primary-hover);
301
+ background-color: var(--background-ondark-primary-hover);
303
302
  }
304
303
 
305
304
  &:active:not(:disabled) {
306
- background-color: var(--background-background-ondark-primary-selected);
305
+ background-color: var(--background-ondark-primary-selected);
307
306
  }
308
307
 
309
308
  &:focus-visible {
310
309
  @include focus-ring(var(--outline-outline-inverse));
311
310
 
312
- background-color: var(--background-background-ondark-primary-hover);
313
- border-color: var(--border-border-action-secondary);
311
+ background-color: var(--background-ondark-primary-hover);
312
+ border-color: var(--border-action-secondary);
314
313
  }
315
314
 
316
315
  &[data-selected='true'] {
317
- background-color: var(--background-background-ondark-primary-selected);
316
+ background-color: var(--background-ondark-primary-selected);
318
317
  }
319
318
 
320
319
  &:disabled:not([data-loading]) {
321
- background-color: var(--background-background-ondark-disabled);
322
- color: var(--font-font-disabled);
320
+ background-color: var(--background-ondark-disabled);
321
+ color: var(--font-disabled);
323
322
  }
324
323
  }
325
324
 
326
325
  .root[data-color='light'][data-variant='secondary'] {
327
326
  background-color: transparent;
328
- color: var(--font-font-on-action);
329
- border-color: var(--border-border-ondark-secondary);
327
+ color: var(--font-on-action);
328
+ border-color: var(--border-ondark-secondary);
330
329
 
331
330
  &:hover:not(:disabled):not(:active):not([data-selected='true']) {
332
- background-color: var(--background-background-ondark-secondary-hover);
333
- color: var(--font-font-on-action);
331
+ background-color: var(--background-ondark-secondary-hover);
332
+ color: var(--font-on-action);
334
333
  }
335
334
 
336
335
  &:active:not(:disabled) {
337
- background-color: var(--background-background-ondark-secondary-selected);
338
- color: var(--font-font-on-action);
336
+ background-color: var(--background-ondark-secondary-selected);
337
+ color: var(--font-on-action);
339
338
  }
340
339
 
341
340
  &:focus-visible {
342
341
  @include focus-ring(var(--outline-outline-inverse));
343
342
 
344
- background-color: var(--background-background-ondark-secondary-hover);
345
- border-color: var(--border-border-action-secondary);
346
- color: var(--font-font-on-action);
343
+ background-color: var(--background-ondark-secondary-hover);
344
+ border-color: var(--border-action-secondary);
345
+ color: var(--font-on-action);
347
346
  }
348
347
 
349
348
  &[data-selected='true'] {
350
- background-color: var(--background-background-ondark-secondary-selected);
349
+ background-color: var(--background-ondark-secondary-selected);
351
350
  }
352
351
 
353
352
  &:disabled:not([data-loading]) {
354
353
  background-color: transparent;
355
- color: var(--font-font-ondark-disabled);
356
- border-color: var(--background-background-ondark-disabled);
354
+ color: var(--font-ondark-disabled);
355
+ border-color: var(--background-ondark-disabled);
357
356
  }
358
357
  }
359
358
 
360
359
  .root[data-color='light'][data-variant='tertiary'] {
361
360
  background-color: transparent;
362
- color: var(--font-font-on-action);
361
+ color: var(--font-on-action);
363
362
  border-color: transparent;
364
363
 
365
364
  &:hover:not(:disabled):not(:active):not([data-selected='true']) {
366
- background-color: var(--background-background-ondark-secondary-hover);
367
- color: var(--font-font-on-action);
365
+ background-color: var(--background-ondark-secondary-hover);
366
+ color: var(--font-on-action);
368
367
  }
369
368
 
370
369
  &:active:not(:disabled) {
371
- background-color: var(--background-background-ondark-secondary-selected);
372
- color: var(--font-font-on-action);
370
+ background-color: var(--background-ondark-secondary-selected);
371
+ color: var(--font-on-action);
373
372
  }
374
373
 
375
374
  &:focus-visible {
376
375
  @include focus-ring(var(--outline-outline-inverse));
377
376
 
378
- background-color: var(--background-background-ondark-secondary-hover);
379
- border-color: var(--border-border-action-secondary);
380
- color: var(--font-font-on-action);
377
+ background-color: var(--background-ondark-secondary-hover);
378
+ border-color: var(--border-action-secondary);
379
+ color: var(--font-on-action);
381
380
  }
382
381
 
383
382
  &[data-selected='true'] {
384
- background-color: var(--background-background-ondark-secondary-selected);
383
+ background-color: var(--background-ondark-secondary-selected);
385
384
  }
386
385
 
387
386
  &:disabled:not([data-loading]) {
388
387
  background-color: transparent;
389
- color: var(--font-font-ondark-disabled);
388
+ color: var(--font-ondark-disabled);
390
389
  }
391
390
  }
@@ -2,7 +2,7 @@ import classNames from 'classnames';
2
2
  import { DsIcon, type IconSize } from '../ds-icon';
3
3
  import { DsSpinner } from '../ds-spinner';
4
4
  import styles from './ds-button-v3.module.scss';
5
- import type { ButtonV3Size, DsButtonV3Props } from './ds-button-v3.types.ts';
5
+ import type { ButtonV3Size, DsButtonV3BaseProps } from './ds-button-v3.types.ts';
6
6
 
7
7
  const iconSizeMap: Record<ButtonV3Size, IconSize> = Object.freeze({
8
8
  large: 'small',
@@ -25,7 +25,7 @@ const DsButtonV3 = ({
25
25
  selected = false,
26
26
  type = 'button',
27
27
  ...rest
28
- }: DsButtonV3Props) => {
28
+ }: DsButtonV3BaseProps) => {
29
29
  const isIconOnly = icon !== undefined && !children;
30
30
 
31
31
  return (
@@ -1,37 +1,45 @@
1
1
  import type { ButtonHTMLAttributes, Ref } from 'react';
2
2
  import type { IconType } from '../ds-icon';
3
+ import type { ResponsiveValue } from '../../utils/responsive';
3
4
 
4
5
  export const buttonV3Variants = ['primary', 'secondary', 'tertiary'] as const;
5
6
  export type ButtonV3Variant = (typeof buttonV3Variants)[number];
6
7
 
7
- export const buttonV3Colors = ['default', 'negative', 'light'] as const;
8
+ export const buttonV3Colors = ['default', 'error', 'light'] as const;
8
9
  export type ButtonV3Color = (typeof buttonV3Colors)[number];
9
10
 
10
11
  export const buttonV3Sizes = ['large', 'medium', 'small', 'tiny'] as const;
11
12
  export type ButtonV3Size = (typeof buttonV3Sizes)[number];
12
13
 
13
- export interface DsButtonV3Props extends ButtonHTMLAttributes<HTMLButtonElement> {
14
+ export interface DsButtonV3BaseProps extends ButtonHTMLAttributes<HTMLButtonElement> {
14
15
  ref?: Ref<HTMLButtonElement>;
15
16
 
16
17
  /**
17
18
  * - `default` — standard light-UI palette
18
- * - `negative` — destructive / danger palette (red tones)
19
+ * - `error` — destructive / danger palette (red tones)
19
20
  * - `light` — palette for dark-background surfaces (Figma **Type** onDark)
20
21
  * @default 'default'
21
22
  */
22
23
  color?: ButtonV3Color;
23
24
 
24
25
  /**
26
+ * Visual variant of the button:
27
+ * - `primary` — filled, highest-emphasis action
28
+ * - `secondary` — outlined, medium-emphasis action
29
+ * - `tertiary` — borderless, low-emphasis action (text-like)
25
30
  * @default 'primary'
26
31
  */
27
32
  variant?: ButtonV3Variant;
28
33
 
29
34
  /**
35
+ * Size of the button. Controls height, padding, font size, and icon size.
30
36
  * @default 'medium'
31
37
  */
32
38
  size?: ButtonV3Size;
33
39
 
34
40
  /**
41
+ * Whether the button is in a selected/pressed state. Used for toggle buttons
42
+ * and segmented controls.
35
43
  * @default false
36
44
  */
37
45
  selected?: boolean;
@@ -47,3 +55,11 @@ export interface DsButtonV3Props extends ButtonHTMLAttributes<HTMLButtonElement>
47
55
  */
48
56
  loading?: boolean;
49
57
  }
58
+
59
+ export interface DsButtonV3Props extends Omit<DsButtonV3BaseProps, 'size'> {
60
+ /**
61
+ * Size of the button. Accepts a static value or a responsive object.
62
+ * @default 'medium'
63
+ */
64
+ size?: ResponsiveValue<ButtonV3Size>;
65
+ }