@noahbaumgartner/svelte-ui 0.0.5 → 0.0.6

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 (214) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +20 -5
  3. package/dist/components/accordion/Accordion.svelte +16 -6
  4. package/dist/components/accordion/Accordion.svelte.d.ts +3 -1
  5. package/dist/components/accordion/AccordionItem.svelte +106 -67
  6. package/dist/components/accordion/AccordionItem.svelte.d.ts +5 -1
  7. package/dist/components/alert-dialog/AlertDialog.svelte +108 -76
  8. package/dist/components/alert-dialog/AlertDialog.svelte.d.ts +5 -2
  9. package/dist/components/avatar/Avatar.svelte +71 -49
  10. package/dist/components/avatar/Avatar.svelte.d.ts +5 -2
  11. package/dist/components/avatar-group/AvatarGroup.svelte +72 -45
  12. package/dist/components/avatar-group/AvatarGroup.svelte.d.ts +5 -1
  13. package/dist/components/badge/Badge.svelte +50 -28
  14. package/dist/components/badge/Badge.svelte.d.ts +6 -4
  15. package/dist/components/breadcrumb/Breadcrumb.svelte +21 -17
  16. package/dist/components/breadcrumb/Breadcrumb.svelte.d.ts +3 -1
  17. package/dist/components/breadcrumb/BreadcrumbEllipsis.svelte +17 -6
  18. package/dist/components/breadcrumb/BreadcrumbEllipsis.svelte.d.ts +5 -2
  19. package/dist/components/breadcrumb/BreadcrumbItem.svelte +75 -36
  20. package/dist/components/breadcrumb/BreadcrumbItem.svelte.d.ts +8 -5
  21. package/dist/components/breadcrumb/BreadcrumbSeparator.svelte +32 -9
  22. package/dist/components/breadcrumb/BreadcrumbSeparator.svelte.d.ts +10 -17
  23. package/dist/components/button/Button.svelte +206 -168
  24. package/dist/components/button/Button.svelte.d.ts +9 -5
  25. package/dist/components/button-group/ButtonGroup.svelte +52 -55
  26. package/dist/components/button-group/ButtonGroup.svelte.d.ts +3 -1
  27. package/dist/components/calendar/Calendar.svelte +232 -144
  28. package/dist/components/calendar/Calendar.svelte.d.ts +19 -2
  29. package/dist/components/calendar/dates.d.ts +4 -1
  30. package/dist/components/calendar/dates.js +8 -2
  31. package/dist/components/card/Card.svelte +48 -32
  32. package/dist/components/card/Card.svelte.d.ts +3 -1
  33. package/dist/components/card/CardAction.svelte +11 -7
  34. package/dist/components/card/CardAction.svelte.d.ts +3 -1
  35. package/dist/components/card/CardContent.svelte +8 -4
  36. package/dist/components/card/CardContent.svelte.d.ts +3 -1
  37. package/dist/components/card/CardDescription.svelte +11 -7
  38. package/dist/components/card/CardDescription.svelte.d.ts +3 -1
  39. package/dist/components/card/CardFooter.svelte +15 -11
  40. package/dist/components/card/CardFooter.svelte.d.ts +3 -1
  41. package/dist/components/card/CardHeader.svelte +15 -11
  42. package/dist/components/card/CardHeader.svelte.d.ts +3 -1
  43. package/dist/components/card/CardTitle.svelte +11 -7
  44. package/dist/components/card/CardTitle.svelte.d.ts +3 -1
  45. package/dist/components/checkbox/Checkbox.svelte +152 -61
  46. package/dist/components/checkbox/Checkbox.svelte.d.ts +5 -2
  47. package/dist/components/color-picker/ColorPicker.svelte +131 -78
  48. package/dist/components/color-picker/ColorPicker.svelte.d.ts +10 -1
  49. package/dist/components/context-menu/ContextMenu.svelte +78 -61
  50. package/dist/components/context-menu/ContextMenu.svelte.d.ts +5 -2
  51. package/dist/components/context-menu/ContextMenuInfo.svelte +91 -0
  52. package/dist/components/context-menu/ContextMenuInfo.svelte.d.ts +19 -0
  53. package/dist/components/context-menu/ContextMenuItem.svelte +102 -57
  54. package/dist/components/context-menu/ContextMenuItem.svelte.d.ts +10 -5
  55. package/dist/components/context-menu/ContextMenuLabel.svelte +28 -0
  56. package/dist/components/context-menu/ContextMenuLabel.svelte.d.ts +10 -0
  57. package/dist/components/context-menu/ContextMenuSeparator.svelte +29 -0
  58. package/dist/components/context-menu/ContextMenuSeparator.svelte.d.ts +8 -0
  59. package/dist/components/dialog/Dialog.svelte +149 -108
  60. package/dist/components/dialog/Dialog.svelte.d.ts +7 -2
  61. package/dist/components/drawer/Drawer.svelte +240 -189
  62. package/dist/components/drawer/Drawer.svelte.d.ts +7 -2
  63. package/dist/components/empty-state/EmptyState.svelte +67 -47
  64. package/dist/components/empty-state/EmptyState.svelte.d.ts +7 -4
  65. package/dist/components/entry/Entry.svelte +53 -42
  66. package/dist/components/entry/Entry.svelte.d.ts +2 -1
  67. package/dist/components/field/Field.svelte +66 -45
  68. package/dist/components/field/Field.svelte.d.ts +2 -1
  69. package/dist/components/field/FieldContent.svelte +11 -8
  70. package/dist/components/field/FieldContent.svelte.d.ts +2 -1
  71. package/dist/components/field/FieldDescription.svelte +18 -15
  72. package/dist/components/field/FieldDescription.svelte.d.ts +2 -1
  73. package/dist/components/field/FieldError.svelte +22 -13
  74. package/dist/components/field/FieldError.svelte.d.ts +2 -1
  75. package/dist/components/field/FieldGroup.svelte +15 -12
  76. package/dist/components/field/FieldGroup.svelte.d.ts +2 -1
  77. package/dist/components/field/FieldLegend.svelte +23 -14
  78. package/dist/components/field/FieldLegend.svelte.d.ts +2 -1
  79. package/dist/components/field/FieldSeparator.svelte +12 -9
  80. package/dist/components/field/FieldSeparator.svelte.d.ts +2 -1
  81. package/dist/components/field/FieldSet.svelte +18 -15
  82. package/dist/components/field/FieldSet.svelte.d.ts +2 -1
  83. package/dist/components/footer/Footer.svelte +63 -47
  84. package/dist/components/footer/Footer.svelte.d.ts +2 -1
  85. package/dist/components/footer/FooterColumn.svelte +17 -14
  86. package/dist/components/footer/FooterColumn.svelte.d.ts +2 -1
  87. package/dist/components/image/Image.svelte +61 -0
  88. package/dist/components/image/Image.svelte.d.ts +18 -0
  89. package/dist/components/input/Input.svelte +307 -208
  90. package/dist/components/input/Input.svelte.d.ts +12 -1
  91. package/dist/components/input-group/InputGroup.svelte +101 -61
  92. package/dist/components/input-group/InputGroup.svelte.d.ts +2 -1
  93. package/dist/components/input-group/InputGroupAddon.svelte +58 -49
  94. package/dist/components/kbd/Kbd.svelte +39 -30
  95. package/dist/components/kbd/Kbd.svelte.d.ts +2 -1
  96. package/dist/components/kbd/KbdGroup.svelte +15 -12
  97. package/dist/components/kbd/KbdGroup.svelte.d.ts +2 -1
  98. package/dist/components/label/Label.svelte +47 -28
  99. package/dist/components/label/Label.svelte.d.ts +2 -1
  100. package/dist/components/link/Link.svelte +71 -17
  101. package/dist/components/link/Link.svelte.d.ts +2 -1
  102. package/dist/components/mesh-gradient/MeshGradient.svelte +33 -22
  103. package/dist/components/mesh-gradient/MeshGradient.svelte.d.ts +2 -3
  104. package/dist/components/navbar/Navbar.svelte +137 -99
  105. package/dist/components/navbar/Navbar.svelte.d.ts +4 -2
  106. package/dist/components/navigation-menu/NavigationMenu.svelte +37 -20
  107. package/dist/components/navigation-menu/NavigationMenu.svelte.d.ts +4 -2
  108. package/dist/components/navigation-menu/NavigationMenuItem.svelte +131 -89
  109. package/dist/components/navigation-menu/NavigationMenuItem.svelte.d.ts +4 -2
  110. package/dist/components/navigation-menu/NavigationMenuLink.svelte +90 -51
  111. package/dist/components/navigation-menu/NavigationMenuLink.svelte.d.ts +7 -5
  112. package/dist/components/number-stepper/NumberStepper.svelte +39 -20
  113. package/dist/components/number-stepper/NumberStepper.svelte.d.ts +6 -1
  114. package/dist/components/popover/Popover.svelte +85 -65
  115. package/dist/components/popover/Popover.svelte.d.ts +5 -2
  116. package/dist/components/preview-card/PreviewCard.svelte +116 -98
  117. package/dist/components/preview-card/PreviewCard.svelte.d.ts +9 -6
  118. package/dist/components/progress/Progress.svelte +61 -38
  119. package/dist/components/progress/Progress.svelte.d.ts +2 -1
  120. package/dist/components/radio-group/RadioGroup.svelte +24 -19
  121. package/dist/components/radio-group/RadioGroup.svelte.d.ts +2 -1
  122. package/dist/components/radio-group/RadioGroupItem.svelte +101 -54
  123. package/dist/components/radio-group/RadioGroupItem.svelte.d.ts +2 -1
  124. package/dist/components/section/Section.svelte +114 -0
  125. package/dist/components/section/Section.svelte.d.ts +22 -0
  126. package/dist/components/select/Select.svelte +216 -133
  127. package/dist/components/select/Select.svelte.d.ts +11 -2
  128. package/dist/components/separator/Separator.svelte +21 -10
  129. package/dist/components/separator/Separator.svelte.d.ts +2 -1
  130. package/dist/components/sidebar/Sidebar.svelte +142 -108
  131. package/dist/components/sidebar/Sidebar.svelte.d.ts +6 -1
  132. package/dist/components/sidebar/SidebarContent.svelte +15 -12
  133. package/dist/components/sidebar/SidebarContent.svelte.d.ts +2 -1
  134. package/dist/components/sidebar/SidebarFooter.svelte +10 -7
  135. package/dist/components/sidebar/SidebarFooter.svelte.d.ts +2 -1
  136. package/dist/components/sidebar/SidebarGroup.svelte +35 -25
  137. package/dist/components/sidebar/SidebarGroup.svelte.d.ts +2 -1
  138. package/dist/components/sidebar/SidebarHeader.svelte +21 -16
  139. package/dist/components/sidebar/SidebarHeader.svelte.d.ts +6 -1
  140. package/dist/components/sidebar/SidebarInset.svelte +11 -8
  141. package/dist/components/sidebar/SidebarInset.svelte.d.ts +2 -1
  142. package/dist/components/sidebar/SidebarMenu.svelte +13 -10
  143. package/dist/components/sidebar/SidebarMenu.svelte.d.ts +2 -1
  144. package/dist/components/sidebar/SidebarMenuItem.svelte +195 -114
  145. package/dist/components/sidebar/SidebarMenuItem.svelte.d.ts +11 -5
  146. package/dist/components/sidebar/SidebarProvider.svelte +18 -9
  147. package/dist/components/sidebar/SidebarProvider.svelte.d.ts +2 -1
  148. package/dist/components/sidebar/SidebarSeparator.svelte +6 -1
  149. package/dist/components/sidebar/SidebarSeparator.svelte.d.ts +6 -17
  150. package/dist/components/sidebar/SidebarTrigger.svelte +17 -5
  151. package/dist/components/sidebar/SidebarTrigger.svelte.d.ts +4 -2
  152. package/dist/components/skeleton/Skeleton.svelte +26 -16
  153. package/dist/components/skeleton/Skeleton.svelte.d.ts +4 -2
  154. package/dist/components/spinner/Spinner.svelte +71 -46
  155. package/dist/components/spinner/Spinner.svelte.d.ts +2 -1
  156. package/dist/components/switch/Switch.svelte +126 -65
  157. package/dist/components/switch/Switch.svelte.d.ts +4 -2
  158. package/dist/components/table/Table.svelte +135 -76
  159. package/dist/components/table/Table.svelte.d.ts +12 -2
  160. package/dist/components/tabs/Tabs.svelte +173 -116
  161. package/dist/components/tabs/Tabs.svelte.d.ts +10 -8
  162. package/dist/components/textarea/Textarea.svelte +76 -42
  163. package/dist/components/textarea/Textarea.svelte.d.ts +4 -1
  164. package/dist/components/time-picker/TimePicker.svelte +214 -85
  165. package/dist/components/time-picker/TimePicker.svelte.d.ts +18 -1
  166. package/dist/components/toaster/Toaster.svelte +132 -70
  167. package/dist/components/toaster/Toaster.svelte.d.ts +18 -2
  168. package/dist/components/toaster/toast.svelte.d.ts +3 -3
  169. package/dist/components/toggle/Toggle.svelte +25 -4
  170. package/dist/components/toggle/Toggle.svelte.d.ts +1 -1
  171. package/dist/components/tooltip/Tooltip.svelte +87 -58
  172. package/dist/components/tooltip/Tooltip.svelte.d.ts +4 -2
  173. package/dist/icon.d.ts +12 -0
  174. package/dist/icon.js +1 -0
  175. package/dist/index.d.ts +6 -0
  176. package/dist/index.js +5 -0
  177. package/dist/internal/icons/ArrowDown.svelte +14 -0
  178. package/dist/internal/icons/ArrowDown.svelte.d.ts +4 -0
  179. package/dist/internal/icons/ArrowUp.svelte +14 -0
  180. package/dist/internal/icons/ArrowUp.svelte.d.ts +4 -0
  181. package/dist/internal/icons/Calendar.svelte +16 -0
  182. package/dist/internal/icons/Calendar.svelte.d.ts +4 -0
  183. package/dist/internal/icons/Check.svelte +8 -0
  184. package/dist/internal/icons/Check.svelte.d.ts +4 -0
  185. package/dist/internal/icons/ChevronDown.svelte +8 -0
  186. package/dist/internal/icons/ChevronDown.svelte.d.ts +4 -0
  187. package/dist/internal/icons/ChevronLeft.svelte +8 -0
  188. package/dist/internal/icons/ChevronLeft.svelte.d.ts +4 -0
  189. package/dist/internal/icons/ChevronRight.svelte +8 -0
  190. package/dist/internal/icons/ChevronRight.svelte.d.ts +4 -0
  191. package/dist/internal/icons/ChevronUp.svelte +8 -0
  192. package/dist/internal/icons/ChevronUp.svelte.d.ts +4 -0
  193. package/dist/internal/icons/ChevronsUpDown.svelte +14 -0
  194. package/dist/internal/icons/ChevronsUpDown.svelte.d.ts +4 -0
  195. package/dist/internal/icons/Clock.svelte +14 -0
  196. package/dist/internal/icons/Clock.svelte.d.ts +4 -0
  197. package/dist/internal/icons/Ellipsis.svelte +15 -0
  198. package/dist/internal/icons/Ellipsis.svelte.d.ts +4 -0
  199. package/dist/internal/icons/Icon.svelte +33 -0
  200. package/dist/internal/icons/Icon.svelte.d.ts +8 -0
  201. package/dist/internal/icons/Minus.svelte +8 -0
  202. package/dist/internal/icons/Minus.svelte.d.ts +4 -0
  203. package/dist/internal/icons/PanelLeft.svelte +14 -0
  204. package/dist/internal/icons/PanelLeft.svelte.d.ts +4 -0
  205. package/dist/internal/icons/Plus.svelte +14 -0
  206. package/dist/internal/icons/Plus.svelte.d.ts +4 -0
  207. package/dist/internal/icons/User.svelte +14 -0
  208. package/dist/internal/icons/User.svelte.d.ts +4 -0
  209. package/dist/internal/icons/X.svelte +14 -0
  210. package/dist/internal/icons/X.svelte.d.ts +4 -0
  211. package/dist/styles/tokens.css +39 -41
  212. package/package.json +5 -10
  213. package/dist/icons.d.ts +0 -2
  214. package/dist/icons.js +0 -4
