Skip to content

Commit eeb7cdf

Browse files
author
gaoyuancheng
committed
feat: select组件更新
1 parent d75d032 commit eeb7cdf

8 files changed

Lines changed: 426 additions & 175 deletions

File tree

src/components/ChartCard/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import FormCard, { FormCardProps } from '../FormCard';
66
interface ChartCardProps
77
extends Omit<FormCardProps, 'childrenRender' | 'request'> {
88
request: (
9-
...args: Parameters<FormCardProps['request']>
9+
...args: Parameters<NonNullable<FormCardProps['request']>>
1010
) => Promise<EChartsOption>;
1111
}
1212

src/components/FormCard/index.tsx

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,16 @@ import { Button, Card, CardProps, Form } from 'antd';
33
import { FormItemProps } from 'antd/es/form';
44
import React from 'react';
55

6-
type GetPromiseReturnType<T extends (...args: any[]) => Promise<any>> =
7-
T extends (...args: any[]) => Promise<infer R> ? R : unknown;
6+
type GetPromiseReturnType<
7+
T extends ((...args: any[]) => Promise<any>) | undefined,
8+
> = T extends (...args: any[]) => Promise<infer R> ? R : unknown;
89

910
export interface FormCardProps extends CardProps {
1011
params?: Record<string, any>;
11-
formItems?: {
12-
label?: string;
13-
name: string;
12+
formItems?: ({
1413
children: React.ReactNode;
15-
formItemProps?: FormItemProps;
16-
}[];
17-
request: (
14+
} & FormItemProps)[];
15+
request?: (
1816
params: FormCardProps['params'] & Record<string, any>,
1917
) => Promise<any>;
2018
childrenRender: (
@@ -42,11 +40,11 @@ const FormCard: React.FC<FormCardProps> = ({
4240

4341
const requestParams = {
4442
// 表单值优先
45-
...values,
4643
...params,
44+
...values,
4745
};
4846

49-
const res = await request(requestParams);
47+
const res = await request?.(requestParams);
5048
return res;
5149
};
5250

@@ -59,10 +57,11 @@ const FormCard: React.FC<FormCardProps> = ({
5957
layout="inline"
6058
>
6159
{formItems.map((item) => {
62-
const { formItemProps = {}, name, label } = item;
60+
const { children, ...restFormItemProps } = item;
61+
const { name } = restFormItemProps;
6362
return (
64-
<Form.Item key={name} name={name} label={label} {...formItemProps}>
65-
{item.children}
63+
<Form.Item key={name} {...restFormItemProps}>
64+
{children}
6665
</Form.Item>
6766
);
6867
})}
@@ -79,11 +78,11 @@ const FormCard: React.FC<FormCardProps> = ({
7978

8079
return (
8180
<Card
82-
bodyStyle={{
83-
height: 250,
84-
}}
8581
loading={loading}
8682
extra={cardExtra}
83+
headStyle={{
84+
height: 64,
85+
}}
8786
{...rest}
8887
>
8988
{childrenRender(data)}

src/components/GSelect/demo/SelectWithScroll.tsx

Lines changed: 0 additions & 113 deletions
This file was deleted.
Lines changed: 168 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,171 @@
1-
import { GSelect } from 'gyc-components';
2-
import React from 'react';
1+
import { Button, Card, Space } from 'antd';
2+
import { GSelect, mockRequest } from 'gyc-components';
3+
import React, { useState } from 'react';
34

4-
const GSelectBase = () => {
5-
return <GSelect />;
5+
interface OptionItem {
6+
label: string;
7+
value: string;
8+
}
9+
10+
/**
11+
* 获取分页数据
12+
*/
13+
const fetchSelectData = (params: { page: number; pageSize: number }) => {
14+
const data: any[] = [];
15+
for (let i = 1; i <= 50; i++) {
16+
data.push({
17+
id: `${i}`,
18+
name: `选项 ${i}`,
19+
});
20+
}
21+
22+
const pageNum = parseInt(params.page.toString(), 10);
23+
const sizeNum = parseInt(params.pageSize.toString(), 10);
24+
25+
const startIndex = (pageNum - 1) * sizeNum;
26+
const endIndex = startIndex + sizeNum;
27+
const list = data.slice(startIndex, endIndex);
28+
29+
return mockRequest(
30+
{},
31+
{
32+
list,
33+
total: data.length,
34+
},
35+
);
636
};
737

8-
export default GSelectBase;
38+
/**
39+
* MySelect 测试页面
40+
* @description 测试分页加载和回填第二页数据功能
41+
*/
42+
export default function MySelectTestPage() {
43+
const [singleValue, setSingleValue] = useState<OptionItem | undefined>({
44+
label: '选项 15',
45+
value: '15',
46+
});
47+
const [multiValue, setMultiValue] = useState<OptionItem[]>([
48+
{ label: '选项 1', value: '1' },
49+
{ label: '选项 15', value: '15' },
50+
{ label: '选项 25', value: '25' },
51+
{ label: '选项 35', value: '35' },
52+
]);
53+
54+
const handleResetToPage2 = () => {
55+
setSingleValue({ label: '选项 15', value: '15' });
56+
};
57+
58+
const handleResetToPage1 = () => {
59+
setSingleValue({ label: '选项 5', value: '5' });
60+
};
61+
62+
const handleClearSingle = () => {
63+
setSingleValue(undefined);
64+
};
65+
66+
const handleResetMulti = () => {
67+
setMultiValue([
68+
{ label: '选项 15', value: '15' },
69+
{ label: '选项 25', value: '25' },
70+
{ label: '选项 35', value: '35' },
71+
]);
72+
};
73+
74+
const handleClearMulti = () => {
75+
setMultiValue([]);
76+
};
77+
78+
return (
79+
<div style={{ padding: 24 }}>
80+
<Space direction="vertical" style={{ width: '100%' }} size="large">
81+
{/* <Card title="MySelect 单选测试" style={{ maxWidth: 500 }}>
82+
<Space direction="vertical" style={{ width: '100%' }} size="middle">
83+
<div>
84+
<h4>测试说明:</h4>
85+
<ul>
86+
<li>默认回填值为 15(第二页的数据)</li>
87+
<li>下拉滚动可加载更多数据</li>
88+
</ul>
89+
</div>
90+
91+
<div>
92+
<h4>当前选中值:{singleValue?.value ?? '无'}</h4>
93+
<MySelect
94+
style={{ width: '100%' }}
95+
placeholder="请选择"
96+
value={singleValue}
97+
onChange={setSingleValue}
98+
request={fetchSelectData}
99+
pageSize={10}
100+
/>
101+
</div>
102+
103+
<Space>
104+
<Button type="primary" onClick={handleResetToPage2}>
105+
回填第二页数据 (ID: 15)
106+
</Button>
107+
<Button onClick={handleResetToPage1}>
108+
回填第一页数据 (ID: 5)
109+
</Button>
110+
<Button danger onClick={handleClearSingle}>
111+
清空
112+
</Button>
113+
</Space>
114+
</Space>
115+
</Card> */}
116+
117+
<Card title="MySelect 多选测试" style={{ maxWidth: 600 }}>
118+
<Space direction="vertical" style={{ width: '100%' }} size="middle">
119+
<div>
120+
<h4>测试说明:</h4>
121+
<ul>
122+
<li>默认回填值为 [15, 25, 35](分布在第二、三、四页)</li>
123+
<li>下拉滚动可加载更多数据</li>
124+
<li>支持多选和回填跨页数据</li>
125+
</ul>
126+
</div>
127+
128+
<div>
129+
<h4>
130+
当前选中值:
131+
{multiValue.length > 0
132+
? multiValue.map((v) => v.value).join(', ')
133+
: '无'}
134+
</h4>
135+
<GSelect
136+
mode="multiple"
137+
style={{ width: '100%' }}
138+
placeholder="请选择(支持多选)"
139+
value={multiValue}
140+
onChange={(val) => setMultiValue(val as OptionItem[])}
141+
request={fetchSelectData}
142+
pageSize={10}
143+
maxTagCount={5}
144+
/>
145+
</div>
146+
147+
<Space>
148+
<Button type="primary" onClick={handleResetMulti}>
149+
回填跨页数据 (ID: 15, 25, 35)
150+
</Button>
151+
<Button danger onClick={handleClearMulti}>
152+
清空
153+
</Button>
154+
</Space>
155+
156+
<div style={{ color: '#666', fontSize: 12 }}>
157+
<p>数据分布:</p>
158+
<ul>
159+
<li>第一页:ID 1-10</li>
160+
<li>第二页:ID 11-20(包含 15)</li>
161+
<li>第三页:ID 21-30(包含 25)</li>
162+
<li>第四页:ID 31-40(包含 35)</li>
163+
<li>...</li>
164+
</ul>
165+
</div>
166+
</Space>
167+
</Card>
168+
</Space>
169+
</div>
170+
);
171+
}

src/components/GSelect/index.md

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +0,0 @@
1-
---
2-
title: GSelect # 组件的标题,会在菜单侧边栏展示
3-
toc: content # 在页面右侧展示锚点链接
4-
# group: # 分组
5-
# title: 高级组件 # 所在分组的名称
6-
# order: 1 # 分组排序,值越小越靠前
7-
---
8-
9-
# GSelect
10-
11-
This is an example component.
12-
13-
<!-- ```jsx
14-
import { GSelect } from 'gyc-components';
15-
16-
export default () => <GSelect />;
17-
``` -->
18-
19-
<code src="./demo/base.tsx" description="demo 描述">基础用法</code>
20-
21-
<code src="./demo/SelectWithScroll.tsx" description="滚动加载更多">滚动加载更多</code>
22-
23-
## API

0 commit comments

Comments
 (0)