@stapel/search-react 0.3.1 → 0.4.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 (57) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/MODULE.md +43 -4
  3. package/dist/api/generated/schema.d.ts +5 -1
  4. package/dist/api/generated/schema.d.ts.map +1 -1
  5. package/dist/default/DegradationNotice.d.ts +27 -0
  6. package/dist/default/DegradationNotice.d.ts.map +1 -1
  7. package/dist/default/DegradationNotice.js +17 -6
  8. package/dist/default/DegradationNotice.js.map +1 -1
  9. package/dist/default/SearchPage.d.ts +4 -0
  10. package/dist/default/SearchPage.d.ts.map +1 -1
  11. package/dist/default/SearchPage.js +4 -2
  12. package/dist/default/SearchPage.js.map +1 -1
  13. package/dist/default/SearchResultsPane.d.ts +12 -0
  14. package/dist/default/SearchResultsPane.d.ts.map +1 -1
  15. package/dist/default/SearchResultsPane.js +8 -5
  16. package/dist/default/SearchResultsPane.js.map +1 -1
  17. package/dist/default/index.d.ts +1 -1
  18. package/dist/default/index.d.ts.map +1 -1
  19. package/dist/default/index.js.map +1 -1
  20. package/dist/headless/SearchResults.d.ts +20 -3
  21. package/dist/headless/SearchResults.d.ts.map +1 -1
  22. package/dist/headless/SearchResults.js +3 -1
  23. package/dist/headless/SearchResults.js.map +1 -1
  24. package/dist/i18n/es.d.ts.map +1 -1
  25. package/dist/i18n/es.js +2 -0
  26. package/dist/i18n/es.js.map +1 -1
  27. package/dist/i18n/keys.d.ts +11 -2
  28. package/dist/i18n/keys.d.ts.map +1 -1
  29. package/dist/i18n/keys.js +14 -2
  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 +4 -0
  33. package/dist/i18n/ru.js.map +1 -1
  34. package/dist/index.d.ts +2 -1
  35. package/dist/index.d.ts.map +1 -1
  36. package/dist/index.js +1 -1
  37. package/dist/index.js.map +1 -1
  38. package/dist/state/degradations.d.ts +41 -0
  39. package/dist/state/degradations.d.ts.map +1 -1
  40. package/dist/state/degradations.js +41 -0
  41. package/dist/state/degradations.js.map +1 -1
  42. package/llms.txt +2 -2
  43. package/manifest.json +8 -2
  44. package/nav-manifest.json +1 -1
  45. package/package.json +3 -3
  46. package/src/analytics/generated/events.json +1 -1
  47. package/src/api/generated/schema.ts +5 -1
  48. package/src/default/DegradationNotice.tsx +61 -13
  49. package/src/default/SearchPage.tsx +8 -0
  50. package/src/default/SearchResultsPane.tsx +27 -6
  51. package/src/default/index.ts +4 -1
  52. package/src/headless/SearchResults.tsx +32 -4
  53. package/src/i18n/es.ts +2 -0
  54. package/src/i18n/keys.ts +14 -2
  55. package/src/i18n/ru.ts +4 -0
  56. package/src/index.ts +8 -1
  57. package/src/state/degradations.ts +60 -0
