@pro6pp/infer-core 0.0.2-beta.7 → 0.0.2-beta.9

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
@@ -7,14 +7,32 @@ Use this package if you are building a custom integration for a framework, or if
7
7
 
8
8
  ## Installation
9
9
 
10
+ ### Package Manager
11
+
10
12
  ```bash
11
13
  npm install @pro6pp/infer-core
12
14
  ```
13
15
 
16
+ ### CDN
17
+
18
+ You can also load the Core SDK directly in the browser via a CDN:
19
+
20
+ ```html
21
+ <script src="https://unpkg.com/@pro6pp/infer-core"></script>
22
+ ```
23
+
24
+ ```html
25
+ <script src="https://cdn.jsdelivr.net/npm/@pro6pp/infer-core"></script>
26
+ ```
27
+
28
+ When loaded via a script tag, the library is available through the global `Pro6PPCore` object.
29
+
14
30
  ## Usage
15
31
 
16
32
  The core logic is exposed via the `InferCore` class. It manages the API requests, state and parses input.
17
33
 
34
+ ### Using ES Modules
35
+
18
36
  ```typescript
19
37
  import { InferCore } from '@pro6pp/infer-core';
20
38
 
@@ -29,7 +47,23 @@ const core = new InferCore({
29
47
  console.log('User selected:', result);
30
48
  },
31
49
  });
50
+ ```
51
+
52
+ ### Using via script tag (global)
53
+
54
+ ```typescript
55
+ const core = new Pro6PPCore.InferCore({
56
+ authKey: 'YOUR_AUTH_KEY',
57
+ country: 'NL',
58
+ onSelect: (result) => console.log(result),
59
+ });
60
+ ```
61
+
62
+ ### Event handling
32
63
 
64
+ Once initialized, pass your input and keyboard events to the core instance to manage state.
65
+
66
+ ```typescript
33
67
  const input = document.querySelector('#my-input');
34
68
 
35
69
  // pass input events to the core
package/dist/index.cjs CHANGED
@@ -1,21 +1,23 @@
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 T=(a,e)=>{for(var t in e)h(a,t,{get:e[t],enumerable:!0})},C=(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 L=a=>C(h({},"__esModule",{value:!0}),a);var l=(a,e,t)=>w(a,typeof e!="symbol"?e+"":e,t);var _={};T(_,{DEFAULT_STYLES:()=>S,INITIAL_STATE:()=>g,InferCore:()=>f});module.exports=L(_);var c={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,"apiUrl");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.apiUrl=e.apiUrl||c.API_URL,this.baseLimit=e.limit||c.LIMIT,this.currentLimit=this.baseLimit;let t=e.maxRetries!==void 0?e.maxRetries:c.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:c.DEBOUNCE_MS,s=Math.max(i,c.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 n=t;if(s&&Object.keys(s).length>0){let{street:p,street_number:u,house_number:d,city:b}=s,m=u||d;p&&m&&b&&(n=`${p} ${m}, ${b}`)}this.finishSelection(n,s);return}let o=typeof e!="string"?e.subtitle:null;this.processSelection(i,o)}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),setTimeout(()=>{this.isSelecting=!1},0)}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 u=this.getQueryPrefix(s);r=u?`${u} ${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=new URL(`${this.apiUrl}/infer/${this.country.toLowerCase()}`),o={authKey:this.authKey,query:i,limit:this.currentLimit.toString()};r.search=new URLSearchParams(o).toString(),this.fetcher(r.toString(),{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=[],n=new Set;for(let u of r){let d=`${u.label}|${u.subtitle||""}|${JSON.stringify(u.value||{})}`;n.has(d)||(n.add(d),o.push(u))}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=[]):(t.suggestions=o,t.cities=[],t.streets=[],e.stage==="final"&&o.length===1&&(i=!0,s=o[0])),t.isValid=e.stage==="final",i&&s){t.query=s.label,t.suggestions=[],t.cities=[],t.streets=[],t.isValid=!0,t.hasMore=!1,this.updateState(t);let u=typeof s.value=="object"?s.value:s.label;this.onSelect(u)}else this.updateState(t)}updateQueryAndFetch(e){this.updateState({query:e,suggestions:[],cities:[],streets:[]}),this.updateState({isLoading:!0,isValid:!1,hasMore:!1}),this.debouncedFetch(e),setTimeout(()=>{this.isSelecting=!1},0)}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=`
1
+ "use strict";var h=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var S=Object.getOwnPropertyNames;var y=Object.prototype.hasOwnProperty;var v=(n,t,e)=>t in n?h(n,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):n[t]=e;var I=(n,t)=>{for(var e in t)h(n,e,{get:t[e],enumerable:!0})},C=(n,t,e,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of S(t))!y.call(n,r)&&r!==e&&h(n,r,{get:()=>t[r],enumerable:!(i=x(t,r))||i.enumerable});return n};var T=n=>C(h({},"__esModule",{value:!0}),n);var l=(n,t,e)=>v(n,typeof t!="symbol"?t+"":t,e);var w={};I(w,{DEFAULT_STYLES:()=>b,INITIAL_STATE:()=>g,InferCore:()=>f,getHighlightSegments:()=>L});module.exports=T(w);var c={API_URL:"https://api.pro6pp.nl/v2",LIMIT:20,DEBOUNCE_MS:150,MIN_DEBOUNCE_MS:50,MAX_RETRIES:0},m={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(t){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");this.country=t.country,this.authKey=t.authKey,this.explicitApiUrl=t.apiUrl,this.baseLimit=t.limit||c.LIMIT,this.currentLimit=this.baseLimit;let e=t.maxRetries!==void 0?t.maxRetries:c.MAX_RETRIES;this.maxRetries=Math.max(0,Math.min(e,10)),this.fetcher=t.fetcher||((s,a)=>fetch(s,a)),this.onStateChange=t.onStateChange||(()=>{}),this.onSelect=t.onSelect||(()=>{}),this.state={...g};let i=t.debounceMs!==void 0?t.debounceMs:c.DEBOUNCE_MS,r=Math.max(i,c.MIN_DEBOUNCE_MS);this.debouncedFetch=this.debounce(s=>this.executeFetch(s),r)}handleInput(t){this.currentLimit=this.baseLimit;let e=this.state.stage==="final"&&t!==this.state.query;this.updateState({query:t,isValid:!1,isLoading:!!t.trim(),selectedSuggestionIndex:-1,hasMore:!1}),e&&this.onSelect(null),this.debouncedFetch(t)}loadMore(){this.state.isLoading||(this.currentLimit+=this.baseLimit,this.updateState({isLoading:!0}),this.executeFetch(this.state.query))}handleKeyDown(t){let e=t.target;if(!e)return;let i=this.state.cities.length+this.state.streets.length+this.state.suggestions.length;if(i>0){if(t.key==="ArrowDown"){t.preventDefault();let s=this.state.selectedSuggestionIndex+1;s>=i&&(s=0),this.updateState({selectedSuggestionIndex:s});return}if(t.key==="ArrowUp"){t.preventDefault();let s=this.state.selectedSuggestionIndex-1;s<0&&(s=i-1),this.updateState({selectedSuggestionIndex:s});return}if(t.key==="Enter"&&this.state.selectedSuggestionIndex>=0){t.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 r=e.value;if(t.key===" "&&this.shouldAutoInsertComma(r)){t.preventDefault();let s=`${r.trim()}, `;this.updateQueryAndFetch(s)}}selectItem(t){this.debouncedFetch.cancel(),this.abortController&&this.abortController.abort();let e=typeof t=="string"?t:t.label,i=e;typeof t!="string"&&typeof t.value=="string"&&(i=t.value);let r=typeof t!="string"&&typeof t.value=="object"?t.value:void 0,s=!!r&&Object.keys(r).length>0;if(this.state.stage==="final"||s){let p=e;if(r&&Object.keys(r).length>0){let{street:u,street_number:o,city:d}=r;u&&o&&d&&(p=`${u} ${o}, ${d}`)}return this.finishSelection(p,r),!0}let a=typeof t!="string"?t.subtitle:null;return this.processSelection(i,a),!1}shouldAutoInsertComma(t){if(!t.includes(",")&&m.DIGITS_1_3.test(t.trim()))return!0;if(this.state.stage==="street_number"){let i=this.getCurrentFragment(t);return m.DIGITS_1_3.test(i)}return!1}finishSelection(t,e){this.updateState({query:t,suggestions:[],cities:[],streets:[],isValid:!0,stage:"final",hasMore:!1}),this.onSelect(e||t)}processSelection(t,e){let{stage:i,query:r}=this.state,s=r;if(e&&(i==="city"||i==="street"||i==="mixed")){if(i==="city")s=`${e}, ${t}, `;else{let o=this.getQueryPrefix(r);s=o?`${o} ${t}, ${e}, `:`${t}, ${e}, `}this.updateQueryAndFetch(s);return}if(i==="direct"||i==="addition"){this.finishSelection(t);return}!r.includes(",")&&(i==="city"||i==="street"||i==="street_number_first")?s=`${t}, `:(s=this.replaceLastSegment(r,t),i!=="street_number"&&(s+=", ")),this.updateQueryAndFetch(s)}executeFetch(t,e=0){let i=(t||"").toString();if(!i.trim()){this.abortController?.abort(),this.resetState();return}e===0&&(this.updateState({isError:!1}),this.abortController&&this.abortController.abort(),this.abortController=new AbortController);let r=this.abortController?.signal,s=this.explicitApiUrl?this.explicitApiUrl:`${c.API_URL}/infer/${this.country.toLowerCase()}`,a=new URLSearchParams({country:this.country.toLowerCase(),query:i,limit:this.currentLimit.toString()});this.authKey&&a.set("authKey",this.authKey);let p=s.includes("?")?"&":"?",u=`${s}${p}${a.toString()}`;this.fetcher(u,{signal:r}).then(o=>{if(!o.ok){if(e<this.maxRetries&&(o.status>=500||o.status===429))return this.retry(t,e,r);throw new Error("Network error")}return o.json()}).then(o=>{o&&this.mapResponseToState(o)}).catch(o=>{if(o.name!=="AbortError"){if(e<this.maxRetries)return this.retry(t,e,r);this.updateState({isError:!0,isLoading:!1})}})}retry(t,e,i){if(i?.aborted)return;let r=Math.pow(2,e)*200;setTimeout(()=>{i?.aborted||this.executeFetch(t,e+1)},r)}mapResponseToState(t){let e={stage:t.stage,isLoading:!1},i=t.suggestions||[],r=[],s=new Set;for(let p of i){let u=`${p.label}|${p.subtitle||""}|${JSON.stringify(p.value||{})}`;s.has(u)||(s.add(u),r.push(p))}let a=r.length+(t.cities?.length||0)+(t.streets?.length||0);e.hasMore=a>=this.currentLimit,t.stage==="mixed"?(e.cities=t.cities||[],e.streets=t.streets||[],e.suggestions=[]):(e.suggestions=r,e.cities=[],e.streets=[]),e.isValid=t.stage==="final",this.updateState(e)}updateQueryAndFetch(t){this.updateState({query:t,suggestions:[],cities:[],streets:[]}),this.updateState({isLoading:!0,isValid:!1,hasMore:!1}),this.debouncedFetch(t)}replaceLastSegment(t,e){let i=t.lastIndexOf(",");return i===-1?e:`${t.slice(0,i+1)} ${e}`.trim()}getQueryPrefix(t){let e=t.lastIndexOf(",");return e===-1?"":t.slice(0,e+1).trimEnd()}getCurrentFragment(t){return(t.split(",").slice(-1)[0]??"").trim()}resetState(){this.updateState({...g,query:this.state.query})}updateState(t){this.state={...this.state,...t},this.onStateChange(this.state)}debounce(t,e){let i,r=(...s)=>{i&&clearTimeout(i),i=setTimeout(()=>t.apply(this,s),e)};return r.cancel=()=>{i&&(clearTimeout(i),i=void 0)},r}};function L(n,t){if(!t||!n)return[{text:n,match:!1}];let e=[],i=n.toLowerCase(),r=t.toLowerCase(),s=0,a=0;for(let o=0;o<n.length;o++){if(!(s<t.length&&i[o]===r[s]))continue;o>a&&e.push({text:n.slice(a,o),match:!1}),e.push({text:n[o],match:!0}),s++,a=o+1}return a<n.length&&e.push({text:n.slice(a),match:!1}),s===t.length?e:[{text:n,match:!1}]}var b=`
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: 10px 12px;
14
+ padding: 12px 14px;
14
15
  padding-right: 48px;
