Skip to content

Commit aff59c2

Browse files
[material-ui][Rating] Fix the hover highlighting for spaced icons (#39775)
1 parent efcdf73 commit aff59c2

File tree

2 files changed

+50
-6
lines changed

2 files changed

+50
-6
lines changed

Diff for: packages/mui-material/src/Rating/Rating.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -367,14 +367,14 @@ const Rating = React.forwardRef(function Rating(inProps, ref) {
367367
}
368368

369369
const rootNode = rootRef.current;
370-
const { right, left } = rootNode.getBoundingClientRect();
371-
const { width } = rootNode.firstChild.getBoundingClientRect();
370+
const { right, left, width: containerWidth } = rootNode.getBoundingClientRect();
371+
372372
let percent;
373373

374374
if (theme.direction === 'rtl') {
375-
percent = (right - event.clientX) / (width * max);
375+
percent = (right - event.clientX) / containerWidth;
376376
} else {
377-
percent = (event.clientX - left) / (width * max);
377+
percent = (event.clientX - left) / containerWidth;
378378
}
379379

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

Diff for: packages/mui-material/src/Rating/Rating.test.js

+46-2
Original file line numberDiff line numberDiff line change
@@ -46,18 +46,62 @@ describe('<Rating />', () => {
4646
stub(container.firstChild, 'getBoundingClientRect').callsFake(() => ({
4747
left: 0,
4848
right: 100,
49+
width: 100,
4950
}));
50-
stub(container.firstChild.firstChild, 'getBoundingClientRect').callsFake(() => ({
51-
width: 20,
51+
fireEvent.mouseMove(container.firstChild, {
52+
clientX: 19,
53+
});
54+
expect(container.querySelectorAll(`.${classes.iconHover}`).length).to.equal(1);
55+
fireEvent.mouseMove(container.firstChild, {
56+
clientX: 21,
57+
});
58+
expect(container.querySelectorAll(`.${classes.iconHover}`).length).to.equal(2);
59+
});
60+
61+
it('should handle mouse hover correctly for icons with spacing', () => {
62+
const { container } = render(
63+
<Rating
64+
sx={{
65+
[`.${classes.decimal}`]: { marginRight: 2 },
66+
}}
67+
precision={0.5}
68+
/>,
69+
);
70+
stub(container.firstChild, 'getBoundingClientRect').callsFake(() => ({
71+
left: 0,
72+
right: 200,
73+
width: 200,
5274
}));
75+
5376
fireEvent.mouseMove(container.firstChild, {
5477
clientX: 19,
5578
});
79+
// half star highlighted
5680
expect(container.querySelectorAll(`.${classes.iconHover}`).length).to.equal(1);
81+
5782
fireEvent.mouseMove(container.firstChild, {
5883
clientX: 21,
5984
});
85+
// one full star highlighted
86+
expect(container.querySelectorAll(`.${classes.iconHover}`).length).to.equal(2);
87+
88+
fireEvent.mouseMove(container.firstChild, {
89+
clientX: 39,
90+
});
91+
// Still one star remains highlighted as the total item width (40px) has not been reached yet, considering 24px for the icon width and 16px for margin-right.
6092
expect(container.querySelectorAll(`.${classes.iconHover}`).length).to.equal(2);
93+
94+
fireEvent.mouseMove(container.firstChild, {
95+
clientX: 41,
96+
});
97+
// one and half star highlighted
98+
expect(container.querySelectorAll(`.${classes.iconHover}`).length).to.equal(3);
99+
100+
fireEvent.mouseMove(container.firstChild, {
101+
clientX: 60,
102+
});
103+
// two full stars highlighted
104+
expect(container.querySelectorAll(`.${classes.iconHover}`).length).to.equal(4);
61105
});
62106

63107
it('should clear the rating', () => {

0 commit comments

Comments
 (0)