@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.
Files changed (430) hide show
  1. package/README.md +24 -0
  2. package/dist/assets/axe-C7YBtOuM.js +30 -0
  3. package/dist/assets/browserAll-DDtGGE48.js +1 -0
  4. package/dist/assets/create-runtime-DbTlBlKG.js +1 -0
  5. package/dist/assets/{game-BI111o5f.js → game-BE0r7DMI.js} +3 -3
  6. package/dist/assets/game-BdTHR2_X.js +1 -0
  7. package/dist/assets/{game-pt_1lQLv.js → game-C3iQGSqo.js} +1 -1
  8. package/dist/assets/game-CcHfYxjP.js +1 -0
  9. package/dist/assets/game-Cqzj_lpD.js +1 -0
  10. package/dist/assets/game-DSZdeCHu.js +1 -0
  11. package/dist/assets/game-Dch9sAPc.js +1 -0
  12. package/dist/assets/{game-xsOho_wg.js → game-SAFn90pA.js} +3 -3
  13. package/dist/assets/game-loop-DMIgSMV-.js +1 -0
  14. package/dist/assets/{game-source-CvidN7AB.js → game-source-Dk83w26t.js} +1 -1
  15. package/dist/assets/{index-Bp5cecD6.js → index-4idIsHHJ.js} +2 -2
  16. package/dist/assets/{index-DL7RcQ0n.js → index-C-LhOTBN.js} +1 -1
  17. package/dist/assets/{index-Cs8xwv3e.js → index-CDkxceqE.js} +1 -1
  18. package/dist/assets/index-CQEfi217.js +15412 -0
  19. package/dist/assets/index-Dvi-V0NE.css +1 -0
  20. package/dist/assets/ingest-siblings-s0P5I1Ub.js +1 -0
  21. package/dist/assets/mount-manifest-DXMOlF79.js +1 -0
  22. package/dist/assets/react-18-C9eHn8x1.js +1 -0
  23. package/dist/assets/webworkerAll-Fn0e-ouF.js +1 -0
  24. package/dist/assets/world-documents-GM0a9Kv7.js +1 -0
  25. package/dist/index.html +15 -13
  26. package/dist/ingest/racing-game/vgai.game.json +5 -4
  27. package/dist/ingest/simcity/vgai.game.json +5 -4
  28. package/dist/ingest/tanks/vgai.game.json +5 -4
  29. package/dist/project-scripts.bundle.js +3917 -0
  30. package/dist/scenes/untitled.vscn.json +2 -0
  31. package/dist-server/packaged.mjs +7697 -3435
  32. package/package.json +31 -4
  33. package/scripts/probe-reporter.ts +349 -0
  34. package/scripts/run-probe.ts +2260 -0
  35. package/server/asset-catalog-audit.ts +268 -0
  36. package/server/asset-catalog-v2.ts +146 -0
  37. package/server/asset-library-routes.ts +276 -58
  38. package/server/canonical-path.ts +1 -1
  39. package/server/dev.ts +148 -44
  40. package/server/editor-server.ts +888 -61
  41. package/server/editor-sse.ts +115 -4
  42. package/server/harness-chat-service.ts +796 -0
  43. package/server/local-asset-catalog.ts +157 -22
  44. package/server/packaged.ts +51 -21
  45. package/server/process-shutdown.ts +136 -0
  46. package/server/prod.ts +9 -6
  47. package/server/project-hmr-files.ts +41 -0
  48. package/server/project-operations.ts +343 -0
  49. package/server/project-optimize-deps-entries.ts +4 -4
  50. package/server/project-output-writer.ts +156 -0
  51. package/server/project-validation.ts +140 -0
  52. package/server/project-view.ts +8 -50
  53. package/server/server-utils.ts +75 -10
  54. package/server/session-registry.ts +12 -0
  55. package/src/EditorContext.tsx +107 -3
  56. package/src/action-registry.ts +115 -17
  57. package/src/adapter-resolver.ts +213 -478
  58. package/src/asset-events.ts +64 -1
  59. package/src/asset-preview.ts +906 -0
  60. package/src/asset-selection.ts +121 -0
  61. package/src/asset-workflow/asset-capabilities.ts +259 -0
  62. package/src/asset-workflow/asset-editor-errors.ts +46 -0
  63. package/src/asset-workflow/asset-import-pipeline.ts +176 -0
  64. package/src/asset-workflow/asset-library-query.ts +107 -0
  65. package/src/asset-workflow/asset-types.ts +192 -0
  66. package/src/asset-workflow/asset-workflow-quality.ts +65 -0
  67. package/src/asset-workflow/import-contract.ts +113 -0
  68. package/src/asset-workflow/model-conversion.ts +126 -0
  69. package/src/asset-workflow/model-inspection.ts +185 -0
  70. package/src/asset-workflow/project-asset-commands.ts +23 -0
  71. package/src/asset-workflow/project-asset-health.ts +153 -0
  72. package/src/asset-workflow/project-asset-operations.ts +119 -0
  73. package/src/asset-workflow/thumbnail-system.ts +172 -0
  74. package/src/authoring/active-systems.ts +15 -0
  75. package/src/authoring/boundary-authoring-adapter.ts +16 -5
  76. package/src/authoring/composite-authoring-adapter.ts +305 -124
  77. package/src/authoring/design-time-layers.ts +300 -117
  78. package/src/authoring/edit-mode-authoring.ts +278 -293
  79. package/src/authoring/embed-only-adapter.ts +4 -2
  80. package/src/authoring/first-party-hierarchy-menu.ts +7 -2
  81. package/src/authoring/first-party-inspector/AddSectionMenu.tsx +5 -12
  82. package/src/authoring/first-party-inspector/EnvironmentSection.tsx +53 -126
  83. package/src/authoring/first-party-inspector/HeaderSection.tsx +54 -65
  84. package/src/authoring/first-party-inspector/is-first-party-selection.ts +30 -11
  85. package/src/authoring/first-party-inspector/register.tsx +13 -2
  86. package/src/authoring/ingest-authoring-adapter.ts +142 -45
  87. package/src/authoring/mount-failure-report.ts +5 -5
  88. package/src/authoring/provenance.ts +41 -0
  89. package/src/authoring/react-dom-authoring-adapter.ts +92 -92
  90. package/src/authoring/react-inspector-section.tsx +489 -51
  91. package/src/authoring/react-world-authoring-adapter.ts +541 -306
  92. package/src/authoring/story-overlay.ts +1 -1
  93. package/src/authoring/story-types.ts +11 -0
  94. package/src/authoring/vgai-scene-authoring-adapter.ts +54 -25
  95. package/src/authoring/viewport-tool-context.ts +78 -0
  96. package/src/authoring/world-canvas-viewport-state.ts +35 -0
  97. package/src/authoring/world-hidden-viewport.ts +186 -0
  98. package/src/authoring/world-pan-state.ts +33 -17
  99. package/src/authoring/world-session-state.ts +1 -1
  100. package/src/authoring/world2d-authoring-adapter.ts +109 -52
  101. package/src/availability-tick.ts +56 -0
  102. package/src/browser-play-entry.ts +5 -5
  103. package/src/browser-project-scripts.ts +1 -0
  104. package/src/build-identity.ts +15 -0
  105. package/src/command-listener.ts +893 -19
  106. package/src/components/AlignToolbar.tsx +74 -63
  107. package/src/components/AppRoot.tsx +193 -26
  108. package/src/components/ApplicationMenus.tsx +272 -0
  109. package/src/components/AssetBrowser.tsx +1450 -293
  110. package/src/components/AssetEditorShell.tsx +141 -0
  111. package/src/components/AssetImportDetails.tsx +218 -0
  112. package/src/components/AssetLibraryPanel.tsx +14 -0
  113. package/src/components/CameraInfo.tsx +11 -20
  114. package/src/components/CenterDocuments.tsx +585 -0
  115. package/src/components/CommandPalette.tsx +75 -30
  116. package/src/components/ConsolePanel.css +55 -0
  117. package/src/components/ConsolePanel.tsx +57 -112
  118. package/src/components/DebugConsolePanel.tsx +461 -0
  119. package/src/components/DebuggerPanel.tsx +165 -0
  120. package/src/components/DefaultEditorLayout.tsx +167 -231
  121. package/src/components/GameHierarchy.tsx +873 -290
  122. package/src/components/GamePerformanceOverlay.tsx +46 -0
  123. package/src/components/HarnessChatPanel.tsx +2352 -0
  124. package/src/components/HistoryPanel.tsx +226 -0
  125. package/src/components/Inspector.tsx +153 -99
  126. package/src/components/InspectorToolSection.tsx +6 -4
  127. package/src/components/MountFailureBanner.tsx +31 -48
  128. package/src/components/NetworkSection.tsx +25 -14
  129. package/src/components/OnlineAssetBrowser.tsx +794 -343
  130. package/src/components/OverlayReportBanner.tsx +38 -64
  131. package/src/components/PerformancePanel.tsx +206 -0
  132. package/src/components/PlayBar.tsx +93 -263
  133. package/src/components/PrefabSaveDialog.tsx +55 -127
  134. package/src/components/ProjectHeader.css +60 -0
  135. package/src/components/ProjectHeader.tsx +170 -105
  136. package/src/components/ProjectScreen.tsx +246 -184
  137. package/src/components/ReactCanvasControls.tsx +185 -0
  138. package/src/components/ResolutionPicker.tsx +85 -0
  139. package/src/components/RootActivateDialog.tsx +39 -68
  140. package/src/components/SaveDialog.tsx +55 -127
  141. package/src/components/SaveStatus.tsx +11 -29
  142. package/src/components/StartupLoadingScreen.tsx +96 -0
  143. package/src/components/StateWatchPanel.tsx +302 -0
  144. package/src/components/StatsOverlay.tsx +12 -5
  145. package/src/components/StatusBar.tsx +64 -0
  146. package/src/components/ThemeManagerDialog.css +89 -0
  147. package/src/components/ThemeManagerDialog.tsx +371 -0
  148. package/src/components/ToolHost.tsx +26 -15
  149. package/src/components/Toolbar.tsx +117 -214
  150. package/src/components/VgaiVoxelLogo.tsx +89 -0
  151. package/src/components/ViewportOverlay.tsx +97 -172
  152. package/src/components/ViewportPanel.tsx +130 -31
  153. package/src/components/WorkspaceDock.tsx +891 -0
  154. package/src/components/WorldSelectionOverlay.tsx +51 -63
  155. package/src/components/WorldTextEditor.tsx +9 -5
  156. package/src/components/asset-documents.tsx +390 -0
  157. package/src/components/asset-editor-persistence.ts +44 -0
  158. package/src/components/asset-selection-section.tsx +338 -0
  159. package/src/components/asset-viewers/AudioViewer.tsx +73 -21
  160. package/src/components/asset-viewers/GenericJsonViewer.tsx +26 -11
  161. package/src/components/asset-viewers/ImageViewer.tsx +43 -11
  162. package/src/components/asset-viewers/InputMapViewer.tsx +512 -134
  163. package/src/components/asset-viewers/MaterialAssetEditor.tsx +540 -0
  164. package/src/components/asset-viewers/ModelViewer.tsx +805 -121
  165. package/src/components/asset-viewers/OnlineAssetDetail.tsx +177 -60
  166. package/src/components/asset-viewers/SourceAssetViewer.tsx +121 -0
  167. package/src/components/asset-workflow.css +506 -0
  168. package/src/components/build-documents.tsx +696 -0
  169. package/src/components/core-utilities.tsx +75 -0
  170. package/src/components/data-documents.tsx +364 -0
  171. package/src/components/{DataPanel.tsx → data-editor.tsx} +138 -288
  172. package/src/components/debugger-panel-state.ts +57 -0
  173. package/src/components/inspector-widgets/AlignmentGrid.tsx +8 -14
  174. package/src/components/inspector-widgets/BorderEditor.tsx +41 -33
  175. package/src/components/inspector-widgets/ColorPicker.tsx +39 -39
  176. package/src/components/inspector-widgets/FontPicker.tsx +13 -21
  177. package/src/components/inspector-widgets/GradientEditor.tsx +11 -19
  178. package/src/components/inspector-widgets/ScrubbableInput.tsx +6 -3
  179. package/src/components/inspector-widgets/ShadowEditor.tsx +20 -33
  180. package/src/components/inspector-widgets/shared.tsx +90 -49
  181. package/src/components/inspectors/AnimationSection.tsx +39 -40
  182. package/src/components/inspectors/AudioSection.tsx +28 -39
  183. package/src/components/inspectors/BoneAttachmentSection.tsx +19 -24
  184. package/src/components/inspectors/CameraSection.tsx +14 -23
  185. package/src/components/inspectors/ComponentsSection.tsx +39 -43
  186. package/src/components/inspectors/JointsSection.tsx +34 -43
  187. package/src/components/inspectors/LightSection.tsx +90 -35
  188. package/src/components/inspectors/MaterialSection.tsx +137 -174
  189. package/src/components/inspectors/MeshSection.tsx +9 -17
  190. package/src/components/inspectors/NavigationSection.tsx +8 -15
  191. package/src/components/inspectors/ParticleSection.tsx +91 -76
  192. package/src/components/inspectors/PhysicsSection.tsx +42 -46
  193. package/src/components/inspectors/PostProcessingSection.tsx +28 -36
  194. package/src/components/inspectors/RenderingSection.tsx +12 -20
  195. package/src/components/inspectors/ShadowSection.tsx +7 -8
  196. package/src/components/inspectors/SplineSection.tsx +31 -42
  197. package/src/components/inspectors/TransformSection.tsx +14 -22
  198. package/src/components/patterns/Dialog.tsx +95 -0
  199. package/src/components/patterns/Fields.tsx +44 -0
  200. package/src/components/patterns/List.tsx +25 -0
  201. package/src/components/patterns/StateSurface.tsx +40 -0
  202. package/src/components/patterns/Surfaces.tsx +115 -0
  203. package/src/components/patterns/Tabs.tsx +80 -0
  204. package/src/components/patterns/Toolbar.tsx +51 -0
  205. package/src/components/patterns/Tree.tsx +72 -0
  206. package/src/components/primitives/Button.tsx +46 -0
  207. package/src/components/primitives/ColorInput.tsx +11 -47
  208. package/src/components/primitives/EditorIcon.tsx +99 -0
  209. package/src/components/primitives/FormControls.tsx +71 -0
  210. package/src/components/primitives/JsonInput.tsx +15 -2
  211. package/src/components/primitives/Layout.tsx +100 -0
  212. package/src/components/primitives/Menu.tsx +105 -0
  213. package/src/components/primitives/NumberInput.tsx +8 -35
  214. package/src/components/primitives/Panel.tsx +49 -44
  215. package/src/components/primitives/SectionHeader.tsx +10 -28
  216. package/src/components/primitives/Text.tsx +46 -0
  217. package/src/components/primitives/Tooltip.tsx +20 -12
  218. package/src/components/primitives/Vec3Input.tsx +3 -0
  219. package/src/components/primitives/banner-tones.ts +33 -0
  220. package/src/components/primitives/editor-icons.ts +102 -0
  221. package/src/components/primitives/panel-header-styles.ts +30 -0
  222. package/src/components/project-operation-documents.tsx +226 -0
  223. package/src/components/status-contributions.tsx +175 -0
  224. package/src/components/story-documents-register.ts +15 -0
  225. package/src/components/story-documents.tsx +1185 -0
  226. package/src/components/tool-documents.tsx +110 -0
  227. package/src/components/workspace-dock.css +293 -0
  228. package/src/components/workspace-history.ts +33 -0
  229. package/src/components/world-documents.tsx +145 -0
  230. package/src/components/xstate-documents.tsx +209 -0
  231. package/src/composite-screenshot.ts +248 -0
  232. package/src/design-system/index.ts +70 -0
  233. package/src/design-system-stories/Foundation.stories.tsx +183 -0
  234. package/src/design-system-stories/Patterns.stories.tsx +251 -0
  235. package/src/design-system-stories/Workspace.stories.tsx +538 -0
  236. package/src/doctor/report.ts +57 -13
  237. package/src/editor-api.ts +295 -31
  238. package/src/editor-compatibility.ts +200 -0
  239. package/src/editor-console.ts +35 -17
  240. package/src/editor-hotkeys.ts +85 -33
  241. package/src/editor-store.ts +538 -233
  242. package/src/editor-viewport.ts +160 -34
  243. package/src/entity-factory.ts +14 -3
  244. package/src/gizmo-registry.ts +21 -5
  245. package/src/harness-chat-editor-context.ts +37 -0
  246. package/src/harness-chat-indicator.ts +68 -0
  247. package/src/harness-chat-layout.ts +53 -0
  248. package/src/harness-chat-lifecycle.ts +170 -0
  249. package/src/harness-chat-reconnect.ts +85 -0
  250. package/src/harness-chat-types.ts +409 -0
  251. package/src/hierarchy-drop.ts +50 -0
  252. package/src/hierarchy-expansion-state.ts +100 -0
  253. package/src/hierarchy-menu-registry.ts +1 -1
  254. package/src/hierarchy-projection.ts +76 -0
  255. package/src/history/editor-session.ts +21 -0
  256. package/src/history/history-commands.ts +147 -0
  257. package/src/history/history-service.ts +904 -0
  258. package/src/history/json-history-resource.ts +165 -0
  259. package/src/history/persistence-coordinator.ts +35 -0
  260. package/src/history/project-file-history.ts +266 -0
  261. package/src/history/project-root-history-backends.ts +53 -0
  262. package/src/history/resource-registry.ts +209 -0
  263. package/src/history/snapshot-store.ts +108 -0
  264. package/src/history/source-history-backend.ts +374 -0
  265. package/src/history/types.ts +100 -0
  266. package/src/hmr-registration-group.ts +67 -0
  267. package/src/hmr-stable-react-context.ts +23 -0
  268. package/src/hosted-example.ts +12 -2
  269. package/src/hotkeys.ts +89 -18
  270. package/src/ingest/discovery-react.ts +9 -10
  271. package/src/ingest/discovery.ts +4 -4
  272. package/src/ingest/discovery2d.ts +5 -5
  273. package/src/ingest/games/bloom-composer/vgai.game.json +3 -3
  274. package/src/ingest/games/embed-bundle/vgai.game.json +3 -3
  275. package/src/ingest/games/games-fps/vgai.game.json +3 -3
  276. package/src/ingest/games/iframe-reachable/vgai.game.json +3 -3
  277. package/src/ingest/games/interactive-cubes/vgai.game.json +3 -3
  278. package/src/ingest/games/mismatched-three/vgai.game.json +3 -3
  279. package/src/ingest/games/own-three-bundled/vgai.game.json +3 -3
  280. package/src/ingest/games/pointerlock-maze/vgai.game.json +7 -4
  281. package/src/ingest/games-2d/bubbo-bubbo/vgai.game.json +3 -3
  282. package/src/ingest/games-2d/bunnymark/vgai.game.json +3 -3
  283. package/src/ingest/games-2d/flappy/vgai.game.json +3 -3
  284. package/src/ingest/games-2d/flappy-pixi/vgai.game.json +3 -3
  285. package/src/ingest/games-2d/puzzling-potions/vgai.game.json +3 -3
  286. package/src/ingest/games-2d/tilemap-camera/vgai.game.json +3 -3
  287. package/src/ingest/games-react/react-rpg/vgai.game.json +3 -3
  288. package/src/ingest/types.ts +1 -1
  289. package/src/ingest-mode.ts +47 -52
  290. package/src/ingest-siblings.ts +23 -33
  291. package/src/initial-scene.ts +1 -2
  292. package/src/main.tsx +16 -8
  293. package/src/manifest-project.ts +10 -12
  294. package/src/model-thumbnail.ts +261 -26
  295. package/src/module-mode.ts +44 -50
  296. package/src/play-log-events.ts +26 -0
  297. package/src/play-mode.ts +495 -401
  298. package/src/play-scene-adoption.ts +23 -0
  299. package/src/playground/main.ts +68 -24
  300. package/src/playwright-shim.ts +473 -0
  301. package/src/project-manager.ts +90 -10
  302. package/src/project-operations.ts +112 -0
  303. package/src/project-story-discovery.ts +25 -0
  304. package/src/project-tool-discovery.ts +43 -0
  305. package/src/scene-serializer.ts +0 -6
  306. package/src/scene-sync.ts +7 -2
  307. package/src/script-loader.ts +3 -3
  308. package/src/skeleton-helper.ts +57 -0
  309. package/src/storage/seed.ts +68 -8
  310. package/src/stories/StoryPreviewMount.tsx +265 -0
  311. package/src/stories/action-stories.fixture.tsx +44 -0
  312. package/src/stories/button-stories.fixture.tsx +50 -0
  313. package/src/stories/compose-project-stories.ts +182 -0
  314. package/src/stories/loader-stories.fixture.tsx +53 -0
  315. package/src/stories/story-discovery.ts +130 -0
  316. package/src/stories/story-registry.ts +146 -0
  317. package/src/theme-css.ts +1049 -0
  318. package/src/theme-library.ts +238 -0
  319. package/src/theme-preference.ts +130 -0
  320. package/src/theme.ts +527 -0
  321. package/src/tool-loader.ts +80 -24
  322. package/src/ui-source/inspect.ts +27 -4
  323. package/src/ui-source/source-write-backend.ts +83 -22
  324. package/src/widgets/index.ts +9 -18
  325. package/src/workspace-aux-commands.ts +11 -0
  326. package/src/workspace-dock-controller.ts +64 -0
  327. package/src/workspace-document-ids.ts +5 -0
  328. package/src/workspace-document-registry.ts +367 -0
  329. package/src/workspace-state-persistence.ts +455 -0
  330. package/src/workspace-status-registry.ts +110 -0
  331. package/src/workspace-utility-commands.ts +49 -0
  332. package/src/workspace-utility-registry.ts +161 -0
  333. package/src/world-document-routing.ts +16 -0
  334. package/src/xstate-inspect/XStateMachineInspector.tsx +544 -0
  335. package/src/xstate-inspect/character-animation-machine.fixture.ts +74 -0
  336. package/src/xstate-inspect/use-live-actor-state.ts +39 -0
  337. package/src/xstate-inspect/xstate-graph.ts +265 -0
  338. package/src/xstate-inspect/xstate-layout.ts +76 -0
  339. package/src/z-index.ts +26 -0
  340. package/template/.claude/skills/editor/SKILL.md +129 -90
  341. package/template/AGENTS.md +1110 -0
  342. package/template/CLAUDE.md +1 -512
  343. package/template/IDIOMS.md +50 -0
  344. package/template/check-idioms.ts +706 -0
  345. package/template/manifest-entry-modules-plugin.ts +53 -0
  346. package/template/package.json +13 -4
  347. package/template/public/scenes/default.scn2d.json +6 -0
  348. package/template/public/scenes/default.vscn.json +7 -1
  349. package/template/public/scenes/untitled.vscn.json +10 -0
  350. package/template/scripts/playtest.ts +40 -0
  351. package/template/server/loopback.ts +75 -0
  352. package/template/server/rooms/arena-room.ts +69 -1
  353. package/template/server/rooms/game-room.ts +68 -1
  354. package/template/src/data/README.md +9 -4
  355. package/template/src/data/data-ref.ts +35 -0
  356. package/template/src/data/tuning.schema.ts +1 -1
  357. package/template/src/main.ts +41 -62
  358. package/template/src/manifest-entry-modules.d.ts +3 -0
  359. package/template/src/operations/README.md +88 -0
  360. package/template/src/runtime/pixi-adapter.ts +24 -0
  361. package/template/src/scripts/components/data-spinner.ts +43 -2
  362. package/template/src/scripts/components/spin-lap-math.ts +27 -0
  363. package/template/src/tools/README.md +5 -3
  364. package/template/src/tools/example.tool.tsx +13 -7
  365. package/template/src/ui/Button.stories.tsx +66 -0
  366. package/template/src/ui/RebindPanel.tsx +2 -6
  367. package/template/src/ui/game.tsx +17 -0
  368. package/template/tests/acceptance/example.spec.ts +64 -0
  369. package/template/tests/logic/example.test.ts +31 -0
  370. package/template/tests/logic/room.test.ts +100 -0
  371. package/template/tests/tsconfig.json +30 -0
  372. package/template/validate-manifest.ts +5 -5
  373. package/template/validate-scenes.ts +50 -18
  374. package/template/vgai.game.json +20 -13
  375. package/template/vite.config.ts +77 -16
  376. package/vite-plugin-ui-oid.ts +261 -17
  377. package/dist/assets/CCDIKSolver-Dz-ysxZF.js +0 -1
  378. package/dist/assets/SelectionBox-BXsv_6aH.js +0 -1
  379. package/dist/assets/browser-project-scripts-DOru4L1x.js +0 -2
  380. package/dist/assets/browserAll-CEkWYlFk.js +0 -1
  381. package/dist/assets/create-runtime-DYIWr3va.js +0 -1
  382. package/dist/assets/data-asset-Bb9sIM7i.js +0 -5
  383. package/dist/assets/game-8SDZPPgH.js +0 -1
  384. package/dist/assets/game-CevorxyV.js +0 -1
  385. package/dist/assets/game-Di7XlywD.js +0 -1
  386. package/dist/assets/game-DjnCaw8R.js +0 -1
  387. package/dist/assets/game-Q9A0aXSV.js +0 -1
  388. package/dist/assets/index-CPVV6pjw.js +0 -1
  389. package/dist/assets/index-CpOnYyeD.js +0 -213
  390. package/dist/assets/index-Dr8H_6Rl.js +0 -1
  391. package/dist/assets/index-_bCaipUk.js +0 -13650
  392. package/dist/assets/ingest-siblings-Dz8eEqrV.js +0 -1
  393. package/dist/assets/mount-manifest-Bhk0ohsl.js +0 -1
  394. package/dist/assets/scene-query-BivAHhJu.js +0 -1
  395. package/dist/assets/webworkerAll-BLrH0F6F.js +0 -1
  396. package/dist/assets/xstate-animation-binding-1NGLmw6y.js +0 -1
  397. package/dist/assets/xstate.esm-BgUD33nl.js +0 -3
  398. package/src/authoring/scene-ui-layer.ts +0 -485
  399. package/src/authoring/ui-authoring-adapter.ts +0 -325
  400. package/src/authoring/ui-hierarchy-menu.ts +0 -40
  401. package/src/authoring/ui-inspector-sections.tsx +0 -156
  402. package/src/authoring/undo-timeline.ts +0 -145
  403. package/src/components/BottomPanel.tsx +0 -326
  404. package/src/components/BuildPanel.tsx +0 -455
  405. package/src/components/FolderTree.tsx +0 -179
  406. package/src/components/RightPanel.tsx +0 -166
  407. package/src/components/WorldContextMenu.tsx +0 -257
  408. package/src/components/asset-viewers/AssetViewer.tsx +0 -38
  409. package/src/ingest/games-react/react-rpg/src/ui/game-state.tsx +0 -129
  410. package/src/scene-ui-mode/active-scene-ui.ts +0 -58
  411. package/src/scene-ui-mode/scene-ui-palette-panel.tsx +0 -152
  412. package/src/scene-ui-mode/scene-ui-timeline-tab.tsx +0 -29
  413. package/src/scene-ui-mode/ui-prefab-dialog-host.tsx +0 -74
  414. package/src/scene-ui-mode/ui-prefab-hierarchy-menu.ts +0 -49
  415. package/src/scene-ui-mode/ui-prefab-io.ts +0 -76
  416. package/src/ui-editor/inspector.tsx +0 -563
  417. package/src/ui-editor/node-ops.ts +0 -266
  418. package/src/ui-editor/overlay.tsx +0 -380
  419. package/src/ui-editor/palette.tsx +0 -114
  420. package/src/ui-editor/react-store.ts +0 -78
  421. package/src/ui-editor/timeline-panel.tsx +0 -443
  422. package/src/ui-editor/ui-edit-store.ts +0 -552
  423. package/src/ui-editor/ui-prefab.ts +0 -95
  424. package/template/project.json +0 -9
  425. package/template/src/scripts/main.ts +0 -94
  426. package/template/src/ui/DefaultHud.tsx +0 -40
  427. package/template/src/ui/game-state.tsx +0 -37
  428. package/template/src/ui/mount-default-hud.tsx +0 -19
  429. package/template/src/ui/mount-ui.ts +0 -15
  430. package/vite-plugin-react-world-provider.ts +0 -81
