Skip to content

Commit f687f07

Browse files
authored
feat(button): refactor antd button, rewrite icon (#585)
* feat(button): refactor antd button, rewrite icon #584 * test(button): change button unit test
1 parent 5f083f6 commit f687f07

File tree

9 files changed

+450
-0
lines changed

9 files changed

+450
-0
lines changed
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`Button should support contentLayout success render 1`] = `
4+
{
5+
"asFragment": [Function],
6+
"baseElement": <body>
7+
<div>
8+
<button
9+
class="ant-btn ant-btn-default dtc-button"
10+
type="button"
11+
>
12+
<span
13+
class="dtc-button__icon dtc-button__icon--middle"
14+
>
15+
<span
16+
data-mock-icon="UploadOutlined"
17+
/>
18+
</span>
19+
<span
20+
class="dtc-button__text dtc-button__text--middle"
21+
>
22+
Primary
23+
</span>
24+
</button>
25+
</div>
26+
</body>,
27+
"container": <div>
28+
<button
29+
class="ant-btn ant-btn-default dtc-button"
30+
type="button"
31+
>
32+
<span
33+
class="dtc-button__icon dtc-button__icon--middle"
34+
>
35+
<span
36+
data-mock-icon="UploadOutlined"
37+
/>
38+
</span>
39+
<span
40+
class="dtc-button__text dtc-button__text--middle"
41+
>
42+
Primary
43+
</span>
44+
</button>
45+
</div>,
46+
"debug": [Function],
47+
"findAllByAltText": [Function],
48+
"findAllByDisplayValue": [Function],
49+
"findAllByLabelText": [Function],
50+
"findAllByPlaceholderText": [Function],
51+
"findAllByRole": [Function],
52+
"findAllByTestId": [Function],
53+
"findAllByText": [Function],
54+
"findAllByTitle": [Function],
55+
"findByAltText": [Function],
56+
"findByDisplayValue": [Function],
57+
"findByLabelText": [Function],
58+
"findByPlaceholderText": [Function],
59+
"findByRole": [Function],
60+
"findByTestId": [Function],
61+
"findByText": [Function],
62+
"findByTitle": [Function],
63+
"getAllByAltText": [Function],
64+
"getAllByDisplayValue": [Function],
65+
"getAllByLabelText": [Function],
66+
"getAllByPlaceholderText": [Function],
67+
"getAllByRole": [Function],
68+
"getAllByTestId": [Function],
69+
"getAllByText": [Function],
70+
"getAllByTitle": [Function],
71+
"getByAltText": [Function],
72+
"getByDisplayValue": [Function],
73+
"getByLabelText": [Function],
74+
"getByPlaceholderText": [Function],
75+
"getByRole": [Function],
76+
"getByTestId": [Function],
77+
"getByText": [Function],
78+
"getByTitle": [Function],
79+
"queryAllByAltText": [Function],
80+
"queryAllByDisplayValue": [Function],
81+
"queryAllByLabelText": [Function],
82+
"queryAllByPlaceholderText": [Function],
83+
"queryAllByRole": [Function],
84+
"queryAllByTestId": [Function],
85+
"queryAllByText": [Function],
86+
"queryAllByTitle": [Function],
87+
"queryByAltText": [Function],
88+
"queryByDisplayValue": [Function],
89+
"queryByLabelText": [Function],
90+
"queryByPlaceholderText": [Function],
91+
"queryByRole": [Function],
92+
"queryByTestId": [Function],
93+
"queryByText": [Function],
94+
"queryByTitle": [Function],
95+
"rerender": [Function],
96+
"unmount": [Function],
97+
}
98+
`;

