@selvajs/ui 6.6.0-beta.8 → 7.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (373) hide show
  1. package/README.md +0 -3
  2. package/dist/components/ErrorScreen.svelte +1 -1
  3. package/dist/components/compute/AppLayout.svelte +95 -37
  4. package/dist/components/compute/AppLayout.svelte.d.ts +18 -1
  5. package/dist/components/compute/CollapsedPanelStrip.svelte +4 -2
  6. package/dist/components/compute/ComputeApp.svelte +6 -2
  7. package/dist/components/compute/ComputeApp.svelte.d.ts +1 -1
  8. package/dist/components/compute/ComputeMessagesDialog.svelte +3 -3
  9. package/dist/components/compute/ParameterPresetManager.svelte +9 -21
  10. package/dist/components/compute/SolveMessages.svelte +101 -87
  11. package/dist/components/compute/SolveMessages.svelte.d.ts +12 -0
  12. package/dist/components/layout/AppShell.svelte +2 -2
  13. package/dist/components/layout/FooterItemRenderer.svelte +2 -2
  14. package/dist/components/layout/FooterItemRenderer.svelte.d.ts +1 -1
  15. package/dist/components/layout/PageContent.svelte +3 -2
  16. package/dist/components/layout/PageFooter.svelte +8 -6
  17. package/dist/components/layout/PageHeader.svelte +3 -3
  18. package/dist/components/layout/SideNav.svelte +56 -15
  19. package/dist/components/layout/SubNav.svelte +2 -2
  20. package/dist/components/preview/ChartOutput.svelte +158 -62
  21. package/dist/components/preview/Group.svelte +14 -9
  22. package/dist/components/preview/HelpButton.svelte +1 -1
  23. package/dist/components/preview/ImageOutput.svelte +16 -11
  24. package/dist/components/preview/InputControl.svelte +115 -50
  25. package/dist/components/preview/InputControl.svelte.d.ts +5 -1
  26. package/dist/components/preview/OutputDisplay.svelte +26 -17
  27. package/dist/components/preview/TabBar.svelte +8 -6
  28. package/dist/components/preview/TabBar.svelte.d.ts +2 -0
  29. package/dist/components/preview/TabContent.svelte +65 -33
  30. package/dist/components/preview/TabContent.svelte.d.ts +5 -1
  31. package/dist/components/preview/TabLayout.svelte +29 -8
  32. package/dist/components/preview/TabLayout.svelte.d.ts +5 -0
  33. package/dist/components/preview/inputs/CheckboxInput.svelte +1 -1
  34. package/dist/components/preview/inputs/ChecklistInput.svelte +11 -6
  35. package/dist/components/preview/inputs/ChecklistInput.svelte.d.ts +2 -1
  36. package/dist/components/preview/inputs/ColorInput.svelte +356 -14
  37. package/dist/components/preview/inputs/ColorInput.svelte.d.ts +1 -0
  38. package/dist/components/preview/inputs/DropdownInput.svelte +18 -6
  39. package/dist/components/preview/inputs/DropdownInput.svelte.d.ts +2 -1
  40. package/dist/components/preview/inputs/FileInput.svelte +71 -75
  41. package/dist/components/preview/inputs/GeometryInput.svelte +128 -0
  42. package/dist/components/preview/inputs/GeometryInput.svelte.d.ts +21 -0
  43. package/dist/components/preview/inputs/NumberInput.svelte +8 -8
  44. package/dist/components/preview/inputs/OptionGlyph.svelte +29 -0
  45. package/dist/components/preview/inputs/OptionGlyph.svelte.d.ts +8 -0
  46. package/dist/components/preview/inputs/SegmentedInput.svelte +45 -0
  47. package/dist/components/preview/inputs/SegmentedInput.svelte.d.ts +12 -0
  48. package/dist/components/preview/inputs/TextInput.svelte +5 -5
  49. package/dist/components/preview/inputs/TileInput.svelte +83 -0
  50. package/dist/components/preview/inputs/TileInput.svelte.d.ts +12 -0
  51. package/dist/components/preview/inputs/index.d.ts +3 -0
  52. package/dist/components/preview/inputs/index.js +3 -0
  53. package/dist/components/primitives/CalculateButton.svelte +10 -4
  54. package/dist/components/primitives/Callout.svelte +8 -6
  55. package/dist/components/primitives/Callout.svelte.d.ts +4 -4
  56. package/dist/components/primitives/DataTable.svelte +1 -1
  57. package/dist/components/primitives/FilterableDropdown.svelte +13 -1
  58. package/dist/components/primitives/FilterableDropdown.svelte.d.ts +5 -0
  59. package/dist/components/primitives/ImageUploadField.svelte +1 -1
  60. package/dist/components/primitives/SolvingIndicator.svelte +245 -19
  61. package/dist/components/primitives/SolvingIndicator.svelte.d.ts +15 -0
  62. package/dist/components/primitives/alert-dialog/alert-dialog-content.svelte +1 -1
  63. package/dist/components/primitives/badge/badge.svelte +2 -2
  64. package/dist/components/primitives/badge/badge.svelte.d.ts +6 -6
  65. package/dist/components/primitives/button/button.svelte +9 -7
  66. package/dist/components/primitives/button/button.svelte.d.ts +19 -16
  67. package/dist/components/primitives/card/card.svelte +1 -1
  68. package/dist/components/primitives/card/card.svelte.d.ts +1 -1
  69. package/dist/components/primitives/checkbox/checkbox.svelte +1 -1
  70. package/dist/components/primitives/command/command-input.svelte +1 -1
  71. package/dist/components/primitives/command/command-item.svelte +1 -1
  72. package/dist/components/primitives/command/command-link-item.svelte +1 -1
  73. package/dist/components/primitives/command/command.svelte +1 -1
  74. package/dist/components/primitives/context-menu/context-menu-checkbox-item.svelte +1 -1
  75. package/dist/components/primitives/context-menu/context-menu-content.svelte +1 -1
  76. package/dist/components/primitives/context-menu/context-menu-item.svelte +1 -1
  77. package/dist/components/primitives/context-menu/context-menu-radio-item.svelte +1 -1
  78. package/dist/components/primitives/context-menu/context-menu-sub-content.svelte +1 -1
  79. package/dist/components/primitives/context-menu/context-menu-sub-trigger.svelte +1 -1
  80. package/dist/components/primitives/dialog/dialog-content.svelte +3 -3
  81. package/dist/components/primitives/drawer/Drawer.svelte +1 -1
  82. package/dist/components/primitives/dropdown-menu/dropdown-menu-checkbox-item.svelte +31 -11
  83. package/dist/components/primitives/dropdown-menu/dropdown-menu-checkbox-item.svelte.d.ts +2 -0
  84. package/dist/components/primitives/dropdown-menu/dropdown-menu-content.svelte +5 -1
  85. package/dist/components/primitives/dropdown-menu/dropdown-menu-content.svelte.d.ts +2 -0
  86. package/dist/components/primitives/dropdown-menu/dropdown-menu-item.svelte +4 -2
  87. package/dist/components/primitives/dropdown-menu/dropdown-menu-item.svelte.d.ts +2 -1
  88. package/dist/components/primitives/dropdown-menu/dropdown-menu-radio-item.svelte +1 -1
  89. package/dist/components/primitives/dropdown-menu/dropdown-menu-shortcut.svelte +1 -1
  90. package/dist/components/primitives/dropdown-menu/dropdown-menu-sub-content.svelte +1 -1
  91. package/dist/components/primitives/dropdown-menu/dropdown-menu-sub-trigger.svelte +1 -1
  92. package/dist/components/primitives/index.d.ts +1 -1
  93. package/dist/components/primitives/index.js +1 -1
  94. package/dist/components/primitives/input/input.svelte +2 -2
  95. package/dist/components/primitives/input-group/input-group-input.svelte.d.ts +1 -1
  96. package/dist/components/primitives/input-group/input-group.svelte +1 -1
  97. package/dist/components/primitives/mode-toggle/mode-toggle.svelte +2 -2
  98. package/dist/components/primitives/popover/popover-content.svelte +1 -1
  99. package/dist/components/primitives/resizable/resizable-handle.svelte +2 -2
  100. package/dist/components/primitives/search/search.svelte +1 -1
  101. package/dist/components/primitives/select/select-content.svelte +1 -1
  102. package/dist/components/primitives/select/select-item.svelte +1 -1
  103. package/dist/components/primitives/select/select-trigger.svelte +1 -1
  104. package/dist/components/primitives/slider/slider.svelte +1 -1
  105. package/dist/components/primitives/switch/switch.svelte +1 -1
  106. package/dist/components/primitives/tabs/tabs-list.svelte +2 -2
  107. package/dist/components/primitives/tabs/tabs-list.svelte.d.ts +6 -6
  108. package/dist/components/primitives/tabs/tabs-trigger.svelte +2 -2
  109. package/dist/components/primitives/tabs/tabs-trigger.svelte.d.ts +6 -6
  110. package/dist/components/primitives/textarea/textarea.svelte +1 -1
  111. package/dist/components/primitives/toggle/toggle.svelte +11 -3
  112. package/dist/components/primitives/toggle/toggle.svelte.d.ts +13 -4
  113. package/dist/components/primitives/toggle-group/toggle-group-item.svelte +1 -1
  114. package/dist/components/primitives/toggle-group/toggle-group.svelte +1 -1
  115. package/dist/components/primitives/tooltip/index.d.ts +6 -0
  116. package/dist/components/primitives/tooltip/index.js +8 -0
  117. package/dist/components/primitives/tooltip/tooltip-content.svelte +34 -0
  118. package/dist/components/primitives/tooltip/tooltip-content.svelte.d.ts +10 -0
  119. package/dist/components/primitives/tooltip/tooltip-portal.svelte +7 -0
  120. package/dist/components/primitives/tooltip/tooltip-portal.svelte.d.ts +4 -0
  121. package/dist/components/primitives/tooltip/tooltip-provider.svelte +7 -0
  122. package/dist/components/primitives/tooltip/tooltip-provider.svelte.d.ts +4 -0
  123. package/dist/components/primitives/tooltip/tooltip-trigger.svelte +7 -0
  124. package/dist/components/primitives/tooltip/tooltip-trigger.svelte.d.ts +4 -0
  125. package/dist/components/primitives/tooltip/tooltip.svelte +7 -0
  126. package/dist/components/primitives/tooltip/tooltip.svelte.d.ts +4 -0
  127. package/dist/components/viewer/MeshMetadataPanel.svelte +2 -2
  128. package/dist/components/viewer/SceneManager.svelte +32 -21
  129. package/dist/components/viewer/SceneManager.svelte.d.ts +3 -1
  130. package/dist/components/viewer/Viewer.svelte +135 -185
  131. package/dist/components/viewer/Viewer.svelte.d.ts +7 -2
  132. package/dist/components/viewer/ViewerDock.svelte +404 -0
  133. package/dist/components/viewer/ViewerDock.svelte.d.ts +42 -0
  134. package/dist/composables/useFooterItem.svelte.d.ts +1 -1
  135. package/dist/composables/useFooterItem.svelte.js +1 -1
  136. package/dist/compute/liveProgress.svelte.d.ts +16 -0
  137. package/dist/compute/liveProgress.svelte.js +90 -0
  138. package/dist/compute/solving.svelte.d.ts +11 -7
  139. package/dist/compute/solving.svelte.js +64 -45
  140. package/dist/constants.d.ts +6 -8
  141. package/dist/constants.js +8 -11
  142. package/dist/contexts/hostContext.svelte.d.ts +39 -0
  143. package/dist/contexts/hostContext.svelte.js +9 -0
  144. package/dist/features/chart/plotly-compat.d.ts +15 -0
  145. package/dist/features/chart/plotly-compat.js +124 -0
  146. package/dist/i18n/messages.d.ts +50 -0
  147. package/dist/i18n/messages.js +84 -0
  148. package/dist/index.d.ts +5 -0
  149. package/dist/index.js +5 -0
  150. package/dist/public.d.ts +1 -0
  151. package/dist/public.js +1 -0
  152. package/dist/schema/host-support.d.ts +29 -0
  153. package/dist/schema/host-support.js +97 -0
  154. package/dist/schema/option-display.d.ts +12 -0
  155. package/dist/schema/option-display.js +29 -0
  156. package/dist/schema/param-exporter.d.ts +4 -1
  157. package/dist/schema/param-exporter.js +10 -6
  158. package/dist/schema/visibility-rules.d.ts +7 -1
  159. package/dist/schema/visibility-rules.js +17 -0
  160. package/dist/styles/base.css +94 -84
  161. package/dist/utils/color-space.d.ts +21 -0
  162. package/dist/utils/color-space.js +90 -0
  163. package/dist/utils/file-download.js +6 -10
  164. package/dist/utils/host-files.d.ts +12 -0
  165. package/dist/utils/host-files.js +46 -0
  166. package/dist/utils/webp-to-png.d.ts +10 -0
  167. package/dist/utils/webp-to-png.js +41 -0
  168. package/package.json +31 -23
  169. package/src/lib/components/ErrorScreen.svelte +1 -1
  170. package/src/lib/components/compute/AppLayout.svelte +96 -38
  171. package/src/lib/components/compute/CollapsedPanelStrip.svelte +4 -2
  172. package/src/lib/components/compute/ComputeApp.svelte +6 -2
  173. package/src/lib/components/compute/ComputeMessagesDialog.svelte +4 -4
  174. package/src/lib/components/compute/ParameterPresetManager.svelte +9 -21
  175. package/src/lib/components/compute/SolveMessages.svelte +103 -89
  176. package/src/lib/components/layout/AppShell.svelte +2 -2
  177. package/src/lib/components/layout/FooterItemRenderer.svelte +2 -2
  178. package/src/lib/components/layout/PageContent.svelte +3 -2
  179. package/src/lib/components/layout/PageFooter.svelte +8 -6
  180. package/src/lib/components/layout/PageHeader.svelte +3 -3
  181. package/src/lib/components/layout/SideNav.svelte +56 -15
  182. package/src/lib/components/layout/SubNav.svelte +2 -2
  183. package/src/lib/components/preview/ChartOutput.svelte +158 -62
  184. package/src/lib/components/preview/Group.svelte +14 -9
  185. package/src/lib/components/preview/HelpButton.svelte +1 -1
  186. package/src/lib/components/preview/ImageOutput.svelte +16 -11
  187. package/src/lib/components/preview/InputControl.svelte +115 -50
  188. package/src/lib/components/preview/OutputDisplay.svelte +26 -17
  189. package/src/lib/components/preview/TabBar.svelte +8 -6
  190. package/src/lib/components/preview/TabContent.svelte +65 -33
  191. package/src/lib/components/preview/TabLayout.svelte +29 -8
  192. package/src/lib/components/preview/inputs/CheckboxInput.svelte +1 -1
  193. package/src/lib/components/preview/inputs/ChecklistInput.svelte +11 -6
  194. package/src/lib/components/preview/inputs/ColorInput.svelte +356 -14
  195. package/src/lib/components/preview/inputs/DropdownInput.svelte +18 -6
  196. package/src/lib/components/preview/inputs/FileInput.svelte +71 -75
  197. package/src/lib/components/preview/inputs/GeometryInput.svelte +128 -0
  198. package/src/lib/components/preview/inputs/NumberInput.svelte +8 -8
  199. package/src/lib/components/preview/inputs/OptionGlyph.svelte +29 -0
  200. package/src/lib/components/preview/inputs/SegmentedInput.svelte +45 -0
  201. package/src/lib/components/preview/inputs/TextInput.svelte +5 -5
  202. package/src/lib/components/preview/inputs/TileInput.svelte +83 -0
  203. package/src/lib/components/preview/inputs/index.ts +3 -0
  204. package/src/lib/components/primitives/CalculateButton.svelte +10 -4
  205. package/src/lib/components/primitives/Callout.svelte +9 -7
  206. package/src/lib/components/primitives/DataTable.svelte +1 -1
  207. package/src/lib/components/primitives/FilterableDropdown.svelte +14 -2
  208. package/src/lib/components/primitives/ImageUploadField.svelte +1 -1
  209. package/src/lib/components/primitives/IssueList.svelte +1 -1
  210. package/src/lib/components/primitives/SeverityIcon.svelte +1 -1
  211. package/src/lib/components/primitives/SolvingIndicator.svelte +245 -19
  212. package/src/lib/components/primitives/StateDisplay.svelte +1 -1
  213. package/src/lib/components/primitives/alert-dialog/alert-dialog-action.svelte +2 -2
  214. package/src/lib/components/primitives/alert-dialog/alert-dialog-cancel.svelte +2 -2
  215. package/src/lib/components/primitives/alert-dialog/alert-dialog-content.svelte +2 -2
  216. package/src/lib/components/primitives/alert-dialog/alert-dialog-description.svelte +1 -1
  217. package/src/lib/components/primitives/alert-dialog/alert-dialog-footer.svelte +1 -1
  218. package/src/lib/components/primitives/alert-dialog/alert-dialog-header.svelte +1 -1
  219. package/src/lib/components/primitives/alert-dialog/alert-dialog-overlay.svelte +1 -1
  220. package/src/lib/components/primitives/alert-dialog/alert-dialog-title.svelte +1 -1
  221. package/src/lib/components/primitives/badge/badge.svelte +3 -3
  222. package/src/lib/components/primitives/button/button.svelte +9 -7
  223. package/src/lib/components/primitives/button-group/button-group-separator.svelte +2 -2
  224. package/src/lib/components/primitives/button-group/button-group-text.svelte +1 -1
  225. package/src/lib/components/primitives/button-group/button-group.svelte +1 -1
  226. package/src/lib/components/primitives/card/card-content.svelte +1 -1
  227. package/src/lib/components/primitives/card/card-description.svelte +1 -1
  228. package/src/lib/components/primitives/card/card-footer.svelte +1 -1
  229. package/src/lib/components/primitives/card/card-header.svelte +1 -1
  230. package/src/lib/components/primitives/card/card-title.svelte +1 -1
  231. package/src/lib/components/primitives/card/card.svelte +2 -2
  232. package/src/lib/components/primitives/checkbox/checkbox.svelte +2 -2
  233. package/src/lib/components/primitives/command/command-dialog.svelte +2 -2
  234. package/src/lib/components/primitives/command/command-empty.svelte +1 -1
  235. package/src/lib/components/primitives/command/command-group.svelte +1 -1
  236. package/src/lib/components/primitives/command/command-input.svelte +3 -3
  237. package/src/lib/components/primitives/command/command-item.svelte +2 -2
  238. package/src/lib/components/primitives/command/command-link-item.svelte +2 -2
  239. package/src/lib/components/primitives/command/command-list.svelte +1 -1
  240. package/src/lib/components/primitives/command/command-separator.svelte +1 -1
  241. package/src/lib/components/primitives/command/command-shortcut.svelte +1 -1
  242. package/src/lib/components/primitives/command/command.svelte +2 -2
  243. package/src/lib/components/primitives/context-menu/context-menu-checkbox-item.svelte +2 -2
  244. package/src/lib/components/primitives/context-menu/context-menu-content.svelte +2 -2
  245. package/src/lib/components/primitives/context-menu/context-menu-group-heading.svelte +1 -1
  246. package/src/lib/components/primitives/context-menu/context-menu-item.svelte +2 -2
  247. package/src/lib/components/primitives/context-menu/context-menu-label.svelte +1 -1
  248. package/src/lib/components/primitives/context-menu/context-menu-radio-item.svelte +2 -2
  249. package/src/lib/components/primitives/context-menu/context-menu-separator.svelte +1 -1
  250. package/src/lib/components/primitives/context-menu/context-menu-shortcut.svelte +1 -1
  251. package/src/lib/components/primitives/context-menu/context-menu-sub-content.svelte +2 -2
  252. package/src/lib/components/primitives/context-menu/context-menu-sub-trigger.svelte +2 -2
  253. package/src/lib/components/primitives/dialog/dialog-content.svelte +4 -4
  254. package/src/lib/components/primitives/dialog/dialog-description.svelte +1 -1
  255. package/src/lib/components/primitives/dialog/dialog-footer.svelte +1 -1
  256. package/src/lib/components/primitives/dialog/dialog-header.svelte +1 -1
  257. package/src/lib/components/primitives/dialog/dialog-overlay.svelte +1 -1
  258. package/src/lib/components/primitives/dialog/dialog-title.svelte +1 -1
  259. package/src/lib/components/primitives/drawer/Drawer.svelte +1 -1
  260. package/src/lib/components/primitives/dropdown-menu/dropdown-menu-checkbox-item.svelte +32 -12
  261. package/src/lib/components/primitives/dropdown-menu/dropdown-menu-content.svelte +6 -2
  262. package/src/lib/components/primitives/dropdown-menu/dropdown-menu-group-heading.svelte +1 -1
  263. package/src/lib/components/primitives/dropdown-menu/dropdown-menu-item.svelte +5 -3
  264. package/src/lib/components/primitives/dropdown-menu/dropdown-menu-label.svelte +1 -1
  265. package/src/lib/components/primitives/dropdown-menu/dropdown-menu-radio-item.svelte +2 -2
  266. package/src/lib/components/primitives/dropdown-menu/dropdown-menu-separator.svelte +1 -1
  267. package/src/lib/components/primitives/dropdown-menu/dropdown-menu-shortcut.svelte +2 -2
  268. package/src/lib/components/primitives/dropdown-menu/dropdown-menu-sub-content.svelte +2 -2
  269. package/src/lib/components/primitives/dropdown-menu/dropdown-menu-sub-trigger.svelte +2 -2
  270. package/src/lib/components/primitives/empty/empty-content.svelte +1 -1
  271. package/src/lib/components/primitives/empty/empty-description.svelte +1 -1
  272. package/src/lib/components/primitives/empty/empty-header.svelte +1 -1
  273. package/src/lib/components/primitives/empty/empty-media.svelte +1 -1
  274. package/src/lib/components/primitives/empty/empty-title.svelte +1 -1
  275. package/src/lib/components/primitives/empty/empty.svelte +1 -1
  276. package/src/lib/components/primitives/field/field-content.svelte +1 -1
  277. package/src/lib/components/primitives/field/field-description.svelte +1 -1
  278. package/src/lib/components/primitives/field/field-error.svelte +1 -1
  279. package/src/lib/components/primitives/field/field-group.svelte +1 -1
  280. package/src/lib/components/primitives/field/field-label.svelte +2 -2
  281. package/src/lib/components/primitives/field/field-legend.svelte +1 -1
  282. package/src/lib/components/primitives/field/field-separator.svelte +2 -2
  283. package/src/lib/components/primitives/field/field-set.svelte +1 -1
  284. package/src/lib/components/primitives/field/field-title.svelte +1 -1
  285. package/src/lib/components/primitives/field/field.svelte +1 -1
  286. package/src/lib/components/primitives/index.ts +1 -1
  287. package/src/lib/components/primitives/input/input.svelte +3 -3
  288. package/src/lib/components/primitives/input-group/input-group-addon.svelte +1 -1
  289. package/src/lib/components/primitives/input-group/input-group-button.svelte +2 -2
  290. package/src/lib/components/primitives/input-group/input-group-input.svelte +2 -2
  291. package/src/lib/components/primitives/input-group/input-group-text.svelte +1 -1
  292. package/src/lib/components/primitives/input-group/input-group-textarea.svelte +2 -2
  293. package/src/lib/components/primitives/input-group/input-group.svelte +2 -2
  294. package/src/lib/components/primitives/label/label.svelte +1 -1
  295. package/src/lib/components/primitives/mode-toggle/mode-toggle.svelte +2 -2
  296. package/src/lib/components/primitives/popover/popover-content.svelte +2 -2
  297. package/src/lib/components/primitives/popover/popover-description.svelte +1 -1
  298. package/src/lib/components/primitives/popover/popover-header.svelte +1 -1
  299. package/src/lib/components/primitives/popover/popover-title.svelte +1 -1
  300. package/src/lib/components/primitives/popover/popover-trigger.svelte +1 -1
  301. package/src/lib/components/primitives/resizable/resizable-handle.svelte +3 -3
  302. package/src/lib/components/primitives/resizable/resizable-pane-group.svelte +1 -1
  303. package/src/lib/components/primitives/scroll-area/scroll-area-scrollbar.svelte +1 -1
  304. package/src/lib/components/primitives/scroll-area/scroll-area.svelte +1 -1
  305. package/src/lib/components/primitives/search/search.svelte +2 -2
  306. package/src/lib/components/primitives/select/select-content.svelte +2 -2
  307. package/src/lib/components/primitives/select/select-group-heading.svelte +1 -1
  308. package/src/lib/components/primitives/select/select-item.svelte +2 -2
  309. package/src/lib/components/primitives/select/select-label.svelte +1 -1
  310. package/src/lib/components/primitives/select/select-scroll-down-button.svelte +1 -1
  311. package/src/lib/components/primitives/select/select-scroll-up-button.svelte +1 -1
  312. package/src/lib/components/primitives/select/select-separator.svelte +2 -2
  313. package/src/lib/components/primitives/select/select-trigger.svelte +2 -2
  314. package/src/lib/components/primitives/separator/separator.svelte +1 -1
  315. package/src/lib/components/primitives/slider/slider.svelte +2 -2
  316. package/src/lib/components/primitives/spinner/spinner.svelte +1 -1
  317. package/src/lib/components/primitives/switch/switch.svelte +2 -2
  318. package/src/lib/components/primitives/tabs/tabs-content.svelte +1 -1
  319. package/src/lib/components/primitives/tabs/tabs-list.svelte +3 -3
  320. package/src/lib/components/primitives/tabs/tabs-trigger.svelte +3 -3
  321. package/src/lib/components/primitives/tabs/tabs.svelte +1 -1
  322. package/src/lib/components/primitives/textarea/textarea.svelte +2 -2
  323. package/src/lib/components/primitives/toggle/toggle.svelte +12 -4
  324. package/src/lib/components/primitives/toggle-group/toggle-group-item.svelte +3 -3
  325. package/src/lib/components/primitives/toggle-group/toggle-group.svelte +3 -3
  326. package/src/lib/components/primitives/tooltip/index.ts +19 -0
  327. package/src/lib/components/primitives/tooltip/tooltip-content.svelte +34 -0
  328. package/src/lib/components/primitives/tooltip/tooltip-portal.svelte +7 -0
  329. package/src/lib/components/primitives/tooltip/tooltip-provider.svelte +7 -0
  330. package/src/lib/components/primitives/tooltip/tooltip-trigger.svelte +7 -0
  331. package/src/lib/components/primitives/tooltip/tooltip.svelte +7 -0
  332. package/src/lib/components/viewer/MeshMetadataPanel.svelte +2 -2
  333. package/src/lib/components/viewer/SceneManager.svelte +32 -21
  334. package/src/lib/components/viewer/Viewer.svelte +136 -186
  335. package/src/lib/components/viewer/ViewerDock.svelte +404 -0
  336. package/src/lib/composables/useFooterItem.svelte.ts +1 -1
  337. package/src/lib/compute/liveProgress.svelte.ts +103 -0
  338. package/src/lib/compute/solving.svelte.ts +66 -50
  339. package/src/lib/constants.ts +8 -11
  340. package/src/lib/contexts/hostContext.svelte.ts +51 -0
  341. package/src/lib/features/chart/plotly-compat.ts +141 -0
  342. package/src/lib/i18n/messages.ts +139 -0
  343. package/src/lib/index.ts +22 -0
  344. package/src/lib/public.ts +1 -0
  345. package/src/lib/schema/host-support.ts +129 -0
  346. package/src/lib/schema/option-display.ts +44 -0
  347. package/src/lib/schema/param-exporter.ts +10 -7
  348. package/src/lib/schema/visibility-rules.ts +27 -1
  349. package/src/lib/styles/base.css +94 -84
  350. package/src/lib/utils/color-space.ts +107 -0
  351. package/src/lib/utils/file-download.ts +7 -11
  352. package/src/lib/utils/host-files.ts +61 -0
  353. package/src/lib/utils/webp-to-png.ts +48 -0
  354. package/dist/components/primitives/theme-switcher/ThemeSwitcher.svelte +0 -39
  355. package/dist/components/primitives/theme-switcher/ThemeSwitcher.svelte.d.ts +0 -3
  356. package/dist/components/primitives/theme-switcher/index.d.ts +0 -1
  357. package/dist/components/primitives/theme-switcher/index.js +0 -1
  358. package/dist/styles/themes/cyberpunk.css +0 -98
  359. package/dist/styles/themes/neutral.css +0 -72
  360. package/dist/styles/themes/ocean.css +0 -75
  361. package/dist/styles/themes/selva.css +0 -105
  362. package/dist/theme/themeStore.svelte.d.ts +0 -12
  363. package/dist/theme/themeStore.svelte.js +0 -40
  364. package/dist/theme/themes.d.ts +0 -5
  365. package/dist/theme/themes.js +0 -13
  366. package/src/lib/components/primitives/theme-switcher/ThemeSwitcher.svelte +0 -39
  367. package/src/lib/components/primitives/theme-switcher/index.ts +0 -1
  368. package/src/lib/styles/themes/cyberpunk.css +0 -98
  369. package/src/lib/styles/themes/neutral.css +0 -72
  370. package/src/lib/styles/themes/ocean.css +0 -75
  371. package/src/lib/styles/themes/selva.css +0 -105
  372. package/src/lib/theme/themeStore.svelte.ts +0 -50
  373. package/src/lib/theme/themes.ts +0 -18
