sv5ui 1.1.2 → 1.2.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 (155) hide show
  1. package/README.md +6 -0
  2. package/dist/Alert/Alert.svelte +33 -22
  3. package/dist/Alert/Alert.svelte.d.ts +1 -1
  4. package/dist/Alert/alert.types.d.ts +4 -0
  5. package/dist/Avatar/Avatar.svelte +72 -46
  6. package/dist/Avatar/avatar.types.d.ts +36 -3
  7. package/dist/Avatar/avatar.variants.d.ts +138 -0
  8. package/dist/Avatar/avatar.variants.js +23 -12
  9. package/dist/Avatar/index.d.ts +1 -1
  10. package/dist/AvatarGroup/AvatarGroup.svelte +11 -6
  11. package/dist/AvatarGroup/AvatarGroup.svelte.d.ts +1 -1
  12. package/dist/AvatarGroup/avatar-group.types.d.ts +18 -3
  13. package/dist/AvatarGroup/avatar-group.variants.d.ts +85 -0
  14. package/dist/AvatarGroup/avatar-group.variants.js +19 -29
  15. package/dist/Badge/Badge.svelte +4 -3
  16. package/dist/Badge/Badge.svelte.d.ts +1 -1
  17. package/dist/Badge/badge.types.d.ts +9 -0
  18. package/dist/Breadcrumb/Breadcrumb.svelte +20 -7
  19. package/dist/Breadcrumb/Breadcrumb.svelte.d.ts +1 -1
  20. package/dist/Breadcrumb/breadcrumb.types.d.ts +5 -1
  21. package/dist/Breadcrumb/breadcrumb.variants.d.ts +15 -5
  22. package/dist/Breadcrumb/breadcrumb.variants.js +7 -3
  23. package/dist/Button/Button.svelte +71 -16
  24. package/dist/Button/Button.svelte.d.ts +0 -1
  25. package/dist/Button/button.types.d.ts +61 -2
  26. package/dist/Calendar/Calendar.svelte +4 -0
  27. package/dist/Calendar/Calendar.svelte.d.ts +1 -1
  28. package/dist/Calendar/calendar.types.d.ts +4 -0
  29. package/dist/Card/Card.svelte +5 -4
  30. package/dist/Card/Card.svelte.d.ts +1 -1
  31. package/dist/Card/card.types.d.ts +5 -1
  32. package/dist/Checkbox/Checkbox.svelte +37 -11
  33. package/dist/Checkbox/Checkbox.svelte.d.ts +1 -1
  34. package/dist/Checkbox/checkbox.types.d.ts +16 -1
  35. package/dist/Checkbox/checkbox.variants.d.ts +90 -0
  36. package/dist/Checkbox/checkbox.variants.js +73 -4
  37. package/dist/Chip/Chip.svelte +3 -2
  38. package/dist/Chip/Chip.svelte.d.ts +1 -1
  39. package/dist/Chip/chip.types.d.ts +5 -1
  40. package/dist/Chip/chip.variants.d.ts +135 -45
  41. package/dist/Chip/chip.variants.js +9 -9
  42. package/dist/ContextMenu/ContextMenu.svelte +87 -77
  43. package/dist/ContextMenu/ContextMenu.svelte.d.ts +1 -1
  44. package/dist/ContextMenu/context-menu.types.d.ts +9 -3
  45. package/dist/ContextMenu/context-menu.types.js +1 -1
  46. package/dist/ContextMenu/context-menu.variants.d.ts +74 -160
  47. package/dist/ContextMenu/context-menu.variants.js +63 -95
  48. package/dist/DropdownMenu/DropdownMenu.svelte +37 -43
  49. package/dist/DropdownMenu/DropdownMenu.svelte.d.ts +1 -1
  50. package/dist/DropdownMenu/dropdown-menu.types.d.ts +9 -3
  51. package/dist/DropdownMenu/dropdown-menu.types.js +1 -1
  52. package/dist/DropdownMenu/dropdown-menu.variants.d.ts +79 -230
  53. package/dist/DropdownMenu/dropdown-menu.variants.js +68 -111
  54. package/dist/DropdownMenu/index.d.ts +1 -1
  55. package/dist/Empty/Empty.svelte +68 -33
  56. package/dist/Empty/Empty.svelte.d.ts +1 -1
  57. package/dist/Empty/empty.types.d.ts +26 -9
  58. package/dist/Empty/empty.variants.d.ts +150 -130
  59. package/dist/Empty/empty.variants.js +33 -324
  60. package/dist/FieldGroup/FieldGroup.svelte +11 -6
  61. package/dist/FieldGroup/FieldGroup.svelte.d.ts +1 -1
  62. package/dist/FieldGroup/field-group.types.d.ts +4 -0
  63. package/dist/FormField/FormField.svelte +17 -18
  64. package/dist/FormField/FormField.svelte.d.ts +1 -1
  65. package/dist/FormField/form-field.types.d.ts +4 -0
  66. package/dist/Icon/Icon.svelte +13 -7
  67. package/dist/Icon/icon.types.d.ts +18 -9
  68. package/dist/Input/Input.svelte +30 -29
  69. package/dist/Kbd/Kbd.svelte +13 -3
  70. package/dist/Kbd/Kbd.svelte.d.ts +1 -1
  71. package/dist/Kbd/index.d.ts +1 -1
  72. package/dist/Kbd/kbd.types.d.ts +15 -1
  73. package/dist/Kbd/kbd.variants.d.ts +92 -30
  74. package/dist/Kbd/kbd.variants.js +55 -35
  75. package/dist/Kbd/useKbd.svelte.d.ts +2 -2
  76. package/dist/Kbd/useKbd.svelte.js +34 -41
  77. package/dist/Link/Link.svelte +69 -24
  78. package/dist/Link/Link.svelte.d.ts +1 -1
  79. package/dist/Link/link.types.d.ts +26 -8
  80. package/dist/Link/link.variants.d.ts +35 -60
  81. package/dist/Link/link.variants.js +8 -110
  82. package/dist/Modal/Modal.svelte +9 -1
  83. package/dist/Modal/modal.types.d.ts +5 -0
  84. package/dist/Modal/modal.variants.d.ts +5 -0
  85. package/dist/Modal/modal.variants.js +1 -0
  86. package/dist/Pagination/Pagination.svelte +143 -94
  87. package/dist/Pagination/Pagination.svelte.d.ts +1 -1
  88. package/dist/Pagination/index.d.ts +1 -1
  89. package/dist/Pagination/pagination.types.d.ts +21 -2
  90. package/dist/Pagination/pagination.variants.d.ts +21 -387
  91. package/dist/Pagination/pagination.variants.js +63 -59
  92. package/dist/Popover/Popover.svelte +9 -12
  93. package/dist/Popover/Popover.svelte.d.ts +1 -1
  94. package/dist/Popover/popover.types.d.ts +4 -0
  95. package/dist/Popover/popover.variants.d.ts +5 -75
  96. package/dist/Popover/popover.variants.js +6 -16
  97. package/dist/Progress/Progress.svelte +58 -30
  98. package/dist/Progress/progress.types.d.ts +9 -1
  99. package/dist/Progress/progress.variants.d.ts +55 -25
  100. package/dist/Progress/progress.variants.js +34 -28
  101. package/dist/RadioGroup/RadioGroup.svelte +105 -61
  102. package/dist/RadioGroup/RadioGroup.svelte.d.ts +1 -1
  103. package/dist/RadioGroup/radio-group.types.d.ts +16 -1
  104. package/dist/RadioGroup/radio-group.variants.d.ts +90 -0
  105. package/dist/RadioGroup/radio-group.variants.js +73 -4
  106. package/dist/Select/Select.svelte +9 -6
  107. package/dist/Select/Select.svelte.d.ts +1 -1
  108. package/dist/Select/select.types.d.ts +4 -0
  109. package/dist/SelectMenu/SelectMenu.svelte +436 -0
  110. package/dist/SelectMenu/SelectMenu.svelte.d.ts +5 -0
  111. package/dist/SelectMenu/index.d.ts +2 -0
  112. package/dist/SelectMenu/index.js +1 -0
  113. package/dist/SelectMenu/select-menu.types.d.ts +262 -0
  114. package/dist/SelectMenu/select-menu.types.js +1 -0
  115. package/dist/SelectMenu/select-menu.variants.d.ts +759 -0
  116. package/dist/SelectMenu/select-menu.variants.js +33 -0
  117. package/dist/Separator/Separator.svelte +1 -2
  118. package/dist/Separator/separator.variants.d.ts +1 -5
  119. package/dist/Separator/separator.variants.js +2 -2
  120. package/dist/Skeleton/Skeleton.svelte +18 -2
  121. package/dist/Skeleton/Skeleton.svelte.d.ts +1 -1
  122. package/dist/Skeleton/skeleton.types.d.ts +10 -1
  123. package/dist/Slideover/Slideover.svelte +9 -1
  124. package/dist/Slideover/slideover.types.d.ts +5 -0
  125. package/dist/Slideover/slideover.variants.d.ts +20 -5
  126. package/dist/Slideover/slideover.variants.js +4 -29
  127. package/dist/Switch/Switch.svelte +32 -31
  128. package/dist/Switch/Switch.svelte.d.ts +1 -1
  129. package/dist/Switch/switch.types.d.ts +6 -1
  130. package/dist/Switch/switch.variants.js +6 -6
  131. package/dist/Tabs/Tabs.svelte +6 -9
  132. package/dist/Tabs/Tabs.svelte.d.ts +1 -1
  133. package/dist/Tabs/tabs.types.d.ts +4 -0
  134. package/dist/Tabs/tabs.variants.js +2 -0
  135. package/dist/Textarea/Textarea.svelte +26 -25
  136. package/dist/ThemeModeButton/theme-mode-button.types.d.ts +7 -2
  137. package/dist/Timeline/Timeline.svelte +62 -19
  138. package/dist/Timeline/Timeline.svelte.d.ts +1 -1
  139. package/dist/Timeline/index.d.ts +1 -1
  140. package/dist/Timeline/timeline.types.d.ts +8 -0
  141. package/dist/Tooltip/Tooltip.svelte +12 -10
  142. package/dist/Tooltip/Tooltip.svelte.d.ts +1 -1
  143. package/dist/Tooltip/tooltip.types.d.ts +8 -4
  144. package/dist/Tooltip/tooltip.variants.d.ts +10 -75
  145. package/dist/Tooltip/tooltip.variants.js +8 -17
  146. package/dist/User/User.svelte +13 -9
  147. package/dist/User/User.svelte.d.ts +1 -1
  148. package/dist/User/user.types.d.ts +4 -0
  149. package/dist/User/user.variants.d.ts +60 -0
  150. package/dist/User/user.variants.js +13 -1
  151. package/dist/config.d.ts +4 -0
  152. package/dist/config.js +4 -0
  153. package/dist/index.d.ts +1 -1
  154. package/dist/index.js +1 -1
  155. package/package.json +2 -2
