@stapel/search-react 0.4.0 → 0.8.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 (154) hide show
  1. package/CHANGELOG.md +191 -0
  2. package/README.md +1 -1
  3. package/dist/default/DegradationNotice.d.ts +7 -0
  4. package/dist/default/DegradationNotice.d.ts.map +1 -1
  5. package/dist/default/DegradationNotice.js +17 -6
  6. package/dist/default/DegradationNotice.js.map +1 -1
  7. package/dist/default/FacetGroupControl.d.ts +40 -0
  8. package/dist/default/FacetGroupControl.d.ts.map +1 -0
  9. package/dist/default/FacetGroupControl.js +176 -0
  10. package/dist/default/FacetGroupControl.js.map +1 -0
  11. package/dist/default/FacetPanelPane.d.ts +54 -3
  12. package/dist/default/FacetPanelPane.d.ts.map +1 -1
  13. package/dist/default/FacetPanelPane.js +116 -22
  14. package/dist/default/FacetPanelPane.js.map +1 -1
  15. package/dist/default/FilterChips.d.ts +28 -0
  16. package/dist/default/FilterChips.d.ts.map +1 -0
  17. package/dist/default/FilterChips.js +204 -0
  18. package/dist/default/FilterChips.js.map +1 -0
  19. package/dist/default/LanguageSelect.d.ts +9 -0
  20. package/dist/default/LanguageSelect.d.ts.map +1 -0
  21. package/dist/default/LanguageSelect.js +72 -0
  22. package/dist/default/LanguageSelect.js.map +1 -0
  23. package/dist/default/PageSizeSelect.d.ts +29 -0
  24. package/dist/default/PageSizeSelect.d.ts.map +1 -0
  25. package/dist/default/PageSizeSelect.js +25 -0
  26. package/dist/default/PageSizeSelect.js.map +1 -0
  27. package/dist/default/RangeFilterRow.d.ts +12 -0
  28. package/dist/default/RangeFilterRow.d.ts.map +1 -0
  29. package/dist/default/RangeFilterRow.js +75 -0
  30. package/dist/default/RangeFilterRow.js.map +1 -0
  31. package/dist/default/RankingDisclosurePane.d.ts +5 -0
  32. package/dist/default/RankingDisclosurePane.d.ts.map +1 -1
  33. package/dist/default/RankingDisclosurePane.js +15 -15
  34. package/dist/default/RankingDisclosurePane.js.map +1 -1
  35. package/dist/default/SearchBox.d.ts +13 -0
  36. package/dist/default/SearchBox.d.ts.map +1 -0
  37. package/dist/default/SearchBox.js +67 -0
  38. package/dist/default/SearchBox.js.map +1 -0
  39. package/dist/default/SearchPage.d.ts +94 -16
  40. package/dist/default/SearchPage.d.ts.map +1 -1
  41. package/dist/default/SearchPage.js +191 -8
  42. package/dist/default/SearchPage.js.map +1 -1
  43. package/dist/default/SearchResultCard.d.ts +19 -18
  44. package/dist/default/SearchResultCard.d.ts.map +1 -1
  45. package/dist/default/SearchResultCard.js +178 -5
  46. package/dist/default/SearchResultCard.js.map +1 -1
  47. package/dist/default/SearchResultsPane.d.ts +61 -3
  48. package/dist/default/SearchResultsPane.d.ts.map +1 -1
  49. package/dist/default/SearchResultsPane.js +51 -21
  50. package/dist/default/SearchResultsPane.js.map +1 -1
  51. package/dist/default/SortSelect.d.ts +10 -2
  52. package/dist/default/SortSelect.d.ts.map +1 -1
  53. package/dist/default/SortSelect.js +27 -24
  54. package/dist/default/SortSelect.js.map +1 -1
  55. package/dist/default/UrlIssueNotice.d.ts.map +1 -1
  56. package/dist/default/UrlIssueNotice.js +19 -1
  57. package/dist/default/UrlIssueNotice.js.map +1 -1
  58. package/dist/default/ViewSwitch.d.ts +66 -0
  59. package/dist/default/ViewSwitch.d.ts.map +1 -0
  60. package/dist/default/ViewSwitch.js +49 -0
  61. package/dist/default/ViewSwitch.js.map +1 -0
  62. package/dist/default/index.d.ts +38 -15
  63. package/dist/default/index.d.ts.map +1 -1
  64. package/dist/default/index.js +29 -12
  65. package/dist/default/index.js.map +1 -1
  66. package/dist/default/sortLabels.d.ts +5 -0
  67. package/dist/default/sortLabels.d.ts.map +1 -0
  68. package/dist/default/sortLabels.js +32 -0
  69. package/dist/default/sortLabels.js.map +1 -0
  70. package/dist/headless/FacetPanel.d.ts +17 -0
  71. package/dist/headless/FacetPanel.d.ts.map +1 -1
  72. package/dist/headless/FacetPanel.js +23 -2
  73. package/dist/headless/FacetPanel.js.map +1 -1
  74. package/dist/headless/useAppliedCount.d.ts +8 -0
  75. package/dist/headless/useAppliedCount.d.ts.map +1 -0
  76. package/dist/headless/useAppliedCount.js +30 -0
  77. package/dist/headless/useAppliedCount.js.map +1 -0
  78. package/dist/headless/useScorerNames.d.ts +4 -0
  79. package/dist/headless/useScorerNames.d.ts.map +1 -0
  80. package/dist/headless/useScorerNames.js +34 -0
  81. package/dist/headless/useScorerNames.js.map +1 -0
  82. package/dist/headless/useSearchBox.d.ts +44 -0
  83. package/dist/headless/useSearchBox.d.ts.map +1 -0
  84. package/dist/headless/useSearchBox.js +116 -0
  85. package/dist/headless/useSearchBox.js.map +1 -0
  86. package/dist/i18n/es.d.ts.map +1 -1
  87. package/dist/i18n/es.js +38 -4
  88. package/dist/i18n/es.js.map +1 -1
  89. package/dist/i18n/keys.d.ts +55 -0
  90. package/dist/i18n/keys.d.ts.map +1 -1
  91. package/dist/i18n/keys.js +101 -4
  92. package/dist/i18n/keys.js.map +1 -1
  93. package/dist/i18n/ru.d.ts.map +1 -1
  94. package/dist/i18n/ru.js +42 -4
  95. package/dist/i18n/ru.js.map +1 -1
  96. package/dist/index.d.ts +7 -2
  97. package/dist/index.d.ts.map +1 -1
  98. package/dist/index.js +5 -2
  99. package/dist/index.js.map +1 -1
  100. package/dist/model/queries.d.ts +26 -2
  101. package/dist/model/queries.d.ts.map +1 -1
  102. package/dist/model/queries.js +38 -1
  103. package/dist/model/queries.js.map +1 -1
  104. package/dist/state/limits.d.ts +44 -0
  105. package/dist/state/limits.d.ts.map +1 -0
  106. package/dist/state/limits.js +44 -0
  107. package/dist/state/limits.js.map +1 -0
  108. package/dist/state/ranges.d.ts +52 -0
  109. package/dist/state/ranges.d.ts.map +1 -0
  110. package/dist/state/ranges.js +108 -0
  111. package/dist/state/ranges.js.map +1 -0
  112. package/llms.txt +16 -4
  113. package/manifest.json +268 -22
  114. package/nav-manifest.json +1 -1
  115. package/package.json +15 -10
  116. package/src/analytics/generated/events.json +1 -1
  117. package/src/default/DegradationNotice.tsx +34 -12
  118. package/src/default/FacetGroupControl.tsx +312 -0
  119. package/src/default/FacetPanelPane.tsx +320 -87
  120. package/src/default/FilterChips.tsx +415 -0
  121. package/src/default/LanguageSelect.tsx +93 -0
  122. package/src/default/PageSizeSelect.tsx +80 -0
  123. package/src/default/RangeFilterRow.tsx +148 -0
  124. package/src/default/RankingDisclosurePane.tsx +67 -35
  125. package/src/default/SearchBox.tsx +130 -0
  126. package/src/default/SearchPage.tsx +454 -44
  127. package/src/default/SearchResultCard.tsx +231 -24
  128. package/src/default/SearchResultsPane.tsx +158 -71
  129. package/src/default/SortSelect.tsx +50 -37
  130. package/src/default/UrlIssueNotice.tsx +21 -3
  131. package/src/default/ViewSwitch.tsx +147 -0
  132. package/src/default/index.ts +55 -15
  133. package/src/default/sortLabels.ts +34 -0
  134. package/src/headless/FacetPanel.tsx +30 -2
  135. package/src/headless/useAppliedCount.ts +41 -0
  136. package/src/headless/useScorerNames.ts +36 -0
  137. package/src/headless/useSearchBox.ts +189 -0
  138. package/src/i18n/es.ts +46 -4
  139. package/src/i18n/keys.ts +114 -4
  140. package/src/i18n/ru.ts +50 -4
  141. package/src/index.ts +22 -2
  142. package/src/model/queries.ts +51 -1
  143. package/src/state/limits.ts +50 -0
  144. package/src/state/ranges.ts +144 -0
  145. package/dist/default/ErrorAlert.d.ts +0 -9
  146. package/dist/default/ErrorAlert.d.ts.map +0 -1
  147. package/dist/default/ErrorAlert.js +0 -27
  148. package/dist/default/ErrorAlert.js.map +0 -1
  149. package/dist/default/theme.d.ts +0 -24
  150. package/dist/default/theme.d.ts.map +0 -1
  151. package/dist/default/theme.js +0 -39
  152. package/dist/default/theme.js.map +0 -1
  153. package/src/default/ErrorAlert.tsx +0 -46
  154. package/src/default/theme.tsx +0 -66
