@vueless/storybook-dark-mode 9.0.6 → 9.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +90 -16
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -176,39 +176,113 @@ export const decorators = [knobDecorator];
|
|
|
176
176
|
|
|
177
177
|
You can also listen for the `DARK_MODE` event via the addons channel.
|
|
178
178
|
|
|
179
|
+
#### Listening for events
|
|
180
|
+
|
|
181
|
+
You can listen for events on the channel with React hooks:
|
|
182
|
+
|
|
179
183
|
```js
|
|
180
|
-
import { useEffect } from 'react';
|
|
184
|
+
import { useState, useEffect } from 'react';
|
|
181
185
|
import { addons } from 'storybook/preview-api';
|
|
182
186
|
import { DARK_MODE_EVENT_NAME } from '@vueless/storybook-dark-mode';
|
|
183
187
|
|
|
188
|
+
const channel = addons.getChannel()
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Use this hook if you want to pass in your own callback, e.g. Mantine's `setColorScheme`
|
|
192
|
+
**/
|
|
193
|
+
export function useOnDarkModeEvent(callback) {
|
|
194
|
+
useEffect(function () {
|
|
195
|
+
channel.on(DARK_MODE_EVENT_NAME, callback)
|
|
196
|
+
return () => channel.off(DARK_MODE_EVENT_NAME, callback)
|
|
197
|
+
})
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Use this hook if you only need to know whether dark mode is toggled on
|
|
202
|
+
**/
|
|
203
|
+
export function useIsDarkMode() {
|
|
204
|
+
const [isDarkMode, setIsDarkMode] = useState()
|
|
205
|
+
useOnDarkModeEvent(setIsDarkMode)
|
|
206
|
+
return isDarkMode
|
|
207
|
+
}
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
You can then use these hooks to theme stories and docs (see below).
|
|
211
|
+
|
|
212
|
+
#### Theming stories
|
|
213
|
+
|
|
214
|
+
You can use the hooks above with your `ThemeContext`:
|
|
215
|
+
|
|
216
|
+
```js
|
|
217
|
+
import { useIsDarkMode } from './hooks'; // the hook we defined above
|
|
184
218
|
// your theme provider
|
|
185
219
|
import ThemeContext from './theme';
|
|
186
220
|
|
|
187
|
-
//
|
|
188
|
-
const channel = addons.getChannel();
|
|
189
|
-
|
|
190
|
-
// create a component that listens for the DARK_MODE event
|
|
221
|
+
// create a component that uses the dark mode hook
|
|
191
222
|
function ThemeWrapper(props) {
|
|
192
|
-
|
|
193
|
-
const [isDark, setDark] = useState(false);
|
|
194
|
-
|
|
195
|
-
useEffect(() => {
|
|
196
|
-
// listen to DARK_MODE event
|
|
197
|
-
channel.on(DARK_MODE_EVENT_NAME, setDark);
|
|
198
|
-
return () => channel.off(DARK_MODE_EVENT_NAME, setDark);
|
|
199
|
-
}, [channel, setDark]);
|
|
223
|
+
const isDarkMode = useIsDarkMode();
|
|
200
224
|
|
|
201
225
|
// render your custom theme provider
|
|
202
226
|
return (
|
|
203
|
-
<ThemeContext.Provider value={
|
|
227
|
+
<ThemeContext.Provider value={isDarkMode ? darkTheme : defaultTheme}>
|
|
204
228
|
{props.children}
|
|
205
229
|
</ThemeContext.Provider>
|
|
206
230
|
);
|
|
207
231
|
}
|
|
208
232
|
|
|
209
|
-
export const decorators = [
|
|
233
|
+
export const decorators = [
|
|
234
|
+
(renderStory) => <ThemeWrapper>{renderStory()}</ThemeWrapper>,
|
|
235
|
+
];
|
|
210
236
|
```
|
|
211
237
|
|
|
238
|
+
Some UI libraries expose hooks for controlling the theme. E.g., if you are using Mantine, you can use this component:
|
|
239
|
+
|
|
240
|
+
```js
|
|
241
|
+
import { useOnDarkModeEvent } from './hooks'; // the hook we defined above
|
|
242
|
+
import { useMantineColorScheme } from '@mantine/core'
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* Custom story wrapper that handles Mantine's dark mode
|
|
246
|
+
**/
|
|
247
|
+
function ThemeWrapper({ children }: { children: React.ReactNode }) {
|
|
248
|
+
const { setColorScheme } = useMantineColorScheme()
|
|
249
|
+
const handleColorScheme = useCallback((value) => setColorScheme(value ? 'dark' : 'light'), [setColorScheme])
|
|
250
|
+
useOnDarkModeEvent(handleColorScheme)
|
|
251
|
+
|
|
252
|
+
return children
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
export const decorators = [
|
|
256
|
+
(renderStory) => <ThemeWrapper>{renderStory()}</ThemeWrapper>,
|
|
257
|
+
];
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
#### Theming docs
|
|
261
|
+
|
|
262
|
+
Docs have a dedicated container component which will _not_ be themed unless you explicitly configure it:
|
|
263
|
+
|
|
264
|
+
```js
|
|
265
|
+
import { useIsDarkMode } from './hooks'; // the hook we defined above
|
|
266
|
+
|
|
267
|
+
function ThemedDocsContainer(props) {
|
|
268
|
+
const isDarkMode = useIsDarkMode() // the hook we defined above
|
|
269
|
+
|
|
270
|
+
return (
|
|
271
|
+
<DocsContainer theme={isDarkMode ? themes.dark : themes.light} context={props.context}>
|
|
272
|
+
{props.children}
|
|
273
|
+
</DocsContainer>
|
|
274
|
+
)
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
export const parameters = {
|
|
278
|
+
docs: {
|
|
279
|
+
container: ThemedDocsContainer,
|
|
280
|
+
},
|
|
281
|
+
},
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
#### Emit event in docs mode
|
|
285
|
+
|
|
212
286
|
Since in docs mode, Storybook will not display its toolbar,
|
|
213
287
|
You can also trigger the `UPDATE_DARK_MODE` event via the addons channel if you want to control that option in docs mode,
|
|
214
288
|
By editing your `.storybook/preview.js`.
|
|
@@ -254,4 +328,4 @@ export const parameters = {
|
|
|
254
328
|
}
|
|
255
329
|
}
|
|
256
330
|
};
|
|
257
|
-
```
|
|
331
|
+
```
|