@vectoriox/iox-ui 5.41.0 → 5.42.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/composite-core/index.d.ts +2 -0
- package/fesm2022/vectoriox-iox-ui-composite-core.mjs +7 -5
- package/fesm2022/vectoriox-iox-ui-composite-core.mjs.map +1 -1
- package/fesm2022/vectoriox-iox-ui-generation-core.mjs +81 -36
- package/fesm2022/vectoriox-iox-ui-generation-core.mjs.map +1 -1
- package/generation-core/index.d.ts +69 -24
- package/package.json +1 -1
- package/src/composite-core/card.ts +6 -4
- package/src/composite-core/segmented.ts +4 -2
- package/src/generation-core/compose-site.ts +1 -0
- package/src/generation-core/patterns.ts +4 -3
- package/src/generation-core/site-spec.generated.ts +80 -36
|
@@ -159,7 +159,7 @@ declare const SPEC_SITE_PATTERNS: {
|
|
|
159
159
|
}];
|
|
160
160
|
};
|
|
161
161
|
};
|
|
162
|
-
readonly "footer.
|
|
162
|
+
readonly "footer.three-column": {
|
|
163
163
|
readonly family: "footer";
|
|
164
164
|
readonly label: "Footer, three columns";
|
|
165
165
|
readonly global: "after";
|
|
@@ -341,7 +341,7 @@ declare const SPEC_SITE_PATTERNS: {
|
|
|
341
341
|
}];
|
|
342
342
|
};
|
|
343
343
|
};
|
|
344
|
-
readonly "
|
|
344
|
+
readonly "collection.card-grid": {
|
|
345
345
|
readonly family: "collection";
|
|
346
346
|
readonly label: "Project cards, three across";
|
|
347
347
|
readonly node: {
|
|
@@ -408,8 +408,8 @@ declare const SPEC_SITE_PATTERNS: {
|
|
|
408
408
|
};
|
|
409
409
|
};
|
|
410
410
|
};
|
|
411
|
-
readonly "
|
|
412
|
-
readonly family: "
|
|
411
|
+
readonly "feature.triad": {
|
|
412
|
+
readonly family: "feature";
|
|
413
413
|
readonly label: "Three services";
|
|
414
414
|
readonly node: {
|
|
415
415
|
readonly t: "Section";
|
|
@@ -503,7 +503,7 @@ declare const SPEC_SITE_PATTERNS: {
|
|
|
503
503
|
};
|
|
504
504
|
};
|
|
505
505
|
};
|
|
506
|
-
readonly "cta.
|
|
506
|
+
readonly "cta.banner": {
|
|
507
507
|
readonly family: "cta";
|
|
508
508
|
readonly label: "Call to action band";
|
|
509
509
|
readonly node: {
|
|
@@ -914,6 +914,9 @@ declare const SPEC_SITE_PATTERNS: {
|
|
|
914
914
|
readonly slot: "eyebrow";
|
|
915
915
|
readonly ph: "copy";
|
|
916
916
|
readonly text: "Pricing";
|
|
917
|
+
readonly lay: {
|
|
918
|
+
readonly textAlign: "center";
|
|
919
|
+
};
|
|
917
920
|
}, {
|
|
918
921
|
readonly t: "Heading";
|
|
919
922
|
readonly es: "h2";
|
|
@@ -921,6 +924,9 @@ declare const SPEC_SITE_PATTERNS: {
|
|
|
921
924
|
readonly slot: "title";
|
|
922
925
|
readonly ph: "copy";
|
|
923
926
|
readonly text: "Plans";
|
|
927
|
+
readonly lay: {
|
|
928
|
+
readonly textAlign: "center";
|
|
929
|
+
};
|
|
924
930
|
}];
|
|
925
931
|
}, {
|
|
926
932
|
readonly t: "Container";
|
|
@@ -934,6 +940,7 @@ declare const SPEC_SITE_PATTERNS: {
|
|
|
934
940
|
readonly position: "sticky";
|
|
935
941
|
readonly top: "calc(12px + env(safe-area-inset-top, 0px))";
|
|
936
942
|
readonly zIndex: "2";
|
|
943
|
+
readonly width: "100%";
|
|
937
944
|
};
|
|
938
945
|
};
|
|
939
946
|
}, {
|
|
@@ -982,10 +989,16 @@ declare const SPEC_SITE_PATTERNS: {
|
|
|
982
989
|
readonly es: "price";
|
|
983
990
|
readonly ph: "price";
|
|
984
991
|
readonly text: "Monthly price";
|
|
992
|
+
readonly lay: {
|
|
993
|
+
readonly width: "auto";
|
|
994
|
+
};
|
|
985
995
|
}, {
|
|
986
996
|
readonly t: "Text";
|
|
987
997
|
readonly es: "small";
|
|
988
998
|
readonly text: "per month";
|
|
999
|
+
readonly lay: {
|
|
1000
|
+
readonly width: "auto";
|
|
1001
|
+
};
|
|
989
1002
|
}];
|
|
990
1003
|
}, {
|
|
991
1004
|
readonly t: "Container";
|
|
@@ -1003,10 +1016,16 @@ declare const SPEC_SITE_PATTERNS: {
|
|
|
1003
1016
|
readonly es: "price";
|
|
1004
1017
|
readonly ph: "price";
|
|
1005
1018
|
readonly text: "Yearly price";
|
|
1019
|
+
readonly lay: {
|
|
1020
|
+
readonly width: "auto";
|
|
1021
|
+
};
|
|
1006
1022
|
}, {
|
|
1007
1023
|
readonly t: "Text";
|
|
1008
1024
|
readonly es: "small";
|
|
1009
1025
|
readonly text: "per year";
|
|
1026
|
+
readonly lay: {
|
|
1027
|
+
readonly width: "auto";
|
|
1028
|
+
};
|
|
1010
1029
|
}];
|
|
1011
1030
|
}, {
|
|
1012
1031
|
readonly t: "Container";
|
|
@@ -1024,7 +1043,7 @@ declare const SPEC_SITE_PATTERNS: {
|
|
|
1024
1043
|
readonly display: "flex";
|
|
1025
1044
|
readonly flexWrap: "nowrap";
|
|
1026
1045
|
readonly gap: "8px";
|
|
1027
|
-
readonly alignItems: "
|
|
1046
|
+
readonly alignItems: "center";
|
|
1028
1047
|
};
|
|
1029
1048
|
readonly c: readonly [{
|
|
1030
1049
|
readonly t: "Icon";
|
|
@@ -1043,7 +1062,7 @@ declare const SPEC_SITE_PATTERNS: {
|
|
|
1043
1062
|
readonly display: "flex";
|
|
1044
1063
|
readonly flexWrap: "nowrap";
|
|
1045
1064
|
readonly gap: "8px";
|
|
1046
|
-
readonly alignItems: "
|
|
1065
|
+
readonly alignItems: "center";
|
|
1047
1066
|
};
|
|
1048
1067
|
readonly c: readonly [{
|
|
1049
1068
|
readonly t: "Icon";
|
|
@@ -1062,7 +1081,7 @@ declare const SPEC_SITE_PATTERNS: {
|
|
|
1062
1081
|
readonly display: "flex";
|
|
1063
1082
|
readonly flexWrap: "nowrap";
|
|
1064
1083
|
readonly gap: "8px";
|
|
1065
|
-
readonly alignItems: "
|
|
1084
|
+
readonly alignItems: "center";
|
|
1066
1085
|
};
|
|
1067
1086
|
readonly c: readonly [{
|
|
1068
1087
|
readonly t: "Icon";
|
|
@@ -1103,6 +1122,7 @@ declare const SPEC_SITE_PATTERNS: {
|
|
|
1103
1122
|
readonly ph: "copy";
|
|
1104
1123
|
readonly scheme: "accent";
|
|
1105
1124
|
readonly badge: "neutral";
|
|
1125
|
+
readonly icon: "ph ph-sparkle";
|
|
1106
1126
|
readonly parts: {
|
|
1107
1127
|
readonly media: false;
|
|
1108
1128
|
readonly eyebrow: false;
|
|
@@ -1130,10 +1150,16 @@ declare const SPEC_SITE_PATTERNS: {
|
|
|
1130
1150
|
readonly es: "price";
|
|
1131
1151
|
readonly ph: "price";
|
|
1132
1152
|
readonly text: "Monthly price";
|
|
1153
|
+
readonly lay: {
|
|
1154
|
+
readonly width: "auto";
|
|
1155
|
+
};
|
|
1133
1156
|
}, {
|
|
1134
1157
|
readonly t: "Text";
|
|
1135
1158
|
readonly es: "small";
|
|
1136
1159
|
readonly text: "per month";
|
|
1160
|
+
readonly lay: {
|
|
1161
|
+
readonly width: "auto";
|
|
1162
|
+
};
|
|
1137
1163
|
}];
|
|
1138
1164
|
}, {
|
|
1139
1165
|
readonly t: "Container";
|
|
@@ -1151,10 +1177,16 @@ declare const SPEC_SITE_PATTERNS: {
|
|
|
1151
1177
|
readonly es: "price";
|
|
1152
1178
|
readonly ph: "price";
|
|
1153
1179
|
readonly text: "Yearly price";
|
|
1180
|
+
readonly lay: {
|
|
1181
|
+
readonly width: "auto";
|
|
1182
|
+
};
|
|
1154
1183
|
}, {
|
|
1155
1184
|
readonly t: "Text";
|
|
1156
1185
|
readonly es: "small";
|
|
1157
1186
|
readonly text: "per year";
|
|
1187
|
+
readonly lay: {
|
|
1188
|
+
readonly width: "auto";
|
|
1189
|
+
};
|
|
1158
1190
|
}];
|
|
1159
1191
|
}, {
|
|
1160
1192
|
readonly t: "Container";
|
|
@@ -1172,7 +1204,7 @@ declare const SPEC_SITE_PATTERNS: {
|
|
|
1172
1204
|
readonly display: "flex";
|
|
1173
1205
|
readonly flexWrap: "nowrap";
|
|
1174
1206
|
readonly gap: "8px";
|
|
1175
|
-
readonly alignItems: "
|
|
1207
|
+
readonly alignItems: "center";
|
|
1176
1208
|
};
|
|
1177
1209
|
readonly c: readonly [{
|
|
1178
1210
|
readonly t: "Icon";
|
|
@@ -1191,7 +1223,7 @@ declare const SPEC_SITE_PATTERNS: {
|
|
|
1191
1223
|
readonly display: "flex";
|
|
1192
1224
|
readonly flexWrap: "nowrap";
|
|
1193
1225
|
readonly gap: "8px";
|
|
1194
|
-
readonly alignItems: "
|
|
1226
|
+
readonly alignItems: "center";
|
|
1195
1227
|
};
|
|
1196
1228
|
readonly c: readonly [{
|
|
1197
1229
|
readonly t: "Icon";
|
|
@@ -1210,7 +1242,7 @@ declare const SPEC_SITE_PATTERNS: {
|
|
|
1210
1242
|
readonly display: "flex";
|
|
1211
1243
|
readonly flexWrap: "nowrap";
|
|
1212
1244
|
readonly gap: "8px";
|
|
1213
|
-
readonly alignItems: "
|
|
1245
|
+
readonly alignItems: "center";
|
|
1214
1246
|
};
|
|
1215
1247
|
readonly c: readonly [{
|
|
1216
1248
|
readonly t: "Icon";
|
|
@@ -1275,10 +1307,16 @@ declare const SPEC_SITE_PATTERNS: {
|
|
|
1275
1307
|
readonly es: "price";
|
|
1276
1308
|
readonly ph: "price";
|
|
1277
1309
|
readonly text: "Monthly price";
|
|
1310
|
+
readonly lay: {
|
|
1311
|
+
readonly width: "auto";
|
|
1312
|
+
};
|
|
1278
1313
|
}, {
|
|
1279
1314
|
readonly t: "Text";
|
|
1280
1315
|
readonly es: "small";
|
|
1281
1316
|
readonly text: "per month";
|
|
1317
|
+
readonly lay: {
|
|
1318
|
+
readonly width: "auto";
|
|
1319
|
+
};
|
|
1282
1320
|
}];
|
|
1283
1321
|
}, {
|
|
1284
1322
|
readonly t: "Container";
|
|
@@ -1296,10 +1334,16 @@ declare const SPEC_SITE_PATTERNS: {
|
|
|
1296
1334
|
readonly es: "price";
|
|
1297
1335
|
readonly ph: "price";
|
|
1298
1336
|
readonly text: "Yearly price";
|
|
1337
|
+
readonly lay: {
|
|
1338
|
+
readonly width: "auto";
|
|
1339
|
+
};
|
|
1299
1340
|
}, {
|
|
1300
1341
|
readonly t: "Text";
|
|
1301
1342
|
readonly es: "small";
|
|
1302
1343
|
readonly text: "per year";
|
|
1344
|
+
readonly lay: {
|
|
1345
|
+
readonly width: "auto";
|
|
1346
|
+
};
|
|
1303
1347
|
}];
|
|
1304
1348
|
}, {
|
|
1305
1349
|
readonly t: "Container";
|
|
@@ -1317,7 +1361,7 @@ declare const SPEC_SITE_PATTERNS: {
|
|
|
1317
1361
|
readonly display: "flex";
|
|
1318
1362
|
readonly flexWrap: "nowrap";
|
|
1319
1363
|
readonly gap: "8px";
|
|
1320
|
-
readonly alignItems: "
|
|
1364
|
+
readonly alignItems: "center";
|
|
1321
1365
|
};
|
|
1322
1366
|
readonly c: readonly [{
|
|
1323
1367
|
readonly t: "Icon";
|
|
@@ -1336,7 +1380,7 @@ declare const SPEC_SITE_PATTERNS: {
|
|
|
1336
1380
|
readonly display: "flex";
|
|
1337
1381
|
readonly flexWrap: "nowrap";
|
|
1338
1382
|
readonly gap: "8px";
|
|
1339
|
-
readonly alignItems: "
|
|
1383
|
+
readonly alignItems: "center";
|
|
1340
1384
|
};
|
|
1341
1385
|
readonly c: readonly [{
|
|
1342
1386
|
readonly t: "Icon";
|
|
@@ -1355,7 +1399,7 @@ declare const SPEC_SITE_PATTERNS: {
|
|
|
1355
1399
|
readonly display: "flex";
|
|
1356
1400
|
readonly flexWrap: "nowrap";
|
|
1357
1401
|
readonly gap: "8px";
|
|
1358
|
-
readonly alignItems: "
|
|
1402
|
+
readonly alignItems: "center";
|
|
1359
1403
|
};
|
|
1360
1404
|
readonly c: readonly [{
|
|
1361
1405
|
readonly t: "Icon";
|
|
@@ -1638,12 +1682,12 @@ declare const SPEC_SITE_TEMPLATES: {
|
|
|
1638
1682
|
readonly sections: readonly [{
|
|
1639
1683
|
readonly pattern: "hero.split";
|
|
1640
1684
|
}, {
|
|
1641
|
-
readonly pattern: "
|
|
1685
|
+
readonly pattern: "collection.card-grid";
|
|
1642
1686
|
readonly binding: "projectsLatest";
|
|
1643
1687
|
}, {
|
|
1644
|
-
readonly pattern: "
|
|
1688
|
+
readonly pattern: "feature.triad";
|
|
1645
1689
|
}, {
|
|
1646
|
-
readonly pattern: "cta.
|
|
1690
|
+
readonly pattern: "cta.banner";
|
|
1647
1691
|
}];
|
|
1648
1692
|
}, {
|
|
1649
1693
|
readonly key: "work";
|
|
@@ -1658,7 +1702,7 @@ declare const SPEC_SITE_TEMPLATES: {
|
|
|
1658
1702
|
readonly title: "Work";
|
|
1659
1703
|
};
|
|
1660
1704
|
}, {
|
|
1661
|
-
readonly pattern: "
|
|
1705
|
+
readonly pattern: "collection.card-grid";
|
|
1662
1706
|
readonly binding: "projects";
|
|
1663
1707
|
readonly without: readonly ["header"];
|
|
1664
1708
|
}];
|
|
@@ -1677,7 +1721,7 @@ declare const SPEC_SITE_TEMPLATES: {
|
|
|
1677
1721
|
}, {
|
|
1678
1722
|
readonly pattern: "project.next";
|
|
1679
1723
|
}, {
|
|
1680
|
-
readonly pattern: "cta.
|
|
1724
|
+
readonly pattern: "cta.banner";
|
|
1681
1725
|
}];
|
|
1682
1726
|
}, {
|
|
1683
1727
|
readonly key: "about";
|
|
@@ -1694,7 +1738,7 @@ declare const SPEC_SITE_TEMPLATES: {
|
|
|
1694
1738
|
}, {
|
|
1695
1739
|
readonly pattern: "about.story";
|
|
1696
1740
|
}, {
|
|
1697
|
-
readonly pattern: "cta.
|
|
1741
|
+
readonly pattern: "cta.banner";
|
|
1698
1742
|
}];
|
|
1699
1743
|
}, {
|
|
1700
1744
|
readonly key: "contact";
|
|
@@ -1708,7 +1752,7 @@ declare const SPEC_SITE_TEMPLATES: {
|
|
|
1708
1752
|
}];
|
|
1709
1753
|
readonly globals: {
|
|
1710
1754
|
readonly header: "nav.inline-cta";
|
|
1711
|
-
readonly footer: "footer.
|
|
1755
|
+
readonly footer: "footer.three-column";
|
|
1712
1756
|
};
|
|
1713
1757
|
};
|
|
1714
1758
|
};
|
|
@@ -1905,8 +1949,9 @@ interface SitePlan {
|
|
|
1905
1949
|
* CC4b (`pricing.tiers`): `recipe: 'segmented'` stamps a Segmented control (Monthly · Yearly, named by `name`, its own
|
|
1906
1950
|
* `lay` / `resp`) · `shownWhen` hides a node at base and shows it while the pattern's segmented option of that key is
|
|
1907
1951
|
* on (the targeted `trigger-on`) · `ph: 'price'` a price the studio types (a publish-blocking placeholder showing its
|
|
1908
|
-
* label) · on a card recipe: `words` (title / text / badge), `badge` (the badge's tone)
|
|
1909
|
-
* `c` — nodes joining its Content column · `icon` an Icon's glyph · `layer` the node's name in the
|
|
1952
|
+
* label) · on a card recipe: `words` (title / text / badge), `badge` (the badge's tone) and `icon` (its glyph), `scheme`
|
|
1953
|
+
* (the Brand card), and `c` — nodes joining its Content column · `icon` an Icon's glyph · `layer` the node's name in the
|
|
1954
|
+
* layer tree.
|
|
1910
1955
|
*/
|
|
1911
1956
|
interface PatternNode {
|
|
1912
1957
|
readonly t: string;
|
|
@@ -1951,7 +1996,7 @@ interface PatternNode {
|
|
|
1951
1996
|
readonly words?: Readonly<Record<string, string>>;
|
|
1952
1997
|
/** CC4b: a card recipe's badge tone (`neutral` · `success` · `warning` · `accent`). */
|
|
1953
1998
|
readonly badge?: string;
|
|
1954
|
-
/** CC4b: an Icon's glyph (`ph ph-check`). */
|
|
1999
|
+
/** CC4b: an Icon's glyph (`ph ph-check`) — on a card recipe, its badge's glyph. */
|
|
1955
2000
|
readonly icon?: string;
|
|
1956
2001
|
/** CC4b: the node's name in the layer tree (`Price · Monthly`). */
|
|
1957
2002
|
readonly layer?: string;
|
package/package.json
CHANGED
|
@@ -230,6 +230,8 @@ export interface CardOptions extends CardEditOptions {
|
|
|
230
230
|
parts?: Partial<Record<CardPart, boolean>>;
|
|
231
231
|
words?: Partial<CardWords>;
|
|
232
232
|
badgeTone?: BadgeTone;
|
|
233
|
+
/** The badge's glyph (else its tone's — `BADGE_TONE_ICONS`): the pricing pattern's "Most popular" sparkle (CC4b). */
|
|
234
|
+
badgeIcon?: string;
|
|
233
235
|
}
|
|
234
236
|
|
|
235
237
|
|
|
@@ -249,7 +251,7 @@ function buttonLabel(create: CompositeNodeFactory, key: string, words: string):
|
|
|
249
251
|
}
|
|
250
252
|
|
|
251
253
|
/** Each optional part (and the locked title) as the recipe builds it. */
|
|
252
|
-
const PART_BUILDERS: Readonly<Record<CardPart, (create: CompositeNodeFactory, words: CardWords, tone: BadgeTone) => CompositeNode>> = {
|
|
254
|
+
const PART_BUILDERS: Readonly<Record<CardPart, (create: CompositeNodeFactory, words: CardWords, tone: BadgeTone, badgeIcon?: string) => CompositeNode>> = {
|
|
253
255
|
[CardPart.Media]: (create) => {
|
|
254
256
|
const media = make(create, 'media', Type.Container, CardRole.Media, Style.Box, {}, 'Media');
|
|
255
257
|
const image = make(create, 'image', Type.Image, null, Style.Media, { src: '', alt: '' });
|
|
@@ -257,8 +259,8 @@ const PART_BUILDERS: Readonly<Record<CardPart, (create: CompositeNodeFactory, wo
|
|
|
257
259
|
media.children = [image];
|
|
258
260
|
return media;
|
|
259
261
|
},
|
|
260
|
-
[CardPart.Badge]: (create, words, tone) => {
|
|
261
|
-
const badge = buildBadge(create, { tone, text: words.badge, key: 'badge' });
|
|
262
|
+
[CardPart.Badge]: (create, words, tone, badgeIcon) => {
|
|
263
|
+
const badge = buildBadge(create, { tone, text: words.badge, key: 'badge', ...(badgeIcon ? { icon: badgeIcon } : {}) });
|
|
262
264
|
badge.role = CardRole.Badge;
|
|
263
265
|
badge.label = 'Badge';
|
|
264
266
|
return badge;
|
|
@@ -296,7 +298,7 @@ export function buildCardRecipe(create: CompositeNodeFactory, options: CardOptio
|
|
|
296
298
|
...(on(CardPart.Actions) ? [PART_BUILDERS[CardPart.Actions](create, words, tone)] : []),
|
|
297
299
|
];
|
|
298
300
|
card.children = [...(on(CardPart.Media) ? [PART_BUILDERS[CardPart.Media](create, words, tone)] : []), content];
|
|
299
|
-
if (on(CardPart.Badge)) placeBadge(card, PART_BUILDERS[CardPart.Badge](create, words, tone), true);
|
|
301
|
+
if (on(CardPart.Badge)) placeBadge(card, PART_BUILDERS[CardPart.Badge](create, words, tone, options.badgeIcon), true);
|
|
300
302
|
applyCardLayout(card, options.layout ?? CardLayout.Top, options);
|
|
301
303
|
return card;
|
|
302
304
|
}
|
|
@@ -68,10 +68,12 @@ enum Style {
|
|
|
68
68
|
const ZERO_BOX = '0px 0px 0px 0px';
|
|
69
69
|
|
|
70
70
|
/** What each part holds — layout only; its LOOK is its element style (the track's fill, border, radius and pad; the
|
|
71
|
-
* option's ink, pad, radius and 44px target). The options sit in a flex row a gap token apart (board 10)
|
|
71
|
+
* option's ink, pad, radius and 44px target). The options sit in a flex row a gap token apart (board 10); each GROWS,
|
|
72
|
+
* which changes nothing while the track hugs them and shares the row when the track is stretched (the pricing
|
|
73
|
+
* pattern's phone layer: board 10's full-width control). */
|
|
72
74
|
const PART_BASE: Readonly<Record<string, Readonly<Record<string, string>>>> = {
|
|
73
75
|
[SegmentedRole.Segmented]: { display: 'inline-flex', flexDirection: 'row', alignItems: 'stretch', gap: 'var(--iox-segmented-gap)', width: 'auto', maxWidth: '100%', height: 'auto' },
|
|
74
|
-
[SegmentedRole.Option]: { display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: '8px', width: 'auto', height: 'auto', cursor: 'pointer' },
|
|
76
|
+
[SegmentedRole.Option]: { display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: '8px', width: 'auto', height: 'auto', cursor: 'pointer', flexGrow: '1' },
|
|
75
77
|
};
|
|
76
78
|
const LABEL_BASE: Readonly<Record<string, string>> = { width: 'auto', minHeight: 'auto', padding: ZERO_BOX, margin: ZERO_BOX };
|
|
77
79
|
/** The badge inside an option keeps to the option's row (never its own line). */
|
|
@@ -672,6 +672,7 @@ function composeRecipe(pn: PatternNode, id: string, repeater: RepeaterScope | nu
|
|
|
672
672
|
for (const key of Object.keys(pn.words ?? {})) if (!CARD_WORD_KEYS.includes(key)) throw new ComposeError(`${id}: a card has no words "${key}"`);
|
|
673
673
|
const card = buildCardRecipe(factory, {
|
|
674
674
|
layout, parts: pn.parts as Partial<Record<CardPart, boolean>>, words: pn.words as Partial<CardWords> | undefined, badgeTone: tone,
|
|
675
|
+
...(pn.icon ? { badgeIcon: pn.icon } : {}),
|
|
675
676
|
}) as SerializedNode;
|
|
676
677
|
if (pn.scheme) {
|
|
677
678
|
if (!COLOR_SCHEMES.some(c => c.id === pn.scheme)) throw new ComposeError(`${id}: no colour scheme "${pn.scheme}"`);
|
|
@@ -25,8 +25,9 @@ import { SPEC_SITE_PATTERNS } from './site-spec.generated';
|
|
|
25
25
|
* CC4b (`pricing.tiers`): `recipe: 'segmented'` stamps a Segmented control (Monthly · Yearly, named by `name`, its own
|
|
26
26
|
* `lay` / `resp`) · `shownWhen` hides a node at base and shows it while the pattern's segmented option of that key is
|
|
27
27
|
* on (the targeted `trigger-on`) · `ph: 'price'` a price the studio types (a publish-blocking placeholder showing its
|
|
28
|
-
* label) · on a card recipe: `words` (title / text / badge), `badge` (the badge's tone)
|
|
29
|
-
* `c` — nodes joining its Content column · `icon` an Icon's glyph · `layer` the node's name in the
|
|
28
|
+
* label) · on a card recipe: `words` (title / text / badge), `badge` (the badge's tone) and `icon` (its glyph), `scheme`
|
|
29
|
+
* (the Brand card), and `c` — nodes joining its Content column · `icon` an Icon's glyph · `layer` the node's name in the
|
|
30
|
+
* layer tree.
|
|
30
31
|
*/
|
|
31
32
|
export interface PatternNode {
|
|
32
33
|
readonly t: string;
|
|
@@ -71,7 +72,7 @@ export interface PatternNode {
|
|
|
71
72
|
readonly words?: Readonly<Record<string, string>>;
|
|
72
73
|
/** CC4b: a card recipe's badge tone (`neutral` · `success` · `warning` · `accent`). */
|
|
73
74
|
readonly badge?: string;
|
|
74
|
-
/** CC4b: an Icon's glyph (`ph ph-check`). */
|
|
75
|
+
/** CC4b: an Icon's glyph (`ph ph-check`) — on a card recipe, its badge's glyph. */
|
|
75
76
|
readonly icon?: string;
|
|
76
77
|
/** CC4b: the node's name in the layer tree (`Price · Monthly`). */
|
|
77
78
|
readonly layer?: string;
|