-
Notifications
You must be signed in to change notification settings - Fork 31
组件开发规范
$ tree -L 2 date-picker
date-picker
├── DatePicker.tsx
├── __test__
│ └── DatePicker.test.tsx
├── demos
│ ├── DatePicker.stories.tsx
│ └── DatePickerPage.tsx
├── index.ts
├── interfaces.ts
├── locales
│ ├── en-US.ts
│ └── zh-CN.ts
└── style
├── index.less
└── index.ts
4 directories, 10 files- 组件实现:包含组件实现、组件接口定义和组件导出等文件;
- Demo:
demos目录下,组件各种样式的 Demo 和组件文档; - 单元测试:
__test__目录下,使用 Jest 和 React Testing Library 实现的测试用例; - 国际化:
locales目录下,每种语言对应一个文件; - 样式:
style目录下,Less 实现的组件样式。
-
index.ts导出组件和组件的 Props -
interfaces.ts定义组件的 Props - 组件实现文件的文件名要和组件名一致
主要包含 DatePicker.stories.tsx 和 DatePickerPage.tsx 两种文件。前者是组件的故事集,包含各种组件的样式;后者是组件文档。
每个组件都有一个默认的 Story,使用 Props 的默认值,然后可通过 Storybook 的 Controls 来修改 Props 值,来查看各种样式。
示例:
const Template: Story = (args) => <DatePicker {...args} />;
export const Basic = Template.bind({});
Basic.args = {};只要返回 Story 类型值即可,如果为 Story 设置了 Props 类型,在 Controls 面板即可控制这些 Props。
示例:
export const DisabledDate = Template.bind({});
DisabledDate.args = {
disabledDate: (date: Date) => isBefore(startOfToday(), date),
};为了方便开发效果和设计对比,集成了 storybook-addon-designs 插件,可以在 Storybook 网站上直接预览设计稿。
集成方式如下:
export default {
parameters: {
design: {
type: 'figma',
url: 'https://www.figma.com/file/kP3A6S2fLUGVVMBgDuUx0f/GrowingIO-Design-Components?node-id=2672%3A30128',
allowFullscreen: true,
},
},
} as Meta;如果某个 Story 有单独的样式,它的设计稿也可以单独设置:
Indicator.story = {
parameters: {
design: {
url: 'https://www.figma.com/file/kP3A6S2fLUGVVMBgDuUx0f/GrowingIO-Design-Components?node-id=889%3A1159',
},
},
};文档主要包含以下几部分:
- 标题
- 代码演示
- 参数说明
标题直接是组件的名称,使用 Storybook 的 Title 组件。关于组件的定义,直接使用 p 标签即可。
示例:
<Title>{formatMessage({ defaultMessage: 'DatePicker 日期选择器' })}</Title>
<p>{formatMessage({ defaultMessage: '当用户需要一个日期,可以在面板中进行选择。' })}</p>“代码演示”用 Heading 标签,各种样式名称用 Subheading。用 Story 来展示组件的各种使用场景,每种场景对应一个 Story。
主要提供场景的描述和 Story 链接。另外,Story 外面包一层 Canvas,这样可以在文档中直接显示组件。
示例:
<Heading>{formatMessage({ defaultMessage: '代码演示' })}</Heading>
<Subheading>{formatMessage({ defaultMessage: '基本样式' })}</Subheading>
<Canvas>
<Story id="pickers-datepicker--basic" />
</Canvas>“参数说明”使用 Heading 标签,使用 Storybook 的 ArgsTable 展示组件的 Props 类型。
示例:
<Heading>{formatMessage({ defaultMessage: '参数说明' })}</Heading>
<ArgsTable of={DatePicker} />组件文档的国际化使用 react-intl 工具来实现。所以上文中所有文案都用 formatMessage 函数。
import React from 'react';
import { Canvas, Title, Heading, Story, Subheading, ArgsTable } from '@storybook/addon-docs';
import { useIntl } from 'react-intl';
import DatePicker from '../DatePicker';
export default function DatePickerPage() {
const { formatMessage } = useIntl();
return (
<>
<Title>{formatMessage({ defaultMessage: 'DatePicker 日期选择器' })}</Title>
...
</>
);
}测试工具使用 Jest + React Testing Library。 在使用 Storybook 时,我们创建了组件的各种使用场景,当我们编写测试用例时,为了提高测试覆盖率,我们需要做同样的工作!所以,在单元测试中要复用 Storybook 的故事集。示例如下:
import { Basic, DisabledDate } from '../demos/DatePicker.stories';
describe('DatePicker', () => {
it('render with default', () => {
const handleOnSelect = jest.fn();
render(<Basic {...Basic.args} onSelect={handleOnSelect} />);
expect(screen.getAllByText(20)).toHaveLength(1);
fireEvent.click(screen.getByText(20));
expect(handleOnSelect).toHaveBeenCalledWith(new Date());
});
it('render with disabled date', () => {
const handleOnSelect = jest.fn();
render(<DisabledDate {...DisabledDate.args} onSelect={handleOnSelect} />);
expect(screen.getAllByText(21)).toHaveLength(1);
fireEvent.click(screen.getByText(21));
expect(handleOnSelect).not.toHaveBeenCalled();
});
});- 每个组件有自己的 Locale 文件
- 在
src/locales目录下是汇总所有组件的 Locale 文件 - 每种语言对应一个文件,语言代码参考 LCID
DatePicker 组件的示例:
import rcPickerLocale from 'rc-picker/lib/locale/zh_CN';
const locale = {
...rcPickerLocale,
};
export default locale;汇总的 Locale 文件:
import type { Locale } from '@gio-design/utils';
import datePickerLocale from '../date-picker/locales/zh-CN';
export const locale: Locale = {
code: 'zh-CN',
DatePicker: {
...datePickerLocale,
},
};
export default locale;-
index.less中实现组件的样式,实现时遵循 CSS BEM 书写规范; -
index.ts要import './index.less'。如果使用了其他组件,也要import对应组件的 Less 文件。