refactor: Use ES6 classes instead of createClass
This commit is contained in:
committed by
Tom MacWright
parent
5657bb232a
commit
f5c5f86b24
1
.babelrc
1
.babelrc
@ -1,4 +1,5 @@
|
||||
{
|
||||
"plugins": ["transform-class-properties"],
|
||||
"presets": [
|
||||
"stage-0",
|
||||
"es2015",
|
||||
|
@ -34,9 +34,8 @@
|
||||
"react/react-in-jsx-scope": 2,
|
||||
"react/no-unknown-property": [2],
|
||||
"react/prop-types": 2,
|
||||
"react/require-extension": [2, { "extensions": [".js", ".jsx"] }],
|
||||
"react/self-closing-comp": [2],
|
||||
"react/wrap-multilines": [2],
|
||||
"react/jsx-wrap-multilines": [2],
|
||||
"semi": [2, "always"],
|
||||
"keyword-spacing": [2, { "before": true, "after": true }],
|
||||
"space-before-blocks": 2,
|
||||
|
@ -27,6 +27,7 @@
|
||||
"dependencies": {
|
||||
"babel-cli": "^6.4.0",
|
||||
"babel-eslint": "^7.2.1",
|
||||
"babel-plugin-transform-class-properties": "^6.24.1",
|
||||
"babel-polyfill": "^6.3.14",
|
||||
"babel-preset-es2015": "^6.3.13",
|
||||
"babel-preset-react": "^6.3.13",
|
||||
@ -44,9 +45,9 @@
|
||||
"isomorphic-fetch": "^2.2.0",
|
||||
"lodash.debounce": "^4.0.3",
|
||||
"minifyify": "^7.1.0",
|
||||
"prop-types": "^15.5.9",
|
||||
"react": "^15.0.2",
|
||||
"react-dom": "^15.0.2",
|
||||
"react-pure-render": "^1.0.2",
|
||||
"remark": "^7.0.0",
|
||||
"remark-html": "^6.0.0",
|
||||
"remark-slug": "^4.1.0",
|
||||
|
@ -1,8 +1,8 @@
|
||||
import React from 'react';
|
||||
import Navigation from './navigation';
|
||||
import PropTypes from 'prop-types';
|
||||
import Content from './content';
|
||||
import RoundedToggle from './rounded_toggle';
|
||||
import PureRenderMixin from 'react-pure-render/mixin';
|
||||
import GithubSlugger from 'github-slugger';
|
||||
import debounce from 'lodash.debounce';
|
||||
import { brandNames, brandClasses } from '../custom';
|
||||
@ -41,13 +41,13 @@ let debouncedReplaceState = debounce(hash => {
|
||||
window.history.replaceState('', '', hash);
|
||||
}, 100);
|
||||
|
||||
var App = React.createClass({
|
||||
mixins: [PureRenderMixin],
|
||||
propTypes: {
|
||||
content: React.PropTypes.string.isRequired,
|
||||
ast: React.PropTypes.object.isRequired
|
||||
},
|
||||
getInitialState() {
|
||||
export default class App extends React.PureComponent {
|
||||
static propTypes = {
|
||||
content: PropTypes.string.isRequired,
|
||||
ast: PropTypes.object.isRequired
|
||||
}
|
||||
constructor(props) {
|
||||
super(props);
|
||||
var active = 'Introduction';
|
||||
|
||||
if (process.browser) {
|
||||
@ -70,7 +70,7 @@ var App = React.createClass({
|
||||
active = headingForHash.children[0].value;
|
||||
}
|
||||
}
|
||||
return {
|
||||
this.state = {
|
||||
// media queryMatches
|
||||
mqls: mqls,
|
||||
// object of currently matched queries, like { desktop: true }
|
||||
@ -82,7 +82,7 @@ var App = React.createClass({
|
||||
showNav: false
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
this.state = {
|
||||
mqls: { },
|
||||
queryMatches: {
|
||||
desktop: true
|
||||
@ -92,17 +92,17 @@ var App = React.createClass({
|
||||
showNav: false
|
||||
};
|
||||
}
|
||||
},
|
||||
}
|
||||
toggleNav() {
|
||||
this.setState({ showNav: !this.state.showNav });
|
||||
},
|
||||
}
|
||||
componentDidMount() {
|
||||
this.mediaQueryChanged();
|
||||
this.onScroll = debounce(this.onScrollImmediate, 100);
|
||||
document.addEventListener('scroll', this.onScroll);
|
||||
this.onScrollImmediate();
|
||||
},
|
||||
onScrollImmediate() {
|
||||
}
|
||||
onScrollImmediate = () => {
|
||||
var sections = document.querySelectorAll('div.section');
|
||||
if (!sections.length) return;
|
||||
for (var i = 0; i < sections.length; i++) {
|
||||
@ -114,7 +114,7 @@ var App = React.createClass({
|
||||
return;
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
mediaQueryChanged() {
|
||||
this.setState({
|
||||
queryMatches: this.state.mqls.reduce((memo, q) => {
|
||||
@ -122,19 +122,19 @@ var App = React.createClass({
|
||||
return memo;
|
||||
}, {})
|
||||
});
|
||||
},
|
||||
}
|
||||
componentWillUnmount() {
|
||||
this.state.mqls.forEach(q => q.removeListener(this.mediaQueryChanged));
|
||||
document.body.removeEventListener('scroll', this.onScroll);
|
||||
},
|
||||
onChangeLanguage(language) {
|
||||
}
|
||||
onChangeLanguage = (language) => {
|
||||
this.setState({ language }, () => {
|
||||
if (window.history) {
|
||||
window.history.pushState(null, null,
|
||||
`?${qs.stringify({ language: language.title })}${window.location.hash}`);
|
||||
}
|
||||
});
|
||||
},
|
||||
}
|
||||
componentDidUpdate(_, prevState) {
|
||||
if (prevState.activeSection !== this.state.activeSection) {
|
||||
// when the section changes, replace the hash
|
||||
@ -144,7 +144,7 @@ var App = React.createClass({
|
||||
// when the language changes, use the hash to set scroll
|
||||
window.location.hash = window.location.hash;
|
||||
}
|
||||
},
|
||||
}
|
||||
navigationItemClicked(activeSection) {
|
||||
setTimeout(() => {
|
||||
this.setState({ activeSection });
|
||||
@ -152,12 +152,12 @@ var App = React.createClass({
|
||||
if (!this.state.queryMatches.desktop) {
|
||||
this.toggleNav();
|
||||
}
|
||||
},
|
||||
}
|
||||
toggleColumnMode() {
|
||||
this.setState({
|
||||
columnMode: this.state.columnMode === 1 ? 2 : 1
|
||||
});
|
||||
},
|
||||
}
|
||||
render() {
|
||||
let ast = JSON.parse(JSON.stringify(this.props.ast));
|
||||
let { activeSection, queryMatches, showNav, columnMode } = this.state;
|
||||
@ -237,6 +237,4 @@ var App = React.createClass({
|
||||
|
||||
</div>);
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = App;
|
||||
}
|
||||
|
@ -1,14 +1,14 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import Section from './section';
|
||||
import PureRenderMixin from 'react-pure-render/mixin';
|
||||
import GithubSlugger from 'github-slugger';
|
||||
import { transformURL } from '../custom';
|
||||
let slugger = new GithubSlugger();
|
||||
let slug = title => { slugger.reset(); return slugger.slug(title); };
|
||||
|
||||
var roundedToggleOptionType = React.PropTypes.shape({
|
||||
title: React.PropTypes.string,
|
||||
value: React.PropTypes.string
|
||||
var roundedToggleOptionType = PropTypes.shape({
|
||||
title: PropTypes.string,
|
||||
value: PropTypes.string
|
||||
});
|
||||
|
||||
function chunkifyAST(ast, language) {
|
||||
@ -71,24 +71,21 @@ function chunkifyAST(ast, language) {
|
||||
});
|
||||
}
|
||||
|
||||
var Content = React.createClass({
|
||||
mixins: [PureRenderMixin],
|
||||
propTypes: {
|
||||
ast: React.PropTypes.object.isRequired,
|
||||
export default class Content extends React.PureComponent {
|
||||
static propTypes = {
|
||||
ast: PropTypes.object.isRequired,
|
||||
language: roundedToggleOptionType,
|
||||
leftClassname: React.PropTypes.string.isRequired,
|
||||
rightClassname: React.PropTypes.string.isRequired
|
||||
},
|
||||
leftClassname: PropTypes.string.isRequired,
|
||||
rightClassname: PropTypes.string.isRequired
|
||||
}
|
||||
render() {
|
||||
let { ast, language, leftClassname, rightClassname } = this.props;
|
||||
return (<div className='clearfix'>
|
||||
{chunkifyAST(ast, language.value).map((chunk, i) => <Section
|
||||
{chunkifyAST(ast, language.value).map((chunk, i) => (<Section
|
||||
leftClassname={leftClassname}
|
||||
rightClassname={rightClassname}
|
||||
chunk={chunk}
|
||||
key={i} />)}
|
||||
key={i} />))}
|
||||
</div>);
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = Content;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React from 'react';
|
||||
import PureRenderMixin from 'react-pure-render/mixin';
|
||||
import PropTypes from 'prop-types';
|
||||
import NavigationItem from './navigation_item';
|
||||
import { footerContent } from '../custom';
|
||||
|
||||
@ -23,13 +23,12 @@ function getAllInSection(headings, idx) {
|
||||
return activeHeadings;
|
||||
}
|
||||
|
||||
var Navigation = React.createClass({
|
||||
mixins: [PureRenderMixin],
|
||||
propTypes: {
|
||||
ast: React.PropTypes.object.isRequired,
|
||||
activeSection: React.PropTypes.string,
|
||||
navigationItemClicked: React.PropTypes.func.isRequired
|
||||
},
|
||||
export default class Navigation extends React.PureComponent {
|
||||
static propTypes = {
|
||||
ast: PropTypes.object.isRequired,
|
||||
activeSection: PropTypes.string,
|
||||
navigationItemClicked: PropTypes.func.isRequired
|
||||
}
|
||||
render() {
|
||||
var activeHeadings = [];
|
||||
let headings = this.props.ast.children
|
||||
@ -91,6 +90,4 @@ var Navigation = React.createClass({
|
||||
{footerContent}
|
||||
</div>);
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = Navigation;
|
||||
}
|
||||
|
@ -1,17 +1,16 @@
|
||||
import React from 'react';
|
||||
import PureRenderMixin from 'react-pure-render/mixin';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
var NavigationItem = React.createClass({
|
||||
mixins: [PureRenderMixin],
|
||||
propTypes: {
|
||||
sectionName: React.PropTypes.string.isRequired,
|
||||
active: React.PropTypes.bool.isRequired,
|
||||
onClick: React.PropTypes.func.isRequired,
|
||||
href: React.PropTypes.string.isRequired
|
||||
},
|
||||
onClick() {
|
||||
export default class NavigationItem extends React.PureComponent {
|
||||
static propTypes = {
|
||||
sectionName: PropTypes.string.isRequired,
|
||||
active: PropTypes.bool.isRequired,
|
||||
onClick: PropTypes.func.isRequired,
|
||||
href: PropTypes.string.isRequired
|
||||
}
|
||||
onClick = () => {
|
||||
this.props.onClick(this.props.sectionName);
|
||||
},
|
||||
}
|
||||
render() {
|
||||
var {sectionName, href, active} = this.props;
|
||||
return (<a
|
||||
@ -21,6 +20,4 @@ var NavigationItem = React.createClass({
|
||||
{sectionName}
|
||||
</a>);
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = NavigationItem;
|
||||
}
|
||||
|
@ -1,50 +1,46 @@
|
||||
import React from 'react';
|
||||
import PureRenderMixin from 'react-pure-render/mixin';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
var roundedToggleOptionType = React.PropTypes.shape({
|
||||
title: React.PropTypes.string,
|
||||
value: React.PropTypes.string
|
||||
var roundedToggleOptionType = PropTypes.shape({
|
||||
title: PropTypes.string,
|
||||
value: PropTypes.string
|
||||
});
|
||||
|
||||
var RoundedToggle = React.createClass({
|
||||
mixins: [PureRenderMixin],
|
||||
propTypes: {
|
||||
options: React.PropTypes.arrayOf(roundedToggleOptionType).isRequired,
|
||||
export default class RoundedToggle extends React.PureComponent {
|
||||
static propTypes = {
|
||||
options: PropTypes.arrayOf(roundedToggleOptionType).isRequired,
|
||||
active: roundedToggleOptionType,
|
||||
short: React.PropTypes.bool,
|
||||
onChange: React.PropTypes.func.isRequired
|
||||
},
|
||||
short: PropTypes.bool,
|
||||
onChange: PropTypes.func.isRequired
|
||||
}
|
||||
render() {
|
||||
let { options, active } = this.props;
|
||||
return (<div className='rounded-toggle inline short'>
|
||||
{options.map(option =>
|
||||
<RoundedToggleOption
|
||||
(<RoundedToggleOption
|
||||
key={option.value}
|
||||
option={option}
|
||||
short={this.props.short}
|
||||
onClick={this.props.onChange}
|
||||
className={`strong ${option.value === active.value ? 'active': ''}`} />)}
|
||||
className={`strong ${option.value === active.value ? 'active': ''}`} />))}
|
||||
</div>);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var RoundedToggleOption = React.createClass({
|
||||
mixins: [PureRenderMixin],
|
||||
propTypes: {
|
||||
class RoundedToggleOption extends React.PureComponent {
|
||||
static propTypes = {
|
||||
option: roundedToggleOptionType,
|
||||
className: React.PropTypes.string.isRequired,
|
||||
short: React.PropTypes.bool,
|
||||
onClick: React.PropTypes.func.isRequired
|
||||
},
|
||||
onClick() {
|
||||
className: PropTypes.string.isRequired,
|
||||
short: PropTypes.bool,
|
||||
onClick: PropTypes.func.isRequired
|
||||
}
|
||||
onClick = () => {
|
||||
this.props.onClick(this.props.option);
|
||||
},
|
||||
}
|
||||
render() {
|
||||
let { className, option } = this.props;
|
||||
return (<a
|
||||
onClick={this.onClick}
|
||||
className={className}>{this.props.short ? option.short : option.title}</a>);
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = RoundedToggle;
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
import React from 'react';
|
||||
import remark from 'remark';
|
||||
import PropTypes from 'prop-types';
|
||||
import remarkHTML from 'remark-html';
|
||||
import remarkHighlight from '../highlight';
|
||||
import PureRenderMixin from 'react-pure-render/mixin';
|
||||
import { postHighlight, remarkPlugins } from '../custom';
|
||||
|
||||
function renderHighlighted(nodes) {
|
||||
@ -19,13 +19,12 @@ function renderHighlighted(nodes) {
|
||||
};
|
||||
}
|
||||
|
||||
var Section = React.createClass({
|
||||
mixins: [PureRenderMixin],
|
||||
propTypes: {
|
||||
chunk: React.PropTypes.object.isRequired,
|
||||
leftClassname: React.PropTypes.string.isRequired,
|
||||
rightClassname: React.PropTypes.string.isRequired
|
||||
},
|
||||
export default class Section extends React.PureComponent {
|
||||
static propTypes = {
|
||||
chunk: PropTypes.object.isRequired,
|
||||
leftClassname: PropTypes.string.isRequired,
|
||||
rightClassname: PropTypes.string.isRequired
|
||||
}
|
||||
render() {
|
||||
let { chunk, leftClassname, rightClassname } = this.props;
|
||||
let { left, right, preview } = chunk;
|
||||
@ -40,6 +39,4 @@ var Section = React.createClass({
|
||||
dangerouslySetInnerHTML={renderHighlighted(right)} />}
|
||||
</div>);
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = Section;
|
||||
}
|
||||
|
Reference in New Issue
Block a user