@pro6pp/infer-js 0.0.2-beta.5 → 0.0.2-beta.6
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 +21 -4
- package/dist/index.d.mts +34 -0
- package/dist/index.d.ts +34 -0
- package/dist/index.global.js +5 -8
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@ A library that adds address autocompletion to any HTML input field.
|
|
|
5
5
|
|
|
6
6
|
## Installation
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
#### Option 1: CDN
|
|
9
9
|
|
|
10
10
|
Add this script to your HTML file. It exposes a global `Pro6PP` variable.
|
|
11
11
|
|
|
@@ -13,7 +13,7 @@ Add this script to your HTML file. It exposes a global `Pro6PP` variable.
|
|
|
13
13
|
<script src="https://unpkg.com/@pro6pp/infer-js"></script>
|
|
14
14
|
```
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
#### Option 2: NPM
|
|
17
17
|
|
|
18
18
|
If you are using a build tool like Webpack or Vite, but not a framework like React.
|
|
19
19
|
|
|
@@ -25,7 +25,7 @@ npm install @pro6pp/infer-js
|
|
|
25
25
|
|
|
26
26
|
## Usage
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
#### Option 1: CDN
|
|
29
29
|
|
|
30
30
|
1. Add the script to your page.
|
|
31
31
|
2. Create an input field.
|
|
@@ -48,7 +48,7 @@ npm install @pro6pp/infer-js
|
|
|
48
48
|
</script>
|
|
49
49
|
```
|
|
50
50
|
|
|
51
|
-
|
|
51
|
+
#### Option 2: NPM
|
|
52
52
|
|
|
53
53
|
1. Create an input field.
|
|
54
54
|
2. Import the `attach` function.
|
|
@@ -72,6 +72,23 @@ attach(inputElement, {
|
|
|
72
72
|
});
|
|
73
73
|
```
|
|
74
74
|
|
|
75
|
+
## API Configuration
|
|
76
|
+
|
|
77
|
+
| Prop | Description | Default |
|
|
78
|
+
| :-------------- | :------------------------------------------------------------ | :--------------------------- |
|
|
79
|
+
| `authKey` | **(Required)** Your Pro6PP Authorization Key. | - |
|
|
80
|
+
| `country` | **(Required)** The country to search in (`'NL'` or `'DE'`). | - |
|
|
81
|
+
| `debounceMs` | Delay in milliseconds before the API search. Minimum of 50ms. | `150` |
|
|
82
|
+
| `style` | Styling theme. Use `'none'` to disable default CSS. | `'default'` |
|
|
83
|
+
| `placeholder` | Custom placeholder text for the input field. | - |
|
|
84
|
+
| `inputClass` | Additional CSS classes to add to the input element. | - |
|
|
85
|
+
| `noResultsText` | Text to display when no suggestions are found. | `'No results found'` |
|
|
86
|
+
| `limit` | Maximum number of suggestions to request. | `1000` |
|
|
87
|
+
| `apiUrl` | Base URL for the Pro6PP API. | `'https://api.pro6pp.nl/v2'` |
|
|
88
|
+
| `fetcher` | Custom fetch implementation for requests. | `window.fetch` |
|
|
89
|
+
| `onSelect` | Callback fired when a result is selected. | - |
|
|
90
|
+
| `onStateChange` | Callback fired whenever the internal state updates. | - |
|
|
91
|
+
|
|
75
92
|
## Styling
|
|
76
93
|
|
|
77
94
|
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:
|
package/dist/index.d.mts
CHANGED
|
@@ -1,11 +1,34 @@
|
|
|
1
1
|
import { InferConfig } from '@pro6pp/infer-core';
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Configuration options for the JS Infer SDK.
|
|
5
|
+
*/
|
|
3
6
|
interface InferJSConfig extends InferConfig {
|
|
7
|
+
/**
|
|
8
|
+
* The styling theme to apply.
|
|
9
|
+
* - `default`: Injects the standard Pro6PP CSS theme.
|
|
10
|
+
* - `none`: No styles are applied, allowing for custom CSS.
|
|
11
|
+
* @default 'default'
|
|
12
|
+
*/
|
|
4
13
|
style?: 'default' | 'none';
|
|
14
|
+
/**
|
|
15
|
+
* Custom placeholder text for the input field.
|
|
16
|
+
*/
|
|
5
17
|
placeholder?: string;
|
|
18
|
+
/**
|
|
19
|
+
* Additional CSS classes to add to the input element.
|
|
20
|
+
*/
|
|
6
21
|
inputClass?: string;
|
|
22
|
+
/**
|
|
23
|
+
* The text to display when no suggestions are found.
|
|
24
|
+
* @default 'No results found'
|
|
25
|
+
*/
|
|
7
26
|
noResultsText?: string;
|
|
8
27
|
}
|
|
28
|
+
/**
|
|
29
|
+
* The JS implementation of the Pro6PP Infer SDK.
|
|
30
|
+
* This class manages the DOM elements, event listeners, and rendering for the autocomplete UI.
|
|
31
|
+
*/
|
|
9
32
|
declare class InferJS {
|
|
10
33
|
private core;
|
|
11
34
|
private input;
|
|
@@ -14,11 +37,22 @@ declare class InferJS {
|
|
|
14
37
|
private loader;
|
|
15
38
|
private useDefaultStyles;
|
|
16
39
|
private noResultsText;
|
|
40
|
+
/**
|
|
41
|
+
* Initializes the Infer logic on a target element.
|
|
42
|
+
* @param target Either a CSS selector string or a direct HTMLElement.
|
|
43
|
+
* @param config Configuration options for the API and UI.
|
|
44
|
+
*/
|
|
17
45
|
constructor(target: string | HTMLElement, config: InferJSConfig);
|
|
18
46
|
private injectStyles;
|
|
19
47
|
private bindEvents;
|
|
20
48
|
private render;
|
|
21
49
|
}
|
|
50
|
+
/**
|
|
51
|
+
* A helper to initialize the Pro6PP Infer SDK on a target element.
|
|
52
|
+
* @param target A CSS selector string or HTMLElement.
|
|
53
|
+
* @param config Configuration for the SDK.
|
|
54
|
+
* @returns An instance of InferJS.
|
|
55
|
+
*/
|
|
22
56
|
declare function attach(target: string | HTMLElement, config: InferJSConfig): InferJS;
|
|
23
57
|
|
|
24
58
|
export { InferJS, type InferJSConfig, attach };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,11 +1,34 @@
|
|
|
1
1
|
import { InferConfig } from '@pro6pp/infer-core';
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Configuration options for the JS Infer SDK.
|
|
5
|
+
*/
|
|
3
6
|
interface InferJSConfig extends InferConfig {
|
|
7
|
+
/**
|
|
8
|
+
* The styling theme to apply.
|
|
9
|
+
* - `default`: Injects the standard Pro6PP CSS theme.
|
|
10
|
+
* - `none`: No styles are applied, allowing for custom CSS.
|
|
11
|
+
* @default 'default'
|
|
12
|
+
*/
|
|
4
13
|
style?: 'default' | 'none';
|
|
14
|
+
/**
|
|
15
|
+
* Custom placeholder text for the input field.
|
|
16
|
+
*/
|
|
5
17
|
placeholder?: string;
|
|
18
|
+
/**
|
|
19
|
+
* Additional CSS classes to add to the input element.
|
|
20
|
+
*/
|
|
6
21
|
inputClass?: string;
|
|
22
|
+
/**
|
|
23
|
+
* The text to display when no suggestions are found.
|
|
24
|
+
* @default 'No results found'
|
|
25
|
+
*/
|
|
7
26
|
noResultsText?: string;
|
|
8
27
|
}
|
|
28
|
+
/**
|
|
29
|
+
* The JS implementation of the Pro6PP Infer SDK.
|
|
30
|
+
* This class manages the DOM elements, event listeners, and rendering for the autocomplete UI.
|
|
31
|
+
*/
|
|
9
32
|
declare class InferJS {
|
|
10
33
|
private core;
|
|
11
34
|
private input;
|
|
@@ -14,11 +37,22 @@ declare class InferJS {
|
|
|
14
37
|
private loader;
|
|
15
38
|
private useDefaultStyles;
|
|
16
39
|
private noResultsText;
|
|
40
|
+
/**
|
|
41
|
+
* Initializes the Infer logic on a target element.
|
|
42
|
+
* @param target Either a CSS selector string or a direct HTMLElement.
|
|
43
|
+
* @param config Configuration options for the API and UI.
|
|
44
|
+
*/
|
|
17
45
|
constructor(target: string | HTMLElement, config: InferJSConfig);
|
|
18
46
|
private injectStyles;
|
|
19
47
|
private bindEvents;
|
|
20
48
|
private render;
|
|
21
49
|
}
|
|
50
|
+
/**
|
|
51
|
+
* A helper to initialize the Pro6PP Infer SDK on a target element.
|
|
52
|
+
* @param target A CSS selector string or HTMLElement.
|
|
53
|
+
* @param config Configuration for the SDK.
|
|
54
|
+
* @returns An instance of InferJS.
|
|
55
|
+
*/
|
|
22
56
|
declare function attach(target: string | HTMLElement, config: InferJSConfig): InferJS;
|
|
23
57
|
|
|
24
58
|
export { InferJS, type InferJSConfig, attach };
|
package/dist/index.global.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";var Pro6PP=(()=>{var
|
|
1
|
+
"use strict";var Pro6PP=(()=>{var f=Object.defineProperty;var v=Object.getOwnPropertyDescriptor;var x=Object.getOwnPropertyNames;var I=Object.prototype.hasOwnProperty;var C=(p,e)=>{for(var t in e)f(p,t,{get:e[t],enumerable:!0})},E=(p,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of x(e))!I.call(p,i)&&i!==t&&f(p,i,{get:()=>e[i],enumerable:!(n=v(e,i))||n.enumerable});return p};var w=p=>E(f({},"__esModule",{value:!0}),p);var L={};C(L,{InferJS:()=>h,attach:()=>T});var d={API_URL:"https://api.pro6pp.nl/v2",LIMIT:1e3,DEBOUNCE_MS:150,MIN_DEBOUNCE_MS:50},y={DIGITS_1_3:/^[0-9]{1,3}$/},b={query:"",stage:null,cities:[],streets:[],suggestions:[],isValid:!1,isError:!1,isLoading:!1,selectedSuggestionIndex:-1},c=class{constructor(e){this.abortController=null;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,s)=>fetch(i,s)),this.onStateChange=e.onStateChange||(()=>{}),this.onSelect=e.onSelect||(()=>{}),this.state={...b};let t=e.debounceMs!==void 0?e.debounceMs:d.DEBOUNCE_MS,n=Math.max(t,d.MIN_DEBOUNCE_MS);this.debouncedFetch=this.debounce(i=>this.executeFetch(i),n)}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 n=this.state.cities.length+this.state.streets.length+this.state.suggestions.length;if(n>0){if(e.key==="ArrowDown"){e.preventDefault();let s=this.state.selectedSuggestionIndex+1;s>=n&&(s=0),this.updateState({selectedSuggestionIndex:s});return}if(e.key==="ArrowUp"){e.preventDefault();let s=this.state.selectedSuggestionIndex-1;s<0&&(s=n-1),this.updateState({selectedSuggestionIndex:s});return}if(e.key==="Enter"&&this.state.selectedSuggestionIndex>=0){e.preventDefault();let l=[...this.state.cities,...this.state.streets,...this.state.suggestions][this.state.selectedSuggestionIndex];l&&(this.selectItem(l),this.updateState({selectedSuggestionIndex:-1}));return}}let i=t.value;if(e.key===" "&&this.shouldAutoInsertComma(i)){e.preventDefault();let s=`${i.trim()}, `;this.updateQueryAndFetch(s)}}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 i=typeof e!="string"&&typeof e.value=="object"?e.value:void 0,s=!!i&&Object.keys(i).length>0;if(this.isSelecting=!0,this.state.stage==="final"||s){let r=t;if(i&&Object.keys(i).length>0){let{street:o,street_number:u,house_number:m,city:a}=i,S=u||m;o&&S&&a&&(r=`${o} ${S}, ${a}`)}this.finishSelection(r,i);return}let l=typeof e!="string"?e.subtitle:null;this.processSelection(n,l)}shouldAutoInsertComma(e){if(!e.includes(",")&&y.DIGITS_1_3.test(e.trim()))return!0;if(this.state.stage==="house_number"){let n=this.getCurrentFragment(e);return y.DIGITS_1_3.test(n)}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:n,query:i}=this.state,s=i;if(t&&(n==="city"||n==="street"||n==="mixed")){if(n==="city")s=`${t}, ${e}, `;else{let u=this.getQueryPrefix(i);s=u?`${u} ${e}, ${t}, `:`${e}, ${t}, `}this.updateQueryAndFetch(s);return}if(n==="direct"||n==="addition"){this.finishSelection(e);return}!i.includes(",")&&(n==="city"||n==="street"||n==="house_number_first")?s=`${e}, `:(s=this.replaceLastSegment(i,e),n!=="house_number"&&(s+=", ")),this.updateQueryAndFetch(s)}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 n=new URL(`${this.apiUrl}/infer/${this.country.toLowerCase()}`),i={authKey:this.authKey,query:t,limit:this.limit.toString()};n.search=new URLSearchParams(i).toString(),this.fetcher(n.toString(),{signal:this.abortController.signal}).then(s=>{if(!s.ok)throw new Error("Network error");return s.json()}).then(s=>this.mapResponseToState(s)).catch(s=>{s.name!=="AbortError"&&this.updateState({isError:!0,isLoading:!1})})}mapResponseToState(e){let t={stage:e.stage,isLoading:!1},n=!1,i=null,s=e.suggestions||[],l=[],r=new Set;for(let o of s){let u=`${o.label}|${o.subtitle||""}|${JSON.stringify(o.value||{})}`;r.has(u)||(r.add(u),l.push(o))}if(e.stage==="mixed"?(t.cities=e.cities||[],t.streets=e.streets||[],t.suggestions=[]):(t.suggestions=l,t.cities=[],t.streets=[],e.stage==="final"&&l.length===1&&(n=!0,i=l[0])),t.isValid=e.stage==="final",n&&i){t.query=i.label,t.suggestions=[],t.cities=[],t.streets=[],t.isValid=!0,this.updateState(t);let o=typeof i.value=="object"?i.value:i.label;this.onSelect(o)}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 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){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 n,i=(...s)=>{n&&clearTimeout(n),n=setTimeout(()=>e.apply(this,s),t)};return i.cancel=()=>{n&&(clearTimeout(n),n=void 0)},i}};var g=`
|
|
2
2
|
.pro6pp-wrapper {
|
|
3
3
|
position: relative;
|
|
4
4
|
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
|
|
@@ -38,21 +38,18 @@
|
|
|
38
38
|
list-style: none !important;
|
|
39
39
|
padding: 0 !important;
|
|
40
40
|
margin: 0 !important;
|
|
41
|
-
overflow: hidden;
|
|
42
41
|
}
|
|
43
42
|
.pro6pp-item {
|
|
44
|
-
padding:
|
|
43
|
+
padding: 10px 16px;
|
|
45
44
|
cursor: pointer;
|
|
46
45
|
display: flex;
|
|
47
46
|
flex-direction: row;
|
|
48
47
|
align-items: center;
|
|
49
48
|
color: #000000;
|
|
50
49
|
font-size: 14px;
|
|
51
|
-
line-height: 1;
|
|
50
|
+
line-height: 1.2;
|
|
52
51
|
white-space: nowrap;
|
|
53
52
|
overflow: hidden;
|
|
54
|
-
border-radius: 0 !important;
|
|
55
|
-
margin: 0 !important;
|
|
56
53
|
}
|
|
57
54
|
.pro6pp-item:hover, .pro6pp-item--active {
|
|
58
55
|
background-color: #f5f5f5;
|
|
@@ -99,8 +96,8 @@
|
|
|
99
96
|
@keyframes pro6pp-spin {
|
|
100
97
|
to { transform: translateY(-50%) rotate(360deg); }
|
|
101
98
|
}
|
|
102
|
-
`;var
|
|
99
|
+
`;var h=class{constructor(e,t){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.useDefaultStyles=t.style!=="none",this.useDefaultStyles&&this.injectStyles(),this.wrapper=document.createElement("div"),this.wrapper.className="pro6pp-wrapper",n instanceof HTMLInputElement?(this.input=n,this.input.parentNode?.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.useDefaultStyles&&this.input.classList.add("pro6pp-input"),t.inputClass){let i=t.inputClass.split(" ");this.input.classList.add(...i)}this.loader=document.createElement("div"),this.loader.className="pro6pp-loader",this.loader.style.display="none",this.wrapper.appendChild(this.loader),this.list=document.createElement("ul"),this.list.className="pro6pp-dropdown",this.list.style.display="none",this.list.setAttribute("role","listbox"),this.wrapper.appendChild(this.list),this.core=new c({...t,onStateChange:i=>this.render(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.bindEvents()}injectStyles(){let e="pro6pp-styles";if(!document.getElementById(e)){let t=document.createElement("style");t.id=e,t.textContent=g,document.head.appendChild(t)}}bindEvents(){this.input.addEventListener("input",e=>{let t=e.target.value;this.core.handleInput(t)}),this.input.addEventListener("keydown",e=>{this.core.handleKeyDown(e)}),document.addEventListener("click",e=>{this.wrapper.contains(e.target)||(this.list.style.display="none")}),this.input.addEventListener("focus",()=>{this.list.children.length>0&&(this.list.style.display="block")})}render(e){this.input.value!==e.query&&(this.input.value=e.query),this.loader.style.display=e.isLoading?"block":"none",this.list.innerHTML="";let t=[...e.cities.map(s=>({item:s,type:"city"})),...e.streets.map(s=>({item:s,type:"street"})),...e.suggestions.map(s=>({item:s,type:"suggestion"}))],n=t.length>0,i=!e.isLoading&&!e.isError&&e.query.length>0&&!n&&!e.isValid;if(!n&&!i){this.list.style.display="none";return}if(this.list.style.display="block",i){let s=document.createElement("li");s.className="pro6pp-no-results",s.textContent=this.noResultsText,this.list.appendChild(s);return}t.forEach(({item:s},l)=>{let r=document.createElement("li");r.className="pro6pp-item",l===e.selectedSuggestionIndex&&r.classList.add("pro6pp-item--active"),r.setAttribute("role","option"),r.setAttribute("aria-selected",l===e.selectedSuggestionIndex?"true":"false");let o=document.createElement("span");o.className="pro6pp-item__label",o.textContent=s.label,r.appendChild(o);let u=s.subtitle||s.count;if(u){let a=document.createElement("span");a.className="pro6pp-item__subtitle",a.textContent=`, ${u}`,r.appendChild(a)}if(s.value===void 0||s.value===null){let a=document.createElement("div");a.className="pro6pp-item__chevron",a.innerHTML=`
|
|
103
100
|
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
104
101
|
<polyline points="9 18 15 12 9 6"></polyline>
|
|
105
102
|
</svg>
|
|
106
|
-
`,r.appendChild(a)}r.onmousedown=a=>a.preventDefault(),r.onclick=a=>{a.stopPropagation(),this.core.selectItem(
|
|
103
|
+
`,r.appendChild(a)}r.onmousedown=a=>a.preventDefault(),r.onclick=a=>{a.stopPropagation(),this.core.selectItem(s),e.isValid||this.input.focus()},this.list.appendChild(r)})}};function T(p,e){return new h(p,e)}return w(L);})();
|
package/package.json
CHANGED
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"sideEffects": [
|
|
19
19
|
"*.css"
|
|
20
20
|
],
|
|
21
|
-
"version": "0.0.2-beta.
|
|
21
|
+
"version": "0.0.2-beta.6",
|
|
22
22
|
"main": "./dist/index.js",
|
|
23
23
|
"module": "./dist/index.mjs",
|
|
24
24
|
"types": "./dist/index.d.ts",
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"test:coverage": "vitest run --coverage"
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
|
-
"@pro6pp/infer-core": "0.0.2-beta.
|
|
46
|
+
"@pro6pp/infer-core": "0.0.2-beta.6"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
49
|
"@testing-library/dom": "^10.4.1",
|