@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/dist/index.js
CHANGED
|
@@ -2096,7 +2096,7 @@ function ScreenshotFeedback() {
|
|
|
2096
2096
|
}
|
|
2097
2097
|
|
|
2098
2098
|
// src/FeedbackButton.tsx
|
|
2099
|
-
import { useRef as useRef5, useEffect as useEffect6, useState as useState7 } from "react";
|
|
2099
|
+
import { useRef as useRef5, useEffect as useEffect6, useState as useState7, useCallback as useCallback8 } from "react";
|
|
2100
2100
|
import { MessageSquarePlus, MapPin, Camera as Camera2 } from "lucide-react";
|
|
2101
2101
|
|
|
2102
2102
|
// src/launcher.ts
|
|
@@ -2118,10 +2118,52 @@ function getLauncherCapabilities({
|
|
|
2118
2118
|
|
|
2119
2119
|
// src/FeedbackButton.tsx
|
|
2120
2120
|
import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
2121
|
+
var LAUNCHER_POS_KEY = "issue-pin:launcher-pos";
|
|
2122
|
+
var DRAG_THRESHOLD = 5;
|
|
2123
|
+
var EDGE_MARGIN = 20;
|
|
2124
|
+
var BTN_SIZE = 48;
|
|
2125
|
+
var SNAP_EASING = "cubic-bezier(0.2, 0, 0, 1)";
|
|
2126
|
+
var SNAP_TRANSITION = `left 0.3s ${SNAP_EASING}, top 0.3s ${SNAP_EASING}`;
|
|
2127
|
+
function loadPos(initialEdge) {
|
|
2128
|
+
try {
|
|
2129
|
+
const raw = localStorage.getItem(LAUNCHER_POS_KEY);
|
|
2130
|
+
if (raw) {
|
|
2131
|
+
const parsed = JSON.parse(raw);
|
|
2132
|
+
if ((parsed.edge === "left" || parsed.edge === "right") && typeof parsed.y === "number") {
|
|
2133
|
+
return { edge: parsed.edge, y: parsed.y };
|
|
2134
|
+
}
|
|
2135
|
+
}
|
|
2136
|
+
} catch {
|
|
2137
|
+
}
|
|
2138
|
+
return {
|
|
2139
|
+
edge: initialEdge === "bottom-left" ? "left" : "right",
|
|
2140
|
+
y: window.innerHeight - BTN_SIZE - EDGE_MARGIN
|
|
2141
|
+
};
|
|
2142
|
+
}
|
|
2143
|
+
function savePos(pos) {
|
|
2144
|
+
try {
|
|
2145
|
+
localStorage.setItem(LAUNCHER_POS_KEY, JSON.stringify(pos));
|
|
2146
|
+
} catch {
|
|
2147
|
+
}
|
|
2148
|
+
}
|
|
2149
|
+
function clampY(y) {
|
|
2150
|
+
return Math.min(
|
|
2151
|
+
Math.max(y, EDGE_MARGIN),
|
|
2152
|
+
window.innerHeight - BTN_SIZE - EDGE_MARGIN
|
|
2153
|
+
);
|
|
2154
|
+
}
|
|
2155
|
+
function snapXForEdge(edge) {
|
|
2156
|
+
return edge === "left" ? EDGE_MARGIN : window.innerWidth - BTN_SIZE - EDGE_MARGIN;
|
|
2157
|
+
}
|
|
2121
2158
|
function FeedbackButton({ position = "bottom-right" }) {
|
|
2122
2159
|
const ctx = useFeedbackSafe();
|
|
2123
2160
|
const menuRef = useRef5(null);
|
|
2124
2161
|
const [hintDismissed, setHintDismissed] = useState7(false);
|
|
2162
|
+
const [pos, setPos] = useState7(() => loadPos(position));
|
|
2163
|
+
const [dragXY, setDragXY] = useState7(null);
|
|
2164
|
+
const [snapping, setSnapping] = useState7(false);
|
|
2165
|
+
const dragStateRef = useRef5(null);
|
|
2166
|
+
const snapTimerRef = useRef5(null);
|
|
2125
2167
|
const menuOpenState = ctx?.menuOpen ?? false;
|
|
2126
2168
|
const debug = ctx?.debug ?? false;
|
|
2127
2169
|
useEffect6(() => {
|
|
@@ -2139,6 +2181,79 @@ function FeedbackButton({ position = "bottom-right" }) {
|
|
|
2139
2181
|
console.log("[EW SDK] FeedbackButton mounted");
|
|
2140
2182
|
return () => console.log("[EW SDK] FeedbackButton unmounted");
|
|
2141
2183
|
}, [debug]);
|
|
2184
|
+
useEffect6(() => {
|
|
2185
|
+
const handleResize = () => {
|
|
2186
|
+
setPos((prev) => {
|
|
2187
|
+
const newPos = {
|
|
2188
|
+
edge: prev.edge,
|
|
2189
|
+
y: clampY(prev.y)
|
|
2190
|
+
};
|
|
2191
|
+
savePos(newPos);
|
|
2192
|
+
return newPos;
|
|
2193
|
+
});
|
|
2194
|
+
};
|
|
2195
|
+
window.addEventListener("resize", handleResize);
|
|
2196
|
+
return () => window.removeEventListener("resize", handleResize);
|
|
2197
|
+
}, []);
|
|
2198
|
+
useEffect6(() => {
|
|
2199
|
+
return () => {
|
|
2200
|
+
if (snapTimerRef.current) clearTimeout(snapTimerRef.current);
|
|
2201
|
+
};
|
|
2202
|
+
}, []);
|
|
2203
|
+
const handlePointerDown = useCallback8((e) => {
|
|
2204
|
+
if (e.button != null && e.button !== 0) return;
|
|
2205
|
+
e.currentTarget.setPointerCapture(e.pointerId);
|
|
2206
|
+
dragStateRef.current = {
|
|
2207
|
+
active: false,
|
|
2208
|
+
startX: e.clientX,
|
|
2209
|
+
startY: e.clientY,
|
|
2210
|
+
currentX: e.clientX,
|
|
2211
|
+
currentY: e.clientY,
|
|
2212
|
+
didDrag: false
|
|
2213
|
+
};
|
|
2214
|
+
}, []);
|
|
2215
|
+
const handlePointerMove = useCallback8((e) => {
|
|
2216
|
+
const ds = dragStateRef.current;
|
|
2217
|
+
if (!ds) return;
|
|
2218
|
+
const dx = e.clientX - ds.startX;
|
|
2219
|
+
const dy = e.clientY - ds.startY;
|
|
2220
|
+
const distance = Math.sqrt(dx * dx + dy * dy);
|
|
2221
|
+
if (!ds.active && distance >= DRAG_THRESHOLD) {
|
|
2222
|
+
ds.active = true;
|
|
2223
|
+
ds.didDrag = true;
|
|
2224
|
+
}
|
|
2225
|
+
if (ds.active) {
|
|
2226
|
+
ds.currentX = e.clientX;
|
|
2227
|
+
ds.currentY = e.clientY;
|
|
2228
|
+
const x = e.clientX - BTN_SIZE / 2;
|
|
2229
|
+
const y = clampY(e.clientY - BTN_SIZE / 2);
|
|
2230
|
+
setDragXY({ x, y });
|
|
2231
|
+
}
|
|
2232
|
+
}, []);
|
|
2233
|
+
const handlePointerUp = useCallback8((e) => {
|
|
2234
|
+
try {
|
|
2235
|
+
e.currentTarget.releasePointerCapture(e.pointerId);
|
|
2236
|
+
} catch {
|
|
2237
|
+
}
|
|
2238
|
+
const ds = dragStateRef.current;
|
|
2239
|
+
if (!ds || !ds.didDrag) {
|
|
2240
|
+
dragStateRef.current = null;
|
|
2241
|
+
return;
|
|
2242
|
+
}
|
|
2243
|
+
const centerX = ds.currentX;
|
|
2244
|
+
const edge = centerX < window.innerWidth / 2 ? "left" : "right";
|
|
2245
|
+
const y = clampY(ds.currentY - BTN_SIZE / 2);
|
|
2246
|
+
const newPos = { edge, y };
|
|
2247
|
+
setSnapping(true);
|
|
2248
|
+
setPos(newPos);
|
|
2249
|
+
savePos(newPos);
|
|
2250
|
+
setDragXY(null);
|
|
2251
|
+
if (snapTimerRef.current) clearTimeout(snapTimerRef.current);
|
|
2252
|
+
snapTimerRef.current = setTimeout(() => {
|
|
2253
|
+
setSnapping(false);
|
|
2254
|
+
snapTimerRef.current = null;
|
|
2255
|
+
}, 300);
|
|
2256
|
+
}, []);
|
|
2142
2257
|
if (!ctx) return null;
|
|
2143
2258
|
const {
|
|
2144
2259
|
mode,
|
|
@@ -2154,9 +2269,13 @@ function FeedbackButton({ position = "bottom-right" }) {
|
|
|
2154
2269
|
} = ctx;
|
|
2155
2270
|
const annotate = mode === "annotate";
|
|
2156
2271
|
const capabilities = getLauncherCapabilities({ allowPinOnPage: canPinOnPage, allowScreenshot: canScreenshot });
|
|
2157
|
-
const posStyle = position === "bottom-left" ? { left: 20, bottom: 20 } : { right: 20, bottom: 20 };
|
|
2158
|
-
const hintStyle = position === "bottom-left" ? { left: 56, bottom: 8 } : { right: 56, bottom: 8 };
|
|
2159
2272
|
const handleToggle = () => {
|
|
2273
|
+
if (dragStateRef.current?.didDrag) {
|
|
2274
|
+
dragStateRef.current.didDrag = false;
|
|
2275
|
+
dragStateRef.current = null;
|
|
2276
|
+
return;
|
|
2277
|
+
}
|
|
2278
|
+
dragStateRef.current = null;
|
|
2160
2279
|
if (debug) console.log("[EW SDK] handleToggle", { mode, menuOpen });
|
|
2161
2280
|
setHintDismissed(true);
|
|
2162
2281
|
if (annotate) {
|
|
@@ -2176,12 +2295,44 @@ function FeedbackButton({ position = "bottom-right" }) {
|
|
|
2176
2295
|
const capturing = screenshotCapturing;
|
|
2177
2296
|
const showLauncherHint = showHints && !hintDismissed && !annotate && !menuOpen;
|
|
2178
2297
|
if (capabilities.actionCount === 0) return null;
|
|
2298
|
+
const restX = snapXForEdge(pos.edge);
|
|
2299
|
+
let wrapperStyle;
|
|
2300
|
+
if (dragXY !== null) {
|
|
2301
|
+
wrapperStyle = {
|
|
2302
|
+
position: "fixed",
|
|
2303
|
+
left: dragXY.x,
|
|
2304
|
+
top: dragXY.y,
|
|
2305
|
+
transition: "none",
|
|
2306
|
+
zIndex: Z.launcher
|
|
2307
|
+
};
|
|
2308
|
+
} else if (snapping) {
|
|
2309
|
+
wrapperStyle = {
|
|
2310
|
+
position: "fixed",
|
|
2311
|
+
left: restX,
|
|
2312
|
+
top: pos.y,
|
|
2313
|
+
transition: SNAP_TRANSITION,
|
|
2314
|
+
zIndex: Z.launcher
|
|
2315
|
+
};
|
|
2316
|
+
} else {
|
|
2317
|
+
wrapperStyle = {
|
|
2318
|
+
position: "fixed",
|
|
2319
|
+
left: restX,
|
|
2320
|
+
top: pos.y,
|
|
2321
|
+
transition: "none",
|
|
2322
|
+
zIndex: Z.launcher
|
|
2323
|
+
};
|
|
2324
|
+
}
|
|
2325
|
+
const hintStyle = pos.edge === "right" ? { right: BTN_SIZE + 8, top: "50%", transform: "translateY(-50%)" } : { left: BTN_SIZE + 8, top: "50%", transform: "translateY(-50%)" };
|
|
2326
|
+
const menuPositionStyle = pos.edge === "right" ? { right: 0, bottom: BTN_SIZE + 4 } : { left: 0, bottom: BTN_SIZE + 4 };
|
|
2179
2327
|
return /* @__PURE__ */ jsxs6(
|
|
2180
2328
|
"div",
|
|
2181
2329
|
{
|
|
2182
2330
|
ref: menuRef,
|
|
2183
2331
|
"data-ew-feedback-interactive": "true",
|
|
2184
|
-
style: {
|
|
2332
|
+
style: { ...wrapperStyle, touchAction: "none" },
|
|
2333
|
+
onPointerDown: handlePointerDown,
|
|
2334
|
+
onPointerMove: handlePointerMove,
|
|
2335
|
+
onPointerUp: handlePointerUp,
|
|
2185
2336
|
children: [
|
|
2186
2337
|
showLauncherHint && /* @__PURE__ */ jsxs6(
|
|
2187
2338
|
"div",
|
|
@@ -2208,8 +2359,7 @@ function FeedbackButton({ position = "bottom-right" }) {
|
|
|
2208
2359
|
{
|
|
2209
2360
|
style: {
|
|
2210
2361
|
position: "absolute",
|
|
2211
|
-
|
|
2212
|
-
right: 0,
|
|
2362
|
+
...menuPositionStyle,
|
|
2213
2363
|
marginBottom: 4,
|
|
2214
2364
|
width: 176,
|
|
2215
2365
|
borderRadius: 8,
|
|
@@ -2274,7 +2424,7 @@ function FeedbackButton({ position = "bottom-right" }) {
|
|
|
2274
2424
|
children: [
|
|
2275
2425
|
/* @__PURE__ */ jsx7(Camera2, { style: { width: 16, height: 16, color: T.primary, flexShrink: 0 } }),
|
|
2276
2426
|
/* @__PURE__ */ jsxs6("div", { children: [
|
|
2277
|
-
/* @__PURE__ */ jsx7("div", { style: { fontWeight: 500 }, children: capturing ? "Capturing
|
|
2427
|
+
/* @__PURE__ */ jsx7("div", { style: { fontWeight: 500 }, children: capturing ? "Capturing..." : "Screenshot" }),
|
|
2278
2428
|
/* @__PURE__ */ jsx7("div", { style: { fontSize: 10, color: T.muted }, children: "Capture current view" })
|
|
2279
2429
|
] })
|
|
2280
2430
|
]
|
|
@@ -2289,8 +2439,8 @@ function FeedbackButton({ position = "bottom-right" }) {
|
|
|
2289
2439
|
onClick: handleToggle,
|
|
2290
2440
|
style: {
|
|
2291
2441
|
display: "flex",
|
|
2292
|
-
height:
|
|
2293
|
-
width:
|
|
2442
|
+
height: BTN_SIZE,
|
|
2443
|
+
width: BTN_SIZE,
|
|
2294
2444
|
alignItems: "center",
|
|
2295
2445
|
justifyContent: "center",
|
|
2296
2446
|
borderRadius: "50%",
|
|
@@ -2299,7 +2449,7 @@ function FeedbackButton({ position = "bottom-right" }) {
|
|
|
2299
2449
|
border: annotate ? "none" : `1px solid ${T.border}`,
|
|
2300
2450
|
background: annotate ? T.primary : T.card,
|
|
2301
2451
|
color: annotate ? T.primaryFg : T.fg,
|
|
2302
|
-
cursor: "pointer",
|
|
2452
|
+
cursor: dragXY !== null ? "grabbing" : "pointer",
|
|
2303
2453
|
transform: annotate ? "scale(1.1)" : "scale(1)"
|
|
2304
2454
|
},
|
|
2305
2455
|
title: annotate ? "Exit feedback mode" : "Open feedback menu",
|
|
@@ -2313,7 +2463,7 @@ function FeedbackButton({ position = "bottom-right" }) {
|
|
|
2313
2463
|
}
|
|
2314
2464
|
|
|
2315
2465
|
// src/ModalFeedbackInjector.tsx
|
|
2316
|
-
import { useState as useState8, useEffect as useEffect7, useCallback as
|
|
2466
|
+
import { useState as useState8, useEffect as useEffect7, useCallback as useCallback9 } from "react";
|
|
2317
2467
|
import { createPortal as createPortal3 } from "react-dom";
|
|
2318
2468
|
import { Camera as Camera3 } from "lucide-react";
|
|
2319
2469
|
import { Fragment as Fragment4, jsx as jsx8 } from "react/jsx-runtime";
|
|
@@ -2332,7 +2482,7 @@ function ModalFeedbackInjector({
|
|
|
2332
2482
|
observer.observe(document.body, { childList: true, subtree: true });
|
|
2333
2483
|
return () => observer.disconnect();
|
|
2334
2484
|
}, []);
|
|
2335
|
-
const handleCapture =
|
|
2485
|
+
const handleCapture = useCallback9(async () => {
|
|
2336
2486
|
if (!ctx) return;
|
|
2337
2487
|
await ctx.startScreenshotCapture();
|
|
2338
2488
|
}, [ctx]);
|