uilint-react 0.1.19 → 0.1.21
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/README.md +50 -93
- package/dist/{InspectionPanel-6DBGEWWD.js → InspectionPanel-ZBDXQ2LU.js} +2 -2
- package/dist/LocatorOverlay-3H446RPO.js +11 -0
- package/dist/{UILintToolbar-7ZYCQC4M.js → UILintToolbar-C6HOAJA4.js} +2 -2
- package/dist/{chunk-KUFV22FO.js → chunk-3DNDKMZ4.js} +72 -2
- package/dist/{chunk-3TA6OKS6.js → chunk-CWCKS753.js} +417 -90
- package/dist/{chunk-7WYVWDRU.js → chunk-EBU7YY73.js} +53 -218
- package/dist/chunk-GUF36FGA.js +276 -0
- package/dist/index.d.ts +26 -65
- package/dist/index.js +33 -1097
- package/package.json +2 -2
- package/dist/LocatorOverlay-FQEYAMT6.js +0 -9
- package/dist/SourceOverlays-2SEINA2B.js +0 -9
- package/dist/chunk-MEP7WO7U.js +0 -210
- package/dist/chunk-OWX36QE3.js +0 -595
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "uilint-react",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.21",
|
|
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.21"
|
|
38
38
|
},
|
|
39
39
|
"peerDependencies": {
|
|
40
40
|
"react": "^19.0.0",
|
package/dist/chunk-MEP7WO7U.js
DELETED
|
@@ -1,210 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import {
|
|
3
|
-
buildEditorUrl,
|
|
4
|
-
useUILintContext
|
|
5
|
-
} from "./chunk-7WYVWDRU.js";
|
|
6
|
-
|
|
7
|
-
// src/components/ui-lint/SourceOverlays.tsx
|
|
8
|
-
import { useState, useEffect, useMemo, useCallback } from "react";
|
|
9
|
-
import { createPortal } from "react-dom";
|
|
10
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
11
|
-
var STYLES = {
|
|
12
|
-
font: 'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
|
|
13
|
-
fontMono: 'ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace',
|
|
14
|
-
shadow: "0 2px 8px rgba(0, 0, 0, 0.3)"
|
|
15
|
-
};
|
|
16
|
-
function getLabelPositionStyles(position) {
|
|
17
|
-
switch (position) {
|
|
18
|
-
case "top-left":
|
|
19
|
-
return { top: "-1px", left: "-1px" };
|
|
20
|
-
case "top-right":
|
|
21
|
-
return { top: "-1px", right: "-1px" };
|
|
22
|
-
case "bottom-left":
|
|
23
|
-
return { bottom: "-1px", left: "-1px" };
|
|
24
|
-
case "bottom-right":
|
|
25
|
-
return { bottom: "-1px", right: "-1px" };
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
function SourceOverlays() {
|
|
29
|
-
const {
|
|
30
|
-
sourceFiles,
|
|
31
|
-
scannedElements,
|
|
32
|
-
settings,
|
|
33
|
-
selectedElement,
|
|
34
|
-
setSelectedElement,
|
|
35
|
-
hoveredElement,
|
|
36
|
-
setHoveredElement,
|
|
37
|
-
mode
|
|
38
|
-
} = useUILintContext();
|
|
39
|
-
const [mounted, setMounted] = useState(false);
|
|
40
|
-
useEffect(() => {
|
|
41
|
-
setMounted(true);
|
|
42
|
-
}, []);
|
|
43
|
-
const elementToFile = useMemo(() => {
|
|
44
|
-
const map = /* @__PURE__ */ new Map();
|
|
45
|
-
for (const file of sourceFiles) {
|
|
46
|
-
for (const element of file.elements) {
|
|
47
|
-
map.set(element.id, file);
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
return map;
|
|
51
|
-
}, [sourceFiles]);
|
|
52
|
-
const handleElementClick = useCallback(
|
|
53
|
-
(element) => {
|
|
54
|
-
if (mode === "inspect") {
|
|
55
|
-
setSelectedElement(
|
|
56
|
-
selectedElement?.id === element.id ? null : element
|
|
57
|
-
);
|
|
58
|
-
}
|
|
59
|
-
},
|
|
60
|
-
[mode, selectedElement, setSelectedElement]
|
|
61
|
-
);
|
|
62
|
-
const handleLabelClick = useCallback(
|
|
63
|
-
(element, e) => {
|
|
64
|
-
e.stopPropagation();
|
|
65
|
-
if (element.source) {
|
|
66
|
-
const url = buildEditorUrl(element.source, "cursor");
|
|
67
|
-
window.open(url, "_blank");
|
|
68
|
-
}
|
|
69
|
-
},
|
|
70
|
-
[]
|
|
71
|
-
);
|
|
72
|
-
if (!mounted) return null;
|
|
73
|
-
const content = /* @__PURE__ */ jsxs("div", { "data-ui-lint": true, style: { pointerEvents: "none" }, children: [
|
|
74
|
-
/* @__PURE__ */ jsx("style", { children: `
|
|
75
|
-
@keyframes uilint-overlay-fade-in {
|
|
76
|
-
from { opacity: 0; }
|
|
77
|
-
to { opacity: 1; }
|
|
78
|
-
}
|
|
79
|
-
` }),
|
|
80
|
-
scannedElements.map((element) => {
|
|
81
|
-
const file = elementToFile.get(element.id);
|
|
82
|
-
if (!file) return null;
|
|
83
|
-
const isSelected = selectedElement?.id === element.id;
|
|
84
|
-
const isHovered = hoveredElement?.id === element.id;
|
|
85
|
-
return /* @__PURE__ */ jsx(
|
|
86
|
-
ElementOverlay,
|
|
87
|
-
{
|
|
88
|
-
element,
|
|
89
|
-
file,
|
|
90
|
-
settings,
|
|
91
|
-
isSelected,
|
|
92
|
-
isHovered,
|
|
93
|
-
onHover: () => setHoveredElement(element),
|
|
94
|
-
onLeave: () => setHoveredElement(null),
|
|
95
|
-
onClick: () => handleElementClick(element),
|
|
96
|
-
onLabelClick: (e) => handleLabelClick(element, e),
|
|
97
|
-
showClickable: mode === "inspect"
|
|
98
|
-
},
|
|
99
|
-
element.id
|
|
100
|
-
);
|
|
101
|
-
})
|
|
102
|
-
] });
|
|
103
|
-
return createPortal(content, document.body);
|
|
104
|
-
}
|
|
105
|
-
function ElementOverlay({
|
|
106
|
-
element,
|
|
107
|
-
file,
|
|
108
|
-
settings,
|
|
109
|
-
isSelected,
|
|
110
|
-
isHovered,
|
|
111
|
-
onHover,
|
|
112
|
-
onLeave,
|
|
113
|
-
onClick,
|
|
114
|
-
onLabelClick,
|
|
115
|
-
showClickable
|
|
116
|
-
}) {
|
|
117
|
-
const { rect } = element;
|
|
118
|
-
if (rect.width < 20 || rect.height < 20) return null;
|
|
119
|
-
if (rect.bottom < 0 || rect.top > window.innerHeight || rect.right < 0 || rect.left > window.innerWidth) {
|
|
120
|
-
return null;
|
|
121
|
-
}
|
|
122
|
-
const borderWidth = isSelected ? 3 : isHovered ? 2 : 1.5;
|
|
123
|
-
return /* @__PURE__ */ jsx(
|
|
124
|
-
"div",
|
|
125
|
-
{
|
|
126
|
-
style: {
|
|
127
|
-
position: "fixed",
|
|
128
|
-
top: rect.top,
|
|
129
|
-
left: rect.left,
|
|
130
|
-
width: rect.width,
|
|
131
|
-
height: rect.height,
|
|
132
|
-
border: `${borderWidth}px solid ${file.color}`,
|
|
133
|
-
borderRadius: "2px",
|
|
134
|
-
pointerEvents: showClickable ? "auto" : "none",
|
|
135
|
-
cursor: showClickable ? "pointer" : "default",
|
|
136
|
-
zIndex: isSelected ? 99998 : isHovered ? 99997 : 99996,
|
|
137
|
-
animation: "uilint-overlay-fade-in 0.15s ease-out",
|
|
138
|
-
transition: "border-width 0.15s"
|
|
139
|
-
},
|
|
140
|
-
onMouseEnter: onHover,
|
|
141
|
-
onMouseLeave: onLeave,
|
|
142
|
-
onClick,
|
|
143
|
-
children: settings.showLabels && /* @__PURE__ */ jsx(
|
|
144
|
-
FileLabel,
|
|
145
|
-
{
|
|
146
|
-
file,
|
|
147
|
-
element,
|
|
148
|
-
position: settings.labelPosition,
|
|
149
|
-
isHovered,
|
|
150
|
-
isSelected,
|
|
151
|
-
onClick: onLabelClick
|
|
152
|
-
}
|
|
153
|
-
)
|
|
154
|
-
}
|
|
155
|
-
);
|
|
156
|
-
}
|
|
157
|
-
function FileLabel({
|
|
158
|
-
file,
|
|
159
|
-
element,
|
|
160
|
-
position,
|
|
161
|
-
isHovered,
|
|
162
|
-
isSelected,
|
|
163
|
-
onClick
|
|
164
|
-
}) {
|
|
165
|
-
const [showFullPath, setShowFullPath] = useState(false);
|
|
166
|
-
const positionStyles = getLabelPositionStyles(position);
|
|
167
|
-
const displayName = file.displayName.length > 20 ? file.displayName.slice(0, 17) + "..." : file.displayName;
|
|
168
|
-
return /* @__PURE__ */ jsxs(
|
|
169
|
-
"div",
|
|
170
|
-
{
|
|
171
|
-
style: {
|
|
172
|
-
position: "absolute",
|
|
173
|
-
...positionStyles,
|
|
174
|
-
display: "flex",
|
|
175
|
-
alignItems: "center",
|
|
176
|
-
gap: "4px",
|
|
177
|
-
padding: "2px 6px",
|
|
178
|
-
borderRadius: "3px",
|
|
179
|
-
backgroundColor: file.color,
|
|
180
|
-
color: "#FFFFFF",
|
|
181
|
-
fontSize: "10px",
|
|
182
|
-
fontWeight: 600,
|
|
183
|
-
fontFamily: STYLES.fontMono,
|
|
184
|
-
whiteSpace: "nowrap",
|
|
185
|
-
pointerEvents: "auto",
|
|
186
|
-
cursor: "pointer",
|
|
187
|
-
boxShadow: STYLES.shadow,
|
|
188
|
-
transition: "transform 0.1s, padding 0.1s",
|
|
189
|
-
transform: isHovered || isSelected ? "scale(1.05)" : "scale(1)",
|
|
190
|
-
zIndex: 99999
|
|
191
|
-
},
|
|
192
|
-
onMouseEnter: () => setShowFullPath(true),
|
|
193
|
-
onMouseLeave: () => setShowFullPath(false),
|
|
194
|
-
onClick,
|
|
195
|
-
title: `${file.path}:${element.source?.lineNumber || "?"}
|
|
196
|
-
Click to open in editor`,
|
|
197
|
-
children: [
|
|
198
|
-
/* @__PURE__ */ jsx("span", { children: displayName }),
|
|
199
|
-
element.source?.lineNumber && /* @__PURE__ */ jsxs("span", { style: { opacity: 0.8, fontSize: "9px" }, children: [
|
|
200
|
-
":",
|
|
201
|
-
element.source.lineNumber
|
|
202
|
-
] })
|
|
203
|
-
]
|
|
204
|
-
}
|
|
205
|
-
);
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
export {
|
|
209
|
-
SourceOverlays
|
|
210
|
-
};
|