uilint-react 0.1.23 → 0.1.25

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,44 +1,5 @@
1
1
  "use client";
2
2
 
3
- // src/components/ui-lint/types.ts
4
- var FILE_COLORS = [
5
- "#3B82F6",
6
- // blue
7
- "#8B5CF6",
8
- // violet
9
- "#EC4899",
10
- // pink
11
- "#10B981",
12
- // emerald
13
- "#F59E0B",
14
- // amber
15
- "#06B6D4",
16
- // cyan
17
- "#EF4444",
18
- // red
19
- "#84CC16",
20
- // lime
21
- "#6366F1",
22
- // indigo
23
- "#F97316",
24
- // orange
25
- "#14B8A6",
26
- // teal
27
- "#A855F7"
28
- // purple
29
- ];
30
- var DEFAULT_SETTINGS = {
31
- hideNodeModules: true,
32
- autoScanEnabled: false
33
- };
34
- var DEFAULT_AUTO_SCAN_STATE = {
35
- status: "idle",
36
- currentIndex: 0,
37
- totalElements: 0,
38
- elements: []
39
- };
40
- var DATA_UILINT_ID = "data-ui-lint-id";
41
-
42
3
  // src/components/ui-lint/fiber-utils.ts
43
4
  var DATA_ATTR = "data-ui-lint-id";
