@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,27 @@
1
+ @use '../../styles/shared/input' as input;
2
+
3
+ .textInputContainer {
4
+ @include input.inputContainer;
5
+ gap: var(--spacing-xs);
6
+ }
7
+
8
+ .input {
9
+ @include input.input;
10
+ }
11
+
12
+ .iconButton {
13
+ @include input.iconButton;
14
+ }
15
+
16
+ .adornment {
17
+ display: flex;
18
+ align-items: center;
19
+
20
+ &:last-child {
21
+ color: var(--form-control-border-color);
22
+ }
23
+
24
+ button {
25
+ @include input.iconButton;
26
+ }
27
+ }
@@ -0,0 +1,75 @@
1
+ import { type ChangeEvent, type FC, Fragment } from 'react';
2
+ import classNames from 'classnames';
3
+ import styles from './ds-text-input.module.scss';
4
+ import type { DsTextInputProps } from './ds-text-input.types';
5
+
6
+ const DsTextInput: FC<DsTextInputProps> = ({
7
+ id,
8
+ ref,
9
+ name,
10
+ size = 'default',
11
+ type = 'text',
12
+ onBlur,
13
+ onKeyDown,
14
+ onChange,
15
+ onValueChange,
16
+ className,
17
+ style = {},
18
+ value,
19
+ defaultValue,
20
+ min,
21
+ max,
22
+ minLength,
23
+ maxLength,
24
+ placeholder,
25
+ disabled = false,
26
+ tabIndex,
27
+ slots,
28
+ }) => {
29
+ const InputWrapper = slots?.inputWrapper ?? Fragment;
30
+
31
+ const containerClass = classNames(
32
+ styles.textInputContainer,
33
+ {
34
+ [styles.small]: size === 'small',
35
+ [styles.default]: size === 'default',
36
+ },
37
+ className,
38
+ );
39
+
40
+ const handleChange = (event: ChangeEvent<HTMLInputElement>) => {
41
+ const newValue = event.target.value;
42
+ onChange?.(event);
43
+ onValueChange?.(newValue);
44
+ };
45
+
46
+ return (
47
+ <div className={containerClass} style={style}>
48
+ {slots?.startAdornment && <div className={styles.adornment}>{slots.startAdornment}</div>}
49
+ <InputWrapper>
50
+ <input
51
+ id={id}
52
+ ref={ref}
53
+ name={name}
54
+ className={classNames(styles.input)}
55
+ type={type}
56
+ value={value}
57
+ defaultValue={defaultValue}
58
+ min={min}
59
+ max={max}
60
+ minLength={minLength}
61
+ maxLength={maxLength}
62
+ placeholder={placeholder}
63
+ disabled={disabled}
64
+ onBlur={onBlur}
65
+ onKeyDown={onKeyDown}
66
+ onChange={handleChange}
67
+ tabIndex={tabIndex}
68
+ />
69
+ </InputWrapper>
70
+ {slots?.endAdornment && <div className={styles.adornment}>{slots.endAdornment}</div>}
71
+ </div>
72
+ );
73
+ };
74
+
75
+ export default DsTextInput;
@@ -0,0 +1,110 @@
1
+ import type { ComponentType } from 'react';
2
+ import type React from 'react';
3
+
4
+ export const textInputSizes = ['small', 'default'] as const;
5
+ export type TextInputSize = (typeof textInputSizes)[number];
6
+
7
+ export interface DsTextInputProps {
8
+ /**
9
+ * Unique identifier for the input field
10
+ */
11
+ id?: string;
12
+ /**
13
+ * The ref to the input field
14
+ */
15
+ ref?: React.Ref<HTMLInputElement>;
16
+ /**
17
+ * The name of the input field
18
+ */
19
+ name?: string;
20
+ /**
21
+ * The size of the input field
22
+ * @default default
23
+ */
24
+ size?: TextInputSize;
25
+ /**
26
+ * The type of the input field
27
+ * @default text
28
+ */
29
+ type?: string;
30
+ /**
31
+ * Event handler called when the input field loses focus
32
+ *
33
+ * @param event
34
+ */
35
+ onBlur?: (event: React.FocusEvent<HTMLInputElement>) => void;
36
+ /**
37
+ * Callback when a key is pressed down
38
+ */
39
+ onKeyDown?: (event: React.KeyboardEvent<HTMLInputElement>) => void;
40
+ /**
41
+ * Callback when the value changes
42
+ */
43
+ onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void;
44
+ /**
45
+ * Value change event handler (provides just the value)
46
+ */
47
+ onValueChange?: (value: string) => void;
48
+ /**
49
+ * Additional CSS class names
50
+ */
51
+ className?: string;
52
+ /**
53
+ * Additional styles to apply to the component
54
+ */
55
+ style?: React.CSSProperties;
56
+ /**
57
+ * The placeholder text
58
+ */
59
+ placeholder?: string;
60
+ /**
61
+ * The current value
62
+ */
63
+ value?: string;
64
+ /**
65
+ * The minimum value of the input
66
+ */
67
+ min?: number | string;
68
+ /**
69
+ * The maximum value of the input
70
+ */
71
+ max?: number | string;
72
+ /**
73
+ * The minimum number of characters
74
+ */
75
+ minLength?: number;
76
+ /**
77
+ * The maximum number of characters
78
+ */
79
+ maxLength?: number;
80
+ /**
81
+ * The initial value of the input when rendered.
82
+ * Use when you don't need to control the value of the input.
83
+ */
84
+ defaultValue?: string;
85
+ /**
86
+ * Whether the input is disabled
87
+ */
88
+ disabled?: boolean;
89
+
90
+ /**
91
+ * The tabIndex of the input
92
+ */
93
+ tabIndex?: number;
94
+
95
+ slots?: {
96
+ /**
97
+ * Custom component to wrap the input element
98
+ */
99
+ inputWrapper?: ComponentType<{ children: React.ReactNode }>;
100
+
101
+ /**
102
+ * Adornment to display at the start of the input
103
+ */
104
+ startAdornment?: React.ReactNode;
105
+ /**
106
+ * Adornment to display at the end of the input
107
+ */
108
+ endAdornment?: React.ReactNode;
109
+ };
110
+ }
@@ -0,0 +1,2 @@
1
+ export { default as DsTextInput } from './ds-text-input';
2
+ export { type DsTextInputProps, type TextInputSize, textInputSizes } from './ds-text-input.types';
@@ -0,0 +1,5 @@
1
+ @use '../../styles/shared/input' as input;
2
+
3
+ .textarea {
4
+ @include input.textarea;
5
+ }
@@ -0,0 +1,49 @@
1
+ import type React from 'react';
2
+ import classNames from 'classnames';
3
+ import styles from './ds-textarea.module.scss';
4
+ import type { DsTextareaProps } from './ds-textarea.types';
5
+
6
+ const DsTextarea: React.FC<DsTextareaProps> = ({
7
+ id,
8
+ ref,
9
+ name,
10
+ onBlur,
11
+ onChange,
12
+ onValueChange,
13
+ className,
14
+ style = {},
15
+ value,
16
+ defaultValue,
17
+ disabled = false,
18
+ rows = 3,
19
+ placeholder,
20
+ minLength,
21
+ maxLength,
22
+ }) => {
23
+ const handleChange = (event: React.ChangeEvent<HTMLTextAreaElement>) => {
24
+ const newValue = event.target.value;
25
+ onChange?.(event);
26
+ onValueChange?.(newValue);
27
+ };
28
+
29
+ return (
30
+ <textarea
31
+ id={id}
32
+ ref={ref}
33
+ name={name}
34
+ className={classNames(styles.textarea, className)}
35
+ style={style}
36
+ value={value}
37
+ defaultValue={defaultValue}
38
+ placeholder={placeholder}
39
+ disabled={disabled}
40
+ rows={rows}
41
+ onBlur={onBlur}
42
+ onChange={handleChange}
43
+ minLength={minLength}
44
+ maxLength={maxLength}
45
+ />
46
+ );
47
+ };
48
+
49
+ export default DsTextarea;
@@ -0,0 +1,67 @@
1
+ import type React from 'react';
2
+
3
+ export interface DsTextareaProps {
4
+ /**
5
+ * Unique identifier for the textarea element
6
+ */
7
+ id?: string;
8
+ /**
9
+ * The ref to the textarea element
10
+ */
11
+ ref?: React.Ref<HTMLTextAreaElement>;
12
+ /**
13
+ * The name of the textarea
14
+ */
15
+ name?: string;
16
+ /**
17
+ * Event handler called when the textarea loses focus
18
+ *
19
+ * @param event
20
+ */
21
+ onBlur?: (event: React.FocusEvent<HTMLTextAreaElement>) => void;
22
+ /**
23
+ * Callback when the value changes
24
+ */
25
+ onChange?: (event: React.ChangeEvent<HTMLTextAreaElement>) => void;
26
+ /**
27
+ * Value change event handler (provides just the value)
28
+ */
29
+ onValueChange?: (value: string) => void;
30
+ /**
31
+ * Additional CSS class names
32
+ */
33
+ className?: string;
34
+ /**
35
+ * Additional styles to apply to the component
36
+ */
37
+ style?: React.CSSProperties;
38
+ /**
39
+ * The placeholder text
40
+ */
41
+ placeholder?: string;
42
+ /**
43
+ * The current value
44
+ */
45
+ value?: string;
46
+ /**
47
+ * The initial value of the input when rendered.
48
+ * Use when you don't need to control the value of the input.
49
+ */
50
+ defaultValue?: string;
51
+ /**
52
+ * Whether the textarea is disabled
53
+ */
54
+ disabled?: boolean;
55
+ /**
56
+ * The number of visible text lines
57
+ */
58
+ rows?: number;
59
+ /**
60
+ * The minimum number of characters
61
+ */
62
+ minLength?: number;
63
+ /**
64
+ * The maximum number of characters
65
+ */
66
+ maxLength?: number;
67
+ }
@@ -0,0 +1,2 @@
1
+ export { default as DsTextarea } from './ds-textarea';
2
+ export * from './ds-textarea.types';
@@ -0,0 +1,79 @@
1
+ import { type FC, type ReactNode, createContext, useContext } from 'react';
2
+ import { type CreateToasterReturn, createToaster } from '@ark-ui/react';
3
+ import { DsToastGroup } from './ds-toast';
4
+ import type { DsToastProps } from './ds-toast.types';
5
+
6
+ export interface DsToastProviderProps {
7
+ /**
8
+ * The maximum number of toasts to display (recommended 3 - 5)
9
+ * @default 3
10
+ */
11
+ max?: number;
12
+ /**
13
+ * The children of the toast provider
14
+ */
15
+ children: ReactNode;
16
+ }
17
+
18
+ export type DsToastContextType = {
19
+ /**
20
+ * Create a new toast
21
+ */
22
+ createToast: (toast: DsToastProps) => string;
23
+ /**
24
+ * Dismiss a toast by id
25
+ */
26
+ dismissToast: (id: string) => void;
27
+ /**
28
+ * Dismiss all toasts
29
+ */
30
+ dismissAllToasts: () => void;
31
+ /**
32
+ * Get all visible toasts
33
+ */
34
+ getToasts: () => DsToastProps[];
35
+ /**
36
+ * Get the total number of toasts
37
+ */
38
+ getToastsCount: () => number;
39
+ };
40
+
41
+ const DsToastContext = createContext<DsToastContextType | null>(null);
42
+
43
+ const createToastFactory = (toaster: CreateToasterReturn) => (toast: DsToastProps) =>
44
+ toaster.create({
45
+ ...toast,
46
+ type: toast.variant,
47
+ duration: toast.persistent ? Infinity : toast.duration || 6000,
48
+ });
49
+
50
+ export const DsToastProvider: FC<DsToastProviderProps> = ({ children, max = 3 }) => {
51
+ const toaster = createToaster({
52
+ placement: 'top',
53
+ gap: 24,
54
+ max,
55
+ });
56
+
57
+ const contextValue: DsToastContextType = {
58
+ createToast: createToastFactory(toaster),
59
+ dismissToast: toaster.dismiss,
60
+ dismissAllToasts: () => toaster.dismiss(),
61
+ getToasts: toaster.getVisibleToasts,
62
+ getToastsCount: toaster.getCount,
63
+ };
64
+
65
+ return (
66
+ <DsToastContext.Provider value={contextValue}>
67
+ {children}
68
+ <DsToastGroup toaster={toaster} />
69
+ </DsToastContext.Provider>
70
+ );
71
+ };
72
+
73
+ export const useToaster = (): DsToastContextType => {
74
+ const context = useContext(DsToastContext);
75
+ if (!context) {
76
+ throw new Error('useToast must be used within a ToastProvider');
77
+ }
78
+ return context;
79
+ };
@@ -0,0 +1,134 @@
1
+ [data-scope='toast'][data-part='root'] {
2
+ display: grid;
3
+ grid-template-columns: auto 1fr auto;
4
+ grid-template-rows: auto 1fr auto;
5
+ grid-template-areas:
6
+ 'icon title close'
7
+ 'description description description'
8
+ 'actions actions actions';
9
+ align-items: start;
10
+ padding: var(--spacing-standard);
11
+ border-radius: 4px;
12
+ column-gap: var(--spacing-xs);
13
+ row-gap: var(--spacing-4xs);
14
+ color: var(--color-font-on-action);
15
+ box-shadow: 0 1.25px 4px 0 rgba(0, 0, 0, 0.25);
16
+ // approx. 6 columns (64 * 2)
17
+ min-width: 384px;
18
+ // approx. 10 columns (64 * 10)
19
+ max-width: 640px;
20
+ overflow-wrap: anywhere;
21
+ translate: var(--x) var(--y);
22
+ z-index: var(--z-index);
23
+
24
+ will-change: translate, opacity, scale;
25
+
26
+ &[data-state='open'] {
27
+ animation: slide-in 0.35s ease-in-out both;
28
+ transition: 0.35s all;
29
+ }
30
+
31
+ &[data-state='closed'] {
32
+ animation: fade-out 0.25s ease-out forwards;
33
+ }
34
+
35
+ &[data-type='success'] {
36
+ background: var(--color-background-success-strong);
37
+ }
38
+
39
+ &[data-type='info'] {
40
+ background: var(--color-background-info-strong);
41
+ }
42
+
43
+ &[data-type='warning'] {
44
+ background: var(--color-background-warning-strong);
45
+ }
46
+
47
+ &[data-type='error'] {
48
+ background: var(--color-background-danger-strong);
49
+ }
50
+
51
+ &:not(:has([data-scope='toast'][data-part='title'])) {
52
+ grid-template-columns: auto 1fr auto auto;
53
+ grid-template-areas: 'icon description actions close';
54
+ align-items: center;
55
+
56
+ .actions {
57
+ margin: 0;
58
+ }
59
+ }
60
+ }
61
+
62
+ [data-scope='toast'][data-part='close-trigger'] {
63
+ grid-area: close;
64
+ display: flex;
65
+ align-items: center;
66
+ justify-content: center;
67
+ border-radius: var(--spacing-4xs);
68
+
69
+ &:hover {
70
+ background: rgba(0, 0, 0, 0.05);
71
+ }
72
+
73
+ &:focus-visible {
74
+ outline: 2px solid currentColor;
75
+ outline-offset: 1px;
76
+ }
77
+ }
78
+
79
+ [data-scope='toast'][data-part='title'] {
80
+ grid-area: title;
81
+ }
82
+
83
+ [data-scope='toast'][data-part='description'] {
84
+ grid-area: description;
85
+ }
86
+
87
+ .icon {
88
+ grid-area: icon;
89
+ color: var(--color-icon-inverse);
90
+ }
91
+
92
+ .actions {
93
+ grid-area: actions;
94
+ margin-top: var(--spacing-sm);
95
+ }
96
+
97
+ @media (max-width: 640px) {
98
+ [data-scope='toast'][data-part='group'] {
99
+ width: 100%;
100
+ }
101
+
102
+ [data-scope='toast'][data-part='root'] {
103
+ inset-inline: 0;
104
+ width: calc(100% - var(--gap) * 2);
105
+ }
106
+ }
107
+
108
+ @keyframes slide-in {
109
+ 0% {
110
+ opacity: 0;
111
+ scale: 0.9;
112
+ }
113
+
114
+ 60% {
115
+ scale: 1.05;
116
+ }
117
+
118
+ 100% {
119
+ opacity: 1;
120
+ scale: 1;
121
+ }
122
+ }
123
+
124
+ @keyframes fade-out {
125
+ 0% {
126
+ opacity: 1;
127
+ translate: 0 var(--offset);
128
+ }
129
+
130
+ 100% {
131
+ opacity: 0;
132
+ translate: 0 var(--offset);
133
+ }
134
+ }
@@ -0,0 +1,54 @@
1
+ import type React from 'react';
2
+ import { type CreateToasterReturn, Toast, Toaster } from '@ark-ui/react';
3
+ import styles from './ds-toast.module.scss';
4
+ import type { DsToastProps, ToastVariant } from './ds-toast.types';
5
+ import { type IconType, DsIcon } from '../ds-icon';
6
+ import { DsTypography } from '../ds-typography';
7
+
8
+ const variantIcons = {
9
+ success: 'check_circle',
10
+ info: 'info',
11
+ warning: 'error',
12
+ error: 'cancel',
13
+ } satisfies Record<ToastVariant, IconType>;
14
+
15
+ /**
16
+ * Design system Toast component
17
+ * This component is used within the Toaster render function
18
+ */
19
+ const DsToast = ({
20
+ style,
21
+ className,
22
+ variant = 'info',
23
+ title,
24
+ description,
25
+ onDismiss,
26
+ actions,
27
+ }: DsToastProps) => (
28
+ <Toast.Root style={style} className={className}>
29
+ <DsIcon icon={variantIcons[variant]} size="small" filled className={styles.icon} />
30
+ {title && (
31
+ <DsTypography variant="body-sm-md" asChild>
32
+ <Toast.Title>{title}</Toast.Title>
33
+ </DsTypography>
34
+ )}
35
+ {description && (
36
+ <DsTypography variant="body-sm-reg" asChild>
37
+ <Toast.Description>{description}</Toast.Description>
38
+ </DsTypography>
39
+ )}
40
+ <Toast.CloseTrigger onClick={onDismiss}>
41
+ <DsIcon icon="close" size="small" />
42
+ </Toast.CloseTrigger>
43
+ {actions && <div className={styles.actions}>{actions}</div>}
44
+ </Toast.Root>
45
+ );
46
+
47
+ /**
48
+ * Design system Toast Group component that wraps the Toaster
49
+ */
50
+ const DsToastGroup: React.FC<{ toaster: CreateToasterReturn }> = ({ toaster }) => {
51
+ return <Toaster toaster={toaster}>{(toast: DsToastProps) => <DsToast {...toast} />}</Toaster>;
52
+ };
53
+
54
+ export { DsToast, DsToastGroup };
@@ -0,0 +1,53 @@
1
+ import type { CSSProperties, ReactNode } from 'react';
2
+
3
+ export const toastVariants = ['info', 'success', 'warning', 'error'] as const;
4
+ export type ToastVariant = (typeof toastVariants)[number];
5
+
6
+ export type DsToastConfig =
7
+ | {
8
+ persistent?: never;
9
+ /**
10
+ * Duration in milliseconds before auto-dismiss (ignored if persistent is true)
11
+ * @default 6000 (6 seconds)
12
+ */
13
+ duration?: number;
14
+ }
15
+ | {
16
+ duration?: never;
17
+ /**
18
+ * Whether the toast should persist until manually dismissed
19
+ * @default false
20
+ */
21
+ persistent?: boolean;
22
+ };
23
+
24
+ export type DsToastProps = DsToastConfig & {
25
+ /**
26
+ * Toast type that determines styling and icon
27
+ */
28
+ variant?: ToastVariant;
29
+ /**
30
+ * Toast title
31
+ */
32
+ title?: ReactNode;
33
+ /**
34
+ * Toast description/message
35
+ */
36
+ description?: ReactNode;
37
+ /**
38
+ * Additional CSS class names
39
+ */
40
+ className?: string;
41
+ /**
42
+ * Additional styles to apply to the component
43
+ */
44
+ style?: CSSProperties;
45
+ /**
46
+ * Optional action buttons to be rendered inside the component
47
+ */
48
+ actions?: ReactNode;
49
+ /**
50
+ * Callback when toast is dismissed
51
+ */
52
+ onDismiss?: () => void;
53
+ };
@@ -0,0 +1,3 @@
1
+ export { DsToastProvider, useToaster } from './ds-toast-context';
2
+ export type { DsToastContextType, DsToastProviderProps } from './ds-toast-context';
3
+ export type { DsToastProps, ToastVariant } from './ds-toast.types';
@@ -0,0 +1,19 @@
1
+ @use '../../styles/typography';
2
+
3
+ .tooltip {
4
+ color: var(--color-font-on-action);
5
+ background-color: var(--color-background-brand);
6
+ padding: var(--spacing-xs) var(--spacing-sm);
7
+ border-radius: var(--exo-spacing-2x-small);
8
+ // approx. 6 grid columns
9
+ max-width: 384px;
10
+ z-index: 9999;
11
+
12
+ .content {
13
+ @include typography.line-clamp(3);
14
+ }
15
+ }
16
+
17
+ .arrow {
18
+ fill: var(--neutral-1);
19
+ }