@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 CHANGED
@@ -1,4 +1,4 @@
1
- "use strict";var c=Object.defineProperty;var y=Object.getOwnPropertyDescriptor;var v=Object.getOwnPropertyNames;var I=Object.prototype.hasOwnProperty;var C=(n,e,t)=>e in n?c(n,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):n[e]=t;var T=(n,e)=>{for(var t in e)c(n,t,{get:e[t],enumerable:!0})},w=(n,e,t,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of v(e))!I.call(n,i)&&i!==t&&c(n,i,{get:()=>e[i],enumerable:!(s=y(e,i))||s.enumerable});return n};var _=n=>w(c({},"__esModule",{value:!0}),n);var o=(n,e,t)=>C(n,typeof e!="symbol"?e+"":e,t);var F={};T(F,{DEFAULT_STYLES:()=>b,INITIAL_STATE:()=>h,InferCore:()=>g});module.exports=_(F);var d={API_URL:"https://api.pro6pp.nl/v2",LIMIT:1e3,DEBOUNCE_MS:150,MIN_DEBOUNCE_MS:50},m={DIGITS_1_3:/^[0-9]{1,3}$/},h={query:"",stage:null,cities:[],streets:[],suggestions:[],isValid:!1,isError:!1,isLoading:!1,selectedSuggestionIndex:-1},g=class{constructor(e){o(this,"country");o(this,"authKey");o(this,"apiUrl");o(this,"limit");o(this,"fetcher");o(this,"onStateChange");o(this,"onSelect");o(this,"state");o(this,"abortController",null);o(this,"debouncedFetch");o(this,"isSelecting",!1);this.country=e.country,this.authKey=e.authKey,this.apiUrl=e.apiUrl||d.API_URL,this.limit=e.limit||d.LIMIT,this.fetcher=e.fetcher||((i,r)=>fetch(i,r)),this.onStateChange=e.onStateChange||(()=>{}),this.onSelect=e.onSelect||(()=>{}),this.state={...h};let t=e.debounceMs!==void 0?e.debounceMs:d.DEBOUNCE_MS,s=Math.max(t,d.MIN_DEBOUNCE_MS);this.debouncedFetch=this.debounce(i=>this.executeFetch(i),s)}handleInput(e){if(this.isSelecting){this.isSelecting=!1;return}let t=this.state.stage==="final"&&e!==this.state.query;this.updateState({query:e,isValid:!1,isLoading:!!e.trim(),selectedSuggestionIndex:-1}),t&&this.onSelect(null),this.debouncedFetch(e)}handleKeyDown(e){let t=e.target;if(!t)return;let s=this.state.cities.length+this.state.streets.length+this.state.suggestions.length;if(s>0){if(e.key==="ArrowDown"){e.preventDefault();let r=this.state.selectedSuggestionIndex+1;r>=s&&(r=0),this.updateState({selectedSuggestionIndex:r});return}if(e.key==="ArrowUp"){e.preventDefault();let r=this.state.selectedSuggestionIndex-1;r<0&&(r=s-1),this.updateState({selectedSuggestionIndex:r});return}if(e.key==="Enter"&&this.state.selectedSuggestionIndex>=0){e.preventDefault();let a=[...this.state.cities,...this.state.streets,...this.state.suggestions][this.state.selectedSuggestionIndex];a&&(this.selectItem(a),this.updateState({selectedSuggestionIndex:-1}));return}}let i=t.value;if(e.key===" "&&this.shouldAutoInsertComma(i)){e.preventDefault();let r=`${i.trim()}, `;this.updateQueryAndFetch(r)}}selectItem(e){this.debouncedFetch.cancel(),this.abortController&&this.abortController.abort();let t=typeof e=="string"?e:e.label,s=t;typeof e!="string"&&typeof e.value=="string"&&(s=e.value);let i=typeof e!="string"&&typeof e.value=="object"?e.value:void 0,r=!!i&&Object.keys(i).length>0;if(this.isSelecting=!0,this.state.stage==="final"||r){let p=t;if(i&&Object.keys(i).length>0){let{street:l,street_number:u,house_number:x,city:f}=i,S=u||x;l&&S&&f&&(p=`${l} ${S}, ${f}`)}this.finishSelection(p,i);return}let a=typeof e!="string"?e.subtitle:null;this.processSelection(s,a)}shouldAutoInsertComma(e){if(!e.includes(",")&&m.DIGITS_1_3.test(e.trim()))return!0;if(this.state.stage==="house_number"){let s=this.getCurrentFragment(e);return m.DIGITS_1_3.test(s)}return!1}finishSelection(e,t){this.updateState({query:e,suggestions:[],cities:[],streets:[],isValid:!0,stage:"final"}),this.onSelect(t||e),setTimeout(()=>{this.isSelecting=!1},0)}processSelection(e,t){let{stage:s,query:i}=this.state,r=i;if(t&&(s==="city"||s==="street"||s==="mixed")){if(s==="city")r=`${t}, ${e}, `;else{let u=this.getQueryPrefix(i);r=u?`${u} ${e}, ${t}, `:`${e}, ${t}, `}this.updateQueryAndFetch(r);return}if(s==="direct"||s==="addition"){this.finishSelection(e);return}!i.includes(",")&&(s==="city"||s==="street"||s==="house_number_first")?r=`${e}, `:(r=this.replaceLastSegment(i,e),s!=="house_number"&&(r+=", ")),this.updateQueryAndFetch(r)}executeFetch(e){let t=(e||"").toString();if(!t.trim()){this.abortController?.abort(),this.resetState();return}this.updateState({isError:!1}),this.abortController&&this.abortController.abort(),this.abortController=new AbortController;let s=new URL(`${this.apiUrl}/infer/${this.country.toLowerCase()}`),i={authKey:this.authKey,query:t,limit:this.limit.toString()};s.search=new URLSearchParams(i).toString(),this.fetcher(s.toString(),{signal:this.abortController.signal}).then(r=>{if(!r.ok)throw new Error("Network error");return r.json()}).then(r=>this.mapResponseToState(r)).catch(r=>{r.name!=="AbortError"&&this.updateState({isError:!0,isLoading:!1})})}mapResponseToState(e){let t={stage:e.stage,isLoading:!1},s=!1,i=null,r=e.suggestions||[],a=[],p=new Set;for(let l of r){let u=`${l.label}|${l.subtitle||""}|${JSON.stringify(l.value||{})}`;p.has(u)||(p.add(u),a.push(l))}if(e.stage==="mixed"?(t.cities=e.cities||[],t.streets=e.streets||[],t.suggestions=[]):(t.suggestions=a,t.cities=[],t.streets=[],e.stage==="final"&&a.length===1&&(s=!0,i=a[0])),t.isValid=e.stage==="final",s&&i){t.query=i.label,t.suggestions=[],t.cities=[],t.streets=[],t.isValid=!0,this.updateState(t);let l=typeof i.value=="object"?i.value:i.label;this.onSelect(l)}else this.updateState(t)}updateQueryAndFetch(e){this.updateState({query:e,suggestions:[],cities:[],streets:[]}),this.updateState({isLoading:!0,isValid:!1}),this.debouncedFetch(e),setTimeout(()=>{this.isSelecting=!1},0)}replaceLastSegment(e,t){let s=e.lastIndexOf(",");return s===-1?t:`${e.slice(0,s+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({...h,query:this.state.query})}updateState(e){this.state={...this.state,...e},this.onStateChange(this.state)}debounce(e,t){let s,i=(...r)=>{s&&clearTimeout(s),s=setTimeout(()=>e.apply(this,r),t)};return i.cancel=()=>{s&&(clearTimeout(s),s=void 0)},i}};var b=`
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.08);
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: 10px 16px;
100
+ padding: 12px 16px;
44
101
  cursor: pointer;
45
102
  display: flex;
46
103
  flex-direction: row;
47
104
  align-items: center;
48
- color: #000000;
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: #f5f5f5;
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: #404040;
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: #a3a3a3;
129
+ color: #9ca3af;
73
130
  padding-left: 8px;
74
131
  }
