Skip to content

Commit

Permalink
feat(rating): prevent null value on keyboard interaction
Browse files Browse the repository at this point in the history
  • Loading branch information
soykje committed Nov 13, 2023
1 parent 1b33f81 commit 0301537
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 5 deletions.
2 changes: 1 addition & 1 deletion packages/components/rating/src/Rating.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export default meta

const sizes: RatingProps['size'][] = ['sm', 'md', 'lg']

export const Default: StoryFn = _args => <Rating defaultValue={3} aria-label="Rating control" />
export const Default: StoryFn = _args => <Rating aria-label="Rating control" />

export const Readonly: StoryFn = _args => (
<Rating defaultValue={3.5} aria-label="Rating control with readOnly" readOnly />
Expand Down
12 changes: 12 additions & 0 deletions packages/components/rating/src/Rating.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,18 @@ describe('Rating', () => {
expect(onValueChangeSpy).toHaveBeenLastCalledWith(2)
})

it('should not be possible to reset value back to zero', () => {
render(<Rating {...defaultProps} defaultValue={3} />)
const input = utils.getInput()

fireEvent.change(input, { target: { value: '1' } })
expect(input).toHaveValue('1')

fireEvent.change(input, { target: { value: '0' } })

expect(input).toHaveValue('1')
})

it('should not be possible to interact when in readOnly (in controlled mode)', async () => {
const user = userEvent.setup()
const handleValueChange = vi.fn()
Expand Down
9 changes: 5 additions & 4 deletions packages/components/rating/src/Rating.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,11 @@ export const Rating = forwardRef<HTMLDivElement, RatingProps>(
}

function onInputChange(event: ChangeEvent<HTMLInputElement>) {
// avoiding unnecessary calls to the onValueChange prop
// when the value remains unchanged
if (valueRef.current === Number(event.target.value)) return
// 1. Avoiding unnecessary calls to onValueChange prop if value doesn't change
// 2. Preventing value to be resetted to 0
if (valueRef.current === Number(event.target.value) || Number(event.target.value) === 0) {
return
}
valueRef.current = Number(event.target.value)

setRatingValue(Number(event.target.value))
Expand Down Expand Up @@ -150,7 +152,6 @@ export const Rating = forwardRef<HTMLDivElement, RatingProps>(
readOnly={readOnly}
value={getNearestDecimal(value)}
onChange={event => isInteractive && onInputChange(event)}
onKeyDown={resetDataPartInputAttr}
onBlur={resetDataPartInputAttr}
/>
<div
Expand Down

0 comments on commit 0301537

Please sign in to comment.