@drivenets/design-system 0.9.1 → 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 (88) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/dist/index.cjs +1065 -594
  3. package/dist/index.d.cts +1797 -635
  4. package/dist/index.d.cts.map +1 -1
  5. package/dist/index.d.ts +1800 -638
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +1072 -603
  8. package/dist/index.js.map +1 -1
  9. package/dist/index.min.css +1 -1
  10. package/package.json +11 -13
  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 +105 -106
  14. package/src/components/ds-button-v3/ds-button-v3.types.ts +7 -0
  15. package/src/components/ds-card/ds-card.types.ts +3 -1
  16. package/src/components/ds-checkbox/ds-checkbox.module.scss +106 -123
  17. package/src/components/ds-checkbox/ds-checkbox.tsx +24 -35
  18. package/src/components/ds-checkbox/ds-checkbox.types.ts +12 -11
  19. package/src/components/ds-checkbox-group/ds-checkbox-group.module.scss +13 -0
  20. package/src/components/ds-checkbox-group/ds-checkbox-group.tsx +20 -0
  21. package/src/components/ds-checkbox-group/ds-checkbox-group.types.ts +8 -0
  22. package/src/components/ds-checkbox-group/hooks/index.ts +6 -0
  23. package/src/components/ds-checkbox-group/hooks/use-checkbox-select-all.ts +65 -0
  24. package/src/components/ds-checkbox-group/index.ts +3 -0
  25. package/src/components/ds-comment-bubble/components/ds-comment-thread/ds-comment-thread.types.ts +26 -0
  26. package/src/components/ds-comment-bubble/components/ds-thread-item/ds-thread-item.types.ts +38 -0
  27. package/src/components/ds-comment-bubble/ds-comment-bubble.types.ts +78 -0
  28. package/src/components/ds-comment-card/ds-comment-card.types.ts +114 -0
  29. package/src/components/ds-comment-indicator/ds-comment-indicator.types.ts +26 -0
  30. package/src/components/ds-comments-drawer/comments-filters.types.ts +33 -0
  31. package/src/components/ds-comments-drawer/components/comments-filter-modal/comments-filter-modal.types.ts +37 -1
  32. package/src/components/ds-comments-drawer/ds-comments-drawer.types.ts +64 -0
  33. package/src/components/ds-date-input/ds-date-input.types.ts +23 -0
  34. package/src/components/ds-date-picker/ds-date-picker.tsx +3 -0
  35. package/src/components/ds-date-picker/ds-date-picker.types.ts +20 -0
  36. package/src/components/ds-date-range-picker/ds-date-range-picker.types.ts +28 -0
  37. package/src/components/ds-dialog/ds-dialog.types.ts +10 -1
  38. package/src/components/ds-dropdown-menu/ds-dropdown-menu.types.ts +24 -0
  39. package/src/components/ds-file-upload/components/file-upload/file-upload.types.ts +1 -0
  40. package/src/components/ds-file-upload/ds-file-upload-api.types.ts +55 -0
  41. package/src/components/ds-form-control/ds-form-control.types.ts +3 -0
  42. package/src/components/ds-grid/ds-grid.tsx +29 -12
  43. package/src/components/ds-grid/ds-grid.types.ts +16 -13
  44. package/src/components/ds-grid/index.ts +10 -2
  45. package/src/components/ds-icon/custom-icons/index.ts +2 -0
  46. package/src/components/ds-icon/custom-icons/special-leading-icon.tsx +11 -0
  47. package/src/components/ds-icon/ds-icon.tsx +10 -4
  48. package/src/components/ds-icon/ds-icon.types.ts +30 -0
  49. package/src/components/ds-key-value-pair/ds-key-value-pair.types.ts +12 -2
  50. package/src/components/ds-modal/ds-modal.types.ts +16 -0
  51. package/src/components/ds-panel/ds-panel.types.ts +39 -0
  52. package/src/components/ds-radio-group/ds-radio-group.module.scss +58 -56
  53. package/src/components/ds-radio-group/ds-radio-group.tsx +35 -28
  54. package/src/components/ds-radio-group/ds-radio-group.types.ts +38 -7
  55. package/src/components/ds-segment-group/ds-segment-group.types.ts +17 -0
  56. package/src/components/ds-select/ds-select.types.ts +32 -0
  57. package/src/components/ds-split-button/ds-split-button.module.scss +7 -7
  58. package/src/components/ds-split-button/ds-split-button.types.ts +28 -0
  59. package/src/components/ds-stack/ds-stack.types.ts +23 -0
  60. package/src/components/ds-stepper/ds-stepper.types.ts +34 -1
  61. package/src/components/ds-table/components/ds-table-body-virtualized/ds-table-body-virtualized.types.ts +27 -0
  62. package/src/components/ds-table/components/ds-table-row-expandable-cell/ds-table-row-expandable-cell.types.ts +10 -0
  63. package/src/components/ds-table/components/ds-table-row-selectable-cell/ds-table-row-selectable-cell.types.ts +11 -0
  64. package/src/components/ds-table/components/ds-table-row-virtualized/ds-table-row-virtualized.types.ts +27 -0
  65. package/src/components/ds-table/filters/types/filter-adapter.types.ts +6 -0
  66. package/src/components/ds-tag/ds-tag.types.ts +6 -0
  67. package/src/components/ds-tag-filter/ds-tag-filter.types.ts +16 -0
  68. package/src/components/ds-text-input/ds-text-input.types.ts +3 -0
  69. package/src/components/ds-time-picker/components/time-item/time-item.types.ts +19 -0
  70. package/src/components/ds-time-picker/components/time-scroller/time-scroller.types.ts +29 -0
  71. package/src/components/ds-time-picker/ds-time-picker.module.scss +7 -0
  72. package/src/components/ds-time-picker/ds-time-picker.tsx +8 -1
  73. package/src/components/ds-time-picker/ds-time-picker.types.ts +80 -0
  74. package/src/components/ds-tooltip/ds-tooltip.types.ts +6 -0
  75. package/src/components/ds-tree/ds-tree.types.ts +84 -2
  76. package/src/components/ds-typography/ds-typography.config.ts +46 -27
  77. package/src/components/ds-typography/ds-typography.tsx +22 -7
  78. package/src/components/ds-typography/ds-typography.types.ts +15 -4
  79. package/src/components/ds-workspace/ds-workspace.module.scss +55 -0
  80. package/src/components/ds-workspace/ds-workspace.tsx +37 -0
  81. package/src/components/ds-workspace/ds-workspace.types.ts +17 -0
  82. package/src/components/ds-workspace/index.ts +8 -0
  83. package/src/index.ts +2 -0
  84. package/src/styles/_grid.scss +2 -2
  85. package/src/styles/_root_new.scss +449 -0
  86. package/src/styles/shared/_input.scss +0 -2
  87. package/src/styles/styles.scss +1 -0
  88. package/src/styles/_root_updated.scss +0 -593
@@ -1,161 +1,144 @@
1
+ @use '../../styles/root_new';
1
2
  @use '../../styles/typography';
2
3
 
3
- .container {
4
+ $checkbox-size: 16px;
5
+ $checkbox-border-radius: 2px;
6
+ $checkbox-focus-ring-width: 2px;
7
+ $transition-duration: 0.2s;
8
+
9
+ .root {
4
10
  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;
11
+ display: inline-flex;
12
+ align-items: flex-start;
13
+ gap: var(--3xs);
14
+ padding: var(--4xs);
15
+ border-radius: $checkbox-border-radius;
16
+ cursor: pointer;
17
+ transition: background-color $transition-duration ease-in-out;
15
18
 
16
- .labelInfo {
17
- color: var(--color-font-disabled);
18
- }
19
+ &:hover,
20
+ &[data-hover],
21
+ &[data-focus-visible] {
22
+ background-color: var(--background-secondary-hover);
19
23
  }
20
24
 
21
- &:has(.label):has(.checkboxRoot:focus-visible) {
22
- border-color: var(--color-background-selected);
25
+ &[data-focus-visible] {
26
+ outline: $checkbox-focus-ring-width solid var(--background-primary-hover);
27
+ outline-offset: 0;
23
28
  }
24
29
 
25
- &:has(.label):has([data-state='unchecked']:focus-visible) {
26
- border-color: var(--color-background-selected-hover);
30
+ .control {
31
+ display: inline-flex;
32
+ align-items: center;
33
+ justify-content: center;
34
+ flex-shrink: 0;
35
+ width: $checkbox-size;
36
+ height: $checkbox-size;
37
+ border: 1px solid var(--secondary-400);
38
+ border-radius: $checkbox-border-radius;
39
+ background-color: transparent;
40
+ transition:
41
+ background-color $transition-duration ease-in-out,
42
+ border-color $transition-duration ease-in-out;
27
43
  }
28
- }
29
44
 
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
- }
45
+ .indicator {
46
+ line-height: 0;
47
+ color: var(--icon-inverse);
49
48
 
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
- }
49
+ svg {
50
+ width: 100%;
51
+ height: 100%;
56
52
  }
57
53
  }
58
54
 
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
- &:focus-visible {
67
- background: var(--color-background-action-secondary-hover);
68
- }
55
+ .labelColumn {
56
+ display: flex;
57
+ flex-direction: column;
58
+ gap: var(--4xs);
59
+ min-width: 0;
69
60
  }
70
61
 
71
- &[data-state='unchecked'] {
72
- .checkboxWrapper {
73
- border-color: var(--color-background-deselected);
74
- }
62
+ .label {
63
+ @include typography.body-sm-reg;
64
+ line-height: normal;
65
+ color: var(--font-main);
66
+ }
75
67
 
76
- &:hover,
77
- &:focus-visible {
78
- background: var(--color-background-action-hover-weak);
79
- }
68
+ .labelInfo {
69
+ @include typography.body-xs-reg;
70
+ @include typography.ellipsis;
71
+ color: var(--font-secondary);
80
72
  }
81
73
 
74
+ &[data-state='checked'],
82
75
  &[data-state='indeterminate'] {
83
- .checkboxWrapper {
84
- border-color: var(--color-background-selected);
85
- background-color: var(--color-background-selected);
86
- }
87
-
88
- &:hover,
89
- &:focus-visible {
90
- background: var(--color-background-action-secondary-hover);
76
+ .control {
77
+ background-color: var(--background-primary);
78
+ border-color: var(--background-primary);
91
79
  }
92
80
  }
93
81
 
94
- .checkboxWrapper {
95
- display: flex;
96
- flex-direction: column;
97
- justify-content: center;
98
- align-items: center;
99
- height: 16px;
100
- width: 16px;
101
- margin: var(--spacing-4xs);
102
- border: 2px solid transparent;
103
- border-radius: 2px;
104
- }
105
- }
82
+ &[data-disabled] {
83
+ cursor: not-allowed;
84
+ background-color: transparent;
106
85
 
107
- .checkboxIndicator {
108
- flex: 1;
109
- color: white;
110
- display: flex;
111
- align-items: center;
112
- justify-content: center;
86
+ .label {
87
+ color: var(--font-disabled);
88
+ }
113
89
 
114
- svg {
115
- width: 100%;
116
- height: 100%;
117
- }
118
- }
90
+ .labelInfo {
91
+ color: var(--font-disabled);
92
+ }
119
93
 
120
- .label {
121
- @include typography.body-sm-reg;
122
- color: var(--color-font-main);
123
- cursor: pointer;
124
- }
94
+ &[data-state='checked'],
95
+ &[data-state='indeterminate'] {
96
+ .label {
97
+ color: var(--font-disabled);
98
+ }
125
99
 
126
- .labelInfo {
127
- @include typography.body-xs-reg;
128
- @include typography.ellipsis;
129
- position: absolute;
130
- color: var(--color-font-secondary);
131
- cursor: pointer;
132
- width: 100%;
100
+ .control {
101
+ background-color: var(--background-disable);
102
+ border-color: var(--background-disable);
103
+ }
104
+ }
105
+ }
133
106
  }
134
107
 
135
- .default {
136
- border-color: transparent;
108
+ // Overlay the native input over the control so `getByRole('checkbox')` clicks
109
+ // land on a real interactive surface. Ark applies `visuallyHiddenStyle` inline
110
+ // (1x1, clipped, off-screen) which Playwright refuses to click; `!important`
111
+ // is required to beat inline-style specificity.
112
+ .hiddenInput {
113
+ position: absolute !important;
114
+ inset-block-start: var(--4xs) !important;
115
+ inset-inline-start: var(--4xs) !important;
116
+ width: $checkbox-size !important;
117
+ height: $checkbox-size !important;
118
+ margin: 0 !important;
119
+ padding: 0 !important;
120
+ clip: auto !important;
121
+ overflow: visible !important;
122
+ opacity: 0 !important;
123
+ cursor: inherit !important;
137
124
  }
138
125
 
139
126
  .warning {
140
- &:has([data-state='checked']),
141
- &:has([data-state='indeterminate']) {
142
- .label {
143
- color: var(--color-font-warning);
144
- }
127
+ &:hover,
128
+ &[data-hover],
129
+ &[data-focus-visible] {
130
+ background-color: var(--background-warning);
145
131
  }
146
132
 
147
- .checkboxRoot {
148
- &[data-state='checked'],
149
- &[data-state='indeterminate'] {
150
- .checkboxWrapper {
151
- border-color: var(--color-background-warning-strong);
152
- background-color: var(--color-background-warning-strong);
153
- }
133
+ &[data-state='checked'],
134
+ &[data-state='indeterminate'] {
135
+ .label {
136
+ color: var(--font-warning);
137
+ }
154
138
 
155
- &:hover,
156
- &:focus-visible {
157
- background: var(--color-background-warning);
158
- }
139
+ .control {
140
+ background-color: var(--background-warning-strong);
141
+ border-color: var(--background-warning-strong);
159
142
  }
160
143
  }
161
144
  }
@@ -1,6 +1,4 @@
1
- import type React from 'react';
2
- import { useId } from 'react';
3
- import * as CheckboxPrimitive from '@radix-ui/react-checkbox';
1
+ import { Checkbox } from '@ark-ui/react/checkbox';
4
2
  import classNames from 'classnames';
5
3
  import styles from './ds-checkbox.module.scss';
6
4
  import type { DsCheckboxProps } from './ds-checkbox.types';
@@ -9,47 +7,38 @@ import { DsIcon } from '../ds-icon';
9
7
  /**
10
8
  * Design system Checkbox component
11
9
  */
12
- const DsCheckbox: React.FC<DsCheckboxProps> = ({
13
- id,
10
+ const DsCheckbox = ({
14
11
  variant = 'default',
15
12
  label,
16
13
  labelInfo,
17
14
  className,
18
- checked,
19
- defaultChecked,
20
15
  onCheckedChange,
16
+ value,
21
17
  ...props
22
- }) => {
23
- const generatedId = useId();
24
- const checkboxId = id || generatedId;
25
-
18
+ }: DsCheckboxProps) => {
26
19
  return (
27
- <div className={classNames(styles.container, styles[variant], className)}>
28
- <CheckboxPrimitive.Root
29
- className={styles.checkboxRoot}
30
- id={checkboxId}
31
- checked={checked}
32
- defaultChecked={defaultChecked}
33
- onCheckedChange={onCheckedChange}
34
- {...props}
35
- >
36
- <div className={styles.checkboxWrapper}>
37
- <CheckboxPrimitive.Indicator className={styles.checkboxIndicator}>
38
- <DsIcon
39
- icon={checked === 'indeterminate' ? 'check_indeterminate_small' : 'check_small'}
40
- size="small"
41
- variant="outlined"
42
- />
43
- </CheckboxPrimitive.Indicator>
44
- </div>
45
- </CheckboxPrimitive.Root>
46
- {label && (
47
- <label className={styles.label} htmlFor={checkboxId}>
48
- {label}
20
+ <Checkbox.Root
21
+ className={classNames(styles.root, variant === 'warning' && styles.warning, className)}
22
+ onCheckedChange={(details) => onCheckedChange?.(details.checked)}
23
+ {...props}
24
+ value={value === undefined ? undefined : String(value)}
25
+ >
26
+ <Checkbox.Control className={styles.control}>
27
+ <Checkbox.Indicator className={styles.indicator}>
28
+ <DsIcon icon="check_small" size="tiny" variant="rounded" />
29
+ </Checkbox.Indicator>
30
+ <Checkbox.Indicator className={styles.indicator} indeterminate>
31
+ <DsIcon icon="check_indeterminate_small" size="tiny" variant="rounded" />
32
+ </Checkbox.Indicator>
33
+ </Checkbox.Control>
34
+ <Checkbox.HiddenInput className={styles.hiddenInput} />
35
+ {(label || labelInfo) && (
36
+ <div className={styles.labelColumn}>
37
+ {label && <Checkbox.Label className={styles.label}>{label}</Checkbox.Label>}
49
38
  {labelInfo && <div className={styles.labelInfo}>{labelInfo}</div>}
50
- </label>
39
+ </div>
51
40
  )}
52
- </div>
41
+ </Checkbox.Root>
53
42
  );
54
43
  };
55
44
 
@@ -1,10 +1,17 @@
1
1
  import type { ComponentPropsWithoutRef, ReactNode } from 'react';
2
- import type { Root } from '@radix-ui/react-checkbox';
2
+ import { type Checkbox } from '@ark-ui/react/checkbox';
3
3
 
4
4
  export const checkboxVariants = ['default', 'warning'] as const;
5
5
  export type CheckboxVariant = (typeof checkboxVariants)[number];
6
6
 
7
- export interface DsCheckboxProps extends ComponentPropsWithoutRef<typeof Root> {
7
+ export interface DsCheckboxProps extends Omit<
8
+ ComponentPropsWithoutRef<typeof Checkbox.Root>,
9
+ 'onCheckedChange' | 'value'
10
+ > {
11
+ /**
12
+ * Value when used in a group or for form submission. Coerced to string for the native control.
13
+ */
14
+ value?: string | number;
8
15
  /**
9
16
  * Visual variant of the checkbox
10
17
  */
@@ -18,17 +25,11 @@ export interface DsCheckboxProps extends ComponentPropsWithoutRef<typeof Root> {
18
25
  */
19
26
  labelInfo?: ReactNode;
20
27
  /**
21
- * The controlled checked state of the checkbox
22
- */
23
- checked?: boolean | 'indeterminate';
24
- /**
25
- * The default checked state of the checkbox
28
+ * Disables the checkbox, preventing user interaction
26
29
  */
27
- defaultChecked?: boolean | 'indeterminate';
30
+ disabled?: boolean;
28
31
  /**
29
- * Event handler called when the checked state of the checkbox changes.
30
- *
31
- * @param checked
32
+ * Callback invoked when the checked state changes
32
33
  */
33
34
  onCheckedChange?: (checked: boolean | 'indeterminate') => void;
34
35
  }
@@ -0,0 +1,13 @@
1
+ .root {
2
+ display: flex;
3
+ gap: var(--3xs);
4
+ }
5
+
6
+ .vertical {
7
+ flex-direction: column;
8
+ }
9
+
10
+ .horizontal {
11
+ flex-direction: row;
12
+ flex-wrap: wrap;
13
+ }
@@ -0,0 +1,20 @@
1
+ import type React from 'react';
2
+ import { Checkbox } from '@ark-ui/react/checkbox';
3
+ import classNames from 'classnames';
4
+ import styles from './ds-checkbox-group.module.scss';
5
+ import type { DsCheckboxGroupProps } from './ds-checkbox-group.types';
6
+
7
+ const DsCheckboxGroup: React.FC<DsCheckboxGroupProps> = ({
8
+ orientation = 'vertical',
9
+ className,
10
+ children,
11
+ ...props
12
+ }) => {
13
+ return (
14
+ <Checkbox.Group className={classNames(styles.root, styles[orientation], className)} {...props}>
15
+ {children}
16
+ </Checkbox.Group>
17
+ );
18
+ };
19
+
20
+ export default DsCheckboxGroup;
@@ -0,0 +1,8 @@
1
+ import type { ComponentPropsWithoutRef } from 'react';
2
+ import { type Checkbox } from '@ark-ui/react/checkbox';
3
+
4
+ export type DsCheckboxGroupOrientation = 'vertical' | 'horizontal';
5
+
6
+ export interface DsCheckboxGroupProps extends ComponentPropsWithoutRef<typeof Checkbox.Group> {
7
+ orientation?: DsCheckboxGroupOrientation;
8
+ }
@@ -0,0 +1,6 @@
1
+ export { useCheckboxSelectAll } from './use-checkbox-select-all';
2
+ export type {
3
+ CheckedState,
4
+ UseCheckboxSelectAllOptions,
5
+ UseCheckboxSelectAllResult,
6
+ } from './use-checkbox-select-all';
@@ -0,0 +1,65 @@
1
+ export type CheckedState = boolean | 'indeterminate';
2
+
3
+ export interface UseCheckboxSelectAllOptions<T> {
4
+ /** Currently selected values. */
5
+ value: T[];
6
+ /** Full set of values represented by the group. */
7
+ allValues: readonly T[];
8
+ /** Callback to update selected values. */
9
+ onValueChange: (next: T[]) => void;
10
+ /**
11
+ * Optional predicate to exclude values from bulk select/deselect.
12
+ * Non-selectable values that are already in `value` are preserved on toggle.
13
+ */
14
+ isSelectable?: (value: T) => boolean;
15
+ }
16
+
17
+ export interface UseCheckboxSelectAllResult {
18
+ /** Tri-state value for the select-all checkbox. */
19
+ selectAllState: CheckedState;
20
+ /** Count of selected values that are also selectable. */
21
+ selectedCount: number;
22
+ /** Count of selectable values. */
23
+ selectableCount: number;
24
+ /** Handler for the select-all checkbox's `onCheckedChange`. */
25
+ onSelectAllChange: (checked: CheckedState) => void;
26
+ }
27
+
28
+ /**
29
+ * Headless helper for a "select all" checkbox bound to a checkbox group.
30
+ *
31
+ * - Derives tri-state (`true` / `false` / `'indeterminate'`) from current selection.
32
+ * - Toggling selects or clears only selectable values; preserves any already-selected
33
+ * non-selectable values so bulk actions don't silently mutate protected items.
34
+ */
35
+ export function useCheckboxSelectAll<T>({
36
+ value,
37
+ allValues,
38
+ onValueChange,
39
+ isSelectable,
40
+ }: UseCheckboxSelectAllOptions<T>): UseCheckboxSelectAllResult {
41
+ const selectableValues = isSelectable ? allValues.filter(isSelectable) : [...allValues];
42
+ const selectableSet = new Set(selectableValues);
43
+ const selectedCount = value.reduce((count, v) => (selectableSet.has(v) ? count + 1 : count), 0);
44
+ const selectableCount = selectableValues.length;
45
+
46
+ let selectAllState: CheckedState = 'indeterminate';
47
+
48
+ if (selectableCount === 0 || selectedCount === 0) {
49
+ selectAllState = false;
50
+ } else if (selectedCount === selectableCount) {
51
+ selectAllState = true;
52
+ }
53
+
54
+ const onSelectAllChange = (checked: CheckedState) => {
55
+ const preserved = value.filter((v) => !selectableSet.has(v));
56
+ onValueChange(checked === true ? [...preserved, ...selectableValues] : preserved);
57
+ };
58
+
59
+ return {
60
+ selectAllState,
61
+ selectedCount,
62
+ selectableCount,
63
+ onSelectAllChange,
64
+ };
65
+ }
@@ -0,0 +1,3 @@
1
+ export { default as DsCheckboxGroup } from './ds-checkbox-group';
2
+ export * from './ds-checkbox-group.types';
3
+ export * from './hooks';
@@ -1,12 +1,38 @@
1
1
  import type { CommentMessage, CommentAuthor } from '../../../ds-comment-card';
2
2
 
3
3
  export interface DsCommentThreadProps {
4
+ /**
5
+ * Ordered list of messages in the thread, from oldest to newest.
6
+ */
4
7
  messages: CommentMessage[];
8
+ /**
9
+ * Author of the top-level comment. Used to visually distinguish their messages
10
+ * from replies by other participants.
11
+ */
5
12
  commentAuthor: CommentAuthor;
13
+ /**
14
+ * The user currently viewing the thread. Used to decide which messages the viewer
15
+ * can edit or delete.
16
+ */
6
17
  currentUser?: CommentAuthor;
18
+ /**
19
+ * Called when a message is edited. Receives the message id and the new content.
20
+ */
7
21
  onEditMessage?: (messageId: string, newContent: string) => void;
22
+ /**
23
+ * Called when a message is deleted. Receives the message id.
24
+ */
8
25
  onDeleteMessage?: (messageId: string) => void;
26
+ /**
27
+ * Called when a message is marked as unread. Receives the message id.
28
+ */
9
29
  onMarkUnread?: (messageId: string) => void;
30
+ /**
31
+ * Called when a message is resolved. Receives the message id.
32
+ */
10
33
  onResolved?: (messageId: string) => void;
34
+ /**
35
+ * Additional CSS class name applied to the thread root
36
+ */
11
37
  className?: string;
12
38
  }
@@ -1,15 +1,53 @@
1
1
  import type { CommentAuthor } from '../../../ds-comment-card';
2
2
 
3
3
  export interface DsThreadItemProps {
4
+ /**
5
+ * Stable identifier for the message. Passed to callbacks to identify which
6
+ * message the user acted on.
7
+ */
4
8
  id: string;
9
+ /**
10
+ * Author of the message
11
+ */
5
12
  author: CommentAuthor;
13
+ /**
14
+ * Text content of the message
15
+ */
6
16
  content: string;
17
+ /**
18
+ * Timestamp when the message was created
19
+ */
7
20
  createdAt: Date;
21
+ /**
22
+ * Whether this message was posted by the author of the top-level comment.
23
+ * Styled slightly differently from replies by other participants.
24
+ * @default false
25
+ */
8
26
  isCommentAuthorMessage?: boolean;
27
+ /**
28
+ * Whether the current viewer can edit or delete this message. Typically true
29
+ * only when the viewer is the message's author.
30
+ * @default false
31
+ */
9
32
  canModify?: boolean;
33
+ /**
34
+ * Called when the viewer saves an edit. Receives the message id and the new content.
35
+ */
10
36
  onEdit?: (messageId: string, newContent: string) => void;
37
+ /**
38
+ * Called when the viewer deletes the message. Receives the message id.
39
+ */
11
40
  onDelete?: (messageId: string) => void;
41
+ /**
42
+ * Called when the viewer marks the message as unread. Receives the message id.
43
+ */
12
44
  onMarkUnread?: (messageId: string) => void;
45
+ /**
46
+ * Called when the viewer resolves the message. Receives the message id.
47
+ */
13
48
  onResolved?: (messageId: string) => void;
49
+ /**
50
+ * Additional CSS class name applied to the item root
51
+ */
14
52
  className?: string;
15
53
  }