uilint-react 0.1.32 → 0.1.34

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.
@@ -1,9 +1,8 @@
1
1
  "use client";
2
2
  import {
3
3
  buildEditorUrl,
4
- useUILintContext,
5
- useUILintStore
6
- } from "./chunk-Y44J7QO6.js";
4
+ useUILintContext
5
+ } from "./chunk-MO4NS6EG.js";
7
6
 
8
7
  // src/components/ui-lint/InspectionPanel.tsx
9
8
  import { useState, useEffect, useCallback, useMemo } from "react";
@@ -83,7 +82,7 @@ async function prefetchSources(filePaths) {
83
82
  }
84
83
 
85
84
  // src/components/ui-lint/InspectionPanel.tsx
86
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
85
+ import { jsx, jsxs } from "react/jsx-runtime";
87
86
  var STYLES = {
88
87
  bg: "rgba(17, 24, 39, 0.95)",
89
88
  bgSurface: "rgba(31, 41, 55, 0.9)",
@@ -556,27 +555,6 @@ function SourceTab({ element }) {
556
555
  }
557
556
  function ScanSection({ element }) {
558
557
  const { elementIssuesCache, autoScanState } = useUILintContext();
559
- const [copied, setCopied] = useState(false);
560
- const manualKey = useMemo(() => {
561
- const dataLoc = element.element.getAttribute("data-loc");
562
- if (dataLoc) return `dataloc:${dataLoc}`;
563
- if (element.source) {
564
- return `src:${element.source.fileName}:${element.source.lineNumber}:${element.source.columnNumber ?? 0}`;
565
- }
566
- return `fallback:${element.element.tagName.toLowerCase()}:${Math.round(
567
- element.rect.left
568
- )}:${Math.round(element.rect.top)}`;
569
- }, [element.element, element.source, element.rect]);
570
- const manualScan = useUILintStore(
571
- (s) => s.manualScanCache.get(manualKey)
572
- );
573
- const upsertManualScan = useUILintStore(
574
- (s) => s.upsertManualScan
575
- );
576
- const clearManualScan = useUILintStore((s) => s.clearManualScan);
577
- const includeChildren = manualScan?.includeChildren ?? false;
578
- const componentName = element.componentStack[0]?.name || element.element.tagName.toLowerCase();
579
- const componentLine = element.source?.lineNumber;
580
558
  const cachedIssue = useMemo(() => {
581
559
  if (element.scannedElementId) {
582
560
  const cached = elementIssuesCache.get(element.scannedElementId);
@@ -599,199 +577,14 @@ function ScanSection({ element }) {
599
577
  elementIssuesCache,
600
578
  autoScanState.elements
601
579
  ]);
602
- const generateFixPrompt = useCallback(
603
- (issues, relativePath) => {
604
- if (issues.length === 0) {
605
- return `No style issues found in the \`${componentName}\` component in \`${relativePath}\`. The component appears to follow the styleguide.`;
606
- }
607
- const issueList = issues.map((issue) => {
608
- const lineInfo = issue.line ? `Line ${issue.line}: ` : "";
609
- return `- ${lineInfo}${issue.message}`;
610
- }).join("\n");
611
- return `Fix the following style issues in the \`${componentName}\` component in \`${relativePath}\`:
612
-
613
- Issues found:
614
- ${issueList}
615
-
616
- Please update this component to match our styleguide.`;
617
- },
618
- [componentName]
619
- );
620
- const cachedFixPrompt = useMemo(() => {
621
- if (!cachedIssue || cachedIssue.status !== "complete") return null;
622
- const relativePath = element.source?.fileName || "unknown";
623
- const allIssues = [
624
- ...cachedIssue.issues,
625
- ...(cachedIssue.eslintIssues || []).map((e) => ({
626
- line: e.line,
627
- message: `[${e.ruleId || "eslint"}] ${e.message}`
628
- }))
629
- ];
630
- return generateFixPrompt(allIssues, relativePath);
631
- }, [cachedIssue, element.source, generateFixPrompt]);
632
580
  const eslintIssues = useMemo(() => {
633
- return cachedIssue?.eslintIssues || [];
581
+ return cachedIssue?.issues || [];
634
582
  }, [cachedIssue]);
635
- const handleScan = useCallback(async () => {
636
- if (!element.source) {
637
- upsertManualScan(manualKey, {
638
- status: "error",
639
- error: "No source information available"
640
- });
641
- return;
642
- }
643
- const MAX_DATALOCS = 80;
644
- const selectedDataLoc = element.element.getAttribute("data-loc");
645
- let dataLocList = [];
646
- if (includeChildren) {
647
- const nodes = [
648
- element.element,
649
- ...Array.from(element.element.querySelectorAll("[data-loc]"))
650
- ];
651
- for (const n of nodes) {
652
- const v = n.getAttribute("data-loc");
653
- if (v) dataLocList.push(v);
654
- }
655
- } else if (selectedDataLoc) {
656
- dataLocList = [selectedDataLoc];
657
- }
658
- dataLocList = Array.from(new Set(dataLocList)).slice(0, MAX_DATALOCS);
659
- upsertManualScan(manualKey, {
660
- status: "scanning",
661
- error: void 0,
662
- fixPrompt: void 0,
663
- issues: [],
664
- progressLine: "Preparing analysis\u2026"
665
- });
666
- try {
667
- const sourceResponse = await fetch(
668
- `/api/.uilint/source?path=${encodeURIComponent(
669
- element.source.fileName
670
- )}`
671
- );
672
- if (!sourceResponse.ok) {
673
- throw new Error("Failed to fetch source code");
674
- }
675
- const sourceData = await sourceResponse.json();
676
- const sourceCode = sourceData.content;
677
- const relativePath = sourceData.relativePath || element.source.fileName;
678
- const analyzeResponse = await fetch("/api/.uilint/analyze", {
679
- method: "POST",
680
- headers: { "Content-Type": "application/json" },
681
- body: JSON.stringify({
682
- sourceCode,
683
- filePath: relativePath,
684
- componentName,
685
- componentLine,
686
- includeChildren,
687
- dataLocs: dataLocList.length > 0 ? dataLocList : void 0,
688
- stream: true
689
- })
690
- });
691
- if (!analyzeResponse.ok) {
692
- throw new Error("Failed to analyze source code");
693
- }
694
- const contentType = analyzeResponse.headers.get("content-type") || "";
695
- if (!contentType.includes("text/event-stream") || !analyzeResponse.body) {
696
- const result = await analyzeResponse.json();
697
- const issues = result.issues || [];
698
- upsertManualScan(manualKey, {
699
- status: "complete",
700
- issues,
701
- fixPrompt: generateFixPrompt(issues, relativePath),
702
- progressLine: void 0
703
- });
704
- return;
705
- }
706
- const reader = analyzeResponse.body.getReader();
707
- const decoder = new TextDecoder();
708
- let buffer = "";
709
- while (true) {
710
- const { done, value } = await reader.read();
711
- if (done) break;
712
- buffer += decoder.decode(value, { stream: true });
713
- const parts = buffer.split("\n\n");
714
- buffer = parts.pop() || "";
715
- for (const part of parts) {
716
- const lines = part.split("\n");
717
- let eventName = "message";
718
- let dataStr = "";
719
- for (const line of lines) {
720
- if (line.startsWith("event:")) eventName = line.slice(6).trim();
721
- if (line.startsWith("data:")) dataStr += line.slice(5).trim();
722
- }
723
- if (!dataStr) continue;
724
- try {
725
- const data = JSON.parse(dataStr);
726
- if (eventName === "progress") {
727
- upsertManualScan(manualKey, {
728
- status: "scanning",
729
- progressLine: data.latestLine || data.phase || "Running analysis\u2026"
730
- });
731
- } else if (eventName === "done") {
732
- const issues = data.issues || [];
733
- upsertManualScan(manualKey, {
734
- status: "complete",
735
- issues,
736
- fixPrompt: generateFixPrompt(issues, relativePath),
737
- progressLine: void 0
738
- });
739
- } else if (eventName === "error") {
740
- upsertManualScan(manualKey, {
741
- status: "error",
742
- error: data.error || "Analysis failed",
743
- progressLine: void 0
744
- });
745
- }
746
- } catch {
747
- }
748
- }
749
- }
750
- } catch (err) {
751
- upsertManualScan(manualKey, {
752
- status: "error",
753
- error: err instanceof Error ? err.message : "An error occurred during scanning",
754
- progressLine: void 0
755
- });
756
- }
757
- }, [
758
- element.source,
759
- element.element,
760
- element.rect,
761
- componentName,
762
- componentLine,
763
- generateFixPrompt,
764
- manualKey,
765
- upsertManualScan,
766
- includeChildren
767
- ]);
768
- const handleCopy = useCallback(
769
- async (text) => {
770
- try {
771
- await navigator.clipboard.writeText(text);
772
- setCopied(true);
773
- setTimeout(() => setCopied(false), 2e3);
774
- } catch {
775
- upsertManualScan(manualKey, {
776
- status: "error",
777
- error: "Failed to copy to clipboard"
778
- });
779
- }
780
- },
781
- [manualKey, upsertManualScan]
782
- );
783
- const manualStatus = manualScan?.status ?? "idle";
784
- const showCachedScanning = cachedIssue?.status === "scanning" && manualStatus === "idle";
785
- const showCachedPending = cachedIssue?.status === "pending" && manualStatus === "idle";
786
- const showCachedError = cachedIssue?.status === "error" && manualStatus === "idle";
787
- const showCachedResult = cachedFixPrompt && manualStatus === "idle";
788
- const showScanButton = !cachedIssue && manualStatus === "idle";
789
- const showManualResult = manualStatus === "complete" && manualScan?.fixPrompt;
790
- const scanning = manualStatus === "scanning";
791
- const error = manualScan?.status === "error" ? manualScan.error : null;
792
- const fixPrompt = manualScan?.fixPrompt ?? null;
793
- const progressLine = manualScan?.progressLine ?? null;
794
- const scopeLabel = includeChildren ? "Element + children" : "Element only";
583
+ const showCachedScanning = cachedIssue?.status === "scanning";
584
+ const showCachedPending = cachedIssue?.status === "pending";
585
+ const showCachedError = cachedIssue?.status === "error";
586
+ const showCachedResult = cachedIssue?.status === "complete";
587
+ const showNoScan = !cachedIssue;
795
588
  return /* @__PURE__ */ jsx(
796
589
  "div",
797
590
  {
@@ -829,385 +622,36 @@ Please update this component to match our styleguide.`;
829
622
  ]
830
623
  }
831
624
  ),
832
- showCachedPending && /* @__PURE__ */ jsxs("div", { style: { textAlign: "center", padding: "16px 0" }, children: [
833
- /* @__PURE__ */ jsxs(
834
- "div",
835
- {
836
- style: {
837
- display: "inline-flex",
838
- alignItems: "center",
839
- gap: "8px",
840
- padding: "10px 20px",
841
- borderRadius: "8px",
842
- backgroundColor: STYLES.bg,
843
- color: STYLES.textMuted,
844
- fontSize: "12px",
845
- marginBottom: "12px"
846
- },
847
- children: [
848
- /* @__PURE__ */ jsx(
849
- "div",
850
- {
851
- style: {
852
- width: "8px",
853
- height: "8px",
854
- borderRadius: "50%",
855
- backgroundColor: "rgba(156, 163, 175, 0.5)"
856
- }
857
- }
858
- ),
859
- "Waiting in scan queue..."
860
- ]
861
- }
862
- ),
863
- /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(
864
- "button",
865
- {
866
- onClick: handleScan,
867
- disabled: !element.source,
868
- style: {
869
- padding: "8px 16px",
870
- borderRadius: "6px",
871
- border: `1px solid ${STYLES.border}`,
872
- backgroundColor: "transparent",
873
- color: element.source ? STYLES.text : STYLES.textDim,
874
- fontSize: "12px",
875
- fontWeight: 500,
876
- cursor: element.source ? "pointer" : "not-allowed",
877
- transition: "all 0.15s"
878
- },
879
- onMouseEnter: (e) => {
880
- if (element.source) {
881
- e.currentTarget.style.borderColor = STYLES.accent;
882
- e.currentTarget.style.backgroundColor = "rgba(59, 130, 246, 0.1)";
883
- }
884
- },
885
- onMouseLeave: (e) => {
886
- e.currentTarget.style.borderColor = STYLES.border;
887
- e.currentTarget.style.backgroundColor = "transparent";
888
- },
889
- children: "Scan Now"
890
- }
891
- ) })
892
- ] }),
893
- showCachedError && /* @__PURE__ */ jsxs("div", { children: [
894
- /* @__PURE__ */ jsx(
895
- "div",
896
- {
897
- style: {
898
- padding: "12px",
899
- backgroundColor: "rgba(239, 68, 68, 0.1)",
900
- border: "1px solid rgba(239, 68, 68, 0.3)",
901
- borderRadius: "8px",
902
- color: "#EF4444",
903
- fontSize: "12px",
904
- marginBottom: "12px"
905
- },
906
- children: "Auto-scan failed for this element"
907
- }
908
- ),
909
- /* @__PURE__ */ jsx("div", { style: { textAlign: "center" }, children: /* @__PURE__ */ jsxs(
910
- "button",
911
- {
912
- onClick: handleScan,
913
- disabled: !element.source,
914
- style: {
915
- display: "inline-flex",
916
- alignItems: "center",
917
- gap: "8px",
918
- padding: "10px 20px",
919
- borderRadius: "8px",
920
- border: "none",
921
- backgroundColor: element.source ? STYLES.success : STYLES.textDim,
922
- color: "#FFFFFF",
923
- fontSize: "13px",
924
- fontWeight: 600,
925
- cursor: element.source ? "pointer" : "not-allowed",
926
- transition: "background-color 0.15s"
927
- },
928
- onMouseEnter: (e) => {
929
- if (element.source) {
930
- e.currentTarget.style.backgroundColor = "#059669";
931
- }
932
- },
933
- onMouseLeave: (e) => {
934
- if (element.source) {
935
- e.currentTarget.style.backgroundColor = STYLES.success;
936
- }
937
- },
938
- children: [
939
- /* @__PURE__ */ jsx(ScanIcon, {}),
940
- "Retry Scan"
941
- ]
942
- }
943
- ) })
944
- ] }),
945
- showCachedResult && /* @__PURE__ */ jsxs("div", { children: [
946
- /* @__PURE__ */ jsxs(
947
- "div",
948
- {
949
- style: {
950
- display: "flex",
951
- alignItems: "center",
952
- gap: "8px",
953
- marginBottom: "12px",
954
- padding: "8px 12px",
955
- backgroundColor: "rgba(16, 185, 129, 0.1)",
956
- borderRadius: "6px",
957
- fontSize: "11px",
958
- color: STYLES.success
959
- },
960
- children: [
961
- /* @__PURE__ */ jsx(CheckIconSmall, {}),
962
- "Scan complete"
963
- ]
964
- }
965
- ),
966
- eslintIssues.length > 0 && /* @__PURE__ */ jsx(ESLintIssuesSection, { issues: eslintIssues }),
967
- /* @__PURE__ */ jsxs(
968
- "div",
969
- {
970
- style: {
971
- display: "flex",
972
- alignItems: "center",
973
- justifyContent: "space-between",
974
- marginBottom: "10px"
975
- },
976
- children: [
977
- /* @__PURE__ */ jsx(
978
- "div",
979
- {
980
- style: {
981
- fontSize: "12px",
982
- fontWeight: 600,
983
- color: STYLES.text
984
- },
985
- children: "Fix Prompt"
986
- }
987
- ),
988
- /* @__PURE__ */ jsx(
989
- "button",
990
- {
991
- onClick: () => handleCopy(cachedFixPrompt),
992
- style: {
993
- display: "flex",
994
- alignItems: "center",
995
- gap: "6px",
996
- padding: "6px 12px",
997
- borderRadius: "6px",
998
- border: "none",
999
- backgroundColor: copied ? STYLES.success : STYLES.accent,
1000
- color: "#FFFFFF",
1001
- fontSize: "11px",
1002
- fontWeight: 500,
1003
- cursor: "pointer",
1004
- transition: "all 0.15s"
1005
- },
1006
- children: copied ? /* @__PURE__ */ jsxs(Fragment, { children: [
1007
- /* @__PURE__ */ jsx(CheckIcon, {}),
1008
- "Copied!"
1009
- ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
1010
- /* @__PURE__ */ jsx(CopyIcon, {}),
1011
- "Copy"
1012
- ] })
1013
- }
1014
- )
1015
- ]
1016
- }
1017
- ),
1018
- /* @__PURE__ */ jsx(
1019
- "div",
1020
- {
1021
- style: {
1022
- padding: "12px",
1023
- backgroundColor: STYLES.bg,
1024
- border: `1px solid ${STYLES.border}`,
1025
- borderRadius: "8px",
1026
- fontFamily: STYLES.fontMono,
1027
- fontSize: "11px",
1028
- lineHeight: 1.6,
1029
- whiteSpace: "pre-wrap",
1030
- color: STYLES.text,
1031
- maxHeight: "200px",
1032
- overflow: "auto"
1033
- },
1034
- children: cachedFixPrompt
1035
- }
1036
- ),
1037
- /* @__PURE__ */ jsx("div", { style: { textAlign: "center", marginTop: "12px" }, children: /* @__PURE__ */ jsx(
1038
- "button",
1039
- {
1040
- onClick: () => clearManualScan(manualKey),
1041
- style: {
1042
- padding: "6px 12px",
1043
- borderRadius: "6px",
1044
- border: `1px solid ${STYLES.border}`,
1045
- backgroundColor: "transparent",
1046
- color: STYLES.textMuted,
1047
- fontSize: "11px",
1048
- cursor: "pointer",
1049
- transition: "all 0.15s"
1050
- },
1051
- onMouseEnter: (e) => {
1052
- e.currentTarget.style.borderColor = STYLES.accent;
1053
- e.currentTarget.style.color = STYLES.text;
1054
- },
1055
- onMouseLeave: (e) => {
1056
- e.currentTarget.style.borderColor = STYLES.border;
1057
- e.currentTarget.style.color = STYLES.textMuted;
1058
- },
1059
- children: "Clear Analysis"
1060
- }
1061
- ) })
1062
- ] }),
1063
- showScanButton && /* @__PURE__ */ jsxs("div", { style: { textAlign: "center", padding: "16px 0" }, children: [
1064
- /* @__PURE__ */ jsxs("div", { style: { marginBottom: "10px" }, children: [
1065
- /* @__PURE__ */ jsxs(
1066
- "label",
1067
- {
1068
- style: {
1069
- display: "inline-flex",
1070
- alignItems: "center",
1071
- gap: "8px",
1072
- fontSize: "12px",
1073
- color: STYLES.textMuted,
1074
- cursor: "pointer",
1075
- userSelect: "none"
1076
- },
1077
- children: [
1078
- /* @__PURE__ */ jsx(
1079
- "input",
1080
- {
1081
- type: "checkbox",
1082
- checked: includeChildren,
1083
- onChange: (e) => upsertManualScan(manualKey, {
1084
- includeChildren: e.currentTarget.checked
1085
- })
1086
- }
1087
- ),
1088
- "Include children"
1089
- ]
1090
- }
1091
- ),
1092
- /* @__PURE__ */ jsxs(
1093
- "div",
1094
- {
1095
- style: {
1096
- marginTop: "6px",
1097
- fontSize: "11px",
1098
- color: STYLES.textDim
1099
- },
1100
- children: [
1101
- "Scope: ",
1102
- scopeLabel
1103
- ]
1104
- }
1105
- )
1106
- ] }),
1107
- /* @__PURE__ */ jsxs(
1108
- "button",
1109
- {
1110
- onClick: handleScan,
1111
- disabled: !element.source,
1112
- style: {
1113
- display: "inline-flex",
1114
- alignItems: "center",
1115
- gap: "8px",
1116
- padding: "12px 24px",
1117
- borderRadius: "8px",
1118
- border: "none",
1119
- backgroundColor: element.source ? STYLES.success : STYLES.textDim,
1120
- color: "#FFFFFF",
1121
- fontSize: "14px",
1122
- fontWeight: 600,
1123
- cursor: element.source ? "pointer" : "not-allowed",
1124
- transition: "all 0.15s"
1125
- },
1126
- onMouseEnter: (e) => {
1127
- if (element.source) {
1128
- e.currentTarget.style.backgroundColor = "#059669";
1129
- }
1130
- },
1131
- onMouseLeave: (e) => {
1132
- if (element.source) {
1133
- e.currentTarget.style.backgroundColor = STYLES.success;
1134
- }
1135
- },
1136
- children: [
1137
- /* @__PURE__ */ jsx(ScanIcon, {}),
1138
- "Scan for Issues"
1139
- ]
1140
- }
1141
- ),
1142
- /* @__PURE__ */ jsx(
1143
- "div",
1144
- {
1145
- style: {
1146
- marginTop: "10px",
1147
- fontSize: "12px",
1148
- color: STYLES.textMuted
1149
- },
1150
- children: "Analyze this component for style issues"
1151
- }
1152
- ),
1153
- !element.source && /* @__PURE__ */ jsx(
1154
- "div",
1155
- {
1156
- style: {
1157
- marginTop: "8px",
1158
- fontSize: "11px",
1159
- color: STYLES.warning
1160
- },
1161
- children: "No source information available"
1162
- }
1163
- )
1164
- ] }),
1165
- scanning && /* @__PURE__ */ jsxs(
625
+ showCachedPending && /* @__PURE__ */ jsx("div", { style: { textAlign: "center", padding: "16px 0" }, children: /* @__PURE__ */ jsxs(
1166
626
  "div",
1167
627
  {
1168
628
  style: {
1169
- display: "flex",
1170
- flexDirection: "column",
629
+ display: "inline-flex",
1171
630
  alignItems: "center",
1172
- justifyContent: "center",
1173
- padding: "32px 24px",
1174
- gap: "12px"
631
+ gap: "8px",
632
+ padding: "10px 20px",
633
+ borderRadius: "8px",
634
+ backgroundColor: STYLES.bg,
635
+ color: STYLES.textMuted,
636
+ fontSize: "12px"
1175
637
  },
1176
638
  children: [
1177
639
  /* @__PURE__ */ jsx(
1178
640
  "div",
1179
641
  {
1180
642
  style: {
1181
- width: "32px",
1182
- height: "32px",
1183
- border: `3px solid ${STYLES.border}`,
1184
- borderTopColor: STYLES.success,
643
+ width: "8px",
644
+ height: "8px",
1185
645
  borderRadius: "50%",
1186
- animation: "uilint-spin 1s linear infinite"
646
+ backgroundColor: "rgba(156, 163, 175, 0.5)"
1187
647
  }
1188
648
  }
1189
649
  ),
1190
- /* @__PURE__ */ jsx("div", { style: { color: STYLES.textMuted, fontSize: "13px" }, children: "Analyzing source code..." }),
1191
- progressLine && /* @__PURE__ */ jsx(
1192
- "div",
1193
- {
1194
- style: {
1195
- color: STYLES.textDim,
1196
- fontSize: "11px",
1197
- fontFamily: STYLES.fontMono,
1198
- maxWidth: "320px",
1199
- whiteSpace: "nowrap",
1200
- overflow: "hidden",
1201
- textOverflow: "ellipsis"
1202
- },
1203
- title: progressLine,
1204
- children: progressLine
1205
- }
1206
- )
650
+ "Waiting in scan queue..."
1207
651
  ]
1208
652
  }
1209
- ),
1210
- error && /* @__PURE__ */ jsx(
653
+ ) }),
654
+ showCachedError && /* @__PURE__ */ jsx(
1211
655
  "div",
1212
656
  {
1213
657
  style: {
@@ -1216,112 +660,58 @@ Please update this component to match our styleguide.`;
1216
660
  border: "1px solid rgba(239, 68, 68, 0.3)",
1217
661
  borderRadius: "8px",
1218
662
  color: "#EF4444",
1219
- fontSize: "12px",
1220
- marginTop: "12px"
663
+ fontSize: "12px"
1221
664
  },
1222
- children: error
665
+ children: "Auto-scan failed for this element"
1223
666
  }
1224
667
  ),
1225
- showManualResult && /* @__PURE__ */ jsxs("div", { children: [
668
+ showCachedResult && /* @__PURE__ */ jsxs("div", { children: [
1226
669
  /* @__PURE__ */ jsxs(
1227
670
  "div",
1228
671
  {
1229
672
  style: {
1230
673
  display: "flex",
1231
674
  alignItems: "center",
1232
- justifyContent: "space-between",
1233
- marginBottom: "10px"
675
+ gap: "8px",
676
+ marginBottom: "12px",
677
+ padding: "8px 12px",
678
+ backgroundColor: "rgba(16, 185, 129, 0.1)",
679
+ borderRadius: "6px",
680
+ fontSize: "11px",
681
+ color: STYLES.success
1234
682
  },
1235
683
  children: [
1236
- /* @__PURE__ */ jsx(
1237
- "div",
1238
- {
1239
- style: {
1240
- fontSize: "12px",
1241
- fontWeight: 600,
1242
- color: STYLES.text
1243
- },
1244
- children: "Fix Prompt"
1245
- }
1246
- ),
1247
- /* @__PURE__ */ jsx(
1248
- "button",
1249
- {
1250
- onClick: () => {
1251
- if (!fixPrompt) return;
1252
- handleCopy(fixPrompt);
1253
- },
1254
- style: {
1255
- display: "flex",
1256
- alignItems: "center",
1257
- gap: "6px",
1258
- padding: "6px 12px",
1259
- borderRadius: "6px",
1260
- border: "none",
1261
- backgroundColor: copied ? STYLES.success : STYLES.accent,
1262
- color: "#FFFFFF",
1263
- fontSize: "11px",
1264
- fontWeight: 500,
1265
- cursor: "pointer",
1266
- transition: "all 0.15s"
1267
- },
1268
- children: copied ? /* @__PURE__ */ jsxs(Fragment, { children: [
1269
- /* @__PURE__ */ jsx(CheckIcon, {}),
1270
- "Copied!"
1271
- ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
1272
- /* @__PURE__ */ jsx(CopyIcon, {}),
1273
- "Copy"
1274
- ] })
1275
- }
1276
- )
684
+ /* @__PURE__ */ jsx(CheckIconSmall, {}),
685
+ "Scan complete"
1277
686
  ]
1278
687
  }
1279
688
  ),
1280
- /* @__PURE__ */ jsx(
689
+ eslintIssues.length > 0 && /* @__PURE__ */ jsx(ESLintIssuesSection, { issues: eslintIssues }),
690
+ eslintIssues.length === 0 && /* @__PURE__ */ jsx(
1281
691
  "div",
1282
692
  {
1283
693
  style: {
1284
- padding: "12px",
1285
- backgroundColor: STYLES.bg,
1286
- border: `1px solid ${STYLES.border}`,
1287
- borderRadius: "8px",
1288
- fontFamily: STYLES.fontMono,
1289
- fontSize: "11px",
1290
- lineHeight: 1.6,
1291
- whiteSpace: "pre-wrap",
1292
- color: STYLES.text,
1293
- maxHeight: "200px",
1294
- overflow: "auto"
1295
- },
1296
- children: fixPrompt
1297
- }
1298
- ),
1299
- /* @__PURE__ */ jsx("div", { style: { textAlign: "center", marginTop: "12px" }, children: /* @__PURE__ */ jsx(
1300
- "button",
1301
- {
1302
- onClick: () => clearManualScan(manualKey),
1303
- style: {
1304
- padding: "6px 12px",
1305
- borderRadius: "6px",
1306
- border: `1px solid ${STYLES.border}`,
1307
- backgroundColor: "transparent",
694
+ padding: "16px",
695
+ textAlign: "center",
1308
696
  color: STYLES.textMuted,
1309
- fontSize: "11px",
1310
- cursor: "pointer",
1311
- transition: "all 0.15s"
1312
- },
1313
- onMouseEnter: (e) => {
1314
- e.currentTarget.style.borderColor = STYLES.accent;
1315
- e.currentTarget.style.color = STYLES.text;
697
+ fontSize: "12px"
1316
698
  },
1317
- onMouseLeave: (e) => {
1318
- e.currentTarget.style.borderColor = STYLES.border;
1319
- e.currentTarget.style.color = STYLES.textMuted;
1320
- },
1321
- children: "Clear Analysis"
699
+ children: "No issues found"
1322
700
  }
1323
- ) })
1324
- ] })
701
+ )
702
+ ] }),
703
+ showNoScan && /* @__PURE__ */ jsx(
704
+ "div",
705
+ {
706
+ style: {
707
+ padding: "16px",
708
+ textAlign: "center",
709
+ color: STYLES.textMuted,
710
+ fontSize: "12px"
711
+ },
712
+ children: "Run auto-scan to analyze this element"
713
+ }
714
+ )
1325
715
  ] })
