Wallet Card
beui/wallet-cardFreeBlock
Wallet overview card with an account switcher and search that morph open from their triggers, a cascading balance with a live change pill and privacy toggle, copy-address, and Send / Deposit / Swap / Buy actions.
Install it
npx shadcn@latest add https://beui.dev/r/wallet-card.jsonSource
1"use client";2// beui.dev/components/blocks/wallet-card34import { Bell, Eye, EyeOff } from "lucide-react";5import { useState } from "react";6import { ActionSwapText } from "@/components/motion/action-swap";7import { Button } from "@/components/motion/button";8import { cn } from "@/lib/utils";9import { AccountSwitcher } from "./account-switcher";10import { WalletActions } from "./actions";11import { BalanceDelta } from "./balance-delta";12import { SearchBar } from "./search-bar";13import type { WalletCardProps } from "./types";1415export type { WalletAccount, WalletCardProps } from "./types";1617/**18 * Composed wallet overview card: an account switcher whose trigger morphs open19 * into a full-width panel, a search icon that morphs into a search bar, a20 * rolling balance with a transient change indicator, and Send / Deposit21 * actions. Actions and search are plain callbacks — the resulting flow is left22 * to the consumer.23 */24export function WalletCard({25 accounts,26 accountId,27 defaultAccountId,28 onAccountChange,29 balance,30 balancePrefix = "$",31 defaultChange,32 defaultBalanceHidden = false,33 onSend,34 onDeposit,35 onSwap,36 onBuy,37 searchPlaceholder,38 searchRecent,39 onSearchChange,40 onSearchSubmit,41 hasNotifications = false,42 onNotifications,43 className,44}: WalletCardProps) {45 const accountControlled = accountId !== undefined;46 const [internalAccountId, setInternalAccountId] = useState(47 defaultAccountId ?? accounts[0]?.id,48 );49 const [balanceHidden, setBalanceHidden] = useState(defaultBalanceHidden);5051 const shownBalance = `${balancePrefix}${balance.toLocaleString(undefined, {52 minimumFractionDigits: 2,53 maximumFractionDigits: 2,54 })}`;55 const maskedBalance = "*".repeat(7);56 const activeAccountId = accountControlled ? accountId : internalAccountId;57 const activeAccount =58 accounts.find((a) => a.id === activeAccountId) ?? accounts[0];5960 const handleAccountChange = (id: string) => {61 if (!accountControlled) setInternalAccountId(id);62 onAccountChange?.(id);63 };6465 return (66 <div67 className={cn(68 "relative w-full max-w-xs overflow-hidden rounded-4xl border border-border p-6",69 className,70 )}71 >72 {/* relative anchor so the switcher + search panels span the whole row */}73 <div className="relative flex items-center justify-between gap-2">74 <AccountSwitcher75 accounts={accounts}76 activeAccount={activeAccount}77 onSelect={handleAccountChange}78 />7980// … truncated
What it pulls in
npm packages
Files it writes
More from beui
All 104 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| File Upload Attachment Uploadattachment-upload | beui | Blocks | Free | 4 deps · 5 files | |
| Availability Scheduleravailability-scheduler | beui | Blocks | Free | 4 deps · 15 files | |
| Bloom Menubloom-menu | beui | Blocks | Free | 4 deps · 3 files | |
| Command Palettecommand-palette | beui | Blocks | Free | 4 deps · 3 files | |
| Dynamic Islanddynamic-island | beui | Blocks | Free | 3 deps · 3 files | |
| Expandable Action Barexpandable-action-bar | beui | Blocks | Free | 3 deps · 2 files | |
| Expandable Tabsexpandable-tabs | beui | Blocks | Free | 3 deps · 3 files | |
| Feedback Widgetfeedback-widget | beui | Blocks | Free | 4 deps · 9 files |
