diff --git a/fixtures/.gitignore b/fixtures/.gitignore new file mode 100644 index 0000000000000..6c96c5cff1242 --- /dev/null +++ b/fixtures/.gitignore @@ -0,0 +1,15 @@ +# See http://help.github.com/ignore-files/ for more about ignoring files. + +# dependencies +node_modules + +# testing +coverage + +# production +build + +# misc +.DS_Store +.env +npm-debug.log diff --git a/fixtures/README.md b/fixtures/README.md index e421c3ebcbe28..fd2bf68fe076b 100644 --- a/fixtures/README.md +++ b/fixtures/README.md @@ -1,16 +1 @@ -# Browser Fixtures - -This folder contains tools to assist in the testing of browser quirks. - -Each document is browsable without setting up a static file server. Just open -the test case in a browser. - -## Browser Targets - -React 15+ supports all ES5 compliant browsers: - -https://facebook.github.io/react/docs/react-dom.html#browser-support - -### IE8 Support - -React 0.14 and lower support IE8 after including several required shims. +# React Fixtures (TODO) \ No newline at end of file diff --git a/fixtures/package.json b/fixtures/package.json new file mode 100644 index 0000000000000..d8154e046e9df --- /dev/null +++ b/fixtures/package.json @@ -0,0 +1,19 @@ +{ + "name": "_fixtures", + "version": "0.1.0", + "private": true, + "devDependencies": { + "react-scripts": "0.8.4" + }, + "dependencies": { + "query-string": "^4.2.3", + "react": "^15.4.1", + "react-dom": "^15.4.1" + }, + "scripts": { + "start": "react-scripts start", + "build": "react-scripts build", + "test": "react-scripts test --env=jsdom", + "eject": "react-scripts eject" + } +} diff --git a/fixtures/public/favicon.ico b/fixtures/public/favicon.ico new file mode 100644 index 0000000000000..5c125de5d897c Binary files /dev/null and b/fixtures/public/favicon.ico differ diff --git a/fixtures/public/index.html b/fixtures/public/index.html new file mode 100644 index 0000000000000..a131a92882520 --- /dev/null +++ b/fixtures/public/index.html @@ -0,0 +1,32 @@ + + + + + + + + React App + + + +
+ + + diff --git a/fixtures/react-loader.js b/fixtures/public/react-loader.js similarity index 89% rename from fixtures/react-loader.js rename to fixtures/public/react-loader.js index 3f47f3ff211c3..aadc7e68431f9 100644 --- a/fixtures/react-loader.js +++ b/fixtures/public/react-loader.js @@ -7,8 +7,8 @@ * (Loads React 15.4.1) */ -var REACT_PATH = '../../build/react.js'; -var DOM_PATH = '../../build/react-dom.js'; +var REACT_PATH = 'react.js'; +var DOM_PATH = 'react-dom.js'; var BABEL_PATH = 'https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.19.0/babel.js'; function parseQuery(qstr) { @@ -25,9 +25,11 @@ function parseQuery(qstr) { return query; } -var query = parseQuery(window.location.search.slice(1)); +var query = parseQuery(window.location.search); var version = query.version || 'local'; +console.log(query) + if (version !== 'local') { REACT_PATH = 'https://unpkg.com/react@' + version + '/dist/react.min.js'; DOM_PATH = 'https://unpkg.com/react-dom@' + version + '/dist/react-dom.min.js'; diff --git a/fixtures/range-inputs/index.html b/fixtures/range-inputs/index.html deleted file mode 100644 index f8bd4c85881ee..0000000000000 --- a/fixtures/range-inputs/index.html +++ /dev/null @@ -1,82 +0,0 @@ - - - - - - Range Inputs - - - - -
Loading...
- - - - - - diff --git a/fixtures/selects/index.html b/fixtures/selects/index.html deleted file mode 100644 index 4f2812ebf7e9a..0000000000000 --- a/fixtures/selects/index.html +++ /dev/null @@ -1,84 +0,0 @@ - - - - - - Selects - - - - -
Loading...
- - - - - - diff --git a/fixtures/src/components/App.js b/fixtures/src/components/App.js new file mode 100644 index 0000000000000..7d6f04b143b6c --- /dev/null +++ b/fixtures/src/components/App.js @@ -0,0 +1,19 @@ +const React = window.React; +import Header from './Header'; +import Fixtures from './fixtures'; +import '../styles/App.css'; + +const App = React.createClass({ + render() { + return ( +
+
+
+ +
+
+ ); + }, +}); + +export default App; diff --git a/fixtures/src/components/Header.js b/fixtures/src/components/Header.js new file mode 100644 index 0000000000000..c93a5150729fc --- /dev/null +++ b/fixtures/src/components/Header.js @@ -0,0 +1,68 @@ +import { parse, stringify } from 'query-string'; +const React = window.React; + +const Header = React.createClass({ + getInitialState() { + const query = parse(window.location.search); + const version = query.version || 'local'; + const versions = [version]; + return { version, versions }; + }, + componentWillMount() { + fetch('http://api.github.com/repos/facebook/react/tags') + .then(res => res.json()) + .then(tags => { + let versions = tags.map(tag => tag.name.slice(1)); + versions = ['local', ...versions]; + this.setState({ versions }); + }); + }, + handleVersionChange(event) { + const query = parse(window.location.search); + query.version = event.target.value; + if (query.version === 'local') { + delete query.version; + } + window.location.search = stringify(query); + }, + handleFixtureChange(event) { + window.location.pathname = event.target.value; + }, + render() { + return ( +
+
+ + + React Sandbox (v{React.version}) + + +
+ + +
+
+
+ ); + }, +}); + +export default Header; diff --git a/fixtures/src/components/RangeInputs.js b/fixtures/src/components/RangeInputs.js new file mode 100644 index 0000000000000..eea1f996d6ed3 --- /dev/null +++ b/fixtures/src/components/RangeInputs.js @@ -0,0 +1,28 @@ +const React = window.React; + +const RangeInputs = React.createClass({ + getInitialState() { + return { value: 0.5 }; + }, + onChange(event) { + this.setState({ value: event.target.value }); + }, + render() { + return ( +
+
+ Controlled + + Value: {this.state.value} +
+ +
+ Uncontrolled + +
+
+ ); + }, +}); + +export default RangeInputs; diff --git a/fixtures/src/components/TextInputs.js b/fixtures/src/components/TextInputs.js new file mode 100644 index 0000000000000..62d16187c93b4 --- /dev/null +++ b/fixtures/src/components/TextInputs.js @@ -0,0 +1,67 @@ +const React = window.React; +import '../styles/TextInputs.css'; + +const TextInputFixtures = React.createClass({ + getInitialState() { + return { + color: '#ffaaee', + }; + }, + + renderControlled(type) { + let id = `controlled_${type}`; + + let onChange = e => { + let value = e.target.value; + if (type === 'number') { + value = value === '' ? '' : parseFloat(value, 10) || 0 + } + this.setState({ + [type] : value, + }); + }; + + let state = this.state[type] || ''; + + return ( +
+ + +   → {JSON.stringify(state)} +
+ ); + }, + + renderUncontrolled(type) { + let id = `uncontrolled_${type}`; + return ( +
+ + +
+ ); + }, + + render() { + // https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input + let types = [ + 'text', 'email', 'number', 'url', 'tel', + 'color', 'date', 'datetime-local', + 'time', 'month', 'week', 'range', 'password', + ]; + return ( +
event.preventDefault()}> +
+ Controlled + {types.map(this.renderControlled)} +
+
+ Uncontrolled + {types.map(this.renderUncontrolled)} +
+
+ ); + }, +}); + +module.exports = TextInputFixtures; diff --git a/fixtures/src/components/fixtures/index.js b/fixtures/src/components/fixtures/index.js new file mode 100644 index 0000000000000..763939d28ff2c --- /dev/null +++ b/fixtures/src/components/fixtures/index.js @@ -0,0 +1,28 @@ +const React = window.React; +import RangeInputFixtures from './range-inputs'; +import TextInputFixtures from './text-inputs'; +import SelectFixtures from './selects'; +import TextAreaFixtures from './textareas/'; + +/** + * A simple routing component that renders the appropriate + * fixture based on the location pathname. + */ +const FixturesPage = React.createClass({ + render() { + switch (window.location.pathname) { + case '/text-inputs': + return ; + case '/range-inputs': + return ; + case '/selects': + return ; + case '/textareas': + return ; + default: + return ; + } + }, +}); + +module.exports = FixturesPage; diff --git a/fixtures/range-inputs/README.md b/fixtures/src/components/fixtures/range-inputs/README.md similarity index 100% rename from fixtures/range-inputs/README.md rename to fixtures/src/components/fixtures/range-inputs/README.md diff --git a/fixtures/src/components/fixtures/range-inputs/index.js b/fixtures/src/components/fixtures/range-inputs/index.js new file mode 100644 index 0000000000000..eea1f996d6ed3 --- /dev/null +++ b/fixtures/src/components/fixtures/range-inputs/index.js @@ -0,0 +1,28 @@ +const React = window.React; + +const RangeInputs = React.createClass({ + getInitialState() { + return { value: 0.5 }; + }, + onChange(event) { + this.setState({ value: event.target.value }); + }, + render() { + return ( +
+
+ Controlled + + Value: {this.state.value} +
+ +
+ Uncontrolled + +
+
+ ); + }, +}); + +export default RangeInputs; diff --git a/fixtures/selects/README.md b/fixtures/src/components/fixtures/selects/README.md similarity index 100% rename from fixtures/selects/README.md rename to fixtures/src/components/fixtures/selects/README.md diff --git a/fixtures/src/components/fixtures/selects/index.js b/fixtures/src/components/fixtures/selects/index.js new file mode 100644 index 0000000000000..3b170b24f54f1 --- /dev/null +++ b/fixtures/src/components/fixtures/selects/index.js @@ -0,0 +1,37 @@ +const React = window.React; + +const SelectFixture = React.createClass({ + getInitialState() { + return { value: '' }; + }, + onChange(event) { + this.setState({ value: event.target.value }) + }, + render() { + return ( +
+
+ Controlled + + Value: {this.state.value} +
+
+ Uncontrolled + +
+
+ ); + }, +}); + +export default SelectFixture; diff --git a/fixtures/text-inputs/README.md b/fixtures/src/components/fixtures/text-inputs/README.md similarity index 100% rename from fixtures/text-inputs/README.md rename to fixtures/src/components/fixtures/text-inputs/README.md diff --git a/fixtures/src/components/fixtures/text-inputs/index.js b/fixtures/src/components/fixtures/text-inputs/index.js new file mode 100644 index 0000000000000..904a8bdc3bfe3 --- /dev/null +++ b/fixtures/src/components/fixtures/text-inputs/index.js @@ -0,0 +1,67 @@ +const React = window.React; +import '../../../styles/TextInputs.css'; + +const TextInputFixtures = React.createClass({ + getInitialState() { + return { + color: '#ffaaee', + }; + }, + + renderControlled(type) { + let id = `controlled_${type}`; + + let onChange = e => { + let value = e.target.value; + if (type === 'number') { + value = value === '' ? '' : parseFloat(value, 10) || 0 + } + this.setState({ + [type] : value, + }); + }; + + let state = this.state[type] || ''; + + return ( +
+ + +   → {JSON.stringify(state)} +
+ ); + }, + + renderUncontrolled(type) { + let id = `uncontrolled_${type}`; + return ( +
+ + +
+ ); + }, + + render() { + // https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input + let types = [ + 'text', 'email', 'number', 'url', 'tel', + 'color', 'date', 'datetime-local', + 'time', 'month', 'week', 'range', 'password', + ]; + return ( +
event.preventDefault()}> +
+ Controlled + {types.map(this.renderControlled)} +
+
+ Uncontrolled + {types.map(this.renderUncontrolled)} +
+
+ ); + }, +}); + +module.exports = TextInputFixtures; diff --git a/fixtures/textareas/README.md b/fixtures/src/components/fixtures/textareas/README.md similarity index 100% rename from fixtures/textareas/README.md rename to fixtures/src/components/fixtures/textareas/README.md diff --git a/fixtures/src/components/fixtures/textareas/index.js b/fixtures/src/components/fixtures/textareas/index.js new file mode 100644 index 0000000000000..f500e679daef1 --- /dev/null +++ b/fixtures/src/components/fixtures/textareas/index.js @@ -0,0 +1,33 @@ +const React = window.React; + +const TextAreaFixtures = React.createClass({ + getInitialState() { + return { value: '' }; + }, + onChange(event) { + this.setState({ value: event.target.value }) + }, + render() { + return ( +
+
+
+ Controlled +