diff --git a/Videos/Redaction/.gitignore b/Videos/Redaction/.gitignore new file mode 100644 index 0000000..a547bf3 --- /dev/null +++ b/Videos/Redaction/.gitignore @@ -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? diff --git a/Videos/Redaction/README.md b/Videos/Redaction/README.md new file mode 100644 index 0000000..7575812 --- /dev/null +++ b/Videos/Redaction/README.md @@ -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 +``` diff --git a/Videos/Redaction/eslint.config.js b/Videos/Redaction/eslint.config.js new file mode 100644 index 0000000..4fa125d --- /dev/null +++ b/Videos/Redaction/eslint.config.js @@ -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_]' }], + }, + }, +]) diff --git a/Videos/Redaction/index.html b/Videos/Redaction/index.html new file mode 100644 index 0000000..6223bfe --- /dev/null +++ b/Videos/Redaction/index.html @@ -0,0 +1,13 @@ + + + + + + + redaction + + +
+ + + diff --git a/Videos/Redaction/package.json b/Videos/Redaction/package.json new file mode 100644 index 0000000..be1ea6d --- /dev/null +++ b/Videos/Redaction/package.json @@ -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" + } +} diff --git a/Videos/Redaction/public/assets/pdf-succinctly.pdf b/Videos/Redaction/public/assets/pdf-succinctly.pdf new file mode 100644 index 0000000..d4e86b6 Binary files /dev/null and b/Videos/Redaction/public/assets/pdf-succinctly.pdf differ diff --git a/Videos/Redaction/public/assets/react.svg b/Videos/Redaction/public/assets/react.svg new file mode 100644 index 0000000..6c87de9 --- /dev/null +++ b/Videos/Redaction/public/assets/react.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/Videos/Redaction/public/assets/redaction.pdf b/Videos/Redaction/public/assets/redaction.pdf new file mode 100644 index 0000000..6086ffc Binary files /dev/null and b/Videos/Redaction/public/assets/redaction.pdf differ diff --git a/Videos/Redaction/public/vite.svg b/Videos/Redaction/public/vite.svg new file mode 100644 index 0000000..e7b8dfb --- /dev/null +++ b/Videos/Redaction/public/vite.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/Videos/Redaction/src/App.css b/Videos/Redaction/src/App.css new file mode 100644 index 0000000..b9d355d --- /dev/null +++ b/Videos/Redaction/src/App.css @@ -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; +} diff --git a/Videos/Redaction/src/App.jsx b/Videos/Redaction/src/App.jsx new file mode 100644 index 0000000..9a0c3fa --- /dev/null +++ b/Videos/Redaction/src/App.jsx @@ -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 ( +
+
+

React PDF Viewer

+
+ + + + + +
+
+
+ + + +
+
+ ); +} + +export default App; \ No newline at end of file diff --git a/Videos/Redaction/src/index.css b/Videos/Redaction/src/index.css new file mode 100644 index 0000000..8476fc2 --- /dev/null +++ b/Videos/Redaction/src/index.css @@ -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"; \ No newline at end of file diff --git a/Videos/Redaction/src/main.jsx b/Videos/Redaction/src/main.jsx new file mode 100644 index 0000000..b9a1a6d --- /dev/null +++ b/Videos/Redaction/src/main.jsx @@ -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( + + + , +) diff --git a/Videos/Redaction/vite.config.js b/Videos/Redaction/vite.config.js new file mode 100644 index 0000000..8b0f57b --- /dev/null +++ b/Videos/Redaction/vite.config.js @@ -0,0 +1,7 @@ +import { defineConfig } from 'vite' +import react from '@vitejs/plugin-react' + +// https://vite.dev/config/ +export default defineConfig({ + plugins: [react()], +})