From 69851602319c78f50dc0501061253321c8fef99d Mon Sep 17 00:00:00 2001 From: Miguel Angel Simon Sierra Date: Sat, 14 Nov 2026 08:54:09 -0500 Subject: [PATCH 1/2] fix(registry): caption-highlight clears a short word's highlight when the word ends On a word shorter than 0.05 s the 0.15 s fade-in outlived the fade-out, so a frame inside that tail lit the highlight again until the phrase ended. --- docs/catalog/components/caption-highlight.mdx | 8 ++-- .../catalog/components/caption-highlight.json | 2 +- .../captionLastGroup.chromium.test.ts | 39 +++++++++++++++++++ .../caption-highlight/caption-highlight.html | 3 +- .../components/caption-highlight/demo.html | 3 +- 5 files changed, 49 insertions(+), 6 deletions(-) diff --git a/docs/catalog/components/caption-highlight.mdx b/docs/catalog/components/caption-highlight.mdx index 59f2bfbbe7e..2c10b4e9665 100644 --- a/docs/catalog/components/caption-highlight.mdx +++ b/docs/catalog/components/caption-highlight.mdx @@ -18,7 +18,7 @@ import { InstallCommand } from "/snippets/install-command.jsx"; compositionSrc="compositions/components/caption-highlight.html" title="Highlight" variables={[]} - meta={{"category":"Captions","badge":"Stable","codeLines":261}} + meta={{"category":"Captions","badge":"Stable","codeLines":263}} attribution={{"path":"registry/components/caption-highlight","tags":["captions","caption-style","highlight","social","tiktok"]}} hasCode rawUrl="https://raw.githubusercontent.com/heygen-com/hyperframes/main/registry/components/caption-highlight/caption-highlight.html" @@ -207,7 +207,8 @@ import { InstallCommand } from "/snippets/install-command.jsx"; var GROUPS = RAW_GROUPS.map(function (pair, gi) { var ws = pair[0], we = pair[1]; - var nextStart = gi + 1 < RAW_GROUPS.length ? WORDS[RAW_GROUPS[gi + 1][0]].start : 8.0; + var nextStart = + gi + 1 < RAW_GROUPS.length ? WORDS[RAW_GROUPS[gi + 1][0]].start : Infinity; var gEnd = Math.min(WORDS[we].end + 0.5, nextStart - 0.05); return { wordStart: ws, wordEnd: we, start: WORDS[ws].start, end: gEnd }; }); @@ -263,7 +264,8 @@ import { InstallCommand } from "/snippets/install-command.jsx"; var bgEl = document.getElementById("hl-bg-" + wi); var wordEl = document.getElementById("hl-w-" + wi); - tl.to(bgEl, { opacity: 1, scaleX: 1, duration: 0.15, ease: "power2.out" }, w.start); + var fadeIn = Math.min(0.15, w.end - w.start); + tl.to(bgEl, { opacity: 1, scaleX: 1, duration: fadeIn, ease: "power2.out" }, w.start); tl.to( wordEl, { filter: "brightness(1.05)", duration: 0.08, ease: "power2.out" }, diff --git a/docs/public/catalog/components/caption-highlight.json b/docs/public/catalog/components/caption-highlight.json index cd9011aa4b2..9b6e82278cc 100644 --- a/docs/public/catalog/components/caption-highlight.json +++ b/docs/public/catalog/components/caption-highlight.json @@ -1 +1 @@ -{"html":"\n\n \n \n \n Highlight\n \n \n \n \n \n \n \n \n
\n
\n \n\n \n \n\n"} \ No newline at end of file +{"html":"\n\n \n \n \n Highlight\n \n \n \n \n \n \n \n \n
\n
\n \n\n \n \n\n"} \ No newline at end of file diff --git a/packages/cli/src/registry/captionLastGroup.chromium.test.ts b/packages/cli/src/registry/captionLastGroup.chromium.test.ts index a602b862afa..c84aa36d6ce 100644 --- a/packages/cli/src/registry/captionLastGroup.chromium.test.ts +++ b/packages/cli/src/registry/captionLastGroup.chromium.test.ts @@ -69,3 +69,42 @@ describe.runIf(executablePath)("caption-highlight last group in Chromium", () => expect(await lastGroupVisibleAt(LAST_WORD_END_S - 0.05)).toBe(true); }); }); + +describe.runIf(executablePath)("caption-highlight short word in Chromium", () => { + let browser: Browser; + + beforeAll(async () => { + browser = await puppeteer.launch({ executablePath, args: ["--no-sandbox"] }); + }); + + afterAll(async () => { + await browser?.close(); + }); + + function componentWithShortWord(): string { + const demoWord = '{ text: "great", start: 0.3, end: 0.55 }'; + if (!componentHtml.includes(demoWord)) throw new Error("the demo's second word changed"); + return componentHtml + .replace(demoWord, '{ text: "great", start: 0.3, end: 0.34 }') + .replace(/`); + } + + // fails without the fix: a frame inside the 0.01 s tail relit the pill until the phrase ended. + it("clears a 0.04 s word's highlight once the word is over", async () => { + const page = await browser.newPage(); + try { + await page.setContent(componentWithShortWord()); + const opacity = await page.evaluate(() => { + const timeline = ( + window as unknown as { __timelines: Record } + ).__timelines["caption-highlight"]; + for (const time of [0, 0.3, 0.333, 0.367, 0.4, 0.433, 0.445, 0.467, 0.5]) + timeline!.seek(time); + return Number(getComputedStyle(document.getElementById("hl-bg-1")!).opacity); + }); + expect(opacity).toBe(0); + } finally { + await page.close(); + } + }); +}); diff --git a/registry/components/caption-highlight/caption-highlight.html b/registry/components/caption-highlight/caption-highlight.html index 615084e01f7..ffaba88c04a 100644 --- a/registry/components/caption-highlight/caption-highlight.html +++ b/registry/components/caption-highlight/caption-highlight.html @@ -235,7 +235,8 @@ var bgEl = document.getElementById("hl-bg-" + wi); var wordEl = document.getElementById("hl-w-" + wi); - tl.to(bgEl, { opacity: 1, scaleX: 1, duration: 0.15, ease: "power2.out" }, w.start); + var fadeIn = Math.min(0.15, w.end - w.start); + tl.to(bgEl, { opacity: 1, scaleX: 1, duration: fadeIn, ease: "power2.out" }, w.start); tl.to( wordEl, { filter: "brightness(1.05)", duration: 0.08, ease: "power2.out" }, diff --git a/registry/components/caption-highlight/demo.html b/registry/components/caption-highlight/demo.html index 2236c8b89e1..88b1da108ec 100644 --- a/registry/components/caption-highlight/demo.html +++ b/registry/components/caption-highlight/demo.html @@ -232,7 +232,8 @@ var bgEl = document.getElementById("hl-bg-" + wi); var wordEl = document.getElementById("hl-w-" + wi); - tl.to(bgEl, { opacity: 1, scaleX: 1, duration: 0.15, ease: "power2.out" }, w.start); + var fadeIn = Math.min(0.15, w.end - w.start); + tl.to(bgEl, { opacity: 1, scaleX: 1, duration: fadeIn, ease: "power2.out" }, w.start); tl.to( wordEl, { filter: "brightness(1.05)", duration: 0.08, ease: "power2.out" }, From fc2d22ca9274cbca34f4243c03f95259f69602c8 Mon Sep 17 00:00:00 2001 From: Miguel Angel Simon Sierra Date: Sat, 14 Nov 2026 09:17:26 -0500 Subject: [PATCH 2/2] fix(registry): leave the generated caption-highlight catalog files to the generator --- docs/catalog/components/caption-highlight.mdx | 8 +++----- docs/public/catalog/components/caption-highlight.json | 2 +- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/docs/catalog/components/caption-highlight.mdx b/docs/catalog/components/caption-highlight.mdx index 2c10b4e9665..59f2bfbbe7e 100644 --- a/docs/catalog/components/caption-highlight.mdx +++ b/docs/catalog/components/caption-highlight.mdx @@ -18,7 +18,7 @@ import { InstallCommand } from "/snippets/install-command.jsx"; compositionSrc="compositions/components/caption-highlight.html" title="Highlight" variables={[]} - meta={{"category":"Captions","badge":"Stable","codeLines":263}} + meta={{"category":"Captions","badge":"Stable","codeLines":261}} attribution={{"path":"registry/components/caption-highlight","tags":["captions","caption-style","highlight","social","tiktok"]}} hasCode rawUrl="https://raw.githubusercontent.com/heygen-com/hyperframes/main/registry/components/caption-highlight/caption-highlight.html" @@ -207,8 +207,7 @@ import { InstallCommand } from "/snippets/install-command.jsx"; var GROUPS = RAW_GROUPS.map(function (pair, gi) { var ws = pair[0], we = pair[1]; - var nextStart = - gi + 1 < RAW_GROUPS.length ? WORDS[RAW_GROUPS[gi + 1][0]].start : Infinity; + var nextStart = gi + 1 < RAW_GROUPS.length ? WORDS[RAW_GROUPS[gi + 1][0]].start : 8.0; var gEnd = Math.min(WORDS[we].end + 0.5, nextStart - 0.05); return { wordStart: ws, wordEnd: we, start: WORDS[ws].start, end: gEnd }; }); @@ -264,8 +263,7 @@ import { InstallCommand } from "/snippets/install-command.jsx"; var bgEl = document.getElementById("hl-bg-" + wi); var wordEl = document.getElementById("hl-w-" + wi); - var fadeIn = Math.min(0.15, w.end - w.start); - tl.to(bgEl, { opacity: 1, scaleX: 1, duration: fadeIn, ease: "power2.out" }, w.start); + tl.to(bgEl, { opacity: 1, scaleX: 1, duration: 0.15, ease: "power2.out" }, w.start); tl.to( wordEl, { filter: "brightness(1.05)", duration: 0.08, ease: "power2.out" }, diff --git a/docs/public/catalog/components/caption-highlight.json b/docs/public/catalog/components/caption-highlight.json index 9b6e82278cc..cd9011aa4b2 100644 --- a/docs/public/catalog/components/caption-highlight.json +++ b/docs/public/catalog/components/caption-highlight.json @@ -1 +1 @@ -{"html":"\n\n \n \n \n Highlight\n \n \n \n \n \n \n \n \n
\n
\n \n\n \n \n\n"} \ No newline at end of file +{"html":"\n\n \n \n \n Highlight\n \n \n \n \n \n \n \n \n
\n
\n \n\n \n \n\n"} \ No newline at end of file