@stapel/search-react 0.18.0 → 0.18.1

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 CHANGED
@@ -1,5 +1,40 @@
1
1
  # @stapel/search-react
2
2
 
3
+ ## 0.18.1
4
+
5
+ ### Patch Changes
6
+
7
+ - f79bdc3: tokens-antd: a gated control is semantically off and interactively ALIVE — it can be tapped, focused, and can say why it will not do the thing
8
+
9
+ `GatedControl` handed callers `bind.disabled` and its own JSDoc told them to spread it straight onto the control. That produced an html-`disabled` element, which fires no events in any browser: it cannot be clicked, cannot take focus, cannot be described to a screen reader that never reaches it, and cannot carry the one gesture that mattered — the tap that should open the sign-in door standing behind the gate. Every gated control across the ~20 pairs using it was inert, and the wrong instruction was half the defect: the docs taught the shape that broke it.
10
+
11
+ Measured on a live deployment: an anonymous visitor taps the favourite heart and nothing happens at all — no sentence, no tooltip, no door (walker defects D45/D72).
12
+
13
+ **The corrected contract.** While the gate is shut a control is now `aria-disabled="true"` and NOT html-disabled, so it stays focusable and keeps receiving events. The ACTION is suppressed by `GatedControl` itself, in a capture-phase wrapper (`display: contents`, so no pair's layout moves by a pixel): the caller's `onClick`, keyboard activation, typing, IME input, paste and drop are swallowed before the control sees them. Callers write their handlers exactly as if the gate did not exist. The activation comes back as the new `onBlockedActivate`, which is where a pair opens its door. The reason stays where it was — visible text wired by `aria-describedby` — and where a `PaneGate` pools it into one footnote, the gesture now brings a `role="status"` copy of the sentence back to the control it belongs to. A blocked `GatedButton` keeps antd's exact disabled paint (its own `-disabled` class, which sets no `pointer-events`), so nothing about any screen looks different.
14
+
15
+ `GatedControlProps.whenBlocked` holds the two deliberate opt-outs, neither of them the default:
16
+
17
+ - `"inert"` — html `disabled`, for the rare control that must be switched off at the browser level. `attributes-react`'s catalogue lock is the one place in the fleet that asks for it, and now says so.
18
+ - `"annotate"` — the control stays fully usable and only gains the sentence, for a gate that judges the VALUE rather than refusing the person: `calendar-react`'s slot-length field must stay editable, because editing it is how the reason goes away, and `search-react`'s sort must still pick the options that are not the blocked one.
19
+
20
+ `useBlockedButtonClassName()` is exported for render-prop call sites that paint their own button and want the same unavailable look rather than a second grey.
21
+
22
+ **⚠️ The readiness-signal hazard, and its cure.** `element.disabled` is now permanently `false` on every gated control in the fleet. Any test using it as a readiness signal — `await waitFor(() => expect(save.disabled).toBe(false))`, meaning "wait until this is allowed" — returns instantly and mis-times SILENTLY: every assertion after it reads an unseeded component, and the failure looks like broken product logic rather than a gate that had not opened. One pair's suite went green → 21 failures across unrelated files on exactly this. Wait on the stamp instead, which is what such a wait was always asking:
23
+
24
+ ```ts
25
+ await waitFor(() =>
26
+ expect(
27
+ screen.getByTestId("save-gate").getAttribute("data-stapel-gated")
28
+ ).toBe("available")
29
+ );
30
+ ```
31
+
32
+ `data-stapel-gated="available" | "blocked"` is on the wrapper of every gated control in all three modes (`GatedButton` names it `<testId>-gate`). For a point assertion on one element, read `aria-disabled`. Never `disabled`.
33
+
34
+ **ChoiceChips** carried the same defect on its own chips and is fixed the same way: a chip at the cap is `aria-disabled` and focusable, and the tap is refused in the handler, so the row's sentence reaches a keyboard.
35
+
36
+ **The consumers.** Every `GatedButton` call site (64 imports across 20 pairs) is fixed with no code change — the correction is in the substrate. The render-prop call sites that consumed the binding field-by-field now spread it whole: `billing-react`'s auto-recharge switch, `calendar-react`'s RSVP buttons, `moderation-react`'s sanction checkbox, `notifications-react`'s push switch, `attributes-react`'s at-max add button. `tasks-react`'s assignee picker is a host slot rendering its own control out of reach of the suppression, so it is handed a plain verdict on purpose. `workspaces-react` had two hand-rolled gates that never went through `GatedControl` at all — a row-action column and the create button on a failed roster read — and both now use the same anatomy.
37
+
3
38
  ## 0.18.0
4
39
 
5
40
  ### Minor Changes
@@ -1 +1 @@
1
- {"version":3,"file":"SortSelect.d.ts","sourceRoot":"","sources":["../../src/default/SortSelect.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAY1C;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,MAAM,CAAC;AAMzC,MAAM,WAAW,eAAe;IAC9B;8EAC0E;IAC1E,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1C;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,eAAe,GAAG,YAAY,CA0F/D"}
1
+ {"version":3,"file":"SortSelect.d.ts","sourceRoot":"","sources":["../../src/default/SortSelect.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAY1C;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,MAAM,CAAC;AAMzC,MAAM,WAAW,eAAe;IAC9B;8EAC0E;IAC1E,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1C;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,eAAe,GAAG,YAAY,CA4F/D"}
@@ -64,7 +64,10 @@ export function SortSelect(props) {
64
64
  setSort(next);
65
65
  }, options: optionsFor() }));
