selva-shared 0.8.1

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 (506) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +45 -0
  3. package/dist/components/AppLayout.svelte +439 -0
  4. package/dist/components/AppLayout.svelte.d.ts +17 -0
  5. package/dist/components/CollapsedPanelStrip.svelte +67 -0
  6. package/dist/components/CollapsedPanelStrip.svelte.d.ts +11 -0
  7. package/dist/components/ComputeMessages.svelte +172 -0
  8. package/dist/components/ComputeMessages.svelte.d.ts +7 -0
  9. package/dist/components/ErrorScreen.svelte +55 -0
  10. package/dist/components/ErrorScreen.svelte.d.ts +9 -0
  11. package/dist/components/StateManager.svelte +318 -0
  12. package/dist/components/StateManager.svelte.d.ts +9 -0
  13. package/dist/components/Viewer.svelte +207 -0
  14. package/dist/components/Viewer.svelte.d.ts +12 -0
  15. package/dist/components/layout/FooterItemRenderer.svelte +20 -0
  16. package/dist/components/layout/FooterItemRenderer.svelte.d.ts +7 -0
  17. package/dist/components/layout/PageContainer.svelte +36 -0
  18. package/dist/components/layout/PageContainer.svelte.d.ts +12 -0
  19. package/dist/components/layout/PageFooter.svelte +223 -0
  20. package/dist/components/layout/PageFooter.svelte.d.ts +9 -0
  21. package/dist/components/layout/PageHeader.svelte +89 -0
  22. package/dist/components/layout/PageHeader.svelte.d.ts +12 -0
  23. package/dist/components/layout/index.d.ts +3 -0
  24. package/dist/components/layout/index.js +4 -0
  25. package/dist/components/preview/ChartOutput.svelte +257 -0
  26. package/dist/components/preview/ChartOutput.svelte.d.ts +8 -0
  27. package/dist/components/preview/Group.svelte +121 -0
  28. package/dist/components/preview/Group.svelte.d.ts +23 -0
  29. package/dist/components/preview/InputControl.svelte +119 -0
  30. package/dist/components/preview/InputControl.svelte.d.ts +11 -0
  31. package/dist/components/preview/OutputDisplay.svelte +296 -0
  32. package/dist/components/preview/OutputDisplay.svelte.d.ts +9 -0
  33. package/dist/components/preview/TabBar.svelte +36 -0
  34. package/dist/components/preview/TabBar.svelte.d.ts +8 -0
  35. package/dist/components/preview/TabContent.svelte +124 -0
  36. package/dist/components/preview/TabContent.svelte.d.ts +13 -0
  37. package/dist/components/preview/TabLayout.svelte +109 -0
  38. package/dist/components/preview/TabLayout.svelte.d.ts +13 -0
  39. package/dist/components/preview/index.d.ts +3 -0
  40. package/dist/components/preview/index.js +4 -0
  41. package/dist/components/preview/inputs/CheckboxInput.svelte +29 -0
  42. package/dist/components/preview/inputs/CheckboxInput.svelte.d.ts +10 -0
  43. package/dist/components/preview/inputs/ColorInput.svelte +21 -0
  44. package/dist/components/preview/inputs/ColorInput.svelte.d.ts +7 -0
  45. package/dist/components/preview/inputs/DropdownInput.svelte +40 -0
  46. package/dist/components/preview/inputs/DropdownInput.svelte.d.ts +10 -0
  47. package/dist/components/preview/inputs/FileInput.svelte +358 -0
  48. package/dist/components/preview/inputs/FileInput.svelte.d.ts +10 -0
  49. package/dist/components/preview/inputs/NumberInput.svelte +152 -0
  50. package/dist/components/preview/inputs/NumberInput.svelte.d.ts +11 -0
  51. package/dist/components/preview/inputs/TextInput.svelte +74 -0
  52. package/dist/components/preview/inputs/TextInput.svelte.d.ts +11 -0
  53. package/dist/components/preview/inputs/index.d.ts +6 -0
  54. package/dist/components/preview/inputs/index.js +6 -0
  55. package/dist/components/ui/CalculateButton.svelte +56 -0
  56. package/dist/components/ui/CalculateButton.svelte.d.ts +9 -0
  57. package/dist/components/ui/SolvingIndicator.svelte +55 -0
  58. package/dist/components/ui/SolvingIndicator.svelte.d.ts +6 -0
  59. package/dist/components/ui/StateDisplay.svelte +106 -0
  60. package/dist/components/ui/StateDisplay.svelte.d.ts +10 -0
  61. package/dist/components/ui/alert/alert-description.svelte +23 -0
  62. package/dist/components/ui/alert/alert-description.svelte.d.ts +5 -0
  63. package/dist/components/ui/alert/alert-title.svelte +20 -0
  64. package/dist/components/ui/alert/alert-title.svelte.d.ts +5 -0
  65. package/dist/components/ui/alert/alert.svelte +44 -0
  66. package/dist/components/ui/alert/alert.svelte.d.ts +26 -0
  67. package/dist/components/ui/alert/index.d.ts +5 -0
  68. package/dist/components/ui/alert/index.js +7 -0
  69. package/dist/components/ui/alert-dialog/alert-dialog-action.svelte +18 -0
  70. package/dist/components/ui/alert-dialog/alert-dialog-action.svelte.d.ts +4 -0
  71. package/dist/components/ui/alert-dialog/alert-dialog-cancel.svelte +18 -0
  72. package/dist/components/ui/alert-dialog/alert-dialog-cancel.svelte.d.ts +4 -0
  73. package/dist/components/ui/alert-dialog/alert-dialog-content.svelte +27 -0
  74. package/dist/components/ui/alert-dialog/alert-dialog-content.svelte.d.ts +8 -0
  75. package/dist/components/ui/alert-dialog/alert-dialog-description.svelte +17 -0
  76. package/dist/components/ui/alert-dialog/alert-dialog-description.svelte.d.ts +4 -0
  77. package/dist/components/ui/alert-dialog/alert-dialog-footer.svelte +20 -0
  78. package/dist/components/ui/alert-dialog/alert-dialog-footer.svelte.d.ts +5 -0
  79. package/dist/components/ui/alert-dialog/alert-dialog-header.svelte +20 -0
  80. package/dist/components/ui/alert-dialog/alert-dialog-header.svelte.d.ts +5 -0
  81. package/dist/components/ui/alert-dialog/alert-dialog-overlay.svelte +20 -0
  82. package/dist/components/ui/alert-dialog/alert-dialog-overlay.svelte.d.ts +4 -0
  83. package/dist/components/ui/alert-dialog/alert-dialog-title.svelte +17 -0
  84. package/dist/components/ui/alert-dialog/alert-dialog-title.svelte.d.ts +4 -0
  85. package/dist/components/ui/alert-dialog/alert-dialog-trigger.svelte +7 -0
  86. package/dist/components/ui/alert-dialog/alert-dialog-trigger.svelte.d.ts +4 -0
  87. package/dist/components/ui/alert-dialog/index.d.ts +12 -0
  88. package/dist/components/ui/alert-dialog/index.js +15 -0
  89. package/dist/components/ui/badge/badge.svelte +50 -0
  90. package/dist/components/ui/badge/badge.svelte.d.ts +32 -0
  91. package/dist/components/ui/badge/index.d.ts +2 -0
  92. package/dist/components/ui/badge/index.js +2 -0
  93. package/dist/components/ui/button/button.svelte +83 -0
  94. package/dist/components/ui/button/button.svelte.d.ts +67 -0
  95. package/dist/components/ui/button/index.d.ts +2 -0
  96. package/dist/components/ui/button/index.js +4 -0
  97. package/dist/components/ui/button-group/button-group-separator.svelte +20 -0
  98. package/dist/components/ui/button-group/button-group-separator.svelte.d.ts +13 -0
  99. package/dist/components/ui/button-group/button-group-text.svelte +30 -0
  100. package/dist/components/ui/button-group/button-group-text.svelte.d.ts +11 -0
  101. package/dist/components/ui/button-group/button-group.svelte +46 -0
  102. package/dist/components/ui/button-group/button-group.svelte.d.ts +26 -0
  103. package/dist/components/ui/button-group/index.d.ts +4 -0
  104. package/dist/components/ui/button-group/index.js +6 -0
  105. package/dist/components/ui/card/card-action.svelte +20 -0
  106. package/dist/components/ui/card/card-action.svelte.d.ts +5 -0
  107. package/dist/components/ui/card/card-content.svelte +15 -0
  108. package/dist/components/ui/card/card-content.svelte.d.ts +5 -0
  109. package/dist/components/ui/card/card-description.svelte +20 -0
  110. package/dist/components/ui/card/card-description.svelte.d.ts +5 -0
  111. package/dist/components/ui/card/card-footer.svelte +20 -0
  112. package/dist/components/ui/card/card-footer.svelte.d.ts +5 -0
  113. package/dist/components/ui/card/card-header.svelte +23 -0
  114. package/dist/components/ui/card/card-header.svelte.d.ts +5 -0
  115. package/dist/components/ui/card/card-title.svelte +20 -0
  116. package/dist/components/ui/card/card-title.svelte.d.ts +5 -0
  117. package/dist/components/ui/card/card.svelte +23 -0
  118. package/dist/components/ui/card/card.svelte.d.ts +5 -0
  119. package/dist/components/ui/card/index.d.ts +8 -0
  120. package/dist/components/ui/card/index.js +10 -0
  121. package/dist/components/ui/checkbox/checkbox.svelte +36 -0
  122. package/dist/components/ui/checkbox/checkbox.svelte.d.ts +4 -0
  123. package/dist/components/ui/checkbox/index.d.ts +2 -0
  124. package/dist/components/ui/checkbox/index.js +4 -0
  125. package/dist/components/ui/collapsible/collapsible-content.svelte +7 -0
  126. package/dist/components/ui/collapsible/collapsible-content.svelte.d.ts +4 -0
  127. package/dist/components/ui/collapsible/collapsible-trigger.svelte +7 -0
  128. package/dist/components/ui/collapsible/collapsible-trigger.svelte.d.ts +4 -0
  129. package/dist/components/ui/collapsible/collapsible.svelte +11 -0
  130. package/dist/components/ui/collapsible/collapsible.svelte.d.ts +4 -0
  131. package/dist/components/ui/collapsible/index.d.ts +4 -0
  132. package/dist/components/ui/collapsible/index.js +6 -0
  133. package/dist/components/ui/context-menu/context-menu-checkbox-item.svelte +38 -0
  134. package/dist/components/ui/context-menu/context-menu-checkbox-item.svelte.d.ts +9 -0
  135. package/dist/components/ui/context-menu/context-menu-content.svelte +25 -0
  136. package/dist/components/ui/context-menu/context-menu-content.svelte.d.ts +7 -0
  137. package/dist/components/ui/context-menu/context-menu-group-heading.svelte +21 -0
  138. package/dist/components/ui/context-menu/context-menu-group-heading.svelte.d.ts +7 -0
  139. package/dist/components/ui/context-menu/context-menu-group.svelte +7 -0
  140. package/dist/components/ui/context-menu/context-menu-group.svelte.d.ts +4 -0
  141. package/dist/components/ui/context-menu/context-menu-item.svelte +27 -0
  142. package/dist/components/ui/context-menu/context-menu-item.svelte.d.ts +8 -0
  143. package/dist/components/ui/context-menu/context-menu-label.svelte +24 -0
  144. package/dist/components/ui/context-menu/context-menu-label.svelte.d.ts +8 -0
  145. package/dist/components/ui/context-menu/context-menu-radio-group.svelte +16 -0
  146. package/dist/components/ui/context-menu/context-menu-radio-group.svelte.d.ts +4 -0
  147. package/dist/components/ui/context-menu/context-menu-radio-item.svelte +31 -0
  148. package/dist/components/ui/context-menu/context-menu-radio-item.svelte.d.ts +4 -0
  149. package/dist/components/ui/context-menu/context-menu-separator.svelte +17 -0
  150. package/dist/components/ui/context-menu/context-menu-separator.svelte.d.ts +4 -0
  151. package/dist/components/ui/context-menu/context-menu-shortcut.svelte +20 -0
  152. package/dist/components/ui/context-menu/context-menu-shortcut.svelte.d.ts +5 -0
  153. package/dist/components/ui/context-menu/context-menu-sub-content.svelte +20 -0
  154. package/dist/components/ui/context-menu/context-menu-sub-content.svelte.d.ts +4 -0
  155. package/dist/components/ui/context-menu/context-menu-sub-trigger.svelte +29 -0
  156. package/dist/components/ui/context-menu/context-menu-sub-trigger.svelte.d.ts +8 -0
  157. package/dist/components/ui/context-menu/context-menu-trigger.svelte +7 -0
  158. package/dist/components/ui/context-menu/context-menu-trigger.svelte.d.ts +4 -0
  159. package/dist/components/ui/context-menu/index.d.ts +16 -0
  160. package/dist/components/ui/context-menu/index.js +19 -0
  161. package/dist/components/ui/dialog/dialog-close.svelte +7 -0
  162. package/dist/components/ui/dialog/dialog-close.svelte.d.ts +4 -0
  163. package/dist/components/ui/dialog/dialog-content.svelte +43 -0
  164. package/dist/components/ui/dialog/dialog-content.svelte.d.ts +11 -0
  165. package/dist/components/ui/dialog/dialog-description.svelte +17 -0
  166. package/dist/components/ui/dialog/dialog-description.svelte.d.ts +4 -0
  167. package/dist/components/ui/dialog/dialog-footer.svelte +20 -0
  168. package/dist/components/ui/dialog/dialog-footer.svelte.d.ts +5 -0
  169. package/dist/components/ui/dialog/dialog-header.svelte +20 -0
  170. package/dist/components/ui/dialog/dialog-header.svelte.d.ts +5 -0
  171. package/dist/components/ui/dialog/dialog-overlay.svelte +20 -0
  172. package/dist/components/ui/dialog/dialog-overlay.svelte.d.ts +4 -0
  173. package/dist/components/ui/dialog/dialog-title.svelte +17 -0
  174. package/dist/components/ui/dialog/dialog-title.svelte.d.ts +4 -0
  175. package/dist/components/ui/dialog/dialog-trigger.svelte +7 -0
  176. package/dist/components/ui/dialog/dialog-trigger.svelte.d.ts +4 -0
  177. package/dist/components/ui/dialog/index.d.ts +11 -0
  178. package/dist/components/ui/dialog/index.js +14 -0
  179. package/dist/components/ui/field/field-content.svelte +20 -0
  180. package/dist/components/ui/field/field-content.svelte.d.ts +5 -0
  181. package/dist/components/ui/field/field-description.svelte +25 -0
  182. package/dist/components/ui/field/field-description.svelte.d.ts +5 -0
  183. package/dist/components/ui/field/field-error.svelte +58 -0
  184. package/dist/components/ui/field/field-error.svelte.d.ts +12 -0
  185. package/dist/components/ui/field/field-group.svelte +23 -0
  186. package/dist/components/ui/field/field-group.svelte.d.ts +5 -0
  187. package/dist/components/ui/field/field-label.svelte +26 -0
  188. package/dist/components/ui/field/field-label.svelte.d.ts +10 -0
  189. package/dist/components/ui/field/field-legend.svelte +29 -0
  190. package/dist/components/ui/field/field-legend.svelte.d.ts +8 -0
  191. package/dist/components/ui/field/field-separator.svelte +38 -0
  192. package/dist/components/ui/field/field-separator.svelte.d.ts +9 -0
  193. package/dist/components/ui/field/field-set.svelte +24 -0
  194. package/dist/components/ui/field/field-set.svelte.d.ts +5 -0
  195. package/dist/components/ui/field/field-title.svelte +23 -0
  196. package/dist/components/ui/field/field-title.svelte.d.ts +5 -0
  197. package/dist/components/ui/field/field.svelte +53 -0
  198. package/dist/components/ui/field/field.svelte.d.ts +29 -0
  199. package/dist/components/ui/field/index.d.ts +11 -0
  200. package/dist/components/ui/field/index.js +13 -0
  201. package/dist/components/ui/index.d.ts +21 -0
  202. package/dist/components/ui/index.js +24 -0
  203. package/dist/components/ui/input/index.d.ts +2 -0
  204. package/dist/components/ui/input/index.js +4 -0
  205. package/dist/components/ui/input/input.svelte +52 -0
  206. package/dist/components/ui/input/input.svelte.d.ts +13 -0
  207. package/dist/components/ui/label/index.d.ts +2 -0
  208. package/dist/components/ui/label/index.js +4 -0
  209. package/dist/components/ui/label/label.svelte +20 -0
  210. package/dist/components/ui/label/label.svelte.d.ts +4 -0
  211. package/dist/components/ui/mode-toggle/index.d.ts +1 -0
  212. package/dist/components/ui/mode-toggle/index.js +1 -0
  213. package/dist/components/ui/mode-toggle/mode-toggle.svelte +16 -0
  214. package/dist/components/ui/mode-toggle/mode-toggle.svelte.d.ts +18 -0
  215. package/dist/components/ui/resizable/index.d.ts +4 -0
  216. package/dist/components/ui/resizable/index.js +6 -0
  217. package/dist/components/ui/resizable/resizable-handle.svelte +30 -0
  218. package/dist/components/ui/resizable/resizable-handle.svelte.d.ts +8 -0
  219. package/dist/components/ui/resizable/resizable-pane-group.svelte +20 -0
  220. package/dist/components/ui/resizable/resizable-pane-group.svelte.d.ts +7 -0
  221. package/dist/components/ui/scroll-area/index.d.ts +3 -0
  222. package/dist/components/ui/scroll-area/index.js +5 -0
  223. package/dist/components/ui/scroll-area/scroll-area-scrollbar.svelte +31 -0
  224. package/dist/components/ui/scroll-area/scroll-area-scrollbar.svelte.d.ts +4 -0
  225. package/dist/components/ui/scroll-area/scroll-area.svelte +43 -0
  226. package/dist/components/ui/scroll-area/scroll-area.svelte.d.ts +11 -0
  227. package/dist/components/ui/select/index.d.ts +11 -0
  228. package/dist/components/ui/select/index.js +14 -0
  229. package/dist/components/ui/select/select-content.svelte +40 -0
  230. package/dist/components/ui/select/select-content.svelte.d.ts +8 -0
  231. package/dist/components/ui/select/select-group-heading.svelte +21 -0
  232. package/dist/components/ui/select/select-group-heading.svelte.d.ts +10 -0
  233. package/dist/components/ui/select/select-group.svelte +7 -0
  234. package/dist/components/ui/select/select-group.svelte.d.ts +4 -0
  235. package/dist/components/ui/select/select-item.svelte +38 -0
  236. package/dist/components/ui/select/select-item.svelte.d.ts +4 -0
  237. package/dist/components/ui/select/select-label.svelte +20 -0
  238. package/dist/components/ui/select/select-label.svelte.d.ts +6 -0
  239. package/dist/components/ui/select/select-scroll-down-button.svelte +20 -0
  240. package/dist/components/ui/select/select-scroll-down-button.svelte.d.ts +4 -0
  241. package/dist/components/ui/select/select-scroll-up-button.svelte +20 -0
  242. package/dist/components/ui/select/select-scroll-up-button.svelte.d.ts +4 -0
  243. package/dist/components/ui/select/select-separator.svelte +18 -0
  244. package/dist/components/ui/select/select-separator.svelte.d.ts +4 -0
  245. package/dist/components/ui/select/select-trigger.svelte +29 -0
  246. package/dist/components/ui/select/select-trigger.svelte.d.ts +8 -0
  247. package/dist/components/ui/separator/index.d.ts +2 -0
  248. package/dist/components/ui/separator/index.js +4 -0
  249. package/dist/components/ui/separator/separator.svelte +21 -0
  250. package/dist/components/ui/separator/separator.svelte.d.ts +4 -0
  251. package/dist/components/ui/slider/index.d.ts +2 -0
  252. package/dist/components/ui/slider/index.js +4 -0
  253. package/dist/components/ui/slider/slider.svelte +52 -0
  254. package/dist/components/ui/slider/slider.svelte.d.ts +5 -0
  255. package/dist/components/ui/sonner/index.d.ts +2 -0
  256. package/dist/components/ui/sonner/index.js +2 -0
  257. package/dist/components/ui/sonner/sonner.svelte +13 -0
  258. package/dist/components/ui/sonner/sonner.svelte.d.ts +4 -0
  259. package/dist/components/ui/switch/index.d.ts +2 -0
  260. package/dist/components/ui/switch/index.js +4 -0
  261. package/dist/components/ui/switch/switch.svelte +29 -0
  262. package/dist/components/ui/switch/switch.svelte.d.ts +4 -0
  263. package/dist/components/ui/tabs/index.d.ts +5 -0
  264. package/dist/components/ui/tabs/index.js +7 -0
  265. package/dist/components/ui/tabs/tabs-content.svelte +17 -0
  266. package/dist/components/ui/tabs/tabs-content.svelte.d.ts +4 -0
  267. package/dist/components/ui/tabs/tabs-list.svelte +16 -0
  268. package/dist/components/ui/tabs/tabs-list.svelte.d.ts +4 -0
  269. package/dist/components/ui/tabs/tabs-trigger.svelte +20 -0
  270. package/dist/components/ui/tabs/tabs-trigger.svelte.d.ts +4 -0
  271. package/dist/components/ui/tabs/tabs.svelte +19 -0
  272. package/dist/components/ui/tabs/tabs.svelte.d.ts +4 -0
  273. package/dist/components/ui/textarea/index.d.ts +2 -0
  274. package/dist/components/ui/textarea/index.js +4 -0
  275. package/dist/components/ui/textarea/textarea.svelte +23 -0
  276. package/dist/components/ui/textarea/textarea.svelte.d.ts +5 -0
  277. package/dist/components/ui/theme-switcher/ThemeSwitcher.svelte +39 -0
  278. package/dist/components/ui/theme-switcher/ThemeSwitcher.svelte.d.ts +3 -0
  279. package/dist/components/ui/theme-switcher/index.d.ts +1 -0
  280. package/dist/components/ui/theme-switcher/index.js +1 -0
  281. package/dist/composables/useFooterItem.svelte.d.ts +15 -0
  282. package/dist/composables/useFooterItem.svelte.js +31 -0
  283. package/dist/constants.d.ts +6 -0
  284. package/dist/constants.js +6 -0
  285. package/dist/contexts/FOOTER_USAGE.md +164 -0
  286. package/dist/contexts/footerContext.svelte.d.ts +17 -0
  287. package/dist/contexts/footerContext.svelte.js +24 -0
  288. package/dist/dummy-output-values.d.ts +3 -0
  289. package/dist/dummy-output-values.js +53 -0
  290. package/dist/dummy-surface-chart.json +13 -0
  291. package/dist/example-schema-left-only.json +367 -0
  292. package/dist/example-schema-right-only.json +322 -0
  293. package/dist/example-schema.json +1582 -0
  294. package/dist/features/preview/handlers.d.ts +55 -0
  295. package/dist/features/preview/handlers.js +175 -0
  296. package/dist/features/preview/index.d.ts +2 -0
  297. package/dist/features/preview/index.js +2 -0
  298. package/dist/features/preview/notifications.d.ts +11 -0
  299. package/dist/features/preview/notifications.js +41 -0
  300. package/dist/index.d.ts +29 -0
  301. package/dist/index.js +39 -0
  302. package/dist/stores/themeStore.svelte.d.ts +12 -0
  303. package/dist/stores/themeStore.svelte.js +42 -0
  304. package/dist/styles/base.css +142 -0
  305. package/dist/styles/themes/cyberpunk.css +98 -0
  306. package/dist/styles/themes/neutral.css +72 -0
  307. package/dist/styles/themes/ocean.css +75 -0
  308. package/dist/styles/themes/selva.css +105 -0
  309. package/dist/themes.d.ts +5 -0
  310. package/dist/themes.js +13 -0
  311. package/dist/types/generated/index.d.ts +6 -0
  312. package/dist/types/generated/index.js +6 -0
  313. package/dist/types/generated/preset.d.ts +80 -0
  314. package/dist/types/generated/preset.js +7 -0
  315. package/dist/types/generated/schema.d.ts +451 -0
  316. package/dist/types/generated/schema.js +48 -0
  317. package/dist/utils/computeThrottle.svelte.d.ts +28 -0
  318. package/dist/utils/computeThrottle.svelte.js +93 -0
  319. package/dist/utils/debounce.d.ts +14 -0
  320. package/dist/utils/debounce.js +25 -0
  321. package/dist/utils/file-download.d.ts +26 -0
  322. package/dist/utils/file-download.js +76 -0
  323. package/dist/utils/loadScript.d.ts +14 -0
  324. package/dist/utils/loadScript.js +41 -0
  325. package/dist/utils/param-exporter.d.ts +30 -0
  326. package/dist/utils/param-exporter.js +186 -0
  327. package/dist/utils/solving.svelte.d.ts +12 -0
  328. package/dist/utils/solving.svelte.js +86 -0
  329. package/dist/utils/utils-shared.d.ts +9 -0
  330. package/dist/utils/utils-shared.js +53 -0
  331. package/dist/utils/visibility-rules.d.ts +12 -0
  332. package/dist/utils/visibility-rules.js +52 -0
  333. package/dist/utils.d.ts +12 -0
  334. package/dist/utils.js +5 -0
  335. package/package.json +70 -0
  336. package/src/lib/components/AppLayout.svelte +439 -0
  337. package/src/lib/components/CollapsedPanelStrip.svelte +67 -0
  338. package/src/lib/components/ComputeMessages.svelte +172 -0
  339. package/src/lib/components/ErrorScreen.svelte +55 -0
  340. package/src/lib/components/StateManager.svelte +318 -0
  341. package/src/lib/components/Viewer.svelte +207 -0
  342. package/src/lib/components/layout/FooterItemRenderer.svelte +20 -0
  343. package/src/lib/components/layout/PageContainer.svelte +36 -0
  344. package/src/lib/components/layout/PageFooter.svelte +223 -0
  345. package/src/lib/components/layout/PageHeader.svelte +89 -0
  346. package/src/lib/components/layout/index.ts +4 -0
  347. package/src/lib/components/preview/ChartOutput.svelte +257 -0
  348. package/src/lib/components/preview/Group.svelte +121 -0
  349. package/src/lib/components/preview/InputControl.svelte +119 -0
  350. package/src/lib/components/preview/OutputDisplay.svelte +296 -0
  351. package/src/lib/components/preview/TabBar.svelte +36 -0
  352. package/src/lib/components/preview/TabContent.svelte +124 -0
  353. package/src/lib/components/preview/TabLayout.svelte +109 -0
  354. package/src/lib/components/preview/index.ts +4 -0
  355. package/src/lib/components/preview/inputs/CheckboxInput.svelte +29 -0
  356. package/src/lib/components/preview/inputs/ColorInput.svelte +21 -0
  357. package/src/lib/components/preview/inputs/DropdownInput.svelte +40 -0
  358. package/src/lib/components/preview/inputs/FileInput.svelte +358 -0
  359. package/src/lib/components/preview/inputs/NumberInput.svelte +152 -0
  360. package/src/lib/components/preview/inputs/TextInput.svelte +74 -0
  361. package/src/lib/components/preview/inputs/index.ts +6 -0
  362. package/src/lib/components/ui/CalculateButton.svelte +56 -0
  363. package/src/lib/components/ui/SolvingIndicator.svelte +55 -0
  364. package/src/lib/components/ui/StateDisplay.svelte +106 -0
  365. package/src/lib/components/ui/alert/alert-description.svelte +23 -0
  366. package/src/lib/components/ui/alert/alert-title.svelte +20 -0
  367. package/src/lib/components/ui/alert/alert.svelte +44 -0
  368. package/src/lib/components/ui/alert/index.ts +14 -0
  369. package/src/lib/components/ui/alert-dialog/alert-dialog-action.svelte +18 -0
  370. package/src/lib/components/ui/alert-dialog/alert-dialog-cancel.svelte +18 -0
  371. package/src/lib/components/ui/alert-dialog/alert-dialog-content.svelte +27 -0
  372. package/src/lib/components/ui/alert-dialog/alert-dialog-description.svelte +17 -0
  373. package/src/lib/components/ui/alert-dialog/alert-dialog-footer.svelte +20 -0
  374. package/src/lib/components/ui/alert-dialog/alert-dialog-header.svelte +20 -0
  375. package/src/lib/components/ui/alert-dialog/alert-dialog-overlay.svelte +20 -0
  376. package/src/lib/components/ui/alert-dialog/alert-dialog-title.svelte +17 -0
  377. package/src/lib/components/ui/alert-dialog/alert-dialog-trigger.svelte +7 -0
  378. package/src/lib/components/ui/alert-dialog/index.ts +39 -0
  379. package/src/lib/components/ui/badge/badge.svelte +50 -0
  380. package/src/lib/components/ui/badge/index.ts +2 -0
  381. package/src/lib/components/ui/button/button.svelte +83 -0
  382. package/src/lib/components/ui/button/index.ts +17 -0
  383. package/src/lib/components/ui/button-group/button-group-separator.svelte +20 -0
  384. package/src/lib/components/ui/button-group/button-group-text.svelte +30 -0
  385. package/src/lib/components/ui/button-group/button-group.svelte +46 -0
  386. package/src/lib/components/ui/button-group/index.ts +13 -0
  387. package/src/lib/components/ui/card/card-action.svelte +20 -0
  388. package/src/lib/components/ui/card/card-content.svelte +15 -0
  389. package/src/lib/components/ui/card/card-description.svelte +20 -0
  390. package/src/lib/components/ui/card/card-footer.svelte +20 -0
  391. package/src/lib/components/ui/card/card-header.svelte +23 -0
  392. package/src/lib/components/ui/card/card-title.svelte +20 -0
  393. package/src/lib/components/ui/card/card.svelte +23 -0
  394. package/src/lib/components/ui/card/index.ts +25 -0
  395. package/src/lib/components/ui/checkbox/checkbox.svelte +36 -0
  396. package/src/lib/components/ui/checkbox/index.ts +6 -0
  397. package/src/lib/components/ui/collapsible/collapsible-content.svelte +7 -0
  398. package/src/lib/components/ui/collapsible/collapsible-trigger.svelte +7 -0
  399. package/src/lib/components/ui/collapsible/collapsible.svelte +11 -0
  400. package/src/lib/components/ui/collapsible/index.ts +13 -0
  401. package/src/lib/components/ui/context-menu/context-menu-checkbox-item.svelte +38 -0
  402. package/src/lib/components/ui/context-menu/context-menu-content.svelte +25 -0
  403. package/src/lib/components/ui/context-menu/context-menu-group-heading.svelte +21 -0
  404. package/src/lib/components/ui/context-menu/context-menu-group.svelte +7 -0
  405. package/src/lib/components/ui/context-menu/context-menu-item.svelte +27 -0
  406. package/src/lib/components/ui/context-menu/context-menu-label.svelte +24 -0
  407. package/src/lib/components/ui/context-menu/context-menu-radio-group.svelte +16 -0
  408. package/src/lib/components/ui/context-menu/context-menu-radio-item.svelte +31 -0
  409. package/src/lib/components/ui/context-menu/context-menu-separator.svelte +17 -0
  410. package/src/lib/components/ui/context-menu/context-menu-shortcut.svelte +20 -0
  411. package/src/lib/components/ui/context-menu/context-menu-sub-content.svelte +20 -0
  412. package/src/lib/components/ui/context-menu/context-menu-sub-trigger.svelte +29 -0
  413. package/src/lib/components/ui/context-menu/context-menu-trigger.svelte +7 -0
  414. package/src/lib/components/ui/context-menu/index.ts +51 -0
  415. package/src/lib/components/ui/dialog/dialog-close.svelte +7 -0
  416. package/src/lib/components/ui/dialog/dialog-content.svelte +43 -0
  417. package/src/lib/components/ui/dialog/dialog-description.svelte +17 -0
  418. package/src/lib/components/ui/dialog/dialog-footer.svelte +20 -0
  419. package/src/lib/components/ui/dialog/dialog-header.svelte +20 -0
  420. package/src/lib/components/ui/dialog/dialog-overlay.svelte +20 -0
  421. package/src/lib/components/ui/dialog/dialog-title.svelte +17 -0
  422. package/src/lib/components/ui/dialog/dialog-trigger.svelte +7 -0
  423. package/src/lib/components/ui/dialog/index.ts +37 -0
  424. package/src/lib/components/ui/field/field-content.svelte +20 -0
  425. package/src/lib/components/ui/field/field-description.svelte +25 -0
  426. package/src/lib/components/ui/field/field-error.svelte +58 -0
  427. package/src/lib/components/ui/field/field-group.svelte +23 -0
  428. package/src/lib/components/ui/field/field-label.svelte +26 -0
  429. package/src/lib/components/ui/field/field-legend.svelte +29 -0
  430. package/src/lib/components/ui/field/field-separator.svelte +38 -0
  431. package/src/lib/components/ui/field/field-set.svelte +24 -0
  432. package/src/lib/components/ui/field/field-title.svelte +23 -0
  433. package/src/lib/components/ui/field/field.svelte +53 -0
  434. package/src/lib/components/ui/field/index.ts +33 -0
  435. package/src/lib/components/ui/index.ts +33 -0
  436. package/src/lib/components/ui/input/index.ts +7 -0
  437. package/src/lib/components/ui/input/input.svelte +52 -0
  438. package/src/lib/components/ui/label/index.ts +7 -0
  439. package/src/lib/components/ui/label/label.svelte +20 -0
  440. package/src/lib/components/ui/mode-toggle/index.ts +1 -0
  441. package/src/lib/components/ui/mode-toggle/mode-toggle.svelte +16 -0
  442. package/src/lib/components/ui/resizable/index.ts +13 -0
  443. package/src/lib/components/ui/resizable/resizable-handle.svelte +30 -0
  444. package/src/lib/components/ui/resizable/resizable-pane-group.svelte +20 -0
  445. package/src/lib/components/ui/scroll-area/index.ts +10 -0
  446. package/src/lib/components/ui/scroll-area/scroll-area-scrollbar.svelte +31 -0
  447. package/src/lib/components/ui/scroll-area/scroll-area.svelte +43 -0
  448. package/src/lib/components/ui/select/index.ts +37 -0
  449. package/src/lib/components/ui/select/select-content.svelte +40 -0
  450. package/src/lib/components/ui/select/select-group-heading.svelte +21 -0
  451. package/src/lib/components/ui/select/select-group.svelte +7 -0
  452. package/src/lib/components/ui/select/select-item.svelte +38 -0
  453. package/src/lib/components/ui/select/select-label.svelte +20 -0
  454. package/src/lib/components/ui/select/select-scroll-down-button.svelte +20 -0
  455. package/src/lib/components/ui/select/select-scroll-up-button.svelte +20 -0
  456. package/src/lib/components/ui/select/select-separator.svelte +18 -0
  457. package/src/lib/components/ui/select/select-trigger.svelte +29 -0
  458. package/src/lib/components/ui/separator/index.ts +7 -0
  459. package/src/lib/components/ui/separator/separator.svelte +21 -0
  460. package/src/lib/components/ui/slider/index.ts +7 -0
  461. package/src/lib/components/ui/slider/slider.svelte +52 -0
  462. package/src/lib/components/ui/sonner/index.ts +2 -0
  463. package/src/lib/components/ui/sonner/sonner.svelte +13 -0
  464. package/src/lib/components/ui/switch/index.ts +7 -0
  465. package/src/lib/components/ui/switch/switch.svelte +29 -0
  466. package/src/lib/components/ui/tabs/index.ts +16 -0
  467. package/src/lib/components/ui/tabs/tabs-content.svelte +17 -0
  468. package/src/lib/components/ui/tabs/tabs-list.svelte +16 -0
  469. package/src/lib/components/ui/tabs/tabs-trigger.svelte +20 -0
  470. package/src/lib/components/ui/tabs/tabs.svelte +19 -0
  471. package/src/lib/components/ui/textarea/index.ts +7 -0
  472. package/src/lib/components/ui/textarea/textarea.svelte +23 -0
  473. package/src/lib/components/ui/theme-switcher/ThemeSwitcher.svelte +39 -0
  474. package/src/lib/components/ui/theme-switcher/index.ts +1 -0
  475. package/src/lib/composables/useFooterItem.svelte.ts +39 -0
  476. package/src/lib/constants.ts +6 -0
  477. package/src/lib/contexts/FOOTER_USAGE.md +164 -0
  478. package/src/lib/contexts/footerContext.svelte.ts +52 -0
  479. package/src/lib/dummy-output-values.ts +62 -0
  480. package/src/lib/dummy-surface-chart.json +13 -0
  481. package/src/lib/example-schema-left-only.json +367 -0
  482. package/src/lib/example-schema-right-only.json +322 -0
  483. package/src/lib/example-schema.json +1582 -0
  484. package/src/lib/features/preview/handlers.ts +243 -0
  485. package/src/lib/features/preview/index.ts +2 -0
  486. package/src/lib/features/preview/notifications.ts +52 -0
  487. package/src/lib/index.ts +52 -0
  488. package/src/lib/stores/themeStore.svelte.ts +54 -0
  489. package/src/lib/styles/base.css +142 -0
  490. package/src/lib/styles/themes/cyberpunk.css +98 -0
  491. package/src/lib/styles/themes/neutral.css +72 -0
  492. package/src/lib/styles/themes/ocean.css +75 -0
  493. package/src/lib/styles/themes/selva.css +105 -0
  494. package/src/lib/themes.ts +18 -0
  495. package/src/lib/types/generated/index.ts +6 -0
  496. package/src/lib/types/generated/preset.ts +82 -0
  497. package/src/lib/types/generated/schema.ts +527 -0
  498. package/src/lib/utils/computeThrottle.svelte.ts +117 -0
  499. package/src/lib/utils/debounce.ts +30 -0
  500. package/src/lib/utils/file-download.ts +88 -0
  501. package/src/lib/utils/loadScript.ts +52 -0
  502. package/src/lib/utils/param-exporter.ts +242 -0
  503. package/src/lib/utils/solving.svelte.ts +100 -0
  504. package/src/lib/utils/utils-shared.ts +57 -0
  505. package/src/lib/utils/visibility-rules.ts +97 -0
  506. package/src/lib/utils.ts +13 -0
