Skip to content

Commit e9314ff

Browse files
committed
v1.0
1 parent edac336 commit e9314ff

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+1696
-72019
lines changed

README.md

Lines changed: 286 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2,42 +2,298 @@
22

33
`npm install --save react-widget-form`
44

5+
```ts
6+
import {
7+
Form,
8+
FormItem,
9+
NativeInput,
10+
FormContext,
11+
FormItemContext,
12+
useForm,
13+
useFormItem
14+
} from 'react-widget-form'
15+
16+
```
17+
518
## Props
619

20+
### Types
21+
22+
```ts
23+
type ValidateTriggerType = "change" | "blur";
24+
25+
type Validator = (
26+
value: any,
27+
formValue: {}
28+
) => boolean | string | Error | Promise;
29+
30+
type InvalidError = {
31+
name: string;
32+
message: any;
33+
};
34+
35+
```
36+
737
### Form
8-
| 参数 | 说明 | 类型 | 默认值 |
9-
| --- | --- | --- | --- |
10-
| prefixCls | 组件CSS样式前缀 | string | rw-form |
11-
| className | 组件className属性 | string | - |
12-
| style | 组件style属性 | React.CSSProperties | - |
13-
| path2obj | 是否启用lodash.get、是否启用lodash.set来获取、设置formValue的值 | boolean | true |
14-
| defaultFormValue | 表单默认数据 | object | {} |
15-
| formValue | 表单数据`受控` | object | |
16-
| validateDelay |- | number | |
17-
| validateTrigger |- | string | |
18-
| validateFieldsAndScroll |- | string | |
19-
| showMessage |- | string | |
20-
| component | 表单默认元素 | React.Element | form |
21-
| rules | 验证规则 | object\|array\|function | null |
22-
| labelWidth | 表单标签域宽度 | number\|string | - |
23-
| labelPosition | 表单标签域位置 | `top` `left` `right` | left |
24-
| alignItems | 表单控制表单项的alignItems的属性 | string | center |
25-
| inline | 行内表单模式 | function(value,e) | |
26-
| onSubmit | 只有当原生表单的onSubmit事件 | function(e) | |
27-
| onChange | 按下回车的回调 | function(formValue, e) | |
28-
| getFormItemInputProps | 自定义表单输入框控件的属性 | function(e) | |
2938

39+
```ts
40+
children: ((form: Form) => React.ReactNode) | React.ReactNode;
41+
prefixCls?: string;
42+
className?: string;
43+
style?: React.CSSProperties;
44+
path2obj?: boolean;
45+
defaultFormValue?: {};
46+
formValue?: {};
47+
getDefaultFieldValue?: (name: string) => any;
48+
renderFieldExtra?: (
49+
component: FormItem,
50+
name: string
51+
) => React.ReactNode;
52+
validators?: {
53+
[name: string]: Validator | Validator[];
54+
};
55+
validateDelay?: number;
56+
validateTrigger?: ValidateTriggerType | ValidateTriggerType[];
57+
asyncTestDelay?: number;
58+
component?: React.ElementType;
59+
labelWidth?: string | number;
60+
labelClassName?: string;
61+
labelStyle?: React.CSSProperties;
62+
labelPosition?: "top" | "left";
63+
controlStyle?: React.CSSProperties;
64+
controlClassName?: string;
65+
clearErrorOnFocus?: boolean;
66+
inline?: boolean;
67+
onSubmit?: (e: React.SyntheticEvent) => void;
68+
onChange?: (formValue: {}) => void;
69+
getInputProps?: (component: FormItem, name: string) => {};
70+
```
3071

3172
### FormItem
32-
| 参数 | 说明 | 类型 | 默认值 |
33-
| --- | --- | --- | --- |
34-
| - | - | - | - |
35-
| - | - | - |
3673

