@jsenv/navi 0.29.152 → 0.29.154

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.
@@ -30,7 +30,15 @@ validation message on the **requester** (the submit button, not the form):
30
30
 
31
31
  - `errorMapping(error)` turns the raw error into what to show: a string, an
32
32
  `Error`, an element, or `{ message, target }` to point the message at another
33
- element.
33
+ element. Two returns matter as much as those:
34
+ - **`return error` — the error untouched — is how a mapping says "not mine"**.
35
+ It is then shown exactly as if there were no mapping at all, so a mapping
36
+ only has to know about the cases it dresses.
37
+ - **returning nothing displays nothing**, on purpose: that is how one
38
+ particular error is swallowed, per error, where `actionErrorEffect="none"`
39
+ says it once for the whole control. Beware of it as a default — a mapping
40
+ whose last branch falls off the end swallows everything it did not
41
+ recognize, and the person sees the button return to idle with no message.
34
42
  - The message is a constraint on the control (`navi_action_error`) rather than a
35
43
  render of its own, and it **auto-resets on the next action**: hitting submit
36
44
  again clears it and re-submits, instead of the form being stuck invalid.
@@ -47,6 +55,49 @@ validation message on the **requester** (the submit button, not the form):
47
55
  `action` — `onActionStart`, `onActionEnd`, `onActionAborted` — are in
48
56
  [actions.md](./actions.md#the-instance-a-control-runs).
49
57
 
58
+ #### A refusal that carries a link
59
+
60
+ The callout is not limited to a sentence. When the refusal has somewhere to go —
61
+ "this slot is already taken by that game" — the mapping returns an element and
62
+ the callout holds it, link included:
63
+
64
+ ```jsx
65
+ <Form
66
+ action={GAME.POST.bindParams(values)}
67
+ errorMapping={(error) => {
68
+ const conflict = error.conflict;
69
+ if (!conflict) return error; // not mine: shown as-is
70
+ return (
71
+ <>
72
+ Ce créneau est déjà pris par{" "}
73
+ <Link route={GAME_ROUTE} routeParams={{ id: conflict.game_id }}>
74
+ cette partie
75
+ </Link>
76
+ </>
77
+ );
78
+ }}
79
+ >
80
+ ```
81
+
82
+ That is the whole thing: the message arrives on the button that was pressed, it
83
+ survives whatever ran before it (a `command` waits for its own action), and it
84
+ clears itself on the next submit. A refusal with a destination does **not** need
85
+ a render of its own in the page.
86
+
87
+ Two consequences of the message being an element:
88
+
89
+ - it is rendered as a **preact tree of its own** into the callout, not as part
90
+ of the app tree, so it receives no context from the app. Anything reading
91
+ global signals — a navi `<Link route>`, a store — works; anything expecting an
92
+ app `Context.Provider` above it does not, and has to be given what it needs
93
+ through props;
94
+ - it has no one-line form, so nothing derives a `title` from it — the callout is
95
+ the only place it is shown. A string or an `Error` message still writes the
96
+ control's `title` when the control has none of its own.
97
+
98
+ [form_error_mapping_jsx demo](../src/control/demos/form_error_mapping_jsx/demo.html)
99
+ shows a mapping answering with a different component per error kind.
100
+
50
101
  ### A screen's data failed — a route action
51
102
 
52
103
  Nobody clicked; the page simply cannot be drawn. It is the page, or a piece of
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jsenv/navi",
3
- "version": "0.29.152",
3
+ "version": "0.29.154",
4
4
  "type": "module",
5
5
  "description": "Library of components including navigation to create frontend applications",
6
6
  "repository": {