review-lens-react 0.2.0 → 0.2.1
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/review-lens-react.js +164 -156
- package/dist/review-lens-react.umd.cjs +1 -1
- package/package.json +1 -1
|
@@ -5,7 +5,7 @@ const ct = [
|
|
|
5
5
|
"https://www.googleapis.com/auth/userinfo.email"
|
|
6
6
|
].join(" "), dt = "https://www.googleapis.com/oauth2/v3/userinfo";
|
|
7
7
|
function ht(e) {
|
|
8
|
-
const t = e.feedbackSheetName ?? "Feedback", n = e.messagesSheetName ?? "Messages",
|
|
8
|
+
const t = e.feedbackSheetName ?? "Feedback", n = e.messagesSheetName ?? "Messages", r = e.usersSheetName ?? "Users";
|
|
9
9
|
let s, c;
|
|
10
10
|
async function g() {
|
|
11
11
|
return s ?? (s = St(e.googleClientId)), s;
|
|
@@ -46,7 +46,7 @@ function ht(e) {
|
|
|
46
46
|
return { email: c };
|
|
47
47
|
},
|
|
48
48
|
async getPermissions(d) {
|
|
49
|
-
const [{ email: v }, p] = await Promise.all([this.getCurrentUser(), u(
|
|
49
|
+
const [{ email: v }, p] = await Promise.all([this.getCurrentUser(), u(r)]), b = ce(p), E = v.toLowerCase(), x = b.find(
|
|
50
50
|
(A) => {
|
|
51
51
|
var h;
|
|
52
52
|
return ((h = A.email) == null ? void 0 : h.toLowerCase()) === E && A.active !== "false" && (!A.projectKey || A.projectKey === d);
|
|
@@ -180,10 +180,10 @@ function pt(e) {
|
|
|
180
180
|
}
|
|
181
181
|
function ce(e) {
|
|
182
182
|
const [t, ...n] = e;
|
|
183
|
-
return t ? n.map((
|
|
183
|
+
return t ? n.map((r) => De(t, r)) : [];
|
|
184
184
|
}
|
|
185
185
|
function De(e, t) {
|
|
186
|
-
return Object.fromEntries(e.map((n,
|
|
186
|
+
return Object.fromEntries(e.map((n, r) => [n, t[r] ?? ""]));
|
|
187
187
|
}
|
|
188
188
|
function Te(e) {
|
|
189
189
|
return e.id ? {
|
|
@@ -283,15 +283,15 @@ function wt(e) {
|
|
|
283
283
|
function yt(e) {
|
|
284
284
|
let t = e, n = "";
|
|
285
285
|
for (; t > 0; ) {
|
|
286
|
-
const
|
|
287
|
-
n = String.fromCharCode(65 +
|
|
286
|
+
const r = (t - 1) % 26;
|
|
287
|
+
n = String.fromCharCode(65 + r) + n, t = Math.floor((t - r) / 26);
|
|
288
288
|
}
|
|
289
289
|
return n;
|
|
290
290
|
}
|
|
291
291
|
async function St(e) {
|
|
292
292
|
return await kt(), new Promise((t, n) => {
|
|
293
293
|
var s;
|
|
294
|
-
const
|
|
294
|
+
const r = (s = window.google) == null ? void 0 : s.accounts.oauth2.initTokenClient({
|
|
295
295
|
client_id: e,
|
|
296
296
|
scope: ct,
|
|
297
297
|
callback: (c) => {
|
|
@@ -302,17 +302,17 @@ async function St(e) {
|
|
|
302
302
|
t(c.access_token);
|
|
303
303
|
}
|
|
304
304
|
});
|
|
305
|
-
|
|
305
|
+
r == null || r.requestAccessToken({ prompt: "" });
|
|
306
306
|
});
|
|
307
307
|
}
|
|
308
308
|
function kt() {
|
|
309
309
|
var e;
|
|
310
310
|
return (e = window.google) != null && e.accounts.oauth2 ? Promise.resolve() : new Promise((t, n) => {
|
|
311
|
-
const
|
|
311
|
+
const r = document.querySelector(
|
|
312
312
|
'script[src="https://accounts.google.com/gsi/client"]'
|
|
313
313
|
);
|
|
314
|
-
if (
|
|
315
|
-
|
|
314
|
+
if (r) {
|
|
315
|
+
r.addEventListener("load", () => t(), { once: !0 }), r.addEventListener("error", () => n(new Error("Google Identity failed to load")), {
|
|
316
316
|
once: !0
|
|
317
317
|
});
|
|
318
318
|
return;
|
|
@@ -325,12 +325,12 @@ function Ct(e) {
|
|
|
325
325
|
return new URL(e, window.location.href).pathname.replace(/\/+$/, "") || "/";
|
|
326
326
|
}
|
|
327
327
|
const ze = st(null);
|
|
328
|
-
function
|
|
328
|
+
function Qt({ config: e, children: t }) {
|
|
329
329
|
const n = re(() => e.adapter ? e.adapter : ht({
|
|
330
330
|
googleClientId: Be(e.googleClientId, "googleClientId"),
|
|
331
331
|
spreadsheetId: Be(e.spreadsheetId, "spreadsheetId"),
|
|
332
332
|
feedbackSheetName: e.sheetName ?? "Feedback"
|
|
333
|
-
}), [e.adapter, e.googleClientId, e.sheetName, e.spreadsheetId]),
|
|
333
|
+
}), [e.adapter, e.googleClientId, e.sheetName, e.spreadsheetId]), r = e.currentUrl ?? window.location.href, s = (e.normalizeUrl ?? Ct)(r), [c, g] = k(), [f, u] = k([]), [d, v] = k([]), p = W(async () => {
|
|
334
334
|
const y = await n.listFeedback({
|
|
335
335
|
projectKey: e.projectKey,
|
|
336
336
|
contentId: e.contentId,
|
|
@@ -454,15 +454,15 @@ function At(e) {
|
|
|
454
454
|
const t = [];
|
|
455
455
|
let n = e;
|
|
456
456
|
for (; n && n.nodeType === Node.ELEMENT_NODE && n !== document.body; ) {
|
|
457
|
-
const
|
|
458
|
-
if (!
|
|
457
|
+
const r = n.parentElement, s = n.tagName.toLowerCase();
|
|
458
|
+
if (!r) {
|
|
459
459
|
t.unshift(s);
|
|
460
460
|
break;
|
|
461
461
|
}
|
|
462
|
-
const c = n.tagName, g = Array.from(
|
|
462
|
+
const c = n.tagName, g = Array.from(r.children).filter(
|
|
463
463
|
(u) => u.tagName === c
|
|
464
464
|
), f = g.indexOf(n) + 1;
|
|
465
|
-
t.unshift(g.length > 1 ? `${s}:nth-of-type(${f})` : s), n =
|
|
465
|
+
t.unshift(g.length > 1 ? `${s}:nth-of-type(${f})` : s), n = r;
|
|
466
466
|
}
|
|
467
467
|
return t.join(" > ");
|
|
468
468
|
}
|
|
@@ -516,8 +516,8 @@ function Ft(e, t) {
|
|
|
516
516
|
height: Math.round(t.height)
|
|
517
517
|
};
|
|
518
518
|
}
|
|
519
|
-
function de(e, t, n,
|
|
520
|
-
return e === t && t === n && n ===
|
|
519
|
+
function de(e, t, n, r) {
|
|
520
|
+
return e === t && t === n && n === r ? e : `${e} ${t} ${n} ${r}`;
|
|
521
521
|
}
|
|
522
522
|
function $e(e) {
|
|
523
523
|
return typeof CSS < "u" && typeof CSS.escape == "function" ? CSS.escape(e) : e.replace(/["\\]/g, "\\$&");
|
|
@@ -551,11 +551,11 @@ const Mt = [
|
|
|
551
551
|
accessibility: "Accessibility",
|
|
552
552
|
responsive: "Responsive"
|
|
553
553
|
};
|
|
554
|
-
function
|
|
554
|
+
function Zt({
|
|
555
555
|
open: e,
|
|
556
556
|
onOpenChange: t,
|
|
557
557
|
placement: n = "top-right",
|
|
558
|
-
showResolved:
|
|
558
|
+
showResolved: r = !1,
|
|
559
559
|
syncSelectionToUrl: s = !1,
|
|
560
560
|
responsivePresets: c = Mt
|
|
561
561
|
}) {
|
|
@@ -572,81 +572,81 @@ function Qt({
|
|
|
572
572
|
listMessages: x,
|
|
573
573
|
createMessage: A,
|
|
574
574
|
uploadAttachment: h
|
|
575
|
-
} = Nt(), [R, y] = k(), [w, C] = k(), [B, D] = k(""), [ue, Je] = k("medium"), [pe,
|
|
575
|
+
} = Nt(), [R, y] = k(), [w, C] = k(), [B, D] = k(""), [ue, Je] = k("medium"), [pe, Ve] = k("visual"), [me, ge] = k(""), [fe, qe] = k(
|
|
576
576
|
((Fe = c[0]) == null ? void 0 : Fe.value) ?? "desktop"
|
|
577
|
-
), [S, H] = k(), [M, $] = k("review"), [Ge, be] = k(!1), [j, ve] = k("all"), [O, we] = k("all"), [K, ye] = k("all"), [J, Se] = k("all"), [
|
|
578
|
-
const
|
|
579
|
-
return u != null && u.email &&
|
|
577
|
+
), [S, H] = k(), [M, $] = k("review"), [Ge, be] = k(!1), [j, ve] = k("all"), [O, we] = k("all"), [K, ye] = k("all"), [J, Se] = k("all"), [V, ke] = k("all"), [Ye, Xe] = k(!1), [Qe, Ce] = k({}), [se, oe] = k(""), ee = We(null), I = !!u, T = p.includes("create"), Ne = p.includes("reply"), xe = p.includes("update"), Ze = p.includes("assign"), P = R ?? w, et = !!w, tt = !!(f.captureScreenshot && (f.uploadAttachment || g.uploadAttachment)), nt = re(() => {
|
|
578
|
+
const a = d.map((m) => m.assigneeEmail).filter((m) => !!m);
|
|
579
|
+
return u != null && u.email && a.push(u.email), Array.from(new Set(a)).sort((m, l) => m.localeCompare(l));
|
|
580
580
|
}, [u == null ? void 0 : u.email, d]), L = re(
|
|
581
|
-
() => d.filter((
|
|
581
|
+
() => d.filter((a) => r || a.status !== "resolved").filter((a) => j === "all" || a.status === j).filter((a) => O === "all" || a.severity === O).filter((a) => K === "all" || a.category === K).filter((a) => J === "all" || a.assigneeEmail === J).filter((a) => V === "all" || a.viewportPreset === V),
|
|
582
582
|
[
|
|
583
583
|
J,
|
|
584
584
|
K,
|
|
585
585
|
d,
|
|
586
586
|
O,
|
|
587
|
-
|
|
587
|
+
r,
|
|
588
588
|
j,
|
|
589
|
-
|
|
589
|
+
V
|
|
590
590
|
]
|
|
591
591
|
), it = [
|
|
592
592
|
j,
|
|
593
593
|
O,
|
|
594
594
|
K,
|
|
595
595
|
J,
|
|
596
|
-
|
|
597
|
-
].filter((
|
|
596
|
+
V
|
|
597
|
+
].filter((a) => a !== "all").length;
|
|
598
598
|
_(() => {
|
|
599
599
|
e || (y(void 0), C(void 0), D(""), oe(""), $("review"));
|
|
600
600
|
}, [e]), _(() => {
|
|
601
601
|
I || (y(void 0), C(void 0));
|
|
602
602
|
}, [I]), _(() => {
|
|
603
603
|
!w || M !== "review" || window.requestAnimationFrame(() => {
|
|
604
|
-
var
|
|
605
|
-
(m = (
|
|
604
|
+
var a, m, l;
|
|
605
|
+
(m = (a = ee.current) == null ? void 0 : a.scrollIntoView) == null || m.call(a, { block: "nearest" }), (l = ee.current) == null || l.focus();
|
|
606
606
|
});
|
|
607
607
|
}, [w, M]), _(() => {
|
|
608
608
|
if (!S)
|
|
609
609
|
return;
|
|
610
|
-
let
|
|
610
|
+
let a = !0;
|
|
611
611
|
return x(S.id).then((m) => {
|
|
612
|
-
|
|
612
|
+
a && Ce((l) => ({ ...l, [S.id]: m }));
|
|
613
613
|
}), () => {
|
|
614
|
-
|
|
614
|
+
a = !1;
|
|
615
615
|
};
|
|
616
616
|
}, [x, S]), _(() => {
|
|
617
617
|
if (!e || !s || S || d.length === 0)
|
|
618
618
|
return;
|
|
619
|
-
const
|
|
620
|
-
m &&
|
|
619
|
+
const a = new URL(window.location.href).searchParams.get("reviewLensFeedback"), m = d.find((l) => l.id === a);
|
|
620
|
+
m && q(m, { syncUrl: !1 });
|
|
621
621
|
}, [d, e, S, s]), _(() => {
|
|
622
622
|
if (!e)
|
|
623
623
|
return;
|
|
624
|
-
function
|
|
624
|
+
function a(l) {
|
|
625
625
|
var N;
|
|
626
626
|
if (l.key === "Shift" && be(!0), l.key === "Escape") {
|
|
627
627
|
l.preventDefault(), t == null || t(!1);
|
|
628
628
|
return;
|
|
629
629
|
}
|
|
630
|
-
|
|
630
|
+
Jt(l.target) || ((l.key === "n" || l.key === "ArrowDown") && (l.preventDefault(), Ee(1)), (l.key === "p" || l.key === "ArrowUp") && (l.preventDefault(), Ee(-1)), l.key === "c" && (l.preventDefault(), $("review"), (N = ee.current) == null || N.focus()), l.key === "f" && S && xe && (l.preventDefault(), Le(S)));
|
|
631
631
|
}
|
|
632
632
|
function m(l) {
|
|
633
633
|
l.key === "Shift" && be(!1);
|
|
634
634
|
}
|
|
635
|
-
return window.addEventListener("keydown",
|
|
636
|
-
window.removeEventListener("keydown",
|
|
635
|
+
return window.addEventListener("keydown", a), window.addEventListener("keyup", m), () => {
|
|
636
|
+
window.removeEventListener("keydown", a), window.removeEventListener("keyup", m);
|
|
637
637
|
};
|
|
638
638
|
});
|
|
639
|
-
const le = W((
|
|
640
|
-
const m =
|
|
639
|
+
const le = W((a) => {
|
|
640
|
+
const m = a.target instanceof Element ? a.target : null;
|
|
641
641
|
if (m)
|
|
642
642
|
return m.closest("[data-review-lens-ui]") ? null : m;
|
|
643
|
-
const l = document.elementFromPoint(
|
|
643
|
+
const l = document.elementFromPoint(a.clientX, a.clientY);
|
|
644
644
|
return !l || l.closest("[data-review-lens-ui]") ? null : l;
|
|
645
645
|
}, []);
|
|
646
646
|
if (_(() => {
|
|
647
647
|
if (!e || !I)
|
|
648
648
|
return;
|
|
649
|
-
function
|
|
649
|
+
function a(l) {
|
|
650
650
|
const N = le(l);
|
|
651
651
|
y(N ? X(N) : void 0);
|
|
652
652
|
}
|
|
@@ -654,18 +654,18 @@ function Qt({
|
|
|
654
654
|
const N = le(l);
|
|
655
655
|
N && (l.preventDefault(), l.stopPropagation(), C(X(N)), $("review"));
|
|
656
656
|
}
|
|
657
|
-
return window.addEventListener("mousemove",
|
|
658
|
-
window.removeEventListener("mousemove",
|
|
657
|
+
return window.addEventListener("mousemove", a, !0), window.addEventListener("click", m, !0), () => {
|
|
658
|
+
window.removeEventListener("mousemove", a, !0), window.removeEventListener("click", m, !0);
|
|
659
659
|
};
|
|
660
660
|
}, [I, le, e]), !e)
|
|
661
661
|
return null;
|
|
662
|
-
function
|
|
662
|
+
function q(a, m = { syncUrl: !0 }) {
|
|
663
663
|
var N;
|
|
664
|
-
if (H(
|
|
664
|
+
if (H(a), C(void 0), $("feedback"), s && m.syncUrl !== !1) {
|
|
665
665
|
const te = new URL(window.location.href);
|
|
666
|
-
te.searchParams.set("reviewLensFeedback",
|
|
666
|
+
te.searchParams.set("reviewLensFeedback", a.id), window.history.replaceState({}, "", te);
|
|
667
667
|
}
|
|
668
|
-
const l = z(
|
|
668
|
+
const l = z(a.selector);
|
|
669
669
|
if (!l) {
|
|
670
670
|
y(void 0);
|
|
671
671
|
return;
|
|
@@ -674,16 +674,16 @@ function Qt({
|
|
|
674
674
|
y(X(l));
|
|
675
675
|
});
|
|
676
676
|
}
|
|
677
|
-
function Ee(
|
|
677
|
+
function Ee(a) {
|
|
678
678
|
if (L.length === 0)
|
|
679
679
|
return;
|
|
680
|
-
const m = S ? L.findIndex((N) => N.id === S.id) : -1, l = m < 0 ?
|
|
681
|
-
|
|
680
|
+
const m = S ? L.findIndex((N) => N.id === S.id) : -1, l = m < 0 ? a > 0 ? 0 : L.length - 1 : (m + a + L.length) % L.length;
|
|
681
|
+
q(L[l]);
|
|
682
682
|
}
|
|
683
683
|
async function Ae() {
|
|
684
684
|
if (!w || !B.trim() || !u || !T)
|
|
685
685
|
return;
|
|
686
|
-
let
|
|
686
|
+
let a = await b({
|
|
687
687
|
projectKey: f.projectKey,
|
|
688
688
|
contentId: f.contentId,
|
|
689
689
|
normalizedPath: v,
|
|
@@ -706,29 +706,29 @@ function Qt({
|
|
|
706
706
|
});
|
|
707
707
|
if (f.captureScreenshot)
|
|
708
708
|
try {
|
|
709
|
-
const m = await f.captureScreenshot(w), l = await h(
|
|
709
|
+
const m = await f.captureScreenshot(w), l = await h(a.id, {
|
|
710
710
|
type: "screenshot",
|
|
711
711
|
data: m,
|
|
712
712
|
createdBy: u.email
|
|
713
713
|
});
|
|
714
|
-
|
|
714
|
+
a = await E(a.id, {
|
|
715
715
|
attachments: [l],
|
|
716
716
|
screenshotUrl: l.url,
|
|
717
717
|
screenshotThumbnailUrl: l.thumbnailUrl
|
|
718
718
|
});
|
|
719
719
|
} catch {
|
|
720
720
|
}
|
|
721
|
-
D(""), ge(""), C(void 0), y(void 0), $("feedback"), H(
|
|
721
|
+
D(""), ge(""), C(void 0), y(void 0), $("feedback"), H(a);
|
|
722
722
|
}
|
|
723
|
-
async function rt(
|
|
724
|
-
const l = (/* @__PURE__ */ new Date()).toISOString(), N = m === "resolved" ? { status: m, resolvedAt: l, resolvedBy: u == null ? void 0 : u.email } : { status: m }, te = await E(
|
|
723
|
+
async function rt(a, m) {
|
|
724
|
+
const l = (/* @__PURE__ */ new Date()).toISOString(), N = m === "resolved" ? { status: m, resolvedAt: l, resolvedBy: u == null ? void 0 : u.email } : { status: m }, te = await E(a.id, N);
|
|
725
725
|
H(te);
|
|
726
726
|
}
|
|
727
|
-
async function Le(
|
|
728
|
-
const m = z(
|
|
727
|
+
async function Le(a) {
|
|
728
|
+
const m = z(a.selector);
|
|
729
729
|
if (!m || !u)
|
|
730
730
|
return;
|
|
731
|
-
const l = X(m), N = await E(
|
|
731
|
+
const l = X(m), N = await E(a.id, {
|
|
732
732
|
status: "fixed",
|
|
733
733
|
fixedCssSnapshot: l.cssSnapshot,
|
|
734
734
|
fixedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -736,17 +736,17 @@ function Qt({
|
|
|
736
736
|
});
|
|
737
737
|
H(N);
|
|
738
738
|
}
|
|
739
|
-
async function at(
|
|
739
|
+
async function at(a) {
|
|
740
740
|
if (!se.trim() || !u || !Ne)
|
|
741
741
|
return;
|
|
742
742
|
const m = await A({
|
|
743
|
-
feedbackId:
|
|
743
|
+
feedbackId: a.id,
|
|
744
744
|
body: se.trim(),
|
|
745
745
|
authorEmail: u.email
|
|
746
746
|
});
|
|
747
747
|
Ce((l) => ({
|
|
748
748
|
...l,
|
|
749
|
-
[
|
|
749
|
+
[a.id]: [...l[a.id] ?? [], m]
|
|
750
750
|
})), oe("");
|
|
751
751
|
}
|
|
752
752
|
return /* @__PURE__ */ o("div", { className: "review-lens-root", "data-review-lens-ui": !0, children: [
|
|
@@ -758,7 +758,7 @@ function Qt({
|
|
|
758
758
|
{
|
|
759
759
|
feedback: L,
|
|
760
760
|
selectedFeedback: S,
|
|
761
|
-
onSelect:
|
|
761
|
+
onSelect: q
|
|
762
762
|
}
|
|
763
763
|
),
|
|
764
764
|
/* @__PURE__ */ i(
|
|
@@ -766,7 +766,7 @@ function Qt({
|
|
|
766
766
|
{
|
|
767
767
|
feedback: L,
|
|
768
768
|
selectedFeedback: S,
|
|
769
|
-
onSelect:
|
|
769
|
+
onSelect: q
|
|
770
770
|
}
|
|
771
771
|
)
|
|
772
772
|
] }) : null,
|
|
@@ -834,8 +834,8 @@ function Qt({
|
|
|
834
834
|
"form",
|
|
835
835
|
{
|
|
836
836
|
className: "review-lens-feedback-form",
|
|
837
|
-
onSubmit: (
|
|
838
|
-
|
|
837
|
+
onSubmit: (a) => {
|
|
838
|
+
a.preventDefault(), Ae();
|
|
839
839
|
},
|
|
840
840
|
children: [
|
|
841
841
|
/* @__PURE__ */ i("label", { htmlFor: "review-lens-comment", children: "New feedback" }),
|
|
@@ -846,9 +846,9 @@ function Qt({
|
|
|
846
846
|
id: "review-lens-comment",
|
|
847
847
|
value: B,
|
|
848
848
|
disabled: !T,
|
|
849
|
-
onChange: (
|
|
850
|
-
onKeyDown: (
|
|
851
|
-
|
|
849
|
+
onChange: (a) => D(a.target.value),
|
|
850
|
+
onKeyDown: (a) => {
|
|
851
|
+
a.key === "Enter" && a.metaKey && (a.preventDefault(), Ae());
|
|
852
852
|
},
|
|
853
853
|
placeholder: T ? "Describe the UX issue..." : "You do not have permission to comment."
|
|
854
854
|
}
|
|
@@ -860,9 +860,9 @@ function Qt({
|
|
|
860
860
|
"select",
|
|
861
861
|
{
|
|
862
862
|
value: ue,
|
|
863
|
-
onChange: (
|
|
863
|
+
onChange: (a) => Je(a.target.value),
|
|
864
864
|
disabled: !T,
|
|
865
|
-
children: je.map((
|
|
865
|
+
children: je.map((a) => /* @__PURE__ */ i("option", { value: a, children: Q[a] }, a))
|
|
866
866
|
}
|
|
867
867
|
)
|
|
868
868
|
] }),
|
|
@@ -872,9 +872,9 @@ function Qt({
|
|
|
872
872
|
"select",
|
|
873
873
|
{
|
|
874
874
|
value: pe,
|
|
875
|
-
onChange: (
|
|
875
|
+
onChange: (a) => Ve(a.target.value),
|
|
876
876
|
disabled: !T,
|
|
877
|
-
children: Oe.map((
|
|
877
|
+
children: Oe.map((a) => /* @__PURE__ */ i("option", { value: a, children: Z[a] }, a))
|
|
878
878
|
}
|
|
879
879
|
)
|
|
880
880
|
] }),
|
|
@@ -884,7 +884,7 @@ function Qt({
|
|
|
884
884
|
"input",
|
|
885
885
|
{
|
|
886
886
|
value: me,
|
|
887
|
-
onChange: (
|
|
887
|
+
onChange: (a) => ge(a.target.value),
|
|
888
888
|
disabled: !T,
|
|
889
889
|
placeholder: "optional@email.com"
|
|
890
890
|
}
|
|
@@ -896,9 +896,9 @@ function Qt({
|
|
|
896
896
|
"select",
|
|
897
897
|
{
|
|
898
898
|
value: fe,
|
|
899
|
-
onChange: (
|
|
899
|
+
onChange: (a) => qe(a.target.value),
|
|
900
900
|
disabled: !T,
|
|
901
|
-
children: c.map((
|
|
901
|
+
children: c.map((a) => /* @__PURE__ */ i("option", { value: a.value, children: a.label }, a.value))
|
|
902
902
|
}
|
|
903
903
|
)
|
|
904
904
|
] })
|
|
@@ -926,7 +926,7 @@ function Qt({
|
|
|
926
926
|
severityFilter: O,
|
|
927
927
|
categoryFilter: K,
|
|
928
928
|
assigneeFilter: J,
|
|
929
|
-
viewportFilter:
|
|
929
|
+
viewportFilter: V,
|
|
930
930
|
assignees: nt,
|
|
931
931
|
responsivePresets: c,
|
|
932
932
|
onStatusChange: ve,
|
|
@@ -934,7 +934,7 @@ function Qt({
|
|
|
934
934
|
onCategoryChange: ye,
|
|
935
935
|
onAssigneeChange: Se,
|
|
936
936
|
onViewportChange: ke,
|
|
937
|
-
onToggle: () => Xe((
|
|
937
|
+
onToggle: () => Xe((a) => !a),
|
|
938
938
|
onClear: () => {
|
|
939
939
|
ve("all"), we("all"), ye("all"), Se("all"), ke("all");
|
|
940
940
|
}
|
|
@@ -947,14 +947,14 @@ function Qt({
|
|
|
947
947
|
] }),
|
|
948
948
|
/* @__PURE__ */ o("div", { className: "review-lens-comments__list", children: [
|
|
949
949
|
L.length === 0 ? /* @__PURE__ */ i("p", { children: "No feedback for this view." }) : null,
|
|
950
|
-
L.map((
|
|
950
|
+
L.map((a) => /* @__PURE__ */ i(
|
|
951
951
|
Tt,
|
|
952
952
|
{
|
|
953
|
-
item:
|
|
954
|
-
selected: (S == null ? void 0 : S.id) ===
|
|
955
|
-
onSelect:
|
|
953
|
+
item: a,
|
|
954
|
+
selected: (S == null ? void 0 : S.id) === a.id,
|
|
955
|
+
onSelect: q
|
|
956
956
|
},
|
|
957
|
-
|
|
957
|
+
a.id
|
|
958
958
|
))
|
|
959
959
|
] })
|
|
960
960
|
] }),
|
|
@@ -971,9 +971,9 @@ function Qt({
|
|
|
971
971
|
canAssign: Ze,
|
|
972
972
|
onMessageDraftChange: oe,
|
|
973
973
|
onSubmitMessage: () => void at(S),
|
|
974
|
-
onStatusChange: (
|
|
975
|
-
onAssigneeChange: (
|
|
976
|
-
assigneeEmail:
|
|
974
|
+
onStatusChange: (a) => void rt(S, a),
|
|
975
|
+
onAssigneeChange: (a) => void E(S.id, {
|
|
976
|
+
assigneeEmail: a.trim() || void 0
|
|
977
977
|
}).then(H),
|
|
978
978
|
onMarkFixed: () => void Le(S)
|
|
979
979
|
},
|
|
@@ -993,7 +993,7 @@ function It({
|
|
|
993
993
|
open: e,
|
|
994
994
|
activeCount: t,
|
|
995
995
|
statusFilter: n,
|
|
996
|
-
severityFilter:
|
|
996
|
+
severityFilter: r,
|
|
997
997
|
categoryFilter: s,
|
|
998
998
|
assigneeFilter: c,
|
|
999
999
|
viewportFilter: g,
|
|
@@ -1037,7 +1037,7 @@ function It({
|
|
|
1037
1037
|
"select",
|
|
1038
1038
|
{
|
|
1039
1039
|
"aria-label": "Filter severity",
|
|
1040
|
-
value:
|
|
1040
|
+
value: r,
|
|
1041
1041
|
onChange: (h) => v(h.target.value),
|
|
1042
1042
|
children: [
|
|
1043
1043
|
/* @__PURE__ */ i("option", { value: "all", children: "All priorities" }),
|
|
@@ -1099,7 +1099,7 @@ function Tt({
|
|
|
1099
1099
|
selected: t,
|
|
1100
1100
|
onSelect: n
|
|
1101
1101
|
}) {
|
|
1102
|
-
const
|
|
1102
|
+
const r = Ke(e);
|
|
1103
1103
|
return /* @__PURE__ */ o(
|
|
1104
1104
|
"article",
|
|
1105
1105
|
{
|
|
@@ -1128,7 +1128,7 @@ function Tt({
|
|
|
1128
1128
|
/* @__PURE__ */ o("div", { className: "review-lens-tags", children: [
|
|
1129
1129
|
/* @__PURE__ */ i("span", { children: Z[e.category] }),
|
|
1130
1130
|
/* @__PURE__ */ i("span", { children: e.viewportPreset }),
|
|
1131
|
-
/* @__PURE__ */ i("span", { children:
|
|
1131
|
+
/* @__PURE__ */ i("span", { children: r.label })
|
|
1132
1132
|
] })
|
|
1133
1133
|
]
|
|
1134
1134
|
}
|
|
@@ -1138,7 +1138,7 @@ function Rt({
|
|
|
1138
1138
|
item: e,
|
|
1139
1139
|
messages: t,
|
|
1140
1140
|
messageDraft: n,
|
|
1141
|
-
canReply:
|
|
1141
|
+
canReply: r,
|
|
1142
1142
|
canUpdate: s,
|
|
1143
1143
|
canAssign: c,
|
|
1144
1144
|
onMessageDraftChange: g,
|
|
@@ -1234,12 +1234,12 @@ function Rt({
|
|
|
1234
1234
|
{
|
|
1235
1235
|
"aria-label": "Reply",
|
|
1236
1236
|
value: n,
|
|
1237
|
-
disabled: !
|
|
1237
|
+
disabled: !r,
|
|
1238
1238
|
onChange: (b) => g(b.target.value),
|
|
1239
|
-
placeholder:
|
|
1239
|
+
placeholder: r ? "Reply..." : "You do not have permission to reply."
|
|
1240
1240
|
}
|
|
1241
1241
|
),
|
|
1242
|
-
/* @__PURE__ */ i("div", { className: "review-lens-actions", children: /* @__PURE__ */ i("button", { type: "button", disabled: !n.trim() || !
|
|
1242
|
+
/* @__PURE__ */ i("div", { className: "review-lens-actions", children: /* @__PURE__ */ i("button", { type: "button", disabled: !n.trim() || !r, onClick: f, children: "Reply" }) })
|
|
1243
1243
|
] })
|
|
1244
1244
|
] });
|
|
1245
1245
|
}
|
|
@@ -1255,14 +1255,14 @@ function Bt({ feedback: e }) {
|
|
|
1255
1255
|
function G({ title: e, values: t }) {
|
|
1256
1256
|
return /* @__PURE__ */ o("section", { children: [
|
|
1257
1257
|
/* @__PURE__ */ i("h3", { children: e }),
|
|
1258
|
-
/* @__PURE__ */ i("dl", { children: t.map(([n,
|
|
1258
|
+
/* @__PURE__ */ i("dl", { children: t.map(([n, r]) => /* @__PURE__ */ o("div", { children: [
|
|
1259
1259
|
/* @__PURE__ */ i("dt", { children: n }),
|
|
1260
|
-
/* @__PURE__ */ i("dd", { children:
|
|
1260
|
+
/* @__PURE__ */ i("dd", { children: r })
|
|
1261
1261
|
] }, n)) })
|
|
1262
1262
|
] });
|
|
1263
1263
|
}
|
|
1264
1264
|
function $t({ target: e, locked: t }) {
|
|
1265
|
-
const n =
|
|
1265
|
+
const n = Gt(e), r = Ot(e.fingerprint);
|
|
1266
1266
|
return /* @__PURE__ */ o(
|
|
1267
1267
|
"div",
|
|
1268
1268
|
{
|
|
@@ -1311,7 +1311,7 @@ function $t({ target: e, locked: t }) {
|
|
|
1311
1311
|
}
|
|
1312
1312
|
),
|
|
1313
1313
|
/* @__PURE__ */ o("div", { className: "review-lens-highlight__label", children: [
|
|
1314
|
-
/* @__PURE__ */ i("strong", { children:
|
|
1314
|
+
/* @__PURE__ */ i("strong", { children: r }),
|
|
1315
1315
|
/* @__PURE__ */ o("span", { children: [
|
|
1316
1316
|
Math.round(e.rect.width),
|
|
1317
1317
|
" x ",
|
|
@@ -1323,20 +1323,20 @@ function $t({ target: e, locked: t }) {
|
|
|
1323
1323
|
);
|
|
1324
1324
|
}
|
|
1325
1325
|
function _t({ from: e, to: t }) {
|
|
1326
|
-
const n =
|
|
1327
|
-
return n.length === 0 ? null : /* @__PURE__ */ i(ie, { children: n.map((
|
|
1326
|
+
const n = Kt(e.rect, t.rect);
|
|
1327
|
+
return n.length === 0 ? null : /* @__PURE__ */ i(ie, { children: n.map((r) => /* @__PURE__ */ i(
|
|
1328
1328
|
"div",
|
|
1329
1329
|
{
|
|
1330
|
-
className: `review-lens-distance review-lens-distance--${
|
|
1330
|
+
className: `review-lens-distance review-lens-distance--${r.axis}`,
|
|
1331
1331
|
style: {
|
|
1332
|
-
top:
|
|
1333
|
-
left:
|
|
1334
|
-
width:
|
|
1335
|
-
height:
|
|
1332
|
+
top: r.top,
|
|
1333
|
+
left: r.left,
|
|
1334
|
+
width: r.width,
|
|
1335
|
+
height: r.height
|
|
1336
1336
|
},
|
|
1337
|
-
children: /* @__PURE__ */ i("span", { children:
|
|
1337
|
+
children: /* @__PURE__ */ i("span", { children: r.label })
|
|
1338
1338
|
},
|
|
1339
|
-
|
|
1339
|
+
r.key
|
|
1340
1340
|
)) });
|
|
1341
1341
|
}
|
|
1342
1342
|
function Pt({
|
|
@@ -1344,14 +1344,14 @@ function Pt({
|
|
|
1344
1344
|
selectedFeedback: t,
|
|
1345
1345
|
onSelect: n
|
|
1346
1346
|
}) {
|
|
1347
|
-
return /* @__PURE__ */ i(ie, { children: e.map((
|
|
1347
|
+
return /* @__PURE__ */ i(ie, { children: e.map((r) => /* @__PURE__ */ i(
|
|
1348
1348
|
Ut,
|
|
1349
1349
|
{
|
|
1350
|
-
feedback:
|
|
1351
|
-
selected: (t == null ? void 0 : t.id) ===
|
|
1350
|
+
feedback: r,
|
|
1351
|
+
selected: (t == null ? void 0 : t.id) === r.id,
|
|
1352
1352
|
onSelect: n
|
|
1353
1353
|
},
|
|
1354
|
-
|
|
1354
|
+
r.id
|
|
1355
1355
|
)) });
|
|
1356
1356
|
}
|
|
1357
1357
|
function Ut({
|
|
@@ -1359,12 +1359,12 @@ function Ut({
|
|
|
1359
1359
|
selected: t,
|
|
1360
1360
|
onSelect: n
|
|
1361
1361
|
}) {
|
|
1362
|
-
const
|
|
1362
|
+
const r = We(null);
|
|
1363
1363
|
return lt(() => {
|
|
1364
1364
|
let s = 0;
|
|
1365
1365
|
const c = () => {
|
|
1366
1366
|
s = 0;
|
|
1367
|
-
const f =
|
|
1367
|
+
const f = r.current, u = z(e.selector), d = u == null ? void 0 : u.getBoundingClientRect();
|
|
1368
1368
|
!f || !d || (f.style.top = `${d.top}px`, f.style.left = `${d.right}px`, f.hidden = d.bottom < 0 || d.top > window.innerHeight);
|
|
1369
1369
|
}, g = () => {
|
|
1370
1370
|
s || (s = window.requestAnimationFrame(c));
|
|
@@ -1375,7 +1375,7 @@ function Ut({
|
|
|
1375
1375
|
}, [e.selector]), /* @__PURE__ */ i(
|
|
1376
1376
|
"button",
|
|
1377
1377
|
{
|
|
1378
|
-
ref:
|
|
1378
|
+
ref: r,
|
|
1379
1379
|
type: "button",
|
|
1380
1380
|
className: t ? "review-lens-marker review-lens-marker--selected" : "review-lens-marker",
|
|
1381
1381
|
onClick: () => n(e),
|
|
@@ -1388,7 +1388,7 @@ function Wt({
|
|
|
1388
1388
|
selectedFeedback: t,
|
|
1389
1389
|
onSelect: n
|
|
1390
1390
|
}) {
|
|
1391
|
-
const
|
|
1391
|
+
const r = e.map((s) => {
|
|
1392
1392
|
const c = z(s.selector), g = c == null ? void 0 : c.getBoundingClientRect(), f = Math.max(
|
|
1393
1393
|
document.documentElement.scrollHeight,
|
|
1394
1394
|
document.body.scrollHeight,
|
|
@@ -1399,7 +1399,7 @@ function Wt({
|
|
|
1399
1399
|
top: Math.min(100, Math.max(0, (g.top + window.scrollY) / f * 100))
|
|
1400
1400
|
};
|
|
1401
1401
|
}).filter((s) => s !== null);
|
|
1402
|
-
return
|
|
1402
|
+
return r.length === 0 ? null : /* @__PURE__ */ i("div", { className: "review-lens-minimap", "data-review-lens-ui": !0, "aria-label": "Feedback map", children: r.map((s) => /* @__PURE__ */ i(
|
|
1403
1403
|
"button",
|
|
1404
1404
|
{
|
|
1405
1405
|
type: "button",
|
|
@@ -1424,9 +1424,9 @@ function Dt({ target: e }) {
|
|
|
1424
1424
|
["Color", e.cssSnapshot.color],
|
|
1425
1425
|
["Background", e.cssSnapshot.backgroundColor]
|
|
1426
1426
|
];
|
|
1427
|
-
return /* @__PURE__ */ i("dl", { className: "review-lens-metrics", children: t.map(([n,
|
|
1427
|
+
return /* @__PURE__ */ i("dl", { className: "review-lens-metrics", children: t.map(([n, r]) => /* @__PURE__ */ o("div", { children: [
|
|
1428
1428
|
/* @__PURE__ */ i("dt", { children: n }),
|
|
1429
|
-
/* @__PURE__ */ i("dd", { children:
|
|
1429
|
+
/* @__PURE__ */ i("dd", { children: r })
|
|
1430
1430
|
] }, n)) });
|
|
1431
1431
|
}
|
|
1432
1432
|
function _e({ title: e, items: t }) {
|
|
@@ -1455,24 +1455,32 @@ function zt(e) {
|
|
|
1455
1455
|
const t = z(e.selector);
|
|
1456
1456
|
if (!t)
|
|
1457
1457
|
return ["Selected element is no longer available."];
|
|
1458
|
-
const n = [],
|
|
1459
|
-
c && !g && n.push("Interactive element has no accessible name."), c && (e.rect.width < 44 || e.rect.height < 44) && n.push("Tap target is smaller than 44 x 44."),
|
|
1460
|
-
const f = /^h[1-6]$/.test(
|
|
1461
|
-
return f > 1 && !document.querySelector(`h${f - 1}`) && n.push("Heading may skip the previous level."),
|
|
1458
|
+
const n = [], r = t.tagName.toLowerCase(), s = t.getAttribute("role"), c = ["button", "a", "input", "select", "textarea"].includes(r) || s === "button" || s === "link", g = t.getAttribute("aria-label") || t.getAttribute("title") || ((u = t.textContent) == null ? void 0 : u.trim());
|
|
1459
|
+
c && !g && n.push("Interactive element has no accessible name."), c && (e.rect.width < 44 || e.rect.height < 44) && n.push("Tap target is smaller than 44 x 44."), r === "img" && !t.getAttribute("alt") && n.push("Image is missing alt text.");
|
|
1460
|
+
const f = /^h[1-6]$/.test(r) ? Number(r.slice(1)) : 0;
|
|
1461
|
+
return f > 1 && !document.querySelector(`h${f - 1}`) && n.push("Heading may skip the previous level."), Vt(e.cssSnapshot.color, e.cssSnapshot.backgroundColor) && n.push("Text contrast may be low."), n;
|
|
1462
1462
|
}
|
|
1463
1463
|
function Ht(e, t = {}) {
|
|
1464
1464
|
const n = [];
|
|
1465
|
-
return U("Padding", e.padding, t.spacing, n), U("Margin", e.margin, t.spacing, n), U("Font size", e.fontSize, t.fontSize, n), U("Line height", e.lineHeight, t.lineHeight, n), U("Text color", e.color, t.color, n), U("Background", e.backgroundColor, t.color, n), U("Radius", e.borderRadius, t.radius, n), n;
|
|
1465
|
+
return U("Padding", e.padding, t.spacing, n, { allowComposite: !0 }), U("Margin", e.margin, t.spacing, n, { allowComposite: !0 }), U("Font size", e.fontSize, t.fontSize, n), U("Line height", e.lineHeight, t.lineHeight, n), U("Text color", e.color, t.color, n), U("Background", e.backgroundColor, t.color, n), U("Radius", e.borderRadius, t.radius, n, { allowComposite: !0 }), n;
|
|
1466
1466
|
}
|
|
1467
|
-
function U(e, t, n,
|
|
1468
|
-
!n || n.length === 0 || !t ||
|
|
1467
|
+
function U(e, t, n, r, s = {}) {
|
|
1468
|
+
!n || n.length === 0 || !t || jt(t, n, s) || r.push(`${e} ${t} is outside configured tokens.`);
|
|
1469
1469
|
}
|
|
1470
|
-
function jt(e) {
|
|
1471
|
-
|
|
1472
|
-
|
|
1470
|
+
function jt(e, t, n = {}) {
|
|
1471
|
+
if (t.includes(e))
|
|
1472
|
+
return !0;
|
|
1473
|
+
if (!n.allowComposite)
|
|
1474
|
+
return !1;
|
|
1475
|
+
const r = e.trim().split(/\s+/);
|
|
1476
|
+
return r.length > 1 && r.every((s) => t.includes(s));
|
|
1473
1477
|
}
|
|
1474
|
-
function Ot(e
|
|
1475
|
-
const
|
|
1478
|
+
function Ot(e) {
|
|
1479
|
+
const t = e.id ? `#${e.id}` : "", n = e.className ? `.${e.className.split(/\s+/).filter(Boolean).slice(0, 2).join(".")}` : "", r = e.ariaLabel ? `[aria-label="${e.ariaLabel}"]` : "";
|
|
1480
|
+
return `${e.tagName}${t}${n}${r}` || e.tagName;
|
|
1481
|
+
}
|
|
1482
|
+
function Kt(e, t) {
|
|
1483
|
+
const n = [], r = (Math.max(e.left, t.left) + Math.min(e.right, t.right)) / 2, s = (Math.max(e.top, t.top) + Math.min(e.bottom, t.bottom)) / 2;
|
|
1476
1484
|
if (e.right <= t.left || t.right <= e.left) {
|
|
1477
1485
|
const c = e.right <= t.left ? e.right : t.right, g = e.right <= t.left ? t.left : e.left;
|
|
1478
1486
|
n.push({
|
|
@@ -1491,7 +1499,7 @@ function Ot(e, t) {
|
|
|
1491
1499
|
key: "vertical",
|
|
1492
1500
|
axis: "vertical",
|
|
1493
1501
|
top: c,
|
|
1494
|
-
left: Pe(
|
|
1502
|
+
left: Pe(r, 0, window.innerWidth),
|
|
1495
1503
|
width: 1,
|
|
1496
1504
|
height: Math.max(g - c, 1),
|
|
1497
1505
|
label: `${Math.round(g - c)}px`
|
|
@@ -1504,43 +1512,43 @@ function Pe(e, t, n) {
|
|
|
1504
1512
|
}
|
|
1505
1513
|
function Y(e, t) {
|
|
1506
1514
|
const n = /* @__PURE__ */ new Map();
|
|
1507
|
-
for (const
|
|
1508
|
-
const s = t(
|
|
1515
|
+
for (const r of e) {
|
|
1516
|
+
const s = t(r);
|
|
1509
1517
|
n.set(s, (n.get(s) ?? 0) + 1);
|
|
1510
1518
|
}
|
|
1511
|
-
return Array.from(n.entries()).sort((
|
|
1519
|
+
return Array.from(n.entries()).sort((r, s) => s[1] - r[1] || r[0].localeCompare(s[0]));
|
|
1512
1520
|
}
|
|
1513
|
-
function
|
|
1521
|
+
function Jt(e) {
|
|
1514
1522
|
return e instanceof HTMLInputElement || e instanceof HTMLTextAreaElement || e instanceof HTMLSelectElement || e instanceof HTMLElement && e.isContentEditable;
|
|
1515
1523
|
}
|
|
1516
|
-
function
|
|
1517
|
-
const n = Ue(e),
|
|
1518
|
-
return !n || !
|
|
1524
|
+
function Vt(e, t) {
|
|
1525
|
+
const n = Ue(e), r = Ue(t);
|
|
1526
|
+
return !n || !r || r.alpha === 0 ? !1 : qt(n, r) < 4.5;
|
|
1519
1527
|
}
|
|
1520
1528
|
function Ue(e) {
|
|
1521
1529
|
const t = e.match(/rgba?\(([^)]+)\)/);
|
|
1522
1530
|
if (!t)
|
|
1523
1531
|
return null;
|
|
1524
|
-
const [n,
|
|
1532
|
+
const [n, r, s, c = "1"] = t[1].split(",").map((g) => g.trim());
|
|
1525
1533
|
return {
|
|
1526
1534
|
red: Number(n),
|
|
1527
|
-
green: Number(
|
|
1535
|
+
green: Number(r),
|
|
1528
1536
|
blue: Number(s),
|
|
1529
1537
|
alpha: Number(c)
|
|
1530
1538
|
};
|
|
1531
1539
|
}
|
|
1532
1540
|
function qt(e, t) {
|
|
1533
|
-
const n = Math.max(ne(e), ne(t)),
|
|
1534
|
-
return (n + 0.05) / (
|
|
1541
|
+
const n = Math.max(ne(e), ne(t)), r = Math.min(ne(e), ne(t));
|
|
1542
|
+
return (n + 0.05) / (r + 0.05);
|
|
1535
1543
|
}
|
|
1536
1544
|
function ne(e) {
|
|
1537
1545
|
const t = [e.red, e.green, e.blue].map((n) => {
|
|
1538
|
-
const
|
|
1539
|
-
return
|
|
1546
|
+
const r = n / 255;
|
|
1547
|
+
return r <= 0.03928 ? r / 12.92 : ((r + 0.055) / 1.055) ** 2.4;
|
|
1540
1548
|
});
|
|
1541
1549
|
return t[0] * 0.2126 + t[1] * 0.7152 + t[2] * 0.0722;
|
|
1542
1550
|
}
|
|
1543
|
-
function
|
|
1551
|
+
function Gt(e) {
|
|
1544
1552
|
const t = {
|
|
1545
1553
|
top: F(e.cssSnapshot.marginTop),
|
|
1546
1554
|
right: F(e.cssSnapshot.marginRight),
|
|
@@ -1551,7 +1559,7 @@ function Vt(e) {
|
|
|
1551
1559
|
right: F(e.cssSnapshot.borderRightWidth),
|
|
1552
1560
|
bottom: F(e.cssSnapshot.borderBottomWidth),
|
|
1553
1561
|
left: F(e.cssSnapshot.borderLeftWidth)
|
|
1554
|
-
},
|
|
1562
|
+
}, r = {
|
|
1555
1563
|
top: F(e.cssSnapshot.paddingTop),
|
|
1556
1564
|
right: F(e.cssSnapshot.paddingRight),
|
|
1557
1565
|
bottom: F(e.cssSnapshot.paddingBottom),
|
|
@@ -1572,10 +1580,10 @@ function Vt(e) {
|
|
|
1572
1580
|
width: Math.max(s.width - n.left - n.right, 0),
|
|
1573
1581
|
height: Math.max(s.height - n.top - n.bottom, 0)
|
|
1574
1582
|
}, f = {
|
|
1575
|
-
top: g.top +
|
|
1576
|
-
left: g.left +
|
|
1577
|
-
width: Math.max(g.width -
|
|
1578
|
-
height: Math.max(g.height -
|
|
1583
|
+
top: g.top + r.top,
|
|
1584
|
+
left: g.left + r.left,
|
|
1585
|
+
width: Math.max(g.width - r.left - r.right, 0),
|
|
1586
|
+
height: Math.max(g.height - r.top - r.bottom, 0)
|
|
1579
1587
|
};
|
|
1580
1588
|
return {
|
|
1581
1589
|
margin: c,
|
|
@@ -1589,8 +1597,8 @@ function F(e) {
|
|
|
1589
1597
|
return Number.isFinite(t) ? t : 0;
|
|
1590
1598
|
}
|
|
1591
1599
|
export {
|
|
1592
|
-
|
|
1593
|
-
|
|
1600
|
+
Zt as ReviewLensOverlay,
|
|
1601
|
+
Qt as ReviewLensProvider,
|
|
1594
1602
|
X as buildElementTarget,
|
|
1595
1603
|
ht as createGoogleSheetsAdapter,
|
|
1596
1604
|
Ct as normalizeReviewUrl,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(x,r){typeof exports=="object"&&typeof module<"u"?r(exports,require("react/jsx-runtime"),require("react")):typeof define=="function"&&define.amd?define(["exports","react/jsx-runtime","react"],r):(x=typeof globalThis<"u"?globalThis:x||self,r(x.ReviewLensReact={},x.jsxRuntime,x.React))})(this,(function(x,r,l){"use strict";const Ke=["https://www.googleapis.com/auth/spreadsheets","https://www.googleapis.com/auth/userinfo.email"].join(" "),Je="https://www.googleapis.com/oauth2/v3/userinfo";function le(e){const t=e.feedbackSheetName??"Feedback",n=e.messagesSheetName??"Messages",a=e.usersSheetName??"Users";let i,d;async function f(){return i??(i=tt(e.googleClientId)),i}async function b(c,w){const u=await f(),v=await fetch(`https://sheets.googleapis.com/v4/spreadsheets/${e.spreadsheetId}${c}`,{...w,headers:{Authorization:`Bearer ${u}`,"Content-Type":"application/json",...w==null?void 0:w.headers}});if(!v.ok)throw new Error(`Google Sheets request failed with ${v.status}`);return v.json()}async function p(c){return(await b(`/values/${encodeURIComponent(c)}`)).values??[]}return{async getCurrentUser(){if(!d){const c=await f(),w=await fetch(Je,{headers:{Authorization:`Bearer ${c}`}});if(!w.ok)throw new Error(`Google userinfo request failed with ${w.status}`);d=(await w.json()).email}if(!d)throw new Error("Google account did not return an email address");return{email:d}},async getPermissions(c){const[{email:w},u]=await Promise.all([this.getCurrentUser(),p(a)]),v=ne(u),E=w.toLowerCase(),N=v.find(A=>{var h;return((h=A.email)==null?void 0:h.toLowerCase())===E&&A.active!=="false"&&(!A.projectKey||A.projectKey===c)});return Ye((N==null?void 0:N.role)??"designer")},async listFeedback(c){return ne(await p(t)).map(pe).filter(u=>u!==null).filter(u=>u.projectKey===c.projectKey&&u.contentId===c.contentId&&u.normalizedPath===c.normalizedPath).sort((u,v)=>v.createdAt.localeCompare(u.createdAt))},async createFeedback(c){const w=new Date().toISOString(),u={...c,id:crypto.randomUUID(),attachments:[],createdAt:w,updatedAt:w};return await b(`/values/${encodeURIComponent(t)}:append?valueInputOption=RAW`,{method:"POST",body:JSON.stringify({values:[ce(u)]})}),u},async updateFeedback(c,w){const u=await p(t),v=u[0]??de,E=v.indexOf("id");if(E===-1)throw new Error(`Sheet ${t} is missing an id column`);const N=u.findIndex((m,k)=>k>0&&m[E]===c);if(N<1)throw new Error(`Feedback ${c} was not found`);const A=new Date().toISOString(),h=pe(he(v,u[N]));if(!h)throw new Error(`Feedback ${c} could not be parsed before updating`);const B={...h,...w,updatedAt:A},y=ce(B);return await b(`/values/${encodeURIComponent(t)}!A${N+1}:${et(de.length)}${N+1}?valueInputOption=RAW`,{method:"PUT",body:JSON.stringify({values:[y]})}),B},async listMessages(c){return ne(await p(n)).map(Ge).filter(u=>u!==null).filter(u=>u.feedbackId===c).sort((u,v)=>u.createdAt.localeCompare(v.createdAt))},async createMessage(c){const w={...c,id:crypto.randomUUID(),createdAt:new Date().toISOString()};return await b(`/values/${encodeURIComponent(n)}:append?valueInputOption=RAW`,{method:"POST",body:JSON.stringify({values:[Ve(w)]})}),w}}}const de=["id","projectKey","contentId","normalizedPath","originalUrl","selector","selectorStrategy","elementFingerprintJson","createdCssSnapshotJson","comment","status","severity","category","assigneeEmail","viewportWidth","viewportHeight","viewportPreset","screenshotUrl","screenshotThumbnailUrl","attachmentJson","authorEmail","createdAt","updatedAt","fixedCssSnapshotJson","fixedAt","fixedBy","resolvedAt","resolvedBy"],qe=["id","feedbackId","body","authorEmail","createdAt"];function ce(e){return[e.id,e.projectKey,e.contentId,e.normalizedPath,e.originalUrl,e.selector,e.selectorStrategy,JSON.stringify(e.elementFingerprint),JSON.stringify(e.createdCssSnapshot),e.comment,e.status,e.severity,e.category,e.assigneeEmail??"",String(e.viewportWidth),String(e.viewportHeight),e.viewportPreset,e.screenshotUrl??"",e.screenshotThumbnailUrl??"",JSON.stringify(e.attachments),e.authorEmail,e.createdAt,e.updatedAt,e.fixedCssSnapshot?JSON.stringify(e.fixedCssSnapshot):"",e.fixedAt??"",e.fixedBy??"",e.resolvedAt??"",e.resolvedBy??""]}function Ve(e){return qe.map(t=>e[t])}function ne(e){const[t,...n]=e;return t?n.map(a=>he(t,a)):[]}function he(e,t){return Object.fromEntries(e.map((n,a)=>[n,t[a]??""]))}function pe(e){return e.id?{id:e.id,projectKey:e.projectKey,contentId:e.contentId,normalizedPath:e.normalizedPath,originalUrl:e.originalUrl,selector:e.selector,selectorStrategy:e.selectorStrategy==="stable-attribute"?"stable-attribute":"css-path",elementFingerprint:re(e.elementFingerprintJson,{tagName:"",width:0,height:0}),createdCssSnapshot:ue(e.createdCssSnapshotJson),fixedCssSnapshot:e.fixedCssSnapshotJson?ue(e.fixedCssSnapshotJson):void 0,comment:e.comment,status:Xe(e.status),severity:Qe(e.severity),category:Ze(e.category),assigneeEmail:e.assigneeEmail||void 0,viewportWidth:Number(e.viewportWidth)||0,viewportHeight:Number(e.viewportHeight)||0,viewportPreset:Re(e.viewportPreset),screenshotUrl:e.screenshotUrl||void 0,screenshotThumbnailUrl:e.screenshotThumbnailUrl||void 0,attachments:re(e.attachmentJson,[]),authorEmail:e.authorEmail,createdAt:e.createdAt,updatedAt:e.updatedAt,fixedAt:e.fixedAt||void 0,fixedBy:e.fixedBy||void 0,resolvedAt:e.resolvedAt||void 0,resolvedBy:e.resolvedBy||void 0}:null}function Ge(e){return!e.id||!e.feedbackId?null:{id:e.id,feedbackId:e.feedbackId,body:e.body,authorEmail:e.authorEmail,createdAt:e.createdAt}}function re(e,t){try{return e?JSON.parse(e):t}catch{return t}}function ue(e){const t=re(e,{});return{margin:t.margin??"",marginTop:t.marginTop??"",marginRight:t.marginRight??"",marginBottom:t.marginBottom??"",marginLeft:t.marginLeft??"",padding:t.padding??"",paddingTop:t.paddingTop??"",paddingRight:t.paddingRight??"",paddingBottom:t.paddingBottom??"",paddingLeft:t.paddingLeft??"",border:t.border??"",borderTopWidth:t.borderTopWidth??"",borderRightWidth:t.borderRightWidth??"",borderBottomWidth:t.borderBottomWidth??"",borderLeftWidth:t.borderLeftWidth??"",fontFamily:t.fontFamily??"",fontSize:t.fontSize??"",lineHeight:t.lineHeight??"",color:t.color??"",backgroundColor:t.backgroundColor??"",borderRadius:t.borderRadius??"",width:t.width??0,height:t.height??0}}function Ye(e){return e==="admin"?["create","read","reply","update","assign"]:e==="developer"?["read","reply","update","assign"]:["create","read","reply"]}function Xe(e){return e==="in_progress"||e==="needs_clarification"||e==="fixed"||e==="wontfix"||e==="resolved"?e:"open"}function Qe(e){return e==="low"||e==="high"?e:"medium"}function Ze(e){return e==="visual"||e==="copy"||e==="accessibility"||e==="responsive"?e:"bug"}function Re(e){return e==="mobile"||e==="tablet"||e==="desktop"?e:"custom"}function et(e){let t=e,n="";for(;t>0;){const a=(t-1)%26;n=String.fromCharCode(65+a)+n,t=Math.floor((t-a)/26)}return n}async function tt(e){return await nt(),new Promise((t,n)=>{var i;const a=(i=window.google)==null?void 0:i.accounts.oauth2.initTokenClient({client_id:e,scope:Ke,callback:d=>{if(d.error||!d.access_token){n(new Error(d.error??"Google OAuth did not return an access token"));return}t(d.access_token)}});a==null||a.requestAccessToken({prompt:""})})}function nt(){var e;return(e=window.google)!=null&&e.accounts.oauth2?Promise.resolve():new Promise((t,n)=>{const a=document.querySelector('script[src="https://accounts.google.com/gsi/client"]');if(a){a.addEventListener("load",()=>t(),{once:!0}),a.addEventListener("error",()=>n(new Error("Google Identity failed to load")),{once:!0});return}const i=document.createElement("script");i.src="https://accounts.google.com/gsi/client",i.async=!0,i.defer=!0,i.onload=()=>t(),i.onerror=()=>n(new Error("Google Identity failed to load")),document.head.append(i)})}function ge(e){return new URL(e,window.location.href).pathname.replace(/\/+$/,"")||"/"}const fe=l.createContext(null);function rt({config:e,children:t}){const n=l.useMemo(()=>e.adapter?e.adapter:le({googleClientId:ve(e.googleClientId,"googleClientId"),spreadsheetId:ve(e.spreadsheetId,"spreadsheetId"),feedbackSheetName:e.sheetName??"Feedback"}),[e.adapter,e.googleClientId,e.sheetName,e.spreadsheetId]),a=e.currentUrl??window.location.href,i=(e.normalizeUrl??ge)(a),[d,f]=l.useState(),[b,p]=l.useState([]),[c,w]=l.useState([]),u=l.useCallback(async()=>{const y=await n.listFeedback({projectKey:e.projectKey,contentId:e.contentId,normalizedPath:i});w(y)},[n,e.contentId,e.projectKey,i]);l.useEffect(()=>{let y=!0;async function m(){const[k,$]=await Promise.all([n.getCurrentUser(),n.getPermissions(e.projectKey)]);y&&(f(k),p($),await u())}return m(),()=>{y=!1}},[n,e.projectKey,u]);const v=l.useCallback(async y=>{const m=await n.createFeedback(y);return w(k=>[m,...k]),m},[n]),E=l.useCallback(async(y,m)=>{const k=await n.updateFeedback(y,m);return w($=>$.map(z=>z.id===y?k:z)),k},[n]),N=l.useCallback(y=>n.listMessages(y),[n]),A=l.useCallback(y=>n.createMessage(y),[n]),h=l.useCallback(async(y,m)=>{const k=e.uploadAttachment??n.uploadAttachment;if(!k)throw new Error("Review Lens attachment upload is not configured");return k(y,m)},[n,e]),B=l.useMemo(()=>({config:e,adapter:n,currentUser:d,permissions:b,feedback:c,normalizedPath:i,refreshFeedback:u,createFeedback:v,updateFeedback:E,listMessages:N,createMessage:A,uploadAttachment:h}),[n,e,v,d,c,i,b,u,E,N,A,h]);return r.jsx(fe.Provider,{value:B,children:t})}function be(){const e=l.useContext(fe);if(!e)throw new Error("useReviewLens must be used inside ReviewLensProvider");return e}function ve(e,t){if(!e)throw new Error(`review-lens-react requires config.${t} when no adapter is provided`);return e}const st=["data-review-id","data-testid","data-test-id","aria-label","name"];function W(e){const t=e.getBoundingClientRect(),n=at(e);return{selector:n.selector,selectorStrategy:n.strategy,fingerprint:ot(e,t),cssSnapshot:lt(e,t),rect:t}}function at(e){for(const t of st){const n=e.getAttribute(t);if(n)return{selector:`[${t}="${we(n)}"]`,strategy:"stable-attribute"}}return e.id?{selector:`#${we(e.id)}`,strategy:"stable-attribute"}:{selector:it(e),strategy:"css-path"}}function it(e){const t=[];let n=e;for(;n&&n.nodeType===Node.ELEMENT_NODE&&n!==document.body;){const a=n.parentElement,i=n.tagName.toLowerCase();if(!a){t.unshift(i);break}const d=n.tagName,f=Array.from(a.children).filter(p=>p.tagName===d),b=f.indexOf(n)+1;t.unshift(f.length>1?`${i}:nth-of-type(${b})`:i),n=a}return t.join(" > ")}function ot(e,t){var n;return{tagName:e.tagName.toLowerCase(),id:e.id||void 0,className:e.getAttribute("class")||void 0,textSnippet:((n=e.textContent)==null?void 0:n.trim().slice(0,80))||void 0,ariaLabel:e.getAttribute("aria-label")||void 0,width:Math.round(t.width),height:Math.round(t.height)}}function lt(e,t){const n=window.getComputedStyle(e);return{margin:se(n.marginTop,n.marginRight,n.marginBottom,n.marginLeft),marginTop:n.marginTop,marginRight:n.marginRight,marginBottom:n.marginBottom,marginLeft:n.marginLeft,padding:se(n.paddingTop,n.paddingRight,n.paddingBottom,n.paddingLeft),paddingTop:n.paddingTop,paddingRight:n.paddingRight,paddingBottom:n.paddingBottom,paddingLeft:n.paddingLeft,border:se(n.borderTopWidth,n.borderRightWidth,n.borderBottomWidth,n.borderLeftWidth),borderTopWidth:n.borderTopWidth,borderRightWidth:n.borderRightWidth,borderBottomWidth:n.borderBottomWidth,borderLeftWidth:n.borderLeftWidth,fontFamily:n.fontFamily,fontSize:n.fontSize,lineHeight:n.lineHeight,color:n.color,backgroundColor:n.backgroundColor,borderRadius:n.borderRadius,width:Math.round(t.width),height:Math.round(t.height)}}function se(e,t,n,a){return e===t&&t===n&&n===a?e:`${e} ${t} ${n} ${a}`}function we(e){return typeof CSS<"u"&&typeof CSS.escape=="function"?CSS.escape(e):e.replace(/["\\]/g,"\\$&")}const dt=[{label:"Desktop",value:"desktop"},{label:"Tablet",value:"tablet"},{label:"Mobile",value:"mobile"}],me=["open","in_progress","needs_clarification","fixed","wontfix","resolved"],ye=["low","medium","high"],Se=["bug","visual","copy","accessibility","responsive"],Z={open:"Open",in_progress:"In progress",needs_clarification:"Needs clarification",fixed:"Fixed",wontfix:"Won't fix",resolved:"Resolved"},H={low:"Low",medium:"Medium",high:"High"},j={bug:"Bug",visual:"Visual",copy:"Copy",accessibility:"Accessibility",responsive:"Responsive"};function ct({open:e,onOpenChange:t,placement:n="top-right",showResolved:a=!1,syncSelectionToUrl:i=!1,responsivePresets:d=dt}){var Oe;const{adapter:f,config:b,currentUser:p,feedback:c,normalizedPath:w,permissions:u,createFeedback:v,updateFeedback:E,listMessages:N,createMessage:A,uploadAttachment:h}=be(),[B,y]=l.useState(),[m,k]=l.useState(),[$,z]=l.useState(""),[xe,Ft]=l.useState("medium"),[Ae,Mt]=l.useState("visual"),[Le,Fe]=l.useState(""),[Me,Tt]=l.useState(((Oe=d[0])==null?void 0:Oe.value)??"desktop"),[S,J]=l.useState(),[M,P]=l.useState("review"),[It,Te]=l.useState(!1),[q,Ie]=l.useState("all"),[V,Be]=l.useState("all"),[G,$e]=l.useState("all"),[Y,Pe]=l.useState("all"),[X,_e]=l.useState("all"),[Bt,$t]=l.useState(!1),[Pt,Ue]=l.useState({}),[ae,ie]=l.useState(""),ee=l.useRef(null),T=!!p,I=u.includes("create"),We=u.includes("reply"),De=u.includes("update"),_t=u.includes("assign"),U=B??m,Ut=!!m,Wt=!!(b.captureScreenshot&&(b.uploadAttachment||f.uploadAttachment)),Dt=l.useMemo(()=>{const s=c.map(g=>g.assigneeEmail).filter(g=>!!g);return p!=null&&p.email&&s.push(p.email),Array.from(new Set(s)).sort((g,o)=>g.localeCompare(o))},[p==null?void 0:p.email,c]),F=l.useMemo(()=>c.filter(s=>a||s.status!=="resolved").filter(s=>q==="all"||s.status===q).filter(s=>V==="all"||s.severity===V).filter(s=>G==="all"||s.category===G).filter(s=>Y==="all"||s.assigneeEmail===Y).filter(s=>X==="all"||s.viewportPreset===X),[Y,G,c,V,a,q,X]),zt=[q,V,G,Y,X].filter(s=>s!=="all").length;l.useEffect(()=>{e||(y(void 0),k(void 0),z(""),ie(""),P("review"))},[e]),l.useEffect(()=>{T||(y(void 0),k(void 0))},[T]),l.useEffect(()=>{!m||M!=="review"||window.requestAnimationFrame(()=>{var s,g,o;(g=(s=ee.current)==null?void 0:s.scrollIntoView)==null||g.call(s,{block:"nearest"}),(o=ee.current)==null||o.focus()})},[m,M]),l.useEffect(()=>{if(!S)return;let s=!0;return N(S.id).then(g=>{s&&Ue(o=>({...o,[S.id]:g}))}),()=>{s=!1}},[N,S]),l.useEffect(()=>{if(!e||!i||S||c.length===0)return;const s=new URL(window.location.href).searchParams.get("reviewLensFeedback"),g=c.find(o=>o.id===s);g&&Q(g,{syncUrl:!1})},[c,e,S,i]),l.useEffect(()=>{if(!e)return;function s(o){var C;if(o.key==="Shift"&&Te(!0),o.key==="Escape"){o.preventDefault(),t==null||t(!1);return}Et(o.target)||((o.key==="n"||o.key==="ArrowDown")&&(o.preventDefault(),ze(1)),(o.key==="p"||o.key==="ArrowUp")&&(o.preventDefault(),ze(-1)),o.key==="c"&&(o.preventDefault(),P("review"),(C=ee.current)==null||C.focus()),o.key==="f"&&S&&De&&(o.preventDefault(),je(S)))}function g(o){o.key==="Shift"&&Te(!1)}return window.addEventListener("keydown",s),window.addEventListener("keyup",g),()=>{window.removeEventListener("keydown",s),window.removeEventListener("keyup",g)}});const oe=l.useCallback(s=>{const g=s.target instanceof Element?s.target:null;if(g)return g.closest("[data-review-lens-ui]")?null:g;const o=document.elementFromPoint(s.clientX,s.clientY);return!o||o.closest("[data-review-lens-ui]")?null:o},[]);if(l.useEffect(()=>{if(!e||!T)return;function s(o){const C=oe(o);y(C?W(C):void 0)}function g(o){const C=oe(o);C&&(o.preventDefault(),o.stopPropagation(),k(W(C)),P("review"))}return window.addEventListener("mousemove",s,!0),window.addEventListener("click",g,!0),()=>{window.removeEventListener("mousemove",s,!0),window.removeEventListener("click",g,!0)}},[T,oe,e]),!e)return null;function Q(s,g={syncUrl:!0}){var C;if(J(s),k(void 0),P("feedback"),i&&g.syncUrl!==!1){const te=new URL(window.location.href);te.searchParams.set("reviewLensFeedback",s.id),window.history.replaceState({},"",te)}const o=D(s.selector);if(!o){y(void 0);return}(C=o.scrollIntoView)==null||C.call(o,{behavior:"smooth",block:"center",inline:"center"}),window.requestAnimationFrame(()=>{y(W(o))})}function ze(s){if(F.length===0)return;const g=S?F.findIndex(C=>C.id===S.id):-1,o=g<0?s>0?0:F.length-1:(g+s+F.length)%F.length;Q(F[o])}async function He(){if(!m||!$.trim()||!p||!I)return;let s=await v({projectKey:b.projectKey,contentId:b.contentId,normalizedPath:w,originalUrl:b.currentUrl??window.location.href,selector:m.selector,selectorStrategy:m.selectorStrategy,elementFingerprint:m.fingerprint,createdCssSnapshot:m.cssSnapshot,comment:$.trim(),status:"open",severity:xe,category:Ae,assigneeEmail:Le.trim()||void 0,viewportWidth:window.innerWidth,viewportHeight:window.innerHeight,viewportPreset:Me,screenshotUrl:void 0,screenshotThumbnailUrl:void 0,authorEmail:p.email});if(b.captureScreenshot)try{const g=await b.captureScreenshot(m),o=await h(s.id,{type:"screenshot",data:g,createdBy:p.email});s=await E(s.id,{attachments:[o],screenshotUrl:o.url,screenshotThumbnailUrl:o.thumbnailUrl})}catch{}z(""),Fe(""),k(void 0),y(void 0),P("feedback"),J(s)}async function Ht(s,g){const o=new Date().toISOString(),C=g==="resolved"?{status:g,resolvedAt:o,resolvedBy:p==null?void 0:p.email}:{status:g},te=await E(s.id,C);J(te)}async function je(s){const g=D(s.selector);if(!g||!p)return;const o=W(g),C=await E(s.id,{status:"fixed",fixedCssSnapshot:o.cssSnapshot,fixedAt:new Date().toISOString(),fixedBy:p.email});J(C)}async function jt(s){if(!ae.trim()||!p||!We)return;const g=await A({feedbackId:s.id,body:ae.trim(),authorEmail:p.email});Ue(o=>({...o,[s.id]:[...o[s.id]??[],g]})),ie("")}return r.jsxs("div",{className:"review-lens-root","data-review-lens-ui":!0,children:[T&&U?r.jsx(ft,{target:U,locked:!!m}):null,T&&m&&B&&It?r.jsx(bt,{from:m,to:B}):null,T?r.jsxs(r.Fragment,{children:[r.jsx(vt,{feedback:F,selectedFeedback:S,onSelect:Q}),r.jsx(mt,{feedback:F,selectedFeedback:S,onSelect:Q})]}):null,r.jsxs("aside",{className:`review-lens-panel review-lens-panel--${n}`,"data-review-lens-ui":!0,children:[r.jsxs("header",{className:"review-lens-panel__header",children:[r.jsxs("div",{children:[r.jsx("p",{className:"review-lens-kicker",children:"Review Lens"}),r.jsx("h2",{children:M==="summary"?"Summary":M==="feedback"?"Feedback":m?"Element locked":"Inspecting"})]}),r.jsx("button",{type:"button",onClick:()=>t==null?void 0:t(!1),children:"Close"})]}),r.jsxs("div",{className:"review-lens-panel__body",children:[r.jsxs("div",{className:"review-lens-mode-switch",role:"tablist","aria-label":"Review Lens mode",children:[r.jsx("button",{type:"button",role:"tab","aria-selected":M==="review",onClick:()=>P("review"),children:"Review"}),r.jsxs("button",{type:"button",role:"tab","aria-selected":M==="feedback",onClick:()=>P("feedback"),children:["Feedback ",r.jsx("span",{children:F.length})]}),r.jsx("button",{type:"button",role:"tab","aria-selected":M==="summary",onClick:()=>P("summary"),children:"Summary"})]}),M==="review"?r.jsxs("div",{className:"review-lens-review-pane",role:"tabpanel",children:[r.jsxs("div",{className:"review-lens-inspection",children:[T?null:r.jsx("p",{children:"Authenticate with Google to inspect this page."}),T&&U?r.jsxs(r.Fragment,{children:[r.jsx(yt,{target:U}),r.jsx(ke,{title:"Accessibility",items:St(U)}),r.jsx(ke,{title:"Design tokens",items:kt(U.cssSnapshot,b.designTokens)})]}):null,T&&!U?r.jsx("p",{children:"Move over the app to inspect."}):null]}),Ut?r.jsx("div",{className:"review-lens-composer-panel",children:r.jsxs("form",{className:"review-lens-feedback-form",onSubmit:s=>{s.preventDefault(),He()},children:[r.jsx("label",{htmlFor:"review-lens-comment",children:"New feedback"}),r.jsx("textarea",{ref:ee,id:"review-lens-comment",value:$,disabled:!I,onChange:s=>z(s.target.value),onKeyDown:s=>{s.key==="Enter"&&s.metaKey&&(s.preventDefault(),He())},placeholder:I?"Describe the UX issue...":"You do not have permission to comment."}),r.jsxs("div",{className:"review-lens-form-grid",children:[r.jsxs("label",{children:["Severity",r.jsx("select",{value:xe,onChange:s=>Ft(s.target.value),disabled:!I,children:ye.map(s=>r.jsx("option",{value:s,children:H[s]},s))})]}),r.jsxs("label",{children:["Type",r.jsx("select",{value:Ae,onChange:s=>Mt(s.target.value),disabled:!I,children:Se.map(s=>r.jsx("option",{value:s,children:j[s]},s))})]}),r.jsxs("label",{children:["Assignee",r.jsx("input",{value:Le,onChange:s=>Fe(s.target.value),disabled:!I,placeholder:"optional@email.com"})]}),r.jsxs("label",{children:["Viewport",r.jsx("select",{value:Me,onChange:s=>Tt(s.target.value),disabled:!I,children:d.map(s=>r.jsx("option",{value:s.value,children:s.label},s.value))})]})]}),I?r.jsxs("p",{className:"review-lens-feedback-form__hint",children:["Press ",r.jsx("kbd",{children:"Command"})," + ",r.jsx("kbd",{children:"Enter"})," to submit.",Wt?" Screenshot capture runs after save.":""]}):null,r.jsx("div",{className:"review-lens-actions",children:r.jsx("button",{type:"submit",disabled:!$.trim()||!I,children:"Save feedback"})})]})}):null]}):null,M==="feedback"?r.jsxs("div",{className:"review-lens-comments",children:[r.jsx(ht,{open:Bt,activeCount:zt,statusFilter:q,severityFilter:V,categoryFilter:G,assigneeFilter:Y,viewportFilter:X,assignees:Dt,responsivePresets:d,onStatusChange:Ie,onSeverityChange:Be,onCategoryChange:$e,onAssigneeChange:Pe,onViewportChange:_e,onToggle:()=>$t(s=>!s),onClear:()=>{Ie("all"),Be("all"),$e("all"),Pe("all"),_e("all")}}),r.jsxs("div",{className:"review-lens-list-panel",children:[r.jsxs("div",{className:"review-lens-comments__header",children:[r.jsx("h3",{children:"All feedback"}),r.jsx("span",{children:F.length})]}),r.jsxs("div",{className:"review-lens-comments__list",children:[F.length===0?r.jsx("p",{children:"No feedback for this view."}):null,F.map(s=>r.jsx(pt,{item:s,selected:(S==null?void 0:S.id)===s.id,onSelect:Q},s.id))]})]}),S?r.jsxs("div",{className:"review-lens-selected-panel",children:[r.jsx("div",{className:"review-lens-selected-panel__label",children:"Selected feedback"}),r.jsx(ut,{item:S,messages:Pt[S.id]??[],messageDraft:ae,canReply:We,canUpdate:De,canAssign:_t,onMessageDraftChange:ie,onSubmitMessage:()=>void jt(S),onStatusChange:s=>void Ht(S,s),onAssigneeChange:s=>void E(S.id,{assigneeEmail:s.trim()||void 0}).then(J),onMarkFixed:()=>void je(S)},S.id)]}):r.jsxs("div",{className:"review-lens-selected-panel review-lens-selected-panel--empty",children:[r.jsx("div",{className:"review-lens-selected-panel__label",children:"Selected feedback"}),r.jsx("p",{children:"Select a feedback item above to review status, assignment, drift, and replies."})]})]}):null,M==="summary"?r.jsx(gt,{feedback:c}):null]})]})]})}function ht({open:e,activeCount:t,statusFilter:n,severityFilter:a,categoryFilter:i,assigneeFilter:d,viewportFilter:f,assignees:b,responsivePresets:p,onStatusChange:c,onSeverityChange:w,onCategoryChange:u,onAssigneeChange:v,onViewportChange:E,onToggle:N,onClear:A}){return r.jsxs("div",{className:"review-lens-filter-shell",children:[r.jsxs("div",{className:"review-lens-filter-bar",children:[r.jsxs("button",{type:"button","aria-expanded":e,onClick:N,children:["Filters",t>0?r.jsx("span",{children:t}):null]}),t>0?r.jsx("button",{type:"button",onClick:A,children:"Clear"}):null]}),e?r.jsxs("div",{className:"review-lens-filters",children:[r.jsxs("label",{children:["Status",r.jsxs("select",{"aria-label":"Filter status",value:n,onChange:h=>c(h.target.value),children:[r.jsx("option",{value:"all",children:"All statuses"}),me.map(h=>r.jsx("option",{value:h,children:Z[h]},h))]})]}),r.jsxs("label",{children:["Priority",r.jsxs("select",{"aria-label":"Filter severity",value:a,onChange:h=>w(h.target.value),children:[r.jsx("option",{value:"all",children:"All priorities"}),ye.map(h=>r.jsx("option",{value:h,children:H[h]},h))]})]}),r.jsxs("label",{children:["Type",r.jsxs("select",{"aria-label":"Filter type",value:i,onChange:h=>u(h.target.value),children:[r.jsx("option",{value:"all",children:"All types"}),Se.map(h=>r.jsx("option",{value:h,children:j[h]},h))]})]}),r.jsxs("label",{children:["Assignee",r.jsxs("select",{"aria-label":"Filter assignee",value:d,onChange:h=>v(h.target.value),children:[r.jsx("option",{value:"all",children:"All assignees"}),b.map(h=>r.jsx("option",{value:h,children:h},h))]})]}),r.jsxs("label",{children:["Viewport",r.jsxs("select",{"aria-label":"Filter viewport",value:f,onChange:h=>E(h.target.value),children:[r.jsx("option",{value:"all",children:"All viewports"}),p.map(h=>r.jsx("option",{value:h.value,children:h.label},h.value))]})]})]}):null]})}function pt({item:e,selected:t,onSelect:n}){const a=Ce(e);return r.jsxs("article",{tabIndex:0,className:["review-lens-comment",`review-lens-comment--${e.severity}`,t?"review-lens-comment--selected":""].filter(Boolean).join(" "),onClick:()=>n(e),onKeyDown:i=>{(i.key==="Enter"||i.key===" ")&&(i.preventDefault(),n(e))},children:[r.jsxs("div",{className:"review-lens-comment__header",children:[r.jsx("span",{children:Z[e.status]}),r.jsx("strong",{children:H[e.severity]})]}),r.jsxs("div",{className:"review-lens-comment__content",children:[r.jsx("p",{children:e.comment}),r.jsxs("span",{children:[e.authorEmail,e.assigneeEmail?` -> ${e.assigneeEmail}`:""]})]}),r.jsxs("div",{className:"review-lens-tags",children:[r.jsx("span",{children:j[e.category]}),r.jsx("span",{children:e.viewportPreset}),r.jsx("span",{children:a.label})]})]})}function ut({item:e,messages:t,messageDraft:n,canReply:a,canUpdate:i,canAssign:d,onMessageDraftChange:f,onSubmitMessage:b,onStatusChange:p,onAssigneeChange:c,onMarkFixed:w}){const u=Ce(e);return r.jsxs("section",{className:"review-lens-detail","aria-label":"Selected feedback detail",children:[r.jsxs("div",{className:"review-lens-detail__header",children:[r.jsxs("h3",{children:[j[e.category]," feedback"]}),r.jsx("strong",{children:H[e.severity]})]}),r.jsx("blockquote",{children:e.comment}),r.jsxs("dl",{className:"review-lens-detail-meta",children:[r.jsxs("div",{children:[r.jsx("dt",{children:"Target"}),r.jsx("dd",{children:u.label})]}),r.jsxs("div",{children:[r.jsx("dt",{children:"Viewport"}),r.jsx("dd",{children:e.viewportPreset})]}),e.screenshotUrl?r.jsxs("div",{children:[r.jsx("dt",{children:"Evidence"}),r.jsx("dd",{children:r.jsx("a",{href:e.screenshotUrl,target:"_blank",rel:"noreferrer",children:"Screenshot"})})]}):null]}),r.jsxs("div",{className:"review-lens-form-grid",children:[r.jsxs("label",{children:["Status",r.jsx("select",{value:e.status,disabled:!i,onChange:v=>p(v.target.value),children:me.map(v=>r.jsx("option",{value:v,children:Z[v]},v))})]}),r.jsxs("label",{children:["Assignee",r.jsx("input",{defaultValue:e.assigneeEmail??"",disabled:!d,onBlur:v=>c(v.target.value),placeholder:"optional@email.com"})]})]}),r.jsxs("div",{className:"review-lens-status-actions",children:[r.jsx("button",{type:"button",className:"review-lens-button-secondary",disabled:!i,onClick:w,children:"Mark fixed"}),r.jsx("button",{type:"button",className:"review-lens-button-primary",disabled:!i,onClick:()=>p("resolved"),children:"Resolve"})]}),r.jsxs("div",{className:"review-lens-thread",children:[r.jsxs("div",{className:"review-lens-thread__header",children:[r.jsx("h3",{children:"Thread"}),r.jsx("span",{children:t.length})]}),t.length===0?r.jsx("p",{children:"No replies yet."}):null,t.map(v=>r.jsxs("div",{className:"review-lens-thread__message",children:[r.jsx("p",{children:v.body}),r.jsx("span",{children:v.authorEmail})]},v.id)),r.jsx("textarea",{"aria-label":"Reply",value:n,disabled:!a,onChange:v=>f(v.target.value),placeholder:a?"Reply...":"You do not have permission to reply."}),r.jsx("div",{className:"review-lens-actions",children:r.jsx("button",{type:"button",disabled:!n.trim()||!a,onClick:b,children:"Reply"})})]})]})}function gt({feedback:e}){return r.jsxs("div",{className:"review-lens-summary",role:"tabpanel",children:[r.jsx(O,{title:"Status",values:K(e,t=>Z[t.status])}),r.jsx(O,{title:"Severity",values:K(e,t=>H[t.severity])}),r.jsx(O,{title:"Type",values:K(e,t=>j[t.category])}),r.jsx(O,{title:"Assignee",values:K(e,t=>t.assigneeEmail??"Unassigned")}),r.jsx(O,{title:"Viewport",values:K(e,t=>t.viewportPreset)})]})}function O({title:e,values:t}){return r.jsxs("section",{children:[r.jsx("h3",{children:e}),r.jsx("dl",{children:t.map(([n,a])=>r.jsxs("div",{children:[r.jsx("dt",{children:n}),r.jsx("dd",{children:a})]},n))})]})}function ft({target:e,locked:t}){const n=Lt(e),a=Ct(e.fingerprint);return r.jsxs("div",{className:t?"review-lens-highlight review-lens-highlight--locked":"review-lens-highlight",style:{top:n.margin.top,left:n.margin.left,width:n.margin.width,height:n.margin.height},children:[r.jsx("div",{className:"review-lens-highlight__border",style:{top:n.border.top-n.margin.top,left:n.border.left-n.margin.left,width:n.border.width,height:n.border.height}}),r.jsx("div",{className:"review-lens-highlight__padding",style:{top:n.padding.top-n.margin.top,left:n.padding.left-n.margin.left,width:n.padding.width,height:n.padding.height}}),r.jsx("div",{className:"review-lens-highlight__content",style:{top:n.content.top-n.margin.top,left:n.content.left-n.margin.left,width:n.content.width,height:n.content.height}}),r.jsxs("div",{className:"review-lens-highlight__label",children:[r.jsx("strong",{children:a}),r.jsxs("span",{children:[Math.round(e.rect.width)," x ",Math.round(e.rect.height)]})]})]})}function bt({from:e,to:t}){const n=Nt(e.rect,t.rect);return n.length===0?null:r.jsx(r.Fragment,{children:n.map(a=>r.jsx("div",{className:`review-lens-distance review-lens-distance--${a.axis}`,style:{top:a.top,left:a.left,width:a.width,height:a.height},children:r.jsx("span",{children:a.label})},a.key))})}function vt({feedback:e,selectedFeedback:t,onSelect:n}){return r.jsx(r.Fragment,{children:e.map(a=>r.jsx(wt,{feedback:a,selected:(t==null?void 0:t.id)===a.id,onSelect:n},a.id))})}function wt({feedback:e,selected:t,onSelect:n}){const a=l.useRef(null);return l.useLayoutEffect(()=>{let i=0;const d=()=>{i=0;const b=a.current,p=D(e.selector),c=p==null?void 0:p.getBoundingClientRect();!b||!c||(b.style.top=`${c.top}px`,b.style.left=`${c.right}px`,b.hidden=c.bottom<0||c.top>window.innerHeight)},f=()=>{i||(i=window.requestAnimationFrame(d))};return d(),window.addEventListener("scroll",f,!0),window.addEventListener("resize",f),()=>{i&&window.cancelAnimationFrame(i),window.removeEventListener("scroll",f,!0),window.removeEventListener("resize",f)}},[e.selector]),r.jsx("button",{ref:a,type:"button",className:t?"review-lens-marker review-lens-marker--selected":"review-lens-marker",onClick:()=>n(e),"aria-label":`Open feedback from ${e.authorEmail}`})}function mt({feedback:e,selectedFeedback:t,onSelect:n}){const a=e.map(i=>{const d=D(i.selector),f=d==null?void 0:d.getBoundingClientRect(),b=Math.max(document.documentElement.scrollHeight,document.body.scrollHeight,window.innerHeight);return!f||b<=0?null:{item:i,top:Math.min(100,Math.max(0,(f.top+window.scrollY)/b*100))}}).filter(i=>i!==null);return a.length===0?null:r.jsx("div",{className:"review-lens-minimap","data-review-lens-ui":!0,"aria-label":"Feedback map",children:a.map(i=>r.jsx("button",{type:"button",className:(t==null?void 0:t.id)===i.item.id?"review-lens-minimap__point review-lens-minimap__point--selected":"review-lens-minimap__point",style:{top:`${i.top}%`},onClick:()=>n(i.item),"aria-label":`Jump to feedback from ${i.item.authorEmail}`},i.item.id))})}function yt({target:e}){const t=[["Selector",e.selector],["Size",`${e.cssSnapshot.width} x ${e.cssSnapshot.height}`],["Margin",e.cssSnapshot.margin],["Padding",e.cssSnapshot.padding],["Border",e.cssSnapshot.border],["Radius",e.cssSnapshot.borderRadius],["Font",`${e.cssSnapshot.fontSize} / ${e.cssSnapshot.lineHeight}`],["Family",e.cssSnapshot.fontFamily],["Color",e.cssSnapshot.color],["Background",e.cssSnapshot.backgroundColor]];return r.jsx("dl",{className:"review-lens-metrics",children:t.map(([n,a])=>r.jsxs("div",{children:[r.jsx("dt",{children:n}),r.jsx("dd",{children:a})]},n))})}function ke({title:e,items:t}){return r.jsxs("section",{className:"review-lens-insights",children:[r.jsx("h3",{children:e}),t.length===0?r.jsx("p",{children:"No issues detected."}):null,t.length>0?r.jsx("ul",{children:t.map(n=>r.jsx("li",{children:n},n))}):null]})}function D(e){try{return document.querySelector(e)}catch{return null}}function Ce(e){const t=D(e.selector);if(!t)return{label:"Target missing",level:"warning"};const n=W(t);return n.fingerprint.tagName!==e.elementFingerprint.tagName?{label:"Element changed",level:"warning"}:Math.abs(n.fingerprint.width-e.elementFingerprint.width)>2||Math.abs(n.fingerprint.height-e.elementFingerprint.height)>2?{label:"Size changed",level:"warning"}:n.cssSnapshot.fontSize!==e.createdCssSnapshot.fontSize||n.cssSnapshot.color!==e.createdCssSnapshot.color||n.cssSnapshot.padding!==e.createdCssSnapshot.padding?{label:"Style changed",level:"warning"}:{label:"Target unchanged",level:"ok"}}function St(e){var p;const t=D(e.selector);if(!t)return["Selected element is no longer available."];const n=[],a=t.tagName.toLowerCase(),i=t.getAttribute("role"),d=["button","a","input","select","textarea"].includes(a)||i==="button"||i==="link",f=t.getAttribute("aria-label")||t.getAttribute("title")||((p=t.textContent)==null?void 0:p.trim());d&&!f&&n.push("Interactive element has no accessible name."),d&&(e.rect.width<44||e.rect.height<44)&&n.push("Tap target is smaller than 44 x 44."),a==="img"&&!t.getAttribute("alt")&&n.push("Image is missing alt text.");const b=/^h[1-6]$/.test(a)?Number(a.slice(1)):0;return b>1&&!document.querySelector(`h${b-1}`)&&n.push("Heading may skip the previous level."),xt(e.cssSnapshot.color,e.cssSnapshot.backgroundColor)&&n.push("Text contrast may be low."),n}function kt(e,t={}){const n=[];return _("Padding",e.padding,t.spacing,n),_("Margin",e.margin,t.spacing,n),_("Font size",e.fontSize,t.fontSize,n),_("Line height",e.lineHeight,t.lineHeight,n),_("Text color",e.color,t.color,n),_("Background",e.backgroundColor,t.color,n),_("Radius",e.borderRadius,t.radius,n),n}function _(e,t,n,a){!n||n.length===0||!t||n.includes(t)||a.push(`${e} ${t} is outside configured tokens.`)}function Ct(e){const t=e.id?`#${e.id}`:"",n=e.className?`.${e.className.split(/\s+/).filter(Boolean).slice(0,2).join(".")}`:"",a=e.ariaLabel?`[aria-label="${e.ariaLabel}"]`:"";return`${e.tagName}${t}${n}${a}`||e.tagName}function Nt(e,t){const n=[],a=(Math.max(e.left,t.left)+Math.min(e.right,t.right))/2,i=(Math.max(e.top,t.top)+Math.min(e.bottom,t.bottom))/2;if(e.right<=t.left||t.right<=e.left){const d=e.right<=t.left?e.right:t.right,f=e.right<=t.left?t.left:e.left;n.push({key:"horizontal",axis:"horizontal",top:Ne(i,0,window.innerHeight),left:d,width:Math.max(f-d,1),height:1,label:`${Math.round(f-d)}px`})}if(e.bottom<=t.top||t.bottom<=e.top){const d=e.bottom<=t.top?e.bottom:t.bottom,f=e.bottom<=t.top?t.top:e.top;n.push({key:"vertical",axis:"vertical",top:d,left:Ne(a,0,window.innerWidth),width:1,height:Math.max(f-d,1),label:`${Math.round(f-d)}px`})}return n}function Ne(e,t,n){return Math.min(Math.max(e,t),n)}function K(e,t){const n=new Map;for(const a of e){const i=t(a);n.set(i,(n.get(i)??0)+1)}return Array.from(n.entries()).sort((a,i)=>i[1]-a[1]||a[0].localeCompare(i[0]))}function Et(e){return e instanceof HTMLInputElement||e instanceof HTMLTextAreaElement||e instanceof HTMLSelectElement||e instanceof HTMLElement&&e.isContentEditable}function xt(e,t){const n=Ee(e),a=Ee(t);return!n||!a||a.alpha===0?!1:At(n,a)<4.5}function Ee(e){const t=e.match(/rgba?\(([^)]+)\)/);if(!t)return null;const[n,a,i,d="1"]=t[1].split(",").map(f=>f.trim());return{red:Number(n),green:Number(a),blue:Number(i),alpha:Number(d)}}function At(e,t){const n=Math.max(R(e),R(t)),a=Math.min(R(e),R(t));return(n+.05)/(a+.05)}function R(e){const t=[e.red,e.green,e.blue].map(n=>{const a=n/255;return a<=.03928?a/12.92:((a+.055)/1.055)**2.4});return t[0]*.2126+t[1]*.7152+t[2]*.0722}function Lt(e){const t={top:L(e.cssSnapshot.marginTop),right:L(e.cssSnapshot.marginRight),bottom:L(e.cssSnapshot.marginBottom),left:L(e.cssSnapshot.marginLeft)},n={top:L(e.cssSnapshot.borderTopWidth),right:L(e.cssSnapshot.borderRightWidth),bottom:L(e.cssSnapshot.borderBottomWidth),left:L(e.cssSnapshot.borderLeftWidth)},a={top:L(e.cssSnapshot.paddingTop),right:L(e.cssSnapshot.paddingRight),bottom:L(e.cssSnapshot.paddingBottom),left:L(e.cssSnapshot.paddingLeft)},i={top:e.rect.top,left:e.rect.left,width:Math.max(e.rect.width,0),height:Math.max(e.rect.height,0)},d={top:i.top-t.top,left:i.left-t.left,width:i.width+t.left+t.right,height:i.height+t.top+t.bottom},f={top:i.top+n.top,left:i.left+n.left,width:Math.max(i.width-n.left-n.right,0),height:Math.max(i.height-n.top-n.bottom,0)},b={top:f.top+a.top,left:f.left+a.left,width:Math.max(f.width-a.left-a.right,0),height:Math.max(f.height-a.top-a.bottom,0)};return{margin:d,border:i,padding:f,content:b}}function L(e){const t=Number.parseFloat(e);return Number.isFinite(t)?t:0}x.ReviewLensOverlay=ct,x.ReviewLensProvider=rt,x.buildElementTarget=W,x.createGoogleSheetsAdapter=le,x.normalizeReviewUrl=ge,x.useReviewLens=be,Object.defineProperty(x,Symbol.toStringTag,{value:"Module"})}));
|
|
1
|
+
(function(x,r){typeof exports=="object"&&typeof module<"u"?r(exports,require("react/jsx-runtime"),require("react")):typeof define=="function"&&define.amd?define(["exports","react/jsx-runtime","react"],r):(x=typeof globalThis<"u"?globalThis:x||self,r(x.ReviewLensReact={},x.jsxRuntime,x.React))})(this,(function(x,r,l){"use strict";const Ke=["https://www.googleapis.com/auth/spreadsheets","https://www.googleapis.com/auth/userinfo.email"].join(" "),Je="https://www.googleapis.com/oauth2/v3/userinfo";function le(e){const t=e.feedbackSheetName??"Feedback",n=e.messagesSheetName??"Messages",s=e.usersSheetName??"Users";let a,d;async function f(){return a??(a=tt(e.googleClientId)),a}async function b(c,w){const u=await f(),v=await fetch(`https://sheets.googleapis.com/v4/spreadsheets/${e.spreadsheetId}${c}`,{...w,headers:{Authorization:`Bearer ${u}`,"Content-Type":"application/json",...w==null?void 0:w.headers}});if(!v.ok)throw new Error(`Google Sheets request failed with ${v.status}`);return v.json()}async function p(c){return(await b(`/values/${encodeURIComponent(c)}`)).values??[]}return{async getCurrentUser(){if(!d){const c=await f(),w=await fetch(Je,{headers:{Authorization:`Bearer ${c}`}});if(!w.ok)throw new Error(`Google userinfo request failed with ${w.status}`);d=(await w.json()).email}if(!d)throw new Error("Google account did not return an email address");return{email:d}},async getPermissions(c){const[{email:w},u]=await Promise.all([this.getCurrentUser(),p(s)]),v=ne(u),E=w.toLowerCase(),N=v.find(A=>{var h;return((h=A.email)==null?void 0:h.toLowerCase())===E&&A.active!=="false"&&(!A.projectKey||A.projectKey===c)});return Ye((N==null?void 0:N.role)??"designer")},async listFeedback(c){return ne(await p(t)).map(pe).filter(u=>u!==null).filter(u=>u.projectKey===c.projectKey&&u.contentId===c.contentId&&u.normalizedPath===c.normalizedPath).sort((u,v)=>v.createdAt.localeCompare(u.createdAt))},async createFeedback(c){const w=new Date().toISOString(),u={...c,id:crypto.randomUUID(),attachments:[],createdAt:w,updatedAt:w};return await b(`/values/${encodeURIComponent(t)}:append?valueInputOption=RAW`,{method:"POST",body:JSON.stringify({values:[ce(u)]})}),u},async updateFeedback(c,w){const u=await p(t),v=u[0]??de,E=v.indexOf("id");if(E===-1)throw new Error(`Sheet ${t} is missing an id column`);const N=u.findIndex((m,k)=>k>0&&m[E]===c);if(N<1)throw new Error(`Feedback ${c} was not found`);const A=new Date().toISOString(),h=pe(he(v,u[N]));if(!h)throw new Error(`Feedback ${c} could not be parsed before updating`);const B={...h,...w,updatedAt:A},y=ce(B);return await b(`/values/${encodeURIComponent(t)}!A${N+1}:${et(de.length)}${N+1}?valueInputOption=RAW`,{method:"PUT",body:JSON.stringify({values:[y]})}),B},async listMessages(c){return ne(await p(n)).map(Ge).filter(u=>u!==null).filter(u=>u.feedbackId===c).sort((u,v)=>u.createdAt.localeCompare(v.createdAt))},async createMessage(c){const w={...c,id:crypto.randomUUID(),createdAt:new Date().toISOString()};return await b(`/values/${encodeURIComponent(n)}:append?valueInputOption=RAW`,{method:"POST",body:JSON.stringify({values:[Ve(w)]})}),w}}}const de=["id","projectKey","contentId","normalizedPath","originalUrl","selector","selectorStrategy","elementFingerprintJson","createdCssSnapshotJson","comment","status","severity","category","assigneeEmail","viewportWidth","viewportHeight","viewportPreset","screenshotUrl","screenshotThumbnailUrl","attachmentJson","authorEmail","createdAt","updatedAt","fixedCssSnapshotJson","fixedAt","fixedBy","resolvedAt","resolvedBy"],qe=["id","feedbackId","body","authorEmail","createdAt"];function ce(e){return[e.id,e.projectKey,e.contentId,e.normalizedPath,e.originalUrl,e.selector,e.selectorStrategy,JSON.stringify(e.elementFingerprint),JSON.stringify(e.createdCssSnapshot),e.comment,e.status,e.severity,e.category,e.assigneeEmail??"",String(e.viewportWidth),String(e.viewportHeight),e.viewportPreset,e.screenshotUrl??"",e.screenshotThumbnailUrl??"",JSON.stringify(e.attachments),e.authorEmail,e.createdAt,e.updatedAt,e.fixedCssSnapshot?JSON.stringify(e.fixedCssSnapshot):"",e.fixedAt??"",e.fixedBy??"",e.resolvedAt??"",e.resolvedBy??""]}function Ve(e){return qe.map(t=>e[t])}function ne(e){const[t,...n]=e;return t?n.map(s=>he(t,s)):[]}function he(e,t){return Object.fromEntries(e.map((n,s)=>[n,t[s]??""]))}function pe(e){return e.id?{id:e.id,projectKey:e.projectKey,contentId:e.contentId,normalizedPath:e.normalizedPath,originalUrl:e.originalUrl,selector:e.selector,selectorStrategy:e.selectorStrategy==="stable-attribute"?"stable-attribute":"css-path",elementFingerprint:re(e.elementFingerprintJson,{tagName:"",width:0,height:0}),createdCssSnapshot:ue(e.createdCssSnapshotJson),fixedCssSnapshot:e.fixedCssSnapshotJson?ue(e.fixedCssSnapshotJson):void 0,comment:e.comment,status:Xe(e.status),severity:Qe(e.severity),category:Ze(e.category),assigneeEmail:e.assigneeEmail||void 0,viewportWidth:Number(e.viewportWidth)||0,viewportHeight:Number(e.viewportHeight)||0,viewportPreset:Re(e.viewportPreset),screenshotUrl:e.screenshotUrl||void 0,screenshotThumbnailUrl:e.screenshotThumbnailUrl||void 0,attachments:re(e.attachmentJson,[]),authorEmail:e.authorEmail,createdAt:e.createdAt,updatedAt:e.updatedAt,fixedAt:e.fixedAt||void 0,fixedBy:e.fixedBy||void 0,resolvedAt:e.resolvedAt||void 0,resolvedBy:e.resolvedBy||void 0}:null}function Ge(e){return!e.id||!e.feedbackId?null:{id:e.id,feedbackId:e.feedbackId,body:e.body,authorEmail:e.authorEmail,createdAt:e.createdAt}}function re(e,t){try{return e?JSON.parse(e):t}catch{return t}}function ue(e){const t=re(e,{});return{margin:t.margin??"",marginTop:t.marginTop??"",marginRight:t.marginRight??"",marginBottom:t.marginBottom??"",marginLeft:t.marginLeft??"",padding:t.padding??"",paddingTop:t.paddingTop??"",paddingRight:t.paddingRight??"",paddingBottom:t.paddingBottom??"",paddingLeft:t.paddingLeft??"",border:t.border??"",borderTopWidth:t.borderTopWidth??"",borderRightWidth:t.borderRightWidth??"",borderBottomWidth:t.borderBottomWidth??"",borderLeftWidth:t.borderLeftWidth??"",fontFamily:t.fontFamily??"",fontSize:t.fontSize??"",lineHeight:t.lineHeight??"",color:t.color??"",backgroundColor:t.backgroundColor??"",borderRadius:t.borderRadius??"",width:t.width??0,height:t.height??0}}function Ye(e){return e==="admin"?["create","read","reply","update","assign"]:e==="developer"?["read","reply","update","assign"]:["create","read","reply"]}function Xe(e){return e==="in_progress"||e==="needs_clarification"||e==="fixed"||e==="wontfix"||e==="resolved"?e:"open"}function Qe(e){return e==="low"||e==="high"?e:"medium"}function Ze(e){return e==="visual"||e==="copy"||e==="accessibility"||e==="responsive"?e:"bug"}function Re(e){return e==="mobile"||e==="tablet"||e==="desktop"?e:"custom"}function et(e){let t=e,n="";for(;t>0;){const s=(t-1)%26;n=String.fromCharCode(65+s)+n,t=Math.floor((t-s)/26)}return n}async function tt(e){return await nt(),new Promise((t,n)=>{var a;const s=(a=window.google)==null?void 0:a.accounts.oauth2.initTokenClient({client_id:e,scope:Ke,callback:d=>{if(d.error||!d.access_token){n(new Error(d.error??"Google OAuth did not return an access token"));return}t(d.access_token)}});s==null||s.requestAccessToken({prompt:""})})}function nt(){var e;return(e=window.google)!=null&&e.accounts.oauth2?Promise.resolve():new Promise((t,n)=>{const s=document.querySelector('script[src="https://accounts.google.com/gsi/client"]');if(s){s.addEventListener("load",()=>t(),{once:!0}),s.addEventListener("error",()=>n(new Error("Google Identity failed to load")),{once:!0});return}const a=document.createElement("script");a.src="https://accounts.google.com/gsi/client",a.async=!0,a.defer=!0,a.onload=()=>t(),a.onerror=()=>n(new Error("Google Identity failed to load")),document.head.append(a)})}function ge(e){return new URL(e,window.location.href).pathname.replace(/\/+$/,"")||"/"}const fe=l.createContext(null);function rt({config:e,children:t}){const n=l.useMemo(()=>e.adapter?e.adapter:le({googleClientId:ve(e.googleClientId,"googleClientId"),spreadsheetId:ve(e.spreadsheetId,"spreadsheetId"),feedbackSheetName:e.sheetName??"Feedback"}),[e.adapter,e.googleClientId,e.sheetName,e.spreadsheetId]),s=e.currentUrl??window.location.href,a=(e.normalizeUrl??ge)(s),[d,f]=l.useState(),[b,p]=l.useState([]),[c,w]=l.useState([]),u=l.useCallback(async()=>{const y=await n.listFeedback({projectKey:e.projectKey,contentId:e.contentId,normalizedPath:a});w(y)},[n,e.contentId,e.projectKey,a]);l.useEffect(()=>{let y=!0;async function m(){const[k,$]=await Promise.all([n.getCurrentUser(),n.getPermissions(e.projectKey)]);y&&(f(k),p($),await u())}return m(),()=>{y=!1}},[n,e.projectKey,u]);const v=l.useCallback(async y=>{const m=await n.createFeedback(y);return w(k=>[m,...k]),m},[n]),E=l.useCallback(async(y,m)=>{const k=await n.updateFeedback(y,m);return w($=>$.map(z=>z.id===y?k:z)),k},[n]),N=l.useCallback(y=>n.listMessages(y),[n]),A=l.useCallback(y=>n.createMessage(y),[n]),h=l.useCallback(async(y,m)=>{const k=e.uploadAttachment??n.uploadAttachment;if(!k)throw new Error("Review Lens attachment upload is not configured");return k(y,m)},[n,e]),B=l.useMemo(()=>({config:e,adapter:n,currentUser:d,permissions:b,feedback:c,normalizedPath:a,refreshFeedback:u,createFeedback:v,updateFeedback:E,listMessages:N,createMessage:A,uploadAttachment:h}),[n,e,v,d,c,a,b,u,E,N,A,h]);return r.jsx(fe.Provider,{value:B,children:t})}function be(){const e=l.useContext(fe);if(!e)throw new Error("useReviewLens must be used inside ReviewLensProvider");return e}function ve(e,t){if(!e)throw new Error(`review-lens-react requires config.${t} when no adapter is provided`);return e}const st=["data-review-id","data-testid","data-test-id","aria-label","name"];function W(e){const t=e.getBoundingClientRect(),n=it(e);return{selector:n.selector,selectorStrategy:n.strategy,fingerprint:ot(e,t),cssSnapshot:lt(e,t),rect:t}}function it(e){for(const t of st){const n=e.getAttribute(t);if(n)return{selector:`[${t}="${we(n)}"]`,strategy:"stable-attribute"}}return e.id?{selector:`#${we(e.id)}`,strategy:"stable-attribute"}:{selector:at(e),strategy:"css-path"}}function at(e){const t=[];let n=e;for(;n&&n.nodeType===Node.ELEMENT_NODE&&n!==document.body;){const s=n.parentElement,a=n.tagName.toLowerCase();if(!s){t.unshift(a);break}const d=n.tagName,f=Array.from(s.children).filter(p=>p.tagName===d),b=f.indexOf(n)+1;t.unshift(f.length>1?`${a}:nth-of-type(${b})`:a),n=s}return t.join(" > ")}function ot(e,t){var n;return{tagName:e.tagName.toLowerCase(),id:e.id||void 0,className:e.getAttribute("class")||void 0,textSnippet:((n=e.textContent)==null?void 0:n.trim().slice(0,80))||void 0,ariaLabel:e.getAttribute("aria-label")||void 0,width:Math.round(t.width),height:Math.round(t.height)}}function lt(e,t){const n=window.getComputedStyle(e);return{margin:se(n.marginTop,n.marginRight,n.marginBottom,n.marginLeft),marginTop:n.marginTop,marginRight:n.marginRight,marginBottom:n.marginBottom,marginLeft:n.marginLeft,padding:se(n.paddingTop,n.paddingRight,n.paddingBottom,n.paddingLeft),paddingTop:n.paddingTop,paddingRight:n.paddingRight,paddingBottom:n.paddingBottom,paddingLeft:n.paddingLeft,border:se(n.borderTopWidth,n.borderRightWidth,n.borderBottomWidth,n.borderLeftWidth),borderTopWidth:n.borderTopWidth,borderRightWidth:n.borderRightWidth,borderBottomWidth:n.borderBottomWidth,borderLeftWidth:n.borderLeftWidth,fontFamily:n.fontFamily,fontSize:n.fontSize,lineHeight:n.lineHeight,color:n.color,backgroundColor:n.backgroundColor,borderRadius:n.borderRadius,width:Math.round(t.width),height:Math.round(t.height)}}function se(e,t,n,s){return e===t&&t===n&&n===s?e:`${e} ${t} ${n} ${s}`}function we(e){return typeof CSS<"u"&&typeof CSS.escape=="function"?CSS.escape(e):e.replace(/["\\]/g,"\\$&")}const dt=[{label:"Desktop",value:"desktop"},{label:"Tablet",value:"tablet"},{label:"Mobile",value:"mobile"}],me=["open","in_progress","needs_clarification","fixed","wontfix","resolved"],ye=["low","medium","high"],Se=["bug","visual","copy","accessibility","responsive"],Z={open:"Open",in_progress:"In progress",needs_clarification:"Needs clarification",fixed:"Fixed",wontfix:"Won't fix",resolved:"Resolved"},H={low:"Low",medium:"Medium",high:"High"},j={bug:"Bug",visual:"Visual",copy:"Copy",accessibility:"Accessibility",responsive:"Responsive"};function ct({open:e,onOpenChange:t,placement:n="top-right",showResolved:s=!1,syncSelectionToUrl:a=!1,responsivePresets:d=dt}){var Oe;const{adapter:f,config:b,currentUser:p,feedback:c,normalizedPath:w,permissions:u,createFeedback:v,updateFeedback:E,listMessages:N,createMessage:A,uploadAttachment:h}=be(),[B,y]=l.useState(),[m,k]=l.useState(),[$,z]=l.useState(""),[xe,Mt]=l.useState("medium"),[Ae,Tt]=l.useState("visual"),[Le,Fe]=l.useState(""),[Me,It]=l.useState(((Oe=d[0])==null?void 0:Oe.value)??"desktop"),[S,J]=l.useState(),[M,P]=l.useState("review"),[Bt,Te]=l.useState(!1),[q,Ie]=l.useState("all"),[V,Be]=l.useState("all"),[G,$e]=l.useState("all"),[Y,Pe]=l.useState("all"),[X,_e]=l.useState("all"),[$t,Pt]=l.useState(!1),[_t,Ue]=l.useState({}),[ie,ae]=l.useState(""),ee=l.useRef(null),T=!!p,I=u.includes("create"),We=u.includes("reply"),De=u.includes("update"),Ut=u.includes("assign"),U=B??m,Wt=!!m,Dt=!!(b.captureScreenshot&&(b.uploadAttachment||f.uploadAttachment)),zt=l.useMemo(()=>{const i=c.map(g=>g.assigneeEmail).filter(g=>!!g);return p!=null&&p.email&&i.push(p.email),Array.from(new Set(i)).sort((g,o)=>g.localeCompare(o))},[p==null?void 0:p.email,c]),F=l.useMemo(()=>c.filter(i=>s||i.status!=="resolved").filter(i=>q==="all"||i.status===q).filter(i=>V==="all"||i.severity===V).filter(i=>G==="all"||i.category===G).filter(i=>Y==="all"||i.assigneeEmail===Y).filter(i=>X==="all"||i.viewportPreset===X),[Y,G,c,V,s,q,X]),Ht=[q,V,G,Y,X].filter(i=>i!=="all").length;l.useEffect(()=>{e||(y(void 0),k(void 0),z(""),ae(""),P("review"))},[e]),l.useEffect(()=>{T||(y(void 0),k(void 0))},[T]),l.useEffect(()=>{!m||M!=="review"||window.requestAnimationFrame(()=>{var i,g,o;(g=(i=ee.current)==null?void 0:i.scrollIntoView)==null||g.call(i,{block:"nearest"}),(o=ee.current)==null||o.focus()})},[m,M]),l.useEffect(()=>{if(!S)return;let i=!0;return N(S.id).then(g=>{i&&Ue(o=>({...o,[S.id]:g}))}),()=>{i=!1}},[N,S]),l.useEffect(()=>{if(!e||!a||S||c.length===0)return;const i=new URL(window.location.href).searchParams.get("reviewLensFeedback"),g=c.find(o=>o.id===i);g&&Q(g,{syncUrl:!1})},[c,e,S,a]),l.useEffect(()=>{if(!e)return;function i(o){var C;if(o.key==="Shift"&&Te(!0),o.key==="Escape"){o.preventDefault(),t==null||t(!1);return}xt(o.target)||((o.key==="n"||o.key==="ArrowDown")&&(o.preventDefault(),ze(1)),(o.key==="p"||o.key==="ArrowUp")&&(o.preventDefault(),ze(-1)),o.key==="c"&&(o.preventDefault(),P("review"),(C=ee.current)==null||C.focus()),o.key==="f"&&S&&De&&(o.preventDefault(),je(S)))}function g(o){o.key==="Shift"&&Te(!1)}return window.addEventListener("keydown",i),window.addEventListener("keyup",g),()=>{window.removeEventListener("keydown",i),window.removeEventListener("keyup",g)}});const oe=l.useCallback(i=>{const g=i.target instanceof Element?i.target:null;if(g)return g.closest("[data-review-lens-ui]")?null:g;const o=document.elementFromPoint(i.clientX,i.clientY);return!o||o.closest("[data-review-lens-ui]")?null:o},[]);if(l.useEffect(()=>{if(!e||!T)return;function i(o){const C=oe(o);y(C?W(C):void 0)}function g(o){const C=oe(o);C&&(o.preventDefault(),o.stopPropagation(),k(W(C)),P("review"))}return window.addEventListener("mousemove",i,!0),window.addEventListener("click",g,!0),()=>{window.removeEventListener("mousemove",i,!0),window.removeEventListener("click",g,!0)}},[T,oe,e]),!e)return null;function Q(i,g={syncUrl:!0}){var C;if(J(i),k(void 0),P("feedback"),a&&g.syncUrl!==!1){const te=new URL(window.location.href);te.searchParams.set("reviewLensFeedback",i.id),window.history.replaceState({},"",te)}const o=D(i.selector);if(!o){y(void 0);return}(C=o.scrollIntoView)==null||C.call(o,{behavior:"smooth",block:"center",inline:"center"}),window.requestAnimationFrame(()=>{y(W(o))})}function ze(i){if(F.length===0)return;const g=S?F.findIndex(C=>C.id===S.id):-1,o=g<0?i>0?0:F.length-1:(g+i+F.length)%F.length;Q(F[o])}async function He(){if(!m||!$.trim()||!p||!I)return;let i=await v({projectKey:b.projectKey,contentId:b.contentId,normalizedPath:w,originalUrl:b.currentUrl??window.location.href,selector:m.selector,selectorStrategy:m.selectorStrategy,elementFingerprint:m.fingerprint,createdCssSnapshot:m.cssSnapshot,comment:$.trim(),status:"open",severity:xe,category:Ae,assigneeEmail:Le.trim()||void 0,viewportWidth:window.innerWidth,viewportHeight:window.innerHeight,viewportPreset:Me,screenshotUrl:void 0,screenshotThumbnailUrl:void 0,authorEmail:p.email});if(b.captureScreenshot)try{const g=await b.captureScreenshot(m),o=await h(i.id,{type:"screenshot",data:g,createdBy:p.email});i=await E(i.id,{attachments:[o],screenshotUrl:o.url,screenshotThumbnailUrl:o.thumbnailUrl})}catch{}z(""),Fe(""),k(void 0),y(void 0),P("feedback"),J(i)}async function jt(i,g){const o=new Date().toISOString(),C=g==="resolved"?{status:g,resolvedAt:o,resolvedBy:p==null?void 0:p.email}:{status:g},te=await E(i.id,C);J(te)}async function je(i){const g=D(i.selector);if(!g||!p)return;const o=W(g),C=await E(i.id,{status:"fixed",fixedCssSnapshot:o.cssSnapshot,fixedAt:new Date().toISOString(),fixedBy:p.email});J(C)}async function Ot(i){if(!ie.trim()||!p||!We)return;const g=await A({feedbackId:i.id,body:ie.trim(),authorEmail:p.email});Ue(o=>({...o,[i.id]:[...o[i.id]??[],g]})),ae("")}return r.jsxs("div",{className:"review-lens-root","data-review-lens-ui":!0,children:[T&&U?r.jsx(ft,{target:U,locked:!!m}):null,T&&m&&B&&Bt?r.jsx(bt,{from:m,to:B}):null,T?r.jsxs(r.Fragment,{children:[r.jsx(vt,{feedback:F,selectedFeedback:S,onSelect:Q}),r.jsx(mt,{feedback:F,selectedFeedback:S,onSelect:Q})]}):null,r.jsxs("aside",{className:`review-lens-panel review-lens-panel--${n}`,"data-review-lens-ui":!0,children:[r.jsxs("header",{className:"review-lens-panel__header",children:[r.jsxs("div",{children:[r.jsx("p",{className:"review-lens-kicker",children:"Review Lens"}),r.jsx("h2",{children:M==="summary"?"Summary":M==="feedback"?"Feedback":m?"Element locked":"Inspecting"})]}),r.jsx("button",{type:"button",onClick:()=>t==null?void 0:t(!1),children:"Close"})]}),r.jsxs("div",{className:"review-lens-panel__body",children:[r.jsxs("div",{className:"review-lens-mode-switch",role:"tablist","aria-label":"Review Lens mode",children:[r.jsx("button",{type:"button",role:"tab","aria-selected":M==="review",onClick:()=>P("review"),children:"Review"}),r.jsxs("button",{type:"button",role:"tab","aria-selected":M==="feedback",onClick:()=>P("feedback"),children:["Feedback ",r.jsx("span",{children:F.length})]}),r.jsx("button",{type:"button",role:"tab","aria-selected":M==="summary",onClick:()=>P("summary"),children:"Summary"})]}),M==="review"?r.jsxs("div",{className:"review-lens-review-pane",role:"tabpanel",children:[r.jsxs("div",{className:"review-lens-inspection",children:[T?null:r.jsx("p",{children:"Authenticate with Google to inspect this page."}),T&&U?r.jsxs(r.Fragment,{children:[r.jsx(yt,{target:U}),r.jsx(ke,{title:"Accessibility",items:St(U)}),r.jsx(ke,{title:"Design tokens",items:kt(U.cssSnapshot,b.designTokens)})]}):null,T&&!U?r.jsx("p",{children:"Move over the app to inspect."}):null]}),Wt?r.jsx("div",{className:"review-lens-composer-panel",children:r.jsxs("form",{className:"review-lens-feedback-form",onSubmit:i=>{i.preventDefault(),He()},children:[r.jsx("label",{htmlFor:"review-lens-comment",children:"New feedback"}),r.jsx("textarea",{ref:ee,id:"review-lens-comment",value:$,disabled:!I,onChange:i=>z(i.target.value),onKeyDown:i=>{i.key==="Enter"&&i.metaKey&&(i.preventDefault(),He())},placeholder:I?"Describe the UX issue...":"You do not have permission to comment."}),r.jsxs("div",{className:"review-lens-form-grid",children:[r.jsxs("label",{children:["Severity",r.jsx("select",{value:xe,onChange:i=>Mt(i.target.value),disabled:!I,children:ye.map(i=>r.jsx("option",{value:i,children:H[i]},i))})]}),r.jsxs("label",{children:["Type",r.jsx("select",{value:Ae,onChange:i=>Tt(i.target.value),disabled:!I,children:Se.map(i=>r.jsx("option",{value:i,children:j[i]},i))})]}),r.jsxs("label",{children:["Assignee",r.jsx("input",{value:Le,onChange:i=>Fe(i.target.value),disabled:!I,placeholder:"optional@email.com"})]}),r.jsxs("label",{children:["Viewport",r.jsx("select",{value:Me,onChange:i=>It(i.target.value),disabled:!I,children:d.map(i=>r.jsx("option",{value:i.value,children:i.label},i.value))})]})]}),I?r.jsxs("p",{className:"review-lens-feedback-form__hint",children:["Press ",r.jsx("kbd",{children:"Command"})," + ",r.jsx("kbd",{children:"Enter"})," to submit.",Dt?" Screenshot capture runs after save.":""]}):null,r.jsx("div",{className:"review-lens-actions",children:r.jsx("button",{type:"submit",disabled:!$.trim()||!I,children:"Save feedback"})})]})}):null]}):null,M==="feedback"?r.jsxs("div",{className:"review-lens-comments",children:[r.jsx(ht,{open:$t,activeCount:Ht,statusFilter:q,severityFilter:V,categoryFilter:G,assigneeFilter:Y,viewportFilter:X,assignees:zt,responsivePresets:d,onStatusChange:Ie,onSeverityChange:Be,onCategoryChange:$e,onAssigneeChange:Pe,onViewportChange:_e,onToggle:()=>Pt(i=>!i),onClear:()=>{Ie("all"),Be("all"),$e("all"),Pe("all"),_e("all")}}),r.jsxs("div",{className:"review-lens-list-panel",children:[r.jsxs("div",{className:"review-lens-comments__header",children:[r.jsx("h3",{children:"All feedback"}),r.jsx("span",{children:F.length})]}),r.jsxs("div",{className:"review-lens-comments__list",children:[F.length===0?r.jsx("p",{children:"No feedback for this view."}):null,F.map(i=>r.jsx(pt,{item:i,selected:(S==null?void 0:S.id)===i.id,onSelect:Q},i.id))]})]}),S?r.jsxs("div",{className:"review-lens-selected-panel",children:[r.jsx("div",{className:"review-lens-selected-panel__label",children:"Selected feedback"}),r.jsx(ut,{item:S,messages:_t[S.id]??[],messageDraft:ie,canReply:We,canUpdate:De,canAssign:Ut,onMessageDraftChange:ae,onSubmitMessage:()=>void Ot(S),onStatusChange:i=>void jt(S,i),onAssigneeChange:i=>void E(S.id,{assigneeEmail:i.trim()||void 0}).then(J),onMarkFixed:()=>void je(S)},S.id)]}):r.jsxs("div",{className:"review-lens-selected-panel review-lens-selected-panel--empty",children:[r.jsx("div",{className:"review-lens-selected-panel__label",children:"Selected feedback"}),r.jsx("p",{children:"Select a feedback item above to review status, assignment, drift, and replies."})]})]}):null,M==="summary"?r.jsx(gt,{feedback:c}):null]})]})]})}function ht({open:e,activeCount:t,statusFilter:n,severityFilter:s,categoryFilter:a,assigneeFilter:d,viewportFilter:f,assignees:b,responsivePresets:p,onStatusChange:c,onSeverityChange:w,onCategoryChange:u,onAssigneeChange:v,onViewportChange:E,onToggle:N,onClear:A}){return r.jsxs("div",{className:"review-lens-filter-shell",children:[r.jsxs("div",{className:"review-lens-filter-bar",children:[r.jsxs("button",{type:"button","aria-expanded":e,onClick:N,children:["Filters",t>0?r.jsx("span",{children:t}):null]}),t>0?r.jsx("button",{type:"button",onClick:A,children:"Clear"}):null]}),e?r.jsxs("div",{className:"review-lens-filters",children:[r.jsxs("label",{children:["Status",r.jsxs("select",{"aria-label":"Filter status",value:n,onChange:h=>c(h.target.value),children:[r.jsx("option",{value:"all",children:"All statuses"}),me.map(h=>r.jsx("option",{value:h,children:Z[h]},h))]})]}),r.jsxs("label",{children:["Priority",r.jsxs("select",{"aria-label":"Filter severity",value:s,onChange:h=>w(h.target.value),children:[r.jsx("option",{value:"all",children:"All priorities"}),ye.map(h=>r.jsx("option",{value:h,children:H[h]},h))]})]}),r.jsxs("label",{children:["Type",r.jsxs("select",{"aria-label":"Filter type",value:a,onChange:h=>u(h.target.value),children:[r.jsx("option",{value:"all",children:"All types"}),Se.map(h=>r.jsx("option",{value:h,children:j[h]},h))]})]}),r.jsxs("label",{children:["Assignee",r.jsxs("select",{"aria-label":"Filter assignee",value:d,onChange:h=>v(h.target.value),children:[r.jsx("option",{value:"all",children:"All assignees"}),b.map(h=>r.jsx("option",{value:h,children:h},h))]})]}),r.jsxs("label",{children:["Viewport",r.jsxs("select",{"aria-label":"Filter viewport",value:f,onChange:h=>E(h.target.value),children:[r.jsx("option",{value:"all",children:"All viewports"}),p.map(h=>r.jsx("option",{value:h.value,children:h.label},h.value))]})]})]}):null]})}function pt({item:e,selected:t,onSelect:n}){const s=Ce(e);return r.jsxs("article",{tabIndex:0,className:["review-lens-comment",`review-lens-comment--${e.severity}`,t?"review-lens-comment--selected":""].filter(Boolean).join(" "),onClick:()=>n(e),onKeyDown:a=>{(a.key==="Enter"||a.key===" ")&&(a.preventDefault(),n(e))},children:[r.jsxs("div",{className:"review-lens-comment__header",children:[r.jsx("span",{children:Z[e.status]}),r.jsx("strong",{children:H[e.severity]})]}),r.jsxs("div",{className:"review-lens-comment__content",children:[r.jsx("p",{children:e.comment}),r.jsxs("span",{children:[e.authorEmail,e.assigneeEmail?` -> ${e.assigneeEmail}`:""]})]}),r.jsxs("div",{className:"review-lens-tags",children:[r.jsx("span",{children:j[e.category]}),r.jsx("span",{children:e.viewportPreset}),r.jsx("span",{children:s.label})]})]})}function ut({item:e,messages:t,messageDraft:n,canReply:s,canUpdate:a,canAssign:d,onMessageDraftChange:f,onSubmitMessage:b,onStatusChange:p,onAssigneeChange:c,onMarkFixed:w}){const u=Ce(e);return r.jsxs("section",{className:"review-lens-detail","aria-label":"Selected feedback detail",children:[r.jsxs("div",{className:"review-lens-detail__header",children:[r.jsxs("h3",{children:[j[e.category]," feedback"]}),r.jsx("strong",{children:H[e.severity]})]}),r.jsx("blockquote",{children:e.comment}),r.jsxs("dl",{className:"review-lens-detail-meta",children:[r.jsxs("div",{children:[r.jsx("dt",{children:"Target"}),r.jsx("dd",{children:u.label})]}),r.jsxs("div",{children:[r.jsx("dt",{children:"Viewport"}),r.jsx("dd",{children:e.viewportPreset})]}),e.screenshotUrl?r.jsxs("div",{children:[r.jsx("dt",{children:"Evidence"}),r.jsx("dd",{children:r.jsx("a",{href:e.screenshotUrl,target:"_blank",rel:"noreferrer",children:"Screenshot"})})]}):null]}),r.jsxs("div",{className:"review-lens-form-grid",children:[r.jsxs("label",{children:["Status",r.jsx("select",{value:e.status,disabled:!a,onChange:v=>p(v.target.value),children:me.map(v=>r.jsx("option",{value:v,children:Z[v]},v))})]}),r.jsxs("label",{children:["Assignee",r.jsx("input",{defaultValue:e.assigneeEmail??"",disabled:!d,onBlur:v=>c(v.target.value),placeholder:"optional@email.com"})]})]}),r.jsxs("div",{className:"review-lens-status-actions",children:[r.jsx("button",{type:"button",className:"review-lens-button-secondary",disabled:!a,onClick:w,children:"Mark fixed"}),r.jsx("button",{type:"button",className:"review-lens-button-primary",disabled:!a,onClick:()=>p("resolved"),children:"Resolve"})]}),r.jsxs("div",{className:"review-lens-thread",children:[r.jsxs("div",{className:"review-lens-thread__header",children:[r.jsx("h3",{children:"Thread"}),r.jsx("span",{children:t.length})]}),t.length===0?r.jsx("p",{children:"No replies yet."}):null,t.map(v=>r.jsxs("div",{className:"review-lens-thread__message",children:[r.jsx("p",{children:v.body}),r.jsx("span",{children:v.authorEmail})]},v.id)),r.jsx("textarea",{"aria-label":"Reply",value:n,disabled:!s,onChange:v=>f(v.target.value),placeholder:s?"Reply...":"You do not have permission to reply."}),r.jsx("div",{className:"review-lens-actions",children:r.jsx("button",{type:"button",disabled:!n.trim()||!s,onClick:b,children:"Reply"})})]})]})}function gt({feedback:e}){return r.jsxs("div",{className:"review-lens-summary",role:"tabpanel",children:[r.jsx(O,{title:"Status",values:K(e,t=>Z[t.status])}),r.jsx(O,{title:"Severity",values:K(e,t=>H[t.severity])}),r.jsx(O,{title:"Type",values:K(e,t=>j[t.category])}),r.jsx(O,{title:"Assignee",values:K(e,t=>t.assigneeEmail??"Unassigned")}),r.jsx(O,{title:"Viewport",values:K(e,t=>t.viewportPreset)})]})}function O({title:e,values:t}){return r.jsxs("section",{children:[r.jsx("h3",{children:e}),r.jsx("dl",{children:t.map(([n,s])=>r.jsxs("div",{children:[r.jsx("dt",{children:n}),r.jsx("dd",{children:s})]},n))})]})}function ft({target:e,locked:t}){const n=Ft(e),s=Nt(e.fingerprint);return r.jsxs("div",{className:t?"review-lens-highlight review-lens-highlight--locked":"review-lens-highlight",style:{top:n.margin.top,left:n.margin.left,width:n.margin.width,height:n.margin.height},children:[r.jsx("div",{className:"review-lens-highlight__border",style:{top:n.border.top-n.margin.top,left:n.border.left-n.margin.left,width:n.border.width,height:n.border.height}}),r.jsx("div",{className:"review-lens-highlight__padding",style:{top:n.padding.top-n.margin.top,left:n.padding.left-n.margin.left,width:n.padding.width,height:n.padding.height}}),r.jsx("div",{className:"review-lens-highlight__content",style:{top:n.content.top-n.margin.top,left:n.content.left-n.margin.left,width:n.content.width,height:n.content.height}}),r.jsxs("div",{className:"review-lens-highlight__label",children:[r.jsx("strong",{children:s}),r.jsxs("span",{children:[Math.round(e.rect.width)," x ",Math.round(e.rect.height)]})]})]})}function bt({from:e,to:t}){const n=Et(e.rect,t.rect);return n.length===0?null:r.jsx(r.Fragment,{children:n.map(s=>r.jsx("div",{className:`review-lens-distance review-lens-distance--${s.axis}`,style:{top:s.top,left:s.left,width:s.width,height:s.height},children:r.jsx("span",{children:s.label})},s.key))})}function vt({feedback:e,selectedFeedback:t,onSelect:n}){return r.jsx(r.Fragment,{children:e.map(s=>r.jsx(wt,{feedback:s,selected:(t==null?void 0:t.id)===s.id,onSelect:n},s.id))})}function wt({feedback:e,selected:t,onSelect:n}){const s=l.useRef(null);return l.useLayoutEffect(()=>{let a=0;const d=()=>{a=0;const b=s.current,p=D(e.selector),c=p==null?void 0:p.getBoundingClientRect();!b||!c||(b.style.top=`${c.top}px`,b.style.left=`${c.right}px`,b.hidden=c.bottom<0||c.top>window.innerHeight)},f=()=>{a||(a=window.requestAnimationFrame(d))};return d(),window.addEventListener("scroll",f,!0),window.addEventListener("resize",f),()=>{a&&window.cancelAnimationFrame(a),window.removeEventListener("scroll",f,!0),window.removeEventListener("resize",f)}},[e.selector]),r.jsx("button",{ref:s,type:"button",className:t?"review-lens-marker review-lens-marker--selected":"review-lens-marker",onClick:()=>n(e),"aria-label":`Open feedback from ${e.authorEmail}`})}function mt({feedback:e,selectedFeedback:t,onSelect:n}){const s=e.map(a=>{const d=D(a.selector),f=d==null?void 0:d.getBoundingClientRect(),b=Math.max(document.documentElement.scrollHeight,document.body.scrollHeight,window.innerHeight);return!f||b<=0?null:{item:a,top:Math.min(100,Math.max(0,(f.top+window.scrollY)/b*100))}}).filter(a=>a!==null);return s.length===0?null:r.jsx("div",{className:"review-lens-minimap","data-review-lens-ui":!0,"aria-label":"Feedback map",children:s.map(a=>r.jsx("button",{type:"button",className:(t==null?void 0:t.id)===a.item.id?"review-lens-minimap__point review-lens-minimap__point--selected":"review-lens-minimap__point",style:{top:`${a.top}%`},onClick:()=>n(a.item),"aria-label":`Jump to feedback from ${a.item.authorEmail}`},a.item.id))})}function yt({target:e}){const t=[["Selector",e.selector],["Size",`${e.cssSnapshot.width} x ${e.cssSnapshot.height}`],["Margin",e.cssSnapshot.margin],["Padding",e.cssSnapshot.padding],["Border",e.cssSnapshot.border],["Radius",e.cssSnapshot.borderRadius],["Font",`${e.cssSnapshot.fontSize} / ${e.cssSnapshot.lineHeight}`],["Family",e.cssSnapshot.fontFamily],["Color",e.cssSnapshot.color],["Background",e.cssSnapshot.backgroundColor]];return r.jsx("dl",{className:"review-lens-metrics",children:t.map(([n,s])=>r.jsxs("div",{children:[r.jsx("dt",{children:n}),r.jsx("dd",{children:s})]},n))})}function ke({title:e,items:t}){return r.jsxs("section",{className:"review-lens-insights",children:[r.jsx("h3",{children:e}),t.length===0?r.jsx("p",{children:"No issues detected."}):null,t.length>0?r.jsx("ul",{children:t.map(n=>r.jsx("li",{children:n},n))}):null]})}function D(e){try{return document.querySelector(e)}catch{return null}}function Ce(e){const t=D(e.selector);if(!t)return{label:"Target missing",level:"warning"};const n=W(t);return n.fingerprint.tagName!==e.elementFingerprint.tagName?{label:"Element changed",level:"warning"}:Math.abs(n.fingerprint.width-e.elementFingerprint.width)>2||Math.abs(n.fingerprint.height-e.elementFingerprint.height)>2?{label:"Size changed",level:"warning"}:n.cssSnapshot.fontSize!==e.createdCssSnapshot.fontSize||n.cssSnapshot.color!==e.createdCssSnapshot.color||n.cssSnapshot.padding!==e.createdCssSnapshot.padding?{label:"Style changed",level:"warning"}:{label:"Target unchanged",level:"ok"}}function St(e){var p;const t=D(e.selector);if(!t)return["Selected element is no longer available."];const n=[],s=t.tagName.toLowerCase(),a=t.getAttribute("role"),d=["button","a","input","select","textarea"].includes(s)||a==="button"||a==="link",f=t.getAttribute("aria-label")||t.getAttribute("title")||((p=t.textContent)==null?void 0:p.trim());d&&!f&&n.push("Interactive element has no accessible name."),d&&(e.rect.width<44||e.rect.height<44)&&n.push("Tap target is smaller than 44 x 44."),s==="img"&&!t.getAttribute("alt")&&n.push("Image is missing alt text.");const b=/^h[1-6]$/.test(s)?Number(s.slice(1)):0;return b>1&&!document.querySelector(`h${b-1}`)&&n.push("Heading may skip the previous level."),At(e.cssSnapshot.color,e.cssSnapshot.backgroundColor)&&n.push("Text contrast may be low."),n}function kt(e,t={}){const n=[];return _("Padding",e.padding,t.spacing,n,{allowComposite:!0}),_("Margin",e.margin,t.spacing,n,{allowComposite:!0}),_("Font size",e.fontSize,t.fontSize,n),_("Line height",e.lineHeight,t.lineHeight,n),_("Text color",e.color,t.color,n),_("Background",e.backgroundColor,t.color,n),_("Radius",e.borderRadius,t.radius,n,{allowComposite:!0}),n}function _(e,t,n,s,a={}){!n||n.length===0||!t||Ct(t,n,a)||s.push(`${e} ${t} is outside configured tokens.`)}function Ct(e,t,n={}){if(t.includes(e))return!0;if(!n.allowComposite)return!1;const s=e.trim().split(/\s+/);return s.length>1&&s.every(a=>t.includes(a))}function Nt(e){const t=e.id?`#${e.id}`:"",n=e.className?`.${e.className.split(/\s+/).filter(Boolean).slice(0,2).join(".")}`:"",s=e.ariaLabel?`[aria-label="${e.ariaLabel}"]`:"";return`${e.tagName}${t}${n}${s}`||e.tagName}function Et(e,t){const n=[],s=(Math.max(e.left,t.left)+Math.min(e.right,t.right))/2,a=(Math.max(e.top,t.top)+Math.min(e.bottom,t.bottom))/2;if(e.right<=t.left||t.right<=e.left){const d=e.right<=t.left?e.right:t.right,f=e.right<=t.left?t.left:e.left;n.push({key:"horizontal",axis:"horizontal",top:Ne(a,0,window.innerHeight),left:d,width:Math.max(f-d,1),height:1,label:`${Math.round(f-d)}px`})}if(e.bottom<=t.top||t.bottom<=e.top){const d=e.bottom<=t.top?e.bottom:t.bottom,f=e.bottom<=t.top?t.top:e.top;n.push({key:"vertical",axis:"vertical",top:d,left:Ne(s,0,window.innerWidth),width:1,height:Math.max(f-d,1),label:`${Math.round(f-d)}px`})}return n}function Ne(e,t,n){return Math.min(Math.max(e,t),n)}function K(e,t){const n=new Map;for(const s of e){const a=t(s);n.set(a,(n.get(a)??0)+1)}return Array.from(n.entries()).sort((s,a)=>a[1]-s[1]||s[0].localeCompare(a[0]))}function xt(e){return e instanceof HTMLInputElement||e instanceof HTMLTextAreaElement||e instanceof HTMLSelectElement||e instanceof HTMLElement&&e.isContentEditable}function At(e,t){const n=Ee(e),s=Ee(t);return!n||!s||s.alpha===0?!1:Lt(n,s)<4.5}function Ee(e){const t=e.match(/rgba?\(([^)]+)\)/);if(!t)return null;const[n,s,a,d="1"]=t[1].split(",").map(f=>f.trim());return{red:Number(n),green:Number(s),blue:Number(a),alpha:Number(d)}}function Lt(e,t){const n=Math.max(R(e),R(t)),s=Math.min(R(e),R(t));return(n+.05)/(s+.05)}function R(e){const t=[e.red,e.green,e.blue].map(n=>{const s=n/255;return s<=.03928?s/12.92:((s+.055)/1.055)**2.4});return t[0]*.2126+t[1]*.7152+t[2]*.0722}function Ft(e){const t={top:L(e.cssSnapshot.marginTop),right:L(e.cssSnapshot.marginRight),bottom:L(e.cssSnapshot.marginBottom),left:L(e.cssSnapshot.marginLeft)},n={top:L(e.cssSnapshot.borderTopWidth),right:L(e.cssSnapshot.borderRightWidth),bottom:L(e.cssSnapshot.borderBottomWidth),left:L(e.cssSnapshot.borderLeftWidth)},s={top:L(e.cssSnapshot.paddingTop),right:L(e.cssSnapshot.paddingRight),bottom:L(e.cssSnapshot.paddingBottom),left:L(e.cssSnapshot.paddingLeft)},a={top:e.rect.top,left:e.rect.left,width:Math.max(e.rect.width,0),height:Math.max(e.rect.height,0)},d={top:a.top-t.top,left:a.left-t.left,width:a.width+t.left+t.right,height:a.height+t.top+t.bottom},f={top:a.top+n.top,left:a.left+n.left,width:Math.max(a.width-n.left-n.right,0),height:Math.max(a.height-n.top-n.bottom,0)},b={top:f.top+s.top,left:f.left+s.left,width:Math.max(f.width-s.left-s.right,0),height:Math.max(f.height-s.top-s.bottom,0)};return{margin:d,border:a,padding:f,content:b}}function L(e){const t=Number.parseFloat(e);return Number.isFinite(t)?t:0}x.ReviewLensOverlay=ct,x.ReviewLensProvider=rt,x.buildElementTarget=W,x.createGoogleSheetsAdapter=le,x.normalizeReviewUrl=ge,x.useReviewLens=be,Object.defineProperty(x,Symbol.toStringTag,{value:"Module"})}));
|