mirror of
https://github.com/zoriya/v10.git
synced 2026-08-16 02:45:09 +00:00
6.7 KiB
6.7 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.