-
-
Notifications
You must be signed in to change notification settings - Fork 32.1k
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
[base-ui][useNumberInput] Integrate useNumberInput with useControllableReducer #40206
Changes from all commits
03b26d8
8bcf895
05c6326
a6d1640
1bc2022
8c5b69b
34d3eaa
4d08fca
808a36c
836b125
0e00664
58acda1
dea150a
0775d7b
bd8cca8
04b2d0d
d7bdbc5
a27fac0
57b8259
de0c038
a16d67f
d400dde
d54da2d
f661961
e768801
6a892cf
c72faa7
66c2867
432ae2a
26ae3e4
fcdb632
38ae823
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -497,32 +497,64 @@ describe('<NumberInput />', () => { | |
expect(input.value).to.equal('1'); | ||
}); | ||
|
||
it('sets value to min when the input has no value and ArrowUp is pressed', async () => { | ||
const handleChange = spy(); | ||
describe('when the input has no value and ArrowUp is pressed', () => { | ||
it('sets value to min if min is provided', async () => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This isn't quite how the native control works - it kinda assumes that no value = 0 (so if There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @michaldudak This was intentional ~ I think it's a worthwhile improvement from the native behavior 😬 If a range is defined with If arrow down starts on the And luckily since the native number input isn't used in the wild that much, it shouldn't be something a typical web user would need to "unlearn", what do you think? PS: Did a quick check as well, react-aria(react-spectrum) also implemented this behavior – sandbox - but mantine and Chakra do not There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. BTW I would love to get @colmtuite's opinion on this as well ~ There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes I agree @mj12albert. When There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. All right, then. Let's get it merged! |
||
const handleChange = spy(); | ||
|
||
const { getByRole } = render(<NumberInput min={5} onChange={handleChange} />); | ||
const { getByRole } = render(<NumberInput min={5} onChange={handleChange} />); | ||
|
||
const input = getByRole('textbox') as HTMLInputElement; | ||
const input = getByRole('textbox') as HTMLInputElement; | ||
|
||
await userEvent.click(input); | ||
await userEvent.keyboard('[ArrowUp]'); | ||
await userEvent.click(input); | ||
await userEvent.keyboard('[ArrowUp]'); | ||
|
||
expect(handleChange.args[0][1]).to.equal(5); | ||
expect(input.value).to.equal('5'); | ||
}); | ||
|
||
it('sets value to 1 if min is not provided', async () => { | ||
const handleChange = spy(); | ||
|
||
const { getByRole } = render(<NumberInput onChange={handleChange} />); | ||
|
||
expect(handleChange.args[0][1]).to.equal(5); | ||
expect(input.value).to.equal('5'); | ||
const input = getByRole('textbox') as HTMLInputElement; | ||
|
||
await userEvent.click(input); | ||
await userEvent.keyboard('[ArrowUp]'); | ||
|
||
expect(handleChange.args[0][1]).to.equal(1); | ||
expect(input.value).to.equal('1'); | ||
}); | ||
}); | ||
|
||
it('sets value to max when the input has no value and ArrowDown is pressed', async () => { | ||
const handleChange = spy(); | ||
describe('when the input has no value and ArrowDown is pressed', () => { | ||
it('sets value to max when max is provided', async () => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This doesn't match the native behavior either - the |
||
const handleChange = spy(); | ||
|
||
const { getByRole } = render(<NumberInput max={9} onChange={handleChange} />); | ||
const { getByRole } = render(<NumberInput max={9} onChange={handleChange} />); | ||
|
||
const input = getByRole('textbox') as HTMLInputElement; | ||
const input = getByRole('textbox') as HTMLInputElement; | ||
|
||
await userEvent.click(input); | ||
await userEvent.keyboard('[ArrowDown]'); | ||
await userEvent.click(input); | ||
await userEvent.keyboard('[ArrowDown]'); | ||
|
||
expect(handleChange.args[0][1]).to.equal(9); | ||
expect(input.value).to.equal('9'); | ||
expect(handleChange.args[0][1]).to.equal(9); | ||
expect(input.value).to.equal('9'); | ||
}); | ||
|
||
it('sets value to -1 when max is not provided', async () => { | ||
const handleChange = spy(); | ||
|
||
const { getByRole } = render(<NumberInput onChange={handleChange} />); | ||
|
||
const input = getByRole('textbox') as HTMLInputElement; | ||
|
||
await userEvent.click(input); | ||
await userEvent.keyboard('[ArrowDown]'); | ||
|
||
expect(handleChange.args[0][1]).to.equal(-1); | ||
expect(input.value).to.equal('-1'); | ||
}); | ||
}); | ||
|
||
it('only includes the input element in the tab order', async () => { | ||
|
@@ -556,4 +588,30 @@ describe('<NumberInput />', () => { | |
expect(getByTestId('adornment')).not.to.equal(null); | ||
}); | ||
}); | ||
|
||
it('Should update NumberInput value when value prop is set through side effects', async () => { | ||
function App() { | ||
const [value, setValue] = React.useState(10); | ||
|
||
return ( | ||
<div> | ||
<button data-testid="button" onClick={() => setValue(20)}> | ||
Enable | ||
</button> | ||
<NumberInput value={value} /> | ||
</div> | ||
); | ||
} | ||
const { getByRole, getByTestId } = render(<App />); | ||
|
||
const input = getByRole('textbox') as HTMLInputElement; | ||
const button = getByTestId('button') as HTMLButtonElement; | ||
|
||
act(() => { | ||
fireEvent.click(button); | ||
}); | ||
|
||
await userEvent.click(input); | ||
expect(input.value).to.equal('20'); | ||
}); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