@sveltier/ui 0.0.0-stage → 0.1.0-alpha.1

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 (331) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +82 -2
  3. package/dist/components/Accordion/Accordion.svelte +74 -0
  4. package/dist/components/Accordion/Accordion.svelte.d.ts +25 -0
  5. package/dist/components/Accordion/accordion.css +88 -0
  6. package/dist/components/Accordion/index.d.ts +2 -0
  7. package/dist/components/Accordion/index.js +1 -0
  8. package/dist/components/Accordion/types.d.ts +64 -0
  9. package/dist/components/Accordion/types.js +1 -0
  10. package/dist/components/Alert/Alert.svelte +88 -0
  11. package/dist/components/Alert/Alert.svelte.d.ts +4 -0
  12. package/dist/components/Alert/alert.css +78 -0
  13. package/dist/components/Alert/index.d.ts +2 -0
  14. package/dist/components/Alert/index.js +1 -0
  15. package/dist/components/Alert/types.d.ts +67 -0
  16. package/dist/components/Alert/types.js +1 -0
  17. package/dist/components/Avatar/Avatar.svelte +47 -0
  18. package/dist/components/Avatar/Avatar.svelte.d.ts +4 -0
  19. package/dist/components/Avatar/avatar.css +34 -0
  20. package/dist/components/Avatar/index.d.ts +2 -0
  21. package/dist/components/Avatar/index.js +1 -0
  22. package/dist/components/Avatar/types.d.ts +47 -0
  23. package/dist/components/Avatar/types.js +1 -0
  24. package/dist/components/Badge/Badge.svelte +53 -0
  25. package/dist/components/Badge/Badge.svelte.d.ts +4 -0
  26. package/dist/components/Badge/badge.css +57 -0
  27. package/dist/components/Badge/index.d.ts +2 -0
  28. package/dist/components/Badge/index.js +1 -0
  29. package/dist/components/Badge/types.d.ts +43 -0
  30. package/dist/components/Badge/types.js +1 -0
  31. package/dist/components/Button/Button.svelte +85 -0
  32. package/dist/components/Button/Button.svelte.d.ts +4 -0
  33. package/dist/components/Button/button.css +132 -0
  34. package/dist/components/Button/index.d.ts +2 -0
  35. package/dist/components/Button/index.js +1 -0
  36. package/dist/components/Button/types.d.ts +76 -0
  37. package/dist/components/Button/types.js +1 -0
  38. package/dist/components/ButtonGroup/ButtonGroup.svelte +61 -0
  39. package/dist/components/ButtonGroup/ButtonGroup.svelte.d.ts +4 -0
  40. package/dist/components/ButtonGroup/button-group.css +39 -0
  41. package/dist/components/ButtonGroup/index.d.ts +2 -0
  42. package/dist/components/ButtonGroup/index.js +1 -0
  43. package/dist/components/ButtonGroup/types.d.ts +48 -0
  44. package/dist/components/ButtonGroup/types.js +1 -0
  45. package/dist/components/Card/Card.svelte +53 -0
  46. package/dist/components/Card/Card.svelte.d.ts +4 -0
  47. package/dist/components/Card/card.css +62 -0
  48. package/dist/components/Card/index.d.ts +2 -0
  49. package/dist/components/Card/index.js +1 -0
  50. package/dist/components/Card/types.d.ts +56 -0
  51. package/dist/components/Card/types.js +1 -0
  52. package/dist/components/Checkbox/Checkbox.svelte +105 -0
  53. package/dist/components/Checkbox/Checkbox.svelte.d.ts +4 -0
  54. package/dist/components/Checkbox/checkbox.css +138 -0
  55. package/dist/components/Checkbox/index.d.ts +2 -0
  56. package/dist/components/Checkbox/index.js +1 -0
  57. package/dist/components/Checkbox/types.d.ts +76 -0
  58. package/dist/components/Checkbox/types.js +1 -0
  59. package/dist/components/Chip/Chip.svelte +109 -0
  60. package/dist/components/Chip/Chip.svelte.d.ts +4 -0
  61. package/dist/components/Chip/chip.css +101 -0
  62. package/dist/components/Chip/index.d.ts +2 -0
  63. package/dist/components/Chip/index.js +1 -0
  64. package/dist/components/Chip/types.d.ts +69 -0
  65. package/dist/components/Chip/types.js +1 -0
  66. package/dist/components/Choice/Choice.svelte +60 -0
  67. package/dist/components/Choice/Choice.svelte.d.ts +4 -0
  68. package/dist/components/Choice/choice.css +75 -0
  69. package/dist/components/Choice/types.d.ts +43 -0
  70. package/dist/components/Choice/types.js +1 -0
  71. package/dist/components/Dialog/Dialog.svelte +36 -0
  72. package/dist/components/Dialog/Dialog.svelte.d.ts +4 -0
  73. package/dist/components/Dialog/index.d.ts +2 -0
  74. package/dist/components/Dialog/index.js +1 -0
  75. package/dist/components/Dialog/types.d.ts +50 -0
  76. package/dist/components/Dialog/types.js +1 -0
  77. package/dist/components/Divider/Divider.svelte +19 -0
  78. package/dist/components/Divider/Divider.svelte.d.ts +4 -0
  79. package/dist/components/Divider/divider.css +23 -0
  80. package/dist/components/Divider/index.d.ts +2 -0
  81. package/dist/components/Divider/index.js +1 -0
  82. package/dist/components/Divider/types.d.ts +10 -0
  83. package/dist/components/Divider/types.js +1 -0
  84. package/dist/components/Field/Field.svelte +95 -0
  85. package/dist/components/Field/Field.svelte.d.ts +4 -0
  86. package/dist/components/Field/field.css +210 -0
  87. package/dist/components/Field/index.d.ts +3 -0
  88. package/dist/components/Field/index.js +2 -0
  89. package/dist/components/Field/types.d.ts +109 -0
  90. package/dist/components/Field/types.js +2 -0
  91. package/dist/components/Form/Form.svelte +93 -0
  92. package/dist/components/Form/Form.svelte.d.ts +8 -0
  93. package/dist/components/Form/form.css +16 -0
  94. package/dist/components/Form/index.d.ts +2 -0
  95. package/dist/components/Form/index.js +1 -0
  96. package/dist/components/Form/types.d.ts +38 -0
  97. package/dist/components/Form/types.js +1 -0
  98. package/dist/components/Icon/Icon.svelte +38 -0
  99. package/dist/components/Icon/Icon.svelte.d.ts +4 -0
  100. package/dist/components/Icon/icon.css +33 -0
  101. package/dist/components/Icon/index.d.ts +2 -0
  102. package/dist/components/Icon/index.js +1 -0
  103. package/dist/components/Icon/types.d.ts +34 -0
  104. package/dist/components/Icon/types.js +1 -0
  105. package/dist/components/List/List.svelte +39 -0
  106. package/dist/components/List/List.svelte.d.ts +4 -0
  107. package/dist/components/List/ListItem.svelte +57 -0
  108. package/dist/components/List/ListItem.svelte.d.ts +4 -0
  109. package/dist/components/List/index.d.ts +3 -0
  110. package/dist/components/List/index.js +2 -0
  111. package/dist/components/List/list.css +127 -0
  112. package/dist/components/List/types.d.ts +67 -0
  113. package/dist/components/List/types.js +1 -0
  114. package/dist/components/Menu/Menu.svelte +195 -0
  115. package/dist/components/Menu/Menu.svelte.d.ts +4 -0
  116. package/dist/components/Menu/index.d.ts +2 -0
  117. package/dist/components/Menu/index.js +1 -0
  118. package/dist/components/Menu/menu.css +103 -0
  119. package/dist/components/Menu/types.d.ts +90 -0
  120. package/dist/components/Menu/types.js +1 -0
  121. package/dist/components/Modal/Modal.svelte +146 -0
  122. package/dist/components/Modal/Modal.svelte.d.ts +4 -0
  123. package/dist/components/Modal/modal.css +150 -0
  124. package/dist/components/Modal/types.d.ts +54 -0
  125. package/dist/components/Modal/types.js +1 -0
  126. package/dist/components/NativeSelect/NativeSelect.svelte +110 -0
  127. package/dist/components/NativeSelect/NativeSelect.svelte.d.ts +25 -0
  128. package/dist/components/NativeSelect/index.d.ts +2 -0
  129. package/dist/components/NativeSelect/index.js +1 -0
  130. package/dist/components/NativeSelect/native-select.css +45 -0
  131. package/dist/components/NativeSelect/types.d.ts +58 -0
  132. package/dist/components/NativeSelect/types.js +1 -0
  133. package/dist/components/NumberField/NumberField.svelte +246 -0
  134. package/dist/components/NumberField/NumberField.svelte.d.ts +4 -0
  135. package/dist/components/NumberField/index.d.ts +2 -0
  136. package/dist/components/NumberField/index.js +1 -0
  137. package/dist/components/NumberField/number-field.css +74 -0
  138. package/dist/components/NumberField/types.d.ts +73 -0
  139. package/dist/components/NumberField/types.js +1 -0
  140. package/dist/components/Popover/Popover.svelte +115 -0
  141. package/dist/components/Popover/Popover.svelte.d.ts +4 -0
  142. package/dist/components/Popover/index.d.ts +2 -0
  143. package/dist/components/Popover/index.js +1 -0
  144. package/dist/components/Popover/popover.css +67 -0
  145. package/dist/components/Popover/types.d.ts +83 -0
  146. package/dist/components/Popover/types.js +1 -0
  147. package/dist/components/Progress/ProgressCircular.svelte +61 -0
  148. package/dist/components/Progress/ProgressCircular.svelte.d.ts +4 -0
  149. package/dist/components/Progress/ProgressLinear.svelte +44 -0
  150. package/dist/components/Progress/ProgressLinear.svelte.d.ts +4 -0
  151. package/dist/components/Progress/index.d.ts +3 -0
  152. package/dist/components/Progress/index.js +2 -0
  153. package/dist/components/Progress/progress-circular.css +61 -0
  154. package/dist/components/Progress/progress-linear.css +67 -0
  155. package/dist/components/Progress/types.d.ts +53 -0
  156. package/dist/components/Progress/types.js +1 -0
  157. package/dist/components/RadioGroup/RadioGroup.svelte +149 -0
  158. package/dist/components/RadioGroup/RadioGroup.svelte.d.ts +25 -0
  159. package/dist/components/RadioGroup/index.d.ts +2 -0
  160. package/dist/components/RadioGroup/index.js +1 -0
  161. package/dist/components/RadioGroup/radio-group.css +139 -0
  162. package/dist/components/RadioGroup/types.d.ts +93 -0
  163. package/dist/components/RadioGroup/types.js +1 -0
  164. package/dist/components/SegmentedControl/SegmentedControl.svelte +70 -0
  165. package/dist/components/SegmentedControl/SegmentedControl.svelte.d.ts +25 -0
  166. package/dist/components/SegmentedControl/index.d.ts +2 -0
  167. package/dist/components/SegmentedControl/index.js +1 -0
  168. package/dist/components/SegmentedControl/segmented-control.css +68 -0
  169. package/dist/components/SegmentedControl/types.d.ts +60 -0
  170. package/dist/components/SegmentedControl/types.js +1 -0
  171. package/dist/components/Sheet/Sheet.svelte +56 -0
  172. package/dist/components/Sheet/Sheet.svelte.d.ts +4 -0
  173. package/dist/components/Sheet/index.d.ts +2 -0
  174. package/dist/components/Sheet/index.js +2 -0
  175. package/dist/components/Sheet/sheet.css +61 -0
  176. package/dist/components/Sheet/types.d.ts +51 -0
  177. package/dist/components/Sheet/types.js +1 -0
  178. package/dist/components/Skeleton/Skeleton.svelte +33 -0
  179. package/dist/components/Skeleton/Skeleton.svelte.d.ts +4 -0
  180. package/dist/components/Skeleton/index.d.ts +2 -0
  181. package/dist/components/Skeleton/index.js +1 -0
  182. package/dist/components/Skeleton/skeleton.css +70 -0
  183. package/dist/components/Skeleton/types.d.ts +25 -0
  184. package/dist/components/Skeleton/types.js +1 -0
  185. package/dist/components/Slider/Slider.svelte +153 -0
  186. package/dist/components/Slider/Slider.svelte.d.ts +4 -0
  187. package/dist/components/Slider/index.d.ts +2 -0
  188. package/dist/components/Slider/index.js +1 -0
  189. package/dist/components/Slider/slider.css +206 -0
  190. package/dist/components/Slider/types.d.ts +102 -0
  191. package/dist/components/Slider/types.js +1 -0
  192. package/dist/components/Switch/Switch.svelte +94 -0
  193. package/dist/components/Switch/Switch.svelte.d.ts +4 -0
  194. package/dist/components/Switch/index.d.ts +2 -0
  195. package/dist/components/Switch/index.js +1 -0
  196. package/dist/components/Switch/switch.css +118 -0
  197. package/dist/components/Switch/types.d.ts +67 -0
  198. package/dist/components/Switch/types.js +1 -0
  199. package/dist/components/Tabs/Tabs.svelte +93 -0
  200. package/dist/components/Tabs/Tabs.svelte.d.ts +25 -0
  201. package/dist/components/Tabs/index.d.ts +2 -0
  202. package/dist/components/Tabs/index.js +1 -0
  203. package/dist/components/Tabs/tabs.css +73 -0
  204. package/dist/components/Tabs/types.d.ts +59 -0
  205. package/dist/components/Tabs/types.js +1 -0
  206. package/dist/components/TextField/TextField.svelte +115 -0
  207. package/dist/components/TextField/TextField.svelte.d.ts +4 -0
  208. package/dist/components/TextField/index.d.ts +2 -0
  209. package/dist/components/TextField/index.js +1 -0
  210. package/dist/components/TextField/types.d.ts +57 -0
  211. package/dist/components/TextField/types.js +1 -0
  212. package/dist/components/Textarea/Textarea.svelte +116 -0
  213. package/dist/components/Textarea/Textarea.svelte.d.ts +4 -0
  214. package/dist/components/Textarea/index.d.ts +2 -0
  215. package/dist/components/Textarea/index.js +1 -0
  216. package/dist/components/Textarea/textarea.css +35 -0
  217. package/dist/components/Textarea/types.d.ts +60 -0
  218. package/dist/components/Textarea/types.js +1 -0
  219. package/dist/components/Tooltip/Tooltip.svelte +161 -0
  220. package/dist/components/Tooltip/Tooltip.svelte.d.ts +4 -0
  221. package/dist/components/Tooltip/index.d.ts +2 -0
  222. package/dist/components/Tooltip/index.js +1 -0
  223. package/dist/components/Tooltip/tooltip.css +44 -0
  224. package/dist/components/Tooltip/types.d.ts +55 -0
  225. package/dist/components/Tooltip/types.js +1 -0
  226. package/dist/core/defaults/DefaultsProvider.svelte +30 -0
  227. package/dist/core/defaults/DefaultsProvider.svelte.d.ts +13 -0
  228. package/dist/core/defaults/context.d.ts +45 -0
  229. package/dist/core/defaults/context.js +38 -0
  230. package/dist/core/display/display.d.ts +39 -0
  231. package/dist/core/display/display.js +53 -0
  232. package/dist/core/errors/codes.d.ts +124 -0
  233. package/dist/core/errors/codes.js +108 -0
  234. package/dist/core/errors/errors.d.ts +8 -0
  235. package/dist/core/errors/errors.js +7 -0
  236. package/dist/core/form/constraints.d.ts +15 -0
  237. package/dist/core/form/constraints.js +42 -0
  238. package/dist/core/form/context.d.ts +19 -0
  239. package/dist/core/form/context.js +4 -0
  240. package/dist/core/form/field.svelte.d.ts +34 -0
  241. package/dist/core/form/field.svelte.js +66 -0
  242. package/dist/core/form/number.d.ts +24 -0
  243. package/dist/core/form/number.js +71 -0
  244. package/dist/core/form/types.d.ts +22 -0
  245. package/dist/core/form/types.js +1 -0
  246. package/dist/core/locale/locale.d.ts +56 -0
  247. package/dist/core/locale/locale.js +82 -0
  248. package/dist/core/overlay/types.d.ts +33 -0
  249. package/dist/core/overlay/types.js +1 -0
  250. package/dist/core/props/classes.d.ts +21 -0
  251. package/dist/core/props/classes.js +44 -0
  252. package/dist/core/props/element.d.ts +18 -0
  253. package/dist/core/props/element.js +1 -0
  254. package/dist/core/props/types.d.ts +47 -0
  255. package/dist/core/props/types.js +16 -0
  256. package/dist/core/provider/UIProvider.svelte +63 -0
  257. package/dist/core/provider/UIProvider.svelte.d.ts +29 -0
  258. package/dist/core/theme/ThemeProvider.svelte +178 -0
  259. package/dist/core/theme/ThemeProvider.svelte.d.ts +25 -0
  260. package/dist/core/theme/color.d.ts +23 -0
  261. package/dist/core/theme/color.js +54 -0
  262. package/dist/core/theme/context.d.ts +25 -0
  263. package/dist/core/theme/context.js +14 -0
  264. package/dist/core/theme/css.d.ts +25 -0
  265. package/dist/core/theme/css.js +73 -0
  266. package/dist/core/theme/define.d.ts +11 -0
  267. package/dist/core/theme/define.js +21 -0
  268. package/dist/core/theme/resolve.d.ts +6 -0
  269. package/dist/core/theme/resolve.js +18 -0
  270. package/dist/core/theme/theme-provider.css +13 -0
  271. package/dist/core/theme/types.d.ts +35 -0
  272. package/dist/core/theme/types.js +61 -0
  273. package/dist/core/toast/ToastOutlet.svelte +192 -0
  274. package/dist/core/toast/ToastOutlet.svelte.d.ts +11 -0
  275. package/dist/core/toast/ToastProvider.svelte +39 -0
  276. package/dist/core/toast/ToastProvider.svelte.d.ts +19 -0
  277. package/dist/core/toast/toast.css +134 -0
  278. package/dist/core/toast/toast.svelte.d.ts +117 -0
  279. package/dist/core/toast/toast.svelte.js +133 -0
  280. package/dist/dev/off.d.ts +5 -0
  281. package/dist/dev/off.js +4 -0
  282. package/dist/dev/on.d.ts +20 -0
  283. package/dist/dev/on.js +49 -0
  284. package/dist/index.d.ts +67 -0
  285. package/dist/index.js +83 -0
  286. package/dist/primitives/anchored/anchored.d.ts +39 -0
  287. package/dist/primitives/anchored/anchored.js +104 -0
  288. package/dist/primitives/anchored/fallback.d.ts +31 -0
  289. package/dist/primitives/anchored/fallback.js +73 -0
  290. package/dist/primitives/focus/focus-trap.d.ts +25 -0
  291. package/dist/primitives/focus/focus-trap.js +86 -0
  292. package/dist/primitives/focus/roving-focus.d.ts +22 -0
  293. package/dist/primitives/focus/roving-focus.js +86 -0
  294. package/dist/primitives/focus/tabbable.d.ts +9 -0
  295. package/dist/primitives/focus/tabbable.js +75 -0
  296. package/dist/primitives/inert/inert-others.d.ts +12 -0
  297. package/dist/primitives/inert/inert-others.js +44 -0
  298. package/dist/primitives/keyboard/keymap.d.ts +17 -0
  299. package/dist/primitives/keyboard/keymap.js +39 -0
  300. package/dist/primitives/keyboard/typeahead.d.ts +18 -0
  301. package/dist/primitives/keyboard/typeahead.js +50 -0
  302. package/dist/primitives/layer/dismissable.d.ts +32 -0
  303. package/dist/primitives/layer/dismissable.js +91 -0
  304. package/dist/primitives/motion/easing.d.ts +9 -0
  305. package/dist/primitives/motion/easing.js +46 -0
  306. package/dist/primitives/motion/motion.d.ts +59 -0
  307. package/dist/primitives/motion/motion.js +80 -0
  308. package/dist/primitives/portal/Portal.svelte +37 -0
  309. package/dist/primitives/portal/Portal.svelte.d.ts +9 -0
  310. package/dist/primitives/portal/PortalContent.svelte +15 -0
  311. package/dist/primitives/portal/PortalContent.svelte.d.ts +9 -0
  312. package/dist/primitives/portal/portal.css +8 -0
  313. package/dist/primitives/scroll-lock/scroll-lock.d.ts +10 -0
  314. package/dist/primitives/scroll-lock/scroll-lock.js +33 -0
  315. package/dist/primitives/virtual/virtual-list.svelte.d.ts +65 -0
  316. package/dist/primitives/virtual/virtual-list.svelte.js +291 -0
  317. package/dist/styles/base.css +44 -0
  318. package/dist/styles/props.css +140 -0
  319. package/dist/styles/tokens.css +84 -0
  320. package/dist/styles/visually-hidden.css +16 -0
  321. package/dist/themes/aurora.d.ts +13 -0
  322. package/dist/themes/aurora.js +103 -0
  323. package/dist/themes/heritage.d.ts +13 -0
  324. package/dist/themes/heritage.js +102 -0
  325. package/dist/themes/maison.d.ts +13 -0
  326. package/dist/themes/maison.js +99 -0
  327. package/dist/themes/milano.d.ts +13 -0
  328. package/dist/themes/milano.js +101 -0
  329. package/dist/themes/monolith.d.ts +13 -0
  330. package/dist/themes/monolith.js +101 -0
  331. package/package.json +87 -5