@@ -1,15 +1,198 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { Col, Flex, Row } from "antd";
3
- import { SearchStateProvider } from "../headless/SearchStateProvider.js";
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ /**
3
+ * `<SearchPage>` the composed screen the nav manifest points at: the query
4
+ * box, the filters, the sort and the results.
5
+ *
6
+ * It composes the panes and owns NO state of its own. The URL is the state,
7
+ * and it arrives through the `adapter` prop — which is where a host hands in
8
+ * `useRouterSearchParams()` from `@stapel/search-react/router`, or its own
9
+ * binding. The page does not reach for a router, so the same component renders
10
+ * under react-router, under a Next.js app router, and in a test with a plain
11
+ * `URLSearchParams`.
12
+ *
13
+ * The seams a storefront fills: `renderCard` (a `<ListingCard>`),
14
+ * `categoryFeatures` (from categories-react, for facet labels and range rows),
15
+ * `renderCategoryFilter` / `renderGeoFilter` (controls other pairs own),
16
+ * `footer` (the container's own chrome), `filtersHeader` and `resultsHeading`.
17
+ * None of them is optional behaviour in disguise — every one has a working
18
+ * default or a visible placeholder.
19
+ *
20
+ * ── The screen could not start a search ───────────────────────────────────
21
+ *
22
+ * Until this release the page rendered filters, sort and results and NO query
23
+ * box: `q` reached the state only from the address bar, and `setText` had zero
24
+ * callers in the repository. A scaffolded app therefore had a search route and
25
+ * no way to search (audit S-1). `<SearchBox>` is now the first thing on the
26
+ * page — and it is exported, so a container that puts the real box in its
27
+ * header can pass `searchBox={false}` and keep exactly one.
28
+ *
29
+ * ── On a phone the filters are a sheet ────────────────────────────────────
30
+ *
31
+ * The filter column was `xs={24}`: on a 390px screen the entire panel stacked
32
+ * ABOVE the results, so a person scrolled past every facet to reach the first
33
+ * card (§83(b), audit S-6). Below the tablet breakpoint the panel now lives
34
+ * behind a "Filters (N)" button and opens as a bottom sheet through the shared
35
+ * `SkinDialog`, with the count of what is applied on the button itself.
36
+ *
37
+ * ── The filter column is laid out only when there is something in it ──────
38
+ *
39
+ * `Col md={7}` was unconditional, and on a deployment whose search plan
40
+ * declares no facets that spent a quarter of every results page — `/s`, every
41
+ * category page, every seller page — on an empty-state illustration saying
42
+ * "no filters for this search". Saying it once is honest; reserving a column
43
+ * for it on every screen is not a message, it is a hole. The page asks the
44
+ * facet bag what it has (`useFacetPanel`) and gives the results the whole
45
+ * width when the answer is nothing AND no other filter control has anything
46
+ * to show. Note which way the test runs: the column stays for `loading` and
47
+ * for `failed`, because a panel that has not answered yet is not a panel with
48
+ * nothing in it, and a layout that reflowed underneath a person mid-load would
49
+ * be worse than the hole.
50
+ */
51
+ import { useState } from "react";
52
+ import { Button, Flex } from "antd";
53
+ import { SkinDialog, SkinTheme, useDialogSurface } from "@stapel/tokens-antd/skin";
54
+ import { useT, useTPlural } from "@stapel/core";
55
+ import { spacing } from "@stapel/tokens";
56
+ import { SearchStateProvider, useSearchState } from "../headless/SearchStateProvider.js";
57
+ import { useFacetPanel } from "../headless/FacetPanel.js";
58
+ import { useAppliedCount } from "../headless/useAppliedCount.js";
59
+ import { buildRangeGroups } from "../state/ranges.js";
60
+ import { SEARCH_I18N_KEYS } from "../i18n/keys.js";
4
61
  import { FacetPanelPane } from "./FacetPanelPane.js";
