import styles from './TooltipShared.module.css'; import type { display } from 'objdiff-wasm'; import React, { useCallback, useMemo } from 'react'; import { Tooltip } from 'react-tooltip'; type TooltipProps = { 'data-tooltip-id': string; 'data-tooltip-content': string; }; export type TooltipCallback = (content: T) => display.HoverItem[] | null; export function createTooltip(): { Tooltip: React.FC<{ callback: TooltipCallback; }>; useTooltip: (content: T) => TooltipProps; } { const id = generateRandomString(10); return { Tooltip: ({ callback }) => { const callbackMemo = useCallback( (content: string) => { if (!content) { return null; } const parsedContent = JSON.parse(content) as T; return callback(parsedContent); }, [callback], ); return ; }, useTooltip: (content: T) => // useMemo( // () => ({ // 'data-tooltip-id': id, // 'data-tooltip-content': JSON.stringify(content), // }), // [content], // ), ({ 'data-tooltip-id': id, 'data-tooltip-content': JSON.stringify(content), }), }; } const TooltipShared = ({ id, callback, }: { id: string; callback: (content: string) => display.HoverItem[] | null; }) => { return ( { const items = useMemo(() => { if (!content) { return null; } return callback(content); }, [callback, content]); if (!items) { return null; } return ; }} /> ); }; const TooltipContent = ({ items }: { items: display.HoverItem[] }) => { const out = []; for (const [i, item] of items.entries()) { let inner: React.ReactNode; switch (item.tag) { case 'text': if (item.val.label) { inner = ( <> {item.val.label} {': '} {item.val.value} ); } else { inner = ( {item.val.value} ); } break; case 'separator': inner =
; break; default: console.warn('Unhandled context item', item); inner = null; break; } out.push(
{inner}
, ); } return
{out}
; }; const TooltipContentMemo = React.memo(TooltipContent); function generateRandomString(length: number): string { const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; let result = ''; for (let i = 0; i < length; i++) { result += characters.charAt(Math.floor(Math.random() * characters.length)); } return result; }