Skip to content
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

[Rating] Simpler customization of active "no value" styles #22613

Merged
merged 3 commits into from
Sep 16, 2020
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/pages/api-docs/rating.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ Any other props supplied will be provided to the root element (native element).
| <span class="prop-name">disabled</span> | <span class="prop-name">.Mui-disabled</span> | Pseudo-class applied to the root element if `disabled={true}`.
| <span class="prop-name">focusVisible</span> | <span class="prop-name">.Mui-focusVisible</span> | Pseudo-class applied to the root element if keyboard focused.
| <span class="prop-name">visuallyHidden</span> | <span class="prop-name">.MuiRating-visuallyHidden</span> | Visually hide an element.
| <span class="prop-name">pristine</span> | <span class="prop-name">.MuiRating-pristine</span> | Styles applied to the pristine label.
| <span class="prop-name">label</span> | <span class="prop-name">.MuiRating-label</span> | Styles applied to the label elements.
| <span class="prop-name">labelEmptyValueActive</span> | <span class="prop-name">.MuiRating-labelEmptyValueActive</span> | Styles applied to the label of the "no value" input when it is active.
| <span class="prop-name">icon</span> | <span class="prop-name">.MuiRating-icon</span> | Styles applied to the icon wrapping elements.
| <span class="prop-name">iconEmpty</span> | <span class="prop-name">.MuiRating-iconEmpty</span> | Styles applied to the icon wrapping elements when empty.
| <span class="prop-name">iconFilled</span> | <span class="prop-name">.MuiRating-iconFilled</span> | Styles applied to the icon wrapping elements when filled.
Expand Down
4 changes: 2 additions & 2 deletions docs/src/pages/components/rating/SimpleRating.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ export default function SimpleRating() {
<Rating name="disabled" value={value} disabled />
</Box>
<Box component="fieldset" mb={3} borderColor="transparent">
<Typography component="legend">Pristine</Typography>
<Rating name="pristine" value={null} />
<Typography component="legend">no rating given</Typography>
<Rating name="no-value" value={null} />
</Box>
</div>
);
Expand Down
4 changes: 2 additions & 2 deletions docs/src/pages/components/rating/SimpleRating.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ export default function SimpleRating() {
<Rating name="disabled" value={value} disabled />
</Box>
<Box component="fieldset" mb={3} borderColor="transparent">
<Typography component="legend">Pristine</Typography>
<Rating name="pristine" value={null} />
<Typography component="legend">no rating given</Typography>
<Rating name="no-value" value={null} />
</Box>
</div>
);
Expand Down
4 changes: 2 additions & 2 deletions packages/material-ui-lab/src/Rating/Rating.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@ export interface RatingProps
focusVisible?: string;
/** Visually hide an element. */
visuallyHidden?: string;
/** Styles applied to the pristine label. */
pristine?: string;
/** Styles applied to the label elements. */
label?: string;
/** Styles applied to the label of the "no value" input when it is active. */
labelEmptyValueActive?: string;
/** Styles applied to the icon wrapping elements. */
icon?: string;
/** Styles applied to the icon wrapping elements when empty. */
Expand Down
30 changes: 15 additions & 15 deletions packages/material-ui-lab/src/Rating/Rating.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,20 +75,18 @@ export const styles = (theme) => ({
focusVisible: {},
/* Visually hide an element. */
visuallyHidden,
/* Styles applied to the pristine label. */
pristine: {
'input:focus + &': {
top: 0,
bottom: 0,
position: 'absolute',
outline: '1px solid #999',
width: '100%',
},
},
/* Styles applied to the label elements. */
label: {
cursor: 'inherit',
},
/* Styles applied to the label of the "no value" input when it is active. */
labelEmptyValueActive: {
top: 0,
bottom: 0,
position: 'absolute',
outline: '1px solid #999',
width: '100%',
},
/* Styles applied to the icon wrapping elements. */
icon: {
// Fit wrapper to actual icon size.
Expand Down Expand Up @@ -313,6 +311,8 @@ const Rating = React.forwardRef(function Rating(props, ref) {
}
};

const [emptyValueFocused, setEmptyValueFocused] = React.useState(false);

const item = (state, labelProps) => {
const id = `${name}-${String(state.value).replace('.', '-')}`;
const container = (
Expand Down Expand Up @@ -428,7 +428,7 @@ const Rating = React.forwardRef(function Rating(props, ref) {
});
})}
{!disabled && valueRounded == null && (
<React.Fragment>
<label className={clsx({ [classes.labelEmptyValueActive]: emptyValueFocused })}>
<input
value=""
id={`${name}-empty`}
Expand All @@ -437,11 +437,11 @@ const Rating = React.forwardRef(function Rating(props, ref) {
defaultChecked
className={classes.visuallyHidden}
readOnly={readOnly}
onFocus={() => setEmptyValueFocused(true)}
onBlur={() => setEmptyValueFocused(false)}
/>
<label className={classes.pristine} htmlFor={`${name}-empty`}>
<span className={classes.visuallyHidden}>{emptyLabelText}</span>
</label>
</React.Fragment>
<span className={classes.visuallyHidden}>{emptyLabelText}</span>
</label>
)}
</span>
);
Expand Down
19 changes: 19 additions & 0 deletions packages/material-ui-lab/src/Rating/Rating.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
describeConformance,
createClientRender,
fireEvent,
screen,
} from 'test/utils';
import Rating from './Rating';

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

it('has a customization point for the label of the empty value when it is active', () => {
const { container } = render(
<Rating classes={{ labelEmptyValueActive: 'customized' }} name="" value={null} />,
);

expect(container.querySelector('.customized')).to.equal(null);

act(() => {
const noValueRadio = screen.getAllByRole('radio').find((radio) => {
return radio.checked;
});

noValueRadio.focus();
});

expect(container.querySelector('.customized')).to.have.property('tagName', 'LABEL');
});

describe('<form> integration', () => {
before(function beforeHook() {
if (/jsdom/.test(window.navigator.userAgent)) {
Expand Down