@grafana/ui
Version:
Grafana Components Library
97 lines (94 loc) • 3.49 kB
JavaScript
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