66
66
  }
67
- return (_jsx(GatedControl, { gate: distance, testId: "search-sort-gate", children: (bind) => (_jsxs(Flex, { gap: spacing[2], align: "center", children: [_jsx(Typography.Text, { type: "secondary", "aria-hidden": "true", children: t(SEARCH_I18N_KEYS.sortLabel) }), _jsx(Select, { "data-testid": "search-sort", "aria-label": t(SEARCH_I18N_KEYS.sortLabel), "aria-describedby": bind["aria-describedby"], style: { minWidth: SORT_SELECT_MIN_WIDTH }, value: active ?? null, onChange: (next) => {
67
+ return (
68
+ // `annotate`: the gate judges ONE option, not the control. Suppressing
69
+ // the select would take away every sort, which is not what is blocked.
70
+ _jsx(GatedControl, { gate: distance, whenBlocked: "annotate", testId: "search-sort-gate", children: (bind) => (_jsxs(Flex, { gap: spacing[2], align: "center", children: [_jsx(Typography.Text, { type: "secondary", "aria-hidden": "true", children: t(SEARCH_I18N_KEYS.sortLabel) }), _jsx(Select, { "data-testid": "search-sort", "aria-label": t(SEARCH_I18N_KEYS.sortLabel), "aria-describedby": bind["aria-describedby"], style: { minWidth: SORT_SELECT_MIN_WIDTH }, value: active ?? null, onChange: (next) => {
68
71
  setSort(next);
69
72
  }, options: optionsFor(bind["aria-describedby"] ?? "") })] })) }));
70
73
  }
@@ -1 +1 @@
1
- {"version":3,"file":"SortSelect.js","sourceRoot":"","sources":["../../src/default/SortSelect.tsx"],"names":[],"mappings":";AAkBA,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AAChD,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEpE,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AACpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE/C;;;;GAIG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,GAAG,CAAC;AAEzC;yEACyE;AACzE,MAAM,qBAAqB,GAAG,oCAAoC,CAAC;AA+BnE,MAAM,UAAU,UAAU,CAAC,KAAsB;IAC/C,MAAM,CAAC,GAAG,IAAI,EAAE,CAAC;IACjB,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,cAAc,EAAE,CAAC;IAC5C,yEAAyE;IACzE,2EAA2E;IAC3E,wEAAwE;IACxE,2BAA2B;IAC3B,MAAM,OAAO,GAAG,cAAc,EAAE,CAAC;IAEjC,yEAAyE;IACzE,4EAA4E;IAC5E,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,WAAW,IAAI,OAAO,CAAC;IAC1D,MAAM,SAAS,GAAG,KAAK,CAAC,GAAG,KAAK,SAAS,CAAC;IAC1C,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,YAAY,CAAC,CAAC;IACpC,MAAM,MAAM,GACV,MAAM,KAAK,SAAS,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC;QACxC,CAAC,CAAC,CAAC,GAAG,YAAY,EAAE,MAAM,CAAC;QAC3B,CAAC,CAAC,YAAY,CAAC;IAEnB,yEAAyE;IACzE,0EAA0E;IAC1E,6EAA6E;IAC7E,qDAAqD;IACrD,MAAM,QAAQ,GAAuB,SAAS;QAC5C,CAAC,CAAC,eAAe,EAAE;QACnB,CAAC,CAAC,aAAa,CAAC,qBAAqB,CAAC,CAAC;IAEzC,MAAM,UAAU,GAAG,CAAC,WAAoB,EAIpC,EAAE,CACJ,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;QACnB,MAAM,GAAG,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;QAChC,MAAM,KAAK,GAAG,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;QACjD,MAAM,OAAO,GAAG,KAAK,KAAK,UAAU,IAAI,CAAC,SAAS,CAAC;QACnD,OAAO;YACL,KAAK;YACL,8DAA8D;YAC9D,uEAAuE;YACvE,gEAAgE;YAChE,KAAK,EACH,OAAO,IAAI,KAAK,CAAC,OAAO,KAAK,IAAI,IAAI,WAAW,KAAK,SAAS;gBAC5D,CAAC,CAAC,GAAG,KAAK,MAAM,CAAC,CAAC,qBAAqB,CAAC,EAAE;gBAC1C,CAAC,CAAC,KAAK;YACX,QAAQ,EAAE,OAAO;SAClB,CAAC;IACJ,CAAC,CAAC,CAAC;IAEL,IAAI,KAAK,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;QAC3B,OAAO,CACL,KAAC,MAAM,mBACO,aAAa,uBACN,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,gBAC1C,CAAC,CAAC,gBAAgB,CAAC,SAAS,CAAC;YACzC,gEAAgE;YAChE,sEAAsE;YACtE,qBAAqB;YACrB,KAAK,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,EACxC,KAAK,EAAE,MAAM,IAAI,IAAI,EACrB,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE;gBACjB,OAAO,CAAC,IAAI,CAAC,CAAC;YAChB,CAAC,EACD,OAAO,EAAE,UAAU,EAAE,GACrB,CACH,CAAC;IACJ,CAAC;IAED,OAAO,CACL,KAAC,YAAY,IAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAC,kBAAkB,YACpD,CAAC,IAAI,EAAE,EAAE,CAAC,CACT,MAAC,IAAI,IAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,KAAK,EAAC,QAAQ,aACnC,KAAC,UAAU,CAAC,IAAI,IAAC,IAAI,EAAC,WAAW,iBAAa,MAAM,YACjD,CAAC,CAAC,gBAAgB,CAAC,SAAS,CAAC,GACd,EAClB,KAAC,MAAM,mBACO,aAAa,gBACb,CAAC,CAAC,gBAAgB,CAAC,SAAS,CAAC,sBACvB,IAAI,CAAC,kBAAkB,CAAC,EAC1C,KAAK,EAAE,EAAE,QAAQ,EAAE,qBAAqB,EAAE,EAC1C,KAAK,EAAE,MAAM,IAAI,IAAI,EACrB,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE;wBACjB,OAAO,CAAC,IAAI,CAAC,CAAC;oBAChB,CAAC,EACD,OAAO,EAAE,UAAU,CAAC,IAAI,CAAC,kBAAkB,CAAC,IAAI,EAAE,CAAC,GACnD,IACG,CACR,GACY,CAChB,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"SortSelect.js","sourceRoot":"","sources":["../../src/default/SortSelect.tsx"],"names":[],"mappings":"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"}
package/llms.txt CHANGED
@@ -1,4 +1,4 @@
1
- # @stapel/search-react 0.18.0
1
+ # @stapel/search-react 0.18.1
2
2
 
3
3
  Headless React flow pair for stapel-search (contract >=0.10 <0.11) — business + state, zero visual opinion.
4
4
  Built on @stapel/core: typed client + StapelApiError envelope, auth token refresh,
package/manifest.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$generated": "by scripts/gen-manifest.mjs — do not edit; drift-gated (pnpm gen:manifest:check)",
3
3
  "package": "@stapel/search-react",
4
- "version": "0.18.0",
4
+ "version": "0.18.1",
5
5
  "backend": {
6
6
  "module": "stapel-search",
7
7
  "contract": ">=0.10 <0.11"
package/nav-manifest.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "package": "@stapel/search-react",
3
- "version": "0.18.0",
3
+ "version": "0.18.1",
4
4
  "entries": [
5
5
  {
6
6
  "id": "search.results",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stapel/search-react",
3
- "version": "0.18.0",
3
+ "version": "0.18.1",
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": {
@@ -115,12 +115,12 @@
115
115
  "size-limit": "^11.2.0",
116
116
  "typescript": "^5.8.3",
117
117
  "vitest": "^3.2.4",
118
- "@stapel/attributes-react": "^0.11.1",
118
+ "@stapel/attributes-react": "^0.13.0",
119
119
  "@stapel/core": "^0.23.1",
120
120
  "@stapel/image": "^0.4.2",
121
121
  "@stapel/showcase": "^0.3.0",
122
122
  "@stapel/tokens": "^0.7.0",
123
- "@stapel/tokens-antd": "^0.14.0"
123
+ "@stapel/tokens-antd": "^0.16.0"
124
124
  },
125
125
  "engines": {
126
126
  "node": ">=22"
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$generated": "by scripts/gen-events.mjs — do not edit; drift-gated (pnpm gen:events:check)",
3
3
  "package": "@stapel/search-react",
4
- "version": "0.18.0",
4
+ "version": "0.18.1",
5
5
  "defined": [],
6
6
  "flows": []
7
7
  }
@@ -136,7 +136,9 @@ export function SortSelect(props: SortSelectProps): ReactElement {
136
136
  }
137
137
 
138
138
  return (
139
- <GatedControl gate={distance} testId="search-sort-gate">
139
+ // `annotate`: the gate judges ONE option, not the control. Suppressing
140
+ // the select would take away every sort, which is not what is blocked.
141
+ <GatedControl gate={distance} whenBlocked="annotate" testId="search-sort-gate">
140
142
  {(bind) => (
141
143
  <Flex gap={spacing[2]} align="center">
142
144
  <Typography.Text type="secondary" aria-hidden="true">