Overview
PreviewPanel renders content in both light and dark modes simultaneously, making it ideal for theme customizers and design system demos. It uses a render prop pattern to provide mode-specific context.
Key Features
- Stacked light/dark previews with consistent styling
- Render prop provides mode, isDark, styles, and tokens
- Custom token overrides for background, foreground, card, border
- Additional CSS custom properties per mode (brand colors)
- Configurable labels, gap spacing
Examples
Basic Usage
Basic preview with custom tokens for light and dark modes.
Dark Mode
Dark Theme
This content adapts to light and dark mode with custom tokens.
Light Mode
Light Theme
This content adapts to light and dark mode with custom tokens.
With Cards & Custom Properties
Preview with Card components and custom accent properties.
Dark Mode
Card Component
Cards render with mode-specific styling.
Light Mode
Card Component
Cards render with mode-specific styling.
No Labels, Compact
Minimal preview without mode labels and tighter spacing.
dark
light
Props Reference
| Prop | Type | Default | Description |
|---|---|---|---|
children | (props: PreviewRenderProps) => ReactNode | required | Render prop receiving mode context (mode, isDark, styles, tokens) |
tokens | PreviewModeTokens | - | Custom token overrides for light/dark modes (background, foreground, card, border, input) |
customProperties | PreviewCustomProperties | - | Additional CSS custom properties per mode (e.g., brand colors) |
lightLabel | string | 'Light Mode' | Label for light mode preview |
darkLabel | string | 'Dark Mode' | Label for dark mode preview |
showLabels | boolean | true | Whether to show mode labels |
gap | 2 | 3 | 4 | 6 | 8 | 4 | Gap between light and dark panels (in Tailwind spacing units) |
className | string | - | Additional className for the outer container |
Usage
import { PreviewPanel } from '@/ui/components';
// Basic usage with render prop
<PreviewPanel
tokens={{
light: { background: '#ffffff', foreground: '#1a1a1a' },
dark: { background: '#0a0a0a', foreground: '#fafafa' },
}}
>
{({ mode, isDark, styles, tokens }) => (
<div style={styles}>
<h3>{mode} mode preview</h3>
<p style={{ color: tokens.foreground }}>
Content with theme-aware styling
</p>
</div>
)}
</PreviewPanel>
// With custom properties (e.g., brand colors)
<PreviewPanel
tokens={{ light: {...}, dark: {...} }}
customProperties={{
light: { '--accent': '#3b82f6' },
dark: { '--accent': '#60a5fa' },
}}
>
{({ styles }) => (
<div style={styles}>
<button style={{ backgroundColor: 'var(--accent)' }}>
Brand Button
</button>
</div>
)}
</PreviewPanel>
// Hide labels, adjust gap
<PreviewPanel showLabels={false} gap={2}>
{({ mode }) => <div>{mode}</div>}
</PreviewPanel>