@@ -1 +1 @@
1
- {"version":3,"file":"keys.js","sourceRoot":"","sources":["../../src/i18n/keys.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"keys.js","sourceRoot":"","sources":["../../src/i18n/keys.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"ru.d.ts","sourceRoot":"","sources":["../../src/i18n/ru.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAG/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAEnE;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,kBAAkB,EAAE,cAoGhC,CAAC;AAEF;yDACyD;AACzD,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI,CAE7D"}
1
+ {"version":3,"file":"ru.d.ts","sourceRoot":"","sources":["../../src/i18n/ru.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAG/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAEnE;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,kBAAkB,EAAE,cAwGhC,CAAC;AAEF;yDACyD;AACzD,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI,CAE7D"}
package/dist/i18n/ru.js CHANGED
@@ -36,6 +36,10 @@ export const searchI18nBundleRu = {
36
36
  "search.results.count_approximate.few": "Примерно {count} объявления",
37
37
  "search.results.count_approximate.many": "Примерно {count} объявлений",
38
38
  "search.results.count_approximate.other": "Примерно {count} объявления",
39
+ "search.results.count_at_least.one": "{count}+ объявление",
40
+ "search.results.count_at_least.few": "{count}+ объявления",
41
+ "search.results.count_at_least.many": "{count}+ объявлений",
42
+ "search.results.count_at_least.other": "{count}+ объявления",
39
43
  "search.results.count_exact.one": "{count} объявление",
40
44
  "search.results.count_exact.few": "{count} объявления",
41
45
  "search.results.count_exact.many": "{count} объявлений",
@@ -1 +1 @@
1
- {"version":3,"file":"ru.js","sourceRoot":"","sources":["../../src/i18n/ru.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ru.js","sourceRoot":"","sources":["../../src/i18n/ru.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -46,7 +46,8 @@ export { SEARCH_SORTS } from "./api/types.js";
46
46
  export type { FacetMeta, FacetSelection, RankingResponse, Scorer, SearchDegradation, SearchDegradationKind, SearchGeo, SearchGeoBox, SearchGeoCenter, SearchItem, SearchQueryState, SearchRange, SearchResponse, SuggestParams, SuggestResponse, } from "./api/types.js";
47
47
  export { FILTER_PREFIX, RANGE_PREFIX, SEARCH_PARAM, activeFilterCount, clearFilters, ownsParam, parseSearchState, patchSearchState, setFilterValues, setRangeValue, toggleFilterValue, writeSearchState, } from "./state/urlState.js";
48
48
  export type { ParseSearchStateOptions, ParsedSearchState, SearchStateIssue, SearchStateIssueCode, SearchStatePatch, } from "./state/urlState.js";
49
- export { countIsEstimate, degradationMessageKey, parseDegradations } from "./state/degradations.js";
49
+ export { countIsEstimate, countKind, degradationMessageKey, isCountNuanceOnly, parseDegradations, } from "./state/degradations.js";
50
+ export type { SearchCountKind } from "./state/degradations.js";
50
51
  export { buildFacetGroups, facetOptionLabel } from "./state/facets.js";
51
52
  export type { BuildFacetGroupsInput, FacetGroup, FacetOption, } from "./state/facets.js";
52
53
  export { createSearchRuntime } from "./model/runtime.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -44,7 +44,7 @@ export { createSearchApi, searchQueryParams } from "./api/searchApi.js";
44
44
  export { SEARCH_SORTS } from "./api/types.js";
45
45
  // ── state (pure: no React, no router) ────────────────────────────────────────
46
46
  export { FILTER_PREFIX, RANGE_PREFIX, SEARCH_PARAM, activeFilterCount, clearFilters, ownsParam, parseSearchState, patchSearchState, setFilterValues, setRangeValue, toggleFilterValue, writeSearchState, } from "./state/urlState.js";
47
- export { countIsEstimate, degradationMessageKey, parseDegradations } from "./state/degradations.js";
47
+ export { countIsEstimate, countKind, degradationMessageKey, isCountNuanceOnly, parseDegradations, } from "./state/degradations.js";
48
48
  export { buildFacetGroups, facetOptionLabel } from "./state/facets.js";
49
49
  // ── model (runtime wiring, query keys, context, hooks) ───────────────────────
50
50
  export { createSearchRuntime } from "./model/runtime.js";
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAEH,gFAAgF;AAChF,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAGxE,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAmB9C,gFAAgF;AAChF,OAAO,EACL,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,iBAAiB,EACjB,YAAY,EACZ,SAAS,EACT,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,aAAa,EACb,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,qBAAqB,CAAC;AAS7B,OAAO,EAAE,eAAe,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAEpG,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAOvE,gFAAgF;AAChF,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAKzD,OAAO,EACL,oBAAoB,EACpB,gBAAgB,EAChB,YAAY,EACZ,kBAAkB,GACnB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAGvD,OAAO,EAAE,oBAAoB,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAE1E,gFAAgF;AAChF,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AAMxF,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAE5D,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAEtD,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AAGpE,gFAAgF;AAChF,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE/C,gFAAgF;AAChF,OAAO,EACL,gBAAgB,EAChB,uBAAuB,EACvB,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,gBAAgB,CAAC;AAGxB,gFAAgF;AAChF,OAAO,EACL,aAAa,EACb,kBAAkB,EAClB,0BAA0B,EAC1B,sBAAsB,EACtB,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAEH,gFAAgF;AAChF,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAGxE,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAmB9C,gFAAgF;AAChF,OAAO,EACL,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,iBAAiB,EACjB,YAAY,EACZ,SAAS,EACT,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,aAAa,EACb,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,qBAAqB,CAAC;AAS7B,OAAO,EACL,eAAe,EACf,SAAS,EACT,qBAAqB,EACrB,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,yBAAyB,CAAC;AAGjC,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAOvE,gFAAgF;AAChF,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAKzD,OAAO,EACL,oBAAoB,EACpB,gBAAgB,EAChB,YAAY,EACZ,kBAAkB,GACnB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAGvD,OAAO,EAAE,oBAAoB,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAE1E,gFAAgF;AAChF,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AAMxF,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAE5D,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAEtD,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AAGpE,gFAAgF;AAChF,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE/C,gFAAgF;AAChF,OAAO,EACL,gBAAgB,EAChB,uBAAuB,EACvB,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,gBAAgB,CAAC;AAGxB,gFAAgF;AAChF,OAAO,EACL,aAAa,EACb,kBAAkB,EAClB,0BAA0B,EAC1B,sBAAsB,EACtB,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,qBAAqB,CAAC"}
@@ -25,6 +25,47 @@ export declare function parseDegradations(degraded: readonly string[] | undefine
25
25
  * the envelope's own `exact_total: false`, and the `"exact_total"`
26
26
  * degradation. They agree in practice; treating either as decisive is what
27
27
  * keeps "≈1 200" from ever being rendered as "1 200".
28
+ *
29
+ * @deprecated Since stapel-search 0.2.0 the envelope answers this directly
30
+ * with `count_is_lower_bound`, and "not exact" now means a FLOOR rather than
31
+ * a fuzzy number. Use {@link countKind}, which reads the wire field and also
32
+ * handles `count: null`.
28
33
  */
29
34
  export declare function countIsEstimate(exactTotal: boolean, degradations: readonly SearchDegradation[]): boolean;
35
+ /**
36
+ * How a count may be spoken: as a number, as a floor, or not at all.
37
+ *
38
+ * The three states stapel-search 0.2.0 made explicit, because the version
39
+ * before it had only two and used `0` for both "none match" and "we do not
40
+ * know" — which is how a storefront came to print "About 0 listings" over
41
+ * four visible cards.
42
+ */
43
+ export type SearchCountKind = "exact" | "at_least" | "unknown";
44
+ /**
45
+ * Read the envelope's three count fields as one decision.
46
+ *
47
+ * `null` is UNKNOWN and renders as no count line — never as `0`, and never
48
+ * as "about 0". Anything the server declines to call exact is rendered as a
49
+ * floor ("N+"), including the defensive case of an `exact_total: false` from
50
+ * a server that predates `count_is_lower_bound`: claiming "at least N" over
51
+ * a page that shows N rows is the one reading that cannot be contradicted by
52
+ * what the reader can see.
53
+ */
54
+ export declare function countKind(count: number | null | undefined, isLowerBound: boolean | undefined, exactTotal: boolean, degradations: readonly SearchDegradation[]): SearchCountKind;
55
+ /**
56
+ * Is `exact_total` the ONLY thing the engine could not do?
57
+ *
58
+ * It is a count NUANCE, not a failed search: the answer is complete, the
59
+ * rows are the right rows, and the single consequence — that the total is a
60
+ * floor — is already spoken by the count itself as "N+". Raising a warning
61
+ * banner over it teaches a reader that a perfectly good result page is
62
+ * broken, and a banner that cries wolf on every landing page is a banner
63
+ * nobody reads on the day `category_rollup` shows up in it.
64
+ *
65
+ * Every other degradation changes what the page MEANS ("typos were not
66
+ * corrected", "subcategories may be missing", "counts are approximate") and
67
+ * still renders. So does `exact_total` when it arrives BESIDE one of them —
68
+ * the list is then a description of a genuinely degraded answer.
69
+ */
70
+ export declare function isCountNuanceOnly(degradations: readonly SearchDegradation[]): boolean;
30
71
  //# sourceMappingURL=degradations.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"degradations.d.ts","sourceRoot":"","sources":["../../src/state/degradations.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,KAAK,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAYhF,+CAA+C;AAC/C,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,qBAAqB,GAAG,MAAM,CAEzE;AAED,0DAA0D;AAC1D,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,GACtC,SAAS,iBAAiB,EAAE,CAwB9B;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAC7B,UAAU,EAAE,OAAO,EACnB,YAAY,EAAE,SAAS,iBAAiB,EAAE,GACzC,OAAO,CAET"}
1
+ {"version":3,"file":"degradations.d.ts","sourceRoot":"","sources":["../../src/state/degradations.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,KAAK,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAYhF,+CAA+C;AAC/C,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,qBAAqB,GAAG,MAAM,CAEzE;AAED,0DAA0D;AAC1D,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,GACtC,SAAS,iBAAiB,EAAE,CAwB9B;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,eAAe,CAC7B,UAAU,EAAE,OAAO,EACnB,YAAY,EAAE,SAAS,iBAAiB,EAAE,GACzC,OAAO,CAET;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,eAAe,GAAG,OAAO,GAAG,UAAU,GAAG,SAAS,CAAC;AAE/D;;;;;;;;;GASG;AACH,wBAAgB,SAAS,CACvB,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAChC,YAAY,EAAE,OAAO,GAAG,SAAS,EACjC,UAAU,EAAE,OAAO,EACnB,YAAY,EAAE,SAAS,iBAAiB,EAAE,GACzC,eAAe,CAIjB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,iBAAiB,CAC/B,YAAY,EAAE,SAAS,iBAAiB,EAAE,GACzC,OAAO,CAKT"}
@@ -45,8 +45,49 @@ export function parseDegradations(degraded) {
45
45
  * the envelope's own `exact_total: false`, and the `"exact_total"`
46
46
  * degradation. They agree in practice; treating either as decisive is what
47
47
  * keeps "≈1 200" from ever being rendered as "1 200".
48
+ *
49
+ * @deprecated Since stapel-search 0.2.0 the envelope answers this directly
50
+ * with `count_is_lower_bound`, and "not exact" now means a FLOOR rather than
51
+ * a fuzzy number. Use {@link countKind}, which reads the wire field and also
52
+ * handles `count: null`.
48
53
  */
49
54
  export function countIsEstimate(exactTotal, degradations) {
50
55
  return !exactTotal || degradations.some((d) => d.kind === "exact_total");
51
56
  }
57
+ /**
58
+ * Read the envelope's three count fields as one decision.
59
+ *
60
+ * `null` is UNKNOWN and renders as no count line — never as `0`, and never
61
+ * as "about 0". Anything the server declines to call exact is rendered as a
62
+ * floor ("N+"), including the defensive case of an `exact_total: false` from
63
+ * a server that predates `count_is_lower_bound`: claiming "at least N" over
64
+ * a page that shows N rows is the one reading that cannot be contradicted by
65
+ * what the reader can see.
66
+ */
67
+ export function countKind(count, isLowerBound, exactTotal, degradations) {
68
+ if (count === null || count === undefined)
69
+ return "unknown";
70
+ if (isLowerBound === true)
71
+ return "at_least";
72
+ return countIsEstimate(exactTotal, degradations) ? "at_least" : "exact";
73
+ }
74
+ /**
75
+ * Is `exact_total` the ONLY thing the engine could not do?
76
+ *
77
+ * It is a count NUANCE, not a failed search: the answer is complete, the
78
+ * rows are the right rows, and the single consequence — that the total is a
79
+ * floor — is already spoken by the count itself as "N+". Raising a warning
80
+ * banner over it teaches a reader that a perfectly good result page is
81
+ * broken, and a banner that cries wolf on every landing page is a banner
82
+ * nobody reads on the day `category_rollup` shows up in it.
83
+ *
84
+ * Every other degradation changes what the page MEANS ("typos were not
85
+ * corrected", "subcategories may be missing", "counts are approximate") and
86
+ * still renders. So does `exact_total` when it arrives BESIDE one of them —
87
+ * the list is then a description of a genuinely degraded answer.
88
+ */
89
+ export function isCountNuanceOnly(degradations) {
90
+ return (degradations.length > 0 &&
91
+ degradations.every((degradation) => degradation.kind === "exact_total"));
92
+ }
52
93
  //# sourceMappingURL=degradations.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"degradations.js","sourceRoot":"","sources":["../../src/state/degradations.ts"],"names":[],"mappings":"AAiBA,MAAM,aAAa,GAAG,SAAS,CAAC;AAEhC,MAAM,KAAK,GAAoD;IAC7D,cAAc,EAAE,gBAAgB;IAChC,eAAe,EAAE,iBAAiB;IAClC,WAAW,EAAE,aAAa;IAC1B,kBAAkB,EAAE,oBAAoB;IACxC,eAAe,EAAE,iBAAiB;CACnC,CAAC;AAEF,+CAA+C;AAC/C,MAAM,UAAU,qBAAqB,CAAC,IAA2B;IAC/D,OAAO,mBAAmB,IAAI,EAAE,CAAC;AACnC,CAAC;AAED,0DAA0D;AAC1D,MAAM,UAAU,iBAAiB,CAC/B,QAAuC;IAEvC,IAAI,QAAQ,KAAK,SAAS;QAAE,OAAO,EAAE,CAAC;IACtC,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,GAAG,GAAwB,EAAE,CAAC;IACpC,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;QAC3B,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,SAAS;QAC5B,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACd,IAAI,GAAG,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;YAClC,GAAG,CAAC,IAAI,CAAC;gBACP,IAAI,EAAE,QAAQ;gBACd,GAAG;gBACH,MAAM,EAAE,GAAG,CAAC,KAAK,CAAC,aAAa,CAAC,MAAM,CAAC;gBACvC,UAAU,EAAE,qBAAqB,CAAC,QAAQ,CAAC;aAC5C,CAAC,CAAC;YACH,SAAS;QACX,CAAC;QACD,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;QACxB,GAAG,CAAC,IAAI,CAAC;YACP,IAAI,EAAE,IAAI,IAAI,SAAS;YACvB,GAAG;YACH,UAAU,EAAE,qBAAqB,CAAC,IAAI,IAAI,SAAS,CAAC;SACrD,CAAC,CAAC;IACL,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,eAAe,CAC7B,UAAmB,EACnB,YAA0C;IAE1C,OAAO,CAAC,UAAU,IAAI,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,aAAa,CAAC,CAAC;AAC3E,CAAC"}
1
+ {"version":3,"file":"degradations.js","sourceRoot":"","sources":["../../src/state/degradations.ts"],"names":[],"mappings":"AAiBA,MAAM,aAAa,GAAG,SAAS,CAAC;AAEhC,MAAM,KAAK,GAAoD;IAC7D,cAAc,EAAE,gBAAgB;IAChC,eAAe,EAAE,iBAAiB;IAClC,WAAW,EAAE,aAAa;IAC1B,kBAAkB,EAAE,oBAAoB;IACxC,eAAe,EAAE,iBAAiB;CACnC,CAAC;AAEF,+CAA+C;AAC/C,MAAM,UAAU,qBAAqB,CAAC,IAA2B;IAC/D,OAAO,mBAAmB,IAAI,EAAE,CAAC;AACnC,CAAC;AAED,0DAA0D;AAC1D,MAAM,UAAU,iBAAiB,CAC/B,QAAuC;IAEvC,IAAI,QAAQ,KAAK,SAAS;QAAE,OAAO,EAAE,CAAC;IACtC,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,GAAG,GAAwB,EAAE,CAAC;IACpC,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;QAC3B,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,SAAS;QAC5B,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACd,IAAI,GAAG,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;YAClC,GAAG,CAAC,IAAI,CAAC;gBACP,IAAI,EAAE,QAAQ;gBACd,GAAG;gBACH,MAAM,EAAE,GAAG,CAAC,KAAK,CAAC,aAAa,CAAC,MAAM,CAAC;gBACvC,UAAU,EAAE,qBAAqB,CAAC,QAAQ,CAAC;aAC5C,CAAC,CAAC;YACH,SAAS;QACX,CAAC;QACD,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;QACxB,GAAG,CAAC,IAAI,CAAC;YACP,IAAI,EAAE,IAAI,IAAI,SAAS;YACvB,GAAG;YACH,UAAU,EAAE,qBAAqB,CAAC,IAAI,IAAI,SAAS,CAAC;SACrD,CAAC,CAAC;IACL,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,eAAe,CAC7B,UAAmB,EACnB,YAA0C;IAE1C,OAAO,CAAC,UAAU,IAAI,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,aAAa,CAAC,CAAC;AAC3E,CAAC;AAYD;;;;;;;;;GASG;AACH,MAAM,UAAU,SAAS,CACvB,KAAgC,EAChC,YAAiC,EACjC,UAAmB,EACnB,YAA0C;IAE1C,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAC5D,IAAI,YAAY,KAAK,IAAI;QAAE,OAAO,UAAU,CAAC;IAC7C,OAAO,eAAe,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC;AAC1E,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,iBAAiB,CAC/B,YAA0C;IAE1C,OAAO,CACL,YAAY,CAAC,MAAM,GAAG,CAAC;QACvB,YAAY,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,WAAW,CAAC,IAAI,KAAK,aAAa,CAAC,CACxE,CAAC;AACJ,CAAC"}
package/llms.txt CHANGED
@@ -1,6 +1,6 @@
1
- # @stapel/search-react 0.3.1
1
+ # @stapel/search-react 0.4.0
2
2
 
3
- Headless React flow pair for stapel-search (contract >=0.1 <0.2) — business + state, zero visual opinion.
3
+ Headless React flow pair for stapel-search (contract >=0.2 <0.3) — business + state, zero visual opinion.
4
4
  Built on @stapel/core: typed client + StapelApiError envelope, auth token refresh,
5
5
  verification-403 interception, i18n engine, analytics facade, TanStack Query layer.
6
6
 
package/manifest.json CHANGED
@@ -1,10 +1,10 @@
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.3.1",
4
+ "version": "0.4.0",
5
5
  "backend": {
6
6
  "module": "stapel-search",
7
- "contract": ">=0.1 <0.2"
7
+ "contract": ">=0.2 <0.3"
8
8
  },
9
9
  "layers": [
10
10
  "api",
@@ -534,6 +534,9 @@
534
534
  "search.results.count_approximate",
535
535
  "search.results.count_approximate.one",
536
536
  "search.results.count_approximate.other",
537
+ "search.results.count_at_least",
538
+ "search.results.count_at_least.one",
539
+ "search.results.count_at_least.other",
537
540
  "search.results.count_exact",
538
541
  "search.results.count_exact.one",
539
542
  "search.results.count_exact.other",
@@ -586,11 +589,13 @@
586
589
  "buildFacetGroups",
587
590
  "clearFilters",
588
591
  "countIsEstimate",
592
+ "countKind",
589
593
  "createSearchApi",
590
594
  "createSearchRuntime",
591
595
  "degradationMessageKey",
592
596
  "explainSearchError",
593
597
  "facetOptionLabel",
598
+ "isCountNuanceOnly",
594
599
  "navEntries",
595
600
  "ownsParam",
596
601
  "parseDegradations",
@@ -629,6 +634,7 @@
629
634
  "Schemas",
630
635
  "Scorer",
631
636
  "SearchApi",
637
+ "SearchCountKind",
632
638
  "SearchDegradation",
633
639
  "SearchDegradationKind",
634
640
  "SearchErrorCode",
package/nav-manifest.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "package": "@stapel/search-react",
3
- "version": "0.3.1",
3
+ "version": "0.4.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.3.1",
3
+ "version": "0.4.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": {
@@ -112,10 +112,10 @@
112
112
  "typescript": "^5.8.3",
113
113
  "vitest": "^3.2.4",
114
114
  "@stapel/attributes-react": "^0.2.0",
115
- "@stapel/core": "^0.17.0",
116
115
  "@stapel/showcase": "^0.2.0",
117
116
  "@stapel/tokens": "^0.5.0",
118
- "@stapel/tokens-antd": "^0.5.0"
117
+ "@stapel/tokens-antd": "^0.5.0",
118
+ "@stapel/core": "^0.17.0"
119
119
  },
120
120
  "engines": {
121
121
  "node": ">=22"
@@ -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.3.1",
4
+ "version": "0.4.0",
5
5
  "defined": [],
6
6
  "flows": []
7
7
  }
@@ -213,7 +213,11 @@ export interface components {
213
213
  prev_anchor: string | null;
214
214
  has_next: boolean;
215
215
  has_prev: boolean;
216
- count: number;
216
+ /** @description How many documents match. NEVER 0 beside a non-empty items[] — the answer may not claim fewer matches than the page shows. `null` means the engine cannot say, and is rendered as no count at all. */
217
+ count: number | null;
218
+ /** @description True when `count` is a floor: at least this many match, possibly more (a capped count, a window-truncated engine answer). Render 'N+', never 'N'. */
219
+ count_is_lower_bound: boolean;
220
+ /** @description True when `count` is exact for THIS answer — equivalent to `count is not null and not count_is_lower_bound`. Per answer, not per engine: an engine without a guaranteed exact total still counts a small candidate set exactly. */
217
221
  exact_total: boolean;
218
222
  /** @description What the configured engine could not do for this query. */
219
223
  degraded: string[];
@@ -9,41 +9,89 @@
9
9
  * An `unknown` degradation still renders — with the raw literal, because a
10
10
  * build that predates a new limitation should say "the engine reported
11
11
  * something we have no wording for: X", not nothing at all.
12
+ *
13
+ * ── Two deliberate ways NOT to shout ───────────────────────────────────────
14
+ *
15
+ * 1. **`exact_total` alone never raises a banner.** It is a count NUANCE, not
16
+ * a failed search: the rows are right, and the single consequence — that
17
+ * the total is a floor — is already spoken by the count as "N+". A warning
18
+ * box over a perfectly good result page teaches the reader that the page
19
+ * is broken, and a banner that cries wolf on every landing page is a
20
+ * banner nobody reads on the day `category_rollup` appears in it. Beside
21
+ * any other degradation it renders normally, because the list is then
22
+ * describing an answer that really is degraded. See
23
+ * {@link isCountNuanceOnly}.
24
+ * 2. **`variant`.** A catalogue page wants the banner; a landing page that
25
+ * shows six cards under a hero has no room for a warning box and passes
26
+ * `"inline"` (one quiet line) or `"off"`. `"off"` is a decision the
27
+ * CONTAINER makes about ITS surface — the notice stays the default, and
28
+ * nothing here silences a degradation for everyone.
12
29
  */
13
30
  import type { ReactElement } from "react";
14
- import { Alert, Typography } from "antd";
31
+ import { Alert, Flex, Typography } from "antd";
15
32
  import { useT } from "@stapel/core";
16
33
  import type { SearchDegradation } from "../api/types.js";
34
+ import { isCountNuanceOnly } from "../state/degradations.js";
17
35
  import { SEARCH_I18N_KEYS } from "../i18n/keys.js";
18
36
 
37
+ /**
38
+ * How loudly a surface says what the engine could not do.
39
+ *
40
+ * - `"banner"` (default) — an antd warning `Alert` with one line per item.
41
+ * - `"inline"` — the same sentences as quiet secondary text, no box.
42
+ * - `"off"` — nothing. For a surface where the notice does not belong at all;
43
+ * the container that turns it off owns saying so somewhere else.
44
+ */
45
+ export type DegradationNoticeVariant = "banner" | "inline" | "off";
46
+
19
47
  export interface DegradationNoticeProps {
20
48
  readonly degradations: readonly SearchDegradation[];
49
+ readonly variant?: DegradationNoticeVariant;
21
50
  }
22
51
 
23
52
  export function DegradationNotice(
24
53
  props: DegradationNoticeProps
25
54
  ): ReactElement | null {
26
55
  const t = useT();
56
+ const variant: DegradationNoticeVariant = props.variant ?? "banner";
57
+ if (variant === "off") return null;
27
58
  if (props.degradations.length === 0) return null;
59
+ // A count nuance is not a degraded search — the count already says "N+".
60
+ if (isCountNuanceOnly(props.degradations)) return null;
61
+
62
+ const lines = props.degradations.map((degradation) => (
63
+ <li key={degradation.raw} data-degradation={degradation.raw}>
64
+ <Typography.Text type="secondary">
65
+ {t(degradation.messageKey, {
66
+ scorer: degradation.scorer ?? "",
67
+ raw: degradation.raw,
68
+ })}
69
+ </Typography.Text>
70
+ </li>
71
+ ));
72
+
73
+ if (variant === "inline") {
74
+ return (
75
+ <Flex vertical gap={2} data-testid="search-degraded" data-variant="inline">
76
+ <Typography.Text type="secondary" style={{ fontSize: 12 }}>
77
+ {t(SEARCH_I18N_KEYS.degradedTitle)}
78
+ </Typography.Text>
79
+ <ul style={{ margin: 0, paddingInlineStart: 20, fontSize: 12 }}>
80
+ {lines}
81
+ </ul>
82
+ </Flex>
83
+ );
84
+ }
85
+
28
86
  return (
29
87
  <Alert
30
88
  type="warning"
31
89
  showIcon
32
90
  data-testid="search-degraded"
91
+ data-variant="banner"
33
92
  message={t(SEARCH_I18N_KEYS.degradedTitle)}
34
93
  description={
35
- <ul style={{ margin: 0, paddingInlineStart: 20 }}>
36
- {props.degradations.map((degradation) => (
37
- <li key={degradation.raw} data-degradation={degradation.raw}>
38
- <Typography.Text type="secondary">
39
- {t(degradation.messageKey, {
40
- scorer: degradation.scorer ?? "",
41
- raw: degradation.raw,
42
- })}
43
- </Typography.Text>
44
- </li>
45
- ))}
46
- </ul>
94
+ <ul style={{ margin: 0, paddingInlineStart: 20 }}>{lines}</ul>
47
95
  }
48
96
  />
49
97
  );
@@ -23,6 +23,7 @@ import type { ParseSearchStateOptions } from "../state/urlState.js";
23
23
  import { FacetPanelPane } from "./FacetPanelPane.js";
24
24
  import { SearchResultsPane } from "./SearchResultsPane.js";
25
25
  import { SortSelect } from "./SortSelect.js";
26
+ import type { DegradationNoticeVariant } from "./DegradationNotice.js";
26
27
  import type { SearchCardRenderer } from "./SearchResultCard.js";
27
28
  import { SearchSkinTheme } from "./theme.js";
28
29
  import { UrlIssueNotice } from "./UrlIssueNotice.js";
@@ -37,6 +38,9 @@ export interface SearchPageProps extends ThemeModeProp, ParseSearchStateOptions
37
38
  readonly locale?: string;
38
39
  /** Container chrome under the results — e.g. the ranking-disclosure link. */
39
40
  readonly footer?: ReactNode;
41
+ /** How the results surface says what the engine could not do (default
42
+ * `"banner"`). Handed straight to `<SearchResultsPane>`. */
43
+ readonly degradationNotice?: DegradationNoticeVariant;
40
44
  }
41
45
 
42
46
  export function SearchPage(props: SearchPageProps): ReactElement {
@@ -46,6 +50,7 @@ export function SearchPage(props: SearchPageProps): ReactElement {
46
50
  categoryFeatures,
47
51
  locale,
48
52
  footer,
53
+ degradationNotice,
49
54
  mode,
50
55
  ...parseOptions
51
56
  } = props;
@@ -72,6 +77,9 @@ export function SearchPage(props: SearchPageProps): ReactElement {
72
77
  toolbar={<SortSelect />}
73
78
  {...(renderCard !== undefined ? { renderCard } : {})}
74
79
  {...(footer !== undefined ? { footer } : {})}
80
+ {...(degradationNotice !== undefined
81
+ ? { degradationNotice }
82
+ : {})}
75
83
  />
76
84
  </Col>
77
85
  </Row>
@@ -29,6 +29,7 @@ import type { SearchResultsBag } from "../headless/SearchResults.js";
29
29
  import { SEARCH_WINDOW_EXCEEDED } from "../i18n/errorsMap.js";
30
30
  import { SEARCH_I18N_KEYS } from "../i18n/keys.js";
31
31
  import { DegradationNotice } from "./DegradationNotice.js";
32
+ import type { DegradationNoticeVariant } from "./DegradationNotice.js";
32
33
  import { ErrorAlert } from "./ErrorAlert.js";
33
34
  import { SearchResultCard } from "./SearchResultCard.js";
34
35
  import type { SearchCardRenderer } from "./SearchResultCard.js";
@@ -82,6 +83,17 @@ export interface SearchResultsPaneProps extends ThemeModeProp {
82
83
  readonly toolbar?: ReactNode;
83
84
  /** Rendered under the pager — where the container puts the ranking link. */
84
85
  readonly footer?: ReactNode;
86
+ /**
87
+ * How this surface says what the engine could not do (default `"banner"`).
88
+ *
89
+ * A catalogue page wants the warning box. A landing page showing six cards
90
+ * under a hero has no room for one and passes `"inline"` or `"off"` — a
91
+ * decision about THIS surface, not about whether the degradation matters.
92
+ * Note that an `exact_total`-only degradation never raises a banner under
93
+ * any variant: it is a count nuance the count itself already speaks as
94
+ * "N+", not a failed search.
95
+ */
96
+ readonly degradationNotice?: DegradationNoticeVariant;
85
97
  readonly enabled?: boolean;
86
98
  }
87
99
 
@@ -92,12 +104,18 @@ function Count(props: { bag: SearchResultsBag }): ReactElement | null {
92
104
  const tPlural = useTPlural();
93
105
  const page = props.bag.page;
94
106
  if (page === null) return null;
107
+ // No count line at all when the server cannot say. The alternative — some
108
+ // number — is how "About 0 listings" ended up printed over four visible
109
+ // cards: an unknown total rendered as a claim about the catalogue.
110
+ if (page.countKind === "unknown" || page.count === null) return null;
95
111
  return (
96
- <Typography.Text type="secondary" data-testid="search-count">
97
- {page.countIsEstimate
98
- ? tPlural(SEARCH_I18N_KEYS.resultsCountApproximate, {
99
- count: page.count,
100
- })
112
+ <Typography.Text
113
+ type="secondary"
114
+ data-testid="search-count"
115
+ data-count-kind={page.countKind}
116
+ >
117
+ {page.countKind === "at_least"
118
+ ? tPlural(SEARCH_I18N_KEYS.resultsCountAtLeast, { count: page.count })
101
119
  : tPlural(SEARCH_I18N_KEYS.resultsCountExact, { count: page.count })}
102
120
  </Typography.Text>
103
121
  );
@@ -152,7 +170,10 @@ export function SearchResultsPane(props: SearchResultsPaneProps): ReactElement {
152
170
  </Flex>
153
171
  </Flex>
154
172
 
155
- <DegradationNotice degradations={bag.degradations} />
173
+ <DegradationNotice
174
+ degradations={bag.degradations}
175
+ variant={props.degradationNotice ?? "banner"}
176
+ />
156
177
 
157
178
  {matchList(bag.state, {
158
179
  loading: () => (
@@ -41,7 +41,10 @@ export type { RankingDisclosurePaneProps } from "./RankingDisclosurePane.js";
41
41
  export { SearchResultCard, GENERIC_CARD_FIELDS } from "./SearchResultCard.js";
42
42
  export type { SearchCardProps, SearchCardRenderer } from "./SearchResultCard.js";
43
43
  export { DegradationNotice } from "./DegradationNotice.js";
44
- export type { DegradationNoticeProps } from "./DegradationNotice.js";
44
+ export type {
45
+ DegradationNoticeProps,
46
+ DegradationNoticeVariant,
47
+ } from "./DegradationNotice.js";
45
48
  export { UrlIssueNotice } from "./UrlIssueNotice.js";
46
49
  export { SortSelect } from "./SortSelect.js";
47
50
  export type { SortSelectProps } from "./SortSelect.js";
@@ -15,15 +15,36 @@ import type {
15
15
  } from "../api/types.js";
16
16
  import { SEARCH_I18N_KEYS } from "../i18n/keys.js";
17
17
  import { useSearchQuery } from "../model/queries.js";
18
- import { countIsEstimate, parseDegradations } from "../state/degradations.js";
18
+ import {
19
+ countIsEstimate,
20
+ countKind,
21
+ parseDegradations,
22
+ } from "../state/degradations.js";
23
+ import type { SearchCountKind } from "../state/degradations.js";
19
24
  import { useSearchState } from "./SearchStateProvider.js";
20
25
 
21
26
  /** What the envelope says about this page, beside the rows. */
22
27
  export interface SearchPageInfo {
23
- /** Total matches — an ESTIMATE unless {@link SearchPageInfo.exactTotal}. */
24
- readonly count: number;
28
+ /**
29
+ * Total matches, or `null` when the engine cannot say — which is a real
30
+ * state and NOT zero. Read it together with {@link SearchPageInfo.countKind}:
31
+ * a `count` under `"at_least"` is a floor, not a total.
32
+ */
33
+ readonly count: number | null;
25
34
  readonly exactTotal: boolean;
26
- /** `true` when `count` must be rendered as approximate ("≈", "about"). */
35
+ /** The server's own word: `count` is a floor ("at least N"), not a total. */
36
+ readonly countIsLowerBound: boolean;
37
+ /**
38
+ * The one value a skin needs to choose a sentence: `"exact"` → "N",
39
+ * `"at_least"` → "N+", `"unknown"` → no count at all.
40
+ */
41
+ readonly countKind: SearchCountKind;
42
+ /**
43
+ * `true` when `count` must not be rendered as a plain number.
44
+ *
45
+ * @deprecated Equivalent to `countKind !== "exact"` and blind to
46
+ * `count: null`. Use {@link SearchPageInfo.countKind}.
47
+ */
27
48
  readonly countIsEstimate: boolean;
28
49
  readonly hasNext: boolean;
29
50
  readonly hasPrev: boolean;
@@ -102,6 +123,13 @@ export function SearchResults(props: {
102
123
  : {
103
124
  count: data.count,
104
125
  exactTotal: data.exact_total,
126
+ countIsLowerBound: data.count_is_lower_bound === true,
127
+ countKind: countKind(
128
+ data.count,
129
+ data.count_is_lower_bound,
130
+ data.exact_total,
131
+ degradations
132
+ ),
105
133
  countIsEstimate: countIsEstimate(data.exact_total, degradations),
106
134
  hasNext: data.has_next,
107
135
  hasPrev: data.has_prev,
package/src/i18n/es.ts CHANGED
@@ -22,6 +22,8 @@ export const searchI18nBundleEs: I18nDictionary = {
22
22
  "search.results.retry": "Reintentar",
23
23
  "search.results.count_approximate.one": "Aproximadamente {count} resultado",
24
24
  "search.results.count_approximate.other": "Unos {count} resultados",
25
+ "search.results.count_at_least.one": "{count}+ resultado",
26
+ "search.results.count_at_least.other": "{count}+ resultados",
25
27
  "search.results.count_exact.one": "{count} resultado",
26
28
  "search.results.count_exact.other": "{count} resultados",
27
29
  "search.results.took_ms": "{ms} ms",