uilint-react 0.1.22 → 0.1.24

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.
@@ -0,0 +1,767 @@
1
+ "use client";
2
+ "use client";
3
+ import {
4
+ useUILintContext
5
+ } from "./chunk-I4C3NAUH.js";
6
+
7
+ // src/components/ui-lint/ElementBadges.tsx
8
+ import React, { useState, useEffect, useCallback, useMemo } from "react";
9
+ import { createPortal } from "react-dom";
10
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
11
+ var STYLES = {
12
+ bg: "rgba(17, 24, 39, 0.95)",
13
+ success: "#10B981",
14
+ warning: "#F59E0B",
15
+ error: "#EF4444",
16
+ text: "#FFFFFF",
17
+ border: "rgba(255, 255, 255, 0.2)",
18
+ highlight: "#3B82F6",
19
+ font: 'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
20
+ shadow: "0 2px 8px rgba(0, 0, 0, 0.3)"
21
+ };
22
+ var PROXIMITY_THRESHOLD = 100;
23
+ var CLUSTER_THRESHOLD = 24;
24
+ function getBadgeColor(issueCount) {
25
+ if (issueCount === 0) return STYLES.success;
26
+ if (issueCount <= 2) return STYLES.warning;
27
+ return STYLES.error;
28
+ }
29
+ function ElementBadge({
30
+ element,
31
+ issue,
32
+ isNearCursor,
33
+ onSelect
34
+ }) {
35
+ const [rect, setRect] = useState(null);
36
+ const [isHovered, setIsHovered] = useState(false);
37
+ useEffect(() => {
38
+ const updateRect = () => {
39
+ if (element.element && document.contains(element.element)) {
40
+ setRect(element.element.getBoundingClientRect());
41
+ } else {
42
+ setRect(null);
43
+ }
44
+ };
45
+ updateRect();
46
+ let rafId;
47
+ const handleUpdate = () => {
48
+ updateRect();
49
+ rafId = requestAnimationFrame(handleUpdate);
50
+ };
51
+ rafId = requestAnimationFrame(handleUpdate);
52
+ return () => {
53
+ cancelAnimationFrame(rafId);
54
+ };
55
+ }, [element.element]);
56
+ const handleClick = useCallback(
57
+ (e) => {
58
+ e.preventDefault();
59
+ e.stopPropagation();
60
+ onSelect(element, issue);
61
+ },
62
+ [element, issue, onSelect]
63
+ );
64
+ if (!rect) return null;
65
+ if (rect.top < -50 || rect.top > window.innerHeight + 50) return null;
66
+ if (rect.left < -50 || rect.left > window.innerWidth + 50) return null;
67
+ const badgeStyle = {
68
+ position: "fixed",
69
+ top: rect.top - 8,
70
+ left: rect.right - 8,
71
+ zIndex: isHovered ? 99999 : 99995,
72
+ cursor: "pointer",
73
+ transition: "transform 0.15s ease-out",
74
+ transform: isHovered ? "scale(1.1)" : "scale(1)"
75
+ };
76
+ const badgeColor = issue.status === "complete" ? getBadgeColor(issue.issues.length) : issue.status === "error" ? STYLES.error : issue.status === "scanning" ? STYLES.highlight : "rgba(156, 163, 175, 0.5)";
77
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
78
+ isHovered && /* @__PURE__ */ jsx(
79
+ "div",
80
+ {
81
+ style: {
82
+ position: "fixed",
83
+ top: rect.top - 2,
84
+ left: rect.left - 2,
85
+ width: rect.width + 4,
86
+ height: rect.height + 4,
87
+ border: `2px solid ${STYLES.highlight}`,
88
+ borderRadius: "4px",
89
+ pointerEvents: "none",
90
+ zIndex: 99994,
91
+ boxShadow: `0 0 0 1px rgba(59, 130, 246, 0.3)`
92
+ },
93
+ "data-ui-lint": true
94
+ }
95
+ ),
96
+ /* @__PURE__ */ jsx(
97
+ "div",
98
+ {
99
+ style: badgeStyle,
100
+ "data-ui-lint": true,
101
+ onMouseEnter: () => setIsHovered(true),
102
+ onMouseLeave: () => setIsHovered(false),
103
+ onClick: handleClick,
104
+ children: isNearCursor || isHovered ? /* @__PURE__ */ jsxs(Fragment, { children: [
105
+ issue.status === "scanning" && /* @__PURE__ */ jsx(ScanningBadge, {}),
106
+ issue.status === "complete" && /* @__PURE__ */ jsx(IssueBadge, { count: issue.issues.length }),
107
+ issue.status === "error" && /* @__PURE__ */ jsx(ErrorBadge, {}),
108
+ issue.status === "pending" && /* @__PURE__ */ jsx(PendingBadge, {})
109
+ ] }) : /* @__PURE__ */ jsx(MinimizedBadge, { color: badgeColor })
110
+ }
111
+ )
112
+ ] });
113
+ }
114
+ function MinimizedBadge({ color }) {
115
+ return /* @__PURE__ */ jsx(
116
+ "div",
117
+ {
118
+ style: {
119
+ width: "6px",
120
+ height: "6px",
121
+ borderRadius: "50%",
122
+ backgroundColor: color,
123
+ opacity: 0.7,
124
+ transition: "all 0.15s ease-out",
125
+ boxShadow: STYLES.shadow
126
+ }
127
+ }
128
+ );
129
+ }
130
+ function IssueBadge({ count }) {
131
+ const color = getBadgeColor(count);
132
+ if (count === 0) {
133
+ return /* @__PURE__ */ jsx(
134
+ "div",
135
+ {
136
+ style: {
137
+ display: "flex",
138
+ alignItems: "center",
139
+ justifyContent: "center",
140
+ width: "18px",
141
+ height: "18px",
142
+ borderRadius: "50%",
143
+ backgroundColor: color,
144
+ boxShadow: STYLES.shadow,
145
+ border: `1px solid ${STYLES.border}`
146
+ },
147
+ children: /* @__PURE__ */ jsx(CheckIcon, {})
148
+ }
149
+ );
150
+ }
151
+ return /* @__PURE__ */ jsx(
152
+ "div",
153
+ {
154
+ style: {
155
+ display: "flex",
156
+ alignItems: "center",
157
+ justifyContent: "center",
158
+ minWidth: "18px",
159
+ height: "18px",
160
+ padding: "0 5px",
161
+ borderRadius: "9px",
162
+ backgroundColor: color,
163
+ color: STYLES.text,
164
+ fontSize: "10px",
165
+ fontWeight: 700,
166
+ fontFamily: STYLES.font,
167
+ boxShadow: STYLES.shadow,
168
+ border: `1px solid ${STYLES.border}`
169
+ },
170
+ children: count > 9 ? "9+" : count
171
+ }
172
+ );
173
+ }
174
+ function ScanningBadge() {
175
+ return /* @__PURE__ */ jsxs(
176
+ "div",
177
+ {
178
+ style: {
179
+ display: "flex",
180
+ alignItems: "center",
181
+ justifyContent: "center",
182
+ width: "18px",
183
+ height: "18px",
184
+ borderRadius: "50%",
185
+ backgroundColor: STYLES.bg,
186
+ boxShadow: STYLES.shadow,
187
+ border: `1px solid ${STYLES.border}`
188
+ },
189
+ children: [
190
+ /* @__PURE__ */ jsx("style", { children: `
191
+ @keyframes uilint-badge-spin {
192
+ from { transform: rotate(0deg); }
193
+ to { transform: rotate(360deg); }
194
+ }
195
+ ` }),
196
+ /* @__PURE__ */ jsx(
197
+ "div",
198
+ {
199
+ style: {
200
+ width: "10px",
201
+ height: "10px",
202
+ border: "2px solid rgba(59, 130, 246, 0.3)",
203
+ borderTopColor: "#3B82F6",
204
+ borderRadius: "50%",
205
+ animation: "uilint-badge-spin 0.8s linear infinite"
206
+ }
207
+ }
208
+ )
209
+ ]
210
+ }
211
+ );
212
+ }
213
+ function PendingBadge() {
214
+ return /* @__PURE__ */ jsx(
215
+ "div",
216
+ {
217
+ style: {
218
+ width: "10px",
219
+ height: "10px",
220
+ borderRadius: "50%",
221
+ backgroundColor: "rgba(156, 163, 175, 0.5)",
222
+ boxShadow: STYLES.shadow
223
+ }
224
+ }
225
+ );
226
+ }
227
+ function ErrorBadge() {
228
+ return /* @__PURE__ */ jsx(
229
+ "div",
230
+ {
231
+ style: {
232
+ display: "flex",
233
+ alignItems: "center",
234
+ justifyContent: "center",
235
+ width: "18px",
236
+ height: "18px",
237
+ borderRadius: "50%",
238
+ backgroundColor: STYLES.error,
239
+ boxShadow: STYLES.shadow,
240
+ border: `1px solid ${STYLES.border}`
241
+ },
242
+ children: /* @__PURE__ */ jsx(ExclamationIcon, {})
243
+ }
244
+ );
245
+ }
246
+ var UnionFind = class {
247
+ parent = /* @__PURE__ */ new Map();
248
+ find(x) {
249
+ if (!this.parent.has(x)) {
250
+ this.parent.set(x, x);
251
+ }
252
+ if (this.parent.get(x) !== x) {
253
+ this.parent.set(x, this.find(this.parent.get(x)));
254
+ }
255
+ return this.parent.get(x);
256
+ }
257
+ union(x, y) {
258
+ const px = this.find(x);
259
+ const py = this.find(y);
260
+ if (px !== py) {
261
+ this.parent.set(px, py);
262
+ }
263
+ }
264
+ };
265
+ function clusterBadges(positions, threshold) {
266
+ if (positions.length === 0) return [];
267
+ const uf = new UnionFind();
268
+ for (let i = 0; i < positions.length; i++) {
269
+ for (let j = i + 1; j < positions.length; j++) {
270
+ const dist = Math.hypot(
271
+ positions[i].x - positions[j].x,
272
+ positions[i].y - positions[j].y
273
+ );
274
+ if (dist <= threshold) {
275
+ uf.union(positions[i].element.id, positions[j].element.id);
276
+ }
277
+ }
278
+ }
279
+ const clusters = /* @__PURE__ */ new Map();
280
+ for (const pos of positions) {
281
+ const root = uf.find(pos.element.id);
282
+ if (!clusters.has(root)) {
283
+ clusters.set(root, []);
284
+ }
285
+ clusters.get(root).push(pos);
286
+ }
287
+ return Array.from(clusters.entries()).map(([id, badges]) => {
288
+ const centroidX = badges.reduce((sum, b) => sum + b.x, 0) / badges.length;
289
+ const centroidY = badges.reduce((sum, b) => sum + b.y, 0) / badges.length;
290
+ return { id, badges, centroidX, centroidY };
291
+ });
292
+ }
293
+ function ElementBadges() {
294
+ const { autoScanState, elementIssuesCache, setInspectedElement } = useUILintContext();
295
+ const [mounted, setMounted] = useState(false);
296
+ const [cursorPos, setCursorPos] = useState({ x: 0, y: 0 });
297
+ const [badgePositions, setBadgePositions] = useState([]);
298
+ useEffect(() => {
299
+ setMounted(true);
300
+ }, []);
301
+ useEffect(() => {
302
+ const handleMouseMove = (e) => {
303
+ setCursorPos({ x: e.clientX, y: e.clientY });
304
+ };
305
+ window.addEventListener("mousemove", handleMouseMove);
306
+ return () => window.removeEventListener("mousemove", handleMouseMove);
307
+ }, []);
308
+ useEffect(() => {
309
+ if (autoScanState.status === "idle") {
310
+ setBadgePositions([]);
311
+ return;
312
+ }
313
+ const updatePositions = () => {
314
+ const positions = [];
315
+ for (const element of autoScanState.elements) {
316
+ const issue = elementIssuesCache.get(element.id);
317
+ if (!issue) continue;
318
+ if (!element.element || !document.contains(element.element)) continue;
319
+ const rect = element.element.getBoundingClientRect();
320
+ const x = rect.right - 8;
321
+ const y = rect.top - 8;
322
+ if (rect.top < -50 || rect.top > window.innerHeight + 50) continue;
323
+ if (rect.left < -50 || rect.left > window.innerWidth + 50) continue;
324
+ positions.push({ element, issue, x, y, rect });
325
+ }
326
+ setBadgePositions(positions);
327
+ };
328
+ updatePositions();
329
+ let rafId;
330
+ const loop = () => {
331
+ updatePositions();
332
+ rafId = requestAnimationFrame(loop);
333
+ };
334
+ rafId = requestAnimationFrame(loop);
335
+ return () => cancelAnimationFrame(rafId);
336
+ }, [autoScanState, elementIssuesCache]);
337
+ const handleSelect = useCallback(
338
+ (element, issue) => {
339
+ const inspected = {
340
+ element: element.element,
341
+ source: element.source,
342
+ componentStack: element.componentStack,
343
+ rect: element.element.getBoundingClientRect(),
344
+ scannedElementId: element.id
345
+ };
346
+ setInspectedElement(inspected);
347
+ },
348
+ [setInspectedElement]
349
+ );
350
+ const clusters = useMemo(
351
+ () => clusterBadges(badgePositions, CLUSTER_THRESHOLD),
352
+ [badgePositions]
353
+ );
354
+ if (!mounted) return null;
355
+ if (autoScanState.status === "idle") return null;
356
+ const content = /* @__PURE__ */ jsx("div", { "data-ui-lint": true, children: clusters.map((cluster) => {
357
+ if (cluster.badges.length === 1) {
358
+ const { element, issue, x, y } = cluster.badges[0];
359
+ const distance = Math.hypot(x - cursorPos.x, y - cursorPos.y);
360
+ const isNearCursor = distance <= PROXIMITY_THRESHOLD;
361
+ return /* @__PURE__ */ jsx(
362
+ ElementBadge,
363
+ {
364
+ element,
365
+ issue,
366
+ isNearCursor,
367
+ onSelect: handleSelect
368
+ },
369
+ element.id
370
+ );
371
+ } else {
372
+ const distance = Math.hypot(
373
+ cluster.centroidX - cursorPos.x,
374
+ cluster.centroidY - cursorPos.y
375
+ );
376
+ const isNearCursor = distance <= PROXIMITY_THRESHOLD;
377
+ return /* @__PURE__ */ jsx(
378
+ ClusteredBadge,
379
+ {
380
+ cluster,
381
+ isNearCursor,
382
+ onSelect: handleSelect
383
+ },
384
+ cluster.id
385
+ );
386
+ }
387
+ }) });
388
+ return createPortal(content, document.body);
389
+ }
390
+ function ClusteredBadge({
391
+ cluster,
392
+ isNearCursor,
393
+ onSelect
394
+ }) {
395
+ const [isExpanded, setIsExpanded] = useState(false);
396
+ const [hoveredIndex, setHoveredIndex] = useState(null);
397
+ const closeTimeoutRef = React.useRef(null);
398
+ const badgeSegments = useMemo(() => {
399
+ return cluster.badges.map(({ issue }) => {
400
+ if (issue.status === "complete") {
401
+ const count = issue.issues.length;
402
+ return {
403
+ type: "count",
404
+ count,
405
+ color: getBadgeColor(count)
406
+ };
407
+ } else if (issue.status === "error") {
408
+ return { type: "error", color: STYLES.error };
409
+ } else if (issue.status === "scanning") {
410
+ return { type: "scanning", color: STYLES.highlight };
411
+ } else {
412
+ return { type: "pending", color: "rgba(156, 163, 175, 0.5)" };
413
+ }
414
+ });
415
+ }, [cluster.badges]);
416
+ const worstColor = useMemo(() => {
417
+ let worst = 0;
418
+ for (const { issue } of cluster.badges) {
419
+ if (issue.status === "complete") {
420
+ worst = Math.max(worst, issue.issues.length);
421
+ } else if (issue.status === "error") {
422
+ worst = Math.max(worst, 10);
423
+ }
424
+ }
425
+ return getBadgeColor(worst);
426
+ }, [cluster.badges]);
427
+ const handleMouseEnter = useCallback(() => {
428
+ if (closeTimeoutRef.current) {
429
+ clearTimeout(closeTimeoutRef.current);
430
+ closeTimeoutRef.current = null;
431
+ }
432
+ setIsExpanded(true);
433
+ }, []);
434
+ const handleMouseLeave = useCallback(() => {
435
+ closeTimeoutRef.current = setTimeout(() => {
436
+ setIsExpanded(false);
437
+ setHoveredIndex(null);
438
+ }, 150);
439
+ }, []);
440
+ const hoveredBadge = hoveredIndex !== null ? cluster.badges[hoveredIndex] : null;
441
+ const dropdownStyle = useMemo(() => {
442
+ const preferRight = cluster.centroidX < window.innerWidth - 200;
443
+ const preferBelow = cluster.centroidY < window.innerHeight - 200;
444
+ return {
445
+ position: "fixed",
446
+ top: preferBelow ? cluster.centroidY + 12 : void 0,
447
+ bottom: preferBelow ? void 0 : window.innerHeight - cluster.centroidY + 12,
448
+ left: preferRight ? cluster.centroidX - 8 : void 0,
449
+ right: preferRight ? void 0 : window.innerWidth - cluster.centroidX - 8,
450
+ zIndex: 1e5,
451
+ backgroundColor: STYLES.bg,
452
+ borderRadius: "8px",
453
+ border: `1px solid ${STYLES.border}`,
454
+ boxShadow: "0 4px 20px rgba(0, 0, 0, 0.4)",
455
+ padding: "4px 0",
456
+ minWidth: "180px",
457
+ fontFamily: STYLES.font
458
+ };
459
+ }, [cluster.centroidX, cluster.centroidY]);
460
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
461
+ hoveredBadge && /* @__PURE__ */ jsx(
462
+ "div",
463
+ {
464
+ style: {
465
+ position: "fixed",
466
+ top: hoveredBadge.rect.top - 2,
467
+ left: hoveredBadge.rect.left - 2,
468
+ width: hoveredBadge.rect.width + 4,
469
+ height: hoveredBadge.rect.height + 4,
470
+ border: `2px solid ${STYLES.highlight}`,
471
+ borderRadius: "4px",
472
+ pointerEvents: "none",
473
+ zIndex: 99994,
474
+ boxShadow: `0 0 0 1px rgba(59, 130, 246, 0.3)`
475
+ },
476
+ "data-ui-lint": true
477
+ }
478
+ ),
479
+ /* @__PURE__ */ jsx(
480
+ "div",
481
+ {
482
+ style: {
483
+ position: "fixed",
484
+ top: cluster.centroidY - 9,
485
+ left: cluster.centroidX - 9,
486
+ zIndex: isExpanded ? 99999 : 99995,
487
+ cursor: "pointer"
488
+ },
489
+ "data-ui-lint": true,
490
+ onMouseEnter: handleMouseEnter,
491
+ onMouseLeave: handleMouseLeave,
492
+ children: isNearCursor || isExpanded ? /* @__PURE__ */ jsx(
493
+ "div",
494
+ {
495
+ style: {
496
+ display: "flex",
497
+ alignItems: "center",
498
+ height: "20px",
499
+ borderRadius: "10px",
500
+ backgroundColor: STYLES.bg,
501
+ boxShadow: STYLES.shadow,
502
+ border: `1px solid ${STYLES.border}`,
503
+ overflow: "hidden",
504
+ transition: "transform 0.15s ease-out",
505
+ transform: isExpanded ? "scale(1.1)" : "scale(1)"
506
+ },
507
+ children: badgeSegments.map((segment, index) => /* @__PURE__ */ jsxs(
508
+ "div",
509
+ {
510
+ style: {
511
+ display: "flex",
512
+ alignItems: "center",
513
+ justifyContent: "center",
514
+ minWidth: "18px",
515
+ height: "100%",
516
+ padding: "0 4px",
517
+ backgroundColor: segment.color,
518
+ borderRight: index < badgeSegments.length - 1 ? `1px solid rgba(0, 0, 0, 0.2)` : void 0
519
+ },
520
+ children: [
521
+ segment.type === "count" && (segment.count === 0 ? /* @__PURE__ */ jsx(CheckIconTiny, {}) : /* @__PURE__ */ jsx(
522
+ "span",
523
+ {
524
+ style: {
525
+ color: STYLES.text,
526
+ fontSize: "10px",
527
+ fontWeight: 700,
528
+ fontFamily: STYLES.font
529
+ },
530
+ children: segment.count > 9 ? "9+" : segment.count
531
+ }
532
+ )),
533
+ segment.type === "error" && /* @__PURE__ */ jsx(ExclamationIconTiny, {}),
534
+ segment.type === "scanning" && /* @__PURE__ */ jsx(
535
+ "div",
536
+ {
537
+ style: {
538
+ width: "8px",
539
+ height: "8px",
540
+ border: "1.5px solid rgba(255, 255, 255, 0.3)",
541
+ borderTopColor: "#FFFFFF",
542
+ borderRadius: "50%",
543
+ animation: "uilint-badge-spin 0.8s linear infinite"
544
+ }
545
+ }
546
+ ),
547
+ segment.type === "pending" && /* @__PURE__ */ jsx(
548
+ "div",
549
+ {
550
+ style: {
551
+ width: "6px",
552
+ height: "6px",
553
+ borderRadius: "50%",
554
+ backgroundColor: "rgba(255, 255, 255, 0.4)"
555
+ }
556
+ }
557
+ )
558
+ ]
559
+ },
560
+ index
561
+ ))
562
+ }
563
+ ) : /* @__PURE__ */ jsx(MinimizedBadge, { color: worstColor })
564
+ }
565
+ ),
566
+ isExpanded && /* @__PURE__ */ jsx(
567
+ "div",
568
+ {
569
+ style: dropdownStyle,
570
+ "data-ui-lint": true,
571
+ onMouseEnter: handleMouseEnter,
572
+ onMouseLeave: handleMouseLeave,
573
+ children: cluster.badges.map((badge, index) => /* @__PURE__ */ jsx(
574
+ ClusterDropdownItem,
575
+ {
576
+ badge,
577
+ isHovered: hoveredIndex === index,
578
+ onMouseEnter: () => setHoveredIndex(index),
579
+ onMouseLeave: () => setHoveredIndex(null),
580
+ onClick: () => onSelect(badge.element, badge.issue)
581
+ },
582
+ badge.element.id
583
+ ))
584
+ }
585
+ )
586
+ ] });
587
+ }
588
+ function ClusterDropdownItem({
589
+ badge,
590
+ isHovered,
591
+ onMouseEnter,
592
+ onMouseLeave,
593
+ onClick
594
+ }) {
595
+ const componentName = badge.element.componentStack[0]?.name || badge.element.tagName.toLowerCase();
596
+ const issueCount = badge.issue.status === "complete" ? badge.issue.issues.length : 0;
597
+ const color = getBadgeColor(issueCount);
598
+ return /* @__PURE__ */ jsxs(
599
+ "div",
600
+ {
601
+ style: {
602
+ display: "flex",
603
+ alignItems: "center",
604
+ justifyContent: "space-between",
605
+ padding: "8px 12px",
606
+ cursor: "pointer",
607
+ backgroundColor: isHovered ? "rgba(59, 130, 246, 0.15)" : "transparent",
608
+ transition: "background-color 0.1s"
609
+ },
610
+ onMouseEnter,
611
+ onMouseLeave,
612
+ onClick,
613
+ children: [
614
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: "8px" }, children: [
615
+ /* @__PURE__ */ jsx(
616
+ "div",
617
+ {
618
+ style: {
619
+ width: "6px",
620
+ height: "6px",
621
+ borderRadius: "50%",
622
+ backgroundColor: color
623
+ }
624
+ }
625
+ ),
626
+ /* @__PURE__ */ jsx(
627
+ "span",
628
+ {
629
+ style: {
630
+ fontSize: "12px",
631
+ color: STYLES.text,
632
+ maxWidth: "120px",
633
+ overflow: "hidden",
634
+ textOverflow: "ellipsis",
635
+ whiteSpace: "nowrap"
636
+ },
637
+ children: componentName
638
+ }
639
+ )
640
+ ] }),
641
+ badge.issue.status === "complete" && (issueCount === 0 ? /* @__PURE__ */ jsx(
642
+ "div",
643
+ {
644
+ style: {
645
+ width: "14px",
646
+ height: "14px",
647
+ borderRadius: "50%",
648
+ backgroundColor: color,
649
+ display: "flex",
650
+ alignItems: "center",
651
+ justifyContent: "center"
652
+ },
653
+ children: /* @__PURE__ */ jsx(CheckIcon, {})
654
+ }
655
+ ) : /* @__PURE__ */ jsx(
656
+ "div",
657
+ {
658
+ style: {
659
+ minWidth: "16px",
660
+ height: "16px",
661
+ padding: "0 4px",
662
+ borderRadius: "8px",
663
+ backgroundColor: color,
664
+ color: STYLES.text,
665
+ fontSize: "10px",
666
+ fontWeight: 700,
667
+ display: "flex",
668
+ alignItems: "center",
669
+ justifyContent: "center"
670
+ },
671
+ children: issueCount > 9 ? "9+" : issueCount
672
+ }
673
+ )),
674
+ badge.issue.status === "scanning" && /* @__PURE__ */ jsx(
675
+ "div",
676
+ {
677
+ style: {
678
+ width: "12px",
679
+ height: "12px",
680
+ border: "2px solid rgba(59, 130, 246, 0.3)",
681
+ borderTopColor: STYLES.highlight,
682
+ borderRadius: "50%",
683
+ animation: "uilint-badge-spin 0.8s linear infinite"
684
+ }
685
+ }
686
+ ),
687
+ badge.issue.status === "error" && /* @__PURE__ */ jsx(
688
+ "div",
689
+ {
690
+ style: {
691
+ width: "14px",
692
+ height: "14px",
693
+ borderRadius: "50%",
694
+ backgroundColor: STYLES.error,
695
+ display: "flex",
696
+ alignItems: "center",
697
+ justifyContent: "center"
698
+ },
699
+ children: /* @__PURE__ */ jsx(ExclamationIcon, {})
700
+ }
701
+ ),
702
+ badge.issue.status === "pending" && /* @__PURE__ */ jsx(
703
+ "div",
704
+ {
705
+ style: {
706
+ width: "8px",
707
+ height: "8px",
708
+ borderRadius: "50%",
709
+ backgroundColor: "rgba(156, 163, 175, 0.5)"
710
+ }
711
+ }
712
+ )
713
+ ]
714
+ }
715
+ );
716
+ }
717
+ function CheckIcon() {
718
+ return /* @__PURE__ */ jsx("svg", { width: "10", height: "10", viewBox: "0 0 24 24", fill: "none", children: /* @__PURE__ */ jsx(
719
+ "path",
720
+ {
721
+ d: "M20 6L9 17l-5-5",
722
+ stroke: STYLES.text,
723
+ strokeWidth: "3",
724
+ strokeLinecap: "round",
725
+ strokeLinejoin: "round"
726
+ }
727
+ ) });
728
+ }
729
+ function CheckIconTiny() {
730
+ return /* @__PURE__ */ jsx("svg", { width: "8", height: "8", viewBox: "0 0 24 24", fill: "none", children: /* @__PURE__ */ jsx(
731
+ "path",
732
+ {
733
+ d: "M20 6L9 17l-5-5",
734
+ stroke: STYLES.text,
735
+ strokeWidth: "4",
736
+ strokeLinecap: "round",
737
+ strokeLinejoin: "round"
738
+ }
739
+ ) });
740
+ }
741
+ function ExclamationIconTiny() {
742
+ return /* @__PURE__ */ jsx("svg", { width: "8", height: "8", viewBox: "0 0 24 24", fill: "none", children: /* @__PURE__ */ jsx(
743
+ "path",
744
+ {
745
+ d: "M12 8v4M12 16h.01",
746
+ stroke: STYLES.text,
747
+ strokeWidth: "4",
748
+ strokeLinecap: "round",
749
+ strokeLinejoin: "round"
750
+ }
751
+ ) });
752
+ }
753
+ function ExclamationIcon() {
754
+ return /* @__PURE__ */ jsx("svg", { width: "10", height: "10", viewBox: "0 0 24 24", fill: "none", children: /* @__PURE__ */ jsx(
755
+ "path",
756
+ {
757
+ d: "M12 8v4M12 16h.01",
758
+ stroke: STYLES.text,
759
+ strokeWidth: "3",
760
+ strokeLinecap: "round",
761
+ strokeLinejoin: "round"
762
+ }
763
+ ) });
764
+ }
765
+ export {
766
+ ElementBadges
767
+ };