@yahoo/uds-create-config 4.54.0 → 4.55.1
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/capture/class-grammar.js +2 -3
- package/dist/configs/platform.d.ts +8 -1
- package/dist/configs/react-native-system.d.ts +21 -9
- package/dist/configs/react-native-system.js +1 -1
- package/dist/configs/system.js +3 -1
- package/dist/css/value-type.js +24 -0
- package/dist/entities/documentation/Documentation.d.ts +1 -1
- package/dist/entities/native/NativeStyleProperty.d.ts +14 -9
- package/dist/entities/native/NativeStyleProperty.js +23 -2
- package/dist/entities/native/NativeToken.d.ts +10 -3
- package/dist/entities/native/NativeToken.js +39 -4
- package/dist/entities/system/Component.js +2 -1
- package/dist/entities/system/GlobalStyle.d.ts +2 -2
- package/dist/entities/system/GlobalStyle.js +2 -1
- package/dist/entities/system/Modifier.d.ts +3 -1
- package/dist/entities/system/Modifier.js +3 -1
- package/dist/entities/system/Settings.d.ts +9 -1
- package/dist/entities/system/Settings.js +6 -2
- package/dist/entities/system/StyleProperty.d.ts +39 -3
- package/dist/entities/system/StyleProperty.js +141 -18
- package/dist/entities/system/Token.d.ts +14 -1
- package/dist/entities/system/Token.js +21 -3
- package/dist/entities/system/calc.d.ts +28 -0
- package/dist/entities/system/calc.js +121 -0
- package/dist/entities/system/color.d.ts +29 -4
- package/dist/entities/system/color.js +61 -8
- package/dist/entities/system/component-module.js +15 -4
- package/dist/entities/system/composed-values.d.ts +3 -2
- package/dist/entities/system/composed-values.js +20 -1
- package/dist/entities/system/defineComponent.d.ts +3 -3
- package/dist/entities/system/link-plan.js +10 -1
- package/dist/entities/system/linked-token-values.d.ts +34 -0
- package/dist/entities/system/linked-token-values.js +135 -0
- package/dist/entities/system/shadow.d.ts +9 -7
- package/dist/entities/system/shadow.js +8 -7
- package/dist/entities/system/style-bag.d.ts +1 -1
- package/dist/entities/system/token-index.js +45 -2
- package/dist/entities/system/token-values.d.ts +3 -2
- package/dist/entities/system/token-values.js +9 -9
- package/dist/framework/Config.d.ts +14 -18
- package/dist/framework/Config.js +105 -55
- package/dist/framework/class-names.d.ts +47 -7
- package/dist/framework/class-names.js +115 -14
- package/dist/framework/defineEntity.d.ts +3 -1
- package/dist/framework/defineEntity.js +3 -1
- package/dist/framework/inline-sources.d.ts +3 -3
- package/dist/framework/inline-sources.js +1 -1
- package/dist/framework/projections.d.ts +84 -3
- package/dist/framework/projections.js +315 -20
- package/dist/framework/ref-graph.js +1 -1
- package/dist/framework/registry.d.ts +7 -0
- package/dist/framework/registry.js +2 -1
- package/dist/framework/schema-version.d.ts +1 -1
- package/dist/framework/schema-version.js +5 -5
- package/dist/framework/utils/group.d.ts +2 -1
- package/dist/framework/utils/refs.d.ts +19 -2
- package/dist/framework/utils/refs.js +100 -12
- package/dist/index.d.ts +12 -10
- package/dist/index.js +10 -8
- package/dist/migrations/20261001162046_oklch_and_emit_fields.d.ts +25 -0
- package/dist/migrations/20261001162046_oklch_and_emit_fields.js +10 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
|
@@ -53,8 +53,26 @@ declare function heldLinked({
|
|
|
53
53
|
* The group segment is kebab-cased and the leaf is not, which is not a stylistic choice: it's the
|
|
54
54
|
* shape the emitted stylesheet declares (`--{prefix}-{kebabCase(namespace)}-{safeTokenName(name)}`).
|
|
55
55
|
* Deriving it any other way produces a `var()` that resolves to nothing for any camelCase group.
|
|
56
|
+
*
|
|
57
|
+
* Under the config's own naming, a token's own `cssVariable` is its whole name (`--spacing`), or
|
|
58
|
+
* the exact name when it starts with `--` (`--mantine-color-primary`, whatever the prefix), and
|
|
59
|
+
* otherwise the nearest token group that declares a `cssPrefix` spells its part of the name:
|
|
60
|
+
* `fontSize/sm` under `fontSize: { cssPrefix: 'text' }` is `--text-sm`, and an empty `cssPrefix`
|
|
61
|
+
* drops the group's segment. An empty config prefix drops its own.
|
|
56
62
|
*/
|
|
57
63
|
declare function cssVar(config: Config, _kind: string, path: string, varPrefix?: VarNaming): string;
|
|
64
|
+
/**
|
|
65
|
+
* Whether a token is declared as a custom property: its own `cssVariable`, else the nearest group's
|
|
66
|
+
* `cssVariables`, else yes. One that isn't is written into each value that uses it, as Tailwind's
|
|
67
|
+
* `@theme inline` does.
|
|
68
|
+
*/
|
|
69
|
+
declare function declaresCssVariable(config: Config, path: string): boolean;
|
|
70
|
+
/**
|
|
71
|
+
* How CSS reaches a token: `var(--…)` when it declares a variable, else its value written in place,
|
|
72
|
+
* as the stylesheet writes it. For anything that paints a token outside a style prop, a swatch, an
|
|
73
|
+
* effect colour, a background.
|
|
74
|
+
*/
|
|
75
|
+
declare function tokenReference(config: Config, path: string): string;
|
|
58
76
|
/** `var(--…)` — the CSS reference to {@link cssVar}. */
|
|
59
77
|
declare function cssVarRef(config: Config, kind: string, path: string, varPrefix?: VarNaming): string;
|
|
60
78
|
/** The utility/class name for an entity — `<prefix>-<path-dashed>`. A class is one identifier, so
|
|
@@ -238,6 +256,13 @@ declare function resolveFieldValue(config: Config, kind: string, path: string, f
|
|
|
238
256
|
/** A token's value with alias refs chased to the base literal — {@link resolveFieldValue} for the one
|
|
239
257
|
* field every token consumer asks about, narrowed to the scalar a display or a stylesheet can use. */
|
|
240
258
|
declare function resolveTokenValue(config: Config, path: string, seen?: Set<string>): string | number | undefined;
|
|
259
|
+
/**
|
|
260
|
+
* A stored value as the literal it comes to: a string or a number as itself, an OKLCH colour as its
|
|
261
|
+
* CSS, arithmetic evaluated over its operands' literals (`multiply(Token.ref('spacing'), 4)` with
|
|
262
|
+
* `spacing` at `0.25rem` is `1rem`), and a token ref as that token's literal. `undefined` for a value
|
|
263
|
+
* that is no single literal (a shadow, a gradient) or a ref that resolves to nothing.
|
|
264
|
+
*/
|
|
265
|
+
declare function literalValueOf(config: Config, value: unknown): string | number | undefined;
|
|
241
266
|
/**
|
|
242
267
|
* The literal a token resolves to under an override condition: its own override there when it holds
|
|
243
268
|
* one, else its base value, with a ref along the way chased under the same condition. That is how the
|
|
@@ -245,6 +270,20 @@ declare function resolveTokenValue(config: Config, path: string, seen?: Set<stri
|
|
|
245
270
|
* for a dark cell paints what dark will show. `null` is the base, the same as {@link resolveTokenValue}.
|
|
246
271
|
*/
|
|
247
272
|
declare function resolveTokenValueUnder(config: Config, path: string, condition: string | null, seen?: Set<string>): string | number | undefined;
|
|
273
|
+
/**
|
|
274
|
+
* A string's interpolated refs written as their tokens: `blur({token:blur/sm})` is
|
|
275
|
+
* `blur(var(--blur-sm))`. A ref opening a `var(` is the variable's name, so a fallback can follow it:
|
|
276
|
+
* `var({token:tw/leading}, 1.5)` is `var(--tw-leading, 1.5)`.
|
|
277
|
+
*/
|
|
278
|
+
declare function renderInterpolated({
|
|
279
|
+
config,
|
|
280
|
+
text,
|
|
281
|
+
varPrefix
|
|
282
|
+
}: {
|
|
283
|
+
readonly config: Config;
|
|
284
|
+
readonly text: string;
|
|
285
|
+
readonly varPrefix?: VarNaming;
|
|
286
|
+
}): string;
|
|
248
287
|
/** A style-bag value → its CSS string: a token ref (or a bare token path) becomes a
|
|
249
288
|
* `var(--…)` reference (so mode/theme overrides still flow), anything else is the literal.
|
|
250
289
|
*
|
|
@@ -254,7 +293,9 @@ declare function resolveTokenValueUnder(config: Config, path: string, condition:
|
|
|
254
293
|
* ordinary call — it is `config`'s own prefix. */
|
|
255
294
|
declare function renderStyleValue(config: Config, value: unknown, varPrefix?: VarNaming): string;
|
|
256
295
|
/**
|
|
257
|
-
* The value a negating prop paints
|
|
296
|
+
* The value a negating prop paints: a length or a percentage with a minus sign (`-1px`, `-100%`, and
|
|
297
|
+
* a zero as it is), a scale step's multiplier negated (`calc(var(--spacing) * -4)`), and anything
|
|
298
|
+
* else, a `var()` included, as `calc(<value> * -1)` — the spellings Tailwind writes.
|
|
258
299
|
*
|
|
259
300
|
* `calc` rather than a computed literal because the value is usually a `var(--…)`: the token it names
|
|
260
301
|
* has to stay a reference, so a mode override or a theme swap still reaches it. It's applied at the
|
|
@@ -371,10 +412,50 @@ declare function routedBag({
|
|
|
371
412
|
readonly through?: readonly (string | undefined)[];
|
|
372
413
|
readonly bag: Record<string, unknown>;
|
|
373
414
|
}): Record<string, unknown>;
|
|
415
|
+
/** A declaration's key as CSS: a property as itself, a token's key `{token:tw/blur}` as the variable
|
|
416
|
+
* the token declares. */
|
|
417
|
+
declare function declarationKeyName({
|
|
418
|
+
config,
|
|
419
|
+
key,
|
|
420
|
+
namespace
|
|
421
|
+
}: {
|
|
422
|
+
readonly config: Config;
|
|
423
|
+
readonly key: string;
|
|
424
|
+
readonly namespace?: VarNaming;
|
|
425
|
+
}): string;
|
|
426
|
+
/**
|
|
427
|
+
* One block of a bag's declarations: those on the element itself, or those a prop writes under its
|
|
428
|
+
* `selector` (`&` standing for the element) or a value writes under an at-rule.
|
|
429
|
+
*/
|
|
430
|
+
interface StyleDeclarationGroup {
|
|
431
|
+
/** The prop's `selector`, with `&` for the element. Absent for the element's own declarations. */
|
|
432
|
+
readonly selector?: string;
|
|
433
|
+
/** The at-rule prelude the block sits in (`@media (width >= 40rem)`). */
|
|
434
|
+
readonly atRule?: string;
|
|
435
|
+
readonly declarations: Record<string, string>;
|
|
436
|
+
}
|
|
437
|
+
/**
|
|
438
|
+
* The declarations a bag sets on the element itself. Declarations a prop scopes to a `selector` or a
|
|
439
|
+
* value scopes to an at-rule are not the element's, so they are left out; a stylesheet reads them
|
|
440
|
+
* from {@link styleDeclarationGroups}.
|
|
441
|
+
*/
|
|
374
442
|
declare function styleDeclarations({
|
|
375
443
|
config,
|
|
376
444
|
bag,
|
|
377
445
|
namespace
|
|
446
|
+
}: {
|
|
447
|
+
readonly config: Config;
|
|
448
|
+
readonly bag: Record<string, unknown>; /** See {@link styleDeclarationGroups}. */
|
|
449
|
+
readonly namespace?: VarNaming;
|
|
450
|
+
}): Record<string, string>;
|
|
451
|
+
/**
|
|
452
|
+
* A bag's declarations in the blocks they apply in: the element's own first, then each `selector`
|
|
453
|
+
* and at-rule block in the order the bag first reaches it. A block that sets nothing is left out.
|
|
454
|
+
*/
|
|
455
|
+
declare function styleDeclarationGroups({
|
|
456
|
+
config,
|
|
457
|
+
bag,
|
|
458
|
+
namespace
|
|
378
459
|
}: {
|
|
379
460
|
readonly config: Config;
|
|
380
461
|
readonly bag: Record<string, unknown>;
|
|
@@ -387,7 +468,7 @@ declare function styleDeclarations({
|
|
|
387
468
|
* nothing on the page declares, which computes to the inherited value and paints silently wrong.
|
|
388
469
|
*/
|
|
389
470
|
readonly namespace?: VarNaming;
|
|
390
|
-
}):
|
|
471
|
+
}): StyleDeclarationGroup[];
|
|
391
472
|
/**
|
|
392
473
|
* An opacity value as a `color-mix()` share.
|
|
393
474
|
*
|
|
@@ -631,4 +712,4 @@ declare function propValueFromAxis(config: Config, path: string, prop: string, v
|
|
|
631
712
|
/** The `value` a string, number or boolean prop declares as its default, per prop. */
|
|
632
713
|
declare function declaredPropDefaults(props: Record<string, unknown> | undefined): Record<string, unknown>;
|
|
633
714
|
//#endregion
|
|
634
|
-
export { IconTool, IndexedPreviewCondition, PreviewMatrix, PropDeclaration, StylePropEntry, StylePropertyItem, VarNaming, authoredBag, authoredValue, className, cssPropValue, cssVar, cssVarRef, declaredPropDefaults, declaredPropRouting, glyphComponentOf, glyphLibrariesOf, glyphPropsOf, heldLinked, holdingPreviewConditions, iconToolAxisOptions, iconToolFor, iconToolOf, iconToolsOf, keyedPreviewConditions, linkedVarNaming, memberFromLeaf, memberLeaves, negatedCssValue, opacityPercentage, previewConditionalProps, previewConditions, previewDefaults, previewMatrix, propOwner, propValueDomain, propValueFromAxis, refListOf, renderStyleValue, resolveComponentProps, resolveFieldValue, resolveTokenValue, resolveTokenValueUnder, routedBag, sourceVarPrefix, styleAliasesOf, styleDeclarations, stylePropEntries, stylePropLeafForToken, stylePropNegates, stylePropTokenGroup, stylePropTokenPath, stylePropTokenValues, stylePropValueFromLeaf, stylePropValueLeaves, stylePropValues, stylePropertiesWriting, stylePropertyAccepts, stylePropertyFor, stylePropertyPathFor, validateComponentProps };
|
|
715
|
+
export { IconTool, IndexedPreviewCondition, PreviewMatrix, PropDeclaration, StyleDeclarationGroup, StylePropEntry, StylePropertyItem, VarNaming, authoredBag, authoredValue, className, cssPropValue, cssVar, cssVarRef, declarationKeyName, declaredPropDefaults, declaredPropRouting, declaresCssVariable, glyphComponentOf, glyphLibrariesOf, glyphPropsOf, heldLinked, holdingPreviewConditions, iconToolAxisOptions, iconToolFor, iconToolOf, iconToolsOf, keyedPreviewConditions, linkedVarNaming, literalValueOf, memberFromLeaf, memberLeaves, negatedCssValue, opacityPercentage, previewConditionalProps, previewConditions, previewDefaults, previewMatrix, propOwner, propValueDomain, propValueFromAxis, refListOf, renderInterpolated, renderStyleValue, resolveComponentProps, resolveFieldValue, resolveTokenValue, resolveTokenValueUnder, routedBag, sourceVarPrefix, styleAliasesOf, styleDeclarationGroups, styleDeclarations, stylePropEntries, stylePropLeafForToken, stylePropNegates, stylePropTokenGroup, stylePropTokenPath, stylePropTokenValues, stylePropValueFromLeaf, stylePropValueLeaves, stylePropValues, stylePropertiesWriting, stylePropertyAccepts, stylePropertyFor, stylePropertyPathFor, tokenReference, validateComponentProps };
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import { isRef, kindOf, memberOf, pathOf, ref, refLeaf, sourceOf, splitRef } from "./utils/refs.js";
|
|
1
|
+
import { declarationText, hasRefMarker, isRef, kindOf, memberOf, pathOf, ref, refLeaf, refOfKey, replaceRefMarkers, sourceOf, splitRef } from "./utils/refs.js";
|
|
2
|
+
import { evaluateCalc, isDivide, isMultiply, leadingNumber } from "../entities/system/calc.js";
|
|
3
|
+
import { isOklchColor, renderOklch } from "../entities/system/color.js";
|
|
2
4
|
import { isComposedValue, renderComposedValue } from "../entities/system/composed-values.js";
|
|
3
5
|
import { modifierCategory } from "../entities/system/modifier-axis.js";
|
|
4
6
|
import { forwardedPropName, forwardsOf, rootLayerOf } from "../entities/system/element.js";
|
|
@@ -6,7 +8,7 @@ import { fontFamilyStack } from "../entities/system/Font.js";
|
|
|
6
8
|
import { listedIn } from "./utils/enumerated.js";
|
|
7
9
|
import "../entities/system/Modifier.js";
|
|
8
10
|
import { createSliceMemo } from "./memo.js";
|
|
9
|
-
import { classPrefixOf, varPrefixOf } from "../entities/system/Settings.js";
|
|
11
|
+
import { classPrefixOf, prefixed, varPrefixOf } from "../entities/system/Settings.js";
|
|
10
12
|
import { StyleProperty, leavesOfStylePropValue } from "../entities/system/StyleProperty.js";
|
|
11
13
|
import { isConditionalPreview, storedPreview, unconditionalPreviewProps } from "./preview-store.js";
|
|
12
14
|
//#region src/framework/projections.ts
|
|
@@ -53,7 +55,10 @@ function domainCache(cache, config) {
|
|
|
53
55
|
* construction, and already the only name resolution uses. So a borrowed variable lives in the
|
|
54
56
|
* consumer's namespace, qualified by the pin it came through.
|
|
55
57
|
*/
|
|
56
|
-
const sourceVarPrefix = (config, slug) =>
|
|
58
|
+
const sourceVarPrefix = (config, slug) => prefixed({
|
|
59
|
+
prefix: varPrefixOf(config),
|
|
60
|
+
name: kebab(slug)
|
|
61
|
+
});
|
|
57
62
|
/**
|
|
58
63
|
* The name each of a linked system's tokens has in `config`'s stylesheet.
|
|
59
64
|
*
|
|
@@ -124,13 +129,114 @@ function kebab(segment) {
|
|
|
124
129
|
* The group segment is kebab-cased and the leaf is not, which is not a stylistic choice: it's the
|
|
125
130
|
* shape the emitted stylesheet declares (`--{prefix}-{kebabCase(namespace)}-{safeTokenName(name)}`).
|
|
126
131
|
* Deriving it any other way produces a `var()` that resolves to nothing for any camelCase group.
|
|
132
|
+
*
|
|
133
|
+
* Under the config's own naming, a token's own `cssVariable` is its whole name (`--spacing`), or
|
|
134
|
+
* the exact name when it starts with `--` (`--mantine-color-primary`, whatever the prefix), and
|
|
135
|
+
* otherwise the nearest token group that declares a `cssPrefix` spells its part of the name:
|
|
136
|
+
* `fontSize/sm` under `fontSize: { cssPrefix: 'text' }` is `--text-sm`, and an empty `cssPrefix`
|
|
137
|
+
* drops the group's segment. An empty config prefix drops its own.
|
|
127
138
|
*/
|
|
128
139
|
function cssVar(config, _kind, path, varPrefix) {
|
|
129
140
|
if (typeof varPrefix === "function") return varPrefix(path);
|
|
130
|
-
const slash = path.indexOf("/");
|
|
131
141
|
const prefix = varPrefix ?? varPrefixOf(config);
|
|
132
|
-
|
|
133
|
-
|
|
142
|
+
const own = varPrefix === void 0 ? ownCssVariable(config, path) : void 0;
|
|
143
|
+
if (typeof own === "string") return own.startsWith("--") ? own : `--${prefixed({
|
|
144
|
+
prefix,
|
|
145
|
+
name: own
|
|
146
|
+
})}`;
|
|
147
|
+
const named = varPrefix === void 0 ? groupPrefixed(config, path) : void 0;
|
|
148
|
+
if (named) return `--${[
|
|
149
|
+
prefix,
|
|
150
|
+
named.prefix,
|
|
151
|
+
leafSegment(named.rest)
|
|
152
|
+
].filter(Boolean).join("-")}`;
|
|
153
|
+
const slash = path.indexOf("/");
|
|
154
|
+
if (slash <= 0 || slash >= path.length - 1) return `--${prefixed({
|
|
155
|
+
prefix,
|
|
156
|
+
name: kebab(path)
|
|
157
|
+
})}`;
|
|
158
|
+
return `--${prefixed({
|
|
159
|
+
prefix,
|
|
160
|
+
name: `${kebab(path.slice(0, slash))}-${leafSegment(path.slice(slash + 1))}`
|
|
161
|
+
})}`;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* A variable name's leaf: an identifier, so a space would end the name and is written as a hyphen,
|
|
165
|
+
* the same spelling the class carries (`stylePropClassName`).
|
|
166
|
+
*/
|
|
167
|
+
function leafSegment(leaf) {
|
|
168
|
+
return leaf.replaceAll(".", "_").replaceAll("/", "-").replace(/\s+/g, "-");
|
|
169
|
+
}
|
|
170
|
+
/** Token group path → its stored fields, per groups listing. */
|
|
171
|
+
const groupMetaCache = /* @__PURE__ */ new WeakMap();
|
|
172
|
+
/** Each token group's own fields by path, as the config holds them. */
|
|
173
|
+
function tokenGroupMeta(config) {
|
|
174
|
+
const groups = config.groups("token");
|
|
175
|
+
let meta = groupMetaCache.get(groups);
|
|
176
|
+
if (!meta) {
|
|
177
|
+
meta = new Map(groups.map((group) => [group.path, group.meta ?? {}]));
|
|
178
|
+
groupMetaCache.set(groups, meta);
|
|
179
|
+
}
|
|
180
|
+
return meta;
|
|
181
|
+
}
|
|
182
|
+
/** The nearest token group above `path` whose fields hold `field`, with the value and the path below
|
|
183
|
+
* the group. Read on the config itself, since a group's emit fields are local to the config that
|
|
184
|
+
* holds it. */
|
|
185
|
+
function nearestGroupField({ config, path, field }) {
|
|
186
|
+
const meta = tokenGroupMeta(config);
|
|
187
|
+
if (meta.size === 0) return void 0;
|
|
188
|
+
for (let at = path.lastIndexOf("/"); at > 0; at = path.lastIndexOf("/", at - 1)) {
|
|
189
|
+
const value = meta.get(path.slice(0, at))?.[field];
|
|
190
|
+
if (value !== void 0) return {
|
|
191
|
+
value,
|
|
192
|
+
rest: path.slice(at + 1)
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* The nearest token group above `path` that declares a `cssPrefix`, and the path below it.
|
|
198
|
+
* `undefined` when none does.
|
|
199
|
+
*/
|
|
200
|
+
function groupPrefixed(config, path) {
|
|
201
|
+
if (!config) return void 0;
|
|
202
|
+
const found = nearestGroupField({
|
|
203
|
+
config,
|
|
204
|
+
path,
|
|
205
|
+
field: "cssPrefix"
|
|
206
|
+
});
|
|
207
|
+
return typeof found?.value === "string" ? {
|
|
208
|
+
prefix: found.value,
|
|
209
|
+
rest: found.rest
|
|
210
|
+
} : void 0;
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Whether a token is declared as a custom property: its own `cssVariable`, else the nearest group's
|
|
214
|
+
* `cssVariables`, else yes. One that isn't is written into each value that uses it, as Tailwind's
|
|
215
|
+
* `@theme inline` does.
|
|
216
|
+
*/
|
|
217
|
+
function declaresCssVariable(config, path) {
|
|
218
|
+
const own = ownCssVariable(config, path);
|
|
219
|
+
if (own !== void 0) return own !== false;
|
|
220
|
+
const overrides = (config.resolve("token", path)?.toJSON())?.overrides;
|
|
221
|
+
if (overrides && Object.keys(overrides).length > 0) return true;
|
|
222
|
+
return nearestGroupField({
|
|
223
|
+
config,
|
|
224
|
+
path,
|
|
225
|
+
field: "cssVariables"
|
|
226
|
+
})?.value !== false;
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* How CSS reaches a token: `var(--…)` when it declares a variable, else its value written in place,
|
|
230
|
+
* as the stylesheet writes it. For anything that paints a token outside a style prop, a swatch, an
|
|
231
|
+
* effect colour, a background.
|
|
232
|
+
*/
|
|
233
|
+
function tokenReference(config, path) {
|
|
234
|
+
return renderStyleValue(config, ref("token", path));
|
|
235
|
+
}
|
|
236
|
+
/** A token's own `cssVariable`: the name it declares, `false` for none, `undefined` when unset. */
|
|
237
|
+
function ownCssVariable(config, path) {
|
|
238
|
+
const own = (config?.resolve("token", path)?.toJSON())?.cssVariable;
|
|
239
|
+
return typeof own === "string" || own === false ? own : void 0;
|
|
134
240
|
}
|
|
135
241
|
/** `var(--…)` — the CSS reference to {@link cssVar}. */
|
|
136
242
|
function cssVarRef(config, kind, path, varPrefix) {
|
|
@@ -140,7 +246,10 @@ function cssVarRef(config, kind, path, varPrefix) {
|
|
|
140
246
|
* whitespace in the path is written as a hyphen too; a composite or motion preset named with a space
|
|
141
247
|
* otherwise declares a rule no element's class list can match. */
|
|
142
248
|
function className(config, _kind, path) {
|
|
143
|
-
return
|
|
249
|
+
return prefixed({
|
|
250
|
+
prefix: classPrefixOf(config),
|
|
251
|
+
name: path.replaceAll("/", "-").replace(/\s+/g, "-")
|
|
252
|
+
});
|
|
144
253
|
}
|
|
145
254
|
/**
|
|
146
255
|
* A style prop's allowed values, flattened to concrete strings: literal keywords (`row`)
|
|
@@ -184,7 +293,7 @@ function memberEntries(config, target, opts) {
|
|
|
184
293
|
}
|
|
185
294
|
function expandMemberEntries(config, target, opts) {
|
|
186
295
|
const { kind, path, source, member: facet } = splitRef(target);
|
|
187
|
-
const offered = (holder, memberPath) => opts?.retired !== false || !holder.retired(kind, memberPath);
|
|
296
|
+
const offered = (holder, memberPath) => (opts?.retired !== false || !holder.retired(kind, memberPath)) && (holder.resolve(kind, memberPath)?.toJSON())?.utility !== false;
|
|
188
297
|
/**
|
|
189
298
|
* Whose members these are.
|
|
190
299
|
*
|
|
@@ -219,7 +328,7 @@ function expandMemberEntries(config, target, opts) {
|
|
|
219
328
|
}));
|
|
220
329
|
}
|
|
221
330
|
if (owner.resolve(kind, path)) {
|
|
222
|
-
if (
|
|
331
|
+
if (opts?.retired === false && owner.retired(kind, path)) return [];
|
|
223
332
|
return [{
|
|
224
333
|
leaf: path.slice(path.lastIndexOf("/") + 1),
|
|
225
334
|
path: qualify(path)
|
|
@@ -533,8 +642,55 @@ function resolveFieldValue(config, kind, path, field, seen = /* @__PURE__ */ new
|
|
|
533
642
|
/** A token's value with alias refs chased to the base literal — {@link resolveFieldValue} for the one
|
|
534
643
|
* field every token consumer asks about, narrowed to the scalar a display or a stylesheet can use. */
|
|
535
644
|
function resolveTokenValue(config, path, seen = /* @__PURE__ */ new Set()) {
|
|
536
|
-
|
|
537
|
-
|
|
645
|
+
return literalOf({
|
|
646
|
+
config,
|
|
647
|
+
value: resolveFieldValue(config, "token", path, "value", seen),
|
|
648
|
+
seen
|
|
649
|
+
});
|
|
650
|
+
}
|
|
651
|
+
/**
|
|
652
|
+
* A stored value as the literal it comes to: a string or a number as itself, an OKLCH colour as its
|
|
653
|
+
* CSS, arithmetic evaluated over its operands' literals (`multiply(Token.ref('spacing'), 4)` with
|
|
654
|
+
* `spacing` at `0.25rem` is `1rem`), and a token ref as that token's literal. `undefined` for a value
|
|
655
|
+
* that is no single literal (a shadow, a gradient) or a ref that resolves to nothing.
|
|
656
|
+
*/
|
|
657
|
+
function literalValueOf(config, value) {
|
|
658
|
+
return literalOf({
|
|
659
|
+
config,
|
|
660
|
+
value,
|
|
661
|
+
seen: /* @__PURE__ */ new Set()
|
|
662
|
+
});
|
|
663
|
+
}
|
|
664
|
+
/** `condition` reads each token the value names under that override condition, `null` its base. */
|
|
665
|
+
function literalOf({ config, value, seen, condition = null }) {
|
|
666
|
+
if (typeof value === "number") return value;
|
|
667
|
+
if (typeof value === "string") {
|
|
668
|
+
if (!hasRefMarker(value)) return value;
|
|
669
|
+
let unresolved = false;
|
|
670
|
+
const text = replaceRefMarkers(value, (target) => {
|
|
671
|
+
const literal = literalOf({
|
|
672
|
+
config,
|
|
673
|
+
value: target,
|
|
674
|
+
seen,
|
|
675
|
+
condition
|
|
676
|
+
});
|
|
677
|
+
if (literal === void 0) unresolved = true;
|
|
678
|
+
return String(literal ?? "");
|
|
679
|
+
});
|
|
680
|
+
return unresolved ? void 0 : text;
|
|
681
|
+
}
|
|
682
|
+
if (isOklchColor(value)) return renderOklch(value);
|
|
683
|
+
if (isMultiply(value) || isDivide(value)) return evaluateCalc(value, (part) => literalOf({
|
|
684
|
+
config,
|
|
685
|
+
value: part,
|
|
686
|
+
seen,
|
|
687
|
+
condition
|
|
688
|
+
}));
|
|
689
|
+
if (isRef(value) && kindOf(value) === "token") {
|
|
690
|
+
const source = config.configFor(value);
|
|
691
|
+
if (!source) return void 0;
|
|
692
|
+
return condition === null ? resolveTokenValue(source, pathOf(value), new Set(seen)) : resolveTokenValueUnder(source, pathOf(value), condition, new Set(seen));
|
|
693
|
+
}
|
|
538
694
|
}
|
|
539
695
|
/**
|
|
540
696
|
* The literal a token resolves to under an override condition: its own override there when it holds
|
|
@@ -559,7 +715,25 @@ function resolveTokenValueUnder(config, path, condition, seen = /* @__PURE__ */
|
|
|
559
715
|
if (kindOf(value) !== "token") return void 0;
|
|
560
716
|
return resolveTokenValueUnder(source, pathOf(value), condition, seen);
|
|
561
717
|
}
|
|
562
|
-
return
|
|
718
|
+
return literalOf({
|
|
719
|
+
config,
|
|
720
|
+
value,
|
|
721
|
+
seen,
|
|
722
|
+
condition
|
|
723
|
+
});
|
|
724
|
+
}
|
|
725
|
+
/**
|
|
726
|
+
* A string's interpolated refs written as their tokens: `blur({token:blur/sm})` is
|
|
727
|
+
* `blur(var(--blur-sm))`. A ref opening a `var(` is the variable's name, so a fallback can follow it:
|
|
728
|
+
* `var({token:tw/leading}, 1.5)` is `var(--tw-leading, 1.5)`.
|
|
729
|
+
*/
|
|
730
|
+
function renderInterpolated({ config, text, varPrefix }) {
|
|
731
|
+
if (!text.includes("{")) return text;
|
|
732
|
+
return text.replace(/(var\(\s*)?\{([a-z][\w-]*:[^{}\s]*)\}/g, (_, open, target) => {
|
|
733
|
+
const rendered = renderStyleValue(config, { __ref: target }, varPrefix);
|
|
734
|
+
if (!open) return rendered;
|
|
735
|
+
return `${open}${/^var\((--[\w-]+)\)$/.exec(rendered)?.[1] ?? rendered}`;
|
|
736
|
+
});
|
|
563
737
|
}
|
|
564
738
|
/** A style-bag value → its CSS string: a token ref (or a bare token path) becomes a
|
|
565
739
|
* `var(--…)` reference (so mode/theme overrides still flow), anything else is the literal.
|
|
@@ -576,18 +750,33 @@ function renderStyleValue(config, value, varPrefix) {
|
|
|
576
750
|
if (!source) return "";
|
|
577
751
|
if (kindOf(value) === "font") return fontStackOf(source, pathOf(value)) ?? "";
|
|
578
752
|
const slug = sourceOf(value);
|
|
753
|
+
if (!declaresCssVariable(source, pathOf(value))) return renderStyleValue(source, inlineValueOf(source, pathOf(value)), slug === void 0 ? varPrefix : linkedVarNaming(config, slug));
|
|
579
754
|
return cssVarRef(source, "token", pathOf(value), slug === void 0 ? varPrefix : linkedVarNaming(config, slug));
|
|
580
755
|
}
|
|
756
|
+
if (typeof value === "string" && hasRefMarker(value)) return renderInterpolated({
|
|
757
|
+
config,
|
|
758
|
+
text: value,
|
|
759
|
+
varPrefix
|
|
760
|
+
});
|
|
581
761
|
if (typeof value === "string" && sourceOf(value) !== void 0) {
|
|
582
762
|
const asRef = ref("token", value);
|
|
583
763
|
if (config.resolveRef(asRef)) return renderStyleValue(config, asRef, varPrefix);
|
|
584
764
|
}
|
|
585
|
-
if (typeof value === "string" && config.resolve("token", value))
|
|
765
|
+
if (typeof value === "string" && config.resolve("token", value)) {
|
|
766
|
+
if (!declaresCssVariable(config, value)) return renderStyleValue(config, inlineValueOf(config, value), varPrefix);
|
|
767
|
+
return cssVarRef(config, "token", value, varPrefix);
|
|
768
|
+
}
|
|
586
769
|
if (typeof value === "string" && value.startsWith("[") && value.endsWith("]")) return value.slice(1, -1).replace(/url\([^)]*\)|_/g, (span) => span === "_" ? " " : span);
|
|
587
770
|
return String(value);
|
|
588
771
|
}
|
|
772
|
+
/** The stored value of a token that declares no variable, rendered in its place. */
|
|
773
|
+
function inlineValueOf(config, path) {
|
|
774
|
+
return (config.resolve("token", path)?.toJSON())?.value;
|
|
775
|
+
}
|
|
589
776
|
/**
|
|
590
|
-
* The value a negating prop paints
|
|
777
|
+
* The value a negating prop paints: a length or a percentage with a minus sign (`-1px`, `-100%`, and
|
|
778
|
+
* a zero as it is), a scale step's multiplier negated (`calc(var(--spacing) * -4)`), and anything
|
|
779
|
+
* else, a `var()` included, as `calc(<value> * -1)` — the spellings Tailwind writes.
|
|
591
780
|
*
|
|
592
781
|
* `calc` rather than a computed literal because the value is usually a `var(--…)`: the token it names
|
|
593
782
|
* has to stay a reference, so a mode override or a theme swap still reaches it. It's applied at the
|
|
@@ -598,8 +787,33 @@ function renderStyleValue(config, value, varPrefix) {
|
|
|
598
787
|
* literal is worse than one that never negates at all.
|
|
599
788
|
*/
|
|
600
789
|
function negatedCssValue(value) {
|
|
790
|
+
const length = leadingNumber(value);
|
|
791
|
+
if (length && NEGATABLE_UNIT.test(length.rest)) {
|
|
792
|
+
const { sign, digits, rest: unit } = length;
|
|
793
|
+
if (Number(digits) === 0) return value;
|
|
794
|
+
return sign ? `${digits}${unit}` : `-${digits}${unit}`;
|
|
795
|
+
}
|
|
796
|
+
const step = scaleStepOf(value);
|
|
797
|
+
if (step) return `calc(${step.base} * ${step.sign ? "" : "-"}${step.digits})`;
|
|
601
798
|
return `calc(${value} * -1)`;
|
|
602
799
|
}
|
|
800
|
+
const NEGATABLE_UNIT = /^(?:px|%|r?em|ch|ex|lh|s?v[hw]|d?v[hw]|l?v[hw]|vmin|vmax|cm|mm|in|pt|pc)$/;
|
|
801
|
+
/** A `calc(var(--name) * <number>)` split into the `var()` and the factor. */
|
|
802
|
+
function scaleStepOf(value) {
|
|
803
|
+
if (!value.startsWith("calc(") || !value.endsWith(")")) return void 0;
|
|
804
|
+
const inner = value.slice(5, -1);
|
|
805
|
+
const times = inner.indexOf(" * ");
|
|
806
|
+
if (times === -1) return void 0;
|
|
807
|
+
const base = inner.slice(0, times);
|
|
808
|
+
if (!/^var\(--[\w-]+\)$/.test(base)) return void 0;
|
|
809
|
+
const factor = leadingNumber(inner.slice(times + 3));
|
|
810
|
+
if (factor?.rest !== "") return void 0;
|
|
811
|
+
return {
|
|
812
|
+
base,
|
|
813
|
+
sign: factor.sign,
|
|
814
|
+
digits: factor.digits
|
|
815
|
+
};
|
|
816
|
+
}
|
|
603
817
|
/**
|
|
604
818
|
* What one component's own module does with each prop it declares — name → the style property that
|
|
605
819
|
* prop writes, or `null` for a prop that writes none.
|
|
@@ -749,6 +963,27 @@ function routedBag({ config, through, bag }) {
|
|
|
749
963
|
}
|
|
750
964
|
return routed;
|
|
751
965
|
}
|
|
966
|
+
/** A declaration's key as CSS: a property as itself, a token's key `{token:tw/blur}` as the variable
|
|
967
|
+
* the token declares. */
|
|
968
|
+
function declarationKeyName({ config, key, namespace }) {
|
|
969
|
+
const keyed = refOfKey(key);
|
|
970
|
+
return keyed ? cssVar(config, "token", pathOf(keyed), namespace) : key;
|
|
971
|
+
}
|
|
972
|
+
/** A style prop's own `declarations`, each ref written as its token: a key `{token:…}` as the
|
|
973
|
+
* variable the token declares, and an interpolated ref as it renders. `{value}` is left in place. */
|
|
974
|
+
function propDeclarations({ config, body, namespace }) {
|
|
975
|
+
return Object.fromEntries(Object.entries(body.declarations ?? {}).map(([key, value]) => {
|
|
976
|
+
return [declarationKeyName({
|
|
977
|
+
config,
|
|
978
|
+
key,
|
|
979
|
+
namespace
|
|
980
|
+
}), renderInterpolated({
|
|
981
|
+
config,
|
|
982
|
+
text: declarationText(value),
|
|
983
|
+
varPrefix: namespace
|
|
984
|
+
})];
|
|
985
|
+
}));
|
|
986
|
+
}
|
|
752
987
|
/**
|
|
753
988
|
* The leaf a bag value names, for looking its entry up — or `undefined` when it names none.
|
|
754
989
|
*
|
|
@@ -759,8 +994,38 @@ function leafAuthoredFor(value) {
|
|
|
759
994
|
if (typeof value === "boolean") return value ? "" : void 0;
|
|
760
995
|
if (typeof value === "string" || typeof value === "number") return String(value);
|
|
761
996
|
}
|
|
997
|
+
/**
|
|
998
|
+
* The declarations a bag sets on the element itself. Declarations a prop scopes to a `selector` or a
|
|
999
|
+
* value scopes to an at-rule are not the element's, so they are left out; a stylesheet reads them
|
|
1000
|
+
* from {@link styleDeclarationGroups}.
|
|
1001
|
+
*/
|
|
762
1002
|
function styleDeclarations({ config, bag, namespace }) {
|
|
763
|
-
|
|
1003
|
+
return styleDeclarationGroups({
|
|
1004
|
+
config,
|
|
1005
|
+
bag,
|
|
1006
|
+
namespace
|
|
1007
|
+
}).find((group) => group.selector === void 0 && group.atRule === void 0)?.declarations ?? {};
|
|
1008
|
+
}
|
|
1009
|
+
/**
|
|
1010
|
+
* A bag's declarations in the blocks they apply in: the element's own first, then each `selector`
|
|
1011
|
+
* and at-rule block in the order the bag first reaches it. A block that sets nothing is left out.
|
|
1012
|
+
*/
|
|
1013
|
+
function styleDeclarationGroups({ config, bag, namespace }) {
|
|
1014
|
+
const groups = /* @__PURE__ */ new Map();
|
|
1015
|
+
const blockFor = ({ selector, atRule }) => {
|
|
1016
|
+
const id = `${selector ?? ""}\u0000${atRule ?? ""}`;
|
|
1017
|
+
let group = groups.get(id);
|
|
1018
|
+
if (!group) {
|
|
1019
|
+
group = {
|
|
1020
|
+
...selector === void 0 ? {} : { selector },
|
|
1021
|
+
...atRule === void 0 ? {} : { atRule },
|
|
1022
|
+
declarations: {}
|
|
1023
|
+
};
|
|
1024
|
+
groups.set(id, group);
|
|
1025
|
+
}
|
|
1026
|
+
return group.declarations;
|
|
1027
|
+
};
|
|
1028
|
+
const out = blockFor({});
|
|
764
1029
|
const fades = /* @__PURE__ */ new Map();
|
|
765
1030
|
for (const [rawKey, value] of Object.entries(bag)) {
|
|
766
1031
|
if (rawKey.startsWith("_") || rawKey.startsWith("--")) continue;
|
|
@@ -794,11 +1059,36 @@ function styleDeclarations({ config, bag, namespace }) {
|
|
|
794
1059
|
if (!prop) continue;
|
|
795
1060
|
const body = prop.toJSON();
|
|
796
1061
|
if (isRef(body.opacityOf)) continue;
|
|
797
|
-
const
|
|
1062
|
+
const selector = body.selector || void 0;
|
|
1063
|
+
const target = blockFor({ selector });
|
|
1064
|
+
const cssProperties = Array.isArray(body.properties) ? body.properties.map((property) => {
|
|
1065
|
+
const keyed = refOfKey(property);
|
|
1066
|
+
return keyed ? cssVar(config, "token", pathOf(keyed), namespace) : property;
|
|
1067
|
+
}) : [];
|
|
798
1068
|
const authoredLeafValue = leafAuthoredFor(value);
|
|
799
1069
|
const entry = authoredLeafValue === void 0 ? void 0 : stylePropEntries(config, key).find((candidate) => candidate.leaf === authoredLeafValue);
|
|
800
1070
|
if (entry?.declarations) {
|
|
801
|
-
for (const [
|
|
1071
|
+
for (const [key, declaredValue] of Object.entries(entry.declarations)) target[declarationKeyName({
|
|
1072
|
+
config,
|
|
1073
|
+
key,
|
|
1074
|
+
namespace
|
|
1075
|
+
})] = renderStyleValue(config, declaredValue, namespace);
|
|
1076
|
+
for (const [cssProperty, declared] of Object.entries(propDeclarations({
|
|
1077
|
+
config,
|
|
1078
|
+
body,
|
|
1079
|
+
namespace
|
|
1080
|
+
}))) if (!declared.includes("{value}")) target[cssProperty] = declared;
|
|
1081
|
+
for (const [atRule, block] of Object.entries(entry.atRules ?? {})) {
|
|
1082
|
+
const scoped = blockFor({
|
|
1083
|
+
selector,
|
|
1084
|
+
atRule
|
|
1085
|
+
});
|
|
1086
|
+
for (const [key, declaredValue] of Object.entries(block)) scoped[declarationKeyName({
|
|
1087
|
+
config,
|
|
1088
|
+
key,
|
|
1089
|
+
namespace
|
|
1090
|
+
})] = renderStyleValue(config, declaredValue, namespace);
|
|
1091
|
+
}
|
|
802
1092
|
continue;
|
|
803
1093
|
}
|
|
804
1094
|
const base = renderBagValue({
|
|
@@ -811,9 +1101,14 @@ function styleDeclarations({ config, bag, namespace }) {
|
|
|
811
1101
|
let rendered = stylePropNegates(config, key) ? negatedCssValue(base) : base;
|
|
812
1102
|
const fade = fades.get(key);
|
|
813
1103
|
if (fade !== void 0) rendered = `color-mix(in srgb, ${rendered} ${fade}, transparent)`;
|
|
814
|
-
for (const cssProperty of cssProperties)
|
|
1104
|
+
for (const cssProperty of cssProperties) target[cssProperty] = rendered;
|
|
1105
|
+
for (const [cssProperty, declared] of Object.entries(propDeclarations({
|
|
1106
|
+
config,
|
|
1107
|
+
body,
|
|
1108
|
+
namespace
|
|
1109
|
+
}))) target[cssProperty] = declared.replaceAll("{value}", rendered);
|
|
815
1110
|
}
|
|
816
|
-
return
|
|
1111
|
+
return [...groups.values()].filter((group) => Object.keys(group.declarations).length > 0);
|
|
817
1112
|
}
|
|
818
1113
|
/** One bag value as CSS text, or `undefined` for a flag turned off. */
|
|
819
1114
|
function renderBagValue({ config, key, value, namespace }) {
|
|
@@ -1375,4 +1670,4 @@ function declaredPropDefaults(props) {
|
|
|
1375
1670
|
return out;
|
|
1376
1671
|
}
|
|
1377
1672
|
//#endregion
|
|
1378
|
-
export { LAYER_PROPS, authoredBag, authoredValue, className, cssPropValue, cssVar, cssVarRef, declaredPropDefaults, declaredPropRouting, glyphComponentOf, glyphLibrariesOf, glyphPropsOf, glyphPropsOfBody, heldLinked, holdingPreviewConditions, iconToolAxisOptions, iconToolFor, iconToolOf, iconToolsOf, keyedPreviewConditions, layerPropsErrors, linkedVarNaming, memberFromLeaf, memberLeaves, negatedCssValue, opacityPercentage, previewConditionalProps, previewConditions, previewDefaults, previewMatrix, propOwner, propValueDomain, propValueFromAxis, refListOf, renderStyleValue, resolveComponentProps, resolveFieldValue, resolveTokenValue, resolveTokenValueUnder, routedBag, sourceVarPrefix, styleAliasesOf, styleDeclarations, stylePropEntries, stylePropLeafForToken, stylePropNegates, stylePropTokenGroup, stylePropTokenPath, stylePropTokenValues, stylePropValueFromLeaf, stylePropValueLeaves, stylePropValues, stylePropertiesWriting, stylePropertyAccepts, stylePropertyFor, stylePropertyPathFor, takenByForward, validateComponentProps };
|
|
1673
|
+
export { LAYER_PROPS, authoredBag, authoredValue, className, cssPropValue, cssVar, cssVarRef, declarationKeyName, declaredPropDefaults, declaredPropRouting, declaresCssVariable, glyphComponentOf, glyphLibrariesOf, glyphPropsOf, glyphPropsOfBody, heldLinked, holdingPreviewConditions, iconToolAxisOptions, iconToolFor, iconToolOf, iconToolsOf, keyedPreviewConditions, layerPropsErrors, linkedVarNaming, literalValueOf, memberFromLeaf, memberLeaves, negatedCssValue, opacityPercentage, previewConditionalProps, previewConditions, previewDefaults, previewMatrix, propOwner, propValueDomain, propValueFromAxis, refListOf, renderInterpolated, renderStyleValue, resolveComponentProps, resolveFieldValue, resolveTokenValue, resolveTokenValueUnder, routedBag, sourceVarPrefix, styleAliasesOf, styleDeclarationGroups, styleDeclarations, stylePropEntries, stylePropLeafForToken, stylePropNegates, stylePropTokenGroup, stylePropTokenPath, stylePropTokenValues, stylePropValueFromLeaf, stylePropValueLeaves, stylePropValues, stylePropertiesWriting, stylePropertyAccepts, stylePropertyFor, stylePropertyPathFor, takenByForward, tokenReference, validateComponentProps };
|
|
@@ -33,7 +33,7 @@ function edgesOf(ref, data, extra = [], linkKinds = [], singletonKinds = []) {
|
|
|
33
33
|
if (linkKinds.length > 0) for (const target of collected) {
|
|
34
34
|
const slug = sourceOf(target);
|
|
35
35
|
if (slug === void 0) continue;
|
|
36
|
-
for (const kind of linkKinds) targets.add(`${kind}:${slug}`);
|
|
36
|
+
for (const kind of linkKinds) targets.add(`${kind}:${slug.split("~")[0]}`);
|
|
37
37
|
}
|
|
38
38
|
for (const target of extra) targets.add(target);
|
|
39
39
|
targets.delete(ref);
|
|
@@ -49,6 +49,13 @@ type AuthoredValueForm = (ctx: {
|
|
|
49
49
|
}) => z.ZodTypeAny | undefined;
|
|
50
50
|
interface EntityKind {
|
|
51
51
|
readonly name: string;
|
|
52
|
+
/** Adapt a pinned source body before this kind validates a linked extension. */
|
|
53
|
+
readonly prepareLinkedBody?: (args: {
|
|
54
|
+
readonly path: string;
|
|
55
|
+
readonly body: Record<string, unknown>;
|
|
56
|
+
readonly source: Config; /** The config borrowing the body, which resolves the body's source-qualified refs. */
|
|
57
|
+
readonly config: Config;
|
|
58
|
+
}) => Record<string, unknown>;
|
|
52
59
|
/** The entity class's name (`style-property` → `StyleProperty`) — what a consumer writes to reach
|
|
53
60
|
* it (`StyleProperty.ref(...)`, `Token.group(...)`).
|
|
54
61
|
*
|
|
@@ -32,7 +32,7 @@ function titleCase(kind) {
|
|
|
32
32
|
/** Derive a kind's immutable metadata from its field schemas — the value a `defineEntity`/
|
|
33
33
|
* `defineDerivedEntity` attaches to its class and a `Config.register` stores in `#entities`. */
|
|
34
34
|
function buildKind(spec) {
|
|
35
|
-
const { name, fields, groupFields, subEntities = {}, computed, label, labelPlural, schemas: userSchemas, derived, sourceIdentity, sourceOrigin, authoredRefs, linkable, localGroupFields, emergentGroups, singleton = false, bareMember, sourceResolution, bulkAdopts, bulkOverlay, bulkDirectives, bulkOverlayWrite, nameEdges, rewriteName, styleBags, uniqueLeaves, authoredValue, mentionFields, invariants } = spec;
|
|
35
|
+
const { name, prepareLinkedBody, fields, groupFields, subEntities = {}, computed, label, labelPlural, schemas: userSchemas, derived, sourceIdentity, sourceOrigin, authoredRefs, linkable, localGroupFields, emergentGroups, singleton = false, bareMember, sourceResolution, bulkAdopts, bulkOverlay, bulkDirectives, bulkOverlayWrite, nameEdges, rewriteName, styleBags, uniqueLeaves, authoredValue, mentionFields, invariants } = spec;
|
|
36
36
|
const allComputed = {
|
|
37
37
|
sources: ({ member, config }) => sourceSlugs(member, config),
|
|
38
38
|
borrowedFrom: ({ config, path }) => config.borrowedFrom(name, path),
|
|
@@ -48,6 +48,7 @@ function buildKind(spec) {
|
|
|
48
48
|
}
|
|
49
49
|
return {
|
|
50
50
|
name,
|
|
51
|
+
...prepareLinkedBody ? { prepareLinkedBody } : {},
|
|
51
52
|
label: resolvedLabel,
|
|
52
53
|
entityName: spec.entityName ?? entityClassName(name),
|
|
53
54
|
labelPlural: labelPlural ?? `${resolvedLabel}s`,
|
|
@@ -15,7 +15,7 @@ import { Patch, SerializedConfig } from "./Config.js";
|
|
|
15
15
|
* sets this constant to its own older timestamp; the merge ref then carries a registered migration
|
|
16
16
|
* newer than the constant, and the assertion fails until the author re-mints.
|
|
17
17
|
*/
|
|
18
|
-
declare const CURRENT_SCHEMA_VERSION =
|
|
18
|
+
declare const CURRENT_SCHEMA_VERSION = 20261001162046;
|
|
19
19
|
/** What the walkers need to see of an envelope — loose on purpose, so a typed `SerializedConfig`
|
|
20
20
|
* and a raw old-shape record both flow in without casts. */
|
|
21
21
|
interface VersionStamped {
|