diff --git a/README.md b/README.md
index c87e1c7..5073f8f 100644
--- a/README.md
+++ b/README.md
@@ -10,36 +10,29 @@ npm install --save react-remarkable
## Usage
```jsx
+import React from 'react';
+import Markdown from 'react-remarkable';
+import Emoji from 'remarkable-emoji'
-var React = require('react');
-var Markdown = require('react-remarkable');
+const MyComponent = () => (
+
+ {/* Pass Markdown source to the `source` prop */}
+
-var MyComponent = React.createClass({
+ {/* Or pass it as children */}
+ {/* You can nest React components, too */}
+
{`
+ ## Reasons React is great
- render() {
- return (
-
- {/* Pass Markdown source to the `source` prop */}
-
+ 1. Server-side rendering
+ 2. This totally works:
- {/* Or pass it as children */}
- {/* You can nest React components, too */}
- {`
- ## Reasons React is great
-
- 1. Server-side rendering
- 2. This totally works:
-
-
-
- Pretty neat!
- `}
-
- );
- }
-
-});
+
+ Pretty neat!
+ `}
+
+);
```
Available props:
@@ -47,6 +40,7 @@ Available props:
- `options` - Hash of Remarkable options
- `source` - Markdown source. You can also pass the source as children, which allows you to mix React components and Markdown.
- `container` - Element to use as container. Defaults to `div`.
+- `plugins` - Array of remarkable plugins
## Syntax Highlighting
diff --git a/package.json b/package.json
index 02c890a..38e6b67 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "react-remarkable",
- "version": "1.1.2",
+ "version": "1.1.3-alpha.2",
"description": "A React component for rendering Markdown with remarkable",
"main": "dist/index.js",
"repository": {
diff --git a/src/index.js b/src/index.js
index 46c7336..405378e 100644
--- a/src/index.js
+++ b/src/index.js
@@ -1,34 +1,70 @@
'use strict';
import React from 'react';
+import PropTypes from 'prop-types';
import Markdown from 'remarkable';
class Remarkable extends React.Component {
+ static propTypes = {
+ container: PropTypes.string,
+ options: PropTypes.object,
+ source: PropTypes.string,
+ children: PropTypes.oneOfType([
+ PropTypes.arrayOf(PropTypes.node),
+ PropTypes.node
+ ])
+ }
+
+ static defaultProps = {
+ container: 'div',
+ options: {}
+ }
render() {
- var Container = this.props.container;
+ var {
+ container: Container,
+ children, options, source, // ⬅ remove Remarkable props
+ ...props // ⬅ only pass non-Remarkable props
+ } = this.props;
return (
-
+
{this.content()}
);
}
+ shouldComponentUpdate(nextProps, nextState) {
+ if (nextProps.options !== this.props.options) {
+ return true;
+ }
+ else if (this.props.source) {
+ return this.props.source !== nextProps.source;
+ }
+ else if (React.Children.count(this.props.children) === 1 && React.Children.count(nextProps.children) === 1) {
+ return (typeof this.props.children === 'string') && this.props.children !== nextProps.children;
+ }
+ else {
+ return true;
+ }
+ }
+
componentWillUpdate(nextProps, nextState) {
if (nextProps.options !== this.props.options) {
- this.md = new Markdown(nextProps.options);
+ this.md = this.createMarkdown(nextProps.options, nextProps.plugins);
}
}
content() {
+ var Wrapper = this.props.contentWrapper;
+
if (this.props.source) {
- return ;
+ return ;
}
else {
return React.Children.map(this.props.children, child => {
if (typeof child === 'string') {
- return ;
+ return ;
}
else {
return child;
@@ -39,16 +75,24 @@ class Remarkable extends React.Component {
renderMarkdown(source) {
if (!this.md) {
- this.md = new Markdown(this.props.options);
+ this.md = this.createMarkdown(this.props.options, this.props.plugins);
}
return this.md.render(source);
}
+
+ createMarkdown(options, plugins) {
+ return plugins.reduce((md, plugin) => {
+ return md.use(plugin);
+ }, new Markdown(options));
+ }
}
Remarkable.defaultProps = {
container: 'div',
+ contentWrapper: 'span',
options: {},
+ plugins: [],
};
export default Remarkable;