@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
353 lines (344 loc) • 11.4 kB
JavaScript
import {
side_nav_styles_default
} from "./chunk.EFSUQWJZ.js";
import {
SynNavItem
} from "./chunk.VI5FLXBL.js";
import {
SynDivider
} from "./chunk.YOAPSA7L.js";
import {
SynDrawer
} from "./chunk.WH5IZKFX.js";
import {
unlockBodyScrolling
} from "./chunk.5732DMBC.js";
import {
waitForEvent
} from "./chunk.C2ENQBPM.js";
import {
getAnimation,
setAnimation,
setDefaultAnimation
} from "./chunk.7JGKUB4A.js";
import {
HasSlotController
} from "./chunk.WVVQK5TE.js";
import {
SynIcon
} from "./chunk.RCBSMXQH.js";
import {
LocalizeController
} from "./chunk.OAQRCZOO.js";
import {
enableDefaultSettings
} from "./chunk.HYFCK7MM.js";
import {
watch
} from "./chunk.BVZQ6QSY.js";
import {
component_styles_default
} from "./chunk.NLYVOJGK.js";
import {
SynergyElement
} from "./chunk.3THJTCRO.js";
import {
__decorateClass
} from "./chunk.Z4XV3SMG.js";
// src/components/side-nav/side-nav.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 SynSideNav = class extends SynergyElement {
constructor() {
super();
this.hasSlotController = new HasSlotController(this, "[default]", "footer");
this.localize = new LocalizeController(this);
this.isAnimationActive = false;
this.open = false;
this.rail = false;
this.variant = "default";
this.noFocusTrapping = false;
this.handleMouseEnter = this.handleMouseEnter.bind(this);
this.handleMouseLeave = this.handleMouseLeave.bind(this);
this.addEventListener("syn-initial-focus", (event) => {
if (this.variant !== "default") {
event.preventDefault();
this.drawer["originalTrigger"] = null;
}
});
this.addEventListener("focusin", (event) => {
const targetTag = event.target.tagName.toLowerCase();
if (targetTag === "syn-nav-item" && this.variant === "rail" && !this.open) {
this.open = true;
}
});
this.addEventListener("focusout", (event) => {
var _a;
const targetTag = event.target.tagName.toLowerCase();
const relatedTargetTag = (_a = event.relatedTarget) == null ? void 0 : _a.tagName.toLowerCase();
if (targetTag === "syn-nav-item" && relatedTargetTag !== "syn-nav-item" && this.variant === "rail" && this.open) {
this.open = false;
}
});
}
setDelayedCallback(callback) {
clearTimeout(this.timeout);
this.timeout = setTimeout(callback, 100);
}
handleMouseEnter() {
this.setDelayedCallback(() => {
this.open = true;
});
}
handleMouseLeave() {
this.setDelayedCallback(() => {
this.open = false;
});
}
handleRequestClose() {
if (this.open) {
this.open = false;
}
}
addMouseListener() {
var _a, _b;
(_a = this.drawer.shadowRoot.querySelector(".drawer__panel")) == null ? void 0 : _a.addEventListener("mouseenter", this.handleMouseEnter);
(_b = this.drawer.shadowRoot.querySelector(".drawer__panel")) == null ? void 0 : _b.addEventListener("mouseleave", this.handleMouseLeave);
}
removeMouseListener() {
var _a, _b;
(_a = this.drawer.shadowRoot.querySelector(".drawer__panel")) == null ? void 0 : _a.removeEventListener("mouseenter", this.handleMouseEnter);
(_b = this.drawer.shadowRoot.querySelector(".drawer__panel")) == null ? void 0 : _b.removeEventListener("mouseleave", this.handleMouseLeave);
}
setDrawerAnimations() {
const showAnimation = getAnimation(this, `sideNav.show${this.variant === "default" ? "NonRail" : "Rail"}`, { dir: this.localize.dir() });
const hideAnimation = getAnimation(this, `sideNav.hide${this.variant === "default" ? "NonRail" : "Rail"}`, { dir: this.localize.dir() });
const hideOverlay = getAnimation(this, "sideNav.overlay.hide", { dir: this.localize.dir() });
const showOverlay = getAnimation(this, "sideNav.overlay.show", { dir: this.localize.dir() });
setAnimation(this.drawer, "drawer.showStart", showAnimation);
setAnimation(this.drawer, "drawer.hideStart", hideAnimation);
setAnimation(this.drawer, "drawer.overlay.hide", hideOverlay);
setAnimation(this.drawer, "drawer.overlay.show", showOverlay);
}
handleVariantChange() {
this.setDrawerAnimations();
this.drawer.forceVisibility(this.variant !== "default");
switch (this.variant) {
case "rail":
this.addMouseListener();
break;
case "sticky":
case "default":
default:
this.removeMouseListener();
}
}
handleOpenChange() {
if (this.variant === "default") {
return;
}
this.isAnimationActive = true;
waitForEvent(this.drawer, `syn-after-${this.open ? "show" : "hide"}`).then(() => {
this.isAnimationActive = false;
});
}
handleFocusTrapping() {
if (this.variant === "default") {
if (this.noFocusTrapping) {
this.drawer.modal.activateExternal();
} else {
this.drawer.modal.deactivateExternal();
}
}
}
/** Shows the side-nav. */
async show() {
if (this.open) {
return void 0;
}
this.open = true;
return waitForEvent(this.drawer, "syn-after-show");
}
/** Hides the side-nav */
async hide() {
if (!this.open) {
return void 0;
}
this.open = false;
return waitForEvent(this.drawer, "syn-after-hide");
}
/**
* Initial setup for first render like special variant="rail" and variant="sticky" handling
* and drawer animations.
* */
firstUpdated() {
this.setDrawerAnimations();
this.drawer.updateComplete.then(() => {
this.drawer.forceVisibility(this.variant !== "default");
this.drawer.shadowRoot.querySelector(".drawer__panel").tabIndex = -1;
});
switch (this.variant) {
case "rail":
this.drawer.updateComplete.then(() => {
this.addMouseListener();
});
break;
case "sticky":
break;
case "default":
default:
if (this.noFocusTrapping) {
this.drawer.modal.activateExternal();
}
}
}
disconnectedCallback() {
super.disconnectedCallback();
if (this.drawer) {
unlockBodyScrolling(this.drawer);
this.drawer.modal.deactivate();
}
}
// eslint-disable-next-line complexity
willUpdate(changedProperties) {
super.willUpdate(changedProperties);
if (changedProperties.has("rail")) {
if (this.rail) {
console.warn("<syn-side-nav/>: The `rail` attribute is deprecated. Please use the `variant` attribute with `rail` instead. It will be removed in synergy version 3.0");
}
if (!changedProperties.has("variant") || this.rail) {
this.variant = this.rail ? "rail" : "default";
}
}
}
toggleOpenState() {
this.open = !this.open;
}
// eslint-disable-next-line complexity
render() {
const isTouch = window.navigator.maxTouchPoints > 0 || !!("ontouchstart" in window);
const hasFooter = this.hasSlotController.test("footer");
const showFooterDivider = hasFooter || this.variant === "sticky";
return html`
<nav
class=${classMap({
"side-nav": true,
"side-nav--animation": this.isAnimationActive,
"side-nav--fix": this.variant === "default",
"side-nav--has-footer": hasFooter,
"side-nav--open": this.open,
"side-nav--rail": this.variant === "rail",
"side-nav--sticky": this.variant === "sticky",
"side-nav--touch": isTouch
})}
part="base"
>
<syn-drawer
class="side-nav__drawer"
?contained=${this.variant !== "default"}
exportparts="overlay,panel,body,base:drawer__base"
label=${this.localize.term("sideNav")}
no-header
?open=${this.open}
part="drawer"
placement="start"
-request-close=${this.handleRequestClose}
>
<div part="content-container" class="side-nav__content-container">
<slot part="content"></slot>
</div>
<footer class="side-nav__footer" part="footer-container" slot="footer">
${showFooterDivider ? html`<syn-divider part="footer-divider" class="side-nav__footer-divider"></syn-divider>` : ""}
<slot name="footer" part="footer" ></slot>
${this.variant === "sticky" ? html`<syn-nav-item part="toggle-nav-item" class="side-nav__toggle-nav-item" =${this.toggleOpenState} ?divider=${hasFooter}>
<slot name="toggle-icon" slot="prefix" class="side-nav__toggle-icon">
<syn-icon library="system" name="sticky_sidebar" part="toggle-icon"></syn-icon>
</slot>
<slot name="toggle-label" part="toggle-label">
${!this.open && !this.isAnimationActive ? this.localize.term("sideNavShow") : this.localize.term("sideNavHide")}
</slot>
</syn-nav-item>` : ""}
</footer>
</syn-drawer>
</nav>
`;
}
};
SynSideNav.styles = [component_styles_default, side_nav_styles_default];
SynSideNav.dependencies = {
"syn-divider": SynDivider,
"syn-drawer": SynDrawer,
"syn-icon": SynIcon,
"syn-nav-item": SynNavItem
};
__decorateClass([
state()
], SynSideNav.prototype, "isAnimationActive", 2);
__decorateClass([
query(".side-nav__drawer")
], SynSideNav.prototype, "drawer", 2);
__decorateClass([
property({ reflect: true, type: Boolean })
], SynSideNav.prototype, "open", 2);
__decorateClass([
property({ reflect: true, type: Boolean })
], SynSideNav.prototype, "rail", 2);
__decorateClass([
property({ reflect: true })
], SynSideNav.prototype, "variant", 2);
__decorateClass([
property({ attribute: "no-focus-trapping", reflect: true, type: Boolean })
], SynSideNav.prototype, "noFocusTrapping", 2);
__decorateClass([
watch("variant", { waitUntilFirstUpdate: true })
], SynSideNav.prototype, "handleVariantChange", 1);
__decorateClass([
watch("open", { waitUntilFirstUpdate: true })
], SynSideNav.prototype, "handleOpenChange", 1);
__decorateClass([
watch("noFocusTrapping", { waitUntilFirstUpdate: true })
], SynSideNav.prototype, "handleFocusTrapping", 1);
SynSideNav = __decorateClass([
enableDefaultSettings("SynSideNav")
], SynSideNav);
setDefaultAnimation("sideNav.showRail", {
keyframes: [
{ width: "var(--side-nav-rail-width)" },
{ width: "var(--side-nav-open-width)" }
],
options: { duration: 250, easing: "ease" }
});
setDefaultAnimation("sideNav.showNonRail", {
keyframes: [
{ opacity: 0, translate: "-100%" },
{ opacity: 1, translate: "0" }
],
options: { duration: 250, easing: "ease" }
});
setDefaultAnimation("sideNav.hideNonRail", {
keyframes: [
{ opacity: 1, translate: "0" },
{ opacity: 0, translate: "-100%" }
],
options: { duration: 250, easing: "ease" }
});
setDefaultAnimation("sideNav.hideRail", {
keyframes: [
{ width: "var(--side-nav-open-width)" },
{ width: "var(--side-nav-rail-width)" }
],
options: { duration: 250, easing: "ease" }
});
setDefaultAnimation("sideNav.overlay.show", {
keyframes: [{ opacity: 0 }, { opacity: 1 }],
options: { duration: 250 }
});
setDefaultAnimation("sideNav.overlay.hide", {
keyframes: [{ opacity: 1 }, { opacity: 0 }],
options: { duration: 250 }
});
export {
SynSideNav
};
//# sourceMappingURL=chunk.EO4UTDA2.js.map