uilint-react 0.1.48 → 0.1.49

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.
@@ -3,7 +3,7 @@
3
3
  import {
4
4
  useUILintContext,
5
5
  useUILintStore
6
- } from "./chunk-C4QQXZFH.js";
6
+ } from "./chunk-N6U5BUAN.js";
7
7
 
8
8
  // src/components/ui-lint/ElementBadges.tsx
9
9
  import React, { useState, useEffect, useCallback, useMemo } from "react";
@@ -130,12 +130,55 @@ function findNearbyBadges(positions, x, y, threshold) {
130
130
  }
131
131
 
132
132
  // src/components/ui-lint/visibility-utils.ts
133
+ function rectFromLTRB(left, top, right, bottom) {
134
+ const width = Math.max(0, right - left);
135
+ const height = Math.max(0, bottom - top);
136
+ return { left, top, right, bottom, width, height };
137
+ }
138
+ function intersectRects(a, b) {
139
+ const left = Math.max(a.left, b.left);
140
+ const top = Math.max(a.top, b.top);
141
+ const right = Math.min(a.right, b.right);
142
+ const bottom = Math.min(a.bottom, b.bottom);
143
+ if (right <= left || bottom <= top) return null;
144
+ return rectFromLTRB(left, top, right, bottom);
145
+ }
146
+ function isOverflowClipping(style) {
147
+ const vals = [style.overflow, style.overflowX, style.overflowY];
148
+ return vals.some((v) => v && v !== "visible");
149
+ }
150
+ function getElementVisibleRect(element) {
151
+ const el = element;
152
+ const base = el.getBoundingClientRect();
153
+ let visible = rectFromLTRB(
154
+ base.left,
155
+ base.top,
156
+ base.right,
157
+ base.bottom
158
+ );
159
+ const viewport = rectFromLTRB(0, 0, window.innerWidth, window.innerHeight);
160
+ visible = intersectRects(visible, viewport);
161
+ if (!visible) return null;
162
+ let cur = el.parentElement;
163
+ while (cur) {
164
+ const style = window.getComputedStyle(cur);
165
+ if (isOverflowClipping(style)) {
166
+ const r = cur.getBoundingClientRect();
167
+ const clip = rectFromLTRB(r.left, r.top, r.right, r.bottom);
168
+ visible = intersectRects(visible, clip);
169
+ if (!visible) return null;
170
+ }
171
+ cur = cur.parentElement;
172
+ }
173
+ return visible;
174
+ }
133
175
  function isElementCoveredByOverlay(element, badgeX, badgeY) {
134
176
  const elementsAtPoint = document.elementsFromPoint(badgeX, badgeY);
135
177
  for (const el of elementsAtPoint) {
136
178
  if (el.hasAttribute("data-ui-lint")) continue;
137
- if (el === element || element.contains(el)) continue;
138
- if (el.contains(element)) continue;
179
+ if (el === element || element.contains(el) || el.contains(element)) {
180
+ return false;
181
+ }
139
182
  const style = window.getComputedStyle(el);
140
183
  const position = style.position;
141
184
  const zIndex = parseInt(style.zIndex, 10);
@@ -270,14 +313,24 @@ function ElementBadges() {
270
313
  if (!issue) continue;
271
314
  if (!element.element || !document.contains(element.element)) continue;
272
315
  const rect = element.element.getBoundingClientRect();
273
- const x = rect.right - 8;
274
- const y = rect.top - 8;
275
- if (rect.top < -50 || rect.top > window.innerHeight + 50) continue;
276
- if (rect.left < -50 || rect.left > window.innerWidth + 50) continue;
277
- if (isElementCoveredByOverlay(element.element, x, y)) {
316
+ const visible = getElementVisibleRect(element.element);
317
+ if (!visible) continue;
318
+ const desiredX = rect.right - 8;
319
+ const desiredY = rect.top - 8;
320
+ const x = Math.min(desiredX, visible.right - 8);
321
+ const y = Math.max(visible.top + 2, desiredY);
322
+ const testX = visible.left + Math.min(8, visible.width / 2);
323
+ const testY = visible.top + Math.min(8, visible.height / 2);
324
+ if (isElementCoveredByOverlay(element.element, testX, testY)) {
278
325
  continue;
279
326
  }
280
- positions.push({ element, issue, x, y, rect });
327
+ const visibleRect = DOMRect.fromRect({
328
+ x: visible.left,
329
+ y: visible.top,
330
+ width: visible.width,
331
+ height: visible.height
332
+ });
333
+ positions.push({ element, issue, x, y, rect: visibleRect });
281
334
  }
282
335
  setBadgePositions(positions);
283
336
  };
@@ -2,9 +2,9 @@
2
2
  "use client";
3
3
  import {
4
4
  InspectionPanel
5
- } from "./chunk-B7DZUX7G.js";
5
+ } from "./chunk-2BV2MBAM.js";
6
6
  import "./chunk-S4IWHBOQ.js";
7
- import "./chunk-C4QQXZFH.js";
7
+ import "./chunk-N6U5BUAN.js";
8
8
  export {
9
9
  InspectionPanel
10
10
  };
@@ -3,8 +3,8 @@
3
3
  import {
4
4
  InspectedElementHighlight,
5
5
  LocatorOverlay
6
- } from "./chunk-VKLP23BP.js";
7
- import "./chunk-C4QQXZFH.js";
6
+ } from "./chunk-IRG3I75F.js";
7
+ import "./chunk-N6U5BUAN.js";
8
8
  export {
9
9
  InspectedElementHighlight,
10
10
  LocatorOverlay
@@ -2,9 +2,9 @@
2
2
  "use client";
3
3
  import {
4
4
  UILintToolbar
5
- } from "./chunk-FLUATYJF.js";
5
+ } from "./chunk-URAH2PAM.js";
6
6
  import "./chunk-S4IWHBOQ.js";
