Group

Render horizontal or vertical groups easily

Features

  • 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 tamagui, or you can install it independently:

yarn add @tamagui/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 'tamagui'
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 '@tamagui/lucide-icons-2'
import { Button, XGroup } from 'tamagui'
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 'tamagui'
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 'tamagui'
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

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

useGroupItem

For full control, use the useGroupItem hook directly in your custom component:

import { useGroupItem } from '@tamagui/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 Tamagui standard props, plus:

Props

  • orientation

    "horizontal" | "vertical"

    Forces applying the border radius styles to left/right vs top/bottom. Defaults to horizontal for XGroup and vertical for YGroup.

  • size

    string | SizeTokens

    Sets the border radius of the Group container using your size tokens.

  • disabled

    boolean

    Passes disabled state down to children.

  • unstyled

    boolean

    Removes all default Tamagui styles.

  • Group.Item

    Wrap each of XGroup or YGroup’s children in one of these. It lets Tamagui apply the needed styles to them. It accepts the following props:

    Props

  • children (required)

    ReactNode

    The child element to wrap.

  • forcePlacement

    "first" | "center" | "last"

    Forces the item to be a starting, center, or ending item and applies the respective styles.