Pill Button
Rounded buttons perfect for filters, tags, and selection interfaces.
Ready to use
Pill Buttons are secondary interactive elements used for filtering, tagging, or toggling options within the interface. They are visually lighter than standard buttons and should never be used for primary actions. Two main use cases sit under the same shell: selectable pills that represent filters or toggles, and informational pills that highlight contextual labels or statuses.
Anatomy
Section titled “Anatomy”- Pill button
- Icon
- Label
When to use it
Section titled “When to use it”Use a Pill Button when:
- You need lightweight, secondary interactions like filters or tag selectors.
- You want to group related options horizontally (e.g. category filters).
- A clear selected / unselected visual state is part of the pattern.
Avoid the Pill Button when:
- The action represents a primary call to action — use Primary Button instead.
- The action leads to navigation — use a Link Button.
- You need destructive or confirmatory actions — use Secondary or Alert Buttons.
Properties
Section titled “Properties”Type
Four colour treatments — Neutral, Contrast, OnOverlay Light, and OnOverlay C2A — each tuned to a different surface. Use Neutral on standard light backgrounds, Contrast on dark, and the OnOverlay variants when the pill sits over imagery or video.
State
Rested, Hover, Active (selected), Disabled, and Focus. Active carries the selected visual; disabled keeps the shape but mutes the colour; focus shows a 2 px outline so the control stays reachable from the keyboard.
Size
Three text sizes — Large for prominent filter areas, Medium as the default, Small for dense layouts. The pill always hugs its label and keeps the rounded shape regardless of size.
Icon
Optional leading and trailing icons. Pair them with the label only when they add meaning (a chevron for a dropdown trigger, a spinner during loading); icon-only pills aren’t supported.
Platform considerations
Section titled “Platform considerations”Desktop
Pointer accuracy is high, but keep at least 8 px between adjacent pills so the hit areas don’t crowd each other in dense filter rows.
Tablet
Mix of touch and pointer — the medium size handles both. Keep the 44 px touch area honoured even when the visual height drops below it (use invisible padding).
Mobile
Touch-first. Stick to medium or large pills wherever possible and pay close attention to spacing so users don’t tap the wrong filter.
Best practices
Section titled “Best practices”Keep pills lightweight and visually distinct from primary actions.
Do
Add invisible padding around pills when needed to expand the touch target without altering the visual, keep at least 8 px horizontally and 4 px vertically between adjacent pills, and make sure each pill carries visible text and a clearly distinguishable focus state.
Don't
Don’t rely on the visible shape alone to define the touch area, don’t define touch areas smaller than 24×24 px even for compact pills, and don’t place pills close enough that their touch areas overlap.
Content guidelines
Section titled “Content guidelines”Pill labels must clearly describe what they do or what they represent. Keep filter labels to 1–2 words (“Electric”, “In stock”) and action labels to 1–3 (“Apply”, “Show all”). Use clear, specific text that stands on its own — users shouldn’t need to read nearby copy to understand a pill — and avoid vague labels like “OK”, “Click”, or “Select”. Stay under 24–30 characters to keep translations and responsive layouts well-behaved, use sentence case (“Apply filter”, not “APPLY FILTER”), and skip trailing punctuation. Use neutral, easily localisable phrasing — avoid idioms or culture-specific references. Never truncate; wrap to a new line if the label needs more room.
Styles
Section titled “Styles”Rounded buttons perfect for filters, tags, and selection interfaces.
The default size is lg.
<button class="tng-pill-button is-sm">Small</button><button class="tng-pill-button is-md">Medium</button><button class="tng-pill-button is-lg">Large</button>States
Section titled “States”<button class="tng-pill-button is-selected">Selected</button><button class="tng-pill-button" disabled>Disabled</button>On overlay
Section titled “On overlay”<button class="tng-pill-button on-overlay">Rested</button><button class="tng-pill-button on-overlay is-selected"> Selected</button><button class="tng-pill-button on-overlay" disabled>Disabled</button><button class="tng-pill-button on-overlay is-cta">Rested</button><button class="tng-pill-button on-overlay is-cta is-selected"> Selected</button><button class="tng-pill-button on-overlay is-cta" disabled> Disabled</button><button class="tng-pill-button"> <i class="tng-icon icon-ui-spinner" aria-hidden="true"></i> <span>Loading</span></button><button class="tng-pill-button"> <span>Popular</span> <i class="tng-icon icon-arrow-right" aria-hidden="true"></i></button>Description
Section titled “Description”The PillButton component renders a button with a pill-shaped design.
Pill buttons are secondary interactive elements used for filtering, tagging, or toggling options whitin the interface. They are visually lighter than standard buttons and should never be used for primary actions.
There are two main use cases:
- Selectable Pills: used to represent filters or toggles that can be selected/deselected.
- Informational Pills: used to highlight contextual information (e.g. labels or statuses).
Component
Section titled “Component”Properties
Section titled “Properties”PillButtonProperties extends <React.HTMLAttributes<HTMLButtonElement>> which means it includes all standard HTML attributes that can be applied to a button element.
| Prop | Type | Description | Optional |
|---|---|---|---|
text |
string |
The text label displayed inside the pill button | ❌ |
className |
ClassValue |
Custom class names applied to the button element | ✅ |
buttonSize |
'sm' | 'md' | 'lg' |
Defines the size of the button | ✅ |
isHighlight |
boolean |
Indicates if the button should appear highlighted | ✅ |
isSelected |
boolean |
Indicates if the button is currently selected | ✅ |
isCta |
boolean |
Marks the button as a Call-To-Action (CTA) | ✅ |
onOverlay |
boolean |
Indicates if the button is displayed on an overlay | ✅ |
leadingIcon |
ToyotaIcon | LexusIcon |
Icon displayed before the text | ✅ |
trailingIcon |
ToyotaIcon | LexusIcon |
Icon displayed after the text | ✅ |
Example
Section titled “Example”import { PillButton } from '@tmedxp/react-components';
const PillButtonExample = () => { return <PillButton text="Pill Button" />;};
export { PillButtonExample };A pill button is a native <button> — a text label, optionally with a leading or trailing icon — so it carries button semantics and keyboard operation for free, and meets WCAG 2.1 AA. Its accessibility hinges on two things: a clear accessible name, and — when the pill is used as a filter or toggle — a selected / pressed state that is exposed to assistive technology, not just shown visually.
For designers
Section titled “For designers”- The label and every state — rested, hover, selected, disabled — must maintain accessible contrast on every supported surface, including the on-overlay variants placed over imagery. Source: WCAG 1.4.3 Contrast (Minimum).
- The selected state must never be conveyed by colour alone — pair the fill change with a shape, weight, or icon cue so the choice reads without relying on hue. Source: WCAG 1.4.1 Use of Color.
- Focus styles must stay visible, meet contrast requirements on every supported surface, and be clearly distinguishable from hover and from the selected state. Source: WCAG 2.4.7 Focus Visible.
- Use semantic colour tokens (e.g.
foreground/neutral/default) rather than fixed values, so the pill adapts correctly across themes and surfaces. - Keep the interactive target comfortable even when the visual pill is small — add invisible padding rather than shrinking the hit area, and keep adjacent pills spaced so their targets don’t overlap. Source: WCAG 2.5.8 Target Size (Minimum).
For developers
Section titled “For developers”Use a native <button>, never a styled <div> or <span> — the native element is focusable, operable with Enter and Space, and announced as a button without extra ARIA. The accessible name comes from the visible text; keep that text present even when an icon is paired with it. When the pill acts as a filter or toggle, reflect its selected state to assistive technology with aria-pressed (or aria-selected in a listbox-style filter group) — the is-selected visual alone is not announced. Keep decorative icons out of the accessibility tree with aria-hidden="true". Interactive targets must be at least 44 px high for comfortable touch use — comfortably clearing the WCAG AA minimum. Source: WCAG 2.5.8 Target Size (Minimum). Each element’s role, accessible name, and state are in the Labelling elements section below.
Labelling elements
Section titled “Labelling elements”Give every element the role, name, and state assistive technology needs.
Button
The native <button> takes its accessible name from its visible text content — keep that text self-describing (e.g. Electric, Apply filter) so it stands on its own. Don’t replace the text with an icon alone; if a design ever calls for an icon-only pill, give it an explicit aria-label.
Icon
A leading or trailing icon is decorative — mark it aria-hidden="true" so it never adds noise to the accessible name. The label text alone must carry the meaning.
Selected / pressed state
When the pill is a filter or toggle, expose its state with aria-pressed="true"/"false" (or aria-selected inside a listbox-style filter group), kept in sync with the visual is-selected treatment. Without it, screen-reader users hear a plain button and miss the choice.
Disabled
Use the native disabled attribute rather than a .is-disabled class — it removes the pill from the tab order and announces it as unavailable. Keep the disabled pill visible so its presence in the set stays discoverable.
Source: WCAG 4.1.2 Name, Role, Value.