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

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 (446) 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 +298 -128
  4. package/dist/components/compute/AppLayout.svelte.d.ts +22 -0
  5. package/dist/components/compute/CollapsedPanelStrip.svelte +4 -2
  6. package/dist/components/compute/ComputeApp.svelte +45 -24
  7. package/dist/components/compute/ComputeApp.svelte.d.ts +19 -2
  8. package/dist/components/compute/ComputeMessagesDialog.svelte +47 -83
  9. package/dist/components/compute/ParameterPresetManager.svelte +37 -130
  10. package/dist/components/compute/ParameterPresetManager.svelte.d.ts +4 -5
  11. package/dist/components/compute/SolveMessages.svelte +131 -77
  12. package/dist/components/compute/SolveMessages.svelte.d.ts +7 -12
  13. package/dist/components/layout/AppShell.svelte +10 -6
  14. package/dist/components/layout/PageFooter.svelte +23 -11
  15. package/dist/components/layout/PageHeader.svelte +11 -7
  16. package/dist/components/layout/Pagination.svelte +2 -4
  17. package/dist/components/layout/SectionHeader.svelte +4 -2
  18. package/dist/components/layout/SideNav.svelte +56 -7
  19. package/dist/components/preview/ChartOutput.svelte +91 -48
  20. package/dist/components/preview/Group.svelte +92 -103
  21. package/dist/components/preview/Group.svelte.d.ts +1 -1
  22. package/dist/components/preview/HelpButton.svelte +36 -0
  23. package/dist/components/preview/HelpButton.svelte.d.ts +8 -0
  24. package/dist/components/preview/ImageOutput.svelte +434 -72
  25. package/dist/components/preview/InputControl.svelte +163 -90
  26. package/dist/components/preview/InputControl.svelte.d.ts +5 -1
  27. package/dist/components/preview/OutputDisplay.svelte +44 -42
  28. package/dist/components/preview/TabBar.svelte +106 -22
  29. package/dist/components/preview/TabBar.svelte.d.ts +1 -0
  30. package/dist/components/preview/TabContent.svelte +63 -57
  31. package/dist/components/preview/TabContent.svelte.d.ts +5 -1
  32. package/dist/components/preview/TabLayout.svelte +27 -5
  33. package/dist/components/preview/TabLayout.svelte.d.ts +5 -0
  34. package/dist/components/preview/inputs/CheckboxInput.svelte +7 -7
  35. package/dist/components/preview/inputs/CheckboxInput.svelte.d.ts +3 -0
  36. package/dist/components/preview/inputs/ChecklistInput.svelte +7 -2
  37. package/dist/components/preview/inputs/ChecklistInput.svelte.d.ts +2 -1
  38. package/dist/components/preview/inputs/ColorInput.svelte +4 -2
  39. package/dist/components/preview/inputs/ColorInput.svelte.d.ts +1 -0
  40. package/dist/components/preview/inputs/DropdownInput.svelte +19 -4
  41. package/dist/components/preview/inputs/DropdownInput.svelte.d.ts +2 -1
  42. package/dist/components/preview/inputs/FileInput.svelte +112 -108
  43. package/dist/components/preview/inputs/GeometryInput.svelte +128 -0
  44. package/dist/components/preview/inputs/GeometryInput.svelte.d.ts +21 -0
  45. package/dist/components/preview/inputs/NumberInput.svelte +123 -61
  46. package/dist/components/preview/inputs/NumberInput.svelte.d.ts +2 -0
  47. package/dist/components/preview/inputs/OptionGlyph.svelte +29 -0
  48. package/dist/components/preview/inputs/OptionGlyph.svelte.d.ts +8 -0
  49. package/dist/components/preview/inputs/SegmentedInput.svelte +44 -0
  50. package/dist/components/preview/inputs/SegmentedInput.svelte.d.ts +12 -0
  51. package/dist/components/preview/inputs/TextInput.svelte +8 -4
  52. package/dist/components/preview/inputs/TileInput.svelte +80 -0
  53. package/dist/components/preview/inputs/TileInput.svelte.d.ts +12 -0
  54. package/dist/components/preview/inputs/index.d.ts +3 -0
  55. package/dist/components/preview/inputs/index.js +3 -0
  56. package/dist/components/primitives/CalculateButton.svelte +56 -24
  57. package/dist/components/primitives/CalculateButton.svelte.d.ts +3 -0
  58. package/dist/components/primitives/Callout.svelte +11 -18
  59. package/dist/components/primitives/DataTable.svelte +38 -5
  60. package/dist/components/primitives/DataTable.svelte.d.ts +2 -0
  61. package/dist/components/primitives/FilterableDropdown.svelte +42 -129
  62. package/dist/components/primitives/FilterableDropdown.svelte.d.ts +1 -1
  63. package/dist/components/primitives/IssueList.svelte +56 -0
  64. package/dist/components/primitives/IssueList.svelte.d.ts +20 -0
  65. package/dist/components/primitives/SeverityIcon.svelte +15 -0
  66. package/dist/components/primitives/SeverityIcon.svelte.d.ts +8 -0
  67. package/dist/components/primitives/SolvingIndicator.svelte +43 -42
  68. package/dist/components/primitives/SolvingIndicator.svelte.d.ts +6 -0
  69. package/dist/components/primitives/StateDisplay.svelte +19 -79
  70. package/dist/components/primitives/ViewToggle.svelte +18 -33
  71. package/dist/components/primitives/alert-dialog/alert-dialog-action.svelte +9 -3
  72. package/dist/components/primitives/alert-dialog/alert-dialog-action.svelte.d.ts +6 -1
  73. package/dist/components/primitives/alert-dialog/alert-dialog-content.svelte +1 -1
  74. package/dist/components/primitives/alert-dialog/alert-dialog-overlay.svelte +1 -1
  75. package/dist/components/primitives/badge/badge.svelte +2 -2
  76. package/dist/components/primitives/badge/badge.svelte.d.ts +4 -4
  77. package/dist/components/primitives/button/button.svelte +6 -2
  78. package/dist/components/primitives/button/button.svelte.d.ts +10 -4
  79. package/dist/components/primitives/card/card-header.svelte +1 -1
  80. package/dist/components/primitives/card/card.svelte +21 -5
  81. package/dist/components/primitives/card/card.svelte.d.ts +25 -1
  82. package/dist/components/primitives/card/index.d.ts +1 -2
  83. package/dist/components/primitives/card/index.js +2 -3
  84. package/dist/components/primitives/checkbox/checkbox.svelte +1 -1
  85. package/dist/components/primitives/command/command-dialog.svelte +42 -0
  86. package/dist/components/primitives/command/command-dialog.svelte.d.ts +14 -0
  87. package/dist/components/primitives/command/command-empty.svelte +17 -0
  88. package/dist/components/primitives/command/command-empty.svelte.d.ts +4 -0
  89. package/dist/components/primitives/command/command-group.svelte +33 -0
  90. package/dist/components/primitives/command/command-group.svelte.d.ts +7 -0
  91. package/dist/components/primitives/command/command-input.svelte +36 -0
  92. package/dist/components/primitives/command/command-input.svelte.d.ts +4 -0
  93. package/dist/components/primitives/command/command-item.svelte +28 -0
  94. package/dist/components/primitives/command/command-item.svelte.d.ts +4 -0
  95. package/dist/components/primitives/command/command-link-item.svelte +21 -0
  96. package/dist/components/primitives/command/command-link-item.svelte.d.ts +4 -0
  97. package/dist/components/primitives/command/command-list.svelte +20 -0
  98. package/dist/components/primitives/command/command-list.svelte.d.ts +4 -0
  99. package/dist/components/primitives/command/command-loading.svelte +7 -0
  100. package/dist/components/primitives/command/command-loading.svelte.d.ts +4 -0
  101. package/dist/components/primitives/command/command-separator.svelte +17 -0
  102. package/dist/components/primitives/command/command-separator.svelte.d.ts +4 -0
  103. package/dist/components/primitives/command/command-shortcut.svelte +23 -0
  104. package/dist/components/primitives/command/command-shortcut.svelte.d.ts +5 -0
  105. package/dist/components/primitives/command/command.svelte +28 -0
  106. package/dist/components/primitives/command/command.svelte.d.ts +8 -0
  107. package/dist/components/primitives/command/index.d.ts +12 -0
  108. package/dist/components/primitives/command/index.js +14 -0
  109. package/dist/components/primitives/context-menu/context-menu-content.svelte +1 -1
  110. package/dist/components/primitives/context-menu/context-menu-sub-content.svelte +1 -1
  111. package/dist/components/primitives/dialog/dialog-content.svelte +11 -3
  112. package/dist/components/primitives/dialog/dialog-content.svelte.d.ts +2 -0
  113. package/dist/components/primitives/dialog/dialog-overlay.svelte +1 -1
  114. package/dist/components/primitives/dialog/dialog-title.svelte +6 -2
  115. package/dist/components/primitives/dialog/dialog-title.svelte.d.ts +5 -1
  116. package/dist/components/primitives/drawer/Drawer.svelte +2 -2
  117. package/dist/components/primitives/dropdown-menu/dropdown-menu-checkbox-group.svelte +16 -0
  118. package/dist/components/primitives/dropdown-menu/dropdown-menu-checkbox-group.svelte.d.ts +4 -0
  119. package/dist/components/primitives/dropdown-menu/dropdown-menu-checkbox-item.svelte +46 -0
  120. package/dist/components/primitives/dropdown-menu/dropdown-menu-checkbox-item.svelte.d.ts +9 -0
  121. package/dist/components/primitives/dropdown-menu/dropdown-menu-content.svelte +31 -0
  122. package/dist/components/primitives/dropdown-menu/dropdown-menu-content.svelte.d.ts +10 -0
  123. package/dist/components/primitives/dropdown-menu/dropdown-menu-group-heading.svelte +22 -0
  124. package/dist/components/primitives/dropdown-menu/dropdown-menu-group-heading.svelte.d.ts +8 -0
  125. package/dist/components/primitives/dropdown-menu/dropdown-menu-group.svelte +7 -0
  126. package/dist/components/primitives/dropdown-menu/dropdown-menu-group.svelte.d.ts +4 -0
  127. package/dist/components/primitives/dropdown-menu/dropdown-menu-item.svelte +27 -0
  128. package/dist/components/primitives/dropdown-menu/dropdown-menu-item.svelte.d.ts +8 -0
  129. package/dist/components/primitives/dropdown-menu/dropdown-menu-label.svelte +24 -0
  130. package/dist/components/primitives/dropdown-menu/dropdown-menu-label.svelte.d.ts +8 -0
  131. package/dist/components/primitives/dropdown-menu/dropdown-menu-portal.svelte +7 -0
  132. package/dist/components/primitives/dropdown-menu/dropdown-menu-portal.svelte.d.ts +3 -0
  133. package/dist/components/primitives/dropdown-menu/dropdown-menu-radio-group.svelte +16 -0
  134. package/dist/components/primitives/dropdown-menu/dropdown-menu-radio-group.svelte.d.ts +4 -0
  135. package/dist/components/primitives/dropdown-menu/dropdown-menu-radio-item.svelte +36 -0
  136. package/dist/components/primitives/dropdown-menu/dropdown-menu-radio-item.svelte.d.ts +4 -0
  137. package/dist/components/primitives/dropdown-menu/dropdown-menu-separator.svelte +17 -0
  138. package/dist/components/primitives/dropdown-menu/dropdown-menu-separator.svelte.d.ts +4 -0
  139. package/dist/components/primitives/dropdown-menu/dropdown-menu-shortcut.svelte +23 -0
  140. package/dist/components/primitives/dropdown-menu/dropdown-menu-shortcut.svelte.d.ts +5 -0
  141. package/dist/components/primitives/dropdown-menu/dropdown-menu-sub-content.svelte +31 -0
  142. package/dist/components/primitives/dropdown-menu/dropdown-menu-sub-content.svelte.d.ts +10 -0
  143. package/dist/components/primitives/dropdown-menu/dropdown-menu-sub-trigger.svelte +29 -0
  144. package/dist/components/primitives/dropdown-menu/dropdown-menu-sub-trigger.svelte.d.ts +7 -0
  145. package/dist/components/primitives/dropdown-menu/dropdown-menu-sub.svelte +7 -0
  146. package/dist/components/primitives/dropdown-menu/dropdown-menu-sub.svelte.d.ts +3 -0
  147. package/dist/components/primitives/dropdown-menu/dropdown-menu-trigger.svelte +7 -0
  148. package/dist/components/primitives/dropdown-menu/dropdown-menu-trigger.svelte.d.ts +4 -0
  149. package/dist/components/primitives/dropdown-menu/dropdown-menu.svelte +7 -0
  150. package/dist/components/primitives/dropdown-menu/dropdown-menu.svelte.d.ts +3 -0
  151. package/dist/components/primitives/dropdown-menu/index.d.ts +18 -0
  152. package/dist/components/primitives/dropdown-menu/index.js +18 -0
  153. package/dist/components/primitives/{alert/alert-description.svelte → empty/empty-content.svelte} +3 -3
  154. package/dist/components/primitives/empty/empty-content.svelte.d.ts +5 -0
  155. package/dist/components/primitives/empty/empty-description.svelte +23 -0
  156. package/dist/components/primitives/{alert/alert-description.svelte.d.ts → empty/empty-description.svelte.d.ts} +4 -4
  157. package/dist/components/primitives/{alert/alert-title.svelte → empty/empty-header.svelte} +3 -3
  158. package/dist/components/primitives/empty/empty-header.svelte.d.ts +5 -0
  159. package/dist/components/primitives/empty/empty-media.svelte +41 -0
  160. package/dist/components/primitives/empty/empty-media.svelte.d.ts +26 -0
  161. package/dist/components/primitives/{card/card-action.svelte → empty/empty-title.svelte} +2 -2
  162. package/dist/components/primitives/{card/card-action.svelte.d.ts → empty/empty-title.svelte.d.ts} +3 -3
  163. package/dist/components/primitives/empty/empty.svelte +23 -0
  164. package/dist/components/primitives/empty/empty.svelte.d.ts +5 -0
  165. package/dist/components/primitives/empty/index.d.ts +7 -0
  166. package/dist/components/primitives/empty/index.js +9 -0
  167. package/dist/components/primitives/index.d.ts +10 -1
  168. package/dist/components/primitives/index.js +10 -1
  169. package/dist/components/primitives/input/input.svelte +4 -4
  170. package/dist/components/primitives/input-group/index.d.ts +7 -0
  171. package/dist/components/primitives/input-group/index.js +9 -0
  172. package/dist/components/primitives/input-group/input-group-addon.svelte +53 -0
  173. package/dist/components/primitives/input-group/input-group-addon.svelte.d.ts +32 -0
  174. package/dist/components/primitives/input-group/input-group-button.svelte +49 -0
  175. package/dist/components/primitives/input-group/input-group-button.svelte.d.ts +32 -0
  176. package/dist/components/primitives/input-group/input-group-input.svelte +25 -0
  177. package/dist/components/primitives/input-group/input-group-input.svelte.d.ts +11 -0
  178. package/dist/components/primitives/input-group/input-group-text.svelte +22 -0
  179. package/dist/components/primitives/input-group/input-group-text.svelte.d.ts +5 -0
  180. package/dist/components/primitives/input-group/input-group-textarea.svelte +23 -0
  181. package/dist/components/primitives/input-group/input-group-textarea.svelte.d.ts +3 -0
  182. package/dist/components/primitives/input-group/input-group.svelte +24 -0
  183. package/dist/components/primitives/{alert/alert-title.svelte.d.ts → input-group/input-group.svelte.d.ts} +4 -4
  184. package/dist/components/primitives/mode-toggle/mode-toggle.svelte +6 -7
  185. package/dist/components/primitives/popover/index.d.ts +9 -0
  186. package/dist/components/primitives/popover/index.js +11 -0
  187. package/dist/components/primitives/popover/popover-close.svelte +7 -0
  188. package/dist/components/primitives/popover/popover-close.svelte.d.ts +4 -0
  189. package/dist/components/primitives/popover/popover-content.svelte +31 -0
  190. package/dist/components/primitives/popover/popover-content.svelte.d.ts +10 -0
  191. package/dist/components/primitives/popover/popover-description.svelte +20 -0
  192. package/dist/components/primitives/popover/popover-description.svelte.d.ts +5 -0
  193. package/dist/components/primitives/popover/popover-header.svelte +20 -0
  194. package/dist/components/primitives/popover/popover-header.svelte.d.ts +5 -0
  195. package/dist/components/primitives/popover/popover-portal.svelte +7 -0
  196. package/dist/components/primitives/popover/popover-portal.svelte.d.ts +3 -0
  197. package/dist/components/primitives/popover/popover-title.svelte +15 -0
  198. package/dist/components/primitives/popover/popover-title.svelte.d.ts +5 -0
  199. package/dist/components/primitives/popover/popover-trigger.svelte +17 -0
  200. package/dist/components/primitives/popover/popover-trigger.svelte.d.ts +4 -0
  201. package/dist/components/primitives/popover/popover.svelte +7 -0
  202. package/dist/components/primitives/popover/popover.svelte.d.ts +3 -0
  203. package/dist/components/primitives/resizable/resizable-handle.svelte +6 -2
  204. package/dist/components/primitives/resizable/resizable-handle.svelte.d.ts +2 -0
  205. package/dist/components/primitives/resizable/resizable-pane-group.svelte +1 -4
  206. package/dist/components/primitives/scroll-area/scroll-area.svelte +1 -1
  207. package/dist/components/primitives/search/search.svelte +3 -3
  208. package/dist/components/primitives/select/select-content.svelte +1 -1
  209. package/dist/components/primitives/select/select-trigger.svelte +1 -1
  210. package/dist/components/primitives/severity.d.ts +7 -0
  211. package/dist/components/primitives/severity.js +19 -0
  212. package/dist/components/primitives/slider/slider.svelte +8 -3
  213. package/dist/components/primitives/slider/slider.svelte.d.ts +5 -1
  214. package/dist/components/primitives/sonner/sonner.svelte +1 -1
  215. package/dist/components/primitives/spinner/index.d.ts +1 -0
  216. package/dist/components/primitives/spinner/index.js +1 -0
  217. package/dist/components/primitives/spinner/spinner.svelte +29 -0
  218. package/dist/components/primitives/spinner/spinner.svelte.d.ts +4 -0
  219. package/dist/components/primitives/switch/switch.svelte +2 -2
  220. package/dist/components/primitives/tabs/tabs-list.svelte +27 -5
  221. package/dist/components/primitives/tabs/tabs-list.svelte.d.ts +22 -1
  222. package/dist/components/primitives/tabs/tabs-trigger.svelte +23 -5
  223. package/dist/components/primitives/tabs/tabs-trigger.svelte.d.ts +22 -1
  224. package/dist/components/primitives/tabs/tabs.svelte +6 -2
  225. package/dist/components/primitives/tabs/tabs.svelte.d.ts +5 -1
  226. package/dist/components/primitives/textarea/textarea.svelte +1 -1
  227. package/dist/components/primitives/theme-switcher/ThemeSwitcher.svelte +1 -1
  228. package/dist/components/primitives/toggle/index.d.ts +3 -0
  229. package/dist/components/primitives/toggle/index.js +5 -0
  230. package/dist/components/primitives/toggle/toggle.svelte +54 -0
  231. package/dist/components/primitives/toggle/toggle.svelte.d.ts +46 -0
  232. package/dist/components/primitives/toggle-group/index.d.ts +3 -0
  233. package/dist/components/primitives/toggle-group/index.js +5 -0
  234. package/dist/components/primitives/toggle-group/toggle-group-item.svelte +35 -0
  235. package/dist/components/primitives/toggle-group/toggle-group-item.svelte.d.ts +6 -0
  236. package/dist/components/primitives/toggle-group/toggle-group.svelte +75 -0
  237. package/dist/components/primitives/toggle-group/toggle-group.svelte.d.ts +17 -0
  238. package/dist/components/viewer/MeshMetadataPanel.svelte +119 -0
  239. package/dist/components/viewer/MeshMetadataPanel.svelte.d.ts +9 -0
  240. package/dist/components/viewer/SceneManager.svelte +14 -5
  241. package/dist/components/viewer/Viewer.svelte +243 -221
  242. package/dist/components/viewer/Viewer.svelte.d.ts +3 -0
  243. package/dist/compute/run-panel-action.d.ts +8 -0
  244. package/dist/compute/run-panel-action.js +12 -0
  245. package/dist/compute/solving.svelte.d.ts +11 -7
  246. package/dist/compute/solving.svelte.js +64 -45
  247. package/dist/compute/useSolveSession.svelte.js +3 -0
  248. package/dist/constants.d.ts +6 -8
  249. package/dist/constants.js +7 -9
  250. package/dist/contexts/hostContext.svelte.d.ts +39 -0
  251. package/dist/contexts/hostContext.svelte.js +9 -0
  252. package/dist/i18n/localeContext.svelte.d.ts +10 -3
  253. package/dist/i18n/localeContext.svelte.js +27 -5
  254. package/dist/i18n/messages.d.ts +150 -2
  255. package/dist/i18n/messages.js +261 -11
  256. package/dist/index.d.ts +4 -1
  257. package/dist/index.js +3 -0
  258. package/dist/public.d.ts +1 -1
  259. package/dist/schema/host-support.d.ts +29 -0
  260. package/dist/schema/host-support.js +97 -0
  261. package/dist/schema/option-display.d.ts +12 -0
  262. package/dist/schema/option-display.js +29 -0
  263. package/dist/schema/param-exporter.d.ts +4 -1
  264. package/dist/schema/param-exporter.js +10 -6
  265. package/dist/schema/visibility-rules.js +21 -0
  266. package/dist/styles/base.css +80 -10
  267. package/dist/types/actionButton.d.ts +17 -3
  268. package/dist/types/presetLabels.d.ts +3 -2
  269. package/dist/types/presetLabels.js +9 -8
  270. package/dist/utils/file-download.js +10 -22
  271. package/dist/utils/host-files.d.ts +12 -0
  272. package/dist/utils/host-files.js +46 -0
  273. package/dist/utils/loadScript.d.ts +2 -0
  274. package/dist/utils/loadScript.js +2 -0
  275. package/dist/utils/webp-to-png.d.ts +10 -0
  276. package/dist/utils/webp-to-png.js +41 -0
  277. package/package.json +19 -15
  278. package/src/lib/components/ConfirmDialog.svelte +2 -10
  279. package/src/lib/components/ErrorScreen.svelte +21 -27
  280. package/src/lib/components/compute/AppLayout.svelte +298 -128
  281. package/src/lib/components/compute/CollapsedPanelStrip.svelte +4 -2
  282. package/src/lib/components/compute/ComputeApp.svelte +45 -24
  283. package/src/lib/components/compute/ComputeMessagesDialog.svelte +47 -83
  284. package/src/lib/components/compute/ParameterPresetManager.svelte +37 -130
  285. package/src/lib/components/compute/SolveMessages.svelte +131 -77
  286. package/src/lib/components/layout/AppShell.svelte +10 -6
  287. package/src/lib/components/layout/PageFooter.svelte +23 -11
  288. package/src/lib/components/layout/PageHeader.svelte +11 -7
  289. package/src/lib/components/layout/Pagination.svelte +2 -4
  290. package/src/lib/components/layout/SectionHeader.svelte +4 -2
  291. package/src/lib/components/layout/SideNav.svelte +56 -7
  292. package/src/lib/components/preview/ChartOutput.svelte +91 -48
  293. package/src/lib/components/preview/Group.svelte +92 -103
  294. package/src/lib/components/preview/HelpButton.svelte +36 -0
  295. package/src/lib/components/preview/ImageOutput.svelte +434 -72
  296. package/src/lib/components/preview/InputControl.svelte +163 -90
  297. package/src/lib/components/preview/OutputDisplay.svelte +44 -42
  298. package/src/lib/components/preview/TabBar.svelte +106 -22
  299. package/src/lib/components/preview/TabContent.svelte +63 -57
  300. package/src/lib/components/preview/TabLayout.svelte +27 -5
  301. package/src/lib/components/preview/inputs/CheckboxInput.svelte +7 -7
  302. package/src/lib/components/preview/inputs/ChecklistInput.svelte +7 -2
  303. package/src/lib/components/preview/inputs/ColorInput.svelte +4 -2
  304. package/src/lib/components/preview/inputs/DropdownInput.svelte +19 -4
  305. package/src/lib/components/preview/inputs/FileInput.svelte +112 -108
  306. package/src/lib/components/preview/inputs/GeometryInput.svelte +128 -0
  307. package/src/lib/components/preview/inputs/NumberInput.svelte +123 -61
  308. package/src/lib/components/preview/inputs/OptionGlyph.svelte +29 -0
  309. package/src/lib/components/preview/inputs/SegmentedInput.svelte +44 -0
  310. package/src/lib/components/preview/inputs/TextInput.svelte +8 -4
  311. package/src/lib/components/preview/inputs/TileInput.svelte +80 -0
  312. package/src/lib/components/preview/inputs/index.ts +3 -0
  313. package/src/lib/components/primitives/CalculateButton.svelte +56 -24
  314. package/src/lib/components/primitives/Callout.svelte +11 -18
  315. package/src/lib/components/primitives/DataTable.svelte +38 -5
  316. package/src/lib/components/primitives/FilterableDropdown.svelte +42 -129
  317. package/src/lib/components/primitives/IssueList.svelte +56 -0
  318. package/src/lib/components/primitives/SeverityIcon.svelte +15 -0
  319. package/src/lib/components/primitives/SolvingIndicator.svelte +43 -42
  320. package/src/lib/components/primitives/StateDisplay.svelte +19 -79
  321. package/src/lib/components/primitives/ViewToggle.svelte +18 -33
  322. package/src/lib/components/primitives/alert-dialog/alert-dialog-action.svelte +9 -3
  323. package/src/lib/components/primitives/alert-dialog/alert-dialog-content.svelte +1 -1
  324. package/src/lib/components/primitives/alert-dialog/alert-dialog-overlay.svelte +1 -1
  325. package/src/lib/components/primitives/badge/badge.svelte +2 -2
  326. package/src/lib/components/primitives/button/button.svelte +6 -2
  327. package/src/lib/components/primitives/card/card-header.svelte +1 -1
  328. package/src/lib/components/primitives/card/card.svelte +21 -5
  329. package/src/lib/components/primitives/card/index.ts +1 -4
  330. package/src/lib/components/primitives/checkbox/checkbox.svelte +1 -1
  331. package/src/lib/components/primitives/command/command-dialog.svelte +42 -0
  332. package/src/lib/components/primitives/command/command-empty.svelte +17 -0
  333. package/src/lib/components/primitives/command/command-group.svelte +33 -0
  334. package/src/lib/components/primitives/command/command-input.svelte +36 -0
  335. package/src/lib/components/primitives/command/command-item.svelte +28 -0
  336. package/src/lib/components/primitives/command/command-link-item.svelte +21 -0
  337. package/src/lib/components/primitives/command/command-list.svelte +20 -0
  338. package/src/lib/components/primitives/command/command-loading.svelte +7 -0
  339. package/src/lib/components/primitives/command/command-separator.svelte +17 -0
  340. package/src/lib/components/primitives/command/command-shortcut.svelte +23 -0
  341. package/src/lib/components/primitives/command/command.svelte +28 -0
  342. package/src/lib/components/primitives/command/index.ts +37 -0
  343. package/src/lib/components/primitives/context-menu/context-menu-content.svelte +1 -1
  344. package/src/lib/components/primitives/context-menu/context-menu-sub-content.svelte +1 -1
  345. package/src/lib/components/primitives/dialog/dialog-content.svelte +11 -3
  346. package/src/lib/components/primitives/dialog/dialog-overlay.svelte +1 -1
  347. package/src/lib/components/primitives/dialog/dialog-title.svelte +6 -2
  348. package/src/lib/components/primitives/drawer/Drawer.svelte +2 -2
  349. package/src/lib/components/primitives/dropdown-menu/dropdown-menu-checkbox-group.svelte +16 -0
  350. package/src/lib/components/primitives/dropdown-menu/dropdown-menu-checkbox-item.svelte +46 -0
  351. package/src/lib/components/primitives/dropdown-menu/dropdown-menu-content.svelte +31 -0
  352. package/src/lib/components/primitives/dropdown-menu/dropdown-menu-group-heading.svelte +22 -0
  353. package/src/lib/components/primitives/dropdown-menu/dropdown-menu-group.svelte +7 -0
  354. package/src/lib/components/primitives/dropdown-menu/dropdown-menu-item.svelte +27 -0
  355. package/src/lib/components/primitives/dropdown-menu/dropdown-menu-label.svelte +24 -0
  356. package/src/lib/components/primitives/dropdown-menu/dropdown-menu-portal.svelte +7 -0
  357. package/src/lib/components/primitives/dropdown-menu/dropdown-menu-radio-group.svelte +16 -0
  358. package/src/lib/components/primitives/dropdown-menu/dropdown-menu-radio-item.svelte +36 -0
  359. package/src/lib/components/primitives/dropdown-menu/dropdown-menu-separator.svelte +17 -0
  360. package/src/lib/components/primitives/dropdown-menu/dropdown-menu-shortcut.svelte +23 -0
  361. package/src/lib/components/primitives/dropdown-menu/dropdown-menu-sub-content.svelte +31 -0
  362. package/src/lib/components/primitives/dropdown-menu/dropdown-menu-sub-trigger.svelte +29 -0
  363. package/src/lib/components/primitives/dropdown-menu/dropdown-menu-sub.svelte +7 -0
  364. package/src/lib/components/primitives/dropdown-menu/dropdown-menu-trigger.svelte +7 -0
  365. package/src/lib/components/primitives/dropdown-menu/dropdown-menu.svelte +7 -0
  366. package/src/lib/components/primitives/dropdown-menu/index.ts +54 -0
  367. package/src/lib/components/primitives/{alert/alert-description.svelte → empty/empty-content.svelte} +3 -3
  368. package/src/lib/components/primitives/empty/empty-description.svelte +23 -0
  369. package/src/lib/components/primitives/{alert/alert-title.svelte → empty/empty-header.svelte} +3 -3
  370. package/src/lib/components/primitives/empty/empty-media.svelte +41 -0
  371. package/src/lib/components/primitives/{card/card-action.svelte → empty/empty-title.svelte} +2 -2
  372. package/src/lib/components/primitives/empty/empty.svelte +23 -0
  373. package/src/lib/components/primitives/empty/index.ts +22 -0
  374. package/src/lib/components/primitives/index.ts +10 -1
  375. package/src/lib/components/primitives/input/input.svelte +4 -4
  376. package/src/lib/components/primitives/input-group/index.ts +22 -0
  377. package/src/lib/components/primitives/input-group/input-group-addon.svelte +53 -0
  378. package/src/lib/components/primitives/input-group/input-group-button.svelte +49 -0
  379. package/src/lib/components/primitives/input-group/input-group-input.svelte +25 -0
  380. package/src/lib/components/primitives/input-group/input-group-text.svelte +22 -0
  381. package/src/lib/components/primitives/input-group/input-group-textarea.svelte +23 -0
  382. package/src/lib/components/primitives/input-group/input-group.svelte +24 -0
  383. package/src/lib/components/primitives/mode-toggle/mode-toggle.svelte +6 -7
  384. package/src/lib/components/primitives/popover/index.ts +28 -0
  385. package/src/lib/components/primitives/popover/popover-close.svelte +7 -0
  386. package/src/lib/components/primitives/popover/popover-content.svelte +31 -0
  387. package/src/lib/components/primitives/popover/popover-description.svelte +20 -0
  388. package/src/lib/components/primitives/popover/popover-header.svelte +20 -0
  389. package/src/lib/components/primitives/popover/popover-portal.svelte +7 -0
  390. package/src/lib/components/primitives/popover/popover-title.svelte +15 -0
  391. package/src/lib/components/primitives/popover/popover-trigger.svelte +17 -0
  392. package/src/lib/components/primitives/popover/popover.svelte +7 -0
  393. package/src/lib/components/primitives/resizable/resizable-handle.svelte +6 -2
  394. package/src/lib/components/primitives/resizable/resizable-pane-group.svelte +1 -4
  395. package/src/lib/components/primitives/scroll-area/scroll-area.svelte +1 -1
  396. package/src/lib/components/primitives/search/search.svelte +3 -3
  397. package/src/lib/components/primitives/select/select-content.svelte +1 -1
  398. package/src/lib/components/primitives/select/select-trigger.svelte +1 -1
  399. package/src/lib/components/primitives/severity.ts +26 -0
  400. package/src/lib/components/primitives/slider/slider.svelte +8 -3
  401. package/src/lib/components/primitives/sonner/sonner.svelte +1 -1
  402. package/src/lib/components/primitives/spinner/index.ts +1 -0
  403. package/src/lib/components/primitives/spinner/spinner.svelte +29 -0
  404. package/src/lib/components/primitives/switch/switch.svelte +2 -2
  405. package/src/lib/components/primitives/tabs/tabs-list.svelte +27 -5
  406. package/src/lib/components/primitives/tabs/tabs-trigger.svelte +23 -5
  407. package/src/lib/components/primitives/tabs/tabs.svelte +6 -2
  408. package/src/lib/components/primitives/textarea/textarea.svelte +1 -1
  409. package/src/lib/components/primitives/theme-switcher/ThemeSwitcher.svelte +1 -1
  410. package/src/lib/components/primitives/toggle/index.ts +13 -0
  411. package/src/lib/components/primitives/toggle/toggle.svelte +54 -0
  412. package/src/lib/components/primitives/toggle-group/index.ts +10 -0
  413. package/src/lib/components/primitives/toggle-group/toggle-group-item.svelte +35 -0
  414. package/src/lib/components/primitives/toggle-group/toggle-group.svelte +75 -0
  415. package/src/lib/components/viewer/MeshMetadataPanel.svelte +119 -0
  416. package/src/lib/components/viewer/SceneManager.svelte +14 -5
  417. package/src/lib/components/viewer/Viewer.svelte +243 -221
  418. package/src/lib/compute/run-panel-action.ts +16 -0
  419. package/src/lib/compute/solving.svelte.ts +66 -50
  420. package/src/lib/compute/useSolveSession.svelte.ts +3 -0
  421. package/src/lib/constants.ts +7 -9
  422. package/src/lib/contexts/hostContext.svelte.ts +51 -0
  423. package/src/lib/i18n/localeContext.svelte.ts +40 -5
  424. package/src/lib/i18n/messages.ts +453 -13
  425. package/src/lib/index.ts +21 -0
  426. package/src/lib/public.ts +1 -0
  427. package/src/lib/schema/host-support.ts +129 -0
  428. package/src/lib/schema/option-display.ts +44 -0
  429. package/src/lib/schema/param-exporter.ts +10 -7
  430. package/src/lib/schema/visibility-rules.ts +23 -0
  431. package/src/lib/styles/base.css +80 -10
  432. package/src/lib/types/actionButton.ts +16 -3
  433. package/src/lib/types/presetLabels.ts +13 -11
  434. package/src/lib/utils/file-download.ts +11 -21
  435. package/src/lib/utils/host-files.ts +61 -0
  436. package/src/lib/utils/loadScript.ts +3 -0
  437. package/src/lib/utils/webp-to-png.ts +48 -0
  438. package/dist/components/primitives/alert/alert.svelte +0 -44
  439. package/dist/components/primitives/alert/alert.svelte.d.ts +0 -26
  440. package/dist/components/primitives/alert/index.d.ts +0 -5
  441. package/dist/components/primitives/alert/index.js +0 -7
  442. package/dist/components/viewer/MeshMetadataDialog.svelte +0 -126
  443. package/dist/components/viewer/MeshMetadataDialog.svelte.d.ts +0 -10
  444. package/src/lib/components/primitives/alert/alert.svelte +0 -44
  445. package/src/lib/components/primitives/alert/index.ts +0 -14
  446. package/src/lib/components/viewer/MeshMetadataDialog.svelte +0 -126
