Skip to content

Commit

Permalink
[Rating] Treat read-only as image (#22639)
Browse files Browse the repository at this point in the history
  • Loading branch information
eps1lon authored Sep 18, 2020
1 parent 2390d45 commit 15af0bd
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 20 deletions.
16 changes: 12 additions & 4 deletions packages/material-ui-lab/src/Rating/Rating.js
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,14 @@ const Rating = React.forwardRef(function Rating(props, ref) {
</IconContainerComponent>
);

if (readOnly) {
return (
<span key={state.value} {...labelProps}>
{container}
</span>
);
}

return (
<React.Fragment key={state.value}>
<label className={classes.label} htmlFor={id} {...labelProps}>
Expand All @@ -341,14 +349,13 @@ const Rating = React.forwardRef(function Rating(props, ref) {
onBlur={handleBlur}
onChange={handleChange}
onClick={handleClear}
disabled={readOnly && !state.checked ? true : disabled}
disabled={disabled}
value={state.value}
id={id}
type="radio"
name={name}
checked={state.checked}
className={classes.visuallyHidden}
readOnly={readOnly}
/>
</React.Fragment>
);
Expand All @@ -369,6 +376,8 @@ const Rating = React.forwardRef(function Rating(props, ref) {
},
className,
)}
role={readOnly ? 'img' : null}
aria-label={readOnly ? getLabelText(value) : null}
{...other}
>
{Array.from(new Array(max)).map((_, index) => {
Expand Down Expand Up @@ -427,7 +436,7 @@ const Rating = React.forwardRef(function Rating(props, ref) {
checked: itemValue === valueRounded,
});
})}
{!disabled && valueRounded == null && (
{!readOnly && !disabled && valueRounded == null && (
<label className={clsx({ [classes.labelEmptyValueActive]: emptyValueFocused })}>
<input
value=""
Expand All @@ -436,7 +445,6 @@ const Rating = React.forwardRef(function Rating(props, ref) {
name={name}
defaultChecked
className={classes.visuallyHidden}
readOnly={readOnly}
onFocus={() => setEmptyValueFocused(true)}
onBlur={() => setEmptyValueFocused(false)}
/>
Expand Down
43 changes: 27 additions & 16 deletions packages/material-ui-lab/src/Rating/Rating.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,12 @@ describe('<Rating />', () => {
const mount = createMount();
const render = createClientRender();
let classes;
const defaultProps = {
name: 'rating-test',
value: 2,
};

before(() => {
classes = getClasses(<Rating {...defaultProps} />);
classes = getClasses(<Rating />);
});

describeConformance(<Rating {...defaultProps} />, () => ({
describeConformance(<Rating />, () => ({
classes,
inheritComponent: 'span',
mount,
Expand All @@ -34,13 +30,13 @@ describe('<Rating />', () => {
}));

it('should render', () => {
const { container } = render(<Rating {...defaultProps} />);
const { container } = render(<Rating />);

expect(container.firstChild).to.have.class(classes.root);
});

it('should round the value to the provided precision', () => {
const { container } = render(<Rating {...defaultProps} value={3.9} precision={0.2} />);
const { container } = render(<Rating name="rating-test" value={3.9} precision={0.2} />);

expect(container.querySelector('input[name="rating-test"]:checked')).to.have.property(
'value',
Expand All @@ -49,7 +45,7 @@ describe('<Rating />', () => {
});

it('should handle mouse hover correctly', () => {
const { container } = render(<Rating {...defaultProps} />);
const { container } = render(<Rating />);
stub(container.firstChild, 'getBoundingClientRect').callsFake(() => ({
left: 0,
right: 100,
Expand All @@ -69,7 +65,7 @@ describe('<Rating />', () => {

it('should clear the rating', () => {
const handleChange = spy();
const { getByRole } = render(<Rating {...defaultProps} onChange={handleChange} />);
const { getByRole } = render(<Rating onChange={handleChange} value={2} />);

const input = getByRole('radio', { name: '2 Stars' });
fireEvent.click(input, {
Expand All @@ -82,7 +78,9 @@ describe('<Rating />', () => {

it('should select the rating', () => {
const handleChange = spy();
const { container, getByRole } = render(<Rating {...defaultProps} onChange={handleChange} />);
const { container, getByRole } = render(
<Rating name="rating-test" onChange={handleChange} value={2} />,
);

fireEvent.click(getByRole('radio', { name: '3 Stars' }));

Expand All @@ -93,17 +91,15 @@ describe('<Rating />', () => {
});

it('should select the empty input if value is null', () => {
const { container, getByRole } = render(<Rating {...defaultProps} value={null} />);
const { container, getByRole } = render(<Rating name="rating-test" value={null} />);
const input = getByRole('radio', { name: 'Empty' });
const checked = container.querySelector('input[name="rating-test"]:checked');
expect(input).to.equal(checked);
expect(input.value).to.equal('');
});

it('should support a defaultValue', () => {
const { container, getByRole } = render(
<Rating {...defaultProps} value={undefined} defaultValue={3} />,
);
const { container, getByRole } = render(<Rating defaultValue={3} name="rating-test" />);
let checked;
checked = container.querySelector('input[name="rating-test"]:checked');
expect(checked.value).to.equal('3');
Expand Down Expand Up @@ -131,6 +127,20 @@ describe('<Rating />', () => {
expect(container.querySelector('.customized')).to.have.property('tagName', 'LABEL');
});

describe('prop: readOnly', () => {
it('renders a role="img"', () => {
render(<Rating readOnly value={2} />);

expect(screen.getByRole('img')).toHaveAccessibleName('2 Stars');
});

it('can be labelled with getLabelText', () => {
render(<Rating getLabelText={(value) => `Stars: ${value}`} readOnly value={2} />);

expect(screen.getByRole('img')).toHaveAccessibleName('Stars: 2');
});
});

describe('<form> integration', () => {
before(function beforeHook() {
if (/jsdom/.test(window.navigator.userAgent)) {
Expand All @@ -151,7 +161,8 @@ describe('<Rating />', () => {
},
{
ratingProps: { name: 'rating', defaultValue: 2, readOnly: true },
formData: [['rating', '2']],
// native <input type="radio" /> and our Radio/Checkbox don't implement readOnly as well
formData: [],
},
{
ratingProps: { name: 'rating', required: true },
Expand Down

0 comments on commit 15af0bd

Please sign in to comment.