Skip to main content
In progress

ButtonGroup

A ButtonGroup is a selection component that groups multiple buttons into one structured unit so users can make single or multiple selections, apply filters, or toggle view states directly in the interface.

Code example
import { ButtonGroup } from '@yleisradio/yds-components-react';

<ButtonGroup>
<ButtonGroup.Button id="btn-1">Option 1</ButtonGroup.Button>
<ButtonGroup.Button id="btn-2">Option 2</ButtonGroup.Button>
<ButtonGroup.Button id="btn-3">Option 3</ButtonGroup.Button>
</ButtonGroup>

Why to use

ButtonGroup offers a compact, highly visible way to present related options side by side. It allows users to compare choices at a glance and make selections without opening menus or dialogs. ButtonGroup supports both single- and multi-select patterns and is well suited for filters, view modes, and inline state controls.

When to use

Use a ButtonGroup when users need to select between a small set of options that should remain visible at all times.

ButtonGroup supports multiple selection patterns

PatternWhat it doesTypical use cases
Single SelectAllows one option at a time; selecting a new option deselects the previous one.View or mode switching (e.g., tuntinäkymä / päivät / karttanäkymät).
Filterable (Multi-select)Allows zero or more options to be active simultaneously, often with visual selection indicators.Content filtering by categories, tags, or features.
Toggle actionsToggles UI states on or off directly within the interface.Enabling or disabling settings or view options without opening a menu.
Do
  • Use ButtonGroup when options must be immediately visible and easily comparable.
  • Use it for switching modes, applying filters, or toggling view states.
  • Use single-select when options are mutually exclusive.
  • Use multi-select when multiple options can be active at the same time.
Don't
  • Don’t use ButtonGroup for long or complex lists — use Select or DropdownMenuGroup.
  • Don’t use it for page-level navigation — use NavigationTabs instead.
  • Don’t use ButtonGroup for switching content within a section — use SectionTabs instead.
  • Don’t mix unrelated actions and selection states in the same group.
  • Don’t use ButtonGroup when options don’t need to stay visible.

Content Guidelines

ButtonGroup labels must be short, scannable, and comparable. Users should be able to understand the differences between options without extra explanation.

Do
  • Use short, clear labels (e.g., “Kaikki”, “Uutiset”, “Suora”, “Klipit”).
  • Use nouns for selections and filters.
  • Use verbs only when a button triggers an immediate action.
  • Keep capitalization and terminology consistent within the group.
  • Keep groups small (ideally 2–6 options).
Don't
  • Don’t use long sentences or explanatory text inside buttons.
  • Don’t change label wording between states without a clear reason.
  • Don’t use vague or context-free labels.
  • Don’t overload buttons with multiple icons or mixed meanings.

Anatomy

ButtonGroup anatomy

  1. Group container – Wraps the buttons and manages spacing, alignment, borders, and wrapping..
  2. Button – Individual selectable option (extends Button component).
  3. Selection icon (optional) – Used mainly in multi-select patterns (e.g., plus → checkmark).
  4. Label – Text inside each button describing the option.

Key ButtonGroup Props

Use these props to configure the ButtonGroup component.

children

ButtonGroup.Button components to display.

TypeExampleDescription
React.ReactNode
ButtonGroup.Button components
Code example
<ButtonGroup>
<ButtonGroup.Button id="btn-1">Option 1</ButtonGroup.Button>
<ButtonGroup.Button id="btn-2">Option 2</ButtonGroup.Button>
</ButtonGroup>

multiple

Whether multiple buttons can be selected simultaneously.

TypeExampleDescription
boolean
Enables multi-select mode
Code example
<ButtonGroup multiple>
<ButtonGroup.Button id="btn-1">Option 1</ButtonGroup.Button>
<ButtonGroup.Button id="btn-2">Option 2</ButtonGroup.Button>
</ButtonGroup>

defaultValue

Initial selected value(s) for uncontrolled component.

