Banner 1
shadcnstore/banner-1FreeBlock
A dismissible announcement bar that remembers the choice
Install it
npx shadcn@latest add https://shadcnstore.com/r/banner-1.jsonSource
1'use client'23import { useEffect, useState } from 'react'4import { useReducedMotion } from 'motion/react'5import { ArrowRight, X } from 'lucide-react'6import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'7import { Badge } from '@/components/ui/badge'8import { Button } from '@/components/ui/button'9import { announcement, announcementAvatars } from "@/components/data/banner-1-data"1011/**12 * 'bar' — full-width strip above the header (the default).13 * 'pill' — floating rounded card pinned to the bottom of the viewport, with an avatar stack.14 * Both shapes share the same dismissal persistence and the same data file.15 */16const shape: 'bar' | 'pill' = 'bar'1718const storageKey = `banner-dismissed:${announcement.id}`1920type Visibility = 'pending' | 'visible' | 'closing' | 'closed'2122export function Banner1() {23 /**24 * Starting in `pending` means the server and the first client render agree on "nothing",25 * so a previously dismissed banner never flashes in before the effect can hide it.26 */27 const [visibility, setVisibility] = useState<Visibility>('pending')28 const reduceMotion = useReducedMotion()2930 useEffect(() => {31 let dismissed = false32 try {33 dismissed = window.localStorage.getItem(storageKey) === 'true'34 } catch {35 // Private-mode browsers throw on localStorage access; showing the banner is the safe default.36 }3738 setVisibility(dismissed ? 'closed' : 'visible')39 }, [])4041 useEffect(() => {42 if (visibility !== 'closing') {43 return44 }4546 const timer = window.setTimeout(() => setVisibility('closed'), 200)47 return () => window.clearTimeout(timer)48 }, [visibility])4950 const dismiss = () => {51 try {52 window.localStorage.setItem(storageKey, 'true')53 } catch {54 // Ignore — dismissal just won't survive a reload.55 }5657 setVisibility(reduceMotion ? 'closed' : 'closing')58 }5960 if (visibility === 'pending' || visibility === 'closed') {61 return null62 }6364 const closing = visibility === 'closing'6566 if (shape === 'pill') {67 return (68 <div69 className={`fixed inset-x-4 bottom-4 z-50 transition-all duration-200 ease-out motion-reduce:transition-none sm:inset-x-auto sm:left-1/2 sm:-translate-x-1/2 ${70 closing ? 'translate-y-2 opacity-0' : 'opacity-100'71 }`}72 >73 <div className='bg-background/95 border-border flex items-center gap-3 rounded-full border py-2 pr-2 pl-3 shadow-lg backdrop-blur sm:pl-4'>74// … truncated
What it pulls in
npm packages
Other registry items
Files it writes
More from ShadcnStore
All 228 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| About 1about-1 | ShadcnStore | Blocks | Free | 1 dep · 3 files | |
| About 2about-2 | ShadcnStore | Blocks | Paid | 2 deps · 3 files | |
| AI Chat 1ai-chat-1 | ShadcnStore | Blocks | Free | 2 deps · 4 files | |
| AI Chat 2ai-chat-2 | ShadcnStore | Blocks | Paid | 1 dep · 4 files | |
| AI Prompt 1ai-prompt-1 | ShadcnStore | Blocks | Paid | 1 dep · 3 files | |
| App Dashboard 1app-1 | ShadcnStore | Blocks | Free | 1 dep · 4 files | |
| Task Management 2app-2 | ShadcnStore | Blocks | Paid | 2 deps · 4 files | |
| Foundational Application Shellapp-shell-1 | ShadcnStore | Blocks | Free | 1 dep · 4 files |
