UNPKG

@navikt/ds-react

Version:

React components from the Norwegian Labour and Welfare Administration.

86 lines 4.42 kB
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