Skip to content
Sign in
WritingSide by side translateMenu

Side by side translatePro

Source and translation set side by side as prose, paragraph against paragraph, with hover and focus sync: point at a sentence and its counterpart lights up while the rest steps back.

ProA supplier's delay notice translated from German sentence by sentence; point at any sentence to light its pair.

Installation

$ pnpm dlx shadcn@latest add @chatcn-pro/side-by-side-translate

Usage

tsx
import { SideBySideTranslate } from "@/components/ui/chatcn/pro/side-by-side-translate"

<SideBySideTranslate
  from={{ label: "German", lang: "de" }}
  to={{ label: "English", lang: "en" }}
  paragraphs={paragraphs}
  status={streaming ? "streaming" : "idle"}
/>

Each paragraph is a list of sentence pairs. Both sides keep reading as prose, and paragraphs line up row by row so long translations never drift. Sentences without a target yet hold their place while streaming. activeId lets another view, such as a glossary or the original PDF, drive the pairing. Each side sets lang and dir, so a right to left target works next to a left to right source.

Examples

States

ProA pair pinned from outside, an error partway, and empty.

Props

PropTypeNotes
from, to{ label, lang, dir? }The two languages
paragraphs{ id, source, target? }[][]Sentence pairs by paragraph
activeId, onActiveIdChangestringThe highlighted pair
statusidle | streaming | errorProgress shows in the header
error, onRetryReactNode, () => voidTranslated sentences stay

Keyboard

KeyAction
TabMoves through source sentences and highlights each pair

Accessibility

  • Each source sentence is a focus stop described by its translation, so the pairing is spoken.
  • Paragraphs carry lang, so screen readers switch voices.
  • The highlight uses the accent tint with Highlight colors in forced colors mode.

Motion

The pair highlight fades in over 150 ms; other sentences step back to gray so the pair stands out. Translations appear whole per sentence.