` | Draggable handle |
## Props Tables
Standard format across all libraries:
| Prop | Type | Default | Description |
| --------------- | ---------------------------- | -------------- | ---------------------------- |
| `value` | `number` | — | Controlled value |
| `defaultValue` | `number` | `0` | Initial value (uncontrolled) |
| `min` | `number` | `0` | Minimum value |
| `max` | `number` | `100` | Maximum value |
| `step` | `number` | `1` | Step increment |
| `disabled` | `boolean` | `false` | Disable interaction |
| `orientation` | `'horizontal' \| 'vertical'` | `'horizontal'` | Slider direction |
| `onValueChange` | `(value: number) => void` | — | Called on change |
**Conventions:**
- Required props: no default, marked with `*` or bold
- Optional props: show default value
- Callback props: `on` prefix, show signature
- Enum props: show all options with `|`
## Data Attributes Tables
Document CSS hooks:
| Attribute | Values | Description |
| ------------------ | ---------------------------- | ------------------------- |
| `data-state` | `'idle' \| 'dragging'` | Current interaction state |
| `data-disabled` | `''` | Present when disabled |
| `data-orientation` | `'horizontal' \| 'vertical'` | Current orientation |
| `data-focus` | `''` | Present when focused |
**Usage example:**
```css
.slider[data-dragging] {
cursor: grabbing;
}
.slider[data-disabled] {
opacity: 0.5;
pointer-events: none;
}
```
## CSS Variables Tables
Document theming hooks:
| Variable | Default | Description |
| ----------------------- | -------------- | ------------------ |
| `--slider-thumb-size` | `20px` | Thumb diameter |
| `--slider-track-height` | `4px` | Track thickness |
| `--slider-range-color` | `currentColor` | Filled range color |
## Context API (Ark UI Pattern)
Document programmatic access:
```tsx
import { Slider, useSliderContext } from "@videojs/dom";
function CustomThumb() {
const slider = useSliderContext();
return
{slider.value}%
;
}
```
| Property | Type | Description |
| ---------- | --------- | ------------------- |
| `value` | `number` | Current value |
| `percent` | `number` | Value as percentage |
| `dragging` | `boolean` | Whether dragging |
| `disabled` | `boolean` | Whether disabled |
## Dual API Pattern (React Aria)
Document both high-level components and low-level hooks:
### Component API
```tsx
import { Slider } from "@videojs/react";
;
```
### Hook API
```tsx
import { useSlider } from "@videojs/react";
function CustomSlider() {
const { rootProps, trackProps, thumbProps, state } = useSlider({
defaultValue: 50,
});
return (
);
}
```
## Accessibility Section
Always include:
### Keyboard Interactions
| Key | Action |
| ------------ | ---------------------- |
| `ArrowRight` | Increase by step |
| `ArrowLeft` | Decrease by step |
| `ArrowUp` | Increase by step |
| `ArrowDown` | Decrease by step |
| `PageUp` | Increase by large step |
| `PageDown` | Decrease by large step |
| `Home` | Set to min |
| `End` | Set to max |
### ARIA
- Role: `slider`
- Required: `aria-valuenow`, `aria-valuemin`, `aria-valuemax`
- Optional: `aria-label`, `aria-valuetext`
### Focus Management
Document focus behavior, trap patterns, restore behavior.
## Framework-Specific Patterns
### React (Radix, React Aria)
- Hooks: `useSlider`, `useSliderContext`
- Refs: `forwardRef` on all parts
- Controlled/uncontrolled: `value` vs `defaultValue`
### Vue (Ark UI)
- v-model: `v-model:value`
- Slots: scoped slots for customization
- Composables: `useSlider()`
### Svelte (Melt UI, Bits UI)
- Builders: `createSlider()`
- Actions: `use:melt={$slider.root}`
- Stores: `$slider.value`
- Svelte 5: snippets for composition
### Solid (Kobalte)
- Primitives: `createSlider()`
- Signals: reactive by default
- `as` prop: polymorphic rendering
### Lit / Web Components
- Controllers: reactive state subscription
- Mixins: class composition for shared behavior
- Context: Lit Context Protocol for dependency injection
- Slots: `
` for composition
## Polymorphic Components
Document `as` prop pattern:
```tsx
// Render as different element
// Render as custom component
```
## Composition Examples
Show real-world compositions:
```tsx
// Volume control with mute
```
---
## Applicable to Video.js
The patterns above are drawn from many libraries. Not all apply to Video.js reference pages. Where existing patterns contradict the patterns outlined here, follow the existing patterns.
---
## See Also
- [Component Patterns](../../component/SKILL.md) — building headless components