@diegotsi/flint-react 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,11 +1,175 @@
1
1
  // src/FlintWidget.tsx
2
- import { useState as useState2, useEffect as useEffect2, useRef as useRef2 } from "react";
2
+ import { useState as useState3, useEffect as useEffect3, useRef as useRef3 } from "react";
3
3
  import { I18nextProvider, useTranslation as useTranslation2 } from "react-i18next";
4
4
 
5
5
  // src/FlintModal.tsx
6
- import { useRef, useState, useEffect, useCallback } from "react";
6
+ import { useRef as useRef2, useState as useState2, useEffect as useEffect2, useCallback } from "react";
7
7
  import { useTranslation } from "react-i18next";
8
8
 
9
+ // src/ScreenAnnotator.tsx
10
+ import { useEffect, useRef, useState } from "react";
11
+ import { jsx, jsxs } from "react/jsx-runtime";
12
+ function normalizeRect(startX, startY, endX, endY) {
13
+ return {
14
+ x: Math.min(startX, endX),
15
+ y: Math.min(startY, endY),
16
+ w: Math.abs(endX - startX),
17
+ h: Math.abs(endY - startY)
18
+ };
19
+ }
20
+ function patchGetComputedStyle() {
21
+ const orig = window.getComputedStyle;
22
+ const cvs = document.createElement("canvas");
23
+ cvs.width = cvs.height = 1;
24
+ const ctx = cvs.getContext("2d", { willReadFrequently: true });
25
+ function resolve(val) {
26
+ try {
27
+ ctx.clearRect(0, 0, 1, 1);
28
+ ctx.fillStyle = val;
29
+ ctx.fillRect(0, 0, 1, 1);
30
+ const [r, g, b, a] = ctx.getImageData(0, 0, 1, 1).data;
31
+ return a < 255 ? `rgba(${r},${g},${b},${(a / 255).toFixed(3)})` : `rgb(${r},${g},${b})`;
32
+ } catch {
33
+ return "transparent";
34
+ }
35
+ }
36
+ function fix(val) {
37
+ if (typeof val !== "string") return val;
38
+ if (!val.includes("oklab") && !val.includes("oklch")) return val;
39
+ return val.replace(/(?:oklab|oklch)\s*\([^)]+\)/gi, resolve);
40
+ }
41
+ window.getComputedStyle = function(...args) {
42
+ const style = orig.apply(window, args);
43
+ return new Proxy(style, {
44
+ get(target, prop) {
45
+ const val = target[prop];
46
+ if (typeof val === "function") {
47
+ return (...fnArgs) => fix(val.apply(target, fnArgs));
48
+ }
49
+ return fix(val);
50
+ }
51
+ });
52
+ };
53
+ return () => {
54
+ window.getComputedStyle = orig;
55
+ };
56
+ }
57
+ function ScreenAnnotator({ zIndex, onCapture, onCancel }) {
58
+ const [phase, setPhase] = useState("idle");
59
+ const [rect, setRect] = useState(null);
60
+ const startRef = useRef(null);
61
+ const overlayRef = useRef(null);
62
+ useEffect(() => {
63
+ const onKey = (e) => {
64
+ if (e.key === "Escape") onCancel();
65
+ };
66
+ window.addEventListener("keydown", onKey);
67
+ return () => window.removeEventListener("keydown", onKey);
68
+ }, [onCancel]);
69
+ const onMouseDown = (e) => {
70
+ e.preventDefault();
71
+ startRef.current = { x: e.clientX, y: e.clientY };
72
+ setPhase("selecting");
73
+ setRect({ x: e.clientX, y: e.clientY, w: 0, h: 0 });
74
+ };
75
+ const onMouseMove = (e) => {
76
+ if (phase !== "selecting" || !startRef.current) return;
77
+ setRect(normalizeRect(startRef.current.x, startRef.current.y, e.clientX, e.clientY));
78
+ };
79
+ const onMouseUp = async (e) => {
80
+ if (phase !== "selecting" || !startRef.current) return;
81
+ const finalRect = normalizeRect(startRef.current.x, startRef.current.y, e.clientX, e.clientY);
82
+ startRef.current = null;
83
+ if (finalRect.w < 5 || finalRect.h < 5) {
84
+ setPhase("idle");
85
+ setRect(null);
86
+ return;
87
+ }
88
+ setPhase("capturing");
89
+ await new Promise(
90
+ (resolve) => requestAnimationFrame(() => requestAnimationFrame(() => resolve()))
91
+ );
92
+ const unpatch = patchGetComputedStyle();
93
+ try {
94
+ const html2canvas = (await import("./html2canvas.esm-4TRSXIVS.js")).default;
95
+ const canvas = await html2canvas(document.body, {
96
+ useCORS: true,
97
+ logging: false,
98
+ allowTaint: true,
99
+ ignoreElements: (el) => el === overlayRef.current
100
+ });
101
+ unpatch();
102
+ const dpr = window.devicePixelRatio ?? 1;
103
+ const ctx = canvas.getContext("2d");
104
+ ctx.fillStyle = "rgba(255,200,0,0.25)";
105
+ ctx.fillRect(finalRect.x * dpr, finalRect.y * dpr, finalRect.w * dpr, finalRect.h * dpr);
106
+ ctx.strokeStyle = "#f97316";
107
+ ctx.lineWidth = 3 * dpr;
108
+ ctx.strokeRect(finalRect.x * dpr, finalRect.y * dpr, finalRect.w * dpr, finalRect.h * dpr);
109
+ canvas.toBlob((blob) => {
110
+ if (blob) {
111
+ onCapture(new File([blob], "annotation.png", { type: "image/png" }));
112
+ } else {
113
+ onCancel();
114
+ }
115
+ }, "image/png");
116
+ } catch (err) {
117
+ unpatch();
118
+ console.error("[Flint] ScreenAnnotator capture failed:", err);
119
+ onCancel();
120
+ }
121
+ };
122
+ const isCapturing = phase === "capturing";
123
+ return /* @__PURE__ */ jsxs(
124
+ "div",
125
+ {
126
+ ref: overlayRef,
127
+ onMouseDown,
128
+ onMouseMove,
129
+ onMouseUp,
130
+ style: {
131
+ position: "fixed",
132
+ inset: 0,
133
+ zIndex,
134
+ cursor: isCapturing ? "default" : "crosshair",
135
+ userSelect: "none",
136
+ background: phase === "selecting" ? "rgba(0,0,0,0.15)" : "rgba(0,0,0,0.05)",
137
+ transition: "background 0.1s",
138
+ opacity: isCapturing ? 0 : 1,
139
+ pointerEvents: isCapturing ? "none" : "auto"
140
+ },
141
+ children: [
142
+ !isCapturing && /* @__PURE__ */ jsx("div", { style: {
143
+ position: "absolute",
144
+ top: 16,
145
+ left: "50%",
146
+ transform: "translateX(-50%)",
147
+ background: "rgba(0,0,0,0.75)",
148
+ color: "#fff",
149
+ padding: "8px 18px",
150
+ borderRadius: 8,
151
+ fontSize: 14,
152
+ fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif',
153
+ pointerEvents: "none",
154
+ whiteSpace: "nowrap",
155
+ backdropFilter: "blur(4px)"
156
+ }, children: "Drag to highlight the problem area \xA0\xB7\xA0 Esc to cancel" }),
157
+ rect && phase === "selecting" && /* @__PURE__ */ jsx("div", { style: {
158
+ position: "absolute",
159
+ left: rect.x,
160
+ top: rect.y,
161
+ width: rect.w,
162
+ height: rect.h,
163
+ background: "rgba(255,200,0,0.2)",
164
+ border: "2px dashed #f97316",
165
+ boxSizing: "border-box",
166
+ pointerEvents: "none"
167
+ } })
168
+ ]
169
+ }
170
+ );
171
+ }
172
+
9
173
  // src/api.ts