62
+ import { FilterChips } from "./FilterChips.js";
63
+ import { PageSizeSelect } from "./PageSizeSelect.js";
64
+ import { SearchBox } from "./SearchBox.js";
5
65
  import { SearchResultsPane } from "./SearchResultsPane.js";
6
66
  import { SortSelect } from "./SortSelect.js";
7
- import { SearchSkinTheme } from "./theme.js";
67
+ import { SEARCH_BUILTIN_VIEWS, ViewSwitch, resolveView } from "./ViewSwitch.js";
8
68
  import { UrlIssueNotice } from "./UrlIssueNotice.js";
69
+ /**
70
+ * The desktop filter rail's width.
71
+ *
72
+ * A rail, not a half-page. `Col md={7}` gave the panel a SHARE of the page, so
73
+ * on a wide screen the filters grew with it — the visual pass measured 570 of
74
+ * 1280px (45%) spent on the controls that narrow a list, next to the list they
75
+ * narrow. Filters are a fixed instrument: a checkbox column needs the width of
76
+ * its longest label and nothing more, and every pixel past that comes out of
77
+ * the results. 280px is that width at the default type step, and it is the
78
+ * same panel the phone sheet draws — one component, two frames.
79
+ */
80
+ export const FILTERS_RAIL_WIDTH = 280;
81
+ /**
82
+ * The rail: fixed width, never squeezed, never grown — and STICKY.
83
+ *
84
+ * A catalogue page is thirty cards long and the filters are at the top of it,
85
+ * so by the fourth row of results the controls that narrow the list are a
86
+ * screenful above the list they narrow: the only way to change a filter after
87
+ * scrolling was to scroll back. The rail now stays put while the results move
88
+ * under it, and scrolls INTERNALLY when its own content is taller than the
89
+ * window (`overflowY: auto` + a viewport-height cap), which is the one place a
90
+ * viewport measure is right — the sticky box's height IS the window's.
91
+ *
92
+ * `alignSelf: flex-start` is load-bearing: a flex child stretches to the row's
93
+ * height by default, and a stretched box has nothing to stick to.
94
+ */
95
+ const RAIL = {
96
+ flex: `0 0 ${String(FILTERS_RAIL_WIDTH)}px`,
97
+ maxWidth: FILTERS_RAIL_WIDTH,
98
+ position: "sticky",
99
+ top: 0,
100
+ alignSelf: "flex-start",
101
+ maxHeight: "100dvh",
102
+ overflowY: "auto",
103
+ overscrollBehavior: "contain",
104
+ // Room for the focus ring of the last control against the scroll edge.
105
+ paddingBlockEnd: spacing[2],
106
+ };
107
+ /** The results take what is left. `minWidth: 0` so a long word inside a card
108
+ * cannot push the grid wider than its column. */
109
+ const RESULTS_COLUMN = { flex: "1 1 auto", minWidth: 0 };
110
+ /**
111
+ * The two columns, inside the state provider — which is where they have to be,
112
+ * because the layout decision reads the same search the panes read.
113
+ */
114
+ function SearchPageBody(props) {
115
+ const t = useT();
116
+ const tPlural = useTPlural();
117
+ const { categoryFeatures, locale, filtersHeader } = props;
118
+ const { state } = useSearchState();
119
+ const facets = useFacetPanel({
120
+ ...(categoryFeatures !== undefined ? { categoryFeatures } : {}),
121
+ ...(locale !== undefined ? { locale } : {}),
122
+ });
123
+ const applied = useAppliedCount();
124
+ const surface = useDialogSurface();
125
+ const layout = props.filtersLayout ?? (surface === "sheet" ? "sheet" : "column");
126
+ const [sheetOpen, setSheetOpen] = useState(props.defaultFiltersOpen === true);
127
+ // How the results are ARRANGED. Component state, not URL state: it changes
128
+ // how the same answer is drawn, never what the answer is, so it must not
129
+ // rewrite the meaning of a link somebody shared (`<ViewSwitch>` §the view is
130
+ // not URL state).
131
+ const views = props.views ?? SEARCH_BUILTIN_VIEWS;
132
+ const [viewId, setViewId] = useState(props.defaultView);
133
+ const view = resolveView(views, viewId) ?? { id: "", labelKey: "" };
134
+ const changeView = (next) => {
135
+ setViewId(next);
136
+ props.onViewChange?.(next);
137
+ };
138
+ /**
139
+ * "Show 25 results", not "Show results".
140
+ *
141
+ * The sheet's own button is the only place a person learns what the filters
142
+ * they just ticked did — the results are behind it. When the engine cannot
143
+ * say how many there are (`countKind: "unknown"`) the button says so by
144
+ * saying nothing: a fabricated number on the one control that commits the
145
+ * change is worse than a generic verb.
146
+ */
147
+ const applyLabel = applied.count === null || applied.kind === "unknown"
148
+ ? t(SEARCH_I18N_KEYS.filtersApply)
149
+ : tPlural(applied.kind === "at_least"
150
+ ? SEARCH_I18N_KEYS.filtersShowCountAtLeast
151
+ : SEARCH_I18N_KEYS.filtersShowCount, { count: applied.count });
152
+ // "Nothing to filter by" is a LOADED answer of zero facet groups AND no
153
+ // other control with anything to say — see the header. Every clause is a
154
+ // control that would otherwise be hidden behind an empty panel: a numeric
155
+ // range the schema declares, a category or a language the URL carries, a
156
+ // host slot that is filled.
157
+ const ranges = buildRangeGroups({
158
+ state,
159
+ ...(categoryFeatures !== undefined ? { categoryFeatures } : {}),
160
+ });
161
+ const filtersEmpty = facets.state.status === "ready" &&
162
+ facets.state.data.length === 0 &&
163
+ facets.activeFilters === 0 &&
164
+ ranges.length === 0 &&
165
+ state.category === undefined &&
166
+ state.lang === undefined &&
167
+ props.renderCategoryFilter === undefined &&
168
+ props.renderGeoFilter === undefined &&
169
+ (props.languages ?? []).length === 0;
170
+ const showFilters = filtersHeader !== undefined || !filtersEmpty;
171
+ const panel = (_jsxs(Flex, { vertical: true, gap: spacing[4], children: [filtersHeader, filtersEmpty ? null : (_jsx(FacetPanelPane, { ...(layout === "sheet" ? { heading: null } : {}), ...(categoryFeatures !== undefined ? { categoryFeatures } : {}), ...(locale !== undefined ? { locale } : {}), ...(props.languages !== undefined ? { languages: props.languages } : {}), ...(props.renderCategoryFilter !== undefined
172
+ ? { renderCategoryFilter: props.renderCategoryFilter }
173
+ : {}), ...(props.renderGeoFilter !== undefined
174
+ ? { renderGeoFilter: props.renderGeoFilter }
175
+ : {}) }))] }));
176
+ // The toolbar over the results: how they are ARRANGED, how they are ORDERED,
177
+ // how many per page — and the surface's own action at the trailing end.
178
+ const toolbar = (_jsxs(Flex, { align: "center", wrap: true, gap: spacing[3], children: [_jsx(ViewSwitch, { views: views, value: view.id, onChange: changeView }), _jsx(SortSelect, {}), props.pageSize !== false && _jsx(PageSizeSelect, {}), props.resultsAction] }));
179
+ const results = (_jsx(SearchResultsPane, { toolbar: toolbar, headingLevel: props.resultsHeadingLevel ?? 1, ...(view.render !== undefined ? { renderResults: view.render } : {}), ...(view.layout !== undefined ? { layout: view.layout } : {}), ...(props.renderCard !== undefined ? { renderCard: props.renderCard } : {}), ...(props.footer !== undefined ? { footer: props.footer } : {}), ...(props.resultsHeading !== undefined
180
+ ? { heading: props.resultsHeading }
181
+ : {}), ...(props.degradationNotice !== undefined
182
+ ? { degradationNotice: props.degradationNotice }
183
+ : {}) }));
184
+ return (_jsxs(Flex, { vertical: true, gap: spacing[4], "data-testid": "search-page", "data-filters": showFilters ? "on" : "off", "data-filters-layout": layout, children: [props.searchBox !== false && _jsx(SearchBox, {}), props.breadcrumb !== undefined && (_jsx("div", { "data-testid": "search-breadcrumb", children: props.breadcrumb })), _jsx(UrlIssueNotice, {}), showFilters && layout === "sheet" ? (_jsxs(_Fragment, { children: [_jsx(FilterChips, { onOpenAll: () => {
185
+ setSheetOpen(true);
186
+ }, ...(categoryFeatures !== undefined ? { categoryFeatures } : {}), ...(locale !== undefined ? { locale } : {}), ...(props.renderGeoFilter !== undefined
187
+ ? { renderGeoFilter: props.renderGeoFilter }
188
+ : {}) }), _jsx(SkinDialog, { open: sheetOpen, onClose: () => {
189
+ setSheetOpen(false);
190
+ }, title: t(SEARCH_I18N_KEYS.facetsTitle), dismissLabel: t(SEARCH_I18N_KEYS.filtersDismiss), "data-testid": "search-filters-sheet", footer: _jsx(Button, { block: true, type: "primary", "data-testid": "search-filters-apply", "data-analytics": "none", "data-analytics-reason": "the filters are already applied; this closes the sheet", onClick: () => {
191
+ setSheetOpen(false);
192
+ }, children: applyLabel }), children: panel }), results] })) : showFilters ? (_jsxs(Flex, { align: "flex-start", gap: spacing[5], "data-testid": "search-page-columns", children: [_jsx("div", { style: RAIL, children: panel }), _jsx("div", { style: RESULTS_COLUMN, children: results })] })) : (results)] }));
193
+ }
9
194
  export function SearchPage(props) {
10
- const { adapter, renderCard, categoryFeatures, locale, footer, degradationNotice, mode, ...parseOptions } = props;
11
- return (_jsx(SearchSkinTheme, { ...(mode !== undefined ? { mode } : {}), children: _jsx(SearchStateProvider, { adapter: adapter, ...parseOptions, children: _jsxs(Flex, { vertical: true, gap: 16, "data-testid": "search-page", children: [_jsx(UrlIssueNotice, {}), _jsxs(Row, { gutter: [16, 16], children: [_jsx(Col, { xs: 24, md: 7, children: _jsx(FacetPanelPane, { ...(categoryFeatures !== undefined ? { categoryFeatures } : {}), ...(locale !== undefined ? { locale } : {}) }) }), _jsx(Col, { xs: 24, md: 17, children: _jsx(SearchResultsPane, { toolbar: _jsx(SortSelect, {}), ...(renderCard !== undefined ? { renderCard } : {}), ...(footer !== undefined ? { footer } : {}), ...(degradationNotice !== undefined
12
- ? { degradationNotice }
13
- : {}) }) })] })] }) }) }));
195
+ const { adapter, renderCard, categoryFeatures, locale, searchBox, languages, renderCategoryFilter, renderGeoFilter, footer, filtersHeader, resultsHeading, degradationNotice, filtersLayout, defaultFiltersOpen, pageSize, breadcrumb, views, defaultView, onViewChange, resultsAction, resultsHeadingLevel, mode, ...parseOptions } = props;
196
+ return (_jsx(SkinTheme, { surface: "base", ...(mode !== undefined ? { mode } : {}), children: _jsx(SearchStateProvider, { adapter: adapter, ...parseOptions, children: _jsx(SearchPageBody, { ...(renderCard !== undefined ? { renderCard } : {}), ...(categoryFeatures !== undefined ? { categoryFeatures } : {}), ...(locale !== undefined ? { locale } : {}), ...(searchBox !== undefined ? { searchBox } : {}), ...(languages !== undefined ? { languages } : {}), ...(renderCategoryFilter !== undefined ? { renderCategoryFilter } : {}), ...(renderGeoFilter !== undefined ? { renderGeoFilter } : {}), ...(footer !== undefined ? { footer } : {}), ...(filtersHeader !== undefined ? { filtersHeader } : {}), ...(resultsHeading !== undefined ? { resultsHeading } : {}), ...(degradationNotice !== undefined ? { degradationNotice } : {}), ...(filtersLayout !== undefined ? { filtersLayout } : {}), ...(defaultFiltersOpen !== undefined ? { defaultFiltersOpen } : {}), ...(pageSize !== undefined ? { pageSize } : {}), ...(breadcrumb !== undefined ? { breadcrumb } : {}), ...(views !== undefined ? { views } : {}), ...(defaultView !== undefined ? { defaultView } : {}), ...(onViewChange !== undefined ? { onViewChange } : {}), ...(resultsAction !== undefined ? { resultsAction } : {}), ...(resultsHeadingLevel !== undefined ? { resultsHeadingLevel } : {}) }) }) }));
14
197
  }
