mirror of
https://github.com/zebrajr/react.git
synced 2025-12-06 12:20:20 +01:00
Run all fixtures through Prettier (#10157)
* Include fixtures in prettier default pattern * Run all fixtures through Prettier
This commit is contained in:
parent
cff012fc16
commit
d04618b28b
|
|
@ -6,7 +6,7 @@
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
*/
|
*/
|
||||||
"use strict";
|
'use strict';
|
||||||
|
|
||||||
var React = require('react');
|
var React = require('react');
|
||||||
var ReactART = require('react-art');
|
var ReactART = require('react-art');
|
||||||
|
|
@ -72,10 +72,7 @@ class VectorWidget extends React.Component {
|
||||||
*/
|
*/
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<Surface
|
<Surface width={700} height={700} style={{cursor: 'pointer'}}>
|
||||||
width={700}
|
|
||||||
height={700}
|
|
||||||
style={{cursor: 'pointer'}}>
|
|
||||||
{this.renderGraphic(this.state.degrees)}
|
{this.renderGraphic(this.state.degrees)}
|
||||||
</Surface>
|
</Surface>
|
||||||
);
|
);
|
||||||
|
|
@ -84,12 +81,9 @@ class VectorWidget extends React.Component {
|
||||||
/**
|
/**
|
||||||
* Better SVG support for React coming soon.
|
* Better SVG support for React coming soon.
|
||||||
*/
|
*/
|
||||||
renderGraphic = (rotation) => {
|
renderGraphic = rotation => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Group
|
<Group onMouseDown={this.handleMouseDown} onMouseUp={this.handleMouseUp}>
|
||||||
onMouseDown={this.handleMouseDown}
|
|
||||||
onMouseUp={this.handleMouseUp}>
|
|
||||||
<Group x={210} y={135}>
|
<Group x={210} y={135}>
|
||||||
<Shape fill="rgba(0,0,0,0.1)" d={BORDER_PATH} />
|
<Shape fill="rgba(0,0,0,0.1)" d={BORDER_PATH} />
|
||||||
<Shape fill="#7BC7BA" d={BG_PATH} />
|
<Shape fill="#7BC7BA" d={BG_PATH} />
|
||||||
|
|
@ -102,8 +96,18 @@ class VectorWidget extends React.Component {
|
||||||
<Shape fill="#FFFFFF" d={CENTER_DOT_PATH} />
|
<Shape fill="#FFFFFF" d={CENTER_DOT_PATH} />
|
||||||
<Group>
|
<Group>
|
||||||
<Shape d={RING_ONE_PATH} stroke="#FFFFFF" strokeWidth={8} />
|
<Shape d={RING_ONE_PATH} stroke="#FFFFFF" strokeWidth={8} />
|
||||||
<Shape d={RING_TWO_PATH} transform={RING_TWO_ROTATE} stroke="#FFFFFF" strokeWidth={8} />
|
<Shape
|
||||||
<Shape d={RING_THREE_PATH} transform={RING_THREE_ROTATE} stroke="#FFFFFF" strokeWidth={8} />
|
d={RING_TWO_PATH}
|
||||||
|
transform={RING_TWO_ROTATE}
|
||||||
|
stroke="#FFFFFF"
|
||||||
|
strokeWidth={8}
|
||||||
|
/>
|
||||||
|
<Shape
|
||||||
|
d={RING_THREE_PATH}
|
||||||
|
transform={RING_THREE_ROTATE}
|
||||||
|
stroke="#FFFFFF"
|
||||||
|
strokeWidth={8}
|
||||||
|
/>
|
||||||
</Group>
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
|
|
@ -113,18 +117,33 @@ class VectorWidget extends React.Component {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
var BORDER_PATH = "M3.00191459,4 C1.34400294,4 0,5.34785514 0,7.00550479 L0,220.994495 C0,222.65439 1.34239483,224 3.00191459,224 L276.998085,224 C278.655997,224 280,222.652145 280,220.994495 L280,7.00550479 C280,5.34561033 278.657605,4 276.998085,4 L3.00191459,4 Z M3.00191459,4";
|
var BORDER_PATH =
|
||||||
var BG_PATH = "M3.00191459,1 C1.34400294,1 0,2.34785514 0,4.00550479 L0,217.994495 C0,219.65439 1.34239483,221 3.00191459,221 L276.998085,221 C278.655997,221 280,219.652145 280,217.994495 L280,4.00550479 C280,2.34561033 278.657605,1 276.998085,1 L3.00191459,1 Z M3.00191459,1";
|
'M3.00191459,4 C1.34400294,4 0,5.34785514 0,7.00550479 L0,220.994495 C0,222.65439 1.34239483,224 3.00191459,224 L276.998085,224 C278.655997,224 280,222.652145 280,220.994495 L280,7.00550479 C280,5.34561033 278.657605,4 276.998085,4 L3.00191459,4 Z M3.00191459,4';
|
||||||
var BAR_PATH = "M3.00191459,0 C1.34400294,0 0,1.34559019 0,3.00878799 L0,21 C0,21 0,21 0,21 L280,21 C280,21 280,21 280,21 L280,3.00878799 C280,1.34708027 278.657605,0 276.998085,0 L3.00191459,0 Z M3.00191459,0";
|
var BG_PATH =
|
||||||
var RED_DOT_PATH = "M12.5,17 C16.0898511,17 19,14.0898511 19,10.5 C19,6.91014895 16.0898511,4 12.5,4 C8.91014895,4 6,6.91014895 6,10.5 C6,14.0898511 8.91014895,17 12.5,17 Z M12.5,17";
|
'M3.00191459,1 C1.34400294,1 0,2.34785514 0,4.00550479 L0,217.994495 C0,219.65439 1.34239483,221 3.00191459,221 L276.998085,221 C278.655997,221 280,219.652145 280,217.994495 L280,4.00550479 C280,2.34561033 278.657605,1 276.998085,1 L3.00191459,1 Z M3.00191459,1';
|
||||||
var YELLOW_DOT_PATH = "M31.5,17 C35.0898511,17 38,14.0898511 38,10.5 C38,6.91014895 35.0898511,4 31.5,4 C27.9101489,4 25,6.91014895 25,10.5 C25,14.0898511 27.9101489,17 31.5,17 Z M31.5,17";
|
var BAR_PATH =
|
||||||
var GREEN_DOT_PATH = "M50.5,17 C54.0898511,17 57,14.0898511 57,10.5 C57,6.91014895 54.0898511,4 50.5,4 C46.9101489,4 44,6.91014895 44,10.5 C44,14.0898511 46.9101489,17 50.5,17 Z M50.5,17";
|
'M3.00191459,0 C1.34400294,0 0,1.34559019 0,3.00878799 L0,21 C0,21 0,21 0,21 L280,21 C280,21 280,21 280,21 L280,3.00878799 C280,1.34708027 278.657605,0 276.998085,0 L3.00191459,0 Z M3.00191459,0';
|
||||||
var CENTER_DOT_PATH = "M84,105 C92.8365564,105 100,97.8365564 100,89 C100,80.1634436 92.8365564,73 84,73 C75.1634436,73 68,80.1634436 68,89 C68,97.8365564 75.1634436,105 84,105 Z M84,105";
|
var RED_DOT_PATH =
|
||||||
var RING_ONE_PATH = "M84,121 C130.391921,121 168,106.673113 168,89 C168,71.3268871 130.391921,57 84,57 C37.6080787,57 0,71.3268871 0,89 C0,106.673113 37.6080787,121 84,121 Z M84,121";
|
'M12.5,17 C16.0898511,17 19,14.0898511 19,10.5 C19,6.91014895 16.0898511,4 12.5,4 C8.91014895,4 6,6.91014895 6,10.5 C6,14.0898511 8.91014895,17 12.5,17 Z M12.5,17';
|
||||||
var RING_TWO_PATH = "M84,121 C130.391921,121 168,106.673113 168,89 C168,71.3268871 130.391921,57 84,57 C37.6080787,57 0,71.3268871 0,89 C0,106.673113 37.6080787,121 84,121 Z M84,121";
|
var YELLOW_DOT_PATH =
|
||||||
var RING_THREE_PATH = "M84,121 C130.391921,121 168,106.673113 168,89 C168,71.3268871 130.391921,57 84,57 C37.6080787,57 0,71.3268871 0,89 C0,106.673113 37.6080787,121 84,121 Z M84,121";
|
'M31.5,17 C35.0898511,17 38,14.0898511 38,10.5 C38,6.91014895 35.0898511,4 31.5,4 C27.9101489,4 25,6.91014895 25,10.5 C25,14.0898511 27.9101489,17 31.5,17 Z M31.5,17';
|
||||||
var RING_TWO_ROTATE = new Transform().translate(84.000000, 89.000000).rotate(-240.000000).translate(-84.000000, -89.000000);
|
var GREEN_DOT_PATH =
|
||||||
var RING_THREE_ROTATE = new Transform().translate(84.000000, 89.000000).rotate(-300.000000).translate(-84.000000, -89.000000);
|
'M50.5,17 C54.0898511,17 57,14.0898511 57,10.5 C57,6.91014895 54.0898511,4 50.5,4 C46.9101489,4 44,6.91014895 44,10.5 C44,14.0898511 46.9101489,17 50.5,17 Z M50.5,17';
|
||||||
|
var CENTER_DOT_PATH =
|
||||||
|
'M84,105 C92.8365564,105 100,97.8365564 100,89 C100,80.1634436 92.8365564,73 84,73 C75.1634436,73 68,80.1634436 68,89 C68,97.8365564 75.1634436,105 84,105 Z M84,105';
|
||||||
|
var RING_ONE_PATH =
|
||||||
|
'M84,121 C130.391921,121 168,106.673113 168,89 C168,71.3268871 130.391921,57 84,57 C37.6080787,57 0,71.3268871 0,89 C0,106.673113 37.6080787,121 84,121 Z M84,121';
|
||||||
|
var RING_TWO_PATH =
|
||||||
|
'M84,121 C130.391921,121 168,106.673113 168,89 C168,71.3268871 130.391921,57 84,57 C37.6080787,57 0,71.3268871 0,89 C0,106.673113 37.6080787,121 84,121 Z M84,121';
|
||||||
|
var RING_THREE_PATH =
|
||||||
|
'M84,121 C130.391921,121 168,106.673113 168,89 C168,71.3268871 130.391921,57 84,57 C37.6080787,57 0,71.3268871 0,89 C0,106.673113 37.6080787,121 84,121 Z M84,121';
|
||||||
|
var RING_TWO_ROTATE = new Transform()
|
||||||
|
.translate(84.000000, 89.000000)
|
||||||
|
.rotate(-240.000000)
|
||||||
|
.translate(-84.000000, -89.000000);
|
||||||
|
var RING_THREE_ROTATE = new Transform()
|
||||||
|
.translate(84.000000, 89.000000)
|
||||||
|
.rotate(-300.000000)
|
||||||
|
.translate(-84.000000, -89.000000);
|
||||||
|
|
||||||
module.exports = VectorWidget;
|
module.exports = VectorWidget;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
"use strict";
|
'use strict';
|
||||||
|
|
||||||
var React = require('react');
|
var React = require('react');
|
||||||
var ReactDOM = require('react-dom');
|
var ReactDOM = require('react-dom');
|
||||||
|
|
|
||||||
|
|
@ -16,19 +16,19 @@ module.exports = {
|
||||||
require.resolve('babel-preset-react'),
|
require.resolve('babel-preset-react'),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
new webpack.DefinePlugin({
|
new webpack.DefinePlugin({
|
||||||
'process.env': {
|
'process.env': {
|
||||||
NODE_ENV: JSON.stringify('development'),
|
NODE_ENV: JSON.stringify('development'),
|
||||||
},
|
},
|
||||||
})
|
}),
|
||||||
],
|
],
|
||||||
resolve: {
|
resolve: {
|
||||||
alias: {
|
alias: {
|
||||||
react: require.resolve('react')
|
react: require.resolve('react'),
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
|
||||||
3
fixtures/dom/public/react-loader.js
vendored
3
fixtures/dom/public/react-loader.js
vendored
|
|
@ -29,7 +29,8 @@ var version = query.version || 'local';
|
||||||
|
|
||||||
if (version !== 'local') {
|
if (version !== 'local') {
|
||||||
REACT_PATH = 'https://unpkg.com/react@' + version + '/dist/react.min.js';
|
REACT_PATH = 'https://unpkg.com/react@' + version + '/dist/react.min.js';
|
||||||
DOM_PATH = 'https://unpkg.com/react-dom@' + version + '/dist/react-dom.min.js';
|
DOM_PATH =
|
||||||
|
'https://unpkg.com/react-dom@' + version + '/dist/react-dom.min.js';
|
||||||
}
|
}
|
||||||
|
|
||||||
document.write('<script src="' + REACT_PATH + '"></script>');
|
document.write('<script src="' + REACT_PATH + '"></script>');
|
||||||
|
|
|
||||||
|
|
@ -4,11 +4,11 @@ import Fixtures from './fixtures';
|
||||||
|
|
||||||
import '../style.css';
|
import '../style.css';
|
||||||
|
|
||||||
function App () {
|
function App() {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Header />
|
<Header />
|
||||||
<div className="container" >
|
<div className="container">
|
||||||
<Fixtures />
|
<Fixtures />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ const propTypes = {
|
||||||
|
|
||||||
class Fixture extends React.Component {
|
class Fixture extends React.Component {
|
||||||
render() {
|
render() {
|
||||||
const { children } = this.props;
|
const {children} = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="test-fixture">
|
<div className="test-fixture">
|
||||||
|
|
@ -19,4 +19,4 @@ class Fixture extends React.Component {
|
||||||
|
|
||||||
Fixture.propTypes = propTypes;
|
Fixture.propTypes = propTypes;
|
||||||
|
|
||||||
export default Fixture
|
export default Fixture;
|
||||||
|
|
|
||||||
|
|
@ -7,16 +7,13 @@ const propTypes = {
|
||||||
};
|
};
|
||||||
|
|
||||||
class FixtureSet extends React.Component {
|
class FixtureSet extends React.Component {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { title, description, children } = this.props;
|
const {title, description, children} = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<h1>{title}</h1>
|
<h1>{title}</h1>
|
||||||
{description && (
|
{description && <p>{description}</p>}
|
||||||
<p>{description}</p>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{children}
|
{children}
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -26,4 +23,4 @@ class FixtureSet extends React.Component {
|
||||||
|
|
||||||
FixtureSet.propTypes = propTypes;
|
FixtureSet.propTypes = propTypes;
|
||||||
|
|
||||||
export default FixtureSet
|
export default FixtureSet;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { parse, stringify } from 'query-string';
|
import {parse, stringify} from 'query-string';
|
||||||
import getVersionTags from '../tags';
|
import getVersionTags from '../tags';
|
||||||
const React = window.React;
|
const React = window.React;
|
||||||
|
|
||||||
|
|
@ -8,15 +8,14 @@ class Header extends React.Component {
|
||||||
const query = parse(window.location.search);
|
const query = parse(window.location.search);
|
||||||
const version = query.version || 'local';
|
const version = query.version || 'local';
|
||||||
const versions = [version];
|
const versions = [version];
|
||||||
this.state = { version, versions };
|
this.state = {version, versions};
|
||||||
}
|
}
|
||||||
componentWillMount() {
|
componentWillMount() {
|
||||||
getVersionTags()
|
getVersionTags().then(tags => {
|
||||||
.then(tags => {
|
let versions = tags.map(tag => tag.name.slice(1));
|
||||||
let versions = tags.map(tag => tag.name.slice(1));
|
versions = [`local`, ...versions];
|
||||||
versions = [`local`, ...versions];
|
this.setState({versions});
|
||||||
this.setState({ versions });
|
});
|
||||||
})
|
|
||||||
}
|
}
|
||||||
handleVersionChange(event) {
|
handleVersionChange(event) {
|
||||||
const query = parse(window.location.search);
|
const query = parse(window.location.search);
|
||||||
|
|
@ -31,41 +30,50 @@ class Header extends React.Component {
|
||||||
}
|
}
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<header className="header">
|
<header className="header">
|
||||||
<div className="header__inner">
|
<div className="header__inner">
|
||||||
<span className="header__logo">
|
<span className="header__logo">
|
||||||
<img src="https://facebook.github.io/react/img/logo.svg" alt="" width="32" height="32" />
|
<img
|
||||||
React Sandbox (v{React.version})
|
src="https://facebook.github.io/react/img/logo.svg"
|
||||||
</span>
|
alt=""
|
||||||
|
width="32"
|
||||||
|
height="32"
|
||||||
|
/>
|
||||||
|
React Sandbox (v{React.version})
|
||||||
|
</span>
|
||||||
|
|
||||||
<div className="header-controls">
|
<div className="header-controls">
|
||||||
<label htmlFor="example">
|
<label htmlFor="example">
|
||||||
<span className="sr-only">Select an example</span>
|
<span className="sr-only">Select an example</span>
|
||||||
<select value={window.location.pathname} onChange={this.handleFixtureChange}>
|
<select
|
||||||
<option value="/">Select a Fixture</option>
|
value={window.location.pathname}
|
||||||
<option value="/range-inputs">Range Inputs</option>
|
onChange={this.handleFixtureChange}>
|
||||||
<option value="/text-inputs">Text Inputs</option>
|
<option value="/">Select a Fixture</option>
|
||||||
<option value="/number-inputs">Number Input</option>
|
<option value="/range-inputs">Range Inputs</option>
|
||||||
<option value="/password-inputs">Password Input</option>
|
<option value="/text-inputs">Text Inputs</option>
|
||||||
<option value="/selects">Selects</option>
|
<option value="/number-inputs">Number Input</option>
|
||||||
<option value="/textareas">Textareas</option>
|
<option value="/password-inputs">Password Input</option>
|
||||||
<option value="/input-change-events">Input change events</option>
|
<option value="/selects">Selects</option>
|
||||||
<option value="/buttons">Buttons</option>
|
<option value="/textareas">Textareas</option>
|
||||||
</select>
|
<option value="/input-change-events">
|
||||||
</label>
|
Input change events
|
||||||
<label htmlFor="react_version">
|
</option>
|
||||||
<span className="sr-only">Select a version to test</span>
|
<option value="/buttons">Buttons</option>
|
||||||
<select
|
</select>
|
||||||
value={this.state.version}
|
</label>
|
||||||
onChange={this.handleVersionChange}>
|
<label htmlFor="react_version">
|
||||||
|
<span className="sr-only">Select a version to test</span>
|
||||||
|
<select
|
||||||
|
value={this.state.version}
|
||||||
|
onChange={this.handleVersionChange}>
|
||||||
{this.state.versions.map(version => (
|
{this.state.versions.map(version => (
|
||||||
<option key={version} value={version}>{version}</option>
|
<option key={version} value={version}>{version}</option>
|
||||||
))}
|
))}
|
||||||
</select>
|
</select>
|
||||||
</label>
|
</label>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</header>
|
||||||
</header>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,14 +2,14 @@ import cn from 'classnames';
|
||||||
import semver from 'semver';
|
import semver from 'semver';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { parse } from 'query-string';
|
import {parse} from 'query-string';
|
||||||
import { semverString } from './propTypes';
|
import {semverString} from './propTypes';
|
||||||
|
|
||||||
const propTypes = {
|
const propTypes = {
|
||||||
children: PropTypes.node.isRequired,
|
children: PropTypes.node.isRequired,
|
||||||
title: PropTypes.node.isRequired,
|
title: PropTypes.node.isRequired,
|
||||||
resolvedIn: semverString,
|
resolvedIn: semverString,
|
||||||
resolvedBy: PropTypes.string
|
resolvedBy: PropTypes.string,
|
||||||
};
|
};
|
||||||
|
|
||||||
class TestCase extends React.Component {
|
class TestCase extends React.Component {
|
||||||
|
|
@ -21,10 +21,10 @@ class TestCase extends React.Component {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
handleChange = (e) => {
|
handleChange = e => {
|
||||||
this.setState({
|
this.setState({
|
||||||
complete: e.target.checked
|
complete: e.target.checked,
|
||||||
})
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
|
@ -37,24 +37,16 @@ class TestCase extends React.Component {
|
||||||
children,
|
children,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
let { complete } = this.state;
|
let {complete} = this.state;
|
||||||
|
|
||||||
const { version } = parse(window.location.search);
|
const {version} = parse(window.location.search);
|
||||||
const isTestRelevant = (
|
const isTestRelevant =
|
||||||
!version ||
|
!version || !resolvedIn || semver.gte(version, resolvedIn);
|
||||||
!resolvedIn ||
|
|
||||||
semver.gte(version, resolvedIn)
|
|
||||||
);
|
|
||||||
|
|
||||||
complete = !isTestRelevant || complete;
|
complete = !isTestRelevant || complete;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section
|
<section className={cn('test-case', complete && 'test-case--complete')}>
|
||||||
className={cn(
|
|
||||||
"test-case",
|
|
||||||
complete && 'test-case--complete'
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
<h2 className="test-case__title type-subheading">
|
<h2 className="test-case__title type-subheading">
|
||||||
<label>
|
<label>
|
||||||
<input
|
<input
|
||||||
|
|
@ -68,31 +60,28 @@ class TestCase extends React.Component {
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
<dl className="test-case__details">
|
<dl className="test-case__details">
|
||||||
{resolvedIn && (
|
{resolvedIn && <dt>First supported in: </dt>}
|
||||||
<dt>First supported in: </dt>)}
|
{resolvedIn &&
|
||||||
{resolvedIn && (
|
|
||||||
<dd>
|
|
||||||
<a href={'https://github.com/facebook/react/tag/v' + resolvedIn}>
|
|
||||||
<code>{resolvedIn}</code>
|
|
||||||
</a>
|
|
||||||
</dd>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{resolvedBy && (
|
|
||||||
<dt>Fixed by: </dt>)}
|
|
||||||
{resolvedBy && (
|
|
||||||
<dd>
|
<dd>
|
||||||
<a href={'https://github.com/facebook/react/pull/' + resolvedBy.slice(1)}>
|
<a href={'https://github.com/facebook/react/tag/v' + resolvedIn}>
|
||||||
|
<code>{resolvedIn}</code>
|
||||||
|
</a>
|
||||||
|
</dd>}
|
||||||
|
|
||||||
|
{resolvedBy && <dt>Fixed by: </dt>}
|
||||||
|
{resolvedBy &&
|
||||||
|
<dd>
|
||||||
|
<a
|
||||||
|
href={
|
||||||
|
'https://github.com/facebook/react/pull/' +
|
||||||
|
resolvedBy.slice(1)
|
||||||
|
}>
|
||||||
<code>{resolvedBy}</code>
|
<code>{resolvedBy}</code>
|
||||||
</a>
|
</a>
|
||||||
</dd>
|
</dd>}
|
||||||
)}
|
|
||||||
|
|
||||||
{affectedBrowsers &&
|
{affectedBrowsers && <dt>Affected browsers: </dt>}
|
||||||
<dt>Affected browsers: </dt>}
|
{affectedBrowsers && <dd>{affectedBrowsers}</dd>}
|
||||||
{affectedBrowsers &&
|
|
||||||
<dd>{affectedBrowsers}</dd>
|
|
||||||
}
|
|
||||||
</dl>
|
</dl>
|
||||||
|
|
||||||
<p className="test-case__desc">
|
<p className="test-case__desc">
|
||||||
|
|
@ -100,12 +89,13 @@ class TestCase extends React.Component {
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div className="test-case__body">
|
<div className="test-case__body">
|
||||||
{!isTestRelevant &&(
|
{!isTestRelevant &&
|
||||||
<p className="test-case__invalid-version">
|
<p className="test-case__invalid-version">
|
||||||
<strong>Note:</strong> This test case was fixed in a later version of React.
|
<strong>Note:</strong>
|
||||||
This test is not expected to pass for the selected version, and that's ok!
|
{' '}
|
||||||
</p>
|
This test case was fixed in a later version of React.
|
||||||
)}
|
This test is not expected to pass for the selected version, and that's ok!
|
||||||
|
</p>}
|
||||||
|
|
||||||
{children}
|
{children}
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -118,7 +108,7 @@ TestCase.propTypes = propTypes;
|
||||||
|
|
||||||
TestCase.Steps = class extends React.Component {
|
TestCase.Steps = class extends React.Component {
|
||||||
render() {
|
render() {
|
||||||
const { children } = this.props;
|
const {children} = this.props;
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<h3>Steps to reproduce:</h3>
|
<h3>Steps to reproduce:</h3>
|
||||||
|
|
@ -126,13 +116,13 @@ TestCase.Steps = class extends React.Component {
|
||||||
{children}
|
{children}
|
||||||
</ol>
|
</ol>
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
TestCase.ExpectedResult = class extends React.Component {
|
TestCase.ExpectedResult = class extends React.Component {
|
||||||
render() {
|
render() {
|
||||||
const { children } = this.props
|
const {children} = this.props;
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<h3>Expected Result:</h3>
|
<h3>Expected Result:</h3>
|
||||||
|
|
@ -140,7 +130,7 @@ TestCase.ExpectedResult = class extends React.Component {
|
||||||
{children}
|
{children}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
export default TestCase
|
export default TestCase;
|
||||||
|
|
|
||||||
|
|
@ -21,10 +21,10 @@ export default class ButtonTestCases extends React.Component {
|
||||||
Nothing should happen
|
Nothing should happen
|
||||||
</TestCase.ExpectedResult>
|
</TestCase.ExpectedResult>
|
||||||
<button disabled onClick={onButtonClick}>Click Me</button>
|
<button disabled onClick={onButtonClick}>Click Me</button>
|
||||||
</TestCase>
|
</TestCase>
|
||||||
<TestCase
|
<TestCase
|
||||||
title="onClick with disabled buttons containing other elements"
|
title="onClick with disabled buttons containing other elements"
|
||||||
description="The onClick event handler should not be invoked when clicking on a disabled button that contains other elements">
|
description="The onClick event handler should not be invoked when clicking on a disabled button that contains other elements">
|
||||||
<TestCase.Steps>
|
<TestCase.Steps>
|
||||||
<li>Click on the disabled button, which contains a span</li>
|
<li>Click on the disabled button, which contains a span</li>
|
||||||
</TestCase.Steps>
|
</TestCase.Steps>
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ function FixturesPage() {
|
||||||
case '/password-inputs':
|
case '/password-inputs':
|
||||||
return <PasswordInputFixtures />;
|
return <PasswordInputFixtures />;
|
||||||
case '/buttons':
|
case '/buttons':
|
||||||
return <ButtonFixtures />
|
return <ButtonFixtures />;
|
||||||
default:
|
default:
|
||||||
return <p>Please select a test fixture.</p>;
|
return <p>Please select a test fixture.</p>;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,6 @@ import React from 'react';
|
||||||
|
|
||||||
import Fixture from '../../Fixture';
|
import Fixture from '../../Fixture';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class InputPlaceholderFixture extends React.Component {
|
class InputPlaceholderFixture extends React.Component {
|
||||||
constructor(props, context) {
|
constructor(props, context) {
|
||||||
super(props, context);
|
super(props, context);
|
||||||
|
|
@ -15,32 +13,32 @@ class InputPlaceholderFixture extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
handleChange = () => {
|
handleChange = () => {
|
||||||
this.setState(({ changeCount }) => {
|
this.setState(({changeCount}) => {
|
||||||
return {
|
return {
|
||||||
changeCount: changeCount + 1
|
changeCount: changeCount + 1,
|
||||||
}
|
};
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
handleGeneratePlaceholder = () => {
|
handleGeneratePlaceholder = () => {
|
||||||
this.setState({
|
this.setState({
|
||||||
placeholder: `A placeholder: ${Math.random() * 100}`
|
placeholder: `A placeholder: ${Math.random() * 100}`,
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
handleReset = () => {
|
handleReset = () => {
|
||||||
this.setState({
|
this.setState({
|
||||||
changeCount: 0,
|
changeCount: 0,
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { placeholder, changeCount } = this.state;
|
const {placeholder, changeCount} = this.state;
|
||||||
const color = changeCount === 0 ? 'green' : 'red';
|
const color = changeCount === 0 ? 'green' : 'red';
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Fixture>
|
<Fixture>
|
||||||
<input
|
<input
|
||||||
type='text'
|
type="text"
|
||||||
placeholder={placeholder}
|
placeholder={placeholder}
|
||||||
onChange={this.handleChange}
|
onChange={this.handleChange}
|
||||||
/>
|
/>
|
||||||
|
|
@ -49,12 +47,12 @@ class InputPlaceholderFixture extends React.Component {
|
||||||
Change placeholder
|
Change placeholder
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<p style={{ color }}>
|
<p style={{color}}>
|
||||||
<code>onChange</code>{' calls: '}<strong>{changeCount}</strong>
|
<code>onChange</code>{' calls: '}<strong>{changeCount}</strong>
|
||||||
</p>
|
</p>
|
||||||
<button onClick={this.handleReset}>Reset count</button>
|
<button onClick={this.handleReset}>Reset count</button>
|
||||||
</Fixture>
|
</Fixture>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,40 +12,36 @@ class RadioClickFixture extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
handleChange = () => {
|
handleChange = () => {
|
||||||
this.setState(({ changeCount }) => {
|
this.setState(({changeCount}) => {
|
||||||
return {
|
return {
|
||||||
changeCount: changeCount + 1
|
changeCount: changeCount + 1,
|
||||||
}
|
};
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
handleReset = () => {
|
handleReset = () => {
|
||||||
this.setState({
|
this.setState({
|
||||||
changeCount: 0,
|
changeCount: 0,
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { changeCount } = this.state;
|
const {changeCount} = this.state;
|
||||||
const color = changeCount === 0 ? 'green' : 'red';
|
const color = changeCount === 0 ? 'green' : 'red';
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Fixture>
|
<Fixture>
|
||||||
<label>
|
<label>
|
||||||
<input
|
<input defaultChecked type="radio" onChange={this.handleChange} />
|
||||||
defaultChecked
|
|
||||||
type='radio'
|
|
||||||
onChange={this.handleChange}
|
|
||||||
/>
|
|
||||||
Test case radio input
|
Test case radio input
|
||||||
</label>
|
</label>
|
||||||
{' '}
|
{' '}
|
||||||
<p style={{ color }}>
|
<p style={{color}}>
|
||||||
<code>onChange</code>{' calls: '}<strong>{changeCount}</strong>
|
<code>onChange</code>{' calls: '}<strong>{changeCount}</strong>
|
||||||
</p>
|
</p>
|
||||||
<button onClick={this.handleReset}>Reset count</button>
|
<button onClick={this.handleReset}>Reset count</button>
|
||||||
</Fixture>
|
</Fixture>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ import React from 'react';
|
||||||
|
|
||||||
import Fixture from '../../Fixture';
|
import Fixture from '../../Fixture';
|
||||||
|
|
||||||
|
|
||||||
class RangeKeyboardFixture extends React.Component {
|
class RangeKeyboardFixture extends React.Component {
|
||||||
constructor(props, context) {
|
constructor(props, context) {
|
||||||
super(props, context);
|
super(props, context);
|
||||||
|
|
@ -14,61 +13,60 @@ class RangeKeyboardFixture extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.input.addEventListener('keydown', this.handleKeydown, false)
|
this.input.addEventListener('keydown', this.handleKeydown, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
this.input.removeEventListener('keydown', this.handleKeydown, false)
|
this.input.removeEventListener('keydown', this.handleKeydown, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
handleChange = () => {
|
handleChange = () => {
|
||||||
this.setState(({ changeCount }) => {
|
this.setState(({changeCount}) => {
|
||||||
return {
|
return {
|
||||||
changeCount: changeCount + 1
|
changeCount: changeCount + 1,
|
||||||
}
|
};
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
handleKeydown = (e) => {
|
handleKeydown = e => {
|
||||||
// only interesting in arrow key events
|
// only interesting in arrow key events
|
||||||
if (![37, 38, 39, 40].includes(e.keyCode))
|
if (![37, 38, 39, 40].includes(e.keyCode)) return;
|
||||||
return;
|
|
||||||
|
|
||||||
this.setState(({ keydownCount }) => {
|
this.setState(({keydownCount}) => {
|
||||||
return {
|
return {
|
||||||
keydownCount: keydownCount + 1
|
keydownCount: keydownCount + 1,
|
||||||
}
|
};
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
handleReset = () => {
|
handleReset = () => {
|
||||||
this.setState({
|
this.setState({
|
||||||
keydownCount: 0,
|
keydownCount: 0,
|
||||||
changeCount: 0,
|
changeCount: 0,
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { keydownCount, changeCount } = this.state;
|
const {keydownCount, changeCount} = this.state;
|
||||||
const color = keydownCount === changeCount ? 'green' : 'red';
|
const color = keydownCount === changeCount ? 'green' : 'red';
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Fixture>
|
<Fixture>
|
||||||
<input
|
<input
|
||||||
type='range'
|
type="range"
|
||||||
ref={r => this.input = r}
|
ref={r => (this.input = r)}
|
||||||
onChange={this.handleChange}
|
onChange={this.handleChange}
|
||||||
/>
|
/>
|
||||||
{' '}
|
{' '}
|
||||||
|
|
||||||
<p style={{ color }}>
|
<p style={{color}}>
|
||||||
<code>onKeyDown</code>{' calls: '}<strong>{keydownCount}</strong>
|
<code>onKeyDown</code>{' calls: '}<strong>{keydownCount}</strong>
|
||||||
{' vs '}
|
{' vs '}
|
||||||
<code>onChange</code>{' calls: '}<strong>{changeCount}</strong>
|
<code>onChange</code>{' calls: '}<strong>{changeCount}</strong>
|
||||||
</p>
|
</p>
|
||||||
<button onClick={this.handleReset}>Reset counts</button>
|
<button onClick={this.handleReset}>Reset counts</button>
|
||||||
</Fixture>
|
</Fixture>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,14 +11,12 @@ class InputChangeEvents extends React.Component {
|
||||||
return (
|
return (
|
||||||
<FixtureSet
|
<FixtureSet
|
||||||
title="Input change events"
|
title="Input change events"
|
||||||
description="Tests proper behavior of the onChange event for inputs"
|
description="Tests proper behavior of the onChange event for inputs">
|
||||||
>
|
|
||||||
<TestCase
|
<TestCase
|
||||||
title="Range keyboard changes"
|
title="Range keyboard changes"
|
||||||
description={`
|
description={`
|
||||||
Range inputs should fire onChange events for keyboard events
|
Range inputs should fire onChange events for keyboard events
|
||||||
`}
|
`}>
|
||||||
>
|
|
||||||
<TestCase.Steps>
|
<TestCase.Steps>
|
||||||
<li>Focus range input</li>
|
<li>Focus range input</li>
|
||||||
<li>change value via the keyboard arrow keys</li>
|
<li>change value via the keyboard arrow keys</li>
|
||||||
|
|
@ -38,8 +36,7 @@ class InputChangeEvents extends React.Component {
|
||||||
Radio inputs should only fire change events when the checked
|
Radio inputs should only fire change events when the checked
|
||||||
state changes.
|
state changes.
|
||||||
`}
|
`}
|
||||||
resolvedIn="16.0.0"
|
resolvedIn="16.0.0">
|
||||||
>
|
|
||||||
<TestCase.Steps>
|
<TestCase.Steps>
|
||||||
<li>Click on the Radio input (or label text)</li>
|
<li>Click on the Radio input (or label text)</li>
|
||||||
</TestCase.Steps>
|
</TestCase.Steps>
|
||||||
|
|
@ -59,8 +56,7 @@ class InputChangeEvents extends React.Component {
|
||||||
`}
|
`}
|
||||||
resolvedIn="15.0.0"
|
resolvedIn="15.0.0"
|
||||||
resolvedBy="#5004"
|
resolvedBy="#5004"
|
||||||
affectedBrowsers="IE9+"
|
affectedBrowsers="IE9+">
|
||||||
>
|
|
||||||
<TestCase.Steps>
|
<TestCase.Steps>
|
||||||
<li>Click on the Text input</li>
|
<li>Click on the Text input</li>
|
||||||
<li>Click on the "Change placeholder" button</li>
|
<li>Click on the "Change placeholder" button</li>
|
||||||
|
|
@ -77,5 +73,4 @@ class InputChangeEvents extends React.Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default InputChangeEvents;
|
||||||
export default InputChangeEvents
|
|
||||||
|
|
|
||||||
|
|
@ -3,12 +3,12 @@ const React = window.React;
|
||||||
import Fixture from '../../Fixture';
|
import Fixture from '../../Fixture';
|
||||||
|
|
||||||
class NumberInputDecimal extends React.Component {
|
class NumberInputDecimal extends React.Component {
|
||||||
state = { value: '.98' };
|
state = {value: '.98'};
|
||||||
changeValue = () => {
|
changeValue = () => {
|
||||||
this.setState({
|
this.setState({
|
||||||
value: '0.98',
|
value: '0.98',
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
render() {
|
render() {
|
||||||
const {value} = this.state;
|
const {value} = this.state;
|
||||||
return (
|
return (
|
||||||
|
|
@ -19,8 +19,8 @@ class NumberInputDecimal extends React.Component {
|
||||||
<input
|
<input
|
||||||
type="number"
|
type="number"
|
||||||
value={value}
|
value={value}
|
||||||
onChange={(e) => {
|
onChange={e => {
|
||||||
this.setState({value: e.target.value});
|
this.setState({value: e.target.value});
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<button onClick={this.changeValue}>change.98 to 0.98</button>
|
<button onClick={this.changeValue}>change.98 to 0.98</button>
|
||||||
|
|
|
||||||
|
|
@ -3,17 +3,17 @@ const React = window.React;
|
||||||
import Fixture from '../../Fixture';
|
import Fixture from '../../Fixture';
|
||||||
|
|
||||||
class NumberInputExtraZeroes extends React.Component {
|
class NumberInputExtraZeroes extends React.Component {
|
||||||
state = { value: '3.0000' }
|
state = {value: '3.0000'};
|
||||||
changeValue = () => {
|
changeValue = () => {
|
||||||
this.setState({
|
this.setState({
|
||||||
value: '3.0000'
|
value: '3.0000',
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
onChange = event => {
|
onChange = event => {
|
||||||
this.setState({ value: event.target.value });
|
this.setState({value: event.target.value});
|
||||||
}
|
};
|
||||||
render() {
|
render() {
|
||||||
const { value } = this.state
|
const {value} = this.state;
|
||||||
return (
|
return (
|
||||||
<Fixture>
|
<Fixture>
|
||||||
<div>{this.props.children}</div>
|
<div>{this.props.children}</div>
|
||||||
|
|
|
||||||
|
|
@ -3,13 +3,13 @@ const React = window.React;
|
||||||
import Fixture from '../../Fixture';
|
import Fixture from '../../Fixture';
|
||||||
|
|
||||||
class NumberTestCase extends React.Component {
|
class NumberTestCase extends React.Component {
|
||||||
state = { value: '' };
|
state = {value: ''};
|
||||||
onChange = (event) => {
|
onChange = event => {
|
||||||
const parsed = parseFloat(event.target.value, 10)
|
const parsed = parseFloat(event.target.value, 10);
|
||||||
const value = isNaN(parsed) ? '' : parsed
|
const value = isNaN(parsed) ? '' : parsed;
|
||||||
|
|
||||||
this.setState({ value })
|
this.setState({value});
|
||||||
}
|
};
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<Fixture>
|
<Fixture>
|
||||||
|
|
@ -18,8 +18,14 @@ class NumberTestCase extends React.Component {
|
||||||
<div className="control-box">
|
<div className="control-box">
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>Controlled</legend>
|
<legend>Controlled</legend>
|
||||||
<input type="number" value={this.state.value} onChange={this.onChange} />
|
<input
|
||||||
<span className="hint"> Value: {JSON.stringify(this.state.value)}</span>
|
type="number"
|
||||||
|
value={this.state.value}
|
||||||
|
onChange={this.onChange}
|
||||||
|
/>
|
||||||
|
<span className="hint">
|
||||||
|
{' '}Value: {JSON.stringify(this.state.value)}
|
||||||
|
</span>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
<fieldset>
|
<fieldset>
|
||||||
|
|
|
||||||
|
|
@ -9,14 +9,12 @@ import NumberInputExtraZeroes from './NumberInputExtraZeroes';
|
||||||
function NumberInputs() {
|
function NumberInputs() {
|
||||||
return (
|
return (
|
||||||
<FixtureSet
|
<FixtureSet
|
||||||
title="Number inputs"
|
title="Number inputs"
|
||||||
description="Number inputs inconsistently assign and report the value
|
description="Number inputs inconsistently assign and report the value
|
||||||
property depending on the browser."
|
property depending on the browser.">
|
||||||
>
|
|
||||||
<TestCase
|
<TestCase
|
||||||
title="Backspacing"
|
title="Backspacing"
|
||||||
description="The decimal place should not be lost"
|
description="The decimal place should not be lost">
|
||||||
>
|
|
||||||
<TestCase.Steps>
|
<TestCase.Steps>
|
||||||
<li>Type "3.1"</li>
|
<li>Type "3.1"</li>
|
||||||
<li>Press backspace, eliminating the "1"</li>
|
<li>Press backspace, eliminating the "1"</li>
|
||||||
|
|
@ -36,9 +34,8 @@ function NumberInputs() {
|
||||||
</TestCase>
|
</TestCase>
|
||||||
|
|
||||||
<TestCase
|
<TestCase
|
||||||
title="Decimal precision"
|
title="Decimal precision"
|
||||||
description="Supports decimal precision greater than 2 places"
|
description="Supports decimal precision greater than 2 places">
|
||||||
>
|
|
||||||
<TestCase.Steps>
|
<TestCase.Steps>
|
||||||
<li>Type "0.01"</li>
|
<li>Type "0.01"</li>
|
||||||
</TestCase.Steps>
|
</TestCase.Steps>
|
||||||
|
|
@ -51,9 +48,8 @@ function NumberInputs() {
|
||||||
</TestCase>
|
</TestCase>
|
||||||
|
|
||||||
<TestCase
|
<TestCase
|
||||||
title="Exponent form"
|
title="Exponent form"
|
||||||
description="Supports exponent form ('2e4')"
|
description="Supports exponent form ('2e4')">
|
||||||
>
|
|
||||||
<TestCase.Steps>
|
<TestCase.Steps>
|
||||||
<li>Type "2e"</li>
|
<li>Type "2e"</li>
|
||||||
<li>Type 4, to read "2e4"</li>
|
<li>Type 4, to read "2e4"</li>
|
||||||
|
|
@ -66,10 +62,7 @@ function NumberInputs() {
|
||||||
<NumberTestCase />
|
<NumberTestCase />
|
||||||
</TestCase>
|
</TestCase>
|
||||||
|
|
||||||
<TestCase
|
<TestCase title="Exponent Form" description="Pressing 'e' at the end">
|
||||||
title="Exponent Form"
|
|
||||||
description="Pressing 'e' at the end"
|
|
||||||
>
|
|
||||||
<TestCase.Steps>
|
<TestCase.Steps>
|
||||||
<li>Type "3.14"</li>
|
<li>Type "3.14"</li>
|
||||||
<li>Press "e", so that the input reads "3.14e"</li>
|
<li>Press "e", so that the input reads "3.14e"</li>
|
||||||
|
|
@ -83,9 +76,8 @@ function NumberInputs() {
|
||||||
</TestCase>
|
</TestCase>
|
||||||
|
|
||||||
<TestCase
|
<TestCase
|
||||||
title="Exponent Form"
|
title="Exponent Form"
|
||||||
description="Supports pressing 'ee' in the middle of a number"
|
description="Supports pressing 'ee' in the middle of a number">
|
||||||
>
|
|
||||||
<TestCase.Steps>
|
<TestCase.Steps>
|
||||||
<li>Type "3.14"</li>
|
<li>Type "3.14"</li>
|
||||||
<li>Move the text cursor to after the decimal place</li>
|
<li>Move the text cursor to after the decimal place</li>
|
||||||
|
|
@ -100,9 +92,8 @@ function NumberInputs() {
|
||||||
</TestCase>
|
</TestCase>
|
||||||
|
|
||||||
<TestCase
|
<TestCase
|
||||||
title="Trailing Zeroes"
|
title="Trailing Zeroes"
|
||||||
description="Typing '3.0' preserves the trailing zero"
|
description="Typing '3.0' preserves the trailing zero">
|
||||||
>
|
|
||||||
<TestCase.Steps>
|
<TestCase.Steps>
|
||||||
<li>Type "3.0"</li>
|
<li>Type "3.0"</li>
|
||||||
</TestCase.Steps>
|
</TestCase.Steps>
|
||||||
|
|
@ -115,9 +106,8 @@ function NumberInputs() {
|
||||||
</TestCase>
|
</TestCase>
|
||||||
|
|
||||||
<TestCase
|
<TestCase
|
||||||
title="Inserting decimals precision"
|
title="Inserting decimals precision"
|
||||||
description="Inserting '.' in to '300' maintains the trailing zeroes"
|
description="Inserting '.' in to '300' maintains the trailing zeroes">
|
||||||
>
|
|
||||||
<TestCase.Steps>
|
<TestCase.Steps>
|
||||||
<li>Type "300"</li>
|
<li>Type "300"</li>
|
||||||
<li>Move the cursor to after the "3"</li>
|
<li>Move the cursor to after the "3"</li>
|
||||||
|
|
@ -131,9 +121,8 @@ function NumberInputs() {
|
||||||
</TestCase>
|
</TestCase>
|
||||||
|
|
||||||
<TestCase
|
<TestCase
|
||||||
title="Replacing numbers with -"
|
title="Replacing numbers with -"
|
||||||
description="Replacing a number with the '-' sign should not clear the value"
|
description="Replacing a number with the '-' sign should not clear the value">
|
||||||
>
|
|
||||||
<TestCase.Steps>
|
<TestCase.Steps>
|
||||||
<li>Type "3"</li>
|
<li>Type "3"</li>
|
||||||
<li>Select the entire value"</li>
|
<li>Select the entire value"</li>
|
||||||
|
|
@ -147,9 +136,8 @@ function NumberInputs() {
|
||||||
</TestCase>
|
</TestCase>
|
||||||
|
|
||||||
<TestCase
|
<TestCase
|
||||||
title="Negative numbers"
|
title="Negative numbers"
|
||||||
description="Typing minus when inserting a negative number should work"
|
description="Typing minus when inserting a negative number should work">
|
||||||
>
|
|
||||||
<TestCase.Steps>
|
<TestCase.Steps>
|
||||||
<li>Type "-"</li>
|
<li>Type "-"</li>
|
||||||
<li>Type '3'</li>
|
<li>Type '3'</li>
|
||||||
|
|
@ -161,9 +149,8 @@ function NumberInputs() {
|
||||||
<NumberTestCase />
|
<NumberTestCase />
|
||||||
</TestCase>
|
</TestCase>
|
||||||
<TestCase
|
<TestCase
|
||||||
title="Decimal numbers"
|
title="Decimal numbers"
|
||||||
description="eg: initial value is '.98', when format to '0.98', should change to '0.98' "
|
description="eg: initial value is '.98', when format to '0.98', should change to '0.98' ">
|
||||||
>
|
|
||||||
<TestCase.Steps>
|
<TestCase.Steps>
|
||||||
<li>initial value is '.98'</li>
|
<li>initial value is '.98'</li>
|
||||||
<li>setState to '0.98'</li>
|
<li>setState to '0.98'</li>
|
||||||
|
|
@ -177,8 +164,7 @@ function NumberInputs() {
|
||||||
|
|
||||||
<TestCase
|
<TestCase
|
||||||
title="Trailing zeroes"
|
title="Trailing zeroes"
|
||||||
description="Extraneous zeroes should be retained when changing the value via setState"
|
description="Extraneous zeroes should be retained when changing the value via setState">
|
||||||
>
|
|
||||||
<TestCase.Steps>
|
<TestCase.Steps>
|
||||||
<li>Change the text to 4.0000</li>
|
<li>Change the text to 4.0000</li>
|
||||||
<li>Click "Reset to 3.0000"</li>
|
<li>Click "Reset to 3.0000"</li>
|
||||||
|
|
@ -193,9 +179,12 @@ function NumberInputs() {
|
||||||
<p className="footnote">
|
<p className="footnote">
|
||||||
<b>Notes:</b> Firefox drops extraneous zeroes when
|
<b>Notes:</b> Firefox drops extraneous zeroes when
|
||||||
assigned. Zeroes are preserved when editing, however
|
assigned. Zeroes are preserved when editing, however
|
||||||
directly assigning a new value will drop zeroes. This <a
|
directly assigning a new value will drop zeroes. This
|
||||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=1003896">is
|
{' '}
|
||||||
a bug in Firefox</a> that we can not control for.
|
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1003896">
|
||||||
|
is
|
||||||
|
a bug in Firefox
|
||||||
|
</a> that we can not control for.
|
||||||
</p>
|
</p>
|
||||||
</TestCase>
|
</TestCase>
|
||||||
</FixtureSet>
|
</FixtureSet>
|
||||||
|
|
|
||||||
|
|
@ -3,10 +3,10 @@ const React = window.React;
|
||||||
import Fixture from '../../Fixture';
|
import Fixture from '../../Fixture';
|
||||||
|
|
||||||
class PasswordTestCase extends React.Component {
|
class PasswordTestCase extends React.Component {
|
||||||
state = { value: '' };
|
state = {value: ''};
|
||||||
onChange = (event) => {
|
onChange = event => {
|
||||||
this.setState({ value: event.target.value })
|
this.setState({value: event.target.value});
|
||||||
}
|
};
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<Fixture>
|
<Fixture>
|
||||||
|
|
@ -15,8 +15,14 @@ class PasswordTestCase extends React.Component {
|
||||||
<div className="control-box">
|
<div className="control-box">
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>Controlled</legend>
|
<legend>Controlled</legend>
|
||||||
<input type="password" value={this.state.value} onChange={this.onChange} />
|
<input
|
||||||
<span className="hint"> Value: {JSON.stringify(this.state.value)}</span>
|
type="password"
|
||||||
|
value={this.state.value}
|
||||||
|
onChange={this.onChange}
|
||||||
|
/>
|
||||||
|
<span className="hint">
|
||||||
|
{' '}Value: {JSON.stringify(this.state.value)}
|
||||||
|
</span>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
<fieldset>
|
<fieldset>
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ const React = window.React;
|
||||||
|
|
||||||
import FixtureSet from '../../FixtureSet';
|
import FixtureSet from '../../FixtureSet';
|
||||||
import TestCase from '../../TestCase';
|
import TestCase from '../../TestCase';
|
||||||
import PasswordTestCase from './PasswordTestCase'
|
import PasswordTestCase from './PasswordTestCase';
|
||||||
|
|
||||||
function NumberInputs() {
|
function NumberInputs() {
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,20 @@
|
||||||
const React = window.React;
|
const React = window.React;
|
||||||
|
|
||||||
class RangeInputs extends React.Component {
|
class RangeInputs extends React.Component {
|
||||||
state = { value: 0.5 };
|
state = {value: 0.5};
|
||||||
onChange = (event) => {
|
onChange = event => {
|
||||||
this.setState({ value: event.target.value });
|
this.setState({value: event.target.value});
|
||||||
}
|
};
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<form>
|
<form>
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>Controlled</legend>
|
<legend>Controlled</legend>
|
||||||
<input type="range" value={this.state.value} onChange={this.onChange} />
|
<input
|
||||||
|
type="range"
|
||||||
|
value={this.state.value}
|
||||||
|
onChange={this.onChange}
|
||||||
|
/>
|
||||||
<span className="hint">Value: {this.state.value}</span>
|
<span className="hint">Value: {this.state.value}</span>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
const React = window.React;
|
const React = window.React;
|
||||||
|
|
||||||
class SelectFixture extends React.Component {
|
class SelectFixture extends React.Component {
|
||||||
state = { value: '' };
|
state = {value: ''};
|
||||||
onChange = (event) => {
|
onChange = event => {
|
||||||
this.setState({ value: event.target.value });
|
this.setState({value: event.target.value});
|
||||||
}
|
};
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<form>
|
<form>
|
||||||
|
|
|
||||||
|
|
@ -6,35 +6,35 @@ class InputTestCase extends React.Component {
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
type: 'text',
|
type: 'text',
|
||||||
defaultValue: '',
|
defaultValue: '',
|
||||||
parseAs: 'text'
|
parseAs: 'text',
|
||||||
}
|
};
|
||||||
|
|
||||||
constructor () {
|
constructor() {
|
||||||
super(...arguments);
|
super(...arguments);
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
value: this.props.defaultValue
|
value: this.props.defaultValue,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
onChange = (event) => {
|
onChange = event => {
|
||||||
const raw = event.target.value;
|
const raw = event.target.value;
|
||||||
|
|
||||||
switch (this.props.type) {
|
switch (this.props.type) {
|
||||||
case 'number':
|
case 'number':
|
||||||
const parsed = parseFloat(event.target.value, 10);
|
const parsed = parseFloat(event.target.value, 10);
|
||||||
|
|
||||||
this.setState({ value: isNaN(parsed) ? '' : parsed });
|
this.setState({value: isNaN(parsed) ? '' : parsed});
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
this.setState({ value: raw });
|
this.setState({value: raw});
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { children, type, defaultValue } = this.props;
|
const {children, type, defaultValue} = this.props;
|
||||||
const { value } = this.state;
|
const {value} = this.state;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Fixture>
|
<Fixture>
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,7 @@ class TextInputFixtures extends React.Component {
|
||||||
return (
|
return (
|
||||||
<FixtureSet
|
<FixtureSet
|
||||||
title="Inputs"
|
title="Inputs"
|
||||||
description="Common behavior across controled and uncontrolled inputs"
|
description="Common behavior across controled and uncontrolled inputs">
|
||||||
>
|
|
||||||
<TestCase title="Numbers in a controlled text field with no handler">
|
<TestCase title="Numbers in a controlled text field with no handler">
|
||||||
<TestCase.Steps>
|
<TestCase.Steps>
|
||||||
<li>Move the cursor to after "2" in the text field</li>
|
<li>Move the cursor to after "2" in the text field</li>
|
||||||
|
|
@ -31,7 +30,7 @@ class TextInputFixtures extends React.Component {
|
||||||
|
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>Value as string</legend>
|
<legend>Value as string</legend>
|
||||||
<input value={"2"} onChange={() => {}} />
|
<input value={'2'} onChange={() => {}} />
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</div>
|
</div>
|
||||||
</Fixture>
|
</Fixture>
|
||||||
|
|
@ -73,13 +72,16 @@ class TextInputFixtures extends React.Component {
|
||||||
|
|
||||||
<TestCase title="All inputs" description="General test of all inputs">
|
<TestCase title="All inputs" description="General test of all inputs">
|
||||||
<InputTestCase type="text" defaultValue="Text" />
|
<InputTestCase type="text" defaultValue="Text" />
|
||||||
<InputTestCase type="email" defaultValue="user@example.com"/>
|
<InputTestCase type="email" defaultValue="user@example.com" />
|
||||||
<InputTestCase type="number" defaultValue={0} />
|
<InputTestCase type="number" defaultValue={0} />
|
||||||
<InputTestCase type="url" defaultValue="http://example.com"/>
|
<InputTestCase type="url" defaultValue="http://example.com" />
|
||||||
<InputTestCase type="tel" defaultValue="555-555-5555"/>
|
<InputTestCase type="tel" defaultValue="555-555-5555" />
|
||||||
<InputTestCase type="color" defaultValue="#ff0000" />
|
<InputTestCase type="color" defaultValue="#ff0000" />
|
||||||
<InputTestCase type="date" defaultValue="2017-01-01" />
|
<InputTestCase type="date" defaultValue="2017-01-01" />
|
||||||
<InputTestCase type="datetime-local" defaultValue="2017-01-01T01:00" />
|
<InputTestCase
|
||||||
|
type="datetime-local"
|
||||||
|
defaultValue="2017-01-01T01:00"
|
||||||
|
/>
|
||||||
<InputTestCase type="time" defaultValue="01:00" />
|
<InputTestCase type="time" defaultValue="01:00" />
|
||||||
<InputTestCase type="month" defaultValue="2017-01" />
|
<InputTestCase type="month" defaultValue="2017-01" />
|
||||||
<InputTestCase type="week" defaultValue="2017-W01" />
|
<InputTestCase type="week" defaultValue="2017-W01" />
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
const React = window.React;
|
const React = window.React;
|
||||||
|
|
||||||
class TextAreaFixtures extends React.Component {
|
class TextAreaFixtures extends React.Component {
|
||||||
state = { value: '' };
|
state = {value: ''};
|
||||||
onChange = (event) => {
|
onChange = event => {
|
||||||
this.setState({ value: event.target.value });
|
this.setState({value: event.target.value});
|
||||||
}
|
};
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,15 @@
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import semver from 'semver';
|
import semver from 'semver';
|
||||||
|
|
||||||
export function semverString (props, propName, componentName) {
|
export function semverString(props, propName, componentName) {
|
||||||
let version = props[propName];
|
let version = props[propName];
|
||||||
|
|
||||||
let error = PropTypes.string(...arguments);
|
let error = PropTypes.string(...arguments);
|
||||||
if (!error && version != null && !semver.valid(version))
|
if (!error && version != null && !semver.valid(version))
|
||||||
error = new Error(
|
error = new Error(
|
||||||
`\`${propName}\` should be a valid "semantic version" matching ` +
|
`\`${propName}\` should be a valid "semantic version" matching ` +
|
||||||
'an existing React version'
|
'an existing React version',
|
||||||
);
|
);
|
||||||
|
|
||||||
return error || null;
|
return error || null;
|
||||||
};
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,4 @@ const React = window.React;
|
||||||
const ReactDOM = window.ReactDOM;
|
const ReactDOM = window.ReactDOM;
|
||||||
import App from './components/App';
|
import App from './components/App';
|
||||||
|
|
||||||
ReactDOM.render(
|
ReactDOM.render(<App />, document.getElementById('root'));
|
||||||
<App />,
|
|
||||||
document.getElementById('root')
|
|
||||||
);
|
|
||||||
|
|
|
||||||
|
|
@ -21,15 +21,15 @@ const fallbackTags = [
|
||||||
'15.1.0',
|
'15.1.0',
|
||||||
'15.0.2',
|
'15.0.2',
|
||||||
'0.14.8',
|
'0.14.8',
|
||||||
'0.13.0'
|
'0.13.0',
|
||||||
].map(version => ({
|
].map(version => ({
|
||||||
name: `v${version}`
|
name: `v${version}`,
|
||||||
}))
|
}));
|
||||||
|
|
||||||
let canUseSessionStorage = true;
|
let canUseSessionStorage = true;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
sessionStorage.setItem('foo', '')
|
sessionStorage.setItem('foo', '');
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
canUseSessionStorage = false;
|
canUseSessionStorage = false;
|
||||||
}
|
}
|
||||||
|
|
@ -43,7 +43,7 @@ try {
|
||||||
* the request is async, even if its loaded from sessionStorage.
|
* the request is async, even if its loaded from sessionStorage.
|
||||||
*/
|
*/
|
||||||
export default function getVersionTags() {
|
export default function getVersionTags() {
|
||||||
return new Promise((resolve) => {
|
return new Promise(resolve => {
|
||||||
let cachedTags;
|
let cachedTags;
|
||||||
if (canUseSessionStorage) {
|
if (canUseSessionStorage) {
|
||||||
cachedTags = sessionStorage.getItem(TAGS_CACHE_KEY);
|
cachedTags = sessionStorage.getItem(TAGS_CACHE_KEY);
|
||||||
|
|
@ -52,19 +52,19 @@ export default function getVersionTags() {
|
||||||
cachedTags = JSON.parse(cachedTags);
|
cachedTags = JSON.parse(cachedTags);
|
||||||
resolve(cachedTags);
|
resolve(cachedTags);
|
||||||
} else {
|
} else {
|
||||||
fetch('https://api.github.com/repos/facebook/react/tags', { mode: 'cors' })
|
fetch('https://api.github.com/repos/facebook/react/tags', {mode: 'cors'})
|
||||||
.then(res => res.json())
|
.then(res => res.json())
|
||||||
.then(tags => {
|
.then(tags => {
|
||||||
// A message property indicates an error was sent from the API
|
// A message property indicates an error was sent from the API
|
||||||
if (tags.message) {
|
if (tags.message) {
|
||||||
return resolve(fallbackTags)
|
return resolve(fallbackTags);
|
||||||
}
|
}
|
||||||
if (canUseSessionStorage) {
|
if (canUseSessionStorage) {
|
||||||
sessionStorage.setItem(TAGS_CACHE_KEY, JSON.stringify(tags))
|
sessionStorage.setItem(TAGS_CACHE_KEY, JSON.stringify(tags));
|
||||||
}
|
}
|
||||||
resolve(tags)
|
resolve(tags);
|
||||||
})
|
})
|
||||||
.catch(() => resolve(fallbackTags))
|
.catch(() => resolve(fallbackTags));
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { Component } from 'react';
|
import React, {Component} from 'react';
|
||||||
import Draggable from 'react-draggable';
|
import Draggable from 'react-draggable';
|
||||||
import ReactNoop from 'react-noop-renderer';
|
import ReactNoop from 'react-noop-renderer';
|
||||||
import Editor from './Editor';
|
import Editor from './Editor';
|
||||||
|
|
@ -6,7 +6,9 @@ import Fibers from './Fibers';
|
||||||
import describeFibers from './describeFibers';
|
import describeFibers from './describeFibers';
|
||||||
|
|
||||||
// The only place where we use it.
|
// The only place where we use it.
|
||||||
const ReactFiberInstrumentation = ReactNoop.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactFiberInstrumentation;
|
const ReactFiberInstrumentation =
|
||||||
|
ReactNoop.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED
|
||||||
|
.ReactFiberInstrumentation;
|
||||||
|
|
||||||
function getFiberState(root, workInProgress) {
|
function getFiberState(root, workInProgress) {
|
||||||
if (!root) {
|
if (!root) {
|
||||||
|
|
@ -40,8 +42,8 @@ class App extends Component {
|
||||||
return: false,
|
return: false,
|
||||||
fx: false,
|
fx: false,
|
||||||
progressedChild: false,
|
progressedChild: false,
|
||||||
progressedDel: false
|
progressedDel: false,
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -57,49 +59,52 @@ class App extends Component {
|
||||||
ReactNoop.render(null);
|
ReactNoop.render(null);
|
||||||
ReactNoop.flush();
|
ReactNoop.flush();
|
||||||
ReactFiberInstrumentation.debugTool = {
|
ReactFiberInstrumentation.debugTool = {
|
||||||
onMountContainer: (root) => {
|
onMountContainer: root => {
|
||||||
currentRoot = root;
|
currentRoot = root;
|
||||||
},
|
},
|
||||||
onUpdateContainer: (root) => {
|
onUpdateContainer: root => {
|
||||||
currentRoot = root;
|
currentRoot = root;
|
||||||
},
|
},
|
||||||
onBeginWork: (fiber) => {
|
onBeginWork: fiber => {
|
||||||
const fibers = getFiberState(currentRoot, fiber);
|
const fibers = getFiberState(currentRoot, fiber);
|
||||||
const stage = currentStage;
|
const stage = currentStage;
|
||||||
this.setState(({ history }) => ({
|
this.setState(({history}) => ({
|
||||||
history: [
|
history: [
|
||||||
...history, {
|
...history,
|
||||||
|
{
|
||||||
action: 'BEGIN',
|
action: 'BEGIN',
|
||||||
fibers,
|
fibers,
|
||||||
stage
|
stage,
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
onCompleteWork: (fiber) => {
|
onCompleteWork: fiber => {
|
||||||
const fibers = getFiberState(currentRoot, fiber);
|
const fibers = getFiberState(currentRoot, fiber);
|
||||||
const stage = currentStage;
|
const stage = currentStage;
|
||||||
this.setState(({ history }) => ({
|
this.setState(({history}) => ({
|
||||||
history: [
|
history: [
|
||||||
...history, {
|
...history,
|
||||||
|
{
|
||||||
action: 'COMPLETE',
|
action: 'COMPLETE',
|
||||||
fibers,
|
fibers,
|
||||||
stage
|
stage,
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
onCommitWork: (fiber) => {
|
onCommitWork: fiber => {
|
||||||
const fibers = getFiberState(currentRoot, fiber);
|
const fibers = getFiberState(currentRoot, fiber);
|
||||||
const stage = currentStage;
|
const stage = currentStage;
|
||||||
this.setState(({ history }) => ({
|
this.setState(({history}) => ({
|
||||||
history: [
|
history: [
|
||||||
...history, {
|
...history,
|
||||||
|
{
|
||||||
action: 'COMMIT',
|
action: 'COMMIT',
|
||||||
fibers,
|
fibers,
|
||||||
stage
|
stage,
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
@ -110,38 +115,40 @@ class App extends Component {
|
||||||
toContain() {},
|
toContain() {},
|
||||||
toEqual() {},
|
toEqual() {},
|
||||||
});
|
});
|
||||||
window.log = s => currentStage = s;
|
window.log = s => (currentStage = s);
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
eval(window.Babel.transform(code, {
|
eval(
|
||||||
presets: ['react', 'es2015']
|
window.Babel.transform(code, {
|
||||||
}).code);
|
presets: ['react', 'es2015'],
|
||||||
|
}).code,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
handleEdit = (e) => {
|
handleEdit = e => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
this.setState({
|
this.setState({
|
||||||
isEditing: true
|
isEditing: true,
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
handleCloseEdit = (nextCode) => {
|
handleCloseEdit = nextCode => {
|
||||||
localStorage.setItem('fiber-debugger-code', nextCode);
|
localStorage.setItem('fiber-debugger-code', nextCode);
|
||||||
this.setState({
|
this.setState({
|
||||||
isEditing: false,
|
isEditing: false,
|
||||||
history: [],
|
history: [],
|
||||||
currentStep: 0,
|
currentStep: 0,
|
||||||
code: nextCode
|
code: nextCode,
|
||||||
});
|
});
|
||||||
this.runCode(nextCode);
|
this.runCode(nextCode);
|
||||||
}
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { history, currentStep, isEditing, code } = this.state;
|
const {history, currentStep, isEditing, code} = this.state;
|
||||||
if (isEditing) {
|
if (isEditing) {
|
||||||
return <Editor code={code} onClose={this.handleCloseEdit} />;
|
return <Editor code={code} onClose={this.handleCloseEdit} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { fibers, action, stage } = history[currentStep] || {};
|
const {fibers, action, stage} = history[currentStep] || {};
|
||||||
let friendlyAction;
|
let friendlyAction;
|
||||||
if (fibers) {
|
if (fibers) {
|
||||||
let wipFiber = fibers.descriptions[fibers.workInProgressID];
|
let wipFiber = fibers.descriptions[fibers.workInProgressID];
|
||||||
|
|
@ -150,45 +157,59 @@ class App extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{ height: '100%' }}>
|
<div style={{height: '100%'}}>
|
||||||
{fibers &&
|
{fibers &&
|
||||||
<Draggable>
|
<Draggable>
|
||||||
<Fibers fibers={fibers} show={this.state.show} />
|
<Fibers fibers={fibers} show={this.state.show} />
|
||||||
</Draggable>
|
</Draggable>}
|
||||||
}
|
<div
|
||||||
<div style={{
|
style={{
|
||||||
width: '100%',
|
width: '100%',
|
||||||
textAlign: 'center',
|
textAlign: 'center',
|
||||||
position: 'fixed',
|
position: 'fixed',
|
||||||
bottom: 0,
|
bottom: 0,
|
||||||
padding: 10,
|
padding: 10,
|
||||||
zIndex: 1,
|
zIndex: 1,
|
||||||
backgroundColor: '#fafafa',
|
backgroundColor: '#fafafa',
|
||||||
border: '1px solid #ccc'
|
border: '1px solid #ccc',
|
||||||
}}>
|
}}>
|
||||||
<input
|
<input
|
||||||
type="range"
|
type="range"
|
||||||
style={{ width: '25%' }}
|
style={{width: '25%'}}
|
||||||
min={0}
|
min={0}
|
||||||
max={history.length - 1}
|
max={history.length - 1}
|
||||||
value={currentStep}
|
value={currentStep}
|
||||||
onChange={e => this.setState({ currentStep: Number(e.target.value) })}
|
onChange={e => this.setState({currentStep: Number(e.target.value)})}
|
||||||
/>
|
/>
|
||||||
<p>Step {currentStep}: {friendlyAction} (<a style={{ color: 'gray' }} onClick={this.handleEdit} href='#'>Edit</a>)</p>
|
<p>
|
||||||
|
Step
|
||||||
|
{' '}
|
||||||
|
{currentStep}
|
||||||
|
:
|
||||||
|
{' '}
|
||||||
|
{friendlyAction}
|
||||||
|
{' '}
|
||||||
|
(
|
||||||
|
<a style={{color: 'gray'}} onClick={this.handleEdit} href="#">
|
||||||
|
Edit
|
||||||
|
</a>
|
||||||
|
)
|
||||||
|
</p>
|
||||||
{stage && <p>Stage: {stage}</p>}
|
{stage && <p>Stage: {stage}</p>}
|
||||||
{Object.keys(this.state.show).map(key =>
|
{Object.keys(this.state.show).map(key => (
|
||||||
<label style={{ marginRight: '10px' }} key={key}>
|
<label style={{marginRight: '10px'}} key={key}>
|
||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
checked={this.state.show[key]}
|
checked={this.state.show[key]}
|
||||||
onChange={e => {
|
onChange={e => {
|
||||||
this.setState(({ show }) => ({
|
this.setState(({show}) => ({
|
||||||
show: {...show, [key]: !show[key]}
|
show: {...show, [key]: !show[key]},
|
||||||
}));
|
}));
|
||||||
}} />
|
}}
|
||||||
|
/>
|
||||||
{key}
|
{key}
|
||||||
</label>
|
</label>
|
||||||
)}
|
))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -1,34 +1,38 @@
|
||||||
import React, { Component } from 'react';
|
import React, {Component} from 'react';
|
||||||
|
|
||||||
class Editor extends Component {
|
class Editor extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
code: props.code
|
code: props.code,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div style={{
|
<div
|
||||||
height: '100%',
|
style={{
|
||||||
width: '100%'
|
height: '100%',
|
||||||
}}>
|
width: '100%',
|
||||||
|
}}>
|
||||||
<textarea
|
<textarea
|
||||||
value={this.state.code}
|
value={this.state.code}
|
||||||
onChange={e => this.setState({ code: e.target.value })}
|
onChange={e => this.setState({code: e.target.value})}
|
||||||
style={{
|
style={{
|
||||||
height: '80%',
|
height: '80%',
|
||||||
width: '100%',
|
width: '100%',
|
||||||
fontSize: '15px'
|
fontSize: '15px',
|
||||||
}} />
|
}}
|
||||||
<div style={{ height: '20%', textAlign: 'center' }}>
|
/>
|
||||||
<button onClick={() => this.props.onClose(this.state.code)} style={{ fontSize: 'large' }}>
|
<div style={{height: '20%', textAlign: 'center'}}>
|
||||||
|
<button
|
||||||
|
onClick={() => this.props.onClose(this.state.code)}
|
||||||
|
style={{fontSize: 'large'}}>
|
||||||
Run
|
Run
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Motion, spring } from 'react-motion';
|
import {Motion, spring} from 'react-motion';
|
||||||
import dagre from 'dagre';
|
import dagre from 'dagre';
|
||||||
// import prettyFormat from 'pretty-format';
|
// import prettyFormat from 'pretty-format';
|
||||||
// import reactElement from 'pretty-format/plugins/ReactElement';
|
// import reactElement from 'pretty-format/plugins/ReactElement';
|
||||||
|
|
@ -35,7 +35,7 @@ function Graph(props) {
|
||||||
g.setNode(child.key, {
|
g.setNode(child.key, {
|
||||||
label: child,
|
label: child,
|
||||||
width: child.props.width,
|
width: child.props.width,
|
||||||
height: child.props.height
|
height: child.props.height,
|
||||||
});
|
});
|
||||||
} else if (child.type.isEdge) {
|
} else if (child.type.isEdge) {
|
||||||
const relationshipKey = child.props.source + ':' + child.props.target;
|
const relationshipKey = child.props.source + ':' + child.props.target;
|
||||||
|
|
@ -52,34 +52,36 @@ function Graph(props) {
|
||||||
g.setEdge(child.props.source, child.props.target, {
|
g.setEdge(child.props.source, child.props.target, {
|
||||||
label: child,
|
label: child,
|
||||||
allChildren: children.map(c => c.props.children),
|
allChildren: children.map(c => c.props.children),
|
||||||
weight: child.props.weight
|
weight: child.props.weight,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
dagre.layout(g);
|
dagre.layout(g);
|
||||||
|
|
||||||
var activeNode = g.nodes().map(v => g.node(v)).find(node =>
|
var activeNode = g
|
||||||
node.label.props.isActive
|
.nodes()
|
||||||
);
|
.map(v => g.node(v))
|
||||||
const [winX, winY] = [window.innerWidth / 2, window.innerHeight / 2]
|
.find(node => node.label.props.isActive);
|
||||||
var focusDx = activeNode ? (winX - activeNode.x) : 0;
|
const [winX, winY] = [window.innerWidth / 2, window.innerHeight / 2];
|
||||||
var focusDy = activeNode ? (winY - activeNode.y) : 0;
|
var focusDx = activeNode ? winX - activeNode.x : 0;
|
||||||
|
var focusDy = activeNode ? winY - activeNode.y : 0;
|
||||||
|
|
||||||
var nodes = g.nodes().map(v => {
|
var nodes = g.nodes().map(v => {
|
||||||
var node = g.node(v);
|
var node = g.node(v);
|
||||||
return (
|
return (
|
||||||
<Motion style={{
|
<Motion
|
||||||
x: props.isDragging ? node.x + focusDx : spring(node.x + focusDx),
|
style={{
|
||||||
y: props.isDragging ? node.y + focusDy : spring(node.y + focusDy)
|
x: props.isDragging ? node.x + focusDx : spring(node.x + focusDx),
|
||||||
}} key={node.label.key}>
|
y: props.isDragging ? node.y + focusDy : spring(node.y + focusDy),
|
||||||
|
}}
|
||||||
|
key={node.label.key}>
|
||||||
{interpolatingStyle =>
|
{interpolatingStyle =>
|
||||||
React.cloneElement(node.label, {
|
React.cloneElement(node.label, {
|
||||||
x: interpolatingStyle.x + props.dx,
|
x: interpolatingStyle.x + props.dx,
|
||||||
y: interpolatingStyle.y + props.dy,
|
y: interpolatingStyle.y + props.dy,
|
||||||
vanillaX: node.x,
|
vanillaX: node.x,
|
||||||
vanillaY: node.y,
|
vanillaY: node.y,
|
||||||
})
|
})}
|
||||||
}
|
|
||||||
</Motion>
|
</Motion>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
@ -88,25 +90,31 @@ function Graph(props) {
|
||||||
var edge = g.edge(e);
|
var edge = g.edge(e);
|
||||||
let idx = 0;
|
let idx = 0;
|
||||||
return (
|
return (
|
||||||
<Motion style={edge.points.reduce((bag, point) => {
|
<Motion
|
||||||
bag[idx + ':x'] = props.isDragging ? point.x + focusDx : spring(point.x + focusDx);
|
style={edge.points.reduce((bag, point) => {
|
||||||
bag[idx + ':y'] = props.isDragging ? point.y + focusDy : spring(point.y + focusDy);
|
bag[idx + ':x'] = props.isDragging
|
||||||
idx++;
|
? point.x + focusDx
|
||||||
return bag;
|
: spring(point.x + focusDx);
|
||||||
}, {})} key={edge.label.key}>
|
bag[idx + ':y'] = props.isDragging
|
||||||
|
? point.y + focusDy
|
||||||
|
: spring(point.y + focusDy);
|
||||||
|
idx++;
|
||||||
|
return bag;
|
||||||
|
}, {})}
|
||||||
|
key={edge.label.key}>
|
||||||
{interpolatedStyle => {
|
{interpolatedStyle => {
|
||||||
let points = [];
|
let points = [];
|
||||||
Object.keys(interpolatedStyle).forEach(key => {
|
Object.keys(interpolatedStyle).forEach(key => {
|
||||||
const [idx, prop] = key.split(':');
|
const [idx, prop] = key.split(':');
|
||||||
if (!points[idx]) {
|
if (!points[idx]) {
|
||||||
points[idx] = { x: props.dx, y: props.dy };
|
points[idx] = {x: props.dx, y: props.dy};
|
||||||
}
|
}
|
||||||
points[idx][prop] += interpolatedStyle[key];
|
points[idx][prop] += interpolatedStyle[key];
|
||||||
});
|
});
|
||||||
return React.cloneElement(edge.label, {
|
return React.cloneElement(edge.label, {
|
||||||
points,
|
points,
|
||||||
id: edge.label.key,
|
id: edge.label.key,
|
||||||
children: edge.allChildren.join(', ')
|
children: edge.allChildren.join(', '),
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
</Motion>
|
</Motion>
|
||||||
|
|
@ -114,10 +122,11 @@ function Graph(props) {
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{
|
<div
|
||||||
position: 'relative',
|
style={{
|
||||||
height: '100%'
|
position: 'relative',
|
||||||
}}>
|
height: '100%',
|
||||||
|
}}>
|
||||||
{edges}
|
{edges}
|
||||||
{nodes}
|
{nodes}
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -130,17 +139,18 @@ function Vertex(props) {
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{
|
<div
|
||||||
position: 'absolute',
|
style={{
|
||||||
border: '1px solid black',
|
position: 'absolute',
|
||||||
left: (props.x-(props.width/2)),
|
border: '1px solid black',
|
||||||
top: (props.y-(props.height/2)),
|
left: props.x - props.width / 2,
|
||||||
width: props.width,
|
top: props.y - props.height / 2,
|
||||||
height: props.height,
|
width: props.width,
|
||||||
overflow: 'hidden',
|
height: props.height,
|
||||||
padding: '4px',
|
overflow: 'hidden',
|
||||||
wordWrap: 'break-word'
|
padding: '4px',
|
||||||
}}>
|
wordWrap: 'break-word',
|
||||||
|
}}>
|
||||||
{props.children}
|
{props.children}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
@ -154,49 +164,67 @@ const strokes = {
|
||||||
return: 'red',
|
return: 'red',
|
||||||
fx: 'purple',
|
fx: 'purple',
|
||||||
progressedChild: 'cyan',
|
progressedChild: 'cyan',
|
||||||
progressedDel: 'brown'
|
progressedDel: 'brown',
|
||||||
};
|
};
|
||||||
|
|
||||||
function Edge(props) {
|
function Edge(props) {
|
||||||
var points = props.points;
|
var points = props.points;
|
||||||
var path = "M" + points[0].x + " " + points[0].y + " ";
|
var path = 'M' + points[0].x + ' ' + points[0].y + ' ';
|
||||||
|
|
||||||
if (!points[0].x || !points[0].y) {
|
if (!points[0].x || !points[0].y) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var i = 1; i < points.length; i++) {
|
for (var i = 1; i < points.length; i++) {
|
||||||
path += "L" + points[i].x + " " + points[i].y + " ";
|
path += 'L' + points[i].x + ' ' + points[i].y + ' ';
|
||||||
if (!points[i].x || !points[i].y) {
|
if (!points[i].x || !points[i].y) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var lineID = props.id;
|
var lineID = props.id;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<svg width="100%" height="100%" style={{
|
<svg
|
||||||
position: 'absolute',
|
width="100%"
|
||||||
left: 0,
|
height="100%"
|
||||||
right: 0,
|
style={{
|
||||||
top: 0,
|
position: 'absolute',
|
||||||
bottom: 0,
|
left: 0,
|
||||||
}}>
|
right: 0,
|
||||||
|
top: 0,
|
||||||
|
bottom: 0,
|
||||||
|
}}>
|
||||||
<defs>
|
<defs>
|
||||||
<path d={path} id={lineID} />
|
<path d={path} id={lineID} />
|
||||||
<marker id="markerCircle" markerWidth="8" markerHeight="8" refX="5" refY="5">
|
<marker
|
||||||
<circle cx="5" cy="5" r="3" style={{stroke: 'none', fill:'black'}}/>
|
id="markerCircle"
|
||||||
|
markerWidth="8"
|
||||||
|
markerHeight="8"
|
||||||
|
refX="5"
|
||||||
|
refY="5">
|
||||||
|
<circle cx="5" cy="5" r="3" style={{stroke: 'none', fill: 'black'}} />
|
||||||
</marker>
|
</marker>
|
||||||
<marker id="markerArrow" markerWidth="13" markerHeight="13" refX="2" refY="6"
|
<marker
|
||||||
orient="auto">
|
id="markerArrow"
|
||||||
|
markerWidth="13"
|
||||||
|
markerHeight="13"
|
||||||
|
refX="2"
|
||||||
|
refY="6"
|
||||||
|
orient="auto">
|
||||||
<path d="M2,2 L2,11 L10,6 L2,2" style={{fill: 'black'}} />
|
<path d="M2,2 L2,11 L10,6 L2,2" style={{fill: 'black'}} />
|
||||||
</marker>
|
</marker>
|
||||||
</defs>
|
</defs>
|
||||||
|
|
||||||
<use xlinkHref={`#${lineID}`} fill="none" stroke={strokes[props.kind]} style={{
|
<use
|
||||||
markerStart: 'url(#markerCircle)',
|
xlinkHref={`#${lineID}`}
|
||||||
markerEnd: 'url(#markerArrow)'
|
fill="none"
|
||||||
}} />
|
stroke={strokes[props.kind]}
|
||||||
|
style={{
|
||||||
|
markerStart: 'url(#markerCircle)',
|
||||||
|
markerEnd: 'url(#markerArrow)',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
<text>
|
<text>
|
||||||
<textPath xlinkHref={`#${lineID}`}>
|
<textPath xlinkHref={`#${lineID}`}>
|
||||||
{' '}{props.children}
|
{' '}{props.children}
|
||||||
|
|
@ -226,32 +254,31 @@ function formatPriority(priority) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function Fibers({ fibers, show, ...rest }) {
|
export default function Fibers({fibers, show, ...rest}) {
|
||||||
const items = Object.keys(fibers.descriptions).map(id =>
|
const items = Object.keys(fibers.descriptions).map(
|
||||||
fibers.descriptions[id]
|
id => fibers.descriptions[id],
|
||||||
);
|
);
|
||||||
|
|
||||||
const isDragging = rest.className.indexOf('dragging') > -1;
|
const isDragging = rest.className.indexOf('dragging') > -1;
|
||||||
const [_, sdx, sdy] = rest.style.transform.match(/translate\((-?\d+)px,(-?\d+)px\)/) || [];
|
const [_, sdx, sdy] = rest.style.transform.match(
|
||||||
|
/translate\((-?\d+)px,(-?\d+)px\)/,
|
||||||
|
) || [];
|
||||||
const dx = Number(sdx);
|
const dx = Number(sdx);
|
||||||
const dy = Number(sdy);
|
const dy = Number(sdy);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div {...rest} style={{
|
<div
|
||||||
width: '100%',
|
{...rest}
|
||||||
height: '100%',
|
style={{
|
||||||
position: 'absolute',
|
width: '100%',
|
||||||
top: 0,
|
height: '100%',
|
||||||
left: 0,
|
position: 'absolute',
|
||||||
...rest.style,
|
top: 0,
|
||||||
transform: null
|
left: 0,
|
||||||
}}>
|
...rest.style,
|
||||||
<Graph
|
transform: null,
|
||||||
className="graph"
|
}}>
|
||||||
dx={dx}
|
<Graph className="graph" dx={dx} dy={dy} isDragging={isDragging}>
|
||||||
dy={dy}
|
|
||||||
isDragging={isDragging}
|
|
||||||
>
|
|
||||||
{items.map(fiber => [
|
{items.map(fiber => [
|
||||||
<Vertex
|
<Vertex
|
||||||
key={fiber.id}
|
key={fiber.id}
|
||||||
|
|
@ -262,7 +289,7 @@ export default function Fibers({ fibers, show, ...rest }) {
|
||||||
style={{
|
style={{
|
||||||
width: '100%',
|
width: '100%',
|
||||||
height: '100%',
|
height: '100%',
|
||||||
backgroundColor: getFiberColor(fibers, fiber.id)
|
backgroundColor: getFiberColor(fibers, fiber.id),
|
||||||
}}
|
}}
|
||||||
title={
|
title={
|
||||||
/*prettyFormat(fiber, { plugins: [reactElement ]})*/
|
/*prettyFormat(fiber, { plugins: [reactElement ]})*/
|
||||||
|
|
@ -272,36 +299,40 @@ export default function Fibers({ fibers, show, ...rest }) {
|
||||||
<br />
|
<br />
|
||||||
{fiber.type}
|
{fiber.type}
|
||||||
<br />
|
<br />
|
||||||
{fibers.currentIDs.indexOf(fiber.id) === -1 ?
|
{fibers.currentIDs.indexOf(fiber.id) === -1
|
||||||
<small>
|
? <small>
|
||||||
{fiber.pendingWorkPriority !== 0 && [
|
{fiber.pendingWorkPriority !== 0 && [
|
||||||
<span style={{
|
<span
|
||||||
fontWeight: fiber.pendingWorkPriority <= fiber.progressedPriority ?
|
style={{
|
||||||
'bold' :
|
fontWeight: fiber.pendingWorkPriority <=
|
||||||
'normal'
|
fiber.progressedPriority
|
||||||
}} key="span">
|
? 'bold'
|
||||||
Needs: {formatPriority(fiber.pendingWorkPriority)}
|
: 'normal',
|
||||||
</span>,
|
}}
|
||||||
<br key="br" />
|
key="span">
|
||||||
]}
|
Needs: {formatPriority(fiber.pendingWorkPriority)}
|
||||||
{fiber.progressedPriority !== 0 && [
|
</span>,
|
||||||
`Finished: ${formatPriority(fiber.progressedPriority)}`,
|
<br key="br" />,
|
||||||
<br key="br" />
|
]}
|
||||||
]}
|
{fiber.progressedPriority !== 0 && [
|
||||||
{fiber.memoizedProps !== null && fiber.pendingProps !== null && [
|
`Finished: ${formatPriority(fiber.progressedPriority)}`,
|
||||||
fiber.memoizedProps === fiber.pendingProps ?
|
<br key="br" />,
|
||||||
'Can reuse memoized.' :
|
]}
|
||||||
'Cannot reuse memoized.',
|
{fiber.memoizedProps !== null &&
|
||||||
<br />
|
fiber.pendingProps !== null && [
|
||||||
]}
|
fiber.memoizedProps === fiber.pendingProps
|
||||||
</small> :
|
? 'Can reuse memoized.'
|
||||||
<small>
|
: 'Cannot reuse memoized.',
|
||||||
Committed
|
<br />,
|
||||||
</small>
|
]}
|
||||||
}
|
</small>
|
||||||
|
: <small>
|
||||||
|
Committed
|
||||||
|
</small>}
|
||||||
</div>
|
</div>
|
||||||
</Vertex>,
|
</Vertex>,
|
||||||
fiber.child && show.child &&
|
fiber.child &&
|
||||||
|
show.child &&
|
||||||
<Edge
|
<Edge
|
||||||
source={fiber.id}
|
source={fiber.id}
|
||||||
target={fiber.child}
|
target={fiber.child}
|
||||||
|
|
@ -310,7 +341,8 @@ export default function Fibers({ fibers, show, ...rest }) {
|
||||||
key={`${fiber.id}-${fiber.child}-child`}>
|
key={`${fiber.id}-${fiber.child}-child`}>
|
||||||
child
|
child
|
||||||
</Edge>,
|
</Edge>,
|
||||||
fiber.progressedChild && show.progressedChild &&
|
fiber.progressedChild &&
|
||||||
|
show.progressedChild &&
|
||||||
<Edge
|
<Edge
|
||||||
source={fiber.id}
|
source={fiber.id}
|
||||||
target={fiber.progressedChild}
|
target={fiber.progressedChild}
|
||||||
|
|
@ -319,7 +351,8 @@ export default function Fibers({ fibers, show, ...rest }) {
|
||||||
key={`${fiber.id}-${fiber.progressedChild}-pChild`}>
|
key={`${fiber.id}-${fiber.progressedChild}-pChild`}>
|
||||||
pChild
|
pChild
|
||||||
</Edge>,
|
</Edge>,
|
||||||
fiber.sibling && show.sibling &&
|
fiber.sibling &&
|
||||||
|
show.sibling &&
|
||||||
<Edge
|
<Edge
|
||||||
source={fiber.id}
|
source={fiber.id}
|
||||||
target={fiber.sibling}
|
target={fiber.sibling}
|
||||||
|
|
@ -328,7 +361,8 @@ export default function Fibers({ fibers, show, ...rest }) {
|
||||||
key={`${fiber.id}-${fiber.sibling}-sibling`}>
|
key={`${fiber.id}-${fiber.sibling}-sibling`}>
|
||||||
sibling
|
sibling
|
||||||
</Edge>,
|
</Edge>,
|
||||||
fiber.return && show.return &&
|
fiber.return &&
|
||||||
|
show.return &&
|
||||||
<Edge
|
<Edge
|
||||||
source={fiber.id}
|
source={fiber.id}
|
||||||
target={fiber.return}
|
target={fiber.return}
|
||||||
|
|
@ -337,7 +371,8 @@ export default function Fibers({ fibers, show, ...rest }) {
|
||||||
key={`${fiber.id}-${fiber.return}-return`}>
|
key={`${fiber.id}-${fiber.return}-return`}>
|
||||||
return
|
return
|
||||||
</Edge>,
|
</Edge>,
|
||||||
fiber.nextEffect && show.fx &&
|
fiber.nextEffect &&
|
||||||
|
show.fx &&
|
||||||
<Edge
|
<Edge
|
||||||
source={fiber.id}
|
source={fiber.id}
|
||||||
target={fiber.nextEffect}
|
target={fiber.nextEffect}
|
||||||
|
|
@ -346,7 +381,8 @@ export default function Fibers({ fibers, show, ...rest }) {
|
||||||
key={`${fiber.id}-${fiber.nextEffect}-nextEffect`}>
|
key={`${fiber.id}-${fiber.nextEffect}-nextEffect`}>
|
||||||
nextFx
|
nextFx
|
||||||
</Edge>,
|
</Edge>,
|
||||||
fiber.firstEffect && show.fx &&
|
fiber.firstEffect &&
|
||||||
|
show.fx &&
|
||||||
<Edge
|
<Edge
|
||||||
source={fiber.id}
|
source={fiber.id}
|
||||||
target={fiber.firstEffect}
|
target={fiber.firstEffect}
|
||||||
|
|
@ -355,7 +391,8 @@ export default function Fibers({ fibers, show, ...rest }) {
|
||||||
key={`${fiber.id}-${fiber.firstEffect}-firstEffect`}>
|
key={`${fiber.id}-${fiber.firstEffect}-firstEffect`}>
|
||||||
firstFx
|
firstFx
|
||||||
</Edge>,
|
</Edge>,
|
||||||
fiber.lastEffect && show.fx &&
|
fiber.lastEffect &&
|
||||||
|
show.fx &&
|
||||||
<Edge
|
<Edge
|
||||||
source={fiber.id}
|
source={fiber.id}
|
||||||
target={fiber.lastEffect}
|
target={fiber.lastEffect}
|
||||||
|
|
@ -364,7 +401,8 @@ export default function Fibers({ fibers, show, ...rest }) {
|
||||||
key={`${fiber.id}-${fiber.lastEffect}-lastEffect`}>
|
key={`${fiber.id}-${fiber.lastEffect}-lastEffect`}>
|
||||||
lastFx
|
lastFx
|
||||||
</Edge>,
|
</Edge>,
|
||||||
fiber.progressedFirstDeletion && show.progressedDel &&
|
fiber.progressedFirstDeletion &&
|
||||||
|
show.progressedDel &&
|
||||||
<Edge
|
<Edge
|
||||||
source={fiber.id}
|
source={fiber.id}
|
||||||
target={fiber.progressedFirstDeletion}
|
target={fiber.progressedFirstDeletion}
|
||||||
|
|
@ -373,7 +411,8 @@ export default function Fibers({ fibers, show, ...rest }) {
|
||||||
key={`${fiber.id}-${fiber.progressedFirstDeletion}-pFD`}>
|
key={`${fiber.id}-${fiber.progressedFirstDeletion}-pFD`}>
|
||||||
pFDel
|
pFDel
|
||||||
</Edge>,
|
</Edge>,
|
||||||
fiber.progressedLastDeletion && show.progressedDel &&
|
fiber.progressedLastDeletion &&
|
||||||
|
show.progressedDel &&
|
||||||
<Edge
|
<Edge
|
||||||
source={fiber.id}
|
source={fiber.id}
|
||||||
target={fiber.progressedLastDeletion}
|
target={fiber.progressedLastDeletion}
|
||||||
|
|
@ -382,7 +421,8 @@ export default function Fibers({ fibers, show, ...rest }) {
|
||||||
key={`${fiber.id}-${fiber.progressedLastDeletion}-pLD`}>
|
key={`${fiber.id}-${fiber.progressedLastDeletion}-pLD`}>
|
||||||
pLDel
|
pLDel
|
||||||
</Edge>,
|
</Edge>,
|
||||||
fiber.alternate && show.alt &&
|
fiber.alternate &&
|
||||||
|
show.alt &&
|
||||||
<Edge
|
<Edge
|
||||||
source={fiber.id}
|
source={fiber.id}
|
||||||
target={fiber.alternate}
|
target={fiber.alternate}
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ export default function describeFibers(rootFiber, workInProgress) {
|
||||||
...fiber,
|
...fiber,
|
||||||
id: id,
|
id: id,
|
||||||
tag: getFriendlyTag(fiber.tag),
|
tag: getFriendlyTag(fiber.tag),
|
||||||
type: (fiber.type && ('<' + (fiber.type.name || fiber.type) + '>')),
|
type: fiber.type && '<' + (fiber.type.name || fiber.type) + '>',
|
||||||
stateNode: `[${typeof fiber.stateNode}]`,
|
stateNode: `[${typeof fiber.stateNode}]`,
|
||||||
return: acknowledgeFiber(fiber.return),
|
return: acknowledgeFiber(fiber.return),
|
||||||
child: acknowledgeFiber(fiber.child),
|
child: acknowledgeFiber(fiber.child),
|
||||||
|
|
@ -91,6 +91,6 @@ export default function describeFibers(rootFiber, workInProgress) {
|
||||||
descriptions,
|
descriptions,
|
||||||
rootID,
|
rootID,
|
||||||
currentIDs: Array.from(currentIDs),
|
currentIDs: Array.from(currentIDs),
|
||||||
workInProgressID
|
workInProgressID,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,4 @@ import ReactDOM from 'react-dom';
|
||||||
import App from './App';
|
import App from './App';
|
||||||
import './index.css';
|
import './index.css';
|
||||||
|
|
||||||
ReactDOM.render(
|
ReactDOM.render(<App />, document.getElementById('root'));
|
||||||
<App />,
|
|
||||||
document.getElementById('root')
|
|
||||||
);
|
|
||||||
|
|
|
||||||
|
|
@ -3,5 +3,5 @@ var ReactDOM = require('react-dom');
|
||||||
|
|
||||||
ReactDOM.render(
|
ReactDOM.render(
|
||||||
React.createElement('h1', null, 'Hello World!'),
|
React.createElement('h1', null, 'Hello World!'),
|
||||||
document.getElementById('container')
|
document.getElementById('container'),
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -3,5 +3,5 @@ var ReactDOM = require('react-dom');
|
||||||
|
|
||||||
ReactDOM.render(
|
ReactDOM.render(
|
||||||
React.createElement('h1', null, 'Hello World!'),
|
React.createElement('h1', null, 'Hello World!'),
|
||||||
document.getElementById('container')
|
document.getElementById('container'),
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -3,5 +3,5 @@ var ReactDOM = require('react-dom');
|
||||||
|
|
||||||
ReactDOM.render(
|
ReactDOM.render(
|
||||||
React.createElement('h1', null, 'Hello World!'),
|
React.createElement('h1', null, 'Hello World!'),
|
||||||
document.getElementById('container')
|
document.getElementById('container'),
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -3,5 +3,5 @@ var ReactDOM = require('react-dom');
|
||||||
|
|
||||||
ReactDOM.render(
|
ReactDOM.render(
|
||||||
React.createElement('h1', null, 'Hello World!'),
|
React.createElement('h1', null, 'Hello World!'),
|
||||||
document.getElementById('container')
|
document.getElementById('container'),
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -3,5 +3,5 @@ var ReactDOM = require('react-dom');
|
||||||
|
|
||||||
ReactDOM.render(
|
ReactDOM.render(
|
||||||
React.createElement('h1', null, 'Hello World!'),
|
React.createElement('h1', null, 'Hello World!'),
|
||||||
document.getElementById('container')
|
document.getElementById('container'),
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -3,5 +3,5 @@ var ReactDOM = require('react-dom');
|
||||||
|
|
||||||
ReactDOM.render(
|
ReactDOM.render(
|
||||||
React.createElement('h1', null, 'Hello World!'),
|
React.createElement('h1', null, 'Hello World!'),
|
||||||
document.getElementById('container')
|
document.getElementById('container'),
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ const fs = require('fs');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const child_process = require('child_process');
|
const child_process = require('child_process');
|
||||||
|
|
||||||
const fixtureDirs = fs.readdirSync(__dirname).filter((file) => {
|
const fixtureDirs = fs.readdirSync(__dirname).filter(file => {
|
||||||
return fs.statSync(path.join(__dirname, file)).isDirectory();
|
return fs.statSync(path.join(__dirname, file)).isDirectory();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
require(['react', 'react-dom'], function(React, ReactDOM) {
|
require(['react', 'react-dom'], function(React, ReactDOM) {
|
||||||
ReactDOM.render(
|
ReactDOM.render(
|
||||||
React.createElement('h1', null, 'Hello World!'),
|
React.createElement('h1', null, 'Hello World!'),
|
||||||
document.getElementById('container')
|
document.getElementById('container'),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
require(['react', 'react-dom'], function(React, ReactDOM) {
|
require(['react', 'react-dom'], function(React, ReactDOM) {
|
||||||
ReactDOM.render(
|
ReactDOM.render(
|
||||||
React.createElement('h1', null, 'Hello World!'),
|
React.createElement('h1', null, 'Hello World!'),
|
||||||
document.getElementById('container')
|
document.getElementById('container'),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -3,5 +3,5 @@ import ReactDOM from 'react-dom';
|
||||||
|
|
||||||
ReactDOM.render(
|
ReactDOM.render(
|
||||||
React.createElement('h1', null, 'Hello World!'),
|
React.createElement('h1', null, 'Hello World!'),
|
||||||
document.getElementById('container')
|
document.getElementById('container'),
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -3,5 +3,5 @@ import ReactDOM from 'react-dom';
|
||||||
|
|
||||||
ReactDOM.render(
|
ReactDOM.render(
|
||||||
React.createElement('h1', null, 'Hello World!'),
|
React.createElement('h1', null, 'Hello World!'),
|
||||||
document.getElementById('container')
|
document.getElementById('container'),
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ module.exports = {
|
||||||
resolve: {
|
resolve: {
|
||||||
root: path.resolve('../../../../build/packages'),
|
root: path.resolve('../../../../build/packages'),
|
||||||
alias: {
|
alias: {
|
||||||
'react': 'react/umd/react.development',
|
react: 'react/umd/react.development',
|
||||||
'react-dom': 'react-dom/umd/react-dom.development',
|
'react-dom': 'react-dom/umd/react-dom.development',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -3,5 +3,5 @@ var ReactDOM = require('react-dom');
|
||||||
|
|
||||||
ReactDOM.render(
|
ReactDOM.render(
|
||||||
React.createElement('h1', null, 'Hello World!'),
|
React.createElement('h1', null, 'Hello World!'),
|
||||||
document.getElementById('container')
|
document.getElementById('container'),
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ module.exports = {
|
||||||
resolve: {
|
resolve: {
|
||||||
root: path.resolve('../../../../build/packages'),
|
root: path.resolve('../../../../build/packages'),
|
||||||
alias: {
|
alias: {
|
||||||
'react': 'react/umd/react.production.min',
|
react: 'react/umd/react.production.min',
|
||||||
'react-dom': 'react-dom/umd/react-dom.production.min',
|
'react-dom': 'react-dom/umd/react-dom.production.min',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -3,5 +3,5 @@ var ReactDOM = require('react-dom');
|
||||||
|
|
||||||
ReactDOM.render(
|
ReactDOM.render(
|
||||||
React.createElement('h1', null, 'Hello World!'),
|
React.createElement('h1', null, 'Hello World!'),
|
||||||
document.getElementById('container')
|
document.getElementById('container'),
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -3,5 +3,5 @@ var ReactDOM = require('react-dom');
|
||||||
|
|
||||||
ReactDOM.render(
|
ReactDOM.render(
|
||||||
React.createElement('h1', null, 'Hello World!'),
|
React.createElement('h1', null, 'Hello World!'),
|
||||||
document.getElementById('container')
|
document.getElementById('container'),
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -9,11 +9,11 @@ module.exports = {
|
||||||
resolve: {
|
resolve: {
|
||||||
root: path.resolve('../../../../build/packages/'),
|
root: path.resolve('../../../../build/packages/'),
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
new webpack.DefinePlugin({
|
new webpack.DefinePlugin({
|
||||||
'process.env':{
|
'process.env': {
|
||||||
'NODE_ENV': JSON.stringify('production')
|
NODE_ENV: JSON.stringify('production'),
|
||||||
}
|
},
|
||||||
})
|
}),
|
||||||
]
|
],
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -3,5 +3,5 @@ var ReactDOM = require('react-dom');
|
||||||
|
|
||||||
ReactDOM.render(
|
ReactDOM.render(
|
||||||
React.createElement('h1', null, 'Hello World!'),
|
React.createElement('h1', null, 'Hello World!'),
|
||||||
document.getElementById('container')
|
document.getElementById('container'),
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -35,10 +35,13 @@ app.use(express.static(path.resolve(__dirname, '..', 'build')));
|
||||||
|
|
||||||
// Proxy everything else to create-react-app's webpack development server
|
// Proxy everything else to create-react-app's webpack development server
|
||||||
if (process.env.NODE_ENV === 'development') {
|
if (process.env.NODE_ENV === 'development') {
|
||||||
app.use('/', proxy({
|
app.use(
|
||||||
ws: true,
|
'/',
|
||||||
target: 'http://localhost:3001'
|
proxy({
|
||||||
}));
|
ws: true,
|
||||||
|
target: 'http://localhost:3001',
|
||||||
|
}),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
app.listen(3000, () => {
|
app.listen(3000, () => {
|
||||||
|
|
@ -50,9 +53,7 @@ app.on('error', function(error) {
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
|
|
||||||
var bind = typeof port === 'string'
|
var bind = typeof port === 'string' ? 'Pipe ' + port : 'Port ' + port;
|
||||||
? 'Pipe ' + port
|
|
||||||
: 'Port ' + port;
|
|
||||||
|
|
||||||
switch (error.code) {
|
switch (error.code) {
|
||||||
case 'EACCES':
|
case 'EACCES':
|
||||||
|
|
|
||||||
|
|
@ -19,4 +19,4 @@ export default function render() {
|
||||||
// There's no way to render a doctype in React so prepend manually.
|
// There's no way to render a doctype in React so prepend manually.
|
||||||
// Also append a bootstrap script tag.
|
// Also append a bootstrap script tag.
|
||||||
return '<!DOCTYPE html>' + html;
|
return '<!DOCTYPE html>' + html;
|
||||||
};
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { Component } from 'react';
|
import React, {Component} from 'react';
|
||||||
|
|
||||||
import Chrome from './Chrome';
|
import Chrome from './Chrome';
|
||||||
import Page from './Page';
|
import Page from './Page';
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { Component } from 'react';
|
import React, {Component} from 'react';
|
||||||
|
|
||||||
import './Chrome.css';
|
import './Chrome.css';
|
||||||
|
|
||||||
|
|
@ -16,9 +16,11 @@ export default class Chrome extends Component {
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
{this.props.children}
|
{this.props.children}
|
||||||
<script dangerouslySetInnerHTML={{
|
<script
|
||||||
__html: `assetManifest = ${JSON.stringify(assets)};`
|
dangerouslySetInnerHTML={{
|
||||||
}} />
|
__html: `assetManifest = ${JSON.stringify(assets)};`,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
<script src={assets['main.js']} />
|
<script src={assets['main.js']} />
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
import React, { Component } from 'react';
|
import React, {Component} from 'react';
|
||||||
|
|
||||||
import './Page.css';
|
import './Page.css';
|
||||||
|
|
||||||
export default class Page extends Component {
|
export default class Page extends Component {
|
||||||
state = { active: false };
|
state = {active: false};
|
||||||
handleClick = (e) => {
|
handleClick = e => {
|
||||||
this.setState({ active: true });
|
this.setState({active: true});
|
||||||
}
|
};
|
||||||
render() {
|
render() {
|
||||||
const link = (
|
const link = (
|
||||||
<a className="bold" onClick={this.handleClick}>
|
<a className="bold" onClick={this.handleClick}>
|
||||||
|
|
@ -16,7 +16,7 @@ export default class Page extends Component {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<p>
|
<p>
|
||||||
{!this.state.active ? link : "Thanks!"}
|
{!this.state.active ? link : 'Thanks!'}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { render } from 'react-dom';
|
import {render} from 'react-dom';
|
||||||
|
|
||||||
import App from './components/App';
|
import App from './components/App';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ const defaultOptions = {
|
||||||
};
|
};
|
||||||
const config = {
|
const config = {
|
||||||
default: {
|
default: {
|
||||||
patterns: ['src/**/*.js'],
|
patterns: ['src/**/*.js', 'fixtures/**/*.js'],
|
||||||
ignore: ['**/third_party/**', '**/node_modules/**'],
|
ignore: ['**/third_party/**', '**/node_modules/**'],
|
||||||
},
|
},
|
||||||
scripts: {
|
scripts: {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user