@coreui/react
Version:
UI Components Library for React.js
161 lines (157 loc) • 7.71 kB
JavaScript
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
;