made-refine 0.2.11 → 0.2.15
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/index.d.mts +4 -3
- package/dist/index.d.ts +4 -3
- package/dist/index.js +411 -62
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +411 -62
- package/dist/index.mjs.map +1 -1
- package/dist/{utils-Dn_oW8f_.d.mts → utils-lksVP2Wq.d.mts} +14 -1
- package/dist/{utils-Dn_oW8f_.d.ts → utils-lksVP2Wq.d.ts} +14 -1
- package/dist/utils.d.mts +1 -1
- package/dist/utils.d.ts +1 -1
- package/dist/utils.js +222 -20
- package/dist/utils.js.map +1 -1
- package/dist/utils.mjs +220 -20
- package/dist/utils.mjs.map +1 -1
- package/package.json +1 -1
package/dist/utils.mjs
CHANGED
|
@@ -40,6 +40,122 @@ function getZoomScale() {
|
|
|
40
40
|
return snap.active ? snap.zoom : 1;
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
+
// src/utils/react-fiber.ts
|
|
44
|
+
var EXCLUDED_PROP_KEYS = /* @__PURE__ */ new Set([
|
|
45
|
+
"className",
|
|
46
|
+
"style",
|
|
47
|
+
"children",
|
|
48
|
+
"ref",
|
|
49
|
+
"key",
|
|
50
|
+
"render"
|
|
51
|
+
]);
|
|
52
|
+
function serializePropValue(value) {
|
|
53
|
+
if (typeof value === "function") return "[function]";
|
|
54
|
+
if (typeof value === "symbol") return void 0;
|
|
55
|
+
if (value === void 0) return void 0;
|
|
56
|
+
if (value !== null && typeof value === "object") {
|
|
57
|
+
if ("$$typeof" in value) return "[element]";
|
|
58
|
+
try {
|
|
59
|
+
JSON.stringify(value);
|
|
60
|
+
return value;
|
|
61
|
+
} catch {
|
|
62
|
+
return "[object]";
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return value;
|
|
66
|
+
}
|
|
67
|
+
function getComponentProps(fiber) {
|
|
68
|
+
const props = fiber?.memoizedProps ?? fiber?.pendingProps;
|
|
69
|
+
if (!props || typeof props !== "object") return {};
|
|
70
|
+
const result = {};
|
|
71
|
+
for (const [key, value] of Object.entries(props)) {
|
|
72
|
+
if (EXCLUDED_PROP_KEYS.has(key)) continue;
|
|
73
|
+
if (key.startsWith("data-")) continue;
|
|
74
|
+
const serialized = serializePropValue(value);
|
|
75
|
+
if (serialized !== void 0) {
|
|
76
|
+
result[key] = serialized;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return result;
|
|
80
|
+
}
|
|
81
|
+
function getCallSiteSource(fiber) {
|
|
82
|
+
const source = fiber?._debugSource;
|
|
83
|
+
if (source?.fileName) {
|
|
84
|
+
return {
|
|
85
|
+
file: source.fileName,
|
|
86
|
+
line: typeof source.lineNumber === "number" ? source.lineNumber : void 0,
|
|
87
|
+
column: typeof source.columnNumber === "number" ? source.columnNumber : void 0
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
const pending = fiber?.pendingProps?.__source;
|
|
91
|
+
if (pending?.fileName) {
|
|
92
|
+
return {
|
|
93
|
+
file: pending.fileName,
|
|
94
|
+
line: typeof pending.lineNumber === "number" ? pending.lineNumber : void 0,
|
|
95
|
+
column: typeof pending.columnNumber === "number" ? pending.columnNumber : void 0
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
function deriveDefinitionSource(frames) {
|
|
101
|
+
for (const frame of frames) {
|
|
102
|
+
if (frame.file && isComponentPrimitivePath(frame.file)) {
|
|
103
|
+
return { file: frame.file, line: frame.line, column: frame.column };
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return null;
|
|
107
|
+
}
|
|
108
|
+
var PRIMITIVE_PATH_PATTERNS = [
|
|
109
|
+
/\/components\/ui\//,
|
|
110
|
+
/\/ui\/primitives\//,
|
|
111
|
+
/\/design-system\//
|
|
112
|
+
];
|
|
113
|
+
var PRIMITIVE_NPM_PATTERNS = [
|
|
114
|
+
/@base-ui\//,
|
|
115
|
+
/@radix-ui\//,
|
|
116
|
+
/@headlessui\//,
|
|
117
|
+
/@chakra-ui\//,
|
|
118
|
+
/@mantine\//,
|
|
119
|
+
/@mui\//,
|
|
120
|
+
/@ark-ui\//
|
|
121
|
+
];
|
|
122
|
+
var FRAMEWORK_EXCLUSION_PATTERNS = [
|
|
123
|
+
/node_modules\/react\//,
|
|
124
|
+
/node_modules\/react-dom\//,
|
|
125
|
+
/node_modules\/next\/dist\//,
|
|
126
|
+
/node_modules\/scheduler\//,
|
|
127
|
+
/node_modules\/react-server\//
|
|
128
|
+
];
|
|
129
|
+
function isComponentPrimitivePath(filePath) {
|
|
130
|
+
const normalized = filePath.replace(/\\/g, "/");
|
|
131
|
+
for (const pattern of FRAMEWORK_EXCLUSION_PATTERNS) {
|
|
132
|
+
if (pattern.test(normalized)) return false;
|
|
133
|
+
}
|
|
134
|
+
for (const pattern of PRIMITIVE_NPM_PATTERNS) {
|
|
135
|
+
if (pattern.test(normalized)) return true;
|
|
136
|
+
}
|
|
137
|
+
for (const pattern of PRIMITIVE_PATH_PATTERNS) {
|
|
138
|
+
if (pattern.test(normalized)) return true;
|
|
139
|
+
}
|
|
140
|
+
return false;
|
|
141
|
+
}
|
|
142
|
+
function classifyComponentFiber(fiber, frames, elementSourceFile) {
|
|
143
|
+
if (elementSourceFile && isComponentPrimitivePath(elementSourceFile)) {
|
|
144
|
+
return { isComponentPrimitive: true };
|
|
145
|
+
}
|
|
146
|
+
if (!fiber) return { isComponentPrimitive: false };
|
|
147
|
+
const callSite = getCallSiteSource(fiber);
|
|
148
|
+
if (callSite?.file && isComponentPrimitivePath(callSite.file)) {
|
|
149
|
+
return { isComponentPrimitive: true };
|
|
150
|
+
}
|
|
151
|
+
for (const frame of frames) {
|
|
152
|
+
if (frame.file && isComponentPrimitivePath(frame.file)) {
|
|
153
|
+
return { isComponentPrimitive: true };
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
return { isComponentPrimitive: false };
|
|
157
|
+
}
|
|
158
|
+
|
|
43
159
|
// src/utils.ts
|
|
44
160
|
function clamp(value, min, max) {
|
|
45
161
|
if (!Number.isFinite(value)) return min;
|
|
@@ -1805,38 +1921,48 @@ function getOwnerStack(fiber) {
|
|
|
1805
1921
|
const frames = [];
|
|
1806
1922
|
let current = fiber;
|
|
1807
1923
|
let lastFrame = null;
|
|
1924
|
+
let nearestComponentFiber = null;
|
|
1808
1925
|
while (current) {
|
|
1809
1926
|
const frame = buildFrame(current);
|
|
1810
1927
|
if (frame && shouldIncludeFrame(frame, lastFrame)) {
|
|
1811
1928
|
frames.push(frame);
|
|
1812
1929
|
lastFrame = frame;
|
|
1930
|
+
if (!nearestComponentFiber) {
|
|
1931
|
+
nearestComponentFiber = current;
|
|
1932
|
+
}
|
|
1813
1933
|
}
|
|
1814
1934
|
current = current._debugOwner;
|
|
1815
1935
|
}
|
|
1816
|
-
return frames;
|
|
1936
|
+
return { frames, nearestComponentFiber };
|
|
1817
1937
|
}
|
|
1818
1938
|
function getRenderStack(fiber) {
|
|
1819
1939
|
const frames = [];
|
|
1820
1940
|
let current = fiber;
|
|
1821
1941
|
let lastFrame = null;
|
|
1942
|
+
let nearestComponentFiber = null;
|
|
1822
1943
|
while (current) {
|
|
1823
1944
|
const frame = buildFrame(current);
|
|
1824
1945
|
if (frame && shouldIncludeFrame(frame, lastFrame)) {
|
|
1825
1946
|
frames.push(frame);
|
|
1826
1947
|
lastFrame = frame;
|
|
1948
|
+
if (!nearestComponentFiber) {
|
|
1949
|
+
nearestComponentFiber = current;
|
|
1950
|
+
}
|
|
1827
1951
|
}
|
|
1828
1952
|
current = current.return;
|
|
1829
1953
|
}
|
|
1830
|
-
return frames;
|
|
1954
|
+
return { frames, nearestComponentFiber };
|
|
1831
1955
|
}
|
|
1832
|
-
function
|
|
1956
|
+
function getReactComponentInfo(element) {
|
|
1833
1957
|
const fiber = getFiberForElement(element);
|
|
1834
|
-
if (!fiber) return [];
|
|
1835
|
-
const
|
|
1836
|
-
|
|
1837
|
-
|
|
1958
|
+
if (!fiber) return { frames: [], nearestComponentFiber: null };
|
|
1959
|
+
const elementSource = getSourceFromFiber(fiber);
|
|
1960
|
+
const elementSourceFile = elementSource?.fileName || void 0;
|
|
1961
|
+
const ownerResult = getOwnerStack(fiber);
|
|
1962
|
+
if (ownerResult.frames.length > 0) {
|
|
1963
|
+
return { ...ownerResult, elementSourceFile };
|
|
1838
1964
|
}
|
|
1839
|
-
return getRenderStack(fiber);
|
|
1965
|
+
return { ...getRenderStack(fiber), elementSourceFile };
|
|
1840
1966
|
}
|
|
1841
1967
|
function getElementDisplayName(element) {
|
|
1842
1968
|
const tag = element.tagName.toLowerCase();
|
|
@@ -2138,6 +2264,27 @@ function parseDomSource(element) {
|
|
|
2138
2264
|
}
|
|
2139
2265
|
return { file, line, column };
|
|
2140
2266
|
}
|
|
2267
|
+
var MAX_SUB_ELEMENT_SOURCES = 20;
|
|
2268
|
+
function collectSubElementSources(element) {
|
|
2269
|
+
const sources = {};
|
|
2270
|
+
const children = element.querySelectorAll("[data-direct-edit-source]");
|
|
2271
|
+
const labelCounts = /* @__PURE__ */ new Map();
|
|
2272
|
+
let count = 0;
|
|
2273
|
+
for (const child of children) {
|
|
2274
|
+
if (count >= MAX_SUB_ELEMENT_SOURCES) break;
|
|
2275
|
+
if (!(child instanceof HTMLElement)) continue;
|
|
2276
|
+
const source = parseDomSource(child);
|
|
2277
|
+
if (!source) continue;
|
|
2278
|
+
const text = ((child.innerText || child.textContent) ?? "").trim();
|
|
2279
|
+
let baseLabel = text.length > 0 && text.length <= 30 ? text.slice(0, 30).toLowerCase().replace(/\s+/g, "_") : child.tagName.toLowerCase();
|
|
2280
|
+
const existing = labelCounts.get(baseLabel) ?? 0;
|
|
2281
|
+
labelCounts.set(baseLabel, existing + 1);
|
|
2282
|
+
const label = existing > 0 ? `${baseLabel}_${existing + 1}` : baseLabel;
|
|
2283
|
+
sources[label] = source;
|
|
2284
|
+
count++;
|
|
2285
|
+
}
|
|
2286
|
+
return sources;
|
|
2287
|
+
}
|
|
2141
2288
|
function getElementSource(element) {
|
|
2142
2289
|
const domSource = parseDomSource(element);
|
|
2143
2290
|
if (domSource) return domSource;
|
|
@@ -2160,8 +2307,15 @@ function getElementSource(element) {
|
|
|
2160
2307
|
function getElementLocator(element) {
|
|
2161
2308
|
const elementInfo = getElementInfo(element);
|
|
2162
2309
|
const domSource = getElementSource(element);
|
|
2310
|
+
const { frames, nearestComponentFiber, elementSourceFile } = getReactComponentInfo(element);
|
|
2311
|
+
const componentName = nearestComponentFiber?.type?.displayName || nearestComponentFiber?.type?.name || void 0;
|
|
2312
|
+
const authoredProps = nearestComponentFiber ? getComponentProps(nearestComponentFiber) : void 0;
|
|
2313
|
+
const classification = classifyComponentFiber(nearestComponentFiber, frames, elementSourceFile);
|
|
2314
|
+
const callSite = nearestComponentFiber ? getCallSiteSource(nearestComponentFiber) : null;
|
|
2315
|
+
const definitionSrc = classification.isComponentPrimitive ? deriveDefinitionSource(frames) : null;
|
|
2316
|
+
const subSources = collectSubElementSources(element);
|
|
2163
2317
|
return {
|
|
2164
|
-
reactStack:
|
|
2318
|
+
reactStack: frames,
|
|
2165
2319
|
domSelector: buildDomSelector(element),
|
|
2166
2320
|
domContextHtml: buildDomContextHtml(element),
|
|
2167
2321
|
targetHtml: buildTargetHtml(element),
|
|
@@ -2169,36 +2323,80 @@ function getElementLocator(element) {
|
|
|
2169
2323
|
tagName: elementInfo.tagName,
|
|
2170
2324
|
id: elementInfo.id,
|
|
2171
2325
|
classList: elementInfo.classList,
|
|
2172
|
-
domSource: domSource ?? void 0
|
|
2326
|
+
domSource: domSource ?? void 0,
|
|
2327
|
+
reactComponentName: componentName,
|
|
2328
|
+
authoredProps: authoredProps && Object.keys(authoredProps).length > 0 ? authoredProps : void 0,
|
|
2329
|
+
subElementSources: Object.keys(subSources).length > 0 ? subSources : void 0,
|
|
2330
|
+
callSiteSource: callSite ?? void 0,
|
|
2331
|
+
definitionSource: definitionSrc ?? void 0,
|
|
2332
|
+
isComponentPrimitive: nearestComponentFiber || elementSourceFile ? classification.isComponentPrimitive : void 0
|
|
2173
2333
|
};
|
|
2174
2334
|
}
|
|
2175
2335
|
function getLocatorHeader(locator) {
|
|
2176
2336
|
const primaryFrame = getPrimaryFrame(locator);
|
|
2177
|
-
const componentLabel =
|
|
2178
|
-
|
|
2179
|
-
|
|
2337
|
+
const componentLabel = locator.reactComponentName ?? primaryFrame?.name ?? locator.tagName;
|
|
2338
|
+
let formattedSource;
|
|
2339
|
+
if (locator.isComponentPrimitive && locator.definitionSource?.file) {
|
|
2340
|
+
formattedSource = formatSourceLocation(
|
|
2341
|
+
locator.definitionSource.file,
|
|
2342
|
+
locator.definitionSource.line,
|
|
2343
|
+
locator.definitionSource.column
|
|
2344
|
+
);
|
|
2345
|
+
} else {
|
|
2346
|
+
formattedSource = locator.domSource?.file ? formatSourceLocation(locator.domSource.file, locator.domSource.line, locator.domSource.column) : primaryFrame?.file ? formatSourceLocation(primaryFrame.file, primaryFrame.line, primaryFrame.column) : null;
|
|
2347
|
+
}
|
|
2348
|
+
const formattedCallSite = locator.callSiteSource?.file ? formatSourceLocation(locator.callSiteSource.file, locator.callSiteSource.line, locator.callSiteSource.column) : null;
|
|
2349
|
+
return { componentLabel, formattedSource, formattedCallSite };
|
|
2350
|
+
}
|
|
2351
|
+
function formatComponentTree(reactStack) {
|
|
2352
|
+
const names = reactStack.map((f) => f.name).filter(Boolean);
|
|
2353
|
+
if (names.length === 0) return null;
|
|
2354
|
+
if (names.length === 1) return names[0];
|
|
2355
|
+
const [component, ...ancestors] = names;
|
|
2356
|
+
return `${component} (in ${ancestors.join(" > ")})`;
|
|
2180
2357
|
}
|
|
2181
2358
|
function buildLocatorContextLines(locator, options) {
|
|
2182
2359
|
const lines = [];
|
|
2183
|
-
const { componentLabel, formattedSource } = getLocatorHeader(locator);
|
|
2360
|
+
const { componentLabel, formattedSource, formattedCallSite } = getLocatorHeader(locator);
|
|
2184
2361
|
const target = (locator.targetHtml || locator.domContextHtml || "").trim();
|
|
2185
2362
|
const context = locator.domContextHtml?.trim() || "";
|
|
2186
|
-
const
|
|
2363
|
+
const path = locator.domSelector?.trim();
|
|
2187
2364
|
const text = locator.textPreview?.trim();
|
|
2188
2365
|
lines.push(`@<${componentLabel}>`);
|
|
2189
2366
|
lines.push("");
|
|
2367
|
+
const tree = formatComponentTree(locator.reactStack);
|
|
2368
|
+
if (tree) {
|
|
2369
|
+
lines.push(`react: ${tree}`);
|
|
2370
|
+
}
|
|
2371
|
+
if (locator.authoredProps && Object.keys(locator.authoredProps).length > 0) {
|
|
2372
|
+
lines.push(`props: ${JSON.stringify(locator.authoredProps)}`);
|
|
2373
|
+
}
|
|
2374
|
+
if (locator.isComponentPrimitive != null) {
|
|
2375
|
+
lines.push(`type: ${locator.isComponentPrimitive ? "component" : "instance"}`);
|
|
2376
|
+
}
|
|
2377
|
+
lines.push(`source: ${formattedSource ?? "(file not available)"}`);
|
|
2378
|
+
if (formattedCallSite && formattedCallSite !== formattedSource) {
|
|
2379
|
+
lines.push(`call-site: ${formattedCallSite}`);
|
|
2380
|
+
}
|
|
2381
|
+
if (locator.subElementSources && Object.keys(locator.subElementSources).length > 0) {
|
|
2382
|
+
lines.push("source-map:");
|
|
2383
|
+
for (const [label, source] of Object.entries(locator.subElementSources)) {
|
|
2384
|
+
lines.push(` - ${label}: ${formatSourceLocation(source.file, source.line, source.column)}`);
|
|
2385
|
+
}
|
|
2386
|
+
}
|
|
2387
|
+
if (path) {
|
|
2388
|
+
lines.push(`path: ${path}`);
|
|
2389
|
+
}
|
|
2190
2390
|
if (target) {
|
|
2391
|
+
lines.push("");
|
|
2191
2392
|
lines.push("target:");
|
|
2192
2393
|
lines.push(target);
|
|
2193
2394
|
}
|
|
2194
2395
|
if (!options?.skipContext && context && context !== target) {
|
|
2396
|
+
lines.push("");
|
|
2195
2397
|
lines.push("context:");
|
|
2196
2398
|
lines.push(context);
|
|
2197
2399
|
}
|
|
2198
|
-
lines.push(`in ${formattedSource ?? "(file not available)"}`);
|
|
2199
|
-
if (selector) {
|
|
2200
|
-
lines.push(`selector: ${selector}`);
|
|
2201
|
-
}
|
|
2202
2400
|
if (text) {
|
|
2203
2401
|
lines.push(`text: ${text}`);
|
|
2204
2402
|
}
|
|
@@ -2908,7 +3106,7 @@ function buildExportInstruction(profile) {
|
|
|
2908
3106
|
return hasComments ? "Address this feedback on the UI. Use the provided source location and selector to find each element in the codebase." : "";
|
|
2909
3107
|
}
|
|
2910
3108
|
const parts = [];
|
|
2911
|
-
if (hasCssEdits) parts.push("Apply the CSS changes to the targeted elements using the project's existing styling approach (Tailwind, CSS modules, etc.).");
|
|
3109
|
+
if (hasCssEdits) parts.push("Apply the CSS changes to the targeted elements using the project's existing styling approach (Tailwind, CSS modules, etc.). Map values to existing CSS variables, design tokens, or utility classes already used in the project whenever possible.");
|
|
2912
3110
|
if (hasTextEdits) parts.push("Update the text content as specified.");
|
|
2913
3111
|
if (hasMoves) parts.push("Implement the move plan below directly in source code. For `structural_move`, reorder/reparent elements using the target anchors. For `layout_refactor`, apply the listed flex/grid refactor steps. Do NOT simulate movement with absolute positioning, left/top offsets, transform, or margin hacks.");
|
|
2914
3112
|
if (hasComments) parts.push("Address the comments on the relevant elements.");
|
|
@@ -2994,6 +3192,7 @@ export {
|
|
|
2994
3192
|
findTextOwnerAtPoint,
|
|
2995
3193
|
findTextOwnerByRangeScan,
|
|
2996
3194
|
flexPropertyToCSSMap,
|
|
3195
|
+
formatComponentTree,
|
|
2997
3196
|
formatPropertyValue,
|
|
2998
3197
|
getAllComputedStyles,
|
|
2999
3198
|
getChildBriefInfo,
|
|
@@ -3011,6 +3210,7 @@ export {
|
|
|
3011
3210
|
getElementSource,
|
|
3012
3211
|
getExportContentProfile,
|
|
3013
3212
|
getFlexDirection,
|
|
3213
|
+
getLocatorHeader,
|
|
3014
3214
|
getMoveIntentForEdit,
|
|
3015
3215
|
getOriginalInlineStyles,
|
|
3016
3216
|
getSelectionColors,
|