Storybook addon that enables theme switching functionality within the preview environment with support for multiple theming strategies
—
Theme switching by setting data attributes on parent elements. This approach is perfect for CSS custom properties, attribute-based selectors, and modern theming systems that rely on data attributes.
Creates a decorator that sets data attributes on a parent element to enable theme switching.
/**
* Creates a decorator for data attribute-based theme switching
* @param config - Configuration object specifying themes and options
* @returns Storybook decorator function
*/
function withThemeByDataAttribute<TRenderer extends Renderer = any>(
config: DataAttributeStrategyConfiguration
): DecoratorFunction<TRenderer>;
interface DataAttributeStrategyConfiguration {
/** Mapping of theme names to data attribute values */
themes: Record<string, string>;
/** Name of the default theme */
defaultTheme: string;
/** CSS selector for the parent element (defaults to 'html') */
parentSelector?: string;
/** Name of the data attribute (defaults to 'data-theme') */
attributeName?: string;
}Usage Examples:
import { withThemeByDataAttribute } from '@storybook/addon-themes';
// Basic usage with data-theme attribute
export const decorators = [
withThemeByDataAttribute({
themes: {
light: 'light',
dark: 'dark',
},
defaultTheme: 'light',
}),
];
// Custom attribute name for Bootstrap
export const decorators = [
withThemeByDataAttribute({
themes: {
light: 'light',
dark: 'dark',
},
defaultTheme: 'light',
attributeName: 'data-bs-theme',
}),
];
// Multiple themes with custom parent
export const decorators = [
withThemeByDataAttribute({
themes: {
default: 'default',
modern: 'modern',
classic: 'classic',
accessible: 'high-contrast',
},
defaultTheme: 'default',
parentSelector: '#root',
attributeName: 'data-color-scheme',
}),
];The decorator automatically:
Stories can override the global theme selection:
export const HighContrastVersion = {
parameters: {
themes: {
themeOverride: 'accessible'
}
}
};Perfect for CSS custom properties and attribute selectors:
/* CSS Custom Properties approach */
[data-theme="light"] {
--bg-color: #ffffff;
--text-color: #000000;
--accent-color: #0066cc;
}
[data-theme="dark"] {
--bg-color: #1a1a1a;
--text-color: #ffffff;
--accent-color: #66aaff;
}
.component {
background-color: var(--bg-color);
color: var(--text-color);
}
/* Bootstrap 5.3+ data-bs-theme */
[data-bs-theme="light"] .btn-primary {
--bs-btn-bg: #0d6efd;
--bs-btn-border-color: #0d6efd;
}
[data-bs-theme="dark"] .btn-primary {
--bs-btn-bg: #6ea8fe;
--bs-btn-border-color: #6ea8fe;
}
/* Tailwind CSS with data attributes */
[data-color-scheme="modern"][data-theme="dark"] {
@apply bg-slate-900 text-slate-100;
}
[data-color-scheme="classic"][data-theme="light"] {
@apply bg-amber-50 text-amber-900;
}Bootstrap 5.3 introduced native dark mode support using data-bs-theme:
export const decorators = [
withThemeByDataAttribute({
themes: {
light: 'light',
dark: 'dark',
},
defaultTheme: 'light',
attributeName: 'data-bs-theme',
}),
];/* theme.module.css */
[data-theme="light"] .card {
background: white;
border: 1px solid #e0e0e0;
}
[data-theme="dark"] .card {
background: #2d2d2d;
border: 1px solid #404040;
}Install with Tessl CLI
npx tessl i tessl/npm-storybook--addon-themes