made-refine 0.2.13 → 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 +385 -49
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +385 -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 +221 -19
- package/dist/utils.js.map +1 -1
- package/dist/utils.mjs +219 -19
- package/dist/utils.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -197,6 +197,225 @@ 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
|
+
return { isComponentPrimitive: false };
|
|
417
|
+
}
|
|
418
|
+
|
|
200
419
|
// src/utils.ts
|
|
201
420
|
function clamp(value, min, max) {
|
|
202
421
|
if (!Number.isFinite(value)) return min;
|
|
@@ -1584,7 +1803,7 @@ function calculateDropPosition(container, pointerX, pointerY, draggedElement) {
|
|
|
1584
1803
|
};
|
|
1585
1804
|
return { insertBefore, indicator };
|
|
1586
1805
|
}
|
|
1587
|
-
function
|
|
1806
|
+
function getFiberForElement2(element) {
|
|
1588
1807
|
if (typeof window !== "undefined") {
|
|
1589
1808
|
const devtools = window.__DIRECT_EDIT_DEVTOOLS__;
|
|
1590
1809
|
if (devtools?.getFiberForElement) {
|
|
@@ -1845,7 +2064,7 @@ function getSourceFromDebugStack(fiber) {
|
|
|
1845
2064
|
}
|
|
1846
2065
|
return null;
|
|
1847
2066
|
}
|
|
1848
|
-
function
|
|
2067
|
+
function getSourceFromFiber2(fiber) {
|
|
1849
2068
|
const debugSource = fiber?._debugSource;
|
|
1850
2069
|
if (debugSource?.fileName) return debugSource;
|
|
1851
2070
|
const owner = fiber?._debugOwner;
|
|
@@ -1861,13 +2080,13 @@ function getSourceFromFiber(fiber) {
|
|
|
1861
2080
|
if (fromDebugStack?.fileName) return fromDebugStack;
|
|
1862
2081
|
return null;
|
|
1863
2082
|
}
|
|
1864
|
-
function
|
|
2083
|
+
function buildFrame2(fiber) {
|
|
1865
2084
|
const type = fiber?.type;
|
|
1866
2085
|
if (typeof type !== "function" && typeof type !== "object") return null;
|
|
1867
2086
|
const name = type?.displayName || type?.name || null;
|
|
1868
2087
|
if (!name || name === "Fragment") return null;
|
|
1869
2088
|
const frame = { name };
|
|
1870
|
-
const source =
|
|
2089
|
+
const source = getSourceFromFiber2(fiber);
|
|
1871
2090
|
if (source?.fileName) {
|
|
1872
2091
|
frame.file = source.fileName;
|
|
1873
2092
|
if (typeof source.lineNumber === "number") {
|
|
@@ -1879,7 +2098,7 @@ function buildFrame(fiber) {
|
|
|
1879
2098
|
}
|
|
1880
2099
|
return frame;
|
|
1881
2100
|
}
|
|
1882
|
-
function
|
|
2101
|
+
function shouldIncludeFrame2(frame, lastFrame) {
|
|
1883
2102
|
if (!lastFrame) return true;
|
|
1884
2103
|
if (frame.name !== lastFrame.name) return true;
|
|
1885
2104
|
if (!lastFrame.file && frame.file) return true;
|
|
@@ -1889,42 +2108,52 @@ function shouldIncludeFrame(frame, lastFrame) {
|
|
|
1889
2108
|
}
|
|
1890
2109
|
return false;
|
|
1891
2110
|
}
|
|
1892
|
-
function
|
|
2111
|
+
function getOwnerStack2(fiber) {
|
|
1893
2112
|
const frames = [];
|
|
1894
2113
|
let current = fiber;
|
|
1895
2114
|
let lastFrame = null;
|
|
2115
|
+
let nearestComponentFiber = null;
|
|
1896
2116
|
while (current) {
|
|
1897
|
-
const frame =
|
|
1898
|
-
if (frame &&
|
|
2117
|
+
const frame = buildFrame2(current);
|
|
2118
|
+
if (frame && shouldIncludeFrame2(frame, lastFrame)) {
|
|
1899
2119
|
frames.push(frame);
|
|
1900
2120
|
lastFrame = frame;
|
|
2121
|
+
if (!nearestComponentFiber) {
|
|
2122
|
+
nearestComponentFiber = current;
|
|
2123
|
+
}
|
|
1901
2124
|
}
|
|
1902
2125
|
current = current._debugOwner;
|
|
1903
2126
|
}
|
|
1904
|
-
return frames;
|
|
2127
|
+
return { frames, nearestComponentFiber };
|
|
1905
2128
|
}
|
|
1906
|
-
function
|
|
2129
|
+
function getRenderStack2(fiber) {
|
|
1907
2130
|
const frames = [];
|
|
1908
2131
|
let current = fiber;
|
|
1909
2132
|
let lastFrame = null;
|
|
2133
|
+
let nearestComponentFiber = null;
|
|
1910
2134
|
while (current) {
|
|
1911
|
-
const frame =
|
|
1912
|
-
if (frame &&
|
|
2135
|
+
const frame = buildFrame2(current);
|
|
2136
|
+
if (frame && shouldIncludeFrame2(frame, lastFrame)) {
|
|
1913
2137
|
frames.push(frame);
|
|
1914
2138
|
lastFrame = frame;
|
|
2139
|
+
if (!nearestComponentFiber) {
|
|
2140
|
+
nearestComponentFiber = current;
|
|
2141
|
+
}
|
|
1915
2142
|
}
|
|
1916
2143
|
current = current.return;
|
|
1917
2144
|
}
|
|
1918
|
-
return frames;
|
|
2145
|
+
return { frames, nearestComponentFiber };
|
|
1919
2146
|
}
|
|
1920
|
-
function
|
|
1921
|
-
const fiber =
|
|
1922
|
-
if (!fiber) return [];
|
|
1923
|
-
const
|
|
1924
|
-
|
|
1925
|
-
|
|
2147
|
+
function getReactComponentInfo2(element) {
|
|
2148
|
+
const fiber = getFiberForElement2(element);
|
|
2149
|
+
if (!fiber) return { frames: [], nearestComponentFiber: null };
|
|
2150
|
+
const elementSource = getSourceFromFiber2(fiber);
|
|
2151
|
+
const elementSourceFile = elementSource?.fileName || void 0;
|
|
2152
|
+
const ownerResult = getOwnerStack2(fiber);
|
|
2153
|
+
if (ownerResult.frames.length > 0) {
|
|
2154
|
+
return { ...ownerResult, elementSourceFile };
|
|
1926
2155
|
}
|
|
1927
|
-
return
|
|
2156
|
+
return { ...getRenderStack2(fiber), elementSourceFile };
|
|
1928
2157
|
}
|
|
1929
2158
|
function getElementDisplayName(element) {
|
|
1930
2159
|
const tag = element.tagName.toLowerCase();
|
|
@@ -2219,14 +2448,35 @@ function parseDomSource(element) {
|
|
|
2219
2448
|
}
|
|
2220
2449
|
return { file, line, column };
|
|
2221
2450
|
}
|
|
2451
|
+
var MAX_SUB_ELEMENT_SOURCES = 20;
|
|
2452
|
+
function collectSubElementSources(element) {
|
|
2453
|
+
const sources = {};
|
|
2454
|
+
const children = element.querySelectorAll("[data-direct-edit-source]");
|
|
2455
|
+
const labelCounts = /* @__PURE__ */ new Map();
|
|
2456
|
+
let count = 0;
|
|
2457
|
+
for (const child of children) {
|
|
2458
|
+
if (count >= MAX_SUB_ELEMENT_SOURCES) break;
|
|
2459
|
+
if (!(child instanceof HTMLElement)) continue;
|
|
2460
|
+
const source = parseDomSource(child);
|
|
2461
|
+
if (!source) continue;
|
|
2462
|
+
const text = ((child.innerText || child.textContent) ?? "").trim();
|
|
2463
|
+
let baseLabel = text.length > 0 && text.length <= 30 ? text.slice(0, 30).toLowerCase().replace(/\s+/g, "_") : child.tagName.toLowerCase();
|
|
2464
|
+
const existing = labelCounts.get(baseLabel) ?? 0;
|
|
2465
|
+
labelCounts.set(baseLabel, existing + 1);
|
|
2466
|
+
const label = existing > 0 ? `${baseLabel}_${existing + 1}` : baseLabel;
|
|
2467
|
+
sources[label] = source;
|
|
2468
|
+
count++;
|
|
2469
|
+
}
|
|
2470
|
+
return sources;
|
|
2471
|
+
}
|
|
2222
2472
|
function getElementSource(element) {
|
|
2223
2473
|
const domSource = parseDomSource(element);
|
|
2224
2474
|
if (domSource) return domSource;
|
|
2225
2475
|
const seenFibers = /* @__PURE__ */ new Set();
|
|
2226
|
-
let fiber =
|
|
2476
|
+
let fiber = getFiberForElement2(element);
|
|
2227
2477
|
while (fiber && !seenFibers.has(fiber)) {
|
|
2228
2478
|
seenFibers.add(fiber);
|
|
2229
|
-
const fiberSource =
|
|
2479
|
+
const fiberSource = getSourceFromFiber2(fiber);
|
|
2230
2480
|
if (fiberSource?.fileName) {
|
|
2231
2481
|
return {
|
|
2232
2482
|
file: fiberSource.fileName,
|
|
@@ -2241,8 +2491,15 @@ function getElementSource(element) {
|
|
|
2241
2491
|
function getElementLocator(element) {
|
|
2242
2492
|
const elementInfo = getElementInfo(element);
|
|
2243
2493
|
const domSource = getElementSource(element);
|
|
2494
|
+
const { frames, nearestComponentFiber, elementSourceFile } = getReactComponentInfo2(element);
|
|
2495
|
+
const componentName = nearestComponentFiber?.type?.displayName || nearestComponentFiber?.type?.name || void 0;
|
|
2496
|
+
const authoredProps = nearestComponentFiber ? getComponentProps(nearestComponentFiber) : void 0;
|
|
2497
|
+
const classification = classifyComponentFiber(nearestComponentFiber, frames, elementSourceFile);
|
|
2498
|
+
const callSite = nearestComponentFiber ? getCallSiteSource(nearestComponentFiber) : null;
|
|
2499
|
+
const definitionSrc = classification.isComponentPrimitive ? deriveDefinitionSource(frames) : null;
|
|
2500
|
+
const subSources = collectSubElementSources(element);
|
|
2244
2501
|
return {
|
|
2245
|
-
reactStack:
|
|
2502
|
+
reactStack: frames,
|
|
2246
2503
|
domSelector: buildDomSelector(element),
|
|
2247
2504
|
domContextHtml: buildDomContextHtml(element),
|
|
2248
2505
|
targetHtml: buildTargetHtml(element),
|
|
@@ -2250,36 +2507,80 @@ function getElementLocator(element) {
|
|
|
2250
2507
|
tagName: elementInfo.tagName,
|
|
2251
2508
|
id: elementInfo.id,
|
|
2252
2509
|
classList: elementInfo.classList,
|
|
2253
|
-
domSource: domSource ?? void 0
|
|
2510
|
+
domSource: domSource ?? void 0,
|
|
2511
|
+
reactComponentName: componentName,
|
|
2512
|
+
authoredProps: authoredProps && Object.keys(authoredProps).length > 0 ? authoredProps : void 0,
|
|
2513
|
+
subElementSources: Object.keys(subSources).length > 0 ? subSources : void 0,
|
|
2514
|
+
callSiteSource: callSite ?? void 0,
|
|
2515
|
+
definitionSource: definitionSrc ?? void 0,
|
|
2516
|
+
isComponentPrimitive: nearestComponentFiber || elementSourceFile ? classification.isComponentPrimitive : void 0
|
|
2254
2517
|
};
|
|
2255
2518
|
}
|
|
2256
2519
|
function getLocatorHeader(locator) {
|
|
2257
2520
|
const primaryFrame = getPrimaryFrame(locator);
|
|
2258
|
-
const componentLabel =
|
|
2259
|
-
|
|
2260
|
-
|
|
2521
|
+
const componentLabel = locator.reactComponentName ?? primaryFrame?.name ?? locator.tagName;
|
|
2522
|
+
let formattedSource;
|
|
2523
|
+
if (locator.isComponentPrimitive && locator.definitionSource?.file) {
|
|
2524
|
+
formattedSource = formatSourceLocation(
|
|
2525
|
+
locator.definitionSource.file,
|
|
2526
|
+
locator.definitionSource.line,
|
|
2527
|
+
locator.definitionSource.column
|
|
2528
|
+
);
|
|
2529
|
+
} else {
|
|
2530
|
+
formattedSource = locator.domSource?.file ? formatSourceLocation(locator.domSource.file, locator.domSource.line, locator.domSource.column) : primaryFrame?.file ? formatSourceLocation(primaryFrame.file, primaryFrame.line, primaryFrame.column) : null;
|
|
2531
|
+
}
|
|
2532
|
+
const formattedCallSite = locator.callSiteSource?.file ? formatSourceLocation(locator.callSiteSource.file, locator.callSiteSource.line, locator.callSiteSource.column) : null;
|
|
2533
|
+
return { componentLabel, formattedSource, formattedCallSite };
|
|
2534
|
+
}
|
|
2535
|
+
function formatComponentTree(reactStack) {
|
|
2536
|
+
const names = reactStack.map((f) => f.name).filter(Boolean);
|
|
2537
|
+
if (names.length === 0) return null;
|
|
2538
|
+
if (names.length === 1) return names[0];
|
|
2539
|
+
const [component, ...ancestors] = names;
|
|
2540
|
+
return `${component} (in ${ancestors.join(" > ")})`;
|
|
2261
2541
|
}
|
|
2262
2542
|
function buildLocatorContextLines(locator, options) {
|
|
2263
2543
|
const lines = [];
|
|
2264
|
-
const { componentLabel, formattedSource } = getLocatorHeader(locator);
|
|
2544
|
+
const { componentLabel, formattedSource, formattedCallSite } = getLocatorHeader(locator);
|
|
2265
2545
|
const target = (locator.targetHtml || locator.domContextHtml || "").trim();
|
|
2266
2546
|
const context = locator.domContextHtml?.trim() || "";
|
|
2267
|
-
const
|
|
2547
|
+
const path = locator.domSelector?.trim();
|
|
2268
2548
|
const text = locator.textPreview?.trim();
|
|
2269
2549
|
lines.push(`@<${componentLabel}>`);
|
|
2270
2550
|
lines.push("");
|
|
2551
|
+
const tree = formatComponentTree(locator.reactStack);
|
|
2552
|
+
if (tree) {
|
|
2553
|
+
lines.push(`react: ${tree}`);
|
|
2554
|
+
}
|
|
2555
|
+
if (locator.authoredProps && Object.keys(locator.authoredProps).length > 0) {
|
|
2556
|
+
lines.push(`props: ${JSON.stringify(locator.authoredProps)}`);
|
|
2557
|
+
}
|
|
2558
|
+
if (locator.isComponentPrimitive != null) {
|
|
2559
|
+
lines.push(`type: ${locator.isComponentPrimitive ? "component" : "instance"}`);
|
|
2560
|
+
}
|
|
2561
|
+
lines.push(`source: ${formattedSource ?? "(file not available)"}`);
|
|
2562
|
+
if (formattedCallSite && formattedCallSite !== formattedSource) {
|
|
2563
|
+
lines.push(`call-site: ${formattedCallSite}`);
|
|
2564
|
+
}
|
|
2565
|
+
if (locator.subElementSources && Object.keys(locator.subElementSources).length > 0) {
|
|
2566
|
+
lines.push("source-map:");
|
|
2567
|
+
for (const [label, source] of Object.entries(locator.subElementSources)) {
|
|
2568
|
+
lines.push(` - ${label}: ${formatSourceLocation(source.file, source.line, source.column)}`);
|
|
2569
|
+
}
|
|
2570
|
+
}
|
|
2571
|
+
if (path) {
|
|
2572
|
+
lines.push(`path: ${path}`);
|
|
2573
|
+
}
|
|
2271
2574
|
if (target) {
|
|
2575
|
+
lines.push("");
|
|
2272
2576
|
lines.push("target:");
|
|
2273
2577
|
lines.push(target);
|
|
2274
2578
|
}
|
|
2275
2579
|
if (!options?.skipContext && context && context !== target) {
|
|
2580
|
+
lines.push("");
|
|
2276
2581
|
lines.push("context:");
|
|
2277
2582
|
lines.push(context);
|
|
2278
2583
|
}
|
|
2279
|
-
lines.push(`in ${formattedSource ?? "(file not available)"}`);
|
|
2280
|
-
if (selector) {
|
|
2281
|
-
lines.push(`selector: ${selector}`);
|
|
2282
|
-
}
|
|
2283
2584
|
if (text) {
|
|
2284
2585
|
lines.push(`text: ${text}`);
|
|
2285
2586
|
}
|
|
@@ -4024,6 +4325,8 @@ function useSessionManager({
|
|
|
4024
4325
|
const originalStyles = options?.originalStyles ?? existingEdit?.originalStyles ?? getOriginalInlineStyles(nextSingleElement);
|
|
4025
4326
|
const pendingStyles = options?.pendingStyles ?? existingEdit?.pendingStyles ?? {};
|
|
4026
4327
|
const elementInfo = getElementInfo(nextSingleElement);
|
|
4328
|
+
const { frames, nearestComponentFiber, elementSourceFile } = getReactComponentInfo(nextSingleElement);
|
|
4329
|
+
const isPrimitive = classifyComponentFiber(nearestComponentFiber, frames, elementSourceFile).isComponentPrimitive;
|
|
4027
4330
|
setState((prev) => ({
|
|
4028
4331
|
comments: prev.activeCommentId ? prev.comments.filter((comment) => {
|
|
4029
4332
|
if (comment.id !== prev.activeCommentId) return true;
|
|
@@ -4042,6 +4345,7 @@ function useSessionManager({
|
|
|
4042
4345
|
computedColor: computed.color,
|
|
4043
4346
|
computedBoxShadow: computed.boxShadow,
|
|
4044
4347
|
computedTypography: computed.typography,
|
|
4348
|
+
isComponentPrimitive: isPrimitive,
|
|
4045
4349
|
originalStyles,
|
|
4046
4350
|
pendingStyles,
|
|
4047
4351
|
editModeActive: prev.editModeActive,
|
|
@@ -4072,6 +4376,7 @@ function useSessionManager({
|
|
|
4072
4376
|
computedColor: null,
|
|
4073
4377
|
computedBoxShadow: null,
|
|
4074
4378
|
computedTypography: null,
|
|
4379
|
+
isComponentPrimitive: false,
|
|
4075
4380
|
originalStyles: {},
|
|
4076
4381
|
pendingStyles: {},
|
|
4077
4382
|
activeCommentId: null,
|
|
@@ -4612,6 +4917,7 @@ function useSessionManager({
|
|
|
4612
4917
|
computedColor: computed.color,
|
|
4613
4918
|
computedBoxShadow: computed.boxShadow,
|
|
4614
4919
|
computedTypography: computed.typography,
|
|
4920
|
+
isComponentPrimitive: prev.isComponentPrimitive,
|
|
4615
4921
|
originalStyles: styleState.originalStyles,
|
|
4616
4922
|
pendingStyles: styleState.pendingStyles,
|
|
4617
4923
|
editModeActive: prev.editModeActive,
|
|
@@ -5396,6 +5702,8 @@ function withInstruction(profile, markdown) {
|
|
|
5396
5702
|
${markdown}` : markdown;
|
|
5397
5703
|
}
|
|
5398
5704
|
function buildLocatorPayload(locator) {
|
|
5705
|
+
const { componentLabel, formattedSource, formattedCallSite } = getLocatorHeader(locator);
|
|
5706
|
+
const reactTree = formatComponentTree(locator.reactStack);
|
|
5399
5707
|
return {
|
|
5400
5708
|
element: {
|
|
5401
5709
|
tagName: locator.tagName,
|
|
@@ -5403,10 +5711,22 @@ function buildLocatorPayload(locator) {
|
|
|
5403
5711
|
classList: locator.classList,
|
|
5404
5712
|
domSelector: locator.domSelector,
|
|
5405
5713
|
targetHtml: locator.targetHtml,
|
|
5714
|
+
contextHtml: locator.domContextHtml || null,
|
|
5406
5715
|
textPreview: locator.textPreview
|
|
5407
5716
|
},
|
|
5408
|
-
|
|
5409
|
-
|
|
5717
|
+
componentLabel,
|
|
5718
|
+
reactTree,
|
|
5719
|
+
reactStack: locator.reactStack,
|
|
5720
|
+
reactComponentName: locator.reactComponentName ?? null,
|
|
5721
|
+
authoredProps: locator.authoredProps ?? null,
|
|
5722
|
+
type: locator.isComponentPrimitive != null ? locator.isComponentPrimitive ? "component" : "instance" : null,
|
|
5723
|
+
isComponentPrimitive: locator.isComponentPrimitive ?? false,
|
|
5724
|
+
source: formattedSource,
|
|
5725
|
+
callSite: formattedCallSite,
|
|
5726
|
+
rawSource: locator.domSource || null,
|
|
5727
|
+
callSiteSource: locator.callSiteSource ?? null,
|
|
5728
|
+
definitionSource: locator.definitionSource ?? null,
|
|
5729
|
+
subElementSources: locator.subElementSources ?? null
|
|
5410
5730
|
};
|
|
5411
5731
|
}
|
|
5412
5732
|
function useAgentComms({ stateRef, sessionEditsRef, getSessionItems, saveCurrentToSession, removeSessionEdit, deleteComment }) {
|
|
@@ -6382,6 +6702,7 @@ function DirectEditProvider({ children }) {
|
|
|
6382
6702
|
computedColor: null,
|
|
6383
6703
|
computedBoxShadow: null,
|
|
6384
6704
|
computedTypography: null,
|
|
6705
|
+
isComponentPrimitive: false,
|
|
6385
6706
|
originalStyles: {},
|
|
6386
6707
|
pendingStyles: {},
|
|
6387
6708
|
editModeActive: false,
|
|
@@ -8674,6 +8995,7 @@ function useSelectionResize({
|
|
|
8674
8995
|
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
8675
8996
|
var BLUE3 = "#0D99FF";
|
|
8676
8997
|
var MAGENTA = "#E11BB6";
|
|
8998
|
+
var COMPONENT_PURPLE = "#8B5CF6";
|
|
8677
8999
|
var DRAG_THRESHOLD = 4;
|
|
8678
9000
|
var DBLCLICK_DELAY = 300;
|
|
8679
9001
|
var HANDLE_SIZE = 12;
|
|
@@ -8717,9 +9039,11 @@ function SelectionOverlay({
|
|
|
8717
9039
|
onHoverElement,
|
|
8718
9040
|
onClickThrough,
|
|
8719
9041
|
onSelectPageFrame,
|
|
9042
|
+
isComponentPrimitive = false,
|
|
8720
9043
|
enableResizeHandles = false,
|
|
8721
9044
|
onResizeSizingChange
|
|
8722
9045
|
}) {
|
|
9046
|
+
const selectionColor = isComponentPrimitive ? COMPONENT_PURPLE : BLUE3;
|
|
8723
9047
|
const rectElement = isDragging && draggedElement ? draggedElement : selectedElement;
|
|
8724
9048
|
const [rect, setRect] = React19.useState(() => rectElement.getBoundingClientRect());
|
|
8725
9049
|
const [pageFrameRect, setPageFrameRect] = React19.useState(() => pageFrameElement ? pageFrameElement.getBoundingClientRect() : null);
|
|
@@ -9047,7 +9371,7 @@ function SelectionOverlay({
|
|
|
9047
9371
|
zIndex: 99997,
|
|
9048
9372
|
background: "transparent",
|
|
9049
9373
|
border: "none",
|
|
9050
|
-
color:
|
|
9374
|
+
color: selectionColor,
|
|
9051
9375
|
fontSize: `${pageLabelFontSize}px`,
|
|
9052
9376
|
lineHeight: `${pageLabelLineHeight}px`,
|
|
9053
9377
|
padding: 0,
|
|
@@ -9075,7 +9399,7 @@ function SelectionOverlay({
|
|
|
9075
9399
|
height: rect.height,
|
|
9076
9400
|
pointerEvents: "none",
|
|
9077
9401
|
zIndex: 99996,
|
|
9078
|
-
border: `1px solid ${
|
|
9402
|
+
border: `1px solid ${selectionColor}`,
|
|
9079
9403
|
borderRadius: "0px",
|
|
9080
9404
|
boxSizing: "border-box"
|
|
9081
9405
|
}
|
|
@@ -9092,18 +9416,28 @@ function SelectionOverlay({
|
|
|
9092
9416
|
transform: "translateX(-50%)",
|
|
9093
9417
|
pointerEvents: "none",
|
|
9094
9418
|
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"
|
|
9419
|
+
display: "flex",
|
|
9420
|
+
alignItems: "center",
|
|
9421
|
+
gap: "4px"
|
|
9105
9422
|
},
|
|
9106
|
-
children:
|
|
9423
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
9424
|
+
"span",
|
|
9425
|
+
{
|
|
9426
|
+
style: {
|
|
9427
|
+
background: selectionColor,
|
|
9428
|
+
color: "white",
|
|
9429
|
+
fontSize: "11px",
|
|
9430
|
+
lineHeight: "20px",
|
|
9431
|
+
padding: "0 6px",
|
|
9432
|
+
borderRadius: "4px",
|
|
9433
|
+
whiteSpace: "nowrap",
|
|
9434
|
+
fontFamily: "system-ui, sans-serif",
|
|
9435
|
+
fontWeight: 500,
|
|
9436
|
+
letterSpacing: "-0.01em"
|
|
9437
|
+
},
|
|
9438
|
+
children: dimensionText
|
|
9439
|
+
}
|
|
9440
|
+
)
|
|
9107
9441
|
}
|
|
9108
9442
|
),
|
|
9109
9443
|
!isDragging && !isTextEditing && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
@@ -9159,7 +9493,7 @@ function SelectionOverlay({
|
|
|
9159
9493
|
position: "absolute",
|
|
9160
9494
|
width: RESIZE_CORNER_SIZE,
|
|
9161
9495
|
height: RESIZE_CORNER_SIZE,
|
|
9162
|
-
border: `1px solid ${
|
|
9496
|
+
border: `1px solid ${selectionColor}`,
|
|
9163
9497
|
background: "#fff",
|
|
9164
9498
|
borderRadius: 1,
|
|
9165
9499
|
boxSizing: "border-box",
|
|
@@ -12533,6 +12867,7 @@ function DirectEditPanelContent() {
|
|
|
12533
12867
|
computedColor,
|
|
12534
12868
|
computedBoxShadow,
|
|
12535
12869
|
computedTypography,
|
|
12870
|
+
isComponentPrimitive,
|
|
12536
12871
|
borderStyleControlPreference,
|
|
12537
12872
|
pendingStyles,
|
|
12538
12873
|
editModeActive,
|
|
@@ -12853,6 +13188,7 @@ function DirectEditPanelContent() {
|
|
|
12853
13188
|
selectElement(child);
|
|
12854
13189
|
}
|
|
12855
13190
|
},
|
|
13191
|
+
isComponentPrimitive,
|
|
12856
13192
|
enableResizeHandles: true,
|
|
12857
13193
|
onResizeSizingChange: updateSizingProperties
|
|
12858
13194
|
}
|