Hanzo GUI

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/group

Usage

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:

PropTypeDefaultRequired
orientation"horizontal" | "vertical"--
sizestring | SizeTokens--
disabledboolean--
unstyledboolean--

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:

PropTypeDefaultRequired
childrenReactNode-
forcePlacement"first" | "center" | "last"--

Last updated on

On this page