W3: presentation fixes — delimiters, line breaks, mermaid
- src/core/math-delims.ts: pure preprocessing for the \(...\)/\[...\] math contract — balanced delimiters rewrite to the two-dollar forms remark-math parses ($ is never math). Skips code fences/spans, escaped delimiters, and leaves unbalanced (mid-stream) delimiters untouched. Display math renders as a block: mid-paragraph gets blank-line padding; indented (list items) degrades to inline so list continuations don't half-parse. - message.tsx: transform in the render path (children-memoized); math plugin now singleDollarTextMath: false — the currency hazard dies structurally. remark-breaks via the cjk remarkPluginsAfter slot (the bare remarkPlugins prop would replace the [remark-gfm, codeMeta] defaults). - mermaid: dark theme + sans font via Streamdown's mermaid prop; dark-styled error fallback (components/mermaid-error.tsx) with error, source in <details>, and retry. - globals.css (appended): @source for streamdown dist — its internal UI chrome (code blocks, mermaid containers, tables) was entirely unstyled because Tailwind v4 never scans node_modules; --color-sidebar → card; wide mermaid SVGs capped to the column; .katex-display scrolls. - tests/render-markdown.test.tsx: 26 tests (transform unit + render). The math describe block in render-cards.test.tsx is updated to the new contract ($...$ now renders as literal text — pinned).
This commit is contained in:
@@ -0,0 +1,44 @@
|
||||
"use client";
|
||||
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { cn } from "@/lib/utils";
|
||||
import type { MermaidErrorComponentProps } from "streamdown";
|
||||
|
||||
/**
|
||||
* Fallback for mermaid diagrams that fail to parse — wired via Streamdown's
|
||||
* `mermaid.errorComponent`. Replaces the default light-themed red box with a
|
||||
* card matching the app: the error, the source in a details block (so a
|
||||
* broken diagram doesn't flood the transcript), and a retry.
|
||||
*/
|
||||
export const MermaidError = ({
|
||||
chart,
|
||||
error,
|
||||
retry,
|
||||
className,
|
||||
}: MermaidErrorComponentProps & { className?: string }) => (
|
||||
<div
|
||||
className={cn(
|
||||
"my-4 rounded-xl border border-destructive/40 bg-destructive/5 p-4",
|
||||
className,
|
||||
)}
|
||||
data-streamdown="mermaid-error"
|
||||
>
|
||||
<p className="text-sm font-medium text-destructive">
|
||||
Diagram failed to render
|
||||
</p>
|
||||
<p className="mt-1 font-mono text-xs break-words text-muted-foreground">
|
||||
{error}
|
||||
</p>
|
||||
<details className="mt-3">
|
||||
<summary className="cursor-pointer text-xs text-muted-foreground">
|
||||
Show diagram source
|
||||
</summary>
|
||||
<pre className="mt-2 overflow-x-auto rounded-lg bg-muted p-3 font-mono text-xs text-foreground">
|
||||
{chart}
|
||||
</pre>
|
||||
</details>
|
||||
<Button className="mt-3" onClick={retry} size="sm" variant="outline">
|
||||
Retry
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
Reference in New Issue
Block a user