@vectoriox/iox-builder 1.4.12 → 1.4.13

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.
@@ -1718,23 +1718,25 @@ class StyleRegistryService {
1718
1718
  this.rules = new Map();
1719
1719
  this.styleEl = null;
1720
1720
  }
1721
- /** Properties that must live on the wrapper element to affect the parent layout. */
1721
+ /**
1722
+ * Properties that must live on the OUTER wrapper (.iox-outer-{id}) because they
1723
+ * affect how the element participates in its PARENT layout (flex/block flow).
1724
+ * Everything else goes to the INNER element (.iox-node-{id}).
1725
+ *
1726
+ * Exception — out-of-flow positioning (position:fixed/absolute):
1727
+ * When position is fixed or absolute, width is redirected to the inner element
1728
+ * (the positioned one) and a default width:100% is added if none is set, so the
1729
+ * element stays visible. top/right/bottom/left/zIndex are always inner because
1730
+ * they are co-ordinates of the positioned element, not the flow wrapper.
1731
+ * position itself goes to inner with `!important` to beat component-scoped CSS.
1732
+ */
1722
1733
  static { this.OUTER_PROPS = new Set([
1723
1734
  'margin', 'marginTop', 'marginRight', 'marginBottom', 'marginLeft',
1724
1735
  'alignSelf', 'flexGrow', 'flexShrink', 'flexBasis', 'order',
1725
1736
  'width',
1726
- // position must go to the outer wrapper so that position:fixed/absolute takes
1727
- // the WHOLE block out of flow. Inner component-scoped CSS (e.g. .section-root
1728
- // { position: relative }) has higher specificity than .iox-node-{id} and would
1729
- // silently win — putting position on the outer class bypasses that entirely.
1730
- 'position',
1731
- // top/right/bottom/left and zIndex are positioning co-ordinates — they only
1732
- // work on the SAME element that carries the position property (the outer
1733
- // wrapper). Putting them on the inner element (iox-node-{id}) would apply them
1734
- // to the inner's position:relative context, not to the fixed/absolute outer.
1735
- 'top', 'right', 'bottom', 'left',
1736
- 'zIndex',
1737
1737
  ]); }
1738
+ /** Properties that need !important on the inner element to beat Angular's scoped-CSS specificity boost. */
1739
+ static { this.IMPORTANT_PROPS = new Set(['position']); }
1738
1740
  init() {
1739
1741
  this.styleEl = document.createElement('style');
1740
1742
  this.styleEl.id = 'iox-runtime-styles';
@@ -1767,16 +1769,24 @@ class StyleRegistryService {
1767
1769
  this.flush();
1768
1770
  return;
1769
1771
  }
1772
+ const pos = String(styles['position'] ?? '');
1773
+ const isOutOfFlow = pos === 'fixed' || pos === 'absolute';
1770
1774
  const inner = {};
1771
1775
  const outer = {};
1772
1776
  for (const [k, v] of Object.entries(styles)) {
1773
- if (StyleRegistryService.OUTER_PROPS.has(k)) {
1777
+ const wantsOuter = StyleRegistryService.OUTER_PROPS.has(k);
1778
+ // width goes to inner for fixed/absolute (the positioned element owns its own width)
1779
+ if (wantsOuter && !(isOutOfFlow && k === 'width')) {
1774
1780
  outer[k] = v;
1775
1781
  }
1776
1782
  else {
1777
1783
  inner[k] = v;
1778
1784
  }
1779
1785
  }
1786
+ // Ensure fixed/absolute elements stay visible when no explicit width is set
1787
+ if (isOutOfFlow && inner['width'] === undefined) {
1788
+ inner['width'] = '100%';
1789
+ }
1780
1790
  const innerCss = this.compile(`iox-node-${nodeId}`, inner);
1781
1791
  const outerCss = this.compile(`iox-outer-${nodeId}`, outer);
1782
1792
  const combined = [innerCss, outerCss].filter(Boolean).join('\n');
@@ -1828,7 +1838,11 @@ class StyleRegistryService {
1828
1838
  compile(className, styles) {
1829
1839
  const entries = Object.entries(styles)
1830
1840
  .filter(([, v]) => v !== undefined && v !== null && v !== '')
1831
- .map(([k, v]) => ` ${this.toKebabCase(k)}: ${this.rewriteVh(String(v))};`);
1841
+ .map(([k, v]) => {
1842
+ const val = this.rewriteVh(String(v));
1843
+ const bang = StyleRegistryService.IMPORTANT_PROPS.has(k) ? ' !important' : '';
1844
+ return ` ${this.toKebabCase(k)}: ${val}${bang};`;
1845
+ });
1832
1846
  if (!entries.length)
1833
1847
  return '';
1834
1848
  return `.${className} {\n${entries.join('\n')}\n}`;