summaryrefslogtreecommitdiffstats
path: root/stories/react/utils/SourceToggle.js
blob: a05c8d0d8e4e803b60fed857314ab8bcc6948a3a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
/* eslint-disable react/no-danger */
import React from 'react';
import jsxToString from './jsxToString.js';

import Prism from 'prismjs';

import PrismJsx from 'prismjs/components/prism-jsx.js'; // eslint-disable-line no-unused-vars

const sources = {
	React: 'React',
	HTML: 'HTML'
};

export default class SourceToggle extends React.Component {
	constructor(props) {
		super(props);
		this.state = {
			source: sources.React
		};
	}

	renderFromSource() {
		let {jsx, html, renderFromJsx} = this.props;
		let {source} = this.state;
		let classname = 'source-toggle-example';
		switch (source) {
			case sources.HTML:
				return renderFromJsx ? <div className={classname}>{jsx}</div> : <div className={classname} dangerouslySetInnerHTML={{__html: html}} />;
			case sources.React:
			default:
				return <div className={classname}>{jsx}</div>;
		}
	}

	renderMarkdown() {
		let {jsx, html, exclude} = this.props;
		let {source} = this.state;
		switch (source) {
			case sources.HTML:
				return {__html: Prism.highlight(html, Prism.languages.html)};
			case sources.React:
			default:
				return {__html: Prism.highlight(jsxToString({jsx, exclude}), Prism.languages.jsx)};
		}
	}

	render() {
		let {title} = this.props;
		return (
			<div className='source-toggle-wrapper'>
				{title && <div className='source-toggle-title'>{title}</div>}
				<div className='source-toggle'>
					{this.renderFromSource()}
					<div className='source-toggle-code'>
						<div className='source-toggle-code-tabs'>
							{Object.keys(sources).map((source, i) => (
									<div
										key={i}
										className={`source-toggle-tab${this.state.source === source ? ' selected' : ''}`}
										onClick={() => this.setState({source})}>
										{source}
									</div>
							))}
						</div>
						<pre>
							<code dangerouslySetInnerHTML={this.renderMarkdown()} />
						</pre>
					</div>
				</div>
			</div>
		);
	}
}