@vueless/storybook-dark-mode 9.0.10 → 10.0.1-beta.1

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/src/Tool.tsx CHANGED
@@ -1,20 +1,16 @@
1
- import * as React from 'react';
2
- import { global } from '@storybook/global';
3
- import { themes, ThemeVars } from 'storybook/theming';
4
- import { IconButton } from 'storybook/internal/components';
5
- import { MoonIcon, SunIcon } from '@storybook/icons';
6
- import {
7
- STORY_CHANGED,
8
- SET_STORIES,
9
- DOCS_RENDERED,
10
- } from 'storybook/internal/core-events';
11
- import { API, useParameter } from 'storybook/manager-api';
12
- import equal from 'fast-deep-equal';
13
- import { DARK_MODE_EVENT_NAME, UPDATE_DARK_MODE_EVENT_NAME } from './constants';
1
+ import * as React from "react";
2
+ import { global } from "@storybook/global";
3
+ import { themes, ThemeVars } from "storybook/theming";
4
+ import { IconButton } from "storybook/internal/components";
5
+ import { MoonIcon, SunIcon } from "@storybook/icons";
6
+ import { STORY_CHANGED, SET_STORIES, DOCS_RENDERED } from "storybook/internal/core-events";
7
+ import { API, useParameter } from "storybook/manager-api";
8
+ import equal from "fast-deep-equal";
9
+ import { DARK_MODE_EVENT_NAME, UPDATE_DARK_MODE_EVENT_NAME } from "./constants";
14
10
 
15
11
  const { document, window } = global as { document: Document; window: Window };
16
- const modes = ['light', 'dark'] as const;
17
- type Mode = typeof modes[number];
12
+
13
+ type Mode = "light" | "dark";
18
14
 
