@selvajs/ui 6.6.0-beta.9 → 7.0.1-beta.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 (345) hide show
  1. package/README.md +0 -3
  2. package/dist/components/ErrorScreen.svelte +1 -1
  3. package/dist/components/compute/AppLayout.svelte +230 -85
  4. package/dist/components/compute/AppLayout.svelte.d.ts +14 -2
  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 +1 -1
  10. package/dist/components/compute/SolveMessages.svelte +79 -88
  11. package/dist/components/compute/SolveMessages.svelte.d.ts +5 -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 +9 -6
  17. package/dist/components/layout/PageHeader.svelte +3 -3
  18. package/dist/components/layout/SideNav.svelte +3 -3
  19. package/dist/components/layout/SubNav.svelte +2 -2
  20. package/dist/components/preview/ChartOutput.svelte +141 -50
  21. package/dist/components/preview/Group.svelte +9 -9
  22. package/dist/components/preview/HelpButton.svelte +1 -1
  23. package/dist/components/preview/ImageOutput.svelte +13 -10
  24. package/dist/components/preview/InputControl.svelte +13 -12
  25. package/dist/components/preview/OutputDisplay.svelte +26 -17
  26. package/dist/components/preview/TabBar.svelte +8 -6
  27. package/dist/components/preview/TabBar.svelte.d.ts +2 -0
  28. package/dist/components/preview/TabContent.svelte +8 -8
  29. package/dist/components/preview/TabLayout.svelte +6 -7
  30. package/dist/components/preview/inputs/CheckboxInput.svelte +1 -1
  31. package/dist/components/preview/inputs/ChecklistInput.svelte +5 -5
  32. package/dist/components/preview/inputs/ColorInput.svelte +356 -14
  33. package/dist/components/preview/inputs/ColorInput.svelte.d.ts +1 -0
  34. package/dist/components/preview/inputs/DropdownInput.svelte +3 -3
  35. package/dist/components/preview/inputs/FileInput.svelte +17 -12
  36. package/dist/components/preview/inputs/GeometryInput.svelte +4 -4
  37. package/dist/components/preview/inputs/GeometryInput.svelte.d.ts +1 -1
  38. package/dist/components/preview/inputs/NumberInput.svelte +8 -8
  39. package/dist/components/preview/inputs/OptionGlyph.svelte +1 -1
  40. package/dist/components/preview/inputs/OptionGlyph.svelte.d.ts +1 -1
  41. package/dist/components/preview/inputs/SegmentedInput.svelte +3 -2
  42. package/dist/components/preview/inputs/TextInput.svelte +5 -5
  43. package/dist/components/preview/inputs/TileInput.svelte +8 -5
  44. package/dist/components/primitives/CalculateButton.svelte +10 -4
  45. package/dist/components/primitives/Callout.svelte +8 -6
  46. package/dist/components/primitives/Callout.svelte.d.ts +4 -4
  47. package/dist/components/primitives/DataTable.svelte +1 -1
  48. package/dist/components/primitives/FilterableDropdown.svelte +13 -1
  49. package/dist/components/primitives/FilterableDropdown.svelte.d.ts +5 -0
  50. package/dist/components/primitives/ImageUploadField.svelte +1 -1
  51. package/dist/components/primitives/SolvingIndicator.svelte +242 -41
  52. package/dist/components/primitives/SolvingIndicator.svelte.d.ts +13 -5
  53. package/dist/components/primitives/alert-dialog/alert-dialog-content.svelte +1 -1
  54. package/dist/components/primitives/badge/badge.svelte +2 -2
  55. package/dist/components/primitives/badge/badge.svelte.d.ts +6 -6
  56. package/dist/components/primitives/button/button.svelte +7 -8
  57. package/dist/components/primitives/button/button.svelte.d.ts +19 -19
  58. package/dist/components/primitives/card/card.svelte +1 -1
  59. package/dist/components/primitives/card/card.svelte.d.ts +1 -1
  60. package/dist/components/primitives/checkbox/checkbox.svelte +1 -1
  61. package/dist/components/primitives/command/command-input.svelte +1 -1
  62. package/dist/components/primitives/command/command-item.svelte +1 -1
  63. package/dist/components/primitives/command/command-link-item.svelte +1 -1
  64. package/dist/components/primitives/command/command.svelte +1 -1
  65. package/dist/components/primitives/context-menu/context-menu-checkbox-item.svelte +1 -1
  66. package/dist/components/primitives/context-menu/context-menu-content.svelte +1 -1
  67. package/dist/components/primitives/context-menu/context-menu-item.svelte +1 -1
  68. package/dist/components/primitives/context-menu/context-menu-radio-item.svelte +1 -1
  69. package/dist/components/primitives/context-menu/context-menu-sub-content.svelte +1 -1
  70. package/dist/components/primitives/context-menu/context-menu-sub-trigger.svelte +1 -1
  71. package/dist/components/primitives/dialog/dialog-content.svelte +3 -3
  72. package/dist/components/primitives/drawer/Drawer.svelte +1 -1
  73. package/dist/components/primitives/dropdown-menu/dropdown-menu-checkbox-item.svelte +31 -11
  74. package/dist/components/primitives/dropdown-menu/dropdown-menu-checkbox-item.svelte.d.ts +2 -0
  75. package/dist/components/primitives/dropdown-menu/dropdown-menu-content.svelte +5 -1
  76. package/dist/components/primitives/dropdown-menu/dropdown-menu-content.svelte.d.ts +2 -0
  77. package/dist/components/primitives/dropdown-menu/dropdown-menu-item.svelte +4 -2
  78. package/dist/components/primitives/dropdown-menu/dropdown-menu-item.svelte.d.ts +2 -1
  79. package/dist/components/primitives/dropdown-menu/dropdown-menu-radio-item.svelte +1 -1
  80. package/dist/components/primitives/dropdown-menu/dropdown-menu-shortcut.svelte +1 -1
  81. package/dist/components/primitives/dropdown-menu/dropdown-menu-sub-content.svelte +1 -1
  82. package/dist/components/primitives/dropdown-menu/dropdown-menu-sub-trigger.svelte +1 -1
  83. package/dist/components/primitives/index.d.ts +1 -1
  84. package/dist/components/primitives/index.js +1 -1
  85. package/dist/components/primitives/input/input.svelte +2 -2
  86. package/dist/components/primitives/input-group/input-group-input.svelte.d.ts +1 -1
  87. package/dist/components/primitives/input-group/input-group.svelte +1 -1
  88. package/dist/components/primitives/mode-toggle/mode-toggle.svelte +2 -2
  89. package/dist/components/primitives/popover/popover-content.svelte +1 -1
  90. package/dist/components/primitives/resizable/resizable-handle.svelte +2 -2
  91. package/dist/components/primitives/search/search.svelte +1 -1
  92. package/dist/components/primitives/select/select-content.svelte +1 -1
  93. package/dist/components/primitives/select/select-item.svelte +1 -1
  94. package/dist/components/primitives/select/select-trigger.svelte +1 -1
  95. package/dist/components/primitives/slider/slider.svelte +1 -1
  96. package/dist/components/primitives/switch/switch.svelte +1 -1
  97. package/dist/components/primitives/tabs/tabs-list.svelte +2 -2
  98. package/dist/components/primitives/tabs/tabs-list.svelte.d.ts +6 -6
  99. package/dist/components/primitives/tabs/tabs-trigger.svelte +2 -2
  100. package/dist/components/primitives/tabs/tabs-trigger.svelte.d.ts +6 -6
  101. package/dist/components/primitives/textarea/textarea.svelte +1 -1
  102. package/dist/components/primitives/toggle/toggle.svelte +8 -2
  103. package/dist/components/primitives/toggle/toggle.svelte.d.ts +10 -4
  104. package/dist/components/primitives/toggle-group/toggle-group-item.svelte +1 -1
  105. package/dist/components/primitives/toggle-group/toggle-group.svelte +1 -1
  106. package/dist/components/primitives/tooltip/index.d.ts +6 -0
  107. package/dist/components/primitives/tooltip/index.js +8 -0
  108. package/dist/components/primitives/tooltip/tooltip-content.svelte +34 -0
  109. package/dist/components/primitives/tooltip/tooltip-content.svelte.d.ts +10 -0
  110. package/dist/components/primitives/tooltip/tooltip-portal.svelte +7 -0
  111. package/dist/components/primitives/tooltip/tooltip-portal.svelte.d.ts +4 -0
  112. package/dist/components/primitives/tooltip/tooltip-provider.svelte +7 -0
  113. package/dist/components/primitives/tooltip/tooltip-provider.svelte.d.ts +4 -0
  114. package/dist/components/primitives/tooltip/tooltip-trigger.svelte +7 -0
  115. package/dist/components/primitives/tooltip/tooltip-trigger.svelte.d.ts +4 -0
  116. package/dist/components/primitives/tooltip/tooltip.svelte +7 -0
  117. package/dist/components/primitives/tooltip/tooltip.svelte.d.ts +4 -0
  118. package/dist/components/viewer/MeshMetadataPanel.svelte +2 -2
  119. package/dist/components/viewer/SceneManager.svelte +32 -21
  120. package/dist/components/viewer/SceneManager.svelte.d.ts +3 -1
  121. package/dist/components/viewer/Viewer.svelte +128 -178
  122. package/dist/components/viewer/Viewer.svelte.d.ts +7 -2
  123. package/dist/components/viewer/ViewerDock.svelte +452 -0
  124. package/dist/components/viewer/ViewerDock.svelte.d.ts +42 -0
  125. package/dist/composables/useFooterItem.svelte.d.ts +1 -1
  126. package/dist/composables/useFooterItem.svelte.js +1 -1
  127. package/dist/compute/liveProgress.svelte.d.ts +16 -0
  128. package/dist/compute/liveProgress.svelte.js +90 -0
  129. package/dist/compute/solving.svelte.d.ts +7 -9
  130. package/dist/compute/solving.svelte.js +56 -48
  131. package/dist/constants.d.ts +6 -8
  132. package/dist/constants.js +8 -11
  133. package/dist/contexts/hostContext.svelte.d.ts +1 -1
  134. package/dist/features/chart/plotly-compat.d.ts +15 -0
  135. package/dist/features/chart/plotly-compat.js +124 -0
  136. package/dist/i18n/messages.d.ts +17 -0
  137. package/dist/i18n/messages.js +26 -0
  138. package/dist/index.d.ts +2 -0
  139. package/dist/index.js +2 -0
  140. package/dist/public.d.ts +1 -0
  141. package/dist/public.js +1 -0
  142. package/dist/schema/visibility-rules.d.ts +7 -1
  143. package/dist/schema/visibility-rules.js +17 -0
  144. package/dist/styles/base.css +100 -86
  145. package/dist/utils/color-space.d.ts +21 -0
  146. package/dist/utils/color-space.js +90 -0
  147. package/package.json +31 -23
  148. package/src/lib/components/ErrorScreen.svelte +1 -1
  149. package/src/lib/components/compute/AppLayout.svelte +231 -86
  150. package/src/lib/components/compute/CollapsedPanelStrip.svelte +4 -2
  151. package/src/lib/components/compute/ComputeApp.svelte +6 -2
  152. package/src/lib/components/compute/ComputeMessagesDialog.svelte +4 -4
  153. package/src/lib/components/compute/ParameterPresetManager.svelte +1 -1
  154. package/src/lib/components/compute/SolveMessages.svelte +81 -90
  155. package/src/lib/components/layout/AppShell.svelte +2 -2
  156. package/src/lib/components/layout/FooterItemRenderer.svelte +2 -2
  157. package/src/lib/components/layout/PageContent.svelte +3 -2
  158. package/src/lib/components/layout/PageFooter.svelte +9 -6
  159. package/src/lib/components/layout/PageHeader.svelte +3 -3
  160. package/src/lib/components/layout/SideNav.svelte +4 -4
  161. package/src/lib/components/layout/SubNav.svelte +2 -2
  162. package/src/lib/components/preview/ChartOutput.svelte +141 -50
  163. package/src/lib/components/preview/Group.svelte +9 -9
  164. package/src/lib/components/preview/HelpButton.svelte +1 -1
  165. package/src/lib/components/preview/ImageOutput.svelte +13 -10
  166. package/src/lib/components/preview/InputControl.svelte +13 -12
  167. package/src/lib/components/preview/OutputDisplay.svelte +26 -17
  168. package/src/lib/components/preview/TabBar.svelte +8 -6
  169. package/src/lib/components/preview/TabContent.svelte +8 -8
  170. package/src/lib/components/preview/TabLayout.svelte +6 -7
  171. package/src/lib/components/preview/inputs/CheckboxInput.svelte +1 -1
  172. package/src/lib/components/preview/inputs/ChecklistInput.svelte +5 -5
  173. package/src/lib/components/preview/inputs/ColorInput.svelte +356 -14
  174. package/src/lib/components/preview/inputs/DropdownInput.svelte +3 -3
  175. package/src/lib/components/preview/inputs/FileInput.svelte +17 -12
  176. package/src/lib/components/preview/inputs/GeometryInput.svelte +4 -4
  177. package/src/lib/components/preview/inputs/NumberInput.svelte +8 -8
  178. package/src/lib/components/preview/inputs/OptionGlyph.svelte +2 -2
  179. package/src/lib/components/preview/inputs/SegmentedInput.svelte +3 -2
  180. package/src/lib/components/preview/inputs/TextInput.svelte +5 -5
  181. package/src/lib/components/preview/inputs/TileInput.svelte +8 -5
  182. package/src/lib/components/primitives/CalculateButton.svelte +10 -4
  183. package/src/lib/components/primitives/Callout.svelte +9 -7
  184. package/src/lib/components/primitives/DataTable.svelte +1 -1
  185. package/src/lib/components/primitives/FilterableDropdown.svelte +14 -2
  186. package/src/lib/components/primitives/ImageUploadField.svelte +1 -1
  187. package/src/lib/components/primitives/IssueList.svelte +1 -1
  188. package/src/lib/components/primitives/SeverityIcon.svelte +1 -1
  189. package/src/lib/components/primitives/SolvingIndicator.svelte +242 -41
  190. package/src/lib/components/primitives/StateDisplay.svelte +1 -1
  191. package/src/lib/components/primitives/alert-dialog/alert-dialog-action.svelte +2 -2
  192. package/src/lib/components/primitives/alert-dialog/alert-dialog-cancel.svelte +2 -2
  193. package/src/lib/components/primitives/alert-dialog/alert-dialog-content.svelte +2 -2
  194. package/src/lib/components/primitives/alert-dialog/alert-dialog-description.svelte +1 -1
  195. package/src/lib/components/primitives/alert-dialog/alert-dialog-footer.svelte +1 -1
  196. package/src/lib/components/primitives/alert-dialog/alert-dialog-header.svelte +1 -1
  197. package/src/lib/components/primitives/alert-dialog/alert-dialog-overlay.svelte +1 -1
  198. package/src/lib/components/primitives/alert-dialog/alert-dialog-title.svelte +1 -1
  199. package/src/lib/components/primitives/badge/badge.svelte +3 -3
  200. package/src/lib/components/primitives/button/button.svelte +7 -8
  201. package/src/lib/components/primitives/button-group/button-group-separator.svelte +2 -2
  202. package/src/lib/components/primitives/button-group/button-group-text.svelte +1 -1
  203. package/src/lib/components/primitives/button-group/button-group.svelte +1 -1
  204. package/src/lib/components/primitives/card/card-content.svelte +1 -1
  205. package/src/lib/components/primitives/card/card-description.svelte +1 -1
  206. package/src/lib/components/primitives/card/card-footer.svelte +1 -1
  207. package/src/lib/components/primitives/card/card-header.svelte +1 -1
  208. package/src/lib/components/primitives/card/card-title.svelte +1 -1
  209. package/src/lib/components/primitives/card/card.svelte +2 -2
  210. package/src/lib/components/primitives/checkbox/checkbox.svelte +2 -2
  211. package/src/lib/components/primitives/command/command-dialog.svelte +2 -2
  212. package/src/lib/components/primitives/command/command-empty.svelte +1 -1
  213. package/src/lib/components/primitives/command/command-group.svelte +1 -1
  214. package/src/lib/components/primitives/command/command-input.svelte +3 -3
  215. package/src/lib/components/primitives/command/command-item.svelte +2 -2
  216. package/src/lib/components/primitives/command/command-link-item.svelte +2 -2
  217. package/src/lib/components/primitives/command/command-list.svelte +1 -1
  218. package/src/lib/components/primitives/command/command-separator.svelte +1 -1
  219. package/src/lib/components/primitives/command/command-shortcut.svelte +1 -1
  220. package/src/lib/components/primitives/command/command.svelte +2 -2
  221. package/src/lib/components/primitives/context-menu/context-menu-checkbox-item.svelte +2 -2
  222. package/src/lib/components/primitives/context-menu/context-menu-content.svelte +2 -2
  223. package/src/lib/components/primitives/context-menu/context-menu-group-heading.svelte +1 -1
  224. package/src/lib/components/primitives/context-menu/context-menu-item.svelte +2 -2
  225. package/src/lib/components/primitives/context-menu/context-menu-label.svelte +1 -1
  226. package/src/lib/components/primitives/context-menu/context-menu-radio-item.svelte +2 -2
  227. package/src/lib/components/primitives/context-menu/context-menu-separator.svelte +1 -1
  228. package/src/lib/components/primitives/context-menu/context-menu-shortcut.svelte +1 -1
  229. package/src/lib/components/primitives/context-menu/context-menu-sub-content.svelte +2 -2
  230. package/src/lib/components/primitives/context-menu/context-menu-sub-trigger.svelte +2 -2
  231. package/src/lib/components/primitives/dialog/dialog-content.svelte +4 -4
  232. package/src/lib/components/primitives/dialog/dialog-description.svelte +1 -1
  233. package/src/lib/components/primitives/dialog/dialog-footer.svelte +1 -1
  234. package/src/lib/components/primitives/dialog/dialog-header.svelte +1 -1
  235. package/src/lib/components/primitives/dialog/dialog-overlay.svelte +1 -1
  236. package/src/lib/components/primitives/dialog/dialog-title.svelte +1 -1
  237. package/src/lib/components/primitives/drawer/Drawer.svelte +1 -1
  238. package/src/lib/components/primitives/dropdown-menu/dropdown-menu-checkbox-item.svelte +32 -12
  239. package/src/lib/components/primitives/dropdown-menu/dropdown-menu-content.svelte +6 -2
  240. package/src/lib/components/primitives/dropdown-menu/dropdown-menu-group-heading.svelte +1 -1
  241. package/src/lib/components/primitives/dropdown-menu/dropdown-menu-item.svelte +5 -3
  242. package/src/lib/components/primitives/dropdown-menu/dropdown-menu-label.svelte +1 -1
  243. package/src/lib/components/primitives/dropdown-menu/dropdown-menu-radio-item.svelte +2 -2
  244. package/src/lib/components/primitives/dropdown-menu/dropdown-menu-separator.svelte +1 -1
  245. package/src/lib/components/primitives/dropdown-menu/dropdown-menu-shortcut.svelte +2 -2
  246. package/src/lib/components/primitives/dropdown-menu/dropdown-menu-sub-content.svelte +2 -2
  247. package/src/lib/components/primitives/dropdown-menu/dropdown-menu-sub-trigger.svelte +2 -2
  248. package/src/lib/components/primitives/empty/empty-content.svelte +1 -1
  249. package/src/lib/components/primitives/empty/empty-description.svelte +1 -1
  250. package/src/lib/components/primitives/empty/empty-header.svelte +1 -1
  251. package/src/lib/components/primitives/empty/empty-media.svelte +1 -1
  252. package/src/lib/components/primitives/empty/empty-title.svelte +1 -1
  253. package/src/lib/components/primitives/empty/empty.svelte +1 -1
  254. package/src/lib/components/primitives/field/field-content.svelte +1 -1
  255. package/src/lib/components/primitives/field/field-description.svelte +1 -1
  256. package/src/lib/components/primitives/field/field-error.svelte +1 -1
  257. package/src/lib/components/primitives/field/field-group.svelte +1 -1
  258. package/src/lib/components/primitives/field/field-label.svelte +2 -2
  259. package/src/lib/components/primitives/field/field-legend.svelte +1 -1
  260. package/src/lib/components/primitives/field/field-separator.svelte +2 -2
  261. package/src/lib/components/primitives/field/field-set.svelte +1 -1
  262. package/src/lib/components/primitives/field/field-title.svelte +1 -1
  263. package/src/lib/components/primitives/field/field.svelte +1 -1
  264. package/src/lib/components/primitives/index.ts +1 -1
  265. package/src/lib/components/primitives/input/input.svelte +3 -3
  266. package/src/lib/components/primitives/input-group/input-group-addon.svelte +1 -1
  267. package/src/lib/components/primitives/input-group/input-group-button.svelte +2 -2
  268. package/src/lib/components/primitives/input-group/input-group-input.svelte +2 -2
  269. package/src/lib/components/primitives/input-group/input-group-text.svelte +1 -1
  270. package/src/lib/components/primitives/input-group/input-group-textarea.svelte +2 -2
  271. package/src/lib/components/primitives/input-group/input-group.svelte +2 -2
  272. package/src/lib/components/primitives/label/label.svelte +1 -1
  273. package/src/lib/components/primitives/mode-toggle/mode-toggle.svelte +2 -2
  274. package/src/lib/components/primitives/popover/popover-content.svelte +2 -2
  275. package/src/lib/components/primitives/popover/popover-description.svelte +1 -1
  276. package/src/lib/components/primitives/popover/popover-header.svelte +1 -1
  277. package/src/lib/components/primitives/popover/popover-title.svelte +1 -1
  278. package/src/lib/components/primitives/popover/popover-trigger.svelte +1 -1
  279. package/src/lib/components/primitives/resizable/resizable-handle.svelte +3 -3
  280. package/src/lib/components/primitives/resizable/resizable-pane-group.svelte +1 -1
  281. package/src/lib/components/primitives/scroll-area/scroll-area-scrollbar.svelte +1 -1
  282. package/src/lib/components/primitives/scroll-area/scroll-area.svelte +1 -1
  283. package/src/lib/components/primitives/search/search.svelte +2 -2
  284. package/src/lib/components/primitives/select/select-content.svelte +2 -2
  285. package/src/lib/components/primitives/select/select-group-heading.svelte +1 -1
  286. package/src/lib/components/primitives/select/select-item.svelte +2 -2
  287. package/src/lib/components/primitives/select/select-label.svelte +1 -1
  288. package/src/lib/components/primitives/select/select-scroll-down-button.svelte +1 -1
  289. package/src/lib/components/primitives/select/select-scroll-up-button.svelte +1 -1
  290. package/src/lib/components/primitives/select/select-separator.svelte +2 -2
  291. package/src/lib/components/primitives/select/select-trigger.svelte +2 -2
  292. package/src/lib/components/primitives/separator/separator.svelte +1 -1
  293. package/src/lib/components/primitives/slider/slider.svelte +2 -2
  294. package/src/lib/components/primitives/spinner/spinner.svelte +1 -1
  295. package/src/lib/components/primitives/switch/switch.svelte +2 -2
  296. package/src/lib/components/primitives/tabs/tabs-content.svelte +1 -1
  297. package/src/lib/components/primitives/tabs/tabs-list.svelte +3 -3
  298. package/src/lib/components/primitives/tabs/tabs-trigger.svelte +3 -3
  299. package/src/lib/components/primitives/tabs/tabs.svelte +1 -1
  300. package/src/lib/components/primitives/textarea/textarea.svelte +2 -2
  301. package/src/lib/components/primitives/toggle/toggle.svelte +9 -3
  302. package/src/lib/components/primitives/toggle-group/toggle-group-item.svelte +3 -3
  303. package/src/lib/components/primitives/toggle-group/toggle-group.svelte +3 -3
  304. package/src/lib/components/primitives/tooltip/index.ts +19 -0
  305. package/src/lib/components/primitives/tooltip/tooltip-content.svelte +34 -0
  306. package/src/lib/components/primitives/tooltip/tooltip-portal.svelte +7 -0
  307. package/src/lib/components/primitives/tooltip/tooltip-provider.svelte +7 -0
  308. package/src/lib/components/primitives/tooltip/tooltip-trigger.svelte +7 -0
  309. package/src/lib/components/primitives/tooltip/tooltip.svelte +7 -0
  310. package/src/lib/components/viewer/MeshMetadataPanel.svelte +2 -2
  311. package/src/lib/components/viewer/SceneManager.svelte +32 -21
  312. package/src/lib/components/viewer/Viewer.svelte +129 -179
  313. package/src/lib/components/viewer/ViewerDock.svelte +452 -0
  314. package/src/lib/composables/useFooterItem.svelte.ts +1 -1
  315. package/src/lib/compute/liveProgress.svelte.ts +103 -0
  316. package/src/lib/compute/solving.svelte.ts +56 -55
  317. package/src/lib/constants.ts +8 -11
  318. package/src/lib/contexts/hostContext.svelte.ts +1 -1
  319. package/src/lib/features/chart/plotly-compat.ts +141 -0
  320. package/src/lib/i18n/messages.ts +43 -0
  321. package/src/lib/index.ts +2 -0
  322. package/src/lib/public.ts +1 -0
  323. package/src/lib/schema/visibility-rules.ts +27 -1
  324. package/src/lib/styles/base.css +100 -86
  325. package/src/lib/utils/color-space.ts +107 -0
  326. package/dist/components/primitives/theme-switcher/ThemeSwitcher.svelte +0 -39
  327. package/dist/components/primitives/theme-switcher/ThemeSwitcher.svelte.d.ts +0 -3
  328. package/dist/components/primitives/theme-switcher/index.d.ts +0 -1
  329. package/dist/components/primitives/theme-switcher/index.js +0 -1
  330. package/dist/styles/themes/cyberpunk.css +0 -98
  331. package/dist/styles/themes/neutral.css +0 -72
  332. package/dist/styles/themes/ocean.css +0 -75
  333. package/dist/styles/themes/selva.css +0 -105
  334. package/dist/theme/themeStore.svelte.d.ts +0 -12
  335. package/dist/theme/themeStore.svelte.js +0 -40
  336. package/dist/theme/themes.d.ts +0 -5
  337. package/dist/theme/themes.js +0 -13
  338. package/src/lib/components/primitives/theme-switcher/ThemeSwitcher.svelte +0 -39
  339. package/src/lib/components/primitives/theme-switcher/index.ts +0 -1
  340. package/src/lib/styles/themes/cyberpunk.css +0 -98
  341. package/src/lib/styles/themes/neutral.css +0 -72
  342. package/src/lib/styles/themes/ocean.css +0 -75
  343. package/src/lib/styles/themes/selva.css +0 -105
  344. package/src/lib/theme/themeStore.svelte.ts +0 -50
  345. package/src/lib/theme/themes.ts +0 -18
