mirror of
https://github.com/zhigang1992/react-native-web.git
synced 2026-04-07 09:28:17 +08:00
Compare commits
68 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
80cb7baf82 | ||
|
|
f08515b1f1 | ||
|
|
8591bf7ce5 | ||
|
|
b7c8f00fcc | ||
|
|
ed81b985a9 | ||
|
|
441dc8efff | ||
|
|
7e8ef5b72c | ||
|
|
641c8c47e0 | ||
|
|
87ead7f64e | ||
|
|
5ed2127175 | ||
|
|
e802026298 | ||
|
|
5d24f4c8fa | ||
|
|
a9f1afc07c | ||
|
|
d185d81560 | ||
|
|
66fa09da8e | ||
|
|
bae4dd806a | ||
|
|
4a680fd9b6 | ||
|
|
e34e4e38d3 | ||
|
|
b23a4f55dc | ||
|
|
26bdf44a4c | ||
|
|
5e98107617 | ||
|
|
86ea0e5eff | ||
|
|
6e02c5690c | ||
|
|
c50d808a2b | ||
|
|
130b10c3f7 | ||
|
|
03ddf074ea | ||
|
|
f201a0347d | ||
|
|
fffbdff6ca | ||
|
|
23e5c8479c | ||
|
|
17e5e374ee | ||
|
|
ef907dce22 | ||
|
|
586f134f76 | ||
|
|
70e2a75b43 | ||
|
|
8756c20ade | ||
|
|
4081d17f25 | ||
|
|
4fa6f77d25 | ||
|
|
17d723559d | ||
|
|
8d80885f5d | ||
|
|
3ca4becc41 | ||
|
|
cc077e9019 | ||
|
|
1225b00cdb | ||
|
|
ed70617e91 | ||
|
|
134114de83 | ||
|
|
08ee7c83bb | ||
|
|
5fad78dcad | ||
|
|
e04343e48e | ||
|
|
5e3a946f8b | ||
|
|
4e3d8dbb02 | ||
|
|
fee909d26a | ||
|
|
9e58a7b5f1 | ||
|
|
20e1febe21 | ||
|
|
ef209ca281 | ||
|
|
a35949fa71 | ||
|
|
f5ac856c2d | ||
|
|
4b557b1e0b | ||
|
|
d4e9d9d256 | ||
|
|
0ff3e91592 | ||
|
|
092d5d12f7 | ||
|
|
507e0d41f5 | ||
|
|
9e863d5402 | ||
|
|
1364b1dfdf | ||
|
|
7f81e313ed | ||
|
|
a1892ec8b8 | ||
|
|
e6232d5980 | ||
|
|
e93a2eb478 | ||
|
|
44ecf1fe87 | ||
|
|
faec2b4a83 | ||
|
|
3677f0dd57 |
@@ -56,7 +56,6 @@
|
||||
"no-dupe-class-members": 2,
|
||||
"no-dupe-keys": 2,
|
||||
"no-duplicate-case": 2,
|
||||
"no-duplicate-imports": 2,
|
||||
"no-empty-character-class": 2,
|
||||
"no-empty-pattern": 2,
|
||||
"no-eval": 2,
|
||||
|
||||
18
.github/CONTRIBUTING.md
vendored
18
.github/CONTRIBUTING.md
vendored
@@ -66,7 +66,7 @@ yarn docs:build
|
||||
To run the performance benchmarks in a browser (opening `./benchmarks/index.html`):
|
||||
|
||||
```
|
||||
yarn benchmarks
|
||||
yarn benchmark
|
||||
```
|
||||
|
||||
## Compile and build
|
||||
@@ -104,13 +104,17 @@ Please open an issue with a proposal for a new feature or refactoring before
|
||||
starting on the work. We don't want you to waste your efforts on a pull request
|
||||
that we won't want to accept.
|
||||
|
||||
## Submitting Changes
|
||||
## Pull requests
|
||||
|
||||
* Open a new issue in the [Issue tracker](https://github.com/necolas/react-native-web/issues).
|
||||
* Fork the repo.
|
||||
* Create a new feature branch based off the `master` branch.
|
||||
* Make sure all tests pass and there are no linting errors.
|
||||
* Submit a pull request, referencing any issues it addresses.
|
||||
**Before submitting a pull request,** please make sure the following is done:
|
||||
|
||||
1. Fork the repository and create your branch from `master`.
|
||||
2. If you've added code that should be tested, add tests!
|
||||
3. If you've changed APIs, update the documentation.
|
||||
4. Ensure the tests pass (`yarn test`).
|
||||
5. Lint and format your code (`yarn fmt && yarn lint`).
|
||||
|
||||
You can now submit a pull request, referencing any issues it addresses.
|
||||
|
||||
Please try to keep your pull request focused in scope and avoid including
|
||||
unrelated commits.
|
||||
|
||||
34
.github/ISSUE_TEMPLATE.md
vendored
34
.github/ISSUE_TEMPLATE.md
vendored
@@ -1,30 +1,20 @@
|
||||
<!--
|
||||
React Native for Web is an implementation of React Native. If you have feature
|
||||
requests, you should post them to https://productpains.com/product/react-native/.
|
||||
|
||||
GitHub issues should only be used for bugs or Web-specific features you believe
|
||||
React Native requires.
|
||||
|
||||
Make sure to add ALL the information needed to understand the bug so that
|
||||
someone can help. If the info is missing we'll add the 'needs more information'
|
||||
label and close the issue until there is enough information.
|
||||
-->
|
||||
**Do you want to request a *feature* or report a *bug*?**
|
||||
|
||||
**What is the current behavior?**
|
||||
|
||||
Link to minimal test case: (template: [codepen](https://codepen.io/necolas/pen/PZzwBR?editors=0010))
|
||||
|
||||
**What is the expected behaviour?**
|
||||
|
||||
**Steps to reproduce**
|
||||
**If the current behavior is a bug, please provide the steps to reproduce and
|
||||
if a minimal demo of the problem via Glitch or similar (template:
|
||||
https://glitch.com/edit/#!/react-native-web-playground).**
|
||||
|
||||
1.
|
||||
2.
|
||||
|
||||
**Environment (include versions)**
|
||||
**What is the expected behavior?**
|
||||
|
||||
OS:
|
||||
Device:
|
||||
Browser:
|
||||
React Native for Web (version):
|
||||
React (version):
|
||||
**Environment (include versions). Did this work in previous versions?**
|
||||
|
||||
* OS:
|
||||
* Device:
|
||||
* Browser:
|
||||
* React Native for Web (version):
|
||||
* React (version):
|
||||
|
||||
19
.github/PULL_REQUEST_TEMPLATE.md
vendored
19
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -1,18 +1 @@
|
||||
<!--
|
||||
Thanks for submitting a pull request! Make sure the PR does only one thing.
|
||||
Please provide enough information so that others can review your pull
|
||||
request. Make sure you have read the Contributing Guidelines -
|
||||
https://github.com/necolas/react-native-web/CONTRIBUTING.md
|
||||
-->
|
||||
|
||||
**This patch solves the following problem**
|
||||
|
||||
**Test plan**
|
||||
|
||||
**This pull request**
|
||||
|
||||
- [ ] includes documentation
|
||||
- [ ] includes tests
|
||||
- [ ] includes benchmark reports
|
||||
- [ ] includes an interactive example
|
||||
- [ ] includes screenshots/videos
|
||||
**Before submitting a pull request,** please make sure you have followed the steps the CONTRIBUTING guide.
|
||||
|
||||
40
README.md
40
README.md
@@ -3,7 +3,11 @@
|
||||
[![Build Status][travis-image]][travis-url]
|
||||
[![npm version][npm-image]][npm-url]
|
||||
|
||||
[React Native][react-native-url] components and APIs for the Web.
|
||||
"React Native for Web" brings [React Native][react-native-url]'s
|
||||
building blocks and touch handling to the Web.
|
||||
|
||||
* [UI Explorer and documentation](https://necolas.github.io/react-native-web/storybook/).
|
||||
* [React Native for Web: Playground](https://glitch.com/edit/#!/react-native-web-playground) using create-react-app.
|
||||
|
||||
Browser support: Chrome, Firefox, Safari >= 7, IE 10, Edge.
|
||||
|
||||
@@ -13,31 +17,22 @@ Browser support: Chrome, Firefox, Safari >= 7, IE 10, Edge.
|
||||
[travis-image]: https://travis-ci.org/necolas/react-native-web.svg?branch=master
|
||||
[travis-url]: https://travis-ci.org/necolas/react-native-web
|
||||
|
||||
## Overview
|
||||
|
||||
"React Native for Web" is a project to bring React Native's building blocks and
|
||||
touch handling to the Web.
|
||||
|
||||
Browse the [UI Explorer](https://necolas.github.io/react-native-web/storybook/)
|
||||
to see React Native examples running on Web. Or try it out online with [React
|
||||
Native for Web: Playground](https://www.webpackbin.com/bins/-KgucwxRbn7HRU-V-3Bc).
|
||||
|
||||
## Quick start
|
||||
|
||||
To install in your app:
|
||||
|
||||
```
|
||||
npm install --save react@15.6 react-dom@15.6 react-native-web
|
||||
```
|
||||
|
||||
NOTE: React Native for Web supports React/ReactDOM 15.4, 15.5, or 15.6.
|
||||
|
||||
Install in your existing app using `yarn` or `npm`:
|
||||
|
||||
```
|
||||
yarn add react@15.6 react-dom@15.6 react-native-web
|
||||
```
|
||||
|
||||
Then read the [Getting Started](docs/guides/getting-started.md) guide.
|
||||
|
||||
## Documentation
|
||||
|
||||
The [UI Explorer](https://necolas.github.io/react-native-web/storybook/)
|
||||
interactively documents all the APIs and Components.
|
||||
interactively documents all the supported APIs and Components.
|
||||
|
||||
Guides:
|
||||
|
||||
@@ -49,6 +44,12 @@ Guides:
|
||||
* [Advanced use](docs/guides/advanced.md)
|
||||
* [Known issues](docs/guides/known-issues.md)
|
||||
|
||||
## Starter kits
|
||||
|
||||
* [create-react-app](https://github.com/facebookincubator/create-react-app) ([on Glitch](https://glitch.com/edit/#!/react-native-web-playground))
|
||||
* [react-native-web-starter](https://github.com/grabcode/react-native-web-starter)
|
||||
* [react-native-web-webpack](https://github.com/ndbroadbent/react-native-web-webpack)
|
||||
|
||||
## Example code
|
||||
|
||||
```js
|
||||
@@ -91,12 +92,9 @@ AppRegistry.runApplication('MyApp', { rootTag: document.getElementById('react-ro
|
||||
## Related projects
|
||||
|
||||
* [react-primitives](https://github.com/lelandrichardson/react-primitives/)
|
||||
* [react-native-web-player](https://github.com/dabbott/react-native-web-player)
|
||||
* [react-native-web-starter](https://github.com/grabcode/react-native-web-starter)
|
||||
* [react-native-web-webpack](https://github.com/ndbroadbent/react-native-web-webpack)
|
||||
* [react-sketchapp](https://github.com/airbnb/react-sketchapp)
|
||||
* [react-web](https://github.com/taobaofed/react-web)
|
||||
* [reactxp](https://github.com/microsoft/reactxp)
|
||||
* [react-native-web-player](https://github.com/dabbott/react-native-web-player)
|
||||
|
||||
## License
|
||||
|
||||
|
||||
104
babel/__tests__/__snapshots__/index-test.js.snap
Normal file
104
babel/__tests__/__snapshots__/index-test.js.snap
Normal file
@@ -0,0 +1,104 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`1. Rewrite react-native paths for react-native-web 1`] = `
|
||||
"
|
||||
import { View } from 'react-native';
|
||||
|
||||
↓ ↓ ↓ ↓ ↓ ↓
|
||||
|
||||
import View from 'react-native-web/dist/components/View';
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`2. Rewrite react-native paths for react-native-web 1`] = `
|
||||
"
|
||||
import { Switch, Text, View as MyView } from 'react-native';
|
||||
|
||||
↓ ↓ ↓ ↓ ↓ ↓
|
||||
|
||||
import Switch from 'react-native-web/dist/components/Switch';
|
||||
import Text from 'react-native-web/dist/components/Text';
|
||||
import MyView from 'react-native-web/dist/components/View';
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`3. Rewrite react-native paths for react-native-web 1`] = `
|
||||
"
|
||||
import { createElement, Switch, StyleSheet } from 'react-native';
|
||||
|
||||
↓ ↓ ↓ ↓ ↓ ↓
|
||||
|
||||
import createElement from 'react-native-web/dist/modules/createElement';
|
||||
import Switch from 'react-native-web/dist/components/Switch';
|
||||
import StyleSheet from 'react-native-web/dist/apis/StyleSheet';
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`4. Rewrite react-native paths for react-native-web 1`] = `
|
||||
"
|
||||
import { InvalidThing, TouchableOpacity } from 'react-native';
|
||||
|
||||
↓ ↓ ↓ ↓ ↓ ↓
|
||||
|
||||
import { InvalidThing } from 'react-native-web';
|
||||
import TouchableOpacity from 'react-native-web/dist/components/Touchable/TouchableOpacity';
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`5. Rewrite react-native paths for react-native-web 1`] = `
|
||||
"
|
||||
import * as RNW from 'react-native';
|
||||
|
||||
↓ ↓ ↓ ↓ ↓ ↓
|
||||
|
||||
import * as RNW from 'react-native-web';
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`6. Rewrite react-native paths for react-native-web 1`] = `
|
||||
"
|
||||
const { View } = require('react-native');
|
||||
|
||||
↓ ↓ ↓ ↓ ↓ ↓
|
||||
|
||||
const View = require('react-native-web/dist/components/View');
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`7. Rewrite react-native paths for react-native-web 1`] = `
|
||||
"
|
||||
let { Switch, Text, View: MyView } = require('react-native');
|
||||
|
||||
↓ ↓ ↓ ↓ ↓ ↓
|
||||
|
||||
let Switch = require('react-native-web/dist/components/Switch');
|
||||
|
||||
let Text = require('react-native-web/dist/components/Text');
|
||||
|
||||
let MyView = require('react-native-web/dist/components/View');
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`8. Rewrite react-native paths for react-native-web 1`] = `
|
||||
"
|
||||
var { createElement, Switch, StyleSheet } = require('react-native');
|
||||
|
||||
↓ ↓ ↓ ↓ ↓ ↓
|
||||
|
||||
var createElement = require('react-native-web/dist/modules/createElement');
|
||||
|
||||
var Switch = require('react-native-web/dist/components/Switch');
|
||||
|
||||
var StyleSheet = require('react-native-web/dist/apis/StyleSheet');
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`9. Rewrite react-native paths for react-native-web 1`] = `
|
||||
"
|
||||
const { InvalidThing, TouchableOpacity } = require('react-native');
|
||||
|
||||
↓ ↓ ↓ ↓ ↓ ↓
|
||||
|
||||
const TouchableOpacity = require('react-native-web/dist/components/Touchable/TouchableOpacity');
|
||||
"
|
||||
`;
|
||||
39
babel/__tests__/index-test.js
Normal file
39
babel/__tests__/index-test.js
Normal file
@@ -0,0 +1,39 @@
|
||||
const plugin = require('..');
|
||||
const pluginTester = require('babel-plugin-tester');
|
||||
|
||||
pluginTester({
|
||||
plugin,
|
||||
snapshot: true,
|
||||
tests: [
|
||||
// import react-native
|
||||
"import { View } from 'react-native';",
|
||||
"import { Switch, Text, View as MyView } from 'react-native';",
|
||||
"import { createElement, Switch, StyleSheet } from 'react-native';",
|
||||
"import { InvalidThing, TouchableOpacity } from 'react-native';",
|
||||
"import * as RNW from 'react-native';",
|
||||
|
||||
// import react-native-web
|
||||
// "import { View } from 'react-native-web';",
|
||||
// "import { Switch, Text, View as MyView } from 'react-native-web';",
|
||||
// "import { createElement, Switch, StyleSheet } from 'react-native-web';",
|
||||
// "import { InvalidThing, TouchableOpacity } from 'react-native-web';",
|
||||
// "import * as RNW from 'react-native-web';",
|
||||
|
||||
// require react-native
|
||||
"const { View } = require('react-native');",
|
||||
"let { Switch, Text, View: MyView } = require('react-native');",
|
||||
"var { createElement, Switch, StyleSheet } = require('react-native');",
|
||||
"const { InvalidThing, TouchableOpacity } = require('react-native');",
|
||||
|
||||
// require react-native-web
|
||||
// "const { View } = require('react-native-web');",
|
||||
// "let { Switch, Text, View: MyView } = require('react-native-web');",
|
||||
// "var { createElement, Switch, StyleSheet } = require('react-native-web');",
|
||||
// "const { InvalidThing, TouchableOpacity } = require('react-native-web');",
|
||||
{
|
||||
code: "const RNW = require('react-native');",
|
||||
output: "const RNW = require('react-native');",
|
||||
snapshot: false
|
||||
}
|
||||
]
|
||||
});
|
||||
148
babel/index.js
Normal file
148
babel/index.js
Normal file
@@ -0,0 +1,148 @@
|
||||
const getDistLocation = importName => {
|
||||
const root = 'react-native-web/dist';
|
||||
|
||||
switch (importName) {
|
||||
// apis
|
||||
case 'Animated':
|
||||
case 'AppRegistry':
|
||||
case 'AppState':
|
||||
case 'AsyncStorage':
|
||||
case 'BackAndroid':
|
||||
case 'Clipboard':
|
||||
case 'Dimensions':
|
||||
case 'Easing':
|
||||
case 'I18nManager':
|
||||
case 'InteractionManager':
|
||||
case 'Keyboard':
|
||||
case 'Linking':
|
||||
case 'NetInfo':
|
||||
case 'PanResponder':
|
||||
case 'PixelRatio':
|
||||
case 'Platform':
|
||||
case 'StyleSheet':
|
||||
case 'UIManager':
|
||||
case 'Vibration': {
|
||||
return `${root}/apis/${importName}`;
|
||||
}
|
||||
|
||||
// components
|
||||
case 'ActivityIndicator':
|
||||
case 'Button':
|
||||
case 'FlatList':
|
||||
case 'Image':
|
||||
case 'KeyboardAvoidingView':
|
||||
case 'ListView':
|
||||
case 'Modal':
|
||||
case 'Picker':
|
||||
case 'ProgressBar':
|
||||
case 'RefreshControl':
|
||||
case 'ScrollView':
|
||||
case 'SectionList':
|
||||
case 'Slider':
|
||||
case 'StatusBar':
|
||||
case 'Switch':
|
||||
case 'Text':
|
||||
case 'TextInput':
|
||||
case 'View':
|
||||
case 'VirtualizedList': {
|
||||
return `${root}/components/${importName}`;
|
||||
}
|
||||
|
||||
case 'Touchable':
|
||||
case 'TouchableHighlight':
|
||||
case 'TouchableNativeFeedback':
|
||||
case 'TouchableOpacity':
|
||||
case 'TouchableWithoutFeedback': {
|
||||
return `${root}/components/Touchable/${importName}`;
|
||||
}
|
||||
|
||||
// modules
|
||||
case 'createElement':
|
||||
case 'findNodeHandle':
|
||||
case 'NativeModules':
|
||||
case 'processColor':
|
||||
case 'render':
|
||||
case 'unmountComponentAtNode': {
|
||||
return `${root}/modules/${importName}`;
|
||||
}
|
||||
|
||||
// propTypes
|
||||
case 'ColorPropType':
|
||||
case 'EdgeInsetsPropType':
|
||||
case 'PointPropType':
|
||||
case 'TextPropTypes':
|
||||
case 'ViewPropTypes': {
|
||||
return `${root}/propTypes/${importName}`;
|
||||
}
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
const isReactNativeRequire = (t, node) => {
|
||||
const { declarations } = node;
|
||||
if (declarations.length > 1) {
|
||||
return false;
|
||||
}
|
||||
const { id, init } = declarations[0];
|
||||
return (
|
||||
t.isObjectPattern(id) &&
|
||||
t.isCallExpression(init) &&
|
||||
t.isIdentifier(init.callee) &&
|
||||
init.callee.name === 'require' &&
|
||||
init.arguments.length === 1 &&
|
||||
init.arguments[0].value === 'react-native'
|
||||
);
|
||||
};
|
||||
|
||||
module.exports = function({ types: t }) {
|
||||
return {
|
||||
name: 'Rewrite react-native paths for react-native-web',
|
||||
visitor: {
|
||||
ImportDeclaration(path) {
|
||||
const { source, specifiers } = path.node;
|
||||
if (source.value === 'react-native' && specifiers.length) {
|
||||
const imports = specifiers
|
||||
.map(specifier => {
|
||||
if (t.isImportSpecifier(specifier)) {
|
||||
const importName = specifier.imported.name;
|
||||
const distLocation = getDistLocation(importName);
|
||||
|
||||
if (distLocation) {
|
||||
return t.importDeclaration(
|
||||
[t.importDefaultSpecifier(t.identifier(specifier.local.name))],
|
||||
t.stringLiteral(distLocation)
|
||||
);
|
||||
}
|
||||
}
|
||||
return t.importDeclaration([specifier], t.stringLiteral('react-native-web'));
|
||||
})
|
||||
.filter(Boolean);
|
||||
|
||||
path.replaceWithMultiple(imports);
|
||||
}
|
||||
},
|
||||
VariableDeclaration(path) {
|
||||
if (isReactNativeRequire(t, path.node)) {
|
||||
const { id } = path.node.declarations[0];
|
||||
const imports = id.properties
|
||||
.map(identifier => {
|
||||
const distLocation = getDistLocation(identifier.key.name);
|
||||
if (distLocation) {
|
||||
return t.variableDeclaration(path.node.kind, [
|
||||
t.variableDeclarator(
|
||||
t.identifier(identifier.value.name),
|
||||
t.callExpression(t.identifier('require'), [t.stringLiteral(distLocation)])
|
||||
)
|
||||
]);
|
||||
}
|
||||
})
|
||||
.filter(Boolean);
|
||||
|
||||
path.replaceWithMultiple(imports);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
@@ -7,6 +7,9 @@ npm run build:performance
|
||||
open ./performance/index.html
|
||||
```
|
||||
|
||||
Append `?fastest` to the URL to include the fastest "other libraries", and
|
||||
`?all` to include all the "other libraries".
|
||||
|
||||
## Notes
|
||||
|
||||
The components used in the render benchmarks are simple enough to be
|
||||
@@ -24,24 +27,26 @@ Typical render timings*: mean ± two standard deviations.
|
||||
|
||||
| Implementation | Deep tree (ms) | Wide tree (ms) | Tweets (ms) |
|
||||
| :--- | ---: | ---: | ---: |
|
||||
| `css-modules` | `94.96` `±31.01` | `200.43` `±38.90` | |
|
||||
| `react-native-web/stylesheet@0.0.107` | `98.58` `±10.83` | `218.59` `±36.52` | |
|
||||
| `react-native-web@0.0.107` | `117.45` `±18.76` | `288.27` `±33.50` | `15.10` `±5.45ms` |
|
||||
| `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` |
|
||||
|
||||
Other libraries
|
||||
|
||||
| Implementation | Deep tree (ms) | Wide tree (ms) |
|
||||
| :--- | ---: | ---: |
|
||||
| `styletron@2.5.1` | `90.38` `±15.15` | `197.40` `±29.02` |
|
||||
| `aphrodite@1.2.0` | `88.65` `±19.62` | `187.35` `±24.60` |
|
||||
| `glamor@3.0.0-1` | `145.64` `±21.93` | `283.60` `±23.26` |
|
||||
| `react-jss@5.4.1` | `143.17` `±19.14` | `361.80` `±33.39` |
|
||||
| `reactxp@0.34.3` | `227.18` `±28.75` | `496.08` `±59.96` |
|
||||
| `styled-components@2.1.0` | `262.85` `±46.12` | `578.43` `±35.86` |
|
||||
| `styled-components/primitives@2.1.0` | `261.43` `±44.14` | `569.65` `±22.19` |
|
||||
| `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` |
|
||||
|
||||
These results indicate that render performance is not a significant
|
||||
differentiating factor between `aphrodite`, `styletron`, and
|
||||
`react-native-web/stylesheet`.
|
||||
These results indicate that style render performance is not a significant
|
||||
differentiating factor between `aphrodite`, `css-modules`, `react-native-web`,
|
||||
and `styletron`.
|
||||
|
||||
*MacBook Pro (13-inch, Early 2015); 3.1 GHz Intel Core i7; 16 GB 1867 MHz DDR3. Google Chrome 58 (2x CPU slowdown).
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import aphrodite from './src/aphrodite';
|
||||
import cssModules from './src/css-modules';
|
||||
import emotion from './src/emotion';
|
||||
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';
|
||||
@@ -14,6 +16,7 @@ import renderTweet from './tests/renderTweet';
|
||||
import renderWideTree from './tests/renderWideTree';
|
||||
|
||||
const testAll = window.location.search === '?all';
|
||||
const testFastest = window.location.search === '?fastest';
|
||||
|
||||
const coreTests = [
|
||||
() => renderTweet('react-native-web', reactNative),
|
||||
@@ -26,27 +29,41 @@ const coreTests = [
|
||||
() => renderWideTree('react-native-web', reactNative)
|
||||
];
|
||||
|
||||
const fastestTests = [
|
||||
() => renderDeepTree('aphrodite', aphrodite),
|
||||
() => renderWideTree('aphrodite', aphrodite),
|
||||
() => renderDeepTree('styletron', styletron),
|
||||
() => renderWideTree('styletron', styletron)
|
||||
];
|
||||
|
||||
/**
|
||||
* Optionally run tests using other libraries
|
||||
*/
|
||||
const extraTests = [
|
||||
() => renderDeepTree('styletron', styletron),
|
||||
() => renderWideTree('styletron', styletron),
|
||||
() => renderDeepTree('aphrodite', aphrodite),
|
||||
() => renderWideTree('aphrodite', aphrodite),
|
||||
const restTests = [
|
||||
() => renderDeepTree('emotion', emotion),
|
||||
() => renderWideTree('emotion', emotion),
|
||||
() => renderDeepTree('glamor', glamor),
|
||||
() => renderWideTree('glamor', glamor),
|
||||
() => renderDeepTree('react-jss', jss),
|
||||
() => renderWideTree('react-jss', jss),
|
||||
() => renderDeepTree('radium', radium),
|
||||
() => renderWideTree('radium', radium),
|
||||
() => renderDeepTree('reactxp', xp),
|
||||
() => renderWideTree('reactxp', xp),
|
||||
() => renderDeepTree('react-jss', jss),
|
||||
() => renderWideTree('react-jss', jss),
|
||||
() => renderDeepTree('styled-components', styledComponents),
|
||||
() => renderWideTree('styled-components', styledComponents),
|
||||
() => renderDeepTree('styled-components/primitives', styledComponentsPrimitives),
|
||||
() => renderWideTree('styled-components/primitives', styledComponentsPrimitives)
|
||||
];
|
||||
|
||||
const tests = testAll ? coreTests.concat(extraTests) : coreTests;
|
||||
const tests = [...coreTests];
|
||||
if (testFastest) {
|
||||
tests.push(...fastestTests);
|
||||
}
|
||||
if (testAll) {
|
||||
tests.push(...fastestTests);
|
||||
tests.push(...restTests);
|
||||
}
|
||||
|
||||
// run benchmarks
|
||||
tests.reduce((promise, test) => promise.then(test()), Promise.resolve());
|
||||
|
||||
@@ -1,21 +1,22 @@
|
||||
{
|
||||
"name": "performance",
|
||||
"name": "benchmarks",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"aphrodite": "^1.2.1",
|
||||
"aphrodite": "^1.2.3",
|
||||
"classnames": "^2.2.5",
|
||||
"glamor": "^3.0.0-2",
|
||||
"emotion": "^7.2.2",
|
||||
"glamor": "^2.20.40",
|
||||
"marky": "^1.2.0",
|
||||
"react-jss": "^7.0.0-pre.1",
|
||||
"radium": "^0.19.4",
|
||||
"react-jss": "^7.1.0",
|
||||
"react-primitives": "^0.4.3",
|
||||
"reactxp": "0.34.3",
|
||||
"styled-components": "^2.1.1",
|
||||
"reactxp": "^0.42.1",
|
||||
"styled-components": "^2.1.2",
|
||||
"styletron-client": "^2.5.7",
|
||||
"styletron-utils": "^2.5.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"css-loader": "^0.28.4",
|
||||
"react-addons-perf": "^15.4.2",
|
||||
"css-loader": "^0.28.7",
|
||||
"style-loader": "^0.18.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,9 +22,7 @@ class AspectRatio extends PureComponent {
|
||||
return (
|
||||
<View style={[styles.root, style]}>
|
||||
<View style={[styles.shim, { paddingBottom: `${percentage}%` }]} />
|
||||
<View style={StyleSheet.absoluteFill}>
|
||||
{children}
|
||||
</View>
|
||||
<View style={StyleSheet.absoluteFill}>{children}</View>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import React from 'react';
|
||||
import View from '../View/aphrodite';
|
||||
import { StyleSheet } from 'aphrodite';
|
||||
|
||||
const Box = ({ color, fixed = false, layout = 'column', outer = false, ...other }) =>
|
||||
const Box = ({ color, fixed = false, layout = 'column', outer = false, ...other }) => (
|
||||
<View
|
||||
{...other}
|
||||
style={[
|
||||
@@ -12,7 +12,8 @@ const Box = ({ color, fixed = false, layout = 'column', outer = false, ...other
|
||||
layout === 'row' && styles.row,
|
||||
outer && styles.outer
|
||||
]}
|
||||
/>;
|
||||
/>
|
||||
);
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
outer: {
|
||||
|
||||
@@ -4,7 +4,7 @@ import React from 'react';
|
||||
import View from '../View/css-modules';
|
||||
import styles from './styles.css';
|
||||
|
||||
const Box = ({ color, fixed = false, layout = 'column', outer = false, ...other }) =>
|
||||
const Box = ({ color, fixed = false, layout = 'column', outer = false, ...other }) => (
|
||||
<View
|
||||
{...other}
|
||||
className={classnames(styles[`color${color}`], {
|
||||
@@ -12,6 +12,7 @@ const Box = ({ color, fixed = false, layout = 'column', outer = false, ...other
|
||||
[styles.outer]: outer,
|
||||
[styles.row]: layout === 'row'
|
||||
})}
|
||||
/>;
|
||||
/>
|
||||
);
|
||||
|
||||
export default Box;
|
||||
|
||||
48
benchmarks/src/components/Box/emotion.js
Normal file
48
benchmarks/src/components/Box/emotion.js
Normal file
@@ -0,0 +1,48 @@
|
||||
/* eslint-disable react/prop-types */
|
||||
import React from 'react';
|
||||
import View from '../View/emotion';
|
||||
|
||||
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 = {
|
||||
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;
|
||||
@@ -2,7 +2,7 @@
|
||||
import React from 'react';
|
||||
import View from '../View/glamor';
|
||||
|
||||
const Box = ({ color, fixed = false, layout = 'column', outer = false, ...other }) =>
|
||||
const Box = ({ color, fixed = false, layout = 'column', outer = false, ...other }) => (
|
||||
<View
|
||||
{...other}
|
||||
style={[
|
||||
@@ -11,7 +11,8 @@ const Box = ({ color, fixed = false, layout = 'column', outer = false, ...other
|
||||
layout === 'row' && styles.row,
|
||||
outer && styles.outer
|
||||
]}
|
||||
/>;
|
||||
/>
|
||||
);
|
||||
|
||||
const styles = {
|
||||
outer: {
|
||||
|
||||
@@ -4,7 +4,7 @@ import injectSheet from 'react-jss';
|
||||
import React from 'react';
|
||||
import View from '../View/jss';
|
||||
|
||||
const Box = ({ classes, color, fixed = false, layout = 'column', outer = false, ...other }) =>
|
||||
const Box = ({ classes, color, fixed = false, layout = 'column', outer = false, ...other }) => (
|
||||
<View
|
||||
{...other}
|
||||
className={classnames({
|
||||
@@ -13,7 +13,8 @@ const Box = ({ classes, color, fixed = false, layout = 'column', outer = false,
|
||||
[classes.row]: layout === 'row',
|
||||
[classes.outer]: outer
|
||||
})}
|
||||
/>;
|
||||
/>
|
||||
);
|
||||
|
||||
const styles = {
|
||||
outer: {
|
||||
|
||||
49
benchmarks/src/components/Box/radium.js
Normal file
49
benchmarks/src/components/Box/radium.js
Normal file
@@ -0,0 +1,49 @@
|
||||
/* eslint-disable react/prop-types */
|
||||
import Radium from 'radium';
|
||||
import React from 'react';
|
||||
import View from '../View/radium';
|
||||
|
||||
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 = {
|
||||
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 Radium(Box);
|
||||
@@ -3,7 +3,7 @@ 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 }) =>
|
||||
const Box = ({ color, fixed = false, layout = 'column', outer = false, ...other }) => (
|
||||
<View
|
||||
{...other}
|
||||
style={[
|
||||
@@ -12,7 +12,8 @@ const Box = ({ color, fixed = false, layout = 'column', outer = false, ...other
|
||||
layout === 'row' && styles.row,
|
||||
outer && styles.outer
|
||||
]}
|
||||
/>;
|
||||
/>
|
||||
);
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
outer: {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import React from 'react';
|
||||
import { StyleSheet, View } from 'react-native';
|
||||
|
||||
const Box = ({ color, fixed = false, layout = 'column', outer = false, ...other }) =>
|
||||
const Box = ({ color, fixed = false, layout = 'column', outer = false, ...other }) => (
|
||||
<View
|
||||
{...other}
|
||||
style={[
|
||||
@@ -11,7 +11,8 @@ const Box = ({ color, fixed = false, layout = 'column', outer = false, ...other
|
||||
layout === 'row' && styles.row,
|
||||
outer && styles.outer
|
||||
]}
|
||||
/>;
|
||||
/>
|
||||
);
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
outer: {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import React from 'react';
|
||||
import { Styles, View } from 'reactxp';
|
||||
|
||||
const Box = ({ color, fixed = false, layout = 'column', outer = false, ...other }) =>
|
||||
const Box = ({ color, fixed = false, layout = 'column', outer = false, ...other }) => (
|
||||
<View
|
||||
{...other}
|
||||
style={[
|
||||
@@ -11,7 +11,8 @@ const Box = ({ color, fixed = false, layout = 'column', outer = false, ...other
|
||||
layout === 'row' && styles.row,
|
||||
outer && styles.outer
|
||||
]}
|
||||
/>;
|
||||
/>
|
||||
);
|
||||
|
||||
const styles = {
|
||||
outer: Styles.createViewStyle({
|
||||
|
||||
@@ -3,7 +3,7 @@ import { injectStylePrefixed } from 'styletron-utils';
|
||||
import React from 'react';
|
||||
import View, { styletron } from '../View/styletron';
|
||||
|
||||
const Box = ({ color, fixed = false, layout = 'column', outer = false, ...other }) =>
|
||||
const Box = ({ color, fixed = false, layout = 'column', outer = false, ...other }) => (
|
||||
<View
|
||||
{...other}
|
||||
style={[
|
||||
@@ -12,7 +12,8 @@ const Box = ({ color, fixed = false, layout = 'column', outer = false, ...other
|
||||
layout === 'row' && styles.row,
|
||||
outer && styles.outer
|
||||
]}
|
||||
/>;
|
||||
/>
|
||||
);
|
||||
|
||||
const styles = {
|
||||
outer: injectStylePrefixed(styletron, {
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { createDOMElement } from 'react-native';
|
||||
/* eslint-disable react/prop-types */
|
||||
import { createElement } from 'react-native';
|
||||
import React from 'react';
|
||||
import styles from './styles';
|
||||
|
||||
const IconDirectMessage = props =>
|
||||
createDOMElement('svg', {
|
||||
createElement('svg', {
|
||||
children: (
|
||||
<g>
|
||||
<path d="M43.34 14H12.66L28 27.946z" />
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { createDOMElement } from 'react-native';
|
||||
/* eslint-disable react/prop-types */
|
||||
import { createElement } from 'react-native';
|
||||
import React from 'react';
|
||||
import styles from './styles';
|
||||
|
||||
const IconHeart = props =>
|
||||
createDOMElement('svg', {
|
||||
createElement('svg', {
|
||||
children: (
|
||||
<g>
|
||||
<path d="M38.723 12c-7.187 0-11.16 7.306-11.723 8.131C26.437 19.306 22.504 12 15.277 12 8.791 12 3.533 18.163 3.533 24.647 3.533 39.964 21.891 55.907 27 56c5.109-.093 23.467-16.036 23.467-31.353C50.467 18.163 45.209 12 38.723 12z" />
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { createDOMElement } from 'react-native';
|
||||
/* eslint-disable react/prop-types */
|
||||
import { createElement } from 'react-native';
|
||||
import React from 'react';
|
||||
import styles from './styles';
|
||||
|
||||
const IconReply = props =>
|
||||
createDOMElement('svg', {
|
||||
createElement('svg', {
|
||||
children: (
|
||||
<g>
|
||||
<path d="M41 31h-9V19a2.999 2.999 0 0 0-4.817-2.386l-21 16a3 3 0 0 0-.001 4.773l21 16a3.006 3.006 0 0 0 3.15.301A2.997 2.997 0 0 0 32 51V39h9c5.514 0 10 4.486 10 10a4 4 0 0 0 8 0c0-9.925-8.075-18-18-18z" />
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { createDOMElement } from 'react-native';
|
||||
/* eslint-disable react/prop-types */
|
||||
import { createElement } from 'react-native';
|
||||
import React from 'react';
|
||||
import styles from './styles';
|
||||
|
||||
const IconRetweet = props =>
|
||||
createDOMElement('svg', {
|
||||
createElement('svg', {
|
||||
children: (
|
||||
<g>
|
||||
<path d="M70.676 36.644A3 3 0 0 0 68 35h-7V19a4 4 0 0 0-4-4H34a4 4 0 0 0 0 8h18a1 1 0 0 1 1 .998V35h-7a3.001 3.001 0 0 0-2.419 4.775l11 15a3.003 3.003 0 0 0 4.839-.001l11-15a3.001 3.001 0 0 0 .256-3.13zM40.001 48H22a.995.995 0 0 1-.992-.96L21.001 36h7a3.001 3.001 0 0 0 2.419-4.775l-11-15a3.003 3.003 0 0 0-4.839.001l-11 15A3 3 0 0 0 6.001 36h7l.011 16.003a4 4 0 0 0 4 3.997h22.989a4 4 0 0 0 0-8z" />
|
||||
|
||||
@@ -10,6 +10,24 @@ class DeepTree extends Component {
|
||||
wrap: PropTypes.number.isRequired
|
||||
};
|
||||
|
||||
/* necessary for reactxp to work without errors */
|
||||
static childContextTypes = {
|
||||
focusManager: PropTypes.object
|
||||
};
|
||||
|
||||
getChildContext() {
|
||||
return {
|
||||
focusManager: {
|
||||
addFocusableComponent() {},
|
||||
removeFocusableComponent() {},
|
||||
restrictFocusWithin() {},
|
||||
removeFocusRestriction() {},
|
||||
limitFocusWithin() {},
|
||||
removeFocusLimitation() {}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
render() {
|
||||
const { breadth, components, depth, id, wrap } = this.props;
|
||||
const { Box } = components;
|
||||
@@ -18,7 +36,7 @@ class DeepTree extends Component {
|
||||
<Box color={id % 3} components={components} layout={depth % 2 === 0 ? 'column' : 'row'} outer>
|
||||
{depth === 0 && <Box color={id % 3 + 3} components={components} fixed />}
|
||||
{depth !== 0 &&
|
||||
Array.from({ length: breadth }).map((el, i) =>
|
||||
Array.from({ length: breadth }).map((el, i) => (
|
||||
<DeepTree
|
||||
breadth={breadth}
|
||||
components={components}
|
||||
@@ -27,15 +45,11 @@ class DeepTree extends Component {
|
||||
key={i}
|
||||
wrap={wrap}
|
||||
/>
|
||||
)}
|
||||
))}
|
||||
</Box>
|
||||
);
|
||||
for (let i = 0; i < wrap; i++) {
|
||||
result = (
|
||||
<Box components={components}>
|
||||
{result}
|
||||
</Box>
|
||||
);
|
||||
result = <Box components={components}>{result}</Box>;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -51,17 +51,17 @@ export class Tweet extends Component {
|
||||
<TweetText displayMode={'links'} lang={lang} textParts={textParts} />
|
||||
</View>
|
||||
|
||||
{media
|
||||
? <View style={styles.richContent}>
|
||||
<AspectRatio ratio={16 / 9}>
|
||||
<Image
|
||||
resizeMode={Image.resizeMode.cover}
|
||||
source={media.source}
|
||||
style={styles.media}
|
||||
/>
|
||||
</AspectRatio>
|
||||
</View>
|
||||
: null}
|
||||
{media ? (
|
||||
<View style={styles.richContent}>
|
||||
<AspectRatio ratio={16 / 9}>
|
||||
<Image
|
||||
resizeMode={Image.resizeMode.cover}
|
||||
source={media.source}
|
||||
style={styles.media}
|
||||
/>
|
||||
</AspectRatio>
|
||||
</View>
|
||||
) : null}
|
||||
</View>
|
||||
|
||||
<TweetActionsBar
|
||||
|
||||
@@ -46,11 +46,7 @@ export default class TweetAction extends React.Component {
|
||||
]}
|
||||
>
|
||||
{getIcon(displayMode, highlighted)}
|
||||
{count > 0
|
||||
? <Text style={styles.count}>
|
||||
{count}
|
||||
</Text>
|
||||
: null}
|
||||
{count > 0 ? <Text style={styles.count}>{count}</Text> : null}
|
||||
</Text>
|
||||
</View>
|
||||
);
|
||||
|
||||
@@ -25,7 +25,7 @@ export default class TweetActionsBar extends PureComponent {
|
||||
/* eslint-disable react/jsx-handler-names */
|
||||
return (
|
||||
<View style={[styles.root, style]}>
|
||||
{actions.map((action, i) =>
|
||||
{actions.map((action, i) => (
|
||||
<TweetAction
|
||||
accessibilityLabel={actions.label}
|
||||
count={action.count}
|
||||
@@ -35,7 +35,7 @@ export default class TweetActionsBar extends PureComponent {
|
||||
onPress={action.onPress}
|
||||
style={styles.action}
|
||||
/>
|
||||
)}
|
||||
))}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -18,9 +18,9 @@ class TweetText extends React.Component {
|
||||
|
||||
return (
|
||||
<AppText {...other} lang={lang} numberOfLines={numberOfLines}>
|
||||
{textParts.map((part, i) =>
|
||||
{textParts.map((part, i) => (
|
||||
<TweetTextPart displayMode={displayMode} key={i} part={part} />
|
||||
)}
|
||||
))}
|
||||
</AppText>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -6,13 +6,14 @@ import theme from '../theme';
|
||||
|
||||
const createTextEntity = ({ part }) => <Text>{`${part.prefix}${part.text}`}</Text>;
|
||||
|
||||
const createTwemojiEntity = ({ part }) =>
|
||||
const createTwemojiEntity = ({ part }) => (
|
||||
<Image
|
||||
accessibilityLabel={part.text}
|
||||
draggable={false}
|
||||
source={{ uri: part.emoji }}
|
||||
style={styles.twemoji}
|
||||
/>;
|
||||
/>
|
||||
);
|
||||
|
||||
// @mention, #hashtag, $cashtag
|
||||
const createSymbolEntity = ({ displayMode, part }) => {
|
||||
|
||||
@@ -23,15 +23,15 @@ class UserAvatar extends PureComponent {
|
||||
|
||||
return (
|
||||
<AspectRatio ratio={1} style={[styles.root, style]}>
|
||||
{uri
|
||||
? <Image
|
||||
accessibilityLabel={accessibilityLabel}
|
||||
onLoad={this._handleLoad}
|
||||
ref={this._setImageRef}
|
||||
source={{ uri }}
|
||||
style={[styles.image, circle && styles.circle]}
|
||||
/>
|
||||
: null}
|
||||
{uri ? (
|
||||
<Image
|
||||
accessibilityLabel={accessibilityLabel}
|
||||
onLoad={this._handleLoad}
|
||||
ref={this._setImageRef}
|
||||
source={{ uri }}
|
||||
style={[styles.image, circle && styles.circle]}
|
||||
/>
|
||||
) : null}
|
||||
</AspectRatio>
|
||||
);
|
||||
}
|
||||
|
||||
29
benchmarks/src/components/View/emotion.js
Normal file
29
benchmarks/src/components/View/emotion.js
Normal file
@@ -0,0 +1,29 @@
|
||||
/* eslint-disable react/prop-types */
|
||||
import { css } from 'emotion';
|
||||
import React from 'react';
|
||||
|
||||
class View extends React.Component {
|
||||
render() {
|
||||
const { style, ...other } = this.props;
|
||||
return <div {...other} className={css([viewStyle, ...style])} />;
|
||||
}
|
||||
}
|
||||
|
||||
const viewStyle = {
|
||||
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;
|
||||
31
benchmarks/src/components/View/radium.js
Normal file
31
benchmarks/src/components/View/radium.js
Normal file
@@ -0,0 +1,31 @@
|
||||
/* eslint-disable react/prop-types */
|
||||
import Radium from 'radium';
|
||||
import React from 'react';
|
||||
|
||||
class View extends React.Component {
|
||||
render() {
|
||||
const { style, ...other } = this.props;
|
||||
return <div {...other} style={[styles.root, style]} />;
|
||||
}
|
||||
}
|
||||
|
||||
const styles = {
|
||||
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 Radium(View);
|
||||
7
benchmarks/src/emotion.js
Normal file
7
benchmarks/src/emotion.js
Normal file
@@ -0,0 +1,7 @@
|
||||
import Box from './components/Box/emotion';
|
||||
import View from './components/View/emotion';
|
||||
|
||||
export default {
|
||||
Box,
|
||||
View
|
||||
};
|
||||
9
benchmarks/src/radium.js
Normal file
9
benchmarks/src/radium.js
Normal file
@@ -0,0 +1,9 @@
|
||||
import Box from './components/Box/radium';
|
||||
import View from './components/View/radium';
|
||||
|
||||
const api = {
|
||||
Box,
|
||||
View
|
||||
};
|
||||
|
||||
export default api;
|
||||
@@ -26,7 +26,9 @@ module.exports = {
|
||||
exclude: /node_modules/,
|
||||
use: {
|
||||
loader: 'babel-loader',
|
||||
options: { cacheDirectory: true }
|
||||
options: {
|
||||
cacheDirectory: true
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@@ -2,6 +2,14 @@
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@types/lodash@^4.14.64", "@types/lodash@^4.14.66":
|
||||
version "4.14.74"
|
||||
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.74.tgz#ac3bd8db988e7f7038e5d22bd76a7ba13f876168"
|
||||
|
||||
abbrev@1:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.0.tgz#d0554c2256636e2f56e7c2e5ad183f859428d81f"
|
||||
|
||||
ajv@^5.0.0:
|
||||
version "5.2.0"
|
||||
resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.2.0.tgz#c1735024c5da2ef75cc190713073d44f098bf486"
|
||||
@@ -37,9 +45,15 @@ ansi-styles@^2.2.1:
|
||||
version "2.2.1"
|
||||
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe"
|
||||
|
||||
aphrodite@^1.2.1:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/aphrodite/-/aphrodite-1.2.1.tgz#a7b5066b198730be7b7a88f78dbefd77d4df5683"
|
||||
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"
|
||||
dependencies:
|
||||
asap "^2.0.3"
|
||||
inline-style-prefixer "^3.0.1"
|
||||
@@ -55,7 +69,15 @@ 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"
|
||||
|
||||
asap@^2.0.3, asap@^2.0.5, asap@~2.0.3:
|
||||
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:
|
||||
version "2.0.6"
|
||||
resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46"
|
||||
|
||||
asap@~2.0.3:
|
||||
version "2.0.5"
|
||||
resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.5.tgz#522765b50c3510490e52d7dcfe085ef9ba96958f"
|
||||
|
||||
@@ -76,6 +98,17 @@ 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"
|
||||
@@ -84,9 +117,25 @@ babel-code-frame@^6.11.0:
|
||||
esutils "^2.0.2"
|
||||
js-tokens "^3.0.0"
|
||||
|
||||
babel-runtime@^6.18.0, babel-runtime@^6.23.0:
|
||||
version "6.23.0"
|
||||
resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.23.0.tgz#0a9489f144de70efb3ce4300accdb329e2fc543b"
|
||||
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"
|
||||
dependencies:
|
||||
autoprefixer "^7.1.2"
|
||||
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"
|
||||
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"
|
||||
@@ -103,10 +152,14 @@ big.js@^3.1.3:
|
||||
version "3.1.3"
|
||||
resolved "https://registry.yarnpkg.com/big.js/-/big.js-3.1.3.tgz#4cada2193652eb3ca9ec8e55c9015669c9806978"
|
||||
|
||||
bowser@^1.0.0, bowser@^1.6.0:
|
||||
bowser@^1.0.0:
|
||||
version "1.6.0"
|
||||
resolved "https://registry.yarnpkg.com/bowser/-/bowser-1.6.0.tgz#37fc387b616cb6aef370dab4d6bd402b74c5c54d"
|
||||
|
||||
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"
|
||||
@@ -118,6 +171,13 @@ 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"
|
||||
@@ -125,6 +185,10 @@ 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"
|
||||
@@ -138,6 +202,10 @@ 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"
|
||||
@@ -148,6 +216,14 @@ 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"
|
||||
@@ -172,7 +248,7 @@ coa@~1.0.1:
|
||||
dependencies:
|
||||
q "^1.1.2"
|
||||
|
||||
color-convert@^1.3.0:
|
||||
color-convert@^1.3.0, color-convert@^1.9.0:
|
||||
version "1.9.0"
|
||||
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.0.tgz#1accf97dd739b983bf994d56fec8f95853641b7a"
|
||||
dependencies:
|
||||
@@ -208,12 +284,6 @@ colors@~1.1.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63"
|
||||
|
||||
common-tags@^1.4.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/common-tags/-/common-tags-1.4.0.tgz#1187be4f3d4cf0c0427d43f74eef1f73501614c0"
|
||||
dependencies:
|
||||
babel-runtime "^6.18.0"
|
||||
|
||||
core-js@^1.0.0:
|
||||
version "1.2.7"
|
||||
resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636"
|
||||
@@ -240,13 +310,13 @@ css-color-names@0.0.4:
|
||||
|
||||
css-in-js-utils@^1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://artifactory.twitter.biz:443/api/npm/js-virtual/css-in-js-utils/-/css-in-js-utils-1.0.3.tgz#9ac7e02f763cf85d94017666565ed68a5b5f3215"
|
||||
resolved "https://registry.yarnpkg.com/css-in-js-utils/-/css-in-js-utils-1.0.3.tgz#9ac7e02f763cf85d94017666565ed68a5b5f3215"
|
||||
dependencies:
|
||||
hyphenate-style-name "^1.0.2"
|
||||
|
||||
css-loader@^0.28.4:
|
||||
version "0.28.4"
|
||||
resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-0.28.4.tgz#6cf3579192ce355e8b38d5f42dd7a1f2ec898d0f"
|
||||
css-loader@^0.28.7:
|
||||
version "0.28.7"
|
||||
resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-0.28.7.tgz#5f2ee989dd32edd907717f953317656160999c1b"
|
||||
dependencies:
|
||||
babel-code-frame "^6.11.0"
|
||||
css-selector-tokenizer "^0.7.0"
|
||||
@@ -261,7 +331,7 @@ css-loader@^0.28.4:
|
||||
postcss-modules-scope "^1.0.0"
|
||||
postcss-modules-values "^1.1.0"
|
||||
postcss-value-parser "^3.3.0"
|
||||
source-list-map "^0.1.7"
|
||||
source-list-map "^2.0.0"
|
||||
|
||||
css-selector-tokenizer@^0.6.0:
|
||||
version "0.6.0"
|
||||
@@ -367,17 +437,43 @@ 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@^7.2.2:
|
||||
version "7.2.2"
|
||||
resolved "https://registry.yarnpkg.com/emotion-utils/-/emotion-utils-7.2.2.tgz#0057927581bdd0877d6d8fb90a6162a15c75b805"
|
||||
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"
|
||||
|
||||
encoding@^0.1.11:
|
||||
version "0.1.12"
|
||||
resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb"
|
||||
dependencies:
|
||||
iconv-lite "~0.4.13"
|
||||
|
||||
escape-string-regexp@^1.0.2:
|
||||
escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
|
||||
|
||||
@@ -389,6 +485,10 @@ esutils@^2.0.2:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b"
|
||||
|
||||
exenv@^1.2.1:
|
||||
version "1.2.2"
|
||||
resolved "https://registry.yarnpkg.com/exenv/-/exenv-1.2.2.tgz#2ae78e85d9894158670b03d47bec1f03bd91bb9d"
|
||||
|
||||
fast-deep-equal@^0.1.0:
|
||||
version "0.1.0"
|
||||
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-0.1.0.tgz#5c6f4599aba6b333ee3342e2ed978672f1001f8d"
|
||||
@@ -397,7 +497,19 @@ fastparse@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/fastparse/-/fastparse-1.1.1.tgz#d1e2643b38a94d7583b479060e6c4affc94071f8"
|
||||
|
||||
fbjs@^0.8.12, fbjs@^0.8.4, fbjs@^0.8.5, fbjs@^0.8.9:
|
||||
fbjs@^0.8.12:
|
||||
version "0.8.14"
|
||||
resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.14.tgz#d1dbe2be254c35a91e09f31f9cd50a40b2a0ed1c"
|
||||
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"
|
||||
dependencies:
|
||||
@@ -421,13 +533,15 @@ function-bind@^1.0.2:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.0.tgz#16176714c801798e4e8f2cf7f7529467bb4a5771"
|
||||
|
||||
glamor@^3.0.0-2:
|
||||
version "3.0.0-2"
|
||||
resolved "https://registry.yarnpkg.com/glamor/-/glamor-3.0.0-2.tgz#cb28eb450a437c63c9911421a4bb74711c473dad"
|
||||
glamor@^2.20.40:
|
||||
version "2.20.40"
|
||||
resolved "https://registry.yarnpkg.com/glamor/-/glamor-2.20.40.tgz#f606660357b7cf18dface731ad1a2cfa93817f05"
|
||||
dependencies:
|
||||
fbjs "^0.8.12"
|
||||
inline-style-prefixer "^3.0.3"
|
||||
react-css-property-operations "^15.4.1"
|
||||
inline-style-prefixer "^3.0.6"
|
||||
object-assign "^4.1.1"
|
||||
prop-types "^15.5.10"
|
||||
through "^2.3.8"
|
||||
|
||||
has-ansi@^2.0.0:
|
||||
version "2.0.0"
|
||||
@@ -498,14 +612,7 @@ inline-style-prefixer@^2.0.1, inline-style-prefixer@^2.0.5:
|
||||
bowser "^1.0.0"
|
||||
hyphenate-style-name "^1.0.1"
|
||||
|
||||
inline-style-prefixer@^3.0.1:
|
||||
version "3.0.2"
|
||||
resolved "https://artifactory.twitter.biz:443/api/npm/js-virtual/inline-style-prefixer/-/inline-style-prefixer-3.0.2.tgz#989865e0c5de7a946acbea71e16e02741efe0dd7"
|
||||
dependencies:
|
||||
bowser "^1.6.0"
|
||||
css-in-js-utils "^1.0.3"
|
||||
|
||||
inline-style-prefixer@^3.0.3, inline-style-prefixer@^3.0.6:
|
||||
inline-style-prefixer@^3.0.1, inline-style-prefixer@^3.0.6:
|
||||
version "3.0.6"
|
||||
resolved "https://registry.yarnpkg.com/inline-style-prefixer/-/inline-style-prefixer-3.0.6.tgz#b27fe309b4168a31eaf38c8e8c60ab9e7c11731f"
|
||||
dependencies:
|
||||
@@ -660,9 +767,9 @@ jss-vendor-prefixer@^6.0.0:
|
||||
dependencies:
|
||||
css-vendor "^0.3.8"
|
||||
|
||||
jss@^8.0.0:
|
||||
version "8.0.0"
|
||||
resolved "https://registry.yarnpkg.com/jss/-/jss-8.0.0.tgz#7b6e3153a5045d396245adc3fad5817d00c59457"
|
||||
jss@^8.1.0:
|
||||
version "8.1.0"
|
||||
resolved "https://registry.yarnpkg.com/jss/-/jss-8.1.0.tgz#b32f15efcce22446dfda4c2be09a04f38431da0a"
|
||||
dependencies:
|
||||
is-in-browser "^1.0.2"
|
||||
warning "^3.0.0"
|
||||
@@ -687,7 +794,7 @@ 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.1, lodash@^4.17.4:
|
||||
version "4.17.4"
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae"
|
||||
|
||||
@@ -726,6 +833,12 @@ node-fetch@^1.0.1:
|
||||
encoding "^0.1.11"
|
||||
is-stream "^1.0.1"
|
||||
|
||||
nopt@~1.0.10:
|
||||
version "1.0.10"
|
||||
resolved "https://registry.yarnpkg.com/nopt/-/nopt-1.0.10.tgz#6ddd21bd2a31417b92727dd585f8a6f37608ebee"
|
||||
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"
|
||||
@@ -812,6 +925,13 @@ 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"
|
||||
@@ -900,6 +1020,13 @@ 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"
|
||||
@@ -943,7 +1070,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.0.0, postcss-selector-parser@^2.2.2, postcss-selector-parser@^2.2.3:
|
||||
version "2.2.3"
|
||||
resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-2.2.3.tgz#f9437788606c3c9acee16ffe8d8b16297f27bb90"
|
||||
dependencies:
|
||||
@@ -997,6 +1124,14 @@ 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"
|
||||
@@ -1007,7 +1142,7 @@ promise@^7.1.1:
|
||||
dependencies:
|
||||
asap "~2.0.3"
|
||||
|
||||
prop-types@^15.5.10, prop-types@^15.5.4, prop-types@^15.5.8:
|
||||
prop-types@^15.5.10, prop-types@^15.5.4, prop-types@^15.5.8, prop-types@^15.5.9:
|
||||
version "15.5.10"
|
||||
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.5.10.tgz#2797dfc3126182e3a95e3dfbb2e893ddd7456154"
|
||||
dependencies:
|
||||
@@ -1025,31 +1160,36 @@ query-string@^4.1.0:
|
||||
object-assign "^4.1.0"
|
||||
strict-uri-encode "^1.0.0"
|
||||
|
||||
react-addons-perf@^15.4.2:
|
||||
version "15.4.2"
|
||||
resolved "https://registry.yarnpkg.com/react-addons-perf/-/react-addons-perf-15.4.2.tgz#110bdcf5c459c4f77cb85ed634bcd3397536383b"
|
||||
radium@^0.19.4:
|
||||
version "0.19.4"
|
||||
resolved "https://registry.yarnpkg.com/radium/-/radium-0.19.4.tgz#56aa49fde6181d2f5e1fa57b4710ffd0c23de820"
|
||||
dependencies:
|
||||
fbjs "^0.8.4"
|
||||
object-assign "^4.1.0"
|
||||
array-find "^1.0.0"
|
||||
exenv "^1.2.1"
|
||||
inline-style-prefixer "^2.0.5"
|
||||
prop-types "^15.5.8"
|
||||
|
||||
react-css-property-operations@^15.4.1:
|
||||
version "15.4.1"
|
||||
resolved "https://registry.yarnpkg.com/react-css-property-operations/-/react-css-property-operations-15.4.1.tgz#4c0e305df4cc35f0f5fd2d65a79214c8b012db35"
|
||||
|
||||
react-jss@^7.0.0-pre.1:
|
||||
version "7.0.0-pre.1"
|
||||
resolved "https://registry.yarnpkg.com/react-jss/-/react-jss-7.0.0-pre.1.tgz#948127be53cd8c9fbd2362e87c1f4a93382aeb26"
|
||||
react-emotion@^7.2.2:
|
||||
version "7.2.2"
|
||||
resolved "https://registry.yarnpkg.com/react-emotion/-/react-emotion-7.2.2.tgz#0401607a0ba011bc16600a2691f5f57cb38ce89d"
|
||||
dependencies:
|
||||
babel-plugin-emotion "^7.2.2"
|
||||
emotion "^7.2.2"
|
||||
emotion-utils "^7.2.2"
|
||||
|
||||
react-jss@^7.1.0:
|
||||
version "7.1.0"
|
||||
resolved "https://registry.yarnpkg.com/react-jss/-/react-jss-7.1.0.tgz#de9430cbe01a82f3b2dcf87a03b798130868ff93"
|
||||
dependencies:
|
||||
common-tags "^1.4.0"
|
||||
hoist-non-react-statics "^1.2.0"
|
||||
jss "^8.0.0"
|
||||
jss "^8.1.0"
|
||||
jss-preset-default "^3.0.0"
|
||||
prop-types "^15.5.8"
|
||||
theming "^1.0.1"
|
||||
theming "^1.1.0"
|
||||
|
||||
react-native-web@0.0.x:
|
||||
version "0.0.106"
|
||||
resolved "https://registry.yarnpkg.com/react-native-web/-/react-native-web-0.0.106.tgz#928427320b5963548b372a32b62459154f1e1d7e"
|
||||
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"
|
||||
@@ -1094,14 +1234,17 @@ react@^15.5.4:
|
||||
object-assign "^4.1.0"
|
||||
prop-types "^15.5.10"
|
||||
|
||||
reactxp@0.34.3:
|
||||
version "0.34.3"
|
||||
resolved "https://registry.yarnpkg.com/reactxp/-/reactxp-0.34.3.tgz#6481992e57758ae6ffffbfde3d497527bb495032"
|
||||
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"
|
||||
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"
|
||||
|
||||
rebound@^0.0.13:
|
||||
@@ -1127,8 +1270,8 @@ regenerate@^1.2.1:
|
||||
resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.3.2.tgz#d1941c67bad437e1be76433add5b385f95b19260"
|
||||
|
||||
regenerator-runtime@^0.10.0:
|
||||
version "0.10.3"
|
||||
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.3.tgz#8c4367a904b51ea62a908ac310bf99ff90a82a3e"
|
||||
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"
|
||||
@@ -1168,14 +1311,18 @@ sort-keys@^1.0.0:
|
||||
dependencies:
|
||||
is-plain-obj "^1.0.0"
|
||||
|
||||
source-list-map@^0.1.7:
|
||||
version "0.1.8"
|
||||
resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-0.1.8.tgz#c550b2ab5427f6b3f21f5afead88c4f5587b2106"
|
||||
source-list-map@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.0.tgz#aaa47403f7b245a92fbc97ea08f250d6087ed085"
|
||||
|
||||
source-map@^0.5.3, source-map@^0.5.6:
|
||||
version "0.5.6"
|
||||
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412"
|
||||
|
||||
source-map@^0.5.7:
|
||||
version "0.5.7"
|
||||
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
|
||||
|
||||
sprintf-js@~1.0.2:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
|
||||
@@ -1186,7 +1333,7 @@ strict-uri-encode@^1.0.0:
|
||||
|
||||
string-hash@^1.1.3:
|
||||
version "1.1.3"
|
||||
resolved "https://artifactory.twitter.biz:443/api/npm/js-virtual/string-hash/-/string-hash-1.1.3.tgz#e8aafc0ac1855b4666929ed7dd1275df5d6c811b"
|
||||
resolved "https://registry.yarnpkg.com/string-hash/-/string-hash-1.1.3.tgz#e8aafc0ac1855b4666929ed7dd1275df5d6c811b"
|
||||
|
||||
strip-ansi@^3.0.0:
|
||||
version "3.0.1"
|
||||
@@ -1201,9 +1348,9 @@ style-loader@^0.18.2:
|
||||
loader-utils "^1.0.2"
|
||||
schema-utils "^0.3.0"
|
||||
|
||||
styled-components@^2.1.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-2.1.1.tgz#7e9b5bc319ee3963b47aebb74f4658119ea9d484"
|
||||
styled-components@^2.1.2:
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-2.1.2.tgz#bb419978e1287c5d0d88fa9106b2dd75f66a324c"
|
||||
dependencies:
|
||||
buffer "^5.0.3"
|
||||
css-to-react-native "^2.0.3"
|
||||
@@ -1235,6 +1382,13 @@ stylis@^3.2.1:
|
||||
version "3.2.3"
|
||||
resolved "https://registry.yarnpkg.com/stylis/-/stylis-3.2.3.tgz#fed751d792af3f48a247769f55aca05c1a100a09"
|
||||
|
||||
subscribableevent@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/subscribableevent/-/subscribableevent-1.0.0.tgz#bde9500fa9009c7740c924109bac6119cd9898e6"
|
||||
dependencies:
|
||||
"@types/lodash" "^4.14.64"
|
||||
lodash "^4.17.4"
|
||||
|
||||
supports-color@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"
|
||||
@@ -1251,6 +1405,12 @@ 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"
|
||||
@@ -1267,9 +1427,9 @@ synctasks@^0.2.9:
|
||||
version "0.2.17"
|
||||
resolved "https://registry.yarnpkg.com/synctasks/-/synctasks-0.2.17.tgz#38852f008878de2e941b6e458ddf552245268da1"
|
||||
|
||||
theming@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/theming/-/theming-1.0.1.tgz#a3838c9de635e2f29fc9cd3dea4bf68d3c5a650a"
|
||||
theming@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/theming/-/theming-1.1.0.tgz#0562760b55a1b919c2d5eeb94130351f8958e13a"
|
||||
dependencies:
|
||||
brcast "^2.0.0"
|
||||
is-function "^1.0.1"
|
||||
@@ -1277,6 +1437,16 @@ theming@^1.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"
|
||||
|
||||
touch@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/touch/-/touch-1.0.0.tgz#449cbe2dbae5a8c8038e30d71fa0ff464947c4de"
|
||||
dependencies:
|
||||
nopt "~1.0.10"
|
||||
|
||||
ua-parser-js@^0.7.9:
|
||||
version "0.7.12"
|
||||
resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.12.tgz#04c81a99bdd5dc52263ea29d24c6bf8d4818a4bb"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
## Use with existing React DOM components
|
||||
|
||||
React Native for Web exports a web-specific module called `createDOMElement`,
|
||||
React Native for Web exports a web-specific module called `createElement`,
|
||||
which can be used to wrap React DOM components. This allows you to use React
|
||||
Native's accessibility and style optimizations.
|
||||
|
||||
@@ -11,9 +11,8 @@ In the example below, `Video` will now accept common React Native props such as
|
||||
props.
|
||||
|
||||
```js
|
||||
import { createDOMElement } from 'react-native';
|
||||
|
||||
const Video = (props) => createDOMElement('video', props);
|
||||
import { createElement } from 'react-native-web';
|
||||
const Video = (props) => createElement('video', props);
|
||||
```
|
||||
|
||||
This also works with composite components defined in your existing component
|
||||
@@ -21,9 +20,10 @@ gallery or dependencies ([live example](https://www.webpackbin.com/bins/-KiTSGFw
|
||||
|
||||
```js
|
||||
import RaisedButton from 'material-ui/RaisedButton';
|
||||
import { createDOMElement, StyleSheet } from 'react-native';
|
||||
import { createElement } from 'react-native-web';
|
||||
import { StyleSheet } from 'react-native';
|
||||
|
||||
const CustomButton = (props) => createDOMElement(RaisedButton, {
|
||||
const CustomButton = (props) => createElement(RaisedButton, {
|
||||
...props,
|
||||
style: [ styles.button, props.style ]
|
||||
});
|
||||
@@ -35,6 +35,14 @@ const styles = StyleSheet.create({
|
||||
});
|
||||
```
|
||||
|
||||
And `createElement` can be used as drop-in replacement for `React.createElement`:
|
||||
|
||||
```js
|
||||
/* @jsx createElement */
|
||||
import { createElement } from 'react-native-web';
|
||||
const Video = (props) => <video {...props} style={[ { marginVertical: 10 }, props.style ]} />
|
||||
```
|
||||
|
||||
Remember that React Native styles are not the same as React DOM styles, and
|
||||
care needs to be taken not to pass React DOM styles into your React Native
|
||||
wrapped components.
|
||||
@@ -47,7 +55,8 @@ an API inspired by styled-components ([live
|
||||
example](https://www.webpackbin.com/bins/-KjT9ziwv4O7FDZdvsnX)).
|
||||
|
||||
```js
|
||||
const { createDOMElement, StyleSheet } = ReactNative;
|
||||
import { createElement } from 'react-native-web';
|
||||
import { StyleSheet } from 'react-native';
|
||||
|
||||
/**
|
||||
* styled API
|
||||
@@ -69,7 +78,7 @@ const styled = (Component, styler) => {
|
||||
|
||||
return (
|
||||
isDOMComponent
|
||||
? createDOMElement(Component, nextProps)
|
||||
? createElement(Component, nextProps)
|
||||
: <Component {...nextProps} />
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,25 +1,22 @@
|
||||
# Getting started
|
||||
|
||||
This guide will help you to correctly configure build and test tools to work
|
||||
with React Native for Web.
|
||||
|
||||
Alternatively, you can quickly setup a local project using
|
||||
[create-react-app](https://github.com/facebookincubator/create-react-app)
|
||||
(which supports `react-native-web` out-of-the-box once installed),
|
||||
[react-native-web-starter](https://github.com/grabcode/react-native-web-starter),
|
||||
or [react-native-web-webpack](https://github.com/ndbroadbent/react-native-web-webpack).
|
||||
with React Native for Web. (Alternatively, you can quickly setup a local
|
||||
project using the starter kits listed in the README.)
|
||||
|
||||
It is recommended that your application provide a `Promise` and `Array.from`
|
||||
polyfill.
|
||||
|
||||
## Webpack and Babel
|
||||
## 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.
|
||||
|
||||
Create a `web/webpack.config.js` file:
|
||||
|
||||
```js
|
||||
// webpack.config.js
|
||||
// web/webpack.config.js
|
||||
|
||||
// This is needed for webpack to compile JavaScript.
|
||||
// Many OSS React Native packages are not compiled to ES5 before being
|
||||
@@ -37,7 +34,10 @@ const babelLoaderConfiguration = {
|
||||
loader: 'babel-loader',
|
||||
options: {
|
||||
cacheDirectory: true,
|
||||
// The 'react-native' preset is recommended
|
||||
// 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)
|
||||
presets: ['react-native']
|
||||
}
|
||||
}
|
||||
@@ -66,17 +66,14 @@ module.exports = {
|
||||
|
||||
plugins: [
|
||||
// `process.env.NODE_ENV === 'production'` must be `true` for production
|
||||
// builds to eliminate development checks and reduce build size.
|
||||
// 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')
|
||||
})
|
||||
],
|
||||
|
||||
resolve: {
|
||||
// Maps the 'react-native' import to 'react-native-web'.
|
||||
alias: {
|
||||
'react-native': 'react-native-web'
|
||||
},
|
||||
// If you're working on a multi-platform React Native app, web-specific
|
||||
// module implementations should be written in files using the extension
|
||||
// `.web.js`.
|
||||
@@ -85,36 +82,97 @@ module.exports = {
|
||||
}
|
||||
```
|
||||
|
||||
Please refer to the Webpack documentation for more information.
|
||||
|
||||
## Jest
|
||||
|
||||
[Jest](https://facebook.github.io/jest/) also needs to map `react-native` to `react-native-web`.
|
||||
To run in development:
|
||||
|
||||
```
|
||||
"jest": {
|
||||
"moduleNameMapper": {
|
||||
"react-native": "<rootDir>/node_modules/react-native-web"
|
||||
}
|
||||
}
|
||||
./node_modules/.bin/webpack-dev-server -d --config web/webpack.config.js --inline --hot --colors
|
||||
```
|
||||
|
||||
Please refer to the Jest documentation for more information.
|
||||
To build for production:
|
||||
|
||||
```
|
||||
./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`:
|
||||
|
||||
```js
|
||||
// index.web.js
|
||||
|
||||
import App from './src/App';
|
||||
import React from 'react';
|
||||
import ReactNative, { AppRegistry } from 'react-native';
|
||||
|
||||
// register the app
|
||||
AppRegistry.registerComponent('App', () => App);
|
||||
|
||||
AppRegistry.runApplication('App', {
|
||||
initialProps: {},
|
||||
rootTag: document.getElementById('react-app')
|
||||
});
|
||||
```
|
||||
|
||||
Rendering within existing web apps is also possible using `ReactNative`:
|
||||
|
||||
```js
|
||||
import AppHeader from './src/AppHeader';
|
||||
import React from 'react';
|
||||
import ReactNative from 'react-native';
|
||||
|
||||
ReactNative.render(<AppHeader />, document.getElementById('react-app-header'))
|
||||
```
|
||||
|
||||
And finally, `react-native-web` components will also be rendering within a tree
|
||||
produced by calling `ReactDOM.render` (i.e., an existing web app), but
|
||||
otherwise it is not recommended.
|
||||
|
||||
### Server-side rendering
|
||||
|
||||
Server-side rendering is supported using the `AppRegistry`:
|
||||
|
||||
```js
|
||||
import App from './src/App';
|
||||
import ReactDOMServer from 'react-dom/server'
|
||||
import ReactNative, { AppRegistry } from 'react-native'
|
||||
|
||||
// register the app
|
||||
AppRegistry.registerComponent('App', () => App)
|
||||
|
||||
// prerender the app
|
||||
const { element, stylesheets } = AppRegistry.getApplication('App', { initialProps });
|
||||
const initialHTML = ReactDOMServer.renderToString(element);
|
||||
const initialStyles = stylesheets.map((sheet) => ReactDOMServer.renderToStaticMarkup(sheet)).join('\n');
|
||||
|
||||
// construct HTML document
|
||||
const document = `
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
${initialStyles}
|
||||
</head>
|
||||
<body>
|
||||
${initialHTML}
|
||||
`
|
||||
```
|
||||
|
||||
## Web-specific code
|
||||
|
||||
Minor platform differences can use the `Platform` module.
|
||||
|
||||
```js
|
||||
import { AppRegistry, Platform } from 'react-native'
|
||||
import { Platform } from 'react-native';
|
||||
|
||||
AppRegistry.registerComponent('MyApp', () => MyApp)
|
||||
|
||||
if (Platform.OS === 'web') {
|
||||
AppRegistry.runApplication('MyApp', {
|
||||
rootTag: document.getElementById('react-root')
|
||||
});
|
||||
}
|
||||
const styles = StyleSheet.create({
|
||||
height: (Platform.OS === 'web') ? 200 : 100,
|
||||
});
|
||||
```
|
||||
|
||||
More significant platform differences should use platform-specific files (see
|
||||
@@ -137,68 +195,16 @@ import MyComponent from './MyComponent';
|
||||
React Native will automatically import the correct variant for each specific
|
||||
target platform.
|
||||
|
||||
## Client-side rendering
|
||||
## Testing with Jest
|
||||
|
||||
Rendering using `ReactNative`:
|
||||
[Jest](https://facebook.github.io/jest/) also needs to map `react-native` to `react-native-web`.
|
||||
|
||||
```js
|
||||
import React from 'react'
|
||||
import ReactNative from 'react-native'
|
||||
|
||||
// component that renders the app
|
||||
const AppHeaderContainer = (props) => { /* ... */ }
|
||||
|
||||
ReactNative.render(<AppHeaderContainer />, document.getElementById('react-app-header'))
|
||||
```
|
||||
"jest": {
|
||||
"moduleNameMapper": {
|
||||
"react-native": "<rootDir>/node_modules/react-native-web"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Rendering using `AppRegistry`:
|
||||
|
||||
```js
|
||||
import React from 'react'
|
||||
import ReactNative, { AppRegistry } from 'react-native'
|
||||
|
||||
// component that renders the app
|
||||
const AppContainer = (props) => { /* ... */ }
|
||||
|
||||
// register the app
|
||||
AppRegistry.registerComponent('App', () => AppContainer)
|
||||
|
||||
AppRegistry.runApplication('App', {
|
||||
initialProps: {},
|
||||
rootTag: document.getElementById('react-app')
|
||||
})
|
||||
```
|
||||
|
||||
Rendering within `ReactDOM.render` also works when introducing
|
||||
`react-native-web` to an existing web app, but otherwise it is not recommended.
|
||||
|
||||
## Server-side rendering
|
||||
|
||||
Rendering using the `AppRegistry`:
|
||||
|
||||
```js
|
||||
import ReactDOMServer from 'react-dom/server'
|
||||
import ReactNative, { AppRegistry } from 'react-native'
|
||||
|
||||
// component that renders the app
|
||||
const AppContainer = (props) => { /* ... */ }
|
||||
|
||||
// register the app
|
||||
AppRegistry.registerComponent('App', () => AppContainer)
|
||||
|
||||
// prerender the app
|
||||
const { element, stylesheets } = AppRegistry.getApplication('App', { initialProps });
|
||||
const initialHTML = ReactDOMServer.renderToString(element);
|
||||
const initialStyles = stylesheets.map((sheet) => ReactDOMServer.renderToStaticMarkup(sheet)).join('\n');
|
||||
|
||||
// construct HTML document
|
||||
const document = `
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
${initialStyles}
|
||||
</head>
|
||||
<body>
|
||||
${initialHTML}
|
||||
`
|
||||
```
|
||||
Please refer to the Jest documentation for more information.
|
||||
|
||||
11
docs/package.json
Normal file
11
docs/package.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"scripts": {
|
||||
"build": "yarn && build-storybook -o ./dist -c ./storybook/.storybook",
|
||||
"start": "start-storybook -p 9001 -c ./storybook/.storybook",
|
||||
"release": "yarn build && git checkout gh-pages && rm -rf ../storybook && mv dist ../storybook && git add -A && git commit -m \"Storybook deploy\" && git push origin gh-pages && git checkout -"
|
||||
},
|
||||
"dependencies": {
|
||||
"@storybook/addon-options": "^3.1.6",
|
||||
"@storybook/react": "^3.1.9"
|
||||
}
|
||||
}
|
||||
@@ -1 +1 @@
|
||||
import '@kadira/storybook-addon-options/register';
|
||||
import '@storybook/addon-options/register';
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { setOptions } from '@kadira/storybook-addon-options';
|
||||
import { setOptions } from '@storybook/addon-options';
|
||||
import centered from './decorator-centered';
|
||||
import { configure, addDecorator } from '@kadira/storybook';
|
||||
import { configure, addDecorator } from '@storybook/react';
|
||||
|
||||
const context = require.context('../', true, /Docs\.js$/);
|
||||
const context = require.context('../', true, /Screen\.js$/);
|
||||
|
||||
addDecorator(centered);
|
||||
|
||||
|
||||
@@ -10,9 +10,5 @@ const styles = StyleSheet.create({
|
||||
});
|
||||
|
||||
export default function(renderStory) {
|
||||
return (
|
||||
<View style={styles.root}>
|
||||
{renderStory()}
|
||||
</View>
|
||||
);
|
||||
return <View style={styles.root}>{renderStory()}</View>;
|
||||
}
|
||||
|
||||
@@ -1,33 +1,36 @@
|
||||
const path = require('path');
|
||||
const webpack = require('webpack');
|
||||
|
||||
const DEV = process.env.NODE_ENV !== 'production';
|
||||
module.exports = (storybookBaseConfig, configType) => {
|
||||
const DEV = configType === 'DEVELOPMENT';
|
||||
|
||||
module.exports = {
|
||||
module: {
|
||||
loaders: [
|
||||
{
|
||||
test: /\.js$/,
|
||||
exclude: /node_modules/,
|
||||
loader: 'babel-loader',
|
||||
query: { cacheDirectory: true }
|
||||
},
|
||||
{
|
||||
test: /\.(gif|jpe?g|png|svg)$/,
|
||||
loader: 'url-loader',
|
||||
query: { name: '[name].[ext]' }
|
||||
}
|
||||
]
|
||||
},
|
||||
plugins: [
|
||||
storybookBaseConfig.module.rules.push({
|
||||
test: /\.js$/,
|
||||
exclude: /node_modules/,
|
||||
use: {
|
||||
loader: 'babel-loader',
|
||||
options: { cacheDirectory: true }
|
||||
}
|
||||
});
|
||||
|
||||
storybookBaseConfig.module.rules.push({
|
||||
test: /\.(gif|jpe?g|png|svg)$/,
|
||||
use: {
|
||||
loader: 'url-loader',
|
||||
options: { name: '[name].[ext]' }
|
||||
}
|
||||
});
|
||||
|
||||
storybookBaseConfig.plugins.push(
|
||||
new webpack.DefinePlugin({
|
||||
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'development'),
|
||||
'process.env.__REACT_NATIVE_DEBUG_ENABLED__': DEV
|
||||
})
|
||||
],
|
||||
resolve: {
|
||||
alias: {
|
||||
'react-native': path.join(__dirname, '../../../src/module')
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
storybookBaseConfig.resolve.alias = {
|
||||
'react-native': path.join(__dirname, '../../../src/module')
|
||||
};
|
||||
|
||||
return storybookBaseConfig;
|
||||
};
|
||||
|
||||
@@ -9,14 +9,13 @@ import PropColor from './examples/PropColor';
|
||||
import PropHidesWhenStopped from './examples/PropHidesWhenStopped';
|
||||
import PropSize from './examples/PropSize';
|
||||
import React from 'react';
|
||||
import { storiesOf } from '@kadira/storybook';
|
||||
import UIExplorer, { DocItem } from '../../ui-explorer';
|
||||
import UIExplorer, { Description, DocItem, Section, storiesOf } from '../../ui-explorer';
|
||||
|
||||
const sections = [
|
||||
{
|
||||
title: 'Props',
|
||||
entries: [
|
||||
<DocItem name="...View props" />,
|
||||
const ActivityIndicatorScreen = () => (
|
||||
<UIExplorer title="ActivityIndicator" url="1-components/ActivityIndicator">
|
||||
<Description>Displays a customizable activity indicator</Description>
|
||||
<Section title="Props">
|
||||
<DocItem name="...View props" />
|
||||
|
||||
<DocItem
|
||||
name="animating"
|
||||
@@ -25,7 +24,7 @@ const sections = [
|
||||
example={{
|
||||
render: () => <PropAnimating />
|
||||
}}
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="color"
|
||||
@@ -34,7 +33,7 @@ const sections = [
|
||||
example={{
|
||||
render: () => <PropColor />
|
||||
}}
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="hidesWhenStopped"
|
||||
@@ -43,7 +42,7 @@ const sections = [
|
||||
example={{
|
||||
render: () => <PropHidesWhenStopped />
|
||||
}}
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="size"
|
||||
@@ -53,15 +52,8 @@ const sections = [
|
||||
render: () => <PropSize />
|
||||
}}
|
||||
/>
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
storiesOf('Components', module).add('ActivityIndicator', () =>
|
||||
<UIExplorer
|
||||
description="Displays a customizable activity indicator"
|
||||
sections={sections}
|
||||
title="ActivityIndicator"
|
||||
url="components/ActivityIndicator"
|
||||
/>
|
||||
</Section>
|
||||
</UIExplorer>
|
||||
);
|
||||
|
||||
storiesOf('Components', module).add('ActivityIndicator', ActivityIndicatorScreen);
|
||||
@@ -5,11 +5,12 @@
|
||||
import { ActivityIndicator, StyleSheet, View } from 'react-native';
|
||||
import React from 'react';
|
||||
|
||||
const ActivityIndicatorAnimatingExample = () =>
|
||||
const ActivityIndicatorAnimatingExample = () => (
|
||||
<View style={styles.horizontal}>
|
||||
<ActivityIndicator />
|
||||
<ActivityIndicator animating={false} />
|
||||
</View>;
|
||||
</View>
|
||||
);
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
horizontal: {
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
import React from 'react';
|
||||
import { ActivityIndicator, StyleSheet, View } from 'react-native';
|
||||
|
||||
const ActivityIndicatorColorExample = () =>
|
||||
const ActivityIndicatorColorExample = () => (
|
||||
<View style={styles.horizontal}>
|
||||
<ActivityIndicator color="#1DA1F2" style={styles.rightPadding} />
|
||||
<ActivityIndicator color="#17BF63" style={styles.rightPadding} />
|
||||
@@ -13,7 +13,8 @@ const ActivityIndicatorColorExample = () =>
|
||||
<ActivityIndicator color="#794BC4" style={styles.rightPadding} />
|
||||
<ActivityIndicator color="#E0245E" style={styles.rightPadding} />
|
||||
<ActivityIndicator color="#FFAD1F" style={styles.rightPadding} />
|
||||
</View>;
|
||||
</View>
|
||||
);
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
horizontal: {
|
||||
|
||||
@@ -43,11 +43,12 @@ class ToggleAnimatingActivityIndicator extends PureComponent {
|
||||
}
|
||||
}
|
||||
|
||||
const ActivityIndicatorHidesWhenStoppedExample = () =>
|
||||
const ActivityIndicatorHidesWhenStoppedExample = () => (
|
||||
<View style={[styles.horizontal]}>
|
||||
<ToggleAnimatingActivityIndicator hidesWhenStopped={false} style={styles.rightPadding} />
|
||||
<ToggleAnimatingActivityIndicator />
|
||||
</View>;
|
||||
</View>
|
||||
);
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
horizontal: {
|
||||
|
||||
@@ -7,11 +7,12 @@ import { ActivityIndicator, StyleSheet, View } from 'react-native';
|
||||
|
||||
const sizes = [20, 'small', 36, 'large', 60];
|
||||
|
||||
const ActivityIndicatorSizeExample = () =>
|
||||
const ActivityIndicatorSizeExample = () => (
|
||||
<View style={styles.horizontal}>
|
||||
{sizes.map((size, i) => <ActivityIndicator key={i} size={size} style={styles.rightPadding} />)}
|
||||
<ActivityIndicator size="large" style={styles.large} />
|
||||
</View>;
|
||||
</View>
|
||||
);
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
horizontal: {
|
||||
|
||||
@@ -8,18 +8,30 @@ import React from 'react';
|
||||
import PropColor from './examples/PropColor';
|
||||
import PropDisabled from './examples/PropDisabled';
|
||||
import PropOnPress from './examples/PropOnPress';
|
||||
import UIExplorer, { AppText, Code, DocItem } from '../../ui-explorer';
|
||||
import { storiesOf } from '@kadira/storybook';
|
||||
import UIExplorer, {
|
||||
AppText,
|
||||
Code,
|
||||
Description,
|
||||
DocItem,
|
||||
Section,
|
||||
storiesOf
|
||||
} from '../../ui-explorer';
|
||||
|
||||
const sections = [
|
||||
{
|
||||
title: 'Props',
|
||||
entries: [
|
||||
const ButtonScreen = () => (
|
||||
<UIExplorer title="Button" url="1-components/Button">
|
||||
<Description>
|
||||
<AppText>
|
||||
A basic button component. Supports a minimal level of customization. You can build your own
|
||||
custom button using <Code>TouchableOpacity</Code> or <Code>TouchableNativeFeedback</Code>.
|
||||
</AppText>
|
||||
</Description>
|
||||
|
||||
<Section title="Props">
|
||||
<DocItem
|
||||
name="accessibilityLabel"
|
||||
typeInfo="?string"
|
||||
description="Overrides the text that's read by a screen reader when the user interacts with the element."
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="color"
|
||||
@@ -28,16 +40,16 @@ const sections = [
|
||||
example={{
|
||||
render: () => <PropColor />
|
||||
}}
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="disabled"
|
||||
typeInfo="?boolean"
|
||||
description="If `true`, disable all interactions for this element."
|
||||
description="If true, disable all interactions for this element."
|
||||
example={{
|
||||
render: () => <PropDisabled />
|
||||
}}
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="onPress"
|
||||
@@ -46,30 +58,17 @@ const sections = [
|
||||
example={{
|
||||
render: () => <PropOnPress />
|
||||
}}
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="testID"
|
||||
typeInfo="?string"
|
||||
description="Used to locate this view in end-to-end tests."
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem name="title" typeInfo="string" description="Text to display inside the button." />
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
storiesOf('Components', module).add('Button', () =>
|
||||
<UIExplorer
|
||||
description={[
|
||||
<AppText>
|
||||
A basic button component. Supports a minimal level of customization. You can build your own
|
||||
custom button using <Code>TouchableOpacity</Code>
|
||||
or <Code>TouchableNativeFeedback</Code>.
|
||||
</AppText>
|
||||
]}
|
||||
sections={sections}
|
||||
title="Button"
|
||||
url="components/Button"
|
||||
/>
|
||||
</Section>
|
||||
</UIExplorer>
|
||||
);
|
||||
|
||||
storiesOf('Components', module).add('Button', ButtonScreen);
|
||||
@@ -8,7 +8,7 @@ import { Button, View } from 'react-native';
|
||||
|
||||
const emptyFunction = () => {};
|
||||
|
||||
const ButtonColorExample = () =>
|
||||
const ButtonColorExample = () => (
|
||||
<View>
|
||||
<Button color="#17BF63" onPress={emptyFunction} title="Press me" />
|
||||
<DividerVertical />
|
||||
@@ -17,6 +17,7 @@ const ButtonColorExample = () =>
|
||||
<Button color="#794BC4" onPress={emptyFunction} title="Press me" />
|
||||
<DividerVertical />
|
||||
<Button color="#E0245E" onPress={emptyFunction} title="Press me" />
|
||||
</View>;
|
||||
</View>
|
||||
);
|
||||
|
||||
export default ButtonColorExample;
|
||||
|
||||
@@ -8,7 +8,7 @@ import { Button, StyleSheet, View } from 'react-native';
|
||||
|
||||
const emptyFunction = () => {};
|
||||
|
||||
const ButtonOnPressExample = () =>
|
||||
const ButtonOnPressExample = () => (
|
||||
<View style={styles.horizontal}>
|
||||
<Button
|
||||
accessibilityLabel="This sounds great!"
|
||||
@@ -17,7 +17,8 @@ const ButtonOnPressExample = () =>
|
||||
/>
|
||||
<DividerHorizontal />
|
||||
<Button color="#841584" onPress={emptyFunction} title="Ok!" />
|
||||
</View>;
|
||||
</View>
|
||||
);
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
horizontal: {
|
||||
|
||||
@@ -16,14 +16,24 @@ import PropResizeMode from './examples/PropResizeMode';
|
||||
import PropSource from './examples/PropSource';
|
||||
import StaticGetSizeExample from './examples/StaticGetSize';
|
||||
import StaticPrefetchExample from './examples/StaticPrefetch';
|
||||
import { storiesOf } from '@kadira/storybook';
|
||||
import UIExplorer, { DocItem } from '../../ui-explorer';
|
||||
import UIExplorer, {
|
||||
AppText,
|
||||
Code,
|
||||
Description,
|
||||
DocItem,
|
||||
Section,
|
||||
storiesOf
|
||||
} from '../../ui-explorer';
|
||||
|
||||
const sections = [
|
||||
{
|
||||
title: 'Props',
|
||||
entries: [
|
||||
<DocItem name="...View props" />,
|
||||
const ImageScreen = () => (
|
||||
<UIExplorer title="Image" url="1-components/Image">
|
||||
<Description>
|
||||
An accessibile image component with support for image resizing, default image, and child
|
||||
content.
|
||||
</Description>
|
||||
|
||||
<Section title="Props">
|
||||
<DocItem name="...View props" />
|
||||
|
||||
<DocItem
|
||||
name="children"
|
||||
@@ -32,34 +42,44 @@ const sections = [
|
||||
example={{
|
||||
render: () => <PropChildren />
|
||||
}}
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="defaultSource"
|
||||
typeInfo="?object"
|
||||
description="An image to display as a placeholder while downloading the final image off the network. `{ uri: string, width, height }`"
|
||||
description={
|
||||
<AppText>
|
||||
An image to display as a placeholder while downloading the final image off the network.{' '}
|
||||
<Code>{'{ uri: string, width, height }'}</Code>
|
||||
</AppText>
|
||||
}
|
||||
example={{
|
||||
render: () => <PropDefaultSource />
|
||||
}}
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
label="web"
|
||||
name="draggable"
|
||||
typeInfo="?boolean = true"
|
||||
description="When false, the image will not be draggable"
|
||||
example={{
|
||||
render: () => <PropDraggable />
|
||||
}}
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="onError"
|
||||
typeInfo="?function"
|
||||
description="Invoked on load error with `{nativeEvent: {error}}`."
|
||||
description={
|
||||
<AppText>
|
||||
Invoked on load error with <Code>{'{nativeEvent: {error}}'}</Code>.
|
||||
</AppText>
|
||||
}
|
||||
example={{
|
||||
render: () => <PropOnError />
|
||||
}}
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="onLoad"
|
||||
@@ -68,7 +88,7 @@ const sections = [
|
||||
example={{
|
||||
render: () => <PropOnLoad />
|
||||
}}
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="onLoadEnd"
|
||||
@@ -77,7 +97,7 @@ const sections = [
|
||||
example={{
|
||||
render: () => <PropOnLoadEnd />
|
||||
}}
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="onLoadStart"
|
||||
@@ -86,7 +106,7 @@ const sections = [
|
||||
example={{
|
||||
render: () => <PropOnLoadStart />
|
||||
}}
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="resizeMode"
|
||||
@@ -95,25 +115,27 @@ const sections = [
|
||||
example={{
|
||||
render: () => <PropResizeMode />
|
||||
}}
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="source"
|
||||
typeInfo="?object"
|
||||
description="`uri` is a string representing the resource identifier for the image, which could be an http address or a base64 encoded image. `{ uri: string, width, height }`"
|
||||
description={
|
||||
<AppText>
|
||||
<Code>uri</Code> is a string representing the resource identifier for the image, which
|
||||
could be an http address or a base64 encoded image.{' '}
|
||||
<Code>{'{ uri: string, width, height }'}</Code>
|
||||
</AppText>
|
||||
}
|
||||
example={{
|
||||
code: '',
|
||||
render: () => <PropSource />
|
||||
}}
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem name="style" typeInfo="?style" />
|
||||
]
|
||||
},
|
||||
</Section>
|
||||
|
||||
{
|
||||
title: 'Properties',
|
||||
entries: [
|
||||
<Section title="Properties">
|
||||
<DocItem
|
||||
name="static resizeMode"
|
||||
typeInfo="object"
|
||||
@@ -121,20 +143,28 @@ const sections = [
|
||||
code: '<Image resizeMode={Image.resizeMode.contain} />'
|
||||
}}
|
||||
/>
|
||||
]
|
||||
},
|
||||
</Section>
|
||||
|
||||
{
|
||||
title: 'Methods',
|
||||
entries: [
|
||||
<Section title="Methods">
|
||||
<DocItem
|
||||
name="static getSize"
|
||||
typeInfo="(uri: string, success: (width, height) => {}, failure: function) => void"
|
||||
description="Retrieve the width and height (in pixels) of an image prior to displaying it. This method can fail if the image cannot be found, or fails to download.\n\n(In order to retrieve the image dimensions, the image may first need to be loaded or downloaded, after which it will be cached. This means that in principle you could use this method to preload images, however it is not optimized for that purpose, and may in future be implemented in a way that does not fully load/download the image data.)"
|
||||
description={[
|
||||
<AppText key={1}>
|
||||
Retrieve the width and height (in pixels) of an image prior to displaying it. This
|
||||
method can fail if the image cannot be found, or fails to download.
|
||||
</AppText>,
|
||||
<AppText key={2}>
|
||||
(In order to retrieve the image dimensions, the image may first need to be loaded or
|
||||
downloaded, after which it will be cached. This means that in principle you could use
|
||||
this method to preload images, however it is not optimized for that purpose, and may in
|
||||
future be implemented in a way that does not fully load/download the image data.)
|
||||
</AppText>
|
||||
]}
|
||||
example={{
|
||||
render: () => <StaticGetSizeExample />
|
||||
}}
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="static prefetch"
|
||||
@@ -144,15 +174,8 @@ const sections = [
|
||||
render: () => <StaticPrefetchExample />
|
||||
}}
|
||||
/>
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
storiesOf('Components', module).add('Image', () =>
|
||||
<UIExplorer
|
||||
description="An accessibile image component with support for image resizing, default image, and child content."
|
||||
sections={sections}
|
||||
title="Image"
|
||||
url="components/Image"
|
||||
/>
|
||||
</Section>
|
||||
</UIExplorer>
|
||||
);
|
||||
|
||||
storiesOf('Components', module).add('Image', ImageScreen);
|
||||
@@ -24,11 +24,11 @@ class NetworkImageExample extends PureComponent {
|
||||
};
|
||||
|
||||
render() {
|
||||
const loader = this.state.loading
|
||||
? <View>
|
||||
<ActivityIndicator />
|
||||
</View>
|
||||
: null;
|
||||
const loader = this.state.loading ? (
|
||||
<View>
|
||||
<ActivityIndicator />
|
||||
</View>
|
||||
) : null;
|
||||
|
||||
return (
|
||||
<View style={[helpers.styles.row, helpers.styles.centerRow]}>
|
||||
@@ -43,10 +43,7 @@ class NetworkImageExample extends PureComponent {
|
||||
>
|
||||
{loader}
|
||||
</Image>
|
||||
{this.state.message &&
|
||||
<Text style={helpers.styles.marginLeft}>
|
||||
{this.state.message}
|
||||
</Text>}
|
||||
{this.state.message && <Text style={helpers.styles.marginLeft}>{this.state.message}</Text>}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -6,10 +6,11 @@ import sources from '../sources';
|
||||
import React from 'react';
|
||||
import { Image, StyleSheet, Text } from 'react-native';
|
||||
|
||||
const ImageChildrenExample = () =>
|
||||
const ImageChildrenExample = () => (
|
||||
<Image source={sources.large} style={styles.image}>
|
||||
<Text style={styles.text}>React</Text>
|
||||
</Image>;
|
||||
</Image>
|
||||
);
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
image: {
|
||||
|
||||
@@ -7,11 +7,12 @@ import sources from '../sources';
|
||||
import React from 'react';
|
||||
import { Image } from 'react-native';
|
||||
|
||||
const ImageDefaultSourceExample = () =>
|
||||
const ImageDefaultSourceExample = () => (
|
||||
<Image
|
||||
defaultSource={sources.placeholder}
|
||||
source={sources.largeAlt}
|
||||
style={helpers.styles.base}
|
||||
/>;
|
||||
/>
|
||||
);
|
||||
|
||||
export default ImageDefaultSourceExample;
|
||||
|
||||
@@ -6,10 +6,11 @@ import sources from '../sources';
|
||||
import React from 'react';
|
||||
import { Image, StyleSheet, View } from 'react-native';
|
||||
|
||||
const ImageDraggableExample = () =>
|
||||
const ImageDraggableExample = () => (
|
||||
<View style={styles.container}>
|
||||
<Image draggable={false} source={sources.large} style={styles.image} />
|
||||
</View>;
|
||||
</View>
|
||||
);
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
|
||||
@@ -7,7 +7,8 @@ import NetworkImage from './NetworkImage';
|
||||
import React from 'react';
|
||||
import sources from '../sources';
|
||||
|
||||
const ImageOnLoadExample = () =>
|
||||
<NetworkImage logMethod="onLoad" source={createUncachedURI(sources.small)} />;
|
||||
const ImageOnLoadExample = () => (
|
||||
<NetworkImage logMethod="onLoad" source={createUncachedURI(sources.small)} />
|
||||
);
|
||||
|
||||
export default ImageOnLoadExample;
|
||||
|
||||
@@ -7,7 +7,8 @@ import NetworkImage from './NetworkImage';
|
||||
import React from 'react';
|
||||
import sources from '../sources';
|
||||
|
||||
const ImageOnLoadEndExample = () =>
|
||||
<NetworkImage logMethod="onLoadEnd" source={createUncachedURI(sources.small)} />;
|
||||
const ImageOnLoadEndExample = () => (
|
||||
<NetworkImage logMethod="onLoadEnd" source={createUncachedURI(sources.small)} />
|
||||
);
|
||||
|
||||
export default ImageOnLoadEndExample;
|
||||
|
||||
@@ -7,7 +7,8 @@ import NetworkImage from './NetworkImage';
|
||||
import React from 'react';
|
||||
import sources from '../sources';
|
||||
|
||||
const ImageOnLoadStartExample = () =>
|
||||
<NetworkImage logMethod="onLoadStart" source={createUncachedURI(sources.small)} />;
|
||||
const ImageOnLoadStartExample = () => (
|
||||
<NetworkImage logMethod="onLoadStart" source={createUncachedURI(sources.small)} />
|
||||
);
|
||||
|
||||
export default ImageOnLoadStartExample;
|
||||
|
||||
@@ -6,7 +6,7 @@ import React from 'react';
|
||||
import sources from '../sources';
|
||||
import { Image, StyleSheet, Text, View } from 'react-native';
|
||||
|
||||
const ImageResizeModeExample = () =>
|
||||
const ImageResizeModeExample = () => (
|
||||
<View>
|
||||
{[sources.small, sources.large].map((source, i) => {
|
||||
return (
|
||||
@@ -48,7 +48,8 @@ const ImageResizeModeExample = () =>
|
||||
</View>
|
||||
);
|
||||
})}
|
||||
</View>;
|
||||
</View>
|
||||
);
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
horizontal: {
|
||||
|
||||
@@ -6,7 +6,7 @@ import sources from '../sources';
|
||||
import React from 'react';
|
||||
import { Image, StyleSheet, Text, View } from 'react-native';
|
||||
|
||||
const ImageSourceExample = () =>
|
||||
const ImageSourceExample = () => (
|
||||
<View style={styles.row}>
|
||||
<View style={styles.column}>
|
||||
<Text style={styles.text}>Static image</Text>
|
||||
@@ -24,7 +24,8 @@ const ImageSourceExample = () =>
|
||||
<Text style={styles.text}>Data SVG</Text>
|
||||
<Image source={sources.dataSvg} style={styles.image} />
|
||||
</View>
|
||||
</View>;
|
||||
</View>
|
||||
);
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
row: {
|
||||
|
||||
@@ -24,20 +24,20 @@ class ImageGetSizeExample extends PureComponent {
|
||||
|
||||
return (
|
||||
<View>
|
||||
{showButton
|
||||
? <View style={styles.button}>
|
||||
<Button onPress={this._handlePress} title="(4.7MB) Get image dimensions" />
|
||||
</View>
|
||||
: null}
|
||||
{startLoad
|
||||
? <View>
|
||||
<Text>
|
||||
Source dimensions:{' '}
|
||||
{JSON.stringify({ width: this.state.width, height: this.state.height })}
|
||||
</Text>
|
||||
<Image source={createUncachedURI(this.props.source.uri)} style={styles.image} />
|
||||
</View>
|
||||
: null}
|
||||
{showButton ? (
|
||||
<View style={styles.button}>
|
||||
<Button onPress={this._handlePress} title="(4.7MB) Get image dimensions" />
|
||||
</View>
|
||||
) : null}
|
||||
{startLoad ? (
|
||||
<View>
|
||||
<Text>
|
||||
Source dimensions:{' '}
|
||||
{JSON.stringify({ width: this.state.width, height: this.state.height })}
|
||||
</Text>
|
||||
<Image source={createUncachedURI(this.props.source.uri)} style={styles.image} />
|
||||
</View>
|
||||
) : null}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -23,25 +23,23 @@ class ImagePrefetchExample extends PureComponent {
|
||||
|
||||
return (
|
||||
<View>
|
||||
{showButton
|
||||
? <View style={styles.button}>
|
||||
<Button onPress={this._handlePress} title="Prefetch image" />
|
||||
</View>
|
||||
: null}
|
||||
{startLoad
|
||||
? <View>
|
||||
<Text>
|
||||
{this.state.events.join('\n')}
|
||||
</Text>
|
||||
<Image
|
||||
onLoad={this._handleLoad}
|
||||
onLoadEnd={this._handleLoadEnd}
|
||||
onLoadStart={this._handleLoadStart}
|
||||
source={this.props.source}
|
||||
style={styles.image}
|
||||
/>
|
||||
</View>
|
||||
: null}
|
||||
{showButton ? (
|
||||
<View style={styles.button}>
|
||||
<Button onPress={this._handlePress} title="Prefetch image" />
|
||||
</View>
|
||||
) : null}
|
||||
{startLoad ? (
|
||||
<View>
|
||||
<Text>{this.state.events.join('\n')}</Text>
|
||||
<Image
|
||||
onLoad={this._handleLoad}
|
||||
onLoadEnd={this._handleLoadEnd}
|
||||
onLoadStart={this._handleLoadStart}
|
||||
source={this.props.source}
|
||||
style={styles.image}
|
||||
/>
|
||||
</View>
|
||||
) : null}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -8,14 +8,13 @@ import PropIndeterminate from './examples/PropIndeterminate';
|
||||
import PropProgress from './examples/PropProgress';
|
||||
import PropTrackColor from './examples/PropTrackColor';
|
||||
import React from 'react';
|
||||
import { storiesOf } from '@kadira/storybook';
|
||||
import UIExplorer, { DocItem } from '../../ui-explorer';
|
||||
import UIExplorer, { Description, DocItem, Section, storiesOf } from '../../ui-explorer';
|
||||
|
||||
const sections = [
|
||||
{
|
||||
title: 'Props',
|
||||
entries: [
|
||||
<DocItem name="...View props" />,
|
||||
const ProgressBarScreen = () => (
|
||||
<UIExplorer title="ProgressBar" url="1-components/ProgressBar">
|
||||
<Description>Display an activity progress bar</Description>
|
||||
<Section title="Props">
|
||||
<DocItem name="...View props" />
|
||||
|
||||
<DocItem
|
||||
description="Color of the progress bar."
|
||||
@@ -24,7 +23,7 @@ const sections = [
|
||||
}}
|
||||
name="color"
|
||||
typeInfo="?string = #1976D2"
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
description="Whether the progress bar will show indeterminate progress."
|
||||
@@ -33,7 +32,7 @@ const sections = [
|
||||
}}
|
||||
name="indeterminate"
|
||||
typeInfo="?boolean = true"
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
description="The progress value (between 0 and 1)."
|
||||
@@ -42,7 +41,7 @@ const sections = [
|
||||
}}
|
||||
name="progress"
|
||||
typeInfo="?number"
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
description="Color of the track bar."
|
||||
@@ -52,11 +51,9 @@ const sections = [
|
||||
name="trackColor"
|
||||
typeInfo="?string = 'transparent'"
|
||||
/>
|
||||
]
|
||||
},
|
||||
{
|
||||
title: 'More examples',
|
||||
entries: [
|
||||
</Section>
|
||||
|
||||
<Section title="More examples">
|
||||
<DocItem
|
||||
description="Custom sizes can be created using styles"
|
||||
example={{
|
||||
@@ -64,15 +61,8 @@ const sections = [
|
||||
render: () => <CustomSize />
|
||||
}}
|
||||
/>
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
storiesOf('Components', module).add('ProgressBar', () =>
|
||||
<UIExplorer
|
||||
description="Display an activity progress bar"
|
||||
sections={sections}
|
||||
title="ProgressBar"
|
||||
url="components/ProgressBar"
|
||||
/>
|
||||
</Section>
|
||||
</UIExplorer>
|
||||
);
|
||||
|
||||
storiesOf('Components', module).add('ProgressBar', ProgressBarScreen);
|
||||
@@ -6,12 +6,13 @@ import { DividerVertical } from '../helpers';
|
||||
import React from 'react';
|
||||
import { ProgressBar, StyleSheet, View } from 'react-native';
|
||||
|
||||
const ProgressBarCustomSizeExample = () =>
|
||||
const ProgressBarCustomSizeExample = () => (
|
||||
<View>
|
||||
<ProgressBar color="#1DA1F2" progress={0.33} style={styles.one} trackColor="#D1E3F6" />
|
||||
<DividerVertical />
|
||||
<ProgressBar color="#1DA1F2" progress={0.33} style={styles.two} trackColor="#D1E3F6" />
|
||||
</View>;
|
||||
</View>
|
||||
);
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
one: {
|
||||
|
||||
@@ -6,7 +6,7 @@ import React from 'react';
|
||||
import { DividerVertical } from '../helpers';
|
||||
import { ProgressBar, View } from 'react-native';
|
||||
|
||||
const ProgressBarColorExample = () =>
|
||||
const ProgressBarColorExample = () => (
|
||||
<View>
|
||||
<ProgressBar color="#1DA1F2" progress={0.2} />
|
||||
<DividerVertical />
|
||||
@@ -17,6 +17,7 @@ const ProgressBarColorExample = () =>
|
||||
<ProgressBar color="#794BC4" progress={0.8} />
|
||||
<DividerVertical />
|
||||
<ProgressBar color="#E0245E" progress={1.0} />
|
||||
</View>;
|
||||
</View>
|
||||
);
|
||||
|
||||
export default ProgressBarColorExample;
|
||||
|
||||
@@ -6,13 +6,14 @@ import { DividerVertical } from '../helpers';
|
||||
import React from 'react';
|
||||
import { ProgressBar, View } from 'react-native';
|
||||
|
||||
const ProgressBarTrackColorExample = () =>
|
||||
const ProgressBarTrackColorExample = () => (
|
||||
<View>
|
||||
<ProgressBar color="#1DA1F2" progress={0.1} trackColor="#17BF63" />
|
||||
<DividerVertical />
|
||||
<ProgressBar color="#1DA1F2" progress={0.2} trackColor="#F45D22" />
|
||||
<DividerVertical />
|
||||
<ProgressBar color="#1DA1F2" progress={0.3} trackColor="#794BC4" />
|
||||
</View>;
|
||||
</View>
|
||||
);
|
||||
|
||||
export default ProgressBarTrackColorExample;
|
||||
|
||||
@@ -8,20 +8,35 @@ import { HorizontalExample } from './examples/Horizontal';
|
||||
import ScrollToExample from './examples/ScrollTo';
|
||||
import ScrollToEndExample from './examples/ScrollToEnd';
|
||||
import React from 'react';
|
||||
import { storiesOf } from '@kadira/storybook';
|
||||
import UIExplorer, { AppText, Code, DocItem, TextList } from '../../ui-explorer';
|
||||
import UIExplorer, {
|
||||
AppText,
|
||||
Code,
|
||||
Description,
|
||||
DocItem,
|
||||
Section,
|
||||
storiesOf,
|
||||
TextList
|
||||
} from '../../ui-explorer';
|
||||
|
||||
const sections = [
|
||||
{
|
||||
title: 'Props',
|
||||
entries: [
|
||||
<DocItem name="...View props" />,
|
||||
const ScrollViewScreen = () => (
|
||||
<UIExplorer title="ScrollView" url="1-components/ScrollView">
|
||||
<Description>
|
||||
<AppText>
|
||||
A scrollable <Code>View</Code> that provides itegration with the touch-locking responder
|
||||
system. <Code>ScrollView</Code>'s must have a bounded height: either set the height of the
|
||||
view directly (discouraged) or make sure all parent views have bounded height (e.g.,
|
||||
transfer <Code>{'{ flex: 1}'}</Code> down the view stack).
|
||||
</AppText>
|
||||
</Description>
|
||||
|
||||
<Section title="Props">
|
||||
<DocItem name="...View props" />
|
||||
|
||||
<DocItem
|
||||
name="contentContainerStyle"
|
||||
typeInfo="?style"
|
||||
description="These styles will be applied to the scroll view content container which wraps all of the child views."
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="horizontal"
|
||||
@@ -30,7 +45,7 @@ const sections = [
|
||||
example={{
|
||||
render: () => <HorizontalExample />
|
||||
}}
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="keyboardDismissMode"
|
||||
@@ -53,7 +68,7 @@ const sections = [
|
||||
]}
|
||||
/>
|
||||
]}
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="onContentSizeChange"
|
||||
@@ -65,7 +80,7 @@ const sections = [
|
||||
which this <Code>ScrollView</Code> renders.
|
||||
</AppText>
|
||||
}
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="onScroll"
|
||||
@@ -84,13 +99,13 @@ const sections = [
|
||||
}
|
||||
}`}</Code>
|
||||
]}
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="scrollEnabled"
|
||||
typeInfo="?boolean = true"
|
||||
description="When false, the content does not scroll."
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="scrollEventThrottle"
|
||||
@@ -105,22 +120,20 @@ const sections = [
|
||||
</AppText>
|
||||
}
|
||||
/>
|
||||
]
|
||||
},
|
||||
{
|
||||
title: 'Instance methods',
|
||||
entries: [
|
||||
</Section>
|
||||
|
||||
<Section title="Instance methods">
|
||||
<DocItem
|
||||
name="getInnerViewNode"
|
||||
typeInfo="() => node"
|
||||
description="Returns a reference to the underlying content container DOM node within the ScrollView."
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="getScrollableNode"
|
||||
typeInfo="() => node"
|
||||
description="Returns a reference to the underlying scrollable DOM node."
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="getScrollResponder"
|
||||
@@ -133,7 +146,7 @@ const sections = [
|
||||
responder's methods.
|
||||
</AppText>
|
||||
}
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="scrollTo"
|
||||
@@ -142,7 +155,7 @@ const sections = [
|
||||
example={{
|
||||
render: () => <ScrollToExample />
|
||||
}}
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="scrollToEnd"
|
||||
@@ -152,22 +165,8 @@ const sections = [
|
||||
render: () => <ScrollToEndExample />
|
||||
}}
|
||||
/>
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
storiesOf('Components', module).add('ScrollView', () =>
|
||||
<UIExplorer
|
||||
description={
|
||||
<AppText>
|
||||
A scrollable <Code>View</Code> that provides itegration with the touch-locking responder
|
||||
system. <Code>ScrollView</Code>'s must have a bounded height: either set the height of the
|
||||
view directly (discouraged) or make sure all parent views have bounded height (e.g.,
|
||||
transfer <Code>{'{ flex: 1}'}</Code> down the view stack).
|
||||
</AppText>
|
||||
}
|
||||
sections={sections}
|
||||
title="ScrollView"
|
||||
url="components/ScrollView"
|
||||
/>
|
||||
</Section>
|
||||
</UIExplorer>
|
||||
);
|
||||
|
||||
storiesOf('Components', module).add('ScrollView', ScrollViewScreen);
|
||||
@@ -5,12 +5,13 @@
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { action } from '@kadira/storybook';
|
||||
import { ScrollView, StyleSheet, Text, View } from 'react-native';
|
||||
|
||||
const onScroll = action('ScrollView.onScroll');
|
||||
const onScroll = () => {
|
||||
console.log('ScrollView.onScroll');
|
||||
};
|
||||
|
||||
const VerticalExample = () =>
|
||||
const VerticalExample = () => (
|
||||
<View style={styles.scrollViewContainer}>
|
||||
<ScrollView
|
||||
contentContainerStyle={styles.scrollViewContentContainerStyle}
|
||||
@@ -18,17 +19,16 @@ const VerticalExample = () =>
|
||||
scrollEventThrottle={16} // ~60 events per second
|
||||
style={styles.scrollViewStyle}
|
||||
>
|
||||
{Array.from({ length: 50 }).map((item, i) =>
|
||||
{Array.from({ length: 50 }).map((item, i) => (
|
||||
<View key={i} style={[styles.box, styles.horizontalBox]}>
|
||||
<Text>
|
||||
{i}
|
||||
</Text>
|
||||
<Text>{i}</Text>
|
||||
</View>
|
||||
)}
|
||||
))}
|
||||
</ScrollView>
|
||||
</View>;
|
||||
</View>
|
||||
);
|
||||
|
||||
const HorizontalExample = () =>
|
||||
const HorizontalExample = () => (
|
||||
<View style={styles.scrollViewContainer}>
|
||||
<ScrollView
|
||||
contentContainerStyle={styles.scrollViewContentContainerStyle}
|
||||
@@ -37,15 +37,14 @@ const HorizontalExample = () =>
|
||||
scrollEventThrottle={16} // ~60 events per second
|
||||
style={styles.scrollViewStyle}
|
||||
>
|
||||
{Array.from({ length: 50 }).map((item, i) =>
|
||||
{Array.from({ length: 50 }).map((item, i) => (
|
||||
<View key={i} style={[styles.box, styles.horizontalBox]}>
|
||||
<Text>
|
||||
{i}
|
||||
</Text>
|
||||
<Text>{i}</Text>
|
||||
</View>
|
||||
)}
|
||||
))}
|
||||
</ScrollView>
|
||||
</View>;
|
||||
</View>
|
||||
);
|
||||
|
||||
export { HorizontalExample, VerticalExample };
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*/
|
||||
|
||||
import React, { PureComponent } from 'react';
|
||||
import { Button, ScrollView, StyleSheet, Text, View } from 'react-native';
|
||||
import { Button, ScrollView, StyleSheet, Text, TouchableHighlight, View } from 'react-native';
|
||||
|
||||
export default class ScrollToExample extends PureComponent {
|
||||
render() {
|
||||
@@ -19,13 +19,15 @@ export default class ScrollToExample extends PureComponent {
|
||||
scrollEventThrottle={16} // ~60 events per second
|
||||
style={styles.scrollViewStyle}
|
||||
>
|
||||
{Array.from({ length: 50 }).map((item, i) =>
|
||||
<View key={i} style={[styles.box, styles.horizontalBox]}>
|
||||
<Text>
|
||||
{i}
|
||||
</Text>
|
||||
</View>
|
||||
)}
|
||||
{Array.from({ length: 50 }).map((item, i) => (
|
||||
<TouchableHighlight
|
||||
key={i}
|
||||
onPress={() => {}}
|
||||
style={[styles.box, styles.horizontalBox]}
|
||||
>
|
||||
<Text>{i}</Text>
|
||||
</TouchableHighlight>
|
||||
))}
|
||||
</ScrollView>
|
||||
<Button
|
||||
onPress={() => {
|
||||
|
||||
@@ -19,13 +19,11 @@ export default class ScrollToEndExample extends PureComponent {
|
||||
scrollEventThrottle={16} // ~60 events per second
|
||||
style={styles.scrollViewStyle}
|
||||
>
|
||||
{Array.from({ length: 50 }).map((item, i) =>
|
||||
{Array.from({ length: 50 }).map((item, i) => (
|
||||
<View key={i} style={[styles.box, styles.horizontalBox]}>
|
||||
<Text>
|
||||
{i}
|
||||
</Text>
|
||||
<Text>{i}</Text>
|
||||
</View>
|
||||
)}
|
||||
))}
|
||||
</ScrollView>
|
||||
<Button
|
||||
onPress={() => {
|
||||
|
||||
@@ -13,14 +13,28 @@ import PropThumbColor from './examples/PropThumbColor';
|
||||
import PropTrackColor from './examples/PropTrackColor';
|
||||
import PropValue from './examples/PropValue';
|
||||
import React from 'react';
|
||||
import { storiesOf } from '@kadira/storybook';
|
||||
import UIExplorer, { AppText, Code, DocItem } from '../../ui-explorer';
|
||||
import UIExplorer, {
|
||||
AppText,
|
||||
Code,
|
||||
Description,
|
||||
DocItem,
|
||||
Section,
|
||||
storiesOf
|
||||
} from '../../ui-explorer';
|
||||
|
||||
const sections = [
|
||||
{
|
||||
title: 'Props',
|
||||
entries: [
|
||||
<DocItem name="...View props" />,
|
||||
const SwitchScreen = () => (
|
||||
<UIExplorer title="Switch" url="1-components/Switch">
|
||||
<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="The color of the thumb grip when the switch is turned on."
|
||||
@@ -29,7 +43,7 @@ const sections = [
|
||||
}}
|
||||
name="activeThumbColor"
|
||||
typeInfo="?color = #009688"
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
description="The color of the track when the switch is turned on."
|
||||
@@ -38,16 +52,16 @@ const sections = [
|
||||
}}
|
||||
name="activeTrackColor"
|
||||
typeInfo="?color = #A3D3CF"
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
description="If `true` the user won't be able to interact with the switch."
|
||||
description="If true, the user won't be able to interact with the switch."
|
||||
example={{
|
||||
render: () => <PropDisabled />
|
||||
}}
|
||||
name="disabled"
|
||||
typeInfo="?boolean = false"
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
description="Invoked with the new value when the value changes."
|
||||
@@ -56,7 +70,7 @@ const sections = [
|
||||
}}
|
||||
name="onValueChange"
|
||||
typeInfo="?function"
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
description="The color of the thumb grip when the switch is turned off."
|
||||
@@ -65,7 +79,7 @@ const sections = [
|
||||
}}
|
||||
name="thumbColor"
|
||||
typeInfo="?color = #FAFAFA"
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
description="The color of the track when the switch is turned off."
|
||||
@@ -74,7 +88,7 @@ const sections = [
|
||||
}}
|
||||
name="trackColor"
|
||||
typeInfo="?color = #939393"
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
description="The value of the switch. If `true` the switch will be turned on."
|
||||
@@ -83,21 +97,21 @@ const sections = [
|
||||
}}
|
||||
name="value"
|
||||
typeInfo="?boolean = false"
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
description="(For compatibility with React Native. Equivalent to "activeTrackColor")"
|
||||
label="compat"
|
||||
name="onTintColor"
|
||||
typeInfo="?color"
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
description="(For compatibility with React Native. Equivalent to "trackColor")"
|
||||
label="compat"
|
||||
name="tintColor"
|
||||
typeInfo="?color"
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
description="(For compatibility with React Native. Equivalent to "thumbColor")"
|
||||
@@ -105,12 +119,9 @@ const sections = [
|
||||
name="thumbTintColor"
|
||||
typeInfo="?color"
|
||||
/>
|
||||
]
|
||||
},
|
||||
</Section>
|
||||
|
||||
{
|
||||
title: 'More examples',
|
||||
entries: [
|
||||
<Section title="More examples">
|
||||
<DocItem
|
||||
description="Custom sizes can be created using styles"
|
||||
example={{
|
||||
@@ -118,22 +129,8 @@ const sections = [
|
||||
render: () => <CustomSize />
|
||||
}}
|
||||
/>
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
storiesOf('Components', module).add('Switch', () =>
|
||||
<UIExplorer
|
||||
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>
|
||||
}
|
||||
sections={sections}
|
||||
title="Switch"
|
||||
url="components/Switch"
|
||||
/>
|
||||
</Section>
|
||||
</UIExplorer>
|
||||
);
|
||||
|
||||
storiesOf('Components', module).add('Switch', SwitchScreen);
|
||||
@@ -9,16 +9,17 @@ import { Switch, View } from 'react-native';
|
||||
const colors = ['#1DA1F2', '#17BF63', '#F45D22', '#794BC4', '#E0245E'];
|
||||
const itemStyle = [styles.marginVertical, styles.marginRight];
|
||||
|
||||
const SwitchActiveThumbColorExample = () =>
|
||||
const SwitchActiveThumbColorExample = () => (
|
||||
<View style={styles.row}>
|
||||
<View style={itemStyle}>
|
||||
<Switch value={true} />
|
||||
</View>
|
||||
{colors.map((color, i) =>
|
||||
{colors.map((color, i) => (
|
||||
<View key={i} style={itemStyle}>
|
||||
<Switch activeThumbColor={color} activeTrackColor="#ccc" value={true} />
|
||||
</View>
|
||||
)}
|
||||
</View>;
|
||||
))}
|
||||
</View>
|
||||
);
|
||||
|
||||
export default SwitchActiveThumbColorExample;
|
||||
|
||||
@@ -9,16 +9,17 @@ import { Switch, View } from 'react-native';
|
||||
const colors = ['#1DA1F2', '#17BF63', '#F45D22', '#794BC4', '#E0245E'];
|
||||
const itemStyle = [styles.marginVertical, styles.marginRight];
|
||||
|
||||
const SwitchActiveTrackColorExample = () =>
|
||||
const SwitchActiveTrackColorExample = () => (
|
||||
<View style={styles.row}>
|
||||
<View style={itemStyle}>
|
||||
<Switch value={true} />
|
||||
</View>
|
||||
{colors.map((color, i) =>
|
||||
{colors.map((color, i) => (
|
||||
<View key={i} style={itemStyle}>
|
||||
<Switch activeThumbColor="#ccc" activeTrackColor={color} value={true} />
|
||||
</View>
|
||||
)}
|
||||
</View>;
|
||||
))}
|
||||
</View>
|
||||
);
|
||||
|
||||
export default SwitchActiveTrackColorExample;
|
||||
|
||||
@@ -6,7 +6,7 @@ import React from 'react';
|
||||
import { styles } from '../helpers';
|
||||
import { Switch, View } from 'react-native';
|
||||
|
||||
const SwitchDisabledExample = () =>
|
||||
const SwitchDisabledExample = () => (
|
||||
<View style={styles.row}>
|
||||
<View style={styles.marginRight}>
|
||||
<Switch disabled={true} value={false} />
|
||||
@@ -14,6 +14,7 @@ const SwitchDisabledExample = () =>
|
||||
<View style={styles.marginRight}>
|
||||
<Switch disabled={true} value={true} />
|
||||
</View>
|
||||
</View>;
|
||||
</View>
|
||||
);
|
||||
|
||||
export default SwitchDisabledExample;
|
||||
|
||||
@@ -28,9 +28,7 @@ class SwitchOnValueChangeExample extends PureComponent {
|
||||
style={styles.marginBottom}
|
||||
value={eventSwitchIsOn}
|
||||
/>
|
||||
<Text>
|
||||
{eventSwitchIsOn ? 'On' : 'Off'}
|
||||
</Text>
|
||||
<Text>{eventSwitchIsOn ? 'On' : 'Off'}</Text>
|
||||
</View>
|
||||
<View style={styles.alignCenter}>
|
||||
<Switch
|
||||
@@ -43,9 +41,7 @@ class SwitchOnValueChangeExample extends PureComponent {
|
||||
style={styles.marginBottom}
|
||||
value={eventSwitchRegressionIsOn}
|
||||
/>
|
||||
<Text>
|
||||
{eventSwitchRegressionIsOn ? 'On' : 'Off'}
|
||||
</Text>
|
||||
<Text>{eventSwitchRegressionIsOn ? 'On' : 'Off'}</Text>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
|
||||
@@ -9,16 +9,17 @@ import { Switch, View } from 'react-native';
|
||||
const colors = ['#ddd', '#aaa', '#999', '#666', '#000'];
|
||||
const itemStyle = [styles.marginVertical, styles.marginRight];
|
||||
|
||||
const SwitchThumbColorExample = () =>
|
||||
const SwitchThumbColorExample = () => (
|
||||
<View style={styles.row}>
|
||||
<View style={itemStyle}>
|
||||
<Switch value={false} />
|
||||
</View>
|
||||
{colors.map((color, i) =>
|
||||
{colors.map((color, i) => (
|
||||
<View key={i} style={itemStyle}>
|
||||
<Switch thumbColor={color} value={false} />
|
||||
</View>
|
||||
)}
|
||||
</View>;
|
||||
))}
|
||||
</View>
|
||||
);
|
||||
|
||||
export default SwitchThumbColorExample;
|
||||
|
||||
@@ -9,16 +9,17 @@ import { Switch, View } from 'react-native';
|
||||
const colors = ['#ddd', '#aaa', '#999', '#666', '#000'];
|
||||
const itemStyle = [styles.marginVertical, styles.marginRight];
|
||||
|
||||
const SwitchTrackColorExample = () =>
|
||||
const SwitchTrackColorExample = () => (
|
||||
<View style={styles.row}>
|
||||
<View style={itemStyle}>
|
||||
<Switch value={false} />
|
||||
</View>
|
||||
{colors.map((color, i) =>
|
||||
{colors.map((color, i) => (
|
||||
<View key={i} style={itemStyle}>
|
||||
<Switch trackColor={color} value={false} />
|
||||
</View>
|
||||
)}
|
||||
</View>;
|
||||
))}
|
||||
</View>
|
||||
);
|
||||
|
||||
export default SwitchTrackColorExample;
|
||||
|
||||
@@ -6,7 +6,7 @@ import { styles } from '../helpers';
|
||||
import React from 'react';
|
||||
import { Switch, View } from 'react-native';
|
||||
|
||||
const SwitchValueExample = () =>
|
||||
const SwitchValueExample = () => (
|
||||
<View style={styles.row}>
|
||||
<View style={styles.marginRight}>
|
||||
<Switch value={false} />
|
||||
@@ -14,6 +14,7 @@ const SwitchValueExample = () =>
|
||||
<View style={styles.marginRight}>
|
||||
<Switch value={true} />
|
||||
</View>
|
||||
</View>;
|
||||
</View>
|
||||
);
|
||||
|
||||
export default SwitchValueExample;
|
||||
|
||||
@@ -8,8 +8,164 @@ import PropChildren from './examples/PropChildren';
|
||||
import PropNumberOfLines from './examples/PropNumberOfLines';
|
||||
import PropOnPress from './examples/PropOnPress';
|
||||
import React from 'react';
|
||||
import { storiesOf } from '@kadira/storybook';
|
||||
import UIExplorer, { AppText, Code, DocItem, StyleList } from '../../ui-explorer';
|
||||
import UIExplorer, {
|
||||
AppText,
|
||||
Code,
|
||||
Description,
|
||||
DocItem,
|
||||
Section,
|
||||
storiesOf,
|
||||
StyleList
|
||||
} from '../../ui-explorer';
|
||||
|
||||
const TextScreen = () => (
|
||||
<UIExplorer title="Text" url="1-components/Text">
|
||||
<Description>
|
||||
<AppText>
|
||||
Text is component for displaying text. It supports style, basic touch handling, and inherits
|
||||
typographic styles from ancestor elements.
|
||||
</AppText>
|
||||
<AppText>
|
||||
Text is unique relative to layout: child elements use text layout ("inline") rather than
|
||||
flexbox layout. This means that elements inside of a Text are not rectangles, as they wrap
|
||||
when reaching the edge of their container.
|
||||
</AppText>
|
||||
<AppText>NOTE: Text will transfer all other props to the rendered HTML element.</AppText>
|
||||
</Description>
|
||||
|
||||
<Section title="Props">
|
||||
<DocItem
|
||||
name="accessibilityLabel"
|
||||
typeInfo="?string"
|
||||
description={
|
||||
<AppText>
|
||||
Overrides the text that is read by a screen reader when the user interacts with the
|
||||
element. (This is implemented using <Code>aria-label</Code>.)
|
||||
</AppText>
|
||||
}
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="accessibilityLiveRegion"
|
||||
typeInfo="?enum('assertive', 'none', 'polite')"
|
||||
description={
|
||||
<AppText>
|
||||
Indicates to assistive technologies whether to notify the user when the view changes.
|
||||
The values of this attribute are expressed in degrees of importance. When regions are
|
||||
specified as <Code>polite</Code> (recommended), updates take low priority. When regions
|
||||
are specified as <Code>assertive</Code>, assistive technologies will interrupt and
|
||||
immediately notify the user. (This is implemented using <Code>aria-live</Code>.)
|
||||
</AppText>
|
||||
}
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
label="web"
|
||||
name="accessibilityRole"
|
||||
typeInfo="?enum(roles)"
|
||||
description={
|
||||
<AppText>
|
||||
Allows assistive technologies to present and support interaction with the view in a
|
||||
manner that is consistent with user expectations for similar views of that type. For
|
||||
example, marking a touchable view with an <Code>accessibilityRole</Code> of{' '}
|
||||
<Code>button</Code>. For compatibility with React Native{' '}
|
||||
<Code>accessibilityTraits</Code> and <Code>accessibilityComponentType</Code> are mapped
|
||||
to <Code>accessibilityRole</Code>. (This is implemented using ARIA roles.)
|
||||
</AppText>
|
||||
}
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="accessible"
|
||||
typeInfo="?boolean"
|
||||
description={
|
||||
<AppText>
|
||||
When <Code>true</Code>, indicates that the view is an accessibility element (i.e.,
|
||||
focusable) and groups its child content. By default, all the touchable elements and
|
||||
elements with <Code>accessibilityRole</Code> of <Code>button</Code> and{' '}
|
||||
<Code>link</Code> are accessible. (This is implemented using <Code>tabindex</Code>.)
|
||||
</AppText>
|
||||
}
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="children"
|
||||
typeInfo="?any"
|
||||
description={
|
||||
<AppText>
|
||||
Child content. Nested text components will inherit the styles of their parents (only
|
||||
backgroundColor is inherited from non-<Code>Text</Code> parents).
|
||||
</AppText>
|
||||
}
|
||||
example={{
|
||||
render: () => <PropChildren />
|
||||
}}
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="importantForAccessibility"
|
||||
typeInfo="?enum('auto', 'no', 'no-hide-descendants', 'yes')"
|
||||
description={[
|
||||
<AppText>
|
||||
A value of <Code>no</Code> will remove the element from the tab flow.
|
||||
</AppText>,
|
||||
<AppText>
|
||||
A value of <Code>no-hide-descendants</Code> will hide the element and its children from
|
||||
assistive technologies. (This is implemented using <Code>aria-hidden</Code>.)
|
||||
</AppText>
|
||||
]}
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="numberOfLines"
|
||||
typeInfo="?number"
|
||||
description="Truncates the text with an ellipsis after this many lines. Currently only supports `1`."
|
||||
example={{
|
||||
render: () => <PropNumberOfLines />
|
||||
}}
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="onLayout"
|
||||
typeInfo="?function"
|
||||
description={
|
||||
<AppText>
|
||||
Invoked on mount and layout changes with{' '}
|
||||
<Code>{'{ nativeEvent: { layout: { x, y, width, height } } }'}</Code>, where{' '}
|
||||
<Code>x</Code> and <Code>y</Code> are the offsets from the parent node.
|
||||
</AppText>
|
||||
}
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="onPress"
|
||||
typeInfo="?function"
|
||||
description="Called when the Text is pressed"
|
||||
example={{
|
||||
render: () => <PropOnPress />
|
||||
}}
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="selectable"
|
||||
typeInfo="?boolean"
|
||||
description="When false, the text is not selectable."
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="style"
|
||||
typeInfo="?style"
|
||||
description={<StyleList stylePropTypes={stylePropTypes} />}
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="testID"
|
||||
typeInfo="?string"
|
||||
description="Used to locate this view in end-to-end tests. The test ID is rendered to a 'data-testid' DOM attribute"
|
||||
/>
|
||||
</Section>
|
||||
</UIExplorer>
|
||||
);
|
||||
|
||||
const stylePropTypes = [
|
||||
{
|
||||
@@ -112,142 +268,4 @@ const stylePropTypes = [
|
||||
}
|
||||
];
|
||||
|
||||
const sections = [
|
||||
{
|
||||
title: 'Props',
|
||||
entries: [
|
||||
<DocItem
|
||||
name="accessibilityLabel"
|
||||
typeInfo="?string"
|
||||
description="Overrides the text that is read by a screen reader when the user interacts with the element. (This is implemented using 'aria-label'.)"
|
||||
/>,
|
||||
|
||||
<DocItem
|
||||
name="accessibilityLiveRegion"
|
||||
typeInfo="?enum('assertive', 'none', 'polite')"
|
||||
description={
|
||||
<AppText>
|
||||
Indicates to assistive technologies whether to notify the user when the view changes.
|
||||
The values of this attribute are expressed in degrees of importance. When regions are
|
||||
specified as <Code>polite</Code> (recommended), updates take low priority. When regions
|
||||
are specified as <Code>assertive</Code>, assistive technologies will interrupt and
|
||||
immediately notify the user. (This is implemented using 'aria-live'.)
|
||||
</AppText>
|
||||
}
|
||||
/>,
|
||||
|
||||
<DocItem
|
||||
label="web"
|
||||
name="accessibilityRole"
|
||||
typeInfo="?enum(roles)"
|
||||
description={
|
||||
<AppText>
|
||||
Allows assistive technologies to present and support interaction with the view in a
|
||||
manner that is consistent with user expectations for similar views of that type. For
|
||||
example, marking a touchable view with an <Code>accessibilityRole</Code> of{' '}
|
||||
<Code>button</Code>. For compatibility with React Native{' '}
|
||||
<Code>accessibilityTraits</Code> and <Code>accessibilityComponentType</Code> are mapped
|
||||
to <Code>accessibilityRole</Code>. (This is implemented using ARIA roles.)
|
||||
</AppText>
|
||||
}
|
||||
/>,
|
||||
|
||||
<DocItem
|
||||
name="accessible"
|
||||
typeInfo="?boolean"
|
||||
description={
|
||||
<AppText>
|
||||
When <Code>true</Code>, indicates that the view is an accessibility element (i.e.,
|
||||
focusable) and groups its child content. By default, all the touchable elements and
|
||||
elements with <Code>accessibilityRole</Code> of <Code>button</Code> and{' '}
|
||||
<Code>link</Code> are accessible. (This is implemented using 'tabindex'.)
|
||||
</AppText>
|
||||
}
|
||||
/>,
|
||||
|
||||
<DocItem
|
||||
name="children"
|
||||
typeInfo="?any"
|
||||
description={`Child content. Nested text components will inherit the styles of their parents
|
||||
(only backgroundColor is inherited from non-Text parents). <Text>
|
||||
only supports other <Text> and raw text (strings) as children.`}
|
||||
example={{
|
||||
code: '',
|
||||
render: () => <PropChildren />
|
||||
}}
|
||||
/>,
|
||||
|
||||
<DocItem
|
||||
name="importantForAccessibility"
|
||||
typeInfo="?enum('auto', 'no', 'no-hide-descendants', 'yes')"
|
||||
description={
|
||||
'A value of `no` will remove the element from the tab flow.\n\nA value of `no-hide-descendants` will hide the element and its children from assistive technologies. (This is implemented using `aria-hidden`.)'
|
||||
}
|
||||
/>,
|
||||
|
||||
<DocItem
|
||||
name="numberOfLines"
|
||||
typeInfo="?number"
|
||||
description="Truncates the text with an ellipsis after this many lines. Currently only supports `1`."
|
||||
example={{
|
||||
code: '',
|
||||
render: () => <PropNumberOfLines />
|
||||
}}
|
||||
/>,
|
||||
|
||||
<DocItem
|
||||
name="onLayout"
|
||||
typeInfo="?function"
|
||||
description="Invoked on mount and layout changes with `{ nativeEvent: { layout: { x, y, width, height } } }`, where `x` and `y` are the offsets from the parent node."
|
||||
/>,
|
||||
|
||||
<DocItem
|
||||
name="onPress"
|
||||
typeInfo="?function"
|
||||
description="Called when the Text is pressed"
|
||||
example={{
|
||||
code: '',
|
||||
render: () => <PropOnPress />
|
||||
}}
|
||||
/>,
|
||||
|
||||
<DocItem
|
||||
name="selectable"
|
||||
typeInfo="?boolean"
|
||||
description="When `false`, the text is not selectable."
|
||||
/>,
|
||||
|
||||
<DocItem
|
||||
name="style"
|
||||
typeInfo="?style"
|
||||
description={<StyleList stylePropTypes={stylePropTypes} />}
|
||||
/>,
|
||||
|
||||
<DocItem
|
||||
name="testID"
|
||||
typeInfo="?string"
|
||||
description="Used to locate this view in end-to-end tests. The test ID is rendered to a `data-testid` DOM attribute"
|
||||
/>
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
storiesOf('Components', module).add('Text', () =>
|
||||
<UIExplorer
|
||||
description={[
|
||||
<AppText>
|
||||
Text is component for displaying text. It supports style, basic touch handling, and inherits
|
||||
typographic styles from ancestor elements.
|
||||
</AppText>,
|
||||
<AppText>
|
||||
Text is unique relative to layout: child elements use text layout ("inline") rather than
|
||||
flexbox layout. This means that elements inside of a Text are not rectangles, as they wrap
|
||||
when reaching the edge of their container.
|
||||
</AppText>,
|
||||
<AppText>NOTE: Text will transfer all other props to the rendered HTML element.</AppText>
|
||||
]}
|
||||
sections={sections}
|
||||
title="Text"
|
||||
url="components/Text"
|
||||
/>
|
||||
);
|
||||
storiesOf('Components', module).add('Text', TextScreen);
|
||||
@@ -7,12 +7,11 @@
|
||||
import React from 'react';
|
||||
import { Image, Text, View } from 'react-native';
|
||||
|
||||
const Entity = ({ children }) =>
|
||||
<Text style={{ fontWeight: '500', color: '#527fe4' }}>
|
||||
{children}
|
||||
</Text>;
|
||||
const Entity = ({ children }) => (
|
||||
<Text style={{ fontWeight: '500', color: '#527fe4' }}>{children}</Text>
|
||||
);
|
||||
|
||||
const TextChildrenExample = () =>
|
||||
const TextChildrenExample = () => (
|
||||
<View>
|
||||
<Text>
|
||||
This text contains an inline blue view{' '}
|
||||
@@ -39,6 +38,7 @@ const TextChildrenExample = () =>
|
||||
<Text>
|
||||
(is inherited
|
||||
<Text style={{ opacity: 0.7 }}>
|
||||
{'\n'}
|
||||
(and accumulated
|
||||
<Text style={{ backgroundColor: '#ffaaaa' }}>(and also applies to the background)</Text>
|
||||
)
|
||||
@@ -51,6 +51,7 @@ const TextChildrenExample = () =>
|
||||
<Entity>Entity Name</Entity>
|
||||
</Text>
|
||||
</View>
|
||||
</View>;
|
||||
</View>
|
||||
);
|
||||
|
||||
export default TextChildrenExample;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
import React from 'react';
|
||||
import { Text, View } from 'react-native';
|
||||
|
||||
const TextNumberOfLinesExample = () =>
|
||||
const TextNumberOfLinesExample = () => (
|
||||
<View style={{ maxWidth: 320 }}>
|
||||
<Text numberOfLines={1}>
|
||||
Maximum of one line, no matter how much I write here. If I keep writing, it
|
||||
@@ -22,6 +22,7 @@ const TextNumberOfLinesExample = () =>
|
||||
{"'"}
|
||||
ll just keep going and going.
|
||||
</Text>
|
||||
</View>;
|
||||
</View>
|
||||
);
|
||||
|
||||
export default TextNumberOfLinesExample;
|
||||
|
||||
@@ -22,9 +22,7 @@ class TextOnPressExample extends React.Component {
|
||||
Text has built-in onPress handling
|
||||
</Text>
|
||||
<View style={styles.logBox}>
|
||||
<Text>
|
||||
{textLog}
|
||||
</Text>
|
||||
<Text>{textLog}</Text>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
|
||||
@@ -5,8 +5,7 @@
|
||||
/*
|
||||
import createReactClass from 'create-react-class';
|
||||
import React from 'react';
|
||||
import { storiesOf } from '@kadira/storybook';
|
||||
import UIExplorer, { PropText, StyleList } from '../../ui-explorer';
|
||||
import UIExplorer, { PropText, storiesOf, StyleList } from '../../ui-explorer';
|
||||
import { Image, Text, View } from 'react-native';
|
||||
|
||||
const AttributeToggler = createReactClass({
|
||||
|
||||
@@ -18,15 +18,31 @@ import PropSecureTextEntry from './examples/PropSecureTextEntry';
|
||||
import PropSelectTextOnFocus from './examples/PropSelectTextOnFocus';
|
||||
import TextInputEvents from './examples/TextInputEvents';
|
||||
import TextInputRewrite, { TextInputRewriteInvalidCharacters } from './examples/Rewrite';
|
||||
import TouchableWrapper from './examples/TouchableWrapper';
|
||||
import React from 'react';
|
||||
import { storiesOf } from '@kadira/storybook';
|
||||
import UIExplorer, { AppText, Code, DocItem, StyleList, TextList } from '../../ui-explorer';
|
||||
import UIExplorer, {
|
||||
AppText,
|
||||
Code,
|
||||
Description,
|
||||
DocItem,
|
||||
Section,
|
||||
storiesOf,
|
||||
StyleList,
|
||||
TextList
|
||||
} from '../../ui-explorer';
|
||||
|
||||
const sections = [
|
||||
{
|
||||
title: 'Props',
|
||||
entries: [
|
||||
<DocItem name="...View props" />,
|
||||
const TextInputScreen = () => (
|
||||
<UIExplorer title="TextInput" url="1-components/TextInput">
|
||||
<Description>
|
||||
<AppText>
|
||||
Accessible single- and multi-line text input via a keyboard. Supports features such as
|
||||
auto-complete, auto-focus, placeholder text, and event callbacks. Note: some props are
|
||||
exclusive to or excluded from <Code>multiline</Code>.
|
||||
</AppText>
|
||||
</Description>
|
||||
|
||||
<Section title="Props">
|
||||
<DocItem name="...View props" />
|
||||
|
||||
<DocItem
|
||||
name="autoCapitalize"
|
||||
@@ -54,10 +70,9 @@ const sections = [
|
||||
/>
|
||||
]}
|
||||
example={{
|
||||
code: '',
|
||||
render: () => <PropAutoCapitalize />
|
||||
}}
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
label="web"
|
||||
@@ -75,19 +90,19 @@ const sections = [
|
||||
</AppText>
|
||||
</AppText>
|
||||
}
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="autoCorrect"
|
||||
typeInfo="?boolean = true"
|
||||
description="Automatically correct spelling mistakes (only available in iOS Safari)."
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="autoFocus"
|
||||
typeInfo="?boolean = false"
|
||||
description="If `true`, focuses the input on `componentDidMount`. Only the first form element in a document with `autofocus` is focused."
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="blurOnSubmit"
|
||||
@@ -104,7 +119,7 @@ const sections = [
|
||||
example={{
|
||||
render: () => <PropBlurOnSubmit />
|
||||
}}
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="clearTextOnFocus"
|
||||
@@ -113,7 +128,7 @@ const sections = [
|
||||
example={{
|
||||
render: () => <PropClearTextOnFocus />
|
||||
}}
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="defaultValue"
|
||||
@@ -125,81 +140,76 @@ const sections = [
|
||||
<Code>value</Code> prop to keep the controlled state in sync.
|
||||
</AppText>
|
||||
}
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="editable"
|
||||
typeInfo="?boolean = true"
|
||||
description="If `false`, text is not editable (i.e., read-only). "
|
||||
example={{
|
||||
code: '',
|
||||
render: () => <PropEditable />
|
||||
}}
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="keyboardType"
|
||||
typeInfo="enum('default', 'email-address', 'numeric', 'phone-pad', 'search', 'url', 'web-search') = 'default'"
|
||||
description="Determines which keyboard to open on devices with a virtual keyboard. Safari iOS requires an ancestral `<form action>` element to display the `search` keyboard). (Not available when `multiline` is `true`.)"
|
||||
example={{
|
||||
code: '',
|
||||
render: () => <PropKeyboardType />
|
||||
}}
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="maxLength"
|
||||
typeInfo="?number"
|
||||
description="Limits the maximum number of characters that can be entered."
|
||||
example={{
|
||||
code: '',
|
||||
render: () => <PropMaxLength />
|
||||
}}
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="multiline"
|
||||
typeInfo="?boolean = false"
|
||||
description="If true, the text input can be multiple lines."
|
||||
example={{
|
||||
code: '',
|
||||
render: () => <PropMultiline />
|
||||
}}
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="numberOfLines"
|
||||
typeInfo="?number"
|
||||
description="Sets the number of lines for a multiline `TextInput`. (Requires `multiline` to be `true`.)"
|
||||
example={{
|
||||
code: '',
|
||||
render: () => <PropNumberOfLines />
|
||||
}}
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="onBlur"
|
||||
typeInfo="?function"
|
||||
description="Callback that is called when the text input is blurred."
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="onChange"
|
||||
typeInfo="?function"
|
||||
description="Callback that is called when the text input's text changes."
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="onChangeText"
|
||||
typeInfo="?function"
|
||||
description="Callback that is called when the text input's text changes. The text is passed as an argument to the callback handler."
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="onFocus"
|
||||
typeInfo="?function"
|
||||
description="Callback that is called when the text input is focused."
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="onKeyPress"
|
||||
@@ -215,7 +225,13 @@ nativeEvent: { key: keyValue } }`}</Code>{' '}
|
||||
<Code>nativeEvent</Code>. Fires before <Code>onChange</Code> callbacks.
|
||||
</AppText>
|
||||
}
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="onLayout"
|
||||
typeInfo="?function"
|
||||
description="Invoked on mount and layout changes with {x, y, width, height}."
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="onSelectionChange"
|
||||
@@ -229,49 +245,46 @@ nativeEvent: { key: keyValue } }`}</Code>{' '}
|
||||
example={{
|
||||
render: () => <PropOnSelectionChange />
|
||||
}}
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="onSubmitEditing"
|
||||
typeInfo="?function"
|
||||
description="Callback that is called when the keyboard's submit button is pressed. When multiline={true}, this is only called if blurOnSubmit={true}."
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="placeholder"
|
||||
typeInfo="?string"
|
||||
description="The string that will be rendered in an empty `TextInput` before text has been entered."
|
||||
example={{
|
||||
code: '',
|
||||
render: () => <PropPlaceholder />
|
||||
}}
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="secureTextEntry"
|
||||
typeInfo="?boolean = false"
|
||||
description="If true, the text input obscures the text entered so that sensitive text like passwords stay secure. (Not available when `multiline` is `true`.)"
|
||||
example={{
|
||||
code: '',
|
||||
render: () => <PropSecureTextEntry />
|
||||
}}
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="selection"
|
||||
typeInfo="?{ start: number, end: ?number }"
|
||||
description="The start and end of the text input's selection. Set start and end to the same value to position the cursor."
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="selectTextOnFocus"
|
||||
typeInfo="?boolean = false"
|
||||
description="If `true`, all text will automatically be selected on focus."
|
||||
example={{
|
||||
code: '',
|
||||
render: () => <PropSelectTextOnFocus />
|
||||
}}
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="style"
|
||||
@@ -290,7 +303,7 @@ nativeEvent: { key: keyValue } }`}</Code>{' '}
|
||||
]}
|
||||
/>
|
||||
}
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="value"
|
||||
@@ -309,43 +322,40 @@ nativeEvent: { key: keyValue } }`}</Code>{' '}
|
||||
</AppText>
|
||||
}
|
||||
/>
|
||||
]
|
||||
},
|
||||
</Section>
|
||||
|
||||
<Section title="Instance methods">
|
||||
<DocItem name="blur" typeInfo="() => void" description="Blur the underlying DOM input." />
|
||||
|
||||
{
|
||||
title: 'Instance methods',
|
||||
entries: [
|
||||
<DocItem name="blur" typeInfo="() => void" description="Blur the underlying DOM input." />,
|
||||
<DocItem
|
||||
name="clear"
|
||||
typeInfo="() => void"
|
||||
description="Clear the text from the underlying DOM input."
|
||||
/>,
|
||||
<DocItem name="focus" typeInfo="() => void" description="Focus the underlying DOM input." />,
|
||||
/>
|
||||
|
||||
<DocItem name="focus" typeInfo="() => void" description="Focus the underlying DOM input." />
|
||||
|
||||
<DocItem
|
||||
name="isFocused"
|
||||
typeInfo="() => boolean"
|
||||
description="Returns `true` if the input is currently focused; `false` otherwise."
|
||||
/>
|
||||
]
|
||||
},
|
||||
</Section>
|
||||
|
||||
{
|
||||
title: 'More examples',
|
||||
entries: [
|
||||
<Section title="More examples">
|
||||
<DocItem
|
||||
description="TextInput events"
|
||||
example={{
|
||||
render: () => <TextInputEvents />
|
||||
}}
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
description="Rewrite (<sp> to '_' with maxLength)"
|
||||
example={{
|
||||
render: () => <TextInputRewrite />
|
||||
}}
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
description="Rewrite (no spaces allowed)"
|
||||
@@ -353,15 +363,15 @@ nativeEvent: { key: keyValue } }`}</Code>{' '}
|
||||
render: () => <TextInputRewriteInvalidCharacters />
|
||||
}}
|
||||
/>
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
storiesOf('Components', module).add('TextInput', () =>
|
||||
<UIExplorer
|
||||
description="Accessible single- and multi-line text input via a keyboard. Supports features such as auto-complete, auto-focus, placeholder text, and event callbacks. Note: some props are exclusive to or excluded from `multiline`."
|
||||
sections={sections}
|
||||
title="TextInput"
|
||||
url="components/TextInput"
|
||||
/>
|
||||
<DocItem
|
||||
description="Wrapped in a TouchableWithoutFeedback"
|
||||
example={{
|
||||
render: () => <TouchableWrapper />
|
||||
}}
|
||||
/>
|
||||
</Section>
|
||||
</UIExplorer>
|
||||
);
|
||||
|
||||
storiesOf('Components', module).add('TextInput', TextInputScreen);
|
||||
@@ -6,7 +6,7 @@ import React from 'react';
|
||||
import { WithLabel, styles } from '../helpers';
|
||||
import { TextInput, View } from 'react-native';
|
||||
|
||||
const TextInputAutoCapitalizeExample = () =>
|
||||
const TextInputAutoCapitalizeExample = () => (
|
||||
<View>
|
||||
<WithLabel label="none">
|
||||
<TextInput autoCapitalize="none" style={styles.textinput} />
|
||||
@@ -20,6 +20,7 @@ const TextInputAutoCapitalizeExample = () =>
|
||||
<WithLabel label="characters">
|
||||
<TextInput autoCapitalize="characters" style={styles.textinput} />
|
||||
</WithLabel>
|
||||
</View>;
|
||||
</View>
|
||||
);
|
||||
|
||||
export default TextInputAutoCapitalizeExample;
|
||||
|
||||
@@ -6,7 +6,7 @@ import React from 'react';
|
||||
import { styles, WithLabel } from '../helpers';
|
||||
import { TextInput, View } from 'react-native';
|
||||
|
||||
const TextInputClearButtonModeExample = () =>
|
||||
const TextInputClearButtonModeExample = () => (
|
||||
<View>
|
||||
<WithLabel label="never">
|
||||
<TextInput clearButtonMode="never" style={styles.textinput} />
|
||||
@@ -20,6 +20,7 @@ const TextInputClearButtonModeExample = () =>
|
||||
<WithLabel label="always">
|
||||
<TextInput clearButtonMode="always" style={styles.textinput} />
|
||||
</WithLabel>
|
||||
</View>;
|
||||
</View>
|
||||
);
|
||||
|
||||
export default TextInputClearButtonModeExample;
|
||||
|
||||
@@ -6,7 +6,7 @@ import React from 'react';
|
||||
import { styles } from '../helpers';
|
||||
import { TextInput, View } from 'react-native';
|
||||
|
||||
const TextInputClearTextOnFocusExample = () =>
|
||||
const TextInputClearTextOnFocusExample = () => (
|
||||
<View>
|
||||
<TextInput
|
||||
clearTextOnFocus={true}
|
||||
@@ -21,6 +21,7 @@ const TextInputClearTextOnFocusExample = () =>
|
||||
placeholder="text is cleared on focus"
|
||||
style={styles.multiline}
|
||||
/>
|
||||
</View>;
|
||||
</View>
|
||||
);
|
||||
|
||||
export default TextInputClearTextOnFocusExample;
|
||||
|
||||
@@ -6,7 +6,7 @@ import React from 'react';
|
||||
import { styles } from '../helpers';
|
||||
import { TextInput, View } from 'react-native';
|
||||
|
||||
const TextInputEditableExample = () =>
|
||||
const TextInputEditableExample = () => (
|
||||
<View>
|
||||
<TextInput defaultValue="uneditable text input" editable={false} style={styles.textinput} />
|
||||
<TextInput
|
||||
@@ -15,6 +15,7 @@ const TextInputEditableExample = () =>
|
||||
multiline={true}
|
||||
style={styles.multiline}
|
||||
/>
|
||||
</View>;
|
||||
</View>
|
||||
);
|
||||
|
||||
export default TextInputEditableExample;
|
||||
|
||||
@@ -21,13 +21,14 @@ const keyboardTypes = [
|
||||
'numeric'
|
||||
];
|
||||
|
||||
const TextInputKeyboardTypeExample = () =>
|
||||
const TextInputKeyboardTypeExample = () => (
|
||||
<View>
|
||||
{keyboardTypes.map(type =>
|
||||
{keyboardTypes.map(type => (
|
||||
<WithLabel key={type} label={type}>
|
||||
<TextInput keyboardType={type} style={styles.textinput} />
|
||||
</WithLabel>
|
||||
)}
|
||||
</View>;
|
||||
))}
|
||||
</View>
|
||||
);
|
||||
|
||||
export default TextInputKeyboardTypeExample;
|
||||
|
||||
@@ -6,7 +6,7 @@ import React from 'react';
|
||||
import { styles, WithLabel } from '../helpers';
|
||||
import { TextInput, View } from 'react-native';
|
||||
|
||||
const TextInputMaxLengthExample = () =>
|
||||
const TextInputMaxLengthExample = () => (
|
||||
<View>
|
||||
<WithLabel label="maxLength: 5">
|
||||
<TextInput maxLength={5} style={styles.textinput} />
|
||||
@@ -20,6 +20,7 @@ const TextInputMaxLengthExample = () =>
|
||||
<WithLabel label="maxLength: 5 with very long default value already set">
|
||||
<TextInput defaultValue="9402512345" maxLength={5} style={styles.textinput} />
|
||||
</WithLabel>
|
||||
</View>;
|
||||
</View>
|
||||
);
|
||||
|
||||
export default TextInputMaxLengthExample;
|
||||
|
||||
@@ -6,10 +6,11 @@ import React from 'react';
|
||||
import { styles } from '../helpers';
|
||||
import { TextInput, View } from 'react-native';
|
||||
|
||||
const TextInputMultilineExample = () =>
|
||||
const TextInputMultilineExample = () => (
|
||||
<View>
|
||||
<TextInput multiline={true} style={styles.multiline} />
|
||||
<TextInput multiline={true} style={styles.multiline} />
|
||||
</View>;
|
||||
</View>
|
||||
);
|
||||
|
||||
export default TextInputMultilineExample;
|
||||
|
||||
@@ -6,7 +6,7 @@ import React from 'react';
|
||||
import { styles } from '../helpers';
|
||||
import { TextInput, View } from 'react-native';
|
||||
|
||||
const TextInputNumberOfLinesExample = () =>
|
||||
const TextInputNumberOfLinesExample = () => (
|
||||
<View>
|
||||
<TextInput
|
||||
multiline={true}
|
||||
@@ -20,6 +20,7 @@ const TextInputNumberOfLinesExample = () =>
|
||||
placeholder="numberOfLines = 3"
|
||||
style={[styles.multiline, { height: 'auto' }]}
|
||||
/>
|
||||
</View>;
|
||||
</View>
|
||||
);
|
||||
|
||||
export default TextInputNumberOfLinesExample;
|
||||
|
||||
@@ -84,9 +84,7 @@ class OnSelectionChangeExample extends React.Component {
|
||||
value={this.state.value}
|
||||
/>
|
||||
<View>
|
||||
<Text>
|
||||
selection = {JSON.stringify(this.state.selection)}
|
||||
</Text>
|
||||
<Text>selection = {JSON.stringify(this.state.selection)}</Text>
|
||||
<Text onPress={this.placeAt(0)}>Place at Start (0, 0)</Text>
|
||||
<Text onPress={this.placeAt(length)}>
|
||||
Place at End ({length}, {length})
|
||||
@@ -100,7 +98,7 @@ class OnSelectionChangeExample extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
const TextInputOnSelectionChangeExample = () =>
|
||||
const TextInputOnSelectionChangeExample = () => (
|
||||
<View>
|
||||
<OnSelectionChangeExample style={styles.textinput} value="text selection can be changed" />
|
||||
<OnSelectionChangeExample
|
||||
@@ -108,6 +106,7 @@ const TextInputOnSelectionChangeExample = () =>
|
||||
style={styles.multiline}
|
||||
value={'multiline text selection\ncan also be changed'}
|
||||
/>
|
||||
</View>;
|
||||
</View>
|
||||
);
|
||||
|
||||
export default TextInputOnSelectionChangeExample;
|
||||
|
||||
@@ -6,10 +6,11 @@ import React from 'react';
|
||||
import { styles } from '../helpers';
|
||||
import { TextInput, View } from 'react-native';
|
||||
|
||||
const TextInputPlaceholderExample = () =>
|
||||
const TextInputPlaceholderExample = () => (
|
||||
<View>
|
||||
<TextInput placeholder="This is placeholder text" style={styles.textinput} />
|
||||
<TextInput multiline={true} placeholder="This is placeholder text" style={styles.multiline} />
|
||||
</View>;
|
||||
</View>
|
||||
);
|
||||
|
||||
export default TextInputPlaceholderExample;
|
||||
|
||||
@@ -6,12 +6,8 @@ import React from 'react';
|
||||
import { styles } from '../helpers';
|
||||
import { TextInput } from 'react-native';
|
||||
|
||||
const TextInputSecureTextEntryExample = () =>
|
||||
<TextInput
|
||||
defaultValue="abc"
|
||||
numberOfLines={2}
|
||||
secureTextEntry={true}
|
||||
style={styles.textinput}
|
||||
/>;
|
||||
const TextInputSecureTextEntryExample = () => (
|
||||
<TextInput defaultValue="abc" numberOfLines={2} secureTextEntry={true} style={styles.textinput} />
|
||||
);
|
||||
|
||||
export default TextInputSecureTextEntryExample;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user