@noahbaumgartner/svelte-ui 0.0.5 → 0.0.7

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 +149 -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
@@ -15,13 +15,25 @@
15
15
  | 'week'
16
16
  | 'color'
17
17
  | 'file';
18
+
19
+ export type InputLabels = {
20
+ increase: string;
21
+ decrease: string;
22
+ chooseDate: string;
23
+ chooseTime: string;
24
+ chooseColor: string;
25
+ };
18
26
  </script>
19
27
 
20
28
  <script lang="ts">
21
29
  import { tick } from 'svelte';
22
30
  import { scale } from 'svelte/transition';
31
+ import { prefersReducedMotion } from 'svelte/motion';
23
32
  import type { HTMLInputAttributes } from 'svelte/elements';
24
- import { Calendar as CalendarIcon, ChevronDown, ChevronUp, Clock } from '@lucide/svelte';
33
+ import CalendarIcon from '../../internal/icons/Calendar.svelte';
34
+ import ChevronDown from '../../internal/icons/ChevronDown.svelte';
35
+ import ChevronUp from '../../internal/icons/ChevronUp.svelte';
36
+ import Clock from '../../internal/icons/Clock.svelte';
25
37
  import Calendar from '../calendar/Calendar.svelte';
26
38
  import ColorPicker from '../color-picker/ColorPicker.svelte';
27
39
  import TimePicker from '../time-picker/TimePicker.svelte';
@@ -30,6 +42,18 @@
30
42
  type Props = Omit<HTMLInputAttributes, 'type'> & {
31
43
  /** Number gets a stepper; date, time and color types open this library's pickers. */
32
44
  type?: InputType;
45
+ /** Accessible names of the built-in buttons and pickers. */
46
+ labels?: Partial<InputLabels>;
47
+ /** The `<input>` element. Bindable. */
48
+ ref?: HTMLInputElement | null;
49
+ };
50
+
51
+ const defaultLabels: InputLabels = {
52
+ increase: 'Increase',
53
+ decrease: 'Decrease',
54
+ chooseDate: 'Choose date',
55
+ chooseTime: 'Choose time',
56
+ chooseColor: 'Choose color'
33
57
  };
34
58
 
35
59
  let {
@@ -39,13 +63,15 @@
39
63
  style,
40
64
  disabled,
41
65
  readonly,
66
+ labels,
67
+ ref = $bindable(null),
42
68
  ...rest
43
69
  }: Props = $props();
44
70
 
45
71
  const pickers = ['date', 'time', 'datetime-local', 'month', 'week'];
46
72
 
47
73
  const id = $props.id();
48
- let input: HTMLInputElement | undefined = $state();
74
+ let mergedLabels = $derived({ ...defaultLabels, ...labels });
49
75
  let wrapperEl: HTMLElement | undefined = $state();
50
76
  let popoverEl: HTMLElement | undefined = $state();
51
77
  let open = $state(false);
@@ -58,18 +84,18 @@
58
84
 
59
85
  /* Updates the native input and fires the events typing would, so bind:value and handlers follow */
60
86
  function set(next: string) {
61
- if (!input) return;
62
- input.value = next;
63
- input.dispatchEvent(new Event('input', { bubbles: true }));
64
- input.dispatchEvent(new Event('change', { bubbles: true }));
87
+ if (!ref) return;
88
+ ref.value = next;
89
+ ref.dispatchEvent(new Event('input', { bubbles: true }));
90
+ ref.dispatchEvent(new Event('change', { bubbles: true }));
65
91
  }
66
92
 
67
93
  function step(direction: 1 | -1) {
68
- if (!input) return;
69
- if (direction === 1) input.stepUp();
70
- else input.stepDown();
71
- set(input.value);
72
- input.focus();
94
+ if (!ref) return;
95
+ if (direction === 1) ref.stepUp();
96
+ else ref.stepDown();
97
+ set(ref.value);
98
+ ref.focus();
73
99
  }
74
100
 
