@grafana/ui
Version:
Grafana Components Library
79 lines (76 loc) • 2.67 kB
JavaScript
import { jsx, jsxs } from 'react/jsx-runtime';
import { cx, css } from '@emotion/css';
import { offset, flip, shift, useFloating, autoUpdate, useTransitionStyles } from '@floating-ui/react';
import { useLayoutEffect } from 'react';
import { useStyles2, useTheme2 } from '../../themes/ThemeContext.mjs';
import { Icon } from '../Icon/Icon.mjs';
import { Portal } from '../Portal/Portal.mjs';
;
function InlineToast({ referenceElement, children, suffixIcon, placement }) {
const styles = useStyles2(getStyles);
const theme = useTheme2();
const middleware = [
offset(8),
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: true,
placement,
middleware,
whileElementsMounted: autoUpdate,
strategy: "fixed"
});
useLayoutEffect(() => {
refs.setReference(referenceElement);
}, [referenceElement, refs]);
const { styles: placementStyles } = useTransitionStyles(context, {
initial: ({ side }) => {
return {
opacity: 0,
transform: getInitialTransform(side, theme)
};
},
duration: theme.transitions.duration.shortest
});
return /* @__PURE__ */ jsx(Portal, { children: /* @__PURE__ */ jsx("div", { style: { display: "inline-block", ...floatingStyles }, ref: refs.setFloating, "aria-live": "polite", children: /* @__PURE__ */ jsxs("span", { className: cx(styles.root), style: placementStyles, children: [
children && /* @__PURE__ */ jsx("span", { children }),
suffixIcon && /* @__PURE__ */ jsx(Icon, { name: suffixIcon })
] }) }) });
}
const getStyles = (theme) => {
return {
root: css({
...theme.typography.bodySmall,
willChange: "transform",
background: theme.components.tooltip.background,
color: theme.components.tooltip.text,
padding: theme.spacing(0.5, 1.5),
// get's an extra .5 of vertical padding to account for the rounded corners
borderRadius: theme.shape.radius.pill,
display: "inline-flex",
gap: theme.spacing(0.5),
alignItems: "center"
})
};
};
const getInitialTransform = (placement, theme) => {
const gap = 1;
switch (placement) {
case "top":
return `translateY(${theme.spacing(gap)})`;
case "bottom":
return `translateY(-${theme.spacing(gap)})`;
case "left":
return `translateX(${theme.spacing(gap)})`;
case "right":
return `translateX(-${theme.spacing(gap)})`;
}
};
export { InlineToast };
//# sourceMappingURL=InlineToast.mjs.map