10
174
  import { gzipSync } from "fflate";
11
175
  async function submitReport(serverUrl, projectKey, payload, screenshot) {
@@ -94,7 +258,7 @@ function resolveTheme(theme) {
94
258
  }
95
259
 
96
260
  // src/FlintModal.tsx
97
- import { jsx, jsxs } from "react/jsx-runtime";
261
+ import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
98
262
  var SEVERITIES = ["P1", "P2", "P3", "P4"];
99
263
  var SEV_COLOR = {
100
264
  P1: "#ef4444",
@@ -155,19 +319,20 @@ function FlintModal({
155
319
  const { t } = useTranslation();
156
320
  const colors = resolveTheme(theme);
157
321
  const isDark = theme === "dark";
158
- const [severity, setSeverity] = useState("P2");
159
- const [description, setDescription] = useState("");
160
- const [expectedBehavior, setExpectedBehavior] = useState("");
161
- const [screenshot, setScreenshot] = useState(null);
162
- const [status, setStatus] = useState("idle");
163
- const [result, setResult] = useState(null);
164
- const [errorMsg, setErrorMsg] = useState("");
165
- const fileRef = useRef(null);
166
- const overlayRef = useRef(null);
167
- useEffect(() => {
322
+ const [severity, setSeverity] = useState2("P2");
323
+ const [description, setDescription] = useState2("");
324
+ const [expectedBehavior, setExpectedBehavior] = useState2("");
325
+ const [screenshot, setScreenshot] = useState2(null);
326
+ const [annotating, setAnnotating] = useState2(false);
327
+ const [status, setStatus] = useState2("idle");
328
+ const [result, setResult] = useState2(null);
329
+ const [errorMsg, setErrorMsg] = useState2("");
330
+ const fileRef = useRef2(null);
331
+ const overlayRef = useRef2(null);
332
+ useEffect2(() => {
168
333
  injectKeyframes();
169
334
  }, []);
170
- useEffect(() => {
335
+ useEffect2(() => {
171
336
  const handler = (e) => {
172
337
  if (e.key === "Escape" && status !== "submitting") onClose();
173
338
  };
@@ -266,11 +431,11 @@ function FlintModal({
266
431
  const isSuccess = status === "success";
267
432
  const ringBorder = isSuccess ? "3px solid #22c55e" : `3px solid ${isDark ? "rgba(255,255,255,0.08)" : "rgba(0,0,0,0.08)"}`;
268
433
  const ringTopColor = isSuccess ? "#22c55e" : colors.accent;
269
- return /* @__PURE__ */ jsx("div", { style: overlayStyle, children: /* @__PURE__ */ jsxs("div", { style: modalStyle, role: "dialog", "aria-modal": "true", "aria-label": isSuccess ? t("successTitle") : t("sending"), children: [
270
- /* @__PURE__ */ jsx(ModalHeader, { colors, inputBorder, showClose: false, onClose }),
271
- /* @__PURE__ */ jsxs("div", { style: { padding: "40px 32px 48px", textAlign: "center", display: "flex", flexDirection: "column", alignItems: "center" }, children: [
272
- /* @__PURE__ */ jsxs("div", { style: { position: "relative", width: 80, height: 80, marginBottom: 28 }, children: [
273
- /* @__PURE__ */ jsx("div", { style: {
434
+ return /* @__PURE__ */ jsx2("div", { style: overlayStyle, children: /* @__PURE__ */ jsxs2("div", { style: modalStyle, role: "dialog", "aria-modal": "true", "aria-label": isSuccess ? t("successTitle") : t("sending"), children: [
435
+ /* @__PURE__ */ jsx2(ModalHeader, { colors, inputBorder, showClose: false, onClose }),
436
+ /* @__PURE__ */ jsxs2("div", { style: { padding: "40px 32px 48px", textAlign: "center", display: "flex", flexDirection: "column", alignItems: "center" }, children: [
437
+ /* @__PURE__ */ jsxs2("div", { style: { position: "relative", width: 80, height: 80, marginBottom: 28 }, children: [
438
+ /* @__PURE__ */ jsx2("div", { style: {
274
439
  position: "absolute",
275
440
  inset: -10,
276
441
  borderRadius: "50%",
@@ -279,7 +444,7 @@ function FlintModal({
279
444
  opacity: isSuccess ? 0 : 1,
280
445
  transition: "opacity 0.3s ease"
281
446
  } }),
282
- /* @__PURE__ */ jsx("div", { style: {
447
+ /* @__PURE__ */ jsx2("div", { style: {
283
448
  position: "absolute",
284
449
  inset: -10,
285
450
  borderRadius: "50%",
@@ -288,7 +453,7 @@ function FlintModal({
288
453
  opacity: isSuccess ? 0 : 1,
289
454
  transition: "opacity 0.3s ease"
290
455
  } }),
291
- /* @__PURE__ */ jsx("div", { style: {
456
+ /* @__PURE__ */ jsx2("div", { style: {
292
457
  position: "absolute",
293
458
  inset: 0,
294
459
  borderRadius: "50%",
@@ -297,8 +462,8 @@ function FlintModal({
297
462
  animation: isSuccess ? "none" : "_flint_spin 0.85s linear infinite",
298
463
  transition: "border-color 0.45s ease, border-top-color 0.45s ease"
299
464
  } }),
300
- /* @__PURE__ */ jsxs("div", { style: { position: "absolute", inset: 14, borderRadius: "50%" }, children: [
301
- /* @__PURE__ */ jsx("div", { style: {
465
+ /* @__PURE__ */ jsxs2("div", { style: { position: "absolute", inset: 14, borderRadius: "50%" }, children: [
466
+ /* @__PURE__ */ jsx2("div", { style: {
302
467
  position: "absolute",
303
468
  inset: 0,
304
469
  borderRadius: "50%",
@@ -309,8 +474,8 @@ function FlintModal({
309
474
  animation: isSuccess ? "none" : "_flint_pulse 2s ease-in-out infinite",
310
475
  opacity: isSuccess ? 0 : 1,
311
476
  transition: "opacity 0.3s ease"
312
- }, children: /* @__PURE__ */ jsx(SparkIcon, { color: colors.accent, size: 20 }) }),
313
- /* @__PURE__ */ jsx("div", { style: {
477
+ }, children: /* @__PURE__ */ jsx2(SparkIcon, { color: colors.accent, size: 20 }) }),
478
+ /* @__PURE__ */ jsx2("div", { style: {
314
479
  position: "absolute",
315
480
  inset: 0,
316
481
  borderRadius: "50%",
@@ -321,11 +486,11 @@ function FlintModal({
321
486
  opacity: isSuccess ? 1 : 0,
322
487
  transform: isSuccess ? "scale(1)" : "scale(0.65)",
323
488
  transition: "opacity 0.35s ease 0.2s, transform 0.4s cubic-bezier(0.16,1,0.3,1) 0.2s"
324
- }, children: /* @__PURE__ */ jsx(CheckIcon, { size: 20 }) })
489
+ }, children: /* @__PURE__ */ jsx2(CheckIcon, { size: 20 }) })
325
490
  ] })
326
491
  ] }),
327
- /* @__PURE__ */ jsxs("div", { style: { position: "relative", height: 26, width: "100%", marginBottom: 10 }, children: [
328
- /* @__PURE__ */ jsx("div", { style: {
492
+ /* @__PURE__ */ jsxs2("div", { style: { position: "relative", height: 26, width: "100%", marginBottom: 10 }, children: [
493
+ /* @__PURE__ */ jsx2("div", { style: {
329
494
  position: "absolute",
330
495
  inset: 0,
331
496
  display: "flex",
@@ -339,7 +504,7 @@ function FlintModal({
339
504
  transition: "opacity 0.25s ease",
340
505
  pointerEvents: "none"
341
506
  }, children: t("sending") }),
342
- /* @__PURE__ */ jsx("div", { style: {
507
+ /* @__PURE__ */ jsx2("div", { style: {
343
508
  position: "absolute",
344
509
  inset: 0,
345
510
  display: "flex",
@@ -355,8 +520,8 @@ function FlintModal({
355
520
  pointerEvents: isSuccess ? "auto" : "none"
356
521
  }, children: t("successTitle") })
357
522
  ] }),
358
- /* @__PURE__ */ jsxs("div", { style: { position: "relative", minHeight: 76, width: "100%" }, children: [
359
- /* @__PURE__ */ jsxs("div", { style: {
523
+ /* @__PURE__ */ jsxs2("div", { style: { position: "relative", minHeight: 76, width: "100%" }, children: [
524
+ /* @__PURE__ */ jsxs2("div", { style: {
360
525
  position: "absolute",
361
526
  inset: 0,
362
527
  display: "flex",
@@ -369,10 +534,10 @@ function FlintModal({
369
534
  transition: "opacity 0.2s ease",
370
535
  pointerEvents: "none"
371
536
  }, children: [
372
- /* @__PURE__ */ jsx("span", { children: t("capturingContext") }),
373
- /* @__PURE__ */ jsx(SendingDots, { color: colors.accent })
537
+ /* @__PURE__ */ jsx2("span", { children: t("capturingContext") }),
538
+ /* @__PURE__ */ jsx2(SendingDots, { color: colors.accent })
374
539
  ] }),
375
- /* @__PURE__ */ jsxs("div", { style: {
540
+ /* @__PURE__ */ jsxs2("div", { style: {
376
541
  position: "absolute",
377
542
  inset: 0,
378
543
  display: "flex",
@@ -384,223 +549,282 @@ function FlintModal({
384
549
  transition: "opacity 0.35s ease 0.35s, transform 0.35s ease 0.35s",
385
550
  pointerEvents: isSuccess ? "auto" : "none"
386
551
  }, children: [
387
- /* @__PURE__ */ jsx("p", { style: { fontSize: 15, color: colors.textMuted, margin: 0 }, children: result?.isDuplicate ? t("successDuplicate") : result ? `ID: ${result.id}` : "" }),
388
- result?.slackMessageUrl && /* @__PURE__ */ jsxs(
389
- "a",
552
+ /* @__PURE__ */ jsx2("p", { style: { fontSize: 15, color: colors.textMuted, margin: 0 }, children: result ? `ID: ${result.id}` : "" }),
553
+ /* @__PURE__ */ jsx2(
554
+ "button",
390
555
  {
391
- href: result.slackMessageUrl,
392
- target: "_blank",
393
- rel: "noreferrer",
556
+ onClick: onClose,
394
557
  style: {
395
- display: "inline-flex",
396
- alignItems: "center",
397
- gap: 6,
398
- padding: "9px 18px",
399
- borderRadius: "10px",
558
+ width: "100%",
559
+ padding: "13px 20px",
560
+ borderRadius: 12,
561
+ border: "none",
400
562
  background: `linear-gradient(135deg, ${colors.accent}, ${colors.accentHover})`,
401
563
  color: colors.buttonText,
402
- textDecoration: "none",
403
- fontSize: "15px",
404
- fontWeight: 600,
405
- boxShadow: accentGlow
564
+ fontSize: 17,
565
+ fontWeight: 700,
566
+ cursor: "pointer",
567
+ letterSpacing: "-0.01em",
568
+ boxShadow: accentGlow,
569
+ fontFamily: "inherit",
570
+ display: "flex",
571
+ alignItems: "center",
572
+ justifyContent: "center",
573
+ gap: 8
406
574
  },
407
- children: [
408
- t("successSlack"),
409
- " \u2197"
410
- ]
575
+ children: t("close")
576
+ }
577
+ )
578
+ ] })
579
+ ] })
580
+ ] })
581
+ ] }) });
582
+ }
583
+ return /* @__PURE__ */ jsxs2(Fragment, { children: [
584
+ annotating && /* @__PURE__ */ jsx2(
585
+ ScreenAnnotator,
586
+ {
587
+ zIndex: zIndex + 1,
588
+ onCapture: (file) => {
589
+ setScreenshot(file);
590
+ setAnnotating(false);
591
+ },
592
+ onCancel: () => setAnnotating(false)
593
+ }
594
+ ),
595
+ /* @__PURE__ */ jsx2("div", { ref: overlayRef, style: { ...overlayStyle, opacity: annotating ? 0 : 1, pointerEvents: annotating ? "none" : "auto" }, onClick: handleOverlayClick, children: /* @__PURE__ */ jsxs2("div", { style: modalStyle, role: "dialog", "aria-modal": "true", "aria-labelledby": "flint-modal-title", children: [
596
+ /* @__PURE__ */ jsx2(
597
+ ModalHeader,
598
+ {
599
+ colors,
600
+ inputBorder,
601
+ showClose: true,
602
+ onClose,
603
+ titleId: "flint-modal-title",
604
+ title: t("modalTitle")
605
+ }
606
+ ),
607
+ /* @__PURE__ */ jsxs2("form", { onSubmit: handleSubmit, style: { padding: "20px 24px 24px" }, children: [
608
+ /* @__PURE__ */ jsxs2("div", { style: { marginBottom: 18 }, children: [
609
+ /* @__PURE__ */ jsx2(FieldLabel, { colors, children: t("severityLabel") }),
610
+ /* @__PURE__ */ jsx2("div", { style: { display: "grid", gridTemplateColumns: "repeat(4,1fr)", gap: 8 }, children: SEVERITIES.map((sev) => /* @__PURE__ */ jsx2(
611
+ SeverityButton,
612
+ {
613
+ sev,
614
+ label: t(`severity_${sev}_label`),
615
+ selected: severity === sev,
616
+ hint: t(`severity_${sev}_hint`),
617
+ color: SEV_COLOR[sev],
618
+ accent: colors.accent,
619
+ border: inputBorder,
620
+ bg: colors.backgroundSecondary,
621
+ text: colors.text,
622
+ onClick: () => setSeverity(sev)
623
+ },
624
+ sev
625
+ )) })
626
+ ] }),
627
+ /* @__PURE__ */ jsxs2("div", { style: { marginBottom: 14 }, children: [
628
+ /* @__PURE__ */ jsx2(FieldLabel, { colors, htmlFor: "flint-description", children: t("whatIsBrokenLabel") }),
629
+ /* @__PURE__ */ jsx2(
630
+ "textarea",
631
+ {
632
+ id: "flint-description",
633
+ style: { ...inputStyle, resize: "vertical", minHeight: 80 },
634
+ value: description,
635
+ onChange: (e) => setDescription(e.target.value),
636
+ placeholder: t("whatIsBrokenPlaceholder"),
637
+ required: true
638
+ }
639
+ )
640
+ ] }),
641
+ /* @__PURE__ */ jsxs2("div", { style: { marginBottom: 14 }, children: [
642
+ /* @__PURE__ */ jsx2(FieldLabel, { colors, htmlFor: "flint-expected", children: t("expectedBehaviorLabel") }),
643
+ /* @__PURE__ */ jsx2(
644
+ "textarea",
645
+ {
646
+ id: "flint-expected",
647
+ style: { ...inputStyle, resize: "vertical", minHeight: 72 },
648
+ value: expectedBehavior,
649
+ onChange: (e) => setExpectedBehavior(e.target.value),
650
+ placeholder: t("expectedBehaviorPlaceholder")
651
+ }
652
+ )
653
+ ] }),
654
+ /* @__PURE__ */ jsxs2("div", { style: { marginBottom: 20 }, children: [
655
+ /* @__PURE__ */ jsx2(FieldLabel, { colors, children: t("screenshotLabel") }),
656
+ screenshot ? /* @__PURE__ */ jsxs2("div", { style: { display: "flex", alignItems: "center", gap: 10 }, children: [
657
+ /* @__PURE__ */ jsx2(
658
+ "img",
659
+ {
660
+ src: URL.createObjectURL(screenshot),
661
+ alt: "Screenshot preview",
662
+ style: { height: 60, borderRadius: 8, objectFit: "cover", border: `1px solid ${inputBorder}` }
411
663
  }
412
664
  ),
413
- /* @__PURE__ */ jsx(
665
+ /* @__PURE__ */ jsx2("span", { style: { fontSize: 13, color: colors.textMuted, flex: 1, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: screenshot.name }),
666
+ /* @__PURE__ */ jsx2(
414
667
  "button",
415
668
  {
416
- onClick: onClose,
669
+ type: "button",
670
+ onClick: () => setScreenshot(null),
671
+ "aria-label": "Remove screenshot",
417
672
  style: {
418
673
  background: "none",
419
674
  border: "none",
420
675
  cursor: "pointer",
421
- fontSize: 15,
676
+ fontSize: 18,
422
677
  color: colors.textMuted,
423
- padding: "4px 8px",
678
+ lineHeight: 1,
679
+ padding: "2px 6px",
680
+ borderRadius: 6,
424
681
  fontFamily: "inherit"
425
682
  },
426
- children: t("cancel")
683
+ children: "\xD7"
427
684
  }
428
685
  )
429
- ] })
430
- ] })
431
- ] })
432
- ] }) });
433
- }
434
- return /* @__PURE__ */ jsx("div", { ref: overlayRef, style: overlayStyle, onClick: handleOverlayClick, children: /* @__PURE__ */ jsxs("div", { style: modalStyle, role: "dialog", "aria-modal": "true", "aria-labelledby": "flint-modal-title", children: [
435
- /* @__PURE__ */ jsx(
436
- ModalHeader,
437
- {
438
- colors,
439
- inputBorder,
440
- showClose: true,
441
- onClose,
442
- titleId: "flint-modal-title",
443
- title: t("modalTitle")
444
- }
445
- ),
446
- /* @__PURE__ */ jsxs("form", { onSubmit: handleSubmit, style: { padding: "20px 24px 24px" }, children: [
447
- /* @__PURE__ */ jsxs("div", { style: { marginBottom: 18 }, children: [
448
- /* @__PURE__ */ jsx(FieldLabel, { colors, children: t("severityLabel") }),
449
- /* @__PURE__ */ jsx("div", { style: { display: "grid", gridTemplateColumns: "repeat(4,1fr)", gap: 8 }, children: SEVERITIES.map((sev) => /* @__PURE__ */ jsx(
450
- SeverityButton,
451
- {
452
- sev,
453
- label: t(`severity_${sev}_label`),
454
- selected: severity === sev,
455
- hint: t(`severity_${sev}_hint`),
456
- color: SEV_COLOR[sev],
457
- accent: colors.accent,
458
- border: inputBorder,
459
- bg: colors.backgroundSecondary,
460
- text: colors.text,
461
- onClick: () => setSeverity(sev)
462
- },
463
- sev
464
- )) })
465
- ] }),
466
- /* @__PURE__ */ jsxs("div", { style: { marginBottom: 14 }, children: [
467
- /* @__PURE__ */ jsx(FieldLabel, { colors, htmlFor: "flint-description", children: t("whatIsBrokenLabel") }),
468
- /* @__PURE__ */ jsx(
469
- "textarea",
470
- {
471
- id: "flint-description",
472
- style: { ...inputStyle, resize: "vertical", minHeight: 80 },
473
- value: description,
474
- onChange: (e) => setDescription(e.target.value),
475
- placeholder: t("whatIsBrokenPlaceholder"),
476
- required: true
477
- }
478
- )
479
- ] }),
480
- /* @__PURE__ */ jsxs("div", { style: { marginBottom: 14 }, children: [
481
- /* @__PURE__ */ jsx(FieldLabel, { colors, htmlFor: "flint-expected", children: t("expectedBehaviorLabel") }),
482
- /* @__PURE__ */ jsx(
483
- "textarea",
484
- {
485
- id: "flint-expected",
486
- style: { ...inputStyle, resize: "vertical", minHeight: 72 },
487
- value: expectedBehavior,
488
- onChange: (e) => setExpectedBehavior(e.target.value),
489
- placeholder: t("expectedBehaviorPlaceholder")
490
- }
491
- )
492
- ] }),
493
- /* @__PURE__ */ jsxs("div", { style: { marginBottom: 20 }, children: [
494
- /* @__PURE__ */ jsx(FieldLabel, { colors, children: t("screenshotLabel") }),
495
- /* @__PURE__ */ jsxs(
496
- "label",
686
+ ] }) : /* @__PURE__ */ jsxs2("div", { style: { display: "flex", gap: 8 }, children: [
687
+ /* @__PURE__ */ jsxs2(
688
+ "button",
689
+ {
690
+ type: "button",
691
+ onClick: () => fileRef.current?.click(),
692
+ style: {
693
+ flex: 1,
694
+ display: "flex",
695
+ alignItems: "center",
696
+ justifyContent: "center",
697
+ gap: 6,
698
+ padding: "10px 13px",
699
+ borderRadius: 10,
700
+ border: `1px dashed ${inputBorder}`,
701
+ cursor: "pointer",
702
+ fontSize: 14,
703
+ color: colors.textMuted,
704
+ background: colors.backgroundSecondary,
705
+ fontFamily: "inherit"
706
+ },
707
+ children: [
708
+ "\u{1F4CE} ",
709
+ t("screenshotAttachFile")
710
+ ]
711
+ }
712
+ ),
713
+ /* @__PURE__ */ jsxs2(
714
+ "button",
715
+ {
716
+ type: "button",
717
+ onClick: () => setAnnotating(true),
718
+ style: {
719
+ flex: 1,
720
+ display: "flex",
721
+ alignItems: "center",
722
+ justifyContent: "center",
723
+ gap: 6,
724
+ padding: "10px 13px",
725
+ borderRadius: 10,
726
+ border: `1px dashed ${inputBorder}`,
727
+ cursor: "pointer",
728
+ fontSize: 14,
729
+ color: colors.textMuted,
730
+ background: colors.backgroundSecondary,
731
+ fontFamily: "inherit"
732
+ },
733
+ children: [
734
+ "\u{1F532} ",
735
+ t("screenshotMarkOnScreen")
736
+ ]
737
+ }
738
+ )
739
+ ] }),
740
+ /* @__PURE__ */ jsx2(
741
+ "input",
742
+ {
743
+ id: "flint-screenshot",
744
+ ref: fileRef,
745
+ type: "file",
746
+ accept: "image/*",
747
+ style: { display: "none" },
748
+ onChange: (e) => setScreenshot(e.target.files?.[0] ?? null)
749
+ }
750
+ )
751
+ ] }),
752
+ /* @__PURE__ */ jsxs2("div", { style: {
753
+ display: "flex",
754
+ alignItems: "center",
755
+ gap: 8,
756
+ padding: "9px 12px",
757
+ borderRadius: 10,
758
+ background: isDark ? "rgba(255,255,255,0.04)" : "rgba(0,77,240,0.04)",
759
+ border: `1px solid ${isDark ? "rgba(255,255,255,0.08)" : "rgba(0,77,240,0.1)"}`,
760
+ marginBottom: 16
761
+ }, children: [
762
+ /* @__PURE__ */ jsx2("span", { style: { fontSize: 16 }, children: "\u{1F3A5}" }),
763
+ /* @__PURE__ */ jsx2("span", { style: { fontSize: 14, color: colors.textMuted, lineHeight: 1.4 }, children: t("replayInfo") })
764
+ ] }),
765
+ status === "error" && /* @__PURE__ */ jsxs2("div", { style: {
766
+ padding: "10px 13px",
767
+ borderRadius: 10,
768
+ background: "rgba(239,68,68,0.08)",
769
+ border: "1px solid rgba(239,68,68,0.2)",
770
+ color: "#f87171",
771
+ fontSize: 14,
772
+ marginBottom: 16
773
+ }, children: [
774
+ "\u26A0\uFE0F ",
775
+ errorMsg || t("errorLabel")
776
+ ] }),
777
+ /* @__PURE__ */ jsxs2(
778
+ "button",
497
779
  {
498
- htmlFor: "flint-screenshot",
780
+ type: "submit",
499
781
  style: {
782
+ width: "100%",
783
+ padding: "13px 20px",
784
+ borderRadius: 12,
785
+ border: "none",
786
+ background: `linear-gradient(135deg, ${colors.accent}, ${colors.accentHover})`,
787
+ color: colors.buttonText,
788
+ fontSize: 17,
789
+ fontWeight: 700,
790
+ cursor: "pointer",
791
+ letterSpacing: "-0.01em",
792
+ boxShadow: accentGlow,
793
+ fontFamily: "inherit",
500
794
  display: "flex",
501
795
  alignItems: "center",
502
- gap: 8,
503
- padding: "10px 13px",
504
- borderRadius: 10,
505
- border: `1px dashed ${inputBorder}`,
506
- cursor: "pointer",
507
- fontSize: 15,
508
- color: colors.textMuted,
509
- background: colors.backgroundSecondary
796
+ justifyContent: "center",
797
+ gap: 8
510
798
  },
511
799
  children: [
512
- "\u{1F4CE} ",
513
- screenshot ? screenshot.name : t("screenshotPlaceholder")
800
+ /* @__PURE__ */ jsx2(SparkIcon, { color: colors.buttonText, size: 15 }),
801
+ t("submitLabel")
514
802
  ]
515
803
  }
516
804
  ),
517
- /* @__PURE__ */ jsx(
518
- "input",
805
+ /* @__PURE__ */ jsx2(
806
+ "button",
519
807
  {
520
- id: "flint-screenshot",
521
- ref: fileRef,
522
- type: "file",
523
- accept: "image/*",
524
- style: { display: "none" },
525
- onChange: (e) => setScreenshot(e.target.files?.[0] ?? null)
808
+ type: "button",
809
+ onClick: onClose,
810
+ style: {
811
+ width: "100%",
812
+ padding: "10px",
813
+ marginTop: 8,
814
+ background: "none",
815
+ border: "none",
816
+ cursor: "pointer",
817
+ fontSize: 15,
818
+ color: colors.textMuted,
819
+ fontFamily: "inherit",
820
+ borderRadius: 8
821
+ },
822
+ children: t("cancel")
526
823
  }
527
824
  )
528
- ] }),
529
- /* @__PURE__ */ jsxs("div", { style: {
530
- display: "flex",
531
- alignItems: "center",
532
- gap: 8,
533
- padding: "9px 12px",
534
- borderRadius: 10,
535
- background: isDark ? "rgba(255,255,255,0.04)" : "rgba(0,77,240,0.04)",
536
- border: `1px solid ${isDark ? "rgba(255,255,255,0.08)" : "rgba(0,77,240,0.1)"}`,
537
- marginBottom: 16
538
- }, children: [
539
- /* @__PURE__ */ jsx("span", { style: { fontSize: 16 }, children: "\u{1F3A5}" }),
540
- /* @__PURE__ */ jsx("span", { style: { fontSize: 14, color: colors.textMuted, lineHeight: 1.4 }, children: t("replayInfo") })
541
- ] }),
542
- status === "error" && /* @__PURE__ */ jsxs("div", { style: {
543
- padding: "10px 13px",
544
- borderRadius: 10,
545
- background: "rgba(239,68,68,0.08)",
546
- border: "1px solid rgba(239,68,68,0.2)",
547
- color: "#f87171",
548
- fontSize: 14,
549
- marginBottom: 16
550
- }, children: [
551
- "\u26A0\uFE0F ",
552
- errorMsg || t("errorLabel")
553
- ] }),
554
- /* @__PURE__ */ jsxs(
555
- "button",
556
- {
557
- type: "submit",
558
- style: {
559
- width: "100%",
560
- padding: "13px 20px",
561
- borderRadius: 12,
562
- border: "none",
563
- background: `linear-gradient(135deg, ${colors.accent}, ${colors.accentHover})`,
564
- color: colors.buttonText,
565
- fontSize: 17,
566
- fontWeight: 700,
567
- cursor: "pointer",
568
- letterSpacing: "-0.01em",
569
- boxShadow: accentGlow,
570
- fontFamily: "inherit",
571
- display: "flex",
572
- alignItems: "center",
573
- justifyContent: "center",
574
- gap: 8
575
- },
576
- children: [
577
- /* @__PURE__ */ jsx(SparkIcon, { color: colors.buttonText, size: 15 }),
578
- t("submitLabel")
579
- ]
580
- }
581
- ),
582
- /* @__PURE__ */ jsx(
583
- "button",
584
- {
585
- type: "button",
586
- onClick: onClose,
587
- style: {
588
- width: "100%",
589
- padding: "10px",
590
- marginTop: 8,
591
- background: "none",
592
- border: "none",
593
- cursor: "pointer",
594
- fontSize: 15,
595
- color: colors.textMuted,
596
- fontFamily: "inherit",
597
- borderRadius: 8
598
- },
599
- children: t("cancel")
600
- }
601
- )
602
- ] })
603
- ] }) });
825
+ ] })
826
+ ] }) })
827
+ ] });
604
828
  }
605
829
  function ModalHeader({
606
830
  colors,
@@ -610,14 +834,14 @@ function ModalHeader({
610
834
  titleId,
611
835
  title
612
836
  }) {
613
- return /* @__PURE__ */ jsxs("div", { style: {
837
+ return /* @__PURE__ */ jsxs2("div", { style: {
614
838
  display: "flex",
615
839
  alignItems: "center",
616
840
  gap: 10,
617
841
  padding: "16px 20px 14px",
618
842
  borderBottom: `1px solid ${inputBorder}`
619
843
  }, children: [
620
- /* @__PURE__ */ jsx("div", { style: {
844
+ /* @__PURE__ */ jsx2("div", { style: {
621
845
  width: 28,
622
846
  height: 28,
623
847
  borderRadius: 8,
@@ -627,9 +851,9 @@ function ModalHeader({
627
851
  alignItems: "center",
628
852
  justifyContent: "center",
629
853
  flexShrink: 0
630
- }, children: /* @__PURE__ */ jsx(SparkIcon, { color: colors.accent, size: 13 }) }),
631
- titleId && title ? /* @__PURE__ */ jsx("h2", { id: titleId, style: { margin: 0, fontSize: 16, fontWeight: 600, color: colors.text, letterSpacing: "-0.01em", flex: 1 }, children: title }) : /* @__PURE__ */ jsx("span", { style: { flex: 1, fontSize: 15, fontWeight: 600, color: colors.textMuted }, children: "Flint" }),
632
- showClose && /* @__PURE__ */ jsx(
854
+ }, children: /* @__PURE__ */ jsx2(SparkIcon, { color: colors.accent, size: 13 }) }),
855
+ titleId && title ? /* @__PURE__ */ jsx2("h2", { id: titleId, style: { margin: 0, fontSize: 16, fontWeight: 600, color: colors.text, letterSpacing: "-0.01em", flex: 1 }, children: title }) : /* @__PURE__ */ jsx2("span", { style: { flex: 1, fontSize: 15, fontWeight: 600, color: colors.textMuted }, children: "Flint" }),
856
+ showClose && /* @__PURE__ */ jsx2(
633
857
  "button",
634
858
  {
635
859
  onClick: onClose,
@@ -659,7 +883,7 @@ function FieldLabel({
659
883
  colors,
660
884
  htmlFor
661
885
  }) {
662
- return /* @__PURE__ */ jsx(
886
+ return /* @__PURE__ */ jsx2(
663
887
  "label",
664
888
  {
665
889
  htmlFor,
@@ -677,7 +901,7 @@ function FieldLabel({
677
901
  );
678
902
  }
679
903
  function SendingDots({ color }) {
680
- return /* @__PURE__ */ jsx("span", { style: { display: "inline-flex", gap: 3, alignItems: "center" }, children: [0, 1, 2].map((i) => /* @__PURE__ */ jsx(
904
+ return /* @__PURE__ */ jsx2("span", { style: { display: "inline-flex", gap: 3, alignItems: "center" }, children: [0, 1, 2].map((i) => /* @__PURE__ */ jsx2(
681
905
  "span",
682
906
  {
683
907
  style: {
@@ -693,7 +917,7 @@ function SendingDots({ color }) {
693
917
  )) });
694
918
  }
695
919
  function SeverityButton({ sev, label, selected, hint, color, accent, border, bg, text, onClick }) {
696
- return /* @__PURE__ */ jsxs(
920
+ return /* @__PURE__ */ jsxs2(
697
921
  "button",
698
922
  {
699
923
  type: "button",
@@ -713,18 +937,18 @@ function SeverityButton({ sev, label, selected, hint, color, accent, border, bg,
713
937
  fontFamily: "inherit"
714
938
  },
715
939
  children: [
716
- /* @__PURE__ */ jsx("span", { style: { width: 8, height: 8, borderRadius: "50%", background: color, display: "block" } }),
717
- /* @__PURE__ */ jsx("span", { style: { fontSize: 13, fontWeight: selected ? 700 : 500, color: selected ? accent : text, letterSpacing: "0.02em" }, children: sev }),
718
- /* @__PURE__ */ jsx("span", { style: { fontSize: 11, color: selected ? accent : text, opacity: 0.6, letterSpacing: "0.02em" }, children: label })
940
+ /* @__PURE__ */ jsx2("span", { style: { width: 8, height: 8, borderRadius: "50%", background: color, display: "block" } }),
941
+ /* @__PURE__ */ jsx2("span", { style: { fontSize: 13, fontWeight: selected ? 700 : 500, color: selected ? accent : text, letterSpacing: "0.02em" }, children: sev }),
942
+ /* @__PURE__ */ jsx2("span", { style: { fontSize: 11, color: selected ? accent : text, opacity: 0.6, letterSpacing: "0.02em" }, children: label })
719
943
  ]
720
944
  }
721
945
  );
722
946
  }
723
947
  function SparkIcon({ color = "currentColor", size = 14 }) {
724
- return /* @__PURE__ */ jsx("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: "2.2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: /* @__PURE__ */ jsx("path", { d: "M13 2L3 14h9l-1 8 10-12h-9l1-8z" }) });
948
+ return /* @__PURE__ */ jsx2("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: "2.2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: /* @__PURE__ */ jsx2("path", { d: "M13 2L3 14h9l-1 8 10-12h-9l1-8z" }) });
725
949
  }
726
950
  function CheckIcon({ size = 20 }) {
727
- return /* @__PURE__ */ jsx("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: "#22c55e", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: /* @__PURE__ */ jsx("polyline", { points: "20 6 9 17 4 12" }) });
951
+ return /* @__PURE__ */ jsx2("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: "#22c55e", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: /* @__PURE__ */ jsx2("polyline", { points: "20 6 9 17 4 12" }) });
728
952
  }
729
953
 
730
954
  // src/i18n/index.ts
@@ -750,7 +974,10 @@ var en_default = {
750
974
  expectedBehaviorPlaceholder: "Describe exactly what the user should see or receive after the fix.",
751
975
  screenshotLabel: "Screenshot (optional)",
752
976
  screenshotPlaceholder: "Click to attach...",
977
+ screenshotAttachFile: "Attach file",
978
+ screenshotMarkOnScreen: "Mark on screen",
753
979
  submitLabel: "Submit",
980
+ close: "Close",
754
981
  successTitle: "Bug reported!",
755
982
  successDuplicate: "Looks like a duplicate of an existing bug.",
756
983
  successGitHub: "View GitHub issue",
@@ -897,6 +1124,20 @@ function createConsoleCollector() {
897
1124
 
898
1125
  // src/collectors/network.ts
899
1126
  var MAX_ENTRIES2 = 20;
1127
+ var BLOCKED_HOSTS = /* @__PURE__ */ new Set([
1128
+ "browser-intake-datadoghq.com",
1129
+ "rum.browser-intake-datadoghq.com",
1130
+ "logs.browser-intake-datadoghq.com",
1131
+ "session-replay.browser-intake-datadoghq.com"
1132
+ ]);
1133
+ function isBlockedUrl(url) {
1134
+ try {
1135
+ const host = new URL(url, location.href).hostname;
1136
+ return BLOCKED_HOSTS.has(host) || [...BLOCKED_HOSTS].some((b) => host.endsWith("." + b));
1137
+ } catch {
1138
+ return false;
1139
+ }
1140
+ }
900
1141
  function truncateUrl(url) {
901
1142
  try {
902
1143
  const u = new URL(url, location.href);
@@ -925,13 +1166,15 @@ function createNetworkCollector() {
925
1166
  const url = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
926
1167
  const startTime = Date.now();
927
1168
  const res = await origFetch.call(window, input, init);
928
- push({
929
- method,
930
- url: truncateUrl(url),
931
- status: res.status,
932
- duration: Date.now() - startTime,
933
- timestamp: startTime
934
- });
1169
+ if (!isBlockedUrl(url)) {
1170
+ push({
1171
+ method,
1172
+ url: truncateUrl(url),
1173
+ status: res.status,
1174
+ duration: Date.now() - startTime,
1175
+ timestamp: startTime
1176
+ });
1177
+ }
935
1178
  return res;
936
1179
  };
937
1180
  origXHROpen = XMLHttpRequest.prototype.open;
@@ -939,13 +1182,15 @@ function createNetworkCollector() {
939
1182
  const startTime = Date.now();
940
1183
  const urlStr = typeof url === "string" ? url : url.href;
941
1184
  this.addEventListener("load", () => {
942
- push({
943
- method: method.toUpperCase(),
944
- url: truncateUrl(urlStr),
945
- status: this.status,
946
- duration: Date.now() - startTime,
947
- timestamp: startTime
948
- });
1185
+ if (!isBlockedUrl(urlStr)) {
1186
+ push({
1187
+ method: method.toUpperCase(),
1188
+ url: truncateUrl(urlStr),
1189
+ status: this.status,
1190
+ duration: Date.now() - startTime,
1191
+ timestamp: startTime
1192
+ });
1193
+ }
949
1194
  });
950
1195
  return origXHROpen.apply(this, [
951
1196
  method,
@@ -998,14 +1243,14 @@ var flint = {
998
1243
 
999
1244
  // src/FlintWidget.tsx
1000
1245
  import { record } from "rrweb";
1001
- import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
1246
+ import { Fragment as Fragment2, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
1002
1247
  var REPLAY_WINDOW_MS = 6e4;
1003
1248
  function FlintWidget(props) {
1004
1249
  const { locale = "en-US" } = props;
1005
- useEffect2(() => {
1250
+ useEffect3(() => {
1006
1251
  i18n_default.changeLanguage(locale);
1007
1252
  }, [locale]);
1008
- return /* @__PURE__ */ jsx2(I18nextProvider, { i18n: i18n_default, children: /* @__PURE__ */ jsx2(WidgetContent, { ...props }) });
1253
+ return /* @__PURE__ */ jsx3(I18nextProvider, { i18n: i18n_default, children: /* @__PURE__ */ jsx3(WidgetContent, { ...props }) });
1009
1254
  }
1010
1255
  function WidgetContent({
1011
1256
  projectKey,
@@ -1025,13 +1270,13 @@ function WidgetContent({
1025
1270
  return typeof src === "function" ? src() : src;
1026
1271
  };
1027
1272
  const { t } = useTranslation2();
1028
- const [open, setOpen] = useState2(false);
1029
- const [hovered, setHovered] = useState2(false);
1273
+ const [open, setOpen] = useState3(false);
1274
+ const [hovered, setHovered] = useState3(false);
1030
1275
  const colors = resolveTheme(theme);
1031
- const consoleCollector = useRef2(null);
1032
- const networkCollector = useRef2(null);
1033
- const replayEvents = useRef2([]);
1034
- const stopReplay = useRef2(null);
1276
+ const consoleCollector = useRef3(null);
1277
+ const networkCollector = useRef3(null);
1278
+ const replayEvents = useRef3([]);
1279
+ const stopReplay = useRef3(null);
1035
1280
  if (!consoleCollector.current) {
1036
1281
  consoleCollector.current = createConsoleCollector();
1037
1282
  consoleCollector.current.start();
@@ -1040,7 +1285,7 @@ function WidgetContent({
1040
1285
  networkCollector.current = createNetworkCollector();
1041
1286
  networkCollector.current.start();
1042
1287
  }
1043
- useEffect2(() => {
1288
+ useEffect3(() => {
1044
1289
  const stopFn = record({
1045
1290
  emit(event) {
1046
1291
  replayEvents.current.push(event);
@@ -1058,8 +1303,8 @@ function WidgetContent({
1058
1303
  };
1059
1304
  }, []);
1060
1305
  const label = buttonLabel ?? t("buttonLabel");
1061
- return /* @__PURE__ */ jsxs2(Fragment, { children: [
1062
- /* @__PURE__ */ jsxs2(
1306
+ return /* @__PURE__ */ jsxs3(Fragment2, { children: [
1307
+ /* @__PURE__ */ jsxs3(
1063
1308
  "button",
1064
1309
  {
1065
1310
  onClick: () => setOpen(true),
@@ -1089,12 +1334,12 @@ function WidgetContent({
1089
1334
  letterSpacing: "0.01em"
1090
1335
  },
1091
1336
  children: [
1092
- /* @__PURE__ */ jsx2(SparkIcon2, {}),
1337
+ /* @__PURE__ */ jsx3(SparkIcon2, {}),
1093
1338
  label
1094
1339
  ]
1095
1340
  }
1096
1341
  ),
1097
- open && /* @__PURE__ */ jsx2(
1342
+ open && /* @__PURE__ */ jsx3(
1098
1343
  FlintModal,
1099
1344
  {
1100
1345
  projectKey,
@@ -1114,7 +1359,7 @@ function WidgetContent({
1114
1359
  ] });
1115
1360
  }
1116
1361
  function SparkIcon2() {
1117
- return /* @__PURE__ */ jsx2(
1362
+ return /* @__PURE__ */ jsx3(
1118
1363
  "svg",
1119
1364
  {
1120
1365
  width: "14",
@@ -1126,7 +1371,7 @@ function SparkIcon2() {
1126
1371
  strokeLinecap: "round",
1127
1372
  strokeLinejoin: "round",
1128
1373
  "aria-hidden": "true",
1129
- children: /* @__PURE__ */ jsx2("path", { d: "M13 2L3 14h9l-1 8 10-12h-9l1-8z" })
1374
+ children: /* @__PURE__ */ jsx3("path", { d: "M13 2L3 14h9l-1 8 10-12h-9l1-8z" })
1130
1375
  }
1131
1376
  );
1132
1377
  }