mirror of
https://github.com/grafana/grafana.git
synced 2025-08-03 04:12:09 +08:00
81 lines
2.3 KiB
TypeScript
81 lines
2.3 KiB
TypeScript
import { css } from '@emotion/css';
|
|
import { useDialog } from '@react-aria/dialog';
|
|
import { useOverlay } from '@react-aria/overlays';
|
|
import React, { createRef } from 'react';
|
|
|
|
import { GrafanaTheme2, LinkModel } from '@grafana/data/src';
|
|
import { LinkButton, Portal, useStyles2, VerticalGroup, VizTooltipContainer } from '@grafana/ui';
|
|
import { CloseButton } from 'app/core/components/CloseButton/CloseButton';
|
|
import { Scene } from 'app/features/canvas/runtime/scene';
|
|
|
|
interface Props {
|
|
scene: Scene;
|
|
}
|
|
|
|
export const CanvasTooltip = ({ scene }: Props) => {
|
|
const style = useStyles2(getStyles);
|
|
|
|
const onClose = () => {
|
|
if (scene?.tooltipCallback && scene.tooltip) {
|
|
scene.tooltipCallback(undefined);
|
|
}
|
|
};
|
|
|
|
const ref = createRef<HTMLElement>();
|
|
const { overlayProps } = useOverlay({ onClose: onClose, isDismissable: true }, ref);
|
|
const { dialogProps } = useDialog({}, ref);
|
|
|
|
const element = scene.tooltip?.element;
|
|
if (!element) {
|
|
return <></>;
|
|
}
|
|
|
|
const renderDataLinks = () =>
|
|
element.data?.links &&
|
|
element.data?.links.length > 0 && (
|
|
<div>
|
|
<VerticalGroup>
|
|
{element.data?.links?.map((link: LinkModel, i: number) => (
|
|
<LinkButton
|
|
key={i}
|
|
icon={'external-link-alt'}
|
|
target={link.target}
|
|
href={link.href}
|
|
onClick={link.onClick}
|
|
fill="text"
|
|
style={{ width: '100%' }}
|
|
>
|
|
{link.title}
|
|
</LinkButton>
|
|
))}
|
|
</VerticalGroup>
|
|
</div>
|
|
);
|
|
|
|
return (
|
|
<>
|
|
{scene.tooltip?.element && scene.tooltip.anchorPoint && (
|
|
<Portal>
|
|
<VizTooltipContainer
|
|
position={{ x: scene.tooltip.anchorPoint.x, y: scene.tooltip.anchorPoint.y }}
|
|
offset={{ x: 5, y: 0 }}
|
|
allowPointerEvents={scene.tooltip.isOpen}
|
|
>
|
|
<section ref={ref} {...overlayProps} {...dialogProps}>
|
|
{scene.tooltip.isOpen && <CloseButton style={{ zIndex: 1 }} onClick={onClose} />}
|
|
<div className={style.wrapper}>{renderDataLinks()}</div>
|
|
</section>
|
|
</VizTooltipContainer>
|
|
</Portal>
|
|
)}
|
|
</>
|
|
);
|
|
};
|
|
|
|
const getStyles = (theme: GrafanaTheme2) => ({
|
|
wrapper: css`
|
|
margin-top: 20px;
|
|
background: ${theme.colors.background.primary};
|
|
`,
|
|
});
|