@nqmcreative/ui 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (308) hide show
  1. package/README.md +151 -439
  2. package/cli/index.mjs +67 -30
  3. package/dist/core/calendar.d.ts +3 -0
  4. package/dist/core/calendar.js +36 -0
  5. package/dist/core/dialog.svelte.d.ts +14 -0
  6. package/dist/core/dialog.svelte.js +23 -0
  7. package/dist/core/files.d.ts +35 -0
  8. package/dist/core/files.js +62 -0
  9. package/dist/core/index.d.ts +37 -0
  10. package/dist/core/index.js +35 -0
  11. package/dist/core/list.svelte.d.ts +41 -0
  12. package/dist/core/list.svelte.js +77 -0
  13. package/dist/core/number.d.ts +7 -0
  14. package/dist/core/number.js +17 -0
  15. package/dist/core/pagination.d.ts +6 -0
  16. package/dist/core/pagination.js +21 -0
  17. package/dist/core/password.d.ts +8 -0
  18. package/dist/core/password.js +23 -0
  19. package/dist/core/table.d.ts +22 -0
  20. package/dist/core/table.js +41 -0
  21. package/dist/core/theme.svelte.d.ts +16 -0
  22. package/dist/core/theme.svelte.js +34 -0
  23. package/dist/core/trigger.d.ts +35 -0
  24. package/dist/core/trigger.js +77 -0
  25. package/dist/index.d.ts +11 -103
  26. package/dist/index.js +11 -75
  27. package/dist/{components → styles/matte}/AccordionItem.svelte +1 -1
  28. package/dist/{components → styles/matte}/AccordionItem.svelte.d.ts +1 -1
  29. package/dist/{components → styles/matte}/Alert.svelte +8 -2
  30. package/dist/{components → styles/matte}/Alert.svelte.d.ts +1 -1
  31. package/dist/{components → styles/matte}/Avatar.svelte +1 -1
  32. package/dist/{components → styles/matte}/Avatar.svelte.d.ts +1 -1
  33. package/dist/{components → styles/matte}/Badge.svelte +8 -3
  34. package/dist/{components → styles/matte}/Badge.svelte.d.ts +1 -3
  35. package/dist/{components → styles/matte}/Breadcrumb.svelte +2 -2
  36. package/dist/{components → styles/matte}/Breadcrumb.svelte.d.ts +1 -1
  37. package/dist/{components → styles/matte}/Button.svelte +1 -1
  38. package/dist/{components → styles/matte}/Button.svelte.d.ts +1 -1
  39. package/dist/styles/matte/CTASection.svelte +76 -0
  40. package/dist/styles/matte/CTASection.svelte.d.ts +18 -0
  41. package/dist/{components → styles/matte}/Calendar.svelte +7 -17
  42. package/dist/{components → styles/matte}/Calendar.svelte.d.ts +1 -1
  43. package/dist/{components → styles/matte}/Card.svelte +1 -1
  44. package/dist/{components → styles/matte}/Card.svelte.d.ts +1 -1
  45. package/dist/{components → styles/matte}/Checkbox.svelte +1 -1
  46. package/dist/{components → styles/matte}/Checkbox.svelte.d.ts +1 -1
  47. package/dist/{components → styles/matte}/CheckboxGroup.svelte +1 -1
  48. package/dist/{components → styles/matte}/CheckboxGroup.svelte.d.ts +1 -1
  49. package/dist/{components → styles/matte}/Combobox.svelte +31 -42
  50. package/dist/{components → styles/matte}/Combobox.svelte.d.ts +1 -1
  51. package/dist/{components → styles/matte}/CommandPalette.svelte +26 -41
  52. package/dist/{components → styles/matte}/CommandPalette.svelte.d.ts +1 -1
  53. package/dist/{components → styles/matte}/ConfirmDialog.svelte +2 -2
  54. package/dist/{components → styles/matte}/ConfirmDialog.svelte.d.ts +2 -2
  55. package/dist/{components → styles/matte}/ContextMenu.svelte +5 -7
  56. package/dist/{components → styles/matte}/DatePicker.svelte +7 -11
  57. package/dist/{components → styles/matte}/DatePicker.svelte.d.ts +1 -1
  58. package/dist/{components → styles/matte}/Drawer.svelte +4 -7
  59. package/dist/{components → styles/matte}/Dropdown.svelte +18 -36
  60. package/dist/{components → styles/matte}/Dropdown.svelte.d.ts +1 -1
  61. package/dist/{components → styles/matte}/Dropzone.svelte +11 -43
  62. package/dist/{components → styles/matte}/Dropzone.svelte.d.ts +2 -5
  63. package/dist/{components → styles/matte}/EmptyState.svelte +1 -1
  64. package/dist/{components → styles/matte}/EmptyState.svelte.d.ts +1 -1
  65. package/dist/styles/matte/FeatureCard.svelte +58 -0
  66. package/dist/styles/matte/FeatureCard.svelte.d.ts +16 -0
  67. package/dist/styles/matte/FeatureGrid.svelte +62 -0
  68. package/dist/styles/matte/FeatureGrid.svelte.d.ts +16 -0
  69. package/dist/{components → styles/matte}/Footer.svelte +1 -1
  70. package/dist/{components → styles/matte}/Footer.svelte.d.ts +1 -1
  71. package/dist/styles/matte/HeroSection.svelte +80 -0
  72. package/dist/styles/matte/HeroSection.svelte.d.ts +21 -0
  73. package/dist/{components → styles/matte}/Input.svelte +1 -1
  74. package/dist/{components → styles/matte}/Input.svelte.d.ts +1 -1
  75. package/dist/{components → styles/matte}/Link.svelte +1 -1
  76. package/dist/{components → styles/matte}/Link.svelte.d.ts +1 -1
  77. package/dist/{components → styles/matte}/LocaleProvider.svelte +1 -1
  78. package/dist/{components → styles/matte}/LocaleProvider.svelte.d.ts +1 -1
  79. package/dist/styles/matte/LogoCloud.svelte +61 -0
  80. package/dist/styles/matte/LogoCloud.svelte.d.ts +19 -0
  81. package/dist/{components → styles/matte}/MenuItem.svelte +1 -1
  82. package/dist/{components → styles/matte}/MenuItem.svelte.d.ts +1 -1
  83. package/dist/{components → styles/matte}/Modal.svelte +4 -7
  84. package/dist/{components → styles/matte}/MultiSelect.svelte +18 -37
  85. package/dist/{components → styles/matte}/MultiSelect.svelte.d.ts +1 -1
  86. package/dist/{components → styles/matte}/Navbar.svelte +2 -2
  87. package/dist/{components → styles/matte}/Navbar.svelte.d.ts +1 -1
  88. package/dist/{components → styles/matte}/NumberInput.svelte +4 -8
  89. package/dist/{components → styles/matte}/NumberInput.svelte.d.ts +1 -1
  90. package/dist/{components → styles/matte}/Pagination.svelte +4 -15
  91. package/dist/{components → styles/matte}/Pagination.svelte.d.ts +1 -1
  92. package/dist/{components → styles/matte}/PasswordInput.svelte +4 -13
  93. package/dist/{components → styles/matte}/PasswordInput.svelte.d.ts +1 -1
  94. package/dist/{components → styles/matte}/Popover.svelte +16 -41
  95. package/dist/{components → styles/matte}/Popover.svelte.d.ts +1 -1
  96. package/dist/styles/matte/PricingCard.svelte +107 -0
  97. package/dist/styles/matte/PricingCard.svelte.d.ts +25 -0
  98. package/dist/{components → styles/matte}/Progress.svelte +3 -2
  99. package/dist/{components → styles/matte}/Progress.svelte.d.ts +1 -1
  100. package/dist/{components → styles/matte}/Radio.svelte +1 -1
  101. package/dist/{components → styles/matte}/Radio.svelte.d.ts +1 -1
  102. package/dist/{components → styles/matte}/RadioGroup.svelte +1 -1
  103. package/dist/{components → styles/matte}/RadioGroup.svelte.d.ts +1 -1
  104. package/dist/{components → styles/matte}/SegmentedControl.svelte +1 -1
  105. package/dist/{components → styles/matte}/SegmentedControl.svelte.d.ts +1 -1
  106. package/dist/{components → styles/matte}/Select.svelte +1 -1
  107. package/dist/{components → styles/matte}/Select.svelte.d.ts +1 -1
  108. package/dist/{components → styles/matte}/Sidebar.svelte +2 -2
  109. package/dist/{components → styles/matte}/Sidebar.svelte.d.ts +1 -1
  110. package/dist/{components → styles/matte}/Slider.svelte +3 -2
  111. package/dist/{components → styles/matte}/Slider.svelte.d.ts +1 -1
  112. package/dist/{components → styles/matte}/Spinner.svelte +2 -2
  113. package/dist/{components → styles/matte}/Spinner.svelte.d.ts +1 -1
  114. package/dist/{components → styles/matte}/Stat.svelte +1 -1
  115. package/dist/{components → styles/matte}/Stat.svelte.d.ts +1 -1
  116. package/dist/styles/matte/StatsBand.svelte +57 -0
  117. package/dist/styles/matte/StatsBand.svelte.d.ts +20 -0
  118. package/dist/{components → styles/matte}/Steps.svelte +1 -1
  119. package/dist/{components → styles/matte}/Steps.svelte.d.ts +1 -1
  120. package/dist/{components → styles/matte}/Switch.svelte +1 -1
  121. package/dist/{components → styles/matte}/Switch.svelte.d.ts +1 -1
  122. package/dist/{components → styles/matte}/Table.svelte +6 -28
  123. package/dist/{components → styles/matte}/Table.svelte.d.ts +2 -6
  124. package/dist/{components → styles/matte}/Tabs.svelte +8 -1
  125. package/dist/{components → styles/matte}/Tabs.svelte.d.ts +1 -1
  126. package/dist/styles/matte/Testimonial.svelte +67 -0
  127. package/dist/styles/matte/Testimonial.svelte.d.ts +19 -0
  128. package/dist/{components → styles/matte}/Textarea.svelte +1 -1
  129. package/dist/{components → styles/matte}/Textarea.svelte.d.ts +1 -1
  130. package/dist/{components → styles/matte}/ThemeToggle.svelte +14 -27
  131. package/dist/{components → styles/matte}/ThemeToggle.svelte.d.ts +2 -6
  132. package/dist/{components → styles/matte}/Toaster.svelte +4 -4
  133. package/dist/{fonts.css → styles/matte/fonts.css} +4 -3
  134. package/dist/styles/matte/index.d.ts +109 -0
  135. package/dist/styles/matte/index.js +83 -0
  136. package/dist/{theme.css → styles/matte/theme.css} +0 -1
  137. package/dist/styles/paper/Accordion.svelte +17 -0
  138. package/dist/styles/paper/Accordion.svelte.d.ts +8 -0
  139. package/dist/styles/paper/AccordionItem.svelte +46 -0
  140. package/dist/styles/paper/AccordionItem.svelte.d.ts +14 -0
  141. package/dist/styles/paper/Alert.svelte +99 -0
  142. package/dist/styles/paper/Alert.svelte.d.ts +18 -0
  143. package/dist/styles/paper/Avatar.svelte +60 -0
  144. package/dist/styles/paper/Avatar.svelte.d.ts +16 -0
  145. package/dist/styles/paper/AvatarGroup.svelte +17 -0
  146. package/dist/styles/paper/AvatarGroup.svelte.d.ts +8 -0
  147. package/dist/styles/paper/Badge.svelte +58 -0
  148. package/dist/styles/paper/Badge.svelte.d.ts +16 -0
  149. package/dist/styles/paper/Breadcrumb.svelte +49 -0
  150. package/dist/styles/paper/Breadcrumb.svelte.d.ts +14 -0
  151. package/dist/styles/paper/Button.svelte +96 -0
  152. package/dist/styles/paper/Button.svelte.d.ts +21 -0
  153. package/dist/styles/paper/CTASection.svelte +76 -0
  154. package/dist/styles/paper/CTASection.svelte.d.ts +18 -0
  155. package/dist/styles/paper/Calendar.svelte +202 -0
  156. package/dist/styles/paper/Calendar.svelte.d.ts +22 -0
  157. package/dist/styles/paper/Card.svelte +78 -0
  158. package/dist/styles/paper/Card.svelte.d.ts +21 -0
  159. package/dist/styles/paper/Checkbox.svelte +75 -0
  160. package/dist/styles/paper/Checkbox.svelte.d.ts +15 -0
  161. package/dist/styles/paper/CheckboxGroup.svelte +111 -0
  162. package/dist/styles/paper/CheckboxGroup.svelte.d.ts +30 -0
  163. package/dist/styles/paper/Combobox.svelte +266 -0
  164. package/dist/styles/paper/Combobox.svelte.d.ts +29 -0
  165. package/dist/styles/paper/CommandPalette.svelte +209 -0
  166. package/dist/styles/paper/CommandPalette.svelte.d.ts +32 -0
  167. package/dist/styles/paper/ConfirmDialog.svelte +97 -0
  168. package/dist/styles/paper/ConfirmDialog.svelte.d.ts +22 -0
  169. package/dist/styles/paper/ContextMenu.svelte +88 -0
  170. package/dist/styles/paper/ContextMenu.svelte.d.ts +15 -0
  171. package/dist/styles/paper/DatePicker.svelte +192 -0
  172. package/dist/styles/paper/DatePicker.svelte.d.ts +23 -0
  173. package/dist/styles/paper/Divider.svelte +30 -0
  174. package/dist/styles/paper/Divider.svelte.d.ts +10 -0
  175. package/dist/styles/paper/Drawer.svelte +165 -0
  176. package/dist/styles/paper/Drawer.svelte.d.ts +20 -0
  177. package/dist/styles/paper/Dropdown.svelte +94 -0
  178. package/dist/styles/paper/Dropdown.svelte.d.ts +23 -0
  179. package/dist/styles/paper/Dropzone.svelte +210 -0
  180. package/dist/styles/paper/Dropzone.svelte.d.ts +29 -0
  181. package/dist/styles/paper/EmptyState.svelte +71 -0
  182. package/dist/styles/paper/EmptyState.svelte.d.ts +18 -0
  183. package/dist/styles/paper/FeatureCard.svelte +58 -0
  184. package/dist/styles/paper/FeatureCard.svelte.d.ts +16 -0
  185. package/dist/styles/paper/FeatureGrid.svelte +62 -0
  186. package/dist/styles/paper/FeatureGrid.svelte.d.ts +16 -0
  187. package/dist/styles/paper/Field.svelte +42 -0
  188. package/dist/styles/paper/Field.svelte.d.ts +16 -0
  189. package/dist/styles/paper/Footer.svelte +91 -0
  190. package/dist/styles/paper/Footer.svelte.d.ts +25 -0
  191. package/dist/styles/paper/HeroSection.svelte +86 -0
  192. package/dist/styles/paper/HeroSection.svelte.d.ts +21 -0
  193. package/dist/styles/paper/Input.svelte +60 -0
  194. package/dist/styles/paper/Input.svelte.d.ts +18 -0
  195. package/dist/styles/paper/InputGroup.svelte +20 -0
  196. package/dist/styles/paper/InputGroup.svelte.d.ts +11 -0
  197. package/dist/styles/paper/Kbd.svelte +17 -0
  198. package/dist/styles/paper/Kbd.svelte.d.ts +8 -0
  199. package/dist/styles/paper/Label.svelte +16 -0
  200. package/dist/styles/paper/Label.svelte.d.ts +9 -0
  201. package/dist/styles/paper/Link.svelte +44 -0
  202. package/dist/styles/paper/Link.svelte.d.ts +16 -0
  203. package/dist/styles/paper/LocaleProvider.svelte +24 -0
  204. package/dist/styles/paper/LocaleProvider.svelte.d.ts +10 -0
  205. package/dist/styles/paper/LogoCloud.svelte +61 -0
  206. package/dist/styles/paper/LogoCloud.svelte.d.ts +19 -0
  207. package/dist/styles/paper/MenuItem.svelte +64 -0
  208. package/dist/styles/paper/MenuItem.svelte.d.ts +18 -0
  209. package/dist/styles/paper/MenuSeparator.svelte +22 -0
  210. package/dist/styles/paper/MenuSeparator.svelte.d.ts +8 -0
  211. package/dist/styles/paper/Modal.svelte +118 -0
  212. package/dist/styles/paper/Modal.svelte.d.ts +21 -0
  213. package/dist/styles/paper/MultiSelect.svelte +287 -0
  214. package/dist/styles/paper/MultiSelect.svelte.d.ts +31 -0
  215. package/dist/styles/paper/Navbar.svelte +201 -0
  216. package/dist/styles/paper/Navbar.svelte.d.ts +33 -0
  217. package/dist/styles/paper/NumberInput.svelte +96 -0
  218. package/dist/styles/paper/NumberInput.svelte.d.ts +15 -0
  219. package/dist/styles/paper/Pagination.svelte +83 -0
  220. package/dist/styles/paper/Pagination.svelte.d.ts +15 -0
  221. package/dist/styles/paper/PasswordInput.svelte +100 -0
  222. package/dist/styles/paper/PasswordInput.svelte.d.ts +12 -0
  223. package/dist/styles/paper/Popover.svelte +89 -0
  224. package/dist/styles/paper/Popover.svelte.d.ts +19 -0
  225. package/dist/styles/paper/PricingCard.svelte +108 -0
  226. package/dist/styles/paper/PricingCard.svelte.d.ts +25 -0
  227. package/dist/styles/paper/Progress.svelte +59 -0
  228. package/dist/styles/paper/Progress.svelte.d.ts +17 -0
  229. package/dist/styles/paper/Radio.svelte +55 -0
  230. package/dist/styles/paper/Radio.svelte.d.ts +15 -0
  231. package/dist/styles/paper/RadioGroup.svelte +95 -0
  232. package/dist/styles/paper/RadioGroup.svelte.d.ts +27 -0
  233. package/dist/styles/paper/SegmentedControl.svelte +88 -0
  234. package/dist/styles/paper/SegmentedControl.svelte.d.ts +25 -0
  235. package/dist/styles/paper/Select.svelte +61 -0
  236. package/dist/styles/paper/Select.svelte.d.ts +20 -0
  237. package/dist/styles/paper/Sidebar.svelte +206 -0
  238. package/dist/styles/paper/Sidebar.svelte.d.ts +36 -0
  239. package/dist/styles/paper/Skeleton.svelte +46 -0
  240. package/dist/styles/paper/Skeleton.svelte.d.ts +13 -0
  241. package/dist/styles/paper/Slider.svelte +80 -0
  242. package/dist/styles/paper/Slider.svelte.d.ts +19 -0
  243. package/dist/styles/paper/Spinner.svelte +34 -0
  244. package/dist/styles/paper/Spinner.svelte.d.ts +13 -0
  245. package/dist/styles/paper/Stat.svelte +51 -0
  246. package/dist/styles/paper/Stat.svelte.d.ts +16 -0
  247. package/dist/styles/paper/StatsBand.svelte +63 -0
  248. package/dist/styles/paper/StatsBand.svelte.d.ts +20 -0
  249. package/dist/styles/paper/Steps.svelte +141 -0
  250. package/dist/styles/paper/Steps.svelte.d.ts +24 -0
  251. package/dist/styles/paper/Switch.svelte +64 -0
  252. package/dist/styles/paper/Switch.svelte.d.ts +14 -0
  253. package/dist/styles/paper/Table.svelte +217 -0
  254. package/dist/styles/paper/Table.svelte.d.ts +66 -0
  255. package/dist/styles/paper/Tabs.svelte +102 -0
  256. package/dist/styles/paper/Tabs.svelte.d.ts +23 -0
  257. package/dist/styles/paper/Testimonial.svelte +64 -0
  258. package/dist/styles/paper/Testimonial.svelte.d.ts +19 -0
  259. package/dist/styles/paper/Textarea.svelte +54 -0
  260. package/dist/styles/paper/Textarea.svelte.d.ts +12 -0
  261. package/dist/styles/paper/ThemeToggle.svelte +130 -0
  262. package/dist/styles/paper/ThemeToggle.svelte.d.ts +16 -0
  263. package/dist/styles/paper/Toaster.svelte +132 -0
  264. package/dist/styles/paper/Toaster.svelte.d.ts +8 -0
  265. package/dist/styles/paper/Tooltip.svelte +33 -0
  266. package/dist/styles/paper/Tooltip.svelte.d.ts +12 -0
  267. package/dist/styles/paper/fonts.css +46 -0
  268. package/dist/styles/paper/index.d.ts +109 -0
  269. package/dist/styles/paper/index.js +83 -0
  270. package/dist/styles/paper/theme.css +222 -0
  271. package/package.json +531 -201
  272. package/registry.json +658 -339
  273. /package/dist/{actions → core/actions}/anchor.d.ts +0 -0
  274. /package/dist/{actions → core/actions}/anchor.js +0 -0
  275. /package/dist/{actions → core/actions}/dismissable.d.ts +0 -0
  276. /package/dist/{actions → core/actions}/dismissable.js +0 -0
  277. /package/dist/{date.d.ts → core/date.d.ts} +0 -0
  278. /package/dist/{date.js → core/date.js} +0 -0
  279. /package/dist/{locale.svelte.d.ts → core/locale.svelte.d.ts} +0 -0
  280. /package/dist/{locale.svelte.js → core/locale.svelte.js} +0 -0
  281. /package/dist/{toast.svelte.d.ts → core/toast.svelte.d.ts} +0 -0
  282. /package/dist/{toast.svelte.js → core/toast.svelte.js} +0 -0
  283. /package/dist/{tones.d.ts → core/tones.d.ts} +0 -0
  284. /package/dist/{tones.js → core/tones.js} +0 -0
  285. /package/dist/{components → styles/matte}/Accordion.svelte +0 -0
  286. /package/dist/{components → styles/matte}/Accordion.svelte.d.ts +0 -0
  287. /package/dist/{components → styles/matte}/AvatarGroup.svelte +0 -0
  288. /package/dist/{components → styles/matte}/AvatarGroup.svelte.d.ts +0 -0
  289. /package/dist/{components → styles/matte}/ContextMenu.svelte.d.ts +0 -0
  290. /package/dist/{components → styles/matte}/Divider.svelte +0 -0
  291. /package/dist/{components → styles/matte}/Divider.svelte.d.ts +0 -0
  292. /package/dist/{components → styles/matte}/Drawer.svelte.d.ts +0 -0
  293. /package/dist/{components → styles/matte}/Field.svelte +0 -0
  294. /package/dist/{components → styles/matte}/Field.svelte.d.ts +0 -0
  295. /package/dist/{components → styles/matte}/InputGroup.svelte +0 -0
  296. /package/dist/{components → styles/matte}/InputGroup.svelte.d.ts +0 -0
  297. /package/dist/{components → styles/matte}/Kbd.svelte +0 -0
  298. /package/dist/{components → styles/matte}/Kbd.svelte.d.ts +0 -0
  299. /package/dist/{components → styles/matte}/Label.svelte +0 -0
  300. /package/dist/{components → styles/matte}/Label.svelte.d.ts +0 -0
  301. /package/dist/{components → styles/matte}/MenuSeparator.svelte +0 -0
  302. /package/dist/{components → styles/matte}/MenuSeparator.svelte.d.ts +0 -0
  303. /package/dist/{components → styles/matte}/Modal.svelte.d.ts +0 -0
  304. /package/dist/{components → styles/matte}/Skeleton.svelte +0 -0
  305. /package/dist/{components → styles/matte}/Skeleton.svelte.d.ts +0 -0
  306. /package/dist/{components → styles/matte}/Toaster.svelte.d.ts +0 -0
  307. /package/dist/{components → styles/matte}/Tooltip.svelte +0 -0
  308. /package/dist/{components → styles/matte}/Tooltip.svelte.d.ts +0 -0
