B

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"
components/ui/billing-address.tsx
"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 code

Examples

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.

billing-form.tsx
"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.

PropTypeDefault
defaultCountrystring"US"
countrystring
onCountryChange(code: string) => void

BillingAddressInput

Input with correct autocomplete, inputMode, and spellCheck based on field type.

PropTypeDefault
field"name" | "line1" | "line2" | "city" | "postalCode"
namestring
valuestring
defaultValuestring""
onValueChange(value: string) => void
trimOnBlurbooleantrue

BillingAddressCountry

Select with all countries. Syncs with root context.

PropTypeDefault
namestring
onValueChange(value: string) => void
placeholderstring"Select country…"
disabledbooleanfalse

BillingAddressState

Select when states exist for the country, Input otherwise. Resets when country changes.

PropTypeDefault
namestring
valuestring
defaultValuestring""
onValueChange(value: string) => void
placeholderstring"State / Province…"
trimOnBlurbooleantrue
disabledbooleanfalse

On this page