npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@mdfe/react-native-htmlview

v0.12.1

Published

A component which renders HTML content as native views

Downloads

12

Readme

React Native HTMLView Build status

A component which takes HTML content and renders it as native views, with customisable style and handling of links, etc.

In action (from ReactNativeHackerNews):

React Native Hacker News Comments

Table of contents

Install

npm install react-native-htmlview --save

Usage

props:

  • value: a string of HTML content to render
  • onLinkPress: a function which will be called with a url when a link is pressed. Passing this prop will override how links are handled (defaults to calling Linking.openURL(url))
  • onLinkLongPress: a function which will be called with a url when a link is long pressed. The default is null.
  • stylesheet: a stylesheet object keyed by tag name, which will override the styles applied to those respective tags.
  • renderNode: a custom function to render HTML nodes however you see fit. If the function returns undefined (not null), the default renderer will be used for that node. The function takes the following arguments:
    • node the html node as parsed by htmlparser2
    • index position of the node in parent node's children
    • siblings parent node's children (including current node)
    • parent parent node
    • defaultRenderer the default rendering implementation, so you can use the normal rendering logic for some subtree. defaultRenderer takes the following arguments:
      • node the node to render with the default rendering logic
      • parent the parent of node of node
  • bullet: text which is rendered before every li inside a ul
  • paragraphBreak: text which appears after every p element
  • lineBreak: text which appears after text elements which create a new line (br, headings)
  • addLineBreaks: when explicitly false, effectively sets paragraphBreak and lineBreak to null
  • NodeComponent, nodeComponentProps, RootComponent, rootComponentProps, TextComponent, textComponentProps: see the heading Customizing things even further below.

Example

import React from 'react';
import {StyleSheet} from 'react-native';
import HTMLView from 'react-native-htmlview';

class App extends React.Component {
  render() {
    const htmlContent = `<p><a href="http://jsdf.co">&hearts; nice job!</a></p>`;

    return (
      <HTMLView
        value={htmlContent}
        stylesheet={styles}
      />
    );
  }
}

const styles = StyleSheet.create({
  a: {
    fontWeight: '300',
    color: '#FF3366', // make links coloured pink
  },
});

Custom Link Handling

When a link is clicked, by default ReactNative.Linking.openURL is called with the link url. You can customise what happens when a link is clicked with onLinkPress:

class App extends React.Component {
  render() {
    return (
      <HTMLView
        value={this.props.html}
        onLinkPress={(url) => console.log('clicked link: ', url)}
      />
    );
  }
}

If you're getting the error "undefined is not an object (evaluating 'RCTLinkingManager.openURL’)” from the LinkingIOS API, try adding ‘RCTLinking' to the project's 'Linked Frameworks and Libraries’. You might have to find RCTLinking.xcodeproj in the react-native package dir and drag that into your main Xcode project first.

Custom Element Rendering

You can implement the renderNode prop to add support for unsupported element types, or override the rendering for supported types. renderNode is a function which is called with the type and attributes of each HTML element found in the input HTML, and from this function you can return a React element to be rendered in its place. If you return null nothing will be rendered in place of this element or its children. If you return undefined (or don't return anything) then HTMLView will drop back to its default rendering for that type of HTML element.

For example, here is how you might implement the <iframe> element:

function renderNode(node, index, siblings, parent, defaultRenderer) {
  if (node.name == 'iframe') {
    const a = node.attribs;
    const iframeHtml = `<iframe src="${a.src}"></iframe>`;
    return (
      <View key={index} style={{width: Number(a.width), height: Number(a.height)}}>
        <WebView source={{html: iframeHtml}} />
      </View>
    );
  }
}

const htmlContent = `
  <div>
    <iframe src="http://info.cern.ch/" width="360" height="300" />
  </div>
`;

class App extends React.Component {
  render() {
    return (
      <HTMLView value={htmlContent} renderNode={renderNode} />
    );
  }
}

Alternatively, this example shows how you could disallow the <iframe> element:

function renderNode(node, index, siblings, parent, defaultRenderer) {
  if (node.name == 'iframe') {
    return null;
  }
}

const htmlContent = `
  <div>
    <iframe src="http://info.cern.ch/" width="360" height="300" />
  </div>
`;

class App extends React.Component {
  render() {
    return (
      <HTMLView value={htmlContent} renderNode={renderNode} />
    );
  }
}

If you want to reuse the default renderer, you need to call it passing an array of nodes. This example shows how to replace a specific HTML tag with something different, but still process the children.

function renderNode(node, index, siblings, parent, defaultRenderer) {
  if (node.name == 'mytag') {
      const specialSyle = node.attribs.style
      return (
        <Text key={index} style={specialSyle}>
          {defaultRenderer(node.children, parent)}
        </Text>
      )
    }
}

const htmlContent = `
  <div>
    <mytag>
      <div>some content processed normally by the engine</div>
    </mytag>
  </div>
`;

class App extends React.Component {
  render() {
    return (
      <HTMLView value={htmlContent} renderNode={renderNode} />
    );
  }
}

For further understanding of the possiblities of the renderNode prop, read through htmlToElement.js. Particularly look at where renderNode is called to see how it can override what sort of React element is created in place of an element in the input HTML.

Customizing things even further

In addition to supplying a custom renderNode function, you can customize what is rendered by the built in renderNode function. Read through htmlToElement.js and note the usage of NodeComponent (for rendering HTML element nodes) and TextComponent (for rendering text strings in the HTML). Both of these components can be injected as the NodeComponent and TextComponent props to HTMLView, or alternatively they can be given extra props by passing an object as the nodeComponentProps and textComponentProps props. Finally you can also use the props RootComponent and rootComponentProps to customize the root wrapper View element that is rendered by the HTMLView in HTMLView.js.

Changelog

  • 0.12.1
    • use ViewPropTypes
    • fix an issue with htmlparser2-without-node-native and inline-requires
    • Thanks to @nikolaik and @douglasjunior
  • 0.12.0
    • inherited styles are now applied in the correct order
    • fixed an issue where the style array was unnecessarily complex and included multiple empty objects
    • changes to the stylesheet will now trigger a re-render
    • textAlign works correctly in most cases
    • fixed an ordered list numbering bug
    • added onLinkLongPress property
    • default and custom styles now apply correctly to <li> prefix
    • fixed code font for Android (monospace)
    • Thanks to @JoeyBetlej, @isilher, @bky, @RobPando
  • 0.11.0
    • style prop passed via textComponentProps is now respected even if no wrapping element is present
    • underline style
    • line break after li
    • nested elements (<b><i>...</i></b>) work properly
    • use PureComponent
    • sundry refactoring
    • Thanks to @michalraska, @tywhang, @isilher, @douglasjunior, @shashkovdanil
  • 0.10.0
    • added props: bullet, paragraphBreak, lineBreak, NodeComponent, nodeComponentProps, RootComponent, rootComponentProps, TextComponent, textComponentProps
  • 0.9.0
    • exposed styles prop
    • exposed defaultRenderer in renderNode (@brandonreavis, @koenpunt)
    • added addLineBreaks (@jmacedoit)
  • 0.7.0 - fixed for recent versions of react-native
  • 0.6.0 - onLinkPress fix (@damusnet), headers now only have one single line break (@crysfel)
  • 0.5.0 - react-native 0.25 compat (@damusnet)
  • 0.4.0 - re-renders properly when html content changes