@vectoriox/iox-builder 4.6.0 → 4.8.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.
@@ -218,7 +218,7 @@ class ComponentConfig {
218
218
  }
219
219
  }
220
220
  class TraitConfig {
221
- constructor(name, label, type, options, defaultValue, inline, showWhen) {
221
+ constructor(name, label, type, options, defaultValue, inline, showWhen, responsive) {
222
222
  this.name = name;
223
223
  this.label = label;
224
224
  this.type = type;
@@ -226,6 +226,7 @@ class TraitConfig {
226
226
  this.default = defaultValue;
227
227
  this.inline = inline;
228
228
  this.showWhen = showWhen;
229
+ this.responsive = responsive;
229
230
  }
230
231
  }
231
232
  class GroupStyleConfig {
@@ -320,7 +321,7 @@ class LayoutGroupStyleConfig extends GroupStyleConfig {
320
321
  { value: 'flex-start', label: 'Start', icon: 'ph-thin ph-align-left' },
321
322
  { value: 'center', label: 'Center', icon: 'ph-thin ph-align-center-horizontal' },
322
323
  { value: 'flex-end', label: 'End', icon: 'ph-thin ph-align-right' },
323
- { value: 'space-between', label: 'Space Between', icon: 'ph-thin ph-distribute-horizontal' },
324
+ { value: 'space-between', label: 'Space Between', icon: 'ph-thin ph-arrows-out-line-horizontal' },
324
325
  { value: 'space-around', label: 'Space Around', icon: 'ph-thin ph-dots-three' },
325
326
  { value: 'space-evenly', label: 'Space Evenly', icon: 'ph-thin ph-dots-six' },
326
327
  ], 'flex-start', false, { trait: 'display', values: ['flex', 'grid'] }),
@@ -344,7 +345,7 @@ class LayoutGroupStyleConfig extends GroupStyleConfig {
344
345
  { value: 'start', label: 'Start', icon: 'ph-thin ph-align-top' },
345
346
  { value: 'center', label: 'Center', icon: 'ph-thin ph-align-center-vertical' },
346
347
  { value: 'end', label: 'End', icon: 'ph-thin ph-align-bottom' },
347
- { value: 'space-between', label: 'Space Between', icon: 'ph-thin ph-distribute-vertical' },
348
+ { value: 'space-between', label: 'Space Between', icon: 'ph-thin ph-arrows-out-line-vertical' },
348
349
  { value: 'space-around', label: 'Space Around', icon: 'ph-thin ph-dots-three' },
349
350
  { value: 'stretch', label: 'Stretch', icon: 'ph-thin ph-arrows-vertical' },
350
351
  ], 'stretch', false, { trait: 'display', values: 'grid' }),
@@ -4273,6 +4274,12 @@ class RenderDirective {
4273
4274
  return;
4274
4275
  safeSetInput(componentRef, trait.name, trait.default);
4275
4276
  });
4277
+ // Per-breakpoint TRAIT overrides — the same hand-off the SSR engine makes. A component that
4278
+ // declares a `responsive` input (SliderContainer) converts it to its own width config, so the
4279
+ // canvas and the live site agree without the canvas needing a resize listener. Dropped by
4280
+ // safeSetInput for every component that does not declare it.
4281
+ if (node.responsive)
4282
+ safeSetInput(componentRef, 'responsive', node.responsive);
4276
4283
  // Build initial style map from styleTraits defaults.
4277
4284
  const initialStyle = {};
