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

fix(inputnumber): 增加 beforeChange,优化异步逻辑 #2950

Open
wants to merge 3 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
57 changes: 33 additions & 24 deletions src/packages/inputnumber/__tests__/inputnumber.spec.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as React from 'react'
import { render, fireEvent, waitFor } from '@testing-library/react'
import { render, fireEvent, waitFor, act } from '@testing-library/react'
import '@testing-library/jest-dom'

import { InputNumber } from '../inputnumber'
Expand All @@ -9,7 +9,7 @@ test('should render modelValue', () => {
expect(container.querySelector('input')?.value).toBe('12')
})

test('should add step 2 when trigger click plus button', () => {
test('should add step 2 when trigger click plus button', async () => {
const overlimit = vi.fn()
const add = vi.fn()
const change = vi.fn()
Expand All @@ -23,13 +23,16 @@ test('should add step 2 when trigger click plus button', () => {
/>
)
const iconPlus = container.querySelectorAll('.nut-icon-Plus')[0]
fireEvent.click(iconPlus)
await act(async () => {
fireEvent.click(iconPlus)
})

expect(overlimit).not.toBeCalled()
expect(add).toBeCalled()
expect(add).toHaveBeenCalled()
expect(change.mock.calls[0][0]).toBe(3)
})

test('should minis step 2 when trigger click minis button', () => {
test('should minis step 2 when trigger click minis button', async () => {
const overlimit = vi.fn()
const reduce = vi.fn()
const change = vi.fn()
Expand All @@ -43,13 +46,15 @@ test('should minis step 2 when trigger click minis button', () => {
/>
)
const iconMinus = container.querySelectorAll('.nut-icon-Minus')[0]
fireEvent.click(iconMinus)
await act(async () => {
fireEvent.click(iconMinus)
})
expect(overlimit).not.toBeCalled()
expect(reduce).toBeCalled()
expect(change.mock.calls[0][0]).toBe(1)
})

test('should render max props', () => {
test('should render max props', async () => {
const overlimit = vi.fn()
const add = vi.fn()
const change = vi.fn()
Expand All @@ -64,13 +69,15 @@ test('should render max props', () => {
/>
)
const iconPlus = container.querySelectorAll('.nut-icon-Plus')[0]
fireEvent.click(iconPlus)
await act(async () => {
fireEvent.click(iconPlus)
})
expect(overlimit).toBeCalled()
expect(add).toBeCalled()
expect(change).not.toBeCalled()
})

test('should render min props', () => {
test('should render min props', async () => {
const overlimit = vi.fn()
const reduce = vi.fn()
const change = vi.fn()
Expand All @@ -85,7 +92,9 @@ test('should render min props', () => {
/>
)
const iconMinus = container.querySelectorAll('.nut-icon-Minus')[0]
fireEvent.click(iconMinus)
await act(async () => {
fireEvent.click(iconMinus)
})
expect(overlimit).toBeCalled()
expect(reduce).toBeCalled()
expect(change).not.toBeCalled()
Expand All @@ -104,23 +113,27 @@ test('should not trigger click when disabled props to be true', () => {
expect(container.querySelector('input')?.value).toBe('1')
})

test('should not focus input when readOnly props to be true', () => {
test('should not focus input when readOnly props to be true', async () => {
const focus = vi.fn()
const { container } = render(
<InputNumber readOnly defaultValue={2} onFocus={focus} />
)
const iconMinus = container.querySelectorAll('.nut-icon-Minus')[0]
fireEvent.click(iconMinus)
await act(async () => {
fireEvent.click(iconMinus)
})
expect(container.querySelector('input')?.value).toBe('1')
expect(focus).not.toBeCalled()
})

test('should render decimal when step props to be 0.2', () => {
test('should render decimal when step props to be 0.2', async () => {
const { container } = render(
<InputNumber step={0.2} digits={1} defaultValue={2} />
)
const iconPlus = container.querySelectorAll('.nut-icon-Plus')[0]
fireEvent.click(iconPlus)
await act(async () => {
fireEvent.click(iconPlus)
})
expect(container.querySelector('input')?.value).toBe('2.2')
})

Expand Down Expand Up @@ -158,19 +171,15 @@ test('allowEmpty', () => {
})
})

test('should overlimit when input', () => {
const change = vi.fn()
test('should overlimit when input', async () => {
const overlimit = vi.fn()
const { container } = render(
<InputNumber
defaultValue={2}
max={100}
onChange={change}
onOverlimit={overlimit}
/>
<InputNumber defaultValue={2} max={100} onOverlimit={overlimit} />
)
const input = container.querySelectorAll('input')[0]
input.value = '200'
fireEvent.input(input)
expect(change).toBeCalled()
await act(async () => {
fireEvent.input(input)
})
expect(overlimit).toBeCalled()
})
23 changes: 13 additions & 10 deletions src/packages/inputnumber/demos/h5/demo8.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,25 @@ const Demo8 = () => {
const overlimit = (e: any) => {
console.log('超出限制事件触发', e)
}
const onChange = (value: string | number) => {

const beforeChange = (value: number | string): Promise<boolean> => {
Toast.show({ icon: 'loading', content: '异步演示2秒后更改' })
console.log('onChange', value)
setTimeout(() => {
setInputValue(Number(value))
Toast.clear()
}, 2000)

return new Promise((resolve) => {
setTimeout(() => {
Toast.clear()
resolve(true)
}, 500)
})
}

return (
<InputNumber
value={inputValue}
min={-6}
max={6}
onChange={onChange}
min={-9999}
beforeChange={beforeChange}
onChange={(value) => setInputValue(Number(value))}
onOverlimit={overlimit}
async
/>
)
}
Expand Down
37 changes: 20 additions & 17 deletions src/packages/inputnumber/demos/taro/demo8.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,42 +3,45 @@ import { InputNumber, Toast } from '@nutui/nutui-react-taro'

const Demo8 = () => {
const [inputValue, setInputValue] = useState(0)
const [show, SetShow] = useState(false)
const [toastMsg, SetToastMsg] = useState('')
const [toastType, SetToastType] = useState('text')
const [show, setShow] = useState(false)
const [toastMsg, setToastMsg] = useState('')
const [toastType, setToastType] = useState('text')

const toastShow = (msg: any, type: string) => {
SetToastMsg(msg)
SetToastType(type)
SetShow(true)
setToastMsg(msg)
setToastType(type)
setShow(true)
}
const overlimit = (e: any) => {
console.log('超出限制事件触发', e)
}
const onChange = (value: string | number) => {

const beforeChange = (value: number | string): Promise<boolean> => {
toastShow('异步演示 2 秒后更改', 'loading')
console.log('onChange', value)
setTimeout(() => {
setInputValue(Number(value))
SetShow(false)
}, 2000)

return new Promise((resolve) => {
setTimeout(() => {
setShow(false)
resolve(true)
}, 500)
})
}

return (
<>
<InputNumber
value={inputValue}
min={-6}
max={6}
onChange={onChange}
min={-9999}
beforeChange={beforeChange}
onChange={(value) => setInputValue(Number(value))}
onOverlimit={overlimit}
async
/>
<Toast
type={toastType}
visible={show}
content={toastMsg}
onClose={() => {
SetShow(false)
setShow(false)
}}
/>
</>
Expand Down
5 changes: 3 additions & 2 deletions src/packages/inputnumber/doc.en-US.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,9 +121,10 @@ Asynchronous modification through `change` event and `model-value`
| digits | Set reserved decimal places | `string` \| `number` | `0` |
| disabled | Disable all features | `boolean` | `false` |
| readOnly | Read only status disables input box operation behavior | `boolean` | `false` |
| async | Support for asynchronous modification | `boolean` | `false` |
| select | Support deselect all text | `boolean` | `true` |
| ~~async~~`2.8.0` | Support for asynchronous modification | `boolean` | `false` |
| select`2.7.0` | Support deselect all text | `boolean` | `true` |
| formatter | Specifies the format of the value displayed in the input box | `function(value: number \| string): string` | `-` |
| beforeChange`2.8.0` | Callback function before the input value changes, return false to prevent input, support returning Promise | `(value: number \| string) => boolean \| Promise<boolean>` | `-` |
| onPlus | Triggered when the Add button is clicked | `(e: MouseEvent) => void` | `-` |
| onMinus | Triggered when the decrease button is clicked | `(e: MouseEvent) => void` | `-` |
| onOverlimit | Triggered when an unavailable button is clicked | `(e: MouseEvent) => void` | `-` |
Expand Down
5 changes: 3 additions & 2 deletions src/packages/inputnumber/doc.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,9 +121,10 @@ import { InputNumber } from '@nutui/nutui-react'
| digits | 设置保留的小数位 | `string` \| `number` | `0` |
| disabled | 禁用所有功能 | `boolean` | `false` |
| readOnly | 只读状态禁用输入框操作行为 | `boolean` | `false` |
| async | 支持异步修改 | `boolean` | `false` |
| select | 支持取消文本全选中 | `boolean` | `true` |
| ~~async~~`2.8.0` | 支持异步修改 | `boolean` | `false` |
| select`2.7.0` | 支持取消文本全选中 | `boolean` | `true` |
| formatter | 指定输入框展示值的格式 | `function(value: number \| string): string` | `-` |
| beforeChange`2.8.0` | 输入值变化前的回调函数,返回 false 可阻止输入,支持返回 Promise | `(value: number \| string) => boolean \| Promise<boolean>` | `-` |
| onPlus | 点击增加按钮时触发 | `(e: MouseEvent) => void` | `-` |
| onMinus | 点击减少按钮时触发 | `(e: MouseEvent) => void` | `-` |
| onOverlimit | 点击不可用的按钮时触发 | `(e: MouseEvent) => void` | `-` |
Expand Down
3 changes: 2 additions & 1 deletion src/packages/inputnumber/doc.taro.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,9 @@ import { InputNumber } from '@nutui/nutui-react-taro'
| digits | 设置保留的小数位 | `string` \| `number` | `0` |
| disabled | 禁用所有功能 | `boolean` | `false` |
| readOnly | 只读状态禁用输入框操作行为 | `boolean` | `false` |
| async | 支持异步修改 | `boolean` | `false` |
| ~~async~~`2.8.0` | 支持异步修改 | `boolean` | `false` |
| formatter | 指定输入框展示值的格式 | `function(value: number \| string): string` | `-` |
| beforeChange`2.8.0` | 输入值变化前的回调函数,返回 false 可阻止输入,支持返回 Promise | `(value: number \| string) => boolean \| Promise<boolean>` | `-` |
| onPlus | 点击增加按钮时触发 | `(e: MouseEvent) => void` | `-` |
| onMinus | 点击减少按钮时触发 | `(e: MouseEvent) => void` | `-` |
| onOverlimit | 点击不可用的按钮时触发 | `(e: MouseEvent) => void` | `-` |
Expand Down
4 changes: 3 additions & 1 deletion src/packages/inputnumber/doc.zh-TW.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,10 @@ import { InputNumber } from '@nutui/nutui-react'
| digits | 設置保留的小數位 | `string` \| `number` | `0` |
| disabled | 禁用所有功能 | `boolean` | `false` |
| readOnly | 只讀狀態禁用輸入框操作行為 | `boolean` | `false` |
| async | 支持異步修改 | `boolean` | `false` |
| ~~async~~`2.8.0` | 支持異步修改 | `boolean` | `false` |
| select`2.7.0` | 支持取消文本全选中 | `boolean` | `true` |
| formatter | 指定輸入框展示值的格式 | `function(value: number \| string): string` | `-` |
| beforeChange`2.8.0` | 输入值变化前的回调函数,返回 false 可阻止输入,支持返回 Promise | `(value: number \| string) => boolean \| Promise<boolean>` | `-` |
| onPlus | 點擊增加按鈕時觸發 | `(e: MouseEvent) => void` | `-` |
| onMinus | 點擊減少按鈕時觸發 | `(e: MouseEvent) => void` | `-` |
| onOverlimit | 點擊不可用的按鈕時觸發 | `(e: MouseEvent) => void` | `-` |
Expand Down
Loading
Loading