Files
v10/packages/html/src/ui/menu/menu-checkbox-item-element.ts
T

77 lines
2.2 KiB
TypeScript

import { applyElementProps } from '@videojs/core/dom';
import type { PropertyDeclarationMap, PropertyValues } from '@videojs/element';
import { ContextConsumer } from '@videojs/element/context';
import { MediaElement } from '../media-element';
import { menuContext } from './context';
export class MenuCheckboxItemElement extends MediaElement {
static readonly tagName = 'media-menu-checkbox-item';
static override properties = {
checked: { type: Boolean },
disabled: { type: Boolean },
} satisfies PropertyDeclarationMap<'checked' | 'disabled'>;
checked = false;
disabled = false;
readonly #ctx = new ContextConsumer(this, { context: menuContext, subscribe: true });
#disconnect: AbortController | null = null;
#registered = false;
#cleanupRegistration: (() => void) | null = null;
override connectedCallback(): void {
super.connectedCallback();
this.#disconnect = new AbortController();
this.#registered = false;
}
override disconnectedCallback(): void {
super.disconnectedCallback();
this.#cleanupRegistration?.();
this.#cleanupRegistration = null;
this.#disconnect?.abort();
this.#disconnect = null;
this.#registered = false;
}
protected override update(_changed: PropertyValues): void {
super.update(_changed);
const ctx = this.#ctx.value;
if (!ctx || !this.#disconnect) return;
if (!this.#registered) {
this.#registered = true;
this.#cleanupRegistration = ctx.menu.registerItem(this);
applyElementProps(
this,
{
onClick: () => {
const currentCtx = this.#ctx.value;
if (!currentCtx || this.disabled) return;
this.checked = !this.checked;
this.dispatchEvent(new CustomEvent('checked-change', { detail: { checked: this.checked }, bubbles: true }));
},
onPointerenter: () => {
const currentCtx = this.#ctx.value;
if (!this.disabled) currentCtx?.menu.highlight(this, { focus: false });
},
},
{ signal: this.#disconnect.signal }
);
}
applyElementProps(this, {
role: 'menuitemcheckbox',
'aria-checked': String(this.checked),
'aria-disabled': this.disabled ? 'true' : undefined,
});
}
}