Instruction file imported from Nizoka/pdfnative-react (
.github/instructions/components.instructions.md). Copyright stays with the author.
Component instructions
components.tsx is the public, declarative API. Each component is a thin,
side-effect-free factory that emits a lowercase host tag via the typed
h(tag, props, children) wrapper (the tags are not DOM intrinsics).
- Map each component 1:1 onto a
pdfnativeblock. Do NOT invent layout primitives (no<View>, no flexbox, no CSS props). The one exception isSection— a composite that returns aFragmentof<Heading>+ children (optionally a leading<PageBreak>); it emits no host tag, so it needs nonodes.ts/serialize.tscase. - Props flow straight through to
serialize.ts; keep prop names aligned with the pdfnative block fields (seedocs/KNOWLEDGE_BASE.md§5 and the block interfaces re-exported frompdfnative). - Container components (
Document,Heading,Paragraph,List,Table,Row,Link) destructurechildrenout of the rest props before forwarding. - Keep aliases intentional:
Text = Paragraph,Toc = TableOfContents. - Every exported component and its props interface needs a TSDoc comment.
When you add a component:
reconciler/nodes.ts— add the host tag.reconciler/serialize.ts— add thecaseintoBlock. Compiler-enforced: a missing case failsnpm run typecheckon theconst exhaustive: neverguard.src/registry.ts— add theCOMPONENT_REGISTRYentry. Compiler-enforced:ComponentRegistryIsExhaustivefails typecheck if aHostTaghas no component.src/index.ts— export the component and its props type.tests/compile.test.tsx— a serialization test, plus the ordered list intests/registry.test.ts.- If it adds authoring capability, mirror it in the
DocSpecgrammar + schema (src/spec/) — seespec.instructions.mdfor that checklist — and refreshtests/compile-snapshot.test.tsxdeliberately, reading the diff.
Composites like Section skip steps 1–3: they emit no host tag, and
COMPONENT_REGISTRY records them with tag: null. A test asserts Section is
the only one.
Client-side components (PDFViewer, PDFDownloadLink, BlobProvider) go in
CLIENT_COMPONENT_REGISTRY instead, and must be re-exported from
src/client.ts so they reach the pdfnative-react/client subpath.