@selvajs/ui 6.5.1-beta.1 → 6.6.0-beta.11

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 (444) hide show
  1. package/dist/components/ConfirmDialog.svelte +2 -10
  2. package/dist/components/ErrorScreen.svelte +21 -27
  3. package/dist/components/compute/AppLayout.svelte +286 -116
  4. package/dist/components/compute/AppLayout.svelte.d.ts +22 -0
  5. package/dist/components/compute/ComputeApp.svelte +45 -24
  6. package/dist/components/compute/ComputeApp.svelte.d.ts +19 -2
  7. package/dist/components/compute/ComputeMessagesDialog.svelte +47 -83
  8. package/dist/components/compute/ParameterPresetManager.svelte +37 -130
  9. package/dist/components/compute/ParameterPresetManager.svelte.d.ts +4 -5
  10. package/dist/components/compute/SolveMessages.svelte +131 -77
  11. package/dist/components/compute/SolveMessages.svelte.d.ts +7 -12
  12. package/dist/components/layout/AppShell.svelte +10 -6
  13. package/dist/components/layout/PageFooter.svelte +23 -11
  14. package/dist/components/layout/PageHeader.svelte +11 -7
  15. package/dist/components/layout/Pagination.svelte +2 -4
  16. package/dist/components/layout/SectionHeader.svelte +4 -2
  17. package/dist/components/layout/SideNav.svelte +56 -7
  18. package/dist/components/preview/ChartOutput.svelte +35 -25
  19. package/dist/components/preview/Group.svelte +92 -103
  20. package/dist/components/preview/Group.svelte.d.ts +1 -1
  21. package/dist/components/preview/HelpButton.svelte +36 -0
  22. package/dist/components/preview/HelpButton.svelte.d.ts +8 -0
  23. package/dist/components/preview/ImageOutput.svelte +430 -71
  24. package/dist/components/preview/InputControl.svelte +163 -90
  25. package/dist/components/preview/InputControl.svelte.d.ts +5 -1
  26. package/dist/components/preview/OutputDisplay.svelte +28 -33
  27. package/dist/components/preview/TabBar.svelte +106 -22
  28. package/dist/components/preview/TabBar.svelte.d.ts +1 -0
  29. package/dist/components/preview/TabContent.svelte +63 -57
  30. package/dist/components/preview/TabContent.svelte.d.ts +5 -1
  31. package/dist/components/preview/TabLayout.svelte +27 -5
  32. package/dist/components/preview/TabLayout.svelte.d.ts +5 -0
  33. package/dist/components/preview/inputs/CheckboxInput.svelte +7 -7
  34. package/dist/components/preview/inputs/CheckboxInput.svelte.d.ts +3 -0
  35. package/dist/components/preview/inputs/ChecklistInput.svelte +7 -2
  36. package/dist/components/preview/inputs/ChecklistInput.svelte.d.ts +2 -1
  37. package/dist/components/preview/inputs/ColorInput.svelte +4 -2
  38. package/dist/components/preview/inputs/ColorInput.svelte.d.ts +1 -0
  39. package/dist/components/preview/inputs/DropdownInput.svelte +19 -4
  40. package/dist/components/preview/inputs/DropdownInput.svelte.d.ts +2 -1
  41. package/dist/components/preview/inputs/FileInput.svelte +112 -108
  42. package/dist/components/preview/inputs/GeometryInput.svelte +128 -0
  43. package/dist/components/preview/inputs/GeometryInput.svelte.d.ts +21 -0
  44. package/dist/components/preview/inputs/NumberInput.svelte +123 -61
  45. package/dist/components/preview/inputs/NumberInput.svelte.d.ts +2 -0
  46. package/dist/components/preview/inputs/OptionGlyph.svelte +29 -0
  47. package/dist/components/preview/inputs/OptionGlyph.svelte.d.ts +8 -0
  48. package/dist/components/preview/inputs/SegmentedInput.svelte +44 -0
  49. package/dist/components/preview/inputs/SegmentedInput.svelte.d.ts +12 -0
  50. package/dist/components/preview/inputs/TextInput.svelte +8 -4
  51. package/dist/components/preview/inputs/TileInput.svelte +80 -0
  52. package/dist/components/preview/inputs/TileInput.svelte.d.ts +12 -0
  53. package/dist/components/preview/inputs/index.d.ts +3 -0
  54. package/dist/components/preview/inputs/index.js +3 -0
  55. package/dist/components/primitives/CalculateButton.svelte +56 -24
  56. package/dist/components/primitives/CalculateButton.svelte.d.ts +3 -0
  57. package/dist/components/primitives/Callout.svelte +11 -18
  58. package/dist/components/primitives/DataTable.svelte +38 -5
  59. package/dist/components/primitives/DataTable.svelte.d.ts +2 -0
  60. package/dist/components/primitives/FilterableDropdown.svelte +42 -129
  61. package/dist/components/primitives/FilterableDropdown.svelte.d.ts +1 -1
  62. package/dist/components/primitives/IssueList.svelte +56 -0
  63. package/dist/components/primitives/IssueList.svelte.d.ts +20 -0
  64. package/dist/components/primitives/SeverityIcon.svelte +15 -0
  65. package/dist/components/primitives/SeverityIcon.svelte.d.ts +8 -0
  66. package/dist/components/primitives/SolvingIndicator.svelte +43 -42
  67. package/dist/components/primitives/SolvingIndicator.svelte.d.ts +6 -0
  68. package/dist/components/primitives/StateDisplay.svelte +19 -79
  69. package/dist/components/primitives/ViewToggle.svelte +18 -33
  70. package/dist/components/primitives/alert-dialog/alert-dialog-action.svelte +9 -3
  71. package/dist/components/primitives/alert-dialog/alert-dialog-action.svelte.d.ts +6 -1
  72. package/dist/components/primitives/alert-dialog/alert-dialog-content.svelte +1 -1
  73. package/dist/components/primitives/alert-dialog/alert-dialog-overlay.svelte +1 -1
  74. package/dist/components/primitives/badge/badge.svelte +2 -2
  75. package/dist/components/primitives/badge/badge.svelte.d.ts +4 -4
  76. package/dist/components/primitives/button/button.svelte +6 -2
  77. package/dist/components/primitives/button/button.svelte.d.ts +10 -4
  78. package/dist/components/primitives/card/card-header.svelte +1 -1
  79. package/dist/components/primitives/card/card.svelte +21 -5
  80. package/dist/components/primitives/card/card.svelte.d.ts +25 -1
  81. package/dist/components/primitives/card/index.d.ts +1 -2
  82. package/dist/components/primitives/card/index.js +2 -3
  83. package/dist/components/primitives/checkbox/checkbox.svelte +1 -1
  84. package/dist/components/primitives/command/command-dialog.svelte +42 -0
  85. package/dist/components/primitives/command/command-dialog.svelte.d.ts +14 -0
  86. package/dist/components/primitives/command/command-empty.svelte +17 -0
  87. package/dist/components/primitives/command/command-empty.svelte.d.ts +4 -0
  88. package/dist/components/primitives/command/command-group.svelte +33 -0
  89. package/dist/components/primitives/command/command-group.svelte.d.ts +7 -0
  90. package/dist/components/primitives/command/command-input.svelte +36 -0
  91. package/dist/components/primitives/command/command-input.svelte.d.ts +4 -0
  92. package/dist/components/primitives/command/command-item.svelte +28 -0
  93. package/dist/components/primitives/command/command-item.svelte.d.ts +4 -0
  94. package/dist/components/primitives/command/command-link-item.svelte +21 -0
  95. package/dist/components/primitives/command/command-link-item.svelte.d.ts +4 -0
  96. package/dist/components/primitives/command/command-list.svelte +20 -0
  97. package/dist/components/primitives/command/command-list.svelte.d.ts +4 -0
  98. package/dist/components/primitives/command/command-loading.svelte +7 -0
  99. package/dist/components/primitives/command/command-loading.svelte.d.ts +4 -0
  100. package/dist/components/primitives/command/command-separator.svelte +17 -0
  101. package/dist/components/primitives/command/command-separator.svelte.d.ts +4 -0
  102. package/dist/components/primitives/command/command-shortcut.svelte +23 -0
  103. package/dist/components/primitives/command/command-shortcut.svelte.d.ts +5 -0
  104. package/dist/components/primitives/command/command.svelte +28 -0
  105. package/dist/components/primitives/command/command.svelte.d.ts +8 -0
  106. package/dist/components/primitives/command/index.d.ts +12 -0
  107. package/dist/components/primitives/command/index.js +14 -0
  108. package/dist/components/primitives/context-menu/context-menu-content.svelte +1 -1
  109. package/dist/components/primitives/context-menu/context-menu-sub-content.svelte +1 -1
  110. package/dist/components/primitives/dialog/dialog-content.svelte +11 -3
  111. package/dist/components/primitives/dialog/dialog-content.svelte.d.ts +2 -0
  112. package/dist/components/primitives/dialog/dialog-overlay.svelte +1 -1
  113. package/dist/components/primitives/dialog/dialog-title.svelte +6 -2
  114. package/dist/components/primitives/dialog/dialog-title.svelte.d.ts +5 -1
  115. package/dist/components/primitives/drawer/Drawer.svelte +2 -2
  116. package/dist/components/primitives/dropdown-menu/dropdown-menu-checkbox-group.svelte +16 -0
  117. package/dist/components/primitives/dropdown-menu/dropdown-menu-checkbox-group.svelte.d.ts +4 -0
  118. package/dist/components/primitives/dropdown-menu/dropdown-menu-checkbox-item.svelte +46 -0
  119. package/dist/components/primitives/dropdown-menu/dropdown-menu-checkbox-item.svelte.d.ts +9 -0
  120. package/dist/components/primitives/dropdown-menu/dropdown-menu-content.svelte +31 -0
  121. package/dist/components/primitives/dropdown-menu/dropdown-menu-content.svelte.d.ts +10 -0
  122. package/dist/components/primitives/dropdown-menu/dropdown-menu-group-heading.svelte +22 -0
  123. package/dist/components/primitives/dropdown-menu/dropdown-menu-group-heading.svelte.d.ts +8 -0
  124. package/dist/components/primitives/dropdown-menu/dropdown-menu-group.svelte +7 -0
  125. package/dist/components/primitives/dropdown-menu/dropdown-menu-group.svelte.d.ts +4 -0
  126. package/dist/components/primitives/dropdown-menu/dropdown-menu-item.svelte +27 -0
  127. package/dist/components/primitives/dropdown-menu/dropdown-menu-item.svelte.d.ts +8 -0
  128. package/dist/components/primitives/dropdown-menu/dropdown-menu-label.svelte +24 -0
  129. package/dist/components/primitives/dropdown-menu/dropdown-menu-label.svelte.d.ts +8 -0
  130. package/dist/components/primitives/dropdown-menu/dropdown-menu-portal.svelte +7 -0
  131. package/dist/components/primitives/dropdown-menu/dropdown-menu-portal.svelte.d.ts +3 -0
  132. package/dist/components/primitives/dropdown-menu/dropdown-menu-radio-group.svelte +16 -0
  133. package/dist/components/primitives/dropdown-menu/dropdown-menu-radio-group.svelte.d.ts +4 -0
  134. package/dist/components/primitives/dropdown-menu/dropdown-menu-radio-item.svelte +36 -0
  135. package/dist/components/primitives/dropdown-menu/dropdown-menu-radio-item.svelte.d.ts +4 -0
  136. package/dist/components/primitives/dropdown-menu/dropdown-menu-separator.svelte +17 -0
  137. package/dist/components/primitives/dropdown-menu/dropdown-menu-separator.svelte.d.ts +4 -0
  138. package/dist/components/primitives/dropdown-menu/dropdown-menu-shortcut.svelte +23 -0
  139. package/dist/components/primitives/dropdown-menu/dropdown-menu-shortcut.svelte.d.ts +5 -0
  140. package/dist/components/primitives/dropdown-menu/dropdown-menu-sub-content.svelte +31 -0
  141. package/dist/components/primitives/dropdown-menu/dropdown-menu-sub-content.svelte.d.ts +10 -0
  142. package/dist/components/primitives/dropdown-menu/dropdown-menu-sub-trigger.svelte +29 -0
  143. package/dist/components/primitives/dropdown-menu/dropdown-menu-sub-trigger.svelte.d.ts +7 -0
  144. package/dist/components/primitives/dropdown-menu/dropdown-menu-sub.svelte +7 -0
  145. package/dist/components/primitives/dropdown-menu/dropdown-menu-sub.svelte.d.ts +3 -0
  146. package/dist/components/primitives/dropdown-menu/dropdown-menu-trigger.svelte +7 -0
  147. package/dist/components/primitives/dropdown-menu/dropdown-menu-trigger.svelte.d.ts +4 -0
  148. package/dist/components/primitives/dropdown-menu/dropdown-menu.svelte +7 -0
  149. package/dist/components/primitives/dropdown-menu/dropdown-menu.svelte.d.ts +3 -0
  150. package/dist/components/primitives/dropdown-menu/index.d.ts +18 -0
  151. package/dist/components/primitives/dropdown-menu/index.js +18 -0
  152. package/dist/components/primitives/{alert/alert-description.svelte → empty/empty-content.svelte} +3 -3
  153. package/dist/components/primitives/empty/empty-content.svelte.d.ts +5 -0
  154. package/dist/components/primitives/empty/empty-description.svelte +23 -0
  155. package/dist/components/primitives/{alert/alert-description.svelte.d.ts → empty/empty-description.svelte.d.ts} +4 -4
  156. package/dist/components/primitives/{alert/alert-title.svelte → empty/empty-header.svelte} +3 -3
  157. package/dist/components/primitives/empty/empty-header.svelte.d.ts +5 -0
  158. package/dist/components/primitives/empty/empty-media.svelte +41 -0
  159. package/dist/components/primitives/empty/empty-media.svelte.d.ts +26 -0
  160. package/dist/components/primitives/{card/card-action.svelte → empty/empty-title.svelte} +2 -2
  161. package/dist/components/primitives/{card/card-action.svelte.d.ts → empty/empty-title.svelte.d.ts} +3 -3
  162. package/dist/components/primitives/empty/empty.svelte +23 -0
  163. package/dist/components/primitives/empty/empty.svelte.d.ts +5 -0
  164. package/dist/components/primitives/empty/index.d.ts +7 -0
  165. package/dist/components/primitives/empty/index.js +9 -0
  166. package/dist/components/primitives/index.d.ts +10 -1
  167. package/dist/components/primitives/index.js +10 -1
  168. package/dist/components/primitives/input/input.svelte +4 -4
  169. package/dist/components/primitives/input-group/index.d.ts +7 -0
  170. package/dist/components/primitives/input-group/index.js +9 -0
  171. package/dist/components/primitives/input-group/input-group-addon.svelte +53 -0
  172. package/dist/components/primitives/input-group/input-group-addon.svelte.d.ts +32 -0
  173. package/dist/components/primitives/input-group/input-group-button.svelte +49 -0
  174. package/dist/components/primitives/input-group/input-group-button.svelte.d.ts +32 -0
  175. package/dist/components/primitives/input-group/input-group-input.svelte +25 -0
  176. package/dist/components/primitives/input-group/input-group-input.svelte.d.ts +11 -0
  177. package/dist/components/primitives/input-group/input-group-text.svelte +22 -0
  178. package/dist/components/primitives/input-group/input-group-text.svelte.d.ts +5 -0
  179. package/dist/components/primitives/input-group/input-group-textarea.svelte +23 -0
  180. package/dist/components/primitives/input-group/input-group-textarea.svelte.d.ts +3 -0
  181. package/dist/components/primitives/input-group/input-group.svelte +24 -0
  182. package/dist/components/primitives/{alert/alert-title.svelte.d.ts → input-group/input-group.svelte.d.ts} +4 -4
  183. package/dist/components/primitives/mode-toggle/mode-toggle.svelte +6 -7
  184. package/dist/components/primitives/popover/index.d.ts +9 -0
  185. package/dist/components/primitives/popover/index.js +11 -0
  186. package/dist/components/primitives/popover/popover-close.svelte +7 -0
  187. package/dist/components/primitives/popover/popover-close.svelte.d.ts +4 -0
  188. package/dist/components/primitives/popover/popover-content.svelte +31 -0
  189. package/dist/components/primitives/popover/popover-content.svelte.d.ts +10 -0
  190. package/dist/components/primitives/popover/popover-description.svelte +20 -0
  191. package/dist/components/primitives/popover/popover-description.svelte.d.ts +5 -0
  192. package/dist/components/primitives/popover/popover-header.svelte +20 -0
  193. package/dist/components/primitives/popover/popover-header.svelte.d.ts +5 -0
  194. package/dist/components/primitives/popover/popover-portal.svelte +7 -0
  195. package/dist/components/primitives/popover/popover-portal.svelte.d.ts +3 -0
  196. package/dist/components/primitives/popover/popover-title.svelte +15 -0
  197. package/dist/components/primitives/popover/popover-title.svelte.d.ts +5 -0
  198. package/dist/components/primitives/popover/popover-trigger.svelte +17 -0
  199. package/dist/components/primitives/popover/popover-trigger.svelte.d.ts +4 -0
  200. package/dist/components/primitives/popover/popover.svelte +7 -0
  201. package/dist/components/primitives/popover/popover.svelte.d.ts +3 -0
  202. package/dist/components/primitives/resizable/resizable-handle.svelte +6 -2
  203. package/dist/components/primitives/resizable/resizable-handle.svelte.d.ts +2 -0
  204. package/dist/components/primitives/resizable/resizable-pane-group.svelte +1 -4
  205. package/dist/components/primitives/scroll-area/scroll-area.svelte +1 -1
  206. package/dist/components/primitives/search/search.svelte +3 -3
  207. package/dist/components/primitives/select/select-content.svelte +1 -1
  208. package/dist/components/primitives/select/select-trigger.svelte +1 -1
  209. package/dist/components/primitives/severity.d.ts +7 -0
  210. package/dist/components/primitives/severity.js +19 -0
  211. package/dist/components/primitives/slider/slider.svelte +8 -3
  212. package/dist/components/primitives/slider/slider.svelte.d.ts +5 -1
  213. package/dist/components/primitives/sonner/sonner.svelte +1 -1
  214. package/dist/components/primitives/spinner/index.d.ts +1 -0
  215. package/dist/components/primitives/spinner/index.js +1 -0
  216. package/dist/components/primitives/spinner/spinner.svelte +29 -0
  217. package/dist/components/primitives/spinner/spinner.svelte.d.ts +4 -0
  218. package/dist/components/primitives/switch/switch.svelte +2 -2
  219. package/dist/components/primitives/tabs/tabs-list.svelte +27 -5
  220. package/dist/components/primitives/tabs/tabs-list.svelte.d.ts +22 -1
  221. package/dist/components/primitives/tabs/tabs-trigger.svelte +23 -5
  222. package/dist/components/primitives/tabs/tabs-trigger.svelte.d.ts +22 -1
  223. package/dist/components/primitives/tabs/tabs.svelte +6 -2
  224. package/dist/components/primitives/tabs/tabs.svelte.d.ts +5 -1
  225. package/dist/components/primitives/textarea/textarea.svelte +1 -1
  226. package/dist/components/primitives/theme-switcher/ThemeSwitcher.svelte +1 -1
  227. package/dist/components/primitives/toggle/index.d.ts +3 -0
  228. package/dist/components/primitives/toggle/index.js +5 -0
  229. package/dist/components/primitives/toggle/toggle.svelte +54 -0
  230. package/dist/components/primitives/toggle/toggle.svelte.d.ts +46 -0
  231. package/dist/components/primitives/toggle-group/index.d.ts +3 -0
  232. package/dist/components/primitives/toggle-group/index.js +5 -0
  233. package/dist/components/primitives/toggle-group/toggle-group-item.svelte +35 -0
  234. package/dist/components/primitives/toggle-group/toggle-group-item.svelte.d.ts +6 -0
  235. package/dist/components/primitives/toggle-group/toggle-group.svelte +75 -0
  236. package/dist/components/primitives/toggle-group/toggle-group.svelte.d.ts +17 -0
  237. package/dist/components/viewer/MeshMetadataPanel.svelte +119 -0
  238. package/dist/components/viewer/MeshMetadataPanel.svelte.d.ts +9 -0
  239. package/dist/components/viewer/SceneManager.svelte +14 -5
  240. package/dist/components/viewer/Viewer.svelte +243 -221
  241. package/dist/components/viewer/Viewer.svelte.d.ts +3 -0
  242. package/dist/compute/run-panel-action.d.ts +8 -0
  243. package/dist/compute/run-panel-action.js +12 -0
  244. package/dist/compute/solving.svelte.d.ts +11 -7
  245. package/dist/compute/solving.svelte.js +64 -45
  246. package/dist/compute/useSolveSession.svelte.js +3 -0
  247. package/dist/constants.d.ts +6 -8
  248. package/dist/constants.js +7 -9
  249. package/dist/contexts/hostContext.svelte.d.ts +39 -0
  250. package/dist/contexts/hostContext.svelte.js +9 -0
  251. package/dist/i18n/localeContext.svelte.d.ts +10 -3
  252. package/dist/i18n/localeContext.svelte.js +27 -5
  253. package/dist/i18n/messages.d.ts +150 -2
  254. package/dist/i18n/messages.js +261 -11
  255. package/dist/index.d.ts +4 -1
  256. package/dist/index.js +3 -0
  257. package/dist/public.d.ts +1 -1
  258. package/dist/schema/host-support.d.ts +29 -0
  259. package/dist/schema/host-support.js +97 -0
  260. package/dist/schema/option-display.d.ts +12 -0
  261. package/dist/schema/option-display.js +29 -0
  262. package/dist/schema/param-exporter.d.ts +4 -1
  263. package/dist/schema/param-exporter.js +10 -6
  264. package/dist/schema/visibility-rules.js +21 -0
  265. package/dist/styles/base.css +80 -10
  266. package/dist/types/actionButton.d.ts +17 -3
  267. package/dist/types/presetLabels.d.ts +3 -2
  268. package/dist/types/presetLabels.js +9 -8
  269. package/dist/utils/file-download.js +10 -22
  270. package/dist/utils/host-files.d.ts +12 -0
  271. package/dist/utils/host-files.js +46 -0
  272. package/dist/utils/loadScript.d.ts +2 -0
  273. package/dist/utils/loadScript.js +2 -0
  274. package/dist/utils/webp-to-png.d.ts +10 -0
  275. package/dist/utils/webp-to-png.js +41 -0
  276. package/package.json +14 -14
  277. package/src/lib/components/ConfirmDialog.svelte +2 -10
  278. package/src/lib/components/ErrorScreen.svelte +21 -27
  279. package/src/lib/components/compute/AppLayout.svelte +286 -116
  280. package/src/lib/components/compute/ComputeApp.svelte +45 -24
  281. package/src/lib/components/compute/ComputeMessagesDialog.svelte +47 -83
  282. package/src/lib/components/compute/ParameterPresetManager.svelte +37 -130
  283. package/src/lib/components/compute/SolveMessages.svelte +131 -77
  284. package/src/lib/components/layout/AppShell.svelte +10 -6
  285. package/src/lib/components/layout/PageFooter.svelte +23 -11
  286. package/src/lib/components/layout/PageHeader.svelte +11 -7
  287. package/src/lib/components/layout/Pagination.svelte +2 -4
  288. package/src/lib/components/layout/SectionHeader.svelte +4 -2
  289. package/src/lib/components/layout/SideNav.svelte +56 -7
  290. package/src/lib/components/preview/ChartOutput.svelte +35 -25
  291. package/src/lib/components/preview/Group.svelte +92 -103
  292. package/src/lib/components/preview/HelpButton.svelte +36 -0
  293. package/src/lib/components/preview/ImageOutput.svelte +430 -71
  294. package/src/lib/components/preview/InputControl.svelte +163 -90
  295. package/src/lib/components/preview/OutputDisplay.svelte +28 -33
  296. package/src/lib/components/preview/TabBar.svelte +106 -22
  297. package/src/lib/components/preview/TabContent.svelte +63 -57
  298. package/src/lib/components/preview/TabLayout.svelte +27 -5
  299. package/src/lib/components/preview/inputs/CheckboxInput.svelte +7 -7
  300. package/src/lib/components/preview/inputs/ChecklistInput.svelte +7 -2
  301. package/src/lib/components/preview/inputs/ColorInput.svelte +4 -2
  302. package/src/lib/components/preview/inputs/DropdownInput.svelte +19 -4
  303. package/src/lib/components/preview/inputs/FileInput.svelte +112 -108
  304. package/src/lib/components/preview/inputs/GeometryInput.svelte +128 -0
  305. package/src/lib/components/preview/inputs/NumberInput.svelte +123 -61
  306. package/src/lib/components/preview/inputs/OptionGlyph.svelte +29 -0
  307. package/src/lib/components/preview/inputs/SegmentedInput.svelte +44 -0
  308. package/src/lib/components/preview/inputs/TextInput.svelte +8 -4
  309. package/src/lib/components/preview/inputs/TileInput.svelte +80 -0
  310. package/src/lib/components/preview/inputs/index.ts +3 -0
  311. package/src/lib/components/primitives/CalculateButton.svelte +56 -24
  312. package/src/lib/components/primitives/Callout.svelte +11 -18
  313. package/src/lib/components/primitives/DataTable.svelte +38 -5
  314. package/src/lib/components/primitives/FilterableDropdown.svelte +42 -129
  315. package/src/lib/components/primitives/IssueList.svelte +56 -0
  316. package/src/lib/components/primitives/SeverityIcon.svelte +15 -0
  317. package/src/lib/components/primitives/SolvingIndicator.svelte +43 -42
  318. package/src/lib/components/primitives/StateDisplay.svelte +19 -79
  319. package/src/lib/components/primitives/ViewToggle.svelte +18 -33
  320. package/src/lib/components/primitives/alert-dialog/alert-dialog-action.svelte +9 -3
  321. package/src/lib/components/primitives/alert-dialog/alert-dialog-content.svelte +1 -1
  322. package/src/lib/components/primitives/alert-dialog/alert-dialog-overlay.svelte +1 -1
  323. package/src/lib/components/primitives/badge/badge.svelte +2 -2
  324. package/src/lib/components/primitives/button/button.svelte +6 -2
  325. package/src/lib/components/primitives/card/card-header.svelte +1 -1
  326. package/src/lib/components/primitives/card/card.svelte +21 -5
  327. package/src/lib/components/primitives/card/index.ts +1 -4
  328. package/src/lib/components/primitives/checkbox/checkbox.svelte +1 -1
  329. package/src/lib/components/primitives/command/command-dialog.svelte +42 -0
  330. package/src/lib/components/primitives/command/command-empty.svelte +17 -0
  331. package/src/lib/components/primitives/command/command-group.svelte +33 -0
  332. package/src/lib/components/primitives/command/command-input.svelte +36 -0
  333. package/src/lib/components/primitives/command/command-item.svelte +28 -0
  334. package/src/lib/components/primitives/command/command-link-item.svelte +21 -0
  335. package/src/lib/components/primitives/command/command-list.svelte +20 -0
  336. package/src/lib/components/primitives/command/command-loading.svelte +7 -0
  337. package/src/lib/components/primitives/command/command-separator.svelte +17 -0
  338. package/src/lib/components/primitives/command/command-shortcut.svelte +23 -0
  339. package/src/lib/components/primitives/command/command.svelte +28 -0
  340. package/src/lib/components/primitives/command/index.ts +37 -0
  341. package/src/lib/components/primitives/context-menu/context-menu-content.svelte +1 -1
  342. package/src/lib/components/primitives/context-menu/context-menu-sub-content.svelte +1 -1
  343. package/src/lib/components/primitives/dialog/dialog-content.svelte +11 -3
  344. package/src/lib/components/primitives/dialog/dialog-overlay.svelte +1 -1
  345. package/src/lib/components/primitives/dialog/dialog-title.svelte +6 -2
  346. package/src/lib/components/primitives/drawer/Drawer.svelte +2 -2
  347. package/src/lib/components/primitives/dropdown-menu/dropdown-menu-checkbox-group.svelte +16 -0
  348. package/src/lib/components/primitives/dropdown-menu/dropdown-menu-checkbox-item.svelte +46 -0
  349. package/src/lib/components/primitives/dropdown-menu/dropdown-menu-content.svelte +31 -0
  350. package/src/lib/components/primitives/dropdown-menu/dropdown-menu-group-heading.svelte +22 -0
  351. package/src/lib/components/primitives/dropdown-menu/dropdown-menu-group.svelte +7 -0
  352. package/src/lib/components/primitives/dropdown-menu/dropdown-menu-item.svelte +27 -0
  353. package/src/lib/components/primitives/dropdown-menu/dropdown-menu-label.svelte +24 -0
  354. package/src/lib/components/primitives/dropdown-menu/dropdown-menu-portal.svelte +7 -0
  355. package/src/lib/components/primitives/dropdown-menu/dropdown-menu-radio-group.svelte +16 -0
  356. package/src/lib/components/primitives/dropdown-menu/dropdown-menu-radio-item.svelte +36 -0
  357. package/src/lib/components/primitives/dropdown-menu/dropdown-menu-separator.svelte +17 -0
  358. package/src/lib/components/primitives/dropdown-menu/dropdown-menu-shortcut.svelte +23 -0
  359. package/src/lib/components/primitives/dropdown-menu/dropdown-menu-sub-content.svelte +31 -0
  360. package/src/lib/components/primitives/dropdown-menu/dropdown-menu-sub-trigger.svelte +29 -0
  361. package/src/lib/components/primitives/dropdown-menu/dropdown-menu-sub.svelte +7 -0
  362. package/src/lib/components/primitives/dropdown-menu/dropdown-menu-trigger.svelte +7 -0
  363. package/src/lib/components/primitives/dropdown-menu/dropdown-menu.svelte +7 -0
  364. package/src/lib/components/primitives/dropdown-menu/index.ts +54 -0
  365. package/src/lib/components/primitives/{alert/alert-description.svelte → empty/empty-content.svelte} +3 -3
  366. package/src/lib/components/primitives/empty/empty-description.svelte +23 -0
  367. package/src/lib/components/primitives/{alert/alert-title.svelte → empty/empty-header.svelte} +3 -3
  368. package/src/lib/components/primitives/empty/empty-media.svelte +41 -0
  369. package/src/lib/components/primitives/{card/card-action.svelte → empty/empty-title.svelte} +2 -2
  370. package/src/lib/components/primitives/empty/empty.svelte +23 -0
  371. package/src/lib/components/primitives/empty/index.ts +22 -0
  372. package/src/lib/components/primitives/index.ts +10 -1
  373. package/src/lib/components/primitives/input/input.svelte +4 -4
  374. package/src/lib/components/primitives/input-group/index.ts +22 -0
  375. package/src/lib/components/primitives/input-group/input-group-addon.svelte +53 -0
  376. package/src/lib/components/primitives/input-group/input-group-button.svelte +49 -0
  377. package/src/lib/components/primitives/input-group/input-group-input.svelte +25 -0
  378. package/src/lib/components/primitives/input-group/input-group-text.svelte +22 -0
  379. package/src/lib/components/primitives/input-group/input-group-textarea.svelte +23 -0
  380. package/src/lib/components/primitives/input-group/input-group.svelte +24 -0
  381. package/src/lib/components/primitives/mode-toggle/mode-toggle.svelte +6 -7
  382. package/src/lib/components/primitives/popover/index.ts +28 -0
  383. package/src/lib/components/primitives/popover/popover-close.svelte +7 -0
  384. package/src/lib/components/primitives/popover/popover-content.svelte +31 -0
  385. package/src/lib/components/primitives/popover/popover-description.svelte +20 -0
  386. package/src/lib/components/primitives/popover/popover-header.svelte +20 -0
  387. package/src/lib/components/primitives/popover/popover-portal.svelte +7 -0
  388. package/src/lib/components/primitives/popover/popover-title.svelte +15 -0
  389. package/src/lib/components/primitives/popover/popover-trigger.svelte +17 -0
  390. package/src/lib/components/primitives/popover/popover.svelte +7 -0
  391. package/src/lib/components/primitives/resizable/resizable-handle.svelte +6 -2
  392. package/src/lib/components/primitives/resizable/resizable-pane-group.svelte +1 -4
  393. package/src/lib/components/primitives/scroll-area/scroll-area.svelte +1 -1
  394. package/src/lib/components/primitives/search/search.svelte +3 -3
  395. package/src/lib/components/primitives/select/select-content.svelte +1 -1
  396. package/src/lib/components/primitives/select/select-trigger.svelte +1 -1
  397. package/src/lib/components/primitives/severity.ts +26 -0
  398. package/src/lib/components/primitives/slider/slider.svelte +8 -3
  399. package/src/lib/components/primitives/sonner/sonner.svelte +1 -1
  400. package/src/lib/components/primitives/spinner/index.ts +1 -0
  401. package/src/lib/components/primitives/spinner/spinner.svelte +29 -0
  402. package/src/lib/components/primitives/switch/switch.svelte +2 -2
  403. package/src/lib/components/primitives/tabs/tabs-list.svelte +27 -5
  404. package/src/lib/components/primitives/tabs/tabs-trigger.svelte +23 -5
  405. package/src/lib/components/primitives/tabs/tabs.svelte +6 -2
  406. package/src/lib/components/primitives/textarea/textarea.svelte +1 -1
  407. package/src/lib/components/primitives/theme-switcher/ThemeSwitcher.svelte +1 -1
  408. package/src/lib/components/primitives/toggle/index.ts +13 -0
  409. package/src/lib/components/primitives/toggle/toggle.svelte +54 -0
  410. package/src/lib/components/primitives/toggle-group/index.ts +10 -0
  411. package/src/lib/components/primitives/toggle-group/toggle-group-item.svelte +35 -0
  412. package/src/lib/components/primitives/toggle-group/toggle-group.svelte +75 -0
  413. package/src/lib/components/viewer/MeshMetadataPanel.svelte +119 -0
  414. package/src/lib/components/viewer/SceneManager.svelte +14 -5
  415. package/src/lib/components/viewer/Viewer.svelte +243 -221
  416. package/src/lib/compute/run-panel-action.ts +16 -0
  417. package/src/lib/compute/solving.svelte.ts +66 -50
  418. package/src/lib/compute/useSolveSession.svelte.ts +3 -0
  419. package/src/lib/constants.ts +7 -9
  420. package/src/lib/contexts/hostContext.svelte.ts +51 -0
  421. package/src/lib/i18n/localeContext.svelte.ts +40 -5
  422. package/src/lib/i18n/messages.ts +453 -13
  423. package/src/lib/index.ts +21 -0
  424. package/src/lib/public.ts +1 -0
  425. package/src/lib/schema/host-support.ts +129 -0
  426. package/src/lib/schema/option-display.ts +44 -0
  427. package/src/lib/schema/param-exporter.ts +10 -7
  428. package/src/lib/schema/visibility-rules.ts +23 -0
  429. package/src/lib/styles/base.css +80 -10
  430. package/src/lib/types/actionButton.ts +16 -3
  431. package/src/lib/types/presetLabels.ts +13 -11
  432. package/src/lib/utils/file-download.ts +11 -21
  433. package/src/lib/utils/host-files.ts +61 -0
  434. package/src/lib/utils/loadScript.ts +3 -0
  435. package/src/lib/utils/webp-to-png.ts +48 -0
  436. package/dist/components/primitives/alert/alert.svelte +0 -44
  437. package/dist/components/primitives/alert/alert.svelte.d.ts +0 -26
  438. package/dist/components/primitives/alert/index.d.ts +0 -5
  439. package/dist/components/primitives/alert/index.js +0 -7
  440. package/dist/components/viewer/MeshMetadataDialog.svelte +0 -126
  441. package/dist/components/viewer/MeshMetadataDialog.svelte.d.ts +0 -10
  442. package/src/lib/components/primitives/alert/alert.svelte +0 -44
  443. package/src/lib/components/primitives/alert/index.ts +0 -14
  444. package/src/lib/components/viewer/MeshMetadataDialog.svelte +0 -126
