feat(site): feature and preset reference UI + docs integration (#1258)

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Darius Cepulis
2026-04-14 17:19:01 -05:00
committed by GitHub
co-authored by Claude Opus 4.6
parent 5301202a18
commit d4b805ea69
35 changed files with 643 additions and 234 deletions
+7 -1
View File
@@ -144,7 +144,13 @@ DASH, YouTube, Vimeo, Mux, and more media elements are currently under developme
**Presets** preconfigure these parts for a specific use case.
The default presets are `/video` and `/audio`, covering the baseline set of controls you'd expect from the HTML `<video>` and `<audio>` tags.
<FrameworkCase frameworks={["react"]}>
The default presets are `@videojs/react/video` and `@videojs/react/audio`, covering the baseline set of controls you'd expect from the HTML `<video>` and `<audio>` tags.
</FrameworkCase>
<FrameworkCase frameworks={["html"]}>
The default presets are `@videojs/html/video` and `@videojs/html/audio`, covering the baseline set of controls you'd expect from the HTML `<video>` and `<audio>` tags.
</FrameworkCase>
Beyond the defaults, presets target more specific use cases. For example, `/background` includes a media element with autoplay, mute, and loop built in, a skin with no controls, and just the features needed to power it:
+6 -20
View File
@@ -3,15 +3,16 @@ title: Presets
description: Pre-packaged player configurations that bundle state management, skins, and media elements for specific use cases.
---
import PresetReference from '@/components/docs/api-reference/PresetReference.astro';
import FrameworkCase from '@/components/docs/FrameworkCase.astro';
import Aside from '@/components/Aside.astro';
import DocsLink from '@/components/docs/DocsLink.astro';
A **preset** packages what you need for a specific player use case. It can include special <DocsLink slug="concepts/features">state management</DocsLink>, one or more <DocsLink slug="concepts/skins">skins</DocsLink> for UI, and specific media elements. Instead of assembling these pieces individually, you pick a preset that matches what you're building.
For example, the `/background` preset includes a media element with autoplay, mute, and loop built in, a skin with no controls, and just the features needed to power them:
<FrameworkCase frameworks={["react"]}>
For example, the `@videojs/react/background` preset includes a media element with autoplay, mute, and loop built in, a skin with no controls, and just the features needed to power them:
```tsx title="App.tsx"
import { createPlayer } from '@videojs/react';
import { backgroundFeatures, BackgroundVideo, BackgroundVideoSkin } from '@videojs/react/background'; // [!code focus]
@@ -30,6 +31,8 @@ function Hero() {
```
</FrameworkCase>
<FrameworkCase frameworks={["html"]}>
For example, the `@videojs/html/background` preset includes a media element with autoplay, mute, and loop built in, a skin with no controls, and just the features needed to power them:
```html title="index.html"
<script type="module">
import '@videojs/html/background/player';
@@ -49,24 +52,7 @@ function Hero() {
The default presets are `/video` and `/audio`. These cover the baseline controls you'd expect from the HTML `<video>` and `<audio>` tags. Beyond the defaults, presets target more specific use cases — the `/background` preset, for example, needs layout but not controls. Over time we'll add more: short-form players, podcast players, TV streaming players, and others.
<FrameworkCase frameworks={["react"]}>
| Preset | Feature bundle | Skins | Default media element |
|--------|---------------|-------|-----------------------|
| `/video` | `videoFeatures` | `<VideoSkin>`, `<MinimalVideoSkin>` | `<Video>` |
| `/audio` | `audioFeatures` | `<AudioSkin>`, `<MinimalAudioSkin>` | `<Audio>` |
| `/background` | `backgroundFeatures` | `<BackgroundVideoSkin>` | `<BackgroundVideo>` |
</FrameworkCase>
<FrameworkCase frameworks={["html"]}>
| Preset | Skins | Default media element |
|--------|-------|-----------------------|
| `/video` | `<video-skin>`, `<video-minimal-skin>` | `<video>` |
| `/audio` | `<audio-skin>`, `<audio-minimal-skin>` | `<audio>` |
| `/background` | `<background-video-skin>` | `<background-video>` |
</FrameworkCase>
<PresetReference />
## What's in a preset
+6 -21
View File
@@ -3,6 +3,7 @@ title: Skins
description: Packaged player designs that include both UI components and their styles.
---
import PresetReference from '@/components/docs/api-reference/PresetReference.astro';
import FrameworkCase from '@/components/docs/FrameworkCase.astro';
import { FrostedSkinDemo } from '@/examples/react/FrostedSkin/FrostedSkinDemo';
import { MinimalSkinDemo } from '@/examples/react/MinimalSkin/MinimalSkinDemo';
@@ -88,31 +89,15 @@ When you choose a skin you have two options for how you use it: **packaged** or
## Skins, features, and presets
Each skin is built with specific <DocsLink slug="concepts/features">features</DocsLink> in mind. For example, a video skin renders fullscreen and picture-in-picture controls. An audio skin doesn't. The features associated with a skin are called a **feature bundle**.
Each skin is built with specific <DocsLink slug="concepts/features">features</DocsLink> in mind. For example, a video skin renders fullscreen and picture-in-picture controls. An audio skin doesn't.
<FrameworkCase frameworks={["html"]}>
You'll find both a skin and the feature bundle it expects exported from the same path. We call these paths **presets**.
| Player with feature bundle | Available skins | Import |
| ---------- | ----------------- | -------- |
| `<video-player>` | `<video-skin>`, `<video-minimal-skin>` | `@videojs/html/video/*` |
| `<audio-player>` | `<audio-skin>`, `<audio-minimal-skin>` | `@videojs/html/audio/*` |
| `<background-video-player>` | `<background-video-skin>` | `@videojs/html/background/*` |
<PresetReference />
</FrameworkCase>
Presets are a topic quite a bit bigger than just this guide. To learn more, check out the guide:
<FrameworkCase frameworks={["react"]}>
| Feature bundle | Available skins | Import |
| ---------- | ----------------- | -------- |
| `videoFeatures` | `<VideoSkin>`, `<MinimalVideoSkin>` | `@videojs/react/video` |
| `audioFeatures` | `<AudioSkin>`, `<MinimalAudioSkin>` | `@videojs/react/audio` |
| `backgroundFeatures` | `<BackgroundVideoSkin>` | `@videojs/react/background` |
</FrameworkCase>
Want to learn more about skins and feature bundles? Check out the presets guide:
<DocsLinkCard slug="concepts/presets">Learn more about presets</DocsLinkCard>
<DocsLinkCard slug="concepts/presets">Read about presets</DocsLinkCard>
## Styling
@@ -3,20 +3,15 @@ title: Buffer
description: Buffered and seekable time range state for the player store
---
import UtilReference from "@/components/docs/api-reference/UtilReference.astro";
import FeatureReference from "@/components/docs/api-reference/FeatureReference.astro";
import DocsLink from "@/components/docs/DocsLink.astro";
import FrameworkCase from "@/components/docs/FrameworkCase.astro";
Read-only — tracks buffered and seekable time ranges.
## State
<FeatureReference feature="buffer" />
| State | Type | Description |
|---|---|---|
| `buffered` | `[number, number][]` | Buffered time ranges as `[start, end]` tuples |
| `seekable` | `[number, number][]` | Seekable time ranges as `[start, end]` tuples |
## Selector
### Selector
<FrameworkCase frameworks={["react"]}>
Pass `selectBuffer` to <DocsLink slug="reference/use-player">`usePlayer`</DocsLink> to subscribe to buffer state. Returns `undefined` if the buffer feature is not configured.
@@ -53,5 +48,3 @@ class BufferBar extends MediaElement {
}
```
</FrameworkCase>
<UtilReference util="selectBuffer" />
@@ -3,20 +3,15 @@ title: Controls
description: User activity and controls visibility state for the player store
---
import UtilReference from "@/components/docs/api-reference/UtilReference.astro";
import FeatureReference from "@/components/docs/api-reference/FeatureReference.astro";
import DocsLink from "@/components/docs/DocsLink.astro";
import FrameworkCase from "@/components/docs/FrameworkCase.astro";
Read-only — tracks user activity for showing and hiding controls.
## State
<FeatureReference feature="controls" />
| State | Type | Description |
|---|---|---|
| `userActive` | `boolean` | Whether the user has recently interacted |
| `controlsVisible` | `boolean` | Whether controls should be visible (active or paused) |
## Selector
### Selector
<FrameworkCase frameworks={["react"]}>
Pass `selectControls` to <DocsLink slug="reference/use-player">`usePlayer`</DocsLink> to subscribe to controls state. Returns `undefined` if the controls feature is not configured.
@@ -55,5 +50,3 @@ class ControlsOverlay extends MediaElement {
}
```
</FrameworkCase>
<UtilReference util="selectControls" />
@@ -3,25 +3,15 @@ title: Error
description: Media error state and actions for the player store
---
import UtilReference from "@/components/docs/api-reference/UtilReference.astro";
import FeatureReference from "@/components/docs/api-reference/FeatureReference.astro";
import DocsLink from "@/components/docs/DocsLink.astro";
import FrameworkCase from "@/components/docs/FrameworkCase.astro";
Tracks media errors.
## State
<FeatureReference feature="error" />
| State | Type | Description |
|---|---|---|
| `error` | `MediaError \| null` | The current error, or `null` |
## Actions
| Action | Description |
|---|---|
| `dismissError()` | Clear the current error |
## Selector
### Selector
<FrameworkCase frameworks={["react"]}>
Pass `selectError` to <DocsLink slug="reference/use-player">`usePlayer`</DocsLink> to subscribe to error state. Returns `undefined` if the error feature is not configured.
@@ -61,5 +51,3 @@ class ErrorDisplay extends MediaElement {
}
```
</FrameworkCase>
<UtilReference util="selectError" />
@@ -3,27 +3,15 @@ title: Fullscreen
description: Fullscreen state and actions for the player store
---
import UtilReference from "@/components/docs/api-reference/UtilReference.astro";
import FeatureReference from "@/components/docs/api-reference/FeatureReference.astro";
import DocsLink from "@/components/docs/DocsLink.astro";
import FrameworkCase from "@/components/docs/FrameworkCase.astro";
Controls fullscreen mode. Tries the container element first, falls back to the media element.
## State
<FeatureReference feature="fullscreen" />
| State | Type | Description |
|---|---|---|
| `fullscreen` | `boolean` | Whether fullscreen is active |
| `fullscreenAvailability` | `MediaFeatureAvailability` | Whether fullscreen is supported |
## Actions
| Action | Description |
|---|---|
| `requestFullscreen()` | Enter fullscreen (returns a `Promise`) |
| `exitFullscreen()` | Exit fullscreen (returns a `Promise`) |
## Selector
### Selector
<FrameworkCase frameworks={["react"]}>
Pass `selectFullscreen` to <DocsLink slug="reference/use-player">`usePlayer`</DocsLink> to subscribe to fullscreen state. Returns `undefined` if the fullscreen feature is not configured.
@@ -62,5 +50,3 @@ class FullscreenButton extends MediaElement {
}
```
</FrameworkCase>
<UtilReference util="selectFullscreen" />
@@ -3,27 +3,15 @@ title: Picture-in-picture
description: Picture-in-picture state and actions for the player store
---
import UtilReference from "@/components/docs/api-reference/UtilReference.astro";
import FeatureReference from "@/components/docs/api-reference/FeatureReference.astro";
import DocsLink from "@/components/docs/DocsLink.astro";
import FrameworkCase from "@/components/docs/FrameworkCase.astro";
Controls picture-in-picture mode.
## State
<FeatureReference feature="pip" />
| State | Type | Description |
|---|---|---|
| `pip` | `boolean` | Whether picture-in-picture is active |
| `pipAvailability` | `MediaFeatureAvailability` | Whether PiP is supported |
## Actions
| Action | Description |
|---|---|
| `requestPictureInPicture()` | Enter picture-in-picture (returns a `Promise`) |
| `exitPictureInPicture()` | Exit picture-in-picture (returns a `Promise`) |
## Selector
### Selector
<FrameworkCase frameworks={["react"]}>
Pass `selectPiP` to <DocsLink slug="reference/use-player">`usePlayer`</DocsLink> to subscribe to picture-in-picture state. Returns `undefined` if the PiP feature is not configured.
@@ -62,5 +50,3 @@ class PiPButton extends MediaElement {
}
```
</FrameworkCase>
<UtilReference util="selectPiP" />
@@ -3,26 +3,15 @@ title: Playback rate
description: Playback speed state and actions for the player store
---
import UtilReference from "@/components/docs/api-reference/UtilReference.astro";
import FeatureReference from "@/components/docs/api-reference/FeatureReference.astro";
import DocsLink from "@/components/docs/DocsLink.astro";
import FrameworkCase from "@/components/docs/FrameworkCase.astro";
Controls speed of playback.
## State
<FeatureReference feature="playbackRate" />
| State | Type | Description |
|---|---|---|
| `playbackRate` | `number` | Current playback speed (1 = normal) |
| `playbackRates` | `readonly number[]` | Available playback rates |
## Actions
| Action | Description |
|---|---|
| `setPlaybackRate(rate)` | Set the playback speed |
## Selector
### Selector
<FrameworkCase frameworks={["react"]}>
Pass `selectPlaybackRate` to <DocsLink slug="reference/use-player">`usePlayer`</DocsLink> to subscribe to playback rate state. Returns `undefined` if the playback rate feature is not configured.
@@ -57,5 +46,3 @@ class RateDisplay extends MediaElement {
}
```
</FrameworkCase>
<UtilReference util="selectPlaybackRate" />
@@ -3,29 +3,15 @@ title: Playback
description: Play/pause state and actions for the player store
---
import UtilReference from "@/components/docs/api-reference/UtilReference.astro";
import FeatureReference from "@/components/docs/api-reference/FeatureReference.astro";
import DocsLink from "@/components/docs/DocsLink.astro";
import FrameworkCase from "@/components/docs/FrameworkCase.astro";
Controls play/pause state and tracks whether playback has started or is stalled.
## State
<FeatureReference feature="playback" />
| State | Type | Description |
|---|---|---|
| `paused` | `boolean` | Whether playback is paused |
| `ended` | `boolean` | Whether playback reached the end |
| `started` | `boolean` | Whether playback has started (played or seeked) |
| `waiting` | `boolean` | Whether playback is stalled waiting for data |
## Actions
| Action | Description |
|---|---|
| `play()` | Start playback (returns a `Promise`) |
| `pause()` | Pause playback |
## Selector
### Selector
<FrameworkCase frameworks={["react"]}>
Pass `selectPlayback` to <DocsLink slug="reference/use-player">`usePlayer`</DocsLink> to subscribe to playback state. Returns `undefined` if the playback feature is not configured.
@@ -59,5 +45,3 @@ class PlayButton extends MediaElement {
}
```
</FrameworkCase>
<UtilReference util="selectPlayback" />
@@ -3,26 +3,15 @@ title: Source
description: Media source state and actions for the player store
---
import UtilReference from "@/components/docs/api-reference/UtilReference.astro";
import FeatureReference from "@/components/docs/api-reference/FeatureReference.astro";
import DocsLink from "@/components/docs/DocsLink.astro";
import FrameworkCase from "@/components/docs/FrameworkCase.astro";
Tracks the current media source and readiness.
## State
<FeatureReference feature="source" />
| State | Type | Description |
|---|---|---|
| `source` | `string \| null` | Current media source URL |
| `canPlay` | `boolean` | Whether enough data is loaded to begin playback |
## Actions
| Action | Description |
|---|---|
| `loadSource(src)` | Load a new media source |
## Selector
### Selector
<FrameworkCase frameworks={["react"]}>
Pass `selectSource` to <DocsLink slug="reference/use-player">`usePlayer`</DocsLink> to subscribe to source state. Returns `undefined` if the source feature is not configured.
@@ -57,5 +46,3 @@ class SourceInfo extends MediaElement {
}
```
</FrameworkCase>
<UtilReference util="selectSource" />
@@ -3,29 +3,15 @@ title: Text tracks
description: Subtitles, captions, and chapter track state for the player store
---
import UtilReference from "@/components/docs/api-reference/UtilReference.astro";
import FeatureReference from "@/components/docs/api-reference/FeatureReference.astro";
import DocsLink from "@/components/docs/DocsLink.astro";
import FrameworkCase from "@/components/docs/FrameworkCase.astro";
Manages subtitles, captions, chapters, and thumbnail tracks.
## State
<FeatureReference feature="textTrack" />
| State | Type | Description |
|---|---|---|
| `textTrackList` | `MediaTextTrack[]` | All text tracks on the media element |
| `subtitlesShowing` | `boolean` | Whether captions/subtitles are enabled |
| `chaptersCues` | `MediaTextCue[]` | Cues from the first chapters track |
| `thumbnailCues` | `MediaTextCue[]` | Cues from the first thumbnails track |
| `thumbnailTrackSrc` | `string \| null` | Track `src` for resolving relative thumbnail URLs |
## Actions
| Action | Description |
|---|---|
| `toggleSubtitles(forceShow?)` | Toggle subtitle visibility. Pass `true`/`false` to force. |
## Selector
### Selector
<FrameworkCase frameworks={["react"]}>
Pass `selectTextTracks` to <DocsLink slug="reference/use-player">`usePlayer`</DocsLink> to subscribe to text track state. Returns `undefined` if the text tracks feature is not configured.
@@ -64,5 +50,3 @@ class CaptionsButton extends MediaElement {
}
```
</FrameworkCase>
<UtilReference util="selectTextTracks" />
@@ -3,27 +3,15 @@ title: Time
description: Playback position and duration state for the player store
---
import UtilReference from "@/components/docs/api-reference/UtilReference.astro";
import FeatureReference from "@/components/docs/api-reference/FeatureReference.astro";
import DocsLink from "@/components/docs/DocsLink.astro";
import FrameworkCase from "@/components/docs/FrameworkCase.astro";
Tracks playback position and duration.
## State
<FeatureReference feature="time" />
| State | Type | Description |
|---|---|---|
| `currentTime` | `number` | Current playback position in seconds |
| `duration` | `number` | Total duration in seconds (0 if unknown) |
| `seeking` | `boolean` | Whether a seek operation is in progress |
## Actions
| Action | Description |
|---|---|
| `seek(time)` | Seek to a position in seconds (returns a `Promise`) |
## Selector
### Selector
<FrameworkCase frameworks={["react"]}>
Pass `selectTime` to <DocsLink slug="reference/use-player">`usePlayer`</DocsLink> to subscribe to time state. Returns `undefined` if the time feature is not configured.
@@ -62,5 +50,3 @@ class TimeDisplay extends MediaElement {
}
```
</FrameworkCase>
<UtilReference util="selectTime" />
@@ -3,28 +3,15 @@ title: Volume
description: Volume level and mute state for the player store
---
import UtilReference from "@/components/docs/api-reference/UtilReference.astro";
import FeatureReference from "@/components/docs/api-reference/FeatureReference.astro";
import DocsLink from "@/components/docs/DocsLink.astro";
import FrameworkCase from "@/components/docs/FrameworkCase.astro";
Controls volume level and mute state.
## State
<FeatureReference feature="volume" />
| State | Type | Description |
|---|---|---|
| `volume` | `number` | Volume level from 0 (silent) to 1 (max) |
| `muted` | `boolean` | Whether audio is muted |
| `volumeAvailability` | `MediaFeatureAvailability` | Whether volume can be set on this platform |
## Actions
| Action | Description |
|---|---|
| `setVolume(volume)` | Set volume (clamped 01). Auto-unmutes when raising above zero. |
| `toggleMuted()` | Toggle mute. Restores volume to 0.25 when unmuting at zero. |
## Selector
### Selector
<FrameworkCase frameworks={["react"]}>
Pass `selectVolume` to <DocsLink slug="reference/use-player">`usePlayer`</DocsLink> to subscribe to volume state. Returns `undefined` if the volume feature is not configured.
@@ -68,5 +55,3 @@ class VolumeSlider extends MediaElement {
}
```
</FrameworkCase>
<UtilReference util="selectVolume" />