uilint-react 0.1.29 → 0.1.31

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.
@@ -2,7 +2,7 @@
2
2
  "use client";
3
3
  import {
4
4
  useUILintContext
5
- } from "./chunk-MDEVC3SQ.js";
5
+ } from "./chunk-M3H56XIZ.js";
6
6
 
7
7
  // src/components/ui-lint/ElementBadges.tsx
8
8
  import React, { useState, useEffect, useCallback, useMemo } from "react";
@@ -19,7 +19,9 @@ var DEFAULT_CONFIG = {
19
19
  function computeLayout(positions, config) {
20
20
  if (positions.length === 0) return [];
21
21
  if (positions.length === 1) {
22
- return [{ ...positions[0], nudgedX: positions[0].x, nudgedY: positions[0].y }];
22
+ return [
23
+ { ...positions[0], nudgedX: positions[0].x, nudgedY: positions[0].y }
24
+ ];
23
25
  }
24
26
  const nodes = positions.map((p) => ({
25
27
  position: p,
@@ -2,8 +2,8 @@
2
2
  "use client";
3
3
  import {
4
4
  InspectionPanel
5
- } from "./chunk-LULWI5RD.js";
6
- import "./chunk-MDEVC3SQ.js";
5
+ } from "./chunk-XAAIRXB4.js";
6
+ import "./chunk-M3H56XIZ.js";
7
7
  export {
8
8
  InspectionPanel
9
9
  };
@@ -3,8 +3,8 @@
3
3
  import {
4
4
  InspectedElementHighlight,
5
5
  LocatorOverlay
6
- } from "./chunk-WUEPTJ24.js";
7
- import "./chunk-MDEVC3SQ.js";
6
+ } from "./chunk-OV5BPTNA.js";
7
+ import "./chunk-M3H56XIZ.js";
8
8
  export {
9
9
  InspectedElementHighlight,
10
10
  LocatorOverlay
@@ -2,8 +2,8 @@
2
2
  "use client";
3
3
  import {
4
4
  UILintToolbar
5
- } from "./chunk-PD24RVVC.js";
6
- import "./chunk-MDEVC3SQ.js";
5
+ } from "./chunk-GLJBGFZK.js";
6
+ import "./chunk-M3H56XIZ.js";
7
7
  export {
8
8
  UILintToolbar
9
9
  };
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import {
3
3
  useUILintContext
4
- } from "./chunk-MDEVC3SQ.js";
4
+ } from "./chunk-M3H56XIZ.js";
5
5
 
6
6
  // src/components/ui-lint/UILintToolbar.tsx
7
7
  import { useState, useRef, useEffect } from "react";
@@ -176,14 +176,6 @@ function SettingsPopover({
176
176
  children: "UILint Settings"
177
177
  }
178
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
179
  /* @__PURE__ */ jsxs(
188
180
  "div",
189
181
  {
@@ -432,57 +424,6 @@ function SettingsPopover({
432
424
  }
433
425
  );
434
426
  }
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
427
  function UILintIcon({ active }) {
487
428
  return /* @__PURE__ */ jsxs("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", children: [
488
429
  /* @__PURE__ */ jsx(
@@ -796,10 +796,10 @@ function UILintUI() {
796
796
  const [components, setComponents] = useState(null);
797
797
  useEffect(() => {
798
798
  Promise.all([
799
- import("./UILintToolbar-2FFHUGZF.js"),
800
- import("./InspectionPanel-G6JJNNY4.js"),
801
- import("./LocatorOverlay-MLZ3K4PZ.js"),
802
- import("./ElementBadges-J4QLKPLG.js")
799
+ import("./UILintToolbar-RD6BT3LL.js"),
800
+ import("./InspectionPanel-MUUDJ2BK.js"),
801
+ import("./LocatorOverlay-XJH5TE2J.js"),
802
+ import("./ElementBadges-BSTXYVB7.js")
803
803
  ]).then(([toolbar, panel, locator, badges]) => {
804
804
  setComponents({
805
805
  Toolbar: toolbar.UILintToolbar,
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import {
3
3
  useUILintContext
4
- } from "./chunk-MDEVC3SQ.js";
4
+ } from "./chunk-M3H56XIZ.js";
5
5
 
6
6
  // src/components/ui-lint/LocatorOverlay.tsx
7
7
  import { useState, useEffect, useMemo } from "react";
@@ -3,7 +3,7 @@ import {
3
3
  buildEditorUrl,
4
4
  useUILintContext,
5
5
  useUILintStore
6
- } from "./chunk-MDEVC3SQ.js";
6
+ } from "./chunk-M3H56XIZ.js";
7
7
 
8
8
  // src/components/ui-lint/InspectionPanel.tsx
9
9
  import { useState, useEffect, useCallback, useMemo } from "react";
@@ -570,7 +570,10 @@ function ScanSection({ element }) {
570
570
  const manualScan = useUILintStore(
571
571
  (s) => s.manualScanCache.get(manualKey)
572
572
  );
573
- const upsertManualScan = useUILintStore((s) => s.upsertManualScan);
573
+ const upsertManualScan = useUILintStore(
574
+ (s) => s.upsertManualScan
575
+ );
576
+ const includeChildren = manualScan?.includeChildren ?? false;
574
577
  const componentName = element.componentStack[0]?.name || element.element.tagName.toLowerCase();
575
578
  const componentLine = element.source?.lineNumber;
576
579
  const cachedIssue = useMemo(() => {
@@ -626,6 +629,22 @@ Please update this component to match our styleguide.`;
626
629
  });
627
630
  return;
628
631
  }
632
+ const MAX_DATALOCS = 80;
633
+ const selectedDataLoc = element.element.getAttribute("data-loc");
634
+ let dataLocList = [];
635
+ if (includeChildren) {
636
+ const nodes = [
637
+ element.element,
638
+ ...Array.from(element.element.querySelectorAll("[data-loc]"))
639
+ ];
640
+ for (const n of nodes) {
641
+ const v = n.getAttribute("data-loc");
642
+ if (v) dataLocList.push(v);
643
+ }
644
+ } else if (selectedDataLoc) {
645
+ dataLocList = [selectedDataLoc];
646
+ }
647
+ dataLocList = Array.from(new Set(dataLocList)).slice(0, MAX_DATALOCS);
629
648
  upsertManualScan(manualKey, {
630
649
  status: "scanning",
631
650
  error: void 0,
@@ -645,7 +664,6 @@ Please update this component to match our styleguide.`;
645
664
  const sourceData = await sourceResponse.json();
646
665
  const sourceCode = sourceData.content;
647
666
  const relativePath = sourceData.relativePath || element.source.fileName;
648
- const dataLoc = element.element.getAttribute("data-loc");
649
667
  const analyzeResponse = await fetch("/api/.uilint/analyze", {
650
668
  method: "POST",
651
669
  headers: { "Content-Type": "application/json" },
@@ -654,7 +672,8 @@ Please update this component to match our styleguide.`;
654
672
  filePath: relativePath,
655
673
  componentName,
656
674
  componentLine,
657
- dataLocs: dataLoc ? [dataLoc] : void 0,
675
+ includeChildren,
676
+ dataLocs: dataLocList.length > 0 ? dataLocList : void 0,
658
677
  stream: true
659
678
  })
660
679
  });
@@ -732,20 +751,24 @@ Please update this component to match our styleguide.`;
732
751
  componentLine,
733
752
  generateFixPrompt,
734
753
  manualKey,
735
- upsertManualScan
754
+ upsertManualScan,
755
+ includeChildren
736
756
  ]);
737
- const handleCopy = useCallback(async (text) => {
738
- try {
739
- await navigator.clipboard.writeText(text);
740
- setCopied(true);
741
- setTimeout(() => setCopied(false), 2e3);
742
- } catch {
743
- upsertManualScan(manualKey, {
744
- status: "error",
745
- error: "Failed to copy to clipboard"
746
- });
747
- }
748
- }, [manualKey, upsertManualScan]);
757
+ const handleCopy = useCallback(
758
+ async (text) => {
759
+ try {
760
+ await navigator.clipboard.writeText(text);
761
+ setCopied(true);
762
+ setTimeout(() => setCopied(false), 2e3);
763
+ } catch {
764
+ upsertManualScan(manualKey, {
765
+ status: "error",
766
+ error: "Failed to copy to clipboard"
767
+ });
768
+ }
769
+ },
770
+ [manualKey, upsertManualScan]
771
+ );
749
772
  const manualStatus = manualScan?.status ?? "idle";
750
773
  const showCachedScanning = cachedIssue?.status === "scanning" && manualStatus === "idle";
751
774
  const showCachedPending = cachedIssue?.status === "pending" && manualStatus === "idle";
@@ -757,6 +780,7 @@ Please update this component to match our styleguide.`;
757
780
  const error = manualScan?.status === "error" ? manualScan.error : null;
758
781
  const fixPrompt = manualScan?.fixPrompt ?? null;
759
782
  const progressLine = manualScan?.progressLine ?? null;
783
+ const scopeLabel = includeChildren ? "Element + children" : "Element only";
760
784
  return /* @__PURE__ */ jsx(
761
785
  "div",
762
786
  {
@@ -1025,6 +1049,49 @@ Please update this component to match our styleguide.`;
1025
1049
  ) })
1026
1050
  ] }),
1027
1051
  showScanButton && /* @__PURE__ */ jsxs("div", { style: { textAlign: "center", padding: "16px 0" }, children: [
1052
+ /* @__PURE__ */ jsxs("div", { style: { marginBottom: "10px" }, children: [
1053
+ /* @__PURE__ */ jsxs(
1054
+ "label",
1055
+ {
1056
+ style: {
1057
+ display: "inline-flex",
1058
+ alignItems: "center",
1059
+ gap: "8px",
1060
+ fontSize: "12px",
1061
+ color: STYLES.textMuted,
1062
+ cursor: "pointer",
1063
+ userSelect: "none"
1064
+ },
1065
+ children: [
1066
+ /* @__PURE__ */ jsx(
1067
+ "input",
1068
+ {
1069
+ type: "checkbox",
1070
+ checked: includeChildren,
1071
+ onChange: (e) => upsertManualScan(manualKey, {
1072
+ includeChildren: e.currentTarget.checked
1073
+ })
1074
+ }
1075
+ ),
1076
+ "Include children"
1077
+ ]
1078
+ }
1079
+ ),
1080
+ /* @__PURE__ */ jsxs(
1081
+ "div",
1082
+ {
1083
+ style: {
1084
+ marginTop: "6px",
1085
+ fontSize: "11px",
1086
+ color: STYLES.textDim
1087
+ },
1088
+ children: [
1089
+ "Scope: ",
1090
+ scopeLabel
1091
+ ]
1092
+ }
1093
+ )
1094
+ ] }),
1028
1095
  /* @__PURE__ */ jsxs(
1029
1096
  "button",
1030
1097
  {
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import {
3
3
  UILintToolbar
4
- } from "./chunk-PD24RVVC.js";
4
+ } from "./chunk-GLJBGFZK.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-LULWI5RD.js";
12
+ } from "./chunk-XAAIRXB4.js";
13
13
  import {
14
14
  LocatorOverlay
15
- } from "./chunk-WUEPTJ24.js";
15
+ } from "./chunk-OV5BPTNA.js";
16
16
  import {
17
17
  DATA_UILINT_ID,
18
18
  DEFAULT_SETTINGS,
@@ -31,7 +31,7 @@ import {
31
31
  scanDOMForSources,
32
32
  updateElementRects,
33
33
  useUILintContext
34
- } from "./chunk-MDEVC3SQ.js";
34
+ } from "./chunk-M3H56XIZ.js";
35
35
 
36
36
  // src/consistency/snapshot.ts
37
37
  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.29",
3
+ "version": "0.1.31",
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.29",
37
+ "uilint-core": "^0.1.31",
38
38
  "zustand": "^5.0.5"
39
39
  },
40
40
  "peerDependencies": {