47 lines
1.6 KiB
JavaScript
47 lines
1.6 KiB
JavaScript
import { getActiveElement } from "../shared/getActiveElement.js";
|
|
|
|
//#region src/RovingFocus/utils.ts
|
|
const ENTRY_FOCUS = "rovingFocusGroup.onEntryFocus";
|
|
const EVENT_OPTIONS = {
|
|
bubbles: false,
|
|
cancelable: true
|
|
};
|
|
const MAP_KEY_TO_FOCUS_INTENT = {
|
|
ArrowLeft: "prev",
|
|
ArrowUp: "prev",
|
|
ArrowRight: "next",
|
|
ArrowDown: "next",
|
|
PageUp: "first",
|
|
Home: "first",
|
|
PageDown: "last",
|
|
End: "last"
|
|
};
|
|
function getDirectionAwareKey(key, dir) {
|
|
if (dir !== "rtl") return key;
|
|
return key === "ArrowLeft" ? "ArrowRight" : key === "ArrowRight" ? "ArrowLeft" : key;
|
|
}
|
|
function getFocusIntent(event, orientation, dir) {
|
|
const key = getDirectionAwareKey(event.key, dir);
|
|
if (orientation === "vertical" && ["ArrowLeft", "ArrowRight"].includes(key)) return void 0;
|
|
if (orientation === "horizontal" && ["ArrowUp", "ArrowDown"].includes(key)) return void 0;
|
|
return MAP_KEY_TO_FOCUS_INTENT[key];
|
|
}
|
|
function focusFirst(candidates, preventScroll = false) {
|
|
const PREVIOUSLY_FOCUSED_ELEMENT = getActiveElement();
|
|
for (const candidate of candidates) {
|
|
if (candidate === PREVIOUSLY_FOCUSED_ELEMENT) return;
|
|
candidate.focus({ preventScroll });
|
|
if (getActiveElement() !== PREVIOUSLY_FOCUSED_ELEMENT) return;
|
|
}
|
|
}
|
|
/**
|
|
* Wraps an array around itself at a given start index
|
|
* Example: `wrapArray(['a', 'b', 'c', 'd'], 2) === ['c', 'd', 'a', 'b']`
|
|
*/
|
|
function wrapArray(array, startIndex) {
|
|
return array.map((_, index) => array[(startIndex + index) % array.length]);
|
|
}
|
|
|
|
//#endregion
|
|
export { ENTRY_FOCUS, EVENT_OPTIONS, MAP_KEY_TO_FOCUS_INTENT, focusFirst, getFocusIntent, wrapArray };
|
|
//# sourceMappingURL=utils.js.map
|