nudge-ui 0.2.4 → 0.2.5

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 (250) hide show
  1. package/dist/cli/agentCommand.js +4 -28
  2. package/dist/client.mjs +863 -213
  3. package/dist/hosts/next/wrapper.js +1 -7
  4. package/dist/hosts/projectBridge.js +3 -17
  5. package/dist/inspector/agent/McpConnectionDialog.js +7 -3
  6. package/dist/inspector/agent/activity.d.ts +1 -1
  7. package/dist/inspector/agent/activity.js +3 -2
  8. package/dist/inspector/agent/client.d.ts +2 -2
  9. package/dist/inspector/agent/client.js +28 -29
  10. package/dist/inspector/agent/connectionStatus.d.ts +3 -1
  11. package/dist/inspector/agent/connectionStatus.js +25 -0
  12. package/dist/inspector/agent/httpTransport.js +31 -147
  13. package/dist/inspector/agent/protocol.d.ts +1 -1
  14. package/dist/inspector/agent/protocol.js +1 -1
  15. package/dist/inspector/agent/verification.d.ts +1 -1
  16. package/dist/inspector/agent/verification.js +7 -4
  17. package/dist/inspector/boot.d.ts +3 -0
  18. package/dist/inspector/boot.js +297 -0
  19. package/dist/inspector/canvas/AgentActivityOverlay.d.ts +2 -1
  20. package/dist/inspector/canvas/AgentActivityOverlay.js +6 -3
  21. package/dist/inspector/canvas/CanvasCard.js +21 -12
  22. package/dist/inspector/canvas/CanvasElementOverlay.js +82 -127
  23. package/dist/inspector/canvas/CanvasToolbar.js +2 -1
  24. package/dist/inspector/canvas/CanvasWorkspace.js +74 -97
  25. package/dist/inspector/canvas/LockedWorkspaceNotice.d.ts +3 -2
  26. package/dist/inspector/canvas/LockedWorkspaceNotice.js +10 -6
  27. package/dist/inspector/canvas/PageCard.d.ts +10 -0
  28. package/dist/inspector/canvas/PageCard.js +51 -0
  29. package/dist/inspector/canvas/SketchToolOptions.d.ts +5 -0
  30. package/dist/inspector/canvas/SketchToolOptions.js +86 -0
  31. package/dist/inspector/canvas/StaleChangeIndicator.d.ts +1 -1
  32. package/dist/inspector/canvas/StaleChangeIndicator.js +1 -1
  33. package/dist/inspector/canvas/ToolOptionsDrawer.d.ts +21 -0
  34. package/dist/inspector/canvas/ToolOptionsDrawer.js +77 -0
  35. package/dist/inspector/canvas/activeCanvasDocument.d.ts +3 -2
  36. package/dist/inspector/canvas/assets/eraser.svg +28 -0
  37. package/dist/inspector/canvas/assets/pen.svg +25 -0
  38. package/dist/inspector/canvas/canvasFrame.d.ts +16 -0
  39. package/dist/inspector/canvas/canvasFrame.js +10 -0
  40. package/dist/inspector/canvas/canvasGestures.d.ts +0 -1
  41. package/dist/inspector/canvas/canvasGestures.js +0 -6
  42. package/dist/inspector/canvas/canvasStore.d.ts +6 -0
  43. package/dist/inspector/canvas/canvasStore.js +36 -1
  44. package/dist/inspector/canvas/frameConnection.d.ts +48 -0
  45. package/dist/inspector/canvas/frameConnection.js +73 -0
  46. package/dist/inspector/canvas/frameProtocol.d.ts +18 -1
  47. package/dist/inspector/canvas/frameProtocol.js +36 -0
  48. package/dist/inspector/canvas/pageSurface.d.ts +11 -0
  49. package/dist/inspector/canvas/pageSurface.js +34 -0
  50. package/dist/inspector/canvas/projection.d.ts +19 -9
  51. package/dist/inspector/canvas/projection.js +58 -31
  52. package/dist/inspector/canvas/rendererBootstrap.js +4 -1
  53. package/dist/inspector/canvas/rendererElementSelector.js +9 -1
  54. package/dist/inspector/canvas/rendererMessageRouter.d.ts +4 -5
  55. package/dist/inspector/canvas/rendererMessageRouter.js +12 -16
  56. package/dist/inspector/canvas/rendererSelectionProxy.d.ts +7 -1
  57. package/dist/inspector/canvas/rendererSelectionProxy.js +8 -36
  58. package/dist/inspector/canvas/rendererStylesheet.js +15 -0
  59. package/dist/inspector/canvas/sessionStore.d.ts +2 -2
  60. package/dist/inspector/canvas/sessionStore.js +12 -9
  61. package/dist/inspector/canvas/staleChangeDetector.d.ts +1 -1
  62. package/dist/inspector/canvas/staleChangeDetector.js +10 -22
  63. package/dist/inspector/changes/codecs.d.ts +1 -0
  64. package/dist/inspector/changes/codecs.js +20 -5
  65. package/dist/inspector/changes/draftPreview.d.ts +12 -0
  66. package/dist/inspector/changes/draftPreview.js +133 -0
  67. package/dist/inspector/changes/editModel.d.ts +8 -0
  68. package/dist/inspector/changes/editModel.js +8 -2
  69. package/dist/inspector/changes/managedStyleProjection.js +2 -1
  70. package/dist/inspector/changes/previewDiagnostics.js +1 -1
  71. package/dist/inspector/changes/types.d.ts +11 -1
  72. package/dist/inspector/comments/CommentsOverlay.js +18 -16
  73. package/dist/inspector/comments/store.js +3 -2
  74. package/dist/inspector/comments/verification.js +1 -1
  75. package/dist/inspector/componentSemantics/ComponentPropsSection.js +2 -1
  76. package/dist/inspector/componentSemantics/changeAction.js +1 -1
  77. package/dist/inspector/componentSemantics/textBinding.d.ts +1 -2
  78. package/dist/inspector/componentSemantics/textBinding.js +4 -45
  79. package/dist/inspector/drafts/draftStore.d.ts +109 -0
  80. package/dist/inspector/drafts/draftStore.js +451 -0
  81. package/dist/inspector/drafts/model.d.ts +9 -1
  82. package/dist/inspector/drafts/model.js +5 -1
  83. package/dist/inspector/drafts/store.d.ts +53 -15
  84. package/dist/inspector/drafts/store.js +143 -169
  85. package/dist/inspector/index.d.ts +2 -4
  86. package/dist/inspector/index.js +2 -264
  87. package/dist/inspector/inline-text/inlineTextEditor.d.ts +1 -1
  88. package/dist/inspector/inline-text/inlineTextEditor.js +1 -2
  89. package/dist/inspector/inline-text/textEditChange.d.ts +1 -1
  90. package/dist/inspector/inspection/bridge.d.ts +1 -1
  91. package/dist/inspector/inspection/bridge.js +2 -1
  92. package/dist/inspector/inspection/browserCssInspection.d.ts +8 -0
  93. package/dist/inspector/inspection/browserCssInspection.js +28 -6
  94. package/dist/inspector/inspection/inspectionSnapshot.d.ts +6 -0
  95. package/dist/inspector/inspection/inspectionSnapshot.js +10 -0
  96. package/dist/inspector/inspection/performanceDiagnostics.d.ts +18 -0
  97. package/dist/inspector/inspection/performanceDiagnostics.js +31 -0
  98. package/dist/inspector/inspection/useBrowserCssInspection.js +17 -38
  99. package/dist/inspector/iterations/capture.d.ts +2 -1
  100. package/dist/inspector/iterations/client.d.ts +2 -1
  101. package/dist/inspector/iterations/coordinator.d.ts +4 -3
  102. package/dist/inspector/iterations/coordinator.js +5 -3
  103. package/dist/inspector/iterations/prompt.js +9 -8
  104. package/dist/inspector/overlay/interactionStyles.js +17 -0
  105. package/dist/inspector/pageInspector.d.ts +42 -0
  106. package/dist/inspector/pageInspector.js +342 -0
  107. package/dist/inspector/projection/draftProjection.d.ts +10 -2
  108. package/dist/inspector/projection/draftProjection.js +9 -1
  109. package/dist/inspector/projection/managedStylesheet.js +24 -4
  110. package/dist/inspector/projection/renderedInstance.js +7 -1
  111. package/dist/inspector/projection/structuralProjection.d.ts +0 -9
  112. package/dist/inspector/projection/structuralProjection.js +14 -44
  113. package/dist/inspector/projection/textProjection.d.ts +8 -2
  114. package/dist/inspector/projection/textProjection.js +21 -13
  115. package/dist/inspector/prompt/clipboardHandoff.d.ts +9 -0
  116. package/dist/inspector/prompt/clipboardHandoff.js +42 -16
  117. package/dist/inspector/prompt/generatePrompt.d.ts +1 -1
  118. package/dist/inspector/prompt/generatePrompt.js +243 -147
  119. package/dist/inspector/prompt/promptDocument.d.ts +3 -0
  120. package/dist/inspector/prompt/promptDocument.js +8 -0
  121. package/dist/inspector/prompt/promptSettings.js +7 -5
  122. package/dist/inspector/runtime/inspectorStorage.d.ts +17 -0
  123. package/dist/inspector/runtime/inspectorStorage.js +42 -0
  124. package/dist/inspector/runtime/ownedStylesheets.d.ts +20 -0
  125. package/dist/inspector/runtime/ownedStylesheets.js +72 -0
  126. package/dist/inspector/runtime/runtimeConfig.d.ts +4 -0
  127. package/dist/inspector/runtime/runtimeConfig.js +10 -1
  128. package/dist/inspector/runtime/runtimeIdentityClaims.d.ts +29 -0
  129. package/dist/inspector/runtime/runtimeIdentityClaims.js +188 -0
  130. package/dist/inspector/runtime/staticHtmlRuntimeIdentity.d.ts +15 -0
  131. package/dist/inspector/runtime/staticHtmlRuntimeIdentity.js +113 -29
  132. package/dist/inspector/selection/editScope.d.ts +1 -0
  133. package/dist/inspector/selection/editScope.js +13 -2
  134. package/dist/inspector/shell/AgentStatusButton.js +2 -2
  135. package/dist/inspector/shell/AppShell.js +6 -2
  136. package/dist/inspector/shell/ChangesLog.js +27 -9
  137. package/dist/inspector/shell/CopyPromptButton.js +60 -54
  138. package/dist/inspector/shell/EmptyState.js +3 -3
  139. package/dist/inspector/shell/InspectorShell.d.ts +0 -3
  140. package/dist/inspector/shell/InspectorShell.js +21 -13
  141. package/dist/inspector/shell/PeekOriginalButton.js +3 -3
  142. package/dist/inspector/shell/interactionStatePreview.d.ts +9 -0
  143. package/dist/inspector/shell/interactionStatePreview.js +112 -0
  144. package/dist/inspector/shell/originalPreview.d.ts +3 -2
  145. package/dist/inspector/shell/originalPreview.js +10 -37
  146. package/dist/inspector/shell/stateValue.js +2 -3
  147. package/dist/inspector/sketch/SketchEditor.js +5 -4
  148. package/dist/inspector/sketch/SketchFrameOverlay.d.ts +2 -1
  149. package/dist/inspector/sketch/SketchFrameOverlay.js +5 -4
  150. package/dist/inspector/sketch/SketchOverlay.d.ts +3 -5
  151. package/dist/inspector/sketch/SketchOverlay.js +139 -263
  152. package/dist/inspector/sketch/SketchPromptPanel.d.ts +1 -1
  153. package/dist/inspector/sketch/SketchPromptPanel.js +8 -1
  154. package/dist/inspector/sketch/SketchThumbnail.d.ts +5 -0
  155. package/dist/inspector/sketch/SketchThumbnail.js +18 -0
  156. package/dist/inspector/sketch/SketchWorkspace.d.ts +1 -2
  157. package/dist/inspector/sketch/SketchWorkspace.js +69 -34
  158. package/dist/inspector/sketch/capture.js +19 -3
  159. package/dist/inspector/sketch/copySketch.d.ts +10 -0
  160. package/dist/inspector/sketch/copySketch.js +52 -0
  161. package/dist/inspector/sketch/drawingTools.d.ts +17 -0
  162. package/dist/inspector/sketch/drawingTools.js +47 -0
  163. package/dist/inspector/sketch/frameHeading.d.ts +9 -0
  164. package/dist/inspector/sketch/frameHeading.js +30 -0
  165. package/dist/inspector/sketch/freehand.js +3 -3
  166. package/dist/inspector/sketch/geometry.d.ts +6 -0
  167. package/dist/inspector/sketch/geometry.js +19 -0
  168. package/dist/inspector/sketch/history.d.ts +30 -0
  169. package/dist/inspector/sketch/history.js +58 -0
  170. package/dist/inspector/sketch/interaction.d.ts +1 -3
  171. package/dist/inspector/sketch/interaction.js +6 -9
  172. package/dist/inspector/sketch/model.d.ts +35 -1
  173. package/dist/inspector/sketch/model.js +116 -61
  174. package/dist/inspector/sketch/persistence.d.ts +14 -0
  175. package/dist/inspector/sketch/persistence.js +63 -7
  176. package/dist/inspector/sketch/raster.d.ts +6 -2
  177. package/dist/inspector/sketch/raster.js +43 -17
  178. package/dist/inspector/sketch/store.d.ts +1 -1
  179. package/dist/inspector/sketch/store.js +1 -1
  180. package/dist/inspector/sketch/videoFrames.d.ts +6 -0
  181. package/dist/inspector/sketch/videoFrames.js +81 -0
  182. package/dist/inspector/styleEditors/BackgroundEditor.js +2 -1
  183. package/dist/inspector/styleEditors/BorderEditor.js +30 -130
  184. package/dist/inspector/styleEditors/BorderRadiusEditor.js +8 -3
  185. package/dist/inspector/styleEditors/ImageBackgroundEditor.js +1 -1
  186. package/dist/inspector/styleEditors/LayoutSection.js +2 -2
  187. package/dist/inspector/styleEditors/borderModel.d.ts +42 -0
  188. package/dist/inspector/styleEditors/borderModel.js +114 -0
  189. package/dist/inspector/styleEditors/layoutValue.js +2 -3
  190. package/dist/inspector/tokens/TokenField.js +34 -3
  191. package/dist/inspector/tokens/TokensPanel.js +2 -1
  192. package/dist/inspector/tokens/editActions.d.ts +3 -3
  193. package/dist/inspector/tokens/editActions.js +9 -3
  194. package/dist/inspector/tokens/resolution/containerQueryEvaluator.d.ts +15 -0
  195. package/dist/inspector/tokens/resolution/containerQueryEvaluator.js +86 -0
  196. package/dist/inspector/tokens/resolution/cssomCollector.js +44 -9
  197. package/dist/inspector/tokens/resolution/nestedSelectors.d.ts +6 -0
  198. package/dist/inspector/tokens/resolution/nestedSelectors.js +67 -0
  199. package/dist/inspector/tokens/resolution/ruleMatching.js +23 -4
  200. package/dist/inspector/tokens/resolution.d.ts +6 -3
  201. package/dist/inspector/tokens/resolution.js +91 -112
  202. package/dist/inspector/tokens/tokenEdits.d.ts +1 -1
  203. package/dist/inspector/tokens/tokenEdits.js +1 -1
  204. package/dist/inspector/ui/InlineStyleWarning.js +2 -2
  205. package/dist/inspector/ui/InspectorStyle.d.ts +8 -0
  206. package/dist/inspector/ui/InspectorStyle.js +26 -0
  207. package/dist/inspector/ui/PopoverListbox.d.ts +2 -1
  208. package/dist/inspector/ui/PopoverListbox.js +3 -3
  209. package/dist/inspector/ui/Toast.d.ts +14 -0
  210. package/dist/inspector/ui/Toast.js +30 -0
  211. package/dist/inspector/ui/assets/canvasIllustration.d.ts +2 -0
  212. package/dist/inspector/ui/assets/canvasIllustration.js +21 -0
  213. package/dist/inspector/ui/assets/gridIllustration.d.ts +2 -0
  214. package/dist/inspector/ui/assets/{grid.svg → gridIllustration.js} +3 -2
  215. package/dist/inspector/ui/customCursors.d.ts +5 -0
  216. package/dist/inspector/ui/customCursors.js +32 -6
  217. package/dist/inspector/ui/styles.js +12 -10
  218. package/dist/inspector/workspace/commands.js +1 -2
  219. package/dist/inspector/workspace/controller.js +1 -2
  220. package/dist/inspector/workspace/handoff.js +3 -2
  221. package/dist/inspector/workspace/sentItems.d.ts +3 -6
  222. package/dist/inspector/workspace/sentItems.js +6 -24
  223. package/dist/inspector/workspace/timeline.d.ts +24 -10
  224. package/dist/inspector/workspace/timeline.js +118 -96
  225. package/dist/internal/agent-protocol.d.ts +50 -13
  226. package/dist/internal/agent-protocol.js +145 -19
  227. package/dist/nudge-ui.mjs +81 -65
  228. package/dist/project/mcpPackage.d.ts +8 -0
  229. package/dist/project/mcpPackage.js +60 -0
  230. package/package.json +12 -2
  231. package/dist/inspector/canvas/measurementProjection.d.ts +0 -8
  232. package/dist/inspector/canvas/measurementProjection.js +0 -16
  233. package/dist/inspector/changes/changesLog.d.ts +0 -49
  234. package/dist/inspector/changes/changesLog.js +0 -255
  235. package/dist/inspector/changes/draftChanges.d.ts +0 -58
  236. package/dist/inspector/changes/draftChanges.js +0 -304
  237. package/dist/inspector/conformance/projection.d.ts +0 -2
  238. package/dist/inspector/conformance/projection.js +0 -3
  239. package/dist/inspector/inline-text/textChangeBoundary.d.ts +0 -6
  240. package/dist/inspector/inline-text/textChangeBoundary.js +0 -1
  241. package/dist/inspector/overlay/InspectorOverlay.d.ts +0 -5
  242. package/dist/inspector/overlay/InspectorOverlay.js +0 -332
  243. package/dist/inspector/overlay/elementSelector.d.ts +0 -1
  244. package/dist/inspector/overlay/elementSelector.js +0 -111
  245. package/dist/inspector/sketch/SketchChanges.d.ts +0 -2
  246. package/dist/inspector/sketch/SketchChanges.js +0 -72
  247. package/dist/inspector/sketch/SketchEntryButton.d.ts +0 -4
  248. package/dist/inspector/sketch/SketchEntryButton.js +0 -11
  249. package/dist/inspector/sketch/SketchLayersPanel.d.ts +0 -2
  250. package/dist/inspector/sketch/SketchLayersPanel.js +0 -71
