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