UNPKG

@geezee/react-ui

Version:

Modern and minimalist React UI library.

103 lines (92 loc) 3.5 kB
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray"; import _extends from "@babel/runtime/helpers/esm/extends"; import _JSXStyle from "styled-jsx/style"; import React, { useEffect, useState } from 'react'; import { createPortal } from 'react-dom'; import usePortal from '../utils/use-portal'; import useResize from '../utils/use-resize'; import CSSTransition from './css-transition'; import useClickAnyWhere from '../utils/use-click-anywhere'; import useDOMObserver from '../utils/use-dom-observer'; var defaultRect = { top: -1000, left: -1000, right: -1000, width: 0 }; var getRect = function getRect(ref) { if (!ref || !ref.current) return defaultRect; var rect = ref.current.getBoundingClientRect(); return _extends(_extends({}, rect), {}, { width: rect.width || rect.right - rect.left, top: rect.bottom + document.documentElement.scrollTop, left: rect.left + document.documentElement.scrollLeft }); }; var Dropdown = React.memo(function (_ref) { var children = _ref.children, parent = _ref.parent, visible = _ref.visible, disableMatchWidth = _ref.disableMatchWidth, enterTime = _ref.enterTime, leaveTime = _ref.leaveTime, clearTime = _ref.clearTime; var el = usePortal('dropdown'); var _useState = useState(defaultRect), _useState2 = _slicedToArray(_useState, 2), rect = _useState2[0], setRect = _useState2[1]; if (!parent) return null; var updateRect = function updateRect() { var _getRect = getRect(parent), top = _getRect.top, left = _getRect.left, right = _getRect.right, nativeWidth = _getRect.width; setRect({ top: top, left: left, right: right, width: nativeWidth }); }; useResize(updateRect); useClickAnyWhere(function () { var _getRect2 = getRect(parent), top = _getRect2.top, left = _getRect2.left; var shouldUpdatePosition = top !== rect.top || left !== rect.left; if (!shouldUpdatePosition) return; updateRect(); }); useDOMObserver(parent, function () { updateRect(); }); useEffect(function () { if (!parent || !parent.current) return; parent.current.addEventListener('mouseenter', updateRect); /* istanbul ignore next */ return function () { if (!parent || !parent.current) return; parent.current.removeEventListener('mouseenter', updateRect); }; }, [parent]); var clickHandler = function clickHandler(event) { event.stopPropagation(); event.preventDefault(); }; if (!el) return null; return createPortal( /*#__PURE__*/React.createElement(CSSTransition, { visible: visible, enterTime: enterTime, leaveTime: leaveTime, clearTime: clearTime }, /*#__PURE__*/React.createElement("div", { onClick: clickHandler, className: _JSXStyle.dynamic([["2976859150", [rect.top + 2, rect.left, rect.width, rect.width]]]) + " " + "dropdown ".concat(disableMatchWidth ? 'disable-match' : 'width-match') }, children, /*#__PURE__*/React.createElement(_JSXStyle, { id: "2976859150", dynamic: [rect.top + 2, rect.left, rect.width, rect.width] }, ".dropdown.__jsx-style-dynamic-selector{position:absolute;top:".concat(rect.top + 2, "px;left:").concat(rect.left, "px;z-index:1100;}.width-match.__jsx-style-dynamic-selector{width:").concat(rect.width, "px;}.disable-match.__jsx-style-dynamic-selector{min-width:").concat(rect.width, "px;}")))), el); }); export default Dropdown;