@@ -1,12 +1,8 @@
1
1
  <script lang="ts">
2
2
  import type { Snippet } from 'svelte';
3
- import { toneBorder, toneSoft, toneSurface, toneText, type Tone } from '../tones.js';
4
- import { useLocale } from '../locale.svelte.js';
5
-
6
- export interface RejectedFile {
7
- file: File;
8
- reason: 'type' | 'size' | 'count';
9
- }
3
+ import { toneBorder, toneSoft, toneSurface, toneText, type Tone } from '../../core/tones.js';
4
+ import { useLocale } from '../../core/locale.svelte.js';
5
+ import { formatSize as toReadableSize, sortFiles, type RejectedFile } from '../../core/files.js';
10
6
 
11
7
  interface Props {
12
8
  /** Bindable list of accepted files. */
@@ -67,46 +63,18 @@
67
63
  return parts.join(' · ');
68
64
  });
69
65
 
70
- function formatSize(bytes: number) {
71
- const units = t.current.byteUnits;
72
- if (bytes < 1024) return `${bytes} ${units[0]}`;
73
- let value = bytes / 1024;
74
- let i = 1;
75
- while (value >= 1024 && i < units.length - 1) {
76
- value /= 1024;
77
- i++;
78
- }
79
- return `${value.toFixed(Number.isInteger(value) || value >= 10 ? 0 : 1)} ${units[i]}`;
80
- }
81
-
82
- function matchesAccept(file: File) {
83
- if (!accept) return true;
84
- return accept.split(',').some((raw) => {
85
- const rule = raw.trim().toLowerCase();
86
- if (!rule) return true;
87
- if (rule.startsWith('.')) return file.name.toLowerCase().endsWith(rule);
88
- if (rule.endsWith('/*')) return file.type.startsWith(rule.slice(0, -1));
89
- return file.type.toLowerCase() === rule;
90
- });
91
- }
66
+ const formatSize = (bytes: number) => toReadableSize(bytes, t.current.byteUnits);
92
67
 
