@thomasfosterau/components 0.0.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 (484) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +241 -56
  3. package/dist/canvas/VectorCanvas.svelte +320 -0
  4. package/dist/canvas/VectorCanvas.svelte.d.ts +105 -0
  5. package/dist/canvas/history.d.ts +105 -0
  6. package/dist/canvas/history.js +147 -0
  7. package/dist/canvas/index.d.ts +15 -0
  8. package/dist/canvas/index.js +14 -0
  9. package/dist/canvas/types.d.ts +91 -0
  10. package/dist/canvas/types.js +13 -0
  11. package/dist/canvas/utils.d.ts +66 -0
  12. package/dist/canvas/utils.js +114 -0
  13. package/dist/charts/Chart.svelte +300 -0
  14. package/dist/charts/Chart.svelte.d.ts +50 -0
  15. package/dist/charts/index.d.ts +11 -0
  16. package/dist/charts/index.js +10 -0
  17. package/dist/charts/types.d.ts +28 -0
  18. package/dist/charts/types.js +6 -0
  19. package/dist/citations/BookCitation.svelte +53 -0
  20. package/dist/citations/BookCitation.svelte.d.ts +41 -0
  21. package/dist/citations/ChapterCitation.svelte +38 -0
  22. package/dist/citations/ChapterCitation.svelte.d.ts +50 -0
  23. package/dist/citations/Citation.svelte +47 -0
  24. package/dist/citations/Citation.svelte.d.ts +24 -0
  25. package/dist/citations/CreditList.svelte +69 -0
  26. package/dist/citations/CreditList.svelte.d.ts +47 -0
  27. package/dist/citations/DOILink.svelte +28 -0
  28. package/dist/citations/DOILink.svelte.d.ts +19 -0
  29. package/dist/citations/Footnote.svelte +39 -0
  30. package/dist/citations/Footnote.svelte.d.ts +17 -0
  31. package/dist/citations/FootnoteList.svelte +36 -0
  32. package/dist/citations/FootnoteList.svelte.d.ts +21 -0
  33. package/dist/citations/ISBNLink.svelte +29 -0
  34. package/dist/citations/ISBNLink.svelte.d.ts +19 -0
  35. package/dist/citations/ISSNLink.svelte +29 -0
  36. package/dist/citations/ISSNLink.svelte.d.ts +19 -0
  37. package/dist/citations/Publisher.svelte +34 -0
  38. package/dist/citations/Publisher.svelte.d.ts +14 -0
  39. package/dist/citations/ReferenceList.svelte +53 -0
  40. package/dist/citations/ReferenceList.svelte.d.ts +21 -0
  41. package/dist/citations/ReportCitation.svelte +41 -0
  42. package/dist/citations/ReportCitation.svelte.d.ts +36 -0
  43. package/dist/citations/ScholarlyArticleCitation.svelte +64 -0
  44. package/dist/citations/ScholarlyArticleCitation.svelte.d.ts +41 -0
  45. package/dist/citations/ThesisCitation.svelte +35 -0
  46. package/dist/citations/ThesisCitation.svelte.d.ts +29 -0
  47. package/dist/citations/bibliography.svelte.d.ts +55 -0
  48. package/dist/citations/bibliography.svelte.js +78 -0
  49. package/dist/citations/citation.d.ts +71 -0
  50. package/dist/citations/citation.js +121 -0
  51. package/dist/citations/csl.d.ts +102 -0
  52. package/dist/citations/csl.js +20 -0
  53. package/dist/citations/index.d.ts +31 -0
  54. package/dist/citations/index.js +36 -0
  55. package/dist/citations/list-format.d.ts +34 -0
  56. package/dist/citations/list-format.js +40 -0
  57. package/dist/context.svelte.d.ts +46 -0
  58. package/dist/context.svelte.js +51 -0
  59. package/dist/data/ChatBubble.svelte +48 -0
  60. package/dist/data/ChatBubble.svelte.d.ts +33 -0
  61. package/dist/data/DataGrid.svelte +150 -0
  62. package/dist/data/DataGrid.svelte.d.ts +118 -0
  63. package/dist/data/DescriptionList.svelte +53 -0
  64. package/dist/data/DescriptionList.svelte.d.ts +26 -0
  65. package/dist/data/DescriptionRow.svelte +56 -0
  66. package/dist/data/DescriptionRow.svelte.d.ts +21 -0
  67. package/dist/data/DiffText.svelte +29 -0
  68. package/dist/data/DiffText.svelte.d.ts +19 -0
  69. package/dist/data/ItemList.svelte +80 -0
  70. package/dist/data/ItemList.svelte.d.ts +52 -0
  71. package/dist/data/LinkListItem.svelte +46 -0
  72. package/dist/data/LinkListItem.svelte.d.ts +21 -0
  73. package/dist/data/MessageThread.svelte +29 -0
  74. package/dist/data/MessageThread.svelte.d.ts +17 -0
  75. package/dist/data/Pagination.svelte +136 -0
  76. package/dist/data/Pagination.svelte.d.ts +79 -0
  77. package/dist/data/PaginationFooter.svelte +42 -0
  78. package/dist/data/PaginationFooter.svelte.d.ts +61 -0
  79. package/dist/data/ResultCount.svelte +27 -0
  80. package/dist/data/ResultCount.svelte.d.ts +18 -0
  81. package/dist/data/Table.svelte +151 -0
  82. package/dist/data/Table.svelte.d.ts +75 -0
  83. package/dist/data/TreeList.svelte +41 -0
  84. package/dist/data/TreeList.svelte.d.ts +17 -0
  85. package/dist/data/TreeListItem.svelte +29 -0
  86. package/dist/data/TreeListItem.svelte.d.ts +10 -0
  87. package/dist/data/description-context.d.ts +39 -0
  88. package/dist/data/description-context.js +36 -0
  89. package/dist/data/diff.d.ts +14 -0
  90. package/dist/data/diff.js +10 -0
  91. package/dist/data/index.d.ts +37 -0
  92. package/dist/data/index.js +37 -0
  93. package/dist/data/list-item.d.ts +30 -0
  94. package/dist/data/list-item.js +19 -0
  95. package/dist/data/pagination.d.ts +81 -0
  96. package/dist/data/pagination.js +79 -0
  97. package/dist/data/table-types.d.ts +71 -0
  98. package/dist/data/table-types.js +35 -0
  99. package/dist/feedback/ConfirmDialog.svelte +79 -0
  100. package/dist/feedback/ConfirmDialog.svelte.d.ts +82 -0
  101. package/dist/feedback/Dialog.svelte +47 -0
  102. package/dist/feedback/Dialog.svelte.d.ts +36 -0
  103. package/dist/feedback/DialogFrame.svelte +64 -0
  104. package/dist/feedback/DialogFrame.svelte.d.ts +23 -0
  105. package/dist/feedback/Drawer.svelte +43 -0
  106. package/dist/feedback/Drawer.svelte.d.ts +43 -0
  107. package/dist/feedback/LoadingBoundary.svelte +61 -0
  108. package/dist/feedback/LoadingBoundary.svelte.d.ts +34 -0
  109. package/dist/feedback/ProgressBar.svelte +46 -0
  110. package/dist/feedback/ProgressBar.svelte.d.ts +28 -0
  111. package/dist/feedback/SegmentBar.svelte +83 -0
  112. package/dist/feedback/SegmentBar.svelte.d.ts +37 -0
  113. package/dist/feedback/StatTile.svelte +77 -0
  114. package/dist/feedback/StatTile.svelte.d.ts +50 -0
  115. package/dist/feedback/Stats.svelte +18 -0
  116. package/dist/feedback/Stats.svelte.d.ts +16 -0
  117. package/dist/feedback/Steps.svelte +72 -0
  118. package/dist/feedback/Steps.svelte.d.ts +61 -0
  119. package/dist/feedback/Timeline.svelte +86 -0
  120. package/dist/feedback/Timeline.svelte.d.ts +55 -0
  121. package/dist/feedback/Toaster.svelte +78 -0
  122. package/dist/feedback/Toaster.svelte.d.ts +32 -0
  123. package/dist/feedback/index.d.ts +34 -0
  124. package/dist/feedback/index.js +29 -0
  125. package/dist/feedback/sizes.d.ts +41 -0
  126. package/dist/feedback/sizes.js +69 -0
  127. package/dist/feedback/toaster.d.ts +48 -0
  128. package/dist/feedback/toaster.js +29 -0
  129. package/dist/fields/Calendar.svelte +60 -0
  130. package/dist/fields/Calendar.svelte.d.ts +11 -0
  131. package/dist/fields/CalendarMonths.svelte +86 -0
  132. package/dist/fields/CalendarMonths.svelte.d.ts +30 -0
  133. package/dist/fields/Checkbox.svelte +33 -0
  134. package/dist/fields/Checkbox.svelte.d.ts +30 -0
  135. package/dist/fields/CheckboxGroup.svelte +41 -0
  136. package/dist/fields/CheckboxGroup.svelte.d.ts +40 -0
  137. package/dist/fields/Combobox.svelte +229 -0
  138. package/dist/fields/Combobox.svelte.d.ts +133 -0
  139. package/dist/fields/DateField.svelte +37 -0
  140. package/dist/fields/DateField.svelte.d.ts +20 -0
  141. package/dist/fields/DateInput.svelte +31 -0
  142. package/dist/fields/DateInput.svelte.d.ts +35 -0
  143. package/dist/fields/DatePicker.svelte +47 -0
  144. package/dist/fields/DatePicker.svelte.d.ts +25 -0
  145. package/dist/fields/DateRangePicker.svelte +70 -0
  146. package/dist/fields/DateRangePicker.svelte.d.ts +43 -0
  147. package/dist/fields/Dropzone.svelte +232 -0
  148. package/dist/fields/Dropzone.svelte.d.ts +103 -0
  149. package/dist/fields/FieldErrors.svelte +30 -0
  150. package/dist/fields/FieldErrors.svelte.d.ts +11 -0
  151. package/dist/fields/Fieldset.svelte +53 -0
  152. package/dist/fields/Fieldset.svelte.d.ts +27 -0
  153. package/dist/fields/FileInput.svelte +68 -0
  154. package/dist/fields/FileInput.svelte.d.ts +39 -0
  155. package/dist/fields/FormField.svelte +78 -0
  156. package/dist/fields/FormField.svelte.d.ts +29 -0
  157. package/dist/fields/ImageInput.svelte +87 -0
  158. package/dist/fields/ImageInput.svelte.d.ts +45 -0
  159. package/dist/fields/MultiSelect.svelte +112 -0
  160. package/dist/fields/MultiSelect.svelte.d.ts +75 -0
  161. package/dist/fields/NumberField.svelte +190 -0
  162. package/dist/fields/NumberField.svelte.d.ts +76 -0
  163. package/dist/fields/PasswordInput.svelte +95 -0
  164. package/dist/fields/PasswordInput.svelte.d.ts +58 -0
  165. package/dist/fields/PickerPopover.svelte +47 -0
  166. package/dist/fields/PickerPopover.svelte.d.ts +16 -0
  167. package/dist/fields/PinInput.svelte +83 -0
  168. package/dist/fields/PinInput.svelte.d.ts +66 -0
  169. package/dist/fields/PushToggle.svelte +93 -0
  170. package/dist/fields/PushToggle.svelte.d.ts +55 -0
  171. package/dist/fields/RadioGroup.svelte +88 -0
  172. package/dist/fields/RadioGroup.svelte.d.ts +41 -0
  173. package/dist/fields/RangeCalendar.svelte +51 -0
  174. package/dist/fields/RangeCalendar.svelte.d.ts +23 -0
  175. package/dist/fields/Rating.svelte +127 -0
  176. package/dist/fields/Rating.svelte.d.ts +86 -0
  177. package/dist/fields/SearchInput.svelte +58 -0
  178. package/dist/fields/SearchInput.svelte.d.ts +33 -0
  179. package/dist/fields/SegmentGroup.svelte +91 -0
  180. package/dist/fields/SegmentGroup.svelte.d.ts +20 -0
  181. package/dist/fields/Select.svelte +36 -0
  182. package/dist/fields/Select.svelte.d.ts +35 -0
  183. package/dist/fields/Slider.svelte +194 -0
  184. package/dist/fields/Slider.svelte.d.ts +100 -0
  185. package/dist/fields/TagsInput.svelte +256 -0
  186. package/dist/fields/TagsInput.svelte.d.ts +102 -0
  187. package/dist/fields/TextInput.svelte +26 -0
  188. package/dist/fields/TextInput.svelte.d.ts +36 -0
  189. package/dist/fields/Textarea.svelte +22 -0
  190. package/dist/fields/Textarea.svelte.d.ts +31 -0
  191. package/dist/fields/TimeField.svelte +30 -0
  192. package/dist/fields/TimeField.svelte.d.ts +19 -0
  193. package/dist/fields/Toggle.svelte +72 -0
  194. package/dist/fields/Toggle.svelte.d.ts +38 -0
  195. package/dist/fields/VideoInput.svelte +35 -0
  196. package/dist/fields/VideoInput.svelte.d.ts +46 -0
  197. package/dist/fields/calendar-props.d.ts +119 -0
  198. package/dist/fields/calendar-props.js +51 -0
  199. package/dist/fields/dates.d.ts +28 -0
  200. package/dist/fields/dates.js +26 -0
  201. package/dist/fields/field-types.d.ts +80 -0
  202. package/dist/fields/field-types.js +92 -0
  203. package/dist/fields/file-validation.d.ts +30 -0
  204. package/dist/fields/file-validation.js +51 -0
  205. package/dist/fields/index.d.ts +43 -0
  206. package/dist/fields/index.js +42 -0
  207. package/dist/fields/latest-search.svelte.d.ts +38 -0
  208. package/dist/fields/latest-search.svelte.js +85 -0
  209. package/dist/fields/number-format.d.ts +52 -0
  210. package/dist/fields/number-format.js +89 -0
  211. package/dist/fields/segmented-field.d.ts +128 -0
  212. package/dist/fields/segmented-field.js +52 -0
  213. package/dist/fields/slider-keys.d.ts +21 -0
  214. package/dist/fields/slider-keys.js +37 -0
  215. package/dist/formatting/Countdown.svelte +110 -0
  216. package/dist/formatting/Countdown.svelte.d.ts +35 -0
  217. package/dist/formatting/DateTime.svelte +35 -0
  218. package/dist/formatting/DateTime.svelte.d.ts +26 -0
  219. package/dist/formatting/Duration.svelte +18 -0
  220. package/dist/formatting/Duration.svelte.d.ts +20 -0
  221. package/dist/formatting/FormatList.svelte +31 -0
  222. package/dist/formatting/FormatList.svelte.d.ts +46 -0
  223. package/dist/formatting/Highlight.svelte +51 -0
  224. package/dist/formatting/Highlight.svelte.d.ts +19 -0
  225. package/dist/formatting/Number.svelte +35 -0
  226. package/dist/formatting/Number.svelte.d.ts +43 -0
  227. package/dist/formatting/RelativeTime.svelte +69 -0
  228. package/dist/formatting/RelativeTime.svelte.d.ts +26 -0
  229. package/dist/formatting/Year.svelte +39 -0
  230. package/dist/formatting/Year.svelte.d.ts +21 -0
  231. package/dist/formatting/duration.d.ts +44 -0
  232. package/dist/formatting/duration.js +125 -0
  233. package/dist/formatting/index.d.ts +15 -0
  234. package/dist/formatting/index.js +17 -0
  235. package/dist/forms/EntityForm.svelte +185 -0
  236. package/dist/forms/EntityForm.svelte.d.ts +66 -0
  237. package/dist/forms/FormActions.svelte +29 -0
  238. package/dist/forms/FormActions.svelte.d.ts +37 -0
  239. package/dist/forms/FormErrors.svelte +21 -0
  240. package/dist/forms/FormErrors.svelte.d.ts +16 -0
  241. package/dist/forms/HiddenField.svelte +22 -0
  242. package/dist/forms/HiddenField.svelte.d.ts +11 -0
  243. package/dist/forms/SearchForm.svelte +43 -0
  244. package/dist/forms/SearchForm.svelte.d.ts +36 -0
  245. package/dist/forms/entity-form.d.ts +12 -0
  246. package/dist/forms/entity-form.js +12 -0
  247. package/dist/forms/index.d.ts +14 -0
  248. package/dist/forms/index.js +14 -0
  249. package/dist/hotkeys/HotkeyBadge.svelte +39 -0
  250. package/dist/hotkeys/HotkeyBadge.svelte.d.ts +25 -0
  251. package/dist/hotkeys/HotkeyHelpDialog.svelte +68 -0
  252. package/dist/hotkeys/HotkeyHelpDialog.svelte.d.ts +35 -0
  253. package/dist/hotkeys/HotkeyProvider.svelte +92 -0
  254. package/dist/hotkeys/HotkeyProvider.svelte.d.ts +4 -0
  255. package/dist/hotkeys/context.svelte.d.ts +47 -0
  256. package/dist/hotkeys/context.svelte.js +72 -0
  257. package/dist/hotkeys/index.d.ts +28 -0
  258. package/dist/hotkeys/index.js +27 -0
  259. package/dist/hotkeys/match.d.ts +65 -0
  260. package/dist/hotkeys/match.js +135 -0
  261. package/dist/hotkeys/registry.svelte.d.ts +55 -0
  262. package/dist/hotkeys/registry.svelte.js +110 -0
  263. package/dist/hotkeys/types.d.ts +74 -0
  264. package/dist/hotkeys/types.js +18 -0
  265. package/dist/index.d.ts +37 -0
  266. package/dist/index.js +37 -0
  267. package/dist/infobox/Infobox.svelte +79 -0
  268. package/dist/infobox/Infobox.svelte.d.ts +33 -0
  269. package/dist/infobox/InfoboxHeader.svelte +35 -0
  270. package/dist/infobox/InfoboxHeader.svelte.d.ts +18 -0
  271. package/dist/infobox/InfoboxImage.svelte +38 -0
  272. package/dist/infobox/InfoboxImage.svelte.d.ts +21 -0
  273. package/dist/infobox/InfoboxRow.svelte +50 -0
  274. package/dist/infobox/InfoboxRow.svelte.d.ts +25 -0
  275. package/dist/infobox/InfoboxSection.svelte +24 -0
  276. package/dist/infobox/InfoboxSection.svelte.d.ts +12 -0
  277. package/dist/infobox/index.d.ts +21 -0
  278. package/dist/infobox/index.js +20 -0
  279. package/dist/infobox/types.d.ts +86 -0
  280. package/dist/infobox/types.js +27 -0
  281. package/dist/layout/AppShell.svelte +50 -0
  282. package/dist/layout/AppShell.svelte.d.ts +28 -0
  283. package/dist/layout/Breadcrumbs.svelte +52 -0
  284. package/dist/layout/Breadcrumbs.svelte.d.ts +18 -0
  285. package/dist/layout/Cluster.svelte +28 -0
  286. package/dist/layout/Cluster.svelte.d.ts +27 -0
  287. package/dist/layout/DetailLayout.svelte +50 -0
  288. package/dist/layout/DetailLayout.svelte.d.ts +19 -0
  289. package/dist/layout/FilterBar.svelte +40 -0
  290. package/dist/layout/FilterBar.svelte.d.ts +12 -0
  291. package/dist/layout/Fits.svelte +27 -0
  292. package/dist/layout/Fits.svelte.d.ts +13 -0
  293. package/dist/layout/Flow.svelte +46 -0
  294. package/dist/layout/Flow.svelte.d.ts +16 -0
  295. package/dist/layout/Footer.svelte +32 -0
  296. package/dist/layout/Footer.svelte.d.ts +12 -0
  297. package/dist/layout/Grid.svelte +23 -0
  298. package/dist/layout/Grid.svelte.d.ts +26 -0
  299. package/dist/layout/HStack.svelte +12 -0
  300. package/dist/layout/HStack.svelte.d.ts +34 -0
  301. package/dist/layout/Hero.svelte +76 -0
  302. package/dist/layout/Hero.svelte.d.ts +36 -0
  303. package/dist/layout/Main.svelte +30 -0
  304. package/dist/layout/Main.svelte.d.ts +15 -0
  305. package/dist/layout/Navbar.svelte +68 -0
  306. package/dist/layout/Navbar.svelte.d.ts +31 -0
  307. package/dist/layout/PageHeader.svelte +77 -0
  308. package/dist/layout/PageHeader.svelte.d.ts +33 -0
  309. package/dist/layout/Section.svelte +72 -0
  310. package/dist/layout/Section.svelte.d.ts +40 -0
  311. package/dist/layout/Sidebar.svelte +54 -0
  312. package/dist/layout/Sidebar.svelte.d.ts +27 -0
  313. package/dist/layout/Spacer.svelte +12 -0
  314. package/dist/layout/Spacer.svelte.d.ts +6 -0
  315. package/dist/layout/Tabs.svelte +85 -0
  316. package/dist/layout/Tabs.svelte.d.ts +42 -0
  317. package/dist/layout/VStack.svelte +12 -0
  318. package/dist/layout/VStack.svelte.d.ts +29 -0
  319. package/dist/layout/index.d.ts +38 -0
  320. package/dist/layout/index.js +38 -0
  321. package/dist/layout/space.d.ts +44 -0
  322. package/dist/layout/space.js +76 -0
  323. package/dist/layout/types.d.ts +52 -0
  324. package/dist/layout/types.js +27 -0
  325. package/dist/links/ContextLinks.svelte +28 -0
  326. package/dist/links/ContextLinks.svelte.d.ts +20 -0
  327. package/dist/links/EmailLink.svelte +26 -0
  328. package/dist/links/EmailLink.svelte.d.ts +20 -0
  329. package/dist/links/index.d.ts +7 -0
  330. package/dist/links/index.js +7 -0
  331. package/dist/media/Figure.svelte +26 -0
  332. package/dist/media/Figure.svelte.d.ts +12 -0
  333. package/dist/media/Image.svelte +76 -0
  334. package/dist/media/Image.svelte.d.ts +41 -0
  335. package/dist/media/Video.svelte +65 -0
  336. package/dist/media/Video.svelte.d.ts +29 -0
  337. package/dist/media/image-dimensions.d.ts +28 -0
  338. package/dist/media/image-dimensions.js +34 -0
  339. package/dist/media/index.d.ts +10 -0
  340. package/dist/media/index.js +10 -0
  341. package/dist/search/CommandPalette.svelte +257 -0
  342. package/dist/search/CommandPalette.svelte.d.ts +59 -0
  343. package/dist/search/index.d.ts +13 -0
  344. package/dist/search/index.js +13 -0
  345. package/dist/search/types.d.ts +40 -0
  346. package/dist/search/types.js +20 -0
  347. package/dist/seo/Head.svelte +190 -0
  348. package/dist/seo/Head.svelte.d.ts +86 -0
  349. package/dist/seo/JsonLd.svelte +30 -0
  350. package/dist/seo/JsonLd.svelte.d.ts +20 -0
  351. package/dist/seo/index.d.ts +18 -0
  352. package/dist/seo/index.js +17 -0
  353. package/dist/seo/json-ld.d.ts +33 -0
  354. package/dist/seo/json-ld.js +29 -0
  355. package/dist/seo/og-image.d.ts +72 -0
  356. package/dist/seo/og-image.js +82 -0
  357. package/dist/seo/types.d.ts +43 -0
  358. package/dist/seo/types.js +6 -0
  359. package/dist/theme.css +161 -0
  360. package/dist/tips/PopoverTip.svelte +80 -0
  361. package/dist/tips/PopoverTip.svelte.d.ts +33 -0
  362. package/dist/tips/Tip.svelte +91 -0
  363. package/dist/tips/Tip.svelte.d.ts +25 -0
  364. package/dist/tips/index.d.ts +15 -0
  365. package/dist/tips/index.js +14 -0
  366. package/dist/tips/tip-stack.d.ts +26 -0
  367. package/dist/tips/tip-stack.js +37 -0
  368. package/dist/tips/tip-store.svelte.d.ts +75 -0
  369. package/dist/tips/tip-store.svelte.js +158 -0
  370. package/dist/tips/types.d.ts +46 -0
  371. package/dist/tips/types.js +6 -0
  372. package/dist/ui/Accordion.svelte +75 -0
  373. package/dist/ui/Accordion.svelte.d.ts +50 -0
  374. package/dist/ui/AccordionItem.svelte +73 -0
  375. package/dist/ui/AccordionItem.svelte.d.ts +18 -0
  376. package/dist/ui/Alert.svelte +61 -0
  377. package/dist/ui/Alert.svelte.d.ts +37 -0
  378. package/dist/ui/Badge.svelte +39 -0
  379. package/dist/ui/Badge.svelte.d.ts +32 -0
  380. package/dist/ui/Button.svelte +44 -0
  381. package/dist/ui/Button.svelte.d.ts +29 -0
  382. package/dist/ui/ButtonGroup.svelte +24 -0
  383. package/dist/ui/ButtonGroup.svelte.d.ts +17 -0
  384. package/dist/ui/Card.svelte +49 -0
  385. package/dist/ui/Card.svelte.d.ts +44 -0
  386. package/dist/ui/Chip.svelte +58 -0
  387. package/dist/ui/Chip.svelte.d.ts +21 -0
  388. package/dist/ui/ConfirmButton.svelte +75 -0
  389. package/dist/ui/ConfirmButton.svelte.d.ts +48 -0
  390. package/dist/ui/ContextMenu.svelte +75 -0
  391. package/dist/ui/ContextMenu.svelte.d.ts +25 -0
  392. package/dist/ui/Disclosure.svelte +46 -0
  393. package/dist/ui/Disclosure.svelte.d.ts +22 -0
  394. package/dist/ui/Divider.svelte +47 -0
  395. package/dist/ui/Divider.svelte.d.ts +28 -0
  396. package/dist/ui/DropdownMenu.svelte +44 -0
  397. package/dist/ui/DropdownMenu.svelte.d.ts +30 -0
  398. package/dist/ui/EmptyState.svelte +37 -0
  399. package/dist/ui/EmptyState.svelte.d.ts +22 -0
  400. package/dist/ui/ExternalLink.svelte +38 -0
  401. package/dist/ui/ExternalLink.svelte.d.ts +34 -0
  402. package/dist/ui/Heading.svelte +58 -0
  403. package/dist/ui/Heading.svelte.d.ts +22 -0
  404. package/dist/ui/Link.svelte +34 -0
  405. package/dist/ui/Link.svelte.d.ts +20 -0
  406. package/dist/ui/LinkButton.svelte +51 -0
  407. package/dist/ui/LinkButton.svelte.d.ts +33 -0
  408. package/dist/ui/Menu.svelte +24 -0
  409. package/dist/ui/Menu.svelte.d.ts +13 -0
  410. package/dist/ui/MenuCheckboxItem.svelte +33 -0
  411. package/dist/ui/MenuCheckboxItem.svelte.d.ts +20 -0
  412. package/dist/ui/MenuItem.svelte +73 -0
  413. package/dist/ui/MenuItem.svelte.d.ts +21 -0
  414. package/dist/ui/MenuRadioGroup.svelte +25 -0
  415. package/dist/ui/MenuRadioGroup.svelte.d.ts +20 -0
  416. package/dist/ui/MenuRadioItem.svelte +20 -0
  417. package/dist/ui/MenuRadioItem.svelte.d.ts +15 -0
  418. package/dist/ui/MenuSeparator.svelte +27 -0
  419. package/dist/ui/MenuSeparator.svelte.d.ts +8 -0
  420. package/dist/ui/MenuSub.svelte +24 -0
  421. package/dist/ui/MenuSub.svelte.d.ts +15 -0
  422. package/dist/ui/Popover.svelte +63 -0
  423. package/dist/ui/Popover.svelte.d.ts +40 -0
  424. package/dist/ui/ShareButton.svelte +64 -0
  425. package/dist/ui/ShareButton.svelte.d.ts +39 -0
  426. package/dist/ui/Skeleton.svelte +43 -0
  427. package/dist/ui/Skeleton.svelte.d.ts +22 -0
  428. package/dist/ui/Spinner.svelte +41 -0
  429. package/dist/ui/Spinner.svelte.d.ts +35 -0
  430. package/dist/ui/Stack.svelte +36 -0
  431. package/dist/ui/Stack.svelte.d.ts +48 -0
  432. package/dist/ui/ThemeToggle.svelte +65 -0
  433. package/dist/ui/ThemeToggle.svelte.d.ts +24 -0
  434. package/dist/ui/ToggleButton.svelte +58 -0
  435. package/dist/ui/ToggleButton.svelte.d.ts +45 -0
  436. package/dist/ui/ToggleGroup.svelte +142 -0
  437. package/dist/ui/ToggleGroup.svelte.d.ts +86 -0
  438. package/dist/ui/Toolbar.svelte +40 -0
  439. package/dist/ui/Toolbar.svelte.d.ts +20 -0
  440. package/dist/ui/ToolbarButton.svelte +29 -0
  441. package/dist/ui/ToolbarButton.svelte.d.ts +21 -0
  442. package/dist/ui/ToolbarLink.svelte +21 -0
  443. package/dist/ui/ToolbarLink.svelte.d.ts +12 -0
  444. package/dist/ui/ToolbarSeparator.svelte +22 -0
  445. package/dist/ui/ToolbarSeparator.svelte.d.ts +12 -0
  446. package/dist/ui/ToolbarToggleGroup.svelte +66 -0
  447. package/dist/ui/ToolbarToggleGroup.svelte.d.ts +52 -0
  448. package/dist/ui/Tooltip.svelte +54 -0
  449. package/dist/ui/Tooltip.svelte.d.ts +35 -0
  450. package/dist/ui/VisuallyHidden.svelte +23 -0
  451. package/dist/ui/VisuallyHidden.svelte.d.ts +10 -0
  452. package/dist/ui/accordion-context.d.ts +26 -0
  453. package/dist/ui/accordion-context.js +23 -0
  454. package/dist/ui/colour-token.d.ts +41 -0
  455. package/dist/ui/colour-token.js +49 -0
  456. package/dist/ui/context-menu.d.ts +13 -0
  457. package/dist/ui/context-menu.js +13 -0
  458. package/dist/ui/index.d.ts +63 -0
  459. package/dist/ui/index.js +62 -0
  460. package/dist/ui/menu-context.d.ts +20 -0
  461. package/dist/ui/menu-context.js +22 -0
  462. package/dist/ui/menu-parts/CheckboxItemPart.svelte +26 -0
  463. package/dist/ui/menu-parts/CheckboxItemPart.svelte.d.ts +5 -0
  464. package/dist/ui/menu-parts/ItemPart.svelte +29 -0
  465. package/dist/ui/menu-parts/ItemPart.svelte.d.ts +5 -0
  466. package/dist/ui/menu-parts/RadioGroupPart.svelte +24 -0
  467. package/dist/ui/menu-parts/RadioGroupPart.svelte.d.ts +5 -0
  468. package/dist/ui/menu-parts/RadioItemPart.svelte +22 -0
  469. package/dist/ui/menu-parts/RadioItemPart.svelte.d.ts +5 -0
  470. package/dist/ui/menu-parts/SeparatorPart.svelte +16 -0
  471. package/dist/ui/menu-parts/SeparatorPart.svelte.d.ts +5 -0
  472. package/dist/ui/menu-parts/SubPart.svelte +28 -0
  473. package/dist/ui/menu-parts/SubPart.svelte.d.ts +5 -0
  474. package/dist/ui/menu-parts/menu-parts.d.ts +104 -0
  475. package/dist/ui/menu-parts/menu-parts.js +31 -0
  476. package/dist/ui/menu-parts/parts.d.ts +12 -0
  477. package/dist/ui/menu-parts/parts.js +27 -0
  478. package/dist/ui/slug.d.ts +19 -0
  479. package/dist/ui/slug.js +25 -0
  480. package/dist/ui/toggle-classes.d.ts +39 -0
  481. package/dist/ui/toggle-classes.js +36 -0
  482. package/dist/ui/tones.d.ts +103 -0
  483. package/dist/ui/tones.js +240 -0
  484. package/package.json +41 -25
