import { ORIENTATIONS, PAGE_SIZES } from "$pdf/constants"; import { getCjkFallbackFont, hasCjkContent, LATIN_ONLY_FONT_NAMES } from "$pdf/fonts"; import { type FontName, MarginSide, Orientation, PageSize } from "$pdf/types"; import { usePdfDialogUiState } from "$state/selectors"; import type { RenderedFontFamily } from "$types"; import { type ReactNode, useCallback } from "react"; type OptionSectionProps = { title: string; description: string; children: ReactNode }; const FIELD_CLASS_NAME = "w-full rounded-md border border-stroke-subtle bg-layer-01 px-3 py-2 text-sm text-text-primary transition-colors focus:border-accent-cyan focus:outline-none"; const OptionSection = ({ title, description, children }: OptionSectionProps) => (

{title}

{description}

{children}
); function PdfExportDialogPageSize() { const { setPageSize, options } = usePdfDialogUiState(); const handlePageSizeChange = useCallback((event: React.ChangeEvent) => { setPageSize(event.target.value as PageSize); }, [setPageSize]); return ( ); } function PdfExportDialogOrientation() { const { setOrientation, options } = usePdfDialogUiState(); const handleOrientationChange = useCallback((event: React.ChangeEvent) => { setOrientation(event.target.value as Orientation); }, [setOrientation]); return ( ); } function PdfExportDialogFontSize() { const { setFontSize, options } = usePdfDialogUiState(); const handleFontSizeChange = useCallback((event: React.ChangeEvent) => { setFontSize(parseInt(event.target.value, 10)); }, [setFontSize]); return (
Font Size {options.fontSize}px
); } function PdfMarginField({ side, value }: { side: MarginSide; value: number }) { const { setMargin } = usePdfDialogUiState(); const onChange = useCallback((event: React.ChangeEvent) => { setMargin(side, parseInt(event.target.value || "0", 10)); }, [setMargin, side]); return ( ); } function PdfExportDialogMargins() { const { options } = usePdfDialogUiState(); return (
); } function PdfExportDialogHeaderFooter() { const { setIncludeTitle, setIncludeHeader, setIncludeFooter, options } = usePdfDialogUiState(); const onTitleChange = useCallback((event: React.ChangeEvent) => { setIncludeTitle(event.target.checked); }, [setIncludeTitle]); const onHeaderChange = useCallback((event: React.ChangeEvent) => { setIncludeHeader(event.target.checked); }, [setIncludeHeader]); const onFooterChange = useCallback((event: React.ChangeEvent) => { setIncludeFooter(event.target.checked); }, [setIncludeFooter]); return (
); } export const PdfExportDialogOptions = () => (
); type PdfCjkWarningProps = { documentText: string; renderedFontFamily: RenderedFontFamily }; export const PdfCjkWarning = ({ documentText, renderedFontFamily }: PdfCjkWarningProps) => { const isLatinOnly = LATIN_ONLY_FONT_NAMES.has(renderedFontFamily as FontName); const hasCjk = hasCjkContent(documentText); const fallbackFont = getCjkFallbackFont(renderedFontFamily as FontName); if (!isLatinOnly || !hasCjk) return null; return (
CJK characters detected. PDF will use {fallbackFont} since {renderedFontFamily} lacks CJK glyphs.
); };