package/README.md CHANGED
@@ -57,9 +57,6 @@ In your `app.css`:
57
57
  @import '@selvajs/ui/styles/base.css';
58
58
  ```
59
59
 
60
- Themes are available under `@selvajs/ui/styles/themes/*` — `selva`, `neutral`, `ocean`, and
61
- `cyberpunk`.
62
-
63
60
  ## Schema types
64
61
 
65
62
  Types generated from `packages/schemas/ui-schema.json` are published by `@selvajs/schemas`, not
@@ -3,7 +3,7 @@
3
3
  import * as Card from './primitives/card/index.js';
4
4
  import { Button } from './primitives/button/index.js';
5
5
  import Callout from './primitives/Callout.svelte';
6
- import { getLocaleContext } from '../i18n/localeContext.svelte';
6
+ import { getLocaleContext } from '../i18n/localeContext.svelte.js';
7
7
 
8
8
  interface Props {
9
9
  status?: number;
@@ -1,6 +1,7 @@
1
1
  <script lang="ts">
2
+ import type { Snippet } from 'svelte';
2
3
  import type { UISchema, SupportedTypes, ParameterPreset } from '@selvajs/schemas';
3
- import type { SolveSettlement } from '@selvajs/solve/client';
4
+ import type { LiveSolveState, SolveSettlement } from '@selvajs/solve/client';
4
5
  import type { ActionButton } from '../../types/actionButton';
5
6
  import type { PresetLabels } from '../../types/presetLabels';
6
7
  import { ChevronUp, Download, Ellipsis, Upload } from '@lucide/svelte';
@@ -10,9 +11,9 @@
10
11
  import SolvingIndicator from '../primitives/SolvingIndicator.svelte';
11
12
  import TabLayout from '../preview/TabLayout.svelte';
12
13
  import CollapsedPanelStrip from './CollapsedPanelStrip.svelte';
13
- import * as Resizable from '../primitives/resizable';
14
+ import * as Resizable from '../primitives/resizable/index.js';
14
15
  import * as DropdownMenu from '../primitives/dropdown-menu/index.js';
15
- import { Button } from '../..';
16
+ import { Button } from '../../index.js';
16
17
  import ParameterPresetManager from './ParameterPresetManager.svelte';
17
18
  import { runPanelAction } from '../../compute/run-panel-action';
18
19
  import { getLocaleContext } from '../../i18n/localeContext.svelte';
@@ -33,7 +34,23 @@
33
34
  showViewer: boolean;
34
35
  meshes?: any[];
35
36
  isSolving: boolean;
37
+ /**
38
+ * `createSolvingIndicator(...).show`, not `isSolving`: grows the action row's solve status,
39
+ * which would otherwise flash on every sub-second solve.
40
+ */
36
41
  showSolvingIndicator?: boolean;
