@vectoriox/iox-ui 5.26.0 → 5.28.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/design-core/index.d.ts +144 -4
- package/fesm2022/vectoriox-iox-ui-design-core.mjs +153 -5
- package/fesm2022/vectoriox-iox-ui-design-core.mjs.map +1 -1
- package/fesm2022/vectoriox-iox-ui-forms-core.mjs +40 -5
- package/fesm2022/vectoriox-iox-ui-forms-core.mjs.map +1 -1
- package/fesm2022/vectoriox-iox-ui-generation-core.mjs +7018 -0
- package/fesm2022/vectoriox-iox-ui-generation-core.mjs.map +1 -0
- package/fesm2022/vectoriox-iox-ui.mjs +72 -14
- package/fesm2022/vectoriox-iox-ui.mjs.map +1 -1
- package/forms-core/index.d.ts +18 -2
- package/generation-core/index.d.ts +1397 -0
- package/generation-core/package.json +3 -0
- package/index.d.ts +13 -2
- package/package.json +5 -1
- package/src/design-core/flavor-spec.generated.ts +153 -5
- package/src/forms-core/collect.ts +3 -1
- package/src/forms-core/options.ts +29 -0
- package/src/forms-core/public-api.ts +1 -0
- package/src/forms-core/transport.ts +6 -2
- package/src/generation-core/compose-site.ts +474 -0
- package/src/generation-core/node-baseline.model.ts +10 -0
- package/src/generation-core/node-baselines.generated.ts +4841 -0
- package/src/generation-core/patterns.ts +125 -0
- package/src/generation-core/public-api.ts +20 -0
- package/src/generation-core/serialized-node.ts +91 -0
- package/src/generation-core/site-plan.model.ts +136 -0
- package/src/generation-core/site-spec.generated.ts +1111 -0
- package/src/generation-core/templates.ts +60 -0
- package/src/generation-core/validate-site-plan.ts +413 -0
- package/styles/iox-forms.css +136 -8
|
@@ -0,0 +1,1397 @@
|
|
|
1
|
+
import { DesignChoices } from '@vectoriox/iox-ui/design-core';
|
|
2
|
+
|
|
3
|
+
declare const SPEC_SITE_PLAN_SHAPE: {
|
|
4
|
+
readonly version: "1";
|
|
5
|
+
readonly source: "{ kind: 'template', templateId, templateVersion } | { kind: 'ai', runId }";
|
|
6
|
+
readonly business: "{ name (required), tagline?, facts: { email?, phone?, city? } }";
|
|
7
|
+
readonly design: "{ flavorId, seed, pairId, shape, density, motion, pillButtons, mode } — the DesignChoices of the design system";
|
|
8
|
+
readonly contentTypes: "ContentTypePlan[] — { name, label, fields[], seed }";
|
|
9
|
+
readonly dataSources: "DataSourcePlan[] — merged by alias into the org library";
|
|
10
|
+
readonly pages: "PagePlan[] — { key, name, route, isHome?, template?, routeSource?, sections: { pattern, slots?, binding?, without? }[] }";
|
|
11
|
+
readonly globals: "{ header: patternId, footer: patternId }";
|
|
12
|
+
};
|
|
13
|
+
declare const SPEC_SITE_FACTS: {
|
|
14
|
+
readonly email: "Email address";
|
|
15
|
+
readonly phone: "Phone number";
|
|
16
|
+
readonly city: "City or area";
|
|
17
|
+
};
|
|
18
|
+
declare const SPEC_SITE_PATTERNS: {
|
|
19
|
+
readonly "nav.inline-cta": {
|
|
20
|
+
readonly family: "nav";
|
|
21
|
+
readonly label: "Navigation bar";
|
|
22
|
+
readonly global: "before";
|
|
23
|
+
readonly node: {
|
|
24
|
+
readonly t: "Container";
|
|
25
|
+
readonly es: "nav";
|
|
26
|
+
readonly tag: "nav";
|
|
27
|
+
readonly lay: {
|
|
28
|
+
readonly display: "flex";
|
|
29
|
+
readonly justifyContent: "space-between";
|
|
30
|
+
readonly alignItems: "center";
|
|
31
|
+
readonly gap: "var(--iox-space-gap)";
|
|
32
|
+
};
|
|
33
|
+
readonly c: readonly [{
|
|
34
|
+
readonly t: "LinkedContainer";
|
|
35
|
+
readonly es: "box";
|
|
36
|
+
readonly href: "/";
|
|
37
|
+
readonly c: readonly [{
|
|
38
|
+
readonly t: "Heading";
|
|
39
|
+
readonly es: "h3";
|
|
40
|
+
readonly level: "h3";
|
|
41
|
+
readonly slot: "brand";
|
|
42
|
+
readonly fromBusiness: "name";
|
|
43
|
+
}];
|
|
44
|
+
}, {
|
|
45
|
+
readonly t: "Container";
|
|
46
|
+
readonly es: "box";
|
|
47
|
+
readonly lay: {
|
|
48
|
+
readonly display: "flex";
|
|
49
|
+
readonly flexWrap: "wrap";
|
|
50
|
+
readonly gap: "28px";
|
|
51
|
+
readonly alignItems: "center";
|
|
52
|
+
};
|
|
53
|
+
readonly c: readonly [{
|
|
54
|
+
readonly t: "Repeater";
|
|
55
|
+
readonly src: "$navPages";
|
|
56
|
+
readonly c: readonly [{
|
|
57
|
+
readonly t: "Link";
|
|
58
|
+
readonly es: "link";
|
|
59
|
+
readonly bind: "page.name";
|
|
60
|
+
readonly href: "$page.route";
|
|
61
|
+
}];
|
|
62
|
+
}, {
|
|
63
|
+
readonly t: "ButtonBlock";
|
|
64
|
+
readonly es: "button-primary";
|
|
65
|
+
readonly href: "/contact";
|
|
66
|
+
readonly slot: "cta";
|
|
67
|
+
readonly text: "Get in touch";
|
|
68
|
+
}];
|
|
69
|
+
}];
|
|
70
|
+
};
|
|
71
|
+
};
|
|
72
|
+
readonly "footer.columns": {
|
|
73
|
+
readonly family: "footer";
|
|
74
|
+
readonly label: "Footer, three columns";
|
|
75
|
+
readonly global: "after";
|
|
76
|
+
readonly node: {
|
|
77
|
+
readonly t: "Section";
|
|
78
|
+
readonly es: "section";
|
|
79
|
+
readonly scheme: "inverse";
|
|
80
|
+
readonly c: readonly [{
|
|
81
|
+
readonly t: "Container";
|
|
82
|
+
readonly es: "box";
|
|
83
|
+
readonly lay: {
|
|
84
|
+
readonly display: "grid";
|
|
85
|
+
readonly gridTemplateColumns: "2fr 1fr 1fr";
|
|
86
|
+
readonly gap: "var(--iox-space-gap)";
|
|
87
|
+
};
|
|
88
|
+
readonly resp: {
|
|
89
|
+
readonly mobile: {
|
|
90
|
+
readonly gridTemplateColumns: "minmax(0, 1fr)";
|
|
91
|
+
};
|
|
92
|
+
};
|
|
93
|
+
readonly c: readonly [{
|
|
94
|
+
readonly t: "Container";
|
|
95
|
+
readonly es: "box";
|
|
96
|
+
readonly lay: {
|
|
97
|
+
readonly display: "flex";
|
|
98
|
+
readonly flexDirection: "column";
|
|
99
|
+
readonly gap: "8px";
|
|
100
|
+
};
|
|
101
|
+
readonly c: readonly [{
|
|
102
|
+
readonly t: "Heading";
|
|
103
|
+
readonly es: "h3";
|
|
104
|
+
readonly level: "h3";
|
|
105
|
+
readonly slot: "brand";
|
|
106
|
+
readonly fromBusiness: "name";
|
|
107
|
+
}, {
|
|
108
|
+
readonly t: "Text";
|
|
109
|
+
readonly es: "small";
|
|
110
|
+
readonly slot: "tagline";
|
|
111
|
+
readonly fromBusiness: "tagline";
|
|
112
|
+
readonly ph: "copy";
|
|
113
|
+
}];
|
|
114
|
+
}, {
|
|
115
|
+
readonly t: "Container";
|
|
116
|
+
readonly es: "box";
|
|
117
|
+
readonly lay: {
|
|
118
|
+
readonly display: "flex";
|
|
119
|
+
readonly flexDirection: "column";
|
|
120
|
+
readonly gap: "8px";
|
|
121
|
+
};
|
|
122
|
+
readonly c: readonly [{
|
|
123
|
+
readonly t: "Heading";
|
|
124
|
+
readonly es: "eyebrow";
|
|
125
|
+
readonly level: "h4";
|
|
126
|
+
readonly text: "Pages";
|
|
127
|
+
}, {
|
|
128
|
+
readonly t: "Repeater";
|
|
129
|
+
readonly src: "$navPages";
|
|
130
|
+
readonly c: readonly [{
|
|
131
|
+
readonly t: "Link";
|
|
132
|
+
readonly es: "link";
|
|
133
|
+
readonly bind: "page.name";
|
|
134
|
+
readonly href: "$page.route";
|
|
135
|
+
}];
|
|
136
|
+
}];
|
|
137
|
+
}, {
|
|
138
|
+
readonly t: "Container";
|
|
139
|
+
readonly es: "box";
|
|
140
|
+
readonly lay: {
|
|
141
|
+
readonly display: "flex";
|
|
142
|
+
readonly flexDirection: "column";
|
|
143
|
+
readonly gap: "8px";
|
|
144
|
+
};
|
|
145
|
+
readonly c: readonly [{
|
|
146
|
+
readonly t: "Heading";
|
|
147
|
+
readonly es: "eyebrow";
|
|
148
|
+
readonly level: "h4";
|
|
149
|
+
readonly text: "Contact";
|
|
150
|
+
}, {
|
|
151
|
+
readonly t: "Text";
|
|
152
|
+
readonly es: "small";
|
|
153
|
+
readonly ph: "email";
|
|
154
|
+
}, {
|
|
155
|
+
readonly t: "Text";
|
|
156
|
+
readonly es: "small";
|
|
157
|
+
readonly ph: "phone";
|
|
158
|
+
}, {
|
|
159
|
+
readonly t: "Text";
|
|
160
|
+
readonly es: "small";
|
|
161
|
+
readonly ph: "city";
|
|
162
|
+
}];
|
|
163
|
+
}];
|
|
164
|
+
}, {
|
|
165
|
+
readonly t: "Divider";
|
|
166
|
+
readonly es: "rule";
|
|
167
|
+
}, {
|
|
168
|
+
readonly t: "Text";
|
|
169
|
+
readonly es: "small";
|
|
170
|
+
readonly slot: "copyright";
|
|
171
|
+
readonly fromBusiness: "copyright";
|
|
172
|
+
}];
|
|
173
|
+
readonly lay: {
|
|
174
|
+
readonly display: "flex";
|
|
175
|
+
readonly flexDirection: "column";
|
|
176
|
+
readonly gap: "32px";
|
|
177
|
+
};
|
|
178
|
+
};
|
|
179
|
+
};
|
|
180
|
+
readonly "hero.split": {
|
|
181
|
+
readonly family: "hero";
|
|
182
|
+
readonly label: "Hero — text beside an image";
|
|
183
|
+
readonly node: {
|
|
184
|
+
readonly t: "Section";
|
|
185
|
+
readonly es: "section";
|
|
186
|
+
readonly c: readonly [{
|
|
187
|
+
readonly t: "Container";
|
|
188
|
+
readonly es: "box";
|
|
189
|
+
readonly lay: {
|
|
190
|
+
readonly display: "grid";
|
|
191
|
+
readonly gridTemplateColumns: "1.1fr 0.9fr";
|
|
192
|
+
readonly gap: "48px";
|
|
193
|
+
readonly alignItems: "center";
|
|
194
|
+
};
|
|
195
|
+
readonly resp: {
|
|
196
|
+
readonly mobile: {
|
|
197
|
+
readonly gridTemplateColumns: "minmax(0, 1fr)";
|
|
198
|
+
};
|
|
199
|
+
};
|
|
200
|
+
readonly c: readonly [{
|
|
201
|
+
readonly t: "Container";
|
|
202
|
+
readonly es: "box";
|
|
203
|
+
readonly lay: {
|
|
204
|
+
readonly display: "flex";
|
|
205
|
+
readonly flexDirection: "column";
|
|
206
|
+
readonly gap: "22px";
|
|
207
|
+
};
|
|
208
|
+
readonly c: readonly [{
|
|
209
|
+
readonly t: "Heading";
|
|
210
|
+
readonly es: "eyebrow";
|
|
211
|
+
readonly level: "h4";
|
|
212
|
+
readonly slot: "eyebrow";
|
|
213
|
+
readonly ph: "copy";
|
|
214
|
+
readonly text: "What you do · where";
|
|
215
|
+
}, {
|
|
216
|
+
readonly t: "Heading";
|
|
217
|
+
readonly es: "display";
|
|
218
|
+
readonly level: "h1";
|
|
219
|
+
readonly slot: "headline";
|
|
220
|
+
readonly fromBusiness: "name";
|
|
221
|
+
}, {
|
|
222
|
+
readonly t: "Text";
|
|
223
|
+
readonly es: "lead";
|
|
224
|
+
readonly slot: "lead";
|
|
225
|
+
readonly fromBusiness: "tagline";
|
|
226
|
+
readonly ph: "copy";
|
|
227
|
+
}, {
|
|
228
|
+
readonly t: "Container";
|
|
229
|
+
readonly es: "box";
|
|
230
|
+
readonly lay: {
|
|
231
|
+
readonly display: "flex";
|
|
232
|
+
readonly flexWrap: "wrap";
|
|
233
|
+
readonly gap: "12px";
|
|
234
|
+
readonly alignItems: "center";
|
|
235
|
+
};
|
|
236
|
+
readonly c: readonly [{
|
|
237
|
+
readonly t: "ButtonBlock";
|
|
238
|
+
readonly es: "button-primary";
|
|
239
|
+
readonly href: "/work";
|
|
240
|
+
readonly text: "See our work";
|
|
241
|
+
}, {
|
|
242
|
+
readonly t: "ButtonBlock";
|
|
243
|
+
readonly es: "button-secondary";
|
|
244
|
+
readonly href: "/contact";
|
|
245
|
+
readonly text: "Get in touch";
|
|
246
|
+
}];
|
|
247
|
+
}];
|
|
248
|
+
}, {
|
|
249
|
+
readonly t: "Image";
|
|
250
|
+
readonly es: "media";
|
|
251
|
+
readonly ph: "image";
|
|
252
|
+
readonly aspect: "4 / 5";
|
|
253
|
+
}];
|
|
254
|
+
}];
|
|
255
|
+
};
|
|
256
|
+
};
|
|
257
|
+
readonly "projects.grid": {
|
|
258
|
+
readonly family: "collection";
|
|
259
|
+
readonly label: "Project cards, three across";
|
|
260
|
+
readonly node: {
|
|
261
|
+
readonly t: "Section";
|
|
262
|
+
readonly es: "section";
|
|
263
|
+
readonly c: readonly [{
|
|
264
|
+
readonly t: "Container";
|
|
265
|
+
readonly es: "box";
|
|
266
|
+
readonly optional: "header";
|
|
267
|
+
readonly lay: {
|
|
268
|
+
readonly display: "flex";
|
|
269
|
+
readonly justifyContent: "space-between";
|
|
270
|
+
readonly alignItems: "baseline";
|
|
271
|
+
readonly gap: "16px";
|
|
272
|
+
readonly flexWrap: "wrap";
|
|
273
|
+
};
|
|
274
|
+
readonly c: readonly [{
|
|
275
|
+
readonly t: "Heading";
|
|
276
|
+
readonly es: "h2";
|
|
277
|
+
readonly level: "h2";
|
|
278
|
+
readonly slot: "title";
|
|
279
|
+
readonly text: "Selected work";
|
|
280
|
+
}, {
|
|
281
|
+
readonly t: "Link";
|
|
282
|
+
readonly es: "link";
|
|
283
|
+
readonly href: "/work";
|
|
284
|
+
readonly text: "All projects";
|
|
285
|
+
}];
|
|
286
|
+
}, {
|
|
287
|
+
readonly t: "Repeater";
|
|
288
|
+
readonly src: "$binding";
|
|
289
|
+
readonly lay: {
|
|
290
|
+
readonly display: "grid";
|
|
291
|
+
readonly gridTemplateColumns: "repeat(3, minmax(0, 1fr))";
|
|
292
|
+
readonly gap: "var(--iox-space-gap)";
|
|
293
|
+
};
|
|
294
|
+
readonly resp: {
|
|
295
|
+
readonly mobile: {
|
|
296
|
+
readonly gridTemplateColumns: "minmax(0, 1fr)";
|
|
297
|
+
};
|
|
298
|
+
};
|
|
299
|
+
readonly c: readonly [{
|
|
300
|
+
readonly t: "LinkedContainer";
|
|
301
|
+
readonly es: "card";
|
|
302
|
+
readonly href: "/work/:slug";
|
|
303
|
+
readonly param: "item.slug";
|
|
304
|
+
readonly lay: {
|
|
305
|
+
readonly display: "flex";
|
|
306
|
+
readonly flexDirection: "column";
|
|
307
|
+
readonly gap: "12px";
|
|
308
|
+
};
|
|
309
|
+
readonly c: readonly [{
|
|
310
|
+
readonly t: "Image";
|
|
311
|
+
readonly es: "media";
|
|
312
|
+
readonly bind: "item.cover";
|
|
313
|
+
readonly aspect: "4 / 3";
|
|
314
|
+
}, {
|
|
315
|
+
readonly t: "Heading";
|
|
316
|
+
readonly es: "h3";
|
|
317
|
+
readonly level: "h3";
|
|
318
|
+
readonly bind: "item.title";
|
|
319
|
+
}, {
|
|
320
|
+
readonly t: "Text";
|
|
321
|
+
readonly es: "small";
|
|
322
|
+
readonly bind: "item.summary";
|
|
323
|
+
}];
|
|
324
|
+
}];
|
|
325
|
+
}];
|
|
326
|
+
readonly lay: {
|
|
327
|
+
readonly display: "flex";
|
|
328
|
+
readonly flexDirection: "column";
|
|
329
|
+
readonly gap: "32px";
|
|
330
|
+
};
|
|
331
|
+
};
|
|
332
|
+
};
|
|
333
|
+
readonly "services.three": {
|
|
334
|
+
readonly family: "features";
|
|
335
|
+
readonly label: "Three services";
|
|
336
|
+
readonly node: {
|
|
337
|
+
readonly t: "Section";
|
|
338
|
+
readonly es: "section";
|
|
339
|
+
readonly scheme: "subtle";
|
|
340
|
+
readonly c: readonly [{
|
|
341
|
+
readonly t: "Heading";
|
|
342
|
+
readonly es: "h2";
|
|
343
|
+
readonly level: "h2";
|
|
344
|
+
readonly slot: "title";
|
|
345
|
+
readonly text: "What we do";
|
|
346
|
+
}, {
|
|
347
|
+
readonly t: "Container";
|
|
348
|
+
readonly es: "box";
|
|
349
|
+
readonly lay: {
|
|
350
|
+
readonly display: "grid";
|
|
351
|
+
readonly gridTemplateColumns: "repeat(3, minmax(0, 1fr))";
|
|
352
|
+
readonly gap: "var(--iox-space-gap)";
|
|
353
|
+
};
|
|
354
|
+
readonly resp: {
|
|
355
|
+
readonly mobile: {
|
|
356
|
+
readonly gridTemplateColumns: "minmax(0, 1fr)";
|
|
357
|
+
};
|
|
358
|
+
};
|
|
359
|
+
readonly c: readonly [{
|
|
360
|
+
readonly t: "Container";
|
|
361
|
+
readonly es: "card";
|
|
362
|
+
readonly lay: {
|
|
363
|
+
readonly display: "flex";
|
|
364
|
+
readonly flexDirection: "column";
|
|
365
|
+
readonly gap: "10px";
|
|
366
|
+
};
|
|
367
|
+
readonly c: readonly [{
|
|
368
|
+
readonly t: "Heading";
|
|
369
|
+
readonly es: "h3";
|
|
370
|
+
readonly level: "h3";
|
|
371
|
+
readonly ph: "copy";
|
|
372
|
+
readonly text: "Name a service";
|
|
373
|
+
}, {
|
|
374
|
+
readonly t: "Text";
|
|
375
|
+
readonly es: "body";
|
|
376
|
+
readonly ph: "copy";
|
|
377
|
+
readonly text: "Describe it in two sentences.";
|
|
378
|
+
}];
|
|
379
|
+
}, {
|
|
380
|
+
readonly t: "Container";
|
|
381
|
+
readonly es: "card";
|
|
382
|
+
readonly lay: {
|
|
383
|
+
readonly display: "flex";
|
|
384
|
+
readonly flexDirection: "column";
|
|
385
|
+
readonly gap: "10px";
|
|
386
|
+
};
|
|
387
|
+
readonly c: readonly [{
|
|
388
|
+
readonly t: "Heading";
|
|
389
|
+
readonly es: "h3";
|
|
390
|
+
readonly level: "h3";
|
|
391
|
+
readonly ph: "copy";
|
|
392
|
+
readonly text: "Name a service";
|
|
393
|
+
}, {
|
|
394
|
+
readonly t: "Text";
|
|
395
|
+
readonly es: "body";
|
|
396
|
+
readonly ph: "copy";
|
|
397
|
+
readonly text: "Describe it in two sentences.";
|
|
398
|
+
}];
|
|
399
|
+
}, {
|
|
400
|
+
readonly t: "Container";
|
|
401
|
+
readonly es: "card";
|
|
402
|
+
readonly lay: {
|
|
403
|
+
readonly display: "flex";
|
|
404
|
+
readonly flexDirection: "column";
|
|
405
|
+
readonly gap: "10px";
|
|
406
|
+
};
|
|
407
|
+
readonly c: readonly [{
|
|
408
|
+
readonly t: "Heading";
|
|
409
|
+
readonly es: "h3";
|
|
410
|
+
readonly level: "h3";
|
|
411
|
+
readonly ph: "copy";
|
|
412
|
+
readonly text: "Name a service";
|
|
413
|
+
}, {
|
|
414
|
+
readonly t: "Text";
|
|
415
|
+
readonly es: "body";
|
|
416
|
+
readonly ph: "copy";
|
|
417
|
+
readonly text: "Describe it in two sentences.";
|
|
418
|
+
}];
|
|
419
|
+
}];
|
|
420
|
+
}];
|
|
421
|
+
readonly lay: {
|
|
422
|
+
readonly display: "flex";
|
|
423
|
+
readonly flexDirection: "column";
|
|
424
|
+
readonly gap: "32px";
|
|
425
|
+
};
|
|
426
|
+
};
|
|
427
|
+
};
|
|
428
|
+
readonly "cta.band": {
|
|
429
|
+
readonly family: "cta";
|
|
430
|
+
readonly label: "Call to action band";
|
|
431
|
+
readonly node: {
|
|
432
|
+
readonly t: "Section";
|
|
433
|
+
readonly es: "section";
|
|
434
|
+
readonly scheme: "inverse";
|
|
435
|
+
readonly c: readonly [{
|
|
436
|
+
readonly t: "Container";
|
|
437
|
+
readonly es: "box";
|
|
438
|
+
readonly lay: {
|
|
439
|
+
readonly display: "grid";
|
|
440
|
+
readonly gridTemplateColumns: "1fr auto";
|
|
441
|
+
readonly gap: "32px";
|
|
442
|
+
readonly alignItems: "center";
|
|
443
|
+
};
|
|
444
|
+
readonly resp: {
|
|
445
|
+
readonly mobile: {
|
|
446
|
+
readonly gridTemplateColumns: "minmax(0, 1fr)";
|
|
447
|
+
};
|
|
448
|
+
};
|
|
449
|
+
readonly c: readonly [{
|
|
450
|
+
readonly t: "Container";
|
|
451
|
+
readonly es: "box";
|
|
452
|
+
readonly lay: {
|
|
453
|
+
readonly display: "flex";
|
|
454
|
+
readonly flexDirection: "column";
|
|
455
|
+
readonly gap: "12px";
|
|
456
|
+
};
|
|
457
|
+
readonly c: readonly [{
|
|
458
|
+
readonly t: "Heading";
|
|
459
|
+
readonly es: "eyebrow";
|
|
460
|
+
readonly level: "h4";
|
|
461
|
+
readonly text: "Start a project";
|
|
462
|
+
}, {
|
|
463
|
+
readonly t: "Heading";
|
|
464
|
+
readonly es: "h2";
|
|
465
|
+
readonly level: "h2";
|
|
466
|
+
readonly slot: "title";
|
|
467
|
+
readonly text: "Tell us about your project.";
|
|
468
|
+
}];
|
|
469
|
+
}, {
|
|
470
|
+
readonly t: "ButtonBlock";
|
|
471
|
+
readonly es: "button-primary";
|
|
472
|
+
readonly href: "/contact";
|
|
473
|
+
readonly text: "Get in touch";
|
|
474
|
+
}];
|
|
475
|
+
}];
|
|
476
|
+
};
|
|
477
|
+
};
|
|
478
|
+
readonly "page-header.simple": {
|
|
479
|
+
readonly family: "header";
|
|
480
|
+
readonly label: "Page header";
|
|
481
|
+
readonly node: {
|
|
482
|
+
readonly t: "Section";
|
|
483
|
+
readonly es: "section";
|
|
484
|
+
readonly c: readonly [{
|
|
485
|
+
readonly t: "Container";
|
|
486
|
+
readonly es: "box";
|
|
487
|
+
readonly lay: {
|
|
488
|
+
readonly display: "flex";
|
|
489
|
+
readonly flexDirection: "column";
|
|
490
|
+
readonly gap: "14px";
|
|
491
|
+
readonly maxWidth: "760px";
|
|
492
|
+
};
|
|
493
|
+
readonly c: readonly [{
|
|
494
|
+
readonly t: "Heading";
|
|
495
|
+
readonly es: "eyebrow";
|
|
496
|
+
readonly level: "h4";
|
|
497
|
+
readonly slot: "eyebrow";
|
|
498
|
+
}, {
|
|
499
|
+
readonly t: "Heading";
|
|
500
|
+
readonly es: "h1";
|
|
501
|
+
readonly level: "h1";
|
|
502
|
+
readonly slot: "title";
|
|
503
|
+
}, {
|
|
504
|
+
readonly t: "Text";
|
|
505
|
+
readonly es: "lead";
|
|
506
|
+
readonly slot: "lead";
|
|
507
|
+
readonly ph: "copy";
|
|
508
|
+
readonly text: "One or two sentences that introduce this page.";
|
|
509
|
+
}];
|
|
510
|
+
}];
|
|
511
|
+
};
|
|
512
|
+
};
|
|
513
|
+
readonly "project.hero": {
|
|
514
|
+
readonly family: "detail";
|
|
515
|
+
readonly label: "Project hero (bound to the route item)";
|
|
516
|
+
readonly node: {
|
|
517
|
+
readonly t: "Section";
|
|
518
|
+
readonly es: "section";
|
|
519
|
+
readonly c: readonly [{
|
|
520
|
+
readonly t: "Container";
|
|
521
|
+
readonly es: "box";
|
|
522
|
+
readonly lay: {
|
|
523
|
+
readonly display: "flex";
|
|
524
|
+
readonly flexDirection: "column";
|
|
525
|
+
readonly gap: "16px";
|
|
526
|
+
readonly maxWidth: "860px";
|
|
527
|
+
};
|
|
528
|
+
readonly c: readonly [{
|
|
529
|
+
readonly t: "Heading";
|
|
530
|
+
readonly es: "eyebrow";
|
|
531
|
+
readonly level: "h4";
|
|
532
|
+
readonly bind: "route.location";
|
|
533
|
+
}, {
|
|
534
|
+
readonly t: "Heading";
|
|
535
|
+
readonly es: "h1";
|
|
536
|
+
readonly level: "h1";
|
|
537
|
+
readonly bind: "route.title";
|
|
538
|
+
}, {
|
|
539
|
+
readonly t: "Text";
|
|
540
|
+
readonly es: "lead";
|
|
541
|
+
readonly bind: "route.summary";
|
|
542
|
+
}, {
|
|
543
|
+
readonly t: "Text";
|
|
544
|
+
readonly es: "small";
|
|
545
|
+
readonly bind: "route.year";
|
|
546
|
+
}];
|
|
547
|
+
}, {
|
|
548
|
+
readonly t: "Image";
|
|
549
|
+
readonly es: "media";
|
|
550
|
+
readonly bind: "route.cover";
|
|
551
|
+
readonly aspect: "16 / 9";
|
|
552
|
+
}];
|
|
553
|
+
readonly lay: {
|
|
554
|
+
readonly display: "flex";
|
|
555
|
+
readonly flexDirection: "column";
|
|
556
|
+
readonly gap: "32px";
|
|
557
|
+
};
|
|
558
|
+
};
|
|
559
|
+
};
|
|
560
|
+
readonly "project.gallery": {
|
|
561
|
+
readonly family: "media";
|
|
562
|
+
readonly label: "Project gallery (the item's images)";
|
|
563
|
+
readonly node: {
|
|
564
|
+
readonly t: "Section";
|
|
565
|
+
readonly es: "section";
|
|
566
|
+
readonly c: readonly [{
|
|
567
|
+
readonly t: "Repeater";
|
|
568
|
+
readonly src: "route.gallery";
|
|
569
|
+
readonly lay: {
|
|
570
|
+
readonly display: "grid";
|
|
571
|
+
readonly gridTemplateColumns: "repeat(2, minmax(0, 1fr))";
|
|
572
|
+
readonly gap: "var(--iox-space-gap)";
|
|
573
|
+
};
|
|
574
|
+
readonly resp: {
|
|
575
|
+
readonly mobile: {
|
|
576
|
+
readonly gridTemplateColumns: "minmax(0, 1fr)";
|
|
577
|
+
};
|
|
578
|
+
};
|
|
579
|
+
readonly c: readonly [{
|
|
580
|
+
readonly t: "Image";
|
|
581
|
+
readonly es: "media";
|
|
582
|
+
readonly bind: "item";
|
|
583
|
+
readonly aspect: "4 / 3";
|
|
584
|
+
}];
|
|
585
|
+
}];
|
|
586
|
+
};
|
|
587
|
+
};
|
|
588
|
+
readonly "project.next": {
|
|
589
|
+
readonly family: "detail";
|
|
590
|
+
readonly label: "Next project";
|
|
591
|
+
readonly node: {
|
|
592
|
+
readonly t: "Section";
|
|
593
|
+
readonly es: "section";
|
|
594
|
+
readonly c: readonly [{
|
|
595
|
+
readonly t: "Divider";
|
|
596
|
+
readonly es: "rule";
|
|
597
|
+
}, {
|
|
598
|
+
readonly t: "LinkedContainer";
|
|
599
|
+
readonly es: "box";
|
|
600
|
+
readonly href: "/work/:slug";
|
|
601
|
+
readonly param: "next.slug";
|
|
602
|
+
readonly lay: {
|
|
603
|
+
readonly display: "flex";
|
|
604
|
+
readonly flexDirection: "column";
|
|
605
|
+
readonly gap: "6px";
|
|
606
|
+
readonly padding: "24px 0px 0px 0px";
|
|
607
|
+
};
|
|
608
|
+
readonly c: readonly [{
|
|
609
|
+
readonly t: "Text";
|
|
610
|
+
readonly es: "small";
|
|
611
|
+
readonly text: "Next project";
|
|
612
|
+
}, {
|
|
613
|
+
readonly t: "Heading";
|
|
614
|
+
readonly es: "h2";
|
|
615
|
+
readonly level: "h2";
|
|
616
|
+
readonly bind: "next.title";
|
|
617
|
+
}];
|
|
618
|
+
}];
|
|
619
|
+
readonly lay: {
|
|
620
|
+
readonly display: "flex";
|
|
621
|
+
readonly flexDirection: "column";
|
|
622
|
+
readonly gap: "32px";
|
|
623
|
+
};
|
|
624
|
+
};
|
|
625
|
+
};
|
|
626
|
+
readonly "about.story": {
|
|
627
|
+
readonly family: "content";
|
|
628
|
+
readonly label: "Story beside an image";
|
|
629
|
+
readonly node: {
|
|
630
|
+
readonly t: "Section";
|
|
631
|
+
readonly es: "section";
|
|
632
|
+
readonly c: readonly [{
|
|
633
|
+
readonly t: "Container";
|
|
634
|
+
readonly es: "box";
|
|
635
|
+
readonly lay: {
|
|
636
|
+
readonly display: "grid";
|
|
637
|
+
readonly gridTemplateColumns: "1fr 1fr";
|
|
638
|
+
readonly gap: "48px";
|
|
639
|
+
readonly alignItems: "start";
|
|
640
|
+
};
|
|
641
|
+
readonly resp: {
|
|
642
|
+
readonly mobile: {
|
|
643
|
+
readonly gridTemplateColumns: "minmax(0, 1fr)";
|
|
644
|
+
};
|
|
645
|
+
};
|
|
646
|
+
readonly c: readonly [{
|
|
647
|
+
readonly t: "Container";
|
|
648
|
+
readonly es: "box";
|
|
649
|
+
readonly lay: {
|
|
650
|
+
readonly display: "flex";
|
|
651
|
+
readonly flexDirection: "column";
|
|
652
|
+
readonly gap: "16px";
|
|
653
|
+
};
|
|
654
|
+
readonly c: readonly [{
|
|
655
|
+
readonly t: "Heading";
|
|
656
|
+
readonly es: "h2";
|
|
657
|
+
readonly level: "h2";
|
|
658
|
+
readonly ph: "copy";
|
|
659
|
+
readonly text: "How the studio started";
|
|
660
|
+
}, {
|
|
661
|
+
readonly t: "Text";
|
|
662
|
+
readonly es: "body";
|
|
663
|
+
readonly ph: "copy";
|
|
664
|
+
readonly text: "Tell your story in your own words: who you are, how you work, what you care about.";
|
|
665
|
+
}];
|
|
666
|
+
}, {
|
|
667
|
+
readonly t: "Image";
|
|
668
|
+
readonly es: "media";
|
|
669
|
+
readonly ph: "image";
|
|
670
|
+
readonly aspect: "4 / 3";
|
|
671
|
+
}];
|
|
672
|
+
}];
|
|
673
|
+
};
|
|
674
|
+
};
|
|
675
|
+
readonly "contact.split": {
|
|
676
|
+
readonly family: "contact";
|
|
677
|
+
readonly label: "Contact details beside a form";
|
|
678
|
+
readonly node: {
|
|
679
|
+
readonly t: "Section";
|
|
680
|
+
readonly es: "section";
|
|
681
|
+
readonly c: readonly [{
|
|
682
|
+
readonly t: "Container";
|
|
683
|
+
readonly es: "box";
|
|
684
|
+
readonly lay: {
|
|
685
|
+
readonly display: "grid";
|
|
686
|
+
readonly gridTemplateColumns: "0.9fr 1.1fr";
|
|
687
|
+
readonly gap: "48px";
|
|
688
|
+
readonly alignItems: "start";
|
|
689
|
+
};
|
|
690
|
+
readonly resp: {
|
|
691
|
+
readonly mobile: {
|
|
692
|
+
readonly gridTemplateColumns: "minmax(0, 1fr)";
|
|
693
|
+
};
|
|
694
|
+
};
|
|
695
|
+
readonly c: readonly [{
|
|
696
|
+
readonly t: "Container";
|
|
697
|
+
readonly es: "box";
|
|
698
|
+
readonly lay: {
|
|
699
|
+
readonly display: "flex";
|
|
700
|
+
readonly flexDirection: "column";
|
|
701
|
+
readonly gap: "16px";
|
|
702
|
+
};
|
|
703
|
+
readonly c: readonly [{
|
|
704
|
+
readonly t: "Heading";
|
|
705
|
+
readonly es: "h1";
|
|
706
|
+
readonly level: "h1";
|
|
707
|
+
readonly text: "Get in touch";
|
|
708
|
+
}, {
|
|
709
|
+
readonly t: "Text";
|
|
710
|
+
readonly es: "lead";
|
|
711
|
+
readonly ph: "copy";
|
|
712
|
+
readonly text: "Say how and when people can expect to hear back.";
|
|
713
|
+
}, {
|
|
714
|
+
readonly t: "Text";
|
|
715
|
+
readonly es: "body";
|
|
716
|
+
readonly ph: "email";
|
|
717
|
+
}, {
|
|
718
|
+
readonly t: "Text";
|
|
719
|
+
readonly es: "body";
|
|
720
|
+
readonly ph: "phone";
|
|
721
|
+
}, {
|
|
722
|
+
readonly t: "Text";
|
|
723
|
+
readonly es: "body";
|
|
724
|
+
readonly ph: "city";
|
|
725
|
+
}];
|
|
726
|
+
}, {
|
|
727
|
+
readonly t: "Container";
|
|
728
|
+
readonly es: "card";
|
|
729
|
+
readonly c: readonly [{
|
|
730
|
+
readonly t: "Form";
|
|
731
|
+
readonly preset: "contact";
|
|
732
|
+
readonly c: readonly [{
|
|
733
|
+
readonly t: "Field";
|
|
734
|
+
readonly control: "text";
|
|
735
|
+
readonly label: "Name";
|
|
736
|
+
readonly required: true;
|
|
737
|
+
}, {
|
|
738
|
+
readonly t: "Field";
|
|
739
|
+
readonly control: "email";
|
|
740
|
+
readonly label: "Email";
|
|
741
|
+
readonly required: true;
|
|
742
|
+
}, {
|
|
743
|
+
readonly t: "Field";
|
|
744
|
+
readonly control: "textarea";
|
|
745
|
+
readonly label: "Message";
|
|
746
|
+
readonly required: true;
|
|
747
|
+
}, {
|
|
748
|
+
readonly t: "SubmitButton";
|
|
749
|
+
readonly es: "button-primary";
|
|
750
|
+
readonly text: "Send";
|
|
751
|
+
}];
|
|
752
|
+
}];
|
|
753
|
+
}];
|
|
754
|
+
}];
|
|
755
|
+
};
|
|
756
|
+
};
|
|
757
|
+
};
|
|
758
|
+
declare const SPEC_SITE_TEMPLATES: {
|
|
759
|
+
readonly studio: {
|
|
760
|
+
readonly id: "studio";
|
|
761
|
+
readonly version: 1;
|
|
762
|
+
readonly label: "Studio";
|
|
763
|
+
readonly blurb: "A portfolio for a studio or service business: your work, what you do, and a way to reach you.";
|
|
764
|
+
readonly bestFor: readonly ["Architecture & interiors", "Design studios", "Photographers", "Agencies", "Consultants"];
|
|
765
|
+
readonly contentTypes: readonly [{
|
|
766
|
+
readonly name: "projects";
|
|
767
|
+
readonly label: "Projects";
|
|
768
|
+
readonly previewTextField: "title";
|
|
769
|
+
readonly previewImageField: "cover";
|
|
770
|
+
readonly fields: readonly [{
|
|
771
|
+
readonly name: "title";
|
|
772
|
+
readonly type: "string";
|
|
773
|
+
readonly controller: "text";
|
|
774
|
+
readonly required: true;
|
|
775
|
+
}, {
|
|
776
|
+
readonly name: "slug";
|
|
777
|
+
readonly type: "string";
|
|
778
|
+
readonly controller: "text";
|
|
779
|
+
readonly required: true;
|
|
780
|
+
readonly note: "derived from title at seed; no slug controller exists yet (gap)";
|
|
781
|
+
}, {
|
|
782
|
+
readonly name: "summary";
|
|
783
|
+
readonly type: "string";
|
|
784
|
+
readonly controller: "textarea";
|
|
785
|
+
}, {
|
|
786
|
+
readonly name: "cover";
|
|
787
|
+
readonly type: "string";
|
|
788
|
+
readonly controller: "image";
|
|
789
|
+
}, {
|
|
790
|
+
readonly name: "gallery";
|
|
791
|
+
readonly type: "array";
|
|
792
|
+
readonly controller: "mediaList";
|
|
793
|
+
}, {
|
|
794
|
+
readonly name: "year";
|
|
795
|
+
readonly type: "string";
|
|
796
|
+
readonly controller: "text";
|
|
797
|
+
}, {
|
|
798
|
+
readonly name: "location";
|
|
799
|
+
readonly type: "string";
|
|
800
|
+
readonly controller: "text";
|
|
801
|
+
}];
|
|
802
|
+
readonly seed: {
|
|
803
|
+
readonly count: 6;
|
|
804
|
+
readonly sample: true;
|
|
805
|
+
readonly isPublished: true;
|
|
806
|
+
readonly title: "Sample project {n}";
|
|
807
|
+
readonly slug: "sample-project-{n}";
|
|
808
|
+
readonly summary: "Replace this with a sentence about the project.";
|
|
809
|
+
readonly cover: "{sampleImage:n}";
|
|
810
|
+
readonly gallery: readonly ["{sampleImage:n+1}", "{sampleImage:n+2}"];
|
|
811
|
+
readonly year: "";
|
|
812
|
+
readonly location: "";
|
|
813
|
+
};
|
|
814
|
+
}];
|
|
815
|
+
readonly dataSources: readonly [{
|
|
816
|
+
readonly alias: "projects";
|
|
817
|
+
readonly type: "cms";
|
|
818
|
+
readonly mode: "query";
|
|
819
|
+
readonly contentType: "projects";
|
|
820
|
+
}, {
|
|
821
|
+
readonly alias: "projectsLatest";
|
|
822
|
+
readonly type: "cms";
|
|
823
|
+
readonly mode: "query";
|
|
824
|
+
readonly contentType: "projects";
|
|
825
|
+
readonly limit: 3;
|
|
826
|
+
}, {
|
|
827
|
+
readonly alias: "project";
|
|
828
|
+
readonly type: "cms";
|
|
829
|
+
readonly mode: "single";
|
|
830
|
+
readonly contentType: "projects";
|
|
831
|
+
readonly filterByRouteParam: {
|
|
832
|
+
readonly field: "slug";
|
|
833
|
+
readonly routeParam: "slug";
|
|
834
|
+
};
|
|
835
|
+
}, {
|
|
836
|
+
readonly alias: "projectNext";
|
|
837
|
+
readonly type: "relative";
|
|
838
|
+
readonly of: "project";
|
|
839
|
+
readonly op: "$siblings.next";
|
|
840
|
+
readonly within: "projects";
|
|
841
|
+
}];
|
|
842
|
+
readonly pages: readonly [{
|
|
843
|
+
readonly key: "home";
|
|
844
|
+
readonly name: "Home";
|
|
845
|
+
readonly route: "/";
|
|
846
|
+
readonly isHome: true;
|
|
847
|
+
readonly required: true;
|
|
848
|
+
readonly inNav: false;
|
|
849
|
+
readonly sections: readonly [{
|
|
850
|
+
readonly pattern: "hero.split";
|
|
851
|
+
}, {
|
|
852
|
+
readonly pattern: "projects.grid";
|
|
853
|
+
readonly binding: "projectsLatest";
|
|
854
|
+
}, {
|
|
855
|
+
readonly pattern: "services.three";
|
|
856
|
+
}, {
|
|
857
|
+
readonly pattern: "cta.band";
|
|
858
|
+
}];
|
|
859
|
+
}, {
|
|
860
|
+
readonly key: "work";
|
|
861
|
+
readonly name: "Work";
|
|
862
|
+
readonly route: "/work";
|
|
863
|
+
readonly required: true;
|
|
864
|
+
readonly inNav: true;
|
|
865
|
+
readonly sections: readonly [{
|
|
866
|
+
readonly pattern: "page-header.simple";
|
|
867
|
+
readonly slots: {
|
|
868
|
+
readonly eyebrow: "Portfolio";
|
|
869
|
+
readonly title: "Work";
|
|
870
|
+
};
|
|
871
|
+
}, {
|
|
872
|
+
readonly pattern: "projects.grid";
|
|
873
|
+
readonly binding: "projects";
|
|
874
|
+
readonly without: readonly ["header"];
|
|
875
|
+
}];
|
|
876
|
+
}, {
|
|
877
|
+
readonly key: "project";
|
|
878
|
+
readonly name: "Project";
|
|
879
|
+
readonly route: "/work/:slug";
|
|
880
|
+
readonly required: true;
|
|
881
|
+
readonly inNav: false;
|
|
882
|
+
readonly template: "projects";
|
|
883
|
+
readonly routeSource: "project";
|
|
884
|
+
readonly sections: readonly [{
|
|
885
|
+
readonly pattern: "project.hero";
|
|
886
|
+
}, {
|
|
887
|
+
readonly pattern: "project.gallery";
|
|
888
|
+
}, {
|
|
889
|
+
readonly pattern: "project.next";
|
|
890
|
+
}, {
|
|
891
|
+
readonly pattern: "cta.band";
|
|
892
|
+
}];
|
|
893
|
+
}, {
|
|
894
|
+
readonly key: "about";
|
|
895
|
+
readonly name: "About";
|
|
896
|
+
readonly route: "/about";
|
|
897
|
+
readonly required: false;
|
|
898
|
+
readonly inNav: true;
|
|
899
|
+
readonly sections: readonly [{
|
|
900
|
+
readonly pattern: "page-header.simple";
|
|
901
|
+
readonly slots: {
|
|
902
|
+
readonly eyebrow: "About";
|
|
903
|
+
readonly title: "About the studio";
|
|
904
|
+
};
|
|
905
|
+
}, {
|
|
906
|
+
readonly pattern: "about.story";
|
|
907
|
+
}, {
|
|
908
|
+
readonly pattern: "cta.band";
|
|
909
|
+
}];
|
|
910
|
+
}, {
|
|
911
|
+
readonly key: "contact";
|
|
912
|
+
readonly name: "Contact";
|
|
913
|
+
readonly route: "/contact";
|
|
914
|
+
readonly required: false;
|
|
915
|
+
readonly inNav: true;
|
|
916
|
+
readonly sections: readonly [{
|
|
917
|
+
readonly pattern: "contact.split";
|
|
918
|
+
}];
|
|
919
|
+
}];
|
|
920
|
+
readonly globals: {
|
|
921
|
+
readonly header: "nav.inline-cta";
|
|
922
|
+
readonly footer: "footer.columns";
|
|
923
|
+
};
|
|
924
|
+
};
|
|
925
|
+
};
|
|
926
|
+
|
|
927
|
+
/** What an untouched node of one registered type saves as (`NODE_BASELINES`, generated from the live
|
|
928
|
+
* iox-builder configs) — the builder serializer's flat `props` / `styleProps`, the trait names it has a
|
|
929
|
+
* slot for, and whether it holds children. */
|
|
930
|
+
interface NodeBaseline {
|
|
931
|
+
readonly props: Readonly<Record<string, unknown>>;
|
|
932
|
+
readonly styleProps: Readonly<Record<string, unknown>>;
|
|
933
|
+
readonly traits: ReadonlyArray<string>;
|
|
934
|
+
readonly styleTraits: ReadonlyArray<string>;
|
|
935
|
+
readonly container: boolean;
|
|
936
|
+
}
|
|
937
|
+
|
|
938
|
+
declare const NODE_BASELINES: Readonly<Record<string, NodeBaseline>>;
|
|
939
|
+
|
|
940
|
+
/**
|
|
941
|
+
* The Site Plan (contract `site.planShape`) — the ONE document the website wizard writes
|
|
942
|
+
* (`source.kind: template`) and the AI agent will write (`source.kind: ai`). One validator, one
|
|
943
|
+
* composer: everything the wizard proves is proven for the agent.
|
|
944
|
+
*/
|
|
945
|
+
declare const SITE_PLAN_VERSION = "1";
|
|
946
|
+
declare enum SitePlanSourceKind {
|
|
947
|
+
Template = "template",
|
|
948
|
+
Ai = "ai"
|
|
949
|
+
}
|
|
950
|
+
type SitePlanSource = {
|
|
951
|
+
kind: `${SitePlanSourceKind.Template}`;
|
|
952
|
+
templateId: string;
|
|
953
|
+
templateVersion: number;
|
|
954
|
+
} | {
|
|
955
|
+
kind: `${SitePlanSourceKind.Ai}`;
|
|
956
|
+
runId: string;
|
|
957
|
+
};
|
|
958
|
+
/** A fact a customer could be held to. Only ever the customer's own words; blank → a placeholder. */
|
|
959
|
+
type FactKey = keyof typeof SPEC_SITE_FACTS;
|
|
960
|
+
declare const FACT_KEYS: ReadonlyArray<FactKey>;
|
|
961
|
+
/** The label a missing fact shows, verbatim from the contract. */
|
|
962
|
+
declare const SITE_FACT_LABELS: Readonly<Record<FactKey, string>>;
|
|
963
|
+
interface SiteBusiness {
|
|
964
|
+
readonly name: string;
|
|
965
|
+
readonly tagline?: string;
|
|
966
|
+
readonly facts?: Readonly<Partial<Record<FactKey, string>>>;
|
|
967
|
+
}
|
|
968
|
+
interface ContentFieldPlan {
|
|
969
|
+
readonly name: string;
|
|
970
|
+
readonly type: string;
|
|
971
|
+
readonly controller: string;
|
|
972
|
+
readonly required?: boolean;
|
|
973
|
+
readonly note?: string;
|
|
974
|
+
}
|
|
975
|
+
/** How the content type's sample items are seeded. String values are templates: `{n}` is the item's
|
|
976
|
+
* 1-based number, `{sampleImage:n}` / `{sampleImage:n+k}` a bundled sample image (resolved by the build). */
|
|
977
|
+
interface ContentSeedPlan {
|
|
978
|
+
readonly count: number;
|
|
979
|
+
readonly sample: boolean;
|
|
980
|
+
readonly isPublished: boolean;
|
|
981
|
+
readonly [field: string]: unknown;
|
|
982
|
+
}
|
|
983
|
+
interface ContentTypePlan {
|
|
984
|
+
readonly name: string;
|
|
985
|
+
readonly label: string;
|
|
986
|
+
readonly previewTextField?: string;
|
|
987
|
+
readonly previewImageField?: string;
|
|
988
|
+
readonly fields: ReadonlyArray<ContentFieldPlan>;
|
|
989
|
+
readonly seed?: ContentSeedPlan;
|
|
990
|
+
}
|
|
991
|
+
declare enum PlanDataSourceType {
|
|
992
|
+
Cms = "cms",
|
|
993
|
+
Relative = "relative"
|
|
994
|
+
}
|
|
995
|
+
declare enum PlanDataSourceMode {
|
|
996
|
+
Query = "query",
|
|
997
|
+
Single = "single"
|
|
998
|
+
}
|
|
999
|
+
/** The relative operations a plan may name, and the shipped `RelativeSourceSpec` each one is. */
|
|
1000
|
+
declare enum RelativeOp {
|
|
1001
|
+
SiblingsNext = "$siblings.next",
|
|
1002
|
+
SiblingsPrev = "$siblings.prev"
|
|
1003
|
+
}
|
|
1004
|
+
interface CmsDataSourcePlan {
|
|
1005
|
+
readonly alias: string;
|
|
1006
|
+
readonly type: `${PlanDataSourceType.Cms}`;
|
|
1007
|
+
readonly mode: `${PlanDataSourceMode}`;
|
|
1008
|
+
readonly contentType: string;
|
|
1009
|
+
readonly limit?: number;
|
|
1010
|
+
readonly filterByRouteParam?: {
|
|
1011
|
+
readonly field: string;
|
|
1012
|
+
readonly routeParam: string;
|
|
1013
|
+
};
|
|
1014
|
+
}
|
|
1015
|
+
interface RelativeDataSourcePlan {
|
|
1016
|
+
readonly alias: string;
|
|
1017
|
+
readonly type: `${PlanDataSourceType.Relative}`;
|
|
1018
|
+
/** The subject: the alias of the current item. */
|
|
1019
|
+
readonly of: string;
|
|
1020
|
+
readonly op: `${RelativeOp}`;
|
|
1021
|
+
/** The collection the subject is located within. */
|
|
1022
|
+
readonly within: string;
|
|
1023
|
+
}
|
|
1024
|
+
type DataSourcePlan = CmsDataSourcePlan | RelativeDataSourcePlan;
|
|
1025
|
+
interface PageSectionPlan {
|
|
1026
|
+
readonly pattern: string;
|
|
1027
|
+
readonly slots?: Readonly<Record<string, string>>;
|
|
1028
|
+
/** The list source alias a pattern's `$binding` repeater iterates. */
|
|
1029
|
+
readonly binding?: string;
|
|
1030
|
+
/** Optional pattern parts (`optional: <id>`) to leave out. */
|
|
1031
|
+
readonly without?: ReadonlyArray<string>;
|
|
1032
|
+
}
|
|
1033
|
+
interface PagePlan {
|
|
1034
|
+
readonly key: string;
|
|
1035
|
+
readonly name: string;
|
|
1036
|
+
readonly route: string;
|
|
1037
|
+
readonly isHome?: boolean;
|
|
1038
|
+
/** Carried by templates (the wizard's Pages step); not part of the documented plan shape. */
|
|
1039
|
+
readonly required?: boolean;
|
|
1040
|
+
/** In the navigation (`$navPages`). Carried by templates; not part of the documented plan shape. */
|
|
1041
|
+
readonly inNav?: boolean;
|
|
1042
|
+
/** A template page: the content type it renders one item of. */
|
|
1043
|
+
readonly template?: string;
|
|
1044
|
+
/** The single source bound to the route item (`route.*`). */
|
|
1045
|
+
readonly routeSource?: string;
|
|
1046
|
+
readonly sections: ReadonlyArray<PageSectionPlan>;
|
|
1047
|
+
}
|
|
1048
|
+
declare enum GlobalSlot {
|
|
1049
|
+
Header = "header",
|
|
1050
|
+
Footer = "footer"
|
|
1051
|
+
}
|
|
1052
|
+
interface SitePlan {
|
|
1053
|
+
readonly version: typeof SITE_PLAN_VERSION;
|
|
1054
|
+
readonly source: SitePlanSource;
|
|
1055
|
+
readonly business: SiteBusiness;
|
|
1056
|
+
readonly design: Readonly<DesignChoices>;
|
|
1057
|
+
readonly contentTypes: ReadonlyArray<ContentTypePlan>;
|
|
1058
|
+
readonly dataSources: ReadonlyArray<DataSourcePlan>;
|
|
1059
|
+
readonly pages: ReadonlyArray<PagePlan>;
|
|
1060
|
+
readonly globals: Readonly<Record<`${GlobalSlot}`, string>>;
|
|
1061
|
+
}
|
|
1062
|
+
|
|
1063
|
+
/**
|
|
1064
|
+
* The pattern library (contract `site.patterns`): structure and element styles only — never a colour,
|
|
1065
|
+
* size or font. Each node is written in the contract's short vocabulary:
|
|
1066
|
+
*
|
|
1067
|
+
* `t` component type · `es` element style · `scheme` section colour scheme · `tag` a Container's html
|
|
1068
|
+
* tag · `level` a Heading's level · `lay` layout-only styleProps · `resp` per-breakpoint styleProps ·
|
|
1069
|
+
* `aspect` an Image's aspect ratio · `slot` author-editable text, filled from the plan's section slots ·
|
|
1070
|
+
* `fromBusiness` text from the plan's business · `text` the pattern's own words · `ph` a publish-blocking
|
|
1071
|
+
* placeholder (a FACT key, `copy` or `image`) · `bind` a binding path on the repeater item (`item.*`,
|
|
1072
|
+
* `page.*`), the route item (`route.*`) or its next sibling (`next.*`) · `src` what a Repeater iterates
|
|
1073
|
+
* (`$binding`, `$navPages`, `route.<array>`) · `href` a page route (`$page.route` = the nav item's) ·
|
|
1074
|
+
* `param` the value of the route's `:param` · `optional` a part a page may leave out (`without`) ·
|
|
1075
|
+
* `preset` a Form preset · `control` / `label` / `required` a Field's · `c` children.
|
|
1076
|
+
*/
|
|
1077
|
+
interface PatternNode {
|
|
1078
|
+
readonly t: string;
|
|
1079
|
+
readonly es?: string;
|
|
1080
|
+
readonly scheme?: string;
|
|
1081
|
+
readonly tag?: string;
|
|
1082
|
+
readonly level?: string;
|
|
1083
|
+
readonly lay?: Readonly<Record<string, string>>;
|
|
1084
|
+
readonly resp?: Readonly<Record<string, Readonly<Record<string, string>>>>;
|
|
1085
|
+
readonly aspect?: string;
|
|
1086
|
+
readonly slot?: string;
|
|
1087
|
+
readonly fromBusiness?: string;
|
|
1088
|
+
readonly text?: string;
|
|
1089
|
+
readonly ph?: string;
|
|
1090
|
+
readonly bind?: string;
|
|
1091
|
+
readonly src?: string;
|
|
1092
|
+
readonly href?: string;
|
|
1093
|
+
readonly param?: string;
|
|
1094
|
+
readonly optional?: string;
|
|
1095
|
+
readonly preset?: string;
|
|
1096
|
+
readonly control?: string;
|
|
1097
|
+
readonly label?: string;
|
|
1098
|
+
readonly required?: boolean;
|
|
1099
|
+
readonly c?: ReadonlyArray<PatternNode>;
|
|
1100
|
+
}
|
|
1101
|
+
declare enum PatternGlobalPosition {
|
|
1102
|
+
Before = "before",
|
|
1103
|
+
After = "after"
|
|
1104
|
+
}
|
|
1105
|
+
interface SitePattern {
|
|
1106
|
+
readonly family: string;
|
|
1107
|
+
readonly label: string;
|
|
1108
|
+
/** Set on a header/footer pattern: it renders on every page, before or after the page. */
|
|
1109
|
+
readonly global?: `${PatternGlobalPosition}`;
|
|
1110
|
+
readonly node: PatternNode;
|
|
1111
|
+
}
|
|
1112
|
+
declare const SITE_PATTERNS: Readonly<Record<string, SitePattern>>;
|
|
1113
|
+
/** The pattern placeholder kinds that are not FACT keys. */
|
|
1114
|
+
declare enum PatternPlaceholder {
|
|
1115
|
+
Copy = "copy",
|
|
1116
|
+
Image = "image"
|
|
1117
|
+
}
|
|
1118
|
+
/** The composer directives a pattern writes where a plan supplies the value. */
|
|
1119
|
+
declare enum PatternDirective {
|
|
1120
|
+
/** A Repeater's source: the section's `binding`. */
|
|
1121
|
+
Binding = "$binding",
|
|
1122
|
+
/** A Repeater's source: the plan's pages that are in the navigation. */
|
|
1123
|
+
NavPages = "$navPages",
|
|
1124
|
+
/** A Link's route: the nav item's route. */
|
|
1125
|
+
PageRoute = "$page.route"
|
|
1126
|
+
}
|
|
1127
|
+
/** The scopes a `bind` / `param` / `src` path starts with. */
|
|
1128
|
+
declare enum BindScope {
|
|
1129
|
+
/** The nearest Repeater's row. */
|
|
1130
|
+
Item = "item",
|
|
1131
|
+
/** The nearest Repeater's row, when that Repeater iterates the navigation's pages. */
|
|
1132
|
+
Page = "page",
|
|
1133
|
+
/** The page's route item (`routeSource`). */
|
|
1134
|
+
Route = "route",
|
|
1135
|
+
/** The route item's next sibling (the plan's `$siblings.next` source of the route item). */
|
|
1136
|
+
Next = "next"
|
|
1137
|
+
}
|
|
1138
|
+
declare function patternById(id: string | null | undefined): SitePattern | undefined;
|
|
1139
|
+
/** Every node of a pattern, depth first. */
|
|
1140
|
+
declare function patternNodes(pattern: SitePattern): PatternNode[];
|
|
1141
|
+
/** The slot names a plan section may fill. */
|
|
1142
|
+
declare function patternSlots(pattern: SitePattern): string[];
|
|
1143
|
+
/** The optional parts a plan section may leave out. */
|
|
1144
|
+
declare function patternOptionalParts(pattern: SitePattern): string[];
|
|
1145
|
+
/** True when the pattern has a Repeater iterating the section's `binding`. */
|
|
1146
|
+
declare function patternNeedsBinding(pattern: SitePattern): boolean;
|
|
1147
|
+
/** The bind scopes a pattern reads (`route`, `next`, …) — what its page must provide. */
|
|
1148
|
+
declare function patternScopes(pattern: SitePattern): Set<string>;
|
|
1149
|
+
|
|
1150
|
+
/** A site structure the wizard offers (contract `site.templates`). A template is a Site Plan without the
|
|
1151
|
+
* customer's part — the business and the look — which `planFromTemplate` adds. */
|
|
1152
|
+
interface SiteTemplate {
|
|
1153
|
+
readonly id: string;
|
|
1154
|
+
readonly version: number;
|
|
1155
|
+
readonly label: string;
|
|
1156
|
+
readonly blurb: string;
|
|
1157
|
+
readonly bestFor: ReadonlyArray<string>;
|
|
1158
|
+
readonly contentTypes: ReadonlyArray<ContentTypePlan>;
|
|
1159
|
+
readonly dataSources: ReadonlyArray<DataSourcePlan>;
|
|
1160
|
+
readonly pages: ReadonlyArray<PagePlan>;
|
|
1161
|
+
readonly globals: Readonly<Record<`${GlobalSlot}`, string>>;
|
|
1162
|
+
}
|
|
1163
|
+
declare const SITE_TEMPLATES: Readonly<Record<string, SiteTemplate>>;
|
|
1164
|
+
declare enum SiteTemplateId {
|
|
1165
|
+
Studio = "studio"
|
|
1166
|
+
}
|
|
1167
|
+
declare const STUDIO_TEMPLATE: SiteTemplate;
|
|
1168
|
+
interface TemplatePlanInput {
|
|
1169
|
+
business: SiteBusiness;
|
|
1170
|
+
design: DesignChoices;
|
|
1171
|
+
/** Keys of the template's OPTIONAL pages to leave out (the wizard's Pages step). */
|
|
1172
|
+
omitPages?: ReadonlyArray<string>;
|
|
1173
|
+
}
|
|
1174
|
+
declare class SiteTemplateError extends Error {
|
|
1175
|
+
}
|
|
1176
|
+
/**
|
|
1177
|
+
* The template as a Site Plan (`source.kind: template`), with the customer's business and look. A
|
|
1178
|
+
* required page cannot be left out, and an unknown key is refused — nothing is guessed.
|
|
1179
|
+
*/
|
|
1180
|
+
declare function planFromTemplate(template: SiteTemplate, input: TemplatePlanInput): SitePlan;
|
|
1181
|
+
|
|
1182
|
+
/**
|
|
1183
|
+
* A node exactly as a saved page layout stores it (the builder serializer's shape): flat `props` and
|
|
1184
|
+
* a FULL `styleProps` (self-describing — render-parity.md, task 10), the element style's pseudo-states,
|
|
1185
|
+
* sparse per-breakpoint overrides and the bindings. What the composer emits; what the builder reloads
|
|
1186
|
+
* and the engine renders, unchanged.
|
|
1187
|
+
*/
|
|
1188
|
+
interface SerializedBinding {
|
|
1189
|
+
prop: string;
|
|
1190
|
+
source: string;
|
|
1191
|
+
path: string;
|
|
1192
|
+
}
|
|
1193
|
+
type SerializedResponsive = Partial<Record<string, {
|
|
1194
|
+
styleProps?: Record<string, unknown>;
|
|
1195
|
+
}>>;
|
|
1196
|
+
interface SerializedNode {
|
|
1197
|
+
id: string;
|
|
1198
|
+
type: string;
|
|
1199
|
+
label?: string;
|
|
1200
|
+
props: Record<string, unknown>;
|
|
1201
|
+
styleProps: Record<string, unknown>;
|
|
1202
|
+
stateStyles?: Partial<Record<string, Record<string, unknown>>>;
|
|
1203
|
+
responsive?: SerializedResponsive;
|
|
1204
|
+
elementStyle?: string;
|
|
1205
|
+
bindings: SerializedBinding[];
|
|
1206
|
+
interactions: unknown[];
|
|
1207
|
+
isGlobal?: boolean;
|
|
1208
|
+
globalPosition?: `${PatternGlobalPosition}`;
|
|
1209
|
+
children?: SerializedNode[];
|
|
1210
|
+
}
|
|
1211
|
+
/** A pattern the composer cannot stamp as the builder would (an unregistered type, a trait the type has
|
|
1212
|
+
* no slot for, a style that does not apply). The plan is validated first, so this means the CONTRACT is
|
|
1213
|
+
* wrong — never something to work around. */
|
|
1214
|
+
declare class ComposeError extends Error {
|
|
1215
|
+
}
|
|
1216
|
+
/**
|
|
1217
|
+
* A NEW node of `type`, as the builder creates one (ComponentRegistryService.createConfig, serialized):
|
|
1218
|
+
* the type's constructor defaults, its text colour released to `inherit` (NEW_NODE_STYLE_DEFAULTS), then
|
|
1219
|
+
* ONE element style — `elementStyle` when given, else the type's default for its props (a Heading
|
|
1220
|
+
* follows its level). `props` are applied before the style is chosen.
|
|
1221
|
+
*/
|
|
1222
|
+
declare function createSerializedNode(id: string, type: string, props?: Record<string, unknown>, elementStyle?: string | null): SerializedNode;
|
|
1223
|
+
/** Refuse a style trait the type has no slot for — the builder would silently drop it. */
|
|
1224
|
+
declare function assertStyleSlots(type: string, names: ReadonlyArray<string>): void;
|
|
1225
|
+
/** Write style traits onto a node (each one a slot the type has). */
|
|
1226
|
+
declare function setStyleProps(node: SerializedNode, values: Readonly<Record<string, unknown>>): void;
|
|
1227
|
+
/** Every node of a tree, depth first. */
|
|
1228
|
+
declare function walkSerialized(nodes: ReadonlyArray<SerializedNode>, visit: (node: SerializedNode, ancestors: SerializedNode[]) => void, ancestors?: SerializedNode[]): void;
|
|
1229
|
+
|
|
1230
|
+
/**
|
|
1231
|
+
* The Site Plan validator — the gate in front of the composer. The wizard's plan and (later) the AI's
|
|
1232
|
+
* plan go through the SAME checks: an unknown pattern, a slot the pattern does not declare, a source
|
|
1233
|
+
* that does not exist, a page whose route item cannot be resolved — all refused, with a path, before a
|
|
1234
|
+
* single page is written. It never repairs: a model gets the issues back and rewrites.
|
|
1235
|
+
*/
|
|
1236
|
+
declare enum SitePlanIssueCode {
|
|
1237
|
+
/** A value of the wrong type, or a required value missing. */
|
|
1238
|
+
Shape = "shape",
|
|
1239
|
+
/** A key the plan shape does not have. */
|
|
1240
|
+
UnknownKey = "unknown-key",
|
|
1241
|
+
Version = "version",
|
|
1242
|
+
UnknownFlavor = "unknown-flavor",
|
|
1243
|
+
InvalidDesign = "invalid-design",
|
|
1244
|
+
MissingBusinessName = "missing-business-name",
|
|
1245
|
+
UnknownFact = "unknown-fact",
|
|
1246
|
+
Duplicate = "duplicate",
|
|
1247
|
+
ReservedAlias = "reserved-alias",
|
|
1248
|
+
UnknownContentType = "unknown-content-type",
|
|
1249
|
+
UnknownField = "unknown-field",
|
|
1250
|
+
UnknownDataSource = "unknown-data-source",
|
|
1251
|
+
InvalidDataSource = "invalid-data-source",
|
|
1252
|
+
InvalidRoute = "invalid-route",
|
|
1253
|
+
Home = "home",
|
|
1254
|
+
RouteSource = "route-source",
|
|
1255
|
+
UnknownPattern = "unknown-pattern",
|
|
1256
|
+
GlobalPattern = "global-pattern",
|
|
1257
|
+
UnknownSlot = "unknown-slot",
|
|
1258
|
+
UnknownOptionalPart = "unknown-optional-part",
|
|
1259
|
+
Binding = "binding",
|
|
1260
|
+
MissingScope = "missing-scope"
|
|
1261
|
+
}
|
|
1262
|
+
interface SitePlanIssue {
|
|
1263
|
+
code: SitePlanIssueCode;
|
|
1264
|
+
/** Where, as a dotted path into the plan (`pages[2].sections[0].binding`). */
|
|
1265
|
+
path: string;
|
|
1266
|
+
message: string;
|
|
1267
|
+
}
|
|
1268
|
+
interface SitePlanValidation {
|
|
1269
|
+
valid: boolean;
|
|
1270
|
+
issues: SitePlanIssue[];
|
|
1271
|
+
}
|
|
1272
|
+
declare class SitePlanError extends Error {
|
|
1273
|
+
readonly issues: ReadonlyArray<SitePlanIssue>;
|
|
1274
|
+
constructor(issues: ReadonlyArray<SitePlanIssue>);
|
|
1275
|
+
}
|
|
1276
|
+
/** The alias of the static source the composer writes for the navigation (`$navPages`). A plan source
|
|
1277
|
+
* may not take it. */
|
|
1278
|
+
declare const NAV_PAGES_ALIAS = "navPages";
|
|
1279
|
+
/** The `:param` names of a route, in order. */
|
|
1280
|
+
declare function routeParams(route: string): string[];
|
|
1281
|
+
/** The plan's `$siblings.next` source of `routeSource` — what a pattern's `next.*` reads. */
|
|
1282
|
+
declare function nextSourceOf(sources: Map<string, {
|
|
1283
|
+
type: string;
|
|
1284
|
+
of?: string;
|
|
1285
|
+
op?: string;
|
|
1286
|
+
}>, routeSource: string): string | null;
|
|
1287
|
+
/** Check a Site Plan against the plan shape and the pattern library. Never throws, never repairs. */
|
|
1288
|
+
declare function validateSitePlan(plan: unknown): SitePlanValidation;
|
|
1289
|
+
/** Throw a `SitePlanError` carrying every issue unless the plan is valid. */
|
|
1290
|
+
declare function assertValidSitePlan(plan: unknown): void;
|
|
1291
|
+
|
|
1292
|
+
/**
|
|
1293
|
+
* THE composer — a Site Plan in, ordinary IOX data out (design-system plan §6b, W1). Deterministic and
|
|
1294
|
+
* pure: the same plan composes to byte-identical output, with no clock, no randomness and no transport.
|
|
1295
|
+
* The wizard and the AI agent both end here; W2's site-build service writes what it returns.
|
|
1296
|
+
*
|
|
1297
|
+
* Every node is created the way the builder creates one (`createSerializedNode`): the type's full
|
|
1298
|
+
* constructor defaults, then ONE element style, then the pattern's layout. So a composed page is what
|
|
1299
|
+
* an author would have built by hand from the palette — the builder reloads it and saves it unchanged,
|
|
1300
|
+
* and the engine renders it with nothing to resolve. Never a colour, size or font a pattern did not
|
|
1301
|
+
* name; never a fact the customer did not give (blank → a placeholder carrying the fact's label).
|
|
1302
|
+
*/
|
|
1303
|
+
declare enum PlaceholderKind {
|
|
1304
|
+
/** A FACT the customer did not give (email, phone, city): publish-blocking. */
|
|
1305
|
+
Fact = "fact",
|
|
1306
|
+
/** The pattern's own words, for the author to rewrite. */
|
|
1307
|
+
Copy = "copy",
|
|
1308
|
+
/** An image slot with no image: the empty-image placeholder (DS3). */
|
|
1309
|
+
Image = "image"
|
|
1310
|
+
}
|
|
1311
|
+
interface ComposedPlaceholder {
|
|
1312
|
+
nodeId: string;
|
|
1313
|
+
/** The page key, or the global slot (`header` / `footer`), the node lives in. */
|
|
1314
|
+
owner: string;
|
|
1315
|
+
kind: PlaceholderKind;
|
|
1316
|
+
fact?: FactKey;
|
|
1317
|
+
slot?: string;
|
|
1318
|
+
/** What the node shows meanwhile: the fact's label, the pattern's copy, or '' for an image. */
|
|
1319
|
+
text: string;
|
|
1320
|
+
}
|
|
1321
|
+
declare enum ComposeIssueCode {
|
|
1322
|
+
/** A slot the plan and the business left empty and the pattern gives no words for — the node keeps
|
|
1323
|
+
* its type's default text. */
|
|
1324
|
+
UnfilledSlot = "unfilled-slot",
|
|
1325
|
+
/** A pattern links to a route the plan has no page for (an optional page was left out). */
|
|
1326
|
+
DanglingLink = "dangling-link"
|
|
1327
|
+
}
|
|
1328
|
+
interface ComposeIssue {
|
|
1329
|
+
code: ComposeIssueCode;
|
|
1330
|
+
nodeId: string;
|
|
1331
|
+
owner: string;
|
|
1332
|
+
detail: string;
|
|
1333
|
+
}
|
|
1334
|
+
interface ComposedPage {
|
|
1335
|
+
key: string;
|
|
1336
|
+
name: string;
|
|
1337
|
+
route: {
|
|
1338
|
+
path: string;
|
|
1339
|
+
};
|
|
1340
|
+
isHome: boolean;
|
|
1341
|
+
status: 'draft';
|
|
1342
|
+
/** DS3: every page the wizard creates follows the look (page-bg / text / font-body). */
|
|
1343
|
+
pageSettings: {
|
|
1344
|
+
designSystem: true;
|
|
1345
|
+
};
|
|
1346
|
+
layout: SerializedNode[];
|
|
1347
|
+
}
|
|
1348
|
+
interface ComposedDataSource {
|
|
1349
|
+
id: string;
|
|
1350
|
+
alias: string;
|
|
1351
|
+
type: string;
|
|
1352
|
+
mode: string;
|
|
1353
|
+
request: Record<string, unknown>;
|
|
1354
|
+
}
|
|
1355
|
+
type ComposedItem = Record<string, unknown> & {
|
|
1356
|
+
isPublished: boolean;
|
|
1357
|
+
isSample: boolean;
|
|
1358
|
+
};
|
|
1359
|
+
interface ComposedRoute {
|
|
1360
|
+
key: string;
|
|
1361
|
+
path: string;
|
|
1362
|
+
isHome: boolean;
|
|
1363
|
+
}
|
|
1364
|
+
interface ComposedSite {
|
|
1365
|
+
source: SitePlanSource;
|
|
1366
|
+
business: SiteBusiness;
|
|
1367
|
+
/** The look, completed against its pack (`resolveDesignChoices`) — what the build applies. */
|
|
1368
|
+
design: DesignChoices;
|
|
1369
|
+
/** The content types to create, as the plan states them. */
|
|
1370
|
+
schemas: ContentTypePlan[];
|
|
1371
|
+
/** Sample items per content type. `{sampleImage:k}` values name a bundled sample image the build resolves. */
|
|
1372
|
+
items: Record<string, ComposedItem[]>;
|
|
1373
|
+
/** Merged by alias into the org data-source library. */
|
|
1374
|
+
dataSources: ComposedDataSource[];
|
|
1375
|
+
pages: ComposedPage[];
|
|
1376
|
+
/** Header + footer: root nodes carry `isGlobal` and `globalPosition`. */
|
|
1377
|
+
globals: SerializedNode[];
|
|
1378
|
+
routes: ComposedRoute[];
|
|
1379
|
+
placeholders: ComposedPlaceholder[];
|
|
1380
|
+
issues: ComposeIssue[];
|
|
1381
|
+
}
|
|
1382
|
+
/** `{sampleImage:k}` — a bundled abstract sample image, never a stock photo (plan §6b). */
|
|
1383
|
+
declare const SAMPLE_IMAGE_REF: RegExp;
|
|
1384
|
+
declare function sampleImageRef(index: number): string;
|
|
1385
|
+
/** The 1-based index a `{sampleImage:k}` value names, or null. */
|
|
1386
|
+
declare function parseSampleImageRef(value: unknown): number | null;
|
|
1387
|
+
/** A page route as a base-relative href — the engine's `resolvePageHref` form (`/contact` → `contact`,
|
|
1388
|
+
* `/` → `./`), so a link stays inside the org's `<base href>`. */
|
|
1389
|
+
declare function baseRelativeHref(route: string): string;
|
|
1390
|
+
/**
|
|
1391
|
+
* Compose a Site Plan. Throws `SitePlanError` (every issue) when the plan does not validate — the
|
|
1392
|
+
* composer never repairs a plan.
|
|
1393
|
+
*/
|
|
1394
|
+
declare function composeSite(plan: SitePlan): ComposedSite;
|
|
1395
|
+
|
|
1396
|
+
export { BindScope, ComposeError, ComposeIssueCode, FACT_KEYS, GlobalSlot, NAV_PAGES_ALIAS, NODE_BASELINES, PatternDirective, PatternGlobalPosition, PatternPlaceholder, PlaceholderKind, PlanDataSourceMode, PlanDataSourceType, RelativeOp, SAMPLE_IMAGE_REF, SITE_FACT_LABELS, SITE_PATTERNS, SITE_PLAN_VERSION, SITE_TEMPLATES, SPEC_SITE_FACTS, SPEC_SITE_PATTERNS, SPEC_SITE_PLAN_SHAPE, SPEC_SITE_TEMPLATES, STUDIO_TEMPLATE, SitePlanError, SitePlanIssueCode, SitePlanSourceKind, SiteTemplateError, SiteTemplateId, assertStyleSlots, assertValidSitePlan, baseRelativeHref, composeSite, createSerializedNode, nextSourceOf, parseSampleImageRef, patternById, patternNeedsBinding, patternNodes, patternOptionalParts, patternScopes, patternSlots, planFromTemplate, routeParams, sampleImageRef, setStyleProps, validateSitePlan, walkSerialized };
|
|
1397
|
+
export type { CmsDataSourcePlan, ComposeIssue, ComposedDataSource, ComposedItem, ComposedPage, ComposedPlaceholder, ComposedRoute, ComposedSite, ContentFieldPlan, ContentSeedPlan, ContentTypePlan, DataSourcePlan, FactKey, NodeBaseline, PagePlan, PageSectionPlan, PatternNode, RelativeDataSourcePlan, SerializedBinding, SerializedNode, SerializedResponsive, SiteBusiness, SitePattern, SitePlan, SitePlanIssue, SitePlanSource, SitePlanValidation, SiteTemplate, TemplatePlanInput };
|