FloatingToolbar
A floating pill of actions anchored under an element, such as crop mode's size, Reset, Cancel and Apply.
import { FloatingToolbar } from "@butteryui/react";Demo
Title slide
Resizing to 1920 × 1080
When to use it
Use it for
- Actions for a mode that works on one element: crop, trim, a selection
Not for
- Actions that are always there: put them in the HeaderBar or an inspector
- A message: use toast()
Examples
Crop bar
Resize mode's bar under the frame, shown from state: the size, then Revert, Discard and Keep size.
Slide 1600 × 900
Selection actions
Actions for the slides picked, shown while any are: how many, then Clear and Duplicate.
Slide actions
Actions under a slide while it's picked: press the slide to pick it, and Done to put them away.
0 copies
Variants and states
Resize mode
12px under the slide, centered and kept inside the viewport; it rises in a beat after resize mode starts and follows the slide as the page scrolls.
Title slide
Props
FloatingToolbar
| Prop | Type | Default | Description |
|---|---|---|---|
dir | "ltr" | "rtl" | Which way the arrow keys run: "ltr" or "rtl". Follows the page when left out. | |
anchorrequired | RefObject<HTMLElement | null> | The element it sits under, such as the crop frame. It follows the element as it moves. | |
labelrequired | string | Names the toolbar, such as "Slide size". | |
open | boolean | true | Whether it shows. Hiding it plays its exit. Defaults to true. |
meta | ReactNode | Text at its start, such as the size being cropped to. Tabular, and it truncates. | |
delayed | boolean | Waits delay-follow (80ms) before arriving, so it comes in after its anchor changes, as in crop mode. | |
focusOnOpen | boolean | false | Moves focus to its first button that can act when it opens, for a toolbar that's the next step, such
as crop mode's. Either way, focus inside it goes back where it came from when it closes.
Defaults to false. |
childrenrequired | ReactNode | The buttons: FloatingToolbar.Buttons. |
It also takes Omit<ComponentPropsWithRef<"div">, "children" | "dir">.
FloatingToolbar.Button
| Prop | Type | Default | Description |
|---|---|---|---|
variant | "primary" | "secondary" | "soft" | "ghost" | "soft" | "primary" for the one main action in view, "soft" (the default) for the rest, "secondary" on a
tinted surface such as the stage, and "ghost" for quiet actions in toolbars. |
size | "sm" | "md" | "cta" | "md" | "sm" (28px), "md" (36px, the default) or "cta" (48px, for dialog steps and calls to action). |
shape | "pill" | "rounded" | "pill" | "pill" (the default) or "rounded", with 12px corners, for calls to action in dialogs. |
loading | boolean | Shows a spinner over the label, keeping the button's size, and ignores presses while it's busy. | |
iconStart | ComponentType<IconComponentProps> | An icon before the label, such as Plus from lucide-react. | |
iconEnd | ComponentType<IconComponentProps> | An icon after the label. | |
arrow | "forward" | "back" | A navigation arrow: "forward" after the label for Next, Continue and Get started, "back" before it.
Its chevron grows a stem on hover or focus. Leave it off Done, Save, Submit and destructive actions. | |
shortcut | Shortcut | A keyboard shortcut to show after the label, written as useShortcut takes it, such as "n" or
"mod+n". It's announced through aria-keyshortcuts; bind it with useShortcut. | |
asChild | boolean | Render the single child element (such as a link) as the button, with the button's look and parts merged in. The child's own content is the label. |
It also takes ComponentPropsWithRef<"button">.
Accessibility
A toolbar named by label: one Tab stop, with the arrow keys moving between its buttons. Toasts and notices move out of its way instead of covering it.
| Keys | What they do |
|---|---|
| Tab | Moves into the toolbar, on the button that last had focus, and out again: the toolbar is one tab stop |
| Left and Right arrows | Move between its buttons, wrapping at the ends; with dir="rtl" they run the other way |
| Home or End | Moves to its first or last button |
| Enter or Space | Presses the focused button |
Motion
It appears with a `Presence` preset and leaves faster than it came, in about 60% of the time.
With reduced motion: It fades in and out in 100ms where it stands, without rising, and a delayed one arrives without its 80ms wait.
Layout
It's a 48px pill (--bt-h-cta) as wide as its meta and buttons, and never wider than the viewport less 8px a side. It sits centered 12px under its anchor, or above it when there's no room below, and stays 8px inside the viewport as the anchor moves; the meta truncates with its full text in its title, and the buttons keep their size.
Related
See it in the Deckhand demo.