docs: use framework exports in player API examples (#821)

This commit is contained in:
rahim
2026-03-10 02:11:02 -07:00
committed by GitHub
parent 09163b8206
commit 4cf69561c2
13 changed files with 57 additions and 108 deletions
+1 -1
View File
@@ -40,7 +40,7 @@ export interface CreatePlayerResult<Store extends PlayerStore> {
*
* @example
* ```ts
* import { createPlayer, MediaElement } from '@videojs/html';
* import { createPlayer, MediaElement, selectPlayback } from '@videojs/html';
* import { videoFeatures } from '@videojs/html/video';
*
* const { ProviderMixin, ContainerMixin, PlayerController, context } = createPlayer({
@@ -15,6 +15,14 @@ import basicUsageReactCss from "@/components/docs/demos/create-player/react/css/
The hook is typed according to the provided features, giving you full type safety for state selectors and actions.
```tsx
import { createPlayer } from '@videojs/react';
import { videoFeatures } from '@videojs/react/video';
const player = createPlayer({ features: videoFeatures });
const { Provider, Container, usePlayer, useMedia } = player;
```
## Examples
### Basic Usage
@@ -15,53 +15,48 @@ import basicUsageHtmlTs from "@/components/docs/demos/html-create-player/html/cs
`createPlayer` is the entry point for setting up a Video.js player with HTML custom elements. It accepts a configuration object with a `features` array and returns a typed <DocsLink slug="reference/player-controller">`PlayerController`</DocsLink>, `context`, `ProviderMixin`, `ContainerMixin`, and a `create` store factory.
```ts
import { createPlayer, MediaElement } from '@videojs/html';
import { createPlayer, MediaElement, selectPlayback } from '@videojs/html';
import { videoFeatures } from '@videojs/html/video';
const {
PlayerController,
context,
ProviderMixin,
ContainerMixin,
create,
} = createPlayer({ features: videoFeatures });
const { ProviderMixin, ContainerMixin, PlayerController, context } = createPlayer({
features: videoFeatures,
});
// Provider element: owns and publishes the store
// Provider element: owns the store, provides context to descendants
class VideoPlayer extends ProviderMixin(MediaElement) {}
// Container element: discovers <video>/<audio> and calls store.attach()
class MediaContainer extends ContainerMixin(MediaElement) {}
customElements.define('video-player', VideoPlayer);
customElements.define('media-container', MediaContainer);
// Control element with selector
class PlayButton extends MediaElement {
#playback = new PlayerController(this, context, selectPlayback);
}
```
### Composition patterns
`PlayerController`, `ProviderMixin`, and `ContainerMixin` are intended for controller hosts and custom-element composition. Keep wiring minimal in utility examples, and build concrete elements where needed.
Use split elements (recommended for reusable skins/layouts):
```ts
const {
PlayerController,
context,
ProviderMixin,
ContainerMixin,
} = createPlayer({ features: videoFeatures });
import { createPlayer, MediaElement } from '@videojs/html';
import { videoFeatures } from '@videojs/html/video';
class VideoPlayer extends ProviderMixin(MediaElement) {}
class MediaContainer extends ContainerMixin(MediaElement) {}
const { ProviderMixin, ContainerMixin } = createPlayer({ features: videoFeatures });
class PlayerRoot extends ProviderMixin(MediaElement) {}
class PlayerRegion extends ContainerMixin(MediaElement) {}
```
Use a single composed element when the same element should both own the store and attach media:
```ts
import { createPlayer, MediaElement } from '@videojs/html';
import { videoFeatures } from '@videojs/html/video';
const { ProviderMixin, ContainerMixin } = createPlayer({ features: videoFeatures });
class VideoPlayer extends ProviderMixin(ContainerMixin(MediaElement)) {}
class ComposedPlayer extends ProviderMixin(ContainerMixin(MediaElement)) {}
```
When using the built-in defined elements (`@videojs/html/video/player`, etc.), `media-container` is expected as the first child and UI should live inside it.
## Examples
### Basic Usage
@@ -1,36 +0,0 @@
---
title: PlayerMixin (Removed)
description: Migration guide for replacing removed PlayerMixin/PlayerElement APIs
---
import DocsLink from "@/components/docs/DocsLink.astro";
`PlayerMixin` and `PlayerElement` were removed from HTML `createPlayer`. Use <DocsLink slug="reference/provider-mixin">`ProviderMixin`</DocsLink> and <DocsLink slug="reference/container-mixin">`ContainerMixin`</DocsLink> directly.
### Migration
Old:
```ts
const { PlayerElement } = createPlayer({ features: videoFeatures });
customElements.define('video-player', PlayerElement);
```
New:
```ts
const { ProviderMixin, ContainerMixin } = createPlayer({ features: videoFeatures });
// Split elements
class VideoPlayer extends ProviderMixin(MediaElement) {}
class MediaContainer extends ContainerMixin(MediaElement) {}
// Single element equivalent of old PlayerMixin
class ComposedPlayer extends ProviderMixin(ContainerMixin(MediaElement)) {}
```
### Notes
- Built-in player elements (`@videojs/html/video/player`, `@videojs/html/audio/player`, etc.) now use a provider element plus `<media-container>` for media attachment.
- Barebones player markup should use `media-container` as first child, with UI inside the container.
- See <DocsLink slug="reference/html-create-player">`createPlayer`</DocsLink> for current API and examples.
@@ -19,8 +19,7 @@ The returned state includes buffered ranges and percent buffered.
<FrameworkCase frameworks={["react"]}>
```tsx
import { usePlayer } from '@videojs/react';
import { selectBuffer } from '@videojs/core/dom';
import { selectBuffer, usePlayer } from '@videojs/react';
function BufferBar() {
const buffer = usePlayer(selectBuffer);
@@ -35,14 +34,13 @@ function BufferBar() {
<FrameworkCase frameworks={["html"]}>
```ts
import { createPlayer, MediaElement } from '@videojs/html';
import { createPlayer, MediaElement, selectBuffer } from '@videojs/html';
import { videoFeatures } from '@videojs/html/video';
import { selectBuffer } from '@videojs/core/dom';
const { PlayerController, context } = createPlayer({ features: videoFeatures });
class BufferBar extends MediaElement {
#buffer = new PlayerController(this, context, selectBuffer);
readonly #buffer = new PlayerController(this, context, selectBuffer);
}
```
</FrameworkCase>
@@ -19,8 +19,7 @@ The returned state includes whether controls are visible and whether the user is
<FrameworkCase frameworks={["react"]}>
```tsx
import { usePlayer } from '@videojs/react';
import { selectControls } from '@videojs/core/dom';
import { selectControls, usePlayer } from '@videojs/react';
function ControlsOverlay({ children }: { children: React.ReactNode }) {
const controls = usePlayer(selectControls);
@@ -37,14 +36,13 @@ function ControlsOverlay({ children }: { children: React.ReactNode }) {
<FrameworkCase frameworks={["html"]}>
```ts
import { createPlayer, MediaElement } from '@videojs/html';
import { createPlayer, MediaElement, selectControls } from '@videojs/html';
import { videoFeatures } from '@videojs/html/video';
import { selectControls } from '@videojs/core/dom';
const { PlayerController, context } = createPlayer({ features: videoFeatures });
class ControlsOverlay extends MediaElement {
#controls = new PlayerController(this, context, selectControls);
readonly #controls = new PlayerController(this, context, selectControls);
}
```
</FrameworkCase>
@@ -19,8 +19,7 @@ The returned state includes whether fullscreen is active and its availability on
<FrameworkCase frameworks={["react"]}>
```tsx
import { usePlayer } from '@videojs/react';
import { selectFullscreen } from '@videojs/core/dom';
import { selectFullscreen, usePlayer } from '@videojs/react';
function FullscreenButton() {
const fs = usePlayer(selectFullscreen);
@@ -37,14 +36,13 @@ function FullscreenButton() {
<FrameworkCase frameworks={["html"]}>
```ts
import { createPlayer, MediaElement } from '@videojs/html';
import { createPlayer, MediaElement, selectFullscreen } from '@videojs/html';
import { videoFeatures } from '@videojs/html/video';
import { selectFullscreen } from '@videojs/core/dom';
const { PlayerController, context } = createPlayer({ features: videoFeatures });
class FullscreenButton extends MediaElement {
#fullscreen = new PlayerController(this, context, selectFullscreen);
readonly #fullscreen = new PlayerController(this, context, selectFullscreen);
}
```
</FrameworkCase>
@@ -19,8 +19,7 @@ The returned state includes whether PiP is active and its availability on the cu
<FrameworkCase frameworks={["react"]}>
```tsx
import { usePlayer } from '@videojs/react';
import { selectPiP } from '@videojs/core/dom';
import { selectPiP, usePlayer } from '@videojs/react';
function PiPButton() {
const pip = usePlayer(selectPiP);
@@ -37,14 +36,13 @@ function PiPButton() {
<FrameworkCase frameworks={["html"]}>
```ts
import { createPlayer, MediaElement } from '@videojs/html';
import { createPlayer, MediaElement, selectPiP } from '@videojs/html';
import { videoFeatures } from '@videojs/html/video';
import { selectPiP } from '@videojs/core/dom';
const { PlayerController, context } = createPlayer({ features: videoFeatures });
class PiPButton extends MediaElement {
#pip = new PlayerController(this, context, selectPiP);
readonly #pip = new PlayerController(this, context, selectPiP);
}
```
</FrameworkCase>
@@ -19,8 +19,7 @@ The returned state includes `playbackRate`, `playbackRates`, and the `setPlaybac
<FrameworkCase frameworks={["react"]}>
```tsx
import { usePlayer } from '@videojs/react';
import { selectPlaybackRate } from '@videojs/core/dom';
import { selectPlaybackRate, usePlayer } from '@videojs/react';
function RateDisplay() {
const rate = usePlayer(selectPlaybackRate);
@@ -33,14 +32,13 @@ function RateDisplay() {
<FrameworkCase frameworks={["html"]}>
```ts
import { createPlayer, MediaElement } from '@videojs/html';
import { createPlayer, MediaElement, selectPlaybackRate } from '@videojs/html';
import { videoFeatures } from '@videojs/html/video';
import { selectPlaybackRate } from '@videojs/core/dom';
const { PlayerController, context } = createPlayer({ features: videoFeatures });
class RateDisplay extends MediaElement {
#rate = new PlayerController(this, context, selectPlaybackRate);
readonly #rate = new PlayerController(this, context, selectPlaybackRate);
}
```
</FrameworkCase>
@@ -20,8 +20,7 @@ The returned state includes `paused`, `ended`, and action methods like `play`, `
<FrameworkCase frameworks={["react"]}>
```tsx
import { usePlayer } from '@videojs/react';
import { selectPlayback } from '@videojs/core/dom';
import { selectPlayback, usePlayer } from '@videojs/react';
function PlayButton() {
const playback = usePlayer(selectPlayback);
@@ -33,14 +32,13 @@ function PlayButton() {
<FrameworkCase frameworks={["html"]}>
```ts
import { createPlayer, MediaElement } from '@videojs/html';
import { createPlayer, MediaElement, selectPlayback } from '@videojs/html';
import { videoFeatures } from '@videojs/html/video';
import { selectPlayback } from '@videojs/core/dom';
const { PlayerController, context } = createPlayer({ features: videoFeatures });
class PlayButton extends MediaElement {
#playback = new PlayerController(this, context, selectPlayback);
readonly #playback = new PlayerController(this, context, selectPlayback);
}
```
</FrameworkCase>
@@ -19,8 +19,7 @@ The returned state includes the current `src` and `type`.
<FrameworkCase frameworks={["react"]}>
```tsx
import { usePlayer } from '@videojs/react';
import { selectSource } from '@videojs/core/dom';
import { selectSource, usePlayer } from '@videojs/react';
function SourceInfo() {
const source = usePlayer(selectSource);
@@ -33,14 +32,13 @@ function SourceInfo() {
<FrameworkCase frameworks={["html"]}>
```ts
import { createPlayer, MediaElement } from '@videojs/html';
import { createPlayer, MediaElement, selectSource } from '@videojs/html';
import { videoFeatures } from '@videojs/html/video';
import { selectSource } from '@videojs/core/dom';
const { PlayerController, context } = createPlayer({ features: videoFeatures });
class SourceInfo extends MediaElement {
#source = new PlayerController(this, context, selectSource);
readonly #source = new PlayerController(this, context, selectSource);
}
```
</FrameworkCase>
@@ -19,8 +19,7 @@ The returned state includes `currentTime`, `duration`, and the `seek` action met
<FrameworkCase frameworks={["react"]}>
```tsx
import { usePlayer } from '@videojs/react';
import { selectTime } from '@videojs/core/dom';
import { selectTime, usePlayer } from '@videojs/react';
function TimeDisplay() {
const time = usePlayer(selectTime);
@@ -37,14 +36,13 @@ function TimeDisplay() {
<FrameworkCase frameworks={["html"]}>
```ts
import { createPlayer, MediaElement } from '@videojs/html';
import { createPlayer, MediaElement, selectTime } from '@videojs/html';
import { videoFeatures } from '@videojs/html/video';
import { selectTime } from '@videojs/core/dom';
const { PlayerController, context } = createPlayer({ features: videoFeatures });
class TimeDisplay extends MediaElement {
#time = new PlayerController(this, context, selectTime);
readonly #time = new PlayerController(this, context, selectTime);
}
```
</FrameworkCase>
@@ -19,8 +19,7 @@ The returned state includes `volume`, `muted`, and action methods like `setVolum
<FrameworkCase frameworks={["react"]}>
```tsx
import { usePlayer } from '@videojs/react';
import { selectVolume } from '@videojs/core/dom';
import { selectVolume, usePlayer } from '@videojs/react';
function VolumeSlider() {
const vol = usePlayer(selectVolume);
@@ -42,14 +41,13 @@ function VolumeSlider() {
<FrameworkCase frameworks={["html"]}>
```ts
import { createPlayer, MediaElement } from '@videojs/html';
import { createPlayer, MediaElement, selectVolume } from '@videojs/html';
import { videoFeatures } from '@videojs/html/video';
import { selectVolume } from '@videojs/core/dom';
const { PlayerController, context } = createPlayer({ features: videoFeatures });
class VolumeSlider extends MediaElement {
#volume = new PlayerController(this, context, selectVolume);
readonly #volume = new PlayerController(this, context, selectVolume);
}
```
</FrameworkCase>