storybook-dark-mode
一個 Storybook 附加元件,讓使用者可以在深色和淺色模式之間切換。
安裝
安裝下列 npm 模組
npm i --save-dev storybook-dark-mode
或使用 yarn
yarn add -D storybook-dark-mode
然後,將以下內容新增至 .storybook/main.js
module.exports = {
addons: ['storybook-dark-mode']
};
設定
將以下內容新增至 .storybook/preview.js
檔案來設定深色和淺色模式
import { themes } from '@storybook/theming';
export parameters = {
darkMode: {
// Override the default dark theme
dark: { ...themes.dark, appBg: 'black' },
// Override the default light theme
light: { ...themes.normal, appBg: 'red' }
}
};
預設主題
初始色彩配置的優先順序
- 如果使用者先前設定了色彩主題,則會使用該主題
- 您在 Storybook 中為
current
參數設定的值 - 作業系統的色彩配置偏好設定
一旦設定了初始色彩配置,後續的重新載入將會使用此值。若要清除快取的色彩配置,您必須在 Chrome 控制台中執行 localStorage.clear()
。
export parameters = {
darkMode: {
// Set the initial theme
current: 'light'
}
};
深色/淺色類別
此外掛程式會將深色和淺色類別名稱套用至管理器。這讓您可以輕鬆地為 Storybook UI 撰寫支援深色模式的主題覆寫。
您可以使用 darkClass
和 lightClass
參數覆寫在淺色和深色模式之間切換時套用的類別名稱。
export parameters = {
darkMode: {
darkClass: 'lights-out',
lightClass: 'lights-on'
}
};
預覽類別目標
此外掛程式會將深色/淺色類別套用至預覽 iframe 的 <body>
元素。這可以使用 classTarget
參數進行設定。此值將傳遞至 iframe 內的 querySelector()
。
如果 <body>
是根據父系的類別進行樣式設定,則這很有用,在這種情況下,可以將其設定為 html
。
export parameters = {
darkMode: {
classTarget: 'html'
}
}
Story 整合
預覽類別名稱
如果您開啟 stylePreview
選項,則此外掛程式會將 darkClass
和 lightClass
類別套用至預覽 iframe。
export parameters = {
darkMode: {
stylePreview: true
}
};
React
如果您的元件使用自訂主題供應器,您可以使用提供的 Hook 進行整合。
import { useDarkMode } from 'storybook-dark-mode';
import { addDecorator } from '@storybook/react';
// your theme provider
import ThemeContext from './theme';
// create a component that uses the dark mode hook
function ThemeWrapper(props) {
// render your custom theme provider
return (
<ThemeContext.Provider value={useDarkMode() ? darkTheme : defaultTheme}>
{props.children}
</ThemeContext.Provider>
);
}
export const decorators = [renderStory => <ThemeWrapper>{renderStory()}</ThemeWrapper>)];
主題旋鈕
如果您想要讓 UI 的深色模式與元件的深色模式分開,請實作此全域裝飾器
import { themes } from '@storybook/theming';
// Add a global decorator that will render a dark background when the
// "Color Scheme" knob is set to dark
const knobDecorator = (storyFn) => {
// A knob for color scheme added to every story
const colorScheme = select('Color Scheme', ['light', 'dark'], 'light');
// Hook your theme provider with some knobs
return React.createElement(ThemeProvider, {
// A knob for theme added to every story
theme: select('Theme', Object.keys(themes), 'default'),
colorScheme,
children: [
React.createElement('style', {
dangerouslySetInnerHTML: {
__html: `html { ${
colorScheme === 'dark' ? 'background-color: rgb(35,35,35);' : ''
} }`
}
}),
storyFn()
]
});
}
export const decorators = [knobDecorator];
事件
您也可以透過附加元件通道監聽 DARK_MODE
事件。
import addons from '@storybook/addons';
import { addDecorator } from '@storybook/react';
// your theme provider
import ThemeContext from './theme';
// get channel to listen to event emitter
const channel = addons.getChannel();
// create a component that listens for the DARK_MODE event
function ThemeWrapper(props) {
// this example uses hook but you can also use class component as well
const [isDark, setDark] = useState(false);
useEffect(() => {
// listen to DARK_MODE event
channel.on('DARK_MODE', setDark);
return () => channel.off('DARK_MODE', setDark);
}, [channel, setDark]);
// render your custom theme provider
return (
<ThemeContext.Provider value={isDark ? darkTheme : defaultTheme}>
{props.children}
</ThemeContext.Provider>
);
}
export const decorators = [renderStory => <ThemeWrapper>{renderStory()}</ThemeWrapper>)];
貢獻者 ✨
感謝這些出色的人士 ( 表情符號鍵)
此專案遵循 all-contributors 規格。歡迎任何形式的貢獻!