npm package: @oxog/printkit
Description: Zero-dependency print management toolkit with preview modal and PDF export capabilities
Author: Ersin KOC
Latest version: 1.0.0

# PrintKit

<div align="center">
  <h3>Zero-dependency print management toolkit for web applications</h3>
  <p>Print preview, PDF export, and React integration - all in one tiny package</p>
</div>

<div align="center">

[![npm version](https://img.shields.io/npm/v/@oxog/printkit.svg)](https://www.npmjs.com/package/@oxog/printkit)
[![bundle size](https://img.shields.io/bundlephobia/minzip/@oxog/printkit)](https://bundlephobia.com/package/@oxog/printkit)
[![license](https://img.shields.io/npm/l/@oxog/printkit.svg)](LICENSE)
[![TypeScript](https://img.shields.io/badge/TypeScript-Ready-blue.svg)](https://www.typescriptlang.org/)

</div>

---

## Features

| Feature | Description |
|---------|-------------|
| **Print Anything** | Elements, HTML strings, URLs, images, JSON, tables |
| **Print Preview** | Modal with zoom, navigation, and keyboard shortcuts |
| **PDF Export** | Download, Blob, Base64, Data URL - no external deps |
| **Page Layouts** | A3, A4, A5, Letter, Legal, Tabloid, custom sizes |
| **Headers/Footers** | Template strings with `{page}`, `{pages}`, `{title}`, `{date}` |
| **Page Breaks** | CSS classes and programmatic control |
| **Print Queue** | Batch printing with priority and retry |
| **React Integration** | Hooks (`usePrint`, `usePDF`) and Components |
| **Zero Dependencies** | No runtime dependencies |
| **Tiny Bundle** | < 40KB minified |

## Installation

```bash
npm install @oxog/printkit
```

## Quick Start

### Basic Printing

```typescript
import { createPrinter } from '@oxog/printkit'

const printer = createPrinter()

// Print an element
await printer.print('#invoice')

// Print with options
await printer.print('#report', {
  title: 'Sales Report',
  pageSize: 'A4',
  orientation: 'landscape',
  header: 'Confidential',
  footer: 'Page {page} of {pages}'
})
```

### Print Preview

```typescript
import { createPrintPreview } from '@oxog/printkit'

const preview = createPrintPreview('#content', {
  pageSize: 'A4',
  modal: { zoom: 75 }
})

preview.open()      // Open preview modal
preview.zoomIn()    // Zoom controls
preview.print()     // Print from preview
preview.download()  // Download as PDF
preview.close()     // Close modal
```

### PDF Export

```typescript
import { createPDFExporter } from '@oxog/printkit'

const pdf = createPDFExporter()

// Download as PDF file
await pdf.download('#content', 'document.pdf')

// Get as Blob (for upload, etc.)
const blob = await pdf.toBlob('#content')

// Get as Base64
const base64 = await pdf.toBase64('#content')

// Get as Data URL
const dataUrl = await pdf.toDataURL('#content')
```

## React Integration

```tsx
import { 
  PrintProvider, 
  usePrint, 
  usePDF,
  PrintButton,
  Printable,
  PageBreak,
  NoPrint,
  PrintOnly
} from '@oxog/printkit/react'

function App() {
  return (
    <PrintProvider defaultOptions={{ pageSize: 'A4' }}>
      <Invoice />
    </PrintProvider>
  )
}

function Invoice() {
  const { print, isPrinting } = usePrint()
  const { download, isExporting } = usePDF()
  const contentRef = useRef(null)

  return (
    <div>
      <NoPrint>
        <button onClick={() => print(contentRef.current)}>
          {isPrinting ? 'Printing...' : 'Print'}
        </button>
        <button onClick={() => download(contentRef.current, 'invoice.pdf')}>
          {isExporting ? 'Exporting...' : 'Download PDF'}
        </button>
      </NoPrint>

      <Printable ref={contentRef}>
        <h1>Invoice #12345</h1>
        <p>Content here...</p>
        
        <PageBreak />
        
        <h2>Page 2</h2>
        <p>More content...</p>
        
        <PrintOnly>
          <p>Printed on: {new Date().toLocaleDateString()}</p>
        </PrintOnly>
      </Printable>
    </div>
  )
}
```

### React Hooks

| Hook | Description |
|------|-------------|
| `usePrint()` | Print with loading/error states |
| `usePDF()` | PDF export with progress tracking |
| `usePrintPreview()` | Control preview modal |
| `usePrintContext()` | Access global print options |

### React Components

| Component | Description |
|-----------|-------------|
| `<PrintProvider>` | Context provider for global options |
| `<Printable>` | Wrapper with ref-based print control |
| `<PrintButton>` | Customizable print trigger |
| `<PrintPreview>` | Preview modal component |
| `<PageBreak>` | Insert page break |
| `<NoPrint>` | Hide content when printing |
| `<PrintOnly>` | Show only when printing |

## Print Methods

```typescript
const printer = createPrinter()

// Print element by selector or reference
await printer.print('#content')
await printer.print(document.getElementById('content'))

// Print HTML string
await printer.printHTML('<h1>Hello World</h1>')

// Print from URL
await printer.printURL('/report.html')

// Print image
await printer.printImage('/chart.png')
await printer.printImages(['/chart1.png', '/chart2.png'])

// Print JSON with syntax highlighting
await printer.printJSON({ user: 'John', age: 30 }, { 
  syntaxHighlight: true 
})

// Print table
await printer.printTable({
  headers: ['Name', 'Email', 'Role'],
  rows: [
    ['John Doe', 'john@example.com', 'Admin'],
    ['Jane Smith', 'jane@example.com', 'User']
  ]
})
```

## Print Queue

```typescript
import { createPrintQueue } from '@oxog/printkit'

const queue = createPrintQueue({ concurrency: 1 })

// Add jobs
queue.add({ content: '#invoice1', priority: 'high' })
queue.add({ content: '#invoice2', priority: 'normal' })
queue.add({ content: '#invoice3', priority: 'low' })

// Event listeners
queue.on('jobStart', (job) => console.log('Started:', job.id))
queue.on('jobComplete', (job) => console.log('Done:', job.id))
queue.on('jobError', (job, error) => console.error('Failed:', error))

// Process queue
await queue.printAll()

// Or process one by one
await queue.printNext()
```

## Configuration Options

```typescript
interface PrintOptions {
  // Document
  title?: string
  pageSize?: 'A3' | 'A4' | 'A5' | 'Letter' | 'Legal' | 'Tabloid' | { width, height }
  orientation?: 'portrait' | 'landscape'
  
  // Margins (number = mm, or use '1in', '2cm', etc.)
  margin?: number | { top, right, bottom, left }
  
  // Header/Footer (string or function)
  header?: string | ((info: PageInfo) => string)
  footer?: string | ((info: PageInfo) => string)
  // Placeholders: {page}, {pages}, {title}, {date}, {time}
  
  // Styling
  styles?: string | string[]      // Custom CSS
  styleSheets?: string[]          // External stylesheets
  copyStyles?: boolean            // Copy page styles (default: true)
  printBackground?: boolean       // Print backgrounds (default: true)
  
  // Page breaks (CSS selectors)
  pageBreakBefore?: string        // e.g., '.chapter'
  pageBreakAfter?: string         // e.g., '.section-end'
  avoidBreakInside?: string       // e.g., '.card, table'
  
  // Callbacks
  onBeforePrint?: () => void | Promise<void>
  onAfterPrint?: () => void
  onError?: (error: PrintError) => void
  onProgress?: (percent: number) => void  // PDF export only
}
```

## CSS Classes

PrintKit provides utility classes for print control:

```html
<!-- Hide when printing -->
<nav class="print-hide">Navigation</nav>

<!-- Show only when printing -->
<div class="print-only">Printed on: 2024-01-01</div>

<!-- Page breaks -->
<div class="print-break-before">Starts on new page</div>
<div class="print-break-after">Next content on new page</div>
<div class="print-avoid-break">Keep together on same page</div>
```

## Utility Functions

```typescript
import {
  // Detection
  isPrintSupported,
  isPDFSupported,
  isBrowser,
  
  // Page breaks
  pageBreak,           // Create page break element
  avoidBreak,          // Mark element to avoid breaks
  breakBefore,         // Mark element to break before
  breakAfter,          // Mark element to break after
  
  // Page dimensions
  getPageDimensions,
  getPagePixelDimensions,
  
  // Style injection
  injectPrintStyles,
  removePrintStyles,
  removeAllPrintStyles,
  
  // Constants
  PAGE_SIZES,          // { A4: {...}, Letter: {...}, ... }
  PRINT_HIDE_CLASS,    // 'print-hide'
  PRINT_ONLY_CLASS,    // 'print-only'
} from '@oxog/printkit'
```

## Browser Support

| Browser | Version |
|---------|---------|
| Chrome | 80+ |
| Firefox | 75+ |
| Safari | 13.1+ |
| Edge | 80+ |

## TypeScript

PrintKit is written in TypeScript and provides full type definitions:

```typescript
import type {
  PrintOptions,
  PDFOptions,
  PreviewOptions,
  PrintTarget,
  PageSize,
  Orientation,
  Printer,
  PDFExporter,
  PrintQueue,
  PrintJob,
} from '@oxog/printkit'
```

## Documentation

For detailed documentation, visit [printkit.oxog.dev](https://printkit.oxog.dev)

- [Getting Started](https://printkit.oxog.dev/docs/getting-started)
- [API Reference](https://printkit.oxog.dev/docs/api)
- [Examples](https://printkit.oxog.dev/examples)
- [React Guide](https://printkit.oxog.dev/docs/react)

## Contributing

Contributions are welcome! Please read [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.

## License

MIT - see [LICENSE](LICENSE) for details.

---

<div align="center">
  Made with care by <a href="https://github.com/ersinkoc">Ersin KOC</a>
</div>