textmachine/frontend/src/showcase/Reader.tsx

74 lines
2.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import type { UnitList } from '../api';
import { Callout } from '../ui/Callout';
import { Loaded } from './Loaded';
import { noteTone } from './format';
import styles from './Reader.module.css';
interface Props {
/** Codes, not names, and they come from the book's data — see the note on the columns below. */
sourceLang?: string;
targetLang?: string;
units: Parameters<typeof Loaded<UnitList>>[0]['query'];
}
/**
* Two columns with NO scroll synchronisation: one scroll container, and the columns sit inside the
* row of a pair — then they physically cannot drift apart (STACK_DECISIONS §2). The unit of a pair
* is the export's edit unit, and a whole chapter is sometimes a single block.
*
* The columns are told apart by ONE device — a hairline down the gutter (owner's remark 9), drawn
* on the sheet rather than per block: a rule repeated on every pair breaks into dashes at the gaps
* between them, which reads as a table rather than as two columns.
*/
export function Reader({ sourceLang, targetLang, units }: Props) {
return (
<Loaded
query={units}
waiting="Раздел"
isEmpty={(data) => data.units.length === 0}
empty={{
title: 'Раздел пуст',
description: 'В этом разделе нет текста для сравнения.',
}}
>
{(data) => (
// tabIndex: a scrollable region has to be reachable from the keyboard, or the chapter can
// only be paged with a mouse. Found by the axe pass over the OPEN state — the route gate
// never saw it, because on its frame the text did not overflow the panel.
<div className={styles.pairs} tabIndex={0}>
<div className={styles.sheet}>
{data.units.map((unit) => {
const columns = (
<div className={styles.columns}>
<div className={styles.source} lang={sourceLang}>
{unit.source}
</div>
<div className={styles.target} lang={targetLang}>
{unit.target === undefined || unit.target === '' ? (
<span className={styles.missing}>перевод не получен</span>
) : (
unit.target
)}
</div>
</div>
);
return unit.note ? (
<Callout
key={unit.id}
tone={noteTone(unit.note.severity)}
caption={unit.note.message}
>
{columns}
</Callout>
) : (
<article key={unit.id} className={styles.pair}>
{columns}
</article>
);
})}
</div>
</div>
)}
</Loaded>
);
}