@stapel/search-react 0.21.0 → 0.22.0

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 (62) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/README.md +65 -2
  3. package/dist/api/types.d.ts +24 -3
  4. package/dist/api/types.d.ts.map +1 -1
  5. package/dist/api/types.js.map +1 -1
  6. package/dist/default/FacetGroupControl.d.ts +34 -4
  7. package/dist/default/FacetGroupControl.d.ts.map +1 -1
  8. package/dist/default/FacetGroupControl.js +112 -7
  9. package/dist/default/FacetGroupControl.js.map +1 -1
  10. package/dist/default/PartitionChips.d.ts +23 -0
  11. package/dist/default/PartitionChips.d.ts.map +1 -0
  12. package/dist/default/PartitionChips.js +94 -0
  13. package/dist/default/PartitionChips.js.map +1 -0
  14. package/dist/default/PopularValues.d.ts +58 -0
  15. package/dist/default/PopularValues.d.ts.map +1 -0
  16. package/dist/default/PopularValues.js +46 -0
  17. package/dist/default/PopularValues.js.map +1 -0
  18. package/dist/default/index.d.ts +5 -1
  19. package/dist/default/index.d.ts.map +1 -1
  20. package/dist/default/index.js +6 -1
  21. package/dist/default/index.js.map +1 -1
  22. package/dist/headless/useFacetLabels.js +7 -7
  23. package/dist/headless/useFacetLabels.js.map +1 -1
  24. package/dist/i18n/es.d.ts.map +1 -1
  25. package/dist/i18n/es.js +6 -0
  26. package/dist/i18n/es.js.map +1 -1
  27. package/dist/i18n/keys.d.ts +30 -0
  28. package/dist/i18n/keys.d.ts.map +1 -1
  29. package/dist/i18n/keys.js +37 -0
  30. package/dist/i18n/keys.js.map +1 -1
  31. package/dist/i18n/ru.d.ts.map +1 -1
  32. package/dist/i18n/ru.js +6 -0
  33. package/dist/i18n/ru.js.map +1 -1
  34. package/dist/index.d.ts +3 -2
  35. package/dist/index.d.ts.map +1 -1
  36. package/dist/index.js +1 -0
  37. package/dist/index.js.map +1 -1
  38. package/dist/state/facets.d.ts +26 -6
  39. package/dist/state/facets.d.ts.map +1 -1
  40. package/dist/state/facets.js +72 -15
  41. package/dist/state/facets.js.map +1 -1
  42. package/dist/state/translit.d.ts +58 -0
  43. package/dist/state/translit.d.ts.map +1 -0
  44. package/dist/state/translit.js +115 -0
  45. package/dist/state/translit.js.map +1 -0
  46. package/llms.txt +3 -1
  47. package/manifest.json +38 -1
  48. package/nav-manifest.json +1 -1
  49. package/package.json +7 -7
  50. package/src/analytics/generated/events.json +1 -1
  51. package/src/api/types.ts +29 -3
  52. package/src/default/FacetGroupControl.tsx +213 -8
  53. package/src/default/PartitionChips.tsx +161 -0
  54. package/src/default/PopularValues.tsx +151 -0
  55. package/src/default/index.ts +15 -0
  56. package/src/headless/useFacetLabels.ts +7 -7
  57. package/src/i18n/es.ts +6 -0
  58. package/src/i18n/keys.ts +38 -0
  59. package/src/i18n/ru.ts +6 -0
  60. package/src/index.ts +9 -0
  61. package/src/state/facets.ts +107 -27
  62. package/src/state/translit.ts +113 -0
