# Wallet home screen

> A banking or wallet home: greeting, the balance of the centered card with hide and show, a swipeable card carousel, quick actions, this month's spending as a scrubbable sparkline and recent transactions, all inside pull to refresh. Swiping to another card rolls the balance, morphs the sparkline and swaps the list.

- Type: Component (screens)
- Access: Pro
- Page: https://goodui.dev/native/components/wallet-home-screen
- Markdown: https://goodui.dev/native/components/wallet-home-screen.md
- Registry item: https://goodui.dev/native/r/wallet-home-screen.json
- Dependencies: react-native-svg
- Keywords: react native wallet screen, banking app home, fintech dashboard expo, card carousel balance, spending chart, recent transactions list, hide balance, pull to refresh balance

## When to use

- The home tab of a bank, wallet, card or budgeting app with one or more cards or accounts.
- Any money app where the balance, a quick send and the latest payments are the first things people look for.

## When not to use

- A full transaction history with search and filters: open your own list from onSeeAllTransactions; this screen shows a short recent list.
- Investment portfolios with holdings and charts per asset: compose sparkline and list-row yourself.
- One transaction's details: use transaction-detail-screen.

## Installation

With the shadcn CLI (needs a components.json in the Expo app), then `npx expo install --fix` so native dependencies match your Expo SDK. The foundation comes along the first time.

```bash
npx shadcn@latest add @goodui-native-pro/wallet-home-screen
npx expo install --fix
```

Pro: add `"@goodui-native-pro": { "url": "https://goodui.dev/native/r/pro/{name}.json", "headers": { "Authorization": "Bearer ${GOODUI_LICENSE_KEY}" } }` to the `registries` of components.json and put your license key in .env.local.

The component lands in `components/goodui-native/wallet-home-screen/` and imports the foundation from `components/goodui-native/foundation/` with relative paths; it also installs avatar, button, carousel, empty-state, icon-button, list-row, pull-to-refresh, rolling-number, sparkline.

### Setup

- Wrap the app in GestureHandlerRootView and ThemeProvider.

## Usage

```tsx
// app/(tabs)/index.tsx
import { Stack, router } from "expo-router";
import { WalletHomeScreen } from "@/components/goodui-native/wallet-home-screen/wallet-home-screen";
import { useAccounts } from "@/lib/bank";

export default function HomeRoute() {
  const { user, cards, transactions, refetch, unread } = useAccounts(); // your data source
  return (
    <>
      <Stack.Screen options={{ headerShown: false }} />
      <WalletHomeScreen
        userName={user.firstName}
        avatar={user.photoUrl}
        cards={cards} // [{ id, name, last4, balance, currency: "EUR", spending: [daily totals] }]
        transactions={transactions} // newest first, amount negative for spending, cardId to filter
        onRefresh={refetch} // return the promise; new balances roll in when it resolves
        onQuickAction={(action, card) => router.push(`/${action}?card=${card.id}`)}
        onTransactionPress={(t) => router.push(`/transaction/${t.id}`)}
        onSeeAllTransactions={() => router.push("/transactions")}
        onNotificationsPress={() => router.push("/notifications")}
        notificationCount={unread}
        onProfilePress={() => router.push("/profile")}
      />
    </>
  );
}
```

## Examples

### On its own, with sample cards and transactions

```tsx
<WalletHomeScreen />
```

### Amounts hidden by default, remembered by the app

```tsx
<WalletHomeScreen cards={cards} transactions={transactions} balanceHidden={hidden} onBalanceHiddenChange={setHidden} onRefresh={refetch} />
```

## API reference

### WalletHomeScreen

`import { WalletHomeScreen } from "@/components/goodui-native/wallet-home-screen/wallet-home-screen";`

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `userName` | `string` | `"Maya"` | First name for the greeting. |
| `avatar` | `ImageSourcePropType \| string` | – | Profile photo. Without it the avatar shows initials. |
| `greeting` | `string` | – | Greeting above the name. Defaults to good morning, afternoon or evening by the device clock. |
| `cards` | `WalletCard[]` | `defaultCards` | Cards and accounts, one carousel card each. The balance, sparkline and transactions follow the centered card. |
| `transactions` | `WalletTransaction[]` | `defaultTransactions` | Recent transactions, newest first. Filtered to the centered card by `cardId`. |
| `cardIndex` | `number` | – | Index of the centered card (controlled). |
| `onCardIndexChange` | `(index: number, card: WalletCard) => void` | – | Called when a different card settles in the center. |
| `balanceHidden` | `boolean` | – | Hide amounts (controlled). |
| `defaultBalanceHidden` | `boolean` | `false` | Start with amounts hidden when uncontrolled. |
| `onBalanceHiddenChange` | `(hidden: boolean) => void` | – | Called when the eye button hides or shows amounts. |
| `onRefresh` | `() => unknown` | `() => new Promise((resolve) => setTimeout(resolve, 900))` | Pull to refresh. Return a promise; pass new `cards` and `transactions` when it resolves and the balance rolls to them. |
| `refreshing` | `boolean` | – | Show the refreshing state from outside, for example on first load. |
| `onQuickAction` | `(action: WalletQuickAction, card: WalletCard) => unknown` | – | Send, request, top up or more, with the centered card. Return a promise to show a spinner on the button. |
| `onCardPress` | `(card: WalletCard) => void` | – | Tap on the centered card. |
| `onTransactionPress` | `(transaction: WalletTransaction) => void` | – | Tap on a transaction row, for example to open its detail screen. |
| `onSeeAllTransactions` | `() => void` | – | "See all" next to the transactions heading. Hidden when omitted. |
| `onNotificationsPress` | `() => void` | – | The bell in the header. Hidden when omitted. |
| `notificationCount` | `number` | – | Count on the bell. |
| `onProfilePress` | `() => void` | – | Tap on the avatar. |
| `locale` | `string` | – | BCP 47 locale for amounts and dates. Defaults to the device locale. |
| `transactionLimit` | `number` | `6` | How many transactions to list. Default 6. |
| `style` | `StyleProp<ViewStyle>` | – | Style for the outer container. |
| `testID` | `string` | – | Identifier for end-to-end tests. |

