Banner
Persistent, page-level messaging with semantic variants, actions, dismissal, and responsive layouts.
Banner is a non-modal message surface for important information that belongs to a page or application shell. Use it for announcements, service status, saved-state feedback, warnings, release notes, maintenance notices, and calls to action. Use AlertInline for smaller contextual feedback inside a form or section.
Basic usage
import { Banner, Button } from '@mosmox/ui';
<Banner
variant="info"
title="New workspace features"
actions={<Button size="sm">Explore</Button>}
>
Create shared views and automate recurring tasks.
</Banner>The banner is visible by default. title, children, actions, and icon accept any React content. The component uses design tokens for its surface, border, accent, typography, focus, and spacing.
The component is intentionally persistent: it does not have an automatic timeout. It stays in the document until the parent changes open, the user dismisses it, or the component is removed by the parent.
Single-line message without a title
title is optional. Omit it when the banner should be a compact one-line message with an icon and text. The variant supplies the semantic default icon; pass icon to replace it. Actions and dismissal remain available.
<Banner
variant="info"
actions={<Button size="sm" variant="text">View details</Button>}
>
Your workspace is ready to use.
</Banner>
<Banner size="sm" variant="success" dismissible={false}>
Changes were saved successfully.
</Banner>When no title is supplied, the content is rendered as the primary message in the same horizontal layout as the icon and actions. Use layout="stacked" only when the actions should move below the message on narrow or content-heavy banners.
Variants
variant controls semantic meaning and the default icon:
<Banner variant="neutral" title="Information">Additional context.</Banner>
<Banner variant="info" title="New release">Version 2.1 is available.</Banner>
<Banner variant="success" title="Changes saved">Your changes are now live.</Banner>
<Banner variant="warning" title="Review required">Some settings need attention.</Banner>
<Banner variant="danger" title="Payment action required">Update your billing method.</Banner>Replace the automatic icon with icon, or pass icon={null} when the message should not show an icon.
| Variant | Use for | Default icon | Landmark role |
|---|---|---|---|
neutral | General, non-urgent context | Information | status |
info | Helpful updates and announcements | Information | status |
success | Completed or saved operations | Check circle | status |
warning | Attention required without a blocking error | Warning triangle | alert |
danger | Errors or urgent problems | Alert circle | alert |
Actions and custom content
Use actions for buttons, links, or any action group. Actions are kept outside the message body so the layout remains predictable.
<Banner
variant="warning"
title="Connection is unstable"
actions={<><Button size="sm" variant="outline">Retry</Button><Button size="sm" variant="text">Details</Button></>}
>
Some changes may be delayed until the connection is restored.
</Banner>Dismissal and controlled visibility
Dismissal is enabled by default. Use dismissible={false} for a permanent message. dismissMode="icon" renders an accessible close icon; dismissMode="button" renders a labeled button.
const [open, setOpen] = useState(true);
<Banner
open={open}
onOpenChange={setOpen}
onClose={() => logEvent('banner_closed')}
dismissMode="button"
dismissLabel="Got it"
closeLabel="Close announcement"
title="Scheduled maintenance"
>
The service will be briefly unavailable on Saturday.
</Banner>Use defaultOpen={false} for an initially hidden uncontrolled banner. Use open and onOpenChange when visibility belongs to the parent state. onClose is called whenever the banner is dismissed.
Layout, sizes, and position
layout="inline"keeps content and actions on one row when space allows.layout="stacked"places actions below the message, useful for longer content or mobile layouts.size="sm",default, andlgcontrol density and type scale.position="static"participates in normal flow;sticky-topandsticky-bottomremain visible while their scroll container moves.fullWidthexpands the banner to its containing block.
<Banner size="sm" title="Compact announcement">Short message.</Banner>
<Banner size="lg" layout="stacked" title="Maintenance">Longer supporting information.</Banner>
<Banner position="sticky-top" fullWidth variant="info" title="Service status">All systems operational.</Banner>Loading and states
loading replaces the action area with a spinner and prevents dismissal. It is useful while saving, publishing, or checking service availability.
<Banner loading variant="neutral" title="Saving preferences">
Please wait while your changes are stored.
</Banner>When loading is true, supplied actions are not rendered and the dismiss control is disabled. The banner remains visible until its controlled state or parent content changes.
ConfigProvider defaults
The provider can define defaults for every Banner in a subtree. Explicit props override provider values.
<ConfigProvider components={{ banner: { variant: 'success', size: 'sm', layout: 'inline', position: 'static' } }}>
<Banner title="Configured defaults">This banner inherits the provider settings.</Banner>
</ConfigProvider>Accessibility
Banner renders an aside landmark. Warning and danger banners use role="alert"; neutral, info, and success banners use role="status". The dismiss control is keyboard accessible and receives closeLabel. Use a visible title for context, and provide aria-label when the surrounding page needs a more specific landmark name. Actions should have their own accessible names.
API
| Prop | Type | Default | Description |
|---|---|---|---|
variant | 'neutral' | 'info' | 'success' | 'warning' | 'danger' | neutral | Semantic tone and default icon. |
title | ReactNode | — | Banner heading. |
children | ReactNode | — | Supporting message content. |
icon | ReactNode | Variant icon | Custom decorative icon; null removes the icon. |
actions | ReactNode | — | Buttons, links, or custom actions. |
size | 'sm' | 'default' | 'lg' | default | Density and typography scale. |
layout | 'inline' | 'stacked' | inline | Arrangement of message and actions. |
position | 'static' | 'sticky-top' | 'sticky-bottom' | static | Positioning behavior in the page. |
fullWidth | boolean | false | Expands to the width of its container. |
dismissible | boolean | true | Shows or hides the dismiss control. |
dismissMode | 'icon' | 'button' | icon | Dismiss control presentation. |
closeLabel | string | Close banner | Accessible label for icon dismissal. |
dismissLabel | ReactNode | Dismiss | Content for button dismissal. |
dismissIcon | ReactNode | Close icon | Custom icon for the dismiss control. |
defaultOpen | boolean | true | Initial uncontrolled visibility. |
open | boolean | — | Controlled visibility. |
onOpenChange | (open: boolean) => void | — | Called when controlled visibility changes. |
onClose | () => void | — | Called after a dismissal request. |
loading | boolean | false | Shows a spinner and disables dismissal. |
aria-label | string | — | Accessible name for the banner landmark. |
id | string | — | DOM id. |
className | string | — | Additional class on the banner. |
style | CSSProperties | — | Inline styles on the banner. |
BannerConfig
ConfigProvider.components.banner accepts variant, size, layout, and position. These values provide subtree defaults and never override explicit Banner props.
Value reference
| Type | Values | Behavior |
|---|---|---|
BannerVariant | neutral, info, success, warning, danger | Semantic color, default icon, and alert/status role. |
BannerSize | sm, default, lg | Compact, standard, or spacious padding and typography. |
BannerLayout | inline, stacked | Inline keeps actions beside the message; stacked moves actions below it. |
BannerPosition | static, sticky-top, sticky-bottom | Normal flow or sticky placement inside the relevant scroll container. |
BannerDismissMode | icon, button | Icon-only close control or labeled Button-based dismissal. |
Controlled and uncontrolled usage
Use defaultOpen when the banner owns its initial visibility. Use open with onOpenChange when the parent owns visibility. Explicit component props always take precedence over ConfigProvider defaults.
const [open, setOpen] = useState(true);
<Banner
open={open}
onOpenChange={setOpen}
onClose={() => analytics.track('banner_closed')}
variant="success"
title="Changes saved"
>
Your changes are now available to the team.
</Banner>