44
5
  var COLORS = [
@@ -66,6 +27,16 @@ var SKIP_TAGS = /* @__PURE__ */ new Set([
66
27
  "LINK"
67
28
  ]);
68
29
  var elementCounter = 0;
30
+ function generateStableId(element, source) {
31
+ const dataLoc = element.getAttribute("data-loc");
32
+ if (dataLoc) {
33
+ return `loc:${dataLoc}`;
34
+ }
35
+ if (source) {
36
+ return `src:${source.fileName}:${source.lineNumber}:${source.columnNumber ?? 0}`;
37
+ }
38
+ return `uilint-${++elementCounter}`;
39
+ }
69
40
  function getFiberFromElement(element) {
70
41
  const keys = Object.keys(element);
71
42
  const fiberKey = keys.find((k) => k.startsWith("__reactFiber$"));
@@ -145,9 +116,6 @@ function shouldSkipElement(element) {
145
116
  if (rect.width === 0 || rect.height === 0) return true;
146
117
  return false;
147
118
  }
148
- function generateElementId() {
149
- return `uilint-${++elementCounter}`;
150
- }
151
119
  function scanDOMForSources(root = document.body, hideNodeModules = true) {
152
120
  const elements = [];
153
121
  elementCounter = 0;
@@ -186,7 +154,7 @@ function scanDOMForSources(root = document.body, hideNodeModules = true) {
186
154
  }
187
155
  }
188
156
  if (source) {
189
- const id = generateElementId();
157
+ const id = generateStableId(node, source);
190
158
  node.setAttribute(DATA_ATTR, id);
191
159
  const scannedElement = {
192
160
  id,
@@ -254,6 +222,45 @@ function buildEditorUrl(source, editor = "cursor") {
254
222
  )}:${lineNumber}:${column}`;
255
223
  }
256
224
 
225
+ // src/components/ui-lint/types.ts
226
+ var FILE_COLORS = [
227
+ "#3B82F6",
228
+ // blue
229
+ "#8B5CF6",
230
+ // violet
231
+ "#EC4899",
232
+ // pink
233
+ "#10B981",
234
+ // emerald
235
+ "#F59E0B",
236
+ // amber
237
+ "#06B6D4",
238
+ // cyan
239
+ "#EF4444",
240
+ // red
241
+ "#84CC16",
242
+ // lime
243
+ "#6366F1",
244
+ // indigo
245
+ "#F97316",
246
+ // orange
247
+ "#14B8A6",
248
+ // teal
249
+ "#A855F7"
250
+ // purple
251
+ ];
252
+ var DEFAULT_SETTINGS = {
253
+ hideNodeModules: true,
254
+ autoScanEnabled: false
255
+ };
256
+ var DEFAULT_AUTO_SCAN_STATE = {
257
+ status: "idle",
258
+ currentIndex: 0,
259
+ totalElements: 0,
260
+ elements: []
261
+ };
262
+ var DATA_UILINT_ID = "data-ui-lint-id";
263
+
257
264
  // src/components/ui-lint/UILintProvider.tsx
258
265
  import {
259
266
  createContext,
@@ -261,9 +268,210 @@ import {
261
268
  useState,
262
269
  useEffect,
263
270
  useCallback,
264
- useMemo,
265
- useRef
271
+ useMemo
266
272
  } from "react";
273
+
274
+ // src/components/ui-lint/store.ts
275
+ import { create } from "zustand";
276
+ async function scanElementForIssues(element) {
277
+ if (!element.source) {
278
+ return {
279
+ elementId: element.id,
280
+ issues: [],
281
+ status: "complete"
282
+ };
283
+ }
284
+ try {
285
+ const sourceResponse = await fetch(
286
+ `/api/.uilint/source?path=${encodeURIComponent(element.source.fileName)}`
287
+ );
288
+ if (!sourceResponse.ok) {
289
+ return {
290
+ elementId: element.id,
291
+ issues: [],
292
+ status: "error"
293
+ };
294
+ }
295
+ const sourceData = await sourceResponse.json();
296
+ const analyzeResponse = await fetch("/api/.uilint/analyze", {
297
+ method: "POST",
298
+ headers: { "Content-Type": "application/json" },
299
+ body: JSON.stringify({
300
+ sourceCode: sourceData.content,
301
+ filePath: sourceData.relativePath || element.source.fileName,
302
+ componentName: element.componentStack[0]?.name || element.tagName,
303
+ componentLine: element.source.lineNumber
304
+ })
305
+ });
306
+ if (!analyzeResponse.ok) {
307
+ return {
308
+ elementId: element.id,
309
+ issues: [],
310
+ status: "error"
311
+ };
312
+ }
313
+ const result = await analyzeResponse.json();
314
+ return {
315
+ elementId: element.id,
316
+ issues: result.issues || [],
317
+ status: "complete"
318
+ };
319
+ } catch {
320
+ return {
321
+ elementId: element.id,
322
+ issues: [],
323
+ status: "error"
324
+ };
325
+ }
326
+ }
327
+ var useUILintStore = create()((set, get) => ({
328
+ // ============ Settings ============
329
+ settings: DEFAULT_SETTINGS,
330
+ updateSettings: (partial) => set((state) => ({
331
+ settings: { ...state.settings, ...partial }
332
+ })),
333
+ // ============ Locator Mode ============
334
+ altKeyHeld: false,
335
+ setAltKeyHeld: (held) => set({ altKeyHeld: held }),
336
+ locatorTarget: null,
337
+ setLocatorTarget: (target) => set({ locatorTarget: target }),
338
+ locatorStackIndex: 0,
339
+ setLocatorStackIndex: (index) => set({ locatorStackIndex: index }),
340
+ locatorGoUp: () => {
341
+ const { locatorTarget, locatorStackIndex } = get();
342
+ if (!locatorTarget) return;
343
+ const maxIndex = locatorTarget.componentStack.length;
344
+ set({ locatorStackIndex: Math.min(locatorStackIndex + 1, maxIndex) });
345
+ },
346
+ locatorGoDown: () => {
347
+ const { locatorStackIndex } = get();
348
+ set({ locatorStackIndex: Math.max(locatorStackIndex - 1, 0) });
349
+ },
350
+ // ============ Inspection ============
351
+ inspectedElement: null,
352
+ setInspectedElement: (el) => set({ inspectedElement: el }),
353
+ // ============ Auto-Scan ============
354
+ autoScanState: DEFAULT_AUTO_SCAN_STATE,
355
+ elementIssuesCache: /* @__PURE__ */ new Map(),
356
+ scanLock: false,
357
+ scanPaused: false,
358
+ scanAborted: false,
359
+ _setScanState: (partial) => set((state) => ({
360
+ autoScanState: { ...state.autoScanState, ...partial }
361
+ })),
362
+ updateElementIssue: (id, issue) => set((state) => {
363
+ const newCache = new Map(state.elementIssuesCache);
364
+ newCache.set(id, issue);
365
+ return { elementIssuesCache: newCache };
366
+ }),
367
+ startAutoScan: async (hideNodeModules) => {
368
+ const state = get();
369
+ if (state.scanLock) {
370
+ console.warn("UILint: Scan already in progress");
371
+ return;
372
+ }
373
+ set({
374
+ scanLock: true,
375
+ scanPaused: false,
376
+ scanAborted: false
377
+ });
378
+ const elements = scanDOMForSources(document.body, hideNodeModules);
379
+ const initialCache = /* @__PURE__ */ new Map();
380
+ for (const el of elements) {
381
+ initialCache.set(el.id, {
382
+ elementId: el.id,
383
+ issues: [],
384
+ status: "pending"
385
+ });
386
+ }
387
+ set({
388
+ elementIssuesCache: initialCache,
389
+ autoScanState: {
390
+ status: "scanning",
391
+ currentIndex: 0,
392
+ totalElements: elements.length,
393
+ elements
394
+ }
395
+ });
396
+ await get()._runScanLoop(elements, 0);
397
+ },
398
+ pauseAutoScan: () => {
399
+ set({ scanPaused: true });
400
+ get()._setScanState({ status: "paused" });
401
+ },
402
+ resumeAutoScan: () => {
403
+ const state = get();
404
+ if (state.autoScanState.status !== "paused") return;
405
+ set({ scanPaused: false });
406
+ get()._setScanState({ status: "scanning" });
407
+ get()._runScanLoop(
408
+ state.autoScanState.elements,
409
+ state.autoScanState.currentIndex
410
+ );
411
+ },
412
+ stopAutoScan: () => {
413
+ set({
414
+ scanAborted: true,
415
+ scanPaused: false,
416
+ scanLock: false,
417
+ autoScanState: DEFAULT_AUTO_SCAN_STATE,
418
+ elementIssuesCache: /* @__PURE__ */ new Map()
419
+ });
420
+ },
421
+ _runScanLoop: async (elements, startIndex) => {
422
+ for (let i = startIndex; i < elements.length; i++) {
423
+ if (get().scanAborted) {
424
+ set({
425
+ scanLock: false,
426
+ autoScanState: { ...get().autoScanState, status: "idle" }
427
+ });
428
+ return;
429
+ }
430
+ while (get().scanPaused) {
431
+ await new Promise((resolve) => setTimeout(resolve, 100));
432
+ if (get().scanAborted) {
433
+ set({
434
+ scanLock: false,
435
+ autoScanState: { ...get().autoScanState, status: "idle" }
436
+ });
437
+ return;
438
+ }
439
+ }
440
+ const element = elements[i];
441
+ get()._setScanState({ currentIndex: i });
442
+ get().updateElementIssue(element.id, {
443
+ elementId: element.id,
444
+ issues: [],
445
+ status: "scanning"
446
+ });
447
+ await new Promise((resolve) => requestAnimationFrame(resolve));
448
+ const result = await scanElementForIssues(element);
449
+ get().updateElementIssue(element.id, result);
450
+ await new Promise((resolve) => requestAnimationFrame(resolve));
451
+ }
452
+ set({
453
+ scanLock: false,
454
+ autoScanState: {
455
+ ...get().autoScanState,
456
+ status: "complete",
457
+ currentIndex: elements.length
458
+ }
459
+ });
460
+ }
461
+ }));
462
+ function useEffectiveLocatorTarget() {
463
+ const locatorTarget = useUILintStore((s) => s.locatorTarget);
464
+ const locatorStackIndex = useUILintStore(
465
+ (s) => s.locatorStackIndex
466
+ );
467
+ if (!locatorTarget) return null;
468
+ return {
469
+ ...locatorTarget,
470
+ stackIndex: locatorStackIndex
471
+ };
472
+ }
473
+
474
+ // src/components/ui-lint/UILintProvider.tsx
267
475
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
268
476
  var UILintContext = createContext(null);
269
477
  function useUILintContext() {
@@ -280,201 +488,37 @@ function UILintProvider({
280
488
  children,
281
489
  enabled = true
282
490
  }) {
283
- const [settings, setSettings] = useState(DEFAULT_SETTINGS);
284
491
  const [isMounted, setIsMounted] = useState(false);
285
- const [altKeyHeld, setAltKeyHeld] = useState(false);
286
- const [locatorTarget, setLocatorTarget] = useState(
287
- null
492
+ const settings = useUILintStore((s) => s.settings);
493
+ const updateSettings = useUILintStore((s) => s.updateSettings);
494
+ const altKeyHeld = useUILintStore((s) => s.altKeyHeld);
495
+ const setAltKeyHeld = useUILintStore((s) => s.setAltKeyHeld);
496
+ const setLocatorTarget = useUILintStore(
497
+ (s) => s.setLocatorTarget
288
498
  );
289
- const [locatorStackIndex, setLocatorStackIndex] = useState(0);
290
- const [inspectedElement, setInspectedElement] = useState(null);
291
- const [autoScanState, setAutoScanState] = useState(
292
- DEFAULT_AUTO_SCAN_STATE
499
+ const locatorStackIndex = useUILintStore(
500
+ (s) => s.locatorStackIndex
293
501
  );
294
- const [elementIssuesCache, setElementIssuesCache] = useState(/* @__PURE__ */ new Map());
295
- const scanPausedRef = useRef(false);
296
- const scanAbortRef = useRef(false);
297
- const updateSettings = useCallback((partial) => {
298
- setSettings((prev) => ({ ...prev, ...partial }));
299
- }, []);
300
- const scanElementForIssues = useCallback(
301
- async (element) => {
302
- if (!element.source) {
303
- return {
304
- elementId: element.id,
305
- issues: [],
306
- status: "complete"
307
- };
308
- }
309
- try {
310
- const sourceResponse = await fetch(
311
- `/api/.uilint/source?path=${encodeURIComponent(
312
- element.source.fileName
313
- )}`
314
- );
315
- if (!sourceResponse.ok) {
316
- return {
317
- elementId: element.id,
318
- issues: [],
319
- status: "error"
320
- };
321
- }
322
- const sourceData = await sourceResponse.json();
323
- const analyzeResponse = await fetch("/api/.uilint/analyze", {
324
- method: "POST",
325
- headers: { "Content-Type": "application/json" },
326
- body: JSON.stringify({
327
- sourceCode: sourceData.content,
328
- filePath: sourceData.relativePath || element.source.fileName,
329
- componentName: element.componentStack[0]?.name || element.tagName,
330
- componentLine: element.source.lineNumber
331
- })
332
- });
333
- if (!analyzeResponse.ok) {
334
- return {
335
- elementId: element.id,
336
- issues: [],
337
- status: "error"
338
- };
339
- }
340
- const result = await analyzeResponse.json();
341
- return {
342
- elementId: element.id,
343
- issues: result.issues || [],
344
- status: "complete"
345
- };
346
- } catch {
347
- return {
348
- elementId: element.id,
349
- issues: [],
350
- status: "error"
351
- };
352
- }
353
- },
354
- []
502
+ const setLocatorStackIndex = useUILintStore(
503
+ (s) => s.setLocatorStackIndex
355
504
  );
356
- const runScanLoop = useCallback(
357
- async (elements, startIndex) => {
358
- const fileToElements = /* @__PURE__ */ new Map();
359
- const scannedFiles = /* @__PURE__ */ new Set();
360
- for (const el of elements) {
361
- if (el.source) {
362
- const file = el.source.fileName;
363
- const existing = fileToElements.get(file) || [];
364
- existing.push(el);
365
- fileToElements.set(file, existing);
366
- }
367
- }
368
- for (let i = startIndex; i < elements.length; i++) {
369
- if (scanAbortRef.current) {
370
- setAutoScanState((prev) => ({ ...prev, status: "idle" }));
371
- return;
372
- }
373
- while (scanPausedRef.current) {
374
- await new Promise((resolve) => setTimeout(resolve, 100));
375
- if (scanAbortRef.current) {
376
- setAutoScanState((prev) => ({ ...prev, status: "idle" }));
377
- return;
378
- }
379
- }
380
- const element = elements[i];
381
- setAutoScanState((prev) => ({
382
- ...prev,
383
- currentIndex: i
384
- }));
385
- if (element.source && scannedFiles.has(element.source.fileName)) {
386
- const existingElements = fileToElements.get(element.source.fileName);
387
- if (existingElements && existingElements.length > 0) {
388
- const firstId = existingElements[0].id;
389
- setElementIssuesCache((prev) => {
390
- const cached = prev.get(firstId);
391
- if (cached) {
392
- const newCache = new Map(prev);
393
- newCache.set(element.id, { ...cached, elementId: element.id });
394
- return newCache;
395
- }
396
- return prev;
397
- });
398
- }
399
- continue;
400
- }
401
- setElementIssuesCache((prev) => {
402
- const newCache = new Map(prev);
403
- newCache.set(element.id, {
404
- elementId: element.id,
405
- issues: [],
406
- status: "scanning"
407
- });
408
- return newCache;
409
- });
410
- const result = await scanElementForIssues(element);
411
- setElementIssuesCache((prev) => {
412
- const newCache = new Map(prev);
413
- newCache.set(element.id, result);
414
- return newCache;
415
- });
416
- if (element.source) {
417
- scannedFiles.add(element.source.fileName);
418
- }
419
- await new Promise((resolve) => setTimeout(resolve, 100));
420
- }
421
- setAutoScanState((prev) => ({
422
- ...prev,
423
- status: "complete",
424
- currentIndex: elements.length
425
- }));
426
- },
427
- [scanElementForIssues]
505
+ const locatorGoUp = useUILintStore((s) => s.locatorGoUp);
506
+ const locatorGoDown = useUILintStore((s) => s.locatorGoDown);
507
+ const inspectedElement = useUILintStore(
508
+ (s) => s.inspectedElement
428
509
  );
429
- const startAutoScan = useCallback(() => {
430
- scanPausedRef.current = false;
431
- scanAbortRef.current = false;
432
- const elements = scanDOMForSources(document.body, settings.hideNodeModules);
433
- const initialCache = /* @__PURE__ */ new Map();
434
- for (const el of elements) {
435
- initialCache.set(el.id, {
436
- elementId: el.id,
437
- issues: [],
438
- status: "pending"
439
- });
440
- }
441
- setElementIssuesCache(initialCache);
442
- setAutoScanState({
443
- status: "scanning",
444
- currentIndex: 0,
445
- totalElements: elements.length,
446
- elements
447
- });
448
- runScanLoop(elements, 0);
449
- }, [settings.hideNodeModules, runScanLoop]);
450
- const pauseAutoScan = useCallback(() => {
451
- scanPausedRef.current = true;
452
- setAutoScanState((prev) => ({ ...prev, status: "paused" }));
453
- }, []);
454
- const resumeAutoScan = useCallback(() => {
455
- scanPausedRef.current = false;
456
- setAutoScanState((prev) => {
457
- if (prev.status === "paused") {
458
- runScanLoop(prev.elements, prev.currentIndex);
459
- return { ...prev, status: "scanning" };
460
- }
461
- return prev;
462
- });
463
- }, [runScanLoop]);
464
- const stopAutoScan = useCallback(() => {
465
- scanAbortRef.current = true;
466
- scanPausedRef.current = false;
467
- setAutoScanState(DEFAULT_AUTO_SCAN_STATE);
468
- setElementIssuesCache(/* @__PURE__ */ new Map());
469
- }, []);
470
- const locatorGoUp = useCallback(() => {
471
- if (!locatorTarget) return;
472
- const maxIndex = locatorTarget.componentStack.length;
473
- setLocatorStackIndex((prev) => Math.min(prev + 1, maxIndex));
474
- }, [locatorTarget]);
475
- const locatorGoDown = useCallback(() => {
476
- setLocatorStackIndex((prev) => Math.max(prev - 1, 0));
477
- }, []);
510
+ const setInspectedElement = useUILintStore(
511
+ (s) => s.setInspectedElement
512
+ );
513
+ const autoScanState = useUILintStore((s) => s.autoScanState);
514
+ const elementIssuesCache = useUILintStore(
515
+ (s) => s.elementIssuesCache
516
+ );
517
+ const startAutoScan = useUILintStore((s) => s.startAutoScan);
518
+ const pauseAutoScan = useUILintStore((s) => s.pauseAutoScan);
519
+ const resumeAutoScan = useUILintStore((s) => s.resumeAutoScan);
520
+ const stopAutoScan = useUILintStore((s) => s.stopAutoScan);
521
+ const effectiveLocatorTarget = useEffectiveLocatorTarget();
478
522
  const getLocatorTargetFromElement = useCallback(
479
523
  (element) => {
480
524
  if (element.closest("[data-ui-lint]")) return null;
@@ -530,31 +574,44 @@ function UILintProvider({
530
574
  }
531
575
  setLocatorTarget(null);
532
576
  },
533
- [altKeyHeld, inspectedElement, getLocatorTargetFromElement]
577
+ [
578
+ altKeyHeld,
579
+ inspectedElement,
580
+ getLocatorTargetFromElement,
581
+ setLocatorTarget
582
+ ]
534
583
  );
535
584
  const handleLocatorClick = useCallback(
536
585
  (e) => {
537
- if (!altKeyHeld || !locatorTarget) return;
586
+ if (!altKeyHeld || !effectiveLocatorTarget) return;
538
587
  e.preventDefault();
539
588
  e.stopPropagation();
540
- let source = locatorTarget.source;
541
- if (locatorStackIndex > 0 && locatorTarget.componentStack.length > 0) {
542
- const stackItem = locatorTarget.componentStack[locatorStackIndex - 1];
589
+ let source = effectiveLocatorTarget.source;
590
+ if (locatorStackIndex > 0 && effectiveLocatorTarget.componentStack.length > 0) {
591
+ const stackItem = effectiveLocatorTarget.componentStack[locatorStackIndex - 1];
543
592
  if (stackItem?.source) {
544
593
  source = stackItem.source;
545
594
  }
546
595
  }
547
596
  setInspectedElement({
548
- element: locatorTarget.element,
597
+ element: effectiveLocatorTarget.element,
549
598
  source,
550
- componentStack: locatorTarget.componentStack,
551
- rect: locatorTarget.rect
599
+ componentStack: effectiveLocatorTarget.componentStack,
600
+ rect: effectiveLocatorTarget.rect
552
601
  });
553
602
  setAltKeyHeld(false);
554
603
  setLocatorTarget(null);
555
604
  setLocatorStackIndex(0);
556
605
  },
557
- [altKeyHeld, locatorTarget, locatorStackIndex]
606
+ [
607
+ altKeyHeld,
608
+ effectiveLocatorTarget,
609
+ locatorStackIndex,
610
+ setInspectedElement,
611
+ setAltKeyHeld,
612
+ setLocatorTarget,
613
+ setLocatorStackIndex
614
+ ]
558
615
  );
559
616
  useEffect(() => {
560
617
  if (!isBrowser() || !enabled) return;
@@ -584,7 +641,7 @@ function UILintProvider({
584
641
  window.removeEventListener("keyup", handleKeyUp);
585
642
  window.removeEventListener("blur", handleBlur);
586
643
  };
587
- }, [enabled]);
644
+ }, [enabled, setAltKeyHeld, setLocatorTarget, setLocatorStackIndex]);
588
645
  useEffect(() => {
589
646
  if (!isBrowser() || !enabled) return;
590
647
  if (!altKeyHeld && !inspectedElement) return;
@@ -606,7 +663,7 @@ function UILintProvider({
606
663
  useEffect(() => {
607
664
  if (!isBrowser() || !enabled || !altKeyHeld) return;
608
665
  const handleWheel = (e) => {
609
- if (!locatorTarget) return;
666
+ if (!effectiveLocatorTarget) return;
610
667
  e.preventDefault();
611
668
  if (e.deltaY > 0) {
612
669
  locatorGoUp();
@@ -616,7 +673,7 @@ function UILintProvider({
616
673
  };
617
674
  window.addEventListener("wheel", handleWheel, { passive: false });
618
675
  return () => window.removeEventListener("wheel", handleWheel);
619
- }, [enabled, altKeyHeld, locatorTarget, locatorGoUp, locatorGoDown]);
676
+ }, [enabled, altKeyHeld, effectiveLocatorTarget, locatorGoUp, locatorGoDown]);
620
677
  useEffect(() => {
621
678
  if (!isBrowser() || !enabled) return;
622
679
  const handleKeyDown = (e) => {
@@ -626,17 +683,13 @@ function UILintProvider({
626
683
  };
627
684
  window.addEventListener("keydown", handleKeyDown);
628
685
  return () => window.removeEventListener("keydown", handleKeyDown);
629
- }, [enabled, inspectedElement]);
686
+ }, [enabled, inspectedElement, setInspectedElement]);
630
687
  useEffect(() => {
631
688
  setIsMounted(true);
632
689
  }, []);
633
- const effectiveLocatorTarget = useMemo(() => {
634
- if (!locatorTarget) return null;
635
- return {
636
- ...locatorTarget,
637
- stackIndex: locatorStackIndex
638
- };
639
- }, [locatorTarget, locatorStackIndex]);
690
+ const wrappedStartAutoScan = useCallback(() => {
691
+ startAutoScan(settings.hideNodeModules);
692
+ }, [startAutoScan, settings.hideNodeModules]);
640
693
  const contextValue = useMemo(
641
694
  () => ({
642
695
  settings,
@@ -649,7 +702,7 @@ function UILintProvider({
649
702
  setInspectedElement,
650
703
  autoScanState,
651
704
  elementIssuesCache,
652
- startAutoScan,
705
+ startAutoScan: wrappedStartAutoScan,
653
706
  pauseAutoScan,
654
707
  resumeAutoScan,
655
708
  stopAutoScan
@@ -662,9 +715,10 @@ function UILintProvider({
662
715
  locatorGoUp,
663
716
  locatorGoDown,
664
717
  inspectedElement,
718
+ setInspectedElement,
665
719
  autoScanState,
666
720
  elementIssuesCache,
667
- startAutoScan,
721
+ wrappedStartAutoScan,
668
722
  pauseAutoScan,
669
723
  resumeAutoScan,
670
724
  stopAutoScan
@@ -681,10 +735,10 @@ function UILintUI() {
681
735
  const [components, setComponents] = useState(null);
682
736
  useEffect(() => {
683
737
  Promise.all([
684
- import("./UILintToolbar-7TFNXFZJ.js"),
685
- import("./InspectionPanel-54HO4UI5.js"),
686
- import("./LocatorOverlay-AXB5VERJ.js"),
687
- import("./ElementBadges-64UOI6QT.js")
738
+ import("./UILintToolbar-57XAWTGK.js"),
739
+ import("./InspectionPanel-FRJB6CJ6.js"),
740
+ import("./LocatorOverlay-O4XZCAPC.js"),
741
+ import("./ElementBadges-2WRRHFLI.js")
688
742
  ]).then(([toolbar, panel, locator, badges]) => {
689
743
  setComponents({
690
744
  Toolbar: toolbar.UILintToolbar,
@@ -710,9 +764,6 @@ function UILintUI() {
710
764
  }
711
765
 
712
766
  export {
713
- FILE_COLORS,
714
- DEFAULT_SETTINGS,
715
- DATA_UILINT_ID,
716
767
  getFiberFromElement,
717
768
  getDebugSource,
718
769
  getDebugOwner,
@@ -725,6 +776,9 @@ export {
725
776
  getElementById,
726
777
  updateElementRects,
727
778
  buildEditorUrl,
779
+ FILE_COLORS,
780
+ DEFAULT_SETTINGS,
781
+ DATA_UILINT_ID,
728
782
  useUILintContext,
729
783
  UILintProvider
730
784
  };