UNPKG

@oslokommune/punkt-elements

Version:

Komponentbiblioteket til Punkt, et designsystem laget av Oslo Origo

87 lines (77 loc) 2.77 kB
import { PktShadowElement } from '@/base-elements/element' import { html, PropertyValues } from 'lit' import { customElement, property } from 'lit/decorators.js' export type TPktHeadingLevel = 1 | 2 | 3 | 4 | 5 | 6 export type TPktHeadingSize = 'xsmall' | 'small' | 'medium' | 'large' | 'xlarge' export interface IPktHeading { size?: TPktHeadingSize level?: TPktHeadingLevel visuallyHidden?: boolean align?: 'start' | 'center' | 'end' } @customElement('pkt-heading') export class PktHeading extends PktShadowElement<IPktHeading> implements IPktHeading { @property({ type: String, reflect: true }) size: TPktHeadingSize = 'medium' @property({ type: Number, reflect: true }) level: TPktHeadingLevel = 2 @property({ type: Boolean, reflect: true }) visuallyHidden: boolean = false @property({ type: String, reflect: true }) align: 'start' | 'center' | 'end' = 'start' connectedCallback(): void { super.connectedCallback() this.setAttribute('role', 'heading') this.setAttribute('aria-level', String(this.level)) this.updateHostClasses() } attributeChangedCallback(name: string, _old: string | null, value: string | null): void { super.attributeChangedCallback(name, _old, value) if (name === 'level' && value) { this.setLevel(Number(value) as TPktHeadingLevel) } if (name === 'size' || name === 'visuallyHidden' || name === 'align') { this.updateHostClasses() } } protected updated(_changedProperties: PropertyValues): void { super.updated(_changedProperties) if (_changedProperties.has('level')) { this.setLevel(this.level) } if ( _changedProperties.has('size') || _changedProperties.has('visuallyHidden') || _changedProperties.has('align') ) { this.updateHostClasses() } } private setLevel(level: TPktHeadingLevel): void { if (level >= 1 && level <= 6) { this.level = level this.setAttribute('aria-level', String(level)) } else { console.warn(`Invalid heading level: ${level}. Must be between 1 and 6.`) } } private updateHostClasses() { // Remove all possible classes first this.classList.remove( 'pkt-heading', 'pkt-heading--xsmall', 'pkt-heading--small', 'pkt-heading--medium', 'pkt-heading--large', 'pkt-heading--xlarge', 'pkt-sr-only', 'pkt-heading--start', 'pkt-heading--center', 'pkt-heading--end', ) // Add current classes this.classList.add('pkt-heading') if (this.size) this.classList.add(`pkt-heading--${this.size}`) if (this.visuallyHidden) this.classList.add('pkt-sr-only') if (this.align) this.classList.add(`pkt-heading--${this.align}`) } render() { return html`<slot></slot>` } }