@sylergydigital/issue-pin-sdk 0.6.3 → 0.6.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.
- package/CHANGELOG.md +245 -0
- package/dist/index.cjs +159 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +162 -12
- package/dist/index.js.map +1 -1
- package/package.json +3 -2
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `@sylergydigital/issue-pin-sdk` are documented here.
|
|
4
|
+
|
|
5
|
+
## [0.6.5] - 2026-04-15
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
- **Draggable launcher button** — the feedback launcher can now be freely dragged across the viewport using mouse, touch, or pen input (iOS AssistiveTouch pattern). On release, the button smoothly snaps to the nearest left or right viewport edge.
|
|
9
|
+
- Position persistence — launcher position (edge + Y offset) is saved to `localStorage` and restored across page reloads.
|
|
10
|
+
- Menu and hint toast auto-flip to the opposite side of the docked edge so they never render off-screen.
|
|
11
|
+
- Viewport resize clamping — button repositions to stay within bounds when the window is resized.
|
|
12
|
+
- Click vs. drag disambiguation — short interactions (< 5px movement) still toggle the menu normally.
|
|
13
|
+
|
|
14
|
+
## [0.6.4] - 2026-04-14
|
|
15
|
+
|
|
16
|
+
### Fixed
|
|
17
|
+
- Included `CHANGELOG.md` in the SDK npm publish pipeline (`files` array in package.json).
|
|
18
|
+
|
|
19
|
+
### Added
|
|
20
|
+
- SDK CHANGELOG.md with full release history.
|
|
21
|
+
|
|
22
|
+
## [0.6.3] - 2026-04-14
|
|
23
|
+
|
|
24
|
+
### Added
|
|
25
|
+
- **UUID normalization for non-UUID auth providers** — SDK auto-converts Firebase, Auth0, Cognito, and other non-UUID user IDs to deterministic UUID v5 format at the SDK boundary. Existing UUID-format IDs pass through unchanged.
|
|
26
|
+
- `normalizeUserId()` / `toSupabaseUuid()` — public utility export for converting user IDs outside the SDK component lifecycle.
|
|
27
|
+
- `CSP_REQUIREMENTS` — typed constant exporting all Content Security Policy directives required by the SDK (`connect-src`, `img-src`, `style-src`), usable in server middleware or build-time CSP generation.
|
|
28
|
+
- Runtime CSP violation detection — `subscribeCspDetection()` automatically activates on SDK mount and logs actionable `[IssuePin]` console warnings when CSP blocks SDK functionality. Per-directive deduplication prevents warning spam.
|
|
29
|
+
- CSP documentation section in SDK README with copy-paste directive block, per-directive explanation table, and programmatic access example.
|
|
30
|
+
- Debug logging for ID conversions — when `debug={true}`, logs `[EW SDK] User ID normalized: "{raw}" -> "{effective}"` for converted IDs.
|
|
31
|
+
|
|
32
|
+
### Fixed
|
|
33
|
+
- Stale closure in identity warning gated on `authReady` state.
|
|
34
|
+
- Missing SSR guard in `subscribeCspDetection` (safe for server-side rendering).
|
|
35
|
+
|
|
36
|
+
### Dependencies
|
|
37
|
+
- Added `uuid@^11.0.3` as bundled dependency (CommonJS-compatible).
|
|
38
|
+
|
|
39
|
+
## [0.6.2] - 2026-04-02
|
|
40
|
+
|
|
41
|
+
### Fixed
|
|
42
|
+
- Replaced `html2canvas` with `html2canvas-pro` to support modern CSS features like `oklab` color space.
|
|
43
|
+
|
|
44
|
+
## [0.6.1] - 2026-03-24
|
|
45
|
+
|
|
46
|
+
### Changed
|
|
47
|
+
- Set up public SDK mirror and npm release pipeline.
|
|
48
|
+
|
|
49
|
+
## [0.6.0] - 2026-03-24
|
|
50
|
+
|
|
51
|
+
### Changed
|
|
52
|
+
- Set up public SDK mirror and npm release pipeline.
|
|
53
|
+
|
|
54
|
+
## [0.5.9] - 2026-03-24
|
|
55
|
+
|
|
56
|
+
### Changed
|
|
57
|
+
- Public SDK mirror and npm registry setup.
|
|
58
|
+
|
|
59
|
+
## [0.5.8] - 2026-03-23
|
|
60
|
+
|
|
61
|
+
### Added
|
|
62
|
+
- `showHints` toggle for instructional UI hints in the SDK.
|
|
63
|
+
|
|
64
|
+
## [0.5.7] - 2026-03-23
|
|
65
|
+
|
|
66
|
+
### Added
|
|
67
|
+
- Verified LMS federation rollout (patch).
|
|
68
|
+
|
|
69
|
+
## [0.5.6] - 2026-03-23
|
|
70
|
+
|
|
71
|
+
### Added
|
|
72
|
+
- LMS federation rollout with verification.
|
|
73
|
+
|
|
74
|
+
## [0.5.5] - 2026-03-22
|
|
75
|
+
|
|
76
|
+
### Fixed
|
|
77
|
+
- SDK build and packaging fixes.
|
|
78
|
+
|
|
79
|
+
## [0.5.4] - 2026-03-22
|
|
80
|
+
|
|
81
|
+
### Fixed
|
|
82
|
+
- SDK build and packaging fixes.
|
|
83
|
+
|
|
84
|
+
## [0.5.3] - 2026-03-22
|
|
85
|
+
|
|
86
|
+
### Changed
|
|
87
|
+
- Aligned SDK docs and package metadata with router-free integration.
|
|
88
|
+
|
|
89
|
+
## [0.5.2] - 2026-03-22
|
|
90
|
+
|
|
91
|
+
### Added
|
|
92
|
+
- Iframe review mode for SDK pins (canvas review surface).
|
|
93
|
+
|
|
94
|
+
## [0.5.1] - 2026-03-22
|
|
95
|
+
|
|
96
|
+
### Added
|
|
97
|
+
- Anonymous screenshot reads for SDK workspaces via Supabase RLS.
|
|
98
|
+
- ThreadPins test coverage.
|
|
99
|
+
- npm registry publishing.
|
|
100
|
+
|
|
101
|
+
## [0.5.0] - 2026-03-22
|
|
102
|
+
|
|
103
|
+
### Changed
|
|
104
|
+
- npm versioning aligned with git tags.
|
|
105
|
+
|
|
106
|
+
## [0.4.9] - 2026-03-22
|
|
107
|
+
|
|
108
|
+
### Changed
|
|
109
|
+
- Vite host allowlist and gitignore for local tooling.
|
|
110
|
+
|
|
111
|
+
## [0.4.8] - 2026-03-17
|
|
112
|
+
|
|
113
|
+
### Added
|
|
114
|
+
- SDK customization APIs for launcher visibility and pin visibility control.
|
|
115
|
+
|
|
116
|
+
## [0.4.7] - 2026-03-17
|
|
117
|
+
|
|
118
|
+
### Fixed
|
|
119
|
+
- SDK publish build for controlled pin mode.
|
|
120
|
+
|
|
121
|
+
## [0.4.6] - 2026-03-17
|
|
122
|
+
|
|
123
|
+
### Changed
|
|
124
|
+
- Thread pins open in a new tab.
|
|
125
|
+
|
|
126
|
+
## [0.4.5] - 2026-03-17
|
|
127
|
+
|
|
128
|
+
### Changed
|
|
129
|
+
- Rewrote SDK pin positioning lifecycle for stability.
|
|
130
|
+
|
|
131
|
+
## [0.4.4] - 2026-03-17
|
|
132
|
+
|
|
133
|
+
### Fixed
|
|
134
|
+
- Stabilized SDK pin rehydration observer.
|
|
135
|
+
|
|
136
|
+
## [0.4.3] - 2026-03-17
|
|
137
|
+
|
|
138
|
+
### Changed
|
|
139
|
+
- Allow anonymous `sdk-resolve` calls.
|
|
140
|
+
|
|
141
|
+
## [0.4.2] - 2026-03-17
|
|
142
|
+
|
|
143
|
+
### Changed
|
|
144
|
+
- Allow commenter workspace memberships.
|
|
145
|
+
|
|
146
|
+
## [0.4.1] - 2026-03-17
|
|
147
|
+
|
|
148
|
+
### Added
|
|
149
|
+
- Documentation for federated first-write gating.
|
|
150
|
+
|
|
151
|
+
## [0.4.0] - 2026-03-17
|
|
152
|
+
|
|
153
|
+
### Fixed
|
|
154
|
+
- Federated SDK author attribution.
|
|
155
|
+
|
|
156
|
+
## [0.3.4] - 2026-03-16
|
|
157
|
+
|
|
158
|
+
### Added
|
|
159
|
+
- Anonymous update RLS policy.
|
|
160
|
+
|
|
161
|
+
## [0.3.3] - 2026-03-16
|
|
162
|
+
|
|
163
|
+
### Changed
|
|
164
|
+
- Enabled React Router v7 future flag.
|
|
165
|
+
|
|
166
|
+
## [0.3.2] - 2026-03-16
|
|
167
|
+
|
|
168
|
+
### Changed
|
|
169
|
+
- Relaxed thread comments foreign key constraint.
|
|
170
|
+
|
|
171
|
+
## [0.3.1] - 2026-03-16
|
|
172
|
+
|
|
173
|
+
### Added
|
|
174
|
+
- RLS policies for anonymous inserts.
|
|
175
|
+
|
|
176
|
+
## [0.3.0] - 2026-03-16
|
|
177
|
+
|
|
178
|
+
### Fixed
|
|
179
|
+
- SDK feedback launcher click behavior.
|
|
180
|
+
|
|
181
|
+
## [0.2.9] - 2026-03-16
|
|
182
|
+
|
|
183
|
+
### Added
|
|
184
|
+
- Hardcoded SDK theme for consistent styling.
|
|
185
|
+
|
|
186
|
+
## [0.2.8] - 2026-03-16
|
|
187
|
+
|
|
188
|
+
### Fixed
|
|
189
|
+
- FeedbackButton `.d.ts` build ordering.
|
|
190
|
+
|
|
191
|
+
## [0.2.7] - 2026-03-16
|
|
192
|
+
|
|
193
|
+
### Added
|
|
194
|
+
- Debug logging for SDK menu state.
|
|
195
|
+
|
|
196
|
+
### Fixed
|
|
197
|
+
- SDK menu state management hardened.
|
|
198
|
+
|
|
199
|
+
## [0.2.6] - 2026-03-16
|
|
200
|
+
|
|
201
|
+
### Fixed
|
|
202
|
+
- SDK feedback launcher click handling.
|
|
203
|
+
|
|
204
|
+
## [0.2.5] - 2026-03-16
|
|
205
|
+
|
|
206
|
+
### Fixed
|
|
207
|
+
- FeedbackButton interaction reliability.
|
|
208
|
+
|
|
209
|
+
## [0.2.4] - 2026-03-16
|
|
210
|
+
|
|
211
|
+
### Fixed
|
|
212
|
+
- Stabilized `getSignedUrlRef` for screenshot storage.
|
|
213
|
+
|
|
214
|
+
## [0.2.3] - 2026-03-16
|
|
215
|
+
|
|
216
|
+
### Added
|
|
217
|
+
- Error boundary wrapping for ThreadPins.
|
|
218
|
+
|
|
219
|
+
## [0.2.0] - 2026-03-16
|
|
220
|
+
|
|
221
|
+
### Changed
|
|
222
|
+
- Renamed SDK package to `@sylergydigital/issue-pin-sdk`.
|
|
223
|
+
|
|
224
|
+
## [0.1.8] - 2026-03-16
|
|
225
|
+
|
|
226
|
+
### Fixed
|
|
227
|
+
- TS2722 error in ScreenshotFeedback component.
|
|
228
|
+
|
|
229
|
+
## [0.1.6] - 2026-03-16
|
|
230
|
+
|
|
231
|
+
### Fixed
|
|
232
|
+
- Viewport auto-screenshot capture.
|
|
233
|
+
|
|
234
|
+
## [0.1.5] - 2026-03-16
|
|
235
|
+
|
|
236
|
+
### Fixed
|
|
237
|
+
- Auto-screenshot fetch reliability.
|
|
238
|
+
|
|
239
|
+
## [0.1.0] - 2026-03-16
|
|
240
|
+
|
|
241
|
+
### Added
|
|
242
|
+
- Initial SDK release as `@sylergydigital/issue-pin-sdk`.
|
|
243
|
+
- `<IssuePin />` drop-in component with pin annotations, screenshot capture, and threaded discussions.
|
|
244
|
+
- Supabase-backed real-time data layer.
|
|
245
|
+
- Federated user identity for SDK consumers.
|
package/dist/index.cjs
CHANGED
|
@@ -2168,10 +2168,52 @@ function getLauncherCapabilities({
|
|
|
2168
2168
|
|
|
2169
2169
|
// src/FeedbackButton.tsx
|
|
2170
2170
|
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
2171
|
+
var LAUNCHER_POS_KEY = "issue-pin:launcher-pos";
|
|
2172
|
+
var DRAG_THRESHOLD = 5;
|
|
2173
|
+
var EDGE_MARGIN = 20;
|
|
2174
|
+
var BTN_SIZE = 48;
|
|
2175
|
+
var SNAP_EASING = "cubic-bezier(0.2, 0, 0, 1)";
|
|
2176
|
+
var SNAP_TRANSITION = `left 0.3s ${SNAP_EASING}, top 0.3s ${SNAP_EASING}`;
|
|
2177
|
+
function loadPos(initialEdge) {
|
|
2178
|
+
try {
|
|
2179
|
+
const raw = localStorage.getItem(LAUNCHER_POS_KEY);
|
|
2180
|
+
if (raw) {
|
|
2181
|
+
const parsed = JSON.parse(raw);
|
|
2182
|
+
if ((parsed.edge === "left" || parsed.edge === "right") && typeof parsed.y === "number") {
|
|
2183
|
+
return { edge: parsed.edge, y: parsed.y };
|
|
2184
|
+
}
|
|
2185
|
+
}
|
|
2186
|
+
} catch {
|
|
2187
|
+
}
|
|
2188
|
+
return {
|
|
2189
|
+
edge: initialEdge === "bottom-left" ? "left" : "right",
|
|
2190
|
+
y: window.innerHeight - BTN_SIZE - EDGE_MARGIN
|
|
2191
|
+
};
|
|
2192
|
+
}
|
|
2193
|
+
function savePos(pos) {
|
|
2194
|
+
try {
|
|
2195
|
+
localStorage.setItem(LAUNCHER_POS_KEY, JSON.stringify(pos));
|
|
2196
|
+
} catch {
|
|
2197
|
+
}
|
|
2198
|
+
}
|
|
2199
|
+
function clampY(y) {
|
|
2200
|
+
return Math.min(
|
|
2201
|
+
Math.max(y, EDGE_MARGIN),
|
|
2202
|
+
window.innerHeight - BTN_SIZE - EDGE_MARGIN
|
|
2203
|
+
);
|
|
2204
|
+
}
|
|
2205
|
+
function snapXForEdge(edge) {
|
|
2206
|
+
return edge === "left" ? EDGE_MARGIN : window.innerWidth - BTN_SIZE - EDGE_MARGIN;
|
|
2207
|
+
}
|
|
2171
2208
|
function FeedbackButton({ position = "bottom-right" }) {
|
|
2172
2209
|
const ctx = useFeedbackSafe();
|
|
2173
2210
|
const menuRef = (0, import_react9.useRef)(null);
|
|
2174
2211
|
const [hintDismissed, setHintDismissed] = (0, import_react9.useState)(false);
|
|
2212
|
+
const [pos, setPos] = (0, import_react9.useState)(() => loadPos(position));
|
|
2213
|
+
const [dragXY, setDragXY] = (0, import_react9.useState)(null);
|
|
2214
|
+
const [snapping, setSnapping] = (0, import_react9.useState)(false);
|
|
2215
|
+
const dragStateRef = (0, import_react9.useRef)(null);
|
|
2216
|
+
const snapTimerRef = (0, import_react9.useRef)(null);
|
|
2175
2217
|
const menuOpenState = ctx?.menuOpen ?? false;
|
|
2176
2218
|
const debug = ctx?.debug ?? false;
|
|
2177
2219
|
(0, import_react9.useEffect)(() => {
|
|
@@ -2189,6 +2231,79 @@ function FeedbackButton({ position = "bottom-right" }) {
|
|
|
2189
2231
|
console.log("[EW SDK] FeedbackButton mounted");
|
|
2190
2232
|
return () => console.log("[EW SDK] FeedbackButton unmounted");
|
|
2191
2233
|
}, [debug]);
|
|
2234
|
+
(0, import_react9.useEffect)(() => {
|
|
2235
|
+
const handleResize = () => {
|
|
2236
|
+
setPos((prev) => {
|
|
2237
|
+
const newPos = {
|
|
2238
|
+
edge: prev.edge,
|
|
2239
|
+
y: clampY(prev.y)
|
|
2240
|
+
};
|
|
2241
|
+
savePos(newPos);
|
|
2242
|
+
return newPos;
|
|
2243
|
+
});
|
|
2244
|
+
};
|
|
2245
|
+
window.addEventListener("resize", handleResize);
|
|
2246
|
+
return () => window.removeEventListener("resize", handleResize);
|
|
2247
|
+
}, []);
|
|
2248
|
+
(0, import_react9.useEffect)(() => {
|
|
2249
|
+
return () => {
|
|
2250
|
+
if (snapTimerRef.current) clearTimeout(snapTimerRef.current);
|
|
2251
|
+
};
|
|
2252
|
+
}, []);
|
|
2253
|
+
const handlePointerDown = (0, import_react9.useCallback)((e) => {
|
|
2254
|
+
if (e.button != null && e.button !== 0) return;
|
|
2255
|
+
e.currentTarget.setPointerCapture(e.pointerId);
|
|
2256
|
+
dragStateRef.current = {
|
|
2257
|
+
active: false,
|
|
2258
|
+
startX: e.clientX,
|
|
2259
|
+
startY: e.clientY,
|
|
2260
|
+
currentX: e.clientX,
|
|
2261
|
+
currentY: e.clientY,
|
|
2262
|
+
didDrag: false
|
|
2263
|
+
};
|
|
2264
|
+
}, []);
|
|
2265
|
+
const handlePointerMove = (0, import_react9.useCallback)((e) => {
|
|
2266
|
+
const ds = dragStateRef.current;
|
|
2267
|
+
if (!ds) return;
|
|
2268
|
+
const dx = e.clientX - ds.startX;
|
|
2269
|
+
const dy = e.clientY - ds.startY;
|
|
2270
|
+
const distance = Math.sqrt(dx * dx + dy * dy);
|
|
2271
|
+
if (!ds.active && distance >= DRAG_THRESHOLD) {
|
|
2272
|
+
ds.active = true;
|
|
2273
|
+
ds.didDrag = true;
|
|
2274
|
+
}
|
|
2275
|
+
if (ds.active) {
|
|
2276
|
+
ds.currentX = e.clientX;
|
|
2277
|
+
ds.currentY = e.clientY;
|
|
2278
|
+
const x = e.clientX - BTN_SIZE / 2;
|
|
2279
|
+
const y = clampY(e.clientY - BTN_SIZE / 2);
|
|
2280
|
+
setDragXY({ x, y });
|
|
2281
|
+
}
|
|
2282
|
+
}, []);
|
|
2283
|
+
const handlePointerUp = (0, import_react9.useCallback)((e) => {
|
|
2284
|
+
try {
|
|
2285
|
+
e.currentTarget.releasePointerCapture(e.pointerId);
|
|
2286
|
+
} catch {
|
|
2287
|
+
}
|
|
2288
|
+
const ds = dragStateRef.current;
|
|
2289
|
+
if (!ds || !ds.didDrag) {
|
|
2290
|
+
dragStateRef.current = null;
|
|
2291
|
+
return;
|
|
2292
|
+
}
|
|
2293
|
+
const centerX = ds.currentX;
|
|
2294
|
+
const edge = centerX < window.innerWidth / 2 ? "left" : "right";
|
|
2295
|
+
const y = clampY(ds.currentY - BTN_SIZE / 2);
|
|
2296
|
+
const newPos = { edge, y };
|
|
2297
|
+
setSnapping(true);
|
|
2298
|
+
setPos(newPos);
|
|
2299
|
+
savePos(newPos);
|
|
2300
|
+
setDragXY(null);
|
|
2301
|
+
if (snapTimerRef.current) clearTimeout(snapTimerRef.current);
|
|
2302
|
+
snapTimerRef.current = setTimeout(() => {
|
|
2303
|
+
setSnapping(false);
|
|
2304
|
+
snapTimerRef.current = null;
|
|
2305
|
+
}, 300);
|
|
2306
|
+
}, []);
|
|
2192
2307
|
if (!ctx) return null;
|
|
2193
2308
|
const {
|
|
2194
2309
|
mode,
|
|
@@ -2204,9 +2319,13 @@ function FeedbackButton({ position = "bottom-right" }) {
|
|
|
2204
2319
|
} = ctx;
|
|
2205
2320
|
const annotate = mode === "annotate";
|
|
2206
2321
|
const capabilities = getLauncherCapabilities({ allowPinOnPage: canPinOnPage, allowScreenshot: canScreenshot });
|
|
2207
|
-
const posStyle = position === "bottom-left" ? { left: 20, bottom: 20 } : { right: 20, bottom: 20 };
|
|
2208
|
-
const hintStyle = position === "bottom-left" ? { left: 56, bottom: 8 } : { right: 56, bottom: 8 };
|
|
2209
2322
|
const handleToggle = () => {
|
|
2323
|
+
if (dragStateRef.current?.didDrag) {
|
|
2324
|
+
dragStateRef.current.didDrag = false;
|
|
2325
|
+
dragStateRef.current = null;
|
|
2326
|
+
return;
|
|
2327
|
+
}
|
|
2328
|
+
dragStateRef.current = null;
|
|
2210
2329
|
if (debug) console.log("[EW SDK] handleToggle", { mode, menuOpen });
|
|
2211
2330
|
setHintDismissed(true);
|
|
2212
2331
|
if (annotate) {
|
|
@@ -2226,12 +2345,44 @@ function FeedbackButton({ position = "bottom-right" }) {
|
|
|
2226
2345
|
const capturing = screenshotCapturing;
|
|
2227
2346
|
const showLauncherHint = showHints && !hintDismissed && !annotate && !menuOpen;
|
|
2228
2347
|
if (capabilities.actionCount === 0) return null;
|
|
2348
|
+
const restX = snapXForEdge(pos.edge);
|
|
2349
|
+
let wrapperStyle;
|
|
2350
|
+
if (dragXY !== null) {
|
|
2351
|
+
wrapperStyle = {
|
|
2352
|
+
position: "fixed",
|
|
2353
|
+
left: dragXY.x,
|
|
2354
|
+
top: dragXY.y,
|
|
2355
|
+
transition: "none",
|
|
2356
|
+
zIndex: Z.launcher
|
|
2357
|
+
};
|
|
2358
|
+
} else if (snapping) {
|
|
2359
|
+
wrapperStyle = {
|
|
2360
|
+
position: "fixed",
|
|
2361
|
+
left: restX,
|
|
2362
|
+
top: pos.y,
|
|
2363
|
+
transition: SNAP_TRANSITION,
|
|
2364
|
+
zIndex: Z.launcher
|
|
2365
|
+
};
|
|
2366
|
+
} else {
|
|
2367
|
+
wrapperStyle = {
|
|
2368
|
+
position: "fixed",
|
|
2369
|
+
left: restX,
|
|
2370
|
+
top: pos.y,
|
|
2371
|
+
transition: "none",
|
|
2372
|
+
zIndex: Z.launcher
|
|
2373
|
+
};
|
|
2374
|
+
}
|
|
2375
|
+
const hintStyle = pos.edge === "right" ? { right: BTN_SIZE + 8, top: "50%", transform: "translateY(-50%)" } : { left: BTN_SIZE + 8, top: "50%", transform: "translateY(-50%)" };
|
|
2376
|
+
const menuPositionStyle = pos.edge === "right" ? { right: 0, bottom: BTN_SIZE + 4 } : { left: 0, bottom: BTN_SIZE + 4 };
|
|
2229
2377
|
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
2230
2378
|
"div",
|
|
2231
2379
|
{
|
|
2232
2380
|
ref: menuRef,
|
|
2233
2381
|
"data-ew-feedback-interactive": "true",
|
|
2234
|
-
style: {
|
|
2382
|
+
style: { ...wrapperStyle, touchAction: "none" },
|
|
2383
|
+
onPointerDown: handlePointerDown,
|
|
2384
|
+
onPointerMove: handlePointerMove,
|
|
2385
|
+
onPointerUp: handlePointerUp,
|
|
2235
2386
|
children: [
|
|
2236
2387
|
showLauncherHint && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
2237
2388
|
"div",
|
|
@@ -2258,8 +2409,7 @@ function FeedbackButton({ position = "bottom-right" }) {
|
|
|
2258
2409
|
{
|
|
2259
2410
|
style: {
|
|
2260
2411
|
position: "absolute",
|
|
2261
|
-
|
|
2262
|
-
right: 0,
|
|
2412
|
+
...menuPositionStyle,
|
|
2263
2413
|
marginBottom: 4,
|
|
2264
2414
|
width: 176,
|
|
2265
2415
|
borderRadius: 8,
|
|
@@ -2324,7 +2474,7 @@ function FeedbackButton({ position = "bottom-right" }) {
|
|
|
2324
2474
|
children: [
|
|
2325
2475
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_lucide_react3.Camera, { style: { width: 16, height: 16, color: T.primary, flexShrink: 0 } }),
|
|
2326
2476
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { children: [
|
|
2327
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: { fontWeight: 500 }, children: capturing ? "Capturing
|
|
2477
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: { fontWeight: 500 }, children: capturing ? "Capturing..." : "Screenshot" }),
|
|
2328
2478
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: { fontSize: 10, color: T.muted }, children: "Capture current view" })
|
|
2329
2479
|
] })
|
|
2330
2480
|
]
|
|
@@ -2339,8 +2489,8 @@ function FeedbackButton({ position = "bottom-right" }) {
|
|
|
2339
2489
|
onClick: handleToggle,
|
|
2340
2490
|
style: {
|
|
2341
2491
|
display: "flex",
|
|
2342
|
-
height:
|
|
2343
|
-
width:
|
|
2492
|
+
height: BTN_SIZE,
|
|
2493
|
+
width: BTN_SIZE,
|
|
2344
2494
|
alignItems: "center",
|
|
2345
2495
|
justifyContent: "center",
|
|
2346
2496
|
borderRadius: "50%",
|
|
@@ -2349,7 +2499,7 @@ function FeedbackButton({ position = "bottom-right" }) {
|
|
|
2349
2499
|
border: annotate ? "none" : `1px solid ${T.border}`,
|
|
2350
2500
|
background: annotate ? T.primary : T.card,
|
|
2351
2501
|
color: annotate ? T.primaryFg : T.fg,
|
|
2352
|
-
cursor: "pointer",
|
|
2502
|
+
cursor: dragXY !== null ? "grabbing" : "pointer",
|
|
2353
2503
|
transform: annotate ? "scale(1.1)" : "scale(1)"
|
|
2354
2504
|
},
|
|
2355
2505
|
title: annotate ? "Exit feedback mode" : "Open feedback menu",
|