@jsenv/navi 0.29.456 → 0.29.457
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/dev/jsenv_navi.js +38 -10
- package/dist/dev/jsenv_navi.js.map +3 -3
- package/dist/jsenv_navi.js +38 -10
- package/dist/jsenv_navi.js.map +3 -3
- package/docs/interactions.md +27 -0
- package/package.json +1 -1
package/dist/jsenv_navi.js
CHANGED
|
@@ -24292,10 +24292,9 @@ const useKeyboardShortcuts = (
|
|
|
24292
24292
|
);
|
|
24293
24293
|
shortcut.action = useAction(shortcut.action);
|
|
24294
24294
|
}
|
|
24295
|
-
const onKeyDown = createOnKeyDownForShortcutArray(
|
|
24296
|
-
|
|
24297
|
-
|
|
24298
|
-
);
|
|
24295
|
+
const onKeyDown = createOnKeyDownForShortcutArray(shortcuts, {
|
|
24296
|
+
busyRef: shortcutActionIsBusyRef,
|
|
24297
|
+
});
|
|
24299
24298
|
useEffect(() => {
|
|
24300
24299
|
const element = elementRef.current;
|
|
24301
24300
|
if (!element) {
|
|
@@ -24313,7 +24312,10 @@ const useKeyboardShortcuts = (
|
|
|
24313
24312
|
}, [shortcutDeps]);
|
|
24314
24313
|
};
|
|
24315
24314
|
|
|
24316
|
-
const createOnKeyDownForShortcutArray = (
|
|
24315
|
+
const createOnKeyDownForShortcutArray = (
|
|
24316
|
+
shortcuts,
|
|
24317
|
+
{ busyRef, ownsTarget } = {},
|
|
24318
|
+
) => {
|
|
24317
24319
|
const shortcutsCopy = [];
|
|
24318
24320
|
for (const shortcutCandidate of shortcuts) {
|
|
24319
24321
|
shortcutsCopy.push({
|
|
@@ -24359,10 +24361,20 @@ const createOnKeyDownForShortcutArray = (shortcuts, busyRef) => {
|
|
|
24359
24361
|
}
|
|
24360
24362
|
|
|
24361
24363
|
return (keyboardEvent) => {
|
|
24362
|
-
return applyKeyboardShortcuts(shortcutsCopy, keyboardEvent
|
|
24364
|
+
return applyKeyboardShortcuts(shortcutsCopy, keyboardEvent, {
|
|
24365
|
+
ownsTarget,
|
|
24366
|
+
});
|
|
24363
24367
|
};
|
|
24364
24368
|
};
|
|
24365
|
-
|
|
24369
|
+
/**
|
|
24370
|
+
* @param {object} shortcuts
|
|
24371
|
+
* @param {object} [options]
|
|
24372
|
+
* @param {(target: Element) => boolean} [options.ownsTarget] Whether a
|
|
24373
|
+
* descendant the key was pressed in is one the shortcuts speak for, so its
|
|
24374
|
+
* native behavior (the caret, typing) is theirs to take. Without it only the
|
|
24375
|
+
* listening element itself is; a descendant keeps every key it has a use for.
|
|
24376
|
+
*/
|
|
24377
|
+
const createOnKeyDownForShortcuts = (shortcuts, { ownsTarget } = {}) => {
|
|
24366
24378
|
const shortcutsArray = [];
|
|
24367
24379
|
for (const key of Object.keys(shortcuts)) {
|
|
24368
24380
|
const value = shortcuts[key];
|
|
@@ -24374,16 +24386,18 @@ const createOnKeyDownForShortcuts = (shortcuts) => {
|
|
|
24374
24386
|
}
|
|
24375
24387
|
shortcutsArray.push(shortcut);
|
|
24376
24388
|
}
|
|
24377
|
-
return createOnKeyDownForShortcutArray(shortcutsArray);
|
|
24389
|
+
return createOnKeyDownForShortcutArray(shortcutsArray, { ownsTarget });
|
|
24378
24390
|
};
|
|
24379
24391
|
|
|
24380
|
-
const applyKeyboardShortcuts = (shortcuts, keyboardEvent) => {
|
|
24392
|
+
const applyKeyboardShortcuts = (shortcuts, keyboardEvent, { ownsTarget }) => {
|
|
24381
24393
|
const currentTarget = keyboardEvent.currentTarget;
|
|
24382
24394
|
const target = keyboardEvent.target;
|
|
24383
24395
|
let canIntercept;
|
|
24384
24396
|
if (target === currentTarget) {
|
|
24385
24397
|
// the event occurs on the element itself so we are sure we won't interfere with native behaviors of child elements
|
|
24386
24398
|
canIntercept = true;
|
|
24399
|
+
} else if (ownsTarget && ownsTarget(target)) {
|
|
24400
|
+
canIntercept = true;
|
|
24387
24401
|
} else {
|
|
24388
24402
|
// we need to check if the default action is something that we can allow to be intercepted
|
|
24389
24403
|
const defaultAction = getKeyboardEventDefaultAction(keyboardEvent);
|
|
@@ -24601,6 +24615,17 @@ const isSameKey = (browserEventKey, key) => {
|
|
|
24601
24615
|
* knows what "ctrl+backspace" means, which keys a control may take without
|
|
24602
24616
|
* swallowing what the browser owed them, and which it may not.
|
|
24603
24617
|
*
|
|
24618
|
+
* The control's own element is the exception to that last part. `interactions`
|
|
24619
|
+
* are set up on a field's outer box while the key goes down in its `<input>`,
|
|
24620
|
+
* and that field is the control the declaration speaks for: an ArrowUp declared
|
|
24621
|
+
* on a text field is the field saying what ArrowUp does there, not a container
|
|
24622
|
+
* taking the caret from a field inside it. A field inside a box that declares
|
|
24623
|
+
* keys for something else (a row, a list) keeps every key it has a use for.
|
|
24624
|
+
*
|
|
24625
|
+
* A declared key that matches takes the key: its default does not happen as
|
|
24626
|
+
* well, whether the gate lets the interaction through or refuses it and says
|
|
24627
|
+
* why — the same as a number field's arrows.
|
|
24628
|
+
*
|
|
24604
24629
|
* The interaction is dispatched under its full name, colon included, so
|
|
24605
24630
|
* `findEvent(event, "keyboard:ctrl+backspace")` gets back to it — the shortcut
|
|
24606
24631
|
* that asked is what the action wants to know, not that a key went down.
|
|
@@ -24617,9 +24642,12 @@ defineInteractionDetector({
|
|
|
24617
24642
|
for (const type of types) {
|
|
24618
24643
|
shortcuts[type.slice(KEYBOARD_PREFIX.length)] = (keyboardEvent) => {
|
|
24619
24644
|
trigger(type, keyboardEvent);
|
|
24645
|
+
keyboardEvent.preventDefault();
|
|
24620
24646
|
};
|
|
24621
24647
|
}
|
|
24622
|
-
const onKeyDown = createOnKeyDownForShortcuts(shortcuts
|
|
24648
|
+
const onKeyDown = createOnKeyDownForShortcuts(shortcuts, {
|
|
24649
|
+
ownsTarget: (target) => target === findNearestControlHost(element),
|
|
24650
|
+
});
|
|
24623
24651
|
element.addEventListener("keydown", onKeyDown);
|
|
24624
24652
|
return () => {
|
|
24625
24653
|
element.removeEventListener("keydown", onKeyDown);
|