uilint-react 0.1.19 → 0.1.20

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.
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  buildEditorUrl,
4
4
  useUILintContext
5
- } from "./chunk-7WYVWDRU.js";
5
+ } from "./chunk-DAFFOBEU.js";
6
6
 
7
7
  // src/components/ui-lint/InspectionPanel.tsx
8
8
  import { useState, useEffect, useCallback } from "react";
@@ -11,7 +11,7 @@ import { createPortal } from "react-dom";
11
11
  // src/components/ui-lint/source-fetcher.ts
12
12
  var sourceCache = /* @__PURE__ */ new Map();
13
13
  var CACHE_TTL = 5 * 60 * 1e3;
14
- var API_ENDPOINT = "/api/dev/source";
14
+ var API_ENDPOINT = "/api/uilint/source";
15
15
  async function fetchSource(filePath) {
16
16
  const cached = sourceCache.get(filePath);
17
17
  if (cached && Date.now() - cached.fetchedAt < CACHE_TTL) {
@@ -82,7 +82,7 @@ async function prefetchSources(filePaths) {
82
82
  }
83
83
 
84
84
  // src/components/ui-lint/InspectionPanel.tsx
85
- import { jsx, jsxs } from "react/jsx-runtime";
85
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
86
86
  var STYLES = {
87
87
  bg: "rgba(17, 24, 39, 0.95)",
88
88
  bgSurface: "rgba(31, 41, 55, 0.9)",
@@ -92,23 +92,24 @@ var STYLES = {
92
92
  textDim: "#6B7280",
93
93
  accent: "#3B82F6",
94
94
  accentHover: "#2563EB",
95
+ success: "#10B981",
96
+ warning: "#F59E0B",
95
97
  shadow: "0 -8px 32px rgba(0, 0, 0, 0.4)",
96
98
  blur: "blur(16px)",
97
99
  font: 'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
98
100
  fontMono: 'ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace'
99
101
  };
100
- var PANEL_WIDTH = 400;
102
+ var PANEL_WIDTH = 420;
101
103
  function InspectionPanel() {
102
- const { selectedElement, setSelectedElement, sourceFiles } = useUILintContext();
104
+ const { inspectedElement, setInspectedElement } = useUILintContext();
103
105
  const [mounted, setMounted] = useState(false);
104
- const [activeTab, setActiveTab] = useState("info");
106
+ const [activeTab, setActiveTab] = useState(
107
+ "info"
108
+ );
105
109
  useEffect(() => {
106
110
  setMounted(true);
107
111
  }, []);
108
- const sourceFile = selectedElement ? sourceFiles.find(
109
- (f) => f.elements.some((e) => e.id === selectedElement.id)
110
- ) ?? null : null;
111
- if (!mounted) return null;
112
+ if (!mounted || !inspectedElement) return null;
112
113
  const content = /* @__PURE__ */ jsxs(
113
114
  "div",
114
115
  {
@@ -118,16 +119,15 @@ function InspectionPanel() {
118
119
  top: 0,
119
120
  right: 0,
120
121
  bottom: 0,
121
- width: selectedElement ? PANEL_WIDTH : 0,
122
+ width: PANEL_WIDTH,
122
123
  backgroundColor: STYLES.bg,
123
124
  backdropFilter: STYLES.blur,
124
125
  WebkitBackdropFilter: STYLES.blur,
125
126
  borderLeft: `1px solid ${STYLES.border}`,
126
- boxShadow: selectedElement ? STYLES.shadow : "none",
127
+ boxShadow: STYLES.shadow,
127
128
  fontFamily: STYLES.font,
128
129
  color: STYLES.text,
129
130
  overflow: "hidden",
130
- transition: "width 0.2s ease-out",
131
131
  zIndex: 99998
132
132
  },
133
133
  children: [
@@ -136,8 +136,12 @@ function InspectionPanel() {
136
136
  from { transform: translateX(100%); }
137
137
  to { transform: translateX(0); }
138
138
  }
139
+ @keyframes uilint-spin {
140
+ from { transform: rotate(0deg); }
141
+ to { transform: rotate(360deg); }
142
+ }
139
143
  ` }),
140
- selectedElement && /* @__PURE__ */ jsxs(
144
+ /* @__PURE__ */ jsxs(
141
145
  "div",
142
146
  {
143
147
  style: {
@@ -150,9 +154,8 @@ function InspectionPanel() {
150
154
  /* @__PURE__ */ jsx(
151
155
  PanelHeader,
152
156
  {
153
- element: selectedElement,
154
- sourceFile,
155
- onClose: () => setSelectedElement(null)
157
+ element: inspectedElement,
158
+ onClose: () => setInspectedElement(null)
156
159
  }
157
160
  ),
158
161
  /* @__PURE__ */ jsxs(
@@ -178,11 +181,24 @@ function InspectionPanel() {
178
181
  active: activeTab === "source",
179
182
  onClick: () => setActiveTab("source")
180
183
  }
184
+ ),
185
+ /* @__PURE__ */ jsx(
186
+ TabButton,
187
+ {
188
+ label: "Scan",
189
+ active: activeTab === "scan",
190
+ onClick: () => setActiveTab("scan"),
191
+ accent: true
192
+ }
181
193
  )
182
194
  ]
183
195
  }
184
196
  ),
185
- /* @__PURE__ */ jsx("div", { style: { flex: 1, overflow: "auto" }, children: activeTab === "info" ? /* @__PURE__ */ jsx(InfoTab, { element: selectedElement, sourceFile }) : /* @__PURE__ */ jsx(SourceTab, { element: selectedElement }) })
197
+ /* @__PURE__ */ jsxs("div", { style: { flex: 1, overflow: "auto" }, children: [
198
+ activeTab === "info" && /* @__PURE__ */ jsx(InfoTab, { element: inspectedElement }),
199
+ activeTab === "source" && /* @__PURE__ */ jsx(SourceTab, { element: inspectedElement }),
200
+ activeTab === "scan" && /* @__PURE__ */ jsx(ScanTab, { element: inspectedElement })
201
+ ] })
186
202
  ]
187
203
  }
188
204
  )
@@ -193,11 +209,10 @@ function InspectionPanel() {
193
209
  }
194
210
  function PanelHeader({
195
211
  element,
196
- sourceFile,
197
212
  onClose
198
213
  }) {
199
- const componentName = element.componentStack[0]?.name || element.tagName.toUpperCase();
200
- const handleOpenInEditor = useCallback(() => {
214
+ const componentName = element.componentStack[0]?.name || element.element.tagName.toLowerCase();
215
+ const handleOpenInCursor = useCallback(() => {
201
216
  if (element.source) {
202
217
  const url = buildEditorUrl(element.source, "cursor");
203
218
  window.open(url, "_blank");
@@ -215,32 +230,19 @@ function PanelHeader({
215
230
  backgroundColor: STYLES.bgSurface
216
231
  },
217
232
  children: [
218
- /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: "10px" }, children: [
219
- sourceFile && /* @__PURE__ */ jsx(
220
- "div",
221
- {
222
- style: {
223
- width: "12px",
224
- height: "12px",
225
- borderRadius: "50%",
226
- backgroundColor: sourceFile.color
227
- }
228
- }
229
- ),
230
- /* @__PURE__ */ jsxs("div", { children: [
231
- /* @__PURE__ */ jsx("div", { style: { fontSize: "14px", fontWeight: 600 }, children: componentName }),
232
- /* @__PURE__ */ jsxs("div", { style: { fontSize: "11px", color: STYLES.textMuted }, children: [
233
- "<",
234
- element.tagName,
235
- ">"
236
- ] })
233
+ /* @__PURE__ */ jsxs("div", { children: [
234
+ /* @__PURE__ */ jsx("div", { style: { fontSize: "14px", fontWeight: 600 }, children: componentName }),
235
+ /* @__PURE__ */ jsxs("div", { style: { fontSize: "11px", color: STYLES.textMuted }, children: [
236
+ "<",
237
+ element.element.tagName.toLowerCase(),
238
+ ">"
237
239
  ] })
238
240
  ] }),
239
241
  /* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: "8px" }, children: [
240
242
  element.source && /* @__PURE__ */ jsxs(
241
243
  "button",
242
244
  {
243
- onClick: handleOpenInEditor,
245
+ onClick: handleOpenInCursor,
244
246
  style: {
245
247
  display: "flex",
246
248
  alignItems: "center",
@@ -261,9 +263,10 @@ function PanelHeader({
261
263
  onMouseLeave: (e) => {
262
264
  e.currentTarget.style.backgroundColor = STYLES.accent;
263
265
  },
266
+ title: "Open in Cursor",
264
267
  children: [
265
- /* @__PURE__ */ jsx(OpenIcon, {}),
266
- "Open"
268
+ /* @__PURE__ */ jsx(CursorIcon, {}),
269
+ "Open in Cursor"
267
270
  ]
268
271
  }
269
272
  ),
@@ -303,7 +306,8 @@ function PanelHeader({
303
306
  function TabButton({
304
307
  label,
305
308
  active,
306
- onClick
309
+ onClick,
310
+ accent
307
311
  }) {
308
312
  return /* @__PURE__ */ jsx(
309
313
  "button",
@@ -314,11 +318,11 @@ function TabButton({
314
318
  padding: "10px 16px",
315
319
  border: "none",
316
320
  backgroundColor: "transparent",
317
- color: active ? STYLES.accent : STYLES.textMuted,
321
+ color: active ? accent ? STYLES.success : STYLES.accent : STYLES.textMuted,
318
322
  fontSize: "12px",
319
323
  fontWeight: 500,
320
324
  cursor: "pointer",
321
- borderBottom: active ? `2px solid ${STYLES.accent}` : "2px solid transparent",
325
+ borderBottom: active ? `2px solid ${accent ? STYLES.success : STYLES.accent}` : "2px solid transparent",
322
326
  marginBottom: "-1px",
323
327
  transition: "all 0.15s"
324
328
  },
@@ -326,61 +330,44 @@ function TabButton({
326
330
  }
327
331
  );
328
332
  }
329
- function InfoTab({
330
- element,
331
- sourceFile
332
- }) {
333
+ function InfoTab({ element }) {
333
334
  return /* @__PURE__ */ jsxs("div", { style: { padding: "16px" }, children: [
334
335
  /* @__PURE__ */ jsxs(Section, { title: "Element", children: [
335
- /* @__PURE__ */ jsx(InfoRow, { label: "Tag", value: `<${element.tagName}>` }),
336
- element.className && /* @__PURE__ */ jsx(InfoRow, { label: "Classes", value: element.className, mono: true }),
337
- element.source && /* @__PURE__ */ jsx(
336
+ /* @__PURE__ */ jsx(
338
337
  InfoRow,
339
338
  {
340
- label: "Location",
341
- value: `Line ${element.source.lineNumber}${element.source.columnNumber ? `, Col ${element.source.columnNumber}` : ""}`
339
+ label: "Tag",
340
+ value: `<${element.element.tagName.toLowerCase()}>`
342
341
  }
343
- )
344
- ] }),
345
- sourceFile && /* @__PURE__ */ jsxs(Section, { title: "Source File", children: [
346
- /* @__PURE__ */ jsxs(
347
- "div",
342
+ ),
343
+ element.element.className && /* @__PURE__ */ jsx(
344
+ InfoRow,
348
345
  {
349
- style: {
350
- display: "flex",
351
- alignItems: "center",
352
- gap: "8px",
353
- marginBottom: "8px"
354
- },
355
- children: [
356
- /* @__PURE__ */ jsx(
357
- "div",
358
- {
359
- style: {
360
- width: "10px",
361
- height: "10px",
362
- borderRadius: "50%",
363
- backgroundColor: sourceFile.color
364
- }
365
- }
366
- ),
367
- /* @__PURE__ */ jsx("span", { style: { fontSize: "12px", fontWeight: 500 }, children: sourceFile.displayName })
368
- ]
346
+ label: "Classes",
347
+ value: typeof element.element.className === "string" ? element.element.className : "",
348
+ mono: true
369
349
  }
370
350
  ),
371
- /* @__PURE__ */ jsx(
372
- "div",
351
+ element.source && /* @__PURE__ */ jsx(
352
+ InfoRow,
373
353
  {
374
- style: {
375
- fontSize: "11px",
376
- color: STYLES.textDim,
377
- fontFamily: STYLES.fontMono,
378
- wordBreak: "break-all"
379
- },
380
- children: sourceFile.path
354
+ label: "Location",
355
+ value: `Line ${element.source.lineNumber}${element.source.columnNumber ? `, Col ${element.source.columnNumber}` : ""}`
381
356
  }
382
357
  )
383
358
  ] }),
359
+ element.source && /* @__PURE__ */ jsx(Section, { title: "Source File", children: /* @__PURE__ */ jsx(
360
+ "div",
361
+ {
362
+ style: {
363
+ fontSize: "11px",
364
+ color: STYLES.textDim,
365
+ fontFamily: STYLES.fontMono,
366
+ wordBreak: "break-all"
367
+ },
368
+ children: element.source.fileName
369
+ }
370
+ ) }),
384
371
  element.componentStack.length > 0 && /* @__PURE__ */ jsx(Section, { title: "Component Stack", children: /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "4px" }, children: [
385
372
  element.componentStack.slice(0, 10).map((comp, index) => /* @__PURE__ */ jsx(
386
373
  ComponentStackItem,
@@ -570,6 +557,299 @@ function SourceTab({ element }) {
570
557
  )
571
558
  ] });
572
559
  }
560
+ function ScanTab({ element }) {
561
+ const [scanning, setScanning] = useState(false);
562
+ const [error, setError] = useState(null);
563
+ const [fixPrompt, setFixPrompt] = useState(null);
564
+ const [copied, setCopied] = useState(false);
565
+ const componentName = element.componentStack[0]?.name || element.element.tagName.toLowerCase();
566
+ const componentLine = element.source?.lineNumber;
567
+ const handleScan = useCallback(async () => {
568
+ if (!element.source) {
569
+ setError("No source information available");
570
+ return;
571
+ }
572
+ setScanning(true);
573
+ setError(null);
574
+ setFixPrompt(null);
575
+ try {
576
+ const sourceResponse = await fetch(
577
+ `/api/uilint/source?path=${encodeURIComponent(element.source.fileName)}`
578
+ );
579
+ if (!sourceResponse.ok) {
580
+ throw new Error("Failed to fetch source code");
581
+ }
582
+ const sourceData = await sourceResponse.json();
583
+ const sourceCode = sourceData.content;
584
+ const relativePath = sourceData.relativePath || element.source.fileName;
585
+ const analyzeResponse = await fetch("/api/uilint/analyze", {
586
+ method: "POST",
587
+ headers: { "Content-Type": "application/json" },
588
+ body: JSON.stringify({
589
+ sourceCode,
590
+ filePath: relativePath,
591
+ componentName,
592
+ componentLine
593
+ })
594
+ });
595
+ if (!analyzeResponse.ok) {
596
+ throw new Error("Failed to analyze source code");
597
+ }
598
+ const result = await analyzeResponse.json();
599
+ const issues = result.issues || [];
600
+ if (issues.length === 0) {
601
+ setFixPrompt(
602
+ `No style issues found in the \`${componentName}\` component in \`${relativePath}\`. The component appears to follow the styleguide.`
603
+ );
604
+ } else {
605
+ const issueList = issues.map((issue) => {
606
+ const lineInfo = issue.line ? `Line ${issue.line}: ` : "";
607
+ return `- ${lineInfo}${issue.message}`;
608
+ }).join("\n");
609
+ setFixPrompt(
610
+ `Fix the following style issues in the \`${componentName}\` component in \`${relativePath}\`:
611
+
612
+ Issues found:
613
+ ${issueList}
614
+
615
+ Please update this component to match our styleguide.`
616
+ );
617
+ }
618
+ } catch (err) {
619
+ setError(
620
+ err instanceof Error ? err.message : "An error occurred during scanning"
621
+ );
622
+ } finally {
623
+ setScanning(false);
624
+ }
625
+ }, [element.source, componentName, componentLine]);
626
+ const handleCopy = useCallback(async () => {
627
+ if (!fixPrompt) return;
628
+ try {
629
+ await navigator.clipboard.writeText(fixPrompt);
630
+ setCopied(true);
631
+ setTimeout(() => setCopied(false), 2e3);
632
+ } catch {
633
+ setError("Failed to copy to clipboard");
634
+ }
635
+ }, [fixPrompt]);
636
+ return /* @__PURE__ */ jsxs("div", { style: { padding: "16px" }, children: [
637
+ !fixPrompt && !scanning && /* @__PURE__ */ jsxs("div", { style: { textAlign: "center", padding: "24px 0" }, children: [
638
+ /* @__PURE__ */ jsxs(
639
+ "button",
640
+ {
641
+ onClick: handleScan,
642
+ disabled: !element.source,
643
+ style: {
644
+ display: "inline-flex",
645
+ alignItems: "center",
646
+ gap: "8px",
647
+ padding: "12px 24px",
648
+ borderRadius: "8px",
649
+ border: "none",
650
+ backgroundColor: element.source ? STYLES.success : STYLES.textDim,
651
+ color: "#FFFFFF",
652
+ fontSize: "14px",
653
+ fontWeight: 600,
654
+ cursor: element.source ? "pointer" : "not-allowed",
655
+ transition: "all 0.15s"
656
+ },
657
+ onMouseEnter: (e) => {
658
+ if (element.source) {
659
+ e.currentTarget.style.backgroundColor = "#059669";
660
+ }
661
+ },
662
+ onMouseLeave: (e) => {
663
+ if (element.source) {
664
+ e.currentTarget.style.backgroundColor = STYLES.success;
665
+ }
666
+ },
667
+ children: [
668
+ /* @__PURE__ */ jsx(ScanIcon, {}),
669
+ "Scan with LLM"
670
+ ]
671
+ }
672
+ ),
673
+ /* @__PURE__ */ jsx(
674
+ "div",
675
+ {
676
+ style: {
677
+ marginTop: "12px",
678
+ fontSize: "12px",
679
+ color: STYLES.textMuted
680
+ },
681
+ children: "Analyze this component for style issues"
682
+ }
683
+ ),
684
+ !element.source && /* @__PURE__ */ jsx(
685
+ "div",
686
+ {
687
+ style: {
688
+ marginTop: "8px",
689
+ fontSize: "11px",
690
+ color: STYLES.warning
691
+ },
692
+ children: "No source information available"
693
+ }
694
+ )
695
+ ] }),
696
+ scanning && /* @__PURE__ */ jsxs(
697
+ "div",
698
+ {
699
+ style: {
700
+ display: "flex",
701
+ flexDirection: "column",
702
+ alignItems: "center",
703
+ justifyContent: "center",
704
+ padding: "48px 24px",
705
+ gap: "16px"
706
+ },
707
+ children: [
708
+ /* @__PURE__ */ jsx(
709
+ "div",
710
+ {
711
+ style: {
712
+ width: "32px",
713
+ height: "32px",
714
+ border: `3px solid ${STYLES.border}`,
715
+ borderTopColor: STYLES.success,
716
+ borderRadius: "50%",
717
+ animation: "uilint-spin 1s linear infinite"
718
+ }
719
+ }
720
+ ),
721
+ /* @__PURE__ */ jsx("div", { style: { color: STYLES.textMuted, fontSize: "13px" }, children: "Analyzing source code..." })
722
+ ]
723
+ }
724
+ ),
725
+ error && /* @__PURE__ */ jsx(
726
+ "div",
727
+ {
728
+ style: {
729
+ padding: "16px",
730
+ backgroundColor: "rgba(239, 68, 68, 0.1)",
731
+ border: "1px solid rgba(239, 68, 68, 0.3)",
732
+ borderRadius: "8px",
733
+ color: "#EF4444",
734
+ fontSize: "13px"
735
+ },
736
+ children: error
737
+ }
738
+ ),
739
+ fixPrompt && /* @__PURE__ */ jsxs("div", { children: [
740
+ /* @__PURE__ */ jsxs(
741
+ "div",
742
+ {
743
+ style: {
744
+ display: "flex",
745
+ alignItems: "center",
746
+ justifyContent: "space-between",
747
+ marginBottom: "12px"
748
+ },
749
+ children: [
750
+ /* @__PURE__ */ jsx(
751
+ "div",
752
+ {
753
+ style: {
754
+ fontSize: "12px",
755
+ fontWeight: 600,
756
+ color: STYLES.text
757
+ },
758
+ children: "Fix Prompt"
759
+ }
760
+ ),
761
+ /* @__PURE__ */ jsx(
762
+ "button",
763
+ {
764
+ onClick: handleCopy,
765
+ style: {
766
+ display: "flex",
767
+ alignItems: "center",
768
+ gap: "6px",
769
+ padding: "6px 12px",
770
+ borderRadius: "6px",
771
+ border: "none",
772
+ backgroundColor: copied ? STYLES.success : STYLES.accent,
773
+ color: "#FFFFFF",
774
+ fontSize: "11px",
775
+ fontWeight: 500,
776
+ cursor: "pointer",
777
+ transition: "all 0.15s"
778
+ },
779
+ children: copied ? /* @__PURE__ */ jsxs(Fragment, { children: [
780
+ /* @__PURE__ */ jsx(CheckIcon, {}),
781
+ "Copied!"
782
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
783
+ /* @__PURE__ */ jsx(CopyIcon, {}),
784
+ "Copy to Clipboard"
785
+ ] })
786
+ }
787
+ )
788
+ ]
789
+ }
790
+ ),
791
+ /* @__PURE__ */ jsx(
792
+ "div",
793
+ {
794
+ style: {
795
+ padding: "12px",
796
+ backgroundColor: STYLES.bgSurface,
797
+ border: `1px solid ${STYLES.border}`,
798
+ borderRadius: "8px",
799
+ fontFamily: STYLES.fontMono,
800
+ fontSize: "12px",
801
+ lineHeight: 1.6,
802
+ whiteSpace: "pre-wrap",
803
+ color: STYLES.text,
804
+ maxHeight: "300px",
805
+ overflow: "auto"
806
+ },
807
+ children: fixPrompt
808
+ }
809
+ ),
810
+ /* @__PURE__ */ jsx(
811
+ "div",
812
+ {
813
+ style: {
814
+ marginTop: "12px",
815
+ fontSize: "11px",
816
+ color: STYLES.textMuted,
817
+ textAlign: "center"
818
+ },
819
+ children: "Paste this prompt into Cursor to fix the issues"
820
+ }
821
+ ),
822
+ /* @__PURE__ */ jsx("div", { style: { textAlign: "center", marginTop: "16px" }, children: /* @__PURE__ */ jsx(
823
+ "button",
824
+ {
825
+ onClick: () => {
826
+ setFixPrompt(null);
827
+ handleScan();
828
+ },
829
+ style: {
830
+ padding: "8px 16px",
831
+ borderRadius: "6px",
832
+ border: `1px solid ${STYLES.border}`,
833
+ backgroundColor: "transparent",
834
+ color: STYLES.textMuted,
835
+ fontSize: "12px",
836
+ cursor: "pointer",
837
+ transition: "all 0.15s"
838
+ },
839
+ onMouseEnter: (e) => {
840
+ e.currentTarget.style.borderColor = STYLES.accent;
841
+ e.currentTarget.style.color = STYLES.text;
842
+ },
843
+ onMouseLeave: (e) => {
844
+ e.currentTarget.style.borderColor = STYLES.border;
845
+ e.currentTarget.style.color = STYLES.textMuted;
846
+ },
847
+ children: "Scan Again"
848
+ }
849
+ ) })
850
+ ] })
851
+ ] });
852
+ }
573
853
  function Section({
574
854
  title,
575
855
  children
@@ -690,7 +970,7 @@ function ComponentStackItem({
690
970
  }
691
971
  );
692
972
  }
693
- function OpenIcon() {
973
+ function CursorIcon() {
694
974
  return /* @__PURE__ */ jsx("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", children: /* @__PURE__ */ jsx(
695
975
  "path",
696
976
  {
@@ -714,6 +994,53 @@ function CloseIcon() {
714
994
  }
715
995
  ) });
716
996
  }
997
+ function ScanIcon() {
998
+ return /* @__PURE__ */ jsx("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", children: /* @__PURE__ */ jsx(
999
+ "path",
1000
+ {
1001
+ 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",
1002
+ stroke: "currentColor",
1003
+ strokeWidth: "2",
1004
+ strokeLinecap: "round"
1005
+ }
1006
+ ) });
1007
+ }
1008
+ function CopyIcon() {
1009
+ return /* @__PURE__ */ jsxs("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", children: [
1010
+ /* @__PURE__ */ jsx(
1011
+ "rect",
1012
+ {
1013
+ x: "9",
1014
+ y: "9",
1015
+ width: "13",
1016
+ height: "13",
1017
+ rx: "2",
1018
+ stroke: "currentColor",
1019
+ strokeWidth: "2"
1020
+ }
1021
+ ),
1022
+ /* @__PURE__ */ jsx(
1023
+ "path",
1024
+ {
1025
+ d: "M5 15H4a2 2 0 01-2-2V4a2 2 0 012-2h9a2 2 0 012 2v1",
1026
+ stroke: "currentColor",
1027
+ strokeWidth: "2"
1028
+ }
1029
+ )
1030
+ ] });
1031
+ }
1032
+ function CheckIcon() {
1033
+ return /* @__PURE__ */ jsx("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", children: /* @__PURE__ */ jsx(
1034
+ "path",
1035
+ {
1036
+ d: "M20 6L9 17l-5-5",
1037
+ stroke: "currentColor",
1038
+ strokeWidth: "2",
1039
+ strokeLinecap: "round",
1040
+ strokeLinejoin: "round"
1041
+ }
1042
+ ) });
1043
+ }
717
1044
 
718
1045
  export {
719
1046
  fetchSource,