nudge-ui 0.2.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 (510) hide show
  1. package/README.md +66 -0
  2. package/bin/nudge-ui.mjs +7 -0
  3. package/dist/LICENSE +21 -0
  4. package/dist/client.mjs +261 -0
  5. package/dist/compiler/ast.d.ts +18 -0
  6. package/dist/compiler/ast.js +75 -0
  7. package/dist/compiler/componentContractTypes.d.ts +19 -0
  8. package/dist/compiler/componentContractTypes.js +1 -0
  9. package/dist/compiler/componentContracts.d.ts +2 -0
  10. package/dist/compiler/componentContracts.js +260 -0
  11. package/dist/compiler/componentInstrumentation.d.ts +32 -0
  12. package/dist/compiler/componentInstrumentation.js +140 -0
  13. package/dist/compiler/componentPolicyResolution.d.ts +71 -0
  14. package/dist/compiler/componentPolicyResolution.js +388 -0
  15. package/dist/compiler/index.d.ts +9 -0
  16. package/dist/compiler/index.js +9 -0
  17. package/dist/compiler/packageComponentContracts.d.ts +32 -0
  18. package/dist/compiler/packageComponentContracts.js +308 -0
  19. package/dist/compiler/reactComponentProtocols.d.ts +145 -0
  20. package/dist/compiler/reactComponentProtocols.js +47 -0
  21. package/dist/compiler/reactIdentity.d.ts +15 -0
  22. package/dist/compiler/reactIdentity.js +339 -0
  23. package/dist/compiler/sourcePaths.d.ts +12 -0
  24. package/dist/compiler/sourcePaths.js +27 -0
  25. package/dist/css/dialects/index.d.ts +62 -0
  26. package/dist/css/dialects/index.js +103 -0
  27. package/dist/css/dialects/tailwind.d.ts +46 -0
  28. package/dist/css/dialects/tailwind.js +119 -0
  29. package/dist/css/dialects/vanillaExtract.d.ts +20 -0
  30. package/dist/css/dialects/vanillaExtract.js +32 -0
  31. package/dist/css/index.d.ts +10 -0
  32. package/dist/css/index.js +10 -0
  33. package/dist/css/model/index.d.ts +190 -0
  34. package/dist/css/model/index.js +10 -0
  35. package/dist/css/token-inventory/index.d.ts +26 -0
  36. package/dist/css/token-inventory/index.js +24 -0
  37. package/dist/css/token-inventory/inventory.d.ts +8 -0
  38. package/dist/css/token-inventory/inventory.js +421 -0
  39. package/dist/css/token-inventory/parseStylesheet.d.ts +16 -0
  40. package/dist/css/token-inventory/parseStylesheet.js +155 -0
  41. package/dist/css/token-inventory/policy.d.ts +47 -0
  42. package/dist/css/token-inventory/policy.js +50 -0
  43. package/dist/css/token-inventory/types.d.ts +97 -0
  44. package/dist/css/token-inventory/types.js +1 -0
  45. package/dist/css/value-semantics/borderSemantics.d.ts +28 -0
  46. package/dist/css/value-semantics/borderSemantics.js +91 -0
  47. package/dist/css/value-semantics/boxSemantics.d.ts +37 -0
  48. package/dist/css/value-semantics/boxSemantics.js +71 -0
  49. package/dist/css/value-semantics/colorSemantics.d.ts +99 -0
  50. package/dist/css/value-semantics/colorSemantics.js +526 -0
  51. package/dist/css/value-semantics/cssSyntax.d.ts +19 -0
  52. package/dist/css/value-semantics/cssSyntax.js +111 -0
  53. package/dist/css/value-semantics/fontSemantics.d.ts +35 -0
  54. package/dist/css/value-semantics/fontSemantics.js +131 -0
  55. package/dist/css/value-semantics/index.d.ts +20 -0
  56. package/dist/css/value-semantics/index.js +15 -0
  57. package/dist/css/value-semantics/propertyPolicy.d.ts +118 -0
  58. package/dist/css/value-semantics/propertyPolicy.js +356 -0
  59. package/dist/css/value-semantics/stringMaps.d.ts +2 -0
  60. package/dist/css/value-semantics/stringMaps.js +1 -0
  61. package/dist/css/value-semantics/structuredValues.d.ts +64 -0
  62. package/dist/css/value-semantics/structuredValues.js +250 -0
  63. package/dist/css/value-semantics/tokenInterpretation.d.ts +90 -0
  64. package/dist/css/value-semantics/tokenInterpretation.js +193 -0
  65. package/dist/css/virtual-design-tokens.d.ts +17 -0
  66. package/dist/hosts/astro/astroRuntimeConfig.d.ts +12 -0
  67. package/dist/hosts/astro/astroRuntimeConfig.js +26 -0
  68. package/dist/hosts/astro/clientAsset.d.ts +12 -0
  69. package/dist/hosts/astro/clientAsset.js +51 -0
  70. package/dist/hosts/astro/clientTransport.d.ts +3 -0
  71. package/dist/hosts/astro/clientTransport.js +57 -0
  72. package/dist/hosts/astro/index.d.ts +3 -0
  73. package/dist/hosts/astro/index.js +2 -0
  74. package/dist/hosts/astro/integration.d.ts +35 -0
  75. package/dist/hosts/astro/integration.js +96 -0
  76. package/dist/hosts/astro/middleware.d.ts +13 -0
  77. package/dist/hosts/astro/middleware.js +22 -0
  78. package/dist/hosts/astro/projectContext.d.ts +11 -0
  79. package/dist/hosts/astro/projectContext.js +34 -0
  80. package/dist/hosts/astro/responseInstrumentation.d.ts +41 -0
  81. package/dist/hosts/astro/responseInstrumentation.js +80 -0
  82. package/dist/hosts/next/index.d.ts +4 -0
  83. package/dist/hosts/next/index.js +7 -0
  84. package/dist/hosts/next/loader.d.ts +66 -0
  85. package/dist/hosts/next/loader.js +346 -0
  86. package/dist/hosts/next/loaders/identity-loader.cjs +228257 -0
  87. package/dist/hosts/next/loaders/loader-plugin.cjs +228257 -0
  88. package/dist/hosts/next/manifest.d.ts +38 -0
  89. package/dist/hosts/next/manifest.js +30 -0
  90. package/dist/hosts/next/mount.d.ts +12 -0
  91. package/dist/hosts/next/mount.js +23 -0
  92. package/dist/hosts/next/repositoryScope.d.ts +20 -0
  93. package/dist/hosts/next/repositoryScope.js +33 -0
  94. package/dist/hosts/next/sidecar.d.ts +27 -0
  95. package/dist/hosts/next/sidecar.js +526 -0
  96. package/dist/hosts/next/wrapper.d.ts +67 -0
  97. package/dist/hosts/next/wrapper.js +310 -0
  98. package/dist/hosts/static/cli.d.ts +12 -0
  99. package/dist/hosts/static/cli.js +77 -0
  100. package/dist/hosts/static/html/bootstrap.d.ts +27 -0
  101. package/dist/hosts/static/html/bootstrap.js +93 -0
  102. package/dist/hosts/static/index.d.ts +4 -0
  103. package/dist/hosts/static/index.js +4 -0
  104. package/dist/hosts/static/manifest.d.ts +18 -0
  105. package/dist/hosts/static/manifest.js +51 -0
  106. package/dist/hosts/static/server.d.ts +72 -0
  107. package/dist/hosts/static/server.js +554 -0
  108. package/dist/hosts/vite/index.d.ts +20 -0
  109. package/dist/hosts/vite/index.js +48 -0
  110. package/dist/hosts/vite/react.d.ts +67 -0
  111. package/dist/hosts/vite/react.js +231 -0
  112. package/dist/hosts/vite/tokens/activeStylesheets.d.ts +28 -0
  113. package/dist/hosts/vite/tokens/activeStylesheets.js +70 -0
  114. package/dist/hosts/vite/tokens/fileMap.d.ts +2 -0
  115. package/dist/hosts/vite/tokens/fileMap.js +1 -0
  116. package/dist/hosts/vite/tokens/viteStylesheetArtifacts.d.ts +46 -0
  117. package/dist/hosts/vite/tokens/viteStylesheetArtifacts.js +104 -0
  118. package/dist/hosts/vite/virtual/design-tokens.d.ts +9 -0
  119. package/dist/hosts/vite/virtual/design-tokens.js +7 -0
  120. package/dist/hosts/vite/virtual-design-tokens.d.ts +1 -0
  121. package/dist/hosts/vite/vite.d.ts +62 -0
  122. package/dist/hosts/vite/vite.js +854 -0
  123. package/dist/html/dom.d.ts +13 -0
  124. package/dist/html/dom.js +46 -0
  125. package/dist/html/identity.d.ts +40 -0
  126. package/dist/html/identity.js +196 -0
  127. package/dist/html/insertions.d.ts +26 -0
  128. package/dist/html/insertions.js +59 -0
  129. package/dist/inspector/agent/McpConnectionDialog.d.ts +26 -0
  130. package/dist/inspector/agent/McpConnectionDialog.js +135 -0
  131. package/dist/inspector/agent/client.d.ts +98 -0
  132. package/dist/inspector/agent/client.js +728 -0
  133. package/dist/inspector/agent/connectionStatus.d.ts +13 -0
  134. package/dist/inspector/agent/connectionStatus.js +35 -0
  135. package/dist/inspector/agent/httpTransport.d.ts +21 -0
  136. package/dist/inspector/agent/httpTransport.js +347 -0
  137. package/dist/inspector/agent/protocol.d.ts +95 -0
  138. package/dist/inspector/agent/protocol.js +9 -0
  139. package/dist/inspector/agent/verification.d.ts +39 -0
  140. package/dist/inspector/agent/verification.js +207 -0
  141. package/dist/inspector/canvas/CanvasCard.d.ts +10 -0
  142. package/dist/inspector/canvas/CanvasCard.js +275 -0
  143. package/dist/inspector/canvas/CanvasElementOverlay.d.ts +2 -0
  144. package/dist/inspector/canvas/CanvasElementOverlay.js +301 -0
  145. package/dist/inspector/canvas/CanvasWorkspace.d.ts +2 -0
  146. package/dist/inspector/canvas/CanvasWorkspace.js +301 -0
  147. package/dist/inspector/canvas/LockedWorkspaceNotice.d.ts +6 -0
  148. package/dist/inspector/canvas/LockedWorkspaceNotice.js +17 -0
  149. package/dist/inspector/canvas/StaleChangeIndicator.d.ts +7 -0
  150. package/dist/inspector/canvas/StaleChangeIndicator.js +43 -0
  151. package/dist/inspector/canvas/agentPresentation.d.ts +87 -0
  152. package/dist/inspector/canvas/agentPresentation.js +421 -0
  153. package/dist/inspector/canvas/canvasGestures.d.ts +12 -0
  154. package/dist/inspector/canvas/canvasGestures.js +21 -0
  155. package/dist/inspector/canvas/canvasStore.d.ts +108 -0
  156. package/dist/inspector/canvas/canvasStore.js +448 -0
  157. package/dist/inspector/canvas/frameProtocol.d.ts +231 -0
  158. package/dist/inspector/canvas/frameProtocol.js +165 -0
  159. package/dist/inspector/canvas/linkEligibility.d.ts +8 -0
  160. package/dist/inspector/canvas/linkEligibility.js +68 -0
  161. package/dist/inspector/canvas/measurementProjection.d.ts +8 -0
  162. package/dist/inspector/canvas/measurementProjection.js +16 -0
  163. package/dist/inspector/canvas/normalizeUrl.d.ts +7 -0
  164. package/dist/inspector/canvas/normalizeUrl.js +27 -0
  165. package/dist/inspector/canvas/projection.d.ts +41 -0
  166. package/dist/inspector/canvas/projection.js +232 -0
  167. package/dist/inspector/canvas/rendererBootstrap.d.ts +4 -0
  168. package/dist/inspector/canvas/rendererBootstrap.js +410 -0
  169. package/dist/inspector/canvas/rendererCidIndex.d.ts +11 -0
  170. package/dist/inspector/canvas/rendererCidIndex.js +21 -0
  171. package/dist/inspector/canvas/rendererElementSelector.d.ts +2 -0
  172. package/dist/inspector/canvas/rendererElementSelector.js +378 -0
  173. package/dist/inspector/canvas/rendererSelectionProxy.d.ts +2 -0
  174. package/dist/inspector/canvas/rendererSelectionProxy.js +61 -0
  175. package/dist/inspector/canvas/rendererStylesheet.d.ts +16 -0
  176. package/dist/inspector/canvas/rendererStylesheet.js +221 -0
  177. package/dist/inspector/canvas/resizeHandleScale.d.ts +13 -0
  178. package/dist/inspector/canvas/resizeHandleScale.js +20 -0
  179. package/dist/inspector/canvas/roleDetection.d.ts +5 -0
  180. package/dist/inspector/canvas/roleDetection.js +21 -0
  181. package/dist/inspector/canvas/sessionStore.d.ts +71 -0
  182. package/dist/inspector/canvas/sessionStore.js +453 -0
  183. package/dist/inspector/canvas/staleChangeDetector.d.ts +11 -0
  184. package/dist/inspector/canvas/staleChangeDetector.js +217 -0
  185. package/dist/inspector/canvas/toolbarScale.d.ts +7 -0
  186. package/dist/inspector/canvas/toolbarScale.js +11 -0
  187. package/dist/inspector/canvas/workspaceLease.d.ts +26 -0
  188. package/dist/inspector/canvas/workspaceLease.js +214 -0
  189. package/dist/inspector/changes/changesLog.d.ts +46 -0
  190. package/dist/inspector/changes/changesLog.js +209 -0
  191. package/dist/inspector/changes/codecs.d.ts +98 -0
  192. package/dist/inspector/changes/codecs.js +389 -0
  193. package/dist/inspector/changes/editModel.d.ts +74 -0
  194. package/dist/inspector/changes/editModel.js +120 -0
  195. package/dist/inspector/changes/managedStyleProjection.d.ts +6 -0
  196. package/dist/inspector/changes/managedStyleProjection.js +109 -0
  197. package/dist/inspector/changes/model.d.ts +13 -0
  198. package/dist/inspector/changes/model.js +163 -0
  199. package/dist/inspector/changes/presentation.d.ts +14 -0
  200. package/dist/inspector/changes/presentation.js +81 -0
  201. package/dist/inspector/changes/previewDiagnostics.d.ts +39 -0
  202. package/dist/inspector/changes/previewDiagnostics.js +172 -0
  203. package/dist/inspector/changes/structuralTypes.d.ts +35 -0
  204. package/dist/inspector/changes/structuralTypes.js +1 -0
  205. package/dist/inspector/changes/types.d.ts +76 -0
  206. package/dist/inspector/changes/types.js +16 -0
  207. package/dist/inspector/changes/workspaceChanges.d.ts +43 -0
  208. package/dist/inspector/changes/workspaceChanges.js +239 -0
  209. package/dist/inspector/clientManifest.d.ts +24 -0
  210. package/dist/inspector/clientManifest.js +69 -0
  211. package/dist/inspector/componentSemantics/ComponentPropsSection.d.ts +5 -0
  212. package/dist/inspector/componentSemantics/ComponentPropsSection.js +44 -0
  213. package/dist/inspector/componentSemantics/adapterRegistry.d.ts +11 -0
  214. package/dist/inspector/componentSemantics/adapterRegistry.js +75 -0
  215. package/dist/inspector/componentSemantics/boundaries.d.ts +2 -0
  216. package/dist/inspector/componentSemantics/boundaries.js +10 -0
  217. package/dist/inspector/componentSemantics/changeAction.d.ts +3 -0
  218. package/dist/inspector/componentSemantics/changeAction.js +6 -0
  219. package/dist/inspector/componentSemantics/changeModel.d.ts +8 -0
  220. package/dist/inspector/componentSemantics/changeModel.js +60 -0
  221. package/dist/inspector/componentSemantics/index.d.ts +4 -0
  222. package/dist/inspector/componentSemantics/index.js +2 -0
  223. package/dist/inspector/componentSemantics/reactRuntime.d.ts +10 -0
  224. package/dist/inspector/componentSemantics/reactRuntime.js +186 -0
  225. package/dist/inspector/componentSemantics/runtimeBridge.d.ts +25 -0
  226. package/dist/inspector/componentSemantics/runtimeBridge.js +161 -0
  227. package/dist/inspector/componentSemantics/runtimeTypes.d.ts +2 -0
  228. package/dist/inspector/componentSemantics/runtimeTypes.js +1 -0
  229. package/dist/inspector/componentSemantics/textBinding.d.ts +69 -0
  230. package/dist/inspector/componentSemantics/textBinding.js +514 -0
  231. package/dist/inspector/componentSemantics/types.d.ts +96 -0
  232. package/dist/inspector/componentSemantics/types.js +5 -0
  233. package/dist/inspector/conformance/borderCases.d.ts +7 -0
  234. package/dist/inspector/conformance/borderCases.js +428 -0
  235. package/dist/inspector/conformance/colorCases.d.ts +8 -0
  236. package/dist/inspector/conformance/colorCases.js +470 -0
  237. package/dist/inspector/conformance/fixture.d.ts +68 -0
  238. package/dist/inspector/conformance/fixture.js +153 -0
  239. package/dist/inspector/conformance/projection.d.ts +2 -0
  240. package/dist/inspector/conformance/projection.js +3 -0
  241. package/dist/inspector/conformance/spacingCases.d.ts +6 -0
  242. package/dist/inspector/conformance/spacingCases.js +417 -0
  243. package/dist/inspector/conformance/typographyCases.d.ts +7 -0
  244. package/dist/inspector/conformance/typographyCases.js +174 -0
  245. package/dist/inspector/editScope.d.ts +4 -0
  246. package/dist/inspector/editScope.js +5 -0
  247. package/dist/inspector/index.d.ts +20 -0
  248. package/dist/inspector/index.js +236 -0
  249. package/dist/inspector/inline-text/inlineTextEditor.d.ts +74 -0
  250. package/dist/inspector/inline-text/inlineTextEditor.js +1207 -0
  251. package/dist/inspector/inline-text/inlineTextLifecycle.d.ts +2 -0
  252. package/dist/inspector/inline-text/inlineTextLifecycle.js +17 -0
  253. package/dist/inspector/inline-text/textChangeBoundary.d.ts +6 -0
  254. package/dist/inspector/inline-text/textChangeBoundary.js +1 -0
  255. package/dist/inspector/inspection/bridge.d.ts +72 -0
  256. package/dist/inspector/inspection/bridge.js +134 -0
  257. package/dist/inspector/inspection/browserCssInspection.d.ts +74 -0
  258. package/dist/inspector/inspection/browserCssInspection.js +317 -0
  259. package/dist/inspector/inspection/browserCssInspectionRegistry.d.ts +12 -0
  260. package/dist/inspector/inspection/browserCssInspectionRegistry.js +66 -0
  261. package/dist/inspector/inspection/selectionProperty.d.ts +32 -0
  262. package/dist/inspector/inspection/selectionProperty.js +33 -0
  263. package/dist/inspector/inspection/useBrowserCssInspection.d.ts +20 -0
  264. package/dist/inspector/inspection/useBrowserCssInspection.js +159 -0
  265. package/dist/inspector/overlay/DropGuideOverlay.d.ts +17 -0
  266. package/dist/inspector/overlay/DropGuideOverlay.js +17 -0
  267. package/dist/inspector/overlay/InspectorOverlay.d.ts +5 -0
  268. package/dist/inspector/overlay/InspectorOverlay.js +328 -0
  269. package/dist/inspector/overlay/MeasurementGuideOverlay.d.ts +19 -0
  270. package/dist/inspector/overlay/MeasurementGuideOverlay.js +40 -0
  271. package/dist/inspector/overlay/clickPolicy.d.ts +7 -0
  272. package/dist/inspector/overlay/clickPolicy.js +13 -0
  273. package/dist/inspector/overlay/dropGuide.d.ts +22 -0
  274. package/dist/inspector/overlay/dropGuide.js +48 -0
  275. package/dist/inspector/overlay/elementSelector.d.ts +1 -0
  276. package/dist/inspector/overlay/elementSelector.js +100 -0
  277. package/dist/inspector/overlay/frameThrottle.d.ts +10 -0
  278. package/dist/inspector/overlay/frameThrottle.js +38 -0
  279. package/dist/inspector/overlay/interactionStyles.d.ts +3 -0
  280. package/dist/inspector/overlay/interactionStyles.js +70 -0
  281. package/dist/inspector/overlay/measurementGeometry.d.ts +25 -0
  282. package/dist/inspector/overlay/measurementGeometry.js +104 -0
  283. package/dist/inspector/overlay/overlayGeometry.d.ts +40 -0
  284. package/dist/inspector/overlay/overlayGeometry.js +59 -0
  285. package/dist/inspector/overlay/selectedGeometry.d.ts +7 -0
  286. package/dist/inspector/overlay/selectedGeometry.js +51 -0
  287. package/dist/inspector/overlay/structuralGestures.d.ts +28 -0
  288. package/dist/inspector/overlay/structuralGestures.js +180 -0
  289. package/dist/inspector/projection/cssEscapes.d.ts +3 -0
  290. package/dist/inspector/projection/cssEscapes.js +20 -0
  291. package/dist/inspector/projection/managedStylesheet.d.ts +33 -0
  292. package/dist/inspector/projection/managedStylesheet.js +240 -0
  293. package/dist/inspector/projection/renderedInstance.d.ts +56 -0
  294. package/dist/inspector/projection/renderedInstance.js +306 -0
  295. package/dist/inspector/projection/structuralProjection.d.ts +93 -0
  296. package/dist/inspector/projection/structuralProjection.js +560 -0
  297. package/dist/inspector/projection/structuralProjectionBoundary.d.ts +5 -0
  298. package/dist/inspector/projection/structuralProjectionBoundary.js +65 -0
  299. package/dist/inspector/projection/textProjection.d.ts +53 -0
  300. package/dist/inspector/projection/textProjection.js +705 -0
  301. package/dist/inspector/projection/workspaceProjection.d.ts +43 -0
  302. package/dist/inspector/projection/workspaceProjection.js +58 -0
  303. package/dist/inspector/prompt/PromptSettingsDialog.d.ts +15 -0
  304. package/dist/inspector/prompt/PromptSettingsDialog.js +17 -0
  305. package/dist/inspector/prompt/clipboardHandoff.d.ts +34 -0
  306. package/dist/inspector/prompt/clipboardHandoff.js +212 -0
  307. package/dist/inspector/prompt/copyToClipboard.d.ts +1 -0
  308. package/dist/inspector/prompt/copyToClipboard.js +34 -0
  309. package/dist/inspector/prompt/detectFramework.d.ts +6 -0
  310. package/dist/inspector/prompt/detectFramework.js +4 -0
  311. package/dist/inspector/prompt/generatePrompt.d.ts +7 -0
  312. package/dist/inspector/prompt/generatePrompt.js +391 -0
  313. package/dist/inspector/prompt/promptSettings.d.ts +8 -0
  314. package/dist/inspector/prompt/promptSettings.js +28 -0
  315. package/dist/inspector/runtime/devFlag.d.ts +28 -0
  316. package/dist/inspector/runtime/devFlag.js +50 -0
  317. package/dist/inspector/runtime/documentStylesheetOrder.d.ts +19 -0
  318. package/dist/inspector/runtime/documentStylesheetOrder.js +89 -0
  319. package/dist/inspector/runtime/domRealm.d.ts +4 -0
  320. package/dist/inspector/runtime/domRealm.js +11 -0
  321. package/dist/inspector/runtime/runtimeConfig.d.ts +119 -0
  322. package/dist/inspector/runtime/runtimeConfig.js +276 -0
  323. package/dist/inspector/runtime/staticHtmlRuntimeIdentity.d.ts +32 -0
  324. package/dist/inspector/runtime/staticHtmlRuntimeIdentity.js +149 -0
  325. package/dist/inspector/runtime/useRuntimeConfig.d.ts +10 -0
  326. package/dist/inspector/runtime/useRuntimeConfig.js +13 -0
  327. package/dist/inspector/selection/editScope.d.ts +32 -0
  328. package/dist/inspector/selection/editScope.js +140 -0
  329. package/dist/inspector/selection/editTarget.d.ts +8 -0
  330. package/dist/inspector/selection/editTarget.js +11 -0
  331. package/dist/inspector/selection/hierarchy.d.ts +7 -0
  332. package/dist/inspector/selection/hierarchy.js +42 -0
  333. package/dist/inspector/selection/resolveSelection.d.ts +10 -0
  334. package/dist/inspector/selection/resolveSelection.js +60 -0
  335. package/dist/inspector/selection/selectionStore.d.ts +41 -0
  336. package/dist/inspector/selection/selectionStore.js +262 -0
  337. package/dist/inspector/selection/selectionTarget.d.ts +5 -0
  338. package/dist/inspector/selection/selectionTarget.js +50 -0
  339. package/dist/inspector/selection/sourceSite.d.ts +2 -0
  340. package/dist/inspector/selection/sourceSite.js +12 -0
  341. package/dist/inspector/selection/styleSelection.d.ts +22 -0
  342. package/dist/inspector/selection/styleSelection.js +104 -0
  343. package/dist/inspector/session/index.d.ts +3 -0
  344. package/dist/inspector/session/index.js +2 -0
  345. package/dist/inspector/session/lifecycle.d.ts +22 -0
  346. package/dist/inspector/session/lifecycle.js +63 -0
  347. package/dist/inspector/session/sessionContext.d.ts +21 -0
  348. package/dist/inspector/session/sessionContext.js +28 -0
  349. package/dist/inspector/session/sessionFactory.d.ts +29 -0
  350. package/dist/inspector/session/sessionFactory.js +73 -0
  351. package/dist/inspector/settings/SettingsDialog.d.ts +12 -0
  352. package/dist/inspector/settings/SettingsDialog.js +46 -0
  353. package/dist/inspector/shell/AppShell.d.ts +2 -0
  354. package/dist/inspector/shell/AppShell.js +9 -0
  355. package/dist/inspector/shell/ChangesLog.d.ts +6 -0
  356. package/dist/inspector/shell/ChangesLog.js +92 -0
  357. package/dist/inspector/shell/CopyPromptButton.d.ts +9 -0
  358. package/dist/inspector/shell/CopyPromptButton.js +159 -0
  359. package/dist/inspector/shell/DomNavigation.d.ts +8 -0
  360. package/dist/inspector/shell/DomNavigation.js +30 -0
  361. package/dist/inspector/shell/EmptyState.d.ts +2 -0
  362. package/dist/inspector/shell/EmptyState.js +15 -0
  363. package/dist/inspector/shell/InspectorShell.d.ts +11 -0
  364. package/dist/inspector/shell/InspectorShell.js +268 -0
  365. package/dist/inspector/shell/openStore.d.ts +6 -0
  366. package/dist/inspector/shell/openStore.js +29 -0
  367. package/dist/inspector/shell/panelLayout.d.ts +2 -0
  368. package/dist/inspector/shell/panelLayout.js +29 -0
  369. package/dist/inspector/shell/shortcuts.d.ts +3 -0
  370. package/dist/inspector/shell/shortcuts.js +25 -0
  371. package/dist/inspector/shell/stateValue.d.ts +3 -0
  372. package/dist/inspector/shell/stateValue.js +34 -0
  373. package/dist/inspector/shell/styleState.d.ts +7 -0
  374. package/dist/inspector/shell/styleState.js +13 -0
  375. package/dist/inspector/spacing/projection.d.ts +43 -0
  376. package/dist/inspector/spacing/projection.js +136 -0
  377. package/dist/inspector/styleEditors/AppearanceSection.d.ts +13 -0
  378. package/dist/inspector/styleEditors/AppearanceSection.js +6 -0
  379. package/dist/inspector/styleEditors/AspectRatioField.d.ts +17 -0
  380. package/dist/inspector/styleEditors/AspectRatioField.js +10 -0
  381. package/dist/inspector/styleEditors/BorderEditor.d.ts +13 -0
  382. package/dist/inspector/styleEditors/BorderEditor.js +295 -0
  383. package/dist/inspector/styleEditors/BorderRadiusEditor.d.ts +14 -0
  384. package/dist/inspector/styleEditors/BorderRadiusEditor.js +108 -0
  385. package/dist/inspector/styleEditors/BoxShadowEditor.d.ts +13 -0
  386. package/dist/inspector/styleEditors/BoxShadowEditor.js +13 -0
  387. package/dist/inspector/styleEditors/ColorPicker.d.ts +15 -0
  388. package/dist/inspector/styleEditors/ColorPicker.js +73 -0
  389. package/dist/inspector/styleEditors/GapField.d.ts +17 -0
  390. package/dist/inspector/styleEditors/GapField.js +12 -0
  391. package/dist/inspector/styleEditors/GridChildSection.d.ts +14 -0
  392. package/dist/inspector/styleEditors/GridChildSection.js +91 -0
  393. package/dist/inspector/styleEditors/GridPicker.d.ts +13 -0
  394. package/dist/inspector/styleEditors/GridPicker.js +179 -0
  395. package/dist/inspector/styleEditors/GridSection.d.ts +17 -0
  396. package/dist/inspector/styleEditors/GridSection.js +27 -0
  397. package/dist/inspector/styleEditors/GridValueField.d.ts +17 -0
  398. package/dist/inspector/styleEditors/GridValueField.js +70 -0
  399. package/dist/inspector/styleEditors/InsetSection.d.ts +15 -0
  400. package/dist/inspector/styleEditors/InsetSection.js +15 -0
  401. package/dist/inspector/styleEditors/LayoutBlockedIndicator.d.ts +6 -0
  402. package/dist/inspector/styleEditors/LayoutBlockedIndicator.js +6 -0
  403. package/dist/inspector/styleEditors/LayoutComboField.d.ts +18 -0
  404. package/dist/inspector/styleEditors/LayoutComboField.js +138 -0
  405. package/dist/inspector/styleEditors/LayoutDropdown.d.ts +14 -0
  406. package/dist/inspector/styleEditors/LayoutDropdown.js +34 -0
  407. package/dist/inspector/styleEditors/LayoutSection.d.ts +13 -0
  408. package/dist/inspector/styleEditors/LayoutSection.js +342 -0
  409. package/dist/inspector/styleEditors/OpacityEditor.d.ts +13 -0
  410. package/dist/inspector/styleEditors/OpacityEditor.js +34 -0
  411. package/dist/inspector/styleEditors/PositionInsets.d.ts +15 -0
  412. package/dist/inspector/styleEditors/PositionInsets.js +12 -0
  413. package/dist/inspector/styleEditors/SpacingBox.d.ts +29 -0
  414. package/dist/inspector/styleEditors/SpacingBox.js +189 -0
  415. package/dist/inspector/styleEditors/Typography.d.ts +13 -0
  416. package/dist/inspector/styleEditors/Typography.js +137 -0
  417. package/dist/inspector/styleEditors/completeCssValue.d.ts +8 -0
  418. package/dist/inspector/styleEditors/completeCssValue.js +34 -0
  419. package/dist/inspector/styleEditors/gridChildModel.d.ts +74 -0
  420. package/dist/inspector/styleEditors/gridChildModel.js +138 -0
  421. package/dist/inspector/styleEditors/layoutValue.d.ts +24 -0
  422. package/dist/inspector/styleEditors/layoutValue.js +103 -0
  423. package/dist/inspector/styleEditors/nudgeValue.d.ts +8 -0
  424. package/dist/inspector/styleEditors/nudgeValue.js +71 -0
  425. package/dist/inspector/styleEditors/rowLookup.d.ts +11 -0
  426. package/dist/inspector/styleEditors/rowLookup.js +13 -0
  427. package/dist/inspector/styleEditors/stringRecord.d.ts +4 -0
  428. package/dist/inspector/styleEditors/stringRecord.js +1 -0
  429. package/dist/inspector/styleEditors/valuePolicy.d.ts +20 -0
  430. package/dist/inspector/styleEditors/valuePolicy.js +82 -0
  431. package/dist/inspector/testing.d.ts +10 -0
  432. package/dist/inspector/testing.js +9 -0
  433. package/dist/inspector/tokens/TokenChip.d.ts +24 -0
  434. package/dist/inspector/tokens/TokenChip.js +23 -0
  435. package/dist/inspector/tokens/TokenDropdown.d.ts +13 -0
  436. package/dist/inspector/tokens/TokenDropdown.js +59 -0
  437. package/dist/inspector/tokens/TokenField.d.ts +68 -0
  438. package/dist/inspector/tokens/TokenField.js +485 -0
  439. package/dist/inspector/tokens/TokenLabel.d.ts +7 -0
  440. package/dist/inspector/tokens/TokenLabel.js +23 -0
  441. package/dist/inspector/tokens/TokensPanel.d.ts +5 -0
  442. package/dist/inspector/tokens/TokensPanel.js +47 -0
  443. package/dist/inspector/tokens/catalog.d.ts +51 -0
  444. package/dist/inspector/tokens/catalog.js +184 -0
  445. package/dist/inspector/tokens/editActions.d.ts +35 -0
  446. package/dist/inspector/tokens/editActions.js +164 -0
  447. package/dist/inspector/tokens/resolution/cascade.d.ts +14 -0
  448. package/dist/inspector/tokens/resolution/cascade.js +31 -0
  449. package/dist/inspector/tokens/resolution/cssomCollector.d.ts +43 -0
  450. package/dist/inspector/tokens/resolution/cssomCollector.js +528 -0
  451. package/dist/inspector/tokens/resolution/selectorSemantics.d.ts +12 -0
  452. package/dist/inspector/tokens/resolution/selectorSemantics.js +106 -0
  453. package/dist/inspector/tokens/resolution.d.ts +56 -0
  454. package/dist/inspector/tokens/resolution.js +1401 -0
  455. package/dist/inspector/tokens/tokenEdits.d.ts +3 -0
  456. package/dist/inspector/tokens/tokenEdits.js +22 -0
  457. package/dist/inspector/tokens/valueSemanticsAdapter.d.ts +6 -0
  458. package/dist/inspector/tokens/valueSemanticsAdapter.js +68 -0
  459. package/dist/inspector/ui/AtRuleContext.d.ts +18 -0
  460. package/dist/inspector/ui/AtRuleContext.js +54 -0
  461. package/dist/inspector/ui/Button.d.ts +9 -0
  462. package/dist/inspector/ui/Button.js +4 -0
  463. package/dist/inspector/ui/ColorSwatch.d.ts +7 -0
  464. package/dist/inspector/ui/ColorSwatch.js +6 -0
  465. package/dist/inspector/ui/ControlSurface.d.ts +14 -0
  466. package/dist/inspector/ui/ControlSurface.js +10 -0
  467. package/dist/inspector/ui/FieldRow.d.ts +14 -0
  468. package/dist/inspector/ui/FieldRow.js +15 -0
  469. package/dist/inspector/ui/IconButton.d.ts +14 -0
  470. package/dist/inspector/ui/IconButton.js +5 -0
  471. package/dist/inspector/ui/InspectorPopover.d.ts +17 -0
  472. package/dist/inspector/ui/InspectorPopover.js +13 -0
  473. package/dist/inspector/ui/PopoverListbox.d.ts +37 -0
  474. package/dist/inspector/ui/PopoverListbox.js +21 -0
  475. package/dist/inspector/ui/SegmentedControl.d.ts +24 -0
  476. package/dist/inspector/ui/SegmentedControl.js +16 -0
  477. package/dist/inspector/ui/Select.d.ts +25 -0
  478. package/dist/inspector/ui/Select.js +56 -0
  479. package/dist/inspector/ui/SideValuesField.d.ts +44 -0
  480. package/dist/inspector/ui/SideValuesField.js +76 -0
  481. package/dist/inspector/ui/StatusCallout.d.ts +9 -0
  482. package/dist/inspector/ui/StatusCallout.js +4 -0
  483. package/dist/inspector/ui/TextInput.d.ts +12 -0
  484. package/dist/inspector/ui/TextInput.js +5 -0
  485. package/dist/inspector/ui/ToggleButton.d.ts +11 -0
  486. package/dist/inspector/ui/ToggleButton.js +6 -0
  487. package/dist/inspector/ui/assets/grid.svg +14 -0
  488. package/dist/inspector/ui/css.d.ts +9 -0
  489. package/dist/inspector/ui/labels.d.ts +1 -0
  490. package/dist/inspector/ui/labels.js +7 -0
  491. package/dist/inspector/ui/styles.d.ts +1 -0
  492. package/dist/inspector/ui/styles.js +68 -0
  493. package/dist/inspector/virtual-modules.d.ts +7 -0
  494. package/dist/inspector/vite-env.d.ts +10 -0
  495. package/dist/internal/agent-protocol.d.ts +232 -0
  496. package/dist/internal/agent-protocol.js +237 -0
  497. package/dist/nudge-ui.mjs +15722 -0
  498. package/dist/project/files.d.ts +19 -0
  499. package/dist/project/files.js +226 -0
  500. package/dist/project/identity.d.ts +6 -0
  501. package/dist/project/identity.js +19 -0
  502. package/dist/project/pathPolicy.d.ts +8 -0
  503. package/dist/project/pathPolicy.js +12 -0
  504. package/dist/project/tokens.d.ts +36 -0
  505. package/dist/project/tokens.js +223 -0
  506. package/dist/transport/index.d.ts +8 -0
  507. package/dist/transport/index.js +8 -0
  508. package/dist/transport/routes.d.ts +13 -0
  509. package/dist/transport/routes.js +16 -0
  510. package/package.json +137 -0
