@oslokommune/punkt-elements
Version:
Komponentbiblioteket til Punkt, et designsystem laget av Oslo Origo
119 lines (104 loc) • 4 kB
text/typescript
import { customElement, property, state } from 'lit/decorators.js'
import { PktInputElement } from '@/base-elements/input-element'
import { Ref, createRef, ref } from 'lit/directives/ref.js'
import { html, nothing } from 'lit'
import { classMap } from 'lit/directives/class-map.js'
export class PktRadioButton extends PktInputElement {
private inputRef: Ref<HTMLInputElement> = createRef()
value: string = ''
checkHelptext: string | null = null
defaultChecked: boolean = false
hasTile: boolean = false
checked: boolean | string | null = null
type: string = 'radio'
tagText: string | null = null
optionalTag: boolean = false
optionalText: string = 'Valgfritt'
requiredTag: boolean = false
requiredText: string = 'Må fylles ut'
_checked: boolean = false
connectedCallback() {
super.connectedCallback()
}
attributeChangedCallback(name: string, _old: string | null, value: string | null): void {
if (name === 'defaultChecked') {
this._checked = this.defaultChecked
}
if (name === 'checked') {
this._checked = this.checked === '' || this.checked === 'true' || this.checked === true
}
super.attributeChangedCallback(name, _old, value)
}
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-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}>
<input
id=${this.id + '-internal'}
class=${inputCheckBoxClasses}
type="radio"
role="radio"
?disabled=${this.disabled}
form=""
name=${this.name + '-internal'}
${ref(this.inputRef)}
=${this.toggleChecked}
=${this.onInput}
=${this.onBlur}
=${this.onFocus}
?checked=${this.checked}
/>
${labelAndHelptext()}
</div>
</div>
`
}
private toggleChecked(e: Event | null = null) {
if (e) e.preventDefault()
if (e) e.stopImmediatePropagation()
this.touched = true
if (this.inputRef.value) {
this._checked = this.inputRef.value.matches(':checked')
this.valueChecked(this._checked)
}
}
}