@jsenv/navi 0.27.66 → 0.27.67
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 +54 -38
- package/dist/jsenv_navi.js.map +12 -12
- package/package.json +1 -1
package/dist/jsenv_navi.js
CHANGED
|
@@ -17418,7 +17418,7 @@ const createCalloutManager = (
|
|
|
17418
17418
|
return;
|
|
17419
17419
|
}
|
|
17420
17420
|
const resolvedAnchorElement =
|
|
17421
|
-
anchorElement || controller.
|
|
17421
|
+
anchorElement || controller.ref.current;
|
|
17422
17422
|
const removeCloseOnCleanup = addTeardown?.(() => {
|
|
17423
17423
|
requestCloseCallout(new CustomEvent("cleanup"), "cleanup");
|
|
17424
17424
|
});
|
|
@@ -17443,7 +17443,7 @@ const createCalloutManager = (
|
|
|
17443
17443
|
tokenData.onClose?.();
|
|
17444
17444
|
}
|
|
17445
17445
|
tokens.clear();
|
|
17446
|
-
const element = controller.
|
|
17446
|
+
const element = controller.ref.current;
|
|
17447
17447
|
if (
|
|
17448
17448
|
shouldTransferFocusFromCallout &&
|
|
17449
17449
|
element &&
|
|
@@ -19491,7 +19491,7 @@ const REQUIRED_CONSTRAINT = {
|
|
|
19491
19491
|
}
|
|
19492
19492
|
return {
|
|
19493
19493
|
message: naviI18n("constraint.required.radio"),
|
|
19494
|
-
target: field.
|
|
19494
|
+
target: field.ref.current,
|
|
19495
19495
|
};
|
|
19496
19496
|
}
|
|
19497
19497
|
if (type === "radio") {
|
|
@@ -19505,7 +19505,7 @@ const REQUIRED_CONSTRAINT = {
|
|
|
19505
19505
|
}
|
|
19506
19506
|
return {
|
|
19507
19507
|
message: naviI18n("constraint.required.radio"),
|
|
19508
|
-
target: field.
|
|
19508
|
+
target: field.ref.current,
|
|
19509
19509
|
};
|
|
19510
19510
|
}
|
|
19511
19511
|
|
|
@@ -19517,7 +19517,7 @@ const REQUIRED_CONSTRAINT = {
|
|
|
19517
19517
|
}
|
|
19518
19518
|
return {
|
|
19519
19519
|
message: naviI18n("constraint.required.checkbox_group"),
|
|
19520
|
-
target: field.
|
|
19520
|
+
target: field.ref.current,
|
|
19521
19521
|
};
|
|
19522
19522
|
}
|
|
19523
19523
|
if (type === "checkbox") {
|
|
@@ -20356,7 +20356,7 @@ const createControlValidation = (
|
|
|
20356
20356
|
|
|
20357
20357
|
const checkValidity = ({
|
|
20358
20358
|
event,
|
|
20359
|
-
requester = controller.
|
|
20359
|
+
requester = controller.ref.current,
|
|
20360
20360
|
fromRequestAction,
|
|
20361
20361
|
} = {}) => {
|
|
20362
20362
|
if (fromRequestAction) {
|
|
@@ -20399,7 +20399,7 @@ const createControlValidation = (
|
|
|
20399
20399
|
...DEFAULT_CONSTRAINT_SET,
|
|
20400
20400
|
...dynamicConstraintSet,
|
|
20401
20401
|
]);
|
|
20402
|
-
const elementSig = getElementSignature(controller.
|
|
20402
|
+
const elementSig = getElementSignature(controller.ref.current);
|
|
20403
20403
|
debugUIState(
|
|
20404
20404
|
event,
|
|
20405
20405
|
`check ${elementSig}: ${constraintSet.size} constraints`,
|
|
@@ -20454,7 +20454,7 @@ const createControlValidation = (
|
|
|
20454
20454
|
if (activeFailedConstraintInfo) {
|
|
20455
20455
|
const titleLess = controller.controlHostProps.title === undefined;
|
|
20456
20456
|
if (titleLess) {
|
|
20457
|
-
const element = controller.
|
|
20457
|
+
const element = controller.ref.current;
|
|
20458
20458
|
if (element) {
|
|
20459
20459
|
element.setAttribute(
|
|
20460
20460
|
"title",
|
|
@@ -20465,7 +20465,7 @@ const createControlValidation = (
|
|
|
20465
20465
|
} else {
|
|
20466
20466
|
const titleLess = controller.controlHostProps.title === undefined;
|
|
20467
20467
|
if (titleLess) {
|
|
20468
|
-
const element = controller.
|
|
20468
|
+
const element = controller.ref.current;
|
|
20469
20469
|
if (element) {
|
|
20470
20470
|
element.removeAttribute("title");
|
|
20471
20471
|
}
|
|
@@ -20479,7 +20479,7 @@ const createControlValidation = (
|
|
|
20479
20479
|
!compareTwoJsValues(constraintValidityState, newConstraintValidityState)
|
|
20480
20480
|
) {
|
|
20481
20481
|
constraintValidityState = newConstraintValidityState;
|
|
20482
|
-
const element = controller.
|
|
20482
|
+
const element = controller.ref.current;
|
|
20483
20483
|
if (element) {
|
|
20484
20484
|
debugUIState(
|
|
20485
20485
|
event,
|
|
@@ -20529,7 +20529,7 @@ const createControlValidation = (
|
|
|
20529
20529
|
event,
|
|
20530
20530
|
{ report = false, fromRequestAction = false } = {},
|
|
20531
20531
|
) => {
|
|
20532
|
-
const elementSig = getElementSignature(controller.
|
|
20532
|
+
const elementSig = getElementSignature(controller.ref.current);
|
|
20533
20533
|
const isValid = checkValidity({ event, fromRequestAction });
|
|
20534
20534
|
if (failingManagedControlValidity) {
|
|
20535
20535
|
// Group/form case: find the actual failing leaf and report on it.
|
|
@@ -21022,7 +21022,7 @@ const createControlInteraction = (
|
|
|
21022
21022
|
// Keep title attribute in sync for accessibility.
|
|
21023
21023
|
const titleLess = !controller.controlHostProps?.title;
|
|
21024
21024
|
if (titleLess) {
|
|
21025
|
-
const element = controller.
|
|
21025
|
+
const element = controller.ref.current;
|
|
21026
21026
|
if (element) {
|
|
21027
21027
|
if (interactionFailedConstraintInfo) {
|
|
21028
21028
|
element.setAttribute(
|
|
@@ -21236,7 +21236,7 @@ const tryActionAfterInteractionAllowed = (
|
|
|
21236
21236
|
if (controller) {
|
|
21237
21237
|
const proxyTargetController = findControlProxyTargetController(controller);
|
|
21238
21238
|
if (proxyTargetController) {
|
|
21239
|
-
elementForAction = proxyTargetController.
|
|
21239
|
+
elementForAction = proxyTargetController.ref.current;
|
|
21240
21240
|
}
|
|
21241
21241
|
const activeController = proxyTargetController ?? controller;
|
|
21242
21242
|
uiState = activeController?.uiState;
|
|
@@ -22359,7 +22359,7 @@ const createControlRules = (
|
|
|
22359
22359
|
* onChildUIAction(child, e, { stateChanged: boolean }): void; // Called when a child fires a UI action
|
|
22360
22360
|
* unregisterChild(child): void; // Called on child unmount
|
|
22361
22361
|
* props: Object;
|
|
22362
|
-
*
|
|
22362
|
+
* ref: Ref; // Used to dispatch DOM events
|
|
22363
22363
|
* getManagedControls(): UIStateController[]; // Returns controls whose validity is managed by this controller
|
|
22364
22364
|
* }
|
|
22365
22365
|
* ```
|
|
@@ -22395,7 +22395,7 @@ const ParentUIStateControllerContext = createContext();
|
|
|
22395
22395
|
* **internalBehavior events** (e.g. radio_sibling_uncheck, state_prop re-sync):
|
|
22396
22396
|
* skip reactions and parent notification — they are programmatic, not user-initiated.
|
|
22397
22397
|
*
|
|
22398
|
-
* The controller exposes `
|
|
22398
|
+
* The controller exposes `ref` so parent groups can dispatch DOM events on children
|
|
22399
22399
|
* (e.g. `resetUIState` cascading `navi_reset_ui_state`).
|
|
22400
22400
|
*/
|
|
22401
22401
|
const useUIStateController = (
|
|
@@ -22417,7 +22417,6 @@ const useUIStateController = (
|
|
|
22417
22417
|
const parentUIStateController = useContext(ParentUIStateControllerContext);
|
|
22418
22418
|
const formContext = useContext(FormContext);
|
|
22419
22419
|
const { id, uiAction } = props;
|
|
22420
|
-
const ref = props.ref;
|
|
22421
22420
|
const isProxy = Boolean(props["navi-control-proxy-for"]);
|
|
22422
22421
|
if (persists === undefined && formContext) {
|
|
22423
22422
|
persists = true;
|
|
@@ -22436,7 +22435,7 @@ const useUIStateController = (
|
|
|
22436
22435
|
);
|
|
22437
22436
|
useLayoutEffect(() => {
|
|
22438
22437
|
const controller = uiStateControllerRef.current;
|
|
22439
|
-
const el = ref.current;
|
|
22438
|
+
const el = controller.ref.current;
|
|
22440
22439
|
if (el) {
|
|
22441
22440
|
el.__uiStateController__ = controller;
|
|
22442
22441
|
}
|
|
@@ -22483,6 +22482,13 @@ const useUIStateController = (
|
|
|
22483
22482
|
// not the resolved/curated host props. useInteractiveProps overwrites
|
|
22484
22483
|
// uiStateController.controlHostProps with the resolved subset on every render.
|
|
22485
22484
|
uiStateController.props = props;
|
|
22485
|
+
// Re-sync to this render's ref object. It's normally stable, but it can
|
|
22486
|
+
// legitimately change identity (e.g. switching from an internal fallback
|
|
22487
|
+
// ref to a forwarded one, or across an interrupted/resumed render such as
|
|
22488
|
+
// a Suspense boundary resolving) — if we kept the original ref forever,
|
|
22489
|
+
// `ref.current` would be stuck at whatever it was at creation time, even
|
|
22490
|
+
// after the controller has moved on to a different, live DOM node.
|
|
22491
|
+
uiStateController.ref = props.ref;
|
|
22486
22492
|
uiStateController.id = props.id; // never suppoed to changed, not supported for now
|
|
22487
22493
|
uiStateController.name = props.name;
|
|
22488
22494
|
|
|
@@ -22508,11 +22514,12 @@ const useUIStateController = (
|
|
|
22508
22514
|
parentUIStateController,
|
|
22509
22515
|
isProxy,
|
|
22510
22516
|
allowNameless,
|
|
22511
|
-
elementRef: ref,
|
|
22512
|
-
props,
|
|
22513
22517
|
|
|
22518
|
+
props,
|
|
22519
|
+
ref: props.ref,
|
|
22514
22520
|
id: props.id,
|
|
22515
22521
|
name: props.name,
|
|
22522
|
+
|
|
22516
22523
|
state: stateInitial,
|
|
22517
22524
|
uiState: stateInitial,
|
|
22518
22525
|
uiStateSignal,
|
|
@@ -22557,7 +22564,7 @@ const useUIStateController = (
|
|
|
22557
22564
|
if (skipCommand) ; else {
|
|
22558
22565
|
const command = uiStateController.controlHostProps.command;
|
|
22559
22566
|
if (command) {
|
|
22560
|
-
const element = uiStateController.
|
|
22567
|
+
const element = uiStateController.ref.current;
|
|
22561
22568
|
if (element) {
|
|
22562
22569
|
debugUIState(
|
|
22563
22570
|
`triggering command "${command}" for "${controlType}"`,
|
|
@@ -22580,7 +22587,9 @@ const useUIStateController = (
|
|
|
22580
22587
|
return false;
|
|
22581
22588
|
}
|
|
22582
22589
|
}
|
|
22583
|
-
const controllerSig = getElementSignature(
|
|
22590
|
+
const controllerSig = getElementSignature(
|
|
22591
|
+
e.currentTarget || uiStateController.ref.current,
|
|
22592
|
+
);
|
|
22584
22593
|
// if (persists) {
|
|
22585
22594
|
// setNavState(prop);
|
|
22586
22595
|
// }
|
|
@@ -22664,7 +22673,7 @@ const useUIStateController = (
|
|
|
22664
22673
|
}
|
|
22665
22674
|
debugUIState(e, `publishUIState(${JSON.stringify(newUIState)})`);
|
|
22666
22675
|
publishUIState(newUIState, e);
|
|
22667
|
-
const el = ref.current;
|
|
22676
|
+
const el = uiStateController.ref.current;
|
|
22668
22677
|
// Always notify the element that its UI state changed.
|
|
22669
22678
|
// Listeners use this to stay in sync (e.g. input_effect.js tracks currentState,
|
|
22670
22679
|
// useUIState subscribes for reactive updates). Separate from navi_set_ui_state
|
|
@@ -22767,7 +22776,7 @@ const useUIStateController = (
|
|
|
22767
22776
|
if (targetController) {
|
|
22768
22777
|
debugUIState(
|
|
22769
22778
|
e,
|
|
22770
|
-
`forwarding set_ui_state "${newUIState}" to ${getElementSignature(targetController.
|
|
22779
|
+
`forwarding set_ui_state "${newUIState}" to ${getElementSignature(targetController.ref.current)}`,
|
|
22771
22780
|
);
|
|
22772
22781
|
const forwardEvent = new CustomEvent("proxy_forward_set_ui_state", {
|
|
22773
22782
|
detail: {},
|
|
@@ -23227,6 +23236,10 @@ const useUIGroupStateController = (
|
|
|
23227
23236
|
const prevValue = existingController.value;
|
|
23228
23237
|
const prevHasValueProp = existingController.hasValueProp;
|
|
23229
23238
|
existingController.props = props;
|
|
23239
|
+
// Re-sync to this render's ref object — see the matching comment in
|
|
23240
|
+
// useUIStateController._checkForUpdates for why this can't be captured
|
|
23241
|
+
// once at creation time and left untouched.
|
|
23242
|
+
existingController.ref = ref;
|
|
23230
23243
|
existingController.id = id;
|
|
23231
23244
|
existingController.name = name;
|
|
23232
23245
|
existingController.value = value;
|
|
@@ -23282,7 +23295,7 @@ const useUIGroupStateController = (
|
|
|
23282
23295
|
uiState: fallbackState,
|
|
23283
23296
|
uiStateSignal,
|
|
23284
23297
|
wantRequesterButtonState,
|
|
23285
|
-
|
|
23298
|
+
ref,
|
|
23286
23299
|
getPropFromState: (uiState) => uiState,
|
|
23287
23300
|
distributeChildUIState: resolvedDistributeChildUIState,
|
|
23288
23301
|
// Cascades newUIState to each monitored child via resolvedDistributeChildUIState,
|
|
@@ -23655,7 +23668,7 @@ const useUIFacadeStateController = (props, realUIStateController) => {
|
|
|
23655
23668
|
const facadeUIStateController = {
|
|
23656
23669
|
controlType: "facade",
|
|
23657
23670
|
props,
|
|
23658
|
-
|
|
23671
|
+
ref: realUIStateController.ref,
|
|
23659
23672
|
uiStateSignal: realUIStateController.uiStateSignal,
|
|
23660
23673
|
registerChild: (child) => {
|
|
23661
23674
|
if (!canRegisterAsFacadeChild(child)) {
|
|
@@ -23977,7 +23990,7 @@ const useControlProps = (props, {
|
|
|
23977
23990
|
return true;
|
|
23978
23991
|
};
|
|
23979
23992
|
const syncUIStateWithDOM = e => {
|
|
23980
|
-
const controlEl = e.currentTarget || uiStateController.
|
|
23993
|
+
const controlEl = e.currentTarget || uiStateController.ref.current;
|
|
23981
23994
|
const value = readControlValue(controlEl);
|
|
23982
23995
|
uiStateController.setUIState(value, e);
|
|
23983
23996
|
};
|
|
@@ -23987,7 +24000,6 @@ const useControlProps = (props, {
|
|
|
23987
24000
|
const triggerUIAction = e => {
|
|
23988
24001
|
syncUIStateWithDOM(e);
|
|
23989
24002
|
};
|
|
23990
|
-
const wasCheckedAtMousedownRef = useRef(false);
|
|
23991
24003
|
const getDefaultEventReactionDefinitions = () => {
|
|
23992
24004
|
const keyDownDefault = e => {
|
|
23993
24005
|
const defaultAction = getKeyboardEventDefaultAction(e);
|
|
@@ -24202,16 +24214,20 @@ const useControlProps = (props, {
|
|
|
24202
24214
|
}
|
|
24203
24215
|
return keyDownDefault(e);
|
|
24204
24216
|
},
|
|
24205
|
-
mouseDown: e => {
|
|
24206
|
-
wasCheckedAtMousedownRef.current = e.currentTarget.checked;
|
|
24207
|
-
},
|
|
24208
24217
|
click: e => {
|
|
24209
|
-
|
|
24210
|
-
|
|
24211
|
-
|
|
24212
|
-
|
|
24213
|
-
|
|
24214
|
-
|
|
24218
|
+
// When a radio is already checked and gets clicked, the browser does NOT
|
|
24219
|
+
// fire an input event (state doesn't change), so syncUIStateWithDOM never
|
|
24220
|
+
// runs. We still want uiAction + command to fire. We can tell whether the
|
|
24221
|
+
// click is on an already-checked radio by comparing our own tracked
|
|
24222
|
+
// uiState (value when checked, undefined when not — see toDomProps) to
|
|
24223
|
+
// this radio's value: it's still the PRE-click value here, since it's
|
|
24224
|
+
// only updated later by the "input" handler. Reading the DOM `.checked`
|
|
24225
|
+
// instead would not work: the browser applies the checked toggle before
|
|
24226
|
+
// dispatching "click", so `.checked` is already the POST-click value
|
|
24227
|
+
// whether or not this was already the checked radio — and worse, a click
|
|
24228
|
+
// that lands on the <label> (not the <input>) never fires "mousedown" on
|
|
24229
|
+
// the input at all, so a DOM-snapshot-at-mousedown approach misses it.
|
|
24230
|
+
if (isRadio && uiStateController.uiState !== undefined) {
|
|
24215
24231
|
return {
|
|
24216
24232
|
name: `click on checked radio`,
|
|
24217
24233
|
allowed: () => triggerUIAction(e),
|
|
@@ -24800,7 +24816,7 @@ const useInteractiveProps = (props, {
|
|
|
24800
24816
|
}
|
|
24801
24817
|
}));
|
|
24802
24818
|
}
|
|
24803
|
-
}, [disabledResolved, readOnlyResolved]);
|
|
24819
|
+
}, [disabledResolved, readOnlyResolved, ref]);
|
|
24804
24820
|
useLayoutEffect(() => {
|
|
24805
24821
|
return () => {
|
|
24806
24822
|
const element = ref.current;
|
|
@@ -25002,7 +25018,7 @@ const useInteractiveProps = (props, {
|
|
|
25002
25018
|
// already aggregated the new state by now, so uiStateSignal is correct.
|
|
25003
25019
|
const parentController = uiStateController.parentUIStateController;
|
|
25004
25020
|
if (parentController && (parentController.controlType === "radio_group" || parentController.controlType === "checkbox_group")) {
|
|
25005
|
-
const parentEl = parentController.
|
|
25021
|
+
const parentEl = parentController.ref.current;
|
|
25006
25022
|
if (parentEl) {
|
|
25007
25023
|
const originalEvent = e.detail.eventChain[0];
|
|
25008
25024
|
dispatchRequestAction(parentEl, {
|