@@ -1 +1 @@
1
- {"version":3,"file":"facets.d.ts","sourceRoot":"","sources":["../../src/state/facets.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"facets.d.ts","sourceRoot":"","sources":["../../src/state/facets.ts"],"names":[],"mappings":"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"}
@@ -8,9 +8,12 @@
8
8
  * they would have if you swapped to them. A panel that greys the siblings
9
9
  * out has silently converted a drill-down facet into a naive one, and the
10
10
  * e2e leg in the spec (§7.2) exists to catch exactly that.
11
- * 2. **Option LABELS have one stated order: ANSWER, then schema, then the
12
- * raw value** — with a host resolver between the last two, applied by
13
- * `useHostFacetLabels` on what this module could not name.
11
+ * 2. **LABELS have one stated order: ANSWER, then schema, then the raw
12
+ * term** — for the group's heading and for every option alike, with a host
13
+ * resolver between the last two for options, applied by
14
+ * `useHostFacetLabels` on what this module could not name. The bottom of
15
+ * that order is not a label and is marked as such: `labelSource: "none"`,
16
+ * a warning in development, and a data attribute on the drawn group.
14
17
  *
15
18
  * The answer leads because it is the only source that always exists and
16
19
  * the only one that has RESOLVED anything: `categoryFeatures` is an
@@ -47,7 +50,29 @@
47
50
  * chipped is therefore decided from the category's own feature defs, by
48
51
  * value TYPE (see {@link FACETABLE_FEATURE_TYPES}), not by what came back.
49
52
  */
50
- import { VOCABULARY_BACKED_TYPES, featureConfig, featureName, featureType, formatFeatureValue, } from "@stapel/attributes-react";
53
+ import { VOCABULARY_BACKED_TYPES, featureConfig, featureType, formatFeatureValue, } from "@stapel/attributes-react";
54
+ /** Slugs already complained about — one warning per slug per page load, not
55
+ * one per render. */
56
+ const warnedSlugs = new Set();
57
+ /**
58
+ * A heading nobody named, said once, in development only.
59
+ *
60
+ * A raw slug in a filter panel is a wiring fault — the category has no
61
+ * feature definition for the slug and the server sent no label — and it is
62
+ * invisible to everyone but the buyer who meets it. The group still renders,
63
+ * because a heading a person cannot read still beats options with no heading
64
+ * at all; `FacetGroup.labelSource` is how a surface marks it up for a test.
65
+ */
66
+ function warnUnnamedGroup(slug) {
67
+ const env = typeof process === "undefined" ? undefined : process.env;
68
+ if (env?.NODE_ENV === "production")
69
+ return;
70
+ if (warnedSlugs.has(slug))
71
+ return;
72
+ warnedSlugs.add(slug);
73
+ console.warn(`[search-react] facet group "${slug}" has no label: the answer sent none ` +
74
+ `and no category feature defines it, so the heading is the raw slug.`);
75
+ }
51
76
  /**
52
77
  * Value types whose values are a BOUNDED OPTION SET — the only kind of
53
78
  * feature a person can be offered as a filter.
@@ -200,8 +225,44 @@ function declaredOptionValues(feature) {
200
225
  * value — never a blank, and never a guess.
201
226
  */
202
227
  function resolveLabel(input, feature, slug, value, labelOptions) {
203
- return (serverLabel(input.facetLabels, slug, value, input.t) ??
204
- facetOptionLabel(feature, value, labelOptions));
228
+ const answer = serverLabel(input.facetLabels, slug, value, input.t);
229
+ if (answer !== undefined)
230
+ return { label: answer, labelSource: "server" };
231
+ const schema = facetOptionLabel(feature, value, labelOptions);
232
+ // `facetOptionLabel` hands back the value unchanged for an option it
233
+ // cannot name, and that identity is the whole test — a formatter that
234
+ // returned the term is a formatter that named nothing.
235
+ return schema === value
236
+ ? { label: value, labelSource: "none" }
237
+ : { label: schema, labelSource: "schema" };
238
+ }
239
+ /**
240
+ * The group's HEADING, in the one order the fleet states: the answer, then
241
+ * the category schema, then the slug under a dev warning.
242
+ *
243
+ * The answer leads because it is the only source that always exists. The
244
+ * schema slot is optional, and at a live classified's cars branch the
245
+ * storefront passed an empty feature list, so every heading in the rail was
246
+ * a raw index slug — the make group was on screen, unlabelled, and the
247
+ * complaint that came back was "I cannot pick a make".
248
+ *
249
+ * The slug is not a fallback anyone may ship: it renders, because a heading
250
+ * beats no heading, and it renders MARKED — `labelSource: "none"`, a warning
251
+ * in development, and a data attribute on the drawn group.
252
+ */
253
+ function resolveGroupLabel(input, feature, slug) {
254
+ const answer = input.facetLabels?.[slug]?.label;
255
+ if (typeof answer === "string" && answer.length > 0) {
256
+ return { label: translate(input.t, answer), labelSource: "server" };
257
+ }
258
+ // `featureName` falls back to the slug itself, so the def has to be asked
259
+ // for a NAME rather than for a name-or-slug: a def with none names nothing.
260
+ const declared = feature?.name;
261
+ if (typeof declared === "string" && declared.length > 0) {
262
+ return { label: translate(input.t, declared), labelSource: "schema" };
263
+ }
264
+ warnUnnamedGroup(slug);
265
+ return { label: slug, labelSource: "none" };
205
266
  }
206
267
  /**
207
268
  * A facet value as a person reads it, through
@@ -350,21 +411,17 @@ export function buildFacetGroups(input) {
350
411
  };
351
412
  return {
352
413
  slug,
353
- label: feature === undefined
354
- ? slug
355
- : translate(input.t, featureName(feature)),
414
+ ...resolveGroupLabel(input, feature, slug),
356
415
  feature,
357
416
  counted,
358
417
  selected,
359
418
  options: values.map((value) => ({
360
419
  value,
361
420
  count: counted ? (counts[value] ?? 0) : null,
362
- // The host's schema first when it actually resolves the value, the
363
- // answer's caption when it does not (or when there is no schema at
364
- // all), the raw value when neither knows. `facetOptionLabel` returns
365
- // the value unchanged for an option it cannot name, which is what
366
- // makes "did it resolve?" answerable without a second lookup.
367
- label: resolveLabel(input, feature, slug, value, labelOptions),
421
+ // The answer's caption first, then the schema's own option table,
422
+ // then the raw value and the source is carried rather than
423
+ // re-derived, so "did it resolve?" needs no second lookup.
424
+ ...resolveLabel(input, feature, slug, value, labelOptions),
368
425
  selected: selected.includes(value),
369
426
  })),
370
427
  };
@@ -1 +1 @@
1
- {"version":3,"file":"facets.js","sourceRoot":"","sources":["../../src/state/facets.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"facets.js","sourceRoot":"","sources":["../../src/state/facets.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Matching a typed prefix against a dictionary value ACROSS ALPHABETS.
3
+ *
4
+ * A vocabulary of car makes holds `Toyota`, `Land Rover`, `Timberland` — Latin
5
+ * words, in a catalogue read by people typing Cyrillic. "toyota" spelled in
6
+ * Cyrillic and `Toyota` are the same word said in two scripts, and a
7
+ * `String.includes` over the caption answers "no" to every one of them. The
8
+ * autocatalog has 418 makes: without this, the search box in a dictionary
9
+ * facet is a box that works only for the half of the buyers whose keyboard
10
+ * matches the catalogue's.
11
+ *
12
+ * ── Two keys per word, and why the second one exists ──────────────────────
13
+ *
14
+ * The first key is a plain transliteration: Cyrillic → Latin through the table
15
+ * below, lowercased, everything but letters and digits dropped. That alone
16
+ * gets the Cyrillic spelling of "toyota" to `toiota` and `Toyota` to `toyota`
17
+ * — still not equal, and this is the general case rather than a bad table.
18
+ * Vowels are exactly where two scripts disagree: `i` against `y`, `e` against
19
+ * `a` in a borrowed word, `timberlend` against `timberland`. A vowel-perfect
20
+ * table does not exist, because the disagreement is in the borrowing, not in
21
+ * the letters.
22
+ *
23
+ * So the second key is the CONSONANT SKELETON: the first key with its vowels
24
+ * removed. `timberlend` and `timberland` are both `tmbrlnd`; `toiota` and
25
+ * `toyota` are both `tt`. Digits stay — a skeleton is about letters people
26
+ * disagree on, and `5` is not one.
27
+ *
28
+ * A candidate matches when either key of any of its WORDS starts with the
29
+ * corresponding key of the needle: a typed "rover" in either script finds
30
+ * `Land Rover`, and typing into the box narrows as you go, which is the whole
31
+ * point of a prefix rule. The skeleton arm is skipped for a needle that has no
32
+ * consonants at all — an empty skeleton is a prefix of everything, and a box
33
+ * that matches all 418 makes after one vowel is a box that has stopped
34
+ * answering.
35
+ *
36
+ * Table-driven and dependency-free on purpose: this is 40 pairs of characters,
37
+ * and a transliteration library is a page-weight decision made for a lookup
38
+ * table.
39
+ */
40
+ /**
41
+ * One word, transliterated and folded to `[a-z0-9]`.
42
+ *
43
+ * `NFKD` + combining-mark strip first, so `Škoda` and `Skoda` are one word
44
+ * before anything else looks at them.
45
+ */
46
+ export declare function translitKey(text: string): string;
47
+ /** {@link translitKey} without its vowels — the key two spellings of one
48
+ * borrowed name agree on. */
49
+ export declare function consonantKey(text: string): string;
50
+ /**
51
+ * Does `candidate` answer the typed `needle`?
52
+ *
53
+ * Prefix, not substring: a dictionary of makes searched by substring puts
54
+ * `Great Wall` under `all`. Every word of the candidate is a starting point,
55
+ * and both keys are tried — see the module note.
56
+ */
57
+ export declare function translitPrefixMatch(needle: string, candidate: string): boolean;
58
+ //# sourceMappingURL=translit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"translit.d.ts","sourceRoot":"","sources":["../../src/state/translit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAuBH;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAYhD;AAED;6BAC6B;AAC7B,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAIjD;AAQD;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAU9E"}
@@ -0,0 +1,115 @@
1
+ /**
2
+ * Matching a typed prefix against a dictionary value ACROSS ALPHABETS.
3
+ *
4
+ * A vocabulary of car makes holds `Toyota`, `Land Rover`, `Timberland` — Latin
5
+ * words, in a catalogue read by people typing Cyrillic. "toyota" spelled in
6
+ * Cyrillic and `Toyota` are the same word said in two scripts, and a
7
+ * `String.includes` over the caption answers "no" to every one of them. The
8
+ * autocatalog has 418 makes: without this, the search box in a dictionary
9
+ * facet is a box that works only for the half of the buyers whose keyboard
10
+ * matches the catalogue's.
11
+ *
12
+ * ── Two keys per word, and why the second one exists ──────────────────────
13
+ *
14
+ * The first key is a plain transliteration: Cyrillic → Latin through the table
15
+ * below, lowercased, everything but letters and digits dropped. That alone
16
+ * gets the Cyrillic spelling of "toyota" to `toiota` and `Toyota` to `toyota`
17
+ * — still not equal, and this is the general case rather than a bad table.
18
+ * Vowels are exactly where two scripts disagree: `i` against `y`, `e` against
19
+ * `a` in a borrowed word, `timberlend` against `timberland`. A vowel-perfect
20
+ * table does not exist, because the disagreement is in the borrowing, not in
21
+ * the letters.
22
+ *
23
+ * So the second key is the CONSONANT SKELETON: the first key with its vowels
24
+ * removed. `timberlend` and `timberland` are both `tmbrlnd`; `toiota` and
25
+ * `toyota` are both `tt`. Digits stay — a skeleton is about letters people
26
+ * disagree on, and `5` is not one.
27
+ *
28
+ * A candidate matches when either key of any of its WORDS starts with the
29
+ * corresponding key of the needle: a typed "rover" in either script finds
30
+ * `Land Rover`, and typing into the box narrows as you go, which is the whole
31
+ * point of a prefix rule. The skeleton arm is skipped for a needle that has no
32
+ * consonants at all — an empty skeleton is a prefix of everything, and a box
33
+ * that matches all 418 makes after one vowel is a box that has stopped
34
+ * answering.
35
+ *
36
+ * Table-driven and dependency-free on purpose: this is 40 pairs of characters,
37
+ * and a transliteration library is a page-weight decision made for a lookup
38
+ * table.
39
+ */
40
+ /**
41
+ * Cyrillic → Latin, chosen for how the two scripts spell the SAME borrowed
42
+ * name rather than for a standard's fidelity: `kha` is `h` (Honda, not
43
+ * Khonda), `tse` is `c`, the two signs are nothing. Any letter absent here is
44
+ * kept as it is, so a Latin caption passes through untouched. Keys are
45
+ * quoted — the fleet's source is English, and a Cyrillic identifier is not.
46
+ */
47
+ const CYRILLIC_TO_LATIN = {
48
+ "а": "a", "б": "b", "в": "v", "г": "g", "д": "d", "е": "e", "ё": "e",
49
+ "ж": "zh", "з": "z", "и": "i", "й": "i", "к": "k", "л": "l", "м": "m",
50
+ "н": "n", "о": "o", "п": "p", "р": "r", "с": "s", "т": "t", "у": "u",
51
+ "ф": "f", "х": "h", "ц": "c", "ч": "ch", "ш": "sh", "щ": "sh", "ъ": "",
52
+ "ы": "y", "ь": "", "э": "e", "ю": "u", "я": "a",
53
+ // Ukrainian/Belarusian letters a shared vocabulary can carry.
54
+ "і": "i", "ї": "i", "є": "e", "ґ": "g", "ў": "u",
55
+ };
56
+ /** Vowels of the transliterated form — `y` included, because it stands for a
57
+ * Cyrillic semi-vowel as often as it stands for a consonant. */
58
+ const VOWELS = new Set(["a", "e", "i", "o", "u", "y"]);
59
+ /**
60
+ * One word, transliterated and folded to `[a-z0-9]`.
61
+ *
62
+ * `NFKD` + combining-mark strip first, so `Škoda` and `Skoda` are one word
63
+ * before anything else looks at them.
64
+ */
65
+ export function translitKey(text) {
66
+ const folded = text
67
+ .normalize("NFKD")
68
+ .replace(/[\u0300-\u036f]/g, "")
69
+ .toLowerCase();
70
+ let out = "";
71
+ for (const char of folded) {
72
+ const mapped = CYRILLIC_TO_LATIN[char];
73
+ if (mapped !== undefined)
74
+ out += mapped;
75
+ else if (/[a-z0-9]/.test(char))
76
+ out += char;
77
+ }
78
+ return out;
79
+ }
80
+ /** {@link translitKey} without its vowels — the key two spellings of one
81
+ * borrowed name agree on. */
82
+ export function consonantKey(text) {
83
+ let out = "";
84
+ for (const char of translitKey(text))
85
+ if (!VOWELS.has(char))
86
+ out += char;
87
+ return out;
88
+ }
89
+ /** The words of a caption, split on everything that is not a letter or a
90
+ * digit — so `Land Rover` is reachable by "rover" in either script. */
91
+ function words(text) {
92
+ return text.split(/[^\p{L}\p{N}]+/u).filter((word) => word.length > 0);
93
+ }
94
+ /**
95
+ * Does `candidate` answer the typed `needle`?
96
+ *
97
+ * Prefix, not substring: a dictionary of makes searched by substring puts
98
+ * `Great Wall` under `all`. Every word of the candidate is a starting point,
99
+ * and both keys are tried — see the module note.
100
+ */
101
+ export function translitPrefixMatch(needle, candidate) {
102
+ const key = translitKey(needle);
103
+ if (key.length === 0)
104
+ return true;
105
+ const skeleton = consonantKey(needle);
106
+ for (const word of [candidate, ...words(candidate)]) {
107
+ const wordKey = translitKey(word);
108
+ if (wordKey.startsWith(key))
109
+ return true;
110
+ if (skeleton.length > 0 && consonantKey(word).startsWith(skeleton))
111
+ return true;
112
+ }
113
+ return false;
114
+ }
115
+ //# sourceMappingURL=translit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"translit.js","sourceRoot":"","sources":["../../src/state/translit.ts"],"names":[],"mappings":"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"}
package/llms.txt CHANGED
@@ -1,4 +1,4 @@
1
- # @stapel/search-react 0.21.0
1
+ # @stapel/search-react 0.22.0
2
2
 
3
3
  Headless React flow pair for stapel-search (contract >=0.14 <0.15) — business + state, zero visual opinion.
4
4
  Built on @stapel/core: typed client + StapelApiError envelope, auth token refresh,
@@ -85,6 +85,8 @@ const { tracked } = useTracked();
85
85
  - search.location-summary → <LocationSummaryLine> [everywhere|placed|narrowed|long-place|wide] demo/LocationSummaryLine.demo.tsx
86
86
  - search.page → <SearchPage> [desktop|phone|unreadable-link] demo/SearchPage.demo.tsx
87
87
  - search.page-size-select → <PageSizeSelect> [ladder|off-ladder] demo/PageSizeSelect.demo.tsx
88
+ - search.partition-chips → <PartitionChips> [parent|child] demo/PartitionChips.demo.tsx
89
+ - search.popular-values → <PopularValues> [desktop|narrow-column] demo/PopularValues.demo.tsx
88
90
  - search.range-filter-row → <RangeFilterRow> [untouched|applied] demo/RangeFilterRow.demo.tsx
89
91
  - search.ranking-pane → <RankingDisclosurePane> [desktop|phone] demo/RankingDisclosurePane.demo.tsx
90
92
  - search.result-card → <SearchResultCard> [gallery|promoted|unresolved|plain] demo/SearchResultCard.demo.tsx
package/manifest.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$generated": "by scripts/gen-manifest.mjs — do not edit; drift-gated (pnpm gen:manifest:check)",
3
3
  "package": "@stapel/search-react",
4
- "version": "0.21.0",
4
+ "version": "0.22.0",
5
5
  "backend": {
6
6
  "module": "stapel-search",
7
7
  "contract": ">=0.14 <0.15"
@@ -573,6 +573,31 @@
573
573
  ],
574
574
  "source": "demo/PageSizeSelect.demo.tsx"
575
575
  },
576
+ {
577
+ "id": "search.partition-chips",
578
+ "title": "Partition chips",
579
+ "description": "A single-select row of the parent plus its children, where the first chip is the parent itself rather than a way of clearing the others — searching the parent IS the union of its children. It is a real radiogroup with roving tabindex: Tab reaches the row once and lands on the chosen chip, the arrow keys move along it and choose as they go. A row of aria-pressed toggles would announce the opposite — independent switches, with no reason why pressing one released another.",
580
+ "component": "PartitionChips",
581
+ "variants": [
582
+ "parent",
583
+ "child"
584
+ ],
585
+ "source": "demo/PartitionChips.demo.tsx"
586
+ },
587
+ {
588
+ "id": "search.popular-values",
589
+ "title": "Popular values",
590
+ "description": "The head of one facet as a multi-column list of value + count, each line applying that filter. The numbers are the answer's own drill-down counts — the same ones the checkbox rows carry — so a value cannot read 802 here and 93 in the panel. Values with no evidence behind them are dropped rather than printed with a blank where the number belongs: the block IS the numbers. Whether a phone has room for it is the page's decision and arrives as the `hidden` prop, never as a media query inside.",
591
+ "component": "PopularValues",
592
+ "tokens": [
593
+ "text-muted"
594
+ ],
595
+ "variants": [
596
+ "desktop",
597
+ "narrow-column"
598
+ ],
599
+ "source": "demo/PopularValues.demo.tsx"
600
+ },
576
601
  {
577
602
  "id": "search.range-filter-row",
578
603
  "title": "Numeric range filter",
@@ -759,6 +784,9 @@
759
784
  "search.facets.approximate",
760
785
  "search.facets.clear",
761
786
  "search.facets.clear_all",
787
+ "search.facets.dictionary_chosen",
788
+ "search.facets.dictionary_empty",
789
+ "search.facets.dictionary_search",
762
790
  "search.facets.drill_down_hint",
763
791
  "search.facets.empty",
764
792
  "search.facets.load_failed",
@@ -767,6 +795,7 @@
767
795
  "search.facets.match_count.one",
768
796
  "search.facets.match_count.other",
769
797
  "search.facets.not_counted",
798
+ "search.facets.popular_all",
770
799
  "search.facets.range_apply",
771
800
  "search.facets.range_clear",
772
801
  "search.facets.range_from",
@@ -815,6 +844,8 @@
815
844
  "search.nav.ranking",
816
845
  "search.nav.ranking.short",
817
846
  "search.nav.results",
847
+ "search.partition.all",
848
+ "search.partition.label",
818
849
  "search.range.price",
819
850
  "search.ranking.applies_to",
820
851
  "search.ranking.empty",
@@ -909,6 +940,7 @@
909
940
  "buildFacetGroups",
910
941
  "buildRangeGroups",
911
942
  "clearFilters",
943
+ "consonantKey",
912
944
  "coreRangeLabelKey",
913
945
  "countIsEstimate",
914
946
  "countKind",
@@ -939,6 +971,8 @@
939
971
  "setRangeValue",
940
972
  "suggestTerms",
941
973
  "toggleFilterValue",
974
+ "translitKey",
975
+ "translitPrefixMatch",
942
976
  "useAppliedSort",
943
977
  "useFacetPanel",
944
978
  "useHostFacetLabels",
@@ -961,6 +995,9 @@
961
995
  "FacetGroup",
962
996
  "FacetLabelRequest",
963
997
  "FacetLabelResolver",
998
+ "FacetLabelSource",
999
+ "FacetLabels",
1000
+ "FacetLabelsMap",
964
1001
  "FacetMeta",
965
1002
  "FacetOption",
966
1003
  "FacetPanelBag",
package/nav-manifest.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "package": "@stapel/search-react",
3
- "version": "0.21.0",
3
+ "version": "0.22.0",
4
4
  "entries": [
5
5
  {
6
6
  "id": "search.results",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stapel/search-react",
3
- "version": "0.21.0",
3
+ "version": "0.22.0",
4
4
  "description": "Headless React pair for stapel-search: a typed query client, TanStack Query hooks, and a URL-first state codec that makes a search shareable by construction (filters, ranges, geo, sort and the keyset cursor all live in the query string). Drill-down facets rendered with their remaining counts and with the server's own honesty flags — approximate, skipped, degraded — never swallowed; keyset pagination with the window refusal named; DSA Art. 26 `promoted` marking carried into every card slot and the P2B Art. 5 ranking disclosure exposed as data. Zero visual opinion in the main entry; an opt-in /default subpath ships the antd skin, and /router binds the codec to react-router's useSearchParams.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -52,14 +52,14 @@
52
52
  ],
53
53
  "size-limit": [
54
54
  {
55
- "name": "index — the headless pair (client + hooks + URL codec + facet model incl. the facetability rule and the host label seam): no antd, no react-router",
55
+ "name": "index — the headless pair (client + hooks + URL codec + facet model incl. the facetability rule, the label-source order and the across-alphabets prefix matcher): no antd, no react-router",
56
56
  "path": "dist/index.js",
57
- "limit": "11.5 KB"
57
+ "limit": "12 KB"
58
58
  },
59
59
  {
60
- "name": "default — the antd skin (query box + a typeahead that offers CATEGORY destinations with their live counts, filters incl. ranges/geo/category slots + the phone chip row with its leading category chip and the location summary row + the rail's evidence-ranked disclosure groups, panel search and sticky count/clear footer, results incl. the view switch, the card photo GALLERY as a SkinCarousel strip, the empty state's derived exits, ranking) must stay out of the main bundle",
60
+ "name": "default — the antd skin (query box + a typeahead that offers CATEGORY destinations with their live counts, filters incl. ranges/geo/category slots + the phone chip row with its leading category chip and the location summary row + the rail's evidence-ranked disclosure groups, panel search and sticky count/clear footer, results incl. the view switch, the card photo GALLERY as a SkinCarousel strip, the empty state's derived exits, ranking, the dictionary control for a vocabulary facet, the popular-values block and the partition chip row) must stay out of the main bundle",
61
61
  "path": "dist/default/index.js",
62
- "limit": "22.5 KB"
62
+ "limit": "24.5 KB"
63
63
  },
64
64
  {
65
65
  "name": "router — the react-router binding is opt-in; the main entry must never pull a router",
@@ -69,7 +69,7 @@
69
69
  {
70
70
  "name": "i18n/ru — the Russian bundle is opt-in, not carried by the main entry",
71
71
  "path": "dist/i18n/ru.js",
72
- "limit": "4.5 KB"
72
+ "limit": "4.75 KB"
73
73
  },
74
74
  {
75
75
  "name": "i18n/es — the Spanish bundle is opt-in, not carried by the main entry",
@@ -115,11 +115,11 @@
115
115
  "size-limit": "^11.2.0",
116
116
  "typescript": "^5.8.3",
117
117
  "vitest": "^3.2.4",
118
- "@stapel/attributes-react": "^0.14.1",
119
118
  "@stapel/core": "^0.24.0",
120
119
  "@stapel/image": "^0.4.2",
121
120
  "@stapel/showcase": "^0.3.0",
122
121
  "@stapel/tokens": "^0.7.0",
122
+ "@stapel/attributes-react": "^0.14.1",
123
123
  "@stapel/tokens-antd": "^0.16.1"
124
124
  },
125
125
  "engines": {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$generated": "by scripts/gen-events.mjs — do not edit; drift-gated (pnpm gen:events:check)",
3
3
  "package": "@stapel/search-react",
4
- "version": "0.21.0",
4
+ "version": "0.22.0",
5
5
  "defined": [],
6
6
  "flows": []
7
7
  }
package/src/api/types.ts CHANGED
@@ -13,10 +13,36 @@ import type { components } from "./generated/schema.js";
13
13
  /** The generated schema table — the one source of truth for wire shapes. */
14
14
  export type Schemas = components["schemas"];
15
15
 
16
- /** `GET /query` 200 — the whole envelope. Corrected in one place: see
17
- * {@link FacetMeta}. */
18
- export type SearchResponse = Omit<Schemas["SearchResponse"], "facet_meta"> & {
16
+ /**
17
+ * One slug's captions: the GROUP's own name, and the words for its values.
18
+ *
19
+ * `label` is the group heading the server resolved from the category's
20
+ * feature definition, in the request's own language. It is the only source
21
+ * that always exists — `categoryFeatures` is an optional slot a live
22
+ * classified board never filled, and without it every heading in the panel
23
+ * was the raw index slug. `null` is the server saying it has no name for the
24
+ * slug either; ABSENT is a server too old to send one, and both read the same
25
+ * way here (fall through to the schema).
26
+ *
27
+ * WHAT THE GENERATOR LOST: the field is newer than this pair's pinned
28
+ * `schema.json`, so it is declared here as optional-and-nullable rather than
29
+ * regenerated into a shape a deployed older server does not send.
30
+ */
31
+ export type FacetLabels = Schemas["FacetLabels"] & {
32
+ readonly label?: string | null;
33
+ };
34
+
35
+ /** `facet_labels` as a whole: `{slug: {label, translatable, values}}`. */
36
+ export type FacetLabelsMap = Readonly<Record<string, FacetLabels>>;
37
+
38
+ /** `GET /query` 200 — the whole envelope. Corrected in two places: see
39
+ * {@link FacetMeta} and {@link FacetLabels}. */
40
+ export type SearchResponse = Omit<
41
+ Schemas["SearchResponse"],
42
+ "facet_meta" | "facet_labels"
43
+ > & {
19
44
  readonly facet_meta: FacetMeta;
45
+ readonly facet_labels: FacetLabelsMap;
20
46
  };
21
47
 
22
48
  /** One result row. `promoted` is present on EVERY item under EVERY sort — a