0
# Data Attribute-Based Theming
1
2
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.
3
4
## Capabilities
5
6
### withThemeByDataAttribute
7
8
Creates a decorator that sets data attributes on a parent element to enable theme switching.
9
10
```typescript { .api }
11
/**
12
* Creates a decorator for data attribute-based theme switching
13
* @param config - Configuration object specifying themes and options
14
* @returns Storybook decorator function
15
*/
16
function withThemeByDataAttribute<TRenderer extends Renderer = any>(
17
config: DataAttributeStrategyConfiguration
18
): DecoratorFunction<TRenderer>;
19
20
interface DataAttributeStrategyConfiguration {
21
/** Mapping of theme names to data attribute values */
22
themes: Record<string, string>;
23
/** Name of the default theme */
24
defaultTheme: string;
25
/** CSS selector for the parent element (defaults to 'html') */
26
parentSelector?: string;
27
/** Name of the data attribute (defaults to 'data-theme') */
28
attributeName?: string;
29
}
30
```
31
32
**Usage Examples:**
33
34
```typescript
35
import { withThemeByDataAttribute } from '@storybook/addon-themes';
36
37
// Basic usage with data-theme attribute
38
export const decorators = [
39
withThemeByDataAttribute({
40
themes: {
41
light: 'light',
42
dark: 'dark',
43
},
44
defaultTheme: 'light',
45
}),
46
];
47
48
// Custom attribute name for Bootstrap
49
export const decorators = [
50
withThemeByDataAttribute({
51
themes: {
52
light: 'light',
53
dark: 'dark',
54
},
55
defaultTheme: 'light',
56
attributeName: 'data-bs-theme',
57
}),
58
];
59
60
// Multiple themes with custom parent
61
export const decorators = [
62
withThemeByDataAttribute({
63
themes: {
64
default: 'default',
65
modern: 'modern',
66
classic: 'classic',
67
accessible: 'high-contrast',
68
},
69
defaultTheme: 'default',
70
parentSelector: '#root',
71
attributeName: 'data-color-scheme',
72
}),
73
];
74
```
75
76
## Implementation Details
77
78
### Attribute Management
79
80
The decorator automatically:
81
- Sets the specified data attribute with the theme value
82
- Updates the attribute when themes change
83
- Works with any CSS selector as the parent element
84
- Supports custom attribute names for framework compatibility
85
86
### Theme Override Support
87
88
Stories can override the global theme selection:
89
90
```javascript
91
export const HighContrastVersion = {
92
parameters: {
93
themes: {
94
themeOverride: 'accessible'
95
}
96
}
97
};
98
```
99
100
### CSS Integration
101
102
Perfect for CSS custom properties and attribute selectors:
103
104
```css
105
/* CSS Custom Properties approach */
106
[data-theme="light"] {
107
--bg-color: #ffffff;
108
--text-color: #000000;
109
--accent-color: #0066cc;
110
}
111
112
[data-theme="dark"] {
113
--bg-color: #1a1a1a;
114
--text-color: #ffffff;
115
--accent-color: #66aaff;
116
}
117
118
.component {
119
background-color: var(--bg-color);
120
color: var(--text-color);
121
}
122
123
/* Bootstrap 5.3+ data-bs-theme */
124
[data-bs-theme="light"] .btn-primary {
125
--bs-btn-bg: #0d6efd;
126
--bs-btn-border-color: #0d6efd;
127
}
128
129
[data-bs-theme="dark"] .btn-primary {
130
--bs-btn-bg: #6ea8fe;
131
--bs-btn-border-color: #6ea8fe;
132
}
133
134
/* Tailwind CSS with data attributes */
135
[data-color-scheme="modern"][data-theme="dark"] {
136
@apply bg-slate-900 text-slate-100;
137
}
138
139
[data-color-scheme="classic"][data-theme="light"] {
140
@apply bg-amber-50 text-amber-900;
141
}
142
```
143
144
## Framework Integration
145
146
### Bootstrap 5.3+
147
148
Bootstrap 5.3 introduced native dark mode support using `data-bs-theme`:
149
150
```typescript
151
export const decorators = [
152
withThemeByDataAttribute({
153
themes: {
154
light: 'light',
155
dark: 'dark',
156
},
157
defaultTheme: 'light',
158
attributeName: 'data-bs-theme',
159
}),
160
];
161
```
162
163
### CSS Modules with Data Attributes
164
165
```css
166
/* theme.module.css */
167
[data-theme="light"] .card {
168
background: white;
169
border: 1px solid #e0e0e0;
170
}
171
172
[data-theme="dark"] .card {
173
background: #2d2d2d;
174
border: 1px solid #404040;
175
}
176
```