Skip to main content

Figma Storybook

Button

Triggers a single action or navigation event. Use the primary variant for the most important action in a context, secondary for supporting actions, and tertiary for low-emphasis actions.

Figma Storybook Docs

Description

What it does

Buttons let users take actions and make choices. They initiate tasks, submit forms, trigger dialogs, and navigate between states. A consistent button vocabulary reduces cognitive load — when primary, secondary, and tertiary have predictable visual weight, users can identify the most important action in any context at a glance.

Where it appears

Appears in forms, dialogs, toolbars, cards, empty states, and page headers.

Why it exists

A shared button vocabulary means every screen in Open Point and Social Point uses the same visual hierarchy. Users learn once that the high-emphasis button is primary, and that knowledge transfers to every context.

Dependencies

Built on Web Awesome (<wa-button>) — framework-agnostic web component that works across Open Point (Angular), Social Point (Vue), and any HTML context. Pairs with ButtonGroup for grouped actions.

Anatomy

PartRequired?Notes
Label Required (or icon) Sentence case. Verb + object preferred. 1–3 words, 5 maximum.
Leading icon Optional 16×16px. Reinforces intent — don't use decoration-only icons.
Trailing icon Optional 16×16px. Use for affordances like dropdowns (chevron) or external links.
Loading indicator Optional Spinner replaces or accompanies label during async operations.

Variants

btn.primary
Save changes

Brand — Accent

The primary call-to-action for a view or dialog. Highest visual weight, in the brand colour.

Use once per view — if two Accent buttons appear together, one should be downgraded.

btn.secondary
Secondary action

Neutral — Accent

A solid, high-commitment action rendered in neutral colour.

Actions that need to read as committed or final, but shouldn't compete with the view's Brand action.

btn.filled-outlined
Tinted action

Neutral — Filled-Outlined

A brand-coloured action with reduced visual weight.

Actions that relate to the primary flow but shouldn't compete with the view's Brand button — e.g. a secondary option alongside the main call-to-action that's still tied to the same task.

btn.outlined
Cancel

Neutral — Outlined

A bordered, no-fill action with moderate visual definition.

Standard secondary actions that need to be distinguishable but not prominent.

btn.plain
Skip for now

Neutral — Plain

The lowest-emphasis action available. Text only, no fill or border.

Dismissive, cancel, or "skip this" actions that shouldn't draw the eye.

btn.disabled
Disabled

Disabled

50% opacity, not interactive.

Avoid where possible. Use only when an action cannot be taken and the reason is visually clear. Prefer aria-disabled over the HTML disabled attribute if keyboard reach is needed.

btn.loading
Saving…

Loading

Spinner replaces or precedes the label. Button dimensions preserved.

After the user triggers an async action — form submit, save, delete. Remove the loading state once the action resolves.

Intent variants

btn.danger
Delete permanently

Danger — Accent

A destructive or irreversible action (delete, remove). Highest warning weight — solid fill in the danger colour.

Should almost always sit behind a confirmation step.

btn.danger-outlined
Delete

Danger — Outlined

A destructive action surfaced inline, without a dialog to carry the weight.

A row, a card, a toolbar — or as a secondary option next to a Danger/Accent confirming action.

btn.danger-plain
Remove

Danger — Plain

A text-only destructive action with the lowest warning weight.

Used inline where a full-weight danger button would be excessive. Pending Ysa's audit.

btn.success
Publish

Success — Accent

Confirms or completes a positive action.

The confirming action inside a dialog or notification modal — e.g. "Publish," "Mark complete." Not used inline.

btn.warning
Continue anyway

Warning — Accent

Proceeding despite a caution.

The confirming action inside a dialog — e.g. "Continue anyway," "Overwrite." Not used inline.

btn.info
Got it

Info — Accent

Acknowledging or dismissing informational content.

The acknowledging action inside an informational dialog or notification modal — e.g. "Got it," "Learn more." Not used inline.

Inverse surfaces

btn.inverse
Secondary action

Outlined — Inverse

White border and label on dark surfaces.