@@ -1,3 +1,4 @@
1
+ import { isFileData } from '../utils/file-download';
1
2
  const toStringArray = (value) => {
2
3
  if (Array.isArray(value))
3
4
  return value.map(String);
@@ -50,6 +51,9 @@ export function evaluateVisibility(item, values) {
50
51
  if ('visible' in item && item.visible === false) {
51
52
  return { visible: false, disabled: false };
52
53
  }
54
+ if (item.type === 'output' && drawsNothing(item, values[item.paramId])) {
55
+ return { visible: false, disabled: false };
56
+ }
53
57
  if (!item.visibilityCondition?.rules)
54
58
  return { visible: true, disabled: false };
55
59
  const { action = 'show', defaultValue } = item.visibilityCondition;
@@ -57,6 +61,23 @@ export function evaluateVisibility(item, values) {
57
61
  const actionFn = ACTIONS[action] ?? ACTIONS.show;
58
62
  return actionFn(met, defaultValue);
59
63
  }
64
+ /**
65
+ * An image or chart output has nothing to draw until a solve returns its data, and an empty
66
+ * preview box would hold its group, tab and pane open; it counts as hidden until then. A dynamic
67
+ * value list output never draws: it only feeds the options of an input.
68
+ */
69
+ function drawsNothing(item, value) {
70
+ switch (item.widgetType) {
71
+ case 'image':
72
+ return !(Array.isArray(value) ? value.some(isFileData) : isFileData(value));
73
+ case 'chart':
74
+ return value === undefined || value === null || value === '';
75
+ case 'dynamicValueList':
76
+ return true;
77
+ default:
78
+ return false;
79
+ }
80
+ }
60
81
  /** Must stay identical to the key the renderers use in their `{#each}` blocks. */
61
82
  export function itemKey(item) {
62
83
  return item.type === 'linebreak' ? item.id : item.paramId;
@@ -3,15 +3,19 @@
3
3
  :root {
4
4
  --radius: 0.625rem;
5
5
  --header-h: 3.5rem;
6
- --page-px: 1.5rem;
6
+ --below-header-h: calc(100svh - var(--header-h));
7
+ --page-px: 1rem;
7
8
  --page-py: 1.75rem;
8
9
  --background: oklch(0.99 0 0);
9
10
  --foreground: oklch(0.22 0 0);
10
- --card: oklch(0.985 0 0);
11
+ /* White, so a card stands apart from background and muted; Group adds a border, since
12
+ white on background alone is too close to see. */
13
+ --card: oklch(1 0 0);
11
14
  --card-foreground: oklch(0.22 0 0);
12
15
  --popover: oklch(0.99 0 0);
13
16
  --popover-foreground: oklch(0.22 0 0);
14
- --primary: oklch(0.57 0.07 135);
17
+ /* 4.5:1 as text on background, card and muted, and under white text. */
18
+ --primary: oklch(0.52 0.07 135);
15
19
  --primary-foreground: oklch(0.985 0 0);
16
20
  --secondary: oklch(0.94 0 0);
17
21
  --secondary-foreground: oklch(0.28 0 0);
@@ -19,10 +23,14 @@
19
23
  --muted-foreground: oklch(0.5 0 0);
20
24
  --accent: oklch(0.93 0 0);
21
25
  --accent-foreground: oklch(0.3 0 0);
22
- --destructive: oklch(0.6 0.18 27);
26
+ /* 4.5:1 as small text on background, card and muted, and under white text. */
27
+ --destructive: oklch(0.55 0.19 27);
28
+ --destructive-foreground: oklch(0.985 0 0);
23
29
  --border: oklch(0.86 0 0);
24
- --input: oklch(0.91 0 0);
25
- --ring: oklch(0.67 0 0);
30
+ /* Field borders and unchecked boxes: at least 3:1 against background, card and muted, the
31
+ WCAG minimum for a control's boundary. Same for the focus ring, which is drawn opaque. */
32
+ --input: oklch(0.62 0 0);
33
+ --ring: oklch(0.55 0 0);
26
34
  --success: oklch(0.66 0.14 145);
27
35
  --success-foreground: oklch(0.99 0 0);
28
36
  --warning: oklch(0.78 0.12 75);
@@ -36,14 +44,16 @@
36
44
  --chart-5: oklch(0.68 0.15 30);
37
45
  --sidebar: oklch(0.96 0 0);
38
46
  --sidebar-foreground: oklch(0.25 0 0);
39
- --sidebar-primary: oklch(0.57 0.07 135);
47
+ --sidebar-primary: oklch(0.52 0.07 135);
40
48
  --sidebar-primary-foreground: oklch(0.985 0 0);
41
49
  --sidebar-accent: oklch(0.93 0 0);
42
50
  --sidebar-accent-foreground: oklch(0.3 0 0);
43
51
  --sidebar-border: oklch(0.88 0 0);
44
- --sidebar-ring: oklch(0.67 0 0);
52
+ --sidebar-ring: oklch(0.55 0 0);
45
53
  --inputparam: oklch(1 0 0);
46
54
  --outputparam: oklch(1 0 0);
55
+ /* Scrim behind modal dialogs and drawers. */
56
+ --overlay: oklch(0 0 0 / 50%);
47
57
  }
48
58
 
49
59
  .dark {
@@ -62,8 +72,9 @@
62
72
  --accent: oklch(0.36 0 0);
63
73
  --accent-foreground: oklch(0.92 0 0);
64
74
  --destructive: oklch(0.7 0.17 22);
75
+ --destructive-foreground: oklch(0.985 0 0);
65
76
  --border: oklch(1 0 0 / 14%);
66
- --input: oklch(1 0 0 / 12%);
77
+ --input: oklch(1 0 0 / 36%);
67
78
  --ring: oklch(0.74 0 0);
68
79
  --success: oklch(0.74 0.15 145);
69
80
  --success-foreground: oklch(0.18 0.03 145);
@@ -108,6 +119,8 @@
108
119
  --color-accent: var(--accent);
109
120
  --color-accent-foreground: var(--accent-foreground);
110
121
  --color-destructive: var(--destructive);
122
+ --color-destructive-foreground: var(--destructive-foreground);
123
+ --color-overlay: var(--overlay);
111
124
  --color-border: var(--border);
112
125
  --color-input: var(--input);
113
126
  --color-ring: var(--ring);
@@ -134,9 +147,66 @@
134
147
  --color-outputparam: var(--outputparam);
135
148
  }
136
149
 
150
+ /* Design tokens beyond Tailwind's defaults. Reach for these before an arbitrary value: the
151
+ design-system lint rejects `text-[10px]`, `max-h-[85dvh]` and the like. */
152
+ @theme {
153
+ /* Type tags, counters and other dense labels. */
154
+ --text-2xs: 0.625rem;
155
+ --text-2xs--line-height: calc(0.875 / 0.625);
156
+ /* Bottom sheets cast their shadow upward. */
157
+ --shadow-sheet: 0 -4px 24px oklch(0 0 0 / 12%);
158
+ /* Width of anything that must keep a 1rem gutter on each side of the viewport. */
159
+ --container-screen-inset: calc(100% - 2rem);
160
+ }
161
+
162
+ @utility max-h-dialog {
163
+ max-height: 85dvh;
164
+ }
165
+
166
+ @utility no-scrollbar {
167
+ scrollbar-width: none;
168
+ &::-webkit-scrollbar {
169
+ display: none;
170
+ }
171
+ }
172
+
173
+ /* Number fields whose value is set elsewhere (a slider, a stepper) drop the browser's spinner. */
174
+ @utility no-spinner {
175
+ appearance: textfield;
176
+ &::-webkit-inner-spin-button,
177
+ &::-webkit-outer-spin-button {
178
+ appearance: none;
179
+ margin: 0;
180
+ }
181
+ }
182
+
183
+ @utility rounded-inherit {
184
+ border-radius: inherit;
185
+ }
186
+
187
+ /* Phones keep a narrower gutter: at 390px every 8px of side padding is 2% of the width. */
188
+ @media (min-width: 40rem) {
189
+ :root {
190
+ --page-px: 1.5rem;
191
+ }
192
+ }
193
+
194
+ /* A native select draws its arrow inside the right padding, so with the `px-2`/`px-3` every
195
+ caller uses it sits on the border. A drawn chevron with its own gutter fixes them all. Unlayered
196
+ on purpose: the gutter has to beat the callers' `px-*` utilities. Mid-grey reads on both themes,
197
+ since a data URI can't take `currentColor`. */
198
+ select:not([multiple]):not([size]) {
199
+ appearance: none;
200
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23888' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
201
+ background-repeat: no-repeat;
202
+ background-position: right 0.625rem center;
203
+ background-size: 1.1em;
204
+ padding-inline-end: calc(1.1em + 1rem);
205
+ }
206
+
137
207
  @layer base {
138
208
  * {
139
- @apply border-border outline-ring/50;
209
+ @apply border-border outline-ring;
140
210
  }
141
211
  html,
142
212
  body {
@@ -1,9 +1,23 @@
1
+ import type { SolveSettlement } from '@selvajs/solve/client';
2
+ /** A host action, listed in the panel footer's ⋯ menu after saving and loading inputs. */
1
3
  export interface ActionButton {
2
4
  id: string;
3
5
  label: string;
4
6
  /** A Svelte component, rendered before the label. */
5
7
  icon?: any;
6
- variant?: 'default' | 'outline' | 'destructive' | 'secondary' | 'ghost';
7
- size?: 'default' | 'sm' | 'lg';
8
- onclick: () => void | Promise<void>;
8
+ variant?: 'default' | 'destructive';
9
+ /** Shows the action as unavailable instead of hiding it. Pair it with a `hint` saying why. */
10
+ disabled?: boolean;
11
+ /** A short line under the label: why it is disabled, or what it does. */
12
+ hint?: string;
13
+ /**
14
+ * The action needs the result for the current inputs: picking it solves first when inputs
15
+ * changed, waits for a solve that is running or under review, and runs `onclick` only if
16
+ * that solve is applied. `onclick` then receives it. A refused or failed solve already shows
17
+ * its messages, so the action just doesn't run.
18
+ */
19
+ solvesFirst?: boolean;
20
+ onclick: (settled?: Extract<SolveSettlement, {
21
+ status: 'applied';
22
+ }>) => void | Promise<void>;
9
23
  }
@@ -3,8 +3,8 @@
3
3
  * unset keys fall back to `DEFAULT_PRESET_LABELS`.
4
4
  */
5
5
  export interface PresetLabels {
6
- saveButton: string;
7
- loadButton: string;
6
+ saveMenuItem: string;
7
+ loadMenuItem: string;
8
8
  saveDialogTitle: string;
9
9
  saveDialogDescription: string;
10
10
  saveNameLabel: string;
@@ -16,6 +16,7 @@ export interface PresetLabels {
16
16
  saveTagsLabel: string;
17
17
  saveTagsPlaceholder: string;
18
18
  saveNameRequired: string;
19
+ saveConfirmButton: string;
19
20
  loadDialogTitle: string;
20
21
  loadDialogDescription: string;
21
22
  loadFromFileButton: string;
@@ -1,9 +1,9 @@
1
1
  export const DEFAULT_PRESET_LABELS = {
2
- saveButton: 'Save State',
3
- loadButton: 'Load State',
4
- saveDialogTitle: 'Save Parameter State',
5
- saveDialogDescription: 'Save the current parameter values as a .slvp file',
6
- saveNameLabel: 'State Name *',
2
+ saveMenuItem: 'Save inputs…',
3
+ loadMenuItem: 'Load inputs…',
4
+ saveDialogTitle: 'Save inputs',
5
+ saveDialogDescription: 'Save the current input values as a .slvp file',
6
+ saveNameLabel: 'Name *',
7
7
  saveNamePlaceholder: 'e.g., Design Option A',
8
8
  saveDescriptionLabel: 'Description',
9
9
  saveDescriptionPlaceholder: 'Optional description of this state',
@@ -11,9 +11,10 @@ export const DEFAULT_PRESET_LABELS = {
11
11
  saveAuthorPlaceholder: 'Your name or email',
12
12
  saveTagsLabel: 'Tags',
13
13
  saveTagsPlaceholder: 'facade, option-a, client-approved (comma-separated)',
14
- saveNameRequired: 'Please enter a name for this state',
15
- loadDialogTitle: 'Load Parameter State',
16
- loadDialogDescription: 'Select a .slvp state file from your drive to load',
14
+ saveNameRequired: 'Please enter a name for these inputs',
15
+ saveConfirmButton: 'Save',
16
+ loadDialogTitle: 'Load inputs',
17
+ loadDialogDescription: 'Select a .slvp file from your drive to load',
17
18
  loadFromFileButton: 'Select .slvp File',
18
19
  loadEmptyList: 'No saved states found',
19
20
  loadImportError: 'Failed to import state: ',
@@ -1,6 +1,7 @@
1
- import { downloadFileDataByRoot } from '@selvajs/compute/core';
1
+ import { decodeBase64ToBinary, downloadFileDataByRoot } from '@selvajs/compute/core';
2
2
  import { SvelteMap } from 'svelte/reactivity';
3
3
  import { APP_DEFAULTS } from '../constants';
4
+ import { saveBlob } from './host-files';
4
5
  export const MIME_BY_EXT = {
5
6
  '.png': 'image/png',
6
7
  '.jpg': 'image/jpeg',
@@ -20,23 +21,10 @@ export const MIME_BY_EXT = {
20
21
  function saveSingleFile(file) {
21
22
  const ext = (file.fileType ?? '').toLowerCase();
22
23
  const mime = MIME_BY_EXT[ext] ?? 'application/octet-stream';
23
- let blob;
24
- if (file.isBase64Encoded) {
25
- const binary = atob(file.data);
26
- const bytes = new Uint8Array(binary.length);
27
- for (let i = 0; i < binary.length; i++)
28
- bytes[i] = binary.charCodeAt(i);
29
- blob = new Blob([bytes], { type: mime });
30
- }
31
- else {
32
- blob = new Blob([file.data], { type: mime });
33
- }
34
- const fullName = `${file.fileName}${file.fileType ?? ''}`;
35
- const a = document.createElement('a');
36
- a.href = URL.createObjectURL(blob);
37
- a.download = fullName;
38
- a.click();
39
- URL.revokeObjectURL(a.href);
24
+ const content = file.isBase64Encoded ? decodeBase64ToBinary(file.data) : file.data;
25
+ // decodeBase64ToBinary returns an ArrayBuffer-backed copy, never a SharedArrayBuffer view.
26
+ const blob = new Blob([content], { type: mime });
27
+ return saveBlob(blob, `${file.fileName}${file.fileType ?? ''}`);
40
28
  }
41
29
  export async function downloadFiles(fileData, fileName = 'grasshopper-output') {
42
30
  try {
@@ -45,13 +33,13 @@ export async function downloadFiles(fileData, fileName = 'grasshopper-output') {
45
33
  console.warn('[FileDownload] No files to download');
46
34
  return;
47
35
  }
48
- // A lone file is saved as itself rather than zipped — the one case that needs the DOM
49
- // directly. Everything else, including the per-root archive split, belongs to compute.
36
+ // A lone file is saved as itself rather than zipped. Everything else, including the
37
+ // per-root archive split, belongs to compute.
50
38
  if (filesArray.length === 1) {
51
- saveSingleFile(filesArray[0]);
39
+ await saveSingleFile(filesArray[0]);
52
40
  return;
53
41
  }
54
- await downloadFileDataByRoot(filesArray, fileName);
42
+ await downloadFileDataByRoot(filesArray, fileName, null, { saveBlob });
55
43
  }
56
44
  catch (error) {
57
45
  console.error('[FileDownload] Error downloading files:', error);
@@ -0,0 +1,12 @@
1
+ /** Resolves false when the user cancelled. An anchor download always resolves true: it can't tell. */
2
+ export type BlobSaver = (blob: Blob, fileName: string) => Promise<boolean>;
3
+ /** `accept` is what `<input accept>` takes: `.slvp,.sps`, `image/*`. Resolves null on cancel. */
4
+ export type FilePicker = (options: {
5
+ accept: string;
6
+ }) => Promise<File | null>;
7
+ export declare function setBlobSaver(next: BlobSaver): void;
8
+ export declare function setFilePicker(next: FilePicker): void;
9
+ export declare function saveBlob(blob: Blob, fileName: string): Promise<boolean>;
10
+ export declare function pickFile(options: {
11
+ accept: string;
12
+ }): Promise<File | null>;
@@ -0,0 +1,46 @@
1
+ // Where a file the page offers goes, and where a file the page asks for comes from. A browser
2
+ // gets an <a download> click and a hidden <input type=file>. A host whose WebView can't do
3
+ // either safely (the Rhino panel) installs its own once at start-up, before the first save or pick.
4
+ let saver = saveWithAnchor;
5
+ let picker = pickWithInput;
6
+ export function setBlobSaver(next) {
7
+ saver = next;
8
+ }
9
+ export function setFilePicker(next) {
10
+ picker = next;
11
+ }
12
+ export function saveBlob(blob, fileName) {
13
+ return saver(blob, fileName);
14
+ }
15
+ export function pickFile(options) {
16
+ return picker(options);
17
+ }
18
+ async function saveWithAnchor(blob, fileName) {
19
+ const url = URL.createObjectURL(blob);
20
+ const a = document.createElement('a');
21
+ a.href = url;
22
+ a.download = fileName;
23
+ // Firefox only downloads from an anchor that is in the document.
24
+ document.body.appendChild(a);
25
+ a.click();
26
+ a.remove();
27
+ // Revoking synchronously can abort the download: the browser pins the blob only once it starts.
28
+ setTimeout(() => URL.revokeObjectURL(url), 10_000);
29
+ return true;
30
+ }
31
+ function pickWithInput({ accept }) {
32
+ return new Promise((resolve) => {
33
+ const input = document.createElement('input');
34
+ input.type = 'file';
35
+ input.accept = accept;
36
+ input.style.display = 'none';
37
+ const settle = (file) => {
38
+ input.remove();
39
+ resolve(file);
40
+ };
41
+ input.addEventListener('change', () => settle(input.files?.[0] ?? null), { once: true });
42
+ input.addEventListener('cancel', () => settle(null), { once: true });
43
+ document.body.appendChild(input);
44
+ input.click();
45
+ });
46
+ }
@@ -4,6 +4,8 @@
4
4
  */
5
5
  export declare function loadScript(src: string, options?: {
6
6
  crossOrigin?: string;
7
+ /** Subresource Integrity hash. A cross-origin script also needs `crossOrigin`. */
8
+ integrity?: string;
7
9
  async?: boolean;
8
10
  defer?: boolean;
9
11
  }): Promise<void>;
@@ -17,6 +17,8 @@ export function loadScript(src, options) {
17
17
  script.src = src;
18
18
  if (options?.crossOrigin)
19
19
  script.crossOrigin = options.crossOrigin;
20
+ if (options?.integrity)
21
+ script.integrity = options.integrity;
20
22
  if (options?.async !== undefined)
21
23
  script.async = options.async;
22
24
  if (options?.defer !== undefined)
@@ -0,0 +1,10 @@
1
+ /** True when a WebP should go out as PNG: the input takes PNG, so a PNG is a valid value. */
2
+ export declare function shouldConvertWebp(fileEnding: string, acceptedFormats: readonly string[]): boolean;
3
+ /** Whether the input takes a file with this ending, counting a WebP it would get as PNG. */
4
+ export declare function acceptsFileEnding(fileEnding: string, acceptedFormats: readonly string[]): boolean;
5
+ /**
6
+ * By content, not name: image CDNs serve WebP from URLs with no extension or one naming another
7
+ * format. A WebP file starts `RIFF`, a 4-byte size, then `WEBP`.
8
+ */
9
+ export declare function isWebp(blob: Blob): Promise<boolean>;
10
+ export declare function webpToPng(blob: Blob): Promise<Blob>;
@@ -0,0 +1,41 @@
1
+ // Grasshopper's PDF export can't read WebP: the plugin's PDF library has no WebP decoder, and
2
+ // nothing on Windows or Rhino.Compute decodes it reliably. The browser can, so a WebP picked for
3
+ // an input that also takes PNG is re-encoded here. PNG rather than JPEG keeps transparency.
4
+ /** True when a WebP should go out as PNG: the input takes PNG, so a PNG is a valid value. */
5
+ export function shouldConvertWebp(fileEnding, acceptedFormats) {
6
+ return fileEnding === '.webp' && acceptedFormats.includes('.png');
7
+ }
8
+ /** Whether the input takes a file with this ending, counting a WebP it would get as PNG. */
9
+ export function acceptsFileEnding(fileEnding, acceptedFormats) {
10
+ const ending = fileEnding.toLowerCase();
11
+ if (acceptedFormats.length === 0 || acceptedFormats.includes(ending))
12
+ return true;
13
+ return shouldConvertWebp(ending, acceptedFormats);
14
+ }
15
+ const ascii = (bytes, start, end) => String.fromCharCode(...bytes.subarray(start, end));
16
+ /**
17
+ * By content, not name: image CDNs serve WebP from URLs with no extension or one naming another
18
+ * format. A WebP file starts `RIFF`, a 4-byte size, then `WEBP`.
19
+ */
20
+ export async function isWebp(blob) {
21
+ if (blob.type === 'image/webp')
22
+ return true;
23
+ const head = new Uint8Array(await blob.slice(0, 12).arrayBuffer());
24
+ return head.length === 12 && ascii(head, 0, 4) === 'RIFF' && ascii(head, 8, 12) === 'WEBP';
25
+ }
26
+ export async function webpToPng(blob) {
27
+ const bitmap = await createImageBitmap(blob);
28
+ try {
29
+ const canvas = document.createElement('canvas');
30
+ canvas.width = bitmap.width;
31
+ canvas.height = bitmap.height;
32
+ const context = canvas.getContext('2d');
33
+ if (!context)
34
+ throw new Error('Canvas 2D context unavailable');
35
+ context.drawImage(bitmap, 0, 0);
36
+ return await new Promise((resolve, reject) => canvas.toBlob((png) => (png ? resolve(png) : reject(new Error('PNG encoding failed'))), 'image/png'));
37
+ }
38
+ finally {
39
+ bitmap.close();
40
+ }
41
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@selvajs/ui",
3
- "version": "6.5.1-beta.1",
3
+ "version": "6.6.0-beta.12",
4
4
  "description": "Shared UI components and utilities for Selva applications",
5
5
  "license": "MIT",
6
6
  "author": "VektorNode",
@@ -31,12 +31,16 @@
31
31
  ".": {
32
32
  "selva-source": {
33
33
  "types": "./dist/index.d.ts",
34
- "svelte": "./dist/index.js"
34
+ "svelte": "./src/lib/index.ts"
35
35
  },
36
36
  "types": "./dist/public.d.ts",
37
37
  "svelte": "./dist/public.js"
38
38
  },
39
39
  "./external": {
40
+ "selva-source": {
41
+ "types": "./dist/external/storage.d.ts",
42
+ "svelte": "./src/lib/external/storage.ts"
43
+ },
40
44
  "types": "./dist/external/storage.d.ts",
41
45
  "svelte": "./dist/external/storage.js"
42
46
  },
@@ -59,10 +63,10 @@
59
63
  "svelte": "^5",
60
64
  "tailwind-variants": "^3.3.1",
61
65
  "three": "^0.186.1",
62
- "@selvajs/compute": "^4.2.1",
63
- "@selvajs/schemas": "^5.2.0",
64
- "@selvajs/solve": "^1.2.3-beta.0",
65
- "@selvajs/visualization": "^1.5.0"
66
+ "@selvajs/compute": "^5.0.0-beta.8",
67
+ "@selvajs/solve": "^2.0.0-beta.10",
68
+ "@selvajs/visualization": "^1.6.0-beta.6",
69
+ "@selvajs/schemas": "^5.3.0-beta.1"
66
70
  },
67
71
  "peerDependenciesMeta": {
68
72
  "three": {
@@ -71,8 +75,8 @@
71
75
  },
72
76
  "dependencies": {
73
77
  "@floating-ui/dom": "^1.8.0",
74
- "@iconify/svelte": "^5.2.1",
75
- "@lucide/svelte": "^1.48.0",
78
+ "@iconify/svelte": "^5.2.3",
79
+ "@lucide/svelte": "^1.61.0",
76
80
  "clsx": "^2.1.1",
77
81
  "mode-watcher": "^1.1.0",
78
82
  "paneforge": "^1.0.2",
@@ -85,16 +89,16 @@
85
89
  "@sveltejs/kit": "2.70.3",
86
90
  "@sveltejs/vite-plugin-svelte": "^7.3.1",
87
91
  "@types/three": "^0.186.0",
88
- "bits-ui": "^2.19.3",
92
+ "bits-ui": "^2.20.2",
89
93
  "rimraf": "^6.1.3",
90
- "svelte": "5.57.1",
94
+ "svelte": "5.57.2",
91
95
  "tailwind-variants": "^3.3.1",
92
- "vitest": "^5.0.2",
96
+ "vitest": "^5.0.5",
97
+ "@selvajs/compute": "5.0.0-beta.8",
93
98
  "@selvajs/config": "0.0.4",
94
- "@selvajs/compute": "4.2.1",
95
- "@selvajs/visualization": "1.5.0",
96
- "@selvajs/solve": "1.2.3-beta.0",
97
- "@selvajs/schemas": "5.2.0"
99
+ "@selvajs/schemas": "5.3.0-beta.1",
100
+ "@selvajs/visualization": "1.6.0-beta.6",
101
+ "@selvajs/solve": "2.0.0-beta.10"
98
102
  },
99
103
  "scripts": {
100
104
  "predev": "node ../../scripts/sync-shared-assets.js",
@@ -38,20 +38,12 @@
38
38
  <AlertDialog.Header>
39
39
  <AlertDialog.Title>{title}</AlertDialog.Title>
40
40
  {#if description}
41
- <AlertDialog.Description class={variant === 'destructive' ? 'text-destructive' : undefined}>
42
- {description}
43
- </AlertDialog.Description>
41
+ <AlertDialog.Description>{description}</AlertDialog.Description>
44
42
  {/if}
45
43
  </AlertDialog.Header>
46
44
  <AlertDialog.Footer>
47
45
  <AlertDialog.Cancel disabled={pending}>{cancelLabel}</AlertDialog.Cancel>
48
- <AlertDialog.Action
49
- onclick={handleConfirm}
50
- disabled={pending}
51
- class={variant === 'destructive'
52
- ? 'text-destructive-foreground bg-destructive hover:bg-destructive/90'
53
- : undefined}
54
- >
46
+ <AlertDialog.Action onclick={handleConfirm} disabled={pending} {variant}>
55
47
  {pending ? (pendingLabel ?? confirmLabel) : confirmLabel}
56
48
  </AlertDialog.Action>
57
49
  </AlertDialog.Footer>
@@ -2,6 +2,8 @@
2
2
  import { AlertCircle } from '@lucide/svelte';
3
3
  import * as Card from './primitives/card/index.js';
4
4
  import { Button } from './primitives/button/index.js';
5
+ import Callout from './primitives/Callout.svelte';
6
+ import { getLocaleContext } from '$lib/i18n/localeContext.svelte';
5
7
 
6
8
  interface Props {
7
9
  status?: number;
@@ -11,43 +13,35 @@
11
13
  }
12
14
 
13
15
  let { status = 500, message, details, homeLink = '/' }: Props = $props();
16
+
17
+ const locale = getLocaleContext();
18
+ const t = $derived(locale.messages);
14
19
  </script>
15
20
 
16
- <div class="p-4 flex min-h-screen items-center justify-center bg-background">
21
+ <div class="p-4 flex min-h-dvh items-center justify-center bg-background">
17
22
  <Card.Root class="max-w-md w-full">
18
- <Card.Header class="text-center">
19
- <div class="mb-4 flex justify-center">
23
+ <Card.Header>
24
+ <div class="gap-4 flex flex-col items-center text-center">
20
25
  <div class="p-3 rounded-full bg-destructive/10">
21
- <AlertCircle class="h-8 w-8 text-destructive" />
26
+ <AlertCircle class="size-8 text-destructive" />
22
27
  </div>
28
+ <h1 class="text-3xl font-semibold">{status}</h1>
23
29
  </div>
24
- <Card.Title class="text-3xl">{status}</Card.Title>
25
30
  </Card.Header>
26
- <Card.Content class="space-y-4">
27
- <div class="p-4 rounded-lg border border-destructive/50 bg-destructive/10">
28
- <div class="gap-3 flex">
29
- <AlertCircle class="mt-0.5 h-4 w-4 shrink-0 text-destructive" />
30
- <div class="flex-1">
31
- <p class="text-sm font-semibold text-destructive">Error</p>
32
- {#if message}
33
- <p class="text-sm text-destructive/80">{message}</p>
34
- {/if}
35
- </div>
36
- </div>
37
- </div>
38
-
39
- {#if details}
40
- <div class="p-4 rounded-lg bg-muted">
41
- <p class="font-mono text-sm break-all text-muted-foreground">
31
+ <Card.Content>
32
+ <div class="gap-4 flex flex-col">
33
+ <Callout tone="danger" title={t.errorTitle}>
34
+ {#if message}{message}{/if}
35
+ </Callout>
36
+ {#if details}
37
+ <p class="p-4 font-mono text-sm rounded-lg bg-muted break-all text-muted-foreground">
42
38
  {details}
43
39
  </p>
44
- </div>
45
- {/if}
40
+ {/if}
41
+ </div>
46
42
  </Card.Content>
47
- <Card.Footer class="gap-2 flex">
48
- <Button variant="outline" class="flex-1">
49
- <a href={homeLink} class="w-full" rel="external">Go Home</a>
50
- </Button>
43
+ <Card.Footer>
44
+ <Button variant="outline" href={homeLink} rel="external" class="w-full">{t.goHome}</Button>
51
45
  </Card.Footer>
52
46
  </Card.Root>
53
47
  </div>