uilint-react 0.1.43 → 0.1.45
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/{ElementBadges-2I25HN6W.js → ElementBadges-RV7I6QXS.js} +1 -1
- package/dist/InspectionPanel-QC6WR5IG.js +10 -0
- package/dist/{LocatorOverlay-ERRFPXKK.js → LocatorOverlay-Z24VU27L.js} +2 -2
- package/dist/UILintToolbar-5NK77IQJ.js +10 -0
- package/dist/{chunk-LAL3JTAA.js → chunk-BJD2V2LF.js} +39 -7
- package/dist/{chunk-C6NUU5MF.js → chunk-EQKEHJI4.js} +291 -141
- package/dist/chunk-W42PI2OF.js +81 -0
- package/dist/{chunk-UD6HPLEZ.js → chunk-YLTHKMTO.js} +1 -1
- package/dist/chunk-ZZOKTGSU.js +1017 -0
- package/dist/index.js +5 -4
- package/package.json +6 -3
- package/dist/InspectionPanel-4LOWGHW7.js +0 -9
- package/dist/UILintToolbar-MJH7RUZK.js +0 -9
- package/dist/chunk-2VRWAMW7.js +0 -927
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
"use client";
|
|
2
|
+
import {
|
|
3
|
+
BADGE_COLORS,
|
|
4
|
+
Badge
|
|
5
|
+
} from "./chunk-W42PI2OF.js";
|
|
2
6
|
import {
|
|
3
7
|
groupBySourceFile,
|
|
4
8
|
useUILintContext,
|
|
5
9
|
useUILintStore
|
|
6
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-BJD2V2LF.js";
|
|
7
11
|
|
|
8
12
|
// src/components/ui-lint/UILintToolbar.tsx
|
|
9
13
|
import { useState as useState2, useRef as useRef2, useEffect as useEffect2, useCallback as useCallback2 } from "react";
|
|
@@ -55,10 +59,6 @@ var STYLES = {
|
|
|
55
59
|
transition: "all 0.15s ease-out",
|
|
56
60
|
transitionFast: "all 0.1s ease-out"
|
|
57
61
|
};
|
|
58
|
-
function getStatusColor(issueCount) {
|
|
59
|
-
if (issueCount === 0) return STYLES.success;
|
|
60
|
-
return STYLES.warning;
|
|
61
|
-
}
|
|
62
62
|
|
|
63
63
|
// src/components/ui-lint/SettingsPopover.tsx
|
|
64
64
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -235,9 +235,6 @@ import { useState, useCallback, useMemo } from "react";
|
|
|
235
235
|
|
|
236
236
|
// src/components/ui-lint/toolbar-icons.tsx
|
|
237
237
|
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
238
|
-
function StopIcon() {
|
|
239
|
-
return /* @__PURE__ */ jsx2("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", children: /* @__PURE__ */ jsx2("rect", { x: "6", y: "6", width: "12", height: "12", rx: "1", fill: "currentColor" }) });
|
|
240
|
-
}
|
|
241
238
|
function ChevronIcon() {
|
|
242
239
|
return /* @__PURE__ */ jsx2("svg", { width: "10", height: "10", viewBox: "0 0 24 24", fill: "none", children: /* @__PURE__ */ jsx2(
|
|
243
240
|
"path",
|
|
@@ -252,7 +249,7 @@ function ChevronIcon() {
|
|
|
252
249
|
}
|
|
253
250
|
|
|
254
251
|
// src/components/ui-lint/ScanResultsPopover.tsx
|
|
255
|
-
import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
252
|
+
import { Fragment, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
256
253
|
function getDisambiguatedName(path, allPaths) {
|
|
257
254
|
const parts = path.split("/");
|
|
258
255
|
const fileName = parts[parts.length - 1] || path;
|
|
@@ -268,11 +265,12 @@ function getDisambiguatedName(path, allPaths) {
|
|
|
268
265
|
}
|
|
269
266
|
return fileName;
|
|
270
267
|
}
|
|
271
|
-
function ScanResultsPopover() {
|
|
272
|
-
const { autoScanState, liveScanEnabled
|
|
268
|
+
function ScanResultsPopover({ onClose }) {
|
|
269
|
+
const { autoScanState, liveScanEnabled } = useUILintContext();
|
|
273
270
|
const elementIssuesCache = useUILintStore(
|
|
274
271
|
(s) => s.elementIssuesCache
|
|
275
272
|
);
|
|
273
|
+
const fileIssuesCache = useUILintStore((s) => s.fileIssuesCache);
|
|
276
274
|
const setLocatorTarget = useUILintStore(
|
|
277
275
|
(s) => s.setLocatorTarget
|
|
278
276
|
);
|
|
@@ -286,6 +284,7 @@ function ScanResultsPopover() {
|
|
|
286
284
|
const allFilesWithIssues = useMemo(() => {
|
|
287
285
|
const sourceFiles = groupBySourceFile(autoScanState.elements);
|
|
288
286
|
const allPaths = sourceFiles.map((sf) => sf.path);
|
|
287
|
+
const filePathsSet = new Set(sourceFiles.map((sf) => sf.path));
|
|
289
288
|
const result = [];
|
|
290
289
|
for (const sf of sourceFiles) {
|
|
291
290
|
const elementsWithIssues = [];
|
|
@@ -301,26 +300,44 @@ function ScanResultsPopover() {
|
|
|
301
300
|
elementsWithIssues.push({ element: el, issueCount, ruleIds });
|
|
302
301
|
}
|
|
303
302
|
}
|
|
304
|
-
|
|
303
|
+
const fileLevelIssues = fileIssuesCache.get(sf.path) || [];
|
|
304
|
+
const elementIssueCount = elementsWithIssues.reduce(
|
|
305
|
+
(sum, e) => sum + e.issueCount,
|
|
306
|
+
0
|
|
307
|
+
);
|
|
308
|
+
const totalIssues2 = elementIssueCount + fileLevelIssues.length;
|
|
309
|
+
if (totalIssues2 > 0) {
|
|
305
310
|
elementsWithIssues.sort(
|
|
306
311
|
(a, b) => a.element.source.lineNumber - b.element.source.lineNumber
|
|
307
312
|
);
|
|
308
|
-
const totalIssues2 = elementsWithIssues.reduce(
|
|
309
|
-
(sum, e) => sum + e.issueCount,
|
|
310
|
-
0
|
|
311
|
-
);
|
|
312
313
|
result.push({
|
|
313
314
|
path: sf.path,
|
|
314
315
|
displayName: sf.displayName,
|
|
315
316
|
disambiguatedName: getDisambiguatedName(sf.path, allPaths),
|
|
316
317
|
issueCount: totalIssues2,
|
|
317
|
-
elementsWithIssues
|
|
318
|
+
elementsWithIssues,
|
|
319
|
+
fileLevelIssues
|
|
320
|
+
});
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
for (const [filePath, fileLevelIssues] of fileIssuesCache.entries()) {
|
|
324
|
+
if (!filePathsSet.has(filePath) && fileLevelIssues.length > 0) {
|
|
325
|
+
const parts = filePath.split("/");
|
|
326
|
+
const displayName = parts[parts.length - 1] || filePath;
|
|
327
|
+
const allPaths2 = Array.from(filePathsSet).concat([filePath]);
|
|
328
|
+
result.push({
|
|
329
|
+
path: filePath,
|
|
330
|
+
displayName,
|
|
331
|
+
disambiguatedName: getDisambiguatedName(filePath, allPaths2),
|
|
332
|
+
issueCount: fileLevelIssues.length,
|
|
333
|
+
elementsWithIssues: [],
|
|
334
|
+
fileLevelIssues
|
|
318
335
|
});
|
|
319
336
|
}
|
|
320
337
|
}
|
|
321
338
|
result.sort((a, b) => b.issueCount - a.issueCount);
|
|
322
339
|
return result;
|
|
323
|
-
}, [autoScanState.elements, elementIssuesCache]);
|
|
340
|
+
}, [autoScanState.elements, elementIssuesCache, fileIssuesCache]);
|
|
324
341
|
const filesWithIssues = useMemo(() => {
|
|
325
342
|
if (!searchQuery.trim()) {
|
|
326
343
|
return allFilesWithIssues;
|
|
@@ -403,15 +420,32 @@ function ScanResultsPopover() {
|
|
|
403
420
|
},
|
|
404
421
|
[setInspectedElement, setLocatorTarget]
|
|
405
422
|
);
|
|
423
|
+
const handleFileLevelIssueClick = useCallback(
|
|
424
|
+
(filePath, issue) => {
|
|
425
|
+
const dummyElement = document.createElement("div");
|
|
426
|
+
dummyElement.style.position = "fixed";
|
|
427
|
+
dummyElement.style.top = "-9999px";
|
|
428
|
+
dummyElement.style.left = "-9999px";
|
|
429
|
+
document.body.appendChild(dummyElement);
|
|
430
|
+
const source = {
|
|
431
|
+
fileName: filePath,
|
|
432
|
+
lineNumber: issue.line,
|
|
433
|
+
columnNumber: issue.column
|
|
434
|
+
};
|
|
435
|
+
setInspectedElement({
|
|
436
|
+
element: dummyElement,
|
|
437
|
+
source,
|
|
438
|
+
rect: new DOMRect(0, 0, 0, 0)
|
|
439
|
+
});
|
|
440
|
+
},
|
|
441
|
+
[setInspectedElement]
|
|
442
|
+
);
|
|
406
443
|
return /* @__PURE__ */ jsxs3(
|
|
407
444
|
"div",
|
|
408
445
|
{
|
|
409
446
|
"data-ui-lint": true,
|
|
410
447
|
style: {
|
|
411
|
-
position: "
|
|
412
|
-
bottom: "100%",
|
|
413
|
-
left: 0,
|
|
414
|
-
marginBottom: "8px",
|
|
448
|
+
position: "relative",
|
|
415
449
|
width: "320px",
|
|
416
450
|
maxHeight: "450px",
|
|
417
451
|
borderRadius: STYLES.popoverRadius,
|
|
@@ -454,25 +488,33 @@ function ScanResultsPopover() {
|
|
|
454
488
|
children: allFilesWithIssues.length === 0 ? "No issues found" : searchQuery ? `${filesWithIssues.length} of ${allFilesWithIssues.length} files` : `${filesWithIssues.length} ${filesWithIssues.length === 1 ? "file" : "files"} with ${totalAllIssues} ${totalAllIssues === 1 ? "issue" : "issues"}`
|
|
455
489
|
}
|
|
456
490
|
),
|
|
457
|
-
|
|
491
|
+
/* @__PURE__ */ jsx3(
|
|
458
492
|
"button",
|
|
459
493
|
{
|
|
460
|
-
onClick:
|
|
494
|
+
onClick: onClose,
|
|
461
495
|
style: {
|
|
462
496
|
display: "flex",
|
|
463
497
|
alignItems: "center",
|
|
464
498
|
justifyContent: "center",
|
|
465
|
-
width: "
|
|
466
|
-
height: "
|
|
499
|
+
width: "26px",
|
|
500
|
+
height: "26px",
|
|
467
501
|
borderRadius: "6px",
|
|
468
|
-
border:
|
|
502
|
+
border: "none",
|
|
469
503
|
backgroundColor: "transparent",
|
|
470
504
|
color: STYLES.textMuted,
|
|
471
505
|
cursor: "pointer",
|
|
472
|
-
transition:
|
|
506
|
+
transition: "all 0.15s"
|
|
507
|
+
},
|
|
508
|
+
onMouseEnter: (e) => {
|
|
509
|
+
e.currentTarget.style.backgroundColor = "rgba(55, 65, 81, 0.5)";
|
|
510
|
+
e.currentTarget.style.color = STYLES.text;
|
|
473
511
|
},
|
|
474
|
-
|
|
475
|
-
|
|
512
|
+
onMouseLeave: (e) => {
|
|
513
|
+
e.currentTarget.style.backgroundColor = "transparent";
|
|
514
|
+
e.currentTarget.style.color = STYLES.textMuted;
|
|
515
|
+
},
|
|
516
|
+
title: "Close",
|
|
517
|
+
children: /* @__PURE__ */ jsx3(CloseIcon, {})
|
|
476
518
|
}
|
|
477
519
|
)
|
|
478
520
|
]
|
|
@@ -612,7 +654,8 @@ function ScanResultsPopover() {
|
|
|
612
654
|
isExpanded: expandedFiles.has(file.path),
|
|
613
655
|
onToggle: () => toggleFile(file.path),
|
|
614
656
|
onElementHover: handleElementHover,
|
|
615
|
-
onElementClick: handleElementClick
|
|
657
|
+
onElementClick: handleElementClick,
|
|
658
|
+
onFileLevelIssueClick: handleFileLevelIssueClick
|
|
616
659
|
},
|
|
617
660
|
file.path
|
|
618
661
|
))
|
|
@@ -627,7 +670,8 @@ function FileRow({
|
|
|
627
670
|
isExpanded,
|
|
628
671
|
onToggle,
|
|
629
672
|
onElementHover,
|
|
630
|
-
onElementClick
|
|
673
|
+
onElementClick,
|
|
674
|
+
onFileLevelIssueClick
|
|
631
675
|
}) {
|
|
632
676
|
return /* @__PURE__ */ jsxs3("div", { children: [
|
|
633
677
|
/* @__PURE__ */ jsxs3(
|
|
@@ -685,29 +729,11 @@ function FileRow({
|
|
|
685
729
|
children: file.disambiguatedName
|
|
686
730
|
}
|
|
687
731
|
),
|
|
688
|
-
/* @__PURE__ */ jsx3(
|
|
689
|
-
"span",
|
|
690
|
-
{
|
|
691
|
-
style: {
|
|
692
|
-
display: "inline-flex",
|
|
693
|
-
alignItems: "center",
|
|
694
|
-
justifyContent: "center",
|
|
695
|
-
minWidth: "22px",
|
|
696
|
-
height: "18px",
|
|
697
|
-
padding: "0 6px",
|
|
698
|
-
borderRadius: "9px",
|
|
699
|
-
backgroundColor: getStatusColor(file.issueCount),
|
|
700
|
-
color: "#FFFFFF",
|
|
701
|
-
fontSize: "10px",
|
|
702
|
-
fontWeight: 700
|
|
703
|
-
},
|
|
704
|
-
children: file.issueCount
|
|
705
|
-
}
|
|
706
|
-
)
|
|
732
|
+
/* @__PURE__ */ jsx3(Badge, { count: file.issueCount, size: "medium" })
|
|
707
733
|
]
|
|
708
734
|
}
|
|
709
735
|
),
|
|
710
|
-
isExpanded && /* @__PURE__ */
|
|
736
|
+
isExpanded && /* @__PURE__ */ jsxs3(
|
|
711
737
|
"div",
|
|
712
738
|
{
|
|
713
739
|
style: {
|
|
@@ -715,15 +741,52 @@ function FileRow({
|
|
|
715
741
|
borderTop: `1px solid ${STYLES.border}`,
|
|
716
742
|
borderBottom: `1px solid ${STYLES.border}`
|
|
717
743
|
},
|
|
718
|
-
children:
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
744
|
+
children: [
|
|
745
|
+
file.fileLevelIssues.length > 0 && /* @__PURE__ */ jsxs3(Fragment, { children: [
|
|
746
|
+
/* @__PURE__ */ jsx3(
|
|
747
|
+
"div",
|
|
748
|
+
{
|
|
749
|
+
style: {
|
|
750
|
+
padding: "6px 12px 4px 34px",
|
|
751
|
+
fontSize: "10px",
|
|
752
|
+
fontWeight: 600,
|
|
753
|
+
color: STYLES.textMuted,
|
|
754
|
+
textTransform: "uppercase",
|
|
755
|
+
letterSpacing: "0.5px"
|
|
756
|
+
},
|
|
757
|
+
children: "File-level issues"
|
|
758
|
+
}
|
|
759
|
+
),
|
|
760
|
+
file.fileLevelIssues.map((issue, index) => /* @__PURE__ */ jsx3(
|
|
761
|
+
FileLevelIssueRow,
|
|
762
|
+
{
|
|
763
|
+
filePath: file.path,
|
|
764
|
+
issue,
|
|
765
|
+
onClick: () => onFileLevelIssueClick(file.path, issue)
|
|
766
|
+
},
|
|
767
|
+
`${issue.line}-${issue.column}-${index}`
|
|
768
|
+
)),
|
|
769
|
+
file.elementsWithIssues.length > 0 && /* @__PURE__ */ jsx3(
|
|
770
|
+
"div",
|
|
771
|
+
{
|
|
772
|
+
style: {
|
|
773
|
+
height: "1px",
|
|
774
|
+
backgroundColor: STYLES.border,
|
|
775
|
+
margin: "4px 12px"
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
)
|
|
779
|
+
] }),
|
|
780
|
+
file.elementsWithIssues.map((item) => /* @__PURE__ */ jsx3(
|
|
781
|
+
ElementRow,
|
|
782
|
+
{
|
|
783
|
+
item,
|
|
784
|
+
onHover: onElementHover,
|
|
785
|
+
onClick: onElementClick
|
|
786
|
+
},
|
|
787
|
+
item.element.id
|
|
788
|
+
))
|
|
789
|
+
]
|
|
727
790
|
}
|
|
728
791
|
)
|
|
729
792
|
] });
|
|
@@ -792,25 +855,76 @@ function ElementRow({ item, onHover, onClick }) {
|
|
|
792
855
|
]
|
|
793
856
|
}
|
|
794
857
|
),
|
|
795
|
-
/* @__PURE__ */ jsx3(
|
|
796
|
-
|
|
858
|
+
/* @__PURE__ */ jsx3(Badge, { count: issueCount, size: "small" })
|
|
859
|
+
]
|
|
860
|
+
}
|
|
861
|
+
);
|
|
862
|
+
}
|
|
863
|
+
function FileLevelIssueRow({
|
|
864
|
+
filePath,
|
|
865
|
+
issue,
|
|
866
|
+
onClick
|
|
867
|
+
}) {
|
|
868
|
+
const fileName = filePath.split("/").pop() || filePath;
|
|
869
|
+
return /* @__PURE__ */ jsxs3(
|
|
870
|
+
"div",
|
|
871
|
+
{
|
|
872
|
+
style: {
|
|
873
|
+
display: "flex",
|
|
874
|
+
alignItems: "center",
|
|
875
|
+
padding: "6px 12px 6px 34px",
|
|
876
|
+
cursor: "pointer",
|
|
877
|
+
transition: STYLES.transitionFast,
|
|
878
|
+
backgroundColor: "transparent"
|
|
879
|
+
},
|
|
880
|
+
onMouseEnter: (e) => {
|
|
881
|
+
e.currentTarget.style.backgroundColor = "rgba(59, 130, 246, 0.15)";
|
|
882
|
+
},
|
|
883
|
+
onMouseLeave: (e) => {
|
|
884
|
+
e.currentTarget.style.backgroundColor = "transparent";
|
|
885
|
+
},
|
|
886
|
+
onClick,
|
|
887
|
+
children: [
|
|
888
|
+
/* @__PURE__ */ jsxs3(
|
|
889
|
+
"div",
|
|
797
890
|
{
|
|
798
891
|
style: {
|
|
799
|
-
display: "
|
|
892
|
+
display: "flex",
|
|
800
893
|
alignItems: "center",
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
padding: "0 5px",
|
|
805
|
-
borderRadius: "8px",
|
|
806
|
-
backgroundColor: getStatusColor(issueCount),
|
|
807
|
-
color: "#FFFFFF",
|
|
808
|
-
fontSize: "9px",
|
|
809
|
-
fontWeight: 700
|
|
894
|
+
gap: "4px",
|
|
895
|
+
flex: 1,
|
|
896
|
+
marginRight: "12px"
|
|
810
897
|
},
|
|
811
|
-
children:
|
|
898
|
+
children: [
|
|
899
|
+
/* @__PURE__ */ jsx3(
|
|
900
|
+
"span",
|
|
901
|
+
{
|
|
902
|
+
style: {
|
|
903
|
+
fontSize: "11px",
|
|
904
|
+
fontFamily: STYLES.fontMono,
|
|
905
|
+
color: STYLES.textMuted
|
|
906
|
+
},
|
|
907
|
+
children: fileName
|
|
908
|
+
}
|
|
909
|
+
),
|
|
910
|
+
/* @__PURE__ */ jsxs3(
|
|
911
|
+
"span",
|
|
912
|
+
{
|
|
913
|
+
style: {
|
|
914
|
+
fontSize: "10px",
|
|
915
|
+
color: STYLES.textDim
|
|
916
|
+
},
|
|
917
|
+
children: [
|
|
918
|
+
":",
|
|
919
|
+
issue.line,
|
|
920
|
+
issue.column ? `:${issue.column}` : ""
|
|
921
|
+
]
|
|
922
|
+
}
|
|
923
|
+
)
|
|
924
|
+
]
|
|
812
925
|
}
|
|
813
|
-
)
|
|
926
|
+
),
|
|
927
|
+
/* @__PURE__ */ jsx3(Badge, { count: 1, size: "small" })
|
|
814
928
|
]
|
|
815
929
|
}
|
|
816
930
|
);
|
|
@@ -861,6 +975,18 @@ function ClearIcon() {
|
|
|
861
975
|
}
|
|
862
976
|
) });
|
|
863
977
|
}
|
|
978
|
+
function CloseIcon() {
|
|
979
|
+
return /* @__PURE__ */ jsx3("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", children: /* @__PURE__ */ jsx3(
|
|
980
|
+
"path",
|
|
981
|
+
{
|
|
982
|
+
d: "M18 6L6 18M6 6l12 12",
|
|
983
|
+
stroke: "currentColor",
|
|
984
|
+
strokeWidth: "2",
|
|
985
|
+
strokeLinecap: "round",
|
|
986
|
+
strokeLinejoin: "round"
|
|
987
|
+
}
|
|
988
|
+
) });
|
|
989
|
+
}
|
|
864
990
|
|
|
865
991
|
// src/components/ui-lint/ScanPanelStack.tsx
|
|
866
992
|
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
@@ -896,7 +1022,19 @@ function ScanPanelStack({ show, onClose }) {
|
|
|
896
1022
|
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
897
1023
|
}, [show, onClose]);
|
|
898
1024
|
if (!show) return null;
|
|
899
|
-
return /* @__PURE__ */ jsx4(
|
|
1025
|
+
return /* @__PURE__ */ jsx4(
|
|
1026
|
+
"div",
|
|
1027
|
+
{
|
|
1028
|
+
ref: containerRef,
|
|
1029
|
+
style: {
|
|
1030
|
+
position: "absolute",
|
|
1031
|
+
bottom: "100%",
|
|
1032
|
+
left: 0,
|
|
1033
|
+
marginBottom: "8px"
|
|
1034
|
+
},
|
|
1035
|
+
children: /* @__PURE__ */ jsx4(ScanResultsPopover, { onClose })
|
|
1036
|
+
}
|
|
1037
|
+
);
|
|
900
1038
|
}
|
|
901
1039
|
|
|
902
1040
|
// src/components/ui-lint/UILintToolbar.tsx
|
|
@@ -915,10 +1053,10 @@ var TOKENS = {
|
|
|
915
1053
|
textDisabled: "rgba(255, 255, 255, 0.25)",
|
|
916
1054
|
accent: "#63b3ed",
|
|
917
1055
|
// Calm blue
|
|
918
|
-
success:
|
|
919
|
-
// Soft green
|
|
920
|
-
warning:
|
|
921
|
-
// Warm orange
|
|
1056
|
+
success: BADGE_COLORS.success,
|
|
1057
|
+
// Soft green (shared with Badge)
|
|
1058
|
+
warning: BADGE_COLORS.warning,
|
|
1059
|
+
// Warm orange (shared with Badge)
|
|
922
1060
|
// Typography
|
|
923
1061
|
fontFamily: `-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif`,
|
|
924
1062
|
fontMono: `"SF Mono", Monaco, "Cascadia Code", monospace`,
|
|
@@ -1146,20 +1284,6 @@ var globalStyles = `
|
|
|
1146
1284
|
transform: translateY(0);
|
|
1147
1285
|
}
|
|
1148
1286
|
|
|
1149
|
-
.uilint-badge {
|
|
1150
|
-
display: inline-flex;
|
|
1151
|
-
align-items: center;
|
|
1152
|
-
justify-content: center;
|
|
1153
|
-
min-width: 20px;
|
|
1154
|
-
height: 20px;
|
|
1155
|
-
padding: 0 6px;
|
|
1156
|
-
border-radius: 10px;
|
|
1157
|
-
font-size: 11px;
|
|
1158
|
-
font-weight: 600;
|
|
1159
|
-
font-family: ${TOKENS.fontMono};
|
|
1160
|
-
letter-spacing: -0.02em;
|
|
1161
|
-
}
|
|
1162
|
-
|
|
1163
1287
|
.uilint-scanning-indicator {
|
|
1164
1288
|
position: relative;
|
|
1165
1289
|
overflow: hidden;
|
|
@@ -1188,6 +1312,50 @@ var globalStyles = `
|
|
|
1188
1312
|
.uilint-popover--closing {
|
|
1189
1313
|
animation: uilint-fade-out ${TOKENS.transitionBase} forwards;
|
|
1190
1314
|
}
|
|
1315
|
+
|
|
1316
|
+
/* Custom scrollbar styling for dark mode - scoped to uilint components */
|
|
1317
|
+
[data-ui-lint] *,
|
|
1318
|
+
[data-ui-lint] {
|
|
1319
|
+
/* Firefox */
|
|
1320
|
+
scrollbar-width: thin;
|
|
1321
|
+
scrollbar-color: rgba(255, 255, 255, 0.15) rgba(15, 15, 15, 0.3);
|
|
1322
|
+
}
|
|
1323
|
+
|
|
1324
|
+
/* WebKit browsers (Chrome, Safari, Edge) */
|
|
1325
|
+
[data-ui-lint] *::-webkit-scrollbar,
|
|
1326
|
+
[data-ui-lint]::-webkit-scrollbar {
|
|
1327
|
+
width: 8px;
|
|
1328
|
+
height: 8px;
|
|
1329
|
+
}
|
|
1330
|
+
|
|
1331
|
+
[data-ui-lint] *::-webkit-scrollbar-track,
|
|
1332
|
+
[data-ui-lint]::-webkit-scrollbar-track {
|
|
1333
|
+
background: rgba(15, 15, 15, 0.3);
|
|
1334
|
+
border-radius: 4px;
|
|
1335
|
+
}
|
|
1336
|
+
|
|
1337
|
+
[data-ui-lint] *::-webkit-scrollbar-thumb,
|
|
1338
|
+
[data-ui-lint]::-webkit-scrollbar-thumb {
|
|
1339
|
+
background: rgba(255, 255, 255, 0.15);
|
|
1340
|
+
border-radius: 4px;
|
|
1341
|
+
border: 1px solid rgba(15, 15, 15, 0.2);
|
|
1342
|
+
transition: background ${TOKENS.transitionFast};
|
|
1343
|
+
}
|
|
1344
|
+
|
|
1345
|
+
[data-ui-lint] *::-webkit-scrollbar-thumb:hover,
|
|
1346
|
+
[data-ui-lint]::-webkit-scrollbar-thumb:hover {
|
|
1347
|
+
background: rgba(255, 255, 255, 0.25);
|
|
1348
|
+
}
|
|
1349
|
+
|
|
1350
|
+
[data-ui-lint] *::-webkit-scrollbar-thumb:active,
|
|
1351
|
+
[data-ui-lint]::-webkit-scrollbar-thumb:active {
|
|
1352
|
+
background: rgba(255, 255, 255, 0.35);
|
|
1353
|
+
}
|
|
1354
|
+
|
|
1355
|
+
[data-ui-lint] *::-webkit-scrollbar-corner,
|
|
1356
|
+
[data-ui-lint]::-webkit-scrollbar-corner {
|
|
1357
|
+
background: rgba(15, 15, 15, 0.3);
|
|
1358
|
+
}
|
|
1191
1359
|
`;
|
|
1192
1360
|
function ToolbarButton({
|
|
1193
1361
|
onClick,
|
|
@@ -1341,17 +1509,7 @@ function ScanStatus({ status, issueCount, enabled }) {
|
|
|
1341
1509
|
children: /* @__PURE__ */ jsx5(Icons.AlertTriangle, {})
|
|
1342
1510
|
}
|
|
1343
1511
|
),
|
|
1344
|
-
/* @__PURE__ */ jsx5(
|
|
1345
|
-
"span",
|
|
1346
|
-
{
|
|
1347
|
-
className: "uilint-badge",
|
|
1348
|
-
style: {
|
|
1349
|
-
backgroundColor: `${TOKENS.warning}20`,
|
|
1350
|
-
color: TOKENS.warning
|
|
1351
|
-
},
|
|
1352
|
-
children: issueCount
|
|
1353
|
-
}
|
|
1354
|
-
)
|
|
1512
|
+
/* @__PURE__ */ jsx5(Badge, { count: issueCount })
|
|
1355
1513
|
]
|
|
1356
1514
|
}
|
|
1357
1515
|
);
|
|
@@ -1367,6 +1525,7 @@ function UILintToolbar() {
|
|
|
1367
1525
|
const elementIssuesCache = useUILintStore(
|
|
1368
1526
|
(s) => s.elementIssuesCache
|
|
1369
1527
|
);
|
|
1528
|
+
const fileIssuesCache = useUILintStore((s) => s.fileIssuesCache);
|
|
1370
1529
|
const [showSettings, setShowSettings] = useState2(false);
|
|
1371
1530
|
const [showResults, setShowResults] = useState2(false);
|
|
1372
1531
|
const [mounted, setMounted] = useState2(false);
|
|
@@ -1403,10 +1562,15 @@ function UILintToolbar() {
|
|
|
1403
1562
|
}, []);
|
|
1404
1563
|
const isScanning = autoScanState.status === "scanning";
|
|
1405
1564
|
const isComplete = autoScanState.status === "complete";
|
|
1406
|
-
let
|
|
1565
|
+
let elementIssues = 0;
|
|
1407
1566
|
elementIssuesCache.forEach((el) => {
|
|
1408
|
-
|
|
1567
|
+
elementIssues += el.issues.length;
|
|
1568
|
+
});
|
|
1569
|
+
let fileLevelIssues = 0;
|
|
1570
|
+
fileIssuesCache.forEach((issues) => {
|
|
1571
|
+
fileLevelIssues += issues.length;
|
|
1409
1572
|
});
|
|
1573
|
+
const totalIssues = elementIssues + fileLevelIssues;
|
|
1410
1574
|
const hasIssues = totalIssues > 0;
|
|
1411
1575
|
useEffect2(() => {
|
|
1412
1576
|
setMounted(true);
|
|
@@ -1433,11 +1597,6 @@ function UILintToolbar() {
|
|
|
1433
1597
|
document.removeEventListener("keydown", handleEscape);
|
|
1434
1598
|
};
|
|
1435
1599
|
}, [showSettings, showResults]);
|
|
1436
|
-
useEffect2(() => {
|
|
1437
|
-
if (hasIssues && liveScanEnabled && isComplete && !showSettings) {
|
|
1438
|
-
setShowResults(true);
|
|
1439
|
-
}
|
|
1440
|
-
}, [hasIssues, liveScanEnabled, isComplete, showSettings]);
|
|
1441
1600
|
const handleToggleClick = useCallback2(() => {
|
|
1442
1601
|
if (liveScanEnabled) {
|
|
1443
1602
|
disableLiveScan();
|
|
@@ -1486,7 +1645,7 @@ function UILintToolbar() {
|
|
|
1486
1645
|
},
|
|
1487
1646
|
children: [
|
|
1488
1647
|
/* @__PURE__ */ jsx5("style", { children: globalStyles }),
|
|
1489
|
-
/* @__PURE__ */
|
|
1648
|
+
/* @__PURE__ */ jsx5(
|
|
1490
1649
|
"div",
|
|
1491
1650
|
{
|
|
1492
1651
|
className: `uilint-hint ${liveScanEnabled ? "uilint-hint--visible" : ""}`,
|
|
@@ -1495,36 +1654,27 @@ function UILintToolbar() {
|
|
|
1495
1654
|
marginBottom: "10px",
|
|
1496
1655
|
fontSize: "11px",
|
|
1497
1656
|
color: TOKENS.textMuted,
|
|
1498
|
-
letterSpacing: "0.02em"
|
|
1499
|
-
// Subtle dark halo for readability on any background
|
|
1500
|
-
textShadow: `
|
|
1501
|
-
0 0 4px rgba(0, 0, 0, 0.8),
|
|
1502
|
-
0 0 8px rgba(0, 0, 0, 0.5),
|
|
1503
|
-
0 1px 2px rgba(0, 0, 0, 0.9)
|
|
1504
|
-
`
|
|
1657
|
+
letterSpacing: "0.02em"
|
|
1505
1658
|
},
|
|
1506
1659
|
"aria-hidden": !liveScanEnabled,
|
|
1507
|
-
children:
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
{
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
),
|
|
1526
|
-
/* @__PURE__ */ jsx5("span", { children: "+ Click to inspect element" })
|
|
1527
|
-
]
|
|
1660
|
+
children: /* @__PURE__ */ jsx5(
|
|
1661
|
+
"kbd",
|
|
1662
|
+
{
|
|
1663
|
+
style: {
|
|
1664
|
+
display: "inline-block",
|
|
1665
|
+
padding: "2px 5px",
|
|
1666
|
+
marginRight: "4px",
|
|
1667
|
+
borderRadius: "4px",
|
|
1668
|
+
backgroundColor: TOKENS.bgElevated,
|
|
1669
|
+
border: `1px solid ${TOKENS.border}`,
|
|
1670
|
+
fontSize: "10px",
|
|
1671
|
+
fontFamily: TOKENS.fontMono,
|
|
1672
|
+
color: TOKENS.textSecondary,
|
|
1673
|
+
boxShadow: `0 1px 3px rgba(0, 0, 0, 0.5)`
|
|
1674
|
+
},
|
|
1675
|
+
children: "\u2325 + Click to inspect element"
|
|
1676
|
+
}
|
|
1677
|
+
)
|
|
1528
1678
|
}
|
|
1529
1679
|
),
|
|
1530
1680
|
/* @__PURE__ */ jsxs4(
|