src/button/__tests__/index.test.tsx

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import React from 'react';
2+
import { UploadOutlined } from '@dtinsight/react-icons';
3+
import { render } from '@testing-library/react';
4+
import '@testing-library/jest-dom/extend-expect';
5+
6+
import Button from '..';
7+
8+
describe('Button', () => {
9+
test('should support contentLayout success render', () => {
10+
const wrapper = render(<Button icon={<UploadOutlined />}>Primary</Button>);
11+
expect(wrapper).toMatchSnapshot();
12+
});
13+
14+
it('renders text correctly', () => {
15+
const { getByText } = render(<Button>Hello</Button>);
16+
expect(getByText('Hello')).toBeInTheDocument();
17+
});
18+
19+
it('renders icon correctly', () => {
20+
const { container } = render(<Button icon={<UploadOutlined />} />);
21+
expect(container.querySelector('.dtc-button__icon')).toBeInTheDocument();
22+
expect(container.querySelector('.dtc-button__text')).not.toBeInTheDocument();
23+
});
24+
25+
it('renders icon and text correctly', () => {
26+
const { getByText, container } = render(<Button icon={<UploadOutlined />}>Search</Button>);
27+
expect(getByText('Search')).toBeInTheDocument();
28+
expect(container.querySelector('.dtc-button__icon')).toBeInTheDocument();
29+
});
30+
31+
it('applies custom className', () => {
32+
const { container } = render(<Button className="custom-class">Test</Button>);
33+
expect(container.firstChild).toHaveClass('custom-class');
34+
});
35+
36+
it('passes other props to AntdButton', () => {
37+
const { getByText } = render(<Button type="primary">Primary</Button>);
38+
expect(getByText('Primary').parentNode).toHaveClass('ant-btn-primary');
39+
});
40+
41+
it('applies size class to icon and text', () => {
42+
const { container } = render(
43+
<Button icon={<UploadOutlined />} size="small">
44+
Test
45+
</Button>
46+
);
47+
expect(container.querySelector('.dtc-button__icon--small')).toBeInTheDocument();
48+
expect(container.querySelector('.dtc-button__text--small')).toBeInTheDocument();
49+
});
50+
});

src/button/demos/basic.tsx

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import React, { useState } from 'react';
2+
import { UploadOutlined } from '@dtinsight/react-icons';
3+
import { Radio, Space } from 'antd';
4+
import { Button } from 'dt-react-component';
5+
6+
import { ButtonProps } from '..';
7+
8+
export default function Basic() {
9+
const [size, setSize] = useState<ButtonProps['size']>('large');
10+
11+
return (
12+
<Space direction="vertical" size="large">
13+
<Radio.Group value={size} onChange={(e) => setSize(e.target.value)}>
14+
<Radio.Button value="large">Large</Radio.Button>
15+
<Radio.Button value="middle">Default</Radio.Button>
16+
<Radio.Button value="small">Small</Radio.Button>
17+
</Radio.Group>
18+
19+
<div>
20+
<h3>按钮类型</h3>
21+
<Space>
22+
<Button type="primary" size={size}>
23+
Primary Button
24+
</Button>
25+
<Button size={size}>Default Button</Button>
26+
<Button type="dashed" size={size}>
27+
Dashed Button
28+
</Button>
29+
<Button type="link" size={size}>
30+
Link Button
31+
</Button>
32+
</Space>
33+
</div>
34+
35+
<div>
36+
<h3>带图标的按钮</h3>
37+
<Space>
38+
<Button type="primary" size={size} icon={<UploadOutlined />}>
39+
Search
40+
</Button>
41+
<Button icon={<UploadOutlined />} size={size}>
42+
Search
43+
</Button>
44+
<Button type="dashed" size={size} icon={<UploadOutlined />}>
45+
Search
46+
</Button>
47+
<Button type="link" size={size} icon={<UploadOutlined />}>
48+
Search
49+
</Button>
50+
</Space>
51+
</div>
52+
53+
<div>
54+
<h3>纯图标按钮</h3>
55+
<Space>
56+
<Button type="primary" size={size} icon={<UploadOutlined />} />
57+
<Button size={size} icon={<UploadOutlined />} />
58+
<Button size={size} type="dashed" icon={<UploadOutlined />} />
59+
<Button size={size} type="link" icon={<UploadOutlined />} />
60+
</Space>
61+
</div>
62+
63+
<div>
64+
<h3>禁用状态</h3>
65+
<Space>
66+
<Button size={size} type="primary" disabled>
67+
Primary(Disabled)
68+
</Button>
69+
<Button size={size} disabled>
70+
Default(Disabled)
71+
</Button>
72+
<Button size={size} type="dashed" disabled>
73+
Dashed(Disabled)
74+
</Button>
75+
<Button size={size} type="link" disabled>
76+
Link(Disabled)
77+
</Button>
78+
</Space>
79+
</div>
80+
</Space>
81+
);
82+
}