15
198
  //# sourceMappingURL=SearchPage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"SearchPage.js","sourceRoot":"","sources":["../../src/default/SearchPage.tsx"],"names":[],"mappings":";AAiBA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,MAAM,CAAC;AAEtC,OAAO,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AAGzE,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAG7C,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAiBrD,MAAM,UAAU,UAAU,CAAC,KAAsB;IAC/C,MAAM,EACJ,OAAO,EACP,UAAU,EACV,gBAAgB,EAChB,MAAM,EACN,MAAM,EACN,iBAAiB,EACjB,IAAI,EACJ,GAAG,YAAY,EAChB,GAAG,KAAK,CAAC;IAEV,OAAO,CACL,KAAC,eAAe,OAAK,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,YACvD,KAAC,mBAAmB,IAAC,OAAO,EAAE,OAAO,KAAM,YAAY,YACrD,MAAC,IAAI,IAAC,QAAQ,QAAC,GAAG,EAAE,EAAE,iBAAc,aAAa,aAC/C,KAAC,cAAc,KAAG,EAClB,MAAC,GAAG,IAAC,MAAM,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,aACnB,KAAC,GAAG,IAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,YAChB,KAAC,cAAc,OACT,CAAC,gBAAgB,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,gBAAgB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,KAC5D,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAC5C,GACE,EACN,KAAC,GAAG,IAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,YAMjB,KAAC,iBAAiB,IAChB,OAAO,EAAE,KAAC,UAAU,KAAG,KACnB,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,KAChD,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,KACxC,CAAC,iBAAiB,KAAK,SAAS;wCAClC,CAAC,CAAC,EAAE,iBAAiB,EAAE;wCACvB,CAAC,CAAC,EAAE,CAAC,GACP,GACE,IACF,IACD,GACa,GACN,CACnB,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"SearchPage.js","sourceRoot":"","sources":["../../src/default/SearchPage.tsx"],"names":[],"mappings":"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"}
