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.mjs
CHANGED
|
@@ -117,6 +117,225 @@ 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
|
+
return { isComponentPrimitive: false };
|
|
337
|
+
}
|
|
338
|
+
|
|
120
339
|
// src/utils.ts
|
|
121
340
|
function clamp(value, min, max) {
|
|
122
341
|
if (!Number.isFinite(value)) return min;
|
|
@@ -1504,7 +1723,7 @@ function calculateDropPosition(container, pointerX, pointerY, draggedElement) {
|
|
|
1504
1723
|
};
|
|
1505
1724
|
return { insertBefore, indicator };
|
|
1506
1725
|
}
|
|
1507
|
-
function
|
|
1726
|
+
function getFiberForElement2(element) {
|
|
1508
1727
|
if (typeof window !== "undefined") {
|
|
1509
1728
|
const devtools = window.__DIRECT_EDIT_DEVTOOLS__;
|
|
1510
1729
|
if (devtools?.getFiberForElement) {
|
|
@@ -1765,7 +1984,7 @@ function getSourceFromDebugStack(fiber) {
|
|
|
1765
1984
|
}
|
|
1766
1985
|
return null;
|
|
1767
1986
|
}
|
|
1768
|
-
function
|
|
1987
|
+
function getSourceFromFiber2(fiber) {
|
|
1769
1988
|
const debugSource = fiber?._debugSource;
|
|
1770
1989
|
if (debugSource?.fileName) return debugSource;
|
|
1771
1990
|
const owner = fiber?._debugOwner;
|
|
@@ -1781,13 +2000,13 @@ function getSourceFromFiber(fiber) {
|
|
|
1781
2000
|
if (fromDebugStack?.fileName) return fromDebugStack;
|
|
1782
2001
|
return null;
|
|
1783
2002
|
}
|
|
1784
|
-
function
|
|
2003
|
+
function buildFrame2(fiber) {
|
|
1785
2004
|
const type = fiber?.type;
|
|
1786
2005
|
if (typeof type !== "function" && typeof type !== "object") return null;
|
|
1787
2006
|
const name = type?.displayName || type?.name || null;
|
|
1788
2007
|
if (!name || name === "Fragment") return null;
|
|
1789
2008
|
const frame = { name };
|
|
1790
|
-
const source =
|
|
2009
|
+
const source = getSourceFromFiber2(fiber);
|
|
1791
2010
|
if (source?.fileName) {
|
|
1792
2011
|
frame.file = source.fileName;
|
|
1793
2012
|
if (typeof source.lineNumber === "number") {
|
|
@@ -1799,7 +2018,7 @@ function buildFrame(fiber) {
|
|
|
1799
2018
|
}
|
|
1800
2019
|
return frame;
|
|
1801
2020
|
}
|
|
1802
|
-
function
|
|
2021
|
+
function shouldIncludeFrame2(frame, lastFrame) {
|
|
1803
2022
|
if (!lastFrame) return true;
|
|
1804
2023
|
if (frame.name !== lastFrame.name) return true;
|
|
1805
2024
|
if (!lastFrame.file && frame.file) return true;
|
|
@@ -1809,42 +2028,52 @@ function shouldIncludeFrame(frame, lastFrame) {
|
|
|
1809
2028
|
}
|
|
1810
2029
|
return false;
|
|
1811
2030
|
}
|
|
1812
|
-
function
|
|
2031
|
+
function getOwnerStack2(fiber) {
|
|
1813
2032
|
const frames = [];
|
|
1814
2033
|
let current = fiber;
|
|
1815
2034
|
let lastFrame = null;
|
|
2035
|
+
let nearestComponentFiber = null;
|
|
1816
2036
|
while (current) {
|
|
1817
|
-
const frame =
|
|
1818
|
-
if (frame &&
|
|
2037
|
+
const frame = buildFrame2(current);
|
|
2038
|
+
if (frame && shouldIncludeFrame2(frame, lastFrame)) {
|
|
1819
2039
|
frames.push(frame);
|
|
1820
2040
|
lastFrame = frame;
|
|
2041
|
+
if (!nearestComponentFiber) {
|
|
2042
|
+
nearestComponentFiber = current;
|
|
2043
|
+
}
|
|
1821
2044
|
}
|
|
1822
2045
|
current = current._debugOwner;
|
|
1823
2046
|
}
|
|
1824
|
-
return frames;
|
|
2047
|
+
return { frames, nearestComponentFiber };
|
|
1825
2048
|
}
|
|
1826
|
-
function
|
|
2049
|
+
function getRenderStack2(fiber) {
|
|
1827
2050
|
const frames = [];
|
|
1828
2051
|
let current = fiber;
|
|
1829
2052
|
let lastFrame = null;
|
|
2053
|
+
let nearestComponentFiber = null;
|
|
1830
2054
|
while (current) {
|
|
1831
|
-
const frame =
|
|
1832
|
-
if (frame &&
|
|
2055
|
+
const frame = buildFrame2(current);
|
|
2056
|
+
if (frame && shouldIncludeFrame2(frame, lastFrame)) {
|
|
1833
2057
|
frames.push(frame);
|
|
1834
2058
|
lastFrame = frame;
|
|
2059
|
+
if (!nearestComponentFiber) {
|
|
2060
|
+
nearestComponentFiber = current;
|
|
2061
|
+
}
|
|
1835
2062
|
}
|
|
1836
2063
|
current = current.return;
|
|
1837
2064
|
}
|
|
1838
|
-
return frames;
|
|
2065
|
+
return { frames, nearestComponentFiber };
|
|
1839
2066
|
}
|
|
1840
|
-
function
|
|
1841
|
-
const fiber =
|
|
1842
|
-
if (!fiber) return [];
|
|
1843
|
-
const
|
|
1844
|
-
|
|
1845
|
-
|
|
2067
|
+
function getReactComponentInfo2(element) {
|
|
2068
|
+
const fiber = getFiberForElement2(element);
|
|
2069
|
+
if (!fiber) return { frames: [], nearestComponentFiber: null };
|
|
2070
|
+
const elementSource = getSourceFromFiber2(fiber);
|
|
2071
|
+
const elementSourceFile = elementSource?.fileName || void 0;
|
|
2072
|
+
const ownerResult = getOwnerStack2(fiber);
|
|
2073
|
+
if (ownerResult.frames.length > 0) {
|
|
2074
|
+
return { ...ownerResult, elementSourceFile };
|
|
1846
2075
|
}
|
|
1847
|
-
return
|
|
2076
|
+
return { ...getRenderStack2(fiber), elementSourceFile };
|
|
1848
2077
|
}
|
|
1849
2078
|
function getElementDisplayName(element) {
|
|
1850
2079
|
const tag = element.tagName.toLowerCase();
|
|
@@ -2139,14 +2368,35 @@ function parseDomSource(element) {
|
|
|
2139
2368
|
}
|
|
2140
2369
|
return { file, line, column };
|
|
2141
2370
|
}
|
|
2371
|
+
var MAX_SUB_ELEMENT_SOURCES = 20;
|
|
2372
|
+
function collectSubElementSources(element) {
|
|
2373
|
+
const sources = {};
|
|
2374
|
+
const children = element.querySelectorAll("[data-direct-edit-source]");
|
|
2375
|
+
const labelCounts = /* @__PURE__ */ new Map();
|
|
2376
|
+
let count = 0;
|
|
2377
|
+
for (const child of children) {
|
|
2378
|
+
if (count >= MAX_SUB_ELEMENT_SOURCES) break;
|
|
2379
|
+
if (!(child instanceof HTMLElement)) continue;
|
|
2380
|
+
const source = parseDomSource(child);
|
|
2381
|
+
if (!source) continue;
|
|
2382
|
+
const text = ((child.innerText || child.textContent) ?? "").trim();
|
|
2383
|
+
let baseLabel = text.length > 0 && text.length <= 30 ? text.slice(0, 30).toLowerCase().replace(/\s+/g, "_") : child.tagName.toLowerCase();
|
|
2384
|
+
const existing = labelCounts.get(baseLabel) ?? 0;
|
|
2385
|
+
labelCounts.set(baseLabel, existing + 1);
|
|
2386
|
+
const label = existing > 0 ? `${baseLabel}_${existing + 1}` : baseLabel;
|
|
2387
|
+
sources[label] = source;
|
|
2388
|
+
count++;
|
|
2389
|
+
}
|
|
2390
|
+
return sources;
|
|
2391
|
+
}
|
|
2142
2392
|
function getElementSource(element) {
|
|
2143
2393
|
const domSource = parseDomSource(element);
|
|
2144
2394
|
if (domSource) return domSource;
|
|
2145
2395
|
const seenFibers = /* @__PURE__ */ new Set();
|
|
2146
|
-
let fiber =
|
|
2396
|
+
let fiber = getFiberForElement2(element);
|
|
2147
2397
|
while (fiber && !seenFibers.has(fiber)) {
|
|
2148
2398
|
seenFibers.add(fiber);
|
|
2149
|
-
const fiberSource =
|
|
2399
|
+
const fiberSource = getSourceFromFiber2(fiber);
|
|
2150
2400
|
if (fiberSource?.fileName) {
|
|
2151
2401
|
return {
|
|
2152
2402
|
file: fiberSource.fileName,
|
|
@@ -2161,8 +2411,15 @@ function getElementSource(element) {
|
|
|
2161
2411
|
function getElementLocator(element) {
|
|
2162
2412
|
const elementInfo = getElementInfo(element);
|
|
2163
2413
|
const domSource = getElementSource(element);
|
|
2414
|
+
const { frames, nearestComponentFiber, elementSourceFile } = getReactComponentInfo2(element);
|
|
2415
|
+
const componentName = nearestComponentFiber?.type?.displayName || nearestComponentFiber?.type?.name || void 0;
|
|
2416
|
+
const authoredProps = nearestComponentFiber ? getComponentProps(nearestComponentFiber) : void 0;
|
|
2417
|
+
const classification = classifyComponentFiber(nearestComponentFiber, frames, elementSourceFile);
|
|
2418
|
+
const callSite = nearestComponentFiber ? getCallSiteSource(nearestComponentFiber) : null;
|
|
2419
|
+
const definitionSrc = classification.isComponentPrimitive ? deriveDefinitionSource(frames) : null;
|
|
2420
|
+
const subSources = collectSubElementSources(element);
|
|
2164
2421
|
return {
|
|
2165
|
-
reactStack:
|
|
2422
|
+
reactStack: frames,
|
|
2166
2423
|
domSelector: buildDomSelector(element),
|
|
2167
2424
|
domContextHtml: buildDomContextHtml(element),
|
|
2168
2425
|
targetHtml: buildTargetHtml(element),
|
|
@@ -2170,36 +2427,80 @@ function getElementLocator(element) {
|
|
|
2170
2427
|
tagName: elementInfo.tagName,
|
|
2171
2428
|
id: elementInfo.id,
|
|
2172
2429
|
classList: elementInfo.classList,
|
|
2173
|
-
domSource: domSource ?? void 0
|
|
2430
|
+
domSource: domSource ?? void 0,
|
|
2431
|
+
reactComponentName: componentName,
|
|
2432
|
+
authoredProps: authoredProps && Object.keys(authoredProps).length > 0 ? authoredProps : void 0,
|
|
2433
|
+
subElementSources: Object.keys(subSources).length > 0 ? subSources : void 0,
|
|
2434
|
+
callSiteSource: callSite ?? void 0,
|
|
2435
|
+
definitionSource: definitionSrc ?? void 0,
|
|
2436
|
+
isComponentPrimitive: nearestComponentFiber || elementSourceFile ? classification.isComponentPrimitive : void 0
|
|
2174
2437
|
};
|
|
2175
2438
|
}
|
|
2176
2439
|
function getLocatorHeader(locator) {
|
|
2177
2440
|
const primaryFrame = getPrimaryFrame(locator);
|
|
2178
|
-
const componentLabel =
|
|
2179
|
-
|
|
2180
|
-
|
|
2441
|
+
const componentLabel = locator.reactComponentName ?? primaryFrame?.name ?? locator.tagName;
|
|
2442
|
+
let formattedSource;
|
|
2443
|
+
if (locator.isComponentPrimitive && locator.definitionSource?.file) {
|
|
2444
|
+
formattedSource = formatSourceLocation(
|
|
2445
|
+
locator.definitionSource.file,
|
|
2446
|
+
locator.definitionSource.line,
|
|
2447
|
+
locator.definitionSource.column
|
|
2448
|
+
);
|
|
2449
|
+
} else {
|
|
2450
|
+
formattedSource = locator.domSource?.file ? formatSourceLocation(locator.domSource.file, locator.domSource.line, locator.domSource.column) : primaryFrame?.file ? formatSourceLocation(primaryFrame.file, primaryFrame.line, primaryFrame.column) : null;
|
|
2451
|
+
}
|
|
2452
|
+
const formattedCallSite = locator.callSiteSource?.file ? formatSourceLocation(locator.callSiteSource.file, locator.callSiteSource.line, locator.callSiteSource.column) : null;
|
|
2453
|
+
return { componentLabel, formattedSource, formattedCallSite };
|
|
2454
|
+
}
|
|
2455
|
+
function formatComponentTree(reactStack) {
|
|
2456
|
+
const names = reactStack.map((f) => f.name).filter(Boolean);
|
|
2457
|
+
if (names.length === 0) return null;
|
|
2458
|
+
if (names.length === 1) return names[0];
|
|
2459
|
+
const [component, ...ancestors] = names;
|
|
2460
|
+
return `${component} (in ${ancestors.join(" > ")})`;
|
|
2181
2461
|
}
|
|
2182
2462
|
function buildLocatorContextLines(locator, options) {
|
|
2183
2463
|
const lines = [];
|
|
2184
|
-
const { componentLabel, formattedSource } = getLocatorHeader(locator);
|
|
2464
|
+
const { componentLabel, formattedSource, formattedCallSite } = getLocatorHeader(locator);
|
|
2185
2465
|
const target = (locator.targetHtml || locator.domContextHtml || "").trim();
|
|
2186
2466
|
const context = locator.domContextHtml?.trim() || "";
|
|
2187
|
-
const
|
|
2467
|
+
const path = locator.domSelector?.trim();
|
|
2188
2468
|
const text = locator.textPreview?.trim();
|
|
2189
2469
|
lines.push(`@<${componentLabel}>`);
|
|
2190
2470
|
lines.push("");
|
|
2471
|
+
const tree = formatComponentTree(locator.reactStack);
|
|
2472
|
+
if (tree) {
|
|
2473
|
+
lines.push(`react: ${tree}`);
|
|
2474
|
+
}
|
|
2475
|
+
if (locator.authoredProps && Object.keys(locator.authoredProps).length > 0) {
|
|
2476
|
+
lines.push(`props: ${JSON.stringify(locator.authoredProps)}`);
|
|
2477
|
+
}
|
|
2478
|
+
if (locator.isComponentPrimitive != null) {
|
|
2479
|
+
lines.push(`type: ${locator.isComponentPrimitive ? "component" : "instance"}`);
|
|
2480
|
+
}
|
|
2481
|
+
lines.push(`source: ${formattedSource ?? "(file not available)"}`);
|
|
2482
|
+
if (formattedCallSite && formattedCallSite !== formattedSource) {
|
|
2483
|
+
lines.push(`call-site: ${formattedCallSite}`);
|
|
2484
|
+
}
|
|
2485
|
+
if (locator.subElementSources && Object.keys(locator.subElementSources).length > 0) {
|
|
2486
|
+
lines.push("source-map:");
|
|
2487
|
+
for (const [label, source] of Object.entries(locator.subElementSources)) {
|
|
2488
|
+
lines.push(` - ${label}: ${formatSourceLocation(source.file, source.line, source.column)}`);
|
|
2489
|
+
}
|
|
2490
|
+
}
|
|
2491
|
+
if (path) {
|
|
2492
|
+
lines.push(`path: ${path}`);
|
|
2493
|
+
}
|
|
2191
2494
|
if (target) {
|
|
2495
|
+
lines.push("");
|
|
2192
2496
|
lines.push("target:");
|
|
2193
2497
|
lines.push(target);
|
|
2194
2498
|
}
|
|
2195
2499
|
if (!options?.skipContext && context && context !== target) {
|
|
2500
|
+
lines.push("");
|
|
2196
2501
|
lines.push("context:");
|
|
2197
2502
|
lines.push(context);
|
|
2198
2503
|
}
|
|
2199
|
-
lines.push(`in ${formattedSource ?? "(file not available)"}`);
|
|
2200
|
-
if (selector) {
|
|
2201
|
-
lines.push(`selector: ${selector}`);
|
|
2202
|
-
}
|
|
2203
2504
|
if (text) {
|
|
2204
2505
|
lines.push(`text: ${text}`);
|
|
2205
2506
|
}
|
|
@@ -3944,6 +4245,8 @@ function useSessionManager({
|
|
|
3944
4245
|
const originalStyles = options?.originalStyles ?? existingEdit?.originalStyles ?? getOriginalInlineStyles(nextSingleElement);
|
|
3945
4246
|
const pendingStyles = options?.pendingStyles ?? existingEdit?.pendingStyles ?? {};
|
|
3946
4247
|
const elementInfo = getElementInfo(nextSingleElement);
|
|
4248
|
+
const { frames, nearestComponentFiber, elementSourceFile } = getReactComponentInfo(nextSingleElement);
|
|
4249
|
+
const isPrimitive = classifyComponentFiber(nearestComponentFiber, frames, elementSourceFile).isComponentPrimitive;
|
|
3947
4250
|
setState((prev) => ({
|
|
3948
4251
|
comments: prev.activeCommentId ? prev.comments.filter((comment) => {
|
|
3949
4252
|
if (comment.id !== prev.activeCommentId) return true;
|
|
@@ -3962,6 +4265,7 @@ function useSessionManager({
|
|
|
3962
4265
|
computedColor: computed.color,
|
|
3963
4266
|
computedBoxShadow: computed.boxShadow,
|
|
3964
4267
|
computedTypography: computed.typography,
|
|
4268
|
+
isComponentPrimitive: isPrimitive,
|
|
3965
4269
|
originalStyles,
|
|
3966
4270
|
pendingStyles,
|
|
3967
4271
|
editModeActive: prev.editModeActive,
|
|
@@ -3992,6 +4296,7 @@ function useSessionManager({
|
|
|
3992
4296
|
computedColor: null,
|
|
3993
4297
|
computedBoxShadow: null,
|
|
3994
4298
|
computedTypography: null,
|
|
4299
|
+
isComponentPrimitive: false,
|
|
3995
4300
|
originalStyles: {},
|
|
3996
4301
|
pendingStyles: {},
|
|
3997
4302
|
activeCommentId: null,
|
|
@@ -4532,6 +4837,7 @@ function useSessionManager({
|
|
|
4532
4837
|
computedColor: computed.color,
|
|
4533
4838
|
computedBoxShadow: computed.boxShadow,
|
|
4534
4839
|
computedTypography: computed.typography,
|
|
4840
|
+
isComponentPrimitive: prev.isComponentPrimitive,
|
|
4535
4841
|
originalStyles: styleState.originalStyles,
|
|
4536
4842
|
pendingStyles: styleState.pendingStyles,
|
|
4537
4843
|
editModeActive: prev.editModeActive,
|
|
@@ -5316,6 +5622,8 @@ function withInstruction(profile, markdown) {
|
|
|
5316
5622
|
${markdown}` : markdown;
|
|
5317
5623
|
}
|
|
5318
5624
|
function buildLocatorPayload(locator) {
|
|
5625
|
+
const { componentLabel, formattedSource, formattedCallSite } = getLocatorHeader(locator);
|
|
5626
|
+
const reactTree = formatComponentTree(locator.reactStack);
|
|
5319
5627
|
return {
|
|
5320
5628
|
element: {
|
|
5321
5629
|
tagName: locator.tagName,
|
|
@@ -5323,10 +5631,22 @@ function buildLocatorPayload(locator) {
|
|
|
5323
5631
|
classList: locator.classList,
|
|
5324
5632
|
domSelector: locator.domSelector,
|
|
5325
5633
|
targetHtml: locator.targetHtml,
|
|
5634
|
+
contextHtml: locator.domContextHtml || null,
|
|
5326
5635
|
textPreview: locator.textPreview
|
|
5327
5636
|
},
|
|
5328
|
-
|
|
5329
|
-
|
|
5637
|
+
componentLabel,
|
|
5638
|
+
reactTree,
|
|
5639
|
+
reactStack: locator.reactStack,
|
|
5640
|
+
reactComponentName: locator.reactComponentName ?? null,
|
|
5641
|
+
authoredProps: locator.authoredProps ?? null,
|
|
5642
|
+
type: locator.isComponentPrimitive != null ? locator.isComponentPrimitive ? "component" : "instance" : null,
|
|
5643
|
+
isComponentPrimitive: locator.isComponentPrimitive ?? false,
|
|
5644
|
+
source: formattedSource,
|
|
5645
|
+
callSite: formattedCallSite,
|
|
5646
|
+
rawSource: locator.domSource || null,
|
|
5647
|
+
callSiteSource: locator.callSiteSource ?? null,
|
|
5648
|
+
definitionSource: locator.definitionSource ?? null,
|
|
5649
|
+
subElementSources: locator.subElementSources ?? null
|
|
5330
5650
|
};
|
|
5331
5651
|
}
|
|
5332
5652
|
function useAgentComms({ stateRef, sessionEditsRef, getSessionItems, saveCurrentToSession, removeSessionEdit, deleteComment }) {
|
|
@@ -6302,6 +6622,7 @@ function DirectEditProvider({ children }) {
|
|
|
6302
6622
|
computedColor: null,
|
|
6303
6623
|
computedBoxShadow: null,
|
|
6304
6624
|
computedTypography: null,
|
|
6625
|
+
isComponentPrimitive: false,
|
|
6305
6626
|
originalStyles: {},
|
|
6306
6627
|
pendingStyles: {},
|
|
6307
6628
|
editModeActive: false,
|
|
@@ -8594,6 +8915,7 @@ function useSelectionResize({
|
|
|
8594
8915
|
import { Fragment as Fragment2, jsx as jsx9, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
8595
8916
|
var BLUE3 = "#0D99FF";
|
|
8596
8917
|
var MAGENTA = "#E11BB6";
|
|
8918
|
+
var COMPONENT_PURPLE = "#8B5CF6";
|
|
8597
8919
|
var DRAG_THRESHOLD = 4;
|
|
8598
8920
|
var DBLCLICK_DELAY = 300;
|
|
8599
8921
|
var HANDLE_SIZE = 12;
|
|
@@ -8637,9 +8959,11 @@ function SelectionOverlay({
|
|
|
8637
8959
|
onHoverElement,
|
|
8638
8960
|
onClickThrough,
|
|
8639
8961
|
onSelectPageFrame,
|
|
8962
|
+
isComponentPrimitive = false,
|
|
8640
8963
|
enableResizeHandles = false,
|
|
8641
8964
|
onResizeSizingChange
|
|
8642
8965
|
}) {
|
|
8966
|
+
const selectionColor = isComponentPrimitive ? COMPONENT_PURPLE : BLUE3;
|
|
8643
8967
|
const rectElement = isDragging && draggedElement ? draggedElement : selectedElement;
|
|
8644
8968
|
const [rect, setRect] = React19.useState(() => rectElement.getBoundingClientRect());
|
|
8645
8969
|
const [pageFrameRect, setPageFrameRect] = React19.useState(() => pageFrameElement ? pageFrameElement.getBoundingClientRect() : null);
|
|
@@ -8967,7 +9291,7 @@ function SelectionOverlay({
|
|
|
8967
9291
|
zIndex: 99997,
|
|
8968
9292
|
background: "transparent",
|
|
8969
9293
|
border: "none",
|
|
8970
|
-
color:
|
|
9294
|
+
color: selectionColor,
|
|
8971
9295
|
fontSize: `${pageLabelFontSize}px`,
|
|
8972
9296
|
lineHeight: `${pageLabelLineHeight}px`,
|
|
8973
9297
|
padding: 0,
|
|
@@ -8995,7 +9319,7 @@ function SelectionOverlay({
|
|
|
8995
9319
|
height: rect.height,
|
|
8996
9320
|
pointerEvents: "none",
|
|
8997
9321
|
zIndex: 99996,
|
|
8998
|
-
border: `1px solid ${
|
|
9322
|
+
border: `1px solid ${selectionColor}`,
|
|
8999
9323
|
borderRadius: "0px",
|
|
9000
9324
|
boxSizing: "border-box"
|
|
9001
9325
|
}
|
|
@@ -9012,18 +9336,28 @@ function SelectionOverlay({
|
|
|
9012
9336
|
transform: "translateX(-50%)",
|
|
9013
9337
|
pointerEvents: "none",
|
|
9014
9338
|
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"
|
|
9339
|
+
display: "flex",
|
|
9340
|
+
alignItems: "center",
|
|
9341
|
+
gap: "4px"
|
|
9025
9342
|
},
|
|
9026
|
-
children:
|
|
9343
|
+
children: /* @__PURE__ */ jsx9(
|
|
9344
|
+
"span",
|
|
9345
|
+
{
|
|
9346
|
+
style: {
|
|
9347
|
+
background: selectionColor,
|
|
9348
|
+
color: "white",
|
|
9349
|
+
fontSize: "11px",
|
|
9350
|
+
lineHeight: "20px",
|
|
9351
|
+
padding: "0 6px",
|
|
9352
|
+
borderRadius: "4px",
|
|
9353
|
+
whiteSpace: "nowrap",
|
|
9354
|
+
fontFamily: "system-ui, sans-serif",
|
|
9355
|
+
fontWeight: 500,
|
|
9356
|
+
letterSpacing: "-0.01em"
|
|
9357
|
+
},
|
|
9358
|
+
children: dimensionText
|
|
9359
|
+
}
|
|
9360
|
+
)
|
|
9027
9361
|
}
|
|
9028
9362
|
),
|
|
9029
9363
|
!isDragging && !isTextEditing && /* @__PURE__ */ jsxs5(
|
|
@@ -9079,7 +9413,7 @@ function SelectionOverlay({
|
|
|
9079
9413
|
position: "absolute",
|
|
9080
9414
|
width: RESIZE_CORNER_SIZE,
|
|
9081
9415
|
height: RESIZE_CORNER_SIZE,
|
|
9082
|
-
border: `1px solid ${
|
|
9416
|
+
border: `1px solid ${selectionColor}`,
|
|
9083
9417
|
background: "#fff",
|
|
9084
9418
|
borderRadius: 1,
|
|
9085
9419
|
boxSizing: "border-box",
|
|
@@ -12504,6 +12838,7 @@ function DirectEditPanelContent() {
|
|
|
12504
12838
|
computedColor,
|
|
12505
12839
|
computedBoxShadow,
|
|
12506
12840
|
computedTypography,
|
|
12841
|
+
isComponentPrimitive,
|
|
12507
12842
|
borderStyleControlPreference,
|
|
12508
12843
|
pendingStyles,
|
|
12509
12844
|
editModeActive,
|
|
@@ -12824,6 +13159,7 @@ function DirectEditPanelContent() {
|
|
|
12824
13159
|
selectElement(child);
|
|
12825
13160
|
}
|
|
12826
13161
|
},
|
|
13162
|
+
isComponentPrimitive,
|
|
12827
13163
|
enableResizeHandles: true,
|
|
12828
13164
|
onResizeSizingChange: updateSizingProperties
|
|
12829
13165
|
}
|