@@ -0,0 +1,21 @@
1
+ import type { HTMLAttributes } from 'svelte/elements';
2
+ import { type ChipSize } from './tones.ts';
3
+ interface Props extends Omit<HTMLAttributes<HTMLElement>, 'title'> {
4
+ /** The short code shown in the chip. */
5
+ label: string;
6
+ /** The expansion, rendered as the `<abbr>` title. */
7
+ title?: string | undefined;
8
+ /** When set, the chip is a link to the subject's page. */
9
+ href?: string | undefined;
10
+ /** A CSS custom-property name the app's theme declares (`--party-alp`). */
11
+ colourToken?: string | undefined;
12
+ /**
13
+ * daisyUI size step.
14
+ * @defaultValue `'md'`
15
+ */
16
+ size?: ChipSize | undefined;
17
+ }
18
+ /** A colour swatch beside a short code, for legends, result rows and filter lists. */
19
+ declare const Chip: import("svelte").Component<Props, {}, "">;
20
+ type Chip = ReturnType<typeof Chip>;
21
+ export default Chip;
@@ -0,0 +1,75 @@
1
+ <!-- @component
2
+ A destructive action behind a two-step inline confirmation.
3
+ -->
4
+ <!--
5
+ ConfirmButton — a destructive action behind a two-step inline confirm.
6
+
7
+ Inline rather than a dialog, deliberately: the confirmation replaces the
8
+ button in place, so nothing is torn out of the reading order, focus is not
9
+ trapped, and the page behind it does not need an overlay. Use
10
+ `ConfirmDialog` instead when the confirmation itself needs to carry content
11
+ (a form, a list of what will be destroyed).
12
+
13
+ ARIA contract: the failure surface is an `Alert` with `live="assertive"` —
14
+ the reader pressed a button and nothing visible happened, so the reason has
15
+ to interrupt. Both buttons are `disabled` while the action is in flight, and
16
+ the confirm button swaps its text to `pendingLabel` rather than emptying
17
+ itself, so its accessible name never disappears mid-press.
18
+
19
+ `action` is a plain promise-returning prop — no Effect in this library. A
20
+ rejection with an `Error` shows that error's message (the caller's own
21
+ wording, usually from the server); anything else shows `failureMessage`.
22
+ On success, `redirectTo` navigates through the components context, so an
23
+ app gets client-side routing and this component stays ignorant of it.
24
+ -->
25
+ <script lang="ts">import { getComponentsContext } from "../context.svelte.js";
26
+ import Alert from "./Alert.svelte";
27
+ import Button from "./Button.svelte";
28
+ let { action, idleLabel = "Delete", confirmLabel = "Confirm", cancelLabel = "Cancel", pendingLabel = "Working…", confirmMessage = "Are you sure? This cannot be undone.", failureMessage = "That didn’t work. Try again.", tone = "error", redirectTo, class: className } = $props();
29
+ const context = getComponentsContext();
30
+ let confirming = $state(false);
31
+ let pending = $state(false);
32
+ let errorMessage = $state(undefined);
33
+ const beginConfirmation = () => {
34
+ errorMessage = undefined;
35
+ confirming = true;
36
+ };
37
+ const cancelConfirmation = () => {
38
+ if (pending) return;
39
+ errorMessage = undefined;
40
+ confirming = false;
41
+ };
42
+ const confirmAction = async () => {
43
+ pending = true;
44
+ errorMessage = undefined;
45
+ try {
46
+ await action();
47
+ confirming = false;
48
+ if (redirectTo !== undefined) await context.navigate(context.href(redirectTo));
49
+ } catch (error) {
50
+ errorMessage = error instanceof Error ? error.message : failureMessage;
51
+ } finally {
52
+ pending = false;
53
+ }
54
+ };
55
+ </script>
56
+
57
+ <div class={['space-y-2', className]}>
58
+ {#if confirming}
59
+ <div class="flex flex-wrap items-center gap-2">
60
+ <p class="text-sm">{confirmMessage}</p>
61
+ <Button {tone} disabled={pending} loading={pending} onclick={confirmAction}>
62
+ {pending ? pendingLabel : confirmLabel}
63
+ </Button>
64
+ <Button variant="ghost" disabled={pending} onclick={cancelConfirmation}>
65
+ {cancelLabel}
66
+ </Button>
67
+ </div>
68
+ {:else}
69
+ <Button {tone} onclick={beginConfirmation}>{idleLabel}</Button>
70
+ {/if}
71
+
72
+ {#if errorMessage !== undefined}
73
+ <Alert tone="error" live="assertive">{errorMessage}</Alert>
74
+ {/if}
75
+ </div>
@@ -0,0 +1,48 @@
1
+ import type { Tone } from './tones.ts';
2
+ interface Props {
3
+ /** The destructive action itself. */
4
+ action: () => Promise<unknown>;
5
+ /**
6
+ * The resting button's text.
7
+ * @defaultValue `'Delete'`
8
+ */
9
+ idleLabel?: string | undefined;
10
+ /**
11
+ * The confirm button's text.
12
+ * @defaultValue `'Confirm'`
13
+ */
14
+ confirmLabel?: string | undefined;
15
+ /**
16
+ * The cancel button's text.
17
+ * @defaultValue `'Cancel'`
18
+ */
19
+ cancelLabel?: string | undefined;
20
+ /**
21
+ * The confirm button's text while the action is in flight.
22
+ * @defaultValue `'Working…'`
23
+ */
24
+ pendingLabel?: string | undefined;
25
+ /**
26
+ * The question shown beside the confirm and cancel buttons.
27
+ * @defaultValue `'Are you sure? This cannot be undone.'`
28
+ */
29
+ confirmMessage?: string | undefined;
30
+ /**
31
+ * Shown when the action rejects with something that is not an `Error`.
32
+ * @defaultValue `'That didn’t work. Try again.'`
33
+ */
34
+ failureMessage?: string | undefined;
35
+ /**
36
+ * Tone of the idle and confirm buttons.
37
+ * @defaultValue `'error'`
38
+ */
39
+ tone?: Tone | undefined;
40
+ /** Navigated to through the components context once `action` resolves. */
41
+ redirectTo?: string | undefined;
42
+ /** Extra classes, merged last. */
43
+ class?: string | undefined;
44
+ }
45
+ /** A destructive action behind a two-step inline confirmation. */
46
+ declare const ConfirmButton: import("svelte").Component<Props, {}, "">;
47
+ type ConfirmButton = ReturnType<typeof ConfirmButton>;
48
+ export default ConfirmButton;
@@ -0,0 +1,75 @@
1
+ <!-- @component
2
+ A menu that opens at the pointer on a right-click (or long-press) of a region, on bits-ui's `ContextMenu`.
3
+ -->
4
+ <!--
5
+ ContextMenu — the actions for one thing (a row in a list, a node on a
6
+ canvas, an image), opened where the reader right-clicks it, long-presses it
7
+ on touch, or presses Shift+F10 / the Menu key while it has focus. Built on
8
+ bits-ui's `ContextMenu`, which owns the menu at the pointer, roving focus,
9
+ typeahead, → / ← for submenus, Escape and outside click to close, and focus
10
+ return. Its children are the same `MenuItem`, `MenuSeparator`,
11
+ `MenuCheckboxItem`, `MenuRadioGroup` / `MenuRadioItem` and `MenuSub` that a
12
+ `DropdownMenu` takes; this component lends them the bits-ui parts through
13
+ context (`menu-parts/`).
14
+
15
+ Never the only route to an action. A context menu is invisible until it is
16
+ summoned, and touch screen-reader users (and many keyboard users) never
17
+ discover it. Put every action somewhere visible too: a row's "More"
18
+ `DropdownMenu`, a toolbar.
19
+
20
+ The region is the caller's own element: the `trigger` snippet receives
21
+ `props` to spread onto it. Those props make it focusable (`tabindex="0"`,
22
+ which a natively focusable element does not mind; pass a `tabindex` of your
23
+ own after the spread to override it), because browsers fire `contextmenu`
24
+ for the keyboard only on the focused element. Shift+F10 and the Menu key
25
+ are handled here rather than left to the browser, so they open the menu at
26
+ the region's corner the same way everywhere.
27
+
28
+ ARIA contract: the content is `role="menu"` named by `label`; the daisyUI
29
+ `menu` `<ul>` and its `<li>`s are `role="none"`, exactly as in
30
+ `DropdownMenu`, so `role="menu"` owns its items. `disabled` lets the
31
+ browser's own context menu show instead.
32
+
33
+ Not part of the root barrel: it is its own entry,
34
+ `@thomasfosterau/components/context-menu`, so the menu runtime loads only on
35
+ the pages that use it.
36
+ -->
37
+ <script lang="ts">import { ContextMenu } from "bits-ui";
38
+ import { menuParts } from "./menu-parts/parts.js";
39
+ import { setMenuParts } from "./menu-parts/menu-parts.js";
40
+ let { label, open = $bindable(false), disabled = false, class: className, trigger, children } = $props();
41
+ setMenuParts(menuParts("context"));
42
+ // Shift+F10 and the Menu key: open at the region's bottom-left corner by
43
+ // dispatching the `contextmenu` event bits-ui's trigger listens for.
44
+ // `preventDefault` stops the browser from generating its own as well.
45
+ const openFromKeyboard = (event) => {
46
+ if (disabled) return;
47
+ const isMenuKey = event.key === "ContextMenu" || event.shiftKey && event.key === "F10";
48
+ if (!isMenuKey) return;
49
+ event.preventDefault();
50
+ const region = event.currentTarget;
51
+ if (!(region instanceof HTMLElement)) return;
52
+ const rect = region.getBoundingClientRect();
53
+ region.dispatchEvent(new MouseEvent("contextmenu", {
54
+ bubbles: true,
55
+ cancelable: true,
56
+ clientX: rect.left,
57
+ clientY: rect.bottom
58
+ }));
59
+ };
60
+ </script>
61
+
62
+ <ContextMenu.Root bind:open>
63
+ <ContextMenu.Trigger {disabled} tabindex={0} onkeydown={openFromKeyboard}>
64
+ {#snippet child({ props })}
65
+ {@render trigger({ props })}
66
+ {/snippet}
67
+ </ContextMenu.Trigger>
68
+ <ContextMenu.Portal>
69
+ <ContextMenu.Content aria-label={label} class="z-50">
70
+ <ul role="none" class={['menu bg-base-100 rounded-box w-56 p-2 shadow-md', className]}>
71
+ {@render children()}
72
+ </ul>
73
+ </ContextMenu.Content>
74
+ </ContextMenu.Portal>
75
+ </ContextMenu.Root>
@@ -0,0 +1,25 @@
1
+ import { ContextMenu } from 'bits-ui';
2
+ import type { Snippet } from 'svelte';
3
+ interface Props {
4
+ /** Accessible name of the open menu ("Actions for Rosa canina"). */
5
+ label: string;
6
+ /** Whether the menu is open. Bindable. */
7
+ open?: boolean | undefined;
8
+ /**
9
+ * Turn the menu off; the browser's own context menu shows instead.
10
+ * @defaultValue `false`
11
+ */
12
+ disabled?: boolean | undefined;
13
+ /** Extra classes on the `<ul class="menu">`. */
14
+ class?: string | undefined;
15
+ /** The region the menu belongs to — the caller's own element, spreading `props`. */
16
+ trigger: Snippet<[{
17
+ props: Record<string, unknown>;
18
+ }]>;
19
+ /** The menu's items. */
20
+ children: Snippet<[]>;
21
+ }
22
+ /** A menu that opens at the pointer on a right-click (or long-press) of a region, on bits-ui's `ContextMenu`. */
23
+ declare const ContextMenu: import("svelte").Component<Props, {}, "open">;
24
+ type ContextMenu = ReturnType<typeof ContextMenu>;
25
+ export default ContextMenu;
@@ -0,0 +1,46 @@
1
+ <!-- @component
2
+ A native `<details>` wearing daisyUI’s `collapse`.
3
+ -->
4
+ <!--
5
+ Disclosure — a native `<details>` wearing daisyUI's `collapse`.
6
+
7
+ Hand-rolled disclosure is one of the most commonly broken widgets on the
8
+ web, and it does not need to be built: `<details>`/`<summary>` already give
9
+ a focusable trigger, the expanded/collapsed state, keyboard activation and
10
+ — on a modern browser — find-in-page inside the collapsed content, which no
11
+ JavaScript implementation matches. So this is NOT on bits-ui: there is
12
+ nothing for a primitive to add.
13
+
14
+ ARIA contract: the platform's. `<summary>` is the button, `open` is the
15
+ state, and no `aria-expanded` is written by hand (the browser maps it, and
16
+ a second copy can only be wrong). `open` is bindable, so a caller can drive
17
+ the state, and the four apps' "open this section because its form failed"
18
+ case is a one-line binding.
19
+
20
+ Exclusive groups are native too: give several `Disclosure`s the same
21
+ `name` (spread onto `<details>`) and the browser keeps at most one open.
22
+ What a `Disclosure` cannot carry is a heading, because `<summary>`'s
23
+ children are presentational, so a heading inside it drops out of the
24
+ heading tree. For a stack of headed sections, or a bindable "which one is
25
+ open", use `Accordion`.
26
+ -->
27
+ <script lang="ts">import { collapseVariant } from "./tones.js";
28
+ let { open = $bindable(false), title, variant = "arrow", contentClass, children, class: className, ...rest } = $props();
29
+ </script>
30
+
31
+ <details
32
+ {...rest}
33
+ bind:open
34
+ class={['collapse border-base-300 bg-base-100 border', collapseVariant[variant], className]}
35
+ >
36
+ <summary class="collapse-title font-medium">
37
+ {#if typeof title === 'string'}
38
+ {title}
39
+ {:else}
40
+ {@render title()}
41
+ {/if}
42
+ </summary>
43
+ <div class={['collapse-content', contentClass]}>
44
+ {@render children()}
45
+ </div>
46
+ </details>
@@ -0,0 +1,22 @@
1
+ import type { Snippet } from 'svelte';
2
+ import type { HTMLDetailsAttributes } from 'svelte/elements';
3
+ import { type DisclosureVariant } from './tones.ts';
4
+ interface Props extends Omit<HTMLDetailsAttributes, 'title' | 'open'> {
5
+ /** Whether the section is expanded. Bindable. */
6
+ open?: boolean | undefined;
7
+ /** The summary — its own text, or a snippet for richer markup. */
8
+ title: string | Snippet<[]>;
9
+ /**
10
+ * The expand indicator: an arrow, a plus, or none.
11
+ * @defaultValue `'arrow'`
12
+ */
13
+ variant?: DisclosureVariant | undefined;
14
+ /** Extra classes on the `collapse-content` wrapper. */
15
+ contentClass?: string | undefined;
16
+ /** The content revealed when open. */
17
+ children: Snippet<[]>;
18
+ }
19
+ /** A native `<details>` wearing daisyUI’s `collapse`. */
20
+ declare const Disclosure: import("svelte").Component<Props, {}, "open">;
21
+ type Disclosure = ReturnType<typeof Disclosure>;
22
+ export default Disclosure;
@@ -0,0 +1,47 @@
1
+ <!-- @component
2
+ A horizontal or vertical rule between content, optionally labelled ("or"), in daisyUI's `divider` styles.
3
+ -->
4
+ <!--
5
+ Divider — a rule between sections or side-by-side items, optionally with a
6
+ short label on it ("or" between two sign-in methods).
7
+
8
+ Hand-rolled, not on bits-ui's `Separator` (AGENTS.md asks for the reason):
9
+ that primitive's whole contribution is `role="separator"` +
10
+ `aria-orientation`, or `role="none"` when decorative — two attributes,
11
+ written here directly, with no bits-ui on the always-loaded path.
12
+
13
+ ARIA contract:
14
+ - Unlabelled: `role="separator"`; vertical adds
15
+ `aria-orientation="vertical"` (horizontal is the implicit default). It
16
+ is a `<div>`, not a native `<hr>`, because daisyUI draws the rule with
17
+ `::before` / `::after`, which a void `<hr>` cannot render.
18
+ - Labelled: NOT a separator. A non-focusable separator's children are
19
+ presentational, so the label would be lost to assistive technology. The
20
+ wrapper is `role="none"` and the text reads in flow — "Sign in with a
21
+ passkey / or / Continue with email" (WAI-ARIA 1.2, separator).
22
+ - `decorative`: `aria-hidden="true"`, nothing announced.
23
+
24
+ Not `MenuSeparator`, which must be an `<li>` inside a menu and defers to
25
+ bits-ui's menu separator for roving focus; use that one inside `Menu`.
26
+ -->
27
+ <script lang="ts">import { dividerAlign, dividerOrientation, dividerTone } from "./tones.js";
28
+ let { orientation = "horizontal", decorative = false, align = "center", tone, children, class: className, ...rest } = $props();
29
+ const classes = $derived([
30
+ "divider",
31
+ dividerOrientation[orientation],
32
+ dividerAlign[align],
33
+ tone !== undefined && dividerTone[tone],
34
+ className
35
+ ]);
36
+ const role = $derived(decorative || children !== undefined ? "none" : "separator");
37
+ </script>
38
+
39
+ <div
40
+ {...rest}
41
+ {role}
42
+ aria-orientation={role === 'separator' && orientation === 'vertical' ? 'vertical' : undefined}
43
+ aria-hidden={decorative ? 'true' : undefined}
44
+ class={classes}
45
+ >
46
+ {#if children}<span>{@render children()}</span>{/if}
47
+ </div>
@@ -0,0 +1,28 @@
1
+ import type { Snippet } from 'svelte';
2
+ import type { HTMLAttributes } from 'svelte/elements';
3
+ import { type DividerAlign, type Tone } from './tones.ts';
4
+ interface Props extends Omit<HTMLAttributes<HTMLDivElement>, 'children'> {
5
+ /**
6
+ * Which way the rule runs: `vertical` sits between side-by-side items.
7
+ * @defaultValue `'horizontal'`
8
+ */
9
+ orientation?: 'horizontal' | 'vertical' | undefined;
10
+ /**
11
+ * The rule marks no real boundary: hide it from assistive technology.
12
+ * @defaultValue `false`
13
+ */
14
+ decorative?: boolean | undefined;
15
+ /**
16
+ * Where a label sits along the rule.
17
+ * @defaultValue `'center'`
18
+ */
19
+ align?: DividerAlign | undefined;
20
+ /** Semantic colour of the rule. */
21
+ tone?: Tone | undefined;
22
+ /** Short text on the rule ("or"). */
23
+ children?: Snippet<[]> | undefined;
24
+ }
25
+ /** A horizontal or vertical rule between content, optionally labelled ("or"), in daisyUI's `divider` styles. */
26
+ declare const Divider: import("svelte").Component<Props, {}, "">;
27
+ type Divider = ReturnType<typeof Divider>;
28
+ export default Divider;
@@ -0,0 +1,44 @@
1
+ <!-- @component
2
+ An application menu behind a trigger — a bits-ui dropdown of `MenuItem`s styled as a daisyUI `menu`.
3
+ -->
4
+ <!--
5
+ DropdownMenu — an application menu: bits-ui's `DropdownMenu`, which owns
6
+ `aria-haspopup`/`aria-expanded` on the trigger, arrow-key roving focus,
7
+ typeahead, Escape to close and focus return. The daisyUI `menu` styling is
8
+ applied to a `<ul>` INSIDE the content; that list and its items' `<li>`
9
+ wrappers carry `role="none"` so the presentation layer does not come
10
+ between `role="menu"` and its `role="menuitem"` children in the
11
+ accessibility tree.
12
+
13
+ It is a separate component from `Menu` (site navigation) so that bits-ui's
14
+ dropdown runtime is reached only by an app that actually renders a
15
+ dropdown: `Menu`, `MenuItem`, `MenuSeparator` and `Sidebar` import nothing
16
+ from bits-ui (#129). The children are the same `MenuItem` /
17
+ `MenuSeparator` a `Menu` takes; this component lends them its bits-ui item
18
+ and separator parts through context (`menu-parts/menu-parts.ts`), and
19
+ the same for `MenuCheckboxItem`, `MenuRadioGroup`, `MenuRadioItem` and
20
+ `MenuSub`.
21
+ -->
22
+ <script lang="ts">import { DropdownMenu } from "bits-ui";
23
+ import { menuParts } from "./menu-parts/parts.js";
24
+ import { setMenuParts } from "./menu-parts/menu-parts.js";
25
+ let { label, open = $bindable(false), side = "bottom", align = "end", class: className, trigger, children } = $props();
26
+ setMenuParts(menuParts("dropdown"));
27
+ </script>
28
+
29
+ <DropdownMenu.Root bind:open>
30
+ {#if trigger}
31
+ <DropdownMenu.Trigger>
32
+ {#snippet child({ props })}
33
+ {@render trigger({ props })}
34
+ {/snippet}
35
+ </DropdownMenu.Trigger>
36
+ {/if}
37
+ <DropdownMenu.Portal>
38
+ <DropdownMenu.Content {side} {align} sideOffset={8} aria-label={label} class="z-50">
39
+ <ul role="none" class={['menu bg-base-100 rounded-box w-56 p-2 shadow-md', className]}>
40
+ {@render children()}
41
+ </ul>
42
+ </DropdownMenu.Content>
43
+ </DropdownMenu.Portal>
44
+ </DropdownMenu.Root>
@@ -0,0 +1,30 @@
1
+ import { DropdownMenu } from 'bits-ui';
2
+ import type { Snippet } from 'svelte';
3
+ interface Props {
4
+ /** Accessible name of the open menu. */
5
+ label: string;
6
+ /** Whether the menu is open. Bindable. */
7
+ open?: boolean | undefined;
8
+ /**
9
+ * Which side of the trigger the menu opens on.
10
+ * @defaultValue `'bottom'`
11
+ */
12
+ side?: 'top' | 'right' | 'bottom' | 'left' | undefined;
13
+ /**
14
+ * Alignment against the trigger.
15
+ * @defaultValue `'end'`
16
+ */
17
+ align?: 'start' | 'center' | 'end' | undefined;
18
+ /** Extra classes on the `<ul class="menu">`. */
19
+ class?: string | undefined;
20
+ /** The trigger — the caller's own element, spreading `props`. */
21
+ trigger?: Snippet<[{
22
+ props: Record<string, unknown>;
23
+ }]> | undefined;
24
+ /** The `MenuItem`s. */
25
+ children: Snippet<[]>;
26
+ }
27
+ /** An application menu behind a trigger — a bits-ui dropdown of `MenuItem`s styled as a daisyUI `menu`. */
28
+ declare const DropdownMenu: import("svelte").Component<Props, {}, "open">;
29
+ type DropdownMenu = ReturnType<typeof DropdownMenu>;
30
+ export default DropdownMenu;
@@ -0,0 +1,37 @@
1
+ <!-- @component
2
+ The quiet card an index or result list shows instead of a bare empty list: a heading, optional copy, icon and call to action.
3
+ -->
4
+ <!--
5
+ EmptyState — the quiet card an index or a result list shows instead of a
6
+ bare empty `<ul>`: a heading, optional supporting copy, an optional icon
7
+ above and an optional call to action below.
8
+
9
+ Content-first, not a hero. "Nothing here" is a normal state of a healthy
10
+ page, and the surface it is drawn on is the same `Card` every other block
11
+ on the page uses, so an empty list does not look like a failure.
12
+
13
+ ARIA contract: `title` is a real heading at `headingLevel` (`h2` by
14
+ default), so a reader navigating by headings finds out the section is empty
15
+ instead of finding nothing at all. The icon is decorative and hidden.
16
+ -->
17
+ <script lang="ts">import Card from "./Card.svelte";
18
+ let { title, description, headingLevel = 2, icon, action, class: className, ...rest } = $props();
19
+ </script>
20
+
21
+ <Card
22
+ {...rest}
23
+ as="div"
24
+ class={className}
25
+ bodyClass="items-center gap-2 p-8 text-center sm:p-10"
26
+ >
27
+ {#if icon}
28
+ <div class="text-base-content/50 mb-2" aria-hidden="true">{@render icon()}</div>
29
+ {/if}
30
+ <svelte:element this={`h${headingLevel}`} class="text-2xl font-semibold">{title}</svelte:element>
31
+ {#if description !== undefined}
32
+ <p class="text-base-content/70 max-w-prose leading-7">{description}</p>
33
+ {/if}
34
+ {#if action}
35
+ <div class="mt-2">{@render action()}</div>
36
+ {/if}
37
+ </Card>
@@ -0,0 +1,22 @@
1
+ import type { Snippet } from 'svelte';
2
+ import type { HTMLAttributes } from 'svelte/elements';
3
+ import type { HeadingLevel } from './tones.ts';
4
+ interface Props extends HTMLAttributes<HTMLElement> {
5
+ /** Short, direct heading for the empty surface ("No results yet"). */
6
+ title: string;
7
+ /** Supporting copy explaining the state or the next step. */
8
+ description?: string | undefined;
9
+ /**
10
+ * The heading level, so the page outline stays intact.
11
+ * @defaultValue `2`
12
+ */
13
+ headingLevel?: HeadingLevel | undefined;
14
+ /** Decorative icon rendered above the heading. */
15
+ icon?: Snippet<[]> | undefined;
16
+ /** Call to action — a button or a link — rendered under the copy. */
17
+ action?: Snippet<[]> | undefined;
18
+ }
19
+ /** The quiet card an index or result list shows instead of a bare empty list: a heading, optional copy, icon and call to action. */
20
+ declare const EmptyState: import("svelte").Component<Props, {}, "">;
21
+ type EmptyState = ReturnType<typeof EmptyState>;
22
+ export default EmptyState;
@@ -0,0 +1,38 @@
1
+ <!-- @component
2
+ A link off the site that opens in a new tab with the right `rel`, and says so to assistive technology.
3
+ -->
4
+ <!--
5
+ ExternalLink — a link off the site, with the `rel` decision made for the
6
+ call site.
7
+
8
+ The `rel` is the reason this is a component and not four lines of markup.
9
+ An address a member typed into their own profile is untrusted outbound
10
+ linkage and carries `nofollow`; a resolver URL the site itself composed
11
+ from a recorded identifier (an ORCID, a DOI) is not, and carries only
12
+ `noreferrer`. The distinction is invisible when it is wrong, which is
13
+ exactly the kind of thing that should not be retyped per page. Hence
14
+ `untrusted` defaults to `true`: the safe answer is the one you get by not
15
+ thinking about it.
16
+
17
+ ARIA contract: `target="_blank"` always pairs with `noreferrer`, and the
18
+ new tab is ANNOUNCED — a visually hidden "(opens in a new tab)" after the
19
+ text, so a screen-reader user learns what a sighted user learns from the
20
+ icon. The icon itself is `aria-hidden`; it says nothing the text does not.
21
+ -->
22
+ <script lang="ts">import { ExternalLink as ExternalLinkIcon } from "@lucide/svelte";
23
+ import { linkVariant } from "./tones.js";
24
+ import VisuallyHidden from "./VisuallyHidden.svelte";
25
+ let { href, variant = "muted", untrusted = true, showIcon = true, newTabLabel = "(opens in a new tab)", children, class: className, ...rest } = $props();
26
+ </script>
27
+
28
+ <a
29
+ {...rest}
30
+ {href}
31
+ target="_blank"
32
+ rel={untrusted ? 'noreferrer nofollow' : 'noreferrer'}
33
+ class={['inline-flex items-center gap-1', linkVariant[variant], className]}
34
+ >
35
+ {@render children()}
36
+ <VisuallyHidden>{newTabLabel}</VisuallyHidden>
37
+ {#if showIcon}<ExternalLinkIcon class="size-3.5 shrink-0" aria-hidden="true" />{/if}
38
+ </a>
@@ -0,0 +1,34 @@
1
+ import type { Snippet } from 'svelte';
2
+ import type { HTMLAnchorAttributes } from 'svelte/elements';
3
+ import { type LinkVariant } from './tones.ts';
4
+ interface Props extends Omit<HTMLAnchorAttributes, 'href'> {
5
+ /** The absolute URL. */
6
+ href: string;
7
+ /**
8
+ * The link weight.
9
+ * @defaultValue `'muted'`
10
+ */
11
+ variant?: LinkVariant | undefined;
12
+ /**
13
+ * Whether the destination is user-supplied. `true` (the default) adds
14
+ * `nofollow`; pass `false` only for an address this site composed itself.
15
+ * @defaultValue `true`
16
+ */
17
+ untrusted?: boolean | undefined;
18
+ /**
19
+ * Show the trailing new-tab icon.
20
+ * @defaultValue `true`
21
+ */
22
+ showIcon?: boolean | undefined;
23
+ /**
24
+ * The announcement appended to the link text, for assistive technology.
25
+ * @defaultValue `'(opens in a new tab)'`
26
+ */
27
+ newTabLabel?: string | undefined;
28
+ /** The link text; the new-tab notice is appended for assistive technology. */
29
+ children: Snippet<[]>;
30
+ }
31
+ /** A link off the site that opens in a new tab with the right `rel`, and says so to assistive technology. */
32
+ declare const ExternalLink: import("svelte").Component<Props, {}, "">;
33
+ type ExternalLink = ReturnType<typeof ExternalLink>;
34
+ export default ExternalLink;
@@ -0,0 +1,58 @@
1
+ <!-- @component
2
+ A heading at any level with a stable `id`, optionally with a copyable anchor link.
3
+ -->
4
+ <!--
5
+ Heading — a section heading at any level, with a stable `id` so the section
6
+ is addressable: a table of contents, a "copy link to this section" anchor,
7
+ a URL fragment someone pasted into a message.
8
+
9
+ ARIA contract: a real `<h1>`–`<h6>` at the level the caller names. The level
10
+ is a PROP and not a consequence of the styling, because the outline is a
11
+ document structure and the type scale is a visual one; `class` overrides the
12
+ latter without touching the former. `scroll-mt` keeps a hash target clear of
13
+ a sticky header. The anchor link, when shown, has a real accessible name
14
+ (`anchorLabel`); the `#` glyph beside it is decorative.
15
+
16
+ The id is derived from `children` AT RENDER when `children` is a string —
17
+ not measured from the mounted element in an `$effect`, which is how the
18
+ original did it and which means the server renders a heading with
19
+ no id at all and every in-page link is dead until hydration. A snippet's
20
+ text is not knowable before render, so a snippet heading that wants an
21
+ anchor must be given an explicit `id`; without one the anchor is omitted
22
+ rather than pointing at nothing.
23
+ -->
24
+ <script lang="ts">import { slugify } from "./slug.js";
25
+ import VisuallyHidden from "./VisuallyHidden.svelte";
26
+ let { level, id, anchor = false, anchorLabel = "Link to this section", children, class: className, ...rest } = $props();
27
+ const headingId = $derived(id ?? (typeof children === "string" ? slugify(children) : undefined));
28
+ const levelClasses = {
29
+ 1: "mt-8 mb-6 text-3xl sm:text-4xl",
30
+ 2: "mt-6 mb-4 text-2xl sm:text-3xl",
31
+ 3: "mt-5 mb-3 text-xl sm:text-2xl",
32
+ 4: "mt-4 mb-3 text-lg sm:text-xl",
33
+ 5: "mt-4 mb-2 text-base sm:text-lg",
34
+ 6: "mt-3 mb-2 text-sm sm:text-base"
35
+ };
36
+ </script>
37
+
38
+ <svelte:element
39
+ this={`h${level}`}
40
+ {...rest}
41
+ id={headingId}
42
+ class={['group scroll-mt-16 font-bold', levelClasses[level], className]}
43
+ >
44
+ {#if typeof children === 'string'}
45
+ {children}
46
+ {:else}
47
+ {@render children()}
48
+ {/if}
49
+ {#if anchor && headingId !== undefined}
50
+ <a
51
+ href={`#${headingId}`}
52
+ class="link link-hover text-base-content/40 ml-2 opacity-0 transition-opacity focus:opacity-100 group-hover:opacity-100"
53
+ >
54
+ <span aria-hidden="true">#</span>
55
+ <VisuallyHidden>{anchorLabel}</VisuallyHidden>
56
+ </a>
57
+ {/if}
58
+ </svelte:element>