42
+ /** `createSolvingIndicator(...).slow`: the solve status grows into a card with progress. */
43
+ solveIsSlow?: boolean;
44
+ /** The session's live channel: step, count and bar for that card. */
45
+ live?: LiveSolveState;
46
+ /** Abort in that card. The host's `SolveMessages` should then take `progressShownByHost`. */
47
+ onabort?: () => void;
48
+ /** As passed to `createSolvingIndicator`. */
49
+ freezesDuringSolve?: boolean;
50
+ /** @deprecated Ignored: the solving status always sits in the action row. */
51
+ solvingIndicatorPlacement?: 'floating' | 'inline';
52
+ /** Rendered above the action row, for a host that keeps the solve's messages in the flow. */
53
+ solveMessages?: Snippet;
37
54
  hasPendingChanges?: boolean;
38
55
  hasNeverSolved?: boolean;
39
56
  isViewerFullscreen?: boolean;
@@ -63,6 +80,11 @@
63
80
  meshes = [],
64
81
  isSolving,
65
82
  showSolvingIndicator = false,
83
+ solveIsSlow = false,
84
+ live,
85
+ onabort,
86
+ freezesDuringSolve = false,
87
+ solveMessages,
66
88
  hasPendingChanges = false,
67
89
  hasNeverSolved = false,
