mirror of
https://github.com/zhigang1992/react-native-web.git
synced 2026-04-04 22:57:38 +08:00
Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
65055028c6 | ||
|
|
93f425e414 | ||
|
|
ce4cc8a946 | ||
|
|
77fd867421 | ||
|
|
22999d7e5b | ||
|
|
3c400a662b | ||
|
|
e78ce713cb | ||
|
|
70282cb4ca | ||
|
|
7abdb33a1d | ||
|
|
a9c7b38df9 | ||
|
|
d57fb6407a | ||
|
|
bcdeda5dab | ||
|
|
edef737249 | ||
|
|
9163b974db | ||
|
|
a388ef3e26 | ||
|
|
a84ecefa5d |
8
.babelrc
8
.babelrc
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"presets": [
|
||||
"react-native"
|
||||
],
|
||||
"plugins": [
|
||||
[ "transform-react-remove-prop-types", { "mode": "wrap" } ]
|
||||
]
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
# EditorConfig: http://editorconfig.org
|
||||
|
||||
root = true
|
||||
|
||||
[*]
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
11
.eslintrc
11
.eslintrc
@@ -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,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
[ignore]
|
||||
.*/__tests__/.*
|
||||
.*/examples/.*
|
||||
.*/performance/.*
|
||||
.*/benchmarks/.*
|
||||
.*/docs/.*
|
||||
.*/node_modules/animated/*
|
||||
|
||||
[include]
|
||||
|
||||
84
CONTRIBUTING.md → .github/CONTRIBUTING.md
vendored
84
CONTRIBUTING.md → .github/CONTRIBUTING.md
vendored
@@ -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
1
.gitignore
vendored
@@ -1,3 +1,2 @@
|
||||
node_modules
|
||||
dist
|
||||
dist-examples
|
||||
|
||||
@@ -5,4 +5,5 @@ before_script:
|
||||
- export DISPLAY=:99.0
|
||||
- sh -e /etc/init.d/xvfb start
|
||||
script:
|
||||
- npm run lint
|
||||
- npm test
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -27,7 +27,7 @@ module.exports = {
|
||||
],
|
||||
resolve: {
|
||||
alias: {
|
||||
'react-native': path.join(__dirname, '../../src/module')
|
||||
'react-native': path.join(__dirname, '../../../src/module')
|
||||
}
|
||||
}
|
||||
};
|
||||
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 850 B After Width: | Height: | Size: 850 B |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
@@ -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>
|
||||
));
|
||||
40
package.json
40
package.json
@@ -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",
|
||||
|
||||
65
src/apis/AppRegistry/AppContainer.js
Normal file
65
src/apis/AppRegistry/AppContainer.js
Normal 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;
|
||||
@@ -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;
|
||||
@@ -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>"
|
||||
`;
|
||||
|
||||
@@ -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();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 };
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user