Floating Action Bar
A persistent, contextual toolbar that floats over page content to provide quick access to key actions. The Floating Action Bar supports two modes: segmented control mode for navigation-style selection, and action mode for grouping related action buttons.
Loading...
Loading...
Overview
Resources
Install
yarn add @camp/floating-action-barUsage
Segment mode
Use segment mode when the bar represents navigation between different views or steps. Selection is controlled at the component level via value and onValueChange.
import { FloatingActionBar } from '@camp/floating-action-bar';
import type { FloatingActionBarSegmentModeItem } from '@camp/floating-action-bar';
import { PencilEditSmall, GridSmall, UsersContactsSmall, SendSmall } from '@camp/icon';
import { useState } from 'react';
const SegmentedFloatingActionBar = () => {
const [selectedSegment, setSelectedSegment] = useState('edit');
const items: FloatingActionBarSegmentModeItem[] = [
{
id: 'edit',
label: 'Edit',
icon: <PencilEditSmall title="Edit" />,
},
{
id: 'template',
label: 'Template',
icon: <GridSmall title="Template" />,
},
{
id: 'audience',
label: 'Audience',
icon: <UsersContactsSmall title="Audience" />,
},
{
id: 'send',
label: 'Send',
icon: <SendSmall title="Send" />,
},
];
return (
<FloatingActionBar
mode="segment"
items={items}
value={selectedSegment}
onValueChange={setSelectedSegment}
overflowPlaceholder="Select step"
/>
);
};Action mode
Use action mode when the bar contains independent action buttons that each handle their own click behavior.
import { FloatingActionBar } from '@camp/floating-action-bar';
import type { FloatingActionBarActionModeItem } from '@camp/floating-action-bar';
import { PipelineColumnsSmall, PencilEditSmall } from '@camp/icon';
const ActionFloatingActionBar = () => {
const items: FloatingActionBarActionModeItem[] = [
{
id: 'layout',
label: 'Layout',
icon: <PipelineColumnsSmall title="Layout" />,
onClick: () => console.log('Layout clicked'),
},
{ id: 'divider-1', divider: true },
{
id: 'edit-classic',
label: 'Edit in classic designer',
icon: <PencilEditSmall title="Edit" />,
onClick: () => console.log('Edit clicked'),
},
];
return <FloatingActionBar mode="action" items={items} />;
};Link items in action mode
Action mode supports link items that navigate to URLs instead of triggering onClick handlers.
import type { FloatingActionBarLinkItem } from '@camp/floating-action-bar';
import { LinkMedium } from '@camp/icon';
const items: FloatingActionBarActionModeItem[] = [
{
id: 'edit',
label: 'Edit',
icon: <PencilEditSmall title="Edit" />,
onClick: () => {},
},
{ id: 'divider-1', divider: true },
{
id: 'docs-link',
link: true,
label: 'Documentation',
href: 'https://help.activecampaign.com',
target: '_blank',
icon: <LinkMedium title="Documentation" />,
},
];Variations
Position
The bar can be positioned at bottom-left, bottom-center (default), or bottom-right when using fixed positioning.
<FloatingActionBar
mode="segment"
items={items}
value={selectedSegment}
onValueChange={setSelectedSegment}
position="bottom-center" // 'bottom-left' | 'bottom-center' | 'bottom-right'
overflowPlaceholder="Select step"
bottomOffset={16} // Distance from bottom edge (default is 16px)
/>Fixed vs inline positioning
By default, the bar uses fixed positioning to stay visible while scrolling. Set fixed={false} to render it inline as a normal block element.
// Fixed positioning (default) - stays visible while scrolling
<FloatingActionBar
mode="action"
items={items}
fixed={true}
bottomOffset={16} // Distance from bottom edge
/>
// Inline positioning - renders in document flow
<FloatingActionBar
mode="action"
items={items}
fixed={false}
/>Icon-only actions
Action items can display only their icon by setting iconOnly: true. The label remains available for accessibility.
const iconOnlyItems: FloatingActionBarActionModeItem[] = [
{
id: 'edit',
label: 'Edit', // Used for accessibility
icon: <PencilEditSmall title="Edit" />,
iconOnly: true,
onClick: () => {},
},
{
id: 'template',
label: 'Template',
icon: <GridSmall title="Template" />,
iconOnly: true,
onClick: () => {},
},
];Disabled items
Both segment and action items can be disabled.
const items: FloatingActionBarSegmentModeItem[] = [
{
id: 'edit',
label: 'Edit',
icon: <PencilEditSmall title="Edit" />,
},
{
id: 'template',
label: 'Template',
icon: <GridSmall title="Template" />,
disabled: true, // This item is disabled
},
];Dividers
Add visual separators between items using divider items.
const items: FloatingActionBarActionModeItem[] = [
{
id: 'layout',
label: 'Layout',
icon: <PipelineColumnsSmall title="Layout" />,
onClick: () => {},
},
{ id: 'divider-1', divider: true }, // Visual separator
{
id: 'edit',
label: 'Edit',
icon: <PencilEditSmall title="Edit" />,
onClick: () => {},
},
];Overflow handling (automatic)
When items don’t fit within the maxWidth, overflow handling kicks in automatically:
- Segment mode: Uses all-or-nothing overflow. If any item can’t fit, all items move to a dropdown menu.
- Action mode: Items overflow progressively from left to right into a “More” menu. In this example, the “Edit content” item was the leftmost item in the action bar that overflowed first, and it appears at the top of the overflow menu.
// Control overflow with maxWidth
<FloatingActionBar
mode="segment"
items={manyItems}
value={selectedSegment}
onValueChange={setSelectedSegment}
maxWidth="300px" // Forces overflow at narrower widths
overflowPlaceholder="Select step"
/>Toggle theming
Prop: themed
Type: boolean
Default value: true
The themed prop toggles light and dark mode support for the FloatingActionBar component.
// Themed (default) - responds to light/dark mode
<FloatingActionBar themed={true} {...otherProps} />
// Unthemed - always light mode
<FloatingActionBar themed={false} {...otherProps} />Best practices
When to use
- Users need ongoing access to actions while scrolling
- Actions apply to the current page or selection
- User is in a focused state such as editing or previewing
- To reduce cognitive load by keeping key actions visible
Common use cases:
- Campaign editing and review
- Layout or template selection
- Multi-step setup flows
- Preview or comparison states
When not to use
- Actions are not critical or time sensitive
- A standard page header or footer is sufficient
- The page already has persistent navigation controls
- Actions are destructive without confirmation
Mode selection
- Use segment mode when items represent mutually exclusive views or steps (like tabs)
- Use action mode when items are independent actions that can be triggered individually
Content guidelines
✅ DO
- Use clear, concise labels (3 words maximum)
- Include icons for faster visual recognition
- Group related actions with dividers
- Provide meaningful overflow placeholder text
🚫 DON’T
- Don’t use overly long labels that cause overflow
- Don’t mix navigation and action patterns in segment mode
- Don’t include more than 6-8 visible items
- Don’t use for destructive actions without confirmation
Accessibility
Keyboard support
- Tab: Navigate to/from the floating action bar
- Arrow keys: Navigate between items within the bar (segment mode)
- Enter/Space: Select a segment item or trigger an action
- Escape: Close overflow menu when open
Screen reader support
- The component uses
role="toolbar"with an accessible label “Action bar” - Segment items communicate their selected state
- Disabled items are announced as disabled
- Overflow menu is properly labeled and navigable
Focus management
- Focus is visible and follows keyboard navigation
- Focus moves predictably through items
- Overflow menu returns focus appropriately when closed
Item types reference
Segment mode items
type FloatingActionBarSegmentModeItem = FloatingActionBarSegmentItem | FloatingActionBarDividerItem;
type FloatingActionBarSegmentItem = {
id: string;
label: string;
icon?: React.ReactNode;
disabled?: boolean;
};Action mode items
type FloatingActionBarActionModeItem =
| FloatingActionBarActionItem
| FloatingActionBarLinkItem
| FloatingActionBarDividerItem;
type FloatingActionBarActionItem = {
id: string;
label: string;
icon?: React.ReactNode;
disabled?: boolean;
onClick: (e?: React.MouseEvent<HTMLButtonElement>) => void;
iconOnly?: boolean;
};
type FloatingActionBarLinkItem = {
id: string;
link: true;
label: string;
href: string;
target?: '_blank' | '_self' | '_parent' | '_top';
rel?: string;
icon?: React.ReactNode;
};
type FloatingActionBarDividerItem = {
id: string;
divider: true;
};