Skip to main content
WireKit
Copy for LLM

FAB

The floating trigger that expands into a small stack of actions — the primary "create" affordance in app-shaped mobile layouts.

A speed dial with three actions

The preview sits in a position: relative frame so the fixed button is contained in the box — in your app you just drop in <x-wirekit::fab> and it pins to the viewport corner (see the Show Code above, which omits the demo frame).

Usage

<x-wirekit::fab label="Create">
    <x-wirekit::fab.action label="New note" icon="pencil" />
    <x-wirekit::fab.action label="Upload file" icon="arrow-up-tray" />
    <x-wirekit::fab.action label="Docs" icon="book-open" href="/docs" />
</x-wirekit::fab>

Every action needs a label. The buttons are icons, so the label is their whole name — without one a screen reader announces "button" three times.

An action with an href renders as a link, and one without renders as a button. A thing that navigates is a link; a thing that acts is a button. Getting that wrong costs middle-click, "open in new tab", and the status bar.

Sitting above a bottom nav

Both are fixed, so a FAB on a page with a bottom nav lands on top of it. Add wk-fab-above-nav:

<x-wirekit::fab label="Create" class="wk-fab-above-nav">…</x-wirekit::fab>

Opt-in, because this component cannot see whether a nav exists elsewhere in the document — and guessing would lift every FAB off the corner it belongs in. The lift disappears at md along with the nav; add wk-fab-above-nav-always if you kept the nav on desktop.

Position

position follows the writing direction rather than assuming everyone reads left to right:

position Where
end The inline-end corner (default — bottom right in English)
start The inline-start corner
center Centered along the bottom

Props

<x-wirekit::fab>

Prop Type Default Description
label string 'Actions' Names the trigger and the menu. The trigger is an icon, so this is all a screen reader gets.
position string 'end' end, start, center.
scope string|null null Class-scope override.

<x-wirekit::fab.action>

Prop Type Default Description
label string '' The action's whole accessible name.
icon string|null null Icon name. Falls back to the slot.
href string|null null Renders a link instead of a button.
scope string|null null Class-scope override.

Slots

Slot Description
trigger Replaces the default plus icon.
default The actions.

Accessibility

The interesting part of a speed dial is not the fan — it is what happens to focus. A menu that opens and leaves focus on the trigger is a menu a keyboard user cannot reach; one that traps focus is a menu they cannot leave. This does neither:

  • Opening moves focus to the first action.
  • / walk the actions and wrap.
  • Esc closes and hands focus back to the trigger — where the reader was — but only if focus was inside the menu. A stray Escape from elsewhere on the page does not yank it.
  • The trigger's aria-haspopup="menu" and the panel's role="menu" agree, so a screen reader is not promised a popup whose contents are something else.
  • Actions are 44px, the touch minimum, and are the smallest targets on the screen.
  • The plus/close icons both stay in the DOM so they can cross-fade, so the inactive one is hidden from assistive tech — otherwise the trigger announces both states.
  • The rotation is dropped under prefers-reduced-motion.

Keyboard Interaction

Key Action
Tab Move focus to the trigger.
Enter / Space Open the actions and focus the first.
Move between actions.
Esc Close and return focus to the trigger.