@wordpress/components
Version:
UI components for WordPress.
113 lines (94 loc) • 2.97 kB
JavaScript
;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = Dropdown;
var _element = require("@wordpress/element");
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
var _classnames = _interopRequireDefault(require("classnames"));
var _popover = _interopRequireDefault(require("../popover"));
/**
* External dependencies
*/
/**
* WordPress 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({
renderContent,
renderToggle,
position = 'bottom right',
className,
contentClassName,
expandOnMobile,
headerTitle,
focusOnMount,
popoverProps,
onClose,
onToggle
}) {
var _popoverProps$anchorR;
const containerRef = (0, _element.useRef)();
const [isOpen, setIsOpen] = useObservableState(false, onToggle);
(0, _element.useEffect)(() => () => {
if (onToggle) {
onToggle(false);
}
}, []);
function toggle() {
setIsOpen(!isOpen);
}
/**
* Closes the dropdown if a focus leaves the dropdown wrapper. This is
* intentionally distinct from `onClose` since focus loss from the popover
* is expected to occur when using the Dropdown's toggle button, in which
* case the correct behavior is to keep the dropdown closed. The same applies
* in case when focus is moved to the modal dialog.
*/
function closeIfFocusOutside() {
const {
ownerDocument
} = containerRef.current;
if (!containerRef.current.contains(ownerDocument.activeElement) && !ownerDocument.activeElement.closest('[role="dialog"]')) {
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
}, 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