Files
v10/packages/html/src/ui/hotkey/hotkey-element.ts
T
2026-05-05 10:34:12 +10:00

83 lines
2.3 KiB
TypeScript

import { createHotkey, type HotkeyActionName, isHotkeyToggleAction, resolveHotkeyAction } from '@videojs/core/dom';
import type { PropertyDeclarationMap, PropertyValues } from '@videojs/element';
import { ContextConsumer } from '@videojs/element/context';
import { containerContext, playerContext } from '../../player/context';
import { PlayerController } from '../../player/player-controller';
import { MediaElement } from '../media-element';
export class HotkeyElement extends MediaElement {
static readonly tagName = 'media-hotkey';
static override properties: PropertyDeclarationMap = {
keys: { type: String },
action: { type: String },
value: { type: Number },
disabled: { type: Boolean },
target: { type: String },
};
keys = '';
action: HotkeyActionName | (string & {}) = '';
value: number | undefined = undefined;
disabled = false;
target: 'player' | 'document' = 'player';
readonly #player = new PlayerController(this, playerContext);
readonly #container = new ContextConsumer(this, {
context: containerContext,
callback: () => this.requestUpdate(),
subscribe: true,
});
#cleanup: (() => void) | null = null;
override connectedCallback(): void {
super.connectedCallback();
this.style.display = 'none';
this.#register();
}
override disconnectedCallback(): void {
super.disconnectedCallback();
this.#unregister();
}
protected override update(changed: PropertyValues): void {
super.update(changed);
// Re-register when attributes change.
if (this.isConnected) {
this.#unregister();
this.#register();
}
}
#register(): void {
const store = this.#player.value;
const container = this.#container.value?.container;
if (!this.keys || !this.action || !store || !container) return;
const resolver = resolveHotkeyAction(this.action);
if (!resolver) return;
const { value, action } = this;
this.#cleanup = createHotkey(container, {
keys: this.keys,
action,
value,
target: this.target,
disabled: this.disabled,
repeatable: !isHotkeyToggleAction(action),
onActivate: (_event, key) => {
resolver({ store, key, value });
},
});
}
#unregister(): void {
this.#cleanup?.();
this.#cleanup = null;
}
}