uilint-react 0.1.35 → 0.1.38

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,695 +0,0 @@
1
- "use client";
2
- import {
3
- useUILintContext,
4
- useUILintStore
5
- } from "./chunk-I4JDR36K.js";
6
-
7
- // src/components/ui-lint/UILintToolbar.tsx
8
- import { useState, useRef, useEffect } from "react";
9
- import { createPortal } from "react-dom";
10
- import { jsx, jsxs } from "react/jsx-runtime";
11
- var STYLES = {
12
- bg: "rgba(17, 24, 39, 0.9)",
13
- bgHover: "rgba(31, 41, 55, 0.95)",
14
- border: "rgba(75, 85, 99, 0.5)",
15
- text: "#F9FAFB",
16
- textMuted: "#9CA3AF",
17
- accent: "#3B82F6",
18
- accentHover: "#2563EB",
19
- shadow: "0 8px 32px rgba(0, 0, 0, 0.4)",
20
- blur: "blur(12px)",
21
- font: 'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
22
- fontMono: 'ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace'
23
- };
24
- function UILintToolbar() {
25
- const { settings, updateSettings, inspectedElement } = useUILintContext();
26
- const [showSettings, setShowSettings] = useState(false);
27
- const [mounted, setMounted] = useState(false);
28
- const settingsRef = useRef(null);
29
- useEffect(() => {
30
- setMounted(true);
31
- }, []);
32
- useEffect(() => {
33
- const handleClickOutside = (e) => {
34
- if (settingsRef.current && !settingsRef.current.contains(e.target)) {
35
- setShowSettings(false);
36
- }
37
- };
38
- if (showSettings) {
39
- document.addEventListener("mousedown", handleClickOutside);
40
- return () => document.removeEventListener("mousedown", handleClickOutside);
41
- }
42
- }, [showSettings]);
43
- if (!mounted) return null;
44
- if (inspectedElement) return null;
45
- const content = /* @__PURE__ */ jsxs(
46
- "div",
47
- {
48
- "data-ui-lint": true,
49
- style: {
50
- position: "fixed",
51
- top: "24px",
52
- right: "24px",
53
- zIndex: 99999,
54
- fontFamily: STYLES.font
55
- },
56
- children: [
57
- /* @__PURE__ */ jsx("style", { children: `
58
- @keyframes uilint-fade-in {
59
- from { opacity: 0; transform: scale(0.95); }
60
- to { opacity: 1; transform: scale(1); }
61
- }
62
- ` }),
63
- /* @__PURE__ */ jsxs("div", { style: { position: "relative" }, ref: settingsRef, children: [
64
- /* @__PURE__ */ jsx(
65
- "button",
66
- {
67
- onClick: () => setShowSettings(!showSettings),
68
- style: {
69
- display: "flex",
70
- alignItems: "center",
71
- justifyContent: "center",
72
- width: "48px",
73
- height: "48px",
74
- borderRadius: "50%",
75
- border: `1px solid ${STYLES.border}`,
76
- backgroundColor: showSettings ? STYLES.bgHover : STYLES.bg,
77
- backdropFilter: STYLES.blur,
78
- WebkitBackdropFilter: STYLES.blur,
79
- boxShadow: STYLES.shadow,
80
- cursor: "pointer",
81
- transition: "all 0.2s ease-out",
82
- color: showSettings ? STYLES.text : STYLES.textMuted,
83
- fontSize: "20px"
84
- },
85
- onMouseEnter: (e) => {
86
- e.currentTarget.style.transform = "scale(1.05)";
87
- e.currentTarget.style.boxShadow = "0 12px 40px rgba(0, 0, 0, 0.5)";
88
- },
89
- onMouseLeave: (e) => {
90
- e.currentTarget.style.transform = "scale(1)";
91
- e.currentTarget.style.boxShadow = STYLES.shadow;
92
- },
93
- title: "UILint Settings (Alt+Click any element to inspect)",
94
- children: /* @__PURE__ */ jsx(UILintIcon, { active: showSettings })
95
- }
96
- ),
97
- showSettings && /* @__PURE__ */ jsx(SettingsPopover, { settings, onUpdate: updateSettings }),
98
- /* @__PURE__ */ jsxs(
99
- "div",
100
- {
101
- style: {
102
- position: "absolute",
103
- left: "100%",
104
- top: "50%",
105
- transform: "translateY(-50%)",
106
- marginLeft: "12px",
107
- padding: "8px 12px",
108
- borderRadius: "8px",
109
- backgroundColor: STYLES.bg,
110
- border: `1px solid ${STYLES.border}`,
111
- backdropFilter: STYLES.blur,
112
- WebkitBackdropFilter: STYLES.blur,
113
- boxShadow: STYLES.shadow,
114
- fontSize: "12px",
115
- color: STYLES.textMuted,
116
- whiteSpace: "nowrap",
117
- opacity: 0,
118
- transition: "opacity 0.2s",
119
- pointerEvents: "none"
120
- },
121
- className: "uilint-hint",
122
- children: [
123
- /* @__PURE__ */ jsx("span", { style: { color: STYLES.text }, children: "Alt+Click" }),
124
- " any element to inspect"
125
- ]
126
- }
127
- )
128
- ] })
129
- ]
130
- }
131
- );
132
- return createPortal(content, document.body);
133
- }
134
- function SettingsPopover({
135
- settings,
136
- onUpdate
137
- }) {
138
- const {
139
- autoScanState,
140
- startAutoScan,
141
- pauseAutoScan,
142
- resumeAutoScan,
143
- stopAutoScan
144
- } = useUILintContext();
145
- const wsConnected = useUILintStore((s) => s.wsConnected);
146
- const wsUrl = useUILintStore((s) => s.wsUrl);
147
- const wsLastActivity = useUILintStore((s) => s.wsLastActivity);
148
- const wsRecentResults = useUILintStore((s) => s.wsRecentResults);
149
- const connectWebSocket = useUILintStore(
150
- (s) => s.connectWebSocket
151
- );
152
- const disconnectWebSocket = useUILintStore(
153
- (s) => s.disconnectWebSocket
154
- );
155
- const isScanning = autoScanState.status === "scanning";
156
- const isPaused = autoScanState.status === "paused";
157
- const isComplete = autoScanState.status === "complete";
158
- const isActive = isScanning || isPaused || isComplete;
159
- return /* @__PURE__ */ jsxs(
160
- "div",
161
- {
162
- style: {
163
- position: "absolute",
164
- top: "100%",
165
- right: 0,
166
- marginTop: "8px",
167
- width: "300px",
168
- padding: "16px",
169
- borderRadius: "12px",
170
- border: `1px solid ${STYLES.border}`,
171
- backgroundColor: STYLES.bg,
172
- backdropFilter: STYLES.blur,
173
- WebkitBackdropFilter: STYLES.blur,
174
- boxShadow: STYLES.shadow,
175
- animation: "uilint-fade-in 0.15s ease-out"
176
- },
177
- children: [
178
- /* @__PURE__ */ jsx(
179
- "div",
180
- {
181
- style: {
182
- fontSize: "13px",
183
- fontWeight: 600,
184
- color: STYLES.text,
185
- marginBottom: "12px"
186
- },
187
- children: "UILint Settings"
188
- }
189
- ),
190
- /* @__PURE__ */ jsxs(
191
- "div",
192
- {
193
- style: {
194
- padding: "10px 12px",
195
- borderRadius: "10px",
196
- border: `1px solid ${STYLES.border}`,
197
- backgroundColor: "rgba(31, 41, 55, 0.65)",
198
- marginBottom: "12px"
199
- },
200
- children: [
201
- /* @__PURE__ */ jsxs(
202
- "div",
203
- {
204
- style: {
205
- display: "flex",
206
- alignItems: "center",
207
- justifyContent: "space-between",
208
- gap: "10px"
209
- },
210
- children: [
211
- /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "2px" }, children: [
212
- /* @__PURE__ */ jsx("div", { style: { fontSize: "11px", color: STYLES.textMuted }, children: "Server" }),
213
- /* @__PURE__ */ jsx(
214
- "div",
215
- {
216
- style: {
217
- fontSize: "12px",
218
- fontWeight: 600,
219
- color: wsConnected ? "#10B981" : "#EF4444"
220
- },
221
- children: wsConnected ? "Connected" : "Disconnected"
222
- }
223
- )
224
- ] }),
225
- /* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: "8px" }, children: [
226
- /* @__PURE__ */ jsx(
227
- "button",
228
- {
229
- onClick: () => connectWebSocket(wsUrl),
230
- style: {
231
- padding: "6px 10px",
232
- borderRadius: "8px",
233
- border: `1px solid ${STYLES.border}`,
234
- backgroundColor: "transparent",
235
- color: STYLES.text,
236
- fontSize: "11px",
237
- fontWeight: 600,
238
- cursor: "pointer"
239
- },
240
- title: "Reconnect to WebSocket server",
241
- children: "Reconnect"
242
- }
243
- ),
244
- /* @__PURE__ */ jsx(
245
- "button",
246
- {
247
- onClick: () => disconnectWebSocket(),
248
- style: {
249
- padding: "6px 10px",
250
- borderRadius: "8px",
251
- border: `1px solid ${STYLES.border}`,
252
- backgroundColor: "transparent",
253
- color: STYLES.textMuted,
254
- fontSize: "11px",
255
- fontWeight: 600,
256
- cursor: "pointer"
257
- },
258
- title: "Disconnect from WebSocket server",
259
- children: "Disconnect"
260
- }
261
- )
262
- ] })
263
- ]
264
- }
265
- ),
266
- /* @__PURE__ */ jsx(
267
- "div",
268
- {
269
- style: {
270
- marginTop: "8px",
271
- fontSize: "10px",
272
- color: STYLES.textMuted,
273
- fontFamily: STYLES.fontMono,
274
- wordBreak: "break-all"
275
- },
276
- children: wsUrl
277
- }
278
- )
279
- ]
280
- }
281
- ),
282
- /* @__PURE__ */ jsxs(
283
- "div",
284
- {
285
- style: {
286
- marginTop: "10px",
287
- padding: "10px 12px",
288
- borderRadius: "10px",
289
- border: `1px solid ${STYLES.border}`,
290
- backgroundColor: "rgba(31, 41, 55, 0.45)",
291
- marginBottom: "12px"
292
- },
293
- children: [
294
- /* @__PURE__ */ jsxs(
295
- "div",
296
- {
297
- style: {
298
- display: "flex",
299
- alignItems: "center",
300
- justifyContent: "space-between",
301
- marginBottom: "8px"
302
- },
303
- children: [
304
- /* @__PURE__ */ jsx(
305
- "div",
306
- {
307
- style: { fontSize: "11px", fontWeight: 700, color: STYLES.text },
308
- children: "Live lint"
309
- }
310
- ),
311
- /* @__PURE__ */ jsx("div", { style: { fontSize: "10px", color: STYLES.textMuted }, children: wsConnected ? "Streaming" : "Offline" })
312
- ]
313
- }
314
- ),
315
- wsLastActivity ? /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "6px" }, children: [
316
- /* @__PURE__ */ jsx("div", { style: { fontSize: "11px", color: STYLES.textMuted }, children: wsLastActivity.phase }),
317
- /* @__PURE__ */ jsx(
318
- "div",
319
- {
320
- style: {
321
- fontSize: "11px",
322
- fontFamily: STYLES.fontMono,
323
- color: STYLES.text,
324
- whiteSpace: "nowrap",
325
- overflow: "hidden",
326
- textOverflow: "ellipsis"
327
- },
328
- title: wsLastActivity.filePath,
329
- children: (wsLastActivity.filePath.split("/").pop() || wsLastActivity.filePath) ?? ""
330
- }
331
- )
332
- ] }) : /* @__PURE__ */ jsx("div", { style: { fontSize: "11px", color: STYLES.textMuted }, children: "No activity yet" }),
333
- wsRecentResults.length > 0 && /* @__PURE__ */ jsxs(
334
- "div",
335
- {
336
- style: {
337
- marginTop: "10px",
338
- display: "flex",
339
- flexDirection: "column",
340
- gap: "6px"
341
- },
342
- children: [
343
- /* @__PURE__ */ jsx("div", { style: { fontSize: "10px", color: STYLES.textMuted }, children: "Recent results" }),
344
- wsRecentResults.slice(0, 5).map((r) => {
345
- const file = r.filePath.split("/").pop() || r.filePath;
346
- const color = r.issueCount === 0 ? "#10B981" : r.issueCount <= 2 ? "#F59E0B" : "#EF4444";
347
- return /* @__PURE__ */ jsxs(
348
- "div",
349
- {
350
- style: {
351
- display: "flex",
352
- alignItems: "center",
353
- justifyContent: "space-between",
354
- gap: "10px",
355
- fontSize: "10px",
356
- fontFamily: STYLES.fontMono,
357
- color: STYLES.textMuted
358
- },
359
- title: r.filePath,
360
- children: [
361
- /* @__PURE__ */ jsx(
362
- "span",
363
- {
364
- style: {
365
- overflow: "hidden",
366
- textOverflow: "ellipsis",
367
- whiteSpace: "nowrap",
368
- flex: 1
369
- },
370
- children: file
371
- }
372
- ),
373
- /* @__PURE__ */ jsx(
374
- "span",
375
- {
376
- style: {
377
- minWidth: "34px",
378
- textAlign: "right",
379
- fontWeight: 700,
380
- color
381
- },
382
- children: r.issueCount
383
- }
384
- )
385
- ]
386
- },
387
- r.filePath
388
- );
389
- })
390
- ]
391
- }
392
- )
393
- ]
394
- }
395
- ),
396
- /* @__PURE__ */ jsxs(
397
- "div",
398
- {
399
- style: {
400
- marginTop: "12px",
401
- paddingTop: "12px",
402
- borderTop: `1px solid ${STYLES.border}`
403
- },
404
- children: [
405
- /* @__PURE__ */ jsx(
406
- "div",
407
- {
408
- style: {
409
- fontSize: "12px",
410
- fontWeight: 600,
411
- color: STYLES.text,
412
- marginBottom: "10px"
413
- },
414
- children: "Auto-Scan Page"
415
- }
416
- ),
417
- !isActive ? (
418
- // Start button
419
- /* @__PURE__ */ jsxs(
420
- "button",
421
- {
422
- onClick: startAutoScan,
423
- style: {
424
- width: "100%",
425
- display: "flex",
426
- alignItems: "center",
427
- justifyContent: "center",
428
- gap: "8px",
429
- padding: "10px",
430
- borderRadius: "8px",
431
- border: "none",
432
- backgroundColor: "#10B981",
433
- color: "#FFFFFF",
434
- fontSize: "12px",
435
- fontWeight: 600,
436
- cursor: "pointer",
437
- transition: "background-color 0.15s"
438
- },
439
- onMouseEnter: (e) => {
440
- e.currentTarget.style.backgroundColor = "#059669";
441
- },
442
- onMouseLeave: (e) => {
443
- e.currentTarget.style.backgroundColor = "#10B981";
444
- },
445
- children: [
446
- /* @__PURE__ */ jsx(ScanIcon, {}),
447
- "Scan All Elements"
448
- ]
449
- }
450
- )
451
- ) : (
452
- // Progress and controls
453
- /* @__PURE__ */ jsxs("div", { children: [
454
- /* @__PURE__ */ jsxs(
455
- "div",
456
- {
457
- style: {
458
- marginBottom: "10px"
459
- },
460
- children: [
461
- /* @__PURE__ */ jsxs(
462
- "div",
463
- {
464
- style: {
465
- display: "flex",
466
- justifyContent: "space-between",
467
- fontSize: "11px",
468
- color: STYLES.textMuted,
469
- marginBottom: "4px"
470
- },
471
- children: [
472
- /* @__PURE__ */ jsx("span", { children: isComplete ? "Complete" : isPaused ? "Paused" : "Scanning..." }),
473
- /* @__PURE__ */ jsxs("span", { children: [
474
- autoScanState.currentIndex,
475
- " / ",
476
- autoScanState.totalElements
477
- ] })
478
- ]
479
- }
480
- ),
481
- /* @__PURE__ */ jsx(
482
- "div",
483
- {
484
- style: {
485
- height: "4px",
486
- backgroundColor: "rgba(75, 85, 99, 0.5)",
487
- borderRadius: "2px",
488
- overflow: "hidden"
489
- },
490
- children: /* @__PURE__ */ jsx(
491
- "div",
492
- {
493
- style: {
494
- height: "100%",
495
- width: `${autoScanState.totalElements > 0 ? autoScanState.currentIndex / autoScanState.totalElements * 100 : 0}%`,
496
- backgroundColor: isComplete ? "#10B981" : STYLES.accent,
497
- transition: "width 0.2s ease-out"
498
- }
499
- }
500
- )
501
- }
502
- )
503
- ]
504
- }
505
- ),
506
- /* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: "8px" }, children: [
507
- isScanning && /* @__PURE__ */ jsxs(
508
- "button",
509
- {
510
- onClick: pauseAutoScan,
511
- style: {
512
- flex: 1,
513
- display: "flex",
514
- alignItems: "center",
515
- justifyContent: "center",
516
- gap: "6px",
517
- padding: "8px",
518
- borderRadius: "6px",
519
- border: `1px solid ${STYLES.border}`,
520
- backgroundColor: "transparent",
521
- color: STYLES.text,
522
- fontSize: "11px",
523
- fontWeight: 500,
524
- cursor: "pointer",
525
- transition: "all 0.15s"
526
- },
527
- onMouseEnter: (e) => {
528
- e.currentTarget.style.backgroundColor = STYLES.bgHover;
529
- },
530
- onMouseLeave: (e) => {
531
- e.currentTarget.style.backgroundColor = "transparent";
532
- },
533
- children: [
534
- /* @__PURE__ */ jsx(PauseIcon, {}),
535
- "Pause"
536
- ]
537
- }
538
- ),
539
- isPaused && /* @__PURE__ */ jsxs(
540
- "button",
541
- {
542
- onClick: resumeAutoScan,
543
- style: {
544
- flex: 1,
545
- display: "flex",
546
- alignItems: "center",
547
- justifyContent: "center",
548
- gap: "6px",
549
- padding: "8px",
550
- borderRadius: "6px",
551
- border: "none",
552
- backgroundColor: STYLES.accent,
553
- color: "#FFFFFF",
554
- fontSize: "11px",
555
- fontWeight: 500,
556
- cursor: "pointer",
557
- transition: "all 0.15s"
558
- },
559
- onMouseEnter: (e) => {
560
- e.currentTarget.style.backgroundColor = STYLES.accentHover;
561
- },
562
- onMouseLeave: (e) => {
563
- e.currentTarget.style.backgroundColor = STYLES.accent;
564
- },
565
- children: [
566
- /* @__PURE__ */ jsx(PlayIcon, {}),
567
- "Resume"
568
- ]
569
- }
570
- ),
571
- /* @__PURE__ */ jsxs(
572
- "button",
573
- {
574
- onClick: stopAutoScan,
575
- style: {
576
- flex: 1,
577
- display: "flex",
578
- alignItems: "center",
579
- justifyContent: "center",
580
- gap: "6px",
581
- padding: "8px",
582
- borderRadius: "6px",
583
- border: `1px solid ${STYLES.border}`,
584
- backgroundColor: "transparent",
585
- color: STYLES.textMuted,
586
- fontSize: "11px",
587
- fontWeight: 500,
588
- cursor: "pointer",
589
- transition: "all 0.15s"
590
- },
591
- onMouseEnter: (e) => {
592
- e.currentTarget.style.backgroundColor = STYLES.bgHover;
593
- e.currentTarget.style.color = STYLES.text;
594
- },
595
- onMouseLeave: (e) => {
596
- e.currentTarget.style.backgroundColor = "transparent";
597
- e.currentTarget.style.color = STYLES.textMuted;
598
- },
599
- children: [
600
- /* @__PURE__ */ jsx(StopIcon, {}),
601
- isComplete ? "Clear" : "Stop"
602
- ]
603
- }
604
- )
605
- ] })
606
- ] })
607
- ),
608
- /* @__PURE__ */ jsx(
609
- "div",
610
- {
611
- style: {
612
- marginTop: "8px",
613
- fontSize: "10px",
614
- color: STYLES.textMuted,
615
- lineHeight: 1.4
616
- },
617
- children: "Scan all elements for style issues and show badges"
618
- }
619
- )
620
- ]
621
- }
622
- ),
623
- /* @__PURE__ */ jsxs(
624
- "div",
625
- {
626
- style: {
627
- marginTop: "12px",
628
- paddingTop: "12px",
629
- borderTop: `1px solid ${STYLES.border}`,
630
- fontSize: "11px",
631
- color: STYLES.textMuted,
632
- lineHeight: 1.5
633
- },
634
- children: [
635
- /* @__PURE__ */ jsx("strong", { style: { color: STYLES.text }, children: "Alt+Click" }),
636
- " any element to open the inspector sidebar"
637
- ]
638
- }
639
- )
640
- ]
641
- }
642
- );
643
- }
644
- function UILintIcon({ active }) {
645
- return /* @__PURE__ */ jsxs("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", children: [
646
- /* @__PURE__ */ jsx(
647
- "rect",
648
- {
649
- x: "3",
650
- y: "3",
651
- width: "18",
652
- height: "18",
653
- rx: "3",
654
- stroke: active ? STYLES.accent : "currentColor",
655
- strokeWidth: "2"
656
- }
657
- ),
658
- /* @__PURE__ */ jsx(
659
- "path",
660
- {
661
- d: "M7 12h10M12 7v10",
662
- stroke: active ? STYLES.accent : "currentColor",
663
- strokeWidth: "2",
664
- strokeLinecap: "round"
665
- }
666
- )
667
- ] });
668
- }
669
- function ScanIcon() {
670
- return /* @__PURE__ */ jsx("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", children: /* @__PURE__ */ jsx(
671
- "path",
672
- {
673
- 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",
674
- stroke: "currentColor",
675
- strokeWidth: "2",
676
- strokeLinecap: "round"
677
- }
678
- ) });
679
- }
680
- function PauseIcon() {
681
- return /* @__PURE__ */ jsxs("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", children: [
682
- /* @__PURE__ */ jsx("rect", { x: "6", y: "4", width: "4", height: "16", rx: "1", fill: "currentColor" }),
683
- /* @__PURE__ */ jsx("rect", { x: "14", y: "4", width: "4", height: "16", rx: "1", fill: "currentColor" })
684
- ] });
685
- }
686
- function PlayIcon() {
687
- return /* @__PURE__ */ jsx("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", children: /* @__PURE__ */ jsx("path", { d: "M8 5v14l11-7L8 5z", fill: "currentColor" }) });
688
- }
689
- function StopIcon() {
690
- return /* @__PURE__ */ jsx("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", children: /* @__PURE__ */ jsx("rect", { x: "6", y: "6", width: "12", height: "12", rx: "1", fill: "currentColor" }) });
691
- }
692
-
693
- export {
694
- UILintToolbar
695
- };