@selvajs/ui 6.5.1-beta.0 → 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 +15 -15
- 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 '$lib/components/primitives/sonner';
|
|
6
6
|
import { FileUp, Link, CircleAlert, CircleCheck } from '@lucide/svelte';
|
|
7
7
|
import { APP_DEFAULTS } from '$lib/constants';
|
|
8
|
+
import { getLocaleContext } from '$lib/i18n/localeContext.svelte';
|
|
9
|
+
import { formatMessage } from '$lib/i18n/messages';
|
|
10
|
+
import { pickFile } from '$lib/utils/host-files';
|
|
11
|
+
import { acceptsFileEnding, isWebp, shouldConvertWebp, webpToPng } from '$lib/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 '$lib/components/primitives/button';
|
|
3
|
+
import type { GeometryPickResult, PickKind } from '$lib/contexts/hostContext.svelte';
|
|
4
|
+
import { getLocaleContext } from '$lib/i18n/localeContext.svelte';
|
|
5
|
+
import type { ViewerMessages } from '$lib/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>
|