UNPKG

@grafana/ui

Version:
111 lines (106 loc) 3.98 kB
'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