Skip to content

Commit

Permalink
[fix] Fix Rating return NaN when using user event
Browse files Browse the repository at this point in the history
  • Loading branch information
NooBat committed Jan 31, 2025
1 parent 4b74f87 commit 6a76a96
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 2 deletions.
10 changes: 8 additions & 2 deletions packages/mui-material/src/Rating/Rating.js
Original file line number Diff line number Diff line change
Expand Up @@ -404,9 +404,17 @@ const Rating = React.forwardRef(function Rating(inProps, ref) {
percent = (event.clientX - left) / containerWidth;
}

setFocusVisible(false);

let newHover = roundValueToPrecision(max * percent + precision / 2, precision);
newHover = clamp(newHover, precision, max);

if (Number.isNaN(newHover)) {
// Workaround for test scenario using userEvent since jsdom defaults getBoundingClientRect to 0
// Fix https://github.com/mui/material-ui/issues/38828
return;
}

setState((prev) =>
prev.hover === newHover && prev.focus === newHover
? prev
Expand All @@ -416,8 +424,6 @@ const Rating = React.forwardRef(function Rating(inProps, ref) {
},
);

setFocusVisible(false);

if (onChangeActive && hover !== newHover) {
onChangeActive(event, newHover);
}
Expand Down
22 changes: 22 additions & 0 deletions packages/mui-material/src/Rating/Rating.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { stub, spy } from 'sinon';
import { act, createRenderer, fireEvent, screen } from '@mui/internal-test-utils';
import Rating, { ratingClasses as classes } from '@mui/material/Rating';
import { createTheme, ThemeProvider } from '@mui/material/styles';
import userEvent from '@testing-library/user-event';
import describeConformance from '../../test/describeConformance';

describe('<Rating />', () => {
Expand Down Expand Up @@ -121,6 +122,27 @@ describe('<Rating />', () => {
expect(checked.value).to.equal('2');
});

it('should select the rating with user clicks', async () => {
const user = userEvent.setup();
const handleChange = spy();

const { container } = render(<Rating name="rating-test" onChange={handleChange} />);

const input = container.getByLabelText('3 Stars');
// A mouse move event is required since userEvent.click triggers a mouse move event
// but clientX is always 0 in the event.
fireEvent.mouseMove(input, {
clientX: 60,
});
await user.click(input);

expect(handleChange.callCount).to.equal(1);
expect(handleChange.args[0][1]).to.deep.equal(3);

const checked = container.querySelector('input[name="rating-test"]:checked');
expect(checked.value).to.equal('3');
});

it('should change the value to null', () => {
const handleChange = spy();
render(<Rating name="rating-test" onChange={handleChange} value={2} />);
Expand Down

0 comments on commit 6a76a96

Please sign in to comment.