UNPKG

@coreui/react-pro

Version:

UI Components Library for React.js

118 lines (115 loc) 5.39 kB
import { __rest } from '../../node_modules/tslib/tslib.es6.js'; import React, { forwardRef, useRef, useId, useState, useEffect } from 'react'; import classNames from '../../_virtual/index.js'; import PropTypes from 'prop-types'; import { CConditionalPortal } from '../conditional-portal/CConditionalPortal.js'; import { usePopper } from '../../hooks/usePopper.js'; import executeAfterTransition from '../../utils/executeAfterTransition.js'; import getRTLPlacement from '../../utils/getRTLPlacement.js'; import { useForkedRef } from '../../hooks/useForkedRef.js'; import { triggerPropType, fallbackPlacementsPropType } from '../../props.js'; const CPopover = forwardRef((_a, ref) => { var { children, animation = true, className, container, content, delay = 0, fallbackPlacements = ['top', 'right', 'bottom', 'left'], offset = [0, 8], onHide, onShow, placement = 'top', popperConfig, title, trigger = 'click', visible } = _a, rest = __rest(_a, ["children", "animation", "className", "container", "content", "delay", "fallbackPlacements", "offset", "onHide", "onShow", "placement", "popperConfig", "title", "trigger", "visible"]); const popoverRef = useRef(null); const togglerRef = useRef(null); const forkedRef = useForkedRef(ref, popoverRef); const id = `popover${useId()}`; const [mounted, setMounted] = useState(false); const [_visible, setVisible] = useState(visible); const { initPopper, destroyPopper } = usePopper(); const _delay = typeof delay === 'number' ? { show: delay, hide: delay } : delay; const defaultPopperConfig = { modifiers: [ { name: 'arrow', options: { element: '.popover-arrow' } }, { name: 'flip', options: { fallbackPlacements } }, { name: 'offset', options: { offset } }, ], placement: getRTLPlacement(placement, togglerRef.current), }; const computedPopperConfig = Object.assign(Object.assign({}, defaultPopperConfig), (typeof popperConfig === 'function' ? popperConfig(defaultPopperConfig) : popperConfig)); useEffect(() => { if (visible) { handleShow(); return; } handleHide(); }, [visible]); useEffect(() => { if (mounted && togglerRef.current && popoverRef.current) { initPopper(togglerRef.current, popoverRef.current, computedPopperConfig); setTimeout(() => { setVisible(true); }, _delay.show); return; } if (!mounted && togglerRef.current && popoverRef.current) { destroyPopper(); } }, [mounted]); useEffect(() => { if (!_visible && togglerRef.current && popoverRef.current) { executeAfterTransition(() => { setMounted(false); }, popoverRef.current); } }, [_visible]); const handleShow = () => { setMounted(true); if (onShow) { onShow(); } }; const handleHide = () => { setTimeout(() => { setVisible(false); if (onHide) { onHide(); } }, _delay.hide); }; return (React.createElement(React.Fragment, null, React.cloneElement(children, Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, (_visible && { 'aria-describedby': id, })), { ref: togglerRef }), ((trigger === 'click' || trigger.includes('click')) && { onClick: () => (_visible ? handleHide() : handleShow()), })), ((trigger === 'focus' || trigger.includes('focus')) && { onFocus: () => handleShow(), onBlur: () => handleHide(), })), ((trigger === 'hover' || trigger.includes('hover')) && { onMouseEnter: () => handleShow(), onMouseLeave: () => handleHide(), }))), React.createElement(CConditionalPortal, { container: container, portal: true }, mounted && (React.createElement("div", Object.assign({ className: classNames('popover', 'bs-popover-auto', { fade: animation, show: _visible, }, className), id: id, ref: forkedRef, role: "tooltip" }, rest), React.createElement("div", { className: "popover-arrow" }), React.createElement("div", { className: "popover-header" }, title), React.createElement("div", { className: "popover-body" }, content)))))); }); CPopover.propTypes = { animation: PropTypes.bool, children: PropTypes.node, className: PropTypes.string, container: PropTypes.any, content: PropTypes.oneOfType([PropTypes.string, PropTypes.node]), delay: PropTypes.oneOfType([ PropTypes.number, PropTypes.shape({ show: PropTypes.number.isRequired, hide: PropTypes.number.isRequired, }), ]), fallbackPlacements: fallbackPlacementsPropType, offset: PropTypes.any, // TODO: find good proptype onHide: PropTypes.func, onShow: PropTypes.func, placement: PropTypes.oneOf(['auto', 'top', 'right', 'bottom', 'left']), popperConfig: PropTypes.oneOfType([PropTypes.func, PropTypes.object]), title: PropTypes.oneOfType([PropTypes.string, PropTypes.node]), trigger: triggerPropType, visible: PropTypes.bool, }; CPopover.displayName = 'CPopover'; export { CPopover }; //# sourceMappingURL=CPopover.js.map