Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions Videos/Redaction/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
dist
dist-ssr
*.local

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
22 changes: 22 additions & 0 deletions Videos/Redaction/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Redaction in PDF Viewer

This section demonstrates how to redact PDF content using the Syncfusion React PDF Viewer.

Documentation: https://help.syncfusion.com/document-processing/pdf/pdf-viewer/react/redaction/overview


## Running the React Sample
To run the React sample

Step 1: Open a terminal or command prompt.

Step 2: Navigate to the root directory of the React sample.

Step 3: Run the command npm install to install the necessary dependencies specified in the package.json file.
```
npm install
```
Step 4 Once the installation is complete, run npm start to start the React development server and open the PDF Viewer component in your default browser.
```
npm start
```
29 changes: 29 additions & 0 deletions Videos/Redaction/eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import js from '@eslint/js'
import globals from 'globals'
import reactHooks from 'eslint-plugin-react-hooks'
import reactRefresh from 'eslint-plugin-react-refresh'
import { defineConfig, globalIgnores } from 'eslint/config'

export default defineConfig([
globalIgnores(['dist']),
{
files: ['**/*.{js,jsx}'],
extends: [
js.configs.recommended,
reactHooks.configs.flat.recommended,
reactRefresh.configs.vite,
],
languageOptions: {
ecmaVersion: 2020,
globals: globals.browser,
parserOptions: {
ecmaVersion: 'latest',
ecmaFeatures: { jsx: true },
sourceType: 'module',
},
},
rules: {
'no-unused-vars': ['error', { varsIgnorePattern: '^[A-Z_]' }],
},
},
])
13 changes: 13 additions & 0 deletions Videos/Redaction/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>redaction</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.jsx"></script>
</body>
</html>
28 changes: 28 additions & 0 deletions Videos/Redaction/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"name": "redaction",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"start": "vite",
"build": "vite build",
"preview": "vite preview"
},
"dependencies": {
"@syncfusion/ej2-react-pdfviewer": "*",
"react": "^19.2.0",
"react-dom": "^19.2.0"
},
"devDependencies": {
"@eslint/js": "^9.39.1",
"@types/react": "^19.2.5",
"@types/react-dom": "^19.2.3",
"@vitejs/plugin-react": "^5.1.1",
"eslint": "^9.39.1",
"eslint-plugin-react-hooks": "^7.0.1",
"eslint-plugin-react-refresh": "^0.4.24",
"globals": "^16.5.0",
"vite": "^7.2.4"
}
}
Binary file not shown.
1 change: 1 addition & 0 deletions Videos/Redaction/public/assets/react.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Videos/Redaction/public/assets/redaction.pdf
Binary file not shown.
1 change: 1 addition & 0 deletions Videos/Redaction/public/vite.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
42 changes: 42 additions & 0 deletions Videos/Redaction/src/App.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#root {
max-width: 1280px;
margin: 0 auto;
padding: 2rem;
text-align: center;
}