15
16
  border: 1px solid #e0e0e0;
16
- border-radius: 4px;
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
  }
21
23
  .pro6pp-input:focus {
@@ -26,12 +28,11 @@
26
28
 
27
29
  .pro6pp-input-addons {
28
30
  position: absolute;
29
- right: 6px;
31
+ right: 4px;
30
32
  top: 0;
31
33
  bottom: 0;
32
34
  display: flex;
33
35
  align-items: center;
34
- gap: 2px;
35
36
  pointer-events: none;
36
37
  }
37
38
  .pro6pp-input-addons > * {
@@ -41,32 +42,33 @@
41
42
  .pro6pp-clear-button {
42
43
  background: none;
43
44
  border: none;
44
- width: 28px;
45
- height: 28px;
45
+ width: 40px;
46
+ height: 40px;
46
47
  cursor: pointer;
47
48
  color: #a3a3a3;
48
49
  display: flex;
49
50
  align-items: center;
50
51
  justify-content: center;
51
52
  border-radius: 50%;
52
- transition: color 0.2s, background-color 0.2s, transform 0.1s;
53
+ transition: color 0.2s, background-color 0.2s;
54
+ touch-action: manipulation;
53
55
  }
54
- .pro6pp-clear-button:hover {
55
- color: #1f2937;
56
- background-color: #f3f4f6;
56
+
57
+ @media (hover: hover) {
58
+ .pro6pp-clear-button:hover {
59
+ color: #1f2937;
60
+ background-color: #f3f4f6;
61
+ }
57
62
  }
63
+
58
64
  .pro6pp-clear-button:active {
59
- transform: scale(0.92);
60
- }
61
- .pro6pp-clear-button svg {
62
- width: 18px;
63
- height: 18px;
65
+ background-color: #f3f4f6;
64
66
  }
65
67
 
66
68
  .pro6pp-loader {
67
- width: 18px;
68
- height: 18px;
69
- margin: 0 4px;
69
+ width: 20px;
70
+ height: 20px;
71
+ margin: 0 8px;
70
72
  border: 2px solid #e0e0e0;
71
73
  border-top-color: #6b7280;
72
74
  border-radius: 50%;
@@ -79,38 +81,58 @@
79
81
  top: 100%;
80
82
  left: 0;
81
83
  right: 0;
82
- z-index: 9999;
83
84
  margin-top: 4px;
84
- background: white;
85
- border: 1px solid #e0e0e0;
86
- border-radius: 4px;
87
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
88
- max-height: 300px;
85
+ background: #ffffff;
86
+ border: 1px solid #e5e7eb;
87
+ border-radius: 6px;
88
+ box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
89
+ z-index: 9999;
90
+ padding: 0;
91
+ max-height: 260px;
89
92
  overflow-y: auto;
90
93
  display: flex;
91
94
  flex-direction: column;
92
95
  }
96
+
97
+ @media (max-height: 500px) {
98
+ .pro6pp-dropdown {
99
+ max-height: 140px;
100
+ }
101
+ }
102
+
93
103
  .pro6pp-list {
94
- list-style: none !important;
95
- padding: 0 !important;
96
- margin: 0 !important;
97
- flex-grow: 1;
104
+ list-style: none;
105
+ margin: 0;
106
+ padding: 0;
107
+ width: 100%;
98
108
  }
109
+
99
110
  .pro6pp-item {
100
- padding: 12px 16px;
111
+ padding: 12px 14px;
101
112
  cursor: pointer;
102
113
  display: flex;
103
- flex-direction: row;
104
114
  align-items: center;
105
- color: #111827;
106
115
  font-size: 14px;
107
- line-height: 1.2;
108
- white-space: nowrap;
109
- overflow: hidden;
116
+ color: #374151;
117
+ border-bottom: 1px solid #f3f4f6;
118
+ transition: background-color 0.1s;
119
+ flex-shrink: 0;
110
120
  }
111
- .pro6pp-item:hover, .pro6pp-item--active {
112
- background-color: #f9fafb;
121
+
122
+ .pro6pp-item:last-child {
123
+ border-bottom: none;
124
+ }
125
+
126
+ @media (hover: hover) {
127
+ .pro6pp-item:hover, .pro6pp-item--active {
128
+ background-color: #f9fafb;
129
+ }
130
+ }
131
+
132
+ .pro6pp-item:active {
133
+ background-color: #f3f4f6;
113
134
  }
135
+
114
136
  .pro6pp-item__label {
115
137
  font-weight: 500;
116
138
  flex-shrink: 0;
@@ -118,41 +140,41 @@
118
140
  .pro6pp-item__subtitle {
119
141
  font-size: 14px;
120
142
  color: #6b7280;
121
- overflow: hidden;
122
- text-overflow: ellipsis;
123
- flex-shrink: 1;
143
+ flex-grow: 1;
124
144
  }
125
145
  .pro6pp-item__chevron {
126
- margin-left: auto;
146
+ color: #d1d5db;
127
147
  display: flex;
128
148
  align-items: center;
129
- color: #9ca3af;
130
- padding-left: 8px;
149
+ margin-left: auto;
131
150
  }
151
+
132
152
  .pro6pp-no-results {
133
- padding: 16px;
153
+ padding: 24px 16px;
134
154
  color: #6b7280;
135
- font-size: 14px;
155
+ font-size: 15px;
136
156
  text-align: center;
137
157
  }
158
+
138
159
  .pro6pp-load-more {
139
160
  width: 100%;
140
- padding: 10px;
161
+ padding: 14px;
141
162
  background: #f9fafb;
142
163
  border: none;
143
164
  border-top: 1px solid #e0e0e0;
144
165
  color: #3b82f6;
145
- font-size: 13px;
166
+ font-size: 14px;
146
167
  font-weight: 600;
147
168
  cursor: pointer;
148
- transition: background-color 0.2s;
149
169
  flex-shrink: 0;
170
+ touch-action: manipulation;
150
171
  }
151
- .pro6pp-load-more:hover {
172
+
173
+ .pro6pp-load-more:active {
152
174
  background-color: #f3f4f6;
153
175
  }
154
176
 
155
177
  @keyframes pro6pp-spin {
156
178
  to { transform: rotate(360deg); }
157
179
  }
158
- `;0&&(module.exports={DEFAULT_STYLES,INITIAL_STATE,InferCore});
180
+ `;0&&(module.exports={DEFAULT_STYLES,INITIAL_STATE,InferCore,getHighlightSegments});
package/dist/index.d.cts CHANGED
@@ -9,13 +9,13 @@ type CountryCode = 'NL' | 'DE';
9
9
  * - `street`: User is selecting a street.
10
10
  * - `city`: User is selecting a city.
11
11
  * - `postcode`: User is entering a postcode.
12
- * - `house_number`: User is entering a house number.
13
- * - `house_number_first`: Specialized mode where number is entered before street.
14
- * - `addition`: Selecting a house number addition (e.g., 'A', 'III').
12
+ * - `street_number`: User is entering a street number.
13
+ * - `street_number_first`: Specialized mode where number is entered before street.
14
+ * - `addition`: Selecting a street number addition (e.g., 'A', 'III').
15
15
  * - `direct`: Direct address hit (often via postcode).
16
16
  * - `final`: A complete, valid address has been identified.
17
17
  */
18
- type Stage = 'empty' | 'mixed' | 'street' | 'city' | 'postcode' | 'house_number' | 'house_number_first' | 'addition' | 'direct' | 'final';
18
+ type Stage = 'empty' | 'mixed' | 'street' | 'city' | 'postcode' | 'street_number' | 'street_number_first' | 'addition' | 'direct' | 'final';
19
19
  /**
20
20
  * The standardized address object returned upon a successful final selection.
21
21
  */
@@ -24,15 +24,11 @@ interface AddressValue {
24
24
  street: string;
25
25
  /** The name of the city/locality. */
26
26
  city: string;
27
- /** The house number (formatted). */
27
+ /** The street number. */
28
28
  street_number?: string | number;
29
- /** The house number (numeric part). */
30
- house_number?: string | number;
31
29
  /** The postal code. */
32
30
  postcode?: string;
33
- /** The full postal code including letters (country-specific). */
34
- postcode_full?: string;
35
- /** The house number addition or suffix. */
31
+ /** The street number addition or suffix. */
36
32
  addition?: string;
37
33
  /** Allow for extra fields if API expands. */
38
34
  [key: string]: unknown;
@@ -92,15 +88,16 @@ type Fetcher = (input: RequestInfo | URL, init?: RequestInit) => Promise<Respons
92
88
  interface InferConfig {
93
89
  /**
94
90
  * Your Pro6PP Authorization Key.
91
+ * Optional if using a proxy.
95
92
  */
96
- authKey: string;
93
+ authKey?: string;
97
94
  /**
98
95
  * The country to perform address lookups in.
99
96
  */
100
97
  country: CountryCode;
101
98
  /**
102
- * Base URL for the Pro6PP API.
103
- * @default 'https://api.pro6pp.nl/v2'
99
+ * * If provided, this URL is used as the API endpoint (query params will be appended).
100
+ * * If not provided, the SDK defaults to 'https://api.pro6pp.nl/v2/infer/{country}'.
104
101
  */
105
102
  apiUrl?: string;
106
103
  /**
@@ -109,7 +106,7 @@ interface InferConfig {
109
106
  */
110
107
  fetcher?: Fetcher;
111
108
  /**
112
- * The number of results to fetch per batch.
109
+ * Number of suggestions to request per batch.
113
110
  * @default 20
114
111
  */
115
112
  limit?: number;
@@ -121,6 +118,7 @@ interface InferConfig {
121
118
  debounceMs?: number;
122
119
  /**
123
120
  * Maximum number of retry attempts for transient network errors.
121
+ * Valid range: 0 to 10.
124
122
  * @default 0
125
123
  */
126
124
  maxRetries?: number;
@@ -135,6 +133,13 @@ interface InferConfig {
135
133
  */
136
134
  onSelect?: (selection: AddressValue | string | null) => void;
137
135
  }
136
+ /**
137
+ * Represents a segment of text that should be highlighted or left plain.
138
+ */
139
+ interface HighlightSegment {
140
+ text: string;
141
+ match: boolean;
142
+ }
138
143
 
139
144
  /**
140
145
  * The initial state of the address inference engine.
@@ -146,8 +151,8 @@ declare const INITIAL_STATE: InferState;
146
151
  */
147
152
  declare class InferCore {
148
153
  private country;
149
- private authKey;
150
- private apiUrl;
154
+ private authKey?;
155
+ private explicitApiUrl?;
151
156
  private baseLimit;
152
157
  private currentLimit;
153
158
  private maxRetries;
@@ -161,7 +166,6 @@ declare class InferCore {
161
166
  state: InferState;
162
167
  private abortController;
163
168
  private debouncedFetch;
164
- private isSelecting;
165
169
  /**
166
170
  * Initializes a new instance of the Infer engine.
167
171
  * @param config The configuration object including API keys and callbacks.
@@ -182,7 +186,7 @@ declare class InferCore {
182
186
  * Supports:
183
187
  * - `ArrowUp`/`ArrowDown`: Navigate through the suggestion list.
184
188
  * - `Enter`: Select the currently highlighted suggestion.
185
- * - `Space`: Automatically inserts a comma if a numeric house number is detected.
189
+ * - `Space`: Automatically inserts a comma if a numeric street number is detected.
186
190
  * @param event The keyboard event from the input element.
187
191
  */
188
192
  handleKeyDown(event: KeyboardEvent | {
@@ -194,8 +198,9 @@ declare class InferCore {
194
198
  * Manually selects a suggestion or a string value.
195
199
  * This is typically called when a user clicks a suggestion in the UI.
196
200
  * @param item The suggestion object or string to select.
201
+ * @returns boolean True if the selection is a final address.
197
202
  */
198
- selectItem(item: InferResult | string): void;
203
+ selectItem(item: InferResult | string): boolean;
199
204
  private shouldAutoInsertComma;
200
205
  private finishSelection;
201
206
  private processSelection;
@@ -211,6 +216,11 @@ declare class InferCore {
211
216
  private debounce;
212
217
  }
213
218
 
214
- 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";
219
+ /**
220
+ * Splits text into matched and unmatched segments based on a fuzzy query sequence.
221
+ */
222
+ declare function getHighlightSegments(text: string, query: string): HighlightSegment[];
223
+
224
+ 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 -webkit-tap-highlight-color: transparent;\n }\n .pro6pp-wrapper * {\n box-sizing: border-box;\n }\n .pro6pp-input {\n width: 100%;\n padding: 12px 14px;\n padding-right: 48px;\n border: 1px solid #e0e0e0;\n border-radius: 8px;\n font-size: 16px;\n line-height: 1.5;\n appearance: none;\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: 4px;\n top: 0;\n bottom: 0;\n display: flex;\n align-items: center;\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: 40px;\n height: 40px;\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;\n touch-action: manipulation;\n }\n\n @media (hover: hover) {\n .pro6pp-clear-button:hover {\n color: #1f2937;\n background-color: #f3f4f6;\n }\n }\n\n .pro6pp-clear-button:active {\n background-color: #f3f4f6;\n }\n\n .pro6pp-loader {\n width: 20px;\n height: 20px;\n margin: 0 8px;\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 margin-top: 4px;\n background: #ffffff;\n border: 1px solid #e5e7eb;\n border-radius: 6px;\n box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);\n z-index: 9999;\n padding: 0;\n max-height: 260px;\n overflow-y: auto;\n display: flex;\n flex-direction: column;\n }\n\n @media (max-height: 500px) {\n .pro6pp-dropdown {\n max-height: 140px;\n }\n }\n\n .pro6pp-list {\n list-style: none;\n margin: 0;\n padding: 0;\n width: 100%;\n }\n\n .pro6pp-item {\n padding: 12px 14px;\n cursor: pointer;\n display: flex;\n align-items: center;\n font-size: 14px;\n color: #374151;\n border-bottom: 1px solid #f3f4f6;\n transition: background-color 0.1s;\n flex-shrink: 0;\n }\n\n .pro6pp-item:last-child {\n border-bottom: none;\n }\n\n @media (hover: hover) {\n .pro6pp-item:hover, .pro6pp-item--active {\n background-color: #f9fafb;\n }\n }\n\n .pro6pp-item:active {\n background-color: #f3f4f6;\n }\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 flex-grow: 1;\n }\n .pro6pp-item__chevron {\n color: #d1d5db;\n display: flex;\n align-items: center;\n margin-left: auto;\n }\n\n .pro6pp-no-results {\n padding: 24px 16px;\n color: #6b7280;\n font-size: 15px;\n text-align: center;\n }\n\n .pro6pp-load-more {\n width: 100%;\n padding: 14px;\n background: #f9fafb;\n border: none;\n border-top: 1px solid #e0e0e0;\n color: #3b82f6;\n font-size: 14px;\n font-weight: 600;\n cursor: pointer;\n flex-shrink: 0;\n touch-action: manipulation;\n }\n\n .pro6pp-load-more:active {\n background-color: #f3f4f6;\n }\n\n @keyframes pro6pp-spin {\n to { transform: rotate(360deg); }\n }\n";
215
225
 
216
- export { type AddressValue, type CountryCode, DEFAULT_STYLES, type Fetcher, INITIAL_STATE, type InferConfig, InferCore, type InferResult, type InferState, type Stage };
226
+ export { type AddressValue, type CountryCode, DEFAULT_STYLES, type Fetcher, type HighlightSegment, INITIAL_STATE, type InferConfig, InferCore, type InferResult, type InferState, type Stage, getHighlightSegments };
package/dist/index.d.ts CHANGED
@@ -9,13 +9,13 @@ type CountryCode = 'NL' | 'DE';
9
9
  * - `street`: User is selecting a street.
10
10
  * - `city`: User is selecting a city.
11
11
  * - `postcode`: User is entering a postcode.
12
- * - `house_number`: User is entering a house number.
13
- * - `house_number_first`: Specialized mode where number is entered before street.
14
- * - `addition`: Selecting a house number addition (e.g., 'A', 'III').
12
+ * - `street_number`: User is entering a street number.
13
+ * - `street_number_first`: Specialized mode where number is entered before street.
14
+ * - `addition`: Selecting a street number addition (e.g., 'A', 'III').
15
15
  * - `direct`: Direct address hit (often via postcode).
16
16
  * - `final`: A complete, valid address has been identified.
17
17
  */
18
- type Stage = 'empty' | 'mixed' | 'street' | 'city' | 'postcode' | 'house_number' | 'house_number_first' | 'addition' | 'direct' | 'final';
18
+ type Stage = 'empty' | 'mixed' | 'street' | 'city' | 'postcode' | 'street_number' | 'street_number_first' | 'addition' | 'direct' | 'final';
19
19
  /**
20
20
  * The standardized address object returned upon a successful final selection.
21
21
  */
@@ -24,15 +24,11 @@ interface AddressValue {
24
24
  street: string;
25
25
  /** The name of the city/locality. */
26
26
  city: string;
27
- /** The house number (formatted). */
27
+ /** The street number. */
28
28
  street_number?: string | number;
29
- /** The house number (numeric part). */
30
- house_number?: string | number;
31
29
  /** The postal code. */
32
30
  postcode?: string;
33
- /** The full postal code including letters (country-specific). */
34
- postcode_full?: string;
35
- /** The house number addition or suffix. */
31
+ /** The street number addition or suffix. */
36
32
  addition?: string;
37
33
  /** Allow for extra fields if API expands. */
38
34
  [key: string]: unknown;
@@ -92,15 +88,16 @@ type Fetcher = (input: RequestInfo | URL, init?: RequestInit) => Promise<Respons
92
88
  interface InferConfig {
93
89
  /**
94
90
  * Your Pro6PP Authorization Key.
91
+ * Optional if using a proxy.
95
92
  */
96
- authKey: string;
93
+ authKey?: string;
97
94
  /**
98
95
  * The country to perform address lookups in.
99
96
  */
100
97
  country: CountryCode;
101
98
  /**
102
- * Base URL for the Pro6PP API.
103
- * @default 'https://api.pro6pp.nl/v2'
99
+ * * If provided, this URL is used as the API endpoint (query params will be appended).
100
+ * * If not provided, the SDK defaults to 'https://api.pro6pp.nl/v2/infer/{country}'.
104
101
  */
105
102
  apiUrl?: string;
106
103
  /**
@@ -109,7 +106,7 @@ interface InferConfig {
109
106
  */
110
107
  fetcher?: Fetcher;
111
108
  /**
112
- * The number of results to fetch per batch.
109
+ * Number of suggestions to request per batch.
113
110
  * @default 20
114
111
  */
115
112
  limit?: number;
@@ -121,6 +118,7 @@ interface InferConfig {
121
118
  debounceMs?: number;
122
119
  /**
123
120
  * Maximum number of retry attempts for transient network errors.
121
+ * Valid range: 0 to 10.
124
122
  * @default 0
125
123
  */
126
124
  maxRetries?: number;
@@ -135,6 +133,13 @@ interface InferConfig {
135
133
  */
136
134
  onSelect?: (selection: AddressValue | string | null) => void;
137
135
  }
136
+ /**
137
+ * Represents a segment of text that should be highlighted or left plain.
138
+ */
139
+ interface HighlightSegment {
140
+ text: string;
141
+ match: boolean;
142
+ }
138
143
 
139
144
  /**
140
145
  * The initial state of the address inference engine.
@@ -146,8 +151,8 @@ declare const INITIAL_STATE: InferState;
146
151
  */
147
152
  declare class InferCore {
148
153
  private country;
149
- private authKey;
150
- private apiUrl;
154
+ private authKey?;
155
+ private explicitApiUrl?;
151
156
  private baseLimit;
152
157
  private currentLimit;
153
158
  private maxRetries;
@@ -161,7 +166,6 @@ declare class InferCore {
161
166
  state: InferState;
162
167
  private abortController;
163
168
  private debouncedFetch;
164
- private isSelecting;
165
169
  /**
166
170
  * Initializes a new instance of the Infer engine.
167
171
  * @param config The configuration object including API keys and callbacks.
@@ -182,7 +186,7 @@ declare class InferCore {
182
186
  * Supports:
183
187
  * - `ArrowUp`/`ArrowDown`: Navigate through the suggestion list.
184
188
  * - `Enter`: Select the currently highlighted suggestion.
185
- * - `Space`: Automatically inserts a comma if a numeric house number is detected.
189
+ * - `Space`: Automatically inserts a comma if a numeric street number is detected.
186
190
  * @param event The keyboard event from the input element.
187
191
  */
188
192
  handleKeyDown(event: KeyboardEvent | {
@@ -194,8 +198,9 @@ declare class InferCore {
194
198
  * Manually selects a suggestion or a string value.
195
199
  * This is typically called when a user clicks a suggestion in the UI.
196
200
  * @param item The suggestion object or string to select.
201
+ * @returns boolean True if the selection is a final address.
197
202
  */
198
- selectItem(item: InferResult | string): void;
203
+ selectItem(item: InferResult | string): boolean;
199
204
  private shouldAutoInsertComma;
200
205
  private finishSelection;
201
206
  private processSelection;
@@ -211,6 +216,11 @@ declare class InferCore {
211
216
  private debounce;
212
217
  }
213
218
 
214
- 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";
219
+ /**
220
+ * Splits text into matched and unmatched segments based on a fuzzy query sequence.
221
+ */
222
+ declare function getHighlightSegments(text: string, query: string): HighlightSegment[];
223
+
224
+ 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 -webkit-tap-highlight-color: transparent;\n }\n .pro6pp-wrapper * {\n box-sizing: border-box;\n }\n .pro6pp-input {\n width: 100%;\n padding: 12px 14px;\n padding-right: 48px;\n border: 1px solid #e0e0e0;\n border-radius: 8px;\n font-size: 16px;\n line-height: 1.5;\n appearance: none;\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: 4px;\n top: 0;\n bottom: 0;\n display: flex;\n align-items: center;\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: 40px;\n height: 40px;\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;\n touch-action: manipulation;\n }\n\n @media (hover: hover) {\n .pro6pp-clear-button:hover {\n color: #1f2937;\n background-color: #f3f4f6;\n }\n }\n\n .pro6pp-clear-button:active {\n background-color: #f3f4f6;\n }\n\n .pro6pp-loader {\n width: 20px;\n height: 20px;\n margin: 0 8px;\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 margin-top: 4px;\n background: #ffffff;\n border: 1px solid #e5e7eb;\n border-radius: 6px;\n box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);\n z-index: 9999;\n padding: 0;\n max-height: 260px;\n overflow-y: auto;\n display: flex;\n flex-direction: column;\n }\n\n @media (max-height: 500px) {\n .pro6pp-dropdown {\n max-height: 140px;\n }\n }\n\n .pro6pp-list {\n list-style: none;\n margin: 0;\n padding: 0;\n width: 100%;\n }\n\n .pro6pp-item {\n padding: 12px 14px;\n cursor: pointer;\n display: flex;\n align-items: center;\n font-size: 14px;\n color: #374151;\n border-bottom: 1px solid #f3f4f6;\n transition: background-color 0.1s;\n flex-shrink: 0;\n }\n\n .pro6pp-item:last-child {\n border-bottom: none;\n }\n\n @media (hover: hover) {\n .pro6pp-item:hover, .pro6pp-item--active {\n background-color: #f9fafb;\n }\n }\n\n .pro6pp-item:active {\n background-color: #f3f4f6;\n }\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 flex-grow: 1;\n }\n .pro6pp-item__chevron {\n color: #d1d5db;\n display: flex;\n align-items: center;\n margin-left: auto;\n }\n\n .pro6pp-no-results {\n padding: 24px 16px;\n color: #6b7280;\n font-size: 15px;\n text-align: center;\n }\n\n .pro6pp-load-more {\n width: 100%;\n padding: 14px;\n background: #f9fafb;\n border: none;\n border-top: 1px solid #e0e0e0;\n color: #3b82f6;\n font-size: 14px;\n font-weight: 600;\n cursor: pointer;\n flex-shrink: 0;\n touch-action: manipulation;\n }\n\n .pro6pp-load-more:active {\n background-color: #f3f4f6;\n }\n\n @keyframes pro6pp-spin {\n to { transform: rotate(360deg); }\n }\n";
215
225
 
216
- export { type AddressValue, type CountryCode, DEFAULT_STYLES, type Fetcher, INITIAL_STATE, type InferConfig, InferCore, type InferResult, type InferState, type Stage };
226
+ export { type AddressValue, type CountryCode, DEFAULT_STYLES, type Fetcher, type HighlightSegment, INITIAL_STATE, type InferConfig, InferCore, type InferResult, type InferState, type Stage, getHighlightSegments };
@@ -1,21 +1,23 @@
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 T=(a,e)=>{for(var t in e)h(a,t,{get:e[t],enumerable:!0})},C=(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 L=a=>C(h({},"__esModule",{value:!0}),a);var l=(a,e,t)=>w(a,typeof e!="symbol"?e+"":e,t);var _={};T(_,{DEFAULT_STYLES:()=>S,INITIAL_STATE:()=>g,InferCore:()=>f});var c={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,"apiUrl");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.apiUrl=e.apiUrl||c.API_URL,this.baseLimit=e.limit||c.LIMIT,this.currentLimit=this.baseLimit;let t=e.maxRetries!==void 0?e.maxRetries:c.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:c.DEBOUNCE_MS,s=Math.max(i,c.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 n=t;if(s&&Object.keys(s).length>0){let{street:p,street_number:u,house_number:d,city:b}=s,m=u||d;p&&m&&b&&(n=`${p} ${m}, ${b}`)}this.finishSelection(n,s);return}let o=typeof e!="string"?e.subtitle:null;this.processSelection(i,o)}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),setTimeout(()=>{this.isSelecting=!1},0)}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 u=this.getQueryPrefix(s);r=u?`${u} ${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=new URL(`${this.apiUrl}/infer/${this.country.toLowerCase()}`),o={authKey:this.authKey,query:i,limit:this.currentLimit.toString()};r.search=new URLSearchParams(o).toString(),this.fetcher(r.toString(),{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=[],n=new Set;for(let u of r){let d=`${u.label}|${u.subtitle||""}|${JSON.stringify(u.value||{})}`;n.has(d)||(n.add(d),o.push(u))}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=[]):(t.suggestions=o,t.cities=[],t.streets=[],e.stage==="final"&&o.length===1&&(i=!0,s=o[0])),t.isValid=e.stage==="final",i&&s){t.query=s.label,t.suggestions=[],t.cities=[],t.streets=[],t.isValid=!0,t.hasMore=!1,this.updateState(t);let u=typeof s.value=="object"?s.value:s.label;this.onSelect(u)}else this.updateState(t)}updateQueryAndFetch(e){this.updateState({query:e,suggestions:[],cities:[],streets:[]}),this.updateState({isLoading:!0,isValid:!1,hasMore:!1}),this.debouncedFetch(e),setTimeout(()=>{this.isSelecting=!1},0)}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=`
1
+ "use strict";var Pro6PPCore=(()=>{var h=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var S=Object.getOwnPropertyNames;var y=Object.prototype.hasOwnProperty;var v=(n,t,e)=>t in n?h(n,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):n[t]=e;var I=(n,t)=>{for(var e in t)h(n,e,{get:t[e],enumerable:!0})},C=(n,t,e,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of S(t))!y.call(n,r)&&r!==e&&h(n,r,{get:()=>t[r],enumerable:!(i=x(t,r))||i.enumerable});return n};var T=n=>C(h({},"__esModule",{value:!0}),n);var l=(n,t,e)=>v(n,typeof t!="symbol"?t+"":t,e);var w={};I(w,{DEFAULT_STYLES:()=>b,INITIAL_STATE:()=>g,InferCore:()=>f,getHighlightSegments:()=>L});var c={API_URL:"https://api.pro6pp.nl/v2",LIMIT:20,DEBOUNCE_MS:150,MIN_DEBOUNCE_MS:50,MAX_RETRIES:0},m={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(t){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");this.country=t.country,this.authKey=t.authKey,this.explicitApiUrl=t.apiUrl,this.baseLimit=t.limit||c.LIMIT,this.currentLimit=this.baseLimit;let e=t.maxRetries!==void 0?t.maxRetries:c.MAX_RETRIES;this.maxRetries=Math.max(0,Math.min(e,10)),this.fetcher=t.fetcher||((s,a)=>fetch(s,a)),this.onStateChange=t.onStateChange||(()=>{}),this.onSelect=t.onSelect||(()=>{}),this.state={...g};let i=t.debounceMs!==void 0?t.debounceMs:c.DEBOUNCE_MS,r=Math.max(i,c.MIN_DEBOUNCE_MS);this.debouncedFetch=this.debounce(s=>this.executeFetch(s),r)}handleInput(t){this.currentLimit=this.baseLimit;let e=this.state.stage==="final"&&t!==this.state.query;this.updateState({query:t,isValid:!1,isLoading:!!t.trim(),selectedSuggestionIndex:-1,hasMore:!1}),e&&this.onSelect(null),this.debouncedFetch(t)}loadMore(){this.state.isLoading||(this.currentLimit+=this.baseLimit,this.updateState({isLoading:!0}),this.executeFetch(this.state.query))}handleKeyDown(t){let e=t.target;if(!e)return;let i=this.state.cities.length+this.state.streets.length+this.state.suggestions.length;if(i>0){if(t.key==="ArrowDown"){t.preventDefault();let s=this.state.selectedSuggestionIndex+1;s>=i&&(s=0),this.updateState({selectedSuggestionIndex:s});return}if(t.key==="ArrowUp"){t.preventDefault();let s=this.state.selectedSuggestionIndex-1;s<0&&(s=i-1),this.updateState({selectedSuggestionIndex:s});return}if(t.key==="Enter"&&this.state.selectedSuggestionIndex>=0){t.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 r=e.value;if(t.key===" "&&this.shouldAutoInsertComma(r)){t.preventDefault();let s=`${r.trim()}, `;this.updateQueryAndFetch(s)}}selectItem(t){this.debouncedFetch.cancel(),this.abortController&&this.abortController.abort();let e=typeof t=="string"?t:t.label,i=e;typeof t!="string"&&typeof t.value=="string"&&(i=t.value);let r=typeof t!="string"&&typeof t.value=="object"?t.value:void 0,s=!!r&&Object.keys(r).length>0;if(this.state.stage==="final"||s){let p=e;if(r&&Object.keys(r).length>0){let{street:u,street_number:o,city:d}=r;u&&o&&d&&(p=`${u} ${o}, ${d}`)}return this.finishSelection(p,r),!0}let a=typeof t!="string"?t.subtitle:null;return this.processSelection(i,a),!1}shouldAutoInsertComma(t){if(!t.includes(",")&&m.DIGITS_1_3.test(t.trim()))return!0;if(this.state.stage==="street_number"){let i=this.getCurrentFragment(t);return m.DIGITS_1_3.test(i)}return!1}finishSelection(t,e){this.updateState({query:t,suggestions:[],cities:[],streets:[],isValid:!0,stage:"final",hasMore:!1}),this.onSelect(e||t)}processSelection(t,e){let{stage:i,query:r}=this.state,s=r;if(e&&(i==="city"||i==="street"||i==="mixed")){if(i==="city")s=`${e}, ${t}, `;else{let o=this.getQueryPrefix(r);s=o?`${o} ${t}, ${e}, `:`${t}, ${e}, `}this.updateQueryAndFetch(s);return}if(i==="direct"||i==="addition"){this.finishSelection(t);return}!r.includes(",")&&(i==="city"||i==="street"||i==="street_number_first")?s=`${t}, `:(s=this.replaceLastSegment(r,t),i!=="street_number"&&(s+=", ")),this.updateQueryAndFetch(s)}executeFetch(t,e=0){let i=(t||"").toString();if(!i.trim()){this.abortController?.abort(),this.resetState();return}e===0&&(this.updateState({isError:!1}),this.abortController&&this.abortController.abort(),this.abortController=new AbortController);let r=this.abortController?.signal,s=this.explicitApiUrl?this.explicitApiUrl:`${c.API_URL}/infer/${this.country.toLowerCase()}`,a=new URLSearchParams({country:this.country.toLowerCase(),query:i,limit:this.currentLimit.toString()});this.authKey&&a.set("authKey",this.authKey);let p=s.includes("?")?"&":"?",u=`${s}${p}${a.toString()}`;this.fetcher(u,{signal:r}).then(o=>{if(!o.ok){if(e<this.maxRetries&&(o.status>=500||o.status===429))return this.retry(t,e,r);throw new Error("Network error")}return o.json()}).then(o=>{o&&this.mapResponseToState(o)}).catch(o=>{if(o.name!=="AbortError"){if(e<this.maxRetries)return this.retry(t,e,r);this.updateState({isError:!0,isLoading:!1})}})}retry(t,e,i){if(i?.aborted)return;let r=Math.pow(2,e)*200;setTimeout(()=>{i?.aborted||this.executeFetch(t,e+1)},r)}mapResponseToState(t){let e={stage:t.stage,isLoading:!1},i=t.suggestions||[],r=[],s=new Set;for(let p of i){let u=`${p.label}|${p.subtitle||""}|${JSON.stringify(p.value||{})}`;s.has(u)||(s.add(u),r.push(p))}let a=r.length+(t.cities?.length||0)+(t.streets?.length||0);e.hasMore=a>=this.currentLimit,t.stage==="mixed"?(e.cities=t.cities||[],e.streets=t.streets||[],e.suggestions=[]):(e.suggestions=r,e.cities=[],e.streets=[]),e.isValid=t.stage==="final",this.updateState(e)}updateQueryAndFetch(t){this.updateState({query:t,suggestions:[],cities:[],streets:[]}),this.updateState({isLoading:!0,isValid:!1,hasMore:!1}),this.debouncedFetch(t)}replaceLastSegment(t,e){let i=t.lastIndexOf(",");return i===-1?e:`${t.slice(0,i+1)} ${e}`.trim()}getQueryPrefix(t){let e=t.lastIndexOf(",");return e===-1?"":t.slice(0,e+1).trimEnd()}getCurrentFragment(t){return(t.split(",").slice(-1)[0]??"").trim()}resetState(){this.updateState({...g,query:this.state.query})}updateState(t){this.state={...this.state,...t},this.onStateChange(this.state)}debounce(t,e){let i,r=(...s)=>{i&&clearTimeout(i),i=setTimeout(()=>t.apply(this,s),e)};return r.cancel=()=>{i&&(clearTimeout(i),i=void 0)},r}};function L(n,t){if(!t||!n)return[{text:n,match:!1}];let e=[],i=n.toLowerCase(),r=t.toLowerCase(),s=0,a=0;for(let o=0;o<n.length;o++){if(!(s<t.length&&i[o]===r[s]))continue;o>a&&e.push({text:n.slice(a,o),match:!1}),e.push({text:n[o],match:!0}),s++,a=o+1}return a<n.length&&e.push({text:n.slice(a),match:!1}),s===t.length?e:[{text:n,match:!1}]}var b=`
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: 10px 12px;
14
+ padding: 12px 14px;
14
15
  padding-right: 48px;
15
16
  border: 1px solid #e0e0e0;
16
- border-radius: 4px;
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
  }
21
23
  .pro6pp-input:focus {
@@ -26,12 +28,11 @@
26
28
 
27
29
  .pro6pp-input-addons {
28
30
  position: absolute;
29
- right: 6px;
31
+ right: 4px;
30
32
  top: 0;
31
33
  bottom: 0;
32
34
  display: flex;
33
35
  align-items: center;
34
- gap: 2px;
35
36
  pointer-events: none;
36
37
  }
37
38
  .pro6pp-input-addons > * {
@@ -41,32 +42,33 @@
41
42
  .pro6pp-clear-button {
42
43
  background: none;
43
44
  border: none;
44
- width: 28px;
45
- height: 28px;
45
+ width: 40px;
46
+ height: 40px;
46
47
  cursor: pointer;
47
48
  color: #a3a3a3;
48
49
  display: flex;
49
50
  align-items: center;
50
51
  justify-content: center;
51
52
  border-radius: 50%;
52
- transition: color 0.2s, background-color 0.2s, transform 0.1s;
53
+ transition: color 0.2s, background-color 0.2s;
54
+ touch-action: manipulation;
53
55
  }
54
- .pro6pp-clear-button:hover {
55
- color: #1f2937;
56
- background-color: #f3f4f6;
56
+
57
+ @media (hover: hover) {
58
+ .pro6pp-clear-button:hover {
59
+ color: #1f2937;
60
+ background-color: #f3f4f6;
61
+ }
57
62
  }
63
+
58
64
  .pro6pp-clear-button:active {
59
- transform: scale(0.92);
60
- }
61
- .pro6pp-clear-button svg {
62
- width: 18px;
63
- height: 18px;
65
+ background-color: #f3f4f6;
64
66
  }
65
67
 
66
68
  .pro6pp-loader {
67
- width: 18px;
68
- height: 18px;
69
- margin: 0 4px;
69
+ width: 20px;
70
+ height: 20px;
71
+ margin: 0 8px;
70
72
  border: 2px solid #e0e0e0;
71
73
  border-top-color: #6b7280;
72
74
  border-radius: 50%;
@@ -79,38 +81,58 @@
79
81
  top: 100%;
80
82
  left: 0;
81
83
  right: 0;
82
- z-index: 9999;
83
84
  margin-top: 4px;
84
- background: white;
85
- border: 1px solid #e0e0e0;
86
- border-radius: 4px;
87
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
88
- max-height: 300px;
85
+ background: #ffffff;
86
+ border: 1px solid #e5e7eb;
87
+ border-radius: 6px;
88
+ box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
89
+ z-index: 9999;
90
+ padding: 0;
91
+ max-height: 260px;
89
92
  overflow-y: auto;
90
93
  display: flex;
91
94
  flex-direction: column;
92
95
  }
96
+
97
+ @media (max-height: 500px) {
98
+ .pro6pp-dropdown {
99
+ max-height: 140px;
100
+ }
101
+ }
102
+
93
103
  .pro6pp-list {
94
- list-style: none !important;
95
- padding: 0 !important;
96
- margin: 0 !important;
97
- flex-grow: 1;
104
+ list-style: none;
105
+ margin: 0;
106
+ padding: 0;
107
+ width: 100%;
98
108
  }
109
+
99
110
  .pro6pp-item {
100
- padding: 12px 16px;
111
+ padding: 12px 14px;
101
112
  cursor: pointer;
102
113
  display: flex;
103
- flex-direction: row;
104
114
  align-items: center;
105
- color: #111827;
106
115
  font-size: 14px;
107
- line-height: 1.2;
108
- white-space: nowrap;
109
- overflow: hidden;
116
+ color: #374151;
117
+ border-bottom: 1px solid #f3f4f6;
118
+ transition: background-color 0.1s;
119
+ flex-shrink: 0;
110
120
  }
111
- .pro6pp-item:hover, .pro6pp-item--active {
112
- background-color: #f9fafb;
121
+
122
+ .pro6pp-item:last-child {
123
+ border-bottom: none;
124
+ }
125
+
126
+ @media (hover: hover) {
127
+ .pro6pp-item:hover, .pro6pp-item--active {
128
+ background-color: #f9fafb;
129
+ }
130
+ }
131
+
132
+ .pro6pp-item:active {
133
+ background-color: #f3f4f6;
113
134
  }
135
+
114
136
  .pro6pp-item__label {
115
137
  font-weight: 500;
116
138
  flex-shrink: 0;
@@ -118,41 +140,41 @@
118
140
  .pro6pp-item__subtitle {
119
141
  font-size: 14px;
120
142
  color: #6b7280;
121
- overflow: hidden;
122
- text-overflow: ellipsis;
123
- flex-shrink: 1;
143
+ flex-grow: 1;
124
144
  }
125
145
  .pro6pp-item__chevron {
126
- margin-left: auto;
146
+ color: #d1d5db;
127
147
  display: flex;
128
148
  align-items: center;
129
- color: #9ca3af;
130
- padding-left: 8px;
149
+ margin-left: auto;
131
150
  }
151
+
132
152
  .pro6pp-no-results {
133
- padding: 16px;
153
+ padding: 24px 16px;
134
154
  color: #6b7280;
135
- font-size: 14px;
155
+ font-size: 15px;
136
156
  text-align: center;
137
157
  }
158
+
138
159
  .pro6pp-load-more {
139
160
  width: 100%;
140
- padding: 10px;
161
+ padding: 14px;
141
162
  background: #f9fafb;
142
163
  border: none;
143
164
  border-top: 1px solid #e0e0e0;
144
165
  color: #3b82f6;
145
- font-size: 13px;
166
+ font-size: 14px;
146
167
  font-weight: 600;
147
168
  cursor: pointer;
148
- transition: background-color 0.2s;
149
169
  flex-shrink: 0;
170
+ touch-action: manipulation;
150
171
  }
151
- .pro6pp-load-more:hover {
172
+
173
+ .pro6pp-load-more:active {
152
174
  background-color: #f3f4f6;
153
175
  }
154
176
 
155
177
  @keyframes pro6pp-spin {
156
178
  to { transform: rotate(360deg); }
157
179
  }
158
- `;return L(_);})();
180
+ `;return T(w);})();
package/dist/index.js CHANGED
@@ -1,21 +1,23 @@
1
- var x=Object.defineProperty;var S=(u,e,t)=>e in u?x(u,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):u[e]=t;var a=(u,e,t)=>S(u,typeof e!="symbol"?e+"":e,t);var c={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,"apiUrl");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.apiUrl=e.apiUrl||c.API_URL,this.baseLimit=e.limit||c.LIMIT,this.currentLimit=this.baseLimit;let t=e.maxRetries!==void 0?e.maxRetries:c.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:c.DEBOUNCE_MS,s=Math.max(i,c.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 n=t;if(s&&Object.keys(s).length>0){let{street:p,street_number:l,house_number:d,city:h}=s,g=l||d;p&&g&&h&&(n=`${p} ${g}, ${h}`)}this.finishSelection(n,s);return}let o=typeof e!="string"?e.subtitle:null;this.processSelection(i,o)}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),setTimeout(()=>{this.isSelecting=!1},0)}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 l=this.getQueryPrefix(s);r=l?`${l} ${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=new URL(`${this.apiUrl}/infer/${this.country.toLowerCase()}`),o={authKey:this.authKey,query:i,limit:this.currentLimit.toString()};r.search=new URLSearchParams(o).toString(),this.fetcher(r.toString(),{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=[],n=new Set;for(let l of r){let d=`${l.label}|${l.subtitle||""}|${JSON.stringify(l.value||{})}`;n.has(d)||(n.add(d),o.push(l))}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=[]):(t.suggestions=o,t.cities=[],t.streets=[],e.stage==="final"&&o.length===1&&(i=!0,s=o[0])),t.isValid=e.stage==="final",i&&s){t.query=s.label,t.suggestions=[],t.cities=[],t.streets=[],t.isValid=!0,t.hasMore=!1,this.updateState(t);let l=typeof s.value=="object"?s.value:s.label;this.onSelect(l)}else this.updateState(t)}updateQueryAndFetch(e){this.updateState({query:e,suggestions:[],cities:[],streets:[]}),this.updateState({isLoading:!0,isValid:!1,hasMore:!1}),this.debouncedFetch(e),setTimeout(()=>{this.isSelecting=!1},0)}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=`
1
+ var m=Object.defineProperty;var b=(a,t,e)=>t in a?m(a,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):a[t]=e;var l=(a,t,e)=>b(a,typeof t!="symbol"?t+"":t,e);var c={API_URL:"https://api.pro6pp.nl/v2",LIMIT:20,DEBOUNCE_MS:150,MIN_DEBOUNCE_MS:50,MAX_RETRIES:0},d={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(t){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");this.country=t.country,this.authKey=t.authKey,this.explicitApiUrl=t.apiUrl,this.baseLimit=t.limit||c.LIMIT,this.currentLimit=this.baseLimit;let e=t.maxRetries!==void 0?t.maxRetries:c.MAX_RETRIES;this.maxRetries=Math.max(0,Math.min(e,10)),this.fetcher=t.fetcher||((r,o)=>fetch(r,o)),this.onStateChange=t.onStateChange||(()=>{}),this.onSelect=t.onSelect||(()=>{}),this.state={...g};let i=t.debounceMs!==void 0?t.debounceMs:c.DEBOUNCE_MS,s=Math.max(i,c.MIN_DEBOUNCE_MS);this.debouncedFetch=this.debounce(r=>this.executeFetch(r),s)}handleInput(t){this.currentLimit=this.baseLimit;let e=this.state.stage==="final"&&t!==this.state.query;this.updateState({query:t,isValid:!1,isLoading:!!t.trim(),selectedSuggestionIndex:-1,hasMore:!1}),e&&this.onSelect(null),this.debouncedFetch(t)}loadMore(){this.state.isLoading||(this.currentLimit+=this.baseLimit,this.updateState({isLoading:!0}),this.executeFetch(this.state.query))}handleKeyDown(t){let e=t.target;if(!e)return;let i=this.state.cities.length+this.state.streets.length+this.state.suggestions.length;if(i>0){if(t.key==="ArrowDown"){t.preventDefault();let r=this.state.selectedSuggestionIndex+1;r>=i&&(r=0),this.updateState({selectedSuggestionIndex:r});return}if(t.key==="ArrowUp"){t.preventDefault();let r=this.state.selectedSuggestionIndex-1;r<0&&(r=i-1),this.updateState({selectedSuggestionIndex:r});return}if(t.key==="Enter"&&this.state.selectedSuggestionIndex>=0){t.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=e.value;if(t.key===" "&&this.shouldAutoInsertComma(s)){t.preventDefault();let r=`${s.trim()}, `;this.updateQueryAndFetch(r)}}selectItem(t){this.debouncedFetch.cancel(),this.abortController&&this.abortController.abort();let e=typeof t=="string"?t:t.label,i=e;typeof t!="string"&&typeof t.value=="string"&&(i=t.value);let s=typeof t!="string"&&typeof t.value=="object"?t.value:void 0,r=!!s&&Object.keys(s).length>0;if(this.state.stage==="final"||r){let p=e;if(s&&Object.keys(s).length>0){let{street:u,street_number:n,city:h}=s;u&&n&&h&&(p=`${u} ${n}, ${h}`)}return this.finishSelection(p,s),!0}let o=typeof t!="string"?t.subtitle:null;return this.processSelection(i,o),!1}shouldAutoInsertComma(t){if(!t.includes(",")&&d.DIGITS_1_3.test(t.trim()))return!0;if(this.state.stage==="street_number"){let i=this.getCurrentFragment(t);return d.DIGITS_1_3.test(i)}return!1}finishSelection(t,e){this.updateState({query:t,suggestions:[],cities:[],streets:[],isValid:!0,stage:"final",hasMore:!1}),this.onSelect(e||t)}processSelection(t,e){let{stage:i,query:s}=this.state,r=s;if(e&&(i==="city"||i==="street"||i==="mixed")){if(i==="city")r=`${e}, ${t}, `;else{let n=this.getQueryPrefix(s);r=n?`${n} ${t}, ${e}, `:`${t}, ${e}, `}this.updateQueryAndFetch(r);return}if(i==="direct"||i==="addition"){this.finishSelection(t);return}!s.includes(",")&&(i==="city"||i==="street"||i==="street_number_first")?r=`${t}, `:(r=this.replaceLastSegment(s,t),i!=="street_number"&&(r+=", ")),this.updateQueryAndFetch(r)}executeFetch(t,e=0){let i=(t||"").toString();if(!i.trim()){this.abortController?.abort(),this.resetState();return}e===0&&(this.updateState({isError:!1}),this.abortController&&this.abortController.abort(),this.abortController=new AbortController);let s=this.abortController?.signal,r=this.explicitApiUrl?this.explicitApiUrl:`${c.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 p=r.includes("?")?"&":"?",u=`${r}${p}${o.toString()}`;this.fetcher(u,{signal:s}).then(n=>{if(!n.ok){if(e<this.maxRetries&&(n.status>=500||n.status===429))return this.retry(t,e,s);throw new Error("Network error")}return n.json()}).then(n=>{n&&this.mapResponseToState(n)}).catch(n=>{if(n.name!=="AbortError"){if(e<this.maxRetries)return this.retry(t,e,s);this.updateState({isError:!0,isLoading:!1})}})}retry(t,e,i){if(i?.aborted)return;let s=Math.pow(2,e)*200;setTimeout(()=>{i?.aborted||this.executeFetch(t,e+1)},s)}mapResponseToState(t){let e={stage:t.stage,isLoading:!1},i=t.suggestions||[],s=[],r=new Set;for(let p of i){let u=`${p.label}|${p.subtitle||""}|${JSON.stringify(p.value||{})}`;r.has(u)||(r.add(u),s.push(p))}let o=s.length+(t.cities?.length||0)+(t.streets?.length||0);e.hasMore=o>=this.currentLimit,t.stage==="mixed"?(e.cities=t.cities||[],e.streets=t.streets||[],e.suggestions=[]):(e.suggestions=s,e.cities=[],e.streets=[]),e.isValid=t.stage==="final",this.updateState(e)}updateQueryAndFetch(t){this.updateState({query:t,suggestions:[],cities:[],streets:[]}),this.updateState({isLoading:!0,isValid:!1,hasMore:!1}),this.debouncedFetch(t)}replaceLastSegment(t,e){let i=t.lastIndexOf(",");return i===-1?e:`${t.slice(0,i+1)} ${e}`.trim()}getQueryPrefix(t){let e=t.lastIndexOf(",");return e===-1?"":t.slice(0,e+1).trimEnd()}getCurrentFragment(t){return(t.split(",").slice(-1)[0]??"").trim()}resetState(){this.updateState({...g,query:this.state.query})}updateState(t){this.state={...this.state,...t},this.onStateChange(this.state)}debounce(t,e){let i,s=(...r)=>{i&&clearTimeout(i),i=setTimeout(()=>t.apply(this,r),e)};return s.cancel=()=>{i&&(clearTimeout(i),i=void 0)},s}};function C(a,t){if(!t||!a)return[{text:a,match:!1}];let e=[],i=a.toLowerCase(),s=t.toLowerCase(),r=0,o=0;for(let n=0;n<a.length;n++){if(!(r<t.length&&i[n]===s[r]))continue;n>o&&e.push({text:a.slice(o,n),match:!1}),e.push({text:a[n],match:!0}),r++,o=n+1}return o<a.length&&e.push({text:a.slice(o),match:!1}),r===t.length?e:[{text:a,match:!1}]}var x=`
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: 10px 12px;
14
+ padding: 12px 14px;
14
15
  padding-right: 48px;
15
16
  border: 1px solid #e0e0e0;
16
- border-radius: 4px;
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
  }
21
23
  .pro6pp-input:focus {
@@ -26,12 +28,11 @@ var x=Object.defineProperty;var S=(u,e,t)=>e in u?x(u,e,{enumerable:!0,configura
26
28
 
27
29
  .pro6pp-input-addons {
28
30
  position: absolute;
29
- right: 6px;
31
+ right: 4px;
30
32
  top: 0;
31
33
  bottom: 0;
32
34
  display: flex;
33
35
  align-items: center;
34
- gap: 2px;
35
36
  pointer-events: none;
36
37
  }
37
38
  .pro6pp-input-addons > * {
@@ -41,32 +42,33 @@ var x=Object.defineProperty;var S=(u,e,t)=>e in u?x(u,e,{enumerable:!0,configura
41
42
  .pro6pp-clear-button {
42
43
  background: none;
43
44
  border: none;
44
- width: 28px;
45
- height: 28px;
45
+ width: 40px;
46
+ height: 40px;
46
47
  cursor: pointer;
47
48
  color: #a3a3a3;
48
49
  display: flex;
49
50
  align-items: center;
50
51
  justify-content: center;
51
52
  border-radius: 50%;
52
- transition: color 0.2s, background-color 0.2s, transform 0.1s;
53
+ transition: color 0.2s, background-color 0.2s;
54
+ touch-action: manipulation;
53
55
  }
54
- .pro6pp-clear-button:hover {
55
- color: #1f2937;
56
- background-color: #f3f4f6;
56
+
57
+ @media (hover: hover) {
58
+ .pro6pp-clear-button:hover {
59
+ color: #1f2937;
60
+ background-color: #f3f4f6;
61
+ }
57
62
  }
63
+
58
64
  .pro6pp-clear-button:active {
59
- transform: scale(0.92);
60
- }
61
- .pro6pp-clear-button svg {
62
- width: 18px;
63
- height: 18px;
65
+ background-color: #f3f4f6;
64
66
  }
65
67
 
66
68
  .pro6pp-loader {
67
- width: 18px;
68
- height: 18px;
69
- margin: 0 4px;
69
+ width: 20px;
70
+ height: 20px;
71
+ margin: 0 8px;
70
72
  border: 2px solid #e0e0e0;
71
73
  border-top-color: #6b7280;
72
74
  border-radius: 50%;
@@ -79,38 +81,58 @@ var x=Object.defineProperty;var S=(u,e,t)=>e in u?x(u,e,{enumerable:!0,configura
79
81
  top: 100%;
80
82
  left: 0;
81
83
  right: 0;
82
- z-index: 9999;
83
84
  margin-top: 4px;
84
- background: white;
85
- border: 1px solid #e0e0e0;
86
- border-radius: 4px;
87
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
88
- max-height: 300px;
85
+ background: #ffffff;
86
+ border: 1px solid #e5e7eb;
87
+ border-radius: 6px;
88
+ box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
89
+ z-index: 9999;
90
+ padding: 0;
91
+ max-height: 260px;
89
92
  overflow-y: auto;
90
93
  display: flex;
91
94
  flex-direction: column;
92
95
  }
96
+
97
+ @media (max-height: 500px) {
98
+ .pro6pp-dropdown {
99
+ max-height: 140px;
100
+ }
101
+ }
102
+
93
103
  .pro6pp-list {
94
- list-style: none !important;
95
- padding: 0 !important;
96
- margin: 0 !important;
97
- flex-grow: 1;
104
+ list-style: none;
105
+ margin: 0;
106
+ padding: 0;
107
+ width: 100%;
98
108
  }
109
+
99
110
  .pro6pp-item {
100
- padding: 12px 16px;
111
+ padding: 12px 14px;
101
112
  cursor: pointer;
102
113
  display: flex;
103
- flex-direction: row;
104
114
  align-items: center;
105
- color: #111827;
106
115
  font-size: 14px;
107
- line-height: 1.2;
108
- white-space: nowrap;
109
- overflow: hidden;
116
+ color: #374151;
117
+ border-bottom: 1px solid #f3f4f6;
118
+ transition: background-color 0.1s;
119
+ flex-shrink: 0;
110
120
  }
111
- .pro6pp-item:hover, .pro6pp-item--active {
112
- background-color: #f9fafb;
121
+
122
+ .pro6pp-item:last-child {
123
+ border-bottom: none;
124
+ }
125
+
126
+ @media (hover: hover) {
127
+ .pro6pp-item:hover, .pro6pp-item--active {
128
+ background-color: #f9fafb;
129
+ }
130
+ }
131
+
132
+ .pro6pp-item:active {
133
+ background-color: #f3f4f6;
113
134
  }
135
+
114
136
  .pro6pp-item__label {
115
137
  font-weight: 500;
116
138
  flex-shrink: 0;
@@ -118,41 +140,41 @@ var x=Object.defineProperty;var S=(u,e,t)=>e in u?x(u,e,{enumerable:!0,configura
118
140
  .pro6pp-item__subtitle {
119
141
  font-size: 14px;
120
142
  color: #6b7280;
121
- overflow: hidden;
122
- text-overflow: ellipsis;
123
- flex-shrink: 1;
143
+ flex-grow: 1;
124
144
  }
125
145
  .pro6pp-item__chevron {
126
- margin-left: auto;
146
+ color: #d1d5db;
127
147
  display: flex;
128
148
  align-items: center;
129
- color: #9ca3af;
130
- padding-left: 8px;
149
+ margin-left: auto;
131
150
  }
151
+
132
152
  .pro6pp-no-results {
133
- padding: 16px;
153
+ padding: 24px 16px;
134
154
  color: #6b7280;
135
- font-size: 14px;
155
+ font-size: 15px;
136
156
  text-align: center;
137
157
  }
158
+
138
159
  .pro6pp-load-more {
139
160
  width: 100%;
140
- padding: 10px;
161
+ padding: 14px;
141
162
  background: #f9fafb;
142
163
  border: none;
143
164
  border-top: 1px solid #e0e0e0;
144
165
  color: #3b82f6;
145
- font-size: 13px;
166
+ font-size: 14px;
146
167
  font-weight: 600;
147
168
  cursor: pointer;
148
- transition: background-color 0.2s;
149
169
  flex-shrink: 0;
170
+ touch-action: manipulation;
150
171
  }
151
- .pro6pp-load-more:hover {
172
+
173
+ .pro6pp-load-more:active {
152
174
  background-color: #f3f4f6;
153
175
  }
154
176
 
155
177
  @keyframes pro6pp-spin {
156
178
  to { transform: rotate(360deg); }
157
179
  }
158
- `;export{y as DEFAULT_STYLES,b as INITIAL_STATE,m as InferCore};
180
+ `;export{x as DEFAULT_STYLES,g as INITIAL_STATE,f as InferCore,C as getHighlightSegments};
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.7",
25
+ "version": "0.0.2-beta.9",
26
26
  "main": "./dist/index.cjs",
27
27
  "module": "./dist/index.js",
28
28
  "types": "./dist/index.d.ts",