@jsenv/navi 0.29.398 → 0.29.399
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/dist/dev/jsenv_navi.js +384 -73
- package/dist/dev/jsenv_navi.js.map +14 -14
- package/dist/jsenv_navi.js +384 -73
- package/dist/jsenv_navi.js.map +14 -14
- package/docs/dynamic_import.md +3 -2
- package/docs/popup_open.md +46 -9
- package/package.json +1 -1
package/docs/dynamic_import.md
CHANGED
|
@@ -146,8 +146,9 @@ by the code arriving.
|
|
|
146
146
|
`prefetch={false}` opts one out. The url is matched against the routes on
|
|
147
147
|
screen, a section and the page inside it alike, and what is prerun is **every
|
|
148
148
|
route action that asks nothing of the address** — a page's code, a read
|
|
149
|
-
without params. An action whose params come from the address is
|
|
150
|
-
prefetched: a prefetch has no address, the id may still be
|
|
149
|
+
without params. An action whose params come from the address is not
|
|
150
|
+
prefetched by a link: a link's prefetch has no address, the id may still be
|
|
151
|
+
chosen.
|
|
151
152
|
`routeAction(route, action, undefined, { prefetch: false })` keeps a
|
|
152
153
|
param-less read that is not worth a hover out of it.
|
|
153
154
|
|
package/docs/popup_open.md
CHANGED
|
@@ -320,6 +320,12 @@ So a dialog whose content is seeded once — an uncontrolled field on a
|
|
|
320
320
|
first render. Learning it afterwards would mean mounting on the previous subject
|
|
321
321
|
and correcting it, which is a flicker at best and stale fields at worst.
|
|
322
322
|
|
|
323
|
+
One opening does not follow that order: a `mount="while-opened"` popup pressed on
|
|
324
|
+
its own `anchor` (a picker's trigger, an expandable's UI part) has its content
|
|
325
|
+
built by the press, ahead of the click (see
|
|
326
|
+
[what the popup holds while it is closed](#what-the-popup-holds-while-it-is-closed)). A popup opened ON something is
|
|
327
|
+
opened by a command pressed elsewhere, and keeps the order above.
|
|
328
|
+
|
|
323
329
|
The two other places one could listen are not that moment, and it is worth
|
|
324
330
|
knowing why:
|
|
325
331
|
|
|
@@ -1008,7 +1014,8 @@ slots".
|
|
|
1008
1014
|
Being open is where the user is, and what a popup draws belongs to the screen
|
|
1009
1015
|
exactly the way a page's own data does. So a popup that loads something binds
|
|
1010
1016
|
its open state (above) and asks for its data with a `routeAction` whose params
|
|
1011
|
-
are `false` while it is closed
|
|
1017
|
+
are `false` while it is closed — and its content reads the question itself,
|
|
1018
|
+
without the part that says whether it is open:
|
|
1012
1019
|
|
|
1013
1020
|
```js
|
|
1014
1021
|
const groupSheetOpenSignal = stateSignal(false, {
|
|
@@ -1016,12 +1023,17 @@ const groupSheetOpenSignal = stateSignal(false, {
|
|
|
1016
1023
|
type: "boolean",
|
|
1017
1024
|
});
|
|
1018
1025
|
|
|
1026
|
+
// asked while the sheet is open
|
|
1019
1027
|
export const GROUP_MEMBERS = routeAction(GAME_ROUTE, USER.GET_MANY, () => {
|
|
1020
1028
|
if (!groupSheetOpenSignal.value) {
|
|
1021
1029
|
return false;
|
|
1022
1030
|
}
|
|
1023
1031
|
return { group: groupSignal.value };
|
|
1024
1032
|
});
|
|
1033
|
+
// read by the sheet, open or closed
|
|
1034
|
+
export const GROUP_MEMBERS_SHOWN = USER.GET_MANY.bindParams({
|
|
1035
|
+
group: groupSignal,
|
|
1036
|
+
});
|
|
1025
1037
|
```
|
|
1026
1038
|
|
|
1027
1039
|
```jsx
|
|
@@ -1030,15 +1042,16 @@ export const GROUP_MEMBERS = routeAction(GAME_ROUTE, USER.GET_MANY, () => {
|
|
|
1030
1042
|
</Dialog>;
|
|
1031
1043
|
|
|
1032
1044
|
const GroupMembers = () => {
|
|
1033
|
-
const [members] = useAsyncData(
|
|
1045
|
+
const [members] = useAsyncData(GROUP_MEMBERS_SHOWN); // reads, never runs
|
|
1034
1046
|
…
|
|
1035
1047
|
};
|
|
1036
1048
|
```
|
|
1037
1049
|
|
|
1038
1050
|
The same shape when the popup is one of many — a sheet on every card, opened
|
|
1039
1051
|
from wherever the card is read. Its open state then says which one, and the
|
|
1040
|
-
route action reads the id straight from it
|
|
1041
|
-
card is not a
|
|
1052
|
+
route action reads the id straight from it, while each card's content reads the
|
|
1053
|
+
question of its own card. Declared on the root route, since a card is not a
|
|
1054
|
+
page:
|
|
1042
1055
|
|
|
1043
1056
|
```js
|
|
1044
1057
|
const seatSheetSignal = stateSignal(undefined, {
|
|
@@ -1048,18 +1061,39 @@ const seatSheetSignal = stateSignal(undefined, {
|
|
|
1048
1061
|
});
|
|
1049
1062
|
const ANY_PAGE = route("/", { searchParams: { seat: seatSheetSignal } });
|
|
1050
1063
|
|
|
1064
|
+
export const seatableUsersOf = (gameId) => ({ game: gameId });
|
|
1051
1065
|
export const SEATABLE_USERS = routeAction(ANY_PAGE, USER.GET_MANY, () => {
|
|
1052
1066
|
const gameId = seatSheetSignal.value;
|
|
1053
|
-
return gameId ?
|
|
1067
|
+
return gameId ? seatableUsersOf(gameId) : false;
|
|
1054
1068
|
});
|
|
1055
1069
|
```
|
|
1056
1070
|
|
|
1057
1071
|
```jsx
|
|
1058
1072
|
<Dialog signal={seatSheetSignal} value={game.id}>
|
|
1059
|
-
<SeatableUsers />
|
|
1060
|
-
</Dialog
|
|
1073
|
+
<SeatableUsers gameId={game.id} />
|
|
1074
|
+
</Dialog>;
|
|
1075
|
+
|
|
1076
|
+
const SeatableUsers = ({ gameId }) => {
|
|
1077
|
+
const [users] = useAsyncData(
|
|
1078
|
+
USER.GET_MANY.bindParams(seatableUsersOf(gameId)),
|
|
1079
|
+
);
|
|
1080
|
+
…
|
|
1081
|
+
};
|
|
1061
1082
|
```
|
|
1062
1083
|
|
|
1084
|
+
**The content reads its question, never the route action.** The route action's
|
|
1085
|
+
params are `false` while the popup is closed, and for the route action that is
|
|
1086
|
+
right: it says _when_ to ask. Read by the content, the same `false` says there
|
|
1087
|
+
is nothing to show — `useAsyncData` hands back `undefined` the moment the popup
|
|
1088
|
+
closes, the list empties while hidden, and the next opening builds it again from
|
|
1089
|
+
the top: the scroll position is lost, and every row is rendered once more for an
|
|
1090
|
+
answer that never left the store. When the popup is one of many, it is worse: the
|
|
1091
|
+
route action follows whichever popup is open, so a card's sheet kept mounted
|
|
1092
|
+
since an earlier opening redraws with another card's rows each time that one
|
|
1093
|
+
opens. Closing a popup does not change what it is about, so what it reads leaves
|
|
1094
|
+
the open state out. Equal params share one instance — the content reads the very
|
|
1095
|
+
one the route action runs, so nothing is asked twice and nothing is copied.
|
|
1096
|
+
|
|
1063
1097
|
**A popup that waits holds its own `<Loading>`**, like every other part of a
|
|
1064
1098
|
screen that can wait — it is not built into `Dialog`/`Popover`, because only the
|
|
1065
1099
|
code inside knows whether anything in there loads at all:
|
|
@@ -1116,7 +1150,8 @@ become a popup's private request — asked for late, and asked for alone.
|
|
|
1116
1150
|
|
|
1117
1151
|
A closed popup builds nothing: `children` are mounted on the first open, and
|
|
1118
1152
|
stay mounted afterwards — a reopened popup finds its scroll position and its
|
|
1119
|
-
half-typed form where it left them
|
|
1153
|
+
half-typed form where it left them, as long as the data it draws does not leave
|
|
1154
|
+
with the close (see [A popup that loads data](#a-popup-that-loads-data)).
|
|
1120
1155
|
|
|
1121
1156
|
"Closed" is two states, not one — never opened yet, and closed again after an
|
|
1122
1157
|
opening — so the `mount` prop answers both at once:
|
|
@@ -1134,7 +1169,9 @@ off it, fields a surrounding form submits, a size measured from outside.
|
|
|
1134
1169
|
|
|
1135
1170
|
Whatever the value but `"while-opened"`, intent on the anchor — a pointer
|
|
1136
1171
|
entering it, focus landing in it — builds the content ahead of the click that
|
|
1137
|
-
will open it.
|
|
1172
|
+
will open it. A `"while-opened"` popup is warmed by a press on its anchor only,
|
|
1173
|
+
and a press that ends without opening it — a scroll, a drag, a release
|
|
1174
|
+
elsewhere — throws the content away: there is still one content at a time.
|
|
1138
1175
|
|
|
1139
1176
|
`"while-opened"` is what an uncontrolled field seeded from a `defaultValue`
|
|
1140
1177
|
needs: without it, a popup reopened after the underlying value changed still
|