Storybook 附加元件主題切換
這個附加元件的靈感來自 @storybook/addon-backgrounds
和 storybook-addon-themes
,並建立了更流暢且功能更豐富的實作。另請參閱 storybook-addon-background-toggle
。
這個附加元件可用於將自訂 HTML 類別新增至一個或多個目標 HTML 元素。所有選項都在下方說明,請參閱下方的 參數 章節。
在 https://nickofthyme.github.io/storybook-addon-theme-toggle/ 試用
相容性
此版本與 Storybook 版本 >6.x
相容。
從 Storybook 6.3.0
開始,全域參數會與 URL 同步為查詢搜尋參數 (storybookjs/storybook#15056)。因此,這會鎖定預設全域,並在不同 Story 之間持續存在。如果您想避免此行為,可以使用 storybook@~6.2.0
。
安裝
yarn
yarn add -D storybook-addon-theme-toggle
npm
npm i -D storybook-addon-theme-toggle
開始使用
安裝後,將此附加元件新增至 Storybook 的 main.js
檔案中的 addons
陣列
// main.js
module.exports = {
addons: [
'storybook-addon-theme-toggle'
],
};
如需更多資訊,請參閱 Storybook 文件。
參數
此外掛程式的參數位於 theme
鍵下,定義如下。
interface Parameters {
/**
* Ignores global values in url params
*
* @default true
*/
ignoreQueryParams?: false;
/**
* Tefault theme id
*/
default?: string;
/**
* Theme options to be applied
*/
themes: Theme[];
/**
* Selected theme is clearable
*
* @default true
*/
clearable?: boolean;
/**
* Disable addon at story level
*
* @default false
*/
disable?: boolean;
/**
* Persist theme selection between stories
*
* @default false
*/
persist?: boolean;
/**
* Blur tooltip on theme selection
*
* @default true
*/
blurOnSelect?: boolean;
/**
* Override icon used in toolbar
* See https://next--storybookjs.netlify.app/official-storybook/?path=/story/basics-icon--labels
*
* @default 'mirror'
*/
icon?: IconsProps['icon'];
/**
* A callback that will be executed when the theme changes
*/
onChange?: (theme: Theme) => void;
/**
* Target element selector(s) to apply class(es)
*
* @default 'body'
*/
selector?: string | string[];
}
Theme
類型定義如下。
interface Theme {
/**
* id of the theme
*/
id: string;
/**
* Title of the theme in theme selector ui
*
* @default {@link Theme#id}
*/
title?: string;
/**
* Class or classes to be applied to targeted element(s) via selector(s)
*/
class?: string | string[]
/**
* Badge color in the theme selector ui
*/
color: string;
/**
* Url of image to display over color swatch on theme selector
*/
imageUrl?: string
}
設定
全域層級
您可以在 Storybook 的 preview.(ts|js)
檔案中,於全域層級設定主題,如下所示。
// preview.ts
import type { ThemeParameter } from 'storybook-addon-theme-toggle';
type Parameters = ThemeParameter & {
// other global parameter types
};
export const parameters: Parameters = {
theme: {
default: 'light',
selector: 'body',
onChange(theme) {
// handle new theme
},
themes: [
{
id: 'light',
title: 'Light',
class: 'light',
color: '#fff',
},
{
id: 'dark',
title: 'Dark',
class: 'dark',
color: '#000',
},
],
}
};
Story 層級
ThemeParameter
中定義的所有屬性都可以在 Story 層級覆寫。但是,建議只覆寫部分參數,以防止定義可能對所有 Story 的附加元件行為產生負面影響的參數。可接受的屬性包括 default
、blurOnSelect
、disable
、ignoreQueryParams
和 clearable
。ThemeStoryParameter
類型是一個輔助程式,應用於限制在 Story 層級覆寫的屬性;
// story1.stories.tsx
import type { ThemeStoryParameter } from 'storybook-addon-theme-toggle';
const Example = () => <span>Hello!</span>;
Example.parameters: ThemeStoryParameter = {
theme: {
default: 'dark',
}
};
在裝飾器中使用
全域 Storybook 裝飾器
可以用於許多事情。因此,在裝飾器中存取選取的主題非常重要。這也是選擇使用 globals
來維護選取主題狀態的主要原因。
以下是一個簡單的範例,說明如何透過 context.globals
存取主題。
// preview.tsx
import React from "react";
import type { DecoratorFunction } from "@storybook/addons";
import type { ThemeGlobals } from 'storybook-addon-theme-toggle';
const Decorator: DecoratorFunction<JSX.Element> = (Story, context) => {
const globals = context.globals as ThemeGlobals;
const selectedTheme = globals.theme;
return (
<div>
<Story {...context} />
<br />
<pre>
Theme: {selectedTheme}
{JSON.stringify(globals, null, 2)}
</pre>
</div>
);
};
export const decorators = [Decorator];
請在 .storybook/Decorator.tsx
中查看完整的範例。
目前 Storybook 未正確初始化全域變數,這表示它們初始值永遠會回傳
{}
。為了修正這個問題,如果全域變數與預設/初始主題 ID 不同,我們會在發出SET_STORIES
事件後更新全域變數。
框架支援
React |
---|
:白色勾號 |