Skip to content

Commit a67879b

Browse files
committed
feat(Form): 新增动态表单
1 parent 8cf44de commit a67879b

File tree

9 files changed

+379
-50
lines changed

9 files changed

+379
-50
lines changed

example/examples/src/routes/Form/index.tsx

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,23 @@ const FormDemo = () => {
105105
field: 'render',
106106
name: '自定义',
107107
},
108+
{
109+
type: 'cardList',
110+
field: 'cardList',
111+
name: '动态list',
112+
items: [
113+
{
114+
type: 'input',
115+
field: 'cardListItem1',
116+
name: '动态表单项1',
117+
},
118+
{
119+
type: 'input',
120+
field: 'cardListItem2',
121+
name: '动态表单项2',
122+
},
123+
],
124+
},
108125
];
109126
const initialValues = {name: '王滴滴'};
110127

packages/core/src/Card/Card.Actions.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,14 @@ export type CardActionsProps = {
2222
actionsTextStyle?: StyleProp<TextStyle>;
2323
}>;
2424
actionsContainerStyle?: StyleProp<ViewStyle>;
25+
driver?: boolean;
2526
children?: React.ReactNode;
2627
};
2728

28-
const CardActions = ({ actions = [], actionsContainerStyle, children }: CardActionsProps) => {
29+
const CardActions = ({ actions = [], actionsContainerStyle, children, driver = true }: CardActionsProps) => {
2930
return (
3031
<Fragment>
31-
<Divider style={StyleSheet.flatten({ marginTop: 15 })} lineStyle={{ backgroundColor: '#e6e6e6' }} />
32+
{driver && <Divider style={StyleSheet.flatten({ marginTop: 15 })} lineStyle={{ backgroundColor: '#e6e6e6' }} />}
3233
{React.isValidElement(children) ? React.cloneElement(children) : null}
3334
<View style={[styles.actionsContainer, actionsContainerStyle]}>
3435
{map(actions, (item, index) => {

packages/core/src/Form/README.md

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ const FormDemo = () => {
2929
```
3030
<!--End-->
3131

32-
### 自定义验证提交
32+
### form.validateFields进行表单验证提交
3333

3434
<!--DemoStart-->
3535
```jsx
@@ -70,7 +70,7 @@ const FormDemo = () => {
7070
```
7171
<!--End-->
7272

73-
### 自定义表单组件
73+
### customComponentList自定义表单组件
7474

7575
<!--DemoStart-->
7676
```jsx
@@ -107,7 +107,7 @@ const FormDemo = () => {
107107
```
108108
<!--End-->
109109

110-
### 监听表单变化
110+
### watch监听表单变化
111111

112112
<!--DemoStart-->
113113
```jsx
@@ -141,6 +141,46 @@ const FormDemo = () => {
141141
```
142142
<!--End-->
143143

144+
### 动态表单list
145+
146+
> ⚠️ 警告:目前仅能嵌套一层cardList<!--rehype:style=background: #F08800; color: #fff;-->
147+
<!--rehype:style=border-left: 8px solid #ffe564;background-color: #ffe56440;padding: 12px 16px;-->
148+
149+
<!--DemoStart-->
150+
```jsx
151+
import { SafeAreaView,Toast } from 'react-native';
152+
import { Form } from '@uiw/react-native';
153+
154+
const FormDemo = () => {
155+
const form = Form.useForm({
156+
changeValidate: true,
157+
});
158+
const initialValues = {name: ''};
159+
const items = [
160+
{
161+
type: 'cardList',
162+
field: 'cardList',
163+
name: '动态list',
164+
required: true,
165+
items:[
166+
{
167+
type: 'input',
168+
field: 'cardList',
169+
name: '动态list',
170+
required: true,
171+
}
172+
]
173+
}
174+
];
175+
return (
176+
<SafeAreaView>
177+
<Form form={form} formDatas={items} initialValues={initialValues} />
178+
</SafeAreaView>
179+
);
180+
};
181+
```
182+
<!--End-->
183+
144184
### FormProps
145185
```ts
146186
interface FormProps<FormData = any, FieldValue = FormData[keyof FormData], FieldKey extends KeyType = keyof FormData> {
@@ -167,9 +207,10 @@ interface FormItemsProps {
167207
name: string;
168208
validate?: RulesOption['validate'];
169209
options?: Array<{ label: string; value: KeyType | any }>;
170-
attr?: any;
210+
attr?: un;
171211
required?: boolean;
172212
render?: JSX.Element;
213+
hide?:boolean
173214
}
174215
```
175216

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import React from 'react';
2+
import Flex from '../../Flex';
3+
import { FormItemsProps } from '../types';
4+
import { Text, StyleSheet } from 'react-native';
5+
6+
const Label = ({ v }: { v: FormItemsProps }) => {
7+
return (
8+
<Flex>
9+
{v.required && <Text style={{ color: 'red', marginRight: 5 }}>*</Text>}
10+
<Text style={styles.label} {...v.attr}>
11+
{v.name}
12+
</Text>
13+
</Flex>
14+
);
15+
};
16+
17+
const styles = StyleSheet.create({
18+
label: {
19+
width: 110,
20+
fontSize: 16,
21+
color: '#434343',
22+
fontWeight: '500',
23+
marginBottom: 10,
24+
},
25+
});
26+
27+
export default Label;
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import React, { useContext } from 'react';
2+
import { Context } from '../hooks/context';
3+
import { FormItemsProps } from '../types';
4+
import { Text } from 'react-native';
5+
6+
const Tip = ({ v }: { v: FormItemsProps }) => {
7+
const {
8+
innerMethods: { store = {}, validator },
9+
} = useContext(Context);
10+
11+
const content = validator.message(v.field, store[v.field], {
12+
validate: v?.validate,
13+
});
14+
return <Text style={{ color: 'red', marginBottom: content && 10, marginTop: content && 10 }}>{content}</Text>;
15+
};
16+
17+
export default Tip;

packages/core/src/Form/formItems.tsx

Lines changed: 14 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,11 @@ import FormDatePicker from './comps/datePicker';
1111
import Stepper from '../Stepper';
1212
import TextArea from '../TextArea';
1313
import Slider from '../Slider';
14-
import Flex from '../Flex';
15-
import { View, Text, SafeAreaView, StyleSheet, TextInput } from 'react-native';
14+
import Label from './comps/label';
15+
import Tip from './comps/tip';
16+
import FormList from './formList';
17+
import { View, SafeAreaView, StyleSheet, TextInput } from 'react-native';
18+
import styles from './styles';
1619

1720
const FormItems: FC<any> = ({ formDatas = [] }) => {
1821
const {
@@ -153,11 +156,15 @@ const FormItems: FC<any> = ({ formDatas = [] }) => {
153156
/>
154157
);
155158
}
159+
if (v.type === 'cardList') {
160+
return <FormList formListValue={v} />;
161+
}
156162
// 自定义组件
157163
if (!isObjectEmpty(customComponentList) && Object.keys(customComponentList).includes(v.type)) {
158164
return React.isValidElement(customComponentList[v.type])
159165
? React.cloneElement(customComponentList[v.type], {
160166
...v.attr,
167+
value: store[v.field],
161168
onChange: (value: unknown) => {
162169
change(v.field, value);
163170
innerValidate();
@@ -168,32 +175,17 @@ const FormItems: FC<any> = ({ formDatas = [] }) => {
168175
return null;
169176
};
170177

171-
const Label = (v: FormItemsProps) => {
172-
return (
173-
<Flex>
174-
{v.required && <Text style={{ color: 'red', marginRight: 5 }}>*</Text>}
175-
<Text style={styles.label} {...v.attr}>
176-
{v.name}
177-
</Text>
178-
</Flex>
179-
);
180-
};
181-
182-
const Tip = (v: FormItemsProps) => {
183-
const content = validator.message(v.field, store[v.field], {
184-
validate: v?.validate,
185-
});
186-
return <Text style={{ color: 'red', marginBottom: content && 10, marginTop: content && 10 }}>{content}</Text>;
187-
};
188-
189178
const _render = () => {
190179
return formDatas.map((v: FormItemsProps, i: number) => {
180+
if (v.hide) {
181+
return null;
182+
}
191183
return (
192184
<View key={i} style={styles.form_items_container}>
193185
<View style={styles.form_items}>
194-
{Label(v)}
186+
<Label v={v} />
195187
{_renderComponent(v)}
196-
{Tip(v)}
188+
<Tip v={v} />
197189
</View>
198190
</View>
199191
);
@@ -203,26 +195,4 @@ const FormItems: FC<any> = ({ formDatas = [] }) => {
203195
return <SafeAreaView style={styles.warpper}>{_render()}</SafeAreaView>;
204196
};
205197

206-
const styles = StyleSheet.create({
207-
warpper: {
208-
backgroundColor: '#fff',
209-
},
210-
form_items_container: {
211-
flex: 1,
212-
},
213-
form_items: {
214-
textAlign: 'center',
215-
margin: 10,
216-
borderBottomWidth: 0.5,
217-
borderBottomColor: '#eee',
218-
},
219-
label: {
220-
width: 110,
221-
fontSize: 16,
222-
color: '#434343',
223-
fontWeight: '500',
224-
marginBottom: 10,
225-
},
226-
});
227-
228198
export default FormItems;

0 commit comments

Comments
 (0)