TypeExampleDescription
string | string[]
Initial selected value(s)
Code example
<ButtonGroup defaultValue="btn-1">
<ButtonGroup.Button id="btn-1">Option 1</ButtonGroup.Button>
<ButtonGroup.Button id="btn-2">Option 2</ButtonGroup.Button>
</ButtonGroup>

<ButtonGroup multiple defaultValue={['btn-1', 'btn-2']}>
<ButtonGroup.Button id="btn-1">Option 1</ButtonGroup.Button>
<ButtonGroup.Button id="btn-2">Option 2</ButtonGroup.Button>
</ButtonGroup>

value

Current selected value(s) for controlled component.

TypeExampleDescription
string | string[]
Controlled selected value(s)
Code example
const [selected, setSelected] = useState('btn-1');

<ButtonGroup value={selected} onChange={setSelected}>
<ButtonGroup.Button id="btn-1">Option 1</ButtonGroup.Button>
<ButtonGroup.Button id="btn-2">Option 2</ButtonGroup.Button>
</ButtonGroup>

variant

Visual style variant of the buttons.

ValueExampleDescriptionPurpose
primary
Primary button styleBest for prominent selections that control the main view content; easier to scan at a glance.
secondary
Secondary button styleBest for supportive controls (e.g., additional filters); use sparingly when the UI is already simple.
Code example
<ButtonGroup variant="primary">
<ButtonGroup.Button id="btn-1">Primary</ButtonGroup.Button>
</ButtonGroup>
<ButtonGroup variant="secondary">
<ButtonGroup.Button id="btn-2">Secondary</ButtonGroup.Button>
</ButtonGroup>

size

Size of the buttons.

ValueExampleDescription
xs
Extra small size
sm
Small size
md
Medium size (default)
lg
Large size
Code example
<ButtonGroup size="xs">
<ButtonGroup.Button id="btn-1">XS</ButtonGroup.Button>
</ButtonGroup>
<ButtonGroup size="sm">
<ButtonGroup.Button id="btn-2">SM</ButtonGroup.Button>
</ButtonGroup>

showIcon

Whether to show selection icons in multiple selection mode.

TypeExampleDescription
boolean
Shows check/plus icons in multiple selection mode
Code example
<ButtonGroup multiple showIcon>
<ButtonGroup.Button id="btn-1">Option 1</ButtonGroup.Button>
<ButtonGroup.Button id="btn-2">Option 2</ButtonGroup.Button>
</ButtonGroup>

Behavior

  • ButtonGroup manages selection state internally or via controlled props.
  • Single-select mode
    • Only one option can be selected at a time.
    • Selecting a new option deselects the previous one.
  • Multi-select mode
    • Each button toggles independently.
    • Multiple options can be active simultaneously.
  • When space is limited, the group may wrap into multiple rows.
  • Keyboard interaction:
    • Arrow keys move focus within the group.
    • Space or Enter selects or toggles the focused option.

Accessibility

  • Provide a descriptive group label using aria-label, aria-labelledby, or visible text.
  • Use role="radiogroup" for single-select patterns, or role="group" for multi-select/toggle patterns.
  • In multi-select patterns, use aria-pressed on buttons to expose toggle state.
  • Ensure full keyboard access (Tab, Arrow keys, Enter, Space).
    (WCAG 2.1.1 — Keyboard)

Implementation Examples

ButtonGroup with line breaks

Code example
<div style={{ maxWidth: '400px' }}>
<ButtonGroup>
<ButtonGroup.Button id="mon">Maanantai</ButtonGroup.Button>
<ButtonGroup.Button id="tue">Tiistai</ButtonGroup.Button>
<ButtonGroup.Button id="wed">Keskiviikko</ButtonGroup.Button>
<ButtonGroup.Button id="thu">Torstai</ButtonGroup.Button>
<ButtonGroup.Button id="fri">Perjantai</ButtonGroup.Button>
<ButtonGroup.Button id="sat">Lauantai</ButtonGroup.Button>
<ButtonGroup.Button id="sun">Sunnuntai</ButtonGroup.Button>
</ButtonGroup>
</div>

