Examples
The examples below mirror the richer Storybook cases from the local fab-button repository, not only the package README.
Example Catalog
| Example | What it demonstrates |
|---|---|
| Default | Single-section default button |
| Tech Stack Button | Multiple static sections for grouped labels |
| Icon Label Count Button | Pill shape with icon, label, and count sections |
| Puzzle Button Four Actions | Grid layout with custom columns, rows, and gap |
| Toolbar Keyboard Navigation | Toolbar roving navigation with loop behavior |
| Keyboard Shortcut Integration | Direct shortcut keys and shortcut ID mapping |
| Section Confirm Flow | Per-section confirmation before action execution |
| Per Section Async State | Promise-aware feedback and manual section state |
| Responsive Overflow Mode | Automatic More menu on narrow layouts |
| Split Button Preset | Primary action plus dropdown alternatives |
| Multi Split Buttons | Several independent split buttons in one UI |
| Action Analytics Hook | Action source tracking from click, shortcut, or keyboard |
| Full Keyboard Shortcut ID Map | Reference map for keyboard codes |
| Legacy CSS Integration | Works inside existing CSS wrappers |
| Tailwind Like Class Name Example | unstyled with external class styling |
| Unstyled Mode | Full control through className and inline style |
| Disabled | Whole-button disabled state |
| Loading | Whole-button loading state |
| Dark Theme | Native dark theme rendering |
| Floating Button | Fixed viewport action menu |
| Attached Panels | Section 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" }
]}
/>