diff --git a/packages/session-ui/component-tests/markdown.spec.ts b/packages/session-ui/component-tests/markdown.spec.ts index 42ea80ad595..ab42613d7d6 100644 --- a/packages/session-ui/component-tests/markdown.spec.ts +++ b/packages/session-ui/component-tests/markdown.spec.ts @@ -501,6 +501,32 @@ story("keeps inline code backgrounds 18px tall", async ({ page }) => { ).toEqual([18, 18]) }) +story("keeps inline code geometry when a completed stream turns it into a file link", async ({ page }) => { + await page.evaluate(async (fixture) => { + const { mountMarkdown } = await import(fixture) + await mountMarkdown({ text: "Edit `src/file.ts` to fix it", streaming: true }) + }, fixture) + await page.evaluate(() => document.fonts.ready.then(() => undefined)) + const harness = page.getByTestId("markdown-fixture") + const code = harness.locator(":not(pre) > code") + await expect(code).toHaveText("src/file.ts") + await expect(code).not.toHaveAttribute("data-inline-code-kind") + + const geometry = () => + code.evaluate((element) => { + const next = document.createRange() + next.selectNodeContents(element.nextSibling!) + const box = element.getBoundingClientRect() + + return { left: box.left, right: box.right, next: next.getBoundingClientRect().left } + }) + + const before = await geometry() + await harness.getByLabel("Streaming").uncheck() + await expect(code).toHaveAttribute("data-inline-code-kind", "path") + expect(await geometry()).toEqual(before) +}) + story("shares in-flight Markdown rendering without overwriting a reclaimed cache entry", async ({ page }) => { const result = await page.evaluate(async (fixture) => { const { getCachedMarkdown, renderCachedMarkdown } = await import(fixture) diff --git a/packages/session-ui/src/components/markdown.css b/packages/session-ui/src/components/markdown.css index 82dde48b017..2d72ba97937 100644 --- a/packages/session-ui/src/components/markdown.css +++ b/packages/session-ui/src/components/markdown.css @@ -395,10 +395,13 @@ background: color-mix(in oklch, var(--v2-text-text-base) var(--markdown-inline-code-bg-mix), transparent); } + /* A path turns into a link after an async existence check, so it keeps the plain code box and only fades its colours. */ :not(pre) > code[data-inline-code-kind="path"] { color: var(--markdown-inline-code-path-color); - padding: 0 2px; - background: none; + background-color: transparent; + transition: + color 200ms ease-out, + background-color 200ms ease-out; } a.external-link > code[data-inline-code-kind="url"] { @@ -497,6 +500,10 @@ [data-component="markdown"] :is([data-markdown-word], code)[data-markdown-enter] { animation: none; } + + [data-component="markdown"] :not(pre) > code[data-inline-code-kind="path"] { + transition: none; + } } [data-component="markdown"] > * {