UNPKG

@synergy-design-system/components

Version:
239 lines (231 loc) 7.79 kB
import { header_styles_default } from "./chunk.HUJAKIZN.js"; import { HasSlotController } from "./chunk.CHFWLQN5.js"; import { SynIcon } from "./chunk.KODS2CCZ.js"; import { LocalizeController } from "./chunk.ZXMSJF2M.js"; import { watch } from "./chunk.UR2E7Y2Q.js"; import { component_styles_default } from "./chunk.2NT3B5WJ.js"; import { SynergyElement } from "./chunk.L2IYPRPF.js"; import { __decorateClass } from "./chunk.VK2FVWOF.js"; // src/components/header/header.component.ts import { classMap } from "lit/directives/class-map.js"; import { html } from "lit/static-html.js"; import { property, query, state } from "lit/decorators.js"; var SynHeader = class extends SynergyElement { constructor() { super(...arguments); this.hasSlotController = new HasSlotController(this, "[default]", "logo", "label", "meta-navigation", "navigation"); this.localize = new LocalizeController(this); /* * #587: If the side nav is animating, we should not allow to trigger the burger menu */ this.isSideNavAnimating = false; this.label = ""; this.burgerMenu = "hidden"; this.sticky = false; } toggleBurgerMenu() { switch (this.burgerMenu) { case "closed": this.burgerMenu = "open"; break; case "open": this.burgerMenu = "closed"; break; default: break; } } handleBurgerMenuToggle() { if (this.sideNav && this.sideNav.variant === "default" && !this.isSideNavAnimating) { this.sideNav.open = !this.sideNav.open; } if (!this.isSideNavAnimating) { this.toggleBurgerMenu(); } } /** * Automatically update the burger menu icon based * on the state of the side-nav, if one is connected. */ updateBurgerMenuBasedOnSideNav() { if (this.sideNav) { if (this.sideNav.variant !== "default") { this.burgerMenu = "hidden"; } else { this.burgerMenu = this.sideNav.open ? "open" : "closed"; } } } /** * #1130: Automatically set the correct styles for vertical syn-dividers in the meta navigation. * Dividers may be slotted directly in the meta navigation or be nested in another element, e.g. a wrapper for the meta navigation. * Horizontal dividers are not supported in the meta navigation and we don't want to override any styles for them that might be set by the user. */ updateMetaNavigation() { const foundDividers = []; this.metaNavigationSlot.assignedElements({ flatten: true }).forEach((el) => { if (el.tagName.toLowerCase() === "syn-divider") { foundDividers.push(el); } else { const directChildDividers = el.querySelectorAll(":scope > syn-divider"); if (directChildDividers.length) { foundDividers.push(...directChildDividers); } } }); const cssText = "--spacing: var(--syn-spacing-x-small); align-self: center; display: flex; height: var(--metanavigation-item-size);"; foundDividers.filter((divider) => divider.hasAttribute("vertical")).forEach((divider) => { divider.style.cssText += cssText; }); } handleBurgerMenu() { const myEvt = `syn-burger-menu-${this.burgerMenu}`; this.emit(myEvt); } connectedCallback() { super.connectedCallback(); this.mutationObserver = new MutationObserver(() => this.updateBurgerMenuBasedOnSideNav()); } firstUpdated() { this.updateComplete.then(() => { const sideNav = document.querySelector("syn-side-nav"); this.connectSideNavigation(sideNav); }); } disconnectedCallback() { super.disconnectedCallback(); this.mutationObserver.disconnect(); } /** * Connect a `syn-side-nav` to add automatic interaction of the header with the side navigation * like showing the burger menu icon and open / close handling. * * If no side navigation is connected, the header will use the first `syn-side-nav` element it * finds. * * @param sideNav The side navigation to connect to the header */ connectSideNavigation(sideNav) { this.mutationObserver.disconnect(); this.sideNav = sideNav || document.querySelector("syn-side-nav"); if (this.sideNav) { this.updateBurgerMenuBasedOnSideNav(); this.mutationObserver.observe(this.sideNav, { attributeFilter: ["open", "variant"], attributes: true }); const isAnimating = (e) => { if (e.target !== this.sideNav) { return; } this.isSideNavAnimating = true; }; const isNotAnimating = (e) => { if (e.target !== this.sideNav) { return; } this.isSideNavAnimating = false; }; this.sideNav.addEventListener("syn-show", isAnimating); this.sideNav.addEventListener("syn-hide", isAnimating); this.sideNav.addEventListener("syn-after-show", isNotAnimating); this.sideNav.addEventListener("syn-after-hide", isNotAnimating); } } render() { const hasNavigation = this.hasSlotController.test("navigation"); const showBurgerMenu = this.burgerMenu !== "hidden"; return html` <header class=${classMap({ header: true, "header--has-burger-menu": showBurgerMenu, "header--has-navigation": hasNavigation })} part="base" > <!-- .header__content --> <div part="content" class="header__content"> ${showBurgerMenu ? html` <button aria-label=${this.localize.term(this.burgerMenu === "closed" ? "openMenu" : "closeMenu")} class="header__burger-menu-toggle" @click=${this.handleBurgerMenuToggle} part="burger-menu-toggle-button" type="button" > ${this.burgerMenu === "open" ? html` <slot name="open-burger-menu-icon"> <syn-icon name="x-lg" library="system"></syn-icon> </slot> ` : html` <slot name="closed-burger-menu-icon"> <syn-icon name="menu" library="system"></syn-icon> </slot> `} </button> ` : ""} <div part="logo" class="header__logo"> <slot name="logo"> <syn-icon name="logo-color" library="system" label="SICK Sensor Intelligence"></syn-icon> </slot> </div> <div part="label" class="header__label"> <slot name="label"> ${this.label} </slot> </div> <div part="meta-navigation" class="header__meta-navigation"> <slot @slotchange=${this.updateMetaNavigation} name="meta-navigation"></slot> </div> </div> <!-- /.header__content --> <div part="navigation" class="header__navigation"> <slot name="navigation"></slot> </div> </header> `; } }; SynHeader.styles = [ component_styles_default, header_styles_default ]; SynHeader.dependencies = { "syn-icon": SynIcon }; __decorateClass([ query('slot[name="meta-navigation"]') ], SynHeader.prototype, "metaNavigationSlot", 2); __decorateClass([ property() ], SynHeader.prototype, "label", 2); __decorateClass([ property({ attribute: "burger-menu", reflect: true }) ], SynHeader.prototype, "burgerMenu", 2); __decorateClass([ property({ reflect: true, type: Boolean }) ], SynHeader.prototype, "sticky", 2); __decorateClass([ state() ], SynHeader.prototype, "sideNav", 2); __decorateClass([ watch("burgerMenu", { waitUntilFirstUpdate: true }) ], SynHeader.prototype, "handleBurgerMenu", 1); export { SynHeader }; //# sourceMappingURL=chunk.JDDXIPHU.js.map