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.
- package/README.md +66 -0
- package/bin/nudge-ui.mjs +7 -0
- package/dist/LICENSE +21 -0
- package/dist/client.mjs +261 -0
- package/dist/compiler/ast.d.ts +18 -0
- package/dist/compiler/ast.js +75 -0
- package/dist/compiler/componentContractTypes.d.ts +19 -0
- package/dist/compiler/componentContractTypes.js +1 -0
- package/dist/compiler/componentContracts.d.ts +2 -0
- package/dist/compiler/componentContracts.js +260 -0
- package/dist/compiler/componentInstrumentation.d.ts +32 -0
- package/dist/compiler/componentInstrumentation.js +140 -0
- package/dist/compiler/componentPolicyResolution.d.ts +71 -0
- package/dist/compiler/componentPolicyResolution.js +388 -0
- package/dist/compiler/index.d.ts +9 -0
- package/dist/compiler/index.js +9 -0
- package/dist/compiler/packageComponentContracts.d.ts +32 -0
- package/dist/compiler/packageComponentContracts.js +308 -0
- package/dist/compiler/reactComponentProtocols.d.ts +145 -0
- package/dist/compiler/reactComponentProtocols.js +47 -0
- package/dist/compiler/reactIdentity.d.ts +15 -0
- package/dist/compiler/reactIdentity.js +339 -0
- package/dist/compiler/sourcePaths.d.ts +12 -0
- package/dist/compiler/sourcePaths.js +27 -0
- package/dist/css/dialects/index.d.ts +62 -0
- package/dist/css/dialects/index.js +103 -0
- package/dist/css/dialects/tailwind.d.ts +46 -0
- package/dist/css/dialects/tailwind.js +119 -0
- package/dist/css/dialects/vanillaExtract.d.ts +20 -0
- package/dist/css/dialects/vanillaExtract.js +32 -0
- package/dist/css/index.d.ts +10 -0
- package/dist/css/index.js +10 -0
- package/dist/css/model/index.d.ts +190 -0
- package/dist/css/model/index.js +10 -0
- package/dist/css/token-inventory/index.d.ts +26 -0
- package/dist/css/token-inventory/index.js +24 -0
- package/dist/css/token-inventory/inventory.d.ts +8 -0
- package/dist/css/token-inventory/inventory.js +421 -0
- package/dist/css/token-inventory/parseStylesheet.d.ts +16 -0
- package/dist/css/token-inventory/parseStylesheet.js +155 -0
- package/dist/css/token-inventory/policy.d.ts +47 -0
- package/dist/css/token-inventory/policy.js +50 -0
- package/dist/css/token-inventory/types.d.ts +97 -0
- package/dist/css/token-inventory/types.js +1 -0
- package/dist/css/value-semantics/borderSemantics.d.ts +28 -0
- package/dist/css/value-semantics/borderSemantics.js +91 -0
- package/dist/css/value-semantics/boxSemantics.d.ts +37 -0
- package/dist/css/value-semantics/boxSemantics.js +71 -0
- package/dist/css/value-semantics/colorSemantics.d.ts +99 -0
- package/dist/css/value-semantics/colorSemantics.js +526 -0
- package/dist/css/value-semantics/cssSyntax.d.ts +19 -0
- package/dist/css/value-semantics/cssSyntax.js +111 -0
- package/dist/css/value-semantics/fontSemantics.d.ts +35 -0
- package/dist/css/value-semantics/fontSemantics.js +131 -0
- package/dist/css/value-semantics/index.d.ts +20 -0
- package/dist/css/value-semantics/index.js +15 -0
- package/dist/css/value-semantics/propertyPolicy.d.ts +118 -0
- package/dist/css/value-semantics/propertyPolicy.js +356 -0
- package/dist/css/value-semantics/stringMaps.d.ts +2 -0
- package/dist/css/value-semantics/stringMaps.js +1 -0
- package/dist/css/value-semantics/structuredValues.d.ts +64 -0
- package/dist/css/value-semantics/structuredValues.js +250 -0
- package/dist/css/value-semantics/tokenInterpretation.d.ts +90 -0
- package/dist/css/value-semantics/tokenInterpretation.js +193 -0
- package/dist/css/virtual-design-tokens.d.ts +17 -0
- package/dist/hosts/astro/astroRuntimeConfig.d.ts +12 -0
- package/dist/hosts/astro/astroRuntimeConfig.js +26 -0
- package/dist/hosts/astro/clientAsset.d.ts +12 -0
- package/dist/hosts/astro/clientAsset.js +51 -0
- package/dist/hosts/astro/clientTransport.d.ts +3 -0
- package/dist/hosts/astro/clientTransport.js +57 -0
- package/dist/hosts/astro/index.d.ts +3 -0
- package/dist/hosts/astro/index.js +2 -0
- package/dist/hosts/astro/integration.d.ts +35 -0
- package/dist/hosts/astro/integration.js +96 -0
- package/dist/hosts/astro/middleware.d.ts +13 -0
- package/dist/hosts/astro/middleware.js +22 -0
- package/dist/hosts/astro/projectContext.d.ts +11 -0
- package/dist/hosts/astro/projectContext.js +34 -0
- package/dist/hosts/astro/responseInstrumentation.d.ts +41 -0
- package/dist/hosts/astro/responseInstrumentation.js +80 -0
- package/dist/hosts/next/index.d.ts +4 -0
- package/dist/hosts/next/index.js +7 -0
- package/dist/hosts/next/loader.d.ts +66 -0
- package/dist/hosts/next/loader.js +346 -0
- package/dist/hosts/next/loaders/identity-loader.cjs +228257 -0
- package/dist/hosts/next/loaders/loader-plugin.cjs +228257 -0
- package/dist/hosts/next/manifest.d.ts +38 -0
- package/dist/hosts/next/manifest.js +30 -0
- package/dist/hosts/next/mount.d.ts +12 -0
- package/dist/hosts/next/mount.js +23 -0
- package/dist/hosts/next/repositoryScope.d.ts +20 -0
- package/dist/hosts/next/repositoryScope.js +33 -0
- package/dist/hosts/next/sidecar.d.ts +27 -0
- package/dist/hosts/next/sidecar.js +526 -0
- package/dist/hosts/next/wrapper.d.ts +67 -0
- package/dist/hosts/next/wrapper.js +310 -0
- package/dist/hosts/static/cli.d.ts +12 -0
- package/dist/hosts/static/cli.js +77 -0
- package/dist/hosts/static/html/bootstrap.d.ts +27 -0
- package/dist/hosts/static/html/bootstrap.js +93 -0
- package/dist/hosts/static/index.d.ts +4 -0
- package/dist/hosts/static/index.js +4 -0
- package/dist/hosts/static/manifest.d.ts +18 -0
- package/dist/hosts/static/manifest.js +51 -0
- package/dist/hosts/static/server.d.ts +72 -0
- package/dist/hosts/static/server.js +554 -0
- package/dist/hosts/vite/index.d.ts +20 -0
- package/dist/hosts/vite/index.js +48 -0
- package/dist/hosts/vite/react.d.ts +67 -0
- package/dist/hosts/vite/react.js +231 -0
- package/dist/hosts/vite/tokens/activeStylesheets.d.ts +28 -0
- package/dist/hosts/vite/tokens/activeStylesheets.js +70 -0
- package/dist/hosts/vite/tokens/fileMap.d.ts +2 -0
- package/dist/hosts/vite/tokens/fileMap.js +1 -0
- package/dist/hosts/vite/tokens/viteStylesheetArtifacts.d.ts +46 -0
- package/dist/hosts/vite/tokens/viteStylesheetArtifacts.js +104 -0
- package/dist/hosts/vite/virtual/design-tokens.d.ts +9 -0
- package/dist/hosts/vite/virtual/design-tokens.js +7 -0
- package/dist/hosts/vite/virtual-design-tokens.d.ts +1 -0
- package/dist/hosts/vite/vite.d.ts +62 -0
- package/dist/hosts/vite/vite.js +854 -0
- package/dist/html/dom.d.ts +13 -0
- package/dist/html/dom.js +46 -0
- package/dist/html/identity.d.ts +40 -0
- package/dist/html/identity.js +196 -0
- package/dist/html/insertions.d.ts +26 -0
- package/dist/html/insertions.js +59 -0
- package/dist/inspector/agent/McpConnectionDialog.d.ts +26 -0
- package/dist/inspector/agent/McpConnectionDialog.js +135 -0
- package/dist/inspector/agent/client.d.ts +98 -0
- package/dist/inspector/agent/client.js +728 -0
- package/dist/inspector/agent/connectionStatus.d.ts +13 -0
- package/dist/inspector/agent/connectionStatus.js +35 -0
- package/dist/inspector/agent/httpTransport.d.ts +21 -0
- package/dist/inspector/agent/httpTransport.js +347 -0
- package/dist/inspector/agent/protocol.d.ts +95 -0
- package/dist/inspector/agent/protocol.js +9 -0
- package/dist/inspector/agent/verification.d.ts +39 -0
- package/dist/inspector/agent/verification.js +207 -0
- package/dist/inspector/canvas/CanvasCard.d.ts +10 -0
- package/dist/inspector/canvas/CanvasCard.js +275 -0
- package/dist/inspector/canvas/CanvasElementOverlay.d.ts +2 -0
- package/dist/inspector/canvas/CanvasElementOverlay.js +301 -0
- package/dist/inspector/canvas/CanvasWorkspace.d.ts +2 -0
- package/dist/inspector/canvas/CanvasWorkspace.js +301 -0
- package/dist/inspector/canvas/LockedWorkspaceNotice.d.ts +6 -0
- package/dist/inspector/canvas/LockedWorkspaceNotice.js +17 -0
- package/dist/inspector/canvas/StaleChangeIndicator.d.ts +7 -0
- package/dist/inspector/canvas/StaleChangeIndicator.js +43 -0
- package/dist/inspector/canvas/agentPresentation.d.ts +87 -0
- package/dist/inspector/canvas/agentPresentation.js +421 -0
- package/dist/inspector/canvas/canvasGestures.d.ts +12 -0
- package/dist/inspector/canvas/canvasGestures.js +21 -0
- package/dist/inspector/canvas/canvasStore.d.ts +108 -0
- package/dist/inspector/canvas/canvasStore.js +448 -0
- package/dist/inspector/canvas/frameProtocol.d.ts +231 -0
- package/dist/inspector/canvas/frameProtocol.js +165 -0
- package/dist/inspector/canvas/linkEligibility.d.ts +8 -0
- package/dist/inspector/canvas/linkEligibility.js +68 -0
- package/dist/inspector/canvas/measurementProjection.d.ts +8 -0
- package/dist/inspector/canvas/measurementProjection.js +16 -0
- package/dist/inspector/canvas/normalizeUrl.d.ts +7 -0
- package/dist/inspector/canvas/normalizeUrl.js +27 -0
- package/dist/inspector/canvas/projection.d.ts +41 -0
- package/dist/inspector/canvas/projection.js +232 -0
- package/dist/inspector/canvas/rendererBootstrap.d.ts +4 -0
- package/dist/inspector/canvas/rendererBootstrap.js +410 -0
- package/dist/inspector/canvas/rendererCidIndex.d.ts +11 -0
- package/dist/inspector/canvas/rendererCidIndex.js +21 -0
- package/dist/inspector/canvas/rendererElementSelector.d.ts +2 -0
- package/dist/inspector/canvas/rendererElementSelector.js +378 -0
- package/dist/inspector/canvas/rendererSelectionProxy.d.ts +2 -0
- package/dist/inspector/canvas/rendererSelectionProxy.js +61 -0
- package/dist/inspector/canvas/rendererStylesheet.d.ts +16 -0
- package/dist/inspector/canvas/rendererStylesheet.js +221 -0
- package/dist/inspector/canvas/resizeHandleScale.d.ts +13 -0
- package/dist/inspector/canvas/resizeHandleScale.js +20 -0
- package/dist/inspector/canvas/roleDetection.d.ts +5 -0
- package/dist/inspector/canvas/roleDetection.js +21 -0
- package/dist/inspector/canvas/sessionStore.d.ts +71 -0
- package/dist/inspector/canvas/sessionStore.js +453 -0
- package/dist/inspector/canvas/staleChangeDetector.d.ts +11 -0
- package/dist/inspector/canvas/staleChangeDetector.js +217 -0
- package/dist/inspector/canvas/toolbarScale.d.ts +7 -0
- package/dist/inspector/canvas/toolbarScale.js +11 -0
- package/dist/inspector/canvas/workspaceLease.d.ts +26 -0
- package/dist/inspector/canvas/workspaceLease.js +214 -0
- package/dist/inspector/changes/changesLog.d.ts +46 -0
- package/dist/inspector/changes/changesLog.js +209 -0
- package/dist/inspector/changes/codecs.d.ts +98 -0
- package/dist/inspector/changes/codecs.js +389 -0
- package/dist/inspector/changes/editModel.d.ts +74 -0
- package/dist/inspector/changes/editModel.js +120 -0
- package/dist/inspector/changes/managedStyleProjection.d.ts +6 -0
- package/dist/inspector/changes/managedStyleProjection.js +109 -0
- package/dist/inspector/changes/model.d.ts +13 -0
- package/dist/inspector/changes/model.js +163 -0
- package/dist/inspector/changes/presentation.d.ts +14 -0
- package/dist/inspector/changes/presentation.js +81 -0
- package/dist/inspector/changes/previewDiagnostics.d.ts +39 -0
- package/dist/inspector/changes/previewDiagnostics.js +172 -0
- package/dist/inspector/changes/structuralTypes.d.ts +35 -0
- package/dist/inspector/changes/structuralTypes.js +1 -0
- package/dist/inspector/changes/types.d.ts +76 -0
- package/dist/inspector/changes/types.js +16 -0
- package/dist/inspector/changes/workspaceChanges.d.ts +43 -0
- package/dist/inspector/changes/workspaceChanges.js +239 -0
- package/dist/inspector/clientManifest.d.ts +24 -0
- package/dist/inspector/clientManifest.js +69 -0
- package/dist/inspector/componentSemantics/ComponentPropsSection.d.ts +5 -0
- package/dist/inspector/componentSemantics/ComponentPropsSection.js +44 -0
- package/dist/inspector/componentSemantics/adapterRegistry.d.ts +11 -0
- package/dist/inspector/componentSemantics/adapterRegistry.js +75 -0
- package/dist/inspector/componentSemantics/boundaries.d.ts +2 -0
- package/dist/inspector/componentSemantics/boundaries.js +10 -0
- package/dist/inspector/componentSemantics/changeAction.d.ts +3 -0
- package/dist/inspector/componentSemantics/changeAction.js +6 -0
- package/dist/inspector/componentSemantics/changeModel.d.ts +8 -0
- package/dist/inspector/componentSemantics/changeModel.js +60 -0
- package/dist/inspector/componentSemantics/index.d.ts +4 -0
- package/dist/inspector/componentSemantics/index.js +2 -0
- package/dist/inspector/componentSemantics/reactRuntime.d.ts +10 -0
- package/dist/inspector/componentSemantics/reactRuntime.js +186 -0
- package/dist/inspector/componentSemantics/runtimeBridge.d.ts +25 -0
- package/dist/inspector/componentSemantics/runtimeBridge.js +161 -0
- package/dist/inspector/componentSemantics/runtimeTypes.d.ts +2 -0
- package/dist/inspector/componentSemantics/runtimeTypes.js +1 -0
- package/dist/inspector/componentSemantics/textBinding.d.ts +69 -0
- package/dist/inspector/componentSemantics/textBinding.js +514 -0
- package/dist/inspector/componentSemantics/types.d.ts +96 -0
- package/dist/inspector/componentSemantics/types.js +5 -0
- package/dist/inspector/conformance/borderCases.d.ts +7 -0
- package/dist/inspector/conformance/borderCases.js +428 -0
- package/dist/inspector/conformance/colorCases.d.ts +8 -0
- package/dist/inspector/conformance/colorCases.js +470 -0
- package/dist/inspector/conformance/fixture.d.ts +68 -0
- package/dist/inspector/conformance/fixture.js +153 -0
- package/dist/inspector/conformance/projection.d.ts +2 -0
- package/dist/inspector/conformance/projection.js +3 -0
- package/dist/inspector/conformance/spacingCases.d.ts +6 -0
- package/dist/inspector/conformance/spacingCases.js +417 -0
- package/dist/inspector/conformance/typographyCases.d.ts +7 -0
- package/dist/inspector/conformance/typographyCases.js +174 -0
- package/dist/inspector/editScope.d.ts +4 -0
- package/dist/inspector/editScope.js +5 -0
- package/dist/inspector/index.d.ts +20 -0
- package/dist/inspector/index.js +236 -0
- package/dist/inspector/inline-text/inlineTextEditor.d.ts +74 -0
- package/dist/inspector/inline-text/inlineTextEditor.js +1207 -0
- package/dist/inspector/inline-text/inlineTextLifecycle.d.ts +2 -0
- package/dist/inspector/inline-text/inlineTextLifecycle.js +17 -0
- package/dist/inspector/inline-text/textChangeBoundary.d.ts +6 -0
- package/dist/inspector/inline-text/textChangeBoundary.js +1 -0
- package/dist/inspector/inspection/bridge.d.ts +72 -0
- package/dist/inspector/inspection/bridge.js +134 -0
- package/dist/inspector/inspection/browserCssInspection.d.ts +74 -0
- package/dist/inspector/inspection/browserCssInspection.js +317 -0
- package/dist/inspector/inspection/browserCssInspectionRegistry.d.ts +12 -0
- package/dist/inspector/inspection/browserCssInspectionRegistry.js +66 -0
- package/dist/inspector/inspection/selectionProperty.d.ts +32 -0
- package/dist/inspector/inspection/selectionProperty.js +33 -0
- package/dist/inspector/inspection/useBrowserCssInspection.d.ts +20 -0
- package/dist/inspector/inspection/useBrowserCssInspection.js +159 -0
- package/dist/inspector/overlay/DropGuideOverlay.d.ts +17 -0
- package/dist/inspector/overlay/DropGuideOverlay.js +17 -0
- package/dist/inspector/overlay/InspectorOverlay.d.ts +5 -0
- package/dist/inspector/overlay/InspectorOverlay.js +328 -0
- package/dist/inspector/overlay/MeasurementGuideOverlay.d.ts +19 -0
- package/dist/inspector/overlay/MeasurementGuideOverlay.js +40 -0
- package/dist/inspector/overlay/clickPolicy.d.ts +7 -0
- package/dist/inspector/overlay/clickPolicy.js +13 -0
- package/dist/inspector/overlay/dropGuide.d.ts +22 -0
- package/dist/inspector/overlay/dropGuide.js +48 -0
- package/dist/inspector/overlay/elementSelector.d.ts +1 -0
- package/dist/inspector/overlay/elementSelector.js +100 -0
- package/dist/inspector/overlay/frameThrottle.d.ts +10 -0
- package/dist/inspector/overlay/frameThrottle.js +38 -0
- package/dist/inspector/overlay/interactionStyles.d.ts +3 -0
- package/dist/inspector/overlay/interactionStyles.js +70 -0
- package/dist/inspector/overlay/measurementGeometry.d.ts +25 -0
- package/dist/inspector/overlay/measurementGeometry.js +104 -0
- package/dist/inspector/overlay/overlayGeometry.d.ts +40 -0
- package/dist/inspector/overlay/overlayGeometry.js +59 -0
- package/dist/inspector/overlay/selectedGeometry.d.ts +7 -0
- package/dist/inspector/overlay/selectedGeometry.js +51 -0
- package/dist/inspector/overlay/structuralGestures.d.ts +28 -0
- package/dist/inspector/overlay/structuralGestures.js +180 -0
- package/dist/inspector/projection/cssEscapes.d.ts +3 -0
- package/dist/inspector/projection/cssEscapes.js +20 -0
- package/dist/inspector/projection/managedStylesheet.d.ts +33 -0
- package/dist/inspector/projection/managedStylesheet.js +240 -0
- package/dist/inspector/projection/renderedInstance.d.ts +56 -0
- package/dist/inspector/projection/renderedInstance.js +306 -0
- package/dist/inspector/projection/structuralProjection.d.ts +93 -0
- package/dist/inspector/projection/structuralProjection.js +560 -0
- package/dist/inspector/projection/structuralProjectionBoundary.d.ts +5 -0
- package/dist/inspector/projection/structuralProjectionBoundary.js +65 -0
- package/dist/inspector/projection/textProjection.d.ts +53 -0
- package/dist/inspector/projection/textProjection.js +705 -0
- package/dist/inspector/projection/workspaceProjection.d.ts +43 -0
- package/dist/inspector/projection/workspaceProjection.js +58 -0
- package/dist/inspector/prompt/PromptSettingsDialog.d.ts +15 -0
- package/dist/inspector/prompt/PromptSettingsDialog.js +17 -0
- package/dist/inspector/prompt/clipboardHandoff.d.ts +34 -0
- package/dist/inspector/prompt/clipboardHandoff.js +212 -0
- package/dist/inspector/prompt/copyToClipboard.d.ts +1 -0
- package/dist/inspector/prompt/copyToClipboard.js +34 -0
- package/dist/inspector/prompt/detectFramework.d.ts +6 -0
- package/dist/inspector/prompt/detectFramework.js +4 -0
- package/dist/inspector/prompt/generatePrompt.d.ts +7 -0
- package/dist/inspector/prompt/generatePrompt.js +391 -0
- package/dist/inspector/prompt/promptSettings.d.ts +8 -0
- package/dist/inspector/prompt/promptSettings.js +28 -0
- package/dist/inspector/runtime/devFlag.d.ts +28 -0
- package/dist/inspector/runtime/devFlag.js +50 -0
- package/dist/inspector/runtime/documentStylesheetOrder.d.ts +19 -0
- package/dist/inspector/runtime/documentStylesheetOrder.js +89 -0
- package/dist/inspector/runtime/domRealm.d.ts +4 -0
- package/dist/inspector/runtime/domRealm.js +11 -0
- package/dist/inspector/runtime/runtimeConfig.d.ts +119 -0
- package/dist/inspector/runtime/runtimeConfig.js +276 -0
- package/dist/inspector/runtime/staticHtmlRuntimeIdentity.d.ts +32 -0
- package/dist/inspector/runtime/staticHtmlRuntimeIdentity.js +149 -0
- package/dist/inspector/runtime/useRuntimeConfig.d.ts +10 -0
- package/dist/inspector/runtime/useRuntimeConfig.js +13 -0
- package/dist/inspector/selection/editScope.d.ts +32 -0
- package/dist/inspector/selection/editScope.js +140 -0
- package/dist/inspector/selection/editTarget.d.ts +8 -0
- package/dist/inspector/selection/editTarget.js +11 -0
- package/dist/inspector/selection/hierarchy.d.ts +7 -0
- package/dist/inspector/selection/hierarchy.js +42 -0
- package/dist/inspector/selection/resolveSelection.d.ts +10 -0
- package/dist/inspector/selection/resolveSelection.js +60 -0
- package/dist/inspector/selection/selectionStore.d.ts +41 -0
- package/dist/inspector/selection/selectionStore.js +262 -0
- package/dist/inspector/selection/selectionTarget.d.ts +5 -0
- package/dist/inspector/selection/selectionTarget.js +50 -0
- package/dist/inspector/selection/sourceSite.d.ts +2 -0
- package/dist/inspector/selection/sourceSite.js +12 -0
- package/dist/inspector/selection/styleSelection.d.ts +22 -0
- package/dist/inspector/selection/styleSelection.js +104 -0
- package/dist/inspector/session/index.d.ts +3 -0
- package/dist/inspector/session/index.js +2 -0
- package/dist/inspector/session/lifecycle.d.ts +22 -0
- package/dist/inspector/session/lifecycle.js +63 -0
- package/dist/inspector/session/sessionContext.d.ts +21 -0
- package/dist/inspector/session/sessionContext.js +28 -0
- package/dist/inspector/session/sessionFactory.d.ts +29 -0
- package/dist/inspector/session/sessionFactory.js +73 -0
- package/dist/inspector/settings/SettingsDialog.d.ts +12 -0
- package/dist/inspector/settings/SettingsDialog.js +46 -0
- package/dist/inspector/shell/AppShell.d.ts +2 -0
- package/dist/inspector/shell/AppShell.js +9 -0
- package/dist/inspector/shell/ChangesLog.d.ts +6 -0
- package/dist/inspector/shell/ChangesLog.js +92 -0
- package/dist/inspector/shell/CopyPromptButton.d.ts +9 -0
- package/dist/inspector/shell/CopyPromptButton.js +159 -0
- package/dist/inspector/shell/DomNavigation.d.ts +8 -0
- package/dist/inspector/shell/DomNavigation.js +30 -0
- package/dist/inspector/shell/EmptyState.d.ts +2 -0
- package/dist/inspector/shell/EmptyState.js +15 -0
- package/dist/inspector/shell/InspectorShell.d.ts +11 -0
- package/dist/inspector/shell/InspectorShell.js +268 -0
- package/dist/inspector/shell/openStore.d.ts +6 -0
- package/dist/inspector/shell/openStore.js +29 -0
- package/dist/inspector/shell/panelLayout.d.ts +2 -0
- package/dist/inspector/shell/panelLayout.js +29 -0
- package/dist/inspector/shell/shortcuts.d.ts +3 -0
- package/dist/inspector/shell/shortcuts.js +25 -0
- package/dist/inspector/shell/stateValue.d.ts +3 -0
- package/dist/inspector/shell/stateValue.js +34 -0
- package/dist/inspector/shell/styleState.d.ts +7 -0
- package/dist/inspector/shell/styleState.js +13 -0
- package/dist/inspector/spacing/projection.d.ts +43 -0
- package/dist/inspector/spacing/projection.js +136 -0
- package/dist/inspector/styleEditors/AppearanceSection.d.ts +13 -0
- package/dist/inspector/styleEditors/AppearanceSection.js +6 -0
- package/dist/inspector/styleEditors/AspectRatioField.d.ts +17 -0
- package/dist/inspector/styleEditors/AspectRatioField.js +10 -0
- package/dist/inspector/styleEditors/BorderEditor.d.ts +13 -0
- package/dist/inspector/styleEditors/BorderEditor.js +295 -0
- package/dist/inspector/styleEditors/BorderRadiusEditor.d.ts +14 -0
- package/dist/inspector/styleEditors/BorderRadiusEditor.js +108 -0
- package/dist/inspector/styleEditors/BoxShadowEditor.d.ts +13 -0
- package/dist/inspector/styleEditors/BoxShadowEditor.js +13 -0
- package/dist/inspector/styleEditors/ColorPicker.d.ts +15 -0
- package/dist/inspector/styleEditors/ColorPicker.js +73 -0
- package/dist/inspector/styleEditors/GapField.d.ts +17 -0
- package/dist/inspector/styleEditors/GapField.js +12 -0
- package/dist/inspector/styleEditors/GridChildSection.d.ts +14 -0
- package/dist/inspector/styleEditors/GridChildSection.js +91 -0
- package/dist/inspector/styleEditors/GridPicker.d.ts +13 -0
- package/dist/inspector/styleEditors/GridPicker.js +179 -0
- package/dist/inspector/styleEditors/GridSection.d.ts +17 -0
- package/dist/inspector/styleEditors/GridSection.js +27 -0
- package/dist/inspector/styleEditors/GridValueField.d.ts +17 -0
- package/dist/inspector/styleEditors/GridValueField.js +70 -0
- package/dist/inspector/styleEditors/InsetSection.d.ts +15 -0
- package/dist/inspector/styleEditors/InsetSection.js +15 -0
- package/dist/inspector/styleEditors/LayoutBlockedIndicator.d.ts +6 -0
- package/dist/inspector/styleEditors/LayoutBlockedIndicator.js +6 -0
- package/dist/inspector/styleEditors/LayoutComboField.d.ts +18 -0
- package/dist/inspector/styleEditors/LayoutComboField.js +138 -0
- package/dist/inspector/styleEditors/LayoutDropdown.d.ts +14 -0
- package/dist/inspector/styleEditors/LayoutDropdown.js +34 -0
- package/dist/inspector/styleEditors/LayoutSection.d.ts +13 -0
- package/dist/inspector/styleEditors/LayoutSection.js +342 -0
- package/dist/inspector/styleEditors/OpacityEditor.d.ts +13 -0
- package/dist/inspector/styleEditors/OpacityEditor.js +34 -0
- package/dist/inspector/styleEditors/PositionInsets.d.ts +15 -0
- package/dist/inspector/styleEditors/PositionInsets.js +12 -0
- package/dist/inspector/styleEditors/SpacingBox.d.ts +29 -0
- package/dist/inspector/styleEditors/SpacingBox.js +189 -0
- package/dist/inspector/styleEditors/Typography.d.ts +13 -0
- package/dist/inspector/styleEditors/Typography.js +137 -0
- package/dist/inspector/styleEditors/completeCssValue.d.ts +8 -0
- package/dist/inspector/styleEditors/completeCssValue.js +34 -0
- package/dist/inspector/styleEditors/gridChildModel.d.ts +74 -0
- package/dist/inspector/styleEditors/gridChildModel.js +138 -0
- package/dist/inspector/styleEditors/layoutValue.d.ts +24 -0
- package/dist/inspector/styleEditors/layoutValue.js +103 -0
- package/dist/inspector/styleEditors/nudgeValue.d.ts +8 -0
- package/dist/inspector/styleEditors/nudgeValue.js +71 -0
- package/dist/inspector/styleEditors/rowLookup.d.ts +11 -0
- package/dist/inspector/styleEditors/rowLookup.js +13 -0
- package/dist/inspector/styleEditors/stringRecord.d.ts +4 -0
- package/dist/inspector/styleEditors/stringRecord.js +1 -0
- package/dist/inspector/styleEditors/valuePolicy.d.ts +20 -0
- package/dist/inspector/styleEditors/valuePolicy.js +82 -0
- package/dist/inspector/testing.d.ts +10 -0
- package/dist/inspector/testing.js +9 -0
- package/dist/inspector/tokens/TokenChip.d.ts +24 -0
- package/dist/inspector/tokens/TokenChip.js +23 -0
- package/dist/inspector/tokens/TokenDropdown.d.ts +13 -0
- package/dist/inspector/tokens/TokenDropdown.js +59 -0
- package/dist/inspector/tokens/TokenField.d.ts +68 -0
- package/dist/inspector/tokens/TokenField.js +485 -0
- package/dist/inspector/tokens/TokenLabel.d.ts +7 -0
- package/dist/inspector/tokens/TokenLabel.js +23 -0
- package/dist/inspector/tokens/TokensPanel.d.ts +5 -0
- package/dist/inspector/tokens/TokensPanel.js +47 -0
- package/dist/inspector/tokens/catalog.d.ts +51 -0
- package/dist/inspector/tokens/catalog.js +184 -0
- package/dist/inspector/tokens/editActions.d.ts +35 -0
- package/dist/inspector/tokens/editActions.js +164 -0
- package/dist/inspector/tokens/resolution/cascade.d.ts +14 -0
- package/dist/inspector/tokens/resolution/cascade.js +31 -0
- package/dist/inspector/tokens/resolution/cssomCollector.d.ts +43 -0
- package/dist/inspector/tokens/resolution/cssomCollector.js +528 -0
- package/dist/inspector/tokens/resolution/selectorSemantics.d.ts +12 -0
- package/dist/inspector/tokens/resolution/selectorSemantics.js +106 -0
- package/dist/inspector/tokens/resolution.d.ts +56 -0
- package/dist/inspector/tokens/resolution.js +1401 -0
- package/dist/inspector/tokens/tokenEdits.d.ts +3 -0
- package/dist/inspector/tokens/tokenEdits.js +22 -0
- package/dist/inspector/tokens/valueSemanticsAdapter.d.ts +6 -0
- package/dist/inspector/tokens/valueSemanticsAdapter.js +68 -0
- package/dist/inspector/ui/AtRuleContext.d.ts +18 -0
- package/dist/inspector/ui/AtRuleContext.js +54 -0
- package/dist/inspector/ui/Button.d.ts +9 -0
- package/dist/inspector/ui/Button.js +4 -0
- package/dist/inspector/ui/ColorSwatch.d.ts +7 -0
- package/dist/inspector/ui/ColorSwatch.js +6 -0
- package/dist/inspector/ui/ControlSurface.d.ts +14 -0
- package/dist/inspector/ui/ControlSurface.js +10 -0
- package/dist/inspector/ui/FieldRow.d.ts +14 -0
- package/dist/inspector/ui/FieldRow.js +15 -0
- package/dist/inspector/ui/IconButton.d.ts +14 -0
- package/dist/inspector/ui/IconButton.js +5 -0
- package/dist/inspector/ui/InspectorPopover.d.ts +17 -0
- package/dist/inspector/ui/InspectorPopover.js +13 -0
- package/dist/inspector/ui/PopoverListbox.d.ts +37 -0
- package/dist/inspector/ui/PopoverListbox.js +21 -0
- package/dist/inspector/ui/SegmentedControl.d.ts +24 -0
- package/dist/inspector/ui/SegmentedControl.js +16 -0
- package/dist/inspector/ui/Select.d.ts +25 -0
- package/dist/inspector/ui/Select.js +56 -0
- package/dist/inspector/ui/SideValuesField.d.ts +44 -0
- package/dist/inspector/ui/SideValuesField.js +76 -0
- package/dist/inspector/ui/StatusCallout.d.ts +9 -0
- package/dist/inspector/ui/StatusCallout.js +4 -0
- package/dist/inspector/ui/TextInput.d.ts +12 -0
- package/dist/inspector/ui/TextInput.js +5 -0
- package/dist/inspector/ui/ToggleButton.d.ts +11 -0
- package/dist/inspector/ui/ToggleButton.js +6 -0
- package/dist/inspector/ui/assets/grid.svg +14 -0
- package/dist/inspector/ui/css.d.ts +9 -0
- package/dist/inspector/ui/labels.d.ts +1 -0
- package/dist/inspector/ui/labels.js +7 -0
- package/dist/inspector/ui/styles.d.ts +1 -0
- package/dist/inspector/ui/styles.js +68 -0
- package/dist/inspector/virtual-modules.d.ts +7 -0
- package/dist/inspector/vite-env.d.ts +10 -0
- package/dist/internal/agent-protocol.d.ts +232 -0
- package/dist/internal/agent-protocol.js +237 -0
- package/dist/nudge-ui.mjs +15722 -0
- package/dist/project/files.d.ts +19 -0
- package/dist/project/files.js +226 -0
- package/dist/project/identity.d.ts +6 -0
- package/dist/project/identity.js +19 -0
- package/dist/project/pathPolicy.d.ts +8 -0
- package/dist/project/pathPolicy.js +12 -0
- package/dist/project/tokens.d.ts +36 -0
- package/dist/project/tokens.js +223 -0
- package/dist/transport/index.d.ts +8 -0
- package/dist/transport/index.js +8 -0
- package/dist/transport/routes.d.ts +13 -0
- package/dist/transport/routes.js +16 -0
- 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,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,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
|
+
}
|