Skip to content

Commit

Permalink
fix(Group): Use flexbox styles for growing group child elements (#3863)
Browse files Browse the repository at this point in the history
  • Loading branch information
markhigham authored Aug 19, 2024
1 parent 41b8d4b commit 889b914
Show file tree
Hide file tree
Showing 3 changed files with 11 additions and 89 deletions.
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import React from 'react'
import styled from 'styled-components'
import { Meta, StoryFn } from '@storybook/react'

import { Group } from '.'
import { Button } from '../Button'
import { getSpacings } from '../../tokens/utils'

export default {
component: Group,
Expand All @@ -18,12 +18,7 @@ export default {
},
argTypes: {
gap: {
options: [
...Array.from({ length: 21 }, (_, i) => i.toString()),
'px',
'half',
'full',
],
options: [...getSpacings(), 'px', 'half', 'full'],
},
justify: {
options: [
Expand All @@ -41,6 +36,9 @@ export default {
wrap: {
options: ['wrap', 'nowrap', 'wrap-reverse'],
},
grow: {
control: 'boolean',
},
},
} as Meta<typeof Group>

Expand All @@ -57,49 +55,3 @@ Default.args = {
justify: 'flex-start',
grow: false,
}

const StyledButton = styled(Button)`
overflow: hidden;
`

const StyledP = styled.p`
margin: 1rem 0;
`

export const PreventGrowOverflow: StoryFn<typeof Group> = (_props) => (
<div>
<StyledP>
preventGrowOverflow: <b>true</b> – each child width is always limited to
33% of parent width (since there are 3 children)
</StyledP>

<Group grow wrap="nowrap" gap="10">
<Button variant="primary">First button</Button>
<StyledButton variant="primary">
Second button with large content
</StyledButton>
<Button variant="primary">Third button</Button>
</Group>

<StyledP>
preventGrowOverflow: <b>false</b> – children will grow based on their
content, they can take more than 33% of parent width
</StyledP>

<Group grow preventGrowOverflow={false} wrap="nowrap" gap="10">
<Button variant="primary">First button</Button>
<Button variant="primary">Second button with large content</Button>
<Button variant="primary">Third button</Button>
</Group>
</div>
)

PreventGrowOverflow.storyName = 'preventGrowOverflow'
PreventGrowOverflow.parameters = {
docs: {
description: {
story:
'preventGrowOverflow prop allows you to control how Group children should behave when there is not enough space to fit them all on one line. By default, children are not allowed to take more space than (1 / children.length) * 100% of parent width (preventGrowOverflow is set to true). To change this behavior, set preventGrowOverflow to false and children will be allowed to grow and take as much space as they need.',
},
},
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,29 +39,13 @@ describe('Group', () => {
expect(container.firstChild).toHaveStyleRule('flex-wrap', 'nowrap')
})

it('apply flex-grow to children when grow is true', () => {
it('apply flex:1 to children when grow is true', () => {
const { container } = render(<Group grow>Content</Group>)
expect(container.firstChild).toHaveStyleRule('flex-grow', '1', {
expect(container.firstChild).toHaveStyleRule('flex', '1', {
modifier: '> *',
})
})

it('apply max-width to children when preventGrowOverflow is true', () => {
const customGap = '2'
const { container } = render(
<Group grow preventGrowOverflow gap={customGap}>
<div>Child 1</div>
<div>Child 2</div>
<div>Child 3</div>
</Group>
)
expect(container.firstChild).toHaveStyleRule(
'max-width',
`calc(33.333333333333336% - (${spacing(customGap)} / 3))`,
{ modifier: '> *' }
)
})

it('render with the specified HTML element', () => {
const { container } = render(<Group el="section">Content</Group>)
expect(container?.firstChild?.nodeName).toBe('SECTION')
Expand Down
22 changes: 4 additions & 18 deletions packages/react-component-library/src/components/Group/Group.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ interface GroupProps extends ComponentWithClass {
*/
gap?: Spacing
/**
* Controls `justify-content` CSS property, `'flex-start'` by default.
* Controls horizontal `justify-content` CSS property, `'flex-start'` by default.
*/
justify?: CSS.Properties['justifyContent']
/**
* Controls `align-items` CSS property, `'center'` by default.
* Controls vertical `align-items` CSS property, `'center'` by default.
*/
align?: CSS.Properties['alignItems']
/**
Expand All @@ -30,12 +30,6 @@ interface GroupProps extends ComponentWithClass {
* style, `false` by default.
*/
grow?: boolean
/**
* Determines whether children should take only dedicated amount of
* space (`max-width` style is set based on the number of children)
* , `true` by default.
*/
preventGrowOverflow?: boolean
/**
* The type of element to use for the root node, `'div'` by default.
*/
Expand All @@ -55,17 +49,11 @@ const StyledGroup = styled.div<StyledGroupProps>`
justify-content: ${({ $justify }) => $justify};
flex-wrap: ${({ $wrap }) => $wrap};
${({ $grow, $gap, $preventGrowOverflow }) =>
${({ $grow }) =>
$grow &&
css`
> * {
flex-grow: 1;
${$preventGrowOverflow &&
css`
max-width: ${$gap === '0'
? '33.333333333333336%'
: `calc(33.333333333333336% - (${spacing($gap!)} / 3))`};
`}
flex: 1;
}
`}
`
Expand All @@ -79,7 +67,6 @@ export const Group = ({
justify = 'flex-start',
wrap = 'wrap',
grow = false,
preventGrowOverflow = true,
}: GroupProps) => {
return (
children && (
Expand All @@ -91,7 +78,6 @@ export const Group = ({
$justify={justify}
$wrap={wrap}
$grow={grow}
$preventGrowOverflow={preventGrowOverflow}
>
{children}
</StyledGroup>
Expand Down

0 comments on commit 889b914

Please sign in to comment.