@vectoriox/iox-ui 5.39.0 → 5.41.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 +210 -12
- package/design-core/index.d.ts +694 -17
- package/fesm2022/vectoriox-iox-ui-actions-core.mjs +4 -3
- package/fesm2022/vectoriox-iox-ui-actions-core.mjs.map +1 -1
- package/fesm2022/vectoriox-iox-ui-composite-core.mjs +535 -121
- package/fesm2022/vectoriox-iox-ui-composite-core.mjs.map +1 -1
- package/fesm2022/vectoriox-iox-ui-design-core.mjs +843 -45
- package/fesm2022/vectoriox-iox-ui-design-core.mjs.map +1 -1
- package/fesm2022/vectoriox-iox-ui-generation-core.mjs +894 -21
- package/fesm2022/vectoriox-iox-ui-generation-core.mjs.map +1 -1
- package/fesm2022/vectoriox-iox-ui.mjs +3945 -3914
- package/fesm2022/vectoriox-iox-ui.mjs.map +1 -1
- package/generation-core/index.d.ts +625 -5
- package/index.d.ts +22 -1
- package/package.json +1 -1
- package/src/actions-core/element-actions.ts +4 -3
- package/src/composite-core/accordion.ts +1 -0
- package/src/composite-core/composite-kinds.ts +42 -6
- package/src/composite-core/exclusive-runtime.ts +60 -10
- package/src/composite-core/exclusive.ts +64 -0
- package/src/composite-core/public-api.ts +5 -2
- package/src/composite-core/segmented.ts +349 -0
- package/src/composite-core/structure.ts +6 -1
- package/src/composite-core/tabs.ts +6 -3
- package/src/design-core/contrast-audit.ts +8 -3
- package/src/design-core/flavor-spec.generated.ts +832 -41
- package/src/generation-core/compose-site.ts +248 -12
- package/src/generation-core/nav-shape.ts +53 -3
- package/src/generation-core/node-baselines.generated.ts +49 -0
- package/src/generation-core/patterns.ts +20 -0
- package/src/generation-core/site-spec.generated.ts +595 -0
- package/styles/iox-design.css +19 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { NEW_NODE_STYLE_DEFAULTS, defaultElementStyleFor, elementStyleById, ownedTraitsOf, applyElementStyle, flavorPackById, parseHexColor, SPEC_AXES, LinkType, resolveDesignChoices } from '@vectoriox/iox-ui/design-core';
|
|
1
|
+
import { NEW_NODE_STYLE_DEFAULTS, defaultElementStyleFor, elementStyleById, ownedTraitsOf, applyElementStyle, flavorPackById, parseHexColor, SPEC_AXES, LinkType, COLOR_SCHEMES, setColorScheme, resolveDesignChoices } from '@vectoriox/iox-ui/design-core';
|
|
2
2
|
import { formPresetById } from '@vectoriox/iox-ui/forms-core';
|
|
3
|
-
import { CardRole, CardLayout, CARD_LAYOUTS, CARD_PARTS, buildCardRecipe, findByRole, AccordionRole, buildAccordionRecipe, ACCORDION_WORDS, accordionItems, accordionQuestionOf, accordionAnswerOf, ACCORDION_BIND_PROP, pickAccordionAutoBinds, ACCORDION_CONTENT_LIMIT, buildTabsRecipe, TABS_WORDS, tabsTriggers, tabLabelNodeOf, TABS_LABEL_BIND_PROP, tabsPanels, tabPanelTextOf, TABS_TEXT_BIND_PROP, tabPanelImageOf, pickTabsAutoBinds, tabsListOf, tabsPanelsOf, TABS_CONTENT_LIMIT, TABS_IMAGE_BIND_PROP, buildCarouselRecipe, SLIDE_TYPE, buildLightboxRecipe, LIGHTBOX_LABEL, SLIDE_TO_ROW } from '@vectoriox/iox-ui/composite-core';
|
|
3
|
+
import { segmentedOptions, ITEM_OPEN_STATE, CardRole, CardLayout, CARD_LAYOUTS, CARD_PARTS, BADGE_TONES, buildCardRecipe, findByRole, buildSegmentedRecipe, AccordionRole, buildAccordionRecipe, ACCORDION_WORDS, accordionItems, accordionQuestionOf, accordionAnswerOf, ACCORDION_BIND_PROP, pickAccordionAutoBinds, ACCORDION_CONTENT_LIMIT, buildTabsRecipe, TABS_WORDS, tabsTriggers, tabLabelNodeOf, TABS_LABEL_BIND_PROP, tabsPanels, tabPanelTextOf, TABS_TEXT_BIND_PROP, tabPanelImageOf, pickTabsAutoBinds, tabsListOf, tabsPanelsOf, TABS_CONTENT_LIMIT, TABS_IMAGE_BIND_PROP, buildCarouselRecipe, SLIDE_TYPE, buildLightboxRecipe, LIGHTBOX_LABEL, SLIDE_TO_ROW } from '@vectoriox/iox-ui/composite-core';
|
|
4
4
|
|
|
5
5
|
// GENERATED from iox-ai-guidance flavor-spec.v1.json — do not edit; re-run scripts/gen-flavor-spec.mjs
|
|
6
6
|
// (npm run gen:flavor-spec). The JSON is itself generated by iox-ai-guidance
|
|
@@ -1027,6 +1027,601 @@ const SPEC_SITE_PATTERNS = {
|
|
|
1027
1027
|
]
|
|
1028
1028
|
}
|
|
1029
1029
|
},
|
|
1030
|
+
"pricing.tiers": {
|
|
1031
|
+
"family": "pricing",
|
|
1032
|
+
"label": "Pricing — plans with a monthly / yearly switch",
|
|
1033
|
+
"node": {
|
|
1034
|
+
"t": "Section",
|
|
1035
|
+
"es": "section",
|
|
1036
|
+
"c": [
|
|
1037
|
+
{
|
|
1038
|
+
"t": "Container",
|
|
1039
|
+
"es": "box",
|
|
1040
|
+
"lay": {
|
|
1041
|
+
"display": "flex",
|
|
1042
|
+
"flexDirection": "column",
|
|
1043
|
+
"gap": "8px",
|
|
1044
|
+
"alignItems": "center",
|
|
1045
|
+
"textAlign": "center"
|
|
1046
|
+
},
|
|
1047
|
+
"c": [
|
|
1048
|
+
{
|
|
1049
|
+
"t": "Text",
|
|
1050
|
+
"es": "eyebrow",
|
|
1051
|
+
"slot": "eyebrow",
|
|
1052
|
+
"ph": "copy",
|
|
1053
|
+
"text": "Pricing"
|
|
1054
|
+
},
|
|
1055
|
+
{
|
|
1056
|
+
"t": "Heading",
|
|
1057
|
+
"es": "h2",
|
|
1058
|
+
"level": "h2",
|
|
1059
|
+
"slot": "title",
|
|
1060
|
+
"ph": "copy",
|
|
1061
|
+
"text": "Plans"
|
|
1062
|
+
}
|
|
1063
|
+
]
|
|
1064
|
+
},
|
|
1065
|
+
{
|
|
1066
|
+
"t": "Container",
|
|
1067
|
+
"recipe": "segmented",
|
|
1068
|
+
"name": "Billing period",
|
|
1069
|
+
"lay": {
|
|
1070
|
+
"alignSelf": "center"
|
|
1071
|
+
},
|
|
1072
|
+
"resp": {
|
|
1073
|
+
"mobile": {
|
|
1074
|
+
"position": "sticky",
|
|
1075
|
+
"top": "calc(12px + env(safe-area-inset-top, 0px))",
|
|
1076
|
+
"zIndex": "2"
|
|
1077
|
+
}
|
|
1078
|
+
}
|
|
1079
|
+
},
|
|
1080
|
+
{
|
|
1081
|
+
"t": "Container",
|
|
1082
|
+
"es": "box",
|
|
1083
|
+
"layer": "Plans",
|
|
1084
|
+
"lay": {
|
|
1085
|
+
"display": "grid",
|
|
1086
|
+
"gridTemplateColumns": "repeat(3, minmax(0, 1fr))",
|
|
1087
|
+
"gap": "var(--iox-space-gap)",
|
|
1088
|
+
"alignItems": "stretch"
|
|
1089
|
+
},
|
|
1090
|
+
"resp": {
|
|
1091
|
+
"mobile": {
|
|
1092
|
+
"gridTemplateColumns": "minmax(0, 1fr)"
|
|
1093
|
+
}
|
|
1094
|
+
},
|
|
1095
|
+
"c": [
|
|
1096
|
+
{
|
|
1097
|
+
"t": "Container",
|
|
1098
|
+
"recipe": "card",
|
|
1099
|
+
"layout": "top",
|
|
1100
|
+
"ph": "copy",
|
|
1101
|
+
"parts": {
|
|
1102
|
+
"media": false,
|
|
1103
|
+
"eyebrow": false,
|
|
1104
|
+
"badge": false,
|
|
1105
|
+
"actions": false
|
|
1106
|
+
},
|
|
1107
|
+
"words": {
|
|
1108
|
+
"title": "First plan",
|
|
1109
|
+
"text": "Who this plan is for, in one sentence."
|
|
1110
|
+
},
|
|
1111
|
+
"c": [
|
|
1112
|
+
{
|
|
1113
|
+
"t": "Container",
|
|
1114
|
+
"es": "box",
|
|
1115
|
+
"layer": "Price · Monthly",
|
|
1116
|
+
"shownWhen": "monthly",
|
|
1117
|
+
"lay": {
|
|
1118
|
+
"display": "flex",
|
|
1119
|
+
"alignItems": "baseline",
|
|
1120
|
+
"flexWrap": "wrap",
|
|
1121
|
+
"gap": "6px"
|
|
1122
|
+
},
|
|
1123
|
+
"c": [
|
|
1124
|
+
{
|
|
1125
|
+
"t": "Text",
|
|
1126
|
+
"es": "price",
|
|
1127
|
+
"ph": "price",
|
|
1128
|
+
"text": "Monthly price"
|
|
1129
|
+
},
|
|
1130
|
+
{
|
|
1131
|
+
"t": "Text",
|
|
1132
|
+
"es": "small",
|
|
1133
|
+
"text": "per month"
|
|
1134
|
+
}
|
|
1135
|
+
]
|
|
1136
|
+
},
|
|
1137
|
+
{
|
|
1138
|
+
"t": "Container",
|
|
1139
|
+
"es": "box",
|
|
1140
|
+
"layer": "Price · Yearly",
|
|
1141
|
+
"shownWhen": "yearly",
|
|
1142
|
+
"lay": {
|
|
1143
|
+
"display": "flex",
|
|
1144
|
+
"alignItems": "baseline",
|
|
1145
|
+
"flexWrap": "wrap",
|
|
1146
|
+
"gap": "6px"
|
|
1147
|
+
},
|
|
1148
|
+
"c": [
|
|
1149
|
+
{
|
|
1150
|
+
"t": "Text",
|
|
1151
|
+
"es": "price",
|
|
1152
|
+
"ph": "price",
|
|
1153
|
+
"text": "Yearly price"
|
|
1154
|
+
},
|
|
1155
|
+
{
|
|
1156
|
+
"t": "Text",
|
|
1157
|
+
"es": "small",
|
|
1158
|
+
"text": "per year"
|
|
1159
|
+
}
|
|
1160
|
+
]
|
|
1161
|
+
},
|
|
1162
|
+
{
|
|
1163
|
+
"t": "Container",
|
|
1164
|
+
"es": "box",
|
|
1165
|
+
"layer": "Includes",
|
|
1166
|
+
"lay": {
|
|
1167
|
+
"display": "flex",
|
|
1168
|
+
"flexDirection": "column",
|
|
1169
|
+
"gap": "8px"
|
|
1170
|
+
},
|
|
1171
|
+
"c": [
|
|
1172
|
+
{
|
|
1173
|
+
"t": "Container",
|
|
1174
|
+
"es": "box",
|
|
1175
|
+
"lay": {
|
|
1176
|
+
"display": "flex",
|
|
1177
|
+
"flexWrap": "nowrap",
|
|
1178
|
+
"gap": "8px",
|
|
1179
|
+
"alignItems": "flex-start"
|
|
1180
|
+
},
|
|
1181
|
+
"c": [
|
|
1182
|
+
{
|
|
1183
|
+
"t": "Icon",
|
|
1184
|
+
"es": "icon",
|
|
1185
|
+
"icon": "ph ph-check"
|
|
1186
|
+
},
|
|
1187
|
+
{
|
|
1188
|
+
"t": "Text",
|
|
1189
|
+
"es": "body",
|
|
1190
|
+
"ph": "copy",
|
|
1191
|
+
"text": "What this plan includes"
|
|
1192
|
+
}
|
|
1193
|
+
]
|
|
1194
|
+
},
|
|
1195
|
+
{
|
|
1196
|
+
"t": "Container",
|
|
1197
|
+
"es": "box",
|
|
1198
|
+
"lay": {
|
|
1199
|
+
"display": "flex",
|
|
1200
|
+
"flexWrap": "nowrap",
|
|
1201
|
+
"gap": "8px",
|
|
1202
|
+
"alignItems": "flex-start"
|
|
1203
|
+
},
|
|
1204
|
+
"c": [
|
|
1205
|
+
{
|
|
1206
|
+
"t": "Icon",
|
|
1207
|
+
"es": "icon",
|
|
1208
|
+
"icon": "ph ph-check"
|
|
1209
|
+
},
|
|
1210
|
+
{
|
|
1211
|
+
"t": "Text",
|
|
1212
|
+
"es": "body",
|
|
1213
|
+
"ph": "copy",
|
|
1214
|
+
"text": "What this plan includes"
|
|
1215
|
+
}
|
|
1216
|
+
]
|
|
1217
|
+
},
|
|
1218
|
+
{
|
|
1219
|
+
"t": "Container",
|
|
1220
|
+
"es": "box",
|
|
1221
|
+
"lay": {
|
|
1222
|
+
"display": "flex",
|
|
1223
|
+
"flexWrap": "nowrap",
|
|
1224
|
+
"gap": "8px",
|
|
1225
|
+
"alignItems": "flex-start"
|
|
1226
|
+
},
|
|
1227
|
+
"c": [
|
|
1228
|
+
{
|
|
1229
|
+
"t": "Icon",
|
|
1230
|
+
"es": "icon",
|
|
1231
|
+
"icon": "ph ph-check"
|
|
1232
|
+
},
|
|
1233
|
+
{
|
|
1234
|
+
"t": "Text",
|
|
1235
|
+
"es": "body",
|
|
1236
|
+
"ph": "copy",
|
|
1237
|
+
"text": "What this plan includes"
|
|
1238
|
+
}
|
|
1239
|
+
]
|
|
1240
|
+
}
|
|
1241
|
+
]
|
|
1242
|
+
},
|
|
1243
|
+
{
|
|
1244
|
+
"t": "Container",
|
|
1245
|
+
"es": "box",
|
|
1246
|
+
"role": "card.actions",
|
|
1247
|
+
"layer": "Buttons",
|
|
1248
|
+
"lay": {
|
|
1249
|
+
"display": "flex",
|
|
1250
|
+
"flexWrap": "wrap",
|
|
1251
|
+
"gap": "8px",
|
|
1252
|
+
"alignItems": "center",
|
|
1253
|
+
"width": "100%",
|
|
1254
|
+
"margin": "auto 0px 0px 0px",
|
|
1255
|
+
"padding": "6px 0px 0px 0px"
|
|
1256
|
+
},
|
|
1257
|
+
"c": [
|
|
1258
|
+
{
|
|
1259
|
+
"t": "ButtonBlock",
|
|
1260
|
+
"es": "button-primary",
|
|
1261
|
+
"href": "/contact",
|
|
1262
|
+
"text": "Choose this plan"
|
|
1263
|
+
}
|
|
1264
|
+
]
|
|
1265
|
+
}
|
|
1266
|
+
]
|
|
1267
|
+
},
|
|
1268
|
+
{
|
|
1269
|
+
"t": "Container",
|
|
1270
|
+
"recipe": "card",
|
|
1271
|
+
"layout": "top",
|
|
1272
|
+
"ph": "copy",
|
|
1273
|
+
"scheme": "accent",
|
|
1274
|
+
"badge": "neutral",
|
|
1275
|
+
"parts": {
|
|
1276
|
+
"media": false,
|
|
1277
|
+
"eyebrow": false,
|
|
1278
|
+
"badge": true,
|
|
1279
|
+
"actions": false
|
|
1280
|
+
},
|
|
1281
|
+
"words": {
|
|
1282
|
+
"title": "Second plan",
|
|
1283
|
+
"text": "Who this plan is for, in one sentence.",
|
|
1284
|
+
"badge": "Most popular"
|
|
1285
|
+
},
|
|
1286
|
+
"c": [
|
|
1287
|
+
{
|
|
1288
|
+
"t": "Container",
|
|
1289
|
+
"es": "box",
|
|
1290
|
+
"layer": "Price · Monthly",
|
|
1291
|
+
"shownWhen": "monthly",
|
|
1292
|
+
"lay": {
|
|
1293
|
+
"display": "flex",
|
|
1294
|
+
"alignItems": "baseline",
|
|
1295
|
+
"flexWrap": "wrap",
|
|
1296
|
+
"gap": "6px"
|
|
1297
|
+
},
|
|
1298
|
+
"c": [
|
|
1299
|
+
{
|
|
1300
|
+
"t": "Text",
|
|
1301
|
+
"es": "price",
|
|
1302
|
+
"ph": "price",
|
|
1303
|
+
"text": "Monthly price"
|
|
1304
|
+
},
|
|
1305
|
+
{
|
|
1306
|
+
"t": "Text",
|
|
1307
|
+
"es": "small",
|
|
1308
|
+
"text": "per month"
|
|
1309
|
+
}
|
|
1310
|
+
]
|
|
1311
|
+
},
|
|
1312
|
+
{
|
|
1313
|
+
"t": "Container",
|
|
1314
|
+
"es": "box",
|
|
1315
|
+
"layer": "Price · Yearly",
|
|
1316
|
+
"shownWhen": "yearly",
|
|
1317
|
+
"lay": {
|
|
1318
|
+
"display": "flex",
|
|
1319
|
+
"alignItems": "baseline",
|
|
1320
|
+
"flexWrap": "wrap",
|
|
1321
|
+
"gap": "6px"
|
|
1322
|
+
},
|
|
1323
|
+
"c": [
|
|
1324
|
+
{
|
|
1325
|
+
"t": "Text",
|
|
1326
|
+
"es": "price",
|
|
1327
|
+
"ph": "price",
|
|
1328
|
+
"text": "Yearly price"
|
|
1329
|
+
},
|
|
1330
|
+
{
|
|
1331
|
+
"t": "Text",
|
|
1332
|
+
"es": "small",
|
|
1333
|
+
"text": "per year"
|
|
1334
|
+
}
|
|
1335
|
+
]
|
|
1336
|
+
},
|
|
1337
|
+
{
|
|
1338
|
+
"t": "Container",
|
|
1339
|
+
"es": "box",
|
|
1340
|
+
"layer": "Includes",
|
|
1341
|
+
"lay": {
|
|
1342
|
+
"display": "flex",
|
|
1343
|
+
"flexDirection": "column",
|
|
1344
|
+
"gap": "8px"
|
|
1345
|
+
},
|
|
1346
|
+
"c": [
|
|
1347
|
+
{
|
|
1348
|
+
"t": "Container",
|
|
1349
|
+
"es": "box",
|
|
1350
|
+
"lay": {
|
|
1351
|
+
"display": "flex",
|
|
1352
|
+
"flexWrap": "nowrap",
|
|
1353
|
+
"gap": "8px",
|
|
1354
|
+
"alignItems": "flex-start"
|
|
1355
|
+
},
|
|
1356
|
+
"c": [
|
|
1357
|
+
{
|
|
1358
|
+
"t": "Icon",
|
|
1359
|
+
"es": "icon",
|
|
1360
|
+
"icon": "ph ph-check"
|
|
1361
|
+
},
|
|
1362
|
+
{
|
|
1363
|
+
"t": "Text",
|
|
1364
|
+
"es": "body",
|
|
1365
|
+
"ph": "copy",
|
|
1366
|
+
"text": "What this plan includes"
|
|
1367
|
+
}
|
|
1368
|
+
]
|
|
1369
|
+
},
|
|
1370
|
+
{
|
|
1371
|
+
"t": "Container",
|
|
1372
|
+
"es": "box",
|
|
1373
|
+
"lay": {
|
|
1374
|
+
"display": "flex",
|
|
1375
|
+
"flexWrap": "nowrap",
|
|
1376
|
+
"gap": "8px",
|
|
1377
|
+
"alignItems": "flex-start"
|
|
1378
|
+
},
|
|
1379
|
+
"c": [
|
|
1380
|
+
{
|
|
1381
|
+
"t": "Icon",
|
|
1382
|
+
"es": "icon",
|
|
1383
|
+
"icon": "ph ph-check"
|
|
1384
|
+
},
|
|
1385
|
+
{
|
|
1386
|
+
"t": "Text",
|
|
1387
|
+
"es": "body",
|
|
1388
|
+
"ph": "copy",
|
|
1389
|
+
"text": "What this plan includes"
|
|
1390
|
+
}
|
|
1391
|
+
]
|
|
1392
|
+
},
|
|
1393
|
+
{
|
|
1394
|
+
"t": "Container",
|
|
1395
|
+
"es": "box",
|
|
1396
|
+
"lay": {
|
|
1397
|
+
"display": "flex",
|
|
1398
|
+
"flexWrap": "nowrap",
|
|
1399
|
+
"gap": "8px",
|
|
1400
|
+
"alignItems": "flex-start"
|
|
1401
|
+
},
|
|
1402
|
+
"c": [
|
|
1403
|
+
{
|
|
1404
|
+
"t": "Icon",
|
|
1405
|
+
"es": "icon",
|
|
1406
|
+
"icon": "ph ph-check"
|
|
1407
|
+
},
|
|
1408
|
+
{
|
|
1409
|
+
"t": "Text",
|
|
1410
|
+
"es": "body",
|
|
1411
|
+
"ph": "copy",
|
|
1412
|
+
"text": "What this plan includes"
|
|
1413
|
+
}
|
|
1414
|
+
]
|
|
1415
|
+
}
|
|
1416
|
+
]
|
|
1417
|
+
},
|
|
1418
|
+
{
|
|
1419
|
+
"t": "Container",
|
|
1420
|
+
"es": "box",
|
|
1421
|
+
"role": "card.actions",
|
|
1422
|
+
"layer": "Buttons",
|
|
1423
|
+
"lay": {
|
|
1424
|
+
"display": "flex",
|
|
1425
|
+
"flexWrap": "wrap",
|
|
1426
|
+
"gap": "8px",
|
|
1427
|
+
"alignItems": "center",
|
|
1428
|
+
"width": "100%",
|
|
1429
|
+
"margin": "auto 0px 0px 0px",
|
|
1430
|
+
"padding": "6px 0px 0px 0px"
|
|
1431
|
+
},
|
|
1432
|
+
"c": [
|
|
1433
|
+
{
|
|
1434
|
+
"t": "ButtonBlock",
|
|
1435
|
+
"es": "button-primary",
|
|
1436
|
+
"href": "/contact",
|
|
1437
|
+
"text": "Choose this plan"
|
|
1438
|
+
}
|
|
1439
|
+
]
|
|
1440
|
+
}
|
|
1441
|
+
]
|
|
1442
|
+
},
|
|
1443
|
+
{
|
|
1444
|
+
"t": "Container",
|
|
1445
|
+
"recipe": "card",
|
|
1446
|
+
"layout": "top",
|
|
1447
|
+
"ph": "copy",
|
|
1448
|
+
"parts": {
|
|
1449
|
+
"media": false,
|
|
1450
|
+
"eyebrow": false,
|
|
1451
|
+
"badge": false,
|
|
1452
|
+
"actions": false
|
|
1453
|
+
},
|
|
1454
|
+
"words": {
|
|
1455
|
+
"title": "Third plan",
|
|
1456
|
+
"text": "Who this plan is for, in one sentence."
|
|
1457
|
+
},
|
|
1458
|
+
"c": [
|
|
1459
|
+
{
|
|
1460
|
+
"t": "Container",
|
|
1461
|
+
"es": "box",
|
|
1462
|
+
"layer": "Price · Monthly",
|
|
1463
|
+
"shownWhen": "monthly",
|
|
1464
|
+
"lay": {
|
|
1465
|
+
"display": "flex",
|
|
1466
|
+
"alignItems": "baseline",
|
|
1467
|
+
"flexWrap": "wrap",
|
|
1468
|
+
"gap": "6px"
|
|
1469
|
+
},
|
|
1470
|
+
"c": [
|
|
1471
|
+
{
|
|
1472
|
+
"t": "Text",
|
|
1473
|
+
"es": "price",
|
|
1474
|
+
"ph": "price",
|
|
1475
|
+
"text": "Monthly price"
|
|
1476
|
+
},
|
|
1477
|
+
{
|
|
1478
|
+
"t": "Text",
|
|
1479
|
+
"es": "small",
|
|
1480
|
+
"text": "per month"
|
|
1481
|
+
}
|
|
1482
|
+
]
|
|
1483
|
+
},
|
|
1484
|
+
{
|
|
1485
|
+
"t": "Container",
|
|
1486
|
+
"es": "box",
|
|
1487
|
+
"layer": "Price · Yearly",
|
|
1488
|
+
"shownWhen": "yearly",
|
|
1489
|
+
"lay": {
|
|
1490
|
+
"display": "flex",
|
|
1491
|
+
"alignItems": "baseline",
|
|
1492
|
+
"flexWrap": "wrap",
|
|
1493
|
+
"gap": "6px"
|
|
1494
|
+
},
|
|
1495
|
+
"c": [
|
|
1496
|
+
{
|
|
1497
|
+
"t": "Text",
|
|
1498
|
+
"es": "price",
|
|
1499
|
+
"ph": "price",
|
|
1500
|
+
"text": "Yearly price"
|
|
1501
|
+
},
|
|
1502
|
+
{
|
|
1503
|
+
"t": "Text",
|
|
1504
|
+
"es": "small",
|
|
1505
|
+
"text": "per year"
|
|
1506
|
+
}
|
|
1507
|
+
]
|
|
1508
|
+
},
|
|
1509
|
+
{
|
|
1510
|
+
"t": "Container",
|
|
1511
|
+
"es": "box",
|
|
1512
|
+
"layer": "Includes",
|
|
1513
|
+
"lay": {
|
|
1514
|
+
"display": "flex",
|
|
1515
|
+
"flexDirection": "column",
|
|
1516
|
+
"gap": "8px"
|
|
1517
|
+
},
|
|
1518
|
+
"c": [
|
|
1519
|
+
{
|
|
1520
|
+
"t": "Container",
|
|
1521
|
+
"es": "box",
|
|
1522
|
+
"lay": {
|
|
1523
|
+
"display": "flex",
|
|
1524
|
+
"flexWrap": "nowrap",
|
|
1525
|
+
"gap": "8px",
|
|
1526
|
+
"alignItems": "flex-start"
|
|
1527
|
+
},
|
|
1528
|
+
"c": [
|
|
1529
|
+
{
|
|
1530
|
+
"t": "Icon",
|
|
1531
|
+
"es": "icon",
|
|
1532
|
+
"icon": "ph ph-check"
|
|
1533
|
+
},
|
|
1534
|
+
{
|
|
1535
|
+
"t": "Text",
|
|
1536
|
+
"es": "body",
|
|
1537
|
+
"ph": "copy",
|
|
1538
|
+
"text": "What this plan includes"
|
|
1539
|
+
}
|
|
1540
|
+
]
|
|
1541
|
+
},
|
|
1542
|
+
{
|
|
1543
|
+
"t": "Container",
|
|
1544
|
+
"es": "box",
|
|
1545
|
+
"lay": {
|
|
1546
|
+
"display": "flex",
|
|
1547
|
+
"flexWrap": "nowrap",
|
|
1548
|
+
"gap": "8px",
|
|
1549
|
+
"alignItems": "flex-start"
|
|
1550
|
+
},
|
|
1551
|
+
"c": [
|
|
1552
|
+
{
|
|
1553
|
+
"t": "Icon",
|
|
1554
|
+
"es": "icon",
|
|
1555
|
+
"icon": "ph ph-check"
|
|
1556
|
+
},
|
|
1557
|
+
{
|
|
1558
|
+
"t": "Text",
|
|
1559
|
+
"es": "body",
|
|
1560
|
+
"ph": "copy",
|
|
1561
|
+
"text": "What this plan includes"
|
|
1562
|
+
}
|
|
1563
|
+
]
|
|
1564
|
+
},
|
|
1565
|
+
{
|
|
1566
|
+
"t": "Container",
|
|
1567
|
+
"es": "box",
|
|
1568
|
+
"lay": {
|
|
1569
|
+
"display": "flex",
|
|
1570
|
+
"flexWrap": "nowrap",
|
|
1571
|
+
"gap": "8px",
|
|
1572
|
+
"alignItems": "flex-start"
|
|
1573
|
+
},
|
|
1574
|
+
"c": [
|
|
1575
|
+
{
|
|
1576
|
+
"t": "Icon",
|
|
1577
|
+
"es": "icon",
|
|
1578
|
+
"icon": "ph ph-check"
|
|
1579
|
+
},
|
|
1580
|
+
{
|
|
1581
|
+
"t": "Text",
|
|
1582
|
+
"es": "body",
|
|
1583
|
+
"ph": "copy",
|
|
1584
|
+
"text": "What this plan includes"
|
|
1585
|
+
}
|
|
1586
|
+
]
|
|
1587
|
+
}
|
|
1588
|
+
]
|
|
1589
|
+
},
|
|
1590
|
+
{
|
|
1591
|
+
"t": "Container",
|
|
1592
|
+
"es": "box",
|
|
1593
|
+
"role": "card.actions",
|
|
1594
|
+
"layer": "Buttons",
|
|
1595
|
+
"lay": {
|
|
1596
|
+
"display": "flex",
|
|
1597
|
+
"flexWrap": "wrap",
|
|
1598
|
+
"gap": "8px",
|
|
1599
|
+
"alignItems": "center",
|
|
1600
|
+
"width": "100%",
|
|
1601
|
+
"margin": "auto 0px 0px 0px",
|
|
1602
|
+
"padding": "6px 0px 0px 0px"
|
|
1603
|
+
},
|
|
1604
|
+
"c": [
|
|
1605
|
+
{
|
|
1606
|
+
"t": "ButtonBlock",
|
|
1607
|
+
"es": "button-primary",
|
|
1608
|
+
"href": "/contact",
|
|
1609
|
+
"text": "Choose this plan"
|
|
1610
|
+
}
|
|
1611
|
+
]
|
|
1612
|
+
}
|
|
1613
|
+
]
|
|
1614
|
+
}
|
|
1615
|
+
]
|
|
1616
|
+
}
|
|
1617
|
+
],
|
|
1618
|
+
"lay": {
|
|
1619
|
+
"display": "flex",
|
|
1620
|
+
"flexDirection": "column",
|
|
1621
|
+
"gap": "32px"
|
|
1622
|
+
}
|
|
1623
|
+
}
|
|
1624
|
+
},
|
|
1030
1625
|
"hero.full-bleed-media": {
|
|
1031
1626
|
"family": "hero",
|
|
1032
1627
|
"label": "Hero — words over a background video",
|
|
@@ -1463,6 +2058,7 @@ const NODE_BASELINES = {
|
|
|
1463
2058
|
"textAlign": "start",
|
|
1464
2059
|
"fontStyle": "normal",
|
|
1465
2060
|
"textDecoration": "none",
|
|
2061
|
+
"fontVariantNumeric": "normal",
|
|
1466
2062
|
"WebkitTextStrokeWidth": "0px",
|
|
1467
2063
|
"WebkitTextStrokeColor": "transparent",
|
|
1468
2064
|
"margin": "0px 0px 0px 0px",
|
|
@@ -1552,6 +2148,7 @@ const NODE_BASELINES = {
|
|
|
1552
2148
|
"textAlign",
|
|
1553
2149
|
"fontStyle",
|
|
1554
2150
|
"textDecoration",
|
|
2151
|
+
"fontVariantNumeric",
|
|
1555
2152
|
"_sep_stroke",
|
|
1556
2153
|
"WebkitTextStrokeWidth",
|
|
1557
2154
|
"WebkitTextStrokeColor",
|
|
@@ -1654,6 +2251,7 @@ const NODE_BASELINES = {
|
|
|
1654
2251
|
"textAlign": "start",
|
|
1655
2252
|
"fontStyle": "normal",
|
|
1656
2253
|
"textDecoration": "none",
|
|
2254
|
+
"fontVariantNumeric": "normal",
|
|
1657
2255
|
"WebkitTextStrokeWidth": "0px",
|
|
1658
2256
|
"WebkitTextStrokeColor": "transparent",
|
|
1659
2257
|
"margin": "0px 0px 0px 0px",
|
|
@@ -1748,6 +2346,7 @@ const NODE_BASELINES = {
|
|
|
1748
2346
|
"textAlign",
|
|
1749
2347
|
"fontStyle",
|
|
1750
2348
|
"textDecoration",
|
|
2349
|
+
"fontVariantNumeric",
|
|
1751
2350
|
"_sep_stroke",
|
|
1752
2351
|
"WebkitTextStrokeWidth",
|
|
1753
2352
|
"WebkitTextStrokeColor",
|
|
@@ -1846,6 +2445,7 @@ const NODE_BASELINES = {
|
|
|
1846
2445
|
"textAlign": "start",
|
|
1847
2446
|
"fontStyle": "normal",
|
|
1848
2447
|
"textDecoration": "none",
|
|
2448
|
+
"fontVariantNumeric": "normal",
|
|
1849
2449
|
"WebkitTextStrokeWidth": "0px",
|
|
1850
2450
|
"WebkitTextStrokeColor": "transparent",
|
|
1851
2451
|
"margin": "0px 0px 0px 0px",
|
|
@@ -1935,6 +2535,7 @@ const NODE_BASELINES = {
|
|
|
1935
2535
|
"textAlign",
|
|
1936
2536
|
"fontStyle",
|
|
1937
2537
|
"textDecoration",
|
|
2538
|
+
"fontVariantNumeric",
|
|
1938
2539
|
"_sep_stroke",
|
|
1939
2540
|
"WebkitTextStrokeWidth",
|
|
1940
2541
|
"WebkitTextStrokeColor",
|
|
@@ -2032,6 +2633,7 @@ const NODE_BASELINES = {
|
|
|
2032
2633
|
"textAlign": "start",
|
|
2033
2634
|
"fontStyle": "normal",
|
|
2034
2635
|
"textDecoration": "none",
|
|
2636
|
+
"fontVariantNumeric": "normal",
|
|
2035
2637
|
"WebkitTextStrokeWidth": "0px",
|
|
2036
2638
|
"WebkitTextStrokeColor": "transparent",
|
|
2037
2639
|
"margin": "0px 0px 0px 0px",
|
|
@@ -2125,6 +2727,7 @@ const NODE_BASELINES = {
|
|
|
2125
2727
|
"textAlign",
|
|
2126
2728
|
"fontStyle",
|
|
2127
2729
|
"textDecoration",
|
|
2730
|
+
"fontVariantNumeric",
|
|
2128
2731
|
"_sep_stroke",
|
|
2129
2732
|
"WebkitTextStrokeWidth",
|
|
2130
2733
|
"WebkitTextStrokeColor",
|
|
@@ -2226,6 +2829,7 @@ const NODE_BASELINES = {
|
|
|
2226
2829
|
"textAlign": "start",
|
|
2227
2830
|
"fontStyle": "normal",
|
|
2228
2831
|
"textDecoration": "none",
|
|
2832
|
+
"fontVariantNumeric": "normal",
|
|
2229
2833
|
"WebkitTextStrokeWidth": "0px",
|
|
2230
2834
|
"WebkitTextStrokeColor": "transparent",
|
|
2231
2835
|
"maxLines": "none",
|
|
@@ -2319,6 +2923,7 @@ const NODE_BASELINES = {
|
|
|
2319
2923
|
"textAlign",
|
|
2320
2924
|
"fontStyle",
|
|
2321
2925
|
"textDecoration",
|
|
2926
|
+
"fontVariantNumeric",
|
|
2322
2927
|
"_sep_stroke",
|
|
2323
2928
|
"WebkitTextStrokeWidth",
|
|
2324
2929
|
"WebkitTextStrokeColor",
|
|
@@ -2417,6 +3022,7 @@ const NODE_BASELINES = {
|
|
|
2417
3022
|
"textAlign": "start",
|
|
2418
3023
|
"fontStyle": "normal",
|
|
2419
3024
|
"textDecoration": "none",
|
|
3025
|
+
"fontVariantNumeric": "normal",
|
|
2420
3026
|
"WebkitTextStrokeWidth": "0px",
|
|
2421
3027
|
"WebkitTextStrokeColor": "transparent",
|
|
2422
3028
|
"maxLines": "none",
|
|
@@ -2506,6 +3112,7 @@ const NODE_BASELINES = {
|
|
|
2506
3112
|
"textAlign",
|
|
2507
3113
|
"fontStyle",
|
|
2508
3114
|
"textDecoration",
|
|
3115
|
+
"fontVariantNumeric",
|
|
2509
3116
|
"_sep_stroke",
|
|
2510
3117
|
"WebkitTextStrokeWidth",
|
|
2511
3118
|
"WebkitTextStrokeColor",
|
|
@@ -2604,6 +3211,7 @@ const NODE_BASELINES = {
|
|
|
2604
3211
|
"textAlign": "start",
|
|
2605
3212
|
"fontStyle": "normal",
|
|
2606
3213
|
"textDecoration": "none",
|
|
3214
|
+
"fontVariantNumeric": "normal",
|
|
2607
3215
|
"WebkitTextStrokeWidth": "0px",
|
|
2608
3216
|
"WebkitTextStrokeColor": "transparent",
|
|
2609
3217
|
"margin": "0px 0px 0px 0px",
|
|
@@ -2692,6 +3300,7 @@ const NODE_BASELINES = {
|
|
|
2692
3300
|
"textAlign",
|
|
2693
3301
|
"fontStyle",
|
|
2694
3302
|
"textDecoration",
|
|
3303
|
+
"fontVariantNumeric",
|
|
2695
3304
|
"_sep_stroke",
|
|
2696
3305
|
"WebkitTextStrokeWidth",
|
|
2697
3306
|
"WebkitTextStrokeColor",
|
|
@@ -2793,6 +3402,7 @@ const NODE_BASELINES = {
|
|
|
2793
3402
|
"textAlign": "start",
|
|
2794
3403
|
"fontStyle": "normal",
|
|
2795
3404
|
"textDecoration": "none",
|
|
3405
|
+
"fontVariantNumeric": "normal",
|
|
2796
3406
|
"WebkitTextStrokeWidth": "0px",
|
|
2797
3407
|
"WebkitTextStrokeColor": "transparent",
|
|
2798
3408
|
"margin": "0px 0px 0px 0px",
|
|
@@ -2886,6 +3496,7 @@ const NODE_BASELINES = {
|
|
|
2886
3496
|
"textAlign",
|
|
2887
3497
|
"fontStyle",
|
|
2888
3498
|
"textDecoration",
|
|
3499
|
+
"fontVariantNumeric",
|
|
2889
3500
|
"_sep_stroke",
|
|
2890
3501
|
"WebkitTextStrokeWidth",
|
|
2891
3502
|
"WebkitTextStrokeColor",
|
|
@@ -2987,6 +3598,7 @@ const NODE_BASELINES = {
|
|
|
2987
3598
|
"textAlign": "start",
|
|
2988
3599
|
"fontStyle": "normal",
|
|
2989
3600
|
"textDecoration": "none",
|
|
3601
|
+
"fontVariantNumeric": "normal",
|
|
2990
3602
|
"WebkitTextStrokeWidth": "0px",
|
|
2991
3603
|
"WebkitTextStrokeColor": "transparent",
|
|
2992
3604
|
"margin": "0px 0px 0px 0px",
|
|
@@ -3080,6 +3692,7 @@ const NODE_BASELINES = {
|
|
|
3080
3692
|
"textAlign",
|
|
3081
3693
|
"fontStyle",
|
|
3082
3694
|
"textDecoration",
|
|
3695
|
+
"fontVariantNumeric",
|
|
3083
3696
|
"_sep_stroke",
|
|
3084
3697
|
"WebkitTextStrokeWidth",
|
|
3085
3698
|
"WebkitTextStrokeColor",
|
|
@@ -3176,6 +3789,7 @@ const NODE_BASELINES = {
|
|
|
3176
3789
|
"textAlign": "start",
|
|
3177
3790
|
"fontStyle": "normal",
|
|
3178
3791
|
"textDecoration": "none",
|
|
3792
|
+
"fontVariantNumeric": "normal",
|
|
3179
3793
|
"WebkitTextStrokeWidth": "0px",
|
|
3180
3794
|
"WebkitTextStrokeColor": "transparent",
|
|
3181
3795
|
"margin": "0px 0px 0px 0px",
|
|
@@ -3263,6 +3877,7 @@ const NODE_BASELINES = {
|
|
|
3263
3877
|
"textAlign",
|
|
3264
3878
|
"fontStyle",
|
|
3265
3879
|
"textDecoration",
|
|
3880
|
+
"fontVariantNumeric",
|
|
3266
3881
|
"_sep_stroke",
|
|
3267
3882
|
"WebkitTextStrokeWidth",
|
|
3268
3883
|
"WebkitTextStrokeColor",
|
|
@@ -3359,6 +3974,7 @@ const NODE_BASELINES = {
|
|
|
3359
3974
|
"textAlign": "start",
|
|
3360
3975
|
"fontStyle": "normal",
|
|
3361
3976
|
"textDecoration": "none",
|
|
3977
|
+
"fontVariantNumeric": "normal",
|
|
3362
3978
|
"WebkitTextStrokeWidth": "0px",
|
|
3363
3979
|
"WebkitTextStrokeColor": "transparent",
|
|
3364
3980
|
"margin": "0px 0px 0px 0px",
|
|
@@ -3446,6 +4062,7 @@ const NODE_BASELINES = {
|
|
|
3446
4062
|
"textAlign",
|
|
3447
4063
|
"fontStyle",
|
|
3448
4064
|
"textDecoration",
|
|
4065
|
+
"fontVariantNumeric",
|
|
3449
4066
|
"_sep_stroke",
|
|
3450
4067
|
"WebkitTextStrokeWidth",
|
|
3451
4068
|
"WebkitTextStrokeColor",
|
|
@@ -3540,6 +4157,7 @@ const NODE_BASELINES = {
|
|
|
3540
4157
|
"textAlign": "start",
|
|
3541
4158
|
"fontStyle": "normal",
|
|
3542
4159
|
"textDecoration": "none",
|
|
4160
|
+
"fontVariantNumeric": "normal",
|
|
3543
4161
|
"WebkitTextStrokeWidth": "0px",
|
|
3544
4162
|
"WebkitTextStrokeColor": "transparent",
|
|
3545
4163
|
"margin": "8px 0px 8px 0px",
|
|
@@ -3625,6 +4243,7 @@ const NODE_BASELINES = {
|
|
|
3625
4243
|
"textAlign",
|
|
3626
4244
|
"fontStyle",
|
|
3627
4245
|
"textDecoration",
|
|
4246
|
+
"fontVariantNumeric",
|
|
3628
4247
|
"_sep_stroke",
|
|
3629
4248
|
"WebkitTextStrokeWidth",
|
|
3630
4249
|
"WebkitTextStrokeColor",
|
|
@@ -3719,6 +4338,7 @@ const NODE_BASELINES = {
|
|
|
3719
4338
|
"textAlign": "start",
|
|
3720
4339
|
"fontStyle": "normal",
|
|
3721
4340
|
"textDecoration": "none",
|
|
4341
|
+
"fontVariantNumeric": "normal",
|
|
3722
4342
|
"WebkitTextStrokeWidth": "0px",
|
|
3723
4343
|
"WebkitTextStrokeColor": "transparent",
|
|
3724
4344
|
"margin": "0px 0px 0px 0px",
|
|
@@ -3804,6 +4424,7 @@ const NODE_BASELINES = {
|
|
|
3804
4424
|
"textAlign",
|
|
3805
4425
|
"fontStyle",
|
|
3806
4426
|
"textDecoration",
|
|
4427
|
+
"fontVariantNumeric",
|
|
3807
4428
|
"_sep_stroke",
|
|
3808
4429
|
"WebkitTextStrokeWidth",
|
|
3809
4430
|
"WebkitTextStrokeColor",
|
|
@@ -3907,6 +4528,7 @@ const NODE_BASELINES = {
|
|
|
3907
4528
|
"textAlign": "start",
|
|
3908
4529
|
"fontStyle": "normal",
|
|
3909
4530
|
"textDecoration": "none",
|
|
4531
|
+
"fontVariantNumeric": "normal",
|
|
3910
4532
|
"WebkitTextStrokeWidth": "0px",
|
|
3911
4533
|
"WebkitTextStrokeColor": "transparent",
|
|
3912
4534
|
"opacity": "1",
|
|
@@ -3995,6 +4617,7 @@ const NODE_BASELINES = {
|
|
|
3995
4617
|
"textAlign",
|
|
3996
4618
|
"fontStyle",
|
|
3997
4619
|
"textDecoration",
|
|
4620
|
+
"fontVariantNumeric",
|
|
3998
4621
|
"_sep_stroke",
|
|
3999
4622
|
"WebkitTextStrokeWidth",
|
|
4000
4623
|
"WebkitTextStrokeColor",
|
|
@@ -4084,6 +4707,7 @@ const NODE_BASELINES = {
|
|
|
4084
4707
|
"textAlign": "start",
|
|
4085
4708
|
"fontStyle": "normal",
|
|
4086
4709
|
"textDecoration": "none",
|
|
4710
|
+
"fontVariantNumeric": "normal",
|
|
4087
4711
|
"WebkitTextStrokeWidth": "0px",
|
|
4088
4712
|
"WebkitTextStrokeColor": "transparent",
|
|
4089
4713
|
"margin": "0px 0px 0px 0px",
|
|
@@ -4171,6 +4795,7 @@ const NODE_BASELINES = {
|
|
|
4171
4795
|
"textAlign",
|
|
4172
4796
|
"fontStyle",
|
|
4173
4797
|
"textDecoration",
|
|
4798
|
+
"fontVariantNumeric",
|
|
4174
4799
|
"_sep_stroke",
|
|
4175
4800
|
"WebkitTextStrokeWidth",
|
|
4176
4801
|
"WebkitTextStrokeColor",
|
|
@@ -4268,6 +4893,7 @@ const NODE_BASELINES = {
|
|
|
4268
4893
|
"textAlign": "start",
|
|
4269
4894
|
"fontStyle": "normal",
|
|
4270
4895
|
"textDecoration": "none",
|
|
4896
|
+
"fontVariantNumeric": "normal",
|
|
4271
4897
|
"WebkitTextStrokeWidth": "0px",
|
|
4272
4898
|
"WebkitTextStrokeColor": "transparent",
|
|
4273
4899
|
"margin": "0px 0px 0px 0px",
|
|
@@ -4361,6 +4987,7 @@ const NODE_BASELINES = {
|
|
|
4361
4987
|
"textAlign",
|
|
4362
4988
|
"fontStyle",
|
|
4363
4989
|
"textDecoration",
|
|
4990
|
+
"fontVariantNumeric",
|
|
4364
4991
|
"_sep_stroke",
|
|
4365
4992
|
"WebkitTextStrokeWidth",
|
|
4366
4993
|
"WebkitTextStrokeColor",
|
|
@@ -4678,6 +5305,7 @@ const NODE_BASELINES = {
|
|
|
4678
5305
|
"textAlign": "start",
|
|
4679
5306
|
"fontStyle": "normal",
|
|
4680
5307
|
"textDecoration": "none",
|
|
5308
|
+
"fontVariantNumeric": "normal",
|
|
4681
5309
|
"WebkitTextStrokeWidth": "0px",
|
|
4682
5310
|
"WebkitTextStrokeColor": "transparent",
|
|
4683
5311
|
"opacity": "1",
|
|
@@ -4755,6 +5383,7 @@ const NODE_BASELINES = {
|
|
|
4755
5383
|
"textAlign",
|
|
4756
5384
|
"fontStyle",
|
|
4757
5385
|
"textDecoration",
|
|
5386
|
+
"fontVariantNumeric",
|
|
4758
5387
|
"_sep_stroke",
|
|
4759
5388
|
"WebkitTextStrokeWidth",
|
|
4760
5389
|
"WebkitTextStrokeColor",
|
|
@@ -4988,6 +5617,7 @@ const NODE_BASELINES = {
|
|
|
4988
5617
|
"textAlign": "start",
|
|
4989
5618
|
"fontStyle": "normal",
|
|
4990
5619
|
"textDecoration": "none",
|
|
5620
|
+
"fontVariantNumeric": "normal",
|
|
4991
5621
|
"WebkitTextStrokeWidth": "0px",
|
|
4992
5622
|
"WebkitTextStrokeColor": "transparent",
|
|
4993
5623
|
"opacity": "1",
|
|
@@ -5081,6 +5711,7 @@ const NODE_BASELINES = {
|
|
|
5081
5711
|
"textAlign",
|
|
5082
5712
|
"fontStyle",
|
|
5083
5713
|
"textDecoration",
|
|
5714
|
+
"fontVariantNumeric",
|
|
5084
5715
|
"_sep_stroke",
|
|
5085
5716
|
"WebkitTextStrokeWidth",
|
|
5086
5717
|
"WebkitTextStrokeColor",
|
|
@@ -5183,6 +5814,7 @@ const NODE_BASELINES = {
|
|
|
5183
5814
|
"textAlign": "start",
|
|
5184
5815
|
"fontStyle": "normal",
|
|
5185
5816
|
"textDecoration": "none",
|
|
5817
|
+
"fontVariantNumeric": "normal",
|
|
5186
5818
|
"WebkitTextStrokeWidth": "0px",
|
|
5187
5819
|
"WebkitTextStrokeColor": "transparent",
|
|
5188
5820
|
"margin": "0px 0px 0px 0px",
|
|
@@ -5286,6 +5918,7 @@ const NODE_BASELINES = {
|
|
|
5286
5918
|
"textAlign",
|
|
5287
5919
|
"fontStyle",
|
|
5288
5920
|
"textDecoration",
|
|
5921
|
+
"fontVariantNumeric",
|
|
5289
5922
|
"_sep_stroke",
|
|
5290
5923
|
"WebkitTextStrokeWidth",
|
|
5291
5924
|
"WebkitTextStrokeColor",
|
|
@@ -5382,6 +6015,7 @@ const NODE_BASELINES = {
|
|
|
5382
6015
|
"textAlign": "start",
|
|
5383
6016
|
"fontStyle": "normal",
|
|
5384
6017
|
"textDecoration": "none",
|
|
6018
|
+
"fontVariantNumeric": "normal",
|
|
5385
6019
|
"WebkitTextStrokeWidth": "0px",
|
|
5386
6020
|
"WebkitTextStrokeColor": "transparent",
|
|
5387
6021
|
"margin": "0px 0px 0px 0px",
|
|
@@ -5469,6 +6103,7 @@ const NODE_BASELINES = {
|
|
|
5469
6103
|
"textAlign",
|
|
5470
6104
|
"fontStyle",
|
|
5471
6105
|
"textDecoration",
|
|
6106
|
+
"fontVariantNumeric",
|
|
5472
6107
|
"_sep_stroke",
|
|
5473
6108
|
"WebkitTextStrokeWidth",
|
|
5474
6109
|
"WebkitTextStrokeColor",
|
|
@@ -5567,6 +6202,7 @@ const NODE_BASELINES = {
|
|
|
5567
6202
|
"textAlign": "start",
|
|
5568
6203
|
"fontStyle": "normal",
|
|
5569
6204
|
"textDecoration": "none",
|
|
6205
|
+
"fontVariantNumeric": "normal",
|
|
5570
6206
|
"WebkitTextStrokeWidth": "0px",
|
|
5571
6207
|
"WebkitTextStrokeColor": "transparent",
|
|
5572
6208
|
"margin": "0px 0px 0px 0px",
|
|
@@ -5656,6 +6292,7 @@ const NODE_BASELINES = {
|
|
|
5656
6292
|
"textAlign",
|
|
5657
6293
|
"fontStyle",
|
|
5658
6294
|
"textDecoration",
|
|
6295
|
+
"fontVariantNumeric",
|
|
5659
6296
|
"_sep_stroke",
|
|
5660
6297
|
"WebkitTextStrokeWidth",
|
|
5661
6298
|
"WebkitTextStrokeColor",
|
|
@@ -5752,6 +6389,7 @@ const NODE_BASELINES = {
|
|
|
5752
6389
|
"textAlign": "start",
|
|
5753
6390
|
"fontStyle": "normal",
|
|
5754
6391
|
"textDecoration": "none",
|
|
6392
|
+
"fontVariantNumeric": "normal",
|
|
5755
6393
|
"WebkitTextStrokeWidth": "0px",
|
|
5756
6394
|
"WebkitTextStrokeColor": "transparent",
|
|
5757
6395
|
"margin": "0px 0px 0px 0px",
|
|
@@ -5839,6 +6477,7 @@ const NODE_BASELINES = {
|
|
|
5839
6477
|
"textAlign",
|
|
5840
6478
|
"fontStyle",
|
|
5841
6479
|
"textDecoration",
|
|
6480
|
+
"fontVariantNumeric",
|
|
5842
6481
|
"_sep_stroke",
|
|
5843
6482
|
"WebkitTextStrokeWidth",
|
|
5844
6483
|
"WebkitTextStrokeColor",
|
|
@@ -5935,6 +6574,7 @@ const NODE_BASELINES = {
|
|
|
5935
6574
|
"textAlign": "start",
|
|
5936
6575
|
"fontStyle": "normal",
|
|
5937
6576
|
"textDecoration": "none",
|
|
6577
|
+
"fontVariantNumeric": "normal",
|
|
5938
6578
|
"WebkitTextStrokeWidth": "0px",
|
|
5939
6579
|
"WebkitTextStrokeColor": "transparent",
|
|
5940
6580
|
"margin": "0px 0px 0px 0px",
|
|
@@ -6022,6 +6662,7 @@ const NODE_BASELINES = {
|
|
|
6022
6662
|
"textAlign",
|
|
6023
6663
|
"fontStyle",
|
|
6024
6664
|
"textDecoration",
|
|
6665
|
+
"fontVariantNumeric",
|
|
6025
6666
|
"_sep_stroke",
|
|
6026
6667
|
"WebkitTextStrokeWidth",
|
|
6027
6668
|
"WebkitTextStrokeColor",
|
|
@@ -6124,6 +6765,7 @@ const NODE_BASELINES = {
|
|
|
6124
6765
|
"textAlign": "start",
|
|
6125
6766
|
"fontStyle": "normal",
|
|
6126
6767
|
"textDecoration": "none",
|
|
6768
|
+
"fontVariantNumeric": "normal",
|
|
6127
6769
|
"WebkitTextStrokeWidth": "0px",
|
|
6128
6770
|
"WebkitTextStrokeColor": "transparent",
|
|
6129
6771
|
"margin": "0px 0px 0px 0px",
|
|
@@ -6219,6 +6861,7 @@ const NODE_BASELINES = {
|
|
|
6219
6861
|
"textAlign",
|
|
6220
6862
|
"fontStyle",
|
|
6221
6863
|
"textDecoration",
|
|
6864
|
+
"fontVariantNumeric",
|
|
6222
6865
|
"_sep_stroke",
|
|
6223
6866
|
"WebkitTextStrokeWidth",
|
|
6224
6867
|
"WebkitTextStrokeColor",
|
|
@@ -6452,6 +7095,7 @@ const NEUTRAL_STYLE_PROPS = {
|
|
|
6452
7095
|
"textAlign": "start",
|
|
6453
7096
|
"fontStyle": "normal",
|
|
6454
7097
|
"textDecoration": "none",
|
|
7098
|
+
"fontVariantNumeric": "normal",
|
|
6455
7099
|
"WebkitTextStrokeWidth": "0px",
|
|
6456
7100
|
"WebkitTextStrokeColor": "transparent",
|
|
6457
7101
|
"margin": "0px 0px 0px 0px",
|
|
@@ -6614,6 +7258,8 @@ var PatternRecipe;
|
|
|
6614
7258
|
/** CC4a: Tabs — Manual (three placeholder tabs), or From content when the section names a list `binding`: the tab
|
|
6615
7259
|
* list and the panels are both Repeaters over it, one row giving its tab AND its panel. */
|
|
6616
7260
|
PatternRecipe["Tabs"] = "tabs";
|
|
7261
|
+
/** CC4b: the Segmented control — Monthly · Yearly, named by the pattern (`name`). */
|
|
7262
|
+
PatternRecipe["Segmented"] = "segmented";
|
|
6617
7263
|
/** CC3: the accessible carousel — a named Slider whose controls are parts, one quote per slide (placeholders). */
|
|
6618
7264
|
PatternRecipe["Carousel"] = "carousel";
|
|
6619
7265
|
/** CC3: the Lightbox — a Dialog holding a Slider over the node's `src` (the gallery's own source). */
|
|
@@ -6644,6 +7290,8 @@ var PatternPlaceholder;
|
|
|
6644
7290
|
PatternPlaceholder["Image"] = "image";
|
|
6645
7291
|
/** CC3: a clip the studio uploads (a Video's file): the poster blank until then, publish-blocking. */
|
|
6646
7292
|
PatternPlaceholder["Video"] = "video";
|
|
7293
|
+
/** CC4b (Q37): a price the studio types — free text, publish-blocking, its label shown meanwhile, never a number. */
|
|
7294
|
+
PatternPlaceholder["Price"] = "price";
|
|
6647
7295
|
})(PatternPlaceholder || (PatternPlaceholder = {}));
|
|
6648
7296
|
/** CC3: what an `opens` node opens. */
|
|
6649
7297
|
var PatternOpens;
|
|
@@ -6911,14 +7559,14 @@ const GLOBAL_POSITION = {
|
|
|
6911
7559
|
[GlobalSlot.Footer]: PatternGlobalPosition.After,
|
|
6912
7560
|
};
|
|
6913
7561
|
const ROUTE = /^\/(?:(?:[a-z0-9]+(?:-[a-z0-9]+)*|:[a-zA-Z_][a-zA-Z0-9_]*)(?:\/(?:[a-z0-9]+(?:-[a-z0-9]+)*|:[a-zA-Z_][a-zA-Z0-9_]*))*)?$/;
|
|
6914
|
-
const ROUTE_PARAM = /:([a-zA-Z_][a-zA-Z0-9_]*)/g;
|
|
7562
|
+
const ROUTE_PARAM$1 = /:([a-zA-Z_][a-zA-Z0-9_]*)/g;
|
|
6915
7563
|
const isObject = (v) => !!v && typeof v === 'object' && !Array.isArray(v);
|
|
6916
7564
|
const isNonEmptyString = (v) => typeof v === 'string' && v.trim() !== '';
|
|
6917
7565
|
const has = (table, key) => Object.prototype.hasOwnProperty.call(table, key);
|
|
6918
7566
|
const at = (path, key) => (path ? `${path}.${key}` : key);
|
|
6919
7567
|
/** The `:param` names of a route, in order. */
|
|
6920
7568
|
function routeParams(route) {
|
|
6921
|
-
return [...route.matchAll(ROUTE_PARAM)].map(m => m[1]);
|
|
7569
|
+
return [...route.matchAll(ROUTE_PARAM$1)].map(m => m[1]);
|
|
6922
7570
|
}
|
|
6923
7571
|
class Collector {
|
|
6924
7572
|
constructor() {
|
|
@@ -7384,7 +8032,7 @@ const DIALOG$1 = 'Dialog';
|
|
|
7384
8032
|
const LINK = 'Link';
|
|
7385
8033
|
const LINKED = 'LinkedContainer';
|
|
7386
8034
|
const BUTTON = 'ButtonBlock';
|
|
7387
|
-
const ICON = 'Icon';
|
|
8035
|
+
const ICON$1 = 'Icon';
|
|
7388
8036
|
const TEXT$1 = 'Text';
|
|
7389
8037
|
const HEADING = 'Heading';
|
|
7390
8038
|
const NAV_STYLE = 'nav';
|
|
@@ -7485,6 +8133,21 @@ function navPages(root) {
|
|
|
7485
8133
|
const source = links.length ? links : collectHeaderLinks(root);
|
|
7486
8134
|
return source.filter(isPageLink).map(n => ({ label: textOf(n), route: String(prop(n, 'pageRoute')) }));
|
|
7487
8135
|
}
|
|
8136
|
+
/** Where a phone menu's pages come from: the header's own page Links, else the studio's pages. */
|
|
8137
|
+
var NavPagesSource;
|
|
8138
|
+
(function (NavPagesSource) {
|
|
8139
|
+
NavPagesSource["Header"] = "header";
|
|
8140
|
+
NavPagesSource["Site"] = "site";
|
|
8141
|
+
NavPagesSource["None"] = "none";
|
|
8142
|
+
})(NavPagesSource || (NavPagesSource = {}));
|
|
8143
|
+
/** The pages a phone menu lists: the header's (`navPages`), else `sitePages` — a hand-built header with no
|
|
8144
|
+
* page links still gets a working menu. */
|
|
8145
|
+
function phoneMenuPages(root, sitePages = []) {
|
|
8146
|
+
const own = navPages(root);
|
|
8147
|
+
if (own.length)
|
|
8148
|
+
return { pages: own, source: NavPagesSource.Header };
|
|
8149
|
+
return sitePages.length ? { pages: [...sitePages], source: NavPagesSource.Site } : { pages: [], source: NavPagesSource.None };
|
|
8150
|
+
}
|
|
7488
8151
|
/** A hand-built header: every page Link outside a drawer. */
|
|
7489
8152
|
function collectHeaderLinks(root) {
|
|
7490
8153
|
const out = [];
|
|
@@ -7560,7 +8223,7 @@ function moveDisplayOverride(node, to) {
|
|
|
7560
8223
|
}
|
|
7561
8224
|
}
|
|
7562
8225
|
function iconNode(kit, suffix, iconClass) {
|
|
7563
|
-
return part(kit, suffix, ICON, { iconClass }, null);
|
|
8226
|
+
return part(kit, suffix, ICON$1, { iconClass }, null);
|
|
7564
8227
|
}
|
|
7565
8228
|
function labelText(kit, suffix, words) {
|
|
7566
8229
|
return part(kit, suffix, TEXT$1, { content: words, tag: 'span' }, 'button-label');
|
|
@@ -7708,7 +8371,7 @@ function planNavShape(globals, shape, options = {}, navId) {
|
|
|
7708
8371
|
throw new NavShapeError(`a phone menu cannot switch at "${at}"`);
|
|
7709
8372
|
const kit = makeKit(out, root.id, options.newId);
|
|
7710
8373
|
adoptRoles(root);
|
|
7711
|
-
const pages =
|
|
8374
|
+
const { pages } = phoneMenuPages(root, options.pages);
|
|
7712
8375
|
const wantDrawer = shape !== NavShape.Bar;
|
|
7713
8376
|
const wantBar = shape !== NavShape.Drawer;
|
|
7714
8377
|
const wantMenuButton = shape === NavShape.Drawer;
|
|
@@ -7828,7 +8491,7 @@ function addBarItem(globals, options = {}) {
|
|
|
7828
8491
|
if (kids.length >= BAR_ITEMS_MAX)
|
|
7829
8492
|
return { globals: out, added: false };
|
|
7830
8493
|
const linked = new Set(kids.filter(c => c.role === NavRole.BarItem).map(c => prop(c, 'pageRoute')));
|
|
7831
|
-
const page = barPages(root,
|
|
8494
|
+
const page = barPages(root, phoneMenuPages(root, options.pages).pages, BAR_ITEMS_MAX + 1).find(p => !linked.has(p.route))
|
|
7832
8495
|
?? { label: NAV_SHAPE_COPY.home, route: HOME_ROUTE };
|
|
7833
8496
|
const item = barItem(makeKit(out, root.id, options.newId), kids.length, page);
|
|
7834
8497
|
const more = kids.findIndex(c => c.role === NavRole.More);
|
|
@@ -7838,6 +8501,32 @@ function addBarItem(globals, options = {}) {
|
|
|
7838
8501
|
kids.push(item);
|
|
7839
8502
|
return { globals: out, added: true };
|
|
7840
8503
|
}
|
|
8504
|
+
function barOf(globals) {
|
|
8505
|
+
const out = clone$1(globals);
|
|
8506
|
+
const b = find(out, NavRole.Bar);
|
|
8507
|
+
return { out, kids: b ? (b.children ?? (b.children = [])) : null };
|
|
8508
|
+
}
|
|
8509
|
+
/**
|
|
8510
|
+
* The bar's Items list "Remove" (board 2): the item goes, More included — refused below three items (Q2:
|
|
8511
|
+
* 3–5), so the bar never shrinks into something a thumb cannot use. Input not mutated.
|
|
8512
|
+
*/
|
|
8513
|
+
function removeBarItem(globals, itemId) {
|
|
8514
|
+
const { out, kids } = barOf(globals);
|
|
8515
|
+
const i = kids ? kids.findIndex(c => c.id === itemId) : -1;
|
|
8516
|
+
if (!kids || i < 0 || kids.length <= BAR_ITEMS_MIN)
|
|
8517
|
+
return { globals: out, changed: false };
|
|
8518
|
+
kids.splice(i, 1);
|
|
8519
|
+
return { globals: out, changed: true };
|
|
8520
|
+
}
|
|
8521
|
+
/** The bar's Items list drag-to-reorder (board 2): item `from` moves to `to`. Input not mutated. */
|
|
8522
|
+
function moveBarItem(globals, from, to) {
|
|
8523
|
+
const { out, kids } = barOf(globals);
|
|
8524
|
+
if (!kids || from === to || from < 0 || to < 0 || from >= kids.length || to >= kids.length)
|
|
8525
|
+
return { globals: out, changed: false };
|
|
8526
|
+
const [item] = kids.splice(from, 1);
|
|
8527
|
+
kids.splice(to, 0, item);
|
|
8528
|
+
return { globals: out, changed: true };
|
|
8529
|
+
}
|
|
7841
8530
|
|
|
7842
8531
|
/**
|
|
7843
8532
|
* THE composer — a Site Plan in, ordinary IOX data out (design-system plan §6b, W1). Deterministic and
|
|
@@ -7862,7 +8551,17 @@ var PlaceholderKind;
|
|
|
7862
8551
|
PlaceholderKind["Image"] = "image";
|
|
7863
8552
|
/** CC3: a video slot with no clip — the studio uploads its own (the poster blank meanwhile). */
|
|
7864
8553
|
PlaceholderKind["Video"] = "video";
|
|
8554
|
+
/** CC4b (Q37): a price — a FACT the customer could be held to. Free text the studio types ("₪ 1,200", "From $40",
|
|
8555
|
+
* "On request"); its label shows meanwhile ("Monthly price"), never a number. No currency model. */
|
|
8556
|
+
PlaceholderKind["Price"] = "price";
|
|
7865
8557
|
})(PlaceholderKind || (PlaceholderKind = {}));
|
|
8558
|
+
/** The placeholders a page cannot be published with unfilled (W4's gate): a fact, a price, the studio's own video.
|
|
8559
|
+
* Copy and an empty image are the author's to rewrite, never blocking. */
|
|
8560
|
+
const PUBLISH_BLOCKING_PLACEHOLDERS = new Set([PlaceholderKind.Fact, PlaceholderKind.Price, PlaceholderKind.Video]);
|
|
8561
|
+
/** True when a placeholder of `kind` blocks publishing until the studio fills it. */
|
|
8562
|
+
function blocksPublish(kind) {
|
|
8563
|
+
return PUBLISH_BLOCKING_PLACEHOLDERS.has(kind);
|
|
8564
|
+
}
|
|
7866
8565
|
var ComposeIssueCode;
|
|
7867
8566
|
(function (ComposeIssueCode) {
|
|
7868
8567
|
/** A slot the plan and the business left empty and the pattern gives no words for — the node keeps
|
|
@@ -7981,6 +8680,8 @@ function chooseText(pn, ctx) {
|
|
|
7981
8680
|
const own = pn.text === undefined ? undefined : fillVariables(pn.text, ctx);
|
|
7982
8681
|
if (pn.ph === PatternPlaceholder.Copy)
|
|
7983
8682
|
return { value: own, placeholder: { kind: PlaceholderKind.Copy } };
|
|
8683
|
+
if (pn.ph === PatternPlaceholder.Price)
|
|
8684
|
+
return { value: own, placeholder: { kind: PlaceholderKind.Price } };
|
|
7984
8685
|
return { value: own };
|
|
7985
8686
|
}
|
|
7986
8687
|
/** A `bind` / `alt` / `param` / `src` path → the binding source + path, in this node's scope. */
|
|
@@ -8075,7 +8776,7 @@ function danglingFate(pn, ctx) {
|
|
|
8075
8776
|
return null;
|
|
8076
8777
|
if (ctx.email)
|
|
8077
8778
|
return DanglingFate.Email;
|
|
8078
|
-
return UNLINKED_TYPE[pn.t] ? DanglingFate.Unlink : DanglingFate.Remove;
|
|
8779
|
+
return UNLINKED_TYPE[pn.t] || (ctx.keepButtons && pn.t === BUTTON_BLOCK) ? DanglingFate.Unlink : DanglingFate.Remove;
|
|
8079
8780
|
}
|
|
8080
8781
|
const DANGLING_ISSUE = {
|
|
8081
8782
|
[DanglingFate.Email]: ComposeIssueCode.LinkToEmail,
|
|
@@ -8087,7 +8788,9 @@ function reportDangling(fate, pn, id, words, ctx) {
|
|
|
8087
8788
|
const outcome = {
|
|
8088
8789
|
[DanglingFate.Email]: `it now opens an email to ${ctx.email}`,
|
|
8089
8790
|
[DanglingFate.Remove]: 'with no email address to send to instead, it was removed',
|
|
8090
|
-
[DanglingFate.Unlink]:
|
|
8791
|
+
[DanglingFate.Unlink]: pn.t === BUTTON_BLOCK
|
|
8792
|
+
? 'with no email address to send to instead, the button keeps its words without the link'
|
|
8793
|
+
: 'with no email address to send to instead, the box keeps its contents without the link',
|
|
8091
8794
|
}[fate];
|
|
8092
8795
|
ctx.issues.push({
|
|
8093
8796
|
code: DANGLING_ISSUE[fate], nodeId: id, owner: ctx.owner, route: pn.href,
|
|
@@ -8171,7 +8874,7 @@ function composeNode(pn, id, repeater, ctx) {
|
|
|
8171
8874
|
reportDangling(fate, pn, id, words.value, ctx);
|
|
8172
8875
|
return null;
|
|
8173
8876
|
}
|
|
8174
|
-
const type = fate === DanglingFate.Unlink ? UNLINKED_TYPE[pn.t] : pn.t;
|
|
8877
|
+
const type = fate === DanglingFate.Unlink ? UNLINKED_TYPE[pn.t] ?? pn.t : pn.t;
|
|
8175
8878
|
const props = {};
|
|
8176
8879
|
if (pn.level)
|
|
8177
8880
|
props['level'] = pn.level;
|
|
@@ -8222,6 +8925,13 @@ function composeNode(pn, id, repeater, ctx) {
|
|
|
8222
8925
|
}
|
|
8223
8926
|
if (pn.name)
|
|
8224
8927
|
setProp(node, 'ariaLabel', pn.name);
|
|
8928
|
+
if (pn.icon) {
|
|
8929
|
+
if (type !== ICON)
|
|
8930
|
+
throw new ComposeError(`${id}: "icon" belongs on an Icon`);
|
|
8931
|
+
setProp(node, 'iconClass', pn.icon);
|
|
8932
|
+
}
|
|
8933
|
+
if (pn.layer)
|
|
8934
|
+
node.label = pn.layer;
|
|
8225
8935
|
if (pn.opens) {
|
|
8226
8936
|
if (pn.opens !== PatternOpens.Lightbox)
|
|
8227
8937
|
throw new ComposeError(`${id}: "opens" names the pattern's lightbox`);
|
|
@@ -8272,13 +8982,9 @@ function composeNode(pn, id, repeater, ctx) {
|
|
|
8272
8982
|
throw new ComposeError(`${id}: "alt" belongs on a bound Image`);
|
|
8273
8983
|
}
|
|
8274
8984
|
// Layout.
|
|
8275
|
-
|
|
8276
|
-
|
|
8277
|
-
|
|
8278
|
-
for (const layer of Object.values(pn.resp))
|
|
8279
|
-
assertStyleSlots(node.type, Object.keys(layer));
|
|
8280
|
-
node.responsive = Object.fromEntries(Object.entries(pn.resp).map(([bp, styleProps]) => [bp, { styleProps: { ...styleProps } }]));
|
|
8281
|
-
}
|
|
8985
|
+
applyLayout(node, pn);
|
|
8986
|
+
if (pn.shownWhen)
|
|
8987
|
+
hideUntilOn(node, pn, ctx);
|
|
8282
8988
|
// A Repeater's rows.
|
|
8283
8989
|
let rowScope = repeater;
|
|
8284
8990
|
if (pn.src) {
|
|
@@ -8306,6 +9012,47 @@ function composeNode(pn, id, repeater, ctx) {
|
|
|
8306
9012
|
composeForm(node, pn, id, ctx);
|
|
8307
9013
|
return node;
|
|
8308
9014
|
}
|
|
9015
|
+
/** A pattern node's layout: its `lay` styleProps and its per-breakpoint `resp` layers. */
|
|
9016
|
+
function applyLayout(node, pn) {
|
|
9017
|
+
if (pn.lay)
|
|
9018
|
+
setStyleProps(node, pn.lay);
|
|
9019
|
+
if (pn.resp) {
|
|
9020
|
+
for (const layer of Object.values(pn.resp))
|
|
9021
|
+
assertStyleSlots(node.type, Object.keys(layer));
|
|
9022
|
+
node.responsive = Object.fromEntries(Object.entries(pn.resp).map(([bp, styleProps]) => [bp, { styleProps: { ...styleProps } }]));
|
|
9023
|
+
}
|
|
9024
|
+
}
|
|
9025
|
+
/** CC4b (`shownWhen`, Q38): hidden at base and shown — with its own layout's display — while the pattern's Segmented
|
|
9026
|
+
* option of that key is on. Wired once the pattern is stamped (the option's id is known then). */
|
|
9027
|
+
function hideUntilOn(node, pn, ctx) {
|
|
9028
|
+
const display = String(node.styleProps['display'] ?? '') || SHOWN_DISPLAY;
|
|
9029
|
+
setStyleProps(node, { display: HIDDEN_DISPLAY });
|
|
9030
|
+
(ctx.shownWhen ??= []).push({ id: node.id, key: pn.shownWhen, display });
|
|
9031
|
+
}
|
|
9032
|
+
/** CC4b: every `shownWhen` node of a stamped pattern follows its option — the targeted `trigger-on` ("when Yearly is
|
|
9033
|
+
* on"), compiled by both renderers to ONE `:has()` rule on the nearest common ancestor. */
|
|
9034
|
+
function wireShownWhen(root, entries) {
|
|
9035
|
+
if (!entries.length)
|
|
9036
|
+
return;
|
|
9037
|
+
const nodes = new Map();
|
|
9038
|
+
const options = new Map();
|
|
9039
|
+
const visit = (n) => {
|
|
9040
|
+
nodes.set(n.id, n);
|
|
9041
|
+
for (const option of segmentedOptions(n))
|
|
9042
|
+
if (option.itemKey && !options.has(option.itemKey))
|
|
9043
|
+
options.set(option.itemKey, option.id);
|
|
9044
|
+
(n.children ?? []).forEach(visit);
|
|
9045
|
+
};
|
|
9046
|
+
visit(root);
|
|
9047
|
+
for (const entry of entries) {
|
|
9048
|
+
const option = options.get(entry.key);
|
|
9049
|
+
if (!option)
|
|
9050
|
+
throw new ComposeError(`${entry.id}: "shownWhen: ${entry.key}" names no option of a segmented in the pattern`);
|
|
9051
|
+
const node = nodes.get(entry.id);
|
|
9052
|
+
node.stateStyles = { ...(node.stateStyles ?? {}), [ITEM_OPEN_STATE]: { display: entry.display } };
|
|
9053
|
+
node.stateTriggers = { ...(node.stateTriggers ?? {}), [ITEM_OPEN_STATE]: option };
|
|
9054
|
+
}
|
|
9055
|
+
}
|
|
8309
9056
|
/** A Card v2 `binds` key → the part it binds and that part's bound prop. */
|
|
8310
9057
|
const CARD_BINDS = {
|
|
8311
9058
|
[CardBindTarget.Image]: { role: CardRole.Media, prop: 'src' },
|
|
@@ -8327,6 +9074,8 @@ function composeRecipe(pn, id, repeater, ctx) {
|
|
|
8327
9074
|
return composeCarousel(pn, id, ctx);
|
|
8328
9075
|
if (pn.recipe === PatternRecipe.Lightbox)
|
|
8329
9076
|
return composeLightbox(pn, id, repeater, ctx);
|
|
9077
|
+
if (pn.recipe === PatternRecipe.Segmented)
|
|
9078
|
+
return composeSegmented(pn, id);
|
|
8330
9079
|
if (pn.recipe !== PatternRecipe.Card)
|
|
8331
9080
|
throw new ComposeError(`${id}: no recipe "${pn.recipe}" in composite-core`);
|
|
8332
9081
|
const layout = (pn.layout ?? CardLayout.Top);
|
|
@@ -8337,7 +9086,26 @@ function composeRecipe(pn, id, repeater, ctx) {
|
|
|
8337
9086
|
throw new ComposeError(`${id}: a card has no part "${part}"`);
|
|
8338
9087
|
}
|
|
8339
9088
|
const factory = (spec) => create(spec.key === CardRole.Card ? id : `${id}-${spec.key}`, spec.type, { ...(spec.props ?? {}) }, spec.elementStyle ?? null);
|
|
8340
|
-
const
|
|
9089
|
+
const tone = pn.badge;
|
|
9090
|
+
if (tone && !BADGE_TONES.includes(tone))
|
|
9091
|
+
throw new ComposeError(`${id}: a badge has no tone "${pn.badge}"`);
|
|
9092
|
+
for (const key of Object.keys(pn.words ?? {}))
|
|
9093
|
+
if (!CARD_WORD_KEYS.includes(key))
|
|
9094
|
+
throw new ComposeError(`${id}: a card has no words "${key}"`);
|
|
9095
|
+
const card = buildCardRecipe(factory, {
|
|
9096
|
+
layout, parts: pn.parts, words: pn.words, badgeTone: tone,
|
|
9097
|
+
});
|
|
9098
|
+
if (pn.scheme) {
|
|
9099
|
+
if (!COLOR_SCHEMES.some(c => c.id === pn.scheme))
|
|
9100
|
+
throw new ComposeError(`${id}: no colour scheme "${pn.scheme}"`);
|
|
9101
|
+
setColorScheme(card, pn.scheme);
|
|
9102
|
+
}
|
|
9103
|
+
if (pn.ph === PatternPlaceholder.Copy)
|
|
9104
|
+
copyPlaceholders(card, ctx);
|
|
9105
|
+
if (pn.c?.length) {
|
|
9106
|
+
const content = findByRole(card, CardRole.Content);
|
|
9107
|
+
content.children = [...(content.children ?? []), ...composeChildren(pn, id, repeater, ctx)];
|
|
9108
|
+
}
|
|
8341
9109
|
for (const [key, path] of Object.entries(pn.binds ?? {})) {
|
|
8342
9110
|
const target = CARD_BINDS[key];
|
|
8343
9111
|
if (!target)
|
|
@@ -8370,6 +9138,31 @@ function composeRecipe(pn, id, repeater, ctx) {
|
|
|
8370
9138
|
return card;
|
|
8371
9139
|
}
|
|
8372
9140
|
const REPEATER = 'Repeater';
|
|
9141
|
+
const ICON = 'Icon';
|
|
9142
|
+
const SHOWN_DISPLAY = 'flex';
|
|
9143
|
+
const HIDDEN_DISPLAY = 'none';
|
|
9144
|
+
/** The words a card recipe's `words` may set (composite-core `CardWords`). */
|
|
9145
|
+
const CARD_WORD_KEYS = ['eyebrow', 'title', 'text', 'primary', 'secondary', 'badge'];
|
|
9146
|
+
/** A card's words the studio rewrites (`ph: 'copy'`): its eyebrow, title, text and badge. */
|
|
9147
|
+
const CARD_COPY_ROLES = [CardRole.Eyebrow, CardRole.Title, CardRole.Text];
|
|
9148
|
+
/** A card's own words, as COPY placeholders (its badge's words too). */
|
|
9149
|
+
function copyPlaceholders(card, ctx) {
|
|
9150
|
+
for (const role of CARD_COPY_ROLES) {
|
|
9151
|
+
const part = findByRole(card, role);
|
|
9152
|
+
if (part)
|
|
9153
|
+
ctx.placeholders.push({ nodeId: part.id, owner: ctx.owner, kind: PlaceholderKind.Copy, text: String(part.props?.['content'] ?? '') });
|
|
9154
|
+
}
|
|
9155
|
+
const badge = findByRole(card, CardRole.Badge);
|
|
9156
|
+
const words = badge?.children?.find(c => c.type === TEXT);
|
|
9157
|
+
if (words)
|
|
9158
|
+
ctx.placeholders.push({ nodeId: words.id, owner: ctx.owner, kind: PlaceholderKind.Copy, text: String(words.props?.['content'] ?? '') });
|
|
9159
|
+
}
|
|
9160
|
+
/** CC4b: the Segmented control — composite-core's recipe (Monthly · Yearly), named by the pattern, laid out by it. */
|
|
9161
|
+
function composeSegmented(pn, id) {
|
|
9162
|
+
const root = buildSegmentedRecipe(recipeFactory(id, 'segmented'), pn.name !== undefined ? { label: pn.name } : {});
|
|
9163
|
+
applyLayout(root, pn);
|
|
9164
|
+
return root;
|
|
9165
|
+
}
|
|
8373
9166
|
/**
|
|
8374
9167
|
* An Accordion (CC2) — the composite-core recipe stamped with this composer's factory. Manual (no section
|
|
8375
9168
|
* binding): three items whose questions and answers are placeholders the studio rewrites (`ph: 'copy'`), never
|
|
@@ -8529,11 +9322,12 @@ function wireOpeners(root, openers) {
|
|
|
8529
9322
|
function composePattern(pattern, id, ctx) {
|
|
8530
9323
|
if (pattern.node.each)
|
|
8531
9324
|
throw new ComposeError(`${id}: a pattern's root cannot be stamped per page`);
|
|
8532
|
-
const own = { ...ctx, openers: [] };
|
|
9325
|
+
const own = { ...ctx, openers: [], shownWhen: [] };
|
|
8533
9326
|
const node = composeNode(pattern.node, id, null, own);
|
|
8534
9327
|
if (!node)
|
|
8535
9328
|
throw new ComposeError(`${id}: a pattern's root cannot be optional or a link`);
|
|
8536
9329
|
wireOpeners(node, own.openers ?? []);
|
|
9330
|
+
wireShownWhen(node, own.shownWhen ?? []);
|
|
8537
9331
|
node.label = pattern.label;
|
|
8538
9332
|
return node;
|
|
8539
9333
|
}
|
|
@@ -8634,6 +9428,85 @@ function composeSite(plan, context) {
|
|
|
8634
9428
|
issues,
|
|
8635
9429
|
};
|
|
8636
9430
|
}
|
|
9431
|
+
// ── The site header on its own (CC1.1) ──────────────────────────────────────────────────────────
|
|
9432
|
+
/** The header pattern the Studio template stamps — and the builder palette's "Navigation bar". */
|
|
9433
|
+
const SITE_HEADER_PATTERN = 'nav.inline-cta';
|
|
9434
|
+
const ROUTE_PARAM = ':';
|
|
9435
|
+
const HOME_PATH = '/';
|
|
9436
|
+
const KEY_UNSAFE = /[^a-z0-9]+/gi;
|
|
9437
|
+
/** The pages a navigation links to: every page but Home (the brand links there) and template pages
|
|
9438
|
+
* (a `/work/:slug` route has no single address), in the studio's order. */
|
|
9439
|
+
function siteNavPages(pages) {
|
|
9440
|
+
return pages.filter(p => !!p.route && !p.isHome && p.route !== HOME_PATH && !p.route.includes(ROUTE_PARAM));
|
|
9441
|
+
}
|
|
9442
|
+
function navPagePlans(pages) {
|
|
9443
|
+
const used = new Set();
|
|
9444
|
+
return pages.map((p, i) => {
|
|
9445
|
+
let key = p.route.replace(KEY_UNSAFE, '-').replace(/^-+|-+$/g, '').toLowerCase() || `page-${i}`;
|
|
9446
|
+
for (let n = 2; used.has(key); n++)
|
|
9447
|
+
key = `${key}-${n}`;
|
|
9448
|
+
used.add(key);
|
|
9449
|
+
return { key, name: p.name, route: p.route, inNav: true, isHome: p.isHome === true, sections: [] };
|
|
9450
|
+
});
|
|
9451
|
+
}
|
|
9452
|
+
/**
|
|
9453
|
+
* The Studio template's header, composed for a studio that has no Site Plan — the builder palette's
|
|
9454
|
+
* "Navigation bar". THE SAME pattern and the same composer as `composeSite`: the brand (the business name),
|
|
9455
|
+
* one plain Link per navigation page, the call to action (W1.1's one dangling-link rule when the studio has
|
|
9456
|
+
* no /contact page: an email to the business, else removed), and the pattern's phone shape. Pure.
|
|
9457
|
+
*/
|
|
9458
|
+
function composeNavHeader(input, options) {
|
|
9459
|
+
if (!nonEmpty(options?.id))
|
|
9460
|
+
throw new ComposeError('composeNavHeader needs the header id');
|
|
9461
|
+
const pattern = patternById(SITE_HEADER_PATTERN);
|
|
9462
|
+
const all = navPagePlans(input.pages);
|
|
9463
|
+
const navRoutes = new Set(siteNavPages(input.pages).map(p => p.route));
|
|
9464
|
+
const pages = all.map(p => ({ ...p, inNav: navRoutes.has(p.route) }));
|
|
9465
|
+
const plan = { business: input.business, pages, dataSources: [], contentTypes: [] };
|
|
9466
|
+
const email = nonEmpty(input.business.facts?.email) ? input.business.facts.email.trim() : null;
|
|
9467
|
+
const issues = [];
|
|
9468
|
+
const ctx = {
|
|
9469
|
+
owner: GlobalSlot.Header, page: null, section: null, plan, year: 0, email, navPage: null, nextAlias: null,
|
|
9470
|
+
placeholders: [], issues, routes: new Set(pages.map(p => p.route)),
|
|
9471
|
+
};
|
|
9472
|
+
const root = composePattern(pattern, options.id, ctx);
|
|
9473
|
+
root.isGlobal = true;
|
|
9474
|
+
root.globalPosition = pattern.global;
|
|
9475
|
+
const shape = pattern.phoneMenu;
|
|
9476
|
+
const header = shape ? planNavShape([root], shape, { newId: options.newId }, root.id).globals[0] : root;
|
|
9477
|
+
return { header, issues };
|
|
9478
|
+
}
|
|
9479
|
+
// ── One pattern on its own (CC4b) ───────────────────────────────────────────────────────────────
|
|
9480
|
+
/** The pricing section (CC4b, board 10): plans with a Monthly / Yearly switch — the library and the palette, never a
|
|
9481
|
+
* Studio page (Q35). */
|
|
9482
|
+
const PRICING_PATTERN = 'pricing.tiers';
|
|
9483
|
+
/**
|
|
9484
|
+
* ONE library pattern composed on its own — the builder palette's ready-made sections (CC4b: "Pricing", the
|
|
9485
|
+
* `pricing.tiers` pattern). THE SAME pattern and composer as `composeSite`: its words, its placeholders (a price shows
|
|
9486
|
+
* its label, never a number) and the one dangling-link rule — except a button to a page the studio lacks keeps its
|
|
9487
|
+
* words, unlinked, for the author to link. Pure.
|
|
9488
|
+
*/
|
|
9489
|
+
function composeSection(patternId, input, options) {
|
|
9490
|
+
if (!nonEmpty(options?.id))
|
|
9491
|
+
throw new ComposeError('composeSection needs the section id');
|
|
9492
|
+
const pattern = patternById(patternId);
|
|
9493
|
+
if (!pattern)
|
|
9494
|
+
throw new ComposeError(`no pattern "${patternId}" in the library`);
|
|
9495
|
+
if (pattern.global)
|
|
9496
|
+
throw new ComposeError(`"${patternId}" is a header or footer — composeNavHeader / composeSite stamp those`);
|
|
9497
|
+
const business = input.business ?? { name: '' };
|
|
9498
|
+
const pages = navPagePlans(input.pages ?? []);
|
|
9499
|
+
const plan = { business, pages, dataSources: [], contentTypes: [] };
|
|
9500
|
+
const email = nonEmpty(business.facts?.email) ? business.facts.email.trim() : null;
|
|
9501
|
+
const placeholders = [];
|
|
9502
|
+
const issues = [];
|
|
9503
|
+
const ctx = {
|
|
9504
|
+
owner: options.id, page: null, section: null, plan, year: 0, email, navPage: null, nextAlias: null,
|
|
9505
|
+
placeholders, issues, routes: new Set(pages.map(p => p.route)), keepButtons: true,
|
|
9506
|
+
};
|
|
9507
|
+
const section = composePattern(pattern, options.id, ctx);
|
|
9508
|
+
return { section, placeholders, issues };
|
|
9509
|
+
}
|
|
8637
9510
|
|
|
8638
9511
|
/**
|
|
8639
9512
|
* @vectoriox/iox-ui/generation-core — the shared, FRAMEWORK-FREE site-plan core (design-system plan
|
|
@@ -8651,5 +9524,5 @@ function composeSite(plan, context) {
|
|
|
8651
9524
|
* Generated bundle index. Do not edit.
|
|
8652
9525
|
*/
|
|
8653
9526
|
|
|
8654
|
-
export { BAR_ITEMS_MAX, BAR_ITEMS_MIN, BASELINE_ROLES, BaselineRole, BindScope, CardBindTarget, ComposeError, ComposeIssueCode, DANGLING_LINK_CODES, DEFAULT_PHONE_MENU_BREAKPOINT, FACT_KEYS, GlobalSlot, NAV_PART_LABELS, NAV_SHAPE_COPY, NEUTRAL_STYLE_PROPS, NODE_BASELINES, NavRole, NavShape, NavShapeError, PatternDirective, PatternGlobalPosition, PatternOpens, PatternPlaceholder, PatternRecipe, PhoneMenuBreakpoint, 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, addBarItem, altSourceScopes, assertStyleSlots, assertValidSitePlan, barIconForRoute, composeSite, createSerializedNode, findNavRoot, navPages, navShapeBreakpoint, navShapeOf, nextSourceOf, nodeBindPaths, parseSampleImageRef, patternById, patternNeedsBinding, patternNodes, patternOptionalParts, patternScopes, patternSlots, patternTakesBinding, planFromTemplate, planNavShape, releasedLayoutDefaults, requiredShapeKeys, routeParams, sampleImageRef, setStyleProps, shapeKeys, validateSitePlan, walkSerialized };
|
|
9527
|
+
export { BAR_ITEMS_MAX, BAR_ITEMS_MIN, BASELINE_ROLES, BaselineRole, BindScope, CardBindTarget, ComposeError, ComposeIssueCode, DANGLING_LINK_CODES, DEFAULT_PHONE_MENU_BREAKPOINT, FACT_KEYS, GlobalSlot, NAV_PART_LABELS, NAV_SHAPE_COPY, NEUTRAL_STYLE_PROPS, NODE_BASELINES, NavPagesSource, NavRole, NavShape, NavShapeError, PRICING_PATTERN, PUBLISH_BLOCKING_PLACEHOLDERS, PatternDirective, PatternGlobalPosition, PatternOpens, PatternPlaceholder, PatternRecipe, PhoneMenuBreakpoint, PlaceholderKind, PlanDataSourceMode, PlanDataSourceType, RelativeOp, SAMPLE_IMAGE_REF, SITE_FACT_LABELS, SITE_HEADER_PATTERN, 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, addBarItem, altSourceScopes, assertStyleSlots, assertValidSitePlan, barIconForRoute, blocksPublish, composeNavHeader, composeSection, composeSite, createSerializedNode, findNavRoot, moveBarItem, navPages, navShapeBreakpoint, navShapeOf, nextSourceOf, nodeBindPaths, parseSampleImageRef, patternById, patternNeedsBinding, patternNodes, patternOptionalParts, patternScopes, patternSlots, patternTakesBinding, phoneMenuPages, planFromTemplate, planNavShape, releasedLayoutDefaults, removeBarItem, requiredShapeKeys, routeParams, sampleImageRef, setStyleProps, shapeKeys, siteNavPages, validateSitePlan, walkSerialized };
|
|
8655
9528
|
//# sourceMappingURL=vectoriox-iox-ui-generation-core.mjs.map
|