Secondary actions on dark backgrounds — nav bars, dark banners, inverse panels.

btn.plain-inverse
Cancel

Plain — Inverse

White label, no border or fill, on dark surfaces.

Tertiary actions on dark surfaces alongside an Outlined Inverse button.

Sizes

XS
xs · 24px
Small
s · 32px
Medium
m · 40px
Large
l · 48px
XL
xl · 56px

States

Action
DEFAULT
Action
HOVER
Action
FOCUS
Action
DISABLED
Action
ACTIVE / PRESSED
Saving…
LOADING
State Behaviour
Default Resting state. Full colour, full opacity.
Hover Slightly darker or lighter depending on variant. Cursor — pointer.
Focus 2px solid focus ring, 2px offset. Always visible — never suppressed.
Disabled Avoid where possible — disabled buttons are not in the tab order and give users no feedback about why the action is unavailable. Prefer showing the button in an error or inactive state with an explanation. When disabled is necessary: 50% opacity, cursor: not-allowed. Use aria-disabled="true" instead of the HTML disabled attribute if the button must remain keyboard-reachable.
Active / Pressed Depressed visual on press.
Loading Spinner visible. Button dimensions preserved. Optional label persists ("Saving…").

Usage guidelines

How to choose a button

Every button's role comes from two independent decisions: how much visual weight it should carry (appearance), and what it means semantically (variant). Pick both, then check the component reference below for the exact wording of that combination's role.

1. Appearance — how much weight?

Appearance Look Choose this when…
Accent Solid fill This is the one committed action in a self-contained decision point — a view's main call-to-action, or a dialog's confirming action.
Filled-Outlined Tinted, light fill The action relates to the primary task but shouldn't compete with it.
Outlined Bordered, no fill A standard action that needs to be visible but not prominent.
Plain Text only A dismissive, cancel, or low-stakes inline action.

2. Variant — what does it mean?

Variant Meaning
Brand The primary task or flow
Neutral No brand or intent meaning attached
Danger Destructive or irreversible
Success Confirms or completes a positive action
Warning Proceeding despite a caution
Info Acknowledging or dismissing informational content

The rule that trips people up: Accent is capped at one per view

Accent is a visual weight, not a colour-specific thing — a solid-fill button competes with any other solid-fill button nearby, regardless of colour. Practically, that means:

  • Brand/Accent is the one recommended action in a view. The brand colour is what signals "this is the recommended path."
  • Neutral/Accent is not a partner to Brand/Accent — it's a substitute for it. Use Neutral/Accent only in views that have no Brand/Accent button at all, where something still needs to read as solid and final without any brand emphasis (an internal tool screen, a settings save, a neutral system dialog).

If a view already has a Brand/Accent button and a second action still needs to feel final rather than soft, drop that second action to Filled-Outlined or Outlined — never bump it up to Neutral/Accent. Two Accent-tier buttons side by side will always compete for attention, no matter what colours they use.

Note: appearance="filled" is a separate, valid value outside this role system — it's used for pressed/active states in segmented controls and toggle button groups (see ButtonGroup), not for standalone button roles.

Component reference

Brand

Component Role
Brand / Accent The one recommended action in a view or dialog. Use once per view. Never pair with another Accent-tier button of any colour.

Brand/Filled-Outlined and Brand/Outlined are not currently in the system — considered and deliberately excluded, since Neutral/Filled-Outlined already covers "tied to the primary flow, reduced weight," and no concrete screen has needed a third brand-weighted step. Revisit if a real use case comes up.

Neutral

Component Role
Neutral / Accent A committed, final action in a view with no Brand/Accent button present — a substitute for Brand/Accent, not a companion to it.
Neutral / Filled-Outlined A brand-coloured action with reduced visual weight, tied to the primary flow but not competing with it — e.g. a secondary option alongside the main CTA that's still part of the same task.
Neutral / Outlined A standard secondary action that needs to be distinguishable but not prominent.
Neutral / Plain The lowest-emphasis action available — dismissive, cancel, or "skip this."

Danger

