Skip to content

SegmentedButton

A segmented button component powered by Jetpack Compose’s SingleChoiceSegmentedButtonRow and MultiChoiceSegmentedButtonRow with Material 3 styling.

import { SegmentedButton } from '@mgcrea/react-native-jetpack-compose';
const [size, setSize] = useState<string | null>('m');
<SegmentedButton
value={size}
onChange={setSize}
options={[
{ value: 's', label: 'S' },
{ value: 'm', label: 'M' },
{ value: 'l', label: 'L' },
]}
/>
PropTypeDefaultDescription
optionsSegmentedButtonOption[]RequiredArray of segment options
valuestring | null (single) or string[] (multi)-Currently selected value(s)
multiSelectbooleanfalseEnable multi-select mode
disabledbooleanfalseDisable the segmented button
styleViewStyle-Container style
EventTypeDescription
onChange(value: string) => void (single) or (values: string[]) => void (multi)Called when selection changes
interface SegmentedButtonOption {
value: string; // Unique identifier
label: string; // Display text
icon?: string; // Optional Material Icon name
}

The following Material Icons are supported:

check, star, favorite, home, settings, person, email, phone, search, add, close, done, edit, delete, share, info, warning, notifications, list

const [alignment, setAlignment] = useState<string | null>('left');
<SegmentedButton
value={alignment}
onChange={setAlignment}
options={[
{ value: 'left', label: 'Left' },
{ value: 'center', label: 'Center' },
{ value: 'right', label: 'Right' },
]}
/>
const [formats, setFormats] = useState<string[]>(['bold']);
<SegmentedButton
multiSelect
value={formats}
onChange={setFormats}
options={[
{ value: 'bold', label: 'B' },
{ value: 'italic', label: 'I' },
{ value: 'underline', label: 'U' },
]}
/>
const [viewMode, setViewMode] = useState<string | null>('list');
<SegmentedButton
value={viewMode}
onChange={setViewMode}
options={[
{ value: 'list', label: 'List', icon: 'list' },
{ value: 'grid', label: 'Grid', icon: 'star' },
]}
/>
<SegmentedButton
disabled
value="m"
onChange={() => {}}
options={[
{ value: 's', label: 'S' },
{ value: 'm', label: 'M' },
{ value: 'l', label: 'L' },
]}
/>
const [size, setSize] = useState<string | null>('m');
<SegmentedButton
value={size}
onChange={setSize}
options={[
{ value: 'xs', label: 'XS' },
{ value: 's', label: 'S' },
{ value: 'm', label: 'M' },
{ value: 'l', label: 'L' },
{ value: 'xl', label: 'XL' },
]}
/>
const [filters, setFilters] = useState<string[]>([]);
<SegmentedButton
multiSelect
value={filters}
onChange={setFilters}
options={[
{ value: 'favorites', label: 'Favorites', icon: 'favorite' },
{ value: 'recent', label: 'Recent', icon: 'notifications' },
{ value: 'shared', label: 'Shared', icon: 'share' },
]}
/>
interface Settings {
theme: string | null;
notifications: string[];
}
const [settings, setSettings] = useState<Settings>({
theme: 'system',
notifications: ['email'],
});
<SegmentedButton
value={settings.theme}
onChange={(theme) => setSettings(s => ({ ...s, theme }))}
options={[
{ value: 'light', label: 'Light' },
{ value: 'dark', label: 'Dark' },
{ value: 'system', label: 'System' },
]}
/>
<SegmentedButton
multiSelect
value={settings.notifications}
onChange={(notifications) => setSettings(s => ({ ...s, notifications }))}
options={[
{ value: 'email', label: 'Email', icon: 'email' },
{ value: 'push', label: 'Push', icon: 'notifications' },
{ value: 'sms', label: 'SMS', icon: 'phone' },
]}
/>
  • Few options (2-5) - Ideal for quick visual selection
  • Binary choices - Toggle between two states
  • Mode switching - Switch between views (list/grid, day/week/month)
  • Multi-select filters - Enable multiple toggleable options
  • Many options (6+) - Consider Picker or SheetPicker