UNPKG

@grafana/ui

Version:
97 lines (94 loc) 3.49 kB
import { jsxs, Fragment, jsx } from 'react/jsx-runtime'; import { css } from '@emotion/css'; import { offset, flip, shift, useFloating, autoUpdate, useClick, useDismiss, useInteractions, FloatingFocusManager } from '@floating-ui/react'; import * as React from 'react'; import { useState, useRef, useCallback } from 'react'; import { CSSTransition } from 'react-transition-group'; import { useStyles2 } from '../../themes/ThemeContext.mjs'; import { renderOrCallToRender } from '../../utils/reactUtils.mjs'; import { getPlacement } from '../../utils/tooltipUtils.mjs'; import { Portal } from '../Portal/Portal.mjs'; const Dropdown = React.memo(({ children, overlay, placement, offset: offset$1, onVisibleChange }) => { var _a, _b; const [show, setShow] = useState(false); const transitionRef = useRef(null); const handleOpenChange = useCallback( (newState) => { setShow(newState); onVisibleChange == null ? void 0 : onVisibleChange(newState); }, [onVisibleChange] ); const middleware = [ offset({ mainAxis: (_a = offset$1 == null ? void 0 : offset$1[0]) != null ? _a : 8, crossAxis: (_b = offset$1 == null ? void 0 : offset$1[1]) != null ? _b : 0 }), flip({ fallbackAxisSideDirection: "end", // see https://floating-ui.com/docs/flip#combining-with-shift crossAxis: false, boundary: document.body }), shift() ]; const { context, refs, floatingStyles } = useFloating({ open: show, placement: getPlacement(placement), onOpenChange: handleOpenChange, middleware, whileElementsMounted: autoUpdate }); const click = useClick(context); const dismiss = useDismiss(context); const { getReferenceProps, getFloatingProps } = useInteractions([dismiss, click]); const animationDuration = 150; const animationStyles = useStyles2(getStyles, animationDuration); const onOverlayClicked = () => { handleOpenChange(false); }; const handleKeys = (event) => { if (event.key === "Tab") { handleOpenChange(false); } }; return /* @__PURE__ */ jsxs(Fragment, { children: [ React.cloneElement(children, { ref: refs.setReference, ...getReferenceProps() }), show && /* @__PURE__ */ jsx(Portal, { children: /* @__PURE__ */ jsx(FloatingFocusManager, { context, children: /* @__PURE__ */ jsx("div", { ref: refs.setFloating, style: floatingStyles, onClick: onOverlayClicked, onKeyDown: handleKeys, children: /* @__PURE__ */ jsx( CSSTransition, { nodeRef: transitionRef, appear: true, in: true, timeout: { appear: animationDuration, exit: 0, enter: 0 }, classNames: animationStyles, children: /* @__PURE__ */ jsx("div", { ref: transitionRef, children: renderOrCallToRender(overlay, { ...getFloatingProps() }) }) } ) }) }) }) ] }); }); Dropdown.displayName = "Dropdown"; const getStyles = (theme, duration) => { return { appear: css({ opacity: "0", position: "relative", transformOrigin: "top", [theme.transitions.handleMotion("no-preference")]: { transform: "scaleY(0.5)" } }), appearActive: css({ opacity: "1", [theme.transitions.handleMotion("no-preference")]: { transform: "scaleY(1)", transition: `transform ${duration}ms cubic-bezier(0.2, 0, 0.2, 1), opacity ${duration}ms cubic-bezier(0.2, 0, 0.2, 1)` } }) }; }; export { Dropdown }; //# sourceMappingURL=Dropdown.mjs.map