Quota Banner
spectrumui/quota-bannerFreeBlock
A message-quota banner with a live reset countdown.
Install it
npx shadcn@latest add https://ui.spectrumhq.in/r/quota-banner.jsonSource
1'use client';23import { useEffect, useState } from 'react';4import { Zap } from 'lucide-react';5import { cn } from '@/lib/utils';67export type QuotaBannerVariant = 'Banner' | 'Compact';89export interface QuotaBannerProps {10 used: number;11 limit: number;12 resetsInSeconds?: number;13 upgradeLabel?: string;14 onUpgrade?: () => void;15 variant?: QuotaBannerVariant;16 className?: string;17}1819function useCountdown(seconds?: number) {20 const [remaining, setRemaining] = useState(seconds ?? 0);21 useEffect(() => {22 setRemaining(seconds ?? 0);23 if (!seconds) return;24 const t = setInterval(() => setRemaining((value) => Math.max(0, value - 1)), 1000);25 return () => clearInterval(t);26 }, [seconds]);27 const minutes = Math.floor(remaining / 60);28 return `${minutes}:${String(remaining % 60).padStart(2, '0')}`;29}3031export function QuotaBanner({32 used,33 limit,34 resetsInSeconds,35 upgradeLabel = 'Upgrade',36 onUpgrade,37 variant = 'Banner',38 className,39}: QuotaBannerProps) {40 const countdown = useCountdown(resetsInSeconds);41 const ratio = Math.min(1, used / limit);42 const exhausted = used >= limit;4344 if (variant === 'Compact') {45 return (46 <div47 className={cn(48 'flex w-fit items-center gap-2.5 rounded-full border border-black/[0.08] bg-white py-1.5 pl-3 pr-1.5 text-[12px] dark:border-white/[0.09] dark:bg-[#0B0B0D]',49 className,50 )}51 >52 <span className="font-mono tabular-nums text-neutral-600 dark:text-neutral-300">53 {used}/{limit}54 </span>55 <span aria-hidden className="h-1 w-12 overflow-hidden rounded-full bg-black/[0.07] dark:bg-white/[0.09]">56 <span57 className={cn(58 'block h-full rounded-full transition-[width] duration-500 ease-[cubic-bezier(0.23,1,0.32,1)]',59 exhausted ? 'bg-amber-500' : 'bg-neutral-900 dark:bg-neutral-100',60 )}61 style={{ width: `${ratio * 100}%` }}62 />63 </span>64 {resetsInSeconds !== undefined && (65 <span className="font-mono text-[10.5px] tabular-nums text-neutral-400 dark:text-neutral-600">66 {countdown}67 </span>68 )}69 </div>70 );71 }7273 return (74 <div75 role="status"76 className={cn(77 'flex w-full max-w-[480px] items-center gap-3 rounded-xl border py-2.5 pl-3 pr-2',78 exhausted79 ? 'border-amber-500/25 bg-amber-500/[0.06]'80// … truncated
What it pulls in
npm packages
Files it writes
More from spectrumui
All 182 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Agent Planagent-plan | spectrumui | Blocks | Free | 1 dep | |
| Agent Stepsagent-steps | spectrumui | Blocks | Free | 1 dep · 2 files | |
| Approval Cardapproval-card | spectrumui | Blocks | Free | 1 dep | |
| Chat Empty Statechat-empty-state | spectrumui | Blocks | Free | 1 dep · 2 files | |
| Citation Sourcescitation-sources | spectrumui | Blocks | Free | no deps · 2 files | |
| Code Blockcode-block | spectrumui | Blocks | Free | 1 dep | |
| Conversation Listconversation-list | spectrumui | Blocks | Free | 1 dep | |
| Diff Viewdiff-view | spectrumui | Blocks | Free | 1 dep |
