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,537 @@
1
+ "use client";
2
+ import {
3
+ useUILintContext
4
+ } from "./chunk-I4C3NAUH.js";
5
+
6
+ // src/components/ui-lint/UILintToolbar.tsx
7
+ import { useState, useRef, useEffect } from "react";
8
+ import { createPortal } from "react-dom";
9
+ import { jsx, jsxs } from "react/jsx-runtime";
10
+ var STYLES = {
11
+ bg: "rgba(17, 24, 39, 0.9)",
12
+ bgHover: "rgba(31, 41, 55, 0.95)",
13
+ border: "rgba(75, 85, 99, 0.5)",
14
+ text: "#F9FAFB",
15
+ textMuted: "#9CA3AF",
16
+ accent: "#3B82F6",
17
+ accentHover: "#2563EB",
18
+ shadow: "0 8px 32px rgba(0, 0, 0, 0.4)",
19
+ blur: "blur(12px)",
20
+ font: 'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
21
+ fontMono: 'ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace'
22
+ };
23
+ function UILintToolbar() {
24
+ const { settings, updateSettings, inspectedElement } = useUILintContext();
25
+ const [showSettings, setShowSettings] = useState(false);
26
+ const [mounted, setMounted] = useState(false);
27
+ const settingsRef = useRef(null);
28
+ useEffect(() => {
29
+ setMounted(true);
30
+ }, []);
31
+ useEffect(() => {
32
+ const handleClickOutside = (e) => {
33
+ if (settingsRef.current && !settingsRef.current.contains(e.target)) {
34
+ setShowSettings(false);
35
+ }
36
+ };
37
+ if (showSettings) {
38
+ document.addEventListener("mousedown", handleClickOutside);
39
+ return () => document.removeEventListener("mousedown", handleClickOutside);
40
+ }
41
+ }, [showSettings]);
42
+ if (!mounted) return null;
43
+ if (inspectedElement) return null;
44
+ const content = /* @__PURE__ */ jsxs(
45
+ "div",
46
+ {
47
+ "data-ui-lint": true,
48
+ style: {
49
+ position: "fixed",
50
+ top: "24px",
51
+ right: "24px",
52
+ zIndex: 99999,
53
+ fontFamily: STYLES.font
54
+ },
55
+ children: [
56
+ /* @__PURE__ */ jsx("style", { children: `
57
+ @keyframes uilint-fade-in {
58
+ from { opacity: 0; transform: scale(0.95); }
59
+ to { opacity: 1; transform: scale(1); }
60
+ }
61
+ ` }),
62
+ /* @__PURE__ */ jsxs("div", { style: { position: "relative" }, ref: settingsRef, children: [
63
+ /* @__PURE__ */ jsx(
64
+ "button",
65
+ {
66
+ onClick: () => setShowSettings(!showSettings),
67
+ style: {
68
+ display: "flex",
69
+ alignItems: "center",
70
+ justifyContent: "center",
71
+ width: "48px",
72
+ height: "48px",
73
+ borderRadius: "50%",
74
+ border: `1px solid ${STYLES.border}`,
75
+ backgroundColor: showSettings ? STYLES.bgHover : STYLES.bg,
76
+ backdropFilter: STYLES.blur,
77
+ WebkitBackdropFilter: STYLES.blur,
78
+ boxShadow: STYLES.shadow,
79
+ cursor: "pointer",
80
+ transition: "all 0.2s ease-out",
81
+ color: showSettings ? STYLES.text : STYLES.textMuted,
82
+ fontSize: "20px"
83
+ },
84
+ onMouseEnter: (e) => {
85
+ e.currentTarget.style.transform = "scale(1.05)";
86
+ e.currentTarget.style.boxShadow = "0 12px 40px rgba(0, 0, 0, 0.5)";
87
+ },
88
+ onMouseLeave: (e) => {
89
+ e.currentTarget.style.transform = "scale(1)";
90
+ e.currentTarget.style.boxShadow = STYLES.shadow;
91
+ },
92
+ title: "UILint Settings (Alt+Click any element to inspect)",
93
+ children: /* @__PURE__ */ jsx(UILintIcon, { active: showSettings })
94
+ }
95
+ ),
96
+ showSettings && /* @__PURE__ */ jsx(SettingsPopover, { settings, onUpdate: updateSettings }),
97
+ /* @__PURE__ */ jsxs(
98
+ "div",
99
+ {
100
+ style: {
101
+ position: "absolute",
102
+ left: "100%",
103
+ top: "50%",
104
+ transform: "translateY(-50%)",
105
+ marginLeft: "12px",
106
+ padding: "8px 12px",
107
+ borderRadius: "8px",
108
+ backgroundColor: STYLES.bg,
109
+ border: `1px solid ${STYLES.border}`,
110
+ backdropFilter: STYLES.blur,
111
+ WebkitBackdropFilter: STYLES.blur,
112
+ boxShadow: STYLES.shadow,
113
+ fontSize: "12px",
114
+ color: STYLES.textMuted,
115
+ whiteSpace: "nowrap",
116
+ opacity: 0,
117
+ transition: "opacity 0.2s",
118
+ pointerEvents: "none"
119
+ },
120
+ className: "uilint-hint",
121
+ children: [
122
+ /* @__PURE__ */ jsx("span", { style: { color: STYLES.text }, children: "Alt+Click" }),
123
+ " any element to inspect"
124
+ ]
125
+ }
126
+ )
127
+ ] })
128
+ ]
129
+ }
130
+ );
131
+ return createPortal(content, document.body);
132
+ }
133
+ function SettingsPopover({
134
+ settings,
135
+ onUpdate
136
+ }) {
137
+ const {
138
+ autoScanState,
139
+ startAutoScan,
140
+ pauseAutoScan,
141
+ resumeAutoScan,
142
+ stopAutoScan
143
+ } = useUILintContext();
144
+ const isScanning = autoScanState.status === "scanning";
145
+ const isPaused = autoScanState.status === "paused";
146
+ const isComplete = autoScanState.status === "complete";
147
+ const isActive = isScanning || isPaused || isComplete;
148
+ return /* @__PURE__ */ jsxs(
149
+ "div",
150
+ {
151
+ style: {
152
+ position: "absolute",
153
+ top: "100%",
154
+ right: 0,
155
+ marginTop: "8px",
156
+ width: "300px",
157
+ padding: "16px",
158
+ borderRadius: "12px",
159
+ border: `1px solid ${STYLES.border}`,
160
+ backgroundColor: STYLES.bg,
161
+ backdropFilter: STYLES.blur,
162
+ WebkitBackdropFilter: STYLES.blur,
163
+ boxShadow: STYLES.shadow,
164
+ animation: "uilint-fade-in 0.15s ease-out"
165
+ },
166
+ children: [
167
+ /* @__PURE__ */ jsx(
168
+ "div",
169
+ {
170
+ style: {
171
+ fontSize: "13px",
172
+ fontWeight: 600,
173
+ color: STYLES.text,
174
+ marginBottom: "12px"
175
+ },
176
+ children: "UILint Settings"
177
+ }
178
+ ),
179
+ /* @__PURE__ */ jsx(
180
+ SettingToggle,
181
+ {
182
+ label: "Hide node_modules",
183
+ checked: settings.hideNodeModules,
184
+ onChange: (checked) => onUpdate({ hideNodeModules: checked })
185
+ }
186
+ ),
187
+ /* @__PURE__ */ jsxs(
188
+ "div",
189
+ {
190
+ style: {
191
+ marginTop: "12px",
192
+ paddingTop: "12px",
193
+ borderTop: `1px solid ${STYLES.border}`
194
+ },
195
+ children: [
196
+ /* @__PURE__ */ jsx(
197
+ "div",
198
+ {
199
+ style: {
200
+ fontSize: "12px",
201
+ fontWeight: 600,
202
+ color: STYLES.text,
203
+ marginBottom: "10px"
204
+ },
205
+ children: "Auto-Scan Page"
206
+ }
207
+ ),
208
+ !isActive ? (
209
+ // Start button
210
+ /* @__PURE__ */ jsxs(
211
+ "button",
212
+ {
213
+ onClick: startAutoScan,
214
+ style: {
215
+ width: "100%",
216
+ display: "flex",
217
+ alignItems: "center",
218
+ justifyContent: "center",
219
+ gap: "8px",
220
+ padding: "10px",
221
+ borderRadius: "8px",
222
+ border: "none",
223
+ backgroundColor: "#10B981",
224
+ color: "#FFFFFF",
225
+ fontSize: "12px",
226
+ fontWeight: 600,
227
+ cursor: "pointer",
228
+ transition: "background-color 0.15s"
229
+ },
230
+ onMouseEnter: (e) => {
231
+ e.currentTarget.style.backgroundColor = "#059669";
232
+ },
233
+ onMouseLeave: (e) => {
234
+ e.currentTarget.style.backgroundColor = "#10B981";
235
+ },
236
+ children: [
237
+ /* @__PURE__ */ jsx(ScanIcon, {}),
238
+ "Scan All Elements"
239
+ ]
240
+ }
241
+ )
242
+ ) : (
243
+ // Progress and controls
244
+ /* @__PURE__ */ jsxs("div", { children: [
245
+ /* @__PURE__ */ jsxs(
246
+ "div",
247
+ {
248
+ style: {
249
+ marginBottom: "10px"
250
+ },
251
+ children: [
252
+ /* @__PURE__ */ jsxs(
253
+ "div",
254
+ {
255
+ style: {
256
+ display: "flex",
257
+ justifyContent: "space-between",
258
+ fontSize: "11px",
259
+ color: STYLES.textMuted,
260
+ marginBottom: "4px"
261
+ },
262
+ children: [
263
+ /* @__PURE__ */ jsx("span", { children: isComplete ? "Complete" : isPaused ? "Paused" : "Scanning..." }),
264
+ /* @__PURE__ */ jsxs("span", { children: [
265
+ autoScanState.currentIndex,
266
+ " / ",
267
+ autoScanState.totalElements
268
+ ] })
269
+ ]
270
+ }
271
+ ),
272
+ /* @__PURE__ */ jsx(
273
+ "div",
274
+ {
275
+ style: {
276
+ height: "4px",
277
+ backgroundColor: "rgba(75, 85, 99, 0.5)",
278
+ borderRadius: "2px",
279
+ overflow: "hidden"
280
+ },
281
+ children: /* @__PURE__ */ jsx(
282
+ "div",
283
+ {
284
+ style: {
285
+ height: "100%",
286
+ width: `${autoScanState.totalElements > 0 ? autoScanState.currentIndex / autoScanState.totalElements * 100 : 0}%`,
287
+ backgroundColor: isComplete ? "#10B981" : STYLES.accent,
288
+ transition: "width 0.2s ease-out"
289
+ }
290
+ }
291
+ )
292
+ }
293
+ )
294
+ ]
295
+ }
296
+ ),
297
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: "8px" }, children: [
298
+ isScanning && /* @__PURE__ */ jsxs(
299
+ "button",
300
+ {
301
+ onClick: pauseAutoScan,
302
+ style: {
303
+ flex: 1,
304
+ display: "flex",
305
+ alignItems: "center",
306
+ justifyContent: "center",
307
+ gap: "6px",
308
+ padding: "8px",
309
+ borderRadius: "6px",
310
+ border: `1px solid ${STYLES.border}`,
311
+ backgroundColor: "transparent",
312
+ color: STYLES.text,
313
+ fontSize: "11px",
314
+ fontWeight: 500,
315
+ cursor: "pointer",
316
+ transition: "all 0.15s"
317
+ },
318
+ onMouseEnter: (e) => {
319
+ e.currentTarget.style.backgroundColor = STYLES.bgHover;
320
+ },
321
+ onMouseLeave: (e) => {
322
+ e.currentTarget.style.backgroundColor = "transparent";
323
+ },
324
+ children: [
325
+ /* @__PURE__ */ jsx(PauseIcon, {}),
326
+ "Pause"
327
+ ]
328
+ }
329
+ ),
330
+ isPaused && /* @__PURE__ */ jsxs(
331
+ "button",
332
+ {
333
+ onClick: resumeAutoScan,
334
+ style: {
335
+ flex: 1,
336
+ display: "flex",
337
+ alignItems: "center",
338
+ justifyContent: "center",
339
+ gap: "6px",
340
+ padding: "8px",
341
+ borderRadius: "6px",
342
+ border: "none",
343
+ backgroundColor: STYLES.accent,
344
+ color: "#FFFFFF",
345
+ fontSize: "11px",
346
+ fontWeight: 500,
347
+ cursor: "pointer",
348
+ transition: "all 0.15s"
349
+ },
350
+ onMouseEnter: (e) => {
351
+ e.currentTarget.style.backgroundColor = STYLES.accentHover;
352
+ },
353
+ onMouseLeave: (e) => {
354
+ e.currentTarget.style.backgroundColor = STYLES.accent;
355
+ },
356
+ children: [
357
+ /* @__PURE__ */ jsx(PlayIcon, {}),
358
+ "Resume"
359
+ ]
360
+ }
361
+ ),
362
+ /* @__PURE__ */ jsxs(
363
+ "button",
364
+ {
365
+ onClick: stopAutoScan,
366
+ style: {
367
+ flex: 1,
368
+ display: "flex",
369
+ alignItems: "center",
370
+ justifyContent: "center",
371
+ gap: "6px",
372
+ padding: "8px",
373
+ borderRadius: "6px",
374
+ border: `1px solid ${STYLES.border}`,
375
+ backgroundColor: "transparent",
376
+ color: STYLES.textMuted,
377
+ fontSize: "11px",
378
+ fontWeight: 500,
379
+ cursor: "pointer",
380
+ transition: "all 0.15s"
381
+ },
382
+ onMouseEnter: (e) => {
383
+ e.currentTarget.style.backgroundColor = STYLES.bgHover;
384
+ e.currentTarget.style.color = STYLES.text;
385
+ },
386
+ onMouseLeave: (e) => {
387
+ e.currentTarget.style.backgroundColor = "transparent";
388
+ e.currentTarget.style.color = STYLES.textMuted;
389
+ },
390
+ children: [
391
+ /* @__PURE__ */ jsx(StopIcon, {}),
392
+ isComplete ? "Clear" : "Stop"
393
+ ]
394
+ }
395
+ )
396
+ ] })
397
+ ] })
398
+ ),
399
+ /* @__PURE__ */ jsx(
400
+ "div",
401
+ {
402
+ style: {
403
+ marginTop: "8px",
404
+ fontSize: "10px",
405
+ color: STYLES.textMuted,
406
+ lineHeight: 1.4
407
+ },
408
+ children: "Scan all elements for style issues and show badges"
409
+ }
410
+ )
411
+ ]
412
+ }
413
+ ),
414
+ /* @__PURE__ */ jsxs(
415
+ "div",
416
+ {
417
+ style: {
418
+ marginTop: "12px",
419
+ paddingTop: "12px",
420
+ borderTop: `1px solid ${STYLES.border}`,
421
+ fontSize: "11px",
422
+ color: STYLES.textMuted,
423
+ lineHeight: 1.5
424
+ },
425
+ children: [
426
+ /* @__PURE__ */ jsx("strong", { style: { color: STYLES.text }, children: "Alt+Click" }),
427
+ " any element to open the inspector sidebar"
428
+ ]
429
+ }
430
+ )
431
+ ]
432
+ }
433
+ );
434
+ }
435
+ function SettingToggle({
436
+ label,
437
+ checked,
438
+ onChange
439
+ }) {
440
+ return /* @__PURE__ */ jsxs(
441
+ "label",
442
+ {
443
+ style: {
444
+ display: "flex",
445
+ alignItems: "center",
446
+ justifyContent: "space-between",
447
+ padding: "8px 0",
448
+ cursor: "pointer"
449
+ },
450
+ children: [
451
+ /* @__PURE__ */ jsx("span", { style: { fontSize: "12px", color: STYLES.textMuted }, children: label }),
452
+ /* @__PURE__ */ jsx(
453
+ "div",
454
+ {
455
+ onClick: () => onChange(!checked),
456
+ style: {
457
+ width: "36px",
458
+ height: "20px",
459
+ borderRadius: "10px",
460
+ backgroundColor: checked ? STYLES.accent : "rgba(75, 85, 99, 0.5)",
461
+ position: "relative",
462
+ transition: "background-color 0.2s"
463
+ },
464
+ children: /* @__PURE__ */ jsx(
465
+ "div",
466
+ {
467
+ style: {
468
+ position: "absolute",
469
+ top: "2px",
470
+ left: checked ? "18px" : "2px",
471
+ width: "16px",
472
+ height: "16px",
473
+ borderRadius: "50%",
474
+ backgroundColor: "#FFFFFF",
475
+ transition: "left 0.2s",
476
+ boxShadow: "0 1px 3px rgba(0, 0, 0, 0.2)"
477
+ }
478
+ }
479
+ )
480
+ }
481
+ )
482
+ ]
483
+ }
484
+ );
485
+ }
486
+ function UILintIcon({ active }) {
487
+ return /* @__PURE__ */ jsxs("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", children: [
488
+ /* @__PURE__ */ jsx(
489
+ "rect",
490
+ {
491
+ x: "3",
492
+ y: "3",
493
+ width: "18",
494
+ height: "18",
495
+ rx: "3",
496
+ stroke: active ? STYLES.accent : "currentColor",
497
+ strokeWidth: "2"
498
+ }
499
+ ),
500
+ /* @__PURE__ */ jsx(
501
+ "path",
502
+ {
503
+ d: "M7 12h10M12 7v10",
504
+ stroke: active ? STYLES.accent : "currentColor",
505
+ strokeWidth: "2",
506
+ strokeLinecap: "round"
507
+ }
508
+ )
509
+ ] });
510
+ }
511
+ function ScanIcon() {
512
+ return /* @__PURE__ */ jsx("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", children: /* @__PURE__ */ jsx(
513
+ "path",
514
+ {
515
+ 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",
516
+ stroke: "currentColor",
517
+ strokeWidth: "2",
518
+ strokeLinecap: "round"
519
+ }
520
+ ) });
521
+ }
522
+ function PauseIcon() {
523
+ return /* @__PURE__ */ jsxs("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", children: [
524
+ /* @__PURE__ */ jsx("rect", { x: "6", y: "4", width: "4", height: "16", rx: "1", fill: "currentColor" }),
525
+ /* @__PURE__ */ jsx("rect", { x: "14", y: "4", width: "4", height: "16", rx: "1", fill: "currentColor" })
526
+ ] });
527
+ }
528
+ function PlayIcon() {
529
+ 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" }) });
530
+ }
531
+ function StopIcon() {
532
+ 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" }) });
533
+ }
534
+
535
+ export {
536
+ UILintToolbar
537
+ };