@yahoo/uds-create-config 5.68.5 → 5.70.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/react-native-system.d.ts +18 -0
- package/dist/configs/system.js +4 -0
- package/dist/entities/native/NativeSettings.d.ts +18 -0
- package/dist/entities/system/Component.js +19 -1
- package/dist/entities/system/LinkedSystem.d.ts +2 -0
- package/dist/entities/system/LinkedSystem.js +14 -4
- package/dist/entities/system/Settings.d.ts +72 -1
- package/dist/entities/system/Settings.js +58 -6
- package/dist/entities/system/link-plan.d.ts +34 -1
- package/dist/entities/system/link-plan.js +157 -2
- package/dist/framework/Config.d.ts +11 -1
- package/dist/framework/Config.js +31 -2
- package/dist/framework/class-names.d.ts +1 -1
- package/dist/framework/component-api-changes.d.ts +14 -1
- package/dist/framework/component-api-changes.js +22 -6
- package/dist/framework/component-states.d.ts +16 -1
- package/dist/framework/component-states.js +17 -1
- package/dist/framework/defineEntity.d.ts +2 -1
- package/dist/framework/defineEntity.js +1 -0
- package/dist/framework/plan.d.ts +5 -0
- package/dist/framework/plan.js +9 -2
- package/dist/framework/registry.d.ts +5 -0
- package/dist/framework/registry.js +2 -1
- package/dist/framework/schema-version.d.ts +1 -1
- package/dist/framework/schema-version.js +5 -5
- package/dist/index.d.ts +5 -5
- package/dist/index.js +4 -4
- package/dist/migrations/20261102143821_default_colors.d.ts +12 -0
- package/dist/migrations/20261102143821_default_colors.js +10 -0
- package/dist/migrations/20261102185610_link_replace.d.ts +7 -0
- package/dist/migrations/20261102185610_link_replace.js +8 -0
- package/dist/spec/bake.js +35 -2
- package/dist/spec/cell.js +11 -2
- package/dist/spec/index.d.ts +2 -2
- package/dist/spec/index.js +2 -2
- package/dist/spec/preview-content.js +3 -1
- package/dist/spec/preview-elements.d.ts +12 -4
- package/dist/spec/preview-elements.js +6 -1
- package/dist/spec/rewrite-refs.d.ts +14 -2
- package/dist/spec/rewrite-refs.js +30 -10
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
|
@@ -76,6 +76,24 @@ declare const ReactNativeSystemDefinition: ConfigClass<{
|
|
|
76
76
|
reason: _$zod.ZodString;
|
|
77
77
|
}, _$zod_v4_core0.$strict>>>;
|
|
78
78
|
}, _$zod_v4_core0.$strict>>;
|
|
79
|
+
defaults: _$zod.ZodOptional<_$zod.ZodObject<{
|
|
80
|
+
background: _$zod.ZodOptional<_$zod.ZodUnion<readonly [_$zod.ZodUnion<readonly [_$zod.ZodString, _$zod.ZodObject<{
|
|
81
|
+
__ref: _$zod.ZodString;
|
|
82
|
+
}, _$zod_v4_core0.$strip>]>, _$zod.ZodObject<{
|
|
83
|
+
value: _$zod.ZodUnion<readonly [_$zod.ZodString, _$zod.ZodObject<{
|
|
84
|
+
__ref: _$zod.ZodString;
|
|
85
|
+
}, _$zod_v4_core0.$strip>]>;
|
|
86
|
+
output: _$zod.ZodOptional<_$zod.ZodBoolean>;
|
|
87
|
+
}, _$zod_v4_core0.$strict>]>>;
|
|
88
|
+
color: _$zod.ZodOptional<_$zod.ZodUnion<readonly [_$zod.ZodUnion<readonly [_$zod.ZodString, _$zod.ZodObject<{
|
|
89
|
+
__ref: _$zod.ZodString;
|
|
90
|
+
}, _$zod_v4_core0.$strip>]>, _$zod.ZodObject<{
|
|
91
|
+
value: _$zod.ZodUnion<readonly [_$zod.ZodString, _$zod.ZodObject<{
|
|
92
|
+
__ref: _$zod.ZodString;
|
|
93
|
+
}, _$zod_v4_core0.$strip>]>;
|
|
94
|
+
output: _$zod.ZodOptional<_$zod.ZodBoolean>;
|
|
95
|
+
}, _$zod_v4_core0.$strict>]>>;
|
|
96
|
+
}, _$zod_v4_core0.$strict>>;
|
|
79
97
|
}, "css" | "playground" | "canvas"> & {
|
|
80
98
|
canvas: _$zod.ZodOptional<_$zod.ZodObject<{
|
|
81
99
|
packageAliases: _$zod.ZodOptional<_$zod.ZodRecord<_$zod.ZodString, _$zod.ZodString>>;
|
package/dist/configs/system.js
CHANGED
|
@@ -35,6 +35,8 @@ import { variantValuesListWithBodiesMigration } from "../migrations/202610271844
|
|
|
35
35
|
import { lintIgnoreMigration } from "../migrations/20261027205147_lint_ignore.js";
|
|
36
36
|
import { componentMapPropsMigration } from "../migrations/20261030134149_component_map_props.js";
|
|
37
37
|
import { layerPrefixMigration } from "../migrations/20261030163028_layer_prefix.js";
|
|
38
|
+
import { defaultColorsMigration } from "../migrations/20261102143821_default_colors.js";
|
|
39
|
+
import { linkReplaceMigration } from "../migrations/20261102185610_link_replace.js";
|
|
38
40
|
import { CanvasRole } from "../entities/system/CanvasRole.js";
|
|
39
41
|
import { GlobalStyle } from "../entities/system/GlobalStyle.js";
|
|
40
42
|
import { Guidance } from "../entities/system/Guidance.js";
|
|
@@ -203,5 +205,7 @@ if (!registeredSchemaMigrations().has(20261027184442)) registerSchemaMigrations(
|
|
|
203
205
|
if (!registeredSchemaMigrations().has(20261027205147)) registerSchemaMigrations(lintIgnoreMigration);
|
|
204
206
|
if (!registeredSchemaMigrations().has(20261030134149)) registerSchemaMigrations(componentMapPropsMigration);
|
|
205
207
|
if (!registeredSchemaMigrations().has(20261030163028)) registerSchemaMigrations(layerPrefixMigration);
|
|
208
|
+
if (!registeredSchemaMigrations().has(20261102143821)) registerSchemaMigrations(defaultColorsMigration);
|
|
209
|
+
if (!registeredSchemaMigrations().has(20261102185610)) registerSchemaMigrations(linkReplaceMigration);
|
|
206
210
|
//#endregion
|
|
207
211
|
export { System };
|
|
@@ -65,6 +65,24 @@ declare const NativeSettings: EntityClass<z.ZodObject<Omit<{
|
|
|
65
65
|
reason: z.ZodString;
|
|
66
66
|
}, z.core.$strict>>>;
|
|
67
67
|
}, z.core.$strict>>;
|
|
68
|
+
defaults: z.ZodOptional<z.ZodObject<{
|
|
69
|
+
background: z.ZodOptional<z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
70
|
+
__ref: z.ZodString;
|
|
71
|
+
}, z.core.$strip>]>, z.ZodObject<{
|
|
72
|
+
value: z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
73
|
+
__ref: z.ZodString;
|
|
74
|
+
}, z.core.$strip>]>;
|
|
75
|
+
output: z.ZodOptional<z.ZodBoolean>;
|
|
76
|
+
}, z.core.$strict>]>>;
|
|
77
|
+
color: z.ZodOptional<z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
78
|
+
__ref: z.ZodString;
|
|
79
|
+
}, z.core.$strip>]>, z.ZodObject<{
|
|
80
|
+
value: z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
81
|
+
__ref: z.ZodString;
|
|
82
|
+
}, z.core.$strip>]>;
|
|
83
|
+
output: z.ZodOptional<z.ZodBoolean>;
|
|
84
|
+
}, z.core.$strict>]>>;
|
|
85
|
+
}, z.core.$strict>>;
|
|
68
86
|
}, "css" | "playground" | "canvas"> & {
|
|
69
87
|
canvas: z.ZodOptional<z.ZodObject<{
|
|
70
88
|
packageAliases: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
@@ -152,6 +152,19 @@ function freeLayerKey(config, path, hint = "el") {
|
|
|
152
152
|
return `${hint}${ordinal}`;
|
|
153
153
|
}
|
|
154
154
|
/**
|
|
155
|
+
* The name a duplicate of the layer `source` takes: its name without a trailing number, numbered
|
|
156
|
+
* from 2 past every name the component already holds, so `box` copies to `box2` and `box2` to
|
|
157
|
+
* `box3` rather than `box21`.
|
|
158
|
+
*/
|
|
159
|
+
function duplicateLayerKey({ config, path, source }) {
|
|
160
|
+
const body = config.resolve("component", path)?.toJSON();
|
|
161
|
+
const taken = new Set([...Object.keys(body?.layers ?? {}), ...Object.keys(body?.anatomy ?? {})]);
|
|
162
|
+
const base = source.replace(/\d+$/, "") || source;
|
|
163
|
+
let ordinal = 2;
|
|
164
|
+
while (taken.has(`${base}${ordinal}`)) ordinal += 1;
|
|
165
|
+
return `${base}${ordinal}`;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
155
168
|
* A `kind:path` marker string as the ref it means.
|
|
156
169
|
*
|
|
157
170
|
* A spec element stores its type as a marker (`component:primitives/Box`), and `element` accepts a
|
|
@@ -2026,6 +2039,7 @@ function withoutProps(conditions, names) {
|
|
|
2026
2039
|
}
|
|
2027
2040
|
const ComponentEntity = defineEntity({
|
|
2028
2041
|
kind: "component",
|
|
2042
|
+
parts: true,
|
|
2029
2043
|
rebaseLinkedBody: (args) => {
|
|
2030
2044
|
const body = { ...translateLinkedStyleBags({
|
|
2031
2045
|
...args,
|
|
@@ -2427,7 +2441,11 @@ count: z.number().int().min(1).max(50).optional() }).prefault({})
|
|
|
2427
2441
|
let next = config;
|
|
2428
2442
|
let previous = source;
|
|
2429
2443
|
for (let n = 0; n < count; n++) {
|
|
2430
|
-
const key =
|
|
2444
|
+
const key = duplicateLayerKey({
|
|
2445
|
+
config: next,
|
|
2446
|
+
path,
|
|
2447
|
+
source
|
|
2448
|
+
});
|
|
2431
2449
|
const siblings = (next.resolve("component", path)?.toJSON())?.anatomy?.[parent]?.children ?? [];
|
|
2432
2450
|
const index = siblings.indexOf(previous) + 1;
|
|
2433
2451
|
next = next.run([{
|
|
@@ -123,6 +123,7 @@ declare const LinkedSystemDefinition: EntityClass<z.ZodObject<{
|
|
|
123
123
|
keep: "keep";
|
|
124
124
|
take: "take";
|
|
125
125
|
}>>;
|
|
126
|
+
replace: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>>>;
|
|
126
127
|
}, z.core.$strip>;
|
|
127
128
|
};
|
|
128
129
|
readonly 'link-plan': {
|
|
@@ -133,6 +134,7 @@ declare const LinkedSystemDefinition: EntityClass<z.ZodObject<{
|
|
|
133
134
|
keep: "keep";
|
|
134
135
|
take: "take";
|
|
135
136
|
}>>;
|
|
137
|
+
replace: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>>>;
|
|
136
138
|
}, z.core.$strip>;
|
|
137
139
|
};
|
|
138
140
|
readonly unlink: {
|
|
@@ -171,7 +171,16 @@ const linkInput = z.object({
|
|
|
171
171
|
data: z.union([z.literal("*"), z.record(z.string(), copyPaths)]),
|
|
172
172
|
/** What to do at a path another linked system provides: `'take'` makes it follow this source,
|
|
173
173
|
* `'keep'` leaves it where it comes from. Required when there is one; `link-plan` lists them. */
|
|
174
|
-
onLinked: z.enum(["keep", "take"]).optional()
|
|
174
|
+
onLinked: z.enum(["keep", "take"]).optional(),
|
|
175
|
+
/**
|
|
176
|
+
* A component this config holds under one name, replaced with the source's of another name, keyed
|
|
177
|
+
* by accessor: `{ components: { SelectContent: 'SelectMenu' } }` replaces the `SelectContent` this
|
|
178
|
+
* config holds with the source's `SelectMenu`. Every ref to `SelectContent` is renamed to
|
|
179
|
+
* `SelectMenu`, so design files and code follow the way they follow a rename, and the system
|
|
180
|
+
* `SelectContent` came through stops deriving it unless its own rows still use it. Each source path
|
|
181
|
+
* is one `data` names; `link-plan` lists each in `replaced`. A take at the same name is `onLinked`.
|
|
182
|
+
*/
|
|
183
|
+
replace: z.record(z.string(), z.record(z.string().min(1), z.string().min(1))).optional()
|
|
175
184
|
});
|
|
176
185
|
const unlinkInput = z.object({
|
|
177
186
|
path: pathInput("linked-system"),
|
|
@@ -216,7 +225,8 @@ function linkPlanInputOf(input) {
|
|
|
216
225
|
return {
|
|
217
226
|
path: String(input.path),
|
|
218
227
|
data: input.data,
|
|
219
|
-
...input.onLinked === void 0 ? {} : { onLinked: input.onLinked }
|
|
228
|
+
...input.onLinked === void 0 ? {} : { onLinked: input.onLinked },
|
|
229
|
+
...input.replace === void 0 ? {} : { replace: input.replace }
|
|
220
230
|
};
|
|
221
231
|
}
|
|
222
232
|
/** A `link` or `unlink` example: one entity the source offers, under the accessor this config files it by. */
|
|
@@ -310,7 +320,7 @@ const LinkedSystemDefinition = defineEntity({
|
|
|
310
320
|
input: linkInput,
|
|
311
321
|
readOnly: false,
|
|
312
322
|
label: "Link from",
|
|
313
|
-
description: "Draw entities from a linked system, following the source: `data` names them by accessor — `{ tokens: ['color/brand', 'color'] }` takes an entity and a folder's members, `{ tokens: '*' }` every token, and `'*'` the whole system. What this config already holds at those paths is replaced by theirs, so run `linked-system/link-plan` with the same input first to see what that is. To hold their values as your own instead, `copy`.",
|
|
323
|
+
description: "Draw entities from a linked system, following the source: `data` names them by accessor — `{ tokens: ['color/brand', 'color'] }` takes an entity and a folder's members, `{ tokens: '*' }` every token, and `'*'` the whole system. What this config already holds at those paths is replaced by theirs, so run `linked-system/link-plan` with the same input first to see what that is. To replace something this config holds under another name (the `SelectContent` it has with the source's `SelectMenu`), name the pair in `replace` (`{ components: { SelectContent: 'SelectMenu' } }`): every reference to the old name moves to the new one, in design files and code too. To hold their values as your own instead, `copy`.",
|
|
314
324
|
scope: "item",
|
|
315
325
|
approval: "reference-change",
|
|
316
326
|
title: (entity) => `Link something from ${entity}`,
|
|
@@ -333,7 +343,7 @@ const LinkedSystemDefinition = defineEntity({
|
|
|
333
343
|
input: linkInput,
|
|
334
344
|
readOnly: true,
|
|
335
345
|
label: "Plan a link",
|
|
336
|
-
description: "What `link` with the same input replaces — rows of yours deleted so the source shows through, every path another linked system provides (`linked`, turned into extensions when `onLinked` says take), the `options` entries another linked system holds at what a take moves, which it removes since they would apply to nothing (`dropped`), members left alone because they are already here from the same origin, paths another linked system declares that the link reaches as a different entity (`settled`), whose row stays, and why the config would refuse the link (`blocked`), a collision it would leave among them. Writes nothing.",
|
|
346
|
+
description: "What `link` with the same input replaces — rows of yours deleted so the source shows through, every path another linked system provides (`linked`, turned into extensions when `onLinked` says take), the `options` entries another linked system holds at what a take moves, which it removes since they would apply to nothing (`dropped`), members left alone because they are already here from the same origin, paths another linked system declares that the link reaches as a different entity (`settled`), whose row stays, what `replace` replaces under another name (`replaced`: each path, what replaces it, the pin it came through, and whether it is left out of that pin or kept because rows of that pin still use it), and why the config would refuse the link (`blocked`), a collision it would leave among them. Writes nothing.",
|
|
337
347
|
scope: "item",
|
|
338
348
|
title: (entity) => `Plan a link from ${entity}`,
|
|
339
349
|
example: linkExample,
|
|
@@ -121,6 +121,59 @@ declare const LintSectionDefinition: SubEntityClass<z.ZodObject<{
|
|
|
121
121
|
}, z.core.$strict>>;
|
|
122
122
|
interface LintSectionClass extends Named<typeof LintSectionDefinition> {}
|
|
123
123
|
declare const LintSection: LintSectionClass;
|
|
124
|
+
/** A default colour: a CSS colour as written, or a token, which follows the modes it is painted
|
|
125
|
+
* under. `refTo` rather than the `Token` class, which imports back into this module. */
|
|
126
|
+
declare const defaultColorValue: z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
127
|
+
__ref: z.ZodString;
|
|
128
|
+
}, z.core.$strip>]>;
|
|
129
|
+
type DefaultColorValue = z.output<typeof defaultColorValue>;
|
|
130
|
+
/** A default colour on its own, or with `output` saying whether the stylesheet's body rule carries
|
|
131
|
+
* it. */
|
|
132
|
+
declare const defaultColor: z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
133
|
+
__ref: z.ZodString;
|
|
134
|
+
}, z.core.$strip>]>, z.ZodObject<{
|
|
135
|
+
value: z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
136
|
+
__ref: z.ZodString;
|
|
137
|
+
}, z.core.$strip>]>;
|
|
138
|
+
output: z.ZodOptional<z.ZodBoolean>;
|
|
139
|
+
}, z.core.$strict>]>;
|
|
140
|
+
/** The `defaults` section — the background and text colour a system's components sit on. */
|
|
141
|
+
declare const DefaultsSectionDefinition: SubEntityClass<z.ZodObject<{
|
|
142
|
+
background: z.ZodOptional<z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
143
|
+
__ref: z.ZodString;
|
|
144
|
+
}, z.core.$strip>]>, z.ZodObject<{
|
|
145
|
+
value: z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
146
|
+
__ref: z.ZodString;
|
|
147
|
+
}, z.core.$strip>]>;
|
|
148
|
+
output: z.ZodOptional<z.ZodBoolean>;
|
|
149
|
+
}, z.core.$strict>]>>;
|
|
150
|
+
color: z.ZodOptional<z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
151
|
+
__ref: z.ZodString;
|
|
152
|
+
}, z.core.$strip>]>, z.ZodObject<{
|
|
153
|
+
value: z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
154
|
+
__ref: z.ZodString;
|
|
155
|
+
}, z.core.$strip>]>;
|
|
156
|
+
output: z.ZodOptional<z.ZodBoolean>;
|
|
157
|
+
}, z.core.$strict>]>>;
|
|
158
|
+
}, z.core.$strict>>;
|
|
159
|
+
interface DefaultsSectionClass extends Named<typeof DefaultsSectionDefinition> {}
|
|
160
|
+
declare const DefaultsSection: DefaultsSectionClass;
|
|
161
|
+
/** One default colour in its long form: the value, and whether the body rule carries it. */
|
|
162
|
+
interface DefaultColor {
|
|
163
|
+
readonly value: DefaultColorValue;
|
|
164
|
+
readonly output: boolean;
|
|
165
|
+
}
|
|
166
|
+
/** A system's default colours, each in its long form; an unset one is absent. */
|
|
167
|
+
interface DefaultColors {
|
|
168
|
+
readonly background?: DefaultColor;
|
|
169
|
+
readonly color?: DefaultColor;
|
|
170
|
+
}
|
|
171
|
+
/** A default colour as authored: the value alone, or `{ value, output }`. */
|
|
172
|
+
type AuthoredDefaultColor = z.output<typeof defaultColor>;
|
|
173
|
+
/** One default colour in its long form, whichever form it was written in. */
|
|
174
|
+
declare function defaultColorOf(authored: AuthoredDefaultColor | undefined): DefaultColor | undefined;
|
|
175
|
+
/** The `defaults` section as every reader takes it, whichever form each colour was written in. */
|
|
176
|
+
declare function defaultColorsOf(config: Config): DefaultColors;
|
|
124
177
|
/**
|
|
125
178
|
* {@link derivedInputDir} over paths alone, for a build that has walked its source graph but not yet
|
|
126
179
|
* written the `file` rows the computed `inputDir` reads. `components` are the config-relative paths
|
|
@@ -175,6 +228,24 @@ declare const SettingsDefinition: EntityClass<z.ZodObject<{
|
|
|
175
228
|
reason: z.ZodString;
|
|
176
229
|
}, z.core.$strict>>>;
|
|
177
230
|
}, z.core.$strict>>;
|
|
231
|
+
defaults: z.ZodOptional<z.ZodObject<{
|
|
232
|
+
background: z.ZodOptional<z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
233
|
+
__ref: z.ZodString;
|
|
234
|
+
}, z.core.$strip>]>, z.ZodObject<{
|
|
235
|
+
value: z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
236
|
+
__ref: z.ZodString;
|
|
237
|
+
}, z.core.$strip>]>;
|
|
238
|
+
output: z.ZodOptional<z.ZodBoolean>;
|
|
239
|
+
}, z.core.$strict>]>>;
|
|
240
|
+
color: z.ZodOptional<z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
241
|
+
__ref: z.ZodString;
|
|
242
|
+
}, z.core.$strip>]>, z.ZodObject<{
|
|
243
|
+
value: z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
244
|
+
__ref: z.ZodString;
|
|
245
|
+
}, z.core.$strip>]>;
|
|
246
|
+
output: z.ZodOptional<z.ZodBoolean>;
|
|
247
|
+
}, z.core.$strict>]>>;
|
|
248
|
+
}, z.core.$strict>>;
|
|
178
249
|
}, z.core.$strict>, z.ZodObject<Record<never, never>, z.core.$strip>, "settings", {}, {
|
|
179
250
|
/**
|
|
180
251
|
* The directory this system's component files are laid out beneath, always defined:
|
|
@@ -189,4 +260,4 @@ declare const SettingsDefinition: EntityClass<z.ZodObject<{
|
|
|
189
260
|
interface SettingsClass extends Named<typeof SettingsDefinition> {}
|
|
190
261
|
declare const Settings: SettingsClass;
|
|
191
262
|
//#endregion
|
|
192
|
-
export { BuildSection, BuildSectionClass, CSS_DEFAULTS, CssPrefix, CssSection, CssSectionClass, LintSection, LintSectionClass, PLAYGROUND_DEFAULTS, PlaygroundSection, PlaygroundSectionClass, Settings, SettingsClass, SystemSection, SystemSectionClass, classPrefixOf, cssPrefixes, deriveInputDir, layerPrefixOf, prefixed, varPrefixOf };
|
|
263
|
+
export { AuthoredDefaultColor, BuildSection, BuildSectionClass, CSS_DEFAULTS, CssPrefix, CssSection, CssSectionClass, DefaultColor, DefaultColorValue, DefaultColors, DefaultsSection, DefaultsSectionClass, LintSection, LintSectionClass, PLAYGROUND_DEFAULTS, PlaygroundSection, PlaygroundSectionClass, Settings, SettingsClass, SystemSection, SystemSectionClass, classPrefixOf, cssPrefixes, defaultColorOf, defaultColorsOf, deriveInputDir, layerPrefixOf, prefixed, varPrefixOf };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { splitRef } from "../../framework/utils/refs.js";
|
|
1
|
+
import { refTo, splitRef } from "../../framework/utils/refs.js";
|
|
2
2
|
import { defineEntity } from "../../framework/defineEntity.js";
|
|
3
3
|
import { defineSubEntity } from "../../framework/defineSubEntity.js";
|
|
4
4
|
import { createSliceMemo } from "../../framework/memo.js";
|
|
@@ -23,8 +23,9 @@ import { z } from "zod";
|
|
|
23
23
|
* field, and a clone emits only what the system chose. The defaults are the `*_DEFAULTS` constants
|
|
24
24
|
* beside each section, which the readers fall back to.
|
|
25
25
|
*
|
|
26
|
-
* Not borrowed and not refed
|
|
27
|
-
*
|
|
26
|
+
* Not borrowed and not refed. A `defaults` colour may ref a token, so renaming that token cascades
|
|
27
|
+
* into it. `linkable: false` is a statement about this kind, not about singletons: a consumer's
|
|
28
|
+
* `link: '*'` must not inherit a source's build directories or CSS prefix.
|
|
28
29
|
*/
|
|
29
30
|
const systemFields = z.strictObject({
|
|
30
31
|
/**
|
|
@@ -222,6 +223,55 @@ const LintSection = defineSubEntity({
|
|
|
222
223
|
singleton: true,
|
|
223
224
|
fields: lintFields
|
|
224
225
|
});
|
|
226
|
+
/** A default colour: a CSS colour as written, or a token, which follows the modes it is painted
|
|
227
|
+
* under. `refTo` rather than the `Token` class, which imports back into this module. */
|
|
228
|
+
const defaultColorValue = z.union([z.string().min(1), refTo("token")]);
|
|
229
|
+
/** A default colour on its own, or with `output` saying whether the stylesheet's body rule carries
|
|
230
|
+
* it. */
|
|
231
|
+
const defaultColor = z.union([defaultColorValue, z.strictObject({
|
|
232
|
+
value: defaultColorValue,
|
|
233
|
+
output: z.boolean().optional()
|
|
234
|
+
})]);
|
|
235
|
+
const defaultsFields = z.strictObject({
|
|
236
|
+
background: defaultColor.meta({
|
|
237
|
+
title: "Background",
|
|
238
|
+
valueType: "color",
|
|
239
|
+
description: "The background this system's components sit on: a CSS colour (`#ffffff`) or a token (`Token.ref('color/surface')`). The stylesheet sets it on `body`, and Create paints it behind a component's matrix cells, under the modes picked there. `{ value, output: false }` keeps it out of the stylesheet. Unset, neither paints one."
|
|
240
|
+
}).optional(),
|
|
241
|
+
color: defaultColor.meta({
|
|
242
|
+
title: "Text color",
|
|
243
|
+
valueType: "color",
|
|
244
|
+
description: "The text colour this system's components inherit: a CSS colour or a token. The stylesheet sets it on `body`, and Create applies it to a component's matrix cells, under the modes picked there. `{ value, output: false }` keeps it out of the stylesheet. Unset, neither sets one."
|
|
245
|
+
}).optional()
|
|
246
|
+
});
|
|
247
|
+
const DefaultsSection = defineSubEntity({
|
|
248
|
+
name: "defaults",
|
|
249
|
+
label: "Defaults",
|
|
250
|
+
singleton: true,
|
|
251
|
+
fields: defaultsFields
|
|
252
|
+
});
|
|
253
|
+
/** One default colour in its long form, whichever form it was written in. */
|
|
254
|
+
function defaultColorOf(authored) {
|
|
255
|
+
if (authored === void 0) return void 0;
|
|
256
|
+
if (typeof authored === "object" && "value" in authored) return {
|
|
257
|
+
value: authored.value,
|
|
258
|
+
output: authored.output ?? true
|
|
259
|
+
};
|
|
260
|
+
return {
|
|
261
|
+
value: authored,
|
|
262
|
+
output: true
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
/** The `defaults` section as every reader takes it, whichever form each colour was written in. */
|
|
266
|
+
function defaultColorsOf(config) {
|
|
267
|
+
const defaults = Settings.get(config)?.defaults;
|
|
268
|
+
const background = defaultColorOf(defaults?.background);
|
|
269
|
+
const color = defaultColorOf(defaults?.color);
|
|
270
|
+
return {
|
|
271
|
+
...background ? { background } : {},
|
|
272
|
+
...color ? { color } : {}
|
|
273
|
+
};
|
|
274
|
+
}
|
|
225
275
|
/** The folders of a path, file name dropped. */
|
|
226
276
|
const foldersOf = (file) => file.split("/").slice(0, -1);
|
|
227
277
|
/** The folders every one of `lists` starts with. */
|
|
@@ -322,14 +372,16 @@ const Settings = defineEntity({
|
|
|
322
372
|
build: buildFields.meta({ title: "Build" }).optional(),
|
|
323
373
|
css: cssFields.meta({ title: "CSS" }).optional(),
|
|
324
374
|
playground: playgroundFields.meta({ title: "Playground" }).optional(),
|
|
325
|
-
lint: lintFields.meta({ title: "Lint" }).optional()
|
|
375
|
+
lint: lintFields.meta({ title: "Lint" }).optional(),
|
|
376
|
+
defaults: defaultsFields.meta({ title: "Defaults" }).optional()
|
|
326
377
|
}),
|
|
327
378
|
subEntities: {
|
|
328
379
|
system: SystemSection,
|
|
329
380
|
build: BuildSection,
|
|
330
381
|
css: CssSection,
|
|
331
382
|
playground: PlaygroundSection,
|
|
332
|
-
lint: LintSection
|
|
383
|
+
lint: LintSection,
|
|
384
|
+
defaults: DefaultsSection
|
|
333
385
|
},
|
|
334
386
|
computed: {
|
|
335
387
|
/**
|
|
@@ -340,4 +392,4 @@ const Settings = defineEntity({
|
|
|
340
392
|
inputDir: ({ member, config }) => resolveInputDir(member.build) ?? derivedInputDir(config) }
|
|
341
393
|
});
|
|
342
394
|
//#endregion
|
|
343
|
-
export { BuildSection, CSS_DEFAULTS, CssSection, LintSection, PLAYGROUND_DEFAULTS, PlaygroundSection, Settings, SystemSection, classPrefixOf, cssPrefixes, deriveInputDir, layerPrefixOf, prefixed, varPrefixOf };
|
|
395
|
+
export { BuildSection, CSS_DEFAULTS, CssSection, DefaultsSection, LintSection, PLAYGROUND_DEFAULTS, PlaygroundSection, Settings, SystemSection, classPrefixOf, cssPrefixes, defaultColorOf, defaultColorsOf, deriveInputDir, layerPrefixOf, prefixed, varPrefixOf };
|
|
@@ -9,12 +9,22 @@ type LinkPaths = '*' | Readonly<Record<string, '*' | readonly string[]>>;
|
|
|
9
9
|
/** What a link does at a path held through another linked system: `'take'` makes the row follow this
|
|
10
10
|
* source, `'keep'` leaves it with the system it comes from. */
|
|
11
11
|
type OnLinked = 'keep' | 'take';
|
|
12
|
+
/** Per accessor, a path this config holds → the source's path that replaces it under another name. */
|
|
13
|
+
type LinkReplacements = Readonly<Record<string, Readonly<Record<string, string>>>>;
|
|
12
14
|
interface LinkPlanInput {
|
|
13
15
|
/** The pin's slug. */
|
|
14
16
|
readonly path: string;
|
|
15
17
|
readonly data: LinkPaths;
|
|
16
18
|
/** Planned as `'take'` when omitted; the `link` op refuses without it while `linked` is not empty. */
|
|
17
19
|
readonly onLinked?: OnLinked;
|
|
20
|
+
/**
|
|
21
|
+
* What this config holds under one name that the source's entity replaces under another:
|
|
22
|
+
* `{ components: { SelectContent: 'SelectMenu' } }` replaces the `SelectContent` this config holds
|
|
23
|
+
* with the source's `SelectMenu`, and everything that pointed at `SelectContent` points at
|
|
24
|
+
* `SelectMenu` after it. Each source path is one `data` names. A take at the same path is
|
|
25
|
+
* `onLinked: 'take'`, not this.
|
|
26
|
+
*/
|
|
27
|
+
readonly replace?: LinkReplacements;
|
|
18
28
|
}
|
|
19
29
|
/** A path the link reaches that another linked system provides, or declares under a row of this
|
|
20
30
|
* config's own. */
|
|
@@ -40,6 +50,22 @@ interface StrandedDirective extends DroppedDirective {
|
|
|
40
50
|
interface LinkArrival extends EntityAddress {
|
|
41
51
|
readonly named: boolean;
|
|
42
52
|
}
|
|
53
|
+
/** A row this config held that a `replace` entry replaces with the source's entity of another name.
|
|
54
|
+
* `path` is the row's; every ref to it is renamed to `with`. */
|
|
55
|
+
interface LinkReplacement extends EntityAddress {
|
|
56
|
+
/** The source's path that replaces it, which is where the row lands. */
|
|
57
|
+
readonly with: string;
|
|
58
|
+
/** The slug of the pin the replaced row came through; absent for a row of this config's own. */
|
|
59
|
+
readonly from?: string;
|
|
60
|
+
/** Whether the replaced path was left out of that pin, so it no longer derives here. */
|
|
61
|
+
readonly excluded: boolean;
|
|
62
|
+
/** That pin's own rows still drawing on the replaced path, which keep it held. */
|
|
63
|
+
readonly keptFor?: readonly EntityAddress[];
|
|
64
|
+
/** Why the replaced path couldn't be left out of that pin, when it couldn't. */
|
|
65
|
+
readonly keptBecause?: string;
|
|
66
|
+
/** That pin's `options` entries at the replaced path, removed with it. */
|
|
67
|
+
readonly dropped: readonly EntityAddress[];
|
|
68
|
+
}
|
|
43
69
|
interface LinkPlan {
|
|
44
70
|
/** The pin's `link` once the op has run. */
|
|
45
71
|
readonly declared: LinkDeclaration | undefined;
|
|
@@ -53,6 +79,8 @@ interface LinkPlan {
|
|
|
53
79
|
readonly linked: readonly LinkedElsewhere[];
|
|
54
80
|
/** Rows held through another pin, turned into extensions through this one. */
|
|
55
81
|
readonly extended: readonly EntityAddress[];
|
|
82
|
+
/** What `replace` replaces, each with the source's entity it's replaced with. */
|
|
83
|
+
readonly replaced: readonly LinkReplacement[];
|
|
56
84
|
/** The other pins' `options` entries at what the take moves, removed with it: they adjust only the
|
|
57
85
|
* rows their pin derives, and the row there follows this one now. Not carried onto the taken row,
|
|
58
86
|
* since an entry corrects what that pin brings rather than stating a value of this config's own. */
|
|
@@ -156,6 +184,11 @@ interface SourceRowState {
|
|
|
156
184
|
* that leaves a referrer dangling until the declaration covers the path. A member
|
|
157
185
|
* already here from the source's own origin is left alone and kept out of the declaration, so a
|
|
158
186
|
* folder that holds one is declared by its other members.
|
|
187
|
+
*
|
|
188
|
+
* A `replace` entry replaces a row this config holds with the source's entity of another name: that
|
|
189
|
+
* row becomes an extension of the source's, is renamed to the source's path so every ref follows
|
|
190
|
+
* (`replacementTakes`), and is left out of the pin it came through unless that pin's own rows still
|
|
191
|
+
* draw on it.
|
|
159
192
|
*/
|
|
160
193
|
declare function planLink({
|
|
161
194
|
config,
|
|
@@ -214,4 +247,4 @@ declare function sourceRowStates({
|
|
|
214
247
|
readonly slug: string;
|
|
215
248
|
}): SourceRowState[];
|
|
216
249
|
//#endregion
|
|
217
|
-
export { BreakOutcome, BreakPlan, BreakPlanInput, BreakPlanRow, BreakReach, DroppedDirective, LinkArrival, LinkPaths, LinkPlan, LinkPlanInput, LinkedElsewhere, OnLinked, SourceRowState, UnlinkPlan, UnlinkPlanInput, planBreak, planLink, planUnlink, sourceRowStates };
|
|
250
|
+
export { BreakOutcome, BreakPlan, BreakPlanInput, BreakPlanRow, BreakReach, DroppedDirective, LinkArrival, LinkPaths, LinkPlan, LinkPlanInput, LinkReplacement, LinkReplacements, LinkedElsewhere, OnLinked, SourceRowState, UnlinkPlan, UnlinkPlanInput, planBreak, planLink, planUnlink, sourceRowStates };
|
|
@@ -71,6 +71,11 @@ function declaredElsewhere({ config, slug, kind, path }) {
|
|
|
71
71
|
* that leaves a referrer dangling until the declaration covers the path. A member
|
|
72
72
|
* already here from the source's own origin is left alone and kept out of the declaration, so a
|
|
73
73
|
* folder that holds one is declared by its other members.
|
|
74
|
+
*
|
|
75
|
+
* A `replace` entry replaces a row this config holds with the source's entity of another name: that
|
|
76
|
+
* row becomes an extension of the source's, is renamed to the source's path so every ref follows
|
|
77
|
+
* (`replacementTakes`), and is left out of the pin it came through unless that pin's own rows still
|
|
78
|
+
* draw on it.
|
|
74
79
|
*/
|
|
75
80
|
function planLink({ config, input }) {
|
|
76
81
|
return planLinkApplied({
|
|
@@ -116,7 +121,15 @@ function planLinkApplied({ config, input }) {
|
|
|
116
121
|
/** Per accessor, what the declaration gains: the kind whole, or paths. */
|
|
117
122
|
const gains = /* @__PURE__ */ new Map();
|
|
118
123
|
let leftAnywhere = false;
|
|
124
|
+
const replacements = replacementTakes({
|
|
125
|
+
config,
|
|
126
|
+
slug,
|
|
127
|
+
source,
|
|
128
|
+
input
|
|
129
|
+
});
|
|
130
|
+
const landing = new Set(replacements.entries.map(({ kind, path }) => `${kind}:${path}`));
|
|
119
131
|
const shadow = (kind, path) => {
|
|
132
|
+
if (landing.has(`${kind}:${path}`)) return true;
|
|
120
133
|
const held = config.resolve(kind, path);
|
|
121
134
|
if (!held || held.borrowedFrom === slug) return true;
|
|
122
135
|
if (sharedWithOrigin({
|
|
@@ -261,12 +274,13 @@ function planLinkApplied({ config, input }) {
|
|
|
261
274
|
declared = Object.keys(next).length === 0 ? current : next;
|
|
262
275
|
}
|
|
263
276
|
const planned = [
|
|
277
|
+
...replacements.patches,
|
|
264
278
|
...takes,
|
|
265
279
|
...declares,
|
|
266
280
|
...shadows
|
|
267
281
|
];
|
|
268
282
|
let result = planned.length > 0 ? applied(config, planned) : void 0;
|
|
269
|
-
if (takes.length > 0 && result && "failed" in result) throw result.failed;
|
|
283
|
+
if ((takes.length > 0 || replacements.patches.length > 0) && result && "failed" in result) throw result.failed;
|
|
270
284
|
const { dropped, stranded, patches: drops } = takes.length > 0 && result && "config" in result ? directivesTakenFrom({
|
|
271
285
|
config,
|
|
272
286
|
slug,
|
|
@@ -277,7 +291,74 @@ function planLinkApplied({ config, input }) {
|
|
|
277
291
|
patches: []
|
|
278
292
|
};
|
|
279
293
|
if (drops.length > 0 && result && "config" in result) result = applied(result.config, drops);
|
|
280
|
-
const
|
|
294
|
+
const taken = [];
|
|
295
|
+
const leaves = [];
|
|
296
|
+
for (const entry of replacements.entries) {
|
|
297
|
+
const { kind, accessor, path, replaces, from } = entry;
|
|
298
|
+
if (from === void 0 || !result || !("config" in result)) {
|
|
299
|
+
taken.push({
|
|
300
|
+
kind,
|
|
301
|
+
path: replaces,
|
|
302
|
+
with: path,
|
|
303
|
+
...from ? { from } : {},
|
|
304
|
+
excluded: false,
|
|
305
|
+
dropped: []
|
|
306
|
+
});
|
|
307
|
+
continue;
|
|
308
|
+
}
|
|
309
|
+
const leftOut = { [accessor]: [replaces] };
|
|
310
|
+
const keptFor = linkedDependents({
|
|
311
|
+
config: result.config,
|
|
312
|
+
slug: from,
|
|
313
|
+
data: leftOut
|
|
314
|
+
});
|
|
315
|
+
if (keptFor.length > 0) {
|
|
316
|
+
taken.push({
|
|
317
|
+
kind,
|
|
318
|
+
path: replaces,
|
|
319
|
+
with: path,
|
|
320
|
+
from,
|
|
321
|
+
excluded: false,
|
|
322
|
+
keptFor,
|
|
323
|
+
dropped: []
|
|
324
|
+
});
|
|
325
|
+
continue;
|
|
326
|
+
}
|
|
327
|
+
const exclusion = planExclude({
|
|
328
|
+
config: result.config,
|
|
329
|
+
input: {
|
|
330
|
+
path: from,
|
|
331
|
+
data: leftOut
|
|
332
|
+
}
|
|
333
|
+
});
|
|
334
|
+
if (exclusion.blocked !== void 0) {
|
|
335
|
+
taken.push({
|
|
336
|
+
kind,
|
|
337
|
+
path: replaces,
|
|
338
|
+
with: path,
|
|
339
|
+
from,
|
|
340
|
+
excluded: false,
|
|
341
|
+
keptBecause: exclusion.blocked,
|
|
342
|
+
dropped: []
|
|
343
|
+
});
|
|
344
|
+
continue;
|
|
345
|
+
}
|
|
346
|
+
leaves.push(...exclusion.patches);
|
|
347
|
+
result = applied(result.config, exclusion.patches);
|
|
348
|
+
taken.push({
|
|
349
|
+
kind,
|
|
350
|
+
path: replaces,
|
|
351
|
+
with: path,
|
|
352
|
+
from,
|
|
353
|
+
excluded: true,
|
|
354
|
+
dropped: exclusion.dropped
|
|
355
|
+
});
|
|
356
|
+
}
|
|
357
|
+
const patches = [
|
|
358
|
+
...planned,
|
|
359
|
+
...drops,
|
|
360
|
+
...leaves
|
|
361
|
+
];
|
|
281
362
|
return {
|
|
282
363
|
plan: {
|
|
283
364
|
declared,
|
|
@@ -291,6 +372,7 @@ function planLinkApplied({ config, input }) {
|
|
|
291
372
|
addresses,
|
|
292
373
|
linked,
|
|
293
374
|
extended,
|
|
375
|
+
replaced: taken,
|
|
294
376
|
dropped,
|
|
295
377
|
shared,
|
|
296
378
|
patches,
|
|
@@ -303,6 +385,79 @@ function planLinkApplied({ config, input }) {
|
|
|
303
385
|
};
|
|
304
386
|
}
|
|
305
387
|
/**
|
|
388
|
+
* The edits that take each `replace` entry: the replaced row becomes this config's own extension of
|
|
389
|
+
* the source's entity, still at the old path, and is then renamed to the source's path. A rename is
|
|
390
|
+
* the edit that moves every ref, and the one design files and code follow, so the replaced name's
|
|
391
|
+
* instances arrive on the taken entity the way a rename's would. The config refuses to rename a row
|
|
392
|
+
* held under its source's own name, so the extension comes first: what it holds is then a name this
|
|
393
|
+
* config gave.
|
|
394
|
+
*/
|
|
395
|
+
function replacementTakes({ config, slug, source, input }) {
|
|
396
|
+
const entries = [];
|
|
397
|
+
const patches = [];
|
|
398
|
+
const accessors = config.accessors();
|
|
399
|
+
const landing = /* @__PURE__ */ new Map();
|
|
400
|
+
for (const [accessor, pairs] of Object.entries(input.replace ?? {})) {
|
|
401
|
+
const kind = accessors[accessor]?.kind;
|
|
402
|
+
if (!kind) rejectData(`Cannot replace anything through "${slug}" — this system has no "${accessor}".`, ["replace", accessor]);
|
|
403
|
+
for (const [replaces, path] of Object.entries(pairs)) {
|
|
404
|
+
const at = [
|
|
405
|
+
"replace",
|
|
406
|
+
accessor,
|
|
407
|
+
replaces
|
|
408
|
+
];
|
|
409
|
+
if (input.data !== "*" && !covers({
|
|
410
|
+
declared: input.data,
|
|
411
|
+
accessor,
|
|
412
|
+
path
|
|
413
|
+
})) rejectData(`Cannot replace "${replaces}" with "${path}" — \`data\` doesn't link "${path}" through "${slug}". Name it there too.`, at);
|
|
414
|
+
if (!source.resolve(kind, path)) rejectData(`Cannot replace "${replaces}" with "${path}" — "${slug}" has no ${kind} "${path}".`, at);
|
|
415
|
+
if (path === replaces) rejectData(`Cannot replace "${path}" with itself — taking the source's "${path}" over it is \`onLinked: 'take'\`.`, at);
|
|
416
|
+
const twice = landing.get(`${kind}:${path}`);
|
|
417
|
+
if (twice !== void 0) rejectData(`Cannot replace both "${twice}" and "${replaces}" with "${path}".`, at);
|
|
418
|
+
const held = config.resolve(kind, replaces);
|
|
419
|
+
if (!held) rejectData(`Cannot replace "${replaces}" — this system has no ${kind} "${replaces}".`, at);
|
|
420
|
+
if (held.borrowedFrom === slug) rejectData(`Cannot replace "${replaces}" with "${path}" — "${replaces}" already comes from "${slug}".`, at);
|
|
421
|
+
const occupied = config.storedBody(kind, path);
|
|
422
|
+
if (occupied !== void 0 && !isMintedRow(occupied)) rejectData(`Cannot replace "${replaces}" with "${path}" — this system already has a ${kind} of its own at "${path}".`, at);
|
|
423
|
+
landing.set(`${kind}:${path}`, replaces);
|
|
424
|
+
const from = held.borrowedFrom ?? declaredElsewhere({
|
|
425
|
+
config,
|
|
426
|
+
slug,
|
|
427
|
+
kind,
|
|
428
|
+
path: replaces
|
|
429
|
+
});
|
|
430
|
+
const stored = config.storedBody(kind, replaces);
|
|
431
|
+
const minted = stored !== void 0 && isMintedRow(stored);
|
|
432
|
+
entries.push({
|
|
433
|
+
kind,
|
|
434
|
+
accessor,
|
|
435
|
+
path,
|
|
436
|
+
replaces,
|
|
437
|
+
...from ? { from } : {}
|
|
438
|
+
});
|
|
439
|
+
patches.push({
|
|
440
|
+
kind,
|
|
441
|
+
operation: minted ? "create" : "replace",
|
|
442
|
+
path: replaces,
|
|
443
|
+
data: {
|
|
444
|
+
...ref(kind, path, slug),
|
|
445
|
+
extend: {}
|
|
446
|
+
}
|
|
447
|
+
}, {
|
|
448
|
+
kind,
|
|
449
|
+
operation: "rename",
|
|
450
|
+
path: replaces,
|
|
451
|
+
to: path
|
|
452
|
+
});
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
return {
|
|
456
|
+
entries,
|
|
457
|
+
patches
|
|
458
|
+
};
|
|
459
|
+
}
|
|
460
|
+
/**
|
|
306
461
|
* The other pins' `options` entries a take leaves applying to nothing, and the pin edits that remove
|
|
307
462
|
* them.
|
|
308
463
|
*
|