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