Button
Triggers actions. Six variants, four sizes, one disabled state.
Variants
Primary
Use it when there's one clear next step: continue a lesson, confirm an answer, unlock the next level. One Primary per screen, max.
Secondary
Use it when both actions carry equal weight and neither should recede. Think: 'Review answers' next to 'Submit test', where either choice matters.
Tertiary
Recedes alongside Primary or Danger so the dominant action wins. Works solo too, for low-stakes optional actions: 'See details', 'View badge history', 'Learn more'.
Ghost
Sits inside cards and dense layouts as a quiet inline action. Not for decision flows: use it for quick edits and secondary navigations within a view.
Danger
Warns before something irreversible happens: exits, resets, deletions. Always pair it with a Tertiary cancel and a confirmation step. Never let it fire on first tap.
Premium
Unlocks what's behind the paywall. Put it on upgrade screens and treat it like Primary: one per screen, never stacked alongside another Premium.
Disabled
Blocks an action until the student meets a condition. Always tell them what they need to do to unlock it. A disabled button with no explanation is a dead end.
Usage
One Primary per screen, maximum. It answers "what do I do next?" and everything else must recede around it. When two actions appear together, the second is almost always Tertiary (it disappears visually so Primary wins). Use Secondary only when both actions truly carry equal weight and neither should fade.
Ghost is not a two-action variant. It lives inside cards, tables, and dense layouts as an inline action, not next to Primary in a decision flow. Premium replaces Primary on upgrade screens; treat it the same way (one per screen, paired with Ghost for "maybe later"). Danger always goes with a Tertiary cancel alongside it, and always requires a confirmation step before it fires.
When the outcome is navigation rather than an action, pass the href prop. The component renders an <a> tag automatically.
Combinations
icon-left for action reinforcement, icon-right for directional cues. Avoid filling both slots at once.
Do's & Don'ts
Do
- Use one primary button per screen. It anchors the user's next move.
- Pair Primary or Danger with Tertiary by default. Tertiary recedes so the dominant action wins.
- Write labels as verb + noun: "Start test", "Save progress", "Unlock module".
- Match size to density:
xlfor full-page CTAs,sm/mdfor inline actions inside cards. - Use
hreffor navigation when the result is a destination, not a triggered action.
Don't
- Don't place two primary buttons on the same screen. One of them needs to step down.
- Don't use Tertiary as the main action when a decision is required. Its low visual weight works for optional actions, not for choices the student has to make.
- Don't use Ghost in two-action flows. It belongs inside dense layouts, not alongside Primary.
- Don't use vague labels. "Click here", "Submit", or "OK" say nothing about what happens next.
- Don't trigger
dangerwithout a confirmation step. Destructive actions need a checkpoint. - Don't repeat
premiumacross multiple elements. Its impact depends on scarcity.
Related: Option Card (the selection component that a primary button confirms) · Progress Bar (tracks lesson progress above the button in quiz screens)