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

[ButtonGroup] Add orientation prop #18762

Merged
Show file tree
Hide file tree
Changes from 11 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
12 changes: 11 additions & 1 deletion docs/pages/api/button-group.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ You can learn more about the difference by [reading this guide](/guides/minimizi
| <span class="prop-name">disableFocusRipple</span> | <span class="prop-type">bool</span> | <span class="prop-default">false</span> | If `true`, the button keyboard focus ripple will be disabled. `disableRipple` must also be true. |
| <span class="prop-name">disableRipple</span> | <span class="prop-type">bool</span> | <span class="prop-default">false</span> | If `true`, the button ripple effect will be disabled. |
| <span class="prop-name">fullWidth</span> | <span class="prop-type">bool</span> | <span class="prop-default">false</span> | If `true`, the buttons will take up the full width of its container. |
| <span class="prop-name">orientation</span> | <span class="prop-type">'vertical'<br>&#124;&nbsp;'horizontal'</span> | <span class="prop-default">'vertical'</span> | The group orientation. |
| <span class="prop-name">size</span> | <span class="prop-type">'small'<br>&#124;&nbsp;'medium'<br>&#124;&nbsp;'large'</span> | <span class="prop-default">'medium'</span> | The size of the button. `small` is equivalent to the dense button styling. |
| <span class="prop-name">variant</span> | <span class="prop-type">'text'<br>&#124;&nbsp;'outlined'<br>&#124;&nbsp;'contained'</span> | <span class="prop-default">'outlined'</span> | The variant to use. |

Expand All @@ -48,18 +49,27 @@ Any other props supplied will be provided to the root element (native element).
|:-----|:-------------|:------------|
| <span class="prop-name">root</span> | <span class="prop-name">.MuiButtonGroup-root</span> | Styles applied to the root element.
| <span class="prop-name">contained</span> | <span class="prop-name">.MuiButtonGroup-contained</span> | Styles applied to the root element if `variant="contained"`.
| <span class="prop-name">disabled</span> | <span class="prop-name">.Mui-disabled</span> | Pseudo-class applied to child elements if `disabled={true}`.
| <span class="prop-name">fullWidth</span> | <span class="prop-name">.MuiButtonGroup-fullWidth</span> | Styles applied to the root element if `fullWidth={true}`.
| <span class="prop-name">vertical</span> | <span class="prop-name">.MuiButtonGroup-vertical</span> | Styles applied to the root element if `orientation="vertical"`.
| <span class="prop-name">grouped</span> | <span class="prop-name">.MuiButtonGroup-grouped</span> | Styles applied to the children.
| <span class="prop-name">groupedHorizontal</span> | <span class="prop-name">.MuiButtonGroup-groupedHorizontal</span> | Styles applied to the children if `orientation="horizontal"`.
| <span class="prop-name">groupedVertical</span> | <span class="prop-name">.MuiButtonGroup-groupedVertical</span> | Styles applied to the children if `orientation="vertical"`.
| <span class="prop-name">groupedText</span> | <span class="prop-name">.MuiButtonGroup-groupedText</span> | Styles applied to the children if `variant="text"`.
| <span class="prop-name">groupedTextHorizontal</span> | <span class="prop-name">.MuiButtonGroup-groupedTextHorizontal</span> | Styles applied to the children if `variant="text"` and `orientation="horizontal"`.
| <span class="prop-name">groupedTextVertical</span> | <span class="prop-name">.MuiButtonGroup-groupedTextVertical</span> | Styles applied to the children if `variant="text"` and `orientation="vertical"`.
| <span class="prop-name">groupedTextPrimary</span> | <span class="prop-name">.MuiButtonGroup-groupedTextPrimary</span> | Styles applied to the children if `variant="text"` and `color="primary"`.
| <span class="prop-name">groupedTextSecondary</span> | <span class="prop-name">.MuiButtonGroup-groupedTextSecondary</span> | Styles applied to the children if `variant="text"` and `color="secondary"`.
| <span class="prop-name">groupedOutlined</span> | <span class="prop-name">.MuiButtonGroup-groupedOutlined</span> | Styles applied to the children if `variant="outlined"`.
| <span class="prop-name">groupedOutlinedHorizontal</span> | <span class="prop-name">.MuiButtonGroup-groupedOutlinedHorizontal</span> | Styles applied to the children if `variant="outlined"` and `orientation="horizontal"`.
| <span class="prop-name">groupedOutlinedVertical</span> | <span class="prop-name">.MuiButtonGroup-groupedOutlinedVertical</span> | Styles applied to the children if `variant="outlined"` and `orientation="vertical"`.
| <span class="prop-name">groupedOutlinedPrimary</span> | <span class="prop-name">.MuiButtonGroup-groupedOutlinedPrimary</span> | Styles applied to the children if `variant="outlined"` and `color="primary"`.
| <span class="prop-name">groupedOutlinedSecondary</span> | <span class="prop-name">.MuiButtonGroup-groupedOutlinedSecondary</span> | Styles applied to the children if `variant="outlined"` and `color="secondary"`.
| <span class="prop-name">groupedContained</span> | <span class="prop-name">.MuiButtonGroup-groupedContained</span> | Styles applied to the children if `variant="contained"`.
| <span class="prop-name">groupedContainedHorizontal</span> | <span class="prop-name">.MuiButtonGroup-groupedContainedHorizontal</span> | Styles applied to the children if `variant="contained"` and `orientation="horizontal"`.
| <span class="prop-name">groupedContainedVertical</span> | <span class="prop-name">.MuiButtonGroup-groupedContainedVertical</span> | Styles applied to the children if `variant="contained"` and `orientation="vertical"`.
| <span class="prop-name">groupedContainedPrimary</span> | <span class="prop-name">.MuiButtonGroup-groupedContainedPrimary</span> | Styles applied to the children if `variant="contained"` and `color="primary"`.
| <span class="prop-name">groupedContainedSecondary</span> | <span class="prop-name">.MuiButtonGroup-groupedContainedSecondary</span> | Styles applied to the children if `variant="contained"` and `color="secondary"`.
| <span class="prop-name">disabled</span> | <span class="prop-name">.Mui-disabled</span> | Pseudo-class applied to child elements if `disabled={true}`.

You can override the style of the component thanks to one of these customization points:

Expand Down
14 changes: 12 additions & 2 deletions packages/material-ui/src/ButtonGroup/ButtonGroup.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export interface ButtonGroupTypeMap<P = {}, D extends React.ElementType = 'div'>
disableFocusRipple?: boolean;
disableRipple?: boolean;
fullWidth?: boolean;
orientation?: 'vertical' | 'horizontal';
size?: 'small' | 'medium' | 'large';
variant?: 'text' | 'outlined' | 'contained';
};
Expand All @@ -21,18 +22,27 @@ declare const ButtonGroup: OverridableComponent<ButtonGroupTypeMap>;
export type ButtonGroupClassKey =
| 'root'
| 'contained'
| 'disabled'
| 'fullWidth'
| 'vertical'
| 'grouped'
| 'groupedHorizontal'
| 'groupedVertical'
| 'groupedText'
| 'groupedTextHorizontal'
| 'groupedTextVertical'
| 'groupedTextPrimary'
| 'groupedTextSecondary'
| 'groupedOutlined'
| 'groupedOutlinedHorizontal'
| 'groupedOutlinedVertical'
| 'groupedOutlinedPrimary'
| 'groupedOutlinedSecondary'
| 'groupedContained'
| 'groupedContainedHorizontal'
| 'groupedContainedVertical'
| 'groupedContainedPrimary'
| 'groupedContainedSecondary'
| 'disabled';
| 'groupedContainedSecondary';

