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
@@ -1,332 +0,0 @@
1
- import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useEffect, useRef, useState } from "react";
3
- import { useInspectorOpen } from "../shell/openStore.js";
4
- import { getSelectedElements, useHierarchy, useSelectedElement, useSelectedElements } from "../selection/selectionStore.js";
5
- import { installElementSelector } from "./elementSelector.js";
6
- import { getMarginFills, getMarginGuides, readBorderWidths, readMargins, toRect, } from "./overlayGeometry.js";
7
- import { observeSelectedGeometry } from "./selectedGeometry.js";
8
- import { getDropLocationAtPoint, moveElement } from "./structuralGestures.js";
9
- import { resolveSelectionFromElement } from "../selection/resolveSelection.js";
10
- import { setSelectedElement } from "../selection/selectionStore.js";
11
- import { installInteractionStyles } from "./interactionStyles.js";
12
- import { clearDropGuide, showDropGuide, useDropGuide } from "./dropGuide.js";
13
- import { DropGuideOverlay } from "./DropGuideOverlay.js";
14
- import { createFrameThrottle } from "./frameThrottle.js";
15
- import { getMeasurementGeometry } from "./measurementGeometry.js";
16
- import { MeasurementGuideOverlay } from "./MeasurementGuideOverlay.js";
17
- import { resolveSelectionTarget, selectionTargetMode } from "../selection/selectionTarget.js";
18
- import { isInlineTextEditingActive, useInlineTextSession } from "../inline-text/inlineTextEditor.js";
19
- import { EMPTY_TEXT_PROJECTION_ATTR } from "../projection/textProjection.js";
20
- import { useNudgeUiRuntimeConfig } from "../runtime/useRuntimeConfig.js";
21
- import { DomNavigator } from "./DomNavigator.js";
22
- export { getMarginFills, getMarginGuides, } from "./overlayGeometry.js";
23
- function overlayStyle(rect) {
24
- return {
25
- position: "fixed",
26
- left: rect.left,
27
- top: rect.top,
28
- width: rect.width,
29
- height: rect.height,
30
- pointerEvents: "none",
31
- };
32
- }
33
- export function InspectorOverlay({ host }) {
34
- const open = useInspectorOpen();
35
- const selected = useSelectedElement();
36
- const selectedElements = useSelectedElements();
37
- const hierarchy = useHierarchy();
38
- const domNavigationEnabled = useNudgeUiRuntimeConfig().capabilities.domNavigation === true;
39
- const inlineTextSession = useInlineTextSession();
40
- const [hoverRect, setHoverRect] = useState(null);
41
- const [hoverMargins, setHoverMargins] = useState(null);
42
- const [hoverBorders, setHoverBorders] = useState(null);
43
- const [selectedRects, setSelectedRects] = useState([]);
44
- const [selectedBorders, setSelectedBorders] = useState(null);
45
- const [optionDown, setOptionDown] = useState(false);
46
- const [pointerOverPage, setPointerOverPage] = useState(false);
47
- const dropGuide = useDropGuide("inspect");
48
- const hoverElRef = useRef(null);
49
- const isDraggingRef = useRef(false);
50
- const rafRef = useRef(0);
51
- useEffect(() => {
52
- if (!open) {
53
- setHoverRect(null);
54
- setHoverMargins(null);
55
- setHoverBorders(null);
56
- hoverElRef.current = null;
57
- setPointerOverPage(false);
58
- return;
59
- }
60
- let observedHover = null;
61
- const ResizeObserverCtor = window.ResizeObserver;
62
- const hoverResizeObserver = ResizeObserverCtor ? new ResizeObserverCtor(scheduleHoverRecalc) : null;
63
- function clearHover() {
64
- hoverElRef.current = null;
65
- setHoverRect(null);
66
- setHoverMargins(null);
67
- setHoverBorders(null);
68
- hoverResizeObserver?.disconnect();
69
- observedHover = null;
70
- }
71
- function observeHover(el) {
72
- if (observedHover === el)
73
- return;
74
- hoverResizeObserver?.disconnect();
75
- hoverResizeObserver?.observe(el);
76
- observedHover = el;
77
- }
78
- function recalcHover() {
79
- if (isDraggingRef.current)
80
- return;
81
- const el = hoverElRef.current;
82
- if (!el) {
83
- setHoverRect(null);
84
- setHoverMargins(null);
85
- setHoverBorders(null);
86
- return;
87
- }
88
- setHoverRect(toRect(el.getBoundingClientRect()));
89
- setHoverMargins(readMargins(el));
90
- setHoverBorders(readBorderWidths(el));
91
- }
92
- function scheduleHoverRecalc() {
93
- if (isDraggingRef.current)
94
- return;
95
- cancelAnimationFrame(rafRef.current);
96
- rafRef.current = requestAnimationFrame(recalcHover);
97
- }
98
- function onMouseOver(e) {
99
- if (isDraggingRef.current)
100
- return;
101
- const target = e.target;
102
- if (!(target instanceof HTMLElement))
103
- return;
104
- if (host === target || host.contains(target)) {
105
- setPointerOverPage(false);
106
- clearHover();
107
- return;
108
- }
109
- setPointerOverPage(true);
110
- const el = resolveSelectionTarget(target, selectionTargetMode(e));
111
- if (!el) {
112
- clearHover();
113
- return;
114
- }
115
- hoverElRef.current = el;
116
- observeHover(el);
117
- scheduleHoverRecalc();
118
- }
119
- function onMouseOut(e) {
120
- if (isDraggingRef.current)
121
- return;
122
- const related = e.relatedTarget;
123
- if (!related || !(related instanceof Node)) {
124
- setPointerOverPage(false);
125
- clearHover();
126
- return;
127
- }
128
- if (host === related || host.contains(related)) {
129
- setPointerOverPage(false);
130
- clearHover();
131
- return;
132
- }
133
- const nearest = resolveSelectionTarget(related, selectionTargetMode(e));
134
- if (nearest !== hoverElRef.current)
135
- clearHover();
136
- }
137
- document.addEventListener("mouseover", onMouseOver, true);
138
- document.addEventListener("mouseout", onMouseOut, true);
139
- window.addEventListener("resize", scheduleHoverRecalc);
140
- window.addEventListener("scroll", scheduleHoverRecalc, true);
141
- const removeClickCapture = installElementSelector(host);
142
- return () => {
143
- cancelAnimationFrame(rafRef.current);
144
- document.removeEventListener("mouseover", onMouseOver, true);
145
- document.removeEventListener("mouseout", onMouseOut, true);
146
- removeClickCapture();
147
- window.removeEventListener("resize", scheduleHoverRecalc);
148
- window.removeEventListener("scroll", scheduleHoverRecalc, true);
149
- hoverResizeObserver?.disconnect();
150
- };
151
- }, [open, host]);
152
- useEffect(() => {
153
- let raf = 0;
154
- function recalc() {
155
- setSelectedRects(selectedElements.map((candidate) => toRect(candidate.domElement.getBoundingClientRect())));
156
- if (selected) {
157
- setSelectedBorders(readBorderWidths(selected.domElement));
158
- }
159
- else {
160
- setSelectedBorders(null);
161
- }
162
- }
163
- function schedule() {
164
- cancelAnimationFrame(raf);
165
- raf = requestAnimationFrame(recalc);
166
- }
167
- recalc();
168
- const stopObserving = selectedElements.map((candidate) => observeSelectedGeometry(candidate.domElement, schedule));
169
- return () => {
170
- cancelAnimationFrame(raf);
171
- stopObserving.forEach((stop) => stop());
172
- };
173
- }, [selectedElements]);
174
- useEffect(() => {
175
- if (!open) {
176
- setOptionDown(false);
177
- return;
178
- }
179
- function updateOptionState(event) {
180
- setOptionDown(event.altKey);
181
- }
182
- function clearOptionState() {
183
- setOptionDown(false);
184
- }
185
- window.addEventListener("keydown", updateOptionState);
186
- window.addEventListener("keyup", updateOptionState);
187
- window.addEventListener("blur", clearOptionState);
188
- return () => {
189
- window.removeEventListener("keydown", updateOptionState);
190
- window.removeEventListener("keyup", updateOptionState);
191
- window.removeEventListener("blur", clearOptionState);
192
- };
193
- }, [open]);
194
- useEffect(() => {
195
- if (!open)
196
- return;
197
- const removeInteractionStyles = installInteractionStyles();
198
- let candidate = null;
199
- let dragging = false;
200
- let start = null;
201
- function updateGuide(point) {
202
- if (!candidate)
203
- return;
204
- const drop = getDropLocationAtPoint(document, candidate, point.x, point.y);
205
- if (drop)
206
- showDropGuide("inspect", document, drop);
207
- else
208
- clearDropGuide("inspect");
209
- }
210
- const guideUpdate = createFrameThrottle(updateGuide);
211
- function clear() {
212
- guideUpdate.cancel();
213
- isDraggingRef.current = false;
214
- candidate = null;
215
- dragging = false;
216
- start = null;
217
- clearDropGuide("inspect");
218
- }
219
- function onPointerDown(event) {
220
- if (isInlineTextEditingActive())
221
- return;
222
- if (getSelectedElements().length > 1)
223
- return;
224
- if (event.button !== 0 || !(event.target instanceof HTMLElement))
225
- return;
226
- if (host === event.target || host.contains(event.target))
227
- return;
228
- if (event.target.closest(`[${EMPTY_TEXT_PROJECTION_ATTR}]`))
229
- return;
230
- const target = resolveSelectionTarget(event.target, selectionTargetMode(event));
231
- if (!target)
232
- return;
233
- candidate = target;
234
- start = { x: event.clientX, y: event.clientY };
235
- }
236
- function onPointerMove(event) {
237
- if (isInlineTextEditingActive())
238
- return;
239
- if (!candidate || !start)
240
- return;
241
- if (!dragging && Math.hypot(event.clientX - start.x, event.clientY - start.y) < 6)
242
- return;
243
- event.preventDefault();
244
- const point = { x: event.clientX, y: event.clientY };
245
- if (!dragging) {
246
- dragging = true;
247
- isDraggingRef.current = true;
248
- hoverElRef.current = null;
249
- setHoverRect(null);
250
- setHoverMargins(null);
251
- const selected = resolveSelectionFromElement(candidate);
252
- if (selected)
253
- setSelectedElement(selected);
254
- updateGuide(point);
255
- return;
256
- }
257
- guideUpdate.schedule(point);
258
- }
259
- function onPointerUp(event) {
260
- if (isInlineTextEditingActive())
261
- return;
262
- if (!candidate || !dragging) {
263
- clear();
264
- return;
265
- }
266
- event.preventDefault();
267
- const drop = getDropLocationAtPoint(document, candidate, event.clientX, event.clientY);
268
- if (drop)
269
- moveElement(candidate, drop);
270
- const selected = resolveSelectionFromElement(candidate);
271
- if (selected)
272
- setSelectedElement(selected);
273
- clear();
274
- }
275
- document.addEventListener("mousedown", onPointerDown, true);
276
- document.addEventListener("mousemove", onPointerMove, true);
277
- document.addEventListener("mouseup", onPointerUp, true);
278
- return () => {
279
- document.removeEventListener("mousedown", onPointerDown, true);
280
- document.removeEventListener("mousemove", onPointerMove, true);
281
- document.removeEventListener("mouseup", onPointerUp, true);
282
- guideUpdate.cancel();
283
- isDraggingRef.current = false;
284
- clearDropGuide("inspect");
285
- removeInteractionStyles();
286
- };
287
- }, [open, host]);
288
- const selectedGeometry = selectedElements.flatMap((candidate, index) => {
289
- const rect = selectedRects[index];
290
- return rect ? [{ element: candidate, rect }] : [];
291
- });
292
- const selectedPrimaryIndex = selectedElements.findIndex((candidate) => candidate.domElement === selected?.domElement);
293
- const selectedRect = selectedRects[selectedPrimaryIndex >= 0 ? selectedPrimaryIndex : 0] ?? null;
294
- const hoverStyle = hoverRect ? overlayStyle(hoverRect) : { display: "none" };
295
- const hoverMarginGuides = hoverRect && hoverMargins
296
- ? getMarginGuides(hoverRect, hoverMargins)
297
- : [];
298
- const hoverMarginFills = hoverRect && hoverMargins
299
- ? getMarginFills(hoverRect, hoverMargins)
300
- : [];
301
- const showGuideOverlay = open
302
- && selectedElements.length === 1
303
- && optionDown
304
- && pointerOverPage
305
- && selectedRect;
306
- const showMeasurement = showGuideOverlay
307
- && hoverRect
308
- && hoverElRef.current !== selected?.domElement;
309
- const measurement = showMeasurement && selectedRect && hoverRect
310
- ? getMeasurementGeometry(selectedRect, hoverRect, {
311
- selectedBorders: selectedBorders ?? undefined,
312
- hoveredBorders: hoverBorders ?? undefined,
313
- })
314
- : null;
315
- return (_jsxs(_Fragment, { children: [showGuideOverlay && selectedRect ? (_jsx(MeasurementGuideOverlay, { selectedRect: selectedRect, segments: measurement?.segments ?? [] })) : null, open && hoverRect ? (_jsxs(_Fragment, { children: [hoverMarginFills.map((fill) => (_jsx("div", { className: "hover-margin-fill", "data-side": fill.side, style: {
316
- position: "fixed",
317
- left: fill.left,
318
- top: fill.top,
319
- width: fill.width,
320
- height: fill.height,
321
- pointerEvents: "none",
322
- }, "aria-hidden": "true" }, fill.side))), _jsx("div", { className: "hover-outline", style: hoverStyle, "aria-hidden": "true" }), hoverMarginGuides.map((guide) => (_jsx("div", { className: "hover-margin", "data-axis": guide.axis, "data-distance": guide.distance, "data-side": guide.side, style: {
323
- position: "fixed",
324
- left: guide.left,
325
- top: guide.top,
326
- width: guide.width,
327
- height: guide.height,
328
- pointerEvents: "none",
329
- }, "aria-hidden": "true" }, guide.side)))] })) : null, open && !inlineTextSession ? selectedGeometry.map(({ element, rect }, index) => (_jsx("div", { className: "selected-outline", "data-test": "selected-outline", "data-selected-cid": element.cid, "data-selected-index": index, "data-selected-src": element.src, style: overlayStyle(rect), "aria-hidden": "true" }, `${element.domElement.getAttribute("data-cid") ?? "element"}-${index}`))) : null, open && domNavigationEnabled && !inlineTextSession && selectedElements.length === 1 && selected && selectedRect ? (_jsx(DomNavigator, { selected: selected, hierarchy: hierarchy, anchor: selectedRect, project: (element) => toRect(element.getBoundingClientRect()) })) : null, open && selectedElements.length === 1 ? _jsx(DropGuideOverlay, { guide: dropGuide?.document === document
330
- ? { orientation: dropGuide.orientation, line: dropGuide.line, target: dropGuide.target }
331
- : null, lineClassName: "dom-drop-line", lineTestId: "dom-drop-line", targetClassName: "dom-drop-target", targetTestId: "dom-drop-target" }) : null] }));
332
- }
@@ -1 +0,0 @@
1
- export declare function installElementSelector(inspectorHost: HTMLElement, acceptsClick?: (event: Event) => boolean): () => void;
@@ -1,111 +0,0 @@
1
- import { getSelectedElements, setSelectedElement, toggleSelectedElement } from "../selection/selectionStore.js";
2
- import { getOpen } from "../shell/openStore.js";
3
- import { resolveSelectionFromEvent } from "../selection/resolveSelection.js";
4
- import { handleInlineTextEditIntent, isInlineTextEditingActive, } from "../inline-text/inlineTextEditor.js";
5
- import { EMPTY_TEXT_PROJECTION_ATTR } from "../projection/textProjection.js";
6
- import { APPLICATION_GESTURE_EVENTS, blockApplicationClick, blockApplicationGesture, isInlineEditorTarget, isUserClick, } from "./clickPolicy.js";
7
- export function installElementSelector(inspectorHost, acceptsClick = isUserClick) {
8
- function applyInlineTextDisposition(event, disposition) {
9
- if (disposition === "pass-through")
10
- return;
11
- if (disposition === "suppress")
12
- event.preventDefault();
13
- event.stopPropagation();
14
- }
15
- function onDoubleClick(e) {
16
- if (!getOpen())
17
- return;
18
- if (isInsideInspectorUi(e))
19
- return;
20
- if (getSelectedElements().length > 1) {
21
- e.preventDefault();
22
- e.stopPropagation();
23
- return;
24
- }
25
- if (!(e.target instanceof Element))
26
- return;
27
- applyInlineTextDisposition(e, handleInlineTextEditIntent({
28
- kind: "double-click",
29
- target: e.target,
30
- point: { x: e.clientX, y: e.clientY },
31
- }));
32
- }
33
- function isInsideInspectorUi(event) {
34
- const target = event.target;
35
- if (!(target instanceof Element))
36
- return false;
37
- if (inspectorHost === target || inspectorHost.contains(target))
38
- return true;
39
- // Composed clicks originating inside the inspector's shadow root are
40
- // retargeted to the host before document-level listeners observe them;
41
- // this branch covers dispatch paths where retargeting has not applied.
42
- const root = target.getRootNode();
43
- return root instanceof ShadowRoot && root.host === inspectorHost;
44
- }
45
- function onClick(e) {
46
- if (!getOpen() || !acceptsClick(e))
47
- return;
48
- if (isInsideInspectorUi(e)) {
49
- // The selector guards the inspected application only. Clicks on the
50
- // inspector's own controls must keep their native behavior, so they
51
- // pass through untouched (no preventDefault / stopPropagation).
52
- return;
53
- }
54
- if (isInlineTextEditingActive()) {
55
- e.preventDefault();
56
- e.stopPropagation();
57
- return;
58
- }
59
- if (e.target instanceof Element
60
- && e.target.closest(`[${EMPTY_TEXT_PROJECTION_ATTR}]`)) {
61
- blockApplicationClick(e);
62
- return;
63
- }
64
- // The inspector is an editing surface while open. Capture every ordinary
65
- // application click so buttons, links, and untracked controls cannot run
66
- // alongside selection. Shift-click toggles the primary target in the
67
- // ordered group; Command/Ctrl-click selects the deepest tracked element.
68
- const sel = resolveSelectionFromEvent(e, inspectorHost);
69
- blockApplicationClick(e);
70
- if (sel) {
71
- if (e.shiftKey && !e.metaKey && !e.ctrlKey)
72
- toggleSelectedElement(sel);
73
- else
74
- setSelectedElement(sel);
75
- }
76
- }
77
- function onMouseDown(e) {
78
- if (!getOpen() || isInsideInspectorUi(e))
79
- return;
80
- if (!(e.target instanceof Element))
81
- return;
82
- applyInlineTextDisposition(e, handleInlineTextEditIntent({
83
- kind: "pointer-down",
84
- target: e.target,
85
- point: { x: e.clientX, y: e.clientY },
86
- clickCount: e.detail,
87
- }));
88
- }
89
- function onApplicationGesture(e) {
90
- if (!getOpen() || !acceptsClick(e) || isInlineEditorTarget(e.target))
91
- return;
92
- if (e.target instanceof Element
93
- && (e.target === inspectorHost || inspectorHost.contains(e.target)))
94
- return;
95
- blockApplicationGesture(e);
96
- }
97
- document.addEventListener("mousedown", onMouseDown, true);
98
- document.addEventListener("dblclick", onDoubleClick, true);
99
- document.addEventListener("click", onClick, true);
100
- for (const type of APPLICATION_GESTURE_EVENTS) {
101
- document.addEventListener(type, onApplicationGesture, true);
102
- }
103
- return () => {
104
- document.removeEventListener("mousedown", onMouseDown, true);
105
- document.removeEventListener("dblclick", onDoubleClick, true);
106
- document.removeEventListener("click", onClick, true);
107
- for (const type of APPLICATION_GESTURE_EVENTS) {
108
- document.removeEventListener(type, onApplicationGesture, true);
109
- }
110
- };
111
- }
@@ -1,2 +0,0 @@
1
- import type { ReactElement } from "react";
2
- export declare function SketchChanges(): ReactElement | null;
@@ -1,72 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useEffect, useState } from "react";
3
- import { IconCheck, IconCopy, IconDownload, IconEdit, IconRefresh, IconTrash } from "@tabler/icons-react";
4
- import { Button } from "../ui/Button.js";
5
- import { StatusCallout } from "../ui/StatusCallout.js";
6
- import { copyImageToClipboard, downloadImage } from "./raster.js";
7
- import { editSketch } from "./SketchWorkspace.js";
8
- import { removeSketch, requeueSketch, useSketchStore } from "./store.js";
9
- import {} from "./model.js";
10
- function routeLabel(url) {
11
- try {
12
- const parsed = new URL(url);
13
- return `${parsed.pathname}${parsed.search}` || "/";
14
- }
15
- catch {
16
- return url;
17
- }
18
- }
19
- function statusLabel(status) {
20
- switch (status) {
21
- case "dispatching": return "Sending";
22
- case "handing-off": return "Handing off";
23
- case "needs-review": return "Needs review";
24
- case "unknown": return "Unknown";
25
- default: return "Pending";
26
- }
27
- }
28
- function Thumbnail({ item }) {
29
- const [url, setUrl] = useState(null);
30
- useEffect(() => {
31
- if (typeof URL === "undefined" || typeof URL.createObjectURL !== "function")
32
- return;
33
- const next = URL.createObjectURL(item.document.annotatedImage);
34
- setUrl(next);
35
- return () => URL.revokeObjectURL(next);
36
- }, [item.document.annotatedImage]);
37
- return url ? _jsx("img", { className: "sketch-change__thumbnail", src: url, alt: "Sketch annotation", "data-test": "sketch-thumbnail" }) : _jsx("div", { className: "sketch-change__thumbnail sketch-change__thumbnail--empty", "data-test": "sketch-thumbnail" });
38
- }
39
- function SketchRow({ item }) {
40
- const [actionError, setActionError] = useState(null);
41
- const busy = item.status === "dispatching" || item.status === "handing-off";
42
- const canReview = item.status === "needs-review" || item.status === "unknown";
43
- const document = item.document;
44
- async function copyImage() {
45
- setActionError(null);
46
- try {
47
- await copyImageToClipboard(document.annotatedImage);
48
- }
49
- catch (error) {
50
- setActionError(error instanceof Error ? error.message : "The image could not be copied.");
51
- }
52
- }
53
- async function runQueueAction(action, failureMessage) {
54
- setActionError(null);
55
- try {
56
- if (!await action())
57
- setActionError(failureMessage);
58
- }
59
- catch (error) {
60
- setActionError(error instanceof Error ? error.message : failureMessage);
61
- }
62
- }
63
- return (_jsxs("div", { className: "sketch-change__row", "data-test": "sketch-row", "data-sketch-id": document.id, children: [_jsx(Thumbnail, { item: item }), _jsxs("div", { className: "sketch-change__body", children: [_jsxs("div", { className: "sketch-change__heading", children: [_jsx("span", { className: "sketch-change__name", children: document.filename }), _jsx("span", { className: "sketch-change__status", "data-test": "sketch-status", "data-status": item.status, children: statusLabel(item.status) })] }), _jsxs("span", { className: "sketch-change__route", children: [routeLabel(document.capture.url), " \u00B7 revision ", document.revision] }), document.description ? _jsx("p", { className: "sketch-change__description", children: document.description }) : null, document.annotations?.length ? (_jsx("ol", { className: "sketch-change__annotations", children: document.annotations.map((annotation) => (_jsxs("li", { children: [_jsxs("span", { children: [annotation.number, "."] }), " ", annotation.description] }, annotation.id))) })) : null, _jsxs("div", { className: "sketch-change__actions", children: [_jsxs(Button, { size: "compact", variant: "quiet", type: "button", "data-test": "sketch-copy-image", onClick: () => void copyImage(), children: [_jsx(IconCopy, { size: "var(--icon-size-small)", "aria-hidden": "true" }), " Copy image"] }), _jsxs(Button, { size: "compact", variant: "quiet", type: "button", "data-test": "sketch-download-image", onClick: () => downloadImage(document.annotatedImage, document.filename), children: [_jsx(IconDownload, { size: "var(--icon-size-small)", "aria-hidden": "true" }), " Download"] }), _jsxs(Button, { size: "compact", variant: "quiet", type: "button", "data-test": "sketch-reopen", onClick: () => editSketch(document.id), disabled: busy, children: [_jsx(IconEdit, { size: "var(--icon-size-small)", "aria-hidden": "true" }), " Reopen"] }), canReview ? (_jsxs(Button, { size: "compact", variant: "quiet", type: "button", "data-test": "sketch-requeue", onClick: () => void runQueueAction(() => requeueSketch(document.id), "The sketch could not be requeued."), disabled: busy, children: [_jsx(IconRefresh, { size: "var(--icon-size-small)", "aria-hidden": "true" }), " Requeue"] })) : null, _jsxs(Button, { size: "compact", variant: "quiet", type: "button", "data-test": "sketch-mark-done", onClick: () => void runQueueAction(() => removeSketch(document.id), "The sketch could not be removed yet."), disabled: busy, children: [canReview ? _jsx(IconCheck, { size: "var(--icon-size-small)", "aria-hidden": "true" }) : _jsx(IconTrash, { size: "var(--icon-size-small)", "aria-hidden": "true" }), " ", canReview ? "Mark done" : "Delete"] })] }), actionError ? _jsx("span", { className: "sketch-change__error", role: "status", children: actionError }) : null] })] }));
64
- }
65
- export function SketchChanges() {
66
- const store = useSketchStore();
67
- const items = store.items;
68
- const hasError = store.error !== null;
69
- if (items.length === 0 && !hasError)
70
- return null;
71
- return (_jsxs("section", { className: "sketch-change", "data-test": "sketches", children: [_jsxs("div", { className: "sketch-change__title", children: ["Sketch annotations ", _jsx("span", { children: items.length })] }), store.error ? _jsx(StatusCallout, { tone: "warning", "data-test": "sketch-storage-error", children: store.error }) : null, items.length > 0 ? items.map((item) => _jsx(SketchRow, { item: item }, `${item.document.id}:${item.document.revision}`)) : (_jsx(StatusCallout, { tone: "warning", children: "Saved sketches need recovery. Reload the page to try again." }))] }));
72
- }
@@ -1,4 +0,0 @@
1
- import type { ReactElement } from "react";
2
- export declare function SketchEntryButton({ hostElement }: {
3
- readonly hostElement: HTMLElement | null;
4
- }): ReactElement;
@@ -1,11 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { IconPencil } from "@tabler/icons-react";
3
- import { Button } from "../ui/Button.js";
4
- import { isInlineTextEditingActive } from "../inline-text/inlineTextEditor.js";
5
- import { useSketchInteractionActive } from "./interaction.js";
6
- import { startSketchCapture } from "./SketchWorkspace.js";
7
- export function SketchEntryButton({ hostElement }) {
8
- const active = useSketchInteractionActive();
9
- const disabled = active || isInlineTextEditingActive();
10
- return (_jsxs(Button, { variant: "quiet", size: "compact", className: "panel__sketch-button", type: "button", "data-test": "sketch-entry", "aria-label": "Sketch viewport", disabled: disabled || !hostElement, onClick: () => startSketchCapture(hostElement), children: [_jsx(IconPencil, { size: "var(--icon-size-small)", stroke: 1.8, "aria-hidden": "true" }), _jsx("span", { className: "panel__sketch-label", children: "Sketch" })] }));
11
- }
@@ -1,2 +0,0 @@
1
- import type { ReactElement } from "react";
2
- export declare function SketchLayersPanel(): ReactElement | null;
@@ -1,71 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useEffect, useState } from "react";
3
- import { IconCheck, IconCopy, IconX } from "@tabler/icons-react";
4
- import { Button } from "../ui/Button.js";
5
- import { IconButton } from "../ui/IconButton.js";
6
- import { copyImageToClipboard } from "./raster.js";
7
- import { closeSketchNote } from "./sketchNote.js";
8
- import { removeSketch, useSketchStore } from "./store.js";
9
- import { useFocusedCardId, useSelectedCardId } from "../canvas/canvasStore.js";
10
- import { sketchBelongsToCard, useDrafts } from "../drafts/store.js";
11
- import { Tooltip } from "../ui/Tooltip.js";
12
- function SketchThumbnail({ item }) {
13
- const [url, setUrl] = useState(null);
14
- const hasMarks = item.document.strokes.length > 0 || (item.document.annotations?.length ?? 0) > 0;
15
- useEffect(() => {
16
- if (!hasMarks) {
17
- setUrl(null);
18
- return;
19
- }
20
- if (typeof URL === "undefined" || typeof URL.createObjectURL !== "function")
21
- return;
22
- const next = URL.createObjectURL(item.document.annotatedImage);
23
- setUrl(next);
24
- return () => URL.revokeObjectURL(next);
25
- }, [hasMarks, item.document.annotatedImage]);
26
- return hasMarks && url ? (_jsx("img", { className: "sketch-layers__thumbnail", src: url, alt: "", "aria-hidden": "true" })) : (_jsx("span", { className: "sketch-layers__thumbnail sketch-layers__thumbnail--empty", "aria-hidden": "true" }));
27
- }
28
- function SketchLayer({ item, index, multiple, }) {
29
- const [copied, setCopied] = useState(false);
30
- const [error, setError] = useState(null);
31
- const busy = item.status === "dispatching" || item.status === "handing-off";
32
- async function copyImage() {
33
- setError(null);
34
- try {
35
- await copyImageToClipboard(item.document.annotatedImage);
36
- setCopied(true);
37
- window.setTimeout(() => setCopied(false), 1500);
38
- }
39
- catch (copyError) {
40
- setError(copyError instanceof Error ? copyError.message : "The sketch image could not be copied.");
41
- }
42
- }
43
- async function deleteLayer() {
44
- setError(null);
45
- try {
46
- if (!await removeSketch(item.document.id)) {
47
- setError("This sketch is being sent and cannot be deleted yet.");
48
- }
49
- else {
50
- closeSketchNote();
51
- }
52
- }
53
- catch (deleteError) {
54
- setError(deleteError instanceof Error ? deleteError.message : "The sketch could not be deleted.");
55
- }
56
- }
57
- return (_jsxs("div", { className: "sketch-layers__item", "data-test": "sketch-layer", "data-sketch-id": item.document.id, children: [_jsxs(Button, { className: "sketch-layers__copy", variant: "primary", type: "button", "data-test": "sketch-layer-copy-image", onClick: () => void copyImage(), disabled: busy, children: [_jsxs("span", { className: "sketch-layers__copy-label", children: [copied
58
- ? _jsx(IconCheck, { size: "var(--icon-size-small)", "aria-hidden": "true" })
59
- : _jsx(IconCopy, { size: "var(--icon-size-small)", stroke: "var(--icon-stroke-width)", "aria-hidden": "true" }), _jsx("span", { className: "sketch-layers__name", children: copied ? "Copied" : `Copy sketch note${multiple ? ` ${index + 1}` : ""}` })] }), _jsx(SketchThumbnail, { item: item })] }), _jsx(Tooltip, { children: _jsx(IconButton, { className: "sketch-layers__delete", variant: "quiet", size: "compact", label: "Delete sketch", "data-test": "sketch-layer-delete", onClick: () => void deleteLayer(), disabled: busy, children: _jsx(IconX, { size: "var(--icon-size-small)", "aria-hidden": "true" }) }) }), error ? _jsx("span", { className: "sketch-layers__error", role: "status", children: error }) : null] }));
60
- }
61
- export function SketchLayersPanel() {
62
- const { items } = useSketchStore();
63
- useDrafts();
64
- const selectedCardId = useSelectedCardId();
65
- const focusedCardId = useFocusedCardId();
66
- const cardId = selectedCardId ?? focusedCardId;
67
- const visibleItems = items.filter((item) => sketchBelongsToCard(item.document, cardId));
68
- if (visibleItems.length === 0)
69
- return null;
70
- return (_jsx("section", { className: "sketch-layers", "data-test": "sketch-layers", "aria-label": "Sketch layers", children: visibleItems.map((item, index) => (_jsx(SketchLayer, { item: item, index: index, multiple: visibleItems.length > 1 }, `${item.document.id}:${item.document.revision}`))) }));
71
- }