From d0dc81073eb14f5620c70e4f4bd6e9216a7b1272 Mon Sep 17 00:00:00 2001 From: Dhaval Vira <32231977+dhavalveera@users.noreply.github.com> Date: Tue, 12 Mar 2024 18:29:50 +0530 Subject: [PATCH] fix(ButtonGroup): dynamic generated button with group wasn't styled properly (#1273) fix(/button/buttongroup.tsx): dynamic generated buton with group wasnt styled properly Dynamically generated buttons within a button group are not properly styled. #1269 fix #1269 --- src/components/Button/ButtonGroup.tsx | 49 +++++++++++++++++++-------- 1 file changed, 35 insertions(+), 14 deletions(-) diff --git a/src/components/Button/ButtonGroup.tsx b/src/components/Button/ButtonGroup.tsx index 0016b6c77..aa25447b2 100644 --- a/src/components/Button/ButtonGroup.tsx +++ b/src/components/Button/ButtonGroup.tsx @@ -1,5 +1,5 @@ -import type { ComponentProps, FC, ReactElement } from 'react'; -import { Children, cloneElement, useMemo } from 'react'; +import type { ComponentProps, FC, ReactElement, ReactNode } from 'react'; +import { Children, cloneElement, isValidElement, useMemo } from 'react'; import { twMerge } from 'tailwind-merge'; import { mergeDeep } from '../../helpers/merge-deep'; import { getTheme } from '../../theme-store'; @@ -22,6 +22,37 @@ export interface ButtonGroupProps extends ComponentProps<'div'>, Pick; } +const processChildren = ( + children: React.ReactNode, + outline: boolean | undefined, + pill: boolean | undefined, +): ReactNode => { + return Children.map(children as ReactElement[], (child, index) => { + if (isValidElement(child)) { + // Check if the child has nested children + if (child.props.children) { + // Recursively process nested children + return cloneElement(child, { + ...child.props, + children: processChildren(child.props.children, outline, pill), + positionInGroup: determinePosition(index, Children.count(children)), + }); + } else { + return cloneElement(child, { + outline, + pill, + positionInGroup: determinePosition(index, Children.count(children)), + }); + } + } + return child; + }); +}; + +const determinePosition = (index: number, totalChildren: number) => { + return index === 0 ? 'start' : index === totalChildren - 1 ? 'end' : 'middle'; +}; + export const ButtonGroup: FC = ({ children, className, @@ -30,18 +61,8 @@ export const ButtonGroup: FC = ({ theme: customTheme = {}, ...props }: ButtonGroupProps) => { - const items = useMemo( - () => - Children.map(children as ReactElement[], (child, index) => - cloneElement(child, { - outline, - pill, - positionInGroup: - index === 0 ? 'start' : index === (children as ReactElement[]).length - 1 ? 'end' : 'middle', - }), - ), - [children, outline, pill], - ); + const items = useMemo(() => processChildren(children, outline, pill), [children, outline, pill]); + const theme = mergeDeep(getTheme().buttonGroup, customTheme); return (