@@ -0,0 +1,34 @@
1
+ @layer sv.tokens, sv.base, sv.components, sv.utilities;
2
+
3
+ @layer sv.components {
4
+ /* As tall as a control of its size; initials are φ⁻² of that. */
5
+ .sv-avatar {
6
+ position: relative;
7
+ display: inline-flex;
8
+ flex: none;
9
+ align-items: center;
10
+ justify-content: center;
11
+ box-sizing: border-box;
12
+ inline-size: var(--sv-size-height);
13
+ block-size: var(--sv-size-height);
14
+ overflow: hidden;
15
+ border: var(--sv-hairline) solid var(--sv-variant-border);
16
+ border-radius: var(--sv-rounded, var(--sv-radius-full));
17
+ background-color: var(--sv-variant-bg);
18
+ box-shadow: var(--sv-variant-shadow);
19
+ color: var(--sv-variant-fg);
20
+ font: var(--sv-weight-medium) calc(var(--sv-size-height) * 0.382) / 1 var(--sv-font-ui);
21
+ letter-spacing: 0.02em;
22
+ text-transform: uppercase;
23
+ vertical-align: middle;
24
+ user-select: none;
25
+ }
26
+
27
+ .sv-avatar__image {
28
+ position: absolute;
29
+ inset: 0;
30
+ inline-size: 100%;
31
+ block-size: 100%;
32
+ object-fit: cover;
33
+ }
34
+ }
@@ -0,0 +1,2 @@
1
+ export { default as Avatar } from './Avatar.svelte';
2
+ export type { AvatarDefaults, AvatarProps } from './types.js';
@@ -0,0 +1 @@
1
+ export { default as Avatar } from './Avatar.svelte';
@@ -0,0 +1,47 @@
1
+ import type { Snippet } from 'svelte';
2
+ import type { HTMLAttributes } from 'svelte/elements';
3
+ import type { ElementProps } from '../../core/props/element.js';
4
+ import type { Color, Rounded, Size, Variant } from '../../core/props/types.js';
5
+ /** The Avatar props that `DefaultsProvider` and `UIProvider` can set for a subtree. */
6
+ export interface AvatarDefaults {
7
+ /**
8
+ * Width and height: the control height of the size.
9
+ * @default 'md'
10
+ */
11
+ size: Size;
12
+ /**
13
+ * How the fallback is painted.
14
+ * @default 'tonal'
15
+ */
16
+ variant: Variant;
17
+ /**
18
+ * The colour of the fallback.
19
+ * @default 'neutral'
20
+ */
21
+ color: Color;
22
+ /**
23
+ * Corner rounding.
24
+ * @default 'full'
25
+ */
26
+ rounded: Rounded;
27
+ }
28
+ declare module '../../core/defaults/context.js' {
29
+ interface ComponentDefaults {
30
+ Avatar: AvatarDefaults;
31
+ }
32
+ }
33
+ /**
34
+ * A picture of a person or an account: an image, or initials or an icon when there is none
35
+ * or it fails to load.
36
+ */
37
+ export type AvatarProps = ElementProps<HTMLSpanElement, HTMLAttributes<HTMLSpanElement>, Partial<AvatarDefaults> & {
38
+ /** The image. */
39
+ src?: string;
40
+ /**
41
+ * Who or what the avatar shows, for screen readers. Leave it out when a name is shown next
42
+ * to the avatar: it is then decorative and hidden from them.
43
+ */
44
+ alt?: string;
45
+ /** Initials or an icon, shown while there is no image or it failed to load. */
46
+ children?: Snippet;
47
+ }>;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,53 @@
1
+ <script lang="ts">
2
+ // A count or a dot on its content, or alone in a line. See BadgeProps for the props.
3
+ import { useDefaults } from '../../core/defaults/context.js';
4
+ import { sharedClasses } from '../../core/props/classes.js';
5
+ import '../../styles/visually-hidden.css';
6
+ import './badge.css';
7
+ import type { BadgeDefaults, BadgeProps } from './types.js';
8
+
9
+ let {
10
+ color,
11
+ max,
12
+ content,
13
+ dot = false,
14
+ label,
15
+ children,
16
+ id,
17
+ class: className,
18
+ ref = $bindable(null),
19
+ ...rest
20
+ }: BadgeProps = $props();
21
+
22
+ const resolve = useDefaults<BadgeDefaults>('Badge', { color: 'primary', max: 99 });
23
+ const p = $derived(resolve({ color, max }));
24
+
25
+ const visible = $derived(dot || (content != null && content !== 0 && content !== ''));
26
+ const shown = $derived(
27
+ typeof content === 'number' && content > p.max ? `${p.max}+` : String(content ?? '')
28
+ );
29
+ // Screen readers hear the real count, with what it counts.
30
+ const spoken = $derived(dot ? label : [content, label].filter((part) => part != null).join(' '));
31
+ </script>
32
+
33
+ <span
34
+ bind:this={ref}
35
+ {...rest}
36
+ {id}
37
+ class={['sv-badge', !children && 'sv-badge--inline', className]}
38
+ >
39
+ {@render children?.()}
40
+ {#if visible}
41
+ <span class="sv-badge__anchor" aria-hidden="true">
42
+ <span
43
+ class={[
44
+ 'sv-badge__badge',
45
+ sharedClasses({ variant: 'flat', color: p.color }, 'Badge'),
46
+ dot && 'sv-badge__badge--dot'
47
+ ]}>{dot ? '' : shown}</span
48
+ >
49
+ </span>
50
+ <!-- With an id, the content can point at this text: aria-describedby="{id}-label". -->
51
+ {#if spoken}<span class="sv-visually-hidden" id={id && `${id}-label`}>{spoken}</span>{/if}
52
+ {/if}
53
+ </span>
@@ -0,0 +1,4 @@
1
+ import type { BadgeProps } from './types.js';
2
+ declare const Badge: import("svelte").Component<BadgeProps, {}, "ref">;
3
+ type Badge = ReturnType<typeof Badge>;
4
+ export default Badge;
@@ -0,0 +1,57 @@
1
+ @layer sv.tokens, sv.base, sv.components, sv.utilities;
2
+
3
+ @layer sv.components {
4
+ .sv-badge {
5
+ position: relative;
6
+ display: inline-flex;
7
+ flex: none;
8
+ vertical-align: middle;
9
+ }
10
+
11
+ /*
12
+ * A point at the top end corner of the content. The badge is centred on it by flex
13
+ * alignment, overflowing evenly, so it follows the writing direction with no direction
14
+ * selector (minifiers rewrite :dir() into language guesses for older browsers).
15
+ */
16
+ .sv-badge__anchor {
17
+ position: absolute;
18
+ inset-block-start: 0;
19
+ inset-inline-end: 0;
20
+ display: flex;
21
+ align-items: center;
22
+ justify-content: center;
23
+ inline-size: 0;
24
+ block-size: 0;
25
+ pointer-events: none;
26
+ }
27
+
28
+ .sv-badge--inline .sv-badge__anchor {
29
+ position: static;
30
+ display: contents;
31
+ }
32
+
33
+ /* A pill φ times its text. */
34
+ .sv-badge__badge {
35
+ display: inline-flex;
36
+ flex: none;
37
+ align-items: center;
38
+ justify-content: center;
39
+ box-sizing: border-box;
40
+ min-inline-size: 1.618em;
41
+ block-size: 1.618em;
42
+ padding-inline: 0.382em;
43
+ border-radius: var(--sv-radius-full);
44
+ background-color: var(--sv-variant-bg);
45
+ color: var(--sv-variant-fg);
46
+ font: var(--sv-weight-medium) var(--sv-text-label) / 1 var(--sv-font-ui);
47
+ font-variant-numeric: tabular-nums;
48
+ white-space: nowrap;
49
+ }
50
+
51
+ .sv-badge__badge--dot {
52
+ min-inline-size: 0.618em;
53
+ inline-size: 0.618em;
54
+ block-size: 0.618em;
55
+ padding: 0;
56
+ }
57
+ }
@@ -0,0 +1,2 @@
1
+ export { default as Badge } from './Badge.svelte';
2
+ export type { BadgeDefaults, BadgeProps } from './types.js';
@@ -0,0 +1 @@
1
+ export { default as Badge } from './Badge.svelte';
@@ -0,0 +1,43 @@
1
+ import type { Snippet } from 'svelte';
2
+ import type { HTMLAttributes } from 'svelte/elements';
3
+ import type { ElementProps } from '../../core/props/element.js';
4
+ import type { Color } from '../../core/props/types.js';
5
+ /** The Badge props that `DefaultsProvider` and `UIProvider` can set for a subtree. */
6
+ export interface BadgeDefaults {
7
+ /**
8
+ * The badge's fill.
9
+ * @default 'primary'
10
+ */
11
+ color: Color;
12
+ /**
13
+ * Counts above it show as `max+`.
14
+ * @default 99
15
+ */
16
+ max: number;
17
+ }
18
+ declare module '../../core/defaults/context.js' {
19
+ interface ComponentDefaults {
20
+ Badge: BadgeDefaults;
21
+ }
22
+ }
23
+ /**
24
+ * A count or a dot pinned to the top end corner of its content, or standing alone in a line
25
+ * when it has none. A count of 0 hides it.
26
+ */
27
+ export type BadgeProps = ElementProps<HTMLSpanElement, HTMLAttributes<HTMLSpanElement>, Partial<BadgeDefaults> & {
28
+ /** What the badge says: usually a count. */
29
+ content?: number | string;
30
+ /**
31
+ * A dot instead of the content.
32
+ * @default false
33
+ */
34
+ dot?: boolean;
35
+ /**
36
+ * What the content counts, read after it by screen readers: `unread messages` reads
37
+ * "3 unread messages". With `dot`, the whole announcement. With an `id`, this text has
38
+ * the id `{id}-label`, for the `aria-describedby` of a button the badge is pinned to.
39
+ */
40
+ label?: string;
41
+ /** The content the badge is pinned to. */
42
+ children?: Snippet;
43
+ }>;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,85 @@
1
+ <script lang="ts">
2
+ // A button, or a link styled as one. See ButtonProps for the props.
3
+ import { useDefaults } from '../../core/defaults/context.js';
4
+ import { useLocale } from '../../core/locale/locale.js';
5
+ import { sharedClasses } from '../../core/props/classes.js';
6
+ import '../../styles/visually-hidden.css';
7
+ import './button.css';
8
+ import type { ButtonDefaults, ButtonProps } from './types.js';
9
+
10
+ let {
11
+ variant,
12
+ size,
13
+ density,
14
+ color,
15
+ rounded,
16
+ block,
17
+ disabled,
18
+ as,
19
+ icon = false,
20
+ loading = false,
21
+ href,
22
+ type,
23
+ onclick,
24
+ 'aria-disabled': ariaDisabled,
25
+ prepend,
26
+ append,
27
+ children,
28
+ class: className,
29
+ ref = $bindable(null),
30
+ ...rest
31
+ }: ButtonProps = $props();
32
+
33
+ const resolve = useDefaults<ButtonDefaults>('Button', {
34
+ variant: 'flat',
35
+ size: 'md',
36
+ density: 'default',
37
+ color: 'primary',
38
+ rounded: true,
39
+ block: false,
40
+ disabled: false
41
+ });
42
+ const p = $derived(resolve({ variant, size, density, color, rounded, block, disabled }));
43
+ const locale = useLocale();
44
+
45
+ const link = $derived((as ?? (href == null ? 'button' : 'a')) === 'a');
46
+ // Only a <button> can be disabled natively. A disabled link loses its href; a loading button
47
+ // and one marked aria-disabled stay focusable. None of them takes presses.
48
+ const native = $derived(!link && p.disabled);
49
+ const inert = $derived(p.disabled || loading || ariaDisabled === true || ariaDisabled === 'true');
50
+
51
+ function click(event: MouseEvent) {
52
+ if (inert) event.preventDefault();
53
+ else (onclick as ((event: MouseEvent) => void) | null | undefined)?.(event);
54
+ }
55
+ </script>
56
+
57
+ <svelte:element
58
+ this={link ? 'a' : 'button'}
59
+ bind:this={ref}
60
+ {...rest}
61
+ href={link && !p.disabled ? href : undefined}
62
+ type={link ? undefined : (type ?? 'button')}
63
+ role={link && p.disabled ? 'link' : undefined}
64
+ disabled={native || undefined}
65
+ aria-disabled={(inert && !native) || undefined}
66
+ class={[
67
+ 'sv-button',
68
+ sharedClasses(p, 'Button'),
69
+ inert && 'sv-button--inert',
70
+ p.disabled && 'sv-button--disabled',
71
+ p.block && 'sv-button--block',
72
+ icon && 'sv-button--icon',
73
+ loading && 'sv-button--loading',
74
+ className
75
+ ]}
76
+ onclick={click}
77
+ >
78
+ {#if prepend}<span class="sv-button__prepend">{@render prepend()}</span>{/if}
79
+ {@render children?.()}
80
+ {#if append}<span class="sv-button__append">{@render append()}</span>{/if}
81
+ {#if loading}
82
+ <span class="sv-button__loader" aria-hidden="true"></span>
83
+ <span class="sv-visually-hidden">{locale.t('loading')}</span>
84
+ {/if}
85
+ </svelte:element>
@@ -0,0 +1,4 @@
1
+ import type { ButtonProps } from './types.js';
2
+ declare const Button: import("svelte").Component<ButtonProps, {}, "ref">;
3
+ type Button = ReturnType<typeof Button>;
4
+ export default Button;
@@ -0,0 +1,132 @@
1
+ @layer sv.tokens, sv.base, sv.components, sv.utilities;
2
+
3
+ @layer sv.components {
4
+ /*
5
+ * Height and padding follow size and density; text follows size only. Colours come from
6
+ * the variant classes, which read the colour class.
7
+ */
8
+ .sv-button {
9
+ position: relative;
10
+ isolation: isolate;
11
+ display: inline-flex;
12
+ align-items: center;
13
+ justify-content: center;
14
+ gap: 0.618em;
15
+ box-sizing: border-box;
16
+ block-size: calc(var(--sv-size-height) * var(--sv-density));
17
+ margin: 0;
18
+ padding: 0 calc(var(--sv-size-height) * var(--sv-density) * 0.382);
19
+ border: var(--sv-hairline) solid var(--sv-variant-border);
20
+ border-radius: var(--sv-rounded, var(--sv-radius-md));
21
+ background-color: var(--sv-variant-bg);
22
+ box-shadow: var(--sv-variant-shadow);
23
+ color: var(--sv-variant-fg);
24
+ font: var(--sv-weight-medium) var(--sv-size-text) / 1 var(--sv-font-ui);
25
+ letter-spacing: var(--sv-button-tracking);
26
+ text-transform: var(--sv-button-transform);
27
+ text-decoration: none;
28
+ white-space: nowrap;
29
+ vertical-align: middle;
30
+ cursor: pointer;
31
+ user-select: none;
32
+ -webkit-tap-highlight-color: transparent;
33
+ transition: transform var(--sv-duration-fast) var(--sv-ease);
34
+ }
35
+
36
+ /* The theme's bevel: a hairline of light along the top edge of filled buttons. */
37
+ .sv-button.sv-variant-flat {
38
+ box-shadow: inset 0 var(--sv-hairline) 0 var(--sv-bevel);
39
+ }
40
+
41
+ /* State layer: the foreground colour over the background, only its opacity changes. */
42
+ .sv-button::before {
43
+ content: '';
44
+ position: absolute;
45
+ inset: calc(var(--sv-hairline) * -1);
46
+ z-index: -1;
47
+ border-radius: inherit;
48
+ background-color: currentColor;
49
+ opacity: 0;
50
+ pointer-events: none;
51
+ transition: opacity var(--sv-duration-fast) var(--sv-ease);
52
+ }
53
+
54
+ @media (hover: hover) {
55
+ .sv-button:where(:not(.sv-button--inert)):hover::before {
56
+ opacity: var(--sv-state-hover);
57
+ }
58
+ }
59
+
60
+ .sv-button:where(:not(.sv-button--inert)):active::before {
61
+ opacity: var(--sv-state-press);
62
+ }
63
+
64
+ .sv-button:where(:not(.sv-button--inert)):active {
65
+ transform: translateY(var(--sv-press-offset));
66
+ }
67
+
68
+ .sv-button--inert {
69
+ cursor: not-allowed;
70
+ }
71
+
72
+ /* Muted at φ⁻². A loading button keeps its colour: it is busy, not unavailable. */
73
+ .sv-button--disabled {
74
+ opacity: 0.382;
75
+ }
76
+
77
+ .sv-button--block {
78
+ display: flex;
79
+ inline-size: 100%;
80
+ }
81
+
82
+ .sv-button--icon {
83
+ inline-size: calc(var(--sv-size-height) * var(--sv-density));
84
+ padding: 0;
85
+ }
86
+
87
+ .sv-button__prepend,
88
+ .sv-button__append {
89
+ display: inline-flex;
90
+ }
91
+
92
+ /* Icons are φ^½ of the text. */
93
+ :where(.sv-button) svg {
94
+ inline-size: 1.272em;
95
+ block-size: 1.272em;
96
+ }
97
+
98
+ /*
99
+ * Loading: the label and icons turn transparent but keep their width and, for screen
100
+ * readers, the name. The spinner is painted in the foreground colour.
101
+ */
102
+ .sv-button--loading {
103
+ color: transparent;
104
+ cursor: wait;
105
+ }
106
+
107
+ .sv-button__loader {
108
+ position: absolute;
109
+ inset: 0;
110
+ box-sizing: border-box;
111
+ inline-size: 1.272em;
112
+ block-size: 1.272em;
113
+ margin: auto;
114
+ border: 0.146em solid var(--sv-variant-fg);
115
+ border-inline-end-color: transparent;
116
+ border-radius: 50%;
117
+ animation: sv-spin 987ms linear infinite;
118
+ }
119
+
120
+ /* A spinner that stops reads as a frozen interface, so it slows down instead. */
121
+ @media (prefers-reduced-motion: reduce) {
122
+ .sv-button__loader {
123
+ animation-duration: 2961ms;
124
+ }
125
+ }
126
+
127
+ @keyframes sv-spin {
128
+ to {
129
+ transform: rotate(1turn);
130
+ }
131
+ }
132
+ }
@@ -0,0 +1,2 @@
1
+ export { default as Button } from './Button.svelte';
2
+ export type { ButtonDefaults, ButtonProps } from './types.js';
@@ -0,0 +1 @@
1
+ export { default as Button } from './Button.svelte';
@@ -0,0 +1,76 @@
1
+ import type { Snippet } from 'svelte';
2
+ import type { HTMLAnchorAttributes, HTMLButtonAttributes } from 'svelte/elements';
3
+ import type { ElementProps } from '../../core/props/element.js';
4
+ import type { Color, Density, Rounded, Size, Variant } from '../../core/props/types.js';
5
+ /** The Button props that `DefaultsProvider` and `UIProvider` can set for a subtree. */
6
+ export interface ButtonDefaults {
7
+ /**
8
+ * Visual weight.
9
+ * @default 'flat'
10
+ */
11
+ variant: Variant;
12
+ /**
13
+ * Height and text size.
14
+ * @default 'md'
15
+ */
16
+ size: Size;
17
+ /**
18
+ * Multiplies the height and padding, never the text.
19
+ * @default 'default'
20
+ */
21
+ density: Density;
22
+ /**
23
+ * The colour the variant is painted with.
24
+ * @default 'primary'
25
+ */
26
+ color: Color;
27
+ /**
28
+ * Corner rounding. `true` keeps the theme's radius.
29
+ * @default true
30
+ */
31
+ rounded: Rounded;
32
+ /**
33
+ * Takes the full width of its container.
34
+ * @default false
35
+ */
36
+ block: boolean;
37
+ /**
38
+ * A disabled button cannot be focused or pressed; a disabled link loses its `href`.
39
+ * @default false
40
+ */
41
+ disabled: boolean;
42
+ }
43
+ declare module '../../core/defaults/context.js' {
44
+ interface ComponentDefaults {
45
+ Button: ButtonDefaults;
46
+ }
47
+ }
48
+ type ButtonOwnProps = Partial<ButtonDefaults> & {
49
+ /**
50
+ * The element to render. Defaults to `'a'` when `href` is given, otherwise `'button'`.
51
+ */
52
+ as?: 'button' | 'a';
53
+ /**
54
+ * Square, for a single icon as the content. Give it an `aria-label`.
55
+ * @default false
56
+ */
57
+ icon?: boolean;
58
+ /**
59
+ * Shows a spinner and ignores presses, while the button keeps focus and its label for
60
+ * screen readers, which also hear that it is loading.
61
+ * @default false
62
+ */
63
+ loading?: boolean;
64
+ /** Content before the label, usually an icon. */
65
+ prepend?: Snippet;
66
+ /** Content after the label, usually an icon. */
67
+ append?: Snippet;
68
+ /** The label. */
69
+ children?: Snippet;
70
+ };
71
+ /**
72
+ * A button, or a link that looks like one (`href`). Every other attribute of `<button>` and
73
+ * `<a>` passes through to the element.
74
+ */
75
+ export type ButtonProps = ElementProps<HTMLButtonElement | HTMLAnchorElement, HTMLButtonAttributes & HTMLAnchorAttributes, ButtonOwnProps>;
76
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,61 @@
1
+ <script lang="ts">
2
+ // Buttons joined into one control. See ButtonGroupProps for the props.
3
+ import {
4
+ getDefaultsContext,
5
+ mergeDefaults,
6
+ setDefaultsContext,
7
+ useDefaults
8
+ } from '../../core/defaults/context.js';
9
+ import { sharedClasses } from '../../core/props/classes.js';
10
+ import './button-group.css';
11
+ import type { ButtonGroupDefaults, ButtonGroupProps } from './types.js';
12
+
13
+ let {
14
+ variant,
15
+ size,
16
+ density,
17
+ color,
18
+ rounded,
19
+ children,
20
+ class: className,
21
+ ref = $bindable(null),
22
+ ...rest
23
+ }: ButtonGroupProps = $props();
24
+
25
+ const resolve = useDefaults<ButtonGroupDefaults>('ButtonGroup', {
26
+ variant: 'outlined',
27
+ size: 'md',
28
+ density: 'default',
29
+ color: 'primary',
30
+ rounded: true
31
+ });
32
+ const p = $derived(resolve({ variant, size, density, color, rounded }));
33
+
34
+ // The Buttons inside take the group's props as their defaults, so their own props still win.
35
+ const parent = getDefaultsContext();
36
+ const merged = $derived(
37
+ mergeDefaults(parent?.config, {
38
+ Button: {
39
+ variant: p.variant,
40
+ size: p.size,
41
+ density: p.density,
42
+ color: p.color,
43
+ rounded: p.rounded
44
+ }
45
+ })
46
+ );
47
+ setDefaultsContext({
48
+ get config() {
49
+ return merged;
50
+ }
51
+ });
52
+ </script>
53
+
54
+ <div
55
+ bind:this={ref}
56
+ {...rest}
57
+ role="group"
58
+ class={['sv-button-group', sharedClasses({ rounded: p.rounded }, 'ButtonGroup'), className]}
59
+ >
60
+ {@render children?.()}
61
+ </div>
@@ -0,0 +1,4 @@
1
+ import type { ButtonGroupProps } from './types.js';
2
+ declare const ButtonGroup: import("svelte").Component<ButtonGroupProps, {}, "ref">;
3
+ type ButtonGroup = ReturnType<typeof ButtonGroup>;
4
+ export default ButtonGroup;
@@ -0,0 +1,39 @@
1
+ @layer sv.tokens, sv.base, sv.components, sv.utilities;
2
+
3
+ @layer sv.components {
4
+ .sv-button-group {
5
+ display: inline-flex;
6
+ isolation: isolate;
7
+ vertical-align: middle;
8
+ border-radius: var(--sv-rounded, var(--sv-radius-md));
9
+ }
10
+
11
+ /* Square inside; the group's own rounding on the outer corners. */
12
+ .sv-button-group > .sv-button {
13
+ border-radius: 0;
14
+ }
15
+
16
+ .sv-button-group > .sv-button:first-child {
17
+ border-start-start-radius: inherit;
18
+ border-end-start-radius: inherit;
19
+ }
20
+
21
+ .sv-button-group > .sv-button:last-child {
22
+ border-start-end-radius: inherit;
23
+ border-end-end-radius: inherit;
24
+ }
25
+
26
+ /* Neighbours share one border; the focused one is drawn on top. */
27
+ .sv-button-group > .sv-button + .sv-button {
28
+ margin-inline-start: calc(var(--sv-hairline) * -1);
29
+ }
30
+
31
+ .sv-button-group > .sv-button:focus-visible {
32
+ z-index: 1;
33
+ }
34
+
35
+ /* Filled and borderless buttons get a faint divider where they meet. */
36
+ .sv-button-group > .sv-button:not(.sv-variant-outlined) + .sv-button:not(.sv-variant-outlined) {
37
+ border-inline-start-color: color-mix(in oklch, var(--sv-variant-fg) 21%, transparent);
38
+ }
39
+ }
@@ -0,0 +1,2 @@
1
+ export { default as ButtonGroup } from './ButtonGroup.svelte';
2
+ export type { ButtonGroupDefaults, ButtonGroupProps } from './types.js';