@jsenv/navi 0.29.46 → 0.29.48
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/jsenv_navi.js +251 -133
- package/dist/jsenv_navi.js.map +21 -17
- package/dist/jsenv_navi_side_effects.js +1 -1
- package/dist/jsenv_navi_side_effects.js.map +2 -2
- package/docs/create_and_edit.md +38 -0
- package/docs/css_architecture.md +52 -0
- package/docs/popup_open.md +83 -13
- package/package.json +1 -1
package/docs/popup_open.md
CHANGED
|
@@ -7,6 +7,7 @@ What opens a `Dialog` or a `Popover`, and who owns the fact that it is open.
|
|
|
7
7
|
- [Something else opens it: `triggerNaviCommand`](#something-else-opens-it-triggernavicommand)
|
|
8
8
|
- [Which element receives the command](#which-element-receives-the-command)
|
|
9
9
|
- [The anchor](#the-anchor)
|
|
10
|
+
- [Opening it ON something](#opening-it-on-something)
|
|
10
11
|
- [Reacting to open and close](#reacting-to-open-and-close)
|
|
11
12
|
- [Escape cancels, the other gestures keep](#escape-cancels-the-other-gestures-keep)
|
|
12
13
|
- [When `open` is the right answer, and what it costs](#when-open-is-the-right-answer-and-what-it-costs)
|
|
@@ -124,23 +125,92 @@ The `anchor` prop always wins over whatever the command carried.
|
|
|
124
125
|
event's anchor entirely, for a popover that must never be anchored to whatever
|
|
125
126
|
opened it.
|
|
126
127
|
|
|
127
|
-
##
|
|
128
|
+
## Opening it ON something
|
|
129
|
+
|
|
130
|
+
A popup that edits is never only open or closed: it is open **on** something. A
|
|
131
|
+
dialog that is "new radar" from the top of a list and "edit this radar" from a
|
|
132
|
+
row is one dialog with two modes, and the press is the only thing that knows
|
|
133
|
+
which one — so the press says it, with its own value:
|
|
134
|
+
|
|
135
|
+
```jsx
|
|
136
|
+
<Button command="--navi-open" commandfor="radar-dialog">Nouveau radar</Button>
|
|
137
|
+
<Button value={radar.id} command="--navi-open" commandfor="radar-dialog" />
|
|
138
|
+
|
|
139
|
+
<Dialog
|
|
140
|
+
id="radar-dialog"
|
|
141
|
+
unmountWhenClosed
|
|
142
|
+
onOpen={(e) => {
|
|
143
|
+
editedRadarIdSignal.value = e.detail.value; // undefined = création
|
|
144
|
+
}}
|
|
145
|
+
>
|
|
146
|
+
```
|
|
128
147
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
148
|
+
That subject travels as the command's **value**, not as an argument after a
|
|
149
|
+
colon (`--navi-open:radar-42`). The two places say different things and the
|
|
150
|
+
distinction holds across every command: an argument says WHAT the command does —
|
|
151
|
+
`--navi-go-to-slide:edit` needs one, "go" without a destination is not an
|
|
152
|
+
instruction — and `value` says what it is about. "Open" is already a complete
|
|
153
|
+
instruction; the radar is what it is about. A button therefore says it the way it
|
|
154
|
+
says it everywhere else, with `value`, and nothing has to be parsed.
|
|
155
|
+
|
|
156
|
+
A JS decision says the same thing through the same door:
|
|
133
157
|
|
|
134
158
|
```js
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
159
|
+
triggerNaviCommand(dialogRef.current, "--navi-open", event, {
|
|
160
|
+
value: radar.id,
|
|
161
|
+
});
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
`--navi-toggle` carries it too, on the half that opens.
|
|
165
|
+
|
|
166
|
+
### `onOpen` runs before the popup has built anything
|
|
167
|
+
|
|
168
|
+
The order is the whole point, and it is a guarantee, not a coincidence:
|
|
169
|
+
|
|
143
170
|
```
|
|
171
|
+
onOpen(openEvent) ← the subject is decided here
|
|
172
|
+
children mounted ← unmountWhenClosed rebuilds them from scratch, on that subject
|
|
173
|
+
positioned, shown
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
So a dialog whose content is seeded once — an uncontrolled field on a
|
|
177
|
+
`defaultValue`, a form keyed on what it edits — reads the right thing on its very
|
|
178
|
+
first render. Learning it afterwards would mean mounting on the previous subject
|
|
179
|
+
and correcting it, which is a flicker at best and stale fields at worst.
|
|
180
|
+
|
|
181
|
+
The two other places one could listen are not that moment, and it is worth
|
|
182
|
+
knowing why:
|
|
183
|
+
|
|
184
|
+
| where | when it runs | chained to the caller |
|
|
185
|
+
| ----------------------------- | ------------------------------ | --------------------- |
|
|
186
|
+
| `onOpen` | before the content is built | yes — this prop |
|
|
187
|
+
| `onnavi_command` on the popup | after the command has been run | yes |
|
|
188
|
+
| `navi_request_open` listener | before the popup's own handler | on the element only |
|
|
189
|
+
|
|
190
|
+
`onnavi_command` receives the whole command string and its value, but it runs
|
|
191
|
+
**after** the opening: whatever it writes lands on a popup that is already open.
|
|
192
|
+
That works only as long as nothing has read the state yet — which
|
|
193
|
+
`unmountWhenClosed` makes a real race rather than a theoretical one.
|
|
194
|
+
|
|
195
|
+
A `navi_request_open` listener added on the element is the request itself, ahead
|
|
196
|
+
of the popup acting on it — but it is ordered against the popup's own handler by
|
|
197
|
+
registration, and it has to be attached in an effect on a ref. `onOpen` is that
|
|
198
|
+
moment, said as a prop.
|
|
199
|
+
|
|
200
|
+
## Reacting to open and close
|
|
201
|
+
|
|
202
|
+
`onOpen` is called on every open, before the popup builds anything (see
|
|
203
|
+
[above](#opening-it-on-something)); `onClose` is called on every real close, and
|
|
204
|
+
carries `detail.isCancel` when the close meant "revert".
|
|
205
|
+
|
|
206
|
+
```jsx
|
|
207
|
+
<Dialog onOpen={(e) => {}} onClose={(e) => {}}>
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
Neither can veto: `onClose` is the close happening, not a request to close.
|
|
211
|
+
Refusing a close is `onRequestClose`, which belongs to whoever owns an
|
|
212
|
+
`openController` (see `open_controller.js`) — an uncontrolled popup already
|
|
213
|
+
refuses the one close that matters, the one over a control mid-action.
|
|
144
214
|
|
|
145
215
|
### Closing when a button also runs an action
|
|
146
216
|
|