@vectoriox/iox-ui 5.29.1 → 5.31.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.
Files changed (35) hide show
  1. package/composite-core/index.d.ts +270 -0
  2. package/composite-core/package.json +3 -0
  3. package/design-core/index.d.ts +870 -41
  4. package/fesm2022/vectoriox-iox-ui-composite-core.mjs +698 -0
  5. package/fesm2022/vectoriox-iox-ui-composite-core.mjs.map +1 -0
  6. package/fesm2022/vectoriox-iox-ui-design-core.mjs +1090 -82
  7. package/fesm2022/vectoriox-iox-ui-design-core.mjs.map +1 -1
  8. package/fesm2022/vectoriox-iox-ui-forms-core.mjs +74 -1
  9. package/fesm2022/vectoriox-iox-ui-forms-core.mjs.map +1 -1
  10. package/fesm2022/vectoriox-iox-ui-generation-core.mjs +110 -30
  11. package/fesm2022/vectoriox-iox-ui-generation-core.mjs.map +1 -1
  12. package/fesm2022/vectoriox-iox-ui.mjs +210 -31
  13. package/fesm2022/vectoriox-iox-ui.mjs.map +1 -1
  14. package/forms-core/index.d.ts +45 -2
  15. package/generation-core/index.d.ts +35 -23
  16. package/index.d.ts +42 -15
  17. package/package.json +5 -1
  18. package/src/composite-core/badge.ts +103 -0
  19. package/src/composite-core/card.ts +524 -0
  20. package/src/composite-core/composite-node.ts +143 -0
  21. package/src/composite-core/public-api.ts +11 -0
  22. package/src/composite-core/structure.ts +58 -0
  23. package/src/design-core/contrast-audit.ts +38 -5
  24. package/src/design-core/flavor-fixtures.generated.ts +144 -144
  25. package/src/design-core/flavor-spec.generated.ts +970 -26
  26. package/src/design-core/node-classes.ts +16 -4
  27. package/src/design-core/node-links.ts +29 -0
  28. package/src/forms-core/nesting.ts +92 -0
  29. package/src/forms-core/public-api.ts +1 -0
  30. package/src/generation-core/compose-site.ts +55 -1
  31. package/src/generation-core/node-baselines.generated.ts +14 -2
  32. package/src/generation-core/patterns.ts +29 -2
  33. package/src/generation-core/serialized-node.ts +2 -0
  34. package/src/generation-core/site-spec.generated.ts +13 -26
  35. package/styles/iox-design.css +62 -0
@@ -899,22 +899,97 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.31", ngImpo
899
899
  type: Input
900
900
  }] } });
901
901
 
