Skip to content

Commit

Permalink
✨ feat: add field select
Browse files Browse the repository at this point in the history
  • Loading branch information
rdmclin2 committed Jul 24, 2023
1 parent 316a4b6 commit 0b52350
Show file tree
Hide file tree
Showing 5 changed files with 274 additions and 1 deletion.
49 changes: 49 additions & 0 deletions src/FieldSelect/demos/basic.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import type { FieldSelectOptionType } from '@ant-design/pro-editor';
import { APIFieldType, FieldSelect } from '@ant-design/pro-editor';

const Demo = () => {
const options: FieldSelectOptionType[] = [
{
label: 'orderId',
value: 'orderId',
type: APIFieldType.integer,
},
{
label: 'orderNumber',
value: 'orderNumber',
type: APIFieldType.string,
},
{
label: 'orderMoney',
value: 'orderMoney',
type: APIFieldType.integer,
},
{
label: 'productName',
value: 'productName',
type: APIFieldType.string,
},
{
label: 'productComment',
value: 'productComment',
type: APIFieldType.string,
},
{
label: 'orderStatus',
value: 'orderStatus',
type: APIFieldType.string,
},
];

return (
<>
<FieldSelect
onChange={(values) => console.log(values)}
options={options}
defaultValue={'orderId'}
/>
</>
);
};

export default Demo;
35 changes: 35 additions & 0 deletions src/FieldSelect/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
---
title: FieldSelect 字段选择器
group: API 相关组件
---

# FieldSelect 字段选择器

## 何时使用

扩展普通选择器,当要选择的是字段时,加上字段类型。

## 代码演示

### 普通使用

<code src="./demos/basic.tsx" ></code>

## API

> 其他属性参考 antd `Select` 组件。
| 参数 | 说明 | 类型 | 默认值 |
| :------- | :----- | :-------------------------- | :----- |
| options | 选项值 | 参考`FieldSelectOptionType` | - |
| onChange | 回调 | (value: string) => void | - |
| value || string | - |

### FieldSelectOptionType 选项类型

| 参数 | 说明 | 类型 | 默认值 |
| :---------- | :------- | :---------------- | :----- |
| type | 字段类型 | 参考字段类型枚举 | - |
| label | 字段名 | `React.ReactNode` | - |
| description | 字段描述 | `React.ReactNode` | - |
| value | 字段标识 | string | - |
154 changes: 154 additions & 0 deletions src/FieldSelect/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
/**
* OneAPI 接口地址: https://oneapi.alipay.com/app/oneapitwa/tag/doc/master
*/
import {
APIFieldType,
ActionIcon,
FieldTitle,
Input,
Select,
getPrefixCls,
} from '@ant-design/pro-editor';
import type { DefaultOptionType, SelectProps } from 'antd/es/select';
import classNames from 'classnames';
import { useState } from 'react';
import useMergedState from 'use-merge-value';

import { PlusOutlined } from '@ant-design/icons';

import { useStyle } from './style';

export interface FieldSelectOptionType extends DefaultOptionType {
/**
* API 字段类型
*/
type?: APIFieldType | string;
/**
* 字段描述
*/
description?: React.ReactNode;
}

export interface FieldSelectProps extends SelectProps {
/**
* @description 自定义前缀
* @ignore
*/
prefixCls?: string;
/**
* 配置项
*/
options?: FieldSelectOptionType[];
/**
* 类名
*/
className?: string;
/**
* 样式
*/
style?: React.CSSProperties;
/**
* 变更后的回调
*/
onChange?: (string) => void;
/**
* 初始值
*/
value?: string;
/**
* 是否显示自定义字段
* @default true
*/
showCustomField?: boolean;
}

const FieldSelect: React.FC<FieldSelectProps> = (props) => {
const {
style,
className,
value: propsValue,
prefixCls: customizePrefixCls,
options,
onChange,
showCustomField = true,
...restProps
} = props;

const [name, setName] = useState('');
const [controlValue, setControlValue] = useMergedState(undefined, {
value: propsValue,
onChange,
});
const [open, setOpen] = useState(false);

const prefixCls = getPrefixCls('field-select', customizePrefixCls);

const { styles } = useStyle(prefixCls);

const onNameChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setName(event.target.value);
};

const onSelectChange = (selectedValue: string) => {
setControlValue(selectedValue);
};

const addItem = (e: any) => {
e.preventDefault();
if (name) {
setControlValue(name);
setName('');
setOpen(false);
}
};

return (
<Select
options={(options || []).map((item: FieldSelectOptionType) => {
const { label, value, type, description } = item;
return {
label: <FieldTitle type={type} title={label} description={description} />,
value,
key: value,
};
})}
style={style}
className={classNames(className, styles.select)}
value={controlValue}
onChange={onSelectChange}
open={open}
onDropdownVisibleChange={(isOpen) => {
setOpen(isOpen);
}}
dropdownRender={(menu) => (
<>
{menu}
{showCustomField && (
<div className={styles.extra}>
<Input
placeholder="自定义字段名"
value={name}
className={styles.extraInput}
onChange={onNameChange}

Check failure on line 132 in src/FieldSelect/index.tsx

View workflow job for this annotation

GitHub Actions / test

Type '(event: React.ChangeEvent<HTMLInputElement>) => void' is not assignable to type '(value: string) => void'.
size="small"
onPressEnter={(e) => {
e.stopPropagation();
addItem(e);
}}
/>
<ActionIcon
title={'找不到字段时可以自定义添加'}
className={styles.extraAction}
icon={<PlusOutlined />}
onClick={addItem}
/>
</div>
)}
</>
)}
{...restProps}
/>
);
};

export default FieldSelect;
34 changes: 34 additions & 0 deletions src/FieldSelect/style.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { createStyles, css, cx } from '@ant-design/pro-editor';

export const useStyle = createStyles(({ token }, prefixCls: string) => {
return {
select: cx(
`${prefixCls}`,
css({
width: '100%',
}),
),
extra: cx(
`${prefixCls}-extra`,
css({
display: 'flex',
alignItems: 'center',
padding: `${token.paddingXXS}px ${token.paddingXS}px`,
}),
),

extraInput: cx(
`${prefixCls}-extra-input`,
css({
marginRight: token.marginXXS,
}),
),

extraAction: cx(
`${prefixCls}-extra-action`,
css({
flexShrink: 0,
}),
),
};
});
3 changes: 2 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ export { default as ErrorBoundary } from './ErrorBoundary';
export { ExcelTable } from './ExcelTable';
export type { ExcelTableProps, ExcelTableStore, TableData } from './ExcelTable';
export { default as FieldIcon } from './FieldIcon';

export * from './FieldSelect';
export { default as FieldSelect } from './FieldSelect';
export { default as FieldTitle } from './FieldTitle';
export { default as FreeCanvas } from './FreeCanvas';
export type { FreeCanvasProps } from './FreeCanvas';
Expand Down

0 comments on commit 0b52350

Please sign in to comment.