7
- import "./chunk-C4QQXZFH.js";
7
+ import "./chunk-N6U5BUAN.js";
8
8
  export {
9
9
  UILintToolbar
10
10
  };
@@ -7,7 +7,7 @@ import {
7
7
  buildEditorUrl,
8
8
  useUILintContext,
9
9
  useUILintStore
10
- } from "./chunk-C4QQXZFH.js";
10
+ } from "./chunk-N6U5BUAN.js";
11
11
 
12
12
  // src/components/ui-lint/InspectionPanel.tsx
13
13
  import React, {
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import {
3
3
  useUILintContext
4
- } from "./chunk-C4QQXZFH.js";
4
+ } from "./chunk-N6U5BUAN.js";
5
5
 
6
6
  // src/components/ui-lint/LocatorOverlay.tsx
7
7
  import { useState, useEffect, useMemo } from "react";
@@ -1063,10 +1063,10 @@ function UILintUI() {
1063
1063
  const [components, setComponents] = useState(null);
1064
1064
  useEffect2(() => {
1065
1065
  Promise.all([
1066
- import("./UILintToolbar-ZBHPX3LA.js"),
1067
- import("./InspectionPanel-PHCAOOL3.js"),
1068
- import("./LocatorOverlay-ZGBYXTXG.js"),
1069
- import("./ElementBadges-TSHIYUHQ.js")
1066
+ import("./UILintToolbar-OQ44CM63.js"),
1067
+ import("./InspectionPanel-FKDEPTX7.js"),
1068
+ import("./LocatorOverlay-W33BHLRE.js"),
1069
+ import("./ElementBadges-TPLIZJA5.js")
1070
1070
  ]).then(([toolbar, panel, locator, badges]) => {
1071
1071
  setComponents({
1072
1072
  Toolbar: toolbar.UILintToolbar,
@@ -9,7 +9,7 @@ import {
9
9
  groupBySourceFile,
10
10
  useUILintContext,
11
11
  useUILintStore
12
- } from "./chunk-C4QQXZFH.js";
12
+ } from "./chunk-N6U5BUAN.js";
13
13
 
14
14
  // src/components/ui-lint/UILintToolbar.tsx
15
15
  import React3, { useState as useState2, useRef as useRef2, useEffect as useEffect3, useCallback as useCallback2 } from "react";
package/dist/index.js CHANGED
@@ -1,10 +1,10 @@
1
1
  "use client";
2
2
  import {
3
3
  UILintToolbar
4
- } from "./chunk-FLUATYJF.js";
4
+ } from "./chunk-URAH2PAM.js";
5
5
  import {
6
6
  InspectionPanel
7
- } from "./chunk-B7DZUX7G.js";
7
+ } from "./chunk-2BV2MBAM.js";
8
8
  import {
9
9
  clearSourceCache,
10
10
  fetchSource,
@@ -14,7 +14,7 @@ import {
14
14
  } from "./chunk-S4IWHBOQ.js";
15
15
  import {
16
16
  LocatorOverlay
17
- } from "./chunk-VKLP23BP.js";
17
+ } from "./chunk-IRG3I75F.js";
18
18
  import {
19
19
  DATA_UILINT_ID,
20
20
  DEFAULT_SETTINGS,
@@ -30,7 +30,7 @@ import {
30
30
  scanDOMForSources,
31
31
  updateElementRects,
32
32
  useUILintContext
33
- } from "./chunk-C4QQXZFH.js";
33
+ } from "./chunk-N6U5BUAN.js";
34
34
 
35
35
  // src/consistency/snapshot.ts
36
36
  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.48",
3
+ "version": "0.1.49",
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.48",
37
+ "uilint-core": "^0.1.49",
38
38
  "zustand": "^5.0.5"
39
39
  },
40
40
  "peerDependencies": {