@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,150 @@
1
+ <!-- @component
2
+ A `Table` with client-side sorting, filtering across every column and paging, for a list that is already entirely in hand.
3
+ -->
4
+ <!--
5
+ DataGrid — the three controls a reader wants over a list that is already
6
+ entirely in hand: sort a column, filter across every column, page through
7
+ the result.
8
+
9
+ It draws no table of its own. The rows go through `Table` and the pager
10
+ through `Pagination`, so the cell markup, the empty state, the sort control
11
+ and the disabled-arm rule all have exactly one implementation, and this file
12
+ is the decisions rather than the markup.
13
+
14
+ **Client-side, and that is the constraint.** Every derivation below runs
15
+ over the whole `rows` array on every keystroke, so this is for a bounded set
16
+ the page already holds — a vocabulary, an account's devices, a taxon's
17
+ synonyms. A collection the API pages belongs on `Table` + `PaginationFooter`,
18
+ where the server does the work; pointing this at one would silently sort and
19
+ filter the current page only, which reads as data loss rather than as a
20
+ limitation.
21
+
22
+ ARIA contract: the `Table`'s and the `Pagination`'s. The filter is a
23
+ `<input type="search">` with a real label (visually hidden, because the
24
+ control sits in a toolbar where a visible label would be the only one), and
25
+ the rows-per-page `<select>` is named by `rowsPerPageLabel`.
26
+ -->
27
+ <script lang="ts" generics="T">import { getComponentsContext } from "../context.svelte.js";
28
+ import Pagination from "./Pagination.svelte";
29
+ import Table from "./Table.svelte";
30
+ let { rows, columns, rowKey, filterable = false, paginated = true, pageSize = 10, pageSizeOptions = [
31
+ 10,
32
+ 25,
33
+ 50,
34
+ 100
35
+ ], caption, captionHidden, size, zebra, pinRows, sort = $bindable(undefined), onSelect, emptyMessage, emptyState, filterLabel = "Search", filterPlaceholder = "Search…", rowsPerPageLabel = "Rows per page", showingLabel = (start, end, total) => `Showing ${start} to ${end} of ${total}`, pageOfLabel = (page, pages) => `Page ${page} of ${pages}`, previousLabel = "Previous", nextLabel = "Next", paginationLabel = "Pagination", sortLabel, locales = getComponentsContext().locale(), class: className, ...rest } = $props();
36
+ let filter = $state("");
37
+ // 0 is "the reader has not chosen": the `pageSize` prop stays authoritative
38
+ // until they pick from the menu, so a page that changes the prop is honoured
39
+ // rather than overridden by state seeded once at mount.
40
+ let chosenSize = $state(0);
41
+ let page = $state(0);
42
+ const limit = $derived(chosenSize === 0 ? pageSize : chosenSize);
43
+ const filtered = $derived.by(() => {
44
+ const needle = filter.trim().toLowerCase();
45
+ if (needle === "") return rows;
46
+ // The filter searches the column's VALUE, not its rendered cell: a cell
47
+ // may be a badge or a link, and a reader typing what they can see is
48
+ // typing the value either way.
49
+ return rows.filter((row) => columns.some((column) => String(column.value(row)).toLowerCase().includes(needle)));
50
+ });
51
+ const sorted = $derived.by(() => {
52
+ const active = sort;
53
+ if (active === undefined) return filtered;
54
+ const column = columns.find((candidate) => candidate.key === active.key);
55
+ if (column === undefined) return filtered;
56
+ const direction = active.direction === "asc" ? 1 : -1;
57
+ // `localeCompare` in the active locale, so a Swedish reader gets Swedish
58
+ // collation rather than code-point order; numbers compare numerically,
59
+ // because "10" sorts before "9" as a string and that is always wrong.
60
+ return filtered.toSorted((left, right) => {
61
+ const a = column.value(left);
62
+ const b = column.value(right);
63
+ if (typeof a === "number" && typeof b === "number") return (a - b) * direction;
64
+ return String(a).localeCompare(String(b), locales) * direction;
65
+ });
66
+ });
67
+ const total = $derived(sorted.length);
68
+ const pageCount = $derived(paginated ? Math.max(1, Math.ceil(total / limit)) : 1);
69
+ // A filter that shrinks the result out from under the current page would
70
+ // otherwise leave the reader looking at an empty body with rows they cannot
71
+ // reach. Clamping in a derivation rather than in the filter's handler keeps
72
+ // it true however the page count changed — including a `rows` prop that
73
+ // shrank without anyone typing.
74
+ const current = $derived(Math.min(page, pageCount - 1));
75
+ const visible = $derived(paginated ? sorted.slice(current * limit, current * limit + limit) : sorted);
76
+ const from = $derived(total === 0 ? 0 : current * limit + 1);
77
+ const to = $derived(Math.min((current + 1) * limit, total));
78
+ </script>
79
+
80
+ <div {...rest} class={['space-y-3', className]}>
81
+ {#if filterable}
82
+ <label class="input input-sm w-full max-w-xs">
83
+ <span class="sr-only">{filterLabel}</span>
84
+ <input
85
+ type="search"
86
+ bind:value={filter}
87
+ oninput={() => {
88
+ page = 0;
89
+ }}
90
+ placeholder={filterPlaceholder}
91
+ aria-label={filterLabel}
92
+ />
93
+ </label>
94
+ {/if}
95
+
96
+ <Table
97
+ rows={visible}
98
+ {columns}
99
+ {rowKey}
100
+ {caption}
101
+ {captionHidden}
102
+ {size}
103
+ {zebra}
104
+ {pinRows}
105
+ {onSelect}
106
+ {emptyMessage}
107
+ {emptyState}
108
+ {sortLabel}
109
+ bind:sort
110
+ onSort={() => {
111
+ // A new sort re-orders the whole result, so the reader's place in the
112
+ // old order means nothing; page 1 is the only honest answer.
113
+ page = 0;
114
+ }}
115
+ />
116
+
117
+ {#if paginated && total > 0}
118
+ <div class="flex flex-wrap items-center justify-between gap-3">
119
+ <div class="flex items-center gap-2">
120
+ <p class="text-base-content/70 text-sm tabular-nums">{showingLabel(from, to, total)}</p>
121
+ <select
122
+ class="select select-sm w-auto"
123
+ aria-label={rowsPerPageLabel}
124
+ value={limit}
125
+ onchange={(event) => {
126
+ chosenSize = Number(event.currentTarget.value);
127
+ page = 0;
128
+ }}
129
+ >
130
+ {#each pageSizeOptions as option (option)}
131
+ <option value={option}>{option}</option>
132
+ {/each}
133
+ </select>
134
+ </div>
135
+ <Pagination
136
+ offset={current * limit}
137
+ {limit}
138
+ {total}
139
+ variant="prevNext"
140
+ label={paginationLabel}
141
+ {previousLabel}
142
+ {nextLabel}
143
+ statusLabel={pageOfLabel}
144
+ onPage={(offset) => {
145
+ page = Math.floor(offset / limit);
146
+ }}
147
+ />
148
+ </div>
149
+ {/if}
150
+ </div>
@@ -0,0 +1,118 @@
1
+ import type { Snippet } from 'svelte';
2
+ import type { HTMLAttributes } from 'svelte/elements';
3
+ import type { Size } from '../ui/tones.ts';
4
+ import type { SortState, TableColumn } from './table-types.ts';
5
+ declare function $$render<T>(): {
6
+ props: Omit<HTMLAttributes<HTMLDivElement>, "children"> & {
7
+ /** Every row; sorting, filtering and paging happen here. */
8
+ rows: readonly T[];
9
+ /** Column definitions: header, cell renderer, sort key. */
10
+ columns: readonly TableColumn<T>[];
11
+ /** Stable identity per row — the `{#each}` key. */
12
+ rowKey: (row: T) => string;
13
+ /** Offer the filter box. */
14
+ filterable?: boolean | undefined;
15
+ /**
16
+ * Offer the pager; every row renders when false.
17
+ * @defaultValue `true`
18
+ */
19
+ paginated?: boolean | undefined;
20
+ /**
21
+ * Rows per page until the reader picks another size.
22
+ * @defaultValue `10`
23
+ */
24
+ pageSize?: number | undefined;
25
+ /**
26
+ * The choices offered in the rows-per-page select.
27
+ * @defaultValue `[10, 25, 50, 100]`
28
+ */
29
+ pageSizeOptions?: readonly number[] | undefined;
30
+ /** The table's accessible name, rendered as its `<caption>`. */
31
+ caption?: string | undefined;
32
+ /** Keep the caption for assistive technology only. */
33
+ captionHidden?: boolean | undefined;
34
+ /** daisyUI size step. */
35
+ size?: Size | undefined;
36
+ /** Stripe alternate rows. */
37
+ zebra?: boolean | undefined;
38
+ /** Stick the header row while the body scrolls; see `Table`. */
39
+ pinRows?: boolean | undefined;
40
+ /** Which column starts sorted. Bindable; `undefined` is the caller's order. */
41
+ sort?: SortState | undefined;
42
+ /** Makes every row activatable by pointer and keyboard; see `Table`. */
43
+ onSelect?: ((row: T) => void) | undefined;
44
+ /** The line shown when no row matches. */
45
+ emptyMessage?: string | undefined;
46
+ /** Richer empty state, in place of `emptyMessage`. */
47
+ emptyState?: Snippet<[]> | undefined;
48
+ /**
49
+ * Accessible name of the filter box.
50
+ * @defaultValue `'Search'`
51
+ */
52
+ filterLabel?: string | undefined;
53
+ /**
54
+ * Placeholder in the filter box.
55
+ * @defaultValue `'Search…'`
56
+ */
57
+ filterPlaceholder?: string | undefined;
58
+ /**
59
+ * Label of the rows-per-page select.
60
+ * @defaultValue `'Rows per page'`
61
+ */
62
+ rowsPerPageLabel?: string | undefined;
63
+ /**
64
+ * The range line under the table.
65
+ * @defaultValue `"Showing <start> to <end> of <total>"`
66
+ */
67
+ showingLabel?: ((start: number, end: number, total: number) => string) | undefined;
68
+ /**
69
+ * The page status between the pager arms.
70
+ * @defaultValue `"Page <page> of <pages>"`
71
+ */
72
+ pageOfLabel?: ((page: number, pages: number) => string) | undefined;
73
+ /**
74
+ * Text of the previous-page control.
75
+ * @defaultValue `'Previous'`
76
+ */
77
+ previousLabel?: string | undefined;
78
+ /**
79
+ * Text of the next-page control.
80
+ * @defaultValue `'Next'`
81
+ */
82
+ nextLabel?: string | undefined;
83
+ /**
84
+ * Accessible name of the pager landmark.
85
+ * @defaultValue `'Pagination'`
86
+ */
87
+ paginationLabel?: string | undefined;
88
+ /** How a sortable column’s button is named; see `Table`. */
89
+ sortLabel?: ((column: TableColumn<T>) => string) | undefined;
90
+ /**
91
+ * Locale(s) for `Intl` formatting.
92
+ * @defaultValue the components context's `locale()`
93
+ */
94
+ locales?: string | readonly string[] | undefined;
95
+ };
96
+ exports: {};
97
+ bindings: "sort";
98
+ slots: {};
99
+ events: {};
100
+ };
101
+ declare class __sveltets_Render<T> {
102
+ props(): ReturnType<typeof $$render<T>>['props'];
103
+ events(): ReturnType<typeof $$render<T>>['events'];
104
+ slots(): ReturnType<typeof $$render<T>>['slots'];
105
+ bindings(): "sort";
106
+ exports(): {};
107
+ }
108
+ interface $$IsomorphicComponent {
109
+ new <T>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<T>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<T>['props']>, ReturnType<__sveltets_Render<T>['events']>, ReturnType<__sveltets_Render<T>['slots']>> & {
110
+ $$bindings?: ReturnType<__sveltets_Render<T>['bindings']>;
111
+ } & ReturnType<__sveltets_Render<T>['exports']>;
112
+ <T>(internal: unknown, props: ReturnType<__sveltets_Render<T>['props']> & {}): ReturnType<__sveltets_Render<T>['exports']>;
113
+ z_$$bindings?: ReturnType<__sveltets_Render<any>['bindings']>;
114
+ }
115
+ /** A `Table` with client-side sorting, filtering across every column and paging, for a list that is already entirely in hand. */
116
+ declare const DataGrid: $$IsomorphicComponent;
117
+ type DataGrid<T> = InstanceType<typeof DataGrid<T>>;
118
+ export default DataGrid;
@@ -0,0 +1,53 @@
1
+ <!-- @component
2
+ Label/value pairs as a `grid`, a bordered `card`, `divided` rows, `inline` pairs, or `bare` pairs in a layout the caller supplies.
3
+ -->
4
+ <!--
5
+ DescriptionList — label / value pairs, in the four shapes a detail page
6
+ wants them: a two-column `grid`, a bordered `card` with the labels in a
7
+ fixed gutter, `divided` rows, or `inline` pairs running across a line —
8
+ or `bare`, which adds no layout of its own: the `<dl>` takes only the
9
+ caller's `class` (say `grid grid-cols-[auto_1fr] gap-x-4`) and every
10
+ row's `<dt>`/`<dd>` is a direct child of it, so a consumer-owned grid can
11
+ mix `DescriptionRow`s with its own `<dt>`/`<dd>` pairs and keep its columns.
12
+
13
+ One component rather than the two the apps had. They had split it by how the
14
+ VALUE arrives — one took rows as strings, the other took them as markup —
15
+ which meant a page needing a formatted date in one row and a string in the
16
+ next had to choose a component per list. Here the value is a prop or a
17
+ snippet on the ROW, so both live in one list.
18
+
19
+ `mono` marks the values that are identifiers (a formula, an InChIKey, a
20
+ DOI) rather than sentences: those want a fixed-width face and a
21
+ break-anywhere rule, and the ones that are prose do not.
22
+
23
+ ARIA contract: a real `<dl>` of `<dt>`/`<dd>` pairs, which is what makes the
24
+ label / value association exist at all — a screen reader reads a `<dd>` as
25
+ the definition of the `<dt>` before it. The variant reaches the rows through
26
+ context (see `description-context.ts`), never through a class on the list
27
+ that the rows would have to guess at.
28
+ -->
29
+ <script lang="ts">import { setDescriptionListStyle } from "./description-context.js";
30
+ let { variant = "grid", mono = false, showEmpty = false, emptyLabel = "unrecorded", children, class: className, ...rest } = $props();
31
+ // Literal lookup table: Tailwind reads the class names out of the source,
32
+ // so a template string would emit no CSS at all.
33
+ const listClass = {
34
+ grid: "grid grid-cols-1 gap-3 sm:grid-cols-2",
35
+ card: "card card-border card-body bg-base-100 grid grid-cols-1 gap-x-6 gap-y-3 sm:grid-cols-[12rem_1fr]",
36
+ divided: "divide-base-300 divide-y",
37
+ inline: "flex flex-wrap gap-x-6 gap-y-2",
38
+ // The caller's `class` is the whole layout.
39
+ bare: ""
40
+ };
41
+ // A getter, not a snapshot: the rows re-read it, so a list whose `variant`
42
+ // changes re-styles the rows it already mounted.
43
+ setDescriptionListStyle(() => ({
44
+ variant,
45
+ mono,
46
+ showEmpty,
47
+ emptyLabel
48
+ }));
49
+ </script>
50
+
51
+ <dl {...rest} class={[listClass[variant], className]}>
52
+ {@render children()}
53
+ </dl>
@@ -0,0 +1,26 @@
1
+ import type { Snippet } from 'svelte';
2
+ import type { HTMLAttributes } from 'svelte/elements';
3
+ import { type DescriptionListStyle } from './description-context.ts';
4
+ type Variant = DescriptionListStyle['variant'];
5
+ interface Props extends HTMLAttributes<HTMLElement> {
6
+ /**
7
+ * The layout.
8
+ * @defaultValue `'grid'`
9
+ */
10
+ variant?: Variant | undefined;
11
+ /** Render values in a fixed-width face that breaks anywhere. */
12
+ mono?: boolean | undefined;
13
+ /** Render rows whose value is empty, rather than dropping them. */
14
+ showEmpty?: boolean | undefined;
15
+ /**
16
+ * What an empty value reads as when `showEmpty`.
17
+ * @defaultValue `'unrecorded'`
18
+ */
19
+ emptyLabel?: string | undefined;
20
+ /** The rows — `DescriptionRow`s, or any other `<dt>`/`<dd>` pairs. */
21
+ children: Snippet<[]>;
22
+ }
23
+ /** Label/value pairs as a `grid`, a bordered `card`, `divided` rows, `inline` pairs, or `bare` pairs in a layout the caller supplies. */
24
+ declare const DescriptionList: import("svelte").Component<Props, {}, "">;
25
+ type DescriptionList = ReturnType<typeof DescriptionList>;
26
+ export default DescriptionList;
@@ -0,0 +1,56 @@
1
+ <!-- @component
2
+ One label and its value inside a `DescriptionList`.
3
+ -->
4
+ <!--
5
+ DescriptionRow — one label and its value inside a `DescriptionList`.
6
+
7
+ A row with nothing in it renders NOTHING. An empty `<dd>` is a worse answer
8
+ than an absent row: it claims the page looked and found a blank, where the
9
+ absent row claims nothing at all. `showEmpty` is for the lists where the
10
+ absence is the point — a specimen record whose empty fields are what the
11
+ reader is checking — and it renders `emptyLabel` in the value's place.
12
+ Both settings come from the enclosing list by default and can be overridden
13
+ per row.
14
+
15
+ The `card` and `bare` variants' `<dt>` and `<dd>` are siblings of every
16
+ other row's, directly in the `<dl>` (the list's own two-column grid for
17
+ `card`, whatever layout the caller gave it for `bare`): a wrapper would
18
+ break the alignment the grid exists for. Every other variant wraps the
19
+ pair, so the two stay together when the rows wrap.
20
+
21
+ ARIA contract: the `<dt>`/`<dd>` pairing is the whole contract — nothing is
22
+ added to it, and nothing needs to be.
23
+ -->
24
+ <script lang="ts">import { getDescriptionListStyle } from "./description-context.js";
25
+ let { label, value, children, valueClass, labelClass, showEmpty, emptyLabel } = $props();
26
+ const style = getDescriptionListStyle();
27
+ const hasValue = $derived(children !== undefined || value !== undefined && String(value).trim() !== "");
28
+ const visible = $derived(hasValue || (showEmpty ?? style().showEmpty));
29
+ const placeholder = $derived(emptyLabel ?? style().emptyLabel);
30
+ const dtClass = $derived(["text-base-content/60 text-sm", labelClass]);
31
+ const ddClass = $derived([
32
+ "text-sm",
33
+ style().mono && "font-mono break-all",
34
+ !hasValue && "text-base-content/50 italic",
35
+ valueClass
36
+ ]);
37
+ </script>
38
+
39
+ {#snippet pair()}
40
+ <dt class={dtClass}>{label}</dt>
41
+ <dd class={ddClass}>
42
+ {#if children}{@render children()}{:else if hasValue}{value}{:else}{placeholder}{/if}
43
+ </dd>
44
+ {/snippet}
45
+
46
+ {#if visible}
47
+ {#if style().variant === 'card' || style().variant === 'bare'}
48
+ {@render pair()}
49
+ {:else if style().variant === 'inline'}
50
+ <div class="flex items-baseline gap-2">{@render pair()}</div>
51
+ {:else if style().variant === 'divided'}
52
+ <div class="flex flex-col gap-0.5 py-2 sm:flex-row sm:gap-4">{@render pair()}</div>
53
+ {:else}
54
+ <div class="flex flex-col gap-0.5">{@render pair()}</div>
55
+ {/if}
56
+ {/if}
@@ -0,0 +1,21 @@
1
+ import type { Snippet } from 'svelte';
2
+ interface Props {
3
+ /** The term, rendered as the `<dt>`. */
4
+ label: string;
5
+ /** The value as text. Ignored when `children` is given. */
6
+ value?: string | number | undefined;
7
+ /** The value as markup — a formatted date, a link, a badge. */
8
+ children?: Snippet<[]> | undefined;
9
+ /** Extra classes on the `<dd>`. */
10
+ valueClass?: string | undefined;
11
+ /** Extra classes on the `<dt>`. */
12
+ labelClass?: string | undefined;
13
+ /** Override the list's `showEmpty` for this row. */
14
+ showEmpty?: boolean | undefined;
15
+ /** Override the list's `emptyLabel` for this row. */
16
+ emptyLabel?: string | undefined;
17
+ }
18
+ /** One label and its value inside a `DescriptionList`. */
19
+ declare const DescriptionRow: import("svelte").Component<Props, {}, "">;
20
+ type DescriptionRow = ReturnType<typeof DescriptionRow>;
21
+ export default DescriptionRow;
@@ -0,0 +1,29 @@
1
+ <!-- @component
2
+ A word-level diff rendered inline: inserted runs in `<ins>`, deleted runs in `<del>`, unchanged runs plain.
3
+ -->
4
+ <!--
5
+ DiffText — a word-level diff rendered inline: inserted runs in `<ins>`,
6
+ deleted runs in `<del>`, unchanged runs plain.
7
+
8
+ ARIA contract: `<ins>` and `<del>` are the contract. They are what carries
9
+ "added" and "removed" into the accessibility tree and into a copy of the
10
+ page; the colour and the strike-through are the sighted reader's copy of
11
+ the same information, never the only copy. Support for announcing the two
12
+ elements is uneven across screen readers, so `insertLabel` / `deleteLabel`
13
+ add a visually hidden word before a run when the diff is the point of the
14
+ page rather than a detail on it — off by default, because a forty-segment
15
+ diff with a prefix on every run is unreadable.
16
+
17
+ `separator` sits BETWEEN segments rather than inside them: a word-level
18
+ diff needs the space and a character-level one must not have it, and only
19
+ the caller knows which it produced. That is also why the template below is
20
+ written without line breaks between the runs — a newline in the markup is a
21
+ space in the output, and it would make the choice for them.
22
+ -->
23
+ <script lang="ts">import VisuallyHidden from "../ui/VisuallyHidden.svelte";
24
+ let { segments, separator = " ", insertLabel, deleteLabel, class: className, ...rest } = $props();
25
+ </script>
26
+
27
+ {#snippet run(segment: DiffSegment)}{#if segment.kind === 'insert'}<ins class="bg-success/20 text-success-content decoration-success underline">{#if insertLabel !== undefined}<VisuallyHidden>{insertLabel}</VisuallyHidden>{/if}{segment.text}</ins>{:else if segment.kind === 'delete'}<del class="bg-error/20 text-error-content">{#if deleteLabel !== undefined}<VisuallyHidden>{deleteLabel}</VisuallyHidden>{/if}{segment.text}</del>{:else}{segment.text}{/if}{/snippet}
28
+
29
+ <p {...rest} class={['leading-7', className]}>{#each segments as segment, index (index)}{#if index > 0}{separator}{/if}{@render run(segment)}{/each}</p>
@@ -0,0 +1,19 @@
1
+ import type { HTMLAttributes } from 'svelte/elements';
2
+ import type { DiffSegment } from './diff.ts';
3
+ interface Props extends Omit<HTMLAttributes<HTMLParagraphElement>, 'children'> {
4
+ /** The diff, in reading order. */
5
+ segments: readonly DiffSegment[];
6
+ /**
7
+ * Rendered between segments — a space for a word-level diff.
8
+ * @defaultValue `' '`
9
+ */
10
+ separator?: string | undefined;
11
+ /** A visually hidden word before each inserted run. */
12
+ insertLabel?: string | undefined;
13
+ /** A visually hidden word before each deleted run. */
14
+ deleteLabel?: string | undefined;
15
+ }
16
+ /** A word-level diff rendered inline: inserted runs in `<ins>`, deleted runs in `<del>`, unchanged runs plain. */
17
+ declare const DiffText: import("svelte").Component<Props, {}, "">;
18
+ type DiffText = ReturnType<typeof DiffText>;
19
+ export default DiffText;
@@ -0,0 +1,80 @@
1
+ <!-- @component
2
+ A list in one of four shapes — `compact` links, `stacked` rows, a `grid` or `cards` — with an optional feed mode for windowed streams.
3
+ -->
4
+ <!--
5
+ ItemList — the list every index page and detail section renders, in the four
6
+ shapes those pages actually use: a `compact` run of links, `stacked` rows
7
+ divided by rules, a responsive `grid`, or a grid of `cards`.
8
+
9
+ The row body is the caller's, through the `item` snippet, because row shape
10
+ varies per resource type; what this owns is the container, the keying and
11
+ the empty state — so an empty list cannot be forgotten in one page out of
12
+ twenty.
13
+
14
+ ARIA contract, two modes:
15
+
16
+ - Default: a plain `<ul>` of `<li>`s. The list structure is the semantics —
17
+ a screen reader announces "list, 12 items" — and nothing is added to it.
18
+ - `feed`: the ARIA feed pattern, for a stream whose items load as the
19
+ reader scrolls. The container takes `role="feed"`, an accessible name from
20
+ `label`, and `aria-busy` while more is loading; each item is an `<article>`
21
+ carrying `aria-posinset` / `aria-setsize`, so "article 7 of 40" is
22
+ announced even though only 20 are in the DOM, and `tabindex="-1"` so the
23
+ reader's Page Down lands somewhere.
24
+
25
+ Feed mode renders `<div role="feed">` with `<article>` children rather
26
+ than a list, deliberately: `feed` is not a role HTML permits on `<ul>`,
27
+ and forcing `role="article"` onto each `<li>` would throw away the list
28
+ semantics to get there. A feed is not a list, and the markup says so.
29
+ -->
30
+ <script lang="ts" generics="T">let { items, variant = "compact", getKey, item, empty, emptyMessage = "Nothing here yet.", feed = false, label, busy = false, class: className, ...rest } = $props();
31
+ // Literal lookup tables: Tailwind only generates the classes it can read
32
+ // verbatim in the source, so these can never become template strings.
33
+ const containerClass = {
34
+ compact: "space-y-1",
35
+ stacked: "divide-base-300 divide-y",
36
+ grid: "grid grid-cols-1 gap-3 sm:grid-cols-2",
37
+ cards: "grid grid-cols-1 gap-4 sm:grid-cols-2"
38
+ };
39
+ const itemClass = {
40
+ compact: "",
41
+ stacked: "py-3",
42
+ grid: "",
43
+ cards: "card card-border bg-base-100 p-4 shadow-sm"
44
+ };
45
+ const setSize = $derived(items.length);
46
+ export {};
47
+ </script>
48
+
49
+ {#if items.length === 0}
50
+ {#if empty}
51
+ {@render empty()}
52
+ {:else}
53
+ <p class="text-base-content/70 text-sm leading-6">{emptyMessage}</p>
54
+ {/if}
55
+ {:else if feed}
56
+ <div
57
+ {...rest}
58
+ role="feed"
59
+ aria-label={label}
60
+ aria-busy={busy}
61
+ class={[containerClass[variant], className]}
62
+ >
63
+ {#each items as entry, index (getKey(entry, index))}
64
+ <article
65
+ aria-posinset={index + 1}
66
+ aria-setsize={setSize}
67
+ tabindex="-1"
68
+ class={itemClass[variant]}
69
+ >
70
+ {@render item(entry, index)}
71
+ </article>
72
+ {/each}
73
+ </div>
74
+ {:else}
75
+ <ul {...rest} aria-label={label} class={[containerClass[variant], className]}>
76
+ {#each items as entry, index (getKey(entry, index))}
77
+ <li class={itemClass[variant]}>{@render item(entry, index)}</li>
78
+ {/each}
79
+ </ul>
80
+ {/if}
@@ -0,0 +1,52 @@
1
+ import type { Snippet } from 'svelte';
2
+ import type { HTMLAttributes } from 'svelte/elements';
3
+ declare function $$render<T>(): {
4
+ props: Omit<HTMLAttributes<HTMLElement>, "children"> & {
5
+ /** The items, each rendered by the `item` snippet. */
6
+ items: readonly T[];
7
+ /**
8
+ * The layout.
9
+ * @defaultValue `'compact'`
10
+ */
11
+ variant?: ("grid" | "compact" | "stacked" | "cards") | undefined;
12
+ /** Stable identity per item — the `{#each}` key. */
13
+ getKey: (item: T, index: number) => string;
14
+ /** One row's body. */
15
+ item: Snippet<[T, number]>;
16
+ /** Rendered in place of the list when there is nothing in it. */
17
+ empty?: Snippet<[]> | undefined;
18
+ /**
19
+ * The line shown when there is nothing and no `empty` snippet.
20
+ * @defaultValue `'Nothing here yet.'`
21
+ */
22
+ emptyMessage?: string | undefined;
23
+ /** Render as an ARIA feed. */
24
+ feed?: boolean | undefined;
25
+ /** The feed's accessible name. Required in `feed` mode to name the region. */
26
+ label?: string | undefined;
27
+ /** More items are loading — `aria-busy` on the feed. */
28
+ busy?: boolean | undefined;
29
+ };
30
+ exports: {};
31
+ bindings: "";
32
+ slots: {};
33
+ events: {};
34
+ };
35
+ declare class __sveltets_Render<T> {
36
+ props(): ReturnType<typeof $$render<T>>['props'];
37
+ events(): ReturnType<typeof $$render<T>>['events'];
38
+ slots(): ReturnType<typeof $$render<T>>['slots'];
39
+ bindings(): "";
40
+ exports(): {};
41
+ }
42
+ interface $$IsomorphicComponent {
43
+ new <T>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<T>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<T>['props']>, ReturnType<__sveltets_Render<T>['events']>, ReturnType<__sveltets_Render<T>['slots']>> & {
44
+ $$bindings?: ReturnType<__sveltets_Render<T>['bindings']>;
45
+ } & ReturnType<__sveltets_Render<T>['exports']>;
46
+ <T>(internal: unknown, props: ReturnType<__sveltets_Render<T>['props']> & {}): ReturnType<__sveltets_Render<T>['exports']>;
47
+ z_$$bindings?: ReturnType<__sveltets_Render<any>['bindings']>;
48
+ }
49
+ /** A list in one of four shapes — `compact` links, `stacked` rows, a `grid` or `cards` — with an optional feed mode for windowed streams. */
50
+ declare const ItemList: $$IsomorphicComponent;
51
+ type ItemList<T> = InstanceType<typeof ItemList<T>>;
52
+ export default ItemList;
@@ -0,0 +1,46 @@
1
+ <!-- @component
2
+ The row body most lists want: a linked title, a line of context under it, and short badges.
3
+ -->
4
+ <!--
5
+ LinkListItem — the row body most lists want: a linked title, a line of
6
+ context under it, and short markers.
7
+
8
+ It renders the body only, never the `<li>` or the `<article>` around it,
9
+ because the container is `ItemList`'s decision (a list item in one mode, a
10
+ feed article in the other) and a component that rendered both would have to
11
+ know which.
12
+
13
+ ARIA contract: the title is a real link, resolved through the components
14
+ context, and it is the row's only interactive element — the subtitle and
15
+ the badges are text beside it, not a second target. `headingLevel` promotes
16
+ the title to a real heading for a list of sections a reader navigates by
17
+ headings; by default it is not one, because twenty `<h3>`s in a filter
18
+ result is worse for navigation than none.
19
+ -->
20
+ <script lang="ts">import Badge from "../ui/Badge.svelte";
21
+ import Link from "../ui/Link.svelte";
22
+ let { href, title, subtitle, badges, headingLevel, meta, class: className, ...rest } = $props();
23
+ </script>
24
+
25
+ <div {...rest} class={['flex flex-col gap-1', className]}>
26
+ {#if headingLevel === undefined}
27
+ <Link {href} variant="muted" class="font-medium">{title}</Link>
28
+ {:else}
29
+ <svelte:element this={`h${headingLevel}`} class="text-base font-medium">
30
+ <Link {href} variant="muted">{title}</Link>
31
+ </svelte:element>
32
+ {/if}
33
+ {#if subtitle !== undefined}
34
+ <p class="text-base-content/70 text-sm">{subtitle}</p>
35
+ {/if}
36
+ {#if meta}
37
+ <div class="text-base-content/60 text-sm">{@render meta()}</div>
38
+ {/if}
39
+ {#if badges !== undefined && badges.length > 0}
40
+ <div class="flex flex-wrap gap-1">
41
+ {#each badges as badge (badge)}
42
+ <Badge variant="outline" size="sm">{badge}</Badge>
43
+ {/each}
44
+ </div>
45
+ {/if}
46
+ </div>