@@ -0,0 +1,301 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useEffect, useMemo, useReducer, useRef, useState } from "react";
3
+ import { isElementClickMessage, isRendererMessageFor, } from "./frameProtocol.js";
4
+ import { findCanvasFrameBySource, PROJECT_ID, WORKSPACE_ID } from "./projection.js";
5
+ import { useBoardCamera, useCanvasCards } from "./canvasStore.js";
6
+ import { handleElementClick } from "./rendererSelectionProxy.js";
7
+ import { getSelectedElements, useSelectedElement, useSelectedElements } from "../selection/selectionStore.js";
8
+ import { getMarginFills, getMarginGuides, readBorderWidths, toRect, } from "../overlay/overlayGeometry.js";
9
+ const overlayStyles = ".canvas-element-overlay {\n position: fixed;\n pointer-events: none;\n z-index: 3;\n background: rgb(59 130 246 / 10%);\n outline: 1.5px solid var(--accent);\n outline-offset: -1px;\n}\n\n.canvas-selected-outline {\n position: fixed;\n pointer-events: none;\n z-index: 3;\n outline: 2px solid var(--accent);\n outline-offset: -2px;\n}\n\n.canvas-hover-margin-fill {\n position: fixed;\n pointer-events: none;\n z-index: 2;\n background: rgb(59 130 246 / 14%);\n}\n\n.canvas-hover-margin {\n position: fixed;\n pointer-events: none;\n z-index: 2;\n border-color: rgb(59 130 246 / 52%);\n border-style: dotted;\n border-width: 0;\n opacity: 0.72;\n}\n\n.canvas-hover-margin[data-axis=\"horizontal\"] {\n border-top-width: 1px;\n}\n\n.canvas-hover-margin[data-axis=\"vertical\"] {\n border-left-width: 1px;\n}\n\n.canvas-dom-drop-line {\n z-index: 2147483647;\n border-radius: 999px;\n background: #3b82f6;\n box-shadow: 0 0 0 1px rgb(255 255 255 / 95%), 0 1px 5px rgb(37 99 235 / 72%);\n}\n\n.canvas-dom-drop-line::before,\n.canvas-dom-drop-line::after {\n position: absolute;\n top: 50%;\n width: 8px;\n height: 8px;\n border: 2px solid #ffffff;\n border-radius: 50%;\n background: #2563eb;\n content: \"\";\n transform: translateY(-50%);\n}\n\n.canvas-dom-drop-line::before { left: -3px; }\n.canvas-dom-drop-line::after { right: -3px; }\n\n.canvas-dom-drop-line[data-orientation=\"vertical\"]::before,\n.canvas-dom-drop-line[data-orientation=\"vertical\"]::after {\n left: 50%;\n right: auto;\n transform: translateX(-50%);\n}\n\n.canvas-dom-drop-line[data-orientation=\"vertical\"]::before { top: -3px; }\n.canvas-dom-drop-line[data-orientation=\"vertical\"]::after { top: auto; bottom: -3px; }\n\n.canvas-dom-drop-target {\n z-index: 2147483646;\n box-sizing: border-box;\n border: 1px solid rgb(59 130 246 / 72%);\n border-radius: 4px;\n background: rgb(59 130 246 / 5%);\n}\n";
10
+ import { deleteElement, getDropLocationAtPoint, moveElement, nudgeElement } from "../overlay/structuralGestures.js";
11
+ import { redo, undo } from "../changes/changesLog.js";
12
+ import { resolveSelectionFromElement } from "../selection/resolveSelection.js";
13
+ import { setSelectedElement } from "../selection/selectionStore.js";
14
+ import { clearDropGuide, showDropGuide, useDropGuide } from "../overlay/dropGuide.js";
15
+ import { DropGuideOverlay } from "../overlay/DropGuideOverlay.js";
16
+ import { getMeasurementGeometry } from "../overlay/measurementGeometry.js";
17
+ import { MeasurementGuideOverlay } from "../overlay/MeasurementGuideOverlay.js";
18
+ import { projectMeasurementSegments } from "./measurementProjection.js";
19
+ import { RENDERER_ELEMENT_ID_ATTR } from "./rendererCidIndex.js";
20
+ import { observeSelectedGeometry } from "../overlay/selectedGeometry.js";
21
+ function projectRect(iframe, rect, zoom) {
22
+ const frameRect = iframe.getBoundingClientRect();
23
+ return {
24
+ left: frameRect.left + rect.left * zoom,
25
+ top: frameRect.top + rect.top * zoom,
26
+ width: rect.width * zoom,
27
+ height: rect.height * zoom,
28
+ };
29
+ }
30
+ function scaleMargins(margins, zoom) {
31
+ return {
32
+ top: margins.top * zoom,
33
+ right: margins.right * zoom,
34
+ bottom: margins.bottom * zoom,
35
+ left: margins.left * zoom,
36
+ };
37
+ }
38
+ function overlayStyle(rect) {
39
+ return {
40
+ position: "fixed",
41
+ left: rect.left,
42
+ top: rect.top,
43
+ width: rect.width,
44
+ height: rect.height,
45
+ pointerEvents: "none",
46
+ };
47
+ }
48
+ function findFrameElement(iframe, elementId, cid, src) {
49
+ const doc = iframe.contentDocument;
50
+ if (!doc)
51
+ return null;
52
+ if (!/^r\d+$/.test(elementId))
53
+ return null;
54
+ const candidates = doc.querySelectorAll(`[${RENDERER_ELEMENT_ID_ATTR}="${elementId}"]`);
55
+ if (candidates.length !== 1)
56
+ return null;
57
+ const candidate = candidates[0] ?? null;
58
+ if (!candidate || candidate.getAttribute("data-cid") !== cid || candidate.getAttribute("data-src") !== src)
59
+ return null;
60
+ const frameWindow = doc.defaultView;
61
+ return frameWindow && candidate instanceof frameWindow.HTMLElement ? candidate : null;
62
+ }
63
+ function projectGuideToCanvas(guide, zoom) {
64
+ if (!guide)
65
+ return null;
66
+ const iframe = guide.document.defaultView?.frameElement;
67
+ if (!(iframe instanceof HTMLIFrameElement))
68
+ return null;
69
+ const iframeRect = iframe.getBoundingClientRect();
70
+ const project = (rect, scaleWidth, scaleHeight) => ({
71
+ left: iframeRect.left + rect.left * zoom,
72
+ top: iframeRect.top + rect.top * zoom,
73
+ width: scaleWidth ? rect.width * zoom : rect.width,
74
+ height: scaleHeight ? rect.height * zoom : rect.height,
75
+ });
76
+ return {
77
+ orientation: guide.orientation,
78
+ line: project(guide.line, guide.orientation === "horizontal", guide.orientation === "vertical"),
79
+ target: project(guide.target, true, true),
80
+ };
81
+ }
82
+ export function CanvasElementOverlay() {
83
+ const [hover, setHover] = useState(null);
84
+ const [measureState, setMeasureState] = useState(null);
85
+ const [, refreshSelectedGeometry] = useReducer((revision) => revision + 1, 0);
86
+ const selected = useSelectedElement();
87
+ const selectedElements = useSelectedElements();
88
+ const camera = useBoardCamera();
89
+ useCanvasCards(); // Projected geometry must follow card drag and resize updates.
90
+ const dragRef = useRef(null);
91
+ const dropGuide = useDropGuide("canvas");
92
+ const projectedDropGuide = projectGuideToCanvas(dropGuide, camera.zoom);
93
+ const selectedFrame = selected?.domElement.ownerDocument.defaultView?.frameElement;
94
+ const selectedInCanvas = selectedFrame instanceof HTMLIFrameElement
95
+ && selectedFrame.hasAttribute("data-nudge-ui-canvas-renderer");
96
+ const selectedRects = selectedInCanvas
97
+ ? selectedElements.map((candidate) => {
98
+ const frame = candidate.domElement.ownerDocument.defaultView?.frameElement;
99
+ return frame === selectedFrame ? toRect(candidate.domElement.getBoundingClientRect()) : null;
100
+ })
101
+ : [];
102
+ const selectedPrimaryIndex = selectedElements.findIndex((candidate) => candidate.domElement === selected?.domElement);
103
+ const selectedLocalRect = selectedRects[selectedPrimaryIndex >= 0 ? selectedPrimaryIndex : 0] ?? null;
104
+ const selectedFrameRect = selectedInCanvas
105
+ ? toRect(selectedFrame.getBoundingClientRect())
106
+ : null;
107
+ const selectedRect = selectedInCanvas && selectedLocalRect
108
+ ? projectRect(selectedFrame, selectedLocalRect, camera.zoom)
109
+ : null;
110
+ const projectedSelectedGeometry = selectedInCanvas
111
+ ? selectedRects.flatMap((rect, index) => {
112
+ const element = selectedElements[index];
113
+ return rect && element
114
+ ? [{ element, rect: projectRect(selectedFrame, rect, camera.zoom) }]
115
+ : [];
116
+ })
117
+ : [];
118
+ const selectedBorders = selectedInCanvas && selected
119
+ ? readBorderWidths(selected.domElement)
120
+ : null;
121
+ useEffect(() => {
122
+ if (!selectedInCanvas || !selected)
123
+ return;
124
+ const stops = selectedElements.map((candidate) => observeSelectedGeometry(candidate.domElement, refreshSelectedGeometry));
125
+ return () => stops.forEach((stop) => stop());
126
+ }, [selected, selectedElements, selectedInCanvas]);
127
+ // The selected element's identity is computed once per selection change
128
+ // (never per hover), so the measurement self-rulers exclusion can compare
129
+ // identities without a per-hover scan of the frame document.
130
+ const selectedIdentity = useMemo(() => {
131
+ const el = selected?.domElement;
132
+ if (!el)
133
+ return null;
134
+ const elementId = el.getAttribute(RENDERER_ELEMENT_ID_ATTR);
135
+ return elementId ? { elementId } : null;
136
+ }, [selected?.domElement]);
137
+ useEffect(() => {
138
+ function onMessage(event) {
139
+ if (event.origin !== window.location.origin)
140
+ return;
141
+ if (!event.data || typeof event.data !== "object")
142
+ return;
143
+ const sourceFrame = findCanvasFrameBySource(event.source);
144
+ if (!sourceFrame)
145
+ return;
146
+ const { cardId: sourceCardId, iframe: sourceIframe } = sourceFrame;
147
+ const frameIdentity = {
148
+ projectId: PROJECT_ID,
149
+ workspaceId: WORKSPACE_ID,
150
+ cardId: sourceCardId,
151
+ };
152
+ if (!isRendererMessageFor(event.data, frameIdentity))
153
+ return;
154
+ // SAFETY: isRendererMessageFor validated the frame identity and message shape above.
155
+ const data = event.data;
156
+ if (data.type === "element-hover") {
157
+ const msg = data;
158
+ if (!msg.cid)
159
+ return;
160
+ if (msg.rect === null) {
161
+ setHover((current) => current?.cardId === sourceCardId ? null : current);
162
+ return;
163
+ }
164
+ setHover({
165
+ iframe: sourceIframe,
166
+ identity: { elementId: msg.elementId },
167
+ rect: msg.rect,
168
+ margins: msg.margins ?? { top: 0, right: 0, bottom: 0, left: 0 },
169
+ borders: msg.borders ?? { top: 0, right: 0, bottom: 0, left: 0 },
170
+ cardId: sourceCardId,
171
+ });
172
+ }
173
+ else if (data.type === "element-measure-state") {
174
+ const msg = data;
175
+ setMeasureState({
176
+ iframe: sourceIframe,
177
+ altKey: msg.altKey,
178
+ pointerOverPage: msg.pointerOverPage,
179
+ });
180
+ }
181
+ else if (data.type === "element-click") {
182
+ if (!isElementClickMessage(event.data, frameIdentity))
183
+ return;
184
+ const msg = data;
185
+ if (!msg.cid)
186
+ return;
187
+ handleElementClick(msg, sourceIframe, sourceCardId);
188
+ }
189
+ else if (data.type === "element-deselect") {
190
+ setSelectedElement(null);
191
+ }
192
+ else if (data.type === "element-drag-start") {
193
+ if (getSelectedElements().length > 1)
194
+ return;
195
+ const msg = data;
196
+ const element = findFrameElement(sourceIframe, msg.elementId, msg.cid, msg.src);
197
+ if (!element)
198
+ return;
199
+ dragRef.current = { iframe: sourceIframe, element };
200
+ const selectedElement = resolveSelectionFromElement(element);
201
+ if (selectedElement)
202
+ setSelectedElement(selectedElement);
203
+ updateDropGuide(msg.point, sourceIframe);
204
+ }
205
+ else if (data.type === "element-drag-move") {
206
+ updateDropGuide(data.point, sourceIframe);
207
+ }
208
+ else if (data.type === "element-drag-end") {
209
+ const msg = data;
210
+ const current = dragRef.current;
211
+ if (current && current.iframe === sourceIframe && sourceIframe.contentDocument) {
212
+ const drop = getDropLocationAtPoint(sourceIframe.contentDocument, current.element, msg.point.x, msg.point.y);
213
+ if (drop)
214
+ moveElement(current.element, drop);
215
+ const selectedElement = resolveSelectionFromElement(current.element);
216
+ if (selectedElement)
217
+ setSelectedElement(selectedElement);
218
+ }
219
+ dragRef.current = null;
220
+ clearDropGuide("canvas");
221
+ }
222
+ else if (data.type === "element-delete") {
223
+ if (getSelectedElements().length !== 1)
224
+ return;
225
+ const msg = data;
226
+ const element = findFrameElement(sourceIframe, msg.elementId, msg.cid, msg.src);
227
+ const selectedElement = element ? resolveSelectionFromElement(element) : null;
228
+ if (selectedElement && deleteElement(selectedElement))
229
+ setSelectedElement(null);
230
+ }
231
+ else if (data.type === "element-nudge") {
232
+ if (getSelectedElements().length !== 1)
233
+ return;
234
+ const msg = data;
235
+ const element = findFrameElement(sourceIframe, msg.elementId, msg.cid, msg.src);
236
+ const record = element ? nudgeElement(element, msg.key) : null;
237
+ if (element && record) {
238
+ const selectedElement = resolveSelectionFromElement(element);
239
+ if (selectedElement)
240
+ setSelectedElement(selectedElement);
241
+ }
242
+ }
243
+ else if (data.type === "history-request") {
244
+ const msg = data;
245
+ if (msg.action === "redo") {
246
+ redo();
247
+ }
248
+ else {
249
+ undo();
250
+ }
251
+ }
252
+ function updateDropGuide(point, iframe) {
253
+ const current = dragRef.current;
254
+ if (!current || current.iframe !== iframe || !iframe.contentDocument)
255
+ return;
256
+ const drop = getDropLocationAtPoint(iframe.contentDocument, current.element, point.x, point.y);
257
+ if (!drop) {
258
+ clearDropGuide("canvas");
259
+ return;
260
+ }
261
+ showDropGuide("canvas", iframe.contentDocument, drop);
262
+ }
263
+ }
264
+ window.addEventListener("message", onMessage);
265
+ return () => {
266
+ window.removeEventListener("message", onMessage);
267
+ clearDropGuide("canvas");
268
+ };
269
+ }, []);
270
+ if (!hover && projectedSelectedGeometry.length === 0 && !projectedDropGuide)
271
+ return null;
272
+ const projectedHoverRect = hover ? projectRect(hover.iframe, hover.rect, camera.zoom) : null;
273
+ const hoverMargins = hover ? scaleMargins(hover.margins, camera.zoom) : null;
274
+ const hoverMarginGuides = projectedHoverRect && hoverMargins
275
+ ? getMarginGuides(projectedHoverRect, hoverMargins)
276
+ : [];
277
+ const hoverMarginFills = projectedHoverRect && hoverMargins
278
+ ? getMarginFills(projectedHoverRect, hoverMargins)
279
+ : [];
280
+ const measureStateForSelectedFrame = measureState?.iframe === selectedFrame ? measureState : null;
281
+ const hoverInSelectedFrame = hover?.iframe === selectedFrame ? hover : null;
282
+ const showGuideOverlay = Boolean(selectedElements.length === 1
283
+ && selectedRect
284
+ && selectedFrameRect
285
+ && measureStateForSelectedFrame?.altKey
286
+ && measureStateForSelectedFrame.pointerOverPage);
287
+ const isSelfHover = Boolean(hoverInSelectedFrame
288
+ && selectedIdentity
289
+ && hoverInSelectedFrame.identity.elementId === selectedIdentity.elementId);
290
+ const showMeasurement = Boolean(showGuideOverlay
291
+ && selectedLocalRect
292
+ && hoverInSelectedFrame
293
+ && !isSelfHover);
294
+ const measurementSegments = showMeasurement && selectedFrameRect && selectedLocalRect && hoverInSelectedFrame
295
+ ? projectMeasurementSegments(selectedFrameRect, getMeasurementGeometry(selectedLocalRect, hoverInSelectedFrame.rect, {
296
+ selectedBorders: selectedBorders ?? undefined,
297
+ hoveredBorders: hoverInSelectedFrame.borders,
298
+ }).segments, camera.zoom)
299
+ : [];
300
+ return (_jsxs(_Fragment, { children: [_jsx("style", { "data-test": "canvas-element-overlay-styles", children: overlayStyles }), showGuideOverlay && selectedRect && selectedFrameRect ? (_jsx(MeasurementGuideOverlay, { testId: "canvas-measurement-overlay", selectedRect: selectedRect, guideViewport: selectedFrameRect, segments: measurementSegments })) : null, projectedHoverRect ? (_jsxs(_Fragment, { children: [hoverMarginFills.map((fill) => (_jsx("div", { className: "canvas-hover-margin-fill", "data-side": fill.side, style: overlayStyle(fill), "aria-hidden": "true" }, fill.side))), _jsx("div", { className: "canvas-element-overlay", "data-test": "canvas-hover-outline", style: overlayStyle(projectedHoverRect), "aria-hidden": "true" }), hoverMarginGuides.map((guide) => (_jsx("div", { className: "canvas-hover-margin", "data-axis": guide.axis, "data-distance": guide.distance, "data-side": guide.side, style: overlayStyle(guide), "aria-hidden": "true" }, guide.side)))] })) : null, projectedSelectedGeometry.map(({ element, rect }, index) => (_jsx("div", { className: "canvas-selected-outline", "data-test": "canvas-selected-outline", "data-selected-cid": element.cid, "data-selected-index": index, "data-selected-src": element.src, style: overlayStyle(rect), "aria-hidden": "true" }, `${element.cid}-${index}`))), _jsx(DropGuideOverlay, { guide: projectedDropGuide, lineClassName: "canvas-dom-drop-line", lineTestId: "canvas-dom-drop-line", targetClassName: "canvas-dom-drop-target", targetTestId: "canvas-dom-drop-target" })] }));
301
+ }
@@ -0,0 +1,2 @@
1
+ import { type ReactElement } from "react";
2
+ export declare function CanvasWorkspace(): ReactElement | null;
@@ -0,0 +1,301 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useCallback, useEffect, useRef, useState } from "react";
3
+ import { useCanvasCards, exitCanvas, exitCanvasToCard, addCanvasCard, removeCanvasCard, findCardByNormalizedUrl, focusCard, getSelectedCardId, setBoardCamera, getBoardCamera, fitAllCards, hasFitAllRan, useBoardCamera, } from "./canvasStore.js";
4
+ import { CanvasCard } from "./CanvasCard.js";
5
+ import { useCanvasMode } from "./canvasStore.js";
6
+ import { subscribeChanges } from "../changes/changesLog.js";
7
+ import { recordCanvasStructuralProjectionReports } from "../projection/structuralProjection.js";
8
+ import { recordCanvasRenderedInstanceProjectionReports } from "../projection/renderedInstance.js";
9
+ import { recordCanvasTextProjectionReports } from "../projection/textProjection.js";
10
+ import { findCanvasFrameBySource, getRegisteredFrames, PROJECT_ID, projectToAllReadyCards, recordCanvasProjectionApplied, WORKSPACE_ID, } from "./projection.js";
11
+ import { normalizeUrl } from "./normalizeUrl.js";
12
+ import { PROTOCOL_VERSION, isRendererMessageFor, isProjectionAppliedMessage, isRenderedInstanceProjectionReportMessage, isTextProjectionReportMessage, isStructuralProjectionReportMessage, } from "./frameProtocol.js";
13
+ import { iframePointToClientPoint, zoomCameraAtPointer } from "./canvasGestures.js";
14
+ const canvasWorkspaceStyles = ".canvas-workspace {\n position: fixed;\n inset: 0;\n display: flex;\n flex-direction: column;\n background: #ffffff;\n pointer-events: auto;\n}\n\n.canvas-workspace__board {\n flex: 1;\n overflow: hidden;\n position: relative;\n background: #ffffff;\n}\n\n.canvas-workspace__board.is-grabbable {\n cursor: grab;\n}\n\n.canvas-workspace__board.is-grabbing {\n cursor: grabbing;\n}\n\n/* Canvas gestures take precedence over every card interaction while Space is\n held. This also closes the short postMessage gap before an iframe receives\n its mirrored modifier state. */\n.canvas-workspace__board.is-grabbable .canvas-card,\n.canvas-workspace__board.is-grabbing .canvas-card {\n pointer-events: none;\n}\n\n.canvas-workspace__board-content {\n position: absolute;\n will-change: transform;\n}\n";
15
+ const canvasCardStyles = ".canvas-card {\n position: relative;\n}\n\n.canvas-card__frame {\n position: relative;\n width: 100%;\n height: 100%;\n background: var(--surface-panel);\n border-radius: var(--radius-control);\n overflow: hidden;\n}\n\n.canvas-card.is-selected .canvas-card__frame {\n outline: 2px solid var(--accent);\n outline-offset: -2px;\n}\n\n.canvas-card.is-focused .canvas-card__frame {\n animation: canvas-card-focus 900ms ease-out;\n}\n\n@keyframes canvas-card-focus {\n 0%, 35% { outline: 3px solid var(--accent); outline-offset: -3px; }\n 100% { outline: 0 solid transparent; outline-offset: -2px; }\n}\n\n.canvas-card__toolbar {\n display: flex;\n align-items: center;\n position: absolute;\n left: 0;\n right: 0;\n bottom: calc(100% + var(--space-8));\n justify-content: space-between;\n z-index: 1;\n cursor: grab;\n}\n\n.canvas-card.is-dragging .canvas-card__toolbar {\n cursor: grabbing;\n}\n\n.canvas-card__drag-surface {\n display: flex;\n align-items: center;\n flex: 1 1 auto;\n min-width: 0;\n min-height: var(--control-height-large);\n padding: 0 var(--space-12);\n cursor: grab;\n user-select: none;\n touch-action: none;\n}\n\n.canvas-card.is-dragging .canvas-card__drag-surface {\n cursor: grabbing;\n}\n\n.canvas-card__dimensions {\n color: var(--text-secondary);\n font-size: var(--font-size-base);\n font-variant-numeric: tabular-nums;\n white-space: nowrap;\n}\n\n.canvas-card__actions {\n display: flex;\n align-items: center;\n gap: var(--space-4);\n flex-shrink: 0;\n}\n\n.canvas-card__iframe {\n width: 100%;\n height: 100%;\n border: none;\n display: block;\n}\n\n.canvas-card__loading {\n display: flex;\n align-items: center;\n justify-content: center;\n height: 100%;\n color: var(--text-muted, #777777);\n font-size: 12px;\n font-weight: 500;\n}\n\n.canvas-card__error {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 12px;\n height: 100%;\n padding: 20px;\n text-align: center;\n}\n\n.canvas-card__error p {\n margin: 0;\n color: var(--text-muted, #777777);\n font-size: 12px;\n font-weight: 500;\n}\n\n.canvas-card__error-actions {\n display: flex;\n gap: 8px;\n}\n\n.canvas-card__resize-handle {\n position: absolute;\n bottom: 0;\n right: 0;\n width: 24px;\n height: 24px;\n display: flex;\n align-items: flex-end;\n justify-content: flex-end;\n padding: 4px;\n cursor: nwse-resize;\n color: var(--text-muted, #777777);\n opacity: 0;\n transition: opacity 150ms ease;\n touch-action: none;\n}\n\n.canvas-card:hover .canvas-card__resize-handle,\n.canvas-card:focus-within .canvas-card__resize-handle {\n opacity: 1;\n}\n\n.canvas-card__resize-handle:hover {\n color: var(--accent);\n}\n\n.canvas-card__resize-handle:focus-visible {\n outline: 2px solid var(--accent);\n outline-offset: 1px;\n opacity: 1;\n}\n";
16
+ const foundationStyles = ":host {\n all: initial;\n --surface-panel: #F5F5F4;\n --surface-control: var(--surface-well);\n --surface-control-hover: var(--surface-well-2x);\n --surface-raised: #FAFAFA;\n --surface-raised-2x: #fff ;\n --surface-raised-hover: #F5F5F4;\n --surface-well: hsla(0, 0%, 0%, 0.05);\n --surface-well-2x: hsla(0, 0%, 0%, 0.10);\n\n --border-subtle: hsla(0, 0%, 0%, 0.1);\n --border-medium: hsla(0, 0%, 0%, 0.2);\n --border-strong: #d8d8d8;\n\n --text-primary: #242424;\n --text-secondary: #6f6f6f;\n --text-muted: #777777;\n --text-muted-subtle: #a1a1a1;\n\n --accent: #0096ff;\n --accent-surface: rgba(0, 176, 255, 0.15);\n --warning: #d97706;\n --warning-text: #9a5b00;\n --warning-surface: #fff6e5;\n --danger: #df4b4b;\n --danger-text: #bd3636;\n --danger-surface: #fff0f0;\n\n --space-0: 0;\n --space-4: 4px;\n --space-8: 8px;\n --space-12: 12px;\n --space-16: 16px;\n --space-20: 20px;\n --space-24: 24px;\n --space-32: 32px;\n --space-40: 40px;\n --space-48: 48px;\n\n /* Radius */\n --radius-0: 0;\n --radius-4: 4px;\n --radius-8: 8px;\n --radius-12: 12px;\n --radius-16: 16px;\n --radius-20: 20px;\n --radius-24: 24px;\n --radius-pill: 999px;\n\n --radius-control: var(--radius-8);\n --shadow-outline: 0 0 0 1px rgba(0, 0, 0, 0.05);\n --shadow-popup: 0 0 0 1px rgba(0, 0, 0, 0.05), 0 4px 16px rgba(0, 0, 0, 0.10);\n --shadow-control: inset 0 -2px 0 rgba(0, 0, 0, 0.03), 0 0 0 0.5px rgba(0, 0, 0, 0.25);\n --z-index: 2147483647;\n\n --font-family: \"Inter Variable\", Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif;\n --font-size-base: 12px;\n --font-size-small: 10px;\n --font-weight-base: 400;\n --font-weight-label: 600;\n\n /* Control semantic sizes */\n --control-height-small: 24px;\n --control-height-large: 32px;\n --label-column: 104px;\n\n --icon-size-small: 16px;\n --icon-size-large: 20px;\n --icon-stroke-width: 1.5px;\n\n position: fixed;\n inset: 0;\n z-index: var(--z-index);\n pointer-events: none;\n font-family: var(--font-family);\n background: transparent;\n box-sizing: border-box;\n}\n\n*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\nbutton,\ninput,\nselect {\n font-family: inherit;\n}\n";
17
+ import { useInspectorOpen } from "../shell/openStore.js";
18
+ import { isEditableEvent } from "../shell/shortcuts.js";
19
+ import { acknowledgeAgentRendererReady } from "./agentPresentation.js";
20
+ import { useInspectorSession } from "../session/sessionContext.js";
21
+ const WORKSPACE_STYLES = [foundationStyles, canvasWorkspaceStyles, canvasCardStyles].join("\n");
22
+ export function CanvasWorkspace() {
23
+ const mode = useCanvasMode();
24
+ const inspectorSession = useInspectorSession();
25
+ const inspectorOpen = useInspectorOpen();
26
+ const cards = useCanvasCards();
27
+ const camera = useBoardCamera();
28
+ const boardRef = useRef(null);
29
+ const panningRef = useRef(false);
30
+ const panOriginRef = useRef({ x: 0, y: 0 });
31
+ const cameraAtPanStartRef = useRef({ x: 0, y: 0 });
32
+ const framePanContextRef = useRef(null);
33
+ const spaceHeldRef = useRef(false);
34
+ const fitAllScheduledRef = useRef(false);
35
+ const [boardCursorClass, setBoardCursorClass] = useState("");
36
+ const sendPanModifier = useCallback((iframe, cardId, spaceHeld) => {
37
+ iframe.contentWindow?.postMessage({
38
+ type: "pan-modifier",
39
+ protocolVersion: PROTOCOL_VERSION,
40
+ projectId: PROJECT_ID,
41
+ workspaceId: WORKSPACE_ID,
42
+ cardId,
43
+ spaceHeld,
44
+ }, window.location.origin);
45
+ }, []);
46
+ const broadcastPanModifier = useCallback((spaceHeld) => {
47
+ for (const [cardId, iframe] of getRegisteredFrames()) {
48
+ sendPanModifier(iframe, cardId, spaceHeld);
49
+ }
50
+ }, [sendPanModifier]);
51
+ const zoomAtPointer = useCallback((point, deltaY) => {
52
+ const board = boardRef.current;
53
+ if (!board)
54
+ return;
55
+ setBoardCamera(zoomCameraAtPointer(getBoardCamera(), point, board.getBoundingClientRect(), deltaY));
56
+ }, []);
57
+ const fitCanvasToBoard = useCallback(() => {
58
+ const board = boardRef.current;
59
+ fitAllCards(board ? { width: board.clientWidth, height: board.clientHeight } : undefined);
60
+ }, []);
61
+ const startPanning = useCallback((point) => {
62
+ if (panningRef.current)
63
+ return;
64
+ panningRef.current = true;
65
+ setBoardCursorClass("is-grabbing");
66
+ panOriginRef.current = point;
67
+ const current = getBoardCamera();
68
+ cameraAtPanStartRef.current = { x: current.x, y: current.y };
69
+ }, []);
70
+ const movePanning = useCallback((point) => {
71
+ if (!panningRef.current)
72
+ return;
73
+ const cameraAtStart = cameraAtPanStartRef.current;
74
+ const current = getBoardCamera();
75
+ setBoardCamera({
76
+ x: cameraAtStart.x + point.x - panOriginRef.current.x,
77
+ y: cameraAtStart.y + point.y - panOriginRef.current.y,
78
+ zoom: current.zoom,
79
+ });
80
+ }, []);
81
+ const endPanning = useCallback(() => {
82
+ if (!panningRef.current)
83
+ return;
84
+ panningRef.current = false;
85
+ setBoardCursorClass(spaceHeldRef.current ? "is-grabbable" : "");
86
+ }, []);
87
+ useEffect(() => {
88
+ return subscribeChanges(() => {
89
+ projectToAllReadyCards();
90
+ });
91
+ }, []);
92
+ useEffect(() => {
93
+ function onMessage(event) {
94
+ if (event.origin !== window.location.origin)
95
+ return;
96
+ if (!event.data || typeof event.data !== "object")
97
+ return;
98
+ const frame = findCanvasFrameBySource(event.source);
99
+ if (!frame)
100
+ return;
101
+ if (!isRendererMessageFor(event.data, {
102
+ projectId: PROJECT_ID,
103
+ workspaceId: WORKSPACE_ID,
104
+ cardId: frame.cardId,
105
+ }))
106
+ return;
107
+ const identity = {
108
+ projectId: PROJECT_ID,
109
+ workspaceId: WORKSPACE_ID,
110
+ cardId: frame.cardId,
111
+ };
112
+ if (isProjectionAppliedMessage(event.data, identity)) {
113
+ recordCanvasProjectionApplied(frame.cardId, event.data.revision);
114
+ return;
115
+ }
116
+ if (isStructuralProjectionReportMessage(event.data, identity)) {
117
+ recordCanvasStructuralProjectionReports(frame.cardId, event.data.revision, event.data.reports);
118
+ return;
119
+ }
120
+ if (isRenderedInstanceProjectionReportMessage(event.data, identity)) {
121
+ recordCanvasRenderedInstanceProjectionReports(frame.cardId, event.data.revision, event.data.reports);
122
+ return;
123
+ }
124
+ if (isTextProjectionReportMessage(event.data, identity)) {
125
+ recordCanvasTextProjectionReports(frame.cardId, event.data.revision, event.data.reports);
126
+ return;
127
+ }
128
+ // SAFETY: isRendererMessageFor validated the frame identity and message shape above.
129
+ const msg = event.data;
130
+ if (msg.type === "frame-ready") {
131
+ acknowledgeAgentRendererReady(frame.cardId);
132
+ // A card can finish loading after Space was pressed on the controller.
133
+ // Seed it with the current modifier state before its first pointer event.
134
+ sendPanModifier(frame.iframe, frame.cardId, spaceHeldRef.current);
135
+ }
136
+ if (msg.type === "pan-modifier") {
137
+ spaceHeldRef.current = msg.spaceHeld;
138
+ if (!panningRef.current) {
139
+ setBoardCursorClass(msg.spaceHeld ? "is-grabbable" : "");
140
+ }
141
+ broadcastPanModifier(msg.spaceHeld);
142
+ return;
143
+ }
144
+ if (msg.type === "zoom") {
145
+ const iframeRect = frame.iframe.getBoundingClientRect();
146
+ const point = iframePointToClientPoint(iframeRect, msg.point, getBoardCamera().zoom);
147
+ zoomAtPointer(point, msg.deltaY);
148
+ return;
149
+ }
150
+ const pointInBoard = (point) => {
151
+ const context = framePanContextRef.current;
152
+ if (!context)
153
+ return null;
154
+ return {
155
+ x: context.left + point.x * context.zoom,
156
+ y: context.top + point.y * context.zoom,
157
+ };
158
+ };
159
+ if (msg.type === "pan-start") {
160
+ const iframeRect = frame.iframe.getBoundingClientRect();
161
+ framePanContextRef.current = {
162
+ left: iframeRect.left,
163
+ top: iframeRect.top,
164
+ zoom: getBoardCamera().zoom,
165
+ };
166
+ const point = pointInBoard(msg.point);
167
+ if (point)
168
+ startPanning(point);
169
+ return;
170
+ }
171
+ if (msg.type === "pan-move") {
172
+ const point = pointInBoard(msg.point);
173
+ if (point)
174
+ movePanning(point);
175
+ return;
176
+ }
177
+ if (msg.type === "pan-end") {
178
+ framePanContextRef.current = null;
179
+ endPanning();
180
+ return;
181
+ }
182
+ if (msg.type === "external-navigation") {
183
+ const destination = normalizeUrl(msg.url);
184
+ if (!destination || destination.origin === window.location.origin)
185
+ return;
186
+ exitCanvas();
187
+ window.location.href = msg.url;
188
+ return;
189
+ }
190
+ if (msg.type !== "navigation-intent")
191
+ return;
192
+ const normalized = normalizeUrl(msg.url);
193
+ if (!normalized || normalized.origin !== window.location.origin)
194
+ return;
195
+ const existing = findCardByNormalizedUrl(normalized);
196
+ if (existing) {
197
+ focusCard(existing.id);
198
+ }
199
+ else {
200
+ addCanvasCard(msg.url);
201
+ }
202
+ }
203
+ window.addEventListener("message", onMessage);
204
+ return () => window.removeEventListener("message", onMessage);
205
+ }, [broadcastPanModifier, endPanning, movePanning, sendPanModifier, startPanning, zoomAtPointer]);
206
+ useEffect(() => {
207
+ if (mode === "canvas" && !hasFitAllRan()) {
208
+ if (!fitAllScheduledRef.current) {
209
+ fitAllScheduledRef.current = true;
210
+ requestAnimationFrame(() => {
211
+ fitCanvasToBoard();
212
+ fitAllScheduledRef.current = false;
213
+ });
214
+ }
215
+ }
216
+ }, [mode, cards.length, inspectorOpen, fitCanvasToBoard]);
217
+ useEffect(() => {
218
+ function onKeyDown(e) {
219
+ if (mode !== "canvas")
220
+ return;
221
+ if ((e.key === "Delete" || e.key === "Backspace") && !isEditableEvent(e)) {
222
+ const selectedCardId = getSelectedCardId();
223
+ if (!selectedCardId)
224
+ return;
225
+ e.preventDefault();
226
+ removeCanvasCard(selectedCardId);
227
+ return;
228
+ }
229
+ if (e.code === "Space" && !e.repeat) {
230
+ // SAFETY: keyboard event targets are HTMLElements in the workspace DOM.
231
+ const target = e.target;
232
+ if (target && (target.tagName === "INPUT" || target.tagName === "TEXTAREA" || target.isContentEditable))
233
+ return;
234
+ e.preventDefault();
235
+ spaceHeldRef.current = true;
236
+ broadcastPanModifier(true);
237
+ if (!panningRef.current) {
238
+ setBoardCursorClass("is-grabbable");
239
+ }
240
+ }
241
+ }
242
+ function onKeyUp(e) {
243
+ if (e.code === "Space") {
244
+ spaceHeldRef.current = false;
245
+ broadcastPanModifier(false);
246
+ if (!panningRef.current) {
247
+ setBoardCursorClass("");
248
+ }
249
+ }
250
+ }
251
+ window.addEventListener("keydown", onKeyDown, true);
252
+ window.addEventListener("keyup", onKeyUp, true);
253
+ return () => {
254
+ window.removeEventListener("keydown", onKeyDown, true);
255
+ window.removeEventListener("keyup", onKeyUp, true);
256
+ };
257
+ }, [broadcastPanModifier, mode]);
258
+ const handleBoardPointerDown = useCallback((e) => {
259
+ if (panningRef.current)
260
+ return;
261
+ if (!spaceHeldRef.current)
262
+ return;
263
+ e.preventDefault();
264
+ e.stopPropagation();
265
+ startPanning({ x: e.clientX, y: e.clientY });
266
+ // SAFETY: pointerdown targets are HTMLElements in the workspace DOM.
267
+ e.target.setPointerCapture(e.pointerId);
268
+ function onMove(ev) {
269
+ movePanning({ x: ev.clientX, y: ev.clientY });
270
+ }
271
+ function onUp() {
272
+ endPanning();
273
+ window.removeEventListener("pointermove", onMove);
274
+ window.removeEventListener("pointerup", onUp);
275
+ }
276
+ window.addEventListener("pointermove", onMove);
277
+ window.addEventListener("pointerup", onUp);
278
+ }, [endPanning, movePanning, startPanning]);
279
+ useEffect(() => {
280
+ if (mode !== "canvas")
281
+ return;
282
+ function handleGlobalWheel(e) {
283
+ if (!e.ctrlKey && !e.metaKey)
284
+ return;
285
+ e.preventDefault();
286
+ e.stopPropagation();
287
+ zoomAtPointer({ x: e.clientX, y: e.clientY }, e.deltaY);
288
+ }
289
+ window.addEventListener("wheel", handleGlobalWheel, { capture: true, passive: false });
290
+ return () => window.removeEventListener("wheel", handleGlobalWheel, { capture: true });
291
+ }, [mode, zoomAtPointer]);
292
+ function handleEdit(card) {
293
+ exitCanvasToCard(card);
294
+ }
295
+ if (mode !== "canvas" || cards.length === 0)
296
+ return null;
297
+ return (_jsxs(_Fragment, { children: [_jsx("style", { "data-test": "canvas-styles", children: WORKSPACE_STYLES }), _jsx("div", { className: "canvas-workspace", "data-test": "canvas-workspace", style: { right: inspectorOpen ? "min(320px, 100vw)" : 0 }, children: _jsx("div", { className: `canvas-workspace__board ${boardCursorClass}`.trim(), "data-test": "canvas-board", ref: boardRef, onPointerDown: handleBoardPointerDown, children: _jsx("div", { className: "canvas-workspace__board-content", style: {
298
+ transform: `translate(${camera.x}px, ${camera.y}px) scale(${camera.zoom})`,
299
+ transformOrigin: "0 0",
300
+ }, "data-test": "canvas-board-content", children: cards.map((card) => (_jsx(CanvasCard, { card: card, onEdit: handleEdit, documentOwner: inspectorSession }, card.id))) }) }) })] }));
301
+ }
@@ -0,0 +1,6 @@
1
+ import type { ReactElement } from "react";
2
+ interface LockedWorkspaceNoticeProps {
3
+ onTakeover: () => void;
4
+ }
5
+ export declare function LockedWorkspaceNotice({ onTakeover }: LockedWorkspaceNoticeProps): ReactElement;
6
+ export {};
@@ -0,0 +1,17 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { useState } from "react";
3
+ import { requestTakeover } from "./workspaceLease.js";
4
+ import { Button } from "../ui/Button.js";
5
+ import { UI_STYLES } from "../ui/styles.js";
6
+ const lockedWorkspaceStyles = ".locked-notice {\n position: fixed;\n top: max(12px, env(safe-area-inset-top));\n right: max(12px, env(safe-area-inset-right));\n width: min(320px, calc(100vw - 24px));\n padding: 18px;\n border-radius: 12px;\n background: var(--surface-raised-2x);\n box-shadow: var(--shadow-popup);\n color: var(--text-primary);\n font-family: var(--font-family);\n pointer-events: auto;\n}\n\n.locked-notice__message {\n margin-bottom: 14px;\n font-size: 14px;\n font-weight: 650;\n}\n";
7
+ export function LockedWorkspaceNotice({ onTakeover }) {
8
+ const [takingOver, setTakingOver] = useState(false);
9
+ function handleTakeover() {
10
+ setTakingOver(true);
11
+ if (requestTakeover())
12
+ onTakeover();
13
+ else
14
+ setTakingOver(false);
15
+ }
16
+ return (_jsxs(_Fragment, { children: [_jsx("style", { "data-test": "locked-workspace-styles", children: `${UI_STYLES}\n${lockedWorkspaceStyles}` }), _jsxs("aside", { className: "locked-notice", "data-test": "locked-workspace-notice", "aria-live": "polite", children: [_jsx("div", { className: "locked-notice__message", children: "Nudge UI is open in another tab" }), _jsx(Button, { "data-test": "takeover-here", disabled: takingOver, onClick: handleTakeover, children: takingOver ? "Taking over..." : "Take Over Here" })] })] }));
17
+ }
@@ -0,0 +1,7 @@
1
+ import type { ReactElement } from "react";
2
+ import type { ChangeRecord } from "../changes/changesLog.js";
3
+ interface Props {
4
+ change: ChangeRecord;
5
+ }
6
+ export declare function StaleChangeIndicator({ change }: Props): ReactElement | null;
7
+ export {};