feat(core): add controls component with activity tracking (#514)

This commit is contained in:
rahim
2026-02-13 01:14:16 +11:00
committed by GitHub
parent 33b21906cd
commit 90d881cec2
20 changed files with 787 additions and 0 deletions
+12
View File
@@ -0,0 +1,12 @@
import { ControlsElement } from '../../ui/controls/controls-element';
import { ControlsGroupElement } from '../../ui/controls/controls-group-element';
customElements.define(ControlsElement.tagName, ControlsElement);
customElements.define(ControlsGroupElement.tagName, ControlsGroupElement);
declare global {
interface HTMLElementTagNameMap {
[ControlsElement.tagName]: ControlsElement;
[ControlsGroupElement.tagName]: ControlsGroupElement;
}
}
+2
View File
@@ -14,6 +14,8 @@ export * from './store/container-mixin';
export * from './store/provider-mixin';
export * from './store/types';
// UI Components
export { ControlsElement } from './ui/controls/controls-element';
export { ControlsGroupElement } from './ui/controls/controls-group-element';
export { FullscreenButtonElement } from './ui/fullscreen-button/fullscreen-button-element';
// Primitives
export * from './ui/media-element';
@@ -0,0 +1,34 @@
import { ControlsCore, ControlsDataAttrs } from '@videojs/core';
import { applyStateDataAttrs, logMissingFeature, selectControls } from '@videojs/core/dom';
import type { PropertyValues } from '@videojs/element';
import { playerContext } from '../../player/context';
import { PlayerController } from '../../player/player-controller';
import { MediaElement } from '../media-element';
export class ControlsElement extends MediaElement {
static readonly tagName = 'media-controls';
readonly #core = new ControlsCore();
readonly #state = new PlayerController(this, playerContext, selectControls);
override connectedCallback(): void {
super.connectedCallback();
if (__DEV__ && !this.#state.value) {
logMissingFeature(ControlsElement.tagName, 'controls');
}
}
protected override update(changed: PropertyValues): void {
super.update(changed);
const controls = this.#state.value;
if (!controls) {
return;
}
applyStateDataAttrs(this, this.#core.getState(controls), ControlsDataAttrs);
}
}
@@ -0,0 +1,13 @@
import { MediaElement } from '../media-element';
export class ControlsGroupElement extends MediaElement {
static readonly tagName = 'media-controls-group';
override connectedCallback(): void {
super.connectedCallback();
if (this.hasAttribute('aria-label') || this.hasAttribute('aria-labelledby')) {
this.setAttribute('role', 'group');
}
}
}