UNPKG

ui-lit

Version:

UI Elements on LIT

175 lines (174 loc) 5.94 kB
import { __decorate } from "tslib"; import { LitElement, html, nothing } from 'lit'; import { state, customElement, property } from 'lit/decorators.js'; import { getScrollbarWidth } from 'kailib'; import { DIALOG_STYLES } from './styles'; import { scrollbar } from '../styles/scrollbar'; import { KeyDownController } from '../controllers/KeyController'; import '../icon'; import '../button'; import '../form'; let dialogs = []; const peekDialog = () => dialogs[dialogs.length - 1]; let LitDialog = class LitDialog extends LitElement { constructor() { super(...arguments); this.closeBtnText = "Close"; this.opened = false; this.useCancelBtn = true; this.content = ""; this.headerVisible = false; this._keyPressController = new KeyDownController(this); // **** Actions **** this._headerChanged = (e) => { this.headerVisible = true; }; } static get styles() { return [DIALOG_STYLES, scrollbar]; } ; _footerTemplate() { return html `${this.useCancelBtn ? html `<div @click = "${this.close}" class = "closebtn-wrapper"> <slot name = "closeBtn"> <lit-button type = "button" class = "button">${this.closeBtnText}</lit-button> </slot> </div>` : nothing} <slot name = "footer"></slot>`; } get form() { var _a; return this.querySelector('lit-form') || ((_a = this.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector('lit-form')); } render() { return html ` <div class = "overlap"> <lit-form class = "dialog" .onAction = "${this.onConfirm}" @submit = "${this._submit}" @click = "${this._onClick}"> <header class = "${this.headerVisible ? 'visible' : ''}"> <slot name = "header" @slotchange = "${this._headerChanged}"></slot> </header> <div class = "icons"> ${dialogs.length > 1 ? html `<lit-icon class = "arrow-back" icon = "back" @click = "${this.back}" ></lit-icon>` : nothing}<lit-icon icon = "cancel" class = "close-icon" @click = "${this.close}"></lit-icon> </div> <main class = "ff-scrollbar"><slot></slot></main> <footer>${this._footerTemplate()}</footer> </lit-form> </div>`; } _show() { document.body.style.paddingRight = getScrollbarWidth() + "px"; document.body.style.overflow = 'hidden'; } _hide() { document.body.style.paddingRight = "initial"; document.body.style.overflow = 'initial'; } _focus() { var _a; (_a = this.querySelector("lit-textfield, lit-numberfield")) === null || _a === void 0 ? void 0 : _a.focus(); } open() { if (!dialogs.includes(this)) { const prev = peekDialog(); if (prev) prev.opened = false; dialogs.push(this); } this._show(); this._openInstance(this); this.dispatchEvent(new CustomEvent('dialogOpened')); setTimeout(() => { this._focus(); }); } _openInstance(dialog) { if (!dialog) return; dialog.opened = true; } back() { this._closeInstanse(dialogs.pop()); this._openInstance(peekDialog()); this.dispatchEvent(new CustomEvent('dialogBack')); } _closeInstanse(dialog) { var _a; if (!dialog) return; dialog.opened = false; (_a = dialog.form) === null || _a === void 0 ? void 0 : _a.reset(); dialog.dispatchEvent(new CustomEvent('dialogClose')); } close() { this._hide(); dialogs.forEach(this._closeInstanse); dialogs = []; } confirm() { var _a; (_a = this.form) === null || _a === void 0 ? void 0 : _a.submit(); } _onConfirm() { this.dispatchEvent(new CustomEvent('dialogConfirm')); this.back(); } // **** Events **** _submit() { this._onConfirm(); } _onClick(e) { const el = e.target; if (el.closest('[confirm]')) { this.confirm(); } else if (el.closest('[close]')) { this.close(); } } // TODO ловушка для фокуса на модальном окне handlekeyDown(e) { if (e.key === "Escape") { this.close(); } } }; __decorate([ property({ type: String, attribute: false }) ], LitDialog.prototype, "closeBtnText", void 0); __decorate([ property({ type: Boolean, attribute: true, reflect: true }) ], LitDialog.prototype, "opened", void 0); __decorate([ property({ type: Boolean, attribute: true, reflect: true }) ], LitDialog.prototype, "useCancelBtn", void 0); __decorate([ property({ type: Object, attribute: false }) ], LitDialog.prototype, "content", void 0); __decorate([ property({ type: Object, attribute: false }) ], LitDialog.prototype, "onConfirm", void 0); __decorate([ state() ], LitDialog.prototype, "headerVisible", void 0); LitDialog = __decorate([ customElement('lit-dialog') ], LitDialog); export { LitDialog };