@useclickly/react 1.0.1 → 1.0.3
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/dist/index.cjs +333 -112
- package/dist/index.js +350 -129
- package/dist/internal/AnnotationPins.d.ts +0 -5
- package/dist/internal/AnnotationPins.d.ts.map +1 -1
- package/dist/internal/Toolbar.d.ts.map +1 -1
- package/dist/internal/icons.d.ts +2 -0
- package/dist/internal/icons.d.ts.map +1 -1
- package/dist/internal/styles.d.ts +1 -1
- package/dist/internal/styles.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1373,6 +1373,18 @@ function Icon({
|
|
|
1373
1373
|
}
|
|
1374
1374
|
);
|
|
1375
1375
|
}
|
|
1376
|
+
var IconFreeze = () => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Icon, { size: 15, children: [
|
|
1377
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "12", y1: "2", x2: "12", y2: "22" }),
|
|
1378
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "2", y1: "12", x2: "22", y2: "12" }),
|
|
1379
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "5", y1: "5", x2: "19", y2: "19" }),
|
|
1380
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "19", y1: "5", x2: "5", y2: "19" }),
|
|
1381
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "12", cy: "12", r: "2", fill: "currentColor", stroke: "none" })
|
|
1382
|
+
] });
|
|
1383
|
+
var IconInfo = () => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Icon, { size: 14, children: [
|
|
1384
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "12", cy: "12", r: "10" }),
|
|
1385
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "12", y1: "8", x2: "12", y2: "8", strokeWidth: "2.5" }),
|
|
1386
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "12", y1: "12", x2: "12", y2: "16" })
|
|
1387
|
+
] });
|
|
1376
1388
|
var IconCursor = () => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Icon, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M4 4l6 16 2-7 7-2z" }) });
|
|
1377
1389
|
var IconLayers = () => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Icon, { children: [
|
|
1378
1390
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M12 2l9 5-9 5-9-5 9-5z" }),
|
|
@@ -1591,7 +1603,46 @@ function AnnotationCard({
|
|
|
1591
1603
|
|
|
1592
1604
|
// packages/react/src/internal/Toolbar.tsx
|
|
1593
1605
|
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
1594
|
-
var TOOLBAR_SIZE = { width:
|
|
1606
|
+
var TOOLBAR_SIZE = { width: 360, height: 44 };
|
|
1607
|
+
var SHORTCUTS = [
|
|
1608
|
+
{ keys: ["\u2318", "\u21E7", "F"], label: "Toggle toolbar" },
|
|
1609
|
+
{ keys: ["1"], label: "Single select mode" },
|
|
1610
|
+
{ keys: ["2"], label: "Multi select mode" },
|
|
1611
|
+
{ keys: ["3"], label: "Area drag mode" },
|
|
1612
|
+
{ keys: ["\u21B5"], label: "Annotate pinned elements" },
|
|
1613
|
+
{ keys: ["Esc"], label: "Cancel / clear / close" },
|
|
1614
|
+
{ keys: ["\u2318", "\u21B5"], label: "Submit annotation" },
|
|
1615
|
+
{ keys: ["C"], label: "Copy all annotations" },
|
|
1616
|
+
{ keys: ["X"], label: "Clear all annotations" }
|
|
1617
|
+
];
|
|
1618
|
+
function ShortcutsPanel() {
|
|
1619
|
+
const [visible, setVisible] = (0, import_react7.useState)(false);
|
|
1620
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
1621
|
+
"span",
|
|
1622
|
+
{
|
|
1623
|
+
className: "clickly-tip shortcuts-trigger",
|
|
1624
|
+
onMouseEnter: () => setVisible(true),
|
|
1625
|
+
onMouseLeave: () => setVisible(false),
|
|
1626
|
+
children: [
|
|
1627
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1628
|
+
"button",
|
|
1629
|
+
{
|
|
1630
|
+
className: "clickly-btn icon-only",
|
|
1631
|
+
"aria-label": "Show keyboard shortcuts",
|
|
1632
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(IconInfo, {})
|
|
1633
|
+
}
|
|
1634
|
+
),
|
|
1635
|
+
visible && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "shortcuts-panel", role: "tooltip", children: [
|
|
1636
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "shortcuts-title", children: "Keyboard shortcuts" }),
|
|
1637
|
+
SHORTCUTS.map((s) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "shortcuts-row", children: [
|
|
1638
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "shortcuts-label", children: s.label }),
|
|
1639
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "shortcuts-keys", children: s.keys.map((k) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("kbd", { children: k }, k)) })
|
|
1640
|
+
] }, s.label))
|
|
1641
|
+
] })
|
|
1642
|
+
]
|
|
1643
|
+
}
|
|
1644
|
+
);
|
|
1645
|
+
}
|
|
1595
1646
|
function Tip({
|
|
1596
1647
|
label,
|
|
1597
1648
|
shortcut,
|
|
@@ -1612,7 +1663,38 @@ function Toolbar({ engine, onCollapse }) {
|
|
|
1612
1663
|
const outputDetail = useSettings((s) => s.outputDetail);
|
|
1613
1664
|
const [showSettings, setShowSettings] = (0, import_react7.useState)(false);
|
|
1614
1665
|
const [showList, setShowList] = (0, import_react7.useState)(false);
|
|
1666
|
+
const [frozen, setFrozen] = (0, import_react7.useState)(false);
|
|
1615
1667
|
const anchorRef = (0, import_react7.useRef)(null);
|
|
1668
|
+
(0, import_react7.useEffect)(() => {
|
|
1669
|
+
const STYLE_ID = "clickly-freeze-animations";
|
|
1670
|
+
const gsap = window.gsap;
|
|
1671
|
+
if (frozen) {
|
|
1672
|
+
if (!document.getElementById(STYLE_ID)) {
|
|
1673
|
+
const el = document.createElement("style");
|
|
1674
|
+
el.id = STYLE_ID;
|
|
1675
|
+
el.textContent = `
|
|
1676
|
+
*, *::before, *::after {
|
|
1677
|
+
animation-play-state: paused !important;
|
|
1678
|
+
transition-duration: 0ms !important;
|
|
1679
|
+
transition-delay: 0ms !important;
|
|
1680
|
+
}
|
|
1681
|
+
`;
|
|
1682
|
+
document.head.appendChild(el);
|
|
1683
|
+
}
|
|
1684
|
+
if (gsap?.globalTimeline) {
|
|
1685
|
+
gsap.globalTimeline.pause();
|
|
1686
|
+
}
|
|
1687
|
+
} else {
|
|
1688
|
+
document.getElementById(STYLE_ID)?.remove();
|
|
1689
|
+
if (gsap?.globalTimeline) {
|
|
1690
|
+
gsap.globalTimeline.resume();
|
|
1691
|
+
}
|
|
1692
|
+
}
|
|
1693
|
+
return () => {
|
|
1694
|
+
document.getElementById(STYLE_ID)?.remove();
|
|
1695
|
+
if (gsap?.globalTimeline) gsap.globalTimeline.resume();
|
|
1696
|
+
};
|
|
1697
|
+
}, [frozen]);
|
|
1616
1698
|
const { position, handleProps } = useDraggable(
|
|
1617
1699
|
{
|
|
1618
1700
|
x: Math.max(8, window.innerWidth - TOOLBAR_SIZE.width - 16),
|
|
@@ -1695,6 +1777,16 @@ function Toolbar({ engine, onCollapse }) {
|
|
|
1695
1777
|
) }),
|
|
1696
1778
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "divider" })
|
|
1697
1779
|
] }),
|
|
1780
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Tip, { label: frozen ? "Unfreeze animations" : "Freeze animations", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1781
|
+
"button",
|
|
1782
|
+
{
|
|
1783
|
+
className: `clickly-btn icon-only${frozen ? " is-freeze" : ""}`,
|
|
1784
|
+
onClick: () => setFrozen((v) => !v),
|
|
1785
|
+
"aria-label": frozen ? "Unfreeze page animations" : "Freeze page animations",
|
|
1786
|
+
"aria-pressed": frozen,
|
|
1787
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(IconFreeze, {})
|
|
1788
|
+
}
|
|
1789
|
+
) }),
|
|
1698
1790
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Tip, { label: "Annotations", shortcut: "L", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
1699
1791
|
"button",
|
|
1700
1792
|
{
|
|
@@ -1728,6 +1820,7 @@ function Toolbar({ engine, onCollapse }) {
|
|
|
1728
1820
|
}
|
|
1729
1821
|
) }),
|
|
1730
1822
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "divider" }),
|
|
1823
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ShortcutsPanel, {}),
|
|
1731
1824
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Tip, { label: "Settings", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1732
1825
|
"button",
|
|
1733
1826
|
{
|
|
@@ -2194,24 +2287,36 @@ function pinLabel(annotation) {
|
|
|
2194
2287
|
const tag = raw.split(/[.#\s]/)[0] ?? "";
|
|
2195
2288
|
return (TAG_LABELS3[tag] ?? tag) || "element";
|
|
2196
2289
|
}
|
|
2290
|
+
function parseStyles(raw) {
|
|
2291
|
+
if (!raw) return [];
|
|
2292
|
+
return raw.split(";").map((s) => s.trim()).filter(Boolean).map((s) => {
|
|
2293
|
+
const colon = s.indexOf(":");
|
|
2294
|
+
if (colon === -1) return null;
|
|
2295
|
+
return [s.slice(0, colon).trim(), s.slice(colon + 1).trim()];
|
|
2296
|
+
}).filter(Boolean);
|
|
2297
|
+
}
|
|
2197
2298
|
function Pin({ number, annotation }) {
|
|
2198
2299
|
const remove = useAnnotations((s) => s.remove);
|
|
2199
2300
|
const update = useAnnotations((s) => s.update);
|
|
2200
2301
|
const [hovered, setHovered] = (0, import_react9.useState)(false);
|
|
2201
2302
|
const [editing, setEditing] = (0, import_react9.useState)(false);
|
|
2202
2303
|
const [draft, setDraft] = (0, import_react9.useState)(annotation.comment);
|
|
2304
|
+
const [showStyles, setShowStyles] = (0, import_react9.useState)(false);
|
|
2203
2305
|
const taRef = (0, import_react9.useRef)(null);
|
|
2204
2306
|
const editRef = (0, import_react9.useRef)(null);
|
|
2205
|
-
const
|
|
2206
|
-
if (!pos) return null;
|
|
2307
|
+
const styleEntries = parseStyles(annotation.computedStyles);
|
|
2207
2308
|
const label = pinLabel(annotation);
|
|
2309
|
+
const headerLabel = annotation.isMultiSelect ? `${label} (multi-select)` : `${label}: "${annotation.elementPath}"`;
|
|
2208
2310
|
const openEdit = () => {
|
|
2209
2311
|
setDraft(annotation.comment);
|
|
2210
2312
|
setEditing(true);
|
|
2211
2313
|
setHovered(false);
|
|
2212
2314
|
requestAnimationFrame(() => taRef.current?.focus());
|
|
2213
2315
|
};
|
|
2214
|
-
const closeEdit = () =>
|
|
2316
|
+
const closeEdit = () => {
|
|
2317
|
+
setEditing(false);
|
|
2318
|
+
setShowStyles(false);
|
|
2319
|
+
};
|
|
2215
2320
|
const save = () => {
|
|
2216
2321
|
const trimmed = draft.trim();
|
|
2217
2322
|
if (trimmed) update(annotation.id, { comment: trimmed });
|
|
@@ -2230,6 +2335,27 @@ function Pin({ number, annotation }) {
|
|
|
2230
2335
|
window.addEventListener("pointerdown", onDown, true);
|
|
2231
2336
|
return () => window.removeEventListener("pointerdown", onDown, true);
|
|
2232
2337
|
}, [editing]);
|
|
2338
|
+
(0, import_react9.useEffect)(() => {
|
|
2339
|
+
if (!editing) return;
|
|
2340
|
+
let el = null;
|
|
2341
|
+
if (annotation.elementPath) {
|
|
2342
|
+
try {
|
|
2343
|
+
el = document.querySelector(annotation.elementPath);
|
|
2344
|
+
} catch {
|
|
2345
|
+
}
|
|
2346
|
+
}
|
|
2347
|
+
if (!el) return;
|
|
2348
|
+
const prevOutline = el.style.outline;
|
|
2349
|
+
const prevOffset = el.style.outlineOffset;
|
|
2350
|
+
el.style.outline = "2px solid #10b981";
|
|
2351
|
+
el.style.outlineOffset = "3px";
|
|
2352
|
+
return () => {
|
|
2353
|
+
el.style.outline = prevOutline;
|
|
2354
|
+
el.style.outlineOffset = prevOffset;
|
|
2355
|
+
};
|
|
2356
|
+
}, [editing, annotation.elementPath]);
|
|
2357
|
+
const pos = resolvePosition(annotation);
|
|
2358
|
+
if (!pos) return null;
|
|
2233
2359
|
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
2234
2360
|
"div",
|
|
2235
2361
|
{
|
|
@@ -2260,21 +2386,42 @@ function Pin({ number, annotation }) {
|
|
|
2260
2386
|
className: "pin-edit",
|
|
2261
2387
|
onClick: (e) => e.stopPropagation(),
|
|
2262
2388
|
children: [
|
|
2263
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2389
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
2390
|
+
"div",
|
|
2391
|
+
{
|
|
2392
|
+
className: "popup-header",
|
|
2393
|
+
role: "button",
|
|
2394
|
+
"aria-expanded": showStyles,
|
|
2395
|
+
onClick: (e) => {
|
|
2396
|
+
e.stopPropagation();
|
|
2397
|
+
setShowStyles((v) => !v);
|
|
2398
|
+
},
|
|
2399
|
+
children: [
|
|
2400
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "popup-chevron", children: showStyles ? "\u25BE" : "\u203A" }),
|
|
2401
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "popup-label", children: headerLabel })
|
|
2402
|
+
]
|
|
2403
|
+
}
|
|
2404
|
+
),
|
|
2405
|
+
showStyles && styleEntries.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "popup-styles", children: [
|
|
2406
|
+
styleEntries.map(([k, v]) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "style-row", children: [
|
|
2407
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "style-key", children: k }),
|
|
2408
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "style-val", children: v })
|
|
2409
|
+
] }, k)),
|
|
2410
|
+
annotation.suggestedCss && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "style-hint", style: { color: "#7c3aed", borderTopColor: "rgba(124,58,237,0.2)" }, children: [
|
|
2411
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("strong", { children: "Suggested changes:" }),
|
|
2412
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("br", {}),
|
|
2413
|
+
annotation.suggestedCss
|
|
2414
|
+
] })
|
|
2415
|
+
] }),
|
|
2268
2416
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
2269
2417
|
"textarea",
|
|
2270
2418
|
{
|
|
2271
2419
|
ref: taRef,
|
|
2272
|
-
className: "pin-edit-textarea",
|
|
2273
2420
|
value: draft,
|
|
2274
2421
|
onChange: (e) => setDraft(e.target.value),
|
|
2275
2422
|
onKeyDown,
|
|
2276
|
-
placeholder: "Describe the issue\u2026",
|
|
2277
|
-
|
|
2423
|
+
placeholder: "Describe the issue\u2026 (\u2318/Ctrl + Enter to save)",
|
|
2424
|
+
"aria-label": "Annotation comment"
|
|
2278
2425
|
}
|
|
2279
2426
|
),
|
|
2280
2427
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "pin-edit-actions", children: [
|
|
@@ -2287,9 +2434,9 @@ function Pin({ number, annotation }) {
|
|
|
2287
2434
|
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(IconTrash, {})
|
|
2288
2435
|
}
|
|
2289
2436
|
),
|
|
2290
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "
|
|
2291
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { className: "
|
|
2292
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { className: "
|
|
2437
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "row", style: { margin: 0, flex: 1, justifyContent: "flex-end" }, children: [
|
|
2438
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { className: "ghost", onClick: closeEdit, children: "Cancel" }),
|
|
2439
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { className: "primary", onClick: save, children: "Save" })
|
|
2293
2440
|
] })
|
|
2294
2441
|
] })
|
|
2295
2442
|
]
|
|
@@ -2311,10 +2458,7 @@ function resolvePosition(a) {
|
|
|
2311
2458
|
}
|
|
2312
2459
|
}
|
|
2313
2460
|
if (a.boundingBox) {
|
|
2314
|
-
return {
|
|
2315
|
-
x: a.boundingBox.x + a.boundingBox.width - 11,
|
|
2316
|
-
y: a.boundingBox.y - 11
|
|
2317
|
-
};
|
|
2461
|
+
return { x: a.boundingBox.x + a.boundingBox.width - 11, y: a.boundingBox.y - 11 };
|
|
2318
2462
|
}
|
|
2319
2463
|
return null;
|
|
2320
2464
|
}
|
|
@@ -2538,6 +2682,14 @@ var REACT_UI_CSS = `
|
|
|
2538
2682
|
.clickly-btn.is-active:hover { background: #0284c7; }
|
|
2539
2683
|
.clickly-btn[disabled] { opacity: 0.28; cursor: not-allowed; pointer-events: none; }
|
|
2540
2684
|
|
|
2685
|
+
/* Freeze-animations active state \u2014 icy blue */
|
|
2686
|
+
.clickly-btn.is-freeze {
|
|
2687
|
+
background: rgba(99, 179, 237, 0.18);
|
|
2688
|
+
color: #63b3ed;
|
|
2689
|
+
box-shadow: 0 0 0 1px rgba(99,179,237,0.35), 0 2px 8px rgba(99,179,237,0.2);
|
|
2690
|
+
}
|
|
2691
|
+
.clickly-btn.is-freeze:hover { background: rgba(99, 179, 237, 0.26); }
|
|
2692
|
+
|
|
2541
2693
|
.clickly-btn.icon-only {
|
|
2542
2694
|
width: 32px;
|
|
2543
2695
|
padding: 0;
|
|
@@ -2615,6 +2767,91 @@ var REACT_UI_CSS = `
|
|
|
2615
2767
|
color: #94a3b8;
|
|
2616
2768
|
}
|
|
2617
2769
|
|
|
2770
|
+
/* \u2500\u2500\u2500 Shortcuts panel \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
|
|
2771
|
+
|
|
2772
|
+
.shortcuts-trigger {
|
|
2773
|
+
position: relative;
|
|
2774
|
+
display: inline-flex;
|
|
2775
|
+
align-items: center;
|
|
2776
|
+
justify-content: center;
|
|
2777
|
+
}
|
|
2778
|
+
|
|
2779
|
+
.shortcuts-panel {
|
|
2780
|
+
position: absolute;
|
|
2781
|
+
bottom: calc(100% + 12px);
|
|
2782
|
+
left: 50%;
|
|
2783
|
+
transform: translateX(-50%);
|
|
2784
|
+
width: 260px;
|
|
2785
|
+
background: rgba(9, 14, 28, 0.97);
|
|
2786
|
+
border: 1px solid rgba(255,255,255,0.08);
|
|
2787
|
+
border-radius: 12px;
|
|
2788
|
+
box-shadow: 0 16px 40px rgba(0,0,0,0.45);
|
|
2789
|
+
padding: 10px;
|
|
2790
|
+
z-index: 10;
|
|
2791
|
+
animation: clickly-fade-in 100ms ease-out;
|
|
2792
|
+
pointer-events: none;
|
|
2793
|
+
}
|
|
2794
|
+
|
|
2795
|
+
/* Arrow pointing down */
|
|
2796
|
+
.shortcuts-panel::after {
|
|
2797
|
+
content: "";
|
|
2798
|
+
position: absolute;
|
|
2799
|
+
top: 100%;
|
|
2800
|
+
left: 50%;
|
|
2801
|
+
transform: translateX(-50%);
|
|
2802
|
+
border: 6px solid transparent;
|
|
2803
|
+
border-top-color: rgba(9, 14, 28, 0.97);
|
|
2804
|
+
}
|
|
2805
|
+
|
|
2806
|
+
.shortcuts-title {
|
|
2807
|
+
font: 600 11px/1 -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
|
|
2808
|
+
color: #64748b;
|
|
2809
|
+
text-transform: uppercase;
|
|
2810
|
+
letter-spacing: 0.06em;
|
|
2811
|
+
padding: 2px 4px 8px;
|
|
2812
|
+
border-bottom: 1px solid rgba(255,255,255,0.06);
|
|
2813
|
+
margin-bottom: 6px;
|
|
2814
|
+
}
|
|
2815
|
+
|
|
2816
|
+
.shortcuts-row {
|
|
2817
|
+
display: flex;
|
|
2818
|
+
align-items: center;
|
|
2819
|
+
justify-content: space-between;
|
|
2820
|
+
padding: 4px 4px;
|
|
2821
|
+
border-radius: 6px;
|
|
2822
|
+
gap: 8px;
|
|
2823
|
+
}
|
|
2824
|
+
.shortcuts-row:hover { background: rgba(255,255,255,0.04); }
|
|
2825
|
+
|
|
2826
|
+
.shortcuts-label {
|
|
2827
|
+
font: 12px/1.4 -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
|
|
2828
|
+
color: #94a3b8;
|
|
2829
|
+
flex: 1;
|
|
2830
|
+
min-width: 0;
|
|
2831
|
+
}
|
|
2832
|
+
|
|
2833
|
+
.shortcuts-keys {
|
|
2834
|
+
display: flex;
|
|
2835
|
+
gap: 3px;
|
|
2836
|
+
align-items: center;
|
|
2837
|
+
flex-shrink: 0;
|
|
2838
|
+
}
|
|
2839
|
+
|
|
2840
|
+
.shortcuts-keys kbd {
|
|
2841
|
+
display: inline-flex;
|
|
2842
|
+
align-items: center;
|
|
2843
|
+
justify-content: center;
|
|
2844
|
+
min-width: 20px;
|
|
2845
|
+
height: 20px;
|
|
2846
|
+
padding: 0 5px;
|
|
2847
|
+
background: rgba(255,255,255,0.08);
|
|
2848
|
+
border: 1px solid rgba(255,255,255,0.10);
|
|
2849
|
+
border-bottom-width: 2px;
|
|
2850
|
+
border-radius: 5px;
|
|
2851
|
+
font: 11px/1 ui-monospace, "SF Mono", Menlo, monospace;
|
|
2852
|
+
color: #e2e8f0;
|
|
2853
|
+
}
|
|
2854
|
+
|
|
2618
2855
|
/* \u2500\u2500\u2500 Popup & popovers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
|
|
2619
2856
|
|
|
2620
2857
|
.clickly-popup, .clickly-popover {
|
|
@@ -2638,8 +2875,10 @@ var REACT_UI_CSS = `
|
|
|
2638
2875
|
flex-direction: column;
|
|
2639
2876
|
}
|
|
2640
2877
|
|
|
2641
|
-
/*
|
|
2642
|
-
|
|
2878
|
+
/* \u2500\u2500\u2500 Shared inner styles \u2014 apply to both popup and pin-edit \u2500\u2500\u2500 */
|
|
2879
|
+
|
|
2880
|
+
.clickly-popup .popup-header,
|
|
2881
|
+
.pin-edit .popup-header {
|
|
2643
2882
|
display: flex;
|
|
2644
2883
|
align-items: center;
|
|
2645
2884
|
gap: 5px;
|
|
@@ -2653,9 +2892,11 @@ var REACT_UI_CSS = `
|
|
|
2653
2892
|
font-family: ui-monospace, "SF Mono", Menlo, monospace;
|
|
2654
2893
|
transition: background 80ms ease;
|
|
2655
2894
|
}
|
|
2656
|
-
.clickly-popup .popup-header:hover
|
|
2895
|
+
.clickly-popup .popup-header:hover,
|
|
2896
|
+
.pin-edit .popup-header:hover { background: #f1f5f9; }
|
|
2657
2897
|
|
|
2658
|
-
.clickly-popup .popup-chevron
|
|
2898
|
+
.clickly-popup .popup-chevron,
|
|
2899
|
+
.pin-edit .popup-chevron {
|
|
2659
2900
|
font-size: 12px;
|
|
2660
2901
|
color: #94a3b8;
|
|
2661
2902
|
flex-shrink: 0;
|
|
@@ -2663,7 +2904,8 @@ var REACT_UI_CSS = `
|
|
|
2663
2904
|
text-align: center;
|
|
2664
2905
|
}
|
|
2665
2906
|
|
|
2666
|
-
.clickly-popup .popup-label
|
|
2907
|
+
.clickly-popup .popup-label,
|
|
2908
|
+
.pin-edit .popup-label {
|
|
2667
2909
|
flex: 1;
|
|
2668
2910
|
overflow: hidden;
|
|
2669
2911
|
white-space: nowrap;
|
|
@@ -2701,7 +2943,8 @@ var REACT_UI_CSS = `
|
|
|
2701
2943
|
}
|
|
2702
2944
|
|
|
2703
2945
|
/* Computed-styles panel */
|
|
2704
|
-
.clickly-popup .popup-styles
|
|
2946
|
+
.clickly-popup .popup-styles,
|
|
2947
|
+
.pin-edit .popup-styles {
|
|
2705
2948
|
margin-bottom: 8px;
|
|
2706
2949
|
padding: 8px;
|
|
2707
2950
|
background: #f8fafc;
|
|
@@ -2714,7 +2957,8 @@ var REACT_UI_CSS = `
|
|
|
2714
2957
|
overscroll-behavior: contain;
|
|
2715
2958
|
}
|
|
2716
2959
|
|
|
2717
|
-
.clickly-popup .style-row
|
|
2960
|
+
.clickly-popup .style-row,
|
|
2961
|
+
.pin-edit .style-row {
|
|
2718
2962
|
display: flex;
|
|
2719
2963
|
align-items: center;
|
|
2720
2964
|
gap: 6px;
|
|
@@ -2724,17 +2968,27 @@ var REACT_UI_CSS = `
|
|
|
2724
2968
|
transition: background 80ms ease;
|
|
2725
2969
|
}
|
|
2726
2970
|
|
|
2727
|
-
.clickly-popup .style-row--changed
|
|
2971
|
+
.clickly-popup .style-row--changed,
|
|
2972
|
+
.pin-edit .style-row--changed {
|
|
2728
2973
|
background: rgba(245, 158, 11, 0.10);
|
|
2729
2974
|
}
|
|
2730
2975
|
|
|
2731
|
-
.clickly-popup .style-key
|
|
2976
|
+
.clickly-popup .style-key,
|
|
2977
|
+
.pin-edit .style-key {
|
|
2732
2978
|
color: #7c3aed;
|
|
2733
2979
|
flex-shrink: 0;
|
|
2734
2980
|
min-width: 90px;
|
|
2735
2981
|
font-size: 11px;
|
|
2736
2982
|
}
|
|
2737
2983
|
|
|
2984
|
+
.clickly-popup .style-val,
|
|
2985
|
+
.pin-edit .style-val {
|
|
2986
|
+
color: #0f172a;
|
|
2987
|
+
font-size: 11px;
|
|
2988
|
+
word-break: break-all;
|
|
2989
|
+
flex: 1;
|
|
2990
|
+
}
|
|
2991
|
+
|
|
2738
2992
|
/* Editable value input \u2014 live CSS preview */
|
|
2739
2993
|
.clickly-popup .style-val-input {
|
|
2740
2994
|
flex: 1;
|
|
@@ -2773,8 +3027,9 @@ var REACT_UI_CSS = `
|
|
|
2773
3027
|
background: rgba(245,158,11,0.12);
|
|
2774
3028
|
}
|
|
2775
3029
|
|
|
2776
|
-
/* Hint text at bottom of CSS panel
|
|
2777
|
-
.clickly-popup .style-hint
|
|
3030
|
+
/* Hint text at bottom of CSS panel */
|
|
3031
|
+
.clickly-popup .style-hint,
|
|
3032
|
+
.pin-edit .style-hint {
|
|
2778
3033
|
margin-top: 6px;
|
|
2779
3034
|
padding-top: 6px;
|
|
2780
3035
|
border-top: 1px solid #e2e8f0;
|
|
@@ -2784,7 +3039,8 @@ var REACT_UI_CSS = `
|
|
|
2784
3039
|
line-height: 1.4;
|
|
2785
3040
|
}
|
|
2786
3041
|
|
|
2787
|
-
.clickly-popup textarea
|
|
3042
|
+
.clickly-popup textarea,
|
|
3043
|
+
.pin-edit textarea {
|
|
2788
3044
|
width: 100%;
|
|
2789
3045
|
min-height: 64px;
|
|
2790
3046
|
max-height: 160px;
|
|
@@ -2795,33 +3051,40 @@ var REACT_UI_CSS = `
|
|
|
2795
3051
|
font: inherit;
|
|
2796
3052
|
color: inherit;
|
|
2797
3053
|
}
|
|
2798
|
-
.clickly-popup textarea:focus
|
|
3054
|
+
.clickly-popup textarea:focus,
|
|
3055
|
+
.pin-edit textarea:focus {
|
|
2799
3056
|
outline: none;
|
|
2800
3057
|
border-color: #0ea5e9;
|
|
2801
3058
|
box-shadow: 0 0 0 3px rgba(14,165,233,0.18);
|
|
2802
3059
|
}
|
|
2803
3060
|
|
|
2804
|
-
.clickly-popup .row
|
|
3061
|
+
.clickly-popup .row,
|
|
3062
|
+
.pin-edit .row {
|
|
2805
3063
|
display: flex;
|
|
2806
3064
|
justify-content: flex-end;
|
|
2807
3065
|
gap: 6px;
|
|
2808
3066
|
margin-top: 10px;
|
|
2809
3067
|
}
|
|
2810
3068
|
|
|
2811
|
-
.clickly-popup .row .ghost
|
|
3069
|
+
.clickly-popup .row .ghost,
|
|
3070
|
+
.pin-edit .row .ghost {
|
|
2812
3071
|
background: transparent;
|
|
2813
3072
|
color: #475569;
|
|
2814
3073
|
border: 1px solid #e2e8f0;
|
|
2815
3074
|
}
|
|
2816
|
-
.clickly-popup .row .ghost:hover
|
|
3075
|
+
.clickly-popup .row .ghost:hover,
|
|
3076
|
+
.pin-edit .row .ghost:hover { background: #f8fafc; }
|
|
2817
3077
|
|
|
2818
|
-
.clickly-popup .row .primary
|
|
3078
|
+
.clickly-popup .row .primary,
|
|
3079
|
+
.pin-edit .row .primary {
|
|
2819
3080
|
background: #0ea5e9;
|
|
2820
3081
|
color: #fff;
|
|
2821
3082
|
border: none;
|
|
2822
3083
|
}
|
|
2823
|
-
.clickly-popup .row .primary:hover
|
|
2824
|
-
.
|
|
3084
|
+
.clickly-popup .row .primary:hover,
|
|
3085
|
+
.pin-edit .row .primary:hover { background: #0284c7; }
|
|
3086
|
+
.clickly-popup .row button,
|
|
3087
|
+
.pin-edit .row button {
|
|
2825
3088
|
height: 28px;
|
|
2826
3089
|
padding: 0 12px;
|
|
2827
3090
|
border-radius: 6px;
|
|
@@ -3102,119 +3365,77 @@ var REACT_UI_CSS = `
|
|
|
3102
3365
|
overflow: hidden;
|
|
3103
3366
|
}
|
|
3104
3367
|
|
|
3105
|
-
/* \u2500\u2500\u2500 Pin edit popup \
|
|
3368
|
+
/* \u2500\u2500\u2500 Pin edit popup \u2014 same white card as .clickly-popup \u2500\u2500\u2500\u2500\u2500\u2500 */
|
|
3106
3369
|
|
|
3107
3370
|
.pin-edit {
|
|
3371
|
+
/* Positioning: floats to the LEFT of the pin */
|
|
3108
3372
|
position: absolute;
|
|
3109
|
-
right: calc(100% +
|
|
3373
|
+
right: calc(100% + 12px);
|
|
3110
3374
|
top: 50%;
|
|
3111
3375
|
transform: translateY(-50%);
|
|
3112
|
-
|
|
3376
|
+
/* Appearance: identical to .clickly-popup */
|
|
3377
|
+
width: 300px;
|
|
3378
|
+
padding: 12px;
|
|
3113
3379
|
background: #fff;
|
|
3114
|
-
border-radius: 12px;
|
|
3115
|
-
box-shadow: 0 12px 40px rgba(2,6,23,0.20), 0 0 0 1px rgba(15,23,42,0.07);
|
|
3116
|
-
font: 13px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
|
|
3117
3380
|
color: #0f172a;
|
|
3381
|
+
border-radius: 10px;
|
|
3382
|
+
box-shadow: 0 12px 32px rgba(2,6,23,0.18), 0 0 0 1px rgba(15,23,42,0.06);
|
|
3383
|
+
font: 13px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
|
|
3118
3384
|
text-align: left;
|
|
3119
3385
|
cursor: default;
|
|
3120
3386
|
z-index: 11;
|
|
3121
3387
|
animation: clickly-fade-in 120ms cubic-bezier(0.16,1,0.3,1);
|
|
3388
|
+
/* Allow inner popup-styles to scroll */
|
|
3389
|
+
max-height: 80vh;
|
|
3122
3390
|
overflow: hidden;
|
|
3391
|
+
display: flex;
|
|
3392
|
+
flex-direction: column;
|
|
3123
3393
|
}
|
|
3124
3394
|
|
|
3125
|
-
.pin-edit
|
|
3126
|
-
|
|
3127
|
-
border-bottom: 1px solid #f1f5f9;
|
|
3128
|
-
}
|
|
3129
|
-
|
|
3130
|
-
.pin-edit-label {
|
|
3131
|
-
font-size: 11.5px;
|
|
3132
|
-
font-weight: 600;
|
|
3133
|
-
color: #475569;
|
|
3134
|
-
}
|
|
3135
|
-
|
|
3136
|
-
.pin-edit-path {
|
|
3137
|
-
font-family: ui-monospace, "SF Mono", Menlo, monospace;
|
|
3138
|
-
font-weight: 400;
|
|
3139
|
-
color: #94a3b8;
|
|
3140
|
-
font-size: 10.5px;
|
|
3141
|
-
overflow: hidden;
|
|
3142
|
-
white-space: nowrap;
|
|
3143
|
-
text-overflow: ellipsis;
|
|
3144
|
-
display: inline-block;
|
|
3145
|
-
max-width: 160px;
|
|
3146
|
-
vertical-align: bottom;
|
|
3147
|
-
}
|
|
3148
|
-
|
|
3149
|
-
.pin-edit-textarea {
|
|
3150
|
-
display: block;
|
|
3395
|
+
/* Reuse .clickly-popup textarea inside pin-edit */
|
|
3396
|
+
.pin-edit textarea {
|
|
3151
3397
|
width: 100%;
|
|
3152
|
-
min-height:
|
|
3153
|
-
|
|
3154
|
-
|
|
3155
|
-
border
|
|
3398
|
+
min-height: 64px;
|
|
3399
|
+
max-height: 120px;
|
|
3400
|
+
padding: 8px;
|
|
3401
|
+
border: 1px solid #e2e8f0;
|
|
3402
|
+
border-radius: 6px;
|
|
3156
3403
|
resize: vertical;
|
|
3157
|
-
font:
|
|
3158
|
-
color:
|
|
3404
|
+
font: inherit;
|
|
3405
|
+
color: inherit;
|
|
3159
3406
|
background: #fff;
|
|
3160
3407
|
box-sizing: border-box;
|
|
3161
3408
|
}
|
|
3162
|
-
.pin-edit
|
|
3409
|
+
.pin-edit textarea:focus {
|
|
3163
3410
|
outline: none;
|
|
3164
|
-
|
|
3411
|
+
border-color: #0ea5e9;
|
|
3412
|
+
box-shadow: 0 0 0 3px rgba(14,165,233,0.18);
|
|
3165
3413
|
}
|
|
3166
3414
|
|
|
3415
|
+
/* Actions row */
|
|
3167
3416
|
.pin-edit-actions {
|
|
3168
3417
|
display: flex;
|
|
3169
3418
|
align-items: center;
|
|
3170
|
-
justify-content: space-between;
|
|
3171
|
-
padding: 8px 10px;
|
|
3172
|
-
gap: 6px;
|
|
3173
|
-
}
|
|
3174
|
-
|
|
3175
|
-
.pin-edit-right {
|
|
3176
|
-
display: flex;
|
|
3177
3419
|
gap: 6px;
|
|
3420
|
+
margin-top: 10px;
|
|
3178
3421
|
}
|
|
3179
3422
|
|
|
3180
3423
|
.pin-edit-delete {
|
|
3181
3424
|
display: grid;
|
|
3182
3425
|
place-items: center;
|
|
3183
|
-
width:
|
|
3184
|
-
height:
|
|
3426
|
+
width: 28px;
|
|
3427
|
+
height: 28px;
|
|
3428
|
+
flex-shrink: 0;
|
|
3185
3429
|
background: transparent;
|
|
3186
3430
|
border: 1px solid #fee2e2;
|
|
3187
|
-
border-radius:
|
|
3431
|
+
border-radius: 6px;
|
|
3188
3432
|
color: #ef4444;
|
|
3189
3433
|
cursor: pointer;
|
|
3190
3434
|
padding: 0;
|
|
3191
3435
|
transition: background 100ms, border-color 100ms;
|
|
3192
3436
|
}
|
|
3193
3437
|
.pin-edit-delete:hover { background: #fef2f2; border-color: #fca5a5; }
|
|
3194
|
-
.pin-edit-delete svg { width:
|
|
3195
|
-
|
|
3196
|
-
.pin-edit-cancel, .pin-edit-save {
|
|
3197
|
-
height: 30px;
|
|
3198
|
-
padding: 0 12px;
|
|
3199
|
-
border-radius: 8px;
|
|
3200
|
-
font: 12px/1 inherit;
|
|
3201
|
-
font-weight: 500;
|
|
3202
|
-
cursor: pointer;
|
|
3203
|
-
border: none;
|
|
3204
|
-
transition: background 100ms;
|
|
3205
|
-
}
|
|
3206
|
-
|
|
3207
|
-
.pin-edit-cancel {
|
|
3208
|
-
background: #f1f5f9;
|
|
3209
|
-
color: #475569;
|
|
3210
|
-
}
|
|
3211
|
-
.pin-edit-cancel:hover { background: #e2e8f0; }
|
|
3212
|
-
|
|
3213
|
-
.pin-edit-save {
|
|
3214
|
-
background: #10b981;
|
|
3215
|
-
color: #fff;
|
|
3216
|
-
}
|
|
3217
|
-
.pin-edit-save:hover { background: #059669; }
|
|
3438
|
+
.pin-edit-delete svg { width: 13px; height: 13px; }
|
|
3218
3439
|
|
|
3219
3440
|
/* \u2500\u2500\u2500 Annotation list \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
|
|
3220
3441
|
|