Compare commits

..

115 Commits

Author SHA1 Message Date
Nicolas Gallagher
450722153d 0.0.128 2017-09-20 09:45:25 -07:00
Nicolas Gallagher
fbba32defb [fix] cross-browser flex styles
Fix #616
Close #648
2017-09-19 15:44:10 -07:00
Nicolas Gallagher
d762d64b49 Revert SSR Image change
Reverts 3c660e2ad7

See #543
2017-09-19 15:23:09 -07:00
Nicolas Gallagher
a5b1dda62d 0.0.127 2017-09-19 15:12:13 -07:00
Nicolas Gallagher
aad904b550 [fix] remove 'use strict' from warnValidStyle 2017-09-19 15:07:54 -07:00
Unknown
a01e895e30 [change] RefreshControl placeholder
Fix #638
Close #644
2017-09-19 13:44:31 -07:00
Nicolas Gallagher
52e5d41518 [fix] keyboard interaction with Touchable as link
Fix #643
Close #645
2017-09-19 13:40:57 -07:00
Nicolas Gallagher
77a40b6237 [fix] Easing import when using babel plugin
Fix #649
2017-09-19 13:37:12 -07:00
Nicolas Gallagher
4bbe1a40aa 0.0.126 2017-09-18 21:08:39 -07:00
Nicolas Gallagher
6942e4e417 Shallow render ActivityIndicator tests
These snapshots should be improved by flattening the React Native style
object.
2017-09-18 19:47:03 -07:00
Nicolas Gallagher
63daff7f80 Simplify Switch tests 2017-09-18 19:32:02 -07:00
Nicolas Gallagher
662b7c3d6e Simplify Image snapshot testing 2017-09-18 19:26:48 -07:00
Nicolas Gallagher
12fb588596 Simplify View snapshot testing 2017-09-18 19:26:11 -07:00
Nicolas Gallagher
5cb09b1a9e [fix] disallow text node children of View
Catch text nodes that are not the only child of View. Fixes a case
missing from 0ad6ab948b.
2017-09-18 13:28:51 -07:00
Nicolas Gallagher
c03cfdf8bd Add compile task to build task 2017-09-17 11:25:50 -07:00
Nicolas Gallagher
997b598de8 [fix] event normalization
Work better with simulated events, and avoid crashing if
'nativeEvent.target' isn't an element node.

Close #597
2017-09-15 15:16:40 -07:00
Nicolas Gallagher
6fe796f9da [add] accessibilityRole 'label' to Text 2017-09-15 11:29:44 -07:00
Nicolas Gallagher
0ad6ab948b [fix] disallow text node children of View
Fix #627
2017-09-15 11:29:41 -07:00
Nicolas Gallagher
32a23136af 0.0.125 2017-09-14 15:16:52 -07:00
Nicolas Gallagher
96f48226cb [fix] ColorPropType validation
Check color is of type string before using `indexOf`.

Fix #630
2017-09-14 13:19:13 -07:00
Peter Schussheim
f1ef0f21af Fix typo in NetInfo docs 2017-09-14 11:31:18 -07:00
Unknown
d42e8907ca [fix] return value of Keyboard.addListener
Close #631
Fix #632
2017-09-14 11:26:46 -07:00
Nicolas Gallagher
90724b2cef [fix] filter unsupported ScrollView props
Fix #633
2017-09-14 11:20:18 -07:00
Nicolas Gallagher
dd0f1de3d1 [fix] avoid prop types check on UnimplementedView
Fix #635
2017-09-14 11:08:36 -07:00
Nicolas Gallagher
fc751ed715 [fix] remove TouchalbeWithoutFeedback children prop type
Fix #634
2017-09-14 10:49:49 -07:00
Nicolas Gallagher
917b06a690 Update README 2017-09-13 11:27:36 -07:00
Nicolas Gallagher
80cb7baf82 0.0.124 2017-09-12 15:58:28 -07:00
Nicolas Gallagher
f08515b1f1 Avoid compiling tests 2017-09-12 15:58:14 -07:00
Nicolas Gallagher
8591bf7ce5 [fix] add AppState to Babel plugin list 2017-09-12 15:46:27 -07:00
Nicolas Gallagher
b7c8f00fcc 0.0.123 2017-09-12 11:31:49 -07:00
Nicolas Gallagher
ed81b985a9 Include the babel dir in published package 2017-09-12 11:31:38 -07:00
Nicolas Gallagher
441dc8efff 0.0.122 2017-09-12 10:54:01 -07:00
Paul Armstrong
7e8ef5b72c Add babel plugin to rewrite import paths
Replace 'react-native' imports with direct imports to the relevant
module within 'react-native-web'. Follow up task is to also rewrite
'react-native-web' imports from the entry file to become direct imports
(reduces bundle size).

