mirror of
https://github.com/zoriya/v10.git
synced 2026-08-16 02:45:09 +00:00
Co-authored-by: Darius Cepulis <dcepulis@mux.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
6.8 KiB
6.8 KiB
Component Library Documentation Patterns
Patterns from Radix UI, Ark UI, React Aria, Melt UI, Bits UI, Kobalte.
Per-Component Page Structure
All top-tier component libraries follow this structure:
- Live interactive demo (top of page)
- Features bullet list (3-5 key capabilities)
- Quick reference (install, version, bundle size, source link)
- Anatomy diagram (component tree)
- Basic example (copy button, runnable)
- Advanced examples (controlled, events, composition)
- Props/API Reference (categorized tables)
- Data Attributes (CSS styling hooks)
- CSS Variables (theming)
- Accessibility (keyboard table, ARIA)
Anatomy Documentation
Show component composition clearly:
// ✅ Clear anatomy
import { Slider } from "@videojs/dom";
<Slider.Root>
<Slider.Track>
<Slider.Range />
</Slider.Track>
<Slider.Thumb />
</Slider.Root>;
Document what each part renders:
| Part | Renders | Purpose |
|---|---|---|
Root |
<div> |
Container, manages state |
Track |
<div> |
Clickable track area |
Range |
<div> |
Filled portion |
Thumb |
<div> |
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:
onprefix, 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:
.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:
import { Slider, useSliderContext } from "@videojs/dom";
function CustomThumb() {
const slider = useSliderContext();
return <div>{slider.value}%</div>;
}
| 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
import { Slider } from "@videojs/react";
<Slider defaultValue={50} />;
Hook API
import { useSlider } from "@videojs/react";
function CustomSlider() {
const { rootProps, trackProps, thumbProps, state } = useSlider({
defaultValue: 50,
});
return (
<div {...rootProps}>
<div {...trackProps}>
<div {...thumbProps} />
</div>
</div>
);
}
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:
forwardRefon all parts - Controlled/uncontrolled:
valuevsdefaultValue
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
asprop: polymorphic rendering
Lit / Web Components
- Controllers: reactive state subscription
- Mixins: class composition for shared behavior
- Context: Lit Context Protocol for dependency injection
- Slots:
<slot>for composition
Polymorphic Components
Document as prop pattern:
// Render as different element
<Slider.Root as="section">
// Render as custom component
<Slider.Root as={CustomContainer}>
Composition Examples
Show real-world compositions:
// Volume control with mute
<div className="volume-control">
<MuteButton />
<Slider.Root value={volume} onValueChange={setVolume}>
<Slider.Track>
<Slider.Range />
</Slider.Track>
<Slider.Thumb />
</Slider.Root>
</div>
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 — building headless components