This commit is contained in:
2026-04-25 16:36:34 +08:00
commit db90e7579b
1876 changed files with 189777 additions and 0 deletions

View File

@@ -0,0 +1,21 @@
import { getValidateStatus } from '../utils';
describe('getValidateStatus', () => {
test('enter undefined', () => {
const status = getValidateStatus(undefined);
expect(status).toBe('');
});
test('enter empty string', () => {
const status = getValidateStatus('');
expect(status).toBe('');
});
test('enter string', () => {
const status = getValidateStatus('any string');
expect(status).toBe('error');
});
});

View File

@@ -0,0 +1,87 @@
import React, { useMemo } from 'react';
import {
FastifyForm,
regField,
FastifyFormContainerComponent,
regFormContainer,
} from 'react-fastify-form';
import { Form, Button } from 'antd';
import { FastifyFormText } from './types/Text';
import { FastifyFormTextArea } from './types/TextArea';
import { FastifyFormPassword } from './types/Password';
import { FastifyFormSelect } from './types/Select';
import { FastifyFormCheckbox } from './types/Checkbox';
import { FastifyFormCustom } from './types/Custom';
regField('text', FastifyFormText);
regField('textarea', FastifyFormTextArea);
regField('password', FastifyFormPassword);
regField('select', FastifyFormSelect);
regField('checkbox', FastifyFormCheckbox);
regField('custom', FastifyFormCustom);
let webFastifyFormConfig = {
submitLabel: 'Submit',
};
export function setWebFastifyFormConfig(config: typeof webFastifyFormConfig) {
webFastifyFormConfig = {
...webFastifyFormConfig,
...config,
};
}
const WebFastifyFormContainer: FastifyFormContainerComponent = React.memo(
(props) => {
const layout = props.layout;
const suffixElement = props.extraProps?.suffixElement;
const submitButtonRender = useMemo(() => {
return (
<Form.Item
wrapperCol={
layout === 'vertical'
? { xs: 24 }
: { sm: 24, md: { span: 16, offset: 8 } }
}
>
<Button
loading={props.loading}
type="primary"
size="large"
htmlType="button"
style={{ width: '100%' }}
onClick={() => props.handleSubmit()}
disabled={props.canSubmit === false}
>
{props.submitLabel ?? webFastifyFormConfig.submitLabel}
</Button>
</Form.Item>
);
}, [
props.loading,
props.handleSubmit,
props.canSubmit,
props.submitLabel,
layout,
]);
return (
<Form
layout={layout}
labelCol={layout === 'vertical' ? { xs: 24 } : { sm: 24, md: 8 }}
wrapperCol={layout === 'vertical' ? { xs: 24 } : { sm: 24, md: 16 }}
>
{props.children}
{suffixElement}
{submitButtonRender}
</Form>
);
}
);
WebFastifyFormContainer.displayName = 'WebFastifyFormContainer';
regFormContainer(WebFastifyFormContainer);
export const WebMetaForm = FastifyForm;
(WebMetaForm as any).displayName = 'WebMetaForm';

View File

@@ -0,0 +1,27 @@
import React from 'react';
import { Form, Checkbox } from 'antd';
import type { FastifyFormFieldComponent } from 'react-fastify-form';
import { getValidateStatus } from '../utils';
export const FastifyFormCheckbox: FastifyFormFieldComponent = React.memo(
(props) => {
const { name, label, value, onChange, error } = props;
return (
<Form.Item
label={label}
validateStatus={getValidateStatus(error)}
help={error}
>
<Checkbox
name={name}
checked={Boolean(value)}
onChange={(e) => onChange(e.target.checked)}
>
{label}
</Checkbox>
</Form.Item>
);
}
);
FastifyFormCheckbox.displayName = 'FastifyFormCheckbox';

View File

@@ -0,0 +1,20 @@
import React from 'react';
import { Form } from 'antd';
import type {
FastifyFormFieldComponent,
FastifyFormFieldProps,
} from 'react-fastify-form';
import { CustomField } from 'react-fastify-form';
export const FastifyFormCustom: FastifyFormFieldComponent<{
render: (props: FastifyFormFieldProps) => React.ReactNode;
}> = React.memo((props) => {
const { label } = props;
return (
<Form.Item label={label}>
<CustomField {...props} />
</Form.Item>
);
});
FastifyFormCustom.displayName = 'FastifyFormCustom';

