@vectoriox/iox-builder 1.5.10 → 1.6.1

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.
@@ -271,6 +271,24 @@ class OverlayService {
271
271
  }
272
272
  return undefined;
273
273
  }
274
+ /**
275
+ * Walk up the DOM from a node's registered host element to the nearest ANCESTOR
276
+ * element that is itself a registered node. Used to resolve the immediate parent
277
+ * for relational style states (e.g. parent-hover). Returns undefined for root nodes.
278
+ */
279
+ getParentEntry(node) {
280
+ const ref = this.nodeMap.get(node);
281
+ if (!ref)
282
+ return undefined;
283
+ let el = ref.element.parentElement;
284
+ while (el) {
285
+ const match = this.findNodeByElement(el);
286
+ if (match)
287
+ return match;
288
+ el = el.parentElement;
289
+ }
290
+ return undefined;
291
+ }
274
292
  setHover(element, componentName, mode) {
275
293
  if (this.selectSubject.getValue()?.element === element)
276
294
  return;
@@ -1998,7 +2016,17 @@ const EASING_OPTIONS = ['linear', 'ease', 'ease-in', 'ease-out', 'ease-in-out'];
1998
2016
  const INTERACTION_STATES = ['hover', 'active', 'focus'];
1999
2017
  /** Structural pseudo-classes — compiled to .iox-outer-{id}:state */
2000
2018
  const STRUCTURAL_STATES = ['first-child', 'last-child', 'nth-child(odd)', 'nth-child(even)'];
2001
- const SUPPORTED_STATES = [...INTERACTION_STATES, ...STRUCTURAL_STATES];
2019
+ /**
2020
+ * Relational pseudo-classes — the styled element is a descendant, the pseudo-class
2021
+ * lives on an ANCESTOR. Compiled to `.iox-node-{parentId}:{base} .iox-node-{id} { … }`,
2022
+ * so they require the ancestor's css id (`relativeToId`) at compile time.
2023
+ * `RELATIONAL_STATE_BASE` maps each relational state to the ancestor pseudo-class.
2024
+ */
2025
+ const RELATIONAL_STATES = ['parent-hover'];
2026
+ const RELATIONAL_STATE_BASE = {
2027
+ 'parent-hover': 'hover',
2028
+ };
2029
+ const SUPPORTED_STATES = [...INTERACTION_STATES, ...STRUCTURAL_STATES, ...RELATIONAL_STATES];
2002
2030
  /**
2003
2031
  * Build a full StyleTraitGroup[] schema populated with values from a flat
2004
2032
  * styleProps map. Used when editing a preset in the Style panel — the panel
@@ -2468,19 +2496,38 @@ class StyleRegistryService {
2468
2496
  *
2469
2497
  * @param nodeId The node's CSS id (used in `.iox-node-{nodeId}`)
2470
2498
  * @param styles Flat CSS property map (camelCase keys)
2471
- * @param state Optional pseudo-class state ('hover' | 'active' | 'focus').
2499
+ * @param state Optional pseudo-class state ('hover' | 'active' | 'focus' | …).
2472
2500
  * When provided, compiles to `.iox-node-{id}:{state} { … }`.
2473
2501
  * State rules are NOT partitioned into inner/outer.
2502
+ * @param relativeToId Ancestor css id, required for RELATIONAL states
2503
+ * (e.g. 'parent-hover'). Compiles to
2504
+ * `.iox-node-{relativeToId}:{base} .iox-node-{nodeId} { … }`.
2474
2505
  */
2475
- upsert(nodeId, styles, state) {
2506
+ upsert(nodeId, styles, state, relativeToId) {
2476
2507
  if (!nodeId)
2477
2508
  return;
2478
2509
  if (state) {
2510
+ const key = `${nodeId}:${state}`;
2511
+ // Relational states (parent-hover): the pseudo-class lives on an ANCESTOR
2512
+ // and cascades to this element. Requires the ancestor's css id.
2513
+ if (RELATIONAL_STATES.includes(state)) {
2514
+ const base = RELATIONAL_STATE_BASE[state];
2515
+ const css = (relativeToId && base)
2516
+ ? this.compile(`iox-node-${relativeToId}:${base} .iox-node-${nodeId}`, styles)
2517
+ : '';
2518
+ if (css) {
2519
+ this.rules.set(key, css);
2520
+ }
2521
+ else {
2522
+ this.rules.delete(key);
2523
+ }
2524
+ this.flush();
2525
+ return;
2526
+ }
2479
2527
  // Structural pseudo-classes (first-child, last-child, nth-child) target the
2480
2528
  // outer wrapper element so they participate correctly in grid/flex layout.
2481
2529
  const prefix = STRUCTURAL_STATES.includes(state) ? 'iox-outer' : 'iox-node';
2482
2530
  const css = this.compile(`${prefix}-${nodeId}:${state}`, styles);
2483
- const key = `${nodeId}:${state}`;
2484
2531
  if (css) {
2485
2532
  this.rules.set(key, css);
2486
2533
  }
@@ -6259,24 +6306,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImpo
6259
6306
  }] } });
