Skip to content

Instantly share code, notes, and snippets.

@jpzwarte
Created October 31, 2022 08:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jpzwarte/a60d0a0db4f0a71dd2d07834ced4d39d to your computer and use it in GitHub Desktop.
Save jpzwarte/a60d0a0db4f0a71dd2d07834ced4d39d to your computer and use it in GitHub Desktop.
import type { PropertyValues, ReactiveElement } from 'lit';
import type { Constructor, FormControlInterface } from '@open-wc/form-control';
import { FormControlMixin as OwcFormControlMixin } from '@open-wc/form-control';
export interface FormControl extends FormControlInterface {
labels: Set<WeakRef<Node>>;
}
let nextUniqueId = 0;
export function FormControlMixin<T extends Constructor<ReactiveElement>>(constructor: T): T & Constructor<FormControl> {
class FormControlElement extends OwcFormControlMixin(constructor) implements FormControl {
#labels = new Set<WeakRef<HTMLLabelElement>>();
#onLabelClick = (event: Event): void => this.onLabelClick(event);
get labels(): Set<WeakRef<HTMLLabelElement>> {
return this.#labels;
}
disconnectedCallback(): void {
this.#labels.forEach(ref => ref.deref()?.removeEventListener('click', this.#onLabelClick));
this.#labels.clear();
super.disconnectedCallback();
}
firstUpdated(changes: PropertyValues<this>): void {
super.firstUpdated(changes);
const ids = Array.from(this.internals.labels)
.filter((label): label is HTMLLabelElement => label instanceof HTMLLabelElement)
.map(label => {
label.id = `sl-label-${nextUniqueId++}`;
label.addEventListener('click', this.#onLabelClick);
this.#labels.add(new WeakRef(label));
return label.id;
});
this.setAttribute('aria-labelledby', ids.join(' '));
}
// eslint-disable-next-line @typescript-eslint/no-empty-function
onLabelClick(_event: Event): void {}
}
return FormControlElement;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment