/** * ReadingSettingsPanel — slide-in drawer from the right for customizing * the reading experience: theme, font, sizing, orientation. */ import type { KeyboardEvent as ReactKeyboardEvent } from "react"; import { useTranslation } from "react-i18n-lite"; import type { FontFamily, OrientationLock, ReadingSettings, ThemePreset, } from "../../types/reader"; import type { SettingsPersistMode } from "../../hooks/useReadingSettings"; import { PanelCloseButton } from "./PanelCloseButton"; interface ReadingSettingsPanelProps { format?: "epub" | "pdf"; settings: ReadingSettings; pdfScale?: number; onPdfScaleChange?: (scale: number) => void; isOpen: boolean; onClose: () => void; onUpdate: ( partial: Partial, persist?: SettingsPersistMode, ) => void; onFlush: () => Promise; } const THEME_OPTIONS: { value: ThemePreset; labelKey: string }[] = [ { value: "sepia", labelKey: "reader.themeSepia" }, { value: "dark", labelKey: "reader.themeDark" }, { value: "light", labelKey: "reader.themeLight" }, { value: "paper", labelKey: "reader.themePaper" }, ]; const FONT_OPTIONS: { value: FontFamily; labelKey: string }[] = [ { value: "sans-serif", labelKey: "reader.fontSans" }, { value: "serif", labelKey: "reader.fontSerif" }, { value: "monospace", labelKey: "reader.fontMonospace" }, ]; const ORIENTATION_OPTIONS: { value: OrientationLock; labelKey: string }[] = [ { value: "auto", labelKey: "reader.orientationAuto" }, { value: "portrait", labelKey: "reader.orientationPortrait" }, { value: "landscape", labelKey: "reader.orientationLandscape" }, ]; export default function ReadingSettingsPanel({ format = "epub", settings, pdfScale = 1.25, onPdfScaleChange, isOpen, onClose, onUpdate, onFlush, }: ReadingSettingsPanelProps) { const { t } = useTranslation(); const handleClose = () => { void onFlush(); onClose(); }; const handleSlider = (key: keyof ReadingSettings, value: number) => { onUpdate({ [key]: value } as Partial, "debounced"); }; const handleDiscrete = (key: keyof ReadingSettings, value: string | number) => { onUpdate({ [key]: value } as Partial, "immediate"); }; return ( <> {isOpen && (
{ if (e.key === "Escape") handleClose(); }} role="presentation" /> )} ); }