@@ -3,6 +3,8 @@
3
3
  label: string;
4
4
  width?: string;
5
5
  align?: 'left' | 'right';
6
+ /** Drop the column below 640px, where fixed widths would crush the flexible one. */
7
+ hideOnMobile?: boolean;
6
8
  }
7
9
  </script>
8
10
 
@@ -19,21 +21,52 @@
19
21
 
20
22
  let { rows, columns, getKey, row, class: className = '' }: Props = $props();
21
23
 
22
- const gridTemplate = $derived(columns.map((c) => c.width ?? '1fr').join(' '));
24
+ // `minmax(0, …)` so a long name truncates rather than widening its row past the others.
25
+ const toTemplate = (cols: DataTableColumn[]) =>
26
+ cols.map((c) => c.width ?? 'minmax(0, 1fr)').join(' ');
27
+ const gridTemplate = $derived(toTemplate(columns));
28
+ const mobileTemplate = $derived(toTemplate(columns.filter((c) => !c.hideOnMobile)));
29
+ // Cells come from the caller's snippet, so they're hidden by position.
30
+ const hiddenCols = $derived(
31
+ columns
32
+ .map((c, i) => (c.hideOnMobile ? `hide-col-${i + 1}` : ''))
33
+ .filter(Boolean)
34
+ .join(' ')
35
+ );
23
36
  </script>
