Appearance
Fab
SFab is the floating action button: the one action a screen is there for, kept within reach above the content. It comes in two shapes — a circle with an icon, and, once label is set, an extended pill with an icon and text. Give it a position and it pins itself to a corner of the viewport; position="static" leaves it in the flow, wherever the page puts it.
With actions the button turns into a speed dial: it opens a fan of secondary actions instead of acting on its own. That is a shortcut, not a navigation pattern — keep it at three to five entries of the same rank. A longer list, entries with checkmarks, groups or destructive items belong in a dropdown menu; a permanent set of editing controls belongs in a toolbar, which stays visible and does not cover the content.
Accessible naming is the part that is easy to get wrong. A circular button shows no text, so it needs ariaLabel; without one the component warns in development. An extended button is named by its visible label and takes no ariaLabel — a label that differs from the visible text would hide the words the visitor reads. A button with actions no longer performs the action itself, so it is named after what it opens: the showActions entry of the locale dictionary ("Show actions"), overridden per instance with actionsLabel. Each action is named by its own label, which is shown as a chip beside the button and given to the button as its accessible name.
The fan is a menu: Enter or Space opens it and moves focus to the first action, the arrow keys walk along the fan, Home and End jump to its ends, and Escape closes it and returns focus to the button. Picking an action emits select with the action and closes the fan. The open state is available as v-model:open.
Circular and extended
variant and color are the same knobs as on SButton, and the actions of the fan follow them.
Sizes
The sizes follow the Material scale — sm 40px, md 56px and lg 72px — so the button stands out from the regular controls around it. The scale carries the icon, the label and the fan with it: an sm fab opens sm actions.
A fan of actions
An action with disabled stays in the fan but is skipped by clicks and by the arrow keys. Set openOn="hover" to unfold the fan as soon as the pointer reaches the button; the click keeps working, because a touch screen has no hover.
Direction
direction unfolds the fan up (the default), down, start or end. start and end are logical: they follow the writing direction of the page. In a vertical fan the chips sit beside the buttons, in a horizontal one underneath them, and they always point away from the edge the button is pinned to.
Pinned to a corner
A pinned button is position: fixed. The example below sits in a wrapper with a transform, which makes that wrapper the containing block — otherwise the button would float over the documentation instead of staying inside the example. The distance from the corner is set by the --s-fab-top, --s-fab-right, --s-fab-bottom and --s-fab-left custom properties (1.5rem by default), so the button can be moved without overriding a single rule.
A pinned button sits at z-index: var(--s-z-sticky), under dialogs and toasts. Only one floating action button belongs on a screen: a second one competes with the first for the same "the" action.
API
Props
| Name | Type | Default | Description |
|---|---|---|---|
icon | string | undefined | Icon of the main button: a registry name (see registerIcons) or a raw SVG path (d). |
label | string | undefined | Text label. With it the button becomes an extended FAB — an icon and text in one pill;
without it the button is a circle and needs ariaLabel. |
aria-label | string | undefined | Accessible name of the button. Required for a circular FAB, which has no visible text.
An extended FAB is named by its label. |
size | "md" | "sm" | "lg" | "md" | Button size: sm (40px), md (56px) or lg (72px). |
variant | | "primary"
| "secondary"
| "negative"
| "outline"
| "ghost" | "primary" | Visual variant: filled primary/secondary/negative, outlined outline or transparent
ghost. The actions of the fan follow the same variant. |
color | string | undefined | Accent color: a name from the palette (primary/teal/teal-10).
Overrides the variant color, for the fan actions as well. |
position | | "static"
| "bottom-end"
| "bottom-start"
| "top-end"
| "top-start" | "bottom-end" | Corner the button is pinned to. Pinned positions are position: fixed; static leaves the
button in the flow, where the page places it. The distance from the corner is set by the
--s-fab-top/--s-fab-right/--s-fab-bottom/--s-fab-left custom properties. |
actions | {
id: string;
label: string;
icon?: string;
disabled?: boolean
}[] | undefined | Actions of the fan (speed dial). With them the button opens a fan of secondary actions instead of acting on its own click. |
direction | | "start"
| "end"
| "up"
| "down" | "up" | Direction the fan of actions unfolds in. |
open-on | "click" | "hover" | "click" | What opens the fan: a click (click) or the pointer entering the button (hover). Hover
keeps the click working, because a touch screen has no hover. |
actions-label | string | undefined | Accessible name of the button and of the fan when actions are set and the button has no
visible label. Defaults to the locale dictionary entry (showActions). |
open | boolean | false | Whether the fan of actions is open. Two-way binding via v-model:open. |
Events
| Name | Signature | Description |
|---|---|---|
update:open | (value: boolean) => void | Emitted when open changes. Used for two-way binding (v-model:open). |
select | (action: SFabAction) => void | An action of the fan was picked; receives the action itself. |