registry:ui · General
float-button — the fixed corner action
The floating action button in two idioms: plain (a lone fixed action) and menu (an actions snippet toggling a popover stack above). Corner is a prop — your layout is never touched.
float-button
float-button — the fixed corner action: scroll this box (or the page), then press the corner button to ride back to the top.
scroll inside this box or the page itself — the button stays pinned to the viewport corner. Press it and the page rides back to its top.
filler row 1
filler row 2
filler row 3
filler row 4
filler row 5
filler row 6
filler row 7
filler row 8
filler row 9
filler row 10
filler row 11
filler row 12
<script lang="ts">
import FloatButton from '@ui/float-button.svelte';
</script>
<!-- plain idiom: a lone fixed action (compose, support, back-to-top) -->
<FloatButton label="back to top" onclick={() => scrollToTop()}>
<span aria-hidden="true">↑</span>
</FloatButton>
<!-- menu idiom: children + an actions snippet — the button toggles a
popover=auto stack above itself (native light dismiss, Escape, top layer) -->
<FloatButton label="quick actions" corner="bottom-right" class="fab-lift-a">
<span aria-hidden="true">+</span>
{#snippet actions()}
<button type="button" role="menuitem" onclick={compose}>compose</button>
<button type="button" role="menuitem" onclick={support}>support</button>
{/snippet}
</FloatButton>law
Corner is a prop, label is the law
Positioning is a prop, not a wrapper: the component owns its fixed point and the consumer's layout is never touched. The surface follows the press-button laws at a fixed size, and the accessible name is mandatory.
-
labelis required — an icon-only button must say itself; the glyph is decorative andaria-hidden -
cornerpicks one of four fixed points (bottom-right default); no wrapper element, no consumer layout change - the menu idiom rides
popover="auto": light dismiss, Escape, and the top layer belong to the browser; CSS anchor positioning keeps the stack glued to its button with flip fallbacks - the press law is shared with press-button (.jx-press at float scale): hover grows
the shadow (--shadow → --shadow-md) without moving the body, active presses +1px,+1px
on the anchored shadow layer,
:focus-visiblekeeps the ring
types
Plain action or action menu
A FloatButton remains one corner-anchored control; passing actions changes it into a native popover menu trigger.
Plain
A single fixed command via onclick.
Menu
An actions snippet opens an anchored popover menu.
usage
Usage
Set the accessible label, choose the viewport corner, then supply either a direct action or an actions snippet — the full usage file, as the canvas above runs it.
<script lang="ts">
import FloatButton from '@ui/float-button.svelte';
</script>
<!-- plain idiom: a lone fixed action (compose, support, back-to-top) -->
<FloatButton label="back to top" onclick={() => scrollToTop()}>
<span aria-hidden="true">↑</span>
</FloatButton>
<!-- menu idiom: children + an actions snippet — the button toggles a
popover=auto stack above itself (native light dismiss, Escape, top layer) -->
<FloatButton label="quick actions" corner="bottom-right" class="fab-lift-a">
<span aria-hidden="true">+</span>
{#snippet actions()}
<button type="button" role="menuitem" onclick={compose}>compose</button>
<button type="button" role="menuitem" onclick={support}>support</button>
{/snippet}
</FloatButton>a11y
Menu semantics
The visible glyph is decorative; label names the trigger. Native popover behavior provides the expected dismissal path.
Keyboard
| Key | Action |
|---|---|
| Tab | Focus the floating action or an open menu item |
| Enter / Space | Activate the plain action or toggle the menu |
| Escape | Dismiss the popover menu |
ARIA
| Attribute | Value | Description |
|---|---|---|
| aria-label | label | Names the icon-only floating action. |
| aria-haspopup | menu when actions exist | Announces the menu trigger. |
| aria-expanded | open state | Reports whether the menu is visible. |
theming
Corner geometry and density
The fixed control consumes the shared density scale and locally repoints the press-shadow poses for its elevated surface.
| Token | Default | Source |
|---|---|---|
| --jx-hit | 28 / 32 / 40 / 48px | density |
| --jx-gap | 8 / 8 / 12 / 16px | density |
| --jx-press-shadow | var(--shadow) | component |
| --jx-press-shadow-hover | var(--shadow-md) | component |
| --jx-press-shadow-active | var(--shadow-md-press) | component |
axes
Universal props
The eight-axis surface (explicit-props): size · shape · radius · density · color · theme · elevation · motion — each axis takes named steps, auto (inherit the ambient context; stamps nothing), an exact number (px · coefficient · dp · hue per axis), or query() for responsive/container-conditional values. The fab carries its OWN elevation STAMP — level3 (6dp, M3's FAB rung) reaches the root (--jx-elevation-effective = 6, measured), but the shadow RECIPE is unwired on the served surface (--jx-shadow-effective ships empty; no shadow channel paints on the button or the menu panel — the menu's shadow child renders a translucent wash). The wire-or-retire decision is the family owner's — W-next. The carriers stamp the family root (the stack wrapper / the fixed button); the panel's promotion keeps the DOM, so the stamps inherit down.
FloatButton · universal props
<FloatButton label="Actions" corner="bottom-right" class="fab-lift-b" elevation="level4">…</FloatButton>api
Props
FloatButton owns position and popover wiring while leaving command content to the caller.
Properties
| Property | Type | Default | Description |
|---|---|---|---|
| label * | string | — | Accessible name for the icon-only control. |
| corner | 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left' | 'bottom-right' | Viewport corner for the fixed control. On scaffold-based docs pages the sections-nav column owns the left 256px full-height (measured) — left corners are covered there; float right-side corners when embedding in the scaffold (the lane question is queued W-next). |
| onclick | () => void | — | Plain-action handler. |
| actions | Snippet | — | Turns the control into a popover menu trigger. |
| variant | 'solid' | 'acrylic' | 'auto' | 'auto' · Own default, not ambient | Menu panel surface treatment. Defaults: literal slot — own ’auto’, ambient when an axis opens. |
| children * | Snippet | — | Decorative icon or glyph. |
Universal props
| Property | Type | Default | Description |
|---|---|---|---|
| size | 'small' | 'medium' | 'large' | 'auto' | number | 'auto' · ambient scope | the base scale — root font-size; parts size in em |
| shape | 'round' | 'scoop' | 'bevel' | 'notch' | 'square' | 'squircle' | 'auto' | 'auto' · ambient scope | corner geometry (CSS corner-shape; §14 degrade table) |
| radius | 'small' | 'medium' | 'large' | 'auto' | number | 'auto' · ambient scope | corner size; auto = the concentric broadcast (§3) |
| density | 'small' | 'medium' | 'large' | 'auto' | number | 'auto' · ambient scope | spacing/leading scale over the kernel channels (§4) |
| color | 'primary' | 'secondary' | 'error' | 'warn' | 'success' | 'info' | 'auto' | number | string | 'auto' · ambient scope | the hue axis of the fixed oklch primary system (§5) |
| theme | 'light' | 'dark' | 'system' | 'auto' | 'auto' · ambient scope | light/dark profile; system = the JS-mutable global (§6) |
| elevation | 'level-1' | 'level0' | 'level1' | 'level2' | 'level3' | 'level4' | 'level5' | 'auto' | number | 'auto' · ambient scope | official M3 levels over the surface ladder (§7) |
| motion | 'reduced' | 'subtle' | 'normal' | 'expressive' | 'auto' | number | 'auto' · ambient scope | intensity across the motion kernels (§8) |