Skip to content

Commit

Permalink
[ButtonGroup] Fix rendering with conditional elements (#38989)
Browse files Browse the repository at this point in the history
  • Loading branch information
ZeeshanTamboli authored Oct 4, 2023
1 parent 62d3b96 commit 58504fa
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 8 deletions.
19 changes: 11 additions & 8 deletions packages/mui-material/src/ButtonGroup/ButtonGroup.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import PropTypes from 'prop-types';
import clsx from 'clsx';
import { unstable_composeClasses as composeClasses } from '@mui/base/composeClasses';
import { alpha } from '@mui/system';
import { getValidReactChildren } from '@mui/utils';
import capitalize from '../utils/capitalize';
import styled from '../styles/styled';
import useThemeProps from '../styles/useThemeProps';
Expand Down Expand Up @@ -256,9 +257,12 @@ const ButtonGroup = React.forwardRef(function ButtonGroup(inProps, ref) {
],
);

const getButtonPositionClassName = (index, childrenParam) => {
const validChildren = getValidReactChildren(children);
const childrenCount = validChildren.length;

const getButtonPositionClassName = (index) => {
const isFirstButton = index === 0;
const isLastButton = index === React.Children.count(childrenParam) - 1;
const isLastButton = index === childrenCount - 1;

if (isFirstButton && isLastButton) {
return '';
Expand All @@ -282,13 +286,12 @@ const ButtonGroup = React.forwardRef(function ButtonGroup(inProps, ref) {
{...other}
>
<ButtonGroupContext.Provider value={context}>
{React.Children.map(children, (child, index) => {
if (!React.isValidElement(child)) {
return child;
}

{validChildren.map((child, index) => {
return (
<ButtonGroupButtonContext.Provider value={getButtonPositionClassName(index, children)}>
<ButtonGroupButtonContext.Provider
key={index}
value={getButtonPositionClassName(index)}
>
{child}
</ButtonGroupButtonContext.Provider>
);
Expand Down
13 changes: 13 additions & 0 deletions packages/mui-utils/src/getValidReactChildren.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import * as React from 'react';

/**
* Gets only the valid children of a component,
* and ignores any nullish or falsy child.
*
* @param children the children
*/
export default function getValidReactChildren(children: React.ReactNode) {
return React.Children.toArray(children).filter((child) =>
React.isValidElement(child),
) as React.ReactElement[];
}
1 change: 1 addition & 0 deletions packages/mui-utils/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export {
getNormalizedScrollLeft as unstable_getNormalizedScrollLeft,
} from './scrollLeft';
export { default as usePreviousProps } from './usePreviousProps';
export { default as getValidReactChildren } from './getValidReactChildren';
export { default as visuallyHidden } from './visuallyHidden';
export { default as integerPropType } from './integerPropType';
export { default as internal_resolveProps } from './resolveProps';
Expand Down
9 changes: 9 additions & 0 deletions test/regressions/fixtures/ButtonGroup/DifferentChildren.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import Stack from '@mui/material/Stack';
import Tooltip from '@mui/material/Tooltip';

export default function DifferentChildren() {
const falsyCondition = 1 === 2;

return (
<Stack spacing={2}>
{/* It has one button with href which is rendered as anchor tag */}
Expand Down Expand Up @@ -35,6 +37,13 @@ export default function DifferentChildren() {
<ButtonGroup>
<Button>Single Button</Button>
</ButtonGroup>

{/* Conditional elements */}
<ButtonGroup>
<Button>One</Button>
<Button>Two</Button>
{falsyCondition ? <Button>Three</Button> : undefined}
</ButtonGroup>
</Stack>
);
}

0 comments on commit 58504fa

Please sign in to comment.