mirror of
https://github.com/zhigang1992/react-native-web.git
synced 2026-03-30 23:23:35 +08:00
Compare commits
70 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b545fe47a7 | ||
|
|
4da4dd57c4 | ||
|
|
3e12ddfb2b | ||
|
|
3ecf5d2ed2 | ||
|
|
0a5acdb996 | ||
|
|
a712a58eba | ||
|
|
6de892c92b | ||
|
|
495defd69b | ||
|
|
1a20fcfce6 | ||
|
|
ed1e45a43d | ||
|
|
556dc8926e | ||
|
|
66cf45b90b | ||
|
|
d1e49e06e6 | ||
|
|
8bf28dbe43 | ||
|
|
9ae95d0797 | ||
|
|
321051b723 | ||
|
|
5f68542529 | ||
|
|
82c044ee33 | ||
|
|
9bcc67e73a | ||
|
|
f1ce6c2acb | ||
|
|
034108a2a0 | ||
|
|
f96d7b868f | ||
|
|
0dfe319d41 | ||
|
|
b7e970f4e6 | ||
|
|
02e62ad5d6 | ||
|
|
541d2458fb | ||
|
|
b1e860ab40 | ||
|
|
e8eab9b3ec | ||
|
|
6bc76c3c92 | ||
|
|
2acd8e477c | ||
|
|
ff2b0c9bdc | ||
|
|
79208720d1 | ||
|
|
fca04c4125 | ||
|
|
5b5b72cc19 | ||
|
|
217ad97bfd | ||
|
|
3e3cfc5325 | ||
|
|
da86ea98fc | ||
|
|
5f3e422b5c | ||
|
|
1f1f89b062 | ||
|
|
0f79960b85 | ||
|
|
117ce59f27 | ||
|
|
214121480e | ||
|
|
6261536f57 | ||
|
|
a748b7e606 | ||
|
|
92952ee746 | ||
|
|
c22a9aff7d | ||
|
|
dd8a3c8d59 | ||
|
|
4a1abee1df | ||
|
|
92ef3ffbb8 | ||
|
|
899763bc34 | ||
|
|
c69ad3c2d6 | ||
|
|
9a5b932139 | ||
|
|
ba96e457b4 | ||
|
|
bdfe943bd5 | ||
|
|
3870445b7e | ||
|
|
5395a3e8bc | ||
|
|
45b3d8b0df | ||
|
|
f1ee3c003a | ||
|
|
606181406c | ||
|
|
b537400f38 | ||
|
|
0a4fdc155e | ||
|
|
0b8e59974b | ||
|
|
22eebea633 | ||
|
|
5dd414f9aa | ||
|
|
72c72f6530 | ||
|
|
de970f9dbb | ||
|
|
e8d6c5b4dd | ||
|
|
e91a5ae13e | ||
|
|
b08bfb9ad5 | ||
|
|
5353011ee4 |
@@ -2,7 +2,6 @@
|
||||
.*/__tests__/.*
|
||||
.*/benchmarks/.*
|
||||
.*/docs/.*
|
||||
.*/node_modules/animated/*
|
||||
.*/node_modules/babel-plugin-transform-react-remove-prop-types/*
|
||||
|
||||
[include]
|
||||
|
||||
@@ -5,5 +5,4 @@ before_script:
|
||||
- export DISPLAY=:99.0
|
||||
- sh -e /etc/init.d/xvfb start
|
||||
script:
|
||||
- npm run lint
|
||||
- npm test
|
||||
- yarn lint
|
||||
|
||||
@@ -107,7 +107,6 @@ AppRegistry.runApplication('MyApp', { rootTag: document.getElementById('react-ro
|
||||
|
||||
* [Glitch](https://glitch.com/edit/#!/react-native-web-playground)
|
||||
* [create-react-app](https://github.com/facebookincubator/create-react-app)
|
||||
* [re-start](https://github.com/react-everywhere/re-start)
|
||||
|
||||
## Related projects
|
||||
|
||||
@@ -121,7 +120,7 @@ AppRegistry.runApplication('MyApp', { rootTag: document.getElementById('react-ro
|
||||
React Native for Web is [BSD licensed](LICENSE).
|
||||
|
||||
[npm-image]: https://badge.fury.io/js/react-native-web.svg
|
||||
[npm-url]: https://npmjs.org/package/react-native-web
|
||||
[npm-url]: https://yarnpkg.com/en/package/react-native-web
|
||||
[react-native-url]: https://facebook.github.io/react-native/
|
||||
[travis-image]: https://travis-ci.org/necolas/react-native-web.svg?branch=master
|
||||
[travis-url]: https://travis-ci.org/necolas/react-native-web
|
||||
|
||||
@@ -103,3 +103,59 @@ const { InvalidThing, TouchableOpacity } = require('react-native');
|
||||
const TouchableOpacity = require('react-native-web/dist/components/Touchable/TouchableOpacity');
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`10. Rewrite react-native paths for react-native-web 1`] = `
|
||||
"
|
||||
export { View } from 'react-native';
|
||||
|
||||
↓ ↓ ↓ ↓ ↓ ↓
|
||||
|
||||
export { default as View } from 'react-native-web/dist/components/View';
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`11. Rewrite react-native paths for react-native-web 1`] = `
|
||||
"
|
||||
export { Switch, Text, View as MyView, ViewPropTypes } from 'react-native';
|
||||
|
||||
↓ ↓ ↓ ↓ ↓ ↓
|
||||
|
||||
export { default as Switch } from 'react-native-web/dist/components/Switch';
|
||||
export { default as Text } from 'react-native-web/dist/components/Text';
|
||||
export { default as MyView } from 'react-native-web/dist/components/View';
|
||||
export { default as ViewPropTypes } from 'react-native-web/dist/components/View/ViewPropTypes';
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`12. Rewrite react-native paths for react-native-web 1`] = `
|
||||
"
|
||||
export { createElement, Switch, StyleSheet } from 'react-native';
|
||||
|
||||
↓ ↓ ↓ ↓ ↓ ↓
|
||||
|
||||
export { default as createElement } from 'react-native-web/dist/modules/createElement';
|
||||
export { default as Switch } from 'react-native-web/dist/components/Switch';
|
||||
export { default as StyleSheet } from 'react-native-web/dist/apis/StyleSheet';
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`13. Rewrite react-native paths for react-native-web 1`] = `
|
||||
"
|
||||
export { InvalidThing, TouchableOpacity } from 'react-native';
|
||||
|
||||
↓ ↓ ↓ ↓ ↓ ↓
|
||||
|
||||
export { InvalidThing } from 'react-native-web';
|
||||
export { default as TouchableOpacity } from 'react-native-web/dist/components/Touchable/TouchableOpacity';
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`14. Rewrite react-native paths for react-native-web 1`] = `
|
||||
"
|
||||
export { default as RNW } from 'react-native';
|
||||
|
||||
↓ ↓ ↓ ↓ ↓ ↓
|
||||
|
||||
export { default as RNW } from 'react-native-web';
|
||||
"
|
||||
`;
|
||||
|
||||
@@ -30,6 +30,13 @@ pluginTester({
|
||||
// "let { Switch, Text, View: MyView } = require('react-native-web');",
|
||||
// "var { createElement, Switch, StyleSheet } = require('react-native-web');",
|
||||
// "const { InvalidThing, TouchableOpacity } = require('react-native-web');",
|
||||
|
||||
// export react-native
|
||||
"export { View } from 'react-native';",
|
||||
"export { Switch, Text, View as MyView, ViewPropTypes } from 'react-native';",
|
||||
"export { createElement, Switch, StyleSheet } from 'react-native';",
|
||||
"export { InvalidThing, TouchableOpacity } from 'react-native';",
|
||||
"export { default as RNW } from 'react-native';",
|
||||
{
|
||||
code: "const RNW = require('react-native');",
|
||||
output: "const RNW = require('react-native');",
|
||||
|
||||
@@ -7,7 +7,7 @@ const getDistLocation = importName => {
|
||||
case 'AppRegistry':
|
||||
case 'AppState':
|
||||
case 'AsyncStorage':
|
||||
case 'BackAndroid':
|
||||
case 'BackHandler':
|
||||
case 'Clipboard':
|
||||
case 'Dimensions':
|
||||
case 'Easing':
|
||||
@@ -27,6 +27,7 @@ const getDistLocation = importName => {
|
||||
|
||||
// components
|
||||
case 'ActivityIndicator':
|
||||
case 'ART':
|
||||
case 'Button':
|
||||
case 'FlatList':
|
||||
case 'Image':
|
||||
@@ -106,7 +107,7 @@ module.exports = function({ types: t }) {
|
||||
visitor: {
|
||||
ImportDeclaration(path) {
|
||||
const { source, specifiers } = path.node;
|
||||
if (source.value === 'react-native' && specifiers.length) {
|
||||
if (source && source.value === 'react-native' && specifiers.length) {
|
||||
const imports = specifiers
|
||||
.map(specifier => {
|
||||
if (t.isImportSpecifier(specifier)) {
|
||||
@@ -127,6 +128,35 @@ module.exports = function({ types: t }) {
|
||||
path.replaceWithMultiple(imports);
|
||||
}
|
||||
},
|
||||
ExportNamedDeclaration(path) {
|
||||
const { source, specifiers } = path.node;
|
||||
if (source && source.value === 'react-native' && specifiers.length) {
|
||||
const exports = specifiers
|
||||
.map(specifier => {
|
||||
if (t.isExportSpecifier(specifier)) {
|
||||
const exportName = specifier.exported.name;
|
||||
const localName = specifier.local.name;
|
||||
const distLocation = getDistLocation(localName);
|
||||
|
||||
if (distLocation) {
|
||||
return t.exportNamedDeclaration(
|
||||
null,
|
||||
[t.exportSpecifier(t.identifier('default'), t.identifier(exportName))],
|
||||
t.stringLiteral(distLocation)
|
||||
);
|
||||
}
|
||||
return t.exportNamedDeclaration(
|
||||
null,
|
||||
[specifier],
|
||||
t.stringLiteral('react-native-web')
|
||||
);
|
||||
}
|
||||
})
|
||||
.filter(Boolean);
|
||||
|
||||
path.replaceWithMultiple(exports);
|
||||
}
|
||||
},
|
||||
VariableDeclaration(path) {
|
||||
if (isReactNativeRequire(t, path.node)) {
|
||||
const { id } = path.node.declarations[0];
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
# Performance
|
||||
|
||||
To run these benchmarks:
|
||||
To run these benchmarks from the root of the project:
|
||||
|
||||
```
|
||||
npm run build:performance
|
||||
open ./performance/index.html
|
||||
yarn benchmark
|
||||
open ./benchmarks/index.html
|
||||
```
|
||||
|
||||
Append `?fastest` to the URL to include the fastest "other libraries", and
|
||||
@@ -14,12 +14,9 @@ Append `?fastest` to the URL to include the fastest "other libraries", and
|
||||
|
||||
The components used in the render benchmarks are simple enough to be
|
||||
implemented by multiple UI or style libraries. The implementations are not
|
||||
equivalent in functionality. For example, React Native for Web's stylesheet is
|
||||
unique in that it also converts React Native styles to DOM styles, has
|
||||
deterministic resolution, and supports RTL layout.
|
||||
|
||||
`react-native-web/stylesheet` is a comparative baseline that implements a
|
||||
simple `View` without much of React Native's functionality.
|
||||
equivalent in functionality. For example, the "React Native for Web" benchmark includes a
|
||||
complete `View` implementation and the `StyleSheet` also converts React Native
|
||||
styles to DOM styles, has deterministic resolution, and supports RTL layout.
|
||||
|
||||
## Benchmark results
|
||||
|
||||
@@ -27,26 +24,24 @@ Typical render timings*: mean ± two standard deviations.
|
||||
|
||||
| Implementation | Deep tree (ms) | Wide tree (ms) | Tweets (ms) |
|
||||
| :--- | ---: | ---: | ---: |
|
||||
| `css-modules` | `88.83` `±18.63` | `198.79` `±22.98` | |
|
||||
| `react-native-web/stylesheet@0.0.121` | `91.17` `±19.29` | `209.67` `±32.38` | |
|
||||
| `react-native-web@0.0.121` | `124.21` `±16.84` | `264.55` `±38.75` | `16.90` `±7.30ms` |
|
||||
| `css-modules` | `80.47` `±25.13` | `144.87` `±32.70` | |
|
||||
| `react-native-web@0.2.1` | `88.68` `±28.78` | `178.17` `±39.90` | `13.78` `±2.90ms` |
|
||||
|
||||
Other libraries
|
||||
|
||||
| Implementation | Deep tree (ms) | Wide tree (ms) |
|
||||
| Implementation | Deep tree (ms) | Wide tree (ms) |
|
||||
| :--- | ---: | ---: |
|
||||
| `aphrodite@1.2.3` | `91.73` `±41.63` | `197.72` `±44.90` |
|
||||
| `styletron@2.5.1` | `94.73` `±37.58` | `201.81` `±57.93` |
|
||||
| `glamor@2.20.40` | `146.60` `±26.73` | `277.46` `±29.17` |
|
||||
| `emotion@7.2.2` | `150.79` `±38.29` | `282.18` `±41.79` |
|
||||
| `react-jss@7.1.0` | `201.83` `±34.65` | `428.61` `±47.8` |
|
||||
| `reactxp@0.42.1` | `262.69` `±24.14` | `595.20` `±66.17` |
|
||||
| `styled-components@2.1.2` | `280.59` `±31.77` | `599.00` `±62.99` |
|
||||
| `styled-components/primitives@2.1.2` | `291.74` `±48.96` | `606.57` `±78.18` |
|
||||
| `radium@0.19.4` | `563.94` `±69.91` | `1139.18` `±152.59` |
|
||||
| `styletron@3.0.0-rc.5` | `79.41` `±27.49` | `152.95` `±29.46` |
|
||||
| `aphrodite@1.2.5` | `85.13` `±25.39` | `162.87` `±25.91` |
|
||||
| `glamor@2.20.40` | `109.92` `±29.88` | `193.01` `±32.03` |
|
||||
| `react-jss@8.2.0` | `134.28` `±49.00` | `278.78` `±50.39` |
|
||||
| `emotion@8.0.12` | `139.08` `±46.18` | `253.45` `±52.69` |
|
||||
| `styled-components@2.3.2` | `194.43` `416.28` | `404.86` `±56.59` |
|
||||
| `reactxp@0.46.6` | `219.46` `±57.24` | `424.18` `±76.10` |
|
||||
| `radium@0.19.6` | `359.32` `±90.27` | `795.91` `±88.93` |
|
||||
|
||||
These results indicate that style render performance is not a significant
|
||||
differentiating factor between `aphrodite`, `css-modules`, `react-native-web`,
|
||||
and `styletron`.
|
||||
These results indicate that render times when using `react-native-web`,
|
||||
`css-modules`, `aphrodite`, and `styletron` are roughly equivalent and
|
||||
significantly faster than alternatives.
|
||||
|
||||
*MacBook Pro (13-inch, Early 2015); 3.1 GHz Intel Core i7; 16 GB 1867 MHz DDR3. Google Chrome 58 (2x CPU slowdown).
|
||||
*MacBook Pro (13-inch, Early 2011); 2.3 GHz Intel Core i5; 8 GB 1333 MHz DDR3. Google Chrome 62.
|
||||
|
||||
@@ -5,9 +5,7 @@ import glamor from './src/glamor';
|
||||
import jss from './src/jss';
|
||||
import radium from './src/radium';
|
||||
import reactNative from './src/react-native';
|
||||
import reactNativeStyleSheet from './src/react-native-stylesheet';
|
||||
import styledComponents from './src/styled-components';
|
||||
import styledComponentsPrimitives from './src/styled-components-primitives';
|
||||
import styletron from './src/styletron';
|
||||
import xp from './src/reactxp';
|
||||
|
||||
@@ -23,37 +21,33 @@ const coreTests = [
|
||||
|
||||
() => renderDeepTree('css-modules', cssModules),
|
||||
() => renderWideTree('css-modules', cssModules),
|
||||
() => renderDeepTree('react-native-web/stylesheet', reactNativeStyleSheet),
|
||||
() => renderWideTree('react-native-web/stylesheet', reactNativeStyleSheet),
|
||||
() => renderDeepTree('react-native-web', reactNative),
|
||||
() => renderWideTree('react-native-web', reactNative)
|
||||
];
|
||||
|
||||
const fastestTests = [
|
||||
() => renderDeepTree('aphrodite', aphrodite),
|
||||
() => renderWideTree('aphrodite', aphrodite),
|
||||
() => renderDeepTree('styletron', styletron),
|
||||
() => renderWideTree('styletron', styletron)
|
||||
() => renderWideTree('styletron', styletron),
|
||||
() => renderDeepTree('aphrodite', aphrodite),
|
||||
() => renderWideTree('aphrodite', aphrodite)
|
||||
];
|
||||
|
||||
/**
|
||||
* Optionally run tests using other libraries
|
||||
*/
|
||||
const restTests = [
|
||||
() => renderDeepTree('emotion', emotion),
|
||||
() => renderWideTree('emotion', emotion),
|
||||
() => renderDeepTree('glamor', glamor),
|
||||
() => renderWideTree('glamor', glamor),
|
||||
() => renderDeepTree('radium', radium),
|
||||
() => renderWideTree('radium', radium),
|
||||
() => renderDeepTree('reactxp', xp),
|
||||
() => renderWideTree('reactxp', xp),
|
||||
() => renderDeepTree('react-jss', jss),
|
||||
() => renderWideTree('react-jss', jss),
|
||||
() => renderDeepTree('emotion', emotion),
|
||||
() => renderWideTree('emotion', emotion),
|
||||
() => renderDeepTree('styled-components', styledComponents),
|
||||
() => renderWideTree('styled-components', styledComponents),
|
||||
() => renderDeepTree('styled-components/primitives', styledComponentsPrimitives),
|
||||
() => renderWideTree('styled-components/primitives', styledComponentsPrimitives)
|
||||
() => renderDeepTree('reactxp', xp),
|
||||
() => renderWideTree('reactxp', xp),
|
||||
() => renderDeepTree('radium', radium),
|
||||
() => renderWideTree('radium', radium)
|
||||
];
|
||||
|
||||
const tests = [...coreTests];
|
||||
|
||||
@@ -2,21 +2,20 @@
|
||||
"name": "benchmarks",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"aphrodite": "^1.2.3",
|
||||
"aphrodite": "^1.2.5",
|
||||
"classnames": "^2.2.5",
|
||||
"emotion": "^7.2.2",
|
||||
"emotion": "^8.0.12",
|
||||
"glamor": "^2.20.40",
|
||||
"marky": "^1.2.0",
|
||||
"radium": "^0.19.4",
|
||||
"react-jss": "^7.1.0",
|
||||
"react-primitives": "^0.4.3",
|
||||
"reactxp": "^0.42.1",
|
||||
"styled-components": "^2.1.2",
|
||||
"styletron-client": "^2.5.7",
|
||||
"styletron-utils": "^2.5.4"
|
||||
"radium": "^0.19.6",
|
||||
"react-jss": "^8.2.0",
|
||||
"reactxp": "^0.46.6",
|
||||
"styled-components": "^2.3.2",
|
||||
"styletron-client": "^3.0.0-rc.5",
|
||||
"styletron-utils": "^3.0.0-rc.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"css-loader": "^0.28.7",
|
||||
"style-loader": "^0.18.2"
|
||||
"style-loader": "^0.19.1"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
/* eslint-disable react/prop-types */
|
||||
import React from 'react';
|
||||
import StyleSheet from 'react-native/apis/StyleSheet';
|
||||
import View from '../View/react-native-stylesheet';
|
||||
|
||||
const Box = ({ color, fixed = false, layout = 'column', outer = false, ...other }) => (
|
||||
<View
|
||||
{...other}
|
||||
style={[
|
||||
styles[`color${color}`],
|
||||
fixed && styles.fixed,
|
||||
layout === 'row' && styles.row,
|
||||
outer && styles.outer
|
||||
]}
|
||||
/>
|
||||
);
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
outer: {
|
||||
padding: 4
|
||||
},
|
||||
row: {
|
||||
flexDirection: 'row'
|
||||
},
|
||||
color0: {
|
||||
backgroundColor: '#222'
|
||||
},
|
||||
color1: {
|
||||
backgroundColor: '#666'
|
||||
},
|
||||
color2: {
|
||||
backgroundColor: '#999'
|
||||
},
|
||||
color3: {
|
||||
backgroundColor: 'blue'
|
||||
},
|
||||
color4: {
|
||||
backgroundColor: 'orange'
|
||||
},
|
||||
color5: {
|
||||
backgroundColor: 'red'
|
||||
},
|
||||
fixed: {
|
||||
width: 20,
|
||||
height: 20
|
||||
}
|
||||
});
|
||||
|
||||
export default Box;
|
||||
@@ -1,30 +0,0 @@
|
||||
import styled from 'styled-components/primitives';
|
||||
|
||||
const getColor = color => {
|
||||
switch (color) {
|
||||
case 0:
|
||||
return '#222';
|
||||
case 1:
|
||||
return '#666';
|
||||
case 2:
|
||||
return '#999';
|
||||
case 3:
|
||||
return 'blue';
|
||||
case 4:
|
||||
return 'orange';
|
||||
case 5:
|
||||
return 'red';
|
||||
default:
|
||||
return 'transparent';
|
||||
}
|
||||
};
|
||||
|
||||
const Box = styled.View`
|
||||
flex-direction: ${props => (props.layout === 'column' ? 'column' : 'row')};
|
||||
padding: ${props => (props.outer ? '4px' : '0')};
|
||||
height: ${props => (props.fixed ? '20px' : 'auto')};
|
||||
width: ${props => (props.fixed ? '20px' : 'auto')};
|
||||
background-color: ${props => getColor(props.color)};
|
||||
`;
|
||||
|
||||
export default Box;
|
||||
@@ -1,35 +0,0 @@
|
||||
/* eslint-disable react/prop-types */
|
||||
import React from 'react';
|
||||
import StyleSheet from 'react-native/apis/StyleSheet';
|
||||
import registry from 'react-native/apis/StyleSheet/registry';
|
||||
|
||||
const emptyObject = {};
|
||||
|
||||
class View extends React.Component {
|
||||
render() {
|
||||
const { style, ...other } = this.props;
|
||||
const styleProps = registry.resolve([styles.root, style]) || emptyObject;
|
||||
return <div {...other} {...styleProps} />;
|
||||
}
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
root: {
|
||||
alignItems: 'stretch',
|
||||
borderWidth: 0,
|
||||
borderStyle: 'solid',
|
||||
boxSizing: 'border-box',
|
||||
display: 'flex',
|
||||
flexBasis: 'auto',
|
||||
flexDirection: 'column',
|
||||
flexShrink: 0,
|
||||
margin: 0,
|
||||
padding: 0,
|
||||
position: 'relative',
|
||||
// fix flexbox bugs
|
||||
minHeight: 0,
|
||||
minWidth: 0
|
||||
}
|
||||
});
|
||||
|
||||
export default View;
|
||||
9
benchmarks/src/react-native-stylesheet.js
vendored
9
benchmarks/src/react-native-stylesheet.js
vendored
@@ -1,9 +0,0 @@
|
||||
import Box from './components/Box/react-native-stylesheet';
|
||||
import View from './components/View/react-native-stylesheet';
|
||||
|
||||
const api = {
|
||||
Box,
|
||||
View
|
||||
};
|
||||
|
||||
export default api;
|
||||
@@ -1,7 +0,0 @@
|
||||
import Box from './components/Box/styled-components';
|
||||
import styled from 'styled-components/primitives';
|
||||
|
||||
export default {
|
||||
Box,
|
||||
View: styled.View
|
||||
};
|
||||
@@ -2,10 +2,44 @@
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@types/lodash@^4.14.64", "@types/lodash@^4.14.66":
|
||||
"@babel/helper-module-imports@7.0.0-beta.32":
|
||||
version "7.0.0-beta.32"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.0.0-beta.32.tgz#8126fc024107c226879841b973677a4f4e510a03"
|
||||
dependencies:
|
||||
"@babel/types" "7.0.0-beta.32"
|
||||
lodash "^4.2.0"
|
||||
|
||||
"@babel/types@7.0.0-beta.32":
|
||||
version "7.0.0-beta.32"
|
||||
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.0.0-beta.32.tgz#c317d0ecc89297b80bbcb2f50608e31f6452a5ff"
|
||||
dependencies:
|
||||
esutils "^2.0.2"
|
||||
lodash "^4.2.0"
|
||||
to-fast-properties "^2.0.0"
|
||||
|
||||
"@types/lodash@^4.14.64":
|
||||
version "4.14.74"
|
||||
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.74.tgz#ac3bd8db988e7f7038e5d22bd76a7ba13f876168"
|
||||
|
||||
"@types/lodash@^4.14.78":
|
||||
version "4.14.91"
|
||||
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.91.tgz#794611b28056d16b5436059c6d800b39d573cd3a"
|
||||
|
||||
"@types/node@*":
|
||||
version "8.5.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-8.5.1.tgz#4ec3020bcdfe2abffeef9ba3fbf26fca097514b5"
|
||||
|
||||
"@types/react-dom@^16.0.0":
|
||||
version "16.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-16.0.3.tgz#8accad7eabdab4cca3e1a56f5ccb57de2da0ff64"
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
"@types/react" "*"
|
||||
|
||||
"@types/react@*", "@types/react@^16.0.0":
|
||||
version "16.0.31"
|
||||
resolved "https://registry.yarnpkg.com/@types/react/-/react-16.0.31.tgz#5285da62f3ac62b797f6d0729a1d6181f3180c3e"
|
||||
|
||||
abbrev@1:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.0.tgz#d0554c2256636e2f56e7c2e5ad183f859428d81f"
|
||||
@@ -23,20 +57,6 @@ alphanum-sort@^1.0.1, alphanum-sort@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3"
|
||||
|
||||
animated@^0.1.5:
|
||||
version "0.1.5"
|
||||
resolved "https://registry.yarnpkg.com/animated/-/animated-0.1.5.tgz#83df8dc443d57abab7b0bb04818b0b655b31c9b9"
|
||||
dependencies:
|
||||
invariant "^2.2.0"
|
||||
normalize-css-color "^1.0.1"
|
||||
|
||||
animated@^0.2.0:
|
||||
version "0.2.0"
|
||||
resolved "https://registry.yarnpkg.com/animated/-/animated-0.2.0.tgz#1a0e96f097b3fbc5b64d7eddc723bcc0a6f97633"
|
||||
dependencies:
|
||||
invariant "^2.2.0"
|
||||
normalize-css-color "^1.0.1"
|
||||
|
||||
ansi-regex@^2.0.0:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df"
|
||||
@@ -45,15 +65,9 @@ ansi-styles@^2.2.1:
|
||||
version "2.2.1"
|
||||
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe"
|
||||
|
||||
ansi-styles@^3.1.0:
|
||||
version "3.2.0"
|
||||
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.0.tgz#c159b8d5be0f9e5a6f346dab94f16ce022161b88"
|
||||
dependencies:
|
||||
color-convert "^1.9.0"
|
||||
|
||||
aphrodite@^1.2.3:
|
||||
version "1.2.3"
|
||||
resolved "https://registry.yarnpkg.com/aphrodite/-/aphrodite-1.2.3.tgz#4b161e9eef319b1f90a889501f985d7b5e70b285"
|
||||
aphrodite@^1.2.5:
|
||||
version "1.2.5"
|
||||
resolved "https://registry.yarnpkg.com/aphrodite/-/aphrodite-1.2.5.tgz#8358c36c80bb03aee9b97165aaa70186225b4983"
|
||||
dependencies:
|
||||
asap "^2.0.3"
|
||||
inline-style-prefixer "^3.0.1"
|
||||
@@ -65,15 +79,11 @@ argparse@^1.0.7:
|
||||
dependencies:
|
||||
sprintf-js "~1.0.2"
|
||||
|
||||
array-find-index@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1"
|
||||
|
||||
array-find@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/array-find/-/array-find-1.0.0.tgz#6c8e286d11ed768327f8e62ecee87353ca3e78b8"
|
||||
|
||||
asap@^2.0.3, asap@^2.0.5:
|
||||
asap@^2.0.3:
|
||||
version "2.0.6"
|
||||
resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46"
|
||||
|
||||
@@ -98,17 +108,6 @@ autoprefixer@^6.3.1:
|
||||
postcss "^5.2.15"
|
||||
postcss-value-parser "^3.2.3"
|
||||
|
||||
autoprefixer@^7.1.2:
|
||||
version "7.1.4"
|
||||
resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-7.1.4.tgz#960847dbaa4016bc8e8e52ec891cbf8f1257a748"
|
||||
dependencies:
|
||||
browserslist "^2.4.0"
|
||||
caniuse-lite "^1.0.30000726"
|
||||
normalize-range "^0.1.2"
|
||||
num2fraction "^1.2.2"
|
||||
postcss "^6.0.11"
|
||||
postcss-value-parser "^3.2.3"
|
||||
|
||||
babel-code-frame@^6.11.0:
|
||||
version "6.22.0"
|
||||
resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.22.0.tgz#027620bee567a88c32561574e7fd0801d33118e4"
|
||||
@@ -117,29 +116,29 @@ babel-code-frame@^6.11.0:
|
||||
esutils "^2.0.2"
|
||||
js-tokens "^3.0.0"
|
||||
|
||||
babel-plugin-emotion@^7.2.2:
|
||||
version "7.2.2"
|
||||
resolved "https://registry.yarnpkg.com/babel-plugin-emotion/-/babel-plugin-emotion-7.2.2.tgz#eae520ef15e4affd87aab761e1c8b48b3385af3e"
|
||||
babel-macros@^1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/babel-macros/-/babel-macros-1.2.0.tgz#39e47ed6d286d4a98f1948d8bab45dac17e4e2d4"
|
||||
dependencies:
|
||||
autoprefixer "^7.1.2"
|
||||
cosmiconfig "3.1.0"
|
||||
|
||||
babel-plugin-emotion@^8.0.12:
|
||||
version "8.0.12"
|
||||
resolved "https://registry.yarnpkg.com/babel-plugin-emotion/-/babel-plugin-emotion-8.0.12.tgz#2ed844001416b0ae2ff787a06b1804ec5f531c89"
|
||||
dependencies:
|
||||
"@babel/helper-module-imports" "7.0.0-beta.32"
|
||||
babel-macros "^1.2.0"
|
||||
babel-plugin-syntax-jsx "^6.18.0"
|
||||
emotion-utils "^7.2.2"
|
||||
postcss "^6.0.9"
|
||||
postcss-js "^1.0.0"
|
||||
postcss-nested "^2.1.1"
|
||||
convert-source-map "^1.5.0"
|
||||
emotion-utils "^8.0.12"
|
||||
find-root "^1.1.0"
|
||||
source-map "^0.5.7"
|
||||
touch "^1.0.0"
|
||||
|
||||
babel-plugin-syntax-jsx@^6.18.0:
|
||||
version "6.18.0"
|
||||
resolved "https://registry.yarnpkg.com/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz#0af32a9a6e13ca7a3fd5069e62d7b0f58d0d8946"
|
||||
|
||||
babel-runtime@^6.23.0:
|
||||
version "6.25.0"
|
||||
resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.25.0.tgz#33b98eaa5d482bb01a8d1aa6b437ad2b01aec41c"
|
||||
dependencies:
|
||||
core-js "^2.4.0"
|
||||
regenerator-runtime "^0.10.0"
|
||||
|
||||
balanced-match@^0.4.2:
|
||||
version "0.4.2"
|
||||
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-0.4.2.tgz#cb3f3e3c732dc0f01ee70b403f302e61d7709838"
|
||||
@@ -160,9 +159,13 @@ bowser@^1.6.0:
|
||||
version "1.7.1"
|
||||
resolved "https://registry.yarnpkg.com/bowser/-/bowser-1.7.1.tgz#a4de8f18a1a0dc9531eb2a92a1521fb6a9ba96a5"
|
||||
|
||||
brcast@^2.0.0:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/brcast/-/brcast-2.0.1.tgz#4311508f0634a6f5a2465b6cf2db27f06902aaca"
|
||||
bowser@^1.7.3:
|
||||
version "1.8.1"
|
||||
resolved "https://registry.yarnpkg.com/bowser/-/bowser-1.8.1.tgz#49785777e7302febadb1a5b71d9a646520ed310d"
|
||||
|
||||
brcast@^3.0.1:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/brcast/-/brcast-3.0.1.tgz#6256a8349b20de9eed44257a9b24d71493cd48dd"
|
||||
|
||||
browserslist@^1.0.1, browserslist@^1.5.2, browserslist@^1.7.5:
|
||||
version "1.7.5"
|
||||
@@ -171,13 +174,6 @@ browserslist@^1.0.1, browserslist@^1.5.2, browserslist@^1.7.5:
|
||||
caniuse-db "^1.0.30000624"
|
||||
electron-to-chromium "^1.2.3"
|
||||
|
||||
browserslist@^2.4.0:
|
||||
version "2.4.0"
|
||||
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-2.4.0.tgz#693ee93d01e66468a6348da5498e011f578f87f8"
|
||||
dependencies:
|
||||
caniuse-lite "^1.0.30000718"
|
||||
electron-to-chromium "^1.3.18"
|
||||
|
||||
buffer@^5.0.3:
|
||||
version "5.0.5"
|
||||
resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.0.5.tgz#35c9393244a90aff83581063d16f0882cecc9418"
|
||||
@@ -185,10 +181,6 @@ buffer@^5.0.3:
|
||||
base64-js "^1.0.2"
|
||||
ieee754 "^1.1.4"
|
||||
|
||||
camelcase-css@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/camelcase-css/-/camelcase-css-1.0.1.tgz#157c4238265f5cf94a1dffde86446552cbf3f705"
|
||||
|
||||
caniuse-api@^1.5.2:
|
||||
version "1.5.3"
|
||||
resolved "https://registry.yarnpkg.com/caniuse-api/-/caniuse-api-1.5.3.tgz#5018e674b51c393e4d50614275dc017e27c4a2a2"
|
||||
@@ -202,10 +194,6 @@ caniuse-db@^1.0.30000346, caniuse-db@^1.0.30000624:
|
||||
version "1.0.30000628"
|
||||
resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000628.tgz#3d010e2a8e2537a8d135792e90e4f2ce0eb838cc"
|
||||
|
||||
caniuse-lite@^1.0.30000718, caniuse-lite@^1.0.30000726:
|
||||
version "1.0.30000726"
|
||||
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000726.tgz#966a753fa107a09d4131cf8b3d616723a06ccf7e"
|
||||
|
||||
chalk@^1.1.0, chalk@^1.1.3:
|
||||
version "1.1.3"
|
||||
resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98"
|
||||
@@ -216,14 +204,6 @@ chalk@^1.1.0, chalk@^1.1.3:
|
||||
strip-ansi "^3.0.0"
|
||||
supports-color "^2.0.0"
|
||||
|
||||
chalk@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.1.0.tgz#ac5becf14fa21b99c6c92ca7a7d7cfd5b17e743e"
|
||||
dependencies:
|
||||
ansi-styles "^3.1.0"
|
||||
escape-string-regexp "^1.0.5"
|
||||
supports-color "^4.0.0"
|
||||
|
||||
clap@^1.0.9:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/clap/-/clap-1.1.2.tgz#316545bf22229225a2cecaa6824cd2f56a9709ed"
|
||||
@@ -248,7 +228,7 @@ coa@~1.0.1:
|
||||
dependencies:
|
||||
q "^1.1.2"
|
||||
|
||||
color-convert@^1.3.0, color-convert@^1.9.0:
|
||||
color-convert@^1.3.0:
|
||||
version "1.9.0"
|
||||
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.0.tgz#1accf97dd739b983bf994d56fec8f95853641b7a"
|
||||
dependencies:
|
||||
@@ -284,21 +264,22 @@ colors@~1.1.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63"
|
||||
|
||||
convert-source-map@^1.5.0:
|
||||
version "1.5.0"
|
||||
resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.0.tgz#9acd70851c6d5dfdd93d9282e5edf94a03ff46b5"
|
||||
|
||||
core-js@^1.0.0:
|
||||
version "1.2.7"
|
||||
resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636"
|
||||
|
||||
core-js@^2.4.0:
|
||||
version "2.4.1"
|
||||
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.4.1.tgz#4de911e667b0eae9124e34254b53aea6fc618d3e"
|
||||
|
||||
create-react-class@^15.6.0:
|
||||
version "15.6.0"
|
||||
resolved "https://registry.yarnpkg.com/create-react-class/-/create-react-class-15.6.0.tgz#ab448497c26566e1e29413e883207d57cfe7bed4"
|
||||
cosmiconfig@3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-3.1.0.tgz#640a94bf9847f321800403cd273af60665c73397"
|
||||
dependencies:
|
||||
fbjs "^0.8.9"
|
||||
loose-envify "^1.3.1"
|
||||
object-assign "^4.1.1"
|
||||
is-directory "^0.3.1"
|
||||
js-yaml "^3.9.0"
|
||||
parse-json "^3.0.0"
|
||||
require-from-string "^2.0.1"
|
||||
|
||||
css-color-keywords@^1.0.0:
|
||||
version "1.0.0"
|
||||
@@ -314,6 +295,12 @@ css-in-js-utils@^1.0.3:
|
||||
dependencies:
|
||||
hyphenate-style-name "^1.0.2"
|
||||
|
||||
css-in-js-utils@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/css-in-js-utils/-/css-in-js-utils-2.0.0.tgz#5af1dd70f4b06b331f48d22a3d86e0786c0b9435"
|
||||
dependencies:
|
||||
hyphenate-style-name "^1.0.2"
|
||||
|
||||
css-loader@^0.28.7:
|
||||
version "0.28.7"
|
||||
resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-0.28.7.tgz#5f2ee989dd32edd907717f953317656160999c1b"
|
||||
@@ -411,61 +398,34 @@ csso@~2.3.1:
|
||||
clap "^1.0.9"
|
||||
source-map "^0.5.3"
|
||||
|
||||
debounce@1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/debounce/-/debounce-1.0.2.tgz#503cc674d8d7f737099664fb75ddbd36b9626dc6"
|
||||
|
||||
decamelize@^1.1.2:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290"
|
||||
|
||||
deep-assign@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/deep-assign/-/deep-assign-2.0.0.tgz#ebe06b1f07f08dae597620e3dd1622f371a1c572"
|
||||
dependencies:
|
||||
is-obj "^1.0.0"
|
||||
|
||||
defined@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693"
|
||||
|
||||
deline@^1.0.4:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/deline/-/deline-1.0.4.tgz#6c05c87836926e1a1c63e47882f3d2eb2c6f14c9"
|
||||
|
||||
electron-to-chromium@^1.2.3:
|
||||
version "1.2.4"
|
||||
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.2.4.tgz#9751cbea89fa120bf88c226ba41eb8d0b6f1b597"
|
||||
|
||||
electron-to-chromium@^1.3.18:
|
||||
version "1.3.21"
|
||||
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.21.tgz#a967ebdcfe8ed0083fc244d1894022a8e8113ea2"
|
||||
|
||||
emojis-list@^2.0.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389"
|
||||
|
||||
emotion-server@^7.2.2:
|
||||
version "7.2.2"
|
||||
resolved "https://registry.yarnpkg.com/emotion-server/-/emotion-server-7.2.2.tgz#d1073df1c71ef6fad4ee5e32319deced97b15c6b"
|
||||
dependencies:
|
||||
emotion "^7.2.2"
|
||||
emotion-utils "^7.2.2"
|
||||
emotion-utils@^8.0.12:
|
||||
version "8.0.12"
|
||||
resolved "https://registry.yarnpkg.com/emotion-utils/-/emotion-utils-8.0.12.tgz#5e0fd72db3008f26ce4f80b1972df08841df2168"
|
||||
|
||||
emotion-utils@^7.2.2:
|
||||
version "7.2.2"
|
||||
resolved "https://registry.yarnpkg.com/emotion-utils/-/emotion-utils-7.2.2.tgz#0057927581bdd0877d6d8fb90a6162a15c75b805"
|
||||
emotion@^8.0.12:
|
||||
version "8.0.12"
|
||||
resolved "https://registry.yarnpkg.com/emotion/-/emotion-8.0.12.tgz#03de11ce26b1b2401c334b94d438652124c514c6"
|
||||
dependencies:
|
||||
fbjs "^0.8.12"
|
||||
|
||||
emotion@^7.2.2:
|
||||
version "7.2.2"
|
||||
resolved "https://registry.yarnpkg.com/emotion/-/emotion-7.2.2.tgz#c89908662f4abb706d488a316ea8bdcad0b29727"
|
||||
dependencies:
|
||||
babel-plugin-emotion "^7.2.2"
|
||||
emotion-server "^7.2.2"
|
||||
emotion-utils "^7.2.2"
|
||||
react-emotion "^7.2.2"
|
||||
babel-plugin-emotion "^8.0.12"
|
||||
emotion-utils "^8.0.12"
|
||||
stylis "^3.3.2"
|
||||
stylis-rule-sheet "^0.0.5"
|
||||
|
||||
encoding@^0.1.11:
|
||||
version "0.1.12"
|
||||
@@ -473,7 +433,13 @@ encoding@^0.1.11:
|
||||
dependencies:
|
||||
iconv-lite "~0.4.13"
|
||||
|
||||
escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5:
|
||||
error-ex@^1.3.1:
|
||||
version "1.3.1"
|
||||
resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.1.tgz#f855a86ce61adc4e8621c3cda21e7a7612c3a8dc"
|
||||
dependencies:
|
||||
is-arrayish "^0.2.1"
|
||||
|
||||
escape-string-regexp@^1.0.2:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
|
||||
|
||||
@@ -481,6 +447,10 @@ esprima@^2.6.0:
|
||||
version "2.7.3"
|
||||
resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581"
|
||||
|
||||
esprima@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.0.tgz#4499eddcd1110e0b218bacf2fa7f7f59f55ca804"
|
||||
|
||||
esutils@^2.0.2:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b"
|
||||
@@ -509,6 +479,18 @@ fbjs@^0.8.12:
|
||||
setimmediate "^1.0.5"
|
||||
ua-parser-js "^0.7.9"
|
||||
|
||||
fbjs@^0.8.16:
|
||||
version "0.8.16"
|
||||
resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.16.tgz#5e67432f550dc41b572bf55847b8aca64e5337db"
|
||||
dependencies:
|
||||
core-js "^1.0.0"
|
||||
isomorphic-fetch "^2.1.1"
|
||||
loose-envify "^1.0.0"
|
||||
object-assign "^4.1.0"
|
||||
promise "^7.1.1"
|
||||
setimmediate "^1.0.5"
|
||||
ua-parser-js "^0.7.9"
|
||||
|
||||
fbjs@^0.8.5, fbjs@^0.8.9:
|
||||
version "0.8.12"
|
||||
resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.12.tgz#10b5d92f76d45575fd63a217d4ea02bea2f8ed04"
|
||||
@@ -521,14 +503,14 @@ fbjs@^0.8.5, fbjs@^0.8.9:
|
||||
setimmediate "^1.0.5"
|
||||
ua-parser-js "^0.7.9"
|
||||
|
||||
find-root@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/find-root/-/find-root-1.1.0.tgz#abcfc8ba76f708c42a97b3d685b7e9450bfb9ce4"
|
||||
|
||||
flatten@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.2.tgz#dae46a9d78fbe25292258cc1e780a41d95c03782"
|
||||
|
||||
flexibility@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/flexibility/-/flexibility-2.0.1.tgz#ad323aafc40f469ce624286518fc4d7cd72b7c77"
|
||||
|
||||
function-bind@^1.0.2:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.0.tgz#16176714c801798e4e8f2cf7f7529467bb4a5771"
|
||||
@@ -567,6 +549,10 @@ hoist-non-react-statics@^1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-1.2.0.tgz#aa448cf0986d55cc40773b17174b7dd066cb7cfb"
|
||||
|
||||
hoist-non-react-statics@^2.3.1:
|
||||
version "2.3.1"
|
||||
resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-2.3.1.tgz#343db84c6018c650778898240135a1420ee22ce0"
|
||||
|
||||
html-comment-regex@^1.1.0:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/html-comment-regex/-/html-comment-regex-1.1.1.tgz#668b93776eaae55ebde8f3ad464b307a4963625e"
|
||||
@@ -605,7 +591,7 @@ inherits@2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1"
|
||||
|
||||
inline-style-prefixer@^2.0.1, inline-style-prefixer@^2.0.5:
|
||||
inline-style-prefixer@^2.0.5:
|
||||
version "2.0.5"
|
||||
resolved "https://registry.yarnpkg.com/inline-style-prefixer/-/inline-style-prefixer-2.0.5.tgz#c153c7e88fd84fef5c602e95a8168b2770671fe7"
|
||||
dependencies:
|
||||
@@ -619,16 +605,25 @@ inline-style-prefixer@^3.0.1, inline-style-prefixer@^3.0.6:
|
||||
bowser "^1.6.0"
|
||||
css-in-js-utils "^1.0.3"
|
||||
|
||||
invariant@^2.2.0, invariant@^2.2.1:
|
||||
version "2.2.2"
|
||||
resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.2.tgz#9e1f56ac0acdb6bf303306f338be3b204ae60360"
|
||||
inline-style-prefixer@^3.0.3:
|
||||
version "3.0.8"
|
||||
resolved "https://registry.yarnpkg.com/inline-style-prefixer/-/inline-style-prefixer-3.0.8.tgz#8551b8e5b4d573244e66a34b04f7d32076a2b534"
|
||||
dependencies:
|
||||
loose-envify "^1.0.0"
|
||||
bowser "^1.7.3"
|
||||
css-in-js-utils "^2.0.0"
|
||||
|
||||
is-absolute-url@^2.0.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-2.1.0.tgz#50530dfb84fcc9aa7dbe7852e83a37b93b9f2aa6"
|
||||
|
||||
is-arrayish@^0.2.1:
|
||||
version "0.2.1"
|
||||
resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d"
|
||||
|
||||
is-directory@^0.3.1:
|
||||
version "0.3.1"
|
||||
resolved "https://registry.yarnpkg.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1"
|
||||
|
||||
is-function@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/is-function/-/is-function-1.0.1.tgz#12cfb98b65b57dd3d193a3121f5f6e2f437602b5"
|
||||
@@ -637,9 +632,9 @@ is-in-browser@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/is-in-browser/-/is-in-browser-1.0.2.tgz#f688bea8f1e5aadc3244ebc870d188cfb9b613cf"
|
||||
|
||||
is-obj@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f"
|
||||
is-in-browser@^1.1.3:
|
||||
version "1.1.3"
|
||||
resolved "https://registry.yarnpkg.com/is-in-browser/-/is-in-browser-1.1.3.tgz#56ff4db683a078c6082eb95dad7dc62e1d04f835"
|
||||
|
||||
is-plain-obj@^1.0.0:
|
||||
version "1.1.0"
|
||||
@@ -680,6 +675,13 @@ js-tokens@^3.0.0:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.1.tgz#08e9f132484a2c45a30907e9dc4d5567b7f114d7"
|
||||
|
||||
js-yaml@^3.9.0:
|
||||
version "3.10.0"
|
||||
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.10.0.tgz#2e78441646bd4682e963f22b6e92823c309c62dc"
|
||||
dependencies:
|
||||
argparse "^1.0.7"
|
||||
esprima "^4.0.0"
|
||||
|
||||
js-yaml@~3.7.0:
|
||||
version "3.7.0"
|
||||
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.7.0.tgz#5c967ddd837a9bfdca5f2de84253abe8a1c03b80"
|
||||
@@ -709,69 +711,77 @@ jsonify@~0.0.0:
|
||||
version "0.0.0"
|
||||
resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73"
|
||||
|
||||
jss-camel-case@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/jss-camel-case/-/jss-camel-case-5.0.0.tgz#886c1fe56a8a11577454d6a8b4133caa6c1f53a0"
|
||||
|
||||
jss-compose@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/jss-compose/-/jss-compose-4.0.0.tgz#f0109e8e8301a2678279301c24523dbc76115b9b"
|
||||
dependencies:
|
||||
warning "^3.0.0"
|
||||
|
||||
jss-default-unit@^7.0.0:
|
||||
version "7.0.0"
|
||||
resolved "https://registry.yarnpkg.com/jss-default-unit/-/jss-default-unit-7.0.0.tgz#176c1db91da870e3ad16301f6f4b4cfc6fe1e90a"
|
||||
|
||||
jss-expand@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/jss-expand/-/jss-expand-4.0.0.tgz#71ec15386d7839bb23892acf9dcaa40b7fe9c785"
|
||||
|
||||
jss-extend@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/jss-extend/-/jss-extend-5.0.0.tgz#08a1d4015d05dfe011e3a281457d471226865387"
|
||||
dependencies:
|
||||
warning "^3.0.0"
|
||||
|
||||
jss-global@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/jss-global/-/jss-global-2.0.0.tgz#a162f822f17e5d760151d908bdb41d7f2824c28f"
|
||||
|
||||
jss-nested@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/jss-nested/-/jss-nested-5.0.0.tgz#c0752f31f2d465110d7de6ac83583dbed669faa0"
|
||||
dependencies:
|
||||
warning "^3.0.0"
|
||||
|
||||
jss-preset-default@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/jss-preset-default/-/jss-preset-default-3.0.0.tgz#e43ee1ac526f689baf2bfd28ae95a6fdc3a02663"
|
||||
dependencies:
|
||||
jss-camel-case "^5.0.0"
|
||||
jss-compose "^4.0.0"
|
||||
jss-default-unit "^7.0.0"
|
||||
jss-expand "^4.0.0"
|
||||
jss-extend "^5.0.0"
|
||||
jss-global "^2.0.0"
|
||||
jss-nested "^5.0.0"
|
||||
jss-props-sort "^5.0.0"
|
||||
jss-vendor-prefixer "^6.0.0"
|
||||
|
||||
jss-props-sort@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/jss-props-sort/-/jss-props-sort-5.0.0.tgz#8839c88433f64e8c1dab1a7068796f19b84f9195"
|
||||
|
||||
jss-vendor-prefixer@^6.0.0:
|
||||
jss-camel-case@^6.0.0:
|
||||
version "6.0.0"
|
||||
resolved "https://registry.yarnpkg.com/jss-vendor-prefixer/-/jss-vendor-prefixer-6.0.0.tgz#be58124f0cbed76e98cc8eb5219dbb260f057d0b"
|
||||
resolved "https://registry.yarnpkg.com/jss-camel-case/-/jss-camel-case-6.0.0.tgz#7cf8453e395c31fed931d11efbc885edcd61132e"
|
||||
|
||||
jss-compose@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/jss-compose/-/jss-compose-5.0.0.tgz#ce01b2e4521d65c37ea42cf49116e5f7ab596484"
|
||||
dependencies:
|
||||
warning "^3.0.0"
|
||||
|
||||
jss-default-unit@^8.0.0:
|
||||
version "8.0.2"
|
||||
resolved "https://registry.yarnpkg.com/jss-default-unit/-/jss-default-unit-8.0.2.tgz#cc1e889bae4c0b9419327b314ab1c8e2826890e6"
|
||||
|
||||
jss-expand@^5.0.0:
|
||||
version "5.1.0"
|
||||
resolved "https://registry.yarnpkg.com/jss-expand/-/jss-expand-5.1.0.tgz#b1ad74ec18631f34f65a2124fcfceb6400610e3d"
|
||||
|
||||
jss-extend@^6.0.1:
|
||||
version "6.1.0"
|
||||
resolved "https://registry.yarnpkg.com/jss-extend/-/jss-extend-6.1.0.tgz#85f3d39944018e8f44b322c14fa316068aa7bb0b"
|
||||
dependencies:
|
||||
warning "^3.0.0"
|
||||
|
||||
jss-global@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/jss-global/-/jss-global-3.0.0.tgz#e19e5c91ab2b96353c227e30aa2cbd938cdaafa2"
|
||||
|
||||
jss-nested@^6.0.1:
|
||||
version "6.0.1"
|
||||
resolved "https://registry.yarnpkg.com/jss-nested/-/jss-nested-6.0.1.tgz#ef992b79d6e8f63d939c4397b9d99b5cbbe824ca"
|
||||
dependencies:
|
||||
warning "^3.0.0"
|
||||
|
||||
jss-preset-default@^4.0.1:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/jss-preset-default/-/jss-preset-default-4.0.1.tgz#822cecb87c27ff91633774422f4c221d61486b65"
|
||||
dependencies:
|
||||
jss-camel-case "^6.0.0"
|
||||
jss-compose "^5.0.0"
|
||||
jss-default-unit "^8.0.0"
|
||||
jss-expand "^5.0.0"
|
||||
jss-extend "^6.0.1"
|
||||
jss-global "^3.0.0"
|
||||
jss-nested "^6.0.1"
|
||||
jss-props-sort "^6.0.0"
|
||||
jss-template "^1.0.0"
|
||||
jss-vendor-prefixer "^7.0.0"
|
||||
|
||||
jss-props-sort@^6.0.0:
|
||||
version "6.0.0"
|
||||
resolved "https://registry.yarnpkg.com/jss-props-sort/-/jss-props-sort-6.0.0.tgz#9105101a3b5071fab61e2d85ea74cc22e9b16323"
|
||||
|
||||
jss-template@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/jss-template/-/jss-template-1.0.0.tgz#4b874608706ddceecacdb5567e254aecb6ea69b3"
|
||||
dependencies:
|
||||
warning "^3.0.0"
|
||||
|
||||
jss-vendor-prefixer@^7.0.0:
|
||||
version "7.0.0"
|
||||
resolved "https://registry.yarnpkg.com/jss-vendor-prefixer/-/jss-vendor-prefixer-7.0.0.tgz#0166729650015ef19d9f02437c73667231605c71"
|
||||
dependencies:
|
||||
css-vendor "^0.3.8"
|
||||
|
||||
jss@^8.1.0:
|
||||
version "8.1.0"
|
||||
resolved "https://registry.yarnpkg.com/jss/-/jss-8.1.0.tgz#b32f15efcce22446dfda4c2be09a04f38431da0a"
|
||||
jss@^9.3.2:
|
||||
version "9.4.0"
|
||||
resolved "https://registry.yarnpkg.com/jss/-/jss-9.4.0.tgz#fbfd1a63556c5afd5bfcffd98df3c50eb2614ed3"
|
||||
dependencies:
|
||||
is-in-browser "^1.0.2"
|
||||
is-in-browser "^1.1.3"
|
||||
symbol-observable "^1.1.0"
|
||||
warning "^3.0.0"
|
||||
|
||||
loader-utils@^1.0.2:
|
||||
@@ -794,11 +804,11 @@ lodash.uniq@^4.3.0:
|
||||
version "4.5.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
|
||||
|
||||
lodash@^4.17.1, lodash@^4.17.4:
|
||||
lodash@^4.17.1, lodash@^4.17.4, lodash@^4.2.0:
|
||||
version "4.17.4"
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae"
|
||||
|
||||
loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.3.1:
|
||||
loose-envify@^1.0.0, loose-envify@^1.3.1:
|
||||
version "1.3.1"
|
||||
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848"
|
||||
dependencies:
|
||||
@@ -839,10 +849,6 @@ nopt@~1.0.10:
|
||||
dependencies:
|
||||
abbrev "1"
|
||||
|
||||
normalize-css-color@^1.0.1, normalize-css-color@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/normalize-css-color/-/normalize-css-color-1.0.2.tgz#02991e97cccec6623fe573afbbf0de6a1f3e9f8d"
|
||||
|
||||
normalize-range@^0.1.2:
|
||||
version "0.1.2"
|
||||
resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942"
|
||||
@@ -864,6 +870,12 @@ object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
|
||||
|
||||
parse-json@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-3.0.0.tgz#fa6f47b18e23826ead32f263e744d0e1e847fb13"
|
||||
dependencies:
|
||||
error-ex "^1.3.1"
|
||||
|
||||
postcss-calc@^5.2.0:
|
||||
version "5.3.1"
|
||||
resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-5.3.1.tgz#77bae7ca928ad85716e2fda42f261bf7c1d65b5e"
|
||||
@@ -925,13 +937,6 @@ postcss-filter-plugins@^2.0.0:
|
||||
postcss "^5.0.4"
|
||||
uniqid "^4.0.0"
|
||||
|
||||
postcss-js@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/postcss-js/-/postcss-js-1.0.0.tgz#ccee5aa3b1970dd457008e79438165f66919ba30"
|
||||
dependencies:
|
||||
camelcase-css "^1.0.1"
|
||||
postcss "^6.0.1"
|
||||
|
||||
postcss-merge-idents@^2.1.5:
|
||||
version "2.1.7"
|
||||
resolved "https://registry.yarnpkg.com/postcss-merge-idents/-/postcss-merge-idents-2.1.7.tgz#4c5530313c08e1d5b3bbf3d2bbc747e278eea270"
|
||||
@@ -1020,13 +1025,6 @@ postcss-modules-values@^1.1.0:
|
||||
icss-replace-symbols "^1.0.2"
|
||||
postcss "^5.0.14"
|
||||
|
||||
postcss-nested@^2.1.1:
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/postcss-nested/-/postcss-nested-2.1.2.tgz#04057281f9631fef684857fb0119bae04ede03c6"
|
||||
dependencies:
|
||||
postcss "^6.0.9"
|
||||
postcss-selector-parser "^2.2.3"
|
||||
|
||||
postcss-normalize-charset@^1.1.0:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/postcss-normalize-charset/-/postcss-normalize-charset-1.1.1.tgz#ef9ee71212d7fe759c78ed162f61ed62b5cb93f1"
|
||||
@@ -1070,7 +1068,7 @@ postcss-reduce-transforms@^1.0.3:
|
||||
postcss "^5.0.8"
|
||||
postcss-value-parser "^3.0.1"
|
||||
|
||||
postcss-selector-parser@^2.0.0, postcss-selector-parser@^2.2.2, postcss-selector-parser@^2.2.3:
|
||||
postcss-selector-parser@^2.0.0, postcss-selector-parser@^2.2.2:
|
||||
version "2.2.3"
|
||||
resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-2.2.3.tgz#f9437788606c3c9acee16ffe8d8b16297f27bb90"
|
||||
dependencies:
|
||||
@@ -1124,14 +1122,6 @@ postcss@^6.0.1:
|
||||
source-map "^0.5.6"
|
||||
supports-color "^4.0.0"
|
||||
|
||||
postcss@^6.0.11, postcss@^6.0.9:
|
||||
version "6.0.11"
|
||||
resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.11.tgz#f48db210b1d37a7f7ab6499b7a54982997ab6f72"
|
||||
dependencies:
|
||||
chalk "^2.1.0"
|
||||
source-map "^0.5.7"
|
||||
supports-color "^4.4.0"
|
||||
|
||||
prepend-http@^1.0.0:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc"
|
||||
@@ -1149,6 +1139,14 @@ prop-types@^15.5.10, prop-types@^15.5.4, prop-types@^15.5.8, prop-types@^15.5.9:
|
||||
fbjs "^0.8.9"
|
||||
loose-envify "^1.3.1"
|
||||
|
||||
prop-types@^15.6.0:
|
||||
version "15.6.0"
|
||||
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.0.tgz#ceaf083022fc46b4a35f69e13ef75aed0d639856"
|
||||
dependencies:
|
||||
fbjs "^0.8.16"
|
||||
loose-envify "^1.3.1"
|
||||
object-assign "^4.1.1"
|
||||
|
||||
q@^1.1.2:
|
||||
version "1.4.1"
|
||||
resolved "https://registry.yarnpkg.com/q/-/q-1.4.1.tgz#55705bcd93c5f3673530c2c2cbc0c2b3addc286e"
|
||||
@@ -1160,92 +1158,39 @@ query-string@^4.1.0:
|
||||
object-assign "^4.1.0"
|
||||
strict-uri-encode "^1.0.0"
|
||||
|
||||
radium@^0.19.4:
|
||||
version "0.19.4"
|
||||
resolved "https://registry.yarnpkg.com/radium/-/radium-0.19.4.tgz#56aa49fde6181d2f5e1fa57b4710ffd0c23de820"
|
||||
radium@^0.19.6:
|
||||
version "0.19.6"
|
||||
resolved "https://registry.yarnpkg.com/radium/-/radium-0.19.6.tgz#b86721d08dbd303b061a4ae2ebb06cc6e335ae72"
|
||||
dependencies:
|
||||
array-find "^1.0.0"
|
||||
exenv "^1.2.1"
|
||||
inline-style-prefixer "^2.0.5"
|
||||
prop-types "^15.5.8"
|
||||
|
||||
react-emotion@^7.2.2:
|
||||
version "7.2.2"
|
||||
resolved "https://registry.yarnpkg.com/react-emotion/-/react-emotion-7.2.2.tgz#0401607a0ba011bc16600a2691f5f57cb38ce89d"
|
||||
react-jss@^8.2.0:
|
||||
version "8.2.0"
|
||||
resolved "https://registry.yarnpkg.com/react-jss/-/react-jss-8.2.0.tgz#8440f08aef27d408ba31f63df09167ed22a5b99b"
|
||||
dependencies:
|
||||
babel-plugin-emotion "^7.2.2"
|
||||
emotion "^7.2.2"
|
||||
emotion-utils "^7.2.2"
|
||||
hoist-non-react-statics "^2.3.1"
|
||||
jss "^9.3.2"
|
||||
jss-preset-default "^4.0.1"
|
||||
prop-types "^15.6.0"
|
||||
theming "^1.3.0"
|
||||
|
||||
react-jss@^7.1.0:
|
||||
version "7.1.0"
|
||||
resolved "https://registry.yarnpkg.com/react-jss/-/react-jss-7.1.0.tgz#de9430cbe01a82f3b2dcf87a03b798130868ff93"
|
||||
reactxp@^0.46.6:
|
||||
version "0.46.6"
|
||||
resolved "https://registry.yarnpkg.com/reactxp/-/reactxp-0.46.6.tgz#166a503a7147f3a1e29efc4469bda32603471a5f"
|
||||
dependencies:
|
||||
hoist-non-react-statics "^1.2.0"
|
||||
jss "^8.1.0"
|
||||
jss-preset-default "^3.0.0"
|
||||
prop-types "^15.5.8"
|
||||
theming "^1.1.0"
|
||||
|
||||
react-native-web@0.0.x:
|
||||
version "0.0.116"
|
||||
resolved "https://registry.yarnpkg.com/react-native-web/-/react-native-web-0.0.116.tgz#e05e376b34617a54d61826e4bc06b0bdbfd3f4b2"
|
||||
dependencies:
|
||||
animated "^0.2.0"
|
||||
array-find-index "^1.0.2"
|
||||
babel-runtime "^6.23.0"
|
||||
create-react-class "^15.6.0"
|
||||
debounce "1.0.2"
|
||||
deep-assign "^2.0.0"
|
||||
fbjs "^0.8.12"
|
||||
hyphenate-style-name "^1.0.2"
|
||||
inline-style-prefixer "^3.0.6"
|
||||
normalize-css-color "^1.0.2"
|
||||
prop-types "^15.5.10"
|
||||
react-timer-mixin "^0.13.3"
|
||||
|
||||
react-primitives@^0.4.3:
|
||||
version "0.4.3"
|
||||
resolved "https://registry.yarnpkg.com/react-primitives/-/react-primitives-0.4.3.tgz#4970afda5a32dccf5ea180380e3a0e16192e4b83"
|
||||
dependencies:
|
||||
animated "^0.1.5"
|
||||
asap "^2.0.5"
|
||||
deline "^1.0.4"
|
||||
flexibility "^2.0.1"
|
||||
inline-style-prefixer "^2.0.5"
|
||||
invariant "^2.2.1"
|
||||
normalize-css-color "^1.0.1"
|
||||
prop-types "^15.5.10"
|
||||
react-native-web "0.0.x"
|
||||
react-timer-mixin "^0.13.3"
|
||||
string-hash "^1.1.3"
|
||||
|
||||
react-timer-mixin@^0.13.3:
|
||||
version "0.13.3"
|
||||
resolved "https://registry.yarnpkg.com/react-timer-mixin/-/react-timer-mixin-0.13.3.tgz#0da8b9f807ec07dc3e854d082c737c65605b3d22"
|
||||
|
||||
react@^15.5.4:
|
||||
version "15.6.1"
|
||||
resolved "https://registry.yarnpkg.com/react/-/react-15.6.1.tgz#baa8434ec6780bde997cdc380b79cd33b96393df"
|
||||
dependencies:
|
||||
create-react-class "^15.6.0"
|
||||
fbjs "^0.8.9"
|
||||
loose-envify "^1.1.0"
|
||||
object-assign "^4.1.0"
|
||||
prop-types "^15.5.10"
|
||||
|
||||
reactxp@^0.42.1:
|
||||
version "0.42.1"
|
||||
resolved "https://registry.yarnpkg.com/reactxp/-/reactxp-0.42.1.tgz#1c142a87f0a82a8da94e5c875525952c35a53a17"
|
||||
dependencies:
|
||||
"@types/lodash" "^4.14.66"
|
||||
"@types/lodash" "^4.14.78"
|
||||
"@types/react" "^16.0.0"
|
||||
"@types/react-dom" "^16.0.0"
|
||||
assert "^1.3.0"
|
||||
ifvisible.js "^1.0.6"
|
||||
lodash "^4.17.1"
|
||||
prop-types "^15.5.9"
|
||||
rebound "^0.0.13"
|
||||
subscribableevent "^1.0.0"
|
||||
synctasks "^0.2.9"
|
||||
synctasks "^0.3.0"
|
||||
|
||||
rebound@^0.0.13:
|
||||
version "0.0.13"
|
||||
@@ -1269,10 +1214,6 @@ regenerate@^1.2.1:
|
||||
version "1.3.2"
|
||||
resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.3.2.tgz#d1941c67bad437e1be76433add5b385f95b19260"
|
||||
|
||||
regenerator-runtime@^0.10.0:
|
||||
version "0.10.5"
|
||||
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz#336c3efc1220adcedda2c9fab67b5a7955a33658"
|
||||
|
||||
regexpu-core@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-1.0.0.tgz#86a763f58ee4d7c2f6b102e4764050de7ed90c6b"
|
||||
@@ -1291,6 +1232,10 @@ regjsparser@^0.1.4:
|
||||
dependencies:
|
||||
jsesc "~0.5.0"
|
||||
|
||||
require-from-string@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.1.tgz#c545233e9d7da6616e9d59adfb39fc9f588676ff"
|
||||
|
||||
sax@~1.2.1:
|
||||
version "1.2.2"
|
||||
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.2.tgz#fd8631a23bc7826bef5d871bdb87378c95647828"
|
||||
@@ -1341,46 +1286,53 @@ strip-ansi@^3.0.0:
|
||||
dependencies:
|
||||
ansi-regex "^2.0.0"
|
||||
|
||||
style-loader@^0.18.2:
|
||||
version "0.18.2"
|
||||
resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-0.18.2.tgz#cc31459afbcd6d80b7220ee54b291a9fd66ff5eb"
|
||||
style-loader@^0.19.1:
|
||||
version "0.19.1"
|
||||
resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-0.19.1.tgz#591ffc80bcefe268b77c5d9ebc0505d772619f85"
|
||||
dependencies:
|
||||
loader-utils "^1.0.2"
|
||||
schema-utils "^0.3.0"
|
||||
|
||||
styled-components@^2.1.2:
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-2.1.2.tgz#bb419978e1287c5d0d88fa9106b2dd75f66a324c"
|
||||
styled-components@^2.3.2:
|
||||
version "2.3.2"
|
||||
resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-2.3.2.tgz#323d86cc9ac89f3fd233a2dfa0849da236f143e3"
|
||||
dependencies:
|
||||
buffer "^5.0.3"
|
||||
css-to-react-native "^2.0.3"
|
||||
fbjs "^0.8.9"
|
||||
hoist-non-react-statics "^1.2.0"
|
||||
is-function "^1.0.1"
|
||||
is-plain-object "^2.0.1"
|
||||
prop-types "^15.5.4"
|
||||
stylis "^3.2.1"
|
||||
stylis "^3.4.0"
|
||||
supports-color "^3.2.3"
|
||||
|
||||
styletron-client@^2.5.7:
|
||||
version "2.5.7"
|
||||
resolved "https://registry.yarnpkg.com/styletron-client/-/styletron-client-2.5.7.tgz#104fa4dc564cd3fe78eb92488e5ef9039c9e242f"
|
||||
styletron-client@^3.0.0-rc.5:
|
||||
version "3.0.0-rc.5"
|
||||
resolved "https://registry.yarnpkg.com/styletron-client/-/styletron-client-3.0.0-rc.5.tgz#275ca0b5f971d244f0e42079ad570be9c31a2a70"
|
||||
dependencies:
|
||||
styletron-core "^2.5.7"
|
||||
styletron-core "^3.0.0-rc.3"
|
||||
|
||||
styletron-core@^2.5.7:
|
||||
version "2.5.7"
|
||||
resolved "https://registry.yarnpkg.com/styletron-core/-/styletron-core-2.5.7.tgz#2c4a1fae537b42235462e438c24ab619bbf8993e"
|
||||
styletron-core@^3.0.0-rc.3:
|
||||
version "3.0.0-rc.3"
|
||||
resolved "https://registry.yarnpkg.com/styletron-core/-/styletron-core-3.0.0-rc.3.tgz#9468e275d9085d2e5d6d6468cc6d8733dbfa3cba"
|
||||
|
||||
styletron-utils@^2.5.4:
|
||||
version "2.5.4"
|
||||
resolved "https://registry.yarnpkg.com/styletron-utils/-/styletron-utils-2.5.4.tgz#f08cca7d58ee0338ce85e408cb32900e65620240"
|
||||
styletron-utils@^3.0.0-rc.3:
|
||||
version "3.0.0-rc.3"
|
||||
resolved "https://registry.yarnpkg.com/styletron-utils/-/styletron-utils-3.0.0-rc.3.tgz#21fef2099f1c368e6ff2b8f76bf7a64bb547b760"
|
||||
dependencies:
|
||||
inline-style-prefixer "^2.0.1"
|
||||
inline-style-prefixer "^3.0.3"
|
||||
|
||||
stylis@^3.2.1:
|
||||
version "3.2.3"
|
||||
resolved "https://registry.yarnpkg.com/stylis/-/stylis-3.2.3.tgz#fed751d792af3f48a247769f55aca05c1a100a09"
|
||||
stylis-rule-sheet@^0.0.5:
|
||||
version "0.0.5"
|
||||
resolved "https://registry.yarnpkg.com/stylis-rule-sheet/-/stylis-rule-sheet-0.0.5.tgz#ebae935cc1f6fb31b9b62dba47f2ea8b833dad9f"
|
||||
|
||||
stylis@^3.3.2:
|
||||
version "3.4.0"
|
||||
resolved "https://registry.yarnpkg.com/stylis/-/stylis-3.4.0.tgz#55c6530ebceeca5976d54fb4adc67578afee828d"
|
||||
|
||||
stylis@^3.4.0:
|
||||
version "3.4.5"
|
||||
resolved "https://registry.yarnpkg.com/stylis/-/stylis-3.4.5.tgz#d7b9595fc18e7b9c8775eca8270a9a1d3e59806e"
|
||||
|
||||
subscribableevent@^1.0.0:
|
||||
version "1.0.0"
|
||||
@@ -1405,12 +1357,6 @@ supports-color@^4.0.0:
|
||||
dependencies:
|
||||
has-flag "^2.0.0"
|
||||
|
||||
supports-color@^4.4.0:
|
||||
version "4.4.0"
|
||||
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.4.0.tgz#883f7ddabc165142b2a61427f3352ded195d1a3e"
|
||||
dependencies:
|
||||
has-flag "^2.0.0"
|
||||
|
||||
svgo@^0.7.0:
|
||||
version "0.7.2"
|
||||
resolved "https://registry.yarnpkg.com/svgo/-/svgo-0.7.2.tgz#9f5772413952135c6fefbf40afe6a4faa88b4bb5"
|
||||
@@ -1423,24 +1369,31 @@ svgo@^0.7.0:
|
||||
sax "~1.2.1"
|
||||
whet.extend "~0.9.9"
|
||||
|
||||
synctasks@^0.2.9:
|
||||
version "0.2.17"
|
||||
resolved "https://registry.yarnpkg.com/synctasks/-/synctasks-0.2.17.tgz#38852f008878de2e941b6e458ddf552245268da1"
|
||||
|
||||
theming@^1.1.0:
|
||||
symbol-observable@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/theming/-/theming-1.1.0.tgz#0562760b55a1b919c2d5eeb94130351f8958e13a"
|
||||
resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.1.0.tgz#5c68fd8d54115d9dfb72a84720549222e8db9b32"
|
||||
|
||||
synctasks@^0.3.0:
|
||||
version "0.3.1"
|
||||
resolved "https://registry.yarnpkg.com/synctasks/-/synctasks-0.3.1.tgz#1f9012b23792ad775ba2693e0cafcfcd65b80d97"
|
||||
|
||||
theming@^1.3.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/theming/-/theming-1.3.0.tgz#286d5bae80be890d0adc645e5ca0498723725bdc"
|
||||
dependencies:
|
||||
brcast "^2.0.0"
|
||||
brcast "^3.0.1"
|
||||
is-function "^1.0.1"
|
||||
is-plain-object "^2.0.1"
|
||||
prop-types "^15.5.8"
|
||||
react "^15.5.4"
|
||||
|
||||
through@^2.3.8:
|
||||
version "2.3.8"
|
||||
resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
|
||||
|
||||
to-fast-properties@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e"
|
||||
|
||||
touch@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/touch/-/touch-1.0.0.tgz#449cbe2dbae5a8c8038e30d71fa0ff464947c4de"
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
# Direct manipulation
|
||||
|
||||
React Native for Web provides several methods to directly access the underlying
|
||||
DOM node. This can be useful when you need to make changes directly to a
|
||||
component without using state/props to trigger a re-render of the entire
|
||||
subtree, or when you want to focus a view or measure its on-screen dimensions.
|
||||
React Native provides several methods to directly access the underlying host
|
||||
node. This can be useful when you need to make changes directly to a component
|
||||
without using state/props to trigger a re-render of the entire subtree, or when
|
||||
you want to focus a view or measure its on-screen dimensions.
|
||||
|
||||
The methods described are available on most of the default components provided
|
||||
by React Native for Web. Note, however, that they are *not* available on the
|
||||
composite components that you define in your own app.
|
||||
by React Native for Web. Note, however, that they are *not* available on the composite
|
||||
components that you define in your own app.
|
||||
|
||||
## Instance methods
|
||||
|
||||
@@ -35,11 +35,17 @@ Like `measure`, but measures the view relative to another view, specified as
|
||||
`relativeToNativeNode`. This means that the returned `x`, `y` are relative to
|
||||
the origin `x`, `y` of the ancestor view.
|
||||
|
||||
As always, to obtain a native node handle for a component, you can use
|
||||
`findNodeHandle(component)`.
|
||||
|
||||
**measureInWindow**(callback: (x, y, width, height) => void)
|
||||
|
||||
Determines the location of the given view in the window and returns the values
|
||||
via an async callback.
|
||||
|
||||
**setNativeProps**(nativeProps: Object)
|
||||
|
||||
This function sends props straight to the underlying DOM node. See the [direct
|
||||
manipulation](../guides/direct-manipulation.md) guide for cases where
|
||||
`setNativeProps` should be used.
|
||||
This function sends props straight to the underlying DOM node.
|
||||
|
||||
## About `setNativeProps`
|
||||
|
||||
|
||||
@@ -10,14 +10,26 @@ polyfill.
|
||||
## Web packager
|
||||
|
||||
[Webpack](https://webpack.js.org) is a popular build tool for web apps. Below is an
|
||||
example of how to configure a build that uses [Babel](https://babeljs.io/) to
|
||||
compile your JavaScript for the web.
|
||||
_example_ of how to configure a build that uses [Babel](https://babeljs.io/) to
|
||||
compile your JavaScript for the web. Please refer to the webpack documentation
|
||||
when setting up your project.
|
||||
|
||||
Install webpack-related dependencies, for example:
|
||||
|
||||
```
|
||||
yarn add --dev babel-loader url-loader webpack webpack-dev-server
|
||||
```
|
||||
|
||||
Create a `web/webpack.config.js` file:
|
||||
|
||||
```js
|
||||
// web/webpack.config.js
|
||||
|
||||
const path = require('path');
|
||||
const webpack = require('webpack');
|
||||
|
||||
const appDirectory = path.resolve(__dirname, '../');
|
||||
|
||||
// This is needed for webpack to compile JavaScript.
|
||||
// Many OSS React Native packages are not compiled to ES5 before being
|
||||
// published. If you depend on uncompiled packages they may cause webpack build
|
||||
@@ -25,25 +37,26 @@ Create a `web/webpack.config.js` file:
|
||||
// `node_module`.
|
||||
const babelLoaderConfiguration = {
|
||||
test: /\.js$/,
|
||||
// Add every directory that needs to be compiled by Babel during the build
|
||||
// Add every directory that needs to be compiled by Babel during the build.
|
||||
include: [
|
||||
path.resolve(__dirname, 'src'),
|
||||
path.resolve(__dirname, 'node_modules/react-native-uncompiled')
|
||||
path.resolve(appDirectory, 'index.web.js'),
|
||||
path.resolve(appDirectory, 'src'),
|
||||
path.resolve(appDirectory, 'node_modules/react-native-uncompiled')
|
||||
],
|
||||
use: {
|
||||
loader: 'babel-loader',
|
||||
options: {
|
||||
cacheDirectory: true,
|
||||
// This aliases 'react-native' to 'react-native-web' and includes only
|
||||
// the modules needed by the app
|
||||
plugins: ['react-native-web/babel']
|
||||
// The 'react-native' preset is recommended (or use your own .babelrc)
|
||||
// the modules needed by the app.
|
||||
plugins: ['react-native-web/babel', 'transform-runtime'],
|
||||
// The 'react-native' preset is recommended (or use your own .babelrc).
|
||||
presets: ['react-native']
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// This is needed for webpack to import static images in JavaScript files
|
||||
// This is needed for webpack to import static images in JavaScript files.
|
||||
const imageLoaderConfiguration = {
|
||||
test: /\.(gif|jpe?g|png|svg)$/,
|
||||
use: {
|
||||
@@ -55,6 +68,15 @@ const imageLoaderConfiguration = {
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
// your web-specific entry file
|
||||
entry: path.resolve(appDirectory, 'index.web.js'),
|
||||
|
||||
// configures where the build ends up
|
||||
output: {
|
||||
filename: 'bundle.web.js',
|
||||
path: path.resolve(appDirectory, 'dist')
|
||||
},
|
||||
|
||||
// ...the rest of your config
|
||||
|
||||
module: {
|
||||
@@ -69,7 +91,8 @@ module.exports = {
|
||||
// builds to eliminate development checks and reduce build size. You may
|
||||
// wish to include additional optimizations.
|
||||
new webpack.DefinePlugin({
|
||||
'process.env.NODE_ENV': JSON.stringify('production')
|
||||
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'development'),
|
||||
__DEV__: process.env.NODE_ENV === 'production' || true
|
||||
})
|
||||
],
|
||||
|
||||
@@ -82,24 +105,20 @@ module.exports = {
|
||||
}
|
||||
```
|
||||
|
||||
To run in development:
|
||||
To run in development from the root of your application:
|
||||
|
||||
```
|
||||
./node_modules/.bin/webpack-dev-server -d --config web/webpack.config.js --inline --hot --colors
|
||||
./node_modules/.bin/webpack-dev-server -d --config ./web/webpack.config.js --inline --hot --colors
|
||||
```
|
||||
|
||||
To build for production:
|
||||
|
||||
```
|
||||
./node_modules/.bin/webpack -p --config web/webpack.config.js
|
||||
./node_modules/.bin/webpack -p --config ./web/webpack.config.js
|
||||
```
|
||||
|
||||
Please refer to the Webpack documentation for more information on configuration.
|
||||
|
||||
## Web entry
|
||||
|
||||
Create a `index.web.js` file (or simply `index.js` for web-only apps).
|
||||
|
||||
### Client-side rendering
|
||||
|
||||
Rendering using `AppRegistry`:
|
||||
@@ -198,10 +217,20 @@ target platform.
|
||||
|
||||
## Testing with Jest
|
||||
|
||||
[Jest](https://facebook.github.io/jest/) also needs to map `react-native` to `react-native-web`.
|
||||
[Jest](https://facebook.github.io/jest/) can be configured to improve snapshots
|
||||
of `react-native-web` components.
|
||||
|
||||
```
|
||||
"jest": {
|
||||
{
|
||||
"snapshotSerializers": [ "enzyme-to-json/serializer", "react-native-web/jest/serializer" ]
|
||||
}
|
||||
```
|
||||
|
||||
Jest also needs to map `react-native` to `react-native-web` (unless you are
|
||||
using Babel with the `react-native-web/babel` plugin).
|
||||
|
||||
```
|
||||
{
|
||||
"moduleNameMapper": {
|
||||
"react-native": "<rootDir>/node_modules/react-native-web"
|
||||
}
|
||||
|
||||
93
docs/storybook/1-components/CheckBox/CheckBoxScreen.js
Normal file
93
docs/storybook/1-components/CheckBox/CheckBoxScreen.js
Normal file
@@ -0,0 +1,93 @@
|
||||
/* eslint-disable react/jsx-sort-props */
|
||||
|
||||
/**
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import CustomSize from './examples/CustomSize';
|
||||
import PropColor from './examples/PropColor';
|
||||
import PropDisabled from './examples/PropDisabled';
|
||||
import PropOnValueChange from './examples/PropOnValueChange';
|
||||
import PropValue from './examples/PropValue';
|
||||
import React from 'react';
|
||||
import UIExplorer, {
|
||||
AppText,
|
||||
Code,
|
||||
Description,
|
||||
DocItem,
|
||||
Section,
|
||||
storiesOf
|
||||
} from '../../ui-explorer';
|
||||
|
||||
const CheckBoxScreen = () => (
|
||||
<UIExplorer title="CheckBox" url="components/CheckBox">
|
||||
<Description>
|
||||
<AppText>
|
||||
This is a controlled component that requires an <Code>onValueChange</Code> callback that
|
||||
updates the value prop in order for the component to reflect user actions. If the{' '}
|
||||
<Code>value</Code> prop is not updated, the component will continue to render the supplied{' '}
|
||||
<Code>value</Code> prop instead of the expected result of any user actions.
|
||||
</AppText>
|
||||
</Description>
|
||||
|
||||
<Section title="Props">
|
||||
<DocItem name="...View props" />
|
||||
|
||||
<DocItem
|
||||
description="Customize the color of the checkbox."
|
||||
example={{
|
||||
render: () => <PropColor />
|
||||
}}
|
||||
label="web"
|
||||
name="color"
|
||||
typeInfo="?color"
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
description="If true, the user won't be able to interact with the checkbox."
|
||||
example={{
|
||||
render: () => <PropDisabled />
|
||||
}}
|
||||
name="disabled"
|
||||
typeInfo="?boolean = false"
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
description="Invoked with the event when the value changes."
|
||||
name="onChange"
|
||||
typeInfo="?function"
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
description="Invoked with the new value when the value changes."
|
||||
example={{
|
||||
render: () => <PropOnValueChange />
|
||||
}}
|
||||
name="onValueChange"
|
||||
typeInfo="?function"
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
description="The value of the checkbox. If `true` the checkbox will be checked."
|
||||
example={{
|
||||
render: () => <PropValue />
|
||||
}}
|
||||
name="value"
|
||||
typeInfo="?boolean = false"
|
||||
/>
|
||||
</Section>
|
||||
|
||||
<Section title="More examples">
|
||||
<DocItem
|
||||
description="The checkbox size can be controlled by the 'height' and 'width' style properties"
|
||||
example={{
|
||||
code: '<CheckBox style={{ height: 32, width: 32 }} />',
|
||||
render: () => <CustomSize />
|
||||
}}
|
||||
name="Custom size"
|
||||
/>
|
||||
</Section>
|
||||
</UIExplorer>
|
||||
);
|
||||
|
||||
storiesOf('Components', module).add('CheckBox', CheckBoxScreen);
|
||||
20
docs/storybook/1-components/CheckBox/examples/CustomSize.js
Normal file
20
docs/storybook/1-components/CheckBox/examples/CustomSize.js
Normal file
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import styles from './styles';
|
||||
import { CheckBox, View } from 'react-native';
|
||||
|
||||
const CustomSizeExample = () => (
|
||||
<View style={styles.row}>
|
||||
<View style={styles.marginRight}>
|
||||
<CheckBox style={{ height: 20, width: 20 }} value />
|
||||
</View>
|
||||
<View style={styles.marginRight}>
|
||||
<CheckBox style={{ height: 32, width: 32 }} value />
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
|
||||
export default CustomSizeExample;
|
||||
20
docs/storybook/1-components/CheckBox/examples/PropColor.js
Normal file
20
docs/storybook/1-components/CheckBox/examples/PropColor.js
Normal file
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import styles from './styles';
|
||||
import { CheckBox, View } from 'react-native';
|
||||
|
||||
const CheckBoxColorExample = () => (
|
||||
<View style={styles.row}>
|
||||
<View style={styles.marginRight}>
|
||||
<CheckBox color="#1DA1F2" value />
|
||||
</View>
|
||||
<View style={styles.marginRight}>
|
||||
<CheckBox color="#F45D22" value />
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
|
||||
export default CheckBoxColorExample;
|
||||
20
docs/storybook/1-components/CheckBox/examples/PropDisabled.js
Executable file
20
docs/storybook/1-components/CheckBox/examples/PropDisabled.js
Executable file
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import styles from './styles';
|
||||
import { CheckBox, View } from 'react-native';
|
||||
|
||||
const CheckBoxDisabledExample = () => (
|
||||
<View style={styles.row}>
|
||||
<View style={styles.marginRight}>
|
||||
<CheckBox disabled value={false} />
|
||||
</View>
|
||||
<View style={styles.marginRight}>
|
||||
<CheckBox disabled value />
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
|
||||
export default CheckBoxDisabledExample;
|
||||
59
docs/storybook/1-components/CheckBox/examples/PropOnValueChange.js
Executable file
59
docs/storybook/1-components/CheckBox/examples/PropOnValueChange.js
Executable file
@@ -0,0 +1,59 @@
|
||||
/**
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import styles from './styles';
|
||||
import React, { PureComponent } from 'react';
|
||||
import { CheckBox, Text, View } from 'react-native';
|
||||
|
||||
class CheckBoxOnValueChangeExample extends PureComponent {
|
||||
state = {
|
||||
eventSwitchIsOn: false,
|
||||
eventSwitchRegressionIsOn: true
|
||||
};
|
||||
|
||||
render() {
|
||||
const { eventSwitchIsOn, eventSwitchRegressionIsOn } = this.state;
|
||||
|
||||
return (
|
||||
<View style={styles.row}>
|
||||
<View style={[styles.alignCenter, styles.marginRight]}>
|
||||
<CheckBox
|
||||
onValueChange={this._handleEventSwitch}
|
||||
style={styles.marginBottom}
|
||||
value={eventSwitchIsOn}
|
||||
/>
|
||||
<CheckBox
|
||||
onValueChange={this._handleEventSwitch}
|
||||
style={styles.marginBottom}
|
||||
value={eventSwitchIsOn}
|
||||
/>
|
||||
<Text>{eventSwitchIsOn ? 'On' : 'Off'}</Text>
|
||||
</View>
|
||||
<View style={styles.alignCenter}>
|
||||
<CheckBox
|
||||
onValueChange={this._handleEventSwitchRegression}
|
||||
style={styles.marginBottom}
|
||||
value={eventSwitchRegressionIsOn}
|
||||
/>
|
||||
<CheckBox
|
||||
onValueChange={this._handleEventSwitchRegression}
|
||||
style={styles.marginBottom}
|
||||
value={eventSwitchRegressionIsOn}
|
||||
/>
|
||||
<Text>{eventSwitchRegressionIsOn ? 'On' : 'Off'}</Text>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
_handleEventSwitch = value => {
|
||||
this.setState({ eventSwitchIsOn: value });
|
||||
};
|
||||
|
||||
_handleEventSwitchRegression = value => {
|
||||
this.setState({ eventSwitchRegressionIsOn: value });
|
||||
};
|
||||
}
|
||||
|
||||
export default CheckBoxOnValueChangeExample;
|
||||
20
docs/storybook/1-components/CheckBox/examples/PropValue.js
Executable file
20
docs/storybook/1-components/CheckBox/examples/PropValue.js
Executable file
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import styles from './styles';
|
||||
import { CheckBox, View } from 'react-native';
|
||||
|
||||
const CheckBoxValueExample = () => (
|
||||
<View style={styles.row}>
|
||||
<View style={styles.marginRight}>
|
||||
<CheckBox value={false} />
|
||||
</View>
|
||||
<View style={styles.marginRight}>
|
||||
<CheckBox value />
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
|
||||
export default CheckBoxValueExample;
|
||||
23
docs/storybook/1-components/CheckBox/examples/styles.js
Executable file
23
docs/storybook/1-components/CheckBox/examples/styles.js
Executable file
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import { StyleSheet } from 'react-native';
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
row: {
|
||||
flexDirection: 'row',
|
||||
flexWrap: 'wrap'
|
||||
},
|
||||
marginRight: {
|
||||
marginRight: 10
|
||||
},
|
||||
marginBottom: {
|
||||
marginBottom: 10
|
||||
},
|
||||
alignCenter: {
|
||||
alignItems: 'center'
|
||||
}
|
||||
});
|
||||
|
||||
export default styles;
|
||||
36
docs/storybook/1-components/CheckBox/helpers.js
Normal file
36
docs/storybook/1-components/CheckBox/helpers.js
Normal file
@@ -0,0 +1,36 @@
|
||||
/**
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { StyleSheet, View } from 'react-native';
|
||||
|
||||
const DividerHorizontal = () => <View style={styles.horizontalDivider} />;
|
||||
const DividerVertical = () => <View style={styles.verticalDivider} />;
|
||||
|
||||
export const styles = StyleSheet.create({
|
||||
horizontalDivider: {
|
||||
width: '0.6rem'
|
||||
},
|
||||
verticalDivider: {
|
||||
height: '1.3125rem'
|
||||
},
|
||||
row: {
|
||||
flexDirection: 'row',
|
||||
flexWrap: 'wrap'
|
||||
},
|
||||
marginRight: {
|
||||
marginRight: 10
|
||||
},
|
||||
marginBottom: {
|
||||
marginBottom: 10
|
||||
},
|
||||
marginVertical: {
|
||||
marginVertical: 5
|
||||
},
|
||||
alignCenter: {
|
||||
alignItems: 'center'
|
||||
}
|
||||
});
|
||||
|
||||
export { DividerHorizontal, DividerVertical };
|
||||
32
docs/storybook/1-components/Image/ImageBackgroundScreen.js
Normal file
32
docs/storybook/1-components/Image/ImageBackgroundScreen.js
Normal file
@@ -0,0 +1,32 @@
|
||||
/* eslint-disable react/jsx-sort-props */
|
||||
|
||||
/**
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import PropChildren from './examples/PropChildren';
|
||||
import UIExplorer, { Description, DocItem, Section, storiesOf } from '../../ui-explorer';
|
||||
|
||||
const ImageBackgroundScreen = () => (
|
||||
<UIExplorer title="ImageBackground" url="1-components/ImageBackground">
|
||||
<Description>A image component with support for child content.</Description>
|
||||
|
||||
<Section title="Props">
|
||||
<DocItem name="...Image props" />
|
||||
|
||||
<DocItem
|
||||
name="children"
|
||||
typeInfo="?any"
|
||||
description="Content to display over the image."
|
||||
example={{
|
||||
render: () => <PropChildren />
|
||||
}}
|
||||
/>
|
||||
|
||||
<DocItem name="imageStyle" typeInfo="?style" description="Styles for the inner image." />
|
||||
</Section>
|
||||
</UIExplorer>
|
||||
);
|
||||
|
||||
storiesOf('Components', module).add('ImageBackground', ImageBackgroundScreen);
|
||||
@@ -5,7 +5,6 @@
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import PropChildren from './examples/PropChildren';
|
||||
import PropDefaultSource from './examples/PropDefaultSource';
|
||||
import PropDraggable from './examples/PropDraggable';
|
||||
import PropOnError from './examples/PropOnError';
|
||||
@@ -35,15 +34,6 @@ const ImageScreen = () => (
|
||||
<Section title="Props">
|
||||
<DocItem name="...View props" />
|
||||
|
||||
<DocItem
|
||||
name="children"
|
||||
typeInfo="?any"
|
||||
description="Content to display over the image."
|
||||
example={{
|
||||
render: () => <PropChildren />
|
||||
}}
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="defaultSource"
|
||||
typeInfo="?object"
|
||||
|
||||
@@ -31,7 +31,8 @@ class NetworkImageExample extends PureComponent {
|
||||
) : null;
|
||||
|
||||
return (
|
||||
<View style={[helpers.styles.row, helpers.styles.centerRow]}>
|
||||
<View>
|
||||
{loader}
|
||||
<Image
|
||||
defaultSource={sources.placeholder}
|
||||
onError={this._handleError}
|
||||
@@ -40,10 +41,8 @@ class NetworkImageExample extends PureComponent {
|
||||
onLoadStart={this._handleLoadStart}
|
||||
source={this.props.source}
|
||||
style={helpers.styles.base}
|
||||
>
|
||||
{loader}
|
||||
</Image>
|
||||
{this.state.message && <Text style={helpers.styles.marginLeft}>{this.state.message}</Text>}
|
||||
/>
|
||||
{this.state.message && <Text style={helpers.styles.marginTop}>{this.state.message}</Text>}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -4,25 +4,29 @@
|
||||
|
||||
import sources from '../sources';
|
||||
import React from 'react';
|
||||
import { Image, StyleSheet, Text } from 'react-native';
|
||||
import { ImageBackground, StyleSheet, Text } from 'react-native';
|
||||
|
||||
const ImageChildrenExample = () => (
|
||||
<Image source={sources.large} style={styles.image}>
|
||||
<Text style={styles.text}>React</Text>
|
||||
</Image>
|
||||
<ImageBackground source={sources.large} style={styles.image}>
|
||||
<Text style={styles.text}>Child content</Text>
|
||||
</ImageBackground>
|
||||
);
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
image: {
|
||||
width: 60,
|
||||
height: 60,
|
||||
width: 300,
|
||||
height: 200,
|
||||
backgroundColor: 'transparent',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center'
|
||||
},
|
||||
text: {
|
||||
backgroundColor: 'transparent',
|
||||
color: 'white'
|
||||
color: 'white',
|
||||
fontWeight: 'bold',
|
||||
fontSize: 18,
|
||||
position: 'relative',
|
||||
top: 50
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -8,11 +8,7 @@ import React from 'react';
|
||||
import { Image } from 'react-native';
|
||||
|
||||
const ImageDefaultSourceExample = () => (
|
||||
<Image
|
||||
defaultSource={sources.placeholder}
|
||||
source={sources.largeAlt}
|
||||
style={helpers.styles.base}
|
||||
/>
|
||||
<Image defaultSource={sources.placeholder} style={helpers.styles.base} />
|
||||
);
|
||||
|
||||
export default ImageDefaultSourceExample;
|
||||
|
||||
@@ -17,8 +17,8 @@ const styles = StyleSheet.create({
|
||||
flexDirection: 'row'
|
||||
},
|
||||
image: {
|
||||
width: 60,
|
||||
height: 60,
|
||||
width: 300,
|
||||
height: 200,
|
||||
backgroundColor: 'transparent',
|
||||
marginRight: 10
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import React from 'react';
|
||||
import sources from '../sources';
|
||||
|
||||
const ImageOnLoadExample = () => (
|
||||
<NetworkImage logMethod="onLoad" source={createUncachedURI(sources.small)} />
|
||||
<NetworkImage logMethod="onLoad" source={createUncachedURI(sources.largeAlt)} />
|
||||
);
|
||||
|
||||
export default ImageOnLoadExample;
|
||||
|
||||
@@ -8,7 +8,7 @@ import React from 'react';
|
||||
import sources from '../sources';
|
||||
|
||||
const ImageOnLoadEndExample = () => (
|
||||
<NetworkImage logMethod="onLoadEnd" source={createUncachedURI(sources.small)} />
|
||||
<NetworkImage logMethod="onLoadEnd" source={createUncachedURI(sources.largeAlt)} />
|
||||
);
|
||||
|
||||
export default ImageOnLoadEndExample;
|
||||
|
||||
@@ -8,7 +8,7 @@ import React from 'react';
|
||||
import sources from '../sources';
|
||||
|
||||
const ImageOnLoadStartExample = () => (
|
||||
<NetworkImage logMethod="onLoadStart" source={createUncachedURI(sources.small)} />
|
||||
<NetworkImage logMethod="onLoadStart" source={createUncachedURI(sources.largeAlt)} />
|
||||
);
|
||||
|
||||
export default ImageOnLoadStartExample;
|
||||
|
||||
@@ -8,7 +8,7 @@ import { Image, StyleSheet, Text, View } from 'react-native';
|
||||
|
||||
const ImageResizeModeExample = () => (
|
||||
<View>
|
||||
{[sources.small, sources.large].map((source, i) => {
|
||||
{[sources.small].map((source, i) => {
|
||||
return (
|
||||
<View key={i}>
|
||||
<View style={styles.horizontal}>
|
||||
@@ -60,12 +60,11 @@ const styles = StyleSheet.create({
|
||||
resizeMode: {
|
||||
borderColor: 'black',
|
||||
borderWidth: 0.5,
|
||||
height: 60,
|
||||
width: 90
|
||||
height: 120,
|
||||
width: 120
|
||||
},
|
||||
resizeModeText: {
|
||||
fontSize: 11,
|
||||
marginBottom: 3
|
||||
marginBottom: '0.5rem'
|
||||
},
|
||||
leftMargin: {
|
||||
marginLeft: 10
|
||||
|
||||
@@ -30,18 +30,22 @@ const ImageSourceExample = () => (
|
||||
const styles = StyleSheet.create({
|
||||
row: {
|
||||
flexDirection: 'row',
|
||||
flexWrap: 'wrap'
|
||||
flexWrap: 'wrap',
|
||||
justifyContent: 'space-between'
|
||||
},
|
||||
column: {
|
||||
marginRight: '1rem'
|
||||
alignItems: 'flex-start',
|
||||
marginBottom: '1rem'
|
||||
},
|
||||
text: {
|
||||
marginBottom: '0.5rem'
|
||||
},
|
||||
image: {
|
||||
flex: 1,
|
||||
height: 50,
|
||||
resizeMode: 'contain'
|
||||
borderColor: 'black',
|
||||
borderWidth: 0.5,
|
||||
height: 120,
|
||||
width: 120,
|
||||
resizeMode: 'cover'
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -13,8 +13,8 @@ const createUncachedURI = source => {
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
base: {
|
||||
height: 38,
|
||||
width: 38
|
||||
height: 200,
|
||||
width: 300
|
||||
},
|
||||
row: {
|
||||
flexDirection: 'row'
|
||||
@@ -22,8 +22,8 @@ const styles = StyleSheet.create({
|
||||
centerRow: {
|
||||
alignItems: 'center'
|
||||
},
|
||||
marginLeft: {
|
||||
marginLeft: '1rem'
|
||||
marginTop: {
|
||||
marginTop: '1rem'
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 18 KiB |
@@ -1,5 +1,5 @@
|
||||
import placeholder from './bunny.png';
|
||||
import staticImage from './uie_thumb_normal@2x.png';
|
||||
import placeholder from './placeholder.jpg';
|
||||
import staticImage from './ladybug.jpg';
|
||||
|
||||
const dataPng =
|
||||
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEsAAABLCAQAAACSR7JhAAADtUlEQVR4Ac3YA2Bj6QLH0XPT1Fzbtm29tW3btm3bfLZtv7e2ObZnms7d8Uw098tuetPzrxv8wiISrtVudrG2JXQZ4VOv+qUfmqCGGl1mqLhoA52oZlb0mrjsnhKpgeUNEs91Z0pd1kvihA3ULGVHiQO2narKSHKkEMulm9VgUyE60s1aWoMQUbpZOWE+kaqs4eLEjdIlZTcFZB0ndc1+lhB1lZrIuk5P2aib1NBpZaL+JaOGIt0ls47SKzLC7CqrlGF6RZ09HGoNy1lYl2aRSWL5GuzqWU1KafRdoRp0iOQEiDzgZPnG6DbldcomadViflnl/cL93tOoVbsOLVM2jylvdWjXolWX1hmfZbGR/wjypDjFLSZIRov09BgYmtUqPQPlQrPapecLgTIy0jMgPKtTeob2zWtrGH3xvjUkPCtNg/tm1rjwrMa+mdUkPd3hWbH0jArPGiU9ufCsNNWFZ40wpwn+62/66R2RUtoso1OB34tnLOcy7YB1fUdc9e0q3yru8PGM773vXsuZ5YIZX+5xmHwHGVvlrGPN6ZSiP1smOsMMde40wKv2VmwPPVXNut4sVpUreZiLBHi0qln/VQeI/LTMYXpsJtFiclUN+5HVZazim+Ky+7sAvxWnvjXrJFneVtLWLyPJu9K3cXLWeOlbMTlrIelbMDlrLenrjEQOtIF+fuI9xRp9ZBFp6+b6WT8RrxEpdK64BuvHgDk+vUy+b5hYk6zfyfs051gRoNO1usU12WWRWL73/MMEy9pMi9qIrR4ZpV16Rrvduxazmy1FSvuFXRkqTnE7m2kdb5U8xGjLw/spRr1uTov4uOgQE+0N/DvFrG/Jt7i/FzwxbA9kDanhf2w+t4V97G8lrT7wc08aA2QNUkuTfW/KimT01wdlfK4yEw030VfT0RtZbzjeMprNq8m8tnSTASrTLti64oBNdpmMQm0eEwvfPwRbUBywG5TzjPCsdwk3IeAXjQblLCoXnDVeoAz6SfJNk5TTzytCNZk/POtTSV40NwOFWzw86wNJRpubpXsn60NJFlHeqlYRbslqZm2jnEZ3qcSKgm0kTli3zZVS7y/iivZTweYXJ26Y+RTbV1zh3hYkgyFGSTKPfRVbRqWWVReaxYeSLarYv1Qqsmh1s95S7G+eEWK0f3jYKTbV6bOwepjfhtafsvUsqrQvrGC8YhmnO9cSCk3yuY984F1vesdHYhWJ5FvASlacshUsajFt2mUM9pqzvKGcyNJW0arTKN1GGGzQlH0tXwLDgQTurS8eIQAAAABJRU5ErkJggg==';
|
||||
@@ -12,11 +12,27 @@ const sources = {
|
||||
'http://38.media.tumblr.com/9e9bd08c6e2d10561dd1fb4197df4c4e/tumblr_mfqekpMktw1rn90umo1_500.gif'
|
||||
},
|
||||
broken: { uri: 'http://TYPO_ERROR.github.io/image.png' },
|
||||
small: { uri: 'http://facebook.github.io/react/img/logo_small_2x.png' },
|
||||
large: { uri: 'http://facebook.github.io/react/img/logo_og.png' },
|
||||
largeAlt: { uri: 'http://facebook.github.io/origami/public/images/birds.jpg' },
|
||||
small: {
|
||||
uri:
|
||||
'https://images.unsplash.com/photo-1488584585634-35fc98ccb808?dpr=1&auto=format&fit=crop&w=100&h=66&q=60&cs=tinysrgb'
|
||||
},
|
||||
smallAlt: {
|
||||
uri:
|
||||
'https://images.unsplash.com/photo-1481595357459-84468f6eeaac?dpr=1&auto=format&fit=crop&w=100&h=66&q=60&cs=tinysrgb'
|
||||
},
|
||||
large: {
|
||||
uri:
|
||||
'https://images.unsplash.com/photo-1481595357459-84468f6eeaac?dpr=1&auto=format&fit=crop&w=376&h=251&q=60&cs=tinysrgb'
|
||||
},
|
||||
largeAlt: {
|
||||
uri:
|
||||
'https://images.unsplash.com/photo-1471145653077-54c6f0aae511?dpr=1&auto=format&fit=crop&w=376&h=251&q=60&cs=tinysrgb'
|
||||
},
|
||||
placeholder,
|
||||
prefetchable: { uri: 'http://origami.design/public/images/bird-logo.png' },
|
||||
prefetchable: {
|
||||
uri:
|
||||
'https://images.unsplash.com/photo-1471145653077-54c6f0aae511?dpr=1&auto=format&fit=crop&w=376&h=251&q=60&cs=tinysrgb'
|
||||
},
|
||||
static: staticImage,
|
||||
huge: {
|
||||
uri: 'https://upload.wikimedia.org/wikipedia/commons/d/d7/Chestnut-mandibled_Toucan.jpg'
|
||||
|
||||
BIN
docs/storybook/1-components/Image/sources/ladybug.jpg
Normal file
BIN
docs/storybook/1-components/Image/sources/ladybug.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 77 KiB |
BIN
docs/storybook/1-components/Image/sources/placeholder.jpg
Normal file
BIN
docs/storybook/1-components/Image/sources/placeholder.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 19 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 850 B |
Binary file not shown.
|
Before Width: | Height: | Size: 1.1 KiB |
113
docs/storybook/1-components/Picker/PickerScreen.js
Normal file
113
docs/storybook/1-components/Picker/PickerScreen.js
Normal file
@@ -0,0 +1,113 @@
|
||||
/* eslint-disable react/jsx-sort-props, react/jsx-no-bind, no-alert */
|
||||
|
||||
/**
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import PickerExample from './examples/PickerExample';
|
||||
import UIExplorer, {
|
||||
AppText,
|
||||
Description,
|
||||
DocItem,
|
||||
Section,
|
||||
StyleList,
|
||||
storiesOf
|
||||
} from '../../ui-explorer';
|
||||
import { View } from 'react-native';
|
||||
|
||||
const PickerScreen = () => (
|
||||
<View>
|
||||
<UIExplorer title="Picker">
|
||||
<Description>
|
||||
<AppText>Renders the native <select> component.</AppText>
|
||||
</Description>
|
||||
<Section title="Props">
|
||||
<DocItem
|
||||
name="children"
|
||||
typeInfo="?Array<Picker.Item>"
|
||||
description="The items to display in the picker."
|
||||
example={{
|
||||
code: `<Picker>
|
||||
<Picker.Item label="Goblet of Fire" />
|
||||
<Picker.Item label="Order of the Phoenix" />
|
||||
</Picker>`
|
||||
}}
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="enabled"
|
||||
typeInfo="?boolean"
|
||||
description="If set to false, the picker will be disabled, i.e., the user will not be able to make a selection."
|
||||
example={{
|
||||
render: () => <PickerExample enabled={false} />
|
||||
}}
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="onValueChange"
|
||||
typeInfo="?(itemValue, itemIndex) => void"
|
||||
description="Callback for when an item is selected. This is called with the value and index prop of the item that was selected."
|
||||
example={{
|
||||
render: () => (
|
||||
<PickerExample
|
||||
onValueChange={(itemValue, itemPosition) => {
|
||||
window.alert(`itemValue: ${itemValue}, itemPosition: ${itemPosition}`);
|
||||
}}
|
||||
/>
|
||||
)
|
||||
}}
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="selectedValue"
|
||||
typeInfo="?string"
|
||||
description="Select the item with the matching value."
|
||||
example={{
|
||||
render: () => <PickerExample selectedValue="book-3" />
|
||||
}}
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="style"
|
||||
typeInfo="?style"
|
||||
description={
|
||||
<StyleList
|
||||
stylePropTypes={[
|
||||
{
|
||||
name: '…View#style'
|
||||
},
|
||||
{
|
||||
name: 'color',
|
||||
typeInfo: 'color'
|
||||
}
|
||||
]}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="testID"
|
||||
typeInfo="?string"
|
||||
description="Used to locate this view in end-to-end tests."
|
||||
/>
|
||||
</Section>
|
||||
</UIExplorer>
|
||||
|
||||
<UIExplorer title="Picker.Item" url="1-components/Picker">
|
||||
<Description>Individual selectable item in a Picker.</Description>
|
||||
|
||||
<Section title="Props">
|
||||
<DocItem name="label" typeInfo="string" description="Text to display for this item" />
|
||||
<DocItem name="testID" typeInfo="?string" />
|
||||
<DocItem
|
||||
name="value"
|
||||
typeInfo="?number | string"
|
||||
description="The value to be passed to the picker's 'onValueChange' callback when this item is selected."
|
||||
/>
|
||||
</Section>
|
||||
</UIExplorer>
|
||||
</View>
|
||||
);
|
||||
|
||||
storiesOf('Components', module).add('Picker', PickerScreen);
|
||||
28
docs/storybook/1-components/Picker/examples/PickerExample.js
Normal file
28
docs/storybook/1-components/Picker/examples/PickerExample.js
Normal file
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { Picker, StyleSheet, View } from 'react-native';
|
||||
|
||||
const PickerExample = props => (
|
||||
<View style={styles.root}>
|
||||
<Picker {...props}>
|
||||
<Picker.Item label="Sourcerer's Stone" value="book-1" />
|
||||
<Picker.Item label="Chamber of Secrets" value="book-2" />
|
||||
<Picker.Item label="Prisoner of Azkaban" value="book-3" />
|
||||
<Picker.Item label="Goblet of Fire" value="book-4" />
|
||||
<Picker.Item label="Order of the Phoenix" value="book-5" />
|
||||
<Picker.Item label="Half-Blood Prince" value="book-6" />
|
||||
<Picker.Item label="Deathly Hallows" value="book-7" />
|
||||
</Picker>
|
||||
</View>
|
||||
);
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
rootl: {
|
||||
alignItems: 'flex-start'
|
||||
}
|
||||
});
|
||||
|
||||
export default PickerExample;
|
||||
@@ -46,9 +46,11 @@ export default class TextEventsExample extends React.Component {
|
||||
event.nativeEvent.selection.start +
|
||||
',' +
|
||||
event.nativeEvent.selection.end
|
||||
)}
|
||||
)
|
||||
}
|
||||
onSubmitEditing={event =>
|
||||
this.updateText('onSubmitEditing text: ' + event.nativeEvent.text)}
|
||||
this.updateText('onSubmitEditing text: ' + event.nativeEvent.text)
|
||||
}
|
||||
placeholder="Enter text to see events"
|
||||
style={[helperStyles.textinput, { maxWidth: 200 }]}
|
||||
/>
|
||||
|
||||
@@ -43,7 +43,7 @@ const DimensionsScreen = () => (
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="static addEventLitener"
|
||||
name="static addEventListener"
|
||||
typeInfo="(type: string, handler: function) => void"
|
||||
description={[
|
||||
<AppText>Add an event handler. Supported events:</AppText>,
|
||||
@@ -65,7 +65,7 @@ const DimensionsScreen = () => (
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="static removeEventLitener"
|
||||
name="static removeEventListener"
|
||||
typeInfo="(type: string, handler: function) => void"
|
||||
description="Remove an event handler."
|
||||
/>
|
||||
|
||||
@@ -32,8 +32,9 @@ const NetInfoScreen = () => (
|
||||
<DocItem
|
||||
description={
|
||||
<AppText>
|
||||
One of <Code>slow-2g</Code>, <Code>2g</Code>, <Code>3g</Code>, <Code>4g</Code>,{' '}
|
||||
<Code>unknown</Code>.
|
||||
One of <Code>bluebooth</Code>, <Code>cellular</Code>, <Code>ethernet</Code>,{' '}
|
||||
<Code>mixed</Code>, <Code>mixed</Code>, <Code>none</Code>, <Code>other</Code>,{' '}
|
||||
<Code>unknown</Code>, <Code>wifi</Code>, <Code>wimax</Code>
|
||||
</AppText>
|
||||
}
|
||||
name="ConnectionType"
|
||||
@@ -41,9 +42,8 @@ const NetInfoScreen = () => (
|
||||
<DocItem
|
||||
description={
|
||||
<AppText>
|
||||
One of <Code>bluebooth</Code>, <Code>cellular</Code>, <Code>ethernet</Code>,{' '}
|
||||
<Code>mixed</Code>, <Code>mixed</Code>, <Code>none</Code>, <Code>other</Code>,{' '}
|
||||
<Code>unknown</Code>, <Code>wifi</Code>, <Code>wimax</Code>
|
||||
One of <Code>slow-2g</Code>, <Code>2g</Code>, <Code>3g</Code>, <Code>4g</Code>,{' '}
|
||||
<Code>unknown</Code>.
|
||||
</AppText>
|
||||
}
|
||||
name="EffectiveConnectionType"
|
||||
|
||||
@@ -21,6 +21,22 @@ const StyleSheetScreen = () => (
|
||||
</Description>
|
||||
|
||||
<Section title="Methods">
|
||||
<DocItem
|
||||
description={
|
||||
<AppText>
|
||||
Combines two styles such that <Code>style2</Code> will override any styles in{' '}
|
||||
<Code>style1</Code>. If either style is falsy, the other one is returned without
|
||||
allocating an array, saving allocations and maintaining reference equality for{' '}
|
||||
<Code>PureComponent</Code> checks.
|
||||
</AppText>
|
||||
}
|
||||
example={{
|
||||
code: 'StyleSheet.compose(style1, style2);'
|
||||
}}
|
||||
name="compose"
|
||||
typeInfo="(style1, style2) => style"
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
description="Each key of the object passed to `create` must define a style object. The returned object replaces style objects with IDs"
|
||||
example={{
|
||||
@@ -88,7 +104,11 @@ StyleSheet.flatten([styles.listItem, styles.selectedListItem]);`
|
||||
typeInfo="object"
|
||||
/>
|
||||
|
||||
<DocItem name="hairlineWidth" typeInfo="number" />
|
||||
<DocItem
|
||||
description="Enables borders of just one physical pixel on retina screens, otherwise it is equal to a CSS value of 1px."
|
||||
name="hairlineWidth"
|
||||
typeInfo="number"
|
||||
/>
|
||||
</Section>
|
||||
</UIExplorer>
|
||||
);
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
import Enzyme from 'enzyme';
|
||||
import Adapter from 'enzyme-adapter-react-16';
|
||||
import createSerializer from './jest/createSerializer';
|
||||
import Enzyme from 'enzyme';
|
||||
import { StyleSheet } from './src';
|
||||
|
||||
const serializer = createSerializer(StyleSheet);
|
||||
|
||||
Enzyme.configure({ adapter: new Adapter() });
|
||||
expect.addSnapshotSerializer(serializer);
|
||||
|
||||
299
jest/__tests__/__snapshots__/serializer-test.js.snap
Normal file
299
jest/__tests__/__snapshots__/serializer-test.js.snap
Normal file
@@ -0,0 +1,299 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`enzyme.mount complex 1`] = `
|
||||
<Box
|
||||
element={
|
||||
<View>
|
||||
<View
|
||||
style={
|
||||
Object {
|
||||
"padding": 20,
|
||||
}
|
||||
}
|
||||
/>
|
||||
<Text>
|
||||
Nested
|
||||
</Text>
|
||||
</View>
|
||||
}
|
||||
>
|
||||
<View
|
||||
style={
|
||||
Object {
|
||||
"backgroundColor": "red",
|
||||
"padding": 10,
|
||||
}
|
||||
}
|
||||
>
|
||||
<div
|
||||
className="rn-alignItems-1oszu61 rn-backgroundColor-1mjtqww rn-borderTopStyle-1efd50x rn-borderRightStyle-14skgim rn-borderBottomStyle-rull8r rn-borderLeftStyle-mm0ijv rn-borderTopWidth-13yce4e rn-borderRightWidth-fnigne rn-borderBottomWidth-ndvcnb rn-borderLeftWidth-gxnn5r rn-boxSizing-deolkf rn-display-6koalj rn-flexShrink-1pxmb3b rn-flexBasis-7vfszb rn-flexDirection-eqz5dr rn-marginTop-1mnahxq rn-marginRight-61z16t rn-marginBottom-p1pxzi rn-marginLeft-11wrixw rn-minHeight-ifefl9 rn-minWidth-bcqeeo rn-paddingTop-m611by rn-paddingRight-1qfoi16 rn-paddingBottom-1mi0q7o rn-paddingLeft-1hfyk0a rn-position-bnwqim rn-zIndex-1lgpqti"
|
||||
>
|
||||
<Title>
|
||||
<Text
|
||||
style={
|
||||
Object {
|
||||
"color": "black",
|
||||
"fontSize": 16,
|
||||
"textAlignVertical": "center",
|
||||
}
|
||||
}
|
||||
>
|
||||
<div
|
||||
className="rn-borderTopWidth-13yce4e rn-borderRightWidth-fnigne rn-borderBottomWidth-ndvcnb rn-borderLeftWidth-gxnn5r rn-boxSizing-deolkf rn-color-1bodaif rn-display-1471scf rn-font-1lw9tu2 rn-fontFamily-10u92zi rn-fontSize-ubezar rn-marginTop-1mnahxq rn-marginRight-61z16t rn-marginBottom-p1pxzi rn-marginLeft-11wrixw rn-paddingTop-wk8lta rn-paddingRight-9aemit rn-paddingBottom-1mdbw0j rn-paddingLeft-gy4na3 rn-verticalAlign-9iso6 rn-textDecoration-bauka4 rn-whiteSpace-q42fyq rn-wordWrap-qvutc0"
|
||||
dir="auto"
|
||||
>
|
||||
Hello World
|
||||
</div>
|
||||
</Text>
|
||||
</Title>
|
||||
<View>
|
||||
<div
|
||||
className="rn-alignItems-1oszu61 rn-borderTopStyle-1efd50x rn-borderRightStyle-14skgim rn-borderBottomStyle-rull8r rn-borderLeftStyle-mm0ijv rn-borderTopWidth-13yce4e rn-borderRightWidth-fnigne rn-borderBottomWidth-ndvcnb rn-borderLeftWidth-gxnn5r rn-boxSizing-deolkf rn-display-6koalj rn-flexShrink-1pxmb3b rn-flexBasis-7vfszb rn-flexDirection-eqz5dr rn-marginTop-1mnahxq rn-marginRight-61z16t rn-marginBottom-p1pxzi rn-marginLeft-11wrixw rn-minHeight-ifefl9 rn-minWidth-bcqeeo rn-paddingTop-wk8lta rn-paddingRight-9aemit rn-paddingBottom-1mdbw0j rn-paddingLeft-gy4na3 rn-position-bnwqim rn-zIndex-1lgpqti"
|
||||
>
|
||||
<View
|
||||
style={
|
||||
Object {
|
||||
"padding": 20,
|
||||
}
|
||||
}
|
||||
>
|
||||
<div
|
||||
className="rn-alignItems-1oszu61 rn-borderTopStyle-1efd50x rn-borderRightStyle-14skgim rn-borderBottomStyle-rull8r rn-borderLeftStyle-mm0ijv rn-borderTopWidth-13yce4e rn-borderRightWidth-fnigne rn-borderBottomWidth-ndvcnb rn-borderLeftWidth-gxnn5r rn-boxSizing-deolkf rn-display-6koalj rn-flexShrink-1pxmb3b rn-flexBasis-7vfszb rn-flexDirection-eqz5dr rn-marginTop-1mnahxq rn-marginRight-61z16t rn-marginBottom-p1pxzi rn-marginLeft-11wrixw rn-minHeight-ifefl9 rn-minWidth-bcqeeo rn-paddingTop-1knelpx rn-paddingRight-1ah4tor rn-paddingBottom-k8qxaj rn-paddingLeft-b5h31w rn-position-bnwqim rn-zIndex-1lgpqti"
|
||||
/>
|
||||
</View>
|
||||
<Text>
|
||||
<div
|
||||
className="rn-borderTopWidth-13yce4e rn-borderRightWidth-fnigne rn-borderBottomWidth-ndvcnb rn-borderLeftWidth-gxnn5r rn-boxSizing-deolkf rn-color-homxoj rn-display-1471scf rn-font-1lw9tu2 rn-fontFamily-10u92zi rn-fontSize-1b43r93 rn-marginTop-1mnahxq rn-marginRight-61z16t rn-marginBottom-p1pxzi rn-marginLeft-11wrixw rn-paddingTop-wk8lta rn-paddingRight-9aemit rn-paddingBottom-1mdbw0j rn-paddingLeft-gy4na3 rn-textDecoration-bauka4 rn-whiteSpace-q42fyq rn-wordWrap-qvutc0"
|
||||
dir="auto"
|
||||
>
|
||||
Nested
|
||||
</div>
|
||||
</Text>
|
||||
</div>
|
||||
</View>
|
||||
</div>
|
||||
</View>
|
||||
</Box>
|
||||
`;
|
||||
|
||||
exports[`enzyme.mount composite 1`] = `
|
||||
<Box>
|
||||
<View
|
||||
style={
|
||||
Object {
|
||||
"backgroundColor": "red",
|
||||
"padding": 10,
|
||||
}
|
||||
}
|
||||
>
|
||||
<div
|
||||
className="rn-alignItems-1oszu61 rn-backgroundColor-1mjtqww rn-borderTopStyle-1efd50x rn-borderRightStyle-14skgim rn-borderBottomStyle-rull8r rn-borderLeftStyle-mm0ijv rn-borderTopWidth-13yce4e rn-borderRightWidth-fnigne rn-borderBottomWidth-ndvcnb rn-borderLeftWidth-gxnn5r rn-boxSizing-deolkf rn-display-6koalj rn-flexShrink-1pxmb3b rn-flexBasis-7vfszb rn-flexDirection-eqz5dr rn-marginTop-1mnahxq rn-marginRight-61z16t rn-marginBottom-p1pxzi rn-marginLeft-11wrixw rn-minHeight-ifefl9 rn-minWidth-bcqeeo rn-paddingTop-m611by rn-paddingRight-1qfoi16 rn-paddingBottom-1mi0q7o rn-paddingLeft-1hfyk0a rn-position-bnwqim rn-zIndex-1lgpqti"
|
||||
/>
|
||||
</View>
|
||||
</Box>
|
||||
`;
|
||||
|
||||
exports[`enzyme.mount nested 1`] = `
|
||||
<Box>
|
||||
<View
|
||||
style={
|
||||
Object {
|
||||
"backgroundColor": "red",
|
||||
"padding": 10,
|
||||
}
|
||||
}
|
||||
>
|
||||
<div
|
||||
className="rn-alignItems-1oszu61 rn-backgroundColor-1mjtqww rn-borderTopStyle-1efd50x rn-borderRightStyle-14skgim rn-borderBottomStyle-rull8r rn-borderLeftStyle-mm0ijv rn-borderTopWidth-13yce4e rn-borderRightWidth-fnigne rn-borderBottomWidth-ndvcnb rn-borderLeftWidth-gxnn5r rn-boxSizing-deolkf rn-display-6koalj rn-flexShrink-1pxmb3b rn-flexBasis-7vfszb rn-flexDirection-eqz5dr rn-marginTop-1mnahxq rn-marginRight-61z16t rn-marginBottom-p1pxzi rn-marginLeft-11wrixw rn-minHeight-ifefl9 rn-minWidth-bcqeeo rn-paddingTop-m611by rn-paddingRight-1qfoi16 rn-paddingBottom-1mi0q7o rn-paddingLeft-1hfyk0a rn-position-bnwqim rn-zIndex-1lgpqti"
|
||||
>
|
||||
<Title>
|
||||
<Text
|
||||
style={
|
||||
Object {
|
||||
"color": "black",
|
||||
"fontSize": 16,
|
||||
"textAlignVertical": "center",
|
||||
}
|
||||
}
|
||||
>
|
||||
<div
|
||||
className="rn-borderTopWidth-13yce4e rn-borderRightWidth-fnigne rn-borderBottomWidth-ndvcnb rn-borderLeftWidth-gxnn5r rn-boxSizing-deolkf rn-color-1bodaif rn-display-1471scf rn-font-1lw9tu2 rn-fontFamily-10u92zi rn-fontSize-ubezar rn-marginTop-1mnahxq rn-marginRight-61z16t rn-marginBottom-p1pxzi rn-marginLeft-11wrixw rn-paddingTop-wk8lta rn-paddingRight-9aemit rn-paddingBottom-1mdbw0j rn-paddingLeft-gy4na3 rn-verticalAlign-9iso6 rn-textDecoration-bauka4 rn-whiteSpace-q42fyq rn-wordWrap-qvutc0"
|
||||
dir="auto"
|
||||
>
|
||||
Hello World
|
||||
</div>
|
||||
</Text>
|
||||
</Title>
|
||||
</div>
|
||||
</View>
|
||||
</Box>
|
||||
`;
|
||||
|
||||
exports[`enzyme.mount noop 1`] = `
|
||||
<View>
|
||||
<div
|
||||
className="rn-alignItems-1oszu61 rn-borderTopStyle-1efd50x rn-borderRightStyle-14skgim rn-borderBottomStyle-rull8r rn-borderLeftStyle-mm0ijv rn-borderTopWidth-13yce4e rn-borderRightWidth-fnigne rn-borderBottomWidth-ndvcnb rn-borderLeftWidth-gxnn5r rn-boxSizing-deolkf rn-display-6koalj rn-flexShrink-1pxmb3b rn-flexBasis-7vfszb rn-flexDirection-eqz5dr rn-marginTop-1mnahxq rn-marginRight-61z16t rn-marginBottom-p1pxzi rn-marginLeft-11wrixw rn-minHeight-ifefl9 rn-minWidth-bcqeeo rn-paddingTop-wk8lta rn-paddingRight-9aemit rn-paddingBottom-1mdbw0j rn-paddingLeft-gy4na3 rn-position-bnwqim rn-zIndex-1lgpqti"
|
||||
/>
|
||||
</View>
|
||||
`;
|
||||
|
||||
exports[`enzyme.render complex 1`] = `
|
||||
<div
|
||||
class="rn-alignItems-1oszu61 rn-backgroundColor-1mjtqww rn-borderTopStyle-1efd50x rn-borderRightStyle-14skgim rn-borderBottomStyle-rull8r rn-borderLeftStyle-mm0ijv rn-borderTopWidth-13yce4e rn-borderRightWidth-fnigne rn-borderBottomWidth-ndvcnb rn-borderLeftWidth-gxnn5r rn-boxSizing-deolkf rn-display-6koalj rn-flexShrink-1pxmb3b rn-flexBasis-7vfszb rn-flexDirection-eqz5dr rn-marginTop-1mnahxq rn-marginRight-61z16t rn-marginBottom-p1pxzi rn-marginLeft-11wrixw rn-minHeight-ifefl9 rn-minWidth-bcqeeo rn-paddingTop-m611by rn-paddingRight-1qfoi16 rn-paddingBottom-1mi0q7o rn-paddingLeft-1hfyk0a rn-position-bnwqim rn-zIndex-1lgpqti"
|
||||
>
|
||||
<div
|
||||
class="rn-borderTopWidth-13yce4e rn-borderRightWidth-fnigne rn-borderBottomWidth-ndvcnb rn-borderLeftWidth-gxnn5r rn-boxSizing-deolkf rn-color-1bodaif rn-display-1471scf rn-font-1lw9tu2 rn-fontFamily-10u92zi rn-fontSize-ubezar rn-marginTop-1mnahxq rn-marginRight-61z16t rn-marginBottom-p1pxzi rn-marginLeft-11wrixw rn-paddingTop-wk8lta rn-paddingRight-9aemit rn-paddingBottom-1mdbw0j rn-paddingLeft-gy4na3 rn-verticalAlign-9iso6 rn-textDecoration-bauka4 rn-whiteSpace-q42fyq rn-wordWrap-qvutc0"
|
||||
dir="auto"
|
||||
>
|
||||
Hello World
|
||||
</div>
|
||||
<div
|
||||
class="rn-alignItems-1oszu61 rn-borderTopStyle-1efd50x rn-borderRightStyle-14skgim rn-borderBottomStyle-rull8r rn-borderLeftStyle-mm0ijv rn-borderTopWidth-13yce4e rn-borderRightWidth-fnigne rn-borderBottomWidth-ndvcnb rn-borderLeftWidth-gxnn5r rn-boxSizing-deolkf rn-display-6koalj rn-flexShrink-1pxmb3b rn-flexBasis-7vfszb rn-flexDirection-eqz5dr rn-marginTop-1mnahxq rn-marginRight-61z16t rn-marginBottom-p1pxzi rn-marginLeft-11wrixw rn-minHeight-ifefl9 rn-minWidth-bcqeeo rn-paddingTop-wk8lta rn-paddingRight-9aemit rn-paddingBottom-1mdbw0j rn-paddingLeft-gy4na3 rn-position-bnwqim rn-zIndex-1lgpqti"
|
||||
>
|
||||
<div
|
||||
class="rn-alignItems-1oszu61 rn-borderTopStyle-1efd50x rn-borderRightStyle-14skgim rn-borderBottomStyle-rull8r rn-borderLeftStyle-mm0ijv rn-borderTopWidth-13yce4e rn-borderRightWidth-fnigne rn-borderBottomWidth-ndvcnb rn-borderLeftWidth-gxnn5r rn-boxSizing-deolkf rn-display-6koalj rn-flexShrink-1pxmb3b rn-flexBasis-7vfszb rn-flexDirection-eqz5dr rn-marginTop-1mnahxq rn-marginRight-61z16t rn-marginBottom-p1pxzi rn-marginLeft-11wrixw rn-minHeight-ifefl9 rn-minWidth-bcqeeo rn-paddingTop-1knelpx rn-paddingRight-1ah4tor rn-paddingBottom-k8qxaj rn-paddingLeft-b5h31w rn-position-bnwqim rn-zIndex-1lgpqti"
|
||||
/>
|
||||
<div
|
||||
class="rn-borderTopWidth-13yce4e rn-borderRightWidth-fnigne rn-borderBottomWidth-ndvcnb rn-borderLeftWidth-gxnn5r rn-boxSizing-deolkf rn-color-homxoj rn-display-1471scf rn-font-1lw9tu2 rn-fontFamily-10u92zi rn-fontSize-1b43r93 rn-marginTop-1mnahxq rn-marginRight-61z16t rn-marginBottom-p1pxzi rn-marginLeft-11wrixw rn-paddingTop-wk8lta rn-paddingRight-9aemit rn-paddingBottom-1mdbw0j rn-paddingLeft-gy4na3 rn-textDecoration-bauka4 rn-whiteSpace-q42fyq rn-wordWrap-qvutc0"
|
||||
dir="auto"
|
||||
>
|
||||
Nested
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`enzyme.render composite 1`] = `
|
||||
<div
|
||||
class="rn-alignItems-1oszu61 rn-backgroundColor-1mjtqww rn-borderTopStyle-1efd50x rn-borderRightStyle-14skgim rn-borderBottomStyle-rull8r rn-borderLeftStyle-mm0ijv rn-borderTopWidth-13yce4e rn-borderRightWidth-fnigne rn-borderBottomWidth-ndvcnb rn-borderLeftWidth-gxnn5r rn-boxSizing-deolkf rn-display-6koalj rn-flexShrink-1pxmb3b rn-flexBasis-7vfszb rn-flexDirection-eqz5dr rn-marginTop-1mnahxq rn-marginRight-61z16t rn-marginBottom-p1pxzi rn-marginLeft-11wrixw rn-minHeight-ifefl9 rn-minWidth-bcqeeo rn-paddingTop-m611by rn-paddingRight-1qfoi16 rn-paddingBottom-1mi0q7o rn-paddingLeft-1hfyk0a rn-position-bnwqim rn-zIndex-1lgpqti"
|
||||
/>
|
||||
`;
|
||||
|
||||
exports[`enzyme.render nested 1`] = `
|
||||
<div
|
||||
class="rn-alignItems-1oszu61 rn-backgroundColor-1mjtqww rn-borderTopStyle-1efd50x rn-borderRightStyle-14skgim rn-borderBottomStyle-rull8r rn-borderLeftStyle-mm0ijv rn-borderTopWidth-13yce4e rn-borderRightWidth-fnigne rn-borderBottomWidth-ndvcnb rn-borderLeftWidth-gxnn5r rn-boxSizing-deolkf rn-display-6koalj rn-flexShrink-1pxmb3b rn-flexBasis-7vfszb rn-flexDirection-eqz5dr rn-marginTop-1mnahxq rn-marginRight-61z16t rn-marginBottom-p1pxzi rn-marginLeft-11wrixw rn-minHeight-ifefl9 rn-minWidth-bcqeeo rn-paddingTop-m611by rn-paddingRight-1qfoi16 rn-paddingBottom-1mi0q7o rn-paddingLeft-1hfyk0a rn-position-bnwqim rn-zIndex-1lgpqti"
|
||||
>
|
||||
<div
|
||||
class="rn-borderTopWidth-13yce4e rn-borderRightWidth-fnigne rn-borderBottomWidth-ndvcnb rn-borderLeftWidth-gxnn5r rn-boxSizing-deolkf rn-color-1bodaif rn-display-1471scf rn-font-1lw9tu2 rn-fontFamily-10u92zi rn-fontSize-ubezar rn-marginTop-1mnahxq rn-marginRight-61z16t rn-marginBottom-p1pxzi rn-marginLeft-11wrixw rn-paddingTop-wk8lta rn-paddingRight-9aemit rn-paddingBottom-1mdbw0j rn-paddingLeft-gy4na3 rn-verticalAlign-9iso6 rn-textDecoration-bauka4 rn-whiteSpace-q42fyq rn-wordWrap-qvutc0"
|
||||
dir="auto"
|
||||
>
|
||||
Hello World
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`enzyme.render noop 1`] = `
|
||||
<div
|
||||
class="rn-alignItems-1oszu61 rn-borderTopStyle-1efd50x rn-borderRightStyle-14skgim rn-borderBottomStyle-rull8r rn-borderLeftStyle-mm0ijv rn-borderTopWidth-13yce4e rn-borderRightWidth-fnigne rn-borderBottomWidth-ndvcnb rn-borderLeftWidth-gxnn5r rn-boxSizing-deolkf rn-display-6koalj rn-flexShrink-1pxmb3b rn-flexBasis-7vfszb rn-flexDirection-eqz5dr rn-marginTop-1mnahxq rn-marginRight-61z16t rn-marginBottom-p1pxzi rn-marginLeft-11wrixw rn-minHeight-ifefl9 rn-minWidth-bcqeeo rn-paddingTop-wk8lta rn-paddingRight-9aemit rn-paddingBottom-1mdbw0j rn-paddingLeft-gy4na3 rn-position-bnwqim rn-zIndex-1lgpqti"
|
||||
/>
|
||||
`;
|
||||
|
||||
exports[`enzyme.shallow complex 1`] = `
|
||||
<View
|
||||
style={
|
||||
Object {
|
||||
"backgroundColor": "red",
|
||||
"padding": 10,
|
||||
}
|
||||
}
|
||||
>
|
||||
<Title>
|
||||
Hello World
|
||||
</Title>
|
||||
<View>
|
||||
<View
|
||||
style={
|
||||
Object {
|
||||
"padding": 20,
|
||||
}
|
||||
}
|
||||
/>
|
||||
<Text>
|
||||
Nested
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
`;
|
||||
|
||||
exports[`enzyme.shallow composite 1`] = `
|
||||
<View
|
||||
style={
|
||||
Object {
|
||||
"backgroundColor": "red",
|
||||
"padding": 10,
|
||||
}
|
||||
}
|
||||
/>
|
||||
`;
|
||||
|
||||
exports[`enzyme.shallow nested 1`] = `
|
||||
<View
|
||||
style={
|
||||
Object {
|
||||
"backgroundColor": "red",
|
||||
"padding": 10,
|
||||
}
|
||||
}
|
||||
>
|
||||
<Title>
|
||||
Hello World
|
||||
</Title>
|
||||
</View>
|
||||
`;
|
||||
|
||||
exports[`enzyme.shallow noop 1`] = `
|
||||
<div
|
||||
className="rn-alignItems-1oszu61 rn-borderTopStyle-1efd50x rn-borderRightStyle-14skgim rn-borderBottomStyle-rull8r rn-borderLeftStyle-mm0ijv rn-borderTopWidth-13yce4e rn-borderRightWidth-fnigne rn-borderBottomWidth-ndvcnb rn-borderLeftWidth-gxnn5r rn-boxSizing-deolkf rn-display-6koalj rn-flexShrink-1pxmb3b rn-flexBasis-7vfszb rn-flexDirection-eqz5dr rn-marginTop-1mnahxq rn-marginRight-61z16t rn-marginBottom-p1pxzi rn-marginLeft-11wrixw rn-minHeight-ifefl9 rn-minWidth-bcqeeo rn-paddingTop-wk8lta rn-paddingRight-9aemit rn-paddingBottom-1mdbw0j rn-paddingLeft-gy4na3 rn-position-bnwqim rn-zIndex-1lgpqti"
|
||||
/>
|
||||
`;
|
||||
|
||||
exports[`react-test-renderer complex 1`] = `
|
||||
<div
|
||||
className="rn-alignItems-1oszu61 rn-backgroundColor-1mjtqww rn-borderTopStyle-1efd50x rn-borderRightStyle-14skgim rn-borderBottomStyle-rull8r rn-borderLeftStyle-mm0ijv rn-borderTopWidth-13yce4e rn-borderRightWidth-fnigne rn-borderBottomWidth-ndvcnb rn-borderLeftWidth-gxnn5r rn-boxSizing-deolkf rn-display-6koalj rn-flexShrink-1pxmb3b rn-flexBasis-7vfszb rn-flexDirection-eqz5dr rn-marginTop-1mnahxq rn-marginRight-61z16t rn-marginBottom-p1pxzi rn-marginLeft-11wrixw rn-minHeight-ifefl9 rn-minWidth-bcqeeo rn-paddingTop-m611by rn-paddingRight-1qfoi16 rn-paddingBottom-1mi0q7o rn-paddingLeft-1hfyk0a rn-position-bnwqim rn-zIndex-1lgpqti"
|
||||
>
|
||||
<div
|
||||
className="rn-borderTopWidth-13yce4e rn-borderRightWidth-fnigne rn-borderBottomWidth-ndvcnb rn-borderLeftWidth-gxnn5r rn-boxSizing-deolkf rn-color-1bodaif rn-display-1471scf rn-font-1lw9tu2 rn-fontFamily-10u92zi rn-fontSize-ubezar rn-marginTop-1mnahxq rn-marginRight-61z16t rn-marginBottom-p1pxzi rn-marginLeft-11wrixw rn-paddingTop-wk8lta rn-paddingRight-9aemit rn-paddingBottom-1mdbw0j rn-paddingLeft-gy4na3 rn-verticalAlign-9iso6 rn-textDecoration-bauka4 rn-whiteSpace-q42fyq rn-wordWrap-qvutc0"
|
||||
dir="auto"
|
||||
>
|
||||
Hello World
|
||||
</div>
|
||||
<div
|
||||
className="rn-alignItems-1oszu61 rn-borderTopStyle-1efd50x rn-borderRightStyle-14skgim rn-borderBottomStyle-rull8r rn-borderLeftStyle-mm0ijv rn-borderTopWidth-13yce4e rn-borderRightWidth-fnigne rn-borderBottomWidth-ndvcnb rn-borderLeftWidth-gxnn5r rn-boxSizing-deolkf rn-display-6koalj rn-flexShrink-1pxmb3b rn-flexBasis-7vfszb rn-flexDirection-eqz5dr rn-marginTop-1mnahxq rn-marginRight-61z16t rn-marginBottom-p1pxzi rn-marginLeft-11wrixw rn-minHeight-ifefl9 rn-minWidth-bcqeeo rn-paddingTop-wk8lta rn-paddingRight-9aemit rn-paddingBottom-1mdbw0j rn-paddingLeft-gy4na3 rn-position-bnwqim rn-zIndex-1lgpqti"
|
||||
>
|
||||
<div
|
||||
className="rn-alignItems-1oszu61 rn-borderTopStyle-1efd50x rn-borderRightStyle-14skgim rn-borderBottomStyle-rull8r rn-borderLeftStyle-mm0ijv rn-borderTopWidth-13yce4e rn-borderRightWidth-fnigne rn-borderBottomWidth-ndvcnb rn-borderLeftWidth-gxnn5r rn-boxSizing-deolkf rn-display-6koalj rn-flexShrink-1pxmb3b rn-flexBasis-7vfszb rn-flexDirection-eqz5dr rn-marginTop-1mnahxq rn-marginRight-61z16t rn-marginBottom-p1pxzi rn-marginLeft-11wrixw rn-minHeight-ifefl9 rn-minWidth-bcqeeo rn-paddingTop-1knelpx rn-paddingRight-1ah4tor rn-paddingBottom-k8qxaj rn-paddingLeft-b5h31w rn-position-bnwqim rn-zIndex-1lgpqti"
|
||||
/>
|
||||
<div
|
||||
className="rn-borderTopWidth-13yce4e rn-borderRightWidth-fnigne rn-borderBottomWidth-ndvcnb rn-borderLeftWidth-gxnn5r rn-boxSizing-deolkf rn-color-homxoj rn-display-1471scf rn-font-1lw9tu2 rn-fontFamily-10u92zi rn-fontSize-1b43r93 rn-marginTop-1mnahxq rn-marginRight-61z16t rn-marginBottom-p1pxzi rn-marginLeft-11wrixw rn-paddingTop-wk8lta rn-paddingRight-9aemit rn-paddingBottom-1mdbw0j rn-paddingLeft-gy4na3 rn-textDecoration-bauka4 rn-whiteSpace-q42fyq rn-wordWrap-qvutc0"
|
||||
dir="auto"
|
||||
>
|
||||
Nested
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`react-test-renderer composite 1`] = `
|
||||
<div
|
||||
className="rn-alignItems-1oszu61 rn-backgroundColor-1mjtqww rn-borderTopStyle-1efd50x rn-borderRightStyle-14skgim rn-borderBottomStyle-rull8r rn-borderLeftStyle-mm0ijv rn-borderTopWidth-13yce4e rn-borderRightWidth-fnigne rn-borderBottomWidth-ndvcnb rn-borderLeftWidth-gxnn5r rn-boxSizing-deolkf rn-display-6koalj rn-flexShrink-1pxmb3b rn-flexBasis-7vfszb rn-flexDirection-eqz5dr rn-marginTop-1mnahxq rn-marginRight-61z16t rn-marginBottom-p1pxzi rn-marginLeft-11wrixw rn-minHeight-ifefl9 rn-minWidth-bcqeeo rn-paddingTop-m611by rn-paddingRight-1qfoi16 rn-paddingBottom-1mi0q7o rn-paddingLeft-1hfyk0a rn-position-bnwqim rn-zIndex-1lgpqti"
|
||||
/>
|
||||
`;
|
||||
|
||||
exports[`react-test-renderer nested 1`] = `
|
||||
<div
|
||||
className="rn-alignItems-1oszu61 rn-backgroundColor-1mjtqww rn-borderTopStyle-1efd50x rn-borderRightStyle-14skgim rn-borderBottomStyle-rull8r rn-borderLeftStyle-mm0ijv rn-borderTopWidth-13yce4e rn-borderRightWidth-fnigne rn-borderBottomWidth-ndvcnb rn-borderLeftWidth-gxnn5r rn-boxSizing-deolkf rn-display-6koalj rn-flexShrink-1pxmb3b rn-flexBasis-7vfszb rn-flexDirection-eqz5dr rn-marginTop-1mnahxq rn-marginRight-61z16t rn-marginBottom-p1pxzi rn-marginLeft-11wrixw rn-minHeight-ifefl9 rn-minWidth-bcqeeo rn-paddingTop-m611by rn-paddingRight-1qfoi16 rn-paddingBottom-1mi0q7o rn-paddingLeft-1hfyk0a rn-position-bnwqim rn-zIndex-1lgpqti"
|
||||
>
|
||||
<div
|
||||
className="rn-borderTopWidth-13yce4e rn-borderRightWidth-fnigne rn-borderBottomWidth-ndvcnb rn-borderLeftWidth-gxnn5r rn-boxSizing-deolkf rn-color-1bodaif rn-display-1471scf rn-font-1lw9tu2 rn-fontFamily-10u92zi rn-fontSize-ubezar rn-marginTop-1mnahxq rn-marginRight-61z16t rn-marginBottom-p1pxzi rn-marginLeft-11wrixw rn-paddingTop-wk8lta rn-paddingRight-9aemit rn-paddingBottom-1mdbw0j rn-paddingLeft-gy4na3 rn-verticalAlign-9iso6 rn-textDecoration-bauka4 rn-whiteSpace-q42fyq rn-wordWrap-qvutc0"
|
||||
dir="auto"
|
||||
>
|
||||
Hello World
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`react-test-renderer noop 1`] = `
|
||||
<div
|
||||
className="rn-alignItems-1oszu61 rn-borderTopStyle-1efd50x rn-borderRightStyle-14skgim rn-borderBottomStyle-rull8r rn-borderLeftStyle-mm0ijv rn-borderTopWidth-13yce4e rn-borderRightWidth-fnigne rn-borderBottomWidth-ndvcnb rn-borderLeftWidth-gxnn5r rn-boxSizing-deolkf rn-display-6koalj rn-flexShrink-1pxmb3b rn-flexBasis-7vfszb rn-flexDirection-eqz5dr rn-marginTop-1mnahxq rn-marginRight-61z16t rn-marginBottom-p1pxzi rn-marginLeft-11wrixw rn-minHeight-ifefl9 rn-minWidth-bcqeeo rn-paddingTop-wk8lta rn-paddingRight-9aemit rn-paddingBottom-1mdbw0j rn-paddingLeft-gy4na3 rn-position-bnwqim rn-zIndex-1lgpqti"
|
||||
/>
|
||||
`;
|
||||
92
jest/__tests__/serializer-test.js
Normal file
92
jest/__tests__/serializer-test.js
Normal file
@@ -0,0 +1,92 @@
|
||||
/* eslint-env jasmine, jest */
|
||||
/* eslint-disable react/prop-types */
|
||||
|
||||
import { mount, render, shallow } from 'enzyme';
|
||||
import React from 'react';
|
||||
import renderer from 'react-test-renderer';
|
||||
import { StyleSheet, Text, View } from '../../src';
|
||||
import toJson from 'enzyme-to-json';
|
||||
|
||||
/**
|
||||
* Fixtures
|
||||
*/
|
||||
|
||||
const Box = ({ children, element, style, ...rest }) => (
|
||||
<View {...rest} style={[styles.box, style]}>
|
||||
{children}
|
||||
{element}
|
||||
</View>
|
||||
);
|
||||
|
||||
const Title = ({ style, ...rest }) => <Text {...rest} style={[styles.title, style]} />;
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
box: {
|
||||
backgroundColor: 'red',
|
||||
padding: 10
|
||||
},
|
||||
boxExtra: {
|
||||
alignItems: 'center'
|
||||
},
|
||||
title: {
|
||||
color: 'black',
|
||||
fontSize: 16,
|
||||
textAlignVertical: 'center'
|
||||
},
|
||||
element: {
|
||||
padding: 20
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Test cases
|
||||
*/
|
||||
|
||||
const cases = {
|
||||
noop: <View />,
|
||||
composite: <Box />,
|
||||
nested: (
|
||||
<Box>
|
||||
<Title>Hello World</Title>
|
||||
</Box>
|
||||
),
|
||||
complex: (
|
||||
<Box
|
||||
element={
|
||||
<View>
|
||||
<View style={styles.element} />
|
||||
<Text>Nested</Text>
|
||||
</View>
|
||||
}
|
||||
>
|
||||
<Title>Hello World</Title>
|
||||
</Box>
|
||||
)
|
||||
};
|
||||
|
||||
const caseNames = Object.keys(cases);
|
||||
|
||||
describe('enzyme', () => {
|
||||
caseNames.forEach(caseName => {
|
||||
test(caseName, () => {
|
||||
const element = cases[caseName];
|
||||
const mountTree = mount(element);
|
||||
const renderTree = render(element);
|
||||
const shallowTree = shallow(element);
|
||||
|
||||
expect(toJson(mountTree)).toMatchSnapshot(`enzyme.mount ${caseName}`);
|
||||
expect(toJson(renderTree)).toMatchSnapshot(`enzyme.render ${caseName}`);
|
||||
expect(toJson(shallowTree)).toMatchSnapshot(`enzyme.shallow ${caseName}`);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('react-test-renderer', () => {
|
||||
caseNames.forEach(caseName => {
|
||||
test(caseName, () => {
|
||||
const element = cases[caseName];
|
||||
const tree = renderer.create(element).toJSON();
|
||||
expect(tree).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
});
|
||||
56
jest/createSerializer.js
Normal file
56
jest/createSerializer.js
Normal file
@@ -0,0 +1,56 @@
|
||||
const React = require('react');
|
||||
|
||||
function createSerializer(styleSheet) {
|
||||
function flattenNodeStyles(node) {
|
||||
if (node && node.props) {
|
||||
// check for React elements in any props
|
||||
const nextProps = Object.keys(node.props).reduce((acc, curr) => {
|
||||
const value = node.props[curr];
|
||||
if (React.isValidElement(value)) {
|
||||
acc[curr] = flattenNodeStyles(value);
|
||||
}
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
// flatten styles and avoid empty objects in snapshots
|
||||
if (node.props.style) {
|
||||
const style = styleSheet.flatten(node.props.style);
|
||||
if (Object.keys(style).length > 0) {
|
||||
nextProps.style = style;
|
||||
} else {
|
||||
delete nextProps.style;
|
||||
}
|
||||
}
|
||||
|
||||
const args = [node, nextProps];
|
||||
|
||||
// recurse over children too
|
||||
const children = node.children || node.props.children;
|
||||
if (children) {
|
||||
if (Array.isArray(children)) {
|
||||
children.forEach(child => {
|
||||
args.push(flattenNodeStyles(child));
|
||||
});
|
||||
} else {
|
||||
args.push(flattenNodeStyles(children));
|
||||
}
|
||||
}
|
||||
|
||||
return React.cloneElement.apply(React.cloneElement, args);
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
function test(value) {
|
||||
return !!value && value.$$typeof === Symbol.for('react.test.json');
|
||||
}
|
||||
|
||||
function print(value, serializer) {
|
||||
return serializer(flattenNodeStyles(value));
|
||||
}
|
||||
|
||||
return { test, print };
|
||||
}
|
||||
|
||||
module.exports = createSerializer;
|
||||
6
jest/serializer.js
Normal file
6
jest/serializer.js
Normal file
@@ -0,0 +1,6 @@
|
||||
const createSerializer = require('./createSerializer');
|
||||
const { StyleSheet } = require('../dist');
|
||||
|
||||
const serializer = createSerializer(StyleSheet);
|
||||
|
||||
module.exports = serializer;
|
||||
58
package.json
58
package.json
@@ -1,32 +1,32 @@
|
||||
{
|
||||
"name": "react-native-web",
|
||||
"version": "0.1.4",
|
||||
"version": "0.2.2",
|
||||
"description": "React Native for Web",
|
||||
"main": "dist/index.js",
|
||||
"module": "dist/module.js",
|
||||
"files": [
|
||||
"babel",
|
||||
"dist",
|
||||
"jest",
|
||||
"src",
|
||||
"!**/__tests__"
|
||||
],
|
||||
"scripts": {
|
||||
"benchmark": "cd benchmarks && yarn && webpack && open index.html",
|
||||
"build": "yarn compile && webpack --config webpack.config.js --sort-assets-by --progress",
|
||||
"build": "yarn clean-dist && yarn compile && webpack --config webpack.config.js --sort-assets-by --progress",
|
||||
"clean-dist": "del ./dist && mkdir dist",
|
||||
"compile": "babel src -d dist --ignore *-test.js",
|
||||
"docs:build": "cd docs && yarn build",
|
||||
"docs:start": "cd docs && yarn && yarn start",
|
||||
"docs:release": "cd docs && yarn release",
|
||||
"flow": "flow",
|
||||
"fmt": "find babel benchmarks docs src -name '*.js' | grep -v -E '(node_modules|dist)' | xargs yarn fmt:cmd",
|
||||
"fmt": "find babel benchmarks docs jest src -name '*.js' | grep -v -E '(node_modules|dist|vendor)' | xargs yarn fmt:cmd",
|
||||
"fmt:cmd": "prettier --print-width=100 --single-quote --write",
|
||||
"jest": "jest",
|
||||
"jest:watch": "yarn test -- --watch",
|
||||
"lint": "yarn lint:cmd -- babel benchmarks docs src",
|
||||
"lint:cmd": "eslint --ignore-path .gitignore --fix",
|
||||
"jest:watch": "yarn test --watch",
|
||||
"lint": "yarn lint:cmd babel benchmarks docs jest src",
|
||||
"lint:cmd": "eslint --ignore-path .gitignore --ignore-pattern '/src/vendor/*' --fix",
|
||||
"precommit": "lint-staged",
|
||||
"release": "yarn clean-dist && yarn lint && yarn test && yarn build && npm publish",
|
||||
"release": "yarn lint && yarn test && yarn build && npm publish",
|
||||
"test": "flow && jest"
|
||||
},
|
||||
"babel": {
|
||||
@@ -61,48 +61,48 @@
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"animated": "^0.2.0",
|
||||
"array-find-index": "^1.0.2",
|
||||
"babel-runtime": "^6.26.0",
|
||||
"create-react-class": "^15.6.2",
|
||||
"debounce": "1.0.2",
|
||||
"debounce": "^1.1.0",
|
||||
"deep-assign": "^2.0.0",
|
||||
"fbjs": "^0.8.16",
|
||||
"hyphenate-style-name": "^1.0.2",
|
||||
"inline-style-prefixer": "^3.0.8",
|
||||
"normalize-css-color": "^1.0.2",
|
||||
"prop-types": "^15.6.0",
|
||||
"react-art": "^16.2.0",
|
||||
"react-timer-mixin": "^0.13.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel-cli": "^6.26.0",
|
||||
"babel-core": "^6.26.0",
|
||||
"babel-eslint": "^7.2.3",
|
||||
"babel-eslint": "^8.0.3",
|
||||
"babel-loader": "^7.1.2",
|
||||
"babel-plugin-tester": "^4.0.0",
|
||||
"babel-plugin-transform-react-remove-prop-types": "^0.4.9",
|
||||
"babel-plugin-transform-react-remove-prop-types": "^0.4.10",
|
||||
"babel-preset-react-native": "^4.0.0",
|
||||
"caniuse-api": "^2.0.0",
|
||||
"del-cli": "^1.1.0",
|
||||
"enzyme": "^3.0.0",
|
||||
"enzyme-adapter-react-16": "^1.0.0",
|
||||
"enzyme-to-json": "^3.0.1",
|
||||
"eslint": "^4.6.1",
|
||||
"eslint-config-prettier": "^2.6.0",
|
||||
"eslint-plugin-promise": "^3.5.0",
|
||||
"eslint-plugin-react": "^7.4.0",
|
||||
"file-loader": "^1.1.4",
|
||||
"flow-bin": "^0.49.1",
|
||||
"enzyme": "^3.2.0",
|
||||
"enzyme-adapter-react-16": "^1.1.0",
|
||||
"enzyme-to-json": "^3.2.2",
|
||||
"eslint": "^4.12.1",
|
||||
"eslint-config-prettier": "^2.9.0",
|
||||
"eslint-plugin-promise": "^3.6.0",
|
||||
"eslint-plugin-react": "^7.5.1",
|
||||
"file-loader": "^1.1.5",
|
||||
"flow-bin": "^0.60.1",
|
||||
"jest": "^21.2.1",
|
||||
"lint-staged": "^4.1.3",
|
||||
"prettier": "^1.7.3",
|
||||
"raf": "^3.3.2",
|
||||
"react": "^16.0.0",
|
||||
"react-dom": "^16.0.0",
|
||||
"react-test-renderer": "^16.0.0",
|
||||
"url-loader": "^0.5.9",
|
||||
"webpack": "^3.6.0",
|
||||
"webpack-bundle-analyzer": "^2.9.0"
|
||||
"prettier": "^1.8.2",
|
||||
"raf": "^3.4.0",
|
||||
"react": "^16.2.0",
|
||||
"react-dom": "^16.2.0",
|
||||
"react-test-renderer": "^16.2.0",
|
||||
"url-loader": "^0.6.2",
|
||||
"webpack": "^3.9.1",
|
||||
"webpack-bundle-analyzer": "^2.9.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "16.x.x",
|
||||
|
||||
@@ -3,27 +3,25 @@
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
* 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.
|
||||
*
|
||||
* @providesModule Animated
|
||||
* @noflow
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import Animated from 'animated';
|
||||
import AnimatedImplementation from '../../vendor/Animated/AnimatedImplementation';
|
||||
import Image from '../../components/Image';
|
||||
import ScrollView from '../../components/ScrollView';
|
||||
import StyleSheet from '../StyleSheet';
|
||||
import Text from '../../components/Text';
|
||||
import View from '../../components/View';
|
||||
|
||||
Animated.inject.FlattenStyle(StyleSheet.flatten);
|
||||
|
||||
const AnimatedImplementation = {
|
||||
...Animated,
|
||||
Image: Animated.createAnimatedComponent(Image),
|
||||
ScrollView: Animated.createAnimatedComponent(ScrollView),
|
||||
Text: Animated.createAnimatedComponent(Text),
|
||||
View: Animated.createAnimatedComponent(View)
|
||||
const Animated = {
|
||||
...AnimatedImplementation,
|
||||
Image: AnimatedImplementation.createAnimatedComponent(Image),
|
||||
ScrollView: AnimatedImplementation.createAnimatedComponent(ScrollView),
|
||||
View: AnimatedImplementation.createAnimatedComponent(View),
|
||||
Text: AnimatedImplementation.createAnimatedComponent(Text)
|
||||
};
|
||||
|
||||
export default AnimatedImplementation;
|
||||
export default Animated;
|
||||
|
||||
@@ -19,6 +19,7 @@ type Context = {
|
||||
};
|
||||
|
||||
type Props = {
|
||||
// $FlowFixMe
|
||||
children?: React.Children,
|
||||
rootTag: any
|
||||
};
|
||||
@@ -27,9 +28,8 @@ type State = {
|
||||
mainKey: number
|
||||
};
|
||||
|
||||
export default class AppContainer extends Component {
|
||||
props: Props;
|
||||
state: State = { mainKey: 1 };
|
||||
export default class AppContainer extends Component<Props, State> {
|
||||
state = { mainKey: 1 };
|
||||
|
||||
static childContextTypes = {
|
||||
rootTag: any
|
||||
|
||||
@@ -26,46 +26,163 @@ input::-webkit-inner-spin-button,input::-webkit-outer-spin-button,input::-webkit
|
||||
exports[`apis/AppRegistry/renderApplication getApplication 3`] = `
|
||||
"<style id=\\"react-native-stylesheet\\">.rn-bottom-1p0dtai{bottom:0px}
|
||||
.rn-left-1d2f490{left:0px}
|
||||
.rn-left-1fe0xdi{left:0%}
|
||||
.rn-left-7b7h2f{left:100%}
|
||||
.rn-position-u8s1d{position:absolute}
|
||||
.rn-position-bnwqim{position:relative}
|
||||
.rn-right-zchlnj{right:0px}
|
||||
.rn-top-ipm5af{top:0px}
|
||||
.rn-cursor-1loqt21{cursor:pointer}
|
||||
.rn-cursor-7q8q6z{cursor:default}
|
||||
.rn-cursor-1ei5mc7{cursor:inherit}
|
||||
.rn-appearance-30o5oe{-moz-appearance:none;-webkit-appearance:none;appearance:none}
|
||||
.rn-backgroundColor-wib322{background-color:transparent}
|
||||
.rn-backgroundColor-8ndhhv{background-color:rgba(33,150,243,1)}
|
||||
.rn-backgroundColor-15al3ab{background-color:rgba(223,223,223,1)}
|
||||
.rn-backgroundColor-44z8sh{background-color:rgba(255,255,255,1)}
|
||||
.rn-backgroundColor-5itogg{background-color:rgba(0,150,136,1)}
|
||||
.rn-backgroundColor-1v82r4u{background-color:rgba(170,184,194,1)}
|
||||
.rn-backgroundColor-1hj8efq{background-color:rgba(213,213,213,1)}
|
||||
.rn-backgroundColor-1bgzomc{background-color:rgba(189,189,189,1)}
|
||||
.rn-color-homxoj{color:inherit}
|
||||
.rn-color-1qtguxu{color:rgba(255,255,255,1)}
|
||||
.rn-color-istcb5{color:rgba(161,161,161,1)}
|
||||
.rn-font-1lw9tu2{font:inherit}
|
||||
.rn-textAlign-1ttztb7{text-align:inherit}
|
||||
.rn-textAlign-q4m81j{text-align:center}
|
||||
.rn-textDecoration-bauka4{text-decoration:none}
|
||||
.rn-listStyle-1ebb2ja{list-style:none}
|
||||
.rn-alignItems-1oszu61{-ms-flex-align:stretch;-webkit-align-items:stretch;-webkit-box-align:stretch;align-items:stretch}
|
||||
.rn-alignItems-1awozwy{-ms-flex-align:center;-webkit-align-items:center;-webkit-box-align:center;align-items:center}
|
||||
.rn-borderTopStyle-1efd50x{border-top-style:solid}
|
||||
.rn-borderRightStyle-14skgim{border-right-style:solid}
|
||||
.rn-borderBottomStyle-rull8r{border-bottom-style:solid}
|
||||
.rn-borderLeftStyle-mm0ijv{border-left-style:solid}
|
||||
.rn-borderTopWidth-13yce4e{border-top-width:0px}
|
||||
.rn-borderTopWidth-1jxfwug{border-top-width:2px}
|
||||
.rn-borderRightWidth-fnigne{border-right-width:0px}
|
||||
.rn-borderRightWidth-18p6if4{border-right-width:2px}
|
||||
.rn-borderBottomWidth-ndvcnb{border-bottom-width:0px}
|
||||
.rn-borderBottomWidth-wgabs5{border-bottom-width:2px}
|
||||
.rn-borderLeftWidth-gxnn5r{border-left-width:0px}
|
||||
.rn-borderLeftWidth-dwliz8{border-left-width:2px}
|
||||
.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-xoduu5{display:-webkit-inline-box;display:-moz-inline-box;display:-ms-inline-flexbox;display:-webkit-inline-flex;display:inline-flex}
|
||||
.rn-display-1471scf{display:inline}
|
||||
.rn-flexShrink-1pxmb3b{-ms-flex-negative:0 !important;-webkit-flex-shrink:0 !important;flex-shrink:0 !important}
|
||||
.rn-flexShrink-1awmn5t{-ms-flex-negative:1 !important;-webkit-flex-shrink:1 !important;flex-shrink:1 !important}
|
||||
.rn-flexBasis-7vfszb{-ms-flex-preferred-size:auto !important;-webkit-flex-basis:auto !important;flex-basis:auto !important}
|
||||
.rn-flexDirection-eqz5dr{-ms-flex-direction:column;-webkit-box-direction:normal;-webkit-box-orient:vertical;-webkit-flex-direction:column;flex-direction:column}
|
||||
.rn-flexDirection-18u37iz{-ms-flex-direction:row;-webkit-box-direction:normal;-webkit-box-orient:horizontal;-webkit-flex-direction:row;flex-direction:row}
|
||||
.rn-marginTop-1mnahxq{margin-top:0px}
|
||||
.rn-marginTop-1t01tom{margin-top:auto}
|
||||
.rn-marginRight-61z16t{margin-right:0px}
|
||||
.rn-marginRight-lchren{margin-right:auto}
|
||||
.rn-marginBottom-p1pxzi{margin-bottom:0px}
|
||||
.rn-marginBottom-1qahzrx{margin-bottom:auto}
|
||||
.rn-marginLeft-11wrixw{margin-left:0px}
|
||||
.rn-marginLeft-1jj8364{margin-left:auto}
|
||||
.rn-minHeight-ifefl9{min-height:0px}
|
||||
.rn-minWidth-bcqeeo{min-width:0px}
|
||||
.rn-paddingTop-wk8lta{padding-top:0px}
|
||||
.rn-paddingTop-tskmnb{padding-top:8px}
|
||||
.rn-paddingRight-9aemit{padding-right:0px}
|
||||
.rn-paddingRight-1pyaxff{padding-right:8px}
|
||||
.rn-paddingBottom-1mdbw0j{padding-bottom:0px}
|
||||
.rn-paddingBottom-xd6kpl{padding-bottom:8px}
|
||||
.rn-paddingLeft-gy4na3{padding-left:0px}
|
||||
.rn-paddingLeft-1m04atk{padding-left:8px}
|
||||
.rn-zIndex-1lgpqti{z-index:0}
|
||||
.rn-zIndex-1wyyakw{z-index:-1}
|
||||
.rn-backgroundPosition-vvn4in{background-position:center}
|
||||
.rn-backgroundRepeat-u6sd8q{background-repeat:no-repeat}
|
||||
.rn-backgroundRepeat-17leim2{background-repeat:repeat}
|
||||
.rn-backgroundSize-4gszlv{background-size:cover}
|
||||
.rn-backgroundSize-1sxrcry{background-size:auto}
|
||||
.rn-backgroundSize-ehq7j7{background-size:contain}
|
||||
.rn-backgroundSize-x3cy2q{background-size:100% 100%}
|
||||
.rn-height-1pi2tsx{height:100%}
|
||||
.rn-height-z80fyv{height:20px}
|
||||
.rn-height-1r8g8re{height:36px}
|
||||
.rn-height-10ptun7{height:16px}
|
||||
.rn-height-4v7adb{height:5px}
|
||||
.rn-height-1dernwh{height:70%}
|
||||
.rn-opacity-1272l3b{opacity:0}
|
||||
.rn-opacity-6dt33c{opacity:1}
|
||||
.rn-width-13qz1uu{width:100%}
|
||||
.rn-width-19wmn03{width:20px}
|
||||
.rn-width-1acpoxo{width:36px}
|
||||
.rn-width-1janqcz{width:16px}
|
||||
.rn-touchAction-19z077z{-ms-touch-action:none;touch-action:none}
|
||||
.rn-touchAction-1gvxusu{-ms-touch-action:manipulate;touch-action:manipulate}
|
||||
.rn-WebkitOverflowScrolling-150rngu{-webkit-overflow-scrolling:touch}
|
||||
.rn-flex-13awgt0{-ms-flex:1;-webkit-flex:1;flex:1}
|
||||
.rn-flexGrow-1m1wadx{-ms-flex-positive:1 !important;-webkit-flex-grow:1 !important;flex-grow:1 !important}</style>"
|
||||
.rn-flexGrow-1m1wadx{-ms-flex-positive:1 !important;-webkit-flex-grow:1 !important;flex-grow:1 !important}
|
||||
.rn-overflowX-11yh6sk{overflow-x:hidden}
|
||||
.rn-overflowX-lltvgl{overflow-x:auto}
|
||||
.rn-overflowY-1rnoaur{overflow-y:auto}
|
||||
.rn-overflowY-buy8e9{overflow-y:hidden}
|
||||
.rn-transform-emqnss{-webkit-transform:translateZ(0px);transform:translateZ(0px)}
|
||||
.rn-fontFamily-10u92zi{font-family:-apple-system, BlinkMacSystemFont, \\"Segoe UI\\", Roboto, Ubuntu, \\"Helvetica Neue\\", sans-serif}
|
||||
.rn-fontFamily-poiln3{font-family:inherit}
|
||||
.rn-fontSize-1b43r93{font-size:14px}
|
||||
.rn-fontSize-7cikom{font-size:inherit}
|
||||
.rn-whiteSpace-q42fyq{white-space:pre-wrap}
|
||||
.rn-whiteSpace-irrty{white-space:inherit}
|
||||
.rn-whiteSpace-3s2u2q{white-space:nowrap}
|
||||
.rn-wordWrap-qvutc0{word-wrap:break-word}
|
||||
.rn-userSelect-lrvibr{-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none;user-select:none}
|
||||
.rn-maxWidth-dnmrzs{max-width:100%}
|
||||
.rn-textOverflow-1udbk01{text-overflow:ellipsis}
|
||||
.rn-justifyContent-1777fci{-ms-flex-pack:center;-webkit-box-pack:center;-webkit-justify-content:center;justify-content:center}
|
||||
.rn-visibility-11j9u27{visibility:hidden}
|
||||
.rn-animationDuration-17bb2tj{-webkit-animation-duration:0.75s;animation-duration:0.75s}
|
||||
.rn-animationDuration-1ay1djp{-webkit-animation-duration:1s;animation-duration:1s}
|
||||
.rn-animationIterationCount-1muvv40{-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite}
|
||||
.rn-animationName-dozj4v{-webkit-animation-name:rn-ActivityIndicator-animation;animation-name:rn-ActivityIndicator-animation}
|
||||
.rn-animationName-141g9a{-webkit-animation-name:rn-ProgressBar-animation;animation-name:rn-ProgressBar-animation}
|
||||
.rn-animationTimingFunction-1ldzwu0{-webkit-animation-timing-function:linear;animation-timing-function:linear}
|
||||
.rn-animationPlayState-1abnn5w{-webkit-animation-play-state:paused;animation-play-state:paused}
|
||||
.rn-transitionDuration-eafdt9{-webkit-transition-duration:0.15s;transition-duration:0.15s}
|
||||
.rn-transitionDuration-13tjlyg{-webkit-transition-duration:0.1s;transition-duration:0.1s}
|
||||
.rn-transitionProperty-1i6wzkk{-moz-transition-property:opacity;-webkit-transition-property:opacity;transition-property:opacity}
|
||||
.rn-borderTopLeftRadius-1iymjk7{border-top-left-radius:2px}
|
||||
.rn-borderTopLeftRadius-jt3ufn{border-top-left-radius:100%}
|
||||
.rn-borderTopLeftRadius-ou6ah9{border-top-left-radius:0px}
|
||||
.rn-borderTopRightRadius-s2skl2{border-top-right-radius:2px}
|
||||
.rn-borderTopRightRadius-1e868j9{border-top-right-radius:100%}
|
||||
.rn-borderTopRightRadius-t12b5v{border-top-right-radius:0px}
|
||||
.rn-borderBottomRightRadius-l5bh9y{border-bottom-right-radius:2px}
|
||||
.rn-borderBottomRightRadius-ujv9e3{border-bottom-right-radius:100%}
|
||||
.rn-borderBottomRightRadius-zmljjp{border-bottom-right-radius:0px}
|
||||
.rn-borderBottomLeftRadius-101sy47{border-bottom-left-radius:2px}
|
||||
.rn-borderBottomLeftRadius-1hakmuk{border-bottom-left-radius:100%}
|
||||
.rn-borderBottomLeftRadius-pm2fo{border-bottom-left-radius:0px}
|
||||
.rn-fontWeight-majxgm{font-weight:500}
|
||||
.rn-textTransform-tsynxw{text-transform:uppercase}
|
||||
.rn-borderTopColor-j4x2lb{border-top-color:rgba(101,119,134,1)}
|
||||
.rn-borderTopColor-gj2eto{border-top-color:rgba(0,150,136,1)}
|
||||
.rn-borderTopColor-1j7vz2b{border-top-color:rgba(204,214,221,1)}
|
||||
.rn-borderTopColor-2dclza{border-top-color:rgba(170,184,194,1)}
|
||||
.rn-borderTopColor-kqr9px{border-top-color:black}
|
||||
.rn-borderRightColor-12i18q1{border-right-color:rgba(101,119,134,1)}
|
||||
.rn-borderRightColor-31ud7z{border-right-color:rgba(0,150,136,1)}
|
||||
.rn-borderRightColor-10fg1ub{border-right-color:rgba(204,214,221,1)}
|
||||
.rn-borderRightColor-8jf312{border-right-color:rgba(170,184,194,1)}
|
||||
.rn-borderRightColor-q0dj5p{border-right-color:black}
|
||||
.rn-borderBottomColor-mg3rfb{border-bottom-color:rgba(101,119,134,1)}
|
||||
.rn-borderBottomColor-1bgnb8i{border-bottom-color:rgba(0,150,136,1)}
|
||||
.rn-borderBottomColor-zxuuv6{border-bottom-color:rgba(204,214,221,1)}
|
||||
.rn-borderBottomColor-1yeakrt{border-bottom-color:rgba(170,184,194,1)}
|
||||
.rn-borderBottomColor-1ah7hsa{border-bottom-color:black}
|
||||
.rn-borderLeftColor-vnhemr{border-left-color:rgba(101,119,134,1)}
|
||||
.rn-borderLeftColor-tbzcuz{border-left-color:rgba(0,150,136,1)}
|
||||
.rn-borderLeftColor-1p34dw6{border-left-color:rgba(204,214,221,1)}
|
||||
.rn-borderLeftColor-bluj2i{border-left-color:rgba(170,184,194,1)}
|
||||
.rn-borderLeftColor-137uh4u{border-left-color:black}
|
||||
.rn-backgroundImage-rs94m5{background-image:url(\\"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcKICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIgogICB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiCiAgIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgdmVyc2lvbj0iMS4xIgogICB2aWV3Qm94PSIwIDAgMSAxIgogICBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJ4TWluWU1pbiBtZWV0Ij4KICA8cGF0aAogICAgIGQ9Ik0gMC4wNDAzODA1OSwwLjYyNjc3NjcgMC4xNDY0NDY2MSwwLjUyMDcxMDY4IDAuNDI5Mjg5MzIsMC44MDM1NTMzOSAwLjMyMzIyMzMsMC45MDk2MTk0MSB6IE0gMC4yMTcxNTcyOSwwLjgwMzU1MzM5IDAuODUzNTUzMzksMC4xNjcxNTcyOSAwLjk1OTYxOTQxLDAuMjczMjIzMyAwLjMyMzIyMzMsMC45MDk2MTk0MSB6IgogICAgIGlkPSJyZWN0Mzc4MCIKICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO2ZpbGwtb3BhY2l0eToxO3N0cm9rZTpub25lIiAvPgo8L3N2Zz4K\\")}
|
||||
.rn-alignSelf-k200y{-ms-flex-item-align:start;-webkit-align-self:flex-start;align-self:flex-start}
|
||||
.rn-boxShadow-1ewcgjf{box-shadow:0px 1px 3px rgba(0,0,0,0.5)}
|
||||
.rn-resize-1dz5y72{resize:none}</style>"
|
||||
`;
|
||||
|
||||
@@ -11,18 +11,20 @@
|
||||
*/
|
||||
|
||||
import invariant from 'fbjs/lib/invariant';
|
||||
import { unmountComponentAtNode } from 'react-dom';
|
||||
import { unmountComponentAtNode } from '../../modules/unmountComponentAtNode';
|
||||
import renderApplication, { getApplication } from './renderApplication';
|
||||
import type { ComponentType } from 'react';
|
||||
|
||||
const emptyObject = {};
|
||||
const runnables = {};
|
||||
|
||||
export type ComponentProvider = () => ReactClass<any>;
|
||||
export type ComponentProvider = () => ComponentType<any>;
|
||||
|
||||
export type AppConfig = {
|
||||
appKey: string,
|
||||
component?: ComponentProvider,
|
||||
run?: Function
|
||||
run?: Function,
|
||||
section?: boolean
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -90,7 +92,7 @@ export default class AppRegistry {
|
||||
runnables[appKey].run(appParameters);
|
||||
}
|
||||
|
||||
static unmountApplicationComponentAtRootTag(rootTag) {
|
||||
static unmountApplicationComponentAtRootTag(rootTag: Object) {
|
||||
unmountComponentAtNode(rootTag);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,19 +10,19 @@
|
||||
*/
|
||||
|
||||
import invariant from 'fbjs/lib/invariant';
|
||||
import { render } from 'react-dom';
|
||||
import hydrate from '../../modules/hydrate';
|
||||
import AppContainer from './AppContainer';
|
||||
import StyleSheet from '../../apis/StyleSheet';
|
||||
import React from 'react';
|
||||
import React, { type ComponentType } from 'react';
|
||||
|
||||
export default function renderApplication(
|
||||
RootComponent: ReactClass<Object>,
|
||||
initialProps: Object,
|
||||
export default function renderApplication<Props: Object>(
|
||||
RootComponent: ComponentType<Props>,
|
||||
initialProps: Props,
|
||||
rootTag: any
|
||||
) {
|
||||
invariant(rootTag, 'Expect to have a valid rootTag, instead got ', rootTag);
|
||||
|
||||
render(
|
||||
hydrate(
|
||||
<AppContainer rootTag={rootTag}>
|
||||
<RootComponent {...initialProps} />
|
||||
</AppContainer>,
|
||||
@@ -30,7 +30,7 @@ export default function renderApplication(
|
||||
);
|
||||
}
|
||||
|
||||
export function getApplication(RootComponent: ReactClass<Object>, initialProps: Object): Object {
|
||||
export function getApplication(RootComponent: ComponentType<Object>, initialProps: Object): Object {
|
||||
const element = (
|
||||
<AppContainer rootTag={{}}>
|
||||
<RootComponent {...initialProps} />
|
||||
@@ -38,7 +38,7 @@ export function getApplication(RootComponent: ReactClass<Object>, initialProps:
|
||||
);
|
||||
const stylesheets = StyleSheet.getStyleSheets().map(sheet => (
|
||||
// ensure that CSS text is not escaped
|
||||
<style dangerouslySetInnerHTML={{ __html: sheet.textContent }} id={sheet.id} />
|
||||
<style dangerouslySetInnerHTML={{ __html: sheet.textContent }} id={sheet.id} key={sheet.id} />
|
||||
));
|
||||
return { element, stylesheets };
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ const mergeLocalStorageItem = (key, value) => {
|
||||
window.localStorage.setItem(key, nextValue);
|
||||
};
|
||||
|
||||
const createPromise = (getValue, callback) => {
|
||||
const createPromise = (getValue, callback): Promise<*> => {
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
const value = getValue();
|
||||
@@ -37,7 +37,7 @@ const createPromise = (getValue, callback) => {
|
||||
});
|
||||
};
|
||||
|
||||
const createPromiseAll = (promises, callback, processResult) => {
|
||||
const createPromiseAll = (promises, callback, processResult): Promise<*> => {
|
||||
return Promise.all(promises).then(
|
||||
result => {
|
||||
const value = processResult ? processResult(result) : null;
|
||||
@@ -55,16 +55,21 @@ export default class AsyncStorage {
|
||||
/**
|
||||
* Erases *all* AsyncStorage for the domain.
|
||||
*/
|
||||
static clear(callback) {
|
||||
static clear(callback?: Function): Promise<*> {
|
||||
return createPromise(() => {
|
||||
window.localStorage.clear();
|
||||
}, callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* (stub) Flushes any pending requests using a single batch call to get the data.
|
||||
*/
|
||||
static flushGetRequests() {}
|
||||
|
||||
/**
|
||||
* Gets *all* keys known to the app, for all callers, libraries, etc.
|
||||
*/
|
||||
static getAllKeys(callback) {
|
||||
static getAllKeys(callback?: Function): Promise<*> {
|
||||
return createPromise(() => {
|
||||
const numberOfKeys = window.localStorage.length;
|
||||
const keys = [];
|
||||
@@ -79,7 +84,7 @@ export default class AsyncStorage {
|
||||
/**
|
||||
* Fetches `key` value.
|
||||
*/
|
||||
static getItem(key: string, callback) {
|
||||
static getItem(key: string, callback?: Function): Promise<*> {
|
||||
return createPromise(() => {
|
||||
return window.localStorage.getItem(key);
|
||||
}, callback);
|
||||
@@ -91,7 +96,7 @@ export default class AsyncStorage {
|
||||
*
|
||||
* multiGet(['k1', 'k2']) -> [['k1', 'val1'], ['k2', 'val2']]
|
||||
*/
|
||||
static multiGet(keys: Array<string>, callback) {
|
||||
static multiGet(keys: Array<string>, callback?: Function): Promise<*> {
|
||||
const promises = keys.map(key => AsyncStorage.getItem(key));
|
||||
const processResult = result => result.map((value, i) => [keys[i], value]);
|
||||
return createPromiseAll(promises, callback, processResult);
|
||||
@@ -100,7 +105,7 @@ export default class AsyncStorage {
|
||||
/**
|
||||
* Sets `value` for `key`.
|
||||
*/
|
||||
static setItem(key: string, value: string, callback) {
|
||||
static setItem(key: string, value: string, callback?: Function): Promise<*> {
|
||||
return createPromise(() => {
|
||||
window.localStorage.setItem(key, value);
|
||||
}, callback);
|
||||
@@ -110,7 +115,7 @@ export default class AsyncStorage {
|
||||
* Takes an array of key-value array pairs.
|
||||
* multiSet([['k1', 'val1'], ['k2', 'val2']])
|
||||
*/
|
||||
static multiSet(keyValuePairs: Array<Array<string>>, callback) {
|
||||
static multiSet(keyValuePairs: Array<Array<string>>, callback?: Function): Promise<*> {
|
||||
const promises = keyValuePairs.map(item => AsyncStorage.setItem(item[0], item[1]));
|
||||
return createPromiseAll(promises, callback);
|
||||
}
|
||||
@@ -118,7 +123,7 @@ export default class AsyncStorage {
|
||||
/**
|
||||
* Merges existing value with input value, assuming they are stringified JSON.
|
||||
*/
|
||||
static mergeItem(key: string, value: string, callback) {
|
||||
static mergeItem(key: string, value: string, callback?: Function): Promise<*> {
|
||||
return createPromise(() => {
|
||||
mergeLocalStorageItem(key, value);
|
||||
}, callback);
|
||||
@@ -130,7 +135,7 @@ export default class AsyncStorage {
|
||||
*
|
||||
* multiMerge([['k1', 'val1'], ['k2', 'val2']])
|
||||
*/
|
||||
static multiMerge(keyValuePairs: Array<Array<string>>, callback) {
|
||||
static multiMerge(keyValuePairs: Array<Array<string>>, callback?: Function): Promise<*> {
|
||||
const promises = keyValuePairs.map(item => AsyncStorage.mergeItem(item[0], item[1]));
|
||||
return createPromiseAll(promises, callback);
|
||||
}
|
||||
@@ -138,7 +143,7 @@ export default class AsyncStorage {
|
||||
/**
|
||||
* Removes a `key`
|
||||
*/
|
||||
static removeItem(key: string, callback) {
|
||||
static removeItem(key: string, callback?: Function): Promise<*> {
|
||||
return createPromise(() => {
|
||||
return window.localStorage.removeItem(key);
|
||||
}, callback);
|
||||
@@ -147,7 +152,7 @@ export default class AsyncStorage {
|
||||
/**
|
||||
* Delete all the keys in the `keys` array.
|
||||
*/
|
||||
static multiRemove(keys: Array<string>, callback) {
|
||||
static multiRemove(keys: Array<string>, callback?: Function): Promise<*> {
|
||||
const promises = keys.map(key => AsyncStorage.removeItem(key));
|
||||
return createPromiseAll(promises, callback);
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
function emptyFunction() {}
|
||||
|
||||
const BackAndroid = {
|
||||
const BackHandler = {
|
||||
exitApp: emptyFunction,
|
||||
addEventListener() {
|
||||
return {
|
||||
@@ -22,4 +22,4 @@ const BackAndroid = {
|
||||
removeEventListener: emptyFunction
|
||||
};
|
||||
|
||||
export default BackAndroid;
|
||||
export default BackHandler;
|
||||
@@ -17,11 +17,11 @@ export default class Clipboard {
|
||||
);
|
||||
}
|
||||
|
||||
static getString() {
|
||||
static getString(): Promise<string> {
|
||||
return Promise.resolve('');
|
||||
}
|
||||
|
||||
static setString(text) {
|
||||
static setString(text: string) {
|
||||
let success = false;
|
||||
const body = document.body;
|
||||
|
||||
|
||||
@@ -66,12 +66,12 @@ export default class Dimensions {
|
||||
}
|
||||
}
|
||||
|
||||
static addEventListener(type, handler): void {
|
||||
static addEventListener(type: string, handler: Function): void {
|
||||
listeners[type] = listeners[type] || [];
|
||||
listeners[type].push(handler);
|
||||
}
|
||||
|
||||
static removeEventListener(type, handler): void {
|
||||
static removeEventListener(type: string, handler: Function): void {
|
||||
if (Array.isArray(listeners[type])) {
|
||||
listeners[type] = listeners[type].filter(_handler => _handler !== handler);
|
||||
}
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @providesModule Easing
|
||||
* @noflow
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import Easing from 'animated/lib/Easing';
|
||||
import Easing from '../../vendor/Animated/Easing';
|
||||
export default Easing;
|
||||
|
||||
@@ -17,13 +17,13 @@ const initialURL = canUseDOM ? window.location.href : '';
|
||||
const Linking = {
|
||||
addEventListener() {},
|
||||
removeEventListener() {},
|
||||
canOpenURL() {
|
||||
canOpenURL(): Promise<boolean> {
|
||||
return Promise.resolve(true);
|
||||
},
|
||||
getInitialURL() {
|
||||
getInitialURL(): Promise<string> {
|
||||
return Promise.resolve(initialURL);
|
||||
},
|
||||
openURL(url: string) {
|
||||
openURL(url: string): Promise<Object | void> {
|
||||
try {
|
||||
iframeOpen(url);
|
||||
return Promise.resolve();
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
import NetInfo from '..';
|
||||
|
||||
const handler = () => {};
|
||||
|
||||
describe('apis/NetInfo', () => {
|
||||
describe('getConnectionInfo', () => {
|
||||
test('fills out basic fields', done => {
|
||||
@@ -13,9 +15,22 @@ describe('apis/NetInfo', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('isConnected', () => {
|
||||
const handler = () => {};
|
||||
describe('addEventListener', () => {
|
||||
test('throws if the provided "eventType" is not supported', () => {
|
||||
expect(() => NetInfo.addEventListener('foo', handler)).toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
describe('removeEventListener', () => {
|
||||
test('throws if the provided "eventType" is not supported', () => {
|
||||
expect(() => NetInfo.removeEventListener('foo', handler)).toThrow();
|
||||
});
|
||||
test('throws if the handler is not registered', () => {
|
||||
expect(() => NetInfo.removeEventListener('connectionChange', handler)).toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
describe('isConnected', () => {
|
||||
afterEach(() => {
|
||||
try {
|
||||
NetInfo.isConnected.removeEventListener('connectionChange', handler);
|
||||
@@ -25,22 +40,18 @@ describe('apis/NetInfo', () => {
|
||||
describe('addEventListener', () => {
|
||||
test('throws if the provided "eventType" is not supported', () => {
|
||||
expect(() => NetInfo.isConnected.addEventListener('foo', handler)).toThrow();
|
||||
expect(() =>
|
||||
NetInfo.isConnected.addEventListener('connectionChange', handler)
|
||||
).not.toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
describe('removeEventListener', () => {
|
||||
test('throws if the handler is not registered', () => {
|
||||
expect(() => NetInfo.isConnected.removeEventListener('connectionChange', handler)).toThrow;
|
||||
});
|
||||
|
||||
test('throws if the provided "eventType" is not supported', () => {
|
||||
NetInfo.isConnected.addEventListener('connectionChange', handler);
|
||||
expect(() => NetInfo.isConnected.removeEventListener('foo', handler)).toThrow;
|
||||
expect(() => NetInfo.isConnected.removeEventListener('connectionChange', handler)).not
|
||||
.toThrow;
|
||||
expect(() => NetInfo.isConnected.removeEventListener('foo', handler)).toThrow();
|
||||
});
|
||||
test('throws if the handler is not registered', () => {
|
||||
expect(() =>
|
||||
NetInfo.isConnected.removeEventListener('connectionChange', handler)
|
||||
).toThrow();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -23,13 +23,17 @@ const connection =
|
||||
// Prevent the underlying event handlers from leaking and include additional
|
||||
// properties available in browsers
|
||||
const getConnectionInfoObject = () => {
|
||||
const result = {};
|
||||
const result = {
|
||||
effectiveType: 'unknown',
|
||||
type: 'unknown'
|
||||
};
|
||||
if (!connection) {
|
||||
return result;
|
||||
}
|
||||
for (const prop in connection) {
|
||||
if (typeof connection[prop] !== 'function') {
|
||||
result[prop] = connection[prop];
|
||||
const value = connection[prop];
|
||||
if (typeof value !== 'function' && value != null) {
|
||||
result[prop] = value;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
@@ -43,6 +47,7 @@ const eventTypesMap = {
|
||||
const eventTypes = Object.keys(eventTypesMap);
|
||||
|
||||
const connectionListeners = [];
|
||||
const netInfoListeners = [];
|
||||
|
||||
/**
|
||||
* Navigator online: https://developer.mozilla.org/en-US/docs/Web/API/NavigatorOnLine/onLine
|
||||
@@ -63,21 +68,29 @@ const NetInfo = {
|
||||
};
|
||||
}
|
||||
|
||||
connection.addEventListener(eventTypesMap[type], handler);
|
||||
const wrappedHandler = () => handler(getConnectionInfoObject());
|
||||
netInfoListeners.push([handler, wrappedHandler]);
|
||||
connection.addEventListener(eventTypesMap[type], wrappedHandler);
|
||||
return {
|
||||
remove: () => NetInfo.removeEventListener(eventTypesMap[type], handler)
|
||||
};
|
||||
},
|
||||
|
||||
removeEventListener(type: string, handler: Function): void {
|
||||
invariant(eventTypes.indexOf(type) !== -1, 'Trying to subscribe to unknown event: "%s"', type);
|
||||
invariant(
|
||||
eventTypes.indexOf(type) !== -1,
|
||||
'Trying to unsubscribe from unknown event: "%s"',
|
||||
type
|
||||
);
|
||||
if (type === 'change') {
|
||||
console.warn('Listening to event `change` is deprecated. Use `connectionChange` instead.');
|
||||
}
|
||||
if (!connection) {
|
||||
return;
|
||||
}
|
||||
connection.removeEventListener(eventTypesMap[type], handler);
|
||||
|
||||
const listenerIndex = findIndex(netInfoListeners, pair => pair[0] === handler);
|
||||
invariant(listenerIndex !== -1, 'Trying to remove NetInfo listener for unregistered handler');
|
||||
const [, wrappedHandler] = netInfoListeners[listenerIndex];
|
||||
connection.removeEventListener(eventTypesMap[type], wrappedHandler);
|
||||
netInfoListeners.splice(listenerIndex, 1);
|
||||
},
|
||||
|
||||
fetch(): Promise<any> {
|
||||
@@ -93,11 +106,7 @@ const NetInfo = {
|
||||
|
||||
getConnectionInfo(): Promise<Object> {
|
||||
return new Promise((resolve, reject) => {
|
||||
resolve({
|
||||
effectiveType: 'unknown',
|
||||
type: 'unknown',
|
||||
...getConnectionInfoObject()
|
||||
});
|
||||
resolve(getConnectionInfoObject());
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
@@ -1,394 +1,2 @@
|
||||
/**
|
||||
* Copyright (c) 2016-present, Nicolas Gallagher.
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @providesModule PanResponder
|
||||
* @noflow
|
||||
*/
|
||||
|
||||
import TouchHistoryMath from '../../vendor/TouchHistoryMath';
|
||||
|
||||
const currentCentroidXOfTouchesChangedAfter =
|
||||
TouchHistoryMath.currentCentroidXOfTouchesChangedAfter;
|
||||
const currentCentroidYOfTouchesChangedAfter =
|
||||
TouchHistoryMath.currentCentroidYOfTouchesChangedAfter;
|
||||
const previousCentroidXOfTouchesChangedAfter =
|
||||
TouchHistoryMath.previousCentroidXOfTouchesChangedAfter;
|
||||
const previousCentroidYOfTouchesChangedAfter =
|
||||
TouchHistoryMath.previousCentroidYOfTouchesChangedAfter;
|
||||
const currentCentroidX = TouchHistoryMath.currentCentroidX;
|
||||
const currentCentroidY = TouchHistoryMath.currentCentroidY;
|
||||
|
||||
/**
|
||||
* `PanResponder` reconciles several touches into a single gesture. It makes
|
||||
* single-touch gestures resilient to extra touches, and can be used to
|
||||
* recognize simple multi-touch gestures.
|
||||
*
|
||||
* It provides a predictable wrapper of the responder handlers provided by the
|
||||
* [gesture responder system](docs/gesture-responder-system.html).
|
||||
* For each handler, it provides a new `gestureState` object alongside the
|
||||
* native event object:
|
||||
*
|
||||
* ```
|
||||
* onPanResponderMove: (event, gestureState) => {}
|
||||
* ```
|
||||
*
|
||||
* A native event is a synthetic touch event with the following form:
|
||||
*
|
||||
* - `nativeEvent`
|
||||
* + `changedTouches` - Array of all touch events that have changed since the last event
|
||||
* + `identifier` - The ID of the touch
|
||||
* + `locationX` - The X position of the touch, relative to the element
|
||||
* + `locationY` - The Y position of the touch, relative to the element
|
||||
* + `pageX` - The X position of the touch, relative to the root element
|
||||
* + `pageY` - The Y position of the touch, relative to the root element
|
||||
* + `target` - The node id of the element receiving the touch event
|
||||
* + `timestamp` - A time identifier for the touch, useful for velocity calculation
|
||||
* + `touches` - Array of all current touches on the screen
|
||||
*
|
||||
* A `gestureState` object has the following:
|
||||
*
|
||||
* - `stateID` - ID of the gestureState- persisted as long as there at least
|
||||
* one touch on screen
|
||||
* - `moveX` - the latest screen coordinates of the recently-moved touch
|
||||
* - `moveY` - the latest screen coordinates of the recently-moved touch
|
||||
* - `x0` - the screen coordinates of the responder grant
|
||||
* - `y0` - the screen coordinates of the responder grant
|
||||
* - `dx` - accumulated distance of the gesture since the touch started
|
||||
* - `dy` - accumulated distance of the gesture since the touch started
|
||||
* - `vx` - current velocity of the gesture
|
||||
* - `vy` - current velocity of the gesture
|
||||
* - `numberActiveTouches` - Number of touches currently on screen
|
||||
*
|
||||
* ### Basic Usage
|
||||
*
|
||||
* ```
|
||||
* componentWillMount: function() {
|
||||
* this._panResponder = PanResponder.create({
|
||||
* // Ask to be the responder:
|
||||
* onStartShouldSetPanResponder: (evt, gestureState) => true,
|
||||
* onStartShouldSetPanResponderCapture: (evt, gestureState) => true,
|
||||
* onMoveShouldSetPanResponder: (evt, gestureState) => true,
|
||||
* onMoveShouldSetPanResponderCapture: (evt, gestureState) => true,
|
||||
*
|
||||
* onPanResponderGrant: (evt, gestureState) => {
|
||||
* // The guesture has started. Show visual feedback so the user knows
|
||||
* // what is happening!
|
||||
*
|
||||
* // gestureState.{x,y}0 will be set to zero now
|
||||
* },
|
||||
* onPanResponderMove: (evt, gestureState) => {
|
||||
* // The most recent move distance is gestureState.move{X,Y}
|
||||
*
|
||||
* // The accumulated gesture distance since becoming responder is
|
||||
* // gestureState.d{x,y}
|
||||
* },
|
||||
* onPanResponderTerminationRequest: (evt, gestureState) => true,
|
||||
* onPanResponderRelease: (evt, gestureState) => {
|
||||
* // The user has released all touches while this view is the
|
||||
* // responder. This typically means a gesture has succeeded
|
||||
* },
|
||||
* onPanResponderTerminate: (evt, gestureState) => {
|
||||
* // Another component has become the responder, so this gesture
|
||||
* // should be cancelled
|
||||
* },
|
||||
* onShouldBlockNativeResponder: (evt, gestureState) => {
|
||||
* // Returns whether this component should block native components from becoming the JS
|
||||
* // responder. Returns true by default. Is currently only supported on android.
|
||||
* return true;
|
||||
* },
|
||||
* });
|
||||
* },
|
||||
*
|
||||
* render: function() {
|
||||
* return (
|
||||
* <View {...this._panResponder.panHandlers} />
|
||||
* );
|
||||
* },
|
||||
*
|
||||
* ```
|
||||
*
|
||||
* ### Working Example
|
||||
*
|
||||
* To see it in action, try the
|
||||
* [PanResponder example in UIExplorer](https://github.com/facebook/react-native/blob/master/Examples/UIExplorer/PanResponderExample.js)
|
||||
*/
|
||||
|
||||
const PanResponder = {
|
||||
/**
|
||||
*
|
||||
* A graphical explanation of the touch data flow:
|
||||
*
|
||||
* +----------------------------+ +--------------------------------+
|
||||
* | ResponderTouchHistoryStore | |TouchHistoryMath |
|
||||
* +----------------------------+ +----------+---------------------+
|
||||
* |Global store of touchHistory| |Allocation-less math util |
|
||||
* |including activeness, start | |on touch history (centroids |
|
||||
* |position, prev/cur position.| |and multitouch movement etc) |
|
||||
* | | | |
|
||||
* +----^-----------------------+ +----^---------------------------+
|
||||
* | |
|
||||
* | (records relevant history |
|
||||
* | of touches relevant for |
|
||||
* | implementing higher level |
|
||||
* | gestures) |
|
||||
* | |
|
||||
* +----+-----------------------+ +----|---------------------------+
|
||||
* | ResponderEventPlugin | | | Your App/Component |
|
||||
* +----------------------------+ +----|---------------------------+
|
||||
* |Negotiates which view gets | Low level | | High level |
|
||||
* |onResponderMove events. | events w/ | +-+-------+ events w/ |
|
||||
* |Also records history into | touchHistory| | Pan | multitouch + |
|
||||
* |ResponderTouchHistoryStore. +---------------->Responder+-----> accumulative|
|
||||
* +----------------------------+ attached to | | | distance and |
|
||||
* each event | +---------+ velocity. |
|
||||
* | |
|
||||
* | |
|
||||
* +--------------------------------+
|
||||
*
|
||||
*
|
||||
*
|
||||
* Gesture that calculates cumulative movement over time in a way that just
|
||||
* "does the right thing" for multiple touches. The "right thing" is very
|
||||
* nuanced. When moving two touches in opposite directions, the cumulative
|
||||
* distance is zero in each dimension. When two touches move in parallel five
|
||||
* pixels in the same direction, the cumulative distance is five, not ten. If
|
||||
* two touches start, one moves five in a direction, then stops and the other
|
||||
* touch moves fives in the same direction, the cumulative distance is ten.
|
||||
*
|
||||
* This logic requires a kind of processing of time "clusters" of touch events
|
||||
* so that two touch moves that essentially occur in parallel but move every
|
||||
* other frame respectively, are considered part of the same movement.
|
||||
*
|
||||
* Explanation of some of the non-obvious fields:
|
||||
*
|
||||
* - moveX/moveY: If no move event has been observed, then `(moveX, moveY)` is
|
||||
* invalid. If a move event has been observed, `(moveX, moveY)` is the
|
||||
* centroid of the most recently moved "cluster" of active touches.
|
||||
* (Currently all move have the same timeStamp, but later we should add some
|
||||
* threshold for what is considered to be "moving"). If a palm is
|
||||
* accidentally counted as a touch, but a finger is moving greatly, the palm
|
||||
* will move slightly, but we only want to count the single moving touch.
|
||||
* - x0/y0: Centroid location (non-cumulative) at the time of becoming
|
||||
* responder.
|
||||
* - dx/dy: Cumulative touch distance - not the same thing as sum of each touch
|
||||
* distance. Accounts for touch moves that are clustered together in time,
|
||||
* moving the same direction. Only valid when currently responder (otherwise,
|
||||
* it only represents the drag distance below the threshold).
|
||||
* - vx/vy: Velocity.
|
||||
*/
|
||||
|
||||
_initializeGestureState: function(gestureState) {
|
||||
gestureState.moveX = 0;
|
||||
gestureState.moveY = 0;
|
||||
gestureState.x0 = 0;
|
||||
gestureState.y0 = 0;
|
||||
gestureState.dx = 0;
|
||||
gestureState.dy = 0;
|
||||
gestureState.vx = 0;
|
||||
gestureState.vy = 0;
|
||||
gestureState.numberActiveTouches = 0;
|
||||
// All `gestureState` accounts for timeStamps up until:
|
||||
gestureState._accountsForMovesUpTo = 0;
|
||||
},
|
||||
|
||||
/**
|
||||
* This is nuanced and is necessary. It is incorrect to continuously take all
|
||||
* active *and* recently moved touches, find the centroid, and track how that
|
||||
* result changes over time. Instead, we must take all recently moved
|
||||
* touches, and calculate how the centroid has changed just for those
|
||||
* recently moved touches, and append that change to an accumulator. This is
|
||||
* to (at least) handle the case where the user is moving three fingers, and
|
||||
* then one of the fingers stops but the other two continue.
|
||||
*
|
||||
* This is very different than taking all of the recently moved touches and
|
||||
* storing their centroid as `dx/dy`. For correctness, we must *accumulate
|
||||
* changes* in the centroid of recently moved touches.
|
||||
*
|
||||
* There is also some nuance with how we handle multiple moved touches in a
|
||||
* single event. With the way `ReactNativeEventEmitter` dispatches touches as
|
||||
* individual events, multiple touches generate two 'move' events, each of
|
||||
* them triggering `onResponderMove`. But with the way `PanResponder` works,
|
||||
* all of the gesture inference is performed on the first dispatch, since it
|
||||
* looks at all of the touches (even the ones for which there hasn't been a
|
||||
* native dispatch yet). Therefore, `PanResponder` does not call
|
||||
* `onResponderMove` passed the first dispatch. This diverges from the
|
||||
* typical responder callback pattern (without using `PanResponder`), but
|
||||
* avoids more dispatches than necessary.
|
||||
*/
|
||||
_updateGestureStateOnMove: function(gestureState, touchHistory) {
|
||||
gestureState.numberActiveTouches = touchHistory.numberActiveTouches;
|
||||
gestureState.moveX = currentCentroidXOfTouchesChangedAfter(
|
||||
touchHistory,
|
||||
gestureState._accountsForMovesUpTo
|
||||
);
|
||||
gestureState.moveY = currentCentroidYOfTouchesChangedAfter(
|
||||
touchHistory,
|
||||
gestureState._accountsForMovesUpTo
|
||||
);
|
||||
const movedAfter = gestureState._accountsForMovesUpTo;
|
||||
const prevX = previousCentroidXOfTouchesChangedAfter(touchHistory, movedAfter);
|
||||
const x = currentCentroidXOfTouchesChangedAfter(touchHistory, movedAfter);
|
||||
const prevY = previousCentroidYOfTouchesChangedAfter(touchHistory, movedAfter);
|
||||
const y = currentCentroidYOfTouchesChangedAfter(touchHistory, movedAfter);
|
||||
const nextDX = gestureState.dx + (x - prevX);
|
||||
const nextDY = gestureState.dy + (y - prevY);
|
||||
|
||||
// TODO: This must be filtered intelligently.
|
||||
const dt = touchHistory.mostRecentTimeStamp - gestureState._accountsForMovesUpTo;
|
||||
gestureState.vx = (nextDX - gestureState.dx) / dt;
|
||||
gestureState.vy = (nextDY - gestureState.dy) / dt;
|
||||
|
||||
gestureState.dx = nextDX;
|
||||
gestureState.dy = nextDY;
|
||||
gestureState._accountsForMovesUpTo = touchHistory.mostRecentTimeStamp;
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {object} config Enhanced versions of all of the responder callbacks
|
||||
* that provide not only the typical `ResponderSyntheticEvent`, but also the
|
||||
* `PanResponder` gesture state. Simply replace the word `Responder` with
|
||||
* `PanResponder` in each of the typical `onResponder*` callbacks. For
|
||||
* example, the `config` object would look like:
|
||||
*
|
||||
* - `onMoveShouldSetPanResponder: (e, gestureState) => {...}`
|
||||
* - `onMoveShouldSetPanResponderCapture: (e, gestureState) => {...}`
|
||||
* - `onStartShouldSetPanResponder: (e, gestureState) => {...}`
|
||||
* - `onStartShouldSetPanResponderCapture: (e, gestureState) => {...}`
|
||||
* - `onPanResponderReject: (e, gestureState) => {...}`
|
||||
* - `onPanResponderGrant: (e, gestureState) => {...}`
|
||||
* - `onPanResponderStart: (e, gestureState) => {...}`
|
||||
* - `onPanResponderEnd: (e, gestureState) => {...}`
|
||||
* - `onPanResponderRelease: (e, gestureState) => {...}`
|
||||
* - `onPanResponderMove: (e, gestureState) => {...}`
|
||||
* - `onPanResponderTerminate: (e, gestureState) => {...}`
|
||||
* - `onPanResponderTerminationRequest: (e, gestureState) => {...}`
|
||||
* - `onShouldBlockNativeResponder: (e, gestureState) => {...}`
|
||||
*
|
||||
* In general, for events that have capture equivalents, we update the
|
||||
* gestureState once in the capture phase and can use it in the bubble phase
|
||||
* as well.
|
||||
*
|
||||
* Be careful with onStartShould* callbacks. They only reflect updated
|
||||
* `gestureState` for start/end events that bubble/capture to the Node.
|
||||
* Once the node is the responder, you can rely on every start/end event
|
||||
* being processed by the gesture and `gestureState` being updated
|
||||
* accordingly. (numberActiveTouches) may not be totally accurate unless you
|
||||
* are the responder.
|
||||
*/
|
||||
create: function(config) {
|
||||
const gestureState = {
|
||||
// Useful for debugging
|
||||
stateID: Math.random()
|
||||
};
|
||||
PanResponder._initializeGestureState(gestureState);
|
||||
const panHandlers = {
|
||||
onStartShouldSetResponder: function(e) {
|
||||
return config.onStartShouldSetPanResponder === undefined
|
||||
? false
|
||||
: config.onStartShouldSetPanResponder(e, gestureState);
|
||||
},
|
||||
onMoveShouldSetResponder: function(e) {
|
||||
return config.onMoveShouldSetPanResponder === undefined
|
||||
? false
|
||||
: config.onMoveShouldSetPanResponder(e, gestureState);
|
||||
},
|
||||
onStartShouldSetResponderCapture: function(e) {
|
||||
// TODO: Actually, we should reinitialize the state any time
|
||||
// touches.length increases from 0 active to > 0 active.
|
||||
if (e.nativeEvent.touches) {
|
||||
if (e.nativeEvent.touches.length === 1) {
|
||||
PanResponder._initializeGestureState(gestureState);
|
||||
}
|
||||
} else if (
|
||||
e.nativeEvent.originalEvent &&
|
||||
e.nativeEvent.originalEvent.type === 'mousedown'
|
||||
) {
|
||||
PanResponder._initializeGestureState(gestureState);
|
||||
}
|
||||
gestureState.numberActiveTouches = e.touchHistory.numberActiveTouches;
|
||||
return config.onStartShouldSetPanResponderCapture !== undefined
|
||||
? config.onStartShouldSetPanResponderCapture(e, gestureState)
|
||||
: false;
|
||||
},
|
||||
|
||||
onMoveShouldSetResponderCapture: function(e) {
|
||||
const touchHistory = e.touchHistory;
|
||||
// Responder system incorrectly dispatches should* to current responder
|
||||
// Filter out any touch moves past the first one - we would have
|
||||
// already processed multi-touch geometry during the first event.
|
||||
if (gestureState._accountsForMovesUpTo === touchHistory.mostRecentTimeStamp) {
|
||||
return false;
|
||||
}
|
||||
PanResponder._updateGestureStateOnMove(gestureState, touchHistory);
|
||||
return config.onMoveShouldSetPanResponderCapture
|
||||
? config.onMoveShouldSetPanResponderCapture(e, gestureState)
|
||||
: false;
|
||||
},
|
||||
|
||||
onResponderGrant: function(e) {
|
||||
gestureState.x0 = currentCentroidX(e.touchHistory);
|
||||
gestureState.y0 = currentCentroidY(e.touchHistory);
|
||||
gestureState.dx = 0;
|
||||
gestureState.dy = 0;
|
||||
config.onPanResponderGrant && config.onPanResponderGrant(e, gestureState);
|
||||
// TODO: t7467124 investigate if this can be removed
|
||||
return config.onShouldBlockNativeResponder === undefined
|
||||
? true
|
||||
: config.onShouldBlockNativeResponder();
|
||||
},
|
||||
|
||||
onResponderReject: function(e) {
|
||||
config.onPanResponderReject && config.onPanResponderReject(e, gestureState);
|
||||
},
|
||||
|
||||
onResponderRelease: function(e) {
|
||||
config.onPanResponderRelease && config.onPanResponderRelease(e, gestureState);
|
||||
PanResponder._initializeGestureState(gestureState);
|
||||
},
|
||||
|
||||
onResponderStart: function(e) {
|
||||
const touchHistory = e.touchHistory;
|
||||
gestureState.numberActiveTouches = touchHistory.numberActiveTouches;
|
||||
config.onPanResponderStart && config.onPanResponderStart(e, gestureState);
|
||||
},
|
||||
|
||||
onResponderMove: function(e) {
|
||||
const touchHistory = e.touchHistory;
|
||||
// Guard against the dispatch of two touch moves when there are two
|
||||
// simultaneously changed touches.
|
||||
if (gestureState._accountsForMovesUpTo === touchHistory.mostRecentTimeStamp) {
|
||||
return;
|
||||
}
|
||||
// Filter out any touch moves past the first one - we would have
|
||||
// already processed multi-touch geometry during the first event.
|
||||
PanResponder._updateGestureStateOnMove(gestureState, touchHistory);
|
||||
config.onPanResponderMove && config.onPanResponderMove(e, gestureState);
|
||||
},
|
||||
|
||||
onResponderEnd: function(e) {
|
||||
const touchHistory = e.touchHistory;
|
||||
gestureState.numberActiveTouches = touchHistory.numberActiveTouches;
|
||||
config.onPanResponderEnd && config.onPanResponderEnd(e, gestureState);
|
||||
},
|
||||
|
||||
onResponderTerminate: function(e) {
|
||||
config.onPanResponderTerminate && config.onPanResponderTerminate(e, gestureState);
|
||||
PanResponder._initializeGestureState(gestureState);
|
||||
},
|
||||
|
||||
onResponderTerminationRequest: function(e) {
|
||||
return config.onPanResponderTerminationRequest === undefined
|
||||
? true
|
||||
: config.onPanResponderTerminationRequest(e, gestureState);
|
||||
}
|
||||
};
|
||||
return { panHandlers: panHandlers };
|
||||
}
|
||||
};
|
||||
|
||||
import PanResponder from '../../vendor/PanResponder';
|
||||
export default PanResponder;
|
||||
|
||||
@@ -182,7 +182,7 @@ export default class StyleRegistry {
|
||||
}
|
||||
|
||||
/**
|
||||
* Caching layer over 'resolveStyle'
|
||||
* Caching layer over 'resolveStyle'
|
||||
*/
|
||||
_resolveStyleIfNeeded(style, options, key) {
|
||||
const dir = I18nManager.isRTL ? 'rtl' : 'ltr';
|
||||
|
||||
@@ -24,7 +24,7 @@ import { number, oneOf, string } from 'prop-types';
|
||||
const ReactPropTypesSecret = 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED';
|
||||
|
||||
export default class StyleSheetValidation {
|
||||
static validateStyleProp(prop, style, caller) {
|
||||
static validateStyleProp(prop: string, style: Object, caller: string) {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
const isCustomProperty = prop.indexOf('--') === 0;
|
||||
if (isCustomProperty) return;
|
||||
@@ -51,7 +51,7 @@ export default class StyleSheetValidation {
|
||||
}
|
||||
}
|
||||
|
||||
static validateStyle(name, styles) {
|
||||
static validateStyle(name: string, styles: Object) {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
for (const prop in styles[name]) {
|
||||
StyleSheetValidation.validateStyleProp(prop, styles[name], 'StyleSheet ' + name);
|
||||
@@ -59,7 +59,7 @@ export default class StyleSheetValidation {
|
||||
}
|
||||
}
|
||||
|
||||
static addValidStylePropTypes(stylePropTypes) {
|
||||
static addValidStylePropTypes(stylePropTypes: Object) {
|
||||
for (const key in stylePropTypes) {
|
||||
allStylePropTypes[key] = stylePropTypes[key];
|
||||
}
|
||||
@@ -91,6 +91,7 @@ StyleSheetValidation.addValidStylePropTypes({
|
||||
borderSpacing: oneOf([number, string]),
|
||||
clear: string,
|
||||
cursor: string,
|
||||
fill: string,
|
||||
float: oneOf(['left', 'none', 'right']),
|
||||
font: string /* @private */,
|
||||
listStyle: string,
|
||||
|
||||
@@ -21,9 +21,165 @@ input::-webkit-inner-spin-button,input::-webkit-outer-spin-button,input::-webkit
|
||||
"id": "react-native-stylesheet",
|
||||
"textContent": ".rn-bottom-1p0dtai{bottom:0px}
|
||||
.rn-left-1d2f490{left:0px}
|
||||
.rn-left-1fe0xdi{left:0%}
|
||||
.rn-left-7b7h2f{left:100%}
|
||||
.rn-position-u8s1d{position:absolute}
|
||||
.rn-position-bnwqim{position:relative}
|
||||
.rn-right-zchlnj{right:0px}
|
||||
.rn-top-ipm5af{top:0px}",
|
||||
.rn-top-ipm5af{top:0px}
|
||||
.rn-cursor-1loqt21{cursor:pointer}
|
||||
.rn-cursor-7q8q6z{cursor:default}
|
||||
.rn-cursor-1ei5mc7{cursor:inherit}
|
||||
.rn-appearance-30o5oe{-moz-appearance:none;-webkit-appearance:none;appearance:none}
|
||||
.rn-backgroundColor-wib322{background-color:transparent}
|
||||
.rn-backgroundColor-8ndhhv{background-color:rgba(33,150,243,1)}
|
||||
.rn-backgroundColor-15al3ab{background-color:rgba(223,223,223,1)}
|
||||
.rn-backgroundColor-44z8sh{background-color:rgba(255,255,255,1)}
|
||||
.rn-backgroundColor-5itogg{background-color:rgba(0,150,136,1)}
|
||||
.rn-backgroundColor-1v82r4u{background-color:rgba(170,184,194,1)}
|
||||
.rn-backgroundColor-1hj8efq{background-color:rgba(213,213,213,1)}
|
||||
.rn-backgroundColor-1bgzomc{background-color:rgba(189,189,189,1)}
|
||||
.rn-color-homxoj{color:inherit}
|
||||
.rn-color-1qtguxu{color:rgba(255,255,255,1)}
|
||||
.rn-color-istcb5{color:rgba(161,161,161,1)}
|
||||
.rn-font-1lw9tu2{font:inherit}
|
||||
.rn-textAlign-1ttztb7{text-align:inherit}
|
||||
.rn-textAlign-q4m81j{text-align:center}
|
||||
.rn-textDecoration-bauka4{text-decoration:none}
|
||||
.rn-listStyle-1ebb2ja{list-style:none}
|
||||
.rn-alignItems-1oszu61{-ms-flex-align:stretch;-webkit-align-items:stretch;-webkit-box-align:stretch;align-items:stretch}
|
||||
.rn-alignItems-1awozwy{-ms-flex-align:center;-webkit-align-items:center;-webkit-box-align:center;align-items:center}
|
||||
.rn-borderTopStyle-1efd50x{border-top-style:solid}
|
||||
.rn-borderRightStyle-14skgim{border-right-style:solid}
|
||||
.rn-borderBottomStyle-rull8r{border-bottom-style:solid}
|
||||
.rn-borderLeftStyle-mm0ijv{border-left-style:solid}
|
||||
.rn-borderTopWidth-13yce4e{border-top-width:0px}
|
||||
.rn-borderTopWidth-1jxfwug{border-top-width:2px}
|
||||
.rn-borderRightWidth-fnigne{border-right-width:0px}
|
||||
.rn-borderRightWidth-18p6if4{border-right-width:2px}
|
||||
.rn-borderBottomWidth-ndvcnb{border-bottom-width:0px}
|
||||
.rn-borderBottomWidth-wgabs5{border-bottom-width:2px}
|
||||
.rn-borderLeftWidth-gxnn5r{border-left-width:0px}
|
||||
.rn-borderLeftWidth-dwliz8{border-left-width:2px}
|
||||
.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-xoduu5{display:-webkit-inline-box;display:-moz-inline-box;display:-ms-inline-flexbox;display:-webkit-inline-flex;display:inline-flex}
|
||||
.rn-display-1471scf{display:inline}
|
||||
.rn-flexShrink-1pxmb3b{-ms-flex-negative:0 !important;-webkit-flex-shrink:0 !important;flex-shrink:0 !important}
|
||||
.rn-flexShrink-1awmn5t{-ms-flex-negative:1 !important;-webkit-flex-shrink:1 !important;flex-shrink:1 !important}
|
||||
.rn-flexBasis-7vfszb{-ms-flex-preferred-size:auto !important;-webkit-flex-basis:auto !important;flex-basis:auto !important}
|
||||
.rn-flexDirection-eqz5dr{-ms-flex-direction:column;-webkit-box-direction:normal;-webkit-box-orient:vertical;-webkit-flex-direction:column;flex-direction:column}
|
||||
.rn-flexDirection-18u37iz{-ms-flex-direction:row;-webkit-box-direction:normal;-webkit-box-orient:horizontal;-webkit-flex-direction:row;flex-direction:row}
|
||||
.rn-marginTop-1mnahxq{margin-top:0px}
|
||||
.rn-marginTop-1t01tom{margin-top:auto}
|
||||
.rn-marginRight-61z16t{margin-right:0px}
|
||||
.rn-marginRight-lchren{margin-right:auto}
|
||||
.rn-marginBottom-p1pxzi{margin-bottom:0px}
|
||||
.rn-marginBottom-1qahzrx{margin-bottom:auto}
|
||||
.rn-marginLeft-11wrixw{margin-left:0px}
|
||||
.rn-marginLeft-1jj8364{margin-left:auto}
|
||||
.rn-minHeight-ifefl9{min-height:0px}
|
||||
.rn-minWidth-bcqeeo{min-width:0px}
|
||||
.rn-paddingTop-wk8lta{padding-top:0px}
|
||||
.rn-paddingTop-tskmnb{padding-top:8px}
|
||||
.rn-paddingRight-9aemit{padding-right:0px}
|
||||
.rn-paddingRight-1pyaxff{padding-right:8px}
|
||||
.rn-paddingBottom-1mdbw0j{padding-bottom:0px}
|
||||
.rn-paddingBottom-xd6kpl{padding-bottom:8px}
|
||||
.rn-paddingLeft-gy4na3{padding-left:0px}
|
||||
.rn-paddingLeft-1m04atk{padding-left:8px}
|
||||
.rn-zIndex-1lgpqti{z-index:0}
|
||||
.rn-zIndex-1wyyakw{z-index:-1}
|
||||
.rn-backgroundPosition-vvn4in{background-position:center}
|
||||
.rn-backgroundRepeat-u6sd8q{background-repeat:no-repeat}
|
||||
.rn-backgroundRepeat-17leim2{background-repeat:repeat}
|
||||
.rn-backgroundSize-4gszlv{background-size:cover}
|
||||
.rn-backgroundSize-1sxrcry{background-size:auto}
|
||||
.rn-backgroundSize-ehq7j7{background-size:contain}
|
||||
.rn-backgroundSize-x3cy2q{background-size:100% 100%}
|
||||
.rn-height-1pi2tsx{height:100%}
|
||||
.rn-height-z80fyv{height:20px}
|
||||
.rn-height-1r8g8re{height:36px}
|
||||
.rn-height-10ptun7{height:16px}
|
||||
.rn-height-4v7adb{height:5px}
|
||||
.rn-height-1dernwh{height:70%}
|
||||
.rn-opacity-1272l3b{opacity:0}
|
||||
.rn-opacity-6dt33c{opacity:1}
|
||||
.rn-width-13qz1uu{width:100%}
|
||||
.rn-width-19wmn03{width:20px}
|
||||
.rn-width-1acpoxo{width:36px}
|
||||
.rn-width-1janqcz{width:16px}
|
||||
.rn-touchAction-19z077z{-ms-touch-action:none;touch-action:none}
|
||||
.rn-touchAction-1gvxusu{-ms-touch-action:manipulate;touch-action:manipulate}
|
||||
.rn-WebkitOverflowScrolling-150rngu{-webkit-overflow-scrolling:touch}
|
||||
.rn-flex-13awgt0{-ms-flex:1;-webkit-flex:1;flex:1}
|
||||
.rn-flexGrow-1m1wadx{-ms-flex-positive:1 !important;-webkit-flex-grow:1 !important;flex-grow:1 !important}
|
||||
.rn-overflowX-11yh6sk{overflow-x:hidden}
|
||||
.rn-overflowX-lltvgl{overflow-x:auto}
|
||||
.rn-overflowY-1rnoaur{overflow-y:auto}
|
||||
.rn-overflowY-buy8e9{overflow-y:hidden}
|
||||
.rn-transform-emqnss{-webkit-transform:translateZ(0px);transform:translateZ(0px)}
|
||||
.rn-fontFamily-10u92zi{font-family:-apple-system, BlinkMacSystemFont, \\"Segoe UI\\", Roboto, Ubuntu, \\"Helvetica Neue\\", sans-serif}
|
||||
.rn-fontFamily-poiln3{font-family:inherit}
|
||||
.rn-fontSize-1b43r93{font-size:14px}
|
||||
.rn-fontSize-7cikom{font-size:inherit}
|
||||
.rn-whiteSpace-q42fyq{white-space:pre-wrap}
|
||||
.rn-whiteSpace-irrty{white-space:inherit}
|
||||
.rn-whiteSpace-3s2u2q{white-space:nowrap}
|
||||
.rn-wordWrap-qvutc0{word-wrap:break-word}
|
||||
.rn-userSelect-lrvibr{-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none;user-select:none}
|
||||
.rn-maxWidth-dnmrzs{max-width:100%}
|
||||
.rn-textOverflow-1udbk01{text-overflow:ellipsis}
|
||||
.rn-justifyContent-1777fci{-ms-flex-pack:center;-webkit-box-pack:center;-webkit-justify-content:center;justify-content:center}
|
||||
.rn-visibility-11j9u27{visibility:hidden}
|
||||
.rn-animationDuration-17bb2tj{-webkit-animation-duration:0.75s;animation-duration:0.75s}
|
||||
.rn-animationDuration-1ay1djp{-webkit-animation-duration:1s;animation-duration:1s}
|
||||
.rn-animationIterationCount-1muvv40{-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite}
|
||||
.rn-animationName-dozj4v{-webkit-animation-name:rn-ActivityIndicator-animation;animation-name:rn-ActivityIndicator-animation}
|
||||
.rn-animationName-141g9a{-webkit-animation-name:rn-ProgressBar-animation;animation-name:rn-ProgressBar-animation}
|
||||
.rn-animationTimingFunction-1ldzwu0{-webkit-animation-timing-function:linear;animation-timing-function:linear}
|
||||
.rn-animationPlayState-1abnn5w{-webkit-animation-play-state:paused;animation-play-state:paused}
|
||||
.rn-transitionDuration-eafdt9{-webkit-transition-duration:0.15s;transition-duration:0.15s}
|
||||
.rn-transitionDuration-13tjlyg{-webkit-transition-duration:0.1s;transition-duration:0.1s}
|
||||
.rn-transitionProperty-1i6wzkk{-moz-transition-property:opacity;-webkit-transition-property:opacity;transition-property:opacity}
|
||||
.rn-borderTopLeftRadius-1iymjk7{border-top-left-radius:2px}
|
||||
.rn-borderTopLeftRadius-jt3ufn{border-top-left-radius:100%}
|
||||
.rn-borderTopLeftRadius-ou6ah9{border-top-left-radius:0px}
|
||||
.rn-borderTopRightRadius-s2skl2{border-top-right-radius:2px}
|
||||
.rn-borderTopRightRadius-1e868j9{border-top-right-radius:100%}
|
||||
.rn-borderTopRightRadius-t12b5v{border-top-right-radius:0px}
|
||||
.rn-borderBottomRightRadius-l5bh9y{border-bottom-right-radius:2px}
|
||||
.rn-borderBottomRightRadius-ujv9e3{border-bottom-right-radius:100%}
|
||||
.rn-borderBottomRightRadius-zmljjp{border-bottom-right-radius:0px}
|
||||
.rn-borderBottomLeftRadius-101sy47{border-bottom-left-radius:2px}
|
||||
.rn-borderBottomLeftRadius-1hakmuk{border-bottom-left-radius:100%}
|
||||
.rn-borderBottomLeftRadius-pm2fo{border-bottom-left-radius:0px}
|
||||
.rn-fontWeight-majxgm{font-weight:500}
|
||||
.rn-textTransform-tsynxw{text-transform:uppercase}
|
||||
.rn-borderTopColor-j4x2lb{border-top-color:rgba(101,119,134,1)}
|
||||
.rn-borderTopColor-gj2eto{border-top-color:rgba(0,150,136,1)}
|
||||
.rn-borderTopColor-1j7vz2b{border-top-color:rgba(204,214,221,1)}
|
||||
.rn-borderTopColor-2dclza{border-top-color:rgba(170,184,194,1)}
|
||||
.rn-borderTopColor-kqr9px{border-top-color:black}
|
||||
.rn-borderRightColor-12i18q1{border-right-color:rgba(101,119,134,1)}
|
||||
.rn-borderRightColor-31ud7z{border-right-color:rgba(0,150,136,1)}
|
||||
.rn-borderRightColor-10fg1ub{border-right-color:rgba(204,214,221,1)}
|
||||
.rn-borderRightColor-8jf312{border-right-color:rgba(170,184,194,1)}
|
||||
.rn-borderRightColor-q0dj5p{border-right-color:black}
|
||||
.rn-borderBottomColor-mg3rfb{border-bottom-color:rgba(101,119,134,1)}
|
||||
.rn-borderBottomColor-1bgnb8i{border-bottom-color:rgba(0,150,136,1)}
|
||||
.rn-borderBottomColor-zxuuv6{border-bottom-color:rgba(204,214,221,1)}
|
||||
.rn-borderBottomColor-1yeakrt{border-bottom-color:rgba(170,184,194,1)}
|
||||
.rn-borderBottomColor-1ah7hsa{border-bottom-color:black}
|
||||
.rn-borderLeftColor-vnhemr{border-left-color:rgba(101,119,134,1)}
|
||||
.rn-borderLeftColor-tbzcuz{border-left-color:rgba(0,150,136,1)}
|
||||
.rn-borderLeftColor-1p34dw6{border-left-color:rgba(204,214,221,1)}
|
||||
.rn-borderLeftColor-bluj2i{border-left-color:rgba(170,184,194,1)}
|
||||
.rn-borderLeftColor-137uh4u{border-left-color:black}
|
||||
.rn-backgroundImage-rs94m5{background-image:url(\\"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcKICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIgogICB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiCiAgIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgdmVyc2lvbj0iMS4xIgogICB2aWV3Qm94PSIwIDAgMSAxIgogICBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJ4TWluWU1pbiBtZWV0Ij4KICA8cGF0aAogICAgIGQ9Ik0gMC4wNDAzODA1OSwwLjYyNjc3NjcgMC4xNDY0NDY2MSwwLjUyMDcxMDY4IDAuNDI5Mjg5MzIsMC44MDM1NTMzOSAwLjMyMzIyMzMsMC45MDk2MTk0MSB6IE0gMC4yMTcxNTcyOSwwLjgwMzU1MzM5IDAuODUzNTUzMzksMC4xNjcxNTcyOSAwLjk1OTYxOTQxLDAuMjczMjIzMyAwLjMyMzIyMzMsMC45MDk2MTk0MSB6IgogICAgIGlkPSJyZWN0Mzc4MCIKICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO2ZpbGwtb3BhY2l0eToxO3N0cm9rZTpub25lIiAvPgo8L3N2Zz4K\\")}
|
||||
.rn-alignSelf-k200y{-ms-flex-item-align:start;-webkit-align-self:flex-start;align-self:flex-start}
|
||||
.rn-boxShadow-1ewcgjf{box-shadow:0px 1px 3px rgba(0,0,0,0.5)}
|
||||
.rn-resize-1dz5y72{resize:none}",
|
||||
},
|
||||
]
|
||||
`;
|
||||
|
||||
@@ -22,6 +22,23 @@ describe('apis/StyleSheet/createReactDOMStyle', () => {
|
||||
expect(firstStyle).toEqual(secondStyle);
|
||||
});
|
||||
|
||||
describe('borderWidth styles', () => {
|
||||
test('defaults to 0 when "null"', () => {
|
||||
expect(createReactDOMStyle({ borderWidth: null })).toEqual({
|
||||
borderTopWidth: '0px',
|
||||
borderRightWidth: '0px',
|
||||
borderBottomWidth: '0px',
|
||||
borderLeftWidth: '0px'
|
||||
});
|
||||
expect(createReactDOMStyle({ borderWidth: 2, borderRightWidth: null })).toEqual({
|
||||
borderTopWidth: '2px',
|
||||
borderRightWidth: '0px',
|
||||
borderBottomWidth: '2px',
|
||||
borderLeftWidth: '2px'
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('flexbox styles', () => {
|
||||
test('flex defaults', () => {
|
||||
expect(createReactDOMStyle({ display: 'flex' })).toEqual({
|
||||
|
||||
@@ -22,6 +22,18 @@ describe('apis/StyleSheet', () => {
|
||||
expect(isPlainObject(StyleSheet.absoluteFillObject) === true).toBeTruthy();
|
||||
});
|
||||
|
||||
describe('compose', () => {
|
||||
test('returns array when neither style is falsey', () => {
|
||||
expect(StyleSheet.compose(1, 2)).toEqual([1, 2]);
|
||||
});
|
||||
test('returns style1 when style2 is falsey', () => {
|
||||
expect(StyleSheet.compose(1, null)).toBe(1);
|
||||
});
|
||||
test('returns style2 when style1 is falsey', () => {
|
||||
expect(StyleSheet.compose(null, 2)).toBe(2);
|
||||
});
|
||||
});
|
||||
|
||||
describe('create', () => {
|
||||
test('replaces styles with numbers', () => {
|
||||
const style = StyleSheet.create({ root: { position: 'absolute' } });
|
||||
|
||||
@@ -52,6 +52,14 @@ const colorProps = {
|
||||
color: true
|
||||
};
|
||||
|
||||
const borderWidthProps = {
|
||||
borderWidth: true,
|
||||
borderTopWidth: true,
|
||||
borderRightWidth: true,
|
||||
borderBottomWidth: true,
|
||||
borderLeftWidth: true
|
||||
};
|
||||
|
||||
const systemFontStack =
|
||||
'-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Ubuntu, "Helvetica Neue", sans-serif';
|
||||
|
||||
@@ -141,13 +149,26 @@ const createReducer = (style, styleProps) => {
|
||||
let hasResolvedTextShadow = false;
|
||||
|
||||
return (resolvedStyle, prop) => {
|
||||
const value = normalizeValue(prop, style[prop]);
|
||||
let value = normalizeValue(prop, style[prop]);
|
||||
|
||||
// Make sure the default border width is explicitly set to '0' to avoid
|
||||
// falling back to any unwanted user-agent styles.
|
||||
if (borderWidthProps[prop]) {
|
||||
value = value == null ? normalizeValue(null, 0) : value;
|
||||
}
|
||||
|
||||
// Normalize color values
|
||||
if (colorProps[prop]) {
|
||||
value = processColor(value);
|
||||
}
|
||||
|
||||
// Ignore everything else with a null value
|
||||
if (value == null) {
|
||||
return resolvedStyle;
|
||||
}
|
||||
|
||||
switch (prop) {
|
||||
// ignore React Native styles
|
||||
// Ignore some React Native styles
|
||||
case 'aspectRatio':
|
||||
case 'elevation':
|
||||
case 'overlayColor':
|
||||
@@ -251,23 +272,17 @@ const createReducer = (style, styleProps) => {
|
||||
}
|
||||
|
||||
default: {
|
||||
// normalize color values
|
||||
let finalValue = value;
|
||||
if (colorProps[prop]) {
|
||||
finalValue = processColor(value);
|
||||
}
|
||||
|
||||
const longFormProperties = styleShortFormProperties[prop];
|
||||
if (longFormProperties) {
|
||||
longFormProperties.forEach((longForm, i) => {
|
||||
// the value of any longform property in the original styles takes
|
||||
// precedence over the shortform's value
|
||||
// The value of any longform property in the original styles takes
|
||||
// precedence over the shortform's value.
|
||||
if (styleProps.indexOf(longForm) === -1) {
|
||||
resolvedStyle[longForm] = finalValue;
|
||||
resolvedStyle[longForm] = value;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
resolvedStyle[prop] = finalValue;
|
||||
resolvedStyle[prop] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
22
src/apis/StyleSheet/getHairlineWidth.js
Normal file
22
src/apis/StyleSheet/getHairlineWidth.js
Normal file
@@ -0,0 +1,22 @@
|
||||
/**
|
||||
* Based on http://dieulot.net/css-retina-hairline
|
||||
* @noflow
|
||||
*/
|
||||
|
||||
import { canUseDOM } from 'fbjs/lib/ExecutionEnvironment';
|
||||
|
||||
const getHairlineWidth = () => {
|
||||
let hairlineWidth = 1;
|
||||
if (canUseDOM && window.devicePixelRatio && window.devicePixelRatio >= 2) {
|
||||
const node = document.createElement('div');
|
||||
node.style.border = '.5px solid transparent';
|
||||
document.body.appendChild(node);
|
||||
if (node.offsetHeight === 1) {
|
||||
hairlineWidth = 0.5;
|
||||
}
|
||||
document.body.removeChild(node);
|
||||
}
|
||||
return hairlineWidth;
|
||||
};
|
||||
|
||||
export default getHairlineWidth;
|
||||
@@ -10,6 +10,7 @@
|
||||
*/
|
||||
|
||||
import flattenStyle from './flattenStyle';
|
||||
import getHairlineWidth from './getHairlineWidth';
|
||||
import modality from '../../modules/modality';
|
||||
import StyleRegistry from './registry';
|
||||
|
||||
@@ -36,6 +37,13 @@ const absoluteFill = StyleRegistry.register(absoluteFillObject);
|
||||
const StyleSheet = {
|
||||
absoluteFill,
|
||||
absoluteFillObject,
|
||||
compose(style1, style2) {
|
||||
if (style1 && style2) {
|
||||
return [style1, style2];
|
||||
} else {
|
||||
return style1 || style2;
|
||||
}
|
||||
},
|
||||
create(styles) {
|
||||
const result = {};
|
||||
Object.keys(styles).forEach(key => {
|
||||
@@ -51,7 +59,7 @@ const StyleSheet = {
|
||||
getStyleSheets() {
|
||||
return StyleRegistry.getStyleSheets();
|
||||
},
|
||||
hairlineWidth: 1
|
||||
hairlineWidth: getHairlineWidth()
|
||||
};
|
||||
|
||||
export default StyleSheet;
|
||||
|
||||
2
src/components/ART/index.js
Normal file
2
src/components/ART/index.js
Normal file
@@ -0,0 +1,2 @@
|
||||
import ART from 'react-art';
|
||||
export default ART;
|
||||
@@ -6,20 +6,24 @@ exports[`components/ActivityIndicator prop "animating" is "false" 1`] = `
|
||||
aria-valuemax="1"
|
||||
aria-valuemin="0"
|
||||
style={
|
||||
Array [
|
||||
15,
|
||||
undefined,
|
||||
]
|
||||
Object {
|
||||
"alignItems": "center",
|
||||
"justifyContent": "center",
|
||||
}
|
||||
}
|
||||
>
|
||||
<View
|
||||
style={
|
||||
Array [
|
||||
19,
|
||||
17,
|
||||
18,
|
||||
16,
|
||||
]
|
||||
Object {
|
||||
"animationDuration": "0.75s",
|
||||
"animationIterationCount": "infinite",
|
||||
"animationName": "rn-ActivityIndicator-animation",
|
||||
"animationPlayState": "paused",
|
||||
"animationTimingFunction": "linear",
|
||||
"height": 20,
|
||||
"visibility": "hidden",
|
||||
"width": 20,
|
||||
}
|
||||
}
|
||||
>
|
||||
<svg
|
||||
@@ -65,20 +69,22 @@ exports[`components/ActivityIndicator prop "animating" is "true" 1`] = `
|
||||
aria-valuemax="1"
|
||||
aria-valuemin="0"
|
||||
style={
|
||||
Array [
|
||||
15,
|
||||
undefined,
|
||||
]
|
||||
Object {
|
||||
"alignItems": "center",
|
||||
"justifyContent": "center",
|
||||
}
|
||||
}
|
||||
>
|
||||
<View
|
||||
style={
|
||||
Array [
|
||||
19,
|
||||
17,
|
||||
false,
|
||||
false,
|
||||
]
|
||||
Object {
|
||||
"animationDuration": "0.75s",
|
||||
"animationIterationCount": "infinite",
|
||||
"animationName": "rn-ActivityIndicator-animation",
|
||||
"animationTimingFunction": "linear",
|
||||
"height": 20,
|
||||
"width": 20,
|
||||
}
|
||||
}
|
||||
>
|
||||
<svg
|
||||
@@ -160,20 +166,23 @@ exports[`components/ActivityIndicator prop "hidesWhenStopped" is "false" 1`] = `
|
||||
aria-valuemax="1"
|
||||
aria-valuemin="0"
|
||||
style={
|
||||
Array [
|
||||
15,
|
||||
undefined,
|
||||
]
|
||||
Object {
|
||||
"alignItems": "center",
|
||||
"justifyContent": "center",
|
||||
}
|
||||
}
|
||||
>
|
||||
<View
|
||||
style={
|
||||
Array [
|
||||
19,
|
||||
17,
|
||||
18,
|
||||
false,
|
||||
]
|
||||
Object {
|
||||
"animationDuration": "0.75s",
|
||||
"animationIterationCount": "infinite",
|
||||
"animationName": "rn-ActivityIndicator-animation",
|
||||
"animationPlayState": "paused",
|
||||
"animationTimingFunction": "linear",
|
||||
"height": 20,
|
||||
"width": 20,
|
||||
}
|
||||
}
|
||||
>
|
||||
<svg
|
||||
@@ -219,20 +228,24 @@ exports[`components/ActivityIndicator prop "hidesWhenStopped" is "true" 1`] = `
|
||||
aria-valuemax="1"
|
||||
aria-valuemin="0"
|
||||
style={
|
||||
Array [
|
||||
15,
|
||||
undefined,
|
||||
]
|
||||
Object {
|
||||
"alignItems": "center",
|
||||
"justifyContent": "center",
|
||||
}
|
||||
}
|
||||
>
|
||||
<View
|
||||
style={
|
||||
Array [
|
||||
19,
|
||||
17,
|
||||
18,
|
||||
16,
|
||||
]
|
||||
Object {
|
||||
"animationDuration": "0.75s",
|
||||
"animationIterationCount": "infinite",
|
||||
"animationName": "rn-ActivityIndicator-animation",
|
||||
"animationPlayState": "paused",
|
||||
"animationTimingFunction": "linear",
|
||||
"height": 20,
|
||||
"visibility": "hidden",
|
||||
"width": 20,
|
||||
}
|
||||
}
|
||||
>
|
||||
<svg
|
||||
@@ -278,20 +291,22 @@ exports[`components/ActivityIndicator prop "size" is "large" 1`] = `
|
||||
aria-valuemax="1"
|
||||
aria-valuemin="0"
|
||||
style={
|
||||
Array [
|
||||
15,
|
||||
undefined,
|
||||
]
|
||||
Object {
|
||||
"alignItems": "center",
|
||||
"justifyContent": "center",
|
||||
}
|
||||
}
|
||||
>
|
||||
<View
|
||||
style={
|
||||
Array [
|
||||
20,
|
||||
17,
|
||||
false,
|
||||
false,
|
||||
]
|
||||
Object {
|
||||
"animationDuration": "0.75s",
|
||||
"animationIterationCount": "infinite",
|
||||
"animationName": "rn-ActivityIndicator-animation",
|
||||
"animationTimingFunction": "linear",
|
||||
"height": 36,
|
||||
"width": 36,
|
||||
}
|
||||
}
|
||||
>
|
||||
<svg
|
||||
@@ -337,23 +352,22 @@ exports[`components/ActivityIndicator prop "size" is a number 1`] = `
|
||||
aria-valuemax="1"
|
||||
aria-valuemin="0"
|
||||
style={
|
||||
Array [
|
||||
15,
|
||||
undefined,
|
||||
]
|
||||
Object {
|
||||
"alignItems": "center",
|
||||
"justifyContent": "center",
|
||||
}
|
||||
}
|
||||
>
|
||||
<View
|
||||
style={
|
||||
Array [
|
||||
Object {
|
||||
"height": 30,
|
||||
"width": 30,
|
||||
},
|
||||
17,
|
||||
false,
|
||||
false,
|
||||
]
|
||||
Object {
|
||||
"animationDuration": "0.75s",
|
||||
"animationIterationCount": "infinite",
|
||||
"animationName": "rn-ActivityIndicator-animation",
|
||||
"animationTimingFunction": "linear",
|
||||
"height": 30,
|
||||
"width": 30,
|
||||
}
|
||||
}
|
||||
>
|
||||
<svg
|
||||
|
||||
@@ -17,7 +17,11 @@ import ViewPropTypes from '../View/ViewPropTypes';
|
||||
import { bool, number, oneOf, oneOfType, string } from 'prop-types';
|
||||
import React, { Component } from 'react';
|
||||
|
||||
class ActivityIndicator extends Component {
|
||||
const createSvgCircle = style => (
|
||||
<circle cx="16" cy="16" fill="none" r="14" strokeWidth="4" style={style} />
|
||||
);
|
||||
|
||||
class ActivityIndicator extends Component<*> {
|
||||
static displayName = 'ActivityIndicator';
|
||||
|
||||
static propTypes = {
|
||||
@@ -40,29 +44,15 @@ class ActivityIndicator extends Component {
|
||||
|
||||
const svg = (
|
||||
<svg height="100%" viewBox="0 0 32 32" width="100%">
|
||||
<circle
|
||||
cx="16"
|
||||
cy="16"
|
||||
fill="none"
|
||||
r="14"
|
||||
strokeWidth="4"
|
||||
style={{
|
||||
stroke: color,
|
||||
opacity: 0.2
|
||||
}}
|
||||
/>
|
||||
<circle
|
||||
cx="16"
|
||||
cy="16"
|
||||
fill="none"
|
||||
r="14"
|
||||
strokeWidth="4"
|
||||
style={{
|
||||
stroke: color,
|
||||
strokeDasharray: 80,
|
||||
strokeDashoffset: 60
|
||||
}}
|
||||
/>
|
||||
{createSvgCircle({
|
||||
stroke: color,
|
||||
opacity: 0.2
|
||||
})}
|
||||
{createSvgCircle({
|
||||
stroke: color,
|
||||
strokeDasharray: 80,
|
||||
strokeDashoffset: 60
|
||||
})}
|
||||
</svg>
|
||||
);
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
/* eslint-env jasmine, jest */
|
||||
/* eslint-disable react/jsx-no-bind */
|
||||
|
||||
import React from 'react';
|
||||
import Button from '..';
|
||||
|
||||
@@ -17,7 +17,7 @@ import Text from '../Text';
|
||||
import { bool, func, string } from 'prop-types';
|
||||
import React, { Component } from 'react';
|
||||
|
||||
class Button extends Component {
|
||||
class Button extends Component<*> {
|
||||
static propTypes = {
|
||||
accessibilityLabel: string,
|
||||
color: ColorPropType,
|
||||
|
||||
60
src/components/CheckBox/__tests__/index-test.js
Normal file
60
src/components/CheckBox/__tests__/index-test.js
Normal file
@@ -0,0 +1,60 @@
|
||||
/* eslint-env jest */
|
||||
|
||||
import CheckBox from '../';
|
||||
import React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
|
||||
const checkboxSelector = 'input[type="checkbox"]';
|
||||
|
||||
describe('CheckBox', () => {
|
||||
describe('disabled', () => {
|
||||
test('when "false" a default checkbox is rendered', () => {
|
||||
const component = shallow(<CheckBox />);
|
||||
expect(component.find(checkboxSelector).prop('disabled')).toBe(false);
|
||||
});
|
||||
|
||||
test('when "true" a disabled checkbox is rendered', () => {
|
||||
const component = shallow(<CheckBox disabled />);
|
||||
expect(component.find(checkboxSelector).prop('disabled')).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('onChange', () => {
|
||||
test('is called with the event object', () => {
|
||||
const onChange = jest.fn();
|
||||
const component = shallow(<CheckBox onChange={onChange} value={false} />);
|
||||
component.find('input').simulate('change', { nativeEvent: { target: { checked: true } } });
|
||||
expect(onChange).toHaveBeenCalledWith({
|
||||
nativeEvent: { target: { checked: true }, value: true }
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('onValueChange', () => {
|
||||
test('when value is "false" it receives "true"', () => {
|
||||
const onValueChange = jest.fn();
|
||||
const component = shallow(<CheckBox onValueChange={onValueChange} value={false} />);
|
||||
component.find('input').simulate('change', { nativeEvent: { target: { checked: true } } });
|
||||
expect(onValueChange).toHaveBeenCalledWith(true);
|
||||
});
|
||||
|
||||
test('when value is "true" it receives "false"', () => {
|
||||
const onValueChange = jest.fn();
|
||||
const component = shallow(<CheckBox onValueChange={onValueChange} value />);
|
||||
component.find('input').simulate('change', { nativeEvent: { target: { checked: false } } });
|
||||
expect(onValueChange).toHaveBeenCalledWith(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('value', () => {
|
||||
test('when "false" an unchecked checkbox is rendered', () => {
|
||||
const component = shallow(<CheckBox value={false} />);
|
||||
expect(component.find(checkboxSelector).prop('checked')).toBe(false);
|
||||
});
|
||||
|
||||
test('when "true" a checked checkbox is rendered', () => {
|
||||
const component = shallow(<CheckBox value />);
|
||||
expect(component.find(checkboxSelector).prop('checked')).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
162
src/components/CheckBox/index.js
Normal file
162
src/components/CheckBox/index.js
Normal file
@@ -0,0 +1,162 @@
|
||||
/**
|
||||
* Copyright (c) 2017-present, Nicolas Gallagher.
|
||||
* Copyright (c) 2017-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @providesModule CheckBox
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import applyNativeMethods from '../../modules/applyNativeMethods';
|
||||
import ColorPropType from '../../propTypes/ColorPropType';
|
||||
import createElement from '../../modules/createElement';
|
||||
import StyleSheet from '../../apis/StyleSheet';
|
||||
import UIManager from '../../apis/UIManager';
|
||||
import View from '../View';
|
||||
import ViewPropTypes, { type ViewProps } from '../View/ViewPropTypes';
|
||||
import React, { Component } from 'react';
|
||||
import { bool, func } from 'prop-types';
|
||||
|
||||
type Props = ViewProps & {
|
||||
color?: ColorPropType,
|
||||
disabled?: boolean,
|
||||
onChange?: Function,
|
||||
onValueChange?: Function,
|
||||
value?: boolean
|
||||
};
|
||||
|
||||
class CheckBox extends Component<Props> {
|
||||
_checkboxElement: HTMLInputElement;
|
||||
|
||||
static displayName = 'CheckBox';
|
||||
|
||||
static propTypes = {
|
||||
...ViewPropTypes,
|
||||
color: ColorPropType,
|
||||
disabled: bool,
|
||||
onChange: func,
|
||||
onValueChange: func,
|
||||
value: bool
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
disabled: false,
|
||||
value: false
|
||||
};
|
||||
|
||||
blur() {
|
||||
UIManager.blur(this._checkboxElement);
|
||||
}
|
||||
|
||||
focus() {
|
||||
UIManager.focus(this._checkboxElement);
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
color,
|
||||
disabled,
|
||||
/* eslint-disable */
|
||||
onChange,
|
||||
onValueChange,
|
||||
/* eslint-enable */
|
||||
style,
|
||||
value,
|
||||
...other
|
||||
} = this.props;
|
||||
|
||||
const fakeControl = (
|
||||
<View
|
||||
style={[
|
||||
styles.fakeControl,
|
||||
value && styles.fakeControlChecked,
|
||||
// custom color
|
||||
value && color && { backgroundColor: color, borderColor: color },
|
||||
disabled && styles.fakeControlDisabled,
|
||||
value && disabled && styles.fakeControlCheckedAndDisabled
|
||||
]}
|
||||
/>
|
||||
);
|
||||
|
||||
const nativeControl = createElement('input', {
|
||||
checked: value,
|
||||
disabled: disabled,
|
||||
onChange: this._handleChange,
|
||||
ref: this._setCheckboxRef,
|
||||
style: [styles.nativeControl, styles.cursorInherit],
|
||||
type: 'checkbox'
|
||||
});
|
||||
|
||||
return (
|
||||
<View {...other} style={[styles.root, style, disabled && styles.cursorDefault]}>
|
||||
{fakeControl}
|
||||
{nativeControl}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
_handleChange = (event: Object) => {
|
||||
const { onChange, onValueChange } = this.props;
|
||||
const value = event.nativeEvent.target.checked;
|
||||
event.nativeEvent.value = value;
|
||||
onChange && onChange(event);
|
||||
onValueChange && onValueChange(value);
|
||||
};
|
||||
|
||||
_setCheckboxRef = element => {
|
||||
this._checkboxElement = element;
|
||||
};
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
root: {
|
||||
cursor: 'pointer',
|
||||
height: 16,
|
||||
userSelect: 'none',
|
||||
width: 16
|
||||
},
|
||||
cursorDefault: {
|
||||
cursor: 'default'
|
||||
},
|
||||
cursorInherit: {
|
||||
cursor: 'inherit'
|
||||
},
|
||||
fakeControl: {
|
||||
alignItems: 'center',
|
||||
backgroundColor: '#fff',
|
||||
borderColor: '#657786',
|
||||
borderRadius: 2,
|
||||
borderStyle: 'solid',
|
||||
borderWidth: 2,
|
||||
height: '100%',
|
||||
justifyContent: 'center',
|
||||
width: '100%'
|
||||
},
|
||||
fakeControlChecked: {
|
||||
backgroundColor: '#009688',
|
||||
backgroundImage:
|
||||
'url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcKICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIgogICB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiCiAgIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgdmVyc2lvbj0iMS4xIgogICB2aWV3Qm94PSIwIDAgMSAxIgogICBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJ4TWluWU1pbiBtZWV0Ij4KICA8cGF0aAogICAgIGQ9Ik0gMC4wNDAzODA1OSwwLjYyNjc3NjcgMC4xNDY0NDY2MSwwLjUyMDcxMDY4IDAuNDI5Mjg5MzIsMC44MDM1NTMzOSAwLjMyMzIyMzMsMC45MDk2MTk0MSB6IE0gMC4yMTcxNTcyOSwwLjgwMzU1MzM5IDAuODUzNTUzMzksMC4xNjcxNTcyOSAwLjk1OTYxOTQxLDAuMjczMjIzMyAwLjMyMzIyMzMsMC45MDk2MTk0MSB6IgogICAgIGlkPSJyZWN0Mzc4MCIKICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO2ZpbGwtb3BhY2l0eToxO3N0cm9rZTpub25lIiAvPgo8L3N2Zz4K")',
|
||||
backgroundRepeat: 'no-repeat',
|
||||
borderColor: '#009688'
|
||||
},
|
||||
fakeControlDisabled: {
|
||||
borderColor: '#CCD6DD'
|
||||
},
|
||||
fakeControlCheckedAndDisabled: {
|
||||
backgroundColor: '#AAB8C2',
|
||||
borderColor: '#AAB8C2'
|
||||
},
|
||||
nativeControl: {
|
||||
...StyleSheet.absoluteFillObject,
|
||||
height: '100%',
|
||||
margin: 0,
|
||||
opacity: 0,
|
||||
padding: 0,
|
||||
width: '100%'
|
||||
}
|
||||
});
|
||||
|
||||
export default applyNativeMethods(CheckBox);
|
||||
79
src/components/Image/ImageBackground.js
Normal file
79
src/components/Image/ImageBackground.js
Normal file
@@ -0,0 +1,79 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* 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.
|
||||
*
|
||||
* @flow
|
||||
*/
|
||||
import ensureComponentIsNative from '../Touchable/ensureComponentIsNative';
|
||||
import Image from './';
|
||||
import StyleSheet from '../../apis/StyleSheet';
|
||||
import View from '../View';
|
||||
import ViewPropTypes from '../View/ViewPropTypes';
|
||||
import React, { Component } from 'react';
|
||||
|
||||
const emptyObject = {};
|
||||
|
||||
/**
|
||||
* Very simple drop-in replacement for <Image> which supports nesting views.
|
||||
*/
|
||||
class ImageBackground extends Component<*> {
|
||||
static propTypes = {
|
||||
...Image.propTypes,
|
||||
imageStyle: Image.propTypes.style,
|
||||
style: ViewPropTypes.style
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
style: emptyObject
|
||||
};
|
||||
|
||||
setNativeProps(props: Object) {
|
||||
// Work-around flow
|
||||
const viewRef = this._viewRef;
|
||||
if (viewRef) {
|
||||
ensureComponentIsNative(viewRef);
|
||||
viewRef.setNativeProps(props);
|
||||
}
|
||||
}
|
||||
|
||||
_viewRef: ?View = null;
|
||||
|
||||
_captureRef = (ref: View) => {
|
||||
this._viewRef = ref;
|
||||
};
|
||||
|
||||
render() {
|
||||
const { children, style, imageStyle, imageRef, ...props } = this.props;
|
||||
|
||||
return (
|
||||
<View ref={this._captureRef} style={style}>
|
||||
<Image
|
||||
{...props}
|
||||
ref={imageRef}
|
||||
style={[
|
||||
StyleSheet.absoluteFill,
|
||||
{
|
||||
// Temporary Workaround:
|
||||
// Current (imperfect yet) implementation of <Image> overwrites width and height styles
|
||||
// (which is not quite correct), and these styles conflict with explicitly set styles
|
||||
// of <ImageBackground> and with our internal layout model here.
|
||||
// So, we have to proxy/reapply these styles explicitly for actual <Image> component.
|
||||
// This workaround should be removed after implementing proper support of
|
||||
// intrinsic content size of the <Image>.
|
||||
width: style.width,
|
||||
height: style.height
|
||||
},
|
||||
imageStyle
|
||||
]}
|
||||
/>
|
||||
{children}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default ImageBackground;
|
||||
36
src/components/Image/__tests__/ImageBackground-test.js
Normal file
36
src/components/Image/__tests__/ImageBackground-test.js
Normal file
@@ -0,0 +1,36 @@
|
||||
/* eslint-env jasmine, jest */
|
||||
|
||||
import Image from '..';
|
||||
import ImageBackground from '../ImageBackground';
|
||||
import React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
import Text from '../../Text';
|
||||
|
||||
describe('components/ImageBackground', () => {
|
||||
describe('prop "children"', () => {
|
||||
it('render child content', () => {
|
||||
const component = shallow(
|
||||
<ImageBackground>
|
||||
<Text>Hello World!</Text>
|
||||
</ImageBackground>
|
||||
);
|
||||
expect(component.find(Text)).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('prop "imageStyle"', () => {
|
||||
it('sets the style of the underlying Image', () => {
|
||||
const imageStyle = { width: 40, height: 60 };
|
||||
const component = shallow(<ImageBackground imageStyle={imageStyle} />);
|
||||
expect(component.find(Image).prop('style')).toContain(imageStyle);
|
||||
});
|
||||
});
|
||||
|
||||
describe('prop "style"', () => {
|
||||
it('sets the style of the container View', () => {
|
||||
const style = { margin: 40 };
|
||||
const component = shallow(<ImageBackground style={style} />);
|
||||
expect(component.prop('style')).toEqual(style);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,6 +1,8 @@
|
||||
/* eslint-env jasmine, jest */
|
||||
/* eslint-disable react/jsx-no-bind */
|
||||
|
||||
import Image from '../';
|
||||
import ImageLoader from '../../../modules/ImageLoader';
|
||||
import ImageUriCache from '../ImageUriCache';
|
||||
import React from 'react';
|
||||
import { mount, shallow } from 'enzyme';
|
||||
@@ -31,12 +33,6 @@ describe('components/Image', () => {
|
||||
expect(component.prop('accessible')).toBe(false);
|
||||
});
|
||||
|
||||
test('prop "children"', () => {
|
||||
const children = <div className="unique" />;
|
||||
const component = shallow(<Image children={children} />);
|
||||
expect(component.find('.unique').length).toBe(1);
|
||||
});
|
||||
|
||||
describe('prop "defaultSource"', () => {
|
||||
test('sets background image when value is an object', () => {
|
||||
const defaultSource = { uri: 'https://google.com/favicon.ico' };
|
||||
@@ -86,6 +82,55 @@ describe('components/Image', () => {
|
||||
expect(component.find('img').prop('draggable')).toBe(false);
|
||||
});
|
||||
|
||||
describe('prop "onLoad"', () => {
|
||||
test('is called after image is loaded from network', () => {
|
||||
jest.useFakeTimers();
|
||||
ImageLoader.load = jest.fn().mockImplementation((_, onLoad, onError) => {
|
||||
onLoad();
|
||||
});
|
||||
const onLoadStub = jest.fn();
|
||||
shallow(<Image onLoad={onLoadStub} source="https://test.com/img.jpg" />);
|
||||
jest.runOnlyPendingTimers();
|
||||
expect(ImageLoader.load).toBeCalled();
|
||||
expect(onLoadStub).toBeCalled();
|
||||
});
|
||||
|
||||
test('is called after image is loaded from cache', () => {
|
||||
jest.useFakeTimers();
|
||||
ImageLoader.load = jest.fn().mockImplementation((_, onLoad, onError) => {
|
||||
onLoad();
|
||||
});
|
||||
const onLoadStub = jest.fn();
|
||||
const uri = 'https://test.com/img.jpg';
|
||||
shallow(<Image onLoad={onLoadStub} source={uri} />);
|
||||
ImageUriCache.add(uri);
|
||||
jest.runOnlyPendingTimers();
|
||||
expect(ImageLoader.load).not.toBeCalled();
|
||||
expect(onLoadStub).toBeCalled();
|
||||
ImageUriCache.remove(uri);
|
||||
});
|
||||
|
||||
test('is called on update if "uri" is different', () => {
|
||||
jest.useFakeTimers();
|
||||
const onLoadStub = jest.fn();
|
||||
const uri = 'https://test.com/img.jpg';
|
||||
const component = mount(<Image onLoad={onLoadStub} source={uri} />);
|
||||
component.setProps({ source: 'https://blah.com/img.png' });
|
||||
jest.runOnlyPendingTimers();
|
||||
expect(onLoadStub.mock.calls.length).toBe(2);
|
||||
});
|
||||
|
||||
test('is not called on update if "uri" is the same', () => {
|
||||
jest.useFakeTimers();
|
||||
const onLoadStub = jest.fn();
|
||||
const uri = 'https://test.com/img.jpg';
|
||||
const component = mount(<Image onLoad={onLoadStub} source={uri} />);
|
||||
component.setProps({ resizeMode: 'stretch' });
|
||||
jest.runOnlyPendingTimers();
|
||||
expect(onLoadStub.mock.calls.length).toBe(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('prop "resizeMode"', () => {
|
||||
[
|
||||
Image.resizeMode.contain,
|
||||
|
||||
@@ -22,7 +22,7 @@ import StyleSheet from '../../apis/StyleSheet';
|
||||
import StyleSheetPropType from '../../propTypes/StyleSheetPropType';
|
||||
import View from '../View';
|
||||
import ViewPropTypes from '../View/ViewPropTypes';
|
||||
import { any, bool, func, number, oneOf, oneOfType, shape, string } from 'prop-types';
|
||||
import { bool, func, number, oneOf, oneOfType, shape, string } from 'prop-types';
|
||||
import React, { Component } from 'react';
|
||||
|
||||
const emptyObject = {};
|
||||
@@ -83,9 +83,11 @@ const resolveAssetSource = source => {
|
||||
return uri;
|
||||
};
|
||||
|
||||
class Image extends Component {
|
||||
state: { shouldDisplaySource: boolean };
|
||||
type State = {
|
||||
shouldDisplaySource: boolean
|
||||
};
|
||||
|
||||
class Image extends Component<*, State> {
|
||||
static displayName = 'Image';
|
||||
|
||||
static contextTypes = {
|
||||
@@ -94,7 +96,6 @@ class Image extends Component {
|
||||
|
||||
static propTypes = {
|
||||
...ViewPropTypes,
|
||||
children: any,
|
||||
defaultSource: ImageSourcePropType,
|
||||
draggable: bool,
|
||||
onError: func,
|
||||
@@ -140,6 +141,9 @@ class Image extends Component {
|
||||
this._isMounted = true;
|
||||
if (this._imageState === STATUS_PENDING) {
|
||||
this._createImageLoader();
|
||||
} else if (this._imageState === STATUS_LOADED) {
|
||||
const { onLoad } = this.props;
|
||||
onLoad && onLoad();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -171,7 +175,6 @@ class Image extends Component {
|
||||
const {
|
||||
accessibilityLabel,
|
||||
accessible,
|
||||
children,
|
||||
defaultSource,
|
||||
draggable,
|
||||
onLayout,
|
||||
@@ -216,6 +219,18 @@ class Image extends Component {
|
||||
})
|
||||
: null;
|
||||
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
if (this.props.src) {
|
||||
console.warn('The <Image> component requires a `source` property rather than `src`.');
|
||||
}
|
||||
|
||||
if (this.props.children) {
|
||||
throw new Error(
|
||||
'The <Image> component cannot contain children. If you want to render content on top of the image, consider using the <ImageBackground> component or absolute positioning.'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<View
|
||||
{...other}
|
||||
@@ -226,7 +241,6 @@ class Image extends Component {
|
||||
testID={testID}
|
||||
>
|
||||
{hiddenImage}
|
||||
{children}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ import React, { Component } from 'react';
|
||||
|
||||
import type { ViewLayout, ViewLayoutEvent } from '../View/ViewPropTypes';
|
||||
|
||||
class KeyboardAvoidingView extends Component {
|
||||
class KeyboardAvoidingView extends Component<*> {
|
||||
static propTypes = {
|
||||
...ViewPropTypes,
|
||||
behavior: oneOf(['height', 'padding', 'position']),
|
||||
|
||||
26
src/components/Picker/PickerItemPropType.js
Normal file
26
src/components/Picker/PickerItemPropType.js
Normal file
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* Copyright (c) 2017-present, Nicolas Gallagher.
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import Picker from './';
|
||||
|
||||
const PickerItemPropType = (props: Object, propName: string, componentName: string) => {
|
||||
const prop = props[propName];
|
||||
let error = null;
|
||||
React.Children.forEach(prop, function(child) {
|
||||
if (child.type !== Picker.Item) {
|
||||
error = new Error('`Picker` children must be of type `Picker.Item`.');
|
||||
}
|
||||
});
|
||||
return error;
|
||||
};
|
||||
|
||||
export default PickerItemPropType;
|
||||
20
src/components/Picker/PickerStylePropTypes.js
Normal file
20
src/components/Picker/PickerStylePropTypes.js
Normal file
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* Copyright (c) 2017-present, Nicolas Gallagher.
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import ColorPropType from '../../propTypes/ColorPropType';
|
||||
import ViewStylePropTypes from '../View/ViewStylePropTypes';
|
||||
|
||||
const PickerStylePropTypes = {
|
||||
...ViewStylePropTypes,
|
||||
color: ColorPropType
|
||||
};
|
||||
|
||||
export default PickerStylePropTypes;
|
||||
@@ -0,0 +1,17 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`components/Picker prop "children" renders items 1`] = `
|
||||
<select
|
||||
className="rn-fontFamily-poiln3 rn-fontSize-7cikom rn-marginTop-1mnahxq rn-marginRight-61z16t rn-marginBottom-p1pxzi rn-marginLeft-11wrixw"
|
||||
onChange={[Function]}
|
||||
>
|
||||
<PickerItem
|
||||
label="label-1"
|
||||
value="value-1"
|
||||
/>
|
||||
<PickerItem
|
||||
label="label-2"
|
||||
value="value-2"
|
||||
/>
|
||||
</select>
|
||||
`;
|
||||
74
src/components/Picker/__tests__/index-test.js
Normal file
74
src/components/Picker/__tests__/index-test.js
Normal file
@@ -0,0 +1,74 @@
|
||||
/* eslint-env jasmine, jest */
|
||||
|
||||
import React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
import Picker from '..';
|
||||
|
||||
describe('components/Picker', () => {
|
||||
describe('prop "children"', () => {
|
||||
test('renders items', () => {
|
||||
const picker = (
|
||||
<Picker>
|
||||
<Picker.Item label="label-1" value="value-1" />
|
||||
<Picker.Item label="label-2" value="value-2" />
|
||||
</Picker>
|
||||
);
|
||||
const component = shallow(picker);
|
||||
expect(component).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
describe('prop "enabled"', () => {
|
||||
test('picker is disabled if false', () => {
|
||||
const picker = (
|
||||
<Picker enabled={false}>
|
||||
<Picker.Item label="label-1" value="value-1" />
|
||||
<Picker.Item label="label-2" value="value-2" />
|
||||
</Picker>
|
||||
);
|
||||
const component = shallow(picker);
|
||||
expect(component.find('select').props().disabled).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('prop "onValueChange"', () => {
|
||||
test('is called with (value, index)', () => {
|
||||
const onValueChange = jest.fn();
|
||||
const picker = (
|
||||
<Picker onValueChange={onValueChange} selectedValue="value-1">
|
||||
<Picker.Item label="label-1" value="value-1" />
|
||||
<Picker.Item label="label-2" value="value-2" />
|
||||
</Picker>
|
||||
);
|
||||
const component = shallow(picker);
|
||||
component.find('select').simulate('change', {
|
||||
target: { selectedIndex: '1', value: 'value-2' }
|
||||
});
|
||||
expect(onValueChange).toHaveBeenCalledWith('value-2', '1');
|
||||
});
|
||||
});
|
||||
|
||||
describe('prop "selectedValue"', () => {
|
||||
test('selects the correct item (string)', () => {
|
||||
const picker = (
|
||||
<Picker selectedValue="value-2">
|
||||
<Picker.Item label="label-1" value="value-1" />
|
||||
<Picker.Item label="label-2" value="value-2" />
|
||||
</Picker>
|
||||
);
|
||||
const component = shallow(picker);
|
||||
expect(component.find('select').prop('value')).toBe('value-2');
|
||||
});
|
||||
|
||||
test('selects the correct item (number)', () => {
|
||||
const picker = (
|
||||
<Picker selectedValue={22}>
|
||||
<Picker.Item label="label-1" value={11} />
|
||||
<Picker.Item label="label-2" value={22} />
|
||||
</Picker>
|
||||
);
|
||||
const component = shallow(picker);
|
||||
expect(component.find('select').prop('value')).toBe(22);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,2 +1,114 @@
|
||||
import UnimplementedView from '../UnimplementedView';
|
||||
export default UnimplementedView;
|
||||
/**
|
||||
* Copyright (c) 2017-present, Nicolas Gallagher.
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @providesModule Picker
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import applyNativeMethods from '../../modules/applyNativeMethods';
|
||||
import { Component } from 'react';
|
||||
import ColorPropType from '../../propTypes/ColorPropType';
|
||||
import createElement from '../../modules/createElement';
|
||||
import PickerItemPropType from './PickerItemPropType';
|
||||
import PickerStylePropTypes from './PickerStylePropTypes';
|
||||
import StyleSheetPropType from '../../propTypes/StyleSheetPropType';
|
||||
import StyleSheet from '../../apis/StyleSheet';
|
||||
import TextStylePropTypes from '../Text/TextStylePropTypes';
|
||||
import { arrayOf, bool, func, number, oneOfType, string } from 'prop-types';
|
||||
|
||||
const pickerStyleType = StyleSheetPropType(PickerStylePropTypes);
|
||||
const itemStylePropType = StyleSheetPropType(TextStylePropTypes);
|
||||
|
||||
type ItemProps = {
|
||||
color?: ColorPropType,
|
||||
label: string,
|
||||
testID?: string,
|
||||
value?: number | string
|
||||
};
|
||||
|
||||
class PickerItem extends Component<ItemProps> {
|
||||
static propTypes = {
|
||||
color: ColorPropType,
|
||||
label: string.isRequired,
|
||||
testID: string,
|
||||
value: oneOfType([number, string])
|
||||
};
|
||||
|
||||
render() {
|
||||
const { label, testID, value } = this.props;
|
||||
return createElement('option', { label, testID, value });
|
||||
}
|
||||
}
|
||||
|
||||
type Props = {
|
||||
children?: Array<typeof PickerItem>,
|
||||
enabled?: boolean,
|
||||
onValueChange?: Function,
|
||||
selectedValue?: number | string,
|
||||
style?: pickerStyleType,
|
||||
testID?: string,
|
||||
/* compat */
|
||||
itemStyle?: itemStylePropType,
|
||||
mode?: string,
|
||||
prompt?: string
|
||||
};
|
||||
|
||||
class Picker extends Component<Props> {
|
||||
static propTypes = {
|
||||
children: arrayOf(PickerItemPropType),
|
||||
enabled: bool,
|
||||
onValueChange: func,
|
||||
selectedValue: oneOfType([number, string]),
|
||||
style: pickerStyleType,
|
||||
testID: string
|
||||
};
|
||||
|
||||
static Item = PickerItem;
|
||||
|
||||
render() {
|
||||
const {
|
||||
children,
|
||||
enabled,
|
||||
selectedValue,
|
||||
style,
|
||||
testID,
|
||||
/* eslint-disable */
|
||||
itemStyle,
|
||||
mode,
|
||||
prompt
|
||||
/* eslint-enable */
|
||||
} = this.props;
|
||||
|
||||
return createElement('select', {
|
||||
children,
|
||||
disabled: enabled === false ? true : undefined,
|
||||
onChange: this._handleChange,
|
||||
style: [styles.initial, style],
|
||||
testID,
|
||||
value: selectedValue
|
||||
});
|
||||
}
|
||||
|
||||
_handleChange = (e: Object) => {
|
||||
const { onValueChange } = this.props;
|
||||
const { selectedIndex, value } = e.target;
|
||||
if (onValueChange) {
|
||||
onValueChange(value, selectedIndex);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
initial: {
|
||||
fontFamily: 'inherit',
|
||||
fontSize: 'inherit',
|
||||
margin: 0
|
||||
}
|
||||
});
|
||||
|
||||
export default applyNativeMethods(Picker);
|
||||
|
||||
@@ -17,7 +17,7 @@ import ViewPropTypes from '../View/ViewPropTypes';
|
||||
import React, { Component } from 'react';
|
||||
import { bool, number } from 'prop-types';
|
||||
|
||||
class ProgressBar extends Component {
|
||||
class ProgressBar extends Component<*> {
|
||||
_progressElement: View;
|
||||
|
||||
static displayName = 'ProgressBar';
|
||||
|
||||
@@ -16,7 +16,7 @@ import ViewPropTypes from '../View/ViewPropTypes';
|
||||
import { arrayOf, bool, func, number, oneOf, string } from 'prop-types';
|
||||
import React, { Component } from 'react';
|
||||
|
||||
class RefreshControl extends Component {
|
||||
class RefreshControl extends Component<*> {
|
||||
static propTypes = {
|
||||
...ViewPropTypes,
|
||||
colors: arrayOf(ColorPropType),
|
||||
|
||||
14
src/components/SafeAreaView/index.js
Normal file
14
src/components/SafeAreaView/index.js
Normal file
@@ -0,0 +1,14 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* 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.
|
||||
*
|
||||
* @providesModule SafeAreaView
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import View from '../View';
|
||||
export default View;
|
||||
@@ -48,7 +48,9 @@ const normalizeScrollEvent = e => ({
|
||||
/**
|
||||
* Encapsulates the Web-specific scroll throttling and disabling logic
|
||||
*/
|
||||
export default class ScrollViewBase extends Component {
|
||||
export default class ScrollViewBase extends Component<*> {
|
||||
_viewRef: View;
|
||||
|
||||
static propTypes = {
|
||||
...ViewPropTypes,
|
||||
onMomentumScrollBegin: func,
|
||||
@@ -73,60 +75,10 @@ export default class ScrollViewBase extends Component {
|
||||
_debouncedOnScrollEnd = debounce(this._handleScrollEnd, 100);
|
||||
_state = { isScrolling: false, scrollLastTick: 0 };
|
||||
|
||||
_createPreventableScrollHandler = (handler: Function) => {
|
||||
return (e: Object) => {
|
||||
if (this.props.scrollEnabled) {
|
||||
if (handler) {
|
||||
handler(e);
|
||||
}
|
||||
} else {
|
||||
// To disable scrolling in all browsers except Chrome
|
||||
e.preventDefault();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
_handleScroll = (e: SyntheticEvent) => {
|
||||
e.persist();
|
||||
e.stopPropagation();
|
||||
const { scrollEventThrottle } = this.props;
|
||||
// A scroll happened, so the scroll bumps the debounce.
|
||||
this._debouncedOnScrollEnd(e);
|
||||
if (this._state.isScrolling) {
|
||||
// Scroll last tick may have changed, check if we need to notify
|
||||
if (this._shouldEmitScrollEvent(this._state.scrollLastTick, scrollEventThrottle)) {
|
||||
this._handleScrollTick(e);
|
||||
}
|
||||
} else {
|
||||
// Weren't scrolling, so we must have just started
|
||||
this._handleScrollStart(e);
|
||||
setNativeProps(props: Object) {
|
||||
if (this._viewRef) {
|
||||
this._viewRef.setNativeProps(props);
|
||||
}
|
||||
};
|
||||
|
||||
_handleScrollStart(e: Object) {
|
||||
this._state.isScrolling = true;
|
||||
this._state.scrollLastTick = Date.now();
|
||||
}
|
||||
|
||||
_handleScrollTick(e: Object) {
|
||||
const { onScroll } = this.props;
|
||||
this._state.scrollLastTick = Date.now();
|
||||
if (onScroll) {
|
||||
onScroll(normalizeScrollEvent(e));
|
||||
}
|
||||
}
|
||||
|
||||
_handleScrollEnd(e: Object) {
|
||||
const { onScroll } = this.props;
|
||||
this._state.isScrolling = false;
|
||||
if (onScroll) {
|
||||
onScroll(normalizeScrollEvent(e));
|
||||
}
|
||||
}
|
||||
|
||||
_shouldEmitScrollEvent(lastTick: number, eventThrottle: number) {
|
||||
const timeSinceLastTick = Date.now() - lastTick;
|
||||
return eventThrottle > 0 && timeSinceLastTick >= eventThrottle;
|
||||
}
|
||||
|
||||
render() {
|
||||
@@ -177,10 +129,71 @@ export default class ScrollViewBase extends Component {
|
||||
onScroll={this._handleScroll}
|
||||
onTouchMove={this._createPreventableScrollHandler(this.props.onTouchMove)}
|
||||
onWheel={this._createPreventableScrollHandler(this.props.onWheel)}
|
||||
ref={this._setViewRef}
|
||||
style={[style, !scrollEnabled && styles.scrollDisabled]}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
_createPreventableScrollHandler = (handler: Function) => {
|
||||
return (e: Object) => {
|
||||
if (this.props.scrollEnabled) {
|
||||
if (handler) {
|
||||
handler(e);
|
||||
}
|
||||
} else {
|
||||
// To disable scrolling in all browsers except Chrome
|
||||
e.preventDefault();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
_handleScroll = (e: Object) => {
|
||||
e.persist();
|
||||
e.stopPropagation();
|
||||
const { scrollEventThrottle } = this.props;
|
||||
// A scroll happened, so the scroll bumps the debounce.
|
||||
this._debouncedOnScrollEnd(e);
|
||||
if (this._state.isScrolling) {
|
||||
// Scroll last tick may have changed, check if we need to notify
|
||||
if (this._shouldEmitScrollEvent(this._state.scrollLastTick, scrollEventThrottle)) {
|
||||
this._handleScrollTick(e);
|
||||
}
|
||||
} else {
|
||||
// Weren't scrolling, so we must have just started
|
||||
this._handleScrollStart(e);
|
||||
}
|
||||
};
|
||||
|
||||
_handleScrollStart(e: Object) {
|
||||
this._state.isScrolling = true;
|
||||
this._state.scrollLastTick = Date.now();
|
||||
}
|
||||
|
||||
_handleScrollTick(e: Object) {
|
||||
const { onScroll } = this.props;
|
||||
this._state.scrollLastTick = Date.now();
|
||||
if (onScroll) {
|
||||
onScroll(normalizeScrollEvent(e));
|
||||
}
|
||||
}
|
||||
|
||||
_handleScrollEnd(e: Object) {
|
||||
const { onScroll } = this.props;
|
||||
this._state.isScrolling = false;
|
||||
if (onScroll) {
|
||||
onScroll(normalizeScrollEvent(e));
|
||||
}
|
||||
}
|
||||
|
||||
_setViewRef = (element: View) => {
|
||||
this._viewRef = element;
|
||||
};
|
||||
|
||||
_shouldEmitScrollEvent(lastTick: number, eventThrottle: number) {
|
||||
const timeSinceLastTick = Date.now() - lastTick;
|
||||
return eventThrottle > 0 && timeSinceLastTick >= eventThrottle;
|
||||
}
|
||||
}
|
||||
|
||||
// Chrome doesn't support e.preventDefault in this case; touch-action must be
|
||||
|
||||
@@ -1,5 +1,14 @@
|
||||
/* eslint-env jasmine, jest */
|
||||
|
||||
import React from 'react';
|
||||
import ScrollView from '..';
|
||||
import { mount } from 'enzyme';
|
||||
|
||||
describe('components/ScrollView', () => {
|
||||
test('NO TEST COVERAGE');
|
||||
test('instance method setNativeProps', () => {
|
||||
const instance = mount(<ScrollView />).instance();
|
||||
expect(() => {
|
||||
instance.setNativeProps();
|
||||
}).not.toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -49,7 +49,9 @@ const ScrollView = createReactClass({
|
||||
},
|
||||
|
||||
setNativeProps(props: Object) {
|
||||
this._scrollViewRef.setNativeProps(props);
|
||||
if (this._scrollViewRef) {
|
||||
this._scrollViewRef.setNativeProps(props);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user