UNPKG

@octopusdeploy/design-system-components

Version:
75 lines (74 loc) 3.15 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.useDropdownButton = useDropdownButton; exports.useOpenControlledDropdownButton = useOpenControlledDropdownButton; const react_1 = require("react"); const useFocusTrap_1 = require("../../hooks/useFocusTrap"); const isHTMLElement_1 = require("../../utils/isHTMLElement"); function useDropdownButton(options) { const [isOpen, setIsOpen] = (0, react_1.useState)(false); return useOpenControlledDropdownButton({ ...options, isOpen, setIsOpen }); } function useOpenControlledDropdownButton({ trapFocus, dropdownAriaRole, setIsOpen, isOpen }) { const baseId = (0, react_1.useId)(); const dropdownId = `dropdown-${baseId}`; const [buttonElement, setButtonElement] = (0, react_1.useState)(null); const [dropdownElement, setDropdownElement] = (0, react_1.useState)(null); (0, useFocusTrap_1.useFocusTrap)(dropdownElement, trapFocus); const closeDropdown = (0, react_1.useCallback)((options) => { setIsOpen(false); if (options?.moveFocusToButton) { buttonElement?.focus(); } }, [setIsOpen, buttonElement]); const toggleDropdown = (0, react_1.useCallback)(() => { setIsOpen((prev) => !prev); }, [setIsOpen]); (0, react_1.useEffect)(() => { if (!isOpen || buttonElement === null || dropdownElement === null) return; const onKeyDown = (event) => { if (event.key === "Escape") { closeDropdown({ moveFocusToButton: true }); event.preventDefault(); event.stopPropagation(); } }; const onFocusInOrPointerDown = (event) => { if ((0, isHTMLElement_1.isHTMLElement)(event.target) && !buttonElement.contains(event.target) && !dropdownElement.contains(event.target)) { closeDropdown(); } }; buttonElement.addEventListener("keydown", onKeyDown); dropdownElement.addEventListener("keydown", onKeyDown); window.addEventListener("focusin", onFocusInOrPointerDown); window.addEventListener("pointerdown", onFocusInOrPointerDown); return () => { buttonElement.removeEventListener("keydown", onKeyDown); dropdownElement.removeEventListener("keydown", onKeyDown); window.removeEventListener("focusin", onFocusInOrPointerDown); window.removeEventListener("pointerdown", onFocusInOrPointerDown); }; }, [isOpen, buttonElement, dropdownElement, closeDropdown]); const buttonAriaAttributes = { "aria-expanded": isOpen ? "true" : "false", "aria-haspopup": dropdownAriaRole, "aria-controls": isOpen ? dropdownId : undefined, }; const dropdownAttributes = { dropdownId, dropdownAriaAttributes: { role: dropdownAriaRole, }, }; return { isOpen, closeDropdown, toggleDropdown, buttonElement, setButtonRef: setButtonElement, buttonAriaAttributes, setDropdownRef: setDropdownElement, dropdownAttributes, }; }