@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
41 lines (37 loc) • 1.76 kB
JavaScript
import { ensureFocus, getFirstTabbableIn, hasFocusWithin, useUpdateEffect } from "reakit-utils";
import { warning } from "reakit-warning";
export function useFocusOnShow(dialogRef, nestedDialogs, options) {
var initialFocusRef = options.unstable_initialFocusRef;
var shouldFocus = options.visible && options.unstable_autoFocusOnShow;
useUpdateEffect(() => {
var dialog = dialogRef.current;
warning(!!shouldFocus && !dialog, "[reakit/Dialog]", "Can't set initial focus on dialog because `ref` wasn't passed to the dialog element.");
if (!shouldFocus) return;
if (!dialog) return;
if (options.animating) return; // If there're nested open dialogs, let them handle focus
if (nestedDialogs.some(child => child.current && !child.current.hidden)) {
return;
}
if (initialFocusRef !== null && initialFocusRef !== void 0 && initialFocusRef.current) {
initialFocusRef.current.focus({
preventScroll: true
});
} else {
var tabbable = getFirstTabbableIn(dialog, true);
var isActive = () => hasFocusWithin(dialog);
if (tabbable) {
ensureFocus(tabbable, {
preventScroll: true,
isActive
});
} else {
ensureFocus(dialog, {
preventScroll: true,
isActive
});
warning(dialog.tabIndex === undefined || dialog.tabIndex < 0, "It's recommended to have at least one tabbable element inside dialog. The dialog element has been automatically focused.", "If this is the intended behavior, pass `tabIndex={0}` to the dialog element to disable this warning.", dialog);
}
}
}, [dialogRef, shouldFocus, options.animating, nestedDialogs, initialFocusRef]);
}
//# sourceMappingURL=useFocusOnShow.js.map