@@ -0,0 +1,86 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { useEffect, useId, useRef, useState } from "react";
3
+ import { IconButton } from "../ui/IconButton.js";
4
+ import { Tooltip } from "../ui/Tooltip.js";
5
+ import { setSketchDrawingTool, setSketchStrokeColor, useSketchDrawingTools, } from "../sketch/drawingTools.js";
6
+ import { SKETCH_PEN_COLORS, SKETCH_RECTANGLE_FILL_OPACITY } from "../sketch/model.js";
7
+ import { ToolOptionsDrawer, useDismissablePopover } from "./ToolOptionsDrawer.js";
8
+ function PenIllustration({ color }) {
9
+ const id = useId();
10
+ return (_jsxs("svg", { className: "sketch-options__illustration sketch-options__illustration--pen", viewBox: "0 0 20 47", width: 20, height: 47, fill: "none", "aria-hidden": "true", children: [_jsx("path", { d: "M1.84492 27.3255C2.22193 26.8144 2.81931 26.5127 3.45445 26.5127H16.1011C16.7362 26.5127 17.3336 26.8144 17.7106 27.3255L19.1651 29.2974C19.4187 29.6413 19.5556 30.0573 19.5556 30.4846V44.9998C19.5556 46.1044 18.6601 46.9998 17.5556 46.9998H2C0.895432 46.9998 0 46.1044 0 44.9998V30.4846C0 30.0573 0.136838 29.6413 0.390464 29.2974L1.84492 27.3255Z", fill: `url(#${id}-barrel)` }), _jsx("path", { d: "M3.4541 26.7627H16.1016C16.6571 26.7628 17.18 27.0265 17.5098 27.4736L18.9639 29.4463C19.1856 29.747 19.3056 30.1107 19.3057 30.4844V45C19.3056 45.9664 18.522 46.7499 17.5557 46.75H2C1.03357 46.75 0.250102 45.9664 0.25 45V30.4844C0.250045 30.1107 0.370031 29.7471 0.591797 29.4463L2.0459 27.4736C2.37572 27.0265 2.89852 26.7628 3.4541 26.7627Z", stroke: "black", strokeOpacity: 0.3, strokeWidth: 0.5 }), _jsx("path", { opacity: 0.2, d: "M0.5 29.827L2.09916 27.8035C2.66811 27.0835 3.53527 26.6636 4.45289 26.6636H15.5314C16.1432 26.6636 16.7213 26.9435 17.1006 27.4235L19 29.827C19 29.827 18.3604 30.6988 10 30.7309C2.7733 30.9407 0.5 29.827 0.5 29.827Z", fill: "white" }), _jsx("rect", { x: 9, width: 2, height: 4.51922, rx: 1, fill: color.value }), _jsx("path", { d: "M8.46794 3.90451L6.3377 11.8468C6.16733 12.482 6.64593 13.1059 7.30356 13.1059H12.6964C13.3541 13.1059 13.8327 12.482 13.6623 11.8468L11.5321 3.90452C11.4148 3.46745 11.0187 3.16357 10.5662 3.16357H9.4338C8.98128 3.16357 8.58516 3.46745 8.46794 3.90451Z", fill: "#DFDBD8" }), _jsx("path", { d: "M9.43359 3.41357H10.5664C10.9057 3.41367 11.2031 3.6415 11.291 3.96924L13.4209 11.9116C13.5486 12.388 13.1895 12.856 12.6963 12.856H7.30371C6.81051 12.856 6.45139 12.388 6.5791 11.9116L8.70898 3.96924C8.79689 3.6415 9.09429 3.41367 9.43359 3.41357Z", stroke: "black", strokeOpacity: 0.2, strokeWidth: 0.5 }), _jsx("path", { d: "M4.21018 13.6159L2.91363 25.8034C2.81727 26.7092 3.34313 27.5769 4.22007 27.8232C8.64659 29.0666 13.0414 28.5136 15.6629 27.8088C16.5323 27.5751 17.0451 26.7212 16.9499 25.826L15.6642 13.7403C15.6121 13.251 15.3815 12.7981 15.0165 12.4681L14.6267 12.1159C14.2591 11.7836 13.7812 11.5996 13.2856 11.5996H6.40068C5.82792 11.5996 5.28266 11.8452 4.90305 12.274L4.70133 12.502C4.42582 12.8132 4.25415 13.2026 4.21018 13.6159Z", fill: `url(#${id}-barrel-upper)` }), _jsx("path", { d: "M6.40039 11.8496H13.2861C13.7196 11.8497 14.1374 12.0111 14.459 12.3018L14.8486 12.6533C15.168 12.942 15.3705 13.3385 15.416 13.7666L16.7012 25.8525C16.785 26.6413 16.3334 27.3696 15.5977 27.5674C13.0048 28.2644 8.6582 28.8104 4.28809 27.583C3.54101 27.3732 3.07734 26.6278 3.16211 25.8301L4.45898 13.6426C4.49746 13.2809 4.64766 12.9403 4.88867 12.668L5.08984 12.4395C5.42194 12.0643 5.89934 11.8497 6.40039 11.8496Z", stroke: "black", strokeOpacity: 0.3, strokeWidth: 0.5 }), _jsx("path", { d: "M0.5 29.8266C0.5 29.8266 0.611036 29.4017 0.812755 29.4479C2.04229 29.73 6.64097 30.7305 10 30.7305C13.3766 30.7305 17.633 29.7195 18.7316 29.4436C18.9052 29.4 19 29.8266 19 29.8266V32.0863C19 32.0863 14.5 33.442 10 33.442C5.5 33.442 0.5 32.0863 0.5 32.0863V29.8266Z", fill: color.value }), _jsxs("defs", { children: [_jsxs("linearGradient", { id: `${id}-barrel`, x1: "1.24823", y1: "37.8542", x2: "16.9974", y2: "38.058", gradientUnits: "userSpaceOnUse", children: [_jsx("stop", { stopColor: "#2E2E2E" }), _jsx("stop", { offset: "0.248334", stopColor: "#575757" }), _jsx("stop", { offset: "0.660438", stopColor: "#242424" }), _jsx("stop", { offset: "1", stopColor: "#2E2E2E" })] }), _jsxs("linearGradient", { id: `${id}-barrel-upper`, x1: "3.66667", y1: "20.9895", x2: "16.1878", y2: "21.6653", gradientUnits: "userSpaceOnUse", children: [_jsx("stop", { stopColor: "#2E2E2E" }), _jsx("stop", { offset: "0.248334", stopColor: "#575757" }), _jsx("stop", { offset: "0.660438", stopColor: "#242424" }), _jsx("stop", { offset: "1", stopColor: "#2E2E2E" })] })] })] }));
11
+ }
12
+ function EraserIllustration() {
13
+ const id = useId();
14
+ return (_jsxs("svg", { className: "sketch-options__illustration sketch-options__illustration--eraser", viewBox: "0 0 22 47", width: 22, height: 47, fill: "none", "aria-hidden": "true", children: [_jsx("path", { d: "M0.302734 4.7855V32.0302C0.302734 33.7251 1.40783 35.2219 3.0276 35.721L16.5844 39.898C19.0565 40.6597 21.5639 38.8232 21.5836 36.2366L21.8269 4.22443C21.8393 2.59599 20.8289 1.13477 19.3009 0.571436L19.1428 0.513114C18.2253 0.174845 17.2467 0.0339522 16.271 0.0996387L3.90538 0.932154C1.8777 1.06867 0.302734 2.75323 0.302734 4.7855Z", fill: "#DFDBD8" }), _jsx("mask", { id: `${id}-shade-mask`, style: { maskType: "alpha" }, maskUnits: "userSpaceOnUse", x: 0, y: 0, width: 22, height: 27, children: _jsx("path", { d: "M0.302734 4.7855V18.1255C0.302734 19.8204 1.40783 21.3173 3.0276 21.8164L16.6054 25.9999C19.0712 26.7596 21.5743 24.9341 21.6044 22.3541L21.8158 4.23606C21.8348 2.60193 20.8233 1.1327 19.2899 0.567375L19.1428 0.513114C18.2253 0.174845 17.2467 0.0339521 16.271 0.0996387L3.90538 0.932154C1.8777 1.06867 0.302734 2.75323 0.302734 4.7855Z", fill: "#131211" }) }), _jsxs("g", { mask: `url(#${id}-shade-mask)`, children: [_jsxs("g", { opacity: 0.7, filter: `url(#${id}-blur)`, children: [_jsx("path", { d: "M4.40022 2.17282C2.33677 1.90432 3.237 0.727298 3.94504 0.335731L14.1105 -2.01367C14.6668 -2.01367 16.4471 -1.71161 19.1174 -0.503342C21.7878 0.704922 22.253 1.11886 22.1519 1.1748L16.6898 1.51043C13.4531 1.73418 6.46367 2.44133 4.40022 2.17282Z", fill: "white" }), _jsx("path", { d: "M5.5 10.4287V21.2917C9.01287 22.5379 17.0143 25.0204 20.8216 22.1607C22.8245 20.6563 21.6392 14.6978 21.8484 12.754C22.4553 7.11543 21.6967 2.68513 18.2071 2.68513C17.4484 2.74107 15 3.04186 10.5 3.47638C6.03379 3.90764 5.39885 7.96741 5.5 10.4287Z", fill: "white" }), _jsx("path", { d: "M4.40022 5.87361V21.7262C3.42918 23.6057 1.51777 20.7842 0.759154 19.5536C0.809729 17.4839 0.758789 6.10855 0.758789 5.03454C0.758789 3.69202 1.51741 1.84606 2.88293 2.3495C3.97534 2.75226 4.34963 4.86672 4.40022 5.87361Z", fill: "white" })] }), _jsx("path", { d: "M16.2881 0.348633C17.2286 0.285354 18.1722 0.421976 19.0566 0.748047L19.2148 0.805664C20.6438 1.33259 21.5887 2.69971 21.5771 4.22266L21.334 36.2344C21.3156 38.6536 18.9702 40.3714 16.6582 39.6592L3.10156 35.4824C1.58668 35.0157 0.552786 33.6154 0.552734 32.0303V4.78516L0.556641 4.6084C0.644771 2.78788 2.08482 1.30547 3.92188 1.18164L16.2881 0.348633Z", stroke: "black", strokeOpacity: 0.1, strokeWidth: 0.5 })] }), _jsx("path", { d: "M4.55172 21.3245L0.303448 18.9751H0V44.6507L4.09655 47.0001L22 44.1473V19.3107L4.55172 21.3245Z", fill: `url(#${id}-sleeve)` }), _jsx("path", { d: "M0.253906 19.1685L4.45801 21.4937L4.5127 21.5229L4.57422 21.5161L21.8066 19.5269V43.9819L4.13281 46.7983L0.193359 44.5386V19.1685H0.253906Z", stroke: "black", strokeOpacity: 0.3, strokeWidth: 0.386207 }), _jsxs("defs", { children: [_jsxs("filter", { id: `${id}-blur`, x: -0.786039, y: -3.5585, width: 24.4949, height: 28.5867, filterUnits: "userSpaceOnUse", colorInterpolationFilters: "sRGB", children: [_jsx("feFlood", { floodOpacity: 0, result: "BackgroundImageFix" }), _jsx("feBlend", { mode: "normal", in: "SourceGraphic", in2: "BackgroundImageFix", result: "shape" }), _jsx("feGaussianBlur", { stdDeviation: 0.772414, result: "effect1_foregroundBlur" })] }), _jsxs("linearGradient", { id: `${id}-sleeve`, x1: "1.01446e-07", y1: "26.0713", x2: "8.5", y2: "26.0713", gradientUnits: "userSpaceOnUse", children: [_jsx("stop", { stopColor: "#5D5D5D" }), _jsx("stop", { offset: "0.48629", stopColor: "#5D5D5D" }), _jsx("stop", { offset: "0.568482", stopColor: "#2B2B2B" })] })] })] }));
15
+ }
16
+ /** Rectangle tool icon: outlined in the selected pen color with a 10% tint, matching what it draws. */
17
+ function RectangleIcon({ color }) {
18
+ return (_jsx("svg", { viewBox: "0 0 24 24", width: 24, height: 24, fill: "none", "aria-hidden": "true", children: _jsx("rect", { x: 1, y: 1, width: 22, height: 22, rx: 4, fill: color.value, fillOpacity: SKETCH_RECTANGLE_FILL_OPACITY, stroke: color.value, strokeWidth: 2 }) }));
19
+ }
20
+ function IllustratedToolButton({ tool, activeTool, label, hidden, children, }) {
21
+ const active = tool === activeTool;
22
+ return (_jsx(Tooltip, { content: label, stableTrigger: true, children: _jsx("button", { type: "button", className: "sketch-options__illustrated", "aria-label": label, "aria-pressed": active, "data-active": active ? "true" : "false", "data-test": `sketch-tool-${tool}`, tabIndex: hidden ? -1 : undefined, onClick: () => setSketchDrawingTool(tool), children: children }) }));
23
+ }
24
+ /** Distance from the picker's center to each swatch center, and the swatch diameter, in px. */
25
+ const PALETTE_RADIUS = 26;
26
+ const PALETTE_SWATCH_SIZE = 32;
27
+ /** Paint order of the overlapping swatches, bottom to top; the selected swatch always wins. */
28
+ /** Delay between neighboring swatches as they fan out or collapse, in ms. */
29
+ const PALETTE_STAGGER_MS = 18;
30
+ const PALETTE_STACK_ORDER = ["yellow", "orange", "red", "black", "green", "blue"];
31
+ /** Offset of swatch `index` of `count` from the picker's center; the first sits at the top right. */
32
+ function paletteSwatchOffset(index, count) {
33
+ const radians = ((-90 + (index + 0.5) * (360 / count)) * Math.PI) / 180;
34
+ return {
35
+ "--swatch-x": `${(PALETTE_RADIUS * Math.cos(radians)).toFixed(2)}px`,
36
+ "--swatch-y": `${(PALETTE_RADIUS * Math.sin(radians)).toFixed(2)}px`,
37
+ };
38
+ }
39
+ /** Matches the longest swatch collapse in SketchToolOptions.css (duration plus stagger). */
40
+ const PALETTE_CLOSE_MS = 180 + (SKETCH_PEN_COLORS.length - 1) * PALETTE_STAGGER_MS;
41
+ function ColorPicker({ color, hidden }) {
42
+ const [phase, setPhase] = useState("closed");
43
+ const rootRef = useRef(null);
44
+ const closeTimer = useRef(undefined);
45
+ const open = phase === "open";
46
+ // Collapse the swatches back into the trigger before unmounting them.
47
+ function closePalette() {
48
+ clearTimeout(closeTimer.current);
49
+ if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) {
50
+ setPhase("closed");
51
+ return;
52
+ }
53
+ setPhase("closing");
54
+ closeTimer.current = setTimeout(() => setPhase("closed"), PALETTE_CLOSE_MS);
55
+ }
56
+ useEffect(() => {
57
+ if (!hidden)
58
+ return;
59
+ clearTimeout(closeTimer.current);
60
+ setPhase("closed");
61
+ }, [hidden]);
62
+ useEffect(() => () => clearTimeout(closeTimer.current), []);
63
+ useDismissablePopover(open, rootRef, closePalette);
64
+ return (_jsxs("div", { className: "sketch-options__color", ref: rootRef, children: [_jsx(Tooltip, { content: "Color", disabled: phase !== "closed", stableTrigger: true, children: _jsx("button", { type: "button", className: "sketch-options__color-trigger", "aria-label": `Color: ${color.name}`, "aria-expanded": open, "data-open": open ? "true" : "false", "data-test": "sketch-tool-color", tabIndex: hidden ? -1 : undefined, onClick: () => {
65
+ if (open) {
66
+ closePalette();
67
+ return;
68
+ }
69
+ clearTimeout(closeTimer.current);
70
+ setPhase("open");
71
+ }, children: _jsx("span", { className: "sketch-options__swatch", style: { background: color.value } }) }) }), phase !== "closed" ? (_jsx("div", { className: "sketch-options__palette", role: "group", "aria-label": "Pen color", "data-state": phase, "data-test": "sketch-color-palette", style: { "--swatch-size": `${PALETTE_SWATCH_SIZE}px` }, children: SKETCH_PEN_COLORS.map((option, index) => (_jsx("button", { type: "button", className: "sketch-options__palette-option", "aria-label": option.name, "aria-pressed": option === color, "data-active": option === color ? "true" : "false", "data-test": `sketch-color-${option.id}`, style: {
72
+ ...paletteSwatchOffset(index, SKETCH_PEN_COLORS.length),
73
+ "--swatch-delay": `${index * PALETTE_STAGGER_MS}ms`,
74
+ "--swatch-delay-out": `${(SKETCH_PEN_COLORS.length - 1 - index) * PALETTE_STAGGER_MS}ms`,
75
+ background: option.value,
76
+ zIndex: option === color ? SKETCH_PEN_COLORS.length : Math.max(PALETTE_STACK_ORDER.indexOf(option.id), 0),
77
+ }, onClick: () => {
78
+ setSketchStrokeColor(option);
79
+ closePalette();
80
+ } }, option.id))) })) : null] }));
81
+ }
82
+ /** Pen, eraser, color and rectangle controls that slide out beside the sketch tool. */
83
+ export function SketchToolOptions({ open }) {
84
+ const drawing = useSketchDrawingTools();
85
+ return (_jsx(ToolOptionsDrawer, { name: "sketch", open: open, label: "Sketch tools", children: ({ hidden, settled }) => (_jsxs(_Fragment, { children: [_jsx(IllustratedToolButton, { tool: "pen", activeTool: drawing.tool, label: "Pen", hidden: hidden, children: _jsx(PenIllustration, { color: drawing.color }) }), _jsx(IllustratedToolButton, { tool: "eraser", activeTool: drawing.tool, label: "Eraser", hidden: hidden, children: _jsx(EraserIllustration, {}) }), _jsx(Tooltip, { content: "Rectangle", stableTrigger: true, children: _jsx(IconButton, { variant: "quiet", size: "large", className: "canvas-toolbar__tool sketch-options__rectangle", label: "Rectangle", "aria-pressed": drawing.tool === "rectangle", "data-active": drawing.tool === "rectangle" ? "true" : "false", "data-test": "sketch-tool-rectangle", tabIndex: hidden ? -1 : undefined, onClick: () => setSketchDrawingTool("rectangle"), children: _jsx(RectangleIcon, { color: drawing.color }) }) }), _jsx(ColorPicker, { color: drawing.color, hidden: hidden || !settled })] })) }));
86
+ }
@@ -1,5 +1,5 @@
1
1
  import type { ReactElement } from "react";
