@navikt/ds-react
Version:
React components from the Norwegian Labour and Welfare Administration.
86 lines • 4.42 kB
JavaScript
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
import React, { forwardRef, useCallback, useEffect, useRef } from "react";
import { Slot } from "../../../slot/Slot.js";
import { composeEventHandlers } from "../../../util/composeEventHandlers.js";
import { useCallbackRef, useMergeRefs } from "../../../util/hooks/index.js";
const ENTRY_FOCUS = "rovingFocusGroup.onEntryFocus";
const EVENT_OPTIONS = { bubbles: false, cancelable: true };
const RovingFocus = forwardRef((_a, ref) => {
var { children, asChild, descendants, onKeyDown, onEntryFocus, onMouseDown, onFocus } = _a, rest = __rest(_a, ["children", "asChild", "descendants", "onKeyDown", "onEntryFocus", "onMouseDown", "onFocus"]);
const _ref = React.useRef(null);
const composedRefs = useMergeRefs(ref, _ref);
const handleEntryFocus = useCallbackRef(onEntryFocus);
const isMouseFocusRef = useRef(false);
useEffect(() => {
const node = _ref.current;
if (node) {
node.addEventListener(ENTRY_FOCUS, handleEntryFocus);
return () => node.removeEventListener(ENTRY_FOCUS, handleEntryFocus);
}
}, [handleEntryFocus]);
const handleKeyDown = useCallback((event) => {
var _a, _b;
const loop = false;
const ownerDocument = (_b = (_a = _ref === null || _ref === void 0 ? void 0 : _ref.current) === null || _a === void 0 ? void 0 : _a.ownerDocument) !== null && _b !== void 0 ? _b : globalThis === null || globalThis === void 0 ? void 0 : globalThis.document;
const idx = descendants
.values()
.findIndex((x) => x.node.isSameNode(ownerDocument.activeElement));
const nextItem = () => {
var _a;
const next = descendants.nextEnabled(idx, loop);
(_a = next === null || next === void 0 ? void 0 : next.node) === null || _a === void 0 ? void 0 : _a.focus();
};
const prevItem = () => {
var _a;
const prev = descendants.prevEnabled(idx, loop);
(_a = prev === null || prev === void 0 ? void 0 : prev.node) === null || _a === void 0 ? void 0 : _a.focus();
};
const firstItem = () => {
var _a;
const first = descendants.firstEnabled();
(_a = first === null || first === void 0 ? void 0 : first.node) === null || _a === void 0 ? void 0 : _a.focus();
};
const lastItem = () => {
var _a;
const last = descendants.lastEnabled();
(_a = last === null || last === void 0 ? void 0 : last.node) === null || _a === void 0 ? void 0 : _a.focus();
};
const keyMap = {
ArrowUp: prevItem,
ArrowDown: nextItem,
Home: firstItem,
End: lastItem,
};
const action = keyMap[event.key];
if (action) {
event.preventDefault();
action(event);
}
}, [descendants]);
const Comp = asChild ? Slot : "div";
return (React.createElement(Comp, Object.assign({ ref: composedRefs }, rest, { tabIndex: descendants.enabledCount() === 0 ? -1 : 0, style: Object.assign({ outline: "none" }, rest.style), onKeyDown: composeEventHandlers(onKeyDown, handleKeyDown), onMouseDown: composeEventHandlers(onMouseDown, () => {
isMouseFocusRef.current = true;
}), onFocus: composeEventHandlers(onFocus, (event) => {
var _a;
if (event.target === event.currentTarget) {
const entryFocusEvent = new CustomEvent(ENTRY_FOCUS, EVENT_OPTIONS);
event.currentTarget.dispatchEvent(entryFocusEvent);
if (!entryFocusEvent.defaultPrevented) {
(_a = descendants.firstEnabled()) === null || _a === void 0 ? void 0 : _a.node.focus({ preventScroll: true });
}
}
isMouseFocusRef.current = false;
}) }), children));
});
export { RovingFocus };
//# sourceMappingURL=RovingFocus.js.map