68
90
  isViewerFullscreen = $bindable(false),
@@ -143,6 +165,14 @@
143
165
  return () => mqMobile.removeEventListener('change', update);
144
166
  });
145
167
 
168
+ // Without a viewer there's nothing to sit beside, so a narrow host (a docked Rhino panel) gets
169
+ // the phone's single edge-to-edge column instead of a card floating in its own margins.
170
+ const STACK_BELOW_WIDTH = 900;
171
+ let rootWidth = $state(0);
172
+ const stacked = $derived(
173
+ isMobile || (!hasViewer && rootWidth > 0 && rootWidth < STACK_BELOW_WIDTH)
174
+ );
175
+
146
176
  let leftCollapsed = $state(false);
147
177
  let rightCollapsed = $state(false);
148
178
  let leftPaneRef = $state<{ expand: () => void } | null>(null);
@@ -248,6 +278,9 @@
248
278
  <!-- One primary action and one menu. A definition that solves on every change has no Calculate,
249
279
  so the menu sits alone at the end of the row. -->
250
280
  {#snippet footer()}
281
+ <!-- No wrapper: it would always render (the messages' live region is never empty) and pick up
282
+ the drawer footer's row padding, leaving a gap above Calculate with nothing in it. -->
283
+ {@render solveMessages?.()}
251
284
  {#if schema.instanceSolve === false}
252
285
  <CalculateButton
253
286
  {hasPendingChanges}
@@ -256,9 +289,19 @@
256
289
  {oncalculate}
257
290
  trailing={hasMenu ? actionsMenu : undefined}
258
291
  />
259
- {:else if hasMenu}
260
- <div class="mt-3 pb-3 pt-2 px-2 flex justify-end border-t border-border/50">
261
- {@render actionsMenu()}
292
+ {:else}
293
+ <div class="mt-3 pb-3 pt-2 px-2 gap-2 flex items-center border-t border-border">
294
+ <SolvingIndicator
295
+ {isSolving}
296
+ show={showSolvingIndicator}
297
+ slow={solveIsSlow}
298
+ {live}
299
+ {onabort}
300
+ {freezesDuringSolve}
301
+ />
302
+ {#if hasMenu}
303
+ {@render actionsMenu()}
304
+ {/if}
262
305
  </div>
263
306
  {/if}
264
307
  {/snippet}
@@ -272,9 +315,9 @@
272
315
  )}
273
316
  <div class="panel-content-wrapper">
274
317
  {#if schema.layout.type === 'tabbed'}
275
- <TabLayout {schema} {values} {onValueChange} {panelFilter} {requestedTabId} />
318
+ <TabLayout {schema} {values} {onValueChange} {panelFilter} {requestedTabId} bare={stacked} />
276
319
  {/if}
277
- {#if hostsFooter && !isMobile}
320
+ {#if hostsFooter && !stacked}
278
321
  <div class="panel-footer px-1">
279
322
  {@render footer()}
280
323
  </div>
@@ -291,15 +334,16 @@
291
334
 
292
335
  <main
293
336
  data-layout-root
294
- class="min-h-0 sm:flex-row sm:py-(--page-py) flex flex-1 flex-col overflow-hidden {leftCollapsed
295
- ? 'sm:pl-0'
296
- : 'sm:pl-(--page-px)'} {rightCollapsed ? 'sm:pr-0' : 'sm:pr-(--page-px)'}"
337
+ class="min-h-0 flex flex-1 flex-col overflow-hidden {stacked
338
+ ? ''
339
+ : `sm:flex-row sm:py-2 ${leftCollapsed ? 'sm:pl-0' : 'sm:pl-2'} ${rightCollapsed ? 'sm:pr-0' : 'sm:pr-2'}`}"
297
340
  class:fullscreen-layout={isViewerFullscreen}
298
341
  class:relative={isMobile}
299
- class:mobile-root={isMobile}
342
+ class:mobile-root={stacked}
343
+ bind:clientWidth={rootWidth}
300
344
  >
301
- {#if isMobile}
302
- {#if hasViewer}
345
+ {#if stacked}
346
+ {#if isMobile && hasViewer}
303
347
  <!-- Ends above the drawer rather than behind it, so the model stays centred in what is
304
348
  visible. It jumps straight to its new size: animating it would resize the canvas,
305
349
  and its render targets, on every frame of the drawer's slide. -->
@@ -307,20 +351,20 @@
307
351
  <Viewer
308
352
  {meshes}
309
353
  bind:isFullscreen={isViewerFullscreen}
310
- {isSolving}
311
354
  drawerOpen={drawer === 'full'}
312
355
  {logoUrl}
313
356
  {onViewerReady}
314
357
  viewerConfig={{
315
358
  ...viewerConfig,
316
- backgroundColor: schema?.viewerOptions?.backgroundColor,
359
+ backgroundColor: schema?.viewerOptions?.backgroundColor ?? viewerConfig.backgroundColor,
360
+ look: schema?.viewerOptions?.look ?? viewerConfig.look,
317
361
  showSceneManager: false
318
362
  }}
319
363
  />
320
364
  </div>
321
365
 
322
366
  <div
323
- class="drawer-container rounded-t-2xl z-40 border-t bg-background shadow-sheet drawer-{drawer}"
367
+ class="drawer-container z-40 rounded-t-xl border-t bg-background shadow-sheet drawer-{drawer}"
324
368
  >
325
369
  <!-- Named by its visible label; aria-expanded carries the open/closed state. -->
326
370
  <button
@@ -344,7 +388,7 @@
344
388
  <!-- Inert while closed: the fields are clipped out of view, and tabbing into them
345
389
  would scroll the drawer's insides around behind the handle. -->
346
390
  <div class="drawer-content" inert={drawer === 'closed'}>
347
- <div class="px-3 pb-6">
391
+ <div class="px-2 pb-4">
348
392
  {#if hasLeftPanel}
349
393
  {@render panelContent(hasRightPanel ? 'left' : undefined, requestedLeftTabId, false)}
350
394
  {/if}
@@ -366,7 +410,7 @@
366
410
  </div>
367
411
  {:else}
368
412
  <div class="flex flex-1 flex-col overflow-hidden">
369
- <div class="px-3 pt-3 flex-1 overflow-y-auto">
413
+ <div class="px-3 pt-3 sm:px-5 flex-1 overflow-y-auto">
370
414
  {#if hasLeftPanel}
371
415
  {@render panelContent(hasRightPanel ? 'left' : undefined, requestedLeftTabId, false)}
372
416
  {/if}
@@ -386,7 +430,7 @@
386
430
  {/if}
387
431
  {:else if !hasViewer && !isTwoPanelMode && hasLeftPanel !== hasRightPanel}
388
432
  <!-- Single centered panel (left-only or right-only), no viewer -->
389
- <div class="min-h-0 flex h-full flex-1 justify-center">
433
+ <div class="min-h-0 p-1 flex h-full flex-1 justify-center">
390
434
  <div class="min-h-0 flex h-full w-4/5 flex-col">
391
435
  {@render panelContent(
392
436
  hasRightPanel ? 'right' : undefined,
@@ -413,7 +457,7 @@
413
457
  <Resizable.PaneGroup
414
458
  direction="horizontal"
415
459
  autoSaveId="selva-layout-{layoutKey}"
416
- class="min-h-0 flex-1"
460
+ class="min-h-0 m-1 flex-1"
417
461
  >
418
462
  {#if hasLeftPanel}
419
463
  <Resizable.Pane
@@ -426,7 +470,6 @@
426
470
  collapsedSize={0}
427
471
  onCollapse={() => (leftCollapsed = true)}
428
472
  onExpand={() => (leftCollapsed = false)}
429
- class="ml-1"
430
473
  >
431
474
  <div
432
475
  class="min-h-0 flex h-full flex-col {isViewerFullscreen || leftCollapsed
@@ -439,6 +482,7 @@
439
482
  <Resizable.Handle
440
483
  withHandle
441
484
  line={false}
485
+ class="translate-x-1.5 z-20"
442
486
  data-collapsed={leftCollapsed}
443
487
  onclick={() => {
444
488
  if (leftCollapsed) leftPaneRef?.expand();
@@ -447,30 +491,34 @@
447
491
  {/if}
448
492
 
449
493
  {#if hasViewer}
450
- <Resizable.Pane order={2} minSize={20} class="min-h-0 mx-1 flex flex-col">
494
+ <Resizable.Pane order={2} minSize={20} class="min-h-0 flex flex-col">
451
495
  <Viewer
452
496
  {meshes}
453
497
  bind:isFullscreen={isViewerFullscreen}
454
- {isSolving}
455
498
  {logoUrl}
456
499
  {onViewerReady}
457
500
  viewerConfig={{
458
501
  ...viewerConfig,
459
- backgroundColor: schema?.viewerOptions?.backgroundColor
502
+ backgroundColor:
503
+ schema?.viewerOptions?.backgroundColor ?? viewerConfig.backgroundColor,
504
+ look: schema?.viewerOptions?.look ?? viewerConfig.look
460
505
  }}
461
506
  />
462
507
  </Resizable.Pane>
463
508
  {/if}
464
509
 
465
510
  {#if hasRightPanel}
466
- <Resizable.Handle
467
- withHandle
468
- line={false}
469
- data-collapsed={rightCollapsed}
470
- onclick={() => {
471
- if (rightCollapsed) rightPaneRef?.expand();
472
- }}
473
- />
511
+ {#if hasViewer || !hasLeftPanel}
512
+ <Resizable.Handle
513
+ withHandle
514
+ line={false}
515
+ class="-translate-x-1.5 z-20"
516
+ data-collapsed={rightCollapsed}
517
+ onclick={() => {
518
+ if (rightCollapsed) rightPaneRef?.expand();
519
+ }}
520
+ />
521
+ {/if}
474
522
  <Resizable.Pane
475
523
  bind:this={rightPaneRef}
476
524
  order={3}
@@ -481,7 +529,6 @@
481
529
  collapsedSize={0}
482
530
  onCollapse={() => (rightCollapsed = true)}
483
531
  onExpand={() => (rightCollapsed = false)}
484
- class="mr-1"
485
532
  >
486
533
  <div
487
534
  class="min-h-0 flex h-full flex-col {isViewerFullscreen || rightCollapsed
@@ -508,8 +555,6 @@
508
555
  {/if}
509
556
  </div>
510
557
  {/if}
511
-
512
- <SolvingIndicator show={showSolvingIndicator} />
513
558
  </main>
514
559
 
515
560
  <!-- The save, load and validation dialogs; the footer's menu opens them. -->
@@ -555,7 +600,13 @@
555
600
 
556
601
  .mobile-root {
557
602
  --drawer-closed-h: 60px;
558
- --drawer-half-h: 50%;
603
+ --drawer-half-h: 60%;
604
+ }
605
+
606
+ /* On a phone the panels stack in one scroller. Held at the scroller's height, a long left
607
+ panel would spill over the right panel below it. */
608
+ .mobile-root .panel-content-wrapper {
609
+ height: auto;
559
610
  }
560
611
 
561
612
  .viewer-region {
@@ -633,6 +684,13 @@
633
684
  padding: 0rem 1rem;
634
685
  }
635
686
 
687
+ /* The sheet's top edge already separates it from the model; the desktop footer's extra
688
+ spacing only takes rows from the fields. */
689
+ .drawer-footer :global(> div) {
690
+ margin-top: 0;
691
+ padding-block: 0.5rem;
692
+ }
693
+
636
694
  /* Touch gets 44px targets on the panel's controls; a fine pointer keeps the denser sizes. */
637
695
  @media (pointer: coarse) {
638
696
  .panel-content-wrapper
@@ -1,5 +1,6 @@
1
+ import type { Snippet } from 'svelte';
1
2
  import type { UISchema, SupportedTypes, ParameterPreset } from '@selvajs/schemas';
2
- import type { SolveSettlement } from '@selvajs/solve/client';
3
+ import type { LiveSolveState, SolveSettlement } from '@selvajs/solve/client';
3
4
  import type { ActionButton } from '../../types/actionButton';
4
5
  import type { PresetLabels } from '../../types/presetLabels';
5
6
  import type { ThreeViewer } from '@selvajs/visualization/render';
@@ -13,7 +14,23 @@ interface Props {
13
14
  showViewer: boolean;
14
15
  meshes?: any[];
15
16
  isSolving: boolean;
17
+ /**
18
+ * `createSolvingIndicator(...).show`, not `isSolving`: grows the action row's solve status,
19
+ * which would otherwise flash on every sub-second solve.
20
+ */
16
21
  showSolvingIndicator?: boolean;
22
+ /** `createSolvingIndicator(...).slow`: the solve status grows into a card with progress. */
23
+ solveIsSlow?: boolean;
24
+ /** The session's live channel: step, count and bar for that card. */
25
+ live?: LiveSolveState;
26
+ /** Abort in that card. The host's `SolveMessages` should then take `progressShownByHost`. */
27
+ onabort?: () => void;
28
+ /** As passed to `createSolvingIndicator`. */
29
+ freezesDuringSolve?: boolean;
30
+ /** @deprecated Ignored: the solving status always sits in the action row. */
31
+ solvingIndicatorPlacement?: 'floating' | 'inline';
32
+ /** Rendered above the action row, for a host that keeps the solve's messages in the flow. */
33
+ solveMessages?: Snippet;
17
34
  hasPendingChanges?: boolean;
18
35
  hasNeverSolved?: boolean;
19
36
  isViewerFullscreen?: boolean;
@@ -20,12 +20,14 @@
20
20
  [
21
21
  'gap-1 py-2 lg:py-3 lg:flex-col lg:w-auto px-2 lg:px-0',
22
22
  'flex w-full shrink-0 flex-row items-center',
23
- 'backdrop-blur-sm bg-background/90 cursor-pointer'
23
+ 'backdrop-blur-sm bg-background/90 cursor-pointer',
24
+ side === 'left' ? 'lg:border-r' : 'lg:border-l',
25
+ 'border-border'
24
26
  ].join(' ')
25
27
  );
26
28
 
27
29
  const tabButtonClass =
28
- 'w-8 h-8 rounded cursor-pointer flex shrink-0 items-center justify-center text-muted-foreground transition-colors hover:bg-accent hover:text-foreground';
30
+ 'w-8 h-8 rounded-md cursor-pointer flex shrink-0 items-center justify-center text-muted-foreground transition-colors hover:bg-hover hover:text-foreground';
29
31
  </script>
30
32
 
31
33
  <div
@@ -57,7 +57,7 @@
57
57
  footerText?: string;
58
58
  /**
59
59
  * How long one solve may take before the client aborts it (ms). Pass the same value the
60
- * server enforces (`COMPUTE_SOLVE_DEADLINE_MS`), or the client aborts solves that would
60
+ * server enforces for this definition's compute server, or the client aborts solves that would
61
61
  * have finished.
62
62
  */
63
63
  solveDeadlineMs: number;
@@ -286,7 +286,10 @@
286
286
  showViewer={!!schema.viewerOptions?.enableRemote}
287
287
  meshes={session.meshes}
288
288
  isSolving={session.isSolving}
289
- showSolvingIndicator={schema.instanceSolve !== false && solvingIndicator.show}
289
+ showSolvingIndicator={solvingIndicator.show}
290
+ solveIsSlow={solvingIndicator.slow}
291
+ live={session.live}
292
+ onabort={() => session.abort()}
290
293
  hasPendingChanges={session.hasPendingChanges}
291
294
  hasNeverSolved={session.hasNeverSolved}
292
295
  bind:isViewerFullscreen
@@ -317,4 +320,5 @@
317
320
  onabort={() => session.abort()}
318
321
  onconfirm={() => session.acknowledge()}
319
322
  ondiscard={() => session.discard()}
323
+ progressShownByHost={schema?.instanceSolve !== false}
320
324
  />
@@ -36,7 +36,7 @@ interface Props {
36
36
  footerText?: string;
37
37
  /**
38
38
  * How long one solve may take before the client aborts it (ms). Pass the same value the
39
- * server enforces (`COMPUTE_SOLVE_DEADLINE_MS`), or the client aborts solves that would
39
+ * server enforces for this definition's compute server, or the client aborts solves that would
40
40
  * have finished.
41
41
  */
42
42
  solveDeadlineMs: number;
@@ -8,10 +8,10 @@
8
8
 
9
9
  import type { Snippet } from 'svelte';
10
10
  import type { SolveDiagnostic } from '@selvajs/solve/shared';
11
- import * as Dialog from '../primitives/dialog';
11
+ import * as Dialog from '../primitives/dialog/index.js';
12
12
  import IssueList, { type Issue } from '../primitives/IssueList.svelte';
13
- import { getLocaleContext } from '../../i18n/localeContext.svelte';
14
- import { formatCount } from '../../i18n/messages';
13
+ import { getLocaleContext } from '../../i18n/localeContext.svelte.js';
14
+ import { formatCount } from '../../i18n/messages.js';
15
15
 
16
16
  interface Props {
17
17
  /** The last solve's messages. Preferred over `errors`/`warnings` when both are given. */
@@ -10,6 +10,7 @@
10
10
  } from '../../schema/param-exporter';
11
11
  import { Button, Input, Label, Textarea, Dialog, Callout, IssueList, toast } from '../primitives';
12
12
  import { DEFAULT_PRESET_LABELS, type PresetLabels } from '../../types/presetLabels';
13
+ import { pickFile } from '../../utils/host-files';
13
14
 
14
15
  interface Props {
15
16
  schema: UISchema;
@@ -37,7 +38,6 @@
37
38
  let showLoadDialog = $state(false);
38
39
  let loadResult = $state<PresetLoadResult | null>(null);
39
40
  let loadingPresetName = $state('');
40
- let fileInputRef = $state<HTMLInputElement | null>(null);
41
41
 
42
42
  let listedStates = $state<ParameterPreset[]>([]);
43
43
  let isLoadingList = $state(false);
@@ -69,7 +69,7 @@
69
69
  });
70
70
 
71
71
  if (onSaveState) await onSaveState(state);
72
- else exportStateAsJson(state);
72
+ else await exportStateAsJson(state);
73
73
  showExportDialog = false;
74
74
  }
75
75
 
@@ -86,19 +86,16 @@
86
86
  }
87
87
  }
88
88
 
89
- async function handleImport(event: Event) {
90
- const input = event.target as HTMLInputElement;
91
- if (!input.files || input.files.length === 0) return;
89
+ async function importFromFile() {
90
+ // .sps is the pre-rename extension; files with it exist on users' drives, so keep accepting it.
91
+ const file = await pickFile({ accept: '.slvp,.sps' });
92
+ if (!file) return;
92
93
 
93
94
  try {
94
- const imported = await importStateFromJson(input.files[0]);
95
- tryLoad(imported);
95
+ tryLoad(await importStateFromJson(file));
96
96
  } catch (error) {
97
97
  toast.error(t.loadImportError + (error as Error).message);
98
98
  }
99
-
100
- // Reset so re-picking the same file fires `change` again.
101
- input.value = '';
102
99
  }
103
100
 
104
101
  function confirmLoad() {
@@ -132,8 +129,8 @@
132
129
  }
133
130
 
134
131
  function handleLoadClick() {
135
- fileInputRef?.click();
136
132
  showLoadDialog = false;
133
+ void importFromFile();
137
134
  }
138
135
 
139
136
  function selectListedState(preset: ParameterPreset) {
@@ -142,15 +139,6 @@
142
139
  }
143
140
  </script>
144
141
 
145
- <!-- .sps is the pre-rename extension; files with it exist on users' drives, so keep accepting it. -->
146
- <input
147
- bind:this={fileInputRef}
148
- type="file"
149
- accept=".slvp,.sps"
150
- onchange={handleImport}
151
- class="hidden"
152
- />
153
-
154
142
  <!-- Save Dialog -->
155
143
  <Dialog.Root bind:open={showExportDialog}>
156
144
  <Dialog.Content>
@@ -215,7 +203,7 @@
215
203
  <button
216
204
  type="button"
217
205
  onclick={() => selectListedState(preset)}
218
- class="p-3 w-full rounded-lg border text-left transition-colors hover:bg-muted"
206
+ class="p-3 w-full rounded-lg border text-left transition-colors hover:bg-hover"
219
207
  >
220
208
  <div class="text-sm font-medium">{preset.name}</div>
221
209
  {#if preset.description}