@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.
Files changed (2) hide show
  1. package/README.md +90 -16
  2. 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
- // get channel to listen to event emitter
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
- // this example uses hook but you can also use class component as well
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={isDark ? darkTheme : defaultTheme}>
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 = [renderStory => <ThemeWrapper>{renderStory()}</ThemeWrapper>];
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
+ ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vueless/storybook-dark-mode",
3
- "version": "9.0.6",
3
+ "version": "9.0.7",
4
4
  "description": "Toggle between light and dark mode in Storybook",
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/esm/index.js",