UNPKG

@alegendstale/holly-components

Version:

Reusable UI components created using lit

120 lines (117 loc) 3.8 kB
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; import { LitElement, html, css } from 'lit'; import { property, state } from 'lit/decorators.js'; import { createRef, ref } from 'lit/directives/ref.js'; import { styleMap } from 'lit/directives/style-map.js'; import { EventEmitter } from '../../utils/EventEmitter.js'; import { condCustomElement } from '../../decorators/condCustomElement.js'; let AbsoluteContainer = class AbsoluteContainer extends LitElement { constructor() { super(...arguments); this.dialogRef = createRef(); this._open = false; this.left = 0; this.top = 0; this.emitter = new EventEmitter(); /** * Disables the ContextEvent (right click, or long touch) * * Useful for context menus */ this.disableContextEvent = false; } set open(val) { this._open = val; requestAnimationFrame(() => { if (!this.dialogRef.value) return; let dialog = this.dialogRef.value; if (dialog.open) dialog.close(); else dialog.showModal(); }); this.emitter.emit('visibility', val); } get open() { return this._open; } disconnectedCallback() { super.disconnectedCallback(); this.emitter.clear(); } render() { const dialogStyles = { inset: this.left === 0 && this.top === 0 ? 0 : 'unset', left: `${this.left}px`, top: `${this.top}px`, }; return html ` <dialog part='dialog' style=${styleMap(dialogStyles)} @mousedown=${(e) => { if (!(e.target instanceof HTMLElement)) return; const outsideWidthBounds = e.offsetX < 0 || e.offsetX > e.target.offsetWidth; const outsideHeightBounds = e.offsetY < 0 || e.offsetY > e.target.offsetHeight; // Check if cursor is inside element bounds. Close dialog if it isn't. if (outsideWidthBounds || outsideHeightBounds) this.open = false; }} @contextmenu=${(e) => this.disableContextEvent && e.preventDefault()} ${ref(this.dialogRef)} > <slot></slot> </dialog> `; } toggle() { this.open = !this.open; } setOpen(val) { this.open = val; } setPosition(left, top) { this.left = left; this.top = top; } }; AbsoluteContainer.styles = [ css ` :host { display: block; } dialog { width: min-content; border: 0; padding: 0; background-color: transparent; scrollbar-width: thin; &::backdrop { background-color: transparent; } } ` ]; __decorate([ property({ type: Boolean, reflect: true }) ], AbsoluteContainer.prototype, "open", null); __decorate([ state() ], AbsoluteContainer.prototype, "left", void 0); __decorate([ state() ], AbsoluteContainer.prototype, "top", void 0); __decorate([ property({ type: Boolean, reflect: true }) ], AbsoluteContainer.prototype, "disableContextEvent", void 0); AbsoluteContainer = __decorate([ condCustomElement('absolute-container') ], AbsoluteContainer); export { AbsoluteContainer };