2
- import type { ChangeRecord } from "../changes/changesLog.js";
2
+ import { type ChangeRecord } from "../changes/types.js";
3
3
  interface Props {
4
4
  change: ChangeRecord;
5
5
  }
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useSyncExternalStore } from "react";
3
- import { isPreviewableChange, isTokenChange } from "../changes/changesLog.js";
3
+ import { isPreviewableChange, isTokenChange } from "../changes/types.js";
4
4
  import { changeKey } from "../changes/model.js";
5
5
  import { getAnyPreviewDiagnostic, getPreviewDiagnosticRevision, subscribePreviewDiagnostics, } from "../changes/previewDiagnostics.js";
6
6
  import { isVerificationPending } from "./staleChangeDetector.js";
@@ -0,0 +1,21 @@
1
+ import type { ReactElement, ReactNode } from "react";
2
+ export interface ToolOptionsDrawerProps {
3
+ /** Stable name that identifies the drawer across toolbar remounts. */
4
+ readonly name: string;
5
+ readonly open: boolean;
6
+ readonly label: string;
7
+ /**
8
+ * Renders the drawer content. `hidden` removes controls from the tab order;
9
+ * `settled` is true once the slide finishes and content may overflow the bar.
10
+ */
11
+ readonly children: (state: {
12
+ readonly hidden: boolean;
13
+ readonly settled: boolean;
14
+ }) => ReactNode;
15
+ }
16
+ /** Slides tool-specific options out of the canvas toolbar beside their tool. */
17
+ export declare function ToolOptionsDrawer({ name, open, label, children }: ToolOptionsDrawerProps): ReactElement;
18
+ /** Closes a toolbar popover on an outside pointer press or Escape. */
19
+ export declare function useDismissablePopover(open: boolean, rootRef: {
20
+ readonly current: HTMLElement | null;
21
+ }, close: () => void): void;
@@ -0,0 +1,77 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useEffect, useLayoutEffect, useRef, useState } from "react";
3
+ /** Matches the `width` transition in CanvasToolbar.css. */
4
+ const SLIDE_DURATION_MS = 220;
5
+ // The toolbar is remounted when sketching moves it into a root-level portal.
6
+ // Remember each drawer's last state and width so the new instance can animate
7
+ // from them; it can mount before its content has been laid out.
8
+ const lastOpen = new Map();
9
+ const lastWidth = new Map();
10
+ /** Slides tool-specific options out of the canvas toolbar beside their tool. */
11
+ export function ToolOptionsDrawer({ name, open, label, children }) {
12
+ const [expanded, setExpanded] = useState(() => lastOpen.get(name) ?? false);
13
+ const [settled, setSettled] = useState(() => (lastOpen.get(name) ?? false) && open);
14
+ const [contentWidth, setContentWidth] = useState(() => lastWidth.get(name) ?? 0);
15
+ const drawerRef = useRef(null);
16
+ const innerRef = useRef(null);
17
+ useLayoutEffect(() => {
18
+ const inner = innerRef.current;
19
+ if (!inner)
20
+ return;
21
+ const measure = () => {
22
+ if (inner.offsetWidth === 0)
23
+ return;
24
+ lastWidth.set(name, inner.offsetWidth);
25
+ setContentWidth(inner.offsetWidth);
26
+ };
27
+ measure();
28
+ const observer = typeof ResizeObserver === "undefined" ? null : new ResizeObserver(measure);
29
+ observer?.observe(inner);
30
+ return () => observer?.disconnect();
31
+ }, [name]);
32
+ useEffect(() => {
33
+ lastOpen.set(name, open);
34
+ if (!open)
35
+ setSettled(false);
36
+ let timer;
37
+ const frame = requestAnimationFrame(() => {
38
+ // Tool clicks and shortcuts are discrete events, so React can run this
39
+ // effect before a freshly mounted toolbar is ever styled. Flush its
40
+ // previous state first so the width change transitions instead of jumping.
41
+ void drawerRef.current?.offsetWidth;
42
+ setExpanded(open);
43
+ if (open)
44
+ timer = setTimeout(() => setSettled(true), SLIDE_DURATION_MS);
45
+ });
46
+ return () => {
47
+ cancelAnimationFrame(frame);
48
+ clearTimeout(timer);
49
+ };
50
+ }, [name, open]);
51
+ return (_jsx("div", { ref: drawerRef, className: "tool-options", role: "group", "aria-label": label, "aria-hidden": !open, "data-expanded": expanded ? "true" : "false", "data-settled": settled ? "true" : "false", "data-test": `${name}-tool-options`, style: { width: expanded ? contentWidth : 0 }, children: _jsx("div", { className: "tool-options__inner", ref: innerRef, children: children({ hidden: !open, settled }) }) }));
52
+ }
53
+ /** Closes a toolbar popover on an outside pointer press or Escape. */
54
+ export function useDismissablePopover(open, rootRef, close) {
55
+ const closeRef = useRef(close);
56
+ closeRef.current = close;
57
+ useEffect(() => {
58
+ if (!open)
59
+ return;
60
+ function onPointerDown(event) {
61
+ if (rootRef.current && !event.composedPath().includes(rootRef.current))
62
+ closeRef.current();
63
+ }
64
+ function onKeyDown(event) {
65
+ if (event.key !== "Escape")
66
+ return;
67
+ event.stopPropagation();
68
+ closeRef.current();
69
+ }
70
+ window.addEventListener("pointerdown", onPointerDown, true);
71
+ window.addEventListener("keydown", onKeyDown, true);
72
+ return () => {
73
+ window.removeEventListener("pointerdown", onPointerDown, true);
74
+ window.removeEventListener("keydown", onKeyDown, true);
75
+ };
76
+ }, [open, rootRef]);
77
+ }
@@ -1,5 +1,6 @@
1
+ import type { CanvasFrame } from "./canvasFrame.js";
1
2
  /** Resolves only the selected or focused frame. */
