Skip to main content

ButtonGroup

iOS Android
ButtonGroup on iOS ButtonGroup on Android

A row of related buttons using MaterialButtonGroup and MaterialButtonToggleGroup (Material 3 Expressive) on Android and a row of UIButtons on iOS. Use it for a set of actions, or for single / multiple selection.

import { ButtonGroup } from 'react-native-platform-components';

// Actions
<ButtonGroup
buttons={[
{ label: 'Copy', value: 'copy' },
{ label: 'Paste', value: 'paste' },
]}
onPress={(value) => run(value)}
/>

// Single selection
<ButtonGroup
buttons={[
{ label: 'Day', value: 'day' },
{ label: 'Week', value: 'week' },
{ label: 'Month', value: 'month' },
]}
selection="single"
selectedValues={[range]}
onSelectionChange={([value]) => value && setRange(value)}
/>

Props

PropTypeDescription
buttonsButtonGroupButton[]Buttons to display
variant'filled' | 'tonal' | 'outlined' | 'text' | 'elevated'Emphasis of every button. See Button variants. Default: 'outlined'
size'xsmall' | 'small' | 'medium' | 'large' | 'xlarge'Size of every button. Default: 'small'
shape'round' | 'square'Corner shape of every button. Default: platform default
connectedbooleanConnected group. See Standard and connected. Default: true when selecting
spacingnumberGap between buttons in points. Default: the platform's group spacing
selection'none' | 'single' | 'multiple'Selection behavior. See Selection. Default: 'none'
selectedValuesstring[]Values of the selected buttons (controlled)
selectionRequiredbooleanWhether one button must stay selected. Default: true for single, false for multiple
disabledbooleanDisables the entire group
colorColorValueContainer (background) color of the buttons
tintColorColorValueLabel and icon color of the buttons
labelStyle{ fontFamily?, fontSize?, fontWeight?, fontStyle? }Label font
onPress(value: string, index: number) => voidCalled when a button is pressed, in every selection mode
onSelectionChange(values: string[]) => voidCalled when the selection changes, with the selected values in button order

ButtonGroupButton

PropertyTypeDescription
labelstringButton text. Omit for an icon-only button
valuestringUnique value returned in callbacks
disabledbooleanDisables this specific button
iconPlatformIconOptional icon. See Button icons
accessibilityLabelstringScreen-reader label. Defaults to label; give icon-only buttons one

Android Props (android)

PropTypeDescription
overflow'none' | 'menu' | 'wrap'Buttons that don't fit are clipped (default), moved into an overflow menu (MaterialButtonGroup overflow), or wrapped onto more rows
rippleColorColorValueRipple shown while pressing a button
strokeColorColorValueOutline color (outlined variant)
material'm3' | 'expressive'Material style: Material 3 Expressive (default) or the classic Material 3 group, which has one size and shape. See Button

Standard and connected

Material 3 Expressive has two kinds of button group:

  • Standard (connected: false, the default for actions): each button keeps its own shape and the group has a wider gap. On Android the pressed button widens and its neighbors shrink, the Expressive size morph.
  • Connected (connected: true, the default when selecting): the buttons share one outline with a hairline gap and small inner corners; the selected button rounds into a pill. This is the successor of Material's segmented buttons. Buttons size to their content; connected buttons also share any extra width equally when you stretch the group (alignSelf: 'stretch').

On iOS both kinds are a row of content-sized UIButtons: a 2pt gap for a connected group, 8pt for a standard one.

Selection

selectionBehavior
'none'Plain actions; only onPress fires
'single'One button selected at a time. Tapping the selected button clears it unless selectionRequired (the default for single)
'multiple'Any number of buttons selected. With selectionRequired, the last selected button can't be cleared

Selection is controlled: pass selectedValues and update it from onSelectionChange. Android uses MaterialButtonToggleGroup, so the selected buttons take the variant's selected colors and the Expressive checked shape. On iOS selected buttons switch to the filled configuration, as UIKit's own toggle buttons do.

const [format, setFormat] = useState<string[]>(['bold']);

<ButtonGroup
buttons={[
{ label: 'Bold', value: 'bold' },
{ label: 'Italic', value: 'italic' },
{ label: 'Underline', value: 'underline' },
]}
variant="tonal"
selection="multiple"
selectedValues={format}
onSelectionChange={setFormat}
/>

Styling

color, tintColor, labelStyle and the Android colors apply to every button; see Button styling. Without them the buttons take their colors from the theme, including the brand color set with useNativeTheme on Android.