Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(form): add validateTrigger, setFieldValue and disabled #2772

Open
wants to merge 10 commits into
base: next
Choose a base branch
from
8 changes: 5 additions & 3 deletions src/packages/form/__tests__/form.spec.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as React from 'react'
import { render, fireEvent, waitFor } from '@testing-library/react'
import '@testing-library/jest-dom'
import { useEffect } from 'react'
import { fireEvent, render, waitFor } from '@testing-library/react'
import '@testing-library/jest-dom'
import Form, { FormInstance } from '@/packages/form'
import Input from '@/packages/input'

Expand Down Expand Up @@ -167,7 +167,9 @@ test('form set required', () => {
</Form.Item>
</Form>
)
expect(container.querySelectorAll('.required')).toHaveLength(1)
expect(
container.querySelectorAll('.nut-form-item-label-required')
).toHaveLength(1)
})

test('form set change value', async () => {
Expand Down
5 changes: 4 additions & 1 deletion src/packages/form/doc.en-US.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ import { Form } from '@nutui/nutui-react'
| name | form name | `any` | `-` |
| labelPosition | The position of the form item label | `top` \| `left` \| `right` | `right` |
| starPosition | The red star position of the required form item label | `left` \| `right` | `left` |
| disabled | Disable all form fields | `boolean` | `false` |
| validateTrigger | uniformly set the timing for fields to trigger validation | `string` \| `string[]` | `onChange` |
| onFinish | Triggered after verification is successful | `(values: any) => void` | `-` |
| onFinishFailed | Triggered when any form item fails validation | `(values: any, errorFields: any) => void` | `-` |

Expand Down Expand Up @@ -125,7 +127,8 @@ Form.useForm() creates a Form instance, which is used to manage all data states.
| --- | --- | --- |
| getFieldValue | Get the value of the corresponding field name | `(name: NamePath) => any` |
| getFieldsValue | Get values by a set of field names. Return according to the corresponding structure. Default return mounted field value, but you can use getFieldsValue(true) to get all values | `(name: NamePath \| boolean) => any` |
| setFieldsValue | set field values | `(values) => void` |
| setFieldsValue | Set the value of the form (the value will be passed directly to the form store. If you do not want the object passed in to be modified, please copy it and pass it in) | `(values) => void` |
| setFieldValue | Set the value of the corresponding field name | `<T>(name: NamePath, value: T) => void` |
oasis-cloud marked this conversation as resolved.
Show resolved Hide resolved
| resetFields | Reset form prompt state | `() => void` |
| submit | method to submit a form for validation | `Promise` |

Expand Down
5 changes: 4 additions & 1 deletion src/packages/form/doc.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ import { Form } from '@nutui/nutui-react'
| name | 表单名称 | `any` | `-` |
| labelPosition | 表单项 label 的位置 | `top` \| `left` \| `right` | `right` |
| starPosition | 必填表单项 label 的红色星标位置 | `left` \| `right` | `left` |
| validateTrigger | 统一设置字段触发验证的时机 | `string` \| `string[]` | `onChange` |
| disabled | 是否禁用 | `boolean` | `false` |
| onFinish | 校验成功后触发 | `(values: any) => void` | `-` |
| onFinishFailed | 任一表单项被校验失败后触发 | `(values: any, errorFields: any) => void` | `-` |

Expand Down Expand Up @@ -124,7 +126,8 @@ Form.useForm()创建 Form 实例,用于管理所有数据状态。
| --- | --- | --- |
| getFieldValue | 获取对应字段名的值 | `(name: NamePath) => any` |
| getFieldsValue | 获取一组字段名对应的值,会按照对应结构返回。默认返回现存字段值,当调用 getFieldsValue(true) 时返回所有值 | `(name: NamePath \| boolean) => any` |
| setFieldsValue | 设置表单的值 | `(values) => void` |
| setFieldsValue | 设置表单的值(该值将直接传入 form store 中。如果你不希望传入对象被修改,请克隆后传入) | `(values) => void` |
| setFieldValue | 设置对应字段名的值 | `<T>(name: NamePath, value: T) => void` |
| resetFields | 重置表单提示状态 | `() => void` |
| submit | 提交表单进行校验的方法 | `Promise` |

Expand Down
5 changes: 4 additions & 1 deletion src/packages/form/doc.taro.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ import { Form } from '@nutui/nutui-react-taro'
| name | 表单名称 | `any` | `-` |
| labelPosition | 表单项 label 的位置 | \`\`'top' | 'left'\` | \`'right'\`\` |
| starPosition | 必填表单项 label 的红色星标位置 | `left` \| `right` | `left` |
| validateTrigger | 统一设置字段触发验证的时机 | `string` \| `string[]` | `onChange` |
| disabled | 是否禁用 | `boolean` | `false` |
| onFinish | 校验成功后触发 | `(values: any) => void` | `-` |
| onFinishFailed | 任一表单项被校验失败后触发 | `(values: any, errorFields: any) => void` | `-` |

Expand Down Expand Up @@ -124,7 +126,8 @@ Form.useForm()创建 Form 实例,用于管理所有数据状态。
| --- | --- | --- |
| getFieldValue | 获取对应字段名的值 | `(name: NamePath) => any` |
| getFieldsValue | 获取一组字段名对应的值,会按照对应结构返回。默认返回现存字段值,当调用 getFieldsValue(true) 时返回所有值 | `(name: NamePath \| boolean) => any` |
| setFieldsValue | 设置表单的值 | `(values) => void` |
| setFieldsValue | 设置表单的值(该值将直接传入 form store 中。如果你不希望传入对象被修改,请克隆后传入) | `(values) => void` |
| setFieldValue | 设置对应字段名的值 | `<T>(name: NamePath, value: T) => void` |
| resetFields | 重置表单提示状态 | `() => void` |
| submit | 提交表单进行校验的方法 | `Promise` |

Expand Down
7 changes: 5 additions & 2 deletions src/packages/form/doc.zh-TW.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ import { Form } from '@nutui/nutui-react'
| label | 标签名 | `ReactNode` | `-` |
| labelPosition | 錶單項 label 的位置 | `top` \| `left` \| `right` | `right` |
| starPosition | 必填錶單項 label 的紅色星標位置 | `left` \| `right` | `left` |
| validateTrigger | 統一設定字段觸發驗證的時機 | `string` \| `string[]` | `onChange` |
| disabled | 是否禁用 | `boolean` | `false` |
oasis-cloud marked this conversation as resolved.
Show resolved Hide resolved
| onFinish | 校驗成功後觸發 | `(values: any) => void` | `-` |
| onFinishFailed | 任一錶單項被校驗失敗後觸發 | `(values: any, errorFields: any) => void` | `-` |

Expand All @@ -98,7 +100,7 @@ import { Form } from '@nutui/nutui-react'
| align | 對齊方式 | `flex-start` \| `center` \| `flex-end` | `flex-start` |
| valuePropName | 子節點的值的屬性,如 Checkbox 的是 'checked' | `string` | `-` |
| getValueFromEvent | 設置如何將 event 的值轉換成字段值 | `(...args: any) => any` | `-` |
| validateTrigger | 统一设置字段触发验证的时机 | `string \| string[]` | `onChange` |
| validateTrigger | 統一設定字段觸發驗證的時機 | `string \| string[]` | `onChange` |
| onClick | 點擊事件併收集子組件 Ref | `(event: React.MouseEvent, componentRef: React.MutableRefObject<any>) => void` | `-` |

### Form.Item Rule
Expand All @@ -124,7 +126,8 @@ Form.useForm()創建 Form 實例,用於管理所有數據狀態。
| --- | --- | --- |
| getFieldValue | 獲取對應字段名的值 | `(name: NamePath) => any` |
| getFieldsValue | 获取一组字段名对应的值,会按照对应结构返回。默认返回现存字段值,当调用 getFieldsValue(true) 时返回所有值 | `(name: NamePath \| boolean) => any` |
| setFieldsValue | 設置錶單的值 | `(values) => void` |
| setFieldsValue | 設定表單的值(該值將直接傳入 form store 中。如果你不希望傳入物件被修改,請複製後傳入) | `(values) => void` |
| setFieldValue | 設定對應欄位名的值 | `<T>(name: NamePath, value: T) => void` |
| resetFields | 重置錶單提示狀態 | `() => void` |
| submit | 提交錶單進行校驗的方法 | `Promise` |

Expand Down
68 changes: 0 additions & 68 deletions src/packages/form/form.scss
Original file line number Diff line number Diff line change
@@ -1,71 +1,3 @@
@import '../cellgroup/cellgroup.scss';
@import '../cell/cell.scss';
@import '../formitem/formitem.scss';

.form-layout-right .nut-form-item-label {
text-align: right;
padding-right: 24px;
white-space: nowrap;
}

.form-layout-left .nut-form-item-label {
position: relative;
text-align: left;
padding-left: 12px;
white-space: nowrap;

.required {
display: block;
line-height: 1.5;
position: absolute;
left: 0.1em;
}
}

.form-layout-top .nut-form-item {
flex-direction: column;
align-items: flex-start;
white-space: nowrap;
}

.form-layout-top .nut-form-item-label {
padding-bottom: 4px;
display: block;
padding-right: 24px;
}

.form-layout-top .nut-form-item-body {
margin-left: 0;
width: 100%;
}

[dir='rtl'] .form-layout-right .nut-form-item-label,
.nut-rtl .form-layout-right .nut-form-item-label {
text-align: left;
padding-right: 0;
padding-left: 24px;
}

[dir='rtl'] .form-layout-left .nut-form-item-label,
.nut-rtl .form-layout-left .nut-form-item-label {
text-align: right;
padding-left: 0;
padding-right: 12px;

.required {
left: auto;
right: 0.1em;
}
}

[dir='rtl'] .form-layout-top .nut-form-item-label,
.nut-rtl .form-layout-top .nut-form-item-label {
padding-right: 0;
padding-left: 24px;
}

[dir='rtl'] .form-layout-top .nut-form-item-body,
.nut-rtl .form-layout-top .nut-form-item-body {
margin-left: 0;
margin-right: 0;
}
17 changes: 14 additions & 3 deletions src/packages/form/form.taro.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React, { ReactNode } from 'react'
import { Form as TForm } from '@tarojs/components'
import classNames from 'classnames'
import { Context } from './context'
import { SECRET, useForm } from './useform.taro'
Expand All @@ -11,7 +12,9 @@ export interface FormProps extends BasicComponent {
initialValues: any
name: string
form: any
disabled: boolean
divider: boolean
validateTrigger: string | string[] | false
labelPosition: 'top' | 'left' | 'right'
starPosition: 'left' | 'right'
onFinish: (values: any) => void
Expand All @@ -22,7 +25,9 @@ const defaultProps = {
...ComponentDefaults,
labelPosition: 'right',
starPosition: 'left',
disabled: false,
divider: false,
validateTrigger: 'onChange',
onFinish: (values) => {},
onFinishFailed: (values, errorFields) => {},
} as FormProps
Expand All @@ -43,8 +48,10 @@ export const Form = React.forwardRef<FormInstance, Partial<FormProps>>(
children,
initialValues,
divider,
disabled,
onFinish,
onFinishFailed,
validateTrigger,
labelPosition,
starPosition,
form,
Expand Down Expand Up @@ -77,7 +84,7 @@ export const Form = React.forwardRef<FormInstance, Partial<FormProps>>(
}

return (
<form
<TForm
className={classNames(
classPrefix,
PositionInfo[labelPosition],
Expand All @@ -96,12 +103,16 @@ export const Form = React.forwardRef<FormInstance, Partial<FormProps>>(
}}
>
<Cell.Group divider={divider}>
<Context.Provider value={formInstance}>{children}</Context.Provider>
<Context.Provider
value={{ formInstance, labelPosition, disabled, validateTrigger }}
>
{children}
</Context.Provider>
oasis-cloud marked this conversation as resolved.
Show resolved Hide resolved
{footer ? (
<Cell className={`${classPrefix}-footer`}>{footer}</Cell>
) : null}
</Cell.Group>
</form>
</TForm>
)
}
)
Expand Down
12 changes: 11 additions & 1 deletion src/packages/form/form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ export interface FormProps extends BasicComponent {
initialValues: any
name: string
form: any
disabled: boolean
divider: boolean
validateTrigger: string | string[] | false
labelPosition: 'top' | 'left' | 'right'
starPosition: 'left' | 'right'
onFinish: (values: any) => void
Expand All @@ -22,7 +24,9 @@ const defaultProps = {
...ComponentDefaults,
labelPosition: 'right',
starPosition: 'left',
disabled: false,
divider: false,
validateTrigger: 'onChange',
onFinish: (values) => {},
onFinishFailed: (values, errorFields) => {},
} as FormProps
Expand All @@ -43,8 +47,10 @@ export const Form = React.forwardRef<FormInstance, Partial<FormProps>>(
children,
initialValues,
divider,
disabled,
onFinish,
onFinishFailed,
validateTrigger,
labelPosition,
starPosition,
form,
Expand Down Expand Up @@ -96,7 +102,11 @@ export const Form = React.forwardRef<FormInstance, Partial<FormProps>>(
}}
>
<Cell.Group divider={divider}>
<Context.Provider value={formInstance}>{children}</Context.Provider>
<Context.Provider
value={{ formInstance, labelPosition, disabled, validateTrigger }}
>
{children}
</Context.Provider>
{footer ? (
<Cell className={`${classPrefix}-footer`}>{footer}</Cell>
) : null}
Expand Down
4 changes: 3 additions & 1 deletion src/packages/form/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export interface FormItemRuleWithoutValidator {
[key: string]: any

regex?: RegExp
required?: boolean
message?: string
Expand All @@ -20,8 +21,9 @@ export interface Store {

export interface FormInstance<Values = any> {
getFieldValue: (name: NamePath) => StoreValue
setFieldValue: <T = any>(name: NamePath, value: T) => void
getFieldsValue: (nameList: NamePath[] | true) => { [key: NamePath]: any }
setFieldsValue: (value: any) => void
setFieldsValue: (value: Store) => void
resetFields: (fields?: NamePath[]) => void
submit: () => void
getInternal: (secret: string) => any
Expand Down
Loading
Loading