UNPKG

@coreui/react

Version:

UI Components Library for React.js

161 lines (157 loc) 7.71 kB
'use strict'; var tslib_es6 = require('../../node_modules/tslib/tslib.es6.js'); var React = require('react'); var PropTypes = require('prop-types'); var index = require('../../_virtual/index.js'); var CDropdownContext = require('./CDropdownContext.js'); var useForkedRef = require('../../hooks/useForkedRef.js'); var usePopper = require('../../hooks/usePopper.js'); var props = require('../../props.js'); var getNextActiveElement = require('../../utils/getNextActiveElement.js'); var isRTL = require('../../utils/isRTL.js'); var utils = require('./utils.js'); var CDropdown = React.forwardRef(function (_a, ref) { var _b; var children = _a.children, alignment = _a.alignment, _c = _a.as, as = _c === void 0 ? 'div' : _c, _d = _a.autoClose, autoClose = _d === void 0 ? true : _d, className = _a.className, container = _a.container, dark = _a.dark, direction = _a.direction, _e = _a.offset, offset = _e === void 0 ? [0, 2] : _e, onHide = _a.onHide, onShow = _a.onShow, _f = _a.placement, placement = _f === void 0 ? 'bottom-start' : _f, _g = _a.popper, popper = _g === void 0 ? true : _g, popperConfig = _a.popperConfig, _h = _a.portal, portal = _h === void 0 ? false : _h, _j = _a.variant, variant = _j === void 0 ? 'btn-group' : _j, _k = _a.visible, visible = _k === void 0 ? false : _k, rest = tslib_es6.__rest(_a, ["children", "alignment", "as", "autoClose", "className", "container", "dark", "direction", "offset", "onHide", "onShow", "placement", "popper", "popperConfig", "portal", "variant", "visible"]); var dropdownRef = React.useRef(null); var dropdownToggleRef = React.useRef(null); var dropdownMenuRef = React.useRef(null); var forkedRef = useForkedRef.useForkedRef(ref, dropdownRef); var _l = React.useState(visible), _visible = _l[0], setVisible = _l[1]; var _m = usePopper.usePopper(), initPopper = _m.initPopper, destroyPopper = _m.destroyPopper; var Component = variant === 'nav-item' ? 'li' : as; // Disable popper if responsive aligment is set. if (typeof alignment === 'object') { popper = false; } var contextValues = { alignment: alignment, container: container, dark: dark, dropdownToggleRef: dropdownToggleRef, dropdownMenuRef: dropdownMenuRef, popper: popper, portal: portal, variant: variant, visible: _visible, setVisible: setVisible, }; var defaultPopperConfig = { modifiers: [ { name: 'offset', options: { offset: offset, }, }, ], placement: utils.getPlacement(placement, direction, alignment, isRTL.default(dropdownMenuRef.current)), }; var computedPopperConfig = tslib_es6.__assign(tslib_es6.__assign({}, defaultPopperConfig), (typeof popperConfig === 'function' ? popperConfig(defaultPopperConfig) : popperConfig)); React.useEffect(function () { setVisible(visible); }, [visible]); React.useEffect(function () { var toggleElement = dropdownToggleRef.current; var menuElement = dropdownMenuRef.current; if (_visible && toggleElement && menuElement) { if (popper) { initPopper(toggleElement, menuElement, computedPopperConfig); } toggleElement.focus(); toggleElement.addEventListener('keydown', handleKeydown); menuElement.addEventListener('keydown', handleKeydown); window.addEventListener('mouseup', handleMouseUp); window.addEventListener('keyup', handleKeyup); onShow === null || onShow === void 0 ? void 0 : onShow(); } return function () { if (popper) { destroyPopper(); } toggleElement === null || toggleElement === void 0 ? void 0 : toggleElement.removeEventListener('keydown', handleKeydown); menuElement === null || menuElement === void 0 ? void 0 : menuElement.removeEventListener('keydown', handleKeydown); window.removeEventListener('mouseup', handleMouseUp); window.removeEventListener('keyup', handleKeyup); onHide === null || onHide === void 0 ? void 0 : onHide(); }; }, [ computedPopperConfig, destroyPopper, dropdownMenuRef, dropdownToggleRef, initPopper, _visible, ]); var handleKeydown = function (event) { if (_visible && dropdownMenuRef.current && (event.key === 'ArrowDown' || event.key === 'ArrowUp')) { event.preventDefault(); var target = event.target; var items = Array.from(dropdownMenuRef.current.querySelectorAll('.dropdown-item:not(.disabled):not(:disabled)')); getNextActiveElement.default(items, target, event.key === 'ArrowDown', true).focus(); } }; var handleKeyup = function (event) { if (autoClose === false) { return; } if (event.key === 'Escape') { setVisible(false); } }; var handleMouseUp = function (event) { if (!dropdownToggleRef.current || !dropdownMenuRef.current) { return; } if (dropdownToggleRef.current.contains(event.target)) { return; } if (autoClose === true || (autoClose === 'inside' && dropdownMenuRef.current.contains(event.target)) || (autoClose === 'outside' && !dropdownMenuRef.current.contains(event.target))) { setTimeout(function () { return setVisible(false); }, 1); return; } }; return (React.createElement(CDropdownContext.CDropdownContext.Provider, { value: contextValues }, variant === 'input-group' ? (React.createElement(React.Fragment, null, children)) : (React.createElement(Component, tslib_es6.__assign({ className: index.default(variant === 'nav-item' ? 'nav-item dropdown' : variant, (_b = { 'dropdown-center': direction === 'center', 'dropup dropup-center': direction === 'dropup-center' }, _b["".concat(direction)] = direction && direction !== 'center' && direction !== 'dropup-center', _b), className) }, rest, { ref: forkedRef }), children)))); }); var alignmentDirection = PropTypes.oneOf(['start', 'end']); CDropdown.propTypes = { alignment: PropTypes.oneOfType([ alignmentDirection, PropTypes.shape({ xs: alignmentDirection.isRequired }), PropTypes.shape({ sm: alignmentDirection.isRequired }), PropTypes.shape({ md: alignmentDirection.isRequired }), PropTypes.shape({ lg: alignmentDirection.isRequired }), PropTypes.shape({ xl: alignmentDirection.isRequired }), PropTypes.shape({ xxl: alignmentDirection.isRequired }), ]), as: PropTypes.elementType, autoClose: PropTypes.oneOfType([ PropTypes.bool, PropTypes.oneOf(['inside', 'outside']), ]), children: PropTypes.node, className: PropTypes.string, dark: PropTypes.bool, direction: PropTypes.oneOf(['center', 'dropup', 'dropup-center', 'dropend', 'dropstart']), offset: PropTypes.any, // TODO: find good proptype onHide: PropTypes.func, onShow: PropTypes.func, placement: props.placementPropType, popper: PropTypes.bool, popperConfig: PropTypes.oneOfType([PropTypes.func, PropTypes.object]), portal: PropTypes.bool, variant: PropTypes.oneOf(['btn-group', 'dropdown', 'input-group', 'nav-item']), visible: PropTypes.bool, }; CDropdown.displayName = 'CDropdown'; exports.CDropdown = CDropdown; //# sourceMappingURL=CDropdown.js.map