Close #608
2017-09-12 10:45:42 -07:00
Nicolas Gallagher
641c8c47e0 [change] Button text style to match Android 2017-09-11 15:52:44 -07:00
Nicolas Gallagher
87ead7f64e Fix doc styles 2017-09-11 15:52:41 -07:00
Nicolas Gallagher
5ed2127175 [fix] default Text styles
Match React Native's default font-size for Text, and use the system font
stack by default. Nested Text elements will inherit font styles from
their parent Text.
2017-09-11 15:47:49 -07:00
Nicolas Gallagher
e802026298 Benchmarks: add emotion and latest results 2017-09-10 12:52:07 -07:00
Nicolas Gallagher
5d24f4c8fa Update jest 2017-09-10 10:36:39 -07:00
Nicolas Gallagher
a9f1afc07c Update formatter and linter tools 2017-09-10 10:35:07 -07:00
Nicolas Gallagher
d185d81560 Update build tools 2017-09-10 10:32:11 -07:00
Nicolas Gallagher
66fa09da8e Move modality initialization to StyleSheet 2017-09-10 10:28:22 -07:00
Nicolas Gallagher
bae4dd806a [change] rename createDOMElement to createElement
Allow 'createElement' to be used as a drop-in replacement for
'ReactDOM.createElement'.
2017-09-10 10:28:21 -07:00
Unknown
4a680fd9b6 [add] basic support for KeyboardAvoidingView
Close #624
2017-09-08 10:57:44 -07:00
Nicolas Gallagher
e34e4e38d3 0.0.121 2017-09-07 13:31:47 -07:00
Unknown
b23a4f55dc [add] support for Keyboard API
Close #625
2017-09-07 13:07:33 -07:00
Nicolas Gallagher
26bdf44a4c [fix] TextInput keyPress events when child of Touchable
Fix #612
2017-09-07 11:40:00 -07:00
Nicolas Gallagher
5e98107617 [fix] support "System" as a font-family on web
Fix #622
2017-09-02 12:26:36 -07:00
Nicolas Gallagher
86ea0e5eff Fix source code URLs in docs 2017-08-31 17:42:03 -07:00
Nicolas Gallagher
6e02c5690c [add] support for AssetRegistry
Applies changes from @fmoo to help with Metro packager support. Also
fixed a Flow exposed by this change.
2017-08-31 12:32:24 -07:00
Nicolas Gallagher
c50d808a2b [change] remove 'core' module export 2017-08-31 12:06:48 -07:00
Nicolas Gallagher
130b10c3f7 0.0.120 2017-08-16 16:02:33 -07:00
Nicolas Gallagher
03ddf074ea Update fbjs and inline-style-prefixer 2017-08-16 14:09:31 -07:00
Nicolas Gallagher
f201a0347d Update prettier 2017-08-16 14:07:25 -07:00
Nicolas Gallagher
fffbdff6ca Update eslint packages 2017-08-16 14:04:32 -07:00
Nicolas Gallagher
23e5c8479c Update webpack packages 2017-08-16 14:03:38 -07:00
Nicolas Gallagher
17e5e374ee Update babel packages 2017-08-16 14:01:58 -07:00
Nicolas Gallagher
ef907dce22 [add] StyleSheet validation allows table styles
Fix #605
2017-08-16 11:27:47 -07:00
Nicolas Gallagher
586f134f76 [fix] Text's CSS box-sizing default
Fix #606
2017-08-16 11:01:26 -07:00
Nicolas Gallagher
70e2a75b43 [add] don't warn about use of position:sticky 2017-08-10 17:00:21 -07:00
Nicolas Gallagher
8756c20ade Minor changes and fixes to docs 2017-08-09 09:44:36 -07:00
Nicolas Gallagher
4081d17f25 0.0.119 2017-08-01 12:08:44 -07:00
Sam
4fa6f77d25 [fix] TouchableMixin async race condition
When a Touchable component returns 0 for
`touchableGetHighlightDelayMS()` the mixin may occasionally try to
detect if the press event occurred on the hit area before the hit area
has been determined. Clearing out this value ensures that
`positionOnActivate` is recalculated before that takes place.

Close #586
2017-08-01 11:58:46 -07:00
Andrew Kennedy
17d723559d Add tests for 'Button' component
Close #583
2017-08-01 11:55:37 -07:00
Nicolas Gallagher
8d80885f5d [fix] Dimensions.get when called on the server 2017-08-01 11:55:23 -07:00
Nicolas Gallagher
3ca4becc41 0.0.118 2017-07-31 16:32:28 -07:00
Nicolas Gallagher
cc077e9019 [fix] allow Dimensions.set to be called on the server
Fix #566
2017-07-31 16:31:42 -07:00
Nicolas Gallagher
1225b00cdb Fix publishing of documentation 2017-07-30 20:25:26 -07:00
Nicolas Gallagher
ed70617e91 0.0.117 2017-07-30 20:13:29 -07:00
Nicolas Gallagher
134114de83 [fix] TextInput: call on onKeyPress for Tab and Cmd+Enter
Add support for more key combinations that only fire 'keydown' React DOM
events. And allow users to call 'preventDefault', etc., on the event.

Fix #567
Close #582
2017-07-30 20:11:19 -07:00
Nicolas Gallagher
08ee7c83bb Minor starting documentation improvement 2017-07-30 18:45:08 -07:00
Nicolas Gallagher
5fad78dcad [fix] remove unsupported TextInput props
For compatibility with React Native, do not pass on unsupported
TextInput props to avoid ReactDOM warnings.

Close #571
2017-07-29 17:30:31 -07:00
Nicolas Gallagher
e04343e48e Benchmarks: use glamor@2 and fix yarn.lock paths 2017-07-28 19:08:49 -07:00
Nicolas Gallagher
5e3a946f8b Upgrade docs to use @storybook/react 2017-07-28 15:29:39 -07:00
Nicolas Gallagher
4e3d8dbb02 [change] support CSS custom properties
Update 'setValueForStyles' and style validation to support defining and
using custom properties.

Fix #516
2017-07-28 15:29:07 -07:00
Nicolas Gallagher
fee909d26a [fix] AppState on the server
Fix #578
2017-07-27 16:30:28 -07:00
Nicolas Gallagher
9e58a7b5f1 Update GitHub files 2017-07-27 11:38:50 -07:00
Nicolas Gallagher
20e1febe21 0.0.116 2017-07-26 19:58:34 -07:00
Nicolas Gallagher
ef209ca281 Fix caniuse-api install, again 2017-07-26 19:55:43 -07:00
Nicolas Gallagher
a35949fa71 0.0.115 2017-07-26 19:25:31 -07:00
Nicolas Gallagher
f5ac856c2d Revert unrelated changes to normalizeNativeEvent 2017-07-26 19:25:18 -07:00
Nicolas Gallagher
4b557b1e0b Fix canuse-api installation 2017-07-26 19:20:34 -07:00
Nicolas Gallagher
d4e9d9d256 0.0.114 2017-07-26 16:17:28 -07:00
Nicolas Gallagher
0ff3e91592 [fix] AppState support for Android browser 4.4 2017-07-26 15:52:11 -07:00
Nicolas Gallagher
092d5d12f7 [fix] unitless values for vendor prefixed properties
Problem:

Numeric values are suffixed with 'px', unless the property supports
unitless values. However, vendor prefixed properties were ignored
resulting in invalid CSS values for properties like
'-webkit-flex-shrink'.

Solution:

