@vectoriox/iox-builder 4.26.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,6 +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, CONSENT_ACTION_TYPES } from '@vectoriox/iox-ui/actions-core';
24
25
  import Moveable from 'moveable';
25
26
  import Selecto from 'selecto';
26
27
  import { map, catchError } from 'rxjs/operators';
@@ -916,6 +917,9 @@ var PanelEventTypes;
916
917
  * would (`string` component type, or a block / symbol object). The builder resolves WHERE from
917
918
  * the current selection — see `resolveInsertTarget`. */
918
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";
919
923
  /** A panel wants to select a NODE it already has a reference to (e.g. the Form's nested field
920
924
  * list). Carries `{ node }`. `OverlayService.setSelect()` alone only updates the overlay's own
921
925
  * visual state — `selectedItem`/`selectedPath` (breadcrumb) and every other panel's idea of
@@ -3268,6 +3272,22 @@ class InteractionEngineService {
3268
3272
  this.executeDialogAction(action);
3269
3273
  continue;
3270
3274
  }
3275
+ // Tier-A behaviour (A1c). The canvas-is-live rules are catalog DATA
3276
+ // (ELEMENT_ACTION_DESCRIPTORS): copy runs, scrollTo runs (scrollIntoView — the frame
3277
+ // scrolls natively here; the Lenis rule is the LIVE side's), navigate and submitForm
3278
+ // SIMULATE — a dispatched event the host surfaces as a toast, never a route change
3279
+ // or a fake submit under the author's feet.
3280
+ if (BEHAVIOUR_ACTION_TYPES.has(action.type)) {
3281
+ this.executeBehaviourAction(node, action, selfEl);
3282
+ continue;
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
+ }
3271
3291
  // Context actions write STATE, not animation. `selfEl` is deliberate: $item is read by
3272
3292
  // walking up from the element actually hovered/clicked, which for a repeater PREVIEW ROW
3273
3293
  // is the clone — so each row publishes its own item, exactly as on the live site.
@@ -3317,6 +3337,37 @@ class InteractionEngineService {
3317
3337
  // MERGE, not replace — a page can hold several repeaters, each publishing its own source.
3318
3338
  this.contextData = { ...this.contextData, ...(data ?? {}) };
3319
3339
  }
3340
+ executeBehaviourAction(node, action, selfEl) {
3341
+ switch (action.type) {
3342
+ case 'copyToClipboard': {
3343
+ const text = String(action.params?.['text'] ?? '');
3344
+ if (text)
3345
+ navigator.clipboard?.writeText(text).catch(() => { });
3346
+ return;
3347
+ }
3348
+ case 'scrollTo': {
3349
+ const target = this.resolveTarget(node, action, selfEl);
3350
+ target?.scrollIntoView({ behavior: 'smooth', block: 'start' });
3351
+ return;
3352
+ }
3353
+ case 'navigate':
3354
+ case 'submitForm': {
3355
+ // Simulated: the host (the admin app) listens and shows "would …" as a toast.
3356
+ const detail = { type: action.type, params: action.params ?? {}, target: action.target };
3357
+ window.dispatchEvent(new CustomEvent('iox-action-simulated', { detail }));
3358
+ return;
3359
+ }
3360
+ }
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
+ }
3320
3371
  executeDialogAction(action) {
3321
3372
  const dialog = action.target && action.target !== 'self' ? this.instanceRegistry.get(action.target) : null;
3322
3373
  if (!dialog)
@@ -6565,11 +6616,32 @@ class BuilderComponent {
6565
6616
  this.lenis = undefined;
6566
6617
  this.lenisRafId = undefined;
6567
6618
  }
6619
+ /**
6620
+ * K5 (actions plan): actions need NAMED targets — the panel lists only labeled nodes, so an
6621
+ * unlabeled Dialog is unpickable. Every insert path labels the node "<Type>" or "<Type> N",
6622
+ * counting existing labels of that family across the whole tree.
6623
+ */
6624
+ autoLabel(config) {
6625
+ if (!config?.type || config.label)
6626
+ return;
6627
+ const base = String(config.type).replace(/([a-z])([A-Z])/g, '$1 $2');
6628
+ let count = 0;
6629
+ const walk = (nodes) => {
6630
+ for (const n of nodes ?? []) {
6631
+ if (typeof n?.label === 'string' && (n.label === base || n.label.startsWith(base + ' ')))
6632
+ count++;
6633
+ walk(n?.children);
6634
+ }
6635
+ };
6636
+ walk(this.layout);
6637
+ config.label = count === 0 ? base : `${base} ${count + 1}`;
6638
+ }
6568
6639
  addComponent(name) {
6569
6640
  const config = this.registry.createConfig(name);
6570
6641
  if (!config) {
6571
6642
  return;
6572
6643
  }
6644
+ this.autoLabel(config);
6573
6645
  this.layout.push(config);
6574
6646
  }
6575
6647
  onDrop(event) {
@@ -6579,6 +6651,7 @@ class BuilderComponent {
6579
6651
  const config = this.registry.createConfig(payload.data);
6580
6652
  if (!config)
6581
6653
  return;
6654
+ this.autoLabel(config);
6582
6655
  this.layout.splice(insertIndex, 0, config);
6583
6656
  this.cdr.markForCheck();
6584
6657
  this._selectAfterDrop(config);
@@ -7213,6 +7286,23 @@ class BuilderComponent {
7213
7286
  this.insertFromPanel(panelEvent.data);
7214
7287
  return;
7215
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
+ }
7216
7306
  // A panel (e.g. the Form's nested field list) wants to select a node it already holds a
7217
7307
  // reference to — same path onTreeNodeSelect/onCrumbSelect use, so selectedItem/selectedPath
7218
7308
  // and every panel stay in sync, not just the overlay's own visual selection box.
@@ -9866,6 +9956,120 @@ function setTrait(node, name, value) {
9866
9956
  trait.default = value;
9867
9957
  }
9868
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
+
9869
10073
  /**
9870
10074
  * Dialog (actions plan A1b) — an ordinary container whose children are normal nodes, rendered
9871
10075
  * on the live site as a real `<dialog>` (top layer, free focus trap/Esc) and in the CANVAS as a
@@ -9880,10 +10084,14 @@ class DialogComponentConfig extends ComponentConfig {
9880
10084
  this.inputs = {
9881
10085
  closeOnBackdrop: 'checkbox',
9882
10086
  showCloseButton: 'checkbox',
10087
+ consentRole: 'checkbox',
9883
10088
  };
9884
10089
  this.traits = [
9885
10090
  new TraitConfig('closeOnBackdrop', 'Close on backdrop', TraitInputType.Checkbox, undefined, true),
9886
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),
9887
10095
  ];
9888
10096
  this.styleTraits = buildFullStyleTraits();
9889
10097
  this.applyStyleDefaults({
@@ -10712,5 +10920,5 @@ class BuilderSpacerComponentConfig extends ComponentConfig {
10712
10920
  * Generated bundle index. Do not edit.
10713
10921
  */
10714
10922
 
10715
- 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 };
10716
10924
  //# sourceMappingURL=vectoriox-iox-builder.mjs.map