@yahoo/uds-create-config 3.0.10 → 3.2.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 +66 -3
- package/dist/configs/react-native-system.d.ts +44 -2
- package/dist/configs/react-native-system.js +2 -0
- package/dist/configs/system.d.ts +74 -7
- package/dist/configs/system.js +2 -0
- package/dist/entities/system/Component.d.ts +40 -2
- package/dist/entities/system/Component.js +40 -2
- package/dist/entities/system/StyleProperty.d.ts +13 -1
- package/dist/entities/system/StyleProperty.js +8 -1
- package/dist/entities/system/defineComponent.d.ts +101 -6
- package/dist/entities/system/defineComponent.js +12 -1
- package/dist/framework/Config.d.ts +1 -1
- package/dist/framework/Config.js +1 -1
- package/dist/framework/registered.d.ts +9 -1
- package/dist/framework/schema-version.d.ts +1 -1
- package/dist/framework/schema-version.js +5 -5
- package/dist/framework/utils/refs.d.ts +9 -2
- package/dist/index.d.ts +3 -3
- package/dist/index.js +2 -2
- package/dist/migrations/2.0.0/v1-artifact.d.ts +38 -4
- package/dist/migrations/20260914155048_component_create_blank_op.d.ts +13 -0
- package/dist/migrations/20260914155048_component_create_blank_op.js +8 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
|
@@ -382,7 +382,7 @@ declare const Node: EntityClass<z.ZodObject<{
|
|
|
382
382
|
}, z.core.$strip>>;
|
|
383
383
|
export: z.ZodOptional<z.ZodString>;
|
|
384
384
|
}, z.core.$strict>;
|
|
385
|
-
readonly description: "Create a component at a new qualified `path`. When its complete body is known, include all layers, anatomy, props, defaults, and styles in this one operation. `data.layers` maps each stable layer name to the element it renders and must include `root` — a tag for a primitive (`{ \"layers\": { \"root\": \"div\" } }`), and for anything built on top, a ref to a primitive (`{ \"root\": { \"__ref\": \"component:Box\" }, \"label\": { \"__ref\": \"component:Text\" } }`), which is what lets the layer take that primitive's style props. A primitive exposes style props as `{ \"type\": \"styleProperty\", \"value\": { \"__ref\": \"style-property:bg\" } }` and declares `children: { \"type\": \"slot\", \"text\": true }` when it holds content — without the slot, nothing nested inside it renders. A composed component exposes a layer's props at its own top level through `forwards`, keyed by layer: `{ \"forwards\": { \"root\": \"*\" } }` passes every prop the root's element takes (so `<Button width=\"full\">` reaches the root's `width`), and a list of member refs (`[{ \"__ref\": \"component:Box#props/width\" }]`, each naming the component that declares the prop) passes only those. A prop a layer already exposes is forwarded, never redeclared in `props`; a `props` entry of `{ \"type\": \"forward\" }` is the reverse route, one of this component's props into a layer's. `anatomy` is the tree the build would read off a render: each node renders a layer (`{ \"__ref\": \"layer:<name>\" }`), an intrinsic tag, or `Slot` (`{ \"element\": \"Slot\", \"props\": { \"name\": \"children\" } }`, where a slot prop's content lands — but a declared slot fills `root` by default, so a primitive still declares its `children` slot prop yet needs no `Slot` node or `children` entry for it, and a `Slot` node is only for landing that content in a nested layer); `children` lists sibling node keys from the `root` node, never a prop name; `text` is a fixed string; `visible` is a condition on a prop (`{ \"$state\": \"<prop>\" }`, or with `eq`); content shown in a nested layer is a route, `children: { \"type\": \"forward\", \"target\": \"label/children\" }`. `$state` appears only in `visible` and in an `element` a prop chooses, never as a prop value. A glyph is a node of its own, `{ \"element\": { \"__ref\": \"icon:<library>/<Name>\" } }`, listed in the `children` of the layer node that holds it, never a prop value. Text a prop supplies to a text layer is never a node either: declare the prop `{ \"type\": \"forward\", \"target\": \"<layer>/children\" }` and the layer shows it; a `Slot` node goes only under a layer that takes nodes. A style rule is `\"styles\": { \"*\": { \"when\": null, \"layers\": { \"root\": { \"bg\": \"surface\" } } } }`, keyed by a name, with each layer's bag under `layers`. A composed component carries its own styles: give it an unconditional (`\"*\"`) rule that lays out and surfaces it through the system's style properties — spacing, alignment and gap on the container, a background and color where it has one — rather than leaning on the bare primitives, which paint flat. Style a layer only with the style props the primitive it renders exposes, set to the values those props accept: `component/get` on the primitive lists both, so read it and choose from that rather than reaching for a CSS name or value the system has no style property for. Set `previewProps` (or `defaultProps`) so the component previews with content; a root that takes children renders empty otherwise. A style rule's layer bag is keyed by style-prop name (`fontWeight`, `color`), never by CSS property name, and each value is one of that prop's values.";
|
|
385
|
+
readonly description: "Create a component at a new qualified `path`. For a component with nothing in it yet, one to design on the canvas before it has props or variants, use `create-blank` with only a `path` instead of authoring a minimal body here. When its complete body is known, include all layers, anatomy, props, defaults, and styles in this one operation. `data.layers` maps each stable layer name to the element it renders and must include `root` — a tag for a primitive (`{ \"layers\": { \"root\": \"div\" } }`), and for anything built on top, a ref to a primitive (`{ \"root\": { \"__ref\": \"component:Box\" }, \"label\": { \"__ref\": \"component:Text\" } }`), which is what lets the layer take that primitive's style props. A primitive exposes style props as `{ \"type\": \"styleProperty\", \"value\": { \"__ref\": \"style-property:bg\" } }` and declares `children: { \"type\": \"slot\", \"text\": true }` when it holds content — without the slot, nothing nested inside it renders. A composed component exposes a layer's props at its own top level through `forwards`, keyed by layer: `{ \"forwards\": { \"root\": \"*\" } }` passes every prop the root's element takes (so `<Button width=\"full\">` reaches the root's `width`), and a list of member refs (`[{ \"__ref\": \"component:Box#props/width\" }]`, each naming the component that declares the prop) passes only those. A prop a layer already exposes is forwarded, never redeclared in `props`; a `props` entry of `{ \"type\": \"forward\" }` is the reverse route, one of this component's props into a layer's. `anatomy` is the tree the build would read off a render: each node renders a layer (`{ \"__ref\": \"layer:<name>\" }`), an intrinsic tag, or `Slot` (`{ \"element\": \"Slot\", \"props\": { \"name\": \"children\" } }`, where a slot prop's content lands — but a declared slot fills `root` by default, so a primitive still declares its `children` slot prop yet needs no `Slot` node or `children` entry for it, and a `Slot` node is only for landing that content in a nested layer); `children` lists sibling node keys from the `root` node, never a prop name; `text` is a fixed string; `visible` is a condition on a prop (`{ \"$state\": \"<prop>\" }`, or with `eq`); content shown in a nested layer is a route, `children: { \"type\": \"forward\", \"target\": \"label/children\" }`. `$state` appears only in `visible` and in an `element` a prop chooses, never as a prop value. A glyph is a node of its own, `{ \"element\": { \"__ref\": \"icon:<library>/<Name>\" } }`, listed in the `children` of the layer node that holds it, never a prop value. Text a prop supplies to a text layer is never a node either: declare the prop `{ \"type\": \"forward\", \"target\": \"<layer>/children\" }` and the layer shows it; a `Slot` node goes only under a layer that takes nodes. A style rule is `\"styles\": { \"*\": { \"when\": null, \"layers\": { \"root\": { \"bg\": \"surface\" } } } }`, keyed by a name, with each layer's bag under `layers`. A composed component carries its own styles: give it an unconditional (`\"*\"`) rule that lays out and surfaces it through the system's style properties — spacing, alignment and gap on the container, a background and color where it has one — rather than leaning on the bare primitives, which paint flat. Style a layer only with the style props the primitive it renders exposes, set to the values those props accept: `component/get` on the primitive lists both, so read it and choose from that rather than reaching for a CSS name or value the system has no style property for. Set `previewProps` (or `defaultProps`) so the component previews with content; a root that takes children renders empty otherwise. A style rule's layer bag is keyed by style-prop name (`fontWeight`, `color`), never by CSS property name, and each value is one of that prop's values.";
|
|
386
386
|
readonly example: ({
|
|
387
387
|
config
|
|
388
388
|
}: {
|
|
@@ -394,6 +394,27 @@ declare const Node: EntityClass<z.ZodObject<{
|
|
|
394
394
|
data: Record<string, unknown>;
|
|
395
395
|
};
|
|
396
396
|
};
|
|
397
|
+
readonly 'create-blank': {
|
|
398
|
+
readonly input: z.ZodObject<{
|
|
399
|
+
path: z.ZodType<string, string | undefined, z.core.$ZodTypeInternals<string, string | undefined>>;
|
|
400
|
+
}, z.core.$strip>;
|
|
401
|
+
readonly readOnly: false;
|
|
402
|
+
readonly label: "Create blank";
|
|
403
|
+
readonly description: "Create an empty component at a new qualified `path`, to design on the canvas first: one `div` root layer and the node that renders it, with no props, no variants, no slot, no styles and no preview content. This is exactly what Studio's \"+\" creates. Takes only `path`. Use it for \"a new component\", \"a blank component\" or \"start a component from nothing\"; `create` is for a component whose body is already known.";
|
|
404
|
+
readonly scope: "item";
|
|
405
|
+
readonly creates: true;
|
|
406
|
+
readonly title: (entity: string) => string;
|
|
407
|
+
readonly example: ({
|
|
408
|
+
config
|
|
409
|
+
}: {
|
|
410
|
+
config: Config;
|
|
411
|
+
kind: string;
|
|
412
|
+
path: string;
|
|
413
|
+
}) => {
|
|
414
|
+
path: string;
|
|
415
|
+
};
|
|
416
|
+
readonly handler: (input: Record<string, unknown>, config: Config) => Config;
|
|
417
|
+
};
|
|
397
418
|
readonly 'sub-create/anatomy': {
|
|
398
419
|
readonly description: "Add one anatomy node (`key` + `data`) to a component. In a batch, create child nodes before a parent whose `children` or `slots` names them; each referenced node must already exist when this operation runs.";
|
|
399
420
|
};
|
|
@@ -1248,7 +1269,7 @@ declare const CanvasConfig: ConfigClass<{
|
|
|
1248
1269
|
}, z.core.$strip>>;
|
|
1249
1270
|
export: z.ZodOptional<z.ZodString>;
|
|
1250
1271
|
}, z.core.$strict>;
|
|
1251
|
-
readonly description: "Create a component at a new qualified `path`. When its complete body is known, include all layers, anatomy, props, defaults, and styles in this one operation. `data.layers` maps each stable layer name to the element it renders and must include `root` — a tag for a primitive (`{ \"layers\": { \"root\": \"div\" } }`), and for anything built on top, a ref to a primitive (`{ \"root\": { \"__ref\": \"component:Box\" }, \"label\": { \"__ref\": \"component:Text\" } }`), which is what lets the layer take that primitive's style props. A primitive exposes style props as `{ \"type\": \"styleProperty\", \"value\": { \"__ref\": \"style-property:bg\" } }` and declares `children: { \"type\": \"slot\", \"text\": true }` when it holds content — without the slot, nothing nested inside it renders. A composed component exposes a layer's props at its own top level through `forwards`, keyed by layer: `{ \"forwards\": { \"root\": \"*\" } }` passes every prop the root's element takes (so `<Button width=\"full\">` reaches the root's `width`), and a list of member refs (`[{ \"__ref\": \"component:Box#props/width\" }]`, each naming the component that declares the prop) passes only those. A prop a layer already exposes is forwarded, never redeclared in `props`; a `props` entry of `{ \"type\": \"forward\" }` is the reverse route, one of this component's props into a layer's. `anatomy` is the tree the build would read off a render: each node renders a layer (`{ \"__ref\": \"layer:<name>\" }`), an intrinsic tag, or `Slot` (`{ \"element\": \"Slot\", \"props\": { \"name\": \"children\" } }`, where a slot prop's content lands — but a declared slot fills `root` by default, so a primitive still declares its `children` slot prop yet needs no `Slot` node or `children` entry for it, and a `Slot` node is only for landing that content in a nested layer); `children` lists sibling node keys from the `root` node, never a prop name; `text` is a fixed string; `visible` is a condition on a prop (`{ \"$state\": \"<prop>\" }`, or with `eq`); content shown in a nested layer is a route, `children: { \"type\": \"forward\", \"target\": \"label/children\" }`. `$state` appears only in `visible` and in an `element` a prop chooses, never as a prop value. A glyph is a node of its own, `{ \"element\": { \"__ref\": \"icon:<library>/<Name>\" } }`, listed in the `children` of the layer node that holds it, never a prop value. Text a prop supplies to a text layer is never a node either: declare the prop `{ \"type\": \"forward\", \"target\": \"<layer>/children\" }` and the layer shows it; a `Slot` node goes only under a layer that takes nodes. A style rule is `\"styles\": { \"*\": { \"when\": null, \"layers\": { \"root\": { \"bg\": \"surface\" } } } }`, keyed by a name, with each layer's bag under `layers`. A composed component carries its own styles: give it an unconditional (`\"*\"`) rule that lays out and surfaces it through the system's style properties — spacing, alignment and gap on the container, a background and color where it has one — rather than leaning on the bare primitives, which paint flat. Style a layer only with the style props the primitive it renders exposes, set to the values those props accept: `component/get` on the primitive lists both, so read it and choose from that rather than reaching for a CSS name or value the system has no style property for. Set `previewProps` (or `defaultProps`) so the component previews with content; a root that takes children renders empty otherwise. A style rule's layer bag is keyed by style-prop name (`fontWeight`, `color`), never by CSS property name, and each value is one of that prop's values.";
|
|
1272
|
+
readonly description: "Create a component at a new qualified `path`. For a component with nothing in it yet, one to design on the canvas before it has props or variants, use `create-blank` with only a `path` instead of authoring a minimal body here. When its complete body is known, include all layers, anatomy, props, defaults, and styles in this one operation. `data.layers` maps each stable layer name to the element it renders and must include `root` — a tag for a primitive (`{ \"layers\": { \"root\": \"div\" } }`), and for anything built on top, a ref to a primitive (`{ \"root\": { \"__ref\": \"component:Box\" }, \"label\": { \"__ref\": \"component:Text\" } }`), which is what lets the layer take that primitive's style props. A primitive exposes style props as `{ \"type\": \"styleProperty\", \"value\": { \"__ref\": \"style-property:bg\" } }` and declares `children: { \"type\": \"slot\", \"text\": true }` when it holds content — without the slot, nothing nested inside it renders. A composed component exposes a layer's props at its own top level through `forwards`, keyed by layer: `{ \"forwards\": { \"root\": \"*\" } }` passes every prop the root's element takes (so `<Button width=\"full\">` reaches the root's `width`), and a list of member refs (`[{ \"__ref\": \"component:Box#props/width\" }]`, each naming the component that declares the prop) passes only those. A prop a layer already exposes is forwarded, never redeclared in `props`; a `props` entry of `{ \"type\": \"forward\" }` is the reverse route, one of this component's props into a layer's. `anatomy` is the tree the build would read off a render: each node renders a layer (`{ \"__ref\": \"layer:<name>\" }`), an intrinsic tag, or `Slot` (`{ \"element\": \"Slot\", \"props\": { \"name\": \"children\" } }`, where a slot prop's content lands — but a declared slot fills `root` by default, so a primitive still declares its `children` slot prop yet needs no `Slot` node or `children` entry for it, and a `Slot` node is only for landing that content in a nested layer); `children` lists sibling node keys from the `root` node, never a prop name; `text` is a fixed string; `visible` is a condition on a prop (`{ \"$state\": \"<prop>\" }`, or with `eq`); content shown in a nested layer is a route, `children: { \"type\": \"forward\", \"target\": \"label/children\" }`. `$state` appears only in `visible` and in an `element` a prop chooses, never as a prop value. A glyph is a node of its own, `{ \"element\": { \"__ref\": \"icon:<library>/<Name>\" } }`, listed in the `children` of the layer node that holds it, never a prop value. Text a prop supplies to a text layer is never a node either: declare the prop `{ \"type\": \"forward\", \"target\": \"<layer>/children\" }` and the layer shows it; a `Slot` node goes only under a layer that takes nodes. A style rule is `\"styles\": { \"*\": { \"when\": null, \"layers\": { \"root\": { \"bg\": \"surface\" } } } }`, keyed by a name, with each layer's bag under `layers`. A composed component carries its own styles: give it an unconditional (`\"*\"`) rule that lays out and surfaces it through the system's style properties — spacing, alignment and gap on the container, a background and color where it has one — rather than leaning on the bare primitives, which paint flat. Style a layer only with the style props the primitive it renders exposes, set to the values those props accept: `component/get` on the primitive lists both, so read it and choose from that rather than reaching for a CSS name or value the system has no style property for. Set `previewProps` (or `defaultProps`) so the component previews with content; a root that takes children renders empty otherwise. A style rule's layer bag is keyed by style-prop name (`fontWeight`, `color`), never by CSS property name, and each value is one of that prop's values.";
|
|
1252
1273
|
readonly example: ({
|
|
1253
1274
|
config
|
|
1254
1275
|
}: {
|
|
@@ -1260,6 +1281,27 @@ declare const CanvasConfig: ConfigClass<{
|
|
|
1260
1281
|
data: Record<string, unknown>;
|
|
1261
1282
|
};
|
|
1262
1283
|
};
|
|
1284
|
+
readonly 'create-blank': {
|
|
1285
|
+
readonly input: z.ZodObject<{
|
|
1286
|
+
path: z.ZodType<string, string | undefined, z.core.$ZodTypeInternals<string, string | undefined>>;
|
|
1287
|
+
}, z.core.$strip>;
|
|
1288
|
+
readonly readOnly: false;
|
|
1289
|
+
readonly label: "Create blank";
|
|
1290
|
+
readonly description: "Create an empty component at a new qualified `path`, to design on the canvas first: one `div` root layer and the node that renders it, with no props, no variants, no slot, no styles and no preview content. This is exactly what Studio's \"+\" creates. Takes only `path`. Use it for \"a new component\", \"a blank component\" or \"start a component from nothing\"; `create` is for a component whose body is already known.";
|
|
1291
|
+
readonly scope: "item";
|
|
1292
|
+
readonly creates: true;
|
|
1293
|
+
readonly title: (entity: string) => string;
|
|
1294
|
+
readonly example: ({
|
|
1295
|
+
config
|
|
1296
|
+
}: {
|
|
1297
|
+
config: Config;
|
|
1298
|
+
kind: string;
|
|
1299
|
+
path: string;
|
|
1300
|
+
}) => {
|
|
1301
|
+
path: string;
|
|
1302
|
+
};
|
|
1303
|
+
readonly handler: (input: Record<string, unknown>, config: Config) => Config;
|
|
1304
|
+
};
|
|
1263
1305
|
readonly 'sub-create/anatomy': {
|
|
1264
1306
|
readonly description: "Add one anatomy node (`key` + `data`) to a component. In a batch, create child nodes before a parent whose `children` or `slots` names them; each referenced node must already exist when this operation runs.";
|
|
1265
1307
|
};
|
|
@@ -2379,7 +2421,7 @@ declare function createCanvasConfig(system: AnySystemConfig): ConfigInstance<{
|
|
|
2379
2421
|
}, z.core.$strip>>;
|
|
2380
2422
|
export: z.ZodOptional<z.ZodString>;
|
|
2381
2423
|
}, z.core.$strict>;
|
|
2382
|
-
readonly description: "Create a component at a new qualified `path`. When its complete body is known, include all layers, anatomy, props, defaults, and styles in this one operation. `data.layers` maps each stable layer name to the element it renders and must include `root` — a tag for a primitive (`{ \"layers\": { \"root\": \"div\" } }`), and for anything built on top, a ref to a primitive (`{ \"root\": { \"__ref\": \"component:Box\" }, \"label\": { \"__ref\": \"component:Text\" } }`), which is what lets the layer take that primitive's style props. A primitive exposes style props as `{ \"type\": \"styleProperty\", \"value\": { \"__ref\": \"style-property:bg\" } }` and declares `children: { \"type\": \"slot\", \"text\": true }` when it holds content — without the slot, nothing nested inside it renders. A composed component exposes a layer's props at its own top level through `forwards`, keyed by layer: `{ \"forwards\": { \"root\": \"*\" } }` passes every prop the root's element takes (so `<Button width=\"full\">` reaches the root's `width`), and a list of member refs (`[{ \"__ref\": \"component:Box#props/width\" }]`, each naming the component that declares the prop) passes only those. A prop a layer already exposes is forwarded, never redeclared in `props`; a `props` entry of `{ \"type\": \"forward\" }` is the reverse route, one of this component's props into a layer's. `anatomy` is the tree the build would read off a render: each node renders a layer (`{ \"__ref\": \"layer:<name>\" }`), an intrinsic tag, or `Slot` (`{ \"element\": \"Slot\", \"props\": { \"name\": \"children\" } }`, where a slot prop's content lands — but a declared slot fills `root` by default, so a primitive still declares its `children` slot prop yet needs no `Slot` node or `children` entry for it, and a `Slot` node is only for landing that content in a nested layer); `children` lists sibling node keys from the `root` node, never a prop name; `text` is a fixed string; `visible` is a condition on a prop (`{ \"$state\": \"<prop>\" }`, or with `eq`); content shown in a nested layer is a route, `children: { \"type\": \"forward\", \"target\": \"label/children\" }`. `$state` appears only in `visible` and in an `element` a prop chooses, never as a prop value. A glyph is a node of its own, `{ \"element\": { \"__ref\": \"icon:<library>/<Name>\" } }`, listed in the `children` of the layer node that holds it, never a prop value. Text a prop supplies to a text layer is never a node either: declare the prop `{ \"type\": \"forward\", \"target\": \"<layer>/children\" }` and the layer shows it; a `Slot` node goes only under a layer that takes nodes. A style rule is `\"styles\": { \"*\": { \"when\": null, \"layers\": { \"root\": { \"bg\": \"surface\" } } } }`, keyed by a name, with each layer's bag under `layers`. A composed component carries its own styles: give it an unconditional (`\"*\"`) rule that lays out and surfaces it through the system's style properties — spacing, alignment and gap on the container, a background and color where it has one — rather than leaning on the bare primitives, which paint flat. Style a layer only with the style props the primitive it renders exposes, set to the values those props accept: `component/get` on the primitive lists both, so read it and choose from that rather than reaching for a CSS name or value the system has no style property for. Set `previewProps` (or `defaultProps`) so the component previews with content; a root that takes children renders empty otherwise. A style rule's layer bag is keyed by style-prop name (`fontWeight`, `color`), never by CSS property name, and each value is one of that prop's values.";
|
|
2424
|
+
readonly description: "Create a component at a new qualified `path`. For a component with nothing in it yet, one to design on the canvas before it has props or variants, use `create-blank` with only a `path` instead of authoring a minimal body here. When its complete body is known, include all layers, anatomy, props, defaults, and styles in this one operation. `data.layers` maps each stable layer name to the element it renders and must include `root` — a tag for a primitive (`{ \"layers\": { \"root\": \"div\" } }`), and for anything built on top, a ref to a primitive (`{ \"root\": { \"__ref\": \"component:Box\" }, \"label\": { \"__ref\": \"component:Text\" } }`), which is what lets the layer take that primitive's style props. A primitive exposes style props as `{ \"type\": \"styleProperty\", \"value\": { \"__ref\": \"style-property:bg\" } }` and declares `children: { \"type\": \"slot\", \"text\": true }` when it holds content — without the slot, nothing nested inside it renders. A composed component exposes a layer's props at its own top level through `forwards`, keyed by layer: `{ \"forwards\": { \"root\": \"*\" } }` passes every prop the root's element takes (so `<Button width=\"full\">` reaches the root's `width`), and a list of member refs (`[{ \"__ref\": \"component:Box#props/width\" }]`, each naming the component that declares the prop) passes only those. A prop a layer already exposes is forwarded, never redeclared in `props`; a `props` entry of `{ \"type\": \"forward\" }` is the reverse route, one of this component's props into a layer's. `anatomy` is the tree the build would read off a render: each node renders a layer (`{ \"__ref\": \"layer:<name>\" }`), an intrinsic tag, or `Slot` (`{ \"element\": \"Slot\", \"props\": { \"name\": \"children\" } }`, where a slot prop's content lands — but a declared slot fills `root` by default, so a primitive still declares its `children` slot prop yet needs no `Slot` node or `children` entry for it, and a `Slot` node is only for landing that content in a nested layer); `children` lists sibling node keys from the `root` node, never a prop name; `text` is a fixed string; `visible` is a condition on a prop (`{ \"$state\": \"<prop>\" }`, or with `eq`); content shown in a nested layer is a route, `children: { \"type\": \"forward\", \"target\": \"label/children\" }`. `$state` appears only in `visible` and in an `element` a prop chooses, never as a prop value. A glyph is a node of its own, `{ \"element\": { \"__ref\": \"icon:<library>/<Name>\" } }`, listed in the `children` of the layer node that holds it, never a prop value. Text a prop supplies to a text layer is never a node either: declare the prop `{ \"type\": \"forward\", \"target\": \"<layer>/children\" }` and the layer shows it; a `Slot` node goes only under a layer that takes nodes. A style rule is `\"styles\": { \"*\": { \"when\": null, \"layers\": { \"root\": { \"bg\": \"surface\" } } } }`, keyed by a name, with each layer's bag under `layers`. A composed component carries its own styles: give it an unconditional (`\"*\"`) rule that lays out and surfaces it through the system's style properties — spacing, alignment and gap on the container, a background and color where it has one — rather than leaning on the bare primitives, which paint flat. Style a layer only with the style props the primitive it renders exposes, set to the values those props accept: `component/get` on the primitive lists both, so read it and choose from that rather than reaching for a CSS name or value the system has no style property for. Set `previewProps` (or `defaultProps`) so the component previews with content; a root that takes children renders empty otherwise. A style rule's layer bag is keyed by style-prop name (`fontWeight`, `color`), never by CSS property name, and each value is one of that prop's values.";
|
|
2383
2425
|
readonly example: ({
|
|
2384
2426
|
config
|
|
2385
2427
|
}: {
|
|
@@ -2391,6 +2433,27 @@ declare function createCanvasConfig(system: AnySystemConfig): ConfigInstance<{
|
|
|
2391
2433
|
data: Record<string, unknown>;
|
|
2392
2434
|
};
|
|
2393
2435
|
};
|
|
2436
|
+
readonly 'create-blank': {
|
|
2437
|
+
readonly input: z.ZodObject<{
|
|
2438
|
+
path: z.ZodType<string, string | undefined, z.core.$ZodTypeInternals<string, string | undefined>>;
|
|
2439
|
+
}, z.core.$strip>;
|
|
2440
|
+
readonly readOnly: false;
|
|
2441
|
+
readonly label: "Create blank";
|
|
2442
|
+
readonly description: "Create an empty component at a new qualified `path`, to design on the canvas first: one `div` root layer and the node that renders it, with no props, no variants, no slot, no styles and no preview content. This is exactly what Studio's \"+\" creates. Takes only `path`. Use it for \"a new component\", \"a blank component\" or \"start a component from nothing\"; `create` is for a component whose body is already known.";
|
|
2443
|
+
readonly scope: "item";
|
|
2444
|
+
readonly creates: true;
|
|
2445
|
+
readonly title: (entity: string) => string;
|
|
2446
|
+
readonly example: ({
|
|
2447
|
+
config
|
|
2448
|
+
}: {
|
|
2449
|
+
config: Config;
|
|
2450
|
+
kind: string;
|
|
2451
|
+
path: string;
|
|
2452
|
+
}) => {
|
|
2453
|
+
path: string;
|
|
2454
|
+
};
|
|
2455
|
+
readonly handler: (input: Record<string, unknown>, config: Config) => Config;
|
|
2456
|
+
};
|
|
2394
2457
|
readonly 'sub-create/anatomy': {
|
|
2395
2458
|
readonly description: "Add one anatomy node (`key` + `data`) to a component. In a batch, create child nodes before a parent whose `children` or `slots` names them; each referenced node must already exist when this operation runs.";
|
|
2396
2459
|
};
|
|
@@ -309,7 +309,7 @@ declare const ReactNativeSystem: ConfigClass<{
|
|
|
309
309
|
}, _$zod_v4_core0.$strip>>;
|
|
310
310
|
export: _$zod.ZodOptional<_$zod.ZodString>;
|
|
311
311
|
}, _$zod_v4_core0.$strict>;
|
|
312
|
-
readonly description: "Create a component at a new qualified `path`. When its complete body is known, include all layers, anatomy, props, defaults, and styles in this one operation. `data.layers` maps each stable layer name to the element it renders and must include `root` — a tag for a primitive (`{ \"layers\": { \"root\": \"div\" } }`), and for anything built on top, a ref to a primitive (`{ \"root\": { \"__ref\": \"component:Box\" }, \"label\": { \"__ref\": \"component:Text\" } }`), which is what lets the layer take that primitive's style props. A primitive exposes style props as `{ \"type\": \"styleProperty\", \"value\": { \"__ref\": \"style-property:bg\" } }` and declares `children: { \"type\": \"slot\", \"text\": true }` when it holds content — without the slot, nothing nested inside it renders. A composed component exposes a layer's props at its own top level through `forwards`, keyed by layer: `{ \"forwards\": { \"root\": \"*\" } }` passes every prop the root's element takes (so `<Button width=\"full\">` reaches the root's `width`), and a list of member refs (`[{ \"__ref\": \"component:Box#props/width\" }]`, each naming the component that declares the prop) passes only those. A prop a layer already exposes is forwarded, never redeclared in `props`; a `props` entry of `{ \"type\": \"forward\" }` is the reverse route, one of this component's props into a layer's. `anatomy` is the tree the build would read off a render: each node renders a layer (`{ \"__ref\": \"layer:<name>\" }`), an intrinsic tag, or `Slot` (`{ \"element\": \"Slot\", \"props\": { \"name\": \"children\" } }`, where a slot prop's content lands — but a declared slot fills `root` by default, so a primitive still declares its `children` slot prop yet needs no `Slot` node or `children` entry for it, and a `Slot` node is only for landing that content in a nested layer); `children` lists sibling node keys from the `root` node, never a prop name; `text` is a fixed string; `visible` is a condition on a prop (`{ \"$state\": \"<prop>\" }`, or with `eq`); content shown in a nested layer is a route, `children: { \"type\": \"forward\", \"target\": \"label/children\" }`. `$state` appears only in `visible` and in an `element` a prop chooses, never as a prop value. A glyph is a node of its own, `{ \"element\": { \"__ref\": \"icon:<library>/<Name>\" } }`, listed in the `children` of the layer node that holds it, never a prop value. Text a prop supplies to a text layer is never a node either: declare the prop `{ \"type\": \"forward\", \"target\": \"<layer>/children\" }` and the layer shows it; a `Slot` node goes only under a layer that takes nodes. A style rule is `\"styles\": { \"*\": { \"when\": null, \"layers\": { \"root\": { \"bg\": \"surface\" } } } }`, keyed by a name, with each layer's bag under `layers`. A composed component carries its own styles: give it an unconditional (`\"*\"`) rule that lays out and surfaces it through the system's style properties — spacing, alignment and gap on the container, a background and color where it has one — rather than leaning on the bare primitives, which paint flat. Style a layer only with the style props the primitive it renders exposes, set to the values those props accept: `component/get` on the primitive lists both, so read it and choose from that rather than reaching for a CSS name or value the system has no style property for. Set `previewProps` (or `defaultProps`) so the component previews with content; a root that takes children renders empty otherwise. A style rule's layer bag is keyed by style-prop name (`fontWeight`, `color`), never by CSS property name, and each value is one of that prop's values.";
|
|
312
|
+
readonly description: "Create a component at a new qualified `path`. For a component with nothing in it yet, one to design on the canvas before it has props or variants, use `create-blank` with only a `path` instead of authoring a minimal body here. When its complete body is known, include all layers, anatomy, props, defaults, and styles in this one operation. `data.layers` maps each stable layer name to the element it renders and must include `root` — a tag for a primitive (`{ \"layers\": { \"root\": \"div\" } }`), and for anything built on top, a ref to a primitive (`{ \"root\": { \"__ref\": \"component:Box\" }, \"label\": { \"__ref\": \"component:Text\" } }`), which is what lets the layer take that primitive's style props. A primitive exposes style props as `{ \"type\": \"styleProperty\", \"value\": { \"__ref\": \"style-property:bg\" } }` and declares `children: { \"type\": \"slot\", \"text\": true }` when it holds content — without the slot, nothing nested inside it renders. A composed component exposes a layer's props at its own top level through `forwards`, keyed by layer: `{ \"forwards\": { \"root\": \"*\" } }` passes every prop the root's element takes (so `<Button width=\"full\">` reaches the root's `width`), and a list of member refs (`[{ \"__ref\": \"component:Box#props/width\" }]`, each naming the component that declares the prop) passes only those. A prop a layer already exposes is forwarded, never redeclared in `props`; a `props` entry of `{ \"type\": \"forward\" }` is the reverse route, one of this component's props into a layer's. `anatomy` is the tree the build would read off a render: each node renders a layer (`{ \"__ref\": \"layer:<name>\" }`), an intrinsic tag, or `Slot` (`{ \"element\": \"Slot\", \"props\": { \"name\": \"children\" } }`, where a slot prop's content lands — but a declared slot fills `root` by default, so a primitive still declares its `children` slot prop yet needs no `Slot` node or `children` entry for it, and a `Slot` node is only for landing that content in a nested layer); `children` lists sibling node keys from the `root` node, never a prop name; `text` is a fixed string; `visible` is a condition on a prop (`{ \"$state\": \"<prop>\" }`, or with `eq`); content shown in a nested layer is a route, `children: { \"type\": \"forward\", \"target\": \"label/children\" }`. `$state` appears only in `visible` and in an `element` a prop chooses, never as a prop value. A glyph is a node of its own, `{ \"element\": { \"__ref\": \"icon:<library>/<Name>\" } }`, listed in the `children` of the layer node that holds it, never a prop value. Text a prop supplies to a text layer is never a node either: declare the prop `{ \"type\": \"forward\", \"target\": \"<layer>/children\" }` and the layer shows it; a `Slot` node goes only under a layer that takes nodes. A style rule is `\"styles\": { \"*\": { \"when\": null, \"layers\": { \"root\": { \"bg\": \"surface\" } } } }`, keyed by a name, with each layer's bag under `layers`. A composed component carries its own styles: give it an unconditional (`\"*\"`) rule that lays out and surfaces it through the system's style properties — spacing, alignment and gap on the container, a background and color where it has one — rather than leaning on the bare primitives, which paint flat. Style a layer only with the style props the primitive it renders exposes, set to the values those props accept: `component/get` on the primitive lists both, so read it and choose from that rather than reaching for a CSS name or value the system has no style property for. Set `previewProps` (or `defaultProps`) so the component previews with content; a root that takes children renders empty otherwise. A style rule's layer bag is keyed by style-prop name (`fontWeight`, `color`), never by CSS property name, and each value is one of that prop's values.";
|
|
313
313
|
readonly example: ({
|
|
314
314
|
config
|
|
315
315
|
}: {
|
|
@@ -321,6 +321,27 @@ declare const ReactNativeSystem: ConfigClass<{
|
|
|
321
321
|
data: Record<string, unknown>;
|
|
322
322
|
};
|
|
323
323
|
};
|
|
324
|
+
readonly 'create-blank': {
|
|
325
|
+
readonly input: _$zod.ZodObject<{
|
|
326
|
+
path: _$zod.ZodType<string, string | undefined, _$zod_v4_core0.$ZodTypeInternals<string, string | undefined>>;
|
|
327
|
+
}, _$zod_v4_core0.$strip>;
|
|
328
|
+
readonly readOnly: false;
|
|
329
|
+
readonly label: "Create blank";
|
|
330
|
+
readonly description: "Create an empty component at a new qualified `path`, to design on the canvas first: one `div` root layer and the node that renders it, with no props, no variants, no slot, no styles and no preview content. This is exactly what Studio's \"+\" creates. Takes only `path`. Use it for \"a new component\", \"a blank component\" or \"start a component from nothing\"; `create` is for a component whose body is already known.";
|
|
331
|
+
readonly scope: "item";
|
|
332
|
+
readonly creates: true;
|
|
333
|
+
readonly title: (entity: string) => string;
|
|
334
|
+
readonly example: ({
|
|
335
|
+
config
|
|
336
|
+
}: {
|
|
337
|
+
config: Config;
|
|
338
|
+
kind: string;
|
|
339
|
+
path: string;
|
|
340
|
+
}) => {
|
|
341
|
+
path: string;
|
|
342
|
+
};
|
|
343
|
+
readonly handler: (input: Record<string, unknown>, config: Config) => Config;
|
|
344
|
+
};
|
|
324
345
|
readonly 'sub-create/anatomy': {
|
|
325
346
|
readonly description: "Add one anatomy node (`key` + `data`) to a component. In a batch, create child nodes before a parent whose `children` or `slots` names them; each referenced node must already exist when this operation runs.";
|
|
326
347
|
};
|
|
@@ -1812,7 +1833,7 @@ declare const ReactNativeSystem: ConfigClass<{
|
|
|
1812
1833
|
}, _$zod_v4_core0.$strip>>;
|
|
1813
1834
|
export: _$zod.ZodOptional<_$zod.ZodString>;
|
|
1814
1835
|
}, _$zod_v4_core0.$strict>;
|
|
1815
|
-
readonly description: "Create a component at a new qualified `path`. When its complete body is known, include all layers, anatomy, props, defaults, and styles in this one operation. `data.layers` maps each stable layer name to the element it renders and must include `root` — a tag for a primitive (`{ \"layers\": { \"root\": \"div\" } }`), and for anything built on top, a ref to a primitive (`{ \"root\": { \"__ref\": \"component:Box\" }, \"label\": { \"__ref\": \"component:Text\" } }`), which is what lets the layer take that primitive's style props. A primitive exposes style props as `{ \"type\": \"styleProperty\", \"value\": { \"__ref\": \"style-property:bg\" } }` and declares `children: { \"type\": \"slot\", \"text\": true }` when it holds content — without the slot, nothing nested inside it renders. A composed component exposes a layer's props at its own top level through `forwards`, keyed by layer: `{ \"forwards\": { \"root\": \"*\" } }` passes every prop the root's element takes (so `<Button width=\"full\">` reaches the root's `width`), and a list of member refs (`[{ \"__ref\": \"component:Box#props/width\" }]`, each naming the component that declares the prop) passes only those. A prop a layer already exposes is forwarded, never redeclared in `props`; a `props` entry of `{ \"type\": \"forward\" }` is the reverse route, one of this component's props into a layer's. `anatomy` is the tree the build would read off a render: each node renders a layer (`{ \"__ref\": \"layer:<name>\" }`), an intrinsic tag, or `Slot` (`{ \"element\": \"Slot\", \"props\": { \"name\": \"children\" } }`, where a slot prop's content lands — but a declared slot fills `root` by default, so a primitive still declares its `children` slot prop yet needs no `Slot` node or `children` entry for it, and a `Slot` node is only for landing that content in a nested layer); `children` lists sibling node keys from the `root` node, never a prop name; `text` is a fixed string; `visible` is a condition on a prop (`{ \"$state\": \"<prop>\" }`, or with `eq`); content shown in a nested layer is a route, `children: { \"type\": \"forward\", \"target\": \"label/children\" }`. `$state` appears only in `visible` and in an `element` a prop chooses, never as a prop value. A glyph is a node of its own, `{ \"element\": { \"__ref\": \"icon:<library>/<Name>\" } }`, listed in the `children` of the layer node that holds it, never a prop value. Text a prop supplies to a text layer is never a node either: declare the prop `{ \"type\": \"forward\", \"target\": \"<layer>/children\" }` and the layer shows it; a `Slot` node goes only under a layer that takes nodes. A style rule is `\"styles\": { \"*\": { \"when\": null, \"layers\": { \"root\": { \"bg\": \"surface\" } } } }`, keyed by a name, with each layer's bag under `layers`. A composed component carries its own styles: give it an unconditional (`\"*\"`) rule that lays out and surfaces it through the system's style properties — spacing, alignment and gap on the container, a background and color where it has one — rather than leaning on the bare primitives, which paint flat. Style a layer only with the style props the primitive it renders exposes, set to the values those props accept: `component/get` on the primitive lists both, so read it and choose from that rather than reaching for a CSS name or value the system has no style property for. Set `previewProps` (or `defaultProps`) so the component previews with content; a root that takes children renders empty otherwise. A style rule's layer bag is keyed by style-prop name (`fontWeight`, `color`), never by CSS property name, and each value is one of that prop's values.";
|
|
1836
|
+
readonly description: "Create a component at a new qualified `path`. For a component with nothing in it yet, one to design on the canvas before it has props or variants, use `create-blank` with only a `path` instead of authoring a minimal body here. When its complete body is known, include all layers, anatomy, props, defaults, and styles in this one operation. `data.layers` maps each stable layer name to the element it renders and must include `root` — a tag for a primitive (`{ \"layers\": { \"root\": \"div\" } }`), and for anything built on top, a ref to a primitive (`{ \"root\": { \"__ref\": \"component:Box\" }, \"label\": { \"__ref\": \"component:Text\" } }`), which is what lets the layer take that primitive's style props. A primitive exposes style props as `{ \"type\": \"styleProperty\", \"value\": { \"__ref\": \"style-property:bg\" } }` and declares `children: { \"type\": \"slot\", \"text\": true }` when it holds content — without the slot, nothing nested inside it renders. A composed component exposes a layer's props at its own top level through `forwards`, keyed by layer: `{ \"forwards\": { \"root\": \"*\" } }` passes every prop the root's element takes (so `<Button width=\"full\">` reaches the root's `width`), and a list of member refs (`[{ \"__ref\": \"component:Box#props/width\" }]`, each naming the component that declares the prop) passes only those. A prop a layer already exposes is forwarded, never redeclared in `props`; a `props` entry of `{ \"type\": \"forward\" }` is the reverse route, one of this component's props into a layer's. `anatomy` is the tree the build would read off a render: each node renders a layer (`{ \"__ref\": \"layer:<name>\" }`), an intrinsic tag, or `Slot` (`{ \"element\": \"Slot\", \"props\": { \"name\": \"children\" } }`, where a slot prop's content lands — but a declared slot fills `root` by default, so a primitive still declares its `children` slot prop yet needs no `Slot` node or `children` entry for it, and a `Slot` node is only for landing that content in a nested layer); `children` lists sibling node keys from the `root` node, never a prop name; `text` is a fixed string; `visible` is a condition on a prop (`{ \"$state\": \"<prop>\" }`, or with `eq`); content shown in a nested layer is a route, `children: { \"type\": \"forward\", \"target\": \"label/children\" }`. `$state` appears only in `visible` and in an `element` a prop chooses, never as a prop value. A glyph is a node of its own, `{ \"element\": { \"__ref\": \"icon:<library>/<Name>\" } }`, listed in the `children` of the layer node that holds it, never a prop value. Text a prop supplies to a text layer is never a node either: declare the prop `{ \"type\": \"forward\", \"target\": \"<layer>/children\" }` and the layer shows it; a `Slot` node goes only under a layer that takes nodes. A style rule is `\"styles\": { \"*\": { \"when\": null, \"layers\": { \"root\": { \"bg\": \"surface\" } } } }`, keyed by a name, with each layer's bag under `layers`. A composed component carries its own styles: give it an unconditional (`\"*\"`) rule that lays out and surfaces it through the system's style properties — spacing, alignment and gap on the container, a background and color where it has one — rather than leaning on the bare primitives, which paint flat. Style a layer only with the style props the primitive it renders exposes, set to the values those props accept: `component/get` on the primitive lists both, so read it and choose from that rather than reaching for a CSS name or value the system has no style property for. Set `previewProps` (or `defaultProps`) so the component previews with content; a root that takes children renders empty otherwise. A style rule's layer bag is keyed by style-prop name (`fontWeight`, `color`), never by CSS property name, and each value is one of that prop's values.";
|
|
1816
1837
|
readonly example: ({
|
|
1817
1838
|
config
|
|
1818
1839
|
}: {
|
|
@@ -1824,6 +1845,27 @@ declare const ReactNativeSystem: ConfigClass<{
|
|
|
1824
1845
|
data: Record<string, unknown>;
|
|
1825
1846
|
};
|
|
1826
1847
|
};
|
|
1848
|
+
readonly 'create-blank': {
|
|
1849
|
+
readonly input: _$zod.ZodObject<{
|
|
1850
|
+
path: _$zod.ZodType<string, string | undefined, _$zod_v4_core0.$ZodTypeInternals<string, string | undefined>>;
|
|
1851
|
+
}, _$zod_v4_core0.$strip>;
|
|
1852
|
+
readonly readOnly: false;
|
|
1853
|
+
readonly label: "Create blank";
|
|
1854
|
+
readonly description: "Create an empty component at a new qualified `path`, to design on the canvas first: one `div` root layer and the node that renders it, with no props, no variants, no slot, no styles and no preview content. This is exactly what Studio's \"+\" creates. Takes only `path`. Use it for \"a new component\", \"a blank component\" or \"start a component from nothing\"; `create` is for a component whose body is already known.";
|
|
1855
|
+
readonly scope: "item";
|
|
1856
|
+
readonly creates: true;
|
|
1857
|
+
readonly title: (entity: string) => string;
|
|
1858
|
+
readonly example: ({
|
|
1859
|
+
config
|
|
1860
|
+
}: {
|
|
1861
|
+
config: Config;
|
|
1862
|
+
kind: string;
|
|
1863
|
+
path: string;
|
|
1864
|
+
}) => {
|
|
1865
|
+
path: string;
|
|
1866
|
+
};
|
|
1867
|
+
readonly handler: (input: Record<string, unknown>, config: Config) => Config;
|
|
1868
|
+
};
|
|
1827
1869
|
readonly 'sub-create/anatomy': {
|
|
1828
1870
|
readonly description: "Add one anatomy node (`key` + `data`) to a component. In a batch, create child nodes before a parent whose `children` or `slots` names them; each referenced node must already exist when this operation runs.";
|
|
1829
1871
|
};
|
|
@@ -17,6 +17,7 @@ import { settingsAsKindMigration } from "../migrations/20260908171448_settings_a
|
|
|
17
17
|
import { visibleStatePointerMigration } from "../migrations/20260908194245_visible_state_pointer.js";
|
|
18
18
|
import { iconKnockoutVariantsMigration } from "../migrations/20260909183001_icon_knockout_variants.js";
|
|
19
19
|
import { linkedSystemLinkOpsMigration } from "../migrations/20260910212453_linked_system_link_ops.js";
|
|
20
|
+
import { componentCreateBlankOpMigration } from "../migrations/20260914155048_component_create_blank_op.js";
|
|
20
21
|
import { NativeModifier } from "../entities/native/NativeModifier.js";
|
|
21
22
|
import { NativeSettings } from "../entities/native/NativeSettings.js";
|
|
22
23
|
import { NativeStyleProperty } from "../entities/native/NativeStyleProperty.js";
|
|
@@ -60,5 +61,6 @@ if (!registeredSchemaMigrations().has(20260908171448)) registerSchemaMigrations(
|
|
|
60
61
|
if (!registeredSchemaMigrations().has(20260908194245)) registerSchemaMigrations(visibleStatePointerMigration);
|
|
61
62
|
if (!registeredSchemaMigrations().has(20260909183001)) registerSchemaMigrations(iconKnockoutVariantsMigration);
|
|
62
63
|
if (!registeredSchemaMigrations().has(20260910212453)) registerSchemaMigrations(linkedSystemLinkOpsMigration);
|
|
64
|
+
if (!registeredSchemaMigrations().has(20260914155048)) registerSchemaMigrations(componentCreateBlankOpMigration);
|
|
63
65
|
//#endregion
|
|
64
66
|
export { ReactNativeSystem };
|
package/dist/configs/system.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { CopyPlan } from "../entities/system/copy-plan.js";
|
|
2
|
-
import { Ref } from "../framework/utils/refs.js";
|
|
2
|
+
import { ExtendableRef, Ref } from "../framework/utils/refs.js";
|
|
3
|
+
import { CreateInput } from "../framework/utils/field-schema.js";
|
|
3
4
|
import { DerivedEntityClass } from "../framework/defineDerivedEntity.js";
|
|
4
5
|
import { SubEntityClass } from "../framework/defineSubEntity.js";
|
|
5
6
|
import { ComponentContractOf, PathOf } from "../framework/registered.js";
|
|
@@ -297,7 +298,7 @@ declare const System: ConfigClass<{
|
|
|
297
298
|
}, _$zod_v4_core0.$strip>>;
|
|
298
299
|
export: _$zod.ZodOptional<_$zod.ZodString>;
|
|
299
300
|
}, _$zod_v4_core0.$strict>;
|
|
300
|
-
readonly description: "Create a component at a new qualified `path`. When its complete body is known, include all layers, anatomy, props, defaults, and styles in this one operation. `data.layers` maps each stable layer name to the element it renders and must include `root` — a tag for a primitive (`{ \"layers\": { \"root\": \"div\" } }`), and for anything built on top, a ref to a primitive (`{ \"root\": { \"__ref\": \"component:Box\" }, \"label\": { \"__ref\": \"component:Text\" } }`), which is what lets the layer take that primitive's style props. A primitive exposes style props as `{ \"type\": \"styleProperty\", \"value\": { \"__ref\": \"style-property:bg\" } }` and declares `children: { \"type\": \"slot\", \"text\": true }` when it holds content — without the slot, nothing nested inside it renders. A composed component exposes a layer's props at its own top level through `forwards`, keyed by layer: `{ \"forwards\": { \"root\": \"*\" } }` passes every prop the root's element takes (so `<Button width=\"full\">` reaches the root's `width`), and a list of member refs (`[{ \"__ref\": \"component:Box#props/width\" }]`, each naming the component that declares the prop) passes only those. A prop a layer already exposes is forwarded, never redeclared in `props`; a `props` entry of `{ \"type\": \"forward\" }` is the reverse route, one of this component's props into a layer's. `anatomy` is the tree the build would read off a render: each node renders a layer (`{ \"__ref\": \"layer:<name>\" }`), an intrinsic tag, or `Slot` (`{ \"element\": \"Slot\", \"props\": { \"name\": \"children\" } }`, where a slot prop's content lands — but a declared slot fills `root` by default, so a primitive still declares its `children` slot prop yet needs no `Slot` node or `children` entry for it, and a `Slot` node is only for landing that content in a nested layer); `children` lists sibling node keys from the `root` node, never a prop name; `text` is a fixed string; `visible` is a condition on a prop (`{ \"$state\": \"<prop>\" }`, or with `eq`); content shown in a nested layer is a route, `children: { \"type\": \"forward\", \"target\": \"label/children\" }`. `$state` appears only in `visible` and in an `element` a prop chooses, never as a prop value. A glyph is a node of its own, `{ \"element\": { \"__ref\": \"icon:<library>/<Name>\" } }`, listed in the `children` of the layer node that holds it, never a prop value. Text a prop supplies to a text layer is never a node either: declare the prop `{ \"type\": \"forward\", \"target\": \"<layer>/children\" }` and the layer shows it; a `Slot` node goes only under a layer that takes nodes. A style rule is `\"styles\": { \"*\": { \"when\": null, \"layers\": { \"root\": { \"bg\": \"surface\" } } } }`, keyed by a name, with each layer's bag under `layers`. A composed component carries its own styles: give it an unconditional (`\"*\"`) rule that lays out and surfaces it through the system's style properties — spacing, alignment and gap on the container, a background and color where it has one — rather than leaning on the bare primitives, which paint flat. Style a layer only with the style props the primitive it renders exposes, set to the values those props accept: `component/get` on the primitive lists both, so read it and choose from that rather than reaching for a CSS name or value the system has no style property for. Set `previewProps` (or `defaultProps`) so the component previews with content; a root that takes children renders empty otherwise. A style rule's layer bag is keyed by style-prop name (`fontWeight`, `color`), never by CSS property name, and each value is one of that prop's values.";
|
|
301
|
+
readonly description: "Create a component at a new qualified `path`. For a component with nothing in it yet, one to design on the canvas before it has props or variants, use `create-blank` with only a `path` instead of authoring a minimal body here. When its complete body is known, include all layers, anatomy, props, defaults, and styles in this one operation. `data.layers` maps each stable layer name to the element it renders and must include `root` — a tag for a primitive (`{ \"layers\": { \"root\": \"div\" } }`), and for anything built on top, a ref to a primitive (`{ \"root\": { \"__ref\": \"component:Box\" }, \"label\": { \"__ref\": \"component:Text\" } }`), which is what lets the layer take that primitive's style props. A primitive exposes style props as `{ \"type\": \"styleProperty\", \"value\": { \"__ref\": \"style-property:bg\" } }` and declares `children: { \"type\": \"slot\", \"text\": true }` when it holds content — without the slot, nothing nested inside it renders. A composed component exposes a layer's props at its own top level through `forwards`, keyed by layer: `{ \"forwards\": { \"root\": \"*\" } }` passes every prop the root's element takes (so `<Button width=\"full\">` reaches the root's `width`), and a list of member refs (`[{ \"__ref\": \"component:Box#props/width\" }]`, each naming the component that declares the prop) passes only those. A prop a layer already exposes is forwarded, never redeclared in `props`; a `props` entry of `{ \"type\": \"forward\" }` is the reverse route, one of this component's props into a layer's. `anatomy` is the tree the build would read off a render: each node renders a layer (`{ \"__ref\": \"layer:<name>\" }`), an intrinsic tag, or `Slot` (`{ \"element\": \"Slot\", \"props\": { \"name\": \"children\" } }`, where a slot prop's content lands — but a declared slot fills `root` by default, so a primitive still declares its `children` slot prop yet needs no `Slot` node or `children` entry for it, and a `Slot` node is only for landing that content in a nested layer); `children` lists sibling node keys from the `root` node, never a prop name; `text` is a fixed string; `visible` is a condition on a prop (`{ \"$state\": \"<prop>\" }`, or with `eq`); content shown in a nested layer is a route, `children: { \"type\": \"forward\", \"target\": \"label/children\" }`. `$state` appears only in `visible` and in an `element` a prop chooses, never as a prop value. A glyph is a node of its own, `{ \"element\": { \"__ref\": \"icon:<library>/<Name>\" } }`, listed in the `children` of the layer node that holds it, never a prop value. Text a prop supplies to a text layer is never a node either: declare the prop `{ \"type\": \"forward\", \"target\": \"<layer>/children\" }` and the layer shows it; a `Slot` node goes only under a layer that takes nodes. A style rule is `\"styles\": { \"*\": { \"when\": null, \"layers\": { \"root\": { \"bg\": \"surface\" } } } }`, keyed by a name, with each layer's bag under `layers`. A composed component carries its own styles: give it an unconditional (`\"*\"`) rule that lays out and surfaces it through the system's style properties — spacing, alignment and gap on the container, a background and color where it has one — rather than leaning on the bare primitives, which paint flat. Style a layer only with the style props the primitive it renders exposes, set to the values those props accept: `component/get` on the primitive lists both, so read it and choose from that rather than reaching for a CSS name or value the system has no style property for. Set `previewProps` (or `defaultProps`) so the component previews with content; a root that takes children renders empty otherwise. A style rule's layer bag is keyed by style-prop name (`fontWeight`, `color`), never by CSS property name, and each value is one of that prop's values.";
|
|
301
302
|
readonly example: ({
|
|
302
303
|
config
|
|
303
304
|
}: {
|
|
@@ -309,6 +310,27 @@ declare const System: ConfigClass<{
|
|
|
309
310
|
data: Record<string, unknown>;
|
|
310
311
|
};
|
|
311
312
|
};
|
|
313
|
+
readonly 'create-blank': {
|
|
314
|
+
readonly input: _$zod.ZodObject<{
|
|
315
|
+
path: _$zod.ZodType<string, string | undefined, _$zod_v4_core0.$ZodTypeInternals<string, string | undefined>>;
|
|
316
|
+
}, _$zod_v4_core0.$strip>;
|
|
317
|
+
readonly readOnly: false;
|
|
318
|
+
readonly label: "Create blank";
|
|
319
|
+
readonly description: "Create an empty component at a new qualified `path`, to design on the canvas first: one `div` root layer and the node that renders it, with no props, no variants, no slot, no styles and no preview content. This is exactly what Studio's \"+\" creates. Takes only `path`. Use it for \"a new component\", \"a blank component\" or \"start a component from nothing\"; `create` is for a component whose body is already known.";
|
|
320
|
+
readonly scope: "item";
|
|
321
|
+
readonly creates: true;
|
|
322
|
+
readonly title: (entity: string) => string;
|
|
323
|
+
readonly example: ({
|
|
324
|
+
config
|
|
325
|
+
}: {
|
|
326
|
+
config: Config;
|
|
327
|
+
kind: string;
|
|
328
|
+
path: string;
|
|
329
|
+
}) => {
|
|
330
|
+
path: string;
|
|
331
|
+
};
|
|
332
|
+
readonly handler: (input: Record<string, unknown>, config: Config) => Config;
|
|
333
|
+
};
|
|
312
334
|
readonly 'sub-create/anatomy': {
|
|
313
335
|
readonly description: "Add one anatomy node (`key` + `data`) to a component. In a batch, create child nodes before a parent whose `children` or `slots` names them; each referenced node must already exist when this operation runs.";
|
|
314
336
|
};
|
|
@@ -838,7 +860,7 @@ declare const System: ConfigClass<{
|
|
|
838
860
|
__ref: _$zod.ZodString;
|
|
839
861
|
}, _$zod_v4_core0.$strip>>;
|
|
840
862
|
}, _$zod_v4_core0.$strip>, "modifier", Record<never, never>, Record<never, never>, false>;
|
|
841
|
-
styleProps: EntityClass<_$zod.ZodObject<{
|
|
863
|
+
styleProps: Omit<EntityClass<_$zod.ZodObject<{
|
|
842
864
|
properties: _$zod.ZodArray<_$zod.ZodString>;
|
|
843
865
|
values: _$zod.ZodOptional<_$zod.ZodArray<_$zod.ZodType<StylePropValue, unknown, _$zod_v4_core0.$ZodTypeInternals<StylePropValue, unknown>>>>;
|
|
844
866
|
responsive: _$zod.ZodDefault<_$zod.ZodBoolean>;
|
|
@@ -864,7 +886,19 @@ declare const System: ConfigClass<{
|
|
|
864
886
|
data: Record<string, unknown>;
|
|
865
887
|
} | undefined;
|
|
866
888
|
};
|
|
867
|
-
}, Record<never, never>, false
|
|
889
|
+
}, Record<never, never>, false>, "ref"> & {
|
|
890
|
+
ref<const Path extends PathOf<"style-property">>(path: Path): ReturnType<(path: string) => ExtendableRef<Partial<CreateInput<_$zod.ZodObject<{
|
|
891
|
+
properties: _$zod.ZodArray<_$zod.ZodString>;
|
|
892
|
+
values: _$zod.ZodOptional<_$zod.ZodArray<_$zod.ZodType<StylePropValue, unknown, _$zod_v4_core0.$ZodTypeInternals<StylePropValue, unknown>>>>;
|
|
893
|
+
responsive: _$zod.ZodDefault<_$zod.ZodBoolean>;
|
|
894
|
+
classPrefix: _$zod.ZodOptional<_$zod.ZodString>;
|
|
895
|
+
arbitrary: _$zod.ZodDefault<_$zod.ZodBoolean>;
|
|
896
|
+
negates: _$zod.ZodDefault<_$zod.ZodBoolean>;
|
|
897
|
+
opacityOf: _$zod.ZodOptional<_$zod.ZodLazy<_$zod.ZodType<Ref, unknown, _$zod_v4_core0.$ZodTypeInternals<Ref, unknown>>>>;
|
|
898
|
+
}, _$zod_v4_core0.$strip>>>>> & {
|
|
899
|
+
readonly __ref: `style-property:${Path}`;
|
|
900
|
+
};
|
|
901
|
+
};
|
|
868
902
|
composites: EntityClass<_$zod.ZodObject<{
|
|
869
903
|
styles: SubEntityClass<_$zod.ZodType<StyleValue, unknown, _$zod_v4_core0.$ZodTypeInternals<StyleValue, unknown>>>;
|
|
870
904
|
}, _$zod_v4_core0.$strip>, _$zod.ZodObject<Record<never, never>, _$zod_v4_core0.$strip>, "composite", Record<never, never>, Record<never, never>, false>;
|
|
@@ -1672,7 +1706,7 @@ declare const System: ConfigClass<{
|
|
|
1672
1706
|
}, _$zod_v4_core0.$strip>>;
|
|
1673
1707
|
export: _$zod.ZodOptional<_$zod.ZodString>;
|
|
1674
1708
|
}, _$zod_v4_core0.$strict>;
|
|
1675
|
-
readonly description: "Create a component at a new qualified `path`. When its complete body is known, include all layers, anatomy, props, defaults, and styles in this one operation. `data.layers` maps each stable layer name to the element it renders and must include `root` — a tag for a primitive (`{ \"layers\": { \"root\": \"div\" } }`), and for anything built on top, a ref to a primitive (`{ \"root\": { \"__ref\": \"component:Box\" }, \"label\": { \"__ref\": \"component:Text\" } }`), which is what lets the layer take that primitive's style props. A primitive exposes style props as `{ \"type\": \"styleProperty\", \"value\": { \"__ref\": \"style-property:bg\" } }` and declares `children: { \"type\": \"slot\", \"text\": true }` when it holds content — without the slot, nothing nested inside it renders. A composed component exposes a layer's props at its own top level through `forwards`, keyed by layer: `{ \"forwards\": { \"root\": \"*\" } }` passes every prop the root's element takes (so `<Button width=\"full\">` reaches the root's `width`), and a list of member refs (`[{ \"__ref\": \"component:Box#props/width\" }]`, each naming the component that declares the prop) passes only those. A prop a layer already exposes is forwarded, never redeclared in `props`; a `props` entry of `{ \"type\": \"forward\" }` is the reverse route, one of this component's props into a layer's. `anatomy` is the tree the build would read off a render: each node renders a layer (`{ \"__ref\": \"layer:<name>\" }`), an intrinsic tag, or `Slot` (`{ \"element\": \"Slot\", \"props\": { \"name\": \"children\" } }`, where a slot prop's content lands — but a declared slot fills `root` by default, so a primitive still declares its `children` slot prop yet needs no `Slot` node or `children` entry for it, and a `Slot` node is only for landing that content in a nested layer); `children` lists sibling node keys from the `root` node, never a prop name; `text` is a fixed string; `visible` is a condition on a prop (`{ \"$state\": \"<prop>\" }`, or with `eq`); content shown in a nested layer is a route, `children: { \"type\": \"forward\", \"target\": \"label/children\" }`. `$state` appears only in `visible` and in an `element` a prop chooses, never as a prop value. A glyph is a node of its own, `{ \"element\": { \"__ref\": \"icon:<library>/<Name>\" } }`, listed in the `children` of the layer node that holds it, never a prop value. Text a prop supplies to a text layer is never a node either: declare the prop `{ \"type\": \"forward\", \"target\": \"<layer>/children\" }` and the layer shows it; a `Slot` node goes only under a layer that takes nodes. A style rule is `\"styles\": { \"*\": { \"when\": null, \"layers\": { \"root\": { \"bg\": \"surface\" } } } }`, keyed by a name, with each layer's bag under `layers`. A composed component carries its own styles: give it an unconditional (`\"*\"`) rule that lays out and surfaces it through the system's style properties — spacing, alignment and gap on the container, a background and color where it has one — rather than leaning on the bare primitives, which paint flat. Style a layer only with the style props the primitive it renders exposes, set to the values those props accept: `component/get` on the primitive lists both, so read it and choose from that rather than reaching for a CSS name or value the system has no style property for. Set `previewProps` (or `defaultProps`) so the component previews with content; a root that takes children renders empty otherwise. A style rule's layer bag is keyed by style-prop name (`fontWeight`, `color`), never by CSS property name, and each value is one of that prop's values.";
|
|
1709
|
+
readonly description: "Create a component at a new qualified `path`. For a component with nothing in it yet, one to design on the canvas before it has props or variants, use `create-blank` with only a `path` instead of authoring a minimal body here. When its complete body is known, include all layers, anatomy, props, defaults, and styles in this one operation. `data.layers` maps each stable layer name to the element it renders and must include `root` — a tag for a primitive (`{ \"layers\": { \"root\": \"div\" } }`), and for anything built on top, a ref to a primitive (`{ \"root\": { \"__ref\": \"component:Box\" }, \"label\": { \"__ref\": \"component:Text\" } }`), which is what lets the layer take that primitive's style props. A primitive exposes style props as `{ \"type\": \"styleProperty\", \"value\": { \"__ref\": \"style-property:bg\" } }` and declares `children: { \"type\": \"slot\", \"text\": true }` when it holds content — without the slot, nothing nested inside it renders. A composed component exposes a layer's props at its own top level through `forwards`, keyed by layer: `{ \"forwards\": { \"root\": \"*\" } }` passes every prop the root's element takes (so `<Button width=\"full\">` reaches the root's `width`), and a list of member refs (`[{ \"__ref\": \"component:Box#props/width\" }]`, each naming the component that declares the prop) passes only those. A prop a layer already exposes is forwarded, never redeclared in `props`; a `props` entry of `{ \"type\": \"forward\" }` is the reverse route, one of this component's props into a layer's. `anatomy` is the tree the build would read off a render: each node renders a layer (`{ \"__ref\": \"layer:<name>\" }`), an intrinsic tag, or `Slot` (`{ \"element\": \"Slot\", \"props\": { \"name\": \"children\" } }`, where a slot prop's content lands — but a declared slot fills `root` by default, so a primitive still declares its `children` slot prop yet needs no `Slot` node or `children` entry for it, and a `Slot` node is only for landing that content in a nested layer); `children` lists sibling node keys from the `root` node, never a prop name; `text` is a fixed string; `visible` is a condition on a prop (`{ \"$state\": \"<prop>\" }`, or with `eq`); content shown in a nested layer is a route, `children: { \"type\": \"forward\", \"target\": \"label/children\" }`. `$state` appears only in `visible` and in an `element` a prop chooses, never as a prop value. A glyph is a node of its own, `{ \"element\": { \"__ref\": \"icon:<library>/<Name>\" } }`, listed in the `children` of the layer node that holds it, never a prop value. Text a prop supplies to a text layer is never a node either: declare the prop `{ \"type\": \"forward\", \"target\": \"<layer>/children\" }` and the layer shows it; a `Slot` node goes only under a layer that takes nodes. A style rule is `\"styles\": { \"*\": { \"when\": null, \"layers\": { \"root\": { \"bg\": \"surface\" } } } }`, keyed by a name, with each layer's bag under `layers`. A composed component carries its own styles: give it an unconditional (`\"*\"`) rule that lays out and surfaces it through the system's style properties — spacing, alignment and gap on the container, a background and color where it has one — rather than leaning on the bare primitives, which paint flat. Style a layer only with the style props the primitive it renders exposes, set to the values those props accept: `component/get` on the primitive lists both, so read it and choose from that rather than reaching for a CSS name or value the system has no style property for. Set `previewProps` (or `defaultProps`) so the component previews with content; a root that takes children renders empty otherwise. A style rule's layer bag is keyed by style-prop name (`fontWeight`, `color`), never by CSS property name, and each value is one of that prop's values.";
|
|
1676
1710
|
readonly example: ({
|
|
1677
1711
|
config
|
|
1678
1712
|
}: {
|
|
@@ -1684,6 +1718,27 @@ declare const System: ConfigClass<{
|
|
|
1684
1718
|
data: Record<string, unknown>;
|
|
1685
1719
|
};
|
|
1686
1720
|
};
|
|
1721
|
+
readonly 'create-blank': {
|
|
1722
|
+
readonly input: _$zod.ZodObject<{
|
|
1723
|
+
path: _$zod.ZodType<string, string | undefined, _$zod_v4_core0.$ZodTypeInternals<string, string | undefined>>;
|
|
1724
|
+
}, _$zod_v4_core0.$strip>;
|
|
1725
|
+
readonly readOnly: false;
|
|
1726
|
+
readonly label: "Create blank";
|
|
1727
|
+
readonly description: "Create an empty component at a new qualified `path`, to design on the canvas first: one `div` root layer and the node that renders it, with no props, no variants, no slot, no styles and no preview content. This is exactly what Studio's \"+\" creates. Takes only `path`. Use it for \"a new component\", \"a blank component\" or \"start a component from nothing\"; `create` is for a component whose body is already known.";
|
|
1728
|
+
readonly scope: "item";
|
|
1729
|
+
readonly creates: true;
|
|
1730
|
+
readonly title: (entity: string) => string;
|
|
1731
|
+
readonly example: ({
|
|
1732
|
+
config
|
|
1733
|
+
}: {
|
|
1734
|
+
config: Config;
|
|
1735
|
+
kind: string;
|
|
1736
|
+
path: string;
|
|
1737
|
+
}) => {
|
|
1738
|
+
path: string;
|
|
1739
|
+
};
|
|
1740
|
+
readonly handler: (input: Record<string, unknown>, config: Config) => Config;
|
|
1741
|
+
};
|
|
1687
1742
|
readonly 'sub-create/anatomy': {
|
|
1688
1743
|
readonly description: "Add one anatomy node (`key` + `data`) to a component. In a batch, create child nodes before a parent whose `children` or `slots` names them; each referenced node must already exist when this operation runs.";
|
|
1689
1744
|
};
|
|
@@ -2213,7 +2268,7 @@ declare const System: ConfigClass<{
|
|
|
2213
2268
|
__ref: _$zod.ZodString;
|
|
2214
2269
|
}, _$zod_v4_core0.$strip>>;
|
|
2215
2270
|
}, _$zod_v4_core0.$strip>, "modifier", Record<never, never>, Record<never, never>, false>;
|
|
2216
|
-
styleProps: EntityClass<_$zod.ZodObject<{
|
|
2271
|
+
styleProps: Omit<EntityClass<_$zod.ZodObject<{
|
|
2217
2272
|
properties: _$zod.ZodArray<_$zod.ZodString>;
|
|
2218
2273
|
values: _$zod.ZodOptional<_$zod.ZodArray<_$zod.ZodType<StylePropValue, unknown, _$zod_v4_core0.$ZodTypeInternals<StylePropValue, unknown>>>>;
|
|
2219
2274
|
responsive: _$zod.ZodDefault<_$zod.ZodBoolean>;
|
|
@@ -2239,7 +2294,19 @@ declare const System: ConfigClass<{
|
|
|
2239
2294
|
data: Record<string, unknown>;
|
|
2240
2295
|
} | undefined;
|
|
2241
2296
|
};
|
|
2242
|
-
}, Record<never, never>, false
|
|
2297
|
+
}, Record<never, never>, false>, "ref"> & {
|
|
2298
|
+
ref<const Path extends PathOf<"style-property">>(path: Path): ReturnType<(path: string) => ExtendableRef<Partial<CreateInput<_$zod.ZodObject<{
|
|
2299
|
+
properties: _$zod.ZodArray<_$zod.ZodString>;
|
|
2300
|
+
values: _$zod.ZodOptional<_$zod.ZodArray<_$zod.ZodType<StylePropValue, unknown, _$zod_v4_core0.$ZodTypeInternals<StylePropValue, unknown>>>>;
|
|
2301
|
+
responsive: _$zod.ZodDefault<_$zod.ZodBoolean>;
|
|
2302
|
+
classPrefix: _$zod.ZodOptional<_$zod.ZodString>;
|
|
2303
|
+
arbitrary: _$zod.ZodDefault<_$zod.ZodBoolean>;
|
|
2304
|
+
negates: _$zod.ZodDefault<_$zod.ZodBoolean>;
|
|
2305
|
+
opacityOf: _$zod.ZodOptional<_$zod.ZodLazy<_$zod.ZodType<Ref, unknown, _$zod_v4_core0.$ZodTypeInternals<Ref, unknown>>>>;
|
|
2306
|
+
}, _$zod_v4_core0.$strip>>>>> & {
|
|
2307
|
+
readonly __ref: `style-property:${Path}`;
|
|
2308
|
+
};
|
|
2309
|
+
};
|
|
2243
2310
|
composites: EntityClass<_$zod.ZodObject<{
|
|
2244
2311
|
styles: SubEntityClass<_$zod.ZodType<StyleValue, unknown, _$zod_v4_core0.$ZodTypeInternals<StyleValue, unknown>>>;
|
|
2245
2312
|
}, _$zod_v4_core0.$strip>, _$zod.ZodObject<Record<never, never>, _$zod_v4_core0.$strip>, "composite", Record<never, never>, Record<never, never>, false>;
|
package/dist/configs/system.js
CHANGED
|
@@ -27,6 +27,7 @@ import { iconKnockoutVariantsMigration } from "../migrations/20260909183001_icon
|
|
|
27
27
|
import { linkedSystemLinkOpsMigration } from "../migrations/20260910212453_linked_system_link_ops.js";
|
|
28
28
|
import { previewConditionsMigration } from "../migrations/20260912161840_preview_conditions.js";
|
|
29
29
|
import { fontVariableMigration } from "../migrations/20260912164927_font_variable.js";
|
|
30
|
+
import { componentCreateBlankOpMigration } from "../migrations/20260914155048_component_create_blank_op.js";
|
|
30
31
|
//#region src/configs/system.ts
|
|
31
32
|
/**
|
|
32
33
|
* `System` — the design-system config TYPE. Declares the exact kinds a design system owns (tokens,
|
|
@@ -74,5 +75,6 @@ if (!registeredSchemaMigrations().has(20260909183001)) registerSchemaMigrations(
|
|
|
74
75
|
if (!registeredSchemaMigrations().has(20260910212453)) registerSchemaMigrations(linkedSystemLinkOpsMigration);
|
|
75
76
|
if (!registeredSchemaMigrations().has(20260912161840)) registerSchemaMigrations(previewConditionsMigration);
|
|
76
77
|
if (!registeredSchemaMigrations().has(20260912164927)) registerSchemaMigrations(fontVariableMigration);
|
|
78
|
+
if (!registeredSchemaMigrations().has(20260914155048)) registerSchemaMigrations(componentCreateBlankOpMigration);
|
|
77
79
|
//#endregion
|
|
78
80
|
export { System };
|
|
@@ -438,6 +438,17 @@ declare const componentFields: z.ZodObject<{
|
|
|
438
438
|
* a surface that needs a field the schema doesn't declare is a gap in the schema, not a cast.
|
|
439
439
|
*/
|
|
440
440
|
type ComponentBody = z.infer<typeof componentFields>;
|
|
441
|
+
/**
|
|
442
|
+
* The body a blank component is created with: one intrinsic `div` layer and the anatomy node that
|
|
443
|
+
* renders it, nothing else. Studio's "+" and the `create-blank` op both write exactly this.
|
|
444
|
+
*
|
|
445
|
+
* Both halves are needed. The kind requires a `root` layer, but layers alone project the component
|
|
446
|
+
* rendering itself, a painting with nothing to compose into; the node is what puts a real `div`
|
|
447
|
+
* carrying the editor's selection markers on the canvas. `div` is an intrinsic tag rather than a
|
|
448
|
+
* system component, so no system is without it. Anything more (a `children` slot, preview content, a
|
|
449
|
+
* style rule) makes the component authored rather than blank, and the editor's drop frame stands down.
|
|
450
|
+
*/
|
|
451
|
+
declare function blankComponentBody(): ComponentBody;
|
|
441
452
|
declare const ComponentEntity: EntityClass<z.ZodObject<{
|
|
442
453
|
layers: SubEntityClass<z.ZodUnion<readonly [z.ZodString, z.ZodLazy<z.ZodType<Ref, unknown, z.core.$ZodTypeInternals<Ref, unknown>>>, EntityClass<z.ZodObject<{
|
|
443
454
|
version: z.ZodOptional<z.ZodString>;
|
|
@@ -671,7 +682,7 @@ declare const ComponentEntity: EntityClass<z.ZodObject<{
|
|
|
671
682
|
}, z.core.$strip>>;
|
|
672
683
|
export: z.ZodOptional<z.ZodString>;
|
|
673
684
|
}, z.core.$strict>;
|
|
674
|
-
readonly description: "Create a component at a new qualified `path`. When its complete body is known, include all layers, anatomy, props, defaults, and styles in this one operation. `data.layers` maps each stable layer name to the element it renders and must include `root` — a tag for a primitive (`{ \"layers\": { \"root\": \"div\" } }`), and for anything built on top, a ref to a primitive (`{ \"root\": { \"__ref\": \"component:Box\" }, \"label\": { \"__ref\": \"component:Text\" } }`), which is what lets the layer take that primitive's style props. A primitive exposes style props as `{ \"type\": \"styleProperty\", \"value\": { \"__ref\": \"style-property:bg\" } }` and declares `children: { \"type\": \"slot\", \"text\": true }` when it holds content — without the slot, nothing nested inside it renders. A composed component exposes a layer's props at its own top level through `forwards`, keyed by layer: `{ \"forwards\": { \"root\": \"*\" } }` passes every prop the root's element takes (so `<Button width=\"full\">` reaches the root's `width`), and a list of member refs (`[{ \"__ref\": \"component:Box#props/width\" }]`, each naming the component that declares the prop) passes only those. A prop a layer already exposes is forwarded, never redeclared in `props`; a `props` entry of `{ \"type\": \"forward\" }` is the reverse route, one of this component's props into a layer's. `anatomy` is the tree the build would read off a render: each node renders a layer (`{ \"__ref\": \"layer:<name>\" }`), an intrinsic tag, or `Slot` (`{ \"element\": \"Slot\", \"props\": { \"name\": \"children\" } }`, where a slot prop's content lands — but a declared slot fills `root` by default, so a primitive still declares its `children` slot prop yet needs no `Slot` node or `children` entry for it, and a `Slot` node is only for landing that content in a nested layer); `children` lists sibling node keys from the `root` node, never a prop name; `text` is a fixed string; `visible` is a condition on a prop (`{ \"$state\": \"<prop>\" }`, or with `eq`); content shown in a nested layer is a route, `children: { \"type\": \"forward\", \"target\": \"label/children\" }`. `$state` appears only in `visible` and in an `element` a prop chooses, never as a prop value. A glyph is a node of its own, `{ \"element\": { \"__ref\": \"icon:<library>/<Name>\" } }`, listed in the `children` of the layer node that holds it, never a prop value. Text a prop supplies to a text layer is never a node either: declare the prop `{ \"type\": \"forward\", \"target\": \"<layer>/children\" }` and the layer shows it; a `Slot` node goes only under a layer that takes nodes. A style rule is `\"styles\": { \"*\": { \"when\": null, \"layers\": { \"root\": { \"bg\": \"surface\" } } } }`, keyed by a name, with each layer's bag under `layers`. A composed component carries its own styles: give it an unconditional (`\"*\"`) rule that lays out and surfaces it through the system's style properties — spacing, alignment and gap on the container, a background and color where it has one — rather than leaning on the bare primitives, which paint flat. Style a layer only with the style props the primitive it renders exposes, set to the values those props accept: `component/get` on the primitive lists both, so read it and choose from that rather than reaching for a CSS name or value the system has no style property for. Set `previewProps` (or `defaultProps`) so the component previews with content; a root that takes children renders empty otherwise. A style rule's layer bag is keyed by style-prop name (`fontWeight`, `color`), never by CSS property name, and each value is one of that prop's values.";
|
|
685
|
+
readonly description: "Create a component at a new qualified `path`. For a component with nothing in it yet, one to design on the canvas before it has props or variants, use `create-blank` with only a `path` instead of authoring a minimal body here. When its complete body is known, include all layers, anatomy, props, defaults, and styles in this one operation. `data.layers` maps each stable layer name to the element it renders and must include `root` — a tag for a primitive (`{ \"layers\": { \"root\": \"div\" } }`), and for anything built on top, a ref to a primitive (`{ \"root\": { \"__ref\": \"component:Box\" }, \"label\": { \"__ref\": \"component:Text\" } }`), which is what lets the layer take that primitive's style props. A primitive exposes style props as `{ \"type\": \"styleProperty\", \"value\": { \"__ref\": \"style-property:bg\" } }` and declares `children: { \"type\": \"slot\", \"text\": true }` when it holds content — without the slot, nothing nested inside it renders. A composed component exposes a layer's props at its own top level through `forwards`, keyed by layer: `{ \"forwards\": { \"root\": \"*\" } }` passes every prop the root's element takes (so `<Button width=\"full\">` reaches the root's `width`), and a list of member refs (`[{ \"__ref\": \"component:Box#props/width\" }]`, each naming the component that declares the prop) passes only those. A prop a layer already exposes is forwarded, never redeclared in `props`; a `props` entry of `{ \"type\": \"forward\" }` is the reverse route, one of this component's props into a layer's. `anatomy` is the tree the build would read off a render: each node renders a layer (`{ \"__ref\": \"layer:<name>\" }`), an intrinsic tag, or `Slot` (`{ \"element\": \"Slot\", \"props\": { \"name\": \"children\" } }`, where a slot prop's content lands — but a declared slot fills `root` by default, so a primitive still declares its `children` slot prop yet needs no `Slot` node or `children` entry for it, and a `Slot` node is only for landing that content in a nested layer); `children` lists sibling node keys from the `root` node, never a prop name; `text` is a fixed string; `visible` is a condition on a prop (`{ \"$state\": \"<prop>\" }`, or with `eq`); content shown in a nested layer is a route, `children: { \"type\": \"forward\", \"target\": \"label/children\" }`. `$state` appears only in `visible` and in an `element` a prop chooses, never as a prop value. A glyph is a node of its own, `{ \"element\": { \"__ref\": \"icon:<library>/<Name>\" } }`, listed in the `children` of the layer node that holds it, never a prop value. Text a prop supplies to a text layer is never a node either: declare the prop `{ \"type\": \"forward\", \"target\": \"<layer>/children\" }` and the layer shows it; a `Slot` node goes only under a layer that takes nodes. A style rule is `\"styles\": { \"*\": { \"when\": null, \"layers\": { \"root\": { \"bg\": \"surface\" } } } }`, keyed by a name, with each layer's bag under `layers`. A composed component carries its own styles: give it an unconditional (`\"*\"`) rule that lays out and surfaces it through the system's style properties — spacing, alignment and gap on the container, a background and color where it has one — rather than leaning on the bare primitives, which paint flat. Style a layer only with the style props the primitive it renders exposes, set to the values those props accept: `component/get` on the primitive lists both, so read it and choose from that rather than reaching for a CSS name or value the system has no style property for. Set `previewProps` (or `defaultProps`) so the component previews with content; a root that takes children renders empty otherwise. A style rule's layer bag is keyed by style-prop name (`fontWeight`, `color`), never by CSS property name, and each value is one of that prop's values.";
|
|
675
686
|
readonly example: ({
|
|
676
687
|
config
|
|
677
688
|
}: {
|
|
@@ -683,6 +694,33 @@ declare const ComponentEntity: EntityClass<z.ZodObject<{
|
|
|
683
694
|
data: Record<string, unknown>;
|
|
684
695
|
};
|
|
685
696
|
};
|
|
697
|
+
/**
|
|
698
|
+
* A component with nothing in it yet, as Studio's "+" makes one. Its own op because `create`
|
|
699
|
+
* teaches the full grammar, and a model asked for a blank component authors a `children` slot and
|
|
700
|
+
* preview content from it, at which point the component is no longer blank. Decomposes into the one
|
|
701
|
+
* `create` patch the rail writes, so the changes list and undo read both gestures alike.
|
|
702
|
+
*/
|
|
703
|
+
readonly 'create-blank': {
|
|
704
|
+
readonly input: z.ZodObject<{
|
|
705
|
+
path: z.ZodType<string, string | undefined, z.core.$ZodTypeInternals<string, string | undefined>>;
|
|
706
|
+
}, z.core.$strip>;
|
|
707
|
+
readonly readOnly: false;
|
|
708
|
+
readonly label: "Create blank";
|
|
709
|
+
readonly description: "Create an empty component at a new qualified `path`, to design on the canvas first: one `div` root layer and the node that renders it, with no props, no variants, no slot, no styles and no preview content. This is exactly what Studio's \"+\" creates. Takes only `path`. Use it for \"a new component\", \"a blank component\" or \"start a component from nothing\"; `create` is for a component whose body is already known.";
|
|
710
|
+
readonly scope: "item";
|
|
711
|
+
readonly creates: true;
|
|
712
|
+
readonly title: (entity: string) => string;
|
|
713
|
+
readonly example: ({
|
|
714
|
+
config
|
|
715
|
+
}: {
|
|
716
|
+
config: Config;
|
|
717
|
+
kind: string;
|
|
718
|
+
path: string;
|
|
719
|
+
}) => {
|
|
720
|
+
path: string;
|
|
721
|
+
};
|
|
722
|
+
readonly handler: (input: Record<string, unknown>, config: Config) => Config;
|
|
723
|
+
};
|
|
686
724
|
readonly 'sub-create/anatomy': {
|
|
687
725
|
readonly description: "Add one anatomy node (`key` + `data`) to a component. In a batch, create child nodes before a parent whose `children` or `slots` names them; each referenced node must already exist when this operation runs.";
|
|
688
726
|
};
|
|
@@ -1297,4 +1335,4 @@ declare const Component: Omit<typeof ComponentEntity, "ref"> & {
|
|
|
1297
1335
|
ref<const Path extends PathOf<"component">>(path: Path): ComponentReference<ComponentContractOf<Path>>;
|
|
1298
1336
|
};
|
|
1299
1337
|
//#endregion
|
|
1300
|
-
export { AuthoredPropBody, Component, ComponentBody, ComponentElementBody, ComponentPropBody, ComponentReference, ComponentStyleBody, ElementVisibility, ElementVisibilityInput, ExtendedComponentRef, ProjectedVisibility, VariantValueBody, VariantValues, canonicalWhen, forwardedNames, layerRef, ownValues, ownsItsValues, valueRef };
|
|
1338
|
+
export { AuthoredPropBody, Component, ComponentBody, ComponentElementBody, ComponentPropBody, ComponentReference, ComponentStyleBody, ElementVisibility, ElementVisibilityInput, ExtendedComponentRef, ProjectedVisibility, VariantValueBody, VariantValues, blankComponentBody, canonicalWhen, forwardedNames, layerRef, ownValues, ownsItsValues, valueRef };
|