Apply the upstream solution from React, which includes vendor prefixed
properties in the "unitless number" map. Also build a custom vendor
prefixer to ensure adequate browser support (i.e., Safari 7 and older
Chrome).
2017-07-26 15:51:46 -07:00
Nicolas Gallagher
507e0d41f5 Move event modules into directories 2017-07-26 15:43:10 -07:00
Nicolas Gallagher
9e863d5402 Install docs dependencies separately 2017-07-22 10:47:40 -07:00
Nicolas Gallagher
1364b1dfdf Rename benchmark script 2017-07-22 10:45:04 -07:00
Nicolas Gallagher
7f81e313ed Add link to Glitch playground 2017-07-22 10:43:25 -07:00
Nicolas Gallagher
a1892ec8b8 Update benchmark subjects and results 2017-07-15 11:04:38 -07:00
Nicolas Gallagher
e6232d5980 0.0.113 2017-07-14 10:02:38 -07:00
Nicolas Gallagher
e93a2eb478 Minor edits to View docs 2017-07-13 17:26:32 -07:00
Nicolas Gallagher
44ecf1fe87 [fix] Touchable to avoid touch delay
According to MDN, "touch-action:manipulation" enables "…panning and
pinch zoom gestures, but disables additional non-standard gestures such
as double-tap to zoom. Disabling double-tap to zoom removes the need for
browsers to delay the generation of click events when the user taps the
screen."
2017-07-13 17:13:01 -07:00
Nicolas Gallagher
faec2b4a83 [fix] ScrollView to use 'touch-action' to disable scroll
The recommendation from the Chrome team is to use 'touch-action' to
disable scrolling (via touch modality) when passive event listeners are
in use.

Close #563
2017-07-13 17:10:38 -07:00
Nicolas Gallagher
3677f0dd57 Use more components to build docs 2017-07-11 20:18:52 -07:00
Nicolas Gallagher
36d161a959 0.0.112 2017-07-11 15:39:20 -07:00
Nicolas Gallagher
1ca18ab056 [fix] TouchableWithoutFeedback keyboard support 2017-07-11 09:56:18 -07:00
Nicolas Gallagher
b43717e797 [fix] ensure 'heading' role styles are reset 2017-07-11 09:53:17 -07:00
Nicolas Gallagher
801d5f8c68 0.0.111 2017-07-10 13:14:47 -07:00
Nicolas Gallagher
30f2ec9bf5 [fix] improve Image accessibility 2017-07-10 13:13:11 -07:00
Nicolas Gallagher
6f3e29f630 [change] better Touchable support for keyboards
Problem:

Although 'Touchable' supports basic keyboard usage, it doesn't support
delays or interaction via the Space key.

Solution:

Extend the 'Touchable' mixin to better support keyboard interactions.
All touchable callbacks and delays are now supported when interacted
with via a keyboard's Enter and Space keys (as would be expected of
native 'button' elements). However, events are not normalized to mimic
touch events.

Minor upstream changes to the Touchables in React Native are also
included.
2017-07-10 12:57:16 -07:00
Nicolas Gallagher
2607cb25ab Clean up benchmark exports and PropTypes import 2017-07-09 18:43:46 -07:00
Nicolas Gallagher
8f56454ed7 0.0.110 2017-07-09 17:49:20 -07:00
Nicolas Gallagher
d03e06632e [fix] remove Image styles not supported by View 2017-07-09 17:47:47 -07:00
Nicolas Gallagher
66732394cb Update benchmark libraries 2017-07-09 16:50:01 -07:00
Nicolas Gallagher
077d2f3e63 Update flow and enzyme 2017-07-09 16:23:45 -07:00
Nicolas Gallagher
f6ad9c3afb Update prettier and linter 2017-07-09 16:22:17 -07:00
Nicolas Gallagher
f91ecaa81d Update build tools 2017-07-09 16:19:27 -07:00
Nicolas Gallagher
ad3dee0204 [change] a11y and layout: button role and DOM props
Problems:

HTML's native <button> tag doesn't support flex styling in all browsers,
causing layout bugs. And buttons or links created by "createDOMElement"
(without an accessibility role) do not have the correct props.

Solution:

The "button" role is rendered to a "div[role=button]" that is focusable
and responds to the same keyboard events as a native button. A native
button can still be rendered using "createDOMElement".

Make "createDOMProps" aware of the component context to ensure style
resets and other props are correctly applied when an accessibility role
is not defined.

Additionally:

This patch also adds a new "label" role to support accessible forms.
It maps to a native label element.

Close #241
2017-07-09 16:14:40 -07:00
Nicolas Gallagher
1a0a40d9be Minor improvements to docs text formatting 2017-07-08 20:24:49 -07:00
Vu Le
0bf6e893c6 [add] Dimensions event listeners
Close #511
2017-07-08 20:04:39 -07:00
Nicolas Gallagher
1190ca20a7 0.0.109 2017-07-03 12:33:31 -07:00
Nicolas Gallagher
8f4bed8cb9 Display example apps in storybook 2017-07-03 12:32:16 -07:00
Nicolas Gallagher
5a5d142100 [fix] flex style resolution 2017-07-03 12:32:00 -07:00
Nicolas Gallagher
fb999b5467 UIExplorer: list Components before APIs 2017-06-29 16:15:51 -07:00
Nicolas Gallagher
8b06f28281 [fix] ActivityIndicator sizing 2017-06-29 16:11:08 -07:00
298 changed files with 11974 additions and 6043 deletions

View File

@@ -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,

View File

@@ -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.

View File

@@ -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):

View File

@@ -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.

View File

