UNPKG

@oslokommune/punkt-elements

Version:

Komponentbiblioteket til Punkt, et designsystem laget av Oslo Origo

86 lines (70 loc) • 2.81 kB
import { PktElement } from '@/base-elements/element' import { PktSlotController } from '@/controllers/pkt-slot-controller' import { ref } from 'lit/directives/ref.js' import { Ref, createRef } from 'lit/directives/ref.js' import { html, nothing, PropertyValues } from 'lit' import { classMap } from 'lit/directives/class-map.js' import { customElement, property, state } from 'lit/decorators.js' import specs from 'componentSpecs/messagebox.json' import '@/components/icon' import { updateClassAttribute } from '@/utils/classutils' export type TMessageboxSkin = 'beige' | 'blue' | 'red' | 'green' export interface IPktMessagebox { skin?: TMessageboxSkin title?: string compact?: boolean closable?: boolean } @customElement('pkt-messagebox') export class PktMessagebox extends PktElement implements IPktMessagebox { defaultSlot: Ref<HTMLElement> = createRef() constructor() { super() this.slotController = new PktSlotController(this, this.defaultSlot) this._isClosed = false } // Properties @property({ type: Boolean, reflect: true }) closable = specs.props.closable.default @property({ type: Boolean, reflect: true }) compact = specs.props.compact.default @property({ type: String, reflect: true }) title = '' @property({ type: String, reflect: true }) skin = specs.props.skin.default as TMessageboxSkin @state() _isClosed: boolean = false // Lifecycle protected updated(_changedProperties: PropertyValues): void { super.updated(_changedProperties) if (_changedProperties.has('_isClosed')) { updateClassAttribute(this, 'pkt-hide', this._isClosed) } } // Render render() { const classes = { 'pkt-messagebox': true, 'pkt-messagebox--compact': this.compact, [`pkt-messagebox--${this.skin}`]: this.skin, 'pkt-messagebox--closable': this.closable, 'pkt-hide': this._isClosed, } return html`<div class=${classMap(classes)}> ${this.closable ? html`<div class="pkt-messagebox__close"> <button @click=${this.close} class="pkt-btn pkt-btn--tertiary pkt-btn--small pkt-btn--icon-only" > <pkt-icon name="close" class="pkt-link__icon"></pkt-icon> </button> </div>` : nothing} ${this.title ? html`<div class="pkt-messagebox__title">${this.title}</div>` : nothing} <div class="pkt-messagebox__text" ${ref(this.defaultSlot)}></div> </div>` } // Methods private close = (event: MouseEvent) => { this._isClosed = true this.dispatchEvent(new CustomEvent('close', { detail: { origin: event }, bubbles: true })) // Historical support of old Vue implementations… this.dispatchEvent(new CustomEvent('on-close', { detail: { origin: event }, bubbles: true })) } }