mirror of
https://github.com/storybookjs/storybook.git
synced 2025-04-09 00:19:13 +08:00
107 lines
2.5 KiB
JavaScript
107 lines
2.5 KiB
JavaScript
import React, { Component } from 'react';
|
|
import PropTypes from 'prop-types';
|
|
import jsx from 'react-syntax-highlighter/languages/prism/jsx';
|
|
import { darcula } from 'react-syntax-highlighter/styles/prism';
|
|
import SyntaxHighlighter, { registerLanguage } from 'react-syntax-highlighter/prism-light';
|
|
import { createElement } from 'react-syntax-highlighter';
|
|
import { EVENT_ID } from './';
|
|
|
|
registerLanguage('jsx', jsx);
|
|
|
|
const styles = {
|
|
selections: {
|
|
backgroundColor: 'rgba(255, 242, 60, 0.2)',
|
|
},
|
|
panel: {
|
|
width: '100%',
|
|
},
|
|
};
|
|
|
|
export default class StoryPanel extends Component {
|
|
constructor(props) {
|
|
super(props);
|
|
|
|
this.state = { source: '// Here will be dragons 🐉' };
|
|
|
|
const { channel } = props;
|
|
|
|
channel.on(EVENT_ID, ({ source, location }) => {
|
|
this.setState({
|
|
source,
|
|
location,
|
|
});
|
|
});
|
|
|
|
this.setSelectedStoryRef = this.setSelectedStoryRef.bind(this);
|
|
this.lineRenderer = this.lineRenderer.bind(this);
|
|
}
|
|
|
|
componentDidUpdate() {
|
|
if (this.selectedStoryRef) {
|
|
this.selectedStoryRef.scrollIntoView();
|
|
}
|
|
}
|
|
|
|
setSelectedStoryRef(ref) {
|
|
this.selectedStoryRef = ref;
|
|
}
|
|
|
|
createPart(rows, stylesheet, useInlineStyles) {
|
|
return rows.map((node, i) =>
|
|
createElement({
|
|
node,
|
|
stylesheet,
|
|
useInlineStyles,
|
|
key: `code-segement${i}`,
|
|
})
|
|
);
|
|
}
|
|
|
|
lineRenderer({ rows, stylesheet, useInlineStyles }) {
|
|
const { location } = this.state;
|
|
|
|
if (location) {
|
|
const first = location.startLoc.line - 1;
|
|
const last = location.endLoc.line;
|
|
|
|
const start = this.createPart(rows.slice(0, first), stylesheet, useInlineStyles);
|
|
const selected = this.createPart(rows.slice(first, last), stylesheet, useInlineStyles);
|
|
const end = this.createPart(rows.slice(last), stylesheet, useInlineStyles);
|
|
|
|
return (
|
|
<span>
|
|
{start}
|
|
<div ref={this.setSelectedStoryRef} style={styles.selections}>
|
|
{selected}
|
|
</div>
|
|
{end}
|
|
</span>
|
|
);
|
|
}
|
|
|
|
return this.createPart(rows, stylesheet, useInlineStyles);
|
|
}
|
|
|
|
render() {
|
|
return (
|
|
<SyntaxHighlighter
|
|
language="jsx"
|
|
showLineNumbers="true"
|
|
style={darcula}
|
|
renderer={this.lineRenderer}
|
|
customStyle={styles.panel}
|
|
>
|
|
{this.state.source}
|
|
</SyntaxHighlighter>
|
|
);
|
|
}
|
|
}
|
|
|
|
StoryPanel.propTypes = {
|
|
channel: PropTypes.shape({
|
|
emit: PropTypes.func,
|
|
on: PropTypes.func,
|
|
removeListener: PropTypes.func,
|
|
}).isRequired,
|
|
};
|