mirror of
https://github.com/zoriya/react-native-web.git
synced 2026-08-15 18:45:06 +00:00
+20
-8
@@ -23,35 +23,47 @@ Install dependencies (requires [yarn](https://yarnpkg.com/en/docs/install):
|
|||||||
yarn
|
yarn
|
||||||
```
|
```
|
||||||
|
|
||||||
## Unit tests
|
## Automated tests
|
||||||
|
|
||||||
|
To run flow:
|
||||||
|
|
||||||
|
```
|
||||||
|
npm run flow
|
||||||
|
```
|
||||||
|
|
||||||
To run the unit tests:
|
To run the unit tests:
|
||||||
|
|
||||||
```
|
```
|
||||||
npm test
|
npm run jest
|
||||||
```
|
```
|
||||||
|
|
||||||
…in watch mode:
|
…in watch mode:
|
||||||
|
|
||||||
```
|
```
|
||||||
npm run test:watch
|
npm run jest:watch
|
||||||
|
```
|
||||||
|
|
||||||
|
To run all automated tests:
|
||||||
|
|
||||||
|
```
|
||||||
|
npm test
|
||||||
```
|
```
|
||||||
|
|
||||||
## Visual tests
|
## Visual tests
|
||||||
|
|
||||||
Run the interactive storybook:
|
To run the interactive storybook:
|
||||||
|
|
||||||
```
|
```
|
||||||
npm run docs:start
|
npm run docs:start
|
||||||
```
|
```
|
||||||
|
|
||||||
Run generate a static build of the storybook:
|
To generate a static build of the storybook:
|
||||||
|
|
||||||
```
|
```
|
||||||
npm run docs:build
|
npm run docs:build
|
||||||
```
|
```
|
||||||
|
|
||||||
Run the performance benchmarks in a browser (opening `./performance/index.html`):
|
To run the performance benchmarks in a browser (opening `./benchmarks/index.html`):
|
||||||
|
|
||||||
```
|
```
|
||||||
npm run benchmarks
|
npm run benchmarks
|
||||||
@@ -59,7 +71,7 @@ npm run benchmarks
|
|||||||
|
|
||||||
## Compile and build
|
## Compile and build
|
||||||
|
|
||||||
Compile the source code to `dist`:
|
To compile the source code to `dist`:
|
||||||
|
|
||||||
```
|
```
|
||||||
npm run compile
|
npm run compile
|
||||||
@@ -73,7 +85,7 @@ npm run build
|
|||||||
|
|
||||||
### Pre-commit
|
### Pre-commit
|
||||||
|
|
||||||
Before creating a commit run:
|
To format and lint code before commit:
|
||||||
|
|
||||||
```
|
```
|
||||||
npm run precommit
|
npm run precommit
|
||||||
|
|||||||
+10
-4
@@ -18,19 +18,25 @@
|
|||||||
"flow": "flow",
|
"flow": "flow",
|
||||||
"fmt": "find benchmarks docs 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",
|
"fmt:cmd": "prettier --print-width=100 --single-quote --write",
|
||||||
|
"jest": "jest",
|
||||||
|
"jest:watch": "npm run test -- --watch",
|
||||||
"lint": "npm run lint:cmd -- benchmarks docs src",
|
"lint": "npm run lint:cmd -- benchmarks docs src",
|
||||||
"lint:cmd": "eslint --fix --ignore-path .gitignore",
|
"lint:cmd": "eslint --fix --ignore-path .gitignore",
|
||||||
"precommit": "lint-staged",
|
"precommit": "lint-staged",
|
||||||
"release": "npm run lint && npm run test && npm run compile && npm run build && npm publish",
|
"release": "npm run lint && npm run test && npm run compile && npm run build && npm publish",
|
||||||
"test": "jest",
|
"test": "flow && jest"
|
||||||
"test:watch": "npm run test -- --watch"
|
|
||||||
},
|
},
|
||||||
"babel": {
|
"babel": {
|
||||||
"presets": [
|
"presets": [
|
||||||
"react-native"
|
"react-native"
|
||||||
],
|
],
|
||||||
"plugins": [
|
"plugins": [
|
||||||
[ "transform-react-remove-prop-types", { "mode": "wrap" } ]
|
[
|
||||||
|
"transform-react-remove-prop-types",
|
||||||
|
{
|
||||||
|
"mode": "wrap"
|
||||||
|
}
|
||||||
|
]
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"jest": {
|
"jest": {
|
||||||
@@ -77,7 +83,7 @@
|
|||||||
"eslint-plugin-promise": "^3.5.0",
|
"eslint-plugin-promise": "^3.5.0",
|
||||||
"eslint-plugin-react": "^6.10.3",
|
"eslint-plugin-react": "^6.10.3",
|
||||||
"file-loader": "^0.11.1",
|
"file-loader": "^0.11.1",
|
||||||
"flow-bin": "^0.46.0",
|
"flow-bin": "^0.47.0",
|
||||||
"jest": "^19.0.2",
|
"jest": "^19.0.2",
|
||||||
"lint-staged": "^3.4.2",
|
"lint-staged": "^3.4.2",
|
||||||
"node-libs-browser": "^0.5.3",
|
"node-libs-browser": "^0.5.3",
|
||||||
|
|||||||
@@ -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,41 +0,0 @@
|
|||||||
/**
|
|
||||||
* @flow
|
|
||||||
*/
|
|
||||||
|
|
||||||
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
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
exports[`apis/AppRegistry/renderApplication getApplication 1`] = `
|
exports[`apis/AppRegistry/renderApplication getApplication 1`] = `
|
||||||
|
<AppContainer
|
||||||
|
rootTag={Object {}}
|
||||||
|
>
|
||||||
|
<RootComponent />
|
||||||
|
</AppContainer>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`apis/AppRegistry/renderApplication getApplication 2`] = `
|
||||||
"<style id=\\"react-native-stylesheet-static\\">
|
"<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);}
|
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;}
|
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-boxSizing-deolkf{box-sizing:border-box}
|
||||||
.rn-display-6koalj{display:-webkit-box;display:-moz-box;display:-ms-flexbox;display:-webkit-flex;display:flex}
|
.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-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-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-flexDirection-eqz5dr{-webkit-box-direction:normal;-webkit-box-orient:vertical;-webkit-flex-direction:column;flex-direction:column}
|
||||||
.rn-marginTop-1mnahxq{margin-top:0px}
|
.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-paddingLeft-gy4na3{padding-left:0px}
|
||||||
.rn-zIndex-1lgpqti{z-index:0}
|
.rn-zIndex-1lgpqti{z-index:0}
|
||||||
.rn-zIndex-1wyyakw{z-index:-1}
|
.rn-zIndex-1wyyakw{z-index:-1}
|
||||||
|
.rn-flexGrow-16y2uox{-webkit-flex-grow:1;flex-grow:1}
|
||||||
</style>"
|
</style>"
|
||||||
`;
|
`;
|
||||||
|
|||||||
@@ -3,13 +3,13 @@
|
|||||||
import { getApplication } from '../renderApplication';
|
import { getApplication } from '../renderApplication';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
const component = () => <div />;
|
const RootComponent = () => <div />;
|
||||||
|
|
||||||
describe('apis/AppRegistry/renderApplication', () => {
|
describe('apis/AppRegistry/renderApplication', () => {
|
||||||
test('getApplication', () => {
|
test('getApplication', () => {
|
||||||
const { element, stylesheet } = getApplication(component, {});
|
const { element, stylesheet } = getApplication(RootComponent, {});
|
||||||
|
|
||||||
expect(element).toBeTruthy();
|
expect(element).toMatchSnapshot();
|
||||||
expect(stylesheet).toMatchSnapshot();
|
expect(stylesheet).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
* @flow
|
* @flow
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Component } from 'react';
|
|
||||||
import invariant from 'fbjs/lib/invariant';
|
import invariant from 'fbjs/lib/invariant';
|
||||||
import { unmountComponentAtNode } from 'react-dom';
|
import { unmountComponentAtNode } from 'react-dom';
|
||||||
import renderApplication, { getApplication } from './renderApplication';
|
import renderApplication, { getApplication } from './renderApplication';
|
||||||
@@ -14,9 +13,9 @@ import renderApplication, { getApplication } from './renderApplication';
|
|||||||
const emptyObject = {};
|
const emptyObject = {};
|
||||||
const runnables = {};
|
const runnables = {};
|
||||||
|
|
||||||
type ComponentProvider = () => Component<any, any, any>;
|
export type ComponentProvider = () => ReactClass<any>;
|
||||||
|
|
||||||
type AppConfig = {
|
export type AppConfig = {
|
||||||
appKey: string,
|
appKey: string,
|
||||||
component?: ComponentProvider,
|
component?: ComponentProvider,
|
||||||
run?: Function
|
run?: Function
|
||||||
|
|||||||
@@ -8,25 +8,31 @@
|
|||||||
|
|
||||||
import invariant from 'fbjs/lib/invariant';
|
import invariant from 'fbjs/lib/invariant';
|
||||||
import { render } from 'react-dom';
|
import { render } from 'react-dom';
|
||||||
import ReactNativeApp from './ReactNativeApp';
|
import AppContainer from './AppContainer';
|
||||||
import StyleSheet from '../../apis/StyleSheet';
|
import StyleSheet from '../../apis/StyleSheet';
|
||||||
import React, { Component } from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
export default function renderApplication(
|
export default function renderApplication(
|
||||||
RootComponent: Component,
|
RootComponent: ReactClass<Object>,
|
||||||
initialProps: Object,
|
initialProps: Object,
|
||||||
rootTag: any
|
rootTag: any
|
||||||
) {
|
) {
|
||||||
invariant(rootTag, 'Expect to have a valid rootTag, instead got ', rootTag);
|
invariant(rootTag, 'Expect to have a valid rootTag, instead got ', rootTag);
|
||||||
|
|
||||||
const component = (
|
render(
|
||||||
<ReactNativeApp initialProps={initialProps} rootComponent={RootComponent} rootTag={rootTag} />
|
<AppContainer rootTag={rootTag}>
|
||||||
|
<RootComponent {...initialProps} />
|
||||||
|
</AppContainer>,
|
||||||
|
rootTag
|
||||||
);
|
);
|
||||||
render(component, rootTag);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getApplication(RootComponent: Component, initialProps: Object): Object {
|
export function getApplication(RootComponent: ReactClass<Object>, initialProps: Object): Object {
|
||||||
const element = <ReactNativeApp initialProps={initialProps} rootComponent={RootComponent} />;
|
const element = (
|
||||||
|
<AppContainer rootTag={{}}>
|
||||||
|
<RootComponent {...initialProps} />
|
||||||
|
</AppContainer>
|
||||||
|
);
|
||||||
const stylesheet = StyleSheet.renderToString();
|
const stylesheet = StyleSheet.renderToString();
|
||||||
return { element, stylesheet };
|
return { element, stylesheet };
|
||||||
}
|
}
|
||||||
|
|||||||
+23
-20
@@ -16,30 +16,33 @@ class Clipboard {
|
|||||||
|
|
||||||
static setString(text) {
|
static setString(text) {
|
||||||
let success = false;
|
let success = false;
|
||||||
|
const body = document.body;
|
||||||
|
|
||||||
// add the text to a hidden node
|
if (body) {
|
||||||
const node = document.createElement('span');
|
// add the text to a hidden node
|
||||||
node.textContent = text;
|
const node = document.createElement('span');
|
||||||
node.style.position = 'absolute';
|
node.textContent = text;
|
||||||
node.style.opacity = '0';
|
node.style.position = 'absolute';
|
||||||
document.body.appendChild(node);
|
node.style.opacity = '0';
|
||||||
|
body.appendChild(node);
|
||||||
|
|
||||||
// select the text
|
// select the text
|
||||||
const selection = window.getSelection();
|
const selection = window.getSelection();
|
||||||
selection.removeAllRanges();
|
selection.removeAllRanges();
|
||||||
const range = document.createRange();
|
const range = document.createRange();
|
||||||
range.selectNodeContents(node);
|
range.selectNodeContents(node);
|
||||||
selection.addRange(range);
|
selection.addRange(range);
|
||||||
|
|
||||||
// attempt to copy
|
// attempt to copy
|
||||||
try {
|
try {
|
||||||
document.execCommand('copy');
|
document.execCommand('copy');
|
||||||
success = true;
|
success = true;
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
|
|
||||||
// remove selection and node
|
// remove selection and node
|
||||||
selection.removeAllRanges();
|
selection.removeAllRanges();
|
||||||
document.body.removeChild(node);
|
body.removeChild(node);
|
||||||
|
}
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,9 @@ const isRTL = () => {
|
|||||||
|
|
||||||
const onChange = () => {
|
const onChange = () => {
|
||||||
if (ExecutionEnvironment.canUseDOM) {
|
if (ExecutionEnvironment.canUseDOM) {
|
||||||
document.documentElement.setAttribute('dir', isRTL() ? 'rtl' : 'ltr');
|
if (document.documentElement && document.documentElement.setAttribute) {
|
||||||
|
document.documentElement.setAttribute('dir', isRTL() ? 'rtl' : 'ltr');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+18
-12
@@ -33,19 +33,25 @@ const Linking = {
|
|||||||
*/
|
*/
|
||||||
const iframeOpen = url => {
|
const iframeOpen = url => {
|
||||||
const noOpener = url.indexOf('mailto:') !== 0;
|
const noOpener = url.indexOf('mailto:') !== 0;
|
||||||
const iframe = document.createElement('iframe');
|
const body = document.body;
|
||||||
iframe.style.display = 'none';
|
if (body) {
|
||||||
document.body.appendChild(iframe);
|
const iframe = document.createElement('iframe');
|
||||||
|
iframe.style.display = 'none';
|
||||||
|
body.appendChild(iframe);
|
||||||
|
|
||||||
const iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
|
const iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
|
||||||
const script = iframeDoc.createElement('script');
|
const iframeBody = iframeDoc.body;
|
||||||
const openerExpression = noOpener ? 'child.opener = null' : '';
|
if (iframeBody) {
|
||||||
script.text = `
|
const script = iframeDoc.createElement('script');
|
||||||
window.parent = null; window.top = null; window.frameElement = null;
|
const openerExpression = noOpener ? 'child.opener = null' : '';
|
||||||
var child = window.open("${url}"); ${openerExpression};
|
script.text = `
|
||||||
`;
|
window.parent = null; window.top = null; window.frameElement = null;
|
||||||
iframeDoc.body.appendChild(script);
|
var child = window.open("${url}"); ${openerExpression};
|
||||||
document.body.removeChild(iframe);
|
`;
|
||||||
|
iframeBody.appendChild(script);
|
||||||
|
}
|
||||||
|
body.removeChild(iframe);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = Linking;
|
module.exports = Linking;
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ function getStyle(style) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function flattenStyle(style: ?StyleObj): ?Object {
|
function flattenStyle(style: ?StyleObj): ?Object {
|
||||||
if (!style) {
|
if (style == null || typeof style === 'boolean') {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ import React, { Component } from 'react';
|
|||||||
import { bool, number } from 'prop-types';
|
import { bool, number } from 'prop-types';
|
||||||
|
|
||||||
class ProgressBar extends Component {
|
class ProgressBar extends Component {
|
||||||
|
_progressElement = null;
|
||||||
|
|
||||||
static displayName = 'ProgressBar';
|
static displayName = 'ProgressBar';
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
@@ -58,17 +60,19 @@ class ProgressBar extends Component {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
_setProgressRef = component => {
|
_setProgressRef = element => {
|
||||||
this._progressRef = component;
|
this._progressElement = element;
|
||||||
};
|
};
|
||||||
|
|
||||||
_updateProgressWidth = () => {
|
_updateProgressWidth = () => {
|
||||||
const { indeterminate, progress } = this.props;
|
const { indeterminate, progress } = this.props;
|
||||||
const percentageProgress = indeterminate ? 50 : progress * 100;
|
const percentageProgress = indeterminate ? 50 : progress * 100;
|
||||||
const width = indeterminate ? '25%' : `${percentageProgress}%`;
|
const width = indeterminate ? '25%' : `${percentageProgress}%`;
|
||||||
this._progressRef.setNativeProps({
|
if (this._progressElement) {
|
||||||
style: { width }
|
this._progressElement.setNativeProps({
|
||||||
});
|
style: { width }
|
||||||
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,8 @@ const thumbDefaultBoxShadow = '0px 1px 3px rgba(0,0,0,0.5)';
|
|||||||
const thumbFocusedBoxShadow = `${thumbDefaultBoxShadow}, 0 0 0 10px rgba(0,0,0,0.1)`;
|
const thumbFocusedBoxShadow = `${thumbDefaultBoxShadow}, 0 0 0 10px rgba(0,0,0,0.1)`;
|
||||||
|
|
||||||
class Switch extends PureComponent {
|
class Switch extends PureComponent {
|
||||||
_checkbox: HTMLInputElement;
|
_checkboxElement: HTMLInputElement;
|
||||||
|
_thumbElement = null;
|
||||||
|
|
||||||
static displayName = 'Switch';
|
static displayName = 'Switch';
|
||||||
|
|
||||||
@@ -44,11 +45,11 @@ class Switch extends PureComponent {
|
|||||||
};
|
};
|
||||||
|
|
||||||
blur() {
|
blur() {
|
||||||
UIManager.blur(this._checkbox);
|
UIManager.blur(this._checkboxElement);
|
||||||
}
|
}
|
||||||
|
|
||||||
focus() {
|
focus() {
|
||||||
UIManager.focus(this._checkbox);
|
UIManager.focus(this._checkboxElement);
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
@@ -136,15 +137,17 @@ class Switch extends PureComponent {
|
|||||||
_handleFocusState = (event: Object) => {
|
_handleFocusState = (event: Object) => {
|
||||||
const isFocused = event.nativeEvent.type === 'focus';
|
const isFocused = event.nativeEvent.type === 'focus';
|
||||||
const boxShadow = isFocused ? thumbFocusedBoxShadow : thumbDefaultBoxShadow;
|
const boxShadow = isFocused ? thumbFocusedBoxShadow : thumbDefaultBoxShadow;
|
||||||
this._thumb.setNativeProps({ style: { boxShadow } });
|
if (this._thumbElement) {
|
||||||
|
this._thumbElement.setNativeProps({ style: { boxShadow } });
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
_setCheckboxRef = component => {
|
_setCheckboxRef = element => {
|
||||||
this._checkbox = component;
|
this._checkboxElement = element;
|
||||||
};
|
};
|
||||||
|
|
||||||
_setThumbRef = component => {
|
_setThumbRef = element => {
|
||||||
this._thumb = component;
|
this._thumbElement = element;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ var PRESS_RETENTION_OFFSET = { top: 20, left: 20, right: 20, bottom: 30 };
|
|||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
var TouchableOpacity = createReactClass({
|
var TouchableOpacity = createReactClass({
|
||||||
|
displayName: 'TouchableOpacity',
|
||||||
mixins: [TimerMixin, Touchable.Mixin, NativeMethodsMixin],
|
mixins: [TimerMixin, Touchable.Mixin, NativeMethodsMixin],
|
||||||
|
|
||||||
propTypes: {
|
propTypes: {
|
||||||
|
|||||||
@@ -82,6 +82,7 @@ const TouchableWithoutFeedback = createReactClass({
|
|||||||
* reactivated! Move it back and forth several times while the scroll view
|
* reactivated! Move it back and forth several times while the scroll view
|
||||||
* is disabled. Ensure you pass in a constant to reduce memory allocations.
|
* is disabled. Ensure you pass in a constant to reduce memory allocations.
|
||||||
*/
|
*/
|
||||||
|
// $FlowFixMe
|
||||||
pressRetentionOffset: EdgeInsetsPropType,
|
pressRetentionOffset: EdgeInsetsPropType,
|
||||||
/**
|
/**
|
||||||
* This defines how far your touch can start away from the button. This is
|
* This defines how far your touch can start away from the button. This is
|
||||||
@@ -91,6 +92,7 @@ const TouchableWithoutFeedback = createReactClass({
|
|||||||
* of sibling views always takes precedence if a touch hits two overlapping
|
* of sibling views always takes precedence if a touch hits two overlapping
|
||||||
* views.
|
* views.
|
||||||
*/
|
*/
|
||||||
|
// $FlowFixMe
|
||||||
hitSlop: EdgeInsetsPropType
|
hitSlop: EdgeInsetsPropType
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
/* eslint-disable */
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copyright (c) 2015-present, Facebook, Inc.
|
* Copyright (c) 2015-present, Facebook, Inc.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
@@ -8,29 +6,28 @@
|
|||||||
* 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.
|
||||||
*
|
*
|
||||||
|
* @providesModule createStrictShapeTypeChecker
|
||||||
* @flow
|
* @flow
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import invariant from 'fbjs/lib/invariant';
|
import invariant from 'fbjs/lib/invariant';
|
||||||
import ReactPropTypeLocationNames from '../vendor/ReactPropTypeLocationNames';
|
|
||||||
import ReactPropTypesSecret from '../vendor/ReactPropTypesSecret';
|
|
||||||
|
|
||||||
function createStrictShapeTypeChecker(shapeTypes: {
|
function createStrictShapeTypeChecker(shapeTypes: {
|
||||||
[key: string]: ReactPropsCheckType
|
[key: string]: ReactPropsCheckType
|
||||||
}): ReactPropsChainableTypeChecker {
|
}): ReactPropsChainableTypeChecker {
|
||||||
function checkType(isRequired, props, propName, componentName, location?) {
|
function checkType(isRequired, props, propName, componentName, location?, ...rest) {
|
||||||
if (!props[propName]) {
|
if (!props[propName]) {
|
||||||
if (isRequired) {
|
if (isRequired) {
|
||||||
invariant(
|
invariant(
|
||||||
false,
|
false,
|
||||||
`Required object \`${propName}\` was not specified in ` + `\`${componentName}\`.`
|
`Required object \`${propName}\` was not specified in \`${componentName}\`.`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var propValue = props[propName];
|
const propValue = props[propName];
|
||||||
var propType = typeof propValue;
|
const propType = typeof propValue;
|
||||||
var locationName = (location && ReactPropTypeLocationNames[location]) || '(unknown)';
|
const locationName = location || '(unknown)';
|
||||||
if (propType !== 'object') {
|
if (propType !== 'object') {
|
||||||
invariant(
|
invariant(
|
||||||
false,
|
false,
|
||||||
@@ -40,24 +37,24 @@ function createStrictShapeTypeChecker(shapeTypes: {
|
|||||||
}
|
}
|
||||||
// We need to check all keys in case some are required but missing from
|
// We need to check all keys in case some are required but missing from
|
||||||
// props.
|
// props.
|
||||||
var allKeys = { ...props[propName], ...shapeTypes };
|
const allKeys = { ...props[propName], ...shapeTypes };
|
||||||
for (var key in allKeys) {
|
for (const key in allKeys) {
|
||||||
var checker = shapeTypes[key];
|
const checker = shapeTypes[key];
|
||||||
if (!checker) {
|
if (!checker) {
|
||||||
invariant(
|
invariant(
|
||||||
false,
|
false,
|
||||||
`Invalid props.${propName} key \`${key}\` supplied to \`${componentName}\`.` +
|
`Invalid props.${propName} key \`${key}\` supplied to \`${componentName}\`.` +
|
||||||
`\nBad object: ` +
|
'\nBad object: ' +
|
||||||
JSON.stringify(props[propName], null, ' ') +
|
JSON.stringify(props[propName], null, ' ') +
|
||||||
`\nValid keys: ` +
|
'\nValid keys: ' +
|
||||||
JSON.stringify(Object.keys(shapeTypes), null, ' ')
|
JSON.stringify(Object.keys(shapeTypes), null, ' ')
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
var error = checker(propValue, key, componentName, location, null, ReactPropTypesSecret);
|
const error = checker(propValue, key, componentName, location, ...rest);
|
||||||
if (error) {
|
if (error) {
|
||||||
invariant(
|
invariant(
|
||||||
false,
|
false,
|
||||||
error.message + `\nBad object: ` + JSON.stringify(props[propName], null, ' ')
|
error.message + '\nBad object: ' + JSON.stringify(props[propName], null, ' ')
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -66,9 +63,10 @@ function createStrictShapeTypeChecker(shapeTypes: {
|
|||||||
props: { [key: string]: any },
|
props: { [key: string]: any },
|
||||||
propName: string,
|
propName: string,
|
||||||
componentName: string,
|
componentName: string,
|
||||||
location?: string
|
location?: string,
|
||||||
|
...rest
|
||||||
): ?Error {
|
): ?Error {
|
||||||
return checkType(false, props, propName, componentName, location);
|
return checkType(false, props, propName, componentName, location, ...rest);
|
||||||
}
|
}
|
||||||
chainedCheckType.isRequired = checkType.bind(null, true);
|
chainedCheckType.isRequired = checkType.bind(null, true);
|
||||||
return chainedCheckType;
|
return chainedCheckType;
|
||||||
|
|||||||
@@ -2756,9 +2756,9 @@ flatten@^1.0.2:
|
|||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.2.tgz#dae46a9d78fbe25292258cc1e780a41d95c03782"
|
resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.2.tgz#dae46a9d78fbe25292258cc1e780a41d95c03782"
|
||||||
|
|
||||||
flow-bin@^0.46.0:
|
flow-bin@^0.47.0:
|
||||||
version "0.46.0"
|
version "0.47.0"
|
||||||
resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.46.0.tgz#06ad7fe19dddb1042264438064a2a32fee12b872"
|
resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.47.0.tgz#a2a08ab3e0d1f1cb57d17e27b30b118b62fda367"
|
||||||
|
|
||||||
flow-parser@0.45.0:
|
flow-parser@0.45.0:
|
||||||
version "0.45.0"
|
version "0.45.0"
|
||||||
|
|||||||
Reference in New Issue
Block a user