@softov/scena 0.1.2
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/LICENSE +21 -0
- package/README.md +42 -0
- package/dist/controls/command.d.ts +18 -0
- package/dist/controls/command.js +150 -0
- package/dist/controls/events.d.ts +3 -0
- package/dist/controls/events.js +43 -0
- package/dist/controls/index.d.ts +10 -0
- package/dist/controls/index.js +10 -0
- package/dist/controls/keybinding.d.ts +9 -0
- package/dist/controls/keybinding.js +94 -0
- package/dist/controls/layout.d.ts +16 -0
- package/dist/controls/layout.js +201 -0
- package/dist/controls/manifest.d.ts +21 -0
- package/dist/controls/manifest.js +219 -0
- package/dist/controls/session.d.ts +16 -0
- package/dist/controls/session.js +95 -0
- package/dist/controls/shell.d.ts +8 -0
- package/dist/controls/shell.js +48 -0
- package/dist/controls/storage/layout-local.d.ts +6 -0
- package/dist/controls/storage/layout-local.js +47 -0
- package/dist/controls/storage/session-local.d.ts +5 -0
- package/dist/controls/storage/session-local.js +38 -0
- package/dist/controls/when.d.ts +7 -0
- package/dist/controls/when.js +226 -0
- package/dist/converters/a2ui-v0.10.d.ts +23 -0
- package/dist/converters/a2ui-v0.10.js +136 -0
- package/dist/converters/index.d.ts +1 -0
- package/dist/converters/index.js +1 -0
- package/dist/core/backends/modus-backend.d.ts +13 -0
- package/dist/core/backends/modus-backend.js +115 -0
- package/dist/core/backends/storage-backend.d.ts +7 -0
- package/dist/core/backends/storage-backend.js +73 -0
- package/dist/core/backends/yjs-backend.d.ts +3 -0
- package/dist/core/backends/yjs-backend.js +44 -0
- package/dist/core/binding-resolver.d.ts +7 -0
- package/dist/core/binding-resolver.js +106 -0
- package/dist/core/component-graph.d.ts +6 -0
- package/dist/core/component-graph.js +77 -0
- package/dist/core/component-registry.d.ts +7 -0
- package/dist/core/component-registry.js +87 -0
- package/dist/core/computed-dsl.d.ts +2 -0
- package/dist/core/computed-dsl.js +267 -0
- package/dist/core/converter-registry.d.ts +2 -0
- package/dist/core/converter-registry.js +37 -0
- package/dist/core/disposable.d.ts +3 -0
- package/dist/core/disposable.js +19 -0
- package/dist/core/dynamic-resolver.d.ts +12 -0
- package/dist/core/dynamic-resolver.js +134 -0
- package/dist/core/index.d.ts +44 -0
- package/dist/core/index.js +48 -0
- package/dist/core/label.d.ts +2 -0
- package/dist/core/label.js +14 -0
- package/dist/core/mount-menu.d.ts +2 -0
- package/dist/core/mount-menu.js +23 -0
- package/dist/core/mount-surface.d.ts +15 -0
- package/dist/core/mount-surface.js +214 -0
- package/dist/core/path-resolver.d.ts +14 -0
- package/dist/core/path-resolver.js +169 -0
- package/dist/core/permissions.d.ts +2 -0
- package/dist/core/permissions.js +50 -0
- package/dist/core/reactive-store.d.ts +17 -0
- package/dist/core/reactive-store.js +496 -0
- package/dist/core/scena.d.ts +2 -0
- package/dist/core/scena.js +115 -0
- package/dist/core/surface-presentation.d.ts +6 -0
- package/dist/core/surface-presentation.js +12 -0
- package/dist/i18n/i18n-backend.d.ts +2 -0
- package/dist/i18n/i18n-backend.js +35 -0
- package/dist/i18n/registry.d.ts +32 -0
- package/dist/i18n/registry.js +200 -0
- package/dist/porta/Limen.css +50 -0
- package/dist/porta/Limen.d.ts +16 -0
- package/dist/porta/Limen.js +14 -0
- package/dist/porta/PortaContext.d.ts +10 -0
- package/dist/porta/PortaContext.js +20 -0
- package/dist/porta/PortaLock.css +14 -0
- package/dist/porta/PortaLock.d.ts +10 -0
- package/dist/porta/PortaLock.js +13 -0
- package/dist/porta/SigillumGate.d.ts +8 -0
- package/dist/porta/SigillumGate.js +7 -0
- package/dist/porta/commands.d.ts +3 -0
- package/dist/porta/commands.js +125 -0
- package/dist/porta/index.d.ts +18 -0
- package/dist/porta/index.js +22 -0
- package/dist/porta/login-form.block.d.ts +2 -0
- package/dist/porta/login-form.block.js +7 -0
- package/dist/porta/match.d.ts +2 -0
- package/dist/porta/match.js +20 -0
- package/dist/porta/provider.d.ts +59 -0
- package/dist/porta/provider.js +1 -0
- package/dist/porta/providers/examples/google-oauth.d.ts +6 -0
- package/dist/porta/providers/examples/google-oauth.js +21 -0
- package/dist/porta/providers/examples/index.d.ts +6 -0
- package/dist/porta/providers/examples/index.js +3 -0
- package/dist/porta/providers/examples/magic-link.d.ts +8 -0
- package/dist/porta/providers/examples/magic-link.js +31 -0
- package/dist/porta/providers/examples/sms-otp.d.ts +9 -0
- package/dist/porta/providers/examples/sms-otp.js +31 -0
- package/dist/porta/providers/password.d.ts +12 -0
- package/dist/porta/providers/password.js +46 -0
- package/dist/porta/register-blocks.d.ts +3 -0
- package/dist/porta/register-blocks.js +31 -0
- package/dist/porta/register.d.ts +15 -0
- package/dist/porta/register.js +31 -0
- package/dist/porta/sigillum.d.ts +19 -0
- package/dist/porta/sigillum.js +41 -0
- package/dist/react/DefaultShell.d.ts +1 -0
- package/dist/react/DefaultShell.js +37 -0
- package/dist/react/Scena.d.ts +9 -0
- package/dist/react/Scena.js +20 -0
- package/dist/react/ScenaProvider.d.ts +8 -0
- package/dist/react/ScenaProvider.js +13 -0
- package/dist/react/ShellSplitter.d.ts +13 -0
- package/dist/react/ShellSplitter.js +88 -0
- package/dist/react/SurfaceArea.d.ts +13 -0
- package/dist/react/SurfaceArea.js +75 -0
- package/dist/react/Translate.d.ts +8 -0
- package/dist/react/Translate.js +10 -0
- package/dist/react/ViewMount.d.ts +12 -0
- package/dist/react/ViewMount.js +268 -0
- package/dist/react/core.d.ts +6 -0
- package/dist/react/core.js +10 -0
- package/dist/react/hooks/useCommand.d.ts +1 -0
- package/dist/react/hooks/useCommand.js +6 -0
- package/dist/react/hooks/useI18n.d.ts +9 -0
- package/dist/react/hooks/useI18n.js +16 -0
- package/dist/react/hooks/useLabel.d.ts +2 -0
- package/dist/react/hooks/useLabel.js +19 -0
- package/dist/react/hooks/useLayout.d.ts +2 -0
- package/dist/react/hooks/useLayout.js +10 -0
- package/dist/react/hooks/useMounts.d.ts +2 -0
- package/dist/react/hooks/useMounts.js +17 -0
- package/dist/react/hooks/useStore.d.ts +3 -0
- package/dist/react/hooks/useStore.js +40 -0
- package/dist/react/hooks/useStoreLabel.d.ts +3 -0
- package/dist/react/hooks/useStoreLabel.js +25 -0
- package/dist/react/hooks/useSurfacePresentation.d.ts +4 -0
- package/dist/react/hooks/useSurfacePresentation.js +16 -0
- package/dist/react/index.d.ts +20 -0
- package/dist/react/index.js +20 -0
- package/dist/react/mount-context.d.ts +8 -0
- package/dist/react/mount-context.js +20 -0
- package/dist/react/useSurfaceResize.d.ts +39 -0
- package/dist/react/useSurfaceResize.js +135 -0
- package/dist/runtime/args-schema.d.ts +11 -0
- package/dist/runtime/args-schema.js +45 -0
- package/dist/runtime/builtins.d.ts +3 -0
- package/dist/runtime/builtins.js +193 -0
- package/dist/runtime/client-handlers.d.ts +3 -0
- package/dist/runtime/client-handlers.js +19 -0
- package/dist/runtime/in-memory-socket.d.ts +7 -0
- package/dist/runtime/in-memory-socket.js +53 -0
- package/dist/runtime/index.d.ts +10 -0
- package/dist/runtime/index.js +7 -0
- package/dist/runtime/layout-commands.d.ts +5 -0
- package/dist/runtime/layout-commands.js +548 -0
- package/dist/runtime/opener-commands.d.ts +17 -0
- package/dist/runtime/opener-commands.js +96 -0
- package/dist/runtime/surface-bridge.d.ts +15 -0
- package/dist/runtime/surface-bridge.js +116 -0
- package/dist/styles/bar.css +155 -0
- package/dist/styles/base.css +285 -0
- package/dist/styles/geometry.css +32 -0
- package/dist/styles/index.d.ts +29 -0
- package/dist/styles/index.js +109 -0
- package/dist/styles/scrollbar.css +45 -0
- package/dist/styles/surface.css +179 -0
- package/dist/styles/theme.css +3 -0
- package/dist/styles/themes/dark.css +30 -0
- package/dist/styles/themes/light.css +1 -0
- package/dist/styles/themes/tokens.css +222 -0
- package/dist/types/binding-resolver.d.ts +30 -0
- package/dist/types/binding-resolver.js +1 -0
- package/dist/types/colors.d.ts +7 -0
- package/dist/types/colors.js +59 -0
- package/dist/types/command.d.ts +62 -0
- package/dist/types/command.js +1 -0
- package/dist/types/component-graph.d.ts +72 -0
- package/dist/types/component-graph.js +40 -0
- package/dist/types/component-registry.d.ts +70 -0
- package/dist/types/component-registry.js +1 -0
- package/dist/types/converter-registry.d.ts +17 -0
- package/dist/types/converter-registry.js +1 -0
- package/dist/types/disposable.d.ts +3 -0
- package/dist/types/disposable.js +1 -0
- package/dist/types/events.d.ts +75 -0
- package/dist/types/events.js +1 -0
- package/dist/types/host.d.ts +50 -0
- package/dist/types/host.js +1 -0
- package/dist/types/index.d.ts +23 -0
- package/dist/types/index.js +23 -0
- package/dist/types/keybinding.d.ts +36 -0
- package/dist/types/keybinding.js +1 -0
- package/dist/types/label.d.ts +9 -0
- package/dist/types/label.js +1 -0
- package/dist/types/layout.d.ts +117 -0
- package/dist/types/layout.js +1 -0
- package/dist/types/manifest.d.ts +152 -0
- package/dist/types/manifest.js +1 -0
- package/dist/types/mount-menu.d.ts +8 -0
- package/dist/types/mount-menu.js +1 -0
- package/dist/types/mount-surface.d.ts +87 -0
- package/dist/types/mount-surface.js +1 -0
- package/dist/types/permissions.d.ts +18 -0
- package/dist/types/permissions.js +1 -0
- package/dist/types/query.d.ts +34 -0
- package/dist/types/query.js +7 -0
- package/dist/types/reactive-store.d.ts +39 -0
- package/dist/types/reactive-store.js +1 -0
- package/dist/types/scena.d.ts +53 -0
- package/dist/types/scena.js +1 -0
- package/dist/types/scope-backend.d.ts +16 -0
- package/dist/types/scope-backend.js +1 -0
- package/dist/types/session.d.ts +39 -0
- package/dist/types/session.js +1 -0
- package/dist/types/shell.d.ts +21 -0
- package/dist/types/shell.js +1 -0
- package/dist/types/when.d.ts +10 -0
- package/dist/types/when.js +1 -0
- package/dist/ui/_utils.d.ts +8 -0
- package/dist/ui/_utils.js +53 -0
- package/dist/ui/campus/CampusMappa.d.ts +18 -0
- package/dist/ui/campus/CampusMappa.js +106 -0
- package/dist/ui/campus/CampusNodus.d.ts +25 -0
- package/dist/ui/campus/CampusNodus.js +211 -0
- package/dist/ui/campus/CampusStratum.d.ts +13 -0
- package/dist/ui/campus/CampusStratum.js +20 -0
- package/dist/ui/campus/CampusVelum.d.ts +7 -0
- package/dist/ui/campus/CampusVelum.js +12 -0
- package/dist/ui/campus/CampusView.d.ts +27 -0
- package/dist/ui/campus/CampusView.js +420 -0
- package/dist/ui/campus/context.d.ts +13 -0
- package/dist/ui/campus/context.js +12 -0
- package/dist/ui/campus/index.d.ts +14 -0
- package/dist/ui/campus/index.js +11 -0
- package/dist/ui/campus/stratum-context.d.ts +2 -0
- package/dist/ui/campus/stratum-context.js +10 -0
- package/dist/ui/campus/types.d.ts +47 -0
- package/dist/ui/campus/types.js +4 -0
- package/dist/ui/chart/BarChart.css +53 -0
- package/dist/ui/chart/BarChart.d.ts +24 -0
- package/dist/ui/chart/BarChart.js +32 -0
- package/dist/ui/chart/Donut.css +15 -0
- package/dist/ui/chart/Donut.d.ts +15 -0
- package/dist/ui/chart/Donut.js +18 -0
- package/dist/ui/chart/LineChart.css +8 -0
- package/dist/ui/chart/LineChart.d.ts +24 -0
- package/dist/ui/chart/LineChart.js +29 -0
- package/dist/ui/chart/catalog.d.ts +2 -0
- package/dist/ui/chart/catalog.js +7 -0
- package/dist/ui/chart/index.d.ts +6 -0
- package/dist/ui/chart/index.js +4 -0
- package/dist/ui/control/Button.css +7 -0
- package/dist/ui/control/Button.d.ts +17 -0
- package/dist/ui/control/Button.js +17 -0
- package/dist/ui/control/CheckBox.css +16 -0
- package/dist/ui/control/CheckBox.d.ts +15 -0
- package/dist/ui/control/CheckBox.js +23 -0
- package/dist/ui/control/Checks.css +6 -0
- package/dist/ui/control/Checks.d.ts +9 -0
- package/dist/ui/control/Checks.js +10 -0
- package/dist/ui/control/ChoicePicker.css +16 -0
- package/dist/ui/control/ChoicePicker.d.ts +25 -0
- package/dist/ui/control/ChoicePicker.js +38 -0
- package/dist/ui/control/DateTimeInput.css +1 -0
- package/dist/ui/control/DateTimeInput.d.ts +22 -0
- package/dist/ui/control/DateTimeInput.js +41 -0
- package/dist/ui/control/LocaleToggle.css +38 -0
- package/dist/ui/control/LocaleToggle.d.ts +11 -0
- package/dist/ui/control/LocaleToggle.js +23 -0
- package/dist/ui/control/ReloadButton.d.ts +6 -0
- package/dist/ui/control/ReloadButton.js +9 -0
- package/dist/ui/control/Slider.css +2 -0
- package/dist/ui/control/Slider.d.ts +21 -0
- package/dist/ui/control/Slider.js +37 -0
- package/dist/ui/control/TextField.css +0 -0
- package/dist/ui/control/TextField.d.ts +25 -0
- package/dist/ui/control/TextField.js +36 -0
- package/dist/ui/control/_field-parts.css +102 -0
- package/dist/ui/control/_field-parts.d.ts +15 -0
- package/dist/ui/control/_field-parts.js +17 -0
- package/dist/ui/control/catalog.d.ts +2 -0
- package/dist/ui/control/catalog.js +10 -0
- package/dist/ui/control/index.d.ts +13 -0
- package/dist/ui/control/index.js +11 -0
- package/dist/ui/data/DataTable.d.ts +19 -0
- package/dist/ui/data/DataTable.js +20 -0
- package/dist/ui/data/Filter.d.ts +13 -0
- package/dist/ui/data/Filter.js +56 -0
- package/dist/ui/data/List.css +16 -0
- package/dist/ui/data/List.d.ts +15 -0
- package/dist/ui/data/List.js +18 -0
- package/dist/ui/data/Listable.css +245 -0
- package/dist/ui/data/Listable.d.ts +60 -0
- package/dist/ui/data/Listable.js +209 -0
- package/dist/ui/data/Pagination.d.ts +5 -0
- package/dist/ui/data/Pagination.js +43 -0
- package/dist/ui/data/Tree.css +118 -0
- package/dist/ui/data/Tree.d.ts +45 -0
- package/dist/ui/data/Tree.js +170 -0
- package/dist/ui/data/catalog.d.ts +2 -0
- package/dist/ui/data/catalog.js +7 -0
- package/dist/ui/data/index.d.ts +11 -0
- package/dist/ui/data/index.js +7 -0
- package/dist/ui/display/AddPlaceholder.d.ts +6 -0
- package/dist/ui/display/AddPlaceholder.js +24 -0
- package/dist/ui/display/Alert.css +42 -0
- package/dist/ui/display/Alert.d.ts +14 -0
- package/dist/ui/display/Alert.js +13 -0
- package/dist/ui/display/Avatar.css +19 -0
- package/dist/ui/display/Avatar.d.ts +16 -0
- package/dist/ui/display/Avatar.js +52 -0
- package/dist/ui/display/Badge.css +26 -0
- package/dist/ui/display/Badge.d.ts +16 -0
- package/dist/ui/display/Badge.js +9 -0
- package/dist/ui/display/Card.css +15 -0
- package/dist/ui/display/Card.d.ts +11 -0
- package/dist/ui/display/Card.js +8 -0
- package/dist/ui/display/DetailContainer.d.ts +6 -0
- package/dist/ui/display/DetailContainer.js +7 -0
- package/dist/ui/display/DetailHeader.css +53 -0
- package/dist/ui/display/DetailHeader.d.ts +22 -0
- package/dist/ui/display/DetailHeader.js +8 -0
- package/dist/ui/display/DetailList.css +26 -0
- package/dist/ui/display/DetailList.d.ts +13 -0
- package/dist/ui/display/DetailList.js +5 -0
- package/dist/ui/display/DetailNotFound.d.ts +17 -0
- package/dist/ui/display/DetailNotFound.js +39 -0
- package/dist/ui/display/Divider.css +6 -0
- package/dist/ui/display/Divider.d.ts +8 -0
- package/dist/ui/display/Divider.js +16 -0
- package/dist/ui/display/Divisor.css +30 -0
- package/dist/ui/display/Divisor.d.ts +11 -0
- package/dist/ui/display/Divisor.js +43 -0
- package/dist/ui/display/Icon.css +10 -0
- package/dist/ui/display/Icon.d.ts +14 -0
- package/dist/ui/display/Icon.js +144 -0
- package/dist/ui/display/Image.css +1 -0
- package/dist/ui/display/Image.d.ts +16 -0
- package/dist/ui/display/Image.js +19 -0
- package/dist/ui/display/Markdown.css +38 -0
- package/dist/ui/display/Markdown.d.ts +8 -0
- package/dist/ui/display/Markdown.js +140 -0
- package/dist/ui/display/Progress.css +39 -0
- package/dist/ui/display/Progress.d.ts +15 -0
- package/dist/ui/display/Progress.js +17 -0
- package/dist/ui/display/SectionTitle.d.ts +6 -0
- package/dist/ui/display/SectionTitle.js +6 -0
- package/dist/ui/display/Skeleton.css +20 -0
- package/dist/ui/display/Skeleton.d.ts +11 -0
- package/dist/ui/display/Skeleton.js +11 -0
- package/dist/ui/display/Spinner.css +20 -0
- package/dist/ui/display/Spinner.d.ts +12 -0
- package/dist/ui/display/Spinner.js +12 -0
- package/dist/ui/display/Svg.d.ts +13 -0
- package/dist/ui/display/Svg.js +17 -0
- package/dist/ui/display/Text.css +20 -0
- package/dist/ui/display/Text.d.ts +13 -0
- package/dist/ui/display/Text.js +15 -0
- package/dist/ui/display/catalog.d.ts +2 -0
- package/dist/ui/display/catalog.js +12 -0
- package/dist/ui/display/index.d.ts +22 -0
- package/dist/ui/display/index.js +14 -0
- package/dist/ui/embed/HtmlEmbed.d.ts +12 -0
- package/dist/ui/embed/HtmlEmbed.js +16 -0
- package/dist/ui/embed/index.d.ts +2 -0
- package/dist/ui/embed/index.js +1 -0
- package/dist/ui/forms/DangerZone.d.ts +8 -0
- package/dist/ui/forms/DangerZone.js +31 -0
- package/dist/ui/forms/Field.css +15 -0
- package/dist/ui/forms/Field.d.ts +28 -0
- package/dist/ui/forms/Field.js +25 -0
- package/dist/ui/forms/FieldGroup.css +15 -0
- package/dist/ui/forms/FieldGroup.d.ts +7 -0
- package/dist/ui/forms/FieldGroup.js +7 -0
- package/dist/ui/forms/Form.css +14 -0
- package/dist/ui/forms/Form.d.ts +18 -0
- package/dist/ui/forms/Form.js +17 -0
- package/dist/ui/forms/FormActions.css +11 -0
- package/dist/ui/forms/FormActions.d.ts +18 -0
- package/dist/ui/forms/FormActions.js +10 -0
- package/dist/ui/forms/FormSection.css +19 -0
- package/dist/ui/forms/FormSection.d.ts +7 -0
- package/dist/ui/forms/FormSection.js +7 -0
- package/dist/ui/forms/LoginForm.css +105 -0
- package/dist/ui/forms/LoginForm.d.ts +12 -0
- package/dist/ui/forms/LoginForm.js +137 -0
- package/dist/ui/forms/SchemaForm.css +81 -0
- package/dist/ui/forms/SchemaForm.d.ts +26 -0
- package/dist/ui/forms/SchemaForm.js +186 -0
- package/dist/ui/forms/SettingsContainer.d.ts +8 -0
- package/dist/ui/forms/SettingsContainer.js +8 -0
- package/dist/ui/forms/catalog.d.ts +2 -0
- package/dist/ui/forms/catalog.js +11 -0
- package/dist/ui/forms/index.d.ts +19 -0
- package/dist/ui/forms/index.js +12 -0
- package/dist/ui/forms/schema-walk.d.ts +50 -0
- package/dist/ui/forms/schema-walk.js +116 -0
- package/dist/ui/index.d.ts +58 -0
- package/dist/ui/index.js +63 -0
- package/dist/ui/layout/BarLayout.d.ts +2 -0
- package/dist/ui/layout/BarLayout.js +18 -0
- package/dist/ui/layout/Column.css +6 -0
- package/dist/ui/layout/Column.d.ts +12 -0
- package/dist/ui/layout/Column.js +13 -0
- package/dist/ui/layout/FloatingLayout.d.ts +2 -0
- package/dist/ui/layout/FloatingLayout.js +12 -0
- package/dist/ui/layout/Grid.css +5 -0
- package/dist/ui/layout/Grid.d.ts +13 -0
- package/dist/ui/layout/Grid.js +19 -0
- package/dist/ui/layout/InlineLayout.d.ts +2 -0
- package/dist/ui/layout/InlineLayout.js +13 -0
- package/dist/ui/layout/MountTitle.d.ts +12 -0
- package/dist/ui/layout/MountTitle.js +42 -0
- package/dist/ui/layout/RailLayout.d.ts +2 -0
- package/dist/ui/layout/RailLayout.js +38 -0
- package/dist/ui/layout/Row.css +16 -0
- package/dist/ui/layout/Row.d.ts +13 -0
- package/dist/ui/layout/Row.js +21 -0
- package/dist/ui/layout/SectionHeader.d.ts +10 -0
- package/dist/ui/layout/SectionHeader.js +65 -0
- package/dist/ui/layout/SingleLayout.d.ts +2 -0
- package/dist/ui/layout/SingleLayout.js +25 -0
- package/dist/ui/layout/SpatialCard.d.ts +9 -0
- package/dist/ui/layout/SpatialCard.js +30 -0
- package/dist/ui/layout/SpatialLayout.d.ts +2 -0
- package/dist/ui/layout/SpatialLayout.js +446 -0
- package/dist/ui/layout/SplitLayout.d.ts +2 -0
- package/dist/ui/layout/SplitLayout.js +159 -0
- package/dist/ui/layout/Splitter.d.ts +12 -0
- package/dist/ui/layout/Splitter.js +64 -0
- package/dist/ui/layout/StackHeader.d.ts +9 -0
- package/dist/ui/layout/StackHeader.js +87 -0
- package/dist/ui/layout/StackLayout.d.ts +2 -0
- package/dist/ui/layout/StackLayout.js +137 -0
- package/dist/ui/layout/TabLayout.d.ts +2 -0
- package/dist/ui/layout/TabLayout.js +145 -0
- package/dist/ui/layout/TabPanelLayout.d.ts +20 -0
- package/dist/ui/layout/TabPanelLayout.js +615 -0
- package/dist/ui/layout/catalog.d.ts +2 -0
- package/dist/ui/layout/catalog.js +10 -0
- package/dist/ui/layout/index.d.ts +17 -0
- package/dist/ui/layout/index.js +17 -0
- package/dist/ui/layout/register.d.ts +3 -0
- package/dist/ui/layout/register.js +25 -0
- package/dist/ui/media/Audio.css +1 -0
- package/dist/ui/media/Audio.d.ts +12 -0
- package/dist/ui/media/Audio.js +8 -0
- package/dist/ui/media/Video.css +1 -0
- package/dist/ui/media/Video.d.ts +16 -0
- package/dist/ui/media/Video.js +9 -0
- package/dist/ui/media/catalog.d.ts +2 -0
- package/dist/ui/media/catalog.js +5 -0
- package/dist/ui/media/index.d.ts +2 -0
- package/dist/ui/media/index.js +3 -0
- package/dist/ui/menu/ActionList.css +262 -0
- package/dist/ui/menu/ActionList.d.ts +19 -0
- package/dist/ui/menu/ActionList.js +369 -0
- package/dist/ui/menu/ContainerMenu.d.ts +13 -0
- package/dist/ui/menu/ContainerMenu.js +57 -0
- package/dist/ui/menu/ContextMenu.d.ts +27 -0
- package/dist/ui/menu/ContextMenu.js +93 -0
- package/dist/ui/menu/index.d.ts +10 -0
- package/dist/ui/menu/index.js +7 -0
- package/dist/ui/menu/token.d.ts +22 -0
- package/dist/ui/menu/token.js +145 -0
- package/dist/ui/menu/useChatPicker.d.ts +24 -0
- package/dist/ui/menu/useChatPicker.js +210 -0
- package/dist/ui/navigation/Breadcrumb.css +30 -0
- package/dist/ui/navigation/Breadcrumb.d.ts +14 -0
- package/dist/ui/navigation/Breadcrumb.js +12 -0
- package/dist/ui/navigation/Link.css +13 -0
- package/dist/ui/navigation/Link.d.ts +18 -0
- package/dist/ui/navigation/Link.js +43 -0
- package/dist/ui/navigation/Tabs.css +39 -0
- package/dist/ui/navigation/Tabs.d.ts +18 -0
- package/dist/ui/navigation/Tabs.js +55 -0
- package/dist/ui/navigation/Toolbar.css +25 -0
- package/dist/ui/navigation/Toolbar.d.ts +12 -0
- package/dist/ui/navigation/Toolbar.js +21 -0
- package/dist/ui/navigation/catalog.d.ts +2 -0
- package/dist/ui/navigation/catalog.js +5 -0
- package/dist/ui/navigation/index.d.ts +8 -0
- package/dist/ui/navigation/index.js +5 -0
- package/dist/ui/overlay/Modal.css +35 -0
- package/dist/ui/overlay/Modal.d.ts +12 -0
- package/dist/ui/overlay/Modal.js +57 -0
- package/dist/ui/overlay/Popup.d.ts +12 -0
- package/dist/ui/overlay/Popup.js +74 -0
- package/dist/ui/overlay/catalog.d.ts +2 -0
- package/dist/ui/overlay/catalog.js +4 -0
- package/dist/ui/overlay/index.d.ts +1 -0
- package/dist/ui/overlay/index.js +2 -0
- package/dist/ui/register.d.ts +6 -0
- package/dist/ui/register.js +26 -0
- package/package.json +115 -0
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import type { DataBinding } from '../types/component-graph.js';
|
|
3
|
+
export type ProviderLabel = string | DataBinding;
|
|
4
|
+
export type PortaProviderKind = 'oauth-button' | 'form-fields' | 'otp' | 'magic-link';
|
|
5
|
+
export interface AuthField {
|
|
6
|
+
name: string;
|
|
7
|
+
label: ProviderLabel | {
|
|
8
|
+
t: string;
|
|
9
|
+
args?: Record<string, unknown>;
|
|
10
|
+
};
|
|
11
|
+
type: 'text' | 'email' | 'password' | 'tel';
|
|
12
|
+
required?: boolean;
|
|
13
|
+
placeholder?: string;
|
|
14
|
+
autoComplete?: string;
|
|
15
|
+
}
|
|
16
|
+
export interface Session {
|
|
17
|
+
userId: string;
|
|
18
|
+
displayName?: string;
|
|
19
|
+
email?: string;
|
|
20
|
+
expiresAt?: number;
|
|
21
|
+
permissions?: string[];
|
|
22
|
+
raw?: Record<string, unknown>;
|
|
23
|
+
}
|
|
24
|
+
export interface ProviderRenderContext {
|
|
25
|
+
pending: boolean;
|
|
26
|
+
error: string | null;
|
|
27
|
+
challenge: {
|
|
28
|
+
providerId: string;
|
|
29
|
+
id: string;
|
|
30
|
+
} | null;
|
|
31
|
+
fieldState: Record<string, string>;
|
|
32
|
+
setField(name: string, value: string): void;
|
|
33
|
+
signin(creds: Record<string, unknown>): Promise<void>;
|
|
34
|
+
request(value: string): Promise<void>;
|
|
35
|
+
verify(code: string): Promise<void>;
|
|
36
|
+
}
|
|
37
|
+
export interface PortaProvider {
|
|
38
|
+
id: string;
|
|
39
|
+
label: ProviderLabel;
|
|
40
|
+
icon?: string;
|
|
41
|
+
kind: PortaProviderKind;
|
|
42
|
+
fields?: AuthField[];
|
|
43
|
+
otp?: {
|
|
44
|
+
digits: number;
|
|
45
|
+
channel: 'sms' | 'email' | 'totp';
|
|
46
|
+
sendLabel?: string;
|
|
47
|
+
};
|
|
48
|
+
magicLink?: {
|
|
49
|
+
channel: 'email' | 'sms';
|
|
50
|
+
sendLabel?: string;
|
|
51
|
+
};
|
|
52
|
+
render?(ctx: ProviderRenderContext): ReactNode;
|
|
53
|
+
signin?(creds: Record<string, unknown>): Promise<Session>;
|
|
54
|
+
request?(value: string): Promise<{
|
|
55
|
+
challengeId: string;
|
|
56
|
+
}>;
|
|
57
|
+
verify?(challengeId: string, code: string): Promise<Session>;
|
|
58
|
+
signout?(session: Session): Promise<void>;
|
|
59
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export function googleOAuthProvider(opts) {
|
|
2
|
+
return {
|
|
3
|
+
id: 'google',
|
|
4
|
+
label: 'Google',
|
|
5
|
+
icon: '🌐',
|
|
6
|
+
kind: 'oauth-button',
|
|
7
|
+
async signin() {
|
|
8
|
+
if (opts.signin)
|
|
9
|
+
return opts.signin();
|
|
10
|
+
// Demo stub
|
|
11
|
+
await new Promise((r) => setTimeout(r, 300));
|
|
12
|
+
return {
|
|
13
|
+
userId: 'demo-google-user',
|
|
14
|
+
displayName: 'Demo User (Google)',
|
|
15
|
+
email: 'demo@google.example',
|
|
16
|
+
permissions: ['session.read'],
|
|
17
|
+
raw: { provider: 'google', clientId: opts.clientId, demo: true },
|
|
18
|
+
};
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { googleOAuthProvider } from './google-oauth.js';
|
|
2
|
+
export type { GoogleOAuthOpts } from './google-oauth.js';
|
|
3
|
+
export { magicLinkProvider } from './magic-link.js';
|
|
4
|
+
export type { MagicLinkOpts } from './magic-link.js';
|
|
5
|
+
export { smsOtpProvider } from './sms-otp.js';
|
|
6
|
+
export type { SmsOtpOpts } from './sms-otp.js';
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { PortaProvider, Session } from '../../provider.js';
|
|
2
|
+
export interface MagicLinkOpts {
|
|
3
|
+
label?: string;
|
|
4
|
+
sendLabel?: string;
|
|
5
|
+
sendLink?: (email: string) => Promise<string>;
|
|
6
|
+
verify?: (challengeId: string, token: string) => Promise<Session>;
|
|
7
|
+
}
|
|
8
|
+
export declare function magicLinkProvider(opts?: MagicLinkOpts): PortaProvider;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export function magicLinkProvider(opts = {}) {
|
|
2
|
+
return {
|
|
3
|
+
id: 'magic-link',
|
|
4
|
+
label: opts.label ?? 'Email a sign-in link',
|
|
5
|
+
icon: '✉',
|
|
6
|
+
kind: 'magic-link',
|
|
7
|
+
magicLink: {
|
|
8
|
+
channel: 'email',
|
|
9
|
+
sendLabel: opts.sendLabel,
|
|
10
|
+
},
|
|
11
|
+
async request(email) {
|
|
12
|
+
if (opts.sendLink)
|
|
13
|
+
return { challengeId: await opts.sendLink(email) };
|
|
14
|
+
// Demo stub — just echoes a synthetic id
|
|
15
|
+
const id = `magic_${Date.now().toString(36)}`;
|
|
16
|
+
console.info(`[magicLinkProvider] (stub) would email ${email} — challengeId=${id}`);
|
|
17
|
+
return { challengeId: id };
|
|
18
|
+
},
|
|
19
|
+
async verify(challengeId, token) {
|
|
20
|
+
if (opts.verify)
|
|
21
|
+
return opts.verify(challengeId, token);
|
|
22
|
+
await new Promise((r) => setTimeout(r, 200));
|
|
23
|
+
return {
|
|
24
|
+
userId: 'demo-magic-user',
|
|
25
|
+
displayName: 'Demo User (Magic link)',
|
|
26
|
+
permissions: ['session.read'],
|
|
27
|
+
raw: { provider: 'magic-link', challengeId, token, demo: true },
|
|
28
|
+
};
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { PortaProvider, Session } from '../../provider.js';
|
|
2
|
+
export interface SmsOtpOpts {
|
|
3
|
+
digits?: number;
|
|
4
|
+
label?: string;
|
|
5
|
+
sendLabel?: string;
|
|
6
|
+
sendCode?: (phone: string) => Promise<string>;
|
|
7
|
+
verify?: (challengeId: string, code: string) => Promise<Session>;
|
|
8
|
+
}
|
|
9
|
+
export declare function smsOtpProvider(opts?: SmsOtpOpts): PortaProvider;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export function smsOtpProvider(opts = {}) {
|
|
2
|
+
const digits = opts.digits ?? 6;
|
|
3
|
+
return {
|
|
4
|
+
id: 'sms-otp',
|
|
5
|
+
label: opts.label ?? 'Sign in with SMS',
|
|
6
|
+
icon: '📱',
|
|
7
|
+
kind: 'otp',
|
|
8
|
+
otp: { digits, channel: 'sms', sendLabel: opts.sendLabel },
|
|
9
|
+
async request(phone) {
|
|
10
|
+
if (opts.sendCode)
|
|
11
|
+
return { challengeId: await opts.sendCode(phone) };
|
|
12
|
+
const id = `sms_${Date.now().toString(36)}`;
|
|
13
|
+
console.info(`[smsOtpProvider] (stub) would SMS ${phone} a ${digits}-digit code — challengeId=${id}`);
|
|
14
|
+
return { challengeId: id };
|
|
15
|
+
},
|
|
16
|
+
async verify(challengeId, code) {
|
|
17
|
+
if (opts.verify)
|
|
18
|
+
return opts.verify(challengeId, code);
|
|
19
|
+
await new Promise((r) => setTimeout(r, 200));
|
|
20
|
+
if (code.length !== digits) {
|
|
21
|
+
throw new Error(`Expected a ${digits}-digit code`);
|
|
22
|
+
}
|
|
23
|
+
return {
|
|
24
|
+
userId: 'demo-sms-user',
|
|
25
|
+
displayName: 'Demo User (SMS)',
|
|
26
|
+
permissions: ['session.read'],
|
|
27
|
+
raw: { provider: 'sms-otp', challengeId, code, demo: true },
|
|
28
|
+
};
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { PortaProvider } from '../provider.js';
|
|
2
|
+
export interface PasswordUser {
|
|
3
|
+
email: string;
|
|
4
|
+
password: string;
|
|
5
|
+
displayName?: string;
|
|
6
|
+
permissions?: string[];
|
|
7
|
+
}
|
|
8
|
+
export interface PasswordProviderOpts {
|
|
9
|
+
users: PasswordUser[];
|
|
10
|
+
label?: string;
|
|
11
|
+
}
|
|
12
|
+
export declare function passwordProvider(opts: PasswordProviderOpts): PortaProvider;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
// Built-in password provider. Matches against an in-memory user table —
|
|
2
|
+
// suitable for testbeds and demos. Real applications swap this for one that
|
|
3
|
+
// POSTs to a backend.
|
|
4
|
+
export function passwordProvider(opts) {
|
|
5
|
+
return {
|
|
6
|
+
id: 'password',
|
|
7
|
+
label: opts.label ?? 'Sign in',
|
|
8
|
+
kind: 'form-fields',
|
|
9
|
+
fields: [
|
|
10
|
+
{
|
|
11
|
+
name: 'email',
|
|
12
|
+
label: {
|
|
13
|
+
path: '$/t/auth/usernameLabel',
|
|
14
|
+
},
|
|
15
|
+
// labelKey: 'auth/usernameLabel',
|
|
16
|
+
type: 'email',
|
|
17
|
+
required: true,
|
|
18
|
+
autoComplete: 'email',
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
name: 'password',
|
|
22
|
+
label: {
|
|
23
|
+
path: '$/t/auth/passwordLabel',
|
|
24
|
+
},
|
|
25
|
+
// labelKey: 'auth/passwordLabel',
|
|
26
|
+
type: 'password',
|
|
27
|
+
required: true,
|
|
28
|
+
autoComplete: 'current-password',
|
|
29
|
+
},
|
|
30
|
+
],
|
|
31
|
+
async signin(creds) {
|
|
32
|
+
const { email, password } = creds;
|
|
33
|
+
if (!email || !password)
|
|
34
|
+
throw new Error('Email and password are required.');
|
|
35
|
+
const user = opts.users.find((u) => u.email === email && u.password === password);
|
|
36
|
+
if (!user)
|
|
37
|
+
throw new Error('Invalid email or password.');
|
|
38
|
+
return {
|
|
39
|
+
userId: user.email,
|
|
40
|
+
displayName: user.displayName ?? user.email,
|
|
41
|
+
email: user.email,
|
|
42
|
+
permissions: user.permissions ?? [],
|
|
43
|
+
};
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { combineDisposables } from '../core/disposable.js';
|
|
2
|
+
import { LoginForm } from '../ui/forms/LoginForm.js';
|
|
3
|
+
import { PortaLock } from './PortaLock.js';
|
|
4
|
+
import { Sigillum } from './SigillumGate.js';
|
|
5
|
+
import { Limen } from './Limen.js';
|
|
6
|
+
// Registers the porta blocks as scena components so they can be referenced
|
|
7
|
+
// by name from ComponentNode trees and agent-sent payloads.
|
|
8
|
+
//
|
|
9
|
+
// Porta.LoginForm — the composer
|
|
10
|
+
// Porta.Sigillum — silent permission gate
|
|
11
|
+
// Porta.PortaLock — inline gate with visible LoginForm fallback
|
|
12
|
+
// Porta.Limen — full-page wall with header / footer / left / right slots
|
|
13
|
+
export function registerPortaBlocks(scena) {
|
|
14
|
+
return combineDisposables(scena.components.register({
|
|
15
|
+
component: 'Porta.LoginForm',
|
|
16
|
+
category: 'page',
|
|
17
|
+
renderer: { kind: 'react', load: async () => ({ default: LoginForm }) },
|
|
18
|
+
}), scena.components.register({
|
|
19
|
+
component: 'Porta.PortaLock',
|
|
20
|
+
category: 'page',
|
|
21
|
+
renderer: { kind: 'react', load: async () => ({ default: PortaLock }) },
|
|
22
|
+
}), scena.components.register({
|
|
23
|
+
component: 'Porta.Sigillum',
|
|
24
|
+
category: 'page',
|
|
25
|
+
renderer: { kind: 'react', load: async () => ({ default: Sigillum }) },
|
|
26
|
+
}), scena.components.register({
|
|
27
|
+
component: 'Porta.Limen',
|
|
28
|
+
category: 'page',
|
|
29
|
+
renderer: { kind: 'react', load: async () => ({ default: Limen }) },
|
|
30
|
+
}));
|
|
31
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Scena } from '../types/scena.js';
|
|
2
|
+
import type { PortaProvider } from './provider.js';
|
|
3
|
+
import { type Sigillum } from './sigillum.js';
|
|
4
|
+
export interface CreatePortaOpts {
|
|
5
|
+
providers: PortaProvider[];
|
|
6
|
+
}
|
|
7
|
+
export interface Porta {
|
|
8
|
+
/** Read-only ordered list of registered providers (preserves opts order). */
|
|
9
|
+
providers: PortaProvider[];
|
|
10
|
+
/** Lookup a provider by id. */
|
|
11
|
+
getProvider(id: string): PortaProvider | undefined;
|
|
12
|
+
/** Sigillum facade — `session()`, `has(scope)`, `isPending()`, `signOut()`. */
|
|
13
|
+
sigillum: Sigillum;
|
|
14
|
+
}
|
|
15
|
+
export declare function createPorta(scena: Scena, opts: CreatePortaOpts): Porta;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { SIGILLUM_PATHS, createSigillum } from './sigillum.js';
|
|
2
|
+
import { registerSigillumCommands } from './commands.js';
|
|
3
|
+
// One-shot setup. Call after createScena():
|
|
4
|
+
// const porta = createPorta(scena, { providers: [...] });
|
|
5
|
+
// Then wrap the app in <PortaProvider porta={porta}>.
|
|
6
|
+
export function createPorta(scena, opts) {
|
|
7
|
+
const providerMap = new Map();
|
|
8
|
+
const seen = new Set();
|
|
9
|
+
for (const p of opts.providers) {
|
|
10
|
+
if (seen.has(p.id)) {
|
|
11
|
+
throw new Error(`Duplicate PortaProvider id "${p.id}".`);
|
|
12
|
+
}
|
|
13
|
+
seen.add(p.id);
|
|
14
|
+
providerMap.set(p.id, p);
|
|
15
|
+
}
|
|
16
|
+
scena.store.patchMany({
|
|
17
|
+
[SIGILLUM_PATHS.providers]: opts.providers.map((p) => p.id),
|
|
18
|
+
[SIGILLUM_PATHS.pending]: false,
|
|
19
|
+
[SIGILLUM_PATHS.error]: null,
|
|
20
|
+
[SIGILLUM_PATHS.challenge]: null,
|
|
21
|
+
});
|
|
22
|
+
if (scena.store.get(SIGILLUM_PATHS.session) === undefined) {
|
|
23
|
+
scena.store.set(SIGILLUM_PATHS.session, null);
|
|
24
|
+
}
|
|
25
|
+
registerSigillumCommands(scena, providerMap);
|
|
26
|
+
return {
|
|
27
|
+
providers: opts.providers,
|
|
28
|
+
getProvider: (id) => providerMap.get(id),
|
|
29
|
+
sigillum: createSigillum(scena),
|
|
30
|
+
};
|
|
31
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { BindingPath } from '../types/component-graph.js';
|
|
2
|
+
import type { Scena } from '../types/scena.js';
|
|
3
|
+
import type { Session } from './provider.js';
|
|
4
|
+
export declare const SIGILLUM_PATHS: {
|
|
5
|
+
readonly session: BindingPath;
|
|
6
|
+
readonly providers: BindingPath;
|
|
7
|
+
readonly pending: BindingPath;
|
|
8
|
+
readonly error: BindingPath;
|
|
9
|
+
readonly challenge: BindingPath;
|
|
10
|
+
};
|
|
11
|
+
export interface Sigillum {
|
|
12
|
+
session(): Session | null;
|
|
13
|
+
/** True if the current session carries `scope`. v0 matcher: equality + trailing `.*` wildcard. */
|
|
14
|
+
has(scope: string): boolean;
|
|
15
|
+
isPending(): boolean;
|
|
16
|
+
error(): string | null;
|
|
17
|
+
signOut(): Promise<unknown>;
|
|
18
|
+
}
|
|
19
|
+
export declare function createSigillum(scena: Scena): Sigillum;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export const SIGILLUM_PATHS = {
|
|
2
|
+
session: '$/sigillum/session',
|
|
3
|
+
providers: '$/sigillum/providers',
|
|
4
|
+
pending: '$/sigillum/pending',
|
|
5
|
+
error: '$/sigillum/error',
|
|
6
|
+
challenge: '$/sigillum/challenge',
|
|
7
|
+
};
|
|
8
|
+
export function createSigillum(scena) {
|
|
9
|
+
function session() {
|
|
10
|
+
return scena.store.get(SIGILLUM_PATHS.session) ?? null;
|
|
11
|
+
}
|
|
12
|
+
return {
|
|
13
|
+
session,
|
|
14
|
+
has(scope) {
|
|
15
|
+
const s = session();
|
|
16
|
+
if (!s || !s.permissions)
|
|
17
|
+
return false;
|
|
18
|
+
return s.permissions.some((p) => matchScope(p, scope));
|
|
19
|
+
},
|
|
20
|
+
isPending() {
|
|
21
|
+
return Boolean(scena.store.get(SIGILLUM_PATHS.pending));
|
|
22
|
+
},
|
|
23
|
+
error() {
|
|
24
|
+
return scena.store.get(SIGILLUM_PATHS.error) ?? null;
|
|
25
|
+
},
|
|
26
|
+
signOut() {
|
|
27
|
+
return scena.commands.execute('sigillum.signout');
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
// Granted `'agents.write'` exactly matches scope `'agents.write'`.
|
|
32
|
+
// Granted `'agents.*'` matches any scope starting with `'agents.'`.
|
|
33
|
+
// (Permission match rules are flagged PENDING in the plan for upgrade later.)
|
|
34
|
+
function matchScope(granted, requested) {
|
|
35
|
+
if (granted === requested)
|
|
36
|
+
return true;
|
|
37
|
+
if (granted.endsWith('.*')) {
|
|
38
|
+
return requested.startsWith(granted.slice(0, -1));
|
|
39
|
+
}
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function DefaultShell(): import("react").JSX.Element;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useLayout } from './hooks/useLayout.js';
|
|
3
|
+
import { SurfaceArea } from './SurfaceArea.js';
|
|
4
|
+
import { ShellSplitter } from './ShellSplitter.js';
|
|
5
|
+
// Minimal flex shell. Each surface is rendered via SurfaceArea, which
|
|
6
|
+
// delegates to the registered layout for that surface (tab / split / stack /
|
|
7
|
+
// rail / inline / floating). Apps that want a different chrome layout can
|
|
8
|
+
// compose SurfaceArea + ShellSplitter directly — see web-next/CustomShell.
|
|
9
|
+
export function DefaultShell() {
|
|
10
|
+
const layout = useLayout();
|
|
11
|
+
const surfaces = layout.surfaces;
|
|
12
|
+
const sidebarLeftWidth = surfaces['sidebar:left']?.size ?? 240;
|
|
13
|
+
const sidebarRightWidth = surfaces['sidebar:right']?.size ?? 280;
|
|
14
|
+
const panelBottomHeight = surfaces['panel:bottom']?.size ?? 200;
|
|
15
|
+
const sidebarLeftVisible = surfaces['sidebar:left']?.visible ?? true;
|
|
16
|
+
const sidebarRightVisible = surfaces['sidebar:right']?.visible ?? false;
|
|
17
|
+
const panelBottomVisible = surfaces['panel:bottom']?.visible ?? false;
|
|
18
|
+
const activitybarVisible = surfaces['activitybar']?.visible ?? true;
|
|
19
|
+
const statusbarVisible = surfaces['statusbar']?.visible ?? true;
|
|
20
|
+
const titlebarVisible = surfaces['titlebar']?.visible ?? true;
|
|
21
|
+
return (_jsxs("div", { className: "oo-shell", style: {
|
|
22
|
+
display: 'flex',
|
|
23
|
+
flexDirection: 'column',
|
|
24
|
+
height: '100vh',
|
|
25
|
+
width: '100vw',
|
|
26
|
+
overflow: 'hidden',
|
|
27
|
+
}, children: [titlebarVisible ? _jsx(SurfaceArea, { surface: "titlebar", layout: "bar" }) : null, _jsxs("div", { style: { display: 'flex', flex: 1, minHeight: 0, overflow: 'hidden' }, children: [activitybarVisible ? _jsx(SurfaceArea, { surface: "activitybar", layout: "rail" }) : null, sidebarLeftVisible ? (_jsxs(_Fragment, { children: [_jsx(SurfaceArea, { surface: "sidebar:left", layout: "stack", style: { width: sidebarLeftWidth, flex: '0 0 auto', overflow: 'hidden' } }), _jsx(ShellSplitter, { surface: "sidebar:left", orientation: "vertical", min: 120, max: 600 })] })) : null, _jsxs("div", { style: { flex: 1, minWidth: 0, display: 'flex', flexDirection: 'column' }, children: [_jsx(SurfaceArea, { surface: "main", layout: "tab", style: { flex: 1, minHeight: 0, overflow: 'hidden' } }), panelBottomVisible ? (_jsxs(_Fragment, { children: [_jsx(ShellSplitter, { surface: "panel:bottom", orientation: "horizontal", invert: true, min: 80, max: 500 }), _jsx(SurfaceArea, { surface: "panel:bottom", layout: "tab", style: {
|
|
28
|
+
height: panelBottomHeight,
|
|
29
|
+
flex: '0 0 auto',
|
|
30
|
+
overflow: 'hidden',
|
|
31
|
+
} })] })) : null] }), sidebarRightVisible ? (_jsxs(_Fragment, { children: [_jsx(ShellSplitter, { surface: "sidebar:right", orientation: "vertical", invert: true, min: 160, max: 600 }), _jsx(SurfaceArea, { surface: "sidebar:right", layout: "stack", style: { width: sidebarRightWidth, flex: '0 0 auto', overflow: 'hidden' } })] })) : null] }), statusbarVisible ? _jsx(SurfaceArea, { surface: "statusbar", layout: "bar" }) : null, _jsx(SurfaceArea, { surface: "overlay", layout: "floating", style: {
|
|
32
|
+
position: 'fixed',
|
|
33
|
+
inset: 0,
|
|
34
|
+
pointerEvents: 'none',
|
|
35
|
+
zIndex: 1000,
|
|
36
|
+
} })] }));
|
|
37
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
import type { Scena as ScenaInstance } from '../types/scena.js';
|
|
3
|
+
import type { CreateScenaOptions } from '../types/scena.js';
|
|
4
|
+
export interface ScenaComponentProps {
|
|
5
|
+
options?: CreateScenaOptions;
|
|
6
|
+
onRender?: (scena: ScenaInstance) => void;
|
|
7
|
+
children?: ReactNode;
|
|
8
|
+
}
|
|
9
|
+
export declare function Scena({ options, onRender, children }: ScenaComponentProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { lazy, Suspense, useEffect, useRef } from 'react';
|
|
3
|
+
import { createScena } from '../core/scena.js';
|
|
4
|
+
import { ScenaProvider } from './ScenaProvider.js';
|
|
5
|
+
// import { DefaultShell } from './DefaultShell.js';
|
|
6
|
+
const DefaultShell = lazy(() => import('./DefaultShell.js').then(module => ({ default: module.DefaultShell })));
|
|
7
|
+
export function Scena({ options, onRender, children }) {
|
|
8
|
+
const scenaRef = useRef(null);
|
|
9
|
+
if (!scenaRef.current) {
|
|
10
|
+
scenaRef.current = createScena(options);
|
|
11
|
+
onRender?.(scenaRef.current);
|
|
12
|
+
}
|
|
13
|
+
useEffect(() => {
|
|
14
|
+
return () => {
|
|
15
|
+
scenaRef.current?.dispose();
|
|
16
|
+
scenaRef.current = null;
|
|
17
|
+
};
|
|
18
|
+
}, []);
|
|
19
|
+
return (_jsx(ScenaProvider, { scena: scenaRef.current, children: children ?? (_jsx(Suspense, { fallback: _jsx("div", { children: "Loading..." }), children: _jsx(DefaultShell, {}) })) }));
|
|
20
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
import type { Scena } from '../types/scena.js';
|
|
3
|
+
export interface ScenaProviderProps {
|
|
4
|
+
scena: Scena;
|
|
5
|
+
children: ReactNode;
|
|
6
|
+
}
|
|
7
|
+
export declare function ScenaProvider({ scena, children }: ScenaProviderProps): import("react").JSX.Element;
|
|
8
|
+
export declare function useScena(): Scena;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { createContext, useContext } from 'react';
|
|
3
|
+
const ScenaContext = createContext(null);
|
|
4
|
+
export function ScenaProvider({ scena, children }) {
|
|
5
|
+
return _jsx(ScenaContext.Provider, { value: scena, children: children });
|
|
6
|
+
}
|
|
7
|
+
export function useScena() {
|
|
8
|
+
const ctx = useContext(ScenaContext);
|
|
9
|
+
if (!ctx) {
|
|
10
|
+
throw new Error('useScena must be used inside <ScenaProvider> or <Scena>');
|
|
11
|
+
}
|
|
12
|
+
return ctx;
|
|
13
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type CSSProperties } from 'react';
|
|
2
|
+
import type { SurfaceName } from '../types/mount-surface.js';
|
|
3
|
+
export interface ShellSplitterProps {
|
|
4
|
+
surface: SurfaceName;
|
|
5
|
+
orientation: 'vertical' | 'horizontal';
|
|
6
|
+
invert?: boolean;
|
|
7
|
+
min?: number;
|
|
8
|
+
max?: number;
|
|
9
|
+
thickness?: number;
|
|
10
|
+
style?: CSSProperties;
|
|
11
|
+
className?: string;
|
|
12
|
+
}
|
|
13
|
+
export declare function ShellSplitter({ surface, orientation, invert, min, max, thickness, style, className, }: ShellSplitterProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useRef } from 'react';
|
|
3
|
+
import { useScena } from './ScenaProvider.js';
|
|
4
|
+
// Chrome-level drag handle. Writes the dragged size to
|
|
5
|
+
// `scena.layout.setSurface(surface, { size })`, which mirrors to the
|
|
6
|
+
// `layout:surfaces.<name>.size` path and persists via LayoutStorage.
|
|
7
|
+
//
|
|
8
|
+
// Used by DefaultShell between adjacent surfaces; apps with custom shells
|
|
9
|
+
// can drop these in wherever they want a resizable edge.
|
|
10
|
+
export function ShellSplitter({ surface, orientation, invert = false, min = 100, max = 800, thickness = 4, style, className, }) {
|
|
11
|
+
const scena = useScena();
|
|
12
|
+
const draggingRef = useRef(false);
|
|
13
|
+
const startSizeRef = useRef(0);
|
|
14
|
+
const startPosRef = useRef(0);
|
|
15
|
+
const rafRef = useRef(null);
|
|
16
|
+
const pendingSizeRef = useRef(null);
|
|
17
|
+
// Transient while the pointer is down: the frame still re-renders the shell,
|
|
18
|
+
// but the layout is not mirrored into the reactive store (which wakes every
|
|
19
|
+
// `useStore` in the app) and not serialised to storage. Releasing commits once.
|
|
20
|
+
function commitPending(transient) {
|
|
21
|
+
if (pendingSizeRef.current !== null) {
|
|
22
|
+
scena.layout.setSurface(surface, { size: pendingSizeRef.current }, { transient });
|
|
23
|
+
pendingSizeRef.current = null;
|
|
24
|
+
}
|
|
25
|
+
rafRef.current = null;
|
|
26
|
+
}
|
|
27
|
+
function onPointerDown(e) {
|
|
28
|
+
e.preventDefault();
|
|
29
|
+
e.stopPropagation();
|
|
30
|
+
e.currentTarget.setPointerCapture(e.pointerId);
|
|
31
|
+
draggingRef.current = true;
|
|
32
|
+
startSizeRef.current = scena.layout.get().surfaces[surface]?.size ?? 240;
|
|
33
|
+
startPosRef.current = orientation === 'vertical' ? e.clientX : e.clientY;
|
|
34
|
+
e.currentTarget.style.background = 'var(--oo-color-accent)';
|
|
35
|
+
// `user-select: none` on the handle alone does not stop the drag from
|
|
36
|
+
// selecting text across the surfaces either side of it, because the pointer
|
|
37
|
+
// is captured but the selection is the document's.
|
|
38
|
+
document.documentElement.classList.add('oo-resizing');
|
|
39
|
+
document.documentElement.style.cursor =
|
|
40
|
+
orientation === 'vertical' ? 'ew-resize' : 'ns-resize';
|
|
41
|
+
}
|
|
42
|
+
function onPointerCancel(e) {
|
|
43
|
+
onPointerUp(e);
|
|
44
|
+
}
|
|
45
|
+
function onPointerMove(e) {
|
|
46
|
+
if (!draggingRef.current)
|
|
47
|
+
return;
|
|
48
|
+
const pos = orientation === 'vertical' ? e.clientX : e.clientY;
|
|
49
|
+
const delta = pos - startPosRef.current;
|
|
50
|
+
const signed = invert ? -delta : delta;
|
|
51
|
+
const next = Math.max(min, Math.min(max, startSizeRef.current + signed));
|
|
52
|
+
pendingSizeRef.current = next;
|
|
53
|
+
if (rafRef.current === null) {
|
|
54
|
+
rafRef.current = requestAnimationFrame(() => commitPending(true));
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
function onPointerUp(e) {
|
|
58
|
+
if (!draggingRef.current)
|
|
59
|
+
return;
|
|
60
|
+
if (rafRef.current !== null) {
|
|
61
|
+
cancelAnimationFrame(rafRef.current);
|
|
62
|
+
rafRef.current = null;
|
|
63
|
+
}
|
|
64
|
+
// The settled value, and the only one that reaches the store or storage.
|
|
65
|
+
// Falls back to the last size when the pointer never moved, so a click on
|
|
66
|
+
// the handle still ends in a consistent state rather than a half-committed
|
|
67
|
+
// transient one.
|
|
68
|
+
pendingSizeRef.current ??= scena.layout.get().surfaces[surface]?.size ?? startSizeRef.current;
|
|
69
|
+
commitPending(false);
|
|
70
|
+
e.currentTarget.releasePointerCapture(e.pointerId);
|
|
71
|
+
draggingRef.current = false;
|
|
72
|
+
e.currentTarget.style.background = 'none';
|
|
73
|
+
document.documentElement.classList.remove('oo-resizing');
|
|
74
|
+
document.documentElement.style.cursor = '';
|
|
75
|
+
}
|
|
76
|
+
const baseStyle = orientation === 'vertical'
|
|
77
|
+
? { width: thickness, height: '100%', cursor: 'ew-resize' }
|
|
78
|
+
: { width: '100%', height: thickness, cursor: 'ns-resize' };
|
|
79
|
+
return (_jsx("div", { className: `oo-shell-splitter oo-shell-splitter--${orientation} ${className ?? ''}`, "data-surface": surface, onPointerDown: onPointerDown, onPointerMove: onPointerMove, onPointerUp: onPointerUp, onPointerCancel: onPointerCancel, style: {
|
|
80
|
+
flex: '0 0 auto',
|
|
81
|
+
background: 'transparent',
|
|
82
|
+
userSelect: 'none',
|
|
83
|
+
touchAction: 'none',
|
|
84
|
+
transition: 'background 0.15s',
|
|
85
|
+
...baseStyle,
|
|
86
|
+
...style,
|
|
87
|
+
} }));
|
|
88
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type CSSProperties } from 'react';
|
|
2
|
+
import type { SurfacePresentation } from '../types/layout.js';
|
|
3
|
+
import type { SurfaceName } from '../types/mount-surface.js';
|
|
4
|
+
import { type SurfaceResizeSpec } from './useSurfaceResize.js';
|
|
5
|
+
export interface SurfaceAreaProps {
|
|
6
|
+
surface: SurfaceName;
|
|
7
|
+
layout?: string;
|
|
8
|
+
style?: CSSProperties;
|
|
9
|
+
className?: string;
|
|
10
|
+
presentation?: SurfacePresentation;
|
|
11
|
+
resize?: SurfaceResizeSpec;
|
|
12
|
+
}
|
|
13
|
+
export declare function SurfaceArea({ surface, layout, style, className, presentation, resize, }: SurfaceAreaProps): import("react").JSX.Element;
|