@makolabs/ripple 1.7.11 → 1.8.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 (90) hide show
  1. package/dist/adapters/ai/OpenAIAdapter.d.ts +8 -1
  2. package/dist/adapters/ai/OpenAIAdapter.js +2 -2
  3. package/dist/adapters/storage/BaseAdapter.js +2 -2
  4. package/dist/adapters/storage/S3Adapter.js +1 -6
  5. package/dist/adapters/storage/types.d.ts +3 -3
  6. package/dist/ai/AIChatInterface.svelte +0 -1
  7. package/dist/ai/ai-chat-interface.d.ts +21 -22
  8. package/dist/ai/content-detector.js +0 -1
  9. package/dist/button/Button.svelte +9 -2
  10. package/dist/button/button.d.ts +39 -40
  11. package/dist/charts/Chart.svelte +4 -1
  12. package/dist/drawer/Drawer.svelte +57 -23
  13. package/dist/drawer/drawer.d.ts +18 -19
  14. package/dist/elements/accordion/Accordion.svelte +39 -18
  15. package/dist/elements/accordion/accordion.d.ts +21 -22
  16. package/dist/elements/alert/Alert.svelte +20 -8
  17. package/dist/elements/badge/Badge.svelte +5 -2
  18. package/dist/elements/badge/badge.d.ts +39 -40
  19. package/dist/elements/dropdown/Dropdown.svelte +18 -2
  20. package/dist/elements/dropdown/Select.svelte +17 -5
  21. package/dist/elements/dropdown/dropdown.d.ts +18 -19
  22. package/dist/elements/dropdown/select.d.ts +18 -19
  23. package/dist/elements/pagination/Pagination.svelte +15 -2
  24. package/dist/elements/pagination/Pagination.svelte.d.ts +1 -0
  25. package/dist/forms/Checkbox.svelte +16 -4
  26. package/dist/forms/Form.svelte +0 -2
  27. package/dist/forms/Input.svelte +16 -4
  28. package/dist/forms/NumberInput.svelte +8 -1
  29. package/dist/forms/RadioInputs.svelte +14 -5
  30. package/dist/forms/Slider.svelte +6 -4
  31. package/dist/forms/Toggle.svelte +67 -29
  32. package/dist/forms/slider.d.ts +72 -10
  33. package/dist/forms/slider.js +21 -0
  34. package/dist/header/Breadcrumbs.svelte +47 -24
  35. package/dist/header/PageHeader.svelte +12 -2
  36. package/dist/header/breadcrumbs.d.ts +47 -39
  37. package/dist/helper/deprecation.d.ts +14 -0
  38. package/dist/helper/deprecation.js +24 -0
  39. package/dist/helper/testid.d.ts +10 -0
  40. package/dist/helper/testid.js +17 -0
  41. package/dist/index.d.ts +147 -47
  42. package/dist/index.js +1 -0
  43. package/dist/layout/activity-list/activity-list.d.ts +21 -22
  44. package/dist/layout/card/Card.svelte +19 -5
  45. package/dist/layout/card/card.d.ts +21 -22
  46. package/dist/layout/card/ranked-card.d.ts +2 -1
  47. package/dist/layout/navbar/Navbar.svelte +14 -16
  48. package/dist/layout/navbar/navbar.d.ts +19 -19
  49. package/dist/layout/sidebar/Sidebar.svelte +6 -3
  50. package/dist/layout/table/Table.svelte +237 -303
  51. package/dist/layout/table/table.d.ts +24 -25
  52. package/dist/layout/tabs/Tab.svelte +3 -1
  53. package/dist/layout/tabs/TabGroup.svelte +7 -4
  54. package/dist/layout/tabs/tabs.d.ts +39 -40
  55. package/dist/modal/Modal.svelte +124 -21
  56. package/dist/modal/modal.d.ts +18 -19
  57. package/dist/modal/modal.js +2 -2
  58. package/dist/user-management/UserModal.svelte +1 -1
  59. package/dist/user-management/UserTable.svelte +3 -3
  60. package/dist/user-management/UserViewModal.svelte +2 -2
  61. package/dist/variants.d.ts +13 -13
  62. package/package.json +9 -6
  63. package/dist/ai/AIChatInterfaceTestWrapper.svelte +0 -26
  64. package/dist/ai/AIChatInterfaceTestWrapper.svelte.d.ts +0 -17
  65. package/dist/button/ButtonTestWrapper.svelte +0 -10
  66. package/dist/button/ButtonTestWrapper.svelte.d.ts +0 -7
  67. package/dist/drawer/DrawerTestWrapper.svelte +0 -19
  68. package/dist/drawer/DrawerTestWrapper.svelte.d.ts +0 -9
  69. package/dist/elements/accordion/AccordionTestWrapper.svelte +0 -21
  70. package/dist/elements/accordion/AccordionTestWrapper.svelte.d.ts +0 -10
  71. package/dist/elements/badge/BadgeTestWrapper.svelte +0 -14
  72. package/dist/elements/badge/BadgeTestWrapper.svelte.d.ts +0 -9
  73. package/dist/forms/CheckboxTestWrapper.svelte +0 -8
  74. package/dist/forms/CheckboxTestWrapper.svelte.d.ts +0 -4
  75. package/dist/forms/InputTestWrapper.svelte +0 -8
  76. package/dist/forms/InputTestWrapper.svelte.d.ts +0 -4
  77. package/dist/forms/ToggleTestWrapper.svelte +0 -8
  78. package/dist/forms/ToggleTestWrapper.svelte.d.ts +0 -7
  79. package/dist/layout/card/CardTestWrapper.svelte +0 -15
  80. package/dist/layout/card/CardTestWrapper.svelte.d.ts +0 -7
  81. package/dist/modal/ModalTestWrapper.svelte +0 -20
  82. package/dist/modal/ModalTestWrapper.svelte.d.ts +0 -8
  83. package/dist/user-management/UserManagementTestWrapper.svelte +0 -32
  84. package/dist/user-management/UserManagementTestWrapper.svelte.d.ts +0 -12
  85. package/dist/user-management/UserModalTestWrapper.svelte +0 -22
  86. package/dist/user-management/UserModalTestWrapper.svelte.d.ts +0 -7
  87. package/dist/user-management/UserTableTestWrapper.svelte +0 -41
  88. package/dist/user-management/UserTableTestWrapper.svelte.d.ts +0 -7
  89. package/dist/user-management/UserViewModalTestWrapper.svelte +0 -22
  90. package/dist/user-management/UserViewModalTestWrapper.svelte.d.ts +0 -7
