@renderlesskit/react
Version:
Collection of headless components/hooks that are accessible, composable, customizable from low level to build your own UI & Design System powered by Reakit
35 lines (31 loc) • 1.48 kB
JavaScript
import * as React from "react";
import { getActiveElement, getDocument, getNextActiveElementOnBlur } from "reakit-utils";
import { warning } from "reakit-warning";
import { useSafeLayoutEffect } from "@chakra-ui/hooks";
function isActualElement(element) {
return element && element.tagName && element.tagName !== "HTML" && element !== getDocument(element).body;
}
export function useFocusOnBlur(dialogRef, options) {
var [blurred, scheduleFocus] = React.useReducer(n => n + 1, 0);
useSafeLayoutEffect(() => {
var dialog = dialogRef.current;
if (!options.visible) return;
if (!blurred) return; // After blur, if the active element isn't an actual element, this probably
// means that element.blur() was called on an element inside the dialog.
// In this case, the browser will automatically focus the body element.
// So we move focus back to the dialog.
if (!isActualElement(getActiveElement(dialog))) {
warning(!dialog, "Can't focus dialog after a nested element got blurred because `ref` wasn't passed to the component");
dialog === null || dialog === void 0 ? void 0 : dialog.focus();
}
}, [blurred, dialogRef]);
var onBlur = React.useCallback(event => {
if (!options.visible) return;
var nextActiveElement = getNextActiveElementOnBlur(event);
if (!isActualElement(nextActiveElement)) {
scheduleFocus();
}
}, [options.visible]);
return onBlur;
}
//# sourceMappingURL=useFocusOnBlur.js.map