made-refine 0.2.13 → 0.2.16
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 +388 -49
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +388 -49
- package/dist/index.mjs.map +1 -1
- package/dist/{utils-DvJ3xKrO.d.mts → utils-lksVP2Wq.d.mts} +14 -1
- package/dist/{utils-DvJ3xKrO.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 +224 -19
- package/dist/utils.js.map +1 -1
- package/dist/utils.mjs +222 -19
- package/dist/utils.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -117,6 +117,228 @@ function getZoomScale() {
|
|
|
117
117
|
return snap.active ? snap.zoom : 1;
|
|
118
118
|
}
|
|
119
119
|
|
|
120
|
+
// src/utils/react-fiber.ts
|
|
121
|
+
function getFiberForElement(element) {
|
|
122
|
+
if (typeof window !== "undefined") {
|
|
123
|
+
const devtools = window.__DIRECT_EDIT_DEVTOOLS__;
|
|
124
|
+
if (devtools?.getFiberForElement) {
|
|
125
|
+
const fiber = devtools.getFiberForElement(element);
|
|
126
|
+
if (fiber) return fiber;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
const fiberKey = Object.keys(element).find(
|
|
130
|
+
(key) => key.startsWith("__reactFiber$") || key.startsWith("__reactInternalInstance$")
|
|
131
|
+
);
|
|
132
|
+
if (!fiberKey) return null;
|
|
133
|
+
return element[fiberKey] || null;
|
|
134
|
+
}
|
|
135
|
+
function getSourceFromFiber(fiber) {
|
|
136
|
+
const debugSource = fiber?._debugSource;
|
|
137
|
+
if (debugSource?.fileName) return debugSource;
|
|
138
|
+
const owner = fiber?._debugOwner;
|
|
139
|
+
const ownerPending = owner?.pendingProps?.__source;
|
|
140
|
+
if (ownerPending?.fileName) return ownerPending;
|
|
141
|
+
const ownerMemo = owner?.memoizedProps?.__source;
|
|
142
|
+
if (ownerMemo?.fileName) return ownerMemo;
|
|
143
|
+
const pending = fiber?.pendingProps?.__source;
|
|
144
|
+
if (pending?.fileName) return pending;
|
|
145
|
+
const memo = fiber?.memoizedProps?.__source;
|
|
146
|
+
if (memo?.fileName) return memo;
|
|
147
|
+
return null;
|
|
148
|
+
}
|
|
149
|
+
function buildFrame(fiber) {
|
|
150
|
+
const type = fiber?.type;
|
|
151
|
+
if (typeof type !== "function" && typeof type !== "object") return null;
|
|
152
|
+
const name = type?.displayName || type?.name || null;
|
|
153
|
+
if (!name || name === "Fragment") return null;
|
|
154
|
+
const frame = { name };
|
|
155
|
+
const source = getSourceFromFiber(fiber);
|
|
156
|
+
if (source?.fileName) {
|
|
157
|
+
frame.file = source.fileName;
|
|
158
|
+
if (typeof source.lineNumber === "number") {
|
|
159
|
+
frame.line = source.lineNumber;
|
|
160
|
+
}
|
|
161
|
+
if (typeof source.columnNumber === "number") {
|
|
162
|
+
frame.column = source.columnNumber;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
return frame;
|
|
166
|
+
}
|
|
167
|
+
function shouldIncludeFrame(frame, lastFrame) {
|
|
168
|
+
if (!lastFrame) return true;
|
|
169
|
+
if (frame.name !== lastFrame.name) return true;
|
|
170
|
+
if (!lastFrame.file && frame.file) return true;
|
|
171
|
+
if (lastFrame.file && frame.file && lastFrame.line == null && frame.line != null) return true;
|
|
172
|
+
if (lastFrame.file && frame.file && lastFrame.line != null && frame.line != null && lastFrame.column == null && frame.column != null) {
|
|
173
|
+
return true;
|
|
174
|
+
}
|
|
175
|
+
return false;
|
|
176
|
+
}
|
|
177
|
+
function getOwnerStack(fiber) {
|
|
178
|
+
const frames = [];
|
|
179
|
+
let current = fiber;
|
|
180
|
+
let lastFrame = null;
|
|
181
|
+
let nearestComponentFiber = null;
|
|
182
|
+
while (current) {
|
|
183
|
+
const frame = buildFrame(current);
|
|
184
|
+
if (frame && shouldIncludeFrame(frame, lastFrame)) {
|
|
185
|
+
frames.push(frame);
|
|
186
|
+
lastFrame = frame;
|
|
187
|
+
if (!nearestComponentFiber) {
|
|
188
|
+
nearestComponentFiber = current;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
current = current._debugOwner;
|
|
192
|
+
}
|
|
193
|
+
return { frames, nearestComponentFiber };
|
|
194
|
+
}
|
|
195
|
+
function getRenderStack(fiber) {
|
|
196
|
+
const frames = [];
|
|
197
|
+
let current = fiber;
|
|
198
|
+
let lastFrame = null;
|
|
199
|
+
let nearestComponentFiber = null;
|
|
200
|
+
while (current) {
|
|
201
|
+
const frame = buildFrame(current);
|
|
202
|
+
if (frame && shouldIncludeFrame(frame, lastFrame)) {
|
|
203
|
+
frames.push(frame);
|
|
204
|
+
lastFrame = frame;
|
|
205
|
+
if (!nearestComponentFiber) {
|
|
206
|
+
nearestComponentFiber = current;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
current = current.return;
|
|
210
|
+
}
|
|
211
|
+
return { frames, nearestComponentFiber };
|
|
212
|
+
}
|
|
213
|
+
function getReactComponentInfo(element) {
|
|
214
|
+
const fiber = getFiberForElement(element);
|
|
215
|
+
if (!fiber) return { frames: [], nearestComponentFiber: null };
|
|
216
|
+
const elementSource = getSourceFromFiber(fiber);
|
|
217
|
+
const elementSourceFile = elementSource?.fileName || void 0;
|
|
218
|
+
const ownerResult = getOwnerStack(fiber);
|
|
219
|
+
if (ownerResult.frames.length > 0) {
|
|
220
|
+
return { ...ownerResult, elementSourceFile };
|
|
221
|
+
}
|
|
222
|
+
return { ...getRenderStack(fiber), elementSourceFile };
|
|
223
|
+
}
|
|
224
|
+
var EXCLUDED_PROP_KEYS = /* @__PURE__ */ new Set([
|
|
225
|
+
"className",
|
|
226
|
+
"style",
|
|
227
|
+
"children",
|
|
228
|
+
"ref",
|
|
229
|
+
"key",
|
|
230
|
+
"render"
|
|
231
|
+
]);
|
|
232
|
+
function serializePropValue(value) {
|
|
233
|
+
if (typeof value === "function") return "[function]";
|
|
234
|
+
if (typeof value === "symbol") return void 0;
|
|
235
|
+
if (value === void 0) return void 0;
|
|
236
|
+
if (value !== null && typeof value === "object") {
|
|
237
|
+
if ("$$typeof" in value) return "[element]";
|
|
238
|
+
try {
|
|
239
|
+
JSON.stringify(value);
|
|
240
|
+
return value;
|
|
241
|
+
} catch {
|
|
242
|
+
return "[object]";
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
return value;
|
|
246
|
+
}
|
|
247
|
+
function getComponentProps(fiber) {
|
|
248
|
+
const props = fiber?.memoizedProps ?? fiber?.pendingProps;
|
|
249
|
+
if (!props || typeof props !== "object") return {};
|
|
250
|
+
const result = {};
|
|
251
|
+
for (const [key, value] of Object.entries(props)) {
|
|
252
|
+
if (EXCLUDED_PROP_KEYS.has(key)) continue;
|
|
253
|
+
if (key.startsWith("data-")) continue;
|
|
254
|
+
const serialized = serializePropValue(value);
|
|
255
|
+
if (serialized !== void 0) {
|
|
256
|
+
result[key] = serialized;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
return result;
|
|
260
|
+
}
|
|
261
|
+
function getCallSiteSource(fiber) {
|
|
262
|
+
const source = fiber?._debugSource;
|
|
263
|
+
if (source?.fileName) {
|
|
264
|
+
return {
|
|
265
|
+
file: source.fileName,
|
|
266
|
+
line: typeof source.lineNumber === "number" ? source.lineNumber : void 0,
|
|
267
|
+
column: typeof source.columnNumber === "number" ? source.columnNumber : void 0
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
const pending = fiber?.pendingProps?.__source;
|
|
271
|
+
if (pending?.fileName) {
|
|
272
|
+
return {
|
|
273
|
+
file: pending.fileName,
|
|
274
|
+
line: typeof pending.lineNumber === "number" ? pending.lineNumber : void 0,
|
|
275
|
+
column: typeof pending.columnNumber === "number" ? pending.columnNumber : void 0
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
return null;
|
|
279
|
+
}
|
|
280
|
+
function deriveDefinitionSource(frames) {
|
|
281
|
+
for (const frame of frames) {
|
|
282
|
+
if (frame.file && isComponentPrimitivePath(frame.file)) {
|
|
283
|
+
return { file: frame.file, line: frame.line, column: frame.column };
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
return null;
|
|
287
|
+
}
|
|
288
|
+
var PRIMITIVE_PATH_PATTERNS = [
|
|
289
|
+
/\/components\/ui\//,
|
|
290
|
+
/\/ui\/primitives\//,
|
|
291
|
+
/\/design-system\//
|
|
292
|
+
];
|
|
293
|
+
var PRIMITIVE_NPM_PATTERNS = [
|
|
294
|
+
/@base-ui\//,
|
|
295
|
+
/@radix-ui\//,
|
|
296
|
+
/@headlessui\//,
|
|
297
|
+
/@chakra-ui\//,
|
|
298
|
+
/@mantine\//,
|
|
299
|
+
/@mui\//,
|
|
300
|
+
/@ark-ui\//
|
|
301
|
+
];
|
|
302
|
+
var FRAMEWORK_EXCLUSION_PATTERNS = [
|
|
303
|
+
/node_modules\/react\//,
|
|
304
|
+
/node_modules\/react-dom\//,
|
|
305
|
+
/node_modules\/next\/dist\//,
|
|
306
|
+
/node_modules\/scheduler\//,
|
|
307
|
+
/node_modules\/react-server\//
|
|
308
|
+
];
|
|
309
|
+
function isComponentPrimitivePath(filePath) {
|
|
310
|
+
const normalized = filePath.replace(/\\/g, "/");
|
|
311
|
+
for (const pattern of FRAMEWORK_EXCLUSION_PATTERNS) {
|
|
312
|
+
if (pattern.test(normalized)) return false;
|
|
313
|
+
}
|
|
314
|
+
for (const pattern of PRIMITIVE_NPM_PATTERNS) {
|
|
315
|
+
if (pattern.test(normalized)) return true;
|
|
316
|
+
}
|
|
317
|
+
for (const pattern of PRIMITIVE_PATH_PATTERNS) {
|
|
318
|
+
if (pattern.test(normalized)) return true;
|
|
319
|
+
}
|
|
320
|
+
return false;
|
|
321
|
+
}
|
|
322
|
+
function classifyComponentFiber(fiber, frames, elementSourceFile) {
|
|
323
|
+
if (elementSourceFile && isComponentPrimitivePath(elementSourceFile)) {
|
|
324
|
+
return { isComponentPrimitive: true };
|
|
325
|
+
}
|
|
326
|
+
if (!fiber) return { isComponentPrimitive: false };
|
|
327
|
+
const callSite = getCallSiteSource(fiber);
|
|
328
|
+
if (callSite?.file && isComponentPrimitivePath(callSite.file)) {
|
|
329
|
+
return { isComponentPrimitive: true };
|
|
330
|
+
}
|
|
331
|
+
for (const frame of frames) {
|
|
332
|
+
if (frame.file && isComponentPrimitivePath(frame.file)) {
|
|
333
|
+
return { isComponentPrimitive: true };
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
if (!elementSourceFile && fiber._debugSource) {
|
|
337
|
+
return { isComponentPrimitive: true };
|
|
338
|
+
}
|
|
339
|
+
return { isComponentPrimitive: false };
|
|
340
|
+
}
|
|
341
|
+
|
|
120
342
|
// src/utils.ts
|
|
121
343
|
function clamp(value, min, max) {
|
|
122
344
|
if (!Number.isFinite(value)) return min;
|
|
@@ -1504,7 +1726,7 @@ function calculateDropPosition(container, pointerX, pointerY, draggedElement) {
|
|
|
1504
1726
|
};
|
|
1505
1727
|
return { insertBefore, indicator };
|
|
1506
1728
|
}
|
|
1507
|
-
function
|
|
1729
|
+
function getFiberForElement2(element) {
|
|
1508
1730
|
if (typeof window !== "undefined") {
|
|
1509
1731
|
const devtools = window.__DIRECT_EDIT_DEVTOOLS__;
|
|
1510
1732
|
if (devtools?.getFiberForElement) {
|
|
@@ -1765,7 +1987,7 @@ function getSourceFromDebugStack(fiber) {
|
|
|
1765
1987
|
}
|
|
1766
1988
|
return null;
|
|
1767
1989
|
}
|
|
1768
|
-
function
|
|
1990
|
+
function getSourceFromFiber2(fiber) {
|
|
1769
1991
|
const debugSource = fiber?._debugSource;
|
|
1770
1992
|
if (debugSource?.fileName) return debugSource;
|
|
1771
1993
|
const owner = fiber?._debugOwner;
|
|
@@ -1781,13 +2003,13 @@ function getSourceFromFiber(fiber) {
|
|
|
1781
2003
|
if (fromDebugStack?.fileName) return fromDebugStack;
|
|
1782
2004
|
return null;
|
|
1783
2005
|
}
|
|
1784
|
-
function
|
|
2006
|
+
function buildFrame2(fiber) {
|
|
1785
2007
|
const type = fiber?.type;
|
|
1786
2008
|
if (typeof type !== "function" && typeof type !== "object") return null;
|
|
1787
2009
|
const name = type?.displayName || type?.name || null;
|
|
1788
2010
|
if (!name || name === "Fragment") return null;
|
|
1789
2011
|
const frame = { name };
|
|
1790
|
-
const source =
|
|
2012
|
+
const source = getSourceFromFiber2(fiber);
|
|
1791
2013
|
if (source?.fileName) {
|
|
1792
2014
|
frame.file = source.fileName;
|
|
1793
2015
|
if (typeof source.lineNumber === "number") {
|
|
@@ -1799,7 +2021,7 @@ function buildFrame(fiber) {
|
|
|
1799
2021
|
}
|
|
1800
2022
|
return frame;
|
|
1801
2023
|
}
|
|
1802
|
-
function
|
|
2024
|
+
function shouldIncludeFrame2(frame, lastFrame) {
|
|
1803
2025
|
if (!lastFrame) return true;
|
|
1804
2026
|
if (frame.name !== lastFrame.name) return true;
|
|
1805
2027
|
if (!lastFrame.file && frame.file) return true;
|
|
@@ -1809,42 +2031,52 @@ function shouldIncludeFrame(frame, lastFrame) {
|
|
|
1809
2031
|
}
|
|
1810
2032
|
return false;
|
|
1811
2033
|
}
|
|
1812
|
-
function
|
|
2034
|
+
function getOwnerStack2(fiber) {
|
|
1813
2035
|
const frames = [];
|
|
1814
2036
|
let current = fiber;
|
|
1815
2037
|
let lastFrame = null;
|
|
2038
|
+
let nearestComponentFiber = null;
|
|
1816
2039
|
while (current) {
|
|
1817
|
-
const frame =
|
|
1818
|
-
if (frame &&
|
|
2040
|
+
const frame = buildFrame2(current);
|
|
2041
|
+
if (frame && shouldIncludeFrame2(frame, lastFrame)) {
|
|
1819
2042
|
frames.push(frame);
|
|
1820
2043
|
lastFrame = frame;
|
|
2044
|
+
if (!nearestComponentFiber) {
|
|
2045
|
+
nearestComponentFiber = current;
|
|
2046
|
+
}
|
|
1821
2047
|
}
|
|
1822
2048
|
current = current._debugOwner;
|
|
1823
2049
|
}
|
|
1824
|
-
return frames;
|
|
2050
|
+
return { frames, nearestComponentFiber };
|
|
1825
2051
|
}
|
|
1826
|
-
function
|
|
2052
|
+
function getRenderStack2(fiber) {
|
|
1827
2053
|
const frames = [];
|
|
1828
2054
|
let current = fiber;
|
|
1829
2055
|
let lastFrame = null;
|
|
2056
|
+
let nearestComponentFiber = null;
|
|
1830
2057
|
while (current) {
|
|
1831
|
-
const frame =
|
|
1832
|
-
if (frame &&
|
|
2058
|
+
const frame = buildFrame2(current);
|
|
2059
|
+
if (frame && shouldIncludeFrame2(frame, lastFrame)) {
|
|
1833
2060
|
frames.push(frame);
|
|
1834
2061
|
lastFrame = frame;
|
|
2062
|
+
if (!nearestComponentFiber) {
|
|
2063
|
+
nearestComponentFiber = current;
|
|
2064
|
+
}
|
|
1835
2065
|
}
|
|
1836
2066
|
current = current.return;
|
|
1837
2067
|
}
|
|
1838
|
-
return frames;
|
|
2068
|
+
return { frames, nearestComponentFiber };
|
|
1839
2069
|
}
|
|
1840
|
-
function
|
|
1841
|
-
const fiber =
|
|
1842
|
-
if (!fiber) return [];
|
|
1843
|
-
const
|
|
1844
|
-
|
|
1845
|
-
|
|
2070
|
+
function getReactComponentInfo2(element) {
|
|
2071
|
+
const fiber = getFiberForElement2(element);
|
|
2072
|
+
if (!fiber) return { frames: [], nearestComponentFiber: null };
|
|
2073
|
+
const elementSource = getSourceFromFiber2(fiber);
|
|
2074
|
+
const elementSourceFile = elementSource?.fileName || void 0;
|
|
2075
|
+
const ownerResult = getOwnerStack2(fiber);
|
|
2076
|
+
if (ownerResult.frames.length > 0) {
|
|
2077
|
+
return { ...ownerResult, elementSourceFile };
|
|
1846
2078
|
}
|
|
1847
|
-
return
|
|
2079
|
+
return { ...getRenderStack2(fiber), elementSourceFile };
|
|
1848
2080
|
}
|
|
1849
2081
|
function getElementDisplayName(element) {
|
|
1850
2082
|
const tag = element.tagName.toLowerCase();
|
|
@@ -2139,14 +2371,35 @@ function parseDomSource(element) {
|
|
|
2139
2371
|
}
|
|
2140
2372
|
return { file, line, column };
|
|
2141
2373
|
}
|
|
2374
|
+
var MAX_SUB_ELEMENT_SOURCES = 20;
|
|
2375
|
+
function collectSubElementSources(element) {
|
|
2376
|
+
const sources = {};
|
|
2377
|
+
const children = element.querySelectorAll("[data-direct-edit-source]");
|
|
2378
|
+
const labelCounts = /* @__PURE__ */ new Map();
|
|
2379
|
+
let count = 0;
|
|
2380
|
+
for (const child of children) {
|
|
2381
|
+
if (count >= MAX_SUB_ELEMENT_SOURCES) break;
|
|
2382
|
+
if (!(child instanceof HTMLElement)) continue;
|
|
2383
|
+
const source = parseDomSource(child);
|
|
2384
|
+
if (!source) continue;
|
|
2385
|
+
const text = ((child.innerText || child.textContent) ?? "").trim();
|
|
2386
|
+
let baseLabel = text.length > 0 && text.length <= 30 ? text.slice(0, 30).toLowerCase().replace(/\s+/g, "_") : child.tagName.toLowerCase();
|
|
2387
|
+
const existing = labelCounts.get(baseLabel) ?? 0;
|
|
2388
|
+
labelCounts.set(baseLabel, existing + 1);
|
|
2389
|
+
const label = existing > 0 ? `${baseLabel}_${existing + 1}` : baseLabel;
|
|
2390
|
+
sources[label] = source;
|
|
2391
|
+
count++;
|
|
2392
|
+
}
|
|
2393
|
+
return sources;
|
|
2394
|
+
}
|
|
2142
2395
|
function getElementSource(element) {
|
|
2143
2396
|
const domSource = parseDomSource(element);
|
|
2144
2397
|
if (domSource) return domSource;
|
|
2145
2398
|
const seenFibers = /* @__PURE__ */ new Set();
|
|
2146
|
-
let fiber =
|
|
2399
|
+
let fiber = getFiberForElement2(element);
|
|
2147
2400
|
while (fiber && !seenFibers.has(fiber)) {
|
|
2148
2401
|
seenFibers.add(fiber);
|
|
2149
|
-
const fiberSource =
|
|
2402
|
+
const fiberSource = getSourceFromFiber2(fiber);
|
|
2150
2403
|
if (fiberSource?.fileName) {
|
|
2151
2404
|
return {
|
|
2152
2405
|
file: fiberSource.fileName,
|
|
@@ -2161,8 +2414,15 @@ function getElementSource(element) {
|
|
|
2161
2414
|
function getElementLocator(element) {
|
|
2162
2415
|
const elementInfo = getElementInfo(element);
|
|
2163
2416
|
const domSource = getElementSource(element);
|
|
2417
|
+
const { frames, nearestComponentFiber, elementSourceFile } = getReactComponentInfo2(element);
|
|
2418
|
+
const componentName = nearestComponentFiber?.type?.displayName || nearestComponentFiber?.type?.name || void 0;
|
|
2419
|
+
const authoredProps = nearestComponentFiber ? getComponentProps(nearestComponentFiber) : void 0;
|
|
2420
|
+
const classification = classifyComponentFiber(nearestComponentFiber, frames, elementSourceFile);
|
|
2421
|
+
const callSite = nearestComponentFiber ? getCallSiteSource(nearestComponentFiber) : null;
|
|
2422
|
+
const definitionSrc = classification.isComponentPrimitive ? deriveDefinitionSource(frames) : null;
|
|
2423
|
+
const subSources = collectSubElementSources(element);
|
|
2164
2424
|
return {
|
|
2165
|
-
reactStack:
|
|
2425
|
+
reactStack: frames,
|
|
2166
2426
|
domSelector: buildDomSelector(element),
|
|
2167
2427
|
domContextHtml: buildDomContextHtml(element),
|
|
2168
2428
|
targetHtml: buildTargetHtml(element),
|
|
@@ -2170,36 +2430,80 @@ function getElementLocator(element) {
|
|
|
2170
2430
|
tagName: elementInfo.tagName,
|
|
2171
2431
|
id: elementInfo.id,
|
|
2172
2432
|
classList: elementInfo.classList,
|
|
2173
|
-
domSource: domSource ?? void 0
|
|
2433
|
+
domSource: domSource ?? void 0,
|
|
2434
|
+
reactComponentName: componentName,
|
|
2435
|
+
authoredProps: authoredProps && Object.keys(authoredProps).length > 0 ? authoredProps : void 0,
|
|
2436
|
+
subElementSources: Object.keys(subSources).length > 0 ? subSources : void 0,
|
|
2437
|
+
callSiteSource: callSite ?? void 0,
|
|
2438
|
+
definitionSource: definitionSrc ?? void 0,
|
|
2439
|
+
isComponentPrimitive: nearestComponentFiber || elementSourceFile ? classification.isComponentPrimitive : void 0
|
|
2174
2440
|
};
|
|
2175
2441
|
}
|
|
2176
2442
|
function getLocatorHeader(locator) {
|
|
2177
2443
|
const primaryFrame = getPrimaryFrame(locator);
|
|
2178
|
-
const componentLabel =
|
|
2179
|
-
|
|
2180
|
-
|
|
2444
|
+
const componentLabel = locator.reactComponentName ?? primaryFrame?.name ?? locator.tagName;
|
|
2445
|
+
let formattedSource;
|
|
2446
|
+
if (locator.isComponentPrimitive && locator.definitionSource?.file) {
|
|
2447
|
+
formattedSource = formatSourceLocation(
|
|
2448
|
+
locator.definitionSource.file,
|
|
2449
|
+
locator.definitionSource.line,
|
|
2450
|
+
locator.definitionSource.column
|
|
2451
|
+
);
|
|
2452
|
+
} else {
|
|
2453
|
+
formattedSource = locator.domSource?.file ? formatSourceLocation(locator.domSource.file, locator.domSource.line, locator.domSource.column) : primaryFrame?.file ? formatSourceLocation(primaryFrame.file, primaryFrame.line, primaryFrame.column) : null;
|
|
2454
|
+
}
|
|
2455
|
+
const formattedCallSite = locator.callSiteSource?.file ? formatSourceLocation(locator.callSiteSource.file, locator.callSiteSource.line, locator.callSiteSource.column) : null;
|
|
2456
|
+
return { componentLabel, formattedSource, formattedCallSite };
|
|
2457
|
+
}
|
|
2458
|
+
function formatComponentTree(reactStack) {
|
|
2459
|
+
const names = reactStack.map((f) => f.name).filter(Boolean);
|
|
2460
|
+
if (names.length === 0) return null;
|
|
2461
|
+
if (names.length === 1) return names[0];
|
|
2462
|
+
const [component, ...ancestors] = names;
|
|
2463
|
+
return `${component} (in ${ancestors.join(" > ")})`;
|
|
2181
2464
|
}
|
|
2182
2465
|
function buildLocatorContextLines(locator, options) {
|
|
2183
2466
|
const lines = [];
|
|
2184
|
-
const { componentLabel, formattedSource } = getLocatorHeader(locator);
|
|
2467
|
+
const { componentLabel, formattedSource, formattedCallSite } = getLocatorHeader(locator);
|
|
2185
2468
|
const target = (locator.targetHtml || locator.domContextHtml || "").trim();
|
|
2186
2469
|
const context = locator.domContextHtml?.trim() || "";
|
|
2187
|
-
const
|
|
2470
|
+
const path = locator.domSelector?.trim();
|
|
2188
2471
|
const text = locator.textPreview?.trim();
|
|
2189
2472
|
lines.push(`@<${componentLabel}>`);
|
|
2190
2473
|
lines.push("");
|
|
2474
|
+
const tree = formatComponentTree(locator.reactStack);
|
|
2475
|
+
if (tree) {
|
|
2476
|
+
lines.push(`react: ${tree}`);
|
|
2477
|
+
}
|
|
2478
|
+
if (locator.authoredProps && Object.keys(locator.authoredProps).length > 0) {
|
|
2479
|
+
lines.push(`props: ${JSON.stringify(locator.authoredProps)}`);
|
|
2480
|
+
}
|
|
2481
|
+
if (locator.isComponentPrimitive != null) {
|
|
2482
|
+
lines.push(`type: ${locator.isComponentPrimitive ? "component" : "instance"}`);
|
|
2483
|
+
}
|
|
2484
|
+
lines.push(`source: ${formattedSource ?? "(file not available)"}`);
|
|
2485
|
+
if (formattedCallSite && formattedCallSite !== formattedSource) {
|
|
2486
|
+
lines.push(`call-site: ${formattedCallSite}`);
|
|
2487
|
+
}
|
|
2488
|
+
if (locator.subElementSources && Object.keys(locator.subElementSources).length > 0) {
|
|
2489
|
+
lines.push("source-map:");
|
|
2490
|
+
for (const [label, source] of Object.entries(locator.subElementSources)) {
|
|
2491
|
+
lines.push(` - ${label}: ${formatSourceLocation(source.file, source.line, source.column)}`);
|
|
2492
|
+
}
|
|
2493
|
+
}
|
|
2494
|
+
if (path) {
|
|
2495
|
+
lines.push(`path: ${path}`);
|
|
2496
|
+
}
|
|
2191
2497
|
if (target) {
|
|
2498
|
+
lines.push("");
|
|
2192
2499
|
lines.push("target:");
|
|
2193
2500
|
lines.push(target);
|
|
2194
2501
|
}
|
|
2195
2502
|
if (!options?.skipContext && context && context !== target) {
|
|
2503
|
+
lines.push("");
|
|
2196
2504
|
lines.push("context:");
|
|
2197
2505
|
lines.push(context);
|
|
2198
2506
|
}
|
|
2199
|
-
lines.push(`in ${formattedSource ?? "(file not available)"}`);
|
|
2200
|
-
if (selector) {
|
|
2201
|
-
lines.push(`selector: ${selector}`);
|
|
2202
|
-
}
|
|
2203
2507
|
if (text) {
|
|
2204
2508
|
lines.push(`text: ${text}`);
|
|
2205
2509
|
}
|
|
@@ -3944,6 +4248,8 @@ function useSessionManager({
|
|
|
3944
4248
|
const originalStyles = options?.originalStyles ?? existingEdit?.originalStyles ?? getOriginalInlineStyles(nextSingleElement);
|
|
3945
4249
|
const pendingStyles = options?.pendingStyles ?? existingEdit?.pendingStyles ?? {};
|
|
3946
4250
|
const elementInfo = getElementInfo(nextSingleElement);
|
|
4251
|
+
const { frames, nearestComponentFiber, elementSourceFile } = getReactComponentInfo(nextSingleElement);
|
|
4252
|
+
const isPrimitive = classifyComponentFiber(nearestComponentFiber, frames, elementSourceFile).isComponentPrimitive;
|
|
3947
4253
|
setState((prev) => ({
|
|
3948
4254
|
comments: prev.activeCommentId ? prev.comments.filter((comment) => {
|
|
3949
4255
|
if (comment.id !== prev.activeCommentId) return true;
|
|
@@ -3962,6 +4268,7 @@ function useSessionManager({
|
|
|
3962
4268
|
computedColor: computed.color,
|
|
3963
4269
|
computedBoxShadow: computed.boxShadow,
|
|
3964
4270
|
computedTypography: computed.typography,
|
|
4271
|
+
isComponentPrimitive: isPrimitive,
|
|
3965
4272
|
originalStyles,
|
|
3966
4273
|
pendingStyles,
|
|
3967
4274
|
editModeActive: prev.editModeActive,
|
|
@@ -3992,6 +4299,7 @@ function useSessionManager({
|
|
|
3992
4299
|
computedColor: null,
|
|
3993
4300
|
computedBoxShadow: null,
|
|
3994
4301
|
computedTypography: null,
|
|
4302
|
+
isComponentPrimitive: false,
|
|
3995
4303
|
originalStyles: {},
|
|
3996
4304
|
pendingStyles: {},
|
|
3997
4305
|
activeCommentId: null,
|
|
@@ -4532,6 +4840,7 @@ function useSessionManager({
|
|
|
4532
4840
|
computedColor: computed.color,
|
|
4533
4841
|
computedBoxShadow: computed.boxShadow,
|
|
4534
4842
|
computedTypography: computed.typography,
|
|
4843
|
+
isComponentPrimitive: prev.isComponentPrimitive,
|
|
4535
4844
|
originalStyles: styleState.originalStyles,
|
|
4536
4845
|
pendingStyles: styleState.pendingStyles,
|
|
4537
4846
|
editModeActive: prev.editModeActive,
|
|
@@ -5316,6 +5625,8 @@ function withInstruction(profile, markdown) {
|
|
|
5316
5625
|
${markdown}` : markdown;
|
|
5317
5626
|
}
|
|
5318
5627
|
function buildLocatorPayload(locator) {
|
|
5628
|
+
const { componentLabel, formattedSource, formattedCallSite } = getLocatorHeader(locator);
|
|
5629
|
+
const reactTree = formatComponentTree(locator.reactStack);
|
|
5319
5630
|
return {
|
|
5320
5631
|
element: {
|
|
5321
5632
|
tagName: locator.tagName,
|
|
@@ -5323,10 +5634,22 @@ function buildLocatorPayload(locator) {
|
|
|
5323
5634
|
classList: locator.classList,
|
|
5324
5635
|
domSelector: locator.domSelector,
|
|
5325
5636
|
targetHtml: locator.targetHtml,
|
|
5637
|
+
contextHtml: locator.domContextHtml || null,
|
|
5326
5638
|
textPreview: locator.textPreview
|
|
5327
5639
|
},
|
|
5328
|
-
|
|
5329
|
-
|
|
5640
|
+
componentLabel,
|
|
5641
|
+
reactTree,
|
|
5642
|
+
reactStack: locator.reactStack,
|
|
5643
|
+
reactComponentName: locator.reactComponentName ?? null,
|
|
5644
|
+
authoredProps: locator.authoredProps ?? null,
|
|
5645
|
+
type: locator.isComponentPrimitive != null ? locator.isComponentPrimitive ? "component" : "instance" : null,
|
|
5646
|
+
isComponentPrimitive: locator.isComponentPrimitive ?? false,
|
|
5647
|
+
source: formattedSource,
|
|
5648
|
+
callSite: formattedCallSite,
|
|
5649
|
+
rawSource: locator.domSource || null,
|
|
5650
|
+
callSiteSource: locator.callSiteSource ?? null,
|
|
5651
|
+
definitionSource: locator.definitionSource ?? null,
|
|
5652
|
+
subElementSources: locator.subElementSources ?? null
|
|
5330
5653
|
};
|
|
5331
5654
|
}
|
|
5332
5655
|
function useAgentComms({ stateRef, sessionEditsRef, getSessionItems, saveCurrentToSession, removeSessionEdit, deleteComment }) {
|
|
@@ -6302,6 +6625,7 @@ function DirectEditProvider({ children }) {
|
|
|
6302
6625
|
computedColor: null,
|
|
6303
6626
|
computedBoxShadow: null,
|
|
6304
6627
|
computedTypography: null,
|
|
6628
|
+
isComponentPrimitive: false,
|
|
6305
6629
|
originalStyles: {},
|
|
6306
6630
|
pendingStyles: {},
|
|
6307
6631
|
editModeActive: false,
|
|
@@ -8594,6 +8918,7 @@ function useSelectionResize({
|
|
|
8594
8918
|
import { Fragment as Fragment2, jsx as jsx9, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
8595
8919
|
var BLUE3 = "#0D99FF";
|
|
8596
8920
|
var MAGENTA = "#E11BB6";
|
|
8921
|
+
var COMPONENT_PURPLE = "#8B5CF6";
|
|
8597
8922
|
var DRAG_THRESHOLD = 4;
|
|
8598
8923
|
var DBLCLICK_DELAY = 300;
|
|
8599
8924
|
var HANDLE_SIZE = 12;
|
|
@@ -8637,9 +8962,11 @@ function SelectionOverlay({
|
|
|
8637
8962
|
onHoverElement,
|
|
8638
8963
|
onClickThrough,
|
|
8639
8964
|
onSelectPageFrame,
|
|
8965
|
+
isComponentPrimitive = false,
|
|
8640
8966
|
enableResizeHandles = false,
|
|
8641
8967
|
onResizeSizingChange
|
|
8642
8968
|
}) {
|
|
8969
|
+
const selectionColor = isComponentPrimitive ? COMPONENT_PURPLE : BLUE3;
|
|
8643
8970
|
const rectElement = isDragging && draggedElement ? draggedElement : selectedElement;
|
|
8644
8971
|
const [rect, setRect] = React19.useState(() => rectElement.getBoundingClientRect());
|
|
8645
8972
|
const [pageFrameRect, setPageFrameRect] = React19.useState(() => pageFrameElement ? pageFrameElement.getBoundingClientRect() : null);
|
|
@@ -8967,7 +9294,7 @@ function SelectionOverlay({
|
|
|
8967
9294
|
zIndex: 99997,
|
|
8968
9295
|
background: "transparent",
|
|
8969
9296
|
border: "none",
|
|
8970
|
-
color:
|
|
9297
|
+
color: selectionColor,
|
|
8971
9298
|
fontSize: `${pageLabelFontSize}px`,
|
|
8972
9299
|
lineHeight: `${pageLabelLineHeight}px`,
|
|
8973
9300
|
padding: 0,
|
|
@@ -8995,7 +9322,7 @@ function SelectionOverlay({
|
|
|
8995
9322
|
height: rect.height,
|
|
8996
9323
|
pointerEvents: "none",
|
|
8997
9324
|
zIndex: 99996,
|
|
8998
|
-
border: `1px solid ${
|
|
9325
|
+
border: `1px solid ${selectionColor}`,
|
|
8999
9326
|
borderRadius: "0px",
|
|
9000
9327
|
boxSizing: "border-box"
|
|
9001
9328
|
}
|
|
@@ -9012,18 +9339,28 @@ function SelectionOverlay({
|
|
|
9012
9339
|
transform: "translateX(-50%)",
|
|
9013
9340
|
pointerEvents: "none",
|
|
9014
9341
|
zIndex: 99992,
|
|
9015
|
-
|
|
9016
|
-
|
|
9017
|
-
|
|
9018
|
-
lineHeight: "20px",
|
|
9019
|
-
padding: "0 6px",
|
|
9020
|
-
borderRadius: "4px",
|
|
9021
|
-
whiteSpace: "nowrap",
|
|
9022
|
-
fontFamily: "system-ui, sans-serif",
|
|
9023
|
-
fontWeight: 500,
|
|
9024
|
-
letterSpacing: "-0.01em"
|
|
9342
|
+
display: "flex",
|
|
9343
|
+
alignItems: "center",
|
|
9344
|
+
gap: "4px"
|
|
9025
9345
|
},
|
|
9026
|
-
children:
|
|
9346
|
+
children: /* @__PURE__ */ jsx9(
|
|
9347
|
+
"span",
|
|
9348
|
+
{
|
|
9349
|
+
style: {
|
|
9350
|
+
background: selectionColor,
|
|
9351
|
+
color: "white",
|
|
9352
|
+
fontSize: "11px",
|
|
9353
|
+
lineHeight: "20px",
|
|
9354
|
+
padding: "0 6px",
|
|
9355
|
+
borderRadius: "4px",
|
|
9356
|
+
whiteSpace: "nowrap",
|
|
9357
|
+
fontFamily: "system-ui, sans-serif",
|
|
9358
|
+
fontWeight: 500,
|
|
9359
|
+
letterSpacing: "-0.01em"
|
|
9360
|
+
},
|
|
9361
|
+
children: dimensionText
|
|
9362
|
+
}
|
|
9363
|
+
)
|
|
9027
9364
|
}
|
|
9028
9365
|
),
|
|
9029
9366
|
!isDragging && !isTextEditing && /* @__PURE__ */ jsxs5(
|
|
@@ -9079,7 +9416,7 @@ function SelectionOverlay({
|
|
|
9079
9416
|
position: "absolute",
|
|
9080
9417
|
width: RESIZE_CORNER_SIZE,
|
|
9081
9418
|
height: RESIZE_CORNER_SIZE,
|
|
9082
|
-
border: `1px solid ${
|
|
9419
|
+
border: `1px solid ${selectionColor}`,
|
|
9083
9420
|
background: "#fff",
|
|
9084
9421
|
borderRadius: 1,
|
|
9085
9422
|
boxSizing: "border-box",
|
|
@@ -12504,6 +12841,7 @@ function DirectEditPanelContent() {
|
|
|
12504
12841
|
computedColor,
|
|
12505
12842
|
computedBoxShadow,
|
|
12506
12843
|
computedTypography,
|
|
12844
|
+
isComponentPrimitive,
|
|
12507
12845
|
borderStyleControlPreference,
|
|
12508
12846
|
pendingStyles,
|
|
12509
12847
|
editModeActive,
|
|
@@ -12824,6 +13162,7 @@ function DirectEditPanelContent() {
|
|
|
12824
13162
|
selectElement(child);
|
|
12825
13163
|
}
|
|
12826
13164
|
},
|
|
13165
|
+
isComponentPrimitive,
|
|
12827
13166
|
enableResizeHandles: true,
|
|
12828
13167
|
onResizeSizingChange: updateSizingProperties
|
|
12829
13168
|
}
|