HyFab
Usage examples on this page are written for Lit / plain HTML (
<hy-fab>). The same component ships asHyFabin@whitespaceux/harmony-react(native React 19), with typed wrappers for Angular, Solid, Svelte, and Vue. The API reference below applies to all frameworks.
A floating action button (FAB) for primary or prominent actions.
The FAB is a circular button that floats above the UI, representing the most important or frequent action on a screen. It supports an extended variant that shows both an icon and a text label in a pill shape.
Key Features
- Circular (icon-only) and extended (icon + label) variants
- Three sizes on the control-height ladder: small (32px), medium (40px), large (48px) at standard density
- Two identity variants (brand, neutral) aligned with the design system, and
highlightfor the one action that stands out on a screen - Optional fixed positioning with presets (bottom-right, bottom-left, etc.)
- Link mode when href is provided
- Loading state with spinner
- Fully accessible with keyboard navigation
- SSR compatible
Accessibility: built in
aria-labelset from thelabelproperty in icon-only mode- In extended mode, visible label text provides the accessible name
- Full keyboard navigation (Enter, Space)
- Visible focus indicators
- Small grows to the 48px touch target on coarse-pointer devices
- High contrast mode support
- Reduced motion support
- Screen reader loading announcements
Accessibility: your part
- Write
labelfor the action it performs, not for the icon it shows.
When to use
- The one action a screen exists for, which people take again and again: compose, add, create.
- A mobile or tablet screen where the main action must stay in reach while the content scrolls.
Do
- Keep one per screen.
- Use
extendedwith a label when the icon alone could mean more than one thing. - Place it where it covers no content people need, with room around it at the end of a scrolling list.
When not to use
- Several actions of equal weight, or more than one per screen: a row of
hy-button. - A destructive or irreversible action:
hy-button variant="danger". - A per-item or toolbar action:
hy-icon-button. - Moving to another page:
hy-link. - A screen with no single main action, such as settings or a read-only view: no floating button.
Examples
Basic icon-only FAB
<hy-fab icon="heart" label="Add to favorites"></hy-fab>Extended FAB with label
<hy-fab icon="heart" label="Favorite" extended></hy-fab>Fixed position FAB
<hy-fab icon="heart" label="Favorite" position="bottom-right"></hy-fab>Brand variant, large size
<hy-fab icon="search" label="Search" variant="brand" size="large"></hy-fab>Link mode FAB
<hy-fab icon="home" label="Home" href="/home"></hy-fab>Loading state
<hy-fab icon="cloud-upload" label="Uploading..." loading></hy-fab>Click gating: Native click events bubble normally. When disabled or loading, clicks are stopped (stopPropagation + preventDefault) on the host so external listeners never see them.
API
Properties
| Property | Attribute | Type | Default | Description |
|---|---|---|---|---|
icon | icon | string | undefined | — | The name of the icon to display. Must match an icon in the configured icon set. |
label | label | string | '' | Accessible label for the FAB. Required. |
variant | variant | 'brand' | 'neutral' | 'highlight' | 'brand' | The visual variant of the FAB determining color scheme. - brand - Primary brand color for the main action (default) - neutral - Subtle, non-semantic styling - highlight - the one action that stands out on a screen: brand, plus the design system's gradients |
emphasis | emphasis | 'solid' | 'soft' | 'outlined' | 'solid' | Visual chrome weight on top of the role. - solid (default) — full role fill, on-color icon - soft — role-tinted fill, role-colored icon - outlined — transparent fill, role border, role-colored icon |
size | size | 'small' | 'medium' | 'large' | 'large' | The size of the FAB. - small - 32px, compact for secondary floating actions - medium - 40px, balanced size - large - 48px, prominent primary actions (default) (control heights at standard density) |
extended | extended | boolean | false | Whether to display the extended variant (icon + visible label text). Extended FABs render as a pill shape instead of a circle. |
disabled | disabled | boolean | false | Whether the FAB is disabled. |
loading | loading | boolean | false | Whether the FAB is in a loading state. Shows a spinner and prevents interaction. |
loadingText | loading-text | string | 'Loading' | Text announced to screen readers during loading state. Use for internationalization. |
href | href | string | undefined | — | URL for link mode. When set, the FAB renders as an anchor element. |
target | target | string | undefined | — | Link target. Only used when href is set. |
rel | rel | string | undefined | — | Link rel attribute. Only used when href is set. |
position | position | 'bottom-right' | 'bottom-left' | 'bottom-center' | 'top-right' | 'top-left' | 'top-center' | — | Preset fixed position for the FAB. When set, the FAB uses position: fixed and is placed at the specified viewport corner or edge. |
autofocus | autofocus | boolean | false | Marks this FAB as the auto-focus target. Read by hy-dialog (and other overlay containers) on show to choose initial focus. Also focuses on first connect when used outside an overlay, mirroring native HTML autofocus but routed through JS so SSR'd HTML doesn't pull focus during hydration. |
CSS Parts
| Part | Description |
|---|---|
base | The FAB's base wrapper element (button or anchor tag) |
icon | The icon container |
label | The visible label text (extended mode only) |
CSS Custom Properties
The documented hooks. Every override hook the component reads — one per token it paints — is listed in @whitespaceux/harmony/theme-api.json, and @whitespaceux/harmony/component-bindings.json (the Harmony MCP get-bindings tool) says which part and state each one paints.
| Property | Default | Description |
|---|---|---|
--hy-fab-text-transform | none | Text transform for FAB label |
--hy-fab-shadow-elevation-3 | var(--hy-shadow-elevation-3) | Box shadow at rest |
--hy-fab-shadow-elevation-4 | var(--hy-shadow-elevation-4) | Box shadow on hover |
--hy-fab-background-brand-solid-rest | var(--hy-background-brand-solid-rest) | One of the generated color hooks (paint/fab.mjs): --hy-fab[-<part>]-<family>-<variant>-<emphasis-or-on>-<state> (family: background, foreground or border), one per cell and state, each falling back to the job token of the same name (the default cell is brand solid). Components ▸ Add an override lists them all. |
--hy-fab-motion-transition-hover-duration | var(--hy-motion-transition-hover-duration) | Transition duration for hover and focus state feedback |
--hy-fab-motion-transition-hover-easing | var(--hy-motion-transition-hover-easing) | Transition easing for hover and focus state feedback |
--hy-fab-motion-loop-slow-spin-duration | var(--hy-motion-loop-slow-spin-duration) | Loading-spinner rotation duration |
--hy-fab-motion-loop-slow-spin-easing | var(--hy-motion-loop-slow-spin-easing) | Loading-spinner rotation easing |
Methods
focus()
Sets focus on the FAB.
blur()
Removes focus from the FAB.