@selvajs/ui 6.5.1-beta.1 → 6.6.0-beta.11
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/dist/components/ConfirmDialog.svelte +2 -10
- package/dist/components/ErrorScreen.svelte +21 -27
- package/dist/components/compute/AppLayout.svelte +286 -116
- package/dist/components/compute/AppLayout.svelte.d.ts +22 -0
- package/dist/components/compute/ComputeApp.svelte +45 -24
- package/dist/components/compute/ComputeApp.svelte.d.ts +19 -2
- package/dist/components/compute/ComputeMessagesDialog.svelte +47 -83
- package/dist/components/compute/ParameterPresetManager.svelte +37 -130
- package/dist/components/compute/ParameterPresetManager.svelte.d.ts +4 -5
- package/dist/components/compute/SolveMessages.svelte +131 -77
- package/dist/components/compute/SolveMessages.svelte.d.ts +7 -12
- package/dist/components/layout/AppShell.svelte +10 -6
- package/dist/components/layout/PageFooter.svelte +23 -11
- package/dist/components/layout/PageHeader.svelte +11 -7
- package/dist/components/layout/Pagination.svelte +2 -4
- package/dist/components/layout/SectionHeader.svelte +4 -2
- package/dist/components/layout/SideNav.svelte +56 -7
- package/dist/components/preview/ChartOutput.svelte +35 -25
- package/dist/components/preview/Group.svelte +92 -103
- package/dist/components/preview/Group.svelte.d.ts +1 -1
- package/dist/components/preview/HelpButton.svelte +36 -0
- package/dist/components/preview/HelpButton.svelte.d.ts +8 -0
- package/dist/components/preview/ImageOutput.svelte +430 -71
- package/dist/components/preview/InputControl.svelte +163 -90
- package/dist/components/preview/InputControl.svelte.d.ts +5 -1
- package/dist/components/preview/OutputDisplay.svelte +28 -33
- package/dist/components/preview/TabBar.svelte +106 -22
- package/dist/components/preview/TabBar.svelte.d.ts +1 -0
- package/dist/components/preview/TabContent.svelte +63 -57
- package/dist/components/preview/TabContent.svelte.d.ts +5 -1
- package/dist/components/preview/TabLayout.svelte +27 -5
- package/dist/components/preview/TabLayout.svelte.d.ts +5 -0
- package/dist/components/preview/inputs/CheckboxInput.svelte +7 -7
- package/dist/components/preview/inputs/CheckboxInput.svelte.d.ts +3 -0
- package/dist/components/preview/inputs/ChecklistInput.svelte +7 -2
- package/dist/components/preview/inputs/ChecklistInput.svelte.d.ts +2 -1
- package/dist/components/preview/inputs/ColorInput.svelte +4 -2
- package/dist/components/preview/inputs/ColorInput.svelte.d.ts +1 -0
- package/dist/components/preview/inputs/DropdownInput.svelte +19 -4
- package/dist/components/preview/inputs/DropdownInput.svelte.d.ts +2 -1
- package/dist/components/preview/inputs/FileInput.svelte +112 -108
- 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 +123 -61
- package/dist/components/preview/inputs/NumberInput.svelte.d.ts +2 -0
- 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 +44 -0
- package/dist/components/preview/inputs/SegmentedInput.svelte.d.ts +12 -0
- package/dist/components/preview/inputs/TextInput.svelte +8 -4
- package/dist/components/preview/inputs/TileInput.svelte +80 -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 +56 -24
- package/dist/components/primitives/CalculateButton.svelte.d.ts +3 -0
- package/dist/components/primitives/Callout.svelte +11 -18
- package/dist/components/primitives/DataTable.svelte +38 -5
- package/dist/components/primitives/DataTable.svelte.d.ts +2 -0
- package/dist/components/primitives/FilterableDropdown.svelte +42 -129
- package/dist/components/primitives/FilterableDropdown.svelte.d.ts +1 -1
- package/dist/components/primitives/IssueList.svelte +56 -0
- package/dist/components/primitives/IssueList.svelte.d.ts +20 -0
- package/dist/components/primitives/SeverityIcon.svelte +15 -0
- package/dist/components/primitives/SeverityIcon.svelte.d.ts +8 -0
- package/dist/components/primitives/SolvingIndicator.svelte +43 -42
- package/dist/components/primitives/SolvingIndicator.svelte.d.ts +6 -0
- package/dist/components/primitives/StateDisplay.svelte +19 -79
- package/dist/components/primitives/ViewToggle.svelte +18 -33
- package/dist/components/primitives/alert-dialog/alert-dialog-action.svelte +9 -3
- package/dist/components/primitives/alert-dialog/alert-dialog-action.svelte.d.ts +6 -1
- package/dist/components/primitives/alert-dialog/alert-dialog-content.svelte +1 -1
- package/dist/components/primitives/alert-dialog/alert-dialog-overlay.svelte +1 -1
- package/dist/components/primitives/badge/badge.svelte +2 -2
- package/dist/components/primitives/badge/badge.svelte.d.ts +4 -4
- package/dist/components/primitives/button/button.svelte +6 -2
- package/dist/components/primitives/button/button.svelte.d.ts +10 -4
- package/dist/components/primitives/card/card-header.svelte +1 -1
- package/dist/components/primitives/card/card.svelte +21 -5
- package/dist/components/primitives/card/card.svelte.d.ts +25 -1
- package/dist/components/primitives/card/index.d.ts +1 -2
- package/dist/components/primitives/card/index.js +2 -3
- package/dist/components/primitives/checkbox/checkbox.svelte +1 -1
- package/dist/components/primitives/command/command-dialog.svelte +42 -0
- package/dist/components/primitives/command/command-dialog.svelte.d.ts +14 -0
- package/dist/components/primitives/command/command-empty.svelte +17 -0
- package/dist/components/primitives/command/command-empty.svelte.d.ts +4 -0
- package/dist/components/primitives/command/command-group.svelte +33 -0
- package/dist/components/primitives/command/command-group.svelte.d.ts +7 -0
- package/dist/components/primitives/command/command-input.svelte +36 -0
- package/dist/components/primitives/command/command-input.svelte.d.ts +4 -0
- package/dist/components/primitives/command/command-item.svelte +28 -0
- package/dist/components/primitives/command/command-item.svelte.d.ts +4 -0
- package/dist/components/primitives/command/command-link-item.svelte +21 -0
- package/dist/components/primitives/command/command-link-item.svelte.d.ts +4 -0
- package/dist/components/primitives/command/command-list.svelte +20 -0
- package/dist/components/primitives/command/command-list.svelte.d.ts +4 -0
- package/dist/components/primitives/command/command-loading.svelte +7 -0
- package/dist/components/primitives/command/command-loading.svelte.d.ts +4 -0
- package/dist/components/primitives/command/command-separator.svelte +17 -0
- package/dist/components/primitives/command/command-separator.svelte.d.ts +4 -0
- package/dist/components/primitives/command/command-shortcut.svelte +23 -0
- package/dist/components/primitives/command/command-shortcut.svelte.d.ts +5 -0
- package/dist/components/primitives/command/command.svelte +28 -0
- package/dist/components/primitives/command/command.svelte.d.ts +8 -0
- package/dist/components/primitives/command/index.d.ts +12 -0
- package/dist/components/primitives/command/index.js +14 -0
- package/dist/components/primitives/context-menu/context-menu-content.svelte +1 -1
- package/dist/components/primitives/context-menu/context-menu-sub-content.svelte +1 -1
- package/dist/components/primitives/dialog/dialog-content.svelte +11 -3
- package/dist/components/primitives/dialog/dialog-content.svelte.d.ts +2 -0
- package/dist/components/primitives/dialog/dialog-overlay.svelte +1 -1
- package/dist/components/primitives/dialog/dialog-title.svelte +6 -2
- package/dist/components/primitives/dialog/dialog-title.svelte.d.ts +5 -1
- package/dist/components/primitives/drawer/Drawer.svelte +2 -2
- package/dist/components/primitives/dropdown-menu/dropdown-menu-checkbox-group.svelte +16 -0
- package/dist/components/primitives/dropdown-menu/dropdown-menu-checkbox-group.svelte.d.ts +4 -0
- package/dist/components/primitives/dropdown-menu/dropdown-menu-checkbox-item.svelte +46 -0
- package/dist/components/primitives/dropdown-menu/dropdown-menu-checkbox-item.svelte.d.ts +9 -0
- package/dist/components/primitives/dropdown-menu/dropdown-menu-content.svelte +31 -0
- package/dist/components/primitives/dropdown-menu/dropdown-menu-content.svelte.d.ts +10 -0
- package/dist/components/primitives/dropdown-menu/dropdown-menu-group-heading.svelte +22 -0
- package/dist/components/primitives/dropdown-menu/dropdown-menu-group-heading.svelte.d.ts +8 -0
- package/dist/components/primitives/dropdown-menu/dropdown-menu-group.svelte +7 -0
- package/dist/components/primitives/dropdown-menu/dropdown-menu-group.svelte.d.ts +4 -0
- package/dist/components/primitives/dropdown-menu/dropdown-menu-item.svelte +27 -0
- package/dist/components/primitives/dropdown-menu/dropdown-menu-item.svelte.d.ts +8 -0
- package/dist/components/primitives/dropdown-menu/dropdown-menu-label.svelte +24 -0
- package/dist/components/primitives/dropdown-menu/dropdown-menu-label.svelte.d.ts +8 -0
- package/dist/components/primitives/dropdown-menu/dropdown-menu-portal.svelte +7 -0
- package/dist/components/primitives/dropdown-menu/dropdown-menu-portal.svelte.d.ts +3 -0
- package/dist/components/primitives/dropdown-menu/dropdown-menu-radio-group.svelte +16 -0
- package/dist/components/primitives/dropdown-menu/dropdown-menu-radio-group.svelte.d.ts +4 -0
- package/dist/components/primitives/dropdown-menu/dropdown-menu-radio-item.svelte +36 -0
- package/dist/components/primitives/dropdown-menu/dropdown-menu-radio-item.svelte.d.ts +4 -0
- package/dist/components/primitives/dropdown-menu/dropdown-menu-separator.svelte +17 -0
- package/dist/components/primitives/dropdown-menu/dropdown-menu-separator.svelte.d.ts +4 -0
- package/dist/components/primitives/dropdown-menu/dropdown-menu-shortcut.svelte +23 -0
- package/dist/components/primitives/dropdown-menu/dropdown-menu-shortcut.svelte.d.ts +5 -0
- package/dist/components/primitives/dropdown-menu/dropdown-menu-sub-content.svelte +31 -0
- package/dist/components/primitives/dropdown-menu/dropdown-menu-sub-content.svelte.d.ts +10 -0
- package/dist/components/primitives/dropdown-menu/dropdown-menu-sub-trigger.svelte +29 -0
- package/dist/components/primitives/dropdown-menu/dropdown-menu-sub-trigger.svelte.d.ts +7 -0
- package/dist/components/primitives/dropdown-menu/dropdown-menu-sub.svelte +7 -0
- package/dist/components/primitives/dropdown-menu/dropdown-menu-sub.svelte.d.ts +3 -0
- package/dist/components/primitives/dropdown-menu/dropdown-menu-trigger.svelte +7 -0
- package/dist/components/primitives/dropdown-menu/dropdown-menu-trigger.svelte.d.ts +4 -0
- package/dist/components/primitives/dropdown-menu/dropdown-menu.svelte +7 -0
- package/dist/components/primitives/dropdown-menu/dropdown-menu.svelte.d.ts +3 -0
- package/dist/components/primitives/dropdown-menu/index.d.ts +18 -0
- package/dist/components/primitives/dropdown-menu/index.js +18 -0
- package/dist/components/primitives/{alert/alert-description.svelte → empty/empty-content.svelte} +3 -3
- package/dist/components/primitives/empty/empty-content.svelte.d.ts +5 -0
- package/dist/components/primitives/empty/empty-description.svelte +23 -0
- package/dist/components/primitives/{alert/alert-description.svelte.d.ts → empty/empty-description.svelte.d.ts} +4 -4
- package/dist/components/primitives/{alert/alert-title.svelte → empty/empty-header.svelte} +3 -3
- package/dist/components/primitives/empty/empty-header.svelte.d.ts +5 -0
- package/dist/components/primitives/empty/empty-media.svelte +41 -0
- package/dist/components/primitives/empty/empty-media.svelte.d.ts +26 -0
- package/dist/components/primitives/{card/card-action.svelte → empty/empty-title.svelte} +2 -2
- package/dist/components/primitives/{card/card-action.svelte.d.ts → empty/empty-title.svelte.d.ts} +3 -3
- package/dist/components/primitives/empty/empty.svelte +23 -0
- package/dist/components/primitives/empty/empty.svelte.d.ts +5 -0
- package/dist/components/primitives/empty/index.d.ts +7 -0
- package/dist/components/primitives/empty/index.js +9 -0
- package/dist/components/primitives/index.d.ts +10 -1
- package/dist/components/primitives/index.js +10 -1
- package/dist/components/primitives/input/input.svelte +4 -4
- package/dist/components/primitives/input-group/index.d.ts +7 -0
- package/dist/components/primitives/input-group/index.js +9 -0
- package/dist/components/primitives/input-group/input-group-addon.svelte +53 -0
- package/dist/components/primitives/input-group/input-group-addon.svelte.d.ts +32 -0
- package/dist/components/primitives/input-group/input-group-button.svelte +49 -0
- package/dist/components/primitives/input-group/input-group-button.svelte.d.ts +32 -0
- package/dist/components/primitives/input-group/input-group-input.svelte +25 -0
- package/dist/components/primitives/input-group/input-group-input.svelte.d.ts +11 -0
- package/dist/components/primitives/input-group/input-group-text.svelte +22 -0
- package/dist/components/primitives/input-group/input-group-text.svelte.d.ts +5 -0
- package/dist/components/primitives/input-group/input-group-textarea.svelte +23 -0
- package/dist/components/primitives/input-group/input-group-textarea.svelte.d.ts +3 -0
- package/dist/components/primitives/input-group/input-group.svelte +24 -0
- package/dist/components/primitives/{alert/alert-title.svelte.d.ts → input-group/input-group.svelte.d.ts} +4 -4
- package/dist/components/primitives/mode-toggle/mode-toggle.svelte +6 -7
- package/dist/components/primitives/popover/index.d.ts +9 -0
- package/dist/components/primitives/popover/index.js +11 -0
- package/dist/components/primitives/popover/popover-close.svelte +7 -0
- package/dist/components/primitives/popover/popover-close.svelte.d.ts +4 -0
- package/dist/components/primitives/popover/popover-content.svelte +31 -0
- package/dist/components/primitives/popover/popover-content.svelte.d.ts +10 -0
- package/dist/components/primitives/popover/popover-description.svelte +20 -0
- package/dist/components/primitives/popover/popover-description.svelte.d.ts +5 -0
- package/dist/components/primitives/popover/popover-header.svelte +20 -0
- package/dist/components/primitives/popover/popover-header.svelte.d.ts +5 -0
- package/dist/components/primitives/popover/popover-portal.svelte +7 -0
- package/dist/components/primitives/popover/popover-portal.svelte.d.ts +3 -0
- package/dist/components/primitives/popover/popover-title.svelte +15 -0
- package/dist/components/primitives/popover/popover-title.svelte.d.ts +5 -0
- package/dist/components/primitives/popover/popover-trigger.svelte +17 -0
- package/dist/components/primitives/popover/popover-trigger.svelte.d.ts +4 -0
- package/dist/components/primitives/popover/popover.svelte +7 -0
- package/dist/components/primitives/popover/popover.svelte.d.ts +3 -0
- package/dist/components/primitives/resizable/resizable-handle.svelte +6 -2
- package/dist/components/primitives/resizable/resizable-handle.svelte.d.ts +2 -0
- package/dist/components/primitives/resizable/resizable-pane-group.svelte +1 -4
- package/dist/components/primitives/scroll-area/scroll-area.svelte +1 -1
- package/dist/components/primitives/search/search.svelte +3 -3
- package/dist/components/primitives/select/select-content.svelte +1 -1
- package/dist/components/primitives/select/select-trigger.svelte +1 -1
- package/dist/components/primitives/severity.d.ts +7 -0
- package/dist/components/primitives/severity.js +19 -0
- package/dist/components/primitives/slider/slider.svelte +8 -3
- package/dist/components/primitives/slider/slider.svelte.d.ts +5 -1
- package/dist/components/primitives/sonner/sonner.svelte +1 -1
- package/dist/components/primitives/spinner/index.d.ts +1 -0
- package/dist/components/primitives/spinner/index.js +1 -0
- package/dist/components/primitives/spinner/spinner.svelte +29 -0
- package/dist/components/primitives/spinner/spinner.svelte.d.ts +4 -0
- package/dist/components/primitives/switch/switch.svelte +2 -2
- package/dist/components/primitives/tabs/tabs-list.svelte +27 -5
- package/dist/components/primitives/tabs/tabs-list.svelte.d.ts +22 -1
- package/dist/components/primitives/tabs/tabs-trigger.svelte +23 -5
- package/dist/components/primitives/tabs/tabs-trigger.svelte.d.ts +22 -1
- package/dist/components/primitives/tabs/tabs.svelte +6 -2
- package/dist/components/primitives/tabs/tabs.svelte.d.ts +5 -1
- package/dist/components/primitives/textarea/textarea.svelte +1 -1
- package/dist/components/primitives/theme-switcher/ThemeSwitcher.svelte +1 -1
- package/dist/components/primitives/toggle/index.d.ts +3 -0
- package/dist/components/primitives/toggle/index.js +5 -0
- package/dist/components/primitives/toggle/toggle.svelte +54 -0
- package/dist/components/primitives/toggle/toggle.svelte.d.ts +46 -0
- package/dist/components/primitives/toggle-group/index.d.ts +3 -0
- package/dist/components/primitives/toggle-group/index.js +5 -0
- package/dist/components/primitives/toggle-group/toggle-group-item.svelte +35 -0
- package/dist/components/primitives/toggle-group/toggle-group-item.svelte.d.ts +6 -0
- package/dist/components/primitives/toggle-group/toggle-group.svelte +75 -0
- package/dist/components/primitives/toggle-group/toggle-group.svelte.d.ts +17 -0
- package/dist/components/viewer/MeshMetadataPanel.svelte +119 -0
- package/dist/components/viewer/MeshMetadataPanel.svelte.d.ts +9 -0
- package/dist/components/viewer/SceneManager.svelte +14 -5
- package/dist/components/viewer/Viewer.svelte +243 -221
- package/dist/components/viewer/Viewer.svelte.d.ts +3 -0
- package/dist/compute/run-panel-action.d.ts +8 -0
- package/dist/compute/run-panel-action.js +12 -0
- package/dist/compute/solving.svelte.d.ts +11 -7
- package/dist/compute/solving.svelte.js +64 -45
- package/dist/compute/useSolveSession.svelte.js +3 -0
- package/dist/constants.d.ts +6 -8
- package/dist/constants.js +7 -9
- package/dist/contexts/hostContext.svelte.d.ts +39 -0
- package/dist/contexts/hostContext.svelte.js +9 -0
- package/dist/i18n/localeContext.svelte.d.ts +10 -3
- package/dist/i18n/localeContext.svelte.js +27 -5
- package/dist/i18n/messages.d.ts +150 -2
- package/dist/i18n/messages.js +261 -11
- package/dist/index.d.ts +4 -1
- package/dist/index.js +3 -0
- package/dist/public.d.ts +1 -1
- 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.js +21 -0
- package/dist/styles/base.css +80 -10
- package/dist/types/actionButton.d.ts +17 -3
- package/dist/types/presetLabels.d.ts +3 -2
- package/dist/types/presetLabels.js +9 -8
- package/dist/utils/file-download.js +10 -22
- package/dist/utils/host-files.d.ts +12 -0
- package/dist/utils/host-files.js +46 -0
- package/dist/utils/loadScript.d.ts +2 -0
- package/dist/utils/loadScript.js +2 -0
- package/dist/utils/webp-to-png.d.ts +10 -0
- package/dist/utils/webp-to-png.js +41 -0
- package/package.json +14 -14
- package/src/lib/components/ConfirmDialog.svelte +2 -10
- package/src/lib/components/ErrorScreen.svelte +21 -27
- package/src/lib/components/compute/AppLayout.svelte +286 -116
- package/src/lib/components/compute/ComputeApp.svelte +45 -24
- package/src/lib/components/compute/ComputeMessagesDialog.svelte +47 -83
- package/src/lib/components/compute/ParameterPresetManager.svelte +37 -130
- package/src/lib/components/compute/SolveMessages.svelte +131 -77
- package/src/lib/components/layout/AppShell.svelte +10 -6
- package/src/lib/components/layout/PageFooter.svelte +23 -11
- package/src/lib/components/layout/PageHeader.svelte +11 -7
- package/src/lib/components/layout/Pagination.svelte +2 -4
- package/src/lib/components/layout/SectionHeader.svelte +4 -2
- package/src/lib/components/layout/SideNav.svelte +56 -7
- package/src/lib/components/preview/ChartOutput.svelte +35 -25
- package/src/lib/components/preview/Group.svelte +92 -103
- package/src/lib/components/preview/HelpButton.svelte +36 -0
- package/src/lib/components/preview/ImageOutput.svelte +430 -71
- package/src/lib/components/preview/InputControl.svelte +163 -90
- package/src/lib/components/preview/OutputDisplay.svelte +28 -33
- package/src/lib/components/preview/TabBar.svelte +106 -22
- package/src/lib/components/preview/TabContent.svelte +63 -57
- package/src/lib/components/preview/TabLayout.svelte +27 -5
- package/src/lib/components/preview/inputs/CheckboxInput.svelte +7 -7
- package/src/lib/components/preview/inputs/ChecklistInput.svelte +7 -2
- package/src/lib/components/preview/inputs/ColorInput.svelte +4 -2
- package/src/lib/components/preview/inputs/DropdownInput.svelte +19 -4
- package/src/lib/components/preview/inputs/FileInput.svelte +112 -108
- package/src/lib/components/preview/inputs/GeometryInput.svelte +128 -0
- package/src/lib/components/preview/inputs/NumberInput.svelte +123 -61
- package/src/lib/components/preview/inputs/OptionGlyph.svelte +29 -0
- package/src/lib/components/preview/inputs/SegmentedInput.svelte +44 -0
- package/src/lib/components/preview/inputs/TextInput.svelte +8 -4
- package/src/lib/components/preview/inputs/TileInput.svelte +80 -0
- package/src/lib/components/preview/inputs/index.ts +3 -0
- package/src/lib/components/primitives/CalculateButton.svelte +56 -24
- package/src/lib/components/primitives/Callout.svelte +11 -18
- package/src/lib/components/primitives/DataTable.svelte +38 -5
- package/src/lib/components/primitives/FilterableDropdown.svelte +42 -129
- package/src/lib/components/primitives/IssueList.svelte +56 -0
- package/src/lib/components/primitives/SeverityIcon.svelte +15 -0
- package/src/lib/components/primitives/SolvingIndicator.svelte +43 -42
- package/src/lib/components/primitives/StateDisplay.svelte +19 -79
- package/src/lib/components/primitives/ViewToggle.svelte +18 -33
- package/src/lib/components/primitives/alert-dialog/alert-dialog-action.svelte +9 -3
- package/src/lib/components/primitives/alert-dialog/alert-dialog-content.svelte +1 -1
- package/src/lib/components/primitives/alert-dialog/alert-dialog-overlay.svelte +1 -1
- package/src/lib/components/primitives/badge/badge.svelte +2 -2
- package/src/lib/components/primitives/button/button.svelte +6 -2
- package/src/lib/components/primitives/card/card-header.svelte +1 -1
- package/src/lib/components/primitives/card/card.svelte +21 -5
- package/src/lib/components/primitives/card/index.ts +1 -4
- package/src/lib/components/primitives/checkbox/checkbox.svelte +1 -1
- package/src/lib/components/primitives/command/command-dialog.svelte +42 -0
- package/src/lib/components/primitives/command/command-empty.svelte +17 -0
- package/src/lib/components/primitives/command/command-group.svelte +33 -0
- package/src/lib/components/primitives/command/command-input.svelte +36 -0
- package/src/lib/components/primitives/command/command-item.svelte +28 -0
- package/src/lib/components/primitives/command/command-link-item.svelte +21 -0
- package/src/lib/components/primitives/command/command-list.svelte +20 -0
- package/src/lib/components/primitives/command/command-loading.svelte +7 -0
- package/src/lib/components/primitives/command/command-separator.svelte +17 -0
- package/src/lib/components/primitives/command/command-shortcut.svelte +23 -0
- package/src/lib/components/primitives/command/command.svelte +28 -0
- package/src/lib/components/primitives/command/index.ts +37 -0
- package/src/lib/components/primitives/context-menu/context-menu-content.svelte +1 -1
- package/src/lib/components/primitives/context-menu/context-menu-sub-content.svelte +1 -1
- package/src/lib/components/primitives/dialog/dialog-content.svelte +11 -3
- package/src/lib/components/primitives/dialog/dialog-overlay.svelte +1 -1
- package/src/lib/components/primitives/dialog/dialog-title.svelte +6 -2
- package/src/lib/components/primitives/drawer/Drawer.svelte +2 -2
- package/src/lib/components/primitives/dropdown-menu/dropdown-menu-checkbox-group.svelte +16 -0
- package/src/lib/components/primitives/dropdown-menu/dropdown-menu-checkbox-item.svelte +46 -0
- package/src/lib/components/primitives/dropdown-menu/dropdown-menu-content.svelte +31 -0
- package/src/lib/components/primitives/dropdown-menu/dropdown-menu-group-heading.svelte +22 -0
- package/src/lib/components/primitives/dropdown-menu/dropdown-menu-group.svelte +7 -0
- package/src/lib/components/primitives/dropdown-menu/dropdown-menu-item.svelte +27 -0
- package/src/lib/components/primitives/dropdown-menu/dropdown-menu-label.svelte +24 -0
- package/src/lib/components/primitives/dropdown-menu/dropdown-menu-portal.svelte +7 -0
- package/src/lib/components/primitives/dropdown-menu/dropdown-menu-radio-group.svelte +16 -0
- package/src/lib/components/primitives/dropdown-menu/dropdown-menu-radio-item.svelte +36 -0
- package/src/lib/components/primitives/dropdown-menu/dropdown-menu-separator.svelte +17 -0
- package/src/lib/components/primitives/dropdown-menu/dropdown-menu-shortcut.svelte +23 -0
- package/src/lib/components/primitives/dropdown-menu/dropdown-menu-sub-content.svelte +31 -0
- package/src/lib/components/primitives/dropdown-menu/dropdown-menu-sub-trigger.svelte +29 -0
- package/src/lib/components/primitives/dropdown-menu/dropdown-menu-sub.svelte +7 -0
- package/src/lib/components/primitives/dropdown-menu/dropdown-menu-trigger.svelte +7 -0
- package/src/lib/components/primitives/dropdown-menu/dropdown-menu.svelte +7 -0
- package/src/lib/components/primitives/dropdown-menu/index.ts +54 -0
- package/src/lib/components/primitives/{alert/alert-description.svelte → empty/empty-content.svelte} +3 -3
- package/src/lib/components/primitives/empty/empty-description.svelte +23 -0
- package/src/lib/components/primitives/{alert/alert-title.svelte → empty/empty-header.svelte} +3 -3
- package/src/lib/components/primitives/empty/empty-media.svelte +41 -0
- package/src/lib/components/primitives/{card/card-action.svelte → empty/empty-title.svelte} +2 -2
- package/src/lib/components/primitives/empty/empty.svelte +23 -0
- package/src/lib/components/primitives/empty/index.ts +22 -0
- package/src/lib/components/primitives/index.ts +10 -1
- package/src/lib/components/primitives/input/input.svelte +4 -4
- package/src/lib/components/primitives/input-group/index.ts +22 -0
- package/src/lib/components/primitives/input-group/input-group-addon.svelte +53 -0
- package/src/lib/components/primitives/input-group/input-group-button.svelte +49 -0
- package/src/lib/components/primitives/input-group/input-group-input.svelte +25 -0
- package/src/lib/components/primitives/input-group/input-group-text.svelte +22 -0
- package/src/lib/components/primitives/input-group/input-group-textarea.svelte +23 -0
- package/src/lib/components/primitives/input-group/input-group.svelte +24 -0
- package/src/lib/components/primitives/mode-toggle/mode-toggle.svelte +6 -7
- package/src/lib/components/primitives/popover/index.ts +28 -0
- package/src/lib/components/primitives/popover/popover-close.svelte +7 -0
- package/src/lib/components/primitives/popover/popover-content.svelte +31 -0
- package/src/lib/components/primitives/popover/popover-description.svelte +20 -0
- package/src/lib/components/primitives/popover/popover-header.svelte +20 -0
- package/src/lib/components/primitives/popover/popover-portal.svelte +7 -0
- package/src/lib/components/primitives/popover/popover-title.svelte +15 -0
- package/src/lib/components/primitives/popover/popover-trigger.svelte +17 -0
- package/src/lib/components/primitives/popover/popover.svelte +7 -0
- package/src/lib/components/primitives/resizable/resizable-handle.svelte +6 -2
- package/src/lib/components/primitives/resizable/resizable-pane-group.svelte +1 -4
- package/src/lib/components/primitives/scroll-area/scroll-area.svelte +1 -1
- package/src/lib/components/primitives/search/search.svelte +3 -3
- package/src/lib/components/primitives/select/select-content.svelte +1 -1
- package/src/lib/components/primitives/select/select-trigger.svelte +1 -1
- package/src/lib/components/primitives/severity.ts +26 -0
- package/src/lib/components/primitives/slider/slider.svelte +8 -3
- package/src/lib/components/primitives/sonner/sonner.svelte +1 -1
- package/src/lib/components/primitives/spinner/index.ts +1 -0
- package/src/lib/components/primitives/spinner/spinner.svelte +29 -0
- package/src/lib/components/primitives/switch/switch.svelte +2 -2
- package/src/lib/components/primitives/tabs/tabs-list.svelte +27 -5
- package/src/lib/components/primitives/tabs/tabs-trigger.svelte +23 -5
- package/src/lib/components/primitives/tabs/tabs.svelte +6 -2
- package/src/lib/components/primitives/textarea/textarea.svelte +1 -1
- package/src/lib/components/primitives/theme-switcher/ThemeSwitcher.svelte +1 -1
- package/src/lib/components/primitives/toggle/index.ts +13 -0
- package/src/lib/components/primitives/toggle/toggle.svelte +54 -0
- package/src/lib/components/primitives/toggle-group/index.ts +10 -0
- package/src/lib/components/primitives/toggle-group/toggle-group-item.svelte +35 -0
- package/src/lib/components/primitives/toggle-group/toggle-group.svelte +75 -0
- package/src/lib/components/viewer/MeshMetadataPanel.svelte +119 -0
- package/src/lib/components/viewer/SceneManager.svelte +14 -5
- package/src/lib/components/viewer/Viewer.svelte +243 -221
- package/src/lib/compute/run-panel-action.ts +16 -0
- package/src/lib/compute/solving.svelte.ts +66 -50
- package/src/lib/compute/useSolveSession.svelte.ts +3 -0
- package/src/lib/constants.ts +7 -9
- package/src/lib/contexts/hostContext.svelte.ts +51 -0
- package/src/lib/i18n/localeContext.svelte.ts +40 -5
- package/src/lib/i18n/messages.ts +453 -13
- package/src/lib/index.ts +21 -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 +23 -0
- package/src/lib/styles/base.css +80 -10
- package/src/lib/types/actionButton.ts +16 -3
- package/src/lib/types/presetLabels.ts +13 -11
- package/src/lib/utils/file-download.ts +11 -21
- package/src/lib/utils/host-files.ts +61 -0
- package/src/lib/utils/loadScript.ts +3 -0
- package/src/lib/utils/webp-to-png.ts +48 -0
- package/dist/components/primitives/alert/alert.svelte +0 -44
- package/dist/components/primitives/alert/alert.svelte.d.ts +0 -26
- package/dist/components/primitives/alert/index.d.ts +0 -5
- package/dist/components/primitives/alert/index.js +0 -7
- package/dist/components/viewer/MeshMetadataDialog.svelte +0 -126
- package/dist/components/viewer/MeshMetadataDialog.svelte.d.ts +0 -10
- package/src/lib/components/primitives/alert/alert.svelte +0 -44
- package/src/lib/components/primitives/alert/index.ts +0 -14
- package/src/lib/components/viewer/MeshMetadataDialog.svelte +0 -126
|
@@ -5,6 +5,10 @@
|
|
|
5
5
|
import { toast } from '../../primitives/sonner';
|
|
6
6
|
import { FileUp, Link, CircleAlert, CircleCheck } from '@lucide/svelte';
|
|
7
7
|
import { APP_DEFAULTS } from '../../../constants';
|
|
8
|
+
import { getLocaleContext } from '../../../i18n/localeContext.svelte';
|
|
9
|
+
import { formatMessage } from '../../../i18n/messages';
|
|
10
|
+
import { pickFile } from '../../../utils/host-files';
|
|
11
|
+
import { acceptsFileEnding, isWebp, shouldConvertWebp, webpToPng } from '../../../utils/webp-to-png';
|
|
8
12
|
|
|
9
13
|
interface Props {
|
|
10
14
|
value?: string;
|
|
@@ -22,6 +26,9 @@
|
|
|
22
26
|
onChange
|
|
23
27
|
}: Props = $props();
|
|
24
28
|
|
|
29
|
+
const locale = getLocaleContext();
|
|
30
|
+
const t = $derived(locale.messages);
|
|
31
|
+
|
|
25
32
|
let effectiveModes = $derived(
|
|
26
33
|
allowedInputModes && allowedInputModes.length > 0
|
|
27
34
|
? allowedInputModes
|
|
@@ -35,7 +42,6 @@
|
|
|
35
42
|
activeMode = effectiveModes.includes(preferred) ? preferred : effectiveModes[0];
|
|
36
43
|
});
|
|
37
44
|
|
|
38
|
-
let fileInput: HTMLInputElement | null = $state(null);
|
|
39
45
|
let uploadedFileName = $state('');
|
|
40
46
|
let urlInput = $state('');
|
|
41
47
|
let isDragging = $state(false);
|
|
@@ -52,9 +58,12 @@
|
|
|
52
58
|
if (parsed.type === 'base64') {
|
|
53
59
|
if (parsed._isMetadata && parsed._fileSize) {
|
|
54
60
|
const sizeMB = (parsed._fileSize / 1024 / 1024).toFixed(2);
|
|
55
|
-
uploadedFileName =
|
|
61
|
+
uploadedFileName = formatMessage(t.uploadedFileSize, {
|
|
62
|
+
ext: parsed.fileEnding,
|
|
63
|
+
size: sizeMB
|
|
64
|
+
});
|
|
56
65
|
} else {
|
|
57
|
-
uploadedFileName =
|
|
66
|
+
uploadedFileName = formatMessage(t.uploadedFile, { ext: parsed.fileEnding });
|
|
58
67
|
}
|
|
59
68
|
} else if (parsed.type === 'url') {
|
|
60
69
|
urlInput = parsed.file;
|
|
@@ -65,6 +74,20 @@
|
|
|
65
74
|
}
|
|
66
75
|
});
|
|
67
76
|
|
|
77
|
+
function formatNotAccepted(fileEnding: string): string {
|
|
78
|
+
return formatMessage(t.fileFormatNotAccepted, {
|
|
79
|
+
ext: fileEnding,
|
|
80
|
+
formats: acceptedFormats.join(', ')
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function formatTooLarge(bytes: number): string {
|
|
85
|
+
return formatMessage(t.fileTooLarge, {
|
|
86
|
+
size: (bytes / 1024 / 1024).toFixed(2),
|
|
87
|
+
max: APP_DEFAULTS.FILE_UPLOAD.MAX_SIZE_MB
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
|
|
68
91
|
function getFileExtension(filename: string): string {
|
|
69
92
|
// Strip query strings before extracting extension
|
|
70
93
|
const cleanPath = filename.split('?')[0];
|
|
@@ -72,9 +95,27 @@
|
|
|
72
95
|
return ext.toLowerCase();
|
|
73
96
|
}
|
|
74
97
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
98
|
+
// Runs before the size cap: the PNG is larger than the WebP it came from. A WebP already over
|
|
99
|
+
// the cap is passed through unconverted, so the cap rejects it without a full decode.
|
|
100
|
+
async function prepare(
|
|
101
|
+
blob: Blob,
|
|
102
|
+
fileEnding: string
|
|
103
|
+
): Promise<{ blob: Blob; fileEnding: string }> {
|
|
104
|
+
if (blob.size > APP_DEFAULTS.FILE_UPLOAD.MAX_SIZE_BYTES) return { blob, fileEnding };
|
|
105
|
+
if (!shouldConvertWebp(fileEnding, acceptedFormats)) return { blob, fileEnding };
|
|
106
|
+
return { blob: await webpToPng(blob), fileEnding: '.png' };
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function readBase64(blob: Blob): Promise<string> {
|
|
110
|
+
return new Promise<string>((resolve, reject) => {
|
|
111
|
+
const reader = new FileReader();
|
|
112
|
+
reader.onload = (e) => {
|
|
113
|
+
const result = e.target?.result as string;
|
|
114
|
+
resolve(result.includes(',') ? result.split(',')[1] : result);
|
|
115
|
+
};
|
|
116
|
+
reader.onerror = () => reject(new Error(t.fileReadFailed));
|
|
117
|
+
reader.readAsDataURL(blob);
|
|
118
|
+
});
|
|
78
119
|
}
|
|
79
120
|
|
|
80
121
|
function isCorsError(error: unknown): boolean {
|
|
@@ -96,56 +137,52 @@
|
|
|
96
137
|
try {
|
|
97
138
|
parsedUrl = new URL(urlInput);
|
|
98
139
|
} catch {
|
|
99
|
-
urlError = { message:
|
|
140
|
+
urlError = { message: t.urlInvalid, isCors: false };
|
|
100
141
|
return;
|
|
101
142
|
}
|
|
102
143
|
|
|
103
144
|
if (parsedUrl.protocol !== 'https:' && parsedUrl.protocol !== 'http:') {
|
|
104
|
-
urlError = { message:
|
|
145
|
+
urlError = { message: t.urlProtocolUnsupported, isCors: false };
|
|
105
146
|
return;
|
|
106
147
|
}
|
|
107
148
|
|
|
108
149
|
const response = await fetch(urlInput);
|
|
109
150
|
if (!response.ok) {
|
|
110
151
|
urlError = {
|
|
111
|
-
message:
|
|
152
|
+
message: formatMessage(t.urlServerError, {
|
|
153
|
+
status: `${response.status} ${response.statusText}`.trim()
|
|
154
|
+
}),
|
|
112
155
|
isCors: false
|
|
113
156
|
};
|
|
114
157
|
return;
|
|
115
158
|
}
|
|
116
159
|
|
|
117
|
-
const
|
|
118
|
-
const
|
|
160
|
+
const fetched = await response.blob();
|
|
161
|
+
const requestedEnding = (await isWebp(fetched)) ? '.webp' : getFileExtension(urlInput);
|
|
119
162
|
|
|
120
|
-
if (!
|
|
121
|
-
urlError = {
|
|
122
|
-
message: `File format "${fileEnding}" is not accepted. Allowed: ${acceptedFormats.join(', ')}`,
|
|
123
|
-
isCors: false
|
|
124
|
-
};
|
|
163
|
+
if (!acceptsFileEnding(requestedEnding, acceptedFormats)) {
|
|
164
|
+
urlError = { message: formatNotAccepted(requestedEnding), isCors: false };
|
|
125
165
|
return;
|
|
126
166
|
}
|
|
127
167
|
|
|
168
|
+
const { blob, fileEnding } = await prepare(fetched, requestedEnding);
|
|
169
|
+
|
|
128
170
|
const maxSize = APP_DEFAULTS.FILE_UPLOAD.MAX_SIZE_BYTES;
|
|
129
171
|
if (blob.size > maxSize) {
|
|
130
172
|
urlError = {
|
|
131
|
-
message:
|
|
173
|
+
message: `${formatTooLarge(blob.size)} ${t.fileTooLargeUseUpload}`,
|
|
132
174
|
isCors: false
|
|
133
175
|
};
|
|
134
176
|
return;
|
|
135
177
|
}
|
|
136
178
|
|
|
137
|
-
const base64Data = await
|
|
138
|
-
const reader = new FileReader();
|
|
139
|
-
reader.onload = (e) => {
|
|
140
|
-
const result = e.target?.result as string;
|
|
141
|
-
resolve(result.includes(',') ? result.split(',')[1] : result);
|
|
142
|
-
};
|
|
143
|
-
reader.onerror = () => reject(new Error('Failed to read the downloaded file.'));
|
|
144
|
-
reader.readAsDataURL(blob);
|
|
145
|
-
});
|
|
179
|
+
const base64Data = await readBase64(blob);
|
|
146
180
|
const data = JSON.stringify({ file: base64Data, type: 'base64', fileEnding });
|
|
147
181
|
value = data;
|
|
148
|
-
urlSuccess =
|
|
182
|
+
urlSuccess = formatMessage(t.fileLoaded, {
|
|
183
|
+
ext: fileEnding,
|
|
184
|
+
size: (blob.size / 1024).toFixed(0)
|
|
185
|
+
});
|
|
149
186
|
onChange(data);
|
|
150
187
|
} catch (error) {
|
|
151
188
|
if (isCorsError(error)) {
|
|
@@ -158,26 +195,22 @@
|
|
|
158
195
|
})();
|
|
159
196
|
// The opaque TypeError hides CORS blocks and plain network failures (404, DNS)
|
|
160
197
|
// alike, so the message has to cover both.
|
|
161
|
-
let hint =
|
|
162
|
-
'Check that the URL is correct and the file is publicly accessible. If the server requires login, download the file and use the Upload option instead.';
|
|
198
|
+
let hint = t.urlUnreachableHint;
|
|
163
199
|
if (host.includes('sharepoint.com') || host.includes('onedrive.com')) {
|
|
164
|
-
hint =
|
|
165
|
-
'SharePoint/OneDrive blocks browser access. Open the file in SharePoint, use "Download" to save it locally, then upload it here.';
|
|
200
|
+
hint = t.urlHintSharePoint;
|
|
166
201
|
} else if (host.includes('drive.google.com')) {
|
|
167
|
-
hint =
|
|
168
|
-
'Google Drive blocks browser access. Use "Download" in Google Drive to save the file locally, then upload it here.';
|
|
202
|
+
hint = t.urlHintGoogleDrive;
|
|
169
203
|
} else if (host.includes('dropbox.com')) {
|
|
170
|
-
hint =
|
|
171
|
-
'Dropbox links may block browser access. Try changing "?dl=0" to "?dl=1" in the URL, or download and upload instead.';
|
|
204
|
+
hint = t.urlHintDropbox;
|
|
172
205
|
}
|
|
173
206
|
urlError = {
|
|
174
|
-
message:
|
|
207
|
+
message: formatMessage(t.urlUnreachable, { host }),
|
|
175
208
|
isCors: true,
|
|
176
209
|
hint
|
|
177
210
|
};
|
|
178
211
|
} else {
|
|
179
212
|
urlError = {
|
|
180
|
-
message: error instanceof Error ? error.message :
|
|
213
|
+
message: error instanceof Error ? error.message : t.unknownError,
|
|
181
214
|
isCors: false
|
|
182
215
|
};
|
|
183
216
|
}
|
|
@@ -186,50 +219,39 @@
|
|
|
186
219
|
}
|
|
187
220
|
}
|
|
188
221
|
|
|
189
|
-
function
|
|
190
|
-
const
|
|
191
|
-
const file = target.files?.[0];
|
|
192
|
-
if (!file) return;
|
|
222
|
+
async function handleFile(file: File) {
|
|
223
|
+
const requestedEnding = getFileExtension(file.name);
|
|
193
224
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
if (!isValidFileExtension(fileEnding)) {
|
|
197
|
-
toast.error(`File format not accepted: ${fileEnding}`);
|
|
225
|
+
if (!acceptsFileEnding(requestedEnding, acceptedFormats)) {
|
|
226
|
+
toast.error(formatNotAccepted(requestedEnding));
|
|
198
227
|
return;
|
|
199
228
|
}
|
|
200
229
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
)
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
uploadedFileName = file.name;
|
|
214
|
-
|
|
215
|
-
const reader = new FileReader();
|
|
216
|
-
reader.onload = (e) => {
|
|
217
|
-
const base64 = e.target?.result as string;
|
|
218
|
-
const base64Data = base64.includes(',') ? base64.split(',')[1] : base64;
|
|
230
|
+
try {
|
|
231
|
+
const { blob, fileEnding } = await prepare(file, requestedEnding);
|
|
232
|
+
|
|
233
|
+
// The file is base64-embedded into the compute request body, so without a
|
|
234
|
+
// client-side cap an oversize file comes back as an opaque 413. This cap is
|
|
235
|
+
// currently LOOSER than the server's COMPUTE_REQUEST_MAX_BYTES (see the TEMP
|
|
236
|
+
// note in constants.ts) — some files pass here and still 413. The URL import
|
|
237
|
+
// path applies the same cap.
|
|
238
|
+
if (blob.size > APP_DEFAULTS.FILE_UPLOAD.MAX_SIZE_BYTES) {
|
|
239
|
+
toast.error(formatTooLarge(blob.size));
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
219
242
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
type: 'base64',
|
|
223
|
-
fileEnding
|
|
224
|
-
});
|
|
243
|
+
uploadedFileName = file.name;
|
|
244
|
+
const data = JSON.stringify({ file: await readBase64(blob), type: 'base64', fileEnding });
|
|
225
245
|
value = data;
|
|
226
246
|
onChange(data);
|
|
227
|
-
}
|
|
228
|
-
|
|
247
|
+
} catch (error) {
|
|
248
|
+
toast.error(error instanceof Error ? error.message : t.fileReadFailed);
|
|
249
|
+
}
|
|
229
250
|
}
|
|
230
251
|
|
|
231
|
-
function openFilePicker() {
|
|
232
|
-
|
|
252
|
+
async function openFilePicker() {
|
|
253
|
+
const file = await pickFile({ accept: acceptAttribute });
|
|
254
|
+
if (file) handleFile(file);
|
|
233
255
|
}
|
|
234
256
|
|
|
235
257
|
function handleDragOver(e: DragEvent) {
|
|
@@ -245,40 +267,28 @@
|
|
|
245
267
|
e.preventDefault();
|
|
246
268
|
isDragging = false;
|
|
247
269
|
|
|
248
|
-
const
|
|
249
|
-
if (
|
|
250
|
-
const fakeEvent = new Event('change');
|
|
251
|
-
const fakeTarget = { files: files } as HTMLInputElement;
|
|
252
|
-
Object.defineProperty(fakeEvent, 'target', { value: fakeTarget });
|
|
253
|
-
handleFileUpload(fakeEvent);
|
|
254
|
-
}
|
|
270
|
+
const file = e.dataTransfer?.files?.[0];
|
|
271
|
+
if (file) handleFile(file);
|
|
255
272
|
}
|
|
256
273
|
|
|
257
274
|
const acceptAttribute = $derived(acceptedFormats.length > 0 ? acceptedFormats.join(',') : '*');
|
|
258
275
|
</script>
|
|
259
276
|
|
|
260
|
-
<div class="gap-
|
|
261
|
-
<input
|
|
262
|
-
bind:this={fileInput}
|
|
263
|
-
type="file"
|
|
264
|
-
accept={acceptAttribute}
|
|
265
|
-
onchange={handleFileUpload}
|
|
266
|
-
class="hidden"
|
|
267
|
-
/>
|
|
268
|
-
|
|
277
|
+
<div class="gap-2.5 flex w-full flex-col">
|
|
269
278
|
{#if showToggle}
|
|
270
|
-
<div class="
|
|
279
|
+
<div class="p-0.5 text-xs flex rounded-md bg-muted">
|
|
271
280
|
{#each effectiveModes as mode (mode)}
|
|
272
281
|
<button
|
|
273
282
|
type="button"
|
|
274
283
|
onclick={() => (activeMode = mode)}
|
|
275
|
-
|
|
284
|
+
aria-pressed={activeMode === mode}
|
|
285
|
+
class={`px-3 py-1 font-medium flex-1 rounded-sm transition-colors ${
|
|
276
286
|
activeMode === mode
|
|
277
|
-
? 'bg-
|
|
278
|
-
: 'text-muted-foreground hover:
|
|
287
|
+
? 'shadow-xs bg-background text-foreground'
|
|
288
|
+
: 'text-muted-foreground hover:text-foreground'
|
|
279
289
|
}`}
|
|
280
290
|
>
|
|
281
|
-
{mode === 'upload' ?
|
|
291
|
+
{mode === 'upload' ? t.fileModeUpload : t.fileModeUrl}
|
|
282
292
|
</button>
|
|
283
293
|
{/each}
|
|
284
294
|
</div>
|
|
@@ -286,9 +296,9 @@
|
|
|
286
296
|
|
|
287
297
|
{#if activeMode === 'url'}
|
|
288
298
|
<div class="gap-2 flex flex-col">
|
|
289
|
-
<Label for="url-input"
|
|
299
|
+
<Label for="url-input">
|
|
290
300
|
<Link size={16} />
|
|
291
|
-
|
|
301
|
+
{t.fileUrlLabel}
|
|
292
302
|
</Label>
|
|
293
303
|
<div class="gap-2 flex">
|
|
294
304
|
<Input
|
|
@@ -297,7 +307,7 @@
|
|
|
297
307
|
bind:value={urlInput}
|
|
298
308
|
placeholder="https://example.com/model.3dm"
|
|
299
309
|
disabled={isLoading}
|
|
300
|
-
|
|
310
|
+
aria-invalid={urlError ? true : undefined}
|
|
301
311
|
oninput={() => {
|
|
302
312
|
urlError = null;
|
|
303
313
|
urlSuccess = '';
|
|
@@ -309,7 +319,7 @@
|
|
|
309
319
|
disabled={isLoading || !urlInput.trim()}
|
|
310
320
|
onclick={handleUrlChange}
|
|
311
321
|
>
|
|
312
|
-
{isLoading ?
|
|
322
|
+
{isLoading ? t.fetchingFile : t.fetchFile}
|
|
313
323
|
</Button>
|
|
314
324
|
</div>
|
|
315
325
|
|
|
@@ -335,32 +345,26 @@
|
|
|
335
345
|
{/if}
|
|
336
346
|
|
|
337
347
|
{#if !urlError && !urlSuccess}
|
|
338
|
-
<p class="text-xs text-muted-foreground">
|
|
339
|
-
URL must be publicly accessible (no login required).
|
|
340
|
-
</p>
|
|
348
|
+
<p class="text-xs text-muted-foreground">{t.fileUrlPublic}</p>
|
|
341
349
|
{/if}
|
|
342
350
|
</div>
|
|
343
351
|
{:else}
|
|
344
352
|
<div class="gap-2 flex flex-col">
|
|
345
|
-
<Label for="file-upload" class="gap-2 flex items-center">
|
|
346
|
-
<FileUp size={16} />
|
|
347
|
-
Upload File
|
|
348
|
-
</Label>
|
|
349
353
|
<Button
|
|
350
354
|
type="button"
|
|
351
|
-
variant=
|
|
352
|
-
class="
|
|
355
|
+
variant={isDragging ? 'secondary' : 'outline'}
|
|
356
|
+
class="w-full"
|
|
353
357
|
onclick={openFilePicker}
|
|
354
358
|
ondragover={handleDragOver}
|
|
355
359
|
ondragleave={handleDragLeave}
|
|
356
360
|
ondrop={handleDrop}
|
|
357
361
|
>
|
|
358
362
|
<FileUp size={16} />
|
|
359
|
-
{uploadedFileName ||
|
|
363
|
+
{uploadedFileName || t.chooseFile}
|
|
360
364
|
</Button>
|
|
361
365
|
{#if acceptedFormats.length > 0}
|
|
362
366
|
<p class="text-xs text-muted-foreground">
|
|
363
|
-
|
|
367
|
+
{formatMessage(t.acceptedFormats, { formats: acceptedFormats.join(', ') })}
|
|
364
368
|
</p>
|
|
365
369
|
{/if}
|
|
366
370
|
</div>
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { Button } from '../../primitives/button';
|
|
3
|
+
import type { GeometryPickResult, PickKind } from '../../../contexts/hostContext.svelte';
|
|
4
|
+
import { getLocaleContext } from '../../../i18n/localeContext.svelte';
|
|
5
|
+
import type { ViewerMessages } from '../../../i18n/messages';
|
|
6
|
+
|
|
7
|
+
interface Props {
|
|
8
|
+
inputId: string;
|
|
9
|
+
/** The kinds of object the input takes; one kind names the button after it. */
|
|
10
|
+
kinds?: readonly PickKind[];
|
|
11
|
+
/** 1 picks a single object. */
|
|
12
|
+
atMost?: number;
|
|
13
|
+
/** What the host reports the param holds, such as "2 curves"; absent until something is picked. */
|
|
14
|
+
summary?: string;
|
|
15
|
+
/** Absent where this page may not pick, such as a browser tab beside the Rhino panel. */
|
|
16
|
+
onPick?: () => Promise<GeometryPickResult>;
|
|
17
|
+
onClear?: () => void;
|
|
18
|
+
/** Subscribes to what the host holds after any page picks or clears; returns an unsubscribe. */
|
|
19
|
+
watchSummary?: (listener: (summary: string | null) => void) => () => void;
|
|
20
|
+
/** Shown when the pick fails; the host's own message. */
|
|
21
|
+
onError?: (message: string) => void;
|
|
22
|
+
disabled?: boolean;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
let {
|
|
26
|
+
inputId,
|
|
27
|
+
kinds,
|
|
28
|
+
atMost,
|
|
29
|
+
summary,
|
|
30
|
+
onPick,
|
|
31
|
+
onClear,
|
|
32
|
+
watchSummary,
|
|
33
|
+
onError,
|
|
34
|
+
disabled = false
|
|
35
|
+
}: Props = $props();
|
|
36
|
+
|
|
37
|
+
const locale = getLocaleContext();
|
|
38
|
+
const t = $derived(locale.messages);
|
|
39
|
+
|
|
40
|
+
type PickLabels = readonly [one: keyof ViewerMessages, other: keyof ViewerMessages];
|
|
41
|
+
|
|
42
|
+
const ANY_LABELS: PickLabels = ['geometryPickAnyOne', 'geometryPickAnyOther'];
|
|
43
|
+
const KIND_LABELS: Record<PickKind, PickLabels> = {
|
|
44
|
+
point: ['geometryPickPointOne', 'geometryPickPointOther'],
|
|
45
|
+
pointCloud: ['geometryPickPointCloudOne', 'geometryPickPointCloudOther'],
|
|
46
|
+
curve: ['geometryPickCurveOne', 'geometryPickCurveOther'],
|
|
47
|
+
line: ['geometryPickLineOne', 'geometryPickLineOther'],
|
|
48
|
+
plane: ['geometryPickPlaneOne', 'geometryPickPlaneOther'],
|
|
49
|
+
surface: ['geometryPickSurfaceOne', 'geometryPickSurfaceOther'],
|
|
50
|
+
polysurface: ['geometryPickPolysurfaceOne', 'geometryPickPolysurfaceOther'],
|
|
51
|
+
extrusion: ['geometryPickExtrusionOne', 'geometryPickExtrusionOther'],
|
|
52
|
+
mesh: ['geometryPickMeshOne', 'geometryPickMeshOther'],
|
|
53
|
+
subd: ['geometryPickSubdOne', 'geometryPickSubdOther'],
|
|
54
|
+
block: ['geometryPickBlockOne', 'geometryPickBlockOther']
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
const pickLabel = $derived.by(() => {
|
|
58
|
+
const [one, other] = kinds?.length === 1 ? KIND_LABELS[kinds[0]] : ANY_LABELS;
|
|
59
|
+
return t[atMost === 1 ? one : other];
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
// Rhino's command line prompts during the pick; the page keeps the button from being pressed
|
|
63
|
+
// twice and says where to look.
|
|
64
|
+
let picking = $state(false);
|
|
65
|
+
// The last pick or clear wins over what the host reported when the page loaded.
|
|
66
|
+
let local = $state<string | null | undefined>(undefined);
|
|
67
|
+
const shown = $derived(local !== undefined ? local : (summary ?? null));
|
|
68
|
+
|
|
69
|
+
$effect(() =>
|
|
70
|
+
watchSummary?.((held) => {
|
|
71
|
+
local = held;
|
|
72
|
+
})
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
async function pick(onPick: () => Promise<GeometryPickResult>) {
|
|
76
|
+
picking = true;
|
|
77
|
+
try {
|
|
78
|
+
const result = await onPick();
|
|
79
|
+
if (result.outcome === 'picked') local = result.summary;
|
|
80
|
+
else if (result.outcome === 'failed') onError?.(result.error);
|
|
81
|
+
} finally {
|
|
82
|
+
picking = false;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// The field label points at inputId: the button where there is one, else an <output>, which
|
|
87
|
+
// unlike a <span> can be labelled.
|
|
88
|
+
const readout = $derived(onPick ? 'span' : 'output');
|
|
89
|
+
|
|
90
|
+
function clear(onClear: () => void) {
|
|
91
|
+
local = null;
|
|
92
|
+
onClear();
|
|
93
|
+
}
|
|
94
|
+
</script>
|
|
95
|
+
|
|
96
|
+
<div class="gap-2 min-w-0 flex flex-wrap items-center">
|
|
97
|
+
{#if onPick}
|
|
98
|
+
<Button
|
|
99
|
+
id={inputId}
|
|
100
|
+
variant="outline"
|
|
101
|
+
size="sm"
|
|
102
|
+
onclick={() => pick(onPick)}
|
|
103
|
+
disabled={disabled || picking}
|
|
104
|
+
>
|
|
105
|
+
{shown ? t.geometryPickAgain : pickLabel}
|
|
106
|
+
</Button>
|
|
107
|
+
{/if}
|
|
108
|
+
{#if picking}
|
|
109
|
+
<span class="text-sm min-w-0 text-muted-foreground" role="status">{t.geometryPicking}</span>
|
|
110
|
+
{:else if shown}
|
|
111
|
+
<svelte:element
|
|
112
|
+
this={readout}
|
|
113
|
+
id={onPick ? undefined : inputId}
|
|
114
|
+
class="text-sm min-w-0 truncate text-foreground"
|
|
115
|
+
>
|
|
116
|
+
{shown}
|
|
117
|
+
</svelte:element>
|
|
118
|
+
{#if onClear}
|
|
119
|
+
<Button variant="ghost" size="sm" onclick={() => clear(onClear)} {disabled}>
|
|
120
|
+
{t.geometryClear}
|
|
121
|
+
</Button>
|
|
122
|
+
{/if}
|
|
123
|
+
{:else if !onPick}
|
|
124
|
+
<output id={inputId} class="text-sm min-w-0 text-muted-foreground"
|
|
125
|
+
>{t.geometryPickInPanel}</output
|
|
126
|
+
>
|
|
127
|
+
{/if}
|
|
128
|
+
</div>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { GeometryPickResult, PickKind } from '../../../contexts/hostContext.svelte';
|
|
2
|
+
interface Props {
|
|
3
|
+
inputId: string;
|
|
4
|
+
/** The kinds of object the input takes; one kind names the button after it. */
|
|
5
|
+
kinds?: readonly PickKind[];
|
|
6
|
+
/** 1 picks a single object. */
|
|
7
|
+
atMost?: number;
|
|
8
|
+
/** What the host reports the param holds, such as "2 curves"; absent until something is picked. */
|
|
9
|
+
summary?: string;
|
|
10
|
+
/** Absent where this page may not pick, such as a browser tab beside the Rhino panel. */
|
|
11
|
+
onPick?: () => Promise<GeometryPickResult>;
|
|
12
|
+
onClear?: () => void;
|
|
13
|
+
/** Subscribes to what the host holds after any page picks or clears; returns an unsubscribe. */
|
|
14
|
+
watchSummary?: (listener: (summary: string | null) => void) => () => void;
|
|
15
|
+
/** Shown when the pick fails; the host's own message. */
|
|
16
|
+
onError?: (message: string) => void;
|
|
17
|
+
disabled?: boolean;
|
|
18
|
+
}
|
|
19
|
+
declare const GeometryInput: import("svelte").Component<Props, {}, "">;
|
|
20
|
+
type GeometryInput = ReturnType<typeof GeometryInput>;
|
|
21
|
+
export default GeometryInput;
|