4278
4285
  if (node.styleTraits?.length) {
@@ -9153,8 +9160,18 @@ class CardComponentConfig extends ComponentConfig {
9153
9160
  new TraitConfig('description', 'Description', TraitInputType.Text, undefined, 'This is a default card description.')
9154
9161
  ];
9155
9162
  this.styleTraits = buildFullStyleTraits();
9163
+ // DEPRECATED — removed from the Components panel (2026-09-22). A Card is a Container with a
9164
+ // border, a radius and a background: every one of those is a style group on Container, so the
9165
+ // component earned no place in the palette. It stays REGISTERED and renderable because saved
9166
+ // pages may contain Card nodes — dropping the type would render those pages blank. Remove the
9167
+ // type entirely only behind a migration that rewrites Card nodes to Container.
9168
+ this.hidden = true;
9156
9169
  this.applyStyleDefaults({
9157
- width: '200px',
9170
+ // Fluid up to the design width: a fixed 200px card overflows a narrow column and is
9171
+ // the single most common `fixed-width` audit finding. Capping keeps the desktop look
9172
+ // identical (parent wider than 200px → still 200px) while shrinking on a phone.
9173
+ width: '100%',
9174
+ maxWidth: '200px',
9158
9175
  height: 'auto',
9159
9176
  padding: '16px 16px 16px 16px',
9160
9177
  borderWidth: '1px 1px 1px 1px',
@@ -9292,7 +9309,10 @@ class BuilderImageComponentConfig extends ComponentConfig {
9292
9309
  ];
9293
9310
  this.styleTraits = buildFullStyleTraits();
9294
9311
  this.applyStyleDefaults({
9295
- width: '300px',
9312
+ // Same reasoning as Card: 300px alone overflows a 320px viewport once the page has any
9313
+ // side padding. Capped-fluid renders identically wherever there is room.
9314
+ width: '100%',
9315
+ maxWidth: '300px',
9296
9316
  aspectRatio: '1/1',
9297
9317
  });
9298
9318
  }
@@ -9449,6 +9469,14 @@ class RepeaterComponentConfig extends ComponentConfig {
9449
9469
  label: 'Limit',
9450
9470
  type: TraitInputType.Number,
9451
9471
  default: 10,
9472
+ // NOT marked `responsive` yet, deliberately. Row COUNT cannot be varied per width the
9473
+ // way the slider's can: Swiper reads its own breakpoints map at runtime, but a
9474
+ // repeater's count is decided when the markup is produced — and SSR has no viewport,
9475
+ // so rendering N on the server and M in the browser is a hydration mismatch. The fix
9476
+ // is to keep rendering every item and HIDE the surplus per width with a generated
9477
+ // `:nth-child(n+X) { display: none }` rule (CSS-expressible, hydration-safe), which is
9478
+ // a separate change. Marking it responsive now would ship a control that silently
9479
+ // does nothing on the live site — exactly the `slidesPerGroup` bug this pass fixed.
9452
9480
  },
9453
9481
  ];
9454
9482
  this.styleTraits = buildFullStyleTraits();
@@ -9549,15 +9577,15 @@ class SliderContainerConfig extends ComponentConfig {
9549
9577
  { label: '4', value: 4 },
9550
9578
  { label: '5', value: 5 },
9551
9579
  { label: '6', value: 6 },
9552
- ], 'auto'),
9553
- new TraitConfig('slidesPerGroup', 'Slides per group', TraitInputType.Scrub, undefined, 1),
9580
+ ], 'auto', undefined, undefined, /* responsive */ true),
9581
+ new TraitConfig('slidesPerGroup', 'Slides per group', TraitInputType.Scrub, undefined, 1, undefined, undefined, /* responsive */ true),
9554
9582
  new TraitConfig('loop', 'Loop', TraitInputType.SelectButton, [
9555
9583
  { label: 'Off', value: 'off' },
9556
9584
  { label: 'Loop', value: 'loop' },
9557
9585
  { label: 'Rewind', value: 'rewind' },
9558
9586
  ], 'off'),
9559
9587
  new TraitConfig('centeredSlides', 'Centered slides', TraitInputType.Checkbox, undefined, false),
9560
- new TraitConfig('spaceBetween', 'Space between (px)', TraitInputType.Scrub, undefined, 0),
9588
+ new TraitConfig('spaceBetween', 'Space between (px)', TraitInputType.Scrub, undefined, 0, undefined, undefined, /* responsive */ true),
9561
9589
  new TraitConfig('initialSlide', 'Initial slide', TraitInputType.Scrub, undefined, 0),
9562
9590
  new TraitConfig('autoHeight', 'Auto height', TraitInputType.Checkbox, undefined, false),
9563
9591
  new TraitConfig('grabCursor', 'Grab cursor', TraitInputType.Checkbox, undefined, true),