@@ -1,5 +1,6 @@
1
1
  import { useEffect, useState } from 'react';
2
2
  import { useInteractiveEditScope } from '../../interactive-edit-scope';
3
+ import { ColorSwatchInput, TextInput } from './FormControls';
3
4
 
4
5
  interface ColorInputProps {
5
6
  value: string | null;
@@ -25,43 +26,24 @@ export function ColorInput({ value, onChange }: ColorInputProps) {
25
26
 
26
27
  if (value === null) {
27
28
  return (
28
- <div style={{ display: 'flex', alignItems: 'center', gap: 4 }}>
29
- <div
30
- style={{
31
- width: 28,
32
- height: 22,
33
- border: '1px solid #333',
34
- borderRadius: 2,
35
- background:
36
- 'linear-gradient(45deg, #666 25%, transparent 25%, transparent 75%, #666 75%), linear-gradient(45deg, #666 25%, transparent 25%, transparent 75%, #666 75%)',
37
- backgroundSize: '8px 8px',
38
- backgroundPosition: '0 0, 4px 4px',
39
- }}
40
- />
41
- <input
42
- placeholder="mixed"
29
+ <div className="vgai-color-input">
30
+ <div className="vgai-color-input-mixed" />
31
+ <TextInput
32
+ // Mixed-value language unified on the em-dash (I-15), matching
33
+ // NumberInput's mixed display.
34
+ placeholder="—"
43
35
  onChange={(e) => {
44
36
  if (e.target.value) onChange(e.target.value);
45
37
  }}
46
- style={{
47
- flex: 1,
48
- background: '#1e1e1e',
49
- color: '#666',
50
- fontStyle: 'italic',
51
- border: '1px solid #333',
52
- borderRadius: 2,
53
- padding: '2px 4px',
54
- fontSize: 12,
55
- }}
38
+ data-mixed="true"
56
39
  />
57
40
  </div>
58
41
  );
59
42
  }
60
43
 
61
44
  return (
62
- <div style={{ display: 'flex', alignItems: 'center', gap: 4 }}>
63
- <input
64
- type="color"
45
+ <div className="vgai-color-input">
46
+ <ColorSwatchInput
65
47
  value={value}
66
48
  // The native picker fires onChange continuously while dragging. Coalesce
67
49
  // the whole drag into one undo step (beginInteractiveEdit is idempotent);
@@ -71,17 +53,8 @@ export function ColorInput({ value, onChange }: ColorInputProps) {
71
53
  onChange(e.target.value);
72
54
  }}
73
55
  onBlur={() => editScope?.end()}
74
- style={{
75
- width: 28,
76
- height: 22,
77
- border: '1px solid #333',
78
- borderRadius: 2,
79
- padding: 0,
80
- cursor: 'pointer',
81
- background: 'transparent',
82
- }}
83
56
  />
84
- <input
57
+ <TextInput
85
58
  value={draft}
86
59
  onChange={(e) => setDraft(e.target.value)}
87
60
  onBlur={commit}
@@ -94,15 +67,6 @@ export function ColorInput({ value, onChange }: ColorInputProps) {
94
67
  (e.target as HTMLInputElement).blur();
95
68
  }
96
69
  }}
