Xzero UI
Pro library

Floating button group

Separate soft buttons in a quiet tray, with one shared highlight that morphs from button to button as you move, and a pressed state that settles in place.

$ pnpm dlx shadcn@4.23.0 add @xzero-ui/floating-button-group
Live · keyboard ready

When to use

When not to use

Installation

Register both Xzero UI namespaces in your project's components.json:

{
  "registries": {
    "@xzero-ui": "https://mcp.xzero.co.uk/r/{name}.json",
    "@xzero-ui-pro": "https://mcp.xzero.co.uk/r/pro/{name}.json"
  }
}
npx shadcn@4.23.0 add @xzero-ui/floating-button-group

Install xzero-foundation once, and import @/components/xzero/foundation.css in your app root. No Xzero token is used by this snapshot. For sample portraits, photos, fonts, or logos, download https://mcp.xzero.co.uk/install-assets.mjs and run node xzero-install-assets.mjs <receiving-project>.

Usage

import { Link2, MessageCircle, Play, Redo2, Undo2 } from "lucide-react";
import { FloatingButtonGroup } from "@/components/xzero/floating-button-group/floating-button-group";

export function BoardToolbar({ history, copied, copyLink, presenting, onPresent }: BoardToolbarProps) {
  return (
    <FloatingButtonGroup
      label="Board actions"
      variant="floating"
      items={[
        { id: "undo", label: "Undo", icon: <Undo2 />, iconOnly: true, shortcut: "⌘Z", disabled: !history.canUndo, onSelect: history.undo },
        { id: "redo", label: "Redo", icon: <Redo2 />, iconOnly: true, shortcut: "⇧⌘Z", disabled: !history.canRedo, onSelect: history.redo },
        { type: "separator" },
        { id: "comment", label: "Comment", icon: <MessageCircle />, shortcut: "C" },
        { id: "share", label: copied ? "Copied" : "Share", reserveLabels: ["Share", "Copied"], icon: <Link2 />, onSelect: copyLink },
        { type: "separator" },
        { id: "present", label: presenting ? "Stop" : "Present", reserveLabels: ["Present", "Stop"], icon: <Play />, pressed: presenting, onSelect: onPresent },
      ]}
      onAction={id => track("toolbar", id)}
    />
  );
}

API reference

FloatingButtonGroup

Separate soft buttons in a quiet tray, with one shared highlight that morphs from button to button as you move, and a pressed state that settles in place. An action toolbar: each button does something; nothing stays selected. For a set of options where one or more stay chosen, use toggle-group.

PropTypeDefaultDescription
items (required)({ id: string; label: string; icon?: ReactNode; iconOnly?: boolean; onSelect?: () => void; disabled?: boolean; pressed?: boolean; shortcut?: string; reserveLabels?: string[] } | { type: "separator"; id?: string })[]–The buttons in order. A separator draws a short rule between logical clusters. label is the visible text and the accessible name; iconOnly moves it into a tooltip. pressed marks an action that switches a mode on, such as Present, with aria-pressed and a quiet tint. shortcut is shown in the tooltip only; the component does not bind the key. reserveLabels lists the other labels an item can switch to, such as ["Share", "Copied"]: the button always has the width of the widest, so a label change never resizes the button, its neighbours or the tray.
label (required)string–Accessible name of the toolbar, such as "Board actions".
variant"muted" | "floating""muted"muted sits quietly on a page on the muted surface. floating raises the tray with a hairline edge and the floating shadow, for overlays such as a selection or canvas toolbar.
size"sm" | "md""md"Button height of 30 or 36px, with matching tray padding, gaps and corner radius.
orientation"horizontal" | "vertical""horizontal"A row or a column, such as a tools rail. Arrow keys follow the orientation.
iconOnlybooleanfalseShows every item with an icon as an icon only. An item's own iconOnly wins, so a toolbar can mix icon buttons with labelled ones.
tooltipSide"top" | "bottom" | "left" | "right""top" for a row, "right" for a columnWhere item tooltips open. Top and bottom use the library Tooltip; left and right open beside a column without covering its neighbours.
onAction(id: string) => void–Called with the item id after the item's own onSelect, for handling every action in one place.
classNamestring–Extra class on the tray.
styleCSSProperties–Inline styles on the tray.

Keyboard interactions

KeysAction
TabMoves into the toolbar on one button, the last one focused, and out again. The highlight appears on the focused button.
Arrow left / Arrow rightIn a row: moves focus to the previous or next enabled button, wrapping at the ends. The highlight follows.
Arrow up / Arrow downIn a column: moves focus to the previous or next enabled button, wrapping at the ends.
Home / EndMoves focus to the first or last enabled button.
Enter / SpaceRuns the focused action. The highlight darkens while the key is held.

Accessibility

Motion

Responsive behavior

Performance

Notes for AI

Also in buttons

Guidance for AI tools

Floating button group: Separate soft buttons in a quiet tray, with one shared highlight that morphs from button to button as you move, and a pressed state that settles in place. Follow the declared prop types and do not invent props. Keep keyboard access, reduced motion support, and both light and dark themes intact when adapting it.

Full library index: https://ui.xzero.co.uk/llms.txt

Browse all components