@autobusal/common 1.33.9 → 1.33.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4,6 +4,7 @@ import { UseFormRegister, UseFormSetValue } from 'react-hook-form';
4
4
  import { useOutside } from '@autobusal/hooks';
5
5
  import { Validate } from '@autobusal/utilities';
6
6
  import Suggestions from './Suggestions';
7
+ import { fold } from './fold';
7
8
  import { Container } from './styles';
8
9
  import { AutocompleteData } from './types';
9
10
 
@@ -49,9 +50,11 @@ const Autocomplete = ({ name, label, defaultValue, data, validation, t, refs, on
49
50
  // eslint-disable-next-line react-hooks/exhaustive-deps
50
51
  }, [ data ]);
51
52
 
52
- const options = data.filter(item => {
53
- return item.name.toLowerCase().indexOf(q.toLowerCase()) > -1;
54
- });
53
+ const needle = fold(q);
54
+
55
+ const options = data.filter(item => (
56
+ [ item.name, ...(item.search ?? []) ].some(candidate => fold(candidate).includes(needle))
57
+ ));
55
58
 
56
59
  const onChange = (event: ChangeEvent<HTMLInputElement>): void => {
57
60
  setQ(event.target.value);
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Case- and accent-insensitive form of a string, for matching only.
3
+ *
4
+ * Claude - Date: 2026-08-21
5
+ *
6
+ * The search box compared raw lowercased strings, which quietly failed on
7
+ * this platform's most common names: in Albanian the cities are Korcë,
8
+ * Vlorë, Shkodër and Kukës, so typing "korce", "vlore", "shkoder" or
9
+ * "kukes" - which is how anybody without an Albanian keyboard layout types
10
+ * them, and how the ENGLISH spellings are written - matched nothing at all.
11
+ *
12
+ * The mobile app has always done this (src/lib/cities.ts); the web never
13
+ * got the same treatment.
14
+ *
15
+ * NFD splits an accented character into its base letter plus a combining
16
+ * mark, and the range below is the Unicode combining-diacritics block, so
17
+ * "ë" becomes "e" and "ç" becomes "c" without a per-language table. It is
18
+ * deliberately not a full transliteration: Cyrillic and Greek are left
19
+ * alone, because those are the scripts people type those names IN, and
20
+ * `search` carries the Latin spellings alongside them anyway.
21
+ */
22
+ export const fold = (value: string): string => (
23
+ value
24
+ .toLowerCase()
25
+ .normalize('NFD')
26
+ .replace(/[\u0300-\u036f]/g, '')
27
+ );
@@ -1,4 +1,20 @@
1
1
  export interface AutocompleteData {
2
+ /** What the option shows - already in the visitor's language */
2
3
  name: string
4
+
3
5
  value: string
4
- }
6
+
7
+ /**
8
+ * Extra spellings this option should MATCH on but never display.
9
+ *
10
+ * Claude - Date: 2026-08-21
11
+ *
12
+ * Matching has to be language-blind even though display is not. A Greek
13
+ * typing "Θεσσαλονίκη", a Serb typing "Solun" and an Englishman typing
14
+ * "Thessaloniki" all mean the same city, and none of them should have to
15
+ * be browsing in the right language to find it. FlixBus behaves the same
16
+ * way - their autocomplete returns one city id for all three queries and
17
+ * only the LABEL changes with the interface language.
18
+ */
19
+ search?: string[]
20
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@autobusal/common",
3
- "version": "1.33.9",
3
+ "version": "1.33.10",
4
4
  "author": "Ferjolt Ozuni",
5
5
  "type": "module",
6
6
  "main": "index.ts"