maxzilla-ui-core
Version:
Core web components library for Maxzilla UI built with Lit Element
297 lines (270 loc) • 8.04 kB
JavaScript
import { css as c, LitElement as p, html as m } from "lit";
import { property as l, state as h, customElement as u } from "lit/decorators.js";
import { classMap as v } from "lit/directives/class-map.js";
import { b } from "./base-CQAGJ0rS.js";
import { a as f } from "./animations-DVdvSNId.js";
var g = Object.defineProperty, y = Object.getOwnPropertyDescriptor, e = (o, s, r, i) => {
for (var a = i > 1 ? void 0 : i ? y(s, r) : s, n = o.length - 1, d; n >= 0; n--)
(d = o[n]) && (a = (i ? d(s, r, a) : d(a)) || a);
return i && a && g(s, r, a), a;
};
let t = class extends p {
constructor() {
super(...arguments), this.open = !1, this.title = "", this.size = "md", this.animation = "scale", this.noCloseOnBackdrop = !1, this.noCloseButton = !1, this.scrollable = !1, this.isAnimating = !1, this.handleBackdropClick = (o) => {
o.target === o.currentTarget && !this.noCloseOnBackdrop && this.close();
}, this.handleCloseClick = () => {
this.close();
}, this.handleKeyDown = (o) => {
o.key === "Escape" && this.open && this.close();
};
}
show() {
this.open = !0, this.isAnimating = !0, document.addEventListener("keydown", this.handleKeyDown), document.body.style.overflow = "hidden", this.dispatchEvent(
new CustomEvent("mz-modal-show", {
bubbles: !0,
composed: !0
})
), setTimeout(() => {
this.isAnimating = !1;
}, 300);
}
close() {
this.isAnimating = !0, this.dispatchEvent(
new CustomEvent("mz-modal-close", {
bubbles: !0,
composed: !0,
cancelable: !0
})
) && setTimeout(() => {
this.open = !1, this.isAnimating = !1, document.removeEventListener("keydown", this.handleKeyDown), document.body.style.overflow = "", this.dispatchEvent(
new CustomEvent("mz-modal-closed", {
bubbles: !0,
composed: !0
})
);
}, 150);
}
updated(o) {
o.has("open") && (this.open ? this.show() : this.close());
}
render() {
if (!this.open) return m``;
const o = {
modal: !0,
"modal--open": this.open && !this.isAnimating,
[`modal--${this.animation}`]: !0
};
return m`
<div
class=${v(o)}
=${this.handleBackdropClick}
>
<div class="modal-backdrop"></div>
<div class="modal-content" role="dialog" aria-modal="true" aria-labelledby="modal-title">
<div class="modal-header">
<h2 id="modal-title" class="modal-title">
<slot name="title">${this.title}</slot>
</h2>
<button
class="modal-close"
aria-label="Close modal"
=${this.handleCloseClick}
>
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M18 6L6 18M6 6l12 12"/>
</svg>
</button>
</div>
<div class="modal-body">
<slot></slot>
</div>
<div class="modal-footer">
<slot name="footer"></slot>
</div>
</div>
</div>
`;
}
};
t.styles = [
b,
f,
c`
:host {
--modal-backdrop: rgba(0, 0, 0, 0.5);
--modal-background: var(--mz-color-neutral-0);
--modal-border-radius: var(--mz-radius-xl);
--modal-shadow: var(--mz-shadow-xl);
--modal-max-width: 32rem;
--modal-max-height: 80vh;
--modal-padding: var(--mz-space-6);
}
:host([open]) {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 1000;
}
.modal {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
display: flex;
align-items: center;
justify-content: center;
padding: var(--mz-space-4);
opacity: 0;
visibility: hidden;
transition: all var(--mz-transition-slow);
}
.modal--open {
opacity: 1;
visibility: visible;
}
.modal-backdrop {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: var(--modal-backdrop);
backdrop-filter: blur(4px);
}
.modal-content {
position: relative;
max-width: var(--modal-max-width);
max-height: var(--modal-max-height);
width: 100%;
background: var(--modal-background);
border-radius: var(--modal-border-radius);
box-shadow: var(--modal-shadow);
overflow: hidden;
transform: scale(0.9) translateY(20px);
transition: all var(--mz-transition-spring);
}
.modal--open .modal-content {
transform: scale(1) translateY(0);
}
.modal-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: var(--modal-padding);
border-bottom: 1px solid var(--mz-color-neutral-200);
}
.modal-title {
font-size: var(--mz-text-lg);
font-weight: 600;
margin: 0;
}
.modal-close {
display: flex;
align-items: center;
justify-content: center;
width: 2rem;
height: 2rem;
border: none;
background: transparent;
border-radius: var(--mz-radius-md);
cursor: pointer;
color: var(--mz-color-neutral-500);
transition: var(--mz-transition-normal);
}
.modal-close:hover {
background: var(--mz-color-neutral-100);
color: var(--mz-color-neutral-700);
}
.modal-close:focus-visible {
outline: 2px solid var(--mz-color-primary-500);
outline-offset: 2px;
}
.modal-body {
padding: var(--modal-padding);
overflow-y: auto;
max-height: calc(var(--modal-max-height) - 8rem);
}
.modal-footer {
display: flex;
gap: var(--mz-space-3);
justify-content: flex-end;
padding: var(--modal-padding);
border-top: 1px solid var(--mz-color-neutral-200);
background: var(--mz-color-neutral-50);
}
/* Size variants */
:host([size='sm']) {
--modal-max-width: 24rem;
}
:host([size='lg']) {
--modal-max-width: 48rem;
}
:host([size='xl']) {
--modal-max-width: 64rem;
}
:host([size='full']) {
--modal-max-width: calc(100vw - 2rem);
--modal-max-height: calc(100vh - 2rem);
}
/* Animation variants */
.modal--fade .modal-content {
transform: none;
opacity: 0;
}
.modal--fade.modal--open .modal-content {
opacity: 1;
}
.modal--slide-up .modal-content {
transform: translateY(100%);
}
.modal--slide-up.modal--open .modal-content {
transform: translateY(0);
}
/* Disable close on backdrop */
:host([no-close-on-backdrop]) .modal-backdrop {
pointer-events: none;
}
/* Hide close button */
:host([no-close-button]) .modal-close {
display: none;
}
/* Scrollable content */
:host([scrollable]) .modal-body {
max-height: 60vh;
}
`
];
e([
l({ type: Boolean, reflect: !0 })
], t.prototype, "open", 2);
e([
l({ type: String })
], t.prototype, "title", 2);
e([
l({ type: String, reflect: !0 })
], t.prototype, "size", 2);
e([
l({ type: String, reflect: !0 })
], t.prototype, "animation", 2);
e([
l({ type: Boolean, reflect: !0, attribute: "no-close-on-backdrop" })
], t.prototype, "noCloseOnBackdrop", 2);
e([
l({ type: Boolean, reflect: !0, attribute: "no-close-button" })
], t.prototype, "noCloseButton", 2);
e([
l({ type: Boolean, reflect: !0 })
], t.prototype, "scrollable", 2);
e([
h()
], t.prototype, "isAnimating", 2);
t = e([
u("mz-modal")
], t);
export {
t as M
};
//# sourceMappingURL=mz-modal-BD-pDPx9.js.map