Compare commits

..

16 Commits

Author SHA1 Message Date
Nicolas Gallagher
65055028c6 0.0.98 2017-06-07 16:03:26 -07:00
Nicolas Gallagher
93f425e414 [fix] event normalization
Fix #508
2017-06-07 16:02:45 -07:00
Nicolas Gallagher
ce4cc8a946 Remove avoidable vendor code
Updates the 'StyleSheetValidation' and 'ColorPropType' implementations
with the latest from React Native.
2017-06-05 20:06:22 -07:00
Nicolas Gallagher
77fd867421 [fix] correct types
Fix #465
2017-06-05 19:51:34 -07:00
Nicolas Gallagher
22999d7e5b Run lint and test before releasing new versions 2017-06-02 15:29:11 -07:00
Nicolas Gallagher
3c400a662b 0.0.97 2017-06-02 15:27:48 -07:00
Nick
e78ce713cb [fix] TextInput selection for Blink on Android
Close #492
2017-06-01 09:30:22 -07:00
Nicolas Gallagher
70282cb4ca Format 2017-06-01 09:20:07 -07:00
Nicolas Gallagher
7abdb33a1d 0.0.96 2017-06-01 08:51:53 -07:00
Tasveer Singh
a9c7b38df9 [fix] low-level performance tuning
createDOMProps: avoid using default parameters as Babel compiles the
function to calls using 'arguments', which Chrome flags as a deopt.
Replace 'typeof' calls with slightly faster calls to constructor.

onLayout: batch layout measurements in a single requestAnimationFrame.

Close #490
2017-06-01 08:45:40 -07:00
Karan Thakkar
d57fb6407a Fix link to getting started in AppRegistry doc
Fixes #498
2017-06-01 10:50:38 +05:30
Nicolas Gallagher
bcdeda5dab [fix] Flow type checking and annotations
Fixes dozens of Flow errors; adds type annotations; marks more files for
Flow type checking. Fixes a bug in 'AppState'.

15 Flow errors remaining. Several React Native files are still not type
checked (e.g., PanResponder, Touchables)

Ref #465
2017-05-27 10:44:33 -07:00
Nicolas Gallagher
edef737249 Move CONTRIBUTING.md 2017-05-27 08:29:22 -07:00
Nicolas Gallagher
9163b974db Reduce number of dotfiles 2017-05-25 23:10:37 -07:00
Nicolas Gallagher
a388ef3e26 Rename 'examples' to 'docs/storybook'
Also changes several npm script names
2017-05-25 22:22:20 -07:00
Nicolas Gallagher
a84ecefa5d Rename 'performance' to 'benchmarks' 2017-05-25 21:44:01 -07:00
147 changed files with 626 additions and 330 deletions

View File

@@ -1,8 +0,0 @@
{
"presets": [
"react-native"
],
"plugins": [
[ "transform-react-remove-prop-types", { "mode": "wrap" } ]
]
}

View File

@@ -1,9 +0,0 @@
# EditorConfig: http://editorconfig.org
root = true
[*]
end_of_line = lf
insert_final_newline = true
indent_style = space
indent_size = 2

View File

