@yahoo/uds-create-config 4.6.0 → 4.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/configs/CanvasConfig.d.ts +900 -80
- package/dist/configs/react-native-system.d.ts +603 -55
- package/dist/configs/system.d.ts +603 -55
- package/dist/configs/system.js +7 -1
- package/dist/entities/system/Component.d.ts +480 -39
- package/dist/entities/system/Component.js +264 -93
- package/dist/entities/system/File.d.ts +1 -1
- package/dist/entities/system/LinkedSystem.d.ts +2 -2
- package/dist/entities/system/Operation.d.ts +1 -1
- package/dist/entities/system/StyleProperty.d.ts +8 -0
- package/dist/entities/system/StyleProperty.js +12 -1
- package/dist/entities/system/Tool.d.ts +1 -1
- package/dist/entities/system/component-module.js +1 -1
- package/dist/entities/system/defineComponent.d.ts +45 -7
- package/dist/entities/system/defineComponent.js +52 -25
- package/dist/framework/Config.d.ts +2 -2
- package/dist/framework/Config.js +59 -7
- package/dist/framework/class-names.d.ts +4 -2
- package/dist/framework/class-names.js +56 -17
- package/dist/framework/defineDerivedEntity.d.ts +1 -1
- package/dist/framework/defineEntity.d.ts +2 -2
- package/dist/framework/defineSubEntity.d.ts +3 -2
- package/dist/framework/preview-store.d.ts +19 -0
- package/dist/framework/preview-store.js +18 -0
- package/dist/framework/projections.d.ts +28 -8
- package/dist/framework/projections.js +50 -16
- package/dist/framework/prop-surface.d.ts +21 -1
- package/dist/framework/prop-surface.js +99 -21
- package/dist/framework/render-spec.d.ts +103 -3
- package/dist/framework/render-spec.js +285 -37
- package/dist/framework/schema-version.d.ts +1 -1
- package/dist/framework/schema-version.js +5 -5
- package/dist/framework/utils/refs.js +10 -1
- package/dist/framework/validate-spec.d.ts +2 -0
- package/dist/framework/validate-spec.js +13 -0
- package/dist/index.d.ts +14 -11
- package/dist/index.js +6 -5
- package/dist/migrations/2.0.0/v1-artifact.d.ts +305 -29
- package/dist/migrations/20260919051027_prop_conditions_and_anatomy_positions_at_rest.d.ts +22 -0
- package/dist/migrations/20260919051027_prop_conditions_and_anatomy_positions_at_rest.js +10 -0
- package/dist/migrations/20260920004019_preview_conditions_keyed.d.ts +27 -0
- package/dist/migrations/20260920004019_preview_conditions_keyed.js +148 -0
- package/dist/migrations/20260920161309_prefixed_token_group.d.ts +12 -0
- package/dist/migrations/20260920161309_prefixed_token_group.js +10 -0
- package/dist/renderer/wrapRegistry.js +8 -2
- package/dist/renderer/wrappers/component-refs.d.ts +14 -0
- package/dist/renderer/wrappers/component-refs.js +79 -0
- package/dist/renderer/wrappers/hex-normalize.d.ts +5 -7
- package/dist/renderer/wrappers/hex-normalize.js +11 -10
- package/dist/spec/cell.d.ts +171 -0
- package/dist/spec/cell.js +361 -0
- package/dist/spec/detach.d.ts +125 -0
- package/dist/spec/detach.js +511 -0
- package/dist/spec/empty-node-slots.d.ts +11 -23
- package/dist/spec/empty-node-slots.js +12 -39
- package/dist/spec/index.d.ts +5 -3
- package/dist/spec/index.js +3 -3
- package/dist/spec/instance.d.ts +77 -0
- package/dist/spec/instance.js +80 -0
- package/dist/spec/preview-content.d.ts +95 -0
- package/dist/spec/preview-content.js +149 -0
- package/dist/spec/preview-elements.d.ts +54 -15
- package/dist/spec/preview-elements.js +109 -29
- package/dist/spec/prop-conditions.d.ts +28 -0
- package/dist/spec/prop-conditions.js +39 -0
- package/dist/spec/slot.d.ts +206 -0
- package/dist/spec/slot.js +542 -0
- package/dist/spec/visibility.d.ts +82 -0
- package/dist/spec/visibility.js +109 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +18 -2
|
@@ -38,7 +38,7 @@ const componentsByFileCache = /* @__PURE__ */ new WeakMap();
|
|
|
38
38
|
/** Documentation and examples never enter emitted component modules. */
|
|
39
39
|
function buildEntityBody(kind, body) {
|
|
40
40
|
if (kind !== "component") return body;
|
|
41
|
-
const {
|
|
41
|
+
const { preview: _preview, description: _description, ...buildBody } = body;
|
|
42
42
|
return buildBody;
|
|
43
43
|
}
|
|
44
44
|
/**
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Ref as Ref$1 } from "../../framework/utils/refs.js";
|
|
2
|
-
import { RegisteredModifiers, RegisteredStyleProps } from "../../framework/registered.js";
|
|
2
|
+
import { RegisteredModifiers, RegisteredPaths, RegisteredStyleProps } from "../../framework/registered.js";
|
|
3
3
|
import { Authored } from "../../framework/authoring.js";
|
|
4
4
|
import { StyleValue } from "./style-bag.js";
|
|
5
5
|
import { VariantValues } from "./Component.js";
|
|
@@ -73,8 +73,17 @@ type LayerPath<L extends LayerMap = LayerMap> = `${keyof L & string}/${string}`;
|
|
|
73
73
|
* from anything else: a widened union left a slot prop inferring as `unknown` where the same prop
|
|
74
74
|
* written by hand stayed a `ReactNode`.
|
|
75
75
|
*/
|
|
76
|
+
/**
|
|
77
|
+
* When a prop applies — the record a style rule's `when` holds: each key a sibling prop, each value
|
|
78
|
+
* one of that prop's values or a list of them. A prop with no condition always applies. Stored with
|
|
79
|
+
* the values as refs (`value:type/color`), which is what lets a value rename cascade into it.
|
|
80
|
+
*/
|
|
81
|
+
type PropCondition = Readonly<Record<string, ConditionValue | ConditionValue[]>>;
|
|
82
|
+
/** A value as authored, or the `value:` ref it is stored as. */
|
|
83
|
+
type ConditionValue = string | number | boolean | Ref$1;
|
|
76
84
|
interface SlotDecl {
|
|
77
85
|
type: 'slot';
|
|
86
|
+
when?: PropCondition;
|
|
78
87
|
/**
|
|
79
88
|
* What may FILL this hole, as refs. Two shapes, both in this repo:
|
|
80
89
|
*
|
|
@@ -131,6 +140,7 @@ interface ForwardDecl<Path extends string = string> {
|
|
|
131
140
|
accepts?: Ref$1 | Ref$1[];
|
|
132
141
|
text?: boolean;
|
|
133
142
|
required?: boolean;
|
|
143
|
+
when?: PropCondition;
|
|
134
144
|
}
|
|
135
145
|
/**
|
|
136
146
|
* One prop's declaration, in both the form it is AUTHORED in and the form it is STORED in.
|
|
@@ -154,20 +164,25 @@ type PropDecl<Path extends string = string> = SlotDecl | ForwardDecl<Path> | {
|
|
|
154
164
|
type: 'variant';
|
|
155
165
|
value: readonly string[] | VariantValues | Ref$1;
|
|
156
166
|
required?: boolean;
|
|
167
|
+
when?: PropCondition;
|
|
157
168
|
} | {
|
|
158
169
|
type: 'styleProperty';
|
|
159
170
|
value: Ref$1;
|
|
160
171
|
required?: boolean;
|
|
172
|
+
when?: PropCondition;
|
|
161
173
|
} | {
|
|
162
174
|
type: 'composite';
|
|
163
175
|
value: Ref$1;
|
|
164
176
|
required?: boolean;
|
|
177
|
+
when?: PropCondition;
|
|
165
178
|
} | {
|
|
166
179
|
type: 'motion';
|
|
167
180
|
required?: boolean;
|
|
181
|
+
when?: PropCondition;
|
|
168
182
|
} | {
|
|
169
183
|
type: 'string' | 'number' | 'boolean';
|
|
170
184
|
required?: boolean;
|
|
185
|
+
when?: PropCondition;
|
|
171
186
|
};
|
|
172
187
|
/**
|
|
173
188
|
* One prop as AUTHORED — a declaration, or one of the two bare forms that already say what they are:
|
|
@@ -228,6 +243,13 @@ type ValueOf<D> = D extends readonly (infer Member)[] ? Member : D extends {
|
|
|
228
243
|
__ref: `style-property:${infer Target}`;
|
|
229
244
|
};
|
|
230
245
|
} ? StylePropValue<Target> : ValueOfDeclaration<D>;
|
|
246
|
+
/**
|
|
247
|
+
* The members a ref-delegated domain offers, read off the registered paths: a variant whose domain
|
|
248
|
+
* is `icon:phosphor` takes every registered `phosphor/<Name>` as `<Name>`, so a misspelled glyph is
|
|
249
|
+
* a compile error once the system is built. A facet ref (`icon:phosphor#variants`), a kind the build
|
|
250
|
+
* did not register, or an unbuilt consumer stays `string`.
|
|
251
|
+
*/
|
|
252
|
+
type RegisteredMembers<Kind extends string, Path extends string> = Path extends `${string}#${string}` ? string : Kind extends keyof RegisteredPaths ? [Extract<RegisteredPaths[Kind], `${Path}/${string}`>] extends [never] ? string : Extract<RegisteredPaths[Kind], `${Path}/${string}`> extends `${Path}/${infer Name}` ? Name : string : string;
|
|
231
253
|
/**
|
|
232
254
|
* A style prop's values, read off the registry by the path the declaration points at. By the target
|
|
233
255
|
* and not the prop's own name, since a component may expose a property under a name of its own —
|
|
@@ -240,7 +262,9 @@ type StylePropValue<Target extends string> = Target extends keyof RegisteredStyl
|
|
|
240
262
|
type ValueOfDeclaration<D> = D extends {
|
|
241
263
|
type: 'variant';
|
|
242
264
|
value: infer V;
|
|
243
|
-
} ? V extends readonly (infer Member)[] ? Member : V extends VariantValues ? keyof V & string :
|
|
265
|
+
} ? V extends readonly (infer Member)[] ? Member : V extends VariantValues ? keyof V & string : V extends {
|
|
266
|
+
__ref: `${infer Kind}:${infer Path}`;
|
|
267
|
+
} ? RegisteredMembers<Kind, Path> : string : D extends {
|
|
244
268
|
type: 'string';
|
|
245
269
|
} ? string : D extends {
|
|
246
270
|
type: 'number';
|
|
@@ -267,7 +291,21 @@ type ValueOfDeclaration<D> = D extends {
|
|
|
267
291
|
type Declared<T> = { [K in keyof T as string extends K ? never : number extends K ? never : K]: T[K] };
|
|
268
292
|
/** What a prop map really exposes: each declaration's value type, with the `null` tombstones — the
|
|
269
293
|
* props it DROPS from what it inherits — gone from the surface entirely. */
|
|
270
|
-
type DeclaredProps<P> = { [K in keyof P as P[K] extends null ? never : K]:
|
|
294
|
+
type DeclaredProps<P, L extends LayerMap = LayerMap> = { [K in keyof P as P[K] extends null ? never : K]: RoutedValueOf<L, P[K]> };
|
|
295
|
+
/**
|
|
296
|
+
* A forward's consumer type is the far prop's: a route onto a layer component's `name` takes what
|
|
297
|
+
* that component's `name` takes, and a route onto `<input disabled>` takes a boolean. The layers
|
|
298
|
+
* are in scope here, which is what {@link ValueOf} lacks. A text forward is a string whatever it
|
|
299
|
+
* lands on. A route onto `children`, or onto a layer the map doesn't hold (an open `LayerMap`, as in
|
|
300
|
+
* a defaults bag), keeps `ValueOf`'s answer.
|
|
301
|
+
*/
|
|
302
|
+
type RoutedValueOf<L extends LayerMap, D> = D extends {
|
|
303
|
+
type: 'forward';
|
|
304
|
+
text: true;
|
|
305
|
+
} ? string : D extends {
|
|
306
|
+
type: 'forward';
|
|
307
|
+
target: `${infer Layer}/${infer Prop}`;
|
|
308
|
+
} ? Prop extends 'children' ? ReactNode : Layer extends keyof L ? Prop extends keyof ElementPropsOf<L[Layer]> ? ElementPropsOf<L[Layer]>[Prop] : unknown : unknown : ValueOf<D>;
|
|
271
309
|
/**
|
|
272
310
|
* The props the rendered ELEMENT contributes, `ref` included.
|
|
273
311
|
*
|
|
@@ -348,7 +386,7 @@ type RequiredKey<P, D> = { [K in keyof P]: P[K] extends {
|
|
|
348
386
|
* is checked against its interface by relating two generic signatures, and a name type that reads
|
|
349
387
|
* `P` is not identical on the two sides of that comparison — a name type reading only `E` is.
|
|
350
388
|
*/
|
|
351
|
-
type ConsumerDeclaredProps<P, D, E> = Without<Partial<DeclaredProps<P>>, Redefined<E>> & { [K in Exclude<RequiredKey<P, D>, Redefined<E>>]-?: K extends keyof DeclaredProps<P> ? DeclaredProps<P>[K] : never };
|
|
389
|
+
type ConsumerDeclaredProps<P, D, E, L extends LayerMap = LayerMap> = Without<Partial<DeclaredProps<P, L>>, Redefined<E>> & { [K in Exclude<RequiredKey<P, D>, Redefined<E>>]-?: K extends keyof DeclaredProps<P, L> ? DeclaredProps<P, L>[K] : never };
|
|
352
390
|
/**
|
|
353
391
|
* The keys a render extra redefines: the ones it names. An open extra (`extends Record<string,
|
|
354
392
|
* unknown>`) names nothing through its index signature, but a key it declares beside that signature
|
|
@@ -395,7 +433,7 @@ type OpenTail<L extends LayerMap> = Registered extends true ? StyleProps & Modif
|
|
|
395
433
|
*
|
|
396
434
|
* Ends in {@link OpenTail}: the system's own surface, open until the system's build has named it.
|
|
397
435
|
*/
|
|
398
|
-
type ComponentPropsOf<L extends LayerMap, P extends PropMap, D = Record<never, never>, E = Record<never, never>, F extends string = never, As = never> = ConsumerDeclaredProps<P, D, E> & Partial<E> & Redeclared<RootSurface<L, D, As>, P, E> & Redeclared<ForwardedPropsOf<L, F>, P, E> & AsPropsOf<As, P, E> & Redeclared<OpenTail<L>, P, E>;
|
|
436
|
+
type ComponentPropsOf<L extends LayerMap, P extends PropMap, D = Record<never, never>, E = Record<never, never>, F extends string = never, As = never> = ConsumerDeclaredProps<P, D, E, L> & Partial<E> & Redeclared<RootSurface<L, D, As>, P, E> & Redeclared<ForwardedPropsOf<L, F>, P, E> & AsPropsOf<As, P, E> & Redeclared<OpenTail<L>, P, E>;
|
|
399
437
|
/**
|
|
400
438
|
* `T` less the keys the component declares and the keys its render extra names — each taken out on
|
|
401
439
|
* its own, because {@link Without} leaves `T` whole when the key set is open, and an open render
|
|
@@ -502,7 +540,7 @@ type RenderArgs<L extends LayerMap, P extends PropMap> = {
|
|
|
502
540
|
* `<input ref={ref}>` in another — and which element is the render's decision.
|
|
503
541
|
*/
|
|
504
542
|
readonly ref?: Ref<any>;
|
|
505
|
-
} & DeclaredProps<P> & Record<string, unknown>;
|
|
543
|
+
} & DeclaredProps<P, L> & Record<string, unknown>;
|
|
506
544
|
interface ComponentBuilder<L extends LayerMap, P extends PropMap,
|
|
507
545
|
/** Props the RENDER takes that the config doesn't describe — React handlers, mostly (`onPress`).
|
|
508
546
|
* They're part of the component's surface but not of its data, which is why they're declared at
|
|
@@ -652,4 +690,4 @@ interface DefineComponent {
|
|
|
652
690
|
declare function definePropsFirst<const P extends PropMap<LayerPath>>(props: P & NoInfer<{ [K in keyof P]: Exact<P[K], AuthoredProp<LayerPath>> }>): ComponentBuilder<LayerMap, P>;
|
|
653
691
|
declare const defineComponent: DefineComponent;
|
|
654
692
|
//#endregion
|
|
655
|
-
export { AsInput, AuthoredComponent, AuthoredProp, ComponentBuilder, ComponentPropsOf, LayerElement, LayerMap, PhantomCallProps, PhantomReadProps, PropDecl, PropMap, RenderArgs, StyleRuleInput, defineComponent };
|
|
693
|
+
export { AsInput, AuthoredComponent, AuthoredProp, ComponentBuilder, ComponentPropsOf, LayerElement, LayerMap, PhantomCallProps, PhantomReadProps, PropCondition, PropDecl, PropMap, RegisteredMembers, RenderArgs, StyleRuleInput, defineComponent };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { isRef, kindOf, memberRef, pathOf } from "../../framework/utils/refs.js";
|
|
1
|
+
import { canonicalCondition, isRef, kindOf, memberRef, pathOf } from "../../framework/utils/refs.js";
|
|
2
|
+
import "../../framework/preview-store.js";
|
|
2
3
|
import { Component, canonicalWhen, layerRef } from "./Component.js";
|
|
3
4
|
//#region src/entities/system/defineComponent.ts
|
|
4
5
|
function build(body) {
|
|
@@ -20,10 +21,8 @@ function build(body) {
|
|
|
20
21
|
render: () => handle,
|
|
21
22
|
renderCanvas: () => handle,
|
|
22
23
|
preview: (spec) => {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
if (spec?.when?.length) patch.previewWhen = spec.when;
|
|
26
|
-
return Object.keys(patch).length === 0 ? handle : next(patch);
|
|
24
|
+
if (spec?.defaultProps === void 0 && !spec?.when?.length) return handle;
|
|
25
|
+
return next({ preview: spec });
|
|
27
26
|
},
|
|
28
27
|
toStored: () => toStored(body),
|
|
29
28
|
assignPath(path) {
|
|
@@ -45,12 +44,15 @@ function build(body) {
|
|
|
45
44
|
* only one of them runs for any given config: the build reads `.preview()` from source with ts-morph,
|
|
46
45
|
* this runs when a config is registered, and a reader can't tell which made the config it holds.
|
|
47
46
|
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
47
|
+
* A component handed as a VALUE (`icon: PlusIcon`) stores as the bare ref the registry keys it under,
|
|
48
|
+
* so the receiving component gets the component back rather than a node.
|
|
49
|
+
*
|
|
50
|
+
* What this path CANNOT do is name a component the source could. A tag is its own name and a
|
|
51
|
+
* component handle carries its adopted path, but a foreign function (a Phosphor glyph, say) is just
|
|
52
|
+
* a function at runtime — its `displayName` is a label, not an identity, and two libraries may both
|
|
53
|
+
* export `StarIcon`. Such a prop is DROPPED: an absent default renders nothing, while a guessed ref
|
|
54
|
+
* renders the wrong glyph and reads as authored. The build resolves those from the import specifier,
|
|
55
|
+
* which is why ~a third of the element-valued preview props in a real system only survive a build.
|
|
54
56
|
*/
|
|
55
57
|
function storableProps(props) {
|
|
56
58
|
if (props === void 0) return void 0;
|
|
@@ -61,9 +63,19 @@ function storableProps(props) {
|
|
|
61
63
|
}
|
|
62
64
|
return Object.keys(out).length === 0 ? void 0 : out;
|
|
63
65
|
}
|
|
64
|
-
/** A live React element, by the marker anything pretending to be one also carries.
|
|
66
|
+
/** A live React element, by the marker anything pretending to be one also carries. A `forwardRef` or
|
|
67
|
+
* `memo` component carries the marker too and is told apart by having no `props`: it is a type. */
|
|
65
68
|
function isReactElement(value) {
|
|
66
|
-
return typeof value === "object" && value !== null && "$$typeof" in value;
|
|
69
|
+
return typeof value === "object" && value !== null && "$$typeof" in value && "props" in value;
|
|
70
|
+
}
|
|
71
|
+
/** A component TYPE handed as a value: a function, or the object `forwardRef` / `memo` return. */
|
|
72
|
+
function isComponentType(value) {
|
|
73
|
+
if (typeof value === "function") return true;
|
|
74
|
+
return typeof value === "object" && value !== null && "$$typeof" in value && !("props" in value);
|
|
75
|
+
}
|
|
76
|
+
/** A component handed as a value, as the ref that names it — `undefined` for one this path can't name. */
|
|
77
|
+
function storableComponentRef(value) {
|
|
78
|
+
return isComponentElement(value) && value.path ? Component.ref(value.path) : void 0;
|
|
67
79
|
}
|
|
68
80
|
const FRAGMENT = Symbol.for("react.fragment");
|
|
69
81
|
/**
|
|
@@ -74,12 +86,20 @@ function storableElementName(type) {
|
|
|
74
86
|
if (typeof type === "string") return type;
|
|
75
87
|
if (isComponentElement(type) && type.path) return Component.ref(type.path);
|
|
76
88
|
}
|
|
77
|
-
/** The scalar half of an element's props
|
|
89
|
+
/** The scalar half of an element's props, plus a component handed as one — what
|
|
90
|
+
* `PreviewElement.props` may hold. */
|
|
78
91
|
function storableAttributes(props) {
|
|
79
92
|
const out = {};
|
|
80
93
|
for (const [key, value] of Object.entries(props)) {
|
|
81
94
|
if (key === "children") continue;
|
|
82
|
-
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean")
|
|
95
|
+
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
96
|
+
out[key] = value;
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
if (isComponentType(value)) {
|
|
100
|
+
const ref = storableComponentRef(value);
|
|
101
|
+
if (ref) out[key] = ref;
|
|
102
|
+
}
|
|
83
103
|
}
|
|
84
104
|
return out;
|
|
85
105
|
}
|
|
@@ -118,13 +138,14 @@ function storableElement(value) {
|
|
|
118
138
|
/**
|
|
119
139
|
* One preview-prop value as the config stores it, or `undefined` to drop the prop.
|
|
120
140
|
*
|
|
121
|
-
* Mirrors the arms the build reads from source: a literal, an element, a fragment
|
|
122
|
-
* under one prop), an array, and a nested record.
|
|
141
|
+
* Mirrors the arms the build reads from source: a literal, a component, an element, a fragment
|
|
142
|
+
* (several elements under one prop), an array, and a nested record.
|
|
123
143
|
*/
|
|
124
144
|
function storableValue(value) {
|
|
125
145
|
if (value === null) return null;
|
|
126
146
|
const type = typeof value;
|
|
127
147
|
if (type === "string" || type === "number" || type === "boolean") return value;
|
|
148
|
+
if (isComponentType(value)) return storableComponentRef(value);
|
|
128
149
|
if (type !== "object") return void 0;
|
|
129
150
|
if (isReactElement(value)) {
|
|
130
151
|
if (value.type === FRAGMENT) {
|
|
@@ -299,15 +320,21 @@ function storedForwards(forwards, layers) {
|
|
|
299
320
|
/** The authored body as the entity's stored shape — which differs in exactly four places. */
|
|
300
321
|
function toStored(body) {
|
|
301
322
|
const stored = { ...body };
|
|
302
|
-
if (body.
|
|
303
|
-
const
|
|
304
|
-
|
|
305
|
-
|
|
323
|
+
if (body.preview !== void 0) {
|
|
324
|
+
const authored = body.preview;
|
|
325
|
+
const keyed = {};
|
|
326
|
+
const defaults = authored.defaultProps !== void 0 ? storableProps(authored.defaultProps) : void 0;
|
|
327
|
+
if (defaults !== void 0) keyed["*"] = {
|
|
328
|
+
when: null,
|
|
329
|
+
props: defaults
|
|
330
|
+
};
|
|
331
|
+
for (const { when, props } of authored.when ?? []) keyed[canonicalCondition(when)] = {
|
|
332
|
+
when,
|
|
333
|
+
props: storableProps(props) ?? {}
|
|
334
|
+
};
|
|
335
|
+
if (Object.keys(keyed).length === 0) delete stored.preview;
|
|
336
|
+
else stored.preview = keyed;
|
|
306
337
|
}
|
|
307
|
-
if (Array.isArray(body.previewWhen)) stored.previewWhen = body.previewWhen.map(({ when, props }) => ({
|
|
308
|
-
when,
|
|
309
|
-
props: storableProps(props) ?? {}
|
|
310
|
-
}));
|
|
311
338
|
if (body.props && typeof body.props === "object") {
|
|
312
339
|
const props = {};
|
|
313
340
|
for (const [name, decl] of Object.entries(body.props)) props[name] = storedProp(decl, body.layers);
|
|
@@ -8,12 +8,12 @@ import { RefGraph, TraverseOptions } from "./ref-graph.js";
|
|
|
8
8
|
import { FieldsSchema } from "./utils/field-schema.js";
|
|
9
9
|
import { SubEntityClass } from "./defineSubEntity.js";
|
|
10
10
|
import { LocalOverlay, SourceAnswer, SourceOverlay, SourceResolver, SourceState } from "./sources.js";
|
|
11
|
+
import { EntityKind } from "./registry.js";
|
|
11
12
|
import { AuthoredEntry } from "./utils/group.js";
|
|
12
13
|
import { EntityClass } from "./defineEntity.js";
|
|
13
14
|
import { BreakPlan, LinkPlan, SourceRowState, UnlinkPlan } from "../entities/system/link-plan.js";
|
|
14
15
|
import { InlineOptions } from "./inline-sources.js";
|
|
15
16
|
import { Snapshot } from "./snapshot.js";
|
|
16
|
-
import { EntityKind } from "./registry.js";
|
|
17
17
|
|
|
18
18
|
//#region src/framework/Config.d.ts
|
|
19
19
|
/**
|
|
@@ -72,7 +72,7 @@ interface RecordedSource {
|
|
|
72
72
|
* The dense-counter `2` a short-lived scheme stamped before the chain existed reads as the mint
|
|
73
73
|
* that replaced it (see `detectedWireVersion`).
|
|
74
74
|
*/
|
|
75
|
-
declare const SERIALIZED_CONFIG_VERSION =
|
|
75
|
+
declare const SERIALIZED_CONFIG_VERSION = 20260920161309;
|
|
76
76
|
interface SerializedConfig {
|
|
77
77
|
/** See {@link SERIALIZED_CONFIG_VERSION}. Always written; a stored artifact may lack it. */
|
|
78
78
|
readonly version: number;
|
package/dist/framework/Config.js
CHANGED
|
@@ -367,31 +367,82 @@ function dropOrphans(sub, def, target, namespace) {
|
|
|
367
367
|
}
|
|
368
368
|
/**
|
|
369
369
|
* Follow a member's name where the item holds it as a value keyed by that member's owner — a
|
|
370
|
-
* Component's `defaultProps
|
|
370
|
+
* Component's `defaultProps`, and the `props` of every `preview` entry, which are all
|
|
371
|
+
* `{ [prop]: value }`.
|
|
371
372
|
*
|
|
372
373
|
* The third rename axis, after refs and record keys, and the only one where the name appears as
|
|
373
374
|
* neither. `to: undefined` is the delete case: a default naming a value that no longer exists isn't
|
|
374
375
|
* a dangling pointer anyone sees, it's a component that quietly reports a default it hasn't got.
|
|
376
|
+
* A field is a `/` path, and a `*` segment stands for every key at that level, as in
|
|
377
|
+
* {@link rekeyAt}.
|
|
375
378
|
*/
|
|
376
379
|
function renameNamedValues(sub, def, owner, from, to) {
|
|
377
380
|
if (!sub?.namedValuesIn?.length || owner === void 0) return def;
|
|
378
381
|
let out = def;
|
|
379
382
|
for (const field of sub.namedValuesIn) {
|
|
380
|
-
const
|
|
381
|
-
if (
|
|
383
|
+
const next = renameValueAt(out, field.split("/"), owner, from, to);
|
|
384
|
+
if (isPlainObject(next)) out = next;
|
|
385
|
+
}
|
|
386
|
+
return out;
|
|
387
|
+
}
|
|
388
|
+
/** Rewrite the value under `owner` in the record `path` addresses, from `from` to `to` (or drop it). */
|
|
389
|
+
function renameValueAt(node, path, owner, from, to) {
|
|
390
|
+
if (!isPlainObject(node)) return node;
|
|
391
|
+
const [head, ...rest] = path;
|
|
392
|
+
if (head === void 0) return node;
|
|
393
|
+
if (rest.length === 0) {
|
|
394
|
+
const record = node[head];
|
|
395
|
+
if (!isPlainObject(record) || record[owner] !== from) return node;
|
|
382
396
|
const next = { ...record };
|
|
383
397
|
if (to === void 0) delete next[owner];
|
|
384
398
|
else next[owner] = to;
|
|
385
|
-
|
|
399
|
+
return {
|
|
400
|
+
...node,
|
|
401
|
+
[head]: next
|
|
402
|
+
};
|
|
403
|
+
}
|
|
404
|
+
if (head === "*") {
|
|
405
|
+
let changed = false;
|
|
406
|
+
const next = {};
|
|
407
|
+
for (const [key, value] of Object.entries(node)) {
|
|
408
|
+
const updated = renameValueAt(value, rest, owner, from, to);
|
|
409
|
+
next[key] = updated;
|
|
410
|
+
if (updated !== value) changed = true;
|
|
411
|
+
}
|
|
412
|
+
return changed ? next : node;
|
|
413
|
+
}
|
|
414
|
+
const updated = renameValueAt(node[head], rest, owner, from, to);
|
|
415
|
+
return updated === node[head] ? node : {
|
|
416
|
+
...node,
|
|
417
|
+
[head]: updated
|
|
418
|
+
};
|
|
419
|
+
}
|
|
420
|
+
/**
|
|
421
|
+
* Drop the members a name removal left declaring nothing. A `keyedByNameIn` path through another
|
|
422
|
+
* collection (`preview/*\/props`) removes a key from each of that collection's members, and a member
|
|
423
|
+
* that held only that key now says nothing; the collection's own `vacant` decides, the same test a
|
|
424
|
+
* `sub-update` asks before bringing one into being.
|
|
425
|
+
*/
|
|
426
|
+
function dropVacated(entry, sub, def) {
|
|
427
|
+
if (!sub?.keyedByNameIn?.length) return def;
|
|
428
|
+
let out = def;
|
|
429
|
+
for (const path of sub.keyedByNameIn) {
|
|
430
|
+
const [field, wildcard] = path.split("/");
|
|
431
|
+
if (wildcard !== "*") continue;
|
|
432
|
+
const collectionSub = entry.subEntities[field];
|
|
433
|
+
const collection = out[field];
|
|
434
|
+
if (!collectionSub?.vacant || !isPlainObject(collection)) continue;
|
|
435
|
+
const kept = Object.fromEntries(Object.entries(collection).filter(([, member]) => collectionSub.vacant?.(member) !== true));
|
|
436
|
+
if (Object.keys(kept).length !== Object.keys(collection).length) out = {
|
|
386
437
|
...out,
|
|
387
|
-
[field]:
|
|
438
|
+
[field]: kept
|
|
388
439
|
};
|
|
389
440
|
}
|
|
390
441
|
return out;
|
|
391
442
|
}
|
|
392
443
|
/**
|
|
393
444
|
* Follow a member's name where the item holds it as a record key — a component's `defaultProps` and
|
|
394
|
-
* `
|
|
445
|
+
* every `preview` entry's `props` are `{ [prop]: value }`.
|
|
395
446
|
*
|
|
396
447
|
* The other half of {@link renameNamedValues}, which reaches the same two fields from the value side.
|
|
397
448
|
* `to: undefined` is the delete case, and it matters as much as the rename: a default left under the
|
|
@@ -1669,6 +1720,7 @@ var Config = class Config {
|
|
|
1669
1720
|
def = store(def, collection);
|
|
1670
1721
|
def = renameNamedValues(sub, def, patch.owner, patch.key, void 0);
|
|
1671
1722
|
def = renameKeyedByName(sub, def, patch.key, void 0);
|
|
1723
|
+
def = dropVacated(entry, sub, def);
|
|
1672
1724
|
def = dropOrphans(sub, def, `${leafOf(patch.field).replace(/s$/, "")}:${refPathOf(patch, patch.key)}`, sub?.namespaces ? {
|
|
1673
1725
|
kind: sub.namespaces,
|
|
1674
1726
|
path: patch.key
|
|
@@ -4739,7 +4791,7 @@ var Config = class Config {
|
|
|
4739
4791
|
* links from the provided sources. A declared `linkedKind` with no provided source throws. */
|
|
4740
4792
|
hydrateFrom(stored, options) {
|
|
4741
4793
|
const claimed = schemaVersionOf(stored);
|
|
4742
|
-
if (claimed >
|
|
4794
|
+
if (claimed > 20260920161309) throw new SchemaVersionTooNew(claimed);
|
|
4743
4795
|
const wire = upgradeSerializedConfig(stored);
|
|
4744
4796
|
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, or port the repo once with \`uds migrate\`.`);
|
|
4745
4797
|
const leftover = wire.options;
|
|
@@ -150,8 +150,10 @@ declare function componentPropClasses(config: Config, path: string, state?: Reco
|
|
|
150
150
|
* travels to it as one, whether or not the element declares it: a composite (`variant` on a
|
|
151
151
|
* `Text`-backed layer, which the receiver resolves to its own class), the receiver's own variant or
|
|
152
152
|
* scalar prop (`size: 'sm'` on an Icon layer), or an attribute of a plain element (`as: 'div'`,
|
|
153
|
-
* `type: 'button'`, `aria-hidden`)
|
|
154
|
-
*
|
|
153
|
+
* `type: 'button'`, `aria-hidden`), or a value the rule hands a receiver's forward or slot
|
|
154
|
+
* (`children: 'AI'` on a badge layer, `icon: 'XIcon'` on a button layer), which the emitted module
|
|
155
|
+
* routes the same way. A style property under another name and motion stay out, since the
|
|
156
|
+
* stylesheet and the motion classes already carry them.
|
|
155
157
|
*
|
|
156
158
|
* Forwarding rather than resolving is what makes a layer's styling live-editable at all: a class only
|
|
157
159
|
* exists once a build has emitted the stylesheet, so an edit that makes a NEW style rule paints
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { isRef, kindOf, pathOf, refLeaf } from "./utils/refs.js";
|
|
2
|
-
import { rootLayerOf } from "../entities/system/element.js";
|
|
1
|
+
import { isRef, kindOf, memberOf, pathOf, refLeaf } from "./utils/refs.js";
|
|
2
|
+
import { forwardsOf, rootLayerOf } from "../entities/system/element.js";
|
|
3
3
|
import { classPrefixOf } from "../entities/system/Settings.js";
|
|
4
4
|
import { createSliceMemo } from "./memo.js";
|
|
5
|
+
import { storedPreview } from "./preview-store.js";
|
|
5
6
|
import { authoredValue, className, negatedCssValue, renderStyleValue, resolveComponentProps, stylePropLeafForToken, stylePropValueLeaves, stylePropertyPathFor } from "./projections.js";
|
|
6
7
|
import { ruleApplies } from "./layer-styles.js";
|
|
7
8
|
//#region src/framework/class-names.ts
|
|
@@ -295,38 +296,74 @@ function componentMotionClasses(config, path) {
|
|
|
295
296
|
function componentPropClasses(config, path, state = {}) {
|
|
296
297
|
const declared = compositePropsOf(config, path);
|
|
297
298
|
if (!declared) return {};
|
|
298
|
-
const {
|
|
299
|
+
const { groups, defaultProps } = declared;
|
|
299
300
|
if (groups.length === 0) return {};
|
|
300
301
|
const resolved = {
|
|
301
302
|
...defaultProps,
|
|
302
303
|
...state
|
|
303
304
|
};
|
|
304
|
-
const
|
|
305
|
-
for (const [prop, group] of groups) {
|
|
305
|
+
const out = {};
|
|
306
|
+
for (const [prop, group, layer] of groups) {
|
|
306
307
|
const value = resolved[prop];
|
|
307
308
|
const target = memberNamed(group, value);
|
|
308
309
|
if (target === void 0) continue;
|
|
309
310
|
if (!config.resolve("composite", target)) continue;
|
|
311
|
+
const classes = out[layer] ?? [];
|
|
310
312
|
classes.push(className(config, "composite", target));
|
|
313
|
+
out[layer] = classes;
|
|
311
314
|
}
|
|
312
|
-
return
|
|
315
|
+
return out;
|
|
313
316
|
}
|
|
314
317
|
/** The part of {@link componentPropClasses} that depends on the component alone, once per slice:
|
|
315
318
|
* an expansion asks it for every instance it paints. `undefined` for a path no component answers. */
|
|
316
|
-
function compositePropsOf(config, path) {
|
|
319
|
+
function compositePropsOf(config, path, seen = /* @__PURE__ */ new Set()) {
|
|
317
320
|
const cache = compositePropsCache(config);
|
|
318
321
|
if (cache.has(path)) return cache.get(path);
|
|
319
322
|
const component = config.resolve("component", path);
|
|
320
323
|
let declared;
|
|
321
324
|
if (component) {
|
|
322
|
-
const
|
|
325
|
+
const body = component.toJSON();
|
|
326
|
+
const { layers = {}, props = {} } = body;
|
|
323
327
|
const [root] = rootLayerOf(layers);
|
|
324
328
|
const groups = [];
|
|
329
|
+
let defaultProps = {};
|
|
325
330
|
for (const [prop, decl] of Object.entries(props)) {
|
|
326
331
|
if (decl?.type !== "composite") continue;
|
|
327
332
|
const group = isRef(decl.value) ? decl.value.__ref : void 0;
|
|
328
|
-
if (group) groups.push([
|
|
333
|
+
if (group) groups.push([
|
|
334
|
+
prop,
|
|
335
|
+
group,
|
|
336
|
+
root
|
|
337
|
+
]);
|
|
329
338
|
}
|
|
339
|
+
const inner = new Set([...seen, path]);
|
|
340
|
+
for (const [layer, entry] of Object.entries(forwardsOf(body))) {
|
|
341
|
+
const element = layers[layer];
|
|
342
|
+
if (!isRef(element) || kindOf(element.__ref) !== "component") continue;
|
|
343
|
+
const from = pathOf(element.__ref);
|
|
344
|
+
if (inner.has(from)) continue;
|
|
345
|
+
const exposed = compositePropsOf(config, from, inner);
|
|
346
|
+
if (!exposed) continue;
|
|
347
|
+
const names = Array.isArray(entry) ? new Set(entry.flatMap((r) => isRef(r) ? [memberOf(r.__ref)?.split("/").pop()] : [])) : void 0;
|
|
348
|
+
for (const [prop, group, at] of exposed.groups) {
|
|
349
|
+
if (at !== exposed.root) continue;
|
|
350
|
+
if (prop in props) continue;
|
|
351
|
+
if (entry !== "*" && !names?.has(prop)) continue;
|
|
352
|
+
groups.push([
|
|
353
|
+
prop,
|
|
354
|
+
group,
|
|
355
|
+
layer
|
|
356
|
+
]);
|
|
357
|
+
}
|
|
358
|
+
defaultProps = {
|
|
359
|
+
...exposed.defaultProps,
|
|
360
|
+
...defaultProps
|
|
361
|
+
};
|
|
362
|
+
}
|
|
363
|
+
defaultProps = {
|
|
364
|
+
...defaultProps,
|
|
365
|
+
...body.defaultProps
|
|
366
|
+
};
|
|
330
367
|
declared = {
|
|
331
368
|
root,
|
|
332
369
|
groups,
|
|
@@ -349,8 +386,10 @@ const compositePropsCache = createSliceMemo({
|
|
|
349
386
|
* travels to it as one, whether or not the element declares it: a composite (`variant` on a
|
|
350
387
|
* `Text`-backed layer, which the receiver resolves to its own class), the receiver's own variant or
|
|
351
388
|
* scalar prop (`size: 'sm'` on an Icon layer), or an attribute of a plain element (`as: 'div'`,
|
|
352
|
-
* `type: 'button'`, `aria-hidden`)
|
|
353
|
-
*
|
|
389
|
+
* `type: 'button'`, `aria-hidden`), or a value the rule hands a receiver's forward or slot
|
|
390
|
+
* (`children: 'AI'` on a badge layer, `icon: 'XIcon'` on a button layer), which the emitted module
|
|
391
|
+
* routes the same way. A style property under another name and motion stay out, since the
|
|
392
|
+
* stylesheet and the motion classes already carry them.
|
|
354
393
|
*
|
|
355
394
|
* Forwarding rather than resolving is what makes a layer's styling live-editable at all: a class only
|
|
356
395
|
* exists once a build has emitted the stylesheet, so an edit that makes a NEW style rule paints
|
|
@@ -377,7 +416,7 @@ function layerRoutedProps(config, path, state = {}) {
|
|
|
377
416
|
}) ?? prop;
|
|
378
417
|
if (config.resolve("style-property", styleKey)) continue;
|
|
379
418
|
const decl = declared[prop];
|
|
380
|
-
if (decl?.type === "styleProperty" || decl?.type === "
|
|
419
|
+
if (decl?.type === "styleProperty" || decl?.type === "motion") continue;
|
|
381
420
|
out[layer] ??= {};
|
|
382
421
|
out[layer][prop] = authoredValue(config, prop, value);
|
|
383
422
|
}
|
|
@@ -598,7 +637,7 @@ function modifierUtilitiesUsed(config) {
|
|
|
598
637
|
/**
|
|
599
638
|
* Every style bag a COMPONENT states it wants, each with the definitions its keys resolve against.
|
|
600
639
|
*
|
|
601
|
-
* Not uniform, which is the whole reason it travels with the bag. `defaultProps` and `
|
|
640
|
+
* Not uniform, which is the whole reason it travels with the bag. `defaultProps` and a preview entry's `props`
|
|
602
641
|
* are the component's OWN props, and nothing else has a claim. A style rule's per-layer bag and an
|
|
603
642
|
* anatomy node's props are set on a LAYER'S ELEMENT, so that element answers too — after the
|
|
604
643
|
* component itself, whose own declaration of a name is what that name means throughout its
|
|
@@ -606,14 +645,14 @@ function modifierUtilitiesUsed(config) {
|
|
|
606
645
|
*/
|
|
607
646
|
function componentBags(entity) {
|
|
608
647
|
const { path } = entity;
|
|
609
|
-
const { defaultProps,
|
|
648
|
+
const { defaultProps, styles, anatomy, layers } = entity.toJSON();
|
|
610
649
|
const bags = [{
|
|
611
650
|
bag: defaultProps,
|
|
612
651
|
through: [path]
|
|
613
|
-
}, {
|
|
614
|
-
bag:
|
|
652
|
+
}, ...Object.values(storedPreview(entity.toJSON())).map((entry) => ({
|
|
653
|
+
bag: entry?.props,
|
|
615
654
|
through: [path]
|
|
616
|
-
}];
|
|
655
|
+
}))];
|
|
617
656
|
for (const rule of Object.values(styles ?? {})) for (const [layer, bag] of Object.entries(rule?.layers ?? {})) bags.push({
|
|
618
657
|
bag,
|
|
619
658
|
through: [path, componentElementOf(layers?.[layer])]
|
|
@@ -2,8 +2,8 @@ import { Entity } from "./Entity.js";
|
|
|
2
2
|
import { Ref } from "./utils/refs.js";
|
|
3
3
|
import { TraverseOptions } from "./ref-graph.js";
|
|
4
4
|
import { FieldsSchema } from "./utils/field-schema.js";
|
|
5
|
-
import { Config } from "./Config.js";
|
|
6
5
|
import { ComputedInput, EntityKind } from "./registry.js";
|
|
6
|
+
import { Config } from "./Config.js";
|
|
7
7
|
import { z } from "zod";
|
|
8
8
|
|
|
9
9
|
//#region src/framework/defineDerivedEntity.d.ts
|
|
@@ -4,11 +4,11 @@ import { TraverseOptions } from "./ref-graph.js";
|
|
|
4
4
|
import { CreateInput, FieldsSchema } from "./utils/field-schema.js";
|
|
5
5
|
import { FieldsCtx, UserSchemas } from "./schemas.js";
|
|
6
6
|
import { SubEntityClass } from "./defineSubEntity.js";
|
|
7
|
-
import { PathOf } from "./registered.js";
|
|
8
7
|
import { BulkOverlayWrite, BulkQuery, SourceOverlay, SourceResolutionSchemas } from "./sources.js";
|
|
8
|
+
import { ComputedFields, EntityKind, Linkable } from "./registry.js";
|
|
9
|
+
import { PathOf } from "./registered.js";
|
|
9
10
|
import { GroupBody } from "./utils/group.js";
|
|
10
11
|
import { Config, ListOptions, TreeNode } from "./Config.js";
|
|
11
|
-
import { ComputedFields, EntityKind, Linkable } from "./registry.js";
|
|
12
12
|
import { z } from "zod";
|
|
13
13
|
|
|
14
14
|
//#region src/framework/defineEntity.d.ts
|
|
@@ -71,7 +71,8 @@ type SubEntityClass<F extends z.ZodTypeAny = z.ZodTypeAny> = CollectionSchema<F>
|
|
|
71
71
|
readonly subEntities?: Readonly<Record<string, SubEntityClass>>;
|
|
72
72
|
/**
|
|
73
73
|
* Fields of the OWNING ENTITY that hold this member's NAME as a VALUE, keyed by the member's
|
|
74
|
-
* owner — a component's `defaultProps` and `
|
|
74
|
+
* owner — a component's `defaultProps` and each `preview` entry's `props` are `{ [prop]: value }`.
|
|
75
|
+
* A field is a `/` path; `*` stands for every key at that level.
|
|
75
76
|
*
|
|
76
77
|
* The mirror of {@link namesMembersOf}, which covers a name held as a record KEY. Neither is
|
|
77
78
|
* reachable by a ref rewrite, and both leave the same kind of wreckage: a default naming a
|
|
@@ -81,7 +82,7 @@ type SubEntityClass<F extends z.ZodTypeAny = z.ZodTypeAny> = CollectionSchema<F>
|
|
|
81
82
|
readonly namedValuesIn?: readonly string[];
|
|
82
83
|
/**
|
|
83
84
|
* Fields of the OWNING ENTITY that are KEYED by this member's name — a component's
|
|
84
|
-
* `defaultProps` and `
|
|
85
|
+
* `defaultProps` and each `preview` entry's `props` are `{ [prop]: value }`, so the prop's name is the key
|
|
85
86
|
* rather than the value.
|
|
86
87
|
*
|
|
87
88
|
* The other half of {@link namedValuesIn}, which covers the same two fields from the value side
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
//#region src/framework/preview-store.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* A component's stored `preview` collection, read off a body with nothing else in scope: the render
|
|
4
|
+
* spec builder and the class scanner read it without reaching the projections module.
|
|
5
|
+
*/
|
|
6
|
+
/** One `preview` entry as stored: the condition it holds under, `null` for the `*` entry every
|
|
7
|
+
* cell reads, and the props the matching cells preview with. */
|
|
8
|
+
interface StoredPreviewCondition {
|
|
9
|
+
readonly when: Record<string, unknown> | null;
|
|
10
|
+
readonly props: Record<string, unknown>;
|
|
11
|
+
}
|
|
12
|
+
/** The `*` entry the `preview` collection stores — see `preview({ defaultProps })`. */
|
|
13
|
+
declare const UNCONDITIONAL_PREVIEW_KEY = "*";
|
|
14
|
+
/** Every `preview` entry a body stores, keyed as stored. Empty for a body that stores none. */
|
|
15
|
+
declare function storedPreview(body: unknown): Readonly<Record<string, StoredPreviewCondition>>;
|
|
16
|
+
/** The props the `*` entry previews with, `undefined` when the body stores no such entry. */
|
|
17
|
+
declare function unconditionalPreviewProps(body: unknown): Record<string, unknown> | undefined;
|
|
18
|
+
//#endregion
|
|
19
|
+
export { StoredPreviewCondition, UNCONDITIONAL_PREVIEW_KEY, storedPreview, unconditionalPreviewProps };
|