UNPKG

@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
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