"use client" import { type CSSProperties, useEffect, useMemo, useRef, useState } from "react" import { Check, Code2, Copy, ExternalLink, X } from "lucide-react" export interface EmbedVariant { id: string /** Display name in the variant picker (e.g. "Histogram", "Frontier"). */ label: string /** Embed route for this variant. */ embedPath: string } interface EmbedButtonProps { /** Path relative to the site root, e.g. `/embed/eval/leaderboard/mmlu`. * Used when there is exactly one embeddable view. Use `variants` when * the surface ships in multiple views (e.g. histogram vs. frontier). */ embedPath?: string /** Multiple variants of the same surface โ€” popover shows a small picker * so users can choose which view to embed. */ variants?: EmbedVariant[] /** Short label for the embeddable surface, shown in the popover header. */ label: string /** Default iframe height in pixels (width is always 100% of the parent). */ defaultHeight?: number /** Tighter affordance for plots with limited room. */ size?: "sm" | "md" /** When `true`, position the button absolutely in the top-right of the * nearest positioned ancestor. When `false` (default), render inline * so callers can place it inside a flex header without overlap. */ floating?: boolean } /** * Embed-this affordance pinned to the top-right of an embeddable surface. * Click โ†’ popover with a copyable iframe snippet + a "preview" link to * open the embed route in a new tab. Anchored absolutely; the parent * container should be `position: relative`. */ export function EmbedButton({ embedPath, variants, label, defaultHeight = 480, size = "md", floating = false, }: EmbedButtonProps) { const resolvedVariants: EmbedVariant[] = useMemo(() => { if (variants && variants.length > 0) return variants if (embedPath) return [{ id: "default", label, embedPath }] return [] }, [variants, embedPath, label]) const [open, setOpen] = useState(false) const [copied, setCopied] = useState(false) const [height, setHeight] = useState(defaultHeight) const [activeVariantId, setActiveVariantId] = useState( () => resolvedVariants[0]?.id ?? "default", ) const activeVariant = resolvedVariants.find((v) => v.id === activeVariantId) ?? resolvedVariants[0] const popoverRef = useRef(null) const triggerRef = useRef(null) useEffect(() => { if (!open) return function onDocClick(e: MouseEvent) { const t = e.target as Node if (popoverRef.current?.contains(t)) return if (triggerRef.current?.contains(t)) return setOpen(false) } function onKey(e: KeyboardEvent) { if (e.key === "Escape") setOpen(false) } document.addEventListener("mousedown", onDocClick) document.addEventListener("keydown", onKey) return () => { document.removeEventListener("mousedown", onDocClick) document.removeEventListener("keydown", onKey) } }, [open]) // Build the snippet at render time so it picks up the deployed origin // when copied from the user's browser. Falls back to a relative URL // during SSR so initial markup stays stable. const activePath = activeVariant?.embedPath ?? "" const fullUrl = typeof window !== "undefined" && activePath ? new URL(activePath, window.location.origin).toString() : activePath const titleAttr = resolvedVariants.length > 1 && activeVariant ? `${label} โ€” ${activeVariant.label}` : label const snippet = `` async function copySnippet() { try { await navigator.clipboard.writeText(snippet) setCopied(true) setTimeout(() => setCopied(false), 1800) } catch { // Fallback: select the textarea for manual copy const ta = popoverRef.current?.querySelector("textarea") if (ta instanceof HTMLTextAreaElement) { ta.select() } } } const wrapperStyle: CSSProperties = floating ? { position: "absolute", top: 8, right: 8, zIndex: 5 } : { position: "relative", display: "inline-block" } return (
{open && (
e.stopPropagation()} >
Embed ยท {label}

Paste this iframe snippet anywhere HTML is allowed (blog post, Notion, Confluence, etc.). The embed updates automatically when the underlying data refreshes.

{resolvedVariants.length > 1 && (
View {resolvedVariants.map((v) => { const isActive = v.id === activeVariant?.id return ( ) })}
)}