@@ -1,16 +1,19 @@
1
1
  import type { Snippet } from 'svelte';
2
2
  import type { HTMLAttributes } from 'svelte/elements';
3
- import type { LucideIcon } from '@lucide/svelte';
3
+ import type { IconComponent } from '../../icon.js';
4
4
  type Props = Omit<HTMLAttributes<HTMLDivElement>, 'children' | 'title'> & {
5
- /** Any Lucide icon (import from `svelte-ui/icons`). */
6
- icon?: LucideIcon;
5
+ /** Any icon component, e.g. from `@lucide/svelte`. */
6
+ icon?: IconComponent;
7
7
  title: string;
8
8
  description?: string;
9
9
  /** `outline` has a dashed border, for empty areas that can be filled. */
10
10
  variant?: 'secondary' | 'outline';
11
11
  /** Optional actions below the text, e.g. a Button that creates the first entry. */
12
12
  children?: Snippet;
13
+ /** Custom media instead of `icon`. */
14
+ media?: Snippet;
15
+ ref?: HTMLDivElement | null;
13
16
  };
14
- declare const EmptyState: import("svelte").Component<Props, {}, "">;
17
+ declare const EmptyState: import("svelte").Component<Props, {}, "ref">;
15
18
  type EmptyState = ReturnType<typeof EmptyState>;
