UNPKG

@oslokommune/punkt-elements

Version:

Komponentbiblioteket til Punkt, et designsystem laget av Oslo Origo

123 lines (112 loc) 4.25 kB
import { html, PropertyValues } from 'lit' import { ifDefined } from 'lit/directives/if-defined.js' import { customElement, property, state } from 'lit/decorators.js' import { Ref, createRef, ref } from 'lit/directives/ref.js' import { classMap } from 'lit/directives/class-map.js' import { live } from 'lit/directives/live.js' import { PktInputElement } from '@/base-elements/input-element' import { slotContent } from '@/directives/slot-content' import '@/components/input-wrapper' import '@/components/icon' import { ElementProps } from '@/types/typeUtils' type Props = ElementProps<PktTextarea, 'autocomplete' | 'rows'> export class PktTextarea extends PktInputElement<Props> { inputRef: Ref<HTMLTextAreaElement> = createRef() @property({ type: String, reflect: true }) value: string = '' @property({ type: String }) autocomplete: string = 'off' @property({ type: Number }) rows: number | null = null @state() counterCurrent = 0 attributeChangedCallback(name: string, _old: string | null, value: string | null): void { if (name === 'value' && this.value !== _old) { this.counterCurrent = value ? value.length : 0 this.valueChanged(value, _old) } super.attributeChangedCallback(name, _old, value) } updated(changedProperties: PropertyValues) { super.updated(changedProperties) if (changedProperties.has('value')) { this.counterCurrent = this.value?.length || 0 this.valueChanged(this.value, changedProperties.get('value')) } if (changedProperties.has('id')) { !this.name && this.id && (this.name = this.id) } } render() { const inputClasses = classMap({ 'pkt-input': true, 'pkt-input--fullwidth': this.fullwidth, 'pkt-input--counter-error': this.counter && this.counterMaxLength && this.value.length && this.value.length > this.counterMaxLength, }) const labelledBy = this.ariaLabelledby || `${this.id}-input-label` return html`<pkt-input-wrapper label=${this.label} ?counter=${this.counter} ?disabled=${this.disabled} ?hasError=${this.hasError} ?inline=${this.inline} ?optionalTag=${this.optionalTag} ?required=${this.required} ?requiredTag=${this.requiredTag} useWrapper=${this.useWrapper} .ariaDescribedBy=${this.ariaDescribedBy} .counterCurrent=${this.counterCurrent} .counterMaxLength=${this.counterMaxLength} .errorMessage=${this.errorMessage} .forId="${this.id + '-input'}" .helptext=${this.helptext} .helptextDropdown=${this.helptextDropdown} .helptextDropdownButton=${this.helptextDropdownButton} .optionalText=${this.optionalText} .requiredText=${this.requiredText} .tagText=${this.tagText} class="pkt-textarea" > <div class="pkt-contents" slot="helptext">${slotContent(this, 'helptext')}</div> <textarea ${ref(this.inputRef)} class=${inputClasses} id=${this.id + '-input'} name=${(this.name || this.id) + '-input'} placeholder=${ifDefined(this.placeholder)} .value=${live(this.value)} minlength=${ifDefined(this.minlength)} maxlength=${ifDefined(this.maxlength)} ?readonly=${this.readonly} autocomplete=${this.autocomplete} aria-labelledby=${labelledBy} aria-invalid=${this.hasError} aria-errormessage=${`${this.id}-error`} rows=${this.rows} ?disabled=${this.disabled} @input=${(e: InputEvent) => { this.value = (e.target as HTMLInputElement).value this.onInput() e.stopImmediatePropagation() }} @change=${(e: Event) => { e.stopImmediatePropagation() }} @focus=${(e: FocusEvent) => { this.onFocus() e.stopImmediatePropagation() }} @blur=${(e: FocusEvent) => { this.value = (e.target as HTMLInputElement).value this.onBlur() e.stopImmediatePropagation() }} ></textarea> </pkt-input-wrapper>` } } try { customElement('pkt-textarea')(PktTextarea) } catch (e) { console.warn('Forsøker å definere <pkt-textarea>, men den er allerede definert') }