Billing Address
Composable address form with correct autocomplete attributes. Country and state selects are automatically linked.
Installation
npx shadcn@latest add "https://billui.com/r/billing-address.json""use client";
import * as React from "react";
import { Input } from "@/components/ui/input";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { cn } from "@/lib/utils";
import { COUNTRIES, getStatesForCountry, type IState } from "./billing-address-data";
// ... component codeExamples
Minimal Form
A compact version with only essential fields.
With Server Actions
The name prop enables native form submission—works with useActionState and Server Actions.
"use client";
import { useActionState } from "react";
function BillingForm() {
const [state, formAction] = useActionState(updateBilling, null);
return (
<form action={formAction}>
<BillingAddress>
<BillingAddressCountry name="country" />
<BillingAddressInput field="line1" name="line1" placeholder="Address" />
<BillingAddressInput field="city" name="city" placeholder="City" />
<BillingAddressState name="state" />
<BillingAddressInput field="postalCode" name="postal" placeholder="ZIP" />
</BillingAddress>
<button type="submit">Save</button>
</form>
);
}Controlled State
For real-time validation or conditional UI.
function ControlledBillingForm() {
const [country, setCountry] = useState("US");
const [state, setState] = useState("");
const showTaxMessage = state === "CA";
return (
<BillingAddress country={country} onCountryChange={setCountry}>
<BillingAddressCountry />
<BillingAddressState value={state} onValueChange={setState} />
{showTaxMessage && <p>California sales tax applies</p>}
</BillingAddress>
);
}API Reference
BillingAddress
Root component that provides country/state synchronization context.
| Prop | Type | Default |
|---|---|---|
defaultCountry | string | "US" |
country | string | — |
onCountryChange | (code: string) => void | — |
BillingAddressInput
Input with correct autocomplete, inputMode, and spellCheck based on field type.
| Prop | Type | Default |
|---|---|---|
field | "name" | "line1" | "line2" | "city" | "postalCode" | — |
name | string | — |
value | string | — |
defaultValue | string | "" |
onValueChange | (value: string) => void | — |
trimOnBlur | boolean | true |
BillingAddressCountry
Select with all countries. Syncs with root context.
| Prop | Type | Default |
|---|---|---|
name | string | — |
onValueChange | (value: string) => void | — |
placeholder | string | "Select country…" |
disabled | boolean | false |
BillingAddressState
Select when states exist for the country, Input otherwise. Resets when country changes.
| Prop | Type | Default |
|---|---|---|
name | string | — |
value | string | — |
defaultValue | string | "" |
onValueChange | (value: string) => void | — |
placeholder | string | "State / Province…" |
trimOnBlur | boolean | true |
disabled | boolean | false |