Skip to content

Commit

Permalink
use classnames instead of data attributes
Browse files Browse the repository at this point in the history
  • Loading branch information
ZeeshanTamboli committed Sep 6, 2023
1 parent 77f651d commit 1939e1b
Show file tree
Hide file tree
Showing 6 changed files with 146 additions and 105 deletions.
5 changes: 4 additions & 1 deletion docs/pages/material-ui/api/button-group.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
"text",
"disableElevation",
"disabled",
"firstButton",
"fullWidth",
"vertical",
"grouped",
Expand All @@ -73,7 +74,9 @@
"groupedContainedHorizontal",
"groupedContainedVertical",
"groupedContainedPrimary",
"groupedContainedSecondary"
"groupedContainedSecondary",
"lastButton",
"middleButton"
],
"globalClasses": { "disabled": "Mui-disabled" },
"name": "MuiButtonGroup"
Expand Down
12 changes: 12 additions & 0 deletions docs/translations/api-docs/button-group/button-group.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@
"nodeName": "the child elements",
"conditions": "<code>disabled={true}</code>"
},
"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",
Expand Down Expand Up @@ -151,6 +155,14 @@
"description": "Styles applied to {{nodeName}} if {{conditions}}.",
"nodeName": "the children",
"conditions": "<code>variant=\"contained\"</code> and <code>color=\"secondary\"</code>"
},
"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"
}
}
}
26 changes: 14 additions & 12 deletions packages/mui-material/src/Button/Button.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -360,22 +363,21 @@ const Button = React.forwardRef(function Button(inProps, ref) {
</ButtonEndIcon>
);

let dataAttributes = {};
let positionClassName = '';
if (buttonGroupButtonContext) {
dataAttributes = addPositionDataAttributes(buttonGroupButtonContext);
positionClassName = addClassNameBasedOnPosition(buttonGroupButtonContext);
}

return (
<ButtonRoot
ownerState={ownerState}
className={clsx(contextProps.className, classes.root, className)}
className={clsx(contextProps.className, classes.root, className, positionClassName)}
component={component}
disabled={disabled}
focusRipple={!disableFocusRipple}
focusVisibleClassName={clsx(classes.focusVisible, focusVisibleClassName)}
ref={ref}
type={type}
{...dataAttributes}
{...other}
classes={classes}
>
Expand Down
194 changes: 104 additions & 90 deletions packages/mui-material/src/ButtonGroup/ButtonGroup.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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);
Expand All @@ -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,
}),
},
}));

Expand Down Expand Up @@ -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 (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import * as React from 'react';

interface ButtonGroupButtonContextType {
isFirstButton?: boolean;
isLastButton?: boolean;
firstButtonClassName?: string;
lastButtonClassName?: string;
middleButtonClassName?: string;
}

/**
Expand Down
9 changes: 9 additions & 0 deletions packages/mui-material/src/ButtonGroup/buttonGroupClasses.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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"`. */
Expand Down Expand Up @@ -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;
Expand All @@ -69,6 +75,7 @@ const buttonGroupClasses: ButtonGroupClasses = generateUtilityClasses('MuiButton
'text',
'disableElevation',
'disabled',
'firstButton',
'fullWidth',
'vertical',
'grouped',
Expand All @@ -89,6 +96,8 @@ const buttonGroupClasses: ButtonGroupClasses = generateUtilityClasses('MuiButton
'groupedContainedVertical',
'groupedContainedPrimary',
'groupedContainedSecondary',
'lastButton',
'middleButton',
]);

export default buttonGroupClasses;

0 comments on commit 1939e1b

Please sign in to comment.