@vgai/editor 0.2.0 → 0.4.0-canary.20260715.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -0
- package/dist/assets/axe-C7YBtOuM.js +30 -0
- package/dist/assets/browserAll-DDtGGE48.js +1 -0
- package/dist/assets/create-runtime-DbTlBlKG.js +1 -0
- package/dist/assets/{game-BI111o5f.js → game-BE0r7DMI.js} +3 -3
- package/dist/assets/game-BdTHR2_X.js +1 -0
- package/dist/assets/{game-pt_1lQLv.js → game-C3iQGSqo.js} +1 -1
- package/dist/assets/game-CcHfYxjP.js +1 -0
- package/dist/assets/game-Cqzj_lpD.js +1 -0
- package/dist/assets/game-DSZdeCHu.js +1 -0
- package/dist/assets/game-Dch9sAPc.js +1 -0
- package/dist/assets/{game-xsOho_wg.js → game-SAFn90pA.js} +3 -3
- package/dist/assets/game-loop-DMIgSMV-.js +1 -0
- package/dist/assets/{game-source-CvidN7AB.js → game-source-Dk83w26t.js} +1 -1
- package/dist/assets/{index-Bp5cecD6.js → index-4idIsHHJ.js} +2 -2
- package/dist/assets/{index-DL7RcQ0n.js → index-C-LhOTBN.js} +1 -1
- package/dist/assets/{index-Cs8xwv3e.js → index-CDkxceqE.js} +1 -1
- package/dist/assets/index-CQEfi217.js +15412 -0
- package/dist/assets/index-Dvi-V0NE.css +1 -0
- package/dist/assets/ingest-siblings-s0P5I1Ub.js +1 -0
- package/dist/assets/mount-manifest-DXMOlF79.js +1 -0
- package/dist/assets/react-18-C9eHn8x1.js +1 -0
- package/dist/assets/webworkerAll-Fn0e-ouF.js +1 -0
- package/dist/assets/world-documents-GM0a9Kv7.js +1 -0
- package/dist/index.html +15 -13
- package/dist/ingest/racing-game/vgai.game.json +5 -4
- package/dist/ingest/simcity/vgai.game.json +5 -4
- package/dist/ingest/tanks/vgai.game.json +5 -4
- package/dist/project-scripts.bundle.js +3917 -0
- package/dist/scenes/untitled.vscn.json +2 -0
- package/dist-server/packaged.mjs +7697 -3435
- package/package.json +31 -4
- package/scripts/probe-reporter.ts +349 -0
- package/scripts/run-probe.ts +2260 -0
- package/server/asset-catalog-audit.ts +268 -0
- package/server/asset-catalog-v2.ts +146 -0
- package/server/asset-library-routes.ts +276 -58
- package/server/canonical-path.ts +1 -1
- package/server/dev.ts +148 -44
- package/server/editor-server.ts +888 -61
- package/server/editor-sse.ts +115 -4
- package/server/harness-chat-service.ts +796 -0
- package/server/local-asset-catalog.ts +157 -22
- package/server/packaged.ts +51 -21
- package/server/process-shutdown.ts +136 -0
- package/server/prod.ts +9 -6
- package/server/project-hmr-files.ts +41 -0
- package/server/project-operations.ts +343 -0
- package/server/project-optimize-deps-entries.ts +4 -4
- package/server/project-output-writer.ts +156 -0
- package/server/project-validation.ts +140 -0
- package/server/project-view.ts +8 -50
- package/server/server-utils.ts +75 -10
- package/server/session-registry.ts +12 -0
- package/src/EditorContext.tsx +107 -3
- package/src/action-registry.ts +115 -17
- package/src/adapter-resolver.ts +213 -478
- package/src/asset-events.ts +64 -1
- package/src/asset-preview.ts +906 -0
- package/src/asset-selection.ts +121 -0
- package/src/asset-workflow/asset-capabilities.ts +259 -0
- package/src/asset-workflow/asset-editor-errors.ts +46 -0
- package/src/asset-workflow/asset-import-pipeline.ts +176 -0
- package/src/asset-workflow/asset-library-query.ts +107 -0
- package/src/asset-workflow/asset-types.ts +192 -0
- package/src/asset-workflow/asset-workflow-quality.ts +65 -0
- package/src/asset-workflow/import-contract.ts +113 -0
- package/src/asset-workflow/model-conversion.ts +126 -0
- package/src/asset-workflow/model-inspection.ts +185 -0
- package/src/asset-workflow/project-asset-commands.ts +23 -0
- package/src/asset-workflow/project-asset-health.ts +153 -0
- package/src/asset-workflow/project-asset-operations.ts +119 -0
- package/src/asset-workflow/thumbnail-system.ts +172 -0
- package/src/authoring/active-systems.ts +15 -0
- package/src/authoring/boundary-authoring-adapter.ts +16 -5
- package/src/authoring/composite-authoring-adapter.ts +305 -124
- package/src/authoring/design-time-layers.ts +300 -117
- package/src/authoring/edit-mode-authoring.ts +278 -293
- package/src/authoring/embed-only-adapter.ts +4 -2
- package/src/authoring/first-party-hierarchy-menu.ts +7 -2
- package/src/authoring/first-party-inspector/AddSectionMenu.tsx +5 -12
- package/src/authoring/first-party-inspector/EnvironmentSection.tsx +53 -126
- package/src/authoring/first-party-inspector/HeaderSection.tsx +54 -65
- package/src/authoring/first-party-inspector/is-first-party-selection.ts +30 -11
- package/src/authoring/first-party-inspector/register.tsx +13 -2
- package/src/authoring/ingest-authoring-adapter.ts +142 -45
- package/src/authoring/mount-failure-report.ts +5 -5
- package/src/authoring/provenance.ts +41 -0
- package/src/authoring/react-dom-authoring-adapter.ts +92 -92
- package/src/authoring/react-inspector-section.tsx +489 -51
- package/src/authoring/react-world-authoring-adapter.ts +541 -306
- package/src/authoring/story-overlay.ts +1 -1
- package/src/authoring/story-types.ts +11 -0
- package/src/authoring/vgai-scene-authoring-adapter.ts +54 -25
- package/src/authoring/viewport-tool-context.ts +78 -0
- package/src/authoring/world-canvas-viewport-state.ts +35 -0
- package/src/authoring/world-hidden-viewport.ts +186 -0
- package/src/authoring/world-pan-state.ts +33 -17
- package/src/authoring/world-session-state.ts +1 -1
- package/src/authoring/world2d-authoring-adapter.ts +109 -52
- package/src/availability-tick.ts +56 -0
- package/src/browser-play-entry.ts +5 -5
- package/src/browser-project-scripts.ts +1 -0
- package/src/build-identity.ts +15 -0
- package/src/command-listener.ts +893 -19
- package/src/components/AlignToolbar.tsx +74 -63
- package/src/components/AppRoot.tsx +193 -26
- package/src/components/ApplicationMenus.tsx +272 -0
- package/src/components/AssetBrowser.tsx +1450 -293
- package/src/components/AssetEditorShell.tsx +141 -0
- package/src/components/AssetImportDetails.tsx +218 -0
- package/src/components/AssetLibraryPanel.tsx +14 -0
- package/src/components/CameraInfo.tsx +11 -20
- package/src/components/CenterDocuments.tsx +585 -0
- package/src/components/CommandPalette.tsx +75 -30
- package/src/components/ConsolePanel.css +55 -0
- package/src/components/ConsolePanel.tsx +57 -112
- package/src/components/DebugConsolePanel.tsx +461 -0
- package/src/components/DebuggerPanel.tsx +165 -0
- package/src/components/DefaultEditorLayout.tsx +167 -231
- package/src/components/GameHierarchy.tsx +873 -290
- package/src/components/GamePerformanceOverlay.tsx +46 -0
- package/src/components/HarnessChatPanel.tsx +2352 -0
- package/src/components/HistoryPanel.tsx +226 -0
- package/src/components/Inspector.tsx +153 -99
- package/src/components/InspectorToolSection.tsx +6 -4
- package/src/components/MountFailureBanner.tsx +31 -48
- package/src/components/NetworkSection.tsx +25 -14
- package/src/components/OnlineAssetBrowser.tsx +794 -343
- package/src/components/OverlayReportBanner.tsx +38 -64
- package/src/components/PerformancePanel.tsx +206 -0
- package/src/components/PlayBar.tsx +93 -263
- package/src/components/PrefabSaveDialog.tsx +55 -127
- package/src/components/ProjectHeader.css +60 -0
- package/src/components/ProjectHeader.tsx +170 -105
- package/src/components/ProjectScreen.tsx +246 -184
- package/src/components/ReactCanvasControls.tsx +185 -0
- package/src/components/ResolutionPicker.tsx +85 -0
- package/src/components/RootActivateDialog.tsx +39 -68
- package/src/components/SaveDialog.tsx +55 -127
- package/src/components/SaveStatus.tsx +11 -29
- package/src/components/StartupLoadingScreen.tsx +96 -0
- package/src/components/StateWatchPanel.tsx +302 -0
- package/src/components/StatsOverlay.tsx +12 -5
- package/src/components/StatusBar.tsx +64 -0
- package/src/components/ThemeManagerDialog.css +89 -0
- package/src/components/ThemeManagerDialog.tsx +371 -0
- package/src/components/ToolHost.tsx +26 -15
- package/src/components/Toolbar.tsx +117 -214
- package/src/components/VgaiVoxelLogo.tsx +89 -0
- package/src/components/ViewportOverlay.tsx +97 -172
- package/src/components/ViewportPanel.tsx +130 -31
- package/src/components/WorkspaceDock.tsx +891 -0
- package/src/components/WorldSelectionOverlay.tsx +51 -63
- package/src/components/WorldTextEditor.tsx +9 -5
- package/src/components/asset-documents.tsx +390 -0
- package/src/components/asset-editor-persistence.ts +44 -0
- package/src/components/asset-selection-section.tsx +338 -0
- package/src/components/asset-viewers/AudioViewer.tsx +73 -21
- package/src/components/asset-viewers/GenericJsonViewer.tsx +26 -11
- package/src/components/asset-viewers/ImageViewer.tsx +43 -11
- package/src/components/asset-viewers/InputMapViewer.tsx +512 -134
- package/src/components/asset-viewers/MaterialAssetEditor.tsx +540 -0
- package/src/components/asset-viewers/ModelViewer.tsx +805 -121
- package/src/components/asset-viewers/OnlineAssetDetail.tsx +177 -60
- package/src/components/asset-viewers/SourceAssetViewer.tsx +121 -0
- package/src/components/asset-workflow.css +506 -0
- package/src/components/build-documents.tsx +696 -0
- package/src/components/core-utilities.tsx +75 -0
- package/src/components/data-documents.tsx +364 -0
- package/src/components/{DataPanel.tsx → data-editor.tsx} +138 -288
- package/src/components/debugger-panel-state.ts +57 -0
- package/src/components/inspector-widgets/AlignmentGrid.tsx +8 -14
- package/src/components/inspector-widgets/BorderEditor.tsx +41 -33
- package/src/components/inspector-widgets/ColorPicker.tsx +39 -39
- package/src/components/inspector-widgets/FontPicker.tsx +13 -21
- package/src/components/inspector-widgets/GradientEditor.tsx +11 -19
- package/src/components/inspector-widgets/ScrubbableInput.tsx +6 -3
- package/src/components/inspector-widgets/ShadowEditor.tsx +20 -33
- package/src/components/inspector-widgets/shared.tsx +90 -49
- package/src/components/inspectors/AnimationSection.tsx +39 -40
- package/src/components/inspectors/AudioSection.tsx +28 -39
- package/src/components/inspectors/BoneAttachmentSection.tsx +19 -24
- package/src/components/inspectors/CameraSection.tsx +14 -23
- package/src/components/inspectors/ComponentsSection.tsx +39 -43
- package/src/components/inspectors/JointsSection.tsx +34 -43
- package/src/components/inspectors/LightSection.tsx +90 -35
- package/src/components/inspectors/MaterialSection.tsx +137 -174
- package/src/components/inspectors/MeshSection.tsx +9 -17
- package/src/components/inspectors/NavigationSection.tsx +8 -15
- package/src/components/inspectors/ParticleSection.tsx +91 -76
- package/src/components/inspectors/PhysicsSection.tsx +42 -46
- package/src/components/inspectors/PostProcessingSection.tsx +28 -36
- package/src/components/inspectors/RenderingSection.tsx +12 -20
- package/src/components/inspectors/ShadowSection.tsx +7 -8
- package/src/components/inspectors/SplineSection.tsx +31 -42
- package/src/components/inspectors/TransformSection.tsx +14 -22
- package/src/components/patterns/Dialog.tsx +95 -0
- package/src/components/patterns/Fields.tsx +44 -0
- package/src/components/patterns/List.tsx +25 -0
- package/src/components/patterns/StateSurface.tsx +40 -0
- package/src/components/patterns/Surfaces.tsx +115 -0
- package/src/components/patterns/Tabs.tsx +80 -0
- package/src/components/patterns/Toolbar.tsx +51 -0
- package/src/components/patterns/Tree.tsx +72 -0
- package/src/components/primitives/Button.tsx +46 -0
- package/src/components/primitives/ColorInput.tsx +11 -47
- package/src/components/primitives/EditorIcon.tsx +99 -0
- package/src/components/primitives/FormControls.tsx +71 -0
- package/src/components/primitives/JsonInput.tsx +15 -2
- package/src/components/primitives/Layout.tsx +100 -0
- package/src/components/primitives/Menu.tsx +105 -0
- package/src/components/primitives/NumberInput.tsx +8 -35
- package/src/components/primitives/Panel.tsx +49 -44
- package/src/components/primitives/SectionHeader.tsx +10 -28
- package/src/components/primitives/Text.tsx +46 -0
- package/src/components/primitives/Tooltip.tsx +20 -12
- package/src/components/primitives/Vec3Input.tsx +3 -0
- package/src/components/primitives/banner-tones.ts +33 -0
- package/src/components/primitives/editor-icons.ts +102 -0
- package/src/components/primitives/panel-header-styles.ts +30 -0
- package/src/components/project-operation-documents.tsx +226 -0
- package/src/components/status-contributions.tsx +175 -0
- package/src/components/story-documents-register.ts +15 -0
- package/src/components/story-documents.tsx +1185 -0
- package/src/components/tool-documents.tsx +110 -0
- package/src/components/workspace-dock.css +293 -0
- package/src/components/workspace-history.ts +33 -0
- package/src/components/world-documents.tsx +145 -0
- package/src/components/xstate-documents.tsx +209 -0
- package/src/composite-screenshot.ts +248 -0
- package/src/design-system/index.ts +70 -0
- package/src/design-system-stories/Foundation.stories.tsx +183 -0
- package/src/design-system-stories/Patterns.stories.tsx +251 -0
- package/src/design-system-stories/Workspace.stories.tsx +538 -0
- package/src/doctor/report.ts +57 -13
- package/src/editor-api.ts +295 -31
- package/src/editor-compatibility.ts +200 -0
- package/src/editor-console.ts +35 -17
- package/src/editor-hotkeys.ts +85 -33
- package/src/editor-store.ts +538 -233
- package/src/editor-viewport.ts +160 -34
- package/src/entity-factory.ts +14 -3
- package/src/gizmo-registry.ts +21 -5
- package/src/harness-chat-editor-context.ts +37 -0
- package/src/harness-chat-indicator.ts +68 -0
- package/src/harness-chat-layout.ts +53 -0
- package/src/harness-chat-lifecycle.ts +170 -0
- package/src/harness-chat-reconnect.ts +85 -0
- package/src/harness-chat-types.ts +409 -0
- package/src/hierarchy-drop.ts +50 -0
- package/src/hierarchy-expansion-state.ts +100 -0
- package/src/hierarchy-menu-registry.ts +1 -1
- package/src/hierarchy-projection.ts +76 -0
- package/src/history/editor-session.ts +21 -0
- package/src/history/history-commands.ts +147 -0
- package/src/history/history-service.ts +904 -0
- package/src/history/json-history-resource.ts +165 -0
- package/src/history/persistence-coordinator.ts +35 -0
- package/src/history/project-file-history.ts +266 -0
- package/src/history/project-root-history-backends.ts +53 -0
- package/src/history/resource-registry.ts +209 -0
- package/src/history/snapshot-store.ts +108 -0
- package/src/history/source-history-backend.ts +374 -0
- package/src/history/types.ts +100 -0
- package/src/hmr-registration-group.ts +67 -0
- package/src/hmr-stable-react-context.ts +23 -0
- package/src/hosted-example.ts +12 -2
- package/src/hotkeys.ts +89 -18
- package/src/ingest/discovery-react.ts +9 -10
- package/src/ingest/discovery.ts +4 -4
- package/src/ingest/discovery2d.ts +5 -5
- package/src/ingest/games/bloom-composer/vgai.game.json +3 -3
- package/src/ingest/games/embed-bundle/vgai.game.json +3 -3
- package/src/ingest/games/games-fps/vgai.game.json +3 -3
- package/src/ingest/games/iframe-reachable/vgai.game.json +3 -3
- package/src/ingest/games/interactive-cubes/vgai.game.json +3 -3
- package/src/ingest/games/mismatched-three/vgai.game.json +3 -3
- package/src/ingest/games/own-three-bundled/vgai.game.json +3 -3
- package/src/ingest/games/pointerlock-maze/vgai.game.json +7 -4
- package/src/ingest/games-2d/bubbo-bubbo/vgai.game.json +3 -3
- package/src/ingest/games-2d/bunnymark/vgai.game.json +3 -3
- package/src/ingest/games-2d/flappy/vgai.game.json +3 -3
- package/src/ingest/games-2d/flappy-pixi/vgai.game.json +3 -3
- package/src/ingest/games-2d/puzzling-potions/vgai.game.json +3 -3
- package/src/ingest/games-2d/tilemap-camera/vgai.game.json +3 -3
- package/src/ingest/games-react/react-rpg/vgai.game.json +3 -3
- package/src/ingest/types.ts +1 -1
- package/src/ingest-mode.ts +47 -52
- package/src/ingest-siblings.ts +23 -33
- package/src/initial-scene.ts +1 -2
- package/src/main.tsx +16 -8
- package/src/manifest-project.ts +10 -12
- package/src/model-thumbnail.ts +261 -26
- package/src/module-mode.ts +44 -50
- package/src/play-log-events.ts +26 -0
- package/src/play-mode.ts +495 -401
- package/src/play-scene-adoption.ts +23 -0
- package/src/playground/main.ts +68 -24
- package/src/playwright-shim.ts +473 -0
- package/src/project-manager.ts +90 -10
- package/src/project-operations.ts +112 -0
- package/src/project-story-discovery.ts +25 -0
- package/src/project-tool-discovery.ts +43 -0
- package/src/scene-serializer.ts +0 -6
- package/src/scene-sync.ts +7 -2
- package/src/script-loader.ts +3 -3
- package/src/skeleton-helper.ts +57 -0
- package/src/storage/seed.ts +68 -8
- package/src/stories/StoryPreviewMount.tsx +265 -0
- package/src/stories/action-stories.fixture.tsx +44 -0
- package/src/stories/button-stories.fixture.tsx +50 -0
- package/src/stories/compose-project-stories.ts +182 -0
- package/src/stories/loader-stories.fixture.tsx +53 -0
- package/src/stories/story-discovery.ts +130 -0
- package/src/stories/story-registry.ts +146 -0
- package/src/theme-css.ts +1049 -0
- package/src/theme-library.ts +238 -0
- package/src/theme-preference.ts +130 -0
- package/src/theme.ts +527 -0
- package/src/tool-loader.ts +80 -24
- package/src/ui-source/inspect.ts +27 -4
- package/src/ui-source/source-write-backend.ts +83 -22
- package/src/widgets/index.ts +9 -18
- package/src/workspace-aux-commands.ts +11 -0
- package/src/workspace-dock-controller.ts +64 -0
- package/src/workspace-document-ids.ts +5 -0
- package/src/workspace-document-registry.ts +367 -0
- package/src/workspace-state-persistence.ts +455 -0
- package/src/workspace-status-registry.ts +110 -0
- package/src/workspace-utility-commands.ts +49 -0
- package/src/workspace-utility-registry.ts +161 -0
- package/src/world-document-routing.ts +16 -0
- package/src/xstate-inspect/XStateMachineInspector.tsx +544 -0
- package/src/xstate-inspect/character-animation-machine.fixture.ts +74 -0
- package/src/xstate-inspect/use-live-actor-state.ts +39 -0
- package/src/xstate-inspect/xstate-graph.ts +265 -0
- package/src/xstate-inspect/xstate-layout.ts +76 -0
- package/src/z-index.ts +26 -0
- package/template/.claude/skills/editor/SKILL.md +129 -90
- package/template/AGENTS.md +1110 -0
- package/template/CLAUDE.md +1 -512
- package/template/IDIOMS.md +50 -0
- package/template/check-idioms.ts +706 -0
- package/template/manifest-entry-modules-plugin.ts +53 -0
- package/template/package.json +13 -4
- package/template/public/scenes/default.scn2d.json +6 -0
- package/template/public/scenes/default.vscn.json +7 -1
- package/template/public/scenes/untitled.vscn.json +10 -0
- package/template/scripts/playtest.ts +40 -0
- package/template/server/loopback.ts +75 -0
- package/template/server/rooms/arena-room.ts +69 -1
- package/template/server/rooms/game-room.ts +68 -1
- package/template/src/data/README.md +9 -4
- package/template/src/data/data-ref.ts +35 -0
- package/template/src/data/tuning.schema.ts +1 -1
- package/template/src/main.ts +41 -62
- package/template/src/manifest-entry-modules.d.ts +3 -0
- package/template/src/operations/README.md +88 -0
- package/template/src/runtime/pixi-adapter.ts +24 -0
- package/template/src/scripts/components/data-spinner.ts +43 -2
- package/template/src/scripts/components/spin-lap-math.ts +27 -0
- package/template/src/tools/README.md +5 -3
- package/template/src/tools/example.tool.tsx +13 -7
- package/template/src/ui/Button.stories.tsx +66 -0
- package/template/src/ui/RebindPanel.tsx +2 -6
- package/template/src/ui/game.tsx +17 -0
- package/template/tests/acceptance/example.spec.ts +64 -0
- package/template/tests/logic/example.test.ts +31 -0
- package/template/tests/logic/room.test.ts +100 -0
- package/template/tests/tsconfig.json +30 -0
- package/template/validate-manifest.ts +5 -5
- package/template/validate-scenes.ts +50 -18
- package/template/vgai.game.json +20 -13
- package/template/vite.config.ts +77 -16
- package/vite-plugin-ui-oid.ts +261 -17
- package/dist/assets/CCDIKSolver-Dz-ysxZF.js +0 -1
- package/dist/assets/SelectionBox-BXsv_6aH.js +0 -1
- package/dist/assets/browser-project-scripts-DOru4L1x.js +0 -2
- package/dist/assets/browserAll-CEkWYlFk.js +0 -1
- package/dist/assets/create-runtime-DYIWr3va.js +0 -1
- package/dist/assets/data-asset-Bb9sIM7i.js +0 -5
- package/dist/assets/game-8SDZPPgH.js +0 -1
- package/dist/assets/game-CevorxyV.js +0 -1
- package/dist/assets/game-Di7XlywD.js +0 -1
- package/dist/assets/game-DjnCaw8R.js +0 -1
- package/dist/assets/game-Q9A0aXSV.js +0 -1
- package/dist/assets/index-CPVV6pjw.js +0 -1
- package/dist/assets/index-CpOnYyeD.js +0 -213
- package/dist/assets/index-Dr8H_6Rl.js +0 -1
- package/dist/assets/index-_bCaipUk.js +0 -13650
- package/dist/assets/ingest-siblings-Dz8eEqrV.js +0 -1
- package/dist/assets/mount-manifest-Bhk0ohsl.js +0 -1
- package/dist/assets/scene-query-BivAHhJu.js +0 -1
- package/dist/assets/webworkerAll-BLrH0F6F.js +0 -1
- package/dist/assets/xstate-animation-binding-1NGLmw6y.js +0 -1
- package/dist/assets/xstate.esm-BgUD33nl.js +0 -3
- package/src/authoring/scene-ui-layer.ts +0 -485
- package/src/authoring/ui-authoring-adapter.ts +0 -325
- package/src/authoring/ui-hierarchy-menu.ts +0 -40
- package/src/authoring/ui-inspector-sections.tsx +0 -156
- package/src/authoring/undo-timeline.ts +0 -145
- package/src/components/BottomPanel.tsx +0 -326
- package/src/components/BuildPanel.tsx +0 -455
- package/src/components/FolderTree.tsx +0 -179
- package/src/components/RightPanel.tsx +0 -166
- package/src/components/WorldContextMenu.tsx +0 -257
- package/src/components/asset-viewers/AssetViewer.tsx +0 -38
- package/src/ingest/games-react/react-rpg/src/ui/game-state.tsx +0 -129
- package/src/scene-ui-mode/active-scene-ui.ts +0 -58
- package/src/scene-ui-mode/scene-ui-palette-panel.tsx +0 -152
- package/src/scene-ui-mode/scene-ui-timeline-tab.tsx +0 -29
- package/src/scene-ui-mode/ui-prefab-dialog-host.tsx +0 -74
- package/src/scene-ui-mode/ui-prefab-hierarchy-menu.ts +0 -49
- package/src/scene-ui-mode/ui-prefab-io.ts +0 -76
- package/src/ui-editor/inspector.tsx +0 -563
- package/src/ui-editor/node-ops.ts +0 -266
- package/src/ui-editor/overlay.tsx +0 -380
- package/src/ui-editor/palette.tsx +0 -114
- package/src/ui-editor/react-store.ts +0 -78
- package/src/ui-editor/timeline-panel.tsx +0 -443
- package/src/ui-editor/ui-edit-store.ts +0 -552
- package/src/ui-editor/ui-prefab.ts +0 -95
- package/template/project.json +0 -9
- package/template/src/scripts/main.ts +0 -94
- package/template/src/ui/DefaultHud.tsx +0 -40
- package/template/src/ui/game-state.tsx +0 -37
- package/template/src/ui/mount-default-hud.tsx +0 -19
- package/template/src/ui/mount-ui.ts +0 -15
- package/vite-plugin-react-world-provider.ts +0 -81
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Button, Checkbox } from '../../design-system';
|
|
1
2
|
/**
|
|
2
3
|
* ShadowEditor / TextShadowEditor — a list of box/text shadows (add/remove,
|
|
3
4
|
* x/y/blur/(spread)/color, inset for box-shadow) (spec 27 §5 C1). Ported from
|
|
@@ -166,20 +167,15 @@ export function ShadowListEditor({
|
|
|
166
167
|
<span style={{ fontSize: 9, color: THEME.textMuted }}>{label}</span>
|
|
167
168
|
<div style={{ flex: 1 }} />
|
|
168
169
|
{!disabled && (
|
|
169
|
-
<
|
|
170
|
+
<Button
|
|
170
171
|
type="button"
|
|
172
|
+
variant="ghost"
|
|
173
|
+
size="compact"
|
|
171
174
|
data-testid={`${testId}-add`}
|
|
172
175
|
onClick={add}
|
|
173
|
-
style={{
|
|
174
|
-
border: 'none',
|
|
175
|
-
background: 'none',
|
|
176
|
-
color: THEME.accent,
|
|
177
|
-
cursor: 'pointer',
|
|
178
|
-
fontSize: 12,
|
|
179
|
-
}}
|
|
180
176
|
>
|
|
181
177
|
+
|
|
182
|
-
</
|
|
178
|
+
</Button>
|
|
183
179
|
)}
|
|
184
180
|
</div>
|
|
185
181
|
{value.map((shadow, i) => {
|
|
@@ -191,25 +187,18 @@ export function ShadowListEditor({
|
|
|
191
187
|
style={{ marginBottom: 6, padding: '4px 0', borderBottom: `1px solid ${THEME.border}` }}
|
|
192
188
|
>
|
|
193
189
|
<div style={{ display: 'flex', alignItems: 'center', gap: 4, marginBottom: 4 }}>
|
|
194
|
-
<
|
|
190
|
+
<Button
|
|
195
191
|
type="button"
|
|
192
|
+
variant="ghost"
|
|
193
|
+
size="compact"
|
|
194
|
+
aria-pressed={shadow.enabled}
|
|
196
195
|
data-testid={`${testId}-toggle-${i}`}
|
|
197
196
|
onClick={() => {
|
|
198
197
|
if (!disabled) update(i, { enabled: !shadow.enabled }, true);
|
|
199
198
|
}}
|
|
200
|
-
style={{
|
|
201
|
-
width: 14,
|
|
202
|
-
height: 14,
|
|
203
|
-
border: 'none',
|
|
204
|
-
background: 'none',
|
|
205
|
-
padding: 0,
|
|
206
|
-
cursor: disabled ? 'not-allowed' : 'pointer',
|
|
207
|
-
fontSize: 10,
|
|
208
|
-
color: shadow.enabled ? THEME.accent : THEME.textMuted,
|
|
209
|
-
}}
|
|
210
199
|
>
|
|
211
200
|
{shadow.enabled ? '●' : '○'}
|
|
212
|
-
</
|
|
201
|
+
</Button>
|
|
213
202
|
<ColorSwatch
|
|
214
203
|
testId={`${testId}-color-${i}`}
|
|
215
204
|
value={hexColor}
|
|
@@ -230,33 +219,31 @@ export function ShadowListEditor({
|
|
|
230
219
|
cursor: 'pointer',
|
|
231
220
|
}}
|
|
232
221
|
>
|
|
233
|
-
<
|
|
234
|
-
|
|
222
|
+
<Checkbox
|
|
223
|
+
// Standard checkbox size via the shared class (I-30: this
|
|
224
|
+
// was the one checkbox in the codebase with its own 10px
|
|
225
|
+
// explicit dimensions).
|
|
226
|
+
className="vgai-checkbox"
|
|
235
227
|
data-testid={`${testId}-inset-${i}`}
|
|
236
228
|
checked={shadow.inset}
|
|
237
229
|
disabled={disabled}
|
|
238
230
|
onChange={(e) => update(i, { inset: e.target.checked }, true)}
|
|
239
|
-
style={{ width: 10, height: 10 }}
|
|
240
231
|
/>
|
|
241
232
|
in
|
|
242
233
|
</label>
|
|
243
234
|
)}
|
|
244
235
|
<div style={{ flex: 1 }} />
|
|
245
236
|
{!disabled && (
|
|
246
|
-
<
|
|
237
|
+
<Button
|
|
247
238
|
type="button"
|
|
239
|
+
variant="ghost"
|
|
240
|
+
size="compact"
|
|
241
|
+
aria-label={`Remove ${label.toLowerCase()} ${i + 1}`}
|
|
248
242
|
data-testid={`${testId}-remove-${i}`}
|
|
249
243
|
onClick={() => remove(i)}
|
|
250
|
-
style={{
|
|
251
|
-
border: 'none',
|
|
252
|
-
background: 'none',
|
|
253
|
-
color: THEME.textMuted,
|
|
254
|
-
cursor: 'pointer',
|
|
255
|
-
fontSize: 11,
|
|
256
|
-
}}
|
|
257
244
|
>
|
|
258
245
|
×
|
|
259
|
-
</
|
|
246
|
+
</Button>
|
|
260
247
|
)}
|
|
261
248
|
</div>
|
|
262
249
|
{shadow.enabled && (
|
|
@@ -1,30 +1,41 @@
|
|
|
1
|
+
import { Button } from '../../design-system';
|
|
1
2
|
/**
|
|
2
3
|
* Shared theme + tiny primitives for the inspector widget kit (spec 27 §5
|
|
3
|
-
* C1).
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* `
|
|
8
|
-
*
|
|
4
|
+
* C1). Values are now sourced from `../../theme.ts` (editor-style-polish
|
|
5
|
+
* U0) — the editor's single canonical token module — rather than
|
|
6
|
+
* independently retyped here, which is how this kit's `themeVars.accent.default` had drifted
|
|
7
|
+
* from the app's actual dominant themeVars.accent.default blue (`EDITOR-STYLE-AUDIT.md` C-2/
|
|
8
|
+
* §3): `THEME.accent` is now `#579EFF`, matching the app-wide plurality
|
|
9
|
+
* color, not the old locally-invented `#3b82f6`. `FONT` also drops
|
|
10
|
+
* `'Inter'` (never loaded anywhere — 0 `@font-face` hits — so it only ever
|
|
11
|
+
* silently fell back to its own fallback chain, per finding I-29); `FONT`/
|
|
12
|
+
* `FONT_MONO` now resolve through the editor theme variables. The
|
|
13
|
+
* exported shape (`THEME`, `FONT`, `FONT_MONO`, `inputStyle()`) is
|
|
14
|
+
* unchanged — only the values now flow from one source of truth.
|
|
9
15
|
*/
|
|
10
16
|
|
|
11
17
|
import type React from 'react';
|
|
18
|
+
import { themeVars } from '../../design-system';
|
|
12
19
|
|
|
13
20
|
export const THEME = {
|
|
14
|
-
bg:
|
|
15
|
-
surface:
|
|
16
|
-
surfaceHover:
|
|
17
|
-
border:
|
|
18
|
-
text:
|
|
19
|
-
textMuted:
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
bg: themeVars.surface.panel,
|
|
22
|
+
surface: themeVars.surface.chrome,
|
|
23
|
+
surfaceHover: themeVars.surface.raised,
|
|
24
|
+
border: themeVars.boundary.default,
|
|
25
|
+
text: themeVars.content.primary,
|
|
26
|
+
textMuted: themeVars.content.muted,
|
|
27
|
+
onAccent: themeVars.content.onAccent,
|
|
28
|
+
accent: themeVars.accent.default,
|
|
29
|
+
neutralHover: themeVars.neutralOverlay.hover,
|
|
30
|
+
radiusSmall: themeVars.shape.small,
|
|
31
|
+
radiusMedium: themeVars.shape.medium,
|
|
32
|
+
inputBg: themeVars.surface.inset,
|
|
33
|
+
dynamic: themeVars.semantic.dynamic,
|
|
34
|
+
dynamicBg: themeVars.semantic.dynamicMuted,
|
|
24
35
|
} as const;
|
|
25
36
|
|
|
26
|
-
export const FONT =
|
|
27
|
-
export const FONT_MONO =
|
|
37
|
+
export const FONT = themeVars.typography.sans;
|
|
38
|
+
export const FONT_MONO = themeVars.typography.mono;
|
|
28
39
|
|
|
29
40
|
/**
|
|
30
41
|
* Every widget's change contract (report §"prop shape" for the C2 wiring
|
|
@@ -34,7 +45,7 @@ export const FONT_MONO = "'SF Mono', 'Fira Code', Menlo, Consolas, monospace";
|
|
|
34
45
|
* gesture (pointerup/blur/Enter — the COMMIT a caller should push through
|
|
35
46
|
* `writeStyleAuto`/`inspector.set` as a single undo step, mirroring
|
|
36
47
|
* `BoxEditProvider.end`). A caller that only cares about single-shot edits
|
|
37
|
-
* (a `<
|
|
48
|
+
* (a `<Select>`, a click) may omit `onChangeEnd` — widgets fall back to
|
|
38
49
|
* treating `onChange` as the commit in that case.
|
|
39
50
|
*/
|
|
40
51
|
export interface ChangeHandlers<T> {
|
|
@@ -59,10 +70,13 @@ export function inputStyle(disabled = false): React.CSSProperties {
|
|
|
59
70
|
return {
|
|
60
71
|
background: disabled ? THEME.dynamicBg : THEME.inputBg,
|
|
61
72
|
color: disabled ? THEME.dynamic : THEME.text,
|
|
62
|
-
border: `1px solid ${disabled ?
|
|
63
|
-
borderRadius:
|
|
64
|
-
|
|
65
|
-
|
|
73
|
+
border: `1px solid ${disabled ? THEME.dynamic : THEME.border}`,
|
|
74
|
+
borderRadius: themeVars.shape.small,
|
|
75
|
+
// Uniform field metrics (editor-style-polish U3): matches theme-css.ts's
|
|
76
|
+
// `.vgai-input`/`.vgai-select` classes exactly (space-1/space-3 padding,
|
|
77
|
+
// font-base) so kit fields and className'd fields render one height.
|
|
78
|
+
padding: '2px 6px',
|
|
79
|
+
fontSize: 'var(--vgai-font-base)',
|
|
66
80
|
fontFamily: FONT,
|
|
67
81
|
outline: 'none',
|
|
68
82
|
minWidth: 0,
|
|
@@ -73,30 +87,54 @@ export function inputStyle(disabled = false): React.CSSProperties {
|
|
|
73
87
|
|
|
74
88
|
export const rowStyle: React.CSSProperties = { display: 'flex', alignItems: 'center', gap: 4 };
|
|
75
89
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
90
|
+
/* ------------------------------------------------------------------------ */
|
|
91
|
+
/* Inspector-section style kit (editor-style-polish U3, I-8/I-10/I-12/I-13/ */
|
|
92
|
+
/* I-17/I-22) — the ONE home for the style objects the first-party sections */
|
|
93
|
+
/* used to hand-duplicate ~15 times each with tiny unintentional drift. */
|
|
94
|
+
/* ------------------------------------------------------------------------ */
|
|
95
|
+
|
|
96
|
+
/** Stacked field label ("label on its own line, field below" grammar) —
|
|
97
|
+
* replaces the `{fontSize:10, color:'#8c8c8c', marginBottom:2}` literal
|
|
98
|
+
* re-authored in nearly every `components/inspectors/*` section (I-8). */
|
|
99
|
+
export const fieldLabelStyle: React.CSSProperties = {
|
|
100
|
+
fontSize: 'var(--vgai-font-sm)',
|
|
101
|
+
color: themeVars.content.muted,
|
|
102
|
+
marginBottom: 2,
|
|
85
103
|
};
|
|
86
104
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
105
|
+
/** Sub-header / group label ("label over a related cluster of fields") — the
|
|
106
|
+
* ONE treatment for what used to be four (I-12): `Inspector.tsx`'s generic
|
|
107
|
+
* group header (11/600/uppercase/ls 0.4/#9aa0a6 — the incumbent this
|
|
108
|
+
* standardizes on), `ParticleSection.subHeaderStyle`,
|
|
109
|
+
* `PostProcessingSection.effectLabel`, and `MaterialSection`'s Textures. */
|
|
110
|
+
export const groupLabelStyle: React.CSSProperties = {
|
|
111
|
+
fontSize: 'var(--vgai-font-base)',
|
|
112
|
+
fontWeight: 600,
|
|
113
|
+
color: themeVars.content.muted,
|
|
114
|
+
textTransform: 'uppercase',
|
|
115
|
+
letterSpacing: 0.4,
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
/** One label-column width for every label-left/field-right row (I-13 —
|
|
119
|
+
* replaces the 56/64/70/76/80 ladder across Inspector.tsx/`Field`/
|
|
120
|
+
* `ComponentsSection`). */
|
|
121
|
+
export const LABEL_COL_WIDTH = 72;
|
|
122
|
+
|
|
123
|
+
/** Floating-surface (popover/dropdown) chrome — the menu contract (bg-2,
|
|
124
|
+
* border-2, radius-md, shadow-md; I-22). ColorPicker/FontPicker/tag
|
|
125
|
+
* suggestions all sit on this. */
|
|
126
|
+
export const popoverStyle: React.CSSProperties = {
|
|
127
|
+
background: themeVars.surface.chrome,
|
|
128
|
+
border: `1px solid ${themeVars.boundary.strong}`,
|
|
129
|
+
borderRadius: themeVars.shape.medium,
|
|
130
|
+
boxShadow: themeVars.elevation.medium,
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
/** Mixed-value (multi-select) presentation for a `<Select>` — italic, dim,
|
|
134
|
+
* matching `NumberInput`'s `—` mixed state so string/enum and numeric mixed
|
|
135
|
+
* values speak ONE visual language (I-15). */
|
|
136
|
+
export function mixedStyle(isMixed: boolean): React.CSSProperties {
|
|
137
|
+
return isMixed ? { color: themeVars.content.dim, fontStyle: 'italic' } : {};
|
|
100
138
|
}
|
|
101
139
|
|
|
102
140
|
export function ToggleButton({
|
|
@@ -113,16 +151,19 @@ export function ToggleButton({
|
|
|
113
151
|
testId?: string | undefined;
|
|
114
152
|
}): React.ReactElement {
|
|
115
153
|
return (
|
|
116
|
-
<
|
|
117
|
-
|
|
154
|
+
<Button
|
|
155
|
+
variant={active ? 'primary' : 'secondary'}
|
|
156
|
+
size="compact"
|
|
157
|
+
aria-pressed={active}
|
|
158
|
+
disabled={disabled}
|
|
118
159
|
data-testid={testId}
|
|
119
160
|
onClick={() => {
|
|
120
161
|
if (!disabled) onClick();
|
|
121
162
|
}}
|
|
122
|
-
style={
|
|
163
|
+
style={{ flex: 1 }}
|
|
123
164
|
>
|
|
124
165
|
{label}
|
|
125
|
-
</
|
|
166
|
+
</Button>
|
|
126
167
|
);
|
|
127
168
|
}
|
|
128
169
|
|
|
@@ -1,34 +1,13 @@
|
|
|
1
1
|
import type { SceneAnimation, SceneEntity } from '@engine/scene/scene-types';
|
|
2
2
|
import { getUserData } from '@engine/scene/user-data';
|
|
3
|
+
import { Button, Checkbox, SectionHeader, Select } from '../../design-system';
|
|
3
4
|
import { useEditorStore } from '../../EditorContext';
|
|
4
|
-
import {
|
|
5
|
+
import { fieldLabelStyle } from '../inspector-widgets/shared';
|
|
5
6
|
import type { SectionProps } from './multi-edit-utils';
|
|
6
7
|
|
|
7
|
-
const labelStyle: React.CSSProperties =
|
|
8
|
-
fontSize: 10,
|
|
9
|
-
color: '#8c8c8c',
|
|
10
|
-
marginBottom: 2,
|
|
11
|
-
};
|
|
8
|
+
const labelStyle: React.CSSProperties = fieldLabelStyle;
|
|
12
9
|
|
|
13
|
-
|
|
14
|
-
width: '100%',
|
|
15
|
-
background: '#1e1e1e',
|
|
16
|
-
color: '#c5c8ce',
|
|
17
|
-
border: '1px solid #333',
|
|
18
|
-
borderRadius: 2,
|
|
19
|
-
padding: '3px 6px',
|
|
20
|
-
fontSize: 12,
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
const btnStyle: React.CSSProperties = {
|
|
24
|
-
background: '#333',
|
|
25
|
-
color: '#c5c8ce',
|
|
26
|
-
border: '1px solid #444',
|
|
27
|
-
borderRadius: 3,
|
|
28
|
-
padding: '3px 8px',
|
|
29
|
-
cursor: 'pointer',
|
|
30
|
-
fontSize: 11,
|
|
31
|
-
};
|
|
10
|
+
// Shared chrome buttons (I-8/I-10) — the old per-file literals.
|
|
32
11
|
|
|
33
12
|
/**
|
|
34
13
|
* Plain-gltf-clip animation UI (E5 — the AnimGraph state-machine section this
|
|
@@ -39,7 +18,13 @@ const btnStyle: React.CSSProperties = {
|
|
|
39
18
|
* that wants discrete state-machine-driven animation now builds its own XState
|
|
40
19
|
* machine + `bindXStateAnimation` in code (see
|
|
41
20
|
* packages/engine/src/animation/xstate-animation-binding.ts) — there is no
|
|
42
|
-
* second
|
|
21
|
+
* second AUTHORED format or authoring section for it (E4,
|
|
22
|
+
* `docs/decisions/e4-xstate-authoring-boundary.md`: hand-authored TypeScript
|
|
23
|
+
* is the authoring boundary, deliberately not visually editable). A
|
|
24
|
+
* read-only VISUAL INSPECTOR for such a machine does exist (E3) — the
|
|
25
|
+
* selected-live-entity `State Machine` section + Debugger > Machines graph
|
|
26
|
+
* (`components/xstate-documents.tsx`), not a
|
|
27
|
+
* section here — this section stays GLTF-clip-only.
|
|
43
28
|
*/
|
|
44
29
|
export function AnimationSection({ entities }: SectionProps) {
|
|
45
30
|
const store = useEditorStore();
|
|
@@ -60,17 +45,28 @@ export function AnimationSection({ entities }: SectionProps) {
|
|
|
60
45
|
|
|
61
46
|
// Available clips from the loaded GLTF model
|
|
62
47
|
const availableClips = (getUserData(obj, '_availableClips') as string[] | undefined) ?? [];
|
|
48
|
+
const skeletonVisible = store.isSkeletonVisible(id);
|
|
49
|
+
|
|
50
|
+
const skeletonToggle = (
|
|
51
|
+
<label
|
|
52
|
+
style={{ display: 'flex', alignItems: 'center', gap: 4, fontSize: 12, cursor: 'pointer' }}
|
|
53
|
+
>
|
|
54
|
+
<Checkbox
|
|
55
|
+
className="vgai-checkbox"
|
|
56
|
+
checked={skeletonVisible}
|
|
57
|
+
onChange={(event) => store.setSkeletonVisible(id, event.target.checked)}
|
|
58
|
+
/>
|
|
59
|
+
Show Skeleton
|
|
60
|
+
</label>
|
|
61
|
+
);
|
|
63
62
|
|
|
64
63
|
if (!animation) {
|
|
65
64
|
return (
|
|
66
65
|
<SectionHeader label="Animation" defaultOpen={false}>
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
style={btnStyle}
|
|
70
|
-
onClick={() => store.updateEntity(id, { animation: {} })}
|
|
71
|
-
>
|
|
66
|
+
{skeletonToggle}
|
|
67
|
+
<Button type="button" onClick={() => store.updateEntity(id, { animation: {} })}>
|
|
72
68
|
Add Animation
|
|
73
|
-
</
|
|
69
|
+
</Button>
|
|
74
70
|
</SectionHeader>
|
|
75
71
|
);
|
|
76
72
|
}
|
|
@@ -78,11 +74,12 @@ export function AnimationSection({ entities }: SectionProps) {
|
|
|
78
74
|
return (
|
|
79
75
|
<SectionHeader label="Animation">
|
|
80
76
|
<div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
|
|
77
|
+
{skeletonToggle}
|
|
81
78
|
{/* Autoplay clip picker */}
|
|
82
79
|
{availableClips.length > 0 && (
|
|
83
80
|
<div>
|
|
84
81
|
<div style={labelStyle}>Autoplay Clip</div>
|
|
85
|
-
<
|
|
82
|
+
<Select
|
|
86
83
|
value={animation.autoplay ?? ''}
|
|
87
84
|
onChange={(e) => {
|
|
88
85
|
const val = e.target.value;
|
|
@@ -93,7 +90,8 @@ export function AnimationSection({ entities }: SectionProps) {
|
|
|
93
90
|
store.updateEntity(id, { animation: Object.keys(rest).length > 0 ? rest : {} });
|
|
94
91
|
}
|
|
95
92
|
}}
|
|
96
|
-
|
|
93
|
+
className="vgai-select"
|
|
94
|
+
style={{ width: '100%' }}
|
|
97
95
|
>
|
|
98
96
|
<option value="">(none)</option>
|
|
99
97
|
{availableClips.map((clip) => (
|
|
@@ -101,7 +99,7 @@ export function AnimationSection({ entities }: SectionProps) {
|
|
|
101
99
|
{clip}
|
|
102
100
|
</option>
|
|
103
101
|
))}
|
|
104
|
-
</
|
|
102
|
+
</Select>
|
|
105
103
|
</div>
|
|
106
104
|
)}
|
|
107
105
|
|
|
@@ -117,8 +115,8 @@ export function AnimationSection({ entities }: SectionProps) {
|
|
|
117
115
|
cursor: 'pointer',
|
|
118
116
|
}}
|
|
119
117
|
>
|
|
120
|
-
<
|
|
121
|
-
|
|
118
|
+
<Checkbox
|
|
119
|
+
className="vgai-checkbox"
|
|
122
120
|
checked={animation.loop !== false}
|
|
123
121
|
onChange={(e) => update({ loop: e.target.checked })}
|
|
124
122
|
/>
|
|
@@ -127,16 +125,17 @@ export function AnimationSection({ entities }: SectionProps) {
|
|
|
127
125
|
</div>
|
|
128
126
|
)}
|
|
129
127
|
|
|
130
|
-
<
|
|
128
|
+
<Button
|
|
131
129
|
type="button"
|
|
132
|
-
|
|
130
|
+
variant="danger"
|
|
131
|
+
size="compact"
|
|
133
132
|
onClick={() => {
|
|
134
133
|
const patch: Record<string, unknown> = { animation: undefined };
|
|
135
134
|
store.updateEntity(id, patch as Partial<SceneEntity>);
|
|
136
135
|
}}
|
|
137
136
|
>
|
|
138
137
|
Remove Animation
|
|
139
|
-
</
|
|
138
|
+
</Button>
|
|
140
139
|
</div>
|
|
141
140
|
</SectionHeader>
|
|
142
141
|
);
|
|
@@ -1,13 +1,20 @@
|
|
|
1
1
|
import type { SceneAudio } from '@engine/scene/scene-types';
|
|
2
2
|
import { useEffect, useRef, useState } from 'react';
|
|
3
|
+
import {
|
|
4
|
+
Button,
|
|
5
|
+
Checkbox,
|
|
6
|
+
NumberInput,
|
|
7
|
+
SectionHeader,
|
|
8
|
+
TextInput,
|
|
9
|
+
Tooltip,
|
|
10
|
+
themeVars,
|
|
11
|
+
} from '../../design-system';
|
|
3
12
|
import { useEditorStore } from '../../EditorContext';
|
|
4
|
-
import {
|
|
5
|
-
import { SectionHeader } from '../primitives/SectionHeader';
|
|
6
|
-
import { Tooltip } from '../primitives/Tooltip';
|
|
13
|
+
import { fieldLabelStyle } from '../inspector-widgets/shared';
|
|
7
14
|
import type { SectionProps } from './multi-edit-utils';
|
|
8
15
|
import { commonBool, commonNum } from './multi-edit-utils';
|
|
9
16
|
|
|
10
|
-
const labelStyle: React.CSSProperties =
|
|
17
|
+
const labelStyle: React.CSSProperties = fieldLabelStyle;
|
|
11
18
|
|
|
12
19
|
export function AudioSection({ entities, ids }: SectionProps) {
|
|
13
20
|
const store = useEditorStore();
|
|
@@ -72,7 +79,7 @@ export function AudioSection({ entities, ids }: SectionProps) {
|
|
|
72
79
|
{!multi && (
|
|
73
80
|
<div>
|
|
74
81
|
<div style={labelStyle}>Source</div>
|
|
75
|
-
<
|
|
82
|
+
<TextInput
|
|
76
83
|
value={audioData.src ?? ''}
|
|
77
84
|
placeholder="path/to/audio.mp3"
|
|
78
85
|
onChange={(e) => {
|
|
@@ -84,48 +91,30 @@ export function AudioSection({ entities, ids }: SectionProps) {
|
|
|
84
91
|
store.updateEntity(entity.id!, { audio: next });
|
|
85
92
|
}
|
|
86
93
|
}}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
background: '#1e1e1e',
|
|
90
|
-
color: '#c5c8ce',
|
|
91
|
-
border: '1px solid #333',
|
|
92
|
-
borderRadius: 2,
|
|
93
|
-
padding: '2px 4px',
|
|
94
|
-
fontSize: 11,
|
|
95
|
-
}}
|
|
94
|
+
className="vgai-input"
|
|
95
|
+
style={{ width: '100%' }}
|
|
96
96
|
/>
|
|
97
97
|
</div>
|
|
98
98
|
)}
|
|
99
99
|
|
|
100
100
|
{/* Preview — single entity only */}
|
|
101
101
|
{!multi && (
|
|
102
|
-
<
|
|
102
|
+
<Button
|
|
103
|
+
variant={playing ? 'danger' : 'secondary'}
|
|
104
|
+
size="compact"
|
|
103
105
|
onClick={togglePreview}
|
|
104
106
|
disabled={!audioData.src}
|
|
105
|
-
style={{
|
|
106
|
-
display: 'flex',
|
|
107
|
-
alignItems: 'center',
|
|
108
|
-
justifyContent: 'center',
|
|
109
|
-
gap: 4,
|
|
110
|
-
width: '100%',
|
|
111
|
-
padding: '3px 0',
|
|
112
|
-
background: playing ? '#3a2a2a' : '#2a2a2a',
|
|
113
|
-
color: !audioData.src ? '#555' : playing ? '#e06060' : '#c5c8ce',
|
|
114
|
-
border: `1px solid ${playing ? '#6a3a3a' : '#333'}`,
|
|
115
|
-
borderRadius: 2,
|
|
116
|
-
fontSize: 11,
|
|
117
|
-
cursor: audioData.src ? 'pointer' : 'default',
|
|
118
|
-
}}
|
|
107
|
+
style={{ width: '100%' }}
|
|
119
108
|
>
|
|
120
109
|
{playing ? '\u25A0 Stop' : '\u25B6 Preview'}
|
|
121
|
-
</
|
|
110
|
+
</Button>
|
|
122
111
|
)}
|
|
123
112
|
|
|
124
113
|
{/* Spatial */}
|
|
125
114
|
<div>
|
|
126
115
|
<div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
|
|
127
|
-
<
|
|
128
|
-
|
|
116
|
+
<Checkbox
|
|
117
|
+
className="vgai-checkbox"
|
|
129
118
|
checked={spatial ?? false}
|
|
130
119
|
ref={(el) => {
|
|
131
120
|
if (el) el.indeterminate = spatial === null;
|
|
@@ -133,7 +122,7 @@ export function AudioSection({ entities, ids }: SectionProps) {
|
|
|
133
122
|
onChange={(e) => update({ spatial: e.target.checked })}
|
|
134
123
|
/>
|
|
135
124
|
<Tooltip text="Positional 3D audio vs non-spatial background audio" position="right">
|
|
136
|
-
<span style={{ fontSize: 11, color:
|
|
125
|
+
<span style={{ fontSize: 11, color: themeVars.content.primary }}>Spatial</span>
|
|
137
126
|
</Tooltip>
|
|
138
127
|
</div>
|
|
139
128
|
</div>
|
|
@@ -183,30 +172,30 @@ export function AudioSection({ entities, ids }: SectionProps) {
|
|
|
183
172
|
{/* Loop */}
|
|
184
173
|
<div>
|
|
185
174
|
<div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
|
|
186
|
-
<
|
|
187
|
-
|
|
175
|
+
<Checkbox
|
|
176
|
+
className="vgai-checkbox"
|
|
188
177
|
checked={loop ?? false}
|
|
189
178
|
ref={(el) => {
|
|
190
179
|
if (el) el.indeterminate = loop === null;
|
|
191
180
|
}}
|
|
192
181
|
onChange={(e) => update({ loop: e.target.checked })}
|
|
193
182
|
/>
|
|
194
|
-
<span style={{ fontSize: 11, color:
|
|
183
|
+
<span style={{ fontSize: 11, color: themeVars.content.primary }}>Loop</span>
|
|
195
184
|
</div>
|
|
196
185
|
</div>
|
|
197
186
|
|
|
198
187
|
{/* Autoplay */}
|
|
199
188
|
<div>
|
|
200
189
|
<div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
|
|
201
|
-
<
|
|
202
|
-
|
|
190
|
+
<Checkbox
|
|
191
|
+
className="vgai-checkbox"
|
|
203
192
|
checked={autoplay ?? false}
|
|
204
193
|
ref={(el) => {
|
|
205
194
|
if (el) el.indeterminate = autoplay === null;
|
|
206
195
|
}}
|
|
207
196
|
onChange={(e) => update({ autoplay: e.target.checked })}
|
|
208
197
|
/>
|
|
209
|
-
<span style={{ fontSize: 11, color:
|
|
198
|
+
<span style={{ fontSize: 11, color: themeVars.content.primary }}>Autoplay</span>
|
|
210
199
|
</div>
|
|
211
200
|
</div>
|
|
212
201
|
</div>
|
|
@@ -1,22 +1,12 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { Button, SectionHeader, Select, TextInput, themeVars } from '../../design-system';
|
|
2
2
|
import { useEditorStore } from '../../EditorContext';
|
|
3
|
-
import {
|
|
3
|
+
import { fieldLabelStyle, mixedStyle } from '../inspector-widgets/shared';
|
|
4
4
|
import type { SectionProps } from './multi-edit-utils';
|
|
5
5
|
import { commonStr } from './multi-edit-utils';
|
|
6
6
|
|
|
7
|
-
const
|
|
8
|
-
width: '100%',
|
|
9
|
-
background: '#1e1e1e',
|
|
10
|
-
color: '#c5c8ce',
|
|
11
|
-
border: '1px solid #333',
|
|
12
|
-
borderRadius: 2,
|
|
13
|
-
padding: '3px 4px',
|
|
14
|
-
fontSize: 11,
|
|
15
|
-
};
|
|
7
|
+
const labelStyle: React.CSSProperties = fieldLabelStyle;
|
|
16
8
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
type BoneAttachment = NonNullable<SceneEntity['boneAttachment']>;
|
|
9
|
+
type BoneAttachment = NonNullable<SectionProps['entities'][number]['boneAttachment']>;
|
|
20
10
|
|
|
21
11
|
export function BoneAttachmentSection({ entities, ids }: SectionProps) {
|
|
22
12
|
const store = useEditorStore();
|
|
@@ -44,38 +34,43 @@ export function BoneAttachmentSection({ entities, ids }: SectionProps) {
|
|
|
44
34
|
<div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
|
|
45
35
|
<div>
|
|
46
36
|
<div style={labelStyle}>Target entity</div>
|
|
47
|
-
<
|
|
37
|
+
<Select
|
|
38
|
+
className="vgai-select"
|
|
48
39
|
value={target ?? ''}
|
|
49
40
|
onChange={(event) => update({ target: event.target.value })}
|
|
50
|
-
style={
|
|
41
|
+
style={{ width: '100%', ...mixedStyle(target === null) }}
|
|
51
42
|
>
|
|
52
|
-
{target === null && <option value=""
|
|
43
|
+
{target === null && <option value="">—</option>}
|
|
53
44
|
{targets.map((entity) => (
|
|
54
45
|
<option key={entity.id} value={entity.id}>
|
|
55
46
|
{entity.name}
|
|
56
47
|
</option>
|
|
57
48
|
))}
|
|
58
|
-
</
|
|
49
|
+
</Select>
|
|
59
50
|
</div>
|
|
60
51
|
<div>
|
|
61
52
|
<div style={labelStyle}>Bone / socket name</div>
|
|
62
|
-
<
|
|
53
|
+
<TextInput
|
|
54
|
+
className="vgai-input"
|
|
63
55
|
value={bone ?? ''}
|
|
64
56
|
placeholder="hand_r"
|
|
65
57
|
onChange={(event) => update({ bone: event.target.value })}
|
|
66
|
-
style={
|
|
58
|
+
style={{ width: '100%' }}
|
|
67
59
|
/>
|
|
68
60
|
</div>
|
|
69
|
-
<div style={{ fontSize: 10, color:
|
|
61
|
+
<div style={{ fontSize: 10, color: themeVars.content.dim }}>
|
|
70
62
|
Transform position, rotation, and scale are the local socket offsets.
|
|
71
63
|
</div>
|
|
72
|
-
<
|
|
64
|
+
<Button
|
|
73
65
|
type="button"
|
|
66
|
+
variant="danger"
|
|
74
67
|
onClick={remove}
|
|
75
|
-
|
|
68
|
+
// Real button chrome + themeVars.semantic.danger text (I-27: this used to wear the
|
|
69
|
+
// text-field style and read as an input with red text).
|
|
70
|
+
style={{ width: '100%' }}
|
|
76
71
|
>
|
|
77
72
|
Remove attachment
|
|
78
|
-
</
|
|
73
|
+
</Button>
|
|
79
74
|
</div>
|
|
80
75
|
</SectionHeader>
|
|
81
76
|
);
|