@yahoo/uds-create-config 5.32.2 → 5.32.4
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/CanvasConfig.d.ts +3 -3
- package/dist/configs/react-native-system.d.ts +58 -26
- package/dist/configs/react-native-system.js +1 -1
- package/dist/configs/system.js +2 -2
- package/dist/entities/native/NativeModifier.d.ts +2 -2
- package/dist/entities/native/NativeStyleProperty.d.ts +39 -39
- package/dist/entities/native/NativeToken.d.ts +40 -7
- package/dist/entities/native/NativeToken.js +8 -4
- package/dist/entities/system/Component.js +28 -6
- package/dist/entities/system/Composite.js +5 -0
- package/dist/entities/system/Modifier.d.ts +2 -2
- package/dist/entities/system/Motion.d.ts +1 -1
- package/dist/entities/system/Settings.js +1 -1
- package/dist/entities/system/Token.js +5 -4
- package/dist/entities/system/component-module.js +1 -1
- package/dist/entities/system/defineComponent.d.ts +14 -8
- package/dist/entities/system/linked-flex-values.d.ts +19 -0
- package/dist/entities/system/linked-flex-values.js +77 -0
- package/dist/entities/system/linked-style-values.d.ts +11 -0
- package/dist/entities/system/linked-style-values.js +47 -0
- package/dist/entities/system/linked-token-values.d.ts +6 -3
- package/dist/entities/system/linked-token-values.js +19 -7
- package/dist/entities/system/motion-presets.js +1 -1
- package/dist/framework/Config.d.ts +3 -1
- package/dist/framework/Config.js +22 -11
- package/dist/framework/projections.js +1 -1
- package/dist/framework/registry.d.ts +5 -2
- package/dist/index.d.ts +2 -1
- package/dist/index.js +10 -9
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { reject, rejectData } from "../../framework/rejection.js";
|
|
2
|
-
import { canonicalCondition, collectRefs, isRef, kindOf, memberRef, pathOf, ref, refLeaf, refSchema, splitRef } from "../../framework/utils/refs.js";
|
|
2
|
+
import { canonicalCondition, collectRefs, isRef, kindOf, memberRef, pathOf, ref, refLeaf, refSchema, sourceOf, splitRef } from "../../framework/utils/refs.js";
|
|
3
3
|
import { isPlainObject } from "../../framework/utils/field-path.js";
|
|
4
4
|
import { pathInput } from "../../framework/schemas.js";
|
|
5
5
|
import { derivedColor, gradient, oklchColor } from "./color.js";
|
|
@@ -8,6 +8,7 @@ import { defineEntity } from "../../framework/defineEntity.js";
|
|
|
8
8
|
import { defineSubEntity, orList } from "../../framework/defineSubEntity.js";
|
|
9
9
|
import { childrenPolicy, forwardedPropName } from "./element.js";
|
|
10
10
|
import { interactionKey, interactionModifiers } from "../../framework/interaction-conditions.js";
|
|
11
|
+
import { translateLinkedStyleBags } from "./linked-style-values.js";
|
|
11
12
|
import { listedIn } from "../../framework/utils/enumerated.js";
|
|
12
13
|
import { valueSchemaOf } from "../../framework/value-domain.js";
|
|
13
14
|
import { Package } from "./Package.js";
|
|
@@ -600,13 +601,21 @@ function declaringInto(config, layers, decl) {
|
|
|
600
601
|
const minted = (route) => {
|
|
601
602
|
if (!isRef(route.target)) return route;
|
|
602
603
|
const element = layers?.[pathOf(route.target)];
|
|
603
|
-
if (
|
|
604
|
+
if (element === void 0 || element === null) return route;
|
|
604
605
|
const name = intoName(route.into);
|
|
605
|
-
|
|
606
|
-
|
|
606
|
+
if (!isRef(element) || kindOf(element) !== "component") return route.into === name ? route : {
|
|
607
|
+
...route,
|
|
608
|
+
into: name
|
|
609
|
+
};
|
|
610
|
+
const ownerConfig = config.configFor(element);
|
|
611
|
+
if (!ownerConfig) return route;
|
|
612
|
+
const owner = propOwner(ownerConfig, pathOf(element), name);
|
|
613
|
+
if (!owner && !isRef(route.into)) return route;
|
|
614
|
+
const into = memberRef("component", owner ?? pathOf(element), "props", name, sourceOf(element));
|
|
615
|
+
if (isRef(route.into) && route.into.__ref === into.__ref) return route;
|
|
607
616
|
return {
|
|
608
617
|
...route,
|
|
609
|
-
into
|
|
618
|
+
into
|
|
610
619
|
};
|
|
611
620
|
};
|
|
612
621
|
const first = minted(decl);
|
|
@@ -1808,7 +1817,7 @@ const componentBags = (data) => {
|
|
|
1808
1817
|
if (!isPlainRecord(layers)) continue;
|
|
1809
1818
|
for (const [layer, bag] of Object.entries(layers)) collectBag(bag, (next) => {
|
|
1810
1819
|
layers[layer] = next;
|
|
1811
|
-
}, out);
|
|
1820
|
+
}, out, body?.layers?.[layer]);
|
|
1812
1821
|
}
|
|
1813
1822
|
for (const node of Object.values(body?.anatomy ?? {})) {
|
|
1814
1823
|
if (!isPlainRecord(node)) continue;
|
|
@@ -1823,6 +1832,19 @@ const componentBags = (data) => {
|
|
|
1823
1832
|
};
|
|
1824
1833
|
const ComponentEntity = defineEntity({
|
|
1825
1834
|
kind: "component",
|
|
1835
|
+
rebaseLinkedBody: (args) => translateLinkedStyleBags({
|
|
1836
|
+
...args,
|
|
1837
|
+
bags: componentBags,
|
|
1838
|
+
owner: args.path
|
|
1839
|
+
}),
|
|
1840
|
+
prepareLinkedBody: ({ body, config }) => {
|
|
1841
|
+
if (!isPlainObject(body.props)) return body;
|
|
1842
|
+
const layers = isPlainObject(body.layers) ? body.layers : void 0;
|
|
1843
|
+
return {
|
|
1844
|
+
...body,
|
|
1845
|
+
props: Object.fromEntries(Object.entries(body.props).map(([name, decl]) => [name, declaringInto(config, layers, decl)]))
|
|
1846
|
+
};
|
|
1847
|
+
},
|
|
1826
1848
|
fields: componentFields,
|
|
1827
1849
|
groupFields: z.object({ icon: z.string().optional() }),
|
|
1828
1850
|
subEntities: {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { defineEntity } from "../../framework/defineEntity.js";
|
|
2
|
+
import { translateLinkedStyleBags } from "./linked-style-values.js";
|
|
2
3
|
import { Style, bagNameEdges, bagRewriteName, collectBag } from "./style-bag.js";
|
|
3
4
|
import { z } from "zod";
|
|
4
5
|
//#region src/entities/system/Composite.ts
|
|
@@ -13,6 +14,10 @@ const compositeBags = (data) => {
|
|
|
13
14
|
};
|
|
14
15
|
const Composite = defineEntity({
|
|
15
16
|
kind: "composite",
|
|
17
|
+
rebaseLinkedBody: (args) => translateLinkedStyleBags({
|
|
18
|
+
...args,
|
|
19
|
+
bags: compositeBags
|
|
20
|
+
}),
|
|
16
21
|
label: "Composite style",
|
|
17
22
|
labelPlural: "Composite styles",
|
|
18
23
|
fields: z.object({ styles: Style.describe("The style values the composite bundles. Each declaration is a member, so an editor writes one key at a time.") }),
|
|
@@ -30,8 +30,8 @@ type WebActivation = (typeof WEB_ACTIVATIONS)[number];
|
|
|
30
30
|
*/
|
|
31
31
|
declare const modifierGroupFields: z.ZodObject<{
|
|
32
32
|
type: z.ZodOptional<z.ZodEnum<{
|
|
33
|
-
mode: "mode";
|
|
34
33
|
state: "state";
|
|
34
|
+
mode: "mode";
|
|
35
35
|
}>>;
|
|
36
36
|
default: z.ZodOptional<z.ZodObject<{
|
|
37
37
|
__ref: z.ZodString;
|
|
@@ -53,8 +53,8 @@ declare const ModifierDefinition: EntityClass<z.ZodObject<{
|
|
|
53
53
|
declarations: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
54
54
|
}, z.core.$strip>, z.ZodObject<{
|
|
55
55
|
type: z.ZodOptional<z.ZodEnum<{
|
|
56
|
-
mode: "mode";
|
|
57
56
|
state: "state";
|
|
57
|
+
mode: "mode";
|
|
58
58
|
}>>;
|
|
59
59
|
default: z.ZodOptional<z.ZodObject<{
|
|
60
60
|
__ref: z.ZodString;
|
|
@@ -11,9 +11,9 @@ import { z } from "zod";
|
|
|
11
11
|
*/
|
|
12
12
|
declare const inlineJsMotion: z.ZodObject<{
|
|
13
13
|
transition: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
14
|
+
initial: z.ZodOptional<z.ZodUnion<readonly [z.ZodRecord<z.ZodString, z.ZodUnknown>, z.ZodString, z.ZodArray<z.ZodString>, z.ZodLiteral<false>]>>;
|
|
14
15
|
exit: z.ZodOptional<z.ZodUnion<readonly [z.ZodRecord<z.ZodString, z.ZodUnknown>, z.ZodString, z.ZodArray<z.ZodString>]>>;
|
|
15
16
|
layout: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodLiteral<"position">, z.ZodLiteral<"size">, z.ZodLiteral<"preserve-aspect">]>>;
|
|
16
|
-
initial: z.ZodOptional<z.ZodUnion<readonly [z.ZodRecord<z.ZodString, z.ZodUnknown>, z.ZodString, z.ZodArray<z.ZodString>, z.ZodLiteral<false>]>>;
|
|
17
17
|
variants: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
|
|
18
18
|
animate: z.ZodOptional<z.ZodUnion<readonly [z.ZodRecord<z.ZodString, z.ZodUnknown>, z.ZodString, z.ZodArray<z.ZodString>]>>;
|
|
19
19
|
whileHover: z.ZodOptional<z.ZodUnion<readonly [z.ZodRecord<z.ZodString, z.ZodUnknown>, z.ZodString, z.ZodArray<z.ZodString>]>>;
|
|
@@ -2,8 +2,8 @@ import { splitRef } from "../../framework/utils/refs.js";
|
|
|
2
2
|
import { defineEntity } from "../../framework/defineEntity.js";
|
|
3
3
|
import { defineSubEntity } from "../../framework/defineSubEntity.js";
|
|
4
4
|
import { createSliceMemo } from "../../framework/memo.js";
|
|
5
|
-
import { buildFields } from "../../configs/build-options.js";
|
|
6
5
|
import { parseRootFontSize } from "../../css/root-font-size.js";
|
|
6
|
+
import { buildFields } from "../../configs/build-options.js";
|
|
7
7
|
import { resolveInputDir } from "../../framework/registry-dir.js";
|
|
8
8
|
import { safelistSchema } from "./safelist.js";
|
|
9
9
|
import { z } from "zod";
|
|
@@ -3,9 +3,9 @@ import { composedValueSchemas } from "./composed-values.js";
|
|
|
3
3
|
import { defineEntity } from "../../framework/defineEntity.js";
|
|
4
4
|
import { defineSubEntity, orList } from "../../framework/defineSubEntity.js";
|
|
5
5
|
import { Font } from "./Font.js";
|
|
6
|
-
import { Modifier } from "./Modifier.js";
|
|
7
|
-
import { spellTokenRead } from "./token-values.js";
|
|
8
6
|
import { WEB_CONFIG_NAME } from "../../configs/platform.js";
|
|
7
|
+
import { spellTokenRead } from "./token-values.js";
|
|
8
|
+
import { Modifier } from "./Modifier.js";
|
|
9
9
|
import { authoringPhantom } from "../../framework/utils/authoring-phantom.js";
|
|
10
10
|
import { prepareLinkedTokenBody } from "./linked-token-values.js";
|
|
11
11
|
import { z } from "zod";
|
|
@@ -119,12 +119,13 @@ function defineOverride(value) {
|
|
|
119
119
|
const Override = defineOverride(tokenValue);
|
|
120
120
|
const TokenEntity = defineEntity({
|
|
121
121
|
kind: "token",
|
|
122
|
-
prepareLinkedBody: ({ path, body, source, config }) => prepareLinkedTokenBody({
|
|
122
|
+
prepareLinkedBody: ({ path, body, source, config, extend }) => prepareLinkedTokenBody({
|
|
123
123
|
path,
|
|
124
124
|
body,
|
|
125
125
|
source,
|
|
126
126
|
config,
|
|
127
|
-
destinationPlatform: WEB_CONFIG_NAME
|
|
127
|
+
destinationPlatform: WEB_CONFIG_NAME,
|
|
128
|
+
extend
|
|
128
129
|
}),
|
|
129
130
|
fields: z.object({
|
|
130
131
|
value: tokenValue.describe("The base value: a literal, a ref to another token, or a composed value such as a gradient."),
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { isRef, kindOf, pathOf, ref, routedSource, sourceHops, splitRef } from "../../framework/utils/refs.js";
|
|
2
2
|
import { createSliceMemo } from "../../framework/memo.js";
|
|
3
|
+
import { isNativeConfig } from "../../configs/platform.js";
|
|
3
4
|
import { Settings, classPrefixOf, prefixed, varPrefixOf } from "./Settings.js";
|
|
4
5
|
import { File } from "./File.js";
|
|
5
|
-
import { isNativeConfig } from "../../configs/platform.js";
|
|
6
6
|
import { Component } from "./Component.js";
|
|
7
7
|
import { contentKey } from "../../framework/utils/content-key.js";
|
|
8
8
|
//#region src/entities/system/component-module.ts
|
|
@@ -380,6 +380,18 @@ type LayerBag<Self, K extends PropertyKey> = Self extends ((props: infer Props)
|
|
|
380
380
|
*/
|
|
381
381
|
type SlotValueOf<D, Self, K extends PropertyKey, View extends SlotView> = View extends 'render' ? OwnSlotValue<D, 'render'> | null : string extends K ? // An open prop map (`PropMap` itself, read at a constraint) names no prop in particular, so
|
|
382
382
|
OwnSlotValue<D, 'consumer'> | null : OwnSlotValue<D, 'consumer'> | SlotCodeValue<D, Self, K> | null;
|
|
383
|
+
/** A forward's address in authored and stored contracts. Ownership refs identify the prop;
|
|
384
|
+
* the effective layer map still decides which element receives it. */
|
|
385
|
+
type ForwardPath<D> = D extends {
|
|
386
|
+
type: 'forward';
|
|
387
|
+
target: infer Target;
|
|
388
|
+
} ? Target extends string ? Target : Target extends readonly [infer First extends string, ...unknown[]] ? First : Target extends {
|
|
389
|
+
readonly __ref: `layer:${infer Layer}`;
|
|
390
|
+
} ? D extends {
|
|
391
|
+
into: infer Into;
|
|
392
|
+
} ? Into extends string ? `${Layer}/${Into}` : Into extends {
|
|
393
|
+
readonly __ref: `component:${string}#props/${infer Prop}`;
|
|
394
|
+
} ? `${Layer}/${Prop}` : never : `${Layer}/children` : never : never;
|
|
383
395
|
/** The declaration arms of {@link ValueOf}, after the two ref arms. */
|
|
384
396
|
type ValueOfDeclaration<D, Self, K extends PropertyKey, View extends SlotView> = D extends {
|
|
385
397
|
type: 'variant';
|
|
@@ -395,10 +407,7 @@ type ValueOfDeclaration<D, Self, K extends PropertyKey, View extends SlotView> =
|
|
|
395
407
|
} ? SlotValueOf<D, Self, K, View> : D extends {
|
|
396
408
|
type: 'forward';
|
|
397
409
|
text: true;
|
|
398
|
-
} ? string : D extends {
|
|
399
|
-
type: 'forward';
|
|
400
|
-
target: `${string}/children` | readonly [`${string}/children`, ...unknown[]];
|
|
401
|
-
} ? ReactNode : unknown;
|
|
410
|
+
} ? string : [ForwardPath<D>] extends [never] ? unknown : ForwardPath<D> extends `${string}/children` ? ReactNode : unknown;
|
|
402
411
|
/**
|
|
403
412
|
* A prop type's DECLARED props — everything but its index signature.
|
|
404
413
|
*
|
|
@@ -422,10 +431,7 @@ type DeclaredProps<P, L extends LayerMap = LayerMap, Self = unknown, View extend
|
|
|
422
431
|
type RoutedValueOf<L extends LayerMap, D, Self = unknown, K extends PropertyKey = never, View extends SlotView = 'consumer'> = D extends {
|
|
423
432
|
type: 'forward';
|
|
424
433
|
text: true;
|
|
425
|
-
} ? string : D extends {
|
|
426
|
-
type: 'forward';
|
|
427
|
-
target: `${infer Layer}/${infer Prop}` | readonly [`${infer Layer}/${infer Prop}`, ...unknown[]];
|
|
428
|
-
} ? Prop extends 'children' ? ReactNode : Layer extends keyof L ? Prop extends keyof ElementPropsOf<L[Layer]> ? ElementPropsOf<L[Layer]>[Prop] : unknown : unknown : ValueOf<D, Self, K, View>;
|
|
434
|
+
} ? string : [ForwardPath<D>] extends [never] ? ValueOf<D, Self, K, View> : ForwardPath<D> extends `${infer Layer}/${infer Prop}` ? Prop extends 'children' ? ReactNode : Layer extends keyof L ? Prop extends keyof ElementPropsOf<L[Layer]> ? ElementPropsOf<L[Layer]>[Prop] : unknown : unknown : ValueOf<D, Self, K, View>;
|
|
429
435
|
/**
|
|
430
436
|
* The props the rendered ELEMENT contributes, `ref` included.
|
|
431
437
|
*
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
|
|
3
|
+
//#region src/entities/system/linked-flex-values.d.ts
|
|
4
|
+
/** Native has no flex shorthand string. Its equivalent is these three style declarations. */
|
|
5
|
+
declare const nativeFlexValue: z.ZodObject<{
|
|
6
|
+
flexGrow: z.ZodNumber;
|
|
7
|
+
flexShrink: z.ZodNumber;
|
|
8
|
+
flexBasis: z.ZodUnion<readonly [z.ZodNumber, z.ZodLiteral<"auto">, z.ZodString]>;
|
|
9
|
+
}, z.core.$strict>;
|
|
10
|
+
type NativeFlexValue = z.infer<typeof nativeFlexValue>;
|
|
11
|
+
declare function isNativeFlexValue(value: unknown): value is NativeFlexValue;
|
|
12
|
+
/** The supported CSS flex grammar, resolved to RN longhands without losing its basis or shrink. */
|
|
13
|
+
declare function webFlexToNative(value: string | number, remBase?: number): NativeFlexValue;
|
|
14
|
+
/** RN numeric flex is not CSS numeric flex: Yoga's native defaults use shrink=0, and positive
|
|
15
|
+
* numbers use a 0pt basis. Negative flex supplies shrink while retaining auto basis.
|
|
16
|
+
* See Yoga Node::resolveFlexGrow/resolveFlexShrink/processFlexBasis with useWebDefaults=false. */
|
|
17
|
+
declare function nativeFlexToWeb(value: NativeFlexValue | number): string;
|
|
18
|
+
//#endregion
|
|
19
|
+
export { NativeFlexValue, isNativeFlexValue, nativeFlexToWeb, webFlexToNative };
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
//#region src/entities/system/linked-flex-values.ts
|
|
3
|
+
/** Native has no flex shorthand string. Its equivalent is these three style declarations. */
|
|
4
|
+
const nativeFlexValue = z.strictObject({
|
|
5
|
+
flexGrow: z.number().nonnegative(),
|
|
6
|
+
flexShrink: z.number().nonnegative(),
|
|
7
|
+
flexBasis: z.union([
|
|
8
|
+
z.number().nonnegative(),
|
|
9
|
+
z.literal("auto"),
|
|
10
|
+
z.string().regex(/^(?:\d+(?:\.\d+)?|\.\d+)%$/)
|
|
11
|
+
])
|
|
12
|
+
});
|
|
13
|
+
function isNativeFlexValue(value) {
|
|
14
|
+
return typeof value === "object" && value !== null && "flexGrow" in value && nativeFlexValue.safeParse(value).success;
|
|
15
|
+
}
|
|
16
|
+
const NUMBER = /^(?:\d+(?:\.\d+)?|\.\d+)$/;
|
|
17
|
+
/** The supported CSS flex grammar, resolved to RN longhands without losing its basis or shrink. */
|
|
18
|
+
function webFlexToNative(value, remBase) {
|
|
19
|
+
const text = String(value).trim();
|
|
20
|
+
if (text === "none") return {
|
|
21
|
+
flexGrow: 0,
|
|
22
|
+
flexShrink: 0,
|
|
23
|
+
flexBasis: "auto"
|
|
24
|
+
};
|
|
25
|
+
if (text === "auto") return {
|
|
26
|
+
flexGrow: 1,
|
|
27
|
+
flexShrink: 1,
|
|
28
|
+
flexBasis: "auto"
|
|
29
|
+
};
|
|
30
|
+
if (text === "initial") return {
|
|
31
|
+
flexGrow: 0,
|
|
32
|
+
flexShrink: 1,
|
|
33
|
+
flexBasis: "auto"
|
|
34
|
+
};
|
|
35
|
+
const parts = text.split(/\s+/);
|
|
36
|
+
let grow = 1;
|
|
37
|
+
let shrink = 1;
|
|
38
|
+
let basis = "0%";
|
|
39
|
+
if (parts.length <= 3 && NUMBER.test(parts[0] ?? "")) {
|
|
40
|
+
grow = Number(parts.shift());
|
|
41
|
+
if (parts.length && NUMBER.test(parts[0] ?? "")) shrink = Number(parts.shift());
|
|
42
|
+
if (parts.length === 1) basis = parts.shift() ?? "";
|
|
43
|
+
} else if (parts.length === 1) basis = parts.shift() ?? "";
|
|
44
|
+
if (parts.length === 0) {
|
|
45
|
+
if (basis === "auto" || /^(?:\d+(?:\.\d+)?|\.\d+)%$/.test(basis)) return {
|
|
46
|
+
flexGrow: grow,
|
|
47
|
+
flexShrink: shrink,
|
|
48
|
+
flexBasis: basis
|
|
49
|
+
};
|
|
50
|
+
const length = /^(\d+(?:\.\d+)?|\.\d+)(px|rem)?$/.exec(basis);
|
|
51
|
+
if (length && (length[2] || Number(length[1]) === 0)) {
|
|
52
|
+
if (length[2] !== "rem" || remBase !== void 0) return {
|
|
53
|
+
flexGrow: grow,
|
|
54
|
+
flexShrink: shrink,
|
|
55
|
+
flexBasis: Number(length[1]) * (length[2] === "rem" ? remBase : 1)
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
throw new Error(`[uds] Cannot translate Web flex ${JSON.stringify(value)} to native. Use none, auto, initial, or numeric grow/shrink with an auto, percentage, px, or fixed-rem basis.`);
|
|
60
|
+
}
|
|
61
|
+
/** RN numeric flex is not CSS numeric flex: Yoga's native defaults use shrink=0, and positive
|
|
62
|
+
* numbers use a 0pt basis. Negative flex supplies shrink while retaining auto basis.
|
|
63
|
+
* See Yoga Node::resolveFlexGrow/resolveFlexShrink/processFlexBasis with useWebDefaults=false. */
|
|
64
|
+
function nativeFlexToWeb(value) {
|
|
65
|
+
const { flexGrow, flexShrink, flexBasis } = typeof value !== "number" ? value : value > 0 ? {
|
|
66
|
+
flexGrow: value,
|
|
67
|
+
flexShrink: 0,
|
|
68
|
+
flexBasis: 0
|
|
69
|
+
} : {
|
|
70
|
+
flexGrow: 0,
|
|
71
|
+
flexShrink: -value,
|
|
72
|
+
flexBasis: "auto"
|
|
73
|
+
};
|
|
74
|
+
return `${flexGrow} ${flexShrink} ${typeof flexBasis === "number" ? `${flexBasis}px` : flexBasis}`;
|
|
75
|
+
}
|
|
76
|
+
//#endregion
|
|
77
|
+
export { isNativeFlexValue, nativeFlexToWeb, nativeFlexValue, webFlexToNative };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Config } from '../../framework/Config';
|
|
2
|
+
import type { BagSites } from './style-bag';
|
|
3
|
+
/** Translate inherited literals before merging the destination's own style overrides. Refs keep
|
|
4
|
+
* their identity: the linked-token adapter handles their values and mode overrides. */
|
|
5
|
+
export declare function translateLinkedStyleBags({ body, source, config, bags, owner, }: {
|
|
6
|
+
body: Record<string, unknown>;
|
|
7
|
+
source?: Config;
|
|
8
|
+
config: Config;
|
|
9
|
+
bags: BagSites;
|
|
10
|
+
owner?: string;
|
|
11
|
+
}): Record<string, unknown>;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { isRef, pathOf } from "../../framework/utils/refs.js";
|
|
2
|
+
import { NATIVE_CONFIG_NAME } from "../../configs/platform.js";
|
|
3
|
+
import { isNativeFlexValue, nativeFlexToWeb, webFlexToNative } from "./linked-flex-values.js";
|
|
4
|
+
import { rootFontSize } from "./token-values.js";
|
|
5
|
+
import { stylePropEntries, stylePropertyPathFor } from "../../framework/projections.js";
|
|
6
|
+
//#region src/entities/system/linked-style-values.ts
|
|
7
|
+
/** Translate inherited literals before merging the destination's own style overrides. Refs keep
|
|
8
|
+
* their identity: the linked-token adapter handles their values and mode overrides. */
|
|
9
|
+
function translateLinkedStyleBags({ body, source, config, bags, owner }) {
|
|
10
|
+
if (!source || source.name === config.name) return body;
|
|
11
|
+
if (!["system-config", "react-native-system"].includes(source.name)) return body;
|
|
12
|
+
if (!["system-config", "react-native-system"].includes(config.name)) return body;
|
|
13
|
+
const native = config.name === NATIVE_CONFIG_NAME;
|
|
14
|
+
const translate = (bag, element) => Object.fromEntries(Object.entries(bag).map(([key, raw]) => {
|
|
15
|
+
if (key.startsWith("_")) return [key, raw];
|
|
16
|
+
const propPath = stylePropertyPathFor({
|
|
17
|
+
config: source,
|
|
18
|
+
key,
|
|
19
|
+
through: [isRef(element) ? pathOf(element) : typeof element === "string" ? element : owner]
|
|
20
|
+
});
|
|
21
|
+
const properties = propPath ? source.resolve("style-property", propPath)?.toJSON().properties : void 0;
|
|
22
|
+
if (!propPath || !Array.isArray(properties) || properties.length !== 1 || isRef(raw)) return [key, raw];
|
|
23
|
+
const property = String(properties[0]).replace(/-([a-z])/g, (_, c) => c.toUpperCase());
|
|
24
|
+
if (![
|
|
25
|
+
"flex",
|
|
26
|
+
"flexGrow",
|
|
27
|
+
"flexShrink"
|
|
28
|
+
].includes(property)) return [key, raw];
|
|
29
|
+
const alias = stylePropEntries(source, propPath).find((entry) => entry.leaf === String(raw));
|
|
30
|
+
if (alias?.declarations) return [key, raw];
|
|
31
|
+
const resolved = alias ? alias.numeric && /^(?:\d+(?:\.\d+)?|\.\d+)$/.test(alias.value) ? Number(alias.value) : alias.value : raw;
|
|
32
|
+
const value = typeof resolved === "string" && resolved.startsWith("[") && resolved.endsWith("]") ? resolved.slice(1, -1) : resolved;
|
|
33
|
+
if (property === "flex") {
|
|
34
|
+
if (native && (typeof value === "string" || typeof value === "number")) return [key, webFlexToNative(value, rootFontSize(source).px)];
|
|
35
|
+
if (!native && (typeof value === "number" || isNativeFlexValue(value))) return [key, `[${nativeFlexToWeb(value)}]`];
|
|
36
|
+
} else if (typeof value === "string" || typeof value === "number") {
|
|
37
|
+
if (!/^(?:\d+(?:\.\d+)?|\.\d+)$/.test(String(value)) || !Number.isFinite(Number(value))) throw new Error(`[uds] Cannot translate ${property} ${JSON.stringify(value)}: expected a non-negative unitless number.`);
|
|
38
|
+
return [key, native ? Number(value) : `[${value}]`];
|
|
39
|
+
}
|
|
40
|
+
return [key, raw];
|
|
41
|
+
}));
|
|
42
|
+
const translated = structuredClone(body);
|
|
43
|
+
for (const site of [...bags(translated)].reverse()) site.write(translate(site.bag, site.element));
|
|
44
|
+
return translated;
|
|
45
|
+
}
|
|
46
|
+
//#endregion
|
|
47
|
+
export { translateLinkedStyleBags };
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Config } from "../../framework/Config.js";
|
|
2
2
|
import { NATIVE_CONFIG_NAME, WEB_CONFIG_NAME } from "../../configs/platform.js";
|
|
3
|
+
import { NativeFlexValue } from "./linked-flex-values.js";
|
|
3
4
|
|
|
4
5
|
//#region src/entities/system/linked-token-values.d.ts
|
|
5
6
|
type Platform = typeof WEB_CONFIG_NAME | typeof NATIVE_CONFIG_NAME;
|
|
@@ -11,24 +12,26 @@ declare function convertLinkedTokenValue({
|
|
|
11
12
|
remBase
|
|
12
13
|
}: {
|
|
13
14
|
path: string;
|
|
14
|
-
value: string | number | boolean;
|
|
15
|
+
value: string | number | boolean | NativeFlexValue;
|
|
15
16
|
sourcePlatform: string;
|
|
16
17
|
destinationPlatform: Platform; /** The pinned web source's fixed root size, only needed for web rem → native points. */
|
|
17
18
|
remBase?: number;
|
|
18
|
-
}): string | number | boolean;
|
|
19
|
+
}): string | number | boolean | NativeFlexValue;
|
|
19
20
|
/** The one adapter for base and mode values before a linked body is parsed by its destination. */
|
|
20
21
|
declare function prepareLinkedTokenBody({
|
|
21
22
|
path,
|
|
22
23
|
body,
|
|
23
24
|
source,
|
|
24
25
|
config,
|
|
25
|
-
destinationPlatform
|
|
26
|
+
destinationPlatform,
|
|
27
|
+
extend
|
|
26
28
|
}: {
|
|
27
29
|
path: string;
|
|
28
30
|
body: Record<string, unknown>;
|
|
29
31
|
source: Config; /** The config whose refs the body spells; a source's own body spells them in the source. */
|
|
30
32
|
config: Config;
|
|
31
33
|
destinationPlatform: Platform;
|
|
34
|
+
extend?: Record<string, unknown>;
|
|
32
35
|
}): Record<string, unknown>;
|
|
33
36
|
//#endregion
|
|
34
37
|
export { convertLinkedTokenValue, prepareLinkedTokenBody };
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { hasRefMarker } from "../../framework/utils/refs.js";
|
|
2
2
|
import { isCalc } from "./calc.js";
|
|
3
3
|
import { isOklchColor } from "./color.js";
|
|
4
|
-
import { literalValueOf } from "../../framework/projections.js";
|
|
5
|
-
import { rootFontSize } from "./token-values.js";
|
|
6
4
|
import "../../configs/platform.js";
|
|
5
|
+
import { isNativeFlexValue, nativeFlexToWeb, webFlexToNative } from "./linked-flex-values.js";
|
|
6
|
+
import { rootFontSize } from "./token-values.js";
|
|
7
|
+
import { literalValueOf } from "../../framework/projections.js";
|
|
7
8
|
//#region src/entities/system/linked-token-values.ts
|
|
8
9
|
/**
|
|
9
10
|
* Adapt a linked token for the system reading it. The source keeps its authored value; only the
|
|
@@ -12,10 +13,12 @@ import "../../configs/platform.js";
|
|
|
12
13
|
*/
|
|
13
14
|
const LENGTH_GROUPS = new Set([
|
|
14
15
|
"spacing",
|
|
16
|
+
"size",
|
|
15
17
|
"radius",
|
|
16
18
|
"borderRadius",
|
|
17
19
|
"iconSize",
|
|
18
20
|
"borderWidth",
|
|
21
|
+
"outlineOffset",
|
|
19
22
|
"fontSize",
|
|
20
23
|
"fontLineHeight",
|
|
21
24
|
"fontLetterSpacing"
|
|
@@ -23,7 +26,9 @@ const LENGTH_GROUPS = new Set([
|
|
|
23
26
|
const NUMBER_GROUPS = new Set([
|
|
24
27
|
"opacity",
|
|
25
28
|
"zIndex",
|
|
26
|
-
"fontWeight"
|
|
29
|
+
"fontWeight",
|
|
30
|
+
"flexGrow",
|
|
31
|
+
"flexShrink"
|
|
27
32
|
]);
|
|
28
33
|
const LENGTH = /^(-?(?:\d+(?:\.\d+)?|\.\d+))(px|rem)$/;
|
|
29
34
|
const NUMBER = /^-?(?:\d+(?:\.\d+)?|\.\d+)$/;
|
|
@@ -33,9 +38,16 @@ const OKLCH = /^oklch\(\s*(-?[\d.]+)(%?)\s+(-?[\d.]+)(%?)\s+(-?[\d.]+|none)(?:de
|
|
|
33
38
|
function convertLinkedTokenValue({ path, value, sourcePlatform, destinationPlatform, remBase }) {
|
|
34
39
|
if (sourcePlatform === destinationPlatform) return value;
|
|
35
40
|
const group = path.split("/")[0];
|
|
41
|
+
if (group === "flex") {
|
|
42
|
+
if (destinationPlatform === "react-native-system") {
|
|
43
|
+
if (isNativeFlexValue(value)) return value;
|
|
44
|
+
if (typeof value === "string" || typeof value === "number") return webFlexToNative(value, remBase);
|
|
45
|
+
} else if (sourcePlatform === "react-native-system" && (typeof value === "number" || isNativeFlexValue(value))) return nativeFlexToWeb(value);
|
|
46
|
+
}
|
|
36
47
|
if (destinationPlatform === "react-native-system") {
|
|
37
48
|
if (LENGTH_GROUPS.has(group)) {
|
|
38
49
|
if (typeof value === "number") return value;
|
|
50
|
+
if (group === "size" && typeof value === "string" && /^-?(?:\d+(?:\.\d+)?|\.\d+)%$/.test(value)) return value;
|
|
39
51
|
const match = typeof value === "string" ? LENGTH.exec(value) : null;
|
|
40
52
|
if (!match) throw unsupported("native", path, value, "a px or rem length");
|
|
41
53
|
if (match[2] === "rem" && remBase === void 0) throw new Error(`[uds] Linked native token "${path}" has value ${JSON.stringify(value)}, but its source has no fixed root font size for rem conversion.`);
|
|
@@ -60,7 +72,7 @@ function convertLinkedTokenValue({ path, value, sourcePlatform, destinationPlatf
|
|
|
60
72
|
return value;
|
|
61
73
|
}
|
|
62
74
|
/** The one adapter for base and mode values before a linked body is parsed by its destination. */
|
|
63
|
-
function prepareLinkedTokenBody({ path, body, source, config, destinationPlatform }) {
|
|
75
|
+
function prepareLinkedTokenBody({ path, body, source, config, destinationPlatform, extend }) {
|
|
64
76
|
if (source.name === destinationPlatform) return body;
|
|
65
77
|
const remBase = source.name === "system-config" ? rootFontSize(source).px : void 0;
|
|
66
78
|
const convert = (value) => {
|
|
@@ -69,7 +81,7 @@ function prepareLinkedTokenBody({ path, body, source, config, destinationPlatfor
|
|
|
69
81
|
value,
|
|
70
82
|
remBase
|
|
71
83
|
}) : value;
|
|
72
|
-
return typeof literal === "string" || typeof literal === "number" || typeof literal === "boolean" ? convertLinkedTokenValue({
|
|
84
|
+
return typeof literal === "string" || typeof literal === "number" || typeof literal === "boolean" || isNativeFlexValue(literal) ? convertLinkedTokenValue({
|
|
73
85
|
path,
|
|
74
86
|
value: literal,
|
|
75
87
|
sourcePlatform: source.name,
|
|
@@ -80,10 +92,10 @@ function prepareLinkedTokenBody({ path, body, source, config, destinationPlatfor
|
|
|
80
92
|
const overrides = body.overrides;
|
|
81
93
|
return {
|
|
82
94
|
...body,
|
|
83
|
-
value: convert(body.value),
|
|
95
|
+
value: extend && Object.hasOwn(extend, "value") ? body.value : convert(body.value),
|
|
84
96
|
...overrides && typeof overrides === "object" && !Array.isArray(overrides) ? { overrides: Object.fromEntries(Object.entries(overrides).map(([key, raw]) => [key, raw && typeof raw === "object" && !Array.isArray(raw) ? {
|
|
85
97
|
...raw,
|
|
86
|
-
value: convert(raw.value)
|
|
98
|
+
value: Object.hasOwn((extend?.overrides)?.[key] ?? {}, "value") ? raw.value : convert(raw.value)
|
|
87
99
|
} : raw])) } : {}
|
|
88
100
|
};
|
|
89
101
|
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { collectRefs, isRef, kindOf, pathOf } from "../../framework/utils/refs.js";
|
|
2
2
|
import { composedValueFormOf } from "./composed-values.js";
|
|
3
3
|
import { createSliceMemo } from "../../framework/memo.js";
|
|
4
|
+
import { tokenValueRow } from "./token-values.js";
|
|
4
5
|
import { MOTION_EASING_NAMES, bezierPoints, motionOfCssKeyword } from "./easings.js";
|
|
5
6
|
import { inlineMotions } from "./motion-variants.js";
|
|
6
7
|
import { isReducedMotion } from "./reduced-motion.js";
|
|
7
8
|
import { jsMotionPropFields } from "./Motion.js";
|
|
8
|
-
import { tokenValueRow } from "./token-values.js";
|
|
9
9
|
import { renderValue } from "./value-render.js";
|
|
10
10
|
//#region src/entities/system/motion-presets.ts
|
|
11
11
|
/** A time spelled in CSS, which `motion/react` reads in seconds. */
|
|
@@ -1415,12 +1415,14 @@ declare class Config {
|
|
|
1415
1415
|
kind,
|
|
1416
1416
|
path,
|
|
1417
1417
|
body,
|
|
1418
|
-
extend
|
|
1418
|
+
extend,
|
|
1419
|
+
source
|
|
1419
1420
|
}: {
|
|
1420
1421
|
kind: string;
|
|
1421
1422
|
path: string;
|
|
1422
1423
|
body: Record<string, unknown>;
|
|
1423
1424
|
extend: Record<string, unknown>;
|
|
1425
|
+
source?: Config;
|
|
1424
1426
|
}): Record<string, unknown>;
|
|
1425
1427
|
/** The body of the entity a re-pointed path names, or `undefined` when there is none to read. */
|
|
1426
1428
|
private redirectedBody;
|
package/dist/framework/Config.js
CHANGED
|
@@ -2074,7 +2074,8 @@ var Config = class Config {
|
|
|
2074
2074
|
kind: patch.kind,
|
|
2075
2075
|
path: pathOf(extension),
|
|
2076
2076
|
body: current.source,
|
|
2077
|
-
extend: current.overlay
|
|
2077
|
+
extend: current.overlay,
|
|
2078
|
+
source: this.configFor(extension)
|
|
2078
2079
|
}) : resolved.toJSON();
|
|
2079
2080
|
const materialized = snapshot.withChanges([itemChange(entry, patch.kind, patch.path, inherited)]);
|
|
2080
2081
|
const changed = this.applySub(materialized, patch, materialized.get(patch.kind, patch.path) ?? resolved, mode);
|
|
@@ -2164,7 +2165,8 @@ var Config = class Config {
|
|
|
2164
2165
|
kind: patch.kind,
|
|
2165
2166
|
path: pathOf(extension),
|
|
2166
2167
|
body: current.source,
|
|
2167
|
-
extend: current.overlay
|
|
2168
|
+
extend: current.overlay,
|
|
2169
|
+
source: this.configFor(extension)
|
|
2168
2170
|
}) : resolved.toJSON(), delta, isField);
|
|
2169
2171
|
const local = { ...current ? current.overlay : extension.extend };
|
|
2170
2172
|
for (const field of touched) if (Object.hasOwn(delta, field) && delta[field] === null) delete local[field];
|
|
@@ -2176,7 +2178,8 @@ var Config = class Config {
|
|
|
2176
2178
|
kind: patch.kind,
|
|
2177
2179
|
path: pathOf(extension),
|
|
2178
2180
|
body: sourceBody,
|
|
2179
|
-
extend: local
|
|
2181
|
+
extend: local,
|
|
2182
|
+
source: this.configFor(extension)
|
|
2180
2183
|
});
|
|
2181
2184
|
const createSchema = wholeBodySchema(entry, { config: this });
|
|
2182
2185
|
let merged = candidate;
|
|
@@ -2926,13 +2929,15 @@ var Config = class Config {
|
|
|
2926
2929
|
kind,
|
|
2927
2930
|
path: pathOf(extension),
|
|
2928
2931
|
body: inherited,
|
|
2929
|
-
extend: extension.extend ?? {}
|
|
2932
|
+
extend: extension.extend ?? {},
|
|
2933
|
+
source
|
|
2930
2934
|
});
|
|
2931
2935
|
return this.entityOf(kind)?.prepareLinkedBody?.({
|
|
2932
2936
|
path: pathOf(extension),
|
|
2933
2937
|
body: merged,
|
|
2934
2938
|
source,
|
|
2935
|
-
config: this
|
|
2939
|
+
config: this,
|
|
2940
|
+
extend: extension.extend ?? {}
|
|
2936
2941
|
}) ?? merged;
|
|
2937
2942
|
}
|
|
2938
2943
|
/**
|
|
@@ -2947,7 +2952,7 @@ var Config = class Config {
|
|
|
2947
2952
|
* nothing. The pin's invariants refuse the last two when they're written, and the build reports a
|
|
2948
2953
|
* missing target (`brokenLinkRedirects`).
|
|
2949
2954
|
*/
|
|
2950
|
-
laidLinkedBody({ kind, path, body, extend }) {
|
|
2955
|
+
laidLinkedBody({ kind, path, body, extend, source }) {
|
|
2951
2956
|
const { target, rest } = redirectOf(extend);
|
|
2952
2957
|
const base = target === void 0 ? body : this.redirectedBody({
|
|
2953
2958
|
kind,
|
|
@@ -2958,7 +2963,9 @@ var Config = class Config {
|
|
|
2958
2963
|
entry: this.entityOf(kind),
|
|
2959
2964
|
path,
|
|
2960
2965
|
body: base,
|
|
2961
|
-
extend: rest
|
|
2966
|
+
extend: rest,
|
|
2967
|
+
config: this,
|
|
2968
|
+
source: target === void 0 ? source : this.configFor({ __ref: target })
|
|
2962
2969
|
}), rest);
|
|
2963
2970
|
}
|
|
2964
2971
|
/** The body of the entity a re-pointed path names, or `undefined` when there is none to read. */
|
|
@@ -3892,7 +3899,8 @@ var Config = class Config {
|
|
|
3892
3899
|
kind,
|
|
3893
3900
|
path,
|
|
3894
3901
|
body: theirs,
|
|
3895
|
-
extend: laid
|
|
3902
|
+
extend: laid,
|
|
3903
|
+
source: this.sourceFor(slug)
|
|
3896
3904
|
});
|
|
3897
3905
|
return laid ? {
|
|
3898
3906
|
...theirs,
|
|
@@ -5111,7 +5119,8 @@ var Config = class Config {
|
|
|
5111
5119
|
source: slug,
|
|
5112
5120
|
owns: (name) => source.ownedKinds().includes(name)
|
|
5113
5121
|
}),
|
|
5114
|
-
extend: extension.extend
|
|
5122
|
+
extend: extension.extend,
|
|
5123
|
+
source
|
|
5115
5124
|
});
|
|
5116
5125
|
visitEntity(kind, body, false, linked);
|
|
5117
5126
|
visitBags(kind, body, linked);
|
|
@@ -6035,11 +6044,13 @@ function redirectOf(extend) {
|
|
|
6035
6044
|
}
|
|
6036
6045
|
/** A source's body as an extension reads it before its `extend` merges in: the kind's
|
|
6037
6046
|
* {@link EntityKind.rebaseLinkedBody}, where it declares one. */
|
|
6038
|
-
function rebasedLinkedBody({ entry, path, body, extend }) {
|
|
6047
|
+
function rebasedLinkedBody({ entry, path, body, extend, source, config }) {
|
|
6039
6048
|
return entry?.rebaseLinkedBody?.({
|
|
6040
6049
|
path,
|
|
6041
6050
|
body,
|
|
6042
|
-
extend
|
|
6051
|
+
extend,
|
|
6052
|
+
source,
|
|
6053
|
+
config
|
|
6043
6054
|
}) ?? body;
|
|
6044
6055
|
}
|
|
6045
6056
|
function overlayBody({ overlay, theirs }) {
|
|
@@ -6,9 +6,9 @@ import { modifierCategory } from "../entities/system/modifier-axis.js";
|
|
|
6
6
|
import { forwardedPropName, forwardsOf, rootLayerOf } from "../entities/system/element.js";
|
|
7
7
|
import { createSliceMemo } from "./memo.js";
|
|
8
8
|
import { fontFamilyStack } from "../entities/system/Font.js";
|
|
9
|
+
import { classPrefixOf, prefixed, varPrefixOf } from "../entities/system/Settings.js";
|
|
9
10
|
import { listedIn } from "./utils/enumerated.js";
|
|
10
11
|
import "../entities/system/Modifier.js";
|
|
11
|
-
import { classPrefixOf, prefixed, varPrefixOf } from "../entities/system/Settings.js";
|
|
12
12
|
import { StyleProperty, leavesOfStylePropValue, numberUnitRefusal } from "../entities/system/StyleProperty.js";
|
|
13
13
|
import { componentStates } from "./component-states.js";
|
|
14
14
|
import { isConditionalPreview, storedPreview, unconditionalPreviewProps } from "./preview-store.js";
|