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.js
CHANGED
|
@@ -197,6 +197,228 @@ function getZoomScale() {
|
|
|
197
197
|
return snap.active ? snap.zoom : 1;
|
|
198
198
|
}
|
|
199
199
|
|
|
200
|
+
// src/utils/react-fiber.ts
|
|
201
|
+
function getFiberForElement(element) {
|
|
202
|
+
if (typeof window !== "undefined") {
|
|
203
|
+
const devtools = window.__DIRECT_EDIT_DEVTOOLS__;
|
|
204
|
+
if (devtools?.getFiberForElement) {
|
|
205
|
+
const fiber = devtools.getFiberForElement(element);
|
|
206
|
+
if (fiber) return fiber;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
const fiberKey = Object.keys(element).find(
|
|
210
|
+
(key) => key.startsWith("__reactFiber$") || key.startsWith("__reactInternalInstance$")
|
|
211
|
+
);
|
|
212
|
+
if (!fiberKey) return null;
|
|
213
|
+
return element[fiberKey] || null;
|
|
214
|
+
}
|
|
215
|
+
function getSourceFromFiber(fiber) {
|
|
216
|
+
const debugSource = fiber?._debugSource;
|
|
217
|
+
if (debugSource?.fileName) return debugSource;
|
|
218
|
+
const owner = fiber?._debugOwner;
|
|
219
|
+
const ownerPending = owner?.pendingProps?.__source;
|
|
220
|
+
if (ownerPending?.fileName) return ownerPending;
|
|
221
|
+
const ownerMemo = owner?.memoizedProps?.__source;
|
|
222
|
+
if (ownerMemo?.fileName) return ownerMemo;
|
|
223
|
+
const pending = fiber?.pendingProps?.__source;
|
|
224
|
+
if (pending?.fileName) return pending;
|
|
225
|
+
const memo = fiber?.memoizedProps?.__source;
|
|
226
|
+
if (memo?.fileName) return memo;
|
|
227
|
+
return null;
|
|
228
|
+
}
|
|
229
|
+
function buildFrame(fiber) {
|
|
230
|
+
const type = fiber?.type;
|
|
231
|
+
if (typeof type !== "function" && typeof type !== "object") return null;
|
|
232
|
+
const name = type?.displayName || type?.name || null;
|
|
233
|
+
if (!name || name === "Fragment") return null;
|
|
234
|
+
const frame = { name };
|
|
235
|
+
const source = getSourceFromFiber(fiber);
|
|
236
|
+
if (source?.fileName) {
|
|
237
|
+
frame.file = source.fileName;
|
|
238
|
+
if (typeof source.lineNumber === "number") {
|
|
239
|
+
frame.line = source.lineNumber;
|
|
240
|
+
}
|
|
241
|
+
if (typeof source.columnNumber === "number") {
|
|
242
|
+
frame.column = source.columnNumber;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
return frame;
|
|
246
|
+
}
|
|
247
|
+
function shouldIncludeFrame(frame, lastFrame) {
|
|
248
|
+
if (!lastFrame) return true;
|
|
249
|
+
if (frame.name !== lastFrame.name) return true;
|
|
250
|
+
if (!lastFrame.file && frame.file) return true;
|
|
251
|
+
if (lastFrame.file && frame.file && lastFrame.line == null && frame.line != null) return true;
|
|
252
|
+
if (lastFrame.file && frame.file && lastFrame.line != null && frame.line != null && lastFrame.column == null && frame.column != null) {
|
|
253
|
+
return true;
|
|
254
|
+
}
|
|
255
|
+
return false;
|
|
256
|
+
}
|
|
257
|
+
function getOwnerStack(fiber) {
|
|
258
|
+
const frames = [];
|
|
259
|
+
let current = fiber;
|
|
260
|
+
let lastFrame = null;
|
|
261
|
+
let nearestComponentFiber = null;
|
|
262
|
+
while (current) {
|
|
263
|
+
const frame = buildFrame(current);
|
|
264
|
+
if (frame && shouldIncludeFrame(frame, lastFrame)) {
|
|
265
|
+
frames.push(frame);
|
|
266
|
+
lastFrame = frame;
|
|
267
|
+
if (!nearestComponentFiber) {
|
|
268
|
+
nearestComponentFiber = current;
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
current = current._debugOwner;
|
|
272
|
+
}
|
|
273
|
+
return { frames, nearestComponentFiber };
|
|
274
|
+
}
|
|
275
|
+
function getRenderStack(fiber) {
|
|
276
|
+
const frames = [];
|
|
277
|
+
let current = fiber;
|
|
278
|
+
let lastFrame = null;
|
|
279
|
+
let nearestComponentFiber = null;
|
|
280
|
+
while (current) {
|
|
281
|
+
const frame = buildFrame(current);
|
|
282
|
+
if (frame && shouldIncludeFrame(frame, lastFrame)) {
|
|
283
|
+
frames.push(frame);
|
|
284
|
+
lastFrame = frame;
|
|
285
|
+
if (!nearestComponentFiber) {
|
|
286
|
+
nearestComponentFiber = current;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
current = current.return;
|
|
290
|
+
}
|
|
291
|
+
return { frames, nearestComponentFiber };
|
|
292
|
+
}
|
|
293
|
+
function getReactComponentInfo(element) {
|
|
294
|
+
const fiber = getFiberForElement(element);
|
|
295
|
+
if (!fiber) return { frames: [], nearestComponentFiber: null };
|
|
296
|
+
const elementSource = getSourceFromFiber(fiber);
|
|
297
|
+
const elementSourceFile = elementSource?.fileName || void 0;
|
|
298
|
+
const ownerResult = getOwnerStack(fiber);
|
|
299
|
+
if (ownerResult.frames.length > 0) {
|
|
300
|
+
return { ...ownerResult, elementSourceFile };
|
|
301
|
+
}
|
|
302
|
+
return { ...getRenderStack(fiber), elementSourceFile };
|
|
303
|
+
}
|
|
304
|
+
var EXCLUDED_PROP_KEYS = /* @__PURE__ */ new Set([
|
|
305
|
+
"className",
|
|
306
|
+
"style",
|
|
307
|
+
"children",
|
|
308
|
+
"ref",
|
|
309
|
+
"key",
|
|
310
|
+
"render"
|
|
311
|
+
]);
|
|
312
|
+
function serializePropValue(value) {
|
|
313
|
+
if (typeof value === "function") return "[function]";
|
|
314
|
+
if (typeof value === "symbol") return void 0;
|
|
315
|
+
if (value === void 0) return void 0;
|
|
316
|
+
if (value !== null && typeof value === "object") {
|
|
317
|
+
if ("$$typeof" in value) return "[element]";
|
|
318
|
+
try {
|
|
319
|
+
JSON.stringify(value);
|
|
320
|
+
return value;
|
|
321
|
+
} catch {
|
|
322
|
+
return "[object]";
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
return value;
|
|
326
|
+
}
|
|
327
|
+
function getComponentProps(fiber) {
|
|
328
|
+
const props = fiber?.memoizedProps ?? fiber?.pendingProps;
|
|
329
|
+
if (!props || typeof props !== "object") return {};
|
|
330
|
+
const result = {};
|
|
331
|
+
for (const [key, value] of Object.entries(props)) {
|
|
332
|
+
if (EXCLUDED_PROP_KEYS.has(key)) continue;
|
|
333
|
+
if (key.startsWith("data-")) continue;
|
|
334
|
+
const serialized = serializePropValue(value);
|
|
335
|
+
if (serialized !== void 0) {
|
|
336
|
+
result[key] = serialized;
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
return result;
|
|
340
|
+
}
|
|
341
|
+
function getCallSiteSource(fiber) {
|
|
342
|
+
const source = fiber?._debugSource;
|
|
343
|
+
if (source?.fileName) {
|
|
344
|
+
return {
|
|
345
|
+
file: source.fileName,
|
|
346
|
+
line: typeof source.lineNumber === "number" ? source.lineNumber : void 0,
|
|
347
|
+
column: typeof source.columnNumber === "number" ? source.columnNumber : void 0
|
|
348
|
+
};
|
|
349
|
+
}
|
|
350
|
+
const pending = fiber?.pendingProps?.__source;
|
|
351
|
+
if (pending?.fileName) {
|
|
352
|
+
return {
|
|
353
|
+
file: pending.fileName,
|
|
354
|
+
line: typeof pending.lineNumber === "number" ? pending.lineNumber : void 0,
|
|
355
|
+
column: typeof pending.columnNumber === "number" ? pending.columnNumber : void 0
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
return null;
|
|
359
|
+
}
|
|
360
|
+
function deriveDefinitionSource(frames) {
|
|
361
|
+
for (const frame of frames) {
|
|
362
|
+
if (frame.file && isComponentPrimitivePath(frame.file)) {
|
|
363
|
+
return { file: frame.file, line: frame.line, column: frame.column };
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
return null;
|
|
367
|
+
}
|
|
368
|
+
var PRIMITIVE_PATH_PATTERNS = [
|
|
369
|
+
/\/components\/ui\//,
|
|
370
|
+
/\/ui\/primitives\//,
|
|
371
|
+
/\/design-system\//
|
|
372
|
+
];
|
|
373
|
+
var PRIMITIVE_NPM_PATTERNS = [
|
|
374
|
+
/@base-ui\//,
|
|
375
|
+
/@radix-ui\//,
|
|
376
|
+
/@headlessui\//,
|
|
377
|
+
/@chakra-ui\//,
|
|
378
|
+
/@mantine\//,
|
|
379
|
+
/@mui\//,
|
|
380
|
+
/@ark-ui\//
|
|
381
|
+
];
|
|
382
|
+
var FRAMEWORK_EXCLUSION_PATTERNS = [
|
|
383
|
+
/node_modules\/react\//,
|
|
384
|
+
/node_modules\/react-dom\//,
|
|
385
|
+
/node_modules\/next\/dist\//,
|
|
386
|
+
/node_modules\/scheduler\//,
|
|
387
|
+
/node_modules\/react-server\//
|
|
388
|
+
];
|
|
389
|
+
function isComponentPrimitivePath(filePath) {
|
|
390
|
+
const normalized = filePath.replace(/\\/g, "/");
|
|
391
|
+
for (const pattern of FRAMEWORK_EXCLUSION_PATTERNS) {
|
|
392
|
+
if (pattern.test(normalized)) return false;
|
|
393
|
+
}
|
|
394
|
+
for (const pattern of PRIMITIVE_NPM_PATTERNS) {
|
|
395
|
+
if (pattern.test(normalized)) return true;
|
|
396
|
+
}
|
|
397
|
+
for (const pattern of PRIMITIVE_PATH_PATTERNS) {
|
|
398
|
+
if (pattern.test(normalized)) return true;
|
|
399
|
+
}
|
|
400
|
+
return false;
|
|
401
|
+
}
|
|
402
|
+
function classifyComponentFiber(fiber, frames, elementSourceFile) {
|
|
403
|
+
if (elementSourceFile && isComponentPrimitivePath(elementSourceFile)) {
|
|
404
|
+
return { isComponentPrimitive: true };
|
|
405
|
+
}
|
|
406
|
+
if (!fiber) return { isComponentPrimitive: false };
|
|
407
|
+
const callSite = getCallSiteSource(fiber);
|
|
408
|
+
if (callSite?.file && isComponentPrimitivePath(callSite.file)) {
|
|
409
|
+
return { isComponentPrimitive: true };
|
|
410
|
+
}
|
|
411
|
+
for (const frame of frames) {
|
|
412
|
+
if (frame.file && isComponentPrimitivePath(frame.file)) {
|
|
413
|
+
return { isComponentPrimitive: true };
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
if (!elementSourceFile && fiber._debugSource) {
|
|
417
|
+
return { isComponentPrimitive: true };
|
|
418
|
+
}
|
|
419
|
+
return { isComponentPrimitive: false };
|
|
420
|
+
}
|
|
421
|
+
|
|
200
422
|
// src/utils.ts
|
|
201
423
|
function clamp(value, min, max) {
|
|
202
424
|
if (!Number.isFinite(value)) return min;
|
|
@@ -1584,7 +1806,7 @@ function calculateDropPosition(container, pointerX, pointerY, draggedElement) {
|
|
|
1584
1806
|
};
|
|
1585
1807
|
return { insertBefore, indicator };
|
|
1586
1808
|
}
|
|
1587
|
-
function
|
|
1809
|
+
function getFiberForElement2(element) {
|
|
1588
1810
|
if (typeof window !== "undefined") {
|
|
1589
1811
|
const devtools = window.__DIRECT_EDIT_DEVTOOLS__;
|
|
1590
1812
|
if (devtools?.getFiberForElement) {
|
|
@@ -1845,7 +2067,7 @@ function getSourceFromDebugStack(fiber) {
|
|
|
1845
2067
|
}
|
|
1846
2068
|
return null;
|
|
1847
2069
|
}
|
|
1848
|
-
function
|
|
2070
|
+
function getSourceFromFiber2(fiber) {
|
|
1849
2071
|
const debugSource = fiber?._debugSource;
|
|
1850
2072
|
if (debugSource?.fileName) return debugSource;
|
|
1851
2073
|
const owner = fiber?._debugOwner;
|
|
@@ -1861,13 +2083,13 @@ function getSourceFromFiber(fiber) {
|
|
|
1861
2083
|
if (fromDebugStack?.fileName) return fromDebugStack;
|
|
1862
2084
|
return null;
|
|
1863
2085
|
}
|
|
1864
|
-
function
|
|
2086
|
+
function buildFrame2(fiber) {
|
|
1865
2087
|
const type = fiber?.type;
|
|
1866
2088
|
if (typeof type !== "function" && typeof type !== "object") return null;
|
|
1867
2089
|
const name = type?.displayName || type?.name || null;
|
|
1868
2090
|
if (!name || name === "Fragment") return null;
|
|
1869
2091
|
const frame = { name };
|
|
1870
|
-
const source =
|
|
2092
|
+
const source = getSourceFromFiber2(fiber);
|
|
1871
2093
|
if (source?.fileName) {
|
|
1872
2094
|
frame.file = source.fileName;
|
|
1873
2095
|
if (typeof source.lineNumber === "number") {
|
|
@@ -1879,7 +2101,7 @@ function buildFrame(fiber) {
|
|
|
1879
2101
|
}
|
|
1880
2102
|
return frame;
|
|
1881
2103
|
}
|
|
1882
|
-
function
|
|
2104
|
+
function shouldIncludeFrame2(frame, lastFrame) {
|
|
1883
2105
|
if (!lastFrame) return true;
|
|
1884
2106
|
if (frame.name !== lastFrame.name) return true;
|
|
1885
2107
|
if (!lastFrame.file && frame.file) return true;
|
|
@@ -1889,42 +2111,52 @@ function shouldIncludeFrame(frame, lastFrame) {
|
|
|
1889
2111
|
}
|
|
1890
2112
|
return false;
|
|
1891
2113
|
}
|
|
1892
|
-
function
|
|
2114
|
+
function getOwnerStack2(fiber) {
|
|
1893
2115
|
const frames = [];
|
|
1894
2116
|
let current = fiber;
|
|
1895
2117
|
let lastFrame = null;
|
|
2118
|
+
let nearestComponentFiber = null;
|
|
1896
2119
|
while (current) {
|
|
1897
|
-
const frame =
|
|
1898
|
-
if (frame &&
|
|
2120
|
+
const frame = buildFrame2(current);
|
|
2121
|
+
if (frame && shouldIncludeFrame2(frame, lastFrame)) {
|
|
1899
2122
|
frames.push(frame);
|
|
1900
2123
|
lastFrame = frame;
|
|
2124
|
+
if (!nearestComponentFiber) {
|
|
2125
|
+
nearestComponentFiber = current;
|
|
2126
|
+
}
|
|
1901
2127
|
}
|
|
1902
2128
|
current = current._debugOwner;
|
|
1903
2129
|
}
|
|
1904
|
-
return frames;
|
|
2130
|
+
return { frames, nearestComponentFiber };
|
|
1905
2131
|
}
|
|
1906
|
-
function
|
|
2132
|
+
function getRenderStack2(fiber) {
|
|
1907
2133
|
const frames = [];
|
|
1908
2134
|
let current = fiber;
|
|
1909
2135
|
let lastFrame = null;
|
|
2136
|
+
let nearestComponentFiber = null;
|
|
1910
2137
|
while (current) {
|
|
1911
|
-
const frame =
|
|
1912
|
-
if (frame &&
|
|
2138
|
+
const frame = buildFrame2(current);
|
|
2139
|
+
if (frame && shouldIncludeFrame2(frame, lastFrame)) {
|
|
1913
2140
|
frames.push(frame);
|
|
1914
2141
|
lastFrame = frame;
|
|
2142
|
+
if (!nearestComponentFiber) {
|
|
2143
|
+
nearestComponentFiber = current;
|
|
2144
|
+
}
|
|
1915
2145
|
}
|
|
1916
2146
|
current = current.return;
|
|
1917
2147
|
}
|
|
1918
|
-
return frames;
|
|
2148
|
+
return { frames, nearestComponentFiber };
|
|
1919
2149
|
}
|
|
1920
|
-
function
|
|
1921
|
-
const fiber =
|
|
1922
|
-
if (!fiber) return [];
|
|
1923
|
-
const
|
|
1924
|
-
|
|
1925
|
-
|
|
2150
|
+
function getReactComponentInfo2(element) {
|
|
2151
|
+
const fiber = getFiberForElement2(element);
|
|
2152
|
+
if (!fiber) return { frames: [], nearestComponentFiber: null };
|
|
2153
|
+
const elementSource = getSourceFromFiber2(fiber);
|
|
2154
|
+
const elementSourceFile = elementSource?.fileName || void 0;
|
|
2155
|
+
const ownerResult = getOwnerStack2(fiber);
|
|
2156
|
+
if (ownerResult.frames.length > 0) {
|
|
2157
|
+
return { ...ownerResult, elementSourceFile };
|
|
1926
2158
|
}
|
|
1927
|
-
return
|
|
2159
|
+
return { ...getRenderStack2(fiber), elementSourceFile };
|
|
1928
2160
|
}
|
|
1929
2161
|
function getElementDisplayName(element) {
|
|
1930
2162
|
const tag = element.tagName.toLowerCase();
|
|
@@ -2219,14 +2451,35 @@ function parseDomSource(element) {
|
|
|
2219
2451
|
}
|
|
2220
2452
|
return { file, line, column };
|
|
2221
2453
|
}
|
|
2454
|
+
var MAX_SUB_ELEMENT_SOURCES = 20;
|
|
2455
|
+
function collectSubElementSources(element) {
|
|
2456
|
+
const sources = {};
|
|
2457
|
+
const children = element.querySelectorAll("[data-direct-edit-source]");
|
|
2458
|
+
const labelCounts = /* @__PURE__ */ new Map();
|
|
2459
|
+
let count = 0;
|
|
2460
|
+
for (const child of children) {
|
|
2461
|
+
if (count >= MAX_SUB_ELEMENT_SOURCES) break;
|
|
2462
|
+
if (!(child instanceof HTMLElement)) continue;
|
|
2463
|
+
const source = parseDomSource(child);
|
|
2464
|
+
if (!source) continue;
|
|
2465
|
+
const text = ((child.innerText || child.textContent) ?? "").trim();
|
|
2466
|
+
let baseLabel = text.length > 0 && text.length <= 30 ? text.slice(0, 30).toLowerCase().replace(/\s+/g, "_") : child.tagName.toLowerCase();
|
|
2467
|
+
const existing = labelCounts.get(baseLabel) ?? 0;
|
|
2468
|
+
labelCounts.set(baseLabel, existing + 1);
|
|
2469
|
+
const label = existing > 0 ? `${baseLabel}_${existing + 1}` : baseLabel;
|
|
2470
|
+
sources[label] = source;
|
|
2471
|
+
count++;
|
|
2472
|
+
}
|
|
2473
|
+
return sources;
|
|
2474
|
+
}
|
|
2222
2475
|
function getElementSource(element) {
|
|
2223
2476
|
const domSource = parseDomSource(element);
|
|
2224
2477
|
if (domSource) return domSource;
|
|
2225
2478
|
const seenFibers = /* @__PURE__ */ new Set();
|
|
2226
|
-
let fiber =
|
|
2479
|
+
let fiber = getFiberForElement2(element);
|
|
2227
2480
|
while (fiber && !seenFibers.has(fiber)) {
|
|
2228
2481
|
seenFibers.add(fiber);
|
|
2229
|
-
const fiberSource =
|
|
2482
|
+
const fiberSource = getSourceFromFiber2(fiber);
|
|
2230
2483
|
if (fiberSource?.fileName) {
|
|
2231
2484
|
return {
|
|
2232
2485
|
file: fiberSource.fileName,
|
|
@@ -2241,8 +2494,15 @@ function getElementSource(element) {
|
|
|
2241
2494
|
function getElementLocator(element) {
|
|
2242
2495
|
const elementInfo = getElementInfo(element);
|
|
2243
2496
|
const domSource = getElementSource(element);
|
|
2497
|
+
const { frames, nearestComponentFiber, elementSourceFile } = getReactComponentInfo2(element);
|
|
2498
|
+
const componentName = nearestComponentFiber?.type?.displayName || nearestComponentFiber?.type?.name || void 0;
|
|
2499
|
+
const authoredProps = nearestComponentFiber ? getComponentProps(nearestComponentFiber) : void 0;
|
|
2500
|
+
const classification = classifyComponentFiber(nearestComponentFiber, frames, elementSourceFile);
|
|
2501
|
+
const callSite = nearestComponentFiber ? getCallSiteSource(nearestComponentFiber) : null;
|
|
2502
|
+
const definitionSrc = classification.isComponentPrimitive ? deriveDefinitionSource(frames) : null;
|
|
2503
|
+
const subSources = collectSubElementSources(element);
|
|
2244
2504
|
return {
|
|
2245
|
-
reactStack:
|
|
2505
|
+
reactStack: frames,
|
|
2246
2506
|
domSelector: buildDomSelector(element),
|
|
2247
2507
|
domContextHtml: buildDomContextHtml(element),
|
|
2248
2508
|
targetHtml: buildTargetHtml(element),
|
|
@@ -2250,36 +2510,80 @@ function getElementLocator(element) {
|
|
|
2250
2510
|
tagName: elementInfo.tagName,
|
|
2251
2511
|
id: elementInfo.id,
|
|
2252
2512
|
classList: elementInfo.classList,
|
|
2253
|
-
domSource: domSource ?? void 0
|
|
2513
|
+
domSource: domSource ?? void 0,
|
|
2514
|
+
reactComponentName: componentName,
|
|
2515
|
+
authoredProps: authoredProps && Object.keys(authoredProps).length > 0 ? authoredProps : void 0,
|
|
2516
|
+
subElementSources: Object.keys(subSources).length > 0 ? subSources : void 0,
|
|
2517
|
+
callSiteSource: callSite ?? void 0,
|
|
2518
|
+
definitionSource: definitionSrc ?? void 0,
|
|
2519
|
+
isComponentPrimitive: nearestComponentFiber || elementSourceFile ? classification.isComponentPrimitive : void 0
|
|
2254
2520
|
};
|
|
2255
2521
|
}
|
|
2256
2522
|
function getLocatorHeader(locator) {
|
|
2257
2523
|
const primaryFrame = getPrimaryFrame(locator);
|
|
2258
|
-
const componentLabel =
|
|
2259
|
-
|
|
2260
|
-
|
|
2524
|
+
const componentLabel = locator.reactComponentName ?? primaryFrame?.name ?? locator.tagName;
|
|
2525
|
+
let formattedSource;
|
|
2526
|
+
if (locator.isComponentPrimitive && locator.definitionSource?.file) {
|
|
2527
|
+
formattedSource = formatSourceLocation(
|
|
2528
|
+
locator.definitionSource.file,
|
|
2529
|
+
locator.definitionSource.line,
|
|
2530
|
+
locator.definitionSource.column
|
|
2531
|
+
);
|
|
2532
|
+
} else {
|
|
2533
|
+
formattedSource = locator.domSource?.file ? formatSourceLocation(locator.domSource.file, locator.domSource.line, locator.domSource.column) : primaryFrame?.file ? formatSourceLocation(primaryFrame.file, primaryFrame.line, primaryFrame.column) : null;
|
|
2534
|
+
}
|
|
2535
|
+
const formattedCallSite = locator.callSiteSource?.file ? formatSourceLocation(locator.callSiteSource.file, locator.callSiteSource.line, locator.callSiteSource.column) : null;
|
|
2536
|
+
return { componentLabel, formattedSource, formattedCallSite };
|
|
2537
|
+
}
|
|
2538
|
+
function formatComponentTree(reactStack) {
|
|
2539
|
+
const names = reactStack.map((f) => f.name).filter(Boolean);
|
|
2540
|
+
if (names.length === 0) return null;
|
|
2541
|
+
if (names.length === 1) return names[0];
|
|
2542
|
+
const [component, ...ancestors] = names;
|
|
2543
|
+
return `${component} (in ${ancestors.join(" > ")})`;
|
|
2261
2544
|
}
|
|
2262
2545
|
function buildLocatorContextLines(locator, options) {
|
|
2263
2546
|
const lines = [];
|
|
2264
|
-
const { componentLabel, formattedSource } = getLocatorHeader(locator);
|
|
2547
|
+
const { componentLabel, formattedSource, formattedCallSite } = getLocatorHeader(locator);
|
|
2265
2548
|
const target = (locator.targetHtml || locator.domContextHtml || "").trim();
|
|
2266
2549
|
const context = locator.domContextHtml?.trim() || "";
|
|
2267
|
-
const
|
|
2550
|
+
const path = locator.domSelector?.trim();
|
|
2268
2551
|
const text = locator.textPreview?.trim();
|
|
2269
2552
|
lines.push(`@<${componentLabel}>`);
|
|
2270
2553
|
lines.push("");
|
|
2554
|
+
const tree = formatComponentTree(locator.reactStack);
|
|
2555
|
+
if (tree) {
|
|
2556
|
+
lines.push(`react: ${tree}`);
|
|
2557
|
+
}
|
|
2558
|
+
if (locator.authoredProps && Object.keys(locator.authoredProps).length > 0) {
|
|
2559
|
+
lines.push(`props: ${JSON.stringify(locator.authoredProps)}`);
|
|
2560
|
+
}
|
|
2561
|
+
if (locator.isComponentPrimitive != null) {
|
|
2562
|
+
lines.push(`type: ${locator.isComponentPrimitive ? "component" : "instance"}`);
|
|
2563
|
+
}
|
|
2564
|
+
lines.push(`source: ${formattedSource ?? "(file not available)"}`);
|
|
2565
|
+
if (formattedCallSite && formattedCallSite !== formattedSource) {
|
|
2566
|
+
lines.push(`call-site: ${formattedCallSite}`);
|
|
2567
|
+
}
|
|
2568
|
+
if (locator.subElementSources && Object.keys(locator.subElementSources).length > 0) {
|
|
2569
|
+
lines.push("source-map:");
|
|
2570
|
+
for (const [label, source] of Object.entries(locator.subElementSources)) {
|
|
2571
|
+
lines.push(` - ${label}: ${formatSourceLocation(source.file, source.line, source.column)}`);
|
|
2572
|
+
}
|
|
2573
|
+
}
|
|
2574
|
+
if (path) {
|
|
2575
|
+
lines.push(`path: ${path}`);
|
|
2576
|
+
}
|
|
2271
2577
|
if (target) {
|
|
2578
|
+
lines.push("");
|
|
2272
2579
|
lines.push("target:");
|
|
2273
2580
|
lines.push(target);
|
|
2274
2581
|
}
|
|
2275
2582
|
if (!options?.skipContext && context && context !== target) {
|
|
2583
|
+
lines.push("");
|
|
2276
2584
|
lines.push("context:");
|
|
2277
2585
|
lines.push(context);
|
|
2278
2586
|
}
|
|
2279
|
-
lines.push(`in ${formattedSource ?? "(file not available)"}`);
|
|
2280
|
-
if (selector) {
|
|
2281
|
-
lines.push(`selector: ${selector}`);
|
|
2282
|
-
}
|
|
2283
2587
|
if (text) {
|
|
2284
2588
|
lines.push(`text: ${text}`);
|
|
2285
2589
|
}
|
|
@@ -4024,6 +4328,8 @@ function useSessionManager({
|
|
|
4024
4328
|
const originalStyles = options?.originalStyles ?? existingEdit?.originalStyles ?? getOriginalInlineStyles(nextSingleElement);
|
|
4025
4329
|
const pendingStyles = options?.pendingStyles ?? existingEdit?.pendingStyles ?? {};
|
|
4026
4330
|
const elementInfo = getElementInfo(nextSingleElement);
|
|
4331
|
+
const { frames, nearestComponentFiber, elementSourceFile } = getReactComponentInfo(nextSingleElement);
|
|
4332
|
+
const isPrimitive = classifyComponentFiber(nearestComponentFiber, frames, elementSourceFile).isComponentPrimitive;
|
|
4027
4333
|
setState((prev) => ({
|
|
4028
4334
|
comments: prev.activeCommentId ? prev.comments.filter((comment) => {
|
|
4029
4335
|
if (comment.id !== prev.activeCommentId) return true;
|
|
@@ -4042,6 +4348,7 @@ function useSessionManager({
|
|
|
4042
4348
|
computedColor: computed.color,
|
|
4043
4349
|
computedBoxShadow: computed.boxShadow,
|
|
4044
4350
|
computedTypography: computed.typography,
|
|
4351
|
+
isComponentPrimitive: isPrimitive,
|
|
4045
4352
|
originalStyles,
|
|
4046
4353
|
pendingStyles,
|
|
4047
4354
|
editModeActive: prev.editModeActive,
|
|
@@ -4072,6 +4379,7 @@ function useSessionManager({
|
|
|
4072
4379
|
computedColor: null,
|
|
4073
4380
|
computedBoxShadow: null,
|
|
4074
4381
|
computedTypography: null,
|
|
4382
|
+
isComponentPrimitive: false,
|
|
4075
4383
|
originalStyles: {},
|
|
4076
4384
|
pendingStyles: {},
|
|
4077
4385
|
activeCommentId: null,
|
|
@@ -4612,6 +4920,7 @@ function useSessionManager({
|
|
|
4612
4920
|
computedColor: computed.color,
|
|
4613
4921
|
computedBoxShadow: computed.boxShadow,
|
|
4614
4922
|
computedTypography: computed.typography,
|
|
4923
|
+
isComponentPrimitive: prev.isComponentPrimitive,
|
|
4615
4924
|
originalStyles: styleState.originalStyles,
|
|
4616
4925
|
pendingStyles: styleState.pendingStyles,
|
|
4617
4926
|
editModeActive: prev.editModeActive,
|
|
@@ -5396,6 +5705,8 @@ function withInstruction(profile, markdown) {
|
|
|
5396
5705
|
${markdown}` : markdown;
|
|
5397
5706
|
}
|
|
5398
5707
|
function buildLocatorPayload(locator) {
|
|
5708
|
+
const { componentLabel, formattedSource, formattedCallSite } = getLocatorHeader(locator);
|
|
5709
|
+
const reactTree = formatComponentTree(locator.reactStack);
|
|
5399
5710
|
return {
|
|
5400
5711
|
element: {
|
|
5401
5712
|
tagName: locator.tagName,
|
|
@@ -5403,10 +5714,22 @@ function buildLocatorPayload(locator) {
|
|
|
5403
5714
|
classList: locator.classList,
|
|
5404
5715
|
domSelector: locator.domSelector,
|
|
5405
5716
|
targetHtml: locator.targetHtml,
|
|
5717
|
+
contextHtml: locator.domContextHtml || null,
|
|
5406
5718
|
textPreview: locator.textPreview
|
|
5407
5719
|
},
|
|
5408
|
-
|
|
5409
|
-
|
|
5720
|
+
componentLabel,
|
|
5721
|
+
reactTree,
|
|
5722
|
+
reactStack: locator.reactStack,
|
|
5723
|
+
reactComponentName: locator.reactComponentName ?? null,
|
|
5724
|
+
authoredProps: locator.authoredProps ?? null,
|
|
5725
|
+
type: locator.isComponentPrimitive != null ? locator.isComponentPrimitive ? "component" : "instance" : null,
|
|
5726
|
+
isComponentPrimitive: locator.isComponentPrimitive ?? false,
|
|
5727
|
+
source: formattedSource,
|
|
5728
|
+
callSite: formattedCallSite,
|
|
5729
|
+
rawSource: locator.domSource || null,
|
|
5730
|
+
callSiteSource: locator.callSiteSource ?? null,
|
|
5731
|
+
definitionSource: locator.definitionSource ?? null,
|
|
5732
|
+
subElementSources: locator.subElementSources ?? null
|
|
5410
5733
|
};
|
|
5411
5734
|
}
|
|
5412
5735
|
function useAgentComms({ stateRef, sessionEditsRef, getSessionItems, saveCurrentToSession, removeSessionEdit, deleteComment }) {
|
|
@@ -6382,6 +6705,7 @@ function DirectEditProvider({ children }) {
|
|
|
6382
6705
|
computedColor: null,
|
|
6383
6706
|
computedBoxShadow: null,
|
|
6384
6707
|
computedTypography: null,
|
|
6708
|
+
isComponentPrimitive: false,
|
|
6385
6709
|
originalStyles: {},
|
|
6386
6710
|
pendingStyles: {},
|
|
6387
6711
|
editModeActive: false,
|
|
@@ -8674,6 +8998,7 @@ function useSelectionResize({
|
|
|
8674
8998
|
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
8675
8999
|
var BLUE3 = "#0D99FF";
|
|
8676
9000
|
var MAGENTA = "#E11BB6";
|
|
9001
|
+
var COMPONENT_PURPLE = "#8B5CF6";
|
|
8677
9002
|
var DRAG_THRESHOLD = 4;
|
|
8678
9003
|
var DBLCLICK_DELAY = 300;
|
|
8679
9004
|
var HANDLE_SIZE = 12;
|
|
@@ -8717,9 +9042,11 @@ function SelectionOverlay({
|
|
|
8717
9042
|
onHoverElement,
|
|
8718
9043
|
onClickThrough,
|
|
8719
9044
|
onSelectPageFrame,
|
|
9045
|
+
isComponentPrimitive = false,
|
|
8720
9046
|
enableResizeHandles = false,
|
|
8721
9047
|
onResizeSizingChange
|
|
8722
9048
|
}) {
|
|
9049
|
+
const selectionColor = isComponentPrimitive ? COMPONENT_PURPLE : BLUE3;
|
|
8723
9050
|
const rectElement = isDragging && draggedElement ? draggedElement : selectedElement;
|
|
8724
9051
|
const [rect, setRect] = React19.useState(() => rectElement.getBoundingClientRect());
|
|
8725
9052
|
const [pageFrameRect, setPageFrameRect] = React19.useState(() => pageFrameElement ? pageFrameElement.getBoundingClientRect() : null);
|
|
@@ -9047,7 +9374,7 @@ function SelectionOverlay({
|
|
|
9047
9374
|
zIndex: 99997,
|
|
9048
9375
|
background: "transparent",
|
|
9049
9376
|
border: "none",
|
|
9050
|
-
color:
|
|
9377
|
+
color: selectionColor,
|
|
9051
9378
|
fontSize: `${pageLabelFontSize}px`,
|
|
9052
9379
|
lineHeight: `${pageLabelLineHeight}px`,
|
|
9053
9380
|
padding: 0,
|
|
@@ -9075,7 +9402,7 @@ function SelectionOverlay({
|
|
|
9075
9402
|
height: rect.height,
|
|
9076
9403
|
pointerEvents: "none",
|
|
9077
9404
|
zIndex: 99996,
|
|
9078
|
-
border: `1px solid ${
|
|
9405
|
+
border: `1px solid ${selectionColor}`,
|
|
9079
9406
|
borderRadius: "0px",
|
|
9080
9407
|
boxSizing: "border-box"
|
|
9081
9408
|
}
|
|
@@ -9092,18 +9419,28 @@ function SelectionOverlay({
|
|
|
9092
9419
|
transform: "translateX(-50%)",
|
|
9093
9420
|
pointerEvents: "none",
|
|
9094
9421
|
zIndex: 99992,
|
|
9095
|
-
|
|
9096
|
-
|
|
9097
|
-
|
|
9098
|
-
lineHeight: "20px",
|
|
9099
|
-
padding: "0 6px",
|
|
9100
|
-
borderRadius: "4px",
|
|
9101
|
-
whiteSpace: "nowrap",
|
|
9102
|
-
fontFamily: "system-ui, sans-serif",
|
|
9103
|
-
fontWeight: 500,
|
|
9104
|
-
letterSpacing: "-0.01em"
|
|
9422
|
+
display: "flex",
|
|
9423
|
+
alignItems: "center",
|
|
9424
|
+
gap: "4px"
|
|
9105
9425
|
},
|
|
9106
|
-
children:
|
|
9426
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
9427
|
+
"span",
|
|
9428
|
+
{
|
|
9429
|
+
style: {
|
|
9430
|
+
background: selectionColor,
|
|
9431
|
+
color: "white",
|
|
9432
|
+
fontSize: "11px",
|
|
9433
|
+
lineHeight: "20px",
|
|
9434
|
+
padding: "0 6px",
|
|
9435
|
+
borderRadius: "4px",
|
|
9436
|
+
whiteSpace: "nowrap",
|
|
9437
|
+
fontFamily: "system-ui, sans-serif",
|
|
9438
|
+
fontWeight: 500,
|
|
9439
|
+
letterSpacing: "-0.01em"
|
|
9440
|
+
},
|
|
9441
|
+
children: dimensionText
|
|
9442
|
+
}
|
|
9443
|
+
)
|
|
9107
9444
|
}
|
|
9108
9445
|
),
|
|
9109
9446
|
!isDragging && !isTextEditing && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
@@ -9159,7 +9496,7 @@ function SelectionOverlay({
|
|
|
9159
9496
|
position: "absolute",
|
|
9160
9497
|
width: RESIZE_CORNER_SIZE,
|
|
9161
9498
|
height: RESIZE_CORNER_SIZE,
|
|
9162
|
-
border: `1px solid ${
|
|
9499
|
+
border: `1px solid ${selectionColor}`,
|
|
9163
9500
|
background: "#fff",
|
|
9164
9501
|
borderRadius: 1,
|
|
9165
9502
|
boxSizing: "border-box",
|
|
@@ -12533,6 +12870,7 @@ function DirectEditPanelContent() {
|
|
|
12533
12870
|
computedColor,
|
|
12534
12871
|
computedBoxShadow,
|
|
12535
12872
|
computedTypography,
|
|
12873
|
+
isComponentPrimitive,
|
|
12536
12874
|
borderStyleControlPreference,
|
|
12537
12875
|
pendingStyles,
|
|
12538
12876
|
editModeActive,
|
|
@@ -12853,6 +13191,7 @@ function DirectEditPanelContent() {
|
|
|
12853
13191
|
selectElement(child);
|
|
12854
13192
|
}
|
|
12855
13193
|
},
|
|
13194
|
+
isComponentPrimitive,
|
|
12856
13195
|
enableResizeHandles: true,
|
|
12857
13196
|
onResizeSizingChange: updateSizingProperties
|
|
12858
13197
|
}
|