Component Role
Danger / Accent A destructive or irreversible action (delete, remove). Highest warning weight — solid fill in the danger colour. Should almost always sit behind a confirmation step.
Danger / Outlined A destructive action surfaced inline — a row, a card, a toolbar — without a dialog to carry the weight, or as a secondary option next to a Danger/Accent confirming action.
Danger / Plain A text-only destructive action with the lowest warning weight, used inline where a full-weight danger button would be excessive. Pending Ysa's audit for the same reason.

Success

Component Role
Success / Accent The confirming action inside a dialog or notification modal for a positive, completing action — e.g. "Publish," "Mark complete."
Success / Outlined A positive action surfaced inline, or a secondary option next to a Success/Accent confirming action.
Success / Plain A low-emphasis, inline positive action.

Warning

Component Role
Warning / Accent The confirming action inside a dialog that proceeds despite a caution — e.g. "Continue anyway," "Overwrite."
Warning / Outlined A cautionary action surfaced inline, or a secondary option next to a Warning/Accent confirming action.
Warning / Plain A low-emphasis, inline cautionary action.

Info

Component Role
Info / Accent The acknowledging action inside an informational dialog or notification modal — e.g. "Got it," "Learn more."
Info / Outlined An informational action surfaced inline, or a secondary option next to an Info/Accent action.
Info / Plain A low-emphasis, inline informational action.

Note: rendered as variant="brand" data-color="info" — this installed version of Web Awesome has no native "info" button variant. See component-overrides.css for the mapping.

Content guidelines

  • Sentence case. "Save changes," not "Save Changes" or "SAVE CHANGES."
  • *Product entity names stay capitalised (pending review).* Stakeholder, Property, Event, Consultation, Response (Open Point) and Project, Team, Team Leader, Campaign (Social Point) are capitalised in button labels, as with any other officially-named product term: "Add Stakeholder," "Create Property," "Delete Event," not "add a stakeholder," "create a property," "delete an event." This is the current standard, applied consistently across both products — see Capitalisation for the full reasoning and its open questions, which are still under review with marketing.
  • Verb + object. Tell the user what happens: "Delete Project," "Add Stakeholder," "Send invitation." Avoid vague labels like "OK," "Yes," or "Submit" — the label should tell users exactly what will happen without needing to read surrounding context.
  • 1–3 words, 5 maximum. Longer labels wrap or truncate at small sizes and slow down scanning.
  • State the consequence directly for destructive actions. "Delete Consultation," not "Remove?" or "Are you sure?" — the confirmation dialog, not the button label, is where you explain what's irreversible.
  • Match the label to the actual outcome. If a "Save" button also triggers a validation step, "Save" still describes the outcome correctly — but if it navigates elsewhere or triggers a side effect the user wouldn't expect, name that instead.
  • Loading labels use present continuous. "Saving…," "Deleting…," "Publishing…" — not "Save" with a spinner, which reads as unresponsive rather than in progress.
  • Never rely on colour alone to convey meaning. A Danger button's label should already say "Delete," "Remove," or "Revoke" — the red colour reinforces the label, it doesn't replace it.

When to use

  • To trigger an action: submitting a form, opening a dialog, deleting a record.
  • Wherever a user needs a clear affordance to do something.

When not to use

  • For navigation between pages or views — use a link (<a>) instead. Buttons set user expectations of action, not destination.
  • When multiple primary buttons would appear simultaneously — rethink the hierarchy.

Do / Don't

Do

Use sentence case for button labels, capitalising product entity names: "Save changes", "Add Stakeholder", "Delete Project".

Don't

Use vague labels like "OK", "Yes", or "Submit". The label should tell users exactly what will happen.

Do

Preserve button dimensions during loading states — prevent layout shift when the spinner appears.

Don't

Soften destructive actions with vague labels like "Remove?" — state the consequence directly: "Delete Consultation".

Do

Use aria-disabled="true" on buttons that should remain keyboard-reachable even when inactive.

Don't

Place multiple primary buttons in the same context. If two actions feel equally important, reconsider the hierarchy.

Was this page helpful?

Updated 9 September 2026