@@ -3,41 +3,56 @@
[![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 the platform-agnostic Components and APIs of
[React Native][react-native-url] to the Web.
Browser support: Chrome, Firefox, Safari >= 7, IE 10, Edge.
Browse the [interactive
documentation](https://necolas.github.io/react-native-web/storybook/) or [try
it out](https://glitch.com/edit/#!/react-native-web-playground) on Glitch.
[npm-image]: https://badge.fury.io/js/react-native-web.svg
[npm-url]: https://npmjs.org/package/react-native-web
[react-native-url]: https://facebook.github.io/react-native/
[travis-image]: https://travis-ci.org/necolas/react-native-web.svg?branch=master
[travis-url]: https://travis-ci.org/necolas/react-native-web
## Features
## 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).
* Interoperability with ReactDOM components.
* Native-like touch handling.
* Built-in integration with web accessibility APIs.
* Built-in support for LTR and RTL layouts.
* Built-in expressive and reliable subset of CSS.
* Optimized, vendor-prefixed CSS with [good runtime performance](benchmarks/README.md).
* Server-side rendering of HTML and critical CSS.
* Browser support: Chrome, Firefox, Safari >= 7, IE 10, Edge.
## 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.
Then read the [Getting Started](docs/guides/getting-started.md) guide.
Install in your existing app using `yarn` or `npm`:
```
yarn add react@15.6 react-dom@15.6 react-native-web
```
Add the `react-native-web/babel` plugin to your Babel configuration. This will
alias `react-native` to `react-native-web` and exclude any modules not required
by the app.
```json
{
"plugins": [
"react-native-web/babel"
],
"presets": [
"react-native"
]
}
```
See the [Getting Started](docs/guides/getting-started.md) guide for more details.
## Documentation
The [UI Explorer](https://necolas.github.io/react-native-web/storybook/)
interactively documents all the APIs and Components.
The [interactive
documentation](https://necolas.github.io/react-native-web/storybook/) shows all
the supported APIs and Components.
Guides:
@@ -49,6 +64,13 @@ Guides:
* [Advanced use](docs/guides/advanced.md)
* [Known issues](docs/guides/known-issues.md)
## Starter kits
* [Glitch](https://glitch.com/edit/#!/react-native-web-playground)
* [create-react-app](https://github.com/facebookincubator/create-react-app)
* [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,13 +113,16 @@ 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
React Native for Web is [BSD licensed](LICENSE).
[npm-image]: https://badge.fury.io/js/react-native-web.svg
[npm-url]: https://npmjs.org/package/react-native-web
[react-native-url]: https://facebook.github.io/react-native/
[travis-image]: https://travis-ci.org/necolas/react-native-web.svg?branch=master
[travis-url]: https://travis-ci.org/necolas/react-native-web

View 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');
"
`;

View 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
View 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);
}
}
}
};
};

View File

@@ -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).

View File

@@ -5,7 +5,9 @@ const node = document.querySelector('.root');
const createRenderBenchmark = ({ description, getElement, name, runs }) => () => {
const setup = () => {};
const teardown = () => ReactDOM.unmountComponentAtNode(node);
const teardown = () => {
ReactDOM.unmountComponentAtNode(node);
};
return benchmark({
name,
@@ -13,7 +15,9 @@ const createRenderBenchmark = ({ description, getElement, name, runs }) => () =>
runs,
setup,
teardown,
task: () => ReactDOM.render(getElement(), node)
task: () => {
ReactDOM.render(getElement(), node);
}
});
};

View File

@@ -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());

View File

@@ -1,21 +1,22 @@
{
"name": "performance",
"name": "benchmarks",
"private": true,
"dependencies": {
"aphrodite": "^1.2.1",
"aphrodite": "^1.2.3",
"classnames": "^2.2.5",
"glamor": "2.20.25",
"emotion": "^7.2.2",
"glamor": "^2.20.40",
"marky": "^1.2.0",
"react-jss": "^6.1.1",
"react-primitives": "^0.4.2",
"reactxp": "^0.34.3",
"styled-components": "^2.1.0",
"radium": "^0.19.4",
"react-jss": "^7.1.0",
"react-primitives": "^0.4.3",
"reactxp": "^0.42.1",
"styled-components": "^2.1.2",
"styletron-client": "^2.5.7",
"styletron-utils": "^2.5.4"
},
"devDependencies": {
"css-loader": "^0.28.4",
"react-addons-perf": "^15.4.2",
"css-loader": "^0.28.7",
"style-loader": "^0.18.2"
}
}

View File

@@ -1,5 +1,6 @@
import PropTypes from 'prop-types';
import theme from '../theme';
import React, { PropTypes, PureComponent } from 'react';
import React, { PureComponent } from 'react';
import { StyleSheet, Text } from 'react-native';
class AppText extends PureComponent {

View File

@@ -1,4 +1,5 @@
import React, { PureComponent, PropTypes } from 'react';
import PropTypes from 'prop-types';
import React, { PureComponent } from 'react';
import { StyleSheet, View } from 'react-native';
class AspectRatio extends PureComponent {

View File

@@ -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: {
@@ -45,4 +46,4 @@ const styles = StyleSheet.create({
}
});
module.exports = Box;
export default Box;

View File

@@ -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'
})}
/>;
/>
);
module.exports = Box;
export default Box;

View 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;

View File

@@ -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: {
@@ -44,4 +45,4 @@ const styles = {
}
};
module.exports = Box;
export default Box;

View File

@@ -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: {
@@ -46,4 +47,4 @@ const styles = {
}
};
module.exports = injectSheet(styles)(Box);
export default injectSheet(styles)(Box);

View 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);

View File

@@ -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: {
@@ -45,4 +46,4 @@ const styles = StyleSheet.create({
}
});
module.exports = Box;
export default Box;

View File

@@ -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: {
@@ -44,4 +45,4 @@ const styles = StyleSheet.create({
}
});
module.exports = Box;
export default Box;

View File

@@ -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({
@@ -44,4 +45,4 @@ const styles = {
})
};
module.exports = Box;
export default Box;

View File

@@ -27,4 +27,4 @@ const Box = styled.View`
background-color: ${props => getColor(props.color)};
`;
module.exports = Box;
export default Box;

View File

@@ -28,4 +28,4 @@ const Box = styled(View)`
background-color: ${props => getColor(props.color)};
`;
module.exports = Box;
export default Box;

View File

@@ -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, {
@@ -45,4 +46,4 @@ const styles = {
})
};
module.exports = Box;
export default Box;

View File

@@ -1,5 +1,6 @@
import PropTypes from 'prop-types';
import { StyleSheet, View } from 'react-native';
import React, { Component, PropTypes } from 'react';
import React, { Component } from 'react';
import theme from '../theme';
class GridView extends Component {

View File

@@ -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" />

View File

@@ -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" />

View File

@@ -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" />

View File

@@ -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" />

View File

@@ -1,4 +1,5 @@
import React, { Component, PropTypes } from 'react';
import PropTypes from 'prop-types';
import React, { Component } from 'react';
class DeepTree extends Component {
static propTypes = {
@@ -9,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;
@@ -17,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}
@@ -26,7 +45,7 @@ class DeepTree extends Component {
key={i}
wrap={wrap}
/>
)}
))}
</Box>
);
for (let i = 0; i < wrap; i++) {
@@ -36,4 +55,4 @@ class DeepTree extends Component {
}
}
module.exports = DeepTree;
export default DeepTree;

View File

@@ -1,11 +1,12 @@
import AspectRatio from '../AspectRatio';
import GridView from '../GridView';
import PropTypes from 'prop-types';
import TweetActionsBar from '../TweetActionsBar';
import TweetText from '../TweetText';
import UserAvatar from '../UserAvatar';
import UserNames from '../UserNames';
import { Image, StyleSheet, Text, View } from 'react-native';
import React, { Component, PropTypes } from 'react';
import React, { Component } from 'react';
import theme from '../theme';
export class Tweet extends Component {
@@ -50,18 +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

View File

@@ -2,9 +2,10 @@ import IconReply from '../Icons/Reply';
import IconHeart from '../Icons/Heart';
import IconRetweet from '../Icons/Retweet';
import IconDirectMessage from '../Icons/DirectMessage';
import { Text, View, StyleSheet } from 'react-native';
import React, { PropTypes } from 'react';
import PropTypes from 'prop-types';
import React from 'react';
import theme from '../theme';
import { Text, View, StyleSheet } from 'react-native';
const getIcon = (icon, highlighted) => {
switch (icon) {

View File

@@ -1,6 +1,7 @@
import PropTypes from 'prop-types';
import TweetAction from '../TweetAction';
import { View, StyleSheet } from 'react-native';
import React, { PropTypes, PureComponent } from 'react';
import React, { PureComponent } from 'react';
const actionNames = ['reply', 'retweet', 'like', 'directMessage'];
@@ -24,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}
@@ -34,7 +35,7 @@ export default class TweetActionsBar extends PureComponent {
onPress={action.onPress}
style={styles.action}
/>
)}
))}
</View>
);
}

View File

@@ -1,15 +1,16 @@
import AppText from '../AppText';
import React from 'react';
import TweetTextPart from '../TweetTextPart';
import React, { PropTypes } from 'react';
import { array, number, string } from 'prop-types';
class TweetText extends React.Component {
static displayName = 'TweetText';
static propTypes = {
displayMode: TweetTextPart.propTypes.displayMode,
lang: PropTypes.string,
numberOfLines: PropTypes.number,
textParts: PropTypes.array.isRequired
lang: string,
numberOfLines: number,
textParts: array.isRequired
};
render() {
@@ -17,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>
);
}

View File

@@ -1,17 +1,19 @@
/* eslint-disable react/prop-types */
import { Image, StyleSheet, Text } from 'react-native';
import React, { PropTypes } from 'react';
import PropTypes from 'prop-types';
import React from 'react';
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 }) => {

View File

@@ -1,6 +1,7 @@
import AspectRatio from '../AspectRatio';
import PropTypes from 'prop-types';
import { Image, StyleSheet } from 'react-native';
import React, { PropTypes, PureComponent } from 'react';
import React, { PureComponent } from 'react';
import theme from '../theme';
class UserAvatar extends PureComponent {
@@ -22,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>
);
}

View File

@@ -1,6 +1,7 @@
import AppText from '../AppText';
import PropTypes from 'prop-types';
import { StyleSheet } from 'react-native';
import React, { PropTypes, PureComponent } from 'react';
import React, { PureComponent } from 'react';
class UserNames extends PureComponent {
static displayName = 'UserNames';
@@ -28,7 +29,9 @@ class UserNames extends PureComponent {
onPress={onPress}
style={[styles.root, style]}
>
<AppText color="normal" weight="bold">{fullName}</AppText>
<AppText color="normal" weight="bold">
{fullName}
</AppText>
{layout === 'stack' ? ' \u000A' : ' '}
<AppText color="deepGray" style={styles.screenName}>{`@${screenName}`}</AppText>
</AppText>

View File

@@ -28,4 +28,4 @@ const styles = StyleSheet.create({
}
});
module.exports = View;
export default View;

View File

@@ -10,4 +10,4 @@ class View extends React.Component {
}
}
module.exports = View;
export default View;

View 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;

View File

@@ -26,4 +26,4 @@ const viewStyle = {
minWidth: 0
};
module.exports = View;
export default View;

View File

@@ -29,4 +29,4 @@ const styles = {
}
};
module.exports = injectSheet(styles)(View);
export default injectSheet(styles)(View);

View 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);

View File

@@ -32,4 +32,4 @@ const styles = StyleSheet.create({
}
});
module.exports = View;
export default View;

View File

@@ -16,4 +16,4 @@ const View = styled.div`
min-width: 0;
`;
module.exports = View;
export default View;

View File

@@ -23,11 +23,11 @@ const fontSize = {
large: '1.25rem'
};
module.exports = {
const theme = {
colors,
fontFamily:
'-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Ubuntu, "Helvetica Neue", sans-serif, ' +
'"Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"', // emoji fonts
'"Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"', // emoji fonts
fontSize,
lineHeight: 1.3125,
spaceX: 0.6,
@@ -36,3 +36,5 @@ module.exports = {
return `${num}${unit}`;
}
};
export default theme;

View File

@@ -1,7 +1,9 @@
import Box from './components/Box/css-modules';
import View from './components/View/css-modules';
export default {
const api = {
Box,
View
};
export default api;

View File

@@ -0,0 +1,7 @@
import Box from './components/Box/emotion';
import View from './components/View/emotion';
export default {
Box,
View
};

View File

@@ -1,7 +1,9 @@
import Box from './components/Box/jss';
import View from './components/View/jss';
export default {
const api = {
Box,
View
};
export default api;

9
benchmarks/src/radium.js Normal file
View File

@@ -0,0 +1,9 @@
import Box from './components/Box/radium';
import View from './components/View/radium';
const api = {
Box,
View
};
export default api;

View File

@@ -1,7 +1,9 @@
import Box from './components/Box/react-native-stylesheet';
import View from './components/View/react-native-stylesheet';
export default {
const api = {
Box,
View
};
export default api;

View File

@@ -96,7 +96,7 @@ const tweet2 = {
}
};
const renderTweet = (label, components) =>
const renderTweet = label =>
createRenderBenchmark({
name: `Tweet [${label}]`,
runs: 10,

View File

@@ -26,7 +26,9 @@ module.exports = {
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: { cacheDirectory: true }
options: {
cacheDirectory: true
}
}
}
]

View File

@@ -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,18 @@ 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"
browserslist@^1.0.1, browserslist@^1.5.2, browserslist@^1.7.5:
version "1.7.5"
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-1.7.5.tgz#eca4713897b51e444283241facf3985de49a9e2b"
@@ -114,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"
@@ -121,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"
@@ -134,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"
@@ -144,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"
@@ -168,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:
@@ -230,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"
@@ -251,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"
@@ -357,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"
@@ -379,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"
@@ -388,8 +498,8 @@ fastparse@^1.1.1:
resolved "https://registry.yarnpkg.com/fastparse/-/fastparse-1.1.1.tgz#d1e2643b38a94d7583b479060e6c4affc94071f8"
fbjs@^0.8.12:
version "0.8.12"
resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.12.tgz#10b5d92f76d45575fd63a217d4ea02bea2f8ed04"
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"
@@ -399,9 +509,9 @@ fbjs@^0.8.12:
setimmediate "^1.0.5"
ua-parser-js "^0.7.9"
fbjs@^0.8.4, fbjs@^0.8.5, fbjs@^0.8.8, fbjs@^0.8.9:
version "0.8.9"
resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.9.tgz#180247fbd347dcc9004517b904f865400a0c8f14"
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:
core-js "^1.0.0"
isomorphic-fetch "^2.1.1"
@@ -423,14 +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@2.20.25:
version "2.20.25"
resolved "https://registry.yarnpkg.com/glamor/-/glamor-2.20.25.tgz#71b84b82b67a9327771ac59de53ee915d148a4a3"
glamor@^2.20.40:
version "2.20.40"
resolved "https://registry.yarnpkg.com/glamor/-/glamor-2.20.40.tgz#f606660357b7cf18dface731ad1a2cfa93817f05"
dependencies:
babel-runtime "^6.18.0"
fbjs "^0.8.8"
object-assign "^4.1.0"
prop-types "^15.5.8"
fbjs "^0.8.12"
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"
@@ -501,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.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:
@@ -529,7 +633,7 @@ is-function@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/is-function/-/is-function-1.0.1.tgz#12cfb98b65b57dd3d193a3121f5f6e2f437602b5"
is-in-browser@1.0.2, is-in-browser@^1.0.2:
is-in-browser@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/is-in-browser/-/is-in-browser-1.0.2.tgz#f688bea8f1e5aadc3244ebc870d188cfb9b613cf"
@@ -605,70 +709,70 @@ jsonify@~0.0.0:
version "0.0.0"
resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73"
jss-camel-case@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/jss-camel-case/-/jss-camel-case-4.0.0.tgz#39ef2a137aaa1e2f160ab826845305f8efabcfd5"
jss-camel-case@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/jss-camel-case/-/jss-camel-case-5.0.0.tgz#886c1fe56a8a11577454d6a8b4133caa6c1f53a0"
jss-compose@^3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/jss-compose/-/jss-compose-3.0.1.tgz#0ac07f20baf1d523c211016d383dab08dcfe4186"
jss-compose@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/jss-compose/-/jss-compose-4.0.0.tgz#f0109e8e8301a2678279301c24523dbc76115b9b"
dependencies:
warning "^3.0.0"
jss-default-unit@^6.0.0:
version "6.1.0"
resolved "https://registry.yarnpkg.com/jss-default-unit/-/jss-default-unit-6.1.0.tgz#ea6ca838de119c17adbce597b21ba9c20f7f4d84"
jss-default-unit@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/jss-default-unit/-/jss-default-unit-7.0.0.tgz#176c1db91da870e3ad16301f6f4b4cfc6fe1e90a"
jss-expand@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/jss-expand/-/jss-expand-3.0.0.tgz#ce22bf8f9d99afa822738d82dcc3bdbf32766b1d"
jss-extend@^4.0.0:
jss-expand@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/jss-extend/-/jss-extend-4.0.0.tgz#1c377d4efd67f34c997b699aa8bc1dab1c7edf95"
resolved "https://registry.yarnpkg.com/jss-expand/-/jss-expand-4.0.0.tgz#71ec15386d7839bb23892acf9dcaa40b7fe9c785"
jss-extend@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/jss-extend/-/jss-extend-5.0.0.tgz#08a1d4015d05dfe011e3a281457d471226865387"
dependencies:
warning "^3.0.0"
jss-global@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/jss-global/-/jss-global-1.0.0.tgz#ba87850cd56d32e0623c3878fd5ef376a61e6f65"
jss-nested@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/jss-nested/-/jss-nested-4.0.0.tgz#70d8aaaeb0ae1c0ca6ac74b329255b71e58bf72e"
dependencies:
warning "^3.0.0"
jss-preset-default@^2.0.0:
jss-global@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/jss-preset-default/-/jss-preset-default-2.0.0.tgz#0368d99626b31067e8d04ab3c7cb17ba8354d422"
resolved "https://registry.yarnpkg.com/jss-global/-/jss-global-2.0.0.tgz#a162f822f17e5d760151d908bdb41d7f2824c28f"
jss-nested@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/jss-nested/-/jss-nested-5.0.0.tgz#c0752f31f2d465110d7de6ac83583dbed669faa0"
dependencies:
jss-camel-case "^4.0.0"
jss-compose "^3.0.0"
jss-default-unit "^6.0.0"
jss-expand "^3.0.0"
jss-extend "^4.0.0"
jss-global "^1.0.0"
jss-nested "^4.0.0"
jss-props-sort "^4.0.0"
jss-vendor-prefixer "^5.0.0"
warning "^3.0.0"
jss-props-sort@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/jss-props-sort/-/jss-props-sort-4.0.0.tgz#ef4239c6795ca304c18dce9e0395a1789ed9f78a"
jss-preset-default@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/jss-preset-default/-/jss-preset-default-3.0.0.tgz#e43ee1ac526f689baf2bfd28ae95a6fdc3a02663"
dependencies:
jss-camel-case "^5.0.0"
jss-compose "^4.0.0"
jss-default-unit "^7.0.0"
jss-expand "^4.0.0"
jss-extend "^5.0.0"
jss-global "^2.0.0"
jss-nested "^5.0.0"
jss-props-sort "^5.0.0"
jss-vendor-prefixer "^6.0.0"
jss-vendor-prefixer@^5.0.0:
version "5.1.0"
resolved "https://registry.yarnpkg.com/jss-vendor-prefixer/-/jss-vendor-prefixer-5.1.0.tgz#59b73544de81e6b2efd71f6d3b744671826865a2"
jss-props-sort@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/jss-props-sort/-/jss-props-sort-5.0.0.tgz#8839c88433f64e8c1dab1a7068796f19b84f9195"
jss-vendor-prefixer@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/jss-vendor-prefixer/-/jss-vendor-prefixer-6.0.0.tgz#be58124f0cbed76e98cc8eb5219dbb260f057d0b"
dependencies:
css-vendor "^0.3.8"
jss@^7.0.0:
version "7.0.3"
resolved "https://registry.yarnpkg.com/jss/-/jss-7.0.3.tgz#87a4ff5c9398f7ee7ddc06a6b02255a4c74d9e1b"
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"
is-in-browser "^1.0.2"
warning "^3.0.0"
loader-utils@^1.0.2:
version "1.0.2"
@@ -690,11 +794,11 @@ lodash.uniq@^4.3.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
lodash@^4.17.1:
lodash@^4.17.1, lodash@^4.17.4:
version "4.17.4"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae"
loose-envify@^1.0.0, loose-envify@^1.3.1:
loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.3.1:
version "1.3.1"
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848"
dependencies:
@@ -729,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"
@@ -815,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"
@@ -903,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"
@@ -946,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:
@@ -1000,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"
@@ -1010,19 +1142,13 @@ promise@^7.1.1:
dependencies:
asap "~2.0.3"
prop-types@^15.5.10:
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:
fbjs "^0.8.9"
loose-envify "^1.3.1"
prop-types@^15.5.4, prop-types@^15.5.8:
version "15.5.8"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.5.8.tgz#6b7b2e141083be38c8595aa51fc55775c7199394"
dependencies:
fbjs "^0.8.9"
q@^1.1.2:
version "1.4.1"
resolved "https://registry.yarnpkg.com/q/-/q-1.4.1.tgz#55705bcd93c5f3673530c2c2cbc0c2b3addc286e"
@@ -1034,25 +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"
react-jss@^6.1.1:
version "6.1.1"
resolved "https://registry.yarnpkg.com/react-jss/-/react-jss-6.1.1.tgz#01a548e6531b691186c3e8d8250980fb2938f1fe"
dependencies:
hoist-non-react-statics "^1.2.0"
jss "^7.0.0"
jss-preset-default "^2.0.0"
array-find "^1.0.0"
exenv "^1.2.1"
inline-style-prefixer "^2.0.5"
prop-types "^15.5.8"
react-emotion@^7.2.2:
version "7.2.2"
resolved "https://registry.yarnpkg.com/react-emotion/-/react-emotion-7.2.2.tgz#0401607a0ba011bc16600a2691f5f57cb38ce89d"
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:
hoist-non-react-statics "^1.2.0"
jss "^8.1.0"
jss-preset-default "^3.0.0"
prop-types "^15.5.8"
theming "^1.1.0"
react-native-web@0.0.x:
version "0.0.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"
@@ -1067,9 +1204,9 @@ react-native-web@0.0.x:
prop-types "^15.5.10"
react-timer-mixin "^0.13.3"
react-primitives@^0.4.2:
version "0.4.2"
resolved "https://registry.yarnpkg.com/react-primitives/-/react-primitives-0.4.2.tgz#cb001c1122734f177559f5bf590aadd5129b0914"
react-primitives@^0.4.3:
version "0.4.3"
resolved "https://registry.yarnpkg.com/react-primitives/-/react-primitives-0.4.3.tgz#4970afda5a32dccf5ea180380e3a0e16192e4b83"
dependencies:
animated "^0.1.5"
asap "^2.0.5"
@@ -1087,14 +1224,27 @@ react-timer-mixin@^0.13.3:
version "0.13.3"
resolved "https://registry.yarnpkg.com/react-timer-mixin/-/react-timer-mixin-0.13.3.tgz#0da8b9f807ec07dc3e854d082c737c65605b3d22"
reactxp@^0.34.3:
version "0.34.3"
resolved "https://registry.yarnpkg.com/reactxp/-/reactxp-0.34.3.tgz#6481992e57758ae6ffffbfde3d497527bb495032"
react@^15.5.4:
version "15.6.1"
resolved "https://registry.yarnpkg.com/react/-/react-15.6.1.tgz#baa8434ec6780bde997cdc380b79cd33b96393df"
dependencies:
create-react-class "^15.6.0"
fbjs "^0.8.9"
loose-envify "^1.1.0"
object-assign "^4.1.0"
prop-types "^15.5.10"
reactxp@^0.42.1:
version "0.42.1"
resolved "https://registry.yarnpkg.com/reactxp/-/reactxp-0.42.1.tgz#1c142a87f0a82a8da94e5c875525952c35a53a17"
dependencies:
"@types/lodash" "^4.14.66"
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:
@@ -1120,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"
@@ -1161,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"
@@ -1179,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"
@@ -1194,9 +1348,9 @@ style-loader@^0.18.2:
loader-utils "^1.0.2"
schema-utils "^0.3.0"
styled-components@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-2.1.0.tgz#425805fca7efa5880aad2171f986bfd8a2f0808f"
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"
@@ -1205,7 +1359,7 @@ styled-components@^2.1.0:
is-function "^1.0.1"
is-plain-object "^2.0.1"
prop-types "^15.5.4"
stylis "^3.0.19"
stylis "^3.2.1"
supports-color "^3.2.3"
styletron-client@^2.5.7:
@@ -1224,9 +1378,16 @@ styletron-utils@^2.5.4:
dependencies:
inline-style-prefixer "^2.0.1"
stylis@^3.0.19:
version "3.1.9"
resolved "https://registry.yarnpkg.com/stylis/-/stylis-3.1.9.tgz#638370451f980437f57c59e58d2e296be29fafb7"
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"
@@ -1244,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"
@@ -1260,6 +1427,26 @@ synctasks@^0.2.9:
version "0.2.17"
resolved "https://registry.yarnpkg.com/synctasks/-/synctasks-0.2.17.tgz#38852f008878de2e941b6e458ddf552245268da1"
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"
is-plain-object "^2.0.1"
prop-types "^15.5.8"
react "^15.5.4"
through@^2.3.8:
version "2.3.8"
resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
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"
@@ -1288,7 +1475,7 @@ vendors@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/vendors/-/vendors-1.0.1.tgz#37ad73c8ee417fb3d580e785312307d274847f22"
warning@3.0.0, warning@^3.0.0:
warning@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/warning/-/warning-3.0.0.tgz#32e5377cb572de4ab04753bdf8821c01ed605b7c"
dependencies:

View File

@@ -1 +0,0 @@
module.exports = require('./dist/core');

View File

@@ -40,35 +40,40 @@ using `aria-label`.
In some cases, we also want to alert the end user of the type of selected
component (i.e., that it is a “button”). To provide more context to screen
readers, you should specify the `accessibilityRole` property. (Note that React
Native for Web provides a compatibility mapping of equivalent
Native for Web also provides a compatibility mapping of equivalent
`accessibilityTraits` and `accessibilityComponentType` values to
`accessibilityRole`).
The `accessibilityRole` prop is used to infer an [analogous HTML
element][html-aria-url] to use in addition to the resulting ARIA `role`, where
possible. While this may contradict some ARIA recommendations, it also helps
avoid certain HTML5 conformance errors and accessibility anti-patterns (e.g.,
giving a `heading` role to a `button` element).
element][html-aria-url] and ARIA `role`, where possible. In most cases, both
the element and ARIA `role` are rendered. While this may contradict some ARIA
recommendations, it also helps avoid certain HTML5 conformance errors and
accessibility anti-patterns (e.g., giving a `heading` role to a `button`
element) and browser bugs.
For example:
* `<View accessibilityRole='article' />` => `<article role='article' />`.
* `<View accessibilityRole='banner' />` => `<header role='banner' />`.
* `<View accessibilityRole='button' />` => `<button type='button' role='button' />`.
* `<View accessibilityRole='button' />` => `<div role='button' tabIndex='0' />`.
* `<Text accessibilityRole='label' />` => `<label />`.
* `<Text accessibilityRole='link' href='/' />` => `<a role='link' href='/' />`.
* `<View accessibilityRole='main' />` => `<main role='main' />`.
In the example below, the `TouchableWithoutFeedback` is announced by screen
readers as a native Button.
In the example below, the `TouchableHighlight` is announced by screen
readers as a button.
```
<TouchableWithoutFeedback accessibilityRole="button" onPress={this._onPress}>
```js
<TouchableHighlight accessibilityRole="button" onPress={this._handlePress}>
<View style={styles.button}>
<Text style={styles.buttonText}>Press me!</Text>
</View>
</TouchableWithoutFeedback>
</TouchableHighlight>
```
Note: The `button` role is not implemented using the native `button` element
due to browsers limiting the use of flexbox layout on its children.
Note: Avoid changing `accessibilityRole` values over time or after user
actions. Generally, accessibility APIs do not provide a means of notifying
assistive technologies of a `role` value change.

View File

@@ -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} />
);
}

View File

@@ -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
View 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"
}
}

View File

@@ -1 +1 @@
import '@kadira/storybook-addon-options/register';
import '@storybook/addon-options/register';

View File

@@ -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);

View File

@@ -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>;
}

View File

@@ -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;
};

