UNPKG

@oslokommune/punkt-elements

Version:

Komponentbiblioteket til Punkt, et designsystem laget av Oslo Origo

127 lines (112 loc) 4.6 kB
import { customElement, property } from 'lit/decorators.js' import { PktInputElement } from '@/base-elements/input-element' import { Ref, createRef, ref } from 'lit/directives/ref.js' import { html, nothing, PropertyValues } from 'lit' import { classMap } from 'lit/directives/class-map.js' @customElement('pkt-checkbox') export class PktCheckbox extends PktInputElement { private inputRef: Ref<HTMLInputElement> = createRef() @property({ type: String, reflect: true }) value: string = '' @property({ type: String }) checkHelptext: string | null = null @property({ type: Boolean }) defaultChecked: boolean = false @property({ type: Boolean }) hasTile: boolean = false @property({ type: Boolean }) isSwitch: boolean = false @property({ type: String }) labelPosition: 'right' | 'left' = 'right' @property({ type: Boolean }) hideLabel: boolean = false @property({ type: Boolean, reflect: true }) checked: boolean | string | null = null @property({ type: String, reflect: true }) type: string = 'checkbox' @property({ type: String }) tagText: string | null = null @property({ type: Boolean }) optionalTag: boolean = false @property({ type: String }) optionalText: string = 'Valgfritt' @property({ type: Boolean }) requiredTag: boolean = false @property({ type: String }) requiredText: string = 'Må fylles ut' connectedCallback() { super.connectedCallback() } attributeChangedCallback(name: string, _old: string | null, value: string | null): void { if (name === 'defaultChecked' && !this.checked) { this.checked = this.defaultChecked } if (name === 'checked') { this.checked = this.checked === '' || this.checked === 'true' || this.checked === true } super.attributeChangedCallback(name, _old, value) } protected firstUpdated(_changedProperties: PropertyValues): void { if (_changedProperties.has('defaultChecked') && !this.checked) { this.checked = this.defaultChecked } super.firstUpdated(_changedProperties) } render() { const inputTileClasses = classMap({ 'pkt-input-check__input': true, 'pkt-input-check__input--tile': this.hasTile, 'pkt-input-check__input--tile-disabled': this.disabled && this.hasTile, }) const inputCheckBoxClasses = classMap({ 'pkt-input-check__input-checkbox': true, 'pkt-input-check__input-checkbox--error': this.hasError, }) const labelClasses = classMap({ 'pkt-input-check__input-label': true, 'pkt-input-check__input-label--disabled': this.disabled, 'pkt-input-check__input-label--left': this.labelPosition === 'left', 'pkt-input-check__input-label--right': this.labelPosition === 'right', 'pkt-sr-only': this.hideLabel, }) const tagClasses = 'pkt-tag pkt-tag--small pkt-tag--thin-text' const tags = () => { return html` ${this.tagText ? html`<span class=${tagClasses + ' pkt-tag--gray'}>${this.tagText}</span>` : nothing} ${this.optionalTag ? html`<span class=${tagClasses + ' pkt-tag--blue-light'}>${this.optionalText}</span>` : nothing} ${this.requiredTag ? html`<span class=${tagClasses + ' pkt-tag--beige'}>${this.requiredText}</span>` : nothing} ` } const labelAndHelptext = () => { return html` <label class=${labelClasses} for=${this.id + '-internal'}> ${this.label} ${tags()} ${this.checkHelptext ? html`<div class="pkt-input-check__input-helptext">${this.checkHelptext}</div>` : nothing} </label> ` } return html` <div class="pkt-input-check"> <div class=${inputTileClasses}> ${this.labelPosition === 'left' ? labelAndHelptext() : nothing} <input id=${this.id + '-internal'} class=${inputCheckBoxClasses} type="checkbox" ?disabled=${this.disabled} name=${this.name + '-internal'} ${ref(this.inputRef)} @change=${this.toggleChecked} @blur=${this.onBlur} @focus=${this.onFocus} ?checked=${this.checked} role=${this.isSwitch ? 'switch' : 'checkbox'} /> ${this.labelPosition === 'right' ? labelAndHelptext() : nothing} </div> </div> ` } private toggleChecked(e: Event) { e.stopImmediatePropagation() this.touched = true if (this.inputRef.value) { this.checked = this.inputRef.value.matches(':checked') this.valueChecked(this.checked) } } }