Skip to content

Commit 141221d

Browse files
committed
fix(Form): 增加自定义布局Form.Item子组件
1 parent aec05fc commit 141221d

File tree

7 files changed

+100
-7
lines changed

7 files changed

+100
-7
lines changed

packages/core/src/Form/README.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,45 @@ const FormComponent = Form.create(FormDemo)
268268
export default FormComponent;
269269
```
270270

271+
### Form.Item
272+
273+
<!--DemoStart-->
274+
```jsx mdx:preview&background=#bebebe29
275+
import React from 'react';
276+
import { SafeAreaView,TextInput } from 'react-native';
277+
import { Form } from '@uiw/react-native';
278+
279+
const Input = ({ value, onChange, ...others }) => {
280+
return (
281+
<TextInput
282+
value={value}
283+
onChangeText={(value) => {
284+
onChange?.(value);
285+
}}
286+
{...others}
287+
/>
288+
);
289+
};
290+
291+
const FormDemo = () => {
292+
const form = Form.useForm();
293+
const watch = {
294+
name: (value) => console.log('value', value)
295+
}
296+
return (
297+
<SafeAreaView>
298+
<Form type="custom" form={form} watch={watch} changeValidate={true}>
299+
<Form.Item required field="name" name="姓名" validate={(val) => (!val ? '请输入姓名' : '')}>
300+
<Input placeholder='请输入' />
301+
</Form.Item>
302+
</Form>
303+
</SafeAreaView>
304+
);
305+
};
306+
export default FormDemo
307+
```
308+
<!--End-->
309+
271310
### Props
272311
273312
| 参数 | 说明 | 类型 | 默认值 |
@@ -276,10 +315,12 @@ export default FormComponent;
276315
| `form` | 经 Form.useForm() 创建的 form 控制实例,不提供时会自动创建 | FormInstance<`FormData`, `FieldValue`, `FieldKey`> | - |
277316
| `initialValues` | 表单默认值,只有初始化以及重置时生效 | Partial<`FormData`> | - |
278317
| `mode` | 支持默认和卡片两种模式 | `default` \| `card` | | default |
318+
| `type` | 表单布局模式 | `json` \| `custom` | `json` |
279319
| `changeValidate` | 表单是否在onChange时进行验证 | boolean | false |
280320
| `watch` | 监听表单字段变化 | Partial<Record<string, (value: unknown) => void>> | - |
281321
| `customComponentList` | 自定义组件 | Partial<Record<string, JSX.Element>> | - |
282322
323+
283324
### FormItemsProps
284325
285326
| 参数 | 说明 | 类型 | 默认值 |

packages/core/src/Form/comps/label.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import Flex from '../../Flex';
33
import { FormItemsProps } from '../types';
44
import { Text, StyleSheet } from 'react-native';
55

6-
const Label = ({ v }: { v: FormItemsProps }) => {
6+
const Label = ({ v }: { v: Partial<FormItemsProps> }) => {
77
return (
88
<Flex>
99
{v.required && <Text style={{ color: 'red', marginRight: 5 }}>*</Text>}

packages/core/src/Form/comps/tip.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { Context } from '../hooks/context';
33
import { FormItemsProps } from '../types';
44
import { Text } from 'react-native';
55

6-
const Tip = ({ v }: { v: FormItemsProps }) => {
6+
const Tip = ({ v }: { v: Partial<FormItemsProps> & { field: string } }) => {
77
const {
88
innerMethods: { store = {}, validator },
99
} = useContext(Context);

packages/core/src/Form/form.tsx

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,11 @@ const Form = (baseProps: FormProps) => {
1919
form,
2020
initialValues = {},
2121
mode = 'default',
22+
type = 'json',
2223
watch,
2324
customComponentList = {},
2425
changeValidate = false,
26+
children,
2527
} = baseProps;
2628

2729
const isMount = useRef<boolean>();
@@ -57,11 +59,7 @@ const Form = (baseProps: FormProps) => {
5759
changeValidate: changeValidate,
5860
};
5961

60-
return (
61-
<Provider contextProps={contextProps}>
62-
<FormItems schema={schema} />
63-
</Provider>
64-
);
62+
return <Provider contextProps={contextProps}>{type === 'json' ? <FormItems schema={schema} /> : children}</Provider>;
6563
};
6664

6765
export default Form;
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import React, { useContext } from 'react';
2+
import { View } from 'react-native';
3+
import { Context } from './hooks/context';
4+
import { KeyType, FormItemsProps } from './types';
5+
import Label from './comps/label';
6+
import Tip from './comps/tip';
7+
import Container from './comps/container';
8+
import styles from './styles';
9+
10+
const formchildItem = (props: Partial<FormItemsProps> & { field: string; children: React.ReactElement }) => {
11+
const { field, name = '', required = false, validate, children } = props;
12+
const {
13+
mode,
14+
innerMethods: { store = {}, updateStore, innerValidate },
15+
watch,
16+
changeValidate,
17+
} = useContext(Context);
18+
19+
const change = (field: KeyType, value: unknown) => {
20+
updateStore?.({ store: { ...store, [field]: value } });
21+
watch && watch[field]?.(value);
22+
};
23+
24+
const _renderComponent = (children: React.ReactElement) => {
25+
return React.isValidElement(children)
26+
? React.cloneElement(children, {
27+
value: store[field],
28+
onChange: (value: unknown) => {
29+
change(field, value);
30+
if (changeValidate) innerValidate();
31+
},
32+
} as any)
33+
: null;
34+
};
35+
return (
36+
<Container mode={mode}>
37+
<View style={styles.form_items_container}>
38+
<View style={[styles.form_items, styles.border_none]}>
39+
<Label v={{ name: name, required: required }} />
40+
{_renderComponent(children)}
41+
<Tip v={{ validate: validate, field: field }} />
42+
</View>
43+
</View>
44+
</Container>
45+
);
46+
};
47+
48+
export default formchildItem;

packages/core/src/Form/index.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import Form from './form';
2+
import FormChildItem from './formchildItem';
23
import create from './createForm';
34
import useForm from './hooks/useForm';
45

@@ -7,11 +8,13 @@ type RefForm = typeof Form;
78
export interface FormComponent extends RefForm {
89
useForm: typeof useForm;
910
create: typeof create;
11+
Item: typeof FormChildItem;
1012
}
1113

1214
const FormComp: FormComponent = Form as FormComponent;
1315

1416
FormComp.useForm = useForm;
1517
FormComp.create = create;
18+
FormComp.Item = FormChildItem;
1619

1720
export default FormComp;

packages/core/src/Form/types/index.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { RulesOption } from '@validator.tool/hook';
2+
import React from 'react';
23
import Validator from 'validator.tool';
34

45
type KeyType = string | number | symbol;
@@ -34,6 +35,8 @@ interface FormProps<FormData = any, FieldValue = FormData[keyof FormData], Field
3435
watch?: Partial<Record<string, (value: unknown) => void>>;
3536
customComponentList?: Partial<Record<string, JSX.Element>>;
3637
changeValidate?: boolean;
38+
type?: 'json' | 'custom';
39+
children?: React.ReactElement;
3740
}
3841

3942
interface actionProps {

0 commit comments

Comments
 (0)