@pro6pp/infer-react 0.0.2-beta.10 → 0.0.2-beta.11

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.
Files changed (3) hide show
  1. package/dist/index.cjs +120 -85
  2. package/dist/index.js +120 -85
  3. package/package.json +2 -2
package/dist/index.cjs CHANGED
@@ -83,7 +83,6 @@ var InferCore = class {
83
83
  __publicField(this, "state");
84
84
  __publicField(this, "abortController", null);
85
85
  __publicField(this, "debouncedFetch");
86
- __publicField(this, "isSelecting", false);
87
86
  this.country = config.country;
88
87
  this.authKey = config.authKey;
89
88
  this.explicitApiUrl = config.apiUrl;
@@ -107,10 +106,6 @@ var InferCore = class {
107
106
  * @param value The raw string from the input field.
108
107
  */
109
108
  handleInput(value) {
110
- if (this.isSelecting) {
111
- this.isSelecting = false;
112
- return;
113
- }
114
109
  this.currentLimit = this.baseLimit;
115
110
  const isEditingFinal = this.state.stage === "final" && value !== this.state.query;
116
111
  this.updateState({
@@ -139,7 +134,7 @@ var InferCore = class {
139
134
  * Supports:
140
135
  * - `ArrowUp`/`ArrowDown`: Navigate through the suggestion list.
141
136
  * - `Enter`: Select the currently highlighted suggestion.
142
- * - `Space`: Automatically inserts a comma if a numeric house number is detected.
137
+ * - `Space`: Automatically inserts a comma if a numeric street number is detected.
143
138
  * @param event The keyboard event from the input element.
144
139
  */
145
140
  handleKeyDown(event) {
@@ -201,14 +196,12 @@ var InferCore = class {
201
196
  }
202
197
  const valueObj = typeof item !== "string" && typeof item.value === "object" ? item.value : void 0;
203
198
  const isFullResult = !!valueObj && Object.keys(valueObj).length > 0;
204
- this.isSelecting = true;
205
199
  if (this.state.stage === "final" || isFullResult) {
206
200
  let finalQuery = label;
207
201
  if (valueObj && Object.keys(valueObj).length > 0) {
208
- const { street, street_number, house_number, city } = valueObj;
209
- const number = street_number || house_number;
210
- if (street && number && city) {
211
- finalQuery = `${street} ${number}, ${city}`;
202
+ const { street, street_number, city } = valueObj;
203
+ if (street && street_number && city) {
204
+ finalQuery = `${street} ${street_number}, ${city}`;
212
205
  }
213
206
  }
214
207
  this.finishSelection(finalQuery, valueObj);
@@ -221,7 +214,7 @@ var InferCore = class {
221
214
  shouldAutoInsertComma(currentVal) {
222
215
  const isStartOfSegmentAndNumeric = !currentVal.includes(",") && PATTERNS.DIGITS_1_3.test(currentVal.trim());
223
216
  if (isStartOfSegmentAndNumeric) return true;
224
- if (this.state.stage === "house_number") {
217
+ if (this.state.stage === "street_number") {
225
218
  const currentFragment = this.getCurrentFragment(currentVal);
226
219
  return PATTERNS.DIGITS_1_3.test(currentFragment);
227
220
  }
@@ -258,12 +251,12 @@ var InferCore = class {
258
251
  return;
259
252
  }
260
253
  const hasComma = query.includes(",");
261
- const isFirstSegment = !hasComma && (stage === "city" || stage === "street" || stage === "house_number_first");
254
+ const isFirstSegment = !hasComma && (stage === "city" || stage === "street" || stage === "street_number_first");
262
255
  if (isFirstSegment) {
263
256
  nextQuery = `${text}, `;
264
257
  } else {
265
258
  nextQuery = this.replaceLastSegment(query, text);
266
- if (stage !== "house_number") {
259
+ if (stage !== "street_number") {
267
260
  nextQuery += ", ";
268
261
  }
269
262
  }
@@ -325,8 +318,6 @@ var InferCore = class {
325
318
  stage: data.stage,
326
319
  isLoading: false
327
320
  };
328
- let autoSelect = false;
329
- let autoSelectItem = null;
330
321
  const rawSuggestions = data.suggestions || [];
331
322
  const uniqueSuggestions = [];
332
323
  const seen = /* @__PURE__ */ new Set();
@@ -347,28 +338,9 @@ var InferCore = class {
347
338
  newState.suggestions = uniqueSuggestions;
348
339
  newState.cities = [];
349
340
  newState.streets = [];
350
- const firstItem = uniqueSuggestions[0];
351
- const hasFullValue = firstItem && typeof firstItem.value === "object" && firstItem.value !== null && Object.keys(firstItem.value).length > 0;
352
- if ((data.stage === "final" || hasFullValue) && uniqueSuggestions.length === 1) {
353
- autoSelect = true;
354
- autoSelectItem = firstItem;
355
- }
356
341
  }
357
342
  newState.isValid = data.stage === "final";
358
- if (autoSelect && autoSelectItem) {
359
- newState.query = autoSelectItem.label;
360
- newState.suggestions = [];
361
- newState.cities = [];
362
- newState.streets = [];
363
- newState.isValid = true;
364
- newState.hasMore = false;
365
- this.isSelecting = true;
366
- this.updateState(newState);
367
- const val = typeof autoSelectItem.value === "object" ? autoSelectItem.value : autoSelectItem.label;
368
- this.onSelect(val);
369
- } else {
370
- this.updateState(newState);
371
- }
343
+ this.updateState(newState);
372
344
  }
373
345
  updateQueryAndFetch(nextQuery) {
374
346
  this.updateState({ query: nextQuery, suggestions: [], cities: [], streets: [] });
@@ -410,6 +382,36 @@ var InferCore = class {
410
382
  }
411
383
  };
412
384
 
385
+ // ../core/src/highlight.ts
386
+ function getHighlightSegments(text, query) {
387
+ if (!query || !text) return [{ text, match: false }];
388
+ const segments = [];
389
+ const normalizedText = text.toLowerCase();
390
+ const normalizedQuery = query.toLowerCase();
391
+ let queryCursor = 0;
392
+ let unmatchedCursor = 0;
393
+ for (let textCursor = 0; textCursor < text.length; textCursor++) {
394
+ const isMatch = queryCursor < query.length && normalizedText[textCursor] === normalizedQuery[queryCursor];
395
+ if (!isMatch) continue;
396
+ const hasPrecedingUnmatched = textCursor > unmatchedCursor;
397
+ if (hasPrecedingUnmatched) {
398
+ segments.push({ text: text.slice(unmatchedCursor, textCursor), match: false });
399
+ }
400
+ segments.push({ text: text[textCursor], match: true });
401
+ queryCursor++;
402
+ unmatchedCursor = textCursor + 1;
403
+ }
404
+ const hasRemainingText = unmatchedCursor < text.length;
405
+ if (hasRemainingText) {
406
+ segments.push({ text: text.slice(unmatchedCursor), match: false });
407
+ }
408
+ const isFullMatch = queryCursor === query.length;
409
+ if (!isFullMatch) {
410
+ return [{ text, match: false }];
411
+ }
412
+ return segments;
413
+ }
414
+
413
415
  // ../core/src/default-styles.ts
414
416
  var DEFAULT_STYLES = `
415
417
  .pro6pp-wrapper {
@@ -417,18 +419,20 @@ var DEFAULT_STYLES = `
417
419
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
418
420
  box-sizing: border-box;
419
421
  width: 100%;
422
+ -webkit-tap-highlight-color: transparent;
420
423
  }
421
424
  .pro6pp-wrapper * {
422
425
  box-sizing: border-box;
423
426
  }
424
427
  .pro6pp-input {
425
428
  width: 100%;
426
- padding: 10px 12px;
429
+ padding: 12px 14px;
427
430
  padding-right: 48px;
428
431
  border: 1px solid #e0e0e0;
429
- border-radius: 4px;
432
+ border-radius: 8px;
430
433
  font-size: 16px;
431
434
  line-height: 1.5;
435
+ appearance: none;
432
436
  transition: border-color 0.2s, box-shadow 0.2s;
433
437
  }
434
438
  .pro6pp-input:focus {
@@ -439,12 +443,11 @@ var DEFAULT_STYLES = `
439
443
 
440
444
  .pro6pp-input-addons {
441
445
  position: absolute;
442
- right: 6px;
446
+ right: 4px;
443
447
  top: 0;
444
448
  bottom: 0;
445
449
  display: flex;
446
450
  align-items: center;
447
- gap: 2px;
448
451
  pointer-events: none;
449
452
  }
450
453
  .pro6pp-input-addons > * {
@@ -454,32 +457,33 @@ var DEFAULT_STYLES = `
454
457
  .pro6pp-clear-button {
455
458
  background: none;
456
459
  border: none;
457
- width: 28px;
458
- height: 28px;
460
+ width: 40px;
461
+ height: 40px;
459
462
  cursor: pointer;
460
463
  color: #a3a3a3;
461
464
  display: flex;
462
465
  align-items: center;
463
466
  justify-content: center;
464
467
  border-radius: 50%;
465
- transition: color 0.2s, background-color 0.2s, transform 0.1s;
468
+ transition: color 0.2s, background-color 0.2s;
469
+ touch-action: manipulation;
466
470
  }
467
- .pro6pp-clear-button:hover {
468
- color: #1f2937;
469
- background-color: #f3f4f6;
471
+
472
+ @media (hover: hover) {
473
+ .pro6pp-clear-button:hover {
474
+ color: #1f2937;
475
+ background-color: #f3f4f6;
476
+ }
470
477
  }
478
+
471
479
  .pro6pp-clear-button:active {
472
- transform: scale(0.92);
473
- }
474
- .pro6pp-clear-button svg {
475
- width: 18px;
476
- height: 18px;
480
+ background-color: #f3f4f6;
477
481
  }
478
482
 
479
483
  .pro6pp-loader {
480
- width: 18px;
481
- height: 18px;
482
- margin: 0 4px;
484
+ width: 20px;
485
+ height: 20px;
486
+ margin: 0 8px;
483
487
  border: 2px solid #e0e0e0;
484
488
  border-top-color: #6b7280;
485
489
  border-radius: 50%;
@@ -492,38 +496,58 @@ var DEFAULT_STYLES = `
492
496
  top: 100%;
493
497
  left: 0;
494
498
  right: 0;
495
- z-index: 9999;
496
499
  margin-top: 4px;
497
- background: white;
498
- border: 1px solid #e0e0e0;
499
- border-radius: 4px;
500
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
501
- max-height: 300px;
500
+ background: #ffffff;
501
+ border: 1px solid #e5e7eb;
502
+ border-radius: 6px;
503
+ box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
504
+ z-index: 9999;
505
+ padding: 0;
506
+ max-height: 260px;
502
507
  overflow-y: auto;
503
508
  display: flex;
504
509
  flex-direction: column;
505
510
  }
511
+
512
+ @media (max-height: 500px) {
513
+ .pro6pp-dropdown {
514
+ max-height: 140px;
515
+ }
516
+ }
517
+
506
518
  .pro6pp-list {
507
- list-style: none !important;
508
- padding: 0 !important;
509
- margin: 0 !important;
510
- flex-grow: 1;
519
+ list-style: none;
520
+ margin: 0;
521
+ padding: 0;
522
+ width: 100%;
511
523
  }
524
+
512
525
  .pro6pp-item {
513
- padding: 12px 16px;
526
+ padding: 12px 14px;
514
527
  cursor: pointer;
515
528
  display: flex;
516
- flex-direction: row;
517
529
  align-items: center;
518
- color: #111827;
519
530
  font-size: 14px;
520
- line-height: 1.2;
521
- white-space: nowrap;
522
- overflow: hidden;
531
+ color: #374151;
532
+ border-bottom: 1px solid #f3f4f6;
533
+ transition: background-color 0.1s;
534
+ flex-shrink: 0;
535
+ }
536
+
537
+ .pro6pp-item:last-child {
538
+ border-bottom: none;
539
+ }
540
+
541
+ @media (hover: hover) {
542
+ .pro6pp-item:hover, .pro6pp-item--active {
543
+ background-color: #f9fafb;
544
+ }
523
545
  }
524
- .pro6pp-item:hover, .pro6pp-item--active {
525
- background-color: #f9fafb;
546
+
547
+ .pro6pp-item:active {
548
+ background-color: #f3f4f6;
526
549
  }
550
+
527
551
  .pro6pp-item__label {
528
552
  font-weight: 500;
529
553
  flex-shrink: 0;
@@ -531,37 +555,37 @@ var DEFAULT_STYLES = `
531
555
  .pro6pp-item__subtitle {
532
556
  font-size: 14px;
533
557
  color: #6b7280;
534
- overflow: hidden;
535
- text-overflow: ellipsis;
536
- flex-shrink: 1;
558
+ flex-grow: 1;
537
559
  }
538
560
  .pro6pp-item__chevron {
539
- margin-left: auto;
561
+ color: #d1d5db;
540
562
  display: flex;
541
563
  align-items: center;
542
- color: #9ca3af;
543
- padding-left: 8px;
564
+ margin-left: auto;
544
565
  }
566
+
545
567
  .pro6pp-no-results {
546
- padding: 16px;
568
+ padding: 24px 16px;
547
569
  color: #6b7280;
548
- font-size: 14px;
570
+ font-size: 15px;
549
571
  text-align: center;
550
572
  }
573
+
551
574
  .pro6pp-load-more {
552
575
  width: 100%;
553
- padding: 10px;
576
+ padding: 14px;
554
577
  background: #f9fafb;
555
578
  border: none;
556
579
  border-top: 1px solid #e0e0e0;
557
580
  color: #3b82f6;
558
- font-size: 13px;
581
+ font-size: 14px;
559
582
  font-weight: 600;
560
583
  cursor: pointer;
561
- transition: background-color 0.2s;
562
584
  flex-shrink: 0;
585
+ touch-action: manipulation;
563
586
  }
564
- .pro6pp-load-more:hover {
587
+
588
+ .pro6pp-load-more:active {
565
589
  background-color: #f3f4f6;
566
590
  }
567
591
 
@@ -571,6 +595,12 @@ var DEFAULT_STYLES = `
571
595
  `;
572
596
 
573
597
  // src/index.tsx
598
+ var HighlightedText = ({ text, query }) => {
599
+ const segments = (0, import_react.useMemo)(() => getHighlightSegments(text, query), [text, query]);
600
+ return /* @__PURE__ */ import_react.default.createElement("span", { className: "pro6pp-item__label" }, segments.map(
601
+ (seg, i) => seg.match ? /* @__PURE__ */ import_react.default.createElement("strong", { key: i, className: "pro6pp-item__label--match" }, seg.text) : seg.text
602
+ ));
603
+ };
574
604
  function useInfer(config) {
575
605
  const [state, setState] = (0, import_react.useState)(INITIAL_STATE);
576
606
  const callbacksRef = (0, import_react.useRef)({
@@ -688,6 +718,11 @@ var Pro6PPInfer = (0, import_react.forwardRef)(
688
718
  className: "pro6pp-input",
689
719
  placeholder,
690
720
  autoComplete: "off",
721
+ autoCorrect: "off",
722
+ autoCapitalize: "none",
723
+ spellCheck: "false",
724
+ inputMode: "search",
725
+ enterKeyHint: "search",
691
726
  ...inputProps,
692
727
  ...coreInputProps,
693
728
  onFocus: (e) => {
@@ -739,7 +774,7 @@ var Pro6PPInfer = (0, import_react.forwardRef)(
739
774
  onMouseDown: (e) => e.preventDefault(),
740
775
  onClick: () => handleSelect(item)
741
776
  },
742
- renderItem ? renderItem(item, isActive) : /* @__PURE__ */ import_react.default.createElement(import_react.default.Fragment, null, /* @__PURE__ */ import_react.default.createElement("span", { className: "pro6pp-item__label" }, item.label), secondaryText && /* @__PURE__ */ import_react.default.createElement("span", { className: "pro6pp-item__subtitle" }, ", ", secondaryText), showChevron && /* @__PURE__ */ import_react.default.createElement("div", { className: "pro6pp-item__chevron" }, /* @__PURE__ */ import_react.default.createElement(
777
+ renderItem ? renderItem(item, isActive) : /* @__PURE__ */ import_react.default.createElement(import_react.default.Fragment, null, /* @__PURE__ */ import_react.default.createElement(HighlightedText, { text: item.label, query: state.query }), secondaryText && /* @__PURE__ */ import_react.default.createElement("span", { className: "pro6pp-item__subtitle" }, ", ", secondaryText), showChevron && /* @__PURE__ */ import_react.default.createElement("div", { className: "pro6pp-item__chevron" }, /* @__PURE__ */ import_react.default.createElement(
743
778
  "svg",
744
779
  {
745
780
  width: "16",
package/dist/index.js CHANGED
@@ -57,7 +57,6 @@ var InferCore = class {
57
57
  __publicField(this, "state");
58
58
  __publicField(this, "abortController", null);
59
59
  __publicField(this, "debouncedFetch");
60
- __publicField(this, "isSelecting", false);
61
60
  this.country = config.country;
62
61
  this.authKey = config.authKey;
63
62
  this.explicitApiUrl = config.apiUrl;
@@ -81,10 +80,6 @@ var InferCore = class {
81
80
  * @param value The raw string from the input field.
82
81
  */
83
82
  handleInput(value) {
84
- if (this.isSelecting) {
85
- this.isSelecting = false;
86
- return;
87
- }
88
83
  this.currentLimit = this.baseLimit;
89
84
  const isEditingFinal = this.state.stage === "final" && value !== this.state.query;
90
85
  this.updateState({
@@ -113,7 +108,7 @@ var InferCore = class {
113
108
  * Supports:
114
109
  * - `ArrowUp`/`ArrowDown`: Navigate through the suggestion list.
115
110
  * - `Enter`: Select the currently highlighted suggestion.
116
- * - `Space`: Automatically inserts a comma if a numeric house number is detected.
111
+ * - `Space`: Automatically inserts a comma if a numeric street number is detected.
117
112
  * @param event The keyboard event from the input element.
118
113
  */
119
114
  handleKeyDown(event) {
@@ -175,14 +170,12 @@ var InferCore = class {
175
170
  }
176
171
  const valueObj = typeof item !== "string" && typeof item.value === "object" ? item.value : void 0;
177
172
  const isFullResult = !!valueObj && Object.keys(valueObj).length > 0;
178
- this.isSelecting = true;
179
173
  if (this.state.stage === "final" || isFullResult) {
180
174
  let finalQuery = label;
181
175
  if (valueObj && Object.keys(valueObj).length > 0) {
182
- const { street, street_number, house_number, city } = valueObj;
183
- const number = street_number || house_number;
184
- if (street && number && city) {
185
- finalQuery = `${street} ${number}, ${city}`;
176
+ const { street, street_number, city } = valueObj;
177
+ if (street && street_number && city) {
178
+ finalQuery = `${street} ${street_number}, ${city}`;
186
179
  }
187
180
  }
188
181
  this.finishSelection(finalQuery, valueObj);
@@ -195,7 +188,7 @@ var InferCore = class {
195
188
  shouldAutoInsertComma(currentVal) {
196
189
  const isStartOfSegmentAndNumeric = !currentVal.includes(",") && PATTERNS.DIGITS_1_3.test(currentVal.trim());
197
190
  if (isStartOfSegmentAndNumeric) return true;
198
- if (this.state.stage === "house_number") {
191
+ if (this.state.stage === "street_number") {
199
192
  const currentFragment = this.getCurrentFragment(currentVal);
200
193
  return PATTERNS.DIGITS_1_3.test(currentFragment);
201
194
  }
@@ -232,12 +225,12 @@ var InferCore = class {
232
225
  return;
233
226
  }
234
227
  const hasComma = query.includes(",");
235
- const isFirstSegment = !hasComma && (stage === "city" || stage === "street" || stage === "house_number_first");
228
+ const isFirstSegment = !hasComma && (stage === "city" || stage === "street" || stage === "street_number_first");
236
229
  if (isFirstSegment) {
237
230
  nextQuery = `${text}, `;
238
231
  } else {
239
232
  nextQuery = this.replaceLastSegment(query, text);
240
- if (stage !== "house_number") {
233
+ if (stage !== "street_number") {
241
234
  nextQuery += ", ";
242
235
  }
243
236
  }
@@ -299,8 +292,6 @@ var InferCore = class {
299
292
  stage: data.stage,
300
293
  isLoading: false
301
294
  };
302
- let autoSelect = false;
303
- let autoSelectItem = null;
304
295
  const rawSuggestions = data.suggestions || [];
305
296
  const uniqueSuggestions = [];
306
297
  const seen = /* @__PURE__ */ new Set();
@@ -321,28 +312,9 @@ var InferCore = class {
321
312
  newState.suggestions = uniqueSuggestions;
322
313
  newState.cities = [];
323
314
  newState.streets = [];
324
- const firstItem = uniqueSuggestions[0];
325
- const hasFullValue = firstItem && typeof firstItem.value === "object" && firstItem.value !== null && Object.keys(firstItem.value).length > 0;
326
- if ((data.stage === "final" || hasFullValue) && uniqueSuggestions.length === 1) {
327
- autoSelect = true;
328
- autoSelectItem = firstItem;
329
- }
330
315
  }
331
316
  newState.isValid = data.stage === "final";
332
- if (autoSelect && autoSelectItem) {
333
- newState.query = autoSelectItem.label;
334
- newState.suggestions = [];
335
- newState.cities = [];
336
- newState.streets = [];
337
- newState.isValid = true;
338
- newState.hasMore = false;
339
- this.isSelecting = true;
340
- this.updateState(newState);
341
- const val = typeof autoSelectItem.value === "object" ? autoSelectItem.value : autoSelectItem.label;
342
- this.onSelect(val);
343
- } else {
344
- this.updateState(newState);
345
- }
317
+ this.updateState(newState);
346
318
  }
347
319
  updateQueryAndFetch(nextQuery) {
348
320
  this.updateState({ query: nextQuery, suggestions: [], cities: [], streets: [] });
@@ -384,6 +356,36 @@ var InferCore = class {
384
356
  }
385
357
  };
386
358
 
359
+ // ../core/src/highlight.ts
360
+ function getHighlightSegments(text, query) {
361
+ if (!query || !text) return [{ text, match: false }];
362
+ const segments = [];
363
+ const normalizedText = text.toLowerCase();
364
+ const normalizedQuery = query.toLowerCase();
365
+ let queryCursor = 0;
366
+ let unmatchedCursor = 0;
367
+ for (let textCursor = 0; textCursor < text.length; textCursor++) {
368
+ const isMatch = queryCursor < query.length && normalizedText[textCursor] === normalizedQuery[queryCursor];
369
+ if (!isMatch) continue;
370
+ const hasPrecedingUnmatched = textCursor > unmatchedCursor;
371
+ if (hasPrecedingUnmatched) {
372
+ segments.push({ text: text.slice(unmatchedCursor, textCursor), match: false });
373
+ }
374
+ segments.push({ text: text[textCursor], match: true });
375
+ queryCursor++;
376
+ unmatchedCursor = textCursor + 1;
377
+ }
378
+ const hasRemainingText = unmatchedCursor < text.length;
379
+ if (hasRemainingText) {
380
+ segments.push({ text: text.slice(unmatchedCursor), match: false });
381
+ }
382
+ const isFullMatch = queryCursor === query.length;
383
+ if (!isFullMatch) {
384
+ return [{ text, match: false }];
385
+ }
386
+ return segments;
387
+ }
388
+
387
389
  // ../core/src/default-styles.ts
388
390
  var DEFAULT_STYLES = `
389
391
  .pro6pp-wrapper {
@@ -391,18 +393,20 @@ var DEFAULT_STYLES = `
391
393
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
392
394
  box-sizing: border-box;
393
395
  width: 100%;
396
+ -webkit-tap-highlight-color: transparent;
394
397
  }
395
398
  .pro6pp-wrapper * {
396
399
  box-sizing: border-box;
397
400
  }
398
401
  .pro6pp-input {
399
402
  width: 100%;
400
- padding: 10px 12px;
403
+ padding: 12px 14px;
401
404
  padding-right: 48px;
402
405
  border: 1px solid #e0e0e0;
403
- border-radius: 4px;
406
+ border-radius: 8px;
404
407
  font-size: 16px;
405
408
  line-height: 1.5;
409
+ appearance: none;
406
410
  transition: border-color 0.2s, box-shadow 0.2s;
407
411
  }
408
412
  .pro6pp-input:focus {
@@ -413,12 +417,11 @@ var DEFAULT_STYLES = `
413
417
 
414
418
  .pro6pp-input-addons {
415
419
  position: absolute;
416
- right: 6px;
420
+ right: 4px;
417
421
  top: 0;
418
422
  bottom: 0;
419
423
  display: flex;
420
424
  align-items: center;
421
- gap: 2px;
422
425
  pointer-events: none;
423
426
  }
424
427
  .pro6pp-input-addons > * {
@@ -428,32 +431,33 @@ var DEFAULT_STYLES = `
428
431
  .pro6pp-clear-button {
429
432
  background: none;
430
433
  border: none;
431
- width: 28px;
432
- height: 28px;
434
+ width: 40px;
435
+ height: 40px;
433
436
  cursor: pointer;
434
437
  color: #a3a3a3;
435
438
  display: flex;
436
439
  align-items: center;
437
440
  justify-content: center;
438
441
  border-radius: 50%;
439
- transition: color 0.2s, background-color 0.2s, transform 0.1s;
442
+ transition: color 0.2s, background-color 0.2s;
443
+ touch-action: manipulation;
440
444
  }
441
- .pro6pp-clear-button:hover {
442
- color: #1f2937;
443
- background-color: #f3f4f6;
445
+
446
+ @media (hover: hover) {
447
+ .pro6pp-clear-button:hover {
448
+ color: #1f2937;
449
+ background-color: #f3f4f6;
450
+ }
444
451
  }
452
+
445
453
  .pro6pp-clear-button:active {
446
- transform: scale(0.92);
447
- }
448
- .pro6pp-clear-button svg {
449
- width: 18px;
450
- height: 18px;
454
+ background-color: #f3f4f6;
451
455
  }
452
456
 
453
457
  .pro6pp-loader {
454
- width: 18px;
455
- height: 18px;
456
- margin: 0 4px;
458
+ width: 20px;
459
+ height: 20px;
460
+ margin: 0 8px;
457
461
  border: 2px solid #e0e0e0;
458
462
  border-top-color: #6b7280;
459
463
  border-radius: 50%;
@@ -466,38 +470,58 @@ var DEFAULT_STYLES = `
466
470
  top: 100%;
467
471
  left: 0;
468
472
  right: 0;
469
- z-index: 9999;
470
473
  margin-top: 4px;
471
- background: white;
472
- border: 1px solid #e0e0e0;
473
- border-radius: 4px;
474
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
475
- max-height: 300px;
474
+ background: #ffffff;
475
+ border: 1px solid #e5e7eb;
476
+ border-radius: 6px;
477
+ box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
478
+ z-index: 9999;
479
+ padding: 0;
480
+ max-height: 260px;
476
481
  overflow-y: auto;
477
482
  display: flex;
478
483
  flex-direction: column;
479
484
  }
485
+
486
+ @media (max-height: 500px) {
487
+ .pro6pp-dropdown {
488
+ max-height: 140px;
489
+ }
490
+ }
491
+
480
492
  .pro6pp-list {
481
- list-style: none !important;
482
- padding: 0 !important;
483
- margin: 0 !important;
484
- flex-grow: 1;
493
+ list-style: none;
494
+ margin: 0;
495
+ padding: 0;
496
+ width: 100%;
485
497
  }
498
+
486
499
  .pro6pp-item {
487
- padding: 12px 16px;
500
+ padding: 12px 14px;
488
501
  cursor: pointer;
489
502
  display: flex;
490
- flex-direction: row;
491
503
  align-items: center;
492
- color: #111827;
493
504
  font-size: 14px;
494
- line-height: 1.2;
495
- white-space: nowrap;
496
- overflow: hidden;
505
+ color: #374151;
506
+ border-bottom: 1px solid #f3f4f6;
507
+ transition: background-color 0.1s;
508
+ flex-shrink: 0;
509
+ }
510
+
511
+ .pro6pp-item:last-child {
512
+ border-bottom: none;
513
+ }
514
+
515
+ @media (hover: hover) {
516
+ .pro6pp-item:hover, .pro6pp-item--active {
517
+ background-color: #f9fafb;
518
+ }
497
519
  }
498
- .pro6pp-item:hover, .pro6pp-item--active {
499
- background-color: #f9fafb;
520
+
521
+ .pro6pp-item:active {
522
+ background-color: #f3f4f6;
500
523
  }
524
+
501
525
  .pro6pp-item__label {
502
526
  font-weight: 500;
503
527
  flex-shrink: 0;
@@ -505,37 +529,37 @@ var DEFAULT_STYLES = `
505
529
  .pro6pp-item__subtitle {
506
530
  font-size: 14px;
507
531
  color: #6b7280;
508
- overflow: hidden;
509
- text-overflow: ellipsis;
510
- flex-shrink: 1;
532
+ flex-grow: 1;
511
533
  }
512
534
  .pro6pp-item__chevron {
513
- margin-left: auto;
535
+ color: #d1d5db;
514
536
  display: flex;
515
537
  align-items: center;
516
- color: #9ca3af;
517
- padding-left: 8px;
538
+ margin-left: auto;
518
539
  }
540
+
519
541
  .pro6pp-no-results {
520
- padding: 16px;
542
+ padding: 24px 16px;
521
543
  color: #6b7280;
522
- font-size: 14px;
544
+ font-size: 15px;
523
545
  text-align: center;
524
546
  }
547
+
525
548
  .pro6pp-load-more {
526
549
  width: 100%;
527
- padding: 10px;
550
+ padding: 14px;
528
551
  background: #f9fafb;
529
552
  border: none;
530
553
  border-top: 1px solid #e0e0e0;
531
554
  color: #3b82f6;
532
- font-size: 13px;
555
+ font-size: 14px;
533
556
  font-weight: 600;
534
557
  cursor: pointer;
535
- transition: background-color 0.2s;
536
558
  flex-shrink: 0;
559
+ touch-action: manipulation;
537
560
  }
538
- .pro6pp-load-more:hover {
561
+
562
+ .pro6pp-load-more:active {
539
563
  background-color: #f3f4f6;
540
564
  }
541
565
 
@@ -545,6 +569,12 @@ var DEFAULT_STYLES = `
545
569
  `;
546
570
 
547
571
  // src/index.tsx
572
+ var HighlightedText = ({ text, query }) => {
573
+ const segments = useMemo(() => getHighlightSegments(text, query), [text, query]);
574
+ return /* @__PURE__ */ React.createElement("span", { className: "pro6pp-item__label" }, segments.map(
575
+ (seg, i) => seg.match ? /* @__PURE__ */ React.createElement("strong", { key: i, className: "pro6pp-item__label--match" }, seg.text) : seg.text
576
+ ));
577
+ };
548
578
  function useInfer(config) {
549
579
  const [state, setState] = useState(INITIAL_STATE);
550
580
  const callbacksRef = useRef({
@@ -662,6 +692,11 @@ var Pro6PPInfer = forwardRef(
662
692
  className: "pro6pp-input",
663
693
  placeholder,
664
694
  autoComplete: "off",
695
+ autoCorrect: "off",
696
+ autoCapitalize: "none",
697
+ spellCheck: "false",
698
+ inputMode: "search",
699
+ enterKeyHint: "search",
665
700
  ...inputProps,
666
701
  ...coreInputProps,
667
702
  onFocus: (e) => {
@@ -713,7 +748,7 @@ var Pro6PPInfer = forwardRef(
713
748
  onMouseDown: (e) => e.preventDefault(),
714
749
  onClick: () => handleSelect(item)
715
750
  },
716
- renderItem ? renderItem(item, isActive) : /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("span", { className: "pro6pp-item__label" }, item.label), secondaryText && /* @__PURE__ */ React.createElement("span", { className: "pro6pp-item__subtitle" }, ", ", secondaryText), showChevron && /* @__PURE__ */ React.createElement("div", { className: "pro6pp-item__chevron" }, /* @__PURE__ */ React.createElement(
751
+ 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(
717
752
  "svg",
718
753
  {
719
754
  width: "16",
package/package.json CHANGED
@@ -20,7 +20,7 @@
20
20
  "url": "https://github.com/pro6pp/infer-sdk/issues"
21
21
  },
22
22
  "sideEffects": false,
23
- "version": "0.0.2-beta.10",
23
+ "version": "0.0.2-beta.11",
24
24
  "main": "./dist/index.cjs",
25
25
  "module": "./dist/index.js",
26
26
  "types": "./dist/index.d.ts",
@@ -46,7 +46,7 @@
46
46
  "react": ">=16"
47
47
  },
48
48
  "dependencies": {
49
- "@pro6pp/infer-core": "0.0.2-beta.8"
49
+ "@pro6pp/infer-core": "0.0.2-beta.9"
50
50
  },
51
51
  "devDependencies": {
52
52
  "@testing-library/dom": "^10.4.1",