@stapel/search-react 0.1.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.
- package/CHANGELOG.md +1 -0
- package/MODULE.md +203 -0
- package/README.md +175 -0
- package/dist/api/generated/schema.d.ts +375 -0
- package/dist/api/generated/schema.d.ts.map +1 -0
- package/dist/api/generated/schema.js +2 -0
- package/dist/api/generated/schema.js.map +1 -0
- package/dist/api/searchApi.d.ts +77 -0
- package/dist/api/searchApi.d.ts.map +1 -0
- package/dist/api/searchApi.js +79 -0
- package/dist/api/searchApi.js.map +1 -0
- package/dist/api/types.d.ts +131 -0
- package/dist/api/types.d.ts.map +1 -0
- package/dist/api/types.js +20 -0
- package/dist/api/types.js.map +1 -0
- package/dist/default/DegradationNotice.d.ts +19 -0
- package/dist/default/DegradationNotice.d.ts.map +1 -0
- package/dist/default/DegradationNotice.js +14 -0
- package/dist/default/DegradationNotice.js.map +1 -0
- package/dist/default/ErrorAlert.d.ts +9 -0
- package/dist/default/ErrorAlert.d.ts.map +1 -0
- package/dist/default/ErrorAlert.js +27 -0
- package/dist/default/ErrorAlert.js.map +1 -0
- package/dist/default/FacetPanelPane.d.ts +26 -0
- package/dist/default/FacetPanelPane.d.ts.map +1 -0
- package/dist/default/FacetPanelPane.js +32 -0
- package/dist/default/FacetPanelPane.js.map +1 -0
- package/dist/default/RankingDisclosurePane.d.ts +17 -0
- package/dist/default/RankingDisclosurePane.d.ts.map +1 -0
- package/dist/default/RankingDisclosurePane.js +23 -0
- package/dist/default/RankingDisclosurePane.js.map +1 -0
- package/dist/default/SearchPage.d.ts +34 -0
- package/dist/default/SearchPage.d.ts.map +1 -0
- package/dist/default/SearchPage.js +16 -0
- package/dist/default/SearchPage.js.map +1 -0
- package/dist/default/SearchResultCard.d.ts +34 -0
- package/dist/default/SearchResultCard.d.ts.map +1 -0
- package/dist/default/SearchResultCard.js +38 -0
- package/dist/default/SearchResultCard.js.map +1 -0
- package/dist/default/SearchResultsPane.d.ts +32 -0
- package/dist/default/SearchResultsPane.d.ts.map +1 -0
- package/dist/default/SearchResultsPane.js +46 -0
- package/dist/default/SearchResultsPane.js.map +1 -0
- package/dist/default/SortSelect.d.ts +22 -0
- package/dist/default/SortSelect.d.ts.map +1 -0
- package/dist/default/SortSelect.js +39 -0
- package/dist/default/SortSelect.js.map +1 -0
- package/dist/default/UrlIssueNotice.d.ts +12 -0
- package/dist/default/UrlIssueNotice.d.ts.map +1 -0
- package/dist/default/UrlIssueNotice.js +13 -0
- package/dist/default/UrlIssueNotice.js.map +1 -0
- package/dist/default/index.d.ts +40 -0
- package/dist/default/index.d.ts.map +1 -0
- package/dist/default/index.js +34 -0
- package/dist/default/index.js.map +1 -0
- package/dist/default/theme.d.ts +24 -0
- package/dist/default/theme.d.ts.map +1 -0
- package/dist/default/theme.js +39 -0
- package/dist/default/theme.js.map +1 -0
- package/dist/default/types.d.ts +12 -0
- package/dist/default/types.d.ts.map +1 -0
- package/dist/default/types.js +2 -0
- package/dist/default/types.js.map +1 -0
- package/dist/headless/FacetPanel.d.ts +61 -0
- package/dist/headless/FacetPanel.d.ts.map +1 -0
- package/dist/headless/FacetPanel.js +57 -0
- package/dist/headless/FacetPanel.js.map +1 -0
- package/dist/headless/RankingDisclosure.d.ts +39 -0
- package/dist/headless/RankingDisclosure.d.ts.map +1 -0
- package/dist/headless/RankingDisclosure.js +28 -0
- package/dist/headless/RankingDisclosure.js.map +1 -0
- package/dist/headless/SearchProvider.d.ts +19 -0
- package/dist/headless/SearchProvider.d.ts.map +1 -0
- package/dist/headless/SearchProvider.js +15 -0
- package/dist/headless/SearchProvider.js.map +1 -0
- package/dist/headless/SearchResults.d.ts +68 -0
- package/dist/headless/SearchResults.d.ts.map +1 -0
- package/dist/headless/SearchResults.js +70 -0
- package/dist/headless/SearchResults.js.map +1 -0
- package/dist/headless/SearchStateProvider.d.ts +69 -0
- package/dist/headless/SearchStateProvider.d.ts.map +1 -0
- package/dist/headless/SearchStateProvider.js +71 -0
- package/dist/headless/SearchStateProvider.js.map +1 -0
- package/dist/i18n/errorsMap.d.ts +27 -0
- package/dist/i18n/errorsMap.d.ts.map +1 -0
- package/dist/i18n/errorsMap.js +37 -0
- package/dist/i18n/errorsMap.js.map +1 -0
- package/dist/i18n/es.d.ts +13 -0
- package/dist/i18n/es.d.ts.map +1 -0
- package/dist/i18n/es.js +85 -0
- package/dist/i18n/es.js.map +1 -0
- package/dist/i18n/generated/errors.es.gen.d.ts +9 -0
- package/dist/i18n/generated/errors.es.gen.d.ts.map +1 -0
- package/dist/i18n/generated/errors.es.gen.js +63 -0
- package/dist/i18n/generated/errors.es.gen.js.map +1 -0
- package/dist/i18n/generated/errors.gen.d.ts +359 -0
- package/dist/i18n/generated/errors.gen.d.ts.map +1 -0
- package/dist/i18n/generated/errors.gen.js +183 -0
- package/dist/i18n/generated/errors.gen.js.map +1 -0
- package/dist/i18n/generated/errors.ru.gen.d.ts +9 -0
- package/dist/i18n/generated/errors.ru.gen.d.ts.map +1 -0
- package/dist/i18n/generated/errors.ru.gen.js +63 -0
- package/dist/i18n/generated/errors.ru.gen.js.map +1 -0
- package/dist/i18n/keys.d.ts +107 -0
- package/dist/i18n/keys.d.ts.map +1 -0
- package/dist/i18n/keys.js +185 -0
- package/dist/i18n/keys.js.map +1 -0
- package/dist/i18n/ru.d.ts +29 -0
- package/dist/i18n/ru.d.ts.map +1 -0
- package/dist/i18n/ru.js +101 -0
- package/dist/i18n/ru.js.map +1 -0
- package/dist/index.d.ts +72 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +66 -0
- package/dist/index.js.map +1 -0
- package/dist/model/context.d.ts +11 -0
- package/dist/model/context.d.ts.map +1 -0
- package/dist/model/context.js +16 -0
- package/dist/model/context.js.map +1 -0
- package/dist/model/queries.d.ts +48 -0
- package/dist/model/queries.d.ts.map +1 -0
- package/dist/model/queries.js +65 -0
- package/dist/model/queries.js.map +1 -0
- package/dist/model/queryKeys.d.ts +25 -0
- package/dist/model/queryKeys.d.ts.map +1 -0
- package/dist/model/queryKeys.js +22 -0
- package/dist/model/queryKeys.js.map +1 -0
- package/dist/model/runtime.d.ts +25 -0
- package/dist/model/runtime.d.ts.map +1 -0
- package/dist/model/runtime.js +6 -0
- package/dist/model/runtime.js.map +1 -0
- package/dist/nav/manifest.d.ts +21 -0
- package/dist/nav/manifest.d.ts.map +1 -0
- package/dist/nav/manifest.js +34 -0
- package/dist/nav/manifest.js.map +1 -0
- package/dist/router/index.d.ts +10 -0
- package/dist/router/index.d.ts.map +1 -0
- package/dist/router/index.js +34 -0
- package/dist/router/index.js.map +1 -0
- package/dist/state/degradations.d.ts +30 -0
- package/dist/state/degradations.d.ts.map +1 -0
- package/dist/state/degradations.js +52 -0
- package/dist/state/degradations.js.map +1 -0
- package/dist/state/facets.d.ts +68 -0
- package/dist/state/facets.d.ts.map +1 -0
- package/dist/state/facets.js +171 -0
- package/dist/state/facets.js.map +1 -0
- package/dist/state/urlState.d.ts +143 -0
- package/dist/state/urlState.d.ts.map +1 -0
- package/dist/state/urlState.js +319 -0
- package/dist/state/urlState.js.map +1 -0
- package/llms.txt +87 -0
- package/manifest.json +652 -0
- package/nav-manifest.json +44 -0
- package/package.json +133 -0
- package/src/analytics/generated/events.json +7 -0
- package/src/api/generated/schema.ts +377 -0
- package/src/api/searchApi.ts +169 -0
- package/src/api/types.ts +160 -0
- package/src/default/DegradationNotice.tsx +50 -0
- package/src/default/ErrorAlert.tsx +46 -0
- package/src/default/FacetPanelPane.tsx +174 -0
- package/src/default/RankingDisclosurePane.tsx +116 -0
- package/src/default/SearchPage.tsx +87 -0
- package/src/default/SearchResultCard.tsx +96 -0
- package/src/default/SearchResultsPane.tsx +173 -0
- package/src/default/SortSelect.tsx +77 -0
- package/src/default/UrlIssueNotice.tsx +37 -0
- package/src/default/index.ts +48 -0
- package/src/default/theme.tsx +66 -0
- package/src/default/types.ts +12 -0
- package/src/headless/FacetPanel.tsx +113 -0
- package/src/headless/RankingDisclosure.tsx +58 -0
- package/src/headless/SearchProvider.tsx +20 -0
- package/src/headless/SearchResults.tsx +149 -0
- package/src/headless/SearchStateProvider.tsx +175 -0
- package/src/i18n/errorsMap.ts +50 -0
- package/src/i18n/es.ts +110 -0
- package/src/i18n/generated/errors.es.gen.ts +69 -0
- package/src/i18n/generated/errors.gen.ts +214 -0
- package/src/i18n/generated/errors.json +423 -0
- package/src/i18n/generated/errors.ru.gen.ts +69 -0
- package/src/i18n/keys.ts +220 -0
- package/src/i18n/ru.ts +126 -0
- package/src/index.ts +154 -0
- package/src/model/context.tsx +28 -0
- package/src/model/queries.ts +79 -0
- package/src/model/queryKeys.ts +48 -0
- package/src/model/runtime.ts +33 -0
- package/src/nav/manifest.ts +53 -0
- package/src/router/index.ts +38 -0
- package/src/state/degradations.ts +75 -0
- package/src/state/facets.ts +219 -0
- package/src/state/urlState.ts +458 -0
- package/tsconfig.json +26 -0
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Button, Empty, Flex, Spin, Typography } from "antd";
|
|
3
|
+
import { errorCode, matchList, toFlowError, useDescribeFlowError, useT, } from "@stapel/core";
|
|
4
|
+
import { SearchResults } from "../headless/SearchResults.js";
|
|
5
|
+
import { SEARCH_WINDOW_EXCEEDED } from "../i18n/errorsMap.js";
|
|
6
|
+
import { SEARCH_I18N_KEYS } from "../i18n/keys.js";
|
|
7
|
+
import { DegradationNotice } from "./DegradationNotice.js";
|
|
8
|
+
import { ErrorAlert } from "./ErrorAlert.js";
|
|
9
|
+
import { SearchResultCard } from "./SearchResultCard.js";
|
|
10
|
+
import { SearchSkinTheme } from "./theme.js";
|
|
11
|
+
function Count(props) {
|
|
12
|
+
const t = useT();
|
|
13
|
+
const page = props.bag.page;
|
|
14
|
+
if (page === null)
|
|
15
|
+
return null;
|
|
16
|
+
return (_jsx(Typography.Text, { type: "secondary", "data-testid": "search-count", children: page.countIsEstimate
|
|
17
|
+
? t(SEARCH_I18N_KEYS.resultsCountApproximate, { count: page.count })
|
|
18
|
+
: t(SEARCH_I18N_KEYS.resultsCountExact, { count: page.count }) }));
|
|
19
|
+
}
|
|
20
|
+
function Pager(props) {
|
|
21
|
+
const t = useT();
|
|
22
|
+
const { prev, next, goPrev, goNext } = props.bag;
|
|
23
|
+
return (_jsxs(Flex, { gap: 8, justify: "center", "data-testid": "search-pager", children: [_jsx(Button, { disabled: !prev.available, title: prev.available ? undefined : t(prev.block.code, prev.block.params), onClick: goPrev, "data-analytics": "none", "data-analytics-reason": "keyset paging is a read, not a flow step", "data-testid": "search-prev", children: t(SEARCH_I18N_KEYS.resultsPrev) }), _jsx(Button, { disabled: !next.available, title: next.available ? undefined : t(next.block.code, next.block.params), onClick: goNext, "data-analytics": "none", "data-analytics-reason": "keyset paging is a read, not a flow step", "data-testid": "search-next", children: t(SEARCH_I18N_KEYS.resultsNext) })] }));
|
|
24
|
+
}
|
|
25
|
+
export function SearchResultsPane(props) {
|
|
26
|
+
const t = useT();
|
|
27
|
+
const describe = useDescribeFlowError();
|
|
28
|
+
const renderCard = props.renderCard;
|
|
29
|
+
return (_jsx(SearchSkinTheme, { ...(props.mode !== undefined ? { mode: props.mode } : {}), children: _jsx(SearchResults, { ...(props.enabled !== undefined ? { enabled: props.enabled } : {}), children: (bag) => (_jsxs(Flex, { vertical: true, gap: 16, children: [_jsxs(Flex, { justify: "space-between", align: "center", wrap: true, gap: 8, children: [_jsx(Typography.Title, { level: 4, style: { margin: 0 }, children: t(SEARCH_I18N_KEYS.resultsTitle) }), _jsx(Count, { bag: bag })] }), _jsx(DegradationNotice, { degradations: bag.degradations }), matchList(bag.state, {
|
|
30
|
+
loading: () => (_jsx(Flex, { justify: "center", style: { padding: 24 }, children: _jsx(Spin, { "data-testid": "search-loading" }) })),
|
|
31
|
+
failed: (error) => {
|
|
32
|
+
// The window refusal is a DIFFERENT sentence from a failed
|
|
33
|
+
// search, and both are different from "nothing found".
|
|
34
|
+
const isWindow = errorCode(error) === SEARCH_WINDOW_EXCEEDED;
|
|
35
|
+
return (_jsx(ErrorAlert, { testId: isWindow ? "search-window-exceeded" : "search-failed", error: {
|
|
36
|
+
...describe(toFlowError(error)),
|
|
37
|
+
message: t(isWindow
|
|
38
|
+
? SEARCH_I18N_KEYS.resultsWindowExceeded
|
|
39
|
+
: SEARCH_I18N_KEYS.resultsLoadFailed),
|
|
40
|
+
}, action: _jsx(Button, { size: "small", onClick: bag.refetch, "data-analytics": "none", "data-analytics-reason": "retry of a failed read; no flow to step", children: t(SEARCH_I18N_KEYS.resultsRetry) }) }));
|
|
41
|
+
},
|
|
42
|
+
empty: () => (_jsx(Empty, { "data-testid": "search-empty", description: t(SEARCH_I18N_KEYS.resultsEmpty) })),
|
|
43
|
+
ready: (items) => (_jsx(Flex, { vertical: true, gap: 12, "data-testid": "search-results", children: items.map((item) => (_jsx("div", { children: renderCard !== undefined ? (renderCard(item)) : (_jsx(SearchResultCard, { item: item })) }, item.key))) })),
|
|
44
|
+
}), _jsx(Pager, { bag: bag }), props.footer] })) }) }));
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=SearchResultsPane.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SearchResultsPane.js","sourceRoot":"","sources":["../../src/default/SearchResultsPane.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The sort control.
|
|
3
|
+
*
|
|
4
|
+
* The options are the shipped `SORTS` list, NOT an enum from the schema —
|
|
5
|
+
* `docs/schema.json` declares none, and a deployment may register more. So a
|
|
6
|
+
* value the URL already carries that is not in the list is still offered as a
|
|
7
|
+
* (raw) option rather than silently reset: resetting it would rewrite a
|
|
8
|
+
* shared link's meaning on load, and the server is the one entitled to refuse
|
|
9
|
+
* an unknown sort (`error.400.search_unknown_sort`, which names it).
|
|
10
|
+
*
|
|
11
|
+
* `sort=distance` needs a centre — the server answers
|
|
12
|
+
* `error.400.search_sort_needs_center` without one. The option is therefore
|
|
13
|
+
* DISABLED with the reason named when no geo centre is set, rather than
|
|
14
|
+
* offered and then refused.
|
|
15
|
+
*/
|
|
16
|
+
import type { ReactElement } from "react";
|
|
17
|
+
export interface SortSelectProps {
|
|
18
|
+
/** The sort the SERVER applied, shown when the URL names none. */
|
|
19
|
+
readonly appliedSort?: string | undefined;
|
|
20
|
+
}
|
|
21
|
+
export declare function SortSelect(props: SortSelectProps): ReactElement;
|
|
22
|
+
//# sourceMappingURL=SortSelect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SortSelect.d.ts","sourceRoot":"","sources":["../../src/default/SortSelect.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAe1C,MAAM,WAAW,eAAe;IAC9B,kEAAkE;IAClE,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC3C;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,eAAe,GAAG,YAAY,CAyC/D"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Flex, Select, Typography } from "antd";
|
|
3
|
+
import { useT } from "@stapel/core";
|
|
4
|
+
import { SEARCH_SORTS } from "../api/types.js";
|
|
5
|
+
import { useSearchState } from "../headless/SearchStateProvider.js";
|
|
6
|
+
import { SEARCH_I18N_KEYS } from "../i18n/keys.js";
|
|
7
|
+
const SORT_LABEL_KEY = {
|
|
8
|
+
relevance: SEARCH_I18N_KEYS.sortRelevance,
|
|
9
|
+
newest: SEARCH_I18N_KEYS.sortNewest,
|
|
10
|
+
price_asc: SEARCH_I18N_KEYS.sortPriceAsc,
|
|
11
|
+
price_desc: SEARCH_I18N_KEYS.sortPriceDesc,
|
|
12
|
+
distance: SEARCH_I18N_KEYS.sortDistance,
|
|
13
|
+
};
|
|
14
|
+
export function SortSelect(props) {
|
|
15
|
+
const t = useT();
|
|
16
|
+
const { state, setSort } = useSearchState();
|
|
17
|
+
const hasCentre = state.geo !== undefined;
|
|
18
|
+
const known = new Set(SEARCH_SORTS);
|
|
19
|
+
const values = state.sort !== undefined && !known.has(state.sort)
|
|
20
|
+
? [...SEARCH_SORTS, state.sort]
|
|
21
|
+
: SEARCH_SORTS;
|
|
22
|
+
return (_jsxs(Flex, { gap: 8, align: "center", children: [_jsx(Typography.Text, { type: "secondary", children: t(SEARCH_I18N_KEYS.sortLabel) }), _jsx(Select, { "data-testid": "search-sort", style: { minWidth: 180 }, value: state.sort ?? props.appliedSort ?? null, placeholder: t(SEARCH_I18N_KEYS.sortLabel), onChange: (next) => {
|
|
23
|
+
setSort(next);
|
|
24
|
+
}, options: values.map((value) => {
|
|
25
|
+
const key = SORT_LABEL_KEY[value];
|
|
26
|
+
const needsCentre = value === "distance" && !hasCentre;
|
|
27
|
+
return {
|
|
28
|
+
value,
|
|
29
|
+
label: key !== undefined ? t(key) : value,
|
|
30
|
+
disabled: needsCentre,
|
|
31
|
+
// A disabled control states its reason (the ActionAvailability
|
|
32
|
+
// canon), even inside a select.
|
|
33
|
+
...(needsCentre
|
|
34
|
+
? { title: t("error.400.search_sort_needs_center") }
|
|
35
|
+
: {}),
|
|
36
|
+
};
|
|
37
|
+
}) })] }));
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=SortSelect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SortSelect.js","sourceRoot":"","sources":["../../src/default/SortSelect.tsx"],"names":[],"mappings":";AAgBA,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AAChD,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AACpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAEnD,MAAM,cAAc,GAAqC;IACvD,SAAS,EAAE,gBAAgB,CAAC,aAAa;IACzC,MAAM,EAAE,gBAAgB,CAAC,UAAU;IACnC,SAAS,EAAE,gBAAgB,CAAC,YAAY;IACxC,UAAU,EAAE,gBAAgB,CAAC,aAAa;IAC1C,QAAQ,EAAE,gBAAgB,CAAC,YAAY;CACxC,CAAC;AAOF,MAAM,UAAU,UAAU,CAAC,KAAsB;IAC/C,MAAM,CAAC,GAAG,IAAI,EAAE,CAAC;IACjB,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,cAAc,EAAE,CAAC;IAE5C,MAAM,SAAS,GAAG,KAAK,CAAC,GAAG,KAAK,SAAS,CAAC;IAC1C,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,YAAY,CAAC,CAAC;IACpC,MAAM,MAAM,GACV,KAAK,CAAC,IAAI,KAAK,SAAS,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC;QAChD,CAAC,CAAC,CAAC,GAAG,YAAY,EAAE,KAAK,CAAC,IAAI,CAAC;QAC/B,CAAC,CAAC,YAAY,CAAC;IAEnB,OAAO,CACL,MAAC,IAAI,IAAC,GAAG,EAAE,CAAC,EAAE,KAAK,EAAC,QAAQ,aAC1B,KAAC,UAAU,CAAC,IAAI,IAAC,IAAI,EAAC,WAAW,YAC9B,CAAC,CAAC,gBAAgB,CAAC,SAAS,CAAC,GACd,EAClB,KAAC,MAAM,mBACO,aAAa,EACzB,KAAK,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,EACxB,KAAK,EAAE,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,WAAW,IAAI,IAAI,EAC9C,WAAW,EAAE,CAAC,CAAC,gBAAgB,CAAC,SAAS,CAAC,EAC1C,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE;oBACjB,OAAO,CAAC,IAAI,CAAC,CAAC;gBAChB,CAAC,EACD,OAAO,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;oBAC5B,MAAM,GAAG,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;oBAClC,MAAM,WAAW,GAAG,KAAK,KAAK,UAAU,IAAI,CAAC,SAAS,CAAC;oBACvD,OAAO;wBACL,KAAK;wBACL,KAAK,EAAE,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK;wBACzC,QAAQ,EAAE,WAAW;wBACrB,+DAA+D;wBAC/D,gCAAgC;wBAChC,GAAG,CAAC,WAAW;4BACb,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,oCAAoC,CAAC,EAAE;4BACpD,CAAC,CAAC,EAAE,CAAC;qBACR,CAAC;gBACJ,CAAC,CAAC,GACF,IACG,CACR,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* "Part of this link could not be read."
|
|
3
|
+
*
|
|
4
|
+
* A shared search is a link somebody typed, edited, or truncated in a chat
|
|
5
|
+
* app. When the codec cannot read a parameter it reports the fact rather than
|
|
6
|
+
* dropping it silently — because the silent version WIDENS the search (a
|
|
7
|
+
* broken `lat` removes the location filter) and the person is then looking at
|
|
8
|
+
* something other than what was shared, with nothing on screen to say so.
|
|
9
|
+
*/
|
|
10
|
+
import type { ReactElement } from "react";
|
|
11
|
+
export declare function UrlIssueNotice(): ReactElement | null;
|
|
12
|
+
//# sourceMappingURL=UrlIssueNotice.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"UrlIssueNotice.d.ts","sourceRoot":"","sources":["../../src/default/UrlIssueNotice.tsx"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAM1C,wBAAgB,cAAc,IAAI,YAAY,GAAG,IAAI,CAqBpD"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Alert } from "antd";
|
|
3
|
+
import { useT } from "@stapel/core";
|
|
4
|
+
import { useSearchState } from "../headless/SearchStateProvider.js";
|
|
5
|
+
import { SEARCH_I18N_KEYS } from "../i18n/keys.js";
|
|
6
|
+
export function UrlIssueNotice() {
|
|
7
|
+
const t = useT();
|
|
8
|
+
const { issues } = useSearchState();
|
|
9
|
+
if (issues.length === 0)
|
|
10
|
+
return null;
|
|
11
|
+
return (_jsx(Alert, { type: "warning", showIcon: true, "data-testid": "search-url-issues", message: t(SEARCH_I18N_KEYS.urlIssuesTitle), description: _jsx("ul", { style: { margin: 0, paddingInlineStart: 20 }, children: issues.map((issue) => (_jsx("li", { children: t(issue.messageKey, { param: issue.param }) }, `${issue.param}:${issue.code}`))) }) }));
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=UrlIssueNotice.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"UrlIssueNotice.js","sourceRoot":"","sources":["../../src/default/UrlIssueNotice.tsx"],"names":[],"mappings":";AAUA,OAAO,EAAE,KAAK,EAAE,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AACpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAEnD,MAAM,UAAU,cAAc;IAC5B,MAAM,CAAC,GAAG,IAAI,EAAE,CAAC;IACjB,MAAM,EAAE,MAAM,EAAE,GAAG,cAAc,EAAE,CAAC;IACpC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACrC,OAAO,CACL,KAAC,KAAK,IACJ,IAAI,EAAC,SAAS,EACd,QAAQ,uBACI,mBAAmB,EAC/B,OAAO,EAAE,CAAC,CAAC,gBAAgB,CAAC,cAAc,CAAC,EAC3C,WAAW,EACT,aAAI,KAAK,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,kBAAkB,EAAE,EAAE,EAAE,YAC7C,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CACrB,uBACG,CAAC,CAAC,KAAK,CAAC,UAAU,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC,IADrC,GAAG,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,IAAI,EAAE,CAElC,CACN,CAAC,GACC,GAEP,CACH,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@stapel/search-react/default` — the antd default skin.
|
|
3
|
+
*
|
|
4
|
+
* A SEPARATE entry point on purpose: the main entry is headless and carries
|
|
5
|
+
* no antd, so a storefront that renders its own cards over `<SearchResults>`
|
|
6
|
+
* never pays for this bundle (enforced by size-limit and the bundle-purity
|
|
7
|
+
* test).
|
|
8
|
+
*
|
|
9
|
+
* Three override levers, none of which requires forking anything:
|
|
10
|
+
*
|
|
11
|
+
* 1. **`renderCard`** — the card slot. A storefront passes
|
|
12
|
+
* `<ListingCard>` from `@stapel/listings-react/default`; the generic card
|
|
13
|
+
* here is the documented default, not the intended end state (spec §3.7).
|
|
14
|
+
* 2. **`categoryFeatures`** — the facet-label slot. The server sends
|
|
15
|
+
* `{value: count}` and no labels; the schema that names them lives in
|
|
16
|
+
* categories, and the container hands it in (spec §6.2 item 2).
|
|
17
|
+
* 3. **retheming through the §68 token JSON** — every surface wraps itself
|
|
18
|
+
* in `<SearchSkinTheme>`, so a host's regenerated `--stapel-*` custom
|
|
19
|
+
* properties reach this skin with zero code.
|
|
20
|
+
*/
|
|
21
|
+
export { SearchPage } from "./SearchPage.js";
|
|
22
|
+
export type { SearchPageProps } from "./SearchPage.js";
|
|
23
|
+
export { SearchResultsPane } from "./SearchResultsPane.js";
|
|
24
|
+
export type { SearchResultsPaneProps } from "./SearchResultsPane.js";
|
|
25
|
+
export { FacetPanelPane } from "./FacetPanelPane.js";
|
|
26
|
+
export type { FacetPanelPaneProps } from "./FacetPanelPane.js";
|
|
27
|
+
export { RankingDisclosurePane } from "./RankingDisclosurePane.js";
|
|
28
|
+
export type { RankingDisclosurePaneProps } from "./RankingDisclosurePane.js";
|
|
29
|
+
export { SearchResultCard, GENERIC_CARD_FIELDS } from "./SearchResultCard.js";
|
|
30
|
+
export type { SearchCardProps, SearchCardRenderer } from "./SearchResultCard.js";
|
|
31
|
+
export { DegradationNotice } from "./DegradationNotice.js";
|
|
32
|
+
export type { DegradationNoticeProps } from "./DegradationNotice.js";
|
|
33
|
+
export { UrlIssueNotice } from "./UrlIssueNotice.js";
|
|
34
|
+
export { SortSelect } from "./SortSelect.js";
|
|
35
|
+
export type { SortSelectProps } from "./SortSelect.js";
|
|
36
|
+
export { ErrorAlert } from "./ErrorAlert.js";
|
|
37
|
+
export { SearchSkinTheme } from "./theme.js";
|
|
38
|
+
export type { SearchSkinThemeProps } from "./theme.js";
|
|
39
|
+
export type { ThemeModeProp } from "./types.js";
|
|
40
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/default/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAGH,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,YAAY,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAEvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,YAAY,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAErE,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,YAAY,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAE/D,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACnE,YAAY,EAAE,0BAA0B,EAAE,MAAM,4BAA4B,CAAC;AAG7E,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC9E,YAAY,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AACjF,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,YAAY,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AACrE,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,YAAY,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAG7C,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7C,YAAY,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AACvD,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@stapel/search-react/default` — the antd default skin.
|
|
3
|
+
*
|
|
4
|
+
* A SEPARATE entry point on purpose: the main entry is headless and carries
|
|
5
|
+
* no antd, so a storefront that renders its own cards over `<SearchResults>`
|
|
6
|
+
* never pays for this bundle (enforced by size-limit and the bundle-purity
|
|
7
|
+
* test).
|
|
8
|
+
*
|
|
9
|
+
* Three override levers, none of which requires forking anything:
|
|
10
|
+
*
|
|
11
|
+
* 1. **`renderCard`** — the card slot. A storefront passes
|
|
12
|
+
* `<ListingCard>` from `@stapel/listings-react/default`; the generic card
|
|
13
|
+
* here is the documented default, not the intended end state (spec §3.7).
|
|
14
|
+
* 2. **`categoryFeatures`** — the facet-label slot. The server sends
|
|
15
|
+
* `{value: count}` and no labels; the schema that names them lives in
|
|
16
|
+
* categories, and the container hands it in (spec §6.2 item 2).
|
|
17
|
+
* 3. **retheming through the §68 token JSON** — every surface wraps itself
|
|
18
|
+
* in `<SearchSkinTheme>`, so a host's regenerated `--stapel-*` custom
|
|
19
|
+
* properties reach this skin with zero code.
|
|
20
|
+
*/
|
|
21
|
+
// ── surfaces ────────────────────────────────────────────────────────────────
|
|
22
|
+
export { SearchPage } from "./SearchPage.js";
|
|
23
|
+
export { SearchResultsPane } from "./SearchResultsPane.js";
|
|
24
|
+
export { FacetPanelPane } from "./FacetPanelPane.js";
|
|
25
|
+
export { RankingDisclosurePane } from "./RankingDisclosurePane.js";
|
|
26
|
+
// ── parts, exported so a host can compose or wrap one ───────────────────────
|
|
27
|
+
export { SearchResultCard, GENERIC_CARD_FIELDS } from "./SearchResultCard.js";
|
|
28
|
+
export { DegradationNotice } from "./DegradationNotice.js";
|
|
29
|
+
export { UrlIssueNotice } from "./UrlIssueNotice.js";
|
|
30
|
+
export { SortSelect } from "./SortSelect.js";
|
|
31
|
+
export { ErrorAlert } from "./ErrorAlert.js";
|
|
32
|
+
// ── theming ─────────────────────────────────────────────────────────────────
|
|
33
|
+
export { SearchSkinTheme } from "./theme.js";
|
|
34
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/default/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,+EAA+E;AAC/E,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAG7C,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAG3D,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAGrD,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AAGnE,+EAA+E;AAC/E,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAE9E,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAE3D,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C,+EAA+E;AAC/E,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { CSSProperties, ReactElement, ReactNode } from "react";
|
|
2
|
+
import type { ThemeMode } from "@stapel/tokens-antd";
|
|
3
|
+
export interface SearchSkinThemeProps {
|
|
4
|
+
/**
|
|
5
|
+
* Light or dark. Defaults to the mode the host's document declares
|
|
6
|
+
* (`resolveThemeMode()`). Pass explicitly to pin a side.
|
|
7
|
+
*/
|
|
8
|
+
readonly mode?: ThemeMode;
|
|
9
|
+
/** Extra styles merged onto the themed root element (layout only — colors
|
|
10
|
+
* come from the mode). */
|
|
11
|
+
readonly style?: CSSProperties;
|
|
12
|
+
readonly children: ReactNode;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* `<SearchSkinTheme/>` — the self-theming wrapper of
|
|
16
|
+
* `@stapel/search-react/default`. Standalone use is supported (wrap any
|
|
17
|
+
* composition of the skin's parts once); the shipped surfaces
|
|
18
|
+
* (`SearchPage`, `SearchResultsPane`, `FacetPanelPane`,
|
|
19
|
+
* `RankingDisclosurePane`) each already wrap themselves, and nested antd
|
|
20
|
+
* `ConfigProvider`s merge, so composing them under one `SearchSkinTheme`
|
|
21
|
+
* stays correct.
|
|
22
|
+
*/
|
|
23
|
+
export declare function SearchSkinTheme(props: SearchSkinThemeProps): ReactElement;
|
|
24
|
+
//# sourceMappingURL=theme.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"theme.d.ts","sourceRoot":"","sources":["../../src/default/theme.tsx"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAOpE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAErD,MAAM,WAAW,oBAAoB;IACnC;;;OAGG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,CAAC;IAC1B;8BAC0B;IAC1B,QAAQ,CAAC,KAAK,CAAC,EAAE,aAAa,CAAC;IAC/B,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC;CAC9B;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,oBAAoB,GAAG,YAAY,CAmBzE"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* The default skin's INTERNAL theme provider — every `/default` surface wraps
|
|
4
|
+
* itself in this, so the skin is readable no matter what the host supplies
|
|
5
|
+
* (tracker #26: a skin set with no internal provider once inherited a theme
|
|
6
|
+
* bridge serving light-mode values inside a dark document — text on
|
|
7
|
+
* background at 1.00:1). The theme derives from `@stapel/tokens` via
|
|
8
|
+
* `@stapel/tokens-antd`'s `toAntdThemeConfig(mode)`; `mode` defaults to what
|
|
9
|
+
* the HOST's document declares (`resolveThemeMode()` — the `data-theme`
|
|
10
|
+
* attribute `tokens.css` keys its dark block on), never to a hardcoded side.
|
|
11
|
+
*
|
|
12
|
+
* This is also what "override styles" means for this pair: a storefront
|
|
13
|
+
* retheming through the §68 token JSON regenerates its `--stapel-*` custom
|
|
14
|
+
* properties and the result page follows with zero code — a far better deal
|
|
15
|
+
* than a prop-per-colour API, and the reason the skin has none.
|
|
16
|
+
*/
|
|
17
|
+
import { useMemo } from "react";
|
|
18
|
+
import { ConfigProvider } from "antd";
|
|
19
|
+
import { resolveThemeMode, toAntdTheme, toAntdThemeConfig, } from "@stapel/tokens-antd";
|
|
20
|
+
/**
|
|
21
|
+
* `<SearchSkinTheme/>` — the self-theming wrapper of
|
|
22
|
+
* `@stapel/search-react/default`. Standalone use is supported (wrap any
|
|
23
|
+
* composition of the skin's parts once); the shipped surfaces
|
|
24
|
+
* (`SearchPage`, `SearchResultsPane`, `FacetPanelPane`,
|
|
25
|
+
* `RankingDisclosurePane`) each already wrap themselves, and nested antd
|
|
26
|
+
* `ConfigProvider`s merge, so composing them under one `SearchSkinTheme`
|
|
27
|
+
* stays correct.
|
|
28
|
+
*/
|
|
29
|
+
export function SearchSkinTheme(props) {
|
|
30
|
+
const mode = props.mode ?? resolveThemeMode();
|
|
31
|
+
const theme = useMemo(() => toAntdThemeConfig(mode), [mode]);
|
|
32
|
+
const token = useMemo(() => toAntdTheme(mode), [mode]);
|
|
33
|
+
return (_jsx(ConfigProvider, { theme: theme, children: _jsx("div", { "data-search-skin-root": true, "data-search-skin-mode": mode, style: {
|
|
34
|
+
color: token.colorText,
|
|
35
|
+
backgroundColor: token.colorBgContainer,
|
|
36
|
+
...props.style,
|
|
37
|
+
}, children: props.children }) }));
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=theme.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"theme.js","sourceRoot":"","sources":["../../src/default/theme.tsx"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAEhC,OAAO,EAAE,cAAc,EAAE,MAAM,MAAM,CAAC;AACtC,OAAO,EACL,gBAAgB,EAChB,WAAW,EACX,iBAAiB,GAClB,MAAM,qBAAqB,CAAC;AAe7B;;;;;;;;GAQG;AACH,MAAM,UAAU,eAAe,CAAC,KAA2B;IACzD,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,IAAI,gBAAgB,EAAE,CAAC;IAC9C,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,iBAAiB,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;IAC7D,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;IACvD,OAAO,CACL,KAAC,cAAc,IAAC,KAAK,EAAE,KAAK,YAC1B,sEAEyB,IAAI,EAC3B,KAAK,EAAE;gBACL,KAAK,EAAE,KAAK,CAAC,SAAS;gBACtB,eAAe,EAAE,KAAK,CAAC,gBAAgB;gBACvC,GAAG,KAAK,CAAC,KAAK;aACf,YAEA,KAAK,CAAC,QAAQ,GACX,GACS,CAClB,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Small shared types for the `/default` skin — kept in one place so every
|
|
3
|
+
* surface takes the same `mode` prop and re-exports the same error dialect.
|
|
4
|
+
*/
|
|
5
|
+
export type { FlowError } from "@stapel/core";
|
|
6
|
+
import type { ThemeMode } from "@stapel/tokens-antd";
|
|
7
|
+
/** Every `/default` surface accepts a theme mode; absent means "whatever the
|
|
8
|
+
* host document declares" (`resolveThemeMode()`), never a hardcoded side. */
|
|
9
|
+
export interface ThemeModeProp {
|
|
10
|
+
readonly mode?: ThemeMode;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/default/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,YAAY,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAErD;6EAC6E;AAC7E,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,CAAC;CAC3B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/default/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
import type { LoadState } from "@stapel/core";
|
|
3
|
+
import type { FeatureDef } from "@stapel/attributes-react";
|
|
4
|
+
import type { SearchRange } from "../api/types.js";
|
|
5
|
+
import type { FacetGroup } from "../state/facets.js";
|
|
6
|
+
/** The bag `<FacetPanel>` hands its render prop. */
|
|
7
|
+
export interface FacetPanelBag {
|
|
8
|
+
/**
|
|
9
|
+
* The facet groups as a state a skin cannot flatten. `empty` means the
|
|
10
|
+
* search genuinely has no facets to offer (facets off, or no plan for the
|
|
11
|
+
* category) — it is NOT what a failed query looks like.
|
|
12
|
+
*/
|
|
13
|
+
readonly state: LoadState<readonly FacetGroup[]>;
|
|
14
|
+
/**
|
|
15
|
+
* `true` when the counts came from a SAMPLE because the candidate set
|
|
16
|
+
* exceeded the backend's cap. The panel must say so — the spec makes this
|
|
17
|
+
* a first-day requirement, not a banner added after somebody notices the
|
|
18
|
+
* numbers moving (§12 risk 3).
|
|
19
|
+
*/
|
|
20
|
+
readonly approximate: boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Plan slugs the server dropped at `MAX_FACET_FIELDS`. Reported, not
|
|
23
|
+
* vanished — the backend's own words. A skin names them; it never renders
|
|
24
|
+
* a zero in their place.
|
|
25
|
+
*/
|
|
26
|
+
readonly skipped: readonly string[];
|
|
27
|
+
/** Slugs that WERE counted. */
|
|
28
|
+
readonly counted: readonly string[];
|
|
29
|
+
/** Size of the largest counted set — the number `approximate` is about. */
|
|
30
|
+
readonly candidates: number;
|
|
31
|
+
/** Facet values + ranges + geo currently applied. */
|
|
32
|
+
readonly activeFilters: number;
|
|
33
|
+
toggle(slug: string, value: string): void;
|
|
34
|
+
setRange(slug: string, range: SearchRange | null): void;
|
|
35
|
+
clear(slug: string): void;
|
|
36
|
+
clearAll(): void;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Headless facet panel over the CURRENT search.
|
|
40
|
+
*
|
|
41
|
+
* It runs the same query as `<SearchResults>` — same state, same key, so
|
|
42
|
+
* TanStack serves both from one request. That is deliberate: facets and rows
|
|
43
|
+
* come from one envelope server-side (one query per page is the contract's
|
|
44
|
+
* stated design), and fetching them separately would put two answers about
|
|
45
|
+
* one search on the screen at once.
|
|
46
|
+
*
|
|
47
|
+
* `categoryFeatures` is the second slot-seam of the pair (spec §6.2 item 2).
|
|
48
|
+
* The server sends `{value: count}` and no labels, because the labels are
|
|
49
|
+
* translation keys in the category's own schema. Hand them in and the options
|
|
50
|
+
* read as words; leave them out and they read as raw index terms — never as
|
|
51
|
+
* blanks.
|
|
52
|
+
*/
|
|
53
|
+
export declare function FacetPanel(props: {
|
|
54
|
+
/** From `categories-react`'s `GET /categories/{id}/features/`. */
|
|
55
|
+
categoryFeatures?: readonly FeatureDef[];
|
|
56
|
+
/** BCP-47 tag for `date`-typed option labels. Defaults to the runtime's. */
|
|
57
|
+
locale?: string;
|
|
58
|
+
enabled?: boolean;
|
|
59
|
+
children: (bag: FacetPanelBag) => ReactNode;
|
|
60
|
+
}): ReactNode;
|
|
61
|
+
//# sourceMappingURL=FacetPanel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FacetPanel.d.ts","sourceRoot":"","sources":["../../src/headless/FacetPanel.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,KAAK,EAAa,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAG9D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAGrD,oDAAoD;AACpD,MAAM,WAAW,aAAa;IAC5B;;;;OAIG;IACH,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC,SAAS,UAAU,EAAE,CAAC,CAAC;IACjD;;;;;OAKG;IACH,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;IAC9B;;;;OAIG;IACH,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,+BAA+B;IAC/B,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,2EAA2E;IAC3E,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,qDAAqD;IACrD,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAE/B,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1C,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,GAAG,IAAI,GAAG,IAAI,CAAC;IACxD,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,QAAQ,IAAI,IAAI,CAAC;CAClB;AASD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE;IAChC,kEAAkE;IAClE,gBAAgB,CAAC,EAAE,SAAS,UAAU,EAAE,CAAC;IACzC,4EAA4E;IAC5E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,CAAC,GAAG,EAAE,aAAa,KAAK,SAAS,CAAC;CAC7C,GAAG,SAAS,CAuCZ"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { loadStateFromQuery, mapLoad, useT } from "@stapel/core";
|
|
2
|
+
import { useSearchQuery } from "../model/queries.js";
|
|
3
|
+
import { buildFacetGroups } from "../state/facets.js";
|
|
4
|
+
import { useSearchState } from "./SearchStateProvider.js";
|
|
5
|
+
const EMPTY_META = {
|
|
6
|
+
approximate: false,
|
|
7
|
+
candidates: 0,
|
|
8
|
+
counted: [],
|
|
9
|
+
skipped: [],
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Headless facet panel over the CURRENT search.
|
|
13
|
+
*
|
|
14
|
+
* It runs the same query as `<SearchResults>` — same state, same key, so
|
|
15
|
+
* TanStack serves both from one request. That is deliberate: facets and rows
|
|
16
|
+
* come from one envelope server-side (one query per page is the contract's
|
|
17
|
+
* stated design), and fetching them separately would put two answers about
|
|
18
|
+
* one search on the screen at once.
|
|
19
|
+
*
|
|
20
|
+
* `categoryFeatures` is the second slot-seam of the pair (spec §6.2 item 2).
|
|
21
|
+
* The server sends `{value: count}` and no labels, because the labels are
|
|
22
|
+
* translation keys in the category's own schema. Hand them in and the options
|
|
23
|
+
* read as words; leave them out and they read as raw index terms — never as
|
|
24
|
+
* blanks.
|
|
25
|
+
*/
|
|
26
|
+
export function FacetPanel(props) {
|
|
27
|
+
const { state: searchState, setFilter, setRange, clearAll, toggleFilter, activeFilters } = useSearchState();
|
|
28
|
+
const t = useT();
|
|
29
|
+
const query = useSearchQuery(searchState, props.enabled !== undefined ? { enabled: props.enabled } : undefined);
|
|
30
|
+
const envelope = loadStateFromQuery(query);
|
|
31
|
+
const meta = envelope.status === "ready" ? envelope.data.facet_meta : EMPTY_META;
|
|
32
|
+
const groups = mapLoad(envelope, (data) => buildFacetGroups({
|
|
33
|
+
facets: data.facets,
|
|
34
|
+
meta: data.facet_meta,
|
|
35
|
+
state: searchState,
|
|
36
|
+
...(props.categoryFeatures !== undefined
|
|
37
|
+
? { categoryFeatures: props.categoryFeatures }
|
|
38
|
+
: {}),
|
|
39
|
+
t,
|
|
40
|
+
...(props.locale !== undefined ? { locale: props.locale } : {}),
|
|
41
|
+
}));
|
|
42
|
+
return props.children({
|
|
43
|
+
state: groups,
|
|
44
|
+
approximate: meta.approximate,
|
|
45
|
+
skipped: meta.skipped,
|
|
46
|
+
counted: meta.counted,
|
|
47
|
+
candidates: meta.candidates,
|
|
48
|
+
activeFilters,
|
|
49
|
+
toggle: toggleFilter,
|
|
50
|
+
setRange,
|
|
51
|
+
clear: (slug) => {
|
|
52
|
+
setFilter(slug, []);
|
|
53
|
+
},
|
|
54
|
+
clearAll,
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=FacetPanel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FacetPanel.js","sourceRoot":"","sources":["../../src/headless/FacetPanel.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAIjE,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAoC1D,MAAM,UAAU,GAAc;IAC5B,WAAW,EAAE,KAAK;IAClB,UAAU,EAAE,CAAC;IACb,OAAO,EAAE,EAAE;IACX,OAAO,EAAE,EAAE;CACZ,CAAC;AAEF;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,UAAU,CAAC,KAO1B;IACC,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,YAAY,EAAE,aAAa,EAAE,GACtF,cAAc,EAAE,CAAC;IACnB,MAAM,CAAC,GAAG,IAAI,EAAE,CAAC;IACjB,MAAM,KAAK,GAAG,cAAc,CAC1B,WAAW,EACX,KAAK,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,SAAS,CACrE,CAAC;IAEF,MAAM,QAAQ,GAAG,kBAAkB,CAAC,KAAK,CAAC,CAAC;IAC3C,MAAM,IAAI,GAAG,QAAQ,CAAC,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC;IAEjF,MAAM,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE,CACxC,gBAAgB,CAAC;QACf,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,IAAI,EAAE,IAAI,CAAC,UAAU;QACrB,KAAK,EAAE,WAAW;QAClB,GAAG,CAAC,KAAK,CAAC,gBAAgB,KAAK,SAAS;YACtC,CAAC,CAAC,EAAE,gBAAgB,EAAE,KAAK,CAAC,gBAAgB,EAAE;YAC9C,CAAC,CAAC,EAAE,CAAC;QACP,CAAC;QACD,GAAG,CAAC,KAAK,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAChE,CAAC,CACH,CAAC;IAEF,OAAO,KAAK,CAAC,QAAQ,CAAC;QACpB,KAAK,EAAE,MAAM;QACb,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,UAAU,EAAE,IAAI,CAAC,UAAU;QAC3B,aAAa;QACb,MAAM,EAAE,YAAY;QACpB,QAAQ;QACR,KAAK,EAAE,CAAC,IAAI,EAAE,EAAE;YACd,SAAS,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACtB,CAAC;QACD,QAAQ;KACT,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
import type { LoadState } from "@stapel/core";
|
|
3
|
+
import type { RankingResponse, Scorer } from "../api/types.js";
|
|
4
|
+
/** The bag `<RankingDisclosure>` hands its render prop. */
|
|
5
|
+
export interface RankingDisclosureBag {
|
|
6
|
+
/**
|
|
7
|
+
* The ranking parameters. `empty` means the deployment declares none — a
|
|
8
|
+
* legitimate answer for a naive backend, and a different sentence from
|
|
9
|
+
* "we could not fetch the disclosure".
|
|
10
|
+
*/
|
|
11
|
+
readonly state: LoadState<readonly Scorer[]>;
|
|
12
|
+
readonly disclosure: LoadState<RankingResponse>;
|
|
13
|
+
/**
|
|
14
|
+
* Parameters the CONFIGURED engine cannot evaluate (`active: false`). They
|
|
15
|
+
* are listed with their `inactive_reason`, not filtered out: a disclosure
|
|
16
|
+
* that quietly dropped them would be disclosing a ranking the site does not
|
|
17
|
+
* actually use — which is the failure mode P2B Art. 5 exists to prevent.
|
|
18
|
+
*/
|
|
19
|
+
readonly inactive: readonly Scorer[];
|
|
20
|
+
readonly docType: string | null;
|
|
21
|
+
readonly backend: string | null;
|
|
22
|
+
readonly notes: readonly string[];
|
|
23
|
+
refetch(): void;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Headless P2B Art. 5 ranking disclosure — "what determines the order of
|
|
27
|
+
* these results", straight from the backend's scorer registry rather than
|
|
28
|
+
* from prose somebody has to remember to update.
|
|
29
|
+
*
|
|
30
|
+
* Pair this with the DSA Art. 26 half: `SearchItem.promoted` marks the paid
|
|
31
|
+
* placements in the list itself, and this explains the ordering of everything
|
|
32
|
+
* else. Neither substitutes for the other.
|
|
33
|
+
*/
|
|
34
|
+
export declare function RankingDisclosure(props: {
|
|
35
|
+
/** Doc type to disclose. Omitted asks for the deployment's default. */
|
|
36
|
+
type?: string;
|
|
37
|
+
children: (bag: RankingDisclosureBag) => ReactNode;
|
|
38
|
+
}): ReactNode;
|
|
39
|
+
//# sourceMappingURL=RankingDisclosure.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RankingDisclosure.d.ts","sourceRoot":"","sources":["../../src/headless/RankingDisclosure.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAG/D,2DAA2D;AAC3D,MAAM,WAAW,oBAAoB;IACnC;;;;OAIG;IACH,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC,SAAS,MAAM,EAAE,CAAC,CAAC;IAC7C,QAAQ,CAAC,UAAU,EAAE,SAAS,CAAC,eAAe,CAAC,CAAC;IAChD;;;;;OAKG;IACH,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,OAAO,IAAI,IAAI,CAAC;CACjB;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE;IACvC,uEAAuE;IACvE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,GAAG,EAAE,oBAAoB,KAAK,SAAS,CAAC;CACpD,GAAG,SAAS,CAgBZ"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { loadStateFromQuery, mapLoad } from "@stapel/core";
|
|
2
|
+
import { useRankingDisclosure } from "../model/queries.js";
|
|
3
|
+
/**
|
|
4
|
+
* Headless P2B Art. 5 ranking disclosure — "what determines the order of
|
|
5
|
+
* these results", straight from the backend's scorer registry rather than
|
|
6
|
+
* from prose somebody has to remember to update.
|
|
7
|
+
*
|
|
8
|
+
* Pair this with the DSA Art. 26 half: `SearchItem.promoted` marks the paid
|
|
9
|
+
* placements in the list itself, and this explains the ordering of everything
|
|
10
|
+
* else. Neither substitutes for the other.
|
|
11
|
+
*/
|
|
12
|
+
export function RankingDisclosure(props) {
|
|
13
|
+
const query = useRankingDisclosure(props.type);
|
|
14
|
+
const disclosure = loadStateFromQuery(query);
|
|
15
|
+
const data = disclosure.status === "ready" ? disclosure.data : null;
|
|
16
|
+
return props.children({
|
|
17
|
+
state: mapLoad(disclosure, (d) => d.scorers),
|
|
18
|
+
disclosure,
|
|
19
|
+
inactive: data === null ? [] : data.scorers.filter((s) => !s.active),
|
|
20
|
+
docType: data?.doc_type ?? null,
|
|
21
|
+
backend: data?.backend ?? null,
|
|
22
|
+
notes: data === null ? [] : data.notes,
|
|
23
|
+
refetch: () => {
|
|
24
|
+
void query.refetch();
|
|
25
|
+
},
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=RankingDisclosure.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RankingDisclosure.js","sourceRoot":"","sources":["../../src/headless/RankingDisclosure.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAG3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAwB3D;;;;;;;;GAQG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAIjC;IACC,MAAM,KAAK,GAAG,oBAAoB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC/C,MAAM,UAAU,GAAG,kBAAkB,CAAC,KAAK,CAAC,CAAC;IAC7C,MAAM,IAAI,GAAG,UAAU,CAAC,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;IAEpE,OAAO,KAAK,CAAC,QAAQ,CAAC;QACpB,KAAK,EAAE,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAA4B,CAAC;QACjE,UAAU;QACV,QAAQ,EAAE,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;QACpE,OAAO,EAAE,IAAI,EAAE,QAAQ,IAAI,IAAI;QAC/B,OAAO,EAAE,IAAI,EAAE,OAAO,IAAI,IAAI;QAC9B,KAAK,EAAE,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK;QACtC,OAAO,EAAE,GAAG,EAAE;YACZ,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC;QACvB,CAAC;KACF,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { ReactElement, ReactNode } from "react";
|
|
2
|
+
import type { SearchRuntime } from "../model/runtime.js";
|
|
3
|
+
/**
|
|
4
|
+
* Provides the wired {@link SearchRuntime} to every search hook and headless
|
|
5
|
+
* component below it. Bring your own visual shell — this component renders
|
|
6
|
+
* nothing of its own. (Core's `createModuleContext` provider, bound to this
|
|
7
|
+
* pair — slim wave §21/S2.)
|
|
8
|
+
*
|
|
9
|
+
* ```tsx
|
|
10
|
+
* const runtime = createSearchRuntime({ baseUrl: "/search/api/v1/" });
|
|
11
|
+
* // give runtime.client to core's <StapelConfigProvider config={{ client }}>
|
|
12
|
+
* <SearchProvider runtime={runtime}>{app}</SearchProvider>
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
15
|
+
export declare const SearchProvider: (props: {
|
|
16
|
+
runtime: SearchRuntime;
|
|
17
|
+
children: ReactNode;
|
|
18
|
+
}) => ReactElement;
|
|
19
|
+
//# sourceMappingURL=SearchProvider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SearchProvider.d.ts","sourceRoot":"","sources":["../../src/headless/SearchProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAErD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,cAAc,EAAE,CAAC,KAAK,EAAE;IACnC,OAAO,EAAE,aAAa,CAAC;IACvB,QAAQ,EAAE,SAAS,CAAC;CACrB,KAAK,YAA6B,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { ModuleProvider } from "../model/context.js";
|
|
2
|
+
/**
|
|
3
|
+
* Provides the wired {@link SearchRuntime} to every search hook and headless
|
|
4
|
+
* component below it. Bring your own visual shell — this component renders
|
|
5
|
+
* nothing of its own. (Core's `createModuleContext` provider, bound to this
|
|
6
|
+
* pair — slim wave §21/S2.)
|
|
7
|
+
*
|
|
8
|
+
* ```tsx
|
|
9
|
+
* const runtime = createSearchRuntime({ baseUrl: "/search/api/v1/" });
|
|
10
|
+
* // give runtime.client to core's <StapelConfigProvider config={{ client }}>
|
|
11
|
+
* <SearchProvider runtime={runtime}>{app}</SearchProvider>
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
export const SearchProvider = ModuleProvider;
|
|
15
|
+
//# sourceMappingURL=SearchProvider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SearchProvider.js","sourceRoot":"","sources":["../../src/headless/SearchProvider.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAGrD;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,cAAc,GAGN,cAAc,CAAC"}
|