tp-responsive-menu/tp-responsive-menu.js
2023-09-02 00:17:38 +02:00

108 lines
2.2 KiB
JavaScript

/**
@license
Copyright (c) 2022 trading_peter
This program is available under Apache License Version 2.0
*/
import '@tp/tp-media-query/tp-media-query.js';
import { LitElement, html, css } from 'lit';
class TpResponsiveMenu extends LitElement {
static get styles() {
return [
css`
:host {
display: block;
pointer-events: none;
}
.content {
display: flex;
flex-direction: column;
background: #ffffff;
z-index: 1;
pointer-events: all;
}
:host([responsive]) {
position: fixed;
inset: 0;
z-index: 9999;
}
:host([responsive]) .content {
position: absolute;
top: 0;
left: 0;
bottom: 0;
transform: translateX(-100%);
transition: transform 300ms ease-in-out;
}
:host([responsive][visible]) .content {
transform: translateX(0);
}
.backdrop {
position: absolute;
inset: 0;
background: #000000;
opacity: 0;
transition: opacity 300ms ease-in-out;
pointer-events: none;
}
:host([visible]) .backdrop {
opacity: 0.7;
pointer-events: all;
}
`
];
}
render() {
return html`
<tp-media-query query="(min-width: 0) and (max-width: ${this.responsiveWidth}px)" @media-query-update=${this._queryUpdated}></tp-media-query>
<div class="content" part="content">
<slot></slot>
</div>
<div class="backdrop" @click=${this.close}></div>
`;
}
static get properties() {
return {
responsive: { type: Boolean, reflect: true },
responsiveWidth: { type: String },
visible: { type: Boolean, reflect: true },
};
}
constructor() {
super();
this.responsiveWidth = '480';
this.visible = false;
}
open() {
this.visible = true;
}
close() {
this.visible = false;
}
toggle() {
this.visible = !this.visible;
}
_queryUpdated(e) {
this.responsive = e.detail;
}
}
window.customElements.define('tp-responsive-menu', TpResponsiveMenu);