A structured postal address in one fieldset: country, then province and district pickers for countries with region data (Türkiye's 81 provinces and 973 districts ship built in, loaded on demand), free text everywhere else. Changing a parent clears its children; read-only prints the address the way the country writes it.
Installation
The whole kit as one package — get updates by bumping the version. Add the styles to globals.css: @import "@vamos-ui/react/styles.css";
Usage
import { AddressField } from "@vamos-ui/react";
<AddressField
legend="Billing address"
name="billing" // billing[country], billing[region1]…
defaultValue={{ country: "TR" }}
required={["region1", "region2", "line1"]}
onValueChange={(address) => save(address)}
/>Turkish postal codes start with the plate code; a mismatch with the chosen province shows a hint, not an error.
Neighbourhoods (region3) are too large to bundle — fetch them from your own endpoint and pass them in.
Examples
Several countries
Countries without a data source get free-text State / Province and City fields; US gets a ZIP code label. formatAddress() orders the lines per country.
Summary + edit in a dialog
For record pages: show the formatted line, edit in a Dialog, save on confirm.
Ege Pilates Studio · branch address
Alsancak Mah. 1482 Sk. No: 7 D: 3, 35220 Konak/İzmir
Region pickers alone
RegionSelect works without the fieldset — location filters, branch pickers.
Filtering 14 spa partners by location — Antalya.
Read-only
A semantic <address> block in the country's order: "34846 Maltepe/İstanbul", "San Francisco, CA 94104".
API
AddressField
| Prop | Type | Default |
|---|---|---|
value / defaultValue{ country, region1?, region2?, region3?, line1?, line2?, postalCode? } — regions are official names, not codes. | Address | null | — |
onValueChangeEvery change. A new parent clears its children. | (address: Address) => void | — |
sourcesRegion data per country (provinces(), districts(code), both async). | Record<string, AddressDataSource> | { TR: trAddress } |
countriesCountry list (names via Intl.DisplayNames in the provider locale). | string[] | all |
defaultCountryInitial country when there is no value. | string | TR for tr locales, else the locale region |
fieldsParts to render. | AddressPart[] | all except region3 |
requiredRequired parts (asterisk + native required). | AddressPart[] | — |
errorsPer-part error messages from your validation. | Partial<Record<AddressPart, ReactNode>> | — |
layoutTwo columns from sm, or one. | "grid" | "stack" | "grid" |
nameForm name prefix: billing → billing[country], billing[region1]… | string | — |
legend / hintFieldset legend and helper text. | ReactNode | — |
readOnly · disabled · sizeRead-only renders a formatted <address>. | boolean · boolean · sm | md | lg | — |
labelsBuilt-in strings (address namespace). | Partial<AddressFieldLabels> | — |
RegionSelect
| Prop | Type | Default |
|---|---|---|
sourcee.g. trAddress from @vamos-ui/react/locale-data. | AddressDataSource | — |
levelWhich list to show. | "province" | "district" | — |
provinceParent province name for districts; disabled until set. | string | — |
value / defaultValue / onValueChangeThe region name. | string | — |
placeholderFirst option text. | string | — |
formatAddress
| Prop | Type | Default |
|---|---|---|
formatAddress(address, { locale?, includeCountry? })Lines in the country's convention (TR, US/CA/AU, GB/IE, others). | string[] | — |