npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@abduljebar/pdf-reader

v1.0.5

Published

A modern, feature-rich PDF viewer component built with React, TypeScript, and Vite. This library provides a responsive PDF viewing experience with extensive customization options.

Readme

React PDF Viewer Library

A modern, feature-rich PDF viewer component built with React, TypeScript, and Vite. This library provides a responsive PDF viewing experience with extensive customization options.

✨ Features

📱 Responsive Design

  • Mobile-first approach with adaptive layouts
  • Touch-friendly controls with gesture support
  • Optimized for all screen sizes (mobile, tablet, desktop)
  • Bottom-sheet navigation on mobile devices

🎨 Customization

  • Configurable toolbar with toggle options
  • Multiple view modes (vertical, horizontal, single page)
  • Custom sidebar panels (thumbnails, outline, annotations)
  • Theme support (light, dark, system)
  • Custom CSS classes for styling

🔧 Core Features

  • High-performance PDF rendering with pdf.js
  • Zoom controls (in/out, fit to width, fit to page)
  • Page navigation with keyboard shortcuts
  • Search functionality
  • Print and download support
  • File upload with drag & drop
  • Smooth scrolling and transitions

🎯 UI/UX Enhancements

  • Smooth animations and transitions
  • Loading states with skeleton screens
  • Error handling with recovery options
  • Accessible with ARIA labels
  • Keyboard navigation support
  • Touch gesture support

📦 Installation

npm install @your-library/pdf-viewer
# or
yarn add @your-library/pdf-viewer

🚀 Quick Start

import { PDFViewer } from '@your-library/pdf-viewer';
import '@your-library/pdf-viewer/dist/style.css';

function App() {
  return (
    <div style={{ height: '100vh' }}>
      <PDFViewer
        pdfUrl="/document.pdf"
        config={{
          enableDarkMode: true,
          enableZoom: true,
          enablePageNavigation: true,
          defaultZoom: 1,
          defaultScrollMode: 'vertical',
          showThumbnails: true,
          showOutline: true,
        }}
        theme="system"
        onPageChange={(page) => console.log('Page:', page)}
        onZoomChange={(zoom) => console.log('Zoom:', zoom)}
      />
    </div>
  );
}

📖 Documentation

Basic Usage

import { PDFViewer } from '@your-library/pdf-viewer';

function MyPDFViewer() {
  return (
    <PDFViewer
      pdfUrl="https://example.com/document.pdf"
      config={{
        enableDarkMode: true,
        enableZoom: true,
        enablePageNavigation: true,
      }}
    />
  );
}

With File Upload

function PDFUploadViewer() {
  const [file, setFile] = useState<File | null>(null);

  return (
    <PDFViewer
      file={file}
      config={{
        enableFileUpload: true,
      }}
      onFileSelect={(selectedFile) => {
        setFile(selectedFile);
        console.log('File selected:', selectedFile.name);
      }}
    />
  );
}

Advanced Configuration

<PDFViewer
  pdfUrl="/document.pdf"
  config={{
    // Feature toggles
    enableDarkMode: true,
    enableZoom: true,
    enablePageNavigation: true,
    enableViewModeToggle: true,
    enableFileUpload: true,
    enableSearch: true,
    enablePrint: true,
    enableDownload: true,
    
    // Display options
    defaultZoom: 1,
    minZoom: 0.25,
    maxZoom: 3,
    defaultScrollMode: 'vertical',
    showThumbnails: true,
    showOutline: true,
    showAnnotations: false,
    pageGap: 40,
    
    // UI/UX options
    enableKeyboardNavigation: true,
    enableSmoothScrolling: true,
    showPageNumbers: true,
    showDocumentTitle: true,
  }}
  
  // Layout
  showSidebar={true}
  sidebarWidth={280}
  sidebarPosition="left"
  
  // Theme
  theme="system"
  
  // Callbacks
  onLoad={(pdfDoc) => console.log('PDF loaded:', pdfDoc)}
  onError={(error) => console.error('Error:', error)}
  onPageChange={(page) => console.log('Page changed:', page)}
  onZoomChange={(zoom) => console.log('Zoom changed:', zoom)}
  
  // Custom components
  customToolbar={<MyCustomToolbar />}
  customSidebar={<MyCustomSidebar />}
  customLoadingComponent={<MyLoadingSpinner />}
/>

🏗️ Component Architecture

src/
├── components/
│   ├── PDFViewer/
│   │   ├── PDFViewer.tsx          # Main component
│   │   ├── Sidebar.tsx            # Responsive sidebar
│   │   ├── PDFDocument.tsx        # PDF rendering
│   │   ├── ThumbnailsPanel.tsx    # Page thumbnails
│   │   ├── OutlinePanel.tsx       # Document outline
│   │   └── AnnotationsPanel.tsx   # Comments & highlights
│   │
│   └── Toolbar/
│       ├── Toolbar.tsx            # Main toolbar
│       ├── ZoomControls.tsx       # Zoom functionality
│       ├── PageControls.tsx       # Page navigation
│       ├── ViewModeToggle.tsx     # View mode switcher
│       ├── DarkModeToggle.tsx     # Theme toggle
│       ├── FileUpload.tsx         # File upload
│       └── ResponsiveDropdown.tsx # Mobile dropdown
│
├── hooks/
│   └── useMediaQuery.ts           # Responsive hooks
│
├── types/
│   └── index.ts                   # TypeScript definitions
│
└── utils/
    └── pdfWorker.ts              # PDF.js setup