@@ -1,4 +1,3 @@
1
- import { Size } from '../../variants.js';
2
1
  export declare const dropdownMenu: import("tailwind-variants").TVReturnType<{
3
2
  position: {
4
3
  'top-left': {
@@ -15,7 +14,7 @@ export declare const dropdownMenu: import("tailwind-variants").TVReturnType<{
15
14
  };
16
15
  };
17
16
  size: {
18
- [Size.XS]: {
17
+ xs: {
19
18
  trigger: string;
20
19
  item: string;
21
20
  itemIcon: string;
@@ -23,7 +22,7 @@ export declare const dropdownMenu: import("tailwind-variants").TVReturnType<{
23
22
  headerTitle: string;
24
23
  headerSubtitle: string;
25
24
  };
26
- [Size.SM]: {
25
+ sm: {
27
26
  trigger: string;
28
27
  item: string;
29
28
  itemIcon: string;
@@ -31,7 +30,7 @@ export declare const dropdownMenu: import("tailwind-variants").TVReturnType<{
31
30
  headerTitle: string;
32
31
  headerSubtitle: string;
33
32
  };
34
- [Size.BASE]: {
33
+ base: {
35
34
  trigger: string;
36
35
  item: string;
37
36
  itemIcon: string;
@@ -39,7 +38,7 @@ export declare const dropdownMenu: import("tailwind-variants").TVReturnType<{
39
38
  headerTitle: string;
40
39
  headerSubtitle: string;
41
40
  };
42
- [Size.LG]: {
41
+ lg: {
43
42
  trigger: string;
44
43
  item: string;
45
44
  itemIcon: string;
@@ -47,7 +46,7 @@ export declare const dropdownMenu: import("tailwind-variants").TVReturnType<{
47
46
  headerTitle: string;
48
47
  headerSubtitle: string;
49
48
  };
50
- [Size.XL]: {
49
+ xl: {
51
50
  trigger: string;
52
51
  item: string;
53
52
  itemIcon: string;
@@ -55,7 +54,7 @@ export declare const dropdownMenu: import("tailwind-variants").TVReturnType<{
55
54
  headerTitle: string;
56
55
  headerSubtitle: string;
57
56
  };
58
- [Size.XXL]: {
57
+ "2xl": {
59
58
  trigger: string;
60
59
  item: string;
61
60
  itemIcon: string;
@@ -98,7 +97,7 @@ export declare const dropdownMenu: import("tailwind-variants").TVReturnType<{
98
97
  };
99
98
  };
100
99
  size: {
101
- [Size.XS]: {
100
+ xs: {
102
101
  trigger: string;
103
102
  item: string;
104
103
  itemIcon: string;
@@ -106,7 +105,7 @@ export declare const dropdownMenu: import("tailwind-variants").TVReturnType<{
106
105
  headerTitle: string;
107
106
  headerSubtitle: string;
108
107
  };
109
- [Size.SM]: {
108
+ sm: {
110
109
  trigger: string;
111
110
  item: string;
112
111
  itemIcon: string;
@@ -114,7 +113,7 @@ export declare const dropdownMenu: import("tailwind-variants").TVReturnType<{
114
113
  headerTitle: string;
115
114
  headerSubtitle: string;
116
115
  };
117
- [Size.BASE]: {
116
+ base: {
118
117
  trigger: string;
119
118
  item: string;
120
119
  itemIcon: string;
@@ -122,7 +121,7 @@ export declare const dropdownMenu: import("tailwind-variants").TVReturnType<{
122
121
  headerTitle: string;
123
122
  headerSubtitle: string;
124
123
  };
125
- [Size.LG]: {
124
+ lg: {
126
125
  trigger: string;
127
126
  item: string;
128
127
  itemIcon: string;
@@ -130,7 +129,7 @@ export declare const dropdownMenu: import("tailwind-variants").TVReturnType<{
130
129
  headerTitle: string;
131
130
  headerSubtitle: string;
132
131
  };
133
- [Size.XL]: {
132
+ xl: {
134
133
  trigger: string;
135
134
  item: string;
136
135
  itemIcon: string;
@@ -138,7 +137,7 @@ export declare const dropdownMenu: import("tailwind-variants").TVReturnType<{
138
137
  headerTitle: string;
139
138
  headerSubtitle: string;
140
139
  };
141
- [Size.XXL]: {
140
+ "2xl": {
142
141
  trigger: string;
143
142
  item: string;
144
143
  itemIcon: string;
@@ -181,7 +180,7 @@ export declare const dropdownMenu: import("tailwind-variants").TVReturnType<{
181
180
  };
182
181
  };
183
182
  size: {
184
- [Size.XS]: {
183
+ xs: {
185
184
  trigger: string;
186
185
  item: string;
187
186
  itemIcon: string;
@@ -189,7 +188,7 @@ export declare const dropdownMenu: import("tailwind-variants").TVReturnType<{
189
188
  headerTitle: string;
190
189
  headerSubtitle: string;
191
190
  };
192
- [Size.SM]: {
191
+ sm: {
193
192
  trigger: string;
194
193
  item: string;
195
194
  itemIcon: string;
@@ -197,7 +196,7 @@ export declare const dropdownMenu: import("tailwind-variants").TVReturnType<{
197
196
  headerTitle: string;
198
197
  headerSubtitle: string;
199
198
  };
200
- [Size.BASE]: {
199
+ base: {
201
200
  trigger: string;
202
201
  item: string;
203
202
  itemIcon: string;
@@ -205,7 +204,7 @@ export declare const dropdownMenu: import("tailwind-variants").TVReturnType<{
205
204
  headerTitle: string;
206
205
  headerSubtitle: string;
207
206
  };
208
- [Size.LG]: {
207
+ lg: {
209
208
  trigger: string;
210
209
  item: string;
211
210
  itemIcon: string;
@@ -213,7 +212,7 @@ export declare const dropdownMenu: import("tailwind-variants").TVReturnType<{
213
212
  headerTitle: string;
214
213
  headerSubtitle: string;
215
214
  };
216
- [Size.XL]: {
215
+ xl: {
217
216
  trigger: string;
218
217
  item: string;
219
218
  itemIcon: string;
@@ -221,7 +220,7 @@ export declare const dropdownMenu: import("tailwind-variants").TVReturnType<{
221
220
  headerTitle: string;
222
221
  headerSubtitle: string;
223
222
  };
224
- [Size.XXL]: {
223
+ "2xl": {
225
224
  trigger: string;
226
225
  item: string;
227
226
  itemIcon: string;
@@ -1,42 +1,41 @@
1
- import { Size } from '../../variants.js';
2
1
  export declare const selectTV: import("tailwind-variants").TVReturnType<{
3
2
  size: {
4
- [Size.XS]: {
3
+ xs: {
5
4
  trigger: string;
6
5
  triggerIcon: string;
7
6
  container: string;
8
7
  item: string;
9
8
  base: string;
10
9
  };
11
- [Size.SM]: {
10
+ sm: {
12
11
  trigger: string;
13
12
  triggerIcon: string;
14
13
  container: string;
15
14
  item: string;
16
15
  base: string;
17
16
  };
18
- [Size.BASE]: {
17
+ base: {
19
18
  trigger: string;
20
19
  triggerIcon: string;
21
20
  container: string;
22
21
  item: string;
23
22
  base: string;
24
23
  };
25
- [Size.LG]: {
24
+ lg: {
26
25
  trigger: string;
27
26
  triggerIcon: string;
28
27
  container: string;
29
28
  item: string;
30
29
  base: string;
31
30
  };
32
- [Size.XL]: {
31
+ xl: {
33
32
  trigger: string;
34
33
  triggerIcon: string;
35
34
  container: string;
36
35
  item: string;
37
36
  base: string;
38
37
  };
39
- [Size.XXL]: {
38
+ "2xl": {
40
39
  trigger: string;
41
40
  triggerIcon: string;
42
41
  container: string;
@@ -67,42 +66,42 @@ export declare const selectTV: import("tailwind-variants").TVReturnType<{
67
66
  emptyMessage: string;
68
67
  }, undefined, {
69
68
  size: {
70
- [Size.XS]: {
69
+ xs: {
71
70
  trigger: string;
72
71
  triggerIcon: string;
73
72
  container: string;
74
73
  item: string;
75
74
  base: string;
76
75
  };
77
- [Size.SM]: {
76
+ sm: {
78
77
  trigger: string;
79
78
  triggerIcon: string;
80
79
  container: string;
81
80
  item: string;
82
81
  base: string;
83
82
  };
84
- [Size.BASE]: {
83
+ base: {
85
84
  trigger: string;
86
85
  triggerIcon: string;
87
86
  container: string;
88
87
  item: string;
89
88
  base: string;
90
89
  };
91
- [Size.LG]: {
90
+ lg: {
92
91
  trigger: string;
93
92
  triggerIcon: string;
94
93
  container: string;
95
94
  item: string;
96
95
  base: string;
97
96
  };
98
- [Size.XL]: {
97
+ xl: {
99
98
  trigger: string;
100
99
  triggerIcon: string;
101
100
  container: string;
102
101
  item: string;
103
102
  base: string;
104
103
  };
105
- [Size.XXL]: {
104
+ "2xl": {
106
105
  trigger: string;
107
106
  triggerIcon: string;
108
107
  container: string;
@@ -133,42 +132,42 @@ export declare const selectTV: import("tailwind-variants").TVReturnType<{
133
132
  emptyMessage: string;
134
133
  }, import("tailwind-variants").TVReturnType<{
135
134
  size: {
136
- [Size.XS]: {
135
+ xs: {
137
136
  trigger: string;
138
137
  triggerIcon: string;
139
138
  container: string;
140
139
  item: string;
141
140
  base: string;
142
141
  };
143
- [Size.SM]: {
142
+ sm: {
144
143
  trigger: string;
145
144
  triggerIcon: string;
146
145
  container: string;
147
146
  item: string;
148
147
  base: string;
149
148
  };
150
- [Size.BASE]: {
149
+ base: {
151
150
  trigger: string;
152
151
  triggerIcon: string;
153
152
  container: string;
154
153
  item: string;
155
154
  base: string;
156
155
  };
157
- [Size.LG]: {
156
+ lg: {
158
157
  trigger: string;
159
158
  triggerIcon: string;
160
159
  container: string;
161
160
  item: string;
162
161
  base: string;
163
162
  };
164
- [Size.XL]: {
163
+ xl: {
165
164
  trigger: string;
166
165
  triggerIcon: string;
167
166
  container: string;
168
167
  item: string;
169
168
  base: string;
170
169
  };
171
- [Size.XXL]: {
170
+ "2xl": {
172
171
  trigger: string;
173
172
  triggerIcon: string;
174
173
  container: string;
@@ -1,5 +1,6 @@
1
1
  <script lang="ts">
2
2
  import { cn } from '../../helper/cls.js';
3
+ import { buildTestId } from '../../helper/testid.js';
3
4
  import type { ClassValue } from 'tailwind-variants';
4
5
 
5
6
  /**
@@ -54,6 +55,7 @@
54
55
  activeButtonClass?: ClassValue;
55
56
  /** Use internal state management (when currentPage is not provided) */
56
57
  internalState?: boolean;
58
+ testId?: string;
57
59
  }
58
60
 
59
61
  let {
@@ -80,7 +82,8 @@
80
82
  infoClass = '',
81
83
  buttonClass = '',
82
84
  activeButtonClass = '',
83
- internalState = false
85
+ internalState = false,
86
+ testId
84
87
  }: PaginationProps = $props();
85
88
 
86
89
  // Internal state management
@@ -256,7 +259,10 @@
256
259
  </script>
257
260
 
258
261
  {#if shouldShowPagination}
259
- <div class={cn(defaultWrapperClass, wrapperClass)}>
262
+ <div
263
+ class={cn(defaultWrapperClass, wrapperClass)}
264
+ data-testid={buildTestId('pagination', undefined, testId)}
265
+ >
260
266
  {#if showInfo}
261
267
  <div class="flex items-center gap-2">
262
268
  {#if showPageSize}
@@ -271,6 +277,7 @@
271
277
  value={pageSize}
272
278
  onchange={handlePageSizeChange}
273
279
  {disabled}
280
+ data-testid={buildTestId('pagination', 'size', testId)}
274
281
  >
275
282
  {#each pageSizeOptions as option (option)}
276
283
  <option value={option}>{option}</option>
@@ -316,6 +323,7 @@
316
323
  : defaultInactiveButtonClass
317
324
  )}
318
325
  aria-label="Previous page"
326
+ data-testid={buildTestId('pagination', 'prev', testId)}
319
327
  type="button"
320
328
  >
321
329
 
@@ -338,6 +346,7 @@
338
346
  )}
339
347
  aria-label="Page {pageNum}"
340
348
  aria-current={validCurrentPage === pageNum ? 'page' : undefined}
349
+ data-testid={buildTestId('pagination', 'page', testId, pageNum)}
341
350
  type="button"
342
351
  >
343
352
  {pageNum}
@@ -363,6 +372,7 @@
363
372
  )}
364
373
  aria-label="Page 1"
365
374
  aria-current={validCurrentPage === 1 ? 'page' : undefined}
375
+ data-testid={buildTestId('pagination', 'page', testId, 1)}
366
376
  type="button"
367
377
  >
368
378
  1
@@ -385,6 +395,7 @@
385
395
  )}
386
396
  aria-label="Page {pageNum}"
387
397
  aria-current={validCurrentPage === pageNum ? 'page' : undefined}
398
+ data-testid={buildTestId('pagination', 'page', testId, pageNum)}
388
399
  type="button"
389
400
  >
390
401
  {pageNum}
@@ -407,6 +418,7 @@
407
418
  )}
408
419
  aria-label="Page {totalPages}"
409
420
  aria-current={validCurrentPage === totalPages ? 'page' : undefined}
421
+ data-testid={buildTestId('pagination', 'page', testId, totalPages)}
410
422
  type="button"
411
423
  >
412
424
  {totalPages}
@@ -430,6 +442,7 @@
430
442
  : defaultInactiveButtonClass
431
443
  )}
432
444
  aria-label="Next page"
445
+ data-testid={buildTestId('pagination', 'next', testId)}
433
446
  type="button"
434
447
  >
435
448
 
@@ -51,6 +51,7 @@ export interface PaginationProps {
51
51
  activeButtonClass?: ClassValue;
52
52
  /** Use internal state management (when currentPage is not provided) */
53
53
  internalState?: boolean;
54
+ testId?: string;
54
55
  }
55
56
  declare const Pagination: import("svelte").Component<PaginationProps, {}, "">;
56
57
  type Pagination = ReturnType<typeof Pagination>;
@@ -1,5 +1,6 @@
1
1
  <script lang="ts">
2
2
  import { cn } from '../helper/cls.js';
3
+ import { buildTestId } from '../helper/testid.js';
3
4
  import type { CheckboxProps } from '../index.js';
4
5
 
5
6
  let {
@@ -8,7 +9,8 @@
8
9
  value = $bindable(false),
9
10
  disabled = false,
10
11
  errors = [],
11
- required = false
12
+ required = false,
13
+ testId
12
14
  }: CheckboxProps = $props();
13
15
 
14
16
  const checkboxClass = $derived(
@@ -36,16 +38,26 @@
36
38
  class={checkboxClass}
37
39
  {disabled}
38
40
  {required}
39
- aria-describedby={errors.length ? `${name}-errors` : undefined}
41
+ aria-describedby={errors.length
42
+ ? errors.map((_, i) => `${name}-error-${i}`).join(' ')
43
+ : undefined}
44
+ data-testid={buildTestId('checkbox', undefined, testId)}
40
45
  />
41
46
  {#if label}
42
- <label for={name} class={labelClass}>{label}</label>
47
+ <label for={name} class={labelClass} data-testid={buildTestId('checkbox', 'label', testId)}
48
+ >{label}</label
49
+ >
43
50
  {/if}
44
51
  </div>
45
52
 
46
53
  {#if errors.length}
47
54
  {#each errors as error, i (i)}
48
- <p id={`${name}-errors`} class="text-danger-600 mt-1 text-sm" role="alert">
55
+ <p
56
+ id={`${name}-error-${i}`}
57
+ class="text-danger-600 mt-1 text-sm"
58
+ role="alert"
59
+ data-testid={buildTestId('checkbox', 'error', testId, i)}
60
+ >
49
61
  {error}
50
62
  </p>
51
63
  {/each}
@@ -1,5 +1,4 @@
1
1
  <script lang="ts">
2
- import { setContext } from 'svelte';
3
2
  import { cn } from '../helper/cls.js';
4
3
  import type { FormProps } from '../index.js';
5
4
 
@@ -17,7 +16,6 @@
17
16
  }: FormProps<any> = $props();
18
17
 
19
18
  const { enhance, delayed } = form;
20
- setContext('form', form);
21
19
 
22
20
  const formClasses = $derived(cn('space-y-4', className));
23
21
  </script>
@@ -1,5 +1,6 @@
1
1
  <script lang="ts">
2
2
  import { cn } from '../helper/cls.js';
3
+ import { buildTestId } from '../helper/testid.js';
3
4
  import { Size } from '../variants.js';
4
5
  import type { InputProps } from '../index.js';
5
6
 
@@ -14,6 +15,7 @@
14
15
  size = Size.BASE,
15
16
  value = $bindable(),
16
17
  errors = [],
18
+ testId,
17
19
  ...restProps
18
20
  }: InputProps = $props();
19
21
 
@@ -65,13 +67,22 @@
65
67
  <div class="w-full">
66
68
  {@render Label('mb-2')}
67
69
  {#if type === 'textarea'}
68
- <textarea {...textareaProps as unknown as Record<string, unknown>} bind:value></textarea>
70
+ <textarea
71
+ {...textareaProps as unknown as Record<string, unknown>}
72
+ data-testid={buildTestId('input', undefined, testId)}
73
+ bind:value
74
+ ></textarea>
69
75
  {:else}
70
- <input {...inputProps} bind:value />
76
+ <input {...inputProps} data-testid={buildTestId('input', undefined, testId)} bind:value />
71
77
  {/if}
72
78
  {#if errors.length}
73
79
  {#each errors as error, i (i)}
74
- <p id="{name}-errors" class="text-danger-600 mt-1 text-sm" role="alert">
80
+ <p
81
+ id="{name}-errors"
82
+ class="text-danger-600 mt-1 text-sm"
83
+ role="alert"
84
+ data-testid={buildTestId('input', 'error', testId, i)}
85
+ >
75
86
  {error}
76
87
  </p>
77
88
  {/each}
@@ -89,7 +100,8 @@
89
100
  'text-danger-600': errors.length
90
101
  },
91
102
  extraClass
92
- )}>{label}</label
103
+ )}
104
+ data-testid={buildTestId('input', 'label', testId)}>{label}</label
93
105
  >
94
106
  {/if}
95
107
  {/snippet}
@@ -1,5 +1,6 @@
1
1
  <script lang="ts">
2
2
  import { cn } from '../helper/cls.js';
3
+ import { buildTestId } from '../helper/testid.js';
3
4
  import { Size } from '../variants.js';
4
5
  import type { NumberInputProps } from '../index.js';
5
6
 
@@ -16,6 +17,7 @@
16
17
  disabled = false,
17
18
  dropdownicon: DropdownIcon,
18
19
  onunitchange: onUnitChange,
20
+ testId,
19
21
  ...restProps
20
22
  }: NumberInputProps = $props();
21
23
 
@@ -79,7 +81,11 @@
79
81
 
80
82
  <div class="space-y-1">
81
83
  {#if label}
82
- <label for={name} class="text-default-700 block text-sm font-medium">{label}</label>
84
+ <label
85
+ for={name}
86
+ class="text-default-700 block text-sm font-medium"
87
+ data-testid={buildTestId('numberinput', 'label', testId)}>{label}</label
88
+ >
83
89
  {/if}
84
90
  <div class={containerClass} bind:this={containerRef}>
85
91
  <svg
@@ -106,6 +112,7 @@
106
112
  {placeholder}
107
113
  {disabled}
108
114
  class={inputClass}
115
+ data-testid={buildTestId('numberinput', undefined, testId)}
109
116
  {...restProps}
110
117
  />
111
118
 
@@ -1,5 +1,6 @@
1
1
  <script lang="ts">
2
2
  import { cn } from '../helper/cls.js';
3
+ import { buildTestId } from '../helper/testid.js';
3
4
  import type { RadioInputsProps } from '../index.js';
4
5
 
5
6
  let {
@@ -10,7 +11,8 @@
10
11
  disabled = false,
11
12
  class: className = '',
12
13
  errors = [],
13
- required = false
14
+ required = false,
15
+ testId
14
16
  }: RadioInputsProps = $props();
15
17
 
16
18
  const containerClass = $derived(cn('space-y-2', className));
@@ -35,7 +37,7 @@
35
37
  <label class={labelClass} for={`${name}-${value || options[0].value}`}>{label}</label>
36
38
  {/if}
37
39
  <div class="space-y-2">
38
- {#each options as option (option.value)}
40
+ {#each options as option, index (option.value)}
39
41
  <div class="flex items-center gap-2">
40
42
  <input
41
43
  type="radio"
@@ -46,9 +48,16 @@
46
48
  class={radioClass}
47
49
  {disabled}
48
50
  {required}
49
- aria-describedby={errors.length ? `${name}-errors` : undefined}
51
+ aria-describedby={errors.length
52
+ ? errors.map((_, i) => `${name}-error-${i}`).join(' ')
53
+ : undefined}
54
+ data-testid={buildTestId('radio', 'option', testId, index)}
50
55
  />
51
- <label for={`${name}-${option.value}`} class="text-default-700 text-sm">
56
+ <label
57
+ for={`${name}-${option.value}`}
58
+ class="text-default-700 text-sm"
59
+ data-testid={buildTestId('radio', 'label', testId, index)}
60
+ >
52
61
  {option.label}
53
62
  </label>
54
63
  </div>
@@ -56,7 +65,7 @@
56
65
  </div>
57
66
  {#if errors.length}
58
67
  {#each errors as error, i (i)}
59
- <p id={`${name}-errors`} class="text-danger-600 mt-1 text-sm" role="alert">
68
+ <p id={`${name}-error-${i}`} class="text-danger-600 mt-1 text-sm" role="alert">
60
69
  {error}
61
70
  </p>
62
71
  {/each}
@@ -1,6 +1,7 @@
1
1
  <!-- A unified slider component supporting enum, single value, and range selection -->
2
2
  <script lang="ts">
3
3
  import { cn } from '../helper/cls.js';
4
+ import { buildTestId } from '../helper/testid.js';
4
5
  import { slider } from './slider.js';
5
6
  import { Size } from '../variants.js';
6
7
  import type { SliderProps } from '../index.js';
@@ -36,7 +37,8 @@
36
37
  notation: 'standard' as NotationType,
37
38
  maximumFractionDigits: 1,
38
39
  minimumFractionDigits: 0
39
- }
40
+ },
41
+ testId
40
42
  }: SliderProps = $props();
41
43
 
42
44
  $effect(() => {
@@ -242,13 +244,13 @@
242
244
  {/if}
243
245
  <input type="hidden" name={`${name}[mode]`} bind:value={mode} />
244
246
 
245
- <div class={baseClass}>
247
+ <div class={baseClass} data-testid={buildTestId('slider', undefined, testId)}>
246
248
  <div class="flex items-center justify-between">
247
249
  {#if label}
248
250
  <label for={name} class={labelClass_}>{label}</label>
249
251
  {/if}
250
252
  {#if showValue && mode !== 'enum'}
251
- <div class={valueClass_}>
253
+ <div class={valueClass_} data-testid={buildTestId('slider', 'value', testId)}>
252
254
  {#if mode === 'range'}
253
255
  <span>{formatValue(valueStart)}</span>
254
256
  <span class="mx-1">-</span>
@@ -258,7 +260,7 @@
258
260
  {/if}
259
261
  </div>
260
262
  {:else if showValue && mode === 'enum'}
261
- <div class={valueClass_}>
263
+ <div class={valueClass_} data-testid={buildTestId('slider', 'value', testId)}>
262
264
  <span>{options[getEnumIndex()]?.label || ''}</span>
263
265
  </div>
264
266
  {/if}