JSPM

  • Created
  • Published
  • Downloads 42331
  • Score
    100M100P100Q145094F
  • License MIT

Html component for react-pdf with CSS support

Package Exports

  • react-pdf-html
  • react-pdf-html/dist/index.js

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (react-pdf-html) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

react-pdf-html

<Html> component for react-pdf

  • Support for CSS via <style> tags and style attributes (limited to Style properties supported by react-pdf)
  • Browser CSS defaults with option for style reset
  • Basic <table>(attempted using flex layouts) <ul> and <ol> support
  • Ability to provide custom renderers for any tag

How it Works

  1. Parses the HTML string into a JSON tree of nodes using node-html-parser
  2. Parses any <style> tags in the document and style attributes using css-tree
  3. Renders all nodes using the appropriate react-pdf components, applying cascading styles for each node as an array passed to the style prop:
    • block/container nodes using <View>
    • inline/text nodes using <Text>, with appropriate nesting and collapsing of whitepace
    • <img> nodes using <Image>
    • <a> nodes using <Link>

Installation

npm i react-pdf-html

Usage

import Html from 'react-pdf-html';

const html = `<html>
  <body>
    <style>
      .my-heading4 {
        background: darkgreen;
        color: white;
      }
      pre {
        background-color: #eee;
        padding: 10px;
      }
    </style>
    <h1>Heading 1</h1>
    <h2 style="background-color: pink">Heading 2</h2>
    <h3>Heading 3</h3>
    <h4 class="my-heading4">Heading 4</h4>
    <p>
      Paragraph with <strong>bold</strong>, <i>italic</i>, <u>underline</u>,
      <s>strikethrough</s>,
      <strong><u><s><i>and all of the above</i></s></u></strong>
    </p>
    <p>
      Paragraph with image <img src="${myFile}" /> and
      <a href="http://google.com">link</a>
    </p>
    <hr />
    <ul>
      <li>Unordered item</li>
      <li>Unordered item</li>
    </ul>
    <ol>
      <li>Ordered item</li>
      <li>Ordered item</li>
    </ol>
    <br /><br /><br /><br /><br />
    Text outside of any tags
    <table>
      <thead>
        <tr>
          <th>Column 1</th>
          <th>Column 2</th>
          <th>Column 3</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>Foo</td>
          <td>Bar</td>
          <td>Foobar</td>
        </tr>
        <tr>
          <td colspan="2">Foo</td>
          <td>Bar</td>
        </tr>
        <tr>
          <td>Some longer thing</td>
          <td>Even more content than before!</td>
          <td>Even more content than before!</td>
        </tr>
      </tbody>
    </table>
    <div style="width: 200px; height: 200px; background: pink"></div>
    <pre>
function myCode() {
  const foo = 'bar';
}
</pre>
  </body>
</html>
`;

return (
  <Document>
    <Page>
      <Html>{html}</Html>
    </Page>
  </Document>
);

Rendering React Components

import ReactDOMServer from 'react-dom/server';

const element = (
  <html>
    <body>
      <style>
        {`
        .heading4 {
          background: darkgreen;
          color: white;
        }
        pre {
          background-color: #eee;
          padding: 10px;
        }`}
      </style>
      <h1>Heading 1</h1>
      <h2 style={{ backgroundColor: 'pink' }}>Heading 2</h2>
      ...
    </body>
  </html>
);

const html = ReactDOMServer.renderToStaticMarkup(element);

return (
  <Document>
    <Page>
      <Html>{html}</Html>
    </Page>
  </Document>
);

Props

type HtmlProps = {
  children: string; // the HTML
  collapse?: boolean; // Default: true. Collapse whitespace. If false, render newlines as breaks
  renderers?: HtmlRenderers; // Mapping of { tagName: HtmlRenderer }
  style?: Style | Style[]; // Html root View style
  stylesheet?: HtmlStyles | HtmlStyles[]; // Mapping of { selector: Style }
  resetStyles?: false; // If true, style/CSS reset
};

Overriding Element Styles

Provide a Stylesheet

const stylesheet = {
  // clear margins for all <p> tags
  p: {
    margin: 0,
  },
  // add pink background color to elements with class="special"
  ['.special']: {
    backgroundColor: 'pink',
  },
};

return (
  <Document>
    <Page>
      <Html stylesheet={stylesheet}>{html}</Html>
    </Page>
  </Document>
);

Inline Styles

const html = `<div style="width: 200px; height: 200px; background-color: pink">Foobar</div>`;

return (
  <Document>
    <Page>
      <Html>{html}</Html>
    </Page>
  </Document>
);

Resetting Styles

Reset browser default styles (see CSS reset)

return (
  <Document>
    <Page>
      <Html resetStyles>{html}</Html>
    </Page>
  </Document>
);

Font Sizes

The default styesheet roughly matches browser defaults, using a rough emulation of ems:

const em = (em: number, relativeSize: number = fontSize) => em * relativeSize;

StyleSheet.create({
  h1: {
    fontSize: em(2),
    marginVertical: em(0.67, em(2)),
    fontWeight: 'bold',
  },
  ...
});

By default, the basis for the font size ems is based on the fontSize from props.style:

return (
  <Document>
    <Page>
      <Html style={{ fontSize: 10 }}>{html}</Html>
    </Page>
  </Document>
);

If this is not defined, it falls back to a default of 18