@pro6pp/infer-js 0.0.2-beta.9 → 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 +49 -4
- package/dist/index.cjs +122 -73
- package/dist/index.d.mts +24 -7
- package/dist/index.d.ts +24 -7
- package/dist/index.global.js +122 -73
- package/dist/index.mjs +122 -73
- package/dist/styles.css +203 -0
- package/package.json +4 -3
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
|
-
|
|
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.
|
|
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
|
|
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
CHANGED
|
@@ -1,23 +1,31 @@
|
|
|
1
|
-
"use strict";var
|
|
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
2
|
.pro6pp-wrapper {
|
|
3
3
|
position: relative;
|
|
4
4
|
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
|
|
5
5
|
box-sizing: border-box;
|
|
6
6
|
width: 100%;
|
|
7
|
+
-webkit-tap-highlight-color: transparent;
|
|
7
8
|
}
|
|
8
9
|
.pro6pp-wrapper * {
|
|
9
10
|
box-sizing: border-box;
|
|
10
11
|
}
|
|
11
12
|
.pro6pp-input {
|
|
12
13
|
width: 100%;
|
|
13
|
-
padding:
|
|
14
|
+
padding: 12px 14px;
|
|
14
15
|
padding-right: 48px;
|
|
15
16
|
border: 1px solid #e0e0e0;
|
|
16
|
-
border-radius:
|
|
17
|
+
border-radius: 8px;
|
|
17
18
|
font-size: 16px;
|
|
18
19
|
line-height: 1.5;
|
|
20
|
+
appearance: none;
|
|
19
21
|
transition: border-color 0.2s, box-shadow 0.2s;
|
|
20
22
|
}
|
|
23
|
+
|
|
24
|
+
.pro6pp-input::placeholder {
|
|
25
|
+
font-size: 16px;
|
|
26
|
+
color: #a3a3a3;
|
|
27
|
+
}
|
|
28
|
+
|
|
21
29
|
.pro6pp-input:focus {
|
|
22
30
|
outline: none;
|
|
23
31
|
border-color: #3b82f6;
|
|
@@ -26,12 +34,11 @@
|
|
|
26
34
|
|
|
27
35
|
.pro6pp-input-addons {
|
|
28
36
|
position: absolute;
|
|
29
|
-
right:
|
|
37
|
+
right: 4px;
|
|
30
38
|
top: 0;
|
|
31
39
|
bottom: 0;
|
|
32
40
|
display: flex;
|
|
33
41
|
align-items: center;
|
|
34
|
-
gap: 2px;
|
|
35
42
|
pointer-events: none;
|
|
36
43
|
}
|
|
37
44
|
.pro6pp-input-addons > * {
|
|
@@ -41,37 +48,27 @@
|
|
|
41
48
|
.pro6pp-clear-button {
|
|
42
49
|
background: none;
|
|
43
50
|
border: none;
|
|
44
|
-
width:
|
|
45
|
-
height:
|
|
51
|
+
width: 32px;
|
|
52
|
+
height: 32px;
|
|
46
53
|
cursor: pointer;
|
|
47
54
|
color: #a3a3a3;
|
|
48
55
|
display: flex;
|
|
49
56
|
align-items: center;
|
|
50
57
|
justify-content: center;
|
|
51
58
|
border-radius: 50%;
|
|
52
|
-
transition: color 0.2s, background-color 0.2s
|
|
53
|
-
|
|
54
|
-
.pro6pp-clear-button:hover {
|
|
55
|
-
color: #1f2937;
|
|
56
|
-
background-color: #f3f4f6;
|
|
57
|
-
}
|
|
58
|
-
.pro6pp-clear-button:active {
|
|
59
|
-
transform: scale(0.92);
|
|
59
|
+
transition: color 0.2s, background-color 0.2s;
|
|
60
|
+
touch-action: manipulation;
|
|
60
61
|
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
62
|
+
|
|
63
|
+
@media (hover: hover) {
|
|
64
|
+
.pro6pp-clear-button:hover {
|
|
65
|
+
color: #1f2937;
|
|
66
|
+
background-color: #f3f4f6;
|
|
67
|
+
}
|
|
64
68
|
}
|
|
65
69
|
|
|
66
|
-
.pro6pp-
|
|
67
|
-
|
|
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;
|
|
70
|
+
.pro6pp-clear-button:active {
|
|
71
|
+
background-color: #f3f4f6;
|
|
75
72
|
}
|
|
76
73
|
|
|
77
74
|
.pro6pp-dropdown {
|
|
@@ -79,89 +76,141 @@
|
|
|
79
76
|
top: 100%;
|
|
80
77
|
left: 0;
|
|
81
78
|
right: 0;
|
|
82
|
-
z-index: 9999;
|
|
83
79
|
margin-top: 4px;
|
|
84
|
-
background:
|
|
85
|
-
border: 1px solid #
|
|
86
|
-
border-radius:
|
|
87
|
-
box-shadow: 0
|
|
88
|
-
|
|
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;
|
|
89
87
|
overflow-y: auto;
|
|
90
88
|
display: flex;
|
|
91
89
|
flex-direction: column;
|
|
92
90
|
}
|
|
91
|
+
|
|
92
|
+
@media (max-height: 500px) {
|
|
93
|
+
.pro6pp-dropdown {
|
|
94
|
+
max-height: 180px;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
93
98
|
.pro6pp-list {
|
|
94
|
-
list-style: none
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
99
|
+
list-style: none;
|
|
100
|
+
margin: 0;
|
|
101
|
+
padding: 0;
|
|
102
|
+
width: 100%;
|
|
98
103
|
}
|
|
104
|
+
|
|
99
105
|
.pro6pp-item {
|
|
100
|
-
padding: 12px
|
|
106
|
+
padding: 12px 14px;
|
|
101
107
|
cursor: pointer;
|
|
102
108
|
display: flex;
|
|
103
|
-
flex-direction: row;
|
|
104
109
|
align-items: center;
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
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;
|
|
110
116
|
}
|
|
111
|
-
|
|
112
|
-
|
|
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
|
+
}
|
|
113
126
|
}
|
|
127
|
+
|
|
128
|
+
.pro6pp-item:active {
|
|
129
|
+
background-color: #f3f4f6;
|
|
130
|
+
}
|
|
131
|
+
|
|
114
132
|
.pro6pp-item__label {
|
|
115
|
-
font-weight:
|
|
116
|
-
flex-shrink:
|
|
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;
|
|
117
147
|
}
|
|
148
|
+
|
|
118
149
|
.pro6pp-item__subtitle {
|
|
119
|
-
font-size: 14px;
|
|
120
150
|
color: #6b7280;
|
|
121
|
-
|
|
122
|
-
text-overflow: ellipsis;
|
|
123
|
-
flex-shrink: 1;
|
|
151
|
+
flex-shrink: 0;
|
|
124
152
|
}
|
|
153
|
+
|
|
125
154
|
.pro6pp-item__chevron {
|
|
126
|
-
|
|
155
|
+
color: #d1d5db;
|
|
127
156
|
display: flex;
|
|
128
157
|
align-items: center;
|
|
129
|
-
|
|
158
|
+
margin-left: auto;
|
|
130
159
|
padding-left: 8px;
|
|
131
160
|
}
|
|
161
|
+
|
|
132
162
|
.pro6pp-no-results {
|
|
133
|
-
padding: 16px;
|
|
163
|
+
padding: 24px 16px;
|
|
134
164
|
color: #6b7280;
|
|
135
|
-
font-size:
|
|
165
|
+
font-size: 15px;
|
|
136
166
|
text-align: center;
|
|
137
167
|
}
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
padding: 10px;
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
flex-shrink: 0;
|
|
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;
|
|
150
179
|
}
|
|
151
|
-
|
|
152
|
-
|
|
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
|
+
}
|
|
153
199
|
}
|
|
154
200
|
|
|
155
201
|
@keyframes pro6pp-spin {
|
|
156
202
|
to { transform: rotate(360deg); }
|
|
157
203
|
}
|
|
158
|
-
`;var
|
|
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=`
|
|
159
205
|
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
160
206
|
<line x1="18" y1="6" x2="6" y2="18"></line>
|
|
161
207
|
<line x1="6" y1="6" x2="18" y2="18"></line>
|
|
162
208
|
</svg>
|
|
163
|
-
`,
|
|
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=`
|
|
164
213
|
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
165
214
|
<polyline points="9 18 15 12 9 6"></polyline>
|
|
166
215
|
</svg>
|
|
167
|
-
`,
|
|
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});
|
package/dist/index.d.mts
CHANGED
|
@@ -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
|
|
29
|
-
* @default '
|
|
28
|
+
* The text to show on the bottom loading indicator.
|
|
29
|
+
* @default 'Loading more...'
|
|
30
30
|
*/
|
|
31
|
-
|
|
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
|
|
48
|
+
private dropdownLoader;
|
|
49
49
|
private clearButton;
|
|
50
|
-
private loadMoreButton;
|
|
51
50
|
private useDefaultStyles;
|
|
52
51
|
private noResultsText;
|
|
53
|
-
private
|
|
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;
|
package/dist/index.d.ts
CHANGED
|
@@ -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
|
|
29
|
-
* @default '
|
|
28
|
+
* The text to show on the bottom loading indicator.
|
|
29
|
+
* @default 'Loading more...'
|
|
30
30
|
*/
|
|
31
|
-
|
|
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
|
|
48
|
+
private dropdownLoader;
|
|
49
49
|
private clearButton;
|
|
50
|
-
private loadMoreButton;
|
|
51
50
|
private useDefaultStyles;
|
|
52
51
|
private noResultsText;
|
|
53
|
-
private
|
|
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;
|