Skip to content

FRD-063: Welcome Banner Widget

FieldValue
OwnerDavid Holmes
StatusDraft
Last Updated2026-05-26
Target Releasev2.0.0 (P2)
T-Shirt SizeS
TypeWidget

Document Summary

A dismissable welcome banner widget for first-time or returning users. Displays an icon, headline, body text, and setup CTAs. Includes a first-session detection callback so consumers can control when it appears. Builds on the visual language of the existing SiteAlert and Callout components.


Introduction

Overview

First-session onboarding banners help users orient themselves and take key setup actions. This widget provides a standardized welcome banner with configurable content, action buttons, and dismiss behavior, along with a callback-based mechanism for detecting first sessions.

Goals

  • Display a prominent banner with icon, headline, body, and CTA buttons.
  • Support dismissal with a close button; persist dismissal via consumer callback.
  • Provide a shouldShow callback for first-session detection.
  • Visual consistency with SiteAlert and Callout while being distinct as a welcome surface.
  • Ship Storybook stories for default, multi-CTA, dismissed, and compact states.

Non-Goals

  • Built-in session tracking or cookie management.
  • Multi-step wizard flows (use FeatureSpotlight for sequential onboarding).
  • Analytics tracking (consumer instruments via callbacks).

Scope

In Scope

ItemDescription
WelcomeBanner componentBanner with icon, headline, body, CTAs, and dismiss
First-session callbackshouldShow async callback consumer implements
Dismiss behaviorClose button; calls onDismiss for persistence
CTA buttonsArray of action buttons with labels and callbacks
Storybook storiesDefault, MultiCTA, Dismissed, Compact, CustomIcon

Out of Scope

ItemRationale
Session trackingConsumer owns detection logic
Animated entryFollow-up enhancement; initial version renders immediately
Progress indicatorsUse FeatureSpotlight for step-based onboarding

Users and Pain Points

UserPain Point
Product teamsNo standard first-session banner; teams build ad-hoc solutions
New usersMissing orientation and setup guidance on first visit
Returning usersSeeing welcome content repeatedly when dismissal is not persisted

Definitions

TermDefinition
Welcome bannerA prominent UI surface shown to orient new users
First-session detectionLogic to determine if the current user has not previously seen the banner
CTACall-to-action button directing the user toward a setup or onboarding step

Current State

site-alert.tsx provides full-width dismissable alerts with tone variants. callout.tsx provides inline callout blocks. Neither is designed for onboarding welcome flows with multiple CTAs and session-aware visibility. Products build custom welcome sections that lack consistency.


Proposed Solution

Create a WelcomeBanner widget at src/components/widgets/welcome-banner.tsx that:

  1. Renders a visually prominent card with an icon slot, headline, body text, and an array of CTA buttons.
  2. Includes a dismiss/close button that calls onDismiss.
  3. Accepts a shouldShow callback (or simple show boolean) to control visibility.
  4. Uses design-system primitives (Button, Card) and follows SiteAlert/Callout visual patterns.
  5. Supports a compact variant for sidebar or narrow-layout placement.

Requirements

The banner must be controllable via props, not manage its own visibility state internally, and degrade gracefully if shouldShow rejects.


Functional Requirements

IDRequirementPriority
FR-01Render a banner with icon, headline, and body textMust
FR-02Display an array of CTA buttons with configurable labels and callbacksMust
FR-03Render a dismiss/close buttonMust
FR-04Call onDismiss when dismissedMust
FR-05Accept a show boolean prop controlling visibilityMust
FR-06Support a variant prop with "default" and "compact" optionsShould
FR-07Accept a custom icon via icon prop; default to a waving-hand or sparkle iconShould
FR-08Support a tone prop reusing FeedbackTone for color themingShould
FR-09Animate out on dismiss using design-system motion tokensCould

Non-Functional Requirements

IDRequirement
NFR-01Bundle size under 2 KB gzipped
NFR-02Full light/dark theme support
NFR-03No layout shift on dismiss (height collapses smoothly or element unmounts)

API / Interface Requirements

interface WelcomeBannerAction {
label: string;
onClick: () => void;
variant?: "default" | "primary" | "ghost";
}
interface WelcomeBannerProps {
show: boolean;
headline: string;
body?: string | ReactNode;
actions?: WelcomeBannerAction[];
icon?: ReactNode;
tone?: FeedbackTone; // default "info"
variant?: "default" | "compact";
onDismiss?: () => void;
className?: string;
}

Accessibility Requirements

IDRequirement
A11Y-01Banner uses role="region" with aria-label="Welcome"
A11Y-02Dismiss button has aria-label="Dismiss welcome banner"
A11Y-03CTA buttons are focusable and keyboard-activatable
A11Y-04When dismissed, focus moves to the next logical element
A11Y-05Icon is decorative (aria-hidden="true")

Content and Documentation Requirements

  • Storybook doc page with props, usage patterns, and session-detection guidance.
  • Stories: Default, MultipleCTAs, Compact, CustomIcon, Dismissed.
  • Example code showing shouldShow implementation with localStorage.
  • JSDoc on all exported types.

Dependencies

DependencyTypeNotes
ButtonInternalCTA and dismiss buttons
FeedbackToneInternalTone-based color theming from @/lib/semantic-tones
feedbackIconByToneInternalDefault icon selection

Risks and Tradeoffs

RiskImpactMitigation
Banner dismissed but show prop not updatedBanner flickers on re-renderDocument that consumer must sync show with onDismiss
Too many CTAsVisual overloadRecommend max 2 CTAs in documentation
Compact variant too small for contentText truncationEnforce max body length in compact mode via CSS

Open Questions

  1. Should the banner support an illustration slot (e.g., SVG graphic) in addition to an icon?
  2. Do we need a “Don’t show again” checkbox built in, or is onDismiss sufficient?
  3. Should the compact variant stack vertically or stay horizontal?

Acceptance Criteria

  • Banner renders with headline, body, icon, and CTA buttons.
  • Dismiss button hides the banner and calls onDismiss.
  • show prop controls visibility.
  • Compact variant renders correctly in narrow containers.
  • All Storybook stories render without errors.
  • Passes axe accessibility audit with zero violations.
  • Unit tests cover rendering, dismiss, and CTA click callbacks.

LLM Handoff Instructions

When implementing this FRD:

  1. Create src/components/widgets/welcome-banner.tsx.
  2. Reference site-alert.tsx and callout.tsx for visual patterns and tone styling.
  3. Use FeedbackTone from @/lib/semantic-tones and feedbackIconByTone from @/lib/feedback-icons.
  4. Create src/components/widgets/welcome-banner.stories.tsx with all listed stories.
  5. Create src/components/widgets/welcome-banner.test.tsx.
  6. Use cn() for class merging; no inline styles.
  7. Dismiss button uses the X icon from @/lib/icon-pack.

Decision Log

DateDecisionRationale
2026-05-26Controlled visibility via show prop, not internal stateConsumer owns persistence; avoids hydration mismatches
2026-05-26Build on SiteAlert/Callout visual languageMaintains design consistency; avoids new visual patterns

Document History

DateVersionAuthorChanges
2026-05-260.1David HolmesInitial draft