@@ -1,10 +1,10 @@
1
1
  <script lang="ts">
2
2
  import type { TextWidgetConfig, SupportedTypes } from '@selvajs/schemas';
3
- import { debounce } from '$lib/utils/debounce';
4
- import { Input } from '$lib/components/primitives/input';
5
- import * as Field from '$lib/components/primitives/field';
6
- import { getLocaleContext } from '$lib/i18n/localeContext.svelte';
7
- import { formatMessage } from '$lib/i18n/messages';
3
+ import { debounce } from '#lib/utils/debounce.js';
4
+ import { Input } from '#lib/components/primitives/input/index.js';
5
+ import * as Field from '#lib/components/primitives/field/index.js';
6
+ import { getLocaleContext } from '#lib/i18n/localeContext.svelte.js';
7
+ import { formatMessage } from '#lib/i18n/messages.js';
8
8
 
9
9
  interface Props {
10
10
  inputId: string;
@@ -1,6 +1,6 @@
1
1
  <script lang="ts">
2
2
  import type { DropdownWidgetConfig, SupportedTypes, UISchema } from '@selvajs/schemas';
3
- import { optionGlyph } from '$lib/schema/option-display';
3
+ import { optionGlyph } from '#lib/schema/option-display.js';
4
4
  import OptionGlyph from './OptionGlyph.svelte';
5
5
 
6
6
  interface Props {
@@ -45,17 +45,20 @@
45
45
  bind:this={tiles[index]}
46
46
  type="button"
47
47
  role="radio"
48
+ title={option.name}
48
49
  aria-checked={selected}
49
50
  tabindex={index === focusIndex ? 0 : -1}
50
51
  {disabled}
51
52
  onclick={() => onChange(option.value)}
52
53
  onkeydown={(e) => onKeydown(e, index)}
53
54
  class="gap-1.5 p-1.5 min-w-0 flex flex-col rounded-lg border text-left transition-colors outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 {selected
54
- ? 'border-primary bg-primary/5 ring-1 ring-primary'
55
- : 'border-input hover:bg-accent/40'}"
55
+ ? 'border-primary bg-primary/10 ring-1 ring-primary'
56
+ : 'border-input hover:bg-hover'}"
56
57
  >