src/button/demos/block.tsx

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import React from 'react';
2+
import { UploadOutlined } from '@dtinsight/react-icons';
3+
import { Space } from 'antd';
4+
import { Button } from 'dt-react-component';
5+
6+
export default function BlockDemo() {
7+
return (
8+
<Space direction="vertical" size="large" style={{ width: '100%' }}>
9+
<div>
10+
<h3>块级按钮</h3>
11+
<Space direction="vertical" style={{ width: '100%' }}>
12+
<Button type="primary" block>
13+
Primary Block Button
14+
</Button>
15+
<Button block>Default Block Button</Button>
16+
<Button type="dashed" block>
17+
Dashed Block Button
18+
</Button>
19+
<Button type="link" block>
20+
Link Block Button
21+
</Button>
22+
</Space>
23+
</div>
24+
25+
<div style={{ background: 'rgb(190, 200, 200)', padding: '16px' }}>
26+
<h3>幽灵按钮</h3>
27+
<Space>
28+
<Button type="primary" ghost>
29+
Primary Ghost
30+
</Button>
31+
<Button ghost>Default Ghost</Button>
32+
<Button type="dashed" ghost>
33+
Dashed Ghost
34+
</Button>
35+
<Button type="primary" ghost icon={<UploadOutlined />}>
36+
Ghost with Icon
37+
</Button>
38+
</Space>
39+
</div>
40+
</Space>
41+
);
42+
}

src/button/demos/loading.tsx

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import React, { useState } from 'react';
2+
import { UploadOutlined } from '@dtinsight/react-icons';
3+
import { Space } from 'antd';
4+
import { Button } from 'dt-react-component';
5+
6+
export default function LoadingDemo() {
7+
const [loading, setLoading] = useState(false);
8+
9+
const handleClick = () => {
10+
setLoading(true);
11+
setTimeout(() => {
12+
setLoading(false);
13+
}, 2000);
14+
};
15+
16+
return (
17+
<Space direction="vertical" size="large">
18+
<div>
19+
<h3>加载状态</h3>
20+
<Space>
21+
<Button type="primary" loading>
22+
Loading
23+
</Button>
24+
<Button loading>Loading</Button>
25+
<Button type="dashed" loading>
26+
Loading
27+
</Button>
28+
<Button type="link" loading>
29+
Loading
30+
</Button>
31+
</Space>
32+
</div>
33+
34+
<div>
35+
<h3>点击后加载</h3>
36+
<Space>
37+
<Button type="primary" loading={loading} onClick={handleClick}>
38+
Click me!
39+
</Button>
40+
<Button loading={loading} onClick={handleClick}>
41+
Click me!
42+
</Button>
43+
<Button
44+
type="primary"
45+
icon={<UploadOutlined />}
46+
loading={loading}
47+
onClick={handleClick}
48+
>
49+
Click me!
50+
</Button>
51+
</Space>
52+
</div>
53+
54+
<div>
55+
<h3>危险按钮</h3>
56+
<Space>
57+
<Button type="primary" danger>
58+
Primary Danger
59+
</Button>
60+
<Button danger>Default Danger</Button>
61+
<Button type="dashed" danger>
62+
Dashed Danger
63+
</Button>
64+
<Button type="link" danger>
65+
Link Danger
66+
</Button>
67+
</Space>
68+
</div>
69+
</Space>
70+
);
71+
}

src/button/index.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
---
2+
title: Button 按钮
3+
group: 组件
4+
toc: content
5+
demo:
6+
cols: 2
7+
---
8+
9+
# Button 按钮
10+
11+
## 何时使用
12+
13+
按钮用于开始一个即时操作。
14+
15+
## 代码演示
16+
17+
<code src="./demos/basic.tsx" title="基本使用" description="按钮的基本使用,包括不同类型的按钮、带图标的按钮、纯图标按钮、不同尺寸的按钮以及禁用状态的按钮。"></code>
18+
19+
<code src="./demos/loading.tsx" title="加载状态" description="展示按钮的加载状态和危险按钮。"></code>
20+
21+
<code src="./demos/block.tsx" title="块级按钮" description="展示块级按钮和幽灵按钮。"></code>
22+
23+
## API
24+
25+
### Button
26+
27+
Button 组件支持 antd Button 组件的所有属性,详见 [Ant Design Button API](https://ant.design/components/button-cn/#API)
28+
29+
## 注意事项
30+
31+
- 使用自定义图标时,请确保图标组件符合规范,建议使用项目内的图标组件。
32+
- 图标大小会根据按钮的 `size` 属性自动调整,也可以通过设置图标组件的 `style` 属性来手动调整大小。
33+
- 当只设置 `icon` 而不设置 `children` 时,按钮将只显示图标。
34+
- 本组件是对 antd Button 的封装,支持 antd Button 的所有属性和事件。

0 commit comments

Comments
 (0)