npm package: @nxavis/pdf
Description: React PDF component library for NXAVIS - 30+ composable components, theme system, and templates built on @react-pdf/renderer
Author: NXAVIS
Latest version: 0.2.0

# @nxavis/pdf

React PDF component library — 30+ composable components, theme system, and templates built on `@react-pdf/renderer`.

## Install

```bash
pnpm add @nxavis/pdf @react-pdf/renderer react
```

## Quick Start

```tsx
import { Document, Page, pdf } from '@react-pdf/renderer';
import {
  PdfxThemeProvider,
  Heading,
  Text,
  Stack,
  Table,
  TableHeader,
  TableBody,
  TableRow,
  TableCell,
  professionalTheme,
} from '@nxavis/pdf';

function MyReport() {
  return (
    <Document>
      <Page size="A4" style={{ padding: 40 }}>
        <PdfxThemeProvider theme={professionalTheme}>
          <Heading level={1}>Monthly Report</Heading>
          <Text>Generated on {new Date().toLocaleDateString()}</Text>
          <Stack gap="md" direction="column">
            <Table>
              <TableHeader>
                <TableRow>
                  <TableCell>Item</TableCell>
                  <TableCell>Amount</TableCell>
                </TableRow>
              </TableHeader>
              <TableBody>
                <TableRow>
                  <TableCell>AWS</TableCell>
                  <TableCell>$1,234</TableCell>
                </TableRow>
              </TableBody>
            </Table>
          </Stack>
        </PdfxThemeProvider>
      </Page>
    </Document>
  );
}

// Generate PDF blob
const blob = await pdf(<MyReport />).toBlob();
```

## Components (30+)

| Category | Components |
|----------|-----------|
| Text | `Heading`, `Text`, `Link` |
| Layout | `Stack`, `Section`, `PageHeader`, `PageFooter` |
| Tables | `Table`, `DataTable`, `KeyValue` |
| Visual | `Badge`, `Card`, `Divider`, `Alert`, `PdfImage`, `Watermark` |
| Data | `PdfList`, `PdfGraph` (bar/line/area/pie/donut), `PdfQRCode` |
| Forms | `PdfForm`, `PdfSignatureBlock` |
| Utility | `PageBreak`, `PdfPageNumber`, `KeepTogether` |

## Templates

```tsx
import { InvoiceTemplate, ResumeTemplate } from '@nxavis/pdf';

// Invoice with 3 variants: classic, modern, minimal
<InvoiceTemplate variant="modern" company={...} client={...} items={...} />

// Resume with 3 variants: professional, modern, minimal
<ResumeTemplate variant="professional" personal={...} experience={...} />
```

## Tailwind CSS

`tw()` 유틸로 Tailwind 클래스를 react-pdf 스타일로 변환합니다. 테마 색상이 자동 매핑됩니다.

```tsx
import { Document, Page, View, Text } from '@react-pdf/renderer';
import { tw } from '@nxavis/pdf';

function Report() {
  return (
    <Document>
      <Page size="A4" style={tw("p-12 font-body")}>
        <View style={tw("flex-row justify-between items-center mb-8")}>
          <Text style={tw("text-3xl font-bold text-primary")}>NXAVIS</Text>
          <Text style={tw("text-sm text-muted-foreground")}>2026-03-17</Text>
        </View>

        <View style={tw("p-6 bg-muted rounded-lg mb-4")}>
          <Text style={tw("text-lg font-bold mb-2")}>Monthly Summary</Text>
          <Text style={tw("text-foreground")}>Total: $12,345.00</Text>
        </View>

        <View style={tw("flex-row gap-4")}>
          <View style={tw("flex-1 p-4 border border-border rounded")}>
            <Text style={tw("text-xs text-muted-foreground")}>AWS</Text>
            <Text style={tw("text-xl font-bold text-info")}>$8,200</Text>
          </View>
          <View style={tw("flex-1 p-4 border border-border rounded")}>
            <Text style={tw("text-xs text-muted-foreground")}>GCP</Text>
            <Text style={tw("text-xl font-bold text-success")}>$4,145</Text>
          </View>
        </View>
      </Page>
    </Document>
  );
}
```

### Custom Theme Tailwind

```tsx
import { createThemeTw, modernTheme } from '@nxavis/pdf';

// modernTheme 색상이 매핑된 tw()
const tw = createThemeTw(modernTheme);

<Text style={tw("text-primary font-heading text-2xl")}>Modern Style</Text>
```

### 사용 가능한 테마 색상 클래스

| 클래스 | 테마 토큰 |
|--------|----------|
| `text-foreground`, `bg-foreground` | colors.foreground |
| `text-background`, `bg-background` | colors.background |
| `text-muted`, `bg-muted` | colors.muted |
| `text-muted-foreground` | colors.mutedForeground |
| `text-primary`, `bg-primary` | colors.primary |
| `text-primary-foreground` | colors.primaryForeground |
| `border-border` | colors.border |
| `text-accent`, `bg-accent` | colors.accent |
| `text-destructive` | colors.destructive |
| `text-success` | colors.success |
| `text-warning` | colors.warning |
| `text-info` | colors.info |
| `font-body` | typography.body.fontFamily |
| `font-heading` | typography.heading.fontFamily |

### 컴포넌트 + Tailwind 혼합

```tsx
// 컴포넌트의 style prop에 tw() 전달 가능
<Heading level={2} style={tw("mb-8 text-primary")}>Section Title</Heading>
<Badge variant="success" style={tw("mr-2")}>Active</Badge>
<Stack gap="md" style={tw("p-4 bg-muted rounded-lg")}>
  <Text>Content</Text>
</Stack>
```

## Theme System

Three built-in presets + custom themes:

```tsx
import { professionalTheme, modernTheme, minimalTheme } from '@nxavis/pdf/themes';

// Or create custom
const customTheme = {
  ...professionalTheme,
  colors: { ...professionalTheme.colors, primary: '#0066cc' },
};
```

## License

MIT