UNPKG

@cauca-911/menu

Version:

Run `npm install @cauca-911/menu --save` to add this library to your project

332 lines (312 loc) 42 kB
import * as i0 from '@angular/core'; import { InjectionToken, Injector, inject, ChangeDetectionStrategy, Component, input, Injectable, signal, computed, Input } from '@angular/core'; import { RouterOutlet, Router, NavigationStart } from '@angular/router'; import { MatToolbar } from '@angular/material/toolbar'; import { MatMenu, MatMenuTrigger } from '@angular/material/menu'; import { Location, NgClass } from '@angular/common'; import { CaucaCoreService } from '@cauca-911/core'; import { MenuItemComponent, IconButtonComponent } from '@cauca-911/material'; import { BreakpointObserver } from '@angular/cdk/layout'; import { toSignal, takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { map, filter } from 'rxjs'; import { MatIcon } from '@angular/material/icon'; import * as i1 from '@ngx-translate/core'; import { TranslateModule } from '@ngx-translate/core'; function provideCaucaMenu(option) { return [ { provide: APP_VERSION_TOKEN, useValue: option.applicationVersion }, { provide: LOGO_PATH_TOKEN, useValue: option.logoPath || '/assets/images/logo.svg' }, { provide: MENU_ITEMS_PROVIDER_TOKEN, useFactory: (injector) => injector.get(option.menuItemsProvider), deps: [Injector] }, { provide: LOGOUT_HANDLER_TOKEN, useFactory: (injector) => injector.get(option.logoutHandler), deps: [Injector] }, { provide: LOGIN_STATE_TOKEN, useFactory: (injector) => injector.get(option.loginState), deps: [Injector] }, ]; } const APP_VERSION_TOKEN = new InjectionToken('Application Version'); const LOGO_PATH_TOKEN = new InjectionToken('Logo Path'); const MENU_ITEMS_PROVIDER_TOKEN = new InjectionToken('Menu Items Provider'); const LOGOUT_HANDLER_TOKEN = new InjectionToken('Logout Handler'); const LOGIN_STATE_TOKEN = new InjectionToken('Login State'); class UserMenuHeaderComponent { constructor() { this.loginState = inject(LOGIN_STATE_TOKEN); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: UserMenuHeaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.3", type: UserMenuHeaderComponent, isStandalone: true, selector: "cauca-user-menu-header", ngImport: i0, template: "<div class=\"menu-header\">\r\n <div class=\"header-content\">\r\n <div class=\"header-content-text\">\r\n <div class=\"body1 fullname\">{{loginState.userFullName()}}</div>\r\n <div class=\"body2 username\">{{loginState.username()}}</div>\r\n </div>\r\n </div>\r\n</div>", styles: [".menu-header{display:flex;flex-direction:column;align-items:flex-start;align-self:stretch}.header-content{display:flex;padding:8px 16px;align-items:center;align-self:stretch}.header-content-text{display:flex;padding:4px 0;flex-direction:column;align-items:flex-start;flex:1 0 0}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: UserMenuHeaderComponent, decorators: [{ type: Component, args: [{ selector: 'cauca-user-menu-header', imports: [], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"menu-header\">\r\n <div class=\"header-content\">\r\n <div class=\"header-content-text\">\r\n <div class=\"body1 fullname\">{{loginState.userFullName()}}</div>\r\n <div class=\"body2 username\">{{loginState.username()}}</div>\r\n </div>\r\n </div>\r\n</div>", styles: [".menu-header{display:flex;flex-direction:column;align-items:flex-start;align-self:stretch}.header-content{display:flex;padding:8px 16px;align-items:center;align-self:stretch}.header-content-text{display:flex;padding:4px 0;flex-direction:column;align-items:flex-start;flex:1 0 0}\n"] }] }] }); class LanguageMenuComponent { constructor() { this.isSubMenu = input(false, ...(ngDevMode ? [{ debugName: "isSubMenu" }] : [])); this.languages = [ { code: 'fr', description: 'Français' }, { code: 'en', description: 'English' } ]; this.location = inject(Location); this.coreService = inject(CaucaCoreService); } setLanguage(languageCode) { this.coreService.setLanguage(languageCode); this.location.historyGo(0); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: LanguageMenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.3", type: LanguageMenuComponent, isStandalone: true, selector: "cauca-language-menu", inputs: { isSubMenu: { classPropertyName: "isSubMenu", publicName: "isSubMenu", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@if (isSubMenu()) {\r\n <cauca-menu-item class=\"change-language-menu-item\" [trigger]=\"languagesMenu\" icon=\"language_rounded\" [translateLabel]=\"true\" label=\"headerBar.changeLanguageButtonLabel\" [matMenuTriggerFor]=\"languagesMenu\"/>\r\n} @else {\r\n <cauca-icon-button class=\"change-language-button\" icon=\"language_rounded\" [matMenuTriggerFor]=\"languagesMenu\" />\r\n}\r\n\r\n<mat-menu #languagesMenu=\"matMenu\">\r\n @for (language of languages; track language.code) {\r\n <cauca-menu-item icon=\"language_rounded\" [label]=\"language.description\" [translateLabel]=\"false\" (click)=\"setLanguage(language.code)\" onkeypress=\"setLanguage(language.code)\" />\r\n }\r\n</mat-menu>", styles: [""], dependencies: [{ kind: "component", type: MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: MenuItemComponent, selector: "cauca-menu-item", inputs: ["translateLabel", "trigger"] }, { kind: "component", type: IconButtonComponent, selector: "cauca-icon-button" }, { kind: "directive", type: MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: LanguageMenuComponent, decorators: [{ type: Component, args: [{ selector: 'cauca-language-menu', imports: [MatMenu, MenuItemComponent, IconButtonComponent, MatMenuTrigger], changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (isSubMenu()) {\r\n <cauca-menu-item class=\"change-language-menu-item\" [trigger]=\"languagesMenu\" icon=\"language_rounded\" [translateLabel]=\"true\" label=\"headerBar.changeLanguageButtonLabel\" [matMenuTriggerFor]=\"languagesMenu\"/>\r\n} @else {\r\n <cauca-icon-button class=\"change-language-button\" icon=\"language_rounded\" [matMenuTriggerFor]=\"languagesMenu\" />\r\n}\r\n\r\n<mat-menu #languagesMenu=\"matMenu\">\r\n @for (language of languages; track language.code) {\r\n <cauca-menu-item icon=\"language_rounded\" [label]=\"language.description\" [translateLabel]=\"false\" (click)=\"setLanguage(language.code)\" onkeypress=\"setLanguage(language.code)\" />\r\n }\r\n</mat-menu>" }] }] }); class MenuSeparatorComponent { static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: MenuSeparatorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.3", type: MenuSeparatorComponent, isStandalone: true, selector: "cauca-menu-separator", ngImport: i0, template: "<hr class=\"separator\" />", styles: [".separator{border:1px solid rgba(0,0,0,.12)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: MenuSeparatorComponent, decorators: [{ type: Component, args: [{ selector: 'cauca-menu-separator', imports: [], changeDetection: ChangeDetectionStrategy.OnPush, template: "<hr class=\"separator\" />", styles: [".separator{border:1px solid rgba(0,0,0,.12)}\n"] }] }] }); class UserAgentReaderService { getUserAgent() { return navigator.userAgent; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: UserAgentReaderService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: UserAgentReaderService, providedIn: 'root' }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: UserAgentReaderService, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }] }); const MOBILE = /Android.*Mobile|webOS|iPhone|iPod|BB|IEMobile|Opera Mini|Opera Mobi/i; const TABLET = /iPad|Android(?!.*Mobile)/i; class ScreenSizeService { constructor() { this.isSmallScreen = toSignal(inject(BreakpointObserver) .observe('(max-width: 1000px)') .pipe(takeUntilDestroyed(), map((value) => value.matches))); this.isMobile = signal(false, ...(ngDevMode ? [{ debugName: "isMobile" }] : [])); this.isCompact = computed(() => this.isMobile() || this.isSmallScreen(), ...(ngDevMode ? [{ debugName: "isCompact" }] : [])); const reader = inject(UserAgentReaderService); this.isMobile.set(this.is(reader, MOBILE) && !this.is(reader, TABLET)); } is(reader, regEx) { return regEx.test(reader.getUserAgent()); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: ScreenSizeService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: ScreenSizeService, providedIn: 'root' }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: ScreenSizeService, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }], ctorParameters: () => [] }); const MENU_STATE_KEY = 'menuState'; class MenuStateService { constructor() { this.version = signal(this.getVersion(inject(APP_VERSION_TOKEN)), ...(ngDevMode ? [{ debugName: "version" }] : [])); this.isOpen = signal(false, ...(ngDevMode ? [{ debugName: "isOpen" }] : [])); this.isPinned = signal(this.getInitialPinState(), ...(ngDevMode ? [{ debugName: "isPinned" }] : [])); this.isExpanded = computed(() => (this.isOpen() || this.isPinned()), ...(ngDevMode ? [{ debugName: "isExpanded" }] : [])); this.isShowingMenuItems = signal(true, ...(ngDevMode ? [{ debugName: "isShowingMenuItems" }] : [])); this.menuItems = inject(MENU_ITEMS_PROVIDER_TOKEN).items; this.currentUrl = signal('', ...(ngDevMode ? [{ debugName: "currentUrl" }] : [])); this.displayMenu = computed(() => !this.screenSize.isCompact() || this.isOpen(), ...(ngDevMode ? [{ debugName: "displayMenu" }] : [])); this.showHeaderMenuButton = computed(() => this.screenSize.isCompact(), ...(ngDevMode ? [{ debugName: "showHeaderMenuButton" }] : [])); this.showPinButton = computed(() => !this.screenSize.isCompact() && this.isExpanded(), ...(ngDevMode ? [{ debugName: "showPinButton" }] : [])); this.caucaLogo = inject(LOGO_PATH_TOKEN); this.screenSize = inject(ScreenSizeService); } setCurrentUrl(url) { this.currentUrl.set(url); } getVersion(applicationVersion) { return applicationVersion ? 'DEV' : applicationVersion; } togglePin() { this.isPinned.set(!this.isPinned()); localStorage.setItem(MENU_STATE_KEY, JSON.stringify(this.isPinned())); } toggleMenu() { this.isOpen.update((isOpen) => !isOpen); } onMouseOver() { if (!this.screenSize.isCompact()) { this.isOpen.set(true); } } onMouseLeave() { if (!this.screenSize.isCompact()) { this.isOpen.set(false); } } hideMenuItems() { this.isShowingMenuItems.set(false); } showMenuItems() { this.isShowingMenuItems.set(true); } getInitialPinState() { return JSON.parse(localStorage.getItem(MENU_STATE_KEY)) ?? false; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: MenuStateService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: MenuStateService, providedIn: 'root' }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: MenuStateService, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }] }); class LoggedInUserHeaderComponent { constructor() { this.loginState = inject(LOGIN_STATE_TOKEN); this.menu = inject(MenuStateService); this.logoutHandler = inject(LOGOUT_HANDLER_TOKEN); } logOut() { this.logoutHandler.logout(); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: LoggedInUserHeaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.3", type: LoggedInUserHeaderComponent, isStandalone: true, selector: "cauca-logged-in-user-header", ngImport: i0, template: "@if (menu.showHeaderMenuButton()) {\r\n <cauca-icon-button id=\"menu-button\" icon=\"menu\" (buttonClick)=\"menu.toggleMenu()\" />\r\n}\r\n\r\n<div class=\"header-bar-filler\"></div>\r\n\r\n<cauca-icon-button class=\"account-button\" icon=\"account_circle\" [matMenuTriggerFor]=\"userMenu\" />\r\n<span class=\"body1 username\">{{loginState.userFullName()}}</span>\r\n\r\n<mat-menu #userMenu=\"matMenu\" xPosition=\"before\">\r\n\r\n <cauca-user-menu-header />\r\n <cauca-menu-separator />\r\n <cauca-language-menu [isSubMenu]=\"true\" />\r\n <cauca-menu-separator />\r\n <cauca-menu-item class=\"logout-menu-item\" icon=\"logout_rounded\" [translateLabel]=\"true\" label=\"headerBar.logoutButtonLabel\" (click)=\"logOut()\" />\r\n\r\n</mat-menu>", styles: [":host{display:flex;align-items:center;gap:4px;padding-right:24px;flex:1 0 0;width:100%}.username{color:#12101499;text-transform:none}.header-bar-filler{flex:1 0 0}\n"], dependencies: [{ kind: "component", type: MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "directive", type: MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "component", type: UserMenuHeaderComponent, selector: "cauca-user-menu-header" }, { kind: "component", type: LanguageMenuComponent, selector: "cauca-language-menu", inputs: ["isSubMenu"] }, { kind: "component", type: MenuSeparatorComponent, selector: "cauca-menu-separator" }, { kind: "component", type: MenuItemComponent, selector: "cauca-menu-item", inputs: ["translateLabel", "trigger"] }, { kind: "component", type: IconButtonComponent, selector: "cauca-icon-button" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: LoggedInUserHeaderComponent, decorators: [{ type: Component, args: [{ selector: 'cauca-logged-in-user-header', imports: [MatMenu, MatMenuTrigger, UserMenuHeaderComponent, LanguageMenuComponent, MenuSeparatorComponent, MenuItemComponent, IconButtonComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (menu.showHeaderMenuButton()) {\r\n <cauca-icon-button id=\"menu-button\" icon=\"menu\" (buttonClick)=\"menu.toggleMenu()\" />\r\n}\r\n\r\n<div class=\"header-bar-filler\"></div>\r\n\r\n<cauca-icon-button class=\"account-button\" icon=\"account_circle\" [matMenuTriggerFor]=\"userMenu\" />\r\n<span class=\"body1 username\">{{loginState.userFullName()}}</span>\r\n\r\n<mat-menu #userMenu=\"matMenu\" xPosition=\"before\">\r\n\r\n <cauca-user-menu-header />\r\n <cauca-menu-separator />\r\n <cauca-language-menu [isSubMenu]=\"true\" />\r\n <cauca-menu-separator />\r\n <cauca-menu-item class=\"logout-menu-item\" icon=\"logout_rounded\" [translateLabel]=\"true\" label=\"headerBar.logoutButtonLabel\" (click)=\"logOut()\" />\r\n\r\n</mat-menu>", styles: [":host{display:flex;align-items:center;gap:4px;padding-right:24px;flex:1 0 0;width:100%}.username{color:#12101499;text-transform:none}.header-bar-filler{flex:1 0 0}\n"] }] }] }); class LoggedInLayoutComponent { static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: LoggedInLayoutComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.3", type: LoggedInLayoutComponent, isStandalone: true, selector: "cauca-logged-in-layout", ngImport: i0, template: "<mat-toolbar>\n <cauca-logged-in-user-header />\n</mat-toolbar>\n\n<div class=\"logged-page-content\" >\n <router-outlet />\n</div>\n", styles: [":host{display:flex;flex-direction:column;overflow:hidden}.mat-toolbar{width:100%;height:72px}.logged-page-content{overflow:auto;flex:1;margin:0;padding:8px 24px 24px;display:flex;min-width:400px;flex-direction:column;box-sizing:border-box}@media (max-width: 500px){.logged-page-content{padding:0;min-height:calc(100svh - 72px);width:100vw;min-width:320px;box-sizing:border-box}}.mat-toolbar-single-row{background-color:#fafafa;padding:0 24px}\n"], dependencies: [{ kind: "directive", type: RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "component", type: LoggedInUserHeaderComponent, selector: "cauca-logged-in-user-header" }, { kind: "component", type: MatToolbar, selector: "mat-toolbar", inputs: ["color"], exportAs: ["matToolbar"] }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: LoggedInLayoutComponent, decorators: [{ type: Component, args: [{ selector: 'cauca-logged-in-layout', standalone: true, imports: [ RouterOutlet, LoggedInUserHeaderComponent, MatToolbar ], template: "<mat-toolbar>\n <cauca-logged-in-user-header />\n</mat-toolbar>\n\n<div class=\"logged-page-content\" >\n <router-outlet />\n</div>\n", styles: [":host{display:flex;flex-direction:column;overflow:hidden}.mat-toolbar{width:100%;height:72px}.logged-page-content{overflow:auto;flex:1;margin:0;padding:8px 24px 24px;display:flex;min-width:400px;flex-direction:column;box-sizing:border-box}@media (max-width: 500px){.logged-page-content{padding:0;min-height:calc(100svh - 72px);width:100vw;min-width:320px;box-sizing:border-box}}.mat-toolbar-single-row{background-color:#fafafa;padding:0 24px}\n"] }] }] }); class HeaderBarComponent { static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: HeaderBarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.3", type: HeaderBarComponent, isStandalone: true, selector: "cauca-header-bar", ngImport: i0, template: "<mat-toolbar>\r\n\r\n <div class=\"header-bar-filler\"></div>\r\n <cauca-logged-in-user-header />\r\n\r\n</mat-toolbar>", styles: [":host{display:flex;width:100%;height:72px;flex-direction:column;justify-content:center;align-items:flex-start}.header-bar-filler{flex:1 0 0}.mat-toolbar-single-row{background-color:#fafafa}\n"], dependencies: [{ kind: "component", type: MatToolbar, selector: "mat-toolbar", inputs: ["color"], exportAs: ["matToolbar"] }, { kind: "component", type: LoggedInUserHeaderComponent, selector: "cauca-logged-in-user-header" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: HeaderBarComponent, decorators: [{ type: Component, args: [{ selector: 'cauca-header-bar', imports: [MatToolbar, LoggedInUserHeaderComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<mat-toolbar>\r\n\r\n <div class=\"header-bar-filler\"></div>\r\n <cauca-logged-in-user-header />\r\n\r\n</mat-toolbar>", styles: [":host{display:flex;width:100%;height:72px;flex-direction:column;justify-content:center;align-items:flex-start}.header-bar-filler{flex:1 0 0}.mat-toolbar-single-row{background-color:#fafafa}\n"] }] }] }); class SideMenuItemComponent { constructor() { this.options = input(null, ...(ngDevMode ? [{ debugName: "options" }] : [])); this.isLastItem = input(false, ...(ngDevMode ? [{ debugName: "isLastItem" }] : [])); this.showIcon = computed(() => this.options().children?.length === 0, ...(ngDevMode ? [{ debugName: "showIcon" }] : [])); this.isParent = computed(() => this.options().isParent, ...(ngDevMode ? [{ debugName: "isParent" }] : [])); this.isSubItem = computed(() => this.options().children?.length > 0, ...(ngDevMode ? [{ debugName: "isSubItem" }] : [])); this.isSelected = computed(() => this.menu.currentUrl().startsWith(this.options().route), ...(ngDevMode ? [{ debugName: "isSelected" }] : [])); this.showChildren = computed(() => this.isSubItem() && this.isSelected(), ...(ngDevMode ? [{ debugName: "showChildren" }] : [])); this.containerClass = computed(() => this.isSubItem() ? 'sub-menu' : undefined, ...(ngDevMode ? [{ debugName: "containerClass" }] : [])); this.itemClass = computed(() => this.getItemClass(this.isSubItem(), this.isParent()), ...(ngDevMode ? [{ debugName: "itemClass" }] : [])); this.children = computed(() => this.options().children, ...(ngDevMode ? [{ debugName: "children" }] : [])); this.route = computed(() => this.isSubItem() ? this.children()[0].route : this.options().route, ...(ngDevMode ? [{ debugName: "route" }] : [])); this.icon = computed(() => this.options().icon, ...(ngDevMode ? [{ debugName: "icon" }] : [])); this.label = computed(() => this.options().label, ...(ngDevMode ? [{ debugName: "label" }] : [])); this.menu = inject(MenuStateService); this.router = inject(Router); } openLink() { this.router.navigate([this.route()]); if (this.menu.showHeaderMenuButton()) { this.menu.toggleMenu(); } } getItemClass(isSubItem, isParent) { switch (true) { case isSubItem: return 'parent-sub-item'; case isParent: return 'parent-item'; default: return 'child-item'; } } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: SideMenuItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.3", type: SideMenuItemComponent, isStandalone: true, selector: "cauca-side-menu-item", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, isLastItem: { classPropertyName: "isLastItem", publicName: "isLastItem", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"item-menu-container\" [ngClass]=\"containerClass()\" [class.selected]=\"isSelected()\">\r\n\r\n <a class=\"item-menu\" (click)=\"openLink()\" [class.selected]=\"isSelected()\" [ngClass]=\"itemClass()\" [class.is-last]=\"isLastItem()\">\r\n\r\n <mat-icon>{{icon()}}</mat-icon>\r\n @if (menu.isExpanded()) {\r\n <span class=\"menu-label\" [ngClass]=\"isParent() ? 'body1' : 'caption'\" >{{label() | translate}}</span>\r\n }\r\n @if (isSubItem()) {\r\n <div class=\"spacer\"></div>\r\n @if (menu.isExpanded()) {\r\n <mat-icon>{{isSelected() ? 'arrow_drop_up' : 'arrow_drop_down'}}</mat-icon>\r\n }\r\n }\r\n\r\n </a>\r\n\r\n <div class=\"sub-menu-items\" [class.hidden]=\"!showChildren()\">\r\n @if (showChildren()) {\r\n @for (child of children(); track child.label) {\r\n <cauca-side-menu-item [options]=\"child\" [isLastItem]=\"$last\" />\r\n }\r\n }\r\n </div>\r\n\r\n</div>", styles: [".menu-label,.mat-icon{color:#fff}.mat-icon{overflow:initial}.item-menu{display:flex;padding:0 16px;align-items:center;gap:8px;text-decoration:none;transition:background-color .3ms linear}.item-menu:hover{background-color:#ffffff0a}.item-menu:hover:not(.child-item):not(.is-last):not(.parent-sub-item.selected){border-radius:16px}.item-menu.is-last:hover{border-radius:0 0 16px 16px}.spacer{flex:1}.parent-item,.parent-sub-item{height:64px;margin:0 8px}.parent-item.selected,.parent-sub-item.selected{border-radius:16px}.parent-item.selected{background-color:#ffffff1f}.parent-item.selected:hover{background-color:#ffffff15}.parent-sub-item.selected{background-color:#433e48;border-radius:16px 16px 0 0;margin:0}.child-item{height:48px}.child-item.selected{background-color:#544f58;font-weight:700}.child-item.selected.is-last{border-radius:0 0 16px 16px}.sub-menu-items.hidden{overflow:hidden;max-height:0;transition:max-height .1s ease-out}.sub-menu-items{max-height:1000px;transition:max-height .3s ease-in;transition-delay:.1s;overflow:hidden}.sub-menu.selected{margin:0 8px;border-radius:16px;background-color:#3c3741}\n"], dependencies: [{ kind: "component", type: SideMenuItemComponent, selector: "cauca-side-menu-item", inputs: ["options", "isLastItem"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "pipe", type: i1.TranslatePipe, name: "translate" }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: SideMenuItemComponent, decorators: [{ type: Component, args: [{ selector: 'cauca-side-menu-item', standalone: true, imports: [MatIcon, TranslateModule, NgClass], template: "<div class=\"item-menu-container\" [ngClass]=\"containerClass()\" [class.selected]=\"isSelected()\">\r\n\r\n <a class=\"item-menu\" (click)=\"openLink()\" [class.selected]=\"isSelected()\" [ngClass]=\"itemClass()\" [class.is-last]=\"isLastItem()\">\r\n\r\n <mat-icon>{{icon()}}</mat-icon>\r\n @if (menu.isExpanded()) {\r\n <span class=\"menu-label\" [ngClass]=\"isParent() ? 'body1' : 'caption'\" >{{label() | translate}}</span>\r\n }\r\n @if (isSubItem()) {\r\n <div class=\"spacer\"></div>\r\n @if (menu.isExpanded()) {\r\n <mat-icon>{{isSelected() ? 'arrow_drop_up' : 'arrow_drop_down'}}</mat-icon>\r\n }\r\n }\r\n\r\n </a>\r\n\r\n <div class=\"sub-menu-items\" [class.hidden]=\"!showChildren()\">\r\n @if (showChildren()) {\r\n @for (child of children(); track child.label) {\r\n <cauca-side-menu-item [options]=\"child\" [isLastItem]=\"$last\" />\r\n }\r\n }\r\n </div>\r\n\r\n</div>", styles: [".menu-label,.mat-icon{color:#fff}.mat-icon{overflow:initial}.item-menu{display:flex;padding:0 16px;align-items:center;gap:8px;text-decoration:none;transition:background-color .3ms linear}.item-menu:hover{background-color:#ffffff0a}.item-menu:hover:not(.child-item):not(.is-last):not(.parent-sub-item.selected){border-radius:16px}.item-menu.is-last:hover{border-radius:0 0 16px 16px}.spacer{flex:1}.parent-item,.parent-sub-item{height:64px;margin:0 8px}.parent-item.selected,.parent-sub-item.selected{border-radius:16px}.parent-item.selected{background-color:#ffffff1f}.parent-item.selected:hover{background-color:#ffffff15}.parent-sub-item.selected{background-color:#433e48;border-radius:16px 16px 0 0;margin:0}.child-item{height:48px}.child-item.selected{background-color:#544f58;font-weight:700}.child-item.selected.is-last{border-radius:0 0 16px 16px}.sub-menu-items.hidden{overflow:hidden;max-height:0;transition:max-height .1s ease-out}.sub-menu-items{max-height:1000px;transition:max-height .3s ease-in;transition-delay:.1s;overflow:hidden}.sub-menu.selected{margin:0 8px;border-radius:16px;background-color:#3c3741}\n"] }] }] }); class SideMenuFooterComponent { constructor() { this.menu = inject(MenuStateService); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: SideMenuFooterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.3", type: SideMenuFooterComponent, isStandalone: true, selector: "cauca-side-menu-footer", ngImport: i0, template: "<div class=\"version list-subheader\">\r\n @if (menu.showPinButton()) { <span class=\"version-label\">Version&nbsp;</span> } {{menu.version()}}\r\n</div>\r\n\r\n@if (menu.showPinButton()) {\r\n <div class=\"pin-button\">\r\n <cauca-icon-button color=\"white\" [icon]=\"menu.isPinned() ? 'chevron_left' : 'chevron_right'\" (click)=\"menu.togglePin()\" />\r\n </div>\r\n}\r\n", styles: [":host{display:flex;flex-direction:row;align-items:center}.version{padding:24px 16px;color:#fff}.pin-button{display:flex;align-self:center;justify-content:flex-end;flex:1 0 0;padding:0 4px}\n"], dependencies: [{ kind: "component", type: IconButtonComponent, selector: "cauca-icon-button" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: SideMenuFooterComponent, decorators: [{ type: Component, args: [{ selector: 'cauca-side-menu-footer', standalone: true, imports: [IconButtonComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"version list-subheader\">\r\n @if (menu.showPinButton()) { <span class=\"version-label\">Version&nbsp;</span> } {{menu.version()}}\r\n</div>\r\n\r\n@if (menu.showPinButton()) {\r\n <div class=\"pin-button\">\r\n <cauca-icon-button color=\"white\" [icon]=\"menu.isPinned() ? 'chevron_left' : 'chevron_right'\" (click)=\"menu.togglePin()\" />\r\n </div>\r\n}\r\n", styles: [":host{display:flex;flex-direction:row;align-items:center}.version{padding:24px 16px;color:#fff}.pin-button{display:flex;align-self:center;justify-content:flex-end;flex:1 0 0;padding:0 4px}\n"] }] }] }); class SideMenuLogoComponent { constructor() { this.size = 'standard'; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: SideMenuLogoComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.3", type: SideMenuLogoComponent, isStandalone: true, selector: "cauca-side-menu-logo", inputs: { logo: "logo", size: "size" }, ngImport: i0, template: "<div class=\"logo-container\">\r\n <img class=\"logo\" alt=\"logo\" [src]=\"logo\" [ngClass]=\"size\">\r\n</div>\r\n", styles: [".logo-container{display:flex;flex-direction:column;gap:8px}.logo{object-fit:contain;object-position:center;max-height:120px}.small{width:90%;max-width:100px}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: SideMenuLogoComponent, decorators: [{ type: Component, args: [{ selector: 'cauca-side-menu-logo', standalone: true, imports: [NgClass], template: "<div class=\"logo-container\">\r\n <img class=\"logo\" alt=\"logo\" [src]=\"logo\" [ngClass]=\"size\">\r\n</div>\r\n", styles: [".logo-container{display:flex;flex-direction:column;gap:8px}.logo{object-fit:contain;object-position:center;max-height:120px}.small{width:90%;max-width:100px}\n"] }] }], propDecorators: { logo: [{ type: Input }], size: [{ type: Input }] } }); class SideMenuContainerComponent { constructor() { this.menu = inject(MenuStateService); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: SideMenuContainerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.3", type: SideMenuContainerComponent, isStandalone: true, selector: "cauca-side-menu-container", ngImport: i0, template: "<div class=\"menu\"\r\n (mouseover)=\"menu.onMouseOver()\"\r\n (mouseleave)=\"menu.onMouseLeave()\"\r\n [class.collapsed]=\"!menu.isExpanded()\"\r\n [class.expanded]=\"menu.isExpanded()\" >\r\n\r\n <ng-content></ng-content>\r\n\r\n</div>", styles: [":host{width:fit-content;display:flex;flex:1 0 0}.menu{background-color:#332e38;display:flex;flex-direction:column;transition:width .2s linear;overflow:auto;z-index:999;position:relative}.collapsed{width:72px}.expanded{width:320px}@media (max-width: 1000px){.expanded{width:100%;max-width:320px}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: SideMenuContainerComponent, decorators: [{ type: Component, args: [{ selector: 'cauca-side-menu-container', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [], template: "<div class=\"menu\"\r\n (mouseover)=\"menu.onMouseOver()\"\r\n (mouseleave)=\"menu.onMouseLeave()\"\r\n [class.collapsed]=\"!menu.isExpanded()\"\r\n [class.expanded]=\"menu.isExpanded()\" >\r\n\r\n <ng-content></ng-content>\r\n\r\n</div>", styles: [":host{width:fit-content;display:flex;flex:1 0 0}.menu{background-color:#332e38;display:flex;flex-direction:column;transition:width .2s linear;overflow:auto;z-index:999;position:relative}.collapsed{width:72px}.expanded{width:320px}@media (max-width: 1000px){.expanded{width:100%;max-width:320px}}\n"] }] }] }); class SideMenuComponent { constructor() { this.menu = inject(MenuStateService); inject(Router).events .pipe(filter(event => event instanceof NavigationStart), takeUntilDestroyed()) .subscribe(route => this.menu.setCurrentUrl(route.url)); } onMouseHover() { this.menu.onMouseOver(); } onMouseOut() { this.menu.onMouseLeave(); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: SideMenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.3", type: SideMenuComponent, isStandalone: true, selector: "cauca-side-menu", ngImport: i0, template: "<cauca-side-menu-container [class.collapsed-menu]=\"!menu.displayMenu()\">\r\n\r\n @if (menu.showHeaderMenuButton()) {\r\n <cauca-icon-button id=\"menu-button\" icon=\"close\" color=\"white\" (buttonClick)=\"menu.toggleMenu()\" />\r\n }\r\n\r\n <cauca-side-menu-logo class=\"top-logo\" [class.collapsed]=\"!menu.isExpanded()\" [logo]=\"menu.caucaLogo\" />\r\n\r\n @if (menu.isShowingMenuItems()) {\r\n @for (item of menu.menuItems(); track item.label) {\r\n <cauca-side-menu-item [options]=\"item\" />\r\n }\r\n }\r\n\r\n <div class=\"spacer\"></div>\r\n\r\n <cauca-side-menu-footer />\r\n\r\n</cauca-side-menu-container>\r\n", styles: [":host{width:fit-content;display:flex;flex:1 0 0}@media (max-width: 1000px){:host{position:absolute}cauca-side-menu-container{width:100vw;height:100%}}.spacer{flex:1 0 0}.top-logo{margin-top:24px;margin-bottom:24px}cauca-side-menu-logo{padding:0 16px;transition:padding .4s ease-out .4s}cauca-side-menu-logo.collapsed{padding:0 2px}#menu-button{float:right;margin-right:8px;display:flex;align-items:end;flex-direction:column;position:absolute;right:0}cauca-side-menu{max-width:unset;transition:max-width .3s ease-in}.collapsed-menu{max-width:0px;transition:max-width .3s ease-out}\n"], dependencies: [{ kind: "component", type: SideMenuContainerComponent, selector: "cauca-side-menu-container" }, { kind: "component", type: SideMenuItemComponent, selector: "cauca-side-menu-item", inputs: ["options", "isLastItem"] }, { kind: "component", type: SideMenuFooterComponent, selector: "cauca-side-menu-footer" }, { kind: "component", type: SideMenuLogoComponent, selector: "cauca-side-menu-logo", inputs: ["logo", "size"] }, { kind: "component", type: IconButtonComponent, selector: "cauca-icon-button" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: SideMenuComponent, decorators: [{ type: Component, args: [{ selector: 'cauca-side-menu', standalone: true, imports: [SideMenuContainerComponent, SideMenuItemComponent, SideMenuFooterComponent, SideMenuLogoComponent, SideMenuContainerComponent, IconButtonComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<cauca-side-menu-container [class.collapsed-menu]=\"!menu.displayMenu()\">\r\n\r\n @if (menu.showHeaderMenuButton()) {\r\n <cauca-icon-button id=\"menu-button\" icon=\"close\" color=\"white\" (buttonClick)=\"menu.toggleMenu()\" />\r\n }\r\n\r\n <cauca-side-menu-logo class=\"top-logo\" [class.collapsed]=\"!menu.isExpanded()\" [logo]=\"menu.caucaLogo\" />\r\n\r\n @if (menu.isShowingMenuItems()) {\r\n @for (item of menu.menuItems(); track item.label) {\r\n <cauca-side-menu-item [options]=\"item\" />\r\n }\r\n }\r\n\r\n <div class=\"spacer\"></div>\r\n\r\n <cauca-side-menu-footer />\r\n\r\n</cauca-side-menu-container>\r\n", styles: [":host{width:fit-content;display:flex;flex:1 0 0}@media (max-width: 1000px){:host{position:absolute}cauca-side-menu-container{width:100vw;height:100%}}.spacer{flex:1 0 0}.top-logo{margin-top:24px;margin-bottom:24px}cauca-side-menu-logo{padding:0 16px;transition:padding .4s ease-out .4s}cauca-side-menu-logo.collapsed{padding:0 2px}#menu-button{float:right;margin-right:8px;display:flex;align-items:end;flex-direction:column;position:absolute;right:0}cauca-side-menu{max-width:unset;transition:max-width .3s ease-in}.collapsed-menu{max-width:0px;transition:max-width .3s ease-out}\n"] }] }], ctorParameters: () => [] }); class LoggedOutUserHeaderComponent { static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: LoggedOutUserHeaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.3", type: LoggedOutUserHeaderComponent, isStandalone: true, selector: "cauca-logged-out-user-header", ngImport: i0, template: "<div class=\"header-bar-filler\"></div>\r\n\r\n<cauca-language-menu />", styles: [":host{display:flex;align-items:center;flex:1 0 0;width:100%}.header-bar-filler{flex:1 0 0}\n"], dependencies: [{ kind: "component", type: LanguageMenuComponent, selector: "cauca-language-menu", inputs: ["isSubMenu"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: LoggedOutUserHeaderComponent, decorators: [{ type: Component, args: [{ selector: 'cauca-logged-out-user-header', standalone: true, imports: [LanguageMenuComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"header-bar-filler\"></div>\r\n\r\n<cauca-language-menu />", styles: [":host{display:flex;align-items:center;flex:1 0 0;width:100%}.header-bar-filler{flex:1 0 0}\n"] }] }] }); /* * Public API Surface of cauca-menu */ /** * Generated bundle index. Do not edit. */ export { APP_VERSION_TOKEN, HeaderBarComponent, LOGIN_STATE_TOKEN, LOGOUT_HANDLER_TOKEN, LOGO_PATH_TOKEN, LoggedInLayoutComponent, LoggedOutUserHeaderComponent, MENU_ITEMS_PROVIDER_TOKEN, MENU_STATE_KEY, MenuSeparatorComponent, MenuStateService, ScreenSizeService, SideMenuComponent, UserAgentReaderService, provideCaucaMenu }; //# sourceMappingURL=cauca-911-menu.mjs.map