View File

@@ -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);

View File

@@ -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: {

View File

@@ -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: {

View File

@@ -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: {

View File

@@ -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: {

View File

@@ -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);

View File

@@ -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;

View File

@@ -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: {

View File

@@ -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);

View File

@@ -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]}>

View File

@@ -6,12 +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>;
<Text style={styles.text}>React</Text>
</Image>
);
const styles = StyleSheet.create({
image: {

View File

@@ -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;

View File

@@ -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: {

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -6,16 +6,14 @@ 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 (
<View key={i}>
<View style={styles.horizontal}>
<View>
<Text style={[styles.resizeModeText]}>
Contain
</Text>
<Text style={[styles.resizeModeText]}>Contain</Text>
<Image
resizeMode={Image.resizeMode.contain}
source={source}
@@ -23,9 +21,7 @@ const ImageResizeModeExample = () =>
/>
</View>
<View>
<Text style={[styles.resizeModeText]}>
Cover
</Text>
<Text style={[styles.resizeModeText]}>Cover</Text>
<Image
resizeMode={Image.resizeMode.cover}
source={source}
@@ -33,9 +29,7 @@ const ImageResizeModeExample = () =>
/>
</View>
<View>
<Text style={[styles.resizeModeText]}>
Stretch
</Text>
<Text style={[styles.resizeModeText]}>Stretch</Text>
<Image
resizeMode={Image.resizeMode.stretch}
source={source}
@@ -43,22 +37,19 @@ const ImageResizeModeExample = () =>
/>
</View>
<View>
<Text style={[styles.resizeModeText]}>
Repeat
</Text>
<Text style={[styles.resizeModeText]}>Repeat</Text>
<Image resizeMode={'repeat'} source={source} style={styles.resizeMode} />
</View>
<View>
<Text style={[styles.resizeModeText]}>
Center
</Text>
<Text style={[styles.resizeModeText]}>Center</Text>
<Image resizeMode={'center'} source={source} style={styles.resizeMode} />
</View>
</View>
</View>
);
})}
</View>;
</View>
);
const styles = StyleSheet.create({
horizontal: {

View File

@@ -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: {

View File

@@ -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>
);
}

View File

@@ -23,23 +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>
);
}

View File

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View File

Before

Width:  |  Height:  |  Size: 850 B

After

Width:  |  Height:  |  Size: 850 B

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -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);

View File

@@ -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: {

View File

@@ -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;

View File

@@ -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;

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