import { html, TemplateResult, nothing } from 'lit'; import { customElement, property, query, state } from 'lit/decorators.js'; import { classMap } from 'lit/directives/class-map.js'; import { styles } from './nile-detail.css'; import NileElement from '../internal/nile-element'; import { watch } from '../internal/watch'; import { animateShow, animateHide, showDetail, hideDetail, handleSummaryClick, handleSummaryKeyDown, } from './nile-detail.utils'; import type { CSSResultGroup } from 'lit'; @customElement('nile-detail') export class NileDetail extends NileElement { static styles: CSSResultGroup = styles; @query('details') detail: HTMLDetailsElement; @query('summary') header: HTMLElement; @query('.detail__body') body: HTMLElement; @property({ attribute: true, type: Boolean, reflect: true }) open = false; @property({ attribute: true, type: String, reflect: true }) heading = ''; @property({ attribute: true, type: String, reflect: true }) description = ''; @property({ attribute: true, reflect: true }) expandIconPlacement: 'left' | 'right' = 'right'; @property({ attribute: true, type: Boolean, reflect: true }) disabled = false; @state() private _detailOpen = false; firstUpdated() { this._detailOpen = this.open; this.body.hidden = !this.open; this.body.style.height = this.open ? 'auto' : '0'; } private _handleSummaryClick(event: Event) { event.preventDefault(); handleSummaryClick(this); } private _handleSummaryKeyDown(event: KeyboardEvent) { handleSummaryKeyDown(event, this); } @watch('open', { waitUntilFirstUpdate: true }) async handleOpenChange() { if (this.open) { this._detailOpen = true; await animateShow(this); } else { await animateHide(this); this._detailOpen = false; } } async show() { return showDetail(this); } async hide() { return hideDetail(this); } private get _summaryLabel(): string { return [this.heading, this.description].filter(Boolean).join(', '); } render(): TemplateResult { return html`
${this.heading} ${this.description ? html`${this.description}` : ''}
`; } } export default NileDetail; declare global { interface HTMLElementTagNameMap { 'nile-detail': NileDetail; } }