@jsenv/navi 0.29.95 → 0.29.96

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.
@@ -177,7 +177,7 @@ it. It matters most inside a picker's popup, where nothing else would bring the
177
177
  value back down: a picker's value IS what the control in its popup holds, so the
178
178
  façade never echoes it back.
179
179
 
180
- Three things follow, and all three were paid for twice before being written
180
+ Four things follow, and each of them was paid for twice before being written
181
181
  here:
182
182
 
183
183
  - **the group's value has to be the view that carries the MOST.** Four seats say
@@ -188,15 +188,35 @@ here:
188
188
  can be computed from;
189
189
  - **the Map must name EVERY child**, the derived view included. A child the Map
190
190
  does not name is left where it is — which reads as "the list never fills";
191
- - **a gesture that moves two children writes the GROUP's value, not the two
192
- children.** Dragging somebody from one seat to another is one intention and
193
- two writes; written one after the other, the group re-places between them, the
194
- rule sees a free seat and puts the person back where they were. Written as one
195
- change of the group's value there is nothing in between. (Wrapping the two
196
- writes in a signal `batch()` does NOT do it: the group aggregates on each
197
- child's change, not on the render that follows.)
191
+ - **name the children you WANT, never exclude the one you don't.** A group holds
192
+ more than the views: a search box, a filter, whatever the popup needs. Reading
193
+ the seats as "every child except the list" collects those too, and the value
194
+ ends up with five slots for four seats. Finding them by name says what it
195
+ means;
196
+ - **a gesture that moves two children must never leave the value in an
197
+ in-between.** Dragging somebody from one seat to another is one intention and
198
+ two writes, and the group aggregates between them: for one instant the person
199
+ is in the list and in no seat, which a value that IS the seating has no room
200
+ for. Measured, that instant costs the person — the aggregate drops them and
201
+ the distribute unticks them before the second write lands. Two ways out, and
202
+ the first is the one to prefer:
203
+
204
+ 1. **write the group's value once.** `rowSignal.value = slots` with both seats
205
+ already moved: there is no in-between at all. Available when the row is
206
+ where the placement lives;
207
+ 2. **write the destination first**, when the seats are the truth and must stay
208
+ separate signals. The person is somewhere at every observable moment (in
209
+ two seats for an instant, which the rule then resolves), instead of nowhere.
210
+ Source-first loses them — measured, and silently.
211
+
212
+ Wrapping the two writes in a signal `batch()` does NOT help: the group
213
+ aggregates on each child's change, not on the render that follows.
198
214
 
199
215
  ```jsx
216
+ // the seats are found by name, never as "everything that is not the list"
217
+ const seatChildren = (children) =>
218
+ SEAT_NAMES.map((name) => children.find((child) => child.name === name));
219
+
200
220
  // the value IS the seating; the list is a view of it
201
221
  <ControlGroup
202
222
  aggregateChildStates={(children) => {…}} // seats, minus who the list dropped, plus who it added
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jsenv/navi",
3
- "version": "0.29.95",
3
+ "version": "0.29.96",
4
4
  "type": "module",
5
5
  "description": "Library of components including navigation to create frontend applications",
6
6
  "repository": {