uilint-react 0.1.38 → 0.1.39
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-J2ELN2PU.js → ElementBadges-3AFD2W4Z.js} +48 -15
- package/dist/{InspectionPanel-7N56XBWA.js → InspectionPanel-VAHZBVVL.js} +2 -2
- package/dist/{LocatorOverlay-RDDLASGB.js → LocatorOverlay-BEJYHU6S.js} +2 -2
- package/dist/{UILintToolbar-OQY2V7Q7.js → UILintToolbar-4SH33QJU.js} +2 -2
- package/dist/{chunk-WEBVLQL5.js → chunk-4TLFW7LD.js} +547 -315
- package/dist/{chunk-V4273T5B.js → chunk-7434TUMX.js} +1 -1
- package/dist/{chunk-PU6XPNPN.js → chunk-ILK73X6L.js} +134 -110
- package/dist/{chunk-GZOQ6QWC.js → chunk-NCNRCF5A.js} +1 -1
- package/dist/index.d.ts +23 -17
- package/dist/index.js +4 -4
- package/package.json +2 -2
|
@@ -70,6 +70,7 @@ function shouldSkipElement(element) {
|
|
|
70
70
|
function scanDOMForSources(root = document.body, hideNodeModules = true) {
|
|
71
71
|
const elements = [];
|
|
72
72
|
elementCounter = 0;
|
|
73
|
+
const occurrenceByDataLoc = /* @__PURE__ */ new Map();
|
|
73
74
|
cleanupDataAttributes();
|
|
74
75
|
const locElements = root.querySelectorAll("[data-loc]");
|
|
75
76
|
for (const el of locElements) {
|
|
@@ -80,7 +81,9 @@ function scanDOMForSources(root = document.body, hideNodeModules = true) {
|
|
|
80
81
|
continue;
|
|
81
82
|
}
|
|
82
83
|
const dataLoc = el.getAttribute("data-loc");
|
|
83
|
-
const
|
|
84
|
+
const occurrence = (occurrenceByDataLoc.get(dataLoc) ?? 0) + 1;
|
|
85
|
+
occurrenceByDataLoc.set(dataLoc, occurrence);
|
|
86
|
+
const id = `loc:${dataLoc}#${occurrence}`;
|
|
84
87
|
el.setAttribute(DATA_ATTR, id);
|
|
85
88
|
elements.push({
|
|
86
89
|
id,
|
|
@@ -186,7 +189,8 @@ var DATA_UILINT_ID = "data-ui-lint-id";
|
|
|
186
189
|
import { create } from "zustand";
|
|
187
190
|
function getDataLocFromId(id) {
|
|
188
191
|
if (id.startsWith("loc:")) {
|
|
189
|
-
|
|
192
|
+
const raw = id.slice(4);
|
|
193
|
+
return raw.split("#")[0] || null;
|
|
190
194
|
}
|
|
191
195
|
return null;
|
|
192
196
|
}
|
|
@@ -211,21 +215,25 @@ async function scanFileForIssues(sourceFile, store) {
|
|
|
211
215
|
return { issues };
|
|
212
216
|
}
|
|
213
217
|
function distributeIssuesToElements(issues, elements, updateElementIssue, hasError) {
|
|
214
|
-
const
|
|
218
|
+
const dataLocToElementIds = /* @__PURE__ */ new Map();
|
|
215
219
|
for (const el of elements) {
|
|
216
220
|
const dataLoc = getDataLocFromId(el.id);
|
|
217
221
|
if (dataLoc) {
|
|
218
|
-
|
|
222
|
+
const existing = dataLocToElementIds.get(dataLoc);
|
|
223
|
+
if (existing) existing.push(el.id);
|
|
224
|
+
else dataLocToElementIds.set(dataLoc, [el.id]);
|
|
219
225
|
}
|
|
220
226
|
}
|
|
221
227
|
const issuesByElement = /* @__PURE__ */ new Map();
|
|
222
228
|
for (const issue of issues) {
|
|
223
229
|
if (issue.dataLoc) {
|
|
224
|
-
const
|
|
225
|
-
if (
|
|
226
|
-
const
|
|
227
|
-
|
|
228
|
-
|
|
230
|
+
const elementIds = dataLocToElementIds.get(issue.dataLoc);
|
|
231
|
+
if (elementIds) {
|
|
232
|
+
for (const elementId of elementIds) {
|
|
233
|
+
const existing = issuesByElement.get(elementId) || [];
|
|
234
|
+
existing.push(issue);
|
|
235
|
+
issuesByElement.set(elementId, existing);
|
|
236
|
+
}
|
|
229
237
|
}
|
|
230
238
|
}
|
|
231
239
|
}
|
|
@@ -265,12 +273,11 @@ var useUILintStore = create()((set, get) => ({
|
|
|
265
273
|
// ============ Inspection ============
|
|
266
274
|
inspectedElement: null,
|
|
267
275
|
setInspectedElement: (el) => set({ inspectedElement: el }),
|
|
268
|
-
// ============
|
|
276
|
+
// ============ Live Scanning ============
|
|
277
|
+
liveScanEnabled: false,
|
|
269
278
|
autoScanState: DEFAULT_AUTO_SCAN_STATE,
|
|
270
279
|
elementIssuesCache: /* @__PURE__ */ new Map(),
|
|
271
280
|
scanLock: false,
|
|
272
|
-
scanPaused: false,
|
|
273
|
-
scanAborted: false,
|
|
274
281
|
_setScanState: (partial) => set((state) => ({
|
|
275
282
|
autoScanState: { ...state.autoScanState, ...partial }
|
|
276
283
|
})),
|
|
@@ -279,17 +286,15 @@ var useUILintStore = create()((set, get) => ({
|
|
|
279
286
|
newCache.set(id, issue);
|
|
280
287
|
return { elementIssuesCache: newCache };
|
|
281
288
|
}),
|
|
282
|
-
|
|
289
|
+
enableLiveScan: async (hideNodeModules) => {
|
|
283
290
|
const state = get();
|
|
284
291
|
if (state.scanLock) {
|
|
285
292
|
console.warn("UILint: Scan already in progress");
|
|
286
293
|
return;
|
|
287
294
|
}
|
|
288
295
|
set({
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
scanAborted: false,
|
|
292
|
-
pendingNewElements: 0
|
|
296
|
+
liveScanEnabled: true,
|
|
297
|
+
scanLock: true
|
|
293
298
|
});
|
|
294
299
|
const elements = scanDOMForSources(document.body, hideNodeModules);
|
|
295
300
|
const initialCache = /* @__PURE__ */ new Map();
|
|
@@ -309,60 +314,72 @@ var useUILintStore = create()((set, get) => ({
|
|
|
309
314
|
elements
|
|
310
315
|
}
|
|
311
316
|
});
|
|
312
|
-
await get()._runScanLoop(elements
|
|
313
|
-
},
|
|
314
|
-
pauseAutoScan: () => {
|
|
315
|
-
set({ scanPaused: true });
|
|
316
|
-
get()._setScanState({ status: "paused" });
|
|
317
|
+
await get()._runScanLoop(elements);
|
|
317
318
|
},
|
|
318
|
-
|
|
319
|
-
const state = get();
|
|
320
|
-
if (state.autoScanState.status !== "paused") return;
|
|
321
|
-
set({ scanPaused: false });
|
|
322
|
-
get()._setScanState({ status: "scanning" });
|
|
323
|
-
get()._runScanLoop(
|
|
324
|
-
state.autoScanState.elements,
|
|
325
|
-
state.autoScanState.currentIndex
|
|
326
|
-
);
|
|
327
|
-
},
|
|
328
|
-
stopAutoScan: () => {
|
|
319
|
+
disableLiveScan: () => {
|
|
329
320
|
set({
|
|
330
|
-
|
|
331
|
-
scanPaused: false,
|
|
321
|
+
liveScanEnabled: false,
|
|
332
322
|
scanLock: false,
|
|
333
323
|
autoScanState: DEFAULT_AUTO_SCAN_STATE,
|
|
334
|
-
elementIssuesCache: /* @__PURE__ */ new Map()
|
|
335
|
-
pendingNewElements: 0
|
|
324
|
+
elementIssuesCache: /* @__PURE__ */ new Map()
|
|
336
325
|
});
|
|
337
326
|
},
|
|
338
|
-
|
|
327
|
+
scanNewElements: async (newElements) => {
|
|
328
|
+
const state = get();
|
|
329
|
+
if (!state.liveScanEnabled) return;
|
|
330
|
+
if (newElements.length === 0) return;
|
|
331
|
+
set((s) => {
|
|
332
|
+
const newCache = new Map(s.elementIssuesCache);
|
|
333
|
+
for (const el of newElements) {
|
|
334
|
+
newCache.set(el.id, {
|
|
335
|
+
elementId: el.id,
|
|
336
|
+
issues: [],
|
|
337
|
+
status: "pending"
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
return {
|
|
341
|
+
elementIssuesCache: newCache,
|
|
342
|
+
autoScanState: {
|
|
343
|
+
...s.autoScanState,
|
|
344
|
+
elements: [...s.autoScanState.elements, ...newElements],
|
|
345
|
+
totalElements: s.autoScanState.totalElements + newElements.length
|
|
346
|
+
}
|
|
347
|
+
};
|
|
348
|
+
});
|
|
349
|
+
const sourceFiles = groupBySourceFile(newElements);
|
|
350
|
+
for (const sourceFile of sourceFiles) {
|
|
351
|
+
for (const el of sourceFile.elements) {
|
|
352
|
+
get().updateElementIssue(el.id, {
|
|
353
|
+
elementId: el.id,
|
|
354
|
+
issues: [],
|
|
355
|
+
status: "scanning"
|
|
356
|
+
});
|
|
357
|
+
}
|
|
358
|
+
await new Promise((resolve) => requestAnimationFrame(resolve));
|
|
359
|
+
const { issues, error } = await scanFileForIssues(sourceFile, get());
|
|
360
|
+
distributeIssuesToElements(
|
|
361
|
+
issues,
|
|
362
|
+
sourceFile.elements,
|
|
363
|
+
get().updateElementIssue,
|
|
364
|
+
error ?? false
|
|
365
|
+
);
|
|
366
|
+
if (get().wsConnected && get().wsConnection) {
|
|
367
|
+
get().subscribeToFile(sourceFile.path);
|
|
368
|
+
}
|
|
369
|
+
await new Promise((resolve) => requestAnimationFrame(resolve));
|
|
370
|
+
}
|
|
371
|
+
},
|
|
372
|
+
_runScanLoop: async (elements) => {
|
|
339
373
|
const sourceFiles = groupBySourceFile(elements);
|
|
340
374
|
let processedElements = 0;
|
|
341
|
-
let skipElements = startIndex;
|
|
342
375
|
for (const sourceFile of sourceFiles) {
|
|
343
|
-
if (
|
|
344
|
-
skipElements -= sourceFile.elements.length;
|
|
345
|
-
processedElements += sourceFile.elements.length;
|
|
346
|
-
continue;
|
|
347
|
-
}
|
|
348
|
-
skipElements = 0;
|
|
349
|
-
if (get().scanAborted) {
|
|
376
|
+
if (!get().liveScanEnabled) {
|
|
350
377
|
set({
|
|
351
378
|
scanLock: false,
|
|
352
|
-
autoScanState:
|
|
379
|
+
autoScanState: DEFAULT_AUTO_SCAN_STATE
|
|
353
380
|
});
|
|
354
381
|
return;
|
|
355
382
|
}
|
|
356
|
-
while (get().scanPaused) {
|
|
357
|
-
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
358
|
-
if (get().scanAborted) {
|
|
359
|
-
set({
|
|
360
|
-
scanLock: false,
|
|
361
|
-
autoScanState: { ...get().autoScanState, status: "idle" }
|
|
362
|
-
});
|
|
363
|
-
return;
|
|
364
|
-
}
|
|
365
|
-
}
|
|
366
383
|
get()._setScanState({ currentIndex: processedElements });
|
|
367
384
|
for (const el of sourceFile.elements) {
|
|
368
385
|
get().updateElementIssue(el.id, {
|
|
@@ -394,10 +411,7 @@ var useUILintStore = create()((set, get) => ({
|
|
|
394
411
|
}
|
|
395
412
|
});
|
|
396
413
|
},
|
|
397
|
-
// ============
|
|
398
|
-
pendingNewElements: 0,
|
|
399
|
-
setPendingNewElements: (count) => set({ pendingNewElements: count }),
|
|
400
|
-
clearPendingNewElements: () => set({ pendingNewElements: 0 }),
|
|
414
|
+
// ============ DOM Observer ============
|
|
401
415
|
removeStaleResults: (elementIds) => set((state) => {
|
|
402
416
|
const newCache = new Map(state.elementIssuesCache);
|
|
403
417
|
const newElements = state.autoScanState.elements.filter(
|
|
@@ -415,6 +429,15 @@ var useUILintStore = create()((set, get) => ({
|
|
|
415
429
|
}
|
|
416
430
|
};
|
|
417
431
|
}),
|
|
432
|
+
// ============ File/Element Selection ============
|
|
433
|
+
hoveredFilePath: null,
|
|
434
|
+
selectedFilePath: null,
|
|
435
|
+
selectedElementId: null,
|
|
436
|
+
hoveredElementId: null,
|
|
437
|
+
setHoveredFilePath: (path) => set({ hoveredFilePath: path }),
|
|
438
|
+
setSelectedFilePath: (path) => set({ selectedFilePath: path }),
|
|
439
|
+
setSelectedElementId: (id) => set({ selectedElementId: id }),
|
|
440
|
+
setHoveredElementId: (id) => set({ hoveredElementId: id }),
|
|
418
441
|
// ============ WebSocket ============
|
|
419
442
|
wsConnection: null,
|
|
420
443
|
wsConnected: false,
|
|
@@ -573,7 +596,7 @@ var useUILintStore = create()((set, get) => ({
|
|
|
573
596
|
return { eslintIssuesCache: next };
|
|
574
597
|
});
|
|
575
598
|
const state = get();
|
|
576
|
-
if (state.
|
|
599
|
+
if (state.liveScanEnabled) {
|
|
577
600
|
const sourceFiles = groupBySourceFile(state.autoScanState.elements);
|
|
578
601
|
const sf = sourceFiles.find((s) => s.path === filePath);
|
|
579
602
|
if (sf) {
|
|
@@ -633,7 +656,7 @@ var useUILintStore = create()((set, get) => ({
|
|
|
633
656
|
return { eslintIssuesCache: next };
|
|
634
657
|
});
|
|
635
658
|
const state = get();
|
|
636
|
-
if (state.
|
|
659
|
+
if (state.liveScanEnabled) {
|
|
637
660
|
const sourceFiles = groupBySourceFile(state.autoScanState.elements);
|
|
638
661
|
const sf = sourceFiles.find((s) => s.path === filePath);
|
|
639
662
|
if (sf) {
|
|
@@ -685,50 +708,53 @@ function useDOMObserver(enabled = true) {
|
|
|
685
708
|
const reconcileTimeoutRef = useRef(
|
|
686
709
|
null
|
|
687
710
|
);
|
|
688
|
-
const
|
|
689
|
-
const
|
|
690
|
-
|
|
691
|
-
);
|
|
711
|
+
const knownElementIdsRef = useRef(/* @__PURE__ */ new Set());
|
|
712
|
+
const liveScanEnabled = useUILintStore((s) => s.liveScanEnabled);
|
|
713
|
+
const settings = useUILintStore((s) => s.settings);
|
|
714
|
+
const autoScanState = useUILintStore((s) => s.autoScanState);
|
|
692
715
|
const removeStaleResults = useUILintStore(
|
|
693
716
|
(s) => s.removeStaleResults
|
|
694
717
|
);
|
|
695
|
-
const
|
|
718
|
+
const scanNewElements = useUILintStore((s) => s.scanNewElements);
|
|
696
719
|
useEffect(() => {
|
|
697
|
-
if (autoScanState.
|
|
720
|
+
if (autoScanState.elements.length > 0) {
|
|
698
721
|
const ids = new Set(autoScanState.elements.map((el) => el.id));
|
|
699
|
-
|
|
722
|
+
knownElementIdsRef.current = ids;
|
|
700
723
|
}
|
|
701
|
-
}, [autoScanState.
|
|
724
|
+
}, [autoScanState.elements]);
|
|
702
725
|
const reconcileElements = useCallback(() => {
|
|
703
|
-
|
|
704
|
-
const
|
|
726
|
+
if (!liveScanEnabled) return;
|
|
727
|
+
const currentElements = scanDOMForSources(
|
|
728
|
+
document.body,
|
|
729
|
+
settings.hideNodeModules
|
|
730
|
+
);
|
|
731
|
+
const currentIds = new Set(currentElements.map((el) => el.id));
|
|
732
|
+
const knownIds = knownElementIdsRef.current;
|
|
733
|
+
const newElements = [];
|
|
705
734
|
for (const el of currentElements) {
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
currentIds.add(`loc:${dataLoc}`);
|
|
709
|
-
}
|
|
710
|
-
}
|
|
711
|
-
const lastScanIds = lastScanElementIdsRef.current;
|
|
712
|
-
if (lastScanIds.size === 0) return;
|
|
713
|
-
const newElementIds = [];
|
|
714
|
-
for (const id of currentIds) {
|
|
715
|
-
if (!lastScanIds.has(id)) {
|
|
716
|
-
newElementIds.push(id);
|
|
735
|
+
if (!knownIds.has(el.id)) {
|
|
736
|
+
newElements.push(el);
|
|
717
737
|
}
|
|
718
738
|
}
|
|
719
739
|
const removedElementIds = [];
|
|
720
|
-
for (const id of
|
|
740
|
+
for (const id of knownIds) {
|
|
721
741
|
if (!currentIds.has(id)) {
|
|
722
742
|
removedElementIds.push(id);
|
|
723
743
|
}
|
|
724
744
|
}
|
|
725
|
-
|
|
726
|
-
|
|
745
|
+
knownElementIdsRef.current = currentIds;
|
|
746
|
+
if (newElements.length > 0) {
|
|
747
|
+
scanNewElements(newElements);
|
|
727
748
|
}
|
|
728
749
|
if (removedElementIds.length > 0) {
|
|
729
750
|
removeStaleResults(removedElementIds);
|
|
730
751
|
}
|
|
731
|
-
}, [
|
|
752
|
+
}, [
|
|
753
|
+
liveScanEnabled,
|
|
754
|
+
settings.hideNodeModules,
|
|
755
|
+
scanNewElements,
|
|
756
|
+
removeStaleResults
|
|
757
|
+
]);
|
|
732
758
|
const debouncedReconcile = useCallback(() => {
|
|
733
759
|
if (reconcileTimeoutRef.current) {
|
|
734
760
|
clearTimeout(reconcileTimeoutRef.current);
|
|
@@ -819,14 +845,15 @@ function UILintProvider({
|
|
|
819
845
|
const setInspectedElement = useUILintStore(
|
|
820
846
|
(s) => s.setInspectedElement
|
|
821
847
|
);
|
|
848
|
+
const liveScanEnabled = useUILintStore((s) => s.liveScanEnabled);
|
|
822
849
|
const autoScanState = useUILintStore((s) => s.autoScanState);
|
|
823
850
|
const elementIssuesCache = useUILintStore(
|
|
824
851
|
(s) => s.elementIssuesCache
|
|
825
852
|
);
|
|
826
|
-
const
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
const
|
|
853
|
+
const storeEnableLiveScan = useUILintStore(
|
|
854
|
+
(s) => s.enableLiveScan
|
|
855
|
+
);
|
|
856
|
+
const disableLiveScan = useUILintStore((s) => s.disableLiveScan);
|
|
830
857
|
const connectWebSocket = useUILintStore(
|
|
831
858
|
(s) => s.connectWebSocket
|
|
832
859
|
);
|
|
@@ -961,9 +988,9 @@ function UILintProvider({
|
|
|
961
988
|
disconnectWebSocket();
|
|
962
989
|
};
|
|
963
990
|
}, [enabled, isMounted, connectWebSocket, disconnectWebSocket]);
|
|
964
|
-
const
|
|
965
|
-
|
|
966
|
-
}, [
|
|
991
|
+
const enableLiveScan = useCallback2(() => {
|
|
992
|
+
storeEnableLiveScan(settings.hideNodeModules);
|
|
993
|
+
}, [storeEnableLiveScan, settings.hideNodeModules]);
|
|
967
994
|
const contextValue = useMemo(
|
|
968
995
|
() => ({
|
|
969
996
|
settings,
|
|
@@ -972,12 +999,11 @@ function UILintProvider({
|
|
|
972
999
|
locatorTarget,
|
|
973
1000
|
inspectedElement,
|
|
974
1001
|
setInspectedElement,
|
|
1002
|
+
liveScanEnabled,
|
|
975
1003
|
autoScanState,
|
|
976
1004
|
elementIssuesCache,
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
resumeAutoScan,
|
|
980
|
-
stopAutoScan
|
|
1005
|
+
enableLiveScan,
|
|
1006
|
+
disableLiveScan
|
|
981
1007
|
}),
|
|
982
1008
|
[
|
|
983
1009
|
settings,
|
|
@@ -986,12 +1012,11 @@ function UILintProvider({
|
|
|
986
1012
|
locatorTarget,
|
|
987
1013
|
inspectedElement,
|
|
988
1014
|
setInspectedElement,
|
|
1015
|
+
liveScanEnabled,
|
|
989
1016
|
autoScanState,
|
|
990
1017
|
elementIssuesCache,
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
resumeAutoScan,
|
|
994
|
-
stopAutoScan
|
|
1018
|
+
enableLiveScan,
|
|
1019
|
+
disableLiveScan
|
|
995
1020
|
]
|
|
996
1021
|
);
|
|
997
1022
|
const shouldRenderUI = enabled && isMounted;
|
|
@@ -1001,14 +1026,14 @@ function UILintProvider({
|
|
|
1001
1026
|
] });
|
|
1002
1027
|
}
|
|
1003
1028
|
function UILintUI() {
|
|
1004
|
-
const { altKeyHeld, inspectedElement,
|
|
1029
|
+
const { altKeyHeld, inspectedElement, liveScanEnabled } = useUILintContext();
|
|
1005
1030
|
const [components, setComponents] = useState(null);
|
|
1006
1031
|
useEffect2(() => {
|
|
1007
1032
|
Promise.all([
|
|
1008
|
-
import("./UILintToolbar-
|
|
1009
|
-
import("./InspectionPanel-
|
|
1010
|
-
import("./LocatorOverlay-
|
|
1011
|
-
import("./ElementBadges-
|
|
1033
|
+
import("./UILintToolbar-4SH33QJU.js"),
|
|
1034
|
+
import("./InspectionPanel-VAHZBVVL.js"),
|
|
1035
|
+
import("./LocatorOverlay-BEJYHU6S.js"),
|
|
1036
|
+
import("./ElementBadges-3AFD2W4Z.js")
|
|
1012
1037
|
]).then(([toolbar, panel, locator, badges]) => {
|
|
1013
1038
|
setComponents({
|
|
1014
1039
|
Toolbar: toolbar.UILintToolbar,
|
|
@@ -1021,11 +1046,10 @@ function UILintUI() {
|
|
|
1021
1046
|
}, []);
|
|
1022
1047
|
if (!components) return null;
|
|
1023
1048
|
const { Toolbar, Panel, LocatorOverlay, InspectedHighlight, ElementBadges } = components;
|
|
1024
|
-
const showBadges = autoScanState.status !== "idle";
|
|
1025
1049
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1026
1050
|
/* @__PURE__ */ jsx(Toolbar, {}),
|
|
1027
1051
|
(altKeyHeld || inspectedElement) && /* @__PURE__ */ jsx(LocatorOverlay, {}),
|
|
1028
|
-
|
|
1052
|
+
liveScanEnabled && /* @__PURE__ */ jsx(ElementBadges, {}),
|
|
1029
1053
|
inspectedElement && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1030
1054
|
/* @__PURE__ */ jsx(InspectedHighlight, {}),
|
|
1031
1055
|
/* @__PURE__ */ jsx(Panel, {})
|
package/dist/index.d.ts
CHANGED
|
@@ -19,7 +19,10 @@ interface SourceLocation {
|
|
|
19
19
|
* Source is always present from data-loc attribute
|
|
20
20
|
*/
|
|
21
21
|
interface ScannedElement {
|
|
22
|
-
/**
|
|
22
|
+
/**
|
|
23
|
+
* Unique per-instance ID derived from data-loc.
|
|
24
|
+
* Format: "loc:path:line:column#occurrence"
|
|
25
|
+
*/
|
|
23
26
|
id: string;
|
|
24
27
|
element: Element;
|
|
25
28
|
tagName: string;
|
|
@@ -109,18 +112,16 @@ interface UILintContextValue {
|
|
|
109
112
|
inspectedElement: InspectedElement | null;
|
|
110
113
|
/** Set the element to inspect (opens sidebar) */
|
|
111
114
|
setInspectedElement: (element: InspectedElement | null) => void;
|
|
112
|
-
/**
|
|
115
|
+
/** Whether live scanning is enabled */
|
|
116
|
+
liveScanEnabled: boolean;
|
|
117
|
+
/** Auto-scan state (for progress tracking) */
|
|
113
118
|
autoScanState: AutoScanState;
|
|
114
|
-
/** Cache of element issues from
|
|
119
|
+
/** Cache of element issues from scanning */
|
|
115
120
|
elementIssuesCache: Map<string, ElementIssue>;
|
|
116
|
-
/**
|
|
117
|
-
|
|
118
|
-
/**
|
|
119
|
-
|
|
120
|
-
/** Resume the auto-scan */
|
|
121
|
-
resumeAutoScan: () => void;
|
|
122
|
-
/** Stop and reset the auto-scan */
|
|
123
|
-
stopAutoScan: () => void;
|
|
121
|
+
/** Enable live scanning */
|
|
122
|
+
enableLiveScan: () => void;
|
|
123
|
+
/** Disable live scanning */
|
|
124
|
+
disableLiveScan: () => void;
|
|
124
125
|
}
|
|
125
126
|
/**
|
|
126
127
|
* Props for the UILintProvider component
|
|
@@ -168,17 +169,22 @@ declare function useUILintContext(): UILintContextValue;
|
|
|
168
169
|
declare function UILintProvider({ children, enabled, }: UILintProviderProps): react_jsx_runtime.JSX.Element;
|
|
169
170
|
|
|
170
171
|
/**
|
|
171
|
-
* UILint Toolbar -
|
|
172
|
+
* UILint Toolbar - Three-segment pill for live scanning
|
|
172
173
|
*
|
|
173
174
|
* Design:
|
|
174
|
-
*
|
|
175
|
-
* │ [
|
|
176
|
-
*
|
|
177
|
-
*
|
|
175
|
+
* ┌────────────────────────────────────────┐
|
|
176
|
+
* │ [👁 Toggle] │ [Issues] │ [...] │
|
|
177
|
+
* └────────────────────────────────────────┘
|
|
178
|
+
* ⌥+Click to inspect
|
|
179
|
+
*
|
|
180
|
+
* Segments:
|
|
181
|
+
* 1. Toggle: Enable/disable live scanning mode
|
|
182
|
+
* 2. Issues: Show issue count, opens results panel
|
|
183
|
+
* 3. Settings: Ellipsis for settings popover
|
|
178
184
|
*/
|
|
179
185
|
|
|
180
186
|
/**
|
|
181
|
-
* Main Toolbar Component -
|
|
187
|
+
* Main Toolbar Component - Three-segment pill
|
|
182
188
|
*/
|
|
183
189
|
declare function UILintToolbar(): React$1.ReactPortal | null;
|
|
184
190
|
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import {
|
|
3
3
|
UILintToolbar
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-4TLFW7LD.js";
|
|
5
5
|
import {
|
|
6
6
|
InspectionPanel,
|
|
7
7
|
clearSourceCache,
|
|
@@ -9,10 +9,10 @@ import {
|
|
|
9
9
|
fetchSourceWithContext,
|
|
10
10
|
getCachedSource,
|
|
11
11
|
prefetchSources
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-NCNRCF5A.js";
|
|
13
13
|
import {
|
|
14
14
|
LocatorOverlay
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-7434TUMX.js";
|
|
16
16
|
import {
|
|
17
17
|
DATA_UILINT_ID,
|
|
18
18
|
DEFAULT_SETTINGS,
|
|
@@ -28,7 +28,7 @@ import {
|
|
|
28
28
|
scanDOMForSources,
|
|
29
29
|
updateElementRects,
|
|
30
30
|
useUILintContext
|
|
31
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-ILK73X6L.js";
|
|
32
32
|
|
|
33
33
|
// src/consistency/snapshot.ts
|
|
34
34
|
var DATA_ELEMENTS_ATTR = "data-elements";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "uilint-react",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.39",
|
|
4
4
|
"description": "React component for AI-powered UI consistency checking",
|
|
5
5
|
"author": "Peter Suggate",
|
|
6
6
|
"repository": {
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"node": ">=20.0.0"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"uilint-core": "^0.1.
|
|
37
|
+
"uilint-core": "^0.1.39",
|
|
38
38
|
"zustand": "^5.0.5"
|
|
39
39
|
},
|
|
40
40
|
"peerDependencies": {
|