@pro6pp/infer-js 0.0.2-beta.0 → 0.0.2-beta.10

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.
@@ -1,222 +1,79 @@
1
- "use strict";
2
- var Pro6PP = (() => {
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __hasOwnProp = Object.prototype.hasOwnProperty;
7
- var __export = (target, all) => {
8
- for (var name in all)
9
- __defProp(target, name, { get: all[name], enumerable: true });
10
- };
11
- var __copyProps = (to, from, except, desc) => {
12
- if (from && typeof from === "object" || typeof from === "function") {
13
- for (let key of __getOwnPropNames(from))
14
- if (!__hasOwnProp.call(to, key) && key !== except)
15
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
- }
17
- return to;
18
- };
19
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
1
+ "use strict";var Pro6PP=(()=>{var g=Object.defineProperty,k=Object.defineProperties,A=Object.getOwnPropertyDescriptor,_=Object.getOwnPropertyDescriptors,B=Object.getOwnPropertyNames,w=Object.getOwnPropertySymbols;var I=Object.prototype.hasOwnProperty,D=Object.prototype.propertyIsEnumerable;var E=(o,t,e)=>t in o?g(o,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):o[t]=e,c=(o,t)=>{for(var e in t||(t={}))I.call(t,e)&&E(o,e,t[e]);if(w)for(var e of w(t))D.call(t,e)&&E(o,e,t[e]);return o},m=(o,t)=>k(o,_(t));var F=(o,t)=>{for(var e in t)g(o,e,{get:t[e],enumerable:!0})},R=(o,t,e,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of B(t))!I.call(o,n)&&n!==e&&g(o,n,{get:()=>t[n],enumerable:!(i=A(t,n))||i.enumerable});return o};var N=o=>R(g({},"__esModule",{value:!0}),o);var U={};F(U,{InferJS:()=>x,attach:()=>$});var f={API_URL:"https://api.pro6pp.nl/v2",LIMIT:20,DEBOUNCE_MS:150,MIN_DEBOUNCE_MS:50,MAX_RETRIES:0},L={DIGITS_1_3:/^[0-9]{1,3}$/},T={query:"",stage:null,cities:[],streets:[],suggestions:[],isValid:!1,isError:!1,isLoading:!1,hasMore:!1,selectedSuggestionIndex:-1},b=class{constructor(t){this.abortController=null;this.country=t.country,this.authKey=t.authKey,this.explicitApiUrl=t.apiUrl,this.baseLimit=t.limit||f.LIMIT,this.currentLimit=this.baseLimit;let e=t.maxRetries!==void 0?t.maxRetries:f.MAX_RETRIES;this.maxRetries=Math.max(0,Math.min(e,10)),this.fetcher=t.fetcher||((r,s)=>fetch(r,s)),this.onStateChange=t.onStateChange||(()=>{}),this.onSelect=t.onSelect||(()=>{}),this.state=c({},T);let i=t.debounceMs!==void 0?t.debounceMs:f.DEBOUNCE_MS,n=Math.max(i,f.MIN_DEBOUNCE_MS);this.debouncedFetch=this.debounce(r=>this.executeFetch(r),n)}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 s=[...this.state.cities,...this.state.streets,...this.state.suggestions][this.state.selectedSuggestionIndex];s&&(this.selectItem(s),this.updateState({selectedSuggestionIndex:-1}));return}}let n=e.value;if(t.key===" "&&this.shouldAutoInsertComma(n)){t.preventDefault();let r=`${n.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 n=typeof t!="string"&&typeof t.value=="object"?t.value:void 0,r=!!n&&Object.keys(n).length>0;if(this.state.stage==="final"||r){let u=e;if(n&&Object.keys(n).length>0){let{street:l,street_number:a,city:h}=n;l&&a&&h&&(u=`${l} ${a}, ${h}`)}return this.finishSelection(u,n),!0}let s=typeof t!="string"?t.subtitle:null;return this.processSelection(i,s),!1}shouldAutoInsertComma(t){if(!t.includes(",")&&L.DIGITS_1_3.test(t.trim()))return!0;if(this.state.stage==="street_number"){let i=this.getCurrentFragment(t);return L.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:n}=this.state,r=n;if(e&&(i==="city"||i==="street"||i==="mixed")){if(i==="city")r=`${e}, ${t}, `;else{let a=this.getQueryPrefix(n);r=a?`${a} ${t}, ${e}, `:`${t}, ${e}, `}this.updateQueryAndFetch(r);return}if(i==="direct"||i==="addition"){this.finishSelection(t);return}!n.includes(",")&&(i==="city"||i==="street"||i==="street_number_first")?r=`${t}, `:(r=this.replaceLastSegment(n,t),i!=="street_number"&&(r+=", ")),this.updateQueryAndFetch(r)}executeFetch(t,e=0){var a,h;let i=(t||"").toString();if(!i.trim()){(a=this.abortController)==null||a.abort(),this.resetState();return}e===0&&(this.updateState({isError:!1}),this.abortController&&this.abortController.abort(),this.abortController=new AbortController);let n=(h=this.abortController)==null?void 0:h.signal,r=this.explicitApiUrl?this.explicitApiUrl:`${f.API_URL}/infer/${this.country.toLowerCase()}`,s=new URLSearchParams({country:this.country.toLowerCase(),query:i,limit:this.currentLimit.toString()});this.authKey&&s.set("authKey",this.authKey);let u=r.includes("?")?"&":"?",l=`${r}${u}${s.toString()}`;this.fetcher(l,{signal:n}).then(d=>{if(!d.ok){if(e<this.maxRetries&&(d.status>=500||d.status===429))return this.retry(t,e,n);throw new Error("Network error")}return d.json()}).then(d=>{d&&this.mapResponseToState(d)}).catch(d=>{if(d.name!=="AbortError"){if(e<this.maxRetries)return this.retry(t,e,n);this.updateState({isError:!0,isLoading:!1})}})}retry(t,e,i){if(i!=null&&i.aborted)return;let n=Math.pow(2,e)*200;setTimeout(()=>{i!=null&&i.aborted||this.executeFetch(t,e+1)},n)}mapResponseToState(t){var u,l;let e={stage:t.stage,isLoading:!1},i=t.suggestions||[],n=[],r=new Set;for(let a of i){let h=`${a.label}|${a.subtitle||""}|${JSON.stringify(a.value||{})}`;r.has(h)||(r.add(h),n.push(a))}let s=n.length+(((u=t.cities)==null?void 0:u.length)||0)+(((l=t.streets)==null?void 0:l.length)||0);e.hasMore=s>=this.currentLimit,t.stage==="mixed"?(e.cities=t.cities||[],e.streets=t.streets||[],e.suggestions=[]):(e.suggestions=n,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){var e;return((e=t.split(",").slice(-1)[0])!=null?e:"").trim()}resetState(){this.updateState(m(c({},T),{query:this.state.query}))}updateState(t){this.state=c(c({},this.state),t),this.onStateChange(this.state)}debounce(t,e){let i,n=(...r)=>{i&&clearTimeout(i),i=setTimeout(()=>t.apply(this,r),e)};return n.cancel=()=>{i&&(clearTimeout(i),i=void 0)},n}};function M(o,t){if(!t||!o)return[{text:o,match:!1}];let e=[],i=o.toLowerCase(),n=t.toLowerCase(),r=0,s=0;for(let a=0;a<o.length;a++){if(!(r<t.length&&i[a]===n[r]))continue;a>s&&e.push({text:o.slice(s,a),match:!1}),e.push({text:o[a],match:!0}),r++,s=a+1}return s<o.length&&e.push({text:o.slice(s),match:!1}),r===t.length?e:[{text:o,match:!1}]}var v=`
2
+ .pro6pp-wrapper {
3
+ position: relative;
4
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
5
+ box-sizing: border-box;
6
+ width: 100%;
7
+ -webkit-tap-highlight-color: transparent;
8
+ }
9
+ .pro6pp-wrapper * {
10
+ box-sizing: border-box;
11
+ }
12
+ .pro6pp-input {
13
+ width: 100%;
14
+ padding: 12px 14px;
15
+ padding-right: 48px;
16
+ border: 1px solid #e0e0e0;
17
+ border-radius: 8px;
18
+ font-size: 16px;
19
+ line-height: 1.5;
20
+ appearance: none;
21
+ transition: border-color 0.2s, box-shadow 0.2s;
22
+ }
23
+ .pro6pp-input:focus {
24
+ outline: none;
25
+ border-color: #3b82f6;
26
+ box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
27
+ }
20
28
 
21
- // src/index.ts
22
- var index_exports = {};
23
- __export(index_exports, {
24
- InferJS: () => InferJS,
25
- attach: () => attach
26
- });
29
+ .pro6pp-input-addons {
30
+ position: absolute;
31
+ right: 4px;
32
+ top: 0;
33
+ bottom: 0;
34
+ display: flex;
35
+ align-items: center;
36
+ pointer-events: none;
37
+ }
38
+ .pro6pp-input-addons > * {
39
+ pointer-events: auto;
40
+ }
27
41
 
28
- // ../core/src/core.ts
29
- var DEFAULTS = {
30
- API_URL: "https://api.pro6pp.nl/v2",
31
- LIMIT: 1e3,
32
- DEBOUNCE_MS: 300
33
- };
34
- var PATTERNS = {
35
- DIGITS_1_3: /^[0-9]{1,3}$/
36
- };
37
- var INITIAL_STATE = {
38
- query: "",
39
- stage: null,
40
- cities: [],
41
- streets: [],
42
- suggestions: [],
43
- isValid: false,
44
- isError: false,
45
- isLoading: false
46
- };
47
- var InferCore = class {
48
- constructor(config) {
49
- this.abortController = null;
50
- this.country = config.country;
51
- this.authKey = config.authKey;
52
- this.apiUrl = config.apiUrl || DEFAULTS.API_URL;
53
- this.limit = config.limit || DEFAULTS.LIMIT;
54
- this.fetcher = config.fetcher || ((url, init) => fetch(url, init));
55
- this.onStateChange = config.onStateChange || (() => {
56
- });
57
- this.onSelect = config.onSelect || (() => {
58
- });
59
- this.state = { ...INITIAL_STATE };
60
- this.debouncedFetch = this.debounce(
61
- (val) => this.executeFetch(val),
62
- DEFAULTS.DEBOUNCE_MS
63
- );
64
- }
65
- handleInput(value) {
66
- this.updateState({
67
- query: value,
68
- isValid: false,
69
- isLoading: !!value.trim()
70
- });
71
- if (this.state.stage === "final") {
72
- this.onSelect(null);
73
- }
74
- this.debouncedFetch(value);
75
- }
76
- handleKeyDown(event) {
77
- const target = event.target;
78
- const val = target.value;
79
- if (event.key === " " && this.shouldAutoInsertComma(val)) {
80
- event.preventDefault();
81
- const next = `${val.trim()}, `;
82
- this.updateQueryAndFetch(next);
83
- }
84
- }
85
- selectItem(item) {
86
- const label = typeof item === "string" ? item : item.label;
87
- const value = typeof item !== "string" ? item.value : void 0;
88
- const subtitle = typeof item !== "string" ? item.subtitle : null;
89
- if (this.state.stage === "final") {
90
- this.finishSelection(label, value);
91
- return;
92
- }
93
- this.processSelection(label, subtitle);
94
- }
95
- shouldAutoInsertComma(currentVal) {
96
- const isStartOfSegmentAndNumeric = !currentVal.includes(",") && PATTERNS.DIGITS_1_3.test(currentVal.trim());
97
- if (isStartOfSegmentAndNumeric) return true;
98
- if (this.state.stage === "house_number") {
99
- const currentFragment = this.getCurrentFragment(currentVal);
100
- return PATTERNS.DIGITS_1_3.test(currentFragment);
101
- }
102
- return false;
103
- }
104
- finishSelection(label, value) {
105
- this.updateState({ query: label, suggestions: [], cities: [], streets: [], isValid: true });
106
- this.onSelect(value || label);
107
- }
108
- processSelection(label, subtitle) {
109
- const { stage, query } = this.state;
110
- let nextQuery = query;
111
- const isContextualSelection = subtitle && (stage === "city" || stage === "street" || stage === "mixed");
112
- if (isContextualSelection) {
113
- if (stage === "city") {
114
- nextQuery = `${subtitle}, ${label}, `;
115
- } else {
116
- const prefix = this.getQueryPrefix(query);
117
- nextQuery = prefix ? `${prefix} ${label}, ${subtitle}, ` : `${label}, ${subtitle}, `;
118
- }
119
- this.updateQueryAndFetch(nextQuery);
120
- return;
121
- }
122
- if (stage === "direct" || stage === "addition") {
123
- this.finishSelection(label);
124
- this.handleInput(label);
125
- return;
126
- }
127
- const hasComma = query.includes(",");
128
- const isFirstSegment = !hasComma && (stage === "city" || stage === "street" || stage === "house_number_first");
129
- if (isFirstSegment) {
130
- nextQuery = `${label}, `;
131
- } else {
132
- nextQuery = this.replaceLastSegment(query, label);
133
- if (stage !== "house_number") {
134
- nextQuery += ", ";
135
- }
136
- }
137
- this.updateQueryAndFetch(nextQuery);
138
- }
139
- executeFetch(val) {
140
- const text = (val || "").toString();
141
- if (!text.trim()) {
142
- this.abortController?.abort();
143
- this.resetState();
144
- return;
145
- }
146
- this.updateState({ isError: false });
147
- if (this.abortController) this.abortController.abort();
148
- this.abortController = new AbortController();
149
- const url = new URL(`${this.apiUrl}/infer/${this.country.toLowerCase()}`);
150
- const params = {
151
- authKey: this.authKey,
152
- query: text,
153
- limit: this.limit.toString()
154
- };
155
- url.search = new URLSearchParams(params).toString();
156
- this.fetcher(url.toString(), { signal: this.abortController.signal }).then((res) => {
157
- if (!res.ok) throw new Error("Network error");
158
- return res.json();
159
- }).then((data) => this.mapResponseToState(data)).catch((e) => {
160
- if (e.name !== "AbortError") {
161
- this.updateState({ isError: true, isLoading: false });
162
- }
163
- });
164
- }
165
- mapResponseToState(data) {
166
- const newState = {
167
- stage: data.stage,
168
- isLoading: false
169
- };
170
- if (data.stage === "mixed") {
171
- newState.cities = data.cities || [];
172
- newState.streets = data.streets || [];
173
- newState.suggestions = [];
174
- } else {
175
- newState.suggestions = data.suggestions || [];
176
- newState.cities = [];
177
- newState.streets = [];
178
- }
179
- newState.isValid = data.stage === "final";
180
- this.updateState(newState);
181
- }
182
- updateQueryAndFetch(nextQuery) {
183
- this.updateState({ query: nextQuery, suggestions: [], cities: [], streets: [] });
184
- this.handleInput(nextQuery);
185
- }
186
- replaceLastSegment(fullText, newSegment) {
187
- const lastCommaIndex = fullText.lastIndexOf(",");
188
- if (lastCommaIndex === -1) return newSegment;
189
- return `${fullText.slice(0, lastCommaIndex + 1)} ${newSegment}`.trim();
190
- }
191
- getQueryPrefix(q) {
192
- const lastComma = q.lastIndexOf(",");
193
- return lastComma === -1 ? "" : q.slice(0, lastComma + 1).trimEnd();
194
- }
195
- getCurrentFragment(q) {
196
- return (q.split(",").slice(-1)[0] ?? "").trim();
197
- }
198
- resetState() {
199
- this.updateState({ ...INITIAL_STATE, query: this.state.query });
200
- }
201
- updateState(updates) {
202
- this.state = { ...this.state, ...updates };
203
- this.onStateChange(this.state);
204
- }
205
- debounce(func, wait) {
206
- let timeout;
207
- return (...args) => {
208
- if (timeout) clearTimeout(timeout);
209
- timeout = setTimeout(() => func.apply(this, args), wait);
210
- };
42
+ .pro6pp-clear-button {
43
+ background: none;
44
+ border: none;
45
+ width: 40px;
46
+ height: 40px;
47
+ cursor: pointer;
48
+ color: #a3a3a3;
49
+ display: flex;
50
+ align-items: center;
51
+ justify-content: center;
52
+ border-radius: 50%;
53
+ transition: color 0.2s, background-color 0.2s;
54
+ touch-action: manipulation;
55
+ }
56
+
57
+ @media (hover: hover) {
58
+ .pro6pp-clear-button:hover {
59
+ color: #1f2937;
60
+ background-color: #f3f4f6;
211
61
  }
212
- };
62
+ }
213
63
 
214
- // src/index.ts
215
- var DEFAULT_STYLES = `
216
- .pro6pp-wrapper {
217
- position: relative;
218
- display: block;
219
- width: 100%;
64
+ .pro6pp-clear-button:active {
65
+ background-color: #f3f4f6;
66
+ }
67
+
68
+ .pro6pp-loader {
69
+ width: 20px;
70
+ height: 20px;
71
+ margin: 0 8px;
72
+ border: 2px solid #e0e0e0;
73
+ border-top-color: #6b7280;
74
+ border-radius: 50%;
75
+ animation: pro6pp-spin 0.6s linear infinite;
76
+ flex-shrink: 0;
220
77
  }
221
78
 
222
79
  .pro6pp-dropdown {
@@ -224,143 +81,109 @@ var Pro6PP = (() => {
224
81
  top: 100%;
225
82
  left: 0;
226
83
  right: 0;
227
- z-index: 10000;
228
- background-color: #ffffff;
229
- border: 1px solid #e2e8f0;
230
- border-radius: 0 0 4px 4px;
231
- box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
84
+ margin-top: 4px;
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;
92
+ overflow-y: auto;
93
+ display: flex;
94
+ flex-direction: column;
95
+ }
96
+
97
+ @media (max-height: 500px) {
98
+ .pro6pp-dropdown {
99
+ max-height: 140px;
100
+ }
101
+ }
102
+
103
+ .pro6pp-list {
232
104
  list-style: none;
233
105
  margin: 0;
234
106
  padding: 0;
235
- max-height: 250px;
236
- overflow-y: auto;
107
+ width: 100%;
237
108
  }
238
109
 
239
110
  .pro6pp-item {
240
- padding: 10px 12px;
111
+ padding: 12px 14px;
241
112
  cursor: pointer;
242
- border-bottom: 1px solid #f1f5f9;
243
- font-family: inherit;
113
+ display: flex;
114
+ align-items: center;
244
115
  font-size: 14px;
245
- line-height: 1.4;
246
- color: #1e293b;
247
- transition: background-color 0.15s ease;
116
+ color: #374151;
117
+ border-bottom: 1px solid #f3f4f6;
118
+ transition: background-color 0.1s;
119
+ flex-shrink: 0;
248
120
  }
249
121
 
250
122
  .pro6pp-item:last-child {
251
123
  border-bottom: none;
252
124
  }
253
125
 
254
- .pro6pp-item:hover, .pro6pp-item--active {
255
- background-color: #f8fafc;
256
- color: #0f172a;
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;
257
134
  }
258
135
 
136
+ .pro6pp-item__label {
137
+ font-weight: 500;
138
+ flex-shrink: 0;
139
+ }
259
140
  .pro6pp-item__subtitle {
260
- display: block;
261
- font-size: 0.85em;
262
- color: #64748b;
263
- margin-top: 2px;
141
+ font-size: 14px;
142
+ color: #6b7280;
143
+ flex-grow: 1;
264
144
  }
265
- `;
266
- var InferJS = class {
267
- constructor(target, config) {
268
- const el = typeof target === "string" ? document.querySelector(target) : target;
269
- if (!el || !(el instanceof HTMLInputElement)) {
270
- throw new Error(`InferJS: Target element not found or is not an input.`);
271
- }
272
- this.input = el;
273
- this.useDefaultStyles = config.style !== "none";
274
- if (this.useDefaultStyles) {
275
- this.injectStyles();
276
- }
277
- this.core = new InferCore({
278
- ...config,
279
- onStateChange: (state) => this.render(state),
280
- onSelect: (selection) => {
281
- if (typeof selection === "string") {
282
- this.input.value = selection;
283
- } else if (selection && typeof selection === "object") {
284
- this.input.value = this.core.state.query;
285
- }
286
- if (config.onSelect) config.onSelect(selection);
287
- }
288
- });
289
- this.setupDOM();
290
- this.bindEvents();
291
- }
292
- injectStyles() {
293
- const styleId = "pro6pp-infer-styles";
294
- if (!document.getElementById(styleId)) {
295
- const styleEl = document.createElement("style");
296
- styleEl.id = styleId;
297
- styleEl.textContent = DEFAULT_STYLES;
298
- document.head.appendChild(styleEl);
299
- }
300
- }
301
- setupDOM() {
302
- this.wrapper = document.createElement("div");
303
- this.wrapper.className = "pro6pp-wrapper";
304
- this.input.parentNode?.insertBefore(this.wrapper, this.input);
305
- this.wrapper.appendChild(this.input);
306
- this.list = document.createElement("ul");
307
- this.list.className = "pro6pp-dropdown";
308
- this.list.style.display = "none";
309
- this.wrapper.appendChild(this.list);
310
- }
311
- bindEvents() {
312
- this.input.addEventListener("input", (e) => {
313
- const val = e.target.value;
314
- this.core.handleInput(val);
315
- });
316
- this.input.addEventListener("keydown", (e) => {
317
- this.core.handleKeyDown(e);
318
- });
319
- document.addEventListener("click", (e) => {
320
- if (!this.wrapper.contains(e.target)) {
321
- this.list.style.display = "none";
322
- }
323
- });
324
- }
325
- render(state) {
326
- if (this.input.value !== state.query) {
327
- this.input.value = state.query;
328
- }
329
- this.list.innerHTML = "";
330
- const items = [
331
- ...state.cities.map((c) => ({ item: c, type: "city" })),
332
- ...state.streets.map((s) => ({ item: s, type: "street" })),
333
- ...state.suggestions.map((s) => ({ item: s, type: "suggestion" }))
334
- ];
335
- if (items.length === 0) {
336
- this.list.style.display = "none";
337
- return;
338
- }
339
- this.list.style.display = "block";
340
- items.forEach(({ item }) => {
341
- const li = document.createElement("li");
342
- li.className = "pro6pp-item";
343
- li.setAttribute("role", "option");
344
- const labelSpan = document.createElement("span");
345
- labelSpan.className = "pro6pp-item__label";
346
- labelSpan.textContent = item.label;
347
- li.appendChild(labelSpan);
348
- if (item.subtitle) {
349
- const subSpan = document.createElement("span");
350
- subSpan.className = "pro6pp-item__subtitle";
351
- subSpan.textContent = item.subtitle;
352
- li.appendChild(subSpan);
353
- }
354
- li.onclick = (e) => {
355
- e.stopPropagation();
356
- this.core.selectItem(item);
357
- };
358
- this.list.appendChild(li);
359
- });
360
- }
361
- };
362
- function attach(target, config) {
363
- return new InferJS(target, config);
145
+ .pro6pp-item__chevron {
146
+ color: #d1d5db;
147
+ display: flex;
148
+ align-items: center;
149
+ margin-left: auto;
150
+ }
151
+
152
+ .pro6pp-no-results {
153
+ padding: 24px 16px;
154
+ color: #6b7280;
155
+ font-size: 15px;
156
+ text-align: center;
157
+ }
158
+
159
+ .pro6pp-load-more {
160
+ width: 100%;
161
+ padding: 14px;
162
+ background: #f9fafb;
163
+ border: none;
164
+ border-top: 1px solid #e0e0e0;
165
+ color: #3b82f6;
166
+ font-size: 14px;
167
+ font-weight: 600;
168
+ cursor: pointer;
169
+ flex-shrink: 0;
170
+ touch-action: manipulation;
171
+ }
172
+
173
+ .pro6pp-load-more:active {
174
+ background-color: #f3f4f6;
175
+ }
176
+
177
+ @keyframes pro6pp-spin {
178
+ to { transform: rotate(360deg); }
364
179
  }
365
- return __toCommonJS(index_exports);
366
- })();
180
+ `;var x=class{constructor(t,e){this.isOpen=!1;var r;let i=typeof t=="string"?document.querySelector(t):t;if(!i)throw new Error("InferJS: Target element not found.");if(this.noResultsText=e.noResultsText||"No results found",this.loadMoreText=e.loadMoreText||"Show more results...",this.showClearButton=e.showClearButton!==!1,this.useDefaultStyles=e.style!=="none",this.useDefaultStyles&&this.injectStyles(),this.wrapper=document.createElement("div"),this.wrapper.className="pro6pp-wrapper",i instanceof HTMLInputElement?(this.input=i,(r=this.input.parentNode)==null||r.insertBefore(this.wrapper,this.input),this.wrapper.appendChild(this.input)):(i.appendChild(this.wrapper),this.input=document.createElement("input"),this.input.type="text",e.placeholder&&(this.input.placeholder=e.placeholder),this.wrapper.appendChild(this.input)),this.input.setAttribute("autocomplete","off"),this.input.setAttribute("autocorrect","off"),this.input.setAttribute("autocapitalize","none"),this.input.setAttribute("spellcheck","false"),this.input.setAttribute("inputmode","search"),this.input.setAttribute("enterkeyhint","search"),this.useDefaultStyles&&this.input.classList.add("pro6pp-input"),e.inputClass){let s=e.inputClass.split(" ");this.input.classList.add(...s)}let n=document.createElement("div");n.className="pro6pp-input-addons",this.wrapper.appendChild(n),this.loader=document.createElement("div"),this.loader.className="pro6pp-loader",this.loader.style.display="none",n.appendChild(this.loader),this.clearButton=document.createElement("button"),this.clearButton.type="button",this.clearButton.className="pro6pp-clear-button",this.clearButton.setAttribute("aria-label","Clear input"),this.clearButton.style.display="none",this.clearButton.innerHTML=`
181
+ <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
182
+ <line x1="18" y1="6" x2="6" y2="18"></line>
183
+ <line x1="6" y1="6" x2="18" y2="18"></line>
184
+ </svg>
185
+ `,n.appendChild(this.clearButton),this.dropdown=document.createElement("div"),this.dropdown.className="pro6pp-dropdown",this.dropdown.style.display="none",this.wrapper.appendChild(this.dropdown),this.list=document.createElement("ul"),this.list.className="pro6pp-list",this.list.setAttribute("role","listbox"),this.dropdown.appendChild(this.list),this.loadMoreButton=document.createElement("button"),this.loadMoreButton.type="button",this.loadMoreButton.className="pro6pp-load-more",this.loadMoreButton.textContent=this.loadMoreText,this.loadMoreButton.style.display="none",this.dropdown.appendChild(this.loadMoreButton),this.core=new b(m(c({},e),{onStateChange:s=>{this.render(s),e.onStateChange&&e.onStateChange(s)},onSelect:s=>{typeof s=="string"?this.input.value=s:s&&typeof s=="object"&&(this.input.value=this.core.state.query),e.onSelect&&e.onSelect(s)}})),this.bindEvents()}injectStyles(){let t="pro6pp-styles";if(!document.getElementById(t)){let e=document.createElement("style");e.id=t,e.textContent=v,document.head.appendChild(e)}}bindEvents(){this.input.addEventListener("input",t=>{let e=t.target.value;this.isOpen=!0,this.core.handleInput(e)}),this.input.addEventListener("keydown",t=>{this.core.handleKeyDown(t)}),this.clearButton.addEventListener("click",()=>{this.core.handleInput(""),this.input.focus()}),this.loadMoreButton.addEventListener("click",t=>{t.preventDefault(),this.core.loadMore()}),document.addEventListener("mousedown",t=>{this.wrapper.contains(t.target)||(this.isOpen=!1,this.dropdown.style.display="none")}),this.input.addEventListener("focus",()=>{this.isOpen=!0,this.render(this.core.state)})}render(t){this.input.value!==t.query&&(this.input.value=t.query),this.loader.style.display=t.isLoading?"block":"none",this.showClearButton&&(this.clearButton.style.display=t.query.length>0?"flex":"none"),this.list.innerHTML="";let e=[...t.cities,...t.streets,...t.suggestions],i=e.length>0,n=!t.isLoading&&!t.isError&&t.query.length>0&&!i&&!t.isValid;if(!(this.isOpen&&(i||t.isLoading||n))){this.dropdown.style.display="none";return}if(this.dropdown.style.display="block",this.loadMoreButton.style.display=t.hasMore?"block":"none",t.isLoading&&!i){let s=document.createElement("li");s.className="pro6pp-no-results",s.textContent="Loading suggestions...",this.list.appendChild(s);return}if(n){let s=document.createElement("li");s.className="pro6pp-no-results",s.textContent=this.noResultsText,this.list.appendChild(s);return}e.forEach((s,u)=>{if(!s.label)return;let l=document.createElement("li");l.className="pro6pp-item",u===t.selectedSuggestionIndex&&l.classList.add("pro6pp-item--active"),l.setAttribute("role","option"),l.setAttribute("aria-selected",u===t.selectedSuggestionIndex?"true":"false");let a=document.createElement("span");a.className="pro6pp-item__label",M(s.label,t.query).forEach(({text:p,match:C})=>{if(C){let y=document.createElement("strong");y.className="pro6pp-item__label--match",y.textContent=p,a.appendChild(y)}else a.appendChild(document.createTextNode(p))}),l.appendChild(a);let d=s.count!==void 0&&s.count!==null?s.count:"",S=s.subtitle||d;if(S!==""){let p=document.createElement("span");p.className="pro6pp-item__subtitle",p.textContent=`, ${S}`,l.appendChild(p)}if(s.value===void 0||s.value===null){let p=document.createElement("div");p.className="pro6pp-item__chevron",p.innerHTML=`
186
+ <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
187
+ <polyline points="9 18 15 12 9 6"></polyline>
188
+ </svg>
189
+ `,l.appendChild(p)}l.onmousedown=p=>p.preventDefault(),l.onclick=p=>{p.stopPropagation(),this.core.selectItem(s)?(this.isOpen=!1,this.dropdown.style.display="none"):setTimeout(()=>this.input.focus(),0)},this.list.appendChild(l)})}};function $(o,t){return new x(o,t)}return N(U);})();