UNPKG

@octopusdeploy/design-system-components

Version:
75 lines (74 loc) 3.14 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.useDropdownButton = useDropdownButton; exports.useOpenControlledDropdownButton = useOpenControlledDropdownButton; const react_1 = __importDefault(require("react")); const useFocusTrap_1 = require("../../hooks/useFocusTrap"); const isHTMLElement_1 = require("../../utils/isHTMLElement"); function useDropdownButton(options) { const [isOpen, setIsOpen] = react_1.default.useState(false); return useOpenControlledDropdownButton({ ...options, isOpen, setIsOpen }); } function useOpenControlledDropdownButton({ trapFocus, dropdownAriaRole, setIsOpen, isOpen }) { const baseId = react_1.default.useId(); const dropdownId = `dropdown-${baseId}`; const [buttonElement, setButtonElement] = react_1.default.useState(null); const [dropdownElement, setDropdownElement] = react_1.default.useState(null); (0, useFocusTrap_1.useFocusTrap)(dropdownElement, trapFocus); const closeDropdown = react_1.default.useCallback((options) => { setIsOpen(false); if (options?.moveFocusToButton) { buttonElement?.focus(); } }, [setIsOpen, buttonElement]); const toggleDropdown = react_1.default.useCallback(() => { setIsOpen((prev) => !prev); }, [setIsOpen]); react_1.default.useEffect(() => { if (!isOpen || buttonElement === null || dropdownElement === null) return; const onKeyDown = (event) => { if (event.key === "Escape") { closeDropdown({ moveFocusToButton: true }); event.preventDefault(); } }; const onFocusInOrPointerDown = (event) => { if ((0, isHTMLElement_1.isHTMLElement)(event.target) && !buttonElement.contains(event.target) && !dropdownElement.contains(event.target)) { closeDropdown(); } }; window.addEventListener("keydown", onKeyDown); window.addEventListener("focusin", onFocusInOrPointerDown); window.addEventListener("pointerdown", onFocusInOrPointerDown); return () => { window.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, }; }