Files
Speedtest-Tracker/conf/site/node_modules/react-overlays/esm/DropdownMenu.js
Henry Whitaker 3a99dc5495 Updated to v1.3.3
2020-05-05 09:34:02 +01:00

195 lines
6.2 KiB
JavaScript
Vendored

import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
import _extends from "@babel/runtime/helpers/esm/extends";
import PropTypes from 'prop-types';
import React, { useContext, useRef } from 'react';
import useCallbackRef from '@restart/hooks/useCallbackRef';
import DropdownContext from './DropdownContext';
import usePopper, { toModifierMap } from './usePopper';
import useRootClose from './useRootClose';
var noop = function noop() {};
/**
* @memberOf Dropdown
* @param {object} options
* @param {boolean} options.flip Automatically adjust the menu `drop` position based on viewport edge detection
* @param {boolean} options.show Display the menu manually, ignored in the context of a `Dropdown`
* @param {boolean} options.usePopper opt in/out of using PopperJS to position menus. When disabled you must position it yourself.
* @param {string} options.rootCloseEvent The pointer event to listen for when determining "clicks outside" the menu for triggering a close.
* @param {object} options.popperConfig Options passed to the [`usePopper`](/api/usePopper) hook.
*/
export function useDropdownMenu(options) {
var _modifiers$arrow;
if (options === void 0) {
options = {};
}
var context = useContext(DropdownContext);
var _useCallbackRef = useCallbackRef(),
arrowElement = _useCallbackRef[0],
attachArrowRef = _useCallbackRef[1];
var hasShownRef = useRef(false);
var _options = options,
flip = _options.flip,
rootCloseEvent = _options.rootCloseEvent,
_options$popperConfig = _options.popperConfig,
popperConfig = _options$popperConfig === void 0 ? {} : _options$popperConfig,
_options$usePopper = _options.usePopper,
shouldUsePopper = _options$usePopper === void 0 ? !!context : _options$usePopper;
var show = (context == null ? void 0 : context.show) == null ? options.show : context.show;
var alignEnd = (context == null ? void 0 : context.alignEnd) == null ? options.alignEnd : context.alignEnd;
if (show && !hasShownRef.current) {
hasShownRef.current = true;
}
var handleClose = function handleClose(e) {
context == null ? void 0 : context.toggle(false, e);
};
var _ref = context || {},
drop = _ref.drop,
setMenu = _ref.setMenu,
menuElement = _ref.menuElement,
toggleElement = _ref.toggleElement;
var placement = alignEnd ? 'bottom-end' : 'bottom-start';
if (drop === 'up') placement = alignEnd ? 'top-end' : 'top-start';else if (drop === 'right') placement = alignEnd ? 'right-end' : 'right-start';else if (drop === 'left') placement = alignEnd ? 'left-end' : 'left-start';
var modifiers = toModifierMap(popperConfig.modifiers);
var popper = usePopper(toggleElement, menuElement, _extends({}, popperConfig, {
placement: placement,
enabled: !!(shouldUsePopper && show),
modifiers: _extends({}, modifiers, {
eventListeners: {
enabled: !!show
},
arrow: _extends({}, modifiers.arrow, {
enabled: !!arrowElement,
options: _extends({}, (_modifiers$arrow = modifiers.arrow) == null ? void 0 : _modifiers$arrow.options, {
element: arrowElement
})
}),
flip: _extends({
enabled: !!flip
}, modifiers.flip)
})
}));
var menu;
var menuProps = {
ref: setMenu || noop,
'aria-labelledby': toggleElement == null ? void 0 : toggleElement.id
};
var childArgs = {
show: show,
alignEnd: alignEnd,
hasShown: hasShownRef.current,
close: handleClose
};
if (!shouldUsePopper) {
menu = _extends({}, childArgs, {
props: menuProps
});
} else {
menu = _extends({}, popper, {}, childArgs, {
props: _extends({}, menuProps, {
style: popper.styles
}),
arrowProps: {
ref: attachArrowRef,
style: popper.arrowStyles
}
});
}
useRootClose(menuElement, handleClose, {
clickTrigger: rootCloseEvent,
disabled: !(menu && show)
});
return menu;
}
var propTypes = {
/**
* A render prop that returns a Menu element. The `props`
* argument should spread through to **a component that can accept a ref**.
*
* @type {Function ({
* show: boolean,
* alignEnd: boolean,
* close: (?SyntheticEvent) => void,
* placement: Placement,
* outOfBoundaries: ?boolean,
* scheduleUpdate: () => void,
* props: {
* ref: (?HTMLElement) => void,
* style: { [string]: string | number },
* aria-labelledby: ?string
* },
* arrowProps: {
* ref: (?HTMLElement) => void,
* style: { [string]: string | number },
* },
* }) => React.Element}
*/
children: PropTypes.func.isRequired,
/**
* Controls the visible state of the menu, generally this is
* provided by the parent `Dropdown` component,
* but may also be specified as a prop directly.
*/
show: PropTypes.bool,
/**
* Aligns the dropdown menu to the 'end' of it's placement position.
* Generally this is provided by the parent `Dropdown` component,
* but may also be specified as a prop directly.
*/
alignEnd: PropTypes.bool,
/**
* Enables the Popper.js `flip` modifier, allowing the Dropdown to
* automatically adjust it's placement in case of overlap with the viewport or toggle.
* Refer to the [flip docs](https://popper.js.org/popper-documentation.html#modifiers..flip.enabled) for more info
*/
flip: PropTypes.bool,
usePopper: PropTypes.oneOf([true, false]),
/**
* A set of popper options and props passed directly to react-popper's Popper component.
*/
popperConfig: PropTypes.object,
/**
* Override the default event used by RootCloseWrapper.
*/
rootCloseEvent: PropTypes.string
};
var defaultProps = {
usePopper: true
};
/**
* Also exported as `<Dropdown.Menu>` from `Dropdown`.
*
* @displayName DropdownMenu
* @memberOf Dropdown
*/
function DropdownMenu(_ref2) {
var children = _ref2.children,
options = _objectWithoutPropertiesLoose(_ref2, ["children"]);
var args = useDropdownMenu(options);
return /*#__PURE__*/React.createElement(React.Fragment, null, args.hasShown ? children(args) : null);
}
DropdownMenu.displayName = 'ReactOverlaysDropdownMenu';
DropdownMenu.propTypes = propTypes;
DropdownMenu.defaultProps = defaultProps;
/** @component */
export default DropdownMenu;