Tooltip
A tooltip annotation where the tooltip content can be any MDX content.
content.mdx
<CodeWithTooltips>```js !code// !tooltip[/lorem/] descriptionfunction lorem(ipsum, dolor = 1) {const sit = ipsum == null ? 0 : ipsum.sitdolor = sit - amet(dolor)// !tooltip[/consectetur/] inspectreturn sit ? consectetur(ipsum) : []}```## !!tooltips description### Hello worldLorem ipsum **dolor** sit amet `consectetur`.Adipiscing elit _sed_ do eiusmod.## !!tooltips inspect```jsfunction consectetur(ipsum) {const { a, b } = ipsumreturn a + b}```</CodeWithTooltips>
function (ipsum, dolor = 1) {const sit = ipsum == null ? 0 : ipsum.sitdolor = sit - amet(dolor)return sit ? (ipsum) : []}
Hover (or focus) the lorem and consectetur tokens to see the respective tooltips.
Implementation
After we highlight the code, we find annotations where the query matches a tooltip title. If we find a match, we include the tooltip content in the annotation data.
code.tsx
import { Block, CodeBlock, parseProps } from "codehike/blocks"import { Pre, highlight } from "codehike/code"import { z } from "zod"const Schema = Block.extend({code: CodeBlock,tooltips: z.array(Block).optional(),})async function CodeWithTooltips(props: unknown) {const { code, tooltips = [] } = parseProps(props, Schema)const highlighted = await highlight(code, theme)highlighted.annotations = highlighted.annotations.map((a) => {const tooltip = tooltips.find((t) => t.title === a.query)if (!tooltip) return areturn {...a,data: { ...a.data, children: tooltip.children },We store the tooltip content in the annotation data
}})return <Pre code={highlighted} handlers={[tooltip]} />}
Then we define an AnnotationHandler
to render the tooltip inline using the shadcn tooltip components (npx shadcn@latest add tooltip
):
code.tsx
import { AnnotationHandler } from "codehike/code"import {TooltipProvider,Tooltip,TooltipTrigger,TooltipContent,} from "@/components/ui/tooltip"const tooltip: AnnotationHandler = {name: "tooltip",Inline: ({ children, annotation }) => {const { query, data } = annotationreturn (<TooltipProvider><Tooltip><TooltipTrigger className="underline decoration-dashed">{children}</TooltipTrigger><TooltipContent align="start">{data?.children || query}</TooltipContent></Tooltip></TooltipProvider>)},}
Make it better
You can use the same concept to embed the MDX not only in tooltips but other annotations like callouts.