@@ -24,7 +24,16 @@
"globals": {
"document": false,
"navigator": false,
"window": false
"window": false,
// Flow global types
"HTMLInputElement": false,
"ReactClass": false,
"ReactComponent": false,
"ReactElement": false,
"ReactPropsChainableTypeChecker": false,
"ReactPropsCheckType": false,
"ReactPropTypes": false,
"SyntheticEvent": false
},
"rules": {
"camelcase": 0,

View File

@@ -1,7 +1,7 @@
[ignore]
.*/__tests__/.*
.*/examples/.*
.*/performance/.*
.*/benchmarks/.*
.*/docs/.*
.*/node_modules/animated/*
[include]

View File

@@ -6,7 +6,7 @@ Before opening an issue, please search the [issue
tracker](https://github.com/necolas/react-native-web/issues) to make sure your
issue hasn't already been reported.
## Development
## Getting started
Visit the [Issue tracker](https://github.com/necolas/react-native-web/issues)
to find a list of open issues that need attention.
@@ -23,51 +23,75 @@ Install dependencies (requires [yarn](https://yarnpkg.com/en/docs/install):
yarn
```
Run the examples:
## Automated tests
To run flow:
```
npm run examples
npm run flow
```
Run the benchmarks in a browser by opening `./performance/index.html` after running:
To run the unit tests:
```
npm run build:performance
npm run jest
```
### Building
…in watch mode:
```
npm run jest:watch
```
To run all automated tests:
```
npm test
```
## Visual tests
To run the interactive storybook:
```
npm run docs:start
```
To generate a static build of the storybook:
```
npm run docs:build
```
To run the performance benchmarks in a browser (opening `./benchmarks/index.html`):
```
npm run benchmarks
```
## Compile and build
To compile the source code to `dist`:
```
npm run compile
```
To create a UMD bundle of the library:
```
npm run build
```
To create a UMD build:
### Pre-commit
```
npm run build:umd
```
### Testing and Linting
To run the tests:
```
npm run test
```
To continuously watch and run tests, run the following:
```
npm run test:watch
```
Before create a commit run:
To format and lint code before commit:
```
npm run precommit
```
To format or lint the entire project:
To format and lint the entire project:
```
npm run fmt
@@ -88,8 +112,10 @@ that we won't want to accept.
* Make sure all tests pass and there are no linting errors.
* Submit a pull request, referencing any issues it addresses.
Please try to keep your pull request focused in scope and avoid including unrelated commits.
Please try to keep your pull request focused in scope and avoid including
unrelated commits.
After you have submitted your pull request, we'll try to get back to you as soon as possible. We may suggest some changes or improvements.
After you have submitted your pull request, we'll try to get back to you as
soon as possible. We may suggest some changes or improvements.
Thank you for contributing!

1
.gitignore vendored
View File

@@ -1,3 +1,2 @@
node_modules
dist
dist-examples

View File

@@ -5,4 +5,5 @@ before_script:
- export DISPLAY=:99.0
- sh -e /etc/init.d/xvfb start
script:
- npm run lint
- npm test

View File

@@ -3,8 +3,7 @@
`AppRegistry` is the control point for registering, running, prerendering, and
unmounting all apps. App root components should register themselves with
`AppRegistry.registerComponent`. Apps can be run by invoking
`AppRegistry.runApplication` (see the [client and server rendering
guide](../guides/rendering.md) for more details).
`AppRegistry.runApplication` (see the [getting started guide](../guides/getting-started.md) for more details).
To "stop" an application when a view should be destroyed, call
`AppRegistry.unmountApplicationComponentAtRootTag` with the tag that was passed

View File

@@ -192,7 +192,7 @@ inline styles.
All this allows React Native for Web to support the rich functionality of React
Native styles (including RTL layouts and `setNativeProps`) while providing one
of the [fastest](https://github.com/necolas/react-native-web/blob/master/performance/README.md),
of the [fastest](https://github.com/necolas/react-native-web/blob/master/benchmarks/README.md),
safest, and most efficient styles-in-JavaScript solutions.
## FAQs

View File

@@ -27,7 +27,7 @@ module.exports = {
],
resolve: {
alias: {
'react-native': path.join(__dirname, '../../src/module')
'react-native': path.join(__dirname, '../../../src/module')
}
}
};

View File

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View File

Before

Width:  |  Height:  |  Size: 850 B

After

Width:  |  Height:  |  Size: 850 B

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -1,3 +1,5 @@
/* eslint-disable react/jsx-no-bind */
/**
* The examples provided by Facebook are for non-commercial testing and
* evaluation purposes only.
@@ -14,12 +16,10 @@
* @providesModule TicTacToeApp
* @flow
*/
'use strict';
import createReactClass from 'create-react-class';
const React = require('react');
const ReactNative = require('react-native');
const { AppRegistry, StyleSheet, Text, TouchableHighlight, View } = ReactNative;
import React from 'react';
import { AppRegistry, StyleSheet, Text, TouchableHighlight, View } from 'react-native';
class Board {
grid: Array<Array<number>>;
@@ -188,7 +188,7 @@ const GameEndOverlay = createReactClass({
const TicTacToeApp = createReactClass({
getInitialState() {
return { board: new Board(), player: 1 }
return { board: new Board(), player: 1 };
},
restartGame() {
@@ -214,7 +214,11 @@ const TicTacToeApp = createReactClass({
const rows = this.state.board.grid.map((cells, row) => (
<View key={'row' + row} style={styles.row}>
{cells.map((player, col) => (
<Cell key={'cell' + col} onPress={this.handleCellPress.bind(this, row, col)} player={player} />
<Cell
key={'cell' + col}
onPress={this.handleCellPress.bind(this, row, col)}
player={player}
/>
))}
</View>
));

View File

@@ -1,6 +1,6 @@
{
"name": "react-native-web",
"version": "0.0.95",
"version": "0.0.98",
"description": "React Native for Web",
"main": "dist/index.js",
"files": [
@@ -9,21 +9,35 @@
"!**/__tests__"
],
"scripts": {
"build": "del ./dist && mkdir dist && babel src -d dist --ignore **/__tests__",
"build:examples": "build-storybook -o dist-examples -c ./examples/.storybook",
"build:performance": "cd performance && yarn && webpack",
"build:umd": "webpack --config webpack.config.js --sort-assets-by --progress",
"deploy:examples": "git checkout gh-pages && rm -rf ./storybook && mv dist-examples storybook && git add -A && git commit -m \"Storybook deploy\" && git push origin gh-pages && git checkout -",
"examples": "start-storybook -p 9001 -c ./examples/.storybook --dont-track",
"benchmarks": "cd benchmarks && yarn && webpack && open index.html",
"build": "webpack --config webpack.config.js --sort-assets-by --progress",
"compile": "del ./dist && mkdir dist && babel src -d dist --ignore **/__tests__",
"docs:build": "build-storybook -o ./docs/dist -c ./docs/storybook/.storybook",
"docs:start": "start-storybook -p 9001 -c ./docs/storybook/.storybook --dont-track",
"docs:publish": "git checkout gh-pages && rm -rf ./storybook && mv docs/dist storybook && git add -A && git commit -m \"Storybook deploy\" && git push origin gh-pages && git checkout -",
"flow": "flow",
"fmt": "find examples performance src -name '*.js' | grep -v -E '(node_modules|dist)' | xargs npm run fmt:cmd",
"fmt": "find benchmarks docs src -name '*.js' | grep -v -E '(node_modules|dist)' | xargs npm run fmt:cmd",
"fmt:cmd": "prettier --print-width=100 --single-quote --write",
"lint": "npm run lint:cmd -- examples performance src",
"jest": "jest",
"jest:watch": "npm run test -- --watch",
"lint": "npm run lint:cmd -- benchmarks docs src",
"lint:cmd": "eslint --fix --ignore-path .gitignore",
"precommit": "lint-staged",
"release": "npm run build && npm run build:umd && npm publish",
"test": "jest",
"test:watch": "npm run test -- --watch"
"release": "npm run lint && npm run test && npm run compile && npm run build && npm publish",
"test": "flow && jest"
},
"babel": {
"presets": [
"react-native"
],
"plugins": [
[
"transform-react-remove-prop-types",
{
"mode": "wrap"
}
]
]
},
"jest": {
"testEnvironment": "jsdom",
@@ -69,7 +83,7 @@
"eslint-plugin-promise": "^3.5.0",
"eslint-plugin-react": "^6.10.3",
"file-loader": "^0.11.1",
"flow-bin": "^0.46.0",
"flow-bin": "^0.47.0",
"jest": "^19.0.2",
"lint-staged": "^3.4.2",
"node-libs-browser": "^0.5.3",

View File

@@ -0,0 +1,65 @@
/**
* @flow
*/
import StyleSheet from '../StyleSheet';
import View from '../../components/View';
import { any, node } from 'prop-types';
import React, { Component } from 'react';
type Context = {
rootTag: any
};
type Props = {
children?: React.Children,
rootTag: any
};
type State = {
mainKey: number
};
class AppContainer extends Component {
props: Props;
state: State = { mainKey: 1 };
static childContextTypes = {
rootTag: any
};
static propTypes = {
children: node,
rootTag: any.isRequired
};
getChildContext(): Context {
return {
rootTag: this.props.rootTag
};
}
render() {
return (
<View pointerEvents="box-none" style={styles.appContainer}>
<View
children={this.props.children}
key={this.state.mainKey}
pointerEvents="box-none"
style={styles.appContainer}
/>
</View>
);
}
}
const styles = StyleSheet.create({
/**
* Ensure that the application covers the whole screen.
*/
appContainer: {
flex: 1
}
});
module.exports = AppContainer;

View File

@@ -1,37 +0,0 @@
import StyleSheet from '../StyleSheet';
import View from '../../components/View';
import { any, object } from 'prop-types';
import React, { Component } from 'react';
class ReactNativeApp extends Component {
static propTypes = {
initialProps: object,
rootComponent: any.isRequired,
rootTag: any
};
render() {
const { initialProps, rootComponent: RootComponent, rootTag } = this.props;
return (
<View style={styles.appContainer}>
<RootComponent {...initialProps} rootTag={rootTag} />
</View>
);
}
}
const styles = StyleSheet.create({
/**
* Ensure that the application covers the whole screen.
*/
appContainer: {
position: 'absolute',
left: 0,
top: 0,
right: 0,
bottom: 0
}
});
module.exports = ReactNativeApp;

View File

@@ -1,6 +1,14 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`apis/AppRegistry/renderApplication getApplication 1`] = `
<AppContainer
rootTag={Object {}}
>
<RootComponent />
</AppContainer>
`;
exports[`apis/AppRegistry/renderApplication getApplication 2`] = `
"<style id=\\"react-native-stylesheet-static\\">
html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:rgba(0,0,0,0);}
body{margin:0;}
@@ -41,6 +49,7 @@ input::-webkit-inner-spin-button,input::-webkit-outer-spin-button,input::-webkit
.rn-boxSizing-deolkf{box-sizing:border-box}
.rn-display-6koalj{display:-webkit-box;display:-moz-box;display:-ms-flexbox;display:-webkit-flex;display:flex}
.rn-flexShrink-1qe8dj5{-webkit-flex-shrink:0;flex-shrink:0}
.rn-flexShrink-1wbh5a2{-webkit-flex-shrink:1;flex-shrink:1}
.rn-flexBasis-1mlwlqe{-webkit-flex-basis:auto;flex-basis:auto}
.rn-flexDirection-eqz5dr{-webkit-box-direction:normal;-webkit-box-orient:vertical;-webkit-flex-direction:column;flex-direction:column}
.rn-marginTop-1mnahxq{margin-top:0px}
@@ -55,5 +64,6 @@ input::-webkit-inner-spin-button,input::-webkit-outer-spin-button,input::-webkit
.rn-paddingLeft-gy4na3{padding-left:0px}
.rn-zIndex-1lgpqti{z-index:0}
.rn-zIndex-1wyyakw{z-index:-1}
.rn-flexGrow-16y2uox{-webkit-flex-grow:1;flex-grow:1}
</style>"
`;

View File

@@ -3,13 +3,13 @@
import { getApplication } from '../renderApplication';
import React from 'react';
const component = () => <div />;
const RootComponent = () => <div />;
describe('apis/AppRegistry/renderApplication', () => {
test('getApplication', () => {
const { element, stylesheet } = getApplication(component, {});
const { element, stylesheet } = getApplication(RootComponent, {});
expect(element).toBeTruthy();
expect(element).toMatchSnapshot();
expect(stylesheet).toMatchSnapshot();
});
});

View File

@@ -6,7 +6,6 @@
* @flow
*/
import { Component } from 'react';
import invariant from 'fbjs/lib/invariant';
import { unmountComponentAtNode } from 'react-dom';
import renderApplication, { getApplication } from './renderApplication';
@@ -14,9 +13,9 @@ import renderApplication, { getApplication } from './renderApplication';
const emptyObject = {};
const runnables = {};
type ComponentProvider = () => Component<any, any, any>;
export type ComponentProvider = () => ReactClass<any>;
type AppConfig = {
export type AppConfig = {
appKey: string,
component?: ComponentProvider,
run?: Function

View File

@@ -8,25 +8,31 @@
import invariant from 'fbjs/lib/invariant';
import { render } from 'react-dom';
import ReactNativeApp from './ReactNativeApp';
import AppContainer from './AppContainer';
import StyleSheet from '../../apis/StyleSheet';
import React, { Component } from 'react';
import React from 'react';
export default function renderApplication(
RootComponent: Component,
RootComponent: ReactClass<Object>,
initialProps: Object,
rootTag: any
) {
invariant(rootTag, 'Expect to have a valid rootTag, instead got ', rootTag);
const component = (
<ReactNativeApp initialProps={initialProps} rootComponent={RootComponent} rootTag={rootTag} />
render(
<AppContainer rootTag={rootTag}>
<RootComponent {...initialProps} />
</AppContainer>,
rootTag
);
render(component, rootTag);
}
export function getApplication(RootComponent: Component, initialProps: Object): Object {
const element = <ReactNativeApp initialProps={initialProps} rootComponent={RootComponent} />;
export function getApplication(RootComponent: ReactClass<Object>, initialProps: Object): Object {
const element = (
<AppContainer rootTag={{}}>
<RootComponent {...initialProps} />
</AppContainer>
);
const stylesheet = StyleSheet.renderToString();
return { element, stylesheet };
}

View File

@@ -1,3 +1,7 @@
/**
* @flow
*/
import ExecutionEnvironment from 'fbjs/lib/ExecutionEnvironment';
import findIndex from 'array-find-index';
import invariant from 'fbjs/lib/invariant';
@@ -17,7 +21,7 @@ class AppState {
static get currentState() {
if (!AppState.isAvailable) {
return AppState.ACTIVE;
return AppStates.ACTIVE;
}
switch (document.visibilityState) {

View File

@@ -2,6 +2,8 @@
* Copyright (c) 2015-present, Nicolas Gallagher.
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* @flow
*/
import merge from 'deep-assign';

Some files were not shown because too many files have changed in this diff Show More