2
- export declare function resolveActiveCanvasFrame(frames: ReadonlyMap<string, HTMLIFrameElement>, selectedCardId: string | null, focusedCardId: string | null): HTMLIFrameElement | null;
3
+ export declare function resolveActiveCanvasFrame(frames: ReadonlyMap<string, CanvasFrame>, selectedCardId: string | null, focusedCardId: string | null): CanvasFrame | null;
3
4
  export declare function getActiveCanvasDocument(): Document | null;
4
5
  /** Returns the iframe that owns the active renderer document. */
5
- export declare function getActiveCanvasFrame(): HTMLIFrameElement | null;
6
+ export declare function getActiveCanvasFrame(): CanvasFrame | null;
@@ -0,0 +1,28 @@
1
+ <svg width="22" height="47" viewBox="0 0 22 47" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M0.302734 4.7855V32.0302C0.302734 33.7251 1.40783 35.2219 3.0276 35.721L16.5844 39.898C19.0565 40.6597 21.5639 38.8232 21.5836 36.2366L21.8269 4.22443C21.8393 2.59599 20.8289 1.13477 19.3009 0.571436L19.1428 0.513114C18.2253 0.174845 17.2467 0.0339522 16.271 0.0996387L3.90538 0.932154C1.8777 1.06867 0.302734 2.75323 0.302734 4.7855Z" fill="#DFDBD8"/>
3
+ <mask id="mask0_1881_2879" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="0" y="0" width="22" height="27">
4
+ <path d="M0.302734 4.7855V18.1255C0.302734 19.8204 1.40783 21.3173 3.0276 21.8164L16.6054 25.9999C19.0712 26.7596 21.5743 24.9341 21.6044 22.3541L21.8158 4.23606C21.8348 2.60193 20.8233 1.1327 19.2899 0.567375L19.1428 0.513114C18.2253 0.174845 17.2467 0.0339521 16.271 0.0996387L3.90538 0.932154C1.8777 1.06867 0.302734 2.75323 0.302734 4.7855Z" fill="#131211"/>
5
+ </mask>
6
+ <g mask="url(#mask0_1881_2879)">
7
+ <g opacity="0.7" filter="url(#filter0_f_1881_2879)">
8
+ <path d="M4.40022 2.17282C2.33677 1.90432 3.237 0.727298 3.94504 0.335731L14.1105 -2.01367C14.6668 -2.01367 16.4471 -1.71161 19.1174 -0.503342C21.7878 0.704922 22.253 1.11886 22.1519 1.1748L16.6898 1.51043C13.4531 1.73418 6.46367 2.44133 4.40022 2.17282Z" fill="white"/>
9
+ <path d="M5.5 10.4287V21.2917C9.01287 22.5379 17.0143 25.0204 20.8216 22.1607C22.8245 20.6563 21.6392 14.6978 21.8484 12.754C22.4553 7.11543 21.6967 2.68513 18.2071 2.68513C17.4484 2.74107 15 3.04186 10.5 3.47638C6.03379 3.90764 5.39885 7.96741 5.5 10.4287Z" fill="white"/>
10
+ <path d="M4.40022 5.87361V21.7262C3.42918 23.6057 1.51777 20.7842 0.759154 19.5536C0.809729 17.4839 0.758789 6.10855 0.758789 5.03454C0.758789 3.69202 1.51741 1.84606 2.88293 2.3495C3.97534 2.75226 4.34963 4.86672 4.40022 5.87361Z" fill="white"/>
11
+ </g>
12
+ <path d="M16.2881 0.348633C17.2286 0.285354 18.1722 0.421976 19.0566 0.748047L19.2148 0.805664C20.6438 1.33259 21.5887 2.69971 21.5771 4.22266L21.334 36.2344C21.3156 38.6536 18.9702 40.3714 16.6582 39.6592L3.10156 35.4824C1.58668 35.0157 0.552786 33.6154 0.552734 32.0303V4.78516L0.556641 4.6084C0.644771 2.78788 2.08482 1.30547 3.92188 1.18164L16.2881 0.348633Z" stroke="black" stroke-opacity="0.1" stroke-width="0.5"/>
13
+ </g>
14
+ <path d="M4.55172 21.3245L0.303448 18.9751H0V44.6507L4.09655 47.0001L22 44.1473V19.3107L4.55172 21.3245Z" fill="url(#paint0_linear_1881_2879)"/>
15
+ <path d="M0.253906 19.1685L4.45801 21.4937L4.5127 21.5229L4.57422 21.5161L21.8066 19.5269V43.9819L4.13281 46.7983L0.193359 44.5386V19.1685H0.253906Z" stroke="black" stroke-opacity="0.3" stroke-width="0.386207"/>
16
+ <defs>
17
+ <filter id="filter0_f_1881_2879" x="-0.786039" y="-3.5585" width="24.4949" height="28.5867" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
18
+ <feFlood flood-opacity="0" result="BackgroundImageFix"/>
19
+ <feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
20
+ <feGaussianBlur stdDeviation="0.772414" result="effect1_foregroundBlur_1881_2879"/>
21
+ </filter>
22
+ <linearGradient id="paint0_linear_1881_2879" x1="1.01446e-07" y1="26.0713" x2="8.5" y2="26.0713" gradientUnits="userSpaceOnUse">
23
+ <stop stop-color="#5D5D5D"/>
24
+ <stop offset="0.48629" stop-color="#5D5D5D"/>
25
+ <stop offset="0.568482" stop-color="#2B2B2B"/>
26
+ </linearGradient>
27
+ </defs>
28
+ </svg>
@@ -0,0 +1,25 @@
1
+ <svg width="20" height="38" viewBox="0 0 20 38" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M1.84492 27.3255C2.22193 26.8144 2.81931 26.5127 3.45445 26.5127H16.1011C16.7362 26.5127 17.3336 26.8144 17.7106 27.3255L19.1651 29.2974C19.4187 29.6413 19.5556 30.0573 19.5556 30.4846V44.9998C19.5556 46.1044 18.6601 46.9998 17.5556 46.9998H2C0.895432 46.9998 0 46.1044 0 44.9998V30.4846C0 30.0573 0.136838 29.6413 0.390464 29.2974L1.84492 27.3255Z" fill="url(#paint0_linear_1880_2833)"/>
3
+ <path d="M3.4541 26.7627H16.1016C16.6571 26.7628 17.18 27.0265 17.5098 27.4736L18.9639 29.4463C19.1856 29.747 19.3056 30.1107 19.3057 30.4844V45C19.3056 45.9664 18.522 46.7499 17.5557 46.75H2C1.03357 46.75 0.250102 45.9664 0.25 45V30.4844C0.250045 30.1107 0.370031 29.7471 0.591797 29.4463L2.0459 27.4736C2.37572 27.0265 2.89852 26.7628 3.4541 26.7627Z" stroke="black" stroke-opacity="0.3" stroke-width="0.5"/>
4
+ <path opacity="0.2" d="M0.5 29.827L2.09916 27.8035C2.66811 27.0835 3.53527 26.6636 4.45289 26.6636H15.5314C16.1432 26.6636 16.7213 26.9435 17.1006 27.4235L19 29.827C19 29.827 18.3604 30.6988 10 30.7309C2.7733 30.9407 0.5 29.827 0.5 29.827Z" fill="white"/>
5
+ <rect x="9" width="2" height="4.51922" rx="1" fill="#0096FF"/>
6
+ <path d="M8.46794 3.90451L6.3377 11.8468C6.16733 12.482 6.64593 13.1059 7.30356 13.1059H12.6964C13.3541 13.1059 13.8327 12.482 13.6623 11.8468L11.5321 3.90452C11.4148 3.46745 11.0187 3.16357 10.5662 3.16357H9.4338C8.98128 3.16357 8.58516 3.46745 8.46794 3.90451Z" fill="#DFDBD8"/>
7
+ <path d="M9.43359 3.41357H10.5664C10.9057 3.41367 11.2031 3.6415 11.291 3.96924L13.4209 11.9116C13.5486 12.388 13.1895 12.856 12.6963 12.856H7.30371C6.81051 12.856 6.45139 12.388 6.5791 11.9116L8.70898 3.96924C8.79689 3.6415 9.09429 3.41367 9.43359 3.41357Z" stroke="black" stroke-opacity="0.2" stroke-width="0.5"/>
8
+ <path d="M4.21018 13.6159L2.91363 25.8034C2.81727 26.7092 3.34313 27.5769 4.22007 27.8232C8.64659 29.0666 13.0414 28.5136 15.6629 27.8088C16.5323 27.5751 17.0451 26.7212 16.9499 25.826L15.6642 13.7403C15.6121 13.251 15.3815 12.7981 15.0165 12.4681L14.6267 12.1159C14.2591 11.7836 13.7812 11.5996 13.2856 11.5996H6.40068C5.82792 11.5996 5.28266 11.8452 4.90305 12.274L4.70133 12.502C4.42582 12.8132 4.25415 13.2026 4.21018 13.6159Z" fill="url(#paint1_linear_1880_2833)"/>
9
+ <path d="M6.40039 11.8496H13.2861C13.7196 11.8497 14.1374 12.0111 14.459 12.3018L14.8486 12.6533C15.168 12.942 15.3705 13.3385 15.416 13.7666L16.7012 25.8525C16.785 26.6413 16.3334 27.3696 15.5977 27.5674C13.0048 28.2644 8.6582 28.8104 4.28809 27.583C3.54101 27.3732 3.07734 26.6278 3.16211 25.8301L4.45898 13.6426C4.49746 13.2809 4.64766 12.9403 4.88867 12.668L5.08984 12.4395C5.42194 12.0643 5.89934 11.8497 6.40039 11.8496Z" stroke="black" stroke-opacity="0.3" stroke-width="0.5"/>
10
+ <path d="M0.5 29.8266C0.5 29.8266 0.611036 29.4017 0.812755 29.4479C2.04229 29.73 6.64097 30.7305 10 30.7305C13.3766 30.7305 17.633 29.7195 18.7316 29.4436C18.9052 29.4 19 29.8266 19 29.8266V32.0863C19 32.0863 14.5 33.442 10 33.442C5.5 33.442 0.5 32.0863 0.5 32.0863V29.8266Z" fill="#0096FF"/>
11
+ <defs>
12
+ <linearGradient id="paint0_linear_1880_2833" x1="1.24823" y1="37.8542" x2="16.9974" y2="38.058" gradientUnits="userSpaceOnUse">
13
+ <stop stop-color="#2E2E2E"/>
14
+ <stop offset="0.248334" stop-color="#575757"/>
15
+ <stop offset="0.660438" stop-color="#242424"/>
16
+ <stop offset="1" stop-color="#2E2E2E"/>
17
+ </linearGradient>
18
+ <linearGradient id="paint1_linear_1880_2833" x1="3.66667" y1="20.9895" x2="16.1878" y2="21.6653" gradientUnits="userSpaceOnUse">
19
+ <stop stop-color="#2E2E2E"/>
20
+ <stop offset="0.248334" stop-color="#575757"/>
21
+ <stop offset="0.660438" stop-color="#242424"/>
22
+ <stop offset="1" stop-color="#2E2E2E"/>
23
+ </linearGradient>
24
+ </defs>
25
+ </svg>
@@ -0,0 +1,16 @@
1
+ /**
2
+ * The renderer behind a Canvas card, as controller code sees it. Cards on the
3
+ * Canvas pass their iframe; the page surface passes the inspected window.
4
+ */
5
+ export interface CanvasFrame {
6
+ readonly contentWindow: Window | null;
7
+ readonly contentDocument: Document | null;
8
+ readonly isConnected: boolean;
9
+ readonly clientWidth: number;
10
+ readonly clientHeight: number;
11
+ getBoundingClientRect(): DOMRect;
12
+ }
13
+ /** The card's iframe element, or null for the page surface. */
14
+ export declare function canvasFrameElement(frame: CanvasFrame): HTMLIFrameElement | null;
15
+ /** The element sketch capture measures: the iframe, or the page's root element. */
16
+ export declare function canvasFrameHost(frame: CanvasFrame | null): HTMLElement | null;
@@ -0,0 +1,10 @@
1
+ /** The card's iframe element, or null for the page surface. */
2
+ export function canvasFrameElement(frame) {
3
+ return typeof HTMLIFrameElement !== "undefined" && frame instanceof HTMLIFrameElement ? frame : null;
4
+ }
5
+ /** The element sketch capture measures: the iframe, or the page's root element. */
6
+ export function canvasFrameHost(frame) {
7
+ if (!frame)
8
+ return null;
9
+ return canvasFrameElement(frame) ?? frame.contentDocument?.documentElement ?? null;
10
+ }
@@ -9,4 +9,3 @@ export interface ClientRect {
9
9
  top: number;
10
10
  }
11
11
  export declare function zoomCameraAtPointer(camera: CanvasCamera, pointer: ClientPoint, boardRect: ClientRect, deltaY: number): CanvasCamera;
12
- export declare function iframePointToClientPoint(iframeRect: ClientRect, point: ClientPoint, cameraZoom: number): ClientPoint;
@@ -13,9 +13,3 @@ export function zoomCameraAtPointer(camera, pointer, boardRect, deltaY) {
13
13
  zoom,
14
14
  };
15
15
  }
