@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
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { showWorkspaceUtility } from '../workspace-dock-controller';
|
|
2
|
+
import { DEBUGGER_UTILITY_ID } from '../workspace-utility-commands';
|
|
3
|
+
|
|
4
|
+
export type DebuggerTabId = 'state' | 'profiler' | 'network' | 'machines' | 'commands';
|
|
5
|
+
|
|
6
|
+
let activeTab: DebuggerTabId = 'profiler';
|
|
7
|
+
let selectedMachineNodeId: string | null = null;
|
|
8
|
+
let version = 0;
|
|
9
|
+
const listeners = new Set<() => void>();
|
|
10
|
+
|
|
11
|
+
function notify(): void {
|
|
12
|
+
version++;
|
|
13
|
+
for (const listener of listeners) listener();
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function subscribeDebuggerPanel(listener: () => void): () => void {
|
|
17
|
+
listeners.add(listener);
|
|
18
|
+
return () => listeners.delete(listener);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function debuggerPanelVersion(): number {
|
|
22
|
+
return version;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function activeDebuggerTab(): DebuggerTabId {
|
|
26
|
+
return activeTab;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function debuggerMachineNodeId(): string | null {
|
|
30
|
+
return selectedMachineNodeId;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function setDebuggerTab(tab: DebuggerTabId, machineNodeId?: string): void {
|
|
34
|
+
const nextMachine = machineNodeId ?? selectedMachineNodeId;
|
|
35
|
+
if (activeTab === tab && selectedMachineNodeId === nextMachine) return;
|
|
36
|
+
activeTab = tab;
|
|
37
|
+
selectedMachineNodeId = nextMachine;
|
|
38
|
+
notify();
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function selectDebuggerMachine(nodeId: string): void {
|
|
42
|
+
if (selectedMachineNodeId === nodeId) return;
|
|
43
|
+
selectedMachineNodeId = nodeId;
|
|
44
|
+
notify();
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** Open one live-observation tool without replacing the document it observes. */
|
|
48
|
+
export function openDebuggerPanel(tab: DebuggerTabId, machineNodeId?: string): void {
|
|
49
|
+
setDebuggerTab(tab, machineNodeId);
|
|
50
|
+
showWorkspaceUtility(DEBUGGER_UTILITY_ID);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export function __resetDebuggerPanelForTest(): void {
|
|
54
|
+
activeTab = 'profiler';
|
|
55
|
+
selectedMachineNodeId = null;
|
|
56
|
+
notify();
|
|
57
|
+
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Button } from '../../design-system';
|
|
1
2
|
/**
|
|
2
3
|
* AlignmentGrid — a 3×3 flex `justify-content`×`align-items` picker (spec 27
|
|
3
4
|
* §5 C1). Ported from `visual-edit/inspector.tsx`'s `AlignmentGrid`
|
|
@@ -94,7 +95,7 @@ function AlignmentCell({
|
|
|
94
95
|
alignItems: 'center',
|
|
95
96
|
justifyContent: 'center',
|
|
96
97
|
cursor: disabled ? 'not-allowed' : 'pointer',
|
|
97
|
-
borderRadius:
|
|
98
|
+
borderRadius: THEME.radiusSmall,
|
|
98
99
|
background: isActive ? THEME.accent : 'transparent',
|
|
99
100
|
}}
|
|
100
101
|
>
|
|
@@ -103,7 +104,7 @@ function AlignmentCell({
|
|
|
103
104
|
width: isActive ? 6 : 4,
|
|
104
105
|
height: isActive ? 6 : 4,
|
|
105
106
|
borderRadius: '50%',
|
|
106
|
-
background: isActive ?
|
|
107
|
+
background: isActive ? THEME.onAccent : THEME.textMuted,
|
|
107
108
|
}}
|
|
108
109
|
/>
|
|
109
110
|
</div>
|
|
@@ -127,7 +128,7 @@ export function AlignmentGrid({
|
|
|
127
128
|
gridTemplateRows: 'repeat(3, 16px)',
|
|
128
129
|
gap: 1,
|
|
129
130
|
background: THEME.inputBg,
|
|
130
|
-
borderRadius:
|
|
131
|
+
borderRadius: THEME.radiusMedium,
|
|
131
132
|
padding: 4,
|
|
132
133
|
opacity: disabled ? 0.35 : 1,
|
|
133
134
|
}}
|
|
@@ -164,24 +165,17 @@ export function AnchorPresets({ onSelect, disabled }: AnchorPresetsProps): React
|
|
|
164
165
|
return (
|
|
165
166
|
<div data-testid="anchor-presets" style={{ display: 'flex', flexWrap: 'wrap', gap: 4 }}>
|
|
166
167
|
{Object.entries(ANCHOR_PRESETS).map(([name, preset]) => (
|
|
167
|
-
<
|
|
168
|
+
<Button
|
|
168
169
|
key={name}
|
|
169
170
|
type="button"
|
|
171
|
+
variant="secondary"
|
|
172
|
+
size="compact"
|
|
170
173
|
data-testid={`anchor-preset-${name}`}
|
|
171
174
|
disabled={disabled}
|
|
172
175
|
onClick={() => onSelect(name, preset)}
|
|
173
|
-
style={{
|
|
174
|
-
background: 'rgba(255,255,255,0.06)',
|
|
175
|
-
border: `1px solid ${THEME.border}`,
|
|
176
|
-
borderRadius: 3,
|
|
177
|
-
color: THEME.text,
|
|
178
|
-
fontSize: 10,
|
|
179
|
-
padding: '3px 6px',
|
|
180
|
-
cursor: disabled ? 'not-allowed' : 'pointer',
|
|
181
|
-
}}
|
|
182
176
|
>
|
|
183
177
|
{name}
|
|
184
|
-
</
|
|
178
|
+
</Button>
|
|
185
179
|
))}
|
|
186
180
|
</div>
|
|
187
181
|
);
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Button, Select } from '../../design-system';
|
|
1
2
|
/**
|
|
2
3
|
* BorderEditor (per-side width/style/color) + BorderRadiusEditor (per-corner)
|
|
3
4
|
* (spec 27 §5 C1). Ported from `visual-edit/inspector.tsx`'s `BorderEditor`
|
|
@@ -6,17 +7,12 @@
|
|
|
6
7
|
* radius is the common case; independent sides are one click away).
|
|
7
8
|
*/
|
|
8
9
|
|
|
10
|
+
import { faBorderAll, faBorderTopLeft } from '@fortawesome/free-solid-svg-icons';
|
|
9
11
|
import { useState } from 'react';
|
|
12
|
+
import { EditorIcon } from '../../design-system';
|
|
10
13
|
import { ColorSwatch } from './ColorPicker';
|
|
11
14
|
import { ScrubbableInput } from './ScrubbableInput';
|
|
12
|
-
import {
|
|
13
|
-
type ChangeHandlers,
|
|
14
|
-
fireChange,
|
|
15
|
-
fireEnd,
|
|
16
|
-
inputStyle,
|
|
17
|
-
miniButtonStyle,
|
|
18
|
-
THEME,
|
|
19
|
-
} from './shared';
|
|
15
|
+
import { type ChangeHandlers, fireChange, fireEnd, THEME } from './shared';
|
|
20
16
|
|
|
21
17
|
const BORDER_STYLES = ['none', 'solid', 'dashed', 'dotted', 'double'];
|
|
22
18
|
|
|
@@ -101,28 +97,34 @@ export function BorderEditor({
|
|
|
101
97
|
onChangeEnd={(v) => applyAll({ width: v }, true)}
|
|
102
98
|
style={{ width: 64 }}
|
|
103
99
|
/>
|
|
104
|
-
<
|
|
100
|
+
<Select
|
|
101
|
+
className="vgai-select"
|
|
105
102
|
data-testid="border-style"
|
|
106
103
|
value={value.top.style}
|
|
107
104
|
disabled={disabled}
|
|
108
105
|
onChange={(e) => applyAll({ style: e.target.value }, true)}
|
|
109
|
-
style={{
|
|
106
|
+
style={{
|
|
107
|
+
flex: 1,
|
|
108
|
+
...(disabled ? { background: THEME.dynamicBg, color: THEME.dynamic } : null),
|
|
109
|
+
}}
|
|
110
110
|
>
|
|
111
111
|
{BORDER_STYLES.map((o) => (
|
|
112
112
|
<option key={o} value={o}>
|
|
113
113
|
{o}
|
|
114
114
|
</option>
|
|
115
115
|
))}
|
|
116
|
-
</
|
|
117
|
-
<
|
|
116
|
+
</Select>
|
|
117
|
+
<Button
|
|
118
118
|
type="button"
|
|
119
119
|
data-testid="border-expand"
|
|
120
120
|
title="Per-side borders"
|
|
121
|
+
aria-label="Edit borders per side"
|
|
121
122
|
onClick={() => setExpanded(true)}
|
|
122
|
-
|
|
123
|
+
variant="ghost"
|
|
124
|
+
size="compact"
|
|
123
125
|
>
|
|
124
|
-
|
|
125
|
-
</
|
|
126
|
+
<EditorIcon icon={faBorderAll} />
|
|
127
|
+
</Button>
|
|
126
128
|
</div>
|
|
127
129
|
);
|
|
128
130
|
}
|
|
@@ -142,15 +144,17 @@ export function BorderEditor({
|
|
|
142
144
|
<div style={{ display: 'flex', alignItems: 'center', gap: 4 }}>
|
|
143
145
|
<span style={{ fontSize: 10, color: THEME.textMuted }}>Per-side</span>
|
|
144
146
|
<div style={{ flex: 1 }} />
|
|
145
|
-
<
|
|
147
|
+
<Button
|
|
146
148
|
type="button"
|
|
149
|
+
variant="primary"
|
|
150
|
+
size="compact"
|
|
147
151
|
data-testid="border-collapse"
|
|
148
152
|
title="Uniform border"
|
|
153
|
+
aria-label="Use one border for all sides"
|
|
149
154
|
onClick={() => setExpanded(false)}
|
|
150
|
-
style={{ ...miniButtonStyle, background: THEME.accent, color: '#fff' }}
|
|
151
155
|
>
|
|
152
|
-
|
|
153
|
-
</
|
|
156
|
+
<EditorIcon icon={faBorderAll} />
|
|
157
|
+
</Button>
|
|
154
158
|
</div>
|
|
155
159
|
{sides.map(({ key, label }) => (
|
|
156
160
|
<div key={key} style={{ display: 'flex', gap: 4, alignItems: 'center' }}>
|
|
@@ -176,16 +180,16 @@ export function BorderEditor({
|
|
|
176
180
|
onChangeEnd={(v) => applySide(key, { width: v }, true)}
|
|
177
181
|
style={{ width: 48 }}
|
|
178
182
|
/>
|
|
179
|
-
<
|
|
183
|
+
<Select
|
|
184
|
+
className="vgai-select"
|
|
180
185
|
data-testid={`border-${key}-style`}
|
|
181
186
|
value={value[key].style}
|
|
182
187
|
disabled={disabled}
|
|
183
188
|
onChange={(e) => applySide(key, { style: e.target.value }, true)}
|
|
184
189
|
style={{
|
|
185
|
-
...inputStyle(disabled),
|
|
186
190
|
flex: 1,
|
|
187
191
|
fontSize: 10,
|
|
188
|
-
|
|
192
|
+
...(disabled ? { background: THEME.dynamicBg, color: THEME.dynamic } : null),
|
|
189
193
|
}}
|
|
190
194
|
>
|
|
191
195
|
{BORDER_STYLES.map((o) => (
|
|
@@ -193,7 +197,7 @@ export function BorderEditor({
|
|
|
193
197
|
{o}
|
|
194
198
|
</option>
|
|
195
199
|
))}
|
|
196
|
-
</
|
|
200
|
+
</Select>
|
|
197
201
|
</div>
|
|
198
202
|
))}
|
|
199
203
|
</div>
|
|
@@ -243,7 +247,7 @@ export function BorderRadiusEditor({
|
|
|
243
247
|
>
|
|
244
248
|
<ScrubbableInput
|
|
245
249
|
testId="border-radius"
|
|
246
|
-
label="
|
|
250
|
+
label={<EditorIcon icon={faBorderTopLeft} label="Radius" />}
|
|
247
251
|
value={value.topLeft}
|
|
248
252
|
min={0}
|
|
249
253
|
disabled={disabled}
|
|
@@ -251,15 +255,17 @@ export function BorderRadiusEditor({
|
|
|
251
255
|
onChangeEnd={(v) => applyAll(v, true)}
|
|
252
256
|
style={{ flex: 1 }}
|
|
253
257
|
/>
|
|
254
|
-
<
|
|
258
|
+
<Button
|
|
255
259
|
type="button"
|
|
256
260
|
data-testid="border-radius-expand"
|
|
257
261
|
title="Independent corners"
|
|
262
|
+
aria-label="Edit radius per corner"
|
|
258
263
|
onClick={() => setExpanded(true)}
|
|
259
|
-
|
|
264
|
+
variant="ghost"
|
|
265
|
+
size="compact"
|
|
260
266
|
>
|
|
261
|
-
|
|
262
|
-
</
|
|
267
|
+
<EditorIcon icon={faBorderTopLeft} />
|
|
268
|
+
</Button>
|
|
263
269
|
</div>
|
|
264
270
|
);
|
|
265
271
|
}
|
|
@@ -274,17 +280,19 @@ export function BorderRadiusEditor({
|
|
|
274
280
|
return (
|
|
275
281
|
<div data-testid="border-radius-editor-expanded">
|
|
276
282
|
<div style={{ display: 'flex', alignItems: 'center', gap: 4, marginBottom: 4 }}>
|
|
277
|
-
<span style={{ fontSize: 10, color: THEME.textMuted }}
|
|
283
|
+
<span style={{ fontSize: 10, color: THEME.textMuted }}>Corners</span>
|
|
278
284
|
<div style={{ flex: 1 }} />
|
|
279
|
-
<
|
|
285
|
+
<Button
|
|
280
286
|
type="button"
|
|
287
|
+
variant="primary"
|
|
288
|
+
size="compact"
|
|
281
289
|
data-testid="border-radius-collapse"
|
|
282
290
|
title="Uniform radius"
|
|
291
|
+
aria-label="Use one radius for all corners"
|
|
283
292
|
onClick={() => setExpanded(false)}
|
|
284
|
-
style={{ ...miniButtonStyle, background: THEME.accent, color: '#fff' }}
|
|
285
293
|
>
|
|
286
|
-
|
|
287
|
-
</
|
|
294
|
+
<EditorIcon icon={faBorderTopLeft} />
|
|
295
|
+
</Button>
|
|
288
296
|
</div>
|
|
289
297
|
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 3 }}>
|
|
290
298
|
{corners.map(({ key, label }) => (
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Button, TextInput } from '../../design-system';
|
|
1
2
|
/**
|
|
2
3
|
* ColorPicker — HSV area + hue/alpha sliders, hex↔rgb↔hsl format cycle,
|
|
3
4
|
* eyedropper, recent colors (spec 27 §5 C1). Ported from
|
|
@@ -36,7 +37,7 @@ import {
|
|
|
36
37
|
rgbToHsv,
|
|
37
38
|
toHex,
|
|
38
39
|
} from './color-utils';
|
|
39
|
-
import {
|
|
40
|
+
import { FONT_MONO, fireChange, fireEnd, inputStyle, popoverStyle, THEME } from './shared';
|
|
40
41
|
|
|
41
42
|
const PICKER_W = 200;
|
|
42
43
|
const PICKER_H = 150;
|
|
@@ -306,9 +307,7 @@ export function ColorPicker({
|
|
|
306
307
|
data-testid="inspector-color-picker"
|
|
307
308
|
onMouseDown={(e) => e.stopPropagation()}
|
|
308
309
|
style={{
|
|
309
|
-
|
|
310
|
-
border: `1px solid ${THEME.border}`,
|
|
311
|
-
borderRadius: 6,
|
|
310
|
+
...popoverStyle,
|
|
312
311
|
padding: 10,
|
|
313
312
|
width: PICKER_W + 16,
|
|
314
313
|
boxSizing: 'border-box',
|
|
@@ -320,7 +319,7 @@ export function ColorPicker({
|
|
|
320
319
|
width={PICKER_W}
|
|
321
320
|
height={PICKER_H}
|
|
322
321
|
onMouseDown={(e) => beginDrag('sat', e)}
|
|
323
|
-
style={{ cursor: 'crosshair', borderRadius:
|
|
322
|
+
style={{ cursor: 'crosshair', borderRadius: THEME.radiusSmall, display: 'block' }}
|
|
324
323
|
/>
|
|
325
324
|
<canvas
|
|
326
325
|
ref={hueCanvasRef}
|
|
@@ -328,7 +327,12 @@ export function ColorPicker({
|
|
|
328
327
|
width={PICKER_W}
|
|
329
328
|
height={HUE_H}
|
|
330
329
|
onMouseDown={(e) => beginDrag('hue', e)}
|
|
331
|
-
style={{
|
|
330
|
+
style={{
|
|
331
|
+
cursor: 'pointer',
|
|
332
|
+
borderRadius: THEME.radiusSmall,
|
|
333
|
+
display: 'block',
|
|
334
|
+
marginTop: 6,
|
|
335
|
+
}}
|
|
332
336
|
/>
|
|
333
337
|
<canvas
|
|
334
338
|
ref={alphaCanvasRef}
|
|
@@ -336,20 +340,25 @@ export function ColorPicker({
|
|
|
336
340
|
width={PICKER_W}
|
|
337
341
|
height={HUE_H}
|
|
338
342
|
onMouseDown={(e) => beginDrag('alpha', e)}
|
|
339
|
-
style={{
|
|
343
|
+
style={{
|
|
344
|
+
cursor: 'pointer',
|
|
345
|
+
borderRadius: THEME.radiusSmall,
|
|
346
|
+
display: 'block',
|
|
347
|
+
marginTop: 6,
|
|
348
|
+
}}
|
|
340
349
|
/>
|
|
341
350
|
<div style={{ display: 'flex', gap: 6, alignItems: 'center', marginTop: 8 }}>
|
|
342
351
|
<div
|
|
343
352
|
style={{
|
|
344
353
|
width: 22,
|
|
345
354
|
height: 22,
|
|
346
|
-
borderRadius:
|
|
355
|
+
borderRadius: THEME.radiusSmall,
|
|
347
356
|
flexShrink: 0,
|
|
348
357
|
border: `1px solid ${THEME.border}`,
|
|
349
358
|
background: previewBg,
|
|
350
359
|
}}
|
|
351
360
|
/>
|
|
352
|
-
<
|
|
361
|
+
<TextInput
|
|
353
362
|
type="text"
|
|
354
363
|
data-testid="color-picker-text"
|
|
355
364
|
value={colorInput}
|
|
@@ -360,46 +369,29 @@ export function ColorPicker({
|
|
|
360
369
|
onBlur={handleColorInputSubmit}
|
|
361
370
|
style={{ ...inputStyle(), flex: 1, fontFamily: FONT_MONO, fontSize: 10 }}
|
|
362
371
|
/>
|
|
363
|
-
<
|
|
372
|
+
<Button
|
|
364
373
|
type="button"
|
|
374
|
+
variant="secondary"
|
|
375
|
+
size="compact"
|
|
365
376
|
data-testid="color-format-toggle"
|
|
366
377
|
onClick={cycleFormat}
|
|
367
378
|
title="Cycle color format"
|
|
368
|
-
style={{
|
|
369
|
-
background: 'rgba(255,255,255,0.06)',
|
|
370
|
-
border: 'none',
|
|
371
|
-
borderRadius: 3,
|
|
372
|
-
color: THEME.textMuted,
|
|
373
|
-
fontSize: 9,
|
|
374
|
-
fontWeight: 600,
|
|
375
|
-
padding: '3px 5px',
|
|
376
|
-
cursor: 'pointer',
|
|
377
|
-
flexShrink: 0,
|
|
378
|
-
fontFamily: FONT,
|
|
379
|
-
}}
|
|
379
|
+
style={{ flexShrink: 0 }}
|
|
380
380
|
>
|
|
381
381
|
{format.toUpperCase()}
|
|
382
|
-
</
|
|
382
|
+
</Button>
|
|
383
383
|
{(canEyedrop || eyedropperFallback || onEyedropperPick) && (
|
|
384
|
-
<
|
|
384
|
+
<Button
|
|
385
385
|
type="button"
|
|
386
|
+
variant="secondary"
|
|
387
|
+
size="compact"
|
|
386
388
|
data-testid="color-picker-eyedropper"
|
|
387
389
|
onClick={handleEyedropper}
|
|
388
390
|
title="Eyedropper"
|
|
389
|
-
style={{
|
|
390
|
-
background: 'rgba(255,255,255,0.06)',
|
|
391
|
-
border: 'none',
|
|
392
|
-
borderRadius: 3,
|
|
393
|
-
color: THEME.textMuted,
|
|
394
|
-
fontSize: 11,
|
|
395
|
-
padding: '3px 5px',
|
|
396
|
-
cursor: 'pointer',
|
|
397
|
-
flexShrink: 0,
|
|
398
|
-
lineHeight: 1,
|
|
399
|
-
}}
|
|
391
|
+
style={{ flexShrink: 0 }}
|
|
400
392
|
>
|
|
401
393
|
⌖
|
|
402
|
-
</
|
|
394
|
+
</Button>
|
|
403
395
|
)}
|
|
404
396
|
</div>
|
|
405
397
|
{recentColors && recentColors.length > 0 && (
|
|
@@ -428,7 +420,7 @@ export function ColorPicker({
|
|
|
428
420
|
style={{
|
|
429
421
|
width: 16,
|
|
430
422
|
height: 16,
|
|
431
|
-
borderRadius:
|
|
423
|
+
borderRadius: THEME.radiusSmall,
|
|
432
424
|
cursor: 'pointer',
|
|
433
425
|
background: rc,
|
|
434
426
|
border: `1px solid ${THEME.border}`,
|
|
@@ -474,7 +466,7 @@ export function ColorSwatch({
|
|
|
474
466
|
style={{
|
|
475
467
|
width: 20,
|
|
476
468
|
height: 20,
|
|
477
|
-
borderRadius:
|
|
469
|
+
borderRadius: THEME.radiusSmall,
|
|
478
470
|
flexShrink: 0,
|
|
479
471
|
background: hex,
|
|
480
472
|
border: `1px solid ${THEME.border}`,
|
|
@@ -485,7 +477,15 @@ export function ColorSwatch({
|
|
|
485
477
|
<span style={{ fontSize: 10, color: THEME.textMuted, flexShrink: 0 }}>{label}</span>
|
|
486
478
|
)}
|
|
487
479
|
{open && !disabled && (
|
|
488
|
-
<div
|
|
480
|
+
<div
|
|
481
|
+
style={{
|
|
482
|
+
position: 'absolute',
|
|
483
|
+
zIndex: 'var(--vgai-z-dropdown)',
|
|
484
|
+
top: '100%',
|
|
485
|
+
left: 0,
|
|
486
|
+
marginTop: 4,
|
|
487
|
+
}}
|
|
488
|
+
>
|
|
489
489
|
<ColorPicker
|
|
490
490
|
value={value}
|
|
491
491
|
onChange={onChange}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Button, TextInput } from '../../design-system';
|
|
1
2
|
/**
|
|
2
3
|
* FontPicker — a searchable, windowed (virtualized-by-hand, no new dep) font
|
|
3
4
|
* list (spec 27 §5 C1). Ported from `visual-edit/inspector.tsx`'s
|
|
@@ -10,7 +11,8 @@
|
|
|
10
11
|
*/
|
|
11
12
|
|
|
12
13
|
import { useEffect, useMemo, useRef, useState } from 'react';
|
|
13
|
-
import {
|
|
14
|
+
import { DisclosureIcon } from '../../design-system';
|
|
15
|
+
import { type ChangeHandlers, FONT, inputStyle, popoverStyle, THEME } from './shared';
|
|
14
16
|
|
|
15
17
|
const ITEM_HEIGHT = 28;
|
|
16
18
|
const MAX_VISIBLE = 10;
|
|
@@ -80,46 +82,36 @@ export function FontPicker({
|
|
|
80
82
|
|
|
81
83
|
return (
|
|
82
84
|
<div ref={containerRef} data-testid={testId} style={{ position: 'relative', flex: 1 }}>
|
|
83
|
-
<
|
|
85
|
+
<Button
|
|
84
86
|
type="button"
|
|
87
|
+
variant="secondary"
|
|
88
|
+
className="vgai-field-trigger"
|
|
89
|
+
disabled={disabled}
|
|
85
90
|
data-testid="font-picker-input"
|
|
86
91
|
onClick={() => {
|
|
87
92
|
if (!disabled) setOpen((v) => !v);
|
|
88
93
|
}}
|
|
89
|
-
style={{
|
|
90
|
-
...inputStyle(disabled),
|
|
91
|
-
width: '100%',
|
|
92
|
-
textAlign: 'left',
|
|
93
|
-
fontSize: 10,
|
|
94
|
-
fontFamily: FONT_MONO,
|
|
95
|
-
cursor: disabled ? 'not-allowed' : 'pointer',
|
|
96
|
-
display: 'flex',
|
|
97
|
-
alignItems: 'center',
|
|
98
|
-
justifyContent: 'space-between',
|
|
99
|
-
}}
|
|
100
94
|
>
|
|
101
95
|
<span style={{ overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
|
|
102
96
|
{displayValue || '—'}
|
|
103
97
|
</span>
|
|
104
|
-
<
|
|
105
|
-
</
|
|
98
|
+
<DisclosureIcon direction="down" tone="muted" style={{ marginLeft: 4 }} />
|
|
99
|
+
</Button>
|
|
106
100
|
{open && (
|
|
107
101
|
<div
|
|
108
102
|
data-testid="font-picker-dropdown"
|
|
109
103
|
style={{
|
|
104
|
+
...popoverStyle,
|
|
110
105
|
position: 'absolute',
|
|
111
106
|
top: '100%',
|
|
112
107
|
left: 0,
|
|
113
108
|
right: 0,
|
|
114
|
-
zIndex:
|
|
115
|
-
background: THEME.bg,
|
|
116
|
-
border: `1px solid ${THEME.border}`,
|
|
117
|
-
borderRadius: 4,
|
|
109
|
+
zIndex: 'var(--vgai-z-dropdown)',
|
|
118
110
|
marginTop: 2,
|
|
119
111
|
}}
|
|
120
112
|
>
|
|
121
113
|
<div style={{ padding: 4 }}>
|
|
122
|
-
<
|
|
114
|
+
<TextInput
|
|
123
115
|
ref={searchRef}
|
|
124
116
|
type="text"
|
|
125
117
|
data-testid="font-picker-search"
|
|
@@ -164,7 +156,7 @@ export function FontPicker({
|
|
|
164
156
|
cursor: 'pointer',
|
|
165
157
|
fontSize: 12,
|
|
166
158
|
background: isActive ? THEME.accent : 'transparent',
|
|
167
|
-
color: isActive ?
|
|
159
|
+
color: isActive ? THEME.onAccent : THEME.text,
|
|
168
160
|
}}
|
|
169
161
|
>
|
|
170
162
|
<span
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Button } from '../../design-system';
|
|
1
2
|
/**
|
|
2
3
|
* GradientEditor — solid/gradient toggle, stop list (add/remove/drag),
|
|
3
4
|
* linear/radial toggle, angle (spec 27 §5 C1). Ported from
|
|
@@ -151,7 +152,7 @@ export function GradientEditor({
|
|
|
151
152
|
data-testid="gradient-preview"
|
|
152
153
|
style={{
|
|
153
154
|
height: 20,
|
|
154
|
-
borderRadius:
|
|
155
|
+
borderRadius: THEME.radiusSmall,
|
|
155
156
|
border: `1px solid ${THEME.border}`,
|
|
156
157
|
background: composeGradient(value),
|
|
157
158
|
}}
|
|
@@ -212,35 +213,26 @@ export function GradientEditor({
|
|
|
212
213
|
/>
|
|
213
214
|
<span style={{ fontSize: 9, color: THEME.textMuted }}>Stop {selectedStop + 1}</span>
|
|
214
215
|
{value.stops.length > 2 && (
|
|
215
|
-
<
|
|
216
|
+
<Button
|
|
216
217
|
type="button"
|
|
218
|
+
variant="ghost"
|
|
219
|
+
size="compact"
|
|
220
|
+
aria-label="Remove gradient stop"
|
|
217
221
|
data-testid="gradient-remove-stop"
|
|
218
222
|
onClick={() => removeStop(selectedStop)}
|
|
219
|
-
style={{
|
|
220
|
-
background: 'none',
|
|
221
|
-
border: 'none',
|
|
222
|
-
color: THEME.textMuted,
|
|
223
|
-
cursor: 'pointer',
|
|
224
|
-
fontSize: 10,
|
|
225
|
-
}}
|
|
226
223
|
>
|
|
227
224
|
×
|
|
228
|
-
</
|
|
225
|
+
</Button>
|
|
229
226
|
)}
|
|
230
|
-
<
|
|
227
|
+
<Button
|
|
231
228
|
type="button"
|
|
229
|
+
variant="ghost"
|
|
230
|
+
size="compact"
|
|
232
231
|
data-testid="gradient-add-stop"
|
|
233
232
|
onClick={addStop}
|
|
234
|
-
style={{
|
|
235
|
-
background: 'none',
|
|
236
|
-
border: 'none',
|
|
237
|
-
color: THEME.accent,
|
|
238
|
-
cursor: 'pointer',
|
|
239
|
-
fontSize: 10,
|
|
240
|
-
}}
|
|
241
233
|
>
|
|
242
234
|
+ stop
|
|
243
|
-
</
|
|
235
|
+
</Button>
|
|
244
236
|
</div>
|
|
245
237
|
<div style={{ display: 'flex', gap: 6, alignItems: 'center' }}>
|
|
246
238
|
<div style={{ display: 'flex', gap: 1, flex: 1 }}>
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { TextInput } from '../../design-system';
|
|
1
2
|
/**
|
|
2
3
|
* ScrubbableInput — a numeric input whose LABEL is a drag-to-scrub handle
|
|
3
4
|
* (spec 27 §5 C1). Ported from `visual-edit/inspector.tsx`'s `ScrubbableInput`
|
|
@@ -11,11 +12,11 @@
|
|
|
11
12
|
* into whatever CSS string they write.
|
|
12
13
|
*/
|
|
13
14
|
|
|
14
|
-
import { useMemo, useRef } from 'react';
|
|
15
|
+
import { type ReactNode, useMemo, useRef } from 'react';
|
|
15
16
|
import { type ChangeHandlers, fireChange, fireEnd, inputStyle, rowStyle, THEME } from './shared';
|
|
16
17
|
|
|
17
18
|
export interface ScrubbableInputProps extends ChangeHandlers<number> {
|
|
18
|
-
label:
|
|
19
|
+
label: ReactNode;
|
|
19
20
|
unit?: string | undefined;
|
|
20
21
|
step?: number | undefined;
|
|
21
22
|
min?: number | undefined;
|
|
@@ -119,8 +120,10 @@ export function ScrubbableInput({
|
|
|
119
120
|
return (
|
|
120
121
|
<div style={{ ...rowStyle, ...extraStyle }}>
|
|
121
122
|
<span
|
|
123
|
+
className="vgai-scrub-label"
|
|
122
124
|
data-testid={testId ? `${testId}-label` : undefined}
|
|
123
125
|
onMouseDown={handleScrubStart}
|
|
126
|
+
data-disabled={disabled || undefined}
|
|
124
127
|
style={{
|
|
125
128
|
fontSize: 11,
|
|
126
129
|
color: disabled ? THEME.dynamic : THEME.textMuted,
|
|
@@ -132,7 +135,7 @@ export function ScrubbableInput({
|
|
|
132
135
|
>
|
|
133
136
|
{label}
|
|
134
137
|
</span>
|
|
135
|
-
<
|
|
138
|
+
<TextInput
|
|
136
139
|
data-testid={testId}
|
|
137
140
|
type="text"
|
|
138
141
|
value={`${value}${unit}`}
|