@pro6pp/infer-js 0.0.2-beta.8 → 0.1.0-beta.18

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/README.md CHANGED
@@ -70,7 +70,12 @@ const inputElement = document.getElementById('address-input');
70
70
  attach(inputElement, {
71
71
  authKey: 'YOUR_AUTH_KEY',
72
72
  country: 'NL',
73
- onSelect: (result) => {
73
+ // triggered whenever the internal state changes
74
+ onStateChange: function (state) {
75
+ console.log('Current State:', state);
76
+ },
77
+ // triggered when the user selects a final address
78
+ onSelect: function (result) {
74
79
  console.log('Selected Address:', result);
75
80
  },
76
81
  });
@@ -93,13 +98,52 @@ attach(inputElement, {
93
98
 
94
99
  ## Styling
95
100
 
96
- By default, the SDK injects the necessary CSS for the dropdown. If you want to control the styling with your own styles, set `style: 'none'` in the config:
101
+ By default, the SDK injects the necessary CSS for the dropdown. You have several options for styling:
102
+
103
+ Note: the JavaScript bundle still contains the default CSS as a fallback. Importing `@pro6pp/infer-js/styles.css` with `style: 'none'` disables runtime style injection, but does not provide a CSS-free JS bundle.
104
+
105
+ ### Option 1: Use auto-injected styles (default)
106
+
107
+ No extra setup needed. The CSS is embedded in the JS bundle and injected automatically.
108
+
109
+ ### Option 2: Import CSS separately
110
+
111
+ If you prefer to load the CSS as a separate file:
112
+
113
+ ```javascript
114
+ import { attach } from '@pro6pp/infer-js';
115
+ import '@pro6pp/infer-js/styles.css';
116
+
117
+ attach(inputElement, {
118
+ authKey: '...',
119
+ country: 'NL',
120
+ style: 'none', // disable auto-injection since we imported CSS separately
121
+ });
122
+ ```
123
+
124
+ ### Option 3: CDN with separate CSS
125
+
126
+ ```html
127
+ <link rel="stylesheet" href="https://unpkg.com/@pro6pp/infer-js/dist/styles.css" />
128
+ <script src="https://unpkg.com/@pro6pp/infer-js"></script>
129
+ <script>
130
+ Pro6PP.attach('#address-input', {
131
+ authKey: 'YOUR_AUTH_KEY',
132
+ country: 'NL',
133
+ style: 'none', // disable auto-injection since we linked CSS separately
134
+ });
135
+ </script>
136
+ ```
137
+
138
+ ### Option 4: Fully custom styles
139
+
140
+ If you want to control the styling entirely with your own CSS:
97
141
 
98
142
  ```js
99
143
  attach(inputElement, {
100
144
  authKey: '...',
101
145
  country: 'NL',
102
- style: 'none', // disables default styles
146
+ style: 'none', // disables default style injection
103
147
  });
104
148
  ```
105
149
 
@@ -109,7 +153,6 @@ You can then target the following classes in your CSS:
109
153
  | :----------------------- | :-------------------------------------------------------- |
110
154
  | `.pro6pp-wrapper` | The container element wrapping the input and dropdown. |
111
155
  | `.pro6pp-input` | The input element itself. |
112
- | `.pro6pp-loader` | The loading spinner shown during API requests. |
113
156
  | `.pro6pp-dropdown` | The `<ul>` list containing the suggestions. |
114
157
  | `.pro6pp-item` | A single suggestion item (`<li>`). |
115
158
  | `.pro6pp-item--active` | The currently highlighted item (for keyboard navigation). |
@@ -117,3 +160,5 @@ You can then target the following classes in your CSS:
117
160
  | `.pro6pp-item__subtitle` | The secondary text (e.g., city or result count). |
118
161
  | `.pro6pp-item__chevron` | The icon indicating a folder/expandable result. |
119
162
  | `.pro6pp-no-results` | The message shown when no suggestions are found. |
163
+ | `.pro6pp-loader-item` | The list item containing the loading spinner and text. |
164
+ | `.pro6pp-mini-spinner` | The spinner icon inside the loader item. |
package/dist/index.cjs ADDED
@@ -0,0 +1,216 @@
1
+ "use strict";var y=Object.defineProperty,k=Object.defineProperties,$=Object.getOwnPropertyDescriptor,R=Object.getOwnPropertyDescriptors,F=Object.getOwnPropertyNames,L=Object.getOwnPropertySymbols;var T=Object.prototype.hasOwnProperty,H=Object.prototype.propertyIsEnumerable;var I=(o,e,t)=>e in o?y(o,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):o[e]=t,f=(o,e)=>{for(var t in e||(e={}))T.call(e,t)&&I(o,t,e[t]);if(L)for(var t of L(e))H.call(e,t)&&I(o,t,e[t]);return o},m=(o,e)=>k(o,R(e));var N=(o,e)=>{for(var t in e)y(o,t,{get:e[t],enumerable:!0})},B=(o,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of F(e))!T.call(o,s)&&s!==t&&y(o,s,{get:()=>e[s],enumerable:!(n=$(e,s))||n.enumerable});return o};var O=o=>B(y({},"__esModule",{value:!0}),o);var K={};N(K,{InferJS:()=>v,attach:()=>q});module.exports=O(K);function _(o){return o.toLowerCase().trim()}function U(o){return o.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function V(o,e){let t=_(o),n=_(e);if(n.includes(" "))return t.indexOf(n);let r=new RegExp(`(?:^|[,\\s])${U(n)}(?:$|[,\\s])`,"g").exec(t);if(r){let i=r.index,p=t[i];return p===","||p===" "?i+1:i}return-1}function P(o,e){let t=[],n=[];e.street&&n.push({value:e.street,type:"street"}),e.city&&n.push({value:e.city,type:"city"}),e.postcode&&n.push({value:e.postcode,type:"postcode"}),e.street_number!==void 0&&e.street_number!==null&&n.push({value:String(e.street_number),type:"street_number"}),e.addition&&n.push({value:e.addition,type:"addition"});for(let s of n){let r=V(o,s.value);r!==-1&&t.push({type:s.type,value:s.value,position:r})}return t.sort((s,r)=>s.position-r.position),t}function M(o,e){if(!e||!o)return"";let t=P(o,e),n=new Set(t.map(i=>i.type)),s=[];for(let i of t)s.push(i.value);let r=["street","street_number","addition","postcode","city"];for(let i of r){if(n.has(i))continue;let p;switch(i){case"street":p=e.street;break;case"city":p=e.city;break;case"street_number":p=e.street_number!==void 0?String(e.street_number):void 0;break;case"postcode":p=e.postcode;break;case"addition":p=e.addition;break}p&&s.push(p)}return s.join(", ")}var b={API_URL:"https://api.pro6pp.nl/v2",LIMIT:20,DEBOUNCE_MS:150,MIN_DEBOUNCE_MS:50,MAX_RETRIES:0},w={DIGITS_1_3:/^[0-9]{1,3}$/,STREET_NUMBER_PREFIX:/^(\d+)\s*,\s*$/},A={query:"",stage:null,cities:[],streets:[],suggestions:[],isValid:!1,value:null,isError:!1,isLoading:!1,hasMore:!1,selectedSuggestionIndex:-1},x=class{constructor(e){this.abortController=null;this.country=e.country,this.authKey=e.authKey,this.explicitApiUrl=e.apiUrl,this.baseLimit=e.limit||b.LIMIT,this.currentLimit=this.baseLimit,this.language=e.language;let t=e.maxRetries!==void 0?e.maxRetries:b.MAX_RETRIES;this.maxRetries=Math.max(0,Math.min(t,10)),this.fetcher=e.fetcher||((r,i)=>fetch(r,i)),this.onStateChange=e.onStateChange||(()=>{}),this.onSelect=e.onSelect||(()=>{}),this.state=f({},A);let n=e.debounceMs!==void 0?e.debounceMs:b.DEBOUNCE_MS,s=Math.max(n,b.MIN_DEBOUNCE_MS);this.debouncedFetch=this.debounce(r=>this.executeFetch(r),s)}handleInput(e){this.currentLimit=this.baseLimit;let t=this.state.stage==="final"&&e!==this.state.query;this.updateState({query:e,isValid:!1,value:null,isLoading:!!e.trim(),selectedSuggestionIndex:-1,hasMore:!1,stage:t?null:this.state.stage}),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 n=this.state.cities.length+this.state.streets.length+this.state.suggestions.length;if(n>0){if(e.key==="ArrowDown"){e.preventDefault();let r=this.state.selectedSuggestionIndex+1;r>=n&&(r=0),this.updateState({selectedSuggestionIndex:r});return}if(e.key==="ArrowUp"){e.preventDefault();let r=this.state.selectedSuggestionIndex-1;r<0&&(r=n-1),this.updateState({selectedSuggestionIndex:r});return}if(e.key==="Enter"&&this.state.selectedSuggestionIndex>=0){e.preventDefault();let i=[...this.state.cities,...this.state.streets,...this.state.suggestions][this.state.selectedSuggestionIndex];i&&(this.selectItem(i),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,n=t;typeof e!="string"&&typeof e.value=="string"&&(n=e.value);let s=typeof e!="string"&&typeof e.value=="object"?e.value:void 0,r=!!s&&Object.keys(s).length>0;if(this.state.stage==="final"||r){let p=t;if(s&&Object.keys(s).length>0){let{street:u,street_number:a,postcode:c,city:l,addition:h}=s;if(u&&a&&l){let g=h?` ${h}`:"",d=c?`${c}, `:"";p=`${u}, ${a}${g}, ${d}${l}`}}return this.finishSelection(p,s),!0}let i=typeof e!="string"?e.subtitle:null;return this.processSelection(n,i),!1}shouldAutoInsertComma(e){if(!e.includes(",")&&w.DIGITS_1_3.test(e.trim()))return!0;if(this.state.stage==="street_number"){let n=this.getCurrentFragment(e);return w.DIGITS_1_3.test(n)}return!1}finishSelection(e,t){this.updateState({query:e,suggestions:[],cities:[],streets:[],isValid:!0,value:t||null,stage:"final",hasMore:!1}),this.onSelect(t||e)}processSelection(e,t){let{stage:n,query:s}=this.state,r=s;if(t&&(n==="city"||n==="street"||n==="mixed")){if(n==="city")r=`${t}, ${e}, `;else{let a=this.getQueryPrefix(s),c=!a||!a.includes(t),l=a;if(a&&t){let h=a.match(w.STREET_NUMBER_PREFIX);if(h){let g=h[1];t.startsWith(g)&&(l="")}}c?r=l?`${l} ${e}, ${t}, `:`${e}, ${t}, `:r=l?`${l} ${e}, `:`${e}, `}this.updateQueryAndFetch(r);return}if(n==="direct"||n==="addition"){this.finishSelection(e);return}!s.includes(",")&&(n==="city"||n==="street"||n==="street_number_first")?r=`${e}, `:(r=this.replaceLastSegment(s,e),n!=="street_number"&&(r+=", ")),this.updateQueryAndFetch(r)}executeFetch(e,t=0){var a,c;let n=(e||"").toString();if(!n.trim()){(a=this.abortController)==null||a.abort(),this.resetState();return}t===0&&(this.updateState({isError:!1}),this.abortController&&this.abortController.abort(),this.abortController=new AbortController);let s=(c=this.abortController)==null?void 0:c.signal,r=this.explicitApiUrl?this.explicitApiUrl:`${b.API_URL}/infer/${this.country.toLowerCase()}`,i=new URLSearchParams({query:n,limit:this.currentLimit.toString()});this.explicitApiUrl&&i.append("country",this.country.toLowerCase()),this.authKey&&i.set("authKey",this.authKey),this.language&&i.set("language",this.language);let p=r.includes("?")?"&":"?",u=`${r}${p}${i.toString()}`;this.fetcher(u,{signal:s}).then(l=>{if(!l.ok){if(t<this.maxRetries&&(l.status>=500||l.status===429))return this.retry(e,t,s);throw new Error("Network error")}return l.json()}).then(l=>{l&&this.mapResponseToState(l)}).catch(l=>{if(l.name!=="AbortError"){if(t<this.maxRetries)return this.retry(e,t,s);this.updateState({isError:!0,isLoading:!1})}})}retry(e,t,n){if(n!=null&&n.aborted)return;let s=Math.pow(2,t)*200;setTimeout(()=>{n!=null&&n.aborted||this.executeFetch(e,t+1)},s)}mapResponseToState(e){var p,u,a,c;let t={stage:e.stage,isLoading:!1},n=e.suggestions||[],s=[],r=new Set;for(let l of n){let h=`${l.label}|${l.subtitle||""}|${JSON.stringify(l.value||{})}`;if(!r.has(h)){r.add(h);let g=this.reformatSuggestionLabel(l);s.push(g)}}let i=s.length+(((p=e.cities)==null?void 0:p.length)||0)+(((u=e.streets)==null?void 0:u.length)||0);t.hasMore=i>=this.currentLimit,e.stage==="mixed"?(t.cities=e.cities||[],t.streets=e.streets||[],((a=t.cities)==null?void 0:a.length)===0&&((c=t.streets)==null?void 0:c.length)===0?t.suggestions=s:t.suggestions=[]):(t.suggestions=s,t.cities=[],t.streets=[]),t.isValid=e.stage==="final",this.updateState(t),t.isValid&&s.length===1&&this.selectItem(s[0])}reformatSuggestionLabel(e){if(!e.value||typeof e.value=="string")return e;let t=e.value;if(!t.street||!t.city)return e;let n=M(this.state.query,t);return n?m(f({},e),{label:n}):e}updateQueryAndFetch(e){this.updateState({query:e,suggestions:[],cities:[],streets:[],isValid:!1,value:null,isLoading:!0,hasMore:!1}),this.debouncedFetch(e)}replaceLastSegment(e,t){let n=e.lastIndexOf(",");return n===-1?t:`${e.slice(0,n+1)} ${t}`.trim()}getQueryPrefix(e){let t=e.lastIndexOf(",");return t===-1?"":e.slice(0,t+1).trimEnd()}getCurrentFragment(e){var t;return((t=e.split(",").slice(-1)[0])!=null?t:"").trim()}resetState(){this.updateState(m(f({},A),{query:this.state.query}))}updateState(e){this.state=f(f({},this.state),e),this.onStateChange(this.state)}debounce(e,t){let n,s=(...r)=>{n&&clearTimeout(n),n=setTimeout(()=>e.apply(this,r),t)};return s.cancel=()=>{n&&(clearTimeout(n),n=void 0)},s}};function z(o){if(o.length===0)return o;let e=[];for(let t of o){let n=e[e.length-1];n&&n.match===t.match?n.text+=t.text:e.push({text:t.text,match:t.match})}return e}function D(o,e){if(!e||!o)return[{text:o,match:!1}];let t=[],n=o.toLowerCase(),s=e.toLowerCase(),r=0,i=0;for(let a=0;a<o.length;a++){if(!(r<e.length&&n[a]===s[r]))continue;a>i&&t.push({text:o.slice(i,a),match:!1}),t.push({text:o[a],match:!0}),r++,i=a+1}return i<o.length&&t.push({text:o.slice(i),match:!1}),r===e.length?z(t):[{text:o,match:!1}]}var C=`
2
+ .pro6pp-wrapper {
3
+ position: relative;
4
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
5
+ box-sizing: border-box;
6
+ width: 100%;
7
+ -webkit-tap-highlight-color: transparent;
8
+ }
9
+ .pro6pp-wrapper * {
10
+ box-sizing: border-box;
11
+ }
12
+ .pro6pp-input {
13
+ width: 100%;
14
+ padding: 12px 14px;
15
+ padding-right: 48px;
16
+ border: 1px solid #e0e0e0;
17
+ border-radius: 8px;
18
+ font-size: 16px;
19
+ line-height: 1.5;
20
+ appearance: none;
21
+ transition: border-color 0.2s, box-shadow 0.2s;
22
+ }
23
+
24
+ .pro6pp-input::placeholder {
25
+ font-size: 16px;
26
+ color: #a3a3a3;
27
+ }
28
+
29
+ .pro6pp-input:focus {
30
+ outline: none;
31
+ border-color: #3b82f6;
32
+ box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
33
+ }
34
+
35
+ .pro6pp-input-addons {
36
+ position: absolute;
37
+ right: 4px;
38
+ top: 0;
39
+ bottom: 0;
40
+ display: flex;
41
+ align-items: center;
42
+ pointer-events: none;
43
+ }
44
+ .pro6pp-input-addons > * {
45
+ pointer-events: auto;
46
+ }
47
+
48
+ .pro6pp-clear-button {
49
+ background: none;
50
+ border: none;
51
+ width: 32px;
52
+ height: 32px;
53
+ cursor: pointer;
54
+ color: #a3a3a3;
55
+ display: flex;
56
+ align-items: center;
57
+ justify-content: center;
58
+ border-radius: 50%;
59
+ transition: color 0.2s, background-color 0.2s;
60
+ touch-action: manipulation;
61
+ }
62
+
63
+ @media (hover: hover) {
64
+ .pro6pp-clear-button:hover {
65
+ color: #1f2937;
66
+ background-color: #f3f4f6;
67
+ }
68
+ }
69
+
70
+ .pro6pp-clear-button:active {
71
+ background-color: #f3f4f6;
72
+ }
73
+
74
+ .pro6pp-dropdown {
75
+ position: absolute;
76
+ top: 100%;
77
+ left: 0;
78
+ right: 0;
79
+ margin-top: 4px;
80
+ background: #ffffff;
81
+ border: 1px solid #e5e7eb;
82
+ border-radius: 6px;
83
+ box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
84
+ z-index: 9999;
85
+ padding: 0;
86
+ max-height: 280px;
87
+ overflow-y: auto;
88
+ display: flex;
89
+ flex-direction: column;
90
+ }
91
+
92
+ @media (max-height: 500px) {
93
+ .pro6pp-dropdown {
94
+ max-height: 180px;
95
+ }
96
+ }
97
+
98
+ .pro6pp-list {
99
+ list-style: none;
100
+ margin: 0;
101
+ padding: 0;
102
+ width: 100%;
103
+ }
104
+
105
+ .pro6pp-item {
106
+ padding: 12px 14px;
107
+ cursor: pointer;
108
+ display: flex;
109
+ align-items: center;
110
+ font-size: 15px;
111
+ line-height: 1.4;
112
+ color: #374151;
113
+ border-bottom: 1px solid #f3f4f6;
114
+ transition: background-color 0.1s;
115
+ flex-shrink: 0;
116
+ }
117
+
118
+ .pro6pp-item:last-child {
119
+ border-bottom: none;
120
+ }
121
+
122
+ @media (hover: hover) {
123
+ .pro6pp-item:hover, .pro6pp-item--active {
124
+ background-color: #f9fafb;
125
+ }
126
+ }
127
+
128
+ .pro6pp-item:active {
129
+ background-color: #f3f4f6;
130
+ }
131
+
132
+ .pro6pp-item__label {
133
+ font-weight: 400;
134
+ flex-shrink: 1;
135
+ overflow: hidden;
136
+ text-overflow: ellipsis;
137
+ white-space: nowrap;
138
+ }
139
+
140
+ .pro6pp-item__label--match {
141
+ font-weight: 520;
142
+ }
143
+
144
+ .pro6pp-item__label--unmatched {
145
+ font-weight: 400;
146
+ color: #4b5563;
147
+ }
148
+
149
+ .pro6pp-item__subtitle {
150
+ color: #6b7280;
151
+ flex-shrink: 0;
152
+ }
153
+
154
+ .pro6pp-item__chevron {
155
+ color: #d1d5db;
156
+ display: flex;
157
+ align-items: center;
158
+ margin-left: auto;
159
+ padding-left: 8px;
160
+ }
161
+
162
+ .pro6pp-no-results {
163
+ padding: 24px 16px;
164
+ color: #6b7280;
165
+ font-size: 15px;
166
+ text-align: center;
167
+ }
168
+
169
+ .pro6pp-loader-item {
170
+ padding: 10px 12px;
171
+ color: #6b7280;
172
+ font-size: 0.875rem;
173
+ display: flex;
174
+ align-items: center;
175
+ justify-content: center;
176
+ gap: 8px;
177
+ background-color: #f9fafb;
178
+ border-top: 1px solid #f3f4f6;
179
+ }
180
+
181
+ .pro6pp-mini-spinner {
182
+ width: 14px;
183
+ height: 14px;
184
+ border: 2px solid #e5e7eb;
185
+ border-top-color: #6b7280;
186
+ border-radius: 50%;
187
+ animation: pro6pp-spin 0.6s linear infinite;
188
+ }
189
+
190
+ @media (max-width: 640px) {
191
+ .pro6pp-input {
192
+ font-size: 16px;
193
+ padding: 10px 12px;
194
+ }
195
+ .pro6pp-item {
196
+ padding: 10px 12px;
197
+ font-size: 14px;
198
+ }
199
+ }
200
+
201
+ @keyframes pro6pp-spin {
202
+ to { transform: rotate(360deg); }
203
+ }
204
+ `;var v=class{constructor(e,t){this.isOpen=!1;this.boundHandlers=null;this.isDestroyed=!1;var r;let n=typeof e=="string"?document.querySelector(e):e;if(!n)throw new Error("InferJS: Target element not found.");if(this.noResultsText=t.noResultsText||"No results found",this.loadingText=t.loadingText||"Loading more...",this.showClearButton=t.showClearButton!==!1,this.useDefaultStyles=t.style!=="none",this.useDefaultStyles&&this.injectStyles(),this.wrapper=document.createElement("div"),this.wrapper.className="pro6pp-wrapper",n instanceof HTMLInputElement?(this.input=n,(r=this.input.parentNode)==null||r.insertBefore(this.wrapper,this.input),this.wrapper.appendChild(this.input)):(n.appendChild(this.wrapper),this.input=document.createElement("input"),this.input.type="text",t.placeholder&&(this.input.placeholder=t.placeholder),this.wrapper.appendChild(this.input)),this.input.setAttribute("autocomplete","off"),this.input.setAttribute("autocorrect","off"),this.input.setAttribute("autocapitalize","none"),this.input.setAttribute("spellcheck","false"),this.input.setAttribute("inputmode","search"),this.input.setAttribute("enterkeyhint","search"),this.input.classList.add("pro6pp-input"),t.inputClass){let i=t.inputClass.split(" ");this.input.classList.add(...i)}let s=document.createElement("div");s.className="pro6pp-input-addons",this.wrapper.appendChild(s),this.clearButton=document.createElement("button"),this.clearButton.type="button",this.clearButton.className="pro6pp-clear-button",this.clearButton.setAttribute("aria-label","Clear input"),this.clearButton.style.display="none",this.clearButton.innerHTML=`
205
+ <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
206
+ <line x1="18" y1="6" x2="6" y2="18"></line>
207
+ <line x1="6" y1="6" x2="18" y2="18"></line>
208
+ </svg>
209
+ `,s.appendChild(this.clearButton),this.dropdown=document.createElement("div"),this.dropdown.className="pro6pp-dropdown",this.dropdown.style.display="none",this.wrapper.appendChild(this.dropdown),this.list=document.createElement("ul"),this.list.className="pro6pp-list",this.list.setAttribute("role","listbox"),this.dropdown.appendChild(this.list),this.dropdownLoader=document.createElement("div"),this.dropdownLoader.className="pro6pp-loader-item",this.dropdownLoader.style.display="none",this.dropdownLoader.innerHTML=`
210
+ <div class="pro6pp-mini-spinner"></div>
211
+ <span>${this.loadingText}</span>
212
+ `,this.dropdown.appendChild(this.dropdownLoader),this.core=new x(m(f({},t),{onStateChange:i=>{this.render(i),t.onStateChange&&t.onStateChange(i)},onSelect:i=>{typeof i=="string"?this.input.value=i:i&&typeof i=="object"&&(this.input.value=this.core.state.query),t.onSelect&&t.onSelect(i)}})),this.observer=new IntersectionObserver(i=>{i[0].isIntersecting&&this.core.state.hasMore&&!this.core.state.isLoading&&this.core.loadMore()},{threshold:.1}),this.bindEvents()}get value(){return this.core.state.value||null}set value(e){if(!e)return;let t=e.addition?` ${e.addition}`:"",n=e.postcode?`${e.postcode}, `:"",s=`${e.street}, ${e.street_number}${t}, ${n}${e.city}`;this.core.selectItem({label:s,value:e})}destroy(){this.isDestroyed||(this.isDestroyed=!0,this.boundHandlers&&(this.input.removeEventListener("input",this.boundHandlers.onInput),this.input.removeEventListener("keydown",this.boundHandlers.onKeyDown),this.clearButton.removeEventListener("click",this.boundHandlers.onClearClick),document.removeEventListener("mousedown",this.boundHandlers.onDocumentMouseDown),this.input.removeEventListener("focus",this.boundHandlers.onFocus),this.boundHandlers=null),this.observer.disconnect(),this.wrapper.parentNode&&(this.wrapper.parentNode.insertBefore(this.input,this.wrapper),this.wrapper.remove()),this.input.classList.remove("pro6pp-input"),this.input.value="")}injectStyles(){let e="pro6pp-styles";if(!document.getElementById(e)){let t=document.createElement("style");t.id=e,t.textContent=C,document.head.appendChild(t)}}bindEvents(){this.boundHandlers={onInput:e=>{let t=e.target.value;this.isOpen=!0,this.core.handleInput(t)},onKeyDown:e=>{this.core.handleKeyDown(e)},onClearClick:()=>{this.core.handleInput(""),this.input.focus()},onDocumentMouseDown:e=>{this.wrapper.contains(e.target)||(this.isOpen=!1,this.dropdown.style.display="none")},onFocus:()=>{this.isOpen=!0,this.render(this.core.state)}},this.input.addEventListener("input",this.boundHandlers.onInput),this.input.addEventListener("keydown",this.boundHandlers.onKeyDown),this.clearButton.addEventListener("click",this.boundHandlers.onClearClick),document.addEventListener("mousedown",this.boundHandlers.onDocumentMouseDown),this.input.addEventListener("focus",this.boundHandlers.onFocus)}render(e){this.input.value!==e.query&&(this.input.value=e.query),this.showClearButton&&(this.clearButton.style.display=e.query.length>0?"flex":"none"),this.list.innerHTML="";let t=[...e.cities,...e.streets,...e.suggestions],n=t.length>0,s=!e.isLoading&&!e.isError&&e.query.length>0&&!n&&!e.isValid;if(!(this.isOpen&&(n||e.isLoading||s))){this.dropdown.style.display="none";return}if(this.dropdown.style.display="block",e.isLoading&&n?this.dropdownLoader.style.display="flex":this.dropdownLoader.style.display="none",e.isLoading&&!n){let i=document.createElement("li");i.className="pro6pp-no-results",i.textContent="Searching...",this.list.appendChild(i),this.dropdownLoader.style.display="none";return}if(s){let i=document.createElement("li");i.className="pro6pp-no-results",i.textContent=this.noResultsText,this.list.appendChild(i);return}if(t.forEach((i,p)=>{if(!i.label)return;let u=document.createElement("li");u.className="pro6pp-item",p===e.selectedSuggestionIndex&&u.classList.add("pro6pp-item--active"),u.setAttribute("role","option"),u.setAttribute("aria-selected",p===e.selectedSuggestionIndex?"true":"false");let a=document.createElement("span");a.className="pro6pp-item__label",D(i.label,e.query).forEach(({text:d,match:E})=>{let S=document.createElement("span");S.className=E?"pro6pp-item__label--match":"pro6pp-item__label--unmatched",S.textContent=d,a.appendChild(S)}),u.appendChild(a);let l=i.count!==void 0&&i.count!==null?i.count:"",h=i.subtitle||l;if(h!==""){let d=document.createElement("span");d.className="pro6pp-item__subtitle",d.textContent=`, ${h}`,u.appendChild(d)}if(i.value===void 0||i.value===null){let d=document.createElement("div");d.className="pro6pp-item__chevron",d.innerHTML=`
213
+ <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
214
+ <polyline points="9 18 15 12 9 6"></polyline>
215
+ </svg>
216
+ `,u.appendChild(d)}u.onmousedown=d=>d.preventDefault(),u.onclick=d=>{d.stopPropagation(),this.core.selectItem(i)?(this.isOpen=!1,this.dropdown.style.display="none"):setTimeout(()=>this.input.focus(),0)},this.list.appendChild(u)}),e.hasMore&&!e.isLoading){let i=document.createElement("li");i.style.height="1px",i.style.opacity="0",this.list.appendChild(i),this.observer.observe(i)}}};function q(o,e){return new v(o,e)}0&&(module.exports={InferJS,attach});
@@ -1,4 +1,4 @@
1
- import { InferConfig } from '@pro6pp/infer-core';
1
+ import { InferConfig, AddressValue } from '@pro6pp/infer-core';
2
2
 
3
3
  /**
4
4
  * Configuration options for the JS Infer SDK.
@@ -25,10 +25,10 @@ interface InferJSConfig extends InferConfig {
25
25
  */
26
26
  noResultsText?: string;
27
27
  /**
28
- * The text to show on the load more button.
29
- * @default 'Show more results...'
28
+ * The text to show on the bottom loading indicator.
29
+ * @default 'Loading more...'
30
30
  */
31
- loadMoreText?: string;
31
+ loadingText?: string;
32
32
  /**
33
33
  * If true, shows a clear button when the input is not empty.
34
34
  * @default true
@@ -45,20 +45,37 @@ declare class InferJS {
45
45
  private list;
46
46
  private dropdown;
47
47
  private wrapper;
48
- private loader;
48
+ private dropdownLoader;
49
49
  private clearButton;
50
- private loadMoreButton;
51
50
  private useDefaultStyles;
52
51
  private noResultsText;
53
- private loadMoreText;
52
+ private loadingText;
54
53
  private showClearButton;
55
54
  private isOpen;
55
+ private observer;
56
+ private boundHandlers;
57
+ private isDestroyed;
56
58
  /**
57
59
  * Initializes the Infer logic on a target element.
58
60
  * @param target Either a CSS selector string or a direct HTMLElement.
59
61
  * @param config Configuration options for the API and UI.
60
62
  */
61
63
  constructor(target: string | HTMLElement, config: InferJSConfig);
64
+ /**
65
+ * Retrieves the current selected address value if available.
66
+ * @returns The AddressValue object if valid, otherwise null.
67
+ */
68
+ get value(): AddressValue | null;
69
+ /**
70
+ * Programmatically sets the address value.
71
+ * @param address The address object to set.
72
+ */
73
+ set value(address: AddressValue);
74
+ /**
75
+ * Destroys the InferJS instance, removing all event listeners and DOM elements.
76
+ * Call this before creating a new instance on the same input element.
77
+ */
78
+ destroy(): void;
62
79
  private injectStyles;
63
80
  private bindEvents;
64
81
  private render;
@@ -1,4 +1,4 @@
1
- import { InferConfig } from '@pro6pp/infer-core';
1
+ import { InferConfig, AddressValue } from '@pro6pp/infer-core';
2
2
 
3
3
  /**
4
4
  * Configuration options for the JS Infer SDK.
@@ -25,10 +25,10 @@ interface InferJSConfig extends InferConfig {
25
25
  */
26
26
  noResultsText?: string;
27
27
  /**
28
- * The text to show on the load more button.
29
- * @default 'Show more results...'
28
+ * The text to show on the bottom loading indicator.
29
+ * @default 'Loading more...'
30
30
  */
31
- loadMoreText?: string;
31
+ loadingText?: string;
32
32
  /**
33
33
  * If true, shows a clear button when the input is not empty.
34
34
  * @default true
@@ -45,20 +45,37 @@ declare class InferJS {
45
45
  private list;
46
46
  private dropdown;
47
47
  private wrapper;
48
- private loader;
48
+ private dropdownLoader;
49
49
  private clearButton;
50
- private loadMoreButton;
51
50
  private useDefaultStyles;
52
51
  private noResultsText;
53
- private loadMoreText;
52
+ private loadingText;
54
53
  private showClearButton;
55
54
  private isOpen;
55
+ private observer;
56
+ private boundHandlers;
57
+ private isDestroyed;
56
58
  /**
57
59
  * Initializes the Infer logic on a target element.
58
60
  * @param target Either a CSS selector string or a direct HTMLElement.
59
61
  * @param config Configuration options for the API and UI.
60
62
  */
61
63
  constructor(target: string | HTMLElement, config: InferJSConfig);
64
+ /**
65
+ * Retrieves the current selected address value if available.
66
+ * @returns The AddressValue object if valid, otherwise null.
67
+ */
68
+ get value(): AddressValue | null;
69
+ /**
70
+ * Programmatically sets the address value.
71
+ * @param address The address object to set.
72
+ */
73
+ set value(address: AddressValue);
74
+ /**
75
+ * Destroys the InferJS instance, removing all event listeners and DOM elements.
76
+ * Call this before creating a new instance on the same input element.
77
+ */
78
+ destroy(): void;
62
79
  private injectStyles;
63
80
  private bindEvents;
64
81
  private render;