@@ -0,0 +1,207 @@
1
+ <script lang="ts">
2
+ import { onMount } from 'svelte';
3
+ import { initThree, updateScene } from 'selva-compute/visualization';
4
+ import type { UISchema } from '../types/generated';
5
+ import { Maximize, Minimize, Camera } from '@lucide/svelte';
6
+ import type * as THREE from 'three';
7
+ import type { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
8
+
9
+ interface Props {
10
+ schema: UISchema;
11
+ meshes: any[];
12
+ isFullscreen?: boolean;
13
+ isSolving?: boolean;
14
+ isBlurred?: boolean;
15
+ drawerOpen?: boolean;
16
+ }
17
+
18
+ let {
19
+ schema,
20
+ meshes,
21
+ isFullscreen = $bindable(false),
22
+ isSolving = false,
23
+ isBlurred = false,
24
+ drawerOpen = false
25
+ }: Props = $props();
26
+
27
+ let canvas: HTMLCanvasElement;
28
+ let scene: THREE.Scene | null = null;
29
+ let camera: THREE.PerspectiveCamera | null = null;
30
+ let controls: OrbitControls | null = null;
31
+ let viewerInitialized = false;
32
+ let hideButton = $state(false);
33
+
34
+ // Hide button instantly when expanding, show after animation when collapsing
35
+ $effect(() => {
36
+ if (drawerOpen) {
37
+ hideButton = true;
38
+ } else {
39
+ const timer = setTimeout(() => {
40
+ hideButton = false;
41
+ }, 350);
42
+ return () => clearTimeout(timer);
43
+ }
44
+ });
45
+
46
+ // Initialize Three.js
47
+ onMount(() => {
48
+ if (!canvas) return;
49
+
50
+ const opts = {
51
+ environment: { backgroundColor: schema?.viewerOptions?.backgroundColor ?? '#E6E6E6' }
52
+ };
53
+
54
+ const init = initThree(canvas, opts);
55
+ scene = init.scene;
56
+ camera = init.camera;
57
+ controls = init.controls;
58
+ });
59
+
60
+ // React to meshes changes
61
+ // We need to manually handle cleanup of Lines and Points because selva-compute's updateScene
62
+ // might only clean up Meshes.
63
+ $effect(() => {
64
+ if (scene && camera && controls) {
65
+ // Manual cleanup of types that updateScene might miss (Lines, Points)
66
+
67
+ updateScene(scene, meshes, camera, controls, viewerInitialized);
68
+
69
+ if (!viewerInitialized && meshes.length > 0) {
70
+ viewerInitialized = true;
71
+ }
72
+ }
73
+ });
74
+
75
+ function toggleFullscreen() {
76
+ isFullscreen = !isFullscreen;
77
+ }
78
+
79
+ function downloadScreenshot() {
80
+ if (!canvas) return;
81
+
82
+ // Use requestAnimationFrame to ensure a render has completed
83
+ requestAnimationFrame(() => {
84
+ canvas.toBlob((blob) => {
85
+ if (!blob) return;
86
+ const url = URL.createObjectURL(blob);
87
+ const link = document.createElement('a');
88
+ const timestamp = new Date().toISOString().slice(0, 19).replace(/:/g, '-');
89
+ link.href = url;
90
+ link.download = `viewer-${timestamp}.png`;
91
+ document.body.appendChild(link);
92
+ link.click();
93
+ document.body.removeChild(link);
94
+ URL.revokeObjectURL(url);
95
+ });
96
+ });
97
+ }
98
+ </script>
99
+
100
+ <div
101
+ class="min-h-64 sm:min-h-96 lg:min-h-125 relative h-full flex-1 {isFullscreen
102
+ ? 'fullscreen-viewer'
103
+ : ''}"
104
+ >
105
+ <div class="inset-0 absolute">
106
+ <canvas
107
+ class="block h-full w-full"
108
+ style="touch-action: none;{isFullscreen ? '' : ' border-radius: 0.625rem;'}"
109
+ bind:this={canvas}
110
+ ></canvas>
111
+ </div>
112
+
113
+ <!-- Drawer open blur overlay -->
114
+ <div
115
+ class="inset-0 blur-overlay sm:border absolute z-20 rounded-lg border-border {isBlurred
116
+ ? 'blur-overlay-active'
117
+ : 'blur-overlay-inactive'}"
118
+ ></div>
119
+
120
+ <!-- Solving overlay: blurs the canvas -->
121
+ {#if isSolving}
122
+ <div
123
+ class="inset-0 absolute z-10 animate-[selva-viewer-fade-in_0.2s_ease-out] rounded-lg backdrop-blur-[2px] transition-all duration-300"
124
+ ></div>
125
+ {/if}
126
+
127
+ <!-- Viewer Control Buttons (hidden when drawer is open on mobile) -->
128
+ <div
129
+ class="right-4 {isFullscreen
130
+ ? 'bottom-4'
131
+ : 'bottom-16 sm:bottom-4'} gap-2 absolute z-50 flex items-center"
132
+ style={hideButton ? 'opacity: 0; pointer-events: none;' : 'opacity: 1; pointer-events: auto;'}
133
+ >
134
+ <!-- Screenshot Button -->
135
+ <button
136
+ class="h-10 w-10 shadow-lg hover:shadow-xl flex items-center justify-center rounded-lg border border-border bg-card/90 transition-all hover:bg-card active:scale-95"
137
+ onclick={downloadScreenshot}
138
+ title="Download screenshot"
139
+ aria-label="Download screenshot"
140
+ >
141
+ <Camera class="h-5 w-5 text-card-foreground" />
142
+ </button>
143
+
144
+ <!-- Fullscreen Toggle Button -->
145
+ <button
146
+ class="h-10 w-10 shadow-lg hover:shadow-xl flex items-center justify-center rounded-lg border border-border bg-card/90 transition-all hover:bg-card active:scale-95"
147
+ onclick={toggleFullscreen}
148
+ title={isFullscreen ? 'Exit fullscreen' : 'Enter fullscreen'}
149
+ aria-label={isFullscreen ? 'Exit fullscreen' : 'Enter fullscreen'}
150
+ >
151
+ {#if isFullscreen}
152
+ <Minimize class="h-5 w-5 text-card-foreground" />
153
+ {:else}
154
+ <Maximize class="h-5 w-5 text-card-foreground" />
155
+ {/if}
156
+ </button>
157
+ </div>
158
+ </div>
159
+
160
+ <style>
161
+ .fullscreen-viewer {
162
+ position: fixed;
163
+ inset: 0;
164
+ z-index: 10000;
165
+ border-radius: 0 !important;
166
+ }
167
+
168
+ /* Blur overlay animation */
169
+ .blur-overlay {
170
+ pointer-events: none;
171
+ }
172
+
173
+ .blur-overlay-active {
174
+ animation: blur-in 0.35s cubic-bezier(0.32, 0.72, 0, 1) forwards;
175
+ }
176
+
177
+ .blur-overlay-inactive {
178
+ animation: blur-out 0.35s cubic-bezier(0.32, 0.72, 0, 1) forwards;
179
+ }
180
+
181
+ @keyframes blur-in {
182
+ from {
183
+ backdrop-filter: blur(0px);
184
+ }
185
+ to {
186
+ backdrop-filter: blur(5px);
187
+ }
188
+ }
189
+
190
+ @keyframes blur-out {
191
+ from {
192
+ backdrop-filter: blur(5px);
193
+ }
194
+ to {
195
+ backdrop-filter: blur(0px);
196
+ }
197
+ }
198
+
199
+ @keyframes selva-viewer-fade-in {
200
+ from {
201
+ opacity: 0;
202
+ }
203
+ to {
204
+ opacity: 1;
205
+ }
206
+ }
207
+ </style>
@@ -0,0 +1,12 @@
1
+ import type { UISchema } from '../types/generated';
2
+ interface Props {
3
+ schema: UISchema;
4
+ meshes: any[];
5
+ isFullscreen?: boolean;
6
+ isSolving?: boolean;
7
+ isBlurred?: boolean;
8
+ drawerOpen?: boolean;
9
+ }
10
+ declare const Viewer: import("svelte").Component<Props, {}, "isFullscreen">;
11
+ type Viewer = ReturnType<typeof Viewer>;
12
+ export default Viewer;
@@ -0,0 +1,20 @@
1
+ <script lang="ts">
2
+ import type { FooterItem } from '../../contexts/footerContext.svelte';
3
+
4
+ let { item }: { item: FooterItem } = $props();
5
+
6
+ const itemProps = $derived(item.getProps());
7
+ </script>
8
+
9
+ {#if item.onClick}
10
+ <button
11
+ onclick={item.onClick}
12
+ class="flex items-center gap-1.5 px-2 py-0.5 rounded transition-colors hover:bg-muted cursor-pointer"
13
+ >
14
+ <item.component {...itemProps} />
15
+ </button>
16
+ {:else}
17
+ <div class="flex items-center">
18
+ <item.component {...itemProps} />
19
+ </div>
20
+ {/if}
@@ -0,0 +1,7 @@
1
+ import type { FooterItem } from '../../contexts/footerContext.svelte';
2
+ type $$ComponentProps = {
3
+ item: FooterItem;
4
+ };
5
+ declare const FooterItemRenderer: import("svelte").Component<$$ComponentProps, {}, "">;
6
+ type FooterItemRenderer = ReturnType<typeof FooterItemRenderer>;
7
+ export default FooterItemRenderer;
@@ -0,0 +1,36 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte';
3
+ import PageFooter from './PageFooter.svelte';
4
+
5
+ interface PageContainerProps {
6
+ background?: 'default' | 'white' | 'gray';
7
+ class?: string;
8
+ errors?: string[];
9
+ warnings?: string[];
10
+ children: Snippet;
11
+ footerChildren?: Snippet;
12
+ }
13
+
14
+ let { background = 'default', class: className = '', errors = [], warnings = [], children, footerChildren }: PageContainerProps = $props();
15
+
16
+ const backgroundClasses = {
17
+ default: 'bg-background',
18
+ white: 'bg-background',
19
+ gray: 'bg-muted'
20
+ };
21
+
22
+ const combinedClasses = $derived(
23
+ `flex flex-col h-screen overflow-hidden ${backgroundClasses[background]} ${className}`
24
+ );
25
+ </script>
26
+
27
+ <div class={combinedClasses}>
28
+ {@render children()}
29
+ <div class="shrink-0">
30
+ <PageFooter {errors} {warnings}>
31
+ {#if footerChildren}
32
+ {@render footerChildren()}
33
+ {/if}
34
+ </PageFooter>
35
+ </div>
36
+ </div>
@@ -0,0 +1,12 @@
1
+ import type { Snippet } from 'svelte';
2
+ interface PageContainerProps {
3
+ background?: 'default' | 'white' | 'gray';
4
+ class?: string;
5
+ errors?: string[];
6
+ warnings?: string[];
7
+ children: Snippet;
8
+ footerChildren?: Snippet;
9
+ }
10
+ declare const PageContainer: import("svelte").Component<PageContainerProps, {}, "">;
11
+ type PageContainer = ReturnType<typeof PageContainer>;
12
+ export default PageContainer;
@@ -0,0 +1,223 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte';
3
+ import * as Dialog from '../ui/dialog';
4
+ import * as Collapsible from '../ui/collapsible';
5
+ import { CircleAlert, TriangleAlert, ChevronDown, ChevronRight } from '@lucide/svelte';
6
+ import { SvelteMap } from 'svelte/reactivity';
7
+ import { useFooter, type FooterItem } from '../../contexts/footerContext.svelte';
8
+ import FooterItemRenderer from './FooterItemRenderer.svelte';
9
+
10
+ interface Props {
11
+ errors?: string[];
12
+ warnings?: string[];
13
+ children?: Snippet;
14
+ }
15
+
16
+ let { errors = [], warnings = [], children }: Props = $props();
17
+
18
+ let footerStore = (() => {
19
+ try {
20
+ return useFooter();
21
+ } catch {
22
+ return null;
23
+ }
24
+ })();
25
+
26
+ // Access items directly so SvelteMap reactivity is tracked
27
+ const leftItems = $derived(
28
+ footerStore
29
+ ? Array.from(footerStore.items.values())
30
+ .filter((item) => item.position === 'left')
31
+ .sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0))
32
+ : []
33
+ );
34
+ const rightItems = $derived(
35
+ footerStore
36
+ ? Array.from(footerStore.items.values())
37
+ .filter((item) => item.position === 'right')
38
+ .sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0))
39
+ : []
40
+ );
41
+
42
+ let _currentYear = new Date().getFullYear();
43
+ let dialogOpen = $state(false);
44
+ let showErrors = $state(true);
45
+ let showWarnings = $state(false);
46
+
47
+ const hasMessages = $derived(errors.length > 0 || warnings.length > 0);
48
+ const totalCount = $derived(errors.length + warnings.length);
49
+
50
+ function groupMessages(messages: string[]): Array<{ message: string; count: number }> {
51
+ const grouped = new SvelteMap<string, number>();
52
+
53
+ for (const msg of messages) {
54
+ // Extract the base message without the component GUID
55
+ const baseMsg = msg.replace(/\([a-f0-9-]{36}\)$/i, '(...)').trim();
56
+ const currentCount = grouped.get(baseMsg) || 0;
57
+ grouped.set(baseMsg, currentCount + 1);
58
+ }
59
+
60
+ return Array.from(grouped.entries())
61
+ .map(([message, count]) => ({ message, count }))
62
+ .sort((a, b) => b.count - a.count);
63
+ }
64
+
65
+ const groupedErrors = $derived(groupMessages(errors));
66
+ const groupedWarnings = $derived(groupMessages(warnings));
67
+ </script>
68
+
69
+ <footer
70
+ class="px-4 gap-4 text-xs h-7 mt-2 flex shrink-0 items-center justify-between border-t border-border bg-background text-muted-foreground select-none"
71
+ >
72
+ <!-- Left section: Status items + custom context items -->
73
+ <div class="gap-4 flex items-center">
74
+ <!-- Custom left items from context -->
75
+ {#each leftItems as item (item.id)}
76
+ <FooterItemRenderer {item} />
77
+ {/each}
78
+
79
+ {#if hasMessages}
80
+ <Dialog.Root bind:open={dialogOpen}>
81
+ <Dialog.Trigger
82
+ class="gap-1.5 px-2 py-1 rounded flex cursor-pointer items-center transition-colors hover:bg-muted {errors.length >
83
+ 0
84
+ ? 'text-destructive hover:bg-destructive/10'
85
+ : 'text-warning hover:bg-warning/10'}"
86
+ title={`${totalCount} ${totalCount === 1 ? 'issue' : 'issues'}`}
87
+ >
88
+ {#if errors.length > 0}
89
+ <CircleAlert class="h-3.5 w-3.5" />
90
+ <span class="font-medium">{errors.length} Error{errors.length !== 1 ? 's' : ''}</span>
91
+ {/if}
92
+
93
+ {#if warnings.length > 0}
94
+ {#if errors.length > 0}
95
+ <span class="text-border">•</span>
96
+ {/if}
97
+ <TriangleAlert class="h-3.5 w-3.5" />
98
+ <span class="font-medium"
99
+ >{warnings.length} Warning{warnings.length !== 1 ? 's' : ''}</span
100
+ >
101
+ {/if}
102
+ </Dialog.Trigger>
103
+
104
+ <Dialog.Content class="max-w-2xl max-h-[80vh]">
105
+ <Dialog.Header>
106
+ <Dialog.Title class="gap-2 flex items-center">
107
+ <CircleAlert class="h-5 w-5" />
108
+ Compute Messages
109
+ </Dialog.Title>
110
+ <Dialog.Description>
111
+ {totalCount}
112
+ {totalCount === 1 ? 'issue' : 'issues'} detected during solve
113
+ </Dialog.Description>
114
+ </Dialog.Header>
115
+
116
+ <div class="space-y-3 pr-2 overflow-y-auto" style="max-height: calc(80vh - 180px);">
117
+ <!-- Errors Section -->
118
+ {#if errors.length > 0}
119
+ <Collapsible.Root bind:open={showErrors}>
120
+ <div class="overflow-hidden rounded-lg border border-destructive bg-card">
121
+ <div class="px-4 py-3 flex items-center">
122
+ <Collapsible.Trigger
123
+ class="-mx-4 -my-3 gap-3 px-4 py-3 flex flex-1 items-center text-left transition-colors hover:bg-destructive/5"
124
+ >
125
+ {#if showErrors}
126
+ <ChevronDown class="h-4 w-4 shrink-0 text-destructive" />
127
+ {:else}
128
+ <ChevronRight class="h-4 w-4 shrink-0 text-destructive" />
129
+ {/if}
130
+ <CircleAlert class="h-4 w-4 shrink-0 text-destructive" />
131
+ <span class="text-sm font-medium text-destructive">
132
+ {errors.length === 1 ? '1 Error' : `${errors.length} Errors`}
133
+ </span>
134
+ </Collapsible.Trigger>
135
+ </div>
136
+
137
+ <Collapsible.Content class="space-y-0">
138
+ <div
139
+ class="max-h-60 px-4 py-3 overflow-y-auto border-t border-destructive bg-card"
140
+ >
141
+ <ul class="space-y-2">
142
+ {#each groupedErrors as { message, count } (message)}
143
+ <li class="gap-2 text-sm flex text-destructive/90">
144
+ <span class="shrink-0">•</span>
145
+ <span class="flex-1">
146
+ {message}
147
+ {#if count > 1}
148
+ <span class="ml-1 font-medium text-destructive/70">×{count} </span>
149
+ {/if}
150
+ </span>
151
+ </li>
152
+ {/each}
153
+ </ul>
154
+ </div>
155
+ </Collapsible.Content>
156
+ </div>
157
+ </Collapsible.Root>
158
+ {/if}
159
+
160
+ <!-- Warnings Section -->
161
+ {#if warnings.length > 0}
162
+ <Collapsible.Root bind:open={showWarnings}>
163
+ <div class="overflow-hidden rounded-lg border border-warning/50 bg-card">
164
+ <div class="px-4 py-3 flex items-center">
165
+ <Collapsible.Trigger
166
+ class="-mx-4 -my-3 gap-3 px-4 py-3 flex flex-1 items-center text-left transition-colors hover:bg-warning/5"
167
+ >
168
+ {#if showWarnings}
169
+ <ChevronDown class="h-4 w-4 shrink-0 text-warning" />
170
+ {:else}
171
+ <ChevronRight class="h-4 w-4 shrink-0 text-warning" />
172
+ {/if}
173
+ <TriangleAlert class="h-4 w-4 shrink-0 text-warning" />
174
+ <span class="text-sm font-medium text-warning">
175
+ {warnings.length === 1 ? '1 Warning' : `${warnings.length} Warnings`}
176
+ </span>
177
+ </Collapsible.Trigger>
178
+ </div>
179
+
180
+ <Collapsible.Content class="space-y-0">
181
+ <div
182
+ class="max-h-60 px-4 py-3 overflow-y-auto border-t border-warning/50 bg-card"
183
+ >
184
+ <ul class="space-y-2">
185
+ {#each groupedWarnings as { message, count } (message)}
186
+ <li class="gap-2 text-sm flex text-muted-foreground">
187
+ <span class="shrink-0">•</span>
188
+ <span class="flex-1">
189
+ {message}
190
+ {#if count > 1}
191
+ <span class="ml-1 font-medium text-warning/70">×{count}</span>
192
+ {/if}
193
+ </span>
194
+ </li>
195
+ {/each}
196
+ </ul>
197
+ </div>
198
+ </Collapsible.Content>
199
+ </div>
200
+ </Collapsible.Root>
201
+ {/if}
202
+ </div>
203
+ </Dialog.Content>
204
+ </Dialog.Root>
205
+ {/if}
206
+
207
+ {#if children}
208
+ <div class="gap-4 flex items-center">
209
+ {@render children()}
210
+ </div>
211
+ {/if}
212
+ </div>
213
+
214
+ <!-- Right section: Custom items + Copyright -->
215
+ <div class="gap-4 ml-auto flex items-center">
216
+ <!-- Custom right items from context -->
217
+ {#each rightItems as item (item.id)}
218
+ <FooterItemRenderer {item} />
219
+ {/each}
220
+
221
+ <p>by Selva &copy; {_currentYear}</p>
222
+ </div>
223
+ </footer>
@@ -0,0 +1,9 @@
1
+ import type { Snippet } from 'svelte';
2
+ interface Props {
3
+ errors?: string[];
4
+ warnings?: string[];
5
+ children?: Snippet;
6
+ }
7
+ declare const PageFooter: import("svelte").Component<Props, {}, "">;
8
+ type PageFooter = ReturnType<typeof PageFooter>;
9
+ export default PageFooter;
@@ -0,0 +1,89 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte';
3
+ import { ModeToggle } from '../ui/mode-toggle';
4
+ import { page } from '$app/state';
5
+ import { SvelteURLSearchParams } from 'svelte/reactivity';
6
+
7
+ interface PageHeaderProps {
8
+ title: string;
9
+ showModeToggle?: boolean;
10
+ logo?: string;
11
+ children?: Snippet;
12
+ rightContent?: Snippet;
13
+ class?: string;
14
+ }
15
+
16
+ let {
17
+ title,
18
+ logo = '/favicon/favicon.svg',
19
+ children,
20
+ rightContent,
21
+ class: className = '',
22
+ showModeToggle = false
23
+ }: PageHeaderProps = $props();
24
+
25
+ // Build home URL preserving current session/wsPort query params
26
+ const homeUrl = $derived.by(() => {
27
+ const session = page.url.searchParams.get('session');
28
+ const wsPort = page.url.searchParams.get('wsPort');
29
+ if (!session && !wsPort) return '/';
30
+ const params = new SvelteURLSearchParams();
31
+ if (session) params.set('session', session);
32
+ if (wsPort) params.set('wsPort', wsPort);
33
+ return `/?${params.toString()}`;
34
+ });
35
+ </script>
36
+
37
+ <header
38
+ class={`px-4 py-3 backdrop-blur-sm sm:px-6 mb-0 sm:mb-4 border-b border-border bg-linear-to-b from-background to-card transition-all duration-200 ${className}`}
39
+ >
40
+ <div class="gap-2 sm:flex-row sm:items-center sm:justify-between sm:gap-4 flex flex-col">
41
+ <!-- Left section -->
42
+ <div class="gap-2 min-w-0 sm:gap-3 flex flex-1 items-center">
43
+ {#if logo}
44
+ <a
45
+ href={homeUrl}
46
+ class="shrink-0 cursor-pointer transition-opacity hover:opacity-75"
47
+ title="Go to home"
48
+ >
49
+ <img src={logo} alt="Logo" class="h-8 w-8" />
50
+ </a>
51
+ {/if}
52
+ <h1 class="text-lg font-bold sm:text-2xl truncate text-foreground">
53
+ {title}
54
+ </h1>
55
+
56
+ {#if showModeToggle && !rightContent}
57
+ <div class="sm:hidden ml-auto">
58
+ <ModeToggle />
59
+ </div>
60
+ {/if}
61
+
62
+ {#if children}
63
+ <div class="gap-2 text-xs sm:flex hidden flex-wrap items-center text-muted-foreground">
64
+ {@render children()}
65
+ </div>
66
+ {/if}
67
+ </div>
68
+
69
+ <!-- Right section (rightContent + ModeToggle) -->
70
+ {#if rightContent || showModeToggle}
71
+ <div class="sm:flex gap-2 hidden items-center">
72
+ {#if rightContent}
73
+ {@render rightContent()}
74
+ {/if}
75
+ {#if showModeToggle}
76
+ <ModeToggle />
77
+ {/if}
78
+ </div>
79
+ {/if}
80
+ </div>
81
+ </header>
82
+
83
+ <style>
84
+ :global(header) {
85
+ box-shadow:
86
+ 0 1px 3px rgba(0, 0, 0, 0.08),
87
+ 0 0 0 1px rgba(0, 0, 0, 0.02);
88
+ }
89
+ </style>
@@ -0,0 +1,12 @@
1
+ import type { Snippet } from 'svelte';
2
+ interface PageHeaderProps {
3
+ title: string;
4
+ showModeToggle?: boolean;
5
+ logo?: string;
6
+ children?: Snippet;
7
+ rightContent?: Snippet;
8
+ class?: string;
9
+ }
10
+ declare const PageHeader: import("svelte").Component<PageHeaderProps, {}, "">;
11
+ type PageHeader = ReturnType<typeof PageHeader>;
12
+ export default PageHeader;
@@ -0,0 +1,3 @@
1
+ export { default as PageContainer } from './PageContainer.svelte';
2
+ export { default as PageHeader } from './PageHeader.svelte';
3
+ export { default as PageFooter } from './PageFooter.svelte';
@@ -0,0 +1,4 @@
1
+ // Layout Components - Page structure and organization
2
+ export { default as PageContainer } from './PageContainer.svelte';
3
+ export { default as PageHeader } from './PageHeader.svelte';
4
+ export { default as PageFooter } from './PageFooter.svelte';