UNPKG

@synergy-design-system/components

Version:

This package provides the base of the Synergy Design System as native web components. It uses [lit](https://www.lit.dev) and parts of [shoelace](https://shoelace.style/). Synergy officially supports the latest two versions of all major browsers (as define

213 lines (208 loc) 6.46 kB
import { filterOnlyNavItems, getAssignedElementsForSlot, hideNavigationItem, showNavigationItem } from "./chunk.OJ3N7TWP.js"; import { prio_nav_styles_default } from "./chunk.74N5WLM5.js"; import { SynNavItem } from "./chunk.VI5FLXBL.js"; import { SynMenu } from "./chunk.2UFVMHUX.js"; import { SynDropdown } from "./chunk.L5NLWYJZ.js"; import { SynIcon } from "./chunk.RCBSMXQH.js"; import { LocalizeController } from "./chunk.OAQRCZOO.js"; import { component_styles_default } from "./chunk.NLYVOJGK.js"; import { SynergyElement } from "./chunk.3THJTCRO.js"; import { __decorateClass } from "./chunk.Z4XV3SMG.js"; // src/components/prio-nav/prio-nav.component.ts import { classMap } from "lit/directives/class-map.js"; import { html } from "lit/static-html.js"; import { query, state } from "lit/decorators.js"; var SynPrioNav = class extends SynergyElement { constructor() { super(...arguments); this.localize = new LocalizeController(this); this.itemPositionsCached = false; this.amountOfNavItems = 0; this.amountOfVisibleItems = 0; this.hasItemsInDropdown = false; } /** * Get a list of all slotted `<syn-nav-item />` elements * that are either in the main slot or the priority menu slot */ getSlottedNavItems() { const navItemsInDefaultSlot = filterOnlyNavItems(getAssignedElementsForSlot(this.defaultSlot)); const navItemsInMenuSlot = filterOnlyNavItems(getAssignedElementsForSlot(this.menuSlot)); return navItemsInDefaultSlot.concat(navItemsInMenuSlot); } /** * Cache the items right offset position to make faster checks placement into priority menu * @param items The items to cache the position for */ cacheItemPositions(items) { const { left } = this.horizontalNav.getBoundingClientRect(); items.forEach((item) => { item.removeAttribute("slot"); const { right } = item.getBoundingClientRect(); item.dataset.right = (right - left).toString(); }); this.itemPositionsCached = true; } /** * Determines which items should be shown or hidden, depending on the current width */ handlePriorityMenu() { const navItems = this.getSlottedNavItems(); if (!this.itemPositionsCached) { this.cacheItemPositions(navItems); } const { width } = this.horizontalNav.getBoundingClientRect(); const reservedPrioMenuSize = this.priorityMenu.classList.contains("priority-menu--hidden") ? 0 : this.priorityMenu.clientWidth; const finalWidth = width - reservedPrioMenuSize; let firstHiddenItemRightPos; const lastNavItem = navItems.at(-1); const itemVisibilities = navItems.map((item) => { const measureWidth = item === lastNavItem ? width : finalWidth; const isHidden = !!(firstHiddenItemRightPos || parseFloat(item.dataset.right) > measureWidth); if (isHidden && !firstHiddenItemRightPos) { firstHiddenItemRightPos = parseFloat(item.dataset.right); } return { isHidden, item }; }); const visibleItems = itemVisibilities.filter(({ isHidden }) => !isHidden).length; const hasOnlyOneItem = visibleItems === 1; itemVisibilities.forEach(({ item, isHidden }) => { if (isHidden || hasOnlyOneItem) { hideNavigationItem(item); } else { showNavigationItem(item); } }); this.hasItemsInDropdown = visibleItems !== navItems.length; this.amountOfVisibleItems = hasOnlyOneItem ? 0 : visibleItems; } renderPriorityMenu() { return html` <syn-dropdown class=${classMap({ "priority-menu": true, "priority-menu--has-visible-items": this.amountOfVisibleItems !== 0, "priority-menu--hidden": !this.hasItemsInDropdown })} part="priority-menu" placement="bottom-end" > <syn-nav-item class="priority-menu__nav-item" slot="trigger" horizontal part="priority-menu-nav-item"> <syn-icon class="priority-menu__icon" label="More" library="system" name="more" part="priority-menu-icon" slot="prefix" > </syn-icon> <span class=${classMap({ "priority-menu__label": true, "priority-menu__label--visible": this.amountOfVisibleItems === 0 })} part="priority-menu-label" > ${this.localize.term("menu")} </span> </syn-nav-item> <syn-menu part="priority-menu-container"> <slot name="menu"></slot> </syn-menu> </syn-dropdown> `; } slotChange() { const slottedItems = this.getSlottedNavItems(); if (slottedItems.length !== this.amountOfNavItems) { this.cacheItemPositions(slottedItems); this.handlePriorityMenu(); this.amountOfNavItems = slottedItems.length; } } firstUpdated() { this.getSlottedNavItems().forEach((item) => { var _a; item.dataset.originalRole = (_a = item.getAttribute("role")) != null ? _a : ""; }); } connectedCallback() { super.connectedCallback(); this.resizeObserver = new ResizeObserver(() => this.handlePriorityMenu()); this.resizeObserver.observe(this); } disconnectedCallback() { super.disconnectedCallback(); this.resizeObserver.unobserve(this); } render() { return html` <nav class="horizontal-nav" part="base"> <slot @slotchange=${this.slotChange}></slot> ${this.renderPriorityMenu()} </nav> `; } }; SynPrioNav.styles = [component_styles_default, prio_nav_styles_default]; SynPrioNav.dependencies = { "syn-dropdown": SynDropdown, "syn-icon": SynIcon, "syn-menu": SynMenu, "syn-nav-item": SynNavItem }; __decorateClass([ query("slot:not([name])") ], SynPrioNav.prototype, "defaultSlot", 2); __decorateClass([ query("slot[name=menu]") ], SynPrioNav.prototype, "menuSlot", 2); __decorateClass([ query(".horizontal-nav") ], SynPrioNav.prototype, "horizontalNav", 2); __decorateClass([ query(".priority-menu") ], SynPrioNav.prototype, "priorityMenu", 2); __decorateClass([ state() ], SynPrioNav.prototype, "itemPositionsCached", 2); __decorateClass([ state() ], SynPrioNav.prototype, "amountOfNavItems", 2); __decorateClass([ state() ], SynPrioNav.prototype, "amountOfVisibleItems", 2); __decorateClass([ state() ], SynPrioNav.prototype, "hasItemsInDropdown", 2); export { SynPrioNav }; //# sourceMappingURL=chunk.6CTU4ASM.js.map