Skip to content

rosylilly/react-jsx-renderer

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

97 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

React JSX Renderer

npm (latest) npm (nightlyt)

demo Coverage Status Dependencies Status Install size License: MIT

latest nightly build test lint

A React Component for Rendering JSX.

Description

React JSX Renderer is a React Component for rendering JSX to React nodes.

It has a JavaScript Runtime inside, and can execute the user's JSX with controlled behavior.

Launch Demo

Features

  • Rendering JSX as React nodes
  • TypeScritpt ready
  • Provides CommonJS and ES Modules
  • JavaScript syntax and featues
    • without async, await and generator
  • Injectable custom React components
  • Pass binding variables
  • Applicable filters to parsed nodes
    • You can create allowlist / denylist filters to tagName, attributes or properties
  • Avoid user's call expressions
  • Avoid user's new expressions
  • Parse with meriyah

Installation

  1. npm install -s react-jsx-renderer (or yarn add react-jsx-renderer)
  2. Add import { JSXRenderer } from 'react-jsx-renderer';
  3. <JSXRenderer code="Hello, World" /> to render Hello, World

Requirements

  • React: >= 16.0.0

Options

interface ParseOptions {
  /**
   * Options of parser
   */
  meriyah?: meriyah.Options;

  /**
   * When this option is enabled, always parse as an expression.
   */
  forceExpression?: boolean;
}

interface EvaluateOptions {
  /**
   * binding
   */
  binding?: Binding;

  /**
   * components
   */
  components?: ComponentsBinding;

  /**
   * Prefix of generated keys.
   */
  keyPrefix?: string;

  /**
   * When this option is enabled, no key will be generated
   */
  disableKeyGeneration?: boolean;

  /**
   * When this option is enabled, bindings will be excluded from the component search.
   */
  disableSearchCompontsByBinding?: boolean;

  /**
   * When this option is enabled, Call Expression and New Expression will always return undefined.
   */
  disableCall?: boolean;

  /**
   * When this option is enabled, New Expression will always return undefined.
   */
  disableNew?: boolean;

  /**
   * When this option is enabled, access to undefined variables will raise an exception.
   */
  raiseReferenceError?: boolean;

  /**
   * List of functions allowed to be executed.
   *
   * If empty, all functions will be allowed to execute.
   */
  allowedFunctions?: AnyFunction[];

  /**
   * Add user-defined functions to the allowed list.
   */
  allowUserDefinedFunction?: boolean;

  /**
   * List of functions denied to be executed.
   *
   * If empty, all functions will be allowed to execute.
   */
  deniedFunctions?: AnyFunction[];
}

interface RenderingOptions {
  /**
   * List of filters to be applied to elements.
   */
  elementFilters?: JSXElementFilter[];

  /**
   * List of filters to be applied to fragments.
   */
  fragmentFilters?: JSXFragmentFilter[];

  /**
   * List of filters to be applied to text nodes.
   */
  textFilters?: JSXTextFilter[];

  /**
   * When this option is enabled, non-existent HTML elements will not be rendered.
   */
  disableUnknownHTMLElement?: boolean;

  /**
   * Function to determine Unknown HTML Element
   */
  isUnknownHTMLElementTagName?: UnknownHTMLElementTagNameFunction;
}

interface RendererOptions extends {
  /**
   * JSX code
   */
  code?: string;

  /**
   * The component that will be displayed instead when an error occurs.
   */
  fallbackComponent?: JSXFallbackComponent;

  /**
   * If you want to receive the parsed result, set a Ref object to this option.
   */
  refNodes?: Ref<JSXNode[]>;
}

Usage

Using like a simple HTML template engine

input:

import { render } from 'react-dom';
import { JSXRenderer } from 'react-jsx-renderer';

const root = document.getElementById('root');

render(
  <JSXRenderer
    binding={{ name: 'Sho Kusano' }}
    code={'<p>Hello, {name}</p>'}
  />,
  root
);

to:

<p>Hello, Sho Kusano</p>

Using JSX with JavaScript expressions

input:

render(
  <JSXRenderer
    binding={{
      three: 3,
      seven: 7,
    }}
    code={
      '<p>+ {three + seven}</p>' +
      '<p>- {three - seven}</p>' +
      '<p>bitwise shift {three << seven}</p>'
    }
  />,
  root
);

to:

<p>+ 10</p>
<p>- -4</p>
<p>bitwise shift 384</p>

Using JSX with your favorite custom components

const Red = ({ children }) => <b style={{ color: 'red' }}>{children}</b>

render(
  <JSXRenderer
    components={{ RedColor: Red }}
    code={'<p><RedColor>red</RedColor></p>'}
  />,
  root
);

to:

<p><b style="color: red">red</b></p>

Convert JSX with filters

const hrefFilter = (element: JSXElement) => {
  const { props, component, children } = element;
  if (component !== 'a') return element;

  let href = props.href || '';
  if (href.includes('//')) {
    href = secureURLConvert(href); // Add prefix https://secure.url/redirect?url=
  }
  const filteredProps = { ...props, href };
  return { component, children, props: filteredProps };
}

render(
  <JSXRenderer
    elementFilters={[hrefFilter]}
    code={
      '<p><a href="/">root</a></p>' +
      '<p><a href="../">upper directory</a></p>' +
      '<p><a href="subdir">sub directory</a></p>' +
      '<p><a href="https://github.com/">github</a></p>' +
    }
  />,
  root
);

to:

<p><a href="/">root</a></p>
<p><a href="../">upper directory</a></p>
<p><a href="subdir">sub directory</a></p>
<p><a href="https://secure.url/redirect?url=https://github.com">github</a></p>

Provide options by context

ex: Server side rendering.

import { JSDOM } from 'jsdom';

render(
  <JSXRendererOptionsProvider isUnknownHTMLElement={(tagName) => {
    const { window } = new JSDOM();
    return window.document.createElement(tagName) instanceof window.HTMLUnknownElement;
  }}>
    <JSXRenderer
      code={
        '<p><unknown>Avoid</unknown></p>'
      }
    />
  </JSXRendererOptionsProvider>,
  root
);

to:

<p></p>

License

MIT License

Related projects

About

A React component for Rendering JSX

Topics

Resources

License

Stars

Watchers

Forks

Contributors 2

  •  
  •