@coreui/react-pro
Version:
UI Components Library for React.js
118 lines (115 loc) • 5.39 kB
JavaScript
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