/** * @license Copyright © HatioLab Inc. All rights reserved. */ import '@material/web/icon/icon.js' import { css, html, nothing } from 'lit' import { customElement, state, query, queryAll } from 'lit/decorators.js' import { OxFormField } from '@operato/input' @customElement('ox-input-nodes') export class OxInputNodes extends OxFormField { static styles = [ css` :host { display: flex; flex-direction: column; overflow: hidden; --md-icon-size: 14px; --spacing-large: 16px; --spacing-medium: 8px; --spacing-small: 4px; --spacing-tiny: 2px; --padding-default: 4px; --button-color: rgba(0, 0, 0, 0.5); --button-border: 1px solid rgba(0, 0, 0, 0.15); --button-background-color: rgba(0, 0, 0, 0.05); --button-background-focus-color: rgba(0, 0, 0, 0.1); --button-active-border: 1px solid rgba(0, 0, 0, 0.2); } div { display: flex; flex-flow: row nowrap; gap: var(--spacing-medium); margin-bottom: var(--spacing-small); } button { border: var(--button-border); border-radius: var(--border-radius); background-color: var(--button-background-color); padding: var(--spacing-small) var(--padding-default); line-height: 0.8; color: var(--button-color); cursor: pointer; } button + button { margin-left: -5px; } button:focus, button:hover, button:active { border: var(--button-active-border); background-color: var(--button-background-focus-color); color: rgba(0, 0, 0, 0.5); } input { flex: 1; border: 0; border: 1px solid rgba(0, 0, 0, 0.15); padding: var(--spacing-tiny); font: var(--input-font); min-width: 50px; } input:focus { outline: none; border: 1px solid rgba(0, 0, 0, 0.2); } ` ] @state() value: string[] = [] @queryAll('[data-record]') records!: NodeListOf @query('[data-record-new] [data-id]') addinput!: HTMLInputElement private _changingNow: boolean = false firstUpdated() { this.renderRoot.addEventListener('change', this._onChange.bind(this)) } render() { const value = this.value || [] return html` ${value.map( item => html`
e.key === 'Enter' && this._build()} />
` )} ${this.disabled ? nothing : html`
e.key === 'Enter' && this._add()} />
`} ` } _onChange(e: Event) { if (this._changingNow) { return } this._changingNow = true const input = e.target as HTMLInputElement const record = (e.target as Element).closest('[data-record],[data-record-new]') as HTMLElement if (record.hasAttribute('data-record')) { this._build() } else if (record.hasAttribute('data-record-new') && input.hasAttribute('data-value')) { this._add() } this._changingNow = false } _build(includeNewRecord?: boolean) { const selector = includeNewRecord ? '[data-record],[data-record-new]' : '[data-record]' const records = this.renderRoot.querySelectorAll(selector) as NodeListOf this.value = Array.from(records) .map(record => (record.querySelector('[data-id]')! as HTMLInputElement).value as string) .filter(Boolean) .sort() this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true, detail: this.value })) } _add() { this._build(true) this.addinput.value = '' this.addinput.focus() } _delete(e: MouseEvent) { const record = (e.target as Element).closest('[data-record]') as HTMLElement ;(record!.querySelector('[data-id]') as HTMLInputElement)!.value = '' this._build() } }