1326
716
  }
1327
717
  );
@@ -1597,53 +987,6 @@ function CloseIcon() {
1597
987
  }
1598
988
  ) });
1599
989
  }
1600
- function ScanIcon() {
1601
- return /* @__PURE__ */ jsx("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", children: /* @__PURE__ */ jsx(
1602
- "path",
1603
- {
1604
- d: "M12 2v4M12 18v4M4.93 4.93l2.83 2.83M16.24 16.24l2.83 2.83M2 12h4M18 12h4M4.93 19.07l2.83-2.83M16.24 7.76l2.83-2.83",
1605
- stroke: "currentColor",
1606
- strokeWidth: "2",
1607
- strokeLinecap: "round"
1608
- }
1609
- ) });
1610
- }
1611
- function CopyIcon() {
1612
- return /* @__PURE__ */ jsxs("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", children: [
1613
- /* @__PURE__ */ jsx(
1614
- "rect",
1615
- {
1616
- x: "9",
1617
- y: "9",
1618
- width: "13",
1619
- height: "13",
1620
- rx: "2",
1621
- stroke: "currentColor",
1622
- strokeWidth: "2"
1623
- }
1624
- ),
1625
- /* @__PURE__ */ jsx(
1626
- "path",
1627
- {
1628
- d: "M5 15H4a2 2 0 01-2-2V4a2 2 0 012-2h9a2 2 0 012 2v1",
1629
- stroke: "currentColor",
1630
- strokeWidth: "2"
1631
- }
1632
- )
1633
- ] });
1634
- }
1635
- function CheckIcon() {
1636
- return /* @__PURE__ */ jsx("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", children: /* @__PURE__ */ jsx(
1637
- "path",
1638
- {
1639
- d: "M20 6L9 17l-5-5",
1640
- stroke: "currentColor",
1641
- strokeWidth: "2",
1642
- strokeLinecap: "round",
1643
- strokeLinejoin: "round"
1644
- }
1645
- ) });
1646
- }
1647
990
  function ESLintIcon() {
1648
991
  return /* @__PURE__ */ jsx("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", children: /* @__PURE__ */ jsx(
1649
992
  "path",