24
37
 
25
- <div class={`divide-y rounded-lg border ${className}`}>
38
+ <div
39
+ class={`divide-y rounded-lg border ${className}`}
40
+ style:--table-cols={gridTemplate}
41
+ style:--table-cols-sm={mobileTemplate}
42
+ >
26
43
  <div
27
- class="gap-4 px-4 py-2 text-xs font-medium tracking-wide grid bg-muted/40 text-muted-foreground uppercase"
28
- style:grid-template-columns={gridTemplate}
44
+ class="data-table-row gap-4 px-4 py-2 text-xs font-medium tracking-wide sm:grid-cols-(--table-cols) grid grid-cols-(--table-cols-sm) bg-muted/40 text-muted-foreground uppercase {hiddenCols}"
29
45
  >
30
46
  {#each columns as col (col.label)}
31
47
  <span class={col.align === 'right' ? 'text-right' : ''}>{col.label}</span>
32
48
  {/each}
33
49
  </div>
34
50
  {#each rows as item (getKey(item))}
35
- <div class="gap-4 px-4 py-3 grid items-center" style:grid-template-columns={gridTemplate}>
51
+ <div
52
+ class="data-table-row gap-4 px-4 py-3 sm:grid-cols-(--table-cols) grid grid-cols-(--table-cols-sm) items-center {hiddenCols}"
53
+ >
36
54
  {@render row(item)}
37
55
  </div>
38
56
  {/each}
39
57
  </div>
58
+
59
+ <style>
60
+ @media (max-width: 639px) {
61
+ :global(.data-table-row.hide-col-1 > :nth-child(1)),
62
+ :global(.data-table-row.hide-col-2 > :nth-child(2)),
63
+ :global(.data-table-row.hide-col-3 > :nth-child(3)),
64
+ :global(.data-table-row.hide-col-4 > :nth-child(4)),
65
+ :global(.data-table-row.hide-col-5 > :nth-child(5)),
66
+ :global(.data-table-row.hide-col-6 > :nth-child(6)),
67
+ :global(.data-table-row.hide-col-7 > :nth-child(7)),
68
+ :global(.data-table-row.hide-col-8 > :nth-child(8)) {
69
+ display: none;
70
+ }
71
+ }
72
+ </style>
@@ -2,6 +2,8 @@ export interface DataTableColumn {
2
2
  label: string;
3
3
  width?: string;
4
4
  align?: 'left' | 'right';
5
+ /** Drop the column below 640px, where fixed widths would crush the flexible one. */
6
+ hideOnMobile?: boolean;
5
7
  }
6
8
  import type { Snippet } from 'svelte';
7
9
  declare function $$render<T>(): {
@@ -1,14 +1,16 @@
1
1
  <script lang="ts">
2
2
  import type { Component } from 'svelte';
3
- import { Search, ChevronDown, Check } from '@lucide/svelte';
3
+ import { ChevronDown } from '@lucide/svelte';
4
4
  import { cn } from '../../utils.js';
5
+ import { buttonVariants } from './button';
6
+ import * as Popover from './popover';
7
+ import * as Command from './command';
5
8
 
6
9
  export interface FilterableDropdownItem {
7
10
  id: string;
8
11
  label: string;
9
12
  icon?: Component;
10
13
  iconClass?: string;
11
- iconStyle?: string;
12
14
  }
13
15
 
14
16
  interface Props {
@@ -19,6 +21,7 @@
19
21
  placeholder?: string;
20
22
  triggerIcon?: Component;
21
23
  searchPlaceholder?: string;
24
+ /** Above this many items the list gets a filter box. */
22
25
  searchThreshold?: number;
23
26
  disabled?: boolean;
24
27
  class?: string;
@@ -38,149 +41,59 @@
38
41
  }: Props = $props();
39
42
 
40
43
  let open = $state(false);
41
- let query = $state('');
42
- let highlighted = $state(0);
43
- let inputRef = $state<HTMLInputElement>();
44
- let containerRef = $state<HTMLDivElement>();
45
44
 
46
45
  const selected = $derived(items.find((item) => item.id === value) ?? null);
47
- const showSearch = $derived(items.length > searchThreshold);
48
-
49
- const matches = $derived.by(() => {
50
- const q = query.trim().toLowerCase();
51
- if (!q) return items;
52
- return items.filter((item) => item.label.toLowerCase().includes(q));
53
- });
54
-
55
- $effect(() => {
56
- void matches;
57
- highlighted = 0;
58
- });
59
-
60
- $effect(() => {
61
- if (open) {
62
- queueMicrotask(() => inputRef?.focus());
63
- } else {
64
- query = '';
65
- }
66
- });
46
+ const SelectedIcon = $derived(selected?.icon ?? TriggerIcon);
67
47
 
68
48
  function pick(item: FilterableDropdownItem) {
69
49
  onChange(item.id);
70
50
  open = false;
71
51
  }
72
-
73
- function handleKey(e: KeyboardEvent) {
74
- if (e.key === 'ArrowDown') {
75
- e.preventDefault();
76
- highlighted = Math.min(highlighted + 1, matches.length - 1);
77
- } else if (e.key === 'ArrowUp') {
78
- e.preventDefault();
79
- highlighted = Math.max(highlighted - 1, 0);
80
- } else if (e.key === 'Enter') {
81
- e.preventDefault();
82
- const m = matches[highlighted];
83
- if (m) pick(m);
84
- } else if (e.key === 'Escape') {
85
- e.preventDefault();
86
- open = false;
87
- }
88
- }
89
-
90
- function handleDocClick(e: MouseEvent) {
91
- if (!open) return;
92
- if (containerRef && !containerRef.contains(e.target as Node)) open = false;
93
- }
94
-
95
- $effect(() => {
96
- if (!open) return;
97
- document.addEventListener('mousedown', handleDocClick);
98
- return () => document.removeEventListener('mousedown', handleDocClick);
99
- });
100
-
101
- const SelectedIcon = $derived(selected?.icon);
102
52
  </script>
103
53
 
104
- <div bind:this={containerRef} class={cn('relative', className)}>
105
- <button
106
- type="button"
54
+ <Popover.Root bind:open>
55
+ <Popover.Trigger
107
56
  {id}
108
57
  {disabled}
109
- onclick={() => (open = !open)}
58
+ role="combobox"
59
+ aria-expanded={open}
110
60
  class={cn(
111
- 'h-10 gap-2 px-3 text-sm flex w-full items-center rounded-md border bg-background text-left transition-colors disabled:cursor-not-allowed disabled:opacity-50',
112
- open ? 'border-ring ring-2 ring-ring/30' : 'border-input hover:bg-muted/40'
61
+ buttonVariants({ variant: 'outline' }),
62
+ 'font-normal w-full justify-start',
63
+ className
113
64
  )}
114
65
  >
115
66
  {#if SelectedIcon}
116
- <SelectedIcon
117
- class={cn('h-3.5 w-3.5 shrink-0', selected?.iconClass ?? 'text-muted-foreground')}
118
- style={selected?.iconStyle}
119
- />
120
- {:else if TriggerIcon}
121
- <TriggerIcon class="h-3.5 w-3.5 shrink-0 text-muted-foreground" />
67
+ <SelectedIcon class={cn('size-3.5', selected?.iconClass ?? 'text-muted-foreground')} />
122
68
  {/if}
123
- <span class={cn('min-w-0 flex-1 truncate', selected ? '' : 'text-muted-foreground')}>
69
+ <span class={cn('min-w-0 flex-1 truncate text-left', !selected && 'text-muted-foreground')}>
124
70
  {selected ? selected.label : placeholder}
125
71
  </span>
126
- <ChevronDown
127
- class={cn(
128
- 'h-3.5 w-3.5 shrink-0 text-muted-foreground transition-transform',
129
- open ? 'rotate-180' : ''
130
- )}
131
- />
132
- </button>
133
-
134
- {#if open}
135
- <div
136
- class="right-0 left-0 mt-1 shadow-md absolute top-full z-50 overflow-hidden rounded-md border border-border bg-popover"
137
- >
138
- {#if showSearch}
139
- <div class="relative border-b border-border">
140
- <Search
141
- class="left-3 h-3.5 w-3.5 pointer-events-none absolute top-1/2 -translate-y-1/2 text-muted-foreground"
142
- />
143
- <input
144
- bind:this={inputRef}
145
- bind:value={query}
146
- onkeydown={handleKey}
147
- placeholder={searchPlaceholder}
148
- class="h-8 pr-3 pl-9 text-sm w-full bg-transparent outline-none placeholder:text-muted-foreground"
149
- />
150
- </div>
72
+ <ChevronDown class="size-3.5 text-muted-foreground" />
73
+ </Popover.Trigger>
74
+ <Popover.Content align="start" class="p-0 w-(--bits-popover-anchor-width)">
75
+ <Command.Root>
76
+ {#if items.length > searchThreshold}
77
+ <Command.Input placeholder={searchPlaceholder} />
151
78
  {/if}
152
-
153
- <div class="max-h-60 overflow-y-auto">
154
- {#if matches.length === 0}
155
- <p class="px-3 py-3 text-xs text-center text-muted-foreground">
156
- No matches for "{query}"
157
- </p>
158
- {:else}
159
- {#each matches as item, i (item.id)}
160
- {@const ItemIcon = item.icon}
161
- <button
162
- type="button"
163
- onclick={() => pick(item)}
164
- onmouseenter={() => (highlighted = i)}
165
- class={cn(
166
- 'gap-2 px-3 py-1.5 text-sm flex w-full items-center text-left transition-colors',
167
- highlighted === i ? 'bg-accent text-accent-foreground' : 'hover:bg-muted/60'
168
- )}
169
- >
170
- {#if ItemIcon}
171
- <ItemIcon
172
- class={cn('h-3.5 w-3.5 shrink-0', item.iconClass ?? 'text-muted-foreground')}
173
- style={item.iconStyle}
174
- />
175
- {/if}
176
- <span class="flex-1 truncate">{item.label}</span>
177
- {#if item.id === value}
178
- <Check class="h-3.5 w-3.5 shrink-0 text-primary" />
179
- {/if}
180
- </button>
181
- {/each}
182
- {/if}
183
- </div>
184
- </div>
185
- {/if}
186
- </div>
79
+ <Command.List>
80
+ <Command.Empty>No matches.</Command.Empty>
81
+ {#each items as item (item.id)}
82
+ {@const ItemIcon = item.icon}
83
+ <!-- Filter on the label; the id is only the key. -->
84
+ <Command.Item
85
+ value={item.id}
86
+ keywords={[item.label]}
87
+ data-checked={item.id === value}
88
+ onSelect={() => pick(item)}
89
+ >
90
+ {#if ItemIcon}
91
+ <ItemIcon class={cn('size-3.5', item.iconClass ?? 'text-muted-foreground')} />
92
+ {/if}
93
+ <span class="truncate">{item.label}</span>
94
+ </Command.Item>
95
+ {/each}
96
+ </Command.List>
97
+ </Command.Root>
98
+ </Popover.Content>
99
+ </Popover.Root>
@@ -4,7 +4,6 @@ export interface FilterableDropdownItem {
4
4
  label: string;
5
5
  icon?: Component;
6
6
  iconClass?: string;
7
- iconStyle?: string;
8
7
  }
9
8
  interface Props {
10
9
  items: FilterableDropdownItem[];
@@ -14,6 +13,7 @@ interface Props {
14
13
  placeholder?: string;
15
14
  triggerIcon?: Component;
16
15
  searchPlaceholder?: string;
16
+ /** Above this many items the list gets a filter box. */
17
17
  searchThreshold?: number;
18
18
  disabled?: boolean;
19
19
  class?: string;
@@ -0,0 +1,56 @@
1
+ <script lang="ts" module>
2
+ import type { Severity } from './severity';
3
+
4
+ export interface Issue {
5
+ severity: Severity;
6
+ message: string;
7
+ /** A second, quieter line: expected vs actual, a path, a hint. */
8
+ detail?: string;
9
+ /** What raised it, such as the component's nickname. */
10
+ source?: string;
11
+ /** How many times the same message came in; shown as ×n above 1. */
12
+ count?: number;
13
+ }
14
+ </script>
15
+
16
+ <script lang="ts">
17
+ import { cn } from '../../utils.js';
18
+ import SeverityIcon from './SeverityIcon.svelte';
19
+
20
+ interface Props {
21
+ issues: readonly Issue[];
22
+ /** `boxed` draws a bordered, divided list; `plain` is for surfaces that already have a frame. */
23
+ variant?: 'boxed' | 'plain';
24
+ class?: string;
25
+ }
26
+
27
+ let { issues, variant = 'boxed', class: className }: Props = $props();
28
+ </script>
29
+
30
+ <ul
31
+ class={cn(
32
+ 'text-sm',
33
+ variant === 'boxed' ? 'divide-y rounded-lg border' : 'gap-2 flex flex-col',
34
+ className
35
+ )}
36
+ >
37
+ {#each issues as issue, i (i)}
38
+ <li class={cn('gap-2 flex items-start', variant === 'boxed' && 'px-3 py-2')}>
39
+ <SeverityIcon severity={issue.severity} class="mt-0.5" />
40
+ <div class="min-w-0 flex-1">
41
+ <p class="wrap-anywhere">
42
+ {issue.message}
43
+ {#if issue.count && issue.count > 1}
44
+ <span class="ml-1 text-xs text-muted-foreground tabular-nums">×{issue.count}</span>
45
+ {/if}
46
+ </p>
47
+ {#if issue.source}
48
+ <p class="text-xs text-muted-foreground">{issue.source}</p>
49
+ {/if}
50
+ {#if issue.detail}
51
+ <p class="mt-0.5 text-xs wrap-anywhere text-muted-foreground">{issue.detail}</p>
52
+ {/if}
53
+ </div>
54
+ </li>
55
+ {/each}
56
+ </ul>
@@ -0,0 +1,20 @@
1
+ import type { Severity } from './severity';
2
+ export interface Issue {
3
+ severity: Severity;
4
+ message: string;
5
+ /** A second, quieter line: expected vs actual, a path, a hint. */
6
+ detail?: string;
7
+ /** What raised it, such as the component's nickname. */
8
+ source?: string;
9
+ /** How many times the same message came in; shown as ×n above 1. */
10
+ count?: number;
11
+ }
12
+ interface Props {
13
+ issues: readonly Issue[];
14
+ /** `boxed` draws a bordered, divided list; `plain` is for surfaces that already have a frame. */
15
+ variant?: 'boxed' | 'plain';
16
+ class?: string;
17
+ }
18
+ declare const IssueList: import("svelte").Component<Props, {}, "">;
19
+ type IssueList = ReturnType<typeof IssueList>;
20
+ export default IssueList;
@@ -0,0 +1,15 @@
1
+ <script lang="ts">
2
+ import { cn } from '../../utils.js';
3
+ import { SEVERITY_ICON, SEVERITY_TEXT, type Severity } from './severity';
4
+
5
+ interface Props {
6
+ severity: Severity;
7
+ class?: string;
8
+ }
9
+
10
+ let { severity, class: className }: Props = $props();
11
+
12
+ const Icon = $derived(SEVERITY_ICON[severity]);
13
+ </script>
14
+
15
+ <Icon class={cn('size-4 shrink-0', SEVERITY_TEXT[severity], className)} aria-hidden="true" />
@@ -0,0 +1,8 @@
1
+ import { type Severity } from './severity';
2
+ interface Props {
3
+ severity: Severity;
4
+ class?: string;
5
+ }
6
+ declare const SeverityIcon: import("svelte").Component<Props, {}, "">;
7
+ type SeverityIcon = ReturnType<typeof SeverityIcon>;
8
+ export default SeverityIcon;
@@ -3,57 +3,58 @@
3
3
 
4
4
  interface Props {
5
5
  show: boolean;
6
+ /**
7
+ * `floating` overlays the bottom-left corner. `inline` is a compact chip the size of an
8
+ * icon button, for a narrow host whose corner holds its content and whose action row
9
+ * already reserves the chip's place. Both say Esc aborts, as every host does.
10
+ */
11
+ placement?: 'floating' | 'inline';
6
12
  }
7
13
 
8
- let { show }: Props = $props();
14
+ let { show, placement = 'floating' }: Props = $props();
9
15
 
10
16
  const locale = getLocaleContext();
11
17
  const t = $derived(locale.messages);
12
18
  </script>
13
19
 
14
- {#if show}
15
- <div
16
- class="bottom-6 left-6 gap-3 px-5 py-3 shadow-xl fixed z-50 flex animate-[selva-slideInLeft_0.2s_ease-out] items-center rounded-lg border border-primary/20 bg-primary text-primary-foreground"
17
- >
18
- <div class="h-5 w-5 relative flex shrink-0 items-center justify-center">
19
- <div
20
- class="animate-ping absolute h-full w-full rounded-full bg-primary-foreground opacity-30"
21
- ></div>
20
+ <!-- The live region stays mounted: a screen reader only announces text that changes inside a
21
+ region it already knows about, so one created together with its text says nothing. -->
22
+ <div
23
+ role="status"
24
+ aria-live="polite"
25
+ aria-atomic="true"
26
+ class={placement === 'inline' ? 'h-10 gap-3 min-w-0 flex items-center' : undefined}
27
+ >
28
+ {#if show && placement === 'inline'}
29
+ <div
30
+ class="gap-2 px-3 h-10 text-sm font-semibold flex shrink-0 items-center rounded-md bg-primary text-primary-foreground"
31
+ >
22
32
  <div
23
33
  class="h-3 w-3 animate-spin rounded-full border-2 border-primary-foreground border-t-transparent"
34
+ aria-hidden="true"
24
35
  ></div>
36
+ {t.solvingEllipsis}
25
37
  </div>
26
- <div class="leading-tight flex flex-col">
27
- <span class="text-sm font-semibold">{t.solving}</span>
28
- <span class="text-xs opacity-70">{t.solvingSubtitle}</span>
38
+ <span class="text-xs min-w-0 truncate text-muted-foreground" data-testid="solve-esc-hint">
39
+ {t.solveMessagesEscHint}
40
+ </span>
41
+ {:else if show}
42
+ <div
43
+ class="bottom-6 left-6 gap-3 px-5 py-3 shadow-xl animate-in fade-in slide-in-from-left fixed z-50 flex items-center rounded-lg border border-primary/20 bg-primary text-primary-foreground duration-200"
44
+ >
45
+ <div class="h-5 w-5 relative flex shrink-0 items-center justify-center" aria-hidden="true">
46
+ <div
47
+ class="animate-ping absolute h-full w-full rounded-full bg-primary-foreground opacity-30"
48
+ ></div>
49
+ <div
50
+ class="h-3 w-3 animate-spin rounded-full border-2 border-primary-foreground border-t-transparent"
51
+ ></div>
52
+ </div>
53
+ <div class="leading-tight flex flex-col">
54
+ <span class="text-sm font-semibold">{t.solving}</span>
55
+ <span class="text-xs opacity-70" data-testid="solve-esc-hint">{t.solveMessagesEscHint}</span
56
+ >
57
+ </div>
29
58
  </div>
30
- </div>
31
- {/if}
32
-
33
- <style>
34
- @keyframes selva-slideInLeft {
35
- from {
36
- transform: translateX(-110%);
37
- opacity: 0;
38
- }
39
- to {
40
- transform: translateX(0);
41
- opacity: 1;
42
- }
43
- }
44
-
45
- @keyframes selva-sweep {
46
- 0% {
47
- width: 0%;
48
- margin-left: 0%;
49
- }
50
- 50% {
51
- width: 60%;
52
- margin-left: 20%;
53
- }
54
- 100% {
55
- width: 0%;
56
- margin-left: 100%;
57
- }
58
- }
59
- </style>
59
+ {/if}
60
+ </div>
@@ -1,5 +1,11 @@
1
1
  interface Props {
2
2
  show: boolean;
3
+ /**
4
+ * `floating` overlays the bottom-left corner. `inline` is a compact chip the size of an
5
+ * icon button, for a narrow host whose corner holds its content and whose action row
6
+ * already reserves the chip's place. Both say Esc aborts, as every host does.
7
+ */
8
+ placement?: 'floating' | 'inline';
3
9
  }
4
10
  declare const SolvingIndicator: import("svelte").Component<Props, {}, "">;
5
11
  type SolvingIndicator = ReturnType<typeof SolvingIndicator>;
@@ -1,6 +1,9 @@
1
1
  <script lang="ts">
2
- import { Loader, AlertCircle, AlertTriangle, Inbox } from '@lucide/svelte';
3
- import * as Card from './card';
2
+ import { Inbox } from '@lucide/svelte';
3
+ import { cn } from '../../utils.js';
4
+ import * as Empty from './empty';
5
+ import { Spinner } from './spinner';
6
+ import SeverityIcon from './SeverityIcon.svelte';
4
7
 
5
8
  interface StateDisplayProps {
6
9
  type: 'loading' | 'error' | 'warning' | 'empty';
@@ -18,89 +21,26 @@
18
21
  class: className = ''
19
22
  }: StateDisplayProps = $props();
20
23
 
21
- const sizeClasses = {
22
- small: {
23
- container: 'p-6 gap-3',
24
- icon: 'w-8 h-8',
25
- title: 'text-sm font-semibold',
26
- message: 'text-xs'
27
- },
28
- medium: {
29
- container: 'p-12 gap-4',
30
- icon: 'w-12 h-12',
31
- title: 'text-lg font-semibold',
32
- message: 'text-sm'
33
- },
34
- large: {
35
- container: 'p-16 gap-6',
36
- icon: 'w-16 h-16',
37
- title: 'text-2xl font-bold',
38
- message: 'text-base'
39
- }
40
- };
41
-
42
- /* Fully semantic, contrast-safe mappings */
43
- const typeClasses = {
44
- loading: {
45
- icon: 'text-primary',
46
- title: 'text-primary-foreground',
47
- message: 'text-primary-foreground/80',
48
- border: 'border-primary',
49
- background: 'bg-primary/15'
50
- },
51
- error: {
52
- icon: 'text-destructive',
53
- title: 'text-destructive-foreground',
54
- message: 'text-destructive-foreground/80',
55
- border: 'border-destructive',
56
- background: 'bg-destructive/15'
57
- },
58
- warning: {
59
- icon: 'text-accent',
60
- title: 'text-accent-foreground',
61
- message: 'text-accent-foreground/80',
62
- border: 'border-accent',
63
- background: 'bg-accent/15'
64
- },
65
- empty: {
66
- icon: 'text-neutral',
67
- title: 'text-neutral-foreground',
68
- message: 'text-neutral-foreground/80',
69
- border: 'border-neutral',
70
- background: 'bg-neutral/15'
71
- }
72
- };
73
-
74
- const sizeConfig = $derived(sizeClasses[size]);
75
- const typeConfig = $derived(typeClasses[type]);
24
+ // Size only changes the breathing room; the look comes from Empty and the severity tokens.
25
+ const PADDING = { small: 'p-4', medium: 'p-8', large: 'p-12' } as const;
76
26
  </script>
77
27
 
78
- <Card.Root class="rounded-lg border-2 {typeConfig.border} {typeConfig.background} {className}">
79
- <Card.Content
80
- class="flex flex-col items-center justify-center text-center {sizeConfig.container}"
81
- >
82
- <div class="{sizeConfig.icon} {typeConfig.icon}">
28
+ <Empty.Root class={cn(PADDING[size], className)}>
29
+ <Empty.Header>
30
+ <Empty.Media variant="icon">
83
31
  {#if type === 'loading'}
84
- <Loader class="animate-spin h-full w-full" />
85
- {:else if type === 'error'}
86
- <AlertCircle class="h-full w-full" />
87
- {:else if type === 'warning'}
88
- <AlertTriangle class="h-full w-full" />
32
+ <Spinner />
89
33
  {:else if type === 'empty'}
90
- <Inbox class="h-full w-full" />
34
+ <Inbox />
35
+ {:else}
36
+ <SeverityIcon severity={type} />
91
37
  {/if}
92
- </div>
93
-
38
+ </Empty.Media>
94
39
  {#if title}
95
- <h3 class="{sizeConfig.title} {typeConfig.title} mt-1">
96
- {title}
97
- </h3>
40
+ <Empty.Title>{title}</Empty.Title>
98
41
  {/if}
99
-
100
42
  {#if message}
101
- <p class="{sizeConfig.message} {typeConfig.message} max-w-md leading-relaxed">
102
- {message}
103
- </p>
43
+ <Empty.Description>{message}</Empty.Description>
104
44
  {/if}
105
- </Card.Content>
106
- </Card.Root>
45
+ </Empty.Header>
46
+ </Empty.Root>