export type ButtonGroupProps<
D extends React.ElementType = ButtonGroupTypeMap['defaultComponent'],
Expand Down
72 changes: 66 additions & 6 deletions packages/material-ui/src/ButtonGroup/ButtonGroup.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,22 @@ export const styles = theme => ({
contained: {
boxShadow: theme.shadows[2],
},
/* Pseudo-class applied to child elements if `disabled={true}`. */
disabled: {},
/* Styles applied to the root element if `fullWidth={true}`. */
fullWidth: {
width: '100%',
},
/* Styles applied to the root element if `orientation="vertical"`. */
vertical: {
flexDirection: 'column',
},
/* Styles applied to the children. */
grouped: {
minWidth: 40,
},
/* Styles applied to the children if `orientation="horizontal"`. */
groupedHorizontal: {
'&:not(:first-child)': {
borderTopLeftRadius: 0,
borderBottomLeftRadius: 0,
Expand All @@ -37,14 +46,35 @@ export const styles = theme => ({
borderBottomRightRadius: 0,
},
},
/* Styles applied to the children if `orientation="vertical"`. */
groupedVertical: {
'&:not(:first-child)': {
borderTopRightRadius: 0,
borderTopLeftRadius: 0,
},
'&:not(:last-child)': {
borderBottomRightRadius: 0,
borderBottomLeftRadius: 0,
},
},
/* Styles applied to the children if `variant="text"`. */
groupedText: {
groupedText: {},
/* Styles applied to the children if `variant="text"` and `orientation="horizontal"`. */
groupedTextHorizontal: {
'&:not(:last-child)': {
borderRight: `1px solid ${
theme.palette.type === 'light' ? 'rgba(0, 0, 0, 0.23)' : 'rgba(255, 255, 255, 0.23)'
}`,
},
},
/* Styles applied to the children if `variant="text"` and `orientation="vertical"`. */
groupedTextVertical: {
'&:not(:last-child)': {
borderBottom: `1px solid ${
theme.palette.type === 'light' ? 'rgba(0, 0, 0, 0.23)' : 'rgba(255, 255, 255, 0.23)'
}`,
},
},
/* Styles applied to the children if `variant="text"` and `color="primary"`. */
groupedTextPrimary: {
'&:not(:last-child)': {
Expand All @@ -58,14 +88,25 @@ export const styles = theme => ({
},
},
/* Styles applied to the children if `variant="outlined"`. */
groupedOutlined: {
groupedOutlined: {},
/* Styles applied to the children if `variant="outlined"` and `orientation="horizontal"`. */
groupedOutlinedHorizontal: {
'&:not(:first-child)': {
marginLeft: -1,
},
'&:not(:last-child)': {
borderRightColor: 'transparent',
},
},
/* Styles applied to the children if `variant="outlined"` and `orientation="vertical"`. */
groupedOutlinedVertical: {
'&:not(:first-child)': {
marginTop: -1,
},
'&:not(:last-child)': {
borderBottomColor: 'transparent',
},
},
/* Styles applied to the children if `variant="outlined"` and `color="primary"`. */
groupedOutlinedPrimary: {
'&:hover': {
Expand All @@ -81,27 +122,38 @@ export const styles = theme => ({
/* Styles applied to the children if `variant="contained"`. */
groupedContained: {
boxShadow: 'none',
},
/* Styles applied to the children if `variant="contained"` and `orientation="horizontal"`. */
groupedContainedHorizontal: {
'&:not(:last-child)': {
borderRight: `1px solid ${theme.palette.grey[400]}`,
'&$disabled': {
borderRight: `1px solid ${theme.palette.action.disabled}`,
},
},
},

/* Styles applied to the children if `variant="contained"` and `orientation="vertical"`. */
groupedContainedVertical: {
'&:not(:last-child)': {
borderBottom: `1px solid ${theme.palette.grey[400]}`,
'&$disabled': {
borderBottom: `1px solid ${theme.palette.action.disabled}`,
},
},
},
/* Styles applied to the children if `variant="contained"` and `color="primary"`. */
groupedContainedPrimary: {
'&:not(:last-child)': {
borderRight: `1px solid ${theme.palette.primary.dark}`,
borderColor: theme.palette.primary.dark,
},
},
/* Styles applied to the children if `variant="contained"` and `color="secondary"`. */
groupedContainedSecondary: {
'&:not(:last-child)': {
borderRight: `1px solid ${theme.palette.secondary.dark}`,
borderColor: theme.palette.secondary.dark,
},
},
/* Pseudo-class applied to child elements if `disabled={true}`. */
disabled: {},
});

const ButtonGroup = React.forwardRef(function ButtonGroup(props, ref) {
Expand All @@ -115,14 +167,17 @@ const ButtonGroup = React.forwardRef(function ButtonGroup(props, ref) {
disableFocusRipple = false,
disableRipple = false,
fullWidth = false,
orientation = 'vertical',
SandraMarcelaHerreraArriaga marked this conversation as resolved.
Show resolved Hide resolved
size = 'medium',
variant = 'outlined',
...other
} = props;

const buttonClassName = clsx(
classes.grouped,
classes[`grouped${capitalize(orientation)}`],
classes[`grouped${capitalize(variant)}`],
classes[`grouped${capitalize(variant)}${capitalize(orientation)}`],
classes[`grouped${capitalize(variant)}${color !== 'default' ? capitalize(color) : ''}`],
{
[classes.disabled]: disabled,
Expand All @@ -136,6 +191,7 @@ const ButtonGroup = React.forwardRef(function ButtonGroup(props, ref) {
classes.root,
{
[classes.contained]: variant === 'contained',
[classes.vertical]: orientation === 'vertical',
[classes.fullWidth]: fullWidth,
},
className,
Expand Down Expand Up @@ -214,6 +270,10 @@ ButtonGroup.propTypes = {
* If `true`, the buttons will take up the full width of its container.
*/
fullWidth: PropTypes.bool,
/**
* The group orientation.
*/
orientation: PropTypes.oneOf(['vertical', 'horizontal']),
/**
* The size of the button.
* `small` is equivalent to the dense button styling.
Expand Down