902
+ /**
903
+ * Where a node links (W1.1). Link and LinkedContainer always had two link types — an external URL or a
904
+ * website PAGE by its route — and ButtonBlock now has the same pair, so a composed "Get in touch" button
905
+ * is a page link the builder shows as `/contact`, not a hand-built URL. Framework-free: the composer
906
+ * (generation-core) writes it, the builder canvas and both engine render paths read it.
907
+ */
908
+ var LinkType;
909
+ (function (LinkType) {
910
+ /** Links nowhere — a Heading's default; "Link the whole card" (Card v2) turns its title's link on. */
911
+ LinkType["None"] = "none";
912
+ LinkType["External"] = "external";
913
+ LinkType["Page"] = "page";
914
+ })(LinkType || (LinkType = {}));
915
+ const ANCHOR_TAG = 'a';
916
+ /**
917
+ * The href a ButtonBlock renders, or `null` for none (it is a `<button>`, or a link with no target).
918
+ * Only an `<a>` links. A page link's route goes through `pageHref` — the engine's `resolvePageHref`
919
+ * (`:params` substituted, base-relative); the builder canvas passes none and shows the route as authored,
920
+ * as its Link does.
921
+ */
922
+ function buttonBlockHref(props, pageHref = route => route) {
923
+ if (props.tag !== ANCHOR_TAG)
924
+ return null;
925
+ const href = props.linkType === LinkType.Page ? pageHref(String(props.pageRoute ?? '')) : String(props.href ?? '');
926
+ return href || null;
927
+ }
928
+ /** The class of the `<a>` a linked Heading renders — the Card v2 stretched link keys on it (iox-design.css:
929
+ * the card is the click target, its buttons sit above, the focus ring is drawn on the card). */
930
+ const CARD_LINK_CLASS = 'iox-card-link';
931
+ /** On the editing canvas the anchor carries this, so the stretched `::after` is off and every part of the
932
+ * card stays clickable (board 8). */
933
+ const CANVAS_LINK_ATTRIBUTE = 'data-iox-canvas';
934
+ /**
935
+ * The href a linked Heading renders (Card v2: the card's title IS its link), or `null` when it links
936
+ * nowhere — `none`, or a link with no target yet (the title then renders as plain words). A page link goes
937
+ * through `pageHref` exactly as a ButtonBlock's does.
938
+ */
939
+ function headingHref(props, pageHref = route => route) {
940
+ if (props.linkType === LinkType.Page) {
941
+ const route = String(props.pageRoute ?? '');
942
+ return route ? pageHref(route) || null : null;
943
+ }
944
+ if (props.linkType === LinkType.External)
945
+ return String(props.url ?? '').trim() || null;
946
+ return null;
947
+ }
948
+
902
949
  /**
903
950
  * Directive-host Heading: the real `<h1>`…`<h6>` IS the host — no `app-builder-heading`
904
951
  * wrapper, no inner/outer split. The tag is chosen by whoever CREATES the component
905
952
  * (engine: `createComponent({ hostElement: document.createElement(level) })`; builder:
906
953
  * RenderDirective does the same), NOT by an internal ngSwitch. `level` is kept as an input
907
954
  * for that creation logic + serialization. Editing (contenteditable) runs in the builder only.
955
+ *
956
+ * A Heading may LINK (Card v2, "Link the whole card"): its words then render inside ONE `<a>` — the
957
+ * card's title is its link, so the link's name is the title. The shared CSS stretches it over the card
958
+ * (iox-design.css). On the editing canvas the anchor never navigates and carries `data-iox-canvas`, so
959
+ * the stretch is off and every part of the card stays clickable; a click still selects the heading.
908
960
  */
