命名组件和层次结构
Watch a video tutorial
Storybook 提供了一种强大的组织故事的方法,为你提供了必要的工具,以便根据组织的需求和偏好对故事进行分类、搜索和过滤。
¥Storybook provides a powerful way to organize your stories, giving you the necessary tools to categorize, search, and filter your stories based on your organization's needs and preferences.
结构和层次结构
¥Structure and hierarchy
组织 Storybook 时,有两种构造故事的方法:隐式和显式。隐式方法 涉及依靠故事的物理位置将它们放置在侧边栏中,而 显式方法 涉及利用 title
参数来放置故事。
¥When organizing your Storybook, there are two methods of structuring your stories: implicit and explicit. The implicit method involves relying upon the physical location of your stories to position them in the sidebar, while the explicit method involves utilizing the title
parameter to place the story.
根据你构建 Storybook 的方式,你可以看到故事层次结构由各个部分组成:
¥Based on how you structure your Storybook, you can see that the story hierarchy is made up of various parts:
-
类别:Storybook 生成的故事和文档页面的顶层分组
¥Category: The top-level grouping of stories and documentation pages generated by Storybook
-
文件夹:一个中级组织单位,将侧边栏中的组件和故事分组,代表应用的功能或部分
¥Folder: A mid-level organizational unit that groups components and stories in the sidebar, representing a feature or section of your application
-
组件:一个底层组织单位,代表故事正在测试的组件
¥Component: A low-level organizational unit representing the component that the story is testing
-
文档:为组件自动生成的 文档页面
¥Docs: The automatically generated documentation page for the component
-
故事:单个故事测试特定的组件状态
¥Story: The individual story testing a specific component state
命名故事
¥Naming stories
创建故事时,你可以明确使用 title
参数来定义故事在侧边栏中的位置。它还可用于将 group 相关组件组合在一个可扩展的界面中,以帮助 Storybook 组织为你的用户提供更直观的体验。例如:
¥When creating your stories, you can explicitly use the title
parameter to define the story's position in the sidebar. It can also be used to group related components together in an expandable interface to help with Storybook organization providing a more intuitive experience for your users. For example:
// Replace your-framework with the name of your framework
import type { Meta } from '@storybook/your-framework';
import { Button } from './Button';
const meta: Meta<typeof Button> = {
/* 👇 The title prop is optional.
* See https://storybook.js.org/docs/configure/#configure-story-loading
* to learn how to generate automatic titles
*/
title: 'Button',
component: Button,
};
export default meta;
结果如下:
¥Yields this:
分组
¥Grouping
还可以将相关组件分组到可扩展界面中,以帮助 Storybook 组织。为此,请使用 /
作为分隔符:
¥It is also possible to group related components in an expandable interface to help with Storybook organization. To do so, use the /
as a separator:
// Replace your-framework with the name of your framework
import type { Meta } from '@storybook/your-framework';
import { Button } from './Button';
const meta: Meta<typeof Button> = {
/* 👇 The title prop is optional.
* See https://storybook.js.org/docs/configure/#configure-story-loading
* to learn how to generate automatic titles
*/
title: 'Design System/Atoms/Button',
component: Button,
};
export default meta;
// Replace your-framework with the name of your framework
import type { Meta } from '@storybook/your-framework';
import { CheckBox } from './Checkbox';
const meta: Meta<typeof CheckBox> = {
/* 👇 The title prop is optional.
* See https://storybook.js.org/docs/configure/#configure-story-loading
* to learn how to generate automatic titles
*/
title: 'Design System/Atoms/Checkbox',
component: CheckBox,
};
export default meta;
结果如下:
¥Yields this:
根
¥Roots
默认情况下,顶层分组将在 Storybook UI 中显示为“根”(即大写的、不可扩展的项目)。如果需要,你可以 配置 Storybook 并禁用此行为。如果你需要为用户提供简化的体验,则很有用;尽管如此,如果你有一个由多个组件故事组成的大型 Storybook,我们建议根据文件层次结构命名你的组件。
¥By default, the top-level grouping will be displayed as “root” in the Storybook UI (i.e., the uppercased, non-expandable items). If you need, you can configure Storybook and disable this behavior. Useful if you need to provide a streamlined experience for your users; nevertheless, if you have a large Storybook composed of multiple component stories, we recommend naming your components according to the file hierarchy.
单层提升
¥Single-story hoisting
单故事组件(即没有兄弟的组件故事)的显示名称与组件名称(title
的最后一部分)完全匹配,会自动提升以替换 UI 中的父组件。例如:
¥Single-story components (i.e., component stories without siblings) whose display name exactly matches the component's name (last part of title
) are automatically hoisted up to replace their parent component in the UI. For example:
// Replace your-framework with the name of your framework
import type { Meta, StoryObj } from '@storybook/your-framework';
import { Button as ButtonComponent } from './Button';
const meta: Meta<typeof ButtonComponent> = {
/* 👇 The title prop is optional.
* See https://storybook.js.org/docs/configure/#configure-story-loading
* to learn how to generate automatic titles
*/
title: 'Design System/Atoms/Button',
component: ButtonComponent,
};
export default meta;
type Story = StoryObj<typeof ButtonComponent>;
// This is the only named export in the file, and it matches the component name
export const Button: Story = {};
由于故事导出自动为 "start 大小写"(myStory
变为 "My Story"
),你的组件名称应与之匹配。或者,你可以使用 myStory.storyName = '...'
覆盖故事名称以匹配组件名称。
¥Because story exports are automatically "start cased" (myStory
becomes "My Story"
), your component name should match that. Alternatively, you can override the story name using myStory.storyName = '...'
to match the component name.
排序故事
¥Sorting stories
开箱即用,Storybook 根据故事的导入顺序对其进行排序。但是,你可以通过将 storySort
添加到 preview.js
文件中的 options
参数来自定义此模式以满足你的需求并提供更直观的体验。
¥Out of the box, Storybook sorts stories based on the order in which they are imported. However, you can customize this pattern to suit your needs and provide a more intuitive experience by adding storySort
to the options
parameter in your preview.js
file.
// Replace your-framework with the framework you are using (e.g., react, vue3)
import { Preview } from '@storybook/your-framework';
const preview: Preview = {
parameters: {
options: {
// The `a` and `b` arguments in this function have a type of `import('@storybook/types').IndexEntry`. Remember that the function is executed in a JavaScript environment, so use JSDoc for IntelliSense to introspect it.
storySort: (a, b) =>
a.id === b.id ? 0 : a.id.localeCompare(b.id, undefined, { numeric: true }),
},
},
};
export default preview;
除了唯一的故事标识符之外,你还可以使用 title
、name
和导入路径通过 storySort
函数对你的故事进行排序。
¥Asides from the unique story identifier, you can also use the title
, name
, and import path to sort your stories using the storySort
function.
storySort
还可以接受配置对象。
¥The storySort
can also accept a configuration object.
// Replace your-framework with the framework you are using (e.g., react, vue3)
import { Preview } from '@storybook/your-framework';
const preview: Preview = {
parameters: {
options: {
storySort: {
method: '',
order: [],
locales: '',
},
},
},
};
export default preview;
字段 | 类型 | 描述 | 必需 | 默认值 | 示例 |
---|---|---|---|---|---|
method | 字符串 | 告诉 Storybook 故事的显示顺序 | 否 | Storybook 配置 | 'alphabetical' |
order | 数组 | 要显示的故事,按提供的名称排序 | 否 | 空数组 [] | ['Intro', 'Components'] |
includeNames | 布尔值 | 在排序计算中包含故事名称 | 否 | false | true |
locales | 字符串 | 需要显示的语言环境 | 否 | 系统语言环境 | en-US |
要按字母顺序对故事进行排序,请将 method
设置为 'alphabetical'
,并可选择设置 locales
字符串。要使用自定义列表对故事进行排序,请使用 order
数组;与 order
列表中的项目不匹配的故事将出现在列表中的项目之后。
¥To sort your stories alphabetically, set method
to 'alphabetical'
and optionally set the locales
string. To sort your stories using a custom list, use the order
array; stories that don't match an item in the order
list will appear after the items in the list.
order
数组可以接受嵌套数组以对第二级故事类型进行排序。例如:
¥The order
array can accept a nested array to sort 2nd-level story kinds. For example:
// Replace your-framework with the framework you are using (e.g., react, vue3)
import { Preview } from '@storybook/your-framework';
const preview: Preview = {
parameters: {
options: {
storySort: {
order: ['Intro', 'Pages', ['Home', 'Login', 'Admin'], 'Components'],
},
},
},
};
export default preview;
这将导致这个故事排序:
¥Which would result in this story ordering:
-
Intro
和Intro/*
故事¥
Intro
and thenIntro/*
stories -
Pages
故事¥
Pages
story -
Pages/Home
和Pages/Home/*
故事¥
Pages/Home
andPages/Home/*
stories -
Pages/Login
和Pages/Login/*
故事¥
Pages/Login
andPages/Login/*
stories -
Pages/Admin
和Pages/Admin/*
故事¥
Pages/Admin
andPages/Admin/*
stories -
Pages/*
故事¥
Pages/*
stories -
Components
和Components/*
故事¥
Components
andComponents/*
stories -
所有其他故事
¥All other stories
如果你希望特定类别排序到列表末尾,则可以将 *
插入 order
数组以指示 "所有其他故事" 应该去哪里:
¥If you want specific categories to sort to the end of the list, you can insert a *
into your order
array to indicate where "all other stories" should go:
// Replace your-framework with the framework you are using (e.g., react, vue3)
import { Preview } from '@storybook/your-framework';
const preview: Preview = {
parameters: {
options: {
storySort: {
order: ['Intro', 'Pages', ['Home', 'Login', 'Admin'], 'Components', '*', 'WIP'],
},
},
},
};
export default preview;
在此示例中,WIP
类别将显示在列表末尾。
¥In this example, the WIP
category would be displayed at the end of the list.
请注意,order
选项独立于 method
选项;故事首先按 order
数组排序,然后按 method: 'alphabetical'
或默认 configure()
导入顺序排序。
¥Note that the order
option is independent of the method
option; stories are sorted first by the order
array and then by either the method: 'alphabetical'
or the default configure()
import order.