0
# React Integration
1
2
React hook and component integration patterns for accessing and responding to theme changes in Storybook Dark Mode.
3
4
## Capabilities
5
6
### useDarkMode Hook
7
8
React hook that returns the current dark mode state and automatically updates when the theme changes.
9
10
```typescript { .api }
11
/**
12
* Returns the current state of storybook's dark-mode
13
* @returns boolean indicating if dark mode is currently active
14
*/
15
function useDarkMode(): boolean;
16
```
17
18
**Usage Examples:**
19
20
```typescript
21
import React from 'react';
22
import { useDarkMode } from 'storybook-dark-mode';
23
24
// Basic theme-aware component
25
function MyComponent() {
26
const isDark = useDarkMode();
27
28
return (
29
<div style={{
30
backgroundColor: isDark ? '#333' : '#fff',
31
color: isDark ? '#fff' : '#333'
32
}}>
33
Current theme: {isDark ? 'Dark' : 'Light'}
34
</div>
35
);
36
}
37
38
// Theme provider wrapper
39
function ThemeWrapper({ children }) {
40
const isDark = useDarkMode();
41
42
return (
43
<ThemeContext.Provider value={isDark ? darkTheme : lightTheme}>
44
{children}
45
</ThemeContext.Provider>
46
);
47
}
48
49
// Using with Storybook decorators
50
export const decorators = [
51
(renderStory) => (
52
<ThemeWrapper>
53
{renderStory()}
54
</ThemeWrapper>
55
)
56
];
57
```
58
59
### Hook Implementation Details
60
61
The hook uses React's `useState` and `useEffect` to:
62
63
1. Initialize with current theme state from internal store
64
2. Listen for theme change events via Storybook's addon channel
65
3. Automatically update component state when theme changes
66
4. Clean up event listeners on component unmount
67
68
**Internal Behavior:**
69
70
- Subscribes to `DARK_MODE_EVENT_NAME` events
71
- Manages local state synchronization with global theme state
72
- Provides automatic re-rendering when theme changes
73
74
### Integration Patterns
75
76
#### With Context Providers
77
78
```typescript
79
import React from 'react';
80
import { useDarkMode } from 'storybook-dark-mode';
81
import { ThemeProvider } from 'styled-components';
82
83
const darkTheme = { bg: '#333', color: '#fff' };
84
const lightTheme = { bg: '#fff', color: '#333' };
85
86
function StyledThemeWrapper({ children }) {
87
const isDark = useDarkMode();
88
89
return (
90
<ThemeProvider theme={isDark ? darkTheme : lightTheme}>
91
{children}
92
</ThemeProvider>
93
);
94
}
95
```
96
97
#### With CSS Classes
98
99
```typescript
100
import React from 'react';
101
import { useDarkMode } from 'storybook-dark-mode';
102
103
function ClassBasedThemeWrapper({ children }) {
104
const isDark = useDarkMode();
105
106
return (
107
<div className={isDark ? 'dark-theme' : 'light-theme'}>
108
{children}
109
</div>
110
);
111
}
112
```
113
114
#### With CSS Variables
115
116
```typescript
117
import React from 'react';
118
import { useDarkMode } from 'storybook-dark-mode';
119
120
function CSSVariableThemeWrapper({ children }) {
121
const isDark = useDarkMode();
122
123
React.useEffect(() => {
124
const root = document.documentElement;
125
if (isDark) {
126
root.style.setProperty('--bg-color', '#333');
127
root.style.setProperty('--text-color', '#fff');
128
} else {
129
root.style.setProperty('--bg-color', '#fff');
130
root.style.setProperty('--text-color', '#333');
131
}
132
}, [isDark]);
133
134
return <>{children}</>;
135
}
136
```
137
138
### Performance Considerations
139
140
- The hook only re-renders components when the theme actually changes
141
- Event listeners are properly cleaned up to prevent memory leaks
142
- State updates are batched through React's event system