Skip to content
Merged
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 Navigation/.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?
116 changes: 116 additions & 0 deletions Navigation/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
# React PDF Viewer Sample

A React + TypeScript proof-of-concept that demonstrates **programmatic navigation** in a PDF using the [Syncfusion React PDF Viewer](https://www.syncfusion.com/pdf-viewer-sdk/react-pdf-viewer) component. The app loads a sample PDF from Syncfusion's CDN and exposes a custom control panel for jumping between pages, navigating to bookmarks, and running text searches.

---

## ✨ Features

| Capability | How it works |
|---|---|
| **Page navigation** | Go to previous / next page, or jump to a specific page number. |
| **Bookmark navigation** | Retrieve all PDF bookmarks, open / close the bookmark panel, and jump to a selected destination. |
| **Text search** | Search the document for a term (with optional match-case), then move to the next or previous result. |
| **Zoom controls** | Fit to page, fit to width, zoom in, and zoom out. |

---

## 📋 Prerequisites

Make sure the following are installed on your machine:

- [Node.js](https://nodejs.org/) (LTS recommended)
- [npm](https://www.npmjs.com/) (bundled with Node.js)

> Verify your environment:
> ```bash
> node --version
> npm --version
> ```

---

## 🚀 Getting started

### 1. Install dependencies

```bash
npm install
```

### 2. Run the development server

```bash
npm run dev
```

Vite will print a local URL (usually `http://localhost:5173`). Open it in your browser to see the PDF viewer.

### 3. Build for production

```bash
npm run build
```

The optimized output is written to the `dist/` folder.

### 4. Preview the production build locally

```bash
npm run preview
```

## 🧩 Project structure

```
pdf-viewer-app/
├── index.html # Vite entry HTML
├── package.json # Scripts and dependencies
├── vite.config.ts # Vite configuration
├── tsconfig*.json # TypeScript configuration
├── public/ # Static assets served as-is
└── src/
├── main.tsx # React root bootstrap (StrictMode)
├── App.tsx # PDF viewer + custom control panel
├── App.css # Layout and styling for the control grid
├── index.css # Global styles
└── assets/ # Local assets
```

---

## 🔍 How the sample works

1. **`src/main.tsx`** mounts the React app inside `#root` using `StrictMode`.
2. **`src/App.tsx`** renders the `PdfViewerComponent` from `@syncfusion/ej2-react-pdfviewer` and wires up:
- A custom **control grid** with page, bookmark, search, and zoom controls.
- A **status banner** that reflects the latest action (e.g. *"5 bookmarks retrieved"*).
- **Event handlers** for `documentLoad`, `pageChange`, and `documentLoadFailed`.

### Key Syncfusion APIs demonstrated

| API | Purpose |
|---|---|
| `viewer.navigation.goToPage(n)` | Jump to a specific page |
| `viewer.navigation.goToNextPage()` / `goToPreviousPage()` | Step through pages |
| `viewer.bookmark.getBookmarks()` | Retrieve the bookmark tree |
| `viewer.bookmark.goToBookmark(pageIndex, y)` | Jump to a bookmark destination |
| `viewer.bookmark.openBookmarkPane()` / `closeBookmarkPane()` | Toggle the bookmark panel |
| `viewer.textSearch.searchText(term, isMatchCase)` | Run a text search |
| `viewer.textSearch.searchNext()` / `searchPrevious()` | Move between matches |
| `viewer.magnification.fitToPage()` / `fitToWidth()` / `zoomIn()` / `zoomOut()` | Adjust the view |

The sample PDF and viewer resources are loaded from Syncfusion's public CDN:

```ts
const SAMPLE_PDF = 'https://cdn.syncfusion.com/content/pdf/pdf-succinctly.pdf';
const RESOURCE_URL = 'https://cdn.syncfusion.com/ej2/34.2.3/dist/ej2-pdfviewer-lib';
```

---

## 🔗 Useful links

- [Syncfusion React PDF Viewer — Overview](https://help.syncfusion.com/document-processing/pdf/pdf-viewer/react/overview)
- [Syncfusion React PDF Viewer — API reference](https://ej2.syncfusion.com/react/documentation/api/pdfviewer)

22 changes: 22 additions & 0 deletions Navigation/eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import js from '@eslint/js'
import globals from 'globals'
import reactHooks from 'eslint-plugin-react-hooks'
import reactRefresh from 'eslint-plugin-react-refresh'
import tseslint from 'typescript-eslint'
import { defineConfig, globalIgnores } from 'eslint/config'

export default defineConfig([
globalIgnores(['dist']),
{
files: ['**/*.{ts,tsx}'],
extends: [
js.configs.recommended,
tseslint.configs.recommended,
reactHooks.configs.flat.recommended,
reactRefresh.configs.vite,
],
languageOptions: {
globals: globals.browser,
},
},
])
13 changes: 13 additions & 0 deletions Navigation/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="/favicon.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>pdf-viewer-app</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
31 changes: 31 additions & 0 deletions Navigation/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"name": "pdf-viewer-app",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "tsc -b && vite build",
"lint": "eslint .",
"preview": "vite preview"
},
"dependencies": {
"@syncfusion/ej2-react-pdfviewer": "^34.2.4",
"react": "^19.2.8",
"react-dom": "^19.2.8"
},
"devDependencies": {
"@eslint/js": "^10.0.1",
"@types/node": "^24.13.3",
"@types/react": "^19.2.17",
"@types/react-dom": "^19.2.3",
"@vitejs/plugin-react": "^6.0.4",
"eslint": "^10.8.0",
"eslint-plugin-react-hooks": "^7.1.1",
"eslint-plugin-react-refresh": "^0.5.3",
"globals": "^17.7.0",
"typescript": "~6.0.2",
"typescript-eslint": "^8.65.0",
"vite": "^8.2.0"
}
}
1 change: 1 addition & 0 deletions Navigation/public/favicon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading