diff --git a/docs/src/pages/demos/buttons/OutlinedButtons.js b/docs/src/pages/demos/buttons/OutlinedButtons.js
new file mode 100644
index 00000000000000..397672a835c8e8
--- /dev/null
+++ b/docs/src/pages/demos/buttons/OutlinedButtons.js
@@ -0,0 +1,55 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import { withStyles } from '@material-ui/core/styles';
+import Button from '@material-ui/core/Button';
+
+const styles = theme => ({
+ button: {
+ margin: theme.spacing.unit,
+ },
+});
+
+function doSomething(event) {
+ // eslint-disable-next-line no-console
+ console.log(event.currentTarget.getAttribute('data-something'));
+}
+
+function OutlinedButtons(props) {
+ const { classes } = props;
+ return (
+
+
+
+
+
+
+
+
+
+ );
+}
+
+OutlinedButtons.propTypes = {
+ classes: PropTypes.object.isRequired,
+};
+
+export default withStyles(styles)(OutlinedButtons);
diff --git a/docs/src/pages/demos/buttons/buttons.md b/docs/src/pages/demos/buttons/buttons.md
index a2c73ce7cc90be..0613f0675f52b1 100644
--- a/docs/src/pages/demos/buttons/buttons.md
+++ b/docs/src/pages/demos/buttons/buttons.md
@@ -18,6 +18,13 @@ They do not lift, but fill with color on press.
{{"demo": "pages/demos/buttons/FlatButtons.js"}}
+## Outlined Buttons
+Outlined buttons are text-only buttons with medium emphasis.
+They behave like flat buttons but have an outline and are typically used for actions that are important, but
+aren’t the primary action in an app.
+
+{{"demo": "pages/demos/buttons/OutlinedButtons.js"}}
+
## Raised Buttons
Raised buttons are rectangular-shaped buttons.
diff --git a/packages/material-ui/src/Button/Button.d.ts b/packages/material-ui/src/Button/Button.d.ts
index 664de5cfb9d1a2..8b2e8687954200 100644
--- a/packages/material-ui/src/Button/Button.d.ts
+++ b/packages/material-ui/src/Button/Button.d.ts
@@ -13,7 +13,7 @@ export interface ButtonProps extends StandardProps ({
},
},
},
+ outlined: {
+ border: `1px solid ${
+ theme.palette.type === 'light' ? 'rgba(0, 0, 0, 0.23)' : 'rgba(255, 255, 255, 0.23)'
+ }`,
+ borderRadius: 4,
+ },
colorInherit: {
color: 'inherit',
},
@@ -178,6 +184,7 @@ function Button(props) {
[classes.flatSecondary]: flat && color === 'secondary',
[classes.raisedPrimary]: !flat && color === 'primary',
[classes.raisedSecondary]: !flat && color === 'secondary',
+ [classes.outlined]: variant === 'outlined',
[classes[`size${capitalize(size)}`]]: size !== 'medium',
[classes.disabled]: disabled,
[classes.fullWidth]: fullWidth,
@@ -263,7 +270,7 @@ Button.propTypes = {
/**
* The type of button.
*/
- variant: PropTypes.oneOf(['flat', 'raised', 'fab']),
+ variant: PropTypes.oneOf(['flat', 'outlined', 'raised', 'fab']),
};
Button.defaultProps = {
diff --git a/packages/material-ui/src/Button/Button.test.js b/packages/material-ui/src/Button/Button.test.js
index 8de6ad2b1760f9..ae87d0a4b09c11 100644
--- a/packages/material-ui/src/Button/Button.test.js
+++ b/packages/material-ui/src/Button/Button.test.js
@@ -122,6 +122,48 @@ describe('', () => {
);
});
+ it('should render an outlined button', () => {
+ const wrapper = shallow();
+ assert.strictEqual(wrapper.hasClass(classes.root), true);
+ assert.strictEqual(wrapper.hasClass(classes.outlined), true, 'should have the outlined class');
+ assert.strictEqual(wrapper.hasClass(classes.raised), false, 'should not have the raised class');
+ assert.strictEqual(wrapper.hasClass(classes.fab), false, 'should not have the fab class');
+ });
+
+ it('should render a primary outlined button', () => {
+ const wrapper = shallow(
+ ,
+ );
+ assert.strictEqual(wrapper.hasClass(classes.root), true);
+ assert.strictEqual(wrapper.hasClass(classes.outlined), true, 'should have the outlined class');
+ assert.strictEqual(
+ wrapper.hasClass(classes.flatPrimary),
+ true,
+ 'should have the flatPrimary class',
+ );
+ assert.strictEqual(wrapper.hasClass(classes.raised), false, 'should not have the raised class');
+ assert.strictEqual(wrapper.hasClass(classes.fab), false, 'should not have the fab class');
+ });
+
+ it('should render a secondary outlined button', () => {
+ const wrapper = shallow(
+ ,
+ );
+ assert.strictEqual(wrapper.hasClass(classes.root), true);
+ assert.strictEqual(wrapper.hasClass(classes.outlined), true, 'should have the outlined class');
+ assert.strictEqual(
+ wrapper.hasClass(classes.flatSecondary),
+ true,
+ 'should have the flatSecondary class',
+ );
+ assert.strictEqual(wrapper.hasClass(classes.raised), false, 'should not have the raised class');
+ assert.strictEqual(wrapper.hasClass(classes.fab), false, 'should not have the fab class');
+ });
+
it('should render a floating action button', () => {
const wrapper = shallow();
assert.strictEqual(wrapper.hasClass(classes.root), true);
diff --git a/packages/material-ui/src/styles/MuiThemeProvider.test.js b/packages/material-ui/src/styles/MuiThemeProvider.test.js
index 21c65031ae546e..10f9db2c914f01 100644
--- a/packages/material-ui/src/styles/MuiThemeProvider.test.js
+++ b/packages/material-ui/src/styles/MuiThemeProvider.test.js
@@ -86,13 +86,13 @@ describe('', () => {
assert.notStrictEqual(markup.match('Hello World'), null);
assert.strictEqual(sheetsRegistry.registry.length, 3);
assert.strictEqual(sheetsRegistry.toString().length > 4000, true);
- assert.strictEqual(sheetsRegistry.registry[0].classes.root, 'MuiTouchRipple-root-19');
+ assert.strictEqual(sheetsRegistry.registry[0].classes.root, 'MuiTouchRipple-root-20');
assert.deepEqual(
sheetsRegistry.registry[1].classes,
{
- disabled: 'MuiButtonBase-disabled-17',
- focusVisible: 'MuiButtonBase-focusVisible-18',
- root: 'MuiButtonBase-root-16',
+ disabled: 'MuiButtonBase-disabled-18',
+ focusVisible: 'MuiButtonBase-focusVisible-19',
+ root: 'MuiButtonBase-root-17',
},
'the class names should be deterministic',
);
diff --git a/pages/api/button.md b/pages/api/button.md
index 348f26c968ecc2..7d9c3d5b8f2655 100644
--- a/pages/api/button.md
+++ b/pages/api/button.md
@@ -23,7 +23,7 @@ filename: /packages/material-ui/src/Button/Button.js
| href | string | | The URL to link to when the button is clicked. If defined, an `a` element will be used as the root node. |
| mini | bool | false | If `true`, and `variant` is `'fab'`, will use mini floating action button styling. |
| size | enum: 'small' |
'medium' |
'large'
| 'medium' | The size of the button. `small` is equivalent to the dense button styling. |
-| variant | enum: 'flat' |
'raised' |
'fab'
| 'flat' | The type of button. |
+| variant | enum: 'flat' |
'outlined' |
'raised' |
'fab'
| 'flat' | The type of button. |
Any other properties supplied will be [spread to the root element](/guides/api#spread).
@@ -35,6 +35,7 @@ This property accepts the following keys:
- `label`
- `flatPrimary`
- `flatSecondary`
+- `outlined`
- `colorInherit`
- `raised`
- `raisedPrimary`
diff --git a/pages/demos/buttons.js b/pages/demos/buttons.js
index 67ce8229c5c369..41d9f853c785a5 100644
--- a/pages/demos/buttons.js
+++ b/pages/demos/buttons.js
@@ -13,6 +13,13 @@ function Page() {
raw: preval`
module.exports = require('fs')
.readFileSync(require.resolve('docs/src/pages/demos/buttons/FlatButtons'), 'utf8')
+`,
+ },
+ 'pages/demos/buttons/OutlinedButtons.js': {
+ js: require('docs/src/pages/demos/buttons/OutlinedButtons').default,
+ raw: preval`
+module.exports = require('fs')
+ .readFileSync(require.resolve('docs/src/pages/demos/buttons/OutlinedButtons'), 'utf8')
`,
},
'pages/demos/buttons/RaisedButtons.js': {