ReferencePlayer
UIElement
Base class for custom elements that read player state through reactive controllers
UIElement is the base class for Video.js custom elements, and the one the built-in UI elements extend. It adds reactive properties, a batched update cycle, reactive controllers, and deferred destruction to HTMLElement, and renders into the light DOM: the subclass writes its own DOM in update().
UIElement extends DestroyMixin(ReactiveElement) from Video.js’s own element base, not from Lit. Its reactive properties and update cycle follow the model of Lit’s ReactiveElement, with the same names: static properties, requestUpdate(), willUpdate(), update(), updated(), updateComplete, and reactive controllers. It has no templates, shadow root, or static styles, no decorators, and no reflection of properties to attributes. DestroyMixin adds the destruction lifecycle and the hostDestroyed controller hook, which Lit doesn’t have.
Import
Usage
Extend UIElement, add a PlayerController for the player state the element needs, and write DOM in update(). The controller requests an update whenever its selected state changes.
The element must be a descendant of a player element, such as <video-player>, to receive state. Until then, and when the player lacks the selected feature, value is undefined.
playerContext is the context every player element provides to its descendants. See Player context for how it resolves and how it is typed. The PlayerController exported by a preset, or returned by createPlayer, is already bound to that player’s context and takes only the host and an optional selector.
Reactive properties
Declare reactive properties in static properties and initialize them as class fields. Setting a declared property to a new value (compared with Object.is) schedules an update. Each declaration also observes a matching attribute.
A PropertyDeclaration has two options:
Attributes update properties; properties do not reflect back to attributes. Set attributes yourself in update() when styling or accessibility depends on them.
Values assigned before the element is defined, or before it connects, are replayed through the reactive accessors on first connection, so they win over the class-field defaults.
A subclass of an element that already declares properties must spread the parent’s declarations:
Update cycle
Property changes and requestUpdate() calls made in the same task are batched into one update, which runs in a microtask. The first update waits until the element connects. Each update calls, in order:
willUpdate(changed)— compute values derived from other properties. Changes made here join the current update.hostUpdate()on each controller.update(changed)— write the element’s DOM. Property changes made here do not schedule another update.hostUpdated()on each controller.firstUpdated(changed)— once, after the first update.updated(changed)— after every update. Property changes made here, or infirstUpdated, schedule another update.
changed is a Map from each changed property name to its previous value. Call super when overriding any of these methods.
Controllers
A reactive controller is an object that hooks into its host element’s lifecycle. Controllers such as PlayerController add themselves to the host when they are constructed.
ReactiveController
ReactiveController is the interface a controller implements. Every hook is optional:
ReactiveControllerHost
ReactiveControllerHost is the interface of the element a controller attaches to. UIElement implements it, so a controller whose constructor accepts a ReactiveControllerHost works with any UIElement subclass.
Destruction
When the element disconnects, it waits two animation frames and then destroys itself if it is still disconnected. Moving the element within the document, or a framework reordering it, therefore keeps it alive. Destruction calls hostDestroyed() on every controller. A destroyed element stops updating and ignores later connections.
Add the keep-alive attribute to skip automatic destruction, for example when you detach an element and insert it again later. Call destroy() yourself when you are done with it.
Release listeners and observers that the element starts on connection in disconnectedCallback(), calling super.disconnectedCallback(), because an element can connect and disconnect many times before it is destroyed.
Examples
Basic Usage
A seek button with a reactive seconds property, set from its attribute.