16
19
  export default EmptyState;
@@ -11,12 +11,21 @@
11
11
  children?: Snippet;
12
12
  /** Below the description, e.g. a Link. */
13
13
  footer?: Snippet;
14
+ ref?: HTMLDivElement | null;
14
15
  };
15
16
 
16
- let { title, meta, class: className, children, footer, ...rest }: Props = $props();
17
+ let {
18
+ title,
19
+ meta,
20
+ class: className,
21
+ children,
22
+ footer,
23
+ ref = $bindable(null),
24
+ ...rest
25
+ }: Props = $props();
17
26
  </script>
18
27
 
19
- <div {...rest} class={['entry', className]}>
28
+ <div {...rest} bind:this={ref} class={['entry', className]}>
20
29
  <div class="entry-heading">
21
30
  <h3 class="entry-title">{title}</h3>
22
31
  {#if meta}
@@ -32,52 +41,54 @@
32
41
  </div>
33
42
 
34
43
  <style>
35
- .entry {
36
- display: flex;
37
- flex-direction: column;
38
- align-items: flex-start;
39
- gap: 10px;
40
- box-sizing: border-box;
41
- padding: 24px;
42
- color: var(--color-text);
43
- border: 1px solid var(--color-border-strong);
44
- border-radius: 14px;
45
- }
44
+ @layer svelte-ui {
45
+ .entry {
46
+ display: flex;
47
+ flex-direction: column;
48
+ align-items: flex-start;
49
+ gap: 10px;
50
+ box-sizing: border-box;
51
+ padding: 24px;
52
+ color: var(--color-text);
53
+ border: 1px solid var(--color-border-strong);
54
+ border-radius: 10px;
55
+ }
46
56
 
47
- .entry-heading {
48
- display: flex;
49
- flex-wrap: wrap;
50
- align-items: baseline;
51
- column-gap: 8px;
52
- }
57
+ .entry-heading {
58
+ display: flex;
59
+ flex-wrap: wrap;
60
+ align-items: baseline;
61
+ column-gap: 8px;
62
+ }
53
63
 
54
- .entry-title {
55
- margin: 0;
56
- font-size: 20px;
57
- font-weight: 500;
58
- }
64
+ .entry-title {
65
+ margin: 0;
66
+ font-size: 20px;
67
+ font-weight: 500;
68
+ }
59
69
 
60
- .entry-meta {
61
- font-size: 14px;
62
- color: var(--color-text-muted);
63
- white-space: nowrap;
64
- }
70
+ .entry-meta {
71
+ font-size: 14px;
72
+ color: var(--color-text-muted);
73
+ white-space: nowrap;
74
+ }
65
75
 
66
- .entry-description {
67
- margin: 0;
68
- max-width: 640px;
69
- }
76
+ .entry-description {
77
+ margin: 0;
78
+ max-width: 640px;
79
+ }
70
80
 
71
- .entry-footer {
72
- display: flex;
73
- flex-wrap: wrap;
74
- align-items: center;
75
- gap: 8px;
76
- }
81
+ .entry-footer {
82
+ display: flex;
83
+ flex-wrap: wrap;
84
+ align-items: center;
85
+ gap: 8px;
86
+ }
77
87
 
78
- @media (min-width: 768px) {
79
- .entry {
80
- padding: 32px;
88
+ @media (min-width: 768px) {
89
+ .entry {
90
+ padding: 32px;
91
+ }
81
92
  }
82
93
  }
83
94
  </style>
@@ -9,7 +9,8 @@ type Props = Omit<HTMLAttributes<HTMLDivElement>, 'children' | 'title'> & {
9
9
  children?: Snippet;
10
10
  /** Below the description, e.g. a Link. */
11
11
  footer?: Snippet;
12
+ ref?: HTMLDivElement | null;
12
13
  };
13
- declare const Entry: import("svelte").Component<Props, {}, "">;
14
+ declare const Entry: import("svelte").Component<Props, {}, "ref">;
14
15
  type Entry = ReturnType<typeof Entry>;
15
16
  export default Entry;
@@ -7,72 +7,93 @@
7
7
  orientation?: 'vertical' | 'horizontal' | 'responsive';
8
8
  /** A Label, the control, and optionally FieldDescription and FieldError. Horizontal fields wrap label and description in a FieldContent. */
9
9
  children: Snippet;
10
+ ref?: HTMLDivElement | null;
10
11
  };
11
12
 
12
- let { orientation = 'vertical', class: className, children, ...rest }: Props = $props();
13
+ let {
14
+ orientation = 'vertical',
15
+ class: className,
16
+ children,
17
+ ref = $bindable(null),
18
+ ...rest
19
+ }: Props = $props();
13
20
  </script>
14
21
 
15
- <div {...rest} role="group" class={['field', `field--${orientation}`, className]}>
22
+ <div {...rest} bind:this={ref} role="group" class={['field', `field--${orientation}`, className]}>
16
23
  {@render children()}
17
24
  </div>
18
25
 
19
26
  <style>
20
- .field {
21
- display: flex;
22
- flex-direction: column;
23
- gap: 8px;
24
- width: 100%;
25
- font-size: 13px;
26
- color: var(--color-text);
27
- }
28
-
29
- .field--horizontal {
30
- flex-direction: row;
31
- align-items: center;
32
- }
33
-
34
- .field--horizontal > :global(.label) {
35
- flex: auto;
36
- }
37
-
38
- .field--horizontal:has(> :global(.field-content)) {
39
- align-items: flex-start;
40
- }
41
-
42
- .field--horizontal:has(> :global(.field-content)) > :global(:is(.checkbox, .radio)) {
43
- margin-top: 2px;
44
- }
27
+ @layer svelte-ui {
28
+ .field {
29
+ display: flex;
30
+ flex-direction: column;
31
+ gap: 8px;
32
+ width: 100%;
33
+ font-size: 13px;
34
+ color: var(--color-text);
35
+ }
45
36
 
46
- @container field-group (min-width: 448px) {
47
- .field--responsive {
37
+ .field--horizontal {
48
38
  flex-direction: row;
49
39
  align-items: center;
50
40
  }
51
41
 
52
- .field--responsive > :global(:is(.label, .field-content)) {
42
+ .field--horizontal > :global(.label) {
53
43
  flex: auto;
54
44
  }
55
45
 
56
- .field--responsive:has(> :global(.field-content)) {
46
+ .field--horizontal:has(> :global(.field-content)) {
57
47
  align-items: flex-start;
58
48
  }
59
- }
60
49
 
61
- /* State follows the control, so there is no invalid or disabled prop to keep in sync */
62
- .field:has(:global([aria-invalid='true'])) :global(.label) {
63
- color: var(--color-destructive);
64
- }
50
+ .field--horizontal:has(> :global(.field-content)) > :global(:is(.checkbox, .radio)) {
51
+ margin-top: 2px;
52
+ }
65
53
 
66
- .field:has(:global(:is(.checkbox, .radio, .switch))) :global(.label) {
67
- cursor: pointer;
68
- }
54
+ @container field-group (min-width: 448px) {
55
+ .field--responsive {
56
+ flex-direction: row;
57
+ align-items: center;
58
+ }
69
59
 
70
- /* The control dims itself */
71
- .field:has(:global(:disabled)) > :global(:is(.label, .field-description, .field-content)) {
72
- opacity: 0.5;
73
- }
60
+ .field--responsive > :global(:is(.label, .field-content)) {
61
+ flex: auto;
62
+ }
63
+
64
+ .field--responsive:has(> :global(.field-content)) {
65
+ align-items: flex-start;
66
+ }
67
+ }
68
+
69
+ /* State follows the control, so there is no invalid or disabled prop to keep in sync */
70
+ .field:has(:global([aria-invalid='true'])) :global(.label) {
71
+ color: var(--color-destructive);
72
+ }
73
+
74
+ .field:has(:global(:is(.checkbox, .radio, .switch))) :global(.label) {
75
+ cursor: pointer;
76
+ }
74
77
 
75
- .field:has(:global(:disabled)) :global(.label) {
76
- cursor: not-allowed;
78
+ /* The control dims itself */
79
+ .field:has(:global(:disabled)) > :global(:is(.label, .field-description, .field-content)) {
80
+ opacity: 0.5;
81
+ }
82
+
83
+ .field:has(:global(:disabled)) :global(.label) {
84
+ cursor: not-allowed;
85
+ }
86
+
87
+ @media (forced-colors: active) {
88
+ .field:has(:global(:disabled)) > :global(:is(.label, .field-description, .field-content)) {
89
+ color: GrayText;
90
+ opacity: 1;
91
+ }
92
+
93
+ .field:has(:global([aria-invalid='true'])) :global(.label) {
94
+ color: Mark;
95
+ text-decoration: underline;
96
+ }
97
+ }
77
98
  }
78
99
  </style>
@@ -5,7 +5,8 @@ type Props = Omit<HTMLAttributes<HTMLDivElement>, 'children'> & {
5
5
  orientation?: 'vertical' | 'horizontal' | 'responsive';
6
6
  /** A Label, the control, and optionally FieldDescription and FieldError. Horizontal fields wrap label and description in a FieldContent. */
7
7
  children: Snippet;
8
+ ref?: HTMLDivElement | null;
8
9
  };
9
- declare const Field: import("svelte").Component<Props, {}, "">;
10
+ declare const Field: import("svelte").Component<Props, {}, "ref">;
10
11
  type Field = ReturnType<typeof Field>;
11
12
  export default Field;
@@ -5,21 +5,24 @@
5
5
  type Props = Omit<HTMLAttributes<HTMLDivElement>, 'children'> & {
6
6
  /** Label, FieldDescription and FieldError next to the control in a horizontal Field. */
7
7
  children: Snippet;
8
+ ref?: HTMLDivElement | null;
8
9
  };
9
10
 
10
- let { class: className, children, ...rest }: Props = $props();
11
+ let { class: className, children, ref = $bindable(null), ...rest }: Props = $props();
11
12
  </script>
12
13
 
13
- <div {...rest} class={['field-content', className]}>
14
+ <div {...rest} bind:this={ref} class={['field-content', className]}>
14
15
  {@render children()}
15
16
  </div>
16
17
 
17
18
  <style>
18
- .field-content {
19
- display: flex;
20
- flex: 1;
21
- flex-direction: column;
22
- gap: 4px;
23
- min-width: 0;
19
+ @layer svelte-ui {
20
+ .field-content {
21
+ display: flex;
22
+ flex: 1;
23
+ flex-direction: column;
24
+ gap: 4px;
25
+ min-width: 0;
26
+ }
24
27
  }
25
28
  </style>
@@ -3,7 +3,8 @@ import type { HTMLAttributes } from 'svelte/elements';
3
3
  type Props = Omit<HTMLAttributes<HTMLDivElement>, 'children'> & {
4
4
  /** Label, FieldDescription and FieldError next to the control in a horizontal Field. */
5
5
  children: Snippet;
6
+ ref?: HTMLDivElement | null;
6
7
  };
7
- declare const FieldContent: import("svelte").Component<Props, {}, "">;
8
+ declare const FieldContent: import("svelte").Component<Props, {}, "ref">;
8
9
  type FieldContent = ReturnType<typeof FieldContent>;
9
10
  export default FieldContent;
@@ -5,30 +5,33 @@
5
5
  type Props = Omit<HTMLAttributes<HTMLParagraphElement>, 'children'> & {
6
6
  /** Give it an id and reference it from the control's `aria-describedby`. */
7
7
  children: Snippet;
8
+ ref?: HTMLParagraphElement | null;
8
9
  };
9
10
 
10
- let { class: className, children, ...rest }: Props = $props();
11
+ let { class: className, children, ref = $bindable(null), ...rest }: Props = $props();
11
12
  </script>
12
13
 
13
- <p {...rest} class={['field-description', className]}>
14
+ <p {...rest} bind:this={ref} class={['field-description', className]}>
14
15
  {@render children()}
15
16
  </p>
16
17
 
17
18
  <style>
18
- .field-description {
19
- margin: 0;
20
- font-size: 12px;
21
- line-height: 1.5;
22
- color: var(--color-text-muted);
23
- }
19
+ @layer svelte-ui {
20
+ .field-description {
21
+ margin: 0;
22
+ font-size: 12px;
23
+ line-height: 1.5;
24
+ color: var(--color-text-muted);
25
+ }
24
26
 
25
- .field-description :global(a) {
26
- color: inherit;
27
- text-decoration: underline;
28
- text-underline-offset: 3px;
29
- }
27
+ .field-description :global(a) {
28
+ color: inherit;
29
+ text-decoration: underline;
30
+ text-underline-offset: 3px;
31
+ }
30
32
 
31
- .field-description :global(a:hover) {
32
- color: var(--color-text);
33
+ .field-description :global(a:hover) {
34
+ color: var(--color-text);
35
+ }
33
36
  }
34
37
  </style>
@@ -3,7 +3,8 @@ import type { HTMLAttributes } from 'svelte/elements';
3
3
  type Props = Omit<HTMLAttributes<HTMLParagraphElement>, 'children'> & {
4
4
  /** Give it an id and reference it from the control's `aria-describedby`. */
5
5
  children: Snippet;
6
+ ref?: HTMLParagraphElement | null;
6
7
  };
7
- declare const FieldDescription: import("svelte").Component<Props, {}, "">;
8
+ declare const FieldDescription: import("svelte").Component<Props, {}, "ref">;
8
9
  type FieldDescription = ReturnType<typeof FieldDescription>;
9
10
  export default FieldDescription;
@@ -7,15 +7,16 @@
7
7
  errors?: (string | undefined)[];
8
8
  /** Custom content instead of `errors`. */
9
9
  children?: Snippet;
10
+ ref?: HTMLDivElement | null;
10
11
  };
11
12
 
12
- let { errors = [], class: className, children, ...rest }: Props = $props();
13
+ let { errors = [], class: className, children, ref = $bindable(null), ...rest }: Props = $props();
13
14
 
14
15
  let messages = $derived([...new Set(errors.filter(Boolean))]);
15
16
  </script>
16
17
 
17
18
  {#if children || messages.length}
18
- <div {...rest} role="alert" class={['field-error', className]}>
19
+ <div {...rest} bind:this={ref} role="alert" class={['field-error', className]}>
19
20
  {#if children}
20
21
  {@render children()}
21
22
  {:else if messages.length === 1}
@@ -29,17 +30,25 @@
29
30
  {/if}
30
31
 
31
32
  <style>
32
- .field-error {
33
- font-size: 12px;
34
- line-height: 1.5;
35
- color: var(--color-destructive);
36
- }
33
+ @layer svelte-ui {
34
+ .field-error {
35
+ font-size: 12px;
36
+ line-height: 1.5;
37
+ color: var(--color-destructive);
38
+ }
39
+
40
+ ul {
41
+ display: flex;
42
+ flex-direction: column;
43
+ gap: 2px;
44
+ margin: 0;
45
+ padding-left: 16px;
46
+ }
37
47
 
38
- ul {
39
- display: flex;
40
- flex-direction: column;
41
- gap: 2px;
42
- margin: 0;
43
- padding-left: 16px;
48
+ @media (forced-colors: active) {
49
+ .field-error {
50
+ color: CanvasText;
51
+ }
52
+ }
44
53
  }
45
54
  </style>
@@ -5,7 +5,8 @@ type Props = Omit<HTMLAttributes<HTMLDivElement>, 'children'> & {
5
5
  errors?: (string | undefined)[];
6
6
  /** Custom content instead of `errors`. */
7
7
  children?: Snippet;
8
+ ref?: HTMLDivElement | null;
8
9
  };
9
- declare const FieldError: import("svelte").Component<Props, {}, "">;
10
+ declare const FieldError: import("svelte").Component<Props, {}, "ref">;
10
11
  type FieldError = ReturnType<typeof FieldError>;
11
12
  export default FieldError;
@@ -5,26 +5,29 @@
5
5
  type Props = Omit<HTMLAttributes<HTMLDivElement>, 'children'> & {
6
6
  /** Fields, FieldSets and FieldSeparators. */
7
7
  children: Snippet;
8
+ ref?: HTMLDivElement | null;
8
9
  };
9
10
 
10
- let { class: className, children, ...rest }: Props = $props();
11
+ let { class: className, children, ref = $bindable(null), ...rest }: Props = $props();
11
12
  </script>
12
13
 
13
- <div {...rest} class={['field-group', className]}>
14
+ <div {...rest} bind:this={ref} class={['field-group', className]}>
14
15
  {@render children()}
15
16
  </div>
16
17
 
17
18
  <style>
18
- .field-group {
19
- container: field-group / inline-size;
20
- display: flex;
21
- flex-direction: column;
22
- gap: 24px;
23
- width: 100%;
24
- }
19
+ @layer svelte-ui {
20
+ .field-group {
21
+ container: field-group / inline-size;
22
+ display: flex;
23
+ flex-direction: column;
24
+ gap: 24px;
25
+ width: 100%;
26
+ }
25
27
 
26
- /* Tighter spacing for lists of checkboxes or radios */
27
- .field-group:has(> :global(.field--horizontal)):not(:has(> :global(:not(.field--horizontal)))) {
28
- gap: 12px;
28
+ /* Tighter spacing for lists of checkboxes or radios */
29
+ .field-group:has(> :global(.field--horizontal)):not(:has(> :global(:not(.field--horizontal)))) {
30
+ gap: 12px;
31
+ }
29
32
  }
30
33
  </style>
@@ -3,7 +3,8 @@ import type { HTMLAttributes } from 'svelte/elements';
3
3
  type Props = Omit<HTMLAttributes<HTMLDivElement>, 'children'> & {
4
4
  /** Fields, FieldSets and FieldSeparators. */
5
5
  children: Snippet;
6
+ ref?: HTMLDivElement | null;
6
7
  };
7
- declare const FieldGroup: import("svelte").Component<Props, {}, "">;
8
+ declare const FieldGroup: import("svelte").Component<Props, {}, "ref">;
8
9
  type FieldGroup = ReturnType<typeof FieldGroup>;
9
10
  export default FieldGroup;
@@ -6,29 +6,38 @@
6
6
  /** `label` matches a Label, for a group of checkboxes or radios. */
7
7
  variant?: 'legend' | 'label';
8
8
  children: Snippet;
9
+ ref?: HTMLLegendElement | null;
9
10
  };
10
11
 
11
- let { variant = 'legend', class: className, children, ...rest }: Props = $props();
12
+ let {
13
+ variant = 'legend',
14
+ class: className,
15
+ children,
16
+ ref = $bindable(null),
17
+ ...rest
18
+ }: Props = $props();
12
19
  </script>
13
20
 
14
- <legend {...rest} class={['field-legend', `field-legend--${variant}`, className]}>
21
+ <legend {...rest} bind:this={ref} class={['field-legend', `field-legend--${variant}`, className]}>
15
22
  {@render children()}
16
23
  </legend>
17
24
 
18
25
  <style>
19
- .field-legend {
20
- margin-bottom: 12px;
21
- padding: 0;
22
- font-weight: 600;
23
- line-height: 1.4;
24
- }
26
+ @layer svelte-ui {
27
+ .field-legend {
28
+ margin-bottom: 12px;
29
+ padding: 0;
30
+ font-weight: 600;
31
+ line-height: 1.4;
32
+ }
25
33
 
26
- .field-legend--legend {
27
- font-size: 15px;
28
- }
34
+ .field-legend--legend {
35
+ font-size: 15px;
36
+ }
29
37
 
30
- .field-legend--label {
31
- font-size: 13px;
32
- font-weight: 500;
38
+ .field-legend--label {
39
+ font-size: 13px;
40
+ font-weight: 500;
41
+ }
33
42
  }
34
43
  </style>
@@ -4,7 +4,8 @@ type Props = Omit<HTMLAttributes<HTMLLegendElement>, 'children'> & {
4
4
  /** `label` matches a Label, for a group of checkboxes or radios. */
5
5
  variant?: 'legend' | 'label';
6
6
  children: Snippet;
7
+ ref?: HTMLLegendElement | null;
7
8
  };
8
- declare const FieldLegend: import("svelte").Component<Props, {}, "">;
9
+ declare const FieldLegend: import("svelte").Component<Props, {}, "ref">;
9
10
  type FieldLegend = ReturnType<typeof FieldLegend>;
10
11
  export default FieldLegend;
@@ -6,12 +6,13 @@
6
6
  type Props = Omit<HTMLAttributes<HTMLDivElement>, 'children'> & {
7
7
  /** Optional text in the middle of the line, e.g. "Or continue with". */
8
8
  children?: Snippet;
9
+ ref?: HTMLDivElement | null;
9
10
  };
10
11
 
11
- let { class: className, children, ...rest }: Props = $props();
12
+ let { class: className, children, ref = $bindable(null), ...rest }: Props = $props();
12
13
  </script>
13
14
 
14
- <div {...rest} role="separator" class={['field-separator', className]}>
15
+ <div {...rest} bind:this={ref} role="separator" class={['field-separator', className]}>
15
16
  <Separator style="flex: 1;" />
16
17
  {#if children}
17
18
  <span class="field-separator-content">{@render children()}</span>
@@ -20,12 +21,14 @@
20
21
  </div>
21
22
 
22
23
  <style>
23
- .field-separator {
24
- display: flex;
25
- align-items: center;
26
- gap: 8px;
27
- min-height: 20px;
28
- font-size: 13px;
29
- color: var(--color-text-muted);
24
+ @layer svelte-ui {
25
+ .field-separator {
26
+ display: flex;
27
+ align-items: center;
28
+ gap: 8px;
29
+ min-height: 20px;
30
+ font-size: 13px;
31
+ color: var(--color-text-muted);
32
+ }
30
33
  }
31
34
  </style>
@@ -3,7 +3,8 @@ import type { HTMLAttributes } from 'svelte/elements';
3
3
  type Props = Omit<HTMLAttributes<HTMLDivElement>, 'children'> & {
4
4
  /** Optional text in the middle of the line, e.g. "Or continue with". */
5
5
  children?: Snippet;
6
+ ref?: HTMLDivElement | null;
6
7
  };
7
- declare const FieldSeparator: import("svelte").Component<Props, {}, "">;
8
+ declare const FieldSeparator: import("svelte").Component<Props, {}, "ref">;
8
9
  type FieldSeparator = ReturnType<typeof FieldSeparator>;
9
10
  export default FieldSeparator;