@@ -1,22 +1,5 @@
1
- /**
2
- * The GENERIC card — the fallback behind `renderCard`, and the default the
3
- * spec (§3.7) says the pair must ship.
4
- *
5
- * `SearchItem.card` is a free-form object: "stored row fields, so a result
6
- * page costs one query". Which fields it holds is the DOC TYPE's business,
7
- * not search's, so this card reads a small, documented set of conventional
8
- * names and shows what it finds. A storefront replaces the whole thing by
9
- * passing `renderCard` and rendering `<ListingCard>` from
10
- * `@stapel/listings-react/default` — that is the slot seam, and the reason
11
- * these two L2 pairs never import each other.
12
- *
13
- * The ONE thing a replacement card may not drop is the `promoted` marking:
14
- * DSA Art. 26 makes it mandatory, the serializer puts it on every item under
15
- * every sort, and a storefront where some lists show it and some do not is
16
- * legally worse than one that never showed it. `renderCard` receives the whole
17
- * item so the marking is always reachable, and this default renders it.
18
- */
19
1
  import type { ReactElement, ReactNode } from "react";
2
+ import type { Format } from "@stapel/core";
20
3
  import type { SearchItem } from "../api/types.js";
21
4
  /** What the card slot is handed. */
22
5
  export interface SearchCardProps {
@@ -30,5 +13,23 @@ export type SearchCardRenderer = (item: SearchItem) => ReactNode;
30
13
  * belongs in the owning pair's own card.
31
14
  */
32
15
  export declare const GENERIC_CARD_FIELDS: readonly string[];
16
+ /**
17
+ * The card's price, written the way money is written.
18
+ *
19
+ * `card.price` arrives as a string because the index stores it as one, and
20
+ * `card.currency` as an ISO 4217 code because that is what a document carries.
21
+ * Rendered verbatim they read "3200 RUB": no grouping, the code where the
22
+ * symbol belongs, and the reader doing the arithmetic of where the thousands
23
+ * are. `Intl` knows all of that per locale, so the code goes in and the
24
+ * locale's own rendering comes out.
25
+ *
26
+ * Two ways this refuses to guess. A `price` that is not a finite number is
27
+ * passed through UNCHANGED — a doc type may store "on request", and turning
28
+ * that into `NaN` or into nothing loses what the seller wrote. A `currency`
29
+ * that is not a three-letter code (or one this runtime rejects) falls back to
30
+ * the plain grouped number plus the code, which is still better than the raw
31
+ * pair and never throws inside a render.
32
+ */
33
+ export declare function formatCardPrice(format: Format, price: string | undefined, currency: string | undefined): string | undefined;
33
34
  export declare function SearchResultCard(props: SearchCardProps): ReactElement;
34
35
  //# sourceMappingURL=SearchResultCard.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"SearchResultCard.d.ts","sourceRoot":"","sources":["../../src/default/SearchResultCard.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGrD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAGlD,oCAAoC;AACpC,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;CAC3B;AAED,wDAAwD;AACxD,MAAM,MAAM,kBAAkB,GAAG,CAAC,IAAI,EAAE,UAAU,KAAK,SAAS,CAAC;AAQjE;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,EAAE,SAAS,MAAM,EAMhD,CAAC;AAEF,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,eAAe,GAAG,YAAY,CA4CrE"}
1
+ {"version":3,"file":"SearchResultCard.d.ts","sourceRoot":"","sources":["../../src/default/SearchResultCard.tsx"],"names":[],"mappings":"AA8CA,OAAO,KAAK,EAAiB,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAKpE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAE3C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAGlD,oCAAoC;AACpC,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;CAC3B;AAED,wDAAwD;AACxD,MAAM,MAAM,kBAAkB,GAAG,CAAC,IAAI,EAAE,UAAU,KAAK,SAAS,CAAC;AAQjE;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,EAAE,SAAS,MAAM,EAOhD,CAAC;AAEF;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,QAAQ,EAAE,MAAM,GAAG,SAAS,GAC3B,MAAM,GAAG,SAAS,CAoBpB;AAiFD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,eAAe,GAAG,YAAY,CAgGrE"}
@@ -1,6 +1,54 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { Card, Flex, Tag, Tooltip, Typography } from "antd";
3
- import { useT } from "@stapel/core";
2
+ /**
3
+ * The GENERIC card — the fallback behind `renderCard`, and the default the
4
+ * spec (§3.7) says the pair must ship.
5
+ *
6
+ * `SearchItem.card` is a free-form object: "stored row fields, so a result
7
+ * page costs one query". Which fields it holds is the DOC TYPE's business,
8
+ * not search's, so this card reads a small, documented set of conventional
9
+ * names and shows what it finds. A storefront replaces the whole thing by
10
+ * passing `renderCard` and rendering `<ListingCard>` from
11
+ * `@stapel/listings-react/default` — that is the slot seam, and the reason
12
+ * these two L2 pairs never import each other.
13
+ *
14
+ * The ONE thing a replacement card may not drop is the `promoted` marking:
15
+ * DSA Art. 26 makes it mandatory, the serializer puts it on every item under
16
+ * every sort, and a storefront where some lists show it and some do not is
17
+ * legally worse than one that never showed it. `renderCard` receives the whole
18
+ * item so the marking is always reachable, and this default renders it.
19
+ *
20
+ * ── Two things this card used to get wrong ────────────────────────────────
21
+ *
22
+ * 1. **It declared `image_url` and drew nothing.** A text-only card in a
23
+ * classifieds search is not a card; the field was in `GENERIC_CARD_FIELDS`
24
+ * and in no render path. It is drawn now, through `@stapel/image`, so the
25
+ * aspect box lands before the network does and a dead URL renders a named
26
+ * placeholder instead of the browser's torn-page icon.
27
+ * 2. **The marking's EXPLANATION was in a `Tooltip`.** Touch has no hover, so
28
+ * on the device most of this traffic arrives from, the sentence the law is
29
+ * actually about was unreachable — the tag said "Promoted" and nothing on
30
+ * screen said what that meant. It is ordinary text under the tag now
31
+ * (`stapel/no-tooltip-in-skin`), and the tag itself is a `--stapel-*` role
32
+ * rather than an antd preset, because the one legally-mandated marking in
33
+ * the pair has to look the same in every skin a deployment builds.
34
+ * 3. **The tag was white on cream.** `warning-on` is the text colour for the
35
+ * SOLID warning fill; over `warning-bg` the readable role is `warning`
36
+ * itself. The visual pass measured the one legally-mandated string in the
37
+ * package at roughly 1.2:1 — a disclosure nobody can read is the same as
38
+ * no disclosure, in both themes.
39
+ * 4. **The price was a raw amount and an ISO code.** "3200 RUB" is a wire
40
+ * value printed as prose: no grouping, no symbol, and the code in the
41
+ * reader's face. It goes through core's `useFormat().number` with
42
+ * `style: "currency"`, which is the same `Intl` path `@stapel/currencies-
43
+ * react`'s `formatMoney` takes — this pair does not depend on that package
44
+ * (a search index is not a price book) but it must not invent a second
45
+ * way to write money either.
46
+ */
47
+ import { useMemo } from "react";
48
+ import { Card, Flex, Typography } from "antd";
49
+ import { Image } from "@stapel/image";
50
+ import { useFormat, useT } from "@stapel/core";
51
+ import { cssVar, fontSize, fontWeight, radii, spacing } from "@stapel/tokens";
4
52
  import { SEARCH_I18N_KEYS } from "../i18n/keys.js";
5
53
  function text(value) {
6
54
  if (typeof value === "string" && value.length > 0)
@@ -20,19 +68,144 @@ export const GENERIC_CARD_FIELDS = [
20
68
  "currency",
21
69
  "location",
22
70
  "image_url",
71
+ "url",
23
72
  ];
73
+ /**
74
+ * The card's price, written the way money is written.
75
+ *
76
+ * `card.price` arrives as a string because the index stores it as one, and
77
+ * `card.currency` as an ISO 4217 code because that is what a document carries.
78
+ * Rendered verbatim they read "3200 RUB": no grouping, the code where the
79
+ * symbol belongs, and the reader doing the arithmetic of where the thousands
80
+ * are. `Intl` knows all of that per locale, so the code goes in and the
81
+ * locale's own rendering comes out.
82
+ *
83
+ * Two ways this refuses to guess. A `price` that is not a finite number is
84
+ * passed through UNCHANGED — a doc type may store "on request", and turning
85
+ * that into `NaN` or into nothing loses what the seller wrote. A `currency`
86
+ * that is not a three-letter code (or one this runtime rejects) falls back to
87
+ * the plain grouped number plus the code, which is still better than the raw
88
+ * pair and never throws inside a render.
89
+ */
90
+ export function formatCardPrice(format, price, currency) {
91
+ if (price === undefined)
92
+ return undefined;
93
+ const amount = Number(price);
94
+ if (!Number.isFinite(amount))
95
+ return price;
96
+ if (currency !== undefined && /^[A-Za-z]{3}$/.test(currency)) {
97
+ try {
98
+ const money = format.number(amount, {
99
+ style: "currency",
100
+ currency: currency.toUpperCase(),
101
+ currencyDisplay: "narrowSymbol",
102
+ maximumFractionDigits: Number.isInteger(amount) ? 0 : 2,
103
+ });
104
+ if (money !== null)
105
+ return money;
106
+ }
107
+ catch {
108
+ // An unsupported currency code: fall through to the grouped number.
109
+ }
110
+ }
111
+ const grouped = format.number(amount);
112
+ if (grouped === null)
113
+ return price;
114
+ return currency === undefined ? grouped : `${grouped} ${currency}`;
115
+ }
116
+ /**
117
+ * The DSA Art. 26 marking, as a token role.
118
+ *
119
+ * `warning` is the §68 dictionary's "look at this, it is not an error" role —
120
+ * the same one every skin in the fleet resolves from its own theme JSON. The
121
+ * previous `<Tag color="gold">` was an antd PRESET: it survived a retheme
122
+ * unchanged, so a deployment with its own palette had one component still
123
+ * painted in Ant Design's gold, and the one marking that must be recognisable
124
+ * everywhere was the one thing the design system did not own.
125
+ */
126
+ const PROMOTED_TAG = {
127
+ alignSelf: "flex-start",
128
+ background: cssVar("warning-bg"),
129
+ // `warning`, not `warning-on`: the latter is the text colour for the SOLID
130
+ // warning fill (white on light), and over `warning-bg` it is cream on cream.
131
+ color: cssVar("warning"),
132
+ fontWeight: fontWeight.medium,
133
+ border: `1px solid ${cssVar("warning-border")}`,
134
+ borderRadius: radii.sm,
135
+ padding: `0 ${String(spacing[2])}px`,
136
+ fontSize: fontSize.xs.fontSize,
137
+ lineHeight: `${String(fontSize.md.lineHeight)}px`,
138
+ whiteSpace: "nowrap",
139
+ };
140
+ /** The photo's box: a 4:3 well the image fills, drawn before it loads. */
141
+ const PHOTO = {
142
+ width: "100%",
143
+ aspectRatio: "4 / 3",
144
+ overflow: "hidden",
145
+ borderRadius: radii.md,
146
+ background: cssVar("surface-sunken"),
147
+ };
148
+ /**
149
+ * A plain `image_url` as the descriptor `<Image>` consumes.
150
+ *
151
+ * A doc type that stores a bare URL has no variant ladder and no dimensions —
152
+ * `source: "link"` is exactly that case, and `<Image>` degrades to the single
153
+ * URL rather than pretending to shop a tier. A doc type that stores the whole
154
+ * `StapelImage` snapshot (`card.image`) gets the ladder, blur-up and all.
155
+ */
156
+ function cardImage(card) {
157
+ const rich = card["image"];
158
+ if (rich !== null && typeof rich === "object" && "url" in rich) {
159
+ return rich;
160
+ }
161
+ const url = text(card["image_url"]);
162
+ if (url === undefined)
163
+ return undefined;
164
+ return {
165
+ source: "link",
166
+ url,
167
+ mime: null,
168
+ width: null,
169
+ height: null,
170
+ aspect: null,
171
+ square: false,
172
+ preview_b64: null,
173
+ variants: [],
174
+ };
175
+ }
176
+ /**
177
+ * The whole card as ONE tap target.
178
+ *
179
+ * A catalogue row is a link — the person taps the picture, the title or the
180
+ * price and expects the same thing to happen. The card used to have no
181
+ * clickable anything at all: the entire result page of a storefront that had
182
+ * not passed `renderCard` was a wall of text with the tap target missing
183
+ * (class C-NOPRIMARY). `card.url` is the conventional field a doc type stores
184
+ * it in; without one the card stays exactly what it was, because inventing a
185
+ * destination is worse than not having one.
186
+ */
187
+ const CARD_LINK = {
188
+ color: "inherit",
189
+ display: "block",
190
+ textDecoration: "none",
191
+ };
24
192
  export function SearchResultCard(props) {
25
193
  const t = useT();
194
+ const format = useFormat();
26
195
  const card = props.item.card;
27
196
  const title = text(card["title"]) ?? t(SEARCH_I18N_KEYS.resultsUntitled);
28
- const price = text(card["price"]);
29
- const currency = text(card["currency"]);
197
+ const price = formatCardPrice(format, text(card["price"]), text(card["currency"]));
198
+ const href = text(card["url"]);
30
199
  const location = text(card["location"]);
31
200
  const distance = props.item.distance_km !== null
32
201
  ? t(SEARCH_I18N_KEYS.resultsDistanceKm, {
33
202
  km: props.item.distance_km.toFixed(1),
34
203
  })
35
204
  : undefined;
36
- return (_jsx(Card, { size: "small", "data-testid": "search-result-card", "data-promoted": props.item.promoted ? "true" : "false", children: _jsxs(Flex, { vertical: true, gap: 4, children: [_jsxs(Flex, { justify: "space-between", align: "start", gap: 8, children: [_jsx(Typography.Text, { strong: true, children: title }), props.item.promoted && (_jsx(Tooltip, { title: t(SEARCH_I18N_KEYS.resultsPromotedHint), children: _jsx(Tag, { color: "gold", "data-testid": "search-result-promoted", children: t(SEARCH_I18N_KEYS.resultsPromoted) }) }))] }), price !== undefined && (_jsx(Typography.Text, { children: currency !== undefined ? `${price} ${currency}` : price })), (location !== undefined || distance !== undefined) && (_jsx(Typography.Text, { type: "secondary", children: [location, distance].filter((v) => v !== undefined).join(" · ") }))] }) }));
205
+ // Memoised on the two fields it reads: a fresh `meta` identity every render
206
+ // is a load `<Image>` has to decide is or is not the same one.
207
+ const image = useMemo(() => cardImage(card), [card]);
208
+ const body = (_jsxs(Flex, { vertical: true, gap: spacing[2], children: [image !== undefined && (_jsx("div", { style: PHOTO, "data-testid": "search-result-photo", children: _jsx(Image, { meta: image, alt: t(SEARCH_I18N_KEYS.resultsImageAlt, { title }), fit: "cover", style: { width: "100%", height: "100%" } }) })), _jsxs(Flex, { vertical: true, gap: spacing[1], children: [_jsx(Typography.Text, { strong: true, children: title }), price !== undefined && (_jsx(Typography.Text, { strong: true, style: { fontSize: fontSize.lg.fontSize }, "data-testid": "search-result-price", children: price })), (location !== undefined || distance !== undefined) && (_jsx(Typography.Text, { type: "secondary", children: [location, distance].filter((v) => v !== undefined).join(" · ") }))] })] }));
209
+ return (_jsx(Card, { size: "small", "data-testid": "search-result-card", "data-promoted": props.item.promoted ? "true" : "false", ...(href !== undefined ? { hoverable: true } : {}), styles: { body: { padding: spacing[3] } }, children: _jsxs(Flex, { vertical: true, gap: spacing[2], children: [href === undefined ? (body) : (_jsx("a", { href: href, style: CARD_LINK, "data-testid": "search-result-link", children: body })), props.item.promoted && (_jsxs(Flex, { vertical: true, gap: spacing[1], "data-testid": "search-result-promotion", children: [_jsx("span", { style: PROMOTED_TAG, "data-testid": "search-result-promoted", children: t(SEARCH_I18N_KEYS.resultsPromoted) }), _jsx(Typography.Text, { type: "secondary", style: { fontSize: fontSize.xs.fontSize }, "data-testid": "search-result-promoted-hint", children: t(SEARCH_I18N_KEYS.resultsPromotedHint) })] }))] }) }));
37
210
  }
38
211
  //# sourceMappingURL=SearchResultCard.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"SearchResultCard.js","sourceRoot":"","sources":["../../src/default/SearchResultCard.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"SearchResultCard.js","sourceRoot":"","sources":["../../src/default/SearchResultCard.tsx"],"names":[],"mappings":"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"}
@@ -2,9 +2,9 @@
2
2
  * `<SearchResultsPane>` — the antd result page: the count, the degradation
3
3
  * banner, the cards, and the keyset controls.
4
4
  *
5
- * Rendered through core's `matchList`, whose FOUR required arms are the point.
6
- * "Nothing matches this search" is reachable only from a search that actually
7
- * ran; a 5xx renders "we could not run this search" plus a retry. The
5
+ * Rendered through the shared substrate's `LoadList`, whose FOUR arms are the
6
+ * point. "Nothing matches this search" is reachable only from a search that
7
+ * actually ran; a 5xx renders "we could not run this search" plus a retry. The
8
8
  * substitution of one for the other is what cost the 2026-08-09 incident, and
9
9
  * the spec's §7.4 negative leg exercises this exact pane against a forced 5xx.
10
10
  *
@@ -12,11 +12,23 @@
12
12
  * is "narrow the search", not "there is nothing here" — it arrives as a 400
13
13
  * with an empty body, which is precisely how it would otherwise render as an
14
14
  * empty page.
15
+ *
16
+ * ── Two things the pager used to get wrong ────────────────────────────────
17
+ *
18
+ * 1. **Its reasons were in `title=`.** A disabled antd Button receives no
19
+ * pointer events, so the browser tooltip never fires — on any device — and
20
+ * a phone has no hover to begin with. Both buttons are `GatedButton` now:
21
+ * the block's reason is ordinary text beside the control and the button's
22
+ * `aria-describedby` points at it.
23
+ * 2. **It rendered when there was nothing to page.** Two dead buttons under an
24
+ * empty state is the fleet's C-DEADPAGER defect; the pager now appears only
25
+ * when the answer actually has another page in some direction.
15
26
  */
16
27
  import type { ReactElement, ReactNode } from "react";
17
28
  import type { SearchItem } from "../api/types.js";
18
29
  import type { DegradationNoticeVariant } from "./DegradationNotice.js";
19
30
  import type { SearchCardRenderer } from "./SearchResultCard.js";
31
+ import type { SearchResultsLayout } from "./ViewSwitch.js";
20
32
  import type { ThemeModeProp } from "./types.js";
21
33
  /**
22
34
  * The whole result LAYOUT, for a container that wants its own — a map beside
@@ -26,6 +38,16 @@ import type { ThemeModeProp } from "./types.js";
26
38
  * problem.
27
39
  */
28
40
  export type SearchResultsRenderer = (items: readonly SearchItem[]) => ReactNode;
41
+ /**
42
+ * The widest a column of results is allowed to get.
43
+ *
44
+ * Off the spacing scale and named for it: it is a MEASURE, the reading-width
45
+ * decision every long page has to take. Without it the pane spread the full
46
+ * width of whatever it was dropped into — the visual pass measured a 2560px
47
+ * pane with four cards floating at the top of it and a status row 1350px from
48
+ * the buttons that act on it (class C-NOMAXW).
49
+ */
50
+ export declare const RESULTS_MAX_WIDTH = 1120;
29
51
  export interface SearchResultsPaneProps extends ThemeModeProp {
30
52
  /**
31
53
  * The card slot (spec §6.2 item 1). A storefront passes
@@ -45,6 +67,21 @@ export interface SearchResultsPaneProps extends ThemeModeProp {
45
67
  * toolbar in here instead of printing a second caption above the pane.
46
68
  */
47
69
  readonly toolbar?: ReactNode;
70
+ /**
71
+ * What this list is CALLED on this surface. Default: "Results".
72
+ *
73
+ * The pane owning the heading row is what stops a screen printing two
74
+ * captions — but "Results" is only the right word when the person performed
75
+ * a search. A landing's newest-first strip is "Fresh listings"; a seller's
76
+ * page is "This seller's listings"; a category page's is the category. Every
77
+ * one of those surfaces had written its own `<Title>` above the pane and got
78
+ * the pane's "Results" underneath it a moment later — two headings, one
79
+ * list, on the three busiest screens of the storefront.
80
+ *
81
+ * So the name comes IN, to the row that already exists, instead of being
82
+ * printed a second time above it. Still exactly one heading either way.
83
+ */
84
+ readonly heading?: ReactNode;
48
85
  /** Rendered under the pager — where the container puts the ranking link. */
49
86
  readonly footer?: ReactNode;
50
87
  /**
@@ -59,6 +96,27 @@ export interface SearchResultsPaneProps extends ThemeModeProp {
59
96
  */
60
97
  readonly degradationNotice?: DegradationNoticeVariant;
61
98
  readonly enabled?: boolean;
99
+ /** Widest the column of results may grow (default {@link RESULTS_MAX_WIDTH});
100
+ * `null` lets the container decide. */
101
+ readonly maxWidth?: number | null;
102
+ /**
103
+ * How the loaded rows are arranged: as many card columns as fit
104
+ * (`"grid"`, the default) or one wide row each (`"list"`). The view SWITCH
105
+ * that flips this lives in `<ViewSwitch>`; the pane only draws.
106
+ *
107
+ * Ignored when `renderResults` replaces the arrangement entirely.
108
+ */
109
+ readonly layout?: SearchResultsLayout;
110
+ /**
111
+ * Heading level for the results caption. Default `4`, which is what every
112
+ * surface that EMBEDS this pane under its own title needs.
113
+ *
114
+ * `<SearchPage>` passes `1`: on a results SCREEN the list's name is the
115
+ * page's heading, and a page whose only heading is an `<h4>` has a document
116
+ * outline that starts three levels down — the thing a screen reader's
117
+ * heading list is for.
118
+ */
119
+ readonly headingLevel?: 1 | 2 | 3 | 4 | 5;
62
120
  }
63
121
  export declare function SearchResultsPane(props: SearchResultsPaneProps): ReactElement;
64
122
  //# sourceMappingURL=SearchResultsPane.d.ts.map