UNPKG

@coreui/react-pro

Version:

UI Components Library for React.js

143 lines (140 loc) 5.98 kB
import { __rest } from '../../node_modules/tslib/tslib.es6.js'; import React, { forwardRef, useRef, useState, useEffect } from 'react'; import { createPortal } from 'react-dom'; import PropTypes from 'prop-types'; import classNames from '../../_virtual/index.js'; import { CBackdrop } from '../backdrop/CBackdrop.js'; import isInViewport from '../../utils/isInViewport.js'; import '@popperjs/core'; import { useForkedRef } from '../../hooks/useForkedRef.js'; const isOnMobile = (element) => Boolean(getComputedStyle(element).getPropertyValue('--cui-is-mobile')); const CSidebar = forwardRef((_a, ref) => { var { children, as: Component = 'div', className, colorScheme, narrow, onHide, onShow, onVisibleChange, overlaid, placement, position, size, unfoldable, visible } = _a, rest = __rest(_a, ["children", "as", "className", "colorScheme", "narrow", "onHide", "onShow", "onVisibleChange", "overlaid", "placement", "position", "size", "unfoldable", "visible"]); const sidebarRef = useRef(null); const forkedRef = useForkedRef(ref, sidebarRef); const [inViewport, setInViewport] = useState(); const [mobile, setMobile] = useState(false); const [visibleMobile, setVisibleMobile] = useState(false); const [visibleDesktop, setVisibleDesktop] = useState(visible === undefined ? !overlaid : visible); useEffect(() => { if (sidebarRef.current) { setMobile(isOnMobile(sidebarRef.current)); } if (visible !== undefined) { handleVisibleChange(visible); } }, [visible]); useEffect(() => { if (inViewport !== undefined) { onVisibleChange === null || onVisibleChange === void 0 ? void 0 : onVisibleChange(inViewport); } if (inViewport) { onShow === null || onShow === void 0 ? void 0 : onShow(); } else { onHide === null || onHide === void 0 ? void 0 : onHide(); } }, [inViewport]); useEffect(() => { if (mobile) { setVisibleMobile(false); } }, [mobile]); useEffect(() => { const element = sidebarRef.current; if (element) { setMobile(isOnMobile(element)); setInViewport(isInViewport(element)); } const handleTransitionEnd = () => { if (element) { setInViewport(isInViewport(element)); } }; window.addEventListener('resize', handleResize); window.addEventListener('mouseup', handleClickOutside); window.addEventListener('keyup', handleKeyup); element === null || element === void 0 ? void 0 : element.addEventListener('mouseup', handleOnClick); element === null || element === void 0 ? void 0 : element.addEventListener('transitionend', handleTransitionEnd); return () => { window.removeEventListener('resize', handleResize); window.removeEventListener('mouseup', handleClickOutside); window.removeEventListener('keyup', handleKeyup); element === null || element === void 0 ? void 0 : element.removeEventListener('mouseup', handleOnClick); element === null || element === void 0 ? void 0 : element.removeEventListener('transitionend', handleTransitionEnd); }; }); const handleVisibleChange = (visible) => { if (mobile) { setVisibleMobile(visible); return; } setVisibleDesktop(visible); }; const handleHide = () => { handleVisibleChange(false); }; const handleResize = () => { if (sidebarRef.current) { setMobile(isOnMobile(sidebarRef.current)); setInViewport(isInViewport(sidebarRef.current)); } }; const handleKeyup = (event) => { if (mobile && sidebarRef.current && !sidebarRef.current.contains(event.target)) { handleHide(); } }; const handleClickOutside = (event) => { if (mobile && sidebarRef.current && !sidebarRef.current.contains(event.target)) { handleHide(); } }; const handleOnClick = (event) => { const target = event.target; if (target && target.classList.contains('nav-link') && !target.classList.contains('nav-group-toggle') && mobile) { handleHide(); } }; return (React.createElement(React.Fragment, null, React.createElement(Component, Object.assign({ className: classNames('sidebar', { [`sidebar-${colorScheme}`]: colorScheme, 'sidebar-narrow': narrow, 'sidebar-overlaid': overlaid, [`sidebar-${placement}`]: placement, [`sidebar-${position}`]: position, [`sidebar-${size}`]: size, 'sidebar-narrow-unfoldable': unfoldable, show: (mobile && visibleMobile) || (overlaid && visibleDesktop), hide: visibleDesktop === false && !mobile && !overlaid, }, className) }, rest, { ref: forkedRef }), children), typeof window !== 'undefined' && mobile && createPortal(React.createElement(CBackdrop, { className: "sidebar-backdrop", visible: mobile && visibleMobile }), document.body))); }); CSidebar.propTypes = { as: PropTypes.elementType, children: PropTypes.node, className: PropTypes.string, colorScheme: PropTypes.oneOf(['dark', 'light']), narrow: PropTypes.bool, onHide: PropTypes.func, onShow: PropTypes.func, onVisibleChange: PropTypes.func, overlaid: PropTypes.bool, placement: PropTypes.oneOf(['start', 'end']), position: PropTypes.oneOf(['fixed', 'sticky']), size: PropTypes.oneOf(['sm', 'lg', 'xl']), unfoldable: PropTypes.bool, visible: PropTypes.bool, }; CSidebar.displayName = 'CSidebar'; export { CSidebar }; //# sourceMappingURL=CSidebar.js.map