@stapel/search-react 0.1.0 → 0.2.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 +54 -0
- package/LICENSE +21 -0
- package/dist/i18n/ru.d.ts +1 -1
- package/dist/i18n/ru.js +1 -1
- package/llms.txt +1 -1
- package/manifest.json +1 -1
- package/nav-manifest.json +1 -1
- package/package.json +15 -15
- package/src/analytics/generated/events.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1 +1,55 @@
|
|
|
1
1
|
# @stapel/search-react
|
|
2
|
+
|
|
3
|
+
## 0.2.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 6356af8: New package: `@stapel/search-react` — the frontend pair for stapel-search, and
|
|
8
|
+
the one surface a storefront's catalogue, category and search pages all come
|
|
9
|
+
from.
|
|
10
|
+
|
|
11
|
+
```tsx
|
|
12
|
+
const runtime = createSearchRuntime({ baseUrl: "/search/api/v1/" });
|
|
13
|
+
<SearchProvider runtime={runtime}>
|
|
14
|
+
<SearchPage adapter={useRouterSearchParams()} defaultType="listing" />
|
|
15
|
+
</SearchProvider>;
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
No session, no workspace id, no auth client: every endpoint it calls is
|
|
19
|
+
`AllowAny`, so a catalogue renders for a visitor who will never sign in.
|
|
20
|
+
|
|
21
|
+
**The URL is the state.** Text, category, facet filters, ranges, geo, sort, page
|
|
22
|
+
size and the keyset cursor all live in the query string, under the backend's own
|
|
23
|
+
parameter names, and no component keeps a second copy. Copying the address into
|
|
24
|
+
another tab reproduces the page, Back removes exactly the last filter, and a
|
|
25
|
+
reload loses nothing — by construction rather than by discipline. Changing any
|
|
26
|
+
of them drops the keyset cursor, because `anchor` is a position inside one
|
|
27
|
+
ordered candidate set and carrying it across a filter change answers page 4 of
|
|
28
|
+
a different search. The router is a two-member seam (`SearchParamsAdapter`);
|
|
29
|
+
`./router` binds react-router's `useSearchParams`, and a Next.js app or a plain
|
|
30
|
+
`URLSearchParams` satisfies the same shape.
|
|
31
|
+
|
|
32
|
+
**Facets are drill-down, and the panel shows it.** Each is counted with its own
|
|
33
|
+
filter removed, so picking a value leaves its siblings with the counts you would
|
|
34
|
+
get by switching to them; closed sets keep their authored order, zeros included.
|
|
35
|
+
The server sends no option labels — they are keys in the category's feature
|
|
36
|
+
schema — so `categoryFeatures` is an explicit input and the captions resolve
|
|
37
|
+
through `@stapel/attributes-react`'s `formatFeatureValue`, the same formatter a
|
|
38
|
+
card uses.
|
|
39
|
+
|
|
40
|
+
**What the server admits, the screen repeats.** `exact_total: false` renders as
|
|
41
|
+
"about N", `facet_meta.approximate` says the counts are a sample, a skipped slug
|
|
42
|
+
shows "not counted" rather than `0`, and every `degraded[]` literal becomes a
|
|
43
|
+
line in a banner — including one this build has no wording for, which arrives
|
|
44
|
+
with its raw text. A failed search says "we could not run this search" with a
|
|
45
|
+
retry, and `error.400.search_window_exceeded` says "narrow the search"; neither
|
|
46
|
+
is ever spelled "nothing found".
|
|
47
|
+
|
|
48
|
+
`promoted` (DSA Art. 26) rides every item under every sort and reaches the card
|
|
49
|
+
slot whole, so a storefront's own `<ListingCard>` can still mark it; the P2B
|
|
50
|
+
Art. 5 ranking disclosure ships as a headless bag and a page, listing even the
|
|
51
|
+
parameters the configured engine cannot evaluate.
|
|
52
|
+
|
|
53
|
+
`./default` is the antd skin (`SearchPage`, `SearchResultsPane`,
|
|
54
|
+
`FacetPanelPane`, `RankingDisclosurePane`); the main entry carries no antd and
|
|
55
|
+
no router.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Stapel contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/dist/i18n/ru.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ export { searchErrorBundleRu } from "./generated/errors.ru.gen.js";
|
|
|
7
7
|
* entry does not import this module — gated by size-limit + the bundle-purity
|
|
8
8
|
* test).
|
|
9
9
|
*
|
|
10
|
-
* This is the storefront's DEFAULT language (
|
|
10
|
+
* This is the storefront's DEFAULT language (storefront spec verdict F1:
|
|
11
11
|
* ru-first), which is why it is the fullest of the three bundles and why the
|
|
12
12
|
* wording is checked against what a marketplace visitor is actually being
|
|
13
13
|
* told — "counts are approximate" has to sound like an explanation, not an
|
package/dist/i18n/ru.js
CHANGED
|
@@ -7,7 +7,7 @@ export { searchErrorBundleRu } from "./generated/errors.ru.gen.js";
|
|
|
7
7
|
* entry does not import this module — gated by size-limit + the bundle-purity
|
|
8
8
|
* test).
|
|
9
9
|
*
|
|
10
|
-
* This is the storefront's DEFAULT language (
|
|
10
|
+
* This is the storefront's DEFAULT language (storefront spec verdict F1:
|
|
11
11
|
* ru-first), which is why it is the fullest of the three bundles and why the
|
|
12
12
|
* wording is checked against what a marketplace visitor is actually being
|
|
13
13
|
* told — "counts are approximate" has to sound like an explanation, not an
|
package/llms.txt
CHANGED
package/manifest.json
CHANGED
package/nav-manifest.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stapel/search-react",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Headless React pair for stapel-search: a typed query client, TanStack Query hooks, and a URL-first state codec that makes a search shareable by construction (filters, ranges, geo, sort and the keyset cursor all live in the query string). Drill-down facets rendered with their remaining counts and with the server's own honesty flags — approximate, skipped, degraded — never swallowed; keyset pagination with the window refusal named; DSA Art. 26 `promoted` marking carried into every card slot and the P2B Art. 5 ranking disclosure exposed as data. Zero visual opinion in the main entry; an opt-in /default subpath ships the antd skin, and /router binds the codec to react-router's useSearchParams.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -50,13 +50,6 @@
|
|
|
50
50
|
"nav-manifest.json",
|
|
51
51
|
"llms.txt"
|
|
52
52
|
],
|
|
53
|
-
"scripts": {
|
|
54
|
-
"build": "tsc -p tsconfig.json",
|
|
55
|
-
"test": "tsc -p tsconfig.test.json && vitest run --exclude test/prodBundlePurity.test.ts",
|
|
56
|
-
"lint": "eslint .",
|
|
57
|
-
"size": "size-limit",
|
|
58
|
-
"test:pack": "vitest run test/prodBundlePurity.test.ts"
|
|
59
|
-
},
|
|
60
53
|
"size-limit": [
|
|
61
54
|
{
|
|
62
55
|
"name": "index — the headless pair (client + hooks + URL codec + facet model): no antd, no react-router",
|
|
@@ -106,11 +99,6 @@
|
|
|
106
99
|
},
|
|
107
100
|
"devDependencies": {
|
|
108
101
|
"@size-limit/preset-small-lib": "^11.2.0",
|
|
109
|
-
"@stapel/attributes-react": "workspace:^",
|
|
110
|
-
"@stapel/core": "workspace:^",
|
|
111
|
-
"@stapel/showcase": "workspace:^",
|
|
112
|
-
"@stapel/tokens": "workspace:^",
|
|
113
|
-
"@stapel/tokens-antd": "workspace:^",
|
|
114
102
|
"@tanstack/react-query": "^5.81.0",
|
|
115
103
|
"@testing-library/react": "^16.3.0",
|
|
116
104
|
"@types/react": "^19.1.0",
|
|
@@ -122,12 +110,24 @@
|
|
|
122
110
|
"react-router": "^7.18.1",
|
|
123
111
|
"size-limit": "^11.2.0",
|
|
124
112
|
"typescript": "^5.8.3",
|
|
125
|
-
"vitest": "^3.2.4"
|
|
113
|
+
"vitest": "^3.2.4",
|
|
114
|
+
"@stapel/attributes-react": "^0.2.0",
|
|
115
|
+
"@stapel/core": "^0.15.0",
|
|
116
|
+
"@stapel/showcase": "^0.2.0",
|
|
117
|
+
"@stapel/tokens": "^0.5.0",
|
|
118
|
+
"@stapel/tokens-antd": "^0.5.0"
|
|
126
119
|
},
|
|
127
120
|
"engines": {
|
|
128
121
|
"node": ">=22"
|
|
129
122
|
},
|
|
130
123
|
"publishConfig": {
|
|
131
124
|
"access": "public"
|
|
125
|
+
},
|
|
126
|
+
"scripts": {
|
|
127
|
+
"build": "tsc -p tsconfig.json",
|
|
128
|
+
"test": "tsc -p tsconfig.test.json && vitest run --exclude test/prodBundlePurity.test.ts",
|
|
129
|
+
"lint": "eslint .",
|
|
130
|
+
"size": "size-limit",
|
|
131
|
+
"test:pack": "vitest run test/prodBundlePurity.test.ts"
|
|
132
132
|
}
|
|
133
|
-
}
|
|
133
|
+
}
|