@rafaelbarross/feedback-widget 0.1.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 ADDED
@@ -0,0 +1,1078 @@
1
+ 'use strict';
2
+
3
+ var chunkDDAAVRWG_js = require('./chunk-DDAAVRWG.js');
4
+ var react = require('react');
5
+ var ReactDOM = require('react-dom');
6
+ var jsxRuntime = require('react/jsx-runtime');
7
+
8
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
9
+
10
+ var ReactDOM__default = /*#__PURE__*/_interopDefault(ReactDOM);
11
+
12
+ var MARGIN = 20;
13
+ function snapStyles(pos) {
14
+ const m = MARGIN;
15
+ const map = {
16
+ "top-left": { top: m, left: m },
17
+ "top-center": { top: m, left: "50%", transform: "translateX(-50%)" },
18
+ "top-right": { top: m, right: m },
19
+ "middle-left": { top: "50%", left: m, transform: "translateY(-50%)" },
20
+ "middle-right": { top: "50%", right: m, transform: "translateY(-50%)" },
21
+ "bottom-left": { bottom: m, left: m },
22
+ "bottom-center": { bottom: m, left: "50%", transform: "translateX(-50%)" },
23
+ "bottom-right": { bottom: m, right: m }
24
+ };
25
+ return map[pos];
26
+ }
27
+ function resolveSnap(x, y) {
28
+ const rx = x / window.innerWidth;
29
+ const ry = y / window.innerHeight;
30
+ const h = rx < 0.33 ? "left" : rx > 0.67 ? "right" : "center";
31
+ const v = ry < 0.25 ? "top" : ry > 0.75 ? "bottom" : "middle";
32
+ if (v === "middle" && h === "center") return rx < 0.5 ? "middle-left" : "middle-right";
33
+ if (v === "middle") return `middle-${h}`;
34
+ return `${v}-${h}`;
35
+ }
36
+ function FeedbackButton({ position, label, onClick }) {
37
+ const [snap, setSnap] = react.useState(position);
38
+ const [hovered, setHovered] = react.useState(false);
39
+ const [dragging, setDragging] = react.useState(false);
40
+ const [dragXY, setDragXY] = react.useState(null);
41
+ const dragStart = react.useRef(null);
42
+ const didDrag = react.useRef(false);
43
+ const btnRef = react.useRef(null);
44
+ react.useEffect(() => {
45
+ if (!dragging) return;
46
+ const onMove = (e) => {
47
+ if (!dragStart.current) return;
48
+ const dx = e.clientX - dragStart.current.mouseX;
49
+ const dy = e.clientY - dragStart.current.mouseY;
50
+ if (Math.abs(dx) > 4 || Math.abs(dy) > 4) didDrag.current = true;
51
+ setDragXY({ x: dragStart.current.btnX + dx, y: dragStart.current.btnY + dy });
52
+ };
53
+ const onUp = (e) => {
54
+ setDragging(false);
55
+ if (didDrag.current) {
56
+ setSnap(resolveSnap(e.clientX, e.clientY));
57
+ setDragXY(null);
58
+ } else {
59
+ setDragXY(null);
60
+ onClick();
61
+ }
62
+ didDrag.current = false;
63
+ dragStart.current = null;
64
+ };
65
+ window.addEventListener("mousemove", onMove);
66
+ window.addEventListener("mouseup", onUp);
67
+ return () => {
68
+ window.removeEventListener("mousemove", onMove);
69
+ window.removeEventListener("mouseup", onUp);
70
+ };
71
+ }, [dragging, onClick]);
72
+ const onMouseDown = (e) => {
73
+ e.preventDefault();
74
+ const rect = btnRef.current.getBoundingClientRect();
75
+ dragStart.current = { mouseX: e.clientX, mouseY: e.clientY, btnX: rect.left, btnY: rect.top };
76
+ didDrag.current = false;
77
+ setDragging(true);
78
+ };
79
+ const baseStyle = {
80
+ position: "fixed",
81
+ zIndex: 999998,
82
+ display: "flex",
83
+ alignItems: "center",
84
+ gap: 8,
85
+ padding: "10px 16px",
86
+ background: hovered && !dragging ? "#4338CA" : "#4F46E5",
87
+ color: "#fff",
88
+ border: "none",
89
+ borderRadius: 9999,
90
+ cursor: dragging ? "grabbing" : "grab",
91
+ fontSize: 14,
92
+ fontFamily: "system-ui, -apple-system, sans-serif",
93
+ fontWeight: 600,
94
+ boxShadow: dragging ? "0 8px 24px rgba(79,70,229,0.55)" : "0 4px 14px rgba(79,70,229,0.45)",
95
+ userSelect: "none",
96
+ transition: dragging ? "none" : "background 0.15s, box-shadow 0.15s"
97
+ };
98
+ const positionStyle = dragging && dragXY ? { left: dragXY.x, top: dragXY.y } : chunkDDAAVRWG_js.__spreadProps(chunkDDAAVRWG_js.__spreadValues({}, snapStyles(snap)), { transition: dragging ? "none" : "all 0.2s cubic-bezier(.34,1.56,.64,1)" });
99
+ return /* @__PURE__ */ jsxRuntime.jsxs(
100
+ "button",
101
+ {
102
+ ref: btnRef,
103
+ onMouseDown,
104
+ onMouseEnter: () => setHovered(true),
105
+ onMouseLeave: () => setHovered(false),
106
+ style: chunkDDAAVRWG_js.__spreadValues(chunkDDAAVRWG_js.__spreadValues({}, baseStyle), positionStyle),
107
+ "aria-label": label,
108
+ children: [
109
+ /* @__PURE__ */ jsxRuntime.jsx(BugIcon, {}),
110
+ label
111
+ ]
112
+ }
113
+ );
114
+ }
115
+ function BugIcon() {
116
+ return /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "15", height: "15", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M8 2l1.5 1.5M14.5 3.5L16 2M9 7.5C9 6.1 10.1 5 11.5 5h1C13.9 5 15 6.1 15 7.5M6.5 9H4a1 1 0 0 0-1 1v1a4 4 0 0 0 4 4M17.5 9H20a1 1 0 0 1 1 1v1a4 4 0 0 1-4 4M8 15a4 4 0 0 0 8 0V9a4 4 0 0 0-8 0v6zM9 19.5V22M15 19.5V22M3 15h2M19 15h2" }) });
117
+ }
118
+ var INIT_DRAG = { active: false, startX: 0, startY: 0, endX: 0, endY: 0 };
119
+ function CaptureOverlay({ fullPageCanvas, onCapture, onCancel }) {
120
+ const canvasRef = react.useRef(null);
121
+ const drag = react.useRef(INIT_DRAG);
122
+ const imgRef = react.useRef(null);
123
+ const [selecting, setSelecting] = react.useState(false);
124
+ const draw = react.useCallback(() => {
125
+ const canvas = canvasRef.current;
126
+ const img = imgRef.current;
127
+ if (!canvas || !img) return;
128
+ const ctx = canvas.getContext("2d");
129
+ const { startX, startY, endX, endY, active } = drag.current;
130
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
131
+ ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
132
+ ctx.fillStyle = "rgba(0,0,0,0.52)";
133
+ ctx.fillRect(0, 0, canvas.width, canvas.height);
134
+ if (active) {
135
+ const x = Math.min(startX, endX);
136
+ const y = Math.min(startY, endY);
137
+ const w = Math.abs(endX - startX);
138
+ const h = Math.abs(endY - startY);
139
+ ctx.clearRect(x, y, w, h);
140
+ ctx.drawImage(img, x, y, w, h, x, y, w, h);
141
+ ctx.strokeStyle = "#4F46E5";
142
+ ctx.lineWidth = 2;
143
+ ctx.strokeRect(x, y, w, h);
144
+ if (w > 60 && h > 20) {
145
+ ctx.fillStyle = "rgba(79,70,229,0.9)";
146
+ ctx.fillRect(x + 4, y + h - 20, 76, 18);
147
+ ctx.fillStyle = "#fff";
148
+ ctx.font = "bold 11px system-ui, -apple-system, sans-serif";
149
+ ctx.fillText(`${Math.round(w)} \xD7 ${Math.round(h)}`, x + 8, y + h - 6);
150
+ }
151
+ }
152
+ }, []);
153
+ react.useEffect(() => {
154
+ const canvas = canvasRef.current;
155
+ if (!canvas) return;
156
+ canvas.width = window.innerWidth;
157
+ canvas.height = window.innerHeight;
158
+ const img = new Image();
159
+ img.onload = () => {
160
+ imgRef.current = img;
161
+ draw();
162
+ };
163
+ img.src = fullPageCanvas.toDataURL();
164
+ }, [fullPageCanvas, draw]);
165
+ react.useEffect(() => {
166
+ const onKeyDown = (e) => {
167
+ if (e.key === "Escape") onCancel();
168
+ };
169
+ window.addEventListener("keydown", onKeyDown);
170
+ return () => window.removeEventListener("keydown", onKeyDown);
171
+ }, [onCancel]);
172
+ const onMouseDown = (e) => {
173
+ drag.current = { active: true, startX: e.clientX, startY: e.clientY, endX: e.clientX, endY: e.clientY };
174
+ setSelecting(true);
175
+ };
176
+ const onMouseMove = (e) => {
177
+ if (!drag.current.active) return;
178
+ drag.current.endX = e.clientX;
179
+ drag.current.endY = e.clientY;
180
+ draw();
181
+ };
182
+ const onMouseUp = () => {
183
+ if (!drag.current.active) return;
184
+ drag.current.active = false;
185
+ setSelecting(false);
186
+ const { startX, startY, endX, endY } = drag.current;
187
+ const w = Math.abs(endX - startX);
188
+ const h = Math.abs(endY - startY);
189
+ if (w < 20 || h < 20) {
190
+ drag.current = INIT_DRAG;
191
+ draw();
192
+ return;
193
+ }
194
+ onCapture({
195
+ startX: Math.min(startX, endX),
196
+ startY: Math.min(startY, endY),
197
+ endX: Math.max(startX, endX),
198
+ endY: Math.max(startY, endY)
199
+ });
200
+ };
201
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
202
+ /* @__PURE__ */ jsxRuntime.jsx(
203
+ "canvas",
204
+ {
205
+ ref: canvasRef,
206
+ onMouseDown,
207
+ onMouseMove,
208
+ onMouseUp,
209
+ style: { position: "fixed", top: 0, left: 0, zIndex: 999999, cursor: "crosshair", display: "block" }
210
+ }
211
+ ),
212
+ /* @__PURE__ */ jsxRuntime.jsxs(
213
+ "div",
214
+ {
215
+ style: {
216
+ position: "fixed",
217
+ top: 16,
218
+ left: "50%",
219
+ transform: "translateX(-50%)",
220
+ zIndex: 1e6,
221
+ display: "flex",
222
+ alignItems: "center",
223
+ gap: 8,
224
+ background: "rgba(15,15,15,0.88)",
225
+ borderRadius: 8,
226
+ padding: "6px 8px 6px 16px",
227
+ fontFamily: "system-ui, -apple-system, sans-serif"
228
+ },
229
+ children: [
230
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { color: "#fff", fontSize: 13, fontWeight: 500, whiteSpace: "nowrap" }, children: [
231
+ "Click and drag to select \xA0\xB7\xA0 ",
232
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { opacity: 0.6 }, children: "Esc to cancel" })
233
+ ] }),
234
+ /* @__PURE__ */ jsxRuntime.jsx(
235
+ "button",
236
+ {
237
+ onClick: () => onCapture({ startX: 0, startY: 0, endX: window.innerWidth, endY: window.innerHeight }),
238
+ style: {
239
+ background: "#4F46E5",
240
+ color: "#fff",
241
+ border: "none",
242
+ borderRadius: 6,
243
+ padding: "5px 12px",
244
+ cursor: "pointer",
245
+ fontSize: 12,
246
+ fontWeight: 600,
247
+ whiteSpace: "nowrap",
248
+ marginLeft: 4
249
+ },
250
+ children: "Full screen"
251
+ }
252
+ ),
253
+ /* @__PURE__ */ jsxRuntime.jsx(
254
+ "button",
255
+ {
256
+ onClick: onCancel,
257
+ style: {
258
+ background: "rgba(255,255,255,0.1)",
259
+ color: "#fff",
260
+ border: "1px solid rgba(255,255,255,0.15)",
261
+ borderRadius: 6,
262
+ padding: "5px 12px",
263
+ cursor: "pointer",
264
+ fontSize: 12
265
+ },
266
+ children: "Cancel"
267
+ }
268
+ )
269
+ ]
270
+ }
271
+ )
272
+ ] });
273
+ }
274
+ var COLORS = ["#EF4444", "#F97316", "#EAB308", "#22C55E", "#3B82F6", "#8B5CF6", "#000000", "#ffffff"];
275
+ var SIZES = [2, 5, 10];
276
+ var TOOL_ICONS = {
277
+ pen: /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M17 3a2.85 2.85 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5Z" }) }),
278
+ rect: /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsxRuntime.jsx("rect", { x: "3", y: "3", width: "18", height: "18", rx: "2" }) }),
279
+ ellipse: /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsxRuntime.jsx("ellipse", { cx: "12", cy: "12", rx: "10", ry: "6" }) }),
280
+ line: /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "4", y1: "20", x2: "20", y2: "4" }) }),
281
+ arrow: /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
282
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "5", y1: "19", x2: "19", y2: "5" }),
283
+ /* @__PURE__ */ jsxRuntime.jsx("polyline", { points: "9 5 19 5 19 15" })
284
+ ] })
285
+ };
286
+ function applyStrokeStyle(ctx, color, size) {
287
+ ctx.strokeStyle = color;
288
+ ctx.fillStyle = color;
289
+ ctx.lineWidth = size;
290
+ ctx.lineCap = "round";
291
+ ctx.lineJoin = "round";
292
+ }
293
+ function drawShape(ctx, tool, x1, y1, x2, y2) {
294
+ ctx.beginPath();
295
+ if (tool === "rect") {
296
+ ctx.strokeRect(x1, y1, x2 - x1, y2 - y1);
297
+ } else if (tool === "ellipse") {
298
+ const cx = (x1 + x2) / 2;
299
+ const cy = (y1 + y2) / 2;
300
+ ctx.ellipse(cx, cy, Math.abs(x2 - x1) / 2, Math.abs(y2 - y1) / 2, 0, 0, Math.PI * 2);
301
+ ctx.stroke();
302
+ } else if (tool === "line") {
303
+ ctx.moveTo(x1, y1);
304
+ ctx.lineTo(x2, y2);
305
+ ctx.stroke();
306
+ } else if (tool === "arrow") {
307
+ const angle = Math.atan2(y2 - y1, x2 - x1);
308
+ const head = Math.max(12, ctx.lineWidth * 4);
309
+ ctx.moveTo(x1, y1);
310
+ ctx.lineTo(x2, y2);
311
+ ctx.stroke();
312
+ ctx.beginPath();
313
+ ctx.moveTo(x2, y2);
314
+ ctx.lineTo(x2 - head * Math.cos(angle - Math.PI / 6), y2 - head * Math.sin(angle - Math.PI / 6));
315
+ ctx.lineTo(x2 - head * Math.cos(angle + Math.PI / 6), y2 - head * Math.sin(angle + Math.PI / 6));
316
+ ctx.closePath();
317
+ ctx.fill();
318
+ }
319
+ }
320
+ function AnnotationCanvas({ screenshotDataUrl, onDone, onBack }) {
321
+ const canvasRef = react.useRef(null);
322
+ const isDrawing = react.useRef(false);
323
+ const startPoint = react.useRef(null);
324
+ const lastPoint = react.useRef(null);
325
+ const baseSnapshot = react.useRef(null);
326
+ const [tool, setTool] = react.useState("pen");
327
+ const [color, setColor] = react.useState("#EF4444");
328
+ const [size, setSize] = react.useState(3);
329
+ const [naturalSize, setNaturalSize] = react.useState({ w: 0, h: 0 });
330
+ const toolRef = react.useRef(tool);
331
+ const colorRef = react.useRef(color);
332
+ const sizeRef = react.useRef(size);
333
+ react.useEffect(() => {
334
+ toolRef.current = tool;
335
+ }, [tool]);
336
+ react.useEffect(() => {
337
+ colorRef.current = color;
338
+ }, [color]);
339
+ react.useEffect(() => {
340
+ sizeRef.current = size;
341
+ }, [size]);
342
+ react.useEffect(() => {
343
+ const img = new Image();
344
+ img.onload = () => {
345
+ const maxW = window.innerWidth * 0.88;
346
+ const maxH = window.innerHeight * 0.72;
347
+ const ratio = img.width / img.height;
348
+ let dw = img.width, dh = img.height;
349
+ if (dw > maxW) {
350
+ dw = maxW;
351
+ dh = dw / ratio;
352
+ }
353
+ if (dh > maxH) {
354
+ dh = maxH;
355
+ dw = dh * ratio;
356
+ }
357
+ setNaturalSize({ w: img.width, h: img.height });
358
+ const canvas = canvasRef.current;
359
+ canvas.width = img.width;
360
+ canvas.height = img.height;
361
+ canvas.style.width = `${Math.round(dw)}px`;
362
+ canvas.style.height = `${Math.round(dh)}px`;
363
+ const ctx = canvas.getContext("2d");
364
+ ctx.drawImage(img, 0, 0);
365
+ baseSnapshot.current = ctx.getImageData(0, 0, canvas.width, canvas.height);
366
+ };
367
+ img.src = screenshotDataUrl;
368
+ }, [screenshotDataUrl]);
369
+ function getPoint(e) {
370
+ const canvas = canvasRef.current;
371
+ const rect = canvas.getBoundingClientRect();
372
+ return {
373
+ x: (e.clientX - rect.left) * (naturalSize.w / rect.width),
374
+ y: (e.clientY - rect.top) * (naturalSize.h / rect.height)
375
+ };
376
+ }
377
+ function onMouseDown(e) {
378
+ isDrawing.current = true;
379
+ const pt = getPoint(e);
380
+ startPoint.current = pt;
381
+ lastPoint.current = pt;
382
+ const canvas = canvasRef.current;
383
+ const ctx = canvas.getContext("2d");
384
+ baseSnapshot.current = ctx.getImageData(0, 0, canvas.width, canvas.height);
385
+ }
386
+ function onMouseMove(e) {
387
+ if (!isDrawing.current || !startPoint.current) return;
388
+ const canvas = canvasRef.current;
389
+ const ctx = canvas.getContext("2d");
390
+ const pt = getPoint(e);
391
+ applyStrokeStyle(ctx, colorRef.current, sizeRef.current);
392
+ if (toolRef.current === "pen") {
393
+ ctx.beginPath();
394
+ ctx.moveTo(lastPoint.current.x, lastPoint.current.y);
395
+ ctx.lineTo(pt.x, pt.y);
396
+ ctx.stroke();
397
+ lastPoint.current = pt;
398
+ } else {
399
+ ctx.putImageData(baseSnapshot.current, 0, 0);
400
+ applyStrokeStyle(ctx, colorRef.current, sizeRef.current);
401
+ drawShape(ctx, toolRef.current, startPoint.current.x, startPoint.current.y, pt.x, pt.y);
402
+ }
403
+ }
404
+ function onMouseUp(e) {
405
+ if (!isDrawing.current || !startPoint.current) return;
406
+ isDrawing.current = false;
407
+ const canvas = canvasRef.current;
408
+ const ctx = canvas.getContext("2d");
409
+ const pt = getPoint(e);
410
+ if (toolRef.current !== "pen") {
411
+ ctx.putImageData(baseSnapshot.current, 0, 0);
412
+ applyStrokeStyle(ctx, colorRef.current, sizeRef.current);
413
+ drawShape(ctx, toolRef.current, startPoint.current.x, startPoint.current.y, pt.x, pt.y);
414
+ }
415
+ baseSnapshot.current = ctx.getImageData(0, 0, canvas.width, canvas.height);
416
+ startPoint.current = null;
417
+ lastPoint.current = null;
418
+ }
419
+ function clearAnnotations() {
420
+ const canvas = canvasRef.current;
421
+ const ctx = canvas.getContext("2d");
422
+ const img = new Image();
423
+ img.onload = () => {
424
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
425
+ ctx.drawImage(img, 0, 0);
426
+ baseSnapshot.current = ctx.getImageData(0, 0, canvas.width, canvas.height);
427
+ };
428
+ img.src = screenshotDataUrl;
429
+ }
430
+ const toolBtn = (t) => ({
431
+ background: tool === t ? "#4F46E5" : "rgba(255,255,255,0.07)",
432
+ color: "#fff",
433
+ border: "none",
434
+ borderRadius: 6,
435
+ width: 30,
436
+ height: 30,
437
+ cursor: "pointer",
438
+ display: "flex",
439
+ alignItems: "center",
440
+ justifyContent: "center",
441
+ flexShrink: 0
442
+ });
443
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: {
444
+ position: "fixed",
445
+ inset: 0,
446
+ zIndex: 999999,
447
+ background: "rgba(0,0,0,0.82)",
448
+ display: "flex",
449
+ flexDirection: "column",
450
+ alignItems: "center",
451
+ justifyContent: "center",
452
+ gap: 16,
453
+ fontFamily: "system-ui, -apple-system, sans-serif"
454
+ }, children: [
455
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: {
456
+ display: "flex",
457
+ alignItems: "center",
458
+ gap: 10,
459
+ background: "#1a1a1a",
460
+ border: "1px solid rgba(255,255,255,0.1)",
461
+ padding: "8px 14px",
462
+ borderRadius: 10,
463
+ flexWrap: "wrap"
464
+ }, children: [
465
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: "#999", fontSize: 11, fontWeight: 600, textTransform: "uppercase", letterSpacing: "0.05em" }, children: "Tool" }),
466
+ Object.keys(TOOL_ICONS).map((t) => /* @__PURE__ */ jsxRuntime.jsx("button", { onClick: () => setTool(t), style: toolBtn(t), title: t, children: TOOL_ICONS[t] }, t)),
467
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { width: 1, height: 20, background: "rgba(255,255,255,0.12)" } }),
468
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: "#999", fontSize: 11, fontWeight: 600, textTransform: "uppercase", letterSpacing: "0.05em" }, children: "Color" }),
469
+ COLORS.map((c) => /* @__PURE__ */ jsxRuntime.jsx("button", { onClick: () => setColor(c), style: {
470
+ width: 20,
471
+ height: 20,
472
+ borderRadius: "50%",
473
+ background: c,
474
+ border: "none",
475
+ cursor: "pointer",
476
+ padding: 0,
477
+ flexShrink: 0,
478
+ outline: color === c ? "2px solid #4F46E5" : "none",
479
+ outlineOffset: 2,
480
+ boxShadow: color === c ? "0 0 0 1px rgba(79,70,229,0.4)" : "none"
481
+ } }, c)),
482
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { width: 1, height: 20, background: "rgba(255,255,255,0.12)" } }),
483
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: "#999", fontSize: 11, fontWeight: 600, textTransform: "uppercase", letterSpacing: "0.05em" }, children: "Size" }),
484
+ SIZES.map((s) => /* @__PURE__ */ jsxRuntime.jsx("button", { onClick: () => setSize(s), style: {
485
+ width: 28,
486
+ height: 28,
487
+ borderRadius: 6,
488
+ border: "none",
489
+ cursor: "pointer",
490
+ background: size === s ? "#4F46E5" : "rgba(255,255,255,0.07)",
491
+ display: "flex",
492
+ alignItems: "center",
493
+ justifyContent: "center",
494
+ flexShrink: 0
495
+ }, children: /* @__PURE__ */ jsxRuntime.jsx("div", { style: { width: s * 2.5, height: s * 2.5, borderRadius: "50%", background: "#fff" } }) }, s)),
496
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { width: 1, height: 20, background: "rgba(255,255,255,0.12)" } }),
497
+ /* @__PURE__ */ jsxRuntime.jsx("button", { onClick: clearAnnotations, style: {
498
+ background: "rgba(255,255,255,0.07)",
499
+ color: "#ccc",
500
+ border: "none",
501
+ borderRadius: 6,
502
+ padding: "4px 10px",
503
+ cursor: "pointer",
504
+ fontSize: 12,
505
+ fontWeight: 500
506
+ }, children: "Clear" })
507
+ ] }),
508
+ /* @__PURE__ */ jsxRuntime.jsx(
509
+ "canvas",
510
+ {
511
+ ref: canvasRef,
512
+ onMouseDown,
513
+ onMouseMove,
514
+ onMouseUp,
515
+ onMouseLeave: onMouseUp,
516
+ style: {
517
+ cursor: tool === "pen" ? "crosshair" : "crosshair",
518
+ borderRadius: 4,
519
+ boxShadow: "0 8px 32px rgba(0,0,0,0.6)",
520
+ display: "block",
521
+ maxWidth: "88vw",
522
+ maxHeight: "72vh"
523
+ }
524
+ }
525
+ ),
526
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", gap: 10 }, children: [
527
+ /* @__PURE__ */ jsxRuntime.jsx("button", { onClick: onBack, style: {
528
+ background: "rgba(255,255,255,0.08)",
529
+ color: "#ccc",
530
+ border: "1px solid rgba(255,255,255,0.12)",
531
+ borderRadius: 8,
532
+ padding: "9px 20px",
533
+ cursor: "pointer",
534
+ fontSize: 14,
535
+ fontWeight: 500
536
+ }, children: "\u2190 Back" }),
537
+ /* @__PURE__ */ jsxRuntime.jsx("button", { onClick: () => canvasRef.current && onDone(canvasRef.current), style: {
538
+ background: "#4F46E5",
539
+ color: "#fff",
540
+ border: "none",
541
+ borderRadius: 8,
542
+ padding: "9px 22px",
543
+ cursor: "pointer",
544
+ fontSize: 14,
545
+ fontWeight: 600
546
+ }, children: "Add comment \u2192" })
547
+ ] })
548
+ ] });
549
+ }
550
+ function FeedbackForm({
551
+ screenshotDataUrl,
552
+ isSubmitting,
553
+ error,
554
+ onSubmit,
555
+ onBack
556
+ }) {
557
+ const [summary, setSummary] = react.useState("");
558
+ const [description, setDescription] = react.useState("");
559
+ function handleSubmit(e) {
560
+ e.preventDefault();
561
+ if (!summary.trim()) return;
562
+ onSubmit(summary.trim(), description.trim());
563
+ }
564
+ return /* @__PURE__ */ jsxRuntime.jsx(
565
+ "div",
566
+ {
567
+ style: {
568
+ position: "fixed",
569
+ inset: 0,
570
+ zIndex: 999999,
571
+ background: "rgba(0,0,0,0.7)",
572
+ display: "flex",
573
+ alignItems: "center",
574
+ justifyContent: "center",
575
+ fontFamily: "system-ui, -apple-system, sans-serif",
576
+ padding: 16
577
+ },
578
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
579
+ "div",
580
+ {
581
+ style: {
582
+ background: "#fff",
583
+ borderRadius: 12,
584
+ width: "100%",
585
+ maxWidth: 480,
586
+ boxShadow: "0 24px 64px rgba(0,0,0,0.4)",
587
+ overflow: "hidden"
588
+ },
589
+ children: [
590
+ /* @__PURE__ */ jsxRuntime.jsxs(
591
+ "div",
592
+ {
593
+ style: {
594
+ background: "#4F46E5",
595
+ padding: "16px 20px",
596
+ color: "#fff"
597
+ },
598
+ children: [
599
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { style: { margin: 0, fontSize: 16, fontWeight: 700 }, children: "Send Feedback" }),
600
+ /* @__PURE__ */ jsxRuntime.jsx("p", { style: { margin: "4px 0 0", fontSize: 13, opacity: 0.8 }, children: "Describe what went wrong or what you'd like to report." })
601
+ ]
602
+ }
603
+ ),
604
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { padding: "12px 20px 0" }, children: [
605
+ /* @__PURE__ */ jsxRuntime.jsx("p", { style: { margin: "0 0 6px", fontSize: 12, fontWeight: 600, color: "#6B7280" }, children: "SCREENSHOT" }),
606
+ /* @__PURE__ */ jsxRuntime.jsx(
607
+ "img",
608
+ {
609
+ src: screenshotDataUrl,
610
+ alt: "Captured screenshot",
611
+ style: {
612
+ width: "100%",
613
+ borderRadius: 6,
614
+ border: "1px solid #E5E7EB",
615
+ display: "block",
616
+ maxHeight: 140,
617
+ objectFit: "cover",
618
+ objectPosition: "top"
619
+ }
620
+ }
621
+ )
622
+ ] }),
623
+ /* @__PURE__ */ jsxRuntime.jsxs("form", { onSubmit: handleSubmit, style: { padding: "16px 20px 20px" }, children: [
624
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { style: { display: "block", marginBottom: 12 }, children: [
625
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { fontSize: 13, fontWeight: 600, color: "#374151", display: "block", marginBottom: 4 }, children: [
626
+ "Summary ",
627
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: "#EF4444" }, children: "*" })
628
+ ] }),
629
+ /* @__PURE__ */ jsxRuntime.jsx(
630
+ "input",
631
+ {
632
+ type: "text",
633
+ value: summary,
634
+ onChange: (e) => setSummary(e.target.value),
635
+ placeholder: "Short description of the issue",
636
+ disabled: isSubmitting,
637
+ maxLength: 120,
638
+ required: true,
639
+ style: {
640
+ width: "100%",
641
+ padding: "8px 12px",
642
+ border: "1px solid #D1D5DB",
643
+ borderRadius: 7,
644
+ fontSize: 14,
645
+ outline: "none",
646
+ boxSizing: "border-box",
647
+ transition: "border-color 0.15s",
648
+ color: "#111827"
649
+ }
650
+ }
651
+ )
652
+ ] }),
653
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { style: { display: "block", marginBottom: 16 }, children: [
654
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: 13, fontWeight: 600, color: "#374151", display: "block", marginBottom: 4 }, children: "Additional details" }),
655
+ /* @__PURE__ */ jsxRuntime.jsx(
656
+ "textarea",
657
+ {
658
+ value: description,
659
+ onChange: (e) => setDescription(e.target.value),
660
+ placeholder: "Steps to reproduce, expected behavior, etc.",
661
+ disabled: isSubmitting,
662
+ rows: 4,
663
+ style: {
664
+ width: "100%",
665
+ padding: "8px 12px",
666
+ border: "1px solid #D1D5DB",
667
+ borderRadius: 7,
668
+ fontSize: 14,
669
+ outline: "none",
670
+ resize: "vertical",
671
+ boxSizing: "border-box",
672
+ fontFamily: "inherit",
673
+ color: "#111827"
674
+ }
675
+ }
676
+ )
677
+ ] }),
678
+ error && /* @__PURE__ */ jsxRuntime.jsx(
679
+ "div",
680
+ {
681
+ style: {
682
+ background: "#FEF2F2",
683
+ border: "1px solid #FECACA",
684
+ color: "#DC2626",
685
+ borderRadius: 7,
686
+ padding: "8px 12px",
687
+ fontSize: 13,
688
+ marginBottom: 12
689
+ },
690
+ children: error
691
+ }
692
+ ),
693
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", gap: 8, justifyContent: "flex-end" }, children: [
694
+ /* @__PURE__ */ jsxRuntime.jsx(
695
+ "button",
696
+ {
697
+ type: "button",
698
+ onClick: onBack,
699
+ disabled: isSubmitting,
700
+ style: {
701
+ background: "transparent",
702
+ color: "#6B7280",
703
+ border: "1px solid #D1D5DB",
704
+ borderRadius: 7,
705
+ padding: "8px 16px",
706
+ cursor: "pointer",
707
+ fontSize: 14,
708
+ fontWeight: 500
709
+ },
710
+ children: "\u2190 Back"
711
+ }
712
+ ),
713
+ /* @__PURE__ */ jsxRuntime.jsx(
714
+ "button",
715
+ {
716
+ type: "submit",
717
+ disabled: isSubmitting || !summary.trim(),
718
+ style: {
719
+ background: isSubmitting || !summary.trim() ? "#A5B4FC" : "#4F46E5",
720
+ color: "#fff",
721
+ border: "none",
722
+ borderRadius: 7,
723
+ padding: "8px 20px",
724
+ cursor: isSubmitting || !summary.trim() ? "not-allowed" : "pointer",
725
+ fontSize: 14,
726
+ fontWeight: 600,
727
+ minWidth: 110,
728
+ transition: "background 0.15s"
729
+ },
730
+ children: isSubmitting ? "Sending\u2026" : "Send to Jira"
731
+ }
732
+ )
733
+ ] })
734
+ ] })
735
+ ]
736
+ }
737
+ )
738
+ }
739
+ );
740
+ }
741
+ function makeAuthHeader(email, token) {
742
+ return "Basic " + btoa(`${email}:${token}`);
743
+ }
744
+ function makeAdfDescription(description, pageUrl, pageTitle) {
745
+ return {
746
+ type: "doc",
747
+ version: 1,
748
+ content: [
749
+ {
750
+ type: "paragraph",
751
+ content: [{ type: "text", text: description }]
752
+ },
753
+ {
754
+ type: "paragraph",
755
+ content: [
756
+ { type: "text", text: "Page: ", marks: [{ type: "strong" }] },
757
+ {
758
+ type: "text",
759
+ text: pageTitle || pageUrl,
760
+ marks: [
761
+ {
762
+ type: "link",
763
+ attrs: { href: pageUrl }
764
+ }
765
+ ]
766
+ }
767
+ ]
768
+ }
769
+ ]
770
+ };
771
+ }
772
+ async function createJiraIssue(params) {
773
+ const {
774
+ host,
775
+ projectKey,
776
+ token,
777
+ userEmail,
778
+ issueType,
779
+ labels,
780
+ summary,
781
+ description,
782
+ screenshotBlob,
783
+ pageUrl,
784
+ pageTitle
785
+ } = params;
786
+ const baseUrl = `https://${host}`;
787
+ const auth = makeAuthHeader(userEmail, token);
788
+ const issueBody = {
789
+ fields: chunkDDAAVRWG_js.__spreadValues({
790
+ project: { key: projectKey },
791
+ summary: `[Feedback] ${summary}`,
792
+ description: makeAdfDescription(description, pageUrl, pageTitle),
793
+ issuetype: { name: issueType }
794
+ }, labels.length > 0 && { labels })
795
+ };
796
+ const createRes = await fetch(`${baseUrl}/rest/api/3/issue`, {
797
+ method: "POST",
798
+ headers: {
799
+ Authorization: auth,
800
+ "Content-Type": "application/json",
801
+ Accept: "application/json"
802
+ },
803
+ body: JSON.stringify(issueBody)
804
+ });
805
+ if (!createRes.ok) {
806
+ const err = await createRes.text();
807
+ throw new Error(`Jira issue creation failed (${createRes.status}): ${err}`);
808
+ }
809
+ const { key: issueKey } = await createRes.json();
810
+ const formData = new FormData();
811
+ formData.append("file", screenshotBlob, "feedback-screenshot.png");
812
+ const attachRes = await fetch(`${baseUrl}/rest/api/3/issue/${issueKey}/attachments`, {
813
+ method: "POST",
814
+ headers: {
815
+ Authorization: auth,
816
+ "X-Atlassian-Token": "no-check"
817
+ },
818
+ body: formData
819
+ });
820
+ if (!attachRes.ok) {
821
+ console.warn(`[FeedbackWidget] Screenshot attachment failed (${attachRes.status})`);
822
+ }
823
+ return {
824
+ issueKey,
825
+ issueUrl: `${baseUrl}/browse/${issueKey}`
826
+ };
827
+ }
828
+ function useJira() {
829
+ const [isLoading, setIsLoading] = react.useState(false);
830
+ const [error, setError] = react.useState(null);
831
+ async function submit(params) {
832
+ setIsLoading(true);
833
+ setError(null);
834
+ try {
835
+ const result = await createJiraIssue(params);
836
+ return result;
837
+ } catch (err) {
838
+ const e = err instanceof Error ? err : new Error(String(err));
839
+ setError(e);
840
+ throw e;
841
+ } finally {
842
+ setIsLoading(false);
843
+ }
844
+ }
845
+ return { submit, isLoading, error };
846
+ }
847
+ function FeedbackWidget({
848
+ jiraHost,
849
+ jiraProjectKey,
850
+ jiraToken,
851
+ jiraUserEmail,
852
+ jiraIssueType = "Bug",
853
+ jiraLabels = [],
854
+ onSubmit: onSubmitProp,
855
+ apiRoute,
856
+ position = "bottom-right",
857
+ buttonLabel = "Feedback",
858
+ onSuccess,
859
+ onError
860
+ }) {
861
+ const [step, setStep] = react.useState("idle");
862
+ const [fullPageCanvas, setFullPageCanvas] = react.useState(null);
863
+ const [screenshotDataUrl, setScreenshotDataUrl] = react.useState("");
864
+ const [annotatedCanvas, setAnnotatedCanvas] = react.useState(null);
865
+ const [submitError, setSubmitError] = react.useState(null);
866
+ const [portalRoot, setPortalRoot] = react.useState(null);
867
+ const { submit: submitToJira } = useJira();
868
+ react.useEffect(() => {
869
+ const hasJiraConfig = jiraHost && jiraProjectKey && jiraToken && jiraUserEmail;
870
+ if (!hasJiraConfig && !onSubmitProp && !apiRoute) {
871
+ console.error("[FeedbackWidget] Provide apiRoute, onSubmit, or (jiraHost + jiraProjectKey + jiraToken + jiraUserEmail).");
872
+ }
873
+ }, [jiraHost, jiraProjectKey, jiraToken, jiraUserEmail, onSubmitProp, apiRoute]);
874
+ react.useEffect(() => {
875
+ const el = document.createElement("div");
876
+ el.setAttribute("data-feedback-widget", "");
877
+ document.body.appendChild(el);
878
+ setPortalRoot(el);
879
+ return () => {
880
+ document.body.removeChild(el);
881
+ };
882
+ }, []);
883
+ const handleButtonClick = react.useCallback(async () => {
884
+ setStep("capturing");
885
+ await new Promise((resolve) => requestAnimationFrame(() => requestAnimationFrame(resolve)));
886
+ try {
887
+ const stream = await navigator.mediaDevices.getDisplayMedia({
888
+ preferCurrentTab: true,
889
+ video: true,
890
+ audio: false
891
+ });
892
+ const video = document.createElement("video");
893
+ video.srcObject = stream;
894
+ video.muted = true;
895
+ await new Promise((resolve) => {
896
+ video.onloadedmetadata = () => resolve();
897
+ });
898
+ await video.play();
899
+ await new Promise((resolve) => requestAnimationFrame(resolve));
900
+ const canvas = document.createElement("canvas");
901
+ canvas.width = video.videoWidth;
902
+ canvas.height = video.videoHeight;
903
+ canvas.getContext("2d").drawImage(video, 0, 0);
904
+ stream.getTracks().forEach((t) => t.stop());
905
+ setFullPageCanvas(canvas);
906
+ setStep("selecting");
907
+ } catch (e) {
908
+ setStep("idle");
909
+ }
910
+ }, []);
911
+ const handleCapture = react.useCallback((rect) => {
912
+ if (!fullPageCanvas) return;
913
+ const scaleX = fullPageCanvas.width / window.innerWidth;
914
+ const scaleY = fullPageCanvas.height / window.innerHeight;
915
+ const cropX = Math.round(rect.startX * scaleX);
916
+ const cropY = Math.round(rect.startY * scaleY);
917
+ const cropW = Math.round((rect.endX - rect.startX) * scaleX);
918
+ const cropH = Math.round((rect.endY - rect.startY) * scaleY);
919
+ const cropped = document.createElement("canvas");
920
+ cropped.width = cropW;
921
+ cropped.height = cropH;
922
+ cropped.getContext("2d").drawImage(fullPageCanvas, cropX, cropY, cropW, cropH, 0, 0, cropW, cropH);
923
+ setScreenshotDataUrl(cropped.toDataURL("image/png"));
924
+ setStep("annotating");
925
+ }, [fullPageCanvas]);
926
+ const handleAnnotationDone = react.useCallback((canvas) => {
927
+ setAnnotatedCanvas(canvas);
928
+ setScreenshotDataUrl(canvas.toDataURL("image/png"));
929
+ setStep("form");
930
+ }, []);
931
+ const handleFormSubmit = react.useCallback(
932
+ async (summary, description) => {
933
+ var _a;
934
+ setSubmitError(null);
935
+ setStep("submitting");
936
+ const screenshotBlob = await new Promise((resolve, reject) => {
937
+ annotatedCanvas.toBlob((b) => b ? resolve(b) : reject(new Error("toBlob failed")), "image/png");
938
+ });
939
+ const payload = {
940
+ screenshot: screenshotBlob,
941
+ summary,
942
+ description,
943
+ pageUrl: window.location.href,
944
+ pageTitle: document.title
945
+ };
946
+ try {
947
+ let result = {};
948
+ if (onSubmitProp) {
949
+ result = (_a = await onSubmitProp(payload)) != null ? _a : {};
950
+ } else if (apiRoute) {
951
+ const fd = new FormData();
952
+ fd.append("screenshot", screenshotBlob);
953
+ fd.append("summary", summary);
954
+ fd.append("description", description);
955
+ fd.append("pageUrl", payload.pageUrl);
956
+ fd.append("pageTitle", payload.pageTitle);
957
+ const res = await fetch(apiRoute, { method: "POST", body: fd });
958
+ if (!res.ok) throw new Error(await res.text());
959
+ result = await res.json();
960
+ } else {
961
+ result = await submitToJira({
962
+ host: jiraHost,
963
+ projectKey: jiraProjectKey,
964
+ token: jiraToken,
965
+ userEmail: jiraUserEmail,
966
+ issueType: jiraIssueType,
967
+ labels: jiraLabels,
968
+ summary,
969
+ description,
970
+ screenshotBlob,
971
+ pageUrl: payload.pageUrl,
972
+ pageTitle: payload.pageTitle
973
+ });
974
+ }
975
+ setStep("success");
976
+ onSuccess == null ? void 0 : onSuccess(result);
977
+ setTimeout(() => {
978
+ setStep("idle");
979
+ setFullPageCanvas(null);
980
+ setScreenshotDataUrl("");
981
+ setAnnotatedCanvas(null);
982
+ }, 3e3);
983
+ } catch (err) {
984
+ const e = err instanceof Error ? err : new Error(String(err));
985
+ setSubmitError(e.message);
986
+ setStep("form");
987
+ onError == null ? void 0 : onError(e);
988
+ }
989
+ },
990
+ [
991
+ annotatedCanvas,
992
+ onSubmitProp,
993
+ submitToJira,
994
+ jiraHost,
995
+ jiraProjectKey,
996
+ jiraToken,
997
+ jiraUserEmail,
998
+ jiraIssueType,
999
+ jiraLabels,
1000
+ onSuccess,
1001
+ onError
1002
+ ]
1003
+ );
1004
+ const reset = react.useCallback(() => {
1005
+ setStep("idle");
1006
+ setFullPageCanvas(null);
1007
+ setScreenshotDataUrl("");
1008
+ setAnnotatedCanvas(null);
1009
+ setSubmitError(null);
1010
+ }, []);
1011
+ if (!portalRoot) return null;
1012
+ return ReactDOM__default.default.createPortal(
1013
+ /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1014
+ step === "idle" && /* @__PURE__ */ jsxRuntime.jsx(
1015
+ FeedbackButton,
1016
+ {
1017
+ position,
1018
+ label: buttonLabel,
1019
+ onClick: handleButtonClick
1020
+ }
1021
+ ),
1022
+ step === "selecting" && fullPageCanvas && /* @__PURE__ */ jsxRuntime.jsx(
1023
+ CaptureOverlay,
1024
+ {
1025
+ fullPageCanvas,
1026
+ onCapture: handleCapture,
1027
+ onCancel: reset
1028
+ }
1029
+ ),
1030
+ step === "annotating" && screenshotDataUrl && /* @__PURE__ */ jsxRuntime.jsx(
1031
+ AnnotationCanvas,
1032
+ {
1033
+ screenshotDataUrl,
1034
+ onDone: handleAnnotationDone,
1035
+ onBack: () => setStep("selecting")
1036
+ }
1037
+ ),
1038
+ (step === "form" || step === "submitting") && screenshotDataUrl && /* @__PURE__ */ jsxRuntime.jsx(
1039
+ FeedbackForm,
1040
+ {
1041
+ screenshotDataUrl,
1042
+ isSubmitting: step === "submitting",
1043
+ error: submitError,
1044
+ onSubmit: handleFormSubmit,
1045
+ onBack: () => setStep("annotating")
1046
+ }
1047
+ ),
1048
+ step === "success" && /* @__PURE__ */ jsxRuntime.jsx(SuccessToast, { position })
1049
+ ] }),
1050
+ portalRoot
1051
+ );
1052
+ }
1053
+ function SuccessToast({ position }) {
1054
+ const posStyle = position === "bottom-right" || position === "bottom-left" ? { bottom: 24 } : { top: 24 };
1055
+ const sideStyle = position === "bottom-right" || position === "top-right" ? { right: 24 } : { left: 24 };
1056
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: chunkDDAAVRWG_js.__spreadValues(chunkDDAAVRWG_js.__spreadValues({
1057
+ position: "fixed",
1058
+ zIndex: 999999,
1059
+ background: "#059669",
1060
+ color: "#fff",
1061
+ padding: "12px 20px",
1062
+ borderRadius: 10,
1063
+ fontFamily: "system-ui, -apple-system, sans-serif",
1064
+ fontSize: 14,
1065
+ fontWeight: 600,
1066
+ display: "flex",
1067
+ alignItems: "center",
1068
+ gap: 8,
1069
+ boxShadow: "0 4px 16px rgba(5,150,105,0.4)"
1070
+ }, posStyle), sideStyle), children: [
1071
+ /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsxRuntime.jsx("polyline", { points: "20 6 9 17 4 12" }) }),
1072
+ "Feedback sent to Jira!"
1073
+ ] });
1074
+ }
1075
+
1076
+ exports.FeedbackWidget = FeedbackWidget;
1077
+ //# sourceMappingURL=index.js.map
1078
+ //# sourceMappingURL=index.js.map