Storybook и документация (references/storybook.md)
Источник:
ds-skills/core-ui-development-skills/src/skills/build-core-ui-components/references/storybook.md— справочник скилла build-core-ui-components
- Использовать
StoryFnиMetaизstorybook-react-rsbuildпо примеру ближайших актуальных историй. - Добавлять
Default; добавлятьCommon, если полезно показать матрицу вариантов. - Исключать из controls технические пропсы.
- Подключать
docs.mdxи сохранять русскоязычную структуру соседних компонентов. - Использовать служебные story-пропсы с префиксом
_и русскимargTypes.name. - Для нового компонента задавать
tags: ["version:1.0.0"]. Не копировать версию соседнего компонента или текущую версию пакетаcore-ui. - При изменении существующего компонента сохранять его текущий version-тег, если повышение версии явно не согласовано.
- Для нетривиальных примеров использовать механизм
src/storybook-docs/write-story-with-code: хранить исполняемый.tsxвstorybook/examples/и импортировать этот же файл через?rawдля панели Code. - Давать вложенному компоненту отдельную Storybook-страницу только при самостоятельном публичном контракте и после согласования.
- Брать
title, параметры и структуру документации у ближайшего компонента того же раздела.
Локальные компоненты историй
Если для истории JSX-фрагмент выносится в константу или функцию ради повторного
использования либо разгрузки stories.tsx, оформлять его React-компонентом в
storybook/components/. Не хранить в stories.tsx конструкции вида
const content = (<div>...</div>) или const heading = (<Component />).
Для каждого такого компонента создавать отдельную kebab-case директорию с
реализацией и локальным index.ts; относящиеся только к нему стили хранить рядом:
storybook/components/
├── index.ts
├── common-content/
│ ├── common-content.tsx
│ ├── styles.module.scss
│ └── index.ts
└── common-section-heading/
├── common-section-heading.tsx
├── styles.module.scss
└── index.ts
В корневом storybook/components/index.ts собирать экспорты локальных story-
компонентов, а в stories.tsx импортировать их через подтверждённый alias
репозитория. Не экспортировать эти компоненты из публичного API библиотеки и не
создавать для них отдельные Storybook-страницы.
Canvas в разделе «Описание»
В разделе ## Описание показывать только одну обзорную историю:
- если компонент имеет
Common, использовать<Canvas of={ComponentStories.Common} />; - если
Commonотсутствует, использовать<Canvas of={ComponentStories.Default} />; - не выводить
DefaultиCommonодновременно в разделе «Описание».
Ссылки на код и дизайн в docs.mdx
При создании документации компонента сразу после заголовка первого уровня добавлять ссылки на код компонента в GitLab и его макет в Figma по паттерну актуальных компонентов:
# ComponentName
[Код](https://gitlab.rshbdev.ru/rshbintech/crft/ckof/ownfin/frontend/core/core-ui/-/tree/master/src/component-name)
|
[Дизайн](https://www.figma.com/design/<figma-file>/<design-system>?node-id=<node-id>&p=f&m=dev)
- Для ссылки
Кодподставлять kebab-case директорию компонента изsrc/и всегда указывать стабильную веткуmaster. - Для ссылки
Дизайниспользовать URL переданного макета или ссылку из документации ближайшего актуального компонента только тогда, когда она относится к тому же макету. - Не придумывать Figma URL или
node-id. Если ссылка на дизайн неизвестна, явно сообщить об этом пользователю и не подставлять фиктивное значение. Исключение — контракт компонента: его разделsourceдаёт ключ файла иnode-id, см. истории из контракта. - Сохранять разделитель
| между ссылками.
Пример с отображением исходного кода
Создавать для примера единственный исполняемый источник:
storybook/examples/
├── index.ts
└── default/
├── default.tsx
├── index.ts
└── styles.module.scss # при наличии локальных стилей примера
Называть директорию, файл, example-компонент и raw-экспорт по сценарию истории. Для Default использовать default/default.tsx, компонент UsingDefault и raw-экспорт defaultCode; для других сценариев использовать соответствующие пары UsingSublist/sublistCode, UsingList/listCode и аналогичные осмысленные имена. Не называть example-компонент по production-компоненту (UsingCustomLayer, UsingBasicList) и не использовать общие имена вроде UsingExample или exampleCode.
В локальном index.ts экспортировать компонент, типы и константы примера, которые используются историей или тестами, и прочитать тот же исполняемый файл через ?raw:
export {
UsingDefault,
DEFAULT_STORY_ITEM,
type ItemType,
} from "./default";
import defaultCode from "./default.tsx?raw";
export { defaultCode };
В examples/index.ts собрать код и публичный компонент примера:
import { defaultCode } from "./default";
export const Examples = { defaultCode };
export { UsingDefault, type ItemType } from "./default";
В stories.tsx передать исходник истории в parameters.docs.source.code:
/**
* Default Story
*/
export const Default: StoryFn<ComponentProps<ItemType> & StoryArgs> = (args) => (
<UsingDefault {...args} />
);
Default.parameters = {
docs: {
source: {
code: Examples.defaultCode,
},
},
};
Не дублировать исполняемый пример строкой в stories.tsx или docs.mdx: код панели должен поступать из того же .tsx, который рендерит история.
Стили историй и examples
- Стили, относящиеся только к конкретному исполняемому примеру, хранить рядом с ним:
storybook/examples/<scenario>/styles.module.scss. - Импортировать локальные стили непосредственно из
<scenario>.tsx; пример должен оставаться самостоятельным источником разметки и оформления для панели Code. - В
storybook/styles.module.scssпреимущественно хранить оформление самой истории: grid/flex-раскладкуCommon, размеры демонстрационной области, расстояния между вариантами, подписи и общие story-обёртки. - Не переносить в общий
storybook/styles.module.scssстили содержимогоDefault,Sublistили другого отдельного example только ради повторного использования файла. - Если один стиль действительно используется несколькими историями, оставить его общим и явно отделить от локальных стилей examples.
Расстояние между вариантами в Common
При вертикальном, горизонтальном или grid-отображении нескольких вариантов задавать между соседними вариантами расстояние не меньше var(--space-xl).
Использовать gap, row-gap и column-gap, а не padding дочерних компонентов:
.common {
display: flex;
flex-wrap: wrap;
gap: var(--space-xl);
}
Если расстояния по осям задаются отдельно, каждое должно быть не меньше var(--space-xl):
.common {
display: grid;
row-gap: var(--space-xl);
column-gap: var(--space-xl);
}
Не считать внутренний padding демонстрируемого компонента расстоянием между вариантами. Не уменьшать gap без явного требования дизайна.