FabButton
DocumentationFabButton

Examples

The examples below mirror the richer Storybook cases from the local fab-button repository, not only the package README.

Example Catalog

ExampleWhat it demonstrates
DefaultSingle-section default button
Tech Stack ButtonMultiple static sections for grouped labels
Icon Label Count ButtonPill shape with icon, label, and count sections
Puzzle Button Four ActionsGrid layout with custom columns, rows, and gap
Toolbar Keyboard NavigationToolbar roving navigation with loop behavior
Keyboard Shortcut IntegrationDirect shortcut keys and shortcut ID mapping
Section Confirm FlowPer-section confirmation before action execution
Per Section Async StatePromise-aware feedback and manual section state
Responsive Overflow ModeAutomatic More menu on narrow layouts
Split Button PresetPrimary action plus dropdown alternatives
Multi Split ButtonsSeveral independent split buttons in one UI
Action Analytics HookAction source tracking from click, shortcut, or keyboard
Full Keyboard Shortcut ID MapReference map for keyboard codes
Legacy CSS IntegrationWorks inside existing CSS wrappers
Tailwind Like Class Name Exampleunstyled with external class styling
Unstyled ModeFull control through className and inline style
DisabledWhole-button disabled state
LoadingWhole-button loading state
Dark ThemeNative dark theme rendering
Floating ButtonFixed viewport action menu
Attached PanelsSection panels for compose/upload/settings workflows

Floating Button With Attached Panels

<FabButton
  floating
  floatingPosition="bottom-right"
  floatingOffset="24px"
  floatingMenuLabel="Actions"
  sections={[
    {
      key: "compose",
      content: "Compose",
      panelTitle: "Compose",
      panel: ({ close }) => (
        <form onSubmit={(event) => {
          event.preventDefault()
          close()
        }}>
          <input aria-label="Subject" placeholder="Subject" />
          <textarea aria-label="Message" placeholder="Write a message" />
          <button type="submit">Save Draft</button>
        </form>
      )
    },
    {
      key: "upload",
      content: "Upload",
      panelTitle: "Upload",
      panel: <div>Upload queue content can live here.</div>
    },
    { key: "share", content: "Share", onClick: () => {} }
  ]}
/>

Escape and outside click close the menu or panel. onClick can be used together with panel for analytics or side effects.

Tech Stack Button

Use multiple non-interactive sections when the button is a compact status or stack indicator.

<FabButton
  variant="primary"
  sections={[
    { key: "js", content: "JS" },
    { key: "ts", content: "TS" },
    { key: "vite", content: "Vite" }
  ]}
/>

Icon Label Count Button

Compose icon, label, and count as separate sections while keeping one visual control.

<FabButton
  shape="pill"
  sections={[
    { key: "icon", content: "Bell", ariaLabel: "Notification icon" },
    { key: "label", content: "Alerts" },
    { key: "count", content: "12" }
  ]}
/>

Grid Action Button

Use layout="grid" when the control needs a compact two-by-two command pad.

<FabButton
  layout="grid"
  columns="repeat(2, minmax(84px, 1fr))"
  rows="repeat(2, minmax(42px, auto))"
  gap="6px"
  sections={[
    { key: "up", content: "Up", onClick: moveUp, ariaLabel: "Move up" },
    { key: "left", content: "Left", onClick: moveLeft, ariaLabel: "Move left" },
    { key: "right", content: "Right", onClick: moveRight, ariaLabel: "Move right" },
    { key: "down", content: "Down", onClick: moveDown, ariaLabel: "Move down" }
  ]}
/>

Keyboard Shortcuts

FabButton can render shortcut hint badges and route shortcut events to the right section.

<FabButton
  keyboardNavigation="toolbar"
  sections={[
    { key: "copy", shortcut: "1", content: "Copy", onClick: copy },
    { key: "share", shortcutId: 16, content: "Share", onClick: share },
    { key: "save", shortcutId: 17, content: "Save", onClick: save }
  ]}