19
15
  interface DarkModeStore {
20
16
  /** The class target in the preview iframe */
@@ -35,15 +31,16 @@ interface DarkModeStore {
35
31
  userHasExplicitlySetTheTheme: boolean;
36
32
  }
37
33
 
38
- const STORAGE_KEY = 'sb-addon-themes-3';
39
- export const prefersDark = window.matchMedia?.('(prefers-color-scheme: dark)');
34
+ const STORAGE_KEY = "sb-addon-themes-3";
35
+
36
+ export const prefersDark = window.matchMedia?.("(prefers-color-scheme: dark)");
40
37
 
41
- const defaultParams: Required<Omit<DarkModeStore, 'current'>> = {
42
- classTarget: 'body',
38
+ const defaultParams: Required<Omit<DarkModeStore, "current">> = {
39
+ classTarget: "body",
43
40
  dark: themes.dark,
44
- darkClass: ['dark'],
41
+ darkClass: ["dark"],
45
42
  light: themes.light,
46
- lightClass: ['light'],
43
+ lightClass: ["light"],
47
44
  stylePreview: false,
48
45
  userHasExplicitlySetTheTheme: false,
49
46
  };
@@ -60,9 +57,9 @@ const toggleDarkClass = (
60
57
  current,
61
58
  darkClass = defaultParams.darkClass,
62
59
  lightClass = defaultParams.lightClass,
63
- }: DarkModeStore
60
+ }: DarkModeStore,
64
61
  ) => {
65
- if (current === 'dark') {
62
+ if (current === "dark") {
66
63
  el.classList.remove(...arrayify(lightClass));
67
64
  el.classList.add(...arrayify(darkClass));
68
65
  } else {
@@ -74,21 +71,19 @@ const toggleDarkClass = (
74
71
  /** Coerce a string to a single item array, or return an array as-is */
75
72
  const arrayify = (classes: string | string[]): string[] => {
76
73
  const arr: string[] = [];
74
+
77
75
  return arr.concat(classes).map((item) => item);
78
76
  };
79
77
 
80
78
  /** Update the preview iframe class */
81
79
  const updatePreview = (store: DarkModeStore) => {
82
- const iframe = document.getElementById(
83
- 'storybook-preview-iframe'
84
- ) as HTMLIFrameElement;
80
+ const iframe = document.getElementById("storybook-preview-iframe") as HTMLIFrameElement;
85
81
 
86
82
  if (!iframe) {
87
83
  return;
88
84
  }
89
85
 
90
- const iframeDocument =
91
- iframe.contentDocument || iframe.contentWindow?.document;
86
+ const iframeDocument = iframe.contentDocument || iframe.contentWindow?.document;
92
87
  const target = iframeDocument?.querySelector<HTMLElement>(store.classTarget);
93
88
 
94
89
  if (!target) {
@@ -110,12 +105,10 @@ const updateManager = (store: DarkModeStore) => {
110
105
  };
111
106
 
112
107
  /** Update changed dark mode settings and persist to localStorage */
113
- export const store = (
114
- userTheme: Partial<DarkModeStore> = {}
115
- ): DarkModeStore => {
108
+ export const store = (userTheme: Partial<DarkModeStore> = {}): DarkModeStore => {
116
109
  const storedItem = window.localStorage.getItem(STORAGE_KEY);
117
110
 
118
- if (typeof storedItem === 'string') {
111
+ if (typeof storedItem === "string") {
119
112
  const stored = JSON.parse(storedItem) as DarkModeStore;
120
113
 
121
114
  if (userTheme) {
@@ -149,39 +142,41 @@ interface DarkModeProps {
149
142
  /** A toolbar icon to toggle between dark and light themes in storybook */
150
143
  export function DarkMode({ api }: DarkModeProps) {
151
144
  const [isDark, setDark] = React.useState(prefersDark.matches);
152
- const darkModeParams = useParameter<Partial<DarkModeStore>>('darkMode', {});
145
+ const darkModeParams = useParameter<Partial<DarkModeStore>>("darkMode", {});
153
146
  const { current: defaultMode, stylePreview, ...params } = darkModeParams;
154
147
  const channel = api.getChannel();
155
148
  // Save custom themes on init
156
149
  const userHasExplicitlySetTheTheme = React.useMemo(
157
150
  () => store(params).userHasExplicitlySetTheTheme,
158
- [params]
151
+ [params],
159
152
  );
160
153
  /** Set the theme in storybook, update the local state, and emit an event */
161
154
  const setMode = React.useCallback(
162
155
  (mode: Mode) => {
163
156
  const currentStore = store();
157
+
164
158
  api.setOptions({ theme: currentStore[mode] });
165
- setDark(mode === 'dark');
166
- api.getChannel().emit(DARK_MODE_EVENT_NAME, mode === 'dark');
159
+ setDark(mode === "dark");
160
+ api.getChannel().emit(DARK_MODE_EVENT_NAME, mode === "dark");
167
161
  updateManager(currentStore);
162
+
168
163
  if (stylePreview) {
169
164
  updatePreview(currentStore);
170
165
  }
171
166
  },
172
- [api, stylePreview]
167
+ [api, stylePreview],
173
168
  );
174
169
 
175
170
  /** Update the theme settings in localStorage, react, and storybook */
176
171
  const updateMode = React.useCallback(
177
172
  (mode?: Mode) => {
178
173
  const currentStore = store();
179
- const current =
180
- mode || (currentStore.current === 'dark' ? 'light' : 'dark');
174
+ const current = mode || (currentStore.current === "dark" ? "light" : "dark");
175
+
181
176
  updateStore({ ...currentStore, current });
182
177
  setMode(current);
183
178
  },
184
- [setMode]
179
+ [setMode],
185
180
  );
186
181
 
187
182
  /** Update the theme based on the color preference */
@@ -190,12 +185,13 @@ export function DarkMode({ api }: DarkModeProps) {
190
185
  return;
191
186
  }
192
187
 
193
- updateMode(event.matches ? 'dark' : 'light');
188
+ updateMode(event.matches ? "dark" : "light");
194
189
  }
195
190
 
196
191
  /** Render the current theme */
197
192
  const renderTheme = React.useCallback(() => {
198
- const { current = 'light' } = store();
193
+ const { current = "light" } = store();
194
+
199
195
  setMode(current);
200
196
  }, [setMode]);
201
197
 
@@ -203,12 +199,14 @@ export function DarkMode({ api }: DarkModeProps) {
203
199
  const handleIconClick = () => {
204
200
  updateMode();
205
201
  const currentStore = store();
202
+
206
203
  updateStore({ ...currentStore, userHasExplicitlySetTheTheme: true });
207
204
  };
208
205
 
209
206
  /** When storybook params change update the stored themes */
210
207
  React.useEffect(() => {
211
208
  const currentStore = store();
209
+
212
210
  // Ensure we use the stores `current` value first to persist
213
211
  // themeing between page loads and story changes.
214
212
  updateStore({
@@ -223,6 +221,7 @@ export function DarkMode({ api }: DarkModeProps) {
223
221
  channel.on(SET_STORIES, renderTheme);
224
222
  channel.on(DOCS_RENDERED, renderTheme);
225
223
  prefersDark.addListener(prefersDarkUpdate);
224
+
226
225
  return () => {
227
226
  channel.removeListener(STORY_CHANGED, renderTheme);
228
227
  channel.removeListener(SET_STORIES, renderTheme);
@@ -232,6 +231,7 @@ export function DarkMode({ api }: DarkModeProps) {
232
231
  });
233
232
  React.useEffect(() => {
234
233
  channel.on(UPDATE_DARK_MODE_EVENT_NAME, updateMode);
234
+
235
235
  return () => {
236
236
  channel.removeListener(UPDATE_DARK_MODE_EVENT_NAME, updateMode);
237
237
  };
@@ -247,15 +247,14 @@ export function DarkMode({ api }: DarkModeProps) {
247
247
  if (defaultMode) {
248
248
  updateMode(defaultMode);
249
249
  } else if (prefersDark.matches) {
250
- updateMode('dark');
250
+ updateMode("dark");
251
251
  }
252
252
  }, [defaultMode, updateMode, userHasExplicitlySetTheTheme]);
253
+
253
254
  return (
254
255
  <IconButton
255
256
  key="dark-mode"
256
- title={
257
- isDark ? 'Change theme to light mode' : 'Change theme to dark mode'
258
- }
257
+ title={isDark ? "Change theme to light mode" : "Change theme to dark mode"}
259
258
  onClick={handleIconClick}
260
259
  >
261
260
  {isDark ? <SunIcon aria-hidden="true" /> : <MoonIcon aria-hidden="true" />}
package/src/constants.ts CHANGED
@@ -1,2 +1,2 @@
1
- export const DARK_MODE_EVENT_NAME = 'DARK_MODE';
2
- export const UPDATE_DARK_MODE_EVENT_NAME = 'UPDATE_DARK_MODE';
1
+ export const DARK_MODE_EVENT_NAME = "DARK_MODE";
2
+ export const UPDATE_DARK_MODE_EVENT_NAME = "UPDATE_DARK_MODE";
package/src/index.tsx CHANGED
@@ -1,20 +1,23 @@
1
- import { addons, useState, useEffect } from 'storybook/preview-api';
2
- import { DARK_MODE_EVENT_NAME } from './constants';
3
- import { store } from './Tool';
1
+ import { useState, useEffect } from "react";
2
+ import { addons } from "storybook/preview-api";
3
+ import { DARK_MODE_EVENT_NAME } from "./constants";
4
+ import { store } from "./Tool";
4
5
 
5
6
  /**
6
7
  * Returns the current state of storybook's dark-mode
7
8
  */
8
9
  export function useDarkMode(): boolean {
9
- const [isDark, setIsDark] = useState(() => store().current === 'dark');
10
+ const [isDark, setIsDark] = useState(() => store().current === "dark");
10
11
 
11
12
  useEffect(() => {
12
13
  const chan = addons.getChannel();
14
+
13
15
  chan.on(DARK_MODE_EVENT_NAME, setIsDark);
16
+
14
17
  return () => chan.off(DARK_MODE_EVENT_NAME, setIsDark);
15
18
  }, []);
16
19
 
17
20
  return isDark;
18
21
  }
19
22
 
20
- export * from './constants';
23
+ export * from "./constants";
@@ -1,13 +1,12 @@
1
- import { addons } from 'storybook/manager-api';
2
- import { Addon_TypesEnum } from 'storybook/internal/types';
3
- import { themes } from 'storybook/theming';
4
- import * as React from 'react';
1
+ import { addons } from "storybook/manager-api";
2
+ import { Addon_TypesEnum } from "storybook/internal/types";
3
+ import { themes } from "storybook/theming";
4
+ import * as React from "react";
5
5
 
6
- import Tool, { prefersDark, store } from '../Tool';
6
+ import Tool, { prefersDark, store } from "../Tool";
7
7
 
8
8
  const currentStore = store();
9
- const currentTheme =
10
- currentStore.current || (prefersDark.matches && 'dark') || 'light';
9
+ const currentTheme = currentStore.current || (prefersDark.matches && "dark") || "light";
11
10
 
12
11
  addons.setConfig({
13
12
  theme: {
@@ -16,11 +15,11 @@ addons.setConfig({
16
15
  },
17
16
  });
18
17
 
19
- addons.register('storybook/dark-mode', (api) => {
20
- addons.add('storybook/dark-mode', {
21
- title: 'dark mode',
18
+ addons.register("storybook/dark-mode", (api) => {
19
+ addons.add("storybook/dark-mode", {
20
+ title: "dark mode",
22
21
  type: Addon_TypesEnum.TOOL,
23
- match: ({ viewMode }) => viewMode === 'story' || viewMode === 'docs',
22
+ match: ({ viewMode }) => viewMode === "story" || viewMode === "docs",
24
23
  render: () => <Tool api={api} />,
25
24
  });
26
25
  });
package/src/preset.ts ADDED
@@ -0,0 +1,5 @@
1
+ import { fileURLToPath } from "node:url";
2
+
3
+ export function managerEntries(entry: string[] = []) {
4
+ return [...entry, fileURLToPath(import.meta.resolve("./manager"))];
5
+ }
package/dist/cjs/Tool.js DELETED
@@ -1,251 +0,0 @@
1
- "use strict";
2
-
3
- function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
4
- Object.defineProperty(exports, "__esModule", {
5
- value: true
6
- });
7
- exports.DarkMode = DarkMode;
8
- exports.updateStore = exports.store = exports.prefersDark = exports["default"] = void 0;
9
- var React = _interopRequireWildcard(require("react"));
10
- var _global = require("@storybook/global");
11
- var _theming = require("storybook/theming");
12
- var _components = require("storybook/internal/components");
13
- var _icons = require("@storybook/icons");
14
- var _coreEvents = require("storybook/internal/core-events");
15
- var _managerApi = require("storybook/manager-api");
16
- var _fastDeepEqual = _interopRequireDefault(require("fast-deep-equal"));
17
- var _constants = require("./constants");
18
- var _excluded = ["current", "stylePreview"];
19
- var _window$matchMedia;
20
- function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
21
- function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, "default": e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
22
- function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; }
23
- function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
24
- function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
25
- function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
26
- function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
27
- function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
28
- function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
29
- function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
30
- function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
31
- function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
32
- function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
33
- function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); }
34
- function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
35
- function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
36
- function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); }
37
- function _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); }
38
- function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
39
- var _ref = _global.global,
40
- document = _ref.document,
41
- window = _ref.window;
42
- var modes = ['light', 'dark'];
43
- var STORAGE_KEY = 'sb-addon-themes-3';
44
- var prefersDark = exports.prefersDark = (_window$matchMedia = window.matchMedia) === null || _window$matchMedia === void 0 ? void 0 : _window$matchMedia.call(window, '(prefers-color-scheme: dark)');
45
- var defaultParams = {
46
- classTarget: 'body',
47
- dark: _theming.themes.dark,
48
- darkClass: ['dark'],
49
- light: _theming.themes.light,
50
- lightClass: ['light'],
51
- stylePreview: false,
52
- userHasExplicitlySetTheTheme: false
53
- };
54
-
55
- /** Persist the dark mode settings in localStorage */
56
- var updateStore = exports.updateStore = function updateStore(newStore) {
57
- window.localStorage.setItem(STORAGE_KEY, JSON.stringify(newStore));
58
- };
59
-
60
- /** Add the light/dark class to an element */
61
- var toggleDarkClass = function toggleDarkClass(el, _ref2) {
62
- var current = _ref2.current,
63
- _ref2$darkClass = _ref2.darkClass,
64
- darkClass = _ref2$darkClass === void 0 ? defaultParams.darkClass : _ref2$darkClass,
65
- _ref2$lightClass = _ref2.lightClass,
66
- lightClass = _ref2$lightClass === void 0 ? defaultParams.lightClass : _ref2$lightClass;
67
- if (current === 'dark') {
68
- var _el$classList, _el$classList2;
69
- (_el$classList = el.classList).remove.apply(_el$classList, _toConsumableArray(arrayify(lightClass)));
70
- (_el$classList2 = el.classList).add.apply(_el$classList2, _toConsumableArray(arrayify(darkClass)));
71
- } else {
72
- var _el$classList3, _el$classList4;
73
- (_el$classList3 = el.classList).remove.apply(_el$classList3, _toConsumableArray(arrayify(darkClass)));
74
- (_el$classList4 = el.classList).add.apply(_el$classList4, _toConsumableArray(arrayify(lightClass)));
75
- }
76
- };
77
-
78
- /** Coerce a string to a single item array, or return an array as-is */
79
- var arrayify = function arrayify(classes) {
80
- var arr = [];
81
- return arr.concat(classes).map(function (item) {
82
- return item;
83
- });
84
- };
85
-
86
- /** Update the preview iframe class */
87
- var updatePreview = function updatePreview(store) {
88
- var _iframe$contentWindow;
89
- var iframe = document.getElementById('storybook-preview-iframe');
90
- if (!iframe) {
91
- return;
92
- }
93
- var iframeDocument = iframe.contentDocument || ((_iframe$contentWindow = iframe.contentWindow) === null || _iframe$contentWindow === void 0 ? void 0 : _iframe$contentWindow.document);
94
- var target = iframeDocument === null || iframeDocument === void 0 ? void 0 : iframeDocument.querySelector(store.classTarget);
95
- if (!target) {
96
- return;
97
- }
98
- toggleDarkClass(target, store);
99
- };
100
-
101
- /** Update the manager iframe class */
102
- var updateManager = function updateManager(store) {
103
- var manager = document.querySelector(store.classTarget);
104
- if (!manager) {
105
- return;
106
- }
107
- toggleDarkClass(manager, store);
108
- };
109
-
110
- /** Update changed dark mode settings and persist to localStorage */
111
- var store = exports.store = function store() {
112
- var userTheme = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
113
- var storedItem = window.localStorage.getItem(STORAGE_KEY);
114
- if (typeof storedItem === 'string') {
115
- var stored = JSON.parse(storedItem);
116
- if (userTheme) {
117
- if (userTheme.dark && !(0, _fastDeepEqual["default"])(stored.dark, userTheme.dark)) {
118
- stored.dark = userTheme.dark;
119
- updateStore(stored);
120
- }
121
- if (userTheme.light && !(0, _fastDeepEqual["default"])(stored.light, userTheme.light)) {
122
- stored.light = userTheme.light;
123
- updateStore(stored);
124
- }
125
- }
126
- return stored;
127
- }
128
- return _objectSpread(_objectSpread({}, defaultParams), userTheme);
129
- };
130
-
131
- // On initial load, set the dark mode class on the manager
132
- // This is needed if you're using mostly CSS overrides to styles the storybook
133
- // Otherwise the default theme is set in src/preset/manager.tsx
134
- updateManager(store());
135
- /** A toolbar icon to toggle between dark and light themes in storybook */
136
- function DarkMode(_ref3) {
137
- var api = _ref3.api;
138
- var _React$useState = React.useState(prefersDark.matches),
139
- _React$useState2 = _slicedToArray(_React$useState, 2),
140
- isDark = _React$useState2[0],
141
- setDark = _React$useState2[1];
142
- var darkModeParams = (0, _managerApi.useParameter)('darkMode', {});
143
- var defaultMode = darkModeParams.current,
144
- stylePreview = darkModeParams.stylePreview,
145
- params = _objectWithoutProperties(darkModeParams, _excluded);
146
- var channel = api.getChannel();
147
- // Save custom themes on init
148
- var userHasExplicitlySetTheTheme = React.useMemo(function () {
149
- return store(params).userHasExplicitlySetTheTheme;
150
- }, [params]);
151
- /** Set the theme in storybook, update the local state, and emit an event */
152
- var setMode = React.useCallback(function (mode) {
153
- var currentStore = store();
154
- api.setOptions({
155
- theme: currentStore[mode]
156
- });
157
- setDark(mode === 'dark');
158
- api.getChannel().emit(_constants.DARK_MODE_EVENT_NAME, mode === 'dark');
159
- updateManager(currentStore);
160
- if (stylePreview) {
161
- updatePreview(currentStore);
162
- }
163
- }, [api, stylePreview]);
164
-
165
- /** Update the theme settings in localStorage, react, and storybook */
166
- var updateMode = React.useCallback(function (mode) {
167
- var currentStore = store();
168
- var current = mode || (currentStore.current === 'dark' ? 'light' : 'dark');
169
- updateStore(_objectSpread(_objectSpread({}, currentStore), {}, {
170
- current: current
171
- }));
172
- setMode(current);
173
- }, [setMode]);
174
-
175
- /** Update the theme based on the color preference */
176
- function prefersDarkUpdate(event) {
177
- if (userHasExplicitlySetTheTheme || defaultMode) {
178
- return;
179
- }
180
- updateMode(event.matches ? 'dark' : 'light');
181
- }
182
-
183
- /** Render the current theme */
184
- var renderTheme = React.useCallback(function () {
185
- var _store = store(),
186
- _store$current = _store.current,
187
- current = _store$current === void 0 ? 'light' : _store$current;
188
- setMode(current);
189
- }, [setMode]);
190
-
191
- /** Handle the user event and side effects */
192
- var handleIconClick = function handleIconClick() {
193
- updateMode();
194
- var currentStore = store();
195
- updateStore(_objectSpread(_objectSpread({}, currentStore), {}, {
196
- userHasExplicitlySetTheTheme: true
197
- }));
198
- };
199
-
200
- /** When storybook params change update the stored themes */
201
- React.useEffect(function () {
202
- var currentStore = store();
203
- // Ensure we use the stores `current` value first to persist
204
- // themeing between page loads and story changes.
205
- updateStore(_objectSpread(_objectSpread(_objectSpread({}, currentStore), darkModeParams), {}, {
206
- current: currentStore.current || darkModeParams.current
207
- }));
208
- renderTheme();
209
- }, [darkModeParams, renderTheme]);
210
- React.useEffect(function () {
211
- channel.on(_coreEvents.STORY_CHANGED, renderTheme);
212
- channel.on(_coreEvents.SET_STORIES, renderTheme);
213
- channel.on(_coreEvents.DOCS_RENDERED, renderTheme);
214
- prefersDark.addListener(prefersDarkUpdate);
215
- return function () {
216
- channel.removeListener(_coreEvents.STORY_CHANGED, renderTheme);
217
- channel.removeListener(_coreEvents.SET_STORIES, renderTheme);
218
- channel.removeListener(_coreEvents.DOCS_RENDERED, renderTheme);
219
- prefersDark.removeListener(prefersDarkUpdate);
220
- };
221
- });
222
- React.useEffect(function () {
223
- channel.on(_constants.UPDATE_DARK_MODE_EVENT_NAME, updateMode);
224
- return function () {
225
- channel.removeListener(_constants.UPDATE_DARK_MODE_EVENT_NAME, updateMode);
226
- };
227
- });
228
- // Storybook's first render doesn't have the global user params loaded so we
229
- // need the effect to run whenever defaultMode is updated
230
- React.useEffect(function () {
231
- // If a users has set the mode this is respected
232
- if (userHasExplicitlySetTheTheme) {
233
- return;
234
- }
235
- if (defaultMode) {
236
- updateMode(defaultMode);
237
- } else if (prefersDark.matches) {
238
- updateMode('dark');
239
- }
240
- }, [defaultMode, updateMode, userHasExplicitlySetTheTheme]);
241
- return /*#__PURE__*/React.createElement(_components.IconButton, {
242
- key: "dark-mode",
243
- title: isDark ? 'Change theme to light mode' : 'Change theme to dark mode',
244
- onClick: handleIconClick
245
- }, isDark ? /*#__PURE__*/React.createElement(_icons.SunIcon, {
246
- "aria-hidden": "true"
247
- }) : /*#__PURE__*/React.createElement(_icons.MoonIcon, {
248
- "aria-hidden": "true"
249
- }));
250
- }
251
- var _default = exports["default"] = DarkMode;
@@ -1,8 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.UPDATE_DARK_MODE_EVENT_NAME = exports.DARK_MODE_EVENT_NAME = void 0;
7
- var DARK_MODE_EVENT_NAME = exports.DARK_MODE_EVENT_NAME = 'DARK_MODE';
8
- var UPDATE_DARK_MODE_EVENT_NAME = exports.UPDATE_DARK_MODE_EVENT_NAME = 'UPDATE_DARK_MODE';
package/dist/cjs/index.js DELETED
@@ -1,48 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- var _exportNames = {
7
- useDarkMode: true
8
- };
9
- exports.useDarkMode = useDarkMode;
10
- var _previewApi = require("storybook/preview-api");
11
- var _constants = require("./constants");
12
- Object.keys(_constants).forEach(function (key) {
13
- if (key === "default" || key === "__esModule") return;
14
- if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
15
- if (key in exports && exports[key] === _constants[key]) return;
16
- Object.defineProperty(exports, key, {
17
- enumerable: true,
18
- get: function get() {
19
- return _constants[key];
20
- }
21
- });
22
- });
23
- var _Tool = require("./Tool");
24
- function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
25
- function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
26
- function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
27
- function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
28
- function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
29
- function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
30
- /**
31
- * Returns the current state of storybook's dark-mode
32
- */
33
- function useDarkMode() {
34
- var _useState = (0, _previewApi.useState)(function () {
35
- return (0, _Tool.store)().current === 'dark';
36
- }),
37
- _useState2 = _slicedToArray(_useState, 2),
38
- isDark = _useState2[0],
39
- setIsDark = _useState2[1];
40
- (0, _previewApi.useEffect)(function () {
41
- var chan = _previewApi.addons.getChannel();
42
- chan.on(_constants.DARK_MODE_EVENT_NAME, setIsDark);
43
- return function () {
44
- return chan.off(_constants.DARK_MODE_EVENT_NAME, setIsDark);
45
- };
46
- }, []);
47
- return isDark;
48
- }
@@ -1,34 +0,0 @@
1
- "use strict";
2
-
3
- var _managerApi = require("storybook/manager-api");
4
- var _types = require("storybook/internal/types");
5
- var _theming = require("storybook/theming");
6
- var React = _interopRequireWildcard(require("react"));
7
- var _Tool = _interopRequireWildcard(require("../Tool"));
8
- function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, "default": e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
9
- function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
10
- function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
11
- function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
12
- function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
13
- function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
14
- function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
15
- var currentStore = (0, _Tool.store)();
16
- var currentTheme = currentStore.current || _Tool.prefersDark.matches && 'dark' || 'light';
17
- _managerApi.addons.setConfig({
18
- theme: _objectSpread(_objectSpread({}, _theming.themes[currentTheme]), currentStore[currentTheme])
19
- });
20
- _managerApi.addons.register('storybook/dark-mode', function (api) {
21
- _managerApi.addons.add('storybook/dark-mode', {
22
- title: 'dark mode',
23
- type: _types.Addon_TypesEnum.TOOL,
24
- match: function match(_ref) {
25
- var viewMode = _ref.viewMode;
26
- return viewMode === 'story' || viewMode === 'docs';
27
- },
28
- render: function render() {
29
- return /*#__PURE__*/React.createElement(_Tool["default"], {
30
- api: api
31
- });
32
- }
33
- });
34
- });