/** * Copyright Aquera Inc 2023 * * This source code is licensed under the BSD-3-Clause license found in the * LICENSE file in the root directory of this source tree. */ import { LitElement, html, CSSResultArray, TemplateResult, PropertyValues, } from 'lit'; import { customElement, property, state } from 'lit/decorators.js'; import { styles } from './nile-card.css'; import { classMap } from 'lit/directives/class-map.js'; import { HasSlotController } from '../internal/slot'; import NileElements from '../internal/nile-element'; import { CSSResultGroup } from 'lit'; /** * Nile icon component. * * @tag nile-card * */ @customElement('nile-card') export class NileCard extends NileElements { static styles: CSSResultGroup = styles; private readonly hasSlotController = new HasSlotController(this, 'footer'); private readonly _internals: ElementInternals = this.attachInternals(); @property({ type: Boolean, reflect: true })active = false; @property({ type: Boolean, reflect: true }) disabled = false; @property({ type: String, reflect: true }) variant: 'default' | 'container' = 'default'; @property({ type: String, attribute: true, reflect: true }) skipOn = ''; /** Reactive states used by the `container` variant. */ @state() private _hover = false; @state() private _active = false; @state() private _disabled = false; /** Set the `hover` state on pointer enter (container variant only). */ private handlePointerEnter = () => { if (this.variant === 'container') { this._hover = true; } }; private handlePointerLeave = () => { this._hover = false; }; private setCustomState(name: string, on: boolean) { if (on) { this._internals.states.add(name); } else { this._internals.states.delete(name); } } private syncCustomStates() { this.setCustomState('hover', this._hover); this.setCustomState('active', this._active); this.setCustomState('disabled', this._disabled); } updated(changedProperties: PropertyValues) { super.updated(changedProperties); if ( changedProperties.has('variant') || changedProperties.has('active') || changedProperties.has('disabled') ) { const isContainer = this.variant === 'container'; this._active = isContainer && this.active; this._disabled = isContainer && this.disabled; if (!isContainer) { this._hover = false; } } this.syncCustomStates(); } private get base(): HTMLElement | null { return this.renderRoot?.querySelector('.card') ?? null; } private handlePointerDown = (event: PointerEvent) => { if (!this.skipOn) return; let skip = false; try { skip = event .composedPath() .some(node => node instanceof Element && node.matches(this.skipOn)); } catch { skip = false; } this.base?.classList.toggle('card--skip-active', skip); }; private handlePointerEnd = () => { this.base?.classList.remove('card--skip-active'); }; render() { return html`
`; } } export default NileCard; declare global { interface HTMLElementTagNameMap { 'nile-card': NileCard; } }