@pro6pp/infer-core 0.0.2-beta.6 → 0.0.2-beta.8
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.
- package/dist/index.cjs +83 -24
- package/dist/index.d.cts +27 -10
- package/dist/index.d.ts +27 -10
- package/dist/index.global.js +84 -25
- package/dist/index.js +84 -25
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var h=Object.defineProperty;var y=Object.getOwnPropertyDescriptor;var v=Object.getOwnPropertyNames;var I=Object.prototype.hasOwnProperty;var w=(a,e,t)=>e in a?h(a,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):a[e]=t;var C=(a,e)=>{for(var t in e)h(a,t,{get:e[t],enumerable:!0})},L=(a,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of v(e))!I.call(a,s)&&s!==t&&h(a,s,{get:()=>e[s],enumerable:!(i=y(e,s))||i.enumerable});return a};var T=a=>L(h({},"__esModule",{value:!0}),a);var l=(a,e,t)=>w(a,typeof e!="symbol"?e+"":e,t);var A={};C(A,{DEFAULT_STYLES:()=>S,INITIAL_STATE:()=>g,InferCore:()=>f});module.exports=T(A);var d={API_URL:"https://api.pro6pp.nl/v2",LIMIT:20,DEBOUNCE_MS:150,MIN_DEBOUNCE_MS:50,MAX_RETRIES:0},x={DIGITS_1_3:/^[0-9]{1,3}$/},g={query:"",stage:null,cities:[],streets:[],suggestions:[],isValid:!1,isError:!1,isLoading:!1,hasMore:!1,selectedSuggestionIndex:-1},f=class{constructor(e){l(this,"country");l(this,"authKey");l(this,"explicitApiUrl");l(this,"baseLimit");l(this,"currentLimit");l(this,"maxRetries");l(this,"fetcher");l(this,"onStateChange");l(this,"onSelect");l(this,"state");l(this,"abortController",null);l(this,"debouncedFetch");l(this,"isSelecting",!1);this.country=e.country,this.authKey=e.authKey,this.explicitApiUrl=e.apiUrl,this.baseLimit=e.limit||d.LIMIT,this.currentLimit=this.baseLimit;let t=e.maxRetries!==void 0?e.maxRetries:d.MAX_RETRIES;this.maxRetries=Math.max(0,Math.min(t,10)),this.fetcher=e.fetcher||((r,o)=>fetch(r,o)),this.onStateChange=e.onStateChange||(()=>{}),this.onSelect=e.onSelect||(()=>{}),this.state={...g};let i=e.debounceMs!==void 0?e.debounceMs:d.DEBOUNCE_MS,s=Math.max(i,d.MIN_DEBOUNCE_MS);this.debouncedFetch=this.debounce(r=>this.executeFetch(r),s)}handleInput(e){if(this.isSelecting){this.isSelecting=!1;return}this.currentLimit=this.baseLimit;let t=this.state.stage==="final"&&e!==this.state.query;this.updateState({query:e,isValid:!1,isLoading:!!e.trim(),selectedSuggestionIndex:-1,hasMore:!1}),t&&this.onSelect(null),this.debouncedFetch(e)}loadMore(){this.state.isLoading||(this.currentLimit+=this.baseLimit,this.updateState({isLoading:!0}),this.executeFetch(this.state.query))}handleKeyDown(e){let t=e.target;if(!t)return;let i=this.state.cities.length+this.state.streets.length+this.state.suggestions.length;if(i>0){if(e.key==="ArrowDown"){e.preventDefault();let r=this.state.selectedSuggestionIndex+1;r>=i&&(r=0),this.updateState({selectedSuggestionIndex:r});return}if(e.key==="ArrowUp"){e.preventDefault();let r=this.state.selectedSuggestionIndex-1;r<0&&(r=i-1),this.updateState({selectedSuggestionIndex:r});return}if(e.key==="Enter"&&this.state.selectedSuggestionIndex>=0){e.preventDefault();let o=[...this.state.cities,...this.state.streets,...this.state.suggestions][this.state.selectedSuggestionIndex];o&&(this.selectItem(o),this.updateState({selectedSuggestionIndex:-1}));return}}let s=t.value;if(e.key===" "&&this.shouldAutoInsertComma(s)){e.preventDefault();let r=`${s.trim()}, `;this.updateQueryAndFetch(r)}}selectItem(e){this.debouncedFetch.cancel(),this.abortController&&this.abortController.abort();let t=typeof e=="string"?e:e.label,i=t;typeof e!="string"&&typeof e.value=="string"&&(i=e.value);let s=typeof e!="string"&&typeof e.value=="object"?e.value:void 0,r=!!s&&Object.keys(s).length>0;if(this.isSelecting=!0,this.state.stage==="final"||r){let u=t;if(s&&Object.keys(s).length>0){let{street:p,street_number:n,house_number:c,city:b}=s,m=n||c;p&&m&&b&&(u=`${p} ${m}, ${b}`)}return this.finishSelection(u,s),!0}let o=typeof e!="string"?e.subtitle:null;return this.processSelection(i,o),!1}shouldAutoInsertComma(e){if(!e.includes(",")&&x.DIGITS_1_3.test(e.trim()))return!0;if(this.state.stage==="house_number"){let i=this.getCurrentFragment(e);return x.DIGITS_1_3.test(i)}return!1}finishSelection(e,t){this.updateState({query:e,suggestions:[],cities:[],streets:[],isValid:!0,stage:"final",hasMore:!1}),this.onSelect(t||e)}processSelection(e,t){let{stage:i,query:s}=this.state,r=s;if(t&&(i==="city"||i==="street"||i==="mixed")){if(i==="city")r=`${t}, ${e}, `;else{let n=this.getQueryPrefix(s);r=n?`${n} ${e}, ${t}, `:`${e}, ${t}, `}this.updateQueryAndFetch(r);return}if(i==="direct"||i==="addition"){this.finishSelection(e);return}!s.includes(",")&&(i==="city"||i==="street"||i==="house_number_first")?r=`${e}, `:(r=this.replaceLastSegment(s,e),i!=="house_number"&&(r+=", ")),this.updateQueryAndFetch(r)}executeFetch(e,t=0){let i=(e||"").toString();if(!i.trim()){this.abortController?.abort(),this.resetState();return}t===0&&(this.updateState({isError:!1}),this.abortController&&this.abortController.abort(),this.abortController=new AbortController);let s=this.abortController?.signal,r=this.explicitApiUrl?this.explicitApiUrl:`${d.API_URL}/infer/${this.country.toLowerCase()}`,o=new URLSearchParams({country:this.country.toLowerCase(),query:i,limit:this.currentLimit.toString()});this.authKey&&o.set("authKey",this.authKey);let u=r.includes("?")?"&":"?",p=`${r}${u}${o.toString()}`;this.fetcher(p,{signal:s}).then(n=>{if(!n.ok){if(t<this.maxRetries&&(n.status>=500||n.status===429))return this.retry(e,t,s);throw new Error("Network error")}return n.json()}).then(n=>{n&&this.mapResponseToState(n)}).catch(n=>{if(n.name!=="AbortError"){if(t<this.maxRetries)return this.retry(e,t,s);this.updateState({isError:!0,isLoading:!1})}})}retry(e,t,i){if(i?.aborted)return;let s=Math.pow(2,t)*200;setTimeout(()=>{i?.aborted||this.executeFetch(e,t+1)},s)}mapResponseToState(e){let t={stage:e.stage,isLoading:!1},i=!1,s=null,r=e.suggestions||[],o=[],u=new Set;for(let n of r){let c=`${n.label}|${n.subtitle||""}|${JSON.stringify(n.value||{})}`;u.has(c)||(u.add(c),o.push(n))}let p=o.length+(e.cities?.length||0)+(e.streets?.length||0);if(t.hasMore=p>=this.currentLimit,e.stage==="mixed")t.cities=e.cities||[],t.streets=e.streets||[],t.suggestions=[];else{t.suggestions=o,t.cities=[],t.streets=[];let n=o[0],c=n&&typeof n.value=="object"&&n.value!==null&&Object.keys(n.value).length>0;(e.stage==="final"||c)&&o.length===1&&(i=!0,s=n)}if(t.isValid=e.stage==="final",i&&s){t.query=s.label,t.suggestions=[],t.cities=[],t.streets=[],t.isValid=!0,t.hasMore=!1,this.isSelecting=!0,this.updateState(t);let n=typeof s.value=="object"?s.value:s.label;this.onSelect(n)}else this.updateState(t)}updateQueryAndFetch(e){this.updateState({query:e,suggestions:[],cities:[],streets:[]}),this.updateState({isLoading:!0,isValid:!1,hasMore:!1}),this.debouncedFetch(e)}replaceLastSegment(e,t){let i=e.lastIndexOf(",");return i===-1?t:`${e.slice(0,i+1)} ${t}`.trim()}getQueryPrefix(e){let t=e.lastIndexOf(",");return t===-1?"":e.slice(0,t+1).trimEnd()}getCurrentFragment(e){return(e.split(",").slice(-1)[0]??"").trim()}resetState(){this.updateState({...g,query:this.state.query})}updateState(e){this.state={...this.state,...e},this.onStateChange(this.state)}debounce(e,t){let i,s=(...r)=>{i&&clearTimeout(i),i=setTimeout(()=>e.apply(this,r),t)};return s.cancel=()=>{i&&(clearTimeout(i),i=void 0)},s}};var S=`
|
|
2
2
|
.pro6pp-wrapper {
|
|
3
3
|
position: relative;
|
|
4
4
|
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
.pro6pp-input {
|
|
12
12
|
width: 100%;
|
|
13
13
|
padding: 10px 12px;
|
|
14
|
+
padding-right: 48px;
|
|
14
15
|
border: 1px solid #e0e0e0;
|
|
15
16
|
border-radius: 4px;
|
|
16
17
|
font-size: 16px;
|
|
@@ -22,6 +23,57 @@
|
|
|
22
23
|
border-color: #3b82f6;
|
|
23
24
|
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
|
|
24
25
|
}
|
|
26
|
+
|
|
27
|
+
.pro6pp-input-addons {
|
|
28
|
+
position: absolute;
|
|
29
|
+
right: 6px;
|
|
30
|
+
top: 0;
|
|
31
|
+
bottom: 0;
|
|
32
|
+
display: flex;
|
|
33
|
+
align-items: center;
|
|
34
|
+
gap: 2px;
|
|
35
|
+
pointer-events: none;
|
|
36
|
+
}
|
|
37
|
+
.pro6pp-input-addons > * {
|
|
38
|
+
pointer-events: auto;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.pro6pp-clear-button {
|
|
42
|
+
background: none;
|
|
43
|
+
border: none;
|
|
44
|
+
width: 28px;
|
|
45
|
+
height: 28px;
|
|
46
|
+
cursor: pointer;
|
|
47
|
+
color: #a3a3a3;
|
|
48
|
+
display: flex;
|
|
49
|
+
align-items: center;
|
|
50
|
+
justify-content: center;
|
|
51
|
+
border-radius: 50%;
|
|
52
|
+
transition: color 0.2s, background-color 0.2s, transform 0.1s;
|
|
53
|
+
}
|
|
54
|
+
.pro6pp-clear-button:hover {
|
|
55
|
+
color: #1f2937;
|
|
56
|
+
background-color: #f3f4f6;
|
|
57
|
+
}
|
|
58
|
+
.pro6pp-clear-button:active {
|
|
59
|
+
transform: scale(0.92);
|
|
60
|
+
}
|
|
61
|
+
.pro6pp-clear-button svg {
|
|
62
|
+
width: 18px;
|
|
63
|
+
height: 18px;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.pro6pp-loader {
|
|
67
|
+
width: 18px;
|
|
68
|
+
height: 18px;
|
|
69
|
+
margin: 0 4px;
|
|
70
|
+
border: 2px solid #e0e0e0;
|
|
71
|
+
border-top-color: #6b7280;
|
|
72
|
+
border-radius: 50%;
|
|
73
|
+
animation: pro6pp-spin 0.6s linear infinite;
|
|
74
|
+
flex-shrink: 0;
|
|
75
|
+
}
|
|
76
|
+
|
|
25
77
|
.pro6pp-dropdown {
|
|
26
78
|
position: absolute;
|
|
27
79
|
top: 100%;
|
|
@@ -32,27 +84,32 @@
|
|
|
32
84
|
background: white;
|
|
33
85
|
border: 1px solid #e0e0e0;
|
|
34
86
|
border-radius: 4px;
|
|
35
|
-
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.
|
|
87
|
+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
|
36
88
|
max-height: 300px;
|
|
37
89
|
overflow-y: auto;
|
|
90
|
+
display: flex;
|
|
91
|
+
flex-direction: column;
|
|
92
|
+
}
|
|
93
|
+
.pro6pp-list {
|
|
38
94
|
list-style: none !important;
|
|
39
95
|
padding: 0 !important;
|
|
40
96
|
margin: 0 !important;
|
|
97
|
+
flex-grow: 1;
|
|
41
98
|
}
|
|
42
99
|
.pro6pp-item {
|
|
43
|
-
padding:
|
|
100
|
+
padding: 12px 16px;
|
|
44
101
|
cursor: pointer;
|
|
45
102
|
display: flex;
|
|
46
103
|
flex-direction: row;
|
|
47
104
|
align-items: center;
|
|
48
|
-
color: #
|
|
105
|
+
color: #111827;
|
|
49
106
|
font-size: 14px;
|
|
50
107
|
line-height: 1.2;
|
|
51
108
|
white-space: nowrap;
|
|
52
109
|
overflow: hidden;
|
|
53
110
|
}
|
|
54
111
|
.pro6pp-item:hover, .pro6pp-item--active {
|
|
55
|
-
background-color: #
|
|
112
|
+
background-color: #f9fafb;
|
|
56
113
|
}
|
|
57
114
|
.pro6pp-item__label {
|
|
58
115
|
font-weight: 500;
|
|
@@ -60,7 +117,7 @@
|
|
|
60
117
|
}
|
|
61
118
|
.pro6pp-item__subtitle {
|
|
62
119
|
font-size: 14px;
|
|
63
|
-
color: #
|
|
120
|
+
color: #6b7280;
|
|
64
121
|
overflow: hidden;
|
|
65
122
|
text-overflow: ellipsis;
|
|
66
123
|
flex-shrink: 1;
|
|
@@ -69,31 +126,33 @@
|
|
|
69
126
|
margin-left: auto;
|
|
70
127
|
display: flex;
|
|
71
128
|
align-items: center;
|
|
72
|
-
color: #
|
|
129
|
+
color: #9ca3af;
|
|
73
130
|
padding-left: 8px;
|
|
74
131
|
}
|
|
75
132
|
.pro6pp-no-results {
|
|
76
|
-
padding:
|
|
77
|
-
color: #
|
|
133
|
+
padding: 16px;
|
|
134
|
+
color: #6b7280;
|
|
78
135
|
font-size: 14px;
|
|
79
136
|
text-align: center;
|
|
80
|
-
user-select: none;
|
|
81
|
-
pointer-events: none;
|
|
82
137
|
}
|
|
83
|
-
.pro6pp-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
138
|
+
.pro6pp-load-more {
|
|
139
|
+
width: 100%;
|
|
140
|
+
padding: 10px;
|
|
141
|
+
background: #f9fafb;
|
|
142
|
+
border: none;
|
|
143
|
+
border-top: 1px solid #e0e0e0;
|
|
144
|
+
color: #3b82f6;
|
|
145
|
+
font-size: 13px;
|
|
146
|
+
font-weight: 600;
|
|
147
|
+
cursor: pointer;
|
|
148
|
+
transition: background-color 0.2s;
|
|
149
|
+
flex-shrink: 0;
|
|
150
|
+
}
|
|
151
|
+
.pro6pp-load-more:hover {
|
|
152
|
+
background-color: #f3f4f6;
|
|
95
153
|
}
|
|
154
|
+
|
|
96
155
|
@keyframes pro6pp-spin {
|
|
97
|
-
to { transform:
|
|
156
|
+
to { transform: rotate(360deg); }
|
|
98
157
|
}
|
|
99
158
|
`;0&&(module.exports={DEFAULT_STYLES,INITIAL_STATE,InferCore});
|
package/dist/index.d.cts
CHANGED
|
@@ -72,6 +72,8 @@ interface InferState {
|
|
|
72
72
|
isError: boolean;
|
|
73
73
|
/** Flag indicating if a network request is currently in progress. */
|
|
74
74
|
isLoading: boolean;
|
|
75
|
+
/** Flag indicating if more results are available to load. */
|
|
76
|
+
hasMore: boolean;
|
|
75
77
|
/**
|
|
76
78
|
* The index of the currently highlighted suggestion.
|
|
77
79
|
* - `0` to `n`: An item is highlighted via keyboard navigation.
|
|
@@ -90,15 +92,16 @@ type Fetcher = (input: RequestInfo | URL, init?: RequestInit) => Promise<Respons
|
|
|
90
92
|
interface InferConfig {
|
|
91
93
|
/**
|
|
92
94
|
* Your Pro6PP Authorization Key.
|
|
95
|
+
* Optional if using a proxy.
|
|
93
96
|
*/
|
|
94
|
-
authKey
|
|
97
|
+
authKey?: string;
|
|
95
98
|
/**
|
|
96
99
|
* The country to perform address lookups in.
|
|
97
100
|
*/
|
|
98
101
|
country: CountryCode;
|
|
99
102
|
/**
|
|
100
|
-
*
|
|
101
|
-
*
|
|
103
|
+
* * If provided, this URL is used as the API endpoint (query params will be appended).
|
|
104
|
+
* * If not provided, the SDK defaults to 'https://api.pro6pp.nl/v2/infer/{country}'.
|
|
102
105
|
*/
|
|
103
106
|
apiUrl?: string;
|
|
104
107
|
/**
|
|
@@ -107,8 +110,8 @@ interface InferConfig {
|
|
|
107
110
|
*/
|
|
108
111
|
fetcher?: Fetcher;
|
|
109
112
|
/**
|
|
110
|
-
*
|
|
111
|
-
* @default
|
|
113
|
+
* Number of suggestions to request per batch.
|
|
114
|
+
* @default 20
|
|
112
115
|
*/
|
|
113
116
|
limit?: number;
|
|
114
117
|
/**
|
|
@@ -117,6 +120,12 @@ interface InferConfig {
|
|
|
117
120
|
* @default 150
|
|
118
121
|
*/
|
|
119
122
|
debounceMs?: number;
|
|
123
|
+
/**
|
|
124
|
+
* Maximum number of retry attempts for transient network errors.
|
|
125
|
+
* Valid range: 0 to 10.
|
|
126
|
+
* @default 0
|
|
127
|
+
*/
|
|
128
|
+
maxRetries?: number;
|
|
120
129
|
/**
|
|
121
130
|
* Callback triggered whenever the internal state (suggestions, loading status, etc.) updates.
|
|
122
131
|
*/
|
|
@@ -139,9 +148,11 @@ declare const INITIAL_STATE: InferState;
|
|
|
139
148
|
*/
|
|
140
149
|
declare class InferCore {
|
|
141
150
|
private country;
|
|
142
|
-
private authKey
|
|
143
|
-
private
|
|
144
|
-
private
|
|
151
|
+
private authKey?;
|
|
152
|
+
private explicitApiUrl?;
|
|
153
|
+
private baseLimit;
|
|
154
|
+
private currentLimit;
|
|
155
|
+
private maxRetries;
|
|
145
156
|
private fetcher;
|
|
146
157
|
private onStateChange;
|
|
147
158
|
private onSelect;
|
|
@@ -164,6 +175,10 @@ declare class InferCore {
|
|
|
164
175
|
* @param value The raw string from the input field.
|
|
165
176
|
*/
|
|
166
177
|
handleInput(value: string): void;
|
|
178
|
+
/**
|
|
179
|
+
* Increases the current limit and re-fetches the query to show more results.
|
|
180
|
+
*/
|
|
181
|
+
loadMore(): void;
|
|
167
182
|
/**
|
|
168
183
|
* Handles keyboard events for the input field.
|
|
169
184
|
* Supports:
|
|
@@ -181,12 +196,14 @@ declare class InferCore {
|
|
|
181
196
|
* Manually selects a suggestion or a string value.
|
|
182
197
|
* This is typically called when a user clicks a suggestion in the UI.
|
|
183
198
|
* @param item The suggestion object or string to select.
|
|
199
|
+
* @returns boolean True if the selection is a final address.
|
|
184
200
|
*/
|
|
185
|
-
selectItem(item: InferResult | string):
|
|
201
|
+
selectItem(item: InferResult | string): boolean;
|
|
186
202
|
private shouldAutoInsertComma;
|
|
187
203
|
private finishSelection;
|
|
188
204
|
private processSelection;
|
|
189
205
|
private executeFetch;
|
|
206
|
+
private retry;
|
|
190
207
|
private mapResponseToState;
|
|
191
208
|
private updateQueryAndFetch;
|
|
192
209
|
private replaceLastSegment;
|
|
@@ -197,6 +214,6 @@ declare class InferCore {
|
|
|
197
214
|
private debounce;
|
|
198
215
|
}
|
|
199
216
|
|
|
200
|
-
declare const DEFAULT_STYLES = "\n .pro6pp-wrapper {\n position: relative;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif;\n box-sizing: border-box;\n width: 100%;\n }\n .pro6pp-wrapper * {\n box-sizing: border-box;\n }\n .pro6pp-input {\n width: 100%;\n padding: 10px 12px;\n border: 1px solid #e0e0e0;\n border-radius: 4px;\n font-size: 16px;\n line-height: 1.5;\n transition: border-color 0.2s, box-shadow 0.2s;\n }\n .pro6pp-input:focus {\n outline: none;\n border-color: #3b82f6;\n box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);\n }\n .pro6pp-dropdown {\n position: absolute;\n top: 100%;\n left: 0;\n right: 0;\n z-index: 9999;\n margin-top: 4px;\n background: white;\n border: 1px solid #e0e0e0;\n border-radius: 4px;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.
|
|
217
|
+
declare const DEFAULT_STYLES = "\n .pro6pp-wrapper {\n position: relative;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif;\n box-sizing: border-box;\n width: 100%;\n }\n .pro6pp-wrapper * {\n box-sizing: border-box;\n }\n .pro6pp-input {\n width: 100%;\n padding: 10px 12px;\n padding-right: 48px;\n border: 1px solid #e0e0e0;\n border-radius: 4px;\n font-size: 16px;\n line-height: 1.5;\n transition: border-color 0.2s, box-shadow 0.2s;\n }\n .pro6pp-input:focus {\n outline: none;\n border-color: #3b82f6;\n box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);\n }\n\n .pro6pp-input-addons {\n position: absolute;\n right: 6px;\n top: 0;\n bottom: 0;\n display: flex;\n align-items: center;\n gap: 2px;\n pointer-events: none;\n }\n .pro6pp-input-addons > * {\n pointer-events: auto;\n }\n\n .pro6pp-clear-button {\n background: none;\n border: none;\n width: 28px;\n height: 28px;\n cursor: pointer;\n color: #a3a3a3;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 50%;\n transition: color 0.2s, background-color 0.2s, transform 0.1s;\n }\n .pro6pp-clear-button:hover {\n color: #1f2937;\n background-color: #f3f4f6;\n }\n .pro6pp-clear-button:active {\n transform: scale(0.92);\n }\n .pro6pp-clear-button svg {\n width: 18px;\n height: 18px;\n }\n\n .pro6pp-loader {\n width: 18px;\n height: 18px;\n margin: 0 4px;\n border: 2px solid #e0e0e0;\n border-top-color: #6b7280;\n border-radius: 50%;\n animation: pro6pp-spin 0.6s linear infinite;\n flex-shrink: 0;\n }\n\n .pro6pp-dropdown {\n position: absolute;\n top: 100%;\n left: 0;\n right: 0;\n z-index: 9999;\n margin-top: 4px;\n background: white;\n border: 1px solid #e0e0e0;\n border-radius: 4px;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);\n max-height: 300px;\n overflow-y: auto;\n display: flex;\n flex-direction: column;\n }\n .pro6pp-list {\n list-style: none !important;\n padding: 0 !important;\n margin: 0 !important;\n flex-grow: 1;\n }\n .pro6pp-item {\n padding: 12px 16px;\n cursor: pointer;\n display: flex;\n flex-direction: row;\n align-items: center;\n color: #111827;\n font-size: 14px;\n line-height: 1.2;\n white-space: nowrap;\n overflow: hidden;\n }\n .pro6pp-item:hover, .pro6pp-item--active {\n background-color: #f9fafb;\n }\n .pro6pp-item__label {\n font-weight: 500;\n flex-shrink: 0;\n }\n .pro6pp-item__subtitle {\n font-size: 14px;\n color: #6b7280;\n overflow: hidden;\n text-overflow: ellipsis;\n flex-shrink: 1;\n }\n .pro6pp-item__chevron {\n margin-left: auto;\n display: flex;\n align-items: center;\n color: #9ca3af;\n padding-left: 8px;\n }\n .pro6pp-no-results {\n padding: 16px;\n color: #6b7280;\n font-size: 14px;\n text-align: center;\n }\n .pro6pp-load-more {\n width: 100%;\n padding: 10px;\n background: #f9fafb;\n border: none;\n border-top: 1px solid #e0e0e0;\n color: #3b82f6;\n font-size: 13px;\n font-weight: 600;\n cursor: pointer;\n transition: background-color 0.2s;\n flex-shrink: 0;\n }\n .pro6pp-load-more:hover {\n background-color: #f3f4f6;\n }\n\n @keyframes pro6pp-spin {\n to { transform: rotate(360deg); }\n }\n";
|
|
201
218
|
|
|
202
219
|
export { type AddressValue, type CountryCode, DEFAULT_STYLES, type Fetcher, INITIAL_STATE, type InferConfig, InferCore, type InferResult, type InferState, type Stage };
|
package/dist/index.d.ts
CHANGED
|
@@ -72,6 +72,8 @@ interface InferState {
|
|
|
72
72
|
isError: boolean;
|
|
73
73
|
/** Flag indicating if a network request is currently in progress. */
|
|
74
74
|
isLoading: boolean;
|
|
75
|
+
/** Flag indicating if more results are available to load. */
|
|
76
|
+
hasMore: boolean;
|
|
75
77
|
/**
|
|
76
78
|
* The index of the currently highlighted suggestion.
|
|
77
79
|
* - `0` to `n`: An item is highlighted via keyboard navigation.
|
|
@@ -90,15 +92,16 @@ type Fetcher = (input: RequestInfo | URL, init?: RequestInit) => Promise<Respons
|
|
|
90
92
|
interface InferConfig {
|
|
91
93
|
/**
|
|
92
94
|
* Your Pro6PP Authorization Key.
|
|
95
|
+
* Optional if using a proxy.
|
|
93
96
|
*/
|
|
94
|
-
authKey
|
|
97
|
+
authKey?: string;
|
|
95
98
|
/**
|
|
96
99
|
* The country to perform address lookups in.
|
|
97
100
|
*/
|
|
98
101
|
country: CountryCode;
|
|
99
102
|
/**
|
|
100
|
-
*
|
|
101
|
-
*
|
|
103
|
+
* * If provided, this URL is used as the API endpoint (query params will be appended).
|
|
104
|
+
* * If not provided, the SDK defaults to 'https://api.pro6pp.nl/v2/infer/{country}'.
|
|
102
105
|
*/
|
|
103
106
|
apiUrl?: string;
|
|
104
107
|
/**
|
|
@@ -107,8 +110,8 @@ interface InferConfig {
|
|
|
107
110
|
*/
|
|
108
111
|
fetcher?: Fetcher;
|
|
109
112
|
/**
|
|
110
|
-
*
|
|
111
|
-
* @default
|
|
113
|
+
* Number of suggestions to request per batch.
|
|
114
|
+
* @default 20
|
|
112
115
|
*/
|
|
113
116
|
limit?: number;
|
|
114
117
|
/**
|
|
@@ -117,6 +120,12 @@ interface InferConfig {
|
|
|
117
120
|
* @default 150
|
|
118
121
|
*/
|
|
119
122
|
debounceMs?: number;
|
|
123
|
+
/**
|
|
124
|
+
* Maximum number of retry attempts for transient network errors.
|
|
125
|
+
* Valid range: 0 to 10.
|
|
126
|
+
* @default 0
|
|
127
|
+
*/
|
|
128
|
+
maxRetries?: number;
|
|
120
129
|
/**
|
|
121
130
|
* Callback triggered whenever the internal state (suggestions, loading status, etc.) updates.
|
|
122
131
|
*/
|
|
@@ -139,9 +148,11 @@ declare const INITIAL_STATE: InferState;
|
|
|
139
148
|
*/
|
|
140
149
|
declare class InferCore {
|
|
141
150
|
private country;
|
|
142
|
-
private authKey
|
|
143
|
-
private
|
|
144
|
-
private
|
|
151
|
+
private authKey?;
|
|
152
|
+
private explicitApiUrl?;
|
|
153
|
+
private baseLimit;
|
|
154
|
+
private currentLimit;
|
|
155
|
+
private maxRetries;
|
|
145
156
|
private fetcher;
|
|
146
157
|
private onStateChange;
|
|
147
158
|
private onSelect;
|
|
@@ -164,6 +175,10 @@ declare class InferCore {
|
|
|
164
175
|
* @param value The raw string from the input field.
|
|
165
176
|
*/
|
|
166
177
|
handleInput(value: string): void;
|
|
178
|
+
/**
|
|
179
|
+
* Increases the current limit and re-fetches the query to show more results.
|
|
180
|
+
*/
|
|
181
|
+
loadMore(): void;
|
|
167
182
|
/**
|
|
168
183
|
* Handles keyboard events for the input field.
|
|
169
184
|
* Supports:
|
|
@@ -181,12 +196,14 @@ declare class InferCore {
|
|
|
181
196
|
* Manually selects a suggestion or a string value.
|
|
182
197
|
* This is typically called when a user clicks a suggestion in the UI.
|
|
183
198
|
* @param item The suggestion object or string to select.
|
|
199
|
+
* @returns boolean True if the selection is a final address.
|
|
184
200
|
*/
|
|
185
|
-
selectItem(item: InferResult | string):
|
|
201
|
+
selectItem(item: InferResult | string): boolean;
|
|
186
202
|
private shouldAutoInsertComma;
|
|
187
203
|
private finishSelection;
|
|
188
204
|
private processSelection;
|
|
189
205
|
private executeFetch;
|
|
206
|
+
private retry;
|
|
190
207
|
private mapResponseToState;
|
|
191
208
|
private updateQueryAndFetch;
|
|
192
209
|
private replaceLastSegment;
|
|
@@ -197,6 +214,6 @@ declare class InferCore {
|
|
|
197
214
|
private debounce;
|
|
198
215
|
}
|
|
199
216
|
|
|
200
|
-
declare const DEFAULT_STYLES = "\n .pro6pp-wrapper {\n position: relative;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif;\n box-sizing: border-box;\n width: 100%;\n }\n .pro6pp-wrapper * {\n box-sizing: border-box;\n }\n .pro6pp-input {\n width: 100%;\n padding: 10px 12px;\n border: 1px solid #e0e0e0;\n border-radius: 4px;\n font-size: 16px;\n line-height: 1.5;\n transition: border-color 0.2s, box-shadow 0.2s;\n }\n .pro6pp-input:focus {\n outline: none;\n border-color: #3b82f6;\n box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);\n }\n .pro6pp-dropdown {\n position: absolute;\n top: 100%;\n left: 0;\n right: 0;\n z-index: 9999;\n margin-top: 4px;\n background: white;\n border: 1px solid #e0e0e0;\n border-radius: 4px;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.
|
|
217
|
+
declare const DEFAULT_STYLES = "\n .pro6pp-wrapper {\n position: relative;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif;\n box-sizing: border-box;\n width: 100%;\n }\n .pro6pp-wrapper * {\n box-sizing: border-box;\n }\n .pro6pp-input {\n width: 100%;\n padding: 10px 12px;\n padding-right: 48px;\n border: 1px solid #e0e0e0;\n border-radius: 4px;\n font-size: 16px;\n line-height: 1.5;\n transition: border-color 0.2s, box-shadow 0.2s;\n }\n .pro6pp-input:focus {\n outline: none;\n border-color: #3b82f6;\n box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);\n }\n\n .pro6pp-input-addons {\n position: absolute;\n right: 6px;\n top: 0;\n bottom: 0;\n display: flex;\n align-items: center;\n gap: 2px;\n pointer-events: none;\n }\n .pro6pp-input-addons > * {\n pointer-events: auto;\n }\n\n .pro6pp-clear-button {\n background: none;\n border: none;\n width: 28px;\n height: 28px;\n cursor: pointer;\n color: #a3a3a3;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 50%;\n transition: color 0.2s, background-color 0.2s, transform 0.1s;\n }\n .pro6pp-clear-button:hover {\n color: #1f2937;\n background-color: #f3f4f6;\n }\n .pro6pp-clear-button:active {\n transform: scale(0.92);\n }\n .pro6pp-clear-button svg {\n width: 18px;\n height: 18px;\n }\n\n .pro6pp-loader {\n width: 18px;\n height: 18px;\n margin: 0 4px;\n border: 2px solid #e0e0e0;\n border-top-color: #6b7280;\n border-radius: 50%;\n animation: pro6pp-spin 0.6s linear infinite;\n flex-shrink: 0;\n }\n\n .pro6pp-dropdown {\n position: absolute;\n top: 100%;\n left: 0;\n right: 0;\n z-index: 9999;\n margin-top: 4px;\n background: white;\n border: 1px solid #e0e0e0;\n border-radius: 4px;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);\n max-height: 300px;\n overflow-y: auto;\n display: flex;\n flex-direction: column;\n }\n .pro6pp-list {\n list-style: none !important;\n padding: 0 !important;\n margin: 0 !important;\n flex-grow: 1;\n }\n .pro6pp-item {\n padding: 12px 16px;\n cursor: pointer;\n display: flex;\n flex-direction: row;\n align-items: center;\n color: #111827;\n font-size: 14px;\n line-height: 1.2;\n white-space: nowrap;\n overflow: hidden;\n }\n .pro6pp-item:hover, .pro6pp-item--active {\n background-color: #f9fafb;\n }\n .pro6pp-item__label {\n font-weight: 500;\n flex-shrink: 0;\n }\n .pro6pp-item__subtitle {\n font-size: 14px;\n color: #6b7280;\n overflow: hidden;\n text-overflow: ellipsis;\n flex-shrink: 1;\n }\n .pro6pp-item__chevron {\n margin-left: auto;\n display: flex;\n align-items: center;\n color: #9ca3af;\n padding-left: 8px;\n }\n .pro6pp-no-results {\n padding: 16px;\n color: #6b7280;\n font-size: 14px;\n text-align: center;\n }\n .pro6pp-load-more {\n width: 100%;\n padding: 10px;\n background: #f9fafb;\n border: none;\n border-top: 1px solid #e0e0e0;\n color: #3b82f6;\n font-size: 13px;\n font-weight: 600;\n cursor: pointer;\n transition: background-color 0.2s;\n flex-shrink: 0;\n }\n .pro6pp-load-more:hover {\n background-color: #f3f4f6;\n }\n\n @keyframes pro6pp-spin {\n to { transform: rotate(360deg); }\n }\n";
|
|
201
218
|
|
|
202
219
|
export { type AddressValue, type CountryCode, DEFAULT_STYLES, type Fetcher, INITIAL_STATE, type InferConfig, InferCore, type InferResult, type InferState, type Stage };
|
package/dist/index.global.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";var Pro6PPCore=(()=>{var
|
|
1
|
+
"use strict";var Pro6PPCore=(()=>{var h=Object.defineProperty;var y=Object.getOwnPropertyDescriptor;var v=Object.getOwnPropertyNames;var I=Object.prototype.hasOwnProperty;var w=(a,e,t)=>e in a?h(a,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):a[e]=t;var C=(a,e)=>{for(var t in e)h(a,t,{get:e[t],enumerable:!0})},L=(a,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of v(e))!I.call(a,s)&&s!==t&&h(a,s,{get:()=>e[s],enumerable:!(i=y(e,s))||i.enumerable});return a};var T=a=>L(h({},"__esModule",{value:!0}),a);var l=(a,e,t)=>w(a,typeof e!="symbol"?e+"":e,t);var A={};C(A,{DEFAULT_STYLES:()=>S,INITIAL_STATE:()=>g,InferCore:()=>f});var d={API_URL:"https://api.pro6pp.nl/v2",LIMIT:20,DEBOUNCE_MS:150,MIN_DEBOUNCE_MS:50,MAX_RETRIES:0},x={DIGITS_1_3:/^[0-9]{1,3}$/},g={query:"",stage:null,cities:[],streets:[],suggestions:[],isValid:!1,isError:!1,isLoading:!1,hasMore:!1,selectedSuggestionIndex:-1},f=class{constructor(e){l(this,"country");l(this,"authKey");l(this,"explicitApiUrl");l(this,"baseLimit");l(this,"currentLimit");l(this,"maxRetries");l(this,"fetcher");l(this,"onStateChange");l(this,"onSelect");l(this,"state");l(this,"abortController",null);l(this,"debouncedFetch");l(this,"isSelecting",!1);this.country=e.country,this.authKey=e.authKey,this.explicitApiUrl=e.apiUrl,this.baseLimit=e.limit||d.LIMIT,this.currentLimit=this.baseLimit;let t=e.maxRetries!==void 0?e.maxRetries:d.MAX_RETRIES;this.maxRetries=Math.max(0,Math.min(t,10)),this.fetcher=e.fetcher||((r,o)=>fetch(r,o)),this.onStateChange=e.onStateChange||(()=>{}),this.onSelect=e.onSelect||(()=>{}),this.state={...g};let i=e.debounceMs!==void 0?e.debounceMs:d.DEBOUNCE_MS,s=Math.max(i,d.MIN_DEBOUNCE_MS);this.debouncedFetch=this.debounce(r=>this.executeFetch(r),s)}handleInput(e){if(this.isSelecting){this.isSelecting=!1;return}this.currentLimit=this.baseLimit;let t=this.state.stage==="final"&&e!==this.state.query;this.updateState({query:e,isValid:!1,isLoading:!!e.trim(),selectedSuggestionIndex:-1,hasMore:!1}),t&&this.onSelect(null),this.debouncedFetch(e)}loadMore(){this.state.isLoading||(this.currentLimit+=this.baseLimit,this.updateState({isLoading:!0}),this.executeFetch(this.state.query))}handleKeyDown(e){let t=e.target;if(!t)return;let i=this.state.cities.length+this.state.streets.length+this.state.suggestions.length;if(i>0){if(e.key==="ArrowDown"){e.preventDefault();let r=this.state.selectedSuggestionIndex+1;r>=i&&(r=0),this.updateState({selectedSuggestionIndex:r});return}if(e.key==="ArrowUp"){e.preventDefault();let r=this.state.selectedSuggestionIndex-1;r<0&&(r=i-1),this.updateState({selectedSuggestionIndex:r});return}if(e.key==="Enter"&&this.state.selectedSuggestionIndex>=0){e.preventDefault();let o=[...this.state.cities,...this.state.streets,...this.state.suggestions][this.state.selectedSuggestionIndex];o&&(this.selectItem(o),this.updateState({selectedSuggestionIndex:-1}));return}}let s=t.value;if(e.key===" "&&this.shouldAutoInsertComma(s)){e.preventDefault();let r=`${s.trim()}, `;this.updateQueryAndFetch(r)}}selectItem(e){this.debouncedFetch.cancel(),this.abortController&&this.abortController.abort();let t=typeof e=="string"?e:e.label,i=t;typeof e!="string"&&typeof e.value=="string"&&(i=e.value);let s=typeof e!="string"&&typeof e.value=="object"?e.value:void 0,r=!!s&&Object.keys(s).length>0;if(this.isSelecting=!0,this.state.stage==="final"||r){let u=t;if(s&&Object.keys(s).length>0){let{street:p,street_number:n,house_number:c,city:b}=s,m=n||c;p&&m&&b&&(u=`${p} ${m}, ${b}`)}return this.finishSelection(u,s),!0}let o=typeof e!="string"?e.subtitle:null;return this.processSelection(i,o),!1}shouldAutoInsertComma(e){if(!e.includes(",")&&x.DIGITS_1_3.test(e.trim()))return!0;if(this.state.stage==="house_number"){let i=this.getCurrentFragment(e);return x.DIGITS_1_3.test(i)}return!1}finishSelection(e,t){this.updateState({query:e,suggestions:[],cities:[],streets:[],isValid:!0,stage:"final",hasMore:!1}),this.onSelect(t||e)}processSelection(e,t){let{stage:i,query:s}=this.state,r=s;if(t&&(i==="city"||i==="street"||i==="mixed")){if(i==="city")r=`${t}, ${e}, `;else{let n=this.getQueryPrefix(s);r=n?`${n} ${e}, ${t}, `:`${e}, ${t}, `}this.updateQueryAndFetch(r);return}if(i==="direct"||i==="addition"){this.finishSelection(e);return}!s.includes(",")&&(i==="city"||i==="street"||i==="house_number_first")?r=`${e}, `:(r=this.replaceLastSegment(s,e),i!=="house_number"&&(r+=", ")),this.updateQueryAndFetch(r)}executeFetch(e,t=0){let i=(e||"").toString();if(!i.trim()){this.abortController?.abort(),this.resetState();return}t===0&&(this.updateState({isError:!1}),this.abortController&&this.abortController.abort(),this.abortController=new AbortController);let s=this.abortController?.signal,r=this.explicitApiUrl?this.explicitApiUrl:`${d.API_URL}/infer/${this.country.toLowerCase()}`,o=new URLSearchParams({country:this.country.toLowerCase(),query:i,limit:this.currentLimit.toString()});this.authKey&&o.set("authKey",this.authKey);let u=r.includes("?")?"&":"?",p=`${r}${u}${o.toString()}`;this.fetcher(p,{signal:s}).then(n=>{if(!n.ok){if(t<this.maxRetries&&(n.status>=500||n.status===429))return this.retry(e,t,s);throw new Error("Network error")}return n.json()}).then(n=>{n&&this.mapResponseToState(n)}).catch(n=>{if(n.name!=="AbortError"){if(t<this.maxRetries)return this.retry(e,t,s);this.updateState({isError:!0,isLoading:!1})}})}retry(e,t,i){if(i?.aborted)return;let s=Math.pow(2,t)*200;setTimeout(()=>{i?.aborted||this.executeFetch(e,t+1)},s)}mapResponseToState(e){let t={stage:e.stage,isLoading:!1},i=!1,s=null,r=e.suggestions||[],o=[],u=new Set;for(let n of r){let c=`${n.label}|${n.subtitle||""}|${JSON.stringify(n.value||{})}`;u.has(c)||(u.add(c),o.push(n))}let p=o.length+(e.cities?.length||0)+(e.streets?.length||0);if(t.hasMore=p>=this.currentLimit,e.stage==="mixed")t.cities=e.cities||[],t.streets=e.streets||[],t.suggestions=[];else{t.suggestions=o,t.cities=[],t.streets=[];let n=o[0],c=n&&typeof n.value=="object"&&n.value!==null&&Object.keys(n.value).length>0;(e.stage==="final"||c)&&o.length===1&&(i=!0,s=n)}if(t.isValid=e.stage==="final",i&&s){t.query=s.label,t.suggestions=[],t.cities=[],t.streets=[],t.isValid=!0,t.hasMore=!1,this.isSelecting=!0,this.updateState(t);let n=typeof s.value=="object"?s.value:s.label;this.onSelect(n)}else this.updateState(t)}updateQueryAndFetch(e){this.updateState({query:e,suggestions:[],cities:[],streets:[]}),this.updateState({isLoading:!0,isValid:!1,hasMore:!1}),this.debouncedFetch(e)}replaceLastSegment(e,t){let i=e.lastIndexOf(",");return i===-1?t:`${e.slice(0,i+1)} ${t}`.trim()}getQueryPrefix(e){let t=e.lastIndexOf(",");return t===-1?"":e.slice(0,t+1).trimEnd()}getCurrentFragment(e){return(e.split(",").slice(-1)[0]??"").trim()}resetState(){this.updateState({...g,query:this.state.query})}updateState(e){this.state={...this.state,...e},this.onStateChange(this.state)}debounce(e,t){let i,s=(...r)=>{i&&clearTimeout(i),i=setTimeout(()=>e.apply(this,r),t)};return s.cancel=()=>{i&&(clearTimeout(i),i=void 0)},s}};var S=`
|
|
2
2
|
.pro6pp-wrapper {
|
|
3
3
|
position: relative;
|
|
4
4
|
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
.pro6pp-input {
|
|
12
12
|
width: 100%;
|
|
13
13
|
padding: 10px 12px;
|
|
14
|
+
padding-right: 48px;
|
|
14
15
|
border: 1px solid #e0e0e0;
|
|
15
16
|
border-radius: 4px;
|
|
16
17
|
font-size: 16px;
|
|
@@ -22,6 +23,57 @@
|
|
|
22
23
|
border-color: #3b82f6;
|
|
23
24
|
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
|
|
24
25
|
}
|
|
26
|
+
|
|
27
|
+
.pro6pp-input-addons {
|
|
28
|
+
position: absolute;
|
|
29
|
+
right: 6px;
|
|
30
|
+
top: 0;
|
|
31
|
+
bottom: 0;
|
|
32
|
+
display: flex;
|
|
33
|
+
align-items: center;
|
|
34
|
+
gap: 2px;
|
|
35
|
+
pointer-events: none;
|
|
36
|
+
}
|
|
37
|
+
.pro6pp-input-addons > * {
|
|
38
|
+
pointer-events: auto;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.pro6pp-clear-button {
|
|
42
|
+
background: none;
|
|
43
|
+
border: none;
|
|
44
|
+
width: 28px;
|
|
45
|
+
height: 28px;
|
|
46
|
+
cursor: pointer;
|
|
47
|
+
color: #a3a3a3;
|
|
48
|
+
display: flex;
|
|
49
|
+
align-items: center;
|
|
50
|
+
justify-content: center;
|
|
51
|
+
border-radius: 50%;
|
|
52
|
+
transition: color 0.2s, background-color 0.2s, transform 0.1s;
|
|
53
|
+
}
|
|
54
|
+
.pro6pp-clear-button:hover {
|
|
55
|
+
color: #1f2937;
|
|
56
|
+
background-color: #f3f4f6;
|
|
57
|
+
}
|
|
58
|
+
.pro6pp-clear-button:active {
|
|
59
|
+
transform: scale(0.92);
|
|
60
|
+
}
|
|
61
|
+
.pro6pp-clear-button svg {
|
|
62
|
+
width: 18px;
|
|
63
|
+
height: 18px;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.pro6pp-loader {
|
|
67
|
+
width: 18px;
|
|
68
|
+
height: 18px;
|
|
69
|
+
margin: 0 4px;
|
|
70
|
+
border: 2px solid #e0e0e0;
|
|
71
|
+
border-top-color: #6b7280;
|
|
72
|
+
border-radius: 50%;
|
|
73
|
+
animation: pro6pp-spin 0.6s linear infinite;
|
|
74
|
+
flex-shrink: 0;
|
|
75
|
+
}
|
|
76
|
+
|
|
25
77
|
.pro6pp-dropdown {
|
|
26
78
|
position: absolute;
|
|
27
79
|
top: 100%;
|
|
@@ -32,27 +84,32 @@
|
|
|
32
84
|
background: white;
|
|
33
85
|
border: 1px solid #e0e0e0;
|
|
34
86
|
border-radius: 4px;
|
|
35
|
-
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.
|
|
87
|
+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
|
36
88
|
max-height: 300px;
|
|
37
89
|
overflow-y: auto;
|
|
90
|
+
display: flex;
|
|
91
|
+
flex-direction: column;
|
|
92
|
+
}
|
|
93
|
+
.pro6pp-list {
|
|
38
94
|
list-style: none !important;
|
|
39
95
|
padding: 0 !important;
|
|
40
96
|
margin: 0 !important;
|
|
97
|
+
flex-grow: 1;
|
|
41
98
|
}
|
|
42
99
|
.pro6pp-item {
|
|
43
|
-
padding:
|
|
100
|
+
padding: 12px 16px;
|
|
44
101
|
cursor: pointer;
|
|
45
102
|
display: flex;
|
|
46
103
|
flex-direction: row;
|
|
47
104
|
align-items: center;
|
|
48
|
-
color: #
|
|
105
|
+
color: #111827;
|
|
49
106
|
font-size: 14px;
|
|
50
107
|
line-height: 1.2;
|
|
51
108
|
white-space: nowrap;
|
|
52
109
|
overflow: hidden;
|
|
53
110
|
}
|
|
54
111
|
.pro6pp-item:hover, .pro6pp-item--active {
|
|
55
|
-
background-color: #
|
|
112
|
+
background-color: #f9fafb;
|
|
56
113
|
}
|
|
57
114
|
.pro6pp-item__label {
|
|
58
115
|
font-weight: 500;
|
|
@@ -60,7 +117,7 @@
|
|
|
60
117
|
}
|
|
61
118
|
.pro6pp-item__subtitle {
|
|
62
119
|
font-size: 14px;
|
|
63
|
-
color: #
|
|
120
|
+
color: #6b7280;
|
|
64
121
|
overflow: hidden;
|
|
65
122
|
text-overflow: ellipsis;
|
|
66
123
|
flex-shrink: 1;
|
|
@@ -69,31 +126,33 @@
|
|
|
69
126
|
margin-left: auto;
|
|
70
127
|
display: flex;
|
|
71
128
|
align-items: center;
|
|
72
|
-
color: #
|
|
129
|
+
color: #9ca3af;
|
|
73
130
|
padding-left: 8px;
|
|
74
131
|
}
|
|
75
132
|
.pro6pp-no-results {
|
|
76
|
-
padding:
|
|
77
|
-
color: #
|
|
133
|
+
padding: 16px;
|
|
134
|
+
color: #6b7280;
|
|
78
135
|
font-size: 14px;
|
|
79
136
|
text-align: center;
|
|
80
|
-
user-select: none;
|
|
81
|
-
pointer-events: none;
|
|
82
137
|
}
|
|
83
|
-
.pro6pp-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
138
|
+
.pro6pp-load-more {
|
|
139
|
+
width: 100%;
|
|
140
|
+
padding: 10px;
|
|
141
|
+
background: #f9fafb;
|
|
142
|
+
border: none;
|
|
143
|
+
border-top: 1px solid #e0e0e0;
|
|
144
|
+
color: #3b82f6;
|
|
145
|
+
font-size: 13px;
|
|
146
|
+
font-weight: 600;
|
|
147
|
+
cursor: pointer;
|
|
148
|
+
transition: background-color 0.2s;
|
|
149
|
+
flex-shrink: 0;
|
|
150
|
+
}
|
|
151
|
+
.pro6pp-load-more:hover {
|
|
152
|
+
background-color: #f3f4f6;
|
|
95
153
|
}
|
|
154
|
+
|
|
96
155
|
@keyframes pro6pp-spin {
|
|
97
|
-
to { transform:
|
|
156
|
+
to { transform: rotate(360deg); }
|
|
98
157
|
}
|
|
99
|
-
`;return
|
|
158
|
+
`;return T(A);})();
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var
|
|
1
|
+
var x=Object.defineProperty;var S=(p,e,t)=>e in p?x(p,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):p[e]=t;var a=(p,e,t)=>S(p,typeof e!="symbol"?e+"":e,t);var d={API_URL:"https://api.pro6pp.nl/v2",LIMIT:20,DEBOUNCE_MS:150,MIN_DEBOUNCE_MS:50,MAX_RETRIES:0},f={DIGITS_1_3:/^[0-9]{1,3}$/},b={query:"",stage:null,cities:[],streets:[],suggestions:[],isValid:!1,isError:!1,isLoading:!1,hasMore:!1,selectedSuggestionIndex:-1},m=class{constructor(e){a(this,"country");a(this,"authKey");a(this,"explicitApiUrl");a(this,"baseLimit");a(this,"currentLimit");a(this,"maxRetries");a(this,"fetcher");a(this,"onStateChange");a(this,"onSelect");a(this,"state");a(this,"abortController",null);a(this,"debouncedFetch");a(this,"isSelecting",!1);this.country=e.country,this.authKey=e.authKey,this.explicitApiUrl=e.apiUrl,this.baseLimit=e.limit||d.LIMIT,this.currentLimit=this.baseLimit;let t=e.maxRetries!==void 0?e.maxRetries:d.MAX_RETRIES;this.maxRetries=Math.max(0,Math.min(t,10)),this.fetcher=e.fetcher||((r,o)=>fetch(r,o)),this.onStateChange=e.onStateChange||(()=>{}),this.onSelect=e.onSelect||(()=>{}),this.state={...b};let i=e.debounceMs!==void 0?e.debounceMs:d.DEBOUNCE_MS,s=Math.max(i,d.MIN_DEBOUNCE_MS);this.debouncedFetch=this.debounce(r=>this.executeFetch(r),s)}handleInput(e){if(this.isSelecting){this.isSelecting=!1;return}this.currentLimit=this.baseLimit;let t=this.state.stage==="final"&&e!==this.state.query;this.updateState({query:e,isValid:!1,isLoading:!!e.trim(),selectedSuggestionIndex:-1,hasMore:!1}),t&&this.onSelect(null),this.debouncedFetch(e)}loadMore(){this.state.isLoading||(this.currentLimit+=this.baseLimit,this.updateState({isLoading:!0}),this.executeFetch(this.state.query))}handleKeyDown(e){let t=e.target;if(!t)return;let i=this.state.cities.length+this.state.streets.length+this.state.suggestions.length;if(i>0){if(e.key==="ArrowDown"){e.preventDefault();let r=this.state.selectedSuggestionIndex+1;r>=i&&(r=0),this.updateState({selectedSuggestionIndex:r});return}if(e.key==="ArrowUp"){e.preventDefault();let r=this.state.selectedSuggestionIndex-1;r<0&&(r=i-1),this.updateState({selectedSuggestionIndex:r});return}if(e.key==="Enter"&&this.state.selectedSuggestionIndex>=0){e.preventDefault();let o=[...this.state.cities,...this.state.streets,...this.state.suggestions][this.state.selectedSuggestionIndex];o&&(this.selectItem(o),this.updateState({selectedSuggestionIndex:-1}));return}}let s=t.value;if(e.key===" "&&this.shouldAutoInsertComma(s)){e.preventDefault();let r=`${s.trim()}, `;this.updateQueryAndFetch(r)}}selectItem(e){this.debouncedFetch.cancel(),this.abortController&&this.abortController.abort();let t=typeof e=="string"?e:e.label,i=t;typeof e!="string"&&typeof e.value=="string"&&(i=e.value);let s=typeof e!="string"&&typeof e.value=="object"?e.value:void 0,r=!!s&&Object.keys(s).length>0;if(this.isSelecting=!0,this.state.stage==="final"||r){let l=t;if(s&&Object.keys(s).length>0){let{street:u,street_number:n,house_number:c,city:h}=s,g=n||c;u&&g&&h&&(l=`${u} ${g}, ${h}`)}return this.finishSelection(l,s),!0}let o=typeof e!="string"?e.subtitle:null;return this.processSelection(i,o),!1}shouldAutoInsertComma(e){if(!e.includes(",")&&f.DIGITS_1_3.test(e.trim()))return!0;if(this.state.stage==="house_number"){let i=this.getCurrentFragment(e);return f.DIGITS_1_3.test(i)}return!1}finishSelection(e,t){this.updateState({query:e,suggestions:[],cities:[],streets:[],isValid:!0,stage:"final",hasMore:!1}),this.onSelect(t||e)}processSelection(e,t){let{stage:i,query:s}=this.state,r=s;if(t&&(i==="city"||i==="street"||i==="mixed")){if(i==="city")r=`${t}, ${e}, `;else{let n=this.getQueryPrefix(s);r=n?`${n} ${e}, ${t}, `:`${e}, ${t}, `}this.updateQueryAndFetch(r);return}if(i==="direct"||i==="addition"){this.finishSelection(e);return}!s.includes(",")&&(i==="city"||i==="street"||i==="house_number_first")?r=`${e}, `:(r=this.replaceLastSegment(s,e),i!=="house_number"&&(r+=", ")),this.updateQueryAndFetch(r)}executeFetch(e,t=0){let i=(e||"").toString();if(!i.trim()){this.abortController?.abort(),this.resetState();return}t===0&&(this.updateState({isError:!1}),this.abortController&&this.abortController.abort(),this.abortController=new AbortController);let s=this.abortController?.signal,r=this.explicitApiUrl?this.explicitApiUrl:`${d.API_URL}/infer/${this.country.toLowerCase()}`,o=new URLSearchParams({country:this.country.toLowerCase(),query:i,limit:this.currentLimit.toString()});this.authKey&&o.set("authKey",this.authKey);let l=r.includes("?")?"&":"?",u=`${r}${l}${o.toString()}`;this.fetcher(u,{signal:s}).then(n=>{if(!n.ok){if(t<this.maxRetries&&(n.status>=500||n.status===429))return this.retry(e,t,s);throw new Error("Network error")}return n.json()}).then(n=>{n&&this.mapResponseToState(n)}).catch(n=>{if(n.name!=="AbortError"){if(t<this.maxRetries)return this.retry(e,t,s);this.updateState({isError:!0,isLoading:!1})}})}retry(e,t,i){if(i?.aborted)return;let s=Math.pow(2,t)*200;setTimeout(()=>{i?.aborted||this.executeFetch(e,t+1)},s)}mapResponseToState(e){let t={stage:e.stage,isLoading:!1},i=!1,s=null,r=e.suggestions||[],o=[],l=new Set;for(let n of r){let c=`${n.label}|${n.subtitle||""}|${JSON.stringify(n.value||{})}`;l.has(c)||(l.add(c),o.push(n))}let u=o.length+(e.cities?.length||0)+(e.streets?.length||0);if(t.hasMore=u>=this.currentLimit,e.stage==="mixed")t.cities=e.cities||[],t.streets=e.streets||[],t.suggestions=[];else{t.suggestions=o,t.cities=[],t.streets=[];let n=o[0],c=n&&typeof n.value=="object"&&n.value!==null&&Object.keys(n.value).length>0;(e.stage==="final"||c)&&o.length===1&&(i=!0,s=n)}if(t.isValid=e.stage==="final",i&&s){t.query=s.label,t.suggestions=[],t.cities=[],t.streets=[],t.isValid=!0,t.hasMore=!1,this.isSelecting=!0,this.updateState(t);let n=typeof s.value=="object"?s.value:s.label;this.onSelect(n)}else this.updateState(t)}updateQueryAndFetch(e){this.updateState({query:e,suggestions:[],cities:[],streets:[]}),this.updateState({isLoading:!0,isValid:!1,hasMore:!1}),this.debouncedFetch(e)}replaceLastSegment(e,t){let i=e.lastIndexOf(",");return i===-1?t:`${e.slice(0,i+1)} ${t}`.trim()}getQueryPrefix(e){let t=e.lastIndexOf(",");return t===-1?"":e.slice(0,t+1).trimEnd()}getCurrentFragment(e){return(e.split(",").slice(-1)[0]??"").trim()}resetState(){this.updateState({...b,query:this.state.query})}updateState(e){this.state={...this.state,...e},this.onStateChange(this.state)}debounce(e,t){let i,s=(...r)=>{i&&clearTimeout(i),i=setTimeout(()=>e.apply(this,r),t)};return s.cancel=()=>{i&&(clearTimeout(i),i=void 0)},s}};var y=`
|
|
2
2
|
.pro6pp-wrapper {
|
|
3
3
|
position: relative;
|
|
4
4
|
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
|
|
@@ -11,6 +11,7 @@ var b=Object.defineProperty;var x=(u,e,t)=>e in u?b(u,e,{enumerable:!0,configura
|
|
|
11
11
|
.pro6pp-input {
|
|
12
12
|
width: 100%;
|
|
13
13
|
padding: 10px 12px;
|
|
14
|
+
padding-right: 48px;
|
|
14
15
|
border: 1px solid #e0e0e0;
|
|
15
16
|
border-radius: 4px;
|
|
16
17
|
font-size: 16px;
|
|
@@ -22,6 +23,57 @@ var b=Object.defineProperty;var x=(u,e,t)=>e in u?b(u,e,{enumerable:!0,configura
|
|
|
22
23
|
border-color: #3b82f6;
|
|
23
24
|
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
|
|
24
25
|
}
|
|
26
|
+
|
|
27
|
+
.pro6pp-input-addons {
|
|
28
|
+
position: absolute;
|
|
29
|
+
right: 6px;
|
|
30
|
+
top: 0;
|
|
31
|
+
bottom: 0;
|
|
32
|
+
display: flex;
|
|
33
|
+
align-items: center;
|
|
34
|
+
gap: 2px;
|
|
35
|
+
pointer-events: none;
|
|
36
|
+
}
|
|
37
|
+
.pro6pp-input-addons > * {
|
|
38
|
+
pointer-events: auto;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.pro6pp-clear-button {
|
|
42
|
+
background: none;
|
|
43
|
+
border: none;
|
|
44
|
+
width: 28px;
|
|
45
|
+
height: 28px;
|
|
46
|
+
cursor: pointer;
|
|
47
|
+
color: #a3a3a3;
|
|
48
|
+
display: flex;
|
|
49
|
+
align-items: center;
|
|
50
|
+
justify-content: center;
|
|
51
|
+
border-radius: 50%;
|
|
52
|
+
transition: color 0.2s, background-color 0.2s, transform 0.1s;
|
|
53
|
+
}
|
|
54
|
+
.pro6pp-clear-button:hover {
|
|
55
|
+
color: #1f2937;
|
|
56
|
+
background-color: #f3f4f6;
|
|
57
|
+
}
|
|
58
|
+
.pro6pp-clear-button:active {
|
|
59
|
+
transform: scale(0.92);
|
|
60
|
+
}
|
|
61
|
+
.pro6pp-clear-button svg {
|
|
62
|
+
width: 18px;
|
|
63
|
+
height: 18px;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.pro6pp-loader {
|
|
67
|
+
width: 18px;
|
|
68
|
+
height: 18px;
|
|
69
|
+
margin: 0 4px;
|
|
70
|
+
border: 2px solid #e0e0e0;
|
|
71
|
+
border-top-color: #6b7280;
|
|
72
|
+
border-radius: 50%;
|
|
73
|
+
animation: pro6pp-spin 0.6s linear infinite;
|
|
74
|
+
flex-shrink: 0;
|
|
75
|
+
}
|
|
76
|
+
|
|
25
77
|
.pro6pp-dropdown {
|
|
26
78
|
position: absolute;
|
|
27
79
|
top: 100%;
|
|
@@ -32,27 +84,32 @@ var b=Object.defineProperty;var x=(u,e,t)=>e in u?b(u,e,{enumerable:!0,configura
|
|
|
32
84
|
background: white;
|
|
33
85
|
border: 1px solid #e0e0e0;
|
|
34
86
|
border-radius: 4px;
|
|
35
|
-
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.
|
|
87
|
+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
|
36
88
|
max-height: 300px;
|
|
37
89
|
overflow-y: auto;
|
|
90
|
+
display: flex;
|
|
91
|
+
flex-direction: column;
|
|
92
|
+
}
|
|
93
|
+
.pro6pp-list {
|
|
38
94
|
list-style: none !important;
|
|
39
95
|
padding: 0 !important;
|
|
40
96
|
margin: 0 !important;
|
|
97
|
+
flex-grow: 1;
|
|
41
98
|
}
|
|
42
99
|
.pro6pp-item {
|
|
43
|
-
padding:
|
|
100
|
+
padding: 12px 16px;
|
|
44
101
|
cursor: pointer;
|
|
45
102
|
display: flex;
|
|
46
103
|
flex-direction: row;
|
|
47
104
|
align-items: center;
|
|
48
|
-
color: #
|
|
105
|
+
color: #111827;
|
|
49
106
|
font-size: 14px;
|
|
50
107
|
line-height: 1.2;
|
|
51
108
|
white-space: nowrap;
|
|
52
109
|
overflow: hidden;
|
|
53
110
|
}
|
|
54
111
|
.pro6pp-item:hover, .pro6pp-item--active {
|
|
55
|
-
background-color: #
|
|
112
|
+
background-color: #f9fafb;
|
|
56
113
|
}
|
|
57
114
|
.pro6pp-item__label {
|
|
58
115
|
font-weight: 500;
|
|
@@ -60,7 +117,7 @@ var b=Object.defineProperty;var x=(u,e,t)=>e in u?b(u,e,{enumerable:!0,configura
|
|
|
60
117
|
}
|
|
61
118
|
.pro6pp-item__subtitle {
|
|
62
119
|
font-size: 14px;
|
|
63
|
-
color: #
|
|
120
|
+
color: #6b7280;
|
|
64
121
|
overflow: hidden;
|
|
65
122
|
text-overflow: ellipsis;
|
|
66
123
|
flex-shrink: 1;
|
|
@@ -69,31 +126,33 @@ var b=Object.defineProperty;var x=(u,e,t)=>e in u?b(u,e,{enumerable:!0,configura
|
|
|
69
126
|
margin-left: auto;
|
|
70
127
|
display: flex;
|
|
71
128
|
align-items: center;
|
|
72
|
-
color: #
|
|
129
|
+
color: #9ca3af;
|
|
73
130
|
padding-left: 8px;
|
|
74
131
|
}
|
|
75
132
|
.pro6pp-no-results {
|
|
76
|
-
padding:
|
|
77
|
-
color: #
|
|
133
|
+
padding: 16px;
|
|
134
|
+
color: #6b7280;
|
|
78
135
|
font-size: 14px;
|
|
79
136
|
text-align: center;
|
|
80
|
-
user-select: none;
|
|
81
|
-
pointer-events: none;
|
|
82
137
|
}
|
|
83
|
-
.pro6pp-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
138
|
+
.pro6pp-load-more {
|
|
139
|
+
width: 100%;
|
|
140
|
+
padding: 10px;
|
|
141
|
+
background: #f9fafb;
|
|
142
|
+
border: none;
|
|
143
|
+
border-top: 1px solid #e0e0e0;
|
|
144
|
+
color: #3b82f6;
|
|
145
|
+
font-size: 13px;
|
|
146
|
+
font-weight: 600;
|
|
147
|
+
cursor: pointer;
|
|
148
|
+
transition: background-color 0.2s;
|
|
149
|
+
flex-shrink: 0;
|
|
150
|
+
}
|
|
151
|
+
.pro6pp-load-more:hover {
|
|
152
|
+
background-color: #f3f4f6;
|
|
95
153
|
}
|
|
154
|
+
|
|
96
155
|
@keyframes pro6pp-spin {
|
|
97
|
-
to { transform:
|
|
156
|
+
to { transform: rotate(360deg); }
|
|
98
157
|
}
|
|
99
|
-
`;export{y as DEFAULT_STYLES,
|
|
158
|
+
`;export{y as DEFAULT_STYLES,b as INITIAL_STATE,m as InferCore};
|
package/package.json
CHANGED