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

[Button] Don't apply hover styles when disabled #26412

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all 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 packages/material-ui/src/Button/Button.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ const ButtonRoot = styled(ButtonBase, {
duration: theme.transitions.duration.short,
},
),
'&:hover': {
'&:hover': !styleProps.disabled && {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mnajdova Any potentially undesired side-effects this might have? Or is this intended to work this way?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, I would maybe write it like this:

...(!styleProps.disabled && {
  '&:hover': {...}
}),

So that we don't end up with '&:hover': false, but even that should not create any issues I think.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Personally, I'm having a hard time parsing the code you wrote. And it's creating an additional object.

So that we don't end up with '&:hover': false, but even that should not create any issues I think.

Yeah, let's try this out then.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is prone to mistakes. For example, we also have '&:hover' on line 229 https://github.com/mui-org/material-ui/blob/8e0eb6d678243e6ffc73145ba3f8a1d30b78bc57/packages/material-ui/src/Button/Button.js#L229

In addition, what other components should incorporate this logic?

textDecoration: 'none',
backgroundColor: alpha(theme.palette.text.primary, theme.palette.action.hoverOpacity),
// Reset on touch devices, it doesn't add specificity
Expand Down
14 changes: 14 additions & 0 deletions test/regressions/fixtures/Button/DisabledButtons.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import * as React from 'react';
import Button from '@material-ui/core/Button';

export default function Demo() {
return (
<React.Fragment>
<Button disabled style={{ pointerEvents: 'all' }}>
disabled with pointer-events
</Button>
<Button disabled>disabled without pointer-events</Button>
<Button aria-disabled>aria-disabled</Button>
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding for future reference. I'm inclined to special case aria-disabled to act as "disabled but focuseable" for a11y: https://css-tricks.com/making-disabled-buttons-more-inclusive/

</React.Fragment>
);
}
15 changes: 15 additions & 0 deletions test/regressions/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,21 @@ async function main() {
});
});

describe('<Button />', () => {
it('hover styles on disabled buttons', async () => {
const index = routes.findIndex((route) => route === '/regression-Button/DisabledButtons');
const testcase = await renderFixture(index);

// force: true so that pointer-events, layout etc is ignored
await page.hover('button:nth-of-type(1)', { force: true });
await takeScreenshot({ testcase, route: '/regression-Button/DisabledButtons-hover1' });
await page.hover('button:nth-of-type(2)', { force: true });
await takeScreenshot({ testcase, route: '/regression-Button/DisabledButtons-hover2' });
await page.hover('button:nth-of-type(3)', { force: true });
await takeScreenshot({ testcase, route: '/regression-Button/DisabledButtons-hover3' });
});
});

describe('Rating', () => {
it('should handle focus-visible correctly', async () => {
const index = routes.findIndex(
Expand Down