diff --git a/docs/pages/material-ui/api/button-group.json b/docs/pages/material-ui/api/button-group.json
index ef1eb072c05e1b..a89d57e49e857b 100644
--- a/docs/pages/material-ui/api/button-group.json
+++ b/docs/pages/material-ui/api/button-group.json
@@ -54,6 +54,7 @@
"text",
"disableElevation",
"disabled",
+ "firstButton",
"fullWidth",
"vertical",
"grouped",
@@ -73,7 +74,9 @@
"groupedContainedHorizontal",
"groupedContainedVertical",
"groupedContainedPrimary",
- "groupedContainedSecondary"
+ "groupedContainedSecondary",
+ "lastButton",
+ "middleButton"
],
"globalClasses": { "disabled": "Mui-disabled" },
"name": "MuiButtonGroup"
diff --git a/docs/translations/api-docs/button-group/button-group.json b/docs/translations/api-docs/button-group/button-group.json
index 4f813acc0ba716..d2479a7bb3dee2 100644
--- a/docs/translations/api-docs/button-group/button-group.json
+++ b/docs/translations/api-docs/button-group/button-group.json
@@ -56,6 +56,10 @@
"nodeName": "the child elements",
"conditions": "disabled={true}
"
},
+ "firstButton": {
+ "description": "Styles applied to {{nodeName}}.",
+ "nodeName": "the first button in the button group"
+ },
"fullWidth": {
"description": "Styles applied to {{nodeName}} if {{conditions}}.",
"nodeName": "the root element",
@@ -151,6 +155,14 @@
"description": "Styles applied to {{nodeName}} if {{conditions}}.",
"nodeName": "the children",
"conditions": "variant=\"contained\"
and color=\"secondary\"
"
+ },
+ "lastButton": {
+ "description": "Styles applied to {{nodeName}}.",
+ "nodeName": "the last button in the button group"
+ },
+ "middleButton": {
+ "description": "Styles applied to {{nodeName}}.",
+ "nodeName": "buttons in the middle of the button group"
}
}
}
diff --git a/packages/mui-material/src/Button/Button.js b/packages/mui-material/src/Button/Button.js
index 5c1915b27e34c5..b287f9e603d545 100644
--- a/packages/mui-material/src/Button/Button.js
+++ b/packages/mui-material/src/Button/Button.js
@@ -296,17 +296,20 @@ const ButtonEndIcon = styled('span', {
...commonIconStyles(ownerState),
}));
-const addPositionDataAttributes = (buttonGroupButtonContext) => {
- if (buttonGroupButtonContext.isFirstButton && buttonGroupButtonContext.isLastButton) {
- return {};
+const addClassNameBasedOnPosition = (buttonGroupButtonContext) => {
+ if (
+ buttonGroupButtonContext.firstButtonClassName &&
+ buttonGroupButtonContext.lastButtonClassName
+ ) {
+ return '';
}
- if (buttonGroupButtonContext.isFirstButton) {
- return { 'data-first-child': '' };
+ if (buttonGroupButtonContext.firstButtonClassName) {
+ return buttonGroupButtonContext.firstButtonClassName;
}
- if (buttonGroupButtonContext.isLastButton) {
- return { 'data-last-child': '' };
+ if (buttonGroupButtonContext.lastButtonClassName) {
+ return buttonGroupButtonContext.lastButtonClassName;
}
- return { 'data-middle-child': '' };
+ return buttonGroupButtonContext.middleButtonClassName;
};
const Button = React.forwardRef(function Button(inProps, ref) {
@@ -360,22 +363,21 @@ const Button = React.forwardRef(function Button(inProps, ref) {
);
- let dataAttributes = {};
+ let positionClassName = '';
if (buttonGroupButtonContext) {
- dataAttributes = addPositionDataAttributes(buttonGroupButtonContext);
+ positionClassName = addClassNameBasedOnPosition(buttonGroupButtonContext);
}
return (
diff --git a/packages/mui-material/src/ButtonGroup/ButtonGroup.js b/packages/mui-material/src/ButtonGroup/ButtonGroup.js
index acb36d5a84ecd7..3046786bd3cb22 100644
--- a/packages/mui-material/src/ButtonGroup/ButtonGroup.js
+++ b/packages/mui-material/src/ButtonGroup/ButtonGroup.js
@@ -28,6 +28,15 @@ const overridesResolver = (props, styles) => {
[`& .${buttonGroupClasses.grouped}`]:
styles[`grouped${capitalize(ownerState.variant)}${capitalize(ownerState.color)}`],
},
+ {
+ [`& .${buttonGroupClasses.firstButton}`]: styles.firstButton,
+ },
+ {
+ [`& .${buttonGroupClasses.lastButton}`]: styles.lastButton,
+ },
+ {
+ [`& .${buttonGroupClasses.middleButton}`]: styles.middleButton,
+ },
styles.root,
styles[ownerState.variant],
ownerState.disableElevation === true && styles.disableElevation,
@@ -56,6 +65,9 @@ const useUtilityClasses = (ownerState) => {
`grouped${capitalize(variant)}${capitalize(color)}`,
disabled && 'disabled',
],
+ firstButton: ['firstButton'],
+ lastButton: ['lastButton'],
+ middleButton: ['middleButton'],
};
return composeClasses(slots, getButtonGroupUtilityClass, classes);
@@ -82,106 +94,106 @@ const ButtonGroupRoot = styled('div', {
}),
[`& .${buttonGroupClasses.grouped}`]: {
minWidth: 40,
- '&[data-last-child],&[data-middle-child]': {
- ...(ownerState.orientation === 'horizontal' && {
- borderTopLeftRadius: 0,
- borderBottomLeftRadius: 0,
- }),
- ...(ownerState.orientation === 'vertical' && {
- borderTopRightRadius: 0,
- borderTopLeftRadius: 0,
+ '&:hover': {
+ ...(ownerState.variant === 'contained' && {
+ boxShadow: 'none',
}),
- ...(ownerState.variant === 'outlined' &&
- ownerState.orientation === 'horizontal' && {
- marginLeft: -1,
- }),
- ...(ownerState.variant === 'outlined' &&
- ownerState.orientation === 'vertical' && {
- marginTop: -1,
- }),
},
- '&[data-first-child],&[data-middle-child]': {
- ...(ownerState.orientation === 'horizontal' && {
- borderTopRightRadius: 0,
- borderBottomRightRadius: 0,
+ ...(ownerState.variant === 'contained' && {
+ boxShadow: 'none',
+ }),
+ },
+ [`& .${buttonGroupClasses.firstButton},& .${buttonGroupClasses.middleButton}`]: {
+ ...(ownerState.orientation === 'horizontal' && {
+ borderTopRightRadius: 0,
+ borderBottomRightRadius: 0,
+ }),
+ ...(ownerState.orientation === 'vertical' && {
+ borderBottomRightRadius: 0,
+ borderBottomLeftRadius: 0,
+ }),
+ ...(ownerState.variant === 'text' &&
+ ownerState.orientation === 'horizontal' && {
+ borderRight: theme.vars
+ ? `1px solid rgba(${theme.vars.palette.common.onBackgroundChannel} / 0.23)`
+ : `1px solid ${
+ theme.palette.mode === 'light' ? 'rgba(0, 0, 0, 0.23)' : 'rgba(255, 255, 255, 0.23)'
+ }`,
+ [`&.${buttonGroupClasses.disabled}`]: {
+ borderRight: `1px solid ${(theme.vars || theme).palette.action.disabled}`,
+ },
}),
- ...(ownerState.orientation === 'vertical' && {
- borderBottomRightRadius: 0,
- borderBottomLeftRadius: 0,
+ ...(ownerState.variant === 'text' &&
+ ownerState.orientation === 'vertical' && {
+ borderBottom: theme.vars
+ ? `1px solid rgba(${theme.vars.palette.common.onBackgroundChannel} / 0.23)`
+ : `1px solid ${
+ theme.palette.mode === 'light' ? 'rgba(0, 0, 0, 0.23)' : 'rgba(255, 255, 255, 0.23)'
+ }`,
+ [`&.${buttonGroupClasses.disabled}`]: {
+ borderBottom: `1px solid ${(theme.vars || theme).palette.action.disabled}`,
+ },
}),
- ...(ownerState.variant === 'text' &&
- ownerState.orientation === 'horizontal' && {
- borderRight: theme.vars
- ? `1px solid rgba(${theme.vars.palette.common.onBackgroundChannel} / 0.23)`
- : `1px solid ${
- theme.palette.mode === 'light' ? 'rgba(0, 0, 0, 0.23)' : 'rgba(255, 255, 255, 0.23)'
- }`,
- [`&.${buttonGroupClasses.disabled}`]: {
- borderRight: `1px solid ${(theme.vars || theme).palette.action.disabled}`,
- },
- }),
- ...(ownerState.variant === 'text' &&
- ownerState.orientation === 'vertical' && {
- borderBottom: theme.vars
- ? `1px solid rgba(${theme.vars.palette.common.onBackgroundChannel} / 0.23)`
- : `1px solid ${
- theme.palette.mode === 'light' ? 'rgba(0, 0, 0, 0.23)' : 'rgba(255, 255, 255, 0.23)'
- }`,
- [`&.${buttonGroupClasses.disabled}`]: {
- borderBottom: `1px solid ${(theme.vars || theme).palette.action.disabled}`,
- },
- }),
- ...(ownerState.variant === 'text' &&
- ownerState.color !== 'inherit' && {
- borderColor: theme.vars
- ? `rgba(${theme.vars.palette[ownerState.color].mainChannel} / 0.5)`
- : alpha(theme.palette[ownerState.color].main, 0.5),
- }),
+ ...(ownerState.variant === 'text' &&
+ ownerState.color !== 'inherit' && {
+ borderColor: theme.vars
+ ? `rgba(${theme.vars.palette[ownerState.color].mainChannel} / 0.5)`
+ : alpha(theme.palette[ownerState.color].main, 0.5),
+ }),
+ ...(ownerState.variant === 'outlined' &&
+ ownerState.orientation === 'horizontal' && {
+ borderRightColor: 'transparent',
+ }),
+ ...(ownerState.variant === 'outlined' &&
+ ownerState.orientation === 'vertical' && {
+ borderBottomColor: 'transparent',
+ }),
+ ...(ownerState.variant === 'contained' &&
+ ownerState.orientation === 'horizontal' && {
+ borderRight: `1px solid ${(theme.vars || theme).palette.grey[400]}`,
+ [`&.${buttonGroupClasses.disabled}`]: {
+ borderRight: `1px solid ${(theme.vars || theme).palette.action.disabled}`,
+ },
+ }),
+ ...(ownerState.variant === 'contained' &&
+ ownerState.orientation === 'vertical' && {
+ borderBottom: `1px solid ${(theme.vars || theme).palette.grey[400]}`,
+ [`&.${buttonGroupClasses.disabled}`]: {
+ borderBottom: `1px solid ${(theme.vars || theme).palette.action.disabled}`,
+ },
+ }),
+ ...(ownerState.variant === 'contained' &&
+ ownerState.color !== 'inherit' && {
+ borderColor: (theme.vars || theme).palette[ownerState.color].dark,
+ }),
+ '&:hover': {
...(ownerState.variant === 'outlined' &&
ownerState.orientation === 'horizontal' && {
- borderRightColor: 'transparent',
+ borderRightColor: 'currentColor',
}),
...(ownerState.variant === 'outlined' &&
ownerState.orientation === 'vertical' && {
- borderBottomColor: 'transparent',
- }),
- ...(ownerState.variant === 'contained' &&
- ownerState.orientation === 'horizontal' && {
- borderRight: `1px solid ${(theme.vars || theme).palette.grey[400]}`,
- [`&.${buttonGroupClasses.disabled}`]: {
- borderRight: `1px solid ${(theme.vars || theme).palette.action.disabled}`,
- },
- }),
- ...(ownerState.variant === 'contained' &&
- ownerState.orientation === 'vertical' && {
- borderBottom: `1px solid ${(theme.vars || theme).palette.grey[400]}`,
- [`&.${buttonGroupClasses.disabled}`]: {
- borderBottom: `1px solid ${(theme.vars || theme).palette.action.disabled}`,
- },
+ borderBottomColor: 'currentColor',
}),
- ...(ownerState.variant === 'contained' &&
- ownerState.color !== 'inherit' && {
- borderColor: (theme.vars || theme).palette[ownerState.color].dark,
- }),
- '&:hover': {
- ...(ownerState.variant === 'outlined' &&
- ownerState.orientation === 'horizontal' && {
- borderRightColor: 'currentColor',
- }),
- ...(ownerState.variant === 'outlined' &&
- ownerState.orientation === 'vertical' && {
- borderBottomColor: 'currentColor',
- }),
- },
- },
- '&:hover': {
- ...(ownerState.variant === 'contained' && {
- boxShadow: 'none',
- }),
},
- ...(ownerState.variant === 'contained' && {
- boxShadow: 'none',
+ },
+ [`& .${buttonGroupClasses.lastButton},& .${buttonGroupClasses.middleButton}`]: {
+ ...(ownerState.orientation === 'horizontal' && {
+ borderTopLeftRadius: 0,
+ borderBottomLeftRadius: 0,
}),
+ ...(ownerState.orientation === 'vertical' && {
+ borderTopRightRadius: 0,
+ borderTopLeftRadius: 0,
+ }),
+ ...(ownerState.variant === 'outlined' &&
+ ownerState.orientation === 'horizontal' && {
+ marginLeft: -1,
+ }),
+ ...(ownerState.variant === 'outlined' &&
+ ownerState.orientation === 'vertical' && {
+ marginTop: -1,
+ }),
},
}));
@@ -245,8 +257,10 @@ const ButtonGroup = React.forwardRef(function ButtonGroup(inProps, ref) {
);
const buttonGroupPositionContext = (index, childrenParam) => ({
- isFirstButton: index === 0,
- isLastButton: index === React.Children.count(childrenParam) - 1,
+ firstButtonClassName: index === 0 ? classes.firstButton : '',
+ lastButtonClassName:
+ index === React.Children.count(childrenParam) - 1 ? classes.lastButton : '',
+ middleButtonClassName: classes.middleButton,
});
return (
diff --git a/packages/mui-material/src/ButtonGroup/ButtonGroupButtonContext.ts b/packages/mui-material/src/ButtonGroup/ButtonGroupButtonContext.ts
index 5d3b96c2da914b..dc5809a7c16cb5 100644
--- a/packages/mui-material/src/ButtonGroup/ButtonGroupButtonContext.ts
+++ b/packages/mui-material/src/ButtonGroup/ButtonGroupButtonContext.ts
@@ -1,8 +1,9 @@
import * as React from 'react';
interface ButtonGroupButtonContextType {
- isFirstButton?: boolean;
- isLastButton?: boolean;
+ firstButtonClassName?: string;
+ lastButtonClassName?: string;
+ middleButtonClassName?: string;
}
/**
diff --git a/packages/mui-material/src/ButtonGroup/buttonGroupClasses.ts b/packages/mui-material/src/ButtonGroup/buttonGroupClasses.ts
index 55dec11fdfe720..433083e3ae20f9 100644
--- a/packages/mui-material/src/ButtonGroup/buttonGroupClasses.ts
+++ b/packages/mui-material/src/ButtonGroup/buttonGroupClasses.ts
@@ -14,6 +14,8 @@ export interface ButtonGroupClasses {
disableElevation: string;
/** State class applied to the child elements if `disabled={true}`. */
disabled: string;
+ /** Styles applied to the first button in the button group. */
+ firstButton: string;
/** Styles applied to the root element if `fullWidth={true}`. */
fullWidth: string;
/** Styles applied to the root element if `orientation="vertical"`. */
@@ -54,6 +56,10 @@ export interface ButtonGroupClasses {
groupedContainedPrimary: string;
/** Styles applied to the children if `variant="contained"` and `color="secondary"`. */
groupedContainedSecondary: string;
+ /** Styles applied to the last button in the button group. */
+ lastButton: string;
+ /** Styles applied to buttons in the middle of the button group. */
+ middleButton: string;
}
export type ButtonGroupClassKey = keyof ButtonGroupClasses;
@@ -69,6 +75,7 @@ const buttonGroupClasses: ButtonGroupClasses = generateUtilityClasses('MuiButton
'text',
'disableElevation',
'disabled',
+ 'firstButton',
'fullWidth',
'vertical',
'grouped',
@@ -89,6 +96,8 @@ const buttonGroupClasses: ButtonGroupClasses = generateUtilityClasses('MuiButton
'groupedContainedVertical',
'groupedContainedPrimary',
'groupedContainedSecondary',
+ 'lastButton',
+ 'middleButton',
]);
export default buttonGroupClasses;