@grafana/ui
Version:
Grafana Components Library
111 lines (106 loc) • 3.98 kB
JavaScript
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var jsxRuntime = require('react/jsx-runtime');
var react = require('@floating-ui/react');
var React = require('react');
var e2eSelectors = require('@grafana/e2e-selectors');
var ThemeContext = require('../../themes/ThemeContext.cjs');
var floating = require('../../utils/floating.cjs');
var tooltipUtils = require('../../utils/tooltipUtils.cjs');
var Portal = require('../Portal/Portal.cjs');
"use strict";
const Tooltip = React.forwardRef(
({ children, theme, interactive, show, placement, content }, forwardedRef) => {
const arrowRef = React.useRef(null);
const [controlledVisible, setControlledVisible] = React.useState(show);
const isOpen = show != null ? show : controlledVisible;
const floatingUIPlacement = tooltipUtils.getPlacement(placement);
const middleware = [
react.offset(8),
...floating.getPositioningMiddleware(floatingUIPlacement),
react.arrow({
element: arrowRef
})
];
const { context, refs, floatingStyles } = react.useFloating({
open: isOpen,
placement: floatingUIPlacement,
onOpenChange: setControlledVisible,
middleware,
whileElementsMounted: react.autoUpdate
});
const tooltipId = React.useId();
const hover = react.useHover(context, {
handleClose: interactive ? react.safePolygon() : void 0,
move: false
});
const focus = react.useFocus(context);
const dismiss = react.useDismiss(context);
const { getReferenceProps, getFloatingProps } = react.useInteractions([dismiss, hover, focus]);
const contentIsFunction = typeof content === "function";
const styles = ThemeContext.useStyles2(getStyles);
const style = styles[theme != null ? theme : "info"];
const handleRef = React.useCallback(
(ref) => {
refs.setReference(ref);
if (typeof forwardedRef === "function") {
forwardedRef(ref);
} else if (forwardedRef) {
forwardedRef.current = ref;
}
},
[forwardedRef, refs]
);
const childHasMatchingAriaLabel = "aria-label" in children.props && children.props["aria-label"] === content;
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
React.cloneElement(children, {
ref: handleRef,
tabIndex: 0,
// tooltip trigger should be keyboard focusable
"aria-describedby": !childHasMatchingAriaLabel && isOpen ? tooltipId : void 0,
...getReferenceProps()
}),
isOpen && /* @__PURE__ */ jsxRuntime.jsx(Portal.Portal, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: refs.setFloating, style: floatingStyles, ...getFloatingProps(), children: [
/* @__PURE__ */ jsxRuntime.jsx(react.FloatingArrow, { className: style.arrow, ref: arrowRef, context }),
/* @__PURE__ */ jsxRuntime.jsxs(
"div",
{
"data-testid": e2eSelectors.selectors.components.Tooltip.container,
id: tooltipId,
role: "tooltip",
className: style.container,
children: [
typeof content === "string" && content,
React.isValidElement(content) && React.cloneElement(content),
contentIsFunction && content({})
]
}
)
] }) })
] });
}
);
Tooltip.displayName = "Tooltip";
const getStyles = (theme) => {
const info = tooltipUtils.buildTooltipTheme(
theme,
theme.components.tooltip.background,
theme.components.tooltip.background,
theme.components.tooltip.text,
{ topBottom: 0.5, rightLeft: 1 }
);
const error = tooltipUtils.buildTooltipTheme(
theme,
theme.colors.error.main,
theme.colors.error.main,
theme.colors.error.contrastText,
{ topBottom: 0.5, rightLeft: 1 }
);
return {
info,
["info-alt"]: info,
error
};
};
exports.Tooltip = Tooltip;
//# sourceMappingURL=Tooltip.cjs.map