UNPKG

@gechiui/components

Version:
120 lines (100 loc) 3.27 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = Dropdown; var _element = require("@gechiui/element"); var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _classnames = _interopRequireDefault(require("classnames")); var _popover = _interopRequireDefault(require("../popover")); // @ts-nocheck /** * External dependencies */ /** * GeChiUI dependencies */ /** * Internal dependencies */ function useObservableState(initialState, onStateChange) { const [state, setState] = (0, _element.useState)(initialState); return [state, value => { setState(value); if (onStateChange) { onStateChange(value); } }]; } function Dropdown(_ref) { var _popoverProps$anchorR; let { renderContent, renderToggle, position = 'bottom right', className, contentClassName, expandOnMobile, headerTitle, focusOnMount, popoverProps, onClose, onToggle } = _ref; const containerRef = (0, _element.useRef)(); const [isOpen, setIsOpen] = useObservableState(false, onToggle); (0, _element.useEffect)(() => () => { if (onToggle) { onToggle(false); } }, []); function toggle() { setIsOpen(!isOpen); } /** * Closes the popover when focus leaves it unless the toggle was pressed or * focus has moved to a separate dialog. The former is to let the toggle * handle closing the popover and the latter is to preserve presence in * case a dialog has opened, allowing focus to return when it's dismissed. */ function closeIfFocusOutside() { const { ownerDocument } = containerRef.current; const dialog = ownerDocument.activeElement.closest('[role="dialog"]'); if (!containerRef.current.contains(ownerDocument.activeElement) && (!dialog || dialog.contains(containerRef.current))) { close(); } } function close() { if (onClose) { onClose(); } setIsOpen(false); } const args = { isOpen, onToggle: toggle, onClose: close }; return (0, _element.createElement)("div", { className: (0, _classnames.default)('components-dropdown', className), ref: containerRef // Some UAs focus the closest focusable parent when the toggle is // clicked. Making this div focusable ensures such UAs will focus // it and `closeIfFocusOutside` can tell if the toggle was clicked. , tabIndex: "-1" }, renderToggle(args), isOpen && (0, _element.createElement)(_popover.default, (0, _extends2.default)({ position: position, onClose: close, onFocusOutside: closeIfFocusOutside, expandOnMobile: expandOnMobile, headerTitle: headerTitle, focusOnMount: focusOnMount }, popoverProps, { anchorRef: (_popoverProps$anchorR = popoverProps === null || popoverProps === void 0 ? void 0 : popoverProps.anchorRef) !== null && _popoverProps$anchorR !== void 0 ? _popoverProps$anchorR : containerRef.current, className: (0, _classnames.default)('components-dropdown__content', popoverProps ? popoverProps.className : undefined, contentClassName) }), renderContent(args))); } //# sourceMappingURL=index.js.map