@jsenv/navi 0.29.218 → 0.29.220

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/docs/actions.md CHANGED
@@ -244,6 +244,17 @@ invisible at the call site and expensive on screen: the request then leaves with
244
244
  the gesture instead of with the screen, one waterfall behind everything else the
245
245
  address needed.
246
246
 
247
+ **A route action is a read.** The parameter says whose data it is; it does not
248
+ say who may ask for it. An address asks again on every arrival — a reload, a
249
+ pasted link, a step back — which is exactly what a read is for and what a write
250
+ cannot survive: `POST /users/:id/invitations` hung on `/users/:id` mints a token
251
+ per reload, for ever, and nothing at the call site says so. So a run that writes
252
+ belongs to the component that decided to write, whatever its parameter, and
253
+ `{ run: true }` is what says it. That is the shape of a request prepared for a
254
+ gesture — a token a share button must already hold when it is pressed, since the
255
+ OS share sheet only opens inside the gesture and never after an `await`: it runs
256
+ at mount because the press cannot wait for it, not because the address changed.
257
+
247
258
  `{ onLoad }` is what the screen does with the data **once, when it becomes
248
259
  known** — seed the fields someone is about to edit, focus something, remember
249
260
  where a list was:
@@ -894,9 +894,12 @@ one tab further, and back to `/me?settings` returning to the first.
894
894
 
895
895
  Two params, because they answer two questions — is the layer there, and which of
896
896
  its pages is shown. One param whose value is "which page of the layer, or none"
897
- (`?settings=alerts`) is arguably the shape the address wants, and it is not
898
- expressible today: a popup says its open state as a boolean, so it would
899
- overwrite the tab on every open.
897
+ (`?settings=alerts`) is arguably the shape the address wants, and a popup cannot
898
+ hold it: it is open on exactly one value of its signal (`value`, see
899
+ [popup_open.md](./popup_open.md#signal--the-app-holds-it-both-ways)), so a tab
900
+ changing under it would read as the layer closing. `value` is for the other
901
+ question — WHICH of several popups is open, one sheet per card under a single
902
+ `?seat=<gameId>` — not for what varies inside one.
900
903
 
901
904
  ### What it costs
902
905
 
@@ -687,6 +687,21 @@ which is what every navi control does with its value (see
687
687
  on them (`SidePanel`) all take it. A signal already `true` at mount means the
688
688
  popup was already open when the page appeared: no entrance plays.
689
689
 
690
+ `value` makes the signal say WHICH popup is open, for several sharing it —
691
+ one sheet per card in a feed, with a single `?seat=<gameId>` for all of them:
692
+
693
+ ```jsx
694
+ <Dialog signal={seatSheetSignal} value={game.id} />
695
+ ```
696
+
697
+ The popup is open while the signal holds its value and closed otherwise;
698
+ opening writes the value, closing writes `undefined`, which a state signal reads
699
+ as its default and takes out of the url. Everything above still holds — the
700
+ same writes, the same history rules — only what "open" is worth in the signal
701
+ changes. A popup is open on exactly one value: what varies while it is open (a
702
+ tab inside it) is a param of its own, see
703
+ [navigation.md](./navigation.md#places-inside-the-layer).
704
+
690
705
  ### `navState` — the history entry holds it
691
706
 
692
707
  ```jsx
@@ -756,6 +771,31 @@ const GroupMembers = () => {
756
771
  };
757
772
  ```
758
773
 
774
+ The same shape when the popup is one of many — a sheet on every card, opened
775
+ from wherever the card is read. Its open state then says which one, and the
776
+ route action reads the id straight from it. Declared on the root route, since a
777
+ card is not a page:
778
+
779
+ ```js
780
+ const seatSheetSignal = stateSignal(undefined, {
781
+ id: "seat",
782
+ type: "string",
783
+ weak: true,
784
+ });
785
+ const ANY_PAGE = route("/", { searchParams: { seat: seatSheetSignal } });
786
+
787
+ export const SEATABLE_USERS = routeAction(ANY_PAGE, USER.GET_MANY, () => {
788
+ const gameId = seatSheetSignal.value;
789
+ return gameId ? { game: gameId } : false;
790
+ });
791
+ ```
792
+
793
+ ```jsx
794
+ <Dialog signal={seatSheetSignal} value={game.id}>
795
+ <SeatableUsers />
796
+ </Dialog>
797
+ ```
798
+
759
799
  **A popup that waits holds its own `<Loading>`**, like every other part of a
760
800
  screen that can wait — it is not built into `Dialog`/`Popover`, because only the
761
801
  code inside knows whether anything in there loads at all:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jsenv/navi",
3
- "version": "0.29.218",
3
+ "version": "0.29.220",
4
4
  "type": "module",
5
5
  "description": "Library of components including navigation to create frontend applications",
6
6
  "repository": {