🎨 Styling

The library uses Tailwind CSS for styling. You can customize the appearance by:

  1. Overriding CSS variables:
:root {
  --pdf-primary: #2563eb;
  --pdf-secondary: #64748b;
  --pdf-background: #ffffff;
  --pdf-foreground: #1f2937;
}
  1. Using custom classes:
<PDFViewer
  className="my-custom-class"
  toolbarClassName="my-toolbar-class"
  sidebarClassName="my-sidebar-class"
  documentClassName="my-document-class"
/>
  1. Extending Tailwind config:
// tailwind.config.js
module.exports = {
  theme: {
    extend: {
      colors: {
        'pdf-primary': '#2563eb',
        'pdf-secondary': '#64748b',
      },
    },
  },
}

📱 Responsive Breakpoints

| Device | Breakpoint | Features | |--------|------------|----------| | Mobile | < 768px | Bottom navigation, simplified controls, touch gestures | | Tablet | 768px - 1024px | Condensed toolbar, medium sidebar | | Desktop | > 1024px | Full toolbar, full sidebar, all features |

🎯 Performance

  • Lazy loading: Components load on demand
  • Virtual scrolling: Only visible pages are rendered
  • Image optimization: Thumbnails use appropriate resolutions
  • Memory management: Proper cleanup of resources
  • Bundle optimization: Code splitting for faster loads

🔧 Development

Prerequisites

  • Node.js 18+
  • npm, yarn, or pnpm

Setup

# Clone the repository
git clone <repository-url>
cd pdf-viewer-library

# Install dependencies
npm install

# Start development server
npm run dev

# Build for production
npm run build

# Run tests
npm test

# Lint code
npm run lint

# Type checking
npm run type-check

Project Structure

.
├── src/                    # Source code
├── dist/                   # Built files
├── examples/               # Usage examples
├── tests/                  # Test files
├── docs/                   # Documentation
└── package.json

Building for Distribution

# Build library
npm run build:lib

# Build documentation
npm run build:docs

# Publish to npm
npm publish

🧪 Testing

# Run all tests
npm test

# Run tests in watch mode
npm run test:watch

# Run tests with coverage
npm run test:coverage

# Run E2E tests
npm run test:e2e

📄 API Reference

PDFViewer Props

| Prop | Type | Default | Description | |------|------|---------|-------------| | pdfUrl | string | - | URL of the PDF to load | | file | File | - | PDF file object | | config | PDFViewerConfig | {} | Configuration object | | theme | 'light' | 'dark' | 'system' | 'system' | Theme mode | | showSidebar | boolean | true | Show/hide sidebar | | sidebarWidth | number | 240 | Sidebar width in pixels | | sidebarPosition | 'left' | 'right' | 'left' | Sidebar position | | onLoad | function | - | Called when PDF loads | | onError | function | - | Called on error | | onPageChange | function | - | Called when page changes | | onZoomChange | function | - | Called when zoom changes |

PDFViewerConfig

interface PDFViewerConfig {
  // Feature toggles
  enableDarkMode?: boolean;
  enableZoom?: boolean;
  enablePageNavigation?: boolean;
  enableViewModeToggle?: boolean;
  enableFileUpload?: boolean;
  enableSearch?: boolean;
  enablePrint?: boolean;
  enableDownload?: boolean;
  
  // Display options
  defaultZoom?: number;
  minZoom?: number;
  maxZoom?: number;
  defaultScrollMode?: ScrollMode;
  showThumbnails?: boolean;
  showOutline?: boolean;
  showAnnotations?: boolean;
  pageGap?: number;
  
  // UI/UX options
  enableKeyboardNavigation?: boolean;
  enableSmoothScrolling?: boolean;
  showPageNumbers?: boolean;
  showDocumentTitle?: boolean;
  
  // Customization
  className?: string;
  toolbarClassName?: string;
  sidebarClassName?: string;
  documentClassName?: string;
}

🤝 Contributing

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

Development Guidelines

  • Follow TypeScript best practices
  • Write comprehensive tests
  • Document new features
  • Update README when necessary
  • Follow the existing code style

📄 License

This project is licensed under the MIT License - see the LICENSE file for details.

🙏 Acknowledgments

📞 Support

🚀 Roadmap

  • [ ] Text selection and copying
  • [ ] Annotation creation and editing
  • [ ] Form filling support
  • [ ] PDF/A compliance
  • [ ] Multi-language support
  • [ ] Plugin system
  • [ ] Offline support
  • [ ] Cloud storage integration

Made with ❤️ by Abduljebar Sani