@@ -1,360 +1,69 @@
1
1
  import { tv } from 'tailwind-variants';
2
2
  export const emptyVariants = tv({
3
3
  slots: {
4
- root: 'flex flex-col items-center justify-center rounded-lg text-center',
5
- icon: 'shrink-0',
6
- avatar: 'shrink-0',
7
- title: 'font-medium',
8
- description: '',
9
- actions: 'flex flex-wrap items-center justify-center gap-2'
4
+ root: 'relative flex flex-col items-center justify-center gap-4 rounded-lg p-4 sm:p-6 lg:p-8 min-w-0',
5
+ header: 'flex flex-col items-center gap-2 max-w-sm text-center',
6
+ avatar: 'shrink-0 mb-2',
7
+ title: 'text-on-surface text-pretty font-medium',
8
+ description: 'text-balance text-center',
9
+ body: 'flex flex-col items-center gap-4 max-w-sm',
10
+ actions: 'flex flex-wrap justify-center gap-2 shrink-0',
11
+ footer: 'flex flex-col items-center gap-2 max-w-sm'
10
12
  },
11
13
  variants: {
12
- variant: {
13
- solid: '',
14
- outline: '',
15
- soft: '',
16
- subtle: ''
17
- },
18
- color: {
19
- primary: '',
20
- secondary: '',
21
- tertiary: '',
22
- success: '',
23
- warning: '',
24
- error: '',
25
- info: '',
26
- surface: ''
27
- },
28
14
  size: {
29
15
  xs: {
30
- root: 'gap-2 p-4',
31
- icon: 'size-8',
16
+ avatar: 'size-8 text-base',
32
17
  title: 'text-sm',
33
18
  description: 'text-xs'
34
19
  },
35
20
  sm: {
36
- root: 'gap-2.5 p-5',
37
- icon: 'size-10',
21
+ avatar: 'size-9 text-lg',
38
22
  title: 'text-sm',
39
23
  description: 'text-xs'
40
24
  },
41
25
  md: {
42
- root: 'gap-3 p-6',
43
- icon: 'size-12',
26
+ avatar: 'size-10 text-xl',
44
27
  title: 'text-base',
45
28
  description: 'text-sm'
46
29
  },
47
30
  lg: {
48
- root: 'gap-4 p-8',
49
- icon: 'size-14',
50
- title: 'text-lg',
31
+ avatar: 'size-11 text-[22px]',
32
+ title: 'text-base',
51
33
  description: 'text-sm'
52
34
  },
53
35
  xl: {
54
- root: 'gap-5 p-10',
55
- icon: 'size-16',
56
- title: 'text-xl',
36
+ avatar: 'size-12 text-2xl',
37
+ title: 'text-lg',
57
38
  description: 'text-base'
58
39
  }
59
- }
60
- },
61
- compoundVariants: [
62
- // ========== SOLID VARIANTS ==========
63
- {
64
- variant: 'solid',
65
- color: 'primary',
66
- class: {
67
- root: 'bg-primary text-on-primary',
68
- icon: 'text-on-primary/70',
69
- description: 'text-on-primary/80'
70
- }
71
- },
72
- {
73
- variant: 'solid',
74
- color: 'secondary',
75
- class: {
76
- root: 'bg-secondary text-on-secondary',
77
- icon: 'text-on-secondary/70',
78
- description: 'text-on-secondary/80'
79
- }
80
- },
81
- {
82
- variant: 'solid',
83
- color: 'tertiary',
84
- class: {
85
- root: 'bg-tertiary text-on-tertiary',
86
- icon: 'text-on-tertiary/70',
87
- description: 'text-on-tertiary/80'
88
- }
89
- },
90
- {
91
- variant: 'solid',
92
- color: 'success',
93
- class: {
94
- root: 'bg-success text-on-success',
95
- icon: 'text-on-success/70',
96
- description: 'text-on-success/80'
97
- }
98
- },
99
- {
100
- variant: 'solid',
101
- color: 'warning',
102
- class: {
103
- root: 'bg-warning text-on-warning',
104
- icon: 'text-on-warning/70',
105
- description: 'text-on-warning/80'
106
- }
107
- },
108
- {
109
- variant: 'solid',
110
- color: 'error',
111
- class: {
112
- root: 'bg-error text-on-error',
113
- icon: 'text-on-error/70',
114
- description: 'text-on-error/80'
115
- }
116
40
  },
117
- {
118
- variant: 'solid',
119
- color: 'info',
120
- class: {
121
- root: 'bg-info text-on-info',
122
- icon: 'text-on-info/70',
123
- description: 'text-on-info/80'
124
- }
125
- },
126
- {
127
- variant: 'solid',
128
- color: 'surface',
129
- class: {
130
- root: 'bg-inverse-surface text-inverse-on-surface',
131
- icon: 'text-inverse-on-surface/70',
41
+ variant: {
42
+ solid: {
43
+ root: 'bg-inverse-surface',
44
+ avatar: 'text-inverse-on-surface/70',
45
+ title: 'text-inverse-on-surface',
132
46
  description: 'text-inverse-on-surface/80'
133
- }
134
- },
135
- // ========== OUTLINE VARIANTS ==========
136
- {
137
- variant: 'outline',
138
- color: 'primary',
139
- class: {
140
- root: 'ring ring-inset ring-primary/25 text-primary',
141
- icon: 'text-primary/70',
142
- description: 'text-primary/80'
143
- }
144
- },
145
- {
146
- variant: 'outline',
147
- color: 'secondary',
148
- class: {
149
- root: 'ring ring-inset ring-secondary/25 text-secondary',
150
- icon: 'text-secondary/70',
151
- description: 'text-secondary/80'
152
- }
153
- },
154
- {
155
- variant: 'outline',
156
- color: 'tertiary',
157
- class: {
158
- root: 'ring ring-inset ring-tertiary/25 text-tertiary',
159
- icon: 'text-tertiary/70',
160
- description: 'text-tertiary/80'
161
- }
162
- },
163
- {
164
- variant: 'outline',
165
- color: 'success',
166
- class: {
167
- root: 'ring ring-inset ring-success/25 text-success',
168
- icon: 'text-success/70',
169
- description: 'text-success/80'
170
- }
171
- },
172
- {
173
- variant: 'outline',
174
- color: 'warning',
175
- class: {
176
- root: 'ring ring-inset ring-warning/25 text-warning',
177
- icon: 'text-warning/70',
178
- description: 'text-warning/80'
179
- }
180
- },
181
- {
182
- variant: 'outline',
183
- color: 'error',
184
- class: {
185
- root: 'ring ring-inset ring-error/25 text-error',
186
- icon: 'text-error/70',
187
- description: 'text-error/80'
188
- }
189
- },
190
- {
191
- variant: 'outline',
192
- color: 'info',
193
- class: {
194
- root: 'ring ring-inset ring-info/25 text-info',
195
- icon: 'text-info/70',
196
- description: 'text-info/80'
197
- }
198
- },
199
- {
200
- variant: 'outline',
201
- color: 'surface',
202
- class: {
203
- root: 'ring ring-inset ring-outline-variant text-on-surface',
204
- icon: 'text-on-surface-variant',
47
+ },
48
+ outline: {
49
+ root: 'ring ring-outline-variant',
205
50
  description: 'text-on-surface-variant'
206
- }
207
- },
208
- // ========== SOFT VARIANTS ==========
209
- {
210
- variant: 'soft',
211
- color: 'primary',
212
- class: {
213
- root: 'bg-primary-container text-on-primary-container',
214
- icon: 'text-on-primary-container/70',
215
- description: 'text-on-primary-container/80'
216
- }
217
- },
218
- {
219
- variant: 'soft',
220
- color: 'secondary',
221
- class: {
222
- root: 'bg-secondary-container text-on-secondary-container',
223
- icon: 'text-on-secondary-container/70',
224
- description: 'text-on-secondary-container/80'
225
- }
226
- },
227
- {
228
- variant: 'soft',
229
- color: 'tertiary',
230
- class: {
231
- root: 'bg-tertiary-container text-on-tertiary-container',
232
- icon: 'text-on-tertiary-container/70',
233
- description: 'text-on-tertiary-container/80'
234
- }
235
- },
236
- {
237
- variant: 'soft',
238
- color: 'success',
239
- class: {
240
- root: 'bg-success-container text-on-success-container',
241
- icon: 'text-on-success-container/70',
242
- description: 'text-on-success-container/80'
243
- }
244
- },
245
- {
246
- variant: 'soft',
247
- color: 'warning',
248
- class: {
249
- root: 'bg-warning-container text-on-warning-container',
250
- icon: 'text-on-warning-container/70',
251
- description: 'text-on-warning-container/80'
252
- }
253
- },
254
- {
255
- variant: 'soft',
256
- color: 'error',
257
- class: {
258
- root: 'bg-error-container text-on-error-container',
259
- icon: 'text-on-error-container/70',
260
- description: 'text-on-error-container/80'
261
- }
262
- },
263
- {
264
- variant: 'soft',
265
- color: 'info',
266
- class: {
267
- root: 'bg-info-container text-on-info-container',
268
- icon: 'text-on-info-container/70',
269
- description: 'text-on-info-container/80'
270
- }
271
- },
272
- {
273
- variant: 'soft',
274
- color: 'surface',
275
- class: {
276
- root: 'bg-surface-container-highest text-on-surface',
277
- icon: 'text-on-surface-variant',
51
+ },
52
+ soft: {
53
+ root: 'bg-surface-container-highest/50',
278
54
  description: 'text-on-surface-variant'
279
- }
280
- },
281
- // ========== SUBTLE VARIANTS ==========
282
- {
283
- variant: 'subtle',
284
- color: 'primary',
285
- class: {
286
- root: 'bg-primary-container text-on-primary-container ring ring-inset ring-primary/25',
287
- icon: 'text-on-primary-container/70',
288
- description: 'text-on-primary-container/80'
289
- }
290
- },
291
- {
292
- variant: 'subtle',
293
- color: 'secondary',
294
- class: {
295
- root: 'bg-secondary-container text-on-secondary-container ring ring-inset ring-secondary/25',
296
- icon: 'text-on-secondary-container/70',
297
- description: 'text-on-secondary-container/80'
298
- }
299
- },
300
- {
301
- variant: 'subtle',
302
- color: 'tertiary',
303
- class: {
304
- root: 'bg-tertiary-container text-on-tertiary-container ring ring-inset ring-tertiary/25',
305
- icon: 'text-on-tertiary-container/70',
306
- description: 'text-on-tertiary-container/80'
307
- }
308
- },
309
- {
310
- variant: 'subtle',
311
- color: 'success',
312
- class: {
313
- root: 'bg-success-container text-on-success-container ring ring-inset ring-success/25',
314
- icon: 'text-on-success-container/70',
315
- description: 'text-on-success-container/80'
316
- }
317
- },
318
- {
319
- variant: 'subtle',
320
- color: 'warning',
321
- class: {
322
- root: 'bg-warning-container text-on-warning-container ring ring-inset ring-warning/25',
323
- icon: 'text-on-warning-container/70',
324
- description: 'text-on-warning-container/80'
325
- }
326
- },
327
- {
328
- variant: 'subtle',
329
- color: 'error',
330
- class: {
331
- root: 'bg-error-container text-on-error-container ring ring-inset ring-error/25',
332
- icon: 'text-on-error-container/70',
333
- description: 'text-on-error-container/80'
334
- }
335
- },
336
- {
337
- variant: 'subtle',
338
- color: 'info',
339
- class: {
340
- root: 'bg-info-container text-on-info-container ring ring-inset ring-info/25',
341
- icon: 'text-on-info-container/70',
342
- description: 'text-on-info-container/80'
343
- }
344
- },
345
- {
346
- variant: 'subtle',
347
- color: 'surface',
348
- class: {
349
- root: 'bg-surface-container-highest text-on-surface ring ring-inset ring-outline-variant',
350
- icon: 'text-on-surface-variant',
55
+ },
56
+ subtle: {
57
+ root: 'bg-surface-container-highest/50 ring ring-outline-variant',
58
+ description: 'text-on-surface-variant'
59
+ },
60
+ naked: {
351
61
  description: 'text-on-surface-variant'
352
62
  }
353
63
  }
354
- ],
64
+ },
355
65
  defaultVariants: {
356
66
  variant: 'outline',
357
- color: 'surface',
358
67
  size: 'md'
359
68
  }
360
69
  });
@@ -12,6 +12,7 @@
12
12
  const config = getComponentConfig('fieldGroup', fieldGroupDefaults)
13
13
 
14
14
  let {
15
+ ref = $bindable(null),
15
16
  as = 'div',
16
17
  ui,
17
18
  size = config.defaultVariants.size ?? 'md',
@@ -21,11 +22,9 @@
21
22
  ...restProps
22
23
  }: Props = $props()
23
24
 
24
- const classes = $derived.by(() => {
25
- const slots = fieldGroupVariants({ size, orientation })
26
- return {
27
- root: slots.root({ class: [config.slots.root, className, ui?.root] })
28
- }
25
+ const variantSlots = $derived(fieldGroupVariants({ size, orientation }))
26
+ const classes = $derived({
27
+ root: variantSlots.root({ class: [config.slots.root, className, ui?.root] })
29
28
  })
30
29
 
31
30
  setContext<{
@@ -41,7 +40,13 @@
41
40
  })
42
41
  </script>
43
42
 
44
- <svelte:element this={as} class={classes.root} data-orientation={orientation} {...restProps}>
43
+ <svelte:element
44
+ this={as}
45
+ bind:this={ref}
46
+ class={classes.root}
47
+ data-orientation={orientation}
48
+ {...restProps}
49
+ >
45
50
  {#if children}
46
51
  {@render children()}
47
52
  {/if}
@@ -1,5 +1,5 @@
1
1
  import type { FieldGroupProps } from './field-group.types.js';
2
2
  export type Props = FieldGroupProps;
3
- declare const FieldGroup: import("svelte").Component<FieldGroupProps, {}, "">;
3
+ declare const FieldGroup: import("svelte").Component<FieldGroupProps, {}, "ref">;
4
4
  type FieldGroup = ReturnType<typeof FieldGroup>;
5
5
  export default FieldGroup;
@@ -3,6 +3,10 @@ import type { HTMLAttributes } from 'svelte/elements';
3
3
  import type { ClassNameValue } from 'tailwind-merge';
4
4
  import type { FieldGroupSlots, FieldGroupVariantProps } from './field-group.variants.js';
5
5
  export type FieldGroupProps = Omit<HTMLAttributes<HTMLDivElement>, 'class'> & {
6
+ /**
7
+ * Bindable reference to the root DOM element.
8
+ */
9
+ ref?: HTMLElement | null;
6
10
  /**
7
11
  * The HTML element to render as.
8
12
  * @default 'div'
@@ -13,6 +13,7 @@
13
13
  const config = getComponentConfig('formField', formFieldDefaults)
14
14
 
15
15
  let {
16
+ ref = $bindable(null),
16
17
  ui,
17
18
  name,
18
19
  label,
@@ -36,23 +37,21 @@
36
37
  const id = useId()
37
38
  const ariaId = $derived(name ? `form-field-${name}` : id)
38
39
 
39
- const classes = $derived.by(() => {
40
- const slots = formFieldVariants({ size, required, orientation })
41
- return {
42
- root: slots.root({ class: [config.slots.root, className, ui?.root] }),
43
- wrapper: slots.wrapper({ class: [config.slots.wrapper, ui?.wrapper] }),
44
- labelWrapper: slots.labelWrapper({
45
- class: [config.slots.labelWrapper, ui?.labelWrapper]
46
- }),
47
- label: slots.label({ class: [config.slots.label, ui?.label] }),
48
- container: slots.container({ class: [config.slots.container, ui?.container] }),
49
- description: slots.description({
50
- class: [config.slots.description, ui?.description]
51
- }),
52
- error: slots.error({ class: [config.slots.error, ui?.error] }),
53
- hint: slots.hint({ class: [config.slots.hint, ui?.hint] }),
54
- help: slots.help({ class: [config.slots.help, ui?.help] })
55
- }
40
+ const variantSlots = $derived(formFieldVariants({ size, required, orientation }))
41
+ const classes = $derived({
42
+ root: variantSlots.root({ class: [config.slots.root, className, ui?.root] }),
43
+ wrapper: variantSlots.wrapper({ class: [config.slots.wrapper, ui?.wrapper] }),
44
+ labelWrapper: variantSlots.labelWrapper({
45
+ class: [config.slots.labelWrapper, ui?.labelWrapper]
46
+ }),
47
+ label: variantSlots.label({ class: [config.slots.label, ui?.label] }),
48
+ container: variantSlots.container({ class: [config.slots.container, ui?.container] }),
49
+ description: variantSlots.description({
50
+ class: [config.slots.description, ui?.description]
51
+ }),
52
+ error: variantSlots.error({ class: [config.slots.error, ui?.error] }),
53
+ hint: variantSlots.hint({ class: [config.slots.hint, ui?.hint] }),
54
+ help: variantSlots.help({ class: [config.slots.help, ui?.help] })
56
55
  })
57
56
 
58
57
  const hasError = $derived(error !== undefined && error !== false)
@@ -79,7 +78,7 @@
79
78
  })
80
79
  </script>
81
80
 
82
- <div class={classes.root} {...restProps}>
81
+ <div bind:this={ref} class={classes.root} {...restProps}>
83
82
  <div class={classes.wrapper}>
84
83
  {#if label || labelSlot || hint || hintSlot}
85
84
  <div class={classes.labelWrapper}>
@@ -1,5 +1,5 @@
1
1
  import type { FormFieldProps } from './form-field.types.js';
2
2
  export type Props = FormFieldProps;
3
- declare const FormField: import("svelte").Component<FormFieldProps, {}, "">;
3
+ declare const FormField: import("svelte").Component<FormFieldProps, {}, "ref">;
4
4
  type FormField = ReturnType<typeof FormField>;
5
5
  export default FormField;
@@ -3,6 +3,10 @@ import type { HTMLAttributes } from 'svelte/elements';
3
3
  import type { ClassNameValue } from 'tailwind-merge';
4
4
  import type { FormFieldSlots, FormFieldVariantProps } from './form-field.variants.js';
5
5
  export type FormFieldProps = Omit<HTMLAttributes<HTMLDivElement>, 'class'> & {
6
+ /**
7
+ * Bindable reference to the root DOM element.
8
+ */
9
+ ref?: HTMLElement | null;
6
10
  /**
7
11
  * The name of the form field, used for matching form errors.
8
12
  */
@@ -6,6 +6,7 @@
6
6
 
7
7
  <script lang="ts">
8
8
  import Icon from '@iconify/svelte'
9
+ import { twMerge } from 'tailwind-merge'
9
10
 
10
11
  let {
11
12
  name,
@@ -18,14 +19,19 @@
18
19
  ...restProps
19
20
  }: Props = $props()
20
21
 
21
- const flip = $derived.by(() => {
22
- if (flipH && flipV) return 'horizontal,vertical'
23
- if (flipH) return 'horizontal'
24
- if (flipV) return 'vertical'
25
- return undefined
26
- })
22
+ const flip = $derived(
23
+ flipH && flipV
24
+ ? 'horizontal,vertical'
25
+ : flipH
26
+ ? 'horizontal'
27
+ : flipV
28
+ ? 'vertical'
29
+ : undefined
30
+ )
27
31
 
28
32
  const rotateValue = $derived(rotate ? rotate / 90 : undefined)
33
+
34
+ const iconClass = $derived(twMerge('shrink-0', className))
29
35
  </script>
30
36
 
31
37
  <Icon
@@ -35,6 +41,6 @@
35
41
  {color}
36
42
  {flip}
37
43
  rotate={rotateValue}
38
- class="shrink-0 {className ?? ''}"
44
+ class={iconClass}
39
45
  {...restProps}
40
46
  />
@@ -1,7 +1,6 @@
1
1
  import type { IconProps as IconifyProps } from '@iconify/svelte';
2
+ import type { ClassNameValue } from 'tailwind-merge';
2
3
  export interface IconProps extends Omit<IconifyProps, 'icon' | 'width' | 'height' | 'rotate' | 'flip' | 'class'> {
3
- /** Additional CSS classes */
4
- class?: string;
5
4
  /**
6
5
  * Icon name in Iconify format: "collection:icon-name"
7
6
  * @example "lucide:home", "mdi:account", "heroicons:star"
@@ -9,29 +8,39 @@ export interface IconProps extends Omit<IconifyProps, 'icon' | 'width' | 'height
9
8
  */
10
9
  name: string;
11
10
  /**
12
- * Icon size (applied to both width and height)
13
- * @default "1em"
11
+ * Icon size (applied to both width and height).
12
+ * Accepts a number (pixels) or CSS string value.
13
+ * @default 24
14
14
  * @example 24, "1.5rem", "20px"
15
15
  */
16
16
  size?: number | string;
17
17
  /**
18
- * Icon color (CSS color value)
19
- * @example "red", "#ff0000", "rgb(255, 0, 0)", "currentColor"
18
+ * Icon color (CSS color value).
19
+ * Defaults to `currentColor`, inheriting the parent's text color.
20
+ * Use Tailwind `text-*` classes on the parent or via `class` prop as an alternative.
21
+ * @default "currentColor"
22
+ * @example "red", "#ff0000", "rgb(255, 0, 0)"
20
23
  */
21
24
  color?: string;
22
25
  /**
23
- * Flip icon horizontally
26
+ * Flip icon horizontally.
24
27
  * @default false
25
28
  */
26
29
  flipH?: boolean;
27
30
  /**
28
- * Flip icon vertically
31
+ * Flip icon vertically.
29
32
  * @default false
30
33
  */
31
34
  flipV?: boolean;
32
35
  /**
33
- * Rotate icon by specified degrees
36
+ * Rotate icon by specified degrees (quarter turns only).
37
+ * For arbitrary rotation, use a CSS class like `rotate-45`.
34
38
  * @default 0
35
39
  */
36
40
  rotate?: 0 | 90 | 180 | 270;
41
+ /**
42
+ * Additional CSS classes for the icon.
43
+ * Merged with `shrink-0` via tailwind-merge, so conflicting utilities are resolved correctly.
44
+ */
45
+ class?: ClassNameValue;
37
46
  }