16
- export function iframePointToClientPoint(iframeRect, point, cameraZoom) {
17
- return {
18
- x: iframeRect.left + point.x * cameraZoom,
19
- y: iframeRect.top + point.y * cameraZoom,
20
- };
21
- }
@@ -89,6 +89,12 @@ export declare function getSelectedCardId(): string | null;
89
89
  export declare function useSelectedCardId(): string | null;
90
90
  export declare function useFocusedCardId(): string | null;
91
91
  export declare function setCardPosition(id: string, x: number, y: number): void;
92
+ /**
93
+ * Starts a user move or resize. The returned commit records the whole gesture
94
+ * as one undo step; programmatic placement through `setCardPosition` and
95
+ * `resizeCard` stays out of history.
96
+ */
97
+ export declare function beginCardGeometryChange(id: string): () => void;
92
98
  export declare function hydrateCanvasStore(newMode: CanvasMode, newCards: CanvasCard[], newCamera: CanvasCamera, restoredFocusedCardId?: string | null, restoredPresentation?: CanvasPresentation, restoredGroups?: readonly FrameGroup[]): void;
93
99
  export { subscribe, getCards, getCards as getCanvasCards, };
94
100
  export declare function useCanvasCards(): CanvasCard[];
@@ -1,5 +1,6 @@
1
1
  import { iterationId, contentSourceUrl, contentEditTarget } from "./frameContent.js";
