dark mode PDF filter init (#5994)

Co-authored-by: a <a>
This commit is contained in:
Anthony Stirling
2026-03-25 15:38:42 +00:00
committed by GitHub
co-authored by a <a>
parent 28613caf8a
commit bb43e9dcdf
7 changed files with 108 additions and 53 deletions
@@ -140,6 +140,8 @@ const EmbedPdfViewerContent = ({
printActions,
setApplyChanges,
applyChanges: viewerApplyChanges,
pdfRenderMode,
cyclePdfRenderMode,
} = useViewer();
const scrollState = getScrollState();
@@ -449,6 +451,7 @@ const EmbedPdfViewerContent = ({
}
}
return;
case 'z':
case 'Z':
// Ctrl+Z: Undo; Ctrl+Shift+Z: Redo
@@ -503,7 +506,7 @@ const EmbedPdfViewerContent = ({
}, [
isViewerHovered, isSearchInterfaceVisible, zoomActions, searchInterfaceActions,
scrollActions, printActions, exportActions, rotationActions, historyApiRef,
viewerApplyChanges,
viewerApplyChanges, cyclePdfRenderMode,
]);
// Watch the annotation history API to detect when the document becomes "dirty".
@@ -964,6 +967,7 @@ const EmbedPdfViewerContent = ({
}}>
<LocalEmbedPDF
key={currentFileId || 'no-file'}
pdfRenderMode={pdfRenderMode}
file={effectiveFile.file}
url={effectiveFile.url}
fileName={
@@ -88,9 +88,11 @@ interface LocalEmbedPDFProps {
commentsSidebarRightOffset?: string;
/** When true, blocks the general ink/pen annotation tool (sign tool context). */
isSignMode?: boolean;
/** Controls CSS filter applied only to rendered PDF canvas tiles */
pdfRenderMode?: 'normal' | 'dark' | 'sepia';
}
export function LocalEmbedPDF({ file, url, fileName, enableAnnotations = false, enableRedaction = false, enableFormFill = false, isManualRedactionMode = false, showBakedAnnotations = true, onSignatureAdded, signatureApiRef, annotationApiRef, historyApiRef, redactionTrackerRef, fileId, isCommentsSidebarVisible = false, commentsSidebarRightOffset = '0rem', isSignMode = false }: LocalEmbedPDFProps) {
export function LocalEmbedPDF({ file, url, fileName, enableAnnotations = false, enableRedaction = false, enableFormFill = false, isManualRedactionMode = false, showBakedAnnotations = true, onSignatureAdded, signatureApiRef, annotationApiRef, historyApiRef, redactionTrackerRef, fileId, isCommentsSidebarVisible = false, commentsSidebarRightOffset = '0rem', isSignMode = false, pdfRenderMode = 'normal' }: LocalEmbedPDFProps) {
const { t } = useTranslation();
const [pdfUrl, setPdfUrl] = useState<string | null>(null);
const [, setAnnotations] = useState<Array<{id: string, pageIndex: number, rect: Rect}>>([]);
@@ -784,7 +786,19 @@ export function LocalEmbedPDF({ file, url, fileName, enableAnnotations = false,
onDrop={(e) => e.preventDefault()}
onDragOver={(e) => e.preventDefault()}
>
<TilingLayer documentId={documentId} pageIndex={pageIndex} />
<div style={{
position: 'absolute',
inset: 0,
transition: 'filter 0.25s ease',
filter:
pdfRenderMode === 'dark'
? 'invert(1) hue-rotate(180deg)'
: pdfRenderMode === 'sepia'
? 'sepia(0.7) brightness(0.85)'
: undefined,
}}>
<TilingLayer documentId={documentId} pageIndex={pageIndex} />
</div>
<CustomSearchLayer documentId={documentId} pageIndex={pageIndex} />
@@ -9,6 +9,9 @@ import ArrowForwardIosIcon from '@mui/icons-material/ArrowForwardIos';
import LastPageIcon from '@mui/icons-material/LastPage';
import DescriptionIcon from '@mui/icons-material/Description';
import ViewWeekIcon from '@mui/icons-material/ViewWeek';
import DarkModeIcon from '@mui/icons-material/DarkMode';
import WbSunnyIcon from '@mui/icons-material/WbSunny';
import WbTwilightIcon from '@mui/icons-material/WbTwilight';
interface PdfViewerToolbarProps {
// Page navigation props (placeholders for now)
@@ -33,6 +36,8 @@ export function PdfViewerToolbar({
registerImmediateZoomUpdate,
registerImmediateScrollUpdate,
registerImmediateSpreadUpdate,
pdfRenderMode,
cyclePdfRenderMode,
} = useViewer();
const scrollState = getScrollState();
@@ -126,7 +131,7 @@ export function PdfViewerToolbar({
borderBottomRightRadius: 0,
boxShadow: "0 -2px 8px rgba(0,0,0,0.04)",
pointerEvents: "auto",
minWidth: '26.5rem',
minWidth: '30rem',
}}
>
{/* First Page Button */}
@@ -234,6 +239,39 @@ export function PdfViewerToolbar({
</Button>
</Tooltip>
{/* PDF Render Mode Toggle */}
<Tooltip
content={
pdfRenderMode === 'normal'
? t("viewer.enableDarkFilter", "Enable Dark Filter")
: pdfRenderMode === 'dark'
? t("viewer.enableSepiaFilter", "Enable Sepia Filter")
: t("viewer.disableColorFilter", "Disable Color Filter")
}
position="top"
arrow
>
<Button
variant={pdfRenderMode !== 'normal' ? "filled" : "light"}
color="blue"
size="md"
radius="xl"
onClick={cyclePdfRenderMode}
style={{ minWidth: '2.5rem' }}
aria-label={
pdfRenderMode === 'normal'
? t("viewer.enableDarkFilter", "Enable Dark Filter")
: pdfRenderMode === 'dark'
? t("viewer.enableSepiaFilter", "Enable Sepia Filter")
: t("viewer.disableColorFilter", "Disable Color Filter")
}
>
{pdfRenderMode === 'normal' && <DarkModeIcon fontSize="small" />}
{pdfRenderMode === 'dark' && <WbTwilightIcon fontSize="small" />}
{pdfRenderMode === 'sepia' && <WbSunnyIcon fontSize="small" />}
</Button>
</Tooltip>
{/* Zoom Controls */}
<Group gap={4} align="center" style={{ marginLeft: 16 }}>
<Button