57
58
  <span
58
- class="flex aspect-square w-full items-center justify-center overflow-hidden rounded-md bg-muted text-muted-foreground"
59
+ class="flex aspect-square w-full items-center justify-center overflow-hidden rounded-md bg-muted {selected
60
+ ? 'text-foreground'
61
+ : 'text-muted-foreground'}"
59
62
  >
60
63
  {#if glyph?.kind === 'image'}
61
64
  <OptionGlyph {glyph} class="size-full" />
@@ -65,7 +68,7 @@
65
68
  <span class="text-lg font-medium" aria-hidden="true">{option.name.charAt(0)}</span>
66
69
  {/if}
67
70
  </span>
68
- <span class="px-0.5 text-xs leading-tight truncate" class:font-medium={selected}>
71
+ <span class="px-0.5 text-xs leading-tight line-clamp-2" class:font-medium={selected}>
69
72
  {option.name}
70
73
  </span>
71
74
  </button>
@@ -1,7 +1,7 @@
1
1
  <script lang="ts">
2
2
  import { untrack, type Snippet } from 'svelte';
3
3
  import { Button } from './button';
4
- import { Zap, Check, Loader, Play } from '@lucide/svelte';
4
+ import { Zap, LoaderCircle, Play } from '@lucide/svelte';
5
5
  import { getLocaleContext } from '../../i18n/localeContext.svelte';
6
6
 
7
7
  const locale = getLocaleContext();
@@ -38,7 +38,7 @@
38
38
  });
