Types
Exported TypeScript types.
Hook types
import type {
UseViraAddressOptions, UseViraAddressReturn, GetSelectPropsOptions,
AddressSelectFlavour, AddressSelectProps,
GetPostalCodeInputPropsOptions, PostalCodeStatus,
} from "@virastack/address"
interface UseViraAddressOptions<P extends string = string> {
source?: AddressSource
defaultValue?: {
provinceCode?: string | number | null
district?: string | null
neighbourhood?: string | null
}
formatLabel?: (name: string, level: AddressLevel) => string
onChange?: (value: AddressValue) => void
form?: AddressForm<P>
names?: AddressFieldNames<P>
shouldValidate?: boolean
}
interface UseViraAddressReturn {
value: AddressValue
provinces: readonly AddressOption[]
districts: readonly AddressOption[]
neighbourhoods: readonly NeighbourhoodOption[]
setProvince: (code: string | number | null) => void
setDistrict: (name: string | null) => void
setNeighbourhood: (name: string | null) => void
setPostalCode: (
code: string | number | null,
) => Promise<PostalCodeStatus | null>
postalCodeStatus: PostalCodeStatus | null
reset: () => void
loading: { neighbourhoods: boolean }
error: Error | null
getProvinceProps: (
options?: GetSelectPropsOptions,
) => Record<string, unknown>
getDistrictProps: (
options?: GetSelectPropsOptions,
) => Record<string, unknown>
getNeighbourhoodProps: (
options?: GetSelectPropsOptions,
) => Record<string, unknown>
getPostalCodeProps: () => Record<string, unknown>
getPostalCodeInputProps: (
options?: GetPostalCodeInputPropsOptions,
) => Record<string, unknown>
}
type PostalCodeStatus = "loading" | "exact" | "partial" | "unknown"
interface GetPostalCodeInputPropsOptions {
disabled?: boolean
placeholder?: string
name?: string
id?: string
}
type AddressSelectFlavour = "native" | "headless" | "shadcn" | "antd"
interface GetSelectPropsOptions {
as?: AddressSelectFlavour // default: "native"
disabled?: boolean
placeholder?: string
name?: string
id?: string
}Form types
P is the set of field paths in your form. Pass useForm<T>() and TypeScript infers it from the form, then checks every name in names.
import type {
AddressForm,
AddressFieldNames,
AddressField,
AddressFormWriteOptions,
} from "@virastack/address"
interface AddressForm<P extends string = string> {
setValue(
name: P,
value: string,
options?: AddressFormWriteOptions,
): void
getValues?(name: P): unknown
subscribe?(options: {
name?: readonly P[]
formState: { values: true }
callback: () => void
}): () => void
}
type AddressField =
| "province"
| "district"
| "neighbourhood"
| "postalCode"
| "provinceCode"
type AddressFieldNames<P extends string = string> =
Partial<Record<AddressField, P>>
interface AddressFormWriteOptions {
shouldDirty?: boolean
shouldTouch?: boolean
shouldValidate?: boolean
}Value types
import type {
AddressValue, AddressOption, NeighbourhoodOption, AddressProvince,
AddressNeighbourhood, AddressSource, AddressLevel,
AddressLineInput, FormatAddressOptions,
} from "@virastack/address"
interface AddressValue {
provinceCode: string | null
province: string | null
district: string | null
neighbourhood: string | null
postalCode: string | null
postalCodes: readonly string[]
}
interface AddressOption { value: string; label: string }
interface NeighbourhoodOption extends AddressOption {
postalCode: string
postalCodes: readonly string[]
}
interface AddressSource {
provinces: readonly AddressProvince[]
neighbourhoods(
provinceCode: number,
): Promise<ReadonlyMap<string, readonly AddressNeighbourhood[]>>
}
type AddressLevel = "province" | "district" | "neighbourhood"
interface AddressLineInput {
province?: string | null
district?: string | null
neighbourhood?: string | null
postalCode?: string | null
}
interface FormatAddressOptions {
postalCode?: boolean // default: false
separator?: string // default: "/"
}/server
import type {
AddressInput,
AddressIssue,
AddressResult,
PostalCodeResult,
} from "@virastack/address/server"
interface AddressInput {
provinceCode?: string | number | null
province?: string | null
district?: string | null
neighbourhood?: string | null
postalCode?: string | number | null
}
type AddressIssue =
| { level: "province"; reason: "missing" | "unknown" }
| { level: "district"; reason: "missing" | "unknown" }
| { level: "neighbourhood"; reason: "missing" | "unknown" }
| { level: "postalCode"; reason: "missing" | "unknown" | "mismatch" }
interface AddressResult {
ok: boolean
value: AddressValue
issues: readonly AddressIssue[]
}
interface PostalCodeResult extends AddressResult {
neighbourhoods: readonly string[]
}/data
import type {
Province,
Neighbourhood,
Source,
Loader,
PostalCodeMatch,
} from "@virastack/address/data"
interface Province {
code: number
name: string
districts: readonly string[]
}
interface Neighbourhood {
name: string
postalCode: string
postalCodes: readonly string[]
}
interface Source {
source: string
date: string
provinces: number
districts: number
neighbourhoods: number
}
type Loader = (provinceCode: number) => Promise<string>
interface PostalCodeMatch {
postalCode: string
province: Province
district: string
neighbourhoods: readonly Neighbourhood[]
}