/>

Confirmation Flow

Use confirm for destructive or sensitive actions.

<FabButton
  sections={[
    { key: "archive", content: "Archive", onClick: archive },
    {
      key: "delete",
      content: "Delete",
      confirm: {
        title: "Delete this item?",
        description: "This action cannot be undone."
      },
      onClick: deleteItem
    }
  ]}
/>

Async Feedback

Returning a promise enables automatic loading and result feedback. For controlled cases, set asyncState manually.

<FabButton
  sections={[
    {
      key: "save",
      content: "Save",
      asyncFeedbackDuration: 1300,
      onClick: async () => {
        await save()
      }
    },
    {
      key: "publish",
      content: "Publish",
      asyncFeedbackDuration: 1600,
      onClick: async () => {
        await publish()
      }
    },
    { key: "sync", content: "Sync", asyncState: manualState }
  ]}
/>

Responsive More Menu

Set overflowMode="more" to keep dense action groups usable on smaller screens.

<FabButton
  keyboardNavigation="toolbar"
  overflowMode="more"
  overflowBreakpoint={900}
  overflowVisibleCount={2}
  overflowMenuLabel="More"
  sections={[
    { key: "copy", content: "Copy", onClick: copy },
    { key: "share", content: "Share", onClick: share },
    { key: "save", content: "Save", onClick: save },
    { key: "archive", content: "Archive", onClick: archive },
    { key: "delete", content: "Delete", onClick: deleteItem }
  ]}
/>

Split Button

actionPreset="split" turns one section into the primary action and places the rest in a dropdown. After a dropdown action is selected, it can become the new primary action.

<FabButton
  keyboardNavigation="toolbar"
  actionPreset="split"
  sections={[
    { key: "save", content: "Save", onClick: save },
    { key: "publish", content: "Publish", onClick: publish },
    { key: "archive", content: "Archive", onClick: archive },
    { key: "delete", content: "Delete", onClick: deleteItem }
  ]}
/>

Multi Split Buttons

Each split button manages its own primary action and dropdown state.

<div className="action-row">
  <FabButton
    keyboardNavigation="toolbar"
    actionPreset="split"
    sections={[
      { key: "save", content: "Save", onClick: save },
      { key: "save-as", content: "Save As", onClick: saveAs },
      { key: "duplicate", content: "Duplicate", onClick: duplicate }
    ]}
  />
  <FabButton
    keyboardNavigation="toolbar"
    actionPreset="split"
    sections={[
      { key: "pdf", content: "Export PDF", onClick: exportPdf },
      { key: "png", content: "Export PNG", onClick: exportPng },
      { key: "csv", content: "Export CSV", onClick: exportCsv }
    ]}
  />
</div>

Action Analytics

onSectionAction receives metadata for the action source, so analytics can distinguish mouse clicks, shortcut activation, and keyboard navigation.

<FabButton
  keyboardNavigation="toolbar"
  sections={[
    { key: "copy", shortcut: "1", content: "Copy", onClick: copy },
    { key: "share", shortcutId: 16, content: "Share", onClick: share },
    { key: "save", content: "Save", onClick: save }
  ]}
  onSectionAction={(meta) => {
    analytics.track("fab_button_action", {
      key: meta.key,
      source: meta.source
    })
  }}
/>

Unstyled And Class-Based Styling

Use unstyled when your own design system should own the class names and section styling.

<FabButton
  className="tailwind-like"
  unstyled
  sections={[
    { key: "left", content: "Tailwind-like" },
    { key: "right", content: "Class Name API" }
  ]}
/>

Disabled, Loading, And Dark Theme

<FabButton disabled sections={[{ key: "label", content: "Disabled" }]} />
 
<FabButton loading sections={[{ key: "label", content: "Submit" }]} />
 
<FabButton
  theme="dark"
  variant="default"
  sections={[
    { key: "label", content: "Dark Theme" },
    { key: "state", content: "Native Support" }
  ]}
/>