Mosmox UI
Current version
GitHubnpmjs.com
Feedback & Status

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.

VariantUse forDefault iconLandmark role
neutralGeneral, non-urgent contextInformationstatus
infoHelpful updates and announcementsInformationstatus
successCompleted or saved operationsCheck circlestatus
warningAttention required without a blocking errorWarning trianglealert
dangerErrors or urgent problemsAlert circlealert

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, and lg control density and type scale.
  • position="static" participates in normal flow; sticky-top and sticky-bottom remain visible while their scroll container moves.
  • fullWidth expands 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

PropTypeDefaultDescription
variant'neutral' | 'info' | 'success' | 'warning' | 'danger'neutralSemantic tone and default icon.
titleReactNode—Banner heading.
childrenReactNode—Supporting message content.
iconReactNodeVariant iconCustom decorative icon; null removes the icon.
actionsReactNode—Buttons, links, or custom actions.
size'sm' | 'default' | 'lg'defaultDensity and typography scale.
layout'inline' | 'stacked'inlineArrangement of message and actions.
position'static' | 'sticky-top' | 'sticky-bottom'staticPositioning behavior in the page.
fullWidthbooleanfalseExpands to the width of its container.
dismissiblebooleantrueShows or hides the dismiss control.
dismissMode'icon' | 'button'iconDismiss control presentation.
closeLabelstringClose bannerAccessible label for icon dismissal.
dismissLabelReactNodeDismissContent for button dismissal.
dismissIconReactNodeClose iconCustom icon for the dismiss control.
defaultOpenbooleantrueInitial uncontrolled visibility.
openboolean—Controlled visibility.
onOpenChange(open: boolean) => void—Called when controlled visibility changes.
onClose() => void—Called after a dismissal request.
loadingbooleanfalseShows a spinner and disables dismissal.
aria-labelstring—Accessible name for the banner landmark.
idstring—DOM id.
classNamestring—Additional class on the banner.
styleCSSProperties—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

TypeValuesBehavior
BannerVariantneutral, info, success, warning, dangerSemantic color, default icon, and alert/status role.
BannerSizesm, default, lgCompact, standard, or spacious padding and typography.
BannerLayoutinline, stackedInline keeps actions beside the message; stacked moves actions below it.
BannerPositionstatic, sticky-top, sticky-bottomNormal flow or sticky placement inside the relevant scroll container.
BannerDismissModeicon, buttonIcon-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>