@xui/components
Version:
xUI Components for Angular
79 lines • 10.9 kB
JavaScript
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=