@vectoriox/iox-ui 5.36.0 → 5.38.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/actions-core/index.d.ts +17 -3
- package/composite-core/index.d.ts +463 -31
- package/design-core/index.d.ts +130 -3
- package/fesm2022/vectoriox-iox-ui-actions-core.mjs +33 -3
- package/fesm2022/vectoriox-iox-ui-actions-core.mjs.map +1 -1
- package/fesm2022/vectoriox-iox-ui-composite-core.mjs +1062 -121
- package/fesm2022/vectoriox-iox-ui-composite-core.mjs.map +1 -1
- package/fesm2022/vectoriox-iox-ui-design-core.mjs +172 -3
- package/fesm2022/vectoriox-iox-ui-design-core.mjs.map +1 -1
- package/fesm2022/vectoriox-iox-ui-generation-core.mjs +410 -10
- package/fesm2022/vectoriox-iox-ui-generation-core.mjs.map +1 -1
- package/fesm2022/vectoriox-iox-ui-media-core.mjs +571 -0
- package/fesm2022/vectoriox-iox-ui-media-core.mjs.map +1 -0
- package/fesm2022/vectoriox-iox-ui.mjs +482 -120
- package/fesm2022/vectoriox-iox-ui.mjs.map +1 -1
- package/generation-core/index.d.ts +167 -4
- package/index.d.ts +209 -25
- package/media-core/index.d.ts +277 -0
- package/media-core/package.json +3 -0
- package/package.json +5 -1
- package/src/actions-core/action.model.ts +4 -2
- package/src/actions-core/element-actions.ts +37 -2
- package/src/composite-core/accordion-runtime.ts +117 -28
- package/src/composite-core/accordion.ts +89 -45
- package/src/composite-core/composite-kinds.ts +110 -0
- package/src/composite-core/composite-node.ts +15 -0
- package/src/composite-core/disclosure.ts +125 -0
- package/src/composite-core/lightbox.ts +192 -0
- package/src/composite-core/public-api.ts +7 -1
- package/src/composite-core/slider-runtime.ts +180 -0
- package/src/composite-core/slider.ts +378 -0
- package/src/composite-core/structure.ts +25 -5
- package/src/design-core/element-styles.ts +27 -0
- package/src/design-core/flavor-spec.generated.ts +146 -2
- package/src/generation-core/baseline-roles.ts +2 -0
- package/src/generation-core/compose-site.ts +80 -4
- package/src/generation-core/node-baselines.generated.ts +148 -4
- package/src/generation-core/patterns.ts +17 -0
- package/src/generation-core/site-spec.generated.ts +164 -0
- package/src/media-core/public-api.ts +9 -0
- package/src/media-core/video-runtime.ts +239 -0
- package/src/media-core/video.ts +443 -0
- package/styles/iox-design.css +96 -0
|
@@ -1108,6 +1108,21 @@ export const SPEC_TIERS = {
|
|
|
1108
1108
|
"name": "media-scrim-ink",
|
|
1109
1109
|
"type": "color",
|
|
1110
1110
|
"default": "#FFFFFF"
|
|
1111
|
+
},
|
|
1112
|
+
{
|
|
1113
|
+
"name": "video-play-bg",
|
|
1114
|
+
"type": "color",
|
|
1115
|
+
"default": "var(--iox-button-primary-bg)"
|
|
1116
|
+
},
|
|
1117
|
+
{
|
|
1118
|
+
"name": "video-play-ink",
|
|
1119
|
+
"type": "color",
|
|
1120
|
+
"default": "var(--iox-button-primary-ink)"
|
|
1121
|
+
},
|
|
1122
|
+
{
|
|
1123
|
+
"name": "video-play-size",
|
|
1124
|
+
"type": "size",
|
|
1125
|
+
"default": "64px"
|
|
1111
1126
|
}
|
|
1112
1127
|
]
|
|
1113
1128
|
} as const;
|
|
@@ -1785,7 +1800,8 @@ export const SPEC_ELEMENT_STYLES = [
|
|
|
1785
1800
|
"appliesTo": [
|
|
1786
1801
|
"Container",
|
|
1787
1802
|
"LinkedContainer",
|
|
1788
|
-
"Card"
|
|
1803
|
+
"Card",
|
|
1804
|
+
"SliderSlide"
|
|
1789
1805
|
],
|
|
1790
1806
|
"base": {
|
|
1791
1807
|
"color": "inherit",
|
|
@@ -1940,7 +1956,8 @@ export const SPEC_ELEMENT_STYLES = [
|
|
|
1940
1956
|
"appliesTo": [
|
|
1941
1957
|
"Image",
|
|
1942
1958
|
"SliderSlide",
|
|
1943
|
-
"Gallery"
|
|
1959
|
+
"Gallery",
|
|
1960
|
+
"Video"
|
|
1944
1961
|
],
|
|
1945
1962
|
"base": {
|
|
1946
1963
|
"borderRadius": "var(--iox-image-radius)",
|
|
@@ -2186,6 +2203,7 @@ export const SPEC_DEFAULT_ELEMENT_STYLE = {
|
|
|
2186
2203
|
"Link": "link",
|
|
2187
2204
|
"Image": "media",
|
|
2188
2205
|
"SliderSlide": "media",
|
|
2206
|
+
"Video": "media",
|
|
2189
2207
|
"Divider": "rule",
|
|
2190
2208
|
"Icon": "icon",
|
|
2191
2209
|
"Dialog": "dialog",
|
|
@@ -4288,6 +4306,27 @@ export const SPEC_FLAVOR_PACKS = [
|
|
|
4288
4306
|
"type": "color",
|
|
4289
4307
|
"group": "components",
|
|
4290
4308
|
"value": "#FFFFFF"
|
|
4309
|
+
},
|
|
4310
|
+
{
|
|
4311
|
+
"name": "video-play-bg",
|
|
4312
|
+
"tier": "component",
|
|
4313
|
+
"type": "color",
|
|
4314
|
+
"group": "components",
|
|
4315
|
+
"value": "var(--iox-button-primary-bg)"
|
|
4316
|
+
},
|
|
4317
|
+
{
|
|
4318
|
+
"name": "video-play-ink",
|
|
4319
|
+
"tier": "component",
|
|
4320
|
+
"type": "color",
|
|
4321
|
+
"group": "components",
|
|
4322
|
+
"value": "var(--iox-button-primary-ink)"
|
|
4323
|
+
},
|
|
4324
|
+
{
|
|
4325
|
+
"name": "video-play-size",
|
|
4326
|
+
"tier": "component",
|
|
4327
|
+
"type": "size",
|
|
4328
|
+
"group": "components",
|
|
4329
|
+
"value": "64px"
|
|
4291
4330
|
}
|
|
4292
4331
|
]
|
|
4293
4332
|
},
|
|
@@ -5910,6 +5949,27 @@ export const SPEC_FLAVOR_PACKS = [
|
|
|
5910
5949
|
"type": "color",
|
|
5911
5950
|
"group": "components",
|
|
5912
5951
|
"value": "#FFFFFF"
|
|
5952
|
+
},
|
|
5953
|
+
{
|
|
5954
|
+
"name": "video-play-bg",
|
|
5955
|
+
"tier": "component",
|
|
5956
|
+
"type": "color",
|
|
5957
|
+
"group": "components",
|
|
5958
|
+
"value": "var(--iox-button-primary-bg)"
|
|
5959
|
+
},
|
|
5960
|
+
{
|
|
5961
|
+
"name": "video-play-ink",
|
|
5962
|
+
"tier": "component",
|
|
5963
|
+
"type": "color",
|
|
5964
|
+
"group": "components",
|
|
5965
|
+
"value": "var(--iox-button-primary-ink)"
|
|
5966
|
+
},
|
|
5967
|
+
{
|
|
5968
|
+
"name": "video-play-size",
|
|
5969
|
+
"tier": "component",
|
|
5970
|
+
"type": "size",
|
|
5971
|
+
"group": "components",
|
|
5972
|
+
"value": "64px"
|
|
5913
5973
|
}
|
|
5914
5974
|
]
|
|
5915
5975
|
},
|
|
@@ -7524,6 +7584,27 @@ export const SPEC_FLAVOR_PACKS = [
|
|
|
7524
7584
|
"type": "color",
|
|
7525
7585
|
"group": "components",
|
|
7526
7586
|
"value": "#FFFFFF"
|
|
7587
|
+
},
|
|
7588
|
+
{
|
|
7589
|
+
"name": "video-play-bg",
|
|
7590
|
+
"tier": "component",
|
|
7591
|
+
"type": "color",
|
|
7592
|
+
"group": "components",
|
|
7593
|
+
"value": "var(--iox-button-primary-bg)"
|
|
7594
|
+
},
|
|
7595
|
+
{
|
|
7596
|
+
"name": "video-play-ink",
|
|
7597
|
+
"tier": "component",
|
|
7598
|
+
"type": "color",
|
|
7599
|
+
"group": "components",
|
|
7600
|
+
"value": "var(--iox-button-primary-ink)"
|
|
7601
|
+
},
|
|
7602
|
+
{
|
|
7603
|
+
"name": "video-play-size",
|
|
7604
|
+
"tier": "component",
|
|
7605
|
+
"type": "size",
|
|
7606
|
+
"group": "components",
|
|
7607
|
+
"value": "64px"
|
|
7527
7608
|
}
|
|
7528
7609
|
]
|
|
7529
7610
|
},
|
|
@@ -9180,6 +9261,27 @@ export const SPEC_FLAVOR_PACKS = [
|
|
|
9180
9261
|
"type": "color",
|
|
9181
9262
|
"group": "components",
|
|
9182
9263
|
"value": "#FFFFFF"
|
|
9264
|
+
},
|
|
9265
|
+
{
|
|
9266
|
+
"name": "video-play-bg",
|
|
9267
|
+
"tier": "component",
|
|
9268
|
+
"type": "color",
|
|
9269
|
+
"group": "components",
|
|
9270
|
+
"value": "var(--iox-button-primary-bg)"
|
|
9271
|
+
},
|
|
9272
|
+
{
|
|
9273
|
+
"name": "video-play-ink",
|
|
9274
|
+
"tier": "component",
|
|
9275
|
+
"type": "color",
|
|
9276
|
+
"group": "components",
|
|
9277
|
+
"value": "var(--iox-button-primary-ink)"
|
|
9278
|
+
},
|
|
9279
|
+
{
|
|
9280
|
+
"name": "video-play-size",
|
|
9281
|
+
"tier": "component",
|
|
9282
|
+
"type": "size",
|
|
9283
|
+
"group": "components",
|
|
9284
|
+
"value": "64px"
|
|
9183
9285
|
}
|
|
9184
9286
|
]
|
|
9185
9287
|
},
|
|
@@ -10798,6 +10900,27 @@ export const SPEC_FLAVOR_PACKS = [
|
|
|
10798
10900
|
"type": "color",
|
|
10799
10901
|
"group": "components",
|
|
10800
10902
|
"value": "#FFFFFF"
|
|
10903
|
+
},
|
|
10904
|
+
{
|
|
10905
|
+
"name": "video-play-bg",
|
|
10906
|
+
"tier": "component",
|
|
10907
|
+
"type": "color",
|
|
10908
|
+
"group": "components",
|
|
10909
|
+
"value": "var(--iox-button-primary-bg)"
|
|
10910
|
+
},
|
|
10911
|
+
{
|
|
10912
|
+
"name": "video-play-ink",
|
|
10913
|
+
"tier": "component",
|
|
10914
|
+
"type": "color",
|
|
10915
|
+
"group": "components",
|
|
10916
|
+
"value": "var(--iox-button-primary-ink)"
|
|
10917
|
+
},
|
|
10918
|
+
{
|
|
10919
|
+
"name": "video-play-size",
|
|
10920
|
+
"tier": "component",
|
|
10921
|
+
"type": "size",
|
|
10922
|
+
"group": "components",
|
|
10923
|
+
"value": "64px"
|
|
10801
10924
|
}
|
|
10802
10925
|
]
|
|
10803
10926
|
},
|
|
@@ -12423,6 +12546,27 @@ export const SPEC_FLAVOR_PACKS = [
|
|
|
12423
12546
|
"type": "color",
|
|
12424
12547
|
"group": "components",
|
|
12425
12548
|
"value": "#FFFFFF"
|
|
12549
|
+
},
|
|
12550
|
+
{
|
|
12551
|
+
"name": "video-play-bg",
|
|
12552
|
+
"tier": "component",
|
|
12553
|
+
"type": "color",
|
|
12554
|
+
"group": "components",
|
|
12555
|
+
"value": "var(--iox-button-primary-bg)"
|
|
12556
|
+
},
|
|
12557
|
+
{
|
|
12558
|
+
"name": "video-play-ink",
|
|
12559
|
+
"tier": "component",
|
|
12560
|
+
"type": "color",
|
|
12561
|
+
"group": "components",
|
|
12562
|
+
"value": "var(--iox-button-primary-ink)"
|
|
12563
|
+
},
|
|
12564
|
+
{
|
|
12565
|
+
"name": "video-play-size",
|
|
12566
|
+
"tier": "component",
|
|
12567
|
+
"type": "size",
|
|
12568
|
+
"group": "components",
|
|
12569
|
+
"value": "64px"
|
|
12426
12570
|
}
|
|
12427
12571
|
]
|
|
12428
12572
|
}
|
|
@@ -61,6 +61,8 @@ export const BASELINE_ROLES: Readonly<Record<string, Readonly<Record<string, Bas
|
|
|
61
61
|
FormSuccess: { width: Behaviour, color: Look, padding: Look, borderRadius: Look, backgroundColor: Look },
|
|
62
62
|
FormError: { width: Behaviour, color: Look, padding: Look, borderRadius: Look, backgroundColor: Look },
|
|
63
63
|
Dialog: { width: Behaviour, padding: Look, borderRadius: Look, backgroundColor: Look, boxShadow: Look },
|
|
64
|
+
// CC3: a Video fills its column at 16 / 9 — the shape the poster and the player take.
|
|
65
|
+
Video: { width: Behaviour, aspectRatio: Behaviour },
|
|
64
66
|
};
|
|
65
67
|
|
|
66
68
|
/** The style values a type's constructor sets for an empty palette drop, each mapped to the value the
|
|
@@ -2,12 +2,12 @@ import { DesignChoices, LinkType, resolveDesignChoices } from '@vectoriox/iox-ui
|
|
|
2
2
|
import { FormPresetDef, FormPresetField, formPresetById } from '@vectoriox/iox-ui/forms-core';
|
|
3
3
|
import {
|
|
4
4
|
ACCORDION_BIND_PROP, ACCORDION_CONTENT_LIMIT, ACCORDION_WORDS, accordionAnswerOf, accordionItems, accordionQuestionOf, AccordionRole,
|
|
5
|
-
buildAccordionRecipe, buildCardRecipe, CardLayout, CardPart, CardRole, CARD_LAYOUTS, CARD_PARTS, CompositeNode,
|
|
6
|
-
pickAccordionAutoBinds,
|
|
5
|
+
buildAccordionRecipe, buildCardRecipe, buildCarouselRecipe, buildLightboxRecipe, CardLayout, CardPart, CardRole, CARD_LAYOUTS, CARD_PARTS, CompositeNode,
|
|
6
|
+
CompositeNodeSpec, findByRole, LIGHTBOX_LABEL, pickAccordionAutoBinds, SLIDE_TO_ROW, SLIDE_TYPE,
|
|
7
7
|
} from '@vectoriox/iox-ui/composite-core';
|
|
8
8
|
|
|
9
9
|
import { NODE_BASELINES } from './node-baselines.generated';
|
|
10
|
-
import { BindScope, CardBindTarget, PatternDirective, PatternNode, PatternPlaceholder, PatternRecipe, SitePattern, patternById } from './patterns';
|
|
10
|
+
import { BindScope, CardBindTarget, PatternDirective, PatternNode, PatternOpens, PatternPlaceholder, PatternRecipe, SitePattern, patternById } from './patterns';
|
|
11
11
|
import { assertStyleSlots, ComposeError, createSerializedNode, SerializedBinding, SerializedNode, setStyleProps } from './serialized-node';
|
|
12
12
|
import {
|
|
13
13
|
ContentTypePlan, DataSourcePlan, FactKey, FACT_KEYS, GlobalSlot, PagePlan, PageSectionPlan, PlanDataSourceMode, PlanDataSourceType,
|
|
@@ -37,6 +37,8 @@ export enum PlaceholderKind {
|
|
|
37
37
|
Copy = 'copy',
|
|
38
38
|
/** An image slot with no image: the empty-image placeholder (DS3). */
|
|
39
39
|
Image = 'image',
|
|
40
|
+
/** CC3: a video slot with no clip — the studio uploads its own (the poster blank meanwhile). */
|
|
41
|
+
Video = 'video',
|
|
40
42
|
}
|
|
41
43
|
|
|
42
44
|
export interface ComposedPlaceholder {
|
|
@@ -174,6 +176,10 @@ const BUTTON_BLOCK = 'ButtonBlock';
|
|
|
174
176
|
const FORM = 'Form';
|
|
175
177
|
const FIELD = 'Field';
|
|
176
178
|
const IMAGE = 'Image';
|
|
179
|
+
const VIDEO = 'Video';
|
|
180
|
+
/** A Video's source prop (media-core `VideoTrait.Source` — not `source`, which names a data source). */
|
|
181
|
+
const VIDEO_SOURCE_PROP = 'videoSource';
|
|
182
|
+
const DIALOG = 'Dialog';
|
|
177
183
|
const SUBMIT_BUTTON = 'SubmitButton';
|
|
178
184
|
const FORM_SUCCESS = 'FormSuccess';
|
|
179
185
|
const FORM_ERROR = 'FormError';
|
|
@@ -231,6 +237,8 @@ interface Ctx {
|
|
|
231
237
|
placeholders: ComposedPlaceholder[];
|
|
232
238
|
issues: ComposeIssue[];
|
|
233
239
|
routes: ReadonlySet<string>;
|
|
240
|
+
/** CC3: nodes whose click opens the pattern's lightbox (`opens`), wired once the pattern is stamped. */
|
|
241
|
+
openers?: string[];
|
|
234
242
|
}
|
|
235
243
|
|
|
236
244
|
function nonEmpty(v: unknown): v is string {
|
|
@@ -480,6 +488,22 @@ function composeNode(pn: PatternNode, id: string, repeater: RepeaterScope | null
|
|
|
480
488
|
}
|
|
481
489
|
}
|
|
482
490
|
|
|
491
|
+
// CC3: a Video in background mode is an uploaded file's; its clip is the studio's own (a placeholder until then).
|
|
492
|
+
if (pn.video) {
|
|
493
|
+
if (type !== VIDEO) throw new ComposeError(`${id}: "video" belongs on a Video`);
|
|
494
|
+
setProp(node, VIDEO_SOURCE_PROP, 'file');
|
|
495
|
+
setProp(node, 'mode', pn.video);
|
|
496
|
+
}
|
|
497
|
+
if (pn.ph === PatternPlaceholder.Video) {
|
|
498
|
+
setProp(node, 'src', '');
|
|
499
|
+
ctx.placeholders.push({ nodeId: id, owner: ctx.owner, kind: PlaceholderKind.Video, text: '' });
|
|
500
|
+
}
|
|
501
|
+
if (pn.name) setProp(node, 'ariaLabel', pn.name);
|
|
502
|
+
if (pn.opens) {
|
|
503
|
+
if (pn.opens !== PatternOpens.Lightbox) throw new ComposeError(`${id}: "opens" names the pattern's lightbox`);
|
|
504
|
+
(ctx.openers ??= []).push(id);
|
|
505
|
+
}
|
|
506
|
+
|
|
483
507
|
// Images: an empty slot, or a bound one — both fall back to the DS3 empty image, never a stock URL.
|
|
484
508
|
if (pn.ph === PatternPlaceholder.Image) {
|
|
485
509
|
setProp(node, 'src', '');
|
|
@@ -562,6 +586,8 @@ const CARD_BINDS: Readonly<Record<CardBindTarget, { role: CardRole; prop: string
|
|
|
562
586
|
*/
|
|
563
587
|
function composeRecipe(pn: PatternNode, id: string, repeater: RepeaterScope | null, ctx: Ctx): SerializedNode {
|
|
564
588
|
if (pn.recipe === PatternRecipe.Accordion) return composeAccordion(pn, id, ctx);
|
|
589
|
+
if (pn.recipe === PatternRecipe.Carousel) return composeCarousel(pn, id, ctx);
|
|
590
|
+
if (pn.recipe === PatternRecipe.Lightbox) return composeLightbox(pn, id, repeater, ctx);
|
|
565
591
|
if (pn.recipe !== PatternRecipe.Card) throw new ComposeError(`${id}: no recipe "${pn.recipe}" in composite-core`);
|
|
566
592
|
const layout = (pn.layout ?? CardLayout.Top) as CardLayout;
|
|
567
593
|
if (!CARD_LAYOUTS.includes(layout)) throw new ComposeError(`${id}: a card has no layout "${pn.layout}"`);
|
|
@@ -641,10 +667,60 @@ function composeAccordion(pn: PatternNode, id: string, ctx: Ctx): SerializedNode
|
|
|
641
667
|
return root;
|
|
642
668
|
}
|
|
643
669
|
|
|
670
|
+
/** A recipe's node factory for this composer: ids derive from the recipe's keys (`<id>-<key>`, the root `<id>`). */
|
|
671
|
+
function recipeFactory(id: string, rootKey: string): (spec: CompositeNodeSpec) => CompositeNode {
|
|
672
|
+
return spec => create(spec.key === rootKey ? id : `${id}-${spec.key}`, spec.type, { ...(spec.props ?? {}) }, spec.elementStyle ?? null) as CompositeNode;
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
/**
|
|
676
|
+
* CC3: the testimonial carousel — composite-core's recipe (the Slider with its control parts), stamped with this
|
|
677
|
+
* composer's factory. Every quote and every "client · project" line is a placeholder the studio rewrites (`ph: copy`):
|
|
678
|
+
* testimonials are facts, never invented.
|
|
679
|
+
*/
|
|
680
|
+
function composeCarousel(pn: PatternNode, id: string, ctx: Ctx): SerializedNode {
|
|
681
|
+
const slider = buildCarouselRecipe(recipeFactory(id, 'carousel')) as SerializedNode;
|
|
682
|
+
if (pn.ph === PatternPlaceholder.Copy) {
|
|
683
|
+
for (const slide of (slider.children ?? []).filter(c => c.type === SLIDE_TYPE)) {
|
|
684
|
+
for (const text of slide.children ?? []) ctx.placeholders.push({ nodeId: text.id, owner: ctx.owner, kind: PlaceholderKind.Copy, text: String(text.props?.['content'] ?? '') });
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
return slider;
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
/**
|
|
691
|
+
* CC3: the Lightbox — a Dialog holding a Slider bound to the node's `src` (the gallery's own source): one template
|
|
692
|
+
* slide whose image reads the row (a bare URL row: decorative alt), its arrows hidden on a phone.
|
|
693
|
+
*/
|
|
694
|
+
function composeLightbox(pn: PatternNode, id: string, repeater: RepeaterScope | null, ctx: Ctx): SerializedNode {
|
|
695
|
+
if (!pn.src) throw new ComposeError(`${id}: a lightbox needs the gallery's source (src)`);
|
|
696
|
+
const scoped = resolveScoped(pn.src, repeater, ctx, id);
|
|
697
|
+
const sourcePath = scoped.path === ITEM_VALUE_PATH ? '' : scoped.path;
|
|
698
|
+
return buildLightboxRecipe(recipeFactory(id, 'lightbox'), { source: scoped.source, sourcePath, imageField: 'item' }) as SerializedNode;
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
/** CC3: every `opens: lightbox` node of a stamped pattern opens the pattern's lightbox at its own row. */
|
|
702
|
+
function wireOpeners(root: SerializedNode, openers: ReadonlyArray<string>): void {
|
|
703
|
+
if (!openers.length) return;
|
|
704
|
+
let lightbox: SerializedNode | null = null;
|
|
705
|
+
const find = (n: SerializedNode) => { if (!lightbox && n.type === DIALOG && n.label === LIGHTBOX_LABEL) lightbox = n; (n.children ?? []).forEach(find); };
|
|
706
|
+
find(root);
|
|
707
|
+
if (!lightbox) throw new ComposeError(`${root.id}: "opens: lightbox" with no lightbox in the pattern`);
|
|
708
|
+
const target = (lightbox as SerializedNode).id;
|
|
709
|
+
const visit = (n: SerializedNode) => {
|
|
710
|
+
if (openers.includes(n.id)) {
|
|
711
|
+
n.interactions = [{ id: `${n.id}-opens`, trigger: 'click', actions: [{ type: 'openDialog', target, params: { slideTo: SLIDE_TO_ROW }, duration: 0, delay: 0, easing: 'ease' }] }];
|
|
712
|
+
}
|
|
713
|
+
(n.children ?? []).forEach(visit);
|
|
714
|
+
};
|
|
715
|
+
visit(root);
|
|
716
|
+
}
|
|
717
|
+
|
|
644
718
|
function composePattern(pattern: SitePattern, id: string, ctx: Ctx): SerializedNode {
|
|
645
719
|
if (pattern.node.each) throw new ComposeError(`${id}: a pattern's root cannot be stamped per page`);
|
|
646
|
-
const
|
|
720
|
+
const own: Ctx = { ...ctx, openers: [] };
|
|
721
|
+
const node = composeNode(pattern.node, id, null, own);
|
|
647
722
|
if (!node) throw new ComposeError(`${id}: a pattern's root cannot be optional or a link`);
|
|
723
|
+
wireOpeners(node, own.openers ?? []);
|
|
648
724
|
node.label = pattern.label;
|
|
649
725
|
return node;
|
|
650
726
|
}
|
|
@@ -3032,7 +3032,8 @@ export const NODE_BASELINES: Readonly<Record<string, NodeBaseline>> = {
|
|
|
3032
3032
|
"enableParallax": false,
|
|
3033
3033
|
"enableGrid": false,
|
|
3034
3034
|
"gridRows": 2,
|
|
3035
|
-
"breakpoints": ""
|
|
3035
|
+
"breakpoints": "",
|
|
3036
|
+
"ariaLabel": ""
|
|
3036
3037
|
},
|
|
3037
3038
|
"styleProps": {
|
|
3038
3039
|
"position": "static",
|
|
@@ -3142,7 +3143,9 @@ export const NODE_BASELINES: Readonly<Record<string, NodeBaseline>> = {
|
|
|
3142
3143
|
"enableGrid",
|
|
3143
3144
|
"gridRows",
|
|
3144
3145
|
"__responsiveLabel",
|
|
3145
|
-
"breakpoints"
|
|
3146
|
+
"breakpoints",
|
|
3147
|
+
"__accessibilityLabel",
|
|
3148
|
+
"ariaLabel"
|
|
3146
3149
|
],
|
|
3147
3150
|
"styleTraits": [
|
|
3148
3151
|
"position",
|
|
@@ -4660,7 +4663,8 @@ export const NODE_BASELINES: Readonly<Record<string, NodeBaseline>> = {
|
|
|
4660
4663
|
"showCloseButton": true,
|
|
4661
4664
|
"consentRole": false,
|
|
4662
4665
|
"closeAbove": "",
|
|
4663
|
-
"ariaLabel": ""
|
|
4666
|
+
"ariaLabel": "",
|
|
4667
|
+
"colorScheme": "default"
|
|
4664
4668
|
},
|
|
4665
4669
|
"styleProps": {
|
|
4666
4670
|
"position": "static",
|
|
@@ -4753,7 +4757,8 @@ export const NODE_BASELINES: Readonly<Record<string, NodeBaseline>> = {
|
|
|
4753
4757
|
"__responsiveLabel",
|
|
4754
4758
|
"closeAbove",
|
|
4755
4759
|
"__accessibilityLabel",
|
|
4756
|
-
"ariaLabel"
|
|
4760
|
+
"ariaLabel",
|
|
4761
|
+
"colorScheme"
|
|
4757
4762
|
],
|
|
4758
4763
|
"styleTraits": [
|
|
4759
4764
|
"position",
|
|
@@ -4847,6 +4852,145 @@ export const NODE_BASELINES: Readonly<Record<string, NodeBaseline>> = {
|
|
|
4847
4852
|
"transitionTimingFunction"
|
|
4848
4853
|
],
|
|
4849
4854
|
"container": true
|
|
4855
|
+
},
|
|
4856
|
+
"Video": {
|
|
4857
|
+
"props": {
|
|
4858
|
+
"videoSource": "youtube",
|
|
4859
|
+
"src": "",
|
|
4860
|
+
"poster": "",
|
|
4861
|
+
"mode": "inline",
|
|
4862
|
+
"autoplay": false,
|
|
4863
|
+
"title": "",
|
|
4864
|
+
"captions": "",
|
|
4865
|
+
"captionsLang": "en",
|
|
4866
|
+
"consentCategory": "marketing"
|
|
4867
|
+
},
|
|
4868
|
+
"styleProps": {
|
|
4869
|
+
"position": "static",
|
|
4870
|
+
"top": "auto",
|
|
4871
|
+
"right": "auto",
|
|
4872
|
+
"bottom": "auto",
|
|
4873
|
+
"left": "auto",
|
|
4874
|
+
"zIndex": "0",
|
|
4875
|
+
"width": "100%",
|
|
4876
|
+
"height": "auto",
|
|
4877
|
+
"minWidth": "auto",
|
|
4878
|
+
"minHeight": "auto",
|
|
4879
|
+
"maxWidth": "auto",
|
|
4880
|
+
"maxHeight": "auto",
|
|
4881
|
+
"aspectRatio": "16 / 9",
|
|
4882
|
+
"objectFit": "cover",
|
|
4883
|
+
"overflow": "visible",
|
|
4884
|
+
"margin": "0px 0px 0px 0px",
|
|
4885
|
+
"padding": "0px 0px 0px 0px",
|
|
4886
|
+
"borderWidth": "0px",
|
|
4887
|
+
"borderStyle": "solid",
|
|
4888
|
+
"borderColor": "#CCCCCC",
|
|
4889
|
+
"borderRadius": "0px",
|
|
4890
|
+
"opacity": "1",
|
|
4891
|
+
"mixBlendMode": "normal",
|
|
4892
|
+
"cursor": "auto",
|
|
4893
|
+
"boxShadow": "",
|
|
4894
|
+
"textShadow": "",
|
|
4895
|
+
"translateX": "0px",
|
|
4896
|
+
"translateY": "0px",
|
|
4897
|
+
"scaleX": "1",
|
|
4898
|
+
"scaleY": "1",
|
|
4899
|
+
"rotate": "0deg",
|
|
4900
|
+
"skewX": "0deg",
|
|
4901
|
+
"skewY": "0deg",
|
|
4902
|
+
"filterBlur": "0px",
|
|
4903
|
+
"filterHueRotate": "0deg",
|
|
4904
|
+
"filterBrightness": "1",
|
|
4905
|
+
"filterContrast": "1",
|
|
4906
|
+
"filterSaturate": "1",
|
|
4907
|
+
"filterGrayscale": "0",
|
|
4908
|
+
"filterSepia": "0",
|
|
4909
|
+
"filterInvert": "0",
|
|
4910
|
+
"backdropFilter": "none",
|
|
4911
|
+
"backdropBlur": "0px",
|
|
4912
|
+
"backdropBrightness": "1",
|
|
4913
|
+
"backdropContrast": "1",
|
|
4914
|
+
"backdropSaturate": "1",
|
|
4915
|
+
"clipPath": "none",
|
|
4916
|
+
"transitionDuration": "0ms",
|
|
4917
|
+
"transitionDelay": "0ms",
|
|
4918
|
+
"transitionTimingFunction": "ease"
|
|
4919
|
+
},
|
|
4920
|
+
"traits": [
|
|
4921
|
+
"__mediaLabel",
|
|
4922
|
+
"videoSource",
|
|
4923
|
+
"src",
|
|
4924
|
+
"poster",
|
|
4925
|
+
"__behaviourLabel",
|
|
4926
|
+
"mode",
|
|
4927
|
+
"autoplay",
|
|
4928
|
+
"__accessibilityLabel",
|
|
4929
|
+
"title",
|
|
4930
|
+
"captions",
|
|
4931
|
+
"captionsLang",
|
|
4932
|
+
"__privacyLabel",
|
|
4933
|
+
"consentCategory"
|
|
4934
|
+
],
|
|
4935
|
+
"styleTraits": [
|
|
4936
|
+
"position",
|
|
4937
|
+
"top",
|
|
4938
|
+
"right",
|
|
4939
|
+
"bottom",
|
|
4940
|
+
"left",
|
|
4941
|
+
"zIndex",
|
|
4942
|
+
"width",
|
|
4943
|
+
"height",
|
|
4944
|
+
"minWidth",
|
|
4945
|
+
"minHeight",
|
|
4946
|
+
"maxWidth",
|
|
4947
|
+
"maxHeight",
|
|
4948
|
+
"aspectRatio",
|
|
4949
|
+
"objectFit",
|
|
4950
|
+
"overflow",
|
|
4951
|
+
"margin",
|
|
4952
|
+
"padding",
|
|
4953
|
+
"borderWidth",
|
|
4954
|
+
"borderStyle",
|
|
4955
|
+
"borderColor",
|
|
4956
|
+
"borderRadius",
|
|
4957
|
+
"opacity",
|
|
4958
|
+
"mixBlendMode",
|
|
4959
|
+
"cursor",
|
|
4960
|
+
"_sep_shadow",
|
|
4961
|
+
"boxShadow",
|
|
4962
|
+
"textShadow",
|
|
4963
|
+
"_sep_transform",
|
|
4964
|
+
"translateX",
|
|
4965
|
+
"translateY",
|
|
4966
|
+
"scaleX",
|
|
4967
|
+
"scaleY",
|
|
4968
|
+
"rotate",
|
|
4969
|
+
"skewX",
|
|
4970
|
+
"skewY",
|
|
4971
|
+
"_sep_filter",
|
|
4972
|
+
"filterBlur",
|
|
4973
|
+
"filterHueRotate",
|
|
4974
|
+
"filterBrightness",
|
|
4975
|
+
"filterContrast",
|
|
4976
|
+
"filterSaturate",
|
|
4977
|
+
"filterGrayscale",
|
|
4978
|
+
"filterSepia",
|
|
4979
|
+
"filterInvert",
|
|
4980
|
+
"_sep_backdrop",
|
|
4981
|
+
"backdropFilter",
|
|
4982
|
+
"backdropBlur",
|
|
4983
|
+
"backdropBrightness",
|
|
4984
|
+
"backdropContrast",
|
|
4985
|
+
"backdropSaturate",
|
|
4986
|
+
"_sep_clip",
|
|
4987
|
+
"clipPath",
|
|
4988
|
+
"_sep_transition",
|
|
4989
|
+
"transitionDuration",
|
|
4990
|
+
"transitionDelay",
|
|
4991
|
+
"transitionTimingFunction"
|
|
4992
|
+
],
|
|
4993
|
+
"container": false
|
|
4850
4994
|
}
|
|
4851
4995
|
};
|
|
4852
4996
|
|
|
@@ -53,6 +53,12 @@ export interface PatternNode {
|
|
|
53
53
|
readonly layout?: string;
|
|
54
54
|
readonly parts?: Readonly<Record<string, boolean>>;
|
|
55
55
|
readonly binds?: Readonly<Record<string, string>>;
|
|
56
|
+
/** CC3: a Video's mode — `background` (an uploaded file, a muted loop). */
|
|
57
|
+
readonly video?: string;
|
|
58
|
+
/** CC3: a click on this node opens the pattern's lightbox at the clicked row (`lightbox`). */
|
|
59
|
+
readonly opens?: string;
|
|
60
|
+
/** CC3: a control's accessible name (`ariaLabel`). */
|
|
61
|
+
readonly name?: string;
|
|
56
62
|
}
|
|
57
63
|
|
|
58
64
|
/** The composite-core recipes a pattern may stamp (`recipe`). */
|
|
@@ -61,6 +67,10 @@ export enum PatternRecipe {
|
|
|
61
67
|
/** CC2: the Accordion — Manual (three placeholder items), or From content when the section names a list
|
|
62
68
|
* `binding` (`src: '$binding?'`): one template item bound to the type's question / answer fields. */
|
|
63
69
|
Accordion = 'accordion',
|
|
70
|
+
/** CC3: the accessible carousel — a named Slider whose controls are parts, one quote per slide (placeholders). */
|
|
71
|
+
Carousel = 'carousel',
|
|
72
|
+
/** CC3: the Lightbox — a Dialog holding a Slider over the node's `src` (the gallery's own source). */
|
|
73
|
+
Lightbox = 'lightbox',
|
|
64
74
|
}
|
|
65
75
|
|
|
66
76
|
/** A recipe node's `binds` keys → the part each binds (Card v2). */
|
|
@@ -97,6 +107,13 @@ export const SITE_PATTERNS: Readonly<Record<string, SitePattern>> = SPEC_SITE_PA
|
|
|
97
107
|
export enum PatternPlaceholder {
|
|
98
108
|
Copy = 'copy',
|
|
99
109
|
Image = 'image',
|
|
110
|
+
/** CC3: a clip the studio uploads (a Video's file): the poster blank until then, publish-blocking. */
|
|
111
|
+
Video = 'video',
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/** CC3: what an `opens` node opens. */
|
|
115
|
+
export enum PatternOpens {
|
|
116
|
+
Lightbox = 'lightbox',
|
|
100
117
|
}
|
|
101
118
|
|
|
102
119
|
/** The composer directives a pattern writes where a plan supplies the value. */
|