Unified UI

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.

🎉 Unified UI v2.4 is now available — check out the new components!
Scheduled maintenance on Sunday, Feb 2 from 2–4 AM UTC.
Your trial expires in 3 days. Upgrade to keep your data.

Installation

Install the component via the CLI in one command.

npx @work-rjkashyap/unified-ui add banner
pnpm dlx @work-rjkashyap/unified-ui add banner
npx @work-rjkashyap/unified-ui add banner
bunx @work-rjkashyap/unified-ui add banner

If 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-ui
pnpm add @work-rjkashyap/unified-ui
yarn add @work-rjkashyap/unified-ui
bun add @work-rjkashyap/unified-ui

Anatomy

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.

Default — neutral announcement or promotion.
Primary — branded announcement or feature highlight.
Info — informational system notice or tip.
Success — confirmation or completed action notice.
Warning — caution or degraded service alert.
Danger — critical error or outage notification.
VariantBackgroundText ColorUse Case
default--foreground--backgroundNeutral promotions, launch notices
primary--primary--primary-foregroundBranded CTAs, new feature highlights
info--info--info-foregroundSystem notices, tips, FYIs
success--success--success-foregroundSuccessful ops, completed migrations
warning--warning--warning-foregroundDegraded services, upcoming changes
danger--danger--danger-foregroundOutages, critical security alerts

Dismissible

Set dismissible to show a close button. The banner animates out on dismiss.

We've updated our privacy policy. Review the changes before April 1st.
Two-factor authentication is not enabled on your account.

With Icon

Use the icon prop to render a leading icon before the message content.

New feature: Export to CSV is now available in your dashboard.
API rate limit at 85% — consider upgrading your plan.

With Action

Pass an action prop to render a button or link in the trailing area (before the dismiss button).

🎉 Unified UI 2.4.0 is here with 15 new components.
Your free trial ends in 2 days.

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>

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

PropTypeDefaultDescription
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.
dismissiblebooleanfalseWhether to show a close button.
onDismiss() => voidCallback fired when the banner is dismissed.
dismissLabelstring"Dismiss"Accessible label for the dismiss button.
iconReactNodeLeading icon slot rendered before the message.
actionReactNodeTrailing action slot rendered before the dismiss button.
visiblebooleanControlled visibility state.
defaultVisiblebooleantrueInitial visibility for uncontrolled mode.
classNamestringAdditional CSS classes on the root element.
childrenReactNodeThe 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 the slideDown preset on mount and reverses on exit.
  • Bottom banner — Slides up from 100% using the slideUp preset on mount and reverses on exit.
  • Inline banner — Uses fadeIn-style opacity transition on mount.
  • DismissAnimatePresence handles the exit animation before the element is removed from the DOM.
  • All animations respect prefers-reduced-motion via useReducedMotion() — 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" or role="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

TokenUsage
--foregroundDefault variant background
--backgroundDefault variant text color
--primaryPrimary variant background
--infoInfo variant background
--successSuccess variant background
--warningWarning variant background
--dangerDanger variant background
--z-bannerZ-index for sticky top/bottom banners
--duration-fastDismiss button transition speed

On this page