@mountainpass/addressr-react 0.2.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +58 -76
  2. package/package.json +13 -36
package/README.md CHANGED
@@ -1,22 +1,18 @@
1
1
  # @mountainpass/addressr-react
2
2
 
3
- React address autocomplete component for Australian address search powered by [Addressr](https://addressr.io).
3
+ React address autocomplete component for Australian address search, powered by [Addressr](https://addressr.io).
4
4
 
5
- Search, validate, and retrieve detailed Australian address data from the Geocoded National Address File (G-NAF).
5
+ Part of the [addressr-ui](https://github.com/mountain-pass/addressr-ui) monorepo.
6
6
 
7
- ## Quick Start
8
-
9
- ### 1. Get an API Key
10
-
11
- Sign up at [RapidAPI](https://rapidapi.com/addressr-addressr-default/api/addressr) to get your API key.
12
-
13
- ### 2. Install
7
+ ## Install
14
8
 
15
9
  ```bash
16
10
  npm install @mountainpass/addressr-react
17
11
  ```
18
12
 
19
- ### 3. Use the Component
13
+ Peer dependencies: `react` >= 18, `react-dom` >= 18.
14
+
15
+ ## Drop-in component
20
16
 
21
17
  ```tsx
22
18
  import { AddressAutocomplete } from '@mountainpass/addressr-react';
@@ -25,104 +21,90 @@ import '@mountainpass/addressr-react/style.css';
25
21
  function MyForm() {
26
22
  return (
27
23
  <AddressAutocomplete
28
- apiKey="your-rapidapi-key"
24
+ apiUrl="https://api.addressr.io/"
29
25
  onSelect={(address) => {
30
- console.log(address.sla); // "1 GEORGE ST, SYDNEY NSW 2000"
31
- console.log(address.structured); // { street, locality, state, postcode, ... }
32
- console.log(address.geocoding); // { latitude, longitude, ... }
26
+ console.log(address.sla); // "1 GEORGE ST, SYDNEY NSW 2000"
27
+ console.log(address.structured); // { street, locality, state, postcode, ... }
28
+ console.log(address.geocoding); // { latitude, longitude, ... }
33
29
  }}
34
30
  />
35
31
  );
36
32
  }
37
33
  ```
38
34
 
39
- ### Or Use the Headless Hook
35
+ ### Props
36
+
37
+ | Prop | Type | Default | Description |
38
+ |------|------|---------|-------------|
39
+ | `apiKey` | `string` | -- | RapidAPI key. Omit for direct API access. |
40
+ | `onSelect` | `(address: AddressDetail) => void` | **required** | Called when an address is selected |
41
+ | `label` | `string` | `"Search Australian addresses"` | Accessible label text |
42
+ | `placeholder` | `string` | `"Start typing an address..."` | Input placeholder |
43
+ | `className` | `string` | -- | Additional CSS class for the wrapper |
44
+ | `debounceMs` | `number` | `300` | Debounce delay in milliseconds |
45
+ | `apiUrl` | `string` | `"https://addressr.p.rapidapi.com/"` | API root URL |
46
+ | `apiHost` | `string` | `"addressr.p.rapidapi.com"` | RapidAPI host header |
47
+
48
+ ## Headless hook
49
+
50
+ Build your own UI while keeping the search logic, debounce, pagination, and abort handling:
40
51
 
41
52
  ```tsx
42
53
  import { useAddressSearch } from '@mountainpass/addressr-react';
43
54
 
44
55
  function MyCustomAutocomplete() {
45
56
  const {
46
- query,
47
- setQuery,
48
- results,
49
- isLoading,
50
- selectedAddress,
51
- selectAddress,
52
- clear,
53
- } = useAddressSearch({ apiKey: 'your-rapidapi-key' });
57
+ query, setQuery,
58
+ results, isLoading,
59
+ hasMore, loadMore, isLoadingMore,
60
+ selectedAddress, selectAddress,
61
+ error, clear,
62
+ } = useAddressSearch({ apiUrl: 'https://api.addressr.io/' });
54
63
 
55
64
  return (
56
65
  <div>
57
- <input
58
- value={query}
59
- onChange={(e) => setQuery(e.target.value)}
60
- placeholder="Search addresses..."
61
- />
62
- {isLoading && <p>Searching...</p>}
66
+ <input value={query} onChange={(e) => setQuery(e.target.value)} />
63
67
  <ul>
64
- {results.map((result) => (
65
- <li key={result.pid} onClick={() => selectAddress(result.pid)}>
66
- {result.sla}
67
- </li>
68
+ {results.map((r) => (
69
+ <li key={r.pid} onClick={() => selectAddress(r.pid)}>{r.sla}</li>
68
70
  ))}
71
+ {hasMore && <li onClick={loadMore}>Load more...</li>}
69
72
  </ul>
70
- {selectedAddress && (
71
- <pre>{JSON.stringify(selectedAddress, null, 2)}</pre>
72
- )}
73
73
  </div>
74
74
  );
75
75
  }
76
76
  ```
77
77
 
78
- ## API
79
-
80
- ### `<AddressAutocomplete />`
81
-
82
- | Prop | Type | Default | Description |
83
- |------|------|---------|-------------|
84
- | `apiKey` | `string` | required | RapidAPI key |
85
- | `onSelect` | `(address: AddressDetail) => void` | required | Called when an address is selected |
86
- | `label` | `string` | `"Search Australian addresses"` | Accessible label |
87
- | `placeholder` | `string` | `"Start typing an address..."` | Input placeholder |
88
- | `className` | `string` | | Additional CSS class for the wrapper |
89
- | `debounceMs` | `number` | `300` | Debounce delay in milliseconds |
90
- | `apiUrl` | `string` | `"https://addressr.p.rapidapi.com/"` | API root URL |
91
-
92
- ### `useAddressSearch(options)`
93
-
94
- Returns `{ query, setQuery, results, isLoading, error, selectedAddress, selectAddress, clear }`.
95
-
96
- | Option | Type | Default | Description |
97
- |--------|------|---------|-------------|
98
- | `apiKey` | `string` | required | RapidAPI key |
99
- | `apiUrl` | `string` | `"https://addressr.p.rapidapi.com/"` | API root URL |
100
- | `debounceMs` | `number` | `300` | Debounce delay |
101
- | `minQueryLength` | `number` | `3` | Minimum characters before searching |
102
-
103
- ### `createAddressrClient(options)`
104
-
105
- Low-level API client for direct use. Returns `{ searchAddresses, getAddressDetail }`.
106
-
107
- ## Architecture
108
-
109
- - **HATEOAS** — the component discovers API endpoints via RFC 8288 Link headers, not hardcoded paths
110
- - **downshift** — WAI-ARIA APG combobox pattern with full keyboard navigation and screen reader support
111
- - **CSS Modules** — scoped styles, override via `className` prop
112
- - **Safe highlights** — search match highlighting rendered via `<mark>` elements, never `dangerouslySetInnerHTML`
78
+ ### Return values
79
+
80
+ | Property | Type | Description |
81
+ |----------|------|-------------|
82
+ | `query` | `string` | Current input value |
83
+ | `setQuery` | `(q: string) => void` | Update query (triggers debounced search) |
84
+ | `results` | `AddressSearchResult[]` | Search results (accumulated across pages) |
85
+ | `isLoading` | `boolean` | Initial search in progress |
86
+ | `isLoadingMore` | `boolean` | Pagination fetch in progress |
87
+ | `hasMore` | `boolean` | More pages available |
88
+ | `loadMore` | `() => Promise<void>` | Load next page of results |
89
+ | `error` | `Error \| null` | Latest error |
90
+ | `selectedAddress` | `AddressDetail \| null` | Selected address detail |
91
+ | `selectAddress` | `(pid: string) => Promise<void>` | Fetch full address detail |
92
+ | `clear` | `() => void` | Reset all state |
113
93
 
114
94
  ## Accessibility
115
95
 
116
- - WCAG AA compliant
117
- - Full keyboard navigation (arrow keys, Enter, Escape)
96
+ Built with [downshift](https://www.downshift-js.com/) for WAI-ARIA combobox pattern compliance:
97
+
98
+ - Full keyboard navigation (Arrow keys, Enter, Escape)
118
99
  - Screen reader announcements for results count and loading state
119
- - Visible focus indicators (3:1 contrast ratio)
100
+ - Visible focus indicators (3:1 contrast)
120
101
  - Touch targets >= 44px
121
102
  - Accessible label always present
103
+ - Infinite scroll with loading indicator
122
104
 
123
- ## Data Source
105
+ ## Re-exports
124
106
 
125
- Address data from the [Geocoded National Address File (G-NAF)](https://data.gov.au/dataset/ds-dga-19432f89-dc3a-4ef3-b943-5326ef1dbecc), Australia's authoritative address database.
107
+ This package re-exports everything from [`@mountainpass/addressr-core`](../core) for convenience -- `createAddressrClient`, `parseHighlight`, and all types.
126
108
 
127
109
  ## License
128
110
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mountainpass/addressr-react",
3
- "version": "0.2.0",
3
+ "version": "0.4.0",
4
4
  "description": "React address autocomplete component for Australian address search via Addressr",
5
5
  "author": {
6
6
  "name": "Mountain Pass",
@@ -13,9 +13,9 @@
13
13
  "types": "./dist/index.d.ts",
14
14
  "exports": {
15
15
  ".": {
16
+ "types": "./dist/index.d.ts",
16
17
  "import": "./dist/index.mjs",
17
- "require": "./dist/index.cjs",
18
- "types": "./dist/index.d.ts"
18
+ "require": "./dist/index.cjs"
19
19
  },
20
20
  "./style.css": "./dist/style.css"
21
21
  },
@@ -28,61 +28,33 @@
28
28
  "engines": {
29
29
  "node": ">=18"
30
30
  },
31
- "scripts": {
32
- "dev": "vite",
33
- "build": "tsc && vite build",
34
- "test": "vitest run",
35
- "test:watch": "vitest",
36
- "lint": "eslint src/",
37
- "pre-commit": "lint-staged",
38
- "push:watch": "bash scripts/push-and-watch.sh",
39
- "release:watch": "bash scripts/release-watch.sh"
40
- },
41
31
  "peerDependencies": {
42
32
  "react": ">=18",
43
33
  "react-dom": ">=18"
44
34
  },
45
35
  "dependencies": {
46
- "@windyroad/fetch-link": "^3.0.5",
47
- "downshift": "^9.0.0"
36
+ "@windyroad/link-header": "^1.0.1",
37
+ "downshift": "^9.0.0",
38
+ "@mountainpass/addressr-core": "0.4.0"
48
39
  },
49
40
  "devDependencies": {
50
- "@changesets/cli": "^2.29.7",
51
- "@eslint/js": "^9.39.4",
52
41
  "@testing-library/jest-dom": "^6.6.3",
53
42
  "@testing-library/react": "^16.3.0",
54
43
  "@testing-library/user-event": "^14.6.1",
55
44
  "@types/react": "^19.2.14",
56
45
  "@types/react-dom": "^19.2.3",
57
46
  "@vitejs/plugin-react": "^4.5.2",
58
- "eslint": "^9.39.4",
59
- "eslint-config-prettier": "^10.1.8",
60
- "eslint-plugin-prettier": "^5.5.5",
61
47
  "eslint-plugin-react-hooks": "^5.2.0",
62
- "globals": "^17.4.0",
63
- "husky": "^9.1.7",
64
48
  "jsdom": "^26.1.0",
65
- "lint-staged": "^16.3.3",
66
- "prettier": "^3.8.1",
67
49
  "react": "^18.3.1",
68
50
  "react-dom": "^18.3.1",
69
- "typescript": "^5.8.3",
70
- "typescript-eslint": "^8.58.0",
71
51
  "vite": "^6.3.5",
72
52
  "vite-plugin-dts": "^4.5.4",
73
53
  "vitest": "^3.2.3"
74
54
  },
75
- "lint-staged": {
76
- "*.{ts,tsx}": "eslint --fix",
77
- "*.{json,css,md}": "prettier --write"
78
- },
79
55
  "publishConfig": {
80
56
  "access": "public"
81
57
  },
82
- "repository": {
83
- "type": "git",
84
- "url": "git+https://github.com/mountain-pass/addressr-react.git"
85
- },
86
58
  "keywords": [
87
59
  "react",
88
60
  "address",
@@ -92,5 +64,10 @@
92
64
  "gnaf",
93
65
  "combobox",
94
66
  "hateoas"
95
- ]
96
- }
67
+ ],
68
+ "scripts": {
69
+ "build": "tsc --noEmit && vite build",
70
+ "test": "vitest run",
71
+ "lint": "eslint -c eslint.config.js src/"
72
+ }
73
+ }