UNPKG

@luminela/menu

Version:

A simple menubar component for Angular.

226 lines (219 loc) 10 kB
import { Component, ContentChildren, Input, ElementRef, HostBinding, HostListener, NgModule } from '@angular/core'; import { MenuItemComponent, ContextMenuModule } from '@luminela/contextmenu'; import { v4 } from 'uuid'; import { ActiveDescendantKeyManager } from '@angular/cdk/a11y'; import { CommonModule } from '@angular/common'; class MenuComponent { constructor() { this.uid = v4(); this.focused = false; this.disabled = false; this.menuItems = []; } ngOnInit() { } ngOnDestroy() { var _a; (_a = this.subMenuItemsSubscription$) === null || _a === void 0 ? void 0 : _a.unsubscribe(); } ngAfterContentInit() { var _a; if (((_a = this.menuItems) === null || _a === void 0 ? void 0 : _a.length) > 0) { return; } this.createMenuItems(); this.initializeMenuItems(this.menuItems); this.subMenuItemsSubscription$ = this.subMenuItems.changes.subscribe(() => { this.createMenuItems(); this.initializeMenuItems(this.menuItems); }); } setActiveStyles() { if (!this.disabled) { this.focused = true; } } setInactiveStyles() { this.focused = false; } createMenuItems() { if (!this.menuItems || this.menuItems.length === 0) { this.menuItems = this.subMenuItems.map(smi => smi.getMenuItemData()); } } initializeMenuItems(items) { items.forEach(item => { var _a; item.visible = item.visible !== false; this.initializeMenuItems(((_a = item.menuItems) === null || _a === void 0 ? void 0 : _a.length) > 0 ? item.menuItems : []); }); } } MenuComponent.decorators = [ { type: Component, args: [{ selector: "yui-menu", template: "" },] } ]; MenuComponent.ctorParameters = () => []; MenuComponent.propDecorators = { subMenuItems: [{ type: ContentChildren, args: [MenuItemComponent,] }], disabled: [{ type: Input }], menuClass: [{ type: Input }], menuItems: [{ type: Input }], target: [{ type: Input }], text: [{ type: Input }], textTemplate: [{ type: Input }] }; class MenuBarComponent { constructor(hostElementRef) { this.hostElementRef = hostElementRef; this.menuThemeClass = "theme-light"; this.menuTheme = "light"; this.menuClass = ""; } set theme(theme) { this.menuTheme = theme; this.menuThemeClass = theme === "dark" ? "theme-dark" : "theme-light"; } get lt() { return this.menuThemeClass === "theme-light"; } get dt() { return this.menuThemeClass === "theme-dark"; } ngOnInit() { } ngAfterContentInit() { console.log(this.menuList); } ngAfterViewInit() { this.keyManager = new ActiveDescendantKeyManager(this.menuList.toArray()).withWrap(true).skipPredicate(m => m.disabled); } onMenuChange(data) { this.menuChangeData = data; } onMenuClose(data) { this.keyManager.setActiveItem(null); this.previousMenuData = null; if (!!this.currentMenu) { this.currentMenu.focused = false; this.currentMenu = null; } this.menuChangeData = null; } onMenuClick(event, menu) { var _a; if (this.previousMenuElement === event.target.closest(`[data-uid='${menu.uid}']`)) { menu.focused = !menu.focused; if (!menu.focused) { (_a = this.previousMenuData) === null || _a === void 0 ? void 0 : _a.contextMenuRef.popupRef.close(); } return; } this.previousMenuElement = event.target.closest("li").firstChild; this.keyManager.setActiveItem(this.menuList.find(m => m.uid === menu.uid)); this.currentMenu = menu; } onMenuMouseEnter(event, menu) { var _a; if (this.previousMenuData) { if (this.previousMenuElement === event.target.closest(`[data-uid='${menu.uid}']`)) { return; } (_a = this.previousMenuData) === null || _a === void 0 ? void 0 : _a.contextMenuRef.popupRef.close(); event.target.dispatchEvent(new MouseEvent("click", Object.assign({}, event))); this.keyManager.setActiveItem(this.menuList.find(m => m.uid === menu.uid)); } this.previousMenuElement = event.target.closest("li").firstChild; this.currentMenu = menu; } onMenuMouseLeave(event, menu) { // this.currentMenu = null; // menu.focused = false; // this.keyManager.setActiveItem(null); } onMenuOpen(data) { if (data.depth > 0) { return; } this.previousMenuData = data; } onKeydown(event) { var _a, _b, _c; if (!this.previousMenuData) { return; } switch (event.key) { case "Enter": case "NumEnter": case " ": this.keyManager.setActiveItem(null); return; case "ArrowUp": case "ArrowDown": console.log("Ignore " + event.key); return; case "ArrowLeft": if (((_a = this.menuChangeData) === null || _a === void 0 ? void 0 : _a.depth) > 1) { return; } this.keyManager.setPreviousItemActive(); break; case "ArrowRight": if (((_c = (_b = this.menuChangeData) === null || _b === void 0 ? void 0 : _b.item.menuItems) === null || _c === void 0 ? void 0 : _c.length) > 0) { return; } this.keyManager.setNextItemActive(); break; default: this.keyManager.onKeydown(event); break; } if (this.keyManager.activeItem) { this.currentMenu = this.keyManager.activeItem; document.querySelector(`[data-uid='${this.currentMenu.uid}']`).dispatchEvent(new MouseEvent("mouseenter")); } } } MenuBarComponent.decorators = [ { type: Component, args: [{ selector: "yui-menu-bar", template: "<div class=\"wrapper\">\n <ul class=\"menubar-list\" *ngIf=\"menuList?.length > 0\">\n <li *ngFor=\"let item of menuList\" #listElement (mouseenter)=\"onMenuMouseEnter($event, item)\"\n (mouseleave)=\"onMenuMouseLeave($event, item)\" (click)=\"onMenuClick($event, item)\"\n [attr.data-uid]=\"item.uid\"\n [ngClass]=\"{'active': item.focused && !item.disabled, 'disabled': item.disabled}\">\n <span *ngIf=\"!item.textTemplate\">{{item.text}}</span>\n <ng-container [ngTemplateOutlet]=\"item.textTemplate\" *ngIf=\"!!item.textTemplate\"></ng-container>\n <yui-contextmenu [target]=\"listElement\" [menuItems]=\"item.menuItems\" [theme]=\"menuTheme\" [menuClass]=\"menuClass\"\n [precise]=\"false\" trigger=\"click\" (menuOpen)=\"onMenuOpen($event)\"\n (menuClose)=\"onMenuClose($event)\" (menuChange)=\"onMenuChange($event)\"></yui-contextmenu>\n </li>\n </ul>\n</div>\n", styles: ["div.wrapper{height:25px;width:100%}div.wrapper,div.wrapper *{-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none;box-sizing:border-box;user-select:none}ul.menubar-list{justify-content:flex-start;width:100%}ul.menubar-list,ul.menubar-list>li{align-items:center;display:flex;height:100%}ul.menubar-list>li{border-left:1px solid transparent;border-right:1px solid transparent;font-size:13px;font-weight:600;justify-content:center;padding:0 10px}ul.menubar-list>li.disabled{pointer-events:none}:host-context(.theme-light) ul.menubar-list{background:#e8e8e8;border-bottom:1px solid #d1d1d1}:host-context(.theme-light) ul.menubar-list>li{color:#383848}:host-context(.theme-light) ul.menubar-list>li.active,:host-context(.theme-light) ul.menubar-list>li:hover:not(.disabled){background:#f2f2f4}:host-context(.theme-light) ul.menubar-list>li.active:not(:first-child),:host-context(.theme-light) ul.menubar-list>li:hover:not(.disabled):not(:first-child){border-left:1px solid #d1d1d1}:host-context(.theme-light) ul.menubar-list>li.disabled{color:#a7a7af}:host-context(.theme-dark) ul.menubar-list{background:#383838;border-bottom:1px solid #585858}:host-context(.theme-dark) ul.menubar-list>li{color:#c0c0c6}:host-context(.theme-dark) ul.menubar-list>li.active,:host-context(.theme-dark) ul.menubar-list>li:hover:not(.disabled){background:#47474f}:host-context(.theme-dark) ul.menubar-list>li.active:not(:first-child),:host-context(.theme-dark) ul.menubar-list>li:hover:not(.disabled):not(:first-child){border-left:1px solid #585858}:host-context(.theme-dark) ul.menubar-list>li.disabled{color:#6a6a70}"] },] } ]; MenuBarComponent.ctorParameters = () => [ { type: ElementRef } ]; MenuBarComponent.propDecorators = { menuList: [{ type: ContentChildren, args: [MenuComponent,] }], menuClass: [{ type: Input }], theme: [{ type: Input }], lt: [{ type: HostBinding, args: ["class.theme-light",] }], dt: [{ type: HostBinding, args: ["class.theme-dark",] }], onKeydown: [{ type: HostListener, args: ["window:keydown", ["$event"],] }] }; class MenuModule { } MenuModule.decorators = [ { type: NgModule, args: [{ declarations: [MenuBarComponent, MenuComponent], imports: [ CommonModule, ContextMenuModule ], exports: [ MenuBarComponent, MenuComponent ] },] } ]; /* * Public API Surface of menu */ /** * Generated bundle index. Do not edit. */ export { MenuBarComponent, MenuComponent, MenuModule }; //# sourceMappingURL=luminela-menu.js.map