CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-storybook-dark-mode

Toggle between light and dark mode in Storybook

Pending
Overview
Eval results
Files

configuration.mddocs/

Configuration

Comprehensive configuration options for customizing Storybook Dark Mode behavior, themes, and CSS class management through Storybook parameters.

Capabilities

Dark Mode Parameters

Configuration object for customizing dark mode behavior in .storybook/preview.js. Parameters are passed as a partial DarkModeStore object.

/**
 * Dark mode configuration parameters
 * All properties are optional and will be merged with default values
 */
type DarkModeParameters = Partial<DarkModeStore>;

interface DarkModeStore {
  /** Initial theme preference - takes precedence over OS preference */
  current?: 'light' | 'dark';
  /** Custom dark theme configuration object */
  dark?: ThemeVars;
  /** Custom light theme configuration object */ 
  light?: ThemeVars;
  /** CSS class(es) applied to target elements in dark mode */
  darkClass?: string | string[];
  /** CSS class(es) applied to target elements in light mode */
  lightClass?: string | string[];
  /** CSS selector for target element in preview iframe */
  classTarget?: string;
  /** Whether to apply theme classes to preview iframe content */
  stylePreview?: boolean;
  /** Whether user has manually set a theme preference (internal) */
  userHasExplicitlySetTheTheme?: boolean;
}

Theme Configuration

Override default Storybook themes with custom styling.

/**
 * Storybook theme configuration object
 * Extends @storybook/theming ThemeVars interface
 */
interface ThemeVars {
  appBg?: string;
  appContentBg?: string;
  appBorderColor?: string;
  appBorderRadius?: number;
  fontBase?: string;
  fontCode?: string;
  textColor?: string;
  barTextColor?: string;
  barSelectedColor?: string;
  barBg?: string;
  inputBg?: string;
  inputBorder?: string;
  inputTextColor?: string;
  inputBorderRadius?: number;
  // ... additional Storybook theme properties
}

Usage Examples:

import { themes } from '@storybook/theming';

export const parameters = {
  darkMode: {
    // Custom dark theme
    dark: { 
      ...themes.dark, 
      appBg: '#1a1a1a',
      appContentBg: '#2d2d2d',
      textColor: '#ffffff'
    },
    // Custom light theme
    light: { 
      ...themes.normal, 
      appBg: '#f8f9fa',
      appContentBg: '#ffffff',
      textColor: '#333333'
    }
  }
};

Initial Theme Settings

Control which theme is active when Storybook first loads.

Theme Precedence Order:

  1. User's previously saved preference (localStorage)
  2. current parameter value
  3. OS color scheme preference
  4. Default light theme
export const parameters = {
  darkMode: {
    // Force light theme on initial load
    current: 'light',
    // Or force dark theme
    current: 'dark'
  }
};

CSS Class Management

Customize CSS classes applied to manager and preview elements for theme styling.

/**
 * CSS class configuration for theme styling
 */
interface ClassConfiguration {
  /** Class(es) applied in dark mode - can be string or array */
  darkClass?: string | string[];
  /** Class(es) applied in light mode - can be string or array */
  lightClass?: string | string[];
  /** CSS selector for target element in preview iframe */
  classTarget?: string;
}

Default Values:

  • darkClass: ['dark']
  • lightClass: ['light']
  • classTarget: 'body'

Usage Examples:

export const parameters = {
  darkMode: {
    // Single class names
    darkClass: 'theme-dark',
    lightClass: 'theme-light',
    
    // Multiple classes
    darkClass: ['dark', 'high-contrast'],
    lightClass: ['light', 'standard-contrast'],
    
    // Target different element
    classTarget: 'html'  // Apply classes to <html> instead of <body>
  }
};

Preview Iframe Styling

Control whether theme classes are applied to the preview iframe content.

/**
 * Preview styling configuration
 */
interface PreviewStylingConfig {
  /** Whether to apply theme classes to preview iframe */
  stylePreview?: boolean;
  /** CSS selector for target element within preview iframe */
  classTarget?: string;
}

Usage Examples:

export const parameters = {
  darkMode: {
    // Enable preview iframe styling
    stylePreview: true,
    // Apply classes to specific element in preview
    classTarget: '.story-wrapper'
  }
};

Complete Configuration Example

import { themes } from '@storybook/theming';

export const parameters = {
  darkMode: {
    // Initial theme
    current: 'light',
    
    // Custom themes
    dark: {
      ...themes.dark,
      appBg: '#0d1117',
      appContentBg: '#161b22',
      appBorderColor: '#30363d',
      textColor: '#f0f6fc',
      barTextColor: '#f0f6fc',
      barSelectedColor: '#58a6ff',
      barBg: '#161b22'
    },
    light: {
      ...themes.normal,
      appBg: '#ffffff',
      appContentBg: '#ffffff',
      appBorderColor: '#e1e4e8',
      textColor: '#24292f',
      barTextColor: '#24292f',
      barSelectedColor: '#0969da',
      barBg: '#f6f8fa'
    },
    
    // CSS class configuration
    darkClass: ['dark-mode', 'high-contrast'],
    lightClass: ['light-mode', 'standard-contrast'],
    classTarget: 'html',
    
    // Preview iframe styling
    stylePreview: true
  }
};

Storage and Persistence

The addon automatically persists user theme preferences using localStorage with the key 'sb-addon-themes-3'. This includes:

  • Current theme selection
  • Custom theme configurations
  • User preference flags

Storage Structure:

interface StoredData {
  current: 'light' | 'dark';
  dark: ThemeVars;
  light: ThemeVars;
  classTarget: string;
  darkClass: string | string[];
  lightClass: string | string[];
  stylePreview: boolean;
  userHasExplicitlySetTheTheme: boolean;
}

Install with Tessl CLI

npx tessl i tessl/npm-storybook-dark-mode

docs

configuration.md

event-system.md

index.md

internal-apis.md

react-integration.md

tile.json