@drivenets/design-system 0.0.1

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 (242) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/LICENSE +201 -0
  3. package/dist/index.cjs +5394 -0
  4. package/dist/index.css +1 -0
  5. package/dist/index.d.cts +9157 -0
  6. package/dist/index.d.cts.map +1 -0
  7. package/dist/index.d.ts +9157 -0
  8. package/dist/index.d.ts.map +1 -0
  9. package/dist/index.js +5335 -0
  10. package/dist/index.js.map +1 -0
  11. package/package.json +104 -0
  12. package/src/components/ds-alert-banner/ds-alert-banner.module.scss +116 -0
  13. package/src/components/ds-alert-banner/ds-alert-banner.tsx +115 -0
  14. package/src/components/ds-alert-banner/ds-alert-banner.types.tsx +47 -0
  15. package/src/components/ds-alert-banner/index.tsx +2 -0
  16. package/src/components/ds-breadcrumb/ds-breadcrumb.module.scss +99 -0
  17. package/src/components/ds-breadcrumb/ds-breadcrumb.tsx +94 -0
  18. package/src/components/ds-breadcrumb/ds-breadcrumb.types.tsx +32 -0
  19. package/src/components/ds-breadcrumb/index.tsx +2 -0
  20. package/src/components/ds-button/ds-button.tsx +12 -0
  21. package/src/components/ds-button/ds-button.types.ts +6 -0
  22. package/src/components/ds-button/index.ts +2 -0
  23. package/src/components/ds-button/versions/ds-button-legacy/ds-button-legacy.module.scss +257 -0
  24. package/src/components/ds-button/versions/ds-button-legacy/ds-button-legacy.tsx +34 -0
  25. package/src/components/ds-button/versions/ds-button-legacy/ds-button-legacy.types.ts +41 -0
  26. package/src/components/ds-button/versions/ds-button-legacy/index.ts +2 -0
  27. package/src/components/ds-button/versions/ds-button-new/ds-button-new.module.scss +580 -0
  28. package/src/components/ds-button/versions/ds-button-new/ds-button-new.tsx +49 -0
  29. package/src/components/ds-button/versions/ds-button-new/ds-button-new.types.ts +41 -0
  30. package/src/components/ds-button/versions/ds-button-new/index.ts +2 -0
  31. package/src/components/ds-checkbox/ds-checkbox.module.scss +130 -0
  32. package/src/components/ds-checkbox/ds-checkbox.tsx +55 -0
  33. package/src/components/ds-checkbox/ds-checkbox.types.tsx +27 -0
  34. package/src/components/ds-checkbox/index.tsx +2 -0
  35. package/src/components/ds-chip/ds-chip.module.scss +71 -0
  36. package/src/components/ds-chip/ds-chip.tsx +73 -0
  37. package/src/components/ds-chip/ds-chip.types.tsx +46 -0
  38. package/src/components/ds-chip/index.tsx +2 -0
  39. package/src/components/ds-chip-group/ds-chip-group.module.scss +59 -0
  40. package/src/components/ds-chip-group/ds-chip-group.tsx +122 -0
  41. package/src/components/ds-chip-group/ds-chip-group.types.ts +52 -0
  42. package/src/components/ds-chip-group/hooks/use-chip-row-calculation.ts +76 -0
  43. package/src/components/ds-chip-group/index.ts +2 -0
  44. package/src/components/ds-confirmation/ds-confirmation.module.scss +58 -0
  45. package/src/components/ds-confirmation/ds-confirmation.tsx +121 -0
  46. package/src/components/ds-confirmation/ds-confirmation.types.tsx +28 -0
  47. package/src/components/ds-confirmation/index.ts +2 -0
  48. package/src/components/ds-dialog/ds-dialog.module.scss +50 -0
  49. package/src/components/ds-dialog/ds-dialog.tsx +70 -0
  50. package/src/components/ds-dialog/ds-dialog.types.tsx +48 -0
  51. package/src/components/ds-dialog/index.tsx +2 -0
  52. package/src/components/ds-drawer/ds-drawer.module.scss +212 -0
  53. package/src/components/ds-drawer/ds-drawer.tsx +160 -0
  54. package/src/components/ds-drawer/ds-drawer.types.tsx +54 -0
  55. package/src/components/ds-drawer/index.ts +2 -0
  56. package/src/components/ds-dropdown-menu/ds-dropdown-menu.module.scss +123 -0
  57. package/src/components/ds-dropdown-menu/ds-dropdown-menu.tsx +396 -0
  58. package/src/components/ds-dropdown-menu/ds-dropdown-menu.types.tsx +262 -0
  59. package/src/components/ds-dropdown-menu/index.tsx +2 -0
  60. package/src/components/ds-expandable-text-input/ds-expandable-text-input.module.scss +70 -0
  61. package/src/components/ds-expandable-text-input/ds-expandable-text-input.tsx +106 -0
  62. package/src/components/ds-expandable-text-input/ds-expandable-text-input.types.tsx +19 -0
  63. package/src/components/ds-expandable-text-input/index.ts +2 -0
  64. package/src/components/ds-file-upload/components/file-upload/file-upload.module.scss +90 -0
  65. package/src/components/ds-file-upload/components/file-upload/file-upload.tsx +106 -0
  66. package/src/components/ds-file-upload/components/file-upload/file-upload.types.tsx +94 -0
  67. package/src/components/ds-file-upload/components/file-upload/index.ts +2 -0
  68. package/src/components/ds-file-upload/components/file-upload-item/file-upload-item.module.scss +125 -0
  69. package/src/components/ds-file-upload/components/file-upload-item/file-upload-item.tsx +143 -0
  70. package/src/components/ds-file-upload/components/file-upload-item/file-upload-item.types.tsx +26 -0
  71. package/src/components/ds-file-upload/components/file-upload-item/index.ts +2 -0
  72. package/src/components/ds-file-upload/ds-file-upload-api.types.ts +38 -0
  73. package/src/components/ds-file-upload/ds-file-upload.tsx +46 -0
  74. package/src/components/ds-file-upload/ds-file-upload.types.tsx +54 -0
  75. package/src/components/ds-file-upload/errors/file-upload-errors.ts +27 -0
  76. package/src/components/ds-file-upload/hooks/index.ts +2 -0
  77. package/src/components/ds-file-upload/hooks/use-file-upload.ts +350 -0
  78. package/src/components/ds-file-upload/index.ts +7 -0
  79. package/src/components/ds-file-upload/types/accept-types.ts +106 -0
  80. package/src/components/ds-file-upload/utils/accept-utils.ts +25 -0
  81. package/src/components/ds-file-upload/utils/constants.ts +21 -0
  82. package/src/components/ds-file-upload/utils/file-factory.ts +18 -0
  83. package/src/components/ds-file-upload/utils/format-file-size.ts +15 -0
  84. package/src/components/ds-file-upload/utils/generate-helper-text.ts +39 -0
  85. package/src/components/ds-file-upload/utils/get-error-message.ts +17 -0
  86. package/src/components/ds-file-upload/utils/is-file-equal.ts +8 -0
  87. package/src/components/ds-form-control/ds-form-control.module.scss +135 -0
  88. package/src/components/ds-form-control/ds-form-control.tsx +94 -0
  89. package/src/components/ds-form-control/ds-form-control.types.tsx +58 -0
  90. package/src/components/ds-form-control/index.tsx +2 -0
  91. package/src/components/ds-grid/ds-grid.module.scss +0 -0
  92. package/src/components/ds-grid/ds-grid.tsx +43 -0
  93. package/src/components/ds-grid/ds-grid.types.ts +55 -0
  94. package/src/components/ds-grid/index.ts +2 -0
  95. package/src/components/ds-icon/ds-icon.module.scss +25 -0
  96. package/src/components/ds-icon/ds-icon.tsx +33 -0
  97. package/src/components/ds-icon/ds-icon.types.ts +53 -0
  98. package/src/components/ds-icon/index.ts +2 -0
  99. package/src/components/ds-icon/material-icons.ts +6203 -0
  100. package/src/components/ds-modal/ds-modal.module.scss +100 -0
  101. package/src/components/ds-modal/ds-modal.tsx +136 -0
  102. package/src/components/ds-modal/ds-modal.types.tsx +44 -0
  103. package/src/components/ds-modal/index.tsx +2 -0
  104. package/src/components/ds-number-input/ds-number-input.module.scss +15 -0
  105. package/src/components/ds-number-input/ds-number-input.tsx +74 -0
  106. package/src/components/ds-number-input/ds-number-input.types.tsx +76 -0
  107. package/src/components/ds-number-input/index.tsx +2 -0
  108. package/src/components/ds-panel/ds-panel.module.scss +95 -0
  109. package/src/components/ds-panel/ds-panel.tsx +46 -0
  110. package/src/components/ds-panel/ds-panel.types.ts +17 -0
  111. package/src/components/ds-panel/index.tsx +2 -0
  112. package/src/components/ds-password-input/ds-password-input.module.scss +10 -0
  113. package/src/components/ds-password-input/ds-password-input.tsx +67 -0
  114. package/src/components/ds-password-input/ds-password-input.types.tsx +62 -0
  115. package/src/components/ds-password-input/index.tsx +2 -0
  116. package/src/components/ds-popover/ds-popover.module.scss +23 -0
  117. package/src/components/ds-popover/ds-popover.tsx +33 -0
  118. package/src/components/ds-popover/ds-popover.types.tsx +24 -0
  119. package/src/components/ds-popover/index.tsx +2 -0
  120. package/src/components/ds-radio-group/ds-radio-group.module.scss +138 -0
  121. package/src/components/ds-radio-group/ds-radio-group.tsx +115 -0
  122. package/src/components/ds-radio-group/ds-radio-group.types.tsx +93 -0
  123. package/src/components/ds-radio-group/index.tsx +2 -0
  124. package/src/components/ds-select/ds-select.module.scss +66 -0
  125. package/src/components/ds-select/ds-select.tsx +239 -0
  126. package/src/components/ds-select/ds-select.types.tsx +80 -0
  127. package/src/components/ds-select/index.tsx +2 -0
  128. package/src/components/ds-select/select-items-chips.tsx +56 -0
  129. package/src/components/ds-smart-tabs/ds-smart-tabs.module.scss +69 -0
  130. package/src/components/ds-smart-tabs/ds-smart-tabs.tsx +113 -0
  131. package/src/components/ds-smart-tabs/ds-smart-tabs.types.tsx +74 -0
  132. package/src/components/ds-smart-tabs/index.tsx +2 -0
  133. package/src/components/ds-spinner/ds-spinner.module.scss +39 -0
  134. package/src/components/ds-spinner/ds-spinner.tsx +51 -0
  135. package/src/components/ds-spinner/ds-spinner.types.tsx +20 -0
  136. package/src/components/ds-spinner/index.tsx +2 -0
  137. package/src/components/ds-status-badge/ds-status-badge.module.scss +79 -0
  138. package/src/components/ds-status-badge/ds-status-badge.tsx +42 -0
  139. package/src/components/ds-status-badge/ds-status-badge.types.tsx +46 -0
  140. package/src/components/ds-status-badge/index.tsx +2 -0
  141. package/src/components/ds-stepper/components/ds-step-content.tsx +32 -0
  142. package/src/components/ds-stepper/components/ds-step-description.tsx +6 -0
  143. package/src/components/ds-stepper/components/ds-step-label.tsx +6 -0
  144. package/src/components/ds-stepper/components/ds-step-next-button.tsx +13 -0
  145. package/src/components/ds-stepper/components/ds-step.tsx +59 -0
  146. package/src/components/ds-stepper/ds-stepper.module.scss +134 -0
  147. package/src/components/ds-stepper/ds-stepper.tsx +34 -0
  148. package/src/components/ds-stepper/ds-stepper.types.ts +12 -0
  149. package/src/components/ds-stepper/hooks/use-stepper.ts +20 -0
  150. package/src/components/ds-stepper/hooks/use-steps.ts +18 -0
  151. package/src/components/ds-stepper/index.tsx +6 -0
  152. package/src/components/ds-system-status/ds-system-status.module.scss +87 -0
  153. package/src/components/ds-system-status/ds-system-status.tsx +33 -0
  154. package/src/components/ds-system-status/ds-system-status.types.tsx +37 -0
  155. package/src/components/ds-system-status/index.tsx +10 -0
  156. package/src/components/ds-table/components/core-table/core-table.module.scss +32 -0
  157. package/src/components/ds-table/components/core-table/core-table.tsx +83 -0
  158. package/src/components/ds-table/components/core-table/index.ts +1 -0
  159. package/src/components/ds-table/components/ds-table-bulk-actions/ds-table-bulk-actions.module.scss +115 -0
  160. package/src/components/ds-table/components/ds-table-bulk-actions/ds-table-bulk-actions.tsx +70 -0
  161. package/src/components/ds-table/components/ds-table-bulk-actions/ds-table-bulk-actions.types.ts +41 -0
  162. package/src/components/ds-table/components/ds-table-bulk-actions/index.ts +2 -0
  163. package/src/components/ds-table/components/ds-table-cell/ds-table-cell.module.scss +53 -0
  164. package/src/components/ds-table/components/ds-table-cell/ds-table-cell.tsx +95 -0
  165. package/src/components/ds-table/components/ds-table-cell/ds-table-cell.types.ts +67 -0
  166. package/src/components/ds-table/components/ds-table-cell/index.ts +2 -0
  167. package/src/components/ds-table/components/ds-table-header/ds-table-header.module.scss +81 -0
  168. package/src/components/ds-table/components/ds-table-header/ds-table-header.tsx +99 -0
  169. package/src/components/ds-table/components/ds-table-header/ds-table-header.types.ts +11 -0
  170. package/src/components/ds-table/components/ds-table-header/index.ts +2 -0
  171. package/src/components/ds-table/components/ds-table-row/ds-table-row.module.scss +137 -0
  172. package/src/components/ds-table/components/ds-table-row/ds-table-row.tsx +205 -0
  173. package/src/components/ds-table/components/ds-table-row/ds-table-row.types.ts +22 -0
  174. package/src/components/ds-table/components/ds-table-row/index.ts +2 -0
  175. package/src/components/ds-table/context/ds-table-context.tsx +39 -0
  176. package/src/components/ds-table/ds-table.module.scss +60 -0
  177. package/src/components/ds-table/ds-table.tsx +312 -0
  178. package/src/components/ds-table/ds-table.types.ts +377 -0
  179. package/src/components/ds-table/filters/adapters/create-checkbox-filter-adapter.tsx +116 -0
  180. package/src/components/ds-table/filters/adapters/create-dual-range-filter-adapter.tsx +171 -0
  181. package/src/components/ds-table/filters/adapters/create-filter-adapter.ts +131 -0
  182. package/src/components/ds-table/filters/adapters/index.ts +12 -0
  183. package/src/components/ds-table/filters/components/checkbox-filter/checkbox-filter.tsx +43 -0
  184. package/src/components/ds-table/filters/components/checkbox-filter/index.ts +2 -0
  185. package/src/components/ds-table/filters/components/range-filter/index.ts +2 -0
  186. package/src/components/ds-table/filters/components/range-filter/range-filter.module.scss +25 -0
  187. package/src/components/ds-table/filters/components/range-filter/range-filter.tsx +79 -0
  188. package/src/components/ds-table/filters/hooks/index.ts +1 -0
  189. package/src/components/ds-table/filters/hooks/use-table-filters.ts +234 -0
  190. package/src/components/ds-table/filters/index.ts +50 -0
  191. package/src/components/ds-table/filters/types/filter-adapter.types.ts +111 -0
  192. package/src/components/ds-table/hooks/use-drag-and-drop.tsx +107 -0
  193. package/src/components/ds-table/index.ts +4 -0
  194. package/src/components/ds-table/styles/_variables.scss +17 -0
  195. package/src/components/ds-table/styles/shared/ds-table-shared.module.scss +16 -0
  196. package/src/components/ds-table/utils/column-styling.ts +30 -0
  197. package/src/components/ds-table/utils/create-columns-grid-template.ts +23 -0
  198. package/src/components/ds-table/utils/merge-refs.ts +15 -0
  199. package/src/components/ds-table/utils/story-data-generator.ts +91 -0
  200. package/src/components/ds-text-input/ds-text-input.module.scss +27 -0
  201. package/src/components/ds-text-input/ds-text-input.tsx +75 -0
  202. package/src/components/ds-text-input/ds-text-input.types.tsx +110 -0
  203. package/src/components/ds-text-input/index.ts +2 -0
  204. package/src/components/ds-textarea/ds-textarea.module.scss +5 -0
  205. package/src/components/ds-textarea/ds-textarea.tsx +49 -0
  206. package/src/components/ds-textarea/ds-textarea.types.tsx +67 -0
  207. package/src/components/ds-textarea/index.tsx +2 -0
  208. package/src/components/ds-toast/ds-toast-context.tsx +79 -0
  209. package/src/components/ds-toast/ds-toast.module.scss +134 -0
  210. package/src/components/ds-toast/ds-toast.tsx +54 -0
  211. package/src/components/ds-toast/ds-toast.types.tsx +53 -0
  212. package/src/components/ds-toast/index.ts +3 -0
  213. package/src/components/ds-tooltip/ds-tooltip.module.scss +19 -0
  214. package/src/components/ds-tooltip/ds-tooltip.tsx +33 -0
  215. package/src/components/ds-tooltip/ds-tooltip.types.tsx +12 -0
  216. package/src/components/ds-tooltip/index.tsx +2 -0
  217. package/src/components/ds-typography/ds-typography.config.ts +32 -0
  218. package/src/components/ds-typography/ds-typography.module.scss +93 -0
  219. package/src/components/ds-typography/ds-typography.tsx +27 -0
  220. package/src/components/ds-typography/ds-typography.types.tsx +27 -0
  221. package/src/components/ds-typography/index.tsx +2 -0
  222. package/src/components/ds-vertical-tabs/ds-vertical-tabs.module.scss +60 -0
  223. package/src/components/ds-vertical-tabs/ds-vertical-tabs.tsx +80 -0
  224. package/src/components/ds-vertical-tabs/ds-vertical-tabs.types.ts +69 -0
  225. package/src/components/ds-vertical-tabs/index.ts +7 -0
  226. package/src/index.ts +34 -0
  227. package/src/styles/_colors.scss +65 -0
  228. package/src/styles/_grid.scss +111 -0
  229. package/src/styles/_mixin.scss +1 -0
  230. package/src/styles/_reset.scss +38 -0
  231. package/src/styles/_root.scss +390 -0
  232. package/src/styles/_scrollbars.scss +41 -0
  233. package/src/styles/_spacing.scss +47 -0
  234. package/src/styles/_typography.scss +301 -0
  235. package/src/styles/_utilities.scss +33 -0
  236. package/src/styles/_variables.scss +44 -0
  237. package/src/styles/mixins/_bounding-box.scss +53 -0
  238. package/src/styles/mixins/_list.scss +74 -0
  239. package/src/styles/shared/_dropdown.scss +89 -0
  240. package/src/styles/shared/_input.scss +365 -0
  241. package/src/styles/shared/_modal.scss +123 -0
  242. package/src/styles/styles.scss +12 -0
