@vectoriox/iox-builder 4.27.0 → 4.28.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -21,7 +21,7 @@ export { ComponentInstanceRegistryService, VIRTUAL_TRAIT_KEYS, composeVirtualTra
|
|
|
21
21
|
import Lenis from 'lenis';
|
|
22
22
|
import { Subject, BehaviorSubject, of, forkJoin } from 'rxjs';
|
|
23
23
|
import interact from 'interactjs';
|
|
24
|
-
import { BEHAVIOUR_ACTION_TYPES } from '@vectoriox/iox-ui/actions-core';
|
|
24
|
+
import { BEHAVIOUR_ACTION_TYPES, CONSENT_ACTION_TYPES } from '@vectoriox/iox-ui/actions-core';
|
|
25
25
|
import Moveable from 'moveable';
|
|
26
26
|
import Selecto from 'selecto';
|
|
27
27
|
import { map, catchError } from 'rxjs/operators';
|
|
@@ -917,6 +917,9 @@ var PanelEventTypes;
|
|
|
917
917
|
* would (`string` component type, or a block / symbol object). The builder resolves WHERE from
|
|
918
918
|
* the current selection — see `resolveInsertTarget`. */
|
|
919
919
|
PanelEventTypes["INSERT_COMPONENT"] = "insertcomponent";
|
|
920
|
+
/** Insert prebuilt node(s) as GLOBAL elements (data = ComponentNode[]) — the consent preset's
|
|
921
|
+
* path (D-C5: site-wide by construction). Mirrors the MakeGlobal toolbar action. */
|
|
922
|
+
PanelEventTypes["INSERT_GLOBAL"] = "insertglobal";
|
|
920
923
|
/** A panel wants to select a NODE it already has a reference to (e.g. the Form's nested field
|
|
921
924
|
* list). Carries `{ node }`. `OverlayService.setSelect()` alone only updates the overlay's own
|
|
922
925
|
* visual state — `selectedItem`/`selectedPath` (breadcrumb) and every other panel's idea of
|
|
@@ -3278,6 +3281,13 @@ class InteractionEngineService {
|
|
|
3278
3281
|
this.executeBehaviourAction(node, action, selfEl);
|
|
3279
3282
|
continue;
|
|
3280
3283
|
}
|
|
3284
|
+
// Consent actions (C3). Recording ones SIMULATE — the canvas is the ADMIN's browser,
|
|
3285
|
+
// and an admin's cookie is not a visitor's decision; the toast says what would be
|
|
3286
|
+
// recorded. Opening the preferences dialog is dialog-opening and honestly RUNS.
|
|
3287
|
+
if (CONSENT_ACTION_TYPES.has(action.type)) {
|
|
3288
|
+
this.executeConsentAction(action);
|
|
3289
|
+
continue;
|
|
3290
|
+
}
|
|
3281
3291
|
// Context actions write STATE, not animation. `selfEl` is deliberate: $item is read by
|
|
3282
3292
|
// walking up from the element actually hovered/clicked, which for a repeater PREVIEW ROW
|
|
3283
3293
|
// is the clone — so each row publishes its own item, exactly as on the live site.
|
|
@@ -3349,6 +3359,15 @@ class InteractionEngineService {
|
|
|
3349
3359
|
}
|
|
3350
3360
|
}
|
|
3351
3361
|
}
|
|
3362
|
+
executeConsentAction(action) {
|
|
3363
|
+
if (action.type === 'openConsentPreferences') {
|
|
3364
|
+
const dialog = action.target && action.target !== 'self' ? this.instanceRegistry.get(action.target) : null;
|
|
3365
|
+
dialog?.open?.();
|
|
3366
|
+
return;
|
|
3367
|
+
}
|
|
3368
|
+
const detail = { type: action.type, params: action.params ?? {}, target: action.target };
|
|
3369
|
+
window.dispatchEvent(new CustomEvent('iox-action-simulated', { detail }));
|
|
3370
|
+
}
|
|
3352
3371
|
executeDialogAction(action) {
|
|
3353
3372
|
const dialog = action.target && action.target !== 'self' ? this.instanceRegistry.get(action.target) : null;
|
|
3354
3373
|
if (!dialog)
|
|
@@ -7267,6 +7286,23 @@ class BuilderComponent {
|
|
|
7267
7286
|
this.insertFromPanel(panelEvent.data);
|
|
7268
7287
|
return;
|
|
7269
7288
|
}
|
|
7289
|
+
// Prebuilt roots straight into the GLOBAL elements (the consent preset, D-C5) — the same
|
|
7290
|
+
// moves as the MakeGlobal toolbar action, minus the remove-from-layout step.
|
|
7291
|
+
if (panelEvent.type === PanelEventTypes.INSERT_GLOBAL) {
|
|
7292
|
+
const nodes = (Array.isArray(panelEvent.data) ? panelEvent.data : [panelEvent.data]);
|
|
7293
|
+
for (const node of nodes) {
|
|
7294
|
+
if (!node)
|
|
7295
|
+
continue;
|
|
7296
|
+
this.autoLabel(node);
|
|
7297
|
+
node.isGlobal = true;
|
|
7298
|
+
node.globalPosition = node.globalPosition ?? 'after';
|
|
7299
|
+
this.globalElements.push(node);
|
|
7300
|
+
}
|
|
7301
|
+
this.globalElementsChange.emit([...this.globalElements]);
|
|
7302
|
+
this.cdr.markForCheck();
|
|
7303
|
+
this.panelEventService.emit(PanelEventTypes.LAYOUT_CHANGED, this.layout);
|
|
7304
|
+
return;
|
|
7305
|
+
}
|
|
7270
7306
|
// A panel (e.g. the Form's nested field list) wants to select a node it already holds a
|
|
7271
7307
|
// reference to — same path onTreeNodeSelect/onCrumbSelect use, so selectedItem/selectedPath
|
|
7272
7308
|
// and every panel stay in sync, not just the overlay's own visual selection box.
|
|
@@ -9920,6 +9956,120 @@ function setTrait(node, name, value) {
|
|
|
9920
9956
|
trait.default = value;
|
|
9921
9957
|
}
|
|
9922
9958
|
|
|
9959
|
+
/**
|
|
9960
|
+
* THE CONSENT PRESET (consent plan C3) — the banner as builder elements, which is the whole bet:
|
|
9961
|
+
* Wix ships a banner you cannot design, Webflow ships a design system and no banner; ours is a
|
|
9962
|
+
* Dialog made of ordinary nodes, so it arrives flavored, stylable, translatable and RTL-correct
|
|
9963
|
+
* like everything else on the canvas.
|
|
9964
|
+
*
|
|
9965
|
+
* Three roots, inserted as GLOBAL elements (D-C5 — site-wide by construction):
|
|
9966
|
+
* 1. the banner Dialog (`consentRole` — the live runtime opens it when `needsPrompt` says so),
|
|
9967
|
+
* 2. the preferences Dialog (per-category Allow/Refuse, recorded immediately — state-free),
|
|
9968
|
+
* 3. a small "Cookie settings" element — the withdrawal path (§7.3), free once actions exist.
|
|
9969
|
+
*
|
|
9970
|
+
* Design rules carried in the tree (§7): Accept and Reject are the SAME component with the same
|
|
9971
|
+
* defaults on the same row — reject is as easy as accept; the three categories are named on the
|
|
9972
|
+
* first layer; `closeOnBackdrop` is OFF — clicking away is not consent; the X stays, because the
|
|
9973
|
+
* live runtime records a close-without-decision as a "no".
|
|
9974
|
+
*
|
|
9975
|
+
* The TEXTS are the customer's (D-C7). These strings are neutral mechanism-microcopy seeded for
|
|
9976
|
+
* editing — never policy language, which we do not write (§8).
|
|
9977
|
+
*/
|
|
9978
|
+
const click = (actions) => ({
|
|
9979
|
+
id: generateNodeId(),
|
|
9980
|
+
trigger: 'click',
|
|
9981
|
+
actions: actions.map(a => ({
|
|
9982
|
+
target: 'self', duration: 0, delay: 0, easing: 'ease', ...a,
|
|
9983
|
+
})),
|
|
9984
|
+
});
|
|
9985
|
+
function button(label, createConfig, interaction) {
|
|
9986
|
+
const btn = createConfig('ButtonBlock');
|
|
9987
|
+
const text = textNode(label, createConfig);
|
|
9988
|
+
if (!btn || !text)
|
|
9989
|
+
return null;
|
|
9990
|
+
setTrait(btn, 'tag', 'button');
|
|
9991
|
+
btn.children = [text];
|
|
9992
|
+
btn.interactions = [interaction];
|
|
9993
|
+
return btn;
|
|
9994
|
+
}
|
|
9995
|
+
function row(createConfig, styles, children) {
|
|
9996
|
+
const container = createConfig('Container');
|
|
9997
|
+
if (!container || children.some(c => !c))
|
|
9998
|
+
return null;
|
|
9999
|
+
for (const [prop, value] of Object.entries(styles))
|
|
10000
|
+
setStyleTrait(container, prop, value);
|
|
10001
|
+
container.children = children;
|
|
10002
|
+
return container;
|
|
10003
|
+
}
|
|
10004
|
+
/** Build the three roots. Null when any type is missing — a half-built banner never ships. */
|
|
10005
|
+
function buildConsentPreset(createConfig) {
|
|
10006
|
+
const banner = createConfig('Dialog');
|
|
10007
|
+
const preferences = createConfig('Dialog');
|
|
10008
|
+
if (!banner || !preferences)
|
|
10009
|
+
return null;
|
|
10010
|
+
// ── the banner ────────────────────────────────────────────────────────────
|
|
10011
|
+
banner.label = 'Consent banner';
|
|
10012
|
+
setTrait(banner, 'consentRole', true);
|
|
10013
|
+
setTrait(banner, 'closeOnBackdrop', false); // clicking away is NOT consent
|
|
10014
|
+
setTrait(banner, 'showCloseButton', true); // the runtime records X as a "no"
|
|
10015
|
+
setStyleTrait(banner, 'width', 'min(560px, calc(100vw - 32px))');
|
|
10016
|
+
setStyleTrait(banner, 'margin', 'auto auto 24px auto'); // bottom-of-viewport placement, restylable
|
|
10017
|
+
const heading = textNode('Privacy choices', createConfig);
|
|
10018
|
+
if (heading)
|
|
10019
|
+
setStyleTrait(heading, 'fontWeight', '600');
|
|
10020
|
+
const body = textNode('We use cookies to understand how this site is used. You choose what we may use, and you can change your mind at any time.', createConfig);
|
|
10021
|
+
const categoriesLine = textNode('Necessary — always on · Analytics · Marketing', createConfig);
|
|
10022
|
+
const accept = button('Accept all', createConfig, click([
|
|
10023
|
+
{ type: 'grantConsent' },
|
|
10024
|
+
{ type: 'closeDialog', target: banner.id },
|
|
10025
|
+
]));
|
|
10026
|
+
const reject = button('Reject all', createConfig, click([
|
|
10027
|
+
{ type: 'denyConsent' },
|
|
10028
|
+
{ type: 'closeDialog', target: banner.id },
|
|
10029
|
+
]));
|
|
10030
|
+
const prefs = button('Preferences', createConfig, click([
|
|
10031
|
+
{ type: 'openConsentPreferences', target: preferences.id },
|
|
10032
|
+
]));
|
|
10033
|
+
const buttonsRow = row(createConfig, { display: 'flex', gap: '12px', flexWrap: 'wrap', alignItems: 'center' }, [accept, reject, prefs]);
|
|
10034
|
+
if (!heading || !body || !categoriesLine || !buttonsRow)
|
|
10035
|
+
return null;
|
|
10036
|
+
banner.children = [heading, body, categoriesLine, buttonsRow];
|
|
10037
|
+
// ── the preferences modal ────────────────────────────────────────────────
|
|
10038
|
+
preferences.label = 'Consent preferences';
|
|
10039
|
+
setTrait(preferences, 'closeOnBackdrop', true);
|
|
10040
|
+
setTrait(preferences, 'showCloseButton', true);
|
|
10041
|
+
const prefsHeading = textNode('Your privacy choices', createConfig);
|
|
10042
|
+
if (prefsHeading)
|
|
10043
|
+
setStyleTrait(prefsHeading, 'fontWeight', '600');
|
|
10044
|
+
const categoryRow = (category, name) => {
|
|
10045
|
+
const allow = button('Allow', createConfig, click([
|
|
10046
|
+
{ type: 'setConsentCategory', params: { category, granted: true } },
|
|
10047
|
+
]));
|
|
10048
|
+
const refuse = button('Refuse', createConfig, click([
|
|
10049
|
+
{ type: 'setConsentCategory', params: { category, granted: false } },
|
|
10050
|
+
]));
|
|
10051
|
+
const pair = row(createConfig, { display: 'flex', gap: '8px' }, [allow, refuse]);
|
|
10052
|
+
return row(createConfig, { display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: '12px', flexWrap: 'wrap' }, [textNode(name, createConfig), pair]);
|
|
10053
|
+
};
|
|
10054
|
+
const necessaryLine = textNode('Necessary — always on', createConfig);
|
|
10055
|
+
const analyticsRow = categoryRow('analytics', 'Analytics');
|
|
10056
|
+
const marketingRow = categoryRow('marketing', 'Marketing');
|
|
10057
|
+
const done = button('Done', createConfig, click([
|
|
10058
|
+
{ type: 'closeDialog', target: preferences.id },
|
|
10059
|
+
]));
|
|
10060
|
+
if (!prefsHeading || !necessaryLine || !analyticsRow || !marketingRow || !done)
|
|
10061
|
+
return null;
|
|
10062
|
+
preferences.children = [prefsHeading, necessaryLine, analyticsRow, marketingRow, done];
|
|
10063
|
+
// ── the withdrawal path (§7.3) ───────────────────────────────────────────
|
|
10064
|
+
const withdrawal = button('Cookie settings', createConfig, click([
|
|
10065
|
+
{ type: 'openConsentPreferences', target: preferences.id },
|
|
10066
|
+
]));
|
|
10067
|
+
if (!withdrawal)
|
|
10068
|
+
return null;
|
|
10069
|
+
withdrawal.label = 'Cookie settings';
|
|
10070
|
+
return { banner, preferences, withdrawal };
|
|
10071
|
+
}
|
|
10072
|
+
|
|
9923
10073
|
/**
|
|
9924
10074
|
* Dialog (actions plan A1b) — an ordinary container whose children are normal nodes, rendered
|
|
9925
10075
|
* on the live site as a real `<dialog>` (top layer, free focus trap/Esc) and in the CANVAS as a
|
|
@@ -9934,10 +10084,14 @@ class DialogComponentConfig extends ComponentConfig {
|
|
|
9934
10084
|
this.inputs = {
|
|
9935
10085
|
closeOnBackdrop: 'checkbox',
|
|
9936
10086
|
showCloseButton: 'checkbox',
|
|
10087
|
+
consentRole: 'checkbox',
|
|
9937
10088
|
};
|
|
9938
10089
|
this.traits = [
|
|
9939
10090
|
new TraitConfig('closeOnBackdrop', 'Close on backdrop', TraitInputType.Checkbox, undefined, true),
|
|
9940
10091
|
new TraitConfig('showCloseButton', 'Close button', TraitInputType.Checkbox, undefined, true),
|
|
10092
|
+
// C3: the live runtime opens THIS dialog when consent is owed (needsPrompt), and a
|
|
10093
|
+
// close without a decision records a "no". The canvas never auto-opens anything.
|
|
10094
|
+
new TraitConfig('consentRole', 'Consent banner role', TraitInputType.Checkbox, undefined, false),
|
|
9941
10095
|
];
|
|
9942
10096
|
this.styleTraits = buildFullStyleTraits();
|
|
9943
10097
|
this.applyStyleDefaults({
|
|
@@ -10766,5 +10920,5 @@ class BuilderSpacerComponentConfig extends ComponentConfig {
|
|
|
10766
10920
|
* Generated bundle index. Do not edit.
|
|
10767
10921
|
*/
|
|
10768
10922
|
|
|
10769
|
-
export { ACTION_TYPE_OPTIONS, AuditCode, AuditPanelComponent, AuditSeverity, BODY_CRUMB_LABEL, BREAKPOINT_PRESENTATION, BUILDER_CANVAS_CONTAINER, BUILDER_CHROME_EN, BackgroundGroupStyleConfig, BorderGroupStyleConfig, BreadcrumbBarComponent, BuilderButtonBlockComponent, BuilderButtonComponentConfig, BuilderClipboardService, BuilderComponent, BuilderContainerComponent, BuilderContainerComponentConfig, BuilderDataSourceService, BuilderDialogComponent, BuilderDividerComponentConfig, BuilderHeadingComponentConfig, BuilderHistoryService, BuilderIconComponentConfig, BuilderImageComponentConfig, BuilderLinkComponentConfig, BuilderLinkedContainerComponent, BuilderLinkedContainerConfig, BuilderListComponentConfig, BuilderListItemComponentConfig, BuilderMode, BuilderRepeaterComponent, BuilderSpacerComponentConfig, ButtonBlockComponentConfig, CardComponentConfig, ChildLayoutGroupStyleConfig, ComponentConfig, ComponentRegistryService, DEFAULT_ESSENTIAL_TRAITS, DRAG_HANDLE_ATTR, DataSourceRegistryService, DataSourceType, DialogComponentConfig, DimensionsGroupStyleConfig, DragEngineService, EASING_OPTIONS$1 as EASING_OPTIONS, ESSENTIAL_TRAITS_BY_TYPE, EffectsGroupStyleConfig, FIELD_PARTS, FORM_PRESETS, FORM_TYPE, FieldComponentConfig, FieldGroupComponentConfig, FormComponentConfig, FormErrorComponentConfig, FormStateService, FormSuccessComponentConfig, GalleryConfig, GroupStyleConfig, INTERACTION_STATES, INVERSE_ACTION, IOX_BUILDER_LABELS, IOX_DATA_SOURCE_ENDPOINTS, IOX_FONT_MANAGER, InteractionEngineService, InteractionPresetRegistryService, IoxBuilderModule, IoxDraggableDirective, IoxDropzoneDirective, LAYOUT_PRESETS, LayerTreeComponent, LayoutGroupStyleConfig, ListGroupStyleConfig, NodeAction, OverlayComponent, OverlayService, PanelChildComponent, PanelComponent, PanelEventService, PanelEventTypes, PanelTypes, PositionGroupStyleConfig, PresetRegistryService, RELATIONAL_STATES, RELATIONAL_STATE_BASE, ROUTE_ANIMATION_OPTIONS, RenderDirective, RepeaterComponentConfig, SCREEN_WIDTH_OPTIONS, STRUCTURAL_STATES, SUPPORTED_STATES, SectionComponent, SectionComponentConfig, SizeGroupStyleConfig, SliderContainerComponent, SliderContainerConfig, SliderSlideComponent, SliderSlideConfig, SpacingGroupStyleConfig, StyleCategory, StyleRegistryService, TraitConfig as StyleTraitConfig, SubmitButtonComponentConfig, SymbolRegistryService, TARGETED_STATES, TARGETED_STATE_BASE, TRIGGER_OPTIONS, TextBlockComponentConfig, ToolbarAction, ToolbarComponent, TraitConfig, TraitInputType, TypographyGroupStyleConfig, UNITS_ALL, UNITS_DEG, UNITS_FIXED, UNITS_NO_VW, VALIDATION_STATES, VALIDATION_STATE_CLASS, ViewportService, ZOOM_OPTIONS, arrayItemSchemaFields, arraySchemaFields, auditNodes, buildFormPreset, buildFullStyleTraits, buildLayoutPreset, buildPresetStyleTraits, canFluidise, collapseColumnsProps, columnCountOf, defaultBuilderLabels, defaultPageSettings, dropTargetLabel, essentialTraitsFor, findNodeLocation, findParentOf, flattenSchemaFields, fluidiseProps, generateNodeId, isHiddenAt, matchesControlSearch, nearestFormNode, nodeAncestorPath, nodeAncestorPathInEither, reorderProps, resolveInsertTarget, resolveTraitControllerType, resolveTraitOptions, setStyleTrait, stackChildrenProps, summarise, visibilityProps, wrapNode };
|
|
10923
|
+
export { ACTION_TYPE_OPTIONS, AuditCode, AuditPanelComponent, AuditSeverity, BODY_CRUMB_LABEL, BREAKPOINT_PRESENTATION, BUILDER_CANVAS_CONTAINER, BUILDER_CHROME_EN, BackgroundGroupStyleConfig, BorderGroupStyleConfig, BreadcrumbBarComponent, BuilderButtonBlockComponent, BuilderButtonComponentConfig, BuilderClipboardService, BuilderComponent, BuilderContainerComponent, BuilderContainerComponentConfig, BuilderDataSourceService, BuilderDialogComponent, BuilderDividerComponentConfig, BuilderHeadingComponentConfig, BuilderHistoryService, BuilderIconComponentConfig, BuilderImageComponentConfig, BuilderLinkComponentConfig, BuilderLinkedContainerComponent, BuilderLinkedContainerConfig, BuilderListComponentConfig, BuilderListItemComponentConfig, BuilderMode, BuilderRepeaterComponent, BuilderSpacerComponentConfig, ButtonBlockComponentConfig, CardComponentConfig, ChildLayoutGroupStyleConfig, ComponentConfig, ComponentRegistryService, DEFAULT_ESSENTIAL_TRAITS, DRAG_HANDLE_ATTR, DataSourceRegistryService, DataSourceType, DialogComponentConfig, DimensionsGroupStyleConfig, DragEngineService, EASING_OPTIONS$1 as EASING_OPTIONS, ESSENTIAL_TRAITS_BY_TYPE, EffectsGroupStyleConfig, FIELD_PARTS, FORM_PRESETS, FORM_TYPE, FieldComponentConfig, FieldGroupComponentConfig, FormComponentConfig, FormErrorComponentConfig, FormStateService, FormSuccessComponentConfig, GalleryConfig, GroupStyleConfig, INTERACTION_STATES, INVERSE_ACTION, IOX_BUILDER_LABELS, IOX_DATA_SOURCE_ENDPOINTS, IOX_FONT_MANAGER, InteractionEngineService, InteractionPresetRegistryService, IoxBuilderModule, IoxDraggableDirective, IoxDropzoneDirective, LAYOUT_PRESETS, LayerTreeComponent, LayoutGroupStyleConfig, ListGroupStyleConfig, NodeAction, OverlayComponent, OverlayService, PanelChildComponent, PanelComponent, PanelEventService, PanelEventTypes, PanelTypes, PositionGroupStyleConfig, PresetRegistryService, RELATIONAL_STATES, RELATIONAL_STATE_BASE, ROUTE_ANIMATION_OPTIONS, RenderDirective, RepeaterComponentConfig, SCREEN_WIDTH_OPTIONS, STRUCTURAL_STATES, SUPPORTED_STATES, SectionComponent, SectionComponentConfig, SizeGroupStyleConfig, SliderContainerComponent, SliderContainerConfig, SliderSlideComponent, SliderSlideConfig, SpacingGroupStyleConfig, StyleCategory, StyleRegistryService, TraitConfig as StyleTraitConfig, SubmitButtonComponentConfig, SymbolRegistryService, TARGETED_STATES, TARGETED_STATE_BASE, TRIGGER_OPTIONS, TextBlockComponentConfig, ToolbarAction, ToolbarComponent, TraitConfig, TraitInputType, TypographyGroupStyleConfig, UNITS_ALL, UNITS_DEG, UNITS_FIXED, UNITS_NO_VW, VALIDATION_STATES, VALIDATION_STATE_CLASS, ViewportService, ZOOM_OPTIONS, arrayItemSchemaFields, arraySchemaFields, auditNodes, buildConsentPreset, buildFormPreset, buildFullStyleTraits, buildLayoutPreset, buildPresetStyleTraits, canFluidise, collapseColumnsProps, columnCountOf, defaultBuilderLabels, defaultPageSettings, dropTargetLabel, essentialTraitsFor, findNodeLocation, findParentOf, flattenSchemaFields, fluidiseProps, generateNodeId, isHiddenAt, matchesControlSearch, nearestFormNode, nodeAncestorPath, nodeAncestorPathInEither, reorderProps, resolveInsertTarget, resolveTraitControllerType, resolveTraitOptions, setStyleTrait, setTrait, stackChildrenProps, summarise, textNode, visibilityProps, wrapNode };
|
|
10770
10924
|
//# sourceMappingURL=vectoriox-iox-builder.mjs.map
|