39
39
  </script>
40
40
 
41
- <div class="bottom-0 mt-3 pb-3 pt-2 backdrop-blur-sm px-2 sticky border-t border-border/50">
41
+ <div class="bottom-0 mt-3 pb-3 pt-2 backdrop-blur-sm px-2 sticky border-t border-border">
42
42
  <span class="sr-only" role="status" aria-live="polite">{announcement}</span>
43
43
  <div class="gap-2 flex">
44
44
  <Button
@@ -52,8 +52,14 @@
52
52
  {!hasPendingChanges && !isSolving ? 'text-muted-foreground' : ''}"
53
53
  >
54
54
  {#if isSolving}
55
- <Loader class="h-4 w-4 animate-spin" />
55
+ <LoaderCircle class="h-4 w-4 animate-spin" />
56
56
  {t.solvingEllipsis}
57
+ <kbd
58
+ class="px-1 rounded-sm border border-current/30 font-sans text-2xs opacity-70"
59
+ title={t.solveMessagesEscHint}
60
+ >
61
+ Esc
62
+ </kbd>
57
63
  {:else if hasNeverSolved}
58
64
  <Play class="h-4 w-4" />
59
65
  {t.pressToCalculate}
@@ -61,7 +67,7 @@
61
67
  <Zap class="h-4 w-4" />
62
68
  {t.calculate}
63
69
  {:else}
64
- <Check class="h-4 w-4" />
70
+ <span class="size-1.5 shrink-0 rounded-full bg-success" aria-hidden="true"></span>
65
71
  {t.upToDate}
66
72
  {/if}
67
73
  </Button>
@@ -8,7 +8,7 @@
8
8
  variants: {
9
9
  tone: {
10
10
  info: 'border-info/40 bg-info/10',
11
- tip: 'border-border bg-muted/40',
11
+ tip: 'border-border bg-muted',
12
12
  success: 'border-success/40 bg-success/10',
13
13
  warning: 'border-warning/40 bg-warning/10',
14
14
  danger: 'border-destructive/40 bg-destructive/10'
@@ -31,14 +31,14 @@
31
31
  <script lang="ts">
32
32
  import type { HTMLAttributes } from 'svelte/elements';
33
33
  import type { Snippet } from 'svelte';
34
- import { cn } from '$lib/utils.js';
34
+ import { cn } from '#lib/utils.js';
35
35
 
36
36
  interface Props extends HTMLAttributes<HTMLDivElement> {
37
37
  tone?: CalloutTone;
38
38
  title?: string;
39
39
  /** Replaces the tone's default icon. `null` drops the icon entirely. */
40
40
  icon?: Component | null;
41
- children: Snippet;
41
+ children?: Snippet;
42
42
  }
43
43
 
44
44
  let { tone = 'info', title, icon, class: className, children, ...restProps }: Props = $props();
@@ -55,12 +55,14 @@
55
55
  {#if Icon}
56
56
  <Icon class={cn('mt-0.5 h-4 w-4 shrink-0', accent)} />
57
57
  {/if}
58
- <div class="min-w-0 space-y-1">
58
+ <div class="min-w-0 space-y-1 wrap-anywhere">
59
59
  {#if title}
60
60
  <p class={cn('leading-tight font-medium', accent)}>{title}</p>
61
61
  {/if}
62
- <div class="leading-relaxed text-muted-foreground [&_a]:underline [&_strong]:text-foreground">
63
- {@render children()}
64
- </div>
62
+ {#if children}
63
+ <div class="leading-relaxed text-muted-foreground [&_a]:underline [&_strong]:text-foreground">
64
+ {@render children()}
65
+ </div>
66
+ {/if}
65
67
  </div>
66
68
  </div>
@@ -41,7 +41,7 @@
41
41
  style:--table-cols-sm={mobileTemplate}
42
42
  >
43
43
  <div
44
- class="data-table-row gap-4 px-4 py-2 text-xs font-medium tracking-wide sm:grid-cols-(--table-cols) grid grid-cols-(--table-cols-sm) bg-muted/40 text-muted-foreground uppercase {hiddenCols}"
44
+ class="data-table-row gap-4 px-4 py-2 text-xs font-medium tracking-wide sm:grid-cols-(--table-cols) grid grid-cols-(--table-cols-sm) bg-muted text-muted-foreground uppercase {hiddenCols}"
45
45
  >
46
46
  {#each columns as col (col.label)}
47
47
  <span class={col.align === 'right' ? 'text-right' : ''}>{col.label}</span>
@@ -1,7 +1,7 @@
1
1
  <script lang="ts">
2
2
  import type { Component } from 'svelte';
3
3
  import { ChevronDown } from '@lucide/svelte';
4
- import { cn } from '$lib/utils.js';
4
+ import { cn } from '#lib/utils.js';
5
5
  import { buttonVariants } from './button';
6
6
  import * as Popover from './popover';
7
7
  import * as Command from './command';
@@ -11,6 +11,7 @@
11
11
  label: string;
12
12
  icon?: Component;
13
13
  iconClass?: string;
14
+ disabled?: boolean;
14
15
  }
15
16
 
16
17
  interface Props {
@@ -24,6 +25,10 @@
24
25
  /** Above this many items the list gets a filter box. */
25
26
  searchThreshold?: number;
26
27
  disabled?: boolean;
28
+ /** Submits the picked id with a plain <form>, like a native select's name. */
29
+ name?: string;
30
+ size?: 'default' | 'sm';
31
+ 'aria-label'?: string;
27
32
  class?: string;
28
33
  }
29
34
 
@@ -37,6 +42,9 @@
37
42
  searchPlaceholder = 'Filter...',
38
43
  searchThreshold = 4,
39
44
  disabled = false,
45
+ name,
46
+ size = 'default',
47
+ 'aria-label': ariaLabel,
40
48
  class: className
41
49
  }: Props = $props();
42
50
 
@@ -51,14 +59,17 @@
51
59
  }
52
60
  </script>
53
61
 
62
+ {#if name}<input type="hidden" {name} value={value ?? ''} />{/if}
63
+
54
64
  <Popover.Root bind:open>
55
65
  <Popover.Trigger
56
66
  {id}
57
67
  {disabled}
58
68
  role="combobox"
59
69
  aria-expanded={open}
70
+ aria-label={ariaLabel}
60
71
  class={cn(
61
- buttonVariants({ variant: 'outline' }),
72
+ buttonVariants({ variant: 'outline', size }),
62
73
  'font-normal w-full justify-start',
63
74
  className
64
75
  )}
@@ -85,6 +96,7 @@
85
96
  value={item.id}
86
97
  keywords={[item.label]}
87
98
  data-checked={item.id === value}
99
+ disabled={item.disabled}
88
100
  onSelect={() => pick(item)}
89
101
  >
90
102
  {#if ItemIcon}
@@ -60,7 +60,7 @@
60
60
  accept="image/*"
61
61
  {disabled}
62
62
  onchange={onFileSelected}
63
- class="h-10 px-3 py-2 text-sm file:text-sm file:font-medium flex flex-1 rounded-md border border-input bg-background file:border-0 file:bg-transparent focus-visible:ring-2 focus-visible:ring-ring focus-visible:outline-none disabled:opacity-50"
63
+ class="h-10 px-3 py-2 text-sm file:text-sm file:font-medium flex flex-1 rounded-md border border-input bg-field file:border-0 file:bg-transparent focus-visible:ring-2 focus-visible:ring-ring focus-visible:outline-none disabled:opacity-50"
64
64
  />
65
65
  <Button
66
66
  size="sm"
@@ -14,7 +14,7 @@
14
14
  </script>
15
15
 
16
16
  <script lang="ts">
17
- import { cn } from '$lib/utils.js';
17
+ import { cn } from '#lib/utils.js';
18
18
  import SeverityIcon from './SeverityIcon.svelte';
19
19
 
20
20
  interface Props {
@@ -1,5 +1,5 @@
1
1
  <script lang="ts">
2
- import { cn } from '$lib/utils.js';
2
+ import { cn } from '#lib/utils.js';
3
3
  import { SEVERITY_ICON, SEVERITY_TEXT, type Severity } from './severity';
4
4
 
5
5
  interface Props {
@@ -1,60 +1,261 @@
1
1
  <script lang="ts">
2
+ import { untrack } from 'svelte';
3
+ import { fade } from 'svelte/transition';
4
+ import { Check, LoaderCircle } from '@lucide/svelte';
5
+ import { EMPTY_LIVE_SOLVE, type LiveSolveState } from '@selvajs/solve/client';
6
+ import { Button } from '#lib/components/primitives/button/index.js';
7
+ import { createLiveProgress } from '#lib/compute/liveProgress.svelte.js';
2
8
  import { getLocaleContext } from '../../i18n/localeContext.svelte';
3
9
 
10
+ // The solve status in a panel's action row. It grows only as far as the solve needs: a quiet
11
+ // "up to date" row, a pill once a solve is visible, a card with progress and Abort once it is
12
+ // slow. It grows upward over the fields, so the footer never changes height.
4
13
  interface Props {
14
+ /** The raw flag: times the solve, and acknowledges one too short to show. */
15
+ isSolving: boolean;
16
+ /** `createSolvingIndicator(...).show`. */
5
17
  show: boolean;
18
+ /** `createSolvingIndicator(...).slow`. */
19
+ slow?: boolean;
20
+ /** Live progress for the card. Without it the card's bar is indeterminate. */
21
+ live?: LiveSolveState;
22
+ /** Without it the card has no Abort button; Esc still works where the host handles it. */
23
+ onabort?: () => void;
6
24
  /**
7
- * `floating` overlays the bottom-left corner. `inline` is a compact chip the size of an
8
- * icon button, for a narrow host whose corner holds its content and whose action row
9
- * already reserves the chip's place. That host freezes while it solves, so the chip says
10
- * Esc aborts: a frozen page can't offer a button.
25
+ * The page can't repaint mid-solve (see `createSolvingIndicator`): the pill says Esc aborts
26
+ * instead of counting seconds, and never grows into the card.
11
27
  */
12
- placement?: 'floating' | 'inline';
28
+ freezesDuringSolve?: boolean;
13
29
  }
14
30
 
15
- let { show, placement = 'floating' }: Props = $props();
31
+ let {
32
+ isSolving,
33
+ show,
34
+ slow = false,
35
+ live,
36
+ onabort,
37
+ freezesDuringSolve = false
38
+ }: Props = $props();
16
39
 
17
40
  const locale = getLocaleContext();
18
41
  const t = $derived(locale.messages);
42
+
43
+ const DONE_VISIBLE_MS = 1400;
44
+ // A drag fires a solve per step; one acknowledgement per this many ms is enough.
45
+ const PING_EVERY_MS = 500;
46
+
47
+ const progress = createLiveProgress(() => live ?? EMPTY_LIVE_SOLVE);
48
+ const head = $derived(progress.headline ?? progress.progress[0]);
49
+ const bar = $derived(
50
+ head?.fraction === undefined
51
+ ? undefined
52
+ : (progress.bars[head.source ?? ''] ?? { width: head.fraction, ms: 150 })
53
+ );
54
+
55
+ let startedAt = 0;
56
+ let elapsed = $state(0);
57
+ let finished = $state<{ ms: number; aborted: boolean } | null>(null);
58
+ let ping = $state(0);
59
+ let lastPingAt = 0;
60
+ // Not `show` itself at the solve's end: the host's indicator may already have dropped it.
61
+ let shownThisSolve = false;
62
+
63
+ $effect(() => {
64
+ if (show) shownThisSolve = true;
65
+ });
66
+
67
+ $effect(() => {
68
+ const solving = isSolving;
69
+ untrack(() => {
70
+ if (solving) {
71
+ startedAt = performance.now();
72
+ shownThisSolve = show;
73
+ elapsed = 0;
74
+ finished = null;
75
+ return;
76
+ }
77
+ if (!startedAt) return;
78
+ const ms = performance.now() - startedAt;
79
+ startedAt = 0;
80
+ if (shownThisSolve) {
81
+ finished = { ms, aborted: live?.ended?.kind === 'aborted' };
82
+ } else if (performance.now() - lastPingAt > PING_EVERY_MS) {
83
+ lastPingAt = performance.now();
84
+ ping++;
85
+ }
86
+ });
87
+ });
88
+
89
+ $effect(() => {
90
+ if (!finished) return;
91
+ const timer = setTimeout(() => (finished = null), DONE_VISIBLE_MS);
92
+ return () => clearTimeout(timer);
93
+ });
94
+
95
+ $effect(() => {
96
+ if (!isSolving || !show || freezesDuringSolve) return;
97
+ const tick = () => (elapsed = performance.now() - startedAt);
98
+ tick();
99
+ const id = setInterval(tick, 100);
100
+ return () => clearInterval(id);
101
+ });
102
+
103
+ // Done wins over a held `show`: the indicator outlives the solve by up to its minimum time,
104
+ // and saying "Solving" over a result that has already landed would be wrong.
105
+ const mode = $derived<'idle' | 'work' | 'card' | 'done'>(
106
+ finished ? 'done' : show ? (slow && !freezesDuringSolve ? 'card' : 'work') : 'idle'
107
+ );
108
+
109
+ const seconds = $derived(
110
+ new Intl.NumberFormat(locale.locale, { minimumFractionDigits: 1, maximumFractionDigits: 1 })
111
+ );
112
+ const fmt = (ms: number) => `${seconds.format(ms / 1000)} s`;
113
+
114
+ const announcement = $derived(
115
+ mode === 'work' || mode === 'card'
116
+ ? t.solvingEllipsis
117
+ : mode === 'done'
118
+ ? finished?.aborted
119
+ ? t.solveStopped
120
+ : t.solveDone
121
+ : ''
122
+ );
19
123
  </script>
20
124
 
21
- <!-- The live region stays mounted: a screen reader only announces text that changes inside a
22
- region it already knows about, so one created together with its text says nothing. -->
23
- <div
24
- role="status"
25
- aria-live="polite"
26
- aria-atomic="true"
27
- class={placement === 'inline' ? 'h-10 gap-3 min-w-0 flex items-center' : undefined}
28
- >
29
- {#if show && placement === 'inline'}
30
- <div
31
- class="gap-2 px-3 h-10 text-sm font-semibold flex shrink-0 items-center rounded-md bg-primary text-primary-foreground"
32
- >
125
+ <div class="h-10 min-w-0 relative flex-1">
126
+ <!-- The live region stays mounted: a screen reader only announces text that changes inside a
127
+ region it already knows about, so one created together with its text says nothing. -->
128
+ <div role="status" aria-live="polite" aria-atomic="true" class="sr-only">{announcement}</div>
129
+
130
+ <div
131
+ class="inset-x-0 bottom-0 backdrop-blur-md ease-out absolute z-10 overflow-hidden border border-border-strong transition-all duration-300 motion-reduce:transition-none {mode ===
132
+ 'card'
133
+ ? 'h-24 shadow-md rounded-lg bg-card/75'
134
+ : mode === 'idle'
135
+ ? 'h-10 shadow-sm rounded-md bg-card/90'
136
+ : 'h-10 shadow-md rounded-md bg-card/75'}"
137
+ data-testid="solve-status"
138
+ data-state={mode}
139
+ >
140
+ {#if mode === 'card'}
33
141
  <div
34
- class="h-3 w-3 animate-spin rounded-full border-2 border-primary-foreground border-t-transparent"
35
- aria-hidden="true"
36
- ></div>
37
- {t.solvingEllipsis}
38
- </div>
39
- <span class="text-xs min-w-0 truncate text-muted-foreground" data-testid="solve-esc-hint">
40
- {t.solveMessagesEscHint}
41
- </span>
42
- {:else if show}
43
- <div
44
- class="bottom-6 left-6 gap-3 px-5 py-3 shadow-xl animate-in fade-in slide-in-from-left fixed z-50 flex items-center rounded-lg border border-primary/20 bg-primary text-primary-foreground duration-200"
45
- >
46
- <div class="h-5 w-5 relative flex shrink-0 items-center justify-center" aria-hidden="true">
47
- <div
48
- class="animate-ping absolute h-full w-full rounded-full bg-primary-foreground opacity-30"
49
- ></div>
142
+ class="px-3 gap-2 flex h-full flex-col justify-center"
143
+ in:fade={{ duration: 150, delay: 80 }}
144
+ >
145
+ <div class="gap-2 min-w-0 flex items-center">
146
+ <LoaderCircle
147
+ class="size-4 animate-spin shrink-0 text-muted-foreground"
148
+ aria-hidden="true"
149
+ />
150
+ <span class="text-sm font-medium min-w-0 flex-1 truncate">{head?.label ?? t.solving}</span
151
+ >
152
+ {#if head?.done !== undefined && head?.total !== undefined}
153
+ <span class="text-xs shrink-0 text-muted-foreground tabular-nums">
154
+ {head.done} / {head.total}
155
+ </span>
156
+ {/if}
157
+ </div>
50
158
  <div
51
- class="h-3 w-3 animate-spin rounded-full border-2 border-primary-foreground border-t-transparent"
52
- ></div>
159
+ class="h-1 overflow-hidden rounded-full bg-muted"
160
+ role="progressbar"
161
+ aria-label={head?.label ?? t.solving}
162
+ aria-valuemin={0}
163
+ aria-valuemax={100}
164
+ aria-valuenow={bar ? Math.round(bar.width * 100) : undefined}
165
+ >
166
+ {#if bar}
167
+ <div
168
+ class="h-full w-(--bar-width) rounded-full bg-primary transition-all duration-(--bar-ms) ease-linear"
169
+ style:--bar-width="{bar.width * 100}%"
170
+ style:--bar-ms="{bar.ms}ms"
171
+ ></div>
172
+ {:else}
173
+ <div class="animate-pulse h-full w-1/3 rounded-full bg-primary/60"></div>
174
+ {/if}
175
+ </div>
176
+ <div class="gap-2 flex items-center">
177
+ <span class="text-xs text-muted-foreground tabular-nums">{fmt(elapsed)}</span>
178
+ {#if onabort}
179
+ <Button
180
+ variant="outline"
181
+ size="xs"
182
+ class="ml-auto shrink-0"
183
+ onclick={onabort}
184
+ aria-keyshortcuts="Escape"
185
+ title={t.solveMessagesEscHint}
186
+ >
187
+ {t.solveMessagesAbort}
188
+ <kbd
189
+ class="px-1 rounded-sm border border-border font-sans text-2xs text-muted-foreground"
190
+ >
191
+ Esc
192
+ </kbd>
193
+ </Button>
194
+ {/if}
195
+ </div>
196
+ </div>
197
+ {:else if mode === 'work'}
198
+ <div class="px-3 gap-2 flex h-full items-center" in:fade={{ duration: 150, delay: 80 }}>
199
+ <LoaderCircle
200
+ class="size-4 animate-spin shrink-0 text-muted-foreground"
201
+ aria-hidden="true"
202
+ />
203
+ {#if freezesDuringSolve}
204
+ <span class="text-sm font-medium shrink-0">{t.solvingEllipsis}</span>
205
+ <span class="text-xs min-w-0 truncate text-muted-foreground" data-testid="solve-esc-hint">
206
+ {t.solveMessagesEscHint}
207
+ </span>
208
+ {:else}
209
+ <span class="text-sm font-medium shrink-0">{t.solving}</span>
210
+ <span class="text-xs text-muted-foreground tabular-nums">{fmt(elapsed)}</span>
211
+ {/if}
53
212
  </div>
54
- <div class="leading-tight flex flex-col">
55
- <span class="text-sm font-semibold">{t.solving}</span>
56
- <span class="text-xs opacity-70">{t.solvingSubtitle}</span>
213
+ {:else if mode === 'done' && finished}
214
+ <div class="px-3 gap-2 flex h-full items-center" in:fade={{ duration: 150, delay: 80 }}>
215
+ {#if finished.aborted}
216
+ <span class="text-sm font-medium min-w-0 truncate">{t.solveStopped}</span>
217
+ {:else}
218
+ <Check class="size-4 shrink-0 text-success" aria-hidden="true" />
219
+ <span class="text-sm font-medium shrink-0">{t.solveDone}</span>
220
+ <span class="text-xs text-muted-foreground tabular-nums">{fmt(finished.ms)}</span>
221
+ {/if}
57
222
  </div>
58
- </div>
59
- {/if}
223
+ {:else}
224
+ <div class="px-3 gap-2 flex h-full items-center" in:fade={{ duration: 150 }}>
225
+ <span class="size-1.5 relative shrink-0 rounded-full bg-success">
226
+ {#key ping}
227
+ {#if ping > 0}
228
+ <span class="solve-ping inset-0 absolute rounded-full border-2 border-success"></span>
229
+ {/if}
230
+ {/key}
231
+ </span>
232
+ <span class="text-sm min-w-0 truncate text-muted-foreground">{t.upToDate}</span>
233
+ </div>
234
+ {/if}
235
+ </div>
60
236
  </div>
237
+
238
+ <style>
239
+ /* One ring that grows and fades: the result landed faster than an indicator could show. */
240
+ .solve-ping {
241
+ animation: solve-ping 0.6s ease-out forwards;
242
+ }
243
+
244
+ @keyframes solve-ping {
245
+ from {
246
+ transform: scale(1);
247
+ opacity: 0.9;
248
+ }
249
+ to {
250
+ transform: scale(3.2);
251
+ opacity: 0;
252
+ }
253
+ }
254
+
255
+ @media (prefers-reduced-motion: reduce) {
256
+ .solve-ping {
257
+ animation: none;
258
+ opacity: 0;
259
+ }
260
+ }
261
+ </style>
@@ -1,6 +1,6 @@
1
1
  <script lang="ts">
2
2
  import { Inbox } from '@lucide/svelte';
3
- import { cn } from '$lib/utils.js';
3
+ import { cn } from '#lib/utils.js';
4
4
  import * as Empty from './empty';
5
5
  import { Spinner } from './spinner';
6
6
  import SeverityIcon from './SeverityIcon.svelte';
@@ -4,8 +4,8 @@
4
4
  buttonVariants,
5
5
  type ButtonSize,
6
6
  type ButtonVariant
7
- } from '$lib/components/primitives/button/index.js';
8
- import { cn } from '$lib/utils.js';
7
+ } from '#lib/components/primitives/button/index.js';
8
+ import { cn } from '#lib/utils.js';
9
9
 
10
10
  let {
11
11
  ref = $bindable(null),
@@ -1,7 +1,7 @@
1
1
  <script lang="ts">
2
2
  import { AlertDialog as AlertDialogPrimitive } from 'bits-ui';
3
- import { buttonVariants } from '$lib/components/primitives/button/index.js';
4
- import { cn } from '$lib/utils.js';
3
+ import { buttonVariants } from '#lib/components/primitives/button/index.js';
4
+ import { cn } from '#lib/utils.js';
5
5
 
6
6
  let {
7
7
  ref = $bindable(null),
@@ -1,7 +1,7 @@
1
1
  <script lang="ts">
2
2
  import { AlertDialog as AlertDialogPrimitive } from 'bits-ui';
3
3
  import AlertDialogOverlay from './alert-dialog-overlay.svelte';
4
- import { cn, type WithoutChild, type WithoutChildrenOrChild } from '$lib/utils.js';
4
+ import { cn, type WithoutChild, type WithoutChildrenOrChild } from '#lib/utils.js';
5
5
 
6
6
  let {
7
7
  ref = $bindable(null),
@@ -19,7 +19,7 @@
19
19
  bind:ref
20
20
  data-slot="alert-dialog-content"
21
21
  class={cn(
22
- 'data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 gap-4 p-6 shadow-lg sm:max-w-lg fixed start-1/2 top-1/2 z-50 grid max-h-dialog w-screen-inset -translate-x-1/2 -translate-y-1/2 overflow-y-auto rounded-lg border bg-background duration-200',
22
+ 'data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 gap-4 p-6 sm:max-w-lg fixed start-1/2 top-1/2 z-50 grid max-h-dialog w-screen-inset -translate-x-1/2 -translate-y-1/2 overflow-y-auto rounded-xl border bg-raised shadow-popover duration-200',
23
23
  className
24
24
  )}
25
25
  {...restProps}
@@ -1,6 +1,6 @@
1
1
  <script lang="ts">
2
2
  import { AlertDialog as AlertDialogPrimitive } from 'bits-ui';
3
- import { cn } from '$lib/utils.js';
3
+ import { cn } from '#lib/utils.js';
4
4
 
5
5
  let {
6
6
  ref = $bindable(null),
@@ -1,5 +1,5 @@
1
1
  <script lang="ts">
2
- import { cn, type WithElementRef } from '$lib/utils.js';
2
+ import { cn, type WithElementRef } from '#lib/utils.js';
3
3
  import type { HTMLAttributes } from 'svelte/elements';
4
4
 
5
5
  let {
@@ -1,6 +1,6 @@
1
1
  <script lang="ts">
2
2
  import type { HTMLAttributes } from 'svelte/elements';
3
- import { cn, type WithElementRef } from '$lib/utils.js';
3
+ import { cn, type WithElementRef } from '#lib/utils.js';
4
4
 
5
5
  let {
6
6
  ref = $bindable(null),
@@ -1,6 +1,6 @@
1
1
  <script lang="ts">
2
2
  import { AlertDialog as AlertDialogPrimitive } from 'bits-ui';
3
- import { cn } from '$lib/utils.js';
3
+ import { cn } from '#lib/utils.js';
4
4
 
5
5
  let {
6
6
  ref = $bindable(null),
@@ -1,6 +1,6 @@
1
1
  <script lang="ts">
2
2
  import { AlertDialog as AlertDialogPrimitive } from 'bits-ui';
3
- import { cn } from '$lib/utils.js';
3
+ import { cn } from '#lib/utils.js';
4
4
 
5
5
  let {
6
6
  ref = $bindable(null),