@pdf-block/react
v1.2.0
Published
A visual, drag-and-drop PDF document builder for React. Renders a full WYSIWYG editor with inline styles, ready for server-side PDF generation.
Maintainers
Readme
@pdf-block/react
Editor visual WYSIWYG de documentos PDF para React. Drag-and-drop, rich text, estilos inline — tudo pronto para gerar PDFs nativos server-side.
Instalação
npm install @pdf-block/react
# ou
pnpm add @pdf-block/reactPeer dependencies:
npm install react react-domInício rápido
import { PDFBuilder } from '@pdf-block/react';
import '@pdf-block/react/styles';
import type { Document } from '@pdf-block/react';
function App() {
const handleChange = (doc: Document) => {
console.log('Document changed:', doc);
};
return (
<div style={{ width: '100vw', height: '100vh' }}>
<PDFBuilder
config={{ locale: 'pt-BR', minimap: true }}
callbacks={{ onDocumentChange: handleChange }}
/>
</div>
);
}Componente principal
<PDFBuilder />
O componente raiz que renderiza o editor completo.
| Prop | Tipo | Descrição |
|---|---|---|
| initialDocument | Document | Documento inicial (opcional — cria um vazio se omitido) |
| config | PDFBuilderConfig | Configuração do editor |
| callbacks | PDFBuilderCallbacks | Callbacks de eventos |
| ref | PDFBuilderRef | Ref para controle programático |
Config
interface PDFBuilderConfig {
locale?: 'pt-BR' | 'en'; // Idioma da interface
minimap?: boolean; // Minimap ativo (default: true)
minimapConfig?: MinimapConfig; // Posição e modo do minimap
theme?: Theme; // 'light' (default)
}Callbacks
interface PDFBuilderCallbacks {
onDocumentChange?: (doc: Document) => void; // Toda alteração
onSave?: (doc: Document) => void; // Ctrl+S / botão salvar
onExport?: (blob: Blob) => void; // Após exportar PDF
}Ref
interface PDFBuilderRef {
getDocument: () => Document;
setDocument: (doc: Document) => void;
exportPDF: () => Promise<Blob>;
}Hooks públicos
useDocument()
Acesso reativo ao documento e funções de manipulação.
const {
document, // Document completo
pageSettings, // PageSettings
globalStyles, // GlobalStyles
updatePageSettings, // (partial: Partial<PageSettings>) => void
updateGlobalStyles, // (partial: Partial<GlobalStyles>) => void
} = useDocument();useEditor()
Controle da UI do editor e operações em blocos.
const {
viewMode, // 'desktop'
sidebarPanel, // SidebarPanel | null
blocks, // StripeBlock[]
addStripe, // () => void
removeStripe, // (id: string) => void
addContentBlock, // (stripeId, structureId, columnId, type, index?) => void
undo, redo, // () => void
canUndo, canRedo, // boolean
} = useEditor();useSelection()
Estado de seleção atual.
const {
selectedBlockId, // string | null
selectedBlock, // AnyBlock | null
selectedStripe, // StripeBlock | null
path, // string[] (caminho hierárquico)
} = useSelection();useExport()
Exportação para PDF e impressão.
const {
exportPDF, // () => Promise<Blob>
downloadPDF, // (filename?: string) => Promise<void>
print, // () => void
isExporting, // boolean
} = useExport();DSL — Estrutura do documento
O documento segue uma hierarquia rigorosa:
Document
├── meta: { title, description, locale, tags }
├── pageSettings: { paperSize, orientation, margins, defaultFontFamily }
├── globalStyles: { pageBackground, contentBackground, defaultFontColor }
└── blocks: StripeBlock[]
└── children: StructureBlock[]
└── columns: Column[]
└── children: ContentBlock[]
├── TextBlock (rich text via TipTap)
├── ImageBlock (src, alt, objectFit, alignment)
├── ButtonBlock (text, url, target, cores)
├── DividerBlock (estilo de linha, espessura, cor)
├── SpacerBlock (altura em px)
├── BannerBlock (imagem de fundo, overlay, textos)
├── TableBlock (linhas, header, zebra, bordas)
├── QRCodeBlock (data, tamanho, cores)
├── ChartBlock (bar/line/pie, dados)
└── PageBreakBlock (forçar quebra de página)Todos os blocos compartilham:
interface BaseBlock {
id: string;
type: BlockType;
meta: BlockMeta; // hideOnExport, locked, breakBefore, breakAfter
styles: BlockStyles; // padding, margin, border, borderRadius, background, shadow, opacity
}Exportação para PDF
Client-side (imagem)
O pacote inclui exportação client-side via html2canvas + jsPDF:
import { useExport } from '@pdf-block/react';
const { downloadPDF } = useExport();
await downloadPDF('meu-documento.pdf');Server-side (nativo) — Recomendado
Para PDFs nativos com texto selecionável e links clicáveis, use o pacote companion pdf-block/laravel:
const doc = editorRef.current.getDocument();
const response = await fetch('/api/export/pdf', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ document: doc }),
});
const blob = await response.blob();Veja a documentação do pacote Laravel para detalhes.
Persistência
O pacote não persiste dados — essa responsabilidade é da aplicação consumidora. Use o callback onDocumentChange para salvar:
<PDFBuilder
initialDocument={loadFromDB()}
callbacks={{
onDocumentChange: (doc) => saveToAPI(doc),
onSave: (doc) => saveToAPI(doc),
}}
/>O documento é um JSON serializável — salve como jsonb no banco, no localStorage, ou em um arquivo.
Internacionalização
import { setLocale, getAvailableLocales } from '@pdf-block/react';
setLocale('en'); // Muda para inglês
getAvailableLocales(); // ['pt-BR', 'en']
// Ou via config:
<PDFBuilder config={{ locale: 'en' }} />Tipos exportados
Todos os tipos da DSL são exportados para uso em TypeScript:
import type {
Document, StripeBlock, StructureBlock, ContentBlock,
TextBlock, ImageBlock, ButtonBlock, DividerBlock,
SpacerBlock, BannerBlock, TableBlock, QRCodeBlock,
ChartBlock, PageBreakBlock, BlockStyles, BlockMeta,
PageSettings, GlobalStyles, PaperSize, EdgeValues,
} from '@pdf-block/react';Desenvolvimento
# No monorepo root
pnpm install
pnpm dev # Sobe o playground na porta 3000
# Build do pacote
pnpm build:react # Gera dist/ com ES + CJS + tipos
# Testes
pnpm test:reactRequisitos
- React ≥ 18.2
- Navegador moderno (Chrome, Firefox, Safari, Edge)
Licença
MIT
