@yahoo/uds-create-config 3.2.0 → 3.3.0
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/configs/react-native-system.d.ts +2 -0
- package/dist/configs/react-native-system.js +2 -0
- package/dist/configs/system.d.ts +2 -0
- package/dist/configs/system.js +2 -0
- package/dist/entities/system/Component.js +34 -7
- package/dist/entities/system/File.d.ts +1 -0
- package/dist/entities/system/File.js +27 -2
- package/dist/entities/system/style-bag.js +24 -5
- package/dist/framework/Config.d.ts +1 -1
- package/dist/framework/Config.js +1 -1
- package/dist/framework/anatomy-check.d.ts +99 -0
- package/dist/framework/anatomy-check.js +337 -0
- package/dist/framework/class-names.js +6 -2
- package/dist/framework/defineEntity.d.ts +1 -0
- package/dist/framework/ref-integrity.js +17 -3
- package/dist/framework/registry.d.ts +1 -0
- package/dist/framework/render-spec.d.ts +12 -1
- package/dist/framework/render-spec.js +122 -28
- package/dist/framework/schema-version.d.ts +1 -1
- package/dist/framework/schema-version.js +5 -5
- package/dist/index.d.ts +4 -2
- package/dist/index.js +4 -2
- package/dist/migrations/2.0.0/v1-artifact.d.ts +1 -0
- package/dist/migrations/20260914181845_anatomy_harness.d.ts +23 -0
- package/dist/migrations/20260914181845_anatomy_harness.js +10 -0
- package/dist/renderer/assetEntries.js +2 -3
- package/dist/renderer/spec-content.js +1 -1
- package/dist/renderer/wrappers/inline-styles.js +21 -1
- package/dist/spec/index.d.ts +1 -1
- package/dist/spec/specToJsx.js +26 -2
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
//#region src/framework/anatomy-check.ts
|
|
2
|
+
/**
|
|
3
|
+
* The computed properties compared on aligned elements. Paint, box, type — what a designer would
|
|
4
|
+
* notice. `width`/`height`/`line-height` compare with a pixel tolerance; everything else exactly,
|
|
5
|
+
* after {@link normalizeStyleValue}.
|
|
6
|
+
*/
|
|
7
|
+
const STYLE_PROPERTIES = [
|
|
8
|
+
"display",
|
|
9
|
+
"background-color",
|
|
10
|
+
"color",
|
|
11
|
+
"opacity",
|
|
12
|
+
"border-top-width",
|
|
13
|
+
"border-top-style",
|
|
14
|
+
"border-top-color",
|
|
15
|
+
"border-top-left-radius",
|
|
16
|
+
"padding-top",
|
|
17
|
+
"padding-right",
|
|
18
|
+
"padding-bottom",
|
|
19
|
+
"padding-left",
|
|
20
|
+
"font-size",
|
|
21
|
+
"font-weight",
|
|
22
|
+
"line-height",
|
|
23
|
+
"width",
|
|
24
|
+
"height"
|
|
25
|
+
];
|
|
26
|
+
/** Pixel slack for the size comparisons — sub-pixel layout and font rounding. */
|
|
27
|
+
const SIZE_TOLERANCE_PX = 1.5;
|
|
28
|
+
/** The alignment key: a layer is `Component/layer`; anything else is its tag. */
|
|
29
|
+
function renderedSignatureOf(tag, component, layer) {
|
|
30
|
+
return component !== void 0 && layer !== void 0 ? `${component}/${layer}` : `<${tag}>`;
|
|
31
|
+
}
|
|
32
|
+
const VOID_TAGS = new Set([
|
|
33
|
+
"area",
|
|
34
|
+
"base",
|
|
35
|
+
"br",
|
|
36
|
+
"col",
|
|
37
|
+
"embed",
|
|
38
|
+
"hr",
|
|
39
|
+
"img",
|
|
40
|
+
"input",
|
|
41
|
+
"link",
|
|
42
|
+
"meta",
|
|
43
|
+
"param",
|
|
44
|
+
"source",
|
|
45
|
+
"track",
|
|
46
|
+
"wbr"
|
|
47
|
+
]);
|
|
48
|
+
const ENTITIES = {
|
|
49
|
+
amp: "&",
|
|
50
|
+
lt: "<",
|
|
51
|
+
gt: ">",
|
|
52
|
+
quot: "\"",
|
|
53
|
+
apos: "'",
|
|
54
|
+
nbsp: "\xA0"
|
|
55
|
+
};
|
|
56
|
+
function decodeEntities(text) {
|
|
57
|
+
return text.replace(/&(#x[0-9a-f]+|#\d+|[a-z]+);/gi, (whole, body) => {
|
|
58
|
+
if (body[0] === "#") {
|
|
59
|
+
const code = body[1]?.toLowerCase() === "x" ? Number.parseInt(body.slice(2), 16) : Number.parseInt(body.slice(1), 10);
|
|
60
|
+
return Number.isFinite(code) ? String.fromCodePoint(code) : whole;
|
|
61
|
+
}
|
|
62
|
+
return ENTITIES[body.toLowerCase()] ?? whole;
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
const ATTRIBUTE = /([^\s"'<>/=]+)(?:\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s"'=<>`]+)))?/g;
|
|
66
|
+
/**
|
|
67
|
+
* Parse the markup `react-dom/server` writes. Not a general HTML parser: React's output is regular
|
|
68
|
+
* (quoted attributes, void elements self-closed or bare, `<!-- -->` text separators, entities), and
|
|
69
|
+
* that regularity is what this reads. A `<script>`/`<style>` body is skipped.
|
|
70
|
+
*/
|
|
71
|
+
function parseHtml(html) {
|
|
72
|
+
const root = {
|
|
73
|
+
tag: "#root",
|
|
74
|
+
attributes: {},
|
|
75
|
+
children: []
|
|
76
|
+
};
|
|
77
|
+
const stack = [root];
|
|
78
|
+
let i = 0;
|
|
79
|
+
while (i < html.length) {
|
|
80
|
+
const lt = html.indexOf("<", i);
|
|
81
|
+
if (lt < 0) {
|
|
82
|
+
pushText(stack, html.slice(i));
|
|
83
|
+
break;
|
|
84
|
+
}
|
|
85
|
+
if (lt > i) pushText(stack, html.slice(i, lt));
|
|
86
|
+
if (html.startsWith("<!--", lt)) {
|
|
87
|
+
const end = html.indexOf("-->", lt + 4);
|
|
88
|
+
i = end < 0 ? html.length : end + 3;
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
if (html.startsWith("</", lt)) {
|
|
92
|
+
const end = html.indexOf(">", lt);
|
|
93
|
+
const name = html.slice(lt + 2, end < 0 ? html.length : end).trim().toLowerCase();
|
|
94
|
+
for (let depth = stack.length - 1; depth > 0; depth--) if (stack[depth]?.tag === name) {
|
|
95
|
+
stack.length = depth;
|
|
96
|
+
break;
|
|
97
|
+
}
|
|
98
|
+
i = end < 0 ? html.length : end + 1;
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
const end = tagEnd(html, lt);
|
|
102
|
+
const raw = html.slice(lt + 1, end);
|
|
103
|
+
const selfClosing = raw.endsWith("/");
|
|
104
|
+
const body = selfClosing ? raw.slice(0, -1) : raw;
|
|
105
|
+
const nameEnd = body.search(/[\s/]/);
|
|
106
|
+
const tag = (nameEnd < 0 ? body : body.slice(0, nameEnd)).toLowerCase();
|
|
107
|
+
const attributes = {};
|
|
108
|
+
const attrText = nameEnd < 0 ? "" : body.slice(nameEnd);
|
|
109
|
+
for (const match of attrText.matchAll(ATTRIBUTE)) {
|
|
110
|
+
const name = match[1];
|
|
111
|
+
if (!name) continue;
|
|
112
|
+
attributes[name.toLowerCase()] = decodeEntities(match[2] ?? match[3] ?? match[4] ?? "");
|
|
113
|
+
}
|
|
114
|
+
const element = {
|
|
115
|
+
tag,
|
|
116
|
+
attributes,
|
|
117
|
+
children: []
|
|
118
|
+
};
|
|
119
|
+
stack[stack.length - 1]?.children.push(element);
|
|
120
|
+
i = end + 1;
|
|
121
|
+
if (tag === "script" || tag === "style") {
|
|
122
|
+
const close = html.indexOf(`</${tag}`, i);
|
|
123
|
+
i = close < 0 ? html.length : html.indexOf(">", close) + 1;
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
if (!selfClosing && !VOID_TAGS.has(tag)) stack.push(element);
|
|
127
|
+
}
|
|
128
|
+
return root;
|
|
129
|
+
}
|
|
130
|
+
/** The index of the `>` that closes the tag opened at `start`, quote-aware. */
|
|
131
|
+
function tagEnd(html, start) {
|
|
132
|
+
let quote = null;
|
|
133
|
+
for (let i = start + 1; i < html.length; i++) {
|
|
134
|
+
const ch = html[i];
|
|
135
|
+
if (quote) {
|
|
136
|
+
if (ch === quote) quote = null;
|
|
137
|
+
} else if (ch === "\"" || ch === "'") quote = ch;
|
|
138
|
+
else if (ch === ">") return i;
|
|
139
|
+
}
|
|
140
|
+
return html.length;
|
|
141
|
+
}
|
|
142
|
+
function pushText(stack, text) {
|
|
143
|
+
if (!text) return;
|
|
144
|
+
stack[stack.length - 1]?.children.push({ text: decodeEntities(text) });
|
|
145
|
+
}
|
|
146
|
+
/** Inline `style="a:b;c:d"` as declarations, property names lower-cased. */
|
|
147
|
+
function inlineStyleOf(attribute) {
|
|
148
|
+
const out = {};
|
|
149
|
+
if (!attribute) return out;
|
|
150
|
+
for (const declaration of attribute.split(";")) {
|
|
151
|
+
const colon = declaration.indexOf(":");
|
|
152
|
+
if (colon < 0) continue;
|
|
153
|
+
const property = declaration.slice(0, colon).trim().toLowerCase();
|
|
154
|
+
const value = declaration.slice(colon + 1).trim();
|
|
155
|
+
if (property) out[property] = value;
|
|
156
|
+
}
|
|
157
|
+
return out;
|
|
158
|
+
}
|
|
159
|
+
function ownTextOf(element) {
|
|
160
|
+
let text = "";
|
|
161
|
+
for (const child of element.children) if ("text" in child) text += child.text;
|
|
162
|
+
return text.replace(/\s+/g, " ").trim();
|
|
163
|
+
}
|
|
164
|
+
function firstComponentRoot(node) {
|
|
165
|
+
for (const child of node.children) {
|
|
166
|
+
if ("text" in child) continue;
|
|
167
|
+
if (child.attributes["data-uds-component"] !== void 0) return child;
|
|
168
|
+
const nested = firstComponentRoot(child);
|
|
169
|
+
if (nested) return nested;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Every element under the component root of `html`, in document order, as {@link RenderedNode}s
|
|
174
|
+
* without computed style. The root is the first element carrying `data-uds-component`; hosts and
|
|
175
|
+
* shells above it are scaffolding. `data-anatomy-check-ignore` subtrees are skipped.
|
|
176
|
+
*/
|
|
177
|
+
function snapshotHtml(html) {
|
|
178
|
+
const root = firstComponentRoot(parseHtml(html));
|
|
179
|
+
if (!root) return [];
|
|
180
|
+
const out = [];
|
|
181
|
+
const visit = (element) => {
|
|
182
|
+
if (element.attributes["data-anatomy-check-ignore"] !== void 0) return;
|
|
183
|
+
const component = element.attributes["data-uds-component"];
|
|
184
|
+
const layer = element.attributes["data-uds-layer"];
|
|
185
|
+
out.push({
|
|
186
|
+
component,
|
|
187
|
+
layer,
|
|
188
|
+
tag: element.tag,
|
|
189
|
+
text: ownTextOf(element),
|
|
190
|
+
classes: (element.attributes.class ?? "").split(/\s+/).filter(Boolean).sort(),
|
|
191
|
+
style: inlineStyleOf(element.attributes.style),
|
|
192
|
+
inlineStyle: true,
|
|
193
|
+
signature: renderedSignatureOf(element.tag, component, layer)
|
|
194
|
+
});
|
|
195
|
+
for (const child of element.children) if (!("text" in child)) visit(child);
|
|
196
|
+
};
|
|
197
|
+
visit(root);
|
|
198
|
+
return out;
|
|
199
|
+
}
|
|
200
|
+
/** Longest common subsequence over signatures — the pairs of indices that align. */
|
|
201
|
+
function align(a, b) {
|
|
202
|
+
const table = Array.from({ length: a.length + 1 }, () => new Array(b.length + 1).fill(0));
|
|
203
|
+
for (let i = a.length - 1; i >= 0; i--) for (let j = b.length - 1; j >= 0; j--) {
|
|
204
|
+
const rowI = table[i];
|
|
205
|
+
const rowNext = table[i + 1];
|
|
206
|
+
rowI[j] = a[i]?.signature === b[j]?.signature ? (rowNext[j + 1] ?? 0) + 1 : Math.max(rowNext[j] ?? 0, rowI[j + 1] ?? 0);
|
|
207
|
+
}
|
|
208
|
+
const pairs = [];
|
|
209
|
+
let i = 0;
|
|
210
|
+
let j = 0;
|
|
211
|
+
while (i < a.length && j < b.length) {
|
|
212
|
+
const rowI = table[i];
|
|
213
|
+
const rowNext = table[i + 1];
|
|
214
|
+
if (a[i]?.signature === b[j]?.signature) {
|
|
215
|
+
pairs.push([i, j]);
|
|
216
|
+
i++;
|
|
217
|
+
j++;
|
|
218
|
+
} else if ((rowNext[j] ?? 0) >= (rowI[j + 1] ?? 0)) i++;
|
|
219
|
+
else j++;
|
|
220
|
+
}
|
|
221
|
+
return pairs;
|
|
222
|
+
}
|
|
223
|
+
/** `rgb(…)` spacing and a trailing `px` zero are the browser's spelling, not a difference. */
|
|
224
|
+
function normalizeStyleValue(value) {
|
|
225
|
+
return value.trim().replace(/\s+/g, " ").replace(/,\s*/g, ", ").replace(/^0(px|em|rem)$/, "0").replace(/\.0+(px|em|rem|%)$/, "$1");
|
|
226
|
+
}
|
|
227
|
+
function pxOf(value) {
|
|
228
|
+
const match = /^(-?\d*\.?\d+)px$/.exec(value.trim());
|
|
229
|
+
return match ? Number(match[1]) : void 0;
|
|
230
|
+
}
|
|
231
|
+
function stylesDiffer(property, a, b) {
|
|
232
|
+
const na = normalizeStyleValue(a);
|
|
233
|
+
const nb = normalizeStyleValue(b);
|
|
234
|
+
if (na === nb) return false;
|
|
235
|
+
if (property === "width" || property === "height" || property === "line-height") {
|
|
236
|
+
const pa = pxOf(na);
|
|
237
|
+
const pb = pxOf(nb);
|
|
238
|
+
if (pa !== void 0 && pb !== void 0) return Math.abs(pa - pb) > SIZE_TOLERANCE_PX;
|
|
239
|
+
}
|
|
240
|
+
return true;
|
|
241
|
+
}
|
|
242
|
+
function ordinals(nodes) {
|
|
243
|
+
const seen = /* @__PURE__ */ new Map();
|
|
244
|
+
return nodes.map((node) => {
|
|
245
|
+
const n = seen.get(node.signature) ?? 0;
|
|
246
|
+
seen.set(node.signature, n + 1);
|
|
247
|
+
return n;
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
function nodeLabel(node, ordinal) {
|
|
251
|
+
return ordinal > 0 ? `${node.signature}#${ordinal + 1}` : node.signature;
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Compare the anatomy's rendering with the module's.
|
|
255
|
+
*
|
|
256
|
+
* Elements align by signature in document order; what the module renders and the anatomy does not
|
|
257
|
+
* is `missing`, the reverse is `extra`. Aligned elements then compare own text, computed style (when
|
|
258
|
+
* both sides carry it) and class set.
|
|
259
|
+
*/
|
|
260
|
+
function diffRendered(anatomy, instance, options = {}) {
|
|
261
|
+
const issues = [];
|
|
262
|
+
const pairs = align(anatomy, instance);
|
|
263
|
+
const matchedA = new Set(pairs.map(([i]) => i));
|
|
264
|
+
const matchedB = new Set(pairs.map(([, j]) => j));
|
|
265
|
+
const ordA = ordinals(anatomy);
|
|
266
|
+
const ordB = ordinals(instance);
|
|
267
|
+
anatomy.forEach((node, i) => {
|
|
268
|
+
if (!matchedA.has(i)) issues.push({
|
|
269
|
+
kind: "extra",
|
|
270
|
+
node: nodeLabel(node, ordA[i] ?? 0),
|
|
271
|
+
anatomy: node.text || void 0
|
|
272
|
+
});
|
|
273
|
+
});
|
|
274
|
+
instance.forEach((node, j) => {
|
|
275
|
+
if (!matchedB.has(j)) issues.push({
|
|
276
|
+
kind: "missing",
|
|
277
|
+
node: nodeLabel(node, ordB[j] ?? 0),
|
|
278
|
+
instance: node.text || void 0
|
|
279
|
+
});
|
|
280
|
+
});
|
|
281
|
+
for (const [i, j] of pairs) {
|
|
282
|
+
const a = anatomy[i];
|
|
283
|
+
const b = instance[j];
|
|
284
|
+
const label = nodeLabel(b, ordB[j] ?? 0);
|
|
285
|
+
if (a.tag !== b.tag) issues.push({
|
|
286
|
+
kind: "tag",
|
|
287
|
+
node: label,
|
|
288
|
+
anatomy: a.tag,
|
|
289
|
+
instance: b.tag
|
|
290
|
+
});
|
|
291
|
+
if (a.text !== b.text) issues.push({
|
|
292
|
+
kind: "text",
|
|
293
|
+
node: label,
|
|
294
|
+
anatomy: a.text,
|
|
295
|
+
instance: b.text
|
|
296
|
+
});
|
|
297
|
+
const inline = a.inlineStyle === true && b.inlineStyle === true;
|
|
298
|
+
const properties = inline ? [...new Set([...Object.keys(a.style), ...Object.keys(b.style)])].sort() : STYLE_PROPERTIES;
|
|
299
|
+
for (const property of properties) {
|
|
300
|
+
const va = a.style[property];
|
|
301
|
+
const vb = b.style[property];
|
|
302
|
+
if (!inline && (va === void 0 || vb === void 0)) continue;
|
|
303
|
+
if (va === vb) continue;
|
|
304
|
+
if (va !== void 0 && vb !== void 0 && !stylesDiffer(property, va, vb)) continue;
|
|
305
|
+
issues.push({
|
|
306
|
+
kind: "style",
|
|
307
|
+
node: label,
|
|
308
|
+
property,
|
|
309
|
+
anatomy: va === void 0 ? void 0 : normalizeStyleValue(va),
|
|
310
|
+
instance: vb === void 0 ? void 0 : normalizeStyleValue(vb)
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
const onlyA = a.classes.filter((c) => !b.classes.includes(c));
|
|
314
|
+
const onlyB = b.classes.filter((c) => !a.classes.includes(c));
|
|
315
|
+
if (onlyA.length || onlyB.length) issues.push({
|
|
316
|
+
kind: "classes",
|
|
317
|
+
node: label,
|
|
318
|
+
anatomy: onlyA.join(" ") || void 0,
|
|
319
|
+
instance: onlyB.join(" ") || void 0
|
|
320
|
+
});
|
|
321
|
+
}
|
|
322
|
+
const fails = (issue) => issue.kind !== "classes" || options.classesFail === true;
|
|
323
|
+
return {
|
|
324
|
+
ok: !issues.some(fails),
|
|
325
|
+
issues,
|
|
326
|
+
counts: {
|
|
327
|
+
anatomy: anatomy.length,
|
|
328
|
+
instance: instance.length
|
|
329
|
+
}
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
/** The allowlist spelling of an issue: kind, node, and the property for a style difference. */
|
|
333
|
+
function anatomyIssueKey(issue) {
|
|
334
|
+
return issue.property ? `${issue.kind} ${issue.node} ${issue.property}` : `${issue.kind} ${issue.node}`;
|
|
335
|
+
}
|
|
336
|
+
//#endregion
|
|
337
|
+
export { SIZE_TOLERANCE_PX, STYLE_PROPERTIES, anatomyIssueKey, diffRendered, normalizeStyleValue, renderedSignatureOf, snapshotHtml };
|
|
@@ -372,8 +372,12 @@ function layerCompositeProps(config, path, state = {}) {
|
|
|
372
372
|
if (!isRef(element)) continue;
|
|
373
373
|
const declared = resolveComponentProps(config, pathOf(element.__ref));
|
|
374
374
|
for (const [prop, value] of Object.entries(bag ?? {})) {
|
|
375
|
-
const
|
|
376
|
-
if (!
|
|
375
|
+
const decl = declared[prop];
|
|
376
|
+
if (!decl) continue;
|
|
377
|
+
const bound = decl.value;
|
|
378
|
+
const composite = isRef(bound) && kindOf(bound.__ref) === "composite";
|
|
379
|
+
const own = decl.type === "variant" || decl.type === "string" || decl.type === "number" || decl.type === "boolean";
|
|
380
|
+
if (!composite && !own) continue;
|
|
377
381
|
out[layer] ??= {};
|
|
378
382
|
out[layer][prop] = authoredValue(config, prop, value);
|
|
379
383
|
}
|
|
@@ -299,6 +299,7 @@ declare function defineEntity<F extends FieldsSchema, G extends FieldsSchema = z
|
|
|
299
299
|
* find every one of them without knowing the kind. */
|
|
300
300
|
styleBags?: (data: unknown) => {
|
|
301
301
|
bag: Record<string, unknown>;
|
|
302
|
+
element?: unknown;
|
|
302
303
|
}[];
|
|
303
304
|
rewriteName?: (data: unknown, from: string, to: string) => unknown;
|
|
304
305
|
}): EntityClass<F, G, K, S, C, Single>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { collectRefs, kindOf, memberOf, pathOf, sourceOf } from "./utils/refs.js";
|
|
1
|
+
import { collectRefs, isRef, kindOf, memberOf, pathOf, sourceOf } from "./utils/refs.js";
|
|
2
2
|
import { cssValueIssue } from "../css/values.js";
|
|
3
3
|
import { stylePropEntries } from "./projections.js";
|
|
4
4
|
//#region src/framework/ref-integrity.ts
|
|
@@ -98,6 +98,20 @@ function danglingLocalRefs(config) {
|
|
|
98
98
|
*/
|
|
99
99
|
const NAME_SHAPED = /^[a-zA-Z][\w-]*$/;
|
|
100
100
|
/**
|
|
101
|
+
* The props of the component an anatomy node renders — through its layer when the element is one,
|
|
102
|
+
* through the fallback when a prop chooses it. `undefined` for an intrinsic tag or a package export.
|
|
103
|
+
*/
|
|
104
|
+
function renderedProps(config, element, layers) {
|
|
105
|
+
let target = element;
|
|
106
|
+
if (target && typeof target === "object" && !isRef(target) && "$state" in target) {
|
|
107
|
+
const bound = target;
|
|
108
|
+
target = bound.layer !== void 0 ? { __ref: `layer:${bound.layer}` } : bound.else;
|
|
109
|
+
}
|
|
110
|
+
if (isRef(target) && kindOf(target.__ref) === "layer") target = layers?.[pathOf(target.__ref)];
|
|
111
|
+
if (!isRef(target) || kindOf(target.__ref) !== "component") return void 0;
|
|
112
|
+
return (config.resolve("component", pathOf(target.__ref))?.toJSON())?.props;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
101
115
|
* Every bare leaf in a style bag that names nothing its property accepts.
|
|
102
116
|
*
|
|
103
117
|
* The companion to {@link danglingLocalRefs}, for the references that were never refs. A leaf that
|
|
@@ -143,8 +157,8 @@ function unknownStyleLeaves(config) {
|
|
|
143
157
|
if (!sites) continue;
|
|
144
158
|
for (const item of config.list(kind)) {
|
|
145
159
|
const body = item.toJSON();
|
|
146
|
-
for (const { bag } of sites(body)) {
|
|
147
|
-
const own = bag === body.defaultProps ? body.props : void 0;
|
|
160
|
+
for (const { bag, element } of sites(body)) {
|
|
161
|
+
const own = bag === body.defaultProps ? body.props : element !== void 0 ? renderedProps(config, element, body.layers) : void 0;
|
|
148
162
|
for (const [prop, value] of Object.entries(bag)) {
|
|
149
163
|
if (typeof value !== "string" || !NAME_SHAPED.test(value)) continue;
|
|
150
164
|
if (!config.resolve("style-property", prop)) continue;
|
|
@@ -27,6 +27,17 @@ interface ComponentSpecs {
|
|
|
27
27
|
readonly render?: RenderSpec;
|
|
28
28
|
readonly preview?: RenderSpec;
|
|
29
29
|
}
|
|
30
|
+
/**
|
|
31
|
+
* The registry key of an element rendered THROUGH a package factory — `motion.create(Box)`, spelled
|
|
32
|
+
* `package:motion/react#motion(component:Box)`.
|
|
33
|
+
*
|
|
34
|
+
* The render wrapped the layer, so the module paints motion's element and the anatomy has to say
|
|
35
|
+
* so, or a cell shows the layer without the transition, the hidden-when-empty collapse, the press
|
|
36
|
+
* scale. The registry emits one entry per pair the anatomies name (see codegen's registry emitter);
|
|
37
|
+
* this is the one spelling both sides use. Not a ref path — the parentheses keep it from parsing as
|
|
38
|
+
* one — since it names a derived thing, not an entity.
|
|
39
|
+
*/
|
|
40
|
+
declare function wrappedElementKey(wrapper: string, type: string): string;
|
|
30
41
|
/**
|
|
31
42
|
* The node a tree ENTERS at — the one nothing else claims as a child.
|
|
32
43
|
*
|
|
@@ -293,4 +304,4 @@ declare function expandSpec(config: Config, spec: RenderSpec, options?: ExpandOp
|
|
|
293
304
|
*/
|
|
294
305
|
declare function expandComponent(config: Config, path: string, props?: Record<string, unknown>, options?: ExpandOptions): ExpansionResult;
|
|
295
306
|
//#endregion
|
|
296
|
-
export { ComponentSpec, ComponentSpecs, ExpandOptions, ExpansionResult, RenderElement, RenderSpec, SlotTarget, VisibilityOperator, VisibilityTerm, boundElementType, componentSpec, deriveSpec, entryKeyOf, expandComponent, expandSpec, instanceSpec, previewSpec, resolveVisibility, slotTargetsOf, specWithResolvedVisibility, visibilityStateProps, visibilityTerms, withoutTruthyTerm };
|
|
307
|
+
export { ComponentSpec, ComponentSpecs, ExpandOptions, ExpansionResult, RenderElement, RenderSpec, SlotTarget, VisibilityOperator, VisibilityTerm, boundElementType, componentSpec, deriveSpec, entryKeyOf, expandComponent, expandSpec, instanceSpec, previewSpec, resolveVisibility, slotTargetsOf, specWithResolvedVisibility, visibilityStateProps, visibilityTerms, withoutTruthyTerm, wrappedElementKey };
|