97
- style={{
98
- flex: 1,
99
- background: '#1e1e1e',
100
- color: '#c5c8ce',
101
- border: '1px solid #333',
102
- borderRadius: 2,
103
- padding: '2px 4px',
104
- fontSize: 12,
105
- }}
106
70
  />
107
71
  </div>
108
72
  );
@@ -0,0 +1,99 @@
1
+ import type { IconDefinition } from '@fortawesome/fontawesome-svg-core';
2
+ import {
3
+ faCaretDown,
4
+ faCaretRight,
5
+ faChevronDown,
6
+ faChevronRight,
7
+ } from '@fortawesome/free-solid-svg-icons';
8
+ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
9
+ import type React from 'react';
10
+ import { themeVars } from '../../theme';
11
+
12
+ export type EditorIconSize = 'xs' | 'sm' | 'md' | 'lg';
13
+ export type EditorIconTone = 'current' | 'primary' | 'muted' | 'dim' | 'accent' | 'danger';
14
+
15
+ const SIZE: Record<EditorIconSize, string> = {
16
+ xs: 'var(--vgai-font-xs)',
17
+ sm: 'var(--vgai-font-sm)',
18
+ md: 'var(--vgai-font-md)',
19
+ lg: 'var(--vgai-font-lg)',
20
+ };
21
+
22
+ const TONE: Record<EditorIconTone, string | undefined> = {
23
+ current: undefined,
24
+ primary: themeVars.content.primary,
25
+ muted: themeVars.content.muted,
26
+ dim: themeVars.content.dim,
27
+ accent: themeVars.accent.default,
28
+ danger: themeVars.semantic.danger,
29
+ };
30
+
31
+ export interface EditorIconProps extends Omit<React.HTMLAttributes<SVGSVGElement>, 'color'> {
32
+ icon: IconDefinition;
33
+ size?: EditorIconSize;
34
+ tone?: EditorIconTone;
35
+ /** Icons inside already-labelled controls stay decorative by default. */
36
+ label?: string;
37
+ spin?: boolean;
38
+ }
39
+
40
+ /** Canonical editor-chrome icon metrics and accessibility behavior. */
41
+ export function EditorIcon({
42
+ icon,
43
+ size = 'sm',
44
+ tone = 'current',
45
+ label,
46
+ className,
47
+ style,
48
+ spin = false,
49
+ ...svgProps
50
+ }: EditorIconProps) {
51
+ return (
52
+ <FontAwesomeIcon
53
+ {...svgProps}
54
+ icon={icon}
55
+ fixedWidth
56
+ spin={spin}
57
+ className={className}
58
+ aria-hidden={label ? undefined : (svgProps['aria-hidden'] ?? 'true')}
59
+ aria-label={label}
60
+ role={label ? 'img' : undefined}
61
+ style={{ fontSize: SIZE[size], color: TONE[tone], ...style }}
62
+ />
63
+ );
64
+ }
65
+
66
+ export function DisclosureIcon({
67
+ direction,
68
+ size = 'xs',
69
+ tone = 'current',
70
+ style,
71
+ }: {
72
+ direction: 'right' | 'down';
73
+ size?: EditorIconSize;
74
+ tone?: EditorIconTone;
75
+ style?: React.CSSProperties;
76
+ }) {
77
+ return (
78
+ <EditorIcon
79
+ icon={direction === 'right' ? faChevronRight : faChevronDown}
80
+ size={size}
81
+ tone={tone}
82
+ {...(style ? { style } : {})}
83
+ />
84
+ );
85
+ }
86
+
87
+ export function TreeDisclosureIcon({
88
+ direction,
89
+ size = 'xs',
90
+ tone = 'current',
91
+ }: {
92
+ direction: 'right' | 'down';
93
+ size?: EditorIconSize;
94
+ tone?: EditorIconTone;
95
+ }) {
96
+ return (
97
+ <EditorIcon icon={direction === 'right' ? faCaretRight : faCaretDown} size={size} tone={tone} />
98
+ );
99
+ }
@@ -0,0 +1,71 @@
1
+ import { forwardRef, type InputHTMLAttributes, type SelectHTMLAttributes } from 'react';
2
+
3
+ function classes(base: string, className?: string): string {
4
+ return className ? `${base} ${className}` : base;
5
+ }
6
+
7
+ export type TextInputProps = InputHTMLAttributes<HTMLInputElement>;
8
+
9
+ export const TextInput = forwardRef<HTMLInputElement, TextInputProps>(function TextInput(
10
+ { className, type = 'text', ...props },
11
+ ref,
12
+ ) {
13
+ return <input {...props} ref={ref} type={type} className={classes('vgai-input', className)} />;
14
+ });
15
+
16
+ export type SelectProps = SelectHTMLAttributes<HTMLSelectElement>;
17
+
18
+ export const Select = forwardRef<HTMLSelectElement, SelectProps>(function Select(
19
+ { className, ...props },
20
+ ref,
21
+ ) {
22
+ return <select {...props} ref={ref} className={classes('vgai-select', className)} />;
23
+ });
24
+
25
+ export type CheckboxProps = Omit<InputHTMLAttributes<HTMLInputElement>, 'type'>;
26
+
27
+ export const Checkbox = forwardRef<HTMLInputElement, CheckboxProps>(function Checkbox(
28
+ { className, ...props },
29
+ ref,
30
+ ) {
31
+ return (
32
+ <input {...props} ref={ref} type="checkbox" className={classes('vgai-checkbox', className)} />
33
+ );
34
+ });
35
+
36
+ export type ColorSwatchInputProps = Omit<InputHTMLAttributes<HTMLInputElement>, 'type'>;
37
+
38
+ /** Native color picker with editor-owned dimensions, border, and focus treatment. */
39
+ export const ColorSwatchInput = forwardRef<HTMLInputElement, ColorSwatchInputProps>(
40
+ function ColorSwatchInput({ className, ...props }, ref) {
41
+ return (
42
+ <input
43
+ {...props}
44
+ ref={ref}
45
+ type="color"
46
+ className={classes('vgai-color-swatch', className)}
47
+ />
48
+ );
49
+ },
50
+ );
51
+
52
+ export type FileInputProps = Omit<InputHTMLAttributes<HTMLInputElement>, 'type'>;
53
+
54
+ /** File input kept native for platform behavior while sharing editor focus/disabled states. */
55
+ export const FileInput = forwardRef<HTMLInputElement, FileInputProps>(function FileInput(
56
+ { className, ...props },
57
+ ref,
58
+ ) {
59
+ return (
60
+ <input {...props} ref={ref} type="file" className={classes('vgai-file-input', className)} />
61
+ );
62
+ });
63
+
64
+ export type RangeInputProps = Omit<InputHTMLAttributes<HTMLInputElement>, 'type'>;
65
+
66
+ export const RangeInput = forwardRef<HTMLInputElement, RangeInputProps>(function RangeInput(
67
+ { className, ...props },
68
+ ref,
69
+ ) {
70
+ return <input {...props} ref={ref} type="range" className={classes('vgai-range', className)} />;
71
+ });
@@ -1,4 +1,5 @@
1
1
  import { useEffect, useRef, useState } from 'react';
