UNPKG

@xui/components

Version:

xUI Components for Angular

79 lines 10.9 kB
import { ChangeDetectionStrategy, Component, ContentChildren, effect, EventEmitter, input, Output, QueryList, TemplateRef, ViewChild, ViewContainerRef } from '@angular/core'; import { ConnectionPositionPair, Overlay } from '@angular/cdk/overlay'; import { TemplatePortal } from '@angular/cdk/portal'; import { XuiButton } from '../button'; import { first } from 'rxjs'; import * as i0 from "@angular/core"; import * as i1 from "@angular/cdk/overlay"; import * as i2 from "@angular/cdk/a11y"; export class XuiContextMenu { constructor(overlay, viewContainerRef) { this.overlay = overlay; this.viewContainerRef = viewContainerRef; this.anchor = input(); this.afterClosed = new EventEmitter(); const config = { scrollStrategy: this.overlay.scrollStrategies.reposition(), hasBackdrop: true, backdropClass: 'x-context-menu-backdrop' }; this.overlayRef = this.overlay.create(config); this.overlayRef.backdropClick().subscribe(() => { this.close(); }); effect(() => { this.overlayRef.updatePositionStrategy(this.calculatePositionStrategy(this.anchor())); }); } open(anchor) { this.overlayRef.updatePositionStrategy(this.calculatePositionStrategy(anchor ?? this.anchor())); const userProfilePortal = new TemplatePortal(this.templateRef, this.viewContainerRef); this.overlayRef.attach(userProfilePortal); for (const btn of this.buttons) { btn.click.pipe(first()).subscribe(() => this.close()); } } calculatePositionStrategy(anchor) { return this.overlay .position() .flexibleConnectedTo(anchor?.elementRef ?? anchor) .withPositions([ new ConnectionPositionPair({ originX: 'start', originY: 'bottom' }, { overlayX: 'start', overlayY: 'top' }) ]) .withPush(false); } close() { this.overlayRef.detach(); this.afterClosed.emit(); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: XuiContextMenu, deps: [{ token: i1.Overlay }, { token: i0.ViewContainerRef }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "18.0.1", type: XuiContextMenu, selector: "xui-context-menu", inputs: { anchor: { classPropertyName: "anchor", publicName: "anchor", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { afterClosed: "afterClosed" }, host: { listeners: { "document:keydown.esc": "close()" } }, queries: [{ propertyName: "buttons", predicate: XuiButton }], viewQueries: [{ propertyName: "templateRef", first: true, predicate: ["templateRef"], descendants: true, static: true }], ngImport: i0, template: `<ng-template #templateRef> <div class="x-context-menu" cdkTrapFocus cdkTrapFocusAutoCapture (click)="close()"> <ng-content /> </div> </ng-template>`, isInline: true, dependencies: [{ kind: "directive", type: i2.CdkTrapFocus, selector: "[cdkTrapFocus]", inputs: ["cdkTrapFocus", "cdkTrapFocusAutoCapture"], exportAs: ["cdkTrapFocus"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: XuiContextMenu, decorators: [{ type: Component, args: [{ selector: 'xui-context-menu', changeDetection: ChangeDetectionStrategy.OnPush, template: `<ng-template #templateRef> <div class="x-context-menu" cdkTrapFocus cdkTrapFocusAutoCapture (click)="close()"> <ng-content /> </div> </ng-template>`, host: { '(document:keydown.esc)': 'close()' } }] }], ctorParameters: () => [{ type: i1.Overlay }, { type: i0.ViewContainerRef }], propDecorators: { afterClosed: [{ type: Output }], templateRef: [{ type: ViewChild, args: ['templateRef', { static: true }] }], buttons: [{ type: ContentChildren, args: [XuiButton] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29udGV4dC1tZW51LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vbGlicy94dWkvc3JjL2NvbnRleHQtbWVudS9jb250ZXh0LW1lbnUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLHVCQUF1QixFQUN2QixTQUFTLEVBQ1QsZUFBZSxFQUNmLE1BQU0sRUFDTixZQUFZLEVBQ1osS0FBSyxFQUNMLE1BQU0sRUFDTixTQUFTLEVBQ1QsV0FBVyxFQUNYLFNBQVMsRUFDVCxnQkFBZ0IsRUFDakIsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE9BQU8sRUFBNkIsTUFBTSxzQkFBc0IsQ0FBQztBQUNsRyxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDckQsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUN0QyxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sTUFBTSxDQUFDOzs7O0FBZTdCLE1BQU0sT0FBTyxjQUFjO0lBU3pCLFlBQ1UsT0FBZ0IsRUFDaEIsZ0JBQWtDO1FBRGxDLFlBQU8sR0FBUCxPQUFPLENBQVM7UUFDaEIscUJBQWdCLEdBQWhCLGdCQUFnQixDQUFrQjtRQVI1QyxXQUFNLEdBQUcsS0FBSyxFQUFxQixDQUFDO1FBQzFCLGdCQUFXLEdBQUcsSUFBSSxZQUFZLEVBQUUsQ0FBQztRQVN6QyxNQUFNLE1BQU0sR0FBa0I7WUFDNUIsY0FBYyxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsZ0JBQWdCLENBQUMsVUFBVSxFQUFFO1lBQzFELFdBQVcsRUFBRSxJQUFJO1lBQ2pCLGFBQWEsRUFBRSx5QkFBeUI7U0FDekMsQ0FBQztRQUVGLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDOUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxhQUFhLEVBQUUsQ0FBQyxTQUFTLENBQUMsR0FBRyxFQUFFO1lBQzdDLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUNmLENBQUMsQ0FBQyxDQUFDO1FBRUgsTUFBTSxDQUFDLEdBQUcsRUFBRTtZQUNWLElBQUksQ0FBQyxVQUFVLENBQUMsc0JBQXNCLENBQUMsSUFBSSxDQUFDLHlCQUF5QixDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUcsQ0FBQyxDQUFDLENBQUM7UUFDekYsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQsSUFBSSxDQUFDLE1BQTBCO1FBQzdCLElBQUksQ0FBQyxVQUFVLENBQUMsc0JBQXNCLENBQUMsSUFBSSxDQUFDLHlCQUF5QixDQUFDLE1BQU0sSUFBSSxJQUFJLENBQUMsTUFBTSxFQUFHLENBQUMsQ0FBQyxDQUFDO1FBRWpHLE1BQU0saUJBQWlCLEdBQUcsSUFBSSxjQUFjLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztRQUN0RixJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO1FBRTFDLEtBQUssTUFBTSxHQUFHLElBQUksSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQy9CLEdBQUcsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUMsU0FBUyxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDO1FBQ3hELENBQUM7SUFDSCxDQUFDO0lBRU8seUJBQXlCLENBQUMsTUFBeUI7UUFDekQsT0FBTyxJQUFJLENBQUMsT0FBTzthQUNoQixRQUFRLEVBQUU7YUFDVixtQkFBbUIsQ0FBRSxNQUFjLEVBQUUsVUFBVSxJQUFJLE1BQU0sQ0FBQzthQUMxRCxhQUFhLENBQUM7WUFDYixJQUFJLHNCQUFzQixDQUFDLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsUUFBUSxFQUFFLEVBQUUsRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsQ0FBQztTQUM1RyxDQUFDO2FBQ0QsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ3JCLENBQUM7SUFFRCxLQUFLO1FBQ0gsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUN6QixJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksRUFBRSxDQUFDO0lBQzFCLENBQUM7OEdBckRVLGNBQWM7a0dBQWQsY0FBYyw0VEFPUixTQUFTLHVKQWhCaEI7Ozs7aUJBSUs7OzJGQUtKLGNBQWM7a0JBWjFCLFNBQVM7bUJBQUM7b0JBQ1QsUUFBUSxFQUFFLGtCQUFrQjtvQkFDNUIsZUFBZSxFQUFFLHVCQUF1QixDQUFDLE1BQU07b0JBQy9DLFFBQVEsRUFBRTs7OztpQkFJSztvQkFDZixJQUFJLEVBQUU7d0JBQ0osd0JBQXdCLEVBQUUsU0FBUztxQkFDcEM7aUJBQ0Y7MkdBS1csV0FBVztzQkFBcEIsTUFBTTtnQkFFNkMsV0FBVztzQkFBOUQsU0FBUzt1QkFBQyxhQUFhLEVBQUUsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFO2dCQUNOLE9BQU87c0JBQTFDLGVBQWU7dUJBQUMsU0FBUyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICBDb21wb25lbnQsXG4gIENvbnRlbnRDaGlsZHJlbixcbiAgZWZmZWN0LFxuICBFdmVudEVtaXR0ZXIsXG4gIGlucHV0LFxuICBPdXRwdXQsXG4gIFF1ZXJ5TGlzdCxcbiAgVGVtcGxhdGVSZWYsXG4gIFZpZXdDaGlsZCxcbiAgVmlld0NvbnRhaW5lclJlZlxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IENvbm5lY3Rpb25Qb3NpdGlvblBhaXIsIE92ZXJsYXksIE92ZXJsYXlDb25maWcsIE92ZXJsYXlSZWYgfSBmcm9tICdAYW5ndWxhci9jZGsvb3ZlcmxheSc7XG5pbXBvcnQgeyBUZW1wbGF0ZVBvcnRhbCB9IGZyb20gJ0Bhbmd1bGFyL2Nkay9wb3J0YWwnO1xuaW1wb3J0IHsgWHVpQnV0dG9uIH0gZnJvbSAnLi4vYnV0dG9uJztcbmltcG9ydCB7IGZpcnN0IH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBDb250ZXh0TWVudUFuY2hvciB9IGZyb20gJy4vY29udGV4dC1tZW51LnR5cGVzJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAneHVpLWNvbnRleHQtbWVudScsXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICB0ZW1wbGF0ZTogYDxuZy10ZW1wbGF0ZSAjdGVtcGxhdGVSZWY+XG4gICAgPGRpdiBjbGFzcz1cIngtY29udGV4dC1tZW51XCIgY2RrVHJhcEZvY3VzIGNka1RyYXBGb2N1c0F1dG9DYXB0dXJlIChjbGljayk9XCJjbG9zZSgpXCI+XG4gICAgICA8bmctY29udGVudCAvPlxuICAgIDwvZGl2PlxuICA8L25nLXRlbXBsYXRlPmAsXG4gIGhvc3Q6IHtcbiAgICAnKGRvY3VtZW50OmtleWRvd24uZXNjKSc6ICdjbG9zZSgpJ1xuICB9XG59KVxuZXhwb3J0IGNsYXNzIFh1aUNvbnRleHRNZW51IHtcbiAgcHJpdmF0ZSBvdmVybGF5UmVmITogT3ZlcmxheVJlZjtcblxuICBhbmNob3IgPSBpbnB1dDxDb250ZXh0TWVudUFuY2hvcj4oKTtcbiAgQE91dHB1dCgpIGFmdGVyQ2xvc2VkID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuXG4gIEBWaWV3Q2hpbGQoJ3RlbXBsYXRlUmVmJywgeyBzdGF0aWM6IHRydWUgfSkgcHJpdmF0ZSB0ZW1wbGF0ZVJlZiE6IFRlbXBsYXRlUmVmPHVua25vd24+O1xuICBAQ29udGVudENoaWxkcmVuKFh1aUJ1dHRvbikgcHJpdmF0ZSBidXR0b25zITogUXVlcnlMaXN0PFh1aUJ1dHRvbj47XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBvdmVybGF5OiBPdmVybGF5LFxuICAgIHByaXZhdGUgdmlld0NvbnRhaW5lclJlZjogVmlld0NvbnRhaW5lclJlZlxuICApIHtcbiAgICBjb25zdCBjb25maWc6IE92ZXJsYXlDb25maWcgPSB7XG4gICAgICBzY3JvbGxTdHJhdGVneTogdGhpcy5vdmVybGF5LnNjcm9sbFN0cmF0ZWdpZXMucmVwb3NpdGlvbigpLFxuICAgICAgaGFzQmFja2Ryb3A6IHRydWUsXG4gICAgICBiYWNrZHJvcENsYXNzOiAneC1jb250ZXh0LW1lbnUtYmFja2Ryb3AnXG4gICAgfTtcblxuICAgIHRoaXMub3ZlcmxheVJlZiA9IHRoaXMub3ZlcmxheS5jcmVhdGUoY29uZmlnKTtcbiAgICB0aGlzLm92ZXJsYXlSZWYuYmFja2Ryb3BDbGljaygpLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICB0aGlzLmNsb3NlKCk7XG4gICAgfSk7XG5cbiAgICBlZmZlY3QoKCkgPT4ge1xuICAgICAgdGhpcy5vdmVybGF5UmVmLnVwZGF0ZVBvc2l0aW9uU3RyYXRlZ3kodGhpcy5jYWxjdWxhdGVQb3NpdGlvblN0cmF0ZWd5KHRoaXMuYW5jaG9yKCkhKSk7XG4gICAgfSk7XG4gIH1cblxuICBvcGVuKGFuY2hvcj86IENvbnRleHRNZW51QW5jaG9yKSB7XG4gICAgdGhpcy5vdmVybGF5UmVmLnVwZGF0ZVBvc2l0aW9uU3RyYXRlZ3kodGhpcy5jYWxjdWxhdGVQb3NpdGlvblN0cmF0ZWd5KGFuY2hvciA/PyB0aGlzLmFuY2hvcigpISkpO1xuXG4gICAgY29uc3QgdXNlclByb2ZpbGVQb3J0YWwgPSBuZXcgVGVtcGxhdGVQb3J0YWwodGhpcy50ZW1wbGF0ZVJlZiwgdGhpcy52aWV3Q29udGFpbmVyUmVmKTtcbiAgICB0aGlzLm92ZXJsYXlSZWYuYXR0YWNoKHVzZXJQcm9maWxlUG9ydGFsKTtcblxuICAgIGZvciAoY29uc3QgYnRuIG9mIHRoaXMuYnV0dG9ucykge1xuICAgICAgYnRuLmNsaWNrLnBpcGUoZmlyc3QoKSkuc3Vic2NyaWJlKCgpID0+IHRoaXMuY2xvc2UoKSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBjYWxjdWxhdGVQb3NpdGlvblN0cmF0ZWd5KGFuY2hvcjogQ29udGV4dE1lbnVBbmNob3IpIHtcbiAgICByZXR1cm4gdGhpcy5vdmVybGF5XG4gICAgICAucG9zaXRpb24oKVxuICAgICAgLmZsZXhpYmxlQ29ubmVjdGVkVG8oKGFuY2hvciBhcyBhbnkpPy5lbGVtZW50UmVmID8/IGFuY2hvcilcbiAgICAgIC53aXRoUG9zaXRpb25zKFtcbiAgICAgICAgbmV3IENvbm5lY3Rpb25Qb3NpdGlvblBhaXIoeyBvcmlnaW5YOiAnc3RhcnQnLCBvcmlnaW5ZOiAnYm90dG9tJyB9LCB7IG92ZXJsYXlYOiAnc3RhcnQnLCBvdmVybGF5WTogJ3RvcCcgfSlcbiAgICAgIF0pXG4gICAgICAud2l0aFB1c2goZmFsc2UpO1xuICB9XG5cbiAgY2xvc2UoKSB7XG4gICAgdGhpcy5vdmVybGF5UmVmLmRldGFjaCgpO1xuICAgIHRoaXMuYWZ0ZXJDbG9zZWQuZW1pdCgpO1xuICB9XG59XG4iXX0=