93
68
  function add(incoming: FileList | File[] | null) {
94
69
  if (!incoming || disabled) return;
95
70
 
96
- const accepted: File[] = [];
97
- const bad: RejectedFile[] = [];
98
- let room = maxFiles ? maxFiles - (multiple ? files.length : 0) : Infinity;
99
-
100
- for (const file of Array.from(incoming)) {
101
- if (!matchesAccept(file)) bad.push({ file, reason: 'type' });
102
- else if (maxSize && file.size > maxSize) bad.push({ file, reason: 'size' });
103
- else if (room <= 0) bad.push({ file, reason: 'count' });
104
- else {
105
- accepted.push(file);
106
- room--;
107
- }
108
- if (!multiple && accepted.length === 1) break;
109
- }
71
+ const { accepted, rejected: bad } = sortFiles(incoming, {
72
+ accept,
73
+ maxSize,
74
+ maxFiles,
75
+ multiple,
76
+ held: files.length
77
+ });
110
78
 
111
79
  rejected = bad;
112
80
  if (bad.length) onreject?.(bad);
@@ -1,9 +1,6 @@
1
1
  import type { Snippet } from 'svelte';
2
- import { type Tone } from '../tones.js';
3
- export interface RejectedFile {
4
- file: File;
5
- reason: 'type' | 'size' | 'count';
6
- }
2
+ import { type Tone } from '../../core/tones.js';
3
+ import { type RejectedFile } from '../../core/files.js';
7
4
  interface Props {
8
5
  /** Bindable list of accepted files. */
9
6
  files?: File[];
@@ -1,7 +1,7 @@
1
1
  <script lang="ts">
2
2
  import type { Snippet } from 'svelte';
3
3
  import type { HTMLAttributes } from 'svelte/elements';
4
- import { toneSoft, type Tone } from '../tones.js';
4
+ import { toneSoft, type Tone } from '../../core/tones.js';
5
5
 
6
6
  interface Props extends HTMLAttributes<HTMLDivElement> {
7
7
  title: string;
@@ -1,6 +1,6 @@
1
1
  import type { Snippet } from 'svelte';
2
2
  import type { HTMLAttributes } from 'svelte/elements';
3
- import { type Tone } from '../tones.js';
3
+ import { type Tone } from '../../core/tones.js';
4
4
  interface Props extends HTMLAttributes<HTMLDivElement> {
5
5
  title: string;
6
6
  description?: string;
@@ -0,0 +1,58 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte';
3
+ import type { HTMLAttributes } from 'svelte/elements';
4
+ import { focusRing, toneHoverText, toneRing, toneSoft, type Tone } from '../../core/tones.js';
5
+
6
+ interface Props extends HTMLAttributes<HTMLDivElement> {
7
+ title: string;
8
+ description?: string;
9
+ tone?: Tone;
10
+ /** Turns the whole card into a link. */
11
+ href?: string;
12
+ /** Glyph inside the tinted square. */
13
+ icon?: Snippet;
14
+ children?: Snippet;
15
+ }
16
+
17
+ let {
18
+ title,
19
+ description,
20
+ tone = 'brand',
21
+ href,
22
+ icon,
23
+ class: className = '',
24
+ children,
25
+ ...rest
26
+ }: Props = $props();
27
+ </script>
28
+
29
+ <svelte:element
30
+ this={href ? 'a' : 'div'}
31
+ {href}
32
+ class="group flex flex-col gap-3 bg-bg p-6 {href
33
+ ? `transition-colors duration-150 ease-brand-out ${focusRing} ${toneRing[tone]}`
34
+ : ''} {className}"
35
+ {...rest}
36
+ >
37
+ {#if icon}
38
+ <span class="flex size-10 items-center justify-center {toneSoft[tone]}">
39
+ {@render icon()}
40
+ </span>
41
+ {/if}
42
+
43
+ <h3
44
+ class="font-heading text-base font-medium text-text {href
45
+ ? `transition-colors duration-150 ${toneHoverText[tone]}`
46
+ : ''}"
47
+ >
48
+ {title}
49
+ </h3>
50
+
51
+ {#if description}
52
+ <p class="font-sans text-sm leading-relaxed text-text-secondary">{description}</p>
53
+ {/if}
54
+
55
+ {#if children}
56
+ {@render children()}
57
+ {/if}
58
+ </svelte:element>
@@ -0,0 +1,16 @@
1
+ import type { Snippet } from 'svelte';
2
+ import type { HTMLAttributes } from 'svelte/elements';
3
+ import { type Tone } from '../../core/tones.js';
4
+ interface Props extends HTMLAttributes<HTMLDivElement> {
5
+ title: string;
6
+ description?: string;
7
+ tone?: Tone;
8
+ /** Turns the whole card into a link. */
9
+ href?: string;
10
+ /** Glyph inside the tinted square. */
11
+ icon?: Snippet;
12
+ children?: Snippet;
13
+ }
14
+ declare const FeatureCard: import("svelte").Component<Props, {}, "">;
15
+ type FeatureCard = ReturnType<typeof FeatureCard>;
16
+ export default FeatureCard;
@@ -0,0 +1,62 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte';
3
+ import type { HTMLAttributes } from 'svelte/elements';
4
+
5
+ export type FeatureColumns = 2 | 3 | 4;
6
+
7
+ interface Props extends HTMLAttributes<HTMLElement> {
8
+ eyebrow?: string;
9
+ title?: string;
10
+ description?: string;
11
+ columns?: FeatureColumns;
12
+ /** Hairline grid rather than free-standing cards. */
13
+ bordered?: boolean;
14
+ /** `FeatureCard`s, or anything else. */
15
+ children: Snippet;
16
+ }
17
+
18
+ let {
19
+ eyebrow,
20
+ title,
21
+ description,
22
+ columns = 3,
23
+ bordered = false,
24
+ class: className = '',
25
+ children,
26
+ ...rest
27
+ }: Props = $props();
28
+
29
+ const cols: Record<FeatureColumns, string> = {
30
+ 2: 'sm:grid-cols-2',
31
+ 3: 'sm:grid-cols-2 lg:grid-cols-3',
32
+ 4: 'sm:grid-cols-2 lg:grid-cols-4'
33
+ };
34
+ </script>
35
+
36
+ <section class="w-full px-6 py-20 {className}" {...rest}>
37
+ <div class="mx-auto flex w-full max-w-6xl flex-col gap-12">
38
+ {#if eyebrow || title || description}
39
+ <div class="flex max-w-xl flex-col gap-3">
40
+ {#if eyebrow}
41
+ <span class="font-mono text-xs tracking-wide text-text-muted uppercase">{eyebrow}</span>
42
+ {/if}
43
+ {#if title}
44
+ <h2 class="font-heading text-3xl font-medium tracking-tight text-balance text-text">
45
+ {title}
46
+ </h2>
47
+ {/if}
48
+ {#if description}
49
+ <p class="font-sans leading-relaxed text-pretty text-text-secondary">{description}</p>
50
+ {/if}
51
+ </div>
52
+ {/if}
53
+
54
+ <div
55
+ class="grid {cols[columns]} {bordered
56
+ ? 'gap-px border border-hairline bg-hairline'
57
+ : 'gap-10'}"
58
+ >
59
+ {@render children()}
60
+ </div>
61
+ </div>
62
+ </section>
@@ -0,0 +1,16 @@
1
+ import type { Snippet } from 'svelte';
2
+ import type { HTMLAttributes } from 'svelte/elements';
3
+ export type FeatureColumns = 2 | 3 | 4;
4
+ interface Props extends HTMLAttributes<HTMLElement> {
5
+ eyebrow?: string;
6
+ title?: string;
7
+ description?: string;
8
+ columns?: FeatureColumns;
9
+ /** Hairline grid rather than free-standing cards. */
10
+ bordered?: boolean;
11
+ /** `FeatureCard`s, or anything else. */
12
+ children: Snippet;
13
+ }
14
+ declare const FeatureGrid: import("svelte").Component<Props, {}, "">;
15
+ type FeatureGrid = ReturnType<typeof FeatureGrid>;
16
+ export default FeatureGrid;
@@ -13,7 +13,7 @@
13
13
 
14
14
  <script lang="ts">
15
15
  import type { Snippet } from 'svelte';
16
- import { toneHoverText, type Tone } from '../tones.js';
16
+ import { toneHoverText, type Tone } from '../../core/tones.js';
17
17
 
18
18
  interface Props {
19
19
  columns?: FooterColumn[];
@@ -8,7 +8,7 @@ export interface FooterColumn {
8
8
  links: FooterLink[];
9
9
  }
10
10
  import type { Snippet } from 'svelte';
11
- import { type Tone } from '../tones.js';
11
+ import { type Tone } from '../../core/tones.js';
12
12
  interface Props {
13
13
  columns?: FooterColumn[];
14
14
  /** Logo, wordmark and a line of copy on the left. */
@@ -0,0 +1,80 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte';
3
+ import type { HTMLAttributes } from 'svelte/elements';
4
+ import { toneText, type Tone } from '../../core/tones.js';
5
+
6
+ interface Props extends HTMLAttributes<HTMLElement> {
7
+ /** Small line above the headline. */
8
+ eyebrow?: string;
9
+ title: string;
10
+ description?: string;
11
+ tone?: Tone;
12
+ /** `center` also centres the actions. Ignored when `media` is set. */
13
+ align?: 'left' | 'center';
14
+ /** Buttons under the copy. */
15
+ actions?: Snippet;
16
+ /** Anything on the right — a screenshot, an illustration, a form. */
17
+ media?: Snippet;
18
+ /** Extra content between the description and the actions. */
19
+ children?: Snippet;
20
+ }
21
+
22
+ let {
23
+ eyebrow,
24
+ title,
25
+ description,
26
+ tone = 'brand',
27
+ align = 'left',
28
+ actions,
29
+ media,
30
+ class: className = '',
31
+ children,
32
+ ...rest
33
+ }: Props = $props();
34
+
35
+ // A media column only makes sense next to left-aligned copy.
36
+ const centred = $derived(align === 'center' && !media);
37
+ </script>
38
+
39
+ <section class="w-full px-6 py-20 sm:py-28 {className}" {...rest}>
40
+ <div
41
+ class="mx-auto flex w-full max-w-6xl gap-16
42
+ {media ? 'flex-col lg:flex-row lg:items-center' : 'flex-col'}"
43
+ >
44
+ <div
45
+ class="flex min-w-0 flex-1 flex-col gap-6 {centred
46
+ ? 'items-center text-center'
47
+ : 'items-start'}"
48
+ >
49
+ {#if eyebrow}
50
+ <span class="font-mono text-xs tracking-wide uppercase {toneText[tone]}">{eyebrow}</span>
51
+ {/if}
52
+
53
+ <h1
54
+ class="max-w-2xl font-heading text-4xl leading-tight font-medium tracking-tight text-balance text-text sm:text-5xl"
55
+ >
56
+ {title}
57
+ </h1>
58
+
59
+ {#if description}
60
+ <p class="max-w-xl font-sans text-lg leading-relaxed text-pretty text-text-secondary">
61
+ {description}
62
+ </p>
63
+ {/if}
64
+
65
+ {#if children}
66
+ {@render children()}
67
+ {/if}
68
+
69
+ {#if actions}
70
+ <div class="flex flex-wrap items-center gap-3 pt-2 {centred ? 'justify-center' : ''}">
71
+ {@render actions()}
72
+ </div>
73
+ {/if}
74
+ </div>
75
+
76
+ {#if media}
77
+ <div class="min-w-0 flex-1">{@render media()}</div>
78
+ {/if}
79
+ </div>
80
+ </section>
@@ -0,0 +1,21 @@
1
+ import type { Snippet } from 'svelte';
2
+ import type { HTMLAttributes } from 'svelte/elements';
3
+ import { type Tone } from '../../core/tones.js';
4
+ interface Props extends HTMLAttributes<HTMLElement> {
5
+ /** Small line above the headline. */
6
+ eyebrow?: string;
7
+ title: string;
8
+ description?: string;
9
+ tone?: Tone;
10
+ /** `center` also centres the actions. Ignored when `media` is set. */
11
+ align?: 'left' | 'center';
12
+ /** Buttons under the copy. */
13
+ actions?: Snippet;
14
+ /** Anything on the right — a screenshot, an illustration, a form. */
15
+ media?: Snippet;
16
+ /** Extra content between the description and the actions. */
17
+ children?: Snippet;
18
+ }
19
+ declare const HeroSection: import("svelte").Component<Props, {}, "">;
20
+ type HeroSection = ReturnType<typeof HeroSection>;
21
+ export default HeroSection;
@@ -1,7 +1,7 @@
1
1
  <script lang="ts">
2
2
  import type { Snippet } from 'svelte';
3
3
  import type { HTMLInputAttributes } from 'svelte/elements';
4
- import { toneFocusWithinBorder, type Tone } from '../tones.js';
4
+ import { toneFocusWithinBorder, type Tone } from '../../core/tones.js';
5
5
 
6
6
  export type InputSize = 'sm' | 'md' | 'lg';
7
7
 
@@ -1,6 +1,6 @@
1
1
  import type { Snippet } from 'svelte';
2
2
  import type { HTMLInputAttributes } from 'svelte/elements';
3
- import { type Tone } from '../tones.js';
3
+ import { type Tone } from '../../core/tones.js';
4
4
  export type InputSize = 'sm' | 'md' | 'lg';
5
5
  interface Props extends Omit<HTMLInputAttributes, 'size' | 'prefix' | 'suffix'> {
6
6
  value?: string;
@@ -1,7 +1,7 @@
1
1
  <script lang="ts">
2
2
  import type { Snippet } from 'svelte';
3
3
  import type { HTMLAnchorAttributes } from 'svelte/elements';
4
- import { focusRing, toneHoverText, toneRing, toneText, type Tone } from '../tones.js';
4
+ import { focusRing, toneHoverText, toneRing, toneText, type Tone } from '../../core/tones.js';
5
5
 
6
6
  interface Props extends HTMLAnchorAttributes {
7
7
  tone?: Tone;
@@ -1,6 +1,6 @@
1
1
  import type { Snippet } from 'svelte';
2
2
  import type { HTMLAnchorAttributes } from 'svelte/elements';
3
- import { type Tone } from '../tones.js';
3
+ import { type Tone } from '../../core/tones.js';
4
4
  interface Props extends HTMLAnchorAttributes {
5
5
  tone?: Tone;
6
6
  /** `'hover'` shows the rule only on hover. */
@@ -1,6 +1,6 @@
1
1
  <script lang="ts">
2
2
  import type { Snippet } from 'svelte';
3
- import { provideLocale, type Locale } from '../locale.svelte.js';
3
+ import { provideLocale, type Locale } from '../../core/locale.svelte.js';
4
4
 
5
5
  interface Props {
6
6
  /** Full locale or just the keys you want to change. */
@@ -1,5 +1,5 @@
1
1
  import type { Snippet } from 'svelte';
2
- import { type Locale } from '../locale.svelte.js';
2
+ import { type Locale } from '../../core/locale.svelte.js';
3
3
  interface Props {
4
4
  /** Full locale or just the keys you want to change. */
5
5
  locale: Partial<Locale>;
@@ -0,0 +1,61 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte';
3
+ import type { HTMLAttributes } from 'svelte/elements';
4
+
5
+ export interface Logo {
6
+ name: string;
7
+ src?: string;
8
+ href?: string;
9
+ }
10
+
11
+ interface Props extends HTMLAttributes<HTMLElement> {
12
+ title?: string;
13
+ /** Without `src` the name is set in the heading face — fine for wordmarks. */
14
+ logos?: Logo[];
15
+ /** Dim until hovered, so the row does not compete with the headline. */
16
+ muted?: boolean;
17
+ /** Your own markup instead of `logos`. */
18
+ children?: Snippet;
19
+ }
20
+
21
+ let {
22
+ title,
23
+ logos = [],
24
+ muted = true,
25
+ class: className = '',
26
+ children,
27
+ ...rest
28
+ }: Props = $props();
29
+ </script>
30
+
31
+ <section class="w-full px-6 py-14 {className}" {...rest}>
32
+ <div class="mx-auto flex w-full max-w-6xl flex-col items-center gap-8">
33
+ {#if title}
34
+ <p class="text-center font-mono text-xs tracking-wide text-text-muted uppercase">{title}</p>
35
+ {/if}
36
+
37
+ <div class="flex flex-wrap items-center justify-center gap-x-12 gap-y-8">
38
+ {#if children}
39
+ {@render children()}
40
+ {:else}
41
+ {#each logos as logo (logo.name)}
42
+ <svelte:element
43
+ this={logo.href ? 'a' : 'div'}
44
+ href={logo.href}
45
+ class="flex items-center transition-all duration-200 ease-brand-out {muted
46
+ ? 'opacity-60 grayscale hover:opacity-100 hover:grayscale-0'
47
+ : ''}"
48
+ >
49
+ {#if logo.src}
50
+ <img src={logo.src} alt={logo.name} class="h-7 w-auto object-contain" />
51
+ {:else}
52
+ <span class="font-heading text-lg font-medium tracking-tight text-text-secondary">
53
+ {logo.name}
54
+ </span>
55
+ {/if}
56
+ </svelte:element>
57
+ {/each}
58
+ {/if}
59
+ </div>
60
+ </div>
61
+ </section>
@@ -0,0 +1,19 @@
1
+ import type { Snippet } from 'svelte';
2
+ import type { HTMLAttributes } from 'svelte/elements';
3
+ export interface Logo {
4
+ name: string;
5
+ src?: string;
6
+ href?: string;
7
+ }
8
+ interface Props extends HTMLAttributes<HTMLElement> {
9
+ title?: string;
10
+ /** Without `src` the name is set in the heading face — fine for wordmarks. */
11
+ logos?: Logo[];
12
+ /** Dim until hovered, so the row does not compete with the headline. */
13
+ muted?: boolean;
14
+ /** Your own markup instead of `logos`. */
15
+ children?: Snippet;
16
+ }
17
+ declare const LogoCloud: import("svelte").Component<Props, {}, "">;
18
+ type LogoCloud = ReturnType<typeof LogoCloud>;
19
+ export default LogoCloud;
@@ -1,7 +1,7 @@
1
1
  <script lang="ts">
2
2
  import type { Snippet } from 'svelte';
3
3
  import type { HTMLButtonAttributes } from 'svelte/elements';
4
- import { toneSoftHover, toneText, type Tone } from '../tones.js';
4
+ import { toneSoftHover, toneText, type Tone } from '../../core/tones.js';
5
5
 
6
6
  interface Props extends HTMLButtonAttributes {
7
7
  /** Renders an `<a>` instead of a `<button>`. */
@@ -1,6 +1,6 @@
1
1
  import type { Snippet } from 'svelte';
2
2
  import type { HTMLButtonAttributes } from 'svelte/elements';
3
- import { type Tone } from '../tones.js';
3
+ import { type Tone } from '../../core/tones.js';
4
4
  interface Props extends HTMLButtonAttributes {
5
5
  /** Renders an `<a>` instead of a `<button>`. */
6
6
  href?: string;
@@ -1,7 +1,8 @@
1
1
  <script lang="ts">
2
2
  import type { Snippet } from 'svelte';
3
3
  import type { HTMLDialogAttributes } from 'svelte/elements';
4
- import { useLocale } from '../locale.svelte.js';
4
+ import { useLocale } from '../../core/locale.svelte.js';
5
+ import { isBackdropClick, syncDialog } from '../../core/dialog.svelte.js';
5
6
 
6
7
  export type ModalSize = 'sm' | 'md' | 'lg';
7
8
 
@@ -46,11 +47,7 @@
46
47
  lg: 'max-w-2xl'
47
48
  };
48
49
 
49
- $effect(() => {
50
- if (!dialog) return;
51
- if (open && !dialog.open) dialog.showModal();
52
- else if (!open && dialog.open) dialog.close();
53
- });
50
+ $effect(() => syncDialog(dialog, open));
54
51
 
55
52
  function close() {
56
53
  open = false;
@@ -59,7 +56,7 @@
59
56
 
60
57
  function onBackdrop(event: MouseEvent) {
61
58
  if (!dismissible) return;
62
- if (event.target === dialog) close();
59
+ if (isBackdropClick(event, dialog)) close();
63
60
  }
64
61
  </script>
65
62