Skip to content

Commit a9428e0

Browse files
feat(studio): format info tooltip on export selector (heygen-com#257)
## Summary - Adds a hover tooltip (?) next to the format dropdown in the render queue export bar - Shows the selected format's details (codec, use case) plus a comparison with the other two formats - Helps users pick between MP4 (general), MOV/ProRes 4444 (transparent video for editors), and WebM/VP9 (transparent for web) ## Test plan - [x] Open studio, go to the render queue panel - [x] Hover over the (?) icon next to the format dropdown — tooltip appears above - [x] Switch format in the dropdown — tooltip content updates to show the selected format first - [x] Move pointer away — tooltip dismisses - [x] Verify tooltip doesn't clip or overflow the panel <img width="420" height="263" alt="image" src="https://github.com/user-attachments/assets/f4bd8bf7-65ed-45ab-ac53-577b4985fa34" />
1 parent 58ddb11 commit a9428e0

1 file changed

Lines changed: 68 additions & 1 deletion

File tree

packages/studio/src/components/renders/RenderQueue.tsx

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,72 @@ interface RenderQueueProps {
1111
isRendering: boolean;
1212
}
1313

14+
const FORMAT_INFO: Record<"mp4" | "webm" | "mov", { label: string; desc: string }> = {
15+
mp4: { label: "MP4", desc: "Best for general use. Smallest file, universal playback." },
16+
mov: {
17+
label: "MOV (ProRes 4444)",
18+
desc: "Transparent video. Works in CapCut, Final Cut Pro, Premiere, DaVinci Resolve, After Effects. Large files.",
19+
},
20+
webm: {
21+
label: "WebM (VP9)",
22+
desc: "Transparent video for web. Smaller than MOV but limited editor support.",
23+
},
24+
};
25+
26+
function FormatInfoTooltip({ format }: { format: "mp4" | "webm" | "mov" }) {
27+
const [open, setOpen] = useState(false);
28+
const timeoutRef = useRef<ReturnType<typeof setTimeout>>(undefined);
29+
30+
const show = () => {
31+
clearTimeout(timeoutRef.current);
32+
setOpen(true);
33+
};
34+
const hide = () => {
35+
timeoutRef.current = setTimeout(() => setOpen(false), 120);
36+
};
37+
38+
useEffect(() => () => clearTimeout(timeoutRef.current), []);
39+
40+
const info = FORMAT_INFO[format];
41+
42+
return (
43+
<div className="relative" onPointerEnter={show} onPointerLeave={hide}>
44+
<svg
45+
width="12"
46+
height="12"
47+
viewBox="0 0 24 24"
48+
fill="none"
49+
stroke="currentColor"
50+
strokeWidth="2"
51+
strokeLinecap="round"
52+
strokeLinejoin="round"
53+
className="text-neutral-600 hover:text-neutral-400 transition-colors cursor-help"
54+
>
55+
<circle cx="12" cy="12" r="10" />
56+
<path d="M9.09 9a3 3 0 015.83 1c0 2-3 3-3 3" />
57+
<line x1="12" y1="17" x2="12.01" y2="17" />
58+
</svg>
59+
{open && (
60+
<div className="absolute bottom-full right-0 mb-1.5 w-52 p-2 rounded bg-neutral-900 border border-neutral-700 shadow-lg z-50">
61+
<p className="text-[10px] font-semibold text-neutral-200 mb-0.5">{info.label}</p>
62+
<p className="text-[9px] text-neutral-400 leading-tight">{info.desc}</p>
63+
<div className="mt-1.5 pt-1.5 border-t border-neutral-800">
64+
{(["mp4", "mov", "webm"] as const)
65+
.filter((f) => f !== format)
66+
.map((f) => (
67+
<p key={f} className="text-[9px] text-neutral-500 leading-relaxed">
68+
<span className="text-neutral-400 font-medium">{FORMAT_INFO[f].label}</span>
69+
{" — "}
70+
{FORMAT_INFO[f].desc}
71+
</p>
72+
))}
73+
</div>
74+
</div>
75+
)}
76+
</div>
77+
);
78+
}
79+
1480
function FormatExportButton({
1581
onStartRender,
1682
isRendering,
@@ -21,7 +87,8 @@ function FormatExportButton({
2187
const [format, setFormat] = useState<"mp4" | "webm" | "mov">("mp4");
2288

2389
return (
24-
<div className="flex items-center gap-0.5">
90+
<div className="flex items-center gap-1">
91+
<FormatInfoTooltip format={format} />
2592
<select
2693
value={format}
2794
onChange={(e) => setFormat(e.target.value as "mp4" | "webm" | "mov")}

0 commit comments

Comments
 (0)