75
132
  .pro6pp-no-results {
76
- padding: 12px;
77
- color: #555555;
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-loader {
84
- position: absolute;
85
- right: 12px;
86
- top: 50%;
87
- transform: translateY(-50%);
88
- width: 16px;
89
- height: 16px;
90
- border: 2px solid #e0e0e0;
91
- border-top-color: #404040;
92
- border-radius: 50%;
93
- animation: pro6pp-spin 0.6s linear infinite;
94
- pointer-events: none;
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: translateY(-50%) rotate(360deg); }
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: string;
97
+ authKey?: string;
95
98
  /**
96
99
  * The country to perform address lookups in.
97
100
  */
98
101
  country: CountryCode;
99
102
  /**
100
- * Base URL for the Pro6PP API.
101
- * @default 'https://api.pro6pp.nl/v2'
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
- * Maximum number of suggestions to request from the API.
111
- * @default 1000
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 apiUrl;
144
- private limit;
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): void;
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.08);\n max-height: 300px;\n overflow-y: auto;\n list-style: none !important;\n padding: 0 !important;\n margin: 0 !important;\n }\n .pro6pp-item {\n padding: 10px 16px;\n cursor: pointer;\n display: flex;\n flex-direction: row;\n align-items: center;\n color: #000000;\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: #f5f5f5;\n }\n .pro6pp-item__label {\n font-weight: 500;\n flex-shrink: 0;\n }\n .pro6pp-item__subtitle {\n font-size: 14px;\n color: #404040;\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: #a3a3a3;\n padding-left: 8px;\n }\n .pro6pp-no-results {\n padding: 12px;\n color: #555555;\n font-size: 14px;\n text-align: center;\n user-select: none;\n pointer-events: none;\n }\n .pro6pp-loader {\n position: absolute;\n right: 12px;\n top: 50%;\n transform: translateY(-50%);\n width: 16px;\n height: 16px;\n border: 2px solid #e0e0e0;\n border-top-color: #404040;\n border-radius: 50%;\n animation: pro6pp-spin 0.6s linear infinite;\n pointer-events: none;\n }\n @keyframes pro6pp-spin {\n to { transform: translateY(-50%) rotate(360deg); }\n }\n";
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: string;
97
+ authKey?: string;
95
98
  /**
96
99
  * The country to perform address lookups in.
97
100
  */
98
101
  country: CountryCode;
99
102
  /**
100
- * Base URL for the Pro6PP API.
101
- * @default 'https://api.pro6pp.nl/v2'
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
- * Maximum number of suggestions to request from the API.
111
- * @default 1000
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 apiUrl;
144
- private limit;
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): void;
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.08);\n max-height: 300px;\n overflow-y: auto;\n list-style: none !important;\n padding: 0 !important;\n margin: 0 !important;\n }\n .pro6pp-item {\n padding: 10px 16px;\n cursor: pointer;\n display: flex;\n flex-direction: row;\n align-items: center;\n color: #000000;\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: #f5f5f5;\n }\n .pro6pp-item__label {\n font-weight: 500;\n flex-shrink: 0;\n }\n .pro6pp-item__subtitle {\n font-size: 14px;\n color: #404040;\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: #a3a3a3;\n padding-left: 8px;\n }\n .pro6pp-no-results {\n padding: 12px;\n color: #555555;\n font-size: 14px;\n text-align: center;\n user-select: none;\n pointer-events: none;\n }\n .pro6pp-loader {\n position: absolute;\n right: 12px;\n top: 50%;\n transform: translateY(-50%);\n width: 16px;\n height: 16px;\n border: 2px solid #e0e0e0;\n border-top-color: #404040;\n border-radius: 50%;\n animation: pro6pp-spin 0.6s linear infinite;\n pointer-events: none;\n }\n @keyframes pro6pp-spin {\n to { transform: translateY(-50%) rotate(360deg); }\n }\n";
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 };
@@ -1,4 +1,4 @@
1
- "use strict";var Pro6PPCore=(()=>{var c=Object.defineProperty;var y=Object.getOwnPropertyDescriptor;var v=Object.getOwnPropertyNames;var I=Object.prototype.hasOwnProperty;var C=(n,e,t)=>e in n?c(n,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):n[e]=t;var T=(n,e)=>{for(var t in e)c(n,t,{get:e[t],enumerable:!0})},w=(n,e,t,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of v(e))!I.call(n,i)&&i!==t&&c(n,i,{get:()=>e[i],enumerable:!(s=y(e,i))||s.enumerable});return n};var _=n=>w(c({},"__esModule",{value:!0}),n);var o=(n,e,t)=>C(n,typeof e!="symbol"?e+"":e,t);var F={};T(F,{DEFAULT_STYLES:()=>b,INITIAL_STATE:()=>h,InferCore:()=>g});var d={API_URL:"https://api.pro6pp.nl/v2",LIMIT:1e3,DEBOUNCE_MS:150,MIN_DEBOUNCE_MS:50},m={DIGITS_1_3:/^[0-9]{1,3}$/},h={query:"",stage:null,cities:[],streets:[],suggestions:[],isValid:!1,isError:!1,isLoading:!1,selectedSuggestionIndex:-1},g=class{constructor(e){o(this,"country");o(this,"authKey");o(this,"apiUrl");o(this,"limit");o(this,"fetcher");o(this,"onStateChange");o(this,"onSelect");o(this,"state");o(this,"abortController",null);o(this,"debouncedFetch");o(this,"isSelecting",!1);this.country=e.country,this.authKey=e.authKey,this.apiUrl=e.apiUrl||d.API_URL,this.limit=e.limit||d.LIMIT,this.fetcher=e.fetcher||((i,r)=>fetch(i,r)),this.onStateChange=e.onStateChange||(()=>{}),this.onSelect=e.onSelect||(()=>{}),this.state={...h};let t=e.debounceMs!==void 0?e.debounceMs:d.DEBOUNCE_MS,s=Math.max(t,d.MIN_DEBOUNCE_MS);this.debouncedFetch=this.debounce(i=>this.executeFetch(i),s)}handleInput(e){if(this.isSelecting){this.isSelecting=!1;return}let t=this.state.stage==="final"&&e!==this.state.query;this.updateState({query:e,isValid:!1,isLoading:!!e.trim(),selectedSuggestionIndex:-1}),t&&this.onSelect(null),this.debouncedFetch(e)}handleKeyDown(e){let t=e.target;if(!t)return;let s=this.state.cities.length+this.state.streets.length+this.state.suggestions.length;if(s>0){if(e.key==="ArrowDown"){e.preventDefault();let r=this.state.selectedSuggestionIndex+1;r>=s&&(r=0),this.updateState({selectedSuggestionIndex:r});return}if(e.key==="ArrowUp"){e.preventDefault();let r=this.state.selectedSuggestionIndex-1;r<0&&(r=s-1),this.updateState({selectedSuggestionIndex:r});return}if(e.key==="Enter"&&this.state.selectedSuggestionIndex>=0){e.preventDefault();let a=[...this.state.cities,...this.state.streets,...this.state.suggestions][this.state.selectedSuggestionIndex];a&&(this.selectItem(a),this.updateState({selectedSuggestionIndex:-1}));return}}let i=t.value;if(e.key===" "&&this.shouldAutoInsertComma(i)){e.preventDefault();let r=`${i.trim()}, `;this.updateQueryAndFetch(r)}}selectItem(e){this.debouncedFetch.cancel(),this.abortController&&this.abortController.abort();let t=typeof e=="string"?e:e.label,s=t;typeof e!="string"&&typeof e.value=="string"&&(s=e.value);let i=typeof e!="string"&&typeof e.value=="object"?e.value:void 0,r=!!i&&Object.keys(i).length>0;if(this.isSelecting=!0,this.state.stage==="final"||r){let p=t;if(i&&Object.keys(i).length>0){let{street:l,street_number:u,house_number:x,city:f}=i,S=u||x;l&&S&&f&&(p=`${l} ${S}, ${f}`)}this.finishSelection(p,i);return}let a=typeof e!="string"?e.subtitle:null;this.processSelection(s,a)}shouldAutoInsertComma(e){if(!e.includes(",")&&m.DIGITS_1_3.test(e.trim()))return!0;if(this.state.stage==="house_number"){let s=this.getCurrentFragment(e);return m.DIGITS_1_3.test(s)}return!1}finishSelection(e,t){this.updateState({query:e,suggestions:[],cities:[],streets:[],isValid:!0,stage:"final"}),this.onSelect(t||e),setTimeout(()=>{this.isSelecting=!1},0)}processSelection(e,t){let{stage:s,query:i}=this.state,r=i;if(t&&(s==="city"||s==="street"||s==="mixed")){if(s==="city")r=`${t}, ${e}, `;else{let u=this.getQueryPrefix(i);r=u?`${u} ${e}, ${t}, `:`${e}, ${t}, `}this.updateQueryAndFetch(r);return}if(s==="direct"||s==="addition"){this.finishSelection(e);return}!i.includes(",")&&(s==="city"||s==="street"||s==="house_number_first")?r=`${e}, `:(r=this.replaceLastSegment(i,e),s!=="house_number"&&(r+=", ")),this.updateQueryAndFetch(r)}executeFetch(e){let t=(e||"").toString();if(!t.trim()){this.abortController?.abort(),this.resetState();return}this.updateState({isError:!1}),this.abortController&&this.abortController.abort(),this.abortController=new AbortController;let s=new URL(`${this.apiUrl}/infer/${this.country.toLowerCase()}`),i={authKey:this.authKey,query:t,limit:this.limit.toString()};s.search=new URLSearchParams(i).toString(),this.fetcher(s.toString(),{signal:this.abortController.signal}).then(r=>{if(!r.ok)throw new Error("Network error");return r.json()}).then(r=>this.mapResponseToState(r)).catch(r=>{r.name!=="AbortError"&&this.updateState({isError:!0,isLoading:!1})})}mapResponseToState(e){let t={stage:e.stage,isLoading:!1},s=!1,i=null,r=e.suggestions||[],a=[],p=new Set;for(let l of r){let u=`${l.label}|${l.subtitle||""}|${JSON.stringify(l.value||{})}`;p.has(u)||(p.add(u),a.push(l))}if(e.stage==="mixed"?(t.cities=e.cities||[],t.streets=e.streets||[],t.suggestions=[]):(t.suggestions=a,t.cities=[],t.streets=[],e.stage==="final"&&a.length===1&&(s=!0,i=a[0])),t.isValid=e.stage==="final",s&&i){t.query=i.label,t.suggestions=[],t.cities=[],t.streets=[],t.isValid=!0,this.updateState(t);let l=typeof i.value=="object"?i.value:i.label;this.onSelect(l)}else this.updateState(t)}updateQueryAndFetch(e){this.updateState({query:e,suggestions:[],cities:[],streets:[]}),this.updateState({isLoading:!0,isValid:!1}),this.debouncedFetch(e),setTimeout(()=>{this.isSelecting=!1},0)}replaceLastSegment(e,t){let s=e.lastIndexOf(",");return s===-1?t:`${e.slice(0,s+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({...h,query:this.state.query})}updateState(e){this.state={...this.state,...e},this.onStateChange(this.state)}debounce(e,t){let s,i=(...r)=>{s&&clearTimeout(s),s=setTimeout(()=>e.apply(this,r),t)};return i.cancel=()=>{s&&(clearTimeout(s),s=void 0)},i}};var b=`
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.08);
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: 10px 16px;
100
+ padding: 12px 16px;
44
101
  cursor: pointer;
45
102
  display: flex;
46
103
  flex-direction: row;
47
104
  align-items: center;
48
- color: #000000;
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: #f5f5f5;
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: #404040;
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: #a3a3a3;
129
+ color: #9ca3af;
73
130
  padding-left: 8px;
74
131
  }
75
132
  .pro6pp-no-results {
76
- padding: 12px;
77
- color: #555555;
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-loader {
84
- position: absolute;
85
- right: 12px;
86
- top: 50%;
87
- transform: translateY(-50%);
88
- width: 16px;
89
- height: 16px;
90
- border: 2px solid #e0e0e0;
91
- border-top-color: #404040;
92
- border-radius: 50%;
93
- animation: pro6pp-spin 0.6s linear infinite;
94
- pointer-events: none;
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: translateY(-50%) rotate(360deg); }
156
+ to { transform: rotate(360deg); }
98
157
  }
99
- `;return _(F);})();
158
+ `;return T(A);})();
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- var b=Object.defineProperty;var x=(u,e,t)=>e in u?b(u,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):u[e]=t;var n=(u,e,t)=>x(u,typeof e!="symbol"?e+"":e,t);var c={API_URL:"https://api.pro6pp.nl/v2",LIMIT:1e3,DEBOUNCE_MS:150,MIN_DEBOUNCE_MS:50},g={DIGITS_1_3:/^[0-9]{1,3}$/},f={query:"",stage:null,cities:[],streets:[],suggestions:[],isValid:!1,isError:!1,isLoading:!1,selectedSuggestionIndex:-1},S=class{constructor(e){n(this,"country");n(this,"authKey");n(this,"apiUrl");n(this,"limit");n(this,"fetcher");n(this,"onStateChange");n(this,"onSelect");n(this,"state");n(this,"abortController",null);n(this,"debouncedFetch");n(this,"isSelecting",!1);this.country=e.country,this.authKey=e.authKey,this.apiUrl=e.apiUrl||c.API_URL,this.limit=e.limit||c.LIMIT,this.fetcher=e.fetcher||((r,i)=>fetch(r,i)),this.onStateChange=e.onStateChange||(()=>{}),this.onSelect=e.onSelect||(()=>{}),this.state={...f};let t=e.debounceMs!==void 0?e.debounceMs:c.DEBOUNCE_MS,s=Math.max(t,c.MIN_DEBOUNCE_MS);this.debouncedFetch=this.debounce(r=>this.executeFetch(r),s)}handleInput(e){if(this.isSelecting){this.isSelecting=!1;return}let t=this.state.stage==="final"&&e!==this.state.query;this.updateState({query:e,isValid:!1,isLoading:!!e.trim(),selectedSuggestionIndex:-1}),t&&this.onSelect(null),this.debouncedFetch(e)}handleKeyDown(e){let t=e.target;if(!t)return;let s=this.state.cities.length+this.state.streets.length+this.state.suggestions.length;if(s>0){if(e.key==="ArrowDown"){e.preventDefault();let i=this.state.selectedSuggestionIndex+1;i>=s&&(i=0),this.updateState({selectedSuggestionIndex:i});return}if(e.key==="ArrowUp"){e.preventDefault();let i=this.state.selectedSuggestionIndex-1;i<0&&(i=s-1),this.updateState({selectedSuggestionIndex:i});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 r=t.value;if(e.key===" "&&this.shouldAutoInsertComma(r)){e.preventDefault();let i=`${r.trim()}, `;this.updateQueryAndFetch(i)}}selectItem(e){this.debouncedFetch.cancel(),this.abortController&&this.abortController.abort();let t=typeof e=="string"?e:e.label,s=t;typeof e!="string"&&typeof e.value=="string"&&(s=e.value);let r=typeof e!="string"&&typeof e.value=="object"?e.value:void 0,i=!!r&&Object.keys(r).length>0;if(this.isSelecting=!0,this.state.stage==="final"||i){let p=t;if(r&&Object.keys(r).length>0){let{street:a,street_number:l,house_number:m,city:d}=r,h=l||m;a&&h&&d&&(p=`${a} ${h}, ${d}`)}this.finishSelection(p,r);return}let o=typeof e!="string"?e.subtitle:null;this.processSelection(s,o)}shouldAutoInsertComma(e){if(!e.includes(",")&&g.DIGITS_1_3.test(e.trim()))return!0;if(this.state.stage==="house_number"){let s=this.getCurrentFragment(e);return g.DIGITS_1_3.test(s)}return!1}finishSelection(e,t){this.updateState({query:e,suggestions:[],cities:[],streets:[],isValid:!0,stage:"final"}),this.onSelect(t||e),setTimeout(()=>{this.isSelecting=!1},0)}processSelection(e,t){let{stage:s,query:r}=this.state,i=r;if(t&&(s==="city"||s==="street"||s==="mixed")){if(s==="city")i=`${t}, ${e}, `;else{let l=this.getQueryPrefix(r);i=l?`${l} ${e}, ${t}, `:`${e}, ${t}, `}this.updateQueryAndFetch(i);return}if(s==="direct"||s==="addition"){this.finishSelection(e);return}!r.includes(",")&&(s==="city"||s==="street"||s==="house_number_first")?i=`${e}, `:(i=this.replaceLastSegment(r,e),s!=="house_number"&&(i+=", ")),this.updateQueryAndFetch(i)}executeFetch(e){let t=(e||"").toString();if(!t.trim()){this.abortController?.abort(),this.resetState();return}this.updateState({isError:!1}),this.abortController&&this.abortController.abort(),this.abortController=new AbortController;let s=new URL(`${this.apiUrl}/infer/${this.country.toLowerCase()}`),r={authKey:this.authKey,query:t,limit:this.limit.toString()};s.search=new URLSearchParams(r).toString(),this.fetcher(s.toString(),{signal:this.abortController.signal}).then(i=>{if(!i.ok)throw new Error("Network error");return i.json()}).then(i=>this.mapResponseToState(i)).catch(i=>{i.name!=="AbortError"&&this.updateState({isError:!0,isLoading:!1})})}mapResponseToState(e){let t={stage:e.stage,isLoading:!1},s=!1,r=null,i=e.suggestions||[],o=[],p=new Set;for(let a of i){let l=`${a.label}|${a.subtitle||""}|${JSON.stringify(a.value||{})}`;p.has(l)||(p.add(l),o.push(a))}if(e.stage==="mixed"?(t.cities=e.cities||[],t.streets=e.streets||[],t.suggestions=[]):(t.suggestions=o,t.cities=[],t.streets=[],e.stage==="final"&&o.length===1&&(s=!0,r=o[0])),t.isValid=e.stage==="final",s&&r){t.query=r.label,t.suggestions=[],t.cities=[],t.streets=[],t.isValid=!0,this.updateState(t);let a=typeof r.value=="object"?r.value:r.label;this.onSelect(a)}else this.updateState(t)}updateQueryAndFetch(e){this.updateState({query:e,suggestions:[],cities:[],streets:[]}),this.updateState({isLoading:!0,isValid:!1}),this.debouncedFetch(e),setTimeout(()=>{this.isSelecting=!1},0)}replaceLastSegment(e,t){let s=e.lastIndexOf(",");return s===-1?t:`${e.slice(0,s+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({...f,query:this.state.query})}updateState(e){this.state={...this.state,...e},this.onStateChange(this.state)}debounce(e,t){let s,r=(...i)=>{s&&clearTimeout(s),s=setTimeout(()=>e.apply(this,i),t)};return r.cancel=()=>{s&&(clearTimeout(s),s=void 0)},r}};var y=`
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.08);
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: 10px 16px;
100
+ padding: 12px 16px;
44
101
  cursor: pointer;
45
102
  display: flex;
46
103
  flex-direction: row;
47
104
  align-items: center;
48
- color: #000000;
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: #f5f5f5;
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: #404040;
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: #a3a3a3;
129
+ color: #9ca3af;
73
130
  padding-left: 8px;
74
131
  }
75
132
  .pro6pp-no-results {
76
- padding: 12px;
77
- color: #555555;
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-loader {
84
- position: absolute;
85
- right: 12px;
86
- top: 50%;
87
- transform: translateY(-50%);
88
- width: 16px;
89
- height: 16px;
90
- border: 2px solid #e0e0e0;
91
- border-top-color: #404040;
92
- border-radius: 50%;
93
- animation: pro6pp-spin 0.6s linear infinite;
94
- pointer-events: none;
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: translateY(-50%) rotate(360deg); }
156
+ to { transform: rotate(360deg); }
98
157
  }
99
- `;export{y as DEFAULT_STYLES,f as INITIAL_STATE,S as InferCore};
158
+ `;export{y as DEFAULT_STYLES,b as INITIAL_STATE,m as InferCore};
package/package.json CHANGED
@@ -22,7 +22,7 @@
22
22
  "url": "https://github.com/pro6pp/infer-sdk/issues"
23
23
  },
24
24
  "sideEffects": false,
25
- "version": "0.0.2-beta.6",
25
+ "version": "0.0.2-beta.8",
26
26
  "main": "./dist/index.cjs",
27
27
  "module": "./dist/index.js",
28
28
  "types": "./dist/index.d.ts",