.logo {
height: 6em;
padding: 1.5em;
will-change: filter;
transition: filter 300ms;
}
.logo:hover {
filter: drop-shadow(0 0 2em #646cffaa);
}
.logo.react:hover {
filter: drop-shadow(0 0 2em #61dafbaa);
}

@keyframes logo-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}

@media (prefers-reduced-motion: no-preference) {
a:nth-of-type(2) .logo {
animation: logo-spin infinite 20s linear;
}
}

.card {
padding: 2em;
}

.read-the-docs {
color: #888;
}
118 changes: 118 additions & 0 deletions Videos/Redaction/src/App.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
import React from 'react';
import './index.css';
import {
PdfViewerComponent, LinkAnnotation, BookmarkView, Magnification, ThumbnailView, Navigation, Annotation,
TextSearch, TextSelection, Toolbar, Print, FormFields, FormDesigner, Inject
} from '@syncfusion/ej2-react-pdfviewer';

function App() {

const viewerRef = React.useRef(null);

const addRedactAnnotation = () => {
if (!viewerRef.current) return;
const viewer = viewerRef.current;
viewer.annotation.addAnnotation('Redaction', {
bound: { x: 460, y: 200, width: 75, height: 20 },
pageNumber: 1,
markerFillColor: '#0000FF',
markerBorderColor: 'red',
fillColor: 'red',
overlayText: 'Confidential',
fontColor: 'yellow',
fontFamily: 'Times New Roman',
fontSize: 8,
beforeRedactionsApplied: false
});
};


const editRedactAnnotation = () => {
if (!viewerRef.current) return;
const viewer = viewerRef.current;
const collection = viewer.annotationCollection;
const annotation = collection[1];
if (annotation.subject === 'Redaction') {
annotation.overlayText = 'EditedAnnotation';
annotation.markerFillColor = '#22FF00';
annotation.markerBorderColor = '#000000';
annotation.isRepeat = true;
annotation.fillColor = '#F8F8F8';
annotation.fontSize = 14;
annotation.fontColor = '#333333';
annotation.fontFamily = 'Symbol';
annotation.textAlign = 'Right';
viewer.annotation.editAnnotation(annotation);
}
};


const deleteAnnotationById = () => {
if (!viewerRef.current) return;
const id = (viewerRef.current).annotationCollection?.[1]?.annotationId;
if (id) {
viewerRef.current.annotationModule.deleteAnnotationById(id);
}
};

const addPageRedactions = () => {
if (!viewerRef.current) return;
const viewer = viewerRef.current;
viewer.annotation.addPageRedactions([3, 5, 7]);
};

const applyRedaction = () => {
if (!viewerRef.current) return;
const viewer = viewerRef.current;
viewer.annotation.redact();
};

return (
<div>
<div
style={{
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
padding: '12px 18px',
borderBottom: '1px solid #e5e5e5',
backgroundColor: '#f9f9f9'
}}>
<h3 style={{ margin: 0 }}>React PDF Viewer</h3>
<div style={{ display: 'flex', gap: 8, flexWrap: 'wrap' }}>
<button id="addRedactAnnotation" type="button" onClick={addRedactAnnotation}>
Add Redaction Annotation
</button>
<button id="editRedactAnnotation" type="button" onClick={editRedactAnnotation}>
Edit Redaction
</button>
<button id="deleteAnnotationById" type="button" onClick={deleteAnnotationById}>
Delete Annotation By Id
</button>
<button id="addPageRedactions" type="button" onClick={addPageRedactions}>
Add Page Redaction
</button>
<button id="applyRedaction" type="button" onClick={applyRedaction}>
Apply Redaction
</button>
</div>
</div>
<div className="control-section">
<PdfViewerComponent
ref={viewerRef}
id="container"
documentPath={window.location.origin + '/assets/redaction.pdf'}
resourceUrl="https://cdn.syncfusion.com/ej2/31.2.2/dist/ej2-pdfviewer-lib"
style={{ height: '660px' }}
>
<Inject services={[
Magnification, Navigation, Annotation, LinkAnnotation, BookmarkView,
ThumbnailView, Print, Toolbar, TextSelection, TextSearch, FormFields, FormDesigner
]} />
</PdfViewerComponent>
</div>
</div>
);
}

export default App;
8 changes: 8 additions & 0 deletions Videos/Redaction/src/index.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
@import '../node_modules/@syncfusion/ej2-base/styles/material.css';
@import '../node_modules/@syncfusion/ej2-buttons/styles/material.css';
@import '../node_modules/@syncfusion/ej2-dropdowns/styles/material.css';
@import '../node_modules/@syncfusion/ej2-inputs/styles/material.css';
@import '../node_modules/@syncfusion/ej2-navigations/styles/material.css';
@import '../node_modules/@syncfusion/ej2-popups/styles/material.css';
@import '../node_modules/@syncfusion/ej2-splitbuttons/styles/material.css';
@import "../node_modules/@syncfusion/ej2-pdfviewer/styles/material.css";
10 changes: 10 additions & 0 deletions Videos/Redaction/src/main.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import './index.css'
import App from './App.jsx'

createRoot(document.getElementById('root')).render(
<StrictMode>
<App />
</StrictMode>,
)
7 changes: 7 additions & 0 deletions Videos/Redaction/vite.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

// https://vite.dev/config/
export default defineConfig({
plugins: [react()],
})