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 useWatch #2932

Open
wants to merge 5 commits into
base: next
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 71 additions & 0 deletions src/packages/form/__tests__/form.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import * as React from 'react'
import { useEffect } from 'react'
import { fireEvent, render, waitFor } from '@testing-library/react'
import '@testing-library/jest-dom'
import { Button, Radio, Space } from '@nutui/nutui-react'
import Form, { FormInstance } from '@/packages/form'
import Input from '@/packages/input'

Expand Down Expand Up @@ -312,3 +313,73 @@ test('no-style and render function', async () => {
expect(relatedInput).toBeTruthy()
})
})

test('useWatch', async () => {
const Demo = () => {
const [form] = Form.useForm()
const account = Form.useWatch('account', form)
const loginMethod = Form.useWatch('loginMethod', form)
return (
<Form
form={form}
initialValues={{ loginMethod: 'mobile', account: '123' }}
footer={
<>
<div
style={{
width: '100%',
}}
>
<div
className="result"
style={{
fontSize: '12px',
textAlign: 'center',
marginBottom: '20px',
}}
>
你将使用 {loginMethod === 'mobile' ? '手机号' : '邮箱'}{' '}
{account} 登录
</div>
<Button block type="primary" size="large" nativeType="submit">
提交
</Button>
</div>
</>
}
>
<Form.Item name="loginMethod" label="登录方式">
<Radio.Group>
<Space>
<Radio value="mobile">手机号</Radio>
<Radio className="clickTest" value="email">
邮箱
</Radio>
</Space>
</Radio.Group>
</Form.Item>

<>
{loginMethod === 'mobile' && (
<Form.Item name="account" label="手机号">
<Input placeholder="请输入手机号" />
</Form.Item>
)}
{loginMethod === 'email' && (
<Form.Item name="account" label="邮箱">
<Input placeholder="请输入邮箱" />
</Form.Item>
)}
</>
</Form>
)
}

const { container } = render(<Demo />)
const clickTest = container.querySelector('.clickTest')
if (clickTest) {
fireEvent.click(clickTest)
const result = container.querySelector('.result')
expect(result).toHaveTextContent('你将使用 邮箱 123 登录')
}
})
oasis-cloud marked this conversation as resolved.
Show resolved Hide resolved
5 changes: 5 additions & 0 deletions src/packages/form/demo.taro.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import Demo4 from './demos/taro/demo4'
import Demo5 from './demos/taro/demo5'
import Demo6 from './demos/taro/demo6'
import Demo7 from './demos/taro/demo7'
import Demo8 from './demos/taro/demo8'

