Components / Actions

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.

Install

npx shadcn@latest add https://irisui.dev/r/floating-button-group.json
import { FloatingButtonGroup } from "@/components/iris/floating-button-group/floating-button-group";
Registry item floating-button-groupBrings in foundationRegistry JSON

Preview

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.

When to use

  • Toolbars that float over content: a text-selection toolbar, a board's action tray, a vertical canvas tool rail.
  • Mode toggles that stay on (Present, Bold) — use pressed for a quiet tint and aria-pressed.
  • For joined segments with hairline dividers and an attached menu, use ButtonGroup. For icon actions that reveal their label on focus, use ExpandingButtonGroup.

Usage

import { FloatingButtonGroup } from "@/components/iris/floating-button-group/floating-button-group";

<FloatingButtonGroup
  label="Text formatting"
  variant="floating"
  iconOnly
  items={[
    { id: "bold", label: "Bold", icon: <BoldIcon />, shortcut: "⌘B", pressed: isBold },
    { id: "italic", label: "Italic", icon: <ItalicIcon />, shortcut: "⌘I" },
    { type: "separator" },
    { id: "link", label: "Add link", icon: <LinkIcon />, shortcut: "⌘K" },
  ]}
  onAction={(id) => editor.run(id)}
/>;

Props

Prop Type Default Description
items (FloatingButtonGroupAction | { type: "separator", id? })[] — Required. Actions: { id, label, icon?, iconOnly?, onSelect?, disabled?, pressed?, shortcut?, reserveLabels? }.
label string — Accessible name of the toolbar (required).
variant "muted" | "floating" "muted" muted sits on a page; floating raises the tray with the floating shadow.
size "sm" | "md" "md" Button size.
orientation "horizontal" | "vertical" "horizontal" Row or column.
iconOnly boolean false Shows every item as an icon with its label in a tooltip. Per-item iconOnly wins.
tooltipSide "top" | "bottom" | "left" | "right" top / right Tooltip side; defaults to top for a row and right for a column.
onAction (id: string) => void — Called with the item id after the item's own onSelect.
className, style — — Passed to the root.

Notes

  • Renders role="toolbar" with aria-orientation and a roving tab stop: Tab enters once, arrow keys, Home and End move between items.
  • shortcut is only a hint in the tooltip; the component does not bind keys.
  • reserveLabels keeps an item at the width of its widest label, so "Share" to "Copied" never moves its neighbours.
  • Reduced motion removes the gliding highlight.