ButtonGroup with SwiperJS

Drag or swipe the container to see all the buttons

Code example
import 'swiper/css';
import { Swiper, SwiperSlide } from 'swiper/react';
import { Mousewheel, FreeMode } from 'swiper/modules';
import { ButtonGroup } from '@yleisradio/yds-components-react';

export const ButtonGroupSwiper = () => {
return (
<ButtonGroup style={{ width: '400px' }}>
<Swiper
modules={[Mousewheel, FreeMode]}
slidesPerView="auto"
spaceBetween={12}
slideToClickedSlide
freeMode={{
enabled: true,
sticky: true,
}}
mousewheel={{
enabled: true,
sensitivity: 1.5,
forceToAxis: true,
}}
>
<SwiperSlide style={{ width: 'auto' }}>
<ButtonGroup.Button id="hours">Lähitunnit</ButtonGroup.Button>
</SwiperSlide>
<SwiperSlide style={{ width: 'auto' }}>
<ButtonGroup.Button id="days">Lähipäivät</ButtonGroup.Button>
</SwiperSlide>
<SwiperSlide style={{ width: 'auto' }}>
<ButtonGroup.Button id="rain">Sadetutka</ButtonGroup.Button>
</SwiperSlide>
<SwiperSlide style={{ width: 'auto' }}>
<ButtonGroup.Button id="wind">Tuuli</ButtonGroup.Button>
</SwiperSlide>
<SwiperSlide style={{ width: 'auto' }}>
<ButtonGroup.Button id="alerts">Varoitukset</ButtonGroup.Button>
</SwiperSlide>
</Swiper>
</ButtonGroup>
);
};

API Reference

ButtonGroup Props

The ButtonGroup component accepts all standard HTML <div> attributes (except onChange) in addition to the following props:

PropTypeRequiredDefaultDescription
childrenReact.ReactNodeYesButtonGroup.Button components to display
multiplebooleanNofalseWhether multiple buttons can be selected
defaultValuestring | string[]NoInitial selected value(s) for uncontrolled
valuestring | string[]NoCurrent selected value(s) for controlled
onChange(value: string | string[]) => voidNoCallback fired when selection changes
variant'primary' | 'secondary'No'primary'Visual style variant
size'xs' | 'sm' | 'md' | 'lg'NoSize of the buttons
showIconbooleanNoShows selection icons in multiple mode

ButtonGroup.Button Props

The ButtonGroup.Button component accepts all standard Button props (except iconAfter) in addition to the following props:

PropTypeRequiredDefaultDescription
idstringYesUnique identifier for tracking selection
childrenReact.ReactNodeYesButton content

Type Definitions

export interface ButtonGroupDSProps {
children: React.ReactNode;
multiple?: boolean;
defaultValue?: string | string[];
value?: string | string[];
onChange?: (value: string | string[]) => void;
variant?: 'primary' | 'secondary';
size?: 'xs' | 'sm' | 'md' | 'lg';
showIcon?: boolean;
}

export type ButtonGroupProps = Omit<React.HTMLAttributes<HTMLDivElement>, 'onChange'> &
ButtonGroupDSProps;

export interface ButtonGroupButtonDSProps {
id: string;
children: React.ReactNode;
}

export type ButtonGroupButtonProps = Omit<ButtonProps<'button' | 'a'>, 'iconAfter'> &
ButtonGroupButtonDSProps;
  • Button – ButtonGroup.Button extends Button functionality
  • RadioGroup – Alternative for single-selection groups with form semantics
  • CheckboxGroup – Alternative for multiple selection in forms
  • DropdownMenuGroup – Use when the option list is long or space is limited
  • NavigationTabs – Page-level navigation between major sections
  • SectionTabs – Switching content within a single page or section