@vectoriox/iox-builder 2.1.0 → 2.1.2
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.
|
@@ -48,6 +48,10 @@ var PanelEventTypes;
|
|
|
48
48
|
PanelEventTypes["INTERACTION_PRESET_EDIT"] = "interactionpresetedit";
|
|
49
49
|
/** Fired after an interaction preset is created, updated, or deleted so panels refresh. */
|
|
50
50
|
PanelEventTypes["INTERACTION_PRESETS_CHANGED"] = "interactionpresetschanged";
|
|
51
|
+
/** Open the Interactions panel and EXPAND a specific interaction for editing (data = interaction
|
|
52
|
+
* id). Emitted when the overlay interaction badge is clicked so that badge → "edit THIS
|
|
53
|
+
* interaction", without firing the element's (live) animation. */
|
|
54
|
+
PanelEventTypes["INTERACTION_EDIT"] = "interactionedit";
|
|
51
55
|
})(PanelEventTypes || (PanelEventTypes = {}));
|
|
52
56
|
class PanelEventService {
|
|
53
57
|
constructor() {
|
|
@@ -3656,11 +3660,24 @@ class OverlayComponent {
|
|
|
3656
3660
|
if (this.selectEntry)
|
|
3657
3661
|
this.toolbarAction.emit({ action: ToolbarAction.EditPreset, entry: this.selectEntry });
|
|
3658
3662
|
}
|
|
3659
|
-
|
|
3663
|
+
/**
|
|
3664
|
+
* Interaction badge clicked. It must ONLY open the Interactions panel with THIS interaction
|
|
3665
|
+
* active — it must NOT fire the element's (live) animation. `preventDefault` + `stopPropagation`
|
|
3666
|
+
* fully swallow the pointer event so it can never reach the node's live `click` interaction
|
|
3667
|
+
* listener. The specific `ix` is forwarded so the builder can expand it in the panel.
|
|
3668
|
+
*/
|
|
3669
|
+
onEditInteractionPreset(event, ix) {
|
|
3670
|
+
event.preventDefault();
|
|
3660
3671
|
event.stopPropagation();
|
|
3661
3672
|
this.activeBadgeType = 'interaction';
|
|
3662
|
-
if (this.selectEntry)
|
|
3663
|
-
this.toolbarAction.emit({ action: ToolbarAction.EditInteractionPreset, entry: this.selectEntry });
|
|
3673
|
+
if (this.selectEntry) {
|
|
3674
|
+
this.toolbarAction.emit({ action: ToolbarAction.EditInteractionPreset, entry: this.selectEntry, interaction: ix });
|
|
3675
|
+
}
|
|
3676
|
+
}
|
|
3677
|
+
/** Swallow the follow-up click on the badge so it can't reach the canvas / a live interaction. */
|
|
3678
|
+
onBadgeClickSwallow(event) {
|
|
3679
|
+
event.preventDefault();
|
|
3680
|
+
event.stopPropagation();
|
|
3664
3681
|
}
|
|
3665
3682
|
// ── Badge context menu ───────────────────────────────────
|
|
3666
3683
|
onBadgeContextMenu(event, type, ix) {
|
|
@@ -3876,11 +3893,11 @@ class OverlayComponent {
|
|
|
3876
3893
|
return `polygon(evenodd, 0px 0px, ${w}px 0px, ${w}px ${h}px, 0px ${h}px, 0px 0px, ${x1}px ${y1}px, ${x2}px ${y1}px, ${x2}px ${y2}px, ${x1}px ${y2}px, ${x1}px ${y1}px)`;
|
|
3877
3894
|
}
|
|
3878
3895
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: OverlayComponent, deps: [{ token: OverlayService }, { token: ViewportService }, { token: PresetRegistryService }, { token: SymbolRegistryService }, { token: InteractionPresetRegistryService }, { token: InteractionEngineService }, { token: BuilderClipboardService }, { token: StyleRegistryService }, { token: PanelEventService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
3879
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.11", type: OverlayComponent, isStandalone: false, selector: "app-overlay", outputs: { toolbarAction: "toolbarAction" }, ngImport: i0, template: "<div class=\"overlay-root\">\n\n <!-- HOVER \u2014 Chrome DevTools-style rings (content area stays transparent) -->\n <ng-container *ngIf=\"hoverEntry\">\n <div class=\"hi-outline\" [ngStyle]=\"hiOutlineStyle\"></div>\n <div class=\"hi-margin\" [ngStyle]=\"hiMarginStyle\"></div>\n <div class=\"hi-padding\" [ngStyle]=\"hiPaddingStyle\"></div>\n </ng-container>\n\n <!-- SELECT \u2014 IOX pink outline + toolbar -->\n <div class=\"select-outline\" *ngIf=\"selectEntry\" [ngStyle]=\"selectOutlineStyle\">\n\n <!-- Preset badges container \u2014 below the outline, start-aligned -->\n <div class=\"preset-badge\" *ngIf=\"selectedPresetName || interactions.length\">\n <div *ngIf=\"selectedPresetName\"\n class=\"preset-badge__item\"\n [class.preset-badge__item--active]=\"activeBadgeType === 'style'\"\n title=\"Style preset: {{ selectedPresetName }} \u2014 click to edit, right-click to copy\"\n (mousedown)=\"onEditPreset($event)\"\n (contextmenu)=\"onBadgeContextMenu($event, 'style')\">\n <i class=\"ph-fill ph-paint-bucket\"></i>\n <span>{{ selectedPresetName }}</span>\n </div>\n <div *ngFor=\"let ix of interactions\"\n class=\"preset-badge__item preset-badge__item--interaction\"\n [class.preset-badge__item--active]=\"activeBadgeType === 'interaction'\"\n [title]=\"triggerLabel(ix.trigger) + ': ' + actionLabel(ix) + ' \u2014 click to edit, right-click to remove'\"\n (mousedown)=\"onEditInteractionPreset($event)\"\n (contextmenu)=\"onBadgeContextMenu($event, 'interaction', ix)\">\n <i [class]=\"triggerIcon(ix.trigger)\"></i>\n <span>{{ triggerLabel(ix.trigger) }}: {{ actionLabel(ix) }}</span>\n </div>\n </div>\n\n <div class=\"select-toolbar\" (click)=\"$event.stopPropagation()\" (mousedown)=\"$event.stopPropagation()\">\n\n <!-- Component name -->\n <span class=\"toolbar-name\">{{ selectEntry?.componentName }}</span>\n <span class=\"toolbar-sep\"></span>\n\n <!-- Quick actions -->\n <button *ngIf=\"isSliderContainer\" class=\"toolbar-btn toolbar-btn--add-slide\" title=\"Add slide\" (mousedown)=\"onAddSlide($event)\">\n <i class=\"ph-thin ph-plus\"></i>\n <span class=\"toolbar-btn__label\">Add slide</span>\n </button>\n <button class=\"toolbar-btn\" title=\"Duplicate\" (mousedown)=\"onDuplicate($event)\">\n <i class=\"ph-thin ph-copy\"></i>\n </button>\n <button *ngIf=\"hasInteractions\" class=\"toolbar-btn toolbar-btn--play\" title=\"Play animations\" (mousedown)=\"onPlay($event)\">\n <i class=\"ph-thin ph-play\"></i>\n </button>\n <button *ngIf=\"isLinkedSymbol\" class=\"toolbar-btn toolbar-btn--symbol\"\n [title]=\"(linkedSymbolName ? linkedSymbolName : 'Symbol') + ' \u2014 click to detach'\"\n (mousedown)=\"onDetachSymbol($event)\">\n <i class=\"ph-thin ph-link\"></i>\n <span class=\"toolbar-btn__label\">{{ linkedSymbolName || 'Symbol' }}</span>\n </button>\n <button *ngIf=\"isDetachedSymbol\" class=\"toolbar-btn toolbar-btn--resync\"\n title=\"Detached \u2014 click to re-link\"\n (mousedown)=\"onResyncSymbol($event)\">\n <i class=\"ph-thin ph-link-break\"></i>\n <span class=\"toolbar-btn__label\">Detached</span>\n </button>\n <button class=\"toolbar-btn toolbar-btn--danger\" title=\"Delete\" (mousedown)=\"onDelete($event)\">\n <i class=\"ph-thin ph-trash\"></i>\n </button>\n <span class=\"toolbar-sep\"></span>\n <button class=\"toolbar-btn\" title=\"Select parent\" (mousedown)=\"onSelectParent($event)\">\n <i class=\"ph-thin ph-arrow-up\"></i>\n </button>\n\n <!-- More menu trigger \u2014 opens a fixed-position dropdown at the cursor -->\n <button class=\"toolbar-btn toolbar-btn--more\" title=\"More actions\" (mousedown)=\"onToggleMore($event)\">\n <i class=\"ph-thin ph-dots-three\"></i>\n </button>\n </div>\n </div>\n\n <!-- Shared more/context menu \u2014 fixed-position, opened by \u22EF button or right-click -->\n <div *ngIf=\"moreMenuVisible\" class=\"toolbar-more-dropdown\" [ngStyle]=\"moreMenuStyle\"\n (click)=\"$event.stopPropagation()\" (mousedown)=\"$event.stopPropagation()\">\n <button class=\"more-item\" (mousedown)=\"onSelectParent($event); closeMoreMenu()\">\n <i class=\"ph-thin ph-arrow-up\"></i>\n Select parent\n </button>\n <button class=\"more-item\" (mousedown)=\"onDuplicate($event); closeMoreMenu()\">\n <i class=\"ph-thin ph-copy\"></i>\n Duplicate\n </button>\n <button class=\"more-item more-item--danger\" (mousedown)=\"onDelete($event); closeMoreMenu()\">\n <i class=\"ph-thin ph-trash\"></i>\n Delete\n </button>\n <div class=\"more-divider\"></div>\n <button class=\"more-item\" (mousedown)=\"onCopyNode($event)\">\n <i class=\"ph-thin ph-scissors\"></i>\n Copy element\n </button>\n <button *ngIf=\"hasCopiedNode\" class=\"more-item\" (mousedown)=\"onPasteNode($event)\">\n <i class=\"ph-thin ph-clipboard\"></i>\n Paste element\n </button>\n <div class=\"more-divider\"></div>\n <button *ngIf=\"selectEntry?.node?.stylePresetId\" class=\"more-item\" (mousedown)=\"onCopyPreset($event)\">\n <i class=\"ph-thin ph-paint-bucket\"></i>\n Copy style preset\n </button>\n <button *ngIf=\"hasPresetInClipboard\" class=\"more-item\" (mousedown)=\"onPastePreset($event)\">\n <i class=\"ph-thin ph-paint-bucket\"></i>\n Paste style preset\n </button>\n <button *ngIf=\"selectEntry?.node?.interactionPresetId\" class=\"more-item\" (mousedown)=\"onCopyInteractionPreset($event)\">\n <i class=\"ph-thin ph-lightning\"></i>\n Copy interaction preset\n </button>\n <button *ngIf=\"hasInteractionPresetInClipboard\" class=\"more-item\" (mousedown)=\"onPasteInteractionPreset($event)\">\n <i class=\"ph-thin ph-lightning\"></i>\n Paste interaction preset\n </button>\n <div class=\"more-divider\"></div>\n <button *ngIf=\"isLinkedSymbol\" class=\"more-item\" (mousedown)=\"onDetachSymbol($event); closeMoreMenu()\">\n <i class=\"ph-thin ph-link-break\"></i>\n Detach from symbol<ng-container *ngIf=\"linkedSymbolName\"> ({{ linkedSymbolName }})</ng-container>\n </button>\n <button *ngIf=\"isDetachedSymbol\" class=\"more-item more-item--resync\" (mousedown)=\"onResyncSymbol($event); closeMoreMenu()\">\n <i class=\"ph-thin ph-link\"></i>\n Re-link to symbol\n </button>\n <button class=\"more-item\" (mousedown)=\"onSaveAsBlock($event); closeMoreMenu()\">\n <i class=\"ph-thin ph-bookmark\"></i>\n Save as reusable block\n </button>\n <button *ngIf=\"hasInteractions\" class=\"more-item more-item--play\" (mousedown)=\"onPlay($event); closeMoreMenu()\">\n <i class=\"ph-thin ph-play\"></i>\n Play animations\n </button>\n <div class=\"more-divider\"></div>\n <ng-container *ngIf=\"!selectedNodeIsGlobal; else removeGlobalItem\">\n <button class=\"more-item\" (mousedown)=\"onMakeGlobal($event, 'before')\">\n <i class=\"ph-thin ph-globe\"></i>\n Make Global (Before Content)\n </button>\n <button class=\"more-item\" (mousedown)=\"onMakeGlobal($event, 'after')\">\n <i class=\"ph-thin ph-globe\"></i>\n Make Global (After Content)\n </button>\n </ng-container>\n <ng-template #removeGlobalItem>\n <button class=\"more-item\" (mousedown)=\"onRemoveGlobal($event)\">\n <i class=\"ph-thin ph-globe\"></i>\n Remove from Global\n </button>\n </ng-template>\n </div>\n\n <!-- Backdrop to close the more menu -->\n <div *ngIf=\"moreMenuVisible\" class=\"overlay-context-backdrop\"\n (mousedown)=\"closeMoreMenu()\">\n </div>\n\n <!-- Badge context menu \u2014 options differ by badge type -->\n <div *ngIf=\"badgeMenuVisible\" class=\"badge-context-menu\"\n [ngStyle]=\"{ top: badgeMenuPos.y + 'px', left: badgeMenuPos.x + 'px' }\"\n (click)=\"$event.stopPropagation()\" (mousedown)=\"$event.stopPropagation()\">\n <ng-container *ngIf=\"badgeMenuType === 'style'\">\n <button class=\"more-item\" (mousedown)=\"onBadgeCopy()\">\n <i class=\"ph-thin ph-copy\"></i>\n Copy preset\n </button>\n <button class=\"more-item\" (mousedown)=\"onBadgeEdit()\">\n <i class=\"ph-thin ph-pencil-simple\"></i>\n Edit preset\n </button>\n </ng-container>\n <ng-container *ngIf=\"badgeMenuType === 'interaction'\">\n <button class=\"more-item\" (mousedown)=\"onBadgeEdit()\">\n <i class=\"ph-thin ph-pencil-simple\"></i>\n Edit in panel\n </button>\n <button class=\"more-item more-item--danger\" (mousedown)=\"onBadgeRemoveInteraction()\">\n <i class=\"ph-thin ph-trash\"></i>\n Remove interaction\n </button>\n </ng-container>\n </div>\n <div *ngIf=\"badgeMenuVisible\" class=\"overlay-context-backdrop\"\n (mousedown)=\"closeBadgeMenu()\">\n </div>\n\n</div>\n", styles: [":host{display:block;position:absolute;inset:0;pointer-events:none;z-index:12;overflow:visible}.hi-outline,.hi-margin,.hi-padding{position:fixed;pointer-events:none;transition:none;box-sizing:border-box}.hi-outline{box-shadow:inset 0 0 0 1.5px #cb9090}.hi-margin{background:#f6b23361}.hi-padding{background:#60c38366}.select-outline{position:fixed;z-index:999;box-shadow:inset 0 0 0 1px #cb9090;pointer-events:none;transition:none;overflow:visible;will-change:transform;box-sizing:border-box}.select-toolbar{position:absolute;top:0;left:0;transform:translateY(-100%);display:flex;align-items:center;background:#cb9090;border-radius:3px 3px 0 0;pointer-events:all;white-space:nowrap;overflow:visible}.select-toolbar .toolbar-name{padding:0 8px;font-size:11px;font-weight:500;color:#fff;max-width:120px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;line-height:22px}.select-toolbar .toolbar-sep{width:1px;height:14px;background:#ffffff59;margin:0 2px;flex-shrink:0}.select-toolbar .toolbar-btn{display:flex;align-items:center;justify-content:center;width:24px;height:22px;padding:0;border:none;background:transparent;color:#fff;font-size:13px;cursor:pointer;transition:background .15s;flex-shrink:0}.select-toolbar .toolbar-btn:hover{background:#ffffff2e}.select-toolbar .toolbar-btn--danger:hover{background:#c8323259}.select-toolbar .toolbar-btn--symbol{width:auto;padding:0 7px;gap:4px;color:#fff;background:#f59e0b;border-radius:3px;font-size:11px}.select-toolbar .toolbar-btn--symbol:hover{background:#d97706}.select-toolbar .toolbar-btn--resync{width:auto;padding:0 7px;gap:4px;color:#fff;background:#22c55e;border-radius:3px;font-size:11px}.select-toolbar .toolbar-btn--resync:hover{background:#16a34a}.select-toolbar .toolbar-btn .toolbar-btn__label{font-size:11px;max-width:90px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.select-toolbar .toolbar-btn--more{border-radius:0 3px 0 0}.toolbar-more-dropdown{position:fixed;z-index:1000;background:#fff;border:1px solid var(--p-surface-200, #e5e7eb);border-radius:6px;box-shadow:0 4px 16px #0000001f;padding:4px 0;min-width:200px;pointer-events:all}.toolbar-more-dropdown .more-item{display:flex;align-items:center;gap:8px;width:100%;padding:8px 14px;border:none;background:transparent;font-size:13px;color:var(--p-text-color, #333);cursor:pointer;text-align:left;white-space:nowrap}.toolbar-more-dropdown .more-item i{font-size:14px}.toolbar-more-dropdown .more-item:hover{background:var(--p-surface-100, #f5f5f5)}.toolbar-more-dropdown .more-item--danger{color:#c84040}.toolbar-more-dropdown .more-item--danger:hover{background:#c8404014}.toolbar-more-dropdown .more-item--play{color:var(--p-text-color, #333)}.toolbar-more-dropdown .more-item--resync{color:#22c55e}.toolbar-more-dropdown .more-item--resync:hover{background:#22c55e14}.toolbar-more-dropdown .more-divider{height:1px;background:var(--p-surface-200, #e5e7eb);margin:4px 0}.preset-badge{position:absolute;bottom:-26px;inset-inline-start:0;display:flex;align-items:center;gap:4px;pointer-events:none;white-space:nowrap}.preset-badge__item{display:flex;align-items:center;gap:5px;padding:3px 9px;background:#cb9090;color:#fff;font-size:11px;font-weight:500;border-radius:20px;pointer-events:all;cursor:pointer;box-shadow:0 2px 6px #0000002e;transition:background .15s,outline-color .15s;outline:2px solid transparent;outline-offset:2px}.preset-badge__item i{font-size:12px}.preset-badge__item:hover{background:#be7474}.preset-badge__item--active{outline-color:#ffffffd9}.preset-badge__item--interaction{background:#7a9ecb}.preset-badge__item--interaction:hover{background:#5d89c0}.badge-context-menu{position:fixed;z-index:1001;background:#fff;border:1px solid var(--p-surface-200, #e5e7eb);border-radius:6px;box-shadow:0 4px 16px #0000001f;padding:4px 0;min-width:160px;pointer-events:all}.badge-context-menu .more-item{display:flex;align-items:center;gap:8px;width:100%;padding:7px 14px;border:none;background:transparent;font-size:12px;color:#333;cursor:pointer;text-align:start;white-space:nowrap}.badge-context-menu .more-item:hover{background:var(--p-surface-50, #f9fafb)}.badge-context-menu .more-item i{font-size:13px;color:#888}.overlay-context-backdrop{position:fixed;inset:0;z-index:998;pointer-events:all}\n"], dependencies: [{ 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"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
3896
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.11", type: OverlayComponent, isStandalone: false, selector: "app-overlay", outputs: { toolbarAction: "toolbarAction" }, ngImport: i0, template: "<div class=\"overlay-root\">\n\n <!-- HOVER \u2014 Chrome DevTools-style rings (content area stays transparent) -->\n <ng-container *ngIf=\"hoverEntry\">\n <div class=\"hi-outline\" [ngStyle]=\"hiOutlineStyle\"></div>\n <div class=\"hi-margin\" [ngStyle]=\"hiMarginStyle\"></div>\n <div class=\"hi-padding\" [ngStyle]=\"hiPaddingStyle\"></div>\n </ng-container>\n\n <!-- SELECT \u2014 IOX pink outline + toolbar -->\n <div class=\"select-outline\" *ngIf=\"selectEntry\" [ngStyle]=\"selectOutlineStyle\">\n\n <!-- Preset badges container \u2014 below the outline, start-aligned -->\n <div class=\"preset-badge\" *ngIf=\"selectedPresetName || interactions.length\">\n <div *ngIf=\"selectedPresetName\"\n class=\"preset-badge__item\"\n [class.preset-badge__item--active]=\"activeBadgeType === 'style'\"\n title=\"Style preset: {{ selectedPresetName }} \u2014 click to edit, right-click to copy\"\n (mousedown)=\"onEditPreset($event)\"\n (contextmenu)=\"onBadgeContextMenu($event, 'style')\">\n <i class=\"ph-fill ph-paint-bucket\"></i>\n <span>{{ selectedPresetName }}</span>\n </div>\n <div *ngFor=\"let ix of interactions\"\n class=\"preset-badge__item preset-badge__item--interaction\"\n [class.preset-badge__item--active]=\"activeBadgeType === 'interaction'\"\n [title]=\"triggerLabel(ix.trigger) + ': ' + actionLabel(ix) + ' \u2014 click to edit, right-click to remove'\"\n (mousedown)=\"onEditInteractionPreset($event, ix)\"\n (click)=\"onBadgeClickSwallow($event)\"\n (contextmenu)=\"onBadgeContextMenu($event, 'interaction', ix)\">\n <i [class]=\"triggerIcon(ix.trigger)\"></i>\n <span>{{ triggerLabel(ix.trigger) }}: {{ actionLabel(ix) }}</span>\n </div>\n </div>\n\n <div class=\"select-toolbar\" (click)=\"$event.stopPropagation()\" (mousedown)=\"$event.stopPropagation()\">\n\n <!-- Component name -->\n <span class=\"toolbar-name\">{{ selectEntry?.componentName }}</span>\n <span class=\"toolbar-sep\"></span>\n\n <!-- Quick actions -->\n <button *ngIf=\"isSliderContainer\" class=\"toolbar-btn toolbar-btn--add-slide\" title=\"Add slide\" (mousedown)=\"onAddSlide($event)\">\n <i class=\"ph-thin ph-plus\"></i>\n <span class=\"toolbar-btn__label\">Add slide</span>\n </button>\n <button class=\"toolbar-btn\" title=\"Duplicate\" (mousedown)=\"onDuplicate($event)\">\n <i class=\"ph-thin ph-copy\"></i>\n </button>\n <button *ngIf=\"hasInteractions\" class=\"toolbar-btn toolbar-btn--play\" title=\"Play animations\" (mousedown)=\"onPlay($event)\">\n <i class=\"ph-thin ph-play\"></i>\n </button>\n <button *ngIf=\"isLinkedSymbol\" class=\"toolbar-btn toolbar-btn--symbol\"\n [title]=\"(linkedSymbolName ? linkedSymbolName : 'Symbol') + ' \u2014 click to detach'\"\n (mousedown)=\"onDetachSymbol($event)\">\n <i class=\"ph-thin ph-link\"></i>\n <span class=\"toolbar-btn__label\">{{ linkedSymbolName || 'Symbol' }}</span>\n </button>\n <button *ngIf=\"isDetachedSymbol\" class=\"toolbar-btn toolbar-btn--resync\"\n title=\"Detached \u2014 click to re-link\"\n (mousedown)=\"onResyncSymbol($event)\">\n <i class=\"ph-thin ph-link-break\"></i>\n <span class=\"toolbar-btn__label\">Detached</span>\n </button>\n <button class=\"toolbar-btn toolbar-btn--danger\" title=\"Delete\" (mousedown)=\"onDelete($event)\">\n <i class=\"ph-thin ph-trash\"></i>\n </button>\n <span class=\"toolbar-sep\"></span>\n <button class=\"toolbar-btn\" title=\"Select parent\" (mousedown)=\"onSelectParent($event)\">\n <i class=\"ph-thin ph-arrow-up\"></i>\n </button>\n\n <!-- More menu trigger \u2014 opens a fixed-position dropdown at the cursor -->\n <button class=\"toolbar-btn toolbar-btn--more\" title=\"More actions\" (mousedown)=\"onToggleMore($event)\">\n <i class=\"ph-thin ph-dots-three\"></i>\n </button>\n </div>\n </div>\n\n <!-- Shared more/context menu \u2014 fixed-position, opened by \u22EF button or right-click -->\n <div *ngIf=\"moreMenuVisible\" class=\"toolbar-more-dropdown\" [ngStyle]=\"moreMenuStyle\"\n (click)=\"$event.stopPropagation()\" (mousedown)=\"$event.stopPropagation()\">\n <button class=\"more-item\" (mousedown)=\"onSelectParent($event); closeMoreMenu()\">\n <i class=\"ph-thin ph-arrow-up\"></i>\n Select parent\n </button>\n <button class=\"more-item\" (mousedown)=\"onDuplicate($event); closeMoreMenu()\">\n <i class=\"ph-thin ph-copy\"></i>\n Duplicate\n </button>\n <button class=\"more-item more-item--danger\" (mousedown)=\"onDelete($event); closeMoreMenu()\">\n <i class=\"ph-thin ph-trash\"></i>\n Delete\n </button>\n <div class=\"more-divider\"></div>\n <button class=\"more-item\" (mousedown)=\"onCopyNode($event)\">\n <i class=\"ph-thin ph-scissors\"></i>\n Copy element\n </button>\n <button *ngIf=\"hasCopiedNode\" class=\"more-item\" (mousedown)=\"onPasteNode($event)\">\n <i class=\"ph-thin ph-clipboard\"></i>\n Paste element\n </button>\n <div class=\"more-divider\"></div>\n <button *ngIf=\"selectEntry?.node?.stylePresetId\" class=\"more-item\" (mousedown)=\"onCopyPreset($event)\">\n <i class=\"ph-thin ph-paint-bucket\"></i>\n Copy style preset\n </button>\n <button *ngIf=\"hasPresetInClipboard\" class=\"more-item\" (mousedown)=\"onPastePreset($event)\">\n <i class=\"ph-thin ph-paint-bucket\"></i>\n Paste style preset\n </button>\n <button *ngIf=\"selectEntry?.node?.interactionPresetId\" class=\"more-item\" (mousedown)=\"onCopyInteractionPreset($event)\">\n <i class=\"ph-thin ph-lightning\"></i>\n Copy interaction preset\n </button>\n <button *ngIf=\"hasInteractionPresetInClipboard\" class=\"more-item\" (mousedown)=\"onPasteInteractionPreset($event)\">\n <i class=\"ph-thin ph-lightning\"></i>\n Paste interaction preset\n </button>\n <div class=\"more-divider\"></div>\n <button *ngIf=\"isLinkedSymbol\" class=\"more-item\" (mousedown)=\"onDetachSymbol($event); closeMoreMenu()\">\n <i class=\"ph-thin ph-link-break\"></i>\n Detach from symbol<ng-container *ngIf=\"linkedSymbolName\"> ({{ linkedSymbolName }})</ng-container>\n </button>\n <button *ngIf=\"isDetachedSymbol\" class=\"more-item more-item--resync\" (mousedown)=\"onResyncSymbol($event); closeMoreMenu()\">\n <i class=\"ph-thin ph-link\"></i>\n Re-link to symbol\n </button>\n <button class=\"more-item\" (mousedown)=\"onSaveAsBlock($event); closeMoreMenu()\">\n <i class=\"ph-thin ph-bookmark\"></i>\n Save as reusable block\n </button>\n <button *ngIf=\"hasInteractions\" class=\"more-item more-item--play\" (mousedown)=\"onPlay($event); closeMoreMenu()\">\n <i class=\"ph-thin ph-play\"></i>\n Play animations\n </button>\n <div class=\"more-divider\"></div>\n <ng-container *ngIf=\"!selectedNodeIsGlobal; else removeGlobalItem\">\n <button class=\"more-item\" (mousedown)=\"onMakeGlobal($event, 'before')\">\n <i class=\"ph-thin ph-globe\"></i>\n Make Global (Before Content)\n </button>\n <button class=\"more-item\" (mousedown)=\"onMakeGlobal($event, 'after')\">\n <i class=\"ph-thin ph-globe\"></i>\n Make Global (After Content)\n </button>\n </ng-container>\n <ng-template #removeGlobalItem>\n <button class=\"more-item\" (mousedown)=\"onRemoveGlobal($event)\">\n <i class=\"ph-thin ph-globe\"></i>\n Remove from Global\n </button>\n </ng-template>\n </div>\n\n <!-- Backdrop to close the more menu -->\n <div *ngIf=\"moreMenuVisible\" class=\"overlay-context-backdrop\"\n (mousedown)=\"closeMoreMenu()\">\n </div>\n\n <!-- Badge context menu \u2014 options differ by badge type -->\n <div *ngIf=\"badgeMenuVisible\" class=\"badge-context-menu\"\n [ngStyle]=\"{ top: badgeMenuPos.y + 'px', left: badgeMenuPos.x + 'px' }\"\n (click)=\"$event.stopPropagation()\" (mousedown)=\"$event.stopPropagation()\">\n <ng-container *ngIf=\"badgeMenuType === 'style'\">\n <button class=\"more-item\" (mousedown)=\"onBadgeCopy()\">\n <i class=\"ph-thin ph-copy\"></i>\n Copy preset\n </button>\n <button class=\"more-item\" (mousedown)=\"onBadgeEdit()\">\n <i class=\"ph-thin ph-pencil-simple\"></i>\n Edit preset\n </button>\n </ng-container>\n <ng-container *ngIf=\"badgeMenuType === 'interaction'\">\n <button class=\"more-item\" (mousedown)=\"onBadgeEdit()\">\n <i class=\"ph-thin ph-pencil-simple\"></i>\n Edit in panel\n </button>\n <button class=\"more-item more-item--danger\" (mousedown)=\"onBadgeRemoveInteraction()\">\n <i class=\"ph-thin ph-trash\"></i>\n Remove interaction\n </button>\n </ng-container>\n </div>\n <div *ngIf=\"badgeMenuVisible\" class=\"overlay-context-backdrop\"\n (mousedown)=\"closeBadgeMenu()\">\n </div>\n\n</div>\n", styles: [":host{display:block;position:absolute;inset:0;pointer-events:none;z-index:12;overflow:visible}.hi-outline,.hi-margin,.hi-padding{position:fixed;pointer-events:none;transition:none;box-sizing:border-box}.hi-outline{box-shadow:inset 0 0 0 1.5px #cb9090}.hi-margin{background:#f6b23361}.hi-padding{background:#60c38366}.select-outline{position:fixed;z-index:999;box-shadow:inset 0 0 0 1px #cb9090;pointer-events:none;transition:none;overflow:visible;will-change:transform;box-sizing:border-box}.select-toolbar{position:absolute;top:0;left:0;transform:translateY(-100%);display:flex;align-items:center;background:#cb9090;border-radius:3px 3px 0 0;pointer-events:all;white-space:nowrap;overflow:visible}.select-toolbar .toolbar-name{padding:0 8px;font-size:11px;font-weight:500;color:#fff;max-width:120px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;line-height:22px}.select-toolbar .toolbar-sep{width:1px;height:14px;background:#ffffff59;margin:0 2px;flex-shrink:0}.select-toolbar .toolbar-btn{display:flex;align-items:center;justify-content:center;width:24px;height:22px;padding:0;border:none;background:transparent;color:#fff;font-size:13px;cursor:pointer;transition:background .15s;flex-shrink:0}.select-toolbar .toolbar-btn:hover{background:#ffffff2e}.select-toolbar .toolbar-btn--danger:hover{background:#c8323259}.select-toolbar .toolbar-btn--symbol{width:auto;padding:0 7px;gap:4px;color:#fff;background:#f59e0b;border-radius:3px;font-size:11px}.select-toolbar .toolbar-btn--symbol:hover{background:#d97706}.select-toolbar .toolbar-btn--resync{width:auto;padding:0 7px;gap:4px;color:#fff;background:#22c55e;border-radius:3px;font-size:11px}.select-toolbar .toolbar-btn--resync:hover{background:#16a34a}.select-toolbar .toolbar-btn .toolbar-btn__label{font-size:11px;max-width:90px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.select-toolbar .toolbar-btn--more{border-radius:0 3px 0 0}.toolbar-more-dropdown{position:fixed;z-index:1000;background:#fff;border:1px solid var(--p-surface-200, #e5e7eb);border-radius:6px;box-shadow:0 4px 16px #0000001f;padding:4px 0;min-width:200px;pointer-events:all}.toolbar-more-dropdown .more-item{display:flex;align-items:center;gap:8px;width:100%;padding:8px 14px;border:none;background:transparent;font-size:13px;color:var(--p-text-color, #333);cursor:pointer;text-align:left;white-space:nowrap}.toolbar-more-dropdown .more-item i{font-size:14px}.toolbar-more-dropdown .more-item:hover{background:var(--p-surface-100, #f5f5f5)}.toolbar-more-dropdown .more-item--danger{color:#c84040}.toolbar-more-dropdown .more-item--danger:hover{background:#c8404014}.toolbar-more-dropdown .more-item--play{color:var(--p-text-color, #333)}.toolbar-more-dropdown .more-item--resync{color:#22c55e}.toolbar-more-dropdown .more-item--resync:hover{background:#22c55e14}.toolbar-more-dropdown .more-divider{height:1px;background:var(--p-surface-200, #e5e7eb);margin:4px 0}.preset-badge{position:absolute;bottom:-26px;inset-inline-start:0;display:flex;align-items:center;gap:4px;pointer-events:none;white-space:nowrap}.preset-badge__item{display:flex;align-items:center;gap:5px;padding:3px 9px;background:#cb9090;color:#fff;font-size:11px;font-weight:500;border-radius:20px;pointer-events:all;cursor:pointer;box-shadow:0 2px 6px #0000002e;transition:background .15s,outline-color .15s;outline:2px solid transparent;outline-offset:2px}.preset-badge__item i{font-size:12px}.preset-badge__item:hover{background:#be7474}.preset-badge__item--active{outline-color:#ffffffd9}.preset-badge__item--interaction{background:#7a9ecb}.preset-badge__item--interaction:hover{background:#5d89c0}.badge-context-menu{position:fixed;z-index:1001;background:#fff;border:1px solid var(--p-surface-200, #e5e7eb);border-radius:6px;box-shadow:0 4px 16px #0000001f;padding:4px 0;min-width:160px;pointer-events:all}.badge-context-menu .more-item{display:flex;align-items:center;gap:8px;width:100%;padding:7px 14px;border:none;background:transparent;font-size:12px;color:#333;cursor:pointer;text-align:start;white-space:nowrap}.badge-context-menu .more-item:hover{background:var(--p-surface-50, #f9fafb)}.badge-context-menu .more-item i{font-size:13px;color:#888}.overlay-context-backdrop{position:fixed;inset:0;z-index:998;pointer-events:all}\n"], dependencies: [{ 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"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
3880
3897
|
}
|
|
3881
3898
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: OverlayComponent, decorators: [{
|
|
3882
3899
|
type: Component,
|
|
3883
|
-
args: [{ selector: 'app-overlay', standalone: false, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"overlay-root\">\n\n <!-- HOVER \u2014 Chrome DevTools-style rings (content area stays transparent) -->\n <ng-container *ngIf=\"hoverEntry\">\n <div class=\"hi-outline\" [ngStyle]=\"hiOutlineStyle\"></div>\n <div class=\"hi-margin\" [ngStyle]=\"hiMarginStyle\"></div>\n <div class=\"hi-padding\" [ngStyle]=\"hiPaddingStyle\"></div>\n </ng-container>\n\n <!-- SELECT \u2014 IOX pink outline + toolbar -->\n <div class=\"select-outline\" *ngIf=\"selectEntry\" [ngStyle]=\"selectOutlineStyle\">\n\n <!-- Preset badges container \u2014 below the outline, start-aligned -->\n <div class=\"preset-badge\" *ngIf=\"selectedPresetName || interactions.length\">\n <div *ngIf=\"selectedPresetName\"\n class=\"preset-badge__item\"\n [class.preset-badge__item--active]=\"activeBadgeType === 'style'\"\n title=\"Style preset: {{ selectedPresetName }} \u2014 click to edit, right-click to copy\"\n (mousedown)=\"onEditPreset($event)\"\n (contextmenu)=\"onBadgeContextMenu($event, 'style')\">\n <i class=\"ph-fill ph-paint-bucket\"></i>\n <span>{{ selectedPresetName }}</span>\n </div>\n <div *ngFor=\"let ix of interactions\"\n class=\"preset-badge__item preset-badge__item--interaction\"\n [class.preset-badge__item--active]=\"activeBadgeType === 'interaction'\"\n [title]=\"triggerLabel(ix.trigger) + ': ' + actionLabel(ix) + ' \u2014 click to edit, right-click to remove'\"\n (mousedown)=\"onEditInteractionPreset($event)\"\n (contextmenu)=\"onBadgeContextMenu($event, 'interaction', ix)\">\n <i [class]=\"triggerIcon(ix.trigger)\"></i>\n <span>{{ triggerLabel(ix.trigger) }}: {{ actionLabel(ix) }}</span>\n </div>\n </div>\n\n <div class=\"select-toolbar\" (click)=\"$event.stopPropagation()\" (mousedown)=\"$event.stopPropagation()\">\n\n <!-- Component name -->\n <span class=\"toolbar-name\">{{ selectEntry?.componentName }}</span>\n <span class=\"toolbar-sep\"></span>\n\n <!-- Quick actions -->\n <button *ngIf=\"isSliderContainer\" class=\"toolbar-btn toolbar-btn--add-slide\" title=\"Add slide\" (mousedown)=\"onAddSlide($event)\">\n <i class=\"ph-thin ph-plus\"></i>\n <span class=\"toolbar-btn__label\">Add slide</span>\n </button>\n <button class=\"toolbar-btn\" title=\"Duplicate\" (mousedown)=\"onDuplicate($event)\">\n <i class=\"ph-thin ph-copy\"></i>\n </button>\n <button *ngIf=\"hasInteractions\" class=\"toolbar-btn toolbar-btn--play\" title=\"Play animations\" (mousedown)=\"onPlay($event)\">\n <i class=\"ph-thin ph-play\"></i>\n </button>\n <button *ngIf=\"isLinkedSymbol\" class=\"toolbar-btn toolbar-btn--symbol\"\n [title]=\"(linkedSymbolName ? linkedSymbolName : 'Symbol') + ' \u2014 click to detach'\"\n (mousedown)=\"onDetachSymbol($event)\">\n <i class=\"ph-thin ph-link\"></i>\n <span class=\"toolbar-btn__label\">{{ linkedSymbolName || 'Symbol' }}</span>\n </button>\n <button *ngIf=\"isDetachedSymbol\" class=\"toolbar-btn toolbar-btn--resync\"\n title=\"Detached \u2014 click to re-link\"\n (mousedown)=\"onResyncSymbol($event)\">\n <i class=\"ph-thin ph-link-break\"></i>\n <span class=\"toolbar-btn__label\">Detached</span>\n </button>\n <button class=\"toolbar-btn toolbar-btn--danger\" title=\"Delete\" (mousedown)=\"onDelete($event)\">\n <i class=\"ph-thin ph-trash\"></i>\n </button>\n <span class=\"toolbar-sep\"></span>\n <button class=\"toolbar-btn\" title=\"Select parent\" (mousedown)=\"onSelectParent($event)\">\n <i class=\"ph-thin ph-arrow-up\"></i>\n </button>\n\n <!-- More menu trigger \u2014 opens a fixed-position dropdown at the cursor -->\n <button class=\"toolbar-btn toolbar-btn--more\" title=\"More actions\" (mousedown)=\"onToggleMore($event)\">\n <i class=\"ph-thin ph-dots-three\"></i>\n </button>\n </div>\n </div>\n\n <!-- Shared more/context menu \u2014 fixed-position, opened by \u22EF button or right-click -->\n <div *ngIf=\"moreMenuVisible\" class=\"toolbar-more-dropdown\" [ngStyle]=\"moreMenuStyle\"\n (click)=\"$event.stopPropagation()\" (mousedown)=\"$event.stopPropagation()\">\n <button class=\"more-item\" (mousedown)=\"onSelectParent($event); closeMoreMenu()\">\n <i class=\"ph-thin ph-arrow-up\"></i>\n Select parent\n </button>\n <button class=\"more-item\" (mousedown)=\"onDuplicate($event); closeMoreMenu()\">\n <i class=\"ph-thin ph-copy\"></i>\n Duplicate\n </button>\n <button class=\"more-item more-item--danger\" (mousedown)=\"onDelete($event); closeMoreMenu()\">\n <i class=\"ph-thin ph-trash\"></i>\n Delete\n </button>\n <div class=\"more-divider\"></div>\n <button class=\"more-item\" (mousedown)=\"onCopyNode($event)\">\n <i class=\"ph-thin ph-scissors\"></i>\n Copy element\n </button>\n <button *ngIf=\"hasCopiedNode\" class=\"more-item\" (mousedown)=\"onPasteNode($event)\">\n <i class=\"ph-thin ph-clipboard\"></i>\n Paste element\n </button>\n <div class=\"more-divider\"></div>\n <button *ngIf=\"selectEntry?.node?.stylePresetId\" class=\"more-item\" (mousedown)=\"onCopyPreset($event)\">\n <i class=\"ph-thin ph-paint-bucket\"></i>\n Copy style preset\n </button>\n <button *ngIf=\"hasPresetInClipboard\" class=\"more-item\" (mousedown)=\"onPastePreset($event)\">\n <i class=\"ph-thin ph-paint-bucket\"></i>\n Paste style preset\n </button>\n <button *ngIf=\"selectEntry?.node?.interactionPresetId\" class=\"more-item\" (mousedown)=\"onCopyInteractionPreset($event)\">\n <i class=\"ph-thin ph-lightning\"></i>\n Copy interaction preset\n </button>\n <button *ngIf=\"hasInteractionPresetInClipboard\" class=\"more-item\" (mousedown)=\"onPasteInteractionPreset($event)\">\n <i class=\"ph-thin ph-lightning\"></i>\n Paste interaction preset\n </button>\n <div class=\"more-divider\"></div>\n <button *ngIf=\"isLinkedSymbol\" class=\"more-item\" (mousedown)=\"onDetachSymbol($event); closeMoreMenu()\">\n <i class=\"ph-thin ph-link-break\"></i>\n Detach from symbol<ng-container *ngIf=\"linkedSymbolName\"> ({{ linkedSymbolName }})</ng-container>\n </button>\n <button *ngIf=\"isDetachedSymbol\" class=\"more-item more-item--resync\" (mousedown)=\"onResyncSymbol($event); closeMoreMenu()\">\n <i class=\"ph-thin ph-link\"></i>\n Re-link to symbol\n </button>\n <button class=\"more-item\" (mousedown)=\"onSaveAsBlock($event); closeMoreMenu()\">\n <i class=\"ph-thin ph-bookmark\"></i>\n Save as reusable block\n </button>\n <button *ngIf=\"hasInteractions\" class=\"more-item more-item--play\" (mousedown)=\"onPlay($event); closeMoreMenu()\">\n <i class=\"ph-thin ph-play\"></i>\n Play animations\n </button>\n <div class=\"more-divider\"></div>\n <ng-container *ngIf=\"!selectedNodeIsGlobal; else removeGlobalItem\">\n <button class=\"more-item\" (mousedown)=\"onMakeGlobal($event, 'before')\">\n <i class=\"ph-thin ph-globe\"></i>\n Make Global (Before Content)\n </button>\n <button class=\"more-item\" (mousedown)=\"onMakeGlobal($event, 'after')\">\n <i class=\"ph-thin ph-globe\"></i>\n Make Global (After Content)\n </button>\n </ng-container>\n <ng-template #removeGlobalItem>\n <button class=\"more-item\" (mousedown)=\"onRemoveGlobal($event)\">\n <i class=\"ph-thin ph-globe\"></i>\n Remove from Global\n </button>\n </ng-template>\n </div>\n\n <!-- Backdrop to close the more menu -->\n <div *ngIf=\"moreMenuVisible\" class=\"overlay-context-backdrop\"\n (mousedown)=\"closeMoreMenu()\">\n </div>\n\n <!-- Badge context menu \u2014 options differ by badge type -->\n <div *ngIf=\"badgeMenuVisible\" class=\"badge-context-menu\"\n [ngStyle]=\"{ top: badgeMenuPos.y + 'px', left: badgeMenuPos.x + 'px' }\"\n (click)=\"$event.stopPropagation()\" (mousedown)=\"$event.stopPropagation()\">\n <ng-container *ngIf=\"badgeMenuType === 'style'\">\n <button class=\"more-item\" (mousedown)=\"onBadgeCopy()\">\n <i class=\"ph-thin ph-copy\"></i>\n Copy preset\n </button>\n <button class=\"more-item\" (mousedown)=\"onBadgeEdit()\">\n <i class=\"ph-thin ph-pencil-simple\"></i>\n Edit preset\n </button>\n </ng-container>\n <ng-container *ngIf=\"badgeMenuType === 'interaction'\">\n <button class=\"more-item\" (mousedown)=\"onBadgeEdit()\">\n <i class=\"ph-thin ph-pencil-simple\"></i>\n Edit in panel\n </button>\n <button class=\"more-item more-item--danger\" (mousedown)=\"onBadgeRemoveInteraction()\">\n <i class=\"ph-thin ph-trash\"></i>\n Remove interaction\n </button>\n </ng-container>\n </div>\n <div *ngIf=\"badgeMenuVisible\" class=\"overlay-context-backdrop\"\n (mousedown)=\"closeBadgeMenu()\">\n </div>\n\n</div>\n", styles: [":host{display:block;position:absolute;inset:0;pointer-events:none;z-index:12;overflow:visible}.hi-outline,.hi-margin,.hi-padding{position:fixed;pointer-events:none;transition:none;box-sizing:border-box}.hi-outline{box-shadow:inset 0 0 0 1.5px #cb9090}.hi-margin{background:#f6b23361}.hi-padding{background:#60c38366}.select-outline{position:fixed;z-index:999;box-shadow:inset 0 0 0 1px #cb9090;pointer-events:none;transition:none;overflow:visible;will-change:transform;box-sizing:border-box}.select-toolbar{position:absolute;top:0;left:0;transform:translateY(-100%);display:flex;align-items:center;background:#cb9090;border-radius:3px 3px 0 0;pointer-events:all;white-space:nowrap;overflow:visible}.select-toolbar .toolbar-name{padding:0 8px;font-size:11px;font-weight:500;color:#fff;max-width:120px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;line-height:22px}.select-toolbar .toolbar-sep{width:1px;height:14px;background:#ffffff59;margin:0 2px;flex-shrink:0}.select-toolbar .toolbar-btn{display:flex;align-items:center;justify-content:center;width:24px;height:22px;padding:0;border:none;background:transparent;color:#fff;font-size:13px;cursor:pointer;transition:background .15s;flex-shrink:0}.select-toolbar .toolbar-btn:hover{background:#ffffff2e}.select-toolbar .toolbar-btn--danger:hover{background:#c8323259}.select-toolbar .toolbar-btn--symbol{width:auto;padding:0 7px;gap:4px;color:#fff;background:#f59e0b;border-radius:3px;font-size:11px}.select-toolbar .toolbar-btn--symbol:hover{background:#d97706}.select-toolbar .toolbar-btn--resync{width:auto;padding:0 7px;gap:4px;color:#fff;background:#22c55e;border-radius:3px;font-size:11px}.select-toolbar .toolbar-btn--resync:hover{background:#16a34a}.select-toolbar .toolbar-btn .toolbar-btn__label{font-size:11px;max-width:90px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.select-toolbar .toolbar-btn--more{border-radius:0 3px 0 0}.toolbar-more-dropdown{position:fixed;z-index:1000;background:#fff;border:1px solid var(--p-surface-200, #e5e7eb);border-radius:6px;box-shadow:0 4px 16px #0000001f;padding:4px 0;min-width:200px;pointer-events:all}.toolbar-more-dropdown .more-item{display:flex;align-items:center;gap:8px;width:100%;padding:8px 14px;border:none;background:transparent;font-size:13px;color:var(--p-text-color, #333);cursor:pointer;text-align:left;white-space:nowrap}.toolbar-more-dropdown .more-item i{font-size:14px}.toolbar-more-dropdown .more-item:hover{background:var(--p-surface-100, #f5f5f5)}.toolbar-more-dropdown .more-item--danger{color:#c84040}.toolbar-more-dropdown .more-item--danger:hover{background:#c8404014}.toolbar-more-dropdown .more-item--play{color:var(--p-text-color, #333)}.toolbar-more-dropdown .more-item--resync{color:#22c55e}.toolbar-more-dropdown .more-item--resync:hover{background:#22c55e14}.toolbar-more-dropdown .more-divider{height:1px;background:var(--p-surface-200, #e5e7eb);margin:4px 0}.preset-badge{position:absolute;bottom:-26px;inset-inline-start:0;display:flex;align-items:center;gap:4px;pointer-events:none;white-space:nowrap}.preset-badge__item{display:flex;align-items:center;gap:5px;padding:3px 9px;background:#cb9090;color:#fff;font-size:11px;font-weight:500;border-radius:20px;pointer-events:all;cursor:pointer;box-shadow:0 2px 6px #0000002e;transition:background .15s,outline-color .15s;outline:2px solid transparent;outline-offset:2px}.preset-badge__item i{font-size:12px}.preset-badge__item:hover{background:#be7474}.preset-badge__item--active{outline-color:#ffffffd9}.preset-badge__item--interaction{background:#7a9ecb}.preset-badge__item--interaction:hover{background:#5d89c0}.badge-context-menu{position:fixed;z-index:1001;background:#fff;border:1px solid var(--p-surface-200, #e5e7eb);border-radius:6px;box-shadow:0 4px 16px #0000001f;padding:4px 0;min-width:160px;pointer-events:all}.badge-context-menu .more-item{display:flex;align-items:center;gap:8px;width:100%;padding:7px 14px;border:none;background:transparent;font-size:12px;color:#333;cursor:pointer;text-align:start;white-space:nowrap}.badge-context-menu .more-item:hover{background:var(--p-surface-50, #f9fafb)}.badge-context-menu .more-item i{font-size:13px;color:#888}.overlay-context-backdrop{position:fixed;inset:0;z-index:998;pointer-events:all}\n"] }]
|
|
3900
|
+
args: [{ selector: 'app-overlay', standalone: false, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"overlay-root\">\n\n <!-- HOVER \u2014 Chrome DevTools-style rings (content area stays transparent) -->\n <ng-container *ngIf=\"hoverEntry\">\n <div class=\"hi-outline\" [ngStyle]=\"hiOutlineStyle\"></div>\n <div class=\"hi-margin\" [ngStyle]=\"hiMarginStyle\"></div>\n <div class=\"hi-padding\" [ngStyle]=\"hiPaddingStyle\"></div>\n </ng-container>\n\n <!-- SELECT \u2014 IOX pink outline + toolbar -->\n <div class=\"select-outline\" *ngIf=\"selectEntry\" [ngStyle]=\"selectOutlineStyle\">\n\n <!-- Preset badges container \u2014 below the outline, start-aligned -->\n <div class=\"preset-badge\" *ngIf=\"selectedPresetName || interactions.length\">\n <div *ngIf=\"selectedPresetName\"\n class=\"preset-badge__item\"\n [class.preset-badge__item--active]=\"activeBadgeType === 'style'\"\n title=\"Style preset: {{ selectedPresetName }} \u2014 click to edit, right-click to copy\"\n (mousedown)=\"onEditPreset($event)\"\n (contextmenu)=\"onBadgeContextMenu($event, 'style')\">\n <i class=\"ph-fill ph-paint-bucket\"></i>\n <span>{{ selectedPresetName }}</span>\n </div>\n <div *ngFor=\"let ix of interactions\"\n class=\"preset-badge__item preset-badge__item--interaction\"\n [class.preset-badge__item--active]=\"activeBadgeType === 'interaction'\"\n [title]=\"triggerLabel(ix.trigger) + ': ' + actionLabel(ix) + ' \u2014 click to edit, right-click to remove'\"\n (mousedown)=\"onEditInteractionPreset($event, ix)\"\n (click)=\"onBadgeClickSwallow($event)\"\n (contextmenu)=\"onBadgeContextMenu($event, 'interaction', ix)\">\n <i [class]=\"triggerIcon(ix.trigger)\"></i>\n <span>{{ triggerLabel(ix.trigger) }}: {{ actionLabel(ix) }}</span>\n </div>\n </div>\n\n <div class=\"select-toolbar\" (click)=\"$event.stopPropagation()\" (mousedown)=\"$event.stopPropagation()\">\n\n <!-- Component name -->\n <span class=\"toolbar-name\">{{ selectEntry?.componentName }}</span>\n <span class=\"toolbar-sep\"></span>\n\n <!-- Quick actions -->\n <button *ngIf=\"isSliderContainer\" class=\"toolbar-btn toolbar-btn--add-slide\" title=\"Add slide\" (mousedown)=\"onAddSlide($event)\">\n <i class=\"ph-thin ph-plus\"></i>\n <span class=\"toolbar-btn__label\">Add slide</span>\n </button>\n <button class=\"toolbar-btn\" title=\"Duplicate\" (mousedown)=\"onDuplicate($event)\">\n <i class=\"ph-thin ph-copy\"></i>\n </button>\n <button *ngIf=\"hasInteractions\" class=\"toolbar-btn toolbar-btn--play\" title=\"Play animations\" (mousedown)=\"onPlay($event)\">\n <i class=\"ph-thin ph-play\"></i>\n </button>\n <button *ngIf=\"isLinkedSymbol\" class=\"toolbar-btn toolbar-btn--symbol\"\n [title]=\"(linkedSymbolName ? linkedSymbolName : 'Symbol') + ' \u2014 click to detach'\"\n (mousedown)=\"onDetachSymbol($event)\">\n <i class=\"ph-thin ph-link\"></i>\n <span class=\"toolbar-btn__label\">{{ linkedSymbolName || 'Symbol' }}</span>\n </button>\n <button *ngIf=\"isDetachedSymbol\" class=\"toolbar-btn toolbar-btn--resync\"\n title=\"Detached \u2014 click to re-link\"\n (mousedown)=\"onResyncSymbol($event)\">\n <i class=\"ph-thin ph-link-break\"></i>\n <span class=\"toolbar-btn__label\">Detached</span>\n </button>\n <button class=\"toolbar-btn toolbar-btn--danger\" title=\"Delete\" (mousedown)=\"onDelete($event)\">\n <i class=\"ph-thin ph-trash\"></i>\n </button>\n <span class=\"toolbar-sep\"></span>\n <button class=\"toolbar-btn\" title=\"Select parent\" (mousedown)=\"onSelectParent($event)\">\n <i class=\"ph-thin ph-arrow-up\"></i>\n </button>\n\n <!-- More menu trigger \u2014 opens a fixed-position dropdown at the cursor -->\n <button class=\"toolbar-btn toolbar-btn--more\" title=\"More actions\" (mousedown)=\"onToggleMore($event)\">\n <i class=\"ph-thin ph-dots-three\"></i>\n </button>\n </div>\n </div>\n\n <!-- Shared more/context menu \u2014 fixed-position, opened by \u22EF button or right-click -->\n <div *ngIf=\"moreMenuVisible\" class=\"toolbar-more-dropdown\" [ngStyle]=\"moreMenuStyle\"\n (click)=\"$event.stopPropagation()\" (mousedown)=\"$event.stopPropagation()\">\n <button class=\"more-item\" (mousedown)=\"onSelectParent($event); closeMoreMenu()\">\n <i class=\"ph-thin ph-arrow-up\"></i>\n Select parent\n </button>\n <button class=\"more-item\" (mousedown)=\"onDuplicate($event); closeMoreMenu()\">\n <i class=\"ph-thin ph-copy\"></i>\n Duplicate\n </button>\n <button class=\"more-item more-item--danger\" (mousedown)=\"onDelete($event); closeMoreMenu()\">\n <i class=\"ph-thin ph-trash\"></i>\n Delete\n </button>\n <div class=\"more-divider\"></div>\n <button class=\"more-item\" (mousedown)=\"onCopyNode($event)\">\n <i class=\"ph-thin ph-scissors\"></i>\n Copy element\n </button>\n <button *ngIf=\"hasCopiedNode\" class=\"more-item\" (mousedown)=\"onPasteNode($event)\">\n <i class=\"ph-thin ph-clipboard\"></i>\n Paste element\n </button>\n <div class=\"more-divider\"></div>\n <button *ngIf=\"selectEntry?.node?.stylePresetId\" class=\"more-item\" (mousedown)=\"onCopyPreset($event)\">\n <i class=\"ph-thin ph-paint-bucket\"></i>\n Copy style preset\n </button>\n <button *ngIf=\"hasPresetInClipboard\" class=\"more-item\" (mousedown)=\"onPastePreset($event)\">\n <i class=\"ph-thin ph-paint-bucket\"></i>\n Paste style preset\n </button>\n <button *ngIf=\"selectEntry?.node?.interactionPresetId\" class=\"more-item\" (mousedown)=\"onCopyInteractionPreset($event)\">\n <i class=\"ph-thin ph-lightning\"></i>\n Copy interaction preset\n </button>\n <button *ngIf=\"hasInteractionPresetInClipboard\" class=\"more-item\" (mousedown)=\"onPasteInteractionPreset($event)\">\n <i class=\"ph-thin ph-lightning\"></i>\n Paste interaction preset\n </button>\n <div class=\"more-divider\"></div>\n <button *ngIf=\"isLinkedSymbol\" class=\"more-item\" (mousedown)=\"onDetachSymbol($event); closeMoreMenu()\">\n <i class=\"ph-thin ph-link-break\"></i>\n Detach from symbol<ng-container *ngIf=\"linkedSymbolName\"> ({{ linkedSymbolName }})</ng-container>\n </button>\n <button *ngIf=\"isDetachedSymbol\" class=\"more-item more-item--resync\" (mousedown)=\"onResyncSymbol($event); closeMoreMenu()\">\n <i class=\"ph-thin ph-link\"></i>\n Re-link to symbol\n </button>\n <button class=\"more-item\" (mousedown)=\"onSaveAsBlock($event); closeMoreMenu()\">\n <i class=\"ph-thin ph-bookmark\"></i>\n Save as reusable block\n </button>\n <button *ngIf=\"hasInteractions\" class=\"more-item more-item--play\" (mousedown)=\"onPlay($event); closeMoreMenu()\">\n <i class=\"ph-thin ph-play\"></i>\n Play animations\n </button>\n <div class=\"more-divider\"></div>\n <ng-container *ngIf=\"!selectedNodeIsGlobal; else removeGlobalItem\">\n <button class=\"more-item\" (mousedown)=\"onMakeGlobal($event, 'before')\">\n <i class=\"ph-thin ph-globe\"></i>\n Make Global (Before Content)\n </button>\n <button class=\"more-item\" (mousedown)=\"onMakeGlobal($event, 'after')\">\n <i class=\"ph-thin ph-globe\"></i>\n Make Global (After Content)\n </button>\n </ng-container>\n <ng-template #removeGlobalItem>\n <button class=\"more-item\" (mousedown)=\"onRemoveGlobal($event)\">\n <i class=\"ph-thin ph-globe\"></i>\n Remove from Global\n </button>\n </ng-template>\n </div>\n\n <!-- Backdrop to close the more menu -->\n <div *ngIf=\"moreMenuVisible\" class=\"overlay-context-backdrop\"\n (mousedown)=\"closeMoreMenu()\">\n </div>\n\n <!-- Badge context menu \u2014 options differ by badge type -->\n <div *ngIf=\"badgeMenuVisible\" class=\"badge-context-menu\"\n [ngStyle]=\"{ top: badgeMenuPos.y + 'px', left: badgeMenuPos.x + 'px' }\"\n (click)=\"$event.stopPropagation()\" (mousedown)=\"$event.stopPropagation()\">\n <ng-container *ngIf=\"badgeMenuType === 'style'\">\n <button class=\"more-item\" (mousedown)=\"onBadgeCopy()\">\n <i class=\"ph-thin ph-copy\"></i>\n Copy preset\n </button>\n <button class=\"more-item\" (mousedown)=\"onBadgeEdit()\">\n <i class=\"ph-thin ph-pencil-simple\"></i>\n Edit preset\n </button>\n </ng-container>\n <ng-container *ngIf=\"badgeMenuType === 'interaction'\">\n <button class=\"more-item\" (mousedown)=\"onBadgeEdit()\">\n <i class=\"ph-thin ph-pencil-simple\"></i>\n Edit in panel\n </button>\n <button class=\"more-item more-item--danger\" (mousedown)=\"onBadgeRemoveInteraction()\">\n <i class=\"ph-thin ph-trash\"></i>\n Remove interaction\n </button>\n </ng-container>\n </div>\n <div *ngIf=\"badgeMenuVisible\" class=\"overlay-context-backdrop\"\n (mousedown)=\"closeBadgeMenu()\">\n </div>\n\n</div>\n", styles: [":host{display:block;position:absolute;inset:0;pointer-events:none;z-index:12;overflow:visible}.hi-outline,.hi-margin,.hi-padding{position:fixed;pointer-events:none;transition:none;box-sizing:border-box}.hi-outline{box-shadow:inset 0 0 0 1.5px #cb9090}.hi-margin{background:#f6b23361}.hi-padding{background:#60c38366}.select-outline{position:fixed;z-index:999;box-shadow:inset 0 0 0 1px #cb9090;pointer-events:none;transition:none;overflow:visible;will-change:transform;box-sizing:border-box}.select-toolbar{position:absolute;top:0;left:0;transform:translateY(-100%);display:flex;align-items:center;background:#cb9090;border-radius:3px 3px 0 0;pointer-events:all;white-space:nowrap;overflow:visible}.select-toolbar .toolbar-name{padding:0 8px;font-size:11px;font-weight:500;color:#fff;max-width:120px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;line-height:22px}.select-toolbar .toolbar-sep{width:1px;height:14px;background:#ffffff59;margin:0 2px;flex-shrink:0}.select-toolbar .toolbar-btn{display:flex;align-items:center;justify-content:center;width:24px;height:22px;padding:0;border:none;background:transparent;color:#fff;font-size:13px;cursor:pointer;transition:background .15s;flex-shrink:0}.select-toolbar .toolbar-btn:hover{background:#ffffff2e}.select-toolbar .toolbar-btn--danger:hover{background:#c8323259}.select-toolbar .toolbar-btn--symbol{width:auto;padding:0 7px;gap:4px;color:#fff;background:#f59e0b;border-radius:3px;font-size:11px}.select-toolbar .toolbar-btn--symbol:hover{background:#d97706}.select-toolbar .toolbar-btn--resync{width:auto;padding:0 7px;gap:4px;color:#fff;background:#22c55e;border-radius:3px;font-size:11px}.select-toolbar .toolbar-btn--resync:hover{background:#16a34a}.select-toolbar .toolbar-btn .toolbar-btn__label{font-size:11px;max-width:90px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.select-toolbar .toolbar-btn--more{border-radius:0 3px 0 0}.toolbar-more-dropdown{position:fixed;z-index:1000;background:#fff;border:1px solid var(--p-surface-200, #e5e7eb);border-radius:6px;box-shadow:0 4px 16px #0000001f;padding:4px 0;min-width:200px;pointer-events:all}.toolbar-more-dropdown .more-item{display:flex;align-items:center;gap:8px;width:100%;padding:8px 14px;border:none;background:transparent;font-size:13px;color:var(--p-text-color, #333);cursor:pointer;text-align:left;white-space:nowrap}.toolbar-more-dropdown .more-item i{font-size:14px}.toolbar-more-dropdown .more-item:hover{background:var(--p-surface-100, #f5f5f5)}.toolbar-more-dropdown .more-item--danger{color:#c84040}.toolbar-more-dropdown .more-item--danger:hover{background:#c8404014}.toolbar-more-dropdown .more-item--play{color:var(--p-text-color, #333)}.toolbar-more-dropdown .more-item--resync{color:#22c55e}.toolbar-more-dropdown .more-item--resync:hover{background:#22c55e14}.toolbar-more-dropdown .more-divider{height:1px;background:var(--p-surface-200, #e5e7eb);margin:4px 0}.preset-badge{position:absolute;bottom:-26px;inset-inline-start:0;display:flex;align-items:center;gap:4px;pointer-events:none;white-space:nowrap}.preset-badge__item{display:flex;align-items:center;gap:5px;padding:3px 9px;background:#cb9090;color:#fff;font-size:11px;font-weight:500;border-radius:20px;pointer-events:all;cursor:pointer;box-shadow:0 2px 6px #0000002e;transition:background .15s,outline-color .15s;outline:2px solid transparent;outline-offset:2px}.preset-badge__item i{font-size:12px}.preset-badge__item:hover{background:#be7474}.preset-badge__item--active{outline-color:#ffffffd9}.preset-badge__item--interaction{background:#7a9ecb}.preset-badge__item--interaction:hover{background:#5d89c0}.badge-context-menu{position:fixed;z-index:1001;background:#fff;border:1px solid var(--p-surface-200, #e5e7eb);border-radius:6px;box-shadow:0 4px 16px #0000001f;padding:4px 0;min-width:160px;pointer-events:all}.badge-context-menu .more-item{display:flex;align-items:center;gap:8px;width:100%;padding:7px 14px;border:none;background:transparent;font-size:12px;color:#333;cursor:pointer;text-align:start;white-space:nowrap}.badge-context-menu .more-item:hover{background:var(--p-surface-50, #f9fafb)}.badge-context-menu .more-item i{font-size:13px;color:#888}.overlay-context-backdrop{position:fixed;inset:0;z-index:998;pointer-events:all}\n"] }]
|
|
3884
3901
|
}], ctorParameters: () => [{ type: OverlayService }, { type: ViewportService }, { type: PresetRegistryService }, { type: SymbolRegistryService }, { type: InteractionPresetRegistryService }, { type: InteractionEngineService }, { type: BuilderClipboardService }, { type: StyleRegistryService }, { type: PanelEventService }, { type: i0.ChangeDetectorRef }], propDecorators: { toolbarAction: [{
|
|
3885
3902
|
type: Output
|
|
3886
3903
|
}] } });
|
|
@@ -4907,8 +4924,16 @@ class BuilderComponent {
|
|
|
4907
4924
|
break;
|
|
4908
4925
|
}
|
|
4909
4926
|
case ToolbarAction.EditInteractionPreset: {
|
|
4910
|
-
|
|
4927
|
+
// Preset-linked node → open preset-edit mode. Plain interaction → just open the panel.
|
|
4928
|
+
if (node.interactionPresetId) {
|
|
4929
|
+
this.panelEventService.emit(PanelEventTypes.INTERACTION_PRESET_EDIT, node.interactionPresetId);
|
|
4930
|
+
}
|
|
4911
4931
|
this.panelEventService.emit(this.isPanelOpen ? PanelEventTypes.PANEL_SELECTED : PanelEventTypes.PANEL_OPEN, PanelTypes.INTERACTIONS);
|
|
4932
|
+
// Expand the specific interaction the badge represents so the panel opens "on the right
|
|
4933
|
+
// interaction active". Emitted AFTER PANEL_OPEN so the panel is showing this node.
|
|
4934
|
+
if (event.interaction?.id) {
|
|
4935
|
+
this.panelEventService.emit(PanelEventTypes.INTERACTION_EDIT, event.interaction.id);
|
|
4936
|
+
}
|
|
4912
4937
|
break;
|
|
4913
4938
|
}
|
|
4914
4939
|
case ToolbarAction.PastePreset: {
|
|
@@ -5972,8 +5997,23 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImpo
|
|
|
5972
5997
|
type: Input
|
|
5973
5998
|
}] } });
|
|
5974
5999
|
|
|
6000
|
+
/**
|
|
6001
|
+
* Directive-host ButtonBlock (wrapper collapse, task 9c). The real `<button>`/`<a>` IS the host —
|
|
6002
|
+
* chosen by RenderDirective via `hostElement` from the `tag` trait (`variableTag`), NOT an internal
|
|
6003
|
+
* `<button>` in the template. This matches the SSR engine's `button[iox-button-block]` component and
|
|
6004
|
+
* every other collapsed builder component (Container/Section/List/…): ONE element per node carrying
|
|
6005
|
+
* BOTH `iox-outer-{id}` (margin/width) + `iox-node-{id}` (visual props). Previously this component
|
|
6006
|
+
* kept the OLD pattern — a custom-element selector plus a template that rendered its own
|
|
6007
|
+
* `<button class="button-block-root">` — so RenderDirective's host `<button>` (iox-outer) wrapped a
|
|
6008
|
+
* second `<button>` (iox-node): button-in-button, and width (outer) + aspect-ratio (inner) split
|
|
6009
|
+
* across two elements so aspect-ratio never resolved. Collapsing to the single host fixes both.
|
|
6010
|
+
*
|
|
6011
|
+
* The `button`/`a` UA resets (border, background, text-decoration) live in the builder app's global
|
|
6012
|
+
* styles.scss, kept OFF `:host` so styleProps (`.iox-node-{id}`) can override them.
|
|
6013
|
+
*/
|
|
5975
6014
|
class BuilderButtonBlockComponent {
|
|
5976
|
-
constructor(dragEngine, cdr) {
|
|
6015
|
+
constructor(elRef, dragEngine, cdr) {
|
|
6016
|
+
this.elRef = elRef;
|
|
5977
6017
|
this.dragEngine = dragEngine;
|
|
5978
6018
|
this.cdr = cdr;
|
|
5979
6019
|
this.children = [];
|
|
@@ -5988,58 +6028,52 @@ class BuilderButtonBlockComponent {
|
|
|
5988
6028
|
this.childMouseEnter = new EventEmitter();
|
|
5989
6029
|
this.childMouseLeave = new EventEmitter();
|
|
5990
6030
|
}
|
|
5991
|
-
ngOnInit() {
|
|
5992
|
-
|
|
6031
|
+
ngOnInit() {
|
|
6032
|
+
// Register the HOST as the dropzone (was the ioxDropzone directive on the inner button).
|
|
6033
|
+
this.dragEngine.registerDropzone(this.dropListId, this.elRef.nativeElement, this.children, this.cdr, (evt) => this.onDrop(evt));
|
|
6034
|
+
}
|
|
6035
|
+
ngOnDestroy() {
|
|
6036
|
+
this.dragEngine.unregisterDropzone(this.dropListId, this.elRef.nativeElement);
|
|
6037
|
+
}
|
|
5993
6038
|
onDrop(event) {
|
|
5994
6039
|
this.dragEngine.handleDrop(this.children, event, this.dropListId, this.cdr);
|
|
5995
6040
|
}
|
|
5996
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: BuilderButtonBlockComponent, deps: [{ token: DragEngineService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
5997
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.11", type: BuilderButtonBlockComponent, isStandalone: false, selector: "
|
|
5998
|
-
<
|
|
5999
|
-
|
|
6000
|
-
|
|
6001
|
-
|
|
6002
|
-
|
|
6003
|
-
|
|
6004
|
-
|
|
6005
|
-
|
|
6006
|
-
|
|
6007
|
-
|
|
6008
|
-
|
|
6009
|
-
|
|
6010
|
-
[ioxRender]="child"
|
|
6011
|
-
[ioxDragSourceId]="dropListId"
|
|
6012
|
-
(onClick)="childClick.emit($event)"
|
|
6013
|
-
(onMouseEnter)="childMouseEnter.emit($event)"
|
|
6014
|
-
(onMouseLeave)="childMouseLeave.emit()">
|
|
6015
|
-
</ng-container>
|
|
6016
|
-
</button>
|
|
6017
|
-
`, isInline: true, styles: [".button-block-root{width:100%;font:inherit;color:inherit;text-decoration:none;box-sizing:border-box}.button-block-placeholder{flex:1;display:flex;align-items:center;justify-content:center;color:#64748b66;font-size:12px;pointer-events:none;-webkit-user-select:none;user-select:none}:host ::ng-deep .button-block-root>[class*=iox-outer-]{min-width:0}\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", "ioxDragSourceId"], outputs: ["onClick", "onMouseEnter", "onMouseLeave"] }, { kind: "directive", type: IoxDropzoneDirective, selector: "[ioxDropzone]", inputs: ["ioxDropzoneId", "ioxDropzoneData", "ioxDropzonePostDrop"], outputs: ["ioxDrop"] }] }); }
|
|
6041
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: BuilderButtonBlockComponent, deps: [{ token: i0.ElementRef }, { token: DragEngineService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
6042
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.11", type: BuilderButtonBlockComponent, isStandalone: false, selector: "button[iox-button-block],a[iox-button-block]", inputs: { children: "children", style: "style", tag: "tag", href: "href", target: "target", type: "type", nodeId: "nodeId", dropListId: "dropListId" }, outputs: { childClick: "childClick", childMouseEnter: "childMouseEnter", childMouseLeave: "childMouseLeave" }, host: { properties: { "class": "'button-block-root iox-node-' + nodeId", "attr.href": "tag === 'a' ? (href || null) : null", "attr.target": "tag === 'a' ? (target || null) : null", "attr.type": "tag === 'a' ? null : type" } }, ngImport: i0, template: `
|
|
6043
|
+
<span *ngIf="!children.length" class="button-block-placeholder">Button</span>
|
|
6044
|
+
|
|
6045
|
+
<!-- WRAPPER COLLAPSE (task 9c): render children directly into the host; iox-outer + drag land
|
|
6046
|
+
on each child's host (via ioxDragSourceId), matching the SSR engine. -->
|
|
6047
|
+
<ng-container *ngFor="let child of children"
|
|
6048
|
+
[ioxRender]="child"
|
|
6049
|
+
[ioxDragSourceId]="dropListId"
|
|
6050
|
+
(onClick)="childClick.emit($event)"
|
|
6051
|
+
(onMouseEnter)="childMouseEnter.emit($event)"
|
|
6052
|
+
(onMouseLeave)="childMouseLeave.emit()">
|
|
6053
|
+
</ng-container>
|
|
6054
|
+
`, isInline: true, styles: [":host{box-sizing:border-box}.button-block-placeholder{flex:1;display:flex;align-items:center;justify-content:center;color:#64748b66;font-size:12px;pointer-events:none;-webkit-user-select:none;user-select:none}:host ::ng-deep>[class*=iox-outer-]{min-width:0}\n"], dependencies: [{ 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", "ioxDragSourceId"], outputs: ["onClick", "onMouseEnter", "onMouseLeave"] }] }); }
|
|
6018
6055
|
}
|
|
6019
6056
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: BuilderButtonBlockComponent, decorators: [{
|
|
6020
6057
|
type: Component,
|
|
6021
|
-
args: [{ selector: '
|
|
6022
|
-
<
|
|
6023
|
-
|
|
6024
|
-
|
|
6025
|
-
|
|
6026
|
-
|
|
6027
|
-
|
|
6028
|
-
|
|
6029
|
-
|
|
6030
|
-
|
|
6031
|
-
|
|
6032
|
-
|
|
6033
|
-
|
|
6034
|
-
|
|
6035
|
-
|
|
6036
|
-
|
|
6037
|
-
|
|
6038
|
-
|
|
6039
|
-
|
|
6040
|
-
</button>
|
|
6041
|
-
`, standalone: false, styles: [".button-block-root{width:100%;font:inherit;color:inherit;text-decoration:none;box-sizing:border-box}.button-block-placeholder{flex:1;display:flex;align-items:center;justify-content:center;color:#64748b66;font-size:12px;pointer-events:none;-webkit-user-select:none;user-select:none}:host ::ng-deep .button-block-root>[class*=iox-outer-]{min-width:0}\n"] }]
|
|
6042
|
-
}], ctorParameters: () => [{ type: DragEngineService }, { type: i0.ChangeDetectorRef }], propDecorators: { children: [{
|
|
6058
|
+
args: [{ selector: 'button[iox-button-block],a[iox-button-block]', template: `
|
|
6059
|
+
<span *ngIf="!children.length" class="button-block-placeholder">Button</span>
|
|
6060
|
+
|
|
6061
|
+
<!-- WRAPPER COLLAPSE (task 9c): render children directly into the host; iox-outer + drag land
|
|
6062
|
+
on each child's host (via ioxDragSourceId), matching the SSR engine. -->
|
|
6063
|
+
<ng-container *ngFor="let child of children"
|
|
6064
|
+
[ioxRender]="child"
|
|
6065
|
+
[ioxDragSourceId]="dropListId"
|
|
6066
|
+
(onClick)="childClick.emit($event)"
|
|
6067
|
+
(onMouseEnter)="childMouseEnter.emit($event)"
|
|
6068
|
+
(onMouseLeave)="childMouseLeave.emit()">
|
|
6069
|
+
</ng-container>
|
|
6070
|
+
`, host: {
|
|
6071
|
+
'[class]': "'button-block-root iox-node-' + nodeId",
|
|
6072
|
+
'[attr.href]': "tag === 'a' ? (href || null) : null",
|
|
6073
|
+
'[attr.target]': "tag === 'a' ? (target || null) : null",
|
|
6074
|
+
'[attr.type]': "tag === 'a' ? null : type",
|
|
6075
|
+
}, standalone: false, styles: [":host{box-sizing:border-box}.button-block-placeholder{flex:1;display:flex;align-items:center;justify-content:center;color:#64748b66;font-size:12px;pointer-events:none;-webkit-user-select:none;user-select:none}:host ::ng-deep>[class*=iox-outer-]{min-width:0}\n"] }]
|
|
6076
|
+
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: DragEngineService }, { type: i0.ChangeDetectorRef }], propDecorators: { children: [{
|
|
6043
6077
|
type: Input
|
|
6044
6078
|
}], style: [{
|
|
6045
6079
|
type: Input
|