Button
A Button triggers an action or confirms a choice when the user activates it.
Code example
import { Button } from '@yleisradio/yds-components-react';
<Button text="Primary" />
Why to use
Buttons are used to execute actions in the interface: submitting a form, opening a modal, cancelling an operation, or performing add/remove actions. They stand out visually from surrounding content and guide the user’s attention to the most important actions. The button text must clearly communicate what happens when it is pressed (for example, “Poista kaikki” or “Lähetä lomake”). It should typically start with a verb and use sentence case.
When to use
Use a Button when the user needs to perform an explicit action. Buttons initiate tasks, submit information, confirm decisions, or open additional functionality. Use a Button whenever the user is expected to do something, not just navigate or view content.
- Use a Button when an action changes data, advances a task, or opens an interaction.
- Use the Primary button for the main action in a section or flow.
- Use Secondary and Text buttons for supporting or lower-priority actions.
- Use a Button instead of a link when something should happen on the same page.
- Use icon-only buttons only when they fit the interaction pattern, the icon is widely recognized, or space is limited.
- Don’t use a Button for simple navigation — use a link instead.
- Don’t use a Button when the action is ambiguous or when a menu would better support the flow.
- Don’t use multiple Primary buttons in the same section — it weakens the main action.
- Don’t use disabled buttons to explain why something can’t be done — use helper or error text instead.
- Don’t use very small button sizes as the default, especially on touch devices.
Content Guidelines
Button labels must be short, clear, and action-oriented. They tell the user exactly what will happen when the button is pressed. Good labels increase confidence and reduce cognitive load.
- Start labels with a clear verb (e.g., Tallenna, Jatka, Muokkaa, Poista).
- Keep labels brief — ideally 1–2 words.
- Use consistent wording across the product (e.g., always use Peruuta for dismissing actions).
- Don’t use vague or generic labels like OK, Hyväksy, or Klikkaa tästä.
- Don’t use humor, jargon, or internal terminology unfamiliar to users.
- Don’t rely on icon-only labels without accessible text.
Usage in UI patterns
Text labels
Use concise, action-oriented labels starting with a verb without unnecessary words or politeness (e.g., Tallenna, Jatka, Muokkaa, Poista).
Good: Clear and concise.
Bad: Unnecessary politeness.
Good: Clear and concise.
Bad: Unnecessary words.
Short labels
Keep labels brief — ideally 1–2 words. Avoid long phrases or sentences.
Good: Short and to the point.
Bad: Too long and wordy.
Icons
Even with an icon, the label must clearly describe the action (e.g., “Poista tiedosto” with a trash can icon), not just an icon.
Good: Text describes the action.
Bad: Icon alone is unclear.
Forms
The label should describe the result of submitting (e.g., “Lähetä lomake”, “Tallenna muutokset”), not the action “Lähetä”.
Good: Describes the result of the action.
Bad: Vague about what happens.
Dialogs & confirmations
The primary button must clearly confirm the intended action (e.g., “Poista tiedosto”, “Hyväksy ehdot”), while secondary actions use neutral wording (e.g., “Peruuta”).
Good: Clearly states the action.
Bad: Ambiguous confirmation.
Destructive actions
Make the consequence explicit to prevent mistakes (e.g., “Poista kaikki”, “Tyhjennä lista”). Avoid ambiguous verbs like “Poista” ilman kohdetta.
Good: Specifies what will be deleted.
Bad: Unclear about the target.
Navigation
Labels should indicate where the user will go (e.g., “Jatka eteenpäin”, “Avaa asetukset”, “Näytä lisää”).
Good: Indicates the destination.
Bad: Vague about where it leads.
Anatomy
- Container – Clickable target
- Label – Action text
- Icon Before (Optional) – Visual cue preceding text
- Icon After (Optional) – Supplementary indicator
Key Button Props
Use these props to configure the Button component.
text
Visible label text of the button. Explains the action performed when pressed.
| Type | Example | Description |
|---|---|---|
string | Text displayed inside the button that explains what happens when it is pressed. |
Code example
<Button text="Submit" />
Avoid using children for text because it may lead to inconsistent styling with some other props.
variant
Defines the visual and hierarchical level of the button.
| Value | Example | Description |
|---|---|---|
primary | Default variant for the main action. | |
secondary | Secondary action. Always used with a primary button. | |
text | Low-emphasis text-style button. |
Code example
<Button text="Save" />
<Button variant="secondary" text="Cancel" />
<Button variant="text" text="Details" />
size
Adjusts dimensions and typography.
| Value | Example | Description |
|---|---|---|
xs | Smallest accessible button. | |
sm | Compact button. | |
md | Default size. | |
lg | Large button for key CTAs. |
Code example
<Button size="xs" text="Button" />
<Button size="sm" text="Button" />
<Button size="md" text="Button" />
<Button size="lg" text="Button" />
isDisabled
Non-interactive, dimmed styling.
| Type | Example | Description |
|---|---|---|
boolean | Temporarily prevents user interaction. Sets aria-disabled on the button. |
Code example
<Button isDisabled text="Submit" />
fullWidth
Expands Button to fill parent width – especially useful in mobile views.
| Type | Example | Description |
|---|---|---|
boolean | Makes the button stretch horizontally. |
Code example
<div style={{ width: '300px' }}>
<Button text="Button" fullWidth />
</div>
iconBefore
Adds icon component before the text.
| Type | Example | Description |
|---|---|---|
ReactNode | Rendered before the label text. |
Code example
import { Play, ArrowRight } from '@yleisradio/yds-icons-react';
<Button iconBefore={<Play />} text="Play" />
iconAfter
Adds icon component after the text. Often used for dropdown indicators or directional arrows.
| Type | Example | Description |
|---|---|---|
ReactNode | Rendered after the label text. |
Code example
import { ArrowRight } from '@yleisradio/yds-icons-react';
<Button text="Next" iconAfter={<ArrowRight />} />
iconOnly
Renders a button with only an icon, requires accessibleText for accessibility.
| Type | Example | Description |
|---|---|---|
boolean | Icon-only button variant. |
Code example
<Button iconBefore={<Play />} accessibleText="Play media" iconOnly />
accessibleText
Supplementary text for screen readers when using icon-only buttons.
| Type | Example | Description |
|---|---|---|
string | Provides additional context for assistive technologies. Uses aria-label. |
Code example
<Button text="Play" accessibleText="Play media" />
removePadding
Removes default padding, use only when you fully control the inner layout.
| Type | Example | Description |
|---|---|---|
boolean | Works only with variant="text". Eliminates default padding inside the button. |
Code example
<Button text="Button" variant="text" removePadding />
loading
Replaces text with a loading spinner and disables interaction.
| Type | Example | Description |
|---|---|---|
boolean | Indicates that an action is in progress. |
Code example
<Button text="Submit" loading />
Behavior
- Buttons provide clear visual feedback for interaction states (hover, focus, active, disabled, loading).
- Clicking or tapping a button triggers its action immediately.
- Loading state prevents repeated submissions or accidental double actions.
- Disabled buttons do not respond to interaction and appear inactive.
- Keep button sizes consistent within a group.
- Use full-width buttons on mobile to improve tap targets and clarity.
- Icon-only buttons and dropdown buttons must behave consistently with text buttons.
- Buttons that open menus or dialogs should visually indicate expanded and collapsed states.
Accessibility
- Ensure icon-only buttons have an accessible name via
aria-label. - Disabled buttons should generally be focusable.
- Disable a button only when the action cannot yet be performed — and provide guidance nearby.
- Icon-only buttons must include accessible text via
accessibleText. - Fully keyboard-accessible and visible focus states.
(WCAG 2.1.1 — Keyboard)
Implementation examples
Asynchronous actions
Code example
import { Button } from '@yleisradio/yds-components-react';
import { useState } from 'react';
export const AsynchronousButton = () => {
const [isLoading, setIsLoading] = useState(false);
const handleClick = () => {
setIsLoading(true);
// Simulate an asynchronous operation
setTimeout(() => {
setIsLoading(false);
}, 2000);
};
return (
<Button
onClick={handleClick}
isDisabled={isLoading}
loading={isLoading}
accessibleText={isLoading ? 'Loading' : undefined}
>
Click to trigger
</Button>
);
};
Disabled until conditions are met
Code example
import { Button, Checkbox } from '@yleisradio/yds-components-react';
import { useState } from 'react';
export const DisabledButton = () => {
const [termsAccepted, setIsTermsAccepted] = useState(false);
return (
<div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>
<Checkbox
name="terms-accepted"
value="terms-accepted"
label="Hyväksyn käyttöehdot"
variant="primary"
onChange={(e) => setIsTermsAccepted(e.target.checked)}
/>
<Button isDisabled={!termsAccepted}>Lähetä lomake</Button>
</div>
);
};
API Reference
Props
The Button component accepts all standard HTML <button> attributes in addition to the following props:
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
variant | 'primary' | 'secondary' | 'text' | No | 'primary' | |
isDisabled | boolean | No | false | |
iconBefore | React.ReactElement<SvgProps> | null | No | undefined | |
iconAfter | React.ReactElement<SvgProps> | null | No | undefined | |
iconOnly | boolean | No | false | |
loading | boolean | No | false | |
size | ButtonSize | No | 'md' | |
text | string | No | — | |
accessibleText | string | No | — | |
fullWidth | boolean | No | false | |
removePadding | boolean | No | false |
Type Definitions
export type ButtonSize = 'xs' | 'sm' | 'md' | 'lg';
export interface ButtonDSProps {
variant?: 'primary' | 'secondary' | 'text';
isDisabled?: boolean;
iconBefore?: React.ReactElement<SvgProps> | null;
iconAfter?: React.ReactElement<SvgProps> | null;
iconOnly?: boolean;
loading?: boolean;
size?: ButtonSize;
text?: string;
accessibleText?: string;
fullWidth?: boolean;
removePadding?: boolean;
}
export type ButtonProps<C extends React.ElementType> = PolymorphicComponentPropsWithRef<
C,
ButtonDSProps
>;
Related Components
- Link – Navigational transitions.
- ButtonGroup – Group of buttons for related actions.