Storybook ADK
此包最初引入的一些功能现在可以通过 Storybook API 获取。请先考虑 https://github.com/storybookjs/addon-kit,它是一个使用最新插件 API 的简单 Github 代码库模板。
此工具包为 Storybook API 提供了额外的中间件,可用于基于此创建插件。
简化插件创建。通过通道保持插件数据的同步。提供用于创建插件 UI 的智能块。提供简单的 API 用于注册插件和创建装饰器。它是快速构建您自定义的全新的出色插件的基础。
功能
- 隐藏在幕后,处理通过通道进行通信和切换故事时数据同步的所有复杂问题。
- 通过 HOC 将您的插件组件连接到您的插件存储并仅在数据更改时更新。
- 将插件存储数据划分为全局和本地。跟踪故事浏览以同时在管理器和预览端切换相应的本地数据。
- 保留不可变的初始化数据和可覆盖的数据,您可以通过操作对其进行更改。
- 提供类似 redux 的方法通过选择器和操作来处理您的插件存储(但不用担心,默认操作只是简单地覆盖您的数据)。
- 允许将任意数量的面板、按钮和任何其他插件类型连接到单个插件存储。
- 提供 UI 容器,该容器会自动反映插件面板的长宽比。对于创建对垂直和水平面板位置有响应的插件 UI 非常有用。
- 包含 Typescript 定义。
用法
npm i --save @storybook/addon-devkit
import {
register,
createDecorator,
setParameters,
setConfig,
Layout,
Block,
} from '@storybook/addon-devkit'
API
注册管理器端的插件面板
HOC 用于注册插件 UI 并将其连接到插件存储。
// in your addon `register.js`
import { register } from '@storybook/addon-devkit'
register(
{
...selectors,
},
({ global, local }) => ({
...globalActions,
...localActions,
})
)(AddonPanelUI);
其中 selectors
是一个包含以下函数的对象:
{
deepData: store => store.path.to.deep.store.data,
}
actions
可以是“全局”和“本地”。全局操作影响存储的全局部分,而本地操作仅影响与当前故事相关的数据。
({ global, local }) => ({
// action to manipulate with common data
increase: global(store => ({
...store,
index: store.index + 1,
})),
// action to manipulate with current story data
// usage: setBackground('#ff66cc')
setBackground: local((store, color) => ({
...store,
backgroundColor: color,
})),
// action to override data
// usage: update({...newData})
update: global(),
})
AddonPanelUI
是您在选择相应的选项卡时显示在插件面板上的组件。
注意:HOC 会自动跟踪插件的
active
状态,并且仅在必要时显示。
register HOC 会将以下道具传递给 AddonPanelUI
组件:
<AddonPanelUI
{...actions} // generated actions
{...selectors} // selected pieces of store
api={api} // storybook API object
active={active} // you don't need to do anything with it
store={store} // entire store. prefer to use selectors
kind={kind} // current story kind
story={story} // current story
ADDON_ID={ADDON_ID}
PANEL_ID={PANEL_ID}
PANEL_Title={PANEL_Title} // Title on the addon panel
rect={rect} // dimensions of panel area
/>
只要您通过操作更改存储,AddonPanelUI
和 storyDecorator
都会使用新数据重新渲染。
如果数据来自故事,也会进行更新。
初始化后,HOC 将等待来自故事的初始化数据,只有在收到数据后才会渲染 UI。
创建故事端的装饰器
HOC 用于创建装饰器并将其连接到插件存储。
// in your addon `decorator.js`
import { createDecorator } from '@storybook/addon-devkit'
export const withMyAddon = createDecorator({
...selectors,
},
({ global, local }) => ({
...globalActions,
...localActions,
})
)(DecoratorUI, { isGlobal });
因此,您可以这样使用装饰器:
// stories.js
import React from 'react';
import { storiesOf, addDecorator, addParameters } from '@storybook/react';
import { withMyAddon, myAddonParams } from 'my-addon';
// add decorator globally
addDecorator(withMyAddon({ ...initData }))
addParameters(myAddonParams({ ...globalParams }))
storiesOf('My UI Kit', module)
// ...or add decorator locally
.addDecorator(withMyAddon({ ...initData }))
.add(
'Awesome',
() => <Button>Make Awesome</Button>,
myAddonParams({ ...localParams })
)
DecoratorUI
可以如下所示:
const DecoratorUI = ({ context, getStory, selectedData }) => (
<div>
<h1>Title: {selectedData}</h1>
{getStory(context)}
</div>
);
当 isGlobal = true
时,装饰器将所有传递的数据视为全局数据。
注意:插件参数将与初始化数据合并,并且装饰器和面板选择器都可以访问。
向插件传递参数
创建用于向插件传递参数的函数。
请参阅上面的用法。
import { setParameters } from '@storybook/addon-devkit'
export const myAddonParams = setParameters()
插件配置
为了创建插件,您需要指定一些唯一的参数,例如事件名称、插件标题、参数键等。它们在管理器和预览端应该相同。如果您没有指定它们,插件开发工具包将使用默认参数。要指定您自己的参数,请使用 setConfig
。
import { setConfig } from '@storybook/addon-devkit';
setConfig({
addId: 'dev_adk',
panelTitle: 'ADK DEV'
});
您应该在使用 register
、setParameters
和 createDecorator
之前运行它。
注意:不要忘记在管理器和预览端使用相同的参数使用 setConfig。
插件面板 UI 组件
组件用于在面板位于底部位置时将 UI 组织成一行,并在面板位于右侧时组织成一列。
import { Layout, Block, register } from '@storybook/addon-devkit';
import { styled } from '@storybook/theming';
import './config'
const LayoutBlock = styled(Layout)`
...styles
`
const AddonBlock = styled(Block)`
...styles
`
const AddonPanel = () => (
<LayoutBlock>
<AddonBlock size={200}>
{UI1}
</AddonBlock>
<AddonBlock>
{UI2}
</AddonBlock>
<AddonBlock>
{UI3}
</AddonBlock>
</LayoutBlock>
)
register()(AddonPanel)
<Layout>
具有 display: flex
,在底部时 flex-direction: row
,在右侧时 flex-direction: column
。
您可以指定 <Block>
的大小。如果是水平布局,它将是元素的宽度,如果是垂直布局,它将是元素的高度。
否则,它将具有 flex-grow: 1
。