@jsenv/navi 0.29.60 → 0.29.61
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 +50 -11
- package/dist/jsenv_navi.js.map +3 -3
- package/docs/AI_INSTRUCTIONS.md +8 -0
- package/docs/actions.md +32 -0
- package/docs/drag_to_travel.md +68 -9
- package/docs/interactions.md +8 -0
- package/package.json +2 -2
package/dist/jsenv_navi.js
CHANGED
|
@@ -12622,10 +12622,10 @@ defineInteractionDetector({
|
|
|
12622
12622
|
if (canReorder) {
|
|
12623
12623
|
element.setAttribute(REORDERABLE_ATTRIBUTE, "");
|
|
12624
12624
|
}
|
|
12625
|
-
// What @jsenv/dom puts on a drag source:
|
|
12626
|
-
//
|
|
12627
|
-
//
|
|
12628
|
-
//
|
|
12625
|
+
// What @jsenv/dom puts on a drag source: the axes written in the DOM for
|
|
12626
|
+
// whoever else answers this press (a sheet pushed down to close it, a row of
|
|
12627
|
+
// slides), no iOS callout, the touch left to the scroll until the press
|
|
12628
|
+
// becomes a grab, and the listener that lets the grab take it back.
|
|
12629
12629
|
const unmarkDragSource = markDragSource(element, axes);
|
|
12630
12630
|
|
|
12631
12631
|
// What a release can mean, which is not all of what was declared: "grab" is a
|
|
@@ -24189,20 +24189,26 @@ const useUIStateController = (
|
|
|
24189
24189
|
e,
|
|
24190
24190
|
"dispatching synthetic input event without data for checkbox/radio",
|
|
24191
24191
|
);
|
|
24192
|
-
|
|
24192
|
+
dispatchSyntheticInput(
|
|
24193
|
+
el,
|
|
24194
|
+
new Event("input", { bubbles: true }),
|
|
24195
|
+
e,
|
|
24196
|
+
);
|
|
24193
24197
|
syntheticInputFired = true;
|
|
24194
24198
|
} else {
|
|
24195
24199
|
debugUIState(
|
|
24196
24200
|
e,
|
|
24197
24201
|
`dispatching synthetic input event with data "${newUIState}" for input`,
|
|
24198
24202
|
);
|
|
24199
|
-
|
|
24203
|
+
dispatchSyntheticInput(
|
|
24204
|
+
el,
|
|
24200
24205
|
new InputEvent("input", {
|
|
24201
24206
|
bubbles: true,
|
|
24202
24207
|
cancelable: true,
|
|
24203
24208
|
inputType: "insertText",
|
|
24204
24209
|
data: newUIState,
|
|
24205
24210
|
}),
|
|
24211
|
+
e,
|
|
24206
24212
|
);
|
|
24207
24213
|
syntheticInputFired = true;
|
|
24208
24214
|
}
|
|
@@ -24214,7 +24220,11 @@ const useUIStateController = (
|
|
|
24214
24220
|
// A plain Event, not an InputEvent: that is what the browser
|
|
24215
24221
|
// itself fires on a select, and input_effect reads the value off
|
|
24216
24222
|
// the element anyway.
|
|
24217
|
-
|
|
24223
|
+
dispatchSyntheticInput(
|
|
24224
|
+
el,
|
|
24225
|
+
new Event("input", { bubbles: true }),
|
|
24226
|
+
e,
|
|
24227
|
+
);
|
|
24218
24228
|
syntheticInputFired = true;
|
|
24219
24229
|
}
|
|
24220
24230
|
// TODO: textarea
|
|
@@ -25317,14 +25327,16 @@ const useUIFacadeStateController = (props, realUIStateController) => {
|
|
|
25317
25327
|
}
|
|
25318
25328
|
if (
|
|
25319
25329
|
silent &&
|
|
25320
|
-
child.uiState
|
|
25321
|
-
s.realUIStateController.uiState
|
|
25330
|
+
uiStateHoldsNothing(child.uiState) &&
|
|
25331
|
+
!uiStateHoldsNothing(s.realUIStateController.uiState)
|
|
25322
25332
|
) {
|
|
25323
25333
|
// A silent sync means the child's own structure changed (children
|
|
25324
25334
|
// mounted/unmounted), not that the user acted. A child that ends up
|
|
25325
25335
|
// with no value there is one that currently *cannot* express one —
|
|
25326
|
-
// a <List loading> holds no items yet
|
|
25327
|
-
//
|
|
25336
|
+
// a <List loading> holds no items yet, a popup whose items are gone
|
|
25337
|
+
// aggregates to the empty array its stateType falls back to — which
|
|
25338
|
+
// must not read as the user clearing the picker, nor fire its
|
|
25339
|
+
// uiAction.
|
|
25328
25340
|
return;
|
|
25329
25341
|
}
|
|
25330
25342
|
updatingRef.current = true;
|
|
@@ -25445,6 +25457,33 @@ const isInternalEvent = (e) => {
|
|
|
25445
25457
|
return INTERNAL_EVENT_SET.has(e.type);
|
|
25446
25458
|
};
|
|
25447
25459
|
|
|
25460
|
+
/**
|
|
25461
|
+
* The synthetic "input" event is how the new state reaches the outside world
|
|
25462
|
+
* (`uiAction` is called from the input handler it triggers). It carries what
|
|
25463
|
+
* caused the state change so a listener can tell a gesture apart from navi
|
|
25464
|
+
* talking to itself: `findEvent(e, "navi_clear_ui_state")` answers "the user
|
|
25465
|
+
* pressed the clear cross", the same way the facade hops are recognized.
|
|
25466
|
+
*/
|
|
25467
|
+
const dispatchSyntheticInput = (el, inputEvent, causeEvent) => {
|
|
25468
|
+
chainEvent(inputEvent, causeEvent);
|
|
25469
|
+
el.dispatchEvent(inputEvent);
|
|
25470
|
+
};
|
|
25471
|
+
|
|
25472
|
+
// What a control says when it has nothing to say: no value at all, or the empty
|
|
25473
|
+
// array/object a group falls back to while it has no child to aggregate.
|
|
25474
|
+
const uiStateHoldsNothing = (uiState) => {
|
|
25475
|
+
if (uiState === undefined) {
|
|
25476
|
+
return true;
|
|
25477
|
+
}
|
|
25478
|
+
if (Array.isArray(uiState)) {
|
|
25479
|
+
return uiState.length === 0;
|
|
25480
|
+
}
|
|
25481
|
+
if (uiState !== null && typeof uiState === "object") {
|
|
25482
|
+
return Object.keys(uiState).length === 0;
|
|
25483
|
+
}
|
|
25484
|
+
return false;
|
|
25485
|
+
};
|
|
25486
|
+
|
|
25448
25487
|
/**
|
|
25449
25488
|
* Core hooks for wiring navi field components to the action/validation system.
|
|
25450
25489
|
*
|