2
+ import { fontSize, themeVars } from '../../theme';
2
3
 
3
4
  /**
4
5
  * Type-preserving JSON input for the component inspector's raw path.
@@ -62,6 +63,10 @@ export function JsonInput({
62
63
  <div>
63
64
  <input
64
65
  data-testid="json-input"
66
+ // Self-styled baseline (I-28): the shared field class means this
67
+ // primitive is never silently unstyled when a caller passes no
68
+ // `style` — callers now only supply layout (width/flex).
69
+ className="vgai-input"
65
70
  value={draft}
66
71
  onChange={(e) => {
67
72
  setDraft(e.target.value);
@@ -78,7 +83,15 @@ export function JsonInput({
78
83
  (e.target as HTMLInputElement).blur();
79
84
  }
80
85
  }}
81
- style={invalid ? { ...style, borderColor: '#FF6B6B', color: '#FF6B6B' } : style}
86
+ style={
87
+ invalid
88
+ ? {
89
+ ...style,
90
+ borderColor: themeVars.semantic.danger,
91
+ color: themeVars.semantic.danger,
92
+ }
93
+ : style
94
+ }
82
95
  title={
83
96
  invalid
84
97
  ? 'Not valid JSON — nothing written. Fix the JSON or press Escape to revert.'
@@ -88,7 +101,7 @@ export function JsonInput({
88
101
  {invalid && (
89
102
  <div
90
103
  data-testid="json-input-error"
91
- style={{ fontSize: 10, color: '#FF6B6B', marginTop: 2 }}
104
+ style={{ fontSize: fontSize.sm, color: themeVars.semantic.danger, marginTop: 2 }}
92
105
  >
93
106
  Not valid JSON — nothing written. Fix the JSON or press Escape to revert.
94
107
  </div>
@@ -0,0 +1,100 @@
1
+ import type { CSSProperties, HTMLAttributes, ReactNode } from 'react';
2
+
3
+ export type LayoutGap = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 8 | 10 | 12;
4
+ export type LayoutAlignment = 'start' | 'center' | 'end' | 'stretch' | 'baseline';
5
+ export type LayoutJustification = 'start' | 'center' | 'end' | 'between' | 'around' | 'evenly';
6
+
7
+ interface LayoutProps extends HTMLAttributes<HTMLDivElement> {
8
+ gap?: LayoutGap;
9
+ align?: LayoutAlignment;
10
+ justify?: LayoutJustification;
11
+ padding?: LayoutGap;
12
+ paddingX?: LayoutGap;
13
+ paddingY?: LayoutGap;
14
+ }
15
+
16
+ const alignValue: Record<LayoutAlignment, CSSProperties['alignItems']> = {
17
+ start: 'flex-start',
18
+ center: 'center',
19
+ end: 'flex-end',
20
+ stretch: 'stretch',
21
+ baseline: 'baseline',
22
+ };
23
+
24
+ const justifyValue: Record<LayoutJustification, CSSProperties['justifyContent']> = {
25
+ start: 'flex-start',
26
+ center: 'center',
27
+ end: 'flex-end',
28
+ between: 'space-between',
29
+ around: 'space-around',
30
+ evenly: 'space-evenly',
31
+ };
32
+
33
+ function token(value: LayoutGap | undefined): string | undefined {
34
+ return value === 0 ? '0px' : value === undefined ? undefined : `var(--vgai-space-${value})`;
35
+ }
36
+
37
+ function layoutStyle({
38
+ gap,
39
+ align,
40
+ justify,
41
+ padding,
42
+ paddingX,
43
+ paddingY,
44
+ style,
45
+ }: LayoutProps): CSSProperties {
46
+ return {
47
+ gap: token(gap),
48
+ alignItems: align ? alignValue[align] : undefined,
49
+ justifyContent: justify ? justifyValue[justify] : undefined,
50
+ padding: token(padding),
51
+ paddingInline: token(paddingX),
52
+ paddingBlock: token(paddingY),
53
+ ...style,
54
+ };
55
+ }
56
+
57
+ function classes(base: string, className?: string): string {
58
+ return className ? `${base} ${className}` : base;
59
+ }
60
+
61
+ export function Stack({ className, ...props }: LayoutProps) {
62
+ return <div {...props} className={classes('vgai-stack', className)} style={layoutStyle(props)} />;
63
+ }
64
+
65
+ export function Inline({ className, ...props }: LayoutProps) {
66
+ return (
67
+ <div {...props} className={classes('vgai-inline', className)} style={layoutStyle(props)} />
68
+ );
69
+ }
70
+
71
+ export function Spacer({ className, ...props }: HTMLAttributes<HTMLSpanElement>) {
72
+ return <span {...props} aria-hidden="true" className={classes('vgai-spacer', className)} />;
73
+ }
74
+
75
+ export function Divider({
76
+ orientation = 'horizontal',
77
+ className,
78
+ ...props
79
+ }: HTMLAttributes<HTMLDivElement> & { orientation?: 'horizontal' | 'vertical' }) {
80
+ return (
81
+ <div
82
+ {...props}
83
+ aria-hidden="true"
84
+ data-orientation={orientation}
85
+ className={classes('vgai-divider', className)}
86
+ />
87
+ );
88
+ }
89
+
90
+ export function Actions({
91
+ children,
92
+ className,
93
+ ...props
94
+ }: HTMLAttributes<HTMLDivElement> & { children: ReactNode }) {
95
+ return (
96
+ <Inline {...props} className={classes('vgai-actions', className)} gap={2} align="center">
97
+ {children}
98
+ </Inline>
99
+ );
100
+ }
@@ -0,0 +1,105 @@
1
+ import {
2
+ type ButtonHTMLAttributes,
3
+ forwardRef,
4
+ type HTMLAttributes,
5
+ useEffect,
6
+ useImperativeHandle,
7
+ useRef,
8
+ } from 'react';
9
+
10
+ function classes(base: string, className?: string): string {
11
+ return className ? `${base} ${className}` : base;
12
+ }
13
+
14
+ export interface MenuProps extends HTMLAttributes<HTMLDivElement> {
15
+ autoFocusFirst?: boolean;
16
+ onDismiss?: () => void;
17
+ }
18
+
19
+ function enabledItems(menu: HTMLDivElement): HTMLElement[] {
20
+ return Array.from(
21
+ menu.querySelectorAll<HTMLElement>(
22
+ '[role="menuitem"]:not(:disabled), [role="menuitemradio"]:not(:disabled), [role="menuitemcheckbox"]:not(:disabled)',
23
+ ),
24
+ );
25
+ }
26
+
27
+ export const Menu = forwardRef<HTMLDivElement, MenuProps>(function Menu(
28
+ { className, role = 'menu', autoFocusFirst = false, onDismiss, onKeyDown, ...props },
29
+ ref,
30
+ ) {
31
+ const localRef = useRef<HTMLDivElement>(null);
32
+ useImperativeHandle(ref, () => localRef.current as HTMLDivElement);
33
+ useEffect(() => {
34
+ if (autoFocusFirst) enabledItems(localRef.current as HTMLDivElement)[0]?.focus();
35
+ }, [autoFocusFirst]);
36
+
37
+ return (
38
+ <div
39
+ {...props}
40
+ ref={localRef}
41
+ role={role}
42
+ className={classes('vgai-menu', className)}
43
+ onKeyDown={(event) => {
44
+ onKeyDown?.(event);
45
+ if (event.defaultPrevented) return;
46
+ if (event.key === 'Escape') {
47
+ event.preventDefault();
48
+ onDismiss?.();
49
+ return;
50
+ }
51
+ if (!['ArrowDown', 'ArrowUp', 'Home', 'End'].includes(event.key)) return;
52
+ event.preventDefault();
53
+ const items = enabledItems(event.currentTarget);
54
+ if (items.length === 0) return;
55
+ const current = items.indexOf(document.activeElement as HTMLElement);
56
+ if (event.key === 'Home') items[0]?.focus();
57
+ else if (event.key === 'End') items.at(-1)?.focus();
58
+ else if (event.key === 'ArrowDown')
59
+ items[(current + 1 + items.length) % items.length]?.focus();
60
+ else items[(current - 1 + items.length) % items.length]?.focus();
61
+ }}
62
+ />
63
+ );
64
+ });
65
+
66
+ export type MenuItemProps = ButtonHTMLAttributes<HTMLButtonElement> & {
67
+ onSelect?: (() => void) | undefined;
68
+ };
69
+
70
+ export const MenuItem = forwardRef<HTMLButtonElement, MenuItemProps>(function MenuItem(
71
+ { className, type = 'button', role = 'menuitem', onClick, onSelect, ...props },
72
+ ref,
73
+ ) {
74
+ return (
75
+ <button
76
+ {...props}
77
+ ref={ref}
78
+ type={type}
79
+ role={role}
80
+ className={classes('vgai-menu-item', className)}
81
+ onClick={(event) => {
82
+ onClick?.(event);
83
+ if (!event.defaultPrevented) onSelect?.();
84
+ }}
85
+ />
86
+ );
87
+ });
88
+
89
+ export function MenuSeparator(props: HTMLAttributes<HTMLHRElement>) {
90
+ return <hr {...props} className={classes('vgai-menu-separator', props.className)} />;
91
+ }
92
+
93
+ export const MenuTrigger = forwardRef<HTMLButtonElement, ButtonHTMLAttributes<HTMLButtonElement>>(
94
+ function MenuTrigger({ className, type = 'button', ...props }, ref) {
95
+ return (
96
+ <button
97
+ {...props}
98
+ ref={ref}
99
+ type={type}
100
+ aria-haspopup={props['aria-haspopup'] ?? 'menu'}
101
+ className={classes('vgai-menu-trigger', className)}
102
+ />
103
+ );
104
+ },
105
+ );
@@ -1,5 +1,6 @@
1
1
  import { useEffect, useRef, useState } from 'react';
2
2
  import { useInteractiveEditScope } from '../../interactive-edit-scope';
3
+ import { TextInput } from './FormControls';
3
4
 
4
5
  interface NumberInputProps {
5
6
  value: number | null; // null = mixed (multi-edit)
@@ -100,23 +101,17 @@ export function NumberInput({
100
101
  };
101
102
 
102
103
  return (
103
- <div data-testid={testId} style={{ display: 'flex', alignItems: 'center', gap: 2, ...style }}>
104
+ <div className="vgai-number-input" data-testid={testId} style={style}>
104
105
  {label && (
105
106
  <span
106
- style={{
107
- fontSize: 10,
108
- fontWeight: 700,
109
- color: labelColor ?? '#8c8c8c',
110
- width: 12,
111
- textAlign: 'center',
112
- userSelect: 'none',
113
- }}
107
+ className="vgai-number-input-label"
108
+ style={labelColor ? { color: labelColor } : undefined}
114
109
  >
115
110
  {label}
116
111
  </span>
117
112
  )}
118
113
  {editing ? (
119
- <input
114
+ <TextInput
120
115
  ref={inputRef}
121
116
  value={text}
122
117
  onChange={(e) => setText(e.target.value)}
@@ -126,35 +121,13 @@ export function NumberInput({
126
121
  if (e.key === 'Escape') setEditing(false);
127
122
  }}
128
123
  placeholder={isMixed ? '—' : undefined}
129
- style={{
130
- width: '100%',
131
- background: '#1e1e1e',
132
- color: '#c5c8ce',
133
- border: '1px solid #579EFF',
134
- borderRadius: 2,
135
- padding: '2px 4px',
136
- fontSize: 12,
137
- outline: 'none',
138
- }}
124
+ className="vgai-number-input-editor"
139
125
  />
140
126
  ) : (
141
127
  <div
142
128
  onPointerDown={handlePointerDown}
143
- style={{
144
- width: '100%',
145
- background: '#1e1e1e',
146
- border: '1px solid #333',
147
- borderRadius: 2,
148
- padding: '2px 4px',
149
- fontSize: 12,
150
- cursor: 'ew-resize',
151
- userSelect: 'none',
152
- overflow: 'hidden',
153
- textOverflow: 'ellipsis',
154
- whiteSpace: 'nowrap',
155
- color: isMixed ? '#666' : undefined,
156
- fontStyle: isMixed ? 'italic' : undefined,
157
- }}
129
+ className="vgai-number-input-scrub"
130
+ data-mixed={isMixed || undefined}
158
131
  >
159
132
  {display}
160
133
  </div>