diff --git a/packages/material-ui/src/Button/Button.js b/packages/material-ui/src/Button/Button.js index 373854bd4d9f90..001e1a61d570cd 100644 --- a/packages/material-ui/src/Button/Button.js +++ b/packages/material-ui/src/Button/Button.js @@ -7,6 +7,7 @@ import { componentPropType, chainPropTypes } from '@material-ui/utils'; import withStyles from '../styles/withStyles'; import { fade } from '../styles/colorManipulator'; import ButtonBase from '../ButtonBase'; +import deprecatedPropType from '../utils/deprecatedPropType'; import { capitalize } from '../utils/helpers'; export const styles = theme => ({ @@ -36,6 +37,9 @@ export const styles = theme => ({ '&$disabled': { color: theme.palette.action.disabled, }, + '&$focusVisible': { + backgroundColor: fade(theme.palette.text.primary, theme.palette.action.focusOpacity), + }, }, /* Styles applied to the span element that wraps the children. */ label: { @@ -58,6 +62,9 @@ export const styles = theme => ({ backgroundColor: 'transparent', }, }, + '&$focusVisible': { + backgroundColor: fade(theme.palette.primary.main, theme.palette.action.focusOpacity), + }, }, /* Styles applied to the root element if `variant="text"` and `color="secondary"`. */ textSecondary: { @@ -69,6 +76,9 @@ export const styles = theme => ({ backgroundColor: 'transparent', }, }, + '&$focusVisible': { + backgroundColor: fade(theme.palette.secondary.main, theme.palette.action.focusOpacity), + }, }, /* Styles applied to the root element for backwards compatibility with legacy variant naming. */ flat: {}, @@ -153,6 +163,9 @@ export const styles = theme => ({ backgroundColor: theme.palette.primary.main, }, }, + '&$focusVisible': { + backgroundColor: fade(theme.palette.primary.main, 1 - 2 * theme.palette.action.focusOpacity), + }, }, /* Styles applied to the root element if `variant="[contained | fab]"` and `color="secondary"`. */ containedSecondary: { @@ -165,6 +178,12 @@ export const styles = theme => ({ backgroundColor: theme.palette.secondary.main, }, }, + '&$focusVisible': { + backgroundColor: fade( + theme.palette.secondary.main, + 1 - 2 * theme.palette.action.focusOpacity, + ), + }, }, /* Styles applied to the root element for backwards compatibility with legacy variant naming. */ raised: {}, // legacy @@ -274,8 +293,9 @@ function Button(props) { {children} @@ -314,7 +334,11 @@ Button.propTypes = { * If `true`, the keyboard focus ripple will be disabled. * `disableRipple` must also be true. */ - disableFocusRipple: PropTypes.bool, + disableFocusRipple: deprecatedPropType( + PropTypes.bool, + 'Focus ripple is not part of Material design. ' + + 'If you want to enable it use `focusRipple` which is passed to `ButtonBase`', + ), /** * If `true`, the ripple effect will be disabled. */ @@ -390,7 +414,6 @@ Button.defaultProps = { color: 'default', component: 'button', disabled: false, - disableFocusRipple: false, fullWidth: false, mini: false, size: 'medium', diff --git a/packages/material-ui/src/Button/Button.test.js b/packages/material-ui/src/Button/Button.test.js index 59e08f2747cfe8..e7dfdaa12d9e6d 100644 --- a/packages/material-ui/src/Button/Button.test.js +++ b/packages/material-ui/src/Button/Button.test.js @@ -296,14 +296,32 @@ describe('); - assert.strictEqual(wrapper.props().focusRipple, true); + assert.isNotOk(wrapper.props().focusRipple); }); - it('should pass disableFocusRipple to ButtonBase', () => { - const wrapper = shallow(); - assert.strictEqual(wrapper.props().focusRipple, false); + describe('disableFocusRipple', () => { + beforeEach(() => { + consoleErrorMock.spy(); + }); + afterEach(() => { + consoleErrorMock.reset(); + }); + + it('should disable focusRipple in ButtonBase', () => { + const wrapper = shallow(); + assert.strictEqual(wrapper.props().focusRipple, false); + }); + + it('is deprecated', () => { + shallow(); + assert.strictEqual(consoleErrorMock.callCount(), 1); + assert.include( + consoleErrorMock.args()[0][0], + 'The prop `disableFocusRipple` of `Button` is deprecated.', + ); + }); }); it('should render Icon children with right classes', () => { diff --git a/packages/material-ui/src/styles/createPalette.d.ts b/packages/material-ui/src/styles/createPalette.d.ts index 969c1947afe57f..158fcf91f1d7d1 100644 --- a/packages/material-ui/src/styles/createPalette.d.ts +++ b/packages/material-ui/src/styles/createPalette.d.ts @@ -12,6 +12,7 @@ export interface TypeText { export interface TypeAction { active: string; + focusOpacity: number; hover: string; hoverOpacity: number; selected: string; diff --git a/packages/material-ui/src/styles/createPalette.js b/packages/material-ui/src/styles/createPalette.js index 7c3ef865d69820..e4e1e69cbf756c 100644 --- a/packages/material-ui/src/styles/createPalette.js +++ b/packages/material-ui/src/styles/createPalette.js @@ -31,6 +31,7 @@ export const light = { action: { // The color of an active action like an icon button. active: 'rgba(0, 0, 0, 0.54)', + focusOpacity: 0.12, // The color of an hovered action. hover: 'rgba(0, 0, 0, 0.08)', hoverOpacity: 0.08, @@ -58,6 +59,7 @@ export const dark = { }, action: { active: common.white, + focusOpacity: 0.15, hover: 'rgba(255, 255, 255, 0.1)', hoverOpacity: 0.1, selected: 'rgba(255, 255, 255, 0.2)', diff --git a/packages/material-ui/src/utils/deprecatedPropType.js b/packages/material-ui/src/utils/deprecatedPropType.js index 01eef8ca8d7299..5c4f60d48c28da 100644 --- a/packages/material-ui/src/utils/deprecatedPropType.js +++ b/packages/material-ui/src/utils/deprecatedPropType.js @@ -11,7 +11,9 @@ function deprecatedPropType(validator, reason) { if (typeof props[propName] !== 'undefined') { return new Error( `The ${location} \`${propFullNameSafe}\` of ` + - `\`${componentNameSafe}\` is deprecated. ${reason}`, + `\`${componentNameSafe}\` is deprecated. ${reason}${ + process.env.NODE_ENV === 'test' ? Date.now() : '' + }`, ); } diff --git a/pages/api/button.md b/pages/api/button.md index 8821b39a10f1e6..449ebf11df2061 100644 --- a/pages/api/button.md +++ b/pages/api/button.md @@ -23,7 +23,7 @@ import Button from '@material-ui/core/Button'; | color | enum: 'default' |
 'inherit' |
 'primary' |
 'secondary'
| 'default' | The color of the component. It supports those theme colors that make sense for this component. | | component | componentPropType | 'button' | The component used for the root node. Either a string to use a DOM element or a component. | | disabled | bool | false | If `true`, the button will be disabled. | -| disableFocusRipple | bool | false | If `true`, the keyboard focus ripple will be disabled. `disableRipple` must also be true. | +| ~~disableFocusRipple~~ | bool |   | *Deprecated*. undefined

If `true`, the keyboard focus ripple will be disabled. `disableRipple` must also be true. | | disableRipple | bool |   | If `true`, the ripple effect will be disabled. | | fullWidth | bool | false | If `true`, the button will take up the full width of its container. | | href | string |   | The URL to link to when the button is clicked. If defined, an `a` element will be used as the root node. |