909
961
  class BuilderHeadingComponent {
910
- constructor(events, cdr) {
962
+ constructor(events, cdr, isPreview) {
911
963
  this.events = events;
912
964
  this.cdr = cdr;
965
+ this.isPreview = isPreview;
913
966
  this.content = 'Heading';
914
967
  this.level = 'h2';
915
968
  this.nodeId = '';
916
969
  this.node = null;
970
+ this.linkType = LinkType.None;
971
+ this.url = '';
972
+ this.pageRoute = '';
973
+ this.target = '_self';
917
974
  this.editing = false;
975
+ this.linkClass = CARD_LINK_CLASS;
976
+ }
977
+ /** Where the heading links, or null (plain words). The engine hands `pageRoute` in already resolved;
978
+ * the canvas shows the route as authored, as its Link does. */
979
+ get href() {
980
+ return headingHref({ linkType: this.linkType, url: this.url, pageRoute: this.pageRoute });
981
+ }
982
+ get linkTarget() {
983
+ return this.target && this.target !== '_self' ? this.target : null;
984
+ }
985
+ get linkRel() {
986
+ return this.target === '_blank' ? 'noopener' : null;
987
+ }
988
+ /** On the editing canvas a link never navigates (plain, modified and middle clicks); the click still
989
+ * bubbles to the heading, which is what selects it. */
990
+ onLinkClick(event) {
991
+ if (!this.isPreview)
992
+ event.preventDefault();
918
993
  }
919
994
  ngOnInit() { }
920
995
  onMouseDown(event) {
@@ -966,12 +1041,14 @@ class BuilderHeadingComponent {
966
1041
  }
967
1042
  this.events.emit('elementselect', { node: this.node, componentRef: null, isCanvasUpdate: true });
968
1043
  }
969
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.31", ngImport: i0, type: BuilderHeadingComponent, deps: [{ token: IOX_BUILDER_EVENTS, optional: true }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
970
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.31", type: BuilderHeadingComponent, isStandalone: false, selector: "h1[iox-heading],h2[iox-heading],h3[iox-heading],h4[iox-heading],h5[iox-heading],h6[iox-heading]", inputs: { content: "content", level: "level", nodeId: "nodeId", node: "node" }, host: { listeners: { "mousedown": "onMouseDown($event)", "dblclick": "startEdit($event)", "blur": "commitEdit($event)", "keydown": "onKeyDown($event)" }, properties: { "class": "'iox-node-' + nodeId", "attr.contenteditable": "editing ? 'true' : null" } }, ngImport: i0, template: `{{ content }}`, isInline: true, styles: [":host{margin:0}:host[contenteditable]{outline:none;cursor:text}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1044
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.31", ngImport: i0, type: BuilderHeadingComponent, deps: [{ token: IOX_BUILDER_EVENTS, optional: true }, { token: i0.ChangeDetectorRef }, { token: IS_PREVIEW, optional: true }], target: i0.ɵɵFactoryTarget.Component }); }
1045
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.31", type: BuilderHeadingComponent, isStandalone: false, selector: "h1[iox-heading],h2[iox-heading],h3[iox-heading],h4[iox-heading],h5[iox-heading],h6[iox-heading]", inputs: { content: "content", level: "level", nodeId: "nodeId", node: "node", linkType: "linkType", url: "url", pageRoute: "pageRoute", target: "target" }, host: { listeners: { "mousedown": "onMouseDown($event)", "dblclick": "startEdit($event)", "blur": "commitEdit($event)", "keydown": "onKeyDown($event)" }, properties: { "class": "'iox-node-' + nodeId", "attr.contenteditable": "editing ? 'true' : null" } }, ngImport: i0, template: `@if (href) {<a [class]="linkClass" [attr.href]="href" [attr.target]="linkTarget" [attr.rel]="linkRel"
1046
+ [attr.data-iox-canvas]="isPreview ? null : ''" (click)="onLinkClick($event)" (auxclick)="onLinkClick($event)">{{ content }}</a>} @else {<ng-container>{{ content }}</ng-container>}`, isInline: true, styles: [":host{margin:0}:host[contenteditable]{outline:none;cursor:text}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
971
1047
  }
972
1048
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.31", ngImport: i0, type: BuilderHeadingComponent, decorators: [{
973
1049
  type: Component,
974
- args: [{ selector: 'h1[iox-heading],h2[iox-heading],h3[iox-heading],h4[iox-heading],h5[iox-heading],h6[iox-heading]', template: `{{ content }}`, host: {
1050
+ args: [{ selector: 'h1[iox-heading],h2[iox-heading],h3[iox-heading],h4[iox-heading],h5[iox-heading],h6[iox-heading]', template: `@if (href) {<a [class]="linkClass" [attr.href]="href" [attr.target]="linkTarget" [attr.rel]="linkRel"
1051
+ [attr.data-iox-canvas]="isPreview ? null : ''" (click)="onLinkClick($event)" (auxclick)="onLinkClick($event)">{{ content }}</a>} @else {<ng-container>{{ content }}</ng-container>}`, host: {
975
1052
  '[class]': "'iox-node-' + nodeId",
976
1053
  '[attr.contenteditable]': "editing ? 'true' : null",
977
1054
  '(mousedown)': 'onMouseDown($event)',
@@ -984,7 +1061,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.31", ngImpo
984
1061
  }, {
985
1062
  type: Inject,
986
1063
  args: [IOX_BUILDER_EVENTS]
987
- }] }, { type: i0.ChangeDetectorRef }], propDecorators: { content: [{
1064
+ }] }, { type: i0.ChangeDetectorRef }, { type: undefined, decorators: [{
1065
+ type: Optional
1066
+ }, {
1067
+ type: Inject,
1068
+ args: [IS_PREVIEW]
1069
+ }] }], propDecorators: { content: [{
988
1070
  type: Input
989
1071
  }], level: [{
990
1072
  type: Input
@@ -992,6 +1074,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.31", ngImpo
992
1074
  type: Input
993
1075
  }], node: [{
994
1076
  type: Input
1077
+ }], linkType: [{
1078
+ type: Input
1079
+ }], url: [{
1080
+ type: Input
1081
+ }], pageRoute: [{
1082
+ type: Input
1083
+ }], target: [{
1084
+ type: Input
995
1085
  }] } });
996
1086
 
997
1087
  /**
@@ -1245,31 +1335,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.31", ngImpo
1245
1335
  args: ['childrenHost', { read: ViewContainerRef, static: true }]
1246
1336
  }] } });
1247
1337
 
1248
- /**
1249
- * Where a node links (W1.1). Link and LinkedContainer always had two link types — an external URL or a
1250
- * website PAGE by its route — and ButtonBlock now has the same pair, so a composed "Get in touch" button
1251
- * is a page link the builder shows as `/contact`, not a hand-built URL. Framework-free: the composer
1252
- * (generation-core) writes it, the builder canvas and both engine render paths read it.
1253
- */
1254
- var LinkType;
1255
- (function (LinkType) {
1256
- LinkType["External"] = "external";
1257
- LinkType["Page"] = "page";
1258
- })(LinkType || (LinkType = {}));
1259
- const ANCHOR_TAG = 'a';
1260
- /**
1261
- * The href a ButtonBlock renders, or `null` for none (it is a `<button>`, or a link with no target).
1262
- * Only an `<a>` links. A page link's route goes through `pageHref` — the engine's `resolvePageHref`
1263
- * (`:params` substituted, base-relative); the builder canvas passes none and shows the route as authored,
1264
- * as its Link does.
1265
- */
1266
- function buttonBlockHref(props, pageHref = route => route) {
1267
- if (props.tag !== ANCHOR_TAG)
1268
- return null;
1269
- const href = props.linkType === LinkType.Page ? pageHref(String(props.pageRoute ?? '')) : String(props.href ?? '');
1270
- return href || null;
1271
- }
1272
-
1273
1338
  /**
1274
1339
  * Directive-host ButtonBlock: the real `<a>`/`<button>` IS the host — no `app-button-block`
1275
1340
  * wrapper, no inner/outer split. The tag is chosen by whoever CREATES the component (engine
@@ -1369,6 +1434,23 @@ const MARKER_FUNS = [
1369
1434
  ['markerFontSize', 'fontSize'],
1370
1435
  ];
1371
1436
  const TRANSITION_KEYS = ['transitionDuration', 'transitionTimingFunction', 'transitionDelay'];
1437
+ // ─── Max lines (line clamp) ─────────────────────────────────────────────────────
1438
+ /** "Max lines" (Card v2, board 8 — opt-in on a Title / Text): a whole number clamps the text to that many
1439
+ * lines with an ellipsis. It composes into the four declarations a line clamp takes; anything else
1440
+ * (`none`, empty, 0) clamps nothing. */
1441
+ const MAX_LINES_KEY = 'maxLines';
1442
+ const LINE_CLAMP_OUTPUT = 'WebkitLineClamp';
1443
+ function lineClamp(value) {
1444
+ const n = Number(String(value ?? '').trim());
1445
+ return Number.isInteger(n) && n > 0 ? n : null;
1446
+ }
1447
+ // ─── Gradient backgrounds ──────────────────────────────────────────────────────
1448
+ /** A Background value that is a gradient (the colour control offers one; the `media-scrim` element style
1449
+ * writes one). `background-color` cannot hold an image, so it composes into `background-image`. */
1450
+ const GRADIENT_VALUE = /(^|[\s,(])(repeating-)?(linear|radial|conic)-gradient\(/i;
1451
+ function isGradientPaint(value) {
1452
+ return typeof value === 'string' && GRADIENT_VALUE.test(value);
1453
+ }
1372
1454
  /** The whole-value backdrop trait (DS2). A plain key — it is copied, not stripped — but it feeds
1373
1455
  * the backdrop group's output, so a breakpoint layer that sets it must count as touching it. */
1374
1456
  const BACKDROP_WHOLE_KEY = 'backdropFilter';
@@ -1380,6 +1462,7 @@ const VIRTUAL_TRAIT_GROUPS = Object.freeze([
1380
1462
  { output: 'transform', keys: TRANSFORM_FUNS.map(([t]) => t), reset: 'none' },
1381
1463
  { output: 'transition', keys: [...TRANSITION_KEYS], reset: 'none' },
1382
1464
  { output: '__markerStyles', keys: MARKER_FUNS.map(([t]) => t), reset: null },
1465
+ { output: LINE_CLAMP_OUTPUT, keys: [MAX_LINES_KEY], reset: 'none' },
1383
1466
  ]);
1384
1467
  // ─── All virtual trait names ──────────────────────────────────────────────────
1385
1468
  /** Every virtual trait key — derived from the groups so there is one list to maintain. */
@@ -1476,6 +1559,24 @@ function composeVirtualTraits(raw, base = raw) {
1476
1559
  const delPart = del && del !== '0ms' && del !== '0s' ? ` ${del}` : '';
1477
1560
  result['transition'] = `all ${dur} ${ease}${delPart}`;
1478
1561
  }
1562
+ // Max lines: the clamp takes over the node's display and overflow.
1563
+ const clamp = lineClamp(raw[MAX_LINES_KEY] ?? base[MAX_LINES_KEY]);
1564
+ if (clamp !== null) {
1565
+ result['display'] = '-webkit-box';
1566
+ result['WebkitBoxOrient'] = 'vertical';
1567
+ result[LINE_CLAMP_OUTPUT] = String(clamp);
1568
+ result['overflow'] = 'hidden';
1569
+ }
1570
+ // A gradient Background is an IMAGE. A solid one over a wider/base gradient (a hover, a breakpoint)
1571
+ // must cancel that image, or the gradient keeps showing through.
1572
+ const background = result['backgroundColor'];
1573
+ if (isGradientPaint(background)) {
1574
+ result['backgroundImage'] = background;
1575
+ result['backgroundColor'] = 'transparent';
1576
+ }
1577
+ else if (background !== undefined && raw !== base && isGradientPaint(base['backgroundColor'])) {
1578
+ result['backgroundImage'] = 'none';
1579
+ }
1479
1580
  // ::marker pseudo-element — collected into __markerStyles so StyleRegistryService
1480
1581
  // can emit a separate `.iox-node-{id}::marker { … }` rule.
1481
1582
  const markerStyles = {};
@@ -3811,6 +3912,79 @@ function formPresetById(id) {
3811
3912
  return FORM_PRESETS.find(p => p.id === id);
3812
3913
  }
3813
3914
 
3915
+ // Where form content may NOT render (Doron, 2026-10-20): inside a link or a button.
3916
+ //
3917
+ // HTML forbids interactive content inside `<a>` and `<button>`, and a click in a field may follow the
3918
+ // link. ONE table and ONE walk, shared by the builder's insert rule (refuse it), the builder's audit
3919
+ // (find it in a page saved before the rule) and the engine (warn about it, never rewrite it).
3920
+ var InteractiveTag;
3921
+ (function (InteractiveTag) {
3922
+ InteractiveTag["Anchor"] = "a";
3923
+ InteractiveTag["Button"] = "button";
3924
+ })(InteractiveTag || (InteractiveTag = {}));
3925
+ /**
3926
+ * Every node type that renders as an interactive element, and the element(s) it can render. A ButtonBlock
3927
+ * renders `<a>` or `<button>` by its `tag` trait — both interactive, so switching the tag never lifts the
3928
+ * rule. Pinned to the engine components' selectors by `interactive-hosts.spec.ts`.
3929
+ */
3930
+ const INTERACTIVE_HOST_TAGS = Object.freeze({
3931
+ LinkedContainer: [InteractiveTag.Anchor],
3932
+ Link: [InteractiveTag.Anchor],
3933
+ Button: [InteractiveTag.Anchor],
3934
+ ButtonBlock: [InteractiveTag.Anchor, InteractiveTag.Button],
3935
+ SubmitButton: [InteractiveTag.Button],
3936
+ });
3937
+ const FIELD_GROUP_NODE_TYPE = 'FieldGroup';
3938
+ const SUBMIT_BUTTON_NODE_TYPE = 'SubmitButton';
3939
+ /**
3940
+ * Form content — what a link or a button must never hold: a Form (its controls), a Field (an input, select
3941
+ * or textarea), a SubmitButton (a `<button>`) and a FieldGroup (it exists only to hold fields, so it moves as
3942
+ * one). A Success / Error block is text and lives only inside its form, so it is not on the list.
3943
+ */
3944
+ const FORM_CONTENT_TYPES = new Set([
3945
+ FORM_NODE_TYPE, FIELD_NODE_TYPE, FIELD_GROUP_NODE_TYPE, SUBMIT_BUTTON_NODE_TYPE,
3946
+ ]);
3947
+ function isInteractiveHost(node) {
3948
+ return !!node?.type && Object.prototype.hasOwnProperty.call(INTERACTIVE_HOST_TAGS, node.type);
3949
+ }
3950
+ function isFormContent(node) {
3951
+ return !!node?.type && FORM_CONTENT_TYPES.has(node.type);
3952
+ }
3953
+ /**
3954
+ * The first form-content node in `node`'s subtree that sits inside an interactive host, or null. `insideHost`
3955
+ * is true when `node` is placed under a host already — so a Form dropped into a link and a link that holds a
3956
+ * Form are the same finding.
3957
+ */
3958
+ function formContentInHost(node, insideHost = false) {
3959
+ if (!node)
3960
+ return null;
3961
+ if (insideHost && isFormContent(node))
3962
+ return node;
3963
+ const nowInside = insideHost || isInteractiveHost(node);
3964
+ for (const child of node.children ?? []) {
3965
+ const found = formContentInHost(child, nowInside);
3966
+ if (found)
3967
+ return found;
3968
+ }
3969
+ return null;
3970
+ }
3971
+ /** Every form-content subtree a tree holds inside an interactive host, in document order. */
3972
+ function findFormContentInHosts(roots) {
3973
+ const out = [];
3974
+ const visit = (node, host) => {
3975
+ if (host && isFormContent(node)) {
3976
+ out.push({ host, content: node });
3977
+ return;
3978
+ }
3979
+ const nextHost = host ?? (isInteractiveHost(node) ? node : null);
3980
+ for (const child of (node.children ?? []))
3981
+ visit(child, nextHost);
3982
+ };
3983
+ for (const root of roots ?? [])
3984
+ visit(root, null);
3985
+ return out;
3986
+ }
3987
+
3814
3988
  /*
3815
3989
  * @vectoriox/iox-ui/forms-core — the shared, FRAMEWORK-FREE core of the forms feature.
3816
3990
  *
@@ -4976,6 +5150,9 @@ class IoxComponentRegistryService {
4976
5150
  hasComponent(type) {
4977
5151
  return this.map.has(type);
4978
5152
  }
5153
+ registeredTypes() {
5154
+ return [...this.map.keys()];
5155
+ }
4979
5156
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.31", ngImport: i0, type: IoxComponentRegistryService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
4980
5157
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.31", ngImport: i0, type: IoxComponentRegistryService, providedIn: 'root' }); }
4981
5158
  }
@@ -5046,6 +5223,8 @@ const NOOP_INITIAL_VALUES = {
5046
5223
  // object-fit/aspect-ratio image clipping everywhere. A user-set hidden/scroll/auto/clip is not the
5047
5224
  // initial, so it still emits and wins.
5048
5225
  'overflow': ['visible'], 'overflow-x': ['visible'], 'overflow-y': ['visible'],
5226
+ // Only a gradient Background writes an image; `none` everywhere else is the initial (Card v2).
5227
+ 'background-image': ['none'],
5049
5228
  'clip-path': ['none'],
5050
5229
  // DS2 traits (design-system plan T3/T4). `backdrop-filter: blur(0px)` would still create a
5051
5230
  // containing block, so the whole-value trait's solid-flavor value is `none` — and `none` must
@@ -7344,5 +7523,5 @@ function effectiveTransitionId(anim) {
7344
7523
  * Generated bundle index. Do not edit.
7345
7524
  */
7346
7525
 
7347
- export { AOSService, BACKDROP_TWIN_KEY, BACKDROP_WHOLE_KEY, BREAKPOINTS, Breakpoint, BreakpointQueryKind, BuilderButtonComponent, BuilderDividerComponent, BuilderHeadingComponent, BuilderIconComponent, BuilderImageComponent, BuilderLinkComponent, BuilderSpacerComponent, ButtonBlockComponent, CONTAINER_HTML_TAGS, CONTEXT_ACTION_TYPES, CardComponent, ClientGalleryComponent, ClientListComponent, ClientListItemComponent, ClientRepeaterComponent, ClientSliderContainerComponent, ClientSliderSlideComponent, ComponentInstanceRegistryService, ContainerComponent, ContextStore, DEFAULT_GALLERY_SCHEDULER, DEFAULT_PAGE_TRANSITION, DEFAULT_PAGE_TRANSITION_DURATION, DEFAULT_PAGE_TRANSITION_EASING, DEFAULT_PAGE_TRANSITION_PERSPECTIVE, DEFAULT_PHOSPHOR_WEIGHT, DEFAULT_WIDTH_BY_TYPE, DeclarationContext, FormRenderState, FormRuntimeService, GALLERY_EFFECTS, GALLERY_EFFECT_DESCRIPTORS, GalleryLoop, HOVER_DEFAULT_TRANSITION, HOVER_STATES, IOX_BUILDER_EVENTS, IOX_FORM_MESSAGES, IOX_FORM_NAVIGATOR, IOX_FORM_TRANSPORT, IS_PREVIEW, IoxAnimateContainer, IoxAosDirective, IoxAosModule, IoxBuilderComponentsModule, IoxComponentRegistryService, IoxDialogComponent, IoxFieldComponent, IoxFormComponent, IoxFormErrorComponent, IoxFormSuccessComponent, IoxPageComponent, IoxPageModule, IoxSubmitButtonComponent, IoxUiModule, LEGACY_HOVER_TRANSITION, LinkedContainerComponent, PAGE_STYLE_TOKENS, PAGE_TOKEN_FALLBACKS, PAGE_TRANSITION_CATEGORIES, PAGE_TRANSITION_PRESETS, PART_CLASS_NAMES, PIPE_DESCRIPTORS, PIPE_REGISTRY, PageScrollProvider, PageStyleField, PageStyleSource, RESERVED_ALIAS_PREFIX, STATE_PSEUDO_CLASS, SUPPRESSED_STYLE_PROPS_BY_TYPE, SWIPER_RESPONSIVE_TRAITS, SectionComponent, TRANSITION_FEELS, TextBlockComponent, VALIDATION_STATES, VALIDATION_STATE_CLASS, VIRTUAL_TRAIT_GROUPS, VIRTUAL_TRAIT_KEYS, ViewPositionDirective, ViewPositionModule, activeActions, applyBindingPipes, applyFeel, breakpointDef, breakpointForWidth, breakpointQueryFor, buildDataSourceFilter, buildPartSelector, buildRelatedFilter, buildSwiperBreakpoints, buildTargetedStateSelector, buildTransitionTimeline, cascadeChain, clearInputOverride, clearOverride, collectContextSlotKeys, collectReferencedAliases, compileDeclarations, compilePageStyle, composeVirtualTraits, computeRelative, containerHtmlTag, contextActionEffect, contextSlotKeys, countOverrides, dataSourcePlanToRequest, declaredInputNames, decomposeBackdropFilter, defaultHoverTransition, defaultMessageResolver, deriveSeoFromContent, describePageStyle, describeSeoFields, effectiveTransitionId, excludeSelf, feelFor, getByPath, getSeoValue, hasHoverState, hasOwnTransition, initialSlotValues, isActionEnabled, isContextAction, isInputOverriddenAt, isOverriddenAt, isReservedAlias, isValidSlotKey, isWholeBackdropSet, legacyEnterToTransition, matchRouteParams, mediaQueryFor, mergeSwiperBreakpoints, nearestCommonAncestorId, nodeCssId, nodeUsesContext, normalizeCollectionResult, normalizeGalleryImage, normalizeIconClass, parentBreakpoint, parseUrlList, partClassName, planDataSource, planResponsiveRules, referencedDataSources, referencedDataSourcesDeep, renderDefaultDeclarations, resetPageStyleField, resetSeoField, resolveBoundValue, resolveContextValue, resolveDerivedInto, resolveGalleryEffect, resolveGalleryUrls, resolveInputChain, resolveInputs, resolvePageTransition, resolvePath, resolveRelativeInto, resolveRepeaterItems, resolveSeo, resolveSiblings, resolveSingleItemId, resolveStateStyles, resolveStyleProps, resolveValueChain, rewriteViewportUnits, safeSetInput, setInputOverride, setOverride, setSeoAuto, setSeoBinding, setSeoOverride, setSeoValue, stateNamesIn, statePseudoClass, stripSuppressedProps, variableAliases, variableItemsFrom, withContextSlots, withDefaultHoverTransition, wrapInBreakpointQuery, wrapInMediaQuery };
7526
+ export { AOSService, BACKDROP_TWIN_KEY, BACKDROP_WHOLE_KEY, BREAKPOINTS, Breakpoint, BreakpointQueryKind, BuilderButtonComponent, BuilderDividerComponent, BuilderHeadingComponent, BuilderIconComponent, BuilderImageComponent, BuilderLinkComponent, BuilderSpacerComponent, ButtonBlockComponent, CONTAINER_HTML_TAGS, CONTEXT_ACTION_TYPES, CardComponent, ClientGalleryComponent, ClientListComponent, ClientListItemComponent, ClientRepeaterComponent, ClientSliderContainerComponent, ClientSliderSlideComponent, ComponentInstanceRegistryService, ContainerComponent, ContextStore, DEFAULT_GALLERY_SCHEDULER, DEFAULT_PAGE_TRANSITION, DEFAULT_PAGE_TRANSITION_DURATION, DEFAULT_PAGE_TRANSITION_EASING, DEFAULT_PAGE_TRANSITION_PERSPECTIVE, DEFAULT_PHOSPHOR_WEIGHT, DEFAULT_WIDTH_BY_TYPE, DeclarationContext, FormRenderState, FormRuntimeService, GALLERY_EFFECTS, GALLERY_EFFECT_DESCRIPTORS, GalleryLoop, HOVER_DEFAULT_TRANSITION, HOVER_STATES, IOX_BUILDER_EVENTS, IOX_FORM_MESSAGES, IOX_FORM_NAVIGATOR, IOX_FORM_TRANSPORT, IS_PREVIEW, IoxAnimateContainer, IoxAosDirective, IoxAosModule, IoxBuilderComponentsModule, IoxComponentRegistryService, IoxDialogComponent, IoxFieldComponent, IoxFormComponent, IoxFormErrorComponent, IoxFormSuccessComponent, IoxPageComponent, IoxPageModule, IoxSubmitButtonComponent, IoxUiModule, LEGACY_HOVER_TRANSITION, LinkedContainerComponent, MAX_LINES_KEY, PAGE_STYLE_TOKENS, PAGE_TOKEN_FALLBACKS, PAGE_TRANSITION_CATEGORIES, PAGE_TRANSITION_PRESETS, PART_CLASS_NAMES, PIPE_DESCRIPTORS, PIPE_REGISTRY, PageScrollProvider, PageStyleField, PageStyleSource, RESERVED_ALIAS_PREFIX, STATE_PSEUDO_CLASS, SUPPRESSED_STYLE_PROPS_BY_TYPE, SWIPER_RESPONSIVE_TRAITS, SectionComponent, TRANSITION_FEELS, TextBlockComponent, VALIDATION_STATES, VALIDATION_STATE_CLASS, VIRTUAL_TRAIT_GROUPS, VIRTUAL_TRAIT_KEYS, ViewPositionDirective, ViewPositionModule, activeActions, applyBindingPipes, applyFeel, breakpointDef, breakpointForWidth, breakpointQueryFor, buildDataSourceFilter, buildPartSelector, buildRelatedFilter, buildSwiperBreakpoints, buildTargetedStateSelector, buildTransitionTimeline, cascadeChain, clearInputOverride, clearOverride, collectContextSlotKeys, collectReferencedAliases, compileDeclarations, compilePageStyle, composeVirtualTraits, computeRelative, containerHtmlTag, contextActionEffect, contextSlotKeys, countOverrides, dataSourcePlanToRequest, declaredInputNames, decomposeBackdropFilter, defaultHoverTransition, defaultMessageResolver, deriveSeoFromContent, describePageStyle, describeSeoFields, effectiveTransitionId, excludeSelf, feelFor, getByPath, getSeoValue, hasHoverState, hasOwnTransition, initialSlotValues, isActionEnabled, isContextAction, isGradientPaint, isInputOverriddenAt, isOverriddenAt, isReservedAlias, isValidSlotKey, isWholeBackdropSet, legacyEnterToTransition, matchRouteParams, mediaQueryFor, mergeSwiperBreakpoints, nearestCommonAncestorId, nodeCssId, nodeUsesContext, normalizeCollectionResult, normalizeGalleryImage, normalizeIconClass, parentBreakpoint, parseUrlList, partClassName, planDataSource, planResponsiveRules, referencedDataSources, referencedDataSourcesDeep, renderDefaultDeclarations, resetPageStyleField, resetSeoField, resolveBoundValue, resolveContextValue, resolveDerivedInto, resolveGalleryEffect, resolveGalleryUrls, resolveInputChain, resolveInputs, resolvePageTransition, resolvePath, resolveRelativeInto, resolveRepeaterItems, resolveSeo, resolveSiblings, resolveSingleItemId, resolveStateStyles, resolveStyleProps, resolveValueChain, rewriteViewportUnits, safeSetInput, setInputOverride, setOverride, setSeoAuto, setSeoBinding, setSeoOverride, setSeoValue, stateNamesIn, statePseudoClass, stripSuppressedProps, variableAliases, variableItemsFrom, withContextSlots, withDefaultHoverTransition, wrapInBreakpointQuery, wrapInMediaQuery };
7348
7527
  //# sourceMappingURL=vectoriox-iox-ui.mjs.map