## Accessibility

- The greeting name is a header; the avatar and bell are buttons with labels ('Notifications, 3 new').
- The eye is a button labelled 'Hide amounts' or 'Show amounts'; toggling it announces 'Amounts hidden' or 'Amounts shown'. Hidden amounts are read as 'Balance hidden'.
- The card carousel is one adjustable element: swipe up or down (arrow keys on the web) to change card; its value reads 'Card 2 of 3, Savings card ending 0019'.
- Quick actions are icon buttons named by their visible label; the label under each is hidden from screen readers so it is not read twice.
- Each transaction row is read as 'Merchant, signed amount, category, date or status'. The balance and totals are read as plain numbers (rolling-number).
- Pull to refresh has a Refresh button for screen readers on every platform.

## Motion

- Swiping the card carousel rolls the balance and the month total to the new card's values, morphs the sparkline into the new card's spending and swaps the transaction list.
- Pull to refresh: the drop stretches, snaps round past the threshold, spins while onRefresh runs, and when new cards arrive the balance digits roll in the direction of the change.
- Scrubbing the sparkline rolls the total to that day's amount and the label switches to 'Spent on <date>'.
- Reduced motion: digits change in place, the carousel settles on a short timing curve instead of a spring, the sparkline changes at once without drawing or morphing (each component's own reduced-motion branch).

## Haptics

- select when a swipe settles on another card (Carousel)
- tap when the pull passes the threshold (PullToRefresh)
- select on the eye toggle, tap on quick actions and the bell (IconButton)
- select for each day the sparkline scrub crosses (Sparkline)

## Performance

- Gestures, the roll and the sparkline animate on the UI thread; React renders on card changes, scrubbed day changes, refreshes and the eye toggle.
- The transaction list is limited by transactionLimit (6) and rendered in a ScrollView; page the full history on its own screen.

## Notes for AI

- Pass cards with balance as a number and currency as an ISO code; amounts are formatted with Intl in the given locale. spending holds daily totals oldest first and drives the sparkline and 'Spent this month'.
- Transactions: amount is signed (negative for spending), date is an ISO string or Date, cardId ties a row to a card; rows without cardId show under every card.
- Return the promise from onRefresh and update cards and transactions when it resolves; without onRefresh the pull waits 0.9 s and resolves, which is only useful in a preview.
- Header buttons appear only for the callbacks you pass: onNotificationsPress (bell), onSeeAllTransactions (See all). onProfilePress makes the avatar a button.
- Render it full-bleed with the navigator header hidden (headerShown: false); it handles the safe areas itself. Do not nest it inside another ScrollView: it is the screen's scroll view.

## Related

- [Transaction detail screen](https://goodui.dev/native/components/transaction-detail-screen.md): One payment in full: merchant header, the signed amount, a status badge and a category chip that recategorizes, the details as grouped rows, split and receipt actions and Report a problem. The split sheet rolls each person's share as you change the head count.
- [Carousel](https://goodui.dev/native/components/carousel.md): A snapping card carousel that follows the finger 1:1, shrinks and dims the neighbours, stretches its pagination pill with the drag, and turns that pill into a timer when it autoplays.
- [Rolling number](https://goodui.dev/native/components/rolling-number.md): A number whose digits roll in the direction of change, with digits that open and close in place and currency signs that glide instead of jumping.
- [Sparkline](https://goodui.dev/native/components/sparkline.md): A small line or area chart that draws itself in and morphs to new data; press and drag to scrub, and a dot rides the curve while the line beyond your finger dims and every point ticks.
- [Pull to refresh](https://goodui.dev/native/components/pull-to-refresh.md): A scroll view whose refresh indicator is a drop that stretches as you pull, snaps round with a bounce and a haptic past the threshold, spins while onRefresh runs and ends on a check or an error.
- [List row](https://goodui.dev/native/components/list-row.md): Settings and navigation cells with a token-colored icon tile, title, subtitle and a trailing value, switch, badge, check or chevron, grouped in inset sections with headers and footers. On touch down the highlight floods in, the tile sinks and the chevron leans forward; on release the highlight lingers and fades.

## Guidance for AI tools

Wallet home screen: A banking or wallet home: greeting, the balance of the centered card with hide and show, a swipeable card carousel, quick actions, this month's spending as a scrubbable sparkline and recent transactions, all inside pull to refresh. Swiping to another card rolls the balance, morphs the sparkline and swaps the list. Use only the documented props. Keep accessibility, reduced motion and both color schemes intact when adapting it.

Full library index: https://goodui.dev/native/llms.txt
