Gazebo_simulation-Frontend/node_modules/react-overlays/cjs/Dropdown.js
2020-12-21 10:29:31 -05:00

272 lines
8.7 KiB
JavaScript

"use strict";
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
exports.__esModule = true;
exports["default"] = void 0;
var _matches = _interopRequireDefault(require("dom-helpers/matches"));
var _querySelectorAll = _interopRequireDefault(require("dom-helpers/querySelectorAll"));
var _react = _interopRequireWildcard(require("react"));
var _propTypes = _interopRequireDefault(require("prop-types"));
var _uncontrollable = require("uncontrollable");
var _usePrevious = _interopRequireDefault(require("@restart/hooks/usePrevious"));
var _useCallbackRef2 = _interopRequireDefault(require("@restart/hooks/useCallbackRef"));
var _useForceUpdate = _interopRequireDefault(require("@restart/hooks/useForceUpdate"));
var _useEventCallback = _interopRequireDefault(require("@restart/hooks/useEventCallback"));
var _DropdownContext = _interopRequireDefault(require("./DropdownContext"));
var _DropdownMenu = _interopRequireDefault(require("./DropdownMenu"));
var _DropdownToggle = _interopRequireDefault(require("./DropdownToggle"));
var propTypes = {
/**
* A render prop that returns the root dropdown element. The `props`
* argument should spread through to an element containing _both_ the
* menu and toggle in order to handle keyboard events for focus management.
*
* @type {Function ({
* props: {
* onKeyDown: (SyntheticEvent) => void,
* },
* }) => React.Element}
*/
children: _propTypes["default"].func.isRequired,
/**
* Determines the direction and location of the Menu in relation to it's Toggle.
*/
drop: _propTypes["default"].oneOf(['up', 'left', 'right', 'down']),
/**
* Controls the focus behavior for when the Dropdown is opened. Set to
* `true` to always focus the first menu item, `keyboard` to focus only when
* navigating via the keyboard, or `false` to disable completely
*
* The Default behavior is `false` **unless** the Menu has a `role="menu"`
* where it will default to `keyboard` to match the recommended [ARIA Authoring practices](https://www.w3.org/TR/wai-aria-practices-1.1/#menubutton).
*/
focusFirstItemOnShow: _propTypes["default"].oneOf([false, true, 'keyboard']),
/**
* A css slector string that will return __focusable__ menu items.
* Selectors should be relative to the menu component:
* e.g. ` > li:not('.disabled')`
*/
itemSelector: _propTypes["default"].string.isRequired,
/**
* Align the menu to the 'end' side of the placement side of the Dropdown toggle. The default placement is `top-start` or `bottom-start`.
*/
alignEnd: _propTypes["default"].bool,
/**
* Whether or not the Dropdown is visible.
*
* @controllable onToggle
*/
show: _propTypes["default"].bool,
/**
* Sets the initial show position of the Dropdown.
*/
defaultShow: _propTypes["default"].bool,
/**
* A callback fired when the Dropdown wishes to change visibility. Called with the requested
* `show` value, the DOM event, and the source that fired it: `'click'`,`'keydown'`,`'rootClose'`, or `'select'`.
*
* ```js
* function(
* isOpen: boolean,
* event: SyntheticEvent,
* ): void
* ```
*
* @controllable show
*/
onToggle: _propTypes["default"].func
};
var defaultProps = {
itemSelector: '* > *'
};
/**
* `Dropdown` is set of structural components for building, accessible dropdown menus with close-on-click,
* keyboard navigation, and correct focus handling. As with all the react-overlay's
* components its BYOS (bring your own styles). Dropdown is primarily
* built from three base components, you should compose to build your Dropdowns.
*
* - `Dropdown`, which wraps the menu and toggle, and handles keyboard navigation
* - `Dropdown.Toggle` generally a button that triggers the menu opening
* - `Dropdown.Menu` The overlaid, menu, positioned to the toggle with PopperJs
*/
function Dropdown(_ref) {
var drop = _ref.drop,
alignEnd = _ref.alignEnd,
defaultShow = _ref.defaultShow,
rawShow = _ref.show,
rawOnToggle = _ref.onToggle,
itemSelector = _ref.itemSelector,
focusFirstItemOnShow = _ref.focusFirstItemOnShow,
children = _ref.children;
var forceUpdate = (0, _useForceUpdate["default"])();
var _useUncontrolled = (0, _uncontrollable.useUncontrolled)({
defaultShow: defaultShow,
show: rawShow,
onToggle: rawOnToggle
}, {
show: 'onToggle'
}),
show = _useUncontrolled.show,
onToggle = _useUncontrolled.onToggle;
var _useCallbackRef = (0, _useCallbackRef2["default"])(),
toggleElement = _useCallbackRef[0],
setToggle = _useCallbackRef[1]; // We use normal refs instead of useCallbackRef in order to populate the
// the value as quickly as possible, otherwise the effect to focus the element
// may run before the state value is set
var menuRef = (0, _react.useRef)();
var menuElement = menuRef.current;
var setMenu = (0, _react.useCallback)(function (ref) {
menuRef.current = ref; // ensure that a menu set triggers an update for consumers
forceUpdate();
}, [forceUpdate]);
var lastShow = (0, _usePrevious["default"])(show);
var lastSourceEvent = (0, _react.useRef)(null);
var focusInDropdown = (0, _react.useRef)(false);
var toggle = (0, _react.useCallback)(function (event) {
onToggle(!show, event);
}, [onToggle, show]);
var context = (0, _react.useMemo)(function () {
return {
toggle: toggle,
drop: drop,
show: show,
alignEnd: alignEnd,
menuElement: menuElement,
toggleElement: toggleElement,
setMenu: setMenu,
setToggle: setToggle
};
}, [toggle, drop, show, alignEnd, menuElement, toggleElement, setMenu, setToggle]);
if (menuElement && lastShow && !show) {
focusInDropdown.current = menuElement.contains(document.activeElement);
}
var focusToggle = (0, _useEventCallback["default"])(function () {
if (toggleElement && toggleElement.focus) {
toggleElement.focus();
}
});
var maybeFocusFirst = (0, _useEventCallback["default"])(function () {
var type = lastSourceEvent.current;
var focusType = focusFirstItemOnShow;
if (focusType == null) {
focusType = menuRef.current && (0, _matches["default"])(menuRef.current, '[role=menu]') ? 'keyboard' : false;
}
if (focusType === false || focusType === 'keyboard' && !/^key.+$/.test(type)) {
return;
}
var first = (0, _querySelectorAll["default"])(menuRef.current, itemSelector)[0];
if (first && first.focus) first.focus();
});
(0, _react.useEffect)(function () {
if (show) maybeFocusFirst();else if (focusInDropdown.current) {
focusInDropdown.current = false;
focusToggle();
} // only `show` should be changing
}, [show, focusInDropdown, focusToggle, maybeFocusFirst]);
(0, _react.useEffect)(function () {
lastSourceEvent.current = null;
});
var getNextFocusedChild = function getNextFocusedChild(current, offset) {
if (!menuRef.current) return null;
var items = (0, _querySelectorAll["default"])(menuRef.current, itemSelector);
var index = items.indexOf(current) + offset;
index = Math.max(0, Math.min(index, items.length));
return items[index];
};
var handleKeyDown = function handleKeyDown(event) {
var key = event.key,
target = event.target; // Second only to https://github.com/twbs/bootstrap/blob/8cfbf6933b8a0146ac3fbc369f19e520bd1ebdac/js/src/dropdown.js#L400
// in inscrutability
var isInput = /input|textarea/i.test(target.tagName);
if (isInput && (key === ' ' || key !== 'Escape' && menuRef.current && menuRef.current.contains(target))) {
return;
}
lastSourceEvent.current = event.type;
switch (key) {
case 'ArrowUp':
{
var next = getNextFocusedChild(target, -1);
if (next && next.focus) next.focus();
event.preventDefault();
return;
}
case 'ArrowDown':
event.preventDefault();
if (!show) {
toggle(event);
} else {
var _next = getNextFocusedChild(target, 1);
if (_next && _next.focus) _next.focus();
}
return;
case 'Escape':
case 'Tab':
onToggle(false, event);
break;
default:
}
};
return _react["default"].createElement(_DropdownContext["default"].Provider, {
value: context
}, children({
props: {
onKeyDown: handleKeyDown
}
}));
}
Dropdown.displayName = 'ReactOverlaysDropdown';
Dropdown.propTypes = propTypes;
Dropdown.defaultProps = defaultProps;
Dropdown.Menu = _DropdownMenu["default"];
Dropdown.Toggle = _DropdownToggle["default"];
var _default = Dropdown;
exports["default"] = _default;
module.exports = exports.default;