View File

@@ -0,0 +1,39 @@
import React from 'react';
import { Input, Form } from 'antd';
import type { FastifyFormFieldComponent } from 'react-fastify-form';
import { getValidateStatus } from '../utils';
export const FastifyFormPassword: FastifyFormFieldComponent = React.memo(
(props) => {
const {
name,
label,
value,
onChange,
onBlur,
error,
maxLength,
placeholder,
} = props;
return (
<Form.Item
label={label}
validateStatus={getValidateStatus(error)}
help={error}
>
<Input.Password
name={name}
type="password"
size="large"
maxLength={maxLength}
placeholder={placeholder}
value={value}
onChange={(e) => onChange(e.target.value)}
onBlur={onBlur}
/>
</Form.Item>
);
}
);
FastifyFormPassword.displayName = 'FastifyFormPassword';

View File

@@ -0,0 +1,43 @@
import React, { useEffect } from 'react';
import { Select, Form } from 'antd';
import _get from 'lodash/get';
import _isNil from 'lodash/isNil';
import type { FastifyFormFieldComponent } from 'react-fastify-form';
const Option = Select.Option;
interface FastifyFormSelectOptionsItem {
label: string;
value: string;
}
export const FastifyFormSelect: FastifyFormFieldComponent<{
options: FastifyFormSelectOptionsItem[];
}> = React.memo((props) => {
const { name, label, value, onChange, onBlur, options } = props;
useEffect(() => {
if (_isNil(value) || value === '') {
// 如果没有值的话则自动设置默认值
onChange(_get(options, [0, 'value']));
}
}, []);
return (
<Form.Item label={label}>
<Select
size="large"
value={value}
onChange={(value) => onChange(value)}
onBlur={onBlur}
>
{options.map((option, i) => (
<Option key={`${option.value}${i}`} value={option.value}>
{option.label}
</Option>
))}
</Select>
</Form.Item>
);
});
FastifyFormSelect.displayName = 'FastifyFormSelect';

View File

@@ -0,0 +1,38 @@
import React from 'react';
import { Input, Form } from 'antd';
import type { FastifyFormFieldComponent } from 'react-fastify-form';
import { getValidateStatus } from '../utils';
export const FastifyFormText: FastifyFormFieldComponent = React.memo(
(props) => {
const {
name,
label,
value,
onChange,
onBlur,
error,
maxLength,
placeholder,
} = props;
return (
<Form.Item
label={label}
validateStatus={getValidateStatus(error)}
help={error}
>
<Input
name={name}
size="large"
maxLength={maxLength}
placeholder={placeholder}
value={value}
onChange={(e) => onChange(e.target.value)}
onBlur={onBlur}
/>
</Form.Item>
);
}
);
FastifyFormText.displayName = 'FastifyFormText';

View File

@@ -0,0 +1,38 @@
import React from 'react';
import { Input, Form } from 'antd';
import type { FastifyFormFieldComponent } from 'react-fastify-form';
import { getValidateStatus } from '../utils';
export const FastifyFormTextArea: FastifyFormFieldComponent = React.memo(
(props) => {
const {
name,
label,
value,
onChange,
onBlur,
error,
maxLength,
placeholder,
} = props;
return (
<Form.Item
label={label}
validateStatus={getValidateStatus(error)}
help={error}
>
<Input.TextArea
name={name}
rows={4}
maxLength={maxLength}
placeholder={placeholder}
value={value}
onChange={(e) => onChange(e.target.value)}
onBlur={onBlur}
/>
</Form.Item>
);
}
);
FastifyFormTextArea.displayName = 'FastifyFormTextArea';

View File

@@ -0,0 +1,10 @@
/**
* 获取校验状态
*/
export function getValidateStatus(error: string | undefined): 'error' | '' {
if (error === undefined || error === '') {
return '';
} else {
return 'error';
}
}