suiss/uim · React Native Component

Button Group

A row or column of related buttons joined into one control.

Button Group is an open-source mobile component from suiss/uim for React Native and Expo, with SwiftUI and Jetpack Compose versions built from the same design tokens. The @esuiss/uim CLI copies its source into your project, so you own the code.

iOS
Button Group on iOS in light mode

ButtonGroup is a View with the group role that joins its children: only the outer ends keep their rounded corners and the shared borders collapse. It works with Button and with other controls such as inputs, selects and menu triggers. ghost and plain buttons are left unjoined.

Nest groups to keep separate clusters in one row with a gap between them. ButtonGroupSeparator draws a divider between joined buttons, and ButtonGroupText shows a label or icon in the same pill shape.

Installation

$ pnpm dlx @esuiss/uim@latest add button-group

The CLI also adds what it builds on: Button, Icon, Separator, Text.

Manual

  1. Install the dependencies:
npx expo install class-variance-authority cn
  1. Add the pieces it builds on: Button, Icon, Separator, Text, and the primitives components/primitives/types.tsx, components/primitives/use-render.tsx.

  2. Copy the source into components/ui/button-group.tsx:

uniwind/components/ui/button-group.tsx
import { cva, type VariantProps } from "class-variance-authority"
import { cn } from "cn"
import * as React from "react"
import { View, type ViewProps } from "react-native"
import type { ClassNameProp, RenderProp } from "@/components/primitives/types"
import { resolveClassName, useRender } from "@/components/primitives/use-render"
import {
  Button,
  ButtonClassContext,
  type ButtonVariant,
} from "@/components/ui/button"
import { IconClassContext } from "@/components/ui/icon"
import { Separator } from "@/components/ui/separator"
import { TextClassContext } from "@/components/ui/text"

type ButtonGroupOrientation = "horizontal" | "vertical"
  1. Update the import paths to match your project.

Usage

import { ButtonGroup, ButtonGroupText, ButtonGroupSeparator } from "@/components/ui/button-group"
<ButtonGroup>
  <ButtonGroup>
    <Button variant="secondary" size="icon" accessibilityLabel="Go back">
      <Icon as={ArrowLeftIcon} />
    </Button>
  </ButtonGroup>
  <ButtonGroup>
    <Button variant="secondary">
      <Text>Archive</Text>
    </Button>
    <ButtonGroupSeparator />
    <Button variant="secondary">
      <Text>Report</Text>
    </Button>
  </ButtonGroup>
  <ButtonGroup>
    <Button variant="secondary">
      <Text>Snooze</Text>
    </Button>
    <ButtonGroupSeparator />
    <DropdownMenu>
      <DropdownMenuTrigger
        accessibilityLabel="More options"
        render={<Button variant="secondary" size="icon" />}
      >
        <Icon as={DotsThreeIcon} />
      </DropdownMenuTrigger>
      <MailMenuContent />
    </DropdownMenu>
  </ButtonGroup>
</ButtonGroup>

Set orientation="vertical" to stack the buttons. Use a separator between buttons of the same filled variant, such as in a split button, where there is no border to divide them.

Give icon-only buttons an accessibilityLabel, and give the group one when its purpose is not clear from its contents.

Examples

Outline

Nested groups of outline buttons.

iOS
Button Group (outline) on iOS in light mode

Orientation

A vertical group of zoom buttons with a horizontal separator.

iOS
Button Group (orientation) on iOS in light mode

Sizes

Groups at different button sizes.

iOS
Button Group (sizes) on iOS in light mode

Nested

Groups inside a group, spaced apart.

iOS
Button Group (nested) on iOS in light mode

With separator

Buttons divided by ButtonGroupSeparator.

iOS
Button Group (with separator) on iOS in light mode

Plain

plain buttons, which stay unjoined.

iOS
Button Group (plain) on iOS in light mode

Split button

A main action with a joined icon button for more options.

iOS
Button Group (split button) on iOS in light mode

With input

An input joined to a search button.

iOS
Button Group (with input) on iOS in light mode

With input group

An input group joined with buttons.

iOS
Button Group (with input group) on iOS in light mode

With text

A ButtonGroupText URL prefix joined to an input and a save button.

iOS
Button Group (with text) on iOS in light mode

With dropdown menu

A button joined to a dropdown menu trigger.

iOS
Button Group (with dropdown menu) on iOS in light mode

With select

A select joined to an input for a currency amount.

iOS
Button Group (with select) on iOS in light mode

With popover

A button joined to a popover trigger.

iOS
Button Group (with popover) on iOS in light mode

Pagination

Page buttons with previous and next arrows.

iOS
Button Group (pagination) on iOS in light mode

API Reference

ButtonGroup

Container that joins its children.

ExtendsViewProps
PropType
About
horizontal or vertical. Defaults to horizontal.
Type
"horizontal""vertical"
Default
"horizontal"

ButtonGroupText

Pill-shaped label or icon slot.

ExtendsViewProps
PropType
About
Element to render instead of the default View.
Type
RenderProp<Record<string, unknown>, Record<string, never>>
Default
—

ButtonGroupSeparator

Divider between joined buttons.

ExtendsReact.ComponentProps<typeof Separator>

Accessibility

  • The container has the group role.
  • Each button keeps its own role and state.
  • Icon-only buttons need an accessibilityLabel.

Notes

  • Uses bg-control for ButtonGroupText and a translucent label color for separators; light and dark follow the system appearance.