@merittdev/horus-lens 0.4.0 → 0.5.0
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/browser.cjs +440 -185
- package/dist/browser.cjs.map +1 -1
- package/dist/browser.d.cts +1 -1
- package/dist/browser.d.ts +1 -1
- package/dist/browser.js +2 -2
- package/dist/{chunk-B7QI3T3E.js → chunk-2G5FEWPU.js} +76 -16
- package/dist/{chunk-B7QI3T3E.js.map → chunk-2G5FEWPU.js.map} +1 -1
- package/dist/{chunk-GQREYSHC.js → chunk-M3QMIY4Y.js} +367 -172
- package/dist/chunk-M3QMIY4Y.js.map +1 -0
- package/dist/cli.cjs +25 -6
- package/dist/cli.cjs.map +1 -1
- package/dist/index.cjs +75 -15
- package/dist/index.cjs.map +1 -1
- package/dist/{index.d-Dyzc1E9T.d.ts → index.d-BYuZWEkh.d.ts} +7 -0
- package/dist/{index.d-BYG_Mjs-.d.cts → index.d-DeJ1mfh0.d.cts} +7 -0
- package/dist/index.d.cts +7 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +1 -1
- package/dist/lens.min.js +204 -130
- package/dist/react.cjs +440 -185
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +1 -1
- package/dist/react.d.ts +1 -1
- package/dist/react.js +2 -2
- package/package.json +3 -2
- package/dist/chunk-GQREYSHC.js.map +0 -1
- package/dist/lens.min.js.map +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
LENS_OVERLAY_HOST_ID,
|
|
3
3
|
LensClient
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-2G5FEWPU.js";
|
|
5
5
|
|
|
6
6
|
// ../browser/dist/index.js
|
|
7
7
|
var DEFAULT_PARAM_NAME = "lens";
|
|
@@ -124,6 +124,113 @@ function el(tag, props = {}, children = []) {
|
|
|
124
124
|
function clear(node) {
|
|
125
125
|
while (node.firstChild) node.removeChild(node.firstChild);
|
|
126
126
|
}
|
|
127
|
+
var MARGIN = 6;
|
|
128
|
+
var DRAG_THRESHOLD = 3;
|
|
129
|
+
var savedPositions = /* @__PURE__ */ new Map();
|
|
130
|
+
function isInteractiveTarget(target) {
|
|
131
|
+
return target instanceof Element && target.closest(
|
|
132
|
+
'button, a, input, textarea, select, [role="switch"], [role="button"], [contenteditable="true"]'
|
|
133
|
+
) !== null;
|
|
134
|
+
}
|
|
135
|
+
function clampToViewport(element, left, top) {
|
|
136
|
+
const rect = element.getBoundingClientRect();
|
|
137
|
+
const vw = window.innerWidth;
|
|
138
|
+
const vh = window.innerHeight;
|
|
139
|
+
const maxLeft = Math.max(MARGIN, vw - rect.width - MARGIN);
|
|
140
|
+
const maxTop = Math.max(MARGIN, vh - rect.height - MARGIN);
|
|
141
|
+
return {
|
|
142
|
+
left: Math.min(Math.max(left, MARGIN), maxLeft),
|
|
143
|
+
top: Math.min(Math.max(top, MARGIN), maxTop)
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
function makeDraggable(element, opts) {
|
|
147
|
+
const { handle, key } = opts;
|
|
148
|
+
const ignore = opts.ignore ?? isInteractiveTarget;
|
|
149
|
+
let startX = 0;
|
|
150
|
+
let startY = 0;
|
|
151
|
+
let originLeft = 0;
|
|
152
|
+
let originTop = 0;
|
|
153
|
+
let dragging = false;
|
|
154
|
+
let armed = false;
|
|
155
|
+
let pointerId = null;
|
|
156
|
+
const apply = (left, top) => {
|
|
157
|
+
const p = clampToViewport(element, left, top);
|
|
158
|
+
element.style.left = `${p.left}px`;
|
|
159
|
+
element.style.top = `${p.top}px`;
|
|
160
|
+
element.style.right = "auto";
|
|
161
|
+
element.style.bottom = "auto";
|
|
162
|
+
element.style.transform = "none";
|
|
163
|
+
savedPositions.set(key, p);
|
|
164
|
+
opts.onMove?.();
|
|
165
|
+
};
|
|
166
|
+
const onPointerDown = (e) => {
|
|
167
|
+
if (e.button !== 0 && e.pointerType === "mouse") return;
|
|
168
|
+
if (ignore(e.target)) return;
|
|
169
|
+
armed = true;
|
|
170
|
+
dragging = false;
|
|
171
|
+
pointerId = e.pointerId;
|
|
172
|
+
startX = e.clientX;
|
|
173
|
+
startY = e.clientY;
|
|
174
|
+
const rect = element.getBoundingClientRect();
|
|
175
|
+
originLeft = rect.left;
|
|
176
|
+
originTop = rect.top;
|
|
177
|
+
window.addEventListener("pointermove", onPointerMove, true);
|
|
178
|
+
window.addEventListener("pointerup", onPointerUp, true);
|
|
179
|
+
window.addEventListener("pointercancel", onPointerUp, true);
|
|
180
|
+
};
|
|
181
|
+
const onPointerMove = (e) => {
|
|
182
|
+
if (!armed || e.pointerId !== pointerId) return;
|
|
183
|
+
const dx = e.clientX - startX;
|
|
184
|
+
const dy = e.clientY - startY;
|
|
185
|
+
if (!dragging) {
|
|
186
|
+
if (Math.abs(dx) + Math.abs(dy) < DRAG_THRESHOLD) return;
|
|
187
|
+
dragging = true;
|
|
188
|
+
element.classList.add("is-dragging");
|
|
189
|
+
}
|
|
190
|
+
e.preventDefault();
|
|
191
|
+
apply(originLeft + dx, originTop + dy);
|
|
192
|
+
};
|
|
193
|
+
const onPointerUp = (e) => {
|
|
194
|
+
if (e.pointerId !== pointerId) return;
|
|
195
|
+
armed = false;
|
|
196
|
+
if (dragging) {
|
|
197
|
+
dragging = false;
|
|
198
|
+
element.classList.remove("is-dragging");
|
|
199
|
+
}
|
|
200
|
+
pointerId = null;
|
|
201
|
+
window.removeEventListener("pointermove", onPointerMove, true);
|
|
202
|
+
window.removeEventListener("pointerup", onPointerUp, true);
|
|
203
|
+
window.removeEventListener("pointercancel", onPointerUp, true);
|
|
204
|
+
};
|
|
205
|
+
const onResize = () => {
|
|
206
|
+
const p = savedPositions.get(key);
|
|
207
|
+
if (p) apply(p.left, p.top);
|
|
208
|
+
};
|
|
209
|
+
handle.classList.add("lens-drag-handle");
|
|
210
|
+
handle.addEventListener("pointerdown", onPointerDown);
|
|
211
|
+
window.addEventListener("resize", onResize);
|
|
212
|
+
const stored = savedPositions.get(key);
|
|
213
|
+
if (stored) requestAnimationFrame(() => apply(stored.left, stored.top));
|
|
214
|
+
return {
|
|
215
|
+
reclamp: onResize,
|
|
216
|
+
reset() {
|
|
217
|
+
savedPositions.delete(key);
|
|
218
|
+
element.style.left = "";
|
|
219
|
+
element.style.top = "";
|
|
220
|
+
element.style.right = "";
|
|
221
|
+
element.style.bottom = "";
|
|
222
|
+
element.style.transform = "";
|
|
223
|
+
element.classList.remove("is-dragging");
|
|
224
|
+
},
|
|
225
|
+
destroy() {
|
|
226
|
+
handle.removeEventListener("pointerdown", onPointerDown);
|
|
227
|
+
window.removeEventListener("pointermove", onPointerMove, true);
|
|
228
|
+
window.removeEventListener("pointerup", onPointerUp, true);
|
|
229
|
+
window.removeEventListener("pointercancel", onPointerUp, true);
|
|
230
|
+
window.removeEventListener("resize", onResize);
|
|
231
|
+
}
|
|
232
|
+
};
|
|
233
|
+
}
|
|
127
234
|
var THIN_MIN_DIST = 3;
|
|
128
235
|
var MAX_POINTS = 2e3;
|
|
129
236
|
var HIGHLIGHTER_WIDTH = 14;
|
|
@@ -274,6 +381,8 @@ var iconTrash = svg(
|
|
|
274
381
|
'<polyline points="3 6 5 6 21 6"/><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/>'
|
|
275
382
|
);
|
|
276
383
|
var iconAnnotate = iconPencil;
|
|
384
|
+
var iconGrip = `<svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><circle cx="9" cy="6" r="1.6"/><circle cx="15" cy="6" r="1.6"/><circle cx="9" cy="12" r="1.6"/><circle cx="15" cy="12" r="1.6"/><circle cx="9" cy="18" r="1.6"/><circle cx="15" cy="18" r="1.6"/></svg>`;
|
|
385
|
+
var iconReport = svg('<path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2Z"/>');
|
|
277
386
|
var SVG_NS = "http://www.w3.org/2000/svg";
|
|
278
387
|
var FONT = "-apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif";
|
|
279
388
|
var MIN_DRAG = 6;
|
|
@@ -302,6 +411,7 @@ var AnnotationEditor = class {
|
|
|
302
411
|
svg = null;
|
|
303
412
|
bg = null;
|
|
304
413
|
toolbar = null;
|
|
414
|
+
toolbarDrag = null;
|
|
305
415
|
textInputEl = null;
|
|
306
416
|
textAnchor = null;
|
|
307
417
|
textColor = COLORS[0];
|
|
@@ -347,6 +457,7 @@ var AnnotationEditor = class {
|
|
|
347
457
|
this.markNodes = [];
|
|
348
458
|
this.annotations = [];
|
|
349
459
|
this.stepCounter = 0;
|
|
460
|
+
this.sessionBase = Math.min(this.sessionBase, this.annotations.length);
|
|
350
461
|
if (!this.active) this.teardownLayer();
|
|
351
462
|
this.syncActionButtons();
|
|
352
463
|
}
|
|
@@ -361,6 +472,7 @@ var AnnotationEditor = class {
|
|
|
361
472
|
this.sizeLayer();
|
|
362
473
|
this.updateTransform();
|
|
363
474
|
svg2.style.pointerEvents = "auto";
|
|
475
|
+
if (this.bg) this.bg.style.pointerEvents = "all";
|
|
364
476
|
svg2.style.touchAction = "none";
|
|
365
477
|
svg2.style.cursor = "crosshair";
|
|
366
478
|
svg2.addEventListener("pointerdown", this.onPointerDown);
|
|
@@ -381,6 +493,7 @@ var AnnotationEditor = class {
|
|
|
381
493
|
if (svg2) {
|
|
382
494
|
svg2.removeEventListener("pointerdown", this.onPointerDown);
|
|
383
495
|
svg2.style.pointerEvents = "none";
|
|
496
|
+
if (this.bg) this.bg.style.pointerEvents = "none";
|
|
384
497
|
svg2.style.touchAction = "";
|
|
385
498
|
svg2.style.cursor = "";
|
|
386
499
|
}
|
|
@@ -390,15 +503,8 @@ var AnnotationEditor = class {
|
|
|
390
503
|
this.onExit = null;
|
|
391
504
|
cb?.();
|
|
392
505
|
}
|
|
393
|
-
/** Cancel — discard marks drawn during this session, then exit. */
|
|
394
|
-
cancel() {
|
|
395
|
-
this.cancelTextInput();
|
|
396
|
-
const removed = this.markNodes.splice(this.sessionBase);
|
|
397
|
-
for (const node of removed) node.remove();
|
|
398
|
-
this.annotations.splice(this.sessionBase);
|
|
399
|
-
this.exit();
|
|
400
|
-
}
|
|
401
506
|
undo() {
|
|
507
|
+
if (this.markNodes.length <= this.sessionBase) return;
|
|
402
508
|
const node = this.markNodes.pop();
|
|
403
509
|
if (!node) return;
|
|
404
510
|
node.remove();
|
|
@@ -614,39 +720,45 @@ var AnnotationEditor = class {
|
|
|
614
720
|
on: { click: () => this.clear() }
|
|
615
721
|
});
|
|
616
722
|
const editGroup = el("div", { class: "lens-tool-group" }, [this.undoBtn, this.clearBtn]);
|
|
617
|
-
const
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
}
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
723
|
+
const closeBtn = el("button", {
|
|
724
|
+
class: "lens-tool-close",
|
|
725
|
+
ariaLabel: "Done",
|
|
726
|
+
title: "Done",
|
|
727
|
+
html: iconClose,
|
|
728
|
+
attrs: { type: "button" },
|
|
729
|
+
on: { click: () => this.exit() }
|
|
730
|
+
});
|
|
731
|
+
const grip = el("span", {
|
|
732
|
+
class: "lens-tool-grip",
|
|
733
|
+
html: iconGrip,
|
|
734
|
+
title: "Drag to move toolbar",
|
|
735
|
+
ariaLabel: "Drag to move toolbar"
|
|
736
|
+
});
|
|
737
|
+
const track = el("div", { class: "lens-tool-track" }, [
|
|
738
|
+
toolGroup,
|
|
739
|
+
el("span", { class: "lens-tool-sep" }),
|
|
740
|
+
colorGroup,
|
|
741
|
+
el("span", { class: "lens-tool-sep" }),
|
|
742
|
+
widthGroup,
|
|
743
|
+
el("span", { class: "lens-tool-sep" }),
|
|
744
|
+
editGroup
|
|
630
745
|
]);
|
|
631
746
|
this.toolbar = el(
|
|
632
747
|
"div",
|
|
633
748
|
{ class: "lens-annotate-toolbar", attrs: { role: "toolbar", "aria-label": "Annotation tools" } },
|
|
634
|
-
[
|
|
635
|
-
toolGroup,
|
|
636
|
-
el("span", { class: "lens-tool-sep" }),
|
|
637
|
-
colorGroup,
|
|
638
|
-
el("span", { class: "lens-tool-sep" }),
|
|
639
|
-
widthGroup,
|
|
640
|
-
el("span", { class: "lens-tool-sep" }),
|
|
641
|
-
editGroup,
|
|
642
|
-
el("span", { class: "lens-tool-sep" }),
|
|
643
|
-
doneGroup
|
|
644
|
-
]
|
|
749
|
+
[grip, track, closeBtn]
|
|
645
750
|
);
|
|
646
751
|
this.host.append(this.toolbar);
|
|
752
|
+
this.toolbarDrag = makeDraggable(this.toolbar, {
|
|
753
|
+
handle: grip,
|
|
754
|
+
key: "lens-annotate-toolbar",
|
|
755
|
+
ignore: isInteractiveTarget
|
|
756
|
+
});
|
|
647
757
|
this.syncActionButtons();
|
|
648
758
|
}
|
|
649
759
|
removeToolbar() {
|
|
760
|
+
this.toolbarDrag?.destroy();
|
|
761
|
+
this.toolbarDrag = null;
|
|
650
762
|
this.toolbar?.remove();
|
|
651
763
|
this.toolbar = null;
|
|
652
764
|
this.toolBtns.clear();
|
|
@@ -683,7 +795,7 @@ var AnnotationEditor = class {
|
|
|
683
795
|
}
|
|
684
796
|
syncActionButtons() {
|
|
685
797
|
const empty = this.markNodes.length === 0;
|
|
686
|
-
if (this.undoBtn) this.undoBtn.disabled =
|
|
798
|
+
if (this.undoBtn) this.undoBtn.disabled = this.markNodes.length <= this.sessionBase;
|
|
687
799
|
if (this.clearBtn) this.clearBtn.disabled = empty;
|
|
688
800
|
}
|
|
689
801
|
// --------------------------------------------------------------------------
|
|
@@ -697,6 +809,7 @@ var AnnotationEditor = class {
|
|
|
697
809
|
}
|
|
698
810
|
onPointerDown = (e) => {
|
|
699
811
|
if (!this.active) return;
|
|
812
|
+
if (this.drag) return;
|
|
700
813
|
if (e.button !== void 0 && e.button !== 0) return;
|
|
701
814
|
e.preventDefault();
|
|
702
815
|
const p = this.toDoc(e);
|
|
@@ -746,6 +859,7 @@ var AnnotationEditor = class {
|
|
|
746
859
|
this.drag = drag;
|
|
747
860
|
window.addEventListener("pointermove", this.onPointerMove, true);
|
|
748
861
|
window.addEventListener("pointerup", this.onPointerUp, true);
|
|
862
|
+
window.addEventListener("pointercancel", this.onPointerCancel, true);
|
|
749
863
|
};
|
|
750
864
|
onPointerMove = (e) => {
|
|
751
865
|
const d = this.drag;
|
|
@@ -855,9 +969,18 @@ var AnnotationEditor = class {
|
|
|
855
969
|
d.node.removeAttribute("data-lens-draft");
|
|
856
970
|
this.commitMark(annotation, d.node);
|
|
857
971
|
};
|
|
972
|
+
/** Pointer capture was cancelled (OS gesture, page hidden, etc.): drop the
|
|
973
|
+
* in-progress draft node and detach listeners so nothing leaks. */
|
|
974
|
+
onPointerCancel = () => {
|
|
975
|
+
const d = this.drag;
|
|
976
|
+
this.detachDragListeners();
|
|
977
|
+
this.drag = null;
|
|
978
|
+
d?.node.remove();
|
|
979
|
+
};
|
|
858
980
|
detachDragListeners() {
|
|
859
981
|
window.removeEventListener("pointermove", this.onPointerMove, true);
|
|
860
982
|
window.removeEventListener("pointerup", this.onPointerUp, true);
|
|
983
|
+
window.removeEventListener("pointercancel", this.onPointerCancel, true);
|
|
861
984
|
}
|
|
862
985
|
commitMark(annotation, node) {
|
|
863
986
|
this.annotations.push(annotation);
|
|
@@ -1051,29 +1174,31 @@ var AnnotationEditor = class {
|
|
|
1051
1174
|
return `lens-${++this.idSeq}`;
|
|
1052
1175
|
}
|
|
1053
1176
|
};
|
|
1054
|
-
var INCLUDE_ITEMS = [
|
|
1055
|
-
{ key: "replay", label: "Replay" },
|
|
1056
|
-
{ key: "console", label: "Console" },
|
|
1057
|
-
{ key: "network", label: "Network" },
|
|
1058
|
-
{ key: "errors", label: "Errors" },
|
|
1059
|
-
{ key: "screenshot", label: "Screenshot" }
|
|
1060
|
-
];
|
|
1061
1177
|
var Panel = class {
|
|
1062
1178
|
constructor(cb) {
|
|
1063
1179
|
this.cb = cb;
|
|
1064
1180
|
this.body = el("div", { class: "lens-panel__body" });
|
|
1065
|
-
|
|
1066
|
-
el("
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1181
|
+
const head = el("div", { class: "lens-panel__head" }, [
|
|
1182
|
+
el("span", {
|
|
1183
|
+
class: "lens-panel__grip",
|
|
1184
|
+
html: iconGrip,
|
|
1185
|
+
title: "Drag to move",
|
|
1186
|
+
ariaLabel: "Drag to move panel"
|
|
1187
|
+
}),
|
|
1188
|
+
el("div", { class: "lens-panel__title", text: "Report an issue" }),
|
|
1189
|
+
el("button", {
|
|
1190
|
+
class: "lens-panel__x",
|
|
1191
|
+
ariaLabel: "Close",
|
|
1192
|
+
html: iconClose,
|
|
1193
|
+
on: { click: () => this.cb.onClose() }
|
|
1194
|
+
})
|
|
1076
1195
|
]);
|
|
1196
|
+
this.root = el(
|
|
1197
|
+
"div",
|
|
1198
|
+
{ class: "lens-panel", attrs: { role: "dialog", "aria-label": "Report an issue" } },
|
|
1199
|
+
[head, this.body]
|
|
1200
|
+
);
|
|
1201
|
+
this.drag = makeDraggable(this.root, { handle: head, key: "lens-panel" });
|
|
1077
1202
|
this.renderForm();
|
|
1078
1203
|
}
|
|
1079
1204
|
cb;
|
|
@@ -1081,6 +1206,7 @@ var Panel = class {
|
|
|
1081
1206
|
body;
|
|
1082
1207
|
textarea;
|
|
1083
1208
|
submitBtn;
|
|
1209
|
+
drag = null;
|
|
1084
1210
|
autoCloseTimer = null;
|
|
1085
1211
|
submitting = false;
|
|
1086
1212
|
/** Selected capture toggles; every flag starts ON. Persists across refresh. */
|
|
@@ -1100,6 +1226,8 @@ var Panel = class {
|
|
|
1100
1226
|
}
|
|
1101
1227
|
destroy() {
|
|
1102
1228
|
if (this.autoCloseTimer) clearTimeout(this.autoCloseTimer);
|
|
1229
|
+
this.drag?.destroy();
|
|
1230
|
+
this.drag = null;
|
|
1103
1231
|
this.root.remove();
|
|
1104
1232
|
}
|
|
1105
1233
|
renderForm() {
|
|
@@ -1114,7 +1242,6 @@ var Panel = class {
|
|
|
1114
1242
|
this.body.append(
|
|
1115
1243
|
this.textarea,
|
|
1116
1244
|
this.buildContext(),
|
|
1117
|
-
this.buildIncludes(),
|
|
1118
1245
|
this.buildChips(),
|
|
1119
1246
|
this.buildActions()
|
|
1120
1247
|
);
|
|
@@ -1134,39 +1261,6 @@ var Panel = class {
|
|
|
1134
1261
|
});
|
|
1135
1262
|
return el("div", { class: "lens-context", title: s.url }, nodes);
|
|
1136
1263
|
}
|
|
1137
|
-
/** Real toggles ("switch"): which captured data to attach. All ON by default. */
|
|
1138
|
-
buildIncludes() {
|
|
1139
|
-
const s = this.cb.getStats();
|
|
1140
|
-
const counts = {
|
|
1141
|
-
console: s.console,
|
|
1142
|
-
network: s.network,
|
|
1143
|
-
errors: s.errors
|
|
1144
|
-
};
|
|
1145
|
-
const toggles = INCLUDE_ITEMS.map((item) => this.buildToggle(item.key, item.label, counts[item.key]));
|
|
1146
|
-
return el("div", { class: "lens-includes" }, [
|
|
1147
|
-
el("span", { class: "lens-includes__label", text: "Include:" }),
|
|
1148
|
-
...toggles
|
|
1149
|
-
]);
|
|
1150
|
-
}
|
|
1151
|
-
buildToggle(key, label, count) {
|
|
1152
|
-
const on = this.include[key];
|
|
1153
|
-
const btn = el("button", {
|
|
1154
|
-
class: `lens-tgl${on ? " is-on" : ""}`,
|
|
1155
|
-
attrs: { type: "button", role: "switch", "aria-checked": String(on) },
|
|
1156
|
-
html: `<span class="lens-tgl__check" aria-hidden="true">${iconCheck}</span>`
|
|
1157
|
-
});
|
|
1158
|
-
btn.append(el("span", { class: "lens-tgl__label", text: label }));
|
|
1159
|
-
if (typeof count === "number" && count > 0) {
|
|
1160
|
-
btn.append(el("span", { class: "lens-tgl__count", text: String(count) }));
|
|
1161
|
-
}
|
|
1162
|
-
btn.addEventListener("click", () => {
|
|
1163
|
-
const next = !this.include[key];
|
|
1164
|
-
this.include[key] = next;
|
|
1165
|
-
btn.classList.toggle("is-on", next);
|
|
1166
|
-
btn.setAttribute("aria-checked", String(next));
|
|
1167
|
-
});
|
|
1168
|
-
return btn;
|
|
1169
|
-
}
|
|
1170
1264
|
/** Removable context chips: annotations, retained recording, picked element. */
|
|
1171
1265
|
buildChips() {
|
|
1172
1266
|
const row = el("div", { class: "lens-chips" });
|
|
@@ -1471,14 +1565,28 @@ var OVERLAY_CSS = (
|
|
|
1471
1565
|
`
|
|
1472
1566
|
:host {
|
|
1473
1567
|
all: initial;
|
|
1474
|
-
|
|
1475
|
-
|
|
1568
|
+
/* Black & white, mirroring the Horus Cloud dashboard: the accent is near-black
|
|
1569
|
+
in light and near-white in dark; the always-dark pill/toolbar use explicit
|
|
1570
|
+
light highlights (defined at their rules). Annotation swatch colors and
|
|
1571
|
+
status red/green are content, not brand, and keep their hues. */
|
|
1572
|
+
--lens-accent: #18181b;
|
|
1573
|
+
--lens-accent-strong: #000000;
|
|
1574
|
+
--lens-on-accent: #ffffff;
|
|
1575
|
+
--lens-focus: rgba(0, 0, 0, 0.16);
|
|
1476
1576
|
--lens-radius: 8px;
|
|
1477
1577
|
--lens-font: system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
|
|
1478
1578
|
--lens-z: 2147483000;
|
|
1479
1579
|
font-family: var(--lens-font);
|
|
1480
1580
|
line-height: 1.4;
|
|
1481
1581
|
}
|
|
1582
|
+
@media (prefers-color-scheme: dark) {
|
|
1583
|
+
:host {
|
|
1584
|
+
--lens-accent: #fafafa;
|
|
1585
|
+
--lens-accent-strong: #ffffff;
|
|
1586
|
+
--lens-on-accent: #18181b;
|
|
1587
|
+
--lens-focus: rgba(255, 255, 255, 0.22);
|
|
1588
|
+
}
|
|
1589
|
+
}
|
|
1482
1590
|
|
|
1483
1591
|
*, *::before, *::after { box-sizing: border-box; }
|
|
1484
1592
|
|
|
@@ -1498,7 +1606,7 @@ var OVERLAY_CSS = (
|
|
|
1498
1606
|
left: 50%;
|
|
1499
1607
|
transform: translateX(-50%);
|
|
1500
1608
|
max-width: calc(100vw - 16px);
|
|
1501
|
-
flex-wrap:
|
|
1609
|
+
flex-wrap: nowrap;
|
|
1502
1610
|
justify-content: center;
|
|
1503
1611
|
display: inline-flex;
|
|
1504
1612
|
align-items: center;
|
|
@@ -1522,7 +1630,7 @@ var OVERLAY_CSS = (
|
|
|
1522
1630
|
height: 26px;
|
|
1523
1631
|
margin-left: 4px;
|
|
1524
1632
|
border-radius: 999px;
|
|
1525
|
-
color: #
|
|
1633
|
+
color: #f4f4f5;
|
|
1526
1634
|
}
|
|
1527
1635
|
.lens-btn {
|
|
1528
1636
|
display: inline-flex;
|
|
@@ -1541,11 +1649,14 @@ var OVERLAY_CSS = (
|
|
|
1541
1649
|
transition: background 150ms ease, color 150ms ease;
|
|
1542
1650
|
}
|
|
1543
1651
|
.lens-btn:hover { background: rgba(255, 255, 255, 0.1); }
|
|
1544
|
-
.lens-btn:focus-visible { outline: 2px solid
|
|
1545
|
-
.lens-btn--primary { background:
|
|
1546
|
-
.lens-btn--primary:hover { background:
|
|
1652
|
+
.lens-btn:focus-visible { outline: 2px solid rgba(255, 255, 255, 0.7); outline-offset: 1px; }
|
|
1653
|
+
.lens-btn--primary { background: #fff; color: #18181b; }
|
|
1654
|
+
.lens-btn--primary:hover { background: #e4e4e7; }
|
|
1655
|
+
.lens-btn--report svg { flex: none; }
|
|
1656
|
+
.lens-btn__label { white-space: nowrap; }
|
|
1547
1657
|
.lens-btn--icon { width: 30px; padding: 0; justify-content: center; }
|
|
1548
|
-
|
|
1658
|
+
/* Always-dark pill: an active control reads as a light (white) highlight. */
|
|
1659
|
+
.lens-btn--icon.is-active { background: #fff; color: #18181b; }
|
|
1549
1660
|
.lens-pill__sep {
|
|
1550
1661
|
width: 1px;
|
|
1551
1662
|
height: 18px;
|
|
@@ -1559,7 +1670,10 @@ var OVERLAY_CSS = (
|
|
|
1559
1670
|
z-index: calc(var(--lens-z) - 2);
|
|
1560
1671
|
pointer-events: none;
|
|
1561
1672
|
border: 2px solid var(--lens-accent);
|
|
1562
|
-
|
|
1673
|
+
/* A light outer ring so the (black-in-light / white-in-dark) border stays
|
|
1674
|
+
visible over any page background. */
|
|
1675
|
+
box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.6), 0 0 0 3px rgba(0, 0, 0, 0.15);
|
|
1676
|
+
background: rgba(127, 127, 127, 0.14);
|
|
1563
1677
|
border-radius: 3px;
|
|
1564
1678
|
transition: all 60ms linear;
|
|
1565
1679
|
display: none;
|
|
@@ -1571,7 +1685,7 @@ var OVERLAY_CSS = (
|
|
|
1571
1685
|
padding: 1px 6px;
|
|
1572
1686
|
border-radius: 4px;
|
|
1573
1687
|
background: var(--lens-accent);
|
|
1574
|
-
color:
|
|
1688
|
+
color: var(--lens-on-accent);
|
|
1575
1689
|
font: 500 11px/1.5 var(--lens-font);
|
|
1576
1690
|
white-space: nowrap;
|
|
1577
1691
|
}
|
|
@@ -1650,7 +1764,7 @@ var OVERLAY_CSS = (
|
|
|
1650
1764
|
padding: 14px 16px;
|
|
1651
1765
|
border-bottom: 1px solid rgba(0, 0, 0, 0.07);
|
|
1652
1766
|
}
|
|
1653
|
-
.lens-panel__title { font-size: 14px; font-weight: 600; }
|
|
1767
|
+
.lens-panel__title { font-size: 14px; font-weight: 600; margin-right: auto; }
|
|
1654
1768
|
.lens-panel__x {
|
|
1655
1769
|
display: inline-flex;
|
|
1656
1770
|
align-items: center;
|
|
@@ -1688,7 +1802,7 @@ var OVERLAY_CSS = (
|
|
|
1688
1802
|
.lens-textarea:focus {
|
|
1689
1803
|
outline: none;
|
|
1690
1804
|
border-color: var(--lens-accent);
|
|
1691
|
-
box-shadow: 0 0 0 3px
|
|
1805
|
+
box-shadow: 0 0 0 3px var(--lens-focus);
|
|
1692
1806
|
}
|
|
1693
1807
|
/* ---- Context row: static, non-interactive page facts (muted, dot-joined) ---- */
|
|
1694
1808
|
.lens-context {
|
|
@@ -1703,49 +1817,6 @@ var OVERLAY_CSS = (
|
|
|
1703
1817
|
.lens-context__item { white-space: nowrap; }
|
|
1704
1818
|
.lens-context__dot { opacity: 0.55; }
|
|
1705
1819
|
|
|
1706
|
-
/* ---- Include row: real toggles (role=switch) for which data to attach ---- */
|
|
1707
|
-
.lens-includes {
|
|
1708
|
-
display: flex;
|
|
1709
|
-
flex-wrap: wrap;
|
|
1710
|
-
align-items: center;
|
|
1711
|
-
gap: 6px;
|
|
1712
|
-
}
|
|
1713
|
-
.lens-includes__label {
|
|
1714
|
-
font-size: 11.5px;
|
|
1715
|
-
font-weight: 600;
|
|
1716
|
-
color: #71717a;
|
|
1717
|
-
margin-right: 2px;
|
|
1718
|
-
}
|
|
1719
|
-
.lens-tgl {
|
|
1720
|
-
display: inline-flex;
|
|
1721
|
-
align-items: center;
|
|
1722
|
-
gap: 5px;
|
|
1723
|
-
padding: 4px 10px;
|
|
1724
|
-
border-radius: 999px;
|
|
1725
|
-
border: 1px solid rgba(0, 0, 0, 0.14);
|
|
1726
|
-
background: #fafafa;
|
|
1727
|
-
color: #a1a1aa;
|
|
1728
|
-
font-family: var(--lens-font);
|
|
1729
|
-
font-size: 11.5px;
|
|
1730
|
-
font-weight: 600;
|
|
1731
|
-
white-space: nowrap;
|
|
1732
|
-
cursor: pointer;
|
|
1733
|
-
opacity: 0.75;
|
|
1734
|
-
transition: background 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;
|
|
1735
|
-
}
|
|
1736
|
-
.lens-tgl:hover { opacity: 1; }
|
|
1737
|
-
.lens-tgl:focus-visible { outline: 2px solid var(--lens-accent); outline-offset: 1px; }
|
|
1738
|
-
.lens-tgl__check { display: none; align-items: center; }
|
|
1739
|
-
.lens-tgl__check svg { width: 13px; height: 13px; }
|
|
1740
|
-
.lens-tgl__count { font-weight: 500; opacity: 0.75; font-variant-numeric: tabular-nums; }
|
|
1741
|
-
.lens-tgl.is-on {
|
|
1742
|
-
opacity: 1;
|
|
1743
|
-
color: var(--lens-accent-strong);
|
|
1744
|
-
border-color: rgba(99, 102, 241, 0.5);
|
|
1745
|
-
background: #eef2ff;
|
|
1746
|
-
}
|
|
1747
|
-
.lens-tgl.is-on .lens-tgl__check { display: inline-flex; }
|
|
1748
|
-
|
|
1749
1820
|
.lens-chips { display: flex; flex-wrap: wrap; gap: 6px; }
|
|
1750
1821
|
.lens-chip {
|
|
1751
1822
|
display: inline-flex;
|
|
@@ -1766,9 +1837,9 @@ var OVERLAY_CSS = (
|
|
|
1766
1837
|
.lens-chip--ok { color: #15803d; background: #f0fdf4; border-color: rgba(21, 128, 61, 0.18); }
|
|
1767
1838
|
.lens-chip--target {
|
|
1768
1839
|
max-width: 100%;
|
|
1769
|
-
background:
|
|
1770
|
-
border-color: rgba(
|
|
1771
|
-
color:
|
|
1840
|
+
background: rgba(0, 0, 0, 0.05);
|
|
1841
|
+
border-color: rgba(0, 0, 0, 0.16);
|
|
1842
|
+
color: #18181b;
|
|
1772
1843
|
}
|
|
1773
1844
|
.lens-chip__code {
|
|
1774
1845
|
font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
|
|
@@ -1816,7 +1887,7 @@ var OVERLAY_CSS = (
|
|
|
1816
1887
|
.lens-abtn svg { flex: none; }
|
|
1817
1888
|
.lens-abtn--ghost { background: transparent; border-color: rgba(0, 0, 0, 0.14); color: #3f3f46; }
|
|
1818
1889
|
.lens-abtn--ghost:hover { background: rgba(0, 0, 0, 0.04); }
|
|
1819
|
-
.lens-abtn--primary { background: var(--lens-accent); color:
|
|
1890
|
+
.lens-abtn--primary { background: var(--lens-accent); color: var(--lens-on-accent); }
|
|
1820
1891
|
.lens-abtn--primary:hover { background: var(--lens-accent-strong); }
|
|
1821
1892
|
.lens-abtn:disabled { opacity: 0.55; cursor: default; }
|
|
1822
1893
|
.lens-abtn:focus-visible { outline: 2px solid var(--lens-accent); outline-offset: 1px; }
|
|
@@ -1870,12 +1941,9 @@ var OVERLAY_CSS = (
|
|
|
1870
1941
|
.lens-panel__x:hover { background: rgba(255, 255, 255, 0.08); }
|
|
1871
1942
|
.lens-textarea { background: #26262a; border-color: rgba(255, 255, 255, 0.14); color: #f4f4f5; }
|
|
1872
1943
|
.lens-context { color: #a1a1aa; }
|
|
1873
|
-
.lens-includes__label { color: #a1a1aa; }
|
|
1874
|
-
.lens-tgl { background: #26262a; border-color: rgba(255, 255, 255, 0.12); color: #a1a1aa; }
|
|
1875
|
-
.lens-tgl.is-on { background: rgba(99, 102, 241, 0.18); border-color: rgba(99, 102, 241, 0.55); color: #c7d2fe; }
|
|
1876
1944
|
.lens-chip { background: #26262a; border-color: rgba(255, 255, 255, 0.08); color: #d4d4d8; }
|
|
1877
1945
|
.lens-chip--ok { color: #4ade80; background: rgba(34, 197, 94, 0.12); border-color: rgba(74, 222, 128, 0.22); }
|
|
1878
|
-
.lens-chip--target { background: rgba(
|
|
1946
|
+
.lens-chip--target { background: rgba(255, 255, 255, 0.1); border-color: rgba(255, 255, 255, 0.18); color: #f4f4f5; }
|
|
1879
1947
|
.lens-abtn--ghost { border-color: rgba(255, 255, 255, 0.16); color: #d4d4d8; }
|
|
1880
1948
|
.lens-abtn--ghost:hover { background: rgba(255, 255, 255, 0.06); }
|
|
1881
1949
|
.lens-state__msg { color: #a1a1aa; }
|
|
@@ -1909,7 +1977,9 @@ var OVERLAY_CSS = (
|
|
|
1909
1977
|
.lens-annotate-chips { z-index: var(--lens-z); }
|
|
1910
1978
|
|
|
1911
1979
|
/* ---------------- Annotation toolbar ---------------- */
|
|
1912
|
-
/*
|
|
1980
|
+
/* Floating top-center anchor. A fixed drag grip sits left of a tools "track":
|
|
1981
|
+
the track wraps on desktop and becomes a single horizontal-scroll row on
|
|
1982
|
+
narrow screens, so the bar stays one slim height instead of a bulky block. */
|
|
1913
1983
|
.lens-annotate-toolbar {
|
|
1914
1984
|
position: fixed;
|
|
1915
1985
|
top: calc(16px + env(safe-area-inset-top));
|
|
@@ -1917,11 +1987,10 @@ var OVERLAY_CSS = (
|
|
|
1917
1987
|
transform: translateX(-50%);
|
|
1918
1988
|
z-index: var(--lens-z);
|
|
1919
1989
|
display: inline-flex;
|
|
1920
|
-
flex-wrap:
|
|
1990
|
+
flex-wrap: nowrap;
|
|
1921
1991
|
align-items: center;
|
|
1922
|
-
justify-content: center;
|
|
1923
1992
|
gap: 6px;
|
|
1924
|
-
max-width: calc(100vw -
|
|
1993
|
+
max-width: calc(100vw - 16px);
|
|
1925
1994
|
padding: 6px 8px;
|
|
1926
1995
|
border-radius: 14px;
|
|
1927
1996
|
background: rgba(20, 20, 23, 0.92);
|
|
@@ -1931,12 +2000,50 @@ var OVERLAY_CSS = (
|
|
|
1931
2000
|
box-shadow: 0 8px 30px rgba(0, 0, 0, 0.35);
|
|
1932
2001
|
color: #f4f4f5;
|
|
1933
2002
|
}
|
|
2003
|
+
/* Tools lay out as ONE horizontal row that scrolls if it can't fit, so the bar
|
|
2004
|
+
is always a single slim height \u2014 never a wrapping (or, worse, min-content
|
|
2005
|
+
collapsed vertical) block. The grip sits outside this track. */
|
|
2006
|
+
.lens-tool-track {
|
|
2007
|
+
display: flex;
|
|
2008
|
+
align-items: center;
|
|
2009
|
+
flex-wrap: nowrap;
|
|
2010
|
+
justify-content: flex-start;
|
|
2011
|
+
gap: 6px;
|
|
2012
|
+
flex: 1 1 auto;
|
|
2013
|
+
min-width: 0;
|
|
2014
|
+
overflow-x: auto;
|
|
2015
|
+
overflow-y: hidden;
|
|
2016
|
+
scrollbar-width: none;
|
|
2017
|
+
-webkit-overflow-scrolling: touch;
|
|
2018
|
+
}
|
|
2019
|
+
.lens-tool-track::-webkit-scrollbar { display: none; }
|
|
1934
2020
|
.lens-tool-group {
|
|
1935
2021
|
display: inline-flex;
|
|
1936
2022
|
align-items: center;
|
|
1937
2023
|
gap: 4px;
|
|
1938
|
-
flex-wrap:
|
|
2024
|
+
flex-wrap: nowrap;
|
|
2025
|
+
flex: none;
|
|
1939
2026
|
}
|
|
2027
|
+
/* Single close (=Done, keeps marks) pinned at the right, always reachable
|
|
2028
|
+
while the tools scroll. Reads as a light control on the dark bar. */
|
|
2029
|
+
.lens-tool-close {
|
|
2030
|
+
display: inline-flex;
|
|
2031
|
+
align-items: center;
|
|
2032
|
+
justify-content: center;
|
|
2033
|
+
flex: none;
|
|
2034
|
+
width: 32px;
|
|
2035
|
+
height: 30px;
|
|
2036
|
+
padding: 0;
|
|
2037
|
+
border: 0;
|
|
2038
|
+
border-radius: 8px;
|
|
2039
|
+
background: rgba(255, 255, 255, 0.14);
|
|
2040
|
+
color: #f4f4f5;
|
|
2041
|
+
cursor: pointer;
|
|
2042
|
+
transition: background 150ms ease;
|
|
2043
|
+
}
|
|
2044
|
+
.lens-tool-close:hover { background: rgba(255, 255, 255, 0.26); }
|
|
2045
|
+
.lens-tool-close:focus-visible { outline: 2px solid rgba(255, 255, 255, 0.7); outline-offset: 1px; }
|
|
2046
|
+
.lens-tool-close svg { width: 18px; height: 18px; }
|
|
1940
2047
|
.lens-tool-sep {
|
|
1941
2048
|
width: 1px;
|
|
1942
2049
|
align-self: stretch;
|
|
@@ -1944,6 +2051,51 @@ var OVERLAY_CSS = (
|
|
|
1944
2051
|
background: rgba(255, 255, 255, 0.16);
|
|
1945
2052
|
margin: 0 2px;
|
|
1946
2053
|
}
|
|
2054
|
+
|
|
2055
|
+
/* ---------------- Draggable surfaces ---------------- */
|
|
2056
|
+
/* Every drag handle: no page pan/scroll gesture starts here, and the cursor
|
|
2057
|
+
signals grabbability. Applied to the pill, panel header, toolbar grip, chips. */
|
|
2058
|
+
.lens-drag-handle { touch-action: none; cursor: grab; }
|
|
2059
|
+
.lens-drag-handle:active { cursor: grabbing; }
|
|
2060
|
+
.is-dragging, .is-dragging * { cursor: grabbing !important; }
|
|
2061
|
+
.is-dragging { user-select: none; }
|
|
2062
|
+
/* While dragging, drop the entry animation/transition so it tracks 1:1. */
|
|
2063
|
+
.lens-pill.is-dragging, .lens-panel.is-dragging,
|
|
2064
|
+
.lens-annotate-toolbar.is-dragging, .lens-rec-chip.is-dragging {
|
|
2065
|
+
animation: none;
|
|
2066
|
+
transition: none;
|
|
2067
|
+
}
|
|
2068
|
+
|
|
2069
|
+
/* Toolbar drag grip \u2014 the only grab region, kept out of the scroll track. */
|
|
2070
|
+
.lens-tool-grip {
|
|
2071
|
+
display: inline-flex;
|
|
2072
|
+
align-items: center;
|
|
2073
|
+
justify-content: center;
|
|
2074
|
+
flex: none;
|
|
2075
|
+
width: 22px;
|
|
2076
|
+
height: 30px;
|
|
2077
|
+
margin-right: 2px;
|
|
2078
|
+
border-radius: 6px;
|
|
2079
|
+
color: #a1a1aa;
|
|
2080
|
+
}
|
|
2081
|
+
.lens-tool-grip:hover { color: #f4f4f5; background: rgba(255, 255, 255, 0.08); }
|
|
2082
|
+
.lens-tool-grip svg { width: 16px; height: 16px; }
|
|
2083
|
+
|
|
2084
|
+
/* Pill grip (the eye dot) + panel header grip. */
|
|
2085
|
+
.lens-pill__grip { cursor: grab; }
|
|
2086
|
+
.lens-panel__grip {
|
|
2087
|
+
display: inline-flex;
|
|
2088
|
+
align-items: center;
|
|
2089
|
+
justify-content: center;
|
|
2090
|
+
flex: none;
|
|
2091
|
+
width: 22px;
|
|
2092
|
+
height: 22px;
|
|
2093
|
+
margin-right: 6px;
|
|
2094
|
+
color: #a1a1aa;
|
|
2095
|
+
}
|
|
2096
|
+
.lens-panel__grip svg { width: 16px; height: 16px; }
|
|
2097
|
+
.lens-panel__head { cursor: grab; }
|
|
2098
|
+
.lens-panel__head:active { cursor: grabbing; }
|
|
1947
2099
|
.lens-tool-btn {
|
|
1948
2100
|
display: inline-flex;
|
|
1949
2101
|
align-items: center;
|
|
@@ -1959,11 +2111,11 @@ var OVERLAY_CSS = (
|
|
|
1959
2111
|
transition: background 150ms ease, color 150ms ease, border-color 150ms ease;
|
|
1960
2112
|
}
|
|
1961
2113
|
.lens-tool-btn:hover { background: rgba(255, 255, 255, 0.1); color: #fff; }
|
|
1962
|
-
.lens-tool-btn:focus-visible { outline: 2px solid
|
|
2114
|
+
.lens-tool-btn:focus-visible { outline: 2px solid rgba(255, 255, 255, 0.7); outline-offset: 1px; }
|
|
1963
2115
|
.lens-tool-btn.is-active {
|
|
1964
|
-
background:
|
|
1965
|
-
border-color:
|
|
1966
|
-
color: #
|
|
2116
|
+
background: #fff;
|
|
2117
|
+
border-color: #fff;
|
|
2118
|
+
color: #18181b;
|
|
1967
2119
|
}
|
|
1968
2120
|
.lens-tool-btn:disabled { opacity: 0.4; cursor: default; }
|
|
1969
2121
|
.lens-tool-btn:disabled:hover { background: transparent; color: #d4d4d8; }
|
|
@@ -2003,17 +2155,18 @@ var OVERLAY_CSS = (
|
|
|
2003
2155
|
transition: background 150ms ease, color 150ms ease, border-color 150ms ease;
|
|
2004
2156
|
}
|
|
2005
2157
|
.lens-width-btn:hover { background: rgba(255, 255, 255, 0.1); color: #fff; }
|
|
2006
|
-
.lens-width-btn:focus-visible { outline: 2px solid
|
|
2158
|
+
.lens-width-btn:focus-visible { outline: 2px solid rgba(255, 255, 255, 0.7); outline-offset: 1px; }
|
|
2007
2159
|
.lens-width-btn.is-active {
|
|
2008
|
-
background:
|
|
2009
|
-
border-color:
|
|
2010
|
-
color: #
|
|
2160
|
+
background: #fff;
|
|
2161
|
+
border-color: #fff;
|
|
2162
|
+
color: #18181b;
|
|
2011
2163
|
}
|
|
2012
2164
|
|
|
2013
2165
|
/* Coarse pointers: bump the tool targets toward 40px. */
|
|
2014
2166
|
@media (pointer: coarse) {
|
|
2015
2167
|
.lens-tool-btn, .lens-width-btn { width: 38px; height: 38px; }
|
|
2016
2168
|
.lens-swatch { width: 30px; height: 30px; }
|
|
2169
|
+
.lens-tool-grip { width: 30px; height: 38px; }
|
|
2017
2170
|
}
|
|
2018
2171
|
|
|
2019
2172
|
/* Stacking inside the shadow layer: the panel, pill and floating chips always
|
|
@@ -2038,8 +2191,8 @@ var OVERLAY_CSS = (
|
|
|
2038
2191
|
transition: background 150ms ease;
|
|
2039
2192
|
}
|
|
2040
2193
|
.lens-pick-chip__btn:hover { background: rgba(255, 255, 255, 0.2); }
|
|
2041
|
-
.lens-pick-chip__btn--primary { background:
|
|
2042
|
-
.lens-pick-chip__btn--primary:hover { background:
|
|
2194
|
+
.lens-pick-chip__btn--primary { background: #fff; color: #18181b; }
|
|
2195
|
+
.lens-pick-chip__btn--primary:hover { background: #e4e4e7; }
|
|
2043
2196
|
|
|
2044
2197
|
/* ---------------- Recording chip ---------------- */
|
|
2045
2198
|
.lens-rec-chip {
|
|
@@ -2094,21 +2247,29 @@ var OVERLAY_CSS = (
|
|
|
2094
2247
|
.lens-rec-chip__stop:hover { background: #dc2626; }
|
|
2095
2248
|
.lens-chip--rec { gap: 6px; }
|
|
2096
2249
|
|
|
2250
|
+
/* Very narrow screens: collapse the pill's "Report issue" label to its icon so
|
|
2251
|
+
the pill stays a single slim row (never wraps into a 2-row blob). */
|
|
2252
|
+
@media (max-width: 400px) {
|
|
2253
|
+
.lens-btn__label { display: none; }
|
|
2254
|
+
.lens-btn--report { width: 44px; padding: 0; justify-content: center; }
|
|
2255
|
+
}
|
|
2256
|
+
|
|
2097
2257
|
/* ---------------- Coarse pointers (touch): \u226544px targets ---------------- */
|
|
2098
2258
|
@media (pointer: coarse) {
|
|
2099
2259
|
.lens-btn { height: 44px; padding: 0 16px; }
|
|
2100
2260
|
.lens-btn--icon { width: 44px; }
|
|
2261
|
+
.lens-tool-close { width: 44px; height: 38px; }
|
|
2101
2262
|
.lens-pill__dot { width: 40px; height: 40px; }
|
|
2102
2263
|
.lens-abtn { height: 44px; }
|
|
2103
|
-
.lens-tgl { min-height: 40px; padding: 4px 14px; }
|
|
2104
2264
|
.lens-panel__x { width: 44px; height: 44px; }
|
|
2105
2265
|
.lens-chip__x { min-width: 32px; min-height: 32px; align-items: center; justify-content: center; }
|
|
2106
2266
|
.lens-pick-chip__btn, .lens-rec-chip__stop { height: 40px; padding: 0 18px; }
|
|
2107
2267
|
}
|
|
2108
2268
|
|
|
2109
|
-
/* ----------------
|
|
2269
|
+
/* ---------------- Narrow screens (\u2264640px) ---------------- */
|
|
2110
2270
|
@media (max-width: 640px) {
|
|
2111
|
-
|
|
2271
|
+
/* Report panel as a bottom sheet (unless the user has dragged it loose). */
|
|
2272
|
+
.lens-panel:not(.is-dragging) {
|
|
2112
2273
|
left: 0;
|
|
2113
2274
|
right: 0;
|
|
2114
2275
|
bottom: 0;
|
|
@@ -2125,6 +2286,14 @@ var OVERLAY_CSS = (
|
|
|
2125
2286
|
to { opacity: 1; transform: none; }
|
|
2126
2287
|
}
|
|
2127
2288
|
.lens-textarea { font-size: 16px; }
|
|
2289
|
+
|
|
2290
|
+
/* On narrow screens the single-row tool track usually overflows: fade its
|
|
2291
|
+
trailing edge so it reads as "more tools this way" (the grip sits outside
|
|
2292
|
+
the track and stays fully opaque). */
|
|
2293
|
+
.lens-tool-track {
|
|
2294
|
+
-webkit-mask-image: linear-gradient(90deg, #000 calc(100% - 20px), transparent 100%);
|
|
2295
|
+
mask-image: linear-gradient(90deg, #000 calc(100% - 20px), transparent 100%);
|
|
2296
|
+
}
|
|
2128
2297
|
}
|
|
2129
2298
|
`
|
|
2130
2299
|
);
|
|
@@ -2142,8 +2311,14 @@ var Overlay = class {
|
|
|
2142
2311
|
this.shadow.append(this.layer);
|
|
2143
2312
|
this.picker = new ElementPicker(this.layer, this.host);
|
|
2144
2313
|
this.annotator = new AnnotationEditor(this.layer);
|
|
2145
|
-
this.
|
|
2314
|
+
const pill = this.buildPill();
|
|
2315
|
+
this.layer.append(pill);
|
|
2146
2316
|
document.documentElement.append(this.host);
|
|
2317
|
+
this.pillDrag = makeDraggable(pill, {
|
|
2318
|
+
handle: pill,
|
|
2319
|
+
key: "lens-pill",
|
|
2320
|
+
ignore: isInteractiveTarget
|
|
2321
|
+
});
|
|
2147
2322
|
window.addEventListener("keydown", this.onGlobalKey, true);
|
|
2148
2323
|
}
|
|
2149
2324
|
deps;
|
|
@@ -2156,7 +2331,9 @@ var Overlay = class {
|
|
|
2156
2331
|
panel = null;
|
|
2157
2332
|
target = null;
|
|
2158
2333
|
destroyed = false;
|
|
2334
|
+
pillDrag = null;
|
|
2159
2335
|
recordingChip = null;
|
|
2336
|
+
recordingDrag = null;
|
|
2160
2337
|
recordingTimerEl = null;
|
|
2161
2338
|
recordingInterval = null;
|
|
2162
2339
|
recordingStartTs = 0;
|
|
@@ -2171,10 +2348,16 @@ var Overlay = class {
|
|
|
2171
2348
|
on: { click: () => this.togglePicker() }
|
|
2172
2349
|
});
|
|
2173
2350
|
return el("div", { class: "lens-pill", attrs: { role: "toolbar", "aria-label": "Lens" } }, [
|
|
2174
|
-
el("span", {
|
|
2351
|
+
el("span", {
|
|
2352
|
+
class: "lens-pill__dot lens-pill__grip",
|
|
2353
|
+
html: iconEye,
|
|
2354
|
+
title: "Drag to move",
|
|
2355
|
+
ariaLabel: "Drag to move Lens"
|
|
2356
|
+
}),
|
|
2175
2357
|
el("button", {
|
|
2176
|
-
class: "lens-btn",
|
|
2177
|
-
|
|
2358
|
+
class: "lens-btn lens-btn--report",
|
|
2359
|
+
html: iconReport + '<span class="lens-btn__label">Report issue</span>',
|
|
2360
|
+
ariaLabel: "Report issue",
|
|
2178
2361
|
on: { click: () => this.open() }
|
|
2179
2362
|
}),
|
|
2180
2363
|
this.pickBtn,
|
|
@@ -2228,6 +2411,7 @@ var Overlay = class {
|
|
|
2228
2411
|
this.stopPicker();
|
|
2229
2412
|
return;
|
|
2230
2413
|
}
|
|
2414
|
+
if (this.annotator.isActive) this.annotator.exit();
|
|
2231
2415
|
this.close();
|
|
2232
2416
|
this.pickBtn.classList.add("is-active");
|
|
2233
2417
|
this.picker.start(
|
|
@@ -2289,6 +2473,11 @@ var Overlay = class {
|
|
|
2289
2473
|
})
|
|
2290
2474
|
]);
|
|
2291
2475
|
this.layer.append(this.recordingChip);
|
|
2476
|
+
this.recordingDrag = makeDraggable(this.recordingChip, {
|
|
2477
|
+
handle: this.recordingChip,
|
|
2478
|
+
key: "lens-rec-chip",
|
|
2479
|
+
ignore: isInteractiveTarget
|
|
2480
|
+
});
|
|
2292
2481
|
this.recordingInterval = setInterval(() => this.tickRecording(), 250);
|
|
2293
2482
|
}
|
|
2294
2483
|
tickRecording() {
|
|
@@ -2301,6 +2490,10 @@ var Overlay = class {
|
|
|
2301
2490
|
clearInterval(this.recordingInterval);
|
|
2302
2491
|
this.recordingInterval = null;
|
|
2303
2492
|
}
|
|
2493
|
+
if (this.recordingDrag) {
|
|
2494
|
+
this.recordingDrag.destroy();
|
|
2495
|
+
this.recordingDrag = null;
|
|
2496
|
+
}
|
|
2304
2497
|
if (this.recordingChip) {
|
|
2305
2498
|
this.recordingChip.remove();
|
|
2306
2499
|
this.recordingChip = null;
|
|
@@ -2341,6 +2534,8 @@ var Overlay = class {
|
|
|
2341
2534
|
if (this.destroyed) return;
|
|
2342
2535
|
this.destroyed = true;
|
|
2343
2536
|
window.removeEventListener("keydown", this.onGlobalKey, true);
|
|
2537
|
+
this.pillDrag?.destroy();
|
|
2538
|
+
this.pillDrag = null;
|
|
2344
2539
|
this.stopPicker();
|
|
2345
2540
|
if (this.deps.client.isRecording()) this.deps.client.stopRecording();
|
|
2346
2541
|
this.hideRecordingChip();
|
|
@@ -2529,4 +2724,4 @@ export {
|
|
|
2529
2724
|
boot,
|
|
2530
2725
|
autoBoot
|
|
2531
2726
|
};
|
|
2532
|
-
//# sourceMappingURL=chunk-
|
|
2727
|
+
//# sourceMappingURL=chunk-M3QMIY4Y.js.map
|