@geezee/react-ui
Version:
Modern and minimalist React UI library.
103 lines (92 loc) • 3.5 kB
JavaScript
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;