@jsenv/navi 0.29.85 → 0.29.86

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.
@@ -11,6 +11,7 @@ whose value is an object needs in its popup.
11
11
  - [`<Form>`: the shape, plus a send](#form-the-shape-plus-a-send)
12
12
  - [Naming, and what a nameless group does](#naming-and-what-a-nameless-group-does)
13
13
  - [A picker whose value is an object](#a-picker-whose-value-is-an-object)
14
+ - [One line, one key](#one-line-one-key)
14
15
  - [A settings sheet](#a-settings-sheet)
15
16
  - [`Group` is not `ControlGroup`](#group-is-not-controlgroup)
16
17
 
@@ -113,6 +114,39 @@ Two things to get right:
113
114
  kind a scalar type and there is no group to distribute anything — the whole
114
115
  object lands on one control, which is how `"[object Object]"` ends up in a
115
116
  url.
117
+ - **A control that helps FIND the answer is not the answer.** A search box above
118
+ a long list, a "select all" beside it: they are tools, and a tool says so with
119
+ `allowNameless`. The picker then walks past it and talks to the list, which is
120
+ what a popup made of one choice and the means to reach it needs.
121
+
122
+ ```jsx
123
+ <Picker name="place_ids" type="array">
124
+ <Input allowNameless placeholder="chercher" navi-list="places" />
125
+ <List id="places" selectable multiple>
126
+
127
+ </List>
128
+ </Picker>
129
+ ```
130
+
131
+ ## One line, one key
132
+
133
+ A row that opens a popup is one control, so what it answers arrives under its
134
+ one name. A row answering two questions at once — where the level comes from
135
+ AND which levels, when it starts AND when it ends — hands back a sub-object:
136
+
137
+ ```jsx
138
+ <Picker name="level" type="object"> // { level: { level_mode, levels } }
139
+ <Picker name="hours" type="object"> // { hours: { from_minute, to_minute } }
140
+ ```
141
+
142
+ Flattening those into the sent object is the caller's business
143
+ (`{ ...value.level, ...value.hours }`), and it is the only reasonable place for
144
+ it: a picker with no name of its own could not be collected, and one merging its
145
+ keys into the object around it would take the row's own identity away — nothing
146
+ would say which row a key came from, nor which row to put an incoming value
147
+ back on. A `<ControlGroup>` with no name IS that merge, and it exists for the
148
+ case where there is no row: several controls in one screen, no door between
149
+ them.
116
150
 
117
151
  ## A settings sheet
118
152
 
@@ -8,6 +8,7 @@ somewhere else in the app.
8
8
  - [A bound signal works in both directions](#a-bound-signal-works-in-both-directions)
9
9
  - [`signal` + `defaultValue`: the answer and where it starts](#signal--defaultvalue-the-answer-and-where-it-starts)
10
10
  - [What a signal holds, control by control](#what-a-signal-holds-control-by-control)
11
+ - [Empty keeps the shape of the question](#empty-keeps-the-shape-of-the-question)
11
12
  - [Which controls take a `signal`](#which-controls-take-a-signal)
12
13
  - [`value` and `signal` exclude each other](#value-and-signal-exclude-each-other)
13
14
  - [A `stateSignal` brings more than a value](#a-statesignal-brings-more-than-a-value)
@@ -117,6 +118,31 @@ writes it, and what they change is written back into it. One signal for a screen
117
118
  whose values arrive together — see
118
119
  [create_and_edit.md](./create_and_edit.md#two-screens-two-states).
119
120
 
121
+ ## Empty keeps the shape of the question
122
+
123
+ What a control is worth when it holds nothing has the type of what it holds when
124
+ it holds something. A list of days nobody picked is `[]`, not `""`:
125
+
126
+ | control | empty is |
127
+ | ------------------------------------------------- | -------- |
128
+ | `Picker type="array"`, `List selectable multiple` | `[]` |
129
+ | `Picker type="object"` | `{}` |
130
+ | text/number/date `Input`, `Select` | `""` |
131
+ | `Input type="checkbox" value={true}` | `false` |
132
+ | radio, checkbox holding a value of its own | absent |
133
+
134
+ This is what a clear (`--navi-clear`, a row's cross) leaves behind and what the
135
+ object around it carries, so the conversion nobody writes — `value.days || []` —
136
+ is not needed, and not needed only after having watched the wrong shape reach
137
+ the server.
138
+
139
+ A checkbox is a member of a set, the way HTML has it: checked it carries its
140
+ `value` (`"on"` when it was given none), unchecked it carries nothing at all —
141
+ which is what lets several checkboxes sharing a name aggregate into an array. A
142
+ checkbox that is a yes/no rather than a member says so with `value={true}`, and
143
+ is then `true` or `false`. Its bound `signal` holds the boolean either way (see
144
+ the table above): what a signal on a checkbox is about is whether it is checked.
145
+
120
146
  ## Which controls take a `signal`
121
147
 
122
148
  All of them: `Input` (every type), `Picker`, `Select`, `Wheel`, `Spin`,
@@ -131,7 +157,8 @@ something else read where the slides are — or move them by writing it.
131
157
  Inside a `List selectable` you can bind the list, or give each `List.Item` its
132
158
  own `selected` — but not expect the two to arbitrate. An item that declares
133
159
  `selected` is answering for itself, and the list's signal does not reposition
134
- it.
160
+ it. On screen that reads as a list where clicking does nothing, so navi says it
161
+ in dev the moment the two claims meet: bind one end or the other, not both.
135
162
 
136
163
  ## `value` and `signal` exclude each other
137
164
 
@@ -168,7 +168,10 @@ row whose value is carried by a hidden input beside it) says so with
168
168
  <Picker allowNameless ui={…}>
169
169
  ```
170
170
 
171
- It is then neither collected nor complained about.
171
+ It is then neither collected nor complained about — and inside a picker's popup
172
+ it is not the control the picker talks to either, which is what lets a search
173
+ box sit above the list that IS the answer (see
174
+ [control_object.md](./control_object.md#a-picker-whose-value-is-an-object)).
172
175
 
173
176
  ## See also
174
177
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jsenv/navi",
3
- "version": "0.29.85",
3
+ "version": "0.29.86",
4
4
  "type": "module",
5
5
  "description": "Library of components including navigation to create frontend applications",
6
6
  "repository": {