2
- import { recordCanvasChange, discardCanvasHistory, isDraftLocked, forgetDraft } from "../changes/draftChanges.js";
2
+ import { isDraftLocked, forgetDraft } from "../drafts/store.js";
3
+ import { recordCanvasChange, discardCanvasHistory } from "../workspace/timeline.js";
3
4
  import { targetKey } from "../drafts/model.js";
4
5
  import { useSyncExternalStore } from "react";
5
6
  import { DEFAULT_CAMERA, getBoardCamera, placeBoardCamera, restoreCanvasView, setCanvasMode, } from "./viewStore.js";
@@ -424,6 +425,40 @@ export function setCardPosition(id, x, y) {
424
425
  cards = cards.map((c) => (c.id === id ? { ...c, x, y } : c));
425
426
  notify();
426
427
  }
428
+ function cardGeometry(id) {
429
+ const card = cards.find((candidate) => candidate.id === id);
430
+ return card ? { x: card.x, y: card.y, width: card.width, height: card.height } : null;
431
+ }
432
+ /**
433
+ * Starts a user move or resize. The returned commit records the whole gesture
434
+ * as one undo step; programmatic placement through `setCardPosition` and
435
+ * `resizeCard` stays out of history.
436
+ */
437
+ export function beginCardGeometryChange(id) {
438
+ const before = cardGeometry(id);
439
+ let committed = false;
440
+ return () => {
441
+ if (committed || !before)
442
+ return;
443
+ committed = true;
444
+ const after = cardGeometry(id);
445
+ if (!after || (after.x === before.x && after.y === before.y && after.width === before.width && after.height === before.height))
446
+ return;
447
+ const restore = (geometry) => {
448
+ if (!cards.some((card) => card.id === id))
449
+ return;
450
+ cards = cards.map((card) => card.id === id ? { ...card, ...geometry } : card);
451
+ selectCard(id);
452
+ activateHistoryCard(id);
453
+ };
454
+ recordCanvasChange({
455
+ cardIds: [id],
456
+ undo: () => restore(before),
457
+ redo: () => restore(after),
458
+ dispose: () => undefined,
459
+ });
460
+ };
461
+ }
427
462
  export function hydrateCanvasStore(newMode, newCards, newCamera, restoredFocusedCardId = null, restoredPresentation = "focus", restoredGroups = []) {
428
463
  frameGroups.clear();
429
464
  for (const group of restoredGroups)
@@ -0,0 +1,48 @@
1
+ import type { CanvasFrame } from "./canvasFrame.js";
2
+ import type { Rect } from "../overlay/overlayGeometry.js";
3
+ import { type ControllerToRendererMessage, type FrameIdentity } from "./frameProtocol.js";
4
+ export declare const PROJECT_ID: string;
5
+ export declare const WORKSPACE_ID: string;
6
+ export interface FramePoint {
7
+ readonly x: number;
8
+ readonly y: number;
9
+ }
10
+ /**
11
+ * Where a frame sits in the controller viewport, measured at one instant.
12
+ * `scale` is measured rather than read from the camera, so it is the board
13
+ * zoom on the Canvas, 1 in focus view, and correct mid-transition.
14
+ */
15
+ export interface FrameViewport extends Readonly<Rect> {
16
+ readonly scale: number;
17
+ }
18
+ /** A renderer-owned element named by a frame message. */
19
+ export interface RendererElementRef {
20
+ readonly elementId: string;
21
+ readonly cid: string;
22
+ readonly src: string;
23
+ }
24
+ type Envelope = "protocolVersion" | "projectId" | "workspaceId" | "cardId";
25
+ type WithoutEnvelope<T> = T extends unknown ? Omit<T, Envelope> : never;
26
+ export type ControllerMessageBody = WithoutEnvelope<ControllerToRendererMessage>;
27
+ /** One mounted Canvas frame as the controller sees it. */
28
+ export interface FrameConnection {
29
+ readonly cardId: string;
30
+ readonly iframe: CanvasFrame;
31
+ readonly identity: FrameIdentity;
32
+ /** The renderer's document; null while the frame navigates or blocks access. */
33
+ document(): Document | null;
34
+ /** Null unless exactly one element carries the renderer ID and its source identity still matches. */
35
+ element(ref: RendererElementRef): HTMLElement | null;
36
+ viewport(): FrameViewport;
37
+ post(message: ControllerMessageBody): void;
38
+ }
39
+ export declare function measureFrameViewport(iframe: CanvasFrame): FrameViewport;
40
+ export declare function toViewportPoint(viewport: FrameViewport, point: FramePoint): FramePoint;
41
+ /** Pass `false` for an axis whose size is a guide thickness in controller pixels. */
42
+ export declare function toViewportRect(viewport: FrameViewport, rect: Rect, scaleSize?: {
43
+ readonly width: boolean;
44
+ readonly height: boolean;
45
+ }): Rect;
46
+ export declare function findRendererElement(doc: Document | null, ref: RendererElementRef): HTMLElement | null;
47
+ export declare function connectFrame(cardId: string, iframe: CanvasFrame): FrameConnection;
48
+ export {};
@@ -0,0 +1,73 @@
1
+ import { PROTOCOL_VERSION, } from "./frameProtocol.js";
2
+ import { RENDERER_ELEMENT_ID_ATTR } from "./rendererCidIndex.js";
3
+ export const PROJECT_ID = typeof window !== "undefined" && window.location?.origin
4
+ ? window.location.origin
5
+ : "";
6
+ export const WORKSPACE_ID = typeof crypto !== "undefined" && typeof crypto.randomUUID === "function"
7
+ ? crypto.randomUUID()
8
+ : `ws-${Date.now()}`;
9
+ const RENDERER_ELEMENT_ID = /^r\d+$/;
10
+ const connections = new WeakMap();
11
+ export function measureFrameViewport(iframe) {
12
+ const rect = iframe.getBoundingClientRect();
13
+ return {
14
+ left: rect.left,
15
+ top: rect.top,
16
+ width: rect.width,
17
+ height: rect.height,
18
+ scale: iframe.clientWidth > 0 ? rect.width / iframe.clientWidth : 1,
19
+ };
20
+ }
21
+ export function toViewportPoint(viewport, point) {
22
+ return {
23
+ x: viewport.left + point.x * viewport.scale,
24
+ y: viewport.top + point.y * viewport.scale,
25
+ };
26
+ }
27
+ /** Pass `false` for an axis whose size is a guide thickness in controller pixels. */
28
+ export function toViewportRect(viewport, rect, scaleSize = { width: true, height: true }) {
29
+ return {
30
+ left: viewport.left + rect.left * viewport.scale,
31
+ top: viewport.top + rect.top * viewport.scale,
32
+ width: scaleSize.width ? rect.width * viewport.scale : rect.width,
33
+ height: scaleSize.height ? rect.height * viewport.scale : rect.height,
34
+ };
35
+ }
36
+ export function findRendererElement(doc, ref) {
37
+ if (!doc || !RENDERER_ELEMENT_ID.test(ref.elementId))
38
+ return null;
39
+ const candidates = doc.querySelectorAll(`[${RENDERER_ELEMENT_ID_ATTR}="${ref.elementId}"]`);
40
+ const candidate = candidates.length === 1 ? candidates[0] : null;
41
+ if (!candidate
42
+ || candidate.getAttribute("data-cid") !== ref.cid
43
+ || (candidate.getAttribute("data-src") ?? "") !== ref.src)
44
+ return null;
45
+ const frameWindow = doc.defaultView;
46
+ return frameWindow && candidate instanceof frameWindow.HTMLElement ? candidate : null;
47
+ }
48
+ export function connectFrame(cardId, iframe) {
49
+ const existing = connections.get(iframe);
50
+ if (existing?.cardId === cardId)
51
+ return existing;
52
+ const identity = { projectId: PROJECT_ID, workspaceId: WORKSPACE_ID, cardId };
53
+ const connection = {
54
+ cardId,
55
+ iframe,
56
+ identity,
57
+ document() {
58
+ try {
59
+ return iframe.contentDocument;
60
+ }
61
+ catch {
62
+ return null;
63
+ }
64
+ },
65
+ element: (ref) => findRendererElement(connection.document(), ref),
66
+ viewport: () => measureFrameViewport(iframe),
67
+ post(message) {
68
+ iframe.contentWindow?.postMessage({ ...message, protocolVersion: PROTOCOL_VERSION, ...identity }, window.location.origin);
69
+ },
70
+ };
71
+ connections.set(iframe, connection);
72
+ return connection;
73
+ }
@@ -2,6 +2,7 @@ import type { ComponentOverride } from "../componentSemantics/types.js";
2
2
  import type { RenderedInstanceOverride } from "../changes/editModel.js";
3
3
  import type { NudgeUiRuntimeConfig } from "../runtime/runtimeConfig.js";
4
4
  import type { SpacingDescriptor } from "../overlay/spacingGestures.js";
5
+ import type { RendererCursor } from "../ui/customCursors.js";
5
6
  export declare const PROTOCOL_VERSION = 21;
6
7
  export interface FrameMessage {
7
8
  type: string;
@@ -63,6 +64,8 @@ export interface ReplaceStylesMessage extends FrameMessage {
63
64
  textContentChanges: import("../changes/types.js").TextContentChangeRecord[];
64
65
  /** Controller-owned semantic component overrides for Canvas runtimes. */
65
66
  componentOverrides: ComponentOverride[];
67
+ /** Generated identities the edits refer to; omitted while edits are hidden. */
68
+ runtimeIdentities?: import("../runtime/runtimeIdentityClaims.js").RuntimeIdentityClaim[];
66
69
  }
67
70
  /** Renderer acknowledgement that one complete controller snapshot is applied. */
68
71
  export interface ProjectionAppliedMessage extends RendererMessage {
@@ -301,7 +304,21 @@ export interface AppInteractionModifierMessage extends RendererMessage {
301
304
  type: "app-interaction-modifier";
302
305
  held: boolean;
303
306
  }
304
- export type FrameProtocolMessage = ParentReadyMessage | RendererHelloMessage | FrameReadyMessage | FrameRuntimeMessage | FrameMetadataMessage | FrameLoadError | ReplaceStylesMessage | ProjectionAppliedMessage | StructuralProjectionReportMessage | RenderedInstanceProjectionReportMessage | TextProjectionReportMessage | NavigationIntentMessage | LinkTargetStateMessage | ElementHoverMessage | ElementMeasureStateMessage | ElementClickMessage | InlineTextIntentMessage | ElementDeselectMessage | ElementDragStartMessage | ElementDragMoveMessage | ElementDragEndMessage | ElementDeleteMessage | ElementNudgeMessage | HistoryRequestMessage | InspectorToggleRequestMessage | InspectorOpenRequestMessage | KeyboardShortcutMessage | PanStartMessage | PanMoveMessage | PanEndMessage | PanModifierMessage | MeasureModifierMessage | BoardGestureStateMessage | ZoomMessage | WheelPanMessage | AppInteractionModifierMessage;
307
+ /** Tells a renderer whether the inspector is open and which cursor its gestures show. */
308
+ export interface InspectorInteractionStateMessage extends RendererMessage {
309
+ type: "inspector-interaction-state";
310
+ open: boolean;
311
+ interactionsEnabled: boolean;
312
+ cursor: RendererCursor;
313
+ /** CSS cursor for the Comment tool; the controller renders it. */
314
+ commentCursor?: string;
315
+ }
316
+ /** Messages a renderer sends to the controller. */
317
+ export type RendererToControllerMessage = RendererHelloMessage | FrameReadyMessage | FrameRuntimeMessage | FrameMetadataMessage | FrameLoadError | ProjectionAppliedMessage | StructuralProjectionReportMessage | RenderedInstanceProjectionReportMessage | TextProjectionReportMessage | NavigationIntentMessage | ElementHoverMessage | ElementMeasureStateMessage | ElementClickMessage | InlineTextIntentMessage | ElementDeselectMessage | ElementDragStartMessage | ElementDragMoveMessage | ElementDragEndMessage | ElementDeleteMessage | ElementNudgeMessage | HistoryRequestMessage | InspectorToggleRequestMessage | InspectorOpenRequestMessage | KeyboardShortcutMessage | PanStartMessage | PanMoveMessage | PanEndMessage | PanModifierMessage | ZoomMessage | WheelPanMessage | AppInteractionModifierMessage;
318
+ /** Messages the controller sends to a renderer. */
319
+ export type ControllerToRendererMessage = ParentReadyMessage | ReplaceStylesMessage | LinkTargetStateMessage | PanModifierMessage | MeasureModifierMessage | BoardGestureStateMessage | InspectorInteractionStateMessage;
320
+ export declare function isRendererMessageType(type: unknown): type is RendererToControllerMessage["type"];
321
+ export type FrameProtocolMessage = ParentReadyMessage | RendererHelloMessage | FrameReadyMessage | FrameRuntimeMessage | FrameMetadataMessage | FrameLoadError | ReplaceStylesMessage | ProjectionAppliedMessage | StructuralProjectionReportMessage | RenderedInstanceProjectionReportMessage | TextProjectionReportMessage | NavigationIntentMessage | LinkTargetStateMessage | ElementHoverMessage | ElementMeasureStateMessage | ElementClickMessage | InlineTextIntentMessage | ElementDeselectMessage | ElementDragStartMessage | ElementDragMoveMessage | ElementDragEndMessage | ElementDeleteMessage | ElementNudgeMessage | HistoryRequestMessage | InspectorToggleRequestMessage | InspectorOpenRequestMessage | KeyboardShortcutMessage | PanStartMessage | PanMoveMessage | PanEndMessage | PanModifierMessage | MeasureModifierMessage | BoardGestureStateMessage | ZoomMessage | WheelPanMessage | AppInteractionModifierMessage | InspectorInteractionStateMessage;
305
322
  export declare function setRendererIdentity(identity: FrameIdentity): void;
306
323
  export declare function clearRendererIdentity(expected?: FrameIdentity): void;
307
324
  export declare function getRendererIdentity(): FrameIdentity | null;
@@ -19,6 +19,42 @@ import { isStructuralProjectionReport } from "../projection/structuralProjection
19
19
  // added the renderer-hello handshake solicitation for runtimes whose boot
20
20
  // completes after the controller's load-time parent-ready.
21
21
  export const PROTOCOL_VERSION = 21;
22
+ const RENDERER_MESSAGE_TYPES = {
23
+ "renderer-hello": true,
24
+ "frame-ready": true,
25
+ "frame-runtime": true,
26
+ "frame-metadata": true,
27
+ "frame-error": true,
28
+ "projection-applied": true,
29
+ "structural-projection-report": true,
30
+ "rendered-instance-projection-report": true,
31
+ "text-projection-report": true,
32
+ "navigation-intent": true,
33
+ "element-hover": true,
34
+ "element-measure-state": true,
35
+ "element-click": true,
36
+ "inline-text-intent": true,
37
+ "element-deselect": true,
38
+ "element-drag-start": true,
39
+ "element-drag-move": true,
40
+ "element-drag-end": true,
41
+ "element-delete": true,
42
+ "element-nudge": true,
43
+ "history-request": true,
44
+ "inspector-toggle-request": true,
45
+ "inspector-open-request": true,
46
+ "keyboard-shortcut": true,
47
+ "pan-start": true,
48
+ "pan-move": true,
49
+ "pan-end": true,
50
+ "pan-modifier": true,
51
+ "zoom": true,
52
+ "wheel-pan": true,
53
+ "app-interaction-modifier": true,
54
+ };
55
+ export function isRendererMessageType(type) {
56
+ return typeof type === "string" && Object.hasOwn(RENDERER_MESSAGE_TYPES, type);
57
+ }
22
58
  let rendererIdentity = null;
23
59
  export function setRendererIdentity(identity) {
24
60
  rendererIdentity = identity;
@@ -0,0 +1,11 @@
1
+ import type { CanvasFrame } from "./canvasFrame.js";
2
+ /**
3
+ * Runs the renderer and controller in the inspected window. The single Canvas
4
+ * card is the page itself, so no iframe or framing permission is needed.
5
+ */
6
+ export declare function enablePageSurface(): void;
7
+ export declare function isPageSurface(): boolean;
8
+ /** The page-surface card's frame: the inspected window, filling the viewport. */
9
+ export declare function getPageFrame(win?: Window): CanvasFrame;
10
+ /** True for events that start inside the inspector's own shadow root. */
11
+ export declare function isInspectorUiEvent(event: Event): boolean;