@diegotsi/flint-react 0.6.0 → 1.0.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/index.cjs +637 -669
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +35 -8
- package/dist/index.d.ts +35 -8
- package/dist/index.js +622 -664
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
package/dist/index.js
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
// src/FlintWidget.tsx
|
|
2
|
-
import { useState as useState3, useEffect as useEffect3, useRef as useRef3, useCallback as useCallback2 } from "react";
|
|
3
|
-
import { I18nextProvider, useTranslation as useTranslation2 } from "react-i18next";
|
|
4
|
-
|
|
5
1
|
// src/FlintModal.tsx
|
|
6
|
-
import {
|
|
2
|
+
import { useCallback, useEffect as useEffect2, useRef as useRef2, useState as useState2 } from "react";
|
|
7
3
|
import { useTranslation } from "react-i18next";
|
|
8
4
|
|
|
5
|
+
// src/api.ts
|
|
6
|
+
import { submitReplay, submitReport } from "@flint/core";
|
|
7
|
+
|
|
9
8
|
// src/ScreenAnnotator.tsx
|
|
10
|
-
import { useEffect, useRef, useState } from "react";
|
|
11
9
|
import { domToCanvas } from "modern-screenshot";
|
|
10
|
+
import { useEffect, useRef, useState } from "react";
|
|
12
11
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
13
12
|
function normalizeRect(startX, startY, endX, endY) {
|
|
14
13
|
return {
|
|
@@ -53,9 +52,7 @@ function ScreenAnnotator({ zIndex, onCapture, onCancel }) {
|
|
|
53
52
|
const dpr = window.devicePixelRatio ?? 1;
|
|
54
53
|
const vw = window.innerWidth;
|
|
55
54
|
const vh = window.innerHeight;
|
|
56
|
-
await new Promise(
|
|
57
|
-
(resolve) => requestAnimationFrame(() => requestAnimationFrame(() => resolve()))
|
|
58
|
-
);
|
|
55
|
+
await new Promise((resolve) => requestAnimationFrame(() => requestAnimationFrame(() => resolve())));
|
|
59
56
|
try {
|
|
60
57
|
const fullCanvas = await domToCanvas(document.documentElement, {
|
|
61
58
|
scale: dpr,
|
|
@@ -70,17 +67,7 @@ function ScreenAnnotator({ zIndex, onCapture, onCancel }) {
|
|
|
70
67
|
canvas.width = vw * dpr;
|
|
71
68
|
canvas.height = vh * dpr;
|
|
72
69
|
const ctx = canvas.getContext("2d");
|
|
73
|
-
ctx.drawImage(
|
|
74
|
-
fullCanvas,
|
|
75
|
-
0,
|
|
76
|
-
0,
|
|
77
|
-
vw * dpr,
|
|
78
|
-
vh * dpr,
|
|
79
|
-
0,
|
|
80
|
-
0,
|
|
81
|
-
vw * dpr,
|
|
82
|
-
vh * dpr
|
|
83
|
-
);
|
|
70
|
+
ctx.drawImage(fullCanvas, 0, 0, vw * dpr, vh * dpr, 0, 0, vw * dpr, vh * dpr);
|
|
84
71
|
ctx.fillStyle = "rgba(255,200,0,0.25)";
|
|
85
72
|
ctx.fillRect(finalRect.x * dpr, finalRect.y * dpr, finalRect.w * dpr, finalRect.h * dpr);
|
|
86
73
|
ctx.strokeStyle = "#f97316";
|
|
@@ -118,123 +105,50 @@ function ScreenAnnotator({ zIndex, onCapture, onCancel }) {
|
|
|
118
105
|
pointerEvents: isCapturing ? "none" : "auto"
|
|
119
106
|
},
|
|
120
107
|
children: [
|
|
121
|
-
!isCapturing && /* @__PURE__ */ jsx(
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
108
|
+
!isCapturing && /* @__PURE__ */ jsx(
|
|
109
|
+
"div",
|
|
110
|
+
{
|
|
111
|
+
style: {
|
|
112
|
+
position: "absolute",
|
|
113
|
+
top: 16,
|
|
114
|
+
left: "50%",
|
|
115
|
+
transform: "translateX(-50%)",
|
|
116
|
+
background: "rgba(0,0,0,0.75)",
|
|
117
|
+
color: "#fff",
|
|
118
|
+
padding: "8px 18px",
|
|
119
|
+
borderRadius: 8,
|
|
120
|
+
fontSize: 14,
|
|
121
|
+
fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif',
|
|
122
|
+
pointerEvents: "none",
|
|
123
|
+
whiteSpace: "nowrap",
|
|
124
|
+
backdropFilter: "blur(4px)"
|
|
125
|
+
},
|
|
126
|
+
children: "Drag to highlight the problem area \xA0\xB7\xA0 Esc to cancel"
|
|
127
|
+
}
|
|
128
|
+
),
|
|
129
|
+
rect && phase === "selecting" && /* @__PURE__ */ jsx(
|
|
130
|
+
"div",
|
|
131
|
+
{
|
|
132
|
+
style: {
|
|
133
|
+
position: "absolute",
|
|
134
|
+
left: rect.x,
|
|
135
|
+
top: rect.y,
|
|
136
|
+
width: rect.w,
|
|
137
|
+
height: rect.h,
|
|
138
|
+
background: "rgba(255,200,0,0.2)",
|
|
139
|
+
border: "2px dashed #f97316",
|
|
140
|
+
boxSizing: "border-box",
|
|
141
|
+
pointerEvents: "none"
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
)
|
|
147
145
|
]
|
|
148
146
|
}
|
|
149
147
|
);
|
|
150
148
|
}
|
|
151
149
|
|
|
152
|
-
// src/api.ts
|
|
153
|
-
import { gzipSync } from "fflate";
|
|
154
|
-
async function submitReport(serverUrl, projectKey, payload, screenshot) {
|
|
155
|
-
const url = `${serverUrl.replace(/\/$/, "")}/api/v1/bug-reports`;
|
|
156
|
-
let body;
|
|
157
|
-
let headers = {
|
|
158
|
-
"x-project-key": projectKey
|
|
159
|
-
};
|
|
160
|
-
if (screenshot) {
|
|
161
|
-
const form = new FormData();
|
|
162
|
-
form.append("reporterId", payload.reporterId);
|
|
163
|
-
form.append("reporterName", payload.reporterName);
|
|
164
|
-
form.append("description", payload.description);
|
|
165
|
-
if (payload.expectedBehavior) form.append("expectedBehavior", payload.expectedBehavior);
|
|
166
|
-
if (payload.stepsToReproduce) form.append("stepsToReproduce", JSON.stringify(payload.stepsToReproduce));
|
|
167
|
-
if (payload.externalReplayUrl) form.append("externalReplayUrl", payload.externalReplayUrl);
|
|
168
|
-
if (payload.additionalContext) form.append("additionalContext", payload.additionalContext);
|
|
169
|
-
form.append("severity", payload.severity);
|
|
170
|
-
if (payload.url) form.append("url", payload.url);
|
|
171
|
-
if (payload.meta) form.append("meta", JSON.stringify(payload.meta));
|
|
172
|
-
form.append("screenshot", screenshot);
|
|
173
|
-
body = form;
|
|
174
|
-
} else {
|
|
175
|
-
body = JSON.stringify(payload);
|
|
176
|
-
headers["Content-Type"] = "application/json";
|
|
177
|
-
}
|
|
178
|
-
const res = await fetch(url, { method: "POST", headers, body });
|
|
179
|
-
if (!res.ok) {
|
|
180
|
-
const err = await res.json().catch(() => ({ error: "Unknown error" }));
|
|
181
|
-
throw new Error(err.error ?? `HTTP ${res.status}`);
|
|
182
|
-
}
|
|
183
|
-
return res.json();
|
|
184
|
-
}
|
|
185
|
-
async function submitReplay(serverUrl, projectKey, reportId, events) {
|
|
186
|
-
const json = JSON.stringify(events);
|
|
187
|
-
const encoded = new TextEncoder().encode(json);
|
|
188
|
-
const compressed = gzipSync(encoded);
|
|
189
|
-
const url = `${serverUrl.replace(/\/$/, "")}/api/v1/bug-reports/${reportId}/replay`;
|
|
190
|
-
await fetch(url, {
|
|
191
|
-
method: "POST",
|
|
192
|
-
headers: {
|
|
193
|
-
"x-project-key": projectKey,
|
|
194
|
-
"Content-Type": "application/octet-stream"
|
|
195
|
-
},
|
|
196
|
-
body: compressed.buffer
|
|
197
|
-
});
|
|
198
|
-
}
|
|
199
|
-
|
|
200
150
|
// src/theme.ts
|
|
201
|
-
|
|
202
|
-
background: "rgba(255,255,255,0.90)",
|
|
203
|
-
backgroundSecondary: "rgba(249,250,251,0.75)",
|
|
204
|
-
accent: "#2563eb",
|
|
205
|
-
accentHover: "#1d4ed8",
|
|
206
|
-
text: "#111827",
|
|
207
|
-
textMuted: "#6b7280",
|
|
208
|
-
border: "rgba(255,255,255,0.9)",
|
|
209
|
-
shadow: "0 32px 80px rgba(0,0,0,0.18), 0 8px 32px rgba(0,0,0,0.1), 0 0 0 1px rgba(0,0,0,0.04)",
|
|
210
|
-
buttonText: "#ffffff",
|
|
211
|
-
backdropFilter: "blur(32px) saturate(1.8)"
|
|
212
|
-
};
|
|
213
|
-
var dark = {
|
|
214
|
-
background: "rgba(15,20,35,0.88)",
|
|
215
|
-
backgroundSecondary: "rgba(5,8,18,0.65)",
|
|
216
|
-
accent: "#f97316",
|
|
217
|
-
accentHover: "#ea6c0a",
|
|
218
|
-
text: "#dde3ef",
|
|
219
|
-
textMuted: "#6b7a93",
|
|
220
|
-
border: "rgba(255,255,255,0.08)",
|
|
221
|
-
shadow: "0 24px 60px rgba(0,0,0,0.6), 0 0 0 1px rgba(255,255,255,0.04)",
|
|
222
|
-
buttonText: "#ffffff",
|
|
223
|
-
backdropFilter: "blur(32px) saturate(1.6)"
|
|
224
|
-
};
|
|
225
|
-
function resolveTheme(theme) {
|
|
226
|
-
if (theme === "dark") return dark;
|
|
227
|
-
if (theme === "light") return light;
|
|
228
|
-
const override = theme;
|
|
229
|
-
return {
|
|
230
|
-
...light,
|
|
231
|
-
background: override.background ?? light.background,
|
|
232
|
-
accent: override.accent ?? light.accent,
|
|
233
|
-
accentHover: override.accent ?? light.accentHover,
|
|
234
|
-
text: override.text ?? light.text,
|
|
235
|
-
border: override.border ?? light.border
|
|
236
|
-
};
|
|
237
|
-
}
|
|
151
|
+
import { resolveTheme } from "@flint/core";
|
|
238
152
|
|
|
239
153
|
// src/FlintModal.tsx
|
|
240
154
|
import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
@@ -294,7 +208,12 @@ function FlintModal({
|
|
|
294
208
|
getNetworkErrors,
|
|
295
209
|
getReplayEvents,
|
|
296
210
|
getExternalReplayUrl,
|
|
297
|
-
initialSelection = ""
|
|
211
|
+
initialSelection = "",
|
|
212
|
+
enableScreenshot = true,
|
|
213
|
+
statusPageUrl,
|
|
214
|
+
onBeforeSubmit,
|
|
215
|
+
onSuccess,
|
|
216
|
+
onError
|
|
298
217
|
}) {
|
|
299
218
|
const { t } = useTranslation();
|
|
300
219
|
const colors = resolveTheme(theme);
|
|
@@ -354,33 +273,40 @@ function FlintModal({
|
|
|
354
273
|
lang: textLang
|
|
355
274
|
};
|
|
356
275
|
}
|
|
276
|
+
const payload = {
|
|
277
|
+
reporterId: user?.id ?? "anonymous",
|
|
278
|
+
reporterName: user?.name ?? "Anonymous",
|
|
279
|
+
reporterEmail: user?.email,
|
|
280
|
+
description: isText ? `[Text issue] "${textOriginal.trim()}" \u2192 "${textSuggested.trim()}"` : description.trim(),
|
|
281
|
+
expectedBehavior: !isText ? expectedBehavior.trim() || void 0 : void 0,
|
|
282
|
+
externalReplayUrl: getExternalReplayUrl() || void 0,
|
|
283
|
+
severity: isText ? "P3" : severity,
|
|
284
|
+
url: window.location.href,
|
|
285
|
+
meta: collectedMeta,
|
|
286
|
+
label: isText ? "TEXT" : void 0
|
|
287
|
+
};
|
|
288
|
+
if (onBeforeSubmit) {
|
|
289
|
+
const proceed = await onBeforeSubmit(payload);
|
|
290
|
+
if (!proceed) {
|
|
291
|
+
setStatus("idle");
|
|
292
|
+
return;
|
|
293
|
+
}
|
|
294
|
+
}
|
|
357
295
|
try {
|
|
358
|
-
const res = await submitReport(
|
|
359
|
-
serverUrl,
|
|
360
|
-
projectKey,
|
|
361
|
-
{
|
|
362
|
-
reporterId: user?.id ?? "anonymous",
|
|
363
|
-
reporterName: user?.name ?? "Anonymous",
|
|
364
|
-
description: isText ? `[Text issue] "${textOriginal.trim()}" \u2192 "${textSuggested.trim()}"` : description.trim(),
|
|
365
|
-
expectedBehavior: !isText ? expectedBehavior.trim() || void 0 : void 0,
|
|
366
|
-
externalReplayUrl: getExternalReplayUrl() || void 0,
|
|
367
|
-
severity: isText ? "P3" : severity,
|
|
368
|
-
url: window.location.href,
|
|
369
|
-
meta: collectedMeta,
|
|
370
|
-
label: isText ? "TEXT" : void 0
|
|
371
|
-
},
|
|
372
|
-
!isText ? screenshot ?? void 0 : void 0
|
|
373
|
-
);
|
|
296
|
+
const res = await submitReport(serverUrl, projectKey, payload, !isText ? screenshot ?? void 0 : void 0);
|
|
374
297
|
setResult(res);
|
|
375
298
|
setStatus("success");
|
|
299
|
+
onSuccess?.(res);
|
|
376
300
|
const events = getReplayEvents();
|
|
377
301
|
if (events.length > 0) {
|
|
378
302
|
submitReplay(serverUrl, projectKey, res.id, events).catch(() => {
|
|
379
303
|
});
|
|
380
304
|
}
|
|
381
305
|
} catch (err) {
|
|
382
|
-
|
|
306
|
+
const error = err instanceof Error ? err : new Error(t("errorLabel"));
|
|
307
|
+
setErrorMsg(error.message);
|
|
383
308
|
setStatus("error");
|
|
309
|
+
onError?.(error);
|
|
384
310
|
}
|
|
385
311
|
};
|
|
386
312
|
const inputBorder = isDark ? "rgba(255,255,255,0.1)" : "rgba(0,0,0,0.1)";
|
|
@@ -430,157 +356,249 @@ function FlintModal({
|
|
|
430
356
|
const isSuccess = status === "success";
|
|
431
357
|
const ringBorder = isSuccess ? "3px solid #22c55e" : `3px solid ${isDark ? "rgba(255,255,255,0.08)" : "rgba(0,0,0,0.08)"}`;
|
|
432
358
|
const ringTopColor = isSuccess ? "#22c55e" : colors.accent;
|
|
433
|
-
return /* @__PURE__ */ jsx2("div", { style: overlayStyle, children: /* @__PURE__ */ jsxs2(
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
359
|
+
return /* @__PURE__ */ jsx2("div", { style: overlayStyle, children: /* @__PURE__ */ jsxs2(
|
|
360
|
+
"div",
|
|
361
|
+
{
|
|
362
|
+
style: modalStyle,
|
|
363
|
+
role: "dialog",
|
|
364
|
+
"aria-modal": "true",
|
|
365
|
+
"aria-label": isSuccess ? t("successTitle") : t("sending"),
|
|
366
|
+
children: [
|
|
367
|
+
/* @__PURE__ */ jsx2(ModalHeader, { colors, inputBorder, showClose: false, onClose }),
|
|
368
|
+
/* @__PURE__ */ jsxs2(
|
|
369
|
+
"div",
|
|
370
|
+
{
|
|
371
|
+
style: {
|
|
372
|
+
padding: "40px 32px 48px",
|
|
373
|
+
textAlign: "center",
|
|
374
|
+
display: "flex",
|
|
375
|
+
flexDirection: "column",
|
|
376
|
+
alignItems: "center"
|
|
377
|
+
},
|
|
378
|
+
children: [
|
|
379
|
+
/* @__PURE__ */ jsxs2("div", { style: { position: "relative", width: 80, height: 80, marginBottom: 28 }, children: [
|
|
380
|
+
/* @__PURE__ */ jsx2(
|
|
381
|
+
"div",
|
|
382
|
+
{
|
|
383
|
+
style: {
|
|
384
|
+
position: "absolute",
|
|
385
|
+
inset: -10,
|
|
386
|
+
borderRadius: "50%",
|
|
387
|
+
border: `1.5px solid ${colors.accent}`,
|
|
388
|
+
animation: "_flint_ripple 1.8s ease-out infinite",
|
|
389
|
+
opacity: isSuccess ? 0 : 1,
|
|
390
|
+
transition: "opacity 0.3s ease"
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
),
|
|
394
|
+
/* @__PURE__ */ jsx2(
|
|
395
|
+
"div",
|
|
396
|
+
{
|
|
397
|
+
style: {
|
|
398
|
+
position: "absolute",
|
|
399
|
+
inset: -10,
|
|
400
|
+
borderRadius: "50%",
|
|
401
|
+
border: `1.5px solid ${colors.accent}`,
|
|
402
|
+
animation: "_flint_ripple 1.8s ease-out infinite 0.6s",
|
|
403
|
+
opacity: isSuccess ? 0 : 1,
|
|
404
|
+
transition: "opacity 0.3s ease"
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
),
|
|
408
|
+
/* @__PURE__ */ jsx2(
|
|
409
|
+
"div",
|
|
410
|
+
{
|
|
411
|
+
style: {
|
|
412
|
+
position: "absolute",
|
|
413
|
+
inset: 0,
|
|
414
|
+
borderRadius: "50%",
|
|
415
|
+
border: ringBorder,
|
|
416
|
+
borderTopColor: ringTopColor,
|
|
417
|
+
animation: isSuccess ? "none" : "_flint_spin 0.85s linear infinite",
|
|
418
|
+
transition: "border-color 0.45s ease, border-top-color 0.45s ease"
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
),
|
|
422
|
+
/* @__PURE__ */ jsxs2("div", { style: { position: "absolute", inset: 14, borderRadius: "50%" }, children: [
|
|
423
|
+
/* @__PURE__ */ jsx2(
|
|
424
|
+
"div",
|
|
425
|
+
{
|
|
426
|
+
style: {
|
|
427
|
+
position: "absolute",
|
|
428
|
+
inset: 0,
|
|
429
|
+
borderRadius: "50%",
|
|
430
|
+
background: `linear-gradient(135deg, ${colors.accent}30, ${colors.accentHover}50)`,
|
|
431
|
+
display: "flex",
|
|
432
|
+
alignItems: "center",
|
|
433
|
+
justifyContent: "center",
|
|
434
|
+
animation: isSuccess ? "none" : "_flint_pulse 2s ease-in-out infinite",
|
|
435
|
+
opacity: isSuccess ? 0 : 1,
|
|
436
|
+
transition: "opacity 0.3s ease"
|
|
437
|
+
},
|
|
438
|
+
children: /* @__PURE__ */ jsx2(SparkIcon, { color: colors.accent, size: 20 })
|
|
439
|
+
}
|
|
440
|
+
),
|
|
441
|
+
/* @__PURE__ */ jsx2(
|
|
442
|
+
"div",
|
|
443
|
+
{
|
|
444
|
+
style: {
|
|
445
|
+
position: "absolute",
|
|
446
|
+
inset: 0,
|
|
447
|
+
borderRadius: "50%",
|
|
448
|
+
background: "rgba(34,197,94,0.15)",
|
|
449
|
+
display: "flex",
|
|
450
|
+
alignItems: "center",
|
|
451
|
+
justifyContent: "center",
|
|
452
|
+
opacity: isSuccess ? 1 : 0,
|
|
453
|
+
transform: isSuccess ? "scale(1)" : "scale(0.65)",
|
|
454
|
+
transition: "opacity 0.35s ease 0.2s, transform 0.4s cubic-bezier(0.16,1,0.3,1) 0.2s"
|
|
455
|
+
},
|
|
456
|
+
children: /* @__PURE__ */ jsx2(CheckIcon, { size: 20 })
|
|
457
|
+
}
|
|
458
|
+
)
|
|
459
|
+
] })
|
|
460
|
+
] }),
|
|
461
|
+
/* @__PURE__ */ jsxs2("div", { style: { position: "relative", height: 26, width: "100%", marginBottom: 10 }, children: [
|
|
462
|
+
/* @__PURE__ */ jsx2(
|
|
463
|
+
"div",
|
|
464
|
+
{
|
|
465
|
+
style: {
|
|
466
|
+
position: "absolute",
|
|
467
|
+
inset: 0,
|
|
468
|
+
display: "flex",
|
|
469
|
+
alignItems: "center",
|
|
470
|
+
justifyContent: "center",
|
|
471
|
+
fontSize: 19,
|
|
472
|
+
fontWeight: 700,
|
|
473
|
+
color: colors.text,
|
|
474
|
+
letterSpacing: "-0.02em",
|
|
475
|
+
opacity: isSuccess ? 0 : 1,
|
|
476
|
+
transition: "opacity 0.25s ease",
|
|
477
|
+
pointerEvents: "none"
|
|
478
|
+
},
|
|
479
|
+
children: t("sending")
|
|
480
|
+
}
|
|
481
|
+
),
|
|
482
|
+
/* @__PURE__ */ jsx2(
|
|
483
|
+
"div",
|
|
484
|
+
{
|
|
485
|
+
style: {
|
|
486
|
+
position: "absolute",
|
|
487
|
+
inset: 0,
|
|
488
|
+
display: "flex",
|
|
489
|
+
alignItems: "center",
|
|
490
|
+
justifyContent: "center",
|
|
491
|
+
fontSize: 19,
|
|
492
|
+
fontWeight: 700,
|
|
493
|
+
color: colors.text,
|
|
494
|
+
letterSpacing: "-0.02em",
|
|
495
|
+
opacity: isSuccess ? 1 : 0,
|
|
496
|
+
transform: isSuccess ? "translateY(0)" : "translateY(6px)",
|
|
497
|
+
transition: "opacity 0.35s ease 0.25s, transform 0.35s ease 0.25s",
|
|
498
|
+
pointerEvents: isSuccess ? "auto" : "none"
|
|
499
|
+
},
|
|
500
|
+
children: t("successTitle")
|
|
501
|
+
}
|
|
502
|
+
)
|
|
503
|
+
] }),
|
|
504
|
+
/* @__PURE__ */ jsxs2("div", { style: { position: "relative", minHeight: 76, width: "100%" }, children: [
|
|
505
|
+
/* @__PURE__ */ jsxs2(
|
|
506
|
+
"div",
|
|
507
|
+
{
|
|
508
|
+
style: {
|
|
509
|
+
position: "absolute",
|
|
510
|
+
inset: 0,
|
|
511
|
+
display: "flex",
|
|
512
|
+
alignItems: "center",
|
|
513
|
+
justifyContent: "center",
|
|
514
|
+
gap: 6,
|
|
515
|
+
color: colors.textMuted,
|
|
516
|
+
fontSize: 15,
|
|
517
|
+
opacity: isSuccess ? 0 : 1,
|
|
518
|
+
transition: "opacity 0.2s ease",
|
|
519
|
+
pointerEvents: "none"
|
|
520
|
+
},
|
|
521
|
+
children: [
|
|
522
|
+
/* @__PURE__ */ jsx2("span", { children: t("capturingContext") }),
|
|
523
|
+
/* @__PURE__ */ jsx2(SendingDots, { color: colors.accent })
|
|
524
|
+
]
|
|
525
|
+
}
|
|
526
|
+
),
|
|
527
|
+
/* @__PURE__ */ jsxs2(
|
|
528
|
+
"div",
|
|
529
|
+
{
|
|
530
|
+
style: {
|
|
531
|
+
position: "absolute",
|
|
532
|
+
inset: 0,
|
|
533
|
+
display: "flex",
|
|
534
|
+
flexDirection: "column",
|
|
535
|
+
alignItems: "center",
|
|
536
|
+
gap: 10,
|
|
537
|
+
opacity: isSuccess ? 1 : 0,
|
|
538
|
+
transform: isSuccess ? "translateY(0)" : "translateY(8px)",
|
|
539
|
+
transition: "opacity 0.35s ease 0.35s, transform 0.35s ease 0.35s",
|
|
540
|
+
pointerEvents: isSuccess ? "auto" : "none"
|
|
541
|
+
},
|
|
542
|
+
children: [
|
|
543
|
+
/* @__PURE__ */ jsx2("p", { style: { fontSize: 15, color: colors.textMuted, margin: 0 }, children: result ? `ID: ${result.id}` : "" }),
|
|
544
|
+
statusPageUrl && user?.id && /* @__PURE__ */ jsxs2(
|
|
545
|
+
"a",
|
|
546
|
+
{
|
|
547
|
+
href: `${statusPageUrl}/status?project_key=${encodeURIComponent(projectKey)}&reporter_id=${encodeURIComponent(user.id)}&server_url=${encodeURIComponent(serverUrl)}`,
|
|
548
|
+
target: "_blank",
|
|
549
|
+
rel: "noreferrer",
|
|
550
|
+
style: {
|
|
551
|
+
fontSize: 14,
|
|
552
|
+
color: colors.accent,
|
|
553
|
+
textDecoration: "none",
|
|
554
|
+
fontWeight: 600,
|
|
555
|
+
animation: "_flint_success_up 0.35s ease 0.4s both"
|
|
556
|
+
},
|
|
557
|
+
children: [
|
|
558
|
+
"\u{1F4CB}",
|
|
559
|
+
" Track your bugs ",
|
|
560
|
+
"\u2192"
|
|
561
|
+
]
|
|
562
|
+
}
|
|
563
|
+
),
|
|
564
|
+
/* @__PURE__ */ jsx2(
|
|
565
|
+
"button",
|
|
566
|
+
{
|
|
567
|
+
onClick: onClose,
|
|
568
|
+
style: {
|
|
569
|
+
width: "100%",
|
|
570
|
+
padding: "13px 20px",
|
|
571
|
+
borderRadius: 12,
|
|
572
|
+
border: "none",
|
|
573
|
+
background: `linear-gradient(135deg, ${colors.accent}, ${colors.accentHover})`,
|
|
574
|
+
color: colors.buttonText,
|
|
575
|
+
fontSize: 17,
|
|
576
|
+
fontWeight: 700,
|
|
577
|
+
cursor: "pointer",
|
|
578
|
+
letterSpacing: "-0.01em",
|
|
579
|
+
boxShadow: accentGlow,
|
|
580
|
+
fontFamily: "inherit",
|
|
581
|
+
display: "flex",
|
|
582
|
+
alignItems: "center",
|
|
583
|
+
justifyContent: "center",
|
|
584
|
+
gap: 8
|
|
585
|
+
},
|
|
586
|
+
children: t("close")
|
|
587
|
+
}
|
|
588
|
+
)
|
|
589
|
+
]
|
|
590
|
+
}
|
|
591
|
+
)
|
|
592
|
+
] })
|
|
593
|
+
]
|
|
594
|
+
}
|
|
595
|
+
)
|
|
596
|
+
]
|
|
597
|
+
}
|
|
598
|
+
) });
|
|
581
599
|
}
|
|
582
600
|
return /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
583
|
-
annotating && /* @__PURE__ */ jsx2(
|
|
601
|
+
enableScreenshot && annotating && /* @__PURE__ */ jsx2(
|
|
584
602
|
ScreenAnnotator,
|
|
585
603
|
{
|
|
586
604
|
zIndex: zIndex + 1,
|
|
@@ -604,37 +622,43 @@ function FlintModal({
|
|
|
604
622
|
}
|
|
605
623
|
),
|
|
606
624
|
/* @__PURE__ */ jsxs2("form", { onSubmit: handleSubmit, style: { padding: "20px 24px 24px" }, children: [
|
|
607
|
-
/* @__PURE__ */ jsx2(
|
|
608
|
-
|
|
609
|
-
gap: 4,
|
|
610
|
-
marginBottom: 20,
|
|
611
|
-
background: colors.backgroundSecondary,
|
|
612
|
-
borderRadius: 12,
|
|
613
|
-
padding: 4,
|
|
614
|
-
border: `1px solid ${inputBorder}`
|
|
615
|
-
}, children: ["bug", "text"].map((m) => /* @__PURE__ */ jsx2(
|
|
616
|
-
"button",
|
|
625
|
+
/* @__PURE__ */ jsx2(
|
|
626
|
+
"div",
|
|
617
627
|
{
|
|
618
|
-
type: "button",
|
|
619
|
-
onClick: () => setMode(m),
|
|
620
628
|
style: {
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
fontFamily: "inherit",
|
|
629
|
-
transition: "background 0.15s, color 0.15s",
|
|
630
|
-
background: mode === m ? `linear-gradient(135deg, ${colors.accent}, ${colors.accentHover})` : "transparent",
|
|
631
|
-
color: mode === m ? colors.buttonText : colors.textMuted,
|
|
632
|
-
boxShadow: mode === m ? `0 2px 8px ${colors.accent}30` : "none"
|
|
629
|
+
display: "flex",
|
|
630
|
+
gap: 4,
|
|
631
|
+
marginBottom: 20,
|
|
632
|
+
background: colors.backgroundSecondary,
|
|
633
|
+
borderRadius: 12,
|
|
634
|
+
padding: 4,
|
|
635
|
+
border: `1px solid ${inputBorder}`
|
|
633
636
|
},
|
|
634
|
-
children:
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
637
|
+
children: ["bug", "text"].map((m) => /* @__PURE__ */ jsx2(
|
|
638
|
+
"button",
|
|
639
|
+
{
|
|
640
|
+
type: "button",
|
|
641
|
+
onClick: () => setMode(m),
|
|
642
|
+
style: {
|
|
643
|
+
flex: 1,
|
|
644
|
+
padding: "8px 10px",
|
|
645
|
+
borderRadius: 9,
|
|
646
|
+
border: "none",
|
|
647
|
+
cursor: "pointer",
|
|
648
|
+
fontSize: 13,
|
|
649
|
+
fontWeight: mode === m ? 700 : 500,
|
|
650
|
+
fontFamily: "inherit",
|
|
651
|
+
transition: "background 0.15s, color 0.15s",
|
|
652
|
+
background: mode === m ? `linear-gradient(135deg, ${colors.accent}, ${colors.accentHover})` : "transparent",
|
|
653
|
+
color: mode === m ? colors.buttonText : colors.textMuted,
|
|
654
|
+
boxShadow: mode === m ? `0 2px 8px ${colors.accent}30` : "none"
|
|
655
|
+
},
|
|
656
|
+
children: m === "bug" ? "\u{1F41B} Bug" : "\u{1F524} Text / Translation"
|
|
657
|
+
},
|
|
658
|
+
m
|
|
659
|
+
))
|
|
660
|
+
}
|
|
661
|
+
),
|
|
638
662
|
mode === "text" && /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
639
663
|
/* @__PURE__ */ jsxs2("div", { style: { marginBottom: 14 }, children: [
|
|
640
664
|
/* @__PURE__ */ jsx2(FieldLabel, { colors, htmlFor: "flint-text-original", children: "Original text" }),
|
|
@@ -731,7 +755,7 @@ function FlintModal({
|
|
|
731
755
|
}
|
|
732
756
|
)
|
|
733
757
|
] }),
|
|
734
|
-
/* @__PURE__ */ jsxs2("div", { style: { marginBottom: 20, display: mode === "text" ? "none" : void 0 }, children: [
|
|
758
|
+
/* @__PURE__ */ jsxs2("div", { style: { marginBottom: 20, display: mode === "text" || !enableScreenshot ? "none" : void 0 }, children: [
|
|
735
759
|
/* @__PURE__ */ jsx2(FieldLabel, { colors, children: t("screenshotLabel") }),
|
|
736
760
|
screenshot ? /* @__PURE__ */ jsxs2("div", { style: { display: "flex", alignItems: "center", gap: 10 }, children: [
|
|
737
761
|
/* @__PURE__ */ jsx2(
|
|
@@ -742,7 +766,20 @@ function FlintModal({
|
|
|
742
766
|
style: { height: 60, borderRadius: 8, objectFit: "cover", border: `1px solid ${inputBorder}` }
|
|
743
767
|
}
|
|
744
768
|
),
|
|
745
|
-
/* @__PURE__ */ jsx2(
|
|
769
|
+
/* @__PURE__ */ jsx2(
|
|
770
|
+
"span",
|
|
771
|
+
{
|
|
772
|
+
style: {
|
|
773
|
+
fontSize: 13,
|
|
774
|
+
color: colors.textMuted,
|
|
775
|
+
flex: 1,
|
|
776
|
+
overflow: "hidden",
|
|
777
|
+
textOverflow: "ellipsis",
|
|
778
|
+
whiteSpace: "nowrap"
|
|
779
|
+
},
|
|
780
|
+
children: screenshot.name
|
|
781
|
+
}
|
|
782
|
+
),
|
|
746
783
|
/* @__PURE__ */ jsx2(
|
|
747
784
|
"button",
|
|
748
785
|
{
|
|
@@ -829,31 +866,43 @@ function FlintModal({
|
|
|
829
866
|
}
|
|
830
867
|
)
|
|
831
868
|
] }),
|
|
832
|
-
/* @__PURE__ */ jsxs2(
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
869
|
+
/* @__PURE__ */ jsxs2(
|
|
870
|
+
"div",
|
|
871
|
+
{
|
|
872
|
+
style: {
|
|
873
|
+
display: "flex",
|
|
874
|
+
alignItems: "center",
|
|
875
|
+
gap: 8,
|
|
876
|
+
padding: "9px 12px",
|
|
877
|
+
borderRadius: 10,
|
|
878
|
+
background: isDark ? "rgba(255,255,255,0.04)" : "rgba(0,77,240,0.04)",
|
|
879
|
+
border: `1px solid ${isDark ? "rgba(255,255,255,0.08)" : "rgba(0,77,240,0.1)"}`,
|
|
880
|
+
marginBottom: 16
|
|
881
|
+
},
|
|
882
|
+
children: [
|
|
883
|
+
/* @__PURE__ */ jsx2("span", { style: { fontSize: 16 }, children: "\u{1F3A5}" }),
|
|
884
|
+
/* @__PURE__ */ jsx2("span", { style: { fontSize: 14, color: colors.textMuted, lineHeight: 1.4 }, children: t("replayInfo") })
|
|
885
|
+
]
|
|
886
|
+
}
|
|
887
|
+
),
|
|
888
|
+
status === "error" && /* @__PURE__ */ jsxs2(
|
|
889
|
+
"div",
|
|
890
|
+
{
|
|
891
|
+
style: {
|
|
892
|
+
padding: "10px 13px",
|
|
893
|
+
borderRadius: 10,
|
|
894
|
+
background: "rgba(239,68,68,0.08)",
|
|
895
|
+
border: "1px solid rgba(239,68,68,0.2)",
|
|
896
|
+
color: "#f87171",
|
|
897
|
+
fontSize: 14,
|
|
898
|
+
marginBottom: 16
|
|
899
|
+
},
|
|
900
|
+
children: [
|
|
901
|
+
"\u26A0\uFE0F ",
|
|
902
|
+
errorMsg || t("errorLabel")
|
|
903
|
+
]
|
|
904
|
+
}
|
|
905
|
+
),
|
|
857
906
|
/* @__PURE__ */ jsxs2(
|
|
858
907
|
"button",
|
|
859
908
|
{
|
|
@@ -914,49 +963,68 @@ function ModalHeader({
|
|
|
914
963
|
titleId,
|
|
915
964
|
title
|
|
916
965
|
}) {
|
|
917
|
-
return /* @__PURE__ */ jsxs2(
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
966
|
+
return /* @__PURE__ */ jsxs2(
|
|
967
|
+
"div",
|
|
968
|
+
{
|
|
969
|
+
style: {
|
|
970
|
+
display: "flex",
|
|
971
|
+
alignItems: "center",
|
|
972
|
+
gap: 10,
|
|
973
|
+
padding: "16px 20px 14px",
|
|
974
|
+
borderBottom: `1px solid ${inputBorder}`
|
|
975
|
+
},
|
|
976
|
+
children: [
|
|
977
|
+
/* @__PURE__ */ jsx2(
|
|
978
|
+
"div",
|
|
979
|
+
{
|
|
980
|
+
style: {
|
|
981
|
+
width: 28,
|
|
982
|
+
height: 28,
|
|
983
|
+
borderRadius: 8,
|
|
984
|
+
background: `linear-gradient(135deg, ${colors.accent}20, ${colors.accentHover}35)`,
|
|
985
|
+
border: `1px solid ${colors.accent}30`,
|
|
986
|
+
display: "flex",
|
|
987
|
+
alignItems: "center",
|
|
988
|
+
justifyContent: "center",
|
|
989
|
+
flexShrink: 0
|
|
990
|
+
},
|
|
991
|
+
children: /* @__PURE__ */ jsx2(SparkIcon, { color: colors.accent, size: 13 })
|
|
992
|
+
}
|
|
993
|
+
),
|
|
994
|
+
titleId && title ? /* @__PURE__ */ jsx2(
|
|
995
|
+
"h2",
|
|
996
|
+
{
|
|
997
|
+
id: titleId,
|
|
998
|
+
style: { margin: 0, fontSize: 16, fontWeight: 600, color: colors.text, letterSpacing: "-0.01em", flex: 1 },
|
|
999
|
+
children: title
|
|
1000
|
+
}
|
|
1001
|
+
) : /* @__PURE__ */ jsx2("span", { style: { flex: 1, fontSize: 15, fontWeight: 600, color: colors.textMuted }, children: "Flint" }),
|
|
1002
|
+
showClose && /* @__PURE__ */ jsx2(
|
|
1003
|
+
"button",
|
|
1004
|
+
{
|
|
1005
|
+
onClick: onClose,
|
|
1006
|
+
"aria-label": "Close",
|
|
1007
|
+
style: {
|
|
1008
|
+
background: "none",
|
|
1009
|
+
border: "none",
|
|
1010
|
+
cursor: "pointer",
|
|
1011
|
+
padding: 4,
|
|
1012
|
+
color: colors.textMuted,
|
|
1013
|
+
fontSize: 22,
|
|
1014
|
+
lineHeight: 1,
|
|
1015
|
+
borderRadius: 6,
|
|
1016
|
+
display: "flex",
|
|
1017
|
+
alignItems: "center",
|
|
1018
|
+
justifyContent: "center",
|
|
1019
|
+
opacity: 0.6,
|
|
1020
|
+
fontFamily: "inherit"
|
|
1021
|
+
},
|
|
1022
|
+
children: "\xD7"
|
|
1023
|
+
}
|
|
1024
|
+
)
|
|
1025
|
+
]
|
|
1026
|
+
}
|
|
1027
|
+
);
|
|
960
1028
|
}
|
|
961
1029
|
function FieldLabel({
|
|
962
1030
|
children,
|
|
@@ -1018,19 +1086,74 @@ function SeverityButton({ sev, label, selected, hint, color, accent, border, bg,
|
|
|
1018
1086
|
},
|
|
1019
1087
|
children: [
|
|
1020
1088
|
/* @__PURE__ */ jsx2("span", { style: { width: 8, height: 8, borderRadius: "50%", background: color, display: "block" } }),
|
|
1021
|
-
/* @__PURE__ */ jsx2(
|
|
1089
|
+
/* @__PURE__ */ jsx2(
|
|
1090
|
+
"span",
|
|
1091
|
+
{
|
|
1092
|
+
style: {
|
|
1093
|
+
fontSize: 13,
|
|
1094
|
+
fontWeight: selected ? 700 : 500,
|
|
1095
|
+
color: selected ? accent : text,
|
|
1096
|
+
letterSpacing: "0.02em"
|
|
1097
|
+
},
|
|
1098
|
+
children: sev
|
|
1099
|
+
}
|
|
1100
|
+
),
|
|
1022
1101
|
/* @__PURE__ */ jsx2("span", { style: { fontSize: 11, color: selected ? accent : text, opacity: 0.6, letterSpacing: "0.02em" }, children: label })
|
|
1023
1102
|
]
|
|
1024
1103
|
}
|
|
1025
1104
|
);
|
|
1026
1105
|
}
|
|
1027
1106
|
function SparkIcon({ color = "currentColor", size = 14 }) {
|
|
1028
|
-
return /* @__PURE__ */ jsx2(
|
|
1107
|
+
return /* @__PURE__ */ jsx2(
|
|
1108
|
+
"svg",
|
|
1109
|
+
{
|
|
1110
|
+
width: size,
|
|
1111
|
+
height: size,
|
|
1112
|
+
viewBox: "0 0 24 24",
|
|
1113
|
+
fill: "none",
|
|
1114
|
+
stroke: color,
|
|
1115
|
+
strokeWidth: "2.2",
|
|
1116
|
+
strokeLinecap: "round",
|
|
1117
|
+
strokeLinejoin: "round",
|
|
1118
|
+
"aria-hidden": "true",
|
|
1119
|
+
children: /* @__PURE__ */ jsx2("path", { d: "M13 2L3 14h9l-1 8 10-12h-9l1-8z" })
|
|
1120
|
+
}
|
|
1121
|
+
);
|
|
1029
1122
|
}
|
|
1030
1123
|
function CheckIcon({ size = 20 }) {
|
|
1031
|
-
return /* @__PURE__ */ jsx2(
|
|
1124
|
+
return /* @__PURE__ */ jsx2(
|
|
1125
|
+
"svg",
|
|
1126
|
+
{
|
|
1127
|
+
width: size,
|
|
1128
|
+
height: size,
|
|
1129
|
+
viewBox: "0 0 24 24",
|
|
1130
|
+
fill: "none",
|
|
1131
|
+
stroke: "#22c55e",
|
|
1132
|
+
strokeWidth: "2.5",
|
|
1133
|
+
strokeLinecap: "round",
|
|
1134
|
+
strokeLinejoin: "round",
|
|
1135
|
+
"aria-hidden": "true",
|
|
1136
|
+
children: /* @__PURE__ */ jsx2("polyline", { points: "20 6 9 17 4 12" })
|
|
1137
|
+
}
|
|
1138
|
+
);
|
|
1032
1139
|
}
|
|
1033
1140
|
|
|
1141
|
+
// src/FlintWidget.tsx
|
|
1142
|
+
import { useCallback as useCallback2, useEffect as useEffect3, useRef as useRef3, useState as useState3 } from "react";
|
|
1143
|
+
import { I18nextProvider, useTranslation as useTranslation2 } from "react-i18next";
|
|
1144
|
+
|
|
1145
|
+
// src/collectors/console.ts
|
|
1146
|
+
import { createConsoleCollector } from "@flint/core";
|
|
1147
|
+
|
|
1148
|
+
// src/collectors/environment.ts
|
|
1149
|
+
import { collectEnvironment } from "@flint/core";
|
|
1150
|
+
|
|
1151
|
+
// src/collectors/frustration.ts
|
|
1152
|
+
import { createFrustrationCollector } from "@flint/core";
|
|
1153
|
+
|
|
1154
|
+
// src/collectors/network.ts
|
|
1155
|
+
import { createNetworkCollector } from "@flint/core";
|
|
1156
|
+
|
|
1034
1157
|
// src/i18n/index.ts
|
|
1035
1158
|
import { createInstance } from "i18next";
|
|
1036
1159
|
import { initReactI18next } from "react-i18next";
|
|
@@ -1080,251 +1203,15 @@ widgetI18n.use(initReactI18next).init({
|
|
|
1080
1203
|
});
|
|
1081
1204
|
var i18n_default = widgetI18n;
|
|
1082
1205
|
|
|
1083
|
-
// src/collectors/environment.ts
|
|
1084
|
-
function collectEnvironment() {
|
|
1085
|
-
const ua = navigator.userAgent;
|
|
1086
|
-
let browser = "Unknown";
|
|
1087
|
-
const chromeM = ua.match(/Chrome\/(\d+)/);
|
|
1088
|
-
const firefoxM = ua.match(/Firefox\/(\d+)/);
|
|
1089
|
-
const edgeM = ua.match(/Edg\/(\d+)/);
|
|
1090
|
-
const safariM = ua.match(/Version\/(\d+)/);
|
|
1091
|
-
const operaM = ua.match(/OPR\/(\d+)/);
|
|
1092
|
-
if (operaM) {
|
|
1093
|
-
browser = `Opera ${operaM[1]}`;
|
|
1094
|
-
} else if (edgeM) {
|
|
1095
|
-
browser = `Edge ${edgeM[1]}`;
|
|
1096
|
-
} else if (chromeM && !/Edg|OPR/.test(ua)) {
|
|
1097
|
-
browser = `Chrome ${chromeM[1]}`;
|
|
1098
|
-
} else if (firefoxM) {
|
|
1099
|
-
browser = `Firefox ${firefoxM[1]}`;
|
|
1100
|
-
} else if (safariM && /Safari\//.test(ua)) {
|
|
1101
|
-
browser = `Safari ${safariM[1]}`;
|
|
1102
|
-
}
|
|
1103
|
-
let os = "Unknown";
|
|
1104
|
-
const macM = ua.match(/Mac OS X (\d+[._]\d+)/);
|
|
1105
|
-
const winM = ua.match(/Windows NT (\d+\.\d+)/);
|
|
1106
|
-
const androidM = ua.match(/Android (\d+)/);
|
|
1107
|
-
const iosM = ua.match(/iPhone OS (\d+[._]\d+)/);
|
|
1108
|
-
if (macM) {
|
|
1109
|
-
os = `macOS ${macM[1].replace("_", ".")}`;
|
|
1110
|
-
} else if (winM) {
|
|
1111
|
-
const winMap = {
|
|
1112
|
-
"10.0": "10/11",
|
|
1113
|
-
"6.3": "8.1",
|
|
1114
|
-
"6.2": "8",
|
|
1115
|
-
"6.1": "7"
|
|
1116
|
-
};
|
|
1117
|
-
os = `Windows ${winMap[winM[1]] ?? winM[1]}`;
|
|
1118
|
-
} else if (androidM) {
|
|
1119
|
-
os = `Android ${androidM[1]}`;
|
|
1120
|
-
} else if (iosM) {
|
|
1121
|
-
os = `iOS ${iosM[1].replace(/_/g, ".")}`;
|
|
1122
|
-
} else if (/Linux/.test(ua)) {
|
|
1123
|
-
os = "Linux";
|
|
1124
|
-
}
|
|
1125
|
-
return {
|
|
1126
|
-
browser,
|
|
1127
|
-
os,
|
|
1128
|
-
viewport: `${window.innerWidth}x${window.innerHeight}`,
|
|
1129
|
-
screen: `${screen.width}x${screen.height}`,
|
|
1130
|
-
language: navigator.language,
|
|
1131
|
-
timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
|
|
1132
|
-
online: navigator.onLine
|
|
1133
|
-
};
|
|
1134
|
-
}
|
|
1135
|
-
|
|
1136
|
-
// src/collectors/console.ts
|
|
1137
|
-
var MAX_ENTRIES = 50;
|
|
1138
|
-
function createConsoleCollector() {
|
|
1139
|
-
const entries = [];
|
|
1140
|
-
let active = false;
|
|
1141
|
-
const originals = {
|
|
1142
|
-
log: console.log.bind(console),
|
|
1143
|
-
warn: console.warn.bind(console),
|
|
1144
|
-
error: console.error.bind(console)
|
|
1145
|
-
};
|
|
1146
|
-
let origOnerror = null;
|
|
1147
|
-
let origUnhandled = null;
|
|
1148
|
-
function push(level, args) {
|
|
1149
|
-
let str;
|
|
1150
|
-
try {
|
|
1151
|
-
str = args.map((a) => typeof a === "string" ? a : JSON.stringify(a)).join(" ");
|
|
1152
|
-
} catch {
|
|
1153
|
-
str = String(args[0]);
|
|
1154
|
-
}
|
|
1155
|
-
if (str.length > 500) str = str.slice(0, 500) + "\u2026";
|
|
1156
|
-
entries.push({ level, args: str, timestamp: Date.now() });
|
|
1157
|
-
if (entries.length > MAX_ENTRIES) entries.shift();
|
|
1158
|
-
}
|
|
1159
|
-
return {
|
|
1160
|
-
start() {
|
|
1161
|
-
if (active) return;
|
|
1162
|
-
active = true;
|
|
1163
|
-
console.log = (...args) => {
|
|
1164
|
-
push("log", args);
|
|
1165
|
-
originals.log(...args);
|
|
1166
|
-
};
|
|
1167
|
-
console.warn = (...args) => {
|
|
1168
|
-
push("warn", args);
|
|
1169
|
-
originals.warn(...args);
|
|
1170
|
-
};
|
|
1171
|
-
console.error = (...args) => {
|
|
1172
|
-
push("error", args);
|
|
1173
|
-
originals.error(...args);
|
|
1174
|
-
};
|
|
1175
|
-
origOnerror = window.onerror;
|
|
1176
|
-
window.onerror = (msg, src, line, col, err) => {
|
|
1177
|
-
push("error", [err?.message ?? String(msg), `${src}:${line}:${col}`]);
|
|
1178
|
-
if (typeof origOnerror === "function")
|
|
1179
|
-
return origOnerror(msg, src, line, col, err);
|
|
1180
|
-
return false;
|
|
1181
|
-
};
|
|
1182
|
-
origUnhandled = window.onunhandledrejection;
|
|
1183
|
-
window.onunhandledrejection = (event) => {
|
|
1184
|
-
const reason = event.reason instanceof Error ? event.reason.message : JSON.stringify(event.reason);
|
|
1185
|
-
push("error", ["UnhandledRejection:", reason]);
|
|
1186
|
-
if (typeof origUnhandled === "function")
|
|
1187
|
-
origUnhandled.call(window, event);
|
|
1188
|
-
};
|
|
1189
|
-
},
|
|
1190
|
-
stop() {
|
|
1191
|
-
if (!active) return;
|
|
1192
|
-
active = false;
|
|
1193
|
-
console.log = originals.log;
|
|
1194
|
-
console.warn = originals.warn;
|
|
1195
|
-
console.error = originals.error;
|
|
1196
|
-
window.onerror = origOnerror;
|
|
1197
|
-
window.onunhandledrejection = origUnhandled;
|
|
1198
|
-
},
|
|
1199
|
-
getEntries() {
|
|
1200
|
-
return [...entries];
|
|
1201
|
-
}
|
|
1202
|
-
};
|
|
1203
|
-
}
|
|
1204
|
-
|
|
1205
|
-
// src/collectors/network.ts
|
|
1206
|
-
var MAX_ENTRIES2 = 50;
|
|
1207
|
-
var BLOCKED_HOSTS = /* @__PURE__ */ new Set([
|
|
1208
|
-
"browser-intake-datadoghq.com",
|
|
1209
|
-
"rum.browser-intake-datadoghq.com",
|
|
1210
|
-
"logs.browser-intake-datadoghq.com",
|
|
1211
|
-
"session-replay.browser-intake-datadoghq.com"
|
|
1212
|
-
]);
|
|
1213
|
-
function isBlockedUrl(url, extra) {
|
|
1214
|
-
try {
|
|
1215
|
-
const host = new URL(url, location.href).hostname;
|
|
1216
|
-
const all = [...BLOCKED_HOSTS, ...extra];
|
|
1217
|
-
return all.some((b) => host === b || host.endsWith("." + b));
|
|
1218
|
-
} catch {
|
|
1219
|
-
return false;
|
|
1220
|
-
}
|
|
1221
|
-
}
|
|
1222
|
-
function truncateUrl(url) {
|
|
1223
|
-
try {
|
|
1224
|
-
const u = new URL(url, location.href);
|
|
1225
|
-
const base = `${u.origin}${u.pathname}`;
|
|
1226
|
-
return base.length > 200 ? base.slice(0, 200) + "\u2026" : base;
|
|
1227
|
-
} catch {
|
|
1228
|
-
return url.length > 200 ? url.slice(0, 200) + "\u2026" : url;
|
|
1229
|
-
}
|
|
1230
|
-
}
|
|
1231
|
-
function createNetworkCollector(extraBlockedHosts = []) {
|
|
1232
|
-
const entries = [];
|
|
1233
|
-
const blocked = new Set(extraBlockedHosts);
|
|
1234
|
-
let origFetch = null;
|
|
1235
|
-
let origXHROpen = null;
|
|
1236
|
-
let active = false;
|
|
1237
|
-
function push(entry) {
|
|
1238
|
-
entries.push(entry);
|
|
1239
|
-
if (entries.length > MAX_ENTRIES2) entries.shift();
|
|
1240
|
-
}
|
|
1241
|
-
return {
|
|
1242
|
-
start() {
|
|
1243
|
-
if (active) return;
|
|
1244
|
-
active = true;
|
|
1245
|
-
origFetch = window.fetch;
|
|
1246
|
-
window.fetch = async (input, init) => {
|
|
1247
|
-
const method = (init?.method ?? "GET").toUpperCase();
|
|
1248
|
-
const url = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
|
|
1249
|
-
const startTime = Date.now();
|
|
1250
|
-
const res = await origFetch.call(window, input, init);
|
|
1251
|
-
if (res.status >= 400 && !isBlockedUrl(url, blocked)) {
|
|
1252
|
-
push({
|
|
1253
|
-
method,
|
|
1254
|
-
url: truncateUrl(url),
|
|
1255
|
-
status: res.status,
|
|
1256
|
-
duration: Date.now() - startTime,
|
|
1257
|
-
timestamp: startTime
|
|
1258
|
-
});
|
|
1259
|
-
}
|
|
1260
|
-
return res;
|
|
1261
|
-
};
|
|
1262
|
-
origXHROpen = XMLHttpRequest.prototype.open;
|
|
1263
|
-
XMLHttpRequest.prototype.open = function(method, url, async, username, password) {
|
|
1264
|
-
const startTime = Date.now();
|
|
1265
|
-
const urlStr = typeof url === "string" ? url : url.href;
|
|
1266
|
-
this.addEventListener("load", () => {
|
|
1267
|
-
if (this.status >= 400 && !isBlockedUrl(urlStr, blocked)) {
|
|
1268
|
-
push({
|
|
1269
|
-
method: method.toUpperCase(),
|
|
1270
|
-
url: truncateUrl(urlStr),
|
|
1271
|
-
status: this.status,
|
|
1272
|
-
duration: Date.now() - startTime,
|
|
1273
|
-
timestamp: startTime
|
|
1274
|
-
});
|
|
1275
|
-
}
|
|
1276
|
-
});
|
|
1277
|
-
return origXHROpen.apply(this, [
|
|
1278
|
-
method,
|
|
1279
|
-
url,
|
|
1280
|
-
async ?? true,
|
|
1281
|
-
username,
|
|
1282
|
-
password
|
|
1283
|
-
]);
|
|
1284
|
-
};
|
|
1285
|
-
},
|
|
1286
|
-
stop() {
|
|
1287
|
-
if (!active) return;
|
|
1288
|
-
active = false;
|
|
1289
|
-
if (origFetch) window.fetch = origFetch;
|
|
1290
|
-
if (origXHROpen) XMLHttpRequest.prototype.open = origXHROpen;
|
|
1291
|
-
},
|
|
1292
|
-
getEntries() {
|
|
1293
|
-
return [...entries];
|
|
1294
|
-
}
|
|
1295
|
-
};
|
|
1296
|
-
}
|
|
1297
|
-
|
|
1298
1206
|
// src/store.ts
|
|
1207
|
+
import { getSnapshot, subscribe } from "@flint/core";
|
|
1299
1208
|
import { useSyncExternalStore } from "react";
|
|
1300
|
-
|
|
1301
|
-
var listeners = /* @__PURE__ */ new Set();
|
|
1302
|
-
function emit() {
|
|
1303
|
-
listeners.forEach((fn) => fn());
|
|
1304
|
-
}
|
|
1305
|
-
function subscribeStore(fn) {
|
|
1306
|
-
listeners.add(fn);
|
|
1307
|
-
return () => listeners.delete(fn);
|
|
1308
|
-
}
|
|
1309
|
-
function getSnapshot() {
|
|
1310
|
-
return state;
|
|
1311
|
-
}
|
|
1209
|
+
import { flint as flint2 } from "@flint/core";
|
|
1312
1210
|
function useFlintStore() {
|
|
1313
|
-
return useSyncExternalStore(
|
|
1211
|
+
return useSyncExternalStore(subscribe, getSnapshot);
|
|
1314
1212
|
}
|
|
1315
|
-
var flint = {
|
|
1316
|
-
setUser(user) {
|
|
1317
|
-
state = { ...state, user: user ?? void 0 };
|
|
1318
|
-
emit();
|
|
1319
|
-
},
|
|
1320
|
-
setSessionReplay(url) {
|
|
1321
|
-
state = { ...state, sessionReplay: url };
|
|
1322
|
-
emit();
|
|
1323
|
-
}
|
|
1324
|
-
};
|
|
1325
1213
|
|
|
1326
1214
|
// src/FlintWidget.tsx
|
|
1327
|
-
import { record } from "rrweb";
|
|
1328
1215
|
import { Fragment as Fragment2, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
1329
1216
|
var REPLAY_WINDOW_MS = 6e4;
|
|
1330
1217
|
function FlintWidget(props) {
|
|
@@ -1343,7 +1230,19 @@ function WidgetContent({
|
|
|
1343
1230
|
buttonLabel,
|
|
1344
1231
|
theme = "dark",
|
|
1345
1232
|
zIndex = 9999,
|
|
1346
|
-
|
|
1233
|
+
statusPageUrl,
|
|
1234
|
+
datadogSite,
|
|
1235
|
+
enableReplay = true,
|
|
1236
|
+
enableScreenshot = true,
|
|
1237
|
+
enableConsole = true,
|
|
1238
|
+
enableNetwork = true,
|
|
1239
|
+
enableFrustration = false,
|
|
1240
|
+
autoReportFrustration = false,
|
|
1241
|
+
onBeforeSubmit,
|
|
1242
|
+
onSuccess,
|
|
1243
|
+
onError,
|
|
1244
|
+
onOpen,
|
|
1245
|
+
onClose
|
|
1347
1246
|
}) {
|
|
1348
1247
|
const globalState = useFlintStore();
|
|
1349
1248
|
const resolvedUser = user ?? globalState.user;
|
|
@@ -1357,9 +1256,9 @@ function WidgetContent({
|
|
|
1357
1256
|
const ddRum = window.DD_RUM;
|
|
1358
1257
|
const ctx = ddRum?.getInternalContext?.();
|
|
1359
1258
|
if (ctx?.session_id) {
|
|
1360
|
-
const now = Date.now();
|
|
1361
|
-
const fromTs = now -
|
|
1362
|
-
const toTs = now +
|
|
1259
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
1260
|
+
const fromTs = now - 30;
|
|
1261
|
+
const toTs = now + 5;
|
|
1363
1262
|
return `https://${datadogSite}/rum/replay/sessions/${ctx.session_id}?from_ts=${fromTs}&to_ts=${toTs}&tab=replay&live=false`;
|
|
1364
1263
|
}
|
|
1365
1264
|
} catch {
|
|
@@ -1412,16 +1311,17 @@ function WidgetContent({
|
|
|
1412
1311
|
pendingSelection.current = text;
|
|
1413
1312
|
setSelectionTooltip(null);
|
|
1414
1313
|
setOpen(true);
|
|
1314
|
+
onOpen?.();
|
|
1415
1315
|
};
|
|
1416
1316
|
const consoleCollector = useRef3(null);
|
|
1417
1317
|
const networkCollector = useRef3(null);
|
|
1418
1318
|
const replayEvents = useRef3([]);
|
|
1419
1319
|
const stopReplay = useRef3(null);
|
|
1420
|
-
if (!consoleCollector.current) {
|
|
1320
|
+
if (enableConsole && !consoleCollector.current) {
|
|
1421
1321
|
consoleCollector.current = createConsoleCollector();
|
|
1422
1322
|
consoleCollector.current.start();
|
|
1423
1323
|
}
|
|
1424
|
-
if (!networkCollector.current) {
|
|
1324
|
+
if (enableNetwork && !networkCollector.current) {
|
|
1425
1325
|
const flintHost = (() => {
|
|
1426
1326
|
try {
|
|
1427
1327
|
return new URL(serverUrl).hostname;
|
|
@@ -1432,23 +1332,58 @@ function WidgetContent({
|
|
|
1432
1332
|
networkCollector.current = createNetworkCollector(flintHost ? [flintHost] : []);
|
|
1433
1333
|
networkCollector.current.start();
|
|
1434
1334
|
}
|
|
1335
|
+
const frustrationCollector = useRef3(null);
|
|
1336
|
+
if (enableFrustration && !frustrationCollector.current) {
|
|
1337
|
+
frustrationCollector.current = createFrustrationCollector();
|
|
1338
|
+
frustrationCollector.current.start();
|
|
1339
|
+
}
|
|
1435
1340
|
useEffect3(() => {
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1341
|
+
let cancelled = false;
|
|
1342
|
+
if (enableReplay) {
|
|
1343
|
+
import("rrweb").then(({ record }) => {
|
|
1344
|
+
if (cancelled) return;
|
|
1345
|
+
const stopFn = record({
|
|
1346
|
+
emit(event) {
|
|
1347
|
+
replayEvents.current.push(event);
|
|
1348
|
+
const cutoff = Date.now() - REPLAY_WINDOW_MS;
|
|
1349
|
+
while (replayEvents.current.length > 0 && replayEvents.current[0].timestamp < cutoff) {
|
|
1350
|
+
replayEvents.current.shift();
|
|
1351
|
+
}
|
|
1352
|
+
}
|
|
1353
|
+
});
|
|
1354
|
+
stopReplay.current = stopFn ?? null;
|
|
1355
|
+
});
|
|
1356
|
+
}
|
|
1446
1357
|
return () => {
|
|
1358
|
+
cancelled = true;
|
|
1447
1359
|
consoleCollector.current?.stop();
|
|
1448
1360
|
networkCollector.current?.stop();
|
|
1361
|
+
frustrationCollector.current?.stop();
|
|
1449
1362
|
stopReplay.current?.();
|
|
1450
1363
|
};
|
|
1451
|
-
}, []);
|
|
1364
|
+
}, [enableReplay]);
|
|
1365
|
+
useEffect3(() => {
|
|
1366
|
+
if (!enableFrustration || !autoReportFrustration || !frustrationCollector.current) return;
|
|
1367
|
+
const unsubscribe = frustrationCollector.current.onFrustration(async (event) => {
|
|
1368
|
+
const user2 = resolvedUser;
|
|
1369
|
+
await submitReport(serverUrl, projectKey, {
|
|
1370
|
+
reporterId: user2?.id ?? "anonymous",
|
|
1371
|
+
reporterName: user2?.name ?? "Anonymous",
|
|
1372
|
+
reporterEmail: user2?.email,
|
|
1373
|
+
description: `[Auto-detected] ${event.type.replace(/_/g, " ")}: ${event.details}`,
|
|
1374
|
+
severity: event.type === "error_loop" ? "P1" : event.type === "rage_click" ? "P2" : "P3",
|
|
1375
|
+
url: event.url,
|
|
1376
|
+
meta: {
|
|
1377
|
+
environment: collectEnvironment(),
|
|
1378
|
+
consoleLogs: consoleCollector.current?.getEntries() ?? [],
|
|
1379
|
+
networkErrors: networkCollector.current?.getEntries() ?? [],
|
|
1380
|
+
frustrationEvent: event
|
|
1381
|
+
}
|
|
1382
|
+
}).catch(() => {
|
|
1383
|
+
});
|
|
1384
|
+
});
|
|
1385
|
+
return unsubscribe;
|
|
1386
|
+
}, [enableFrustration, autoReportFrustration]);
|
|
1452
1387
|
const label = buttonLabel ?? t("buttonLabel");
|
|
1453
1388
|
return /* @__PURE__ */ jsxs3(Fragment2, { children: [
|
|
1454
1389
|
/* @__PURE__ */ jsxs3(
|
|
@@ -1458,7 +1393,10 @@ function WidgetContent({
|
|
|
1458
1393
|
onMouseDown: () => {
|
|
1459
1394
|
pendingSelection.current = window.getSelection()?.toString().trim() ?? "";
|
|
1460
1395
|
},
|
|
1461
|
-
onClick: () =>
|
|
1396
|
+
onClick: () => {
|
|
1397
|
+
setOpen(true);
|
|
1398
|
+
onOpen?.();
|
|
1399
|
+
},
|
|
1462
1400
|
onMouseEnter: () => setHovered(true),
|
|
1463
1401
|
onMouseLeave: () => setHovered(false),
|
|
1464
1402
|
"aria-label": label,
|
|
@@ -1539,6 +1477,7 @@ function WidgetContent({
|
|
|
1539
1477
|
zIndex,
|
|
1540
1478
|
onClose: () => {
|
|
1541
1479
|
setOpen(false);
|
|
1480
|
+
onClose?.();
|
|
1542
1481
|
pendingSelection.current = "";
|
|
1543
1482
|
},
|
|
1544
1483
|
getEnvironment: collectEnvironment,
|
|
@@ -1546,18 +1485,37 @@ function WidgetContent({
|
|
|
1546
1485
|
getNetworkErrors: () => networkCollector.current?.getEntries() ?? [],
|
|
1547
1486
|
getReplayEvents: () => [...replayEvents.current],
|
|
1548
1487
|
getExternalReplayUrl,
|
|
1549
|
-
initialSelection: pendingSelection.current
|
|
1488
|
+
initialSelection: pendingSelection.current,
|
|
1489
|
+
enableScreenshot,
|
|
1490
|
+
statusPageUrl,
|
|
1491
|
+
onBeforeSubmit,
|
|
1492
|
+
onSuccess,
|
|
1493
|
+
onError
|
|
1550
1494
|
}
|
|
1551
1495
|
)
|
|
1552
1496
|
] });
|
|
1553
1497
|
}
|
|
1554
1498
|
function TextIcon() {
|
|
1555
|
-
return /* @__PURE__ */ jsxs3(
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1499
|
+
return /* @__PURE__ */ jsxs3(
|
|
1500
|
+
"svg",
|
|
1501
|
+
{
|
|
1502
|
+
width: "12",
|
|
1503
|
+
height: "12",
|
|
1504
|
+
viewBox: "0 0 24 24",
|
|
1505
|
+
fill: "none",
|
|
1506
|
+
stroke: "currentColor",
|
|
1507
|
+
strokeWidth: "2.2",
|
|
1508
|
+
strokeLinecap: "round",
|
|
1509
|
+
strokeLinejoin: "round",
|
|
1510
|
+
"aria-hidden": "true",
|
|
1511
|
+
children: [
|
|
1512
|
+
/* @__PURE__ */ jsx3("path", { d: "M17 10H3" }),
|
|
1513
|
+
/* @__PURE__ */ jsx3("path", { d: "M21 6H3" }),
|
|
1514
|
+
/* @__PURE__ */ jsx3("path", { d: "M21 14H3" }),
|
|
1515
|
+
/* @__PURE__ */ jsx3("path", { d: "M17 18H3" })
|
|
1516
|
+
]
|
|
1517
|
+
}
|
|
1518
|
+
);
|
|
1561
1519
|
}
|
|
1562
1520
|
function SparkIcon2() {
|
|
1563
1521
|
return /* @__PURE__ */ jsx3(
|
|
@@ -1579,6 +1537,6 @@ function SparkIcon2() {
|
|
|
1579
1537
|
export {
|
|
1580
1538
|
FlintModal,
|
|
1581
1539
|
FlintWidget,
|
|
1582
|
-
flint
|
|
1540
|
+
flint2 as flint
|
|
1583
1541
|
};
|
|
1584
1542
|
//# sourceMappingURL=index.js.map
|