@pro6pp/infer-react 0.0.2-beta.9 → 0.1.0-beta.19
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 +32 -1
- package/dist/index.cjs +562 -270
- package/dist/index.d.cts +24 -13
- package/dist/index.d.ts +24 -13
- package/dist/index.js +570 -271
- package/dist/styles.css +203 -0
- package/package.json +7 -4
package/dist/index.js
CHANGED
|
@@ -3,7 +3,108 @@ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { en
|
|
|
3
3
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
4
4
|
|
|
5
5
|
// src/index.tsx
|
|
6
|
-
import React, {
|
|
6
|
+
import React, {
|
|
7
|
+
useState,
|
|
8
|
+
useMemo,
|
|
9
|
+
useEffect,
|
|
10
|
+
useRef,
|
|
11
|
+
forwardRef,
|
|
12
|
+
useImperativeHandle
|
|
13
|
+
} from "react";
|
|
14
|
+
|
|
15
|
+
// ../core/src/label-formatter.ts
|
|
16
|
+
function normalize(str) {
|
|
17
|
+
return str.toLowerCase().trim();
|
|
18
|
+
}
|
|
19
|
+
function escapeRegex(str) {
|
|
20
|
+
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
21
|
+
}
|
|
22
|
+
function findWordPosition(query, value) {
|
|
23
|
+
const normalizedQuery = normalize(query);
|
|
24
|
+
const normalizedValue = normalize(value);
|
|
25
|
+
if (normalizedValue.includes(" ")) {
|
|
26
|
+
return normalizedQuery.indexOf(normalizedValue);
|
|
27
|
+
}
|
|
28
|
+
const pattern = new RegExp(`(?:^|[,\\s])${escapeRegex(normalizedValue)}(?:$|[,\\s])`, "g");
|
|
29
|
+
const match = pattern.exec(normalizedQuery);
|
|
30
|
+
if (match) {
|
|
31
|
+
const matchStart = match.index;
|
|
32
|
+
const firstChar = normalizedQuery[matchStart];
|
|
33
|
+
if (firstChar === "," || firstChar === " ") {
|
|
34
|
+
return matchStart + 1;
|
|
35
|
+
}
|
|
36
|
+
return matchStart;
|
|
37
|
+
}
|
|
38
|
+
return -1;
|
|
39
|
+
}
|
|
40
|
+
function detectComponentOrder(query, value) {
|
|
41
|
+
const detected = [];
|
|
42
|
+
const componentMap = [];
|
|
43
|
+
if (value.street) {
|
|
44
|
+
componentMap.push({ value: value.street, type: "street" });
|
|
45
|
+
}
|
|
46
|
+
if (value.city) {
|
|
47
|
+
componentMap.push({ value: value.city, type: "city" });
|
|
48
|
+
}
|
|
49
|
+
if (value.postcode) {
|
|
50
|
+
componentMap.push({ value: value.postcode, type: "postcode" });
|
|
51
|
+
}
|
|
52
|
+
if (value.street_number !== void 0 && value.street_number !== null) {
|
|
53
|
+
componentMap.push({ value: String(value.street_number), type: "street_number" });
|
|
54
|
+
}
|
|
55
|
+
if (value.addition) {
|
|
56
|
+
componentMap.push({ value: value.addition, type: "addition" });
|
|
57
|
+
}
|
|
58
|
+
for (const comp of componentMap) {
|
|
59
|
+
const position = findWordPosition(query, comp.value);
|
|
60
|
+
if (position !== -1) {
|
|
61
|
+
detected.push({
|
|
62
|
+
type: comp.type,
|
|
63
|
+
value: comp.value,
|
|
64
|
+
position
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
detected.sort((a, b) => a.position - b.position);
|
|
69
|
+
return detected;
|
|
70
|
+
}
|
|
71
|
+
function formatLabelByInputOrder(query, value) {
|
|
72
|
+
if (!value || !query) {
|
|
73
|
+
return "";
|
|
74
|
+
}
|
|
75
|
+
const detectedOrder = detectComponentOrder(query, value);
|
|
76
|
+
const detectedTypes = new Set(detectedOrder.map((d) => d.type));
|
|
77
|
+
const parts = [];
|
|
78
|
+
for (const detected of detectedOrder) {
|
|
79
|
+
parts.push(detected.value);
|
|
80
|
+
}
|
|
81
|
+
const defaultOrder = ["street", "street_number", "addition", "postcode", "city"];
|
|
82
|
+
for (const type of defaultOrder) {
|
|
83
|
+
if (detectedTypes.has(type)) continue;
|
|
84
|
+
let val;
|
|
85
|
+
switch (type) {
|
|
86
|
+
case "street":
|
|
87
|
+
val = value.street;
|
|
88
|
+
break;
|
|
89
|
+
case "city":
|
|
90
|
+
val = value.city;
|
|
91
|
+
break;
|
|
92
|
+
case "street_number":
|
|
93
|
+
val = value.street_number !== void 0 ? String(value.street_number) : void 0;
|
|
94
|
+
break;
|
|
95
|
+
case "postcode":
|
|
96
|
+
val = value.postcode;
|
|
97
|
+
break;
|
|
98
|
+
case "addition":
|
|
99
|
+
val = value.addition;
|
|
100
|
+
break;
|
|
101
|
+
}
|
|
102
|
+
if (val) {
|
|
103
|
+
parts.push(val);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return parts.join(", ");
|
|
107
|
+
}
|
|
7
108
|
|
|
8
109
|
// ../core/src/core.ts
|
|
9
110
|
var DEFAULTS = {
|
|
@@ -14,7 +115,8 @@ var DEFAULTS = {
|
|
|
14
115
|
MAX_RETRIES: 0
|
|
15
116
|
};
|
|
16
117
|
var PATTERNS = {
|
|
17
|
-
DIGITS_1_3: /^[0-9]{1,3}
|
|
118
|
+
DIGITS_1_3: /^[0-9]{1,3}$/,
|
|
119
|
+
STREET_NUMBER_PREFIX: /^(\d+)\s*,\s*$/
|
|
18
120
|
};
|
|
19
121
|
var INITIAL_STATE = {
|
|
20
122
|
query: "",
|
|
@@ -23,6 +125,7 @@ var INITIAL_STATE = {
|
|
|
23
125
|
streets: [],
|
|
24
126
|
suggestions: [],
|
|
25
127
|
isValid: false,
|
|
128
|
+
value: null,
|
|
26
129
|
isError: false,
|
|
27
130
|
isLoading: false,
|
|
28
131
|
hasMore: false,
|
|
@@ -36,10 +139,11 @@ var InferCore = class {
|
|
|
36
139
|
constructor(config) {
|
|
37
140
|
__publicField(this, "country");
|
|
38
141
|
__publicField(this, "authKey");
|
|
39
|
-
__publicField(this, "
|
|
142
|
+
__publicField(this, "explicitApiUrl");
|
|
40
143
|
__publicField(this, "baseLimit");
|
|
41
144
|
__publicField(this, "currentLimit");
|
|
42
145
|
__publicField(this, "maxRetries");
|
|
146
|
+
__publicField(this, "language");
|
|
43
147
|
__publicField(this, "fetcher");
|
|
44
148
|
__publicField(this, "onStateChange");
|
|
45
149
|
__publicField(this, "onSelect");
|
|
@@ -50,12 +154,12 @@ var InferCore = class {
|
|
|
50
154
|
__publicField(this, "state");
|
|
51
155
|
__publicField(this, "abortController", null);
|
|
52
156
|
__publicField(this, "debouncedFetch");
|
|
53
|
-
__publicField(this, "isSelecting", false);
|
|
54
157
|
this.country = config.country;
|
|
55
158
|
this.authKey = config.authKey;
|
|
56
|
-
this.
|
|
159
|
+
this.explicitApiUrl = config.apiUrl;
|
|
57
160
|
this.baseLimit = config.limit || DEFAULTS.LIMIT;
|
|
58
161
|
this.currentLimit = this.baseLimit;
|
|
162
|
+
this.language = config.language;
|
|
59
163
|
const configRetries = config.maxRetries !== void 0 ? config.maxRetries : DEFAULTS.MAX_RETRIES;
|
|
60
164
|
this.maxRetries = Math.max(0, Math.min(configRetries, 10));
|
|
61
165
|
this.fetcher = config.fetcher || ((url, init) => fetch(url, init));
|
|
@@ -74,18 +178,16 @@ var InferCore = class {
|
|
|
74
178
|
* @param value The raw string from the input field.
|
|
75
179
|
*/
|
|
76
180
|
handleInput(value) {
|
|
77
|
-
if (this.isSelecting) {
|
|
78
|
-
this.isSelecting = false;
|
|
79
|
-
return;
|
|
80
|
-
}
|
|
81
181
|
this.currentLimit = this.baseLimit;
|
|
82
182
|
const isEditingFinal = this.state.stage === "final" && value !== this.state.query;
|
|
83
183
|
this.updateState({
|
|
84
184
|
query: value,
|
|
85
185
|
isValid: false,
|
|
186
|
+
value: null,
|
|
86
187
|
isLoading: !!value.trim(),
|
|
87
188
|
selectedSuggestionIndex: -1,
|
|
88
|
-
hasMore: false
|
|
189
|
+
hasMore: false,
|
|
190
|
+
stage: isEditingFinal ? null : this.state.stage
|
|
89
191
|
});
|
|
90
192
|
if (isEditingFinal) {
|
|
91
193
|
this.onSelect(null);
|
|
@@ -106,7 +208,7 @@ var InferCore = class {
|
|
|
106
208
|
* Supports:
|
|
107
209
|
* - `ArrowUp`/`ArrowDown`: Navigate through the suggestion list.
|
|
108
210
|
* - `Enter`: Select the currently highlighted suggestion.
|
|
109
|
-
* - `Space`: Automatically inserts a comma if a numeric
|
|
211
|
+
* - `Space`: Automatically inserts a comma if a numeric street number is detected.
|
|
110
212
|
* @param event The keyboard event from the input element.
|
|
111
213
|
*/
|
|
112
214
|
handleKeyDown(event) {
|
|
@@ -154,6 +256,7 @@ var InferCore = class {
|
|
|
154
256
|
* Manually selects a suggestion or a string value.
|
|
155
257
|
* This is typically called when a user clicks a suggestion in the UI.
|
|
156
258
|
* @param item The suggestion object or string to select.
|
|
259
|
+
* @returns boolean True if the selection is a final address.
|
|
157
260
|
*/
|
|
158
261
|
selectItem(item) {
|
|
159
262
|
this.debouncedFetch.cancel();
|
|
@@ -167,26 +270,27 @@ var InferCore = class {
|
|
|
167
270
|
}
|
|
168
271
|
const valueObj = typeof item !== "string" && typeof item.value === "object" ? item.value : void 0;
|
|
169
272
|
const isFullResult = !!valueObj && Object.keys(valueObj).length > 0;
|
|
170
|
-
this.isSelecting = true;
|
|
171
273
|
if (this.state.stage === "final" || isFullResult) {
|
|
172
274
|
let finalQuery = label;
|
|
173
275
|
if (valueObj && Object.keys(valueObj).length > 0) {
|
|
174
|
-
const { street, street_number,
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
276
|
+
const { street, street_number, postcode, city, addition } = valueObj;
|
|
277
|
+
if (street && street_number && city) {
|
|
278
|
+
const suffix = addition ? ` ${addition}` : "";
|
|
279
|
+
const postcodeStr = postcode ? `${postcode}, ` : "";
|
|
280
|
+
finalQuery = `${street}, ${street_number}${suffix}, ${postcodeStr}${city}`;
|
|
178
281
|
}
|
|
179
282
|
}
|
|
180
283
|
this.finishSelection(finalQuery, valueObj);
|
|
181
|
-
return;
|
|
284
|
+
return true;
|
|
182
285
|
}
|
|
183
286
|
const subtitle = typeof item !== "string" ? item.subtitle : null;
|
|
184
287
|
this.processSelection(logicValue, subtitle);
|
|
288
|
+
return false;
|
|
185
289
|
}
|
|
186
290
|
shouldAutoInsertComma(currentVal) {
|
|
187
291
|
const isStartOfSegmentAndNumeric = !currentVal.includes(",") && PATTERNS.DIGITS_1_3.test(currentVal.trim());
|
|
188
292
|
if (isStartOfSegmentAndNumeric) return true;
|
|
189
|
-
if (this.state.stage === "
|
|
293
|
+
if (this.state.stage === "street_number") {
|
|
190
294
|
const currentFragment = this.getCurrentFragment(currentVal);
|
|
191
295
|
return PATTERNS.DIGITS_1_3.test(currentFragment);
|
|
192
296
|
}
|
|
@@ -199,13 +303,11 @@ var InferCore = class {
|
|
|
199
303
|
cities: [],
|
|
200
304
|
streets: [],
|
|
201
305
|
isValid: true,
|
|
306
|
+
value: value || null,
|
|
202
307
|
stage: "final",
|
|
203
308
|
hasMore: false
|
|
204
309
|
});
|
|
205
310
|
this.onSelect(value || label);
|
|
206
|
-
setTimeout(() => {
|
|
207
|
-
this.isSelecting = false;
|
|
208
|
-
}, 0);
|
|
209
311
|
}
|
|
210
312
|
processSelection(text, subtitle) {
|
|
211
313
|
const { stage, query } = this.state;
|
|
@@ -216,7 +318,22 @@ var InferCore = class {
|
|
|
216
318
|
nextQuery = `${subtitle}, ${text}, `;
|
|
217
319
|
} else {
|
|
218
320
|
const prefix = this.getQueryPrefix(query);
|
|
219
|
-
|
|
321
|
+
const shouldAddSubtitle = !prefix || !prefix.includes(subtitle);
|
|
322
|
+
let effectivePrefix = prefix;
|
|
323
|
+
if (prefix && subtitle) {
|
|
324
|
+
const prefixNumMatch = prefix.match(PATTERNS.STREET_NUMBER_PREFIX);
|
|
325
|
+
if (prefixNumMatch) {
|
|
326
|
+
const num = prefixNumMatch[1];
|
|
327
|
+
if (subtitle.startsWith(num)) {
|
|
328
|
+
effectivePrefix = "";
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
if (shouldAddSubtitle) {
|
|
333
|
+
nextQuery = effectivePrefix ? `${effectivePrefix} ${text}, ${subtitle}, ` : `${text}, ${subtitle}, `;
|
|
334
|
+
} else {
|
|
335
|
+
nextQuery = effectivePrefix ? `${effectivePrefix} ${text}, ` : `${text}, `;
|
|
336
|
+
}
|
|
220
337
|
}
|
|
221
338
|
this.updateQueryAndFetch(nextQuery);
|
|
222
339
|
return;
|
|
@@ -226,12 +343,12 @@ var InferCore = class {
|
|
|
226
343
|
return;
|
|
227
344
|
}
|
|
228
345
|
const hasComma = query.includes(",");
|
|
229
|
-
const isFirstSegment = !hasComma && (stage === "city" || stage === "street" || stage === "
|
|
346
|
+
const isFirstSegment = !hasComma && (stage === "city" || stage === "street" || stage === "street_number_first");
|
|
230
347
|
if (isFirstSegment) {
|
|
231
348
|
nextQuery = `${text}, `;
|
|
232
349
|
} else {
|
|
233
350
|
nextQuery = this.replaceLastSegment(query, text);
|
|
234
|
-
if (stage !== "
|
|
351
|
+
if (stage !== "street_number") {
|
|
235
352
|
nextQuery += ", ";
|
|
236
353
|
}
|
|
237
354
|
}
|
|
@@ -250,14 +367,23 @@ var InferCore = class {
|
|
|
250
367
|
this.abortController = new AbortController();
|
|
251
368
|
}
|
|
252
369
|
const currentSignal = this.abortController?.signal;
|
|
253
|
-
const
|
|
254
|
-
const params = {
|
|
255
|
-
authKey: this.authKey,
|
|
370
|
+
const baseUrl = this.explicitApiUrl ? this.explicitApiUrl : `${DEFAULTS.API_URL}/infer/${this.country.toLowerCase()}`;
|
|
371
|
+
const params = new URLSearchParams({
|
|
256
372
|
query: text,
|
|
257
373
|
limit: this.currentLimit.toString()
|
|
258
|
-
};
|
|
259
|
-
|
|
260
|
-
|
|
374
|
+
});
|
|
375
|
+
if (this.explicitApiUrl) {
|
|
376
|
+
params.append("country", this.country.toLowerCase());
|
|
377
|
+
}
|
|
378
|
+
if (this.authKey) {
|
|
379
|
+
params.set("authKey", this.authKey);
|
|
380
|
+
}
|
|
381
|
+
if (this.language) {
|
|
382
|
+
params.set("language", this.language);
|
|
383
|
+
}
|
|
384
|
+
const separator = baseUrl.includes("?") ? "&" : "?";
|
|
385
|
+
const finalUrl = `${baseUrl}${separator}${params.toString()}`;
|
|
386
|
+
this.fetcher(finalUrl, { signal: currentSignal }).then((res) => {
|
|
261
387
|
if (!res.ok) {
|
|
262
388
|
if (attempt < this.maxRetries && (res.status >= 500 || res.status === 429)) {
|
|
263
389
|
return this.retry(val, attempt, currentSignal);
|
|
@@ -289,8 +415,6 @@ var InferCore = class {
|
|
|
289
415
|
stage: data.stage,
|
|
290
416
|
isLoading: false
|
|
291
417
|
};
|
|
292
|
-
let autoSelect = false;
|
|
293
|
-
let autoSelectItem = null;
|
|
294
418
|
const rawSuggestions = data.suggestions || [];
|
|
295
419
|
const uniqueSuggestions = [];
|
|
296
420
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -298,7 +422,8 @@ var InferCore = class {
|
|
|
298
422
|
const key = `${item.label}|${item.subtitle || ""}|${JSON.stringify(item.value || {})}`;
|
|
299
423
|
if (!seen.has(key)) {
|
|
300
424
|
seen.add(key);
|
|
301
|
-
|
|
425
|
+
const reformattedItem = this.reformatSuggestionLabel(item);
|
|
426
|
+
uniqueSuggestions.push(reformattedItem);
|
|
302
427
|
}
|
|
303
428
|
}
|
|
304
429
|
const totalCount = uniqueSuggestions.length + (data.cities?.length || 0) + (data.streets?.length || 0);
|
|
@@ -306,38 +431,53 @@ var InferCore = class {
|
|
|
306
431
|
if (data.stage === "mixed") {
|
|
307
432
|
newState.cities = data.cities || [];
|
|
308
433
|
newState.streets = data.streets || [];
|
|
309
|
-
newState.
|
|
434
|
+
if (newState.cities?.length === 0 && newState.streets?.length === 0) {
|
|
435
|
+
newState.suggestions = uniqueSuggestions;
|
|
436
|
+
} else {
|
|
437
|
+
newState.suggestions = [];
|
|
438
|
+
}
|
|
310
439
|
} else {
|
|
311
440
|
newState.suggestions = uniqueSuggestions;
|
|
312
441
|
newState.cities = [];
|
|
313
442
|
newState.streets = [];
|
|
314
|
-
if (data.stage === "final" && uniqueSuggestions.length === 1) {
|
|
315
|
-
autoSelect = true;
|
|
316
|
-
autoSelectItem = uniqueSuggestions[0];
|
|
317
|
-
}
|
|
318
443
|
}
|
|
319
444
|
newState.isValid = data.stage === "final";
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
newState.cities = [];
|
|
324
|
-
newState.streets = [];
|
|
325
|
-
newState.isValid = true;
|
|
326
|
-
newState.hasMore = false;
|
|
327
|
-
this.updateState(newState);
|
|
328
|
-
const val = typeof autoSelectItem.value === "object" ? autoSelectItem.value : autoSelectItem.label;
|
|
329
|
-
this.onSelect(val);
|
|
330
|
-
} else {
|
|
331
|
-
this.updateState(newState);
|
|
445
|
+
this.updateState(newState);
|
|
446
|
+
if (newState.isValid && uniqueSuggestions.length === 1) {
|
|
447
|
+
this.selectItem(uniqueSuggestions[0]);
|
|
332
448
|
}
|
|
333
449
|
}
|
|
450
|
+
/**
|
|
451
|
+
* Reformats a suggestion's label based on the user's input order.
|
|
452
|
+
* If the suggestion has a structured value object, we reorder the label
|
|
453
|
+
* to match how the user typed the components.
|
|
454
|
+
*/
|
|
455
|
+
reformatSuggestionLabel(item) {
|
|
456
|
+
if (!item.value || typeof item.value === "string") {
|
|
457
|
+
return item;
|
|
458
|
+
}
|
|
459
|
+
const addressValue = item.value;
|
|
460
|
+
if (!addressValue.street || !addressValue.city) {
|
|
461
|
+
return item;
|
|
462
|
+
}
|
|
463
|
+
const reformattedLabel = formatLabelByInputOrder(this.state.query, addressValue);
|
|
464
|
+
if (reformattedLabel) {
|
|
465
|
+
return { ...item, label: reformattedLabel };
|
|
466
|
+
}
|
|
467
|
+
return item;
|
|
468
|
+
}
|
|
334
469
|
updateQueryAndFetch(nextQuery) {
|
|
335
|
-
this.updateState({
|
|
336
|
-
|
|
470
|
+
this.updateState({
|
|
471
|
+
query: nextQuery,
|
|
472
|
+
suggestions: [],
|
|
473
|
+
cities: [],
|
|
474
|
+
streets: [],
|
|
475
|
+
isValid: false,
|
|
476
|
+
value: null,
|
|
477
|
+
isLoading: true,
|
|
478
|
+
hasMore: false
|
|
479
|
+
});
|
|
337
480
|
this.debouncedFetch(nextQuery);
|
|
338
|
-
setTimeout(() => {
|
|
339
|
-
this.isSelecting = false;
|
|
340
|
-
}, 0);
|
|
341
481
|
}
|
|
342
482
|
replaceLastSegment(fullText, newSegment) {
|
|
343
483
|
const lastCommaIndex = fullText.lastIndexOf(",");
|
|
@@ -374,6 +514,49 @@ var InferCore = class {
|
|
|
374
514
|
}
|
|
375
515
|
};
|
|
376
516
|
|
|
517
|
+
// ../core/src/highlight.ts
|
|
518
|
+
function mergeSegments(segments) {
|
|
519
|
+
if (segments.length === 0) return segments;
|
|
520
|
+
const merged = [];
|
|
521
|
+
for (const seg of segments) {
|
|
522
|
+
const last = merged[merged.length - 1];
|
|
523
|
+
if (last && last.match === seg.match) {
|
|
524
|
+
last.text += seg.text;
|
|
525
|
+
} else {
|
|
526
|
+
merged.push({ text: seg.text, match: seg.match });
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
return merged;
|
|
530
|
+
}
|
|
531
|
+
function getHighlightSegments(text, query) {
|
|
532
|
+
if (!query || !text) return [{ text, match: false }];
|
|
533
|
+
const segments = [];
|
|
534
|
+
const normalizedText = text.toLowerCase();
|
|
535
|
+
const normalizedQuery = query.toLowerCase();
|
|
536
|
+
let queryCursor = 0;
|
|
537
|
+
let unmatchedCursor = 0;
|
|
538
|
+
for (let textCursor = 0; textCursor < text.length; textCursor++) {
|
|
539
|
+
const isMatch = queryCursor < query.length && normalizedText[textCursor] === normalizedQuery[queryCursor];
|
|
540
|
+
if (!isMatch) continue;
|
|
541
|
+
const hasPrecedingUnmatched = textCursor > unmatchedCursor;
|
|
542
|
+
if (hasPrecedingUnmatched) {
|
|
543
|
+
segments.push({ text: text.slice(unmatchedCursor, textCursor), match: false });
|
|
544
|
+
}
|
|
545
|
+
segments.push({ text: text[textCursor], match: true });
|
|
546
|
+
queryCursor++;
|
|
547
|
+
unmatchedCursor = textCursor + 1;
|
|
548
|
+
}
|
|
549
|
+
const hasRemainingText = unmatchedCursor < text.length;
|
|
550
|
+
if (hasRemainingText) {
|
|
551
|
+
segments.push({ text: text.slice(unmatchedCursor), match: false });
|
|
552
|
+
}
|
|
553
|
+
const isFullMatch = queryCursor === query.length;
|
|
554
|
+
if (!isFullMatch) {
|
|
555
|
+
return [{ text, match: false }];
|
|
556
|
+
}
|
|
557
|
+
return mergeSegments(segments);
|
|
558
|
+
}
|
|
559
|
+
|
|
377
560
|
// ../core/src/default-styles.ts
|
|
378
561
|
var DEFAULT_STYLES = `
|
|
379
562
|
.pro6pp-wrapper {
|
|
@@ -381,20 +564,28 @@ var DEFAULT_STYLES = `
|
|
|
381
564
|
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
|
|
382
565
|
box-sizing: border-box;
|
|
383
566
|
width: 100%;
|
|
567
|
+
-webkit-tap-highlight-color: transparent;
|
|
384
568
|
}
|
|
385
569
|
.pro6pp-wrapper * {
|
|
386
570
|
box-sizing: border-box;
|
|
387
571
|
}
|
|
388
572
|
.pro6pp-input {
|
|
389
573
|
width: 100%;
|
|
390
|
-
padding:
|
|
574
|
+
padding: 12px 14px;
|
|
391
575
|
padding-right: 48px;
|
|
392
576
|
border: 1px solid #e0e0e0;
|
|
393
|
-
border-radius:
|
|
577
|
+
border-radius: 8px;
|
|
394
578
|
font-size: 16px;
|
|
395
579
|
line-height: 1.5;
|
|
580
|
+
appearance: none;
|
|
396
581
|
transition: border-color 0.2s, box-shadow 0.2s;
|
|
397
582
|
}
|
|
583
|
+
|
|
584
|
+
.pro6pp-input::placeholder {
|
|
585
|
+
font-size: 16px;
|
|
586
|
+
color: #a3a3a3;
|
|
587
|
+
}
|
|
588
|
+
|
|
398
589
|
.pro6pp-input:focus {
|
|
399
590
|
outline: none;
|
|
400
591
|
border-color: #3b82f6;
|
|
@@ -403,12 +594,11 @@ var DEFAULT_STYLES = `
|
|
|
403
594
|
|
|
404
595
|
.pro6pp-input-addons {
|
|
405
596
|
position: absolute;
|
|
406
|
-
right:
|
|
597
|
+
right: 4px;
|
|
407
598
|
top: 0;
|
|
408
599
|
bottom: 0;
|
|
409
600
|
display: flex;
|
|
410
601
|
align-items: center;
|
|
411
|
-
gap: 2px;
|
|
412
602
|
pointer-events: none;
|
|
413
603
|
}
|
|
414
604
|
.pro6pp-input-addons > * {
|
|
@@ -418,37 +608,27 @@ var DEFAULT_STYLES = `
|
|
|
418
608
|
.pro6pp-clear-button {
|
|
419
609
|
background: none;
|
|
420
610
|
border: none;
|
|
421
|
-
width:
|
|
422
|
-
height:
|
|
611
|
+
width: 32px;
|
|
612
|
+
height: 32px;
|
|
423
613
|
cursor: pointer;
|
|
424
614
|
color: #a3a3a3;
|
|
425
615
|
display: flex;
|
|
426
616
|
align-items: center;
|
|
427
617
|
justify-content: center;
|
|
428
618
|
border-radius: 50%;
|
|
429
|
-
transition: color 0.2s, background-color 0.2s
|
|
619
|
+
transition: color 0.2s, background-color 0.2s;
|
|
620
|
+
touch-action: manipulation;
|
|
430
621
|
}
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
}
|
|
438
|
-
.pro6pp-clear-button svg {
|
|
439
|
-
width: 18px;
|
|
440
|
-
height: 18px;
|
|
622
|
+
|
|
623
|
+
@media (hover: hover) {
|
|
624
|
+
.pro6pp-clear-button:hover {
|
|
625
|
+
color: #1f2937;
|
|
626
|
+
background-color: #f3f4f6;
|
|
627
|
+
}
|
|
441
628
|
}
|
|
442
629
|
|
|
443
|
-
.pro6pp-
|
|
444
|
-
|
|
445
|
-
height: 18px;
|
|
446
|
-
margin: 0 4px;
|
|
447
|
-
border: 2px solid #e0e0e0;
|
|
448
|
-
border-top-color: #6b7280;
|
|
449
|
-
border-radius: 50%;
|
|
450
|
-
animation: pro6pp-spin 0.6s linear infinite;
|
|
451
|
-
flex-shrink: 0;
|
|
630
|
+
.pro6pp-clear-button:active {
|
|
631
|
+
background-color: #f3f4f6;
|
|
452
632
|
}
|
|
453
633
|
|
|
454
634
|
.pro6pp-dropdown {
|
|
@@ -456,77 +636,126 @@ var DEFAULT_STYLES = `
|
|
|
456
636
|
top: 100%;
|
|
457
637
|
left: 0;
|
|
458
638
|
right: 0;
|
|
459
|
-
z-index: 9999;
|
|
460
639
|
margin-top: 4px;
|
|
461
|
-
background:
|
|
462
|
-
border: 1px solid #
|
|
463
|
-
border-radius:
|
|
464
|
-
box-shadow: 0
|
|
465
|
-
|
|
640
|
+
background: #ffffff;
|
|
641
|
+
border: 1px solid #e5e7eb;
|
|
642
|
+
border-radius: 6px;
|
|
643
|
+
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
|
|
644
|
+
z-index: 9999;
|
|
645
|
+
padding: 0;
|
|
646
|
+
max-height: 280px;
|
|
466
647
|
overflow-y: auto;
|
|
467
648
|
display: flex;
|
|
468
649
|
flex-direction: column;
|
|
469
650
|
}
|
|
651
|
+
|
|
652
|
+
@media (max-height: 500px) {
|
|
653
|
+
.pro6pp-dropdown {
|
|
654
|
+
max-height: 180px;
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
|
|
470
658
|
.pro6pp-list {
|
|
471
|
-
list-style: none
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
659
|
+
list-style: none;
|
|
660
|
+
margin: 0;
|
|
661
|
+
padding: 0;
|
|
662
|
+
width: 100%;
|
|
475
663
|
}
|
|
664
|
+
|
|
476
665
|
.pro6pp-item {
|
|
477
|
-
padding: 12px
|
|
666
|
+
padding: 12px 14px;
|
|
478
667
|
cursor: pointer;
|
|
479
668
|
display: flex;
|
|
480
|
-
flex-direction: row;
|
|
481
669
|
align-items: center;
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
670
|
+
font-size: 15px;
|
|
671
|
+
line-height: 1.4;
|
|
672
|
+
color: #374151;
|
|
673
|
+
border-bottom: 1px solid #f3f4f6;
|
|
674
|
+
transition: background-color 0.1s;
|
|
675
|
+
flex-shrink: 0;
|
|
487
676
|
}
|
|
488
|
-
|
|
489
|
-
|
|
677
|
+
|
|
678
|
+
.pro6pp-item:last-child {
|
|
679
|
+
border-bottom: none;
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
@media (hover: hover) {
|
|
683
|
+
.pro6pp-item:hover, .pro6pp-item--active {
|
|
684
|
+
background-color: #f9fafb;
|
|
685
|
+
}
|
|
490
686
|
}
|
|
687
|
+
|
|
688
|
+
.pro6pp-item:active {
|
|
689
|
+
background-color: #f3f4f6;
|
|
690
|
+
}
|
|
691
|
+
|
|
491
692
|
.pro6pp-item__label {
|
|
492
|
-
font-weight:
|
|
493
|
-
flex-shrink:
|
|
693
|
+
font-weight: 400;
|
|
694
|
+
flex-shrink: 1;
|
|
695
|
+
overflow: hidden;
|
|
696
|
+
text-overflow: ellipsis;
|
|
697
|
+
white-space: nowrap;
|
|
494
698
|
}
|
|
699
|
+
|
|
700
|
+
.pro6pp-item__label--match {
|
|
701
|
+
font-weight: 520;
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
.pro6pp-item__label--unmatched {
|
|
705
|
+
font-weight: 400;
|
|
706
|
+
color: #4b5563;
|
|
707
|
+
}
|
|
708
|
+
|
|
495
709
|
.pro6pp-item__subtitle {
|
|
496
|
-
font-size: 14px;
|
|
497
710
|
color: #6b7280;
|
|
498
|
-
|
|
499
|
-
text-overflow: ellipsis;
|
|
500
|
-
flex-shrink: 1;
|
|
711
|
+
flex-shrink: 0;
|
|
501
712
|
}
|
|
713
|
+
|
|
502
714
|
.pro6pp-item__chevron {
|
|
503
|
-
|
|
715
|
+
color: #d1d5db;
|
|
504
716
|
display: flex;
|
|
505
717
|
align-items: center;
|
|
506
|
-
|
|
718
|
+
margin-left: auto;
|
|
507
719
|
padding-left: 8px;
|
|
508
720
|
}
|
|
721
|
+
|
|
509
722
|
.pro6pp-no-results {
|
|
510
|
-
padding: 16px;
|
|
723
|
+
padding: 24px 16px;
|
|
511
724
|
color: #6b7280;
|
|
512
|
-
font-size:
|
|
725
|
+
font-size: 15px;
|
|
513
726
|
text-align: center;
|
|
514
727
|
}
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
padding: 10px;
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
flex-shrink: 0;
|
|
728
|
+
|
|
729
|
+
.pro6pp-loader-item {
|
|
730
|
+
padding: 10px 12px;
|
|
731
|
+
color: #6b7280;
|
|
732
|
+
font-size: 0.875rem;
|
|
733
|
+
display: flex;
|
|
734
|
+
align-items: center;
|
|
735
|
+
justify-content: center;
|
|
736
|
+
gap: 8px;
|
|
737
|
+
background-color: #f9fafb;
|
|
738
|
+
border-top: 1px solid #f3f4f6;
|
|
527
739
|
}
|
|
528
|
-
|
|
529
|
-
|
|
740
|
+
|
|
741
|
+
.pro6pp-mini-spinner {
|
|
742
|
+
width: 14px;
|
|
743
|
+
height: 14px;
|
|
744
|
+
border: 2px solid #e5e7eb;
|
|
745
|
+
border-top-color: #6b7280;
|
|
746
|
+
border-radius: 50%;
|
|
747
|
+
animation: pro6pp-spin 0.6s linear infinite;
|
|
748
|
+
}
|
|
749
|
+
|
|
750
|
+
@media (max-width: 640px) {
|
|
751
|
+
.pro6pp-input {
|
|
752
|
+
font-size: 16px;
|
|
753
|
+
padding: 10px 12px;
|
|
754
|
+
}
|
|
755
|
+
.pro6pp-item {
|
|
756
|
+
padding: 10px 12px;
|
|
757
|
+
font-size: 14px;
|
|
758
|
+
}
|
|
530
759
|
}
|
|
531
760
|
|
|
532
761
|
@keyframes pro6pp-spin {
|
|
@@ -535,21 +764,76 @@ var DEFAULT_STYLES = `
|
|
|
535
764
|
`;
|
|
536
765
|
|
|
537
766
|
// src/index.tsx
|
|
767
|
+
var HighlightedText = ({ text, query }) => {
|
|
768
|
+
const segments = useMemo(() => getHighlightSegments(text, query), [text, query]);
|
|
769
|
+
return /* @__PURE__ */ React.createElement("span", { className: "pro6pp-item__label" }, segments.map(
|
|
770
|
+
(seg, i) => seg.match ? /* @__PURE__ */ React.createElement("span", { key: i, className: "pro6pp-item__label--match" }, seg.text) : /* @__PURE__ */ React.createElement("span", { key: i, className: "pro6pp-item__label--unmatched" }, seg.text)
|
|
771
|
+
));
|
|
772
|
+
};
|
|
538
773
|
function useInfer(config) {
|
|
539
|
-
const [state, setState] = useState(
|
|
774
|
+
const [state, setState] = useState(() => {
|
|
775
|
+
if (config.initialValue) {
|
|
776
|
+
const suffix = config.initialValue.addition ? ` ${config.initialValue.addition}` : "";
|
|
777
|
+
const postcodeStr = config.initialValue.postcode ? `${config.initialValue.postcode}, ` : "";
|
|
778
|
+
return {
|
|
779
|
+
...INITIAL_STATE,
|
|
780
|
+
value: config.initialValue,
|
|
781
|
+
query: `${config.initialValue.street}, ${config.initialValue.street_number}${suffix}, ${postcodeStr}${config.initialValue.city}`,
|
|
782
|
+
isValid: true,
|
|
783
|
+
stage: "final"
|
|
784
|
+
};
|
|
785
|
+
}
|
|
786
|
+
return INITIAL_STATE;
|
|
787
|
+
});
|
|
788
|
+
const callbacksRef = useRef({
|
|
789
|
+
onStateChange: config.onStateChange,
|
|
790
|
+
onSelect: config.onSelect
|
|
791
|
+
});
|
|
792
|
+
useEffect(() => {
|
|
793
|
+
callbacksRef.current = {
|
|
794
|
+
onStateChange: config.onStateChange,
|
|
795
|
+
onSelect: config.onSelect
|
|
796
|
+
};
|
|
797
|
+
}, [config.onStateChange, config.onSelect]);
|
|
540
798
|
const core = useMemo(() => {
|
|
541
|
-
|
|
799
|
+
const instance = new InferCore({
|
|
542
800
|
...config,
|
|
543
801
|
onStateChange: (newState) => {
|
|
544
802
|
setState({ ...newState });
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
803
|
+
callbacksRef.current.onStateChange?.(newState);
|
|
804
|
+
},
|
|
805
|
+
onSelect: (selection) => {
|
|
806
|
+
callbacksRef.current.onSelect?.(selection);
|
|
548
807
|
}
|
|
549
808
|
});
|
|
550
|
-
|
|
809
|
+
if (config.initialValue) {
|
|
810
|
+
const address = config.initialValue;
|
|
811
|
+
const suffix = address.addition ? ` ${address.addition}` : "";
|
|
812
|
+
const postcodeStr = address.postcode ? `${address.postcode}, ` : "";
|
|
813
|
+
const label = `${address.street}, ${address.street_number}${suffix}, ${postcodeStr}${address.city}`;
|
|
814
|
+
instance.selectItem({ label, value: address });
|
|
815
|
+
}
|
|
816
|
+
return instance;
|
|
817
|
+
}, [
|
|
818
|
+
config.country,
|
|
819
|
+
config.authKey,
|
|
820
|
+
config.apiUrl,
|
|
821
|
+
config.fetcher,
|
|
822
|
+
config.limit,
|
|
823
|
+
config.debounceMs,
|
|
824
|
+
config.maxRetries,
|
|
825
|
+
config.initialValue,
|
|
826
|
+
config.language
|
|
827
|
+
]);
|
|
828
|
+
const setValue = (address) => {
|
|
829
|
+
if (!address) return;
|
|
830
|
+
const suffix = address.addition ? ` ${address.addition}` : "";
|
|
831
|
+
const postcodeStr = address.postcode ? `${address.postcode}, ` : "";
|
|
832
|
+
const label = `${address.street}, ${address.street_number}${suffix}, ${postcodeStr}${address.city}`;
|
|
833
|
+
core.selectItem({ label, value: address });
|
|
834
|
+
};
|
|
551
835
|
return {
|
|
552
|
-
/** The current UI state (suggestions, loading status, query, etc.). */
|
|
836
|
+
/** The current UI state (suggestions, loading status, query, value, etc.). */
|
|
553
837
|
state,
|
|
554
838
|
/** The raw InferCore instance for manual control. */
|
|
555
839
|
core,
|
|
@@ -559,160 +843,175 @@ function useInfer(config) {
|
|
|
559
843
|
onChange: (e) => core.handleInput(e.target.value),
|
|
560
844
|
onKeyDown: (e) => core.handleKeyDown(e)
|
|
561
845
|
},
|
|
562
|
-
/**
|
|
846
|
+
/** Manually select a specific suggestion. */
|
|
563
847
|
selectItem: (item) => core.selectItem(item),
|
|
564
|
-
/**
|
|
848
|
+
/** Programmatically set the address value. */
|
|
849
|
+
setValue,
|
|
850
|
+
/** Load more results. */
|
|
565
851
|
loadMore: () => core.loadMore()
|
|
566
852
|
};
|
|
567
853
|
}
|
|
568
|
-
var Pro6PPInfer = (
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
854
|
+
var Pro6PPInfer = forwardRef(
|
|
855
|
+
({
|
|
856
|
+
className,
|
|
857
|
+
style,
|
|
858
|
+
inputProps,
|
|
859
|
+
placeholder = "Start typing an address...",
|
|
860
|
+
renderItem,
|
|
861
|
+
disableDefaultStyles = false,
|
|
862
|
+
noResultsText = "No results found",
|
|
863
|
+
loadingText = "Loading more...",
|
|
864
|
+
renderNoResults,
|
|
865
|
+
showClearButton = true,
|
|
866
|
+
...config
|
|
867
|
+
}, ref) => {
|
|
868
|
+
const { state, selectItem, loadMore, inputProps: coreInputProps, core } = useInfer(config);
|
|
869
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
870
|
+
const internalInputRef = useRef(null);
|
|
871
|
+
const wrapperRef = useRef(null);
|
|
872
|
+
const observerTarget = useRef(null);
|
|
873
|
+
useImperativeHandle(ref, () => internalInputRef.current);
|
|
874
|
+
useEffect(() => {
|
|
875
|
+
if (disableDefaultStyles) return;
|
|
876
|
+
const styleId = "pro6pp-styles";
|
|
877
|
+
if (!document.getElementById(styleId)) {
|
|
878
|
+
const styleEl = document.createElement("style");
|
|
879
|
+
styleEl.id = styleId;
|
|
880
|
+
styleEl.textContent = DEFAULT_STYLES;
|
|
881
|
+
document.head.appendChild(styleEl);
|
|
882
|
+
}
|
|
883
|
+
}, [disableDefaultStyles]);
|
|
884
|
+
useEffect(() => {
|
|
885
|
+
const handleClickOutside = (event) => {
|
|
886
|
+
if (wrapperRef.current && !wrapperRef.current.contains(event.target)) {
|
|
887
|
+
setIsOpen(false);
|
|
888
|
+
}
|
|
889
|
+
};
|
|
890
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
891
|
+
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
892
|
+
}, []);
|
|
893
|
+
useEffect(() => {
|
|
894
|
+
const currentTarget = observerTarget.current;
|
|
895
|
+
if (!currentTarget) return;
|
|
896
|
+
const observer = new IntersectionObserver(
|
|
897
|
+
(entries) => {
|
|
898
|
+
if (entries[0].isIntersecting && state.hasMore && !state.isLoading) {
|
|
899
|
+
loadMore();
|
|
900
|
+
}
|
|
901
|
+
},
|
|
902
|
+
{ threshold: 0.1 }
|
|
903
|
+
);
|
|
904
|
+
observer.observe(currentTarget);
|
|
905
|
+
return () => {
|
|
906
|
+
if (currentTarget) observer.unobserve(currentTarget);
|
|
907
|
+
};
|
|
908
|
+
}, [state.hasMore, state.isLoading, loadMore, isOpen]);
|
|
909
|
+
const items = useMemo(() => {
|
|
910
|
+
return [
|
|
911
|
+
...state.cities.map((c) => ({ ...c, type: "city" })),
|
|
912
|
+
...state.streets.map((s) => ({ ...s, type: "street" })),
|
|
913
|
+
...state.suggestions.map((s) => ({ ...s, type: "suggestion" }))
|
|
914
|
+
];
|
|
915
|
+
}, [state.cities, state.streets, state.suggestions]);
|
|
916
|
+
const handleSelect = (item) => {
|
|
917
|
+
const isFinal = selectItem(item);
|
|
918
|
+
if (!isFinal) {
|
|
919
|
+
setTimeout(() => internalInputRef.current?.focus(), 0);
|
|
920
|
+
} else {
|
|
598
921
|
setIsOpen(false);
|
|
599
922
|
}
|
|
600
923
|
};
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
"input",
|
|
629
|
-
{
|
|
630
|
-
ref: inputRef,
|
|
631
|
-
type: "text",
|
|
632
|
-
className: "pro6pp-input",
|
|
633
|
-
placeholder,
|
|
634
|
-
autoComplete: "off",
|
|
635
|
-
...inputProps,
|
|
636
|
-
...coreInputProps,
|
|
637
|
-
onFocus: (e) => {
|
|
638
|
-
setIsOpen(true);
|
|
639
|
-
inputProps?.onFocus?.(e);
|
|
924
|
+
const handleClear = () => {
|
|
925
|
+
core.handleInput("");
|
|
926
|
+
internalInputRef.current?.focus();
|
|
927
|
+
};
|
|
928
|
+
const hasResults = items.length > 0;
|
|
929
|
+
const showNoResults = !state.isLoading && !state.isError && state.query.length > 0 && !hasResults && !state.isValid;
|
|
930
|
+
const showDropdown = isOpen && (hasResults || state.isLoading || showNoResults);
|
|
931
|
+
const isInfiniteLoading = state.isLoading && items.length > 0;
|
|
932
|
+
return /* @__PURE__ */ React.createElement("div", { ref: wrapperRef, className: `pro6pp-wrapper ${className || ""}`, style }, /* @__PURE__ */ React.createElement("div", { style: { position: "relative" } }, /* @__PURE__ */ React.createElement(
|
|
933
|
+
"input",
|
|
934
|
+
{
|
|
935
|
+
ref: internalInputRef,
|
|
936
|
+
type: "text",
|
|
937
|
+
className: "pro6pp-input",
|
|
938
|
+
placeholder,
|
|
939
|
+
autoComplete: "off",
|
|
940
|
+
autoCorrect: "off",
|
|
941
|
+
autoCapitalize: "none",
|
|
942
|
+
spellCheck: "false",
|
|
943
|
+
inputMode: "search",
|
|
944
|
+
enterKeyHint: "search",
|
|
945
|
+
...inputProps,
|
|
946
|
+
...coreInputProps,
|
|
947
|
+
onFocus: (e) => {
|
|
948
|
+
setIsOpen(true);
|
|
949
|
+
inputProps?.onFocus?.(e);
|
|
950
|
+
}
|
|
640
951
|
}
|
|
641
|
-
}
|
|
642
|
-
|
|
643
|
-
"button",
|
|
644
|
-
{
|
|
645
|
-
type: "button",
|
|
646
|
-
className: "pro6pp-clear-button",
|
|
647
|
-
onClick: handleClear,
|
|
648
|
-
"aria-label": "Clear input"
|
|
649
|
-
},
|
|
650
|
-
/* @__PURE__ */ React.createElement(
|
|
651
|
-
"svg",
|
|
952
|
+
), /* @__PURE__ */ React.createElement("div", { className: "pro6pp-input-addons" }, showClearButton && state.query.length > 0 && /* @__PURE__ */ React.createElement(
|
|
953
|
+
"button",
|
|
652
954
|
{
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
stroke: "currentColor",
|
|
658
|
-
strokeWidth: "2",
|
|
659
|
-
strokeLinecap: "round",
|
|
660
|
-
strokeLinejoin: "round"
|
|
955
|
+
type: "button",
|
|
956
|
+
className: "pro6pp-clear-button",
|
|
957
|
+
onClick: handleClear,
|
|
958
|
+
"aria-label": "Clear input"
|
|
661
959
|
},
|
|
662
|
-
/* @__PURE__ */ React.createElement(
|
|
663
|
-
|
|
664
|
-
)
|
|
665
|
-
))), showDropdown && /* @__PURE__ */ React.createElement(
|
|
666
|
-
"div",
|
|
667
|
-
{
|
|
668
|
-
className: "pro6pp-dropdown",
|
|
669
|
-
onWheel: (e) => e.stopPropagation(),
|
|
670
|
-
onMouseDown: (e) => e.stopPropagation()
|
|
671
|
-
},
|
|
672
|
-
/* @__PURE__ */ React.createElement("ul", { className: "pro6pp-list", role: "listbox" }, hasResults ? items.map((item, index) => {
|
|
673
|
-
const isActive = index === state.selectedSuggestionIndex;
|
|
674
|
-
const secondaryText = item.subtitle || (item.count !== void 0 ? item.count : "");
|
|
675
|
-
const showChevron = item.value === void 0 || item.value === null;
|
|
676
|
-
return /* @__PURE__ */ React.createElement(
|
|
677
|
-
"li",
|
|
960
|
+
/* @__PURE__ */ React.createElement(
|
|
961
|
+
"svg",
|
|
678
962
|
{
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
"
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
963
|
+
width: "14",
|
|
964
|
+
height: "14",
|
|
965
|
+
viewBox: "0 0 24 24",
|
|
966
|
+
fill: "none",
|
|
967
|
+
stroke: "currentColor",
|
|
968
|
+
strokeWidth: "2",
|
|
969
|
+
strokeLinecap: "round",
|
|
970
|
+
strokeLinejoin: "round"
|
|
685
971
|
},
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
viewBox: "0 0 24 24",
|
|
692
|
-
fill: "none",
|
|
693
|
-
stroke: "currentColor",
|
|
694
|
-
strokeWidth: "2",
|
|
695
|
-
strokeLinecap: "round",
|
|
696
|
-
strokeLinejoin: "round"
|
|
697
|
-
},
|
|
698
|
-
/* @__PURE__ */ React.createElement("polyline", { points: "9 18 15 12 9 6" })
|
|
699
|
-
)))
|
|
700
|
-
);
|
|
701
|
-
}) : /* @__PURE__ */ React.createElement("li", { className: "pro6pp-no-results" }, renderNoResults ? renderNoResults(state) : noResultsText)),
|
|
702
|
-
state.hasMore && /* @__PURE__ */ React.createElement(
|
|
703
|
-
"button",
|
|
972
|
+
/* @__PURE__ */ React.createElement("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
|
|
973
|
+
/* @__PURE__ */ React.createElement("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
|
|
974
|
+
)
|
|
975
|
+
))), showDropdown && /* @__PURE__ */ React.createElement(
|
|
976
|
+
"div",
|
|
704
977
|
{
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
e.preventDefault();
|
|
709
|
-
loadMore();
|
|
710
|
-
}
|
|
978
|
+
className: "pro6pp-dropdown",
|
|
979
|
+
onWheel: (e) => e.stopPropagation(),
|
|
980
|
+
onMouseDown: (e) => e.stopPropagation()
|
|
711
981
|
},
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
982
|
+
/* @__PURE__ */ React.createElement("ul", { className: "pro6pp-list", role: "listbox" }, hasResults ? /* @__PURE__ */ React.createElement(React.Fragment, null, items.map((item, index) => {
|
|
983
|
+
const isActive = index === state.selectedSuggestionIndex;
|
|
984
|
+
const secondaryText = item.subtitle || (item.count !== void 0 ? item.count : "");
|
|
985
|
+
const showChevron = item.value === void 0 || item.value === null;
|
|
986
|
+
return /* @__PURE__ */ React.createElement(
|
|
987
|
+
"li",
|
|
988
|
+
{
|
|
989
|
+
key: `${item.label}-${index}`,
|
|
990
|
+
role: "option",
|
|
991
|
+
"aria-selected": isActive,
|
|
992
|
+
className: `pro6pp-item ${isActive ? "pro6pp-item--active" : ""}`,
|
|
993
|
+
onMouseDown: (e) => e.preventDefault(),
|
|
994
|
+
onClick: () => handleSelect(item)
|
|
995
|
+
},
|
|
996
|
+
renderItem ? renderItem(item, isActive) : /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(HighlightedText, { text: item.label, query: state.query }), secondaryText && /* @__PURE__ */ React.createElement("span", { className: "pro6pp-item__subtitle" }, ", ", secondaryText), showChevron && /* @__PURE__ */ React.createElement("div", { className: "pro6pp-item__chevron" }, /* @__PURE__ */ React.createElement(
|
|
997
|
+
"svg",
|
|
998
|
+
{
|
|
999
|
+
width: "16",
|
|
1000
|
+
height: "16",
|
|
1001
|
+
viewBox: "0 0 24 24",
|
|
1002
|
+
fill: "none",
|
|
1003
|
+
stroke: "currentColor",
|
|
1004
|
+
strokeWidth: "2",
|
|
1005
|
+
strokeLinecap: "round",
|
|
1006
|
+
strokeLinejoin: "round"
|
|
1007
|
+
},
|
|
1008
|
+
/* @__PURE__ */ React.createElement("polyline", { points: "9 18 15 12 9 6" })
|
|
1009
|
+
)))
|
|
1010
|
+
);
|
|
1011
|
+
}), state.hasMore && !state.isLoading && /* @__PURE__ */ React.createElement("li", { key: "sentinel", ref: observerTarget, style: { height: "1px", opacity: 0 } }), isInfiniteLoading && /* @__PURE__ */ React.createElement("li", { key: "loader", className: "pro6pp-loader-item" }, /* @__PURE__ */ React.createElement("div", { className: "pro6pp-mini-spinner" }), /* @__PURE__ */ React.createElement("span", null, loadingText))) : state.isLoading ? /* @__PURE__ */ React.createElement("li", { className: "pro6pp-no-results" }, "Searching...") : /* @__PURE__ */ React.createElement("li", { className: "pro6pp-no-results" }, renderNoResults ? renderNoResults(state) : noResultsText))
|
|
1012
|
+
));
|
|
1013
|
+
}
|
|
1014
|
+
);
|
|
716
1015
|
export {
|
|
717
1016
|
Pro6PPInfer,
|
|
718
1017
|
useInfer
|