React address autocomplete component for Australian address search, powered by Addressr.
Part of the addressr-ui monorepo.
npm install @mountainpass/addressr-reactPeer dependencies: react >= 18, react-dom >= 18.
import { AddressAutocomplete } from '@mountainpass/addressr-react';
import '@mountainpass/addressr-react/style.css';
function MyForm() {
return (
<AddressAutocomplete
apiUrl="https://api.addressr.io/"
onSelect={(address) => {
console.log(address.sla); // "1 GEORGE ST, SYDNEY NSW 2000"
console.log(address.structured); // { street, locality, state, postcode, ... }
console.log(address.geocoding); // { latitude, longitude, ... }
}}
/>
);
}| Prop | Type | Default | Description |
|---|---|---|---|
apiKey |
string |
-- | RapidAPI key. Omit for direct API access. |
onSelect |
(address: AddressDetail) => void |
required | Called when an address is selected |
label |
string |
"Search Australian addresses" |
Accessible label text |
placeholder |
string |
"Start typing an address..." |
Input placeholder |
className |
string |
-- | Additional CSS class for the wrapper |
debounceMs |
number |
300 |
Debounce delay in milliseconds |
name |
string |
"address" |
Input name attribute for form submission |
required |
boolean |
-- | Sets aria-required on the input |
apiUrl |
string |
"https://addressr.p.rapidapi.com/" |
API root URL |
apiHost |
string |
"addressr.p.rapidapi.com" |
RapidAPI host header |
renderLoading |
() => ReactNode |
-- | Custom loading state renderer |
renderNoResults |
() => ReactNode |
-- | Custom no-results renderer |
renderError |
(error: Error) => ReactNode |
-- | Custom error renderer |
renderItem |
(item, highlighted, segments) => ReactNode |
-- | Custom result item renderer |
Override any rendering zone while keeping built-in search logic and keyboard navigation:
<AddressAutocomplete
apiUrl="https://api.addressr.io/"
onSelect={handleSelect}
renderLoading={() => <li>Loading addresses...</li>}
renderNoResults={() => <li>No matches found</li>}
renderError={(err) => <div role="alert">Error: {err.message}</div>}
renderItem={(item, highlighted, segments) => (
<span>{segments.map((s, i) => s.highlighted ? <mark key={i}>{s.text}</mark> : s.text)}</span>
)}
/>When you provide a custom renderer, you are responsible for accessibility in that zone -- use appropriate roles and contrast ratios.
Build your own UI while keeping the search logic, debounce, pagination, and abort handling:
import { useAddressSearch } from '@mountainpass/addressr-react';
function MyCustomAutocomplete() {
const {
query, setQuery,
results, isLoading,
hasMore, loadMore, isLoadingMore,
selectedAddress, selectAddress,
error, clear,
} = useAddressSearch({ apiUrl: 'https://api.addressr.io/' });
return (
<div>
<input value={query} onChange={(e) => setQuery(e.target.value)} />
<ul>
{results.map((r) => (
<li key={r.pid} onClick={() => selectAddress(r.pid)}>{r.sla}</li>
))}
{hasMore && <li onClick={loadMore}>Load more...</li>}
</ul>
</div>
);
}| Property | Type | Description |
|---|---|---|
query |
string |
Current input value |
setQuery |
(q: string) => void |
Update query (triggers debounced search) |
results |
AddressSearchResult[] |
Search results (accumulated across pages) |
isLoading |
boolean |
Initial search in progress |
isLoadingMore |
boolean |
Pagination fetch in progress |
hasMore |
boolean |
More pages available |
loadMore |
() => Promise<void> |
Load next page of results |
error |
Error | null |
Latest error |
selectedAddress |
AddressDetail | null |
Selected address detail |
selectAddress |
(pid: string) => Promise<void> |
Fetch full address detail |
clear |
() => void |
Reset all state |
All visual styles use CSS custom properties. Override on any ancestor element:
.my-form {
--addressr-font-family: 'Inter', sans-serif;
--addressr-border-color: #ccc;
--addressr-focus-color: #0066cc;
--addressr-highlight-bg: #e0f0ff;
--addressr-error-color: #c62828;
}| Token | Default | Description |
|---|---|---|
--addressr-font-family |
system-ui, -apple-system, sans-serif |
Font stack |
--addressr-padding-x |
0.75rem |
Horizontal padding |
--addressr-padding-y |
0.625rem |
Vertical padding |
--addressr-text-color |
inherit |
Text color |
--addressr-border-color |
#767676 |
Input and dropdown border |
--addressr-border-radius |
0.25rem |
Corner radius |
--addressr-focus-color |
#005fcc |
Focus ring and border |
--addressr-z-index |
1000 |
Dropdown stacking order |
--addressr-bg |
#fff |
Dropdown background |
--addressr-shadow |
0 4px 6px rgba(0,0,0,0.1) |
Dropdown shadow |
--addressr-highlight-bg |
#e8f0fe |
Active item background |
--addressr-mark-weight |
700 |
Search match font weight |
--addressr-mark-color |
inherit |
Search match text color |
--addressr-muted-color |
#555 |
Status and empty text |
--addressr-error-color |
#d32f2f |
Error message text |
--addressr-skeleton-from |
#e0e0e0 |
Loading skeleton base |
--addressr-skeleton-to |
#f0f0f0 |
Loading skeleton shimmer |
The loading state shows animated skeleton lines instead of text. The animation respects prefers-reduced-motion: reduce.
Built with downshift for WAI-ARIA combobox pattern compliance:
- Full keyboard navigation (Arrow keys, Enter, Escape)
- Screen reader announcements for results count and loading state
- Visible focus indicators (3:1 contrast)
- Touch targets >= 44px
- Accessible label always present
- Infinite scroll with loading indicator
This package re-exports everything from @mountainpass/addressr-core for convenience -- createAddressrClient, parseHighlight, and all types.
Apache-2.0