import React, {Component} from 'react';
import {Parser} from 'commonmark';
import shallowEqual from 'shallowequal';
import {getChildren} from './util';
import COMPONENT_NAMES from './component-names';
const defaultCustomizer = (render, children) => children.map(render);
const render = (components, customizer = defaultCustomizer, node) => {
const NodeComponent = components[COMPONENT_NAMES[node.type]];
const {info, level, listType, listStart, title, destination} = node;
const children = [...getChildren(node)];
return (
<NodeComponent {...{info, level, listType, listStart, title, destination}}>
{!children.length
? node.literal
: customizer(
(child, i) =>
React.cloneElement(render(components, customizer, child), {
key: i,
}),
children,
)}
</NodeComponent>
);
};
class Markdown extends Component {
parser = new Parser();
shouldComponentUpdate(nextProps) {
const {components, ...rest} = this.props;
const {components: nextComponents, ...nextRest} = nextProps;
return !shallowEqual(rest, nextRest) || !shallowEqual(components, nextComponents);
}
render() {
const {components, customizer, children} = this.props;
return render(components, customizer, this.parser.parse(children));
}
}
export default Markdown;
|