CentercodeDitto
DittoPorygonAPI

PreviewPanel

Stacked light/dark mode preview component

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

PropTypeDefaultDescription
children(props: PreviewRenderProps) => ReactNoderequiredRender prop receiving mode context (mode, isDark, styles, tokens)
tokensPreviewModeTokens-Custom token overrides for light/dark modes (background, foreground, card, border, input)
customPropertiesPreviewCustomProperties-Additional CSS custom properties per mode (e.g., brand colors)
lightLabelstring'Light Mode'Label for light mode preview
darkLabelstring'Dark Mode'Label for dark mode preview
showLabelsbooleantrueWhether to show mode labels
gap2 | 3 | 4 | 6 | 84Gap between light and dark panels (in Tailwind spacing units)
classNamestring-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>