const FormDemo = () => {
const [translated] = useTranslate({
Expand All @@ -20,6 +21,7 @@ const FormDemo = () => {
title4: 'Form.useForm 对表单数据域进行交互。',
title5: '表单类型',
validateTrigger: '校验触发时机',
useWatch: 'useWatch',
},
'en-US': {
basic: 'Basic Usage',
Expand All @@ -29,6 +31,7 @@ const FormDemo = () => {
title4: 'Interact with form data fields via Form.useForm',
title5: 'Form Type',
validateTrigger: 'Validate Trigger',
useWatch: 'useWatch',
},
})

Expand All @@ -50,6 +53,8 @@ const FormDemo = () => {
<Demo6 />
<h2>{translated.title5}</h2>
<Demo7 />
<h2>{translated.useWatch}</h2>
<Demo8 />
</div>
</>
)
Expand Down
5 changes: 5 additions & 0 deletions src/packages/form/demo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import Demo4 from './demos/h5/demo4'
import Demo5 from './demos/h5/demo5'
import Demo6 from './demos/h5/demo6'
import Demo7 from './demos/h5/demo7'
import Demo8 from './demos/h5/demo8'

const FormDemo = () => {
const [translated] = useTranslate({
Expand All @@ -18,6 +19,7 @@ const FormDemo = () => {
title4: 'Form.useForm 对表单数据域进行交互。',
title5: '表单类型',
validateTrigger: '校验触发时机',
useWatch: 'useWatch',
},
'en-US': {
basic: 'Basic Usage',
Expand All @@ -27,6 +29,7 @@ const FormDemo = () => {
title4: 'Interact with form data fields via Form.useForm',
title5: 'Form Type',
validateTrigger: 'Validate Trigger',
useWatch: 'useWatch',
},
})

Expand All @@ -47,6 +50,8 @@ const FormDemo = () => {
<Demo6 />
<h2>{translated.title5}</h2>
<Demo7 />
<h2>{translated.useWatch}</h2>
<Demo8 />
</div>
</>
)
Expand Down
64 changes: 64 additions & 0 deletions src/packages/form/demos/h5/demo8.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import React from 'react'
import { Button, Form, Input, Radio, Space } from '@nutui/nutui-react'

type FieldType = { account?: string; loginMethod?: 'mobile' | 'email' }

const Demo8 = () => {
const [form] = Form.useForm()
const account = Form.useWatch('account', form)
const loginMethod = Form.useWatch('loginMethod', form)

return (
<Form
form={form}
initialValues={{ loginMethod: 'mobile', account: '123' }}
footer={
<>
<div
style={{
width: '100%',
}}
>
<div
style={{
fontSize: '12px',
textAlign: 'center',
marginBottom: '20px',
}}
>
你将使用{loginMethod === 'mobile' ? '手机号' : '电子邮箱'}
{account}登录
</div>
<Button block type="primary" size="large" nativeType="submit">
提交
</Button>
</div>
</>
}
>
<Form.Item name="loginMethod" label="登录方式">
<Radio.Group>
<Space>
<Radio value="mobile">手机号</Radio>
<Radio value="email">电子邮箱</Radio>
</Space>
</Radio.Group>
</Form.Item>

<>
{loginMethod === 'mobile' && (
<Form.Item name="account" label="手机号">
<Input placeholder="请输入手机号" />
</Form.Item>
)}
{loginMethod === 'email' && (
<Form.Item name="account" label="电子邮箱">
<Input placeholder="请输入邮箱" />
</Form.Item>
)}
</>
</Form>
)
}

export default Demo8
64 changes: 64 additions & 0 deletions src/packages/form/demos/taro/demo8.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import React from 'react'
import { Button, Form, Input, Radio, Space } from '@nutui/nutui-react-taro'

type FieldType = { account?: string; loginMethod?: 'mobile' | 'email' }

const Demo8 = () => {
const [form] = Form.useForm()
const account = Form.useWatch('account', form)
const loginMethod = Form.useWatch('loginMethod', form)

return (
<Form
form={form}
initialValues={{ loginMethod: 'mobile', account: '123' }}
footer={
<>
<div
style={{
width: '100%',
}}
>
<div
style={{
fontSize: '12px',
textAlign: 'center',
marginBottom: '20px',
}}
>
你将使用{loginMethod === 'mobile' ? '手机号' : '电子邮箱'}
{account}登录
</div>
<Button block type="primary" size="large" nativeType="submit">
提交
</Button>
</div>
</>
}
>
<Form.Item name="loginMethod" label="登录方式">
<Radio.Group>
<Space>
<Radio value="mobile">手机号</Radio>
<Radio value="email">电子邮箱</Radio>
</Space>
</Radio.Group>
</Form.Item>

<>
{loginMethod === 'mobile' && (
<Form.Item name="account" label="手机号">
<Input placeholder="请输入手机号" />
</Form.Item>
)}
{loginMethod === 'email' && (
<Form.Item name="account" label="电子邮箱">
<Input placeholder="请输入邮箱" />
</Form.Item>
)}
</>
</Form>
)
}

export default Demo8
12 changes: 11 additions & 1 deletion src/packages/form/doc.en-US.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,14 @@ import { Form } from '@nutui/nutui-react'

:::

### useWatch

:::demo

<CodeBlock src='h5/demo8.tsx'></CodeBlock>

:::

### Form Type

:::demo
Expand Down Expand Up @@ -121,7 +129,7 @@ The rule validation process is based on [async-validator](https://github.com/yim

### FormInstance

Form.useForm() creates a Form instance, which is used to manage all data states.
`Form.useForm()` creates a Form instance, which is used to manage all data states.

| Property | Description | Type |
| --- | --- | --- |
Expand All @@ -132,6 +140,8 @@ Form.useForm() creates a Form instance, which is used to manage all data states.
| resetFields | Reset form prompt state | `() => void` |
| submit | method to submit a form for validation | `Promise` |

`Form.useWatch()`, this method will watch specified inputs and return their values. It is useful to render input value and for determining what to render by condition.

## Theming

### CSS Variables
Expand Down
12 changes: 11 additions & 1 deletion src/packages/form/doc.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,14 @@ import { Form } from '@nutui/nutui-react'

:::

### useWatch

:::demo

<CodeBlock src='h5/demo8.tsx'></CodeBlock>

:::

### 表单类型

:::demo
Expand Down Expand Up @@ -120,7 +128,7 @@ import { Form } from '@nutui/nutui-react'

### FormInstance

Form.useForm()创建 Form 实例,用于管理所有数据状态。
`Form.useForm()`创建 Form 实例,用于管理所有数据状态。

| 属性 | 说明 | 类型 |
| --- | --- | --- |
Expand All @@ -131,6 +139,8 @@ Form.useForm()创建 Form 实例,用于管理所有数据状态。
| resetFields | 重置表单提示状态 | `() => void` |
| submit | 提交表单进行校验的方法 | `Promise` |

`Form.useWatch()`此方法将监视指定的输入并返回其值。它对于呈现输入值和确定根据条件呈现的内容很有用。

## 主题定制

### 样式变量
Expand Down
12 changes: 11 additions & 1 deletion src/packages/form/doc.taro.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,14 @@ import { Form } from '@nutui/nutui-react-taro'

:::

### useWatch

:::demo

<CodeBlock src='taro/demo8.tsx'></CodeBlock>

:::

### 表单类型

:::demo
Expand Down Expand Up @@ -120,7 +128,7 @@ import { Form } from '@nutui/nutui-react-taro'

### FormInstance

Form.useForm()创建 Form 实例,用于管理所有数据状态。
`Form.useForm()`创建 Form 实例,用于管理所有数据状态。

| 属性 | 说明 | 类型 |
| --- | --- | --- |
Expand All @@ -131,6 +139,8 @@ Form.useForm()创建 Form 实例,用于管理所有数据状态。
| resetFields | 重置表单提示状态 | `() => void` |
| submit | 提交表单进行校验的方法 | `Promise` |

`Form.useWatch()`此方法将监视指定的输入并返回其值。它对于呈现输入值和确定根据条件呈现的内容很有用。

## 主题定制

### 样式变量
Expand Down
Loading
Loading