37-
### NativeField
38-
| 参数 | 说明 | 类型 | 默认值 |
39-
| --- | --- | --- | --- |
40-
| component | 接收`value` `onChange(e)`的控件 | React.Element | input |
74+
```ts
75+
children:
76+
| ((props: FormItemChildProps, item: FormItem) => React.ReactNode)
77+
| React.ReactNode;
78+
prefixCls?: string;
79+
name?: string;
80+
className?: string;
81+
style?: React.CSSProperties;
82+
validator?: Validator | Validator[];
83+
label?: React.ReactNode;
84+
labelFor?: string;
85+
labelWidth?: string | number;
86+
labelClassName?: string;
87+
labelStyle?: React.CSSProperties;
88+
labelPosition?: "top" | "left";
89+
controlStyle?: React.CSSProperties;
90+
controlClassName?: string;
91+
required?: boolean;
92+
requiredMessage?: string;
93+
clearErrorOnFocus?: boolean;
94+
normalize?: (value: any) => any;
95+
renderExtra?: (component: FormItem) => React.ReactNode;
96+
validateDelay?: number;
97+
validateTrigger?: ValidateTriggerType | ValidateTriggerType[];
98+
inline?: boolean;
99+
onChange?: (value: any) => void;
100+
onFocus?: (e: React.SyntheticEvent) => void;
101+
onBlur?: (e: React.SyntheticEvent) => void;
102+
```
103+
104+
FormItem的会覆盖child的部分属性,覆盖属性如下:
105+
106+
如果child的值发生改变必须要调用`onChange`来更新`Form`的状态,同样child发生`focus` `blur`最好也要调用`onFocus` `onBlur`
107+
108+
- 【重要】 `onChange` 会触发 `validateTrigger` 及 Form的`onChange`
109+
- `onFocus` 会触发`clearErrorOnFocus`行为
110+
- `onBlur` 会触发`validateTrigger`行为
111+
112+
```ts
113+
{
114+
value: any;
115+
onChange: (value: any) => void;
116+
onFocus: (e: React.SyntheticEvent) => void;
117+
onBlur: (e: React.SyntheticEvent) => void;
118+
[propName: string]: any;
119+
}
120+
```
121+
122+
由于FormItem的`onChange`接收的是一个值,所以不能直接使用原生表单组件或其他并非直接提供值的组件,例如:
123+
```jsx
124+
//这是错误的,onChange会将Event当作值赋值给formValue,可能导致预期不一致
125+
//ERROR
126+
<FormItem name="email">
127+
<input type="text" />
128+
</FormItem>
129+
130+
//正确写法一:
131+
<FormItem name="email">
132+
{
133+
(props) => {
134+
135+
return <input {...props} type="text" onChange={e => props.onChange(e.target.value)} />
136+
}
137+
}
138+
</FormItem>
139+
140+
//正确写法二:
141+
function Input(props){
142+
return <input {...props} type="text" onChange={e => props.onChange(e.target.value)} />
143+
}
144+
<FormItem name="email">
145+
<Input />
146+
</FormItem>
147+
148+
//正确写法三,使用NativeInput:
149+
<FormItem name="email">
150+
<NativeInput component="input" />
151+
</FormItem>
152+
```
153+
154+
155+
### NativeInput
156+
157+
```ts
158+
component: React.ElementType;
159+
onChange?: (value: any) => void;
160+
inputRef?: (dom: any) => void;
161+
[others: string]: any;
162+
```
163+
164+
> others 会传递给component组件
165+
166+
`NativeInput`是为了解决`onChange`返回事件的情况下做了简单的处理,封装代码如下:
167+
```js
168+
export default function NativeInput(props) {
169+
const {
170+
component: Component = "input",
171+
value,
172+
inputRef,
173+
onChange,
174+
...others
175+
} = props;
176+
177+
const onInputChange = e => {
178+
const value = e.target.value;
179+
onChange && onChange(value, e);
180+
};
181+
182+
return (
183+
<Component
184+
ref={inputRef}
185+
onChange={onInputChange}
186+
value={value}
187+
{...others}
188+
/>
189+
);
190+
}
191+
192+
```
193+
194+
## Methods
195+
196+
### Form
197+
```ts
198+
{
199+
getValue(name: string): any;
200+
setValue(
201+
name: string,
202+
value: any,
203+
callback: (formValue: {}) => void
204+
): void;
205+
setValues(formValue: {}, callback: (formValue: {}) => void): void;
206+
hasError(name: string): boolean;
207+
getError(name: string): any;
208+
cleanError(name: string): void;
209+
setError(name: string): void;
210+
cleanErrors(): void;
211+
setErrors(errors: {}): void;
212+
isFieldValidating(name: string): boolean;
213+
isValidating(): boolean;
214+
validateField(
215+
name: string,
216+
callback: (errors: null | InvalidError[], formValue: {}) => void
217+
): boolean;
218+
validate(
219+
callback: (errors: null | InvalidError[], formValue: {}) => void
220+
): boolean;
221+
validateAndScroll(
222+
callback: (errors: null | InvalidError[], formValue: {}) => void
223+
): boolean;
224+
}
225+
```
226+
227+
### FormItem
228+
```ts
229+
{
230+
getDOM(): any;
231+
getForm(): Form;
232+
getValue(): any;
233+
setValue(value: any, callback: (formValue: {}) => void): void;
234+
hasError(): boolean;
235+
getError(): any;
236+
cleanError(): void;
237+
setError(message: any): void;
238+
isValidating(): boolean;
239+
validate(
240+
callback: (errors: null | InvalidError[], formValue: {}) => void
241+
): boolean;
242+
}
243+
```
244+
245+
## hooks
246+
247+
- useForm
248+
- useFormItem
249+
250+
251+
## 基础样式
252+
253+
```scss
254+
$form-item-cls: nex-form-item;
255+
256+
.#{$form-item-cls} {
257+
display: flex;
258+
259+
&-inline {
260+
display: inline-flex;
261+
}
262+
263+
&-label {
264+
text-align: right;
265+
flex: none;
266+
}
267+
268+
&-top {
269+
display: block;
270+
}
271+
272+
&-top.#{$form-item-cls}-inline {
273+
display: inline-block;
274+
vertical-align: top;
275+
}
276+
277+
&-top &-label {
278+
text-align: left;
279+
display: block;
280+
}
281+
282+
&-control {
283+
position: relative;
284+
flex: 1;
285+
}
286+
287+
&.is-required &-label:before {
288+
content: "*";
289+
display: inline-block;
290+
margin-right: 4px;
291+
font-family: SimSun;
292+
color: red;
293+
}
294+
}
295+
296+
```
297+
41298

42-
其余属性传递给component。
43299

0 commit comments

Comments
 (0)