6260
6307
 
6261
6308
  class SliderSlideComponent {
6262
- set style(v) {
6263
- if (v === this._style)
6264
- return;
6265
- this._style = v;
6266
- // Strip width constraints; rebuild cached object so ngStyle only updates DOM
6267
- // when the input actually changed — prevents spurious MutationObserver triggers.
6268
- const { width, minWidth, maxWidth, ...rest } = v || {};
6269
- this._slideEditStyle = rest;
6270
- }
6309
+ set style(v) { this._style = v; }
6271
6310
  get style() { return this._style; }
6272
- get slideEditStyle() { return this._slideEditStyle; }
6273
6311
  constructor(dragEngine, cdr, isPreview) {
6274
6312
  this.dragEngine = dragEngine;
6275
6313
  this.cdr = cdr;
6276
6314
  this.isPreview = isPreview;
6277
6315
  this.children = [];
6316
+ // Slide visual styles are applied via the shared `iox-node-<cssId>` CSS class
6317
+ // (StyleRegistryService), not inline — so repeated preview clones inherit master
6318
+ // style edits. Kept as an @Input so render.directive / style panel can still set it
6319
+ // (read internally for CDK orientation) without an NG0303 warning.
6278
6320
  this._style = {};
6279
- this._slideEditStyle = {};
6280
6321
  this.nodeId = '';
6281
6322
  this.dropListId = '';
6282
6323
  this.childClick = new EventEmitter();
@@ -6295,7 +6336,6 @@ class SliderSlideComponent {
6295
6336
  <div *ngIf="isPreview"
6296
6337
  class="swiper-slide"
6297
6338
  [ngClass]="['iox-node-' + nodeId]"
6298
- [ngStyle]="style"
6299
6339
  ioxDropzone
6300
6340
  [ioxDropzoneId]="dropListId"
6301
6341
  [ioxDropzoneData]="children"
@@ -6320,14 +6360,13 @@ class SliderSlideComponent {
6320
6360
  </div>
6321
6361
  </div>
6322
6362
 
6323
- <!-- EDIT: plain block so it sits in the horizontal strip.
6324
- Width/min-width/max-width are stripped from ngStyle here — they belong on the
6325
- iox-outer-* wrapper (already applied by StyleRegistryService), not on this inner
6326
- div. Applying them here too would make the content 33% of 33%. -->
6363
+ <!-- EDIT: plain block. Visual styles come from the shared iox-node-<cssId> CSS
6364
+ class (StyleRegistryService), NOT inline — so repeated preview clones inherit
6365
+ master-slide style edits through the shared rule. -->
6327
6366
  <div *ngIf="!isPreview"
6328
6367
  class="slide-edit-block"
6368
+ [class.slide-empty]="!children.length"
6329
6369
  [ngClass]="['iox-node-' + nodeId]"
6330
- [ngStyle]="slideEditStyle"
6331
6370
  ioxDropzone
6332
6371
  [ioxDropzoneId]="dropListId"
6333
6372
  [ioxDropzoneData]="children"
@@ -6351,7 +6390,7 @@ class SliderSlideComponent {
6351
6390
  </ng-container>
6352
6391
  </div>
6353
6392
  </div>
6354
- `, isInline: true, styles: [".swiper-slide,.slide-edit-block{position:relative;box-sizing:border-box;display:flex;align-items:center;justify-content:center;overflow:hidden;background-color:var(--p-surface-300)}.slide-edit-block{width:100%}.slide-placeholder{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:.5rem;border:1.5px dashed rgba(100,116,139,.35);border-radius:4px;color:#64748b80;font-size:12px;pointer-events:none;-webkit-user-select:none;user-select:none;opacity:0;transition:opacity .15s}:host:hover .slide-placeholder,:host.iox-drag-over .slide-placeholder{opacity:1}.slide-placeholder i{font-size:22px}\n"], dependencies: [{ kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: RenderDirective, selector: "[ioxRender]", inputs: ["ioxRender"], outputs: ["onClick", "onMouseEnter", "onMouseLeave"] }, { kind: "directive", type: IoxDraggableDirective, selector: "[ioxDraggable]", inputs: ["ioxDragData", "ioxDragSourceId"] }, { kind: "directive", type: IoxDropzoneDirective, selector: "[ioxDropzone]", inputs: ["ioxDropzoneId", "ioxDropzoneData", "ioxDropzonePostDrop"], outputs: ["ioxDrop"] }] }); }
6393
+ `, isInline: true, styles: [".swiper-slide,.slide-edit-block{position:relative;box-sizing:border-box;display:flex;align-items:center;justify-content:center;overflow:hidden;background-color:var(--p-surface-300)}.slide-edit-block{width:100%}.slide-edit-block.slide-empty{min-height:120px}.slide-placeholder{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:.5rem;border:1.5px dashed rgba(100,116,139,.35);border-radius:4px;color:#64748b80;font-size:12px;pointer-events:none;-webkit-user-select:none;user-select:none;opacity:0;transition:opacity .15s}:host:hover .slide-placeholder,:host.iox-drag-over .slide-placeholder{opacity:1}.slide-placeholder i{font-size:22px}\n"], dependencies: [{ kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: RenderDirective, selector: "[ioxRender]", inputs: ["ioxRender"], outputs: ["onClick", "onMouseEnter", "onMouseLeave"] }, { kind: "directive", type: IoxDraggableDirective, selector: "[ioxDraggable]", inputs: ["ioxDragData", "ioxDragSourceId"] }, { kind: "directive", type: IoxDropzoneDirective, selector: "[ioxDropzone]", inputs: ["ioxDropzoneId", "ioxDropzoneData", "ioxDropzonePostDrop"], outputs: ["ioxDrop"] }] }); }
6355
6394
  }
6356
6395
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: SliderSlideComponent, decorators: [{
6357
6396
  type: Component,
@@ -6360,7 +6399,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImpo
6360
6399
  <div *ngIf="isPreview"
6361
6400
  class="swiper-slide"
6362
6401
  [ngClass]="['iox-node-' + nodeId]"
6363
- [ngStyle]="style"
6364
6402
  ioxDropzone
6365
6403
  [ioxDropzoneId]="dropListId"
6366
6404
  [ioxDropzoneData]="children"
@@ -6385,14 +6423,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImpo
6385
6423
  </div>
6386
6424
  </div>
6387
6425
 
6388
- <!-- EDIT: plain block so it sits in the horizontal strip.
6389
- Width/min-width/max-width are stripped from ngStyle here — they belong on the
6390
- iox-outer-* wrapper (already applied by StyleRegistryService), not on this inner
6391
- div. Applying them here too would make the content 33% of 33%. -->
6426
+ <!-- EDIT: plain block. Visual styles come from the shared iox-node-<cssId> CSS
6427
+ class (StyleRegistryService), NOT inline — so repeated preview clones inherit
6428
+ master-slide style edits through the shared rule. -->
6392
6429
  <div *ngIf="!isPreview"
6393
6430
  class="slide-edit-block"
6431
+ [class.slide-empty]="!children.length"
6394
6432
  [ngClass]="['iox-node-' + nodeId]"
6395
- [ngStyle]="slideEditStyle"
6396
6433
  ioxDropzone
6397
6434
  [ioxDropzoneId]="dropListId"
6398
6435
  [ioxDropzoneData]="children"
@@ -6416,7 +6453,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImpo
6416
6453
  </ng-container>
6417
6454
  </div>
6418
6455
  </div>
6419
- `, standalone: false, styles: [".swiper-slide,.slide-edit-block{position:relative;box-sizing:border-box;display:flex;align-items:center;justify-content:center;overflow:hidden;background-color:var(--p-surface-300)}.slide-edit-block{width:100%}.slide-placeholder{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:.5rem;border:1.5px dashed rgba(100,116,139,.35);border-radius:4px;color:#64748b80;font-size:12px;pointer-events:none;-webkit-user-select:none;user-select:none;opacity:0;transition:opacity .15s}:host:hover .slide-placeholder,:host.iox-drag-over .slide-placeholder{opacity:1}.slide-placeholder i{font-size:22px}\n"] }]
6456
+ `, standalone: false, styles: [".swiper-slide,.slide-edit-block{position:relative;box-sizing:border-box;display:flex;align-items:center;justify-content:center;overflow:hidden;background-color:var(--p-surface-300)}.slide-edit-block{width:100%}.slide-edit-block.slide-empty{min-height:120px}.slide-placeholder{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:.5rem;border:1.5px dashed rgba(100,116,139,.35);border-radius:4px;color:#64748b80;font-size:12px;pointer-events:none;-webkit-user-select:none;user-select:none;opacity:0;transition:opacity .15s}:host:hover .slide-placeholder,:host.iox-drag-over .slide-placeholder{opacity:1}.slide-placeholder i{font-size:22px}\n"] }]
6420
6457
  }], ctorParameters: () => [{ type: DragEngineService }, { type: i0.ChangeDetectorRef }, { type: undefined, decorators: [{
6421
6458
  type: Optional
6422
6459
  }, {
@@ -7452,5 +7489,5 @@ class BuilderSpacerComponentConfig extends ComponentConfig {
7452
7489
  * Generated bundle index. Do not edit.
7453
7490
  */
7454
7491
 
7455
- export { ACTION_TYPE_OPTIONS, BackgroundGroupStyleConfig, BorderGroupStyleConfig, BuilderButtonBlockComponent, BuilderButtonComponentConfig, BuilderClipboardService, BuilderComponent, BuilderContainerComponent, BuilderContainerComponentConfig, BuilderDividerComponentConfig, BuilderHeadingComponentConfig, BuilderHistoryService, BuilderIconComponentConfig, BuilderImageComponentConfig, BuilderLinkComponentConfig, BuilderLinkedContainerComponent, BuilderLinkedContainerConfig, BuilderListComponentConfig, BuilderListItemComponentConfig, BuilderMode, BuilderRepeaterComponent, BuilderSpacerComponentConfig, ButtonBlockComponentConfig, CardComponentConfig, ComponentConfig, ComponentRegistryService, DEVICE_OPTIONS, DataSourceRegistryService, DataSourceType, DeviceMode, DimensionsGroupStyleConfig, DragEngineService, EASING_OPTIONS, EffectsGroupStyleConfig, GroupStyleConfig, INTERACTION_STATES, INVERSE_ACTION, IOX_CONTENT_SERVICE, IOX_FONT_MANAGER, IOX_SHOP_SERVICE, InteractionEngineService, InteractionPresetRegistryService, InteractionsPanelComponent, IoxBuilderModule, IoxDraggableDirective, IoxDropzoneDirective, LayerTreeComponent, LayoutGroupStyleConfig, ListGroupStyleConfig, NodeAction, OverlayComponent, OverlayService, PanelChildComponent, PanelComponent, PanelEventService, PanelEventTypes, PanelTypes, PositionGroupStyleConfig, PresetRegistryService, 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, SymbolRegistryService, TRIGGER_OPTIONS, TextBlockComponentConfig, ToolbarAction, ToolbarComponent, TraitConfig, TraitInputType, TypographyGroupStyleConfig, UNITS_ALL, UNITS_DEG, UNITS_FIXED, UNITS_NO_VW, VIRTUAL_TRAIT_KEYS, ViewportService, ZOOM_OPTIONS, buildFullStyleTraits, buildPresetStyleTraits, composeVirtualTraits, defaultPageSettings, flattenSchemaFields, generateNodeId, resolveTraitControllerType, resolveTraitOptions };
7492
+ export { ACTION_TYPE_OPTIONS, BackgroundGroupStyleConfig, BorderGroupStyleConfig, BuilderButtonBlockComponent, BuilderButtonComponentConfig, BuilderClipboardService, BuilderComponent, BuilderContainerComponent, BuilderContainerComponentConfig, BuilderDividerComponentConfig, BuilderHeadingComponentConfig, BuilderHistoryService, BuilderIconComponentConfig, BuilderImageComponentConfig, BuilderLinkComponentConfig, BuilderLinkedContainerComponent, BuilderLinkedContainerConfig, BuilderListComponentConfig, BuilderListItemComponentConfig, BuilderMode, BuilderRepeaterComponent, BuilderSpacerComponentConfig, ButtonBlockComponentConfig, CardComponentConfig, ComponentConfig, ComponentRegistryService, DEVICE_OPTIONS, DataSourceRegistryService, DataSourceType, DeviceMode, DimensionsGroupStyleConfig, DragEngineService, EASING_OPTIONS, EffectsGroupStyleConfig, GroupStyleConfig, INTERACTION_STATES, INVERSE_ACTION, IOX_CONTENT_SERVICE, IOX_FONT_MANAGER, IOX_SHOP_SERVICE, InteractionEngineService, InteractionPresetRegistryService, InteractionsPanelComponent, IoxBuilderModule, IoxDraggableDirective, IoxDropzoneDirective, 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, SymbolRegistryService, TRIGGER_OPTIONS, TextBlockComponentConfig, ToolbarAction, ToolbarComponent, TraitConfig, TraitInputType, TypographyGroupStyleConfig, UNITS_ALL, UNITS_DEG, UNITS_FIXED, UNITS_NO_VW, VIRTUAL_TRAIT_KEYS, ViewportService, ZOOM_OPTIONS, buildFullStyleTraits, buildPresetStyleTraits, composeVirtualTraits, defaultPageSettings, flattenSchemaFields, generateNodeId, resolveTraitControllerType, resolveTraitOptions };
7456
7493
  //# sourceMappingURL=vectoriox-iox-builder.mjs.map