@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
47 lines (40 loc) • 2.1 kB
JavaScript
import * as React from "react";
import { getDocument, isButton } from "reakit-utils";
export function useDisclosureRef(dialogRef, options) {
var ref = React.useRef(null);
React.useEffect(() => {
if (options.visible || options.animating) return undefined; // We get the last focused element before the dialog opens, so we can move
// focus back to it when the dialog closes.
var onFocus = event => {
var target = event.target;
if ("focus" in target) {
ref.current = target;
if (options.disclosureRef) {
options.disclosureRef.current = target;
}
}
};
var document = getDocument(dialogRef.current);
document.addEventListener("focusin", onFocus);
return () => document.removeEventListener("focusin", onFocus);
}, [options.visible, options.animating, options.disclosureRef, dialogRef]);
React.useEffect(() => {
var _options$disclosureRe;
if (!options.visible || options.animating) return undefined; // Safari and Firefox on MacOS don't focus on buttons on mouse down.
// Instead, they focus on the closest focusable parent (ultimately, the
// body element). This works around that by preventing that behavior and
// forcing focus on the disclosure button. Otherwise, we wouldn't be able
// to close the dialog by clicking again on the disclosure.
var onMouseDown = event => {
var element = event.currentTarget;
if (!isButton(element)) return;
event.preventDefault();
element.focus();
};
var disclosure = ((_options$disclosureRe = options.disclosureRef) === null || _options$disclosureRe === void 0 ? void 0 : _options$disclosureRe.current) || ref.current;
disclosure === null || disclosure === void 0 ? void 0 : disclosure.addEventListener("mousedown", onMouseDown);
return () => disclosure === null || disclosure === void 0 ? void 0 : disclosure.removeEventListener("mousedown", onMouseDown);
}, [options.visible, options.animating, options.disclosureRef]);
return options.disclosureRef || ref;
}
//# sourceMappingURL=useDisclosureRef.js.map