uilint-react 0.1.25 → 0.1.26
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-2WRRHFLI.js → ElementBadges-HFQNIIO2.js} +1 -1
- package/dist/{InspectionPanel-FRJB6CJ6.js → InspectionPanel-4OWY4FVY.js} +2 -2
- package/dist/{LocatorOverlay-O4XZCAPC.js → LocatorOverlay-JJDOKNOS.js} +2 -2
- package/dist/{UILintToolbar-57XAWTGK.js → UILintToolbar-GMZ6YSI2.js} +2 -2
- package/dist/{chunk-45MPASAN.js → chunk-5VJ2Q2QW.js} +141 -79
- package/dist/{chunk-ORYG2TNM.js → chunk-7X5HN55P.js} +1 -1
- package/dist/chunk-QYRESGFG.js +1463 -0
- package/dist/{chunk-RA27RIJ2.js → chunk-XLIDEQXH.js} +1 -1
- package/dist/index.d.ts +12 -4
- package/dist/index.js +4 -4
- package/package.json +2 -2
- package/dist/chunk-SIVHTQ2P.js +0 -1359
|
@@ -130,17 +130,18 @@ function scanDOMForSources(root = document.body, hideNodeModules = true) {
|
|
|
130
130
|
let node = walker.currentNode;
|
|
131
131
|
while (node) {
|
|
132
132
|
if (node instanceof Element) {
|
|
133
|
-
let source =
|
|
133
|
+
let source = null;
|
|
134
134
|
let componentStack = [];
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
source = getDebugSource(fiber._debugOwner);
|
|
141
|
-
}
|
|
142
|
-
componentStack = getComponentStack(fiber);
|
|
135
|
+
const fiber = getFiberFromElement(node);
|
|
136
|
+
if (fiber) {
|
|
137
|
+
source = getDebugSource(fiber);
|
|
138
|
+
if (!source && fiber._debugOwner) {
|
|
139
|
+
source = getDebugSource(fiber._debugOwner);
|
|
143
140
|
}
|
|
141
|
+
componentStack = getComponentStack(fiber);
|
|
142
|
+
}
|
|
143
|
+
if (!source) {
|
|
144
|
+
source = getSourceFromDataLoc(node);
|
|
144
145
|
}
|
|
145
146
|
if (hideNodeModules && source && isNodeModulesPath(source.fileName)) {
|
|
146
147
|
const appSource = componentStack.find(
|
|
@@ -261,67 +262,78 @@ var DEFAULT_AUTO_SCAN_STATE = {
|
|
|
261
262
|
};
|
|
262
263
|
var DATA_UILINT_ID = "data-ui-lint-id";
|
|
263
264
|
|
|
264
|
-
// src/components/ui-lint/UILintProvider.tsx
|
|
265
|
-
import {
|
|
266
|
-
createContext,
|
|
267
|
-
useContext,
|
|
268
|
-
useState,
|
|
269
|
-
useEffect,
|
|
270
|
-
useCallback,
|
|
271
|
-
useMemo
|
|
272
|
-
} from "react";
|
|
273
|
-
|
|
274
265
|
// src/components/ui-lint/store.ts
|
|
275
266
|
import { create } from "zustand";
|
|
276
|
-
|
|
277
|
-
if (
|
|
278
|
-
return
|
|
279
|
-
elementId: element.id,
|
|
280
|
-
issues: [],
|
|
281
|
-
status: "complete"
|
|
282
|
-
};
|
|
267
|
+
function getDataLocFromId(id) {
|
|
268
|
+
if (id.startsWith("loc:")) {
|
|
269
|
+
return id.slice(4);
|
|
283
270
|
}
|
|
271
|
+
return null;
|
|
272
|
+
}
|
|
273
|
+
async function scanFileForIssues(sourceFile) {
|
|
274
|
+
if (sourceFile.elements.length === 0) {
|
|
275
|
+
return { issues: [] };
|
|
276
|
+
}
|
|
277
|
+
const filePath = sourceFile.path;
|
|
284
278
|
try {
|
|
285
279
|
const sourceResponse = await fetch(
|
|
286
|
-
`/api/.uilint/source?path=${encodeURIComponent(
|
|
280
|
+
`/api/.uilint/source?path=${encodeURIComponent(filePath)}`
|
|
287
281
|
);
|
|
288
282
|
if (!sourceResponse.ok) {
|
|
289
|
-
return {
|
|
290
|
-
elementId: element.id,
|
|
291
|
-
issues: [],
|
|
292
|
-
status: "error"
|
|
293
|
-
};
|
|
283
|
+
return { issues: [], error: true };
|
|
294
284
|
}
|
|
295
285
|
const sourceData = await sourceResponse.json();
|
|
286
|
+
const dataLocs = [];
|
|
287
|
+
for (const el of sourceFile.elements) {
|
|
288
|
+
const dataLoc = getDataLocFromId(el.id);
|
|
289
|
+
if (dataLoc) {
|
|
290
|
+
dataLocs.push(dataLoc);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
296
293
|
const analyzeResponse = await fetch("/api/.uilint/analyze", {
|
|
297
294
|
method: "POST",
|
|
298
295
|
headers: { "Content-Type": "application/json" },
|
|
299
296
|
body: JSON.stringify({
|
|
300
297
|
sourceCode: sourceData.content,
|
|
301
|
-
filePath: sourceData.relativePath ||
|
|
302
|
-
|
|
303
|
-
componentLine: element.source.lineNumber
|
|
298
|
+
filePath: sourceData.relativePath || filePath,
|
|
299
|
+
dataLocs
|
|
304
300
|
})
|
|
305
301
|
});
|
|
306
302
|
if (!analyzeResponse.ok) {
|
|
307
|
-
return {
|
|
308
|
-
elementId: element.id,
|
|
309
|
-
issues: [],
|
|
310
|
-
status: "error"
|
|
311
|
-
};
|
|
303
|
+
return { issues: [], error: true };
|
|
312
304
|
}
|
|
313
305
|
const result = await analyzeResponse.json();
|
|
314
|
-
return {
|
|
315
|
-
elementId: element.id,
|
|
316
|
-
issues: result.issues || [],
|
|
317
|
-
status: "complete"
|
|
318
|
-
};
|
|
306
|
+
return { issues: result.issues || [] };
|
|
319
307
|
} catch {
|
|
320
|
-
return {
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
308
|
+
return { issues: [], error: true };
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
function distributeIssuesToElements(issues, elements, updateElementIssue, hasError) {
|
|
312
|
+
const dataLocToElementId = /* @__PURE__ */ new Map();
|
|
313
|
+
for (const el of elements) {
|
|
314
|
+
const dataLoc = getDataLocFromId(el.id);
|
|
315
|
+
if (dataLoc) {
|
|
316
|
+
dataLocToElementId.set(dataLoc, el.id);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
const issuesByElement = /* @__PURE__ */ new Map();
|
|
320
|
+
for (const issue of issues) {
|
|
321
|
+
if (issue.dataLoc) {
|
|
322
|
+
const elementId = dataLocToElementId.get(issue.dataLoc);
|
|
323
|
+
if (elementId) {
|
|
324
|
+
const existing = issuesByElement.get(elementId) || [];
|
|
325
|
+
existing.push(issue);
|
|
326
|
+
issuesByElement.set(elementId, existing);
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
for (const el of elements) {
|
|
331
|
+
const elementIssues = issuesByElement.get(el.id) || [];
|
|
332
|
+
updateElementIssue(el.id, {
|
|
333
|
+
elementId: el.id,
|
|
334
|
+
issues: elementIssues,
|
|
335
|
+
status: hasError ? "error" : "complete"
|
|
336
|
+
});
|
|
325
337
|
}
|
|
326
338
|
}
|
|
327
339
|
var useUILintStore = create()((set, get) => ({
|
|
@@ -350,6 +362,31 @@ var useUILintStore = create()((set, get) => ({
|
|
|
350
362
|
// ============ Inspection ============
|
|
351
363
|
inspectedElement: null,
|
|
352
364
|
setInspectedElement: (el) => set({ inspectedElement: el }),
|
|
365
|
+
// ============ Manual Scan (InspectionPanel) ============
|
|
366
|
+
manualScanCache: /* @__PURE__ */ new Map(),
|
|
367
|
+
upsertManualScan: (key, patch) => set((state) => {
|
|
368
|
+
const next = new Map(state.manualScanCache);
|
|
369
|
+
const existing = next.get(key);
|
|
370
|
+
const base = existing ?? {
|
|
371
|
+
key,
|
|
372
|
+
status: "idle",
|
|
373
|
+
issues: [],
|
|
374
|
+
updatedAt: Date.now()
|
|
375
|
+
};
|
|
376
|
+
next.set(key, {
|
|
377
|
+
...base,
|
|
378
|
+
...patch,
|
|
379
|
+
key,
|
|
380
|
+
updatedAt: Date.now()
|
|
381
|
+
});
|
|
382
|
+
return { manualScanCache: next };
|
|
383
|
+
}),
|
|
384
|
+
clearManualScan: (key) => set((state) => {
|
|
385
|
+
if (!state.manualScanCache.has(key)) return state;
|
|
386
|
+
const next = new Map(state.manualScanCache);
|
|
387
|
+
next.delete(key);
|
|
388
|
+
return { manualScanCache: next };
|
|
389
|
+
}),
|
|
353
390
|
// ============ Auto-Scan ============
|
|
354
391
|
autoScanState: DEFAULT_AUTO_SCAN_STATE,
|
|
355
392
|
elementIssuesCache: /* @__PURE__ */ new Map(),
|
|
@@ -419,7 +456,16 @@ var useUILintStore = create()((set, get) => ({
|
|
|
419
456
|
});
|
|
420
457
|
},
|
|
421
458
|
_runScanLoop: async (elements, startIndex) => {
|
|
422
|
-
|
|
459
|
+
const sourceFiles = groupBySourceFile(elements);
|
|
460
|
+
let processedElements = 0;
|
|
461
|
+
let skipElements = startIndex;
|
|
462
|
+
for (const sourceFile of sourceFiles) {
|
|
463
|
+
if (skipElements >= sourceFile.elements.length) {
|
|
464
|
+
skipElements -= sourceFile.elements.length;
|
|
465
|
+
processedElements += sourceFile.elements.length;
|
|
466
|
+
continue;
|
|
467
|
+
}
|
|
468
|
+
skipElements = 0;
|
|
423
469
|
if (get().scanAborted) {
|
|
424
470
|
set({
|
|
425
471
|
scanLock: false,
|
|
@@ -437,16 +483,23 @@ var useUILintStore = create()((set, get) => ({
|
|
|
437
483
|
return;
|
|
438
484
|
}
|
|
439
485
|
}
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
486
|
+
get()._setScanState({ currentIndex: processedElements });
|
|
487
|
+
for (const el of sourceFile.elements) {
|
|
488
|
+
get().updateElementIssue(el.id, {
|
|
489
|
+
elementId: el.id,
|
|
490
|
+
issues: [],
|
|
491
|
+
status: "scanning"
|
|
492
|
+
});
|
|
493
|
+
}
|
|
447
494
|
await new Promise((resolve) => requestAnimationFrame(resolve));
|
|
448
|
-
const
|
|
449
|
-
|
|
495
|
+
const { issues, error } = await scanFileForIssues(sourceFile);
|
|
496
|
+
distributeIssuesToElements(
|
|
497
|
+
issues,
|
|
498
|
+
sourceFile.elements,
|
|
499
|
+
get().updateElementIssue,
|
|
500
|
+
error ?? false
|
|
501
|
+
);
|
|
502
|
+
processedElements += sourceFile.elements.length;
|
|
450
503
|
await new Promise((resolve) => requestAnimationFrame(resolve));
|
|
451
504
|
}
|
|
452
505
|
set({
|
|
@@ -472,6 +525,14 @@ function useEffectiveLocatorTarget() {
|
|
|
472
525
|
}
|
|
473
526
|
|
|
474
527
|
// src/components/ui-lint/UILintProvider.tsx
|
|
528
|
+
import {
|
|
529
|
+
createContext,
|
|
530
|
+
useContext,
|
|
531
|
+
useState,
|
|
532
|
+
useEffect,
|
|
533
|
+
useCallback,
|
|
534
|
+
useMemo
|
|
535
|
+
} from "react";
|
|
475
536
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
476
537
|
var UILintContext = createContext(null);
|
|
477
538
|
function useUILintContext() {
|
|
@@ -522,17 +583,18 @@ function UILintProvider({
|
|
|
522
583
|
const getLocatorTargetFromElement = useCallback(
|
|
523
584
|
(element) => {
|
|
524
585
|
if (element.closest("[data-ui-lint]")) return null;
|
|
525
|
-
let source =
|
|
586
|
+
let source = null;
|
|
526
587
|
let componentStack = [];
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
source = getDebugSource(fiber._debugOwner);
|
|
533
|
-
}
|
|
534
|
-
componentStack = getComponentStack(fiber);
|
|
588
|
+
const fiber = getFiberFromElement(element);
|
|
589
|
+
if (fiber) {
|
|
590
|
+
source = getDebugSource(fiber);
|
|
591
|
+
if (!source && fiber._debugOwner) {
|
|
592
|
+
source = getDebugSource(fiber._debugOwner);
|
|
535
593
|
}
|
|
594
|
+
componentStack = getComponentStack(fiber);
|
|
595
|
+
}
|
|
596
|
+
if (!source) {
|
|
597
|
+
source = getSourceFromDataLoc(element);
|
|
536
598
|
}
|
|
537
599
|
if (!source && componentStack.length === 0) return null;
|
|
538
600
|
if (settings.hideNodeModules && source && isNodeModulesPath(source.fileName)) {
|
|
@@ -583,7 +645,9 @@ function UILintProvider({
|
|
|
583
645
|
);
|
|
584
646
|
const handleLocatorClick = useCallback(
|
|
585
647
|
(e) => {
|
|
586
|
-
if (!altKeyHeld || !effectiveLocatorTarget) return;
|
|
648
|
+
if (!altKeyHeld && !inspectedElement || !effectiveLocatorTarget) return;
|
|
649
|
+
const targetEl = e.target;
|
|
650
|
+
if (targetEl?.closest?.("[data-ui-lint]")) return;
|
|
587
651
|
e.preventDefault();
|
|
588
652
|
e.stopPropagation();
|
|
589
653
|
let source = effectiveLocatorTarget.source;
|
|
@@ -599,16 +663,15 @@ function UILintProvider({
|
|
|
599
663
|
componentStack: effectiveLocatorTarget.componentStack,
|
|
600
664
|
rect: effectiveLocatorTarget.rect
|
|
601
665
|
});
|
|
602
|
-
setAltKeyHeld(false);
|
|
603
666
|
setLocatorTarget(null);
|
|
604
667
|
setLocatorStackIndex(0);
|
|
605
668
|
},
|
|
606
669
|
[
|
|
607
670
|
altKeyHeld,
|
|
608
671
|
effectiveLocatorTarget,
|
|
672
|
+
inspectedElement,
|
|
609
673
|
locatorStackIndex,
|
|
610
674
|
setInspectedElement,
|
|
611
|
-
setAltKeyHeld,
|
|
612
675
|
setLocatorTarget,
|
|
613
676
|
setLocatorStackIndex
|
|
614
677
|
]
|
|
@@ -646,9 +709,7 @@ function UILintProvider({
|
|
|
646
709
|
if (!isBrowser() || !enabled) return;
|
|
647
710
|
if (!altKeyHeld && !inspectedElement) return;
|
|
648
711
|
window.addEventListener("mousemove", handleMouseMove);
|
|
649
|
-
|
|
650
|
-
window.addEventListener("click", handleLocatorClick, true);
|
|
651
|
-
}
|
|
712
|
+
window.addEventListener("click", handleLocatorClick, true);
|
|
652
713
|
return () => {
|
|
653
714
|
window.removeEventListener("mousemove", handleMouseMove);
|
|
654
715
|
window.removeEventListener("click", handleLocatorClick, true);
|
|
@@ -735,10 +796,10 @@ function UILintUI() {
|
|
|
735
796
|
const [components, setComponents] = useState(null);
|
|
736
797
|
useEffect(() => {
|
|
737
798
|
Promise.all([
|
|
738
|
-
import("./UILintToolbar-
|
|
739
|
-
import("./InspectionPanel-
|
|
740
|
-
import("./LocatorOverlay-
|
|
741
|
-
import("./ElementBadges-
|
|
799
|
+
import("./UILintToolbar-GMZ6YSI2.js"),
|
|
800
|
+
import("./InspectionPanel-4OWY4FVY.js"),
|
|
801
|
+
import("./LocatorOverlay-JJDOKNOS.js"),
|
|
802
|
+
import("./ElementBadges-HFQNIIO2.js")
|
|
742
803
|
]).then(([toolbar, panel, locator, badges]) => {
|
|
743
804
|
setComponents({
|
|
744
805
|
Toolbar: toolbar.UILintToolbar,
|
|
@@ -779,6 +840,7 @@ export {
|
|
|
779
840
|
FILE_COLORS,
|
|
780
841
|
DEFAULT_SETTINGS,
|
|
781
842
|
DATA_UILINT_ID,
|
|
843
|
+
useUILintStore,
|
|
782
844
|
useUILintContext,
|
|
783
845
|
UILintProvider
|
|
784
846
|
};
|