Banner
A full-width dismissible announcement banner with 6 semantic variants, top/bottom/inline positioning, and Framer Motion slide animations.
Basic
A full-width announcement banner for system notices, promotions, and alerts. Supports 6 color variants, top/bottom/inline positioning, dismissible mode, and slide animations.
Installation
Install the component via the CLI in one command.
npx @work-rjkashyap/unified-ui add bannerpnpm dlx @work-rjkashyap/unified-ui add bannernpx @work-rjkashyap/unified-ui add bannerbunx @work-rjkashyap/unified-ui add bannerIf you haven't initialized your project yet, run npx @work-rjkashyap/unified-ui init first. See the CLI docs for details.
Or install the full package
Use this approach if you prefer to install the entire design system as a dependency instead of copying individual components.
npm install @work-rjkashyap/unified-uipnpm add @work-rjkashyap/unified-uiyarn add @work-rjkashyap/unified-uibun add @work-rjkashyap/unified-uiAnatomy
import {
Banner,
Button,
} from "@work-rjkashyap/unified-ui";Basic Usage
Render a simple inline banner by wrapping your message in <Banner>. It manages its own visibility state by default.
<Banner>
Welcome to Unified UI — the production-ready design system for React.
</Banner>Variants
Six semantic color variants for different message types and urgency levels.
| Variant | Background | Text Color | Use Case |
|---|---|---|---|
default | --foreground | --background | Neutral promotions, launch notices |
primary | --primary | --primary-foreground | Branded CTAs, new feature highlights |
info | --info | --info-foreground | System notices, tips, FYIs |
success | --success | --success-foreground | Successful ops, completed migrations |
warning | --warning | --warning-foreground | Degraded services, upcoming changes |
danger | --danger | --danger-foreground | Outages, critical security alerts |
Dismissible
Set dismissible to show a close button. The banner animates out on dismiss.
With Icon
Use the icon prop to render a leading icon before the message content.
With Action
Pass an action prop to render a button or link in the trailing area (before the dismiss button).
Positioning
Inline (default)
The inline position renders the banner as a block element with rounded-md — suitable for use inside page sections, cards, or forms.
<Banner variant="info" position="inline">
This is an inline banner inside a form or card section.
</Banner>Sticky Top
position="top" makes the banner sticky to the top of its scroll container with z-banner. It slides down from the top on mount and slides back up on dismiss.
{/* Typically placed at the very top of your layout */}
<Banner variant="warning" position="top" dismissible>
Scheduled maintenance in 30 minutes — save your work.
</Banner>Sticky Bottom
position="bottom" makes the banner sticky to the bottom of its scroll container. It slides up from the bottom on mount.
<Banner variant="primary" position="bottom" dismissible>
🍪 We use cookies to improve your experience.{" "}
<a href="/privacy" className="underline">
Learn more
</a>
</Banner>Controlled Visibility
Use visible and onDismiss for programmatic control of the banner's open state.
const [bannerVisible, setBannerVisible] = useState(true);
<Banner
variant="info"
visible={bannerVisible}
onDismiss={() => setBannerVisible(false)}
dismissible
>
This banner is controlled externally.
</Banner>;Default Visible
Use defaultVisible={false} to start the banner hidden and show it later.
const [show, setShow] = useState(false);
<Button onClick={() => setShow(true)}>Show Banner</Button>
<Banner
variant="success"
defaultVisible={false}
visible={show}
dismissible
onDismiss={() => setShow(false)}
>
Settings saved successfully.
</Banner>Cookie Consent Pattern
A common pattern for GDPR / cookie consent banners.
import { useState, useEffect } from "react";
import { Banner, Button } from "@work-rjkashyap/unified-ui";
function CookieBanner() {
const [visible, setVisible] = useState(false);
useEffect(() => {
const accepted = localStorage.getItem("cookies-accepted");
if (!accepted) setVisible(true);
}, []);
const accept = () => {
localStorage.setItem("cookies-accepted", "true");
setVisible(false);
};
return (
<Banner
variant="default"
position="bottom"
visible={visible}
action={
<div className="flex gap-2 shrink-0">
<Button size="sm" variant="secondary" onClick={() => setVisible(false)}>
Decline
</Button>
<Button size="sm" variant="primary" onClick={accept}>
Accept All
</Button>
</div>
}
>
We use cookies to improve your experience and analyze site usage.{" "}
<a href="/privacy" className="underline font-medium">
Privacy Policy
</a>
</Banner>
);
}Maintenance Notice Pattern
<Banner
variant="warning"
position="top"
icon={<AlertTriangle className="size-4" />}
action={
<a href="/status" className="text-xs underline font-medium shrink-0">
Status page →
</a>
}
dismissible
>
Scheduled maintenance window: Sunday Feb 2, 2:00–4:00 AM UTC. Some
features may be unavailable.
</Banner>Props
| Prop | Type | Default | Description |
|---|---|---|---|
variant | "default" | "primary" | "info" | "success" | "warning" | "danger" | "default" | Color variant of the banner. |
position | "top" | "bottom" | "inline" | "inline" | Positioning strategy — sticky top, sticky bottom, or inline block. |
dismissible | boolean | false | Whether to show a close button. |
onDismiss | () => void | — | Callback fired when the banner is dismissed. |
dismissLabel | string | "Dismiss" | Accessible label for the dismiss button. |
icon | ReactNode | — | Leading icon slot rendered before the message. |
action | ReactNode | — | Trailing action slot rendered before the dismiss button. |
visible | boolean | — | Controlled visibility state. |
defaultVisible | boolean | true | Initial visibility for uncontrolled mode. |
className | string | — | Additional CSS classes on the root element. |
children | ReactNode | — | The banner message content. |
Standard HTML div attributes (id, style, role, aria-label, aria-live) are also accepted and forwarded to the root element.
Motion
- Top banner — Slides down from
-100%using theslideDownpreset on mount and reverses on exit. - Bottom banner — Slides up from
100%using theslideUppreset on mount and reverses on exit. - Inline banner — Uses
fadeIn-style opacity transition on mount. - Dismiss —
AnimatePresencehandles the exit animation before the element is removed from the DOM. - All animations respect
prefers-reduced-motionviauseReducedMotion()— falling back to a simple opacity transition.
Accessibility
- Wrap the banner content in
aria-live="polite"(or"assertive"for urgent notices) to announce it to screen readers when it appears dynamically. - The dismiss button has
aria-label(defaults to"Dismiss"). - Dismiss button icon is
aria-hidden="true". - For top/bottom sticky banners, add
role="banner"orrole="complementary"when appropriate for the page context. - Ensure sufficient color contrast for all text in each variant — all default variants meet WCAG AA.
Design Tokens
| Token | Usage |
|---|---|
--foreground | Default variant background |
--background | Default variant text color |
--primary | Primary variant background |
--info | Info variant background |
--success | Success variant background |
--warning | Warning variant background |
--danger | Danger variant background |
--z-banner | Z-index for sticky top/bottom banners |
--duration-fast | Dismiss button transition speed |
Alert
A static notification component for contextual feedback messages with semantic variants, dismissible close, collapsible content, and optional animated entrance.
Toast
Stackable notification toasts with 6 positions, semantic variants, action support, progress indicator, and auto-dismiss with pause-on-hover.