@pro6pp/infer-react 0.0.2-beta.16 → 0.0.2-beta.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +31 -0
- package/dist/index.cjs +152 -35
- package/dist/index.js +152 -35
- package/dist/styles.css +203 -0
- package/package.json +7 -4
package/README.md
CHANGED
|
@@ -47,6 +47,37 @@ You can customize the appearance of the component via the following props:
|
|
|
47
47
|
| `showClearButton` | If `true`, displays a button to empty the input field. Defaults to `true`. |
|
|
48
48
|
| `loadingText` | The text displayed at the bottom of the list when fetching more results. |
|
|
49
49
|
|
|
50
|
+
## Styling
|
|
51
|
+
|
|
52
|
+
By default, the component auto-injects the necessary CSS. You have several options:
|
|
53
|
+
|
|
54
|
+
### Option 1: Use auto-injected styles (default)
|
|
55
|
+
|
|
56
|
+
No extra setup needed. The CSS is embedded and injected automatically.
|
|
57
|
+
|
|
58
|
+
### Option 2: Import CSS separately
|
|
59
|
+
|
|
60
|
+
If you prefer to import the CSS file directly:
|
|
61
|
+
|
|
62
|
+
```tsx
|
|
63
|
+
import { Pro6PPInfer } from '@pro6pp/infer-react';
|
|
64
|
+
import '@pro6pp/infer-react/styles.css';
|
|
65
|
+
|
|
66
|
+
<Pro6PPInfer
|
|
67
|
+
authKey="..."
|
|
68
|
+
country="NL"
|
|
69
|
+
disableDefaultStyles // disable auto-injection since we imported the CSS
|
|
70
|
+
/>;
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Option 3: Fully custom styles
|
|
74
|
+
|
|
75
|
+
Set `disableDefaultStyles` and provide your own CSS targeting the `.pro6pp-*` classes:
|
|
76
|
+
|
|
77
|
+
```tsx
|
|
78
|
+
<Pro6PPInfer authKey="..." country="NL" disableDefaultStyles className="my-custom-wrapper" />
|
|
79
|
+
```
|
|
80
|
+
|
|
50
81
|
---
|
|
51
82
|
|
|
52
83
|
Alternatively, you can use the headless `useInfer` hook.
|
package/dist/index.cjs
CHANGED
|
@@ -38,6 +38,100 @@ __export(index_exports, {
|
|
|
38
38
|
module.exports = __toCommonJS(index_exports);
|
|
39
39
|
var import_react = __toESM(require("react"), 1);
|
|
40
40
|
|
|
41
|
+
// ../core/src/label-formatter.ts
|
|
42
|
+
function normalize(str) {
|
|
43
|
+
return str.toLowerCase().trim();
|
|
44
|
+
}
|
|
45
|
+
function escapeRegex(str) {
|
|
46
|
+
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
47
|
+
}
|
|
48
|
+
function findWordPosition(query, value) {
|
|
49
|
+
const normalizedQuery = normalize(query);
|
|
50
|
+
const normalizedValue = normalize(value);
|
|
51
|
+
if (normalizedValue.includes(" ")) {
|
|
52
|
+
return normalizedQuery.indexOf(normalizedValue);
|
|
53
|
+
}
|
|
54
|
+
const pattern = new RegExp(`(?:^|[,\\s])${escapeRegex(normalizedValue)}(?:$|[,\\s])`, "g");
|
|
55
|
+
const match = pattern.exec(normalizedQuery);
|
|
56
|
+
if (match) {
|
|
57
|
+
const matchStart = match.index;
|
|
58
|
+
const firstChar = normalizedQuery[matchStart];
|
|
59
|
+
if (firstChar === "," || firstChar === " ") {
|
|
60
|
+
return matchStart + 1;
|
|
61
|
+
}
|
|
62
|
+
return matchStart;
|
|
63
|
+
}
|
|
64
|
+
return -1;
|
|
65
|
+
}
|
|
66
|
+
function detectComponentOrder(query, value) {
|
|
67
|
+
const detected = [];
|
|
68
|
+
const componentMap = [];
|
|
69
|
+
if (value.street) {
|
|
70
|
+
componentMap.push({ value: value.street, type: "street" });
|
|
71
|
+
}
|
|
72
|
+
if (value.city) {
|
|
73
|
+
componentMap.push({ value: value.city, type: "city" });
|
|
74
|
+
}
|
|
75
|
+
if (value.postcode) {
|
|
76
|
+
componentMap.push({ value: value.postcode, type: "postcode" });
|
|
77
|
+
}
|
|
78
|
+
if (value.street_number !== void 0 && value.street_number !== null) {
|
|
79
|
+
componentMap.push({ value: String(value.street_number), type: "street_number" });
|
|
80
|
+
}
|
|
81
|
+
if (value.addition) {
|
|
82
|
+
componentMap.push({ value: value.addition, type: "addition" });
|
|
83
|
+
}
|
|
84
|
+
for (const comp of componentMap) {
|
|
85
|
+
const position = findWordPosition(query, comp.value);
|
|
86
|
+
if (position !== -1) {
|
|
87
|
+
detected.push({
|
|
88
|
+
type: comp.type,
|
|
89
|
+
value: comp.value,
|
|
90
|
+
position
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
detected.sort((a, b) => a.position - b.position);
|
|
95
|
+
return detected;
|
|
96
|
+
}
|
|
97
|
+
function formatLabelByInputOrder(query, value) {
|
|
98
|
+
if (!value || !query) {
|
|
99
|
+
return "";
|
|
100
|
+
}
|
|
101
|
+
const detectedOrder = detectComponentOrder(query, value);
|
|
102
|
+
const detectedTypes = new Set(detectedOrder.map((d) => d.type));
|
|
103
|
+
const parts = [];
|
|
104
|
+
for (const detected of detectedOrder) {
|
|
105
|
+
parts.push(detected.value);
|
|
106
|
+
}
|
|
107
|
+
const defaultOrder = ["street", "street_number", "addition", "postcode", "city"];
|
|
108
|
+
for (const type of defaultOrder) {
|
|
109
|
+
if (detectedTypes.has(type)) continue;
|
|
110
|
+
let val;
|
|
111
|
+
switch (type) {
|
|
112
|
+
case "street":
|
|
113
|
+
val = value.street;
|
|
114
|
+
break;
|
|
115
|
+
case "city":
|
|
116
|
+
val = value.city;
|
|
117
|
+
break;
|
|
118
|
+
case "street_number":
|
|
119
|
+
val = value.street_number !== void 0 ? String(value.street_number) : void 0;
|
|
120
|
+
break;
|
|
121
|
+
case "postcode":
|
|
122
|
+
val = value.postcode;
|
|
123
|
+
break;
|
|
124
|
+
case "addition":
|
|
125
|
+
val = value.addition;
|
|
126
|
+
break;
|
|
127
|
+
}
|
|
128
|
+
if (val) {
|
|
129
|
+
parts.push(val);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return parts.join(", ");
|
|
133
|
+
}
|
|
134
|
+
|
|
41
135
|
// ../core/src/core.ts
|
|
42
136
|
var DEFAULTS = {
|
|
43
137
|
API_URL: "https://api.pro6pp.nl/v2",
|
|
@@ -203,10 +297,11 @@ var InferCore = class {
|
|
|
203
297
|
if (this.state.stage === "final" || isFullResult) {
|
|
204
298
|
let finalQuery = label;
|
|
205
299
|
if (valueObj && Object.keys(valueObj).length > 0) {
|
|
206
|
-
const { street, street_number, city, addition } = valueObj;
|
|
300
|
+
const { street, street_number, postcode, city, addition } = valueObj;
|
|
207
301
|
if (street && street_number && city) {
|
|
208
302
|
const suffix = addition ? ` ${addition}` : "";
|
|
209
|
-
|
|
303
|
+
const postcodeStr = postcode ? `${postcode}, ` : "";
|
|
304
|
+
finalQuery = `${street}, ${street_number}${suffix}, ${postcodeStr}${city}`;
|
|
210
305
|
}
|
|
211
306
|
}
|
|
212
307
|
this.finishSelection(finalQuery, valueObj);
|
|
@@ -348,7 +443,8 @@ var InferCore = class {
|
|
|
348
443
|
const key = `${item.label}|${item.subtitle || ""}|${JSON.stringify(item.value || {})}`;
|
|
349
444
|
if (!seen.has(key)) {
|
|
350
445
|
seen.add(key);
|
|
351
|
-
|
|
446
|
+
const reformattedItem = this.reformatSuggestionLabel(item);
|
|
447
|
+
uniqueSuggestions.push(reformattedItem);
|
|
352
448
|
}
|
|
353
449
|
}
|
|
354
450
|
const totalCount = uniqueSuggestions.length + (data.cities?.length || 0) + (data.streets?.length || 0);
|
|
@@ -372,6 +468,25 @@ var InferCore = class {
|
|
|
372
468
|
this.selectItem(uniqueSuggestions[0]);
|
|
373
469
|
}
|
|
374
470
|
}
|
|
471
|
+
/**
|
|
472
|
+
* Reformats a suggestion's label based on the user's input order.
|
|
473
|
+
* If the suggestion has a structured value object, we reorder the label
|
|
474
|
+
* to match how the user typed the components.
|
|
475
|
+
*/
|
|
476
|
+
reformatSuggestionLabel(item) {
|
|
477
|
+
if (!item.value || typeof item.value === "string") {
|
|
478
|
+
return item;
|
|
479
|
+
}
|
|
480
|
+
const addressValue = item.value;
|
|
481
|
+
if (!addressValue.street || !addressValue.city) {
|
|
482
|
+
return item;
|
|
483
|
+
}
|
|
484
|
+
const reformattedLabel = formatLabelByInputOrder(this.state.query, addressValue);
|
|
485
|
+
if (reformattedLabel) {
|
|
486
|
+
return { ...item, label: reformattedLabel };
|
|
487
|
+
}
|
|
488
|
+
return item;
|
|
489
|
+
}
|
|
375
490
|
updateQueryAndFetch(nextQuery) {
|
|
376
491
|
this.updateState({
|
|
377
492
|
query: nextQuery,
|
|
@@ -421,6 +536,19 @@ var InferCore = class {
|
|
|
421
536
|
};
|
|
422
537
|
|
|
423
538
|
// ../core/src/highlight.ts
|
|
539
|
+
function mergeSegments(segments) {
|
|
540
|
+
if (segments.length === 0) return segments;
|
|
541
|
+
const merged = [];
|
|
542
|
+
for (const seg of segments) {
|
|
543
|
+
const last = merged[merged.length - 1];
|
|
544
|
+
if (last && last.match === seg.match) {
|
|
545
|
+
last.text += seg.text;
|
|
546
|
+
} else {
|
|
547
|
+
merged.push({ text: seg.text, match: seg.match });
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
return merged;
|
|
551
|
+
}
|
|
424
552
|
function getHighlightSegments(text, query) {
|
|
425
553
|
if (!query || !text) return [{ text, match: false }];
|
|
426
554
|
const segments = [];
|
|
@@ -447,7 +575,7 @@ function getHighlightSegments(text, query) {
|
|
|
447
575
|
if (!isFullMatch) {
|
|
448
576
|
return [{ text, match: false }];
|
|
449
577
|
}
|
|
450
|
-
return segments;
|
|
578
|
+
return mergeSegments(segments);
|
|
451
579
|
}
|
|
452
580
|
|
|
453
581
|
// ../core/src/default-styles.ts
|
|
@@ -583,15 +711,23 @@ var DEFAULT_STYLES = `
|
|
|
583
711
|
}
|
|
584
712
|
|
|
585
713
|
.pro6pp-item__label {
|
|
586
|
-
font-weight:
|
|
714
|
+
font-weight: 400;
|
|
587
715
|
flex-shrink: 1;
|
|
588
716
|
overflow: hidden;
|
|
589
717
|
text-overflow: ellipsis;
|
|
590
718
|
white-space: nowrap;
|
|
591
719
|
}
|
|
592
720
|
|
|
721
|
+
.pro6pp-item__label--match {
|
|
722
|
+
font-weight: 520;
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
.pro6pp-item__label--unmatched {
|
|
726
|
+
font-weight: 400;
|
|
727
|
+
color: #4b5563;
|
|
728
|
+
}
|
|
729
|
+
|
|
593
730
|
.pro6pp-item__subtitle {
|
|
594
|
-
font-size: 13px;
|
|
595
731
|
color: #6b7280;
|
|
596
732
|
flex-shrink: 0;
|
|
597
733
|
}
|
|
@@ -611,20 +747,6 @@ var DEFAULT_STYLES = `
|
|
|
611
747
|
text-align: center;
|
|
612
748
|
}
|
|
613
749
|
|
|
614
|
-
.pro6pp-load-more {
|
|
615
|
-
width: 100%;
|
|
616
|
-
padding: 14px;
|
|
617
|
-
background: #f9fafb;
|
|
618
|
-
border: none;
|
|
619
|
-
border-top: 1px solid #e0e0e0;
|
|
620
|
-
color: #3b82f6;
|
|
621
|
-
font-size: 14px;
|
|
622
|
-
font-weight: 600;
|
|
623
|
-
cursor: pointer;
|
|
624
|
-
flex-shrink: 0;
|
|
625
|
-
touch-action: manipulation;
|
|
626
|
-
}
|
|
627
|
-
|
|
628
750
|
.pro6pp-loader-item {
|
|
629
751
|
padding: 10px 12px;
|
|
630
752
|
color: #6b7280;
|
|
@@ -655,17 +777,6 @@ var DEFAULT_STYLES = `
|
|
|
655
777
|
padding: 10px 12px;
|
|
656
778
|
font-size: 14px;
|
|
657
779
|
}
|
|
658
|
-
.pro6pp-item__subtitle {
|
|
659
|
-
font-size: 12px;
|
|
660
|
-
}
|
|
661
|
-
.pro6pp-load-more {
|
|
662
|
-
padding: 12px;
|
|
663
|
-
font-size: 13px;
|
|
664
|
-
}
|
|
665
|
-
}
|
|
666
|
-
|
|
667
|
-
.pro6pp-load-more:active {
|
|
668
|
-
background-color: #f3f4f6;
|
|
669
780
|
}
|
|
670
781
|
|
|
671
782
|
@keyframes pro6pp-spin {
|
|
@@ -677,16 +788,18 @@ var DEFAULT_STYLES = `
|
|
|
677
788
|
var HighlightedText = ({ text, query }) => {
|
|
678
789
|
const segments = (0, import_react.useMemo)(() => getHighlightSegments(text, query), [text, query]);
|
|
679
790
|
return /* @__PURE__ */ import_react.default.createElement("span", { className: "pro6pp-item__label" }, segments.map(
|
|
680
|
-
(seg, i) => seg.match ? /* @__PURE__ */ import_react.default.createElement("
|
|
791
|
+
(seg, i) => seg.match ? /* @__PURE__ */ import_react.default.createElement("span", { key: i, className: "pro6pp-item__label--match" }, seg.text) : /* @__PURE__ */ import_react.default.createElement("span", { key: i, className: "pro6pp-item__label--unmatched" }, seg.text)
|
|
681
792
|
));
|
|
682
793
|
};
|
|
683
794
|
function useInfer(config) {
|
|
684
795
|
const [state, setState] = (0, import_react.useState)(() => {
|
|
685
796
|
if (config.initialValue) {
|
|
797
|
+
const suffix = config.initialValue.addition ? ` ${config.initialValue.addition}` : "";
|
|
798
|
+
const postcodeStr = config.initialValue.postcode ? `${config.initialValue.postcode}, ` : "";
|
|
686
799
|
return {
|
|
687
800
|
...INITIAL_STATE,
|
|
688
801
|
value: config.initialValue,
|
|
689
|
-
query: `${config.initialValue.street} ${config.initialValue.street_number}, ${config.initialValue.city}`,
|
|
802
|
+
query: `${config.initialValue.street}, ${config.initialValue.street_number}${suffix}, ${postcodeStr}${config.initialValue.city}`,
|
|
690
803
|
isValid: true,
|
|
691
804
|
stage: "final"
|
|
692
805
|
};
|
|
@@ -716,7 +829,9 @@ function useInfer(config) {
|
|
|
716
829
|
});
|
|
717
830
|
if (config.initialValue) {
|
|
718
831
|
const address = config.initialValue;
|
|
719
|
-
const
|
|
832
|
+
const suffix = address.addition ? ` ${address.addition}` : "";
|
|
833
|
+
const postcodeStr = address.postcode ? `${address.postcode}, ` : "";
|
|
834
|
+
const label = `${address.street}, ${address.street_number}${suffix}, ${postcodeStr}${address.city}`;
|
|
720
835
|
instance.selectItem({ label, value: address });
|
|
721
836
|
}
|
|
722
837
|
return instance;
|
|
@@ -732,7 +847,9 @@ function useInfer(config) {
|
|
|
732
847
|
]);
|
|
733
848
|
const setValue = (address) => {
|
|
734
849
|
if (!address) return;
|
|
735
|
-
const
|
|
850
|
+
const suffix = address.addition ? ` ${address.addition}` : "";
|
|
851
|
+
const postcodeStr = address.postcode ? `${address.postcode}, ` : "";
|
|
852
|
+
const label = `${address.street}, ${address.street_number}${suffix}, ${postcodeStr}${address.city}`;
|
|
736
853
|
core.selectItem({ label, value: address });
|
|
737
854
|
};
|
|
738
855
|
return {
|
package/dist/index.js
CHANGED
|
@@ -12,6 +12,100 @@ import React, {
|
|
|
12
12
|
useImperativeHandle
|
|
13
13
|
} from "react";
|
|
14
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
|
+
}
|
|
108
|
+
|
|
15
109
|
// ../core/src/core.ts
|
|
16
110
|
var DEFAULTS = {
|
|
17
111
|
API_URL: "https://api.pro6pp.nl/v2",
|
|
@@ -177,10 +271,11 @@ var InferCore = class {
|
|
|
177
271
|
if (this.state.stage === "final" || isFullResult) {
|
|
178
272
|
let finalQuery = label;
|
|
179
273
|
if (valueObj && Object.keys(valueObj).length > 0) {
|
|
180
|
-
const { street, street_number, city, addition } = valueObj;
|
|
274
|
+
const { street, street_number, postcode, city, addition } = valueObj;
|
|
181
275
|
if (street && street_number && city) {
|
|
182
276
|
const suffix = addition ? ` ${addition}` : "";
|
|
183
|
-
|
|
277
|
+
const postcodeStr = postcode ? `${postcode}, ` : "";
|
|
278
|
+
finalQuery = `${street}, ${street_number}${suffix}, ${postcodeStr}${city}`;
|
|
184
279
|
}
|
|
185
280
|
}
|
|
186
281
|
this.finishSelection(finalQuery, valueObj);
|
|
@@ -322,7 +417,8 @@ var InferCore = class {
|
|
|
322
417
|
const key = `${item.label}|${item.subtitle || ""}|${JSON.stringify(item.value || {})}`;
|
|
323
418
|
if (!seen.has(key)) {
|
|
324
419
|
seen.add(key);
|
|
325
|
-
|
|
420
|
+
const reformattedItem = this.reformatSuggestionLabel(item);
|
|
421
|
+
uniqueSuggestions.push(reformattedItem);
|
|
326
422
|
}
|
|
327
423
|
}
|
|
328
424
|
const totalCount = uniqueSuggestions.length + (data.cities?.length || 0) + (data.streets?.length || 0);
|
|
@@ -346,6 +442,25 @@ var InferCore = class {
|
|
|
346
442
|
this.selectItem(uniqueSuggestions[0]);
|
|
347
443
|
}
|
|
348
444
|
}
|
|
445
|
+
/**
|
|
446
|
+
* Reformats a suggestion's label based on the user's input order.
|
|
447
|
+
* If the suggestion has a structured value object, we reorder the label
|
|
448
|
+
* to match how the user typed the components.
|
|
449
|
+
*/
|
|
450
|
+
reformatSuggestionLabel(item) {
|
|
451
|
+
if (!item.value || typeof item.value === "string") {
|
|
452
|
+
return item;
|
|
453
|
+
}
|
|
454
|
+
const addressValue = item.value;
|
|
455
|
+
if (!addressValue.street || !addressValue.city) {
|
|
456
|
+
return item;
|
|
457
|
+
}
|
|
458
|
+
const reformattedLabel = formatLabelByInputOrder(this.state.query, addressValue);
|
|
459
|
+
if (reformattedLabel) {
|
|
460
|
+
return { ...item, label: reformattedLabel };
|
|
461
|
+
}
|
|
462
|
+
return item;
|
|
463
|
+
}
|
|
349
464
|
updateQueryAndFetch(nextQuery) {
|
|
350
465
|
this.updateState({
|
|
351
466
|
query: nextQuery,
|
|
@@ -395,6 +510,19 @@ var InferCore = class {
|
|
|
395
510
|
};
|
|
396
511
|
|
|
397
512
|
// ../core/src/highlight.ts
|
|
513
|
+
function mergeSegments(segments) {
|
|
514
|
+
if (segments.length === 0) return segments;
|
|
515
|
+
const merged = [];
|
|
516
|
+
for (const seg of segments) {
|
|
517
|
+
const last = merged[merged.length - 1];
|
|
518
|
+
if (last && last.match === seg.match) {
|
|
519
|
+
last.text += seg.text;
|
|
520
|
+
} else {
|
|
521
|
+
merged.push({ text: seg.text, match: seg.match });
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
return merged;
|
|
525
|
+
}
|
|
398
526
|
function getHighlightSegments(text, query) {
|
|
399
527
|
if (!query || !text) return [{ text, match: false }];
|
|
400
528
|
const segments = [];
|
|
@@ -421,7 +549,7 @@ function getHighlightSegments(text, query) {
|
|
|
421
549
|
if (!isFullMatch) {
|
|
422
550
|
return [{ text, match: false }];
|
|
423
551
|
}
|
|
424
|
-
return segments;
|
|
552
|
+
return mergeSegments(segments);
|
|
425
553
|
}
|
|
426
554
|
|
|
427
555
|
// ../core/src/default-styles.ts
|
|
@@ -557,15 +685,23 @@ var DEFAULT_STYLES = `
|
|
|
557
685
|
}
|
|
558
686
|
|
|
559
687
|
.pro6pp-item__label {
|
|
560
|
-
font-weight:
|
|
688
|
+
font-weight: 400;
|
|
561
689
|
flex-shrink: 1;
|
|
562
690
|
overflow: hidden;
|
|
563
691
|
text-overflow: ellipsis;
|
|
564
692
|
white-space: nowrap;
|
|
565
693
|
}
|
|
566
694
|
|
|
695
|
+
.pro6pp-item__label--match {
|
|
696
|
+
font-weight: 520;
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
.pro6pp-item__label--unmatched {
|
|
700
|
+
font-weight: 400;
|
|
701
|
+
color: #4b5563;
|
|
702
|
+
}
|
|
703
|
+
|
|
567
704
|
.pro6pp-item__subtitle {
|
|
568
|
-
font-size: 13px;
|
|
569
705
|
color: #6b7280;
|
|
570
706
|
flex-shrink: 0;
|
|
571
707
|
}
|
|
@@ -585,20 +721,6 @@ var DEFAULT_STYLES = `
|
|
|
585
721
|
text-align: center;
|
|
586
722
|
}
|
|
587
723
|
|
|
588
|
-
.pro6pp-load-more {
|
|
589
|
-
width: 100%;
|
|
590
|
-
padding: 14px;
|
|
591
|
-
background: #f9fafb;
|
|
592
|
-
border: none;
|
|
593
|
-
border-top: 1px solid #e0e0e0;
|
|
594
|
-
color: #3b82f6;
|
|
595
|
-
font-size: 14px;
|
|
596
|
-
font-weight: 600;
|
|
597
|
-
cursor: pointer;
|
|
598
|
-
flex-shrink: 0;
|
|
599
|
-
touch-action: manipulation;
|
|
600
|
-
}
|
|
601
|
-
|
|
602
724
|
.pro6pp-loader-item {
|
|
603
725
|
padding: 10px 12px;
|
|
604
726
|
color: #6b7280;
|
|
@@ -629,17 +751,6 @@ var DEFAULT_STYLES = `
|
|
|
629
751
|
padding: 10px 12px;
|
|
630
752
|
font-size: 14px;
|
|
631
753
|
}
|
|
632
|
-
.pro6pp-item__subtitle {
|
|
633
|
-
font-size: 12px;
|
|
634
|
-
}
|
|
635
|
-
.pro6pp-load-more {
|
|
636
|
-
padding: 12px;
|
|
637
|
-
font-size: 13px;
|
|
638
|
-
}
|
|
639
|
-
}
|
|
640
|
-
|
|
641
|
-
.pro6pp-load-more:active {
|
|
642
|
-
background-color: #f3f4f6;
|
|
643
754
|
}
|
|
644
755
|
|
|
645
756
|
@keyframes pro6pp-spin {
|
|
@@ -651,16 +762,18 @@ var DEFAULT_STYLES = `
|
|
|
651
762
|
var HighlightedText = ({ text, query }) => {
|
|
652
763
|
const segments = useMemo(() => getHighlightSegments(text, query), [text, query]);
|
|
653
764
|
return /* @__PURE__ */ React.createElement("span", { className: "pro6pp-item__label" }, segments.map(
|
|
654
|
-
(seg, i) => seg.match ? /* @__PURE__ */ React.createElement("
|
|
765
|
+
(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)
|
|
655
766
|
));
|
|
656
767
|
};
|
|
657
768
|
function useInfer(config) {
|
|
658
769
|
const [state, setState] = useState(() => {
|
|
659
770
|
if (config.initialValue) {
|
|
771
|
+
const suffix = config.initialValue.addition ? ` ${config.initialValue.addition}` : "";
|
|
772
|
+
const postcodeStr = config.initialValue.postcode ? `${config.initialValue.postcode}, ` : "";
|
|
660
773
|
return {
|
|
661
774
|
...INITIAL_STATE,
|
|
662
775
|
value: config.initialValue,
|
|
663
|
-
query: `${config.initialValue.street} ${config.initialValue.street_number}, ${config.initialValue.city}`,
|
|
776
|
+
query: `${config.initialValue.street}, ${config.initialValue.street_number}${suffix}, ${postcodeStr}${config.initialValue.city}`,
|
|
664
777
|
isValid: true,
|
|
665
778
|
stage: "final"
|
|
666
779
|
};
|
|
@@ -690,7 +803,9 @@ function useInfer(config) {
|
|
|
690
803
|
});
|
|
691
804
|
if (config.initialValue) {
|
|
692
805
|
const address = config.initialValue;
|
|
693
|
-
const
|
|
806
|
+
const suffix = address.addition ? ` ${address.addition}` : "";
|
|
807
|
+
const postcodeStr = address.postcode ? `${address.postcode}, ` : "";
|
|
808
|
+
const label = `${address.street}, ${address.street_number}${suffix}, ${postcodeStr}${address.city}`;
|
|
694
809
|
instance.selectItem({ label, value: address });
|
|
695
810
|
}
|
|
696
811
|
return instance;
|
|
@@ -706,7 +821,9 @@ function useInfer(config) {
|
|
|
706
821
|
]);
|
|
707
822
|
const setValue = (address) => {
|
|
708
823
|
if (!address) return;
|
|
709
|
-
const
|
|
824
|
+
const suffix = address.addition ? ` ${address.addition}` : "";
|
|
825
|
+
const postcodeStr = address.postcode ? `${address.postcode}, ` : "";
|
|
826
|
+
const label = `${address.street}, ${address.street_number}${suffix}, ${postcodeStr}${address.city}`;
|
|
710
827
|
core.selectItem({ label, value: address });
|
|
711
828
|
};
|
|
712
829
|
return {
|
package/dist/styles.css
ADDED
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
/* Pro6PP Infer SDK - Default Styles */
|
|
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
|
+
|
|
24
|
+
.pro6pp-input::placeholder {
|
|
25
|
+
font-size: 16px;
|
|
26
|
+
color: #a3a3a3;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.pro6pp-input:focus {
|
|
30
|
+
outline: none;
|
|
31
|
+
border-color: #3b82f6;
|
|
32
|
+
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.pro6pp-input-addons {
|
|
36
|
+
position: absolute;
|
|
37
|
+
right: 4px;
|
|
38
|
+
top: 0;
|
|
39
|
+
bottom: 0;
|
|
40
|
+
display: flex;
|
|
41
|
+
align-items: center;
|
|
42
|
+
pointer-events: none;
|
|
43
|
+
}
|
|
44
|
+
.pro6pp-input-addons > * {
|
|
45
|
+
pointer-events: auto;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.pro6pp-clear-button {
|
|
49
|
+
background: none;
|
|
50
|
+
border: none;
|
|
51
|
+
width: 32px;
|
|
52
|
+
height: 32px;
|
|
53
|
+
cursor: pointer;
|
|
54
|
+
color: #a3a3a3;
|
|
55
|
+
display: flex;
|
|
56
|
+
align-items: center;
|
|
57
|
+
justify-content: center;
|
|
58
|
+
border-radius: 50%;
|
|
59
|
+
transition: color 0.2s, background-color 0.2s;
|
|
60
|
+
touch-action: manipulation;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
@media (hover: hover) {
|
|
64
|
+
.pro6pp-clear-button:hover {
|
|
65
|
+
color: #1f2937;
|
|
66
|
+
background-color: #f3f4f6;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.pro6pp-clear-button:active {
|
|
71
|
+
background-color: #f3f4f6;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
.pro6pp-dropdown {
|
|
75
|
+
position: absolute;
|
|
76
|
+
top: 100%;
|
|
77
|
+
left: 0;
|
|
78
|
+
right: 0;
|
|
79
|
+
margin-top: 4px;
|
|
80
|
+
background: #ffffff;
|
|
81
|
+
border: 1px solid #e5e7eb;
|
|
82
|
+
border-radius: 6px;
|
|
83
|
+
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
|
|
84
|
+
z-index: 9999;
|
|
85
|
+
padding: 0;
|
|
86
|
+
max-height: 280px;
|
|
87
|
+
overflow-y: auto;
|
|
88
|
+
display: flex;
|
|
89
|
+
flex-direction: column;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
@media (max-height: 500px) {
|
|
93
|
+
.pro6pp-dropdown {
|
|
94
|
+
max-height: 180px;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
.pro6pp-list {
|
|
99
|
+
list-style: none;
|
|
100
|
+
margin: 0;
|
|
101
|
+
padding: 0;
|
|
102
|
+
width: 100%;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
.pro6pp-item {
|
|
106
|
+
padding: 12px 14px;
|
|
107
|
+
cursor: pointer;
|
|
108
|
+
display: flex;
|
|
109
|
+
align-items: center;
|
|
110
|
+
font-size: 15px;
|
|
111
|
+
line-height: 1.4;
|
|
112
|
+
color: #374151;
|
|
113
|
+
border-bottom: 1px solid #f3f4f6;
|
|
114
|
+
transition: background-color 0.1s;
|
|
115
|
+
flex-shrink: 0;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
.pro6pp-item:last-child {
|
|
119
|
+
border-bottom: none;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
@media (hover: hover) {
|
|
123
|
+
.pro6pp-item:hover, .pro6pp-item--active {
|
|
124
|
+
background-color: #f9fafb;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
.pro6pp-item:active {
|
|
129
|
+
background-color: #f3f4f6;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
.pro6pp-item__label {
|
|
133
|
+
font-weight: 400;
|
|
134
|
+
flex-shrink: 1;
|
|
135
|
+
overflow: hidden;
|
|
136
|
+
text-overflow: ellipsis;
|
|
137
|
+
white-space: nowrap;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
.pro6pp-item__label--match {
|
|
141
|
+
font-weight: 520;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
.pro6pp-item__label--unmatched {
|
|
145
|
+
font-weight: 400;
|
|
146
|
+
color: #4b5563;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
.pro6pp-item__subtitle {
|
|
150
|
+
color: #6b7280;
|
|
151
|
+
flex-shrink: 0;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
.pro6pp-item__chevron {
|
|
155
|
+
color: #d1d5db;
|
|
156
|
+
display: flex;
|
|
157
|
+
align-items: center;
|
|
158
|
+
margin-left: auto;
|
|
159
|
+
padding-left: 8px;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
.pro6pp-no-results {
|
|
163
|
+
padding: 24px 16px;
|
|
164
|
+
color: #6b7280;
|
|
165
|
+
font-size: 15px;
|
|
166
|
+
text-align: center;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
.pro6pp-loader-item {
|
|
170
|
+
padding: 10px 12px;
|
|
171
|
+
color: #6b7280;
|
|
172
|
+
font-size: 0.875rem;
|
|
173
|
+
display: flex;
|
|
174
|
+
align-items: center;
|
|
175
|
+
justify-content: center;
|
|
176
|
+
gap: 8px;
|
|
177
|
+
background-color: #f9fafb;
|
|
178
|
+
border-top: 1px solid #f3f4f6;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
.pro6pp-mini-spinner {
|
|
182
|
+
width: 14px;
|
|
183
|
+
height: 14px;
|
|
184
|
+
border: 2px solid #e5e7eb;
|
|
185
|
+
border-top-color: #6b7280;
|
|
186
|
+
border-radius: 50%;
|
|
187
|
+
animation: pro6pp-spin 0.6s linear infinite;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
@media (max-width: 640px) {
|
|
191
|
+
.pro6pp-input {
|
|
192
|
+
font-size: 16px;
|
|
193
|
+
padding: 10px 12px;
|
|
194
|
+
}
|
|
195
|
+
.pro6pp-item {
|
|
196
|
+
padding: 10px 12px;
|
|
197
|
+
font-size: 14px;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
@keyframes pro6pp-spin {
|
|
202
|
+
to { transform: rotate(360deg); }
|
|
203
|
+
}
|
package/package.json
CHANGED
|
@@ -19,8 +19,10 @@
|
|
|
19
19
|
"bugs": {
|
|
20
20
|
"url": "https://github.com/pro6pp/infer-sdk/issues"
|
|
21
21
|
},
|
|
22
|
-
"sideEffects":
|
|
23
|
-
|
|
22
|
+
"sideEffects": [
|
|
23
|
+
"*.css"
|
|
24
|
+
],
|
|
25
|
+
"version": "0.0.2-beta.18",
|
|
24
26
|
"main": "./dist/index.cjs",
|
|
25
27
|
"module": "./dist/index.js",
|
|
26
28
|
"types": "./dist/index.d.ts",
|
|
@@ -29,7 +31,8 @@
|
|
|
29
31
|
"types": "./dist/index.d.ts",
|
|
30
32
|
"import": "./dist/index.js",
|
|
31
33
|
"require": "./dist/index.cjs"
|
|
32
|
-
}
|
|
34
|
+
},
|
|
35
|
+
"./styles.css": "./dist/styles.css"
|
|
33
36
|
},
|
|
34
37
|
"files": [
|
|
35
38
|
"dist",
|
|
@@ -46,7 +49,7 @@
|
|
|
46
49
|
"react": ">=16"
|
|
47
50
|
},
|
|
48
51
|
"dependencies": {
|
|
49
|
-
"@pro6pp/infer-core": "0.0.2-beta.
|
|
52
|
+
"@pro6pp/infer-core": "0.0.2-beta.16"
|
|
50
53
|
},
|
|
51
54
|
"devDependencies": {
|
|
52
55
|
"@testing-library/dom": "^10.4.1",
|