@yahoo/uds-create-config 5.53.1 → 5.55.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/capture/node-ops.js +1 -1
- package/dist/configs/system.js +2 -0
- package/dist/entities/canvas/node-gestures.js +1 -1
- package/dist/entities/canvas/node-patches.js +1 -1
- package/dist/entities/system/Component.d.ts +5 -2
- package/dist/entities/system/Component.js +121 -8
- package/dist/entities/system/LinkedSystem.js +2 -2
- package/dist/entities/system/Operation.js +1 -1
- package/dist/entities/system/StyleProperty.js +5 -0
- package/dist/entities/system/component-forwards.js +1 -1
- package/dist/entities/system/component-source-fields.js +1 -1
- package/dist/entities/system/component-style-set.js +1 -1
- package/dist/entities/system/conditional-defaults.d.ts +45 -0
- package/dist/entities/system/conditional-defaults.js +142 -0
- package/dist/entities/system/copy-plan.js +1 -1
- package/dist/entities/system/css-motion-reach.js +1 -1
- package/dist/entities/system/defineComponent.d.ts +11 -2
- package/dist/entities/system/defineComponent.js +3 -0
- package/dist/entities/system/drawn-motion.d.ts +2 -1
- package/dist/entities/system/drawn-motion.js +23 -16
- package/dist/entities/system/link-plan.js +1 -1
- package/dist/entities/system/motion-convert.js +1 -1
- package/dist/entities/system/motion-variants.js +2 -2
- package/dist/framework/Config.d.ts +1 -1
- package/dist/framework/Config.js +13 -4
- package/dist/framework/class-names.d.ts +14 -9
- package/dist/framework/class-names.js +37 -22
- package/dist/framework/default-conditions.d.ts +26 -0
- package/dist/framework/default-conditions.js +35 -0
- package/dist/framework/defineEntity.js +1 -1
- package/dist/framework/inline-sources.js +1 -1
- package/dist/framework/layer-styles.js +7 -2
- package/dist/framework/module-views.d.ts +9 -10
- package/dist/framework/plan.js +1 -1
- package/dist/framework/projections.d.ts +36 -4
- package/dist/framework/projections.js +97 -24
- package/dist/framework/render-spec.js +10 -2
- package/dist/framework/schema-version.d.ts +1 -1
- package/dist/framework/schema-version.js +5 -5
- package/dist/framework/schemas.js +2 -2
- package/dist/framework/source-integrity.js +1 -1
- package/dist/index.d.ts +6 -3
- package/dist/index.js +7 -4
- package/dist/migrations/20261023152030_conditional_defaults.d.ts +6 -0
- package/dist/migrations/20261023152030_conditional_defaults.js +8 -0
- package/dist/spec/bake.js +14 -6
- package/dist/spec/cell.d.ts +2 -1
- package/dist/spec/cell.js +14 -6
- package/dist/spec/detach.js +5 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { isRef, pathOf, ref, routedSource, sourceOf } from "../../framework/utils/refs.js";
|
|
2
2
|
import { moduleViewOf } from "../../framework/module-views.js";
|
|
3
|
-
import {
|
|
3
|
+
import { linkedDraw } from "../../framework/projections.js";
|
|
4
4
|
//#region src/entities/system/drawn-motion.ts
|
|
5
5
|
/**
|
|
6
6
|
* The name the preset a `motion` value names plays under in `config`: a path of `config`'s own, or a
|
|
@@ -32,36 +32,43 @@ function drawnMotionBody(config, name) {
|
|
|
32
32
|
return (sourceOf(name) === void 0 ? at.resolve("motion", name) : at.resolveRef(ref("motion", name)))?.toJSON();
|
|
33
33
|
}
|
|
34
34
|
function linkedName({ config, slug, path }) {
|
|
35
|
-
|
|
35
|
+
const drawn = linkedDraw({
|
|
36
36
|
config,
|
|
37
37
|
slug,
|
|
38
38
|
kind: "motion",
|
|
39
39
|
path
|
|
40
|
-
})
|
|
40
|
+
});
|
|
41
|
+
return "row" in drawn ? drawn.row : `${drawn.path}@${drawn.slug}`;
|
|
41
42
|
}
|
|
42
43
|
const linkedPresets = /* @__PURE__ */ new WeakMap();
|
|
43
44
|
/**
|
|
44
45
|
* Every linked preset `config` plays under its pin's name: each preset a reached source holds that
|
|
45
|
-
* this config's refs reach, unless the link draws it with a row of this config's own
|
|
46
|
+
* this config's refs reach, unless the link draws it with a row of this config's own, and the preset
|
|
47
|
+
* of a nearer link's that a routed pin draws with in its place ({@link linkedDraw}).
|
|
46
48
|
*/
|
|
47
49
|
function linkedMotionPresets(config) {
|
|
48
50
|
const hit = linkedPresets.get(config);
|
|
49
51
|
if (hit) return hit;
|
|
50
52
|
const out = [];
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
if (!
|
|
54
|
-
for (const target of config.sourceClosure(
|
|
55
|
-
const
|
|
56
|
-
if (linkedLocalRow({
|
|
53
|
+
const seen = /* @__PURE__ */ new Set();
|
|
54
|
+
for (const reached of config.reachedSlugs()) {
|
|
55
|
+
if (!config.sourceFor(reached)) continue;
|
|
56
|
+
for (const target of config.sourceClosure(reached, "motion")) {
|
|
57
|
+
const drawn = linkedDraw({
|
|
57
58
|
config,
|
|
58
|
-
slug,
|
|
59
|
+
slug: reached,
|
|
59
60
|
kind: "motion",
|
|
60
|
-
path
|
|
61
|
-
})
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
61
|
+
path: pathOf(target)
|
|
62
|
+
});
|
|
63
|
+
if ("row" in drawn) continue;
|
|
64
|
+
const { slug, path } = drawn;
|
|
65
|
+
const name = `${path}@${slug}`;
|
|
66
|
+
const source = config.sourceFor(slug);
|
|
67
|
+
const body = source?.resolve("motion", path)?.toJSON();
|
|
68
|
+
if (!source || !body || seen.has(name)) continue;
|
|
69
|
+
seen.add(name);
|
|
70
|
+
out.push({
|
|
71
|
+
name,
|
|
65
72
|
slug,
|
|
66
73
|
path,
|
|
67
74
|
body,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { isConfigRejection, rejectData } from "../../framework/rejection.js";
|
|
2
1
|
import { collectRefs, isMintedRow, ref, sourceOf, splitRef } from "../../framework/utils/refs.js";
|
|
2
|
+
import { isConfigRejection, rejectData } from "../../framework/rejection.js";
|
|
3
3
|
import { blockedBy } from "../../framework/plan.js";
|
|
4
4
|
import { excludedCondition } from "../../framework/source-integrity.js";
|
|
5
5
|
import { PIN_KIND, covers, declarationOf, entriesFor, excludePaths, excludes, includePaths, narrowDeclaration } from "./link-declaration.js";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { isRef } from "../../framework/utils/refs.js";
|
|
2
1
|
import { isPlainObject } from "../../framework/utils/field-path.js";
|
|
2
|
+
import { isRef } from "../../framework/utils/refs.js";
|
|
3
3
|
import { MOTION_EASING_NAMES, bezierPoints, motionOfCssKeyword } from "./easings.js";
|
|
4
4
|
import { cssEasing } from "./css-timing.js";
|
|
5
5
|
import { JS_ONLY_FIELDS } from "./Motion.js";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { reject } from "../../framework/rejection.js";
|
|
2
|
-
import { isRef, kindOf, pathOf } from "../../framework/utils/refs.js";
|
|
3
1
|
import { isPlainObject } from "../../framework/utils/field-path.js";
|
|
2
|
+
import { isRef, kindOf, pathOf } from "../../framework/utils/refs.js";
|
|
3
|
+
import { reject } from "../../framework/rejection.js";
|
|
4
4
|
import { createSliceMemo } from "../../framework/memo.js";
|
|
5
5
|
import { drawnMotionBody, drawnMotionName } from "./drawn-motion.js";
|
|
6
6
|
import { webMotionBody } from "./motion-types.js";
|
|
@@ -73,7 +73,7 @@ interface RecordedSource {
|
|
|
73
73
|
* The dense-counter `2` a short-lived scheme stamped before the chain existed reads as the mint
|
|
74
74
|
* that replaced it (see `detectedWireVersion`).
|
|
75
75
|
*/
|
|
76
|
-
declare const SERIALIZED_CONFIG_VERSION =
|
|
76
|
+
declare const SERIALIZED_CONFIG_VERSION = 20261023152030;
|
|
77
77
|
interface SerializedConfig {
|
|
78
78
|
/** See {@link SERIALIZED_CONFIG_VERSION}. Always written; a stored artifact may lack it. */
|
|
79
79
|
readonly version: number;
|
package/dist/framework/Config.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
+
import { applyPathDelta, isPlainObject, namedFields, pathSegments, sectionDelta, touchedFields } from "./utils/field-path.js";
|
|
2
|
+
import { MINTED, collectRefs, entityPathProblem, entityRefOf, isExtendedRef, isMintedRow, isRef, kindOf, memberOf, memberRef, pathOf, qualifyRefs, ref, rewriteRefNamespace, rewriteRefSource, rewriteRefs, routedSource, singletonRef, sourceHops, sourceOf, splitRef } from "./utils/refs.js";
|
|
1
3
|
import "./config-operation-kind.js";
|
|
2
4
|
import { ConfigFormatError, ConfigRejection, isConfigRejection, issuePath, refusalIssues, reject, rejectData, rejectInvalid, rejectReferrers } from "./rejection.js";
|
|
3
|
-
import { MINTED, collectRefs, entityPathProblem, entityRefOf, isExtendedRef, isMintedRow, isRef, kindOf, memberOf, memberRef, pathOf, qualifyRefs, ref, rewriteRefNamespace, rewriteRefSource, rewriteRefs, routedSource, singletonRef, sourceHops, sourceOf, splitRef } from "./utils/refs.js";
|
|
4
5
|
import { describePatch } from "./plan.js";
|
|
5
|
-
import { applyPathDelta, isPlainObject, namedFields, pathSegments, sectionDelta, touchedFields } from "./utils/field-path.js";
|
|
6
6
|
import { METADATA_KEYS, declaredField } from "./utils/field-schema.js";
|
|
7
7
|
import { dataSchema, resolveInputSchema } from "./schemas.js";
|
|
8
8
|
import { isComposedValue } from "../entities/system/composed-values.js";
|
|
@@ -438,13 +438,18 @@ function storeCollection(def, patch, next) {
|
|
|
438
438
|
}
|
|
439
439
|
/** Drop every member of a declared `orphans` collection that still points at `target` — what a
|
|
440
440
|
* delete leaves behind when a sibling member exists only to describe the one removed. */
|
|
441
|
-
function dropOrphans(sub, def, target, namespace) {
|
|
441
|
+
function dropOrphans(sub, def, target, namespace, keyed) {
|
|
442
442
|
if (!sub?.orphans?.length) return def;
|
|
443
443
|
let out = def;
|
|
444
444
|
for (const field of sub.orphans) {
|
|
445
445
|
const collection = out[field];
|
|
446
446
|
if (!isPlainObject(collection)) continue;
|
|
447
|
+
const keyedFields = Object.entries(keyed?.subEntities[field]?.namesMembersOf ?? {}).filter(([, names]) => names === keyed?.collection).map(([record]) => record);
|
|
447
448
|
const kept = Object.fromEntries(Object.entries(collection).filter(([, member]) => {
|
|
449
|
+
if (keyed && isPlainObject(member) && keyedFields.some((record) => {
|
|
450
|
+
const names = member[record];
|
|
451
|
+
return isPlainObject(names) && Object.hasOwn(names, keyed.key);
|
|
452
|
+
})) return false;
|
|
448
453
|
const refs = collectRefs(member);
|
|
449
454
|
if (refs.includes(target)) return false;
|
|
450
455
|
if (!namespace) return true;
|
|
@@ -2401,6 +2406,10 @@ var Config = class Config {
|
|
|
2401
2406
|
def = dropOrphans(sub, def, `${leafOf(patch.field).replace(/s$/, "")}:${refPathOf(patch, patch.key)}`, sub?.namespaces ? {
|
|
2402
2407
|
kind: sub.namespaces,
|
|
2403
2408
|
path: patch.key
|
|
2409
|
+
} : void 0, patch.owner === void 0 ? {
|
|
2410
|
+
collection: patch.field,
|
|
2411
|
+
key: patch.key,
|
|
2412
|
+
subEntities: entry.subEntities
|
|
2404
2413
|
} : void 0);
|
|
2405
2414
|
}
|
|
2406
2415
|
const next = snapshot.withChanges([itemChange(entry, patch.kind, patch.path, def)]);
|
|
@@ -6044,7 +6053,7 @@ var Config = class Config {
|
|
|
6044
6053
|
* links from the provided sources. A declared `linkedKind` with no provided source throws. */
|
|
6045
6054
|
hydrateFrom(stored, options) {
|
|
6046
6055
|
const claimed = schemaVersionOf(stored);
|
|
6047
|
-
if (claimed >
|
|
6056
|
+
if (claimed > 20261023152030) throw new SchemaVersionTooNew(claimed);
|
|
6048
6057
|
const wire = upgradeSerializedConfig(stored);
|
|
6049
6058
|
if (!Array.isArray(wire.ownedKinds) || typeof wire.items !== "object" || wire.items === null) throw new ConfigFormatError(`Config "${stored.name ?? "system-config"}" cannot be hydrated: this is not a serialized config-v2 config (no "ownedKinds"/"items"). A pre-cutover build artifact converts through the registered cutover migration — import the config type's module (e.g. \`configs/system\`) before hydrating.`);
|
|
6050
6059
|
const leftover = wire.options;
|
|
@@ -217,30 +217,35 @@ declare function componentPropComposites(config: Config, path: string, state?: R
|
|
|
217
217
|
*/
|
|
218
218
|
declare function inlineRuleComposites(config: Config, element: unknown, authored: Record<string, unknown>): Record<string, unknown>;
|
|
219
219
|
/**
|
|
220
|
-
* The composites a rule's bag names that are drawn with another config's
|
|
220
|
+
* The composites a rule's bag names that are drawn with another config's entity, taken out of the bag.
|
|
221
221
|
*
|
|
222
222
|
* A linked component's rule is read against its source, and a `hybrid` link draws a composite it
|
|
223
|
-
* names with the consuming config's row of that name
|
|
224
|
-
* member path in
|
|
225
|
-
*
|
|
226
|
-
* the
|
|
223
|
+
* names with the consuming config's row of that name, or a routed pin with a nearer link's. `drawnWith`
|
|
224
|
+
* answers which entity that is, as a config and a member path in it, and the member's styles are
|
|
225
|
+
* that entity's, so they have to be rendered against that config while the rest of the rule is
|
|
226
|
+
* rendered against the source. Each config's members come back as one bag. The marker is the
|
|
227
|
+
* source's, which the component's own `_on<Group><Member>` rules query. `bag` is what's left for
|
|
227
228
|
* {@link inlineRuleComposites}.
|
|
228
229
|
*/
|
|
229
230
|
declare function splitRuleComposites({
|
|
230
231
|
config,
|
|
231
232
|
element,
|
|
232
233
|
bag: authored,
|
|
233
|
-
local,
|
|
234
234
|
drawnWith
|
|
235
235
|
}: {
|
|
236
236
|
readonly config: Config;
|
|
237
237
|
readonly element: unknown;
|
|
238
238
|
readonly bag: Record<string, unknown>;
|
|
239
|
-
readonly
|
|
240
|
-
|
|
239
|
+
readonly drawnWith: (member: string) => {
|
|
240
|
+
readonly config: Config;
|
|
241
|
+
readonly path: string;
|
|
242
|
+
} | undefined;
|
|
241
243
|
}): {
|
|
242
244
|
readonly bag: Record<string, unknown>;
|
|
243
|
-
readonly drawn:
|
|
245
|
+
readonly drawn: readonly {
|
|
246
|
+
readonly config: Config;
|
|
247
|
+
readonly bag: Record<string, unknown>;
|
|
248
|
+
}[];
|
|
244
249
|
};
|
|
245
250
|
/**
|
|
246
251
|
* A composite member's styles as a bag, with the composite's marker
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { isRef, kindOf, memberOf, pathOf, refLeaf, refOfKey, sourceHops, sourceOf } from "./utils/refs.js";
|
|
2
|
+
import { defaultsFor } from "./default-conditions.js";
|
|
2
3
|
import { forwardsOf, rootLayerOf } from "../entities/system/element.js";
|
|
3
4
|
import { createSliceMemo } from "./memo.js";
|
|
4
5
|
import { moduleViewOf } from "./module-views.js";
|
|
@@ -568,40 +569,43 @@ function inlineRuleComposites(config, element, authored) {
|
|
|
568
569
|
return mergeStyleBags(inlined, rest);
|
|
569
570
|
}
|
|
570
571
|
/**
|
|
571
|
-
* The composites a rule's bag names that are drawn with another config's
|
|
572
|
+
* The composites a rule's bag names that are drawn with another config's entity, taken out of the bag.
|
|
572
573
|
*
|
|
573
574
|
* A linked component's rule is read against its source, and a `hybrid` link draws a composite it
|
|
574
|
-
* names with the consuming config's row of that name
|
|
575
|
-
* member path in
|
|
576
|
-
*
|
|
577
|
-
* the
|
|
575
|
+
* names with the consuming config's row of that name, or a routed pin with a nearer link's. `drawnWith`
|
|
576
|
+
* answers which entity that is, as a config and a member path in it, and the member's styles are
|
|
577
|
+
* that entity's, so they have to be rendered against that config while the rest of the rule is
|
|
578
|
+
* rendered against the source. Each config's members come back as one bag. The marker is the
|
|
579
|
+
* source's, which the component's own `_on<Group><Member>` rules query. `bag` is what's left for
|
|
578
580
|
* {@link inlineRuleComposites}.
|
|
579
581
|
*/
|
|
580
|
-
function splitRuleComposites({ config, element, bag: authored,
|
|
582
|
+
function splitRuleComposites({ config, element, bag: authored, drawnWith }) {
|
|
581
583
|
const bag = resolveAppliedComposites(config, authored);
|
|
582
|
-
|
|
584
|
+
const drawn = /* @__PURE__ */ new Map();
|
|
583
585
|
const taken = /* @__PURE__ */ new Set();
|
|
584
586
|
for (const [key, member] of ruleCompositeMembers({
|
|
585
587
|
config,
|
|
586
588
|
element,
|
|
587
589
|
bag
|
|
588
590
|
})) {
|
|
589
|
-
const
|
|
590
|
-
if (
|
|
591
|
-
drawn
|
|
592
|
-
|
|
593
|
-
path,
|
|
591
|
+
const at = drawnWith(member);
|
|
592
|
+
if (!at?.config.resolve("composite", at.path)) continue;
|
|
593
|
+
drawn.set(at.config, mergeStyleBags(drawn.get(at.config) ?? {}, compositeMemberBag({
|
|
594
|
+
...at,
|
|
594
595
|
markedIn: config
|
|
595
|
-
}));
|
|
596
|
+
})));
|
|
596
597
|
taken.add(key);
|
|
597
598
|
}
|
|
598
|
-
if (
|
|
599
|
+
if (taken.size === 0) return {
|
|
599
600
|
bag,
|
|
600
|
-
drawn
|
|
601
|
+
drawn: []
|
|
601
602
|
};
|
|
602
603
|
return {
|
|
603
604
|
bag: Object.fromEntries(Object.entries(bag).filter(([key]) => !taken.has(key))),
|
|
604
|
-
drawn
|
|
605
|
+
drawn: [...drawn].map(([from, styles]) => ({
|
|
606
|
+
config: from,
|
|
607
|
+
bag: styles
|
|
608
|
+
}))
|
|
605
609
|
};
|
|
606
610
|
}
|
|
607
611
|
/** The composite member each key of a rule's bag names, by key: a key `element` declares as a
|
|
@@ -655,9 +659,13 @@ function compositeMemberBag({ config, path, markedIn = config }) {
|
|
|
655
659
|
function layerRoutedProps(config, path, state = {}) {
|
|
656
660
|
const component = config.resolve("component", path);
|
|
657
661
|
if (!component) return {};
|
|
658
|
-
const
|
|
662
|
+
const body = component.toJSON();
|
|
663
|
+
const { layers = {}, styles = {} } = body;
|
|
659
664
|
const resolved = {
|
|
660
|
-
...
|
|
665
|
+
...defaultsFor({
|
|
666
|
+
body,
|
|
667
|
+
given: state
|
|
668
|
+
}),
|
|
661
669
|
...state
|
|
662
670
|
};
|
|
663
671
|
const out = {};
|
|
@@ -704,9 +712,13 @@ function layerRoutedProps(config, path, state = {}) {
|
|
|
704
712
|
* that layer through motion's factory and hands it the preset's props.
|
|
705
713
|
*/
|
|
706
714
|
function layerJsMotionPresets(config, path, state = {}) {
|
|
707
|
-
const
|
|
715
|
+
const body = config.resolve("component", path)?.toJSON();
|
|
716
|
+
const { styles = {} } = body ?? {};
|
|
708
717
|
const resolved = {
|
|
709
|
-
...
|
|
718
|
+
...defaultsFor({
|
|
719
|
+
body,
|
|
720
|
+
given: state
|
|
721
|
+
}),
|
|
710
722
|
...state
|
|
711
723
|
};
|
|
712
724
|
const rules = Object.entries(styles);
|
|
@@ -743,9 +755,12 @@ function layerJsMotionPresets(config, path, state = {}) {
|
|
|
743
755
|
* here, and one expanded from the config alone needs this.
|
|
744
756
|
*/
|
|
745
757
|
function styleRuleMotionClasses(config, path, state = {}) {
|
|
746
|
-
const
|
|
758
|
+
const body = config.resolve("component", path)?.toJSON();
|
|
747
759
|
const resolved = {
|
|
748
|
-
...
|
|
760
|
+
...defaultsFor({
|
|
761
|
+
body,
|
|
762
|
+
given: state
|
|
763
|
+
}),
|
|
749
764
|
...state
|
|
750
765
|
};
|
|
751
766
|
const out = {};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
//#region src/framework/default-conditions.d.ts
|
|
2
|
+
/** One `defaultPropsWhen` entry as stored: the condition, and the defaults that hold under it. */
|
|
3
|
+
interface StoredDefaultCondition {
|
|
4
|
+
readonly when: Record<string, unknown>;
|
|
5
|
+
readonly props: Record<string, unknown>;
|
|
6
|
+
}
|
|
7
|
+
/** Every `defaultPropsWhen` entry a body stores, keyed and ordered as stored. Empty for none. */
|
|
8
|
+
declare function storedDefaultConditions(body: unknown): Readonly<Record<string, StoredDefaultCondition>>;
|
|
9
|
+
/**
|
|
10
|
+
* The defaults that apply to a component given the props it was handed: `defaultProps`, with every
|
|
11
|
+
* `defaultPropsWhen` entry whose condition holds laid over it in stored order, so a later entry wins
|
|
12
|
+
* on the prop it sets.
|
|
13
|
+
*
|
|
14
|
+
* A condition reads a prop's given value, else its unconditional default. A prop that is itself
|
|
15
|
+
* conditionally defaulted can't be a condition (the schema refuses it), so one pass decides.
|
|
16
|
+
* Values compare by leaf, so a stored value ref and the bare name a call site writes match.
|
|
17
|
+
*/
|
|
18
|
+
declare function defaultsFor({
|
|
19
|
+
body,
|
|
20
|
+
given
|
|
21
|
+
}: {
|
|
22
|
+
body: unknown;
|
|
23
|
+
given: Readonly<Record<string, unknown>>;
|
|
24
|
+
}): Record<string, unknown>;
|
|
25
|
+
//#endregion
|
|
26
|
+
export { StoredDefaultCondition, defaultsFor, storedDefaultConditions };
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { isPlainObject } from "./utils/field-path.js";
|
|
2
|
+
import { refLeaf } from "./utils/refs.js";
|
|
3
|
+
//#region src/framework/default-conditions.ts
|
|
4
|
+
/**
|
|
5
|
+
* A component's stored `defaultPropsWhen` collection, read off a body with nothing else in scope:
|
|
6
|
+
* the defaults that hold only under a condition on the component's other props, beside the
|
|
7
|
+
* unconditional `defaultProps` they override.
|
|
8
|
+
*/
|
|
9
|
+
/** Every `defaultPropsWhen` entry a body stores, keyed and ordered as stored. Empty for none. */
|
|
10
|
+
function storedDefaultConditions(body) {
|
|
11
|
+
const stored = body?.defaultPropsWhen;
|
|
12
|
+
return isPlainObject(stored) ? stored : {};
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* The defaults that apply to a component given the props it was handed: `defaultProps`, with every
|
|
16
|
+
* `defaultPropsWhen` entry whose condition holds laid over it in stored order, so a later entry wins
|
|
17
|
+
* on the prop it sets.
|
|
18
|
+
*
|
|
19
|
+
* A condition reads a prop's given value, else its unconditional default. A prop that is itself
|
|
20
|
+
* conditionally defaulted can't be a condition (the schema refuses it), so one pass decides.
|
|
21
|
+
* Values compare by leaf, so a stored value ref and the bare name a call site writes match.
|
|
22
|
+
*/
|
|
23
|
+
function defaultsFor({ body, given }) {
|
|
24
|
+
const defaults = body?.defaultProps ?? {};
|
|
25
|
+
const conditions = Object.values(storedDefaultConditions(body));
|
|
26
|
+
if (conditions.length === 0) return defaults;
|
|
27
|
+
const out = { ...defaults };
|
|
28
|
+
for (const { when, props } of conditions) if (Object.entries(when).every(([prop, value]) => {
|
|
29
|
+
const current = given[prop] !== void 0 ? given[prop] : defaults[prop];
|
|
30
|
+
return String(refLeaf(current)) === String(refLeaf(value));
|
|
31
|
+
})) Object.assign(out, props);
|
|
32
|
+
return out;
|
|
33
|
+
}
|
|
34
|
+
//#endregion
|
|
35
|
+
export { defaultsFor, storedDefaultConditions };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { CONFIG_OPERATION_KIND } from "./config-operation-kind.js";
|
|
2
1
|
import { isRef, kindOf, pathOf, ref, refSchema, refTo, sourceOf } from "./utils/refs.js";
|
|
2
|
+
import { CONFIG_OPERATION_KIND } from "./config-operation-kind.js";
|
|
3
3
|
import { resolveFields } from "./schemas.js";
|
|
4
4
|
import { buildKind } from "./registry.js";
|
|
5
5
|
import { brandGroup } from "./utils/group.js";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { rejectData } from "./rejection.js";
|
|
2
1
|
import { MINTED, collectRefs, entityRefOf, isRef, kindOf, pathOf, ref, rewriteRefs, sourceOf } from "./utils/refs.js";
|
|
2
|
+
import { rejectData } from "./rejection.js";
|
|
3
3
|
import { kindBorrowable } from "./registry.js";
|
|
4
4
|
//#region src/framework/inline-sources.ts
|
|
5
5
|
/**
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { isRef, refLeaf } from "./utils/refs.js";
|
|
2
|
+
import { defaultsFor } from "./default-conditions.js";
|
|
2
3
|
import { authoredBag } from "./projections.js";
|
|
3
4
|
import { resolveAppliedComposites } from "../entities/system/applied-composites.js";
|
|
4
5
|
//#region src/framework/layer-styles.ts
|
|
@@ -83,9 +84,13 @@ function ruleSpecificity(when) {
|
|
|
83
84
|
* "styled with nothing".
|
|
84
85
|
*/
|
|
85
86
|
function layerStyles(config, path, props = {}, options = {}) {
|
|
86
|
-
const
|
|
87
|
+
const body = config.resolve("component", path)?.toJSON();
|
|
88
|
+
const { styles = {} } = body ?? {};
|
|
87
89
|
const state = {
|
|
88
|
-
...
|
|
90
|
+
...defaultsFor({
|
|
91
|
+
body,
|
|
92
|
+
given: props
|
|
93
|
+
}),
|
|
89
94
|
...props
|
|
90
95
|
};
|
|
91
96
|
const forced = (options.forced ?? []).map((name) => name.replace(/^_/, ""));
|
|
@@ -1,15 +1,14 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { Config } from "./Config.js";
|
|
2
|
+
|
|
3
|
+
//#region src/framework/module-views.d.ts
|
|
2
4
|
/** The config a linked component's module view is built for, and the pin its owner is reached
|
|
3
5
|
* through. */
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
6
|
+
interface ModuleViewLink {
|
|
7
|
+
readonly consumer: Config;
|
|
8
|
+
readonly slug: string;
|
|
7
9
|
}
|
|
8
|
-
/** Records that `view` is an owner's config as `link.consumer` converts its files. */
|
|
9
|
-
export declare function registerModuleView({ view, link, }: {
|
|
10
|
-
readonly view: Config;
|
|
11
|
-
readonly link: ModuleViewLink;
|
|
12
|
-
}): void;
|
|
13
10
|
/** The consumer and pin `config` was built for, when it is a module view. A name it reads is its
|
|
14
11
|
* owner's, and what that names is drawn as the consumer draws it. */
|
|
15
|
-
|
|
12
|
+
declare function moduleViewOf(config: Config): ModuleViewLink | undefined;
|
|
13
|
+
//#endregion
|
|
14
|
+
export { ModuleViewLink, moduleViewOf };
|
package/dist/framework/plan.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { isConfigRejection } from "./rejection.js";
|
|
2
1
|
import { splitRef } from "./utils/refs.js";
|
|
2
|
+
import { isConfigRejection } from "./rejection.js";
|
|
3
3
|
//#region src/framework/plan.ts
|
|
4
4
|
/**
|
|
5
5
|
* One line for a patch, read off the patch itself: its kind, what it did, and where. The payload
|
|
@@ -34,12 +34,15 @@ type VarNaming = string | ((tokenPath: string) => string);
|
|
|
34
34
|
* is declared under the pin's namespace ({@link sourceVarPrefix}), since this config has no name of
|
|
35
35
|
* its own for it. A relative own name (`cssVariable: 'spacing'`) is placed under a prefix, and the
|
|
36
36
|
* pin's is the one that keeps it apart from ours.
|
|
37
|
+
*
|
|
38
|
+
* Which of these a token is comes from {@link linkedDraw}: a token drawn with a row of this config's
|
|
39
|
+
* is named by that row, and one a routed pin draws with an entity of a nearer link's is named as that
|
|
40
|
+
* link names it.
|
|
37
41
|
*/
|
|
38
42
|
declare function linkedVarNaming(config: Config, slug: string): (tokenPath: string) => string;
|
|
39
43
|
/**
|
|
40
|
-
* The path of this config's row that what `slug` brings at `kind:path` is drawn with
|
|
41
|
-
*
|
|
42
|
-
* ({@link Config.drawsWithLocalRow}). `undefined` when the source's own entity is drawn.
|
|
44
|
+
* The path of this config's row that what `slug` brings at `kind:path` is drawn with
|
|
45
|
+
* ({@link linkedDraw}). `undefined` when a source's entity is drawn.
|
|
43
46
|
*/
|
|
44
47
|
declare function linkedLocalRow({
|
|
45
48
|
config,
|
|
@@ -52,6 +55,35 @@ declare function linkedLocalRow({
|
|
|
52
55
|
readonly kind: string;
|
|
53
56
|
readonly path: string;
|
|
54
57
|
}): string | undefined;
|
|
58
|
+
/** What a linked value is drawn with: a row of this config's own, or a source's entity, named by the
|
|
59
|
+
* pin it's reached through. */
|
|
60
|
+
type LinkedDraw = {
|
|
61
|
+
readonly row: string;
|
|
62
|
+
} | {
|
|
63
|
+
readonly slug: string;
|
|
64
|
+
readonly path: string;
|
|
65
|
+
};
|
|
66
|
+
/**
|
|
67
|
+
* What `slug` brings at `kind:path` is drawn with, from this config.
|
|
68
|
+
*
|
|
69
|
+
* Through a pin of this config's own, it's this config's row pointing at it ({@link heldLinked}), or
|
|
70
|
+
* its row at the path when the pin draws with one ({@link Config.drawsWithLocalRow}), and otherwise
|
|
71
|
+
* the source's entity. A routed slug (`bridge~yos`) is resolved one link at a time: `bridge` is asked
|
|
72
|
+
* what it draws `yos`'s entity with, and a row of `bridge`'s own is then what this config draws
|
|
73
|
+
* through `bridge`. So an app linking the Bridge draws a component the Bridge takes through a `hybrid`
|
|
74
|
+
* link with the Bridge's values, as the Bridge does.
|
|
75
|
+
*/
|
|
76
|
+
declare function linkedDraw({
|
|
77
|
+
config,
|
|
78
|
+
slug,
|
|
79
|
+
kind,
|
|
80
|
+
path
|
|
81
|
+
}: {
|
|
82
|
+
readonly config: Config;
|
|
83
|
+
readonly slug: string;
|
|
84
|
+
readonly kind: string;
|
|
85
|
+
readonly path: string;
|
|
86
|
+
}): LinkedDraw;
|
|
55
87
|
/**
|
|
56
88
|
* Their path → the path of this config's row pointing at it, for every row of `kind` that is a
|
|
57
89
|
* pointer into `slug`: the rows a `link` mints and any written by hand. A pointer with a local delta
|
|
@@ -839,4 +871,4 @@ declare function propValueFromAxis(config: Config, path: string, prop: string, v
|
|
|
839
871
|
/** The `value` a string, number or boolean prop declares as its default, per prop. */
|
|
840
872
|
declare function declaredPropDefaults(props: Record<string, unknown> | undefined): Record<string, unknown>;
|
|
841
873
|
//#endregion
|
|
842
|
-
export { IconTool, IndexedPreviewCondition, PreviewMatrix, PropDeclaration, StyleDeclarationGroup, StylePropEntry, StylePropertyItem, VarNaming, authoredBag, authoredValue, bodyNumberLeaves, bodyNumberUnit, className, cssPropValue, cssVar, cssVarRef, declarationKeyName, declaredPropDefaults, declaredPropRouting, declaresCssVariable, glyphComponentOf, glyphLibrariesOf, glyphPropsOf, heldLinked, holdingPreviewConditions, iconToolAxisOptions, iconToolFor, iconToolOf, iconToolsOf, isCustomPropertyKey, keyedPreviewConditions, linkedLocalRow, linkedVarNaming, literalValueOf, memberFromLeaf, memberLeaves, nameStyleNumbers, negatedCssValue, opacityPercentage, pinStyleNumbers, previewConditionalProps, previewConditions, previewDefaults, previewMatrix, propOwner, propValueDomain, propValueFromAxis, refListOf, renderInterpolated, renderStyleValue, resolveComponentProps, resolveFieldValue, resolveTokenValue, resolveTokenValueUnder, rewriteStyleNumbers, routedBag, sourceVarPrefix, styleAliasesOf, styleDeclarationGroups, styleDeclarations, styleNumberAsPainted, styleNumberReadingChanges, stylePropEntries, stylePropLeafForToken, stylePropNegates, stylePropNumberCss, stylePropNumberLeaf, stylePropNumberLeaves, stylePropNumberName, stylePropNumberNamedLeaves, stylePropNumberUnit, stylePropNumberUnitRefusal, stylePropTokenGroup, stylePropTokenPath, stylePropTokenValues, stylePropValueFromLeaf, stylePropValueLeaves, stylePropValues, stylePropertiesWriting, stylePropertyAccepts, stylePropertyFor, stylePropertyPathFor, tokenReference, validateComponentProps };
|
|
874
|
+
export { IconTool, IndexedPreviewCondition, LinkedDraw, PreviewMatrix, PropDeclaration, StyleDeclarationGroup, StylePropEntry, StylePropertyItem, VarNaming, authoredBag, authoredValue, bodyNumberLeaves, bodyNumberUnit, className, cssPropValue, cssVar, cssVarRef, declarationKeyName, declaredPropDefaults, declaredPropRouting, declaresCssVariable, glyphComponentOf, glyphLibrariesOf, glyphPropsOf, heldLinked, holdingPreviewConditions, iconToolAxisOptions, iconToolFor, iconToolOf, iconToolsOf, isCustomPropertyKey, keyedPreviewConditions, linkedDraw, linkedLocalRow, linkedVarNaming, literalValueOf, memberFromLeaf, memberLeaves, nameStyleNumbers, negatedCssValue, opacityPercentage, pinStyleNumbers, previewConditionalProps, previewConditions, previewDefaults, previewMatrix, propOwner, propValueDomain, propValueFromAxis, refListOf, renderInterpolated, renderStyleValue, resolveComponentProps, resolveFieldValue, resolveTokenValue, resolveTokenValueUnder, rewriteStyleNumbers, routedBag, sourceVarPrefix, styleAliasesOf, styleDeclarationGroups, styleDeclarations, styleNumberAsPainted, styleNumberReadingChanges, stylePropEntries, stylePropLeafForToken, stylePropNegates, stylePropNumberCss, stylePropNumberLeaf, stylePropNumberLeaves, stylePropNumberName, stylePropNumberNamedLeaves, stylePropNumberUnit, stylePropNumberUnitRefusal, stylePropTokenGroup, stylePropTokenPath, stylePropTokenValues, stylePropValueFromLeaf, stylePropValueLeaves, stylePropValues, stylePropertiesWriting, stylePropertyAccepts, stylePropertyFor, stylePropertyPathFor, tokenReference, validateComponentProps };
|