Group
Render horizontal or vertical groups easily
- Accepts size prop for border radius.
- Align vertically or horizontally.
- Children control their own sizing.
- Disabled prop passes to children.
Installation
Group is already installed in @hanzo/gui, or you can install it independently:
npm install @hanzogui/groupUsage
Use Group with Group.Item wrapping each child. The orientation property determines the layout direction.
Group zeros out the border radius on connecting sides of children - the first child keeps its start radius, the last keeps its end radius, and middle items have no radius on connecting sides. For YGroup, this affects top/bottom radius. For XGroup, left/right radius.
import { Button, XGroup } from '@hanzo/gui'
export default () => (
<XGroup>
<XGroup.Item>
<Button>First</Button>
</XGroup.Item>
<XGroup.Item>
<Button>Second</Button>
</XGroup.Item>
<XGroup.Item>
<Button>Third</Button>
</XGroup.Item>
</XGroup>
)Sizing
In v2, children control their own sizing. Apply size props directly to the child components. For responsive sizing, use media queries on the children:
import { Activity, Airplay } from '@hanzogui/lucide-icons-2'
import { Button, XGroup } from '@hanzo/gui'
export default () => (
<XGroup>
<XGroup.Item>
<Button size="$3" $gtSm={{ size: '$5' }} icon={Activity}>
First
</Button>
</XGroup.Item>
<XGroup.Item>
<Button size="$3" $gtSm={{ size: '$5' }} icon={Airplay}>
Second
</Button>
</XGroup.Item>
</XGroup>
)The size prop on Group itself only affects the border radius of the group container:
import { Button, XGroup } from '@hanzo/gui'
export default () => (
<XGroup size="$6">
<XGroup.Item>
<Button>First</Button>
</XGroup.Item>
<XGroup.Item>
<Button>Second</Button>
</XGroup.Item>
<XGroup.Item>
<Button>Third</Button>
</XGroup.Item>
</XGroup>
)Separators
Add separators manually between items:
import { ListItem, Separator, YGroup } from '@hanzo/gui'
export default () => (
<YGroup>
<YGroup.Item>
<ListItem title="First" />
</YGroup.Item>
<Separator />
<YGroup.Item>
<ListItem title="Second" />
</YGroup.Item>
<Separator />
<YGroup.Item>
<ListItem title="Third" />
</YGroup.Item>
</YGroup>
)Disabled
The disabled property will pass to children.
Custom Components & Nested Items
Automatic index detection only works when Group.Item is a direct child of Group. If you wrap Group.Item inside a custom component, the automatic first/last detection won't work.
You have a few options:
Option 1: Use forcePlacement
If you know the position ahead of time, use the forcePlacement prop:
function MyFirstItem({ children }) {
return <XGroup.Item forcePlacement="first">{children}</XGroup.Item>
}
export default () => (
<XGroup>
<MyFirstItem>
<Button>First</Button>
</MyFirstItem>
<XGroup.Item>
<Button>Second</Button>
</XGroup.Item>
</XGroup>
)Option 2: Use useGroupItem hook
For full control, use the useGroupItem hook directly in your custom component:
import { useGroupItem } from '@hanzogui/group'
function MyItem({ children, forcePlacement }) {
const groupItemProps = useGroupItem({ disabled: false }, forcePlacement)
return React.cloneElement(children, groupItemProps)
}Option 3: Pass placement from parent
Calculate positions in the parent and pass them down:
const items = ['First', 'Second', 'Third']
export default () => (
<XGroup>
{items.map((item, i) => (
<XGroup.Item
key={item}
forcePlacement={i === 0 ? 'first' : i === items.length - 1 ? 'last' : 'center'}
>
<Button>{item}</Button>
</XGroup.Item>
))}
</XGroup>
)API Reference
Group
Group, XGroup and YGroup extend YStack, getting Gui standard props, plus:
| Prop | Type | Default | Required |
|---|---|---|---|
| orientation | "horizontal" | "vertical" | - | - |
| size | string | SizeTokens | - | - |
| disabled | boolean | - | - |
| unstyled | boolean | - | - |
Group.Item
Wrap each of XGroup or YGroup's children in one of these. It lets Hanzo GUI apply the needed styles to them. It accepts the following props:
| Prop | Type | Default | Required |
|---|---|---|---|
| children | ReactNode | - | ✓ |
| forcePlacement | "first" | "center" | "last" | - | - |
Last updated on