@@ -0,0 +1,130 @@
1
+ @use '../../styles/typography';
2
+
3
+ .container {
4
+ position: relative;
5
+ display: flex;
6
+ align-items: center;
7
+ gap: 4px;
8
+ padding-right: 1px;
9
+ border: 1px solid transparent;
10
+ border-radius: 4px;
11
+
12
+ &:has([data-disabled]) {
13
+ cursor: not-allowed;
14
+ pointer-events: none;
15
+
16
+ .labelInfo {
17
+ color: var(--color-font-disabled);
18
+ }
19
+ }
20
+
21
+ &:has(.checkboxRoot:focus-visible) {
22
+ border-color: var(--color-background-selected);
23
+ }
24
+
25
+ &:has([data-state='unchecked']:focus-visible) {
26
+ border-color: var(--color-background-selected-hover);
27
+ }
28
+ }
29
+
30
+ .checkboxRoot {
31
+ all: unset;
32
+ position: relative;
33
+ border-radius: 2px;
34
+ display: flex;
35
+ align-items: center;
36
+ justify-content: center;
37
+ transition: all 0.2s ease-in-out;
38
+ cursor: pointer;
39
+
40
+ &[data-disabled] {
41
+ border-color: var(--color-background-disable);
42
+ pointer-events: none;
43
+
44
+ &[data-state='unchecked'] {
45
+ .checkboxWrapper {
46
+ border-color: var(--color-background-disable);
47
+ }
48
+ }
49
+
50
+ &[data-state='checked'],
51
+ &[data-state='indeterminate'] {
52
+ .checkboxWrapper {
53
+ border-color: var(--color-background-disable);
54
+ background-color: var(--color-background-disable);
55
+ }
56
+ }
57
+ }
58
+
59
+ &[data-state='checked'] {
60
+ .checkboxWrapper {
61
+ border-color: var(--color-background-selected);
62
+ background-color: var(--color-background-selected);
63
+ }
64
+
65
+ &:hover {
66
+ background: var(--color-background-action-secondary-hover);
67
+ }
68
+ }
69
+
70
+ &[data-state='unchecked'] {
71
+ .checkboxWrapper {
72
+ border-color: var(--color-background-deselected);
73
+ }
74
+
75
+ &:hover {
76
+ background: var(--color-background-action-hover-weak);
77
+ }
78
+ }
79
+
80
+ &[data-state='indeterminate'] {
81
+ .checkboxWrapper {
82
+ border-color: var(--color-background-selected);
83
+ background-color: var(--color-background-selected);
84
+ }
85
+
86
+ &:hover {
87
+ background: var(--color-background-action-secondary-hover);
88
+ }
89
+ }
90
+
91
+ .checkboxWrapper {
92
+ display: flex;
93
+ flex-direction: column;
94
+ justify-content: center;
95
+ align-items: center;
96
+ height: 16px;
97
+ width: 16px;
98
+ margin: var(--spacing-4xs);
99
+ border: 2px solid transparent;
100
+ border-radius: 2px;
101
+ }
102
+ }
103
+
104
+ .checkboxIndicator {
105
+ flex: 1;
106
+ color: white;
107
+ display: flex;
108
+ align-items: center;
109
+ justify-content: center;
110
+
111
+ svg {
112
+ width: 100%;
113
+ height: 100%;
114
+ }
115
+ }
116
+
117
+ .label {
118
+ @include typography.body-sm-reg;
119
+ color: var(--color-font-main);
120
+ cursor: pointer;
121
+ }
122
+
123
+ .labelInfo {
124
+ @include typography.body-xs-reg;
125
+ @include typography.ellipsis;
126
+ position: absolute;
127
+ color: var(--color-font-secondary);
128
+ cursor: pointer;
129
+ width: 100%;
130
+ }
@@ -0,0 +1,55 @@
1
+ import type React from 'react';
2
+ import { useId } from 'react';
3
+ import * as CheckboxPrimitive from '@radix-ui/react-checkbox';
4
+ import classNames from 'classnames';
5
+ import styles from './ds-checkbox.module.scss';
6
+ import type { DsCheckboxProps } from './ds-checkbox.types';
7
+ import { DsIcon } from '../ds-icon';
8
+
9
+ /**
10
+ * Design system Checkbox component
11
+ */
12
+ const DsCheckbox: React.FC<DsCheckboxProps> = ({
13
+ id,
14
+ label,
15
+ labelInfo,
16
+ className,
17
+ checked,
18
+ defaultChecked,
19
+ onCheckedChange,
20
+ ...props
21
+ }) => {
22
+ const generatedId = useId();
23
+ const checkboxId = id || generatedId;
24
+
25
+ return (
26
+ <div className={classNames(styles.container, className)}>
27
+ <CheckboxPrimitive.Root
28
+ className={styles.checkboxRoot}
29
+ id={checkboxId}
30
+ checked={checked}
31
+ defaultChecked={defaultChecked}
32
+ onCheckedChange={onCheckedChange}
33
+ {...props}
34
+ >
35
+ <div className={styles.checkboxWrapper}>
36
+ <CheckboxPrimitive.Indicator className={styles.checkboxIndicator}>
37
+ <DsIcon
38
+ icon={checked === 'indeterminate' ? 'check_indeterminate_small' : 'check_small'}
39
+ size="small"
40
+ variant="outlined"
41
+ />
42
+ </CheckboxPrimitive.Indicator>
43
+ </div>
44
+ </CheckboxPrimitive.Root>
45
+ {label && (
46
+ <label className={styles.label} htmlFor={checkboxId}>
47
+ {label}
48
+ {labelInfo && <div className={styles.labelInfo}>{labelInfo}</div>}
49
+ </label>
50
+ )}
51
+ </div>
52
+ );
53
+ };
54
+
55
+ export default DsCheckbox;
@@ -0,0 +1,27 @@
1
+ import type { ComponentPropsWithoutRef, ReactNode } from 'react';
2
+ import type { Root } from '@radix-ui/react-checkbox';
3
+
4
+ export interface DsCheckboxProps extends ComponentPropsWithoutRef<typeof Root> {
5
+ /**
6
+ * Label for the checkbox
7
+ */
8
+ label?: ReactNode;
9
+ /**
10
+ * Additional label info for the checkbox
11
+ */
12
+ labelInfo?: ReactNode;
13
+ /**
14
+ * The controlled checked state of the checkbox
15
+ */
16
+ checked?: boolean | 'indeterminate';
17
+ /**
18
+ * The default checked state of the checkbox
19
+ */
20
+ defaultChecked?: boolean | 'indeterminate';
21
+ /**
22
+ * Event handler called when the checked state of the checkbox changes.
23
+ *
24
+ * @param checked
25
+ */
26
+ onCheckedChange?: (checked: boolean | 'indeterminate') => void;
27
+ }
@@ -0,0 +1,2 @@
1
+ export { default as DsCheckbox } from './ds-checkbox';
2
+ export * from './ds-checkbox.types';
@@ -0,0 +1,71 @@
1
+ @use '../../styles/typography';
2
+
3
+ .chip {
4
+ display: inline-flex;
5
+ align-items: center;
6
+ gap: var(--spacing-3xs);
7
+ padding: 1px var(--spacing-3xs) 1px var(--spacing-xs);
8
+ background: var(--color-background);
9
+ border: 1px solid var(--color-border-contrast);
10
+ border-radius: 100vmax;
11
+ color: var(--color-font-main);
12
+ cursor: default;
13
+ overflow: hidden;
14
+ transition:
15
+ background-color 0.2s,
16
+ border-color 0.2s,
17
+ color 0.2s;
18
+
19
+ &.clickable {
20
+ cursor: pointer;
21
+
22
+ &:hover {
23
+ background: var(--color-background-action-hover-weak);
24
+ border-color: var(--color-border-action-secondary-hover);
25
+ }
26
+
27
+ &:focus-visible {
28
+ outline: 2px solid var(--color-background-selected);
29
+ outline-offset: 2px;
30
+ }
31
+ }
32
+
33
+ &.small {
34
+ padding: 0 var(--spacing-4xs) 0 var(--spacing-3xs);
35
+ gap: var(--spacing-4xs);
36
+ }
37
+
38
+ &[aria-pressed='true'] {
39
+ background: var(--color-background-selected-weak);
40
+ border-color: var(--color-border-action-primary);
41
+ color: var(--color-font-action);
42
+ }
43
+ }
44
+
45
+ .label {
46
+ @include typography.ellipsis;
47
+ padding: var(--spacing-4xs) var(--spacing-3xs);
48
+ flex: 1;
49
+ }
50
+
51
+ .deleteButton {
52
+ display: flex;
53
+ align-items: center;
54
+ justify-content: center;
55
+ border: none;
56
+ background: transparent;
57
+ color: var(--color-icon-information-main);
58
+ cursor: pointer;
59
+ transition:
60
+ background-color 0.2s,
61
+ color 0.2s;
62
+ flex-shrink: 0;
63
+
64
+ &:hover {
65
+ color: var(--color-icon-secondary);
66
+ }
67
+
68
+ .chip.small & {
69
+ padding: 1px var(--spacing-4xs);
70
+ }
71
+ }
@@ -0,0 +1,73 @@
1
+ import type React from 'react';
2
+ import classNames from 'classnames';
3
+ import styles from './ds-chip.module.scss';
4
+ import type { DsChipProps } from './ds-chip.types';
5
+ import { DsIcon } from '../ds-icon';
6
+ import { DsTypography } from '../ds-typography';
7
+
8
+ /**
9
+ * Design system Chip component
10
+ */
11
+ const DsChip: React.FC<DsChipProps> = ({
12
+ ref,
13
+ label,
14
+ className,
15
+ style = {},
16
+ onClick,
17
+ onDelete,
18
+ size = 'medium',
19
+ deleteIcon,
20
+ selected = false,
21
+ }) => {
22
+ const chipClass = classNames(
23
+ styles.chip,
24
+ {
25
+ [styles.clickable]: onClick !== undefined,
26
+ [styles.small]: size === 'small',
27
+ },
28
+ className,
29
+ );
30
+
31
+ const handleDeleteClick = (event: React.MouseEvent<HTMLElement>) => {
32
+ event.stopPropagation();
33
+ onDelete?.(event);
34
+ };
35
+
36
+ const handleKeyDown = (event: React.KeyboardEvent<HTMLElement>) => {
37
+ if (onDelete && (event.key === 'Backspace' || event.key === 'Delete')) {
38
+ event.preventDefault();
39
+ onDelete(event);
40
+ }
41
+ };
42
+
43
+ return (
44
+ <div
45
+ ref={ref as React.Ref<HTMLDivElement>}
46
+ className={chipClass}
47
+ style={style}
48
+ onClick={onClick}
49
+ onKeyDown={handleKeyDown}
50
+ role={onClick || onDelete ? 'button' : undefined}
51
+ tabIndex={onClick || onDelete ? 0 : undefined}
52
+ aria-label={label}
53
+ aria-pressed={onClick && selected ? 'true' : undefined}
54
+ >
55
+ <DsTypography variant={size === 'small' ? 'body-xs-reg' : 'body-sm-reg'} className={styles.label}>
56
+ {label}
57
+ </DsTypography>
58
+ {onDelete && (
59
+ <button
60
+ type="button"
61
+ className={styles.deleteButton}
62
+ onClick={handleDeleteClick}
63
+ aria-label="Delete chip"
64
+ tabIndex={-1}
65
+ >
66
+ <DsIcon icon={deleteIcon || 'cancel'} size="tiny" />
67
+ </button>
68
+ )}
69
+ </div>
70
+ );
71
+ };
72
+
73
+ export default DsChip;
@@ -0,0 +1,46 @@
1
+ import type { CSSProperties, KeyboardEvent, MouseEvent, Ref } from 'react';
2
+ import type { IconType } from '../ds-icon';
3
+
4
+ export const chipSizes = ['medium', 'small'] as const;
5
+ export type ChipSize = (typeof chipSizes)[number];
6
+
7
+ export interface DsChipProps {
8
+ /**
9
+ * Ref to the chip element
10
+ */
11
+ ref?: Ref<HTMLElement>;
12
+ /**
13
+ * The label text to display in the chip
14
+ */
15
+ label: string;
16
+ /**
17
+ * Additional CSS class names
18
+ */
19
+ className?: string;
20
+ /**
21
+ * Additional styles to apply to the component
22
+ */
23
+ style?: CSSProperties;
24
+ /**
25
+ * Optional click handler
26
+ */
27
+ onClick?: (event: MouseEvent<HTMLElement>) => void;
28
+ /**
29
+ * Callback function when delete icon is clicked
30
+ */
31
+ onDelete?: (event: MouseEvent<HTMLElement> | KeyboardEvent<HTMLElement>) => void;
32
+ /**
33
+ * Size of the chip
34
+ * @default 'medium'
35
+ */
36
+ size?: ChipSize;
37
+ /**
38
+ * Custom delete icon element
39
+ */
40
+ deleteIcon?: IconType;
41
+ /**
42
+ * Whether the chip is in a selected/pressed state
43
+ * @default false
44
+ */
45
+ selected?: boolean;
46
+ }
@@ -0,0 +1,2 @@
1
+ export { default as DsChip } from './ds-chip';
2
+ export type { ChipSize, DsChipProps } from './ds-chip.types';
@@ -0,0 +1,59 @@
1
+ .container {
2
+ display: flex;
3
+ align-items: center;
4
+ gap: var(--spacing-standard);
5
+ padding: var(--spacing-xs) var(--spacing-standard);
6
+ background: var(--color-background-selected-weak);
7
+ border: 1px solid var(--color-outline-weak);
8
+ border-radius: var(--spacing-3xs);
9
+ }
10
+
11
+ .chipsWrapper {
12
+ display: flex;
13
+ flex: 1;
14
+ flex-wrap: wrap;
15
+ align-items: center;
16
+ gap: var(--spacing-xs);
17
+ max-height: var(--spacing-3xl);
18
+ overflow: hidden;
19
+
20
+ .hidden {
21
+ visibility: hidden;
22
+ position: absolute;
23
+ pointer-events: none;
24
+ }
25
+ }
26
+
27
+ .label {
28
+ color: var(--color-font-secondary);
29
+ white-space: nowrap;
30
+ }
31
+
32
+ .expandChip {
33
+ cursor: pointer;
34
+ }
35
+
36
+ .dialog {
37
+ position: fixed;
38
+ background: var(--color-background);
39
+ border: 1px solid var(--color-border-secondary);
40
+ border-radius: var(--spacing-3xs);
41
+ box-shadow: 0 5px 15px 0 rgba(0, 0, 0, 0.15);
42
+ padding: var(--spacing-xs);
43
+ max-height: 80vh;
44
+ overflow-y: auto;
45
+ z-index: 1001;
46
+ min-width: 300px;
47
+ max-width: 500px;
48
+ }
49
+
50
+ .dialogContent {
51
+ display: flex;
52
+ flex-direction: column;
53
+ gap: 10px;
54
+ }
55
+
56
+ .itemCheckbox {
57
+ display: flex;
58
+ align-items: center;
59
+ }
@@ -0,0 +1,122 @@
1
+ import type React from 'react';
2
+ import { useRef, useState } from 'react';
3
+ import * as RadixDialog from '@radix-ui/react-dialog';
4
+ import { Root as VisuallyHidden } from '@radix-ui/react-visually-hidden';
5
+ import classNames from 'classnames';
6
+ import styles from './ds-chip-group.module.scss';
7
+ import type { DsChipGroupProps } from './ds-chip-group.types';
8
+ import { useChipRowCalculation } from './hooks/use-chip-row-calculation';
9
+ import { DsTypography } from '../ds-typography';
10
+ import DsChip from '../ds-chip/ds-chip';
11
+ import { DsCheckbox } from '../ds-checkbox';
12
+ import { DsButton } from '../ds-button';
13
+ import { DsIcon } from '../ds-icon';
14
+
15
+ /**
16
+ * Design system chip group component displays a collection of chips with overflow handling
17
+ * Used for displaying filters, selected items, tags, etc.
18
+ */
19
+ const DsChipGroup: React.FC<DsChipGroupProps> = ({
20
+ items,
21
+ label = 'Filtered by:',
22
+ onClearAll,
23
+ onItemDelete,
24
+ onItemSelect,
25
+ className,
26
+ style,
27
+ }) => {
28
+ const [dialogOpen, setDialogOpen] = useState(false);
29
+ const showAllChipsRef = useRef<HTMLDivElement>(null);
30
+ const chipsWrapperRef = useRef<HTMLDivElement>(null);
31
+ const visibleCount = useChipRowCalculation({
32
+ chipsWrapperRef,
33
+ totalFilters: items.length,
34
+ });
35
+
36
+ if (items.length === 0) {
37
+ return null;
38
+ }
39
+
40
+ const hiddenCount = items.length - visibleCount;
41
+ const showExpandButton = hiddenCount > 0;
42
+
43
+ const handleOpenDialog = () => {
44
+ setDialogOpen(true);
45
+ };
46
+
47
+ let dialogStyle: React.CSSProperties = {};
48
+ if (showExpandButton && showAllChipsRef.current) {
49
+ const rect = showAllChipsRef.current.getBoundingClientRect();
50
+ dialogStyle = {
51
+ position: 'fixed',
52
+ top: rect.bottom + 4,
53
+ left: rect.left,
54
+ };
55
+ }
56
+
57
+ return (
58
+ <div className={classNames(styles.container, className)} style={style}>
59
+ {label && (
60
+ <DsTypography variant="body-sm-reg" className={styles.label}>
61
+ {label}
62
+ </DsTypography>
63
+ )}
64
+
65
+ <div ref={chipsWrapperRef} className={styles.chipsWrapper}>
66
+ {items.map((item, index) => (
67
+ <DsChip
68
+ key={item.id}
69
+ label={item.label}
70
+ selected={item.selected}
71
+ onClick={() => onItemSelect?.(item)}
72
+ onDelete={() => onItemDelete?.(item)}
73
+ className={classNames({
74
+ [styles.hidden]: index >= visibleCount,
75
+ })}
76
+ />
77
+ ))}
78
+ {showExpandButton && (
79
+ <DsChip
80
+ ref={showAllChipsRef}
81
+ label={`+${String(hiddenCount)} ${hiddenCount === 1 ? 'item' : 'items'} show all`}
82
+ onClick={handleOpenDialog}
83
+ className={styles.expandChip}
84
+ />
85
+ )}
86
+ </div>
87
+
88
+ {onClearAll && (
89
+ <DsButton design="v1.2" buttonType="tertiary" variant="ghost" size="small" onClick={onClearAll}>
90
+ <DsIcon icon="close" />
91
+ Clear all
92
+ </DsButton>
93
+ )}
94
+
95
+ <RadixDialog.Root open={dialogOpen} onOpenChange={setDialogOpen}>
96
+ <VisuallyHidden>
97
+ <RadixDialog.Title />
98
+ </VisuallyHidden>
99
+ <RadixDialog.Portal>
100
+ <RadixDialog.Content style={dialogStyle} className={styles.dialog}>
101
+ <div className={styles.dialogContent}>
102
+ {items
103
+ .filter((item, index) => index >= visibleCount)
104
+ .map((item) => (
105
+ <div key={item.id} className={styles.itemCheckbox}>
106
+ <DsCheckbox
107
+ id={`chip-${item.id}`}
108
+ checked={item.selected}
109
+ onCheckedChange={() => onItemSelect?.(item)}
110
+ label={item.label}
111
+ />
112
+ </div>
113
+ ))}
114
+ </div>
115
+ </RadixDialog.Content>
116
+ </RadixDialog.Portal>
117
+ </RadixDialog.Root>
118
+ </div>
119
+ );
120
+ };
121
+
122
+ export default DsChipGroup;
@@ -0,0 +1,52 @@
1
+ import type { CSSProperties } from 'react';
2
+
3
+ export interface ChipItem {
4
+ /**
5
+ * Unique identifier for the chip
6
+ */
7
+ id: string;
8
+ /**
9
+ * The label text to display in the chip
10
+ */
11
+ label: string;
12
+ /**
13
+ * Additional metadata to store with the chip
14
+ */
15
+ metadata?: Record<string, unknown>;
16
+ /**
17
+ * Whether the chip is selected/checked
18
+ */
19
+ selected?: boolean;
20
+ }
21
+
22
+ export interface DsChipGroupProps {
23
+ /**
24
+ * Array of chip items to display
25
+ */
26
+ items: ChipItem[];
27
+ /**
28
+ * Label text to display before the chips (e.g., "Filtered by:")
29
+ * @default "Filtered by:"
30
+ */
31
+ label?: string;
32
+ /**
33
+ * Callback when "Clear all" is clicked
34
+ */
35
+ onClearAll?: () => void;
36
+ /**
37
+ * Callback when a chip is deleted/unchecked
38
+ */
39
+ onItemDelete?: (item: ChipItem) => void;
40
+ /**
41
+ * Callback when a chip is selected
42
+ */
43
+ onItemSelect?: (item: ChipItem) => void;
44
+ /**
45
+ * Additional CSS class names
46
+ */
47
+ className?: string;
48
+ /**
49
+ * Additional styles to apply to the component
50
+ */
51
+ style?: CSSProperties;
52
+ }