75
101
  async function show() {
@@ -80,7 +106,7 @@
80
106
 
81
107
  function close(restoreFocus = false) {
82
108
  open = false;
83
- if (restoreFocus) input?.focus();
109
+ if (restoreFocus) ref?.focus();
84
110
  }
85
111
 
86
112
  function toggle() {
@@ -139,7 +165,7 @@
139
165
  {...rest}
140
166
  {type}
141
167
  bind:value
142
- bind:this={input}
168
+ bind:this={ref}
143
169
  {disabled}
144
170
  {readonly}
145
171
  class={['input', { 'input--with-controls': type !== 'color' }]}
@@ -153,7 +179,7 @@
153
179
  <button
154
180
  type="button"
155
181
  tabindex="-1"
156
- aria-label="Increase"
182
+ aria-label={mergedLabels.increase}
157
183
  disabled={inactive}
158
184
  onclick={() => step(1)}
159
185
  >
@@ -162,7 +188,7 @@
162
188
  <button
163
189
  type="button"
164
190
  tabindex="-1"
165
- aria-label="Decrease"
191
+ aria-label={mergedLabels.decrease}
166
192
  disabled={inactive}
167
193
  onclick={() => step(-1)}
168
194
  >
@@ -172,7 +198,7 @@
172
198
  {@const Icon = type === 'time' ? Clock : CalendarIcon}
173
199
  <button
174
200
  type="button"
175
- aria-label={type === 'time' ? 'Choose time' : 'Choose date'}
201
+ aria-label={type === 'time' ? mergedLabels.chooseTime : mergedLabels.chooseDate}
176
202
  aria-haspopup="dialog"
177
203
  aria-expanded={open}
178
204
  aria-controls="{id}-picker"
@@ -190,13 +216,13 @@
190
216
  id="{id}-picker"
191
217
  role="dialog"
192
218
  aria-label={type === 'color'
193
- ? 'Choose color'
219
+ ? mergedLabels.chooseColor
194
220
  : type === 'time'
195
- ? 'Choose time'
196
- : 'Choose date'}
221
+ ? mergedLabels.chooseTime
222
+ : mergedLabels.chooseDate}
197
223
  class={['input-popover', `input-popover--${side}`]}
198
224
  bind:this={popoverEl}
199
- transition:scale={{ duration: 140, start: 0.95 }}
225
+ transition:scale={{ duration: prefersReducedMotion.current ? 0 : 140, start: 0.95 }}
200
226
  >
201
227
  {#if type === 'date' || type === 'week' || type === 'month'}
202
228
  <Calendar
@@ -232,228 +258,301 @@
232
258
  {/if}
233
259
  </span>
234
260
  {:else}
235
- <input {...rest} {type} bind:value {disabled} {readonly} {style} class={['input', className]} />
261
+ <input
262
+ {...rest}
263
+ {type}
264
+ bind:value
265
+ bind:this={ref}
266
+ {disabled}
267
+ {readonly}
268
+ {style}
269
+ class={['input', className]}
270
+ />
236
271
  {/if}
237
272
 
238
273
  <style>
239
- .input {
240
- box-sizing: border-box;
241
- width: 100%;
242
- min-width: 0;
243
- height: 32px;
244
- padding: 0 10px;
245
- font-family: inherit;
246
- font-size: 13px;
247
- color: var(--color-text);
248
- background-color: transparent;
249
- border: 1px solid var(--color-border-strong);
250
- border-radius: 10px;
251
- outline: none;
252
- transition: border-color 200ms ease;
253
- }
274
+ @layer svelte-ui {
275
+ .input {
276
+ box-sizing: border-box;
277
+ width: 100%;
278
+ min-width: 0;
279
+ height: 32px;
280
+ padding: 0 10px;
281
+ font-family: inherit;
282
+ font-size: 13px;
283
+ color: var(--color-text);
284
+ background-color: transparent;
285
+ border: 1px solid var(--color-border-strong);
286
+ border-radius: 10px;
287
+ outline: none;
288
+ transition: border-color 200ms ease;
289
+ }
254
290
 
255
- .input::selection {
256
- color: var(--color-accent-foreground);
257
- background-color: var(--color-accent);
258
- }
291
+ .input::selection {
292
+ color: var(--color-accent-foreground);
293
+ background-color: var(--color-accent);
294
+ }
259
295
 
260
- .input[type='file'] {
261
- padding: 0 10px 0 4px;
262
- color: var(--color-text-muted);
263
- cursor: pointer;
264
- }
296
+ .input[type='file'] {
297
+ padding: 0 10px 0 4px;
298
+ color: var(--color-text-muted);
299
+ cursor: pointer;
300
+ }
265
301
 
266
- .input::file-selector-button {
267
- height: 24px;
268
- margin: 3px 8px 0 0;
269
- padding: 0 8px;
270
- font-family: inherit;
271
- font-size: 13px;
272
- font-weight: 500;
273
- color: var(--color-text);
274
- background-color: var(--color-surface);
275
- border: none;
276
- border-radius: 6px;
277
- cursor: pointer;
278
- }
302
+ .input::file-selector-button {
303
+ height: 24px;
304
+ margin: 3px 8px 0 0;
305
+ padding: 0 8px;
306
+ font-family: inherit;
307
+ font-size: 13px;
308
+ font-weight: 500;
309
+ color: var(--color-text);
310
+ background-color: var(--color-surface);
311
+ border: none;
312
+ border-radius: 6px;
313
+ cursor: pointer;
314
+ }
279
315
 
280
- .input[type='search'] {
281
- padding-right: 4px;
282
- }
316
+ .input[type='search'] {
317
+ padding-right: 4px;
318
+ }
283
319
 
284
- /* Native clear button as a ghost button with a gradient X */
285
- .input::-webkit-search-cancel-button {
286
- appearance: none;
287
- width: 24px;
288
- height: 24px;
289
- margin: 0;
290
- border-radius: 6px;
291
- background:
292
- linear-gradient(45deg, transparent 46%, var(--color-text) 46% 54%, transparent 54%),
293
- linear-gradient(-45deg, transparent 46%, var(--color-text) 46% 54%, transparent 54%),
294
- transparent;
295
- background-size:
296
- 10px 10px,
297
- 10px 10px,
298
- auto;
299
- background-position: center;
300
- background-repeat: no-repeat;
301
- cursor: pointer;
302
- }
320
+ /* Native clear button as a ghost button with a gradient X */
321
+ .input::-webkit-search-cancel-button {
322
+ appearance: none;
323
+ width: 24px;
324
+ height: 24px;
325
+ margin: 0;
326
+ border-radius: 6px;
327
+ background:
328
+ linear-gradient(45deg, transparent 46%, var(--color-text) 46% 54%, transparent 54%),
329
+ linear-gradient(-45deg, transparent 46%, var(--color-text) 46% 54%, transparent 54%),
330
+ transparent;
331
+ background-size:
332
+ 10px 10px,
333
+ 10px 10px,
334
+ auto;
335
+ background-position: center;
336
+ background-repeat: no-repeat;
337
+ cursor: pointer;
338
+ }
303
339
 
304
- .input::-webkit-search-cancel-button:hover {
305
- background-color: var(--color-surface);
306
- }
340
+ .input::-webkit-search-cancel-button:hover {
341
+ background-color: var(--color-surface);
342
+ }
307
343
 
308
- .input[type='color'] {
309
- width: 64px;
310
- padding: 3px;
311
- cursor: pointer;
312
- }
344
+ .input[type='color'] {
345
+ width: 64px;
346
+ padding: 3px;
347
+ cursor: pointer;
348
+ }
313
349
 
314
- .input::-webkit-color-swatch-wrapper {
315
- padding: 0;
316
- }
350
+ .input::-webkit-color-swatch-wrapper {
351
+ padding: 0;
352
+ }
317
353
 
318
- .input::-webkit-color-swatch {
319
- border: none;
320
- border-radius: 6px;
321
- }
354
+ .input::-webkit-color-swatch {
355
+ border: none;
356
+ border-radius: 6px;
357
+ }
322
358
 
323
- .input::-moz-color-swatch {
324
- border: none;
325
- border-radius: 6px;
326
- }
359
+ .input::-moz-color-swatch {
360
+ border: none;
361
+ border-radius: 6px;
362
+ }
327
363
 
328
- /* Number and date/time types: custom buttons replace the native spinners and picker icon */
329
- .input-wrapper {
330
- position: relative;
331
- display: flex;
332
- width: 100%;
333
- min-width: 0;
334
- }
364
+ /* Number and date/time types: custom buttons replace the native spinners and picker icon */
365
+ .input-wrapper {
366
+ position: relative;
367
+ display: flex;
368
+ width: 100%;
369
+ min-width: 0;
370
+ }
335
371
 
336
- .input-wrapper--color {
337
- width: fit-content;
338
- }
372
+ .input-wrapper--color {
373
+ width: fit-content;
374
+ }
339
375
 
340
- .input-popover {
341
- position: absolute;
342
- left: 0;
343
- z-index: 60;
344
- display: flex;
345
- gap: 12px;
346
- padding: 12px;
347
- background-color: var(--color-bg);
348
- border: 1px solid var(--color-border);
349
- border-radius: 14px;
350
- box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
351
- }
376
+ .input-popover {
377
+ position: absolute;
378
+ left: 0;
379
+ z-index: 60;
380
+ display: flex;
381
+ gap: 12px;
382
+ padding: 12px;
383
+ background-color: var(--color-bg);
384
+ border: 1px solid var(--color-border);
385
+ border-radius: 14px;
386
+ box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
387
+ }
352
388
 
353
- .input-popover--bottom {
354
- top: calc(100% + 8px);
355
- transform-origin: top left;
356
- }
389
+ .input-popover--bottom {
390
+ top: calc(100% + 8px);
391
+ transform-origin: top left;
392
+ }
357
393
 
358
- .input-popover--top {
359
- bottom: calc(100% + 8px);
360
- transform-origin: bottom left;
361
- }
394
+ .input-popover--top {
395
+ bottom: calc(100% + 8px);
396
+ transform-origin: bottom left;
397
+ }
362
398
 
363
- .input--with-controls {
364
- padding-right: 32px;
365
- }
399
+ .input--with-controls {
400
+ padding-right: 32px;
401
+ }
366
402
 
367
- .input[type='number'] {
368
- appearance: textfield;
369
- }
403
+ .input[type='number'] {
404
+ appearance: textfield;
405
+ }
370
406
 
371
- .input::-webkit-inner-spin-button,
372
- .input::-webkit-outer-spin-button,
373
- .input::-webkit-calendar-picker-indicator {
374
- display: none;
375
- appearance: none;
376
- margin: 0;
377
- }
407
+ .input::-webkit-inner-spin-button,
408
+ .input::-webkit-outer-spin-button,
409
+ .input::-webkit-calendar-picker-indicator {
410
+ display: none;
411
+ appearance: none;
412
+ margin: 0;
413
+ }
378
414
 
379
- .input::-webkit-datetime-edit-fields-wrapper {
380
- padding: 0;
381
- }
415
+ .input::-webkit-datetime-edit-fields-wrapper {
416
+ padding: 0;
417
+ }
382
418
 
383
- .input::-webkit-datetime-edit-text {
384
- color: var(--color-text-muted);
385
- }
419
+ .input::-webkit-datetime-edit-text {
420
+ color: var(--color-text-muted);
421
+ }
386
422
 
387
- .input-controls {
388
- position: absolute;
389
- top: 4px;
390
- right: 4px;
391
- bottom: 4px;
392
- display: flex;
393
- flex-direction: column;
394
- }
423
+ .input-controls {
424
+ position: absolute;
425
+ top: 4px;
426
+ right: 4px;
427
+ bottom: 4px;
428
+ display: flex;
429
+ flex-direction: column;
430
+ }
395
431
 
396
- .input-controls button {
397
- display: flex;
398
- flex: 1;
399
- align-items: center;
400
- justify-content: center;
401
- width: 24px;
402
- padding: 0;
403
- color: var(--color-text-muted);
404
- background-color: transparent;
405
- border: none;
406
- border-radius: 6px;
407
- cursor: pointer;
408
- transition:
409
- background-color 200ms ease,
410
- color 200ms ease;
411
- }
432
+ .input-controls button {
433
+ display: flex;
434
+ flex: 1;
435
+ align-items: center;
436
+ justify-content: center;
437
+ width: 24px;
438
+ padding: 0;
439
+ color: var(--color-text-muted);
440
+ background-color: transparent;
441
+ border: none;
442
+ border-radius: 6px;
443
+ cursor: pointer;
444
+ transition:
445
+ background-color 200ms ease,
446
+ color 200ms ease;
447
+ }
412
448
 
413
- .input-controls button:hover:not(:disabled) {
414
- color: var(--color-text);
415
- background-color: var(--color-surface);
416
- }
449
+ .input-controls button:hover:not(:disabled) {
450
+ color: var(--color-text);
451
+ background-color: var(--color-surface);
452
+ }
417
453
 
418
- .input-controls button:disabled {
419
- cursor: not-allowed;
420
- opacity: 0.5;
421
- }
454
+ .input-controls button:disabled {
455
+ cursor: not-allowed;
456
+ opacity: 0.5;
457
+ }
422
458
 
423
- .input-controls :global(svg) {
424
- width: 14px;
425
- height: 14px;
426
- }
459
+ .input-controls :global(svg) {
460
+ width: 14px;
461
+ height: 14px;
462
+ }
427
463
 
428
- /* Two stacked stepper buttons are half height */
429
- .input-controls button:not(:only-child) {
430
- border-radius: 4px;
431
- }
464
+ /* Two stacked stepper buttons are half height */
465
+ .input-controls button:not(:only-child) {
466
+ border-radius: 4px;
467
+ }
432
468
 
433
- .input-controls button:not(:only-child) :global(svg) {
434
- width: 12px;
435
- height: 12px;
436
- }
469
+ .input-controls button:not(:only-child) :global(svg) {
470
+ width: 12px;
471
+ height: 12px;
472
+ }
437
473
 
438
- .input::placeholder {
439
- color: var(--color-text-faint);
440
- }
474
+ .input::placeholder {
475
+ color: var(--color-text-faint);
476
+ }
441
477
 
442
- .input:focus-visible {
443
- border-color: var(--color-accent);
444
- outline: 1px solid var(--color-accent);
445
- }
478
+ .input:focus-visible {
479
+ border-color: var(--color-accent);
480
+ outline: 1px solid var(--color-accent);
481
+ }
446
482
 
447
- .input[aria-invalid='true'] {
448
- border-color: var(--color-destructive);
449
- }
483
+ .input[aria-invalid='true'] {
484
+ border-color: var(--color-destructive);
485
+ }
450
486
 
451
- .input[aria-invalid='true']:focus-visible {
452
- outline-color: var(--color-destructive);
453
- }
487
+ .input[aria-invalid='true']:focus-visible {
488
+ outline-color: var(--color-destructive);
489
+ }
490
+
491
+ .input:disabled {
492
+ cursor: not-allowed;
493
+ opacity: 0.5;
494
+ }
454
495
 
455
- .input:disabled {
456
- cursor: not-allowed;
457
- opacity: 0.5;
496
+ @media (prefers-reduced-motion: reduce) {
497
+ .input,
498
+ .input-controls button {
499
+ transition: none;
500
+ }
501
+ }
502
+
503
+ @media (forced-colors: active) {
504
+ .input:focus-visible {
505
+ border-color: Highlight;
506
+ outline: 2px solid Highlight;
507
+ }
508
+
509
+ .input[aria-invalid='true'] {
510
+ border-width: 2px;
511
+ border-style: dashed;
512
+ }
513
+
514
+ .input:disabled,
515
+ .input-controls button:disabled {
516
+ color: GrayText;
517
+ border-color: GrayText;
518
+ opacity: 1;
519
+ }
520
+
521
+ .input-controls button:hover:not(:disabled) {
522
+ outline: 1px solid Highlight;
523
+ }
524
+
525
+ .input-controls button:focus-visible {
526
+ outline: 2px solid Highlight;
527
+ }
528
+ }
529
+
530
+ @media (pointer: coarse) {
531
+ .input {
532
+ min-height: 44px;
533
+ }
534
+
535
+ .input-controls {
536
+ top: 0;
537
+ right: 0;
538
+ bottom: 0;
539
+ }
540
+
541
+ .input-controls button {
542
+ min-width: 44px;
543
+ }
544
+
545
+ .input-controls:has(button:not(:only-child)) {
546
+ flex-direction: row;
547
+ }
548
+
549
+ .input--with-controls {
550
+ padding-right: 48px;
551
+ }
552
+
553
+ .input[type='number'].input--with-controls {
554
+ padding-right: 92px;
555
+ }
556
+ }
458
557
  }
459
558
  </style>
@@ -1,10 +1,21 @@
1
1
  /** Checkbox and radio have their own components; buttons are Button; range and hidden are not text fields. */
2
2
  export type InputType = 'text' | 'email' | 'password' | 'tel' | 'url' | 'search' | 'number' | 'date' | 'time' | 'datetime-local' | 'month' | 'week' | 'color' | 'file';
3
+ export type InputLabels = {
4
+ increase: string;
5
+ decrease: string;
6
+ chooseDate: string;
7
+ chooseTime: string;
8
+ chooseColor: string;
9
+ };
3
10
  import type { HTMLInputAttributes } from 'svelte/elements';
4
11
  type Props = Omit<HTMLInputAttributes, 'type'> & {
5
12
  /** Number gets a stepper; date, time and color types open this library's pickers. */
6
13
  type?: InputType;
14
+ /** Accessible names of the built-in buttons and pickers. */
15
+ labels?: Partial<InputLabels>;
16
+ /** The `<input>` element. Bindable. */
17
+ ref?: HTMLInputElement | null;
7
18
  };
8
- declare const Input: import("svelte").Component<Props, {}, "value">;
19
+ declare const Input: import("svelte").Component<Props, {}, "ref" | "value">;
9
20
  type Input = ReturnType<typeof Input>;
10
21
  export default Input;