UNPKG

@coreui/react-pro

Version:

UI Components Library for React.js

109 lines (106 loc) 4.32 kB
import React, { forwardRef, useRef, useState, useEffect } from 'react'; import PropTypes from 'prop-types'; import classNames from '../../_virtual/index.js'; import { CConditionalPortal } from '../conditional-portal/CConditionalPortal.js'; import { CFocusTrap } from '../focus-trap/CFocusTrap.js'; import '../../node_modules/tslib/tslib.es6.js'; import { usePopper } from '../../hooks/usePopper.js'; import isRTL from '../../utils/isRTL.js'; import { useForkedRef } from '../../hooks/useForkedRef.js'; const CPicker = forwardRef(({ children, className, container = 'dropdown', disabled, dropdownClassNames, footer, footerContent, onHide, onShow, portal = true, toggler, visible = false, }, ref) => { const pickerRef = useRef(null); const pickerForkedRef = useForkedRef(ref, pickerRef); const dropdownRef = useRef(null); const togglerRef = useRef(null); const { initPopper, destroyPopper } = usePopper(); const [_visible, setVisible] = useState(visible); const popperConfig = { placement: (isRTL(pickerRef.current) ? 'bottom-end' : 'bottom-start'), modifiers: [ { name: 'preventOverflow', options: { boundary: 'clippingParents', }, }, { name: 'offset', options: { offset: [0, 2], }, }, ], }; useEffect(() => { setVisible(visible); }, [visible]); useEffect(() => { if (container !== 'inline' && _visible) { onShow === null || onShow === void 0 ? void 0 : onShow(); window.addEventListener('mouseup', handleMouseUp); window.addEventListener('keyup', handleKeyUp); if (togglerRef.current && dropdownRef.current) { initPopper(togglerRef.current, dropdownRef.current, popperConfig); } } return () => { onHide === null || onHide === void 0 ? void 0 : onHide(); window.removeEventListener('mouseup', handleMouseUp); window.removeEventListener('keyup', handleKeyUp); destroyPopper(); }; }, [_visible]); const handleKeyUp = (event) => { if (event.key === 'Escape') { setVisible(false); } }; const handleMouseUp = (event) => { if (pickerRef.current && pickerRef.current.contains(event.target)) { return; } if (dropdownRef.current && dropdownRef.current.contains(event.target)) { return; } setVisible(false); }; switch (container) { case 'inline': { return (React.createElement("div", { className: classNames('picker', className), ref: pickerForkedRef }, children)); } default: { return (React.createElement(CFocusTrap, Object.assign({ active: _visible }, (portal && { additionalContainer: dropdownRef })), React.createElement("div", { className: classNames(className, { show: _visible, }), onClick: () => !disabled && setVisible(true), ref: pickerForkedRef }, toggler && React.isValidElement(toggler) && React.cloneElement(toggler, { ref: togglerRef, }), React.createElement(CConditionalPortal, { portal: portal }, React.createElement("div", { className: classNames(dropdownClassNames, { show: portal && _visible, }), ref: dropdownRef }, children, footer && footerContent))))); } } }); CPicker.displayName = 'CPicker'; CPicker.propTypes = { children: PropTypes.node, className: PropTypes.string, container: PropTypes.oneOf(['dropdown', 'inline']), disabled: PropTypes.bool, dropdownClassNames: PropTypes.string, footer: PropTypes.bool, footerContent: PropTypes.node, onHide: PropTypes.func, onShow: PropTypes.func, portal: PropTypes.bool, toggler: PropTypes.node, visible: PropTypes.bool, }; export { CPicker }; //# sourceMappingURL=CPicker.js.map