# ElvixAddressBook

> Single-frame wizard for billing or shipping addresses with Google Places search, default toggle, and tap-to-edit.

<!-- app/checkout/shipping/page.tsx -->
```tsx
"use client";

import { ElvixAddressBook } from "@elvix.is/sdk/react";

export function CheckoutShippingPane({ userName }: { userName?: string }) {
  return (
    <ElvixAddressBook
      kind="shipping"
      width={360}
      userDisplayName={userName}
      onChange={(addresses) => {
        // Re-read the default for your checkout summary.
        const def = addresses.find((a) => a.isDefault);
        console.log("default shipping address:", def?.id);
      }}
    />
  );
}
```

## Props

| Prop | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `kind` | `"billing" \| "shipping"` | **required** | . | Scopes the address book to one kind. One mount per kind. Fixed for you when you use the `ElvixBillingAddressBook` / `ElvixShippingAddressBook` aliases. |
| `card` | `boolean` | optional | `true` | Render inside the `<ElvixCard>` chrome (brand border + Secured-by-elvix badge). Pass `false` for a bare frame when composing into your own surface. |
| `height` | `number` | optional | `520` | Fixed frame height in pixels. Takes precedence over min/max. |
| `minHeight` | `number` | optional | . | Bottom bound when `height` is unset. |
| `maxHeight` | `number` | optional | . | Top bound when `height` is unset. |
| `width` | `number \| string` | optional | `"100%"` | Frame width. Pass a number for fixed pixels. |
| `userDisplayName` | `string \| null` | optional | . | Powers the recipient "Me" card. Falls back to email or "You". |
| `onChange` | `(addresses: AddressRecord[]) => void` | optional | . | Fires after every successful save or delete with the full list. Use this when you need the rows. |
| `onResult` | `(result: ElvixAddressBookResult) => void` | optional | . | Terminal callback with a count-only success or `{ ok: false, error, message }`. Safe analytics hook, never carries rows. |

> **Note:** Everything happens inside the frame. There is no `redirect` field on the result and the SDK never navigates the host. If your checkout needs to advance after a save, do it from `onChange` or `onResult` in the host wrapper.

> **Warning:** `onResult` never carries the address rows. If you need the actual records (for a summary panel, a server sync, anything), read them from `onChange(addresses)` instead. The split is deliberate: `onResult` is the safe analytics hook, `onChange` is the data hook.

## Kind-fixed aliases

Prefer an explicit name and never want to pass `kind`? Import `ElvixBillingAddressBook` or `ElvixShippingAddressBook` — thin aliases that fix `kind` for you (same pattern as `ElvixSignOutMenuItem` / `ElvixSignOutLink`). Every other prop (`card`, `width`, `height`, `userDisplayName`, `onChange`, `onResult`) is identical.

<!-- app/account/addresses/page.tsx -->
```tsx
"use client";

import {
  ElvixBillingAddressBook,
  ElvixShippingAddressBook,
} from "@elvix.is/sdk/react";

export function AddressesPane() {
  return (
    <div className="grid gap-6 md:grid-cols-2">
      {/* No `kind` prop — the alias fixes it. */}
      <ElvixBillingAddressBook width={400} />
      <ElvixShippingAddressBook width={400} />
    </div>
  );
}
```


## Related

- [ElvixLegalEntities](/docs/components/elvix-legal-entities.md): Single-frame multi-step wizard for legal entities (individual, sole prop, company) with VAT live-validation and tap-to-edit.
- [ElvixRegion](/docs/components/elvix-region.md): Single-frame wizard for the user's regional preferences singleton: country cascade plus tap-to-edit on every derived field.
