@selvajs/ui 6.6.0-beta.8 → 7.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -3
- package/dist/components/ErrorScreen.svelte +1 -1
- package/dist/components/compute/AppLayout.svelte +95 -37
- package/dist/components/compute/AppLayout.svelte.d.ts +18 -1
- package/dist/components/compute/CollapsedPanelStrip.svelte +4 -2
- package/dist/components/compute/ComputeApp.svelte +6 -2
- package/dist/components/compute/ComputeApp.svelte.d.ts +1 -1
- package/dist/components/compute/ComputeMessagesDialog.svelte +3 -3
- package/dist/components/compute/ParameterPresetManager.svelte +9 -21
- package/dist/components/compute/SolveMessages.svelte +101 -87
- package/dist/components/compute/SolveMessages.svelte.d.ts +12 -0
- package/dist/components/layout/AppShell.svelte +2 -2
- package/dist/components/layout/FooterItemRenderer.svelte +2 -2
- package/dist/components/layout/FooterItemRenderer.svelte.d.ts +1 -1
- package/dist/components/layout/PageContent.svelte +3 -2
- package/dist/components/layout/PageFooter.svelte +8 -6
- package/dist/components/layout/PageHeader.svelte +3 -3
- package/dist/components/layout/SideNav.svelte +56 -15
- package/dist/components/layout/SubNav.svelte +2 -2
- package/dist/components/preview/ChartOutput.svelte +158 -62
- package/dist/components/preview/Group.svelte +14 -9
- package/dist/components/preview/HelpButton.svelte +1 -1
- package/dist/components/preview/ImageOutput.svelte +16 -11
- package/dist/components/preview/InputControl.svelte +115 -50
- package/dist/components/preview/InputControl.svelte.d.ts +5 -1
- package/dist/components/preview/OutputDisplay.svelte +26 -17
- package/dist/components/preview/TabBar.svelte +8 -6
- package/dist/components/preview/TabBar.svelte.d.ts +2 -0
- package/dist/components/preview/TabContent.svelte +65 -33
- package/dist/components/preview/TabContent.svelte.d.ts +5 -1
- package/dist/components/preview/TabLayout.svelte +29 -8
- package/dist/components/preview/TabLayout.svelte.d.ts +5 -0
- package/dist/components/preview/inputs/CheckboxInput.svelte +1 -1
- package/dist/components/preview/inputs/ChecklistInput.svelte +11 -6
- package/dist/components/preview/inputs/ChecklistInput.svelte.d.ts +2 -1
- package/dist/components/preview/inputs/ColorInput.svelte +356 -14
- package/dist/components/preview/inputs/ColorInput.svelte.d.ts +1 -0
- package/dist/components/preview/inputs/DropdownInput.svelte +18 -6
- package/dist/components/preview/inputs/DropdownInput.svelte.d.ts +2 -1
- package/dist/components/preview/inputs/FileInput.svelte +71 -75
- package/dist/components/preview/inputs/GeometryInput.svelte +128 -0
- package/dist/components/preview/inputs/GeometryInput.svelte.d.ts +21 -0
- package/dist/components/preview/inputs/NumberInput.svelte +8 -8
- package/dist/components/preview/inputs/OptionGlyph.svelte +29 -0
- package/dist/components/preview/inputs/OptionGlyph.svelte.d.ts +8 -0
- package/dist/components/preview/inputs/SegmentedInput.svelte +45 -0
- package/dist/components/preview/inputs/SegmentedInput.svelte.d.ts +12 -0
- package/dist/components/preview/inputs/TextInput.svelte +5 -5
- package/dist/components/preview/inputs/TileInput.svelte +83 -0
- package/dist/components/preview/inputs/TileInput.svelte.d.ts +12 -0
- package/dist/components/preview/inputs/index.d.ts +3 -0
- package/dist/components/preview/inputs/index.js +3 -0
- package/dist/components/primitives/CalculateButton.svelte +10 -4
- package/dist/components/primitives/Callout.svelte +8 -6
- package/dist/components/primitives/Callout.svelte.d.ts +4 -4
- package/dist/components/primitives/DataTable.svelte +1 -1
- package/dist/components/primitives/FilterableDropdown.svelte +13 -1
- package/dist/components/primitives/FilterableDropdown.svelte.d.ts +5 -0
- package/dist/components/primitives/ImageUploadField.svelte +1 -1
- package/dist/components/primitives/SolvingIndicator.svelte +245 -19
- package/dist/components/primitives/SolvingIndicator.svelte.d.ts +15 -0
- package/dist/components/primitives/alert-dialog/alert-dialog-content.svelte +1 -1
- package/dist/components/primitives/badge/badge.svelte +2 -2
- package/dist/components/primitives/badge/badge.svelte.d.ts +6 -6
- package/dist/components/primitives/button/button.svelte +9 -7
- package/dist/components/primitives/button/button.svelte.d.ts +19 -16
- package/dist/components/primitives/card/card.svelte +1 -1
- package/dist/components/primitives/card/card.svelte.d.ts +1 -1
- package/dist/components/primitives/checkbox/checkbox.svelte +1 -1
- package/dist/components/primitives/command/command-input.svelte +1 -1
- package/dist/components/primitives/command/command-item.svelte +1 -1
- package/dist/components/primitives/command/command-link-item.svelte +1 -1
- package/dist/components/primitives/command/command.svelte +1 -1
- package/dist/components/primitives/context-menu/context-menu-checkbox-item.svelte +1 -1
- package/dist/components/primitives/context-menu/context-menu-content.svelte +1 -1
- package/dist/components/primitives/context-menu/context-menu-item.svelte +1 -1
- package/dist/components/primitives/context-menu/context-menu-radio-item.svelte +1 -1
- package/dist/components/primitives/context-menu/context-menu-sub-content.svelte +1 -1
- package/dist/components/primitives/context-menu/context-menu-sub-trigger.svelte +1 -1
- package/dist/components/primitives/dialog/dialog-content.svelte +3 -3
- package/dist/components/primitives/drawer/Drawer.svelte +1 -1
- package/dist/components/primitives/dropdown-menu/dropdown-menu-checkbox-item.svelte +31 -11
- package/dist/components/primitives/dropdown-menu/dropdown-menu-checkbox-item.svelte.d.ts +2 -0
- package/dist/components/primitives/dropdown-menu/dropdown-menu-content.svelte +5 -1
- package/dist/components/primitives/dropdown-menu/dropdown-menu-content.svelte.d.ts +2 -0
- package/dist/components/primitives/dropdown-menu/dropdown-menu-item.svelte +4 -2
- package/dist/components/primitives/dropdown-menu/dropdown-menu-item.svelte.d.ts +2 -1
- package/dist/components/primitives/dropdown-menu/dropdown-menu-radio-item.svelte +1 -1
- package/dist/components/primitives/dropdown-menu/dropdown-menu-shortcut.svelte +1 -1
- package/dist/components/primitives/dropdown-menu/dropdown-menu-sub-content.svelte +1 -1
- package/dist/components/primitives/dropdown-menu/dropdown-menu-sub-trigger.svelte +1 -1
- package/dist/components/primitives/index.d.ts +1 -1
- package/dist/components/primitives/index.js +1 -1
- package/dist/components/primitives/input/input.svelte +2 -2
- package/dist/components/primitives/input-group/input-group-input.svelte.d.ts +1 -1
- package/dist/components/primitives/input-group/input-group.svelte +1 -1
- package/dist/components/primitives/mode-toggle/mode-toggle.svelte +2 -2
- package/dist/components/primitives/popover/popover-content.svelte +1 -1
- package/dist/components/primitives/resizable/resizable-handle.svelte +2 -2
- package/dist/components/primitives/search/search.svelte +1 -1
- package/dist/components/primitives/select/select-content.svelte +1 -1
- package/dist/components/primitives/select/select-item.svelte +1 -1
- package/dist/components/primitives/select/select-trigger.svelte +1 -1
- package/dist/components/primitives/slider/slider.svelte +1 -1
- package/dist/components/primitives/switch/switch.svelte +1 -1
- package/dist/components/primitives/tabs/tabs-list.svelte +2 -2
- package/dist/components/primitives/tabs/tabs-list.svelte.d.ts +6 -6
- package/dist/components/primitives/tabs/tabs-trigger.svelte +2 -2
- package/dist/components/primitives/tabs/tabs-trigger.svelte.d.ts +6 -6
- package/dist/components/primitives/textarea/textarea.svelte +1 -1
- package/dist/components/primitives/toggle/toggle.svelte +11 -3
- package/dist/components/primitives/toggle/toggle.svelte.d.ts +13 -4
- package/dist/components/primitives/toggle-group/toggle-group-item.svelte +1 -1
- package/dist/components/primitives/toggle-group/toggle-group.svelte +1 -1
- package/dist/components/primitives/tooltip/index.d.ts +6 -0
- package/dist/components/primitives/tooltip/index.js +8 -0
- package/dist/components/primitives/tooltip/tooltip-content.svelte +34 -0
- package/dist/components/primitives/tooltip/tooltip-content.svelte.d.ts +10 -0
- package/dist/components/primitives/tooltip/tooltip-portal.svelte +7 -0
- package/dist/components/primitives/tooltip/tooltip-portal.svelte.d.ts +4 -0
- package/dist/components/primitives/tooltip/tooltip-provider.svelte +7 -0
- package/dist/components/primitives/tooltip/tooltip-provider.svelte.d.ts +4 -0
- package/dist/components/primitives/tooltip/tooltip-trigger.svelte +7 -0
- package/dist/components/primitives/tooltip/tooltip-trigger.svelte.d.ts +4 -0
- package/dist/components/primitives/tooltip/tooltip.svelte +7 -0
- package/dist/components/primitives/tooltip/tooltip.svelte.d.ts +4 -0
- package/dist/components/viewer/MeshMetadataPanel.svelte +2 -2
- package/dist/components/viewer/SceneManager.svelte +32 -21
- package/dist/components/viewer/SceneManager.svelte.d.ts +3 -1
- package/dist/components/viewer/Viewer.svelte +135 -185
- package/dist/components/viewer/Viewer.svelte.d.ts +7 -2
- package/dist/components/viewer/ViewerDock.svelte +404 -0
- package/dist/components/viewer/ViewerDock.svelte.d.ts +42 -0
- package/dist/composables/useFooterItem.svelte.d.ts +1 -1
- package/dist/composables/useFooterItem.svelte.js +1 -1
- package/dist/compute/liveProgress.svelte.d.ts +16 -0
- package/dist/compute/liveProgress.svelte.js +90 -0
- package/dist/compute/solving.svelte.d.ts +11 -7
- package/dist/compute/solving.svelte.js +64 -45
- package/dist/constants.d.ts +6 -8
- package/dist/constants.js +8 -11
- package/dist/contexts/hostContext.svelte.d.ts +39 -0
- package/dist/contexts/hostContext.svelte.js +9 -0
- package/dist/features/chart/plotly-compat.d.ts +15 -0
- package/dist/features/chart/plotly-compat.js +124 -0
- package/dist/i18n/messages.d.ts +50 -0
- package/dist/i18n/messages.js +84 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +5 -0
- package/dist/public.d.ts +1 -0
- package/dist/public.js +1 -0
- package/dist/schema/host-support.d.ts +29 -0
- package/dist/schema/host-support.js +97 -0
- package/dist/schema/option-display.d.ts +12 -0
- package/dist/schema/option-display.js +29 -0
- package/dist/schema/param-exporter.d.ts +4 -1
- package/dist/schema/param-exporter.js +10 -6
- package/dist/schema/visibility-rules.d.ts +7 -1
- package/dist/schema/visibility-rules.js +17 -0
- package/dist/styles/base.css +94 -84
- package/dist/utils/color-space.d.ts +21 -0
- package/dist/utils/color-space.js +90 -0
- package/dist/utils/file-download.js +6 -10
- package/dist/utils/host-files.d.ts +12 -0
- package/dist/utils/host-files.js +46 -0
- package/dist/utils/webp-to-png.d.ts +10 -0
- package/dist/utils/webp-to-png.js +41 -0
- package/package.json +31 -23
- package/src/lib/components/ErrorScreen.svelte +1 -1
- package/src/lib/components/compute/AppLayout.svelte +96 -38
- package/src/lib/components/compute/CollapsedPanelStrip.svelte +4 -2
- package/src/lib/components/compute/ComputeApp.svelte +6 -2
- package/src/lib/components/compute/ComputeMessagesDialog.svelte +4 -4
- package/src/lib/components/compute/ParameterPresetManager.svelte +9 -21
- package/src/lib/components/compute/SolveMessages.svelte +103 -89
- package/src/lib/components/layout/AppShell.svelte +2 -2
- package/src/lib/components/layout/FooterItemRenderer.svelte +2 -2
- package/src/lib/components/layout/PageContent.svelte +3 -2
- package/src/lib/components/layout/PageFooter.svelte +8 -6
- package/src/lib/components/layout/PageHeader.svelte +3 -3
- package/src/lib/components/layout/SideNav.svelte +56 -15
- package/src/lib/components/layout/SubNav.svelte +2 -2
- package/src/lib/components/preview/ChartOutput.svelte +158 -62
- package/src/lib/components/preview/Group.svelte +14 -9
- package/src/lib/components/preview/HelpButton.svelte +1 -1
- package/src/lib/components/preview/ImageOutput.svelte +16 -11
- package/src/lib/components/preview/InputControl.svelte +115 -50
- package/src/lib/components/preview/OutputDisplay.svelte +26 -17
- package/src/lib/components/preview/TabBar.svelte +8 -6
- package/src/lib/components/preview/TabContent.svelte +65 -33
- package/src/lib/components/preview/TabLayout.svelte +29 -8
- package/src/lib/components/preview/inputs/CheckboxInput.svelte +1 -1
- package/src/lib/components/preview/inputs/ChecklistInput.svelte +11 -6
- package/src/lib/components/preview/inputs/ColorInput.svelte +356 -14
- package/src/lib/components/preview/inputs/DropdownInput.svelte +18 -6
- package/src/lib/components/preview/inputs/FileInput.svelte +71 -75
- package/src/lib/components/preview/inputs/GeometryInput.svelte +128 -0
- package/src/lib/components/preview/inputs/NumberInput.svelte +8 -8
- package/src/lib/components/preview/inputs/OptionGlyph.svelte +29 -0
- package/src/lib/components/preview/inputs/SegmentedInput.svelte +45 -0
- package/src/lib/components/preview/inputs/TextInput.svelte +5 -5
- package/src/lib/components/preview/inputs/TileInput.svelte +83 -0
- package/src/lib/components/preview/inputs/index.ts +3 -0
- package/src/lib/components/primitives/CalculateButton.svelte +10 -4
- package/src/lib/components/primitives/Callout.svelte +9 -7
- package/src/lib/components/primitives/DataTable.svelte +1 -1
- package/src/lib/components/primitives/FilterableDropdown.svelte +14 -2
- package/src/lib/components/primitives/ImageUploadField.svelte +1 -1
- package/src/lib/components/primitives/IssueList.svelte +1 -1
- package/src/lib/components/primitives/SeverityIcon.svelte +1 -1
- package/src/lib/components/primitives/SolvingIndicator.svelte +245 -19
- package/src/lib/components/primitives/StateDisplay.svelte +1 -1
- package/src/lib/components/primitives/alert-dialog/alert-dialog-action.svelte +2 -2
- package/src/lib/components/primitives/alert-dialog/alert-dialog-cancel.svelte +2 -2
- package/src/lib/components/primitives/alert-dialog/alert-dialog-content.svelte +2 -2
- package/src/lib/components/primitives/alert-dialog/alert-dialog-description.svelte +1 -1
- package/src/lib/components/primitives/alert-dialog/alert-dialog-footer.svelte +1 -1
- package/src/lib/components/primitives/alert-dialog/alert-dialog-header.svelte +1 -1
- package/src/lib/components/primitives/alert-dialog/alert-dialog-overlay.svelte +1 -1
- package/src/lib/components/primitives/alert-dialog/alert-dialog-title.svelte +1 -1
- package/src/lib/components/primitives/badge/badge.svelte +3 -3
- package/src/lib/components/primitives/button/button.svelte +9 -7
- package/src/lib/components/primitives/button-group/button-group-separator.svelte +2 -2
- package/src/lib/components/primitives/button-group/button-group-text.svelte +1 -1
- package/src/lib/components/primitives/button-group/button-group.svelte +1 -1
- package/src/lib/components/primitives/card/card-content.svelte +1 -1
- package/src/lib/components/primitives/card/card-description.svelte +1 -1
- package/src/lib/components/primitives/card/card-footer.svelte +1 -1
- package/src/lib/components/primitives/card/card-header.svelte +1 -1
- package/src/lib/components/primitives/card/card-title.svelte +1 -1
- package/src/lib/components/primitives/card/card.svelte +2 -2
- package/src/lib/components/primitives/checkbox/checkbox.svelte +2 -2
- package/src/lib/components/primitives/command/command-dialog.svelte +2 -2
- package/src/lib/components/primitives/command/command-empty.svelte +1 -1
- package/src/lib/components/primitives/command/command-group.svelte +1 -1
- package/src/lib/components/primitives/command/command-input.svelte +3 -3
- package/src/lib/components/primitives/command/command-item.svelte +2 -2
- package/src/lib/components/primitives/command/command-link-item.svelte +2 -2
- package/src/lib/components/primitives/command/command-list.svelte +1 -1
- package/src/lib/components/primitives/command/command-separator.svelte +1 -1
- package/src/lib/components/primitives/command/command-shortcut.svelte +1 -1
- package/src/lib/components/primitives/command/command.svelte +2 -2
- package/src/lib/components/primitives/context-menu/context-menu-checkbox-item.svelte +2 -2
- package/src/lib/components/primitives/context-menu/context-menu-content.svelte +2 -2
- package/src/lib/components/primitives/context-menu/context-menu-group-heading.svelte +1 -1
- package/src/lib/components/primitives/context-menu/context-menu-item.svelte +2 -2
- package/src/lib/components/primitives/context-menu/context-menu-label.svelte +1 -1
- package/src/lib/components/primitives/context-menu/context-menu-radio-item.svelte +2 -2
- package/src/lib/components/primitives/context-menu/context-menu-separator.svelte +1 -1
- package/src/lib/components/primitives/context-menu/context-menu-shortcut.svelte +1 -1
- package/src/lib/components/primitives/context-menu/context-menu-sub-content.svelte +2 -2
- package/src/lib/components/primitives/context-menu/context-menu-sub-trigger.svelte +2 -2
- package/src/lib/components/primitives/dialog/dialog-content.svelte +4 -4
- package/src/lib/components/primitives/dialog/dialog-description.svelte +1 -1
- package/src/lib/components/primitives/dialog/dialog-footer.svelte +1 -1
- package/src/lib/components/primitives/dialog/dialog-header.svelte +1 -1
- package/src/lib/components/primitives/dialog/dialog-overlay.svelte +1 -1
- package/src/lib/components/primitives/dialog/dialog-title.svelte +1 -1
- package/src/lib/components/primitives/drawer/Drawer.svelte +1 -1
- package/src/lib/components/primitives/dropdown-menu/dropdown-menu-checkbox-item.svelte +32 -12
- package/src/lib/components/primitives/dropdown-menu/dropdown-menu-content.svelte +6 -2
- package/src/lib/components/primitives/dropdown-menu/dropdown-menu-group-heading.svelte +1 -1
- package/src/lib/components/primitives/dropdown-menu/dropdown-menu-item.svelte +5 -3
- package/src/lib/components/primitives/dropdown-menu/dropdown-menu-label.svelte +1 -1
- package/src/lib/components/primitives/dropdown-menu/dropdown-menu-radio-item.svelte +2 -2
- package/src/lib/components/primitives/dropdown-menu/dropdown-menu-separator.svelte +1 -1
- package/src/lib/components/primitives/dropdown-menu/dropdown-menu-shortcut.svelte +2 -2
- package/src/lib/components/primitives/dropdown-menu/dropdown-menu-sub-content.svelte +2 -2
- package/src/lib/components/primitives/dropdown-menu/dropdown-menu-sub-trigger.svelte +2 -2
- package/src/lib/components/primitives/empty/empty-content.svelte +1 -1
- package/src/lib/components/primitives/empty/empty-description.svelte +1 -1
- package/src/lib/components/primitives/empty/empty-header.svelte +1 -1
- package/src/lib/components/primitives/empty/empty-media.svelte +1 -1
- package/src/lib/components/primitives/empty/empty-title.svelte +1 -1
- package/src/lib/components/primitives/empty/empty.svelte +1 -1
- package/src/lib/components/primitives/field/field-content.svelte +1 -1
- package/src/lib/components/primitives/field/field-description.svelte +1 -1
- package/src/lib/components/primitives/field/field-error.svelte +1 -1
- package/src/lib/components/primitives/field/field-group.svelte +1 -1
- package/src/lib/components/primitives/field/field-label.svelte +2 -2
- package/src/lib/components/primitives/field/field-legend.svelte +1 -1
- package/src/lib/components/primitives/field/field-separator.svelte +2 -2
- package/src/lib/components/primitives/field/field-set.svelte +1 -1
- package/src/lib/components/primitives/field/field-title.svelte +1 -1
- package/src/lib/components/primitives/field/field.svelte +1 -1
- package/src/lib/components/primitives/index.ts +1 -1
- package/src/lib/components/primitives/input/input.svelte +3 -3
- package/src/lib/components/primitives/input-group/input-group-addon.svelte +1 -1
- package/src/lib/components/primitives/input-group/input-group-button.svelte +2 -2
- package/src/lib/components/primitives/input-group/input-group-input.svelte +2 -2
- package/src/lib/components/primitives/input-group/input-group-text.svelte +1 -1
- package/src/lib/components/primitives/input-group/input-group-textarea.svelte +2 -2
- package/src/lib/components/primitives/input-group/input-group.svelte +2 -2
- package/src/lib/components/primitives/label/label.svelte +1 -1
- package/src/lib/components/primitives/mode-toggle/mode-toggle.svelte +2 -2
- package/src/lib/components/primitives/popover/popover-content.svelte +2 -2
- package/src/lib/components/primitives/popover/popover-description.svelte +1 -1
- package/src/lib/components/primitives/popover/popover-header.svelte +1 -1
- package/src/lib/components/primitives/popover/popover-title.svelte +1 -1
- package/src/lib/components/primitives/popover/popover-trigger.svelte +1 -1
- package/src/lib/components/primitives/resizable/resizable-handle.svelte +3 -3
- package/src/lib/components/primitives/resizable/resizable-pane-group.svelte +1 -1
- package/src/lib/components/primitives/scroll-area/scroll-area-scrollbar.svelte +1 -1
- package/src/lib/components/primitives/scroll-area/scroll-area.svelte +1 -1
- package/src/lib/components/primitives/search/search.svelte +2 -2
- package/src/lib/components/primitives/select/select-content.svelte +2 -2
- package/src/lib/components/primitives/select/select-group-heading.svelte +1 -1
- package/src/lib/components/primitives/select/select-item.svelte +2 -2
- package/src/lib/components/primitives/select/select-label.svelte +1 -1
- package/src/lib/components/primitives/select/select-scroll-down-button.svelte +1 -1
- package/src/lib/components/primitives/select/select-scroll-up-button.svelte +1 -1
- package/src/lib/components/primitives/select/select-separator.svelte +2 -2
- package/src/lib/components/primitives/select/select-trigger.svelte +2 -2
- package/src/lib/components/primitives/separator/separator.svelte +1 -1
- package/src/lib/components/primitives/slider/slider.svelte +2 -2
- package/src/lib/components/primitives/spinner/spinner.svelte +1 -1
- package/src/lib/components/primitives/switch/switch.svelte +2 -2
- package/src/lib/components/primitives/tabs/tabs-content.svelte +1 -1
- package/src/lib/components/primitives/tabs/tabs-list.svelte +3 -3
- package/src/lib/components/primitives/tabs/tabs-trigger.svelte +3 -3
- package/src/lib/components/primitives/tabs/tabs.svelte +1 -1
- package/src/lib/components/primitives/textarea/textarea.svelte +2 -2
- package/src/lib/components/primitives/toggle/toggle.svelte +12 -4
- package/src/lib/components/primitives/toggle-group/toggle-group-item.svelte +3 -3
- package/src/lib/components/primitives/toggle-group/toggle-group.svelte +3 -3
- package/src/lib/components/primitives/tooltip/index.ts +19 -0
- package/src/lib/components/primitives/tooltip/tooltip-content.svelte +34 -0
- package/src/lib/components/primitives/tooltip/tooltip-portal.svelte +7 -0
- package/src/lib/components/primitives/tooltip/tooltip-provider.svelte +7 -0
- package/src/lib/components/primitives/tooltip/tooltip-trigger.svelte +7 -0
- package/src/lib/components/primitives/tooltip/tooltip.svelte +7 -0
- package/src/lib/components/viewer/MeshMetadataPanel.svelte +2 -2
- package/src/lib/components/viewer/SceneManager.svelte +32 -21
- package/src/lib/components/viewer/Viewer.svelte +136 -186
- package/src/lib/components/viewer/ViewerDock.svelte +404 -0
- package/src/lib/composables/useFooterItem.svelte.ts +1 -1
- package/src/lib/compute/liveProgress.svelte.ts +103 -0
- package/src/lib/compute/solving.svelte.ts +66 -50
- package/src/lib/constants.ts +8 -11
- package/src/lib/contexts/hostContext.svelte.ts +51 -0
- package/src/lib/features/chart/plotly-compat.ts +141 -0
- package/src/lib/i18n/messages.ts +139 -0
- package/src/lib/index.ts +22 -0
- package/src/lib/public.ts +1 -0
- package/src/lib/schema/host-support.ts +129 -0
- package/src/lib/schema/option-display.ts +44 -0
- package/src/lib/schema/param-exporter.ts +10 -7
- package/src/lib/schema/visibility-rules.ts +27 -1
- package/src/lib/styles/base.css +94 -84
- package/src/lib/utils/color-space.ts +107 -0
- package/src/lib/utils/file-download.ts +7 -11
- package/src/lib/utils/host-files.ts +61 -0
- package/src/lib/utils/webp-to-png.ts +48 -0
- package/dist/components/primitives/theme-switcher/ThemeSwitcher.svelte +0 -39
- package/dist/components/primitives/theme-switcher/ThemeSwitcher.svelte.d.ts +0 -3
- package/dist/components/primitives/theme-switcher/index.d.ts +0 -1
- package/dist/components/primitives/theme-switcher/index.js +0 -1
- package/dist/styles/themes/cyberpunk.css +0 -98
- package/dist/styles/themes/neutral.css +0 -72
- package/dist/styles/themes/ocean.css +0 -75
- package/dist/styles/themes/selva.css +0 -105
- package/dist/theme/themeStore.svelte.d.ts +0 -12
- package/dist/theme/themeStore.svelte.js +0 -40
- package/dist/theme/themes.d.ts +0 -5
- package/dist/theme/themes.js +0 -13
- package/src/lib/components/primitives/theme-switcher/ThemeSwitcher.svelte +0 -39
- package/src/lib/components/primitives/theme-switcher/index.ts +0 -1
- package/src/lib/styles/themes/cyberpunk.css +0 -98
- package/src/lib/styles/themes/neutral.css +0 -72
- package/src/lib/styles/themes/ocean.css +0 -75
- package/src/lib/styles/themes/selva.css +0 -105
- package/src/lib/theme/themeStore.svelte.ts +0 -50
- package/src/lib/theme/themes.ts +0 -18
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
} from '../../schema/param-exporter';
|
|
11
11
|
import { Button, Input, Label, Textarea, Dialog, Callout, IssueList, toast } from '../primitives';
|
|
12
12
|
import { DEFAULT_PRESET_LABELS, type PresetLabels } from '../../types/presetLabels';
|
|
13
|
+
import { pickFile } from '../../utils/host-files';
|
|
13
14
|
|
|
14
15
|
interface Props {
|
|
15
16
|
schema: UISchema;
|
|
@@ -37,7 +38,6 @@
|
|
|
37
38
|
let showLoadDialog = $state(false);
|
|
38
39
|
let loadResult = $state<PresetLoadResult | null>(null);
|
|
39
40
|
let loadingPresetName = $state('');
|
|
40
|
-
let fileInputRef = $state<HTMLInputElement | null>(null);
|
|
41
41
|
|
|
42
42
|
let listedStates = $state<ParameterPreset[]>([]);
|
|
43
43
|
let isLoadingList = $state(false);
|
|
@@ -69,7 +69,7 @@
|
|
|
69
69
|
});
|
|
70
70
|
|
|
71
71
|
if (onSaveState) await onSaveState(state);
|
|
72
|
-
else exportStateAsJson(state);
|
|
72
|
+
else await exportStateAsJson(state);
|
|
73
73
|
showExportDialog = false;
|
|
74
74
|
}
|
|
75
75
|
|
|
@@ -86,19 +86,16 @@
|
|
|
86
86
|
}
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
-
async function
|
|
90
|
-
|
|
91
|
-
|
|
89
|
+
async function importFromFile() {
|
|
90
|
+
// .sps is the pre-rename extension; files with it exist on users' drives, so keep accepting it.
|
|
91
|
+
const file = await pickFile({ accept: '.slvp,.sps' });
|
|
92
|
+
if (!file) return;
|
|
92
93
|
|
|
93
94
|
try {
|
|
94
|
-
|
|
95
|
-
tryLoad(imported);
|
|
95
|
+
tryLoad(await importStateFromJson(file));
|
|
96
96
|
} catch (error) {
|
|
97
97
|
toast.error(t.loadImportError + (error as Error).message);
|
|
98
98
|
}
|
|
99
|
-
|
|
100
|
-
// Reset so re-picking the same file fires `change` again.
|
|
101
|
-
input.value = '';
|
|
102
99
|
}
|
|
103
100
|
|
|
104
101
|
function confirmLoad() {
|
|
@@ -132,8 +129,8 @@
|
|
|
132
129
|
}
|
|
133
130
|
|
|
134
131
|
function handleLoadClick() {
|
|
135
|
-
fileInputRef?.click();
|
|
136
132
|
showLoadDialog = false;
|
|
133
|
+
void importFromFile();
|
|
137
134
|
}
|
|
138
135
|
|
|
139
136
|
function selectListedState(preset: ParameterPreset) {
|
|
@@ -142,15 +139,6 @@
|
|
|
142
139
|
}
|
|
143
140
|
</script>
|
|
144
141
|
|
|
145
|
-
<!-- .sps is the pre-rename extension; files with it exist on users' drives, so keep accepting it. -->
|
|
146
|
-
<input
|
|
147
|
-
bind:this={fileInputRef}
|
|
148
|
-
type="file"
|
|
149
|
-
accept=".slvp,.sps"
|
|
150
|
-
onchange={handleImport}
|
|
151
|
-
class="hidden"
|
|
152
|
-
/>
|
|
153
|
-
|
|
154
142
|
<!-- Save Dialog -->
|
|
155
143
|
<Dialog.Root bind:open={showExportDialog}>
|
|
156
144
|
<Dialog.Content>
|
|
@@ -215,7 +203,7 @@
|
|
|
215
203
|
<button
|
|
216
204
|
type="button"
|
|
217
205
|
onclick={() => selectListedState(preset)}
|
|
218
|
-
class="p-3 w-full rounded-lg border text-left transition-colors hover:bg-
|
|
206
|
+
class="p-3 w-full rounded-lg border text-left transition-colors hover:bg-hover"
|
|
219
207
|
>
|
|
220
208
|
<div class="text-sm font-medium">{preset.name}</div>
|
|
221
209
|
{#if preset.description}
|
|
@@ -16,10 +16,11 @@
|
|
|
16
16
|
import { LoaderCircle } from '@lucide/svelte';
|
|
17
17
|
import type { SolveDiagnostic } from '@selvajs/solve/shared';
|
|
18
18
|
import type { LiveSolveState, SolvePhase } from '@selvajs/solve/client';
|
|
19
|
-
import { Button } from '
|
|
20
|
-
import IssueList, { type Issue } from '
|
|
21
|
-
import SeverityIcon from '
|
|
22
|
-
import { getLocaleContext } from '
|
|
19
|
+
import { Button } from '#lib/components/primitives/button/index.js';
|
|
20
|
+
import IssueList, { type Issue } from '#lib/components/primitives/IssueList.svelte';
|
|
21
|
+
import SeverityIcon from '#lib/components/primitives/SeverityIcon.svelte';
|
|
22
|
+
import { getLocaleContext } from '#lib/i18n/localeContext.svelte.js';
|
|
23
|
+
import { createLiveProgress } from '#lib/compute/liveProgress.svelte.js';
|
|
23
24
|
|
|
24
25
|
interface Props {
|
|
25
26
|
/** What the running (or most recent) solve has said over the live channel. */
|
|
@@ -31,6 +32,18 @@
|
|
|
31
32
|
onabort: () => void;
|
|
32
33
|
onconfirm: () => void;
|
|
33
34
|
ondiscard: () => void;
|
|
35
|
+
/**
|
|
36
|
+
* See `createSolvingIndicator`. The live panel would only paint once the solve is over, so
|
|
37
|
+
* an Esc hint stands in for it; the result's messages still show.
|
|
38
|
+
*/
|
|
39
|
+
freezesDuringSolve?: boolean;
|
|
40
|
+
/** `floating` overlays the bottom centre; `inline` sits in the flow below the host's content. */
|
|
41
|
+
placement?: 'floating' | 'inline';
|
|
42
|
+
/**
|
|
43
|
+
* The host shows progress and Abort itself (`AppLayout`'s solve status), so the live view
|
|
44
|
+
* keeps only the messages that arrive mid-solve.
|
|
45
|
+
*/
|
|
46
|
+
progressShownByHost?: boolean;
|
|
34
47
|
}
|
|
35
48
|
|
|
36
49
|
let {
|
|
@@ -39,7 +52,10 @@
|
|
|
39
52
|
diagnostics = [],
|
|
40
53
|
onabort,
|
|
41
54
|
onconfirm,
|
|
42
|
-
ondiscard
|
|
55
|
+
ondiscard,
|
|
56
|
+
freezesDuringSolve = false,
|
|
57
|
+
placement = 'floating',
|
|
58
|
+
progressShownByHost = false
|
|
43
59
|
}: Props = $props();
|
|
44
60
|
|
|
45
61
|
const locale = getLocaleContext();
|
|
@@ -47,50 +63,10 @@
|
|
|
47
63
|
|
|
48
64
|
const REMARK_LINGER_MS = 6000;
|
|
49
65
|
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
// bar runs linearly to where the step will end, over that time. Steps are weighted by time, so
|
|
55
|
-
// linear gives one steady speed across the solve; any easing curve visibly speeds up and
|
|
56
|
-
// crawls within each step. A slower run waits at the step's end; a faster one snaps ahead.
|
|
57
|
-
let bars = $state.raw<Record<string, { width: number; ms: number }>>({});
|
|
58
|
-
// Any live event re-runs the effect below. Only a source with a new report may re-snap;
|
|
59
|
-
// the rest keep easing where they are.
|
|
60
|
-
let seen = new Map<string, unknown>();
|
|
61
|
-
let targets: Record<string, { width: number; ms: number }> = {};
|
|
62
|
-
$effect(() => {
|
|
63
|
-
const snapped: Record<string, { width: number; ms: number }> = {};
|
|
64
|
-
const eased: Record<string, { width: number; ms: number }> = {};
|
|
65
|
-
const current = untrack(() => bars);
|
|
66
|
-
// eslint-disable-next-line svelte/prefer-svelte-reactivity -- bookkeeping for this effect; reactive reads here would re-trigger it
|
|
67
|
-
const nextSeen = new Map<string, unknown>();
|
|
68
|
-
for (const p of progress) {
|
|
69
|
-
if (p.fraction === undefined) continue;
|
|
70
|
-
const key = p.source ?? '';
|
|
71
|
-
nextSeen.set(key, p);
|
|
72
|
-
if (seen.get(key) === p && current[key]) {
|
|
73
|
-
snapped[key] = current[key];
|
|
74
|
-
// This run's cleanup cancelled the frame that would have started the ease.
|
|
75
|
-
if (targets[key] && current[key] !== targets[key]) eased[key] = targets[key];
|
|
76
|
-
continue;
|
|
77
|
-
}
|
|
78
|
-
snapped[key] = { width: p.fraction, ms: 150 };
|
|
79
|
-
if (p.nextFraction !== undefined && p.stepMs !== undefined) {
|
|
80
|
-
eased[key] = { width: p.nextFraction, ms: p.stepMs };
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
seen = nextSeen;
|
|
84
|
-
targets = eased;
|
|
85
|
-
bars = snapped;
|
|
86
|
-
if (Object.keys(eased).length === 0) return;
|
|
87
|
-
// Two frames: the snapped width must be painted before the eased one is set, or the
|
|
88
|
-
// browser folds both into one style change and there is nothing to transition from.
|
|
89
|
-
let frame = requestAnimationFrame(() => {
|
|
90
|
-
frame = requestAnimationFrame(() => (bars = { ...snapped, ...eased }));
|
|
91
|
-
});
|
|
92
|
-
return () => cancelAnimationFrame(frame);
|
|
93
|
-
});
|
|
66
|
+
const liveProgress = createLiveProgress(() => live);
|
|
67
|
+
const progress = $derived(liveProgress.progress);
|
|
68
|
+
const bars = $derived(liveProgress.bars);
|
|
69
|
+
const headline = $derived(liveProgress.headline);
|
|
94
70
|
// Grasshopper's own complaints stay in the footer log; this panel shows what the author wrote.
|
|
95
71
|
const authored = $derived(diagnostics.filter((d) => d.isGate));
|
|
96
72
|
|
|
@@ -117,16 +93,30 @@
|
|
|
117
93
|
// Keyed on the diagnostics array's identity, which every report renews, rather than on a
|
|
118
94
|
// solve id: only the live channel has one, and on the Compute path remarks arrive with the
|
|
119
95
|
// result. Once per array, so remarks that sat behind a review do not reappear after Continue.
|
|
96
|
+
//
|
|
97
|
+
// A remark is shown once while it stays raised, not after every solve. Every report repeats
|
|
98
|
+
// it: Grasshopper keeps runtime messages on a Message component an input change did not
|
|
99
|
+
// reach, and Compute re-solves the whole definition. It shows again once a solve stops
|
|
100
|
+
// raising it and a later one raises it anew.
|
|
120
101
|
let lingering = $state(false);
|
|
121
102
|
let lingeredFor: SolveDiagnostic[] | null = null;
|
|
103
|
+
let shownRemarks: ReadonlySet<string> = new Set();
|
|
104
|
+
let freshRemarks = $state.raw<SolveDiagnostic[]>([]);
|
|
105
|
+
const remarkKey = (d: SolveDiagnostic) => `${d.source ?? ''}\u0000${d.message}`;
|
|
122
106
|
$effect(() => {
|
|
123
107
|
if (phase === 'live') {
|
|
124
108
|
lingering = false;
|
|
125
109
|
return;
|
|
126
110
|
}
|
|
127
|
-
if (
|
|
111
|
+
if (lingeredFor === diagnostics) return;
|
|
128
112
|
lingeredFor = diagnostics;
|
|
129
|
-
|
|
113
|
+
const raised = authoredRemarks.map(remarkKey);
|
|
114
|
+
const stillShown = raised.filter((k) => shownRemarks.has(k));
|
|
115
|
+
const fresh = authoredRemarks.filter((d) => !shownRemarks.has(remarkKey(d)));
|
|
116
|
+
const showNow = phase === 'idle' && fresh.length > 0;
|
|
117
|
+
shownRemarks = new Set(showNow ? [...stillShown, ...fresh.map(remarkKey)] : stillShown);
|
|
118
|
+
if (!showNow) return;
|
|
119
|
+
freshRemarks = fresh;
|
|
130
120
|
lingering = true;
|
|
131
121
|
const timer = setTimeout(() => (lingering = false), REMARK_LINGER_MS);
|
|
132
122
|
return () => clearTimeout(timer);
|
|
@@ -145,6 +135,7 @@
|
|
|
145
135
|
$effect(() => {
|
|
146
136
|
if (phase === 'live') {
|
|
147
137
|
finishing = false;
|
|
138
|
+
if (freezesDuringSolve) return;
|
|
148
139
|
const timer = setTimeout(() => {
|
|
149
140
|
revealed = true;
|
|
150
141
|
revealedAt = performance.now();
|
|
@@ -171,7 +162,7 @@
|
|
|
171
162
|
// While solving, the live channel is all there is. Once the result lands it is authoritative
|
|
172
163
|
// — it carries remarks too — so the live list is dropped entirely and nothing is shown twice.
|
|
173
164
|
const rows = $derived<SolveDiagnostic[]>(
|
|
174
|
-
view === 'live' ? [...live.diagnostics] : view === 'idle' ?
|
|
165
|
+
view === 'live' ? [...live.diagnostics] : view === 'idle' ? freshRemarks : authoredGating
|
|
175
166
|
);
|
|
176
167
|
|
|
177
168
|
// A remark states something without asking anything, so it reads as a quiet note.
|
|
@@ -183,37 +174,11 @@
|
|
|
183
174
|
}))
|
|
184
175
|
);
|
|
185
176
|
|
|
186
|
-
// Steps a few milliseconds long would swap the headline faster than it can be read. Each one
|
|
187
|
-
// stays up for at least this long; steps that end sooner are skipped in the label but still
|
|
188
|
-
// count in the bar. The label and its step count move together so they never disagree.
|
|
189
|
-
const HEADLINE_MIN_MS = 200;
|
|
190
|
-
let headline = $state.raw<(typeof progress)[number] | undefined>(undefined);
|
|
191
|
-
let headlineAt = 0;
|
|
192
|
-
$effect(() => {
|
|
193
|
-
const next = progress[0];
|
|
194
|
-
const shown = untrack(() => headline);
|
|
195
|
-
if (next?.label === shown?.label && next?.done === shown?.done) {
|
|
196
|
-
headline = next;
|
|
197
|
-
return;
|
|
198
|
-
}
|
|
199
|
-
const show = () => {
|
|
200
|
-
headline = next;
|
|
201
|
-
headlineAt = performance.now();
|
|
202
|
-
};
|
|
203
|
-
const wait = HEADLINE_MIN_MS - (performance.now() - headlineAt);
|
|
204
|
-
if (!shown || wait <= 0) {
|
|
205
|
-
show();
|
|
206
|
-
return;
|
|
207
|
-
}
|
|
208
|
-
const timer = setTimeout(show, wait);
|
|
209
|
-
return () => clearTimeout(timer);
|
|
210
|
-
});
|
|
211
|
-
|
|
212
177
|
const visible = $derived(
|
|
213
178
|
view === 'review' || view === 'blocked'
|
|
214
179
|
? true
|
|
215
180
|
: view === 'live'
|
|
216
|
-
? revealed && (rows.length > 0 || progress.length > 0)
|
|
181
|
+
? revealed && (rows.length > 0 || (!progressShownByHost && progress.length > 0))
|
|
217
182
|
: rows.length > 0 && lingering
|
|
218
183
|
);
|
|
219
184
|
|
|
@@ -235,10 +200,14 @@
|
|
|
235
200
|
}
|
|
236
201
|
|
|
237
202
|
// Escape resolves to the safe side — discard, keeping what is on screen — never to silently
|
|
238
|
-
// applying a result the user has not accepted.
|
|
203
|
+
// applying a result the user has not accepted. A frozen host gets no keydown until the solve
|
|
204
|
+
// ends; there the plugin aborts on the key state, which only counts while Rhino is in front, so
|
|
205
|
+
// a browser tab (local or Compute) has to abort from the page.
|
|
239
206
|
function handleKeydown(e: KeyboardEvent) {
|
|
240
207
|
if (e.key !== 'Escape') return;
|
|
241
|
-
if (phase === '
|
|
208
|
+
if (phase === 'live') {
|
|
209
|
+
if (!freezesDuringSolve) onabort();
|
|
210
|
+
} else if (phase === 'review') ondiscard();
|
|
242
211
|
else if (phase === 'blocked') dismiss();
|
|
243
212
|
}
|
|
244
213
|
</script>
|
|
@@ -247,17 +216,29 @@
|
|
|
247
216
|
|
|
248
217
|
<div class="sr-only" role="status" aria-live="polite">{announcement}</div>
|
|
249
218
|
|
|
250
|
-
{#if
|
|
219
|
+
{#if freezesDuringSolve && view === 'live'}
|
|
220
|
+
<!-- Painted before the solve takes the thread; Abort could not be clicked until it ends. Inline,
|
|
221
|
+
the solving chip carries the hint instead: a line here would resize the footer mid-solve. -->
|
|
222
|
+
{#if placement === 'floating'}
|
|
223
|
+
<p
|
|
224
|
+
class="bottom-4 text-xs fixed left-1/2 z-50 -translate-x-1/2 text-muted-foreground"
|
|
225
|
+
data-testid="solve-esc-hint"
|
|
226
|
+
>
|
|
227
|
+
{t.solveMessagesEscHint}
|
|
228
|
+
</p>
|
|
229
|
+
{/if}
|
|
230
|
+
{:else if visible}
|
|
231
|
+
<!-- Inline, it is a row of the host's footer like the Calculate row under it, not a card: a
|
|
232
|
+
framed box inside an edge-to-edge column reads as a dialog glued into the page. -->
|
|
251
233
|
<div
|
|
252
|
-
class=
|
|
253
|
-
|
|
254
|
-
? 'border-destructive/50'
|
|
255
|
-
: ''}"
|
|
234
|
+
class={placement === 'inline'
|
|
235
|
+
? `px-2 py-2 border-t ${view === 'blocked' ? 'border-destructive/40' : 'border-border'}`
|
|
236
|
+
: `p-3 bottom-4 shadow-lg w-lg fixed left-1/2 z-50 max-w-screen-inset -translate-x-1/2 rounded-lg border bg-background ${view === 'blocked' ? 'border-destructive/50' : ''}`}
|
|
256
237
|
role={view === 'review' || view === 'blocked' ? 'alert' : undefined}
|
|
257
238
|
data-testid="solve-messages"
|
|
258
239
|
data-view={view}
|
|
259
240
|
>
|
|
260
|
-
{#if view === 'live'}
|
|
241
|
+
{#if view === 'live' && !progressShownByHost}
|
|
261
242
|
{@const head = headline ?? progress[0]}
|
|
262
243
|
<div>
|
|
263
244
|
<div>
|
|
@@ -275,8 +256,13 @@
|
|
|
275
256
|
class="-my-1 shrink-0"
|
|
276
257
|
disabled={finishing}
|
|
277
258
|
onclick={onabort}
|
|
259
|
+
aria-keyshortcuts="Escape"
|
|
260
|
+
title={t.solveMessagesEscHint}
|
|
278
261
|
>
|
|
279
262
|
{t.solveMessagesAbort}
|
|
263
|
+
<kbd class="px-1 rounded-sm border border-border font-sans text-2xs opacity-70">
|
|
264
|
+
Esc
|
|
265
|
+
</kbd>
|
|
280
266
|
</Button>
|
|
281
267
|
</div>
|
|
282
268
|
{#each progress as p, i (p.source ?? '')}
|
|
@@ -315,6 +301,30 @@
|
|
|
315
301
|
{/each}
|
|
316
302
|
</div>
|
|
317
303
|
</div>
|
|
304
|
+
{:else if (view === 'review' || view === 'blocked') && placement === 'inline'}
|
|
305
|
+
<!-- Each message carries its own icon, so the label goes without one; the buttons share
|
|
306
|
+
its row rather than adding one under a single line of text. -->
|
|
307
|
+
<div class="mb-1.5 gap-2 flex items-center">
|
|
308
|
+
<span
|
|
309
|
+
class="min-w-0 text-xs font-medium flex-1 truncate {view === 'blocked'
|
|
310
|
+
? 'text-destructive'
|
|
311
|
+
: 'text-muted-foreground'}"
|
|
312
|
+
>
|
|
313
|
+
{view === 'blocked' ? t.solveBlockedTitle : t.solveMessagesTitle}
|
|
314
|
+
</span>
|
|
315
|
+
{#if view === 'blocked'}
|
|
316
|
+
<Button variant="ghost" size="xs" class="-my-1 shrink-0" onclick={dismiss}>
|
|
317
|
+
{t.solveMessagesDismiss}
|
|
318
|
+
</Button>
|
|
319
|
+
{:else}
|
|
320
|
+
<Button variant="ghost" size="xs" class="-my-1 shrink-0" onclick={ondiscard}>
|
|
321
|
+
{t.solveMessagesDiscard}
|
|
322
|
+
</Button>
|
|
323
|
+
<Button size="xs" class="-my-1 shrink-0" onclick={onconfirm}>
|
|
324
|
+
{t.solveMessagesConfirm}
|
|
325
|
+
</Button>
|
|
326
|
+
{/if}
|
|
327
|
+
</div>
|
|
318
328
|
{:else if view === 'review' || view === 'blocked'}
|
|
319
329
|
<div class="mb-2">
|
|
320
330
|
<div class="gap-2 text-sm font-medium flex items-center">
|
|
@@ -333,12 +343,16 @@
|
|
|
333
343
|
{/if}
|
|
334
344
|
|
|
335
345
|
{#if rows.length > 0}
|
|
336
|
-
<div
|
|
346
|
+
<div
|
|
347
|
+
class="max-h-40 overflow-y-auto {view === 'live' && !progressShownByHost
|
|
348
|
+
? 'mt-3 pt-3 border-t'
|
|
349
|
+
: ''}"
|
|
350
|
+
>
|
|
337
351
|
<IssueList {issues} variant="plain" />
|
|
338
352
|
</div>
|
|
339
353
|
{/if}
|
|
340
354
|
|
|
341
|
-
{#if view === 'review' || view === 'blocked'}
|
|
355
|
+
{#if (view === 'review' || view === 'blocked') && placement === 'floating'}
|
|
342
356
|
<div class="mt-3 gap-2 flex justify-end">
|
|
343
357
|
{#if view === 'blocked'}
|
|
344
358
|
<Button variant="outline" size="sm" onclick={dismiss}>{t.solveMessagesDismiss}</Button>
|
|
@@ -94,14 +94,14 @@
|
|
|
94
94
|
const sidenavWrapClass = $derived(
|
|
95
95
|
_mode === 'fixed'
|
|
96
96
|
? 'flex shrink-0'
|
|
97
|
-
: 'flex shrink-0 sm:self-start sm:sticky sm:top-(--header-h) sm:max-h-
|
|
97
|
+
: 'flex shrink-0 sm:self-start sm:sticky sm:top-(--header-h) sm:max-h-(--below-header-h)'
|
|
98
98
|
);
|
|
99
99
|
|
|
100
100
|
// The sticky wrapper is only as tall as its content, so in scroll mode the divider comes
|
|
101
101
|
// from the main column's left edge — that one spans the full body height.
|
|
102
102
|
const mainClass = $derived(
|
|
103
103
|
_mode === 'fixed'
|
|
104
|
-
? 'min-h-0 flex-1 overflow-y-auto'
|
|
104
|
+
? 'min-h-0 min-w-0 flex-1 overflow-y-auto'
|
|
105
105
|
: 'min-w-0 flex-1 overflow-y-auto border-border sm:border-l'
|
|
106
106
|
);
|
|
107
107
|
</script>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import type { FooterItem } from '
|
|
2
|
+
import type { FooterItem } from '#lib/contexts/footerContext.svelte.js';
|
|
3
3
|
|
|
4
4
|
let { item }: { item: FooterItem } = $props();
|
|
5
5
|
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
{#if item.onClick}
|
|
10
10
|
<button
|
|
11
11
|
onclick={item.onClick}
|
|
12
|
-
class="gap-1.5 px-2 py-0.5
|
|
12
|
+
class="gap-1.5 px-2 py-0.5 flex cursor-pointer items-center rounded-sm transition-colors hover:bg-hover"
|
|
13
13
|
>
|
|
14
14
|
<item.component {...itemProps} />
|
|
15
15
|
</button>
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
let { class: className = '', children }: PageContentProps = $props();
|
|
8
8
|
</script>
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
<!-- One content width for every page, so moving between pages doesn't change the frame. -->
|
|
11
|
+
<div class={`max-w-6xl min-w-0 mx-auto w-full px-(--page-px) py-(--page-py) ${className}`}>
|
|
11
12
|
{@render children?.()}
|
|
12
|
-
</
|
|
13
|
+
</div>
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
import type { Snippet } from 'svelte';
|
|
3
3
|
import { CircleAlert, TriangleAlert, Info } from '@lucide/svelte';
|
|
4
4
|
import type { SolveDiagnostic } from '@selvajs/solve/shared';
|
|
5
|
-
import { useFooter } from '
|
|
5
|
+
import { useFooter } from '#lib/contexts/footerContext.svelte.js';
|
|
6
6
|
import ComputeMessagesDialog from '../compute/ComputeMessagesDialog.svelte';
|
|
7
7
|
import FooterItemRenderer from './FooterItemRenderer.svelte';
|
|
8
|
-
import { getLocaleContext } from '
|
|
9
|
-
import { formatCount, formatMessage } from '
|
|
8
|
+
import { getLocaleContext } from '#lib/i18n/localeContext.svelte.js';
|
|
9
|
+
import { formatCount, formatMessage } from '#lib/i18n/messages.js';
|
|
10
10
|
|
|
11
11
|
interface Props {
|
|
12
12
|
errors?: string[];
|
|
@@ -88,12 +88,12 @@
|
|
|
88
88
|
<ComputeMessagesDialog {errors} {warnings} {diagnostics}>
|
|
89
89
|
{#snippet trigger()}
|
|
90
90
|
<div
|
|
91
|
-
class="gap-1.5 px-2 py-1
|
|
91
|
+
class="gap-1.5 px-2 py-1 flex cursor-pointer items-center rounded-sm transition-colors hover:bg-hover {errorCount >
|
|
92
92
|
0
|
|
93
93
|
? 'text-destructive hover:bg-destructive/10'
|
|
94
94
|
: warningCount > 0
|
|
95
95
|
? 'text-warning hover:bg-warning/10'
|
|
96
|
-
: 'hover:bg-
|
|
96
|
+
: 'hover:bg-hover'}"
|
|
97
97
|
title={formatCount(totalCount, t.lastSolveMessagesOne, t.lastSolveMessagesOther)}
|
|
98
98
|
>
|
|
99
99
|
{#if errorCount > 0}
|
|
@@ -136,6 +136,8 @@
|
|
|
136
136
|
<FooterItemRenderer {item} />
|
|
137
137
|
{/each}
|
|
138
138
|
|
|
139
|
-
|
|
139
|
+
{#if copyrightLine}
|
|
140
|
+
<p class="truncate">{copyrightLine}</p>
|
|
141
|
+
{/if}
|
|
140
142
|
</div>
|
|
141
143
|
</footer>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { Snippet } from 'svelte';
|
|
3
|
-
import { ModeToggle } from '
|
|
3
|
+
import { ModeToggle } from '#lib/components/primitives/mode-toggle/index.js';
|
|
4
4
|
|
|
5
5
|
interface PageHeaderProps {
|
|
6
6
|
homeUrl?: string;
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
<div class="gap-2 sm:gap-5 flex h-(--header-h) items-center px-(--page-px)">
|
|
35
35
|
<!-- Logo -->
|
|
36
36
|
<a href={homeUrl} class="gap-2 flex shrink-0 items-center" aria-label={brandName}>
|
|
37
|
-
<img src={logo} alt="" aria-hidden="true" class="h-
|
|
37
|
+
<img src={logo} alt="" aria-hidden="true" class="h-7 w-7" />
|
|
38
38
|
<!-- On a phone the page title needs the room more than the brand does. -->
|
|
39
39
|
<span
|
|
40
40
|
class="font-semibold text-sm tracking-tight {title !== undefined ? 'sm:inline hidden' : ''}"
|
|
@@ -66,7 +66,7 @@
|
|
|
66
66
|
</div>
|
|
67
67
|
|
|
68
68
|
{#if subnav}
|
|
69
|
-
<div class="h-10 flex items-center border-t border-border
|
|
69
|
+
<div class="h-10 flex items-center border-t border-border px-(--page-px)">
|
|
70
70
|
{@render subnav()}
|
|
71
71
|
</div>
|
|
72
72
|
{/if}
|
|
@@ -13,6 +13,9 @@
|
|
|
13
13
|
<script lang="ts">
|
|
14
14
|
import type { Snippet } from 'svelte';
|
|
15
15
|
import { page } from '$app/state';
|
|
16
|
+
import ChevronsUpDown from '@lucide/svelte/icons/chevrons-up-down';
|
|
17
|
+
import Check from '@lucide/svelte/icons/check';
|
|
18
|
+
import * as DropdownMenu from '#lib/components/primitives/dropdown-menu/index.js';
|
|
16
19
|
|
|
17
20
|
interface SideNavProps {
|
|
18
21
|
items: SideNavItem[];
|
|
@@ -41,10 +44,12 @@
|
|
|
41
44
|
if (item.match === 'prefix') return path.startsWith(item.href);
|
|
42
45
|
return path === item.href;
|
|
43
46
|
}
|
|
47
|
+
|
|
48
|
+
const activeItem = $derived(items.find(isActive));
|
|
44
49
|
</script>
|
|
45
50
|
|
|
46
|
-
<!-- On a phone a 240px column would leave the page ~150px, so the nav
|
|
47
|
-
|
|
51
|
+
<!-- On a phone a 240px column would leave the page ~150px, so the nav collapses to one switcher
|
|
52
|
+
naming the current section; the header and footer drop out. -->
|
|
48
53
|
<aside
|
|
49
54
|
class={`sm:h-full sm:w-60 sm:overflow-y-auto sm:border-b-0 flex w-full shrink-0 flex-col border-b border-border bg-background ${
|
|
50
55
|
border ? 'sm:border-r' : ''
|
|
@@ -64,31 +69,67 @@
|
|
|
64
69
|
</div>
|
|
65
70
|
{/if}
|
|
66
71
|
|
|
67
|
-
<
|
|
68
|
-
|
|
69
|
-
|
|
72
|
+
<div class="py-2 sm:hidden px-(--page-px)">
|
|
73
|
+
<DropdownMenu.Root>
|
|
74
|
+
<DropdownMenu.Trigger>
|
|
75
|
+
{#snippet child({ props })}
|
|
76
|
+
<button
|
|
77
|
+
{...props}
|
|
78
|
+
class="min-h-11 gap-3 px-3 text-sm font-medium flex w-full items-center rounded-md border border-border bg-card text-left"
|
|
79
|
+
>
|
|
80
|
+
{#if activeItem?.icon}
|
|
81
|
+
{@const Icon = activeItem.icon}
|
|
82
|
+
<Icon class="size-4 shrink-0 opacity-70" />
|
|
83
|
+
{/if}
|
|
84
|
+
<span class="min-w-0 flex-1 truncate">
|
|
85
|
+
{#if eyebrow}<span class="text-muted-foreground">{eyebrow} /</span>{/if}
|
|
86
|
+
{activeItem?.label ?? ''}
|
|
87
|
+
</span>
|
|
88
|
+
<ChevronsUpDown class="size-4 shrink-0 opacity-60" />
|
|
89
|
+
</button>
|
|
90
|
+
{/snippet}
|
|
91
|
+
</DropdownMenu.Trigger>
|
|
92
|
+
<DropdownMenu.Content sideOffset={4}>
|
|
93
|
+
{#each items as item (item.href)}
|
|
94
|
+
{@const active = isActive(item)}
|
|
95
|
+
{@const Icon = item.icon}
|
|
96
|
+
<DropdownMenu.Item class="min-h-11">
|
|
97
|
+
{#snippet child({ props })}
|
|
98
|
+
<a href={item.href} aria-current={active ? 'page' : undefined} {...props}>
|
|
99
|
+
{#if Icon}<Icon class="size-4 opacity-70" />{/if}
|
|
100
|
+
<span class="flex-1">{item.label}</span>
|
|
101
|
+
{#if item.badge !== undefined}
|
|
102
|
+
<span class="font-mono text-2xs tabular-nums opacity-60">{item.badge}</span>
|
|
103
|
+
{/if}
|
|
104
|
+
{#if active}<Check class="size-4" aria-hidden="true" />{/if}
|
|
105
|
+
</a>
|
|
106
|
+
{/snippet}
|
|
107
|
+
</DropdownMenu.Item>
|
|
108
|
+
{/each}
|
|
109
|
+
</DropdownMenu.Content>
|
|
110
|
+
</DropdownMenu.Root>
|
|
111
|
+
</div>
|
|
112
|
+
|
|
113
|
+
<nav class="pb-4 pr-2 sm:block hidden flex-1 space-y-px">
|
|
70
114
|
{#each items as item (item.href)}
|
|
71
115
|
{@const active = isActive(item)}
|
|
72
116
|
{@const Icon = item.icon}
|
|
73
117
|
<a
|
|
74
118
|
href={item.href}
|
|
75
|
-
|
|
119
|
+
aria-current={active ? 'page' : undefined}
|
|
120
|
+
class={`group gap-2 py-1.5 pr-2.5 relative flex w-full items-center text-left transition-colors ${
|
|
76
121
|
active
|
|
77
|
-
? 'pl-
|
|
78
|
-
: '
|
|
122
|
+
? 'pl-4 rounded-r-md bg-selected text-foreground'
|
|
123
|
+
: 'mx-2 pl-2.5 rounded-md text-muted-foreground hover:bg-hover hover:text-foreground'
|
|
79
124
|
}`}
|
|
80
125
|
>
|
|
81
126
|
{#if active}
|
|
82
|
-
<span
|
|
83
|
-
class="left-0 top-0 bottom-0 w-0.75 sm:block absolute hidden bg-primary"
|
|
84
|
-
aria-hidden="true"
|
|
85
|
-
></span>
|
|
127
|
+
<span class="left-0 top-0 bottom-0 w-0.75 absolute bg-primary" aria-hidden="true"></span>
|
|
86
128
|
{/if}
|
|
87
129
|
{#if Icon}
|
|
88
130
|
<Icon class="h-3.5 w-3.5 shrink-0 opacity-70" />
|
|
89
131
|
{/if}
|
|
90
|
-
<span class="text-sm font-medium
|
|
91
|
-
>
|
|
132
|
+
<span class="text-sm font-medium flex-1 truncate">{item.label}</span>
|
|
92
133
|
{#if item.badge !== undefined}
|
|
93
134
|
<span class="font-mono shrink-0 text-2xs tabular-nums opacity-60">{item.badge}</span>
|
|
94
135
|
{/if}
|
|
@@ -97,7 +138,7 @@
|
|
|
97
138
|
</nav>
|
|
98
139
|
|
|
99
140
|
{#if footer}
|
|
100
|
-
<div class="px-3 py-3 sm:block hidden border-t border-border
|
|
141
|
+
<div class="px-3 py-3 sm:block hidden border-t border-border">
|
|
101
142
|
{@render footer()}
|
|
102
143
|
</div>
|
|
103
144
|
{/if}
|
|
@@ -31,8 +31,8 @@
|
|
|
31
31
|
class={[
|
|
32
32
|
'h-7 px-3 gap-1.5 text-sm font-medium flex items-center rounded-md transition-colors',
|
|
33
33
|
active
|
|
34
|
-
? 'bg-
|
|
35
|
-
: 'text-muted-foreground hover:bg-
|
|
34
|
+
? 'bg-selected text-foreground'
|
|
35
|
+
: 'text-muted-foreground hover:bg-hover hover:text-foreground'
|
|
36
36
|
].join(' ')}
|
|
37
37
|
>
|
|
38
38
|
{#if item.icon}
|