@vueless/storybook-dark-mode 10.0.1-beta.0 → 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/dist/index.js +2 -2
- package/dist/preset.js +3 -1
- package/package.json +30 -26
- package/preset.js +1 -0
- package/src/Tool.tsx +27 -27
- package/src/constants.ts +2 -2
- package/src/index.tsx +6 -5
- package/src/preset/manager.tsx +10 -10
- package/src/preset.ts +3 -1
- package/preset.ts +0 -2
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { useState, useEffect
|
|
2
|
-
import '
|
|
1
|
+
import { useState, useEffect } from 'react';
|
|
2
|
+
import { addons } from 'storybook/preview-api';
|
|
3
3
|
import { global } from '@storybook/global';
|
|
4
4
|
import { themes } from 'storybook/theming';
|
|
5
5
|
import 'storybook/internal/components';
|
package/dist/preset.js
CHANGED
package/package.json
CHANGED
|
@@ -1,28 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vueless/storybook-dark-mode",
|
|
3
|
-
"version": "10.0.1-beta.
|
|
3
|
+
"version": "10.0.1-beta.1",
|
|
4
4
|
"description": "Toggle between light and dark mode in Storybook",
|
|
5
|
-
"type": "module",
|
|
6
|
-
"exports": {
|
|
7
|
-
".": {
|
|
8
|
-
"types": "./dist/index.d.ts",
|
|
9
|
-
"default": "./dist/index.js"
|
|
10
|
-
},
|
|
11
|
-
"./preview": {
|
|
12
|
-
"types": "./dist/index.d.ts",
|
|
13
|
-
"default": "./dist/index.js"
|
|
14
|
-
},
|
|
15
|
-
"./preset": "./dist/preset.js",
|
|
16
|
-
"./manager": "./dist/manager.js",
|
|
17
|
-
"./package.json": "./package.json"
|
|
18
|
-
},
|
|
19
|
-
"main": "dist/index.js",
|
|
20
|
-
"types": "dist/index.d.ts",
|
|
21
|
-
"files": [
|
|
22
|
-
"src",
|
|
23
|
-
"dist",
|
|
24
|
-
"preset.ts"
|
|
25
|
-
],
|
|
26
5
|
"author": "Johnny Grid <hello@vueless.com> (https://vueless.com)",
|
|
27
6
|
"repository": {
|
|
28
7
|
"type": "git",
|
|
@@ -36,8 +15,8 @@
|
|
|
36
15
|
"prebuild": "npm run clean",
|
|
37
16
|
"build": "tsup",
|
|
38
17
|
"build:watch": "tsup --watch",
|
|
39
|
-
"lint": "eslint --no-fix
|
|
40
|
-
"lint:fix": "eslint --fix
|
|
18
|
+
"lint": "eslint --no-fix .",
|
|
19
|
+
"lint:fix": "eslint --fix .",
|
|
41
20
|
"lint:ci": "eslint --no-fix src/ --max-warnings=0",
|
|
42
21
|
"release:beta": "release-it --increment=prerelease --preRelease=beta --ci --no-git.tag --no-github.release",
|
|
43
22
|
"release:patch": "release-it patch --ci",
|
|
@@ -79,8 +58,29 @@
|
|
|
79
58
|
"vite": "^7.1.11"
|
|
80
59
|
},
|
|
81
60
|
"peerDependencies": {
|
|
82
|
-
"storybook": "^10.0.0"
|
|
61
|
+
"storybook": "^9.0.0 || ^10.0.0"
|
|
83
62
|
},
|
|
63
|
+
"type": "module",
|
|
64
|
+
"main": "dist/index.js",
|
|
65
|
+
"types": "dist/index.d.ts",
|
|
66
|
+
"exports": {
|
|
67
|
+
".": {
|
|
68
|
+
"types": "./dist/index.d.ts",
|
|
69
|
+
"default": "./dist/index.js"
|
|
70
|
+
},
|
|
71
|
+
"./preview": {
|
|
72
|
+
"types": "./dist/index.d.ts",
|
|
73
|
+
"default": "./dist/index.js"
|
|
74
|
+
},
|
|
75
|
+
"./preset": "./dist/preset.js",
|
|
76
|
+
"./manager": "./dist/manager.js",
|
|
77
|
+
"./package.json": "./package.json"
|
|
78
|
+
},
|
|
79
|
+
"files": [
|
|
80
|
+
"src",
|
|
81
|
+
"dist",
|
|
82
|
+
"preset.js"
|
|
83
|
+
],
|
|
84
84
|
"bundler": {
|
|
85
85
|
"managerEntries": [
|
|
86
86
|
"src/preset/manager.tsx"
|
|
@@ -100,6 +100,10 @@
|
|
|
100
100
|
},
|
|
101
101
|
"keywords": [
|
|
102
102
|
"storybook-addon",
|
|
103
|
-
"appearance"
|
|
103
|
+
"appearance",
|
|
104
|
+
"storybook",
|
|
105
|
+
"vueless",
|
|
106
|
+
"dark mode",
|
|
107
|
+
"color mode"
|
|
104
108
|
]
|
|
105
109
|
}
|
package/preset.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./dist/preset.js";
|
package/src/Tool.tsx
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import * as React from
|
|
2
|
-
import { global } from
|
|
3
|
-
import { themes, ThemeVars } from
|
|
4
|
-
import { IconButton } from
|
|
5
|
-
import { MoonIcon, SunIcon } from
|
|
6
|
-
import { STORY_CHANGED, SET_STORIES, DOCS_RENDERED } from
|
|
7
|
-
import { API, useParameter } from
|
|
8
|
-
import equal from
|
|
9
|
-
import { DARK_MODE_EVENT_NAME, UPDATE_DARK_MODE_EVENT_NAME } from
|
|
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";
|
|
10
10
|
|
|
11
11
|
const { document, window } = global as { document: Document; window: Window };
|
|
12
12
|
|
|
13
|
-
type Mode =
|
|
13
|
+
type Mode = "light" | "dark";
|
|
14
14
|
|
|
15
15
|
interface DarkModeStore {
|
|
16
16
|
/** The class target in the preview iframe */
|
|
@@ -31,16 +31,16 @@ interface DarkModeStore {
|
|
|
31
31
|
userHasExplicitlySetTheTheme: boolean;
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
const STORAGE_KEY =
|
|
34
|
+
const STORAGE_KEY = "sb-addon-themes-3";
|
|
35
35
|
|
|
36
|
-
export const prefersDark = window.matchMedia?.(
|
|
36
|
+
export const prefersDark = window.matchMedia?.("(prefers-color-scheme: dark)");
|
|
37
37
|
|
|
38
|
-
const defaultParams: Required<Omit<DarkModeStore,
|
|
39
|
-
classTarget:
|
|
38
|
+
const defaultParams: Required<Omit<DarkModeStore, "current">> = {
|
|
39
|
+
classTarget: "body",
|
|
40
40
|
dark: themes.dark,
|
|
41
|
-
darkClass: [
|
|
41
|
+
darkClass: ["dark"],
|
|
42
42
|
light: themes.light,
|
|
43
|
-
lightClass: [
|
|
43
|
+
lightClass: ["light"],
|
|
44
44
|
stylePreview: false,
|
|
45
45
|
userHasExplicitlySetTheTheme: false,
|
|
46
46
|
};
|
|
@@ -59,7 +59,7 @@ const toggleDarkClass = (
|
|
|
59
59
|
lightClass = defaultParams.lightClass,
|
|
60
60
|
}: DarkModeStore,
|
|
61
61
|
) => {
|
|
62
|
-
if (current ===
|
|
62
|
+
if (current === "dark") {
|
|
63
63
|
el.classList.remove(...arrayify(lightClass));
|
|
64
64
|
el.classList.add(...arrayify(darkClass));
|
|
65
65
|
} else {
|
|
@@ -77,7 +77,7 @@ const arrayify = (classes: string | string[]): string[] => {
|
|
|
77
77
|
|
|
78
78
|
/** Update the preview iframe class */
|
|
79
79
|
const updatePreview = (store: DarkModeStore) => {
|
|
80
|
-
const iframe = document.getElementById(
|
|
80
|
+
const iframe = document.getElementById("storybook-preview-iframe") as HTMLIFrameElement;
|
|
81
81
|
|
|
82
82
|
if (!iframe) {
|
|
83
83
|
return;
|
|
@@ -108,7 +108,7 @@ const updateManager = (store: DarkModeStore) => {
|
|
|
108
108
|
export const store = (userTheme: Partial<DarkModeStore> = {}): DarkModeStore => {
|
|
109
109
|
const storedItem = window.localStorage.getItem(STORAGE_KEY);
|
|
110
110
|
|
|
111
|
-
if (typeof storedItem ===
|
|
111
|
+
if (typeof storedItem === "string") {
|
|
112
112
|
const stored = JSON.parse(storedItem) as DarkModeStore;
|
|
113
113
|
|
|
114
114
|
if (userTheme) {
|
|
@@ -142,7 +142,7 @@ interface DarkModeProps {
|
|
|
142
142
|
/** A toolbar icon to toggle between dark and light themes in storybook */
|
|
143
143
|
export function DarkMode({ api }: DarkModeProps) {
|
|
144
144
|
const [isDark, setDark] = React.useState(prefersDark.matches);
|
|
145
|
-
const darkModeParams = useParameter<Partial<DarkModeStore>>(
|
|
145
|
+
const darkModeParams = useParameter<Partial<DarkModeStore>>("darkMode", {});
|
|
146
146
|
const { current: defaultMode, stylePreview, ...params } = darkModeParams;
|
|
147
147
|
const channel = api.getChannel();
|
|
148
148
|
// Save custom themes on init
|
|
@@ -156,8 +156,8 @@ export function DarkMode({ api }: DarkModeProps) {
|
|
|
156
156
|
const currentStore = store();
|
|
157
157
|
|
|
158
158
|
api.setOptions({ theme: currentStore[mode] });
|
|
159
|
-
setDark(mode ===
|
|
160
|
-
api.getChannel().emit(DARK_MODE_EVENT_NAME, mode ===
|
|
159
|
+
setDark(mode === "dark");
|
|
160
|
+
api.getChannel().emit(DARK_MODE_EVENT_NAME, mode === "dark");
|
|
161
161
|
updateManager(currentStore);
|
|
162
162
|
|
|
163
163
|
if (stylePreview) {
|
|
@@ -171,7 +171,7 @@ export function DarkMode({ api }: DarkModeProps) {
|
|
|
171
171
|
const updateMode = React.useCallback(
|
|
172
172
|
(mode?: Mode) => {
|
|
173
173
|
const currentStore = store();
|
|
174
|
-
const current = mode || (currentStore.current ===
|
|
174
|
+
const current = mode || (currentStore.current === "dark" ? "light" : "dark");
|
|
175
175
|
|
|
176
176
|
updateStore({ ...currentStore, current });
|
|
177
177
|
setMode(current);
|
|
@@ -185,12 +185,12 @@ export function DarkMode({ api }: DarkModeProps) {
|
|
|
185
185
|
return;
|
|
186
186
|
}
|
|
187
187
|
|
|
188
|
-
updateMode(event.matches ?
|
|
188
|
+
updateMode(event.matches ? "dark" : "light");
|
|
189
189
|
}
|
|
190
190
|
|
|
191
191
|
/** Render the current theme */
|
|
192
192
|
const renderTheme = React.useCallback(() => {
|
|
193
|
-
const { current =
|
|
193
|
+
const { current = "light" } = store();
|
|
194
194
|
|
|
195
195
|
setMode(current);
|
|
196
196
|
}, [setMode]);
|
|
@@ -247,14 +247,14 @@ export function DarkMode({ api }: DarkModeProps) {
|
|
|
247
247
|
if (defaultMode) {
|
|
248
248
|
updateMode(defaultMode);
|
|
249
249
|
} else if (prefersDark.matches) {
|
|
250
|
-
updateMode(
|
|
250
|
+
updateMode("dark");
|
|
251
251
|
}
|
|
252
252
|
}, [defaultMode, updateMode, userHasExplicitlySetTheTheme]);
|
|
253
253
|
|
|
254
254
|
return (
|
|
255
255
|
<IconButton
|
|
256
256
|
key="dark-mode"
|
|
257
|
-
title={isDark ?
|
|
257
|
+
title={isDark ? "Change theme to light mode" : "Change theme to dark mode"}
|
|
258
258
|
onClick={handleIconClick}
|
|
259
259
|
>
|
|
260
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 =
|
|
2
|
-
export const UPDATE_DARK_MODE_EVENT_NAME =
|
|
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,12 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
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 ===
|
|
10
|
+
const [isDark, setIsDark] = useState(() => store().current === "dark");
|
|
10
11
|
|
|
11
12
|
useEffect(() => {
|
|
12
13
|
const chan = addons.getChannel();
|
|
@@ -19,4 +20,4 @@ export function useDarkMode(): boolean {
|
|
|
19
20
|
return isDark;
|
|
20
21
|
}
|
|
21
22
|
|
|
22
|
-
export * from
|
|
23
|
+
export * from "./constants";
|
package/src/preset/manager.tsx
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { addons } from
|
|
2
|
-
import { Addon_TypesEnum } from
|
|
3
|
-
import { themes } from
|
|
4
|
-
import * as React from
|
|
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
|
|
6
|
+
import Tool, { prefersDark, store } from "../Tool";
|
|
7
7
|
|
|
8
8
|
const currentStore = store();
|
|
9
|
-
const currentTheme = currentStore.current || (prefersDark.matches &&
|
|
9
|
+
const currentTheme = currentStore.current || (prefersDark.matches && "dark") || "light";
|
|
10
10
|
|
|
11
11
|
addons.setConfig({
|
|
12
12
|
theme: {
|
|
@@ -15,11 +15,11 @@ addons.setConfig({
|
|
|
15
15
|
},
|
|
16
16
|
});
|
|
17
17
|
|
|
18
|
-
addons.register(
|
|
19
|
-
addons.add(
|
|
20
|
-
title:
|
|
18
|
+
addons.register("storybook/dark-mode", (api) => {
|
|
19
|
+
addons.add("storybook/dark-mode", {
|
|
20
|
+
title: "dark mode",
|
|
21
21
|
type: Addon_TypesEnum.TOOL,
|
|
22
|
-
match: ({ viewMode }) => viewMode ===
|
|
22
|
+
match: ({ viewMode }) => viewMode === "story" || viewMode === "docs",
|
|
23
23
|
render: () => <Tool api={api} />,
|
|
24
24
|
});
|
|
25
25
|
});
|
package/src/preset.ts
CHANGED
package/preset.ts
DELETED