mirror of
https://github.com/zoriya/v10.git
synced 2026-08-16 02:45:09 +00:00
77 lines
2.2 KiB
TypeScript
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,
|
|
});
|
|
}
|
|
}
|