Compare commits

...

236 Commits

Author SHA1 Message Date
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
Nicolas Gallagher
9376c72a40 0.0.108 2017-06-29 11:37:39 -07:00
Nicolas Gallagher
d4b1fde9cf Rewrite interactive documentation
Ref #491
2017-06-29 11:33:25 -07:00
Nicolas Gallagher
f237fc3094 Add styled-components/primitives to benchmarks 2017-06-28 16:05:09 -07:00
Nicolas Gallagher
8777e25d8e [add] Image: draggable prop
Allows control over browser's default drag-and-drop behaviour for
images. Setting draggable to 'false' will prevent dragging.

Close #514
2017-06-28 14:03:19 -07:00
Jiaming
18d60047d2 [add] ScrollView: support scrollToEnd method
Close #541
2017-06-28 13:49:08 -07:00
Paul Armstrong
535a7b7027 [fix] TextInput: fix onSubmitEditing when multiline=true
Do not trigger onSubmitEditing when Shift+Enter is pressed in a multiline TextInput.

Fix #524
Close #526
2017-06-27 16:24:52 -07:00
Nicolas Gallagher
bdaeac964c 0.0.107 2017-06-26 10:50:59 -07:00
Nicolas Gallagher
20257afe88 [fix] TextInput onSubmitEditing event 2017-06-26 10:38:53 -07:00
Nicolas Gallagher
99348eaedb [fix] StyleSheet: server-side rendering of styles
Problem:

The content of style sheets was being set as a child of 'style', which
causes React to escape the content. This meant that the pointer-events
selectors were broken (">" became "&gt;") and pointer-events were
disabled for the entire server-rendered document.

Solution:

Use 'dangerouslySetInnerHTML' to avoid the CSS text being escaped.

Fix #546
2017-06-24 10:23:14 -07:00
Peter Ruibal
6cb16d059d Fix @providesModule for a few APIs
Close #542
2017-06-24 07:42:24 -07:00
Nicolas Gallagher
3c660e2ad7 [fix] SSR of Image renders source
When rendered on the server, images now include the 'src' and will be
downloaded by the browser rather than waiting for the client-side JS to
initiate image loading.

Fix #543
2017-06-24 07:37:29 -07:00
Nicolas Gallagher
e9101abefe [change] TextInput 'onKeyPress' includes modifier keys
Include modifier keys in the 'nativeEvent'. This allows keyboard
shortcuts such as "Shift+Enter" to be implemented for submiting text
input content when the modality is keyboard + mouse rather than touch.
2017-06-23 14:48:34 -07:00
Nicolas Gallagher
dfa8087f9a 0.0.106 2017-06-22 18:06:39 -07:00
Nicolas Gallagher
eaccd8799d Fix yarn.lock 2017-06-22 18:06:25 -07:00
Kenneth Lynne
85b2afc313 [fix] TextInput 'onKeyPress' return values
Match the current React Native API for 'onKeyPress'.

Fix #518
Close #537
2017-06-22 18:00:54 -07:00
Nicolas Gallagher
4865c7bcce [change] Clipboard.isSupported -> Clipboard.isAvailable
Rename this method to be consistent with AppState.isAvailable
2017-06-20 16:10:29 -07:00
Nicolas Gallagher
9e9ab78130 0.0.105 2017-06-20 14:09:16 -07:00
Nicolas Gallagher
00b795a87e [change] Nested Text renders as span 2017-06-20 14:05:30 -07:00
Nicolas Gallagher
1edf5241a1 Update webpack and babel-loader 2017-06-20 10:39:09 -07:00
Nicolas Gallagher
4cfcdef264 [fix] AppRegistry container layout
Absolute fill positioning provides better default layout for full-screen
apps.

Fix #528
2017-06-20 10:17:55 -07:00
Nicolas Gallagher
a264c0b956 0.0.104 2017-06-19 07:31:00 -07:00
Nicolas Gallagher
0d8aa24ff3 [fix] 'flex' shorthand sets 'flexBasis' to '0%'
The previous attempt at a fix (88ddeca0c6)
didn't account for 'View' handling the 'flexBasis' reset (as it used to
with 'flexShrink'). This patch moves flex style resolution into the DOM
style resolver.

Fix #426
2017-06-19 07:28:25 -07:00
Nicolas Gallagher
1b77ac4b2f Remove unused file 2017-06-18 16:00:31 -07:00
Nicolas Gallagher
44b185ed4c Add 'unimplemented view' stubs 2017-06-18 15:27:24 -07:00
Nicolas Gallagher
d1d570268a Add note about React Dev Tools to Style guide 2017-06-18 14:36:39 -07:00
Nicolas Gallagher
997c92f841 Update eslint and flow packages 2017-06-18 14:36:39 -07:00
Nicolas Gallagher
8e60690877 Update build tools 2017-06-18 14:36:39 -07:00
Nicolas Gallagher
7bab19ae6c Update inline-style-prefixer 2017-06-18 14:36:33 -07:00
Nicolas Gallagher
c7f287b207 Update React packages 2017-06-18 13:10:58 -07:00
Nicolas Gallagher
02cfbf8987 Add @providesModule annotations and update copyright notices
'providesModule' is necessary for haste support
2017-06-18 12:59:40 -07:00
Nicolas Gallagher
6203a3fec6 Misc flow and lint fixes 2017-06-18 12:59:19 -07:00
Nicolas Gallagher
d1d5461b29 Move 'hash' to 'vendor' directory 2017-06-18 12:24:04 -07:00
Nicolas Gallagher
b0ff4489a9 [fix] Switch compatibility with React Native
Add compatibility support for React Native's 'Switch' props
2017-06-18 12:14:46 -07:00
Nicolas Gallagher
635fda8d63 [fix] ProgressBar indicator overflow
This allows ProgressBar to correctly render provided styles like
'border-radius' without the indicator bar overflowing.
2017-06-17 08:48:37 -07:00
Nicolas Gallagher
5a5eb5425f Allow component styles to be editable in React Dev Tools 2017-06-15 19:30:18 -07:00
Nicolas Gallagher
44d59f4996 Use yarn to run scripts 2017-06-15 19:29:56 -07:00
Nicolas Gallagher
868ab55bac 0.0.103 2017-06-15 08:46:09 -07:00
Paul Armstrong
65d5a89040 [fix] Remove requestAnimationFrame from StyleManager
Using requestAnimationFrame while registering styles/classes slows down
iOS/Mobile Webkit. By removing it, it's possible that we add a little
bit of overhead, slowing down current cycles, but should be mostly
unnoticed.

Fix #517
2017-06-15 08:44:13 -07:00
Nicolas Gallagher
deb0a85440 [change] AppRegistry.getApplication returns React elements
This changes the return value of 'getApplication' so that the
application element and stylesheets are all available as React elements.
Also changes StyleSheet's 'renderToString' to 'getStyleSheets'.

Fix #504
2017-06-14 10:41:20 -07:00
Nicolas Gallagher
19381da37f 0.0.102 2017-06-13 15:43:40 -07:00
Nicolas Gallagher
47ba46780c [add] 'View' support for 'backgroundBlendMode' CSS
Fix #476
2017-06-13 14:22:52 -07:00
Nicolas Gallagher
88ddeca0c6 [fix] 'flex' shorthand sets 'flexBasis' to '0%'
Ref #426
2017-06-13 14:22:44 -07:00
Nicolas Gallagher
a61f71133e 0.0.101 2017-06-12 16:36:55 -07:00
Nicolas Gallagher
dad2888f7e [add] Text support for inline View and Image
When 'View' or 'Image' are within a 'Text', lay them out as
'inline-flex'.

Fix #472
2017-06-12 16:32:33 -07:00
Nicolas Gallagher
5e9e81eafe 0.0.100 2017-06-11 16:18:45 -07:00
Nicolas Gallagher
7ae2a5e188 Update README 2017-06-11 16:18:23 -07:00
Nicolas Gallagher
d13f78622b [fix] pointerEvents CSS
Fix #513
2017-06-11 14:42:01 -07:00
Nicolas Gallagher
6ae68e948f [fix] ScrollView passive event listener warning
'touchstart' and 'touchmove' listeners added to the document will
default to 'passive:true' (so that calls to 'preventDefault' will be
ignored). Source https://www.chromestatus.com/features/5093566007214080

To support 'scrollEnabled', listeners are bound to the underlying
ScrollView DOM node to avoid being passive.

Fix #477
2017-06-11 14:39:42 -07:00
Nicolas Gallagher
b1b70a420d [fix] Image support for inline SVG data
SVG data may contain characters that need escaping when applied as a CSS
background image.

Fix #512
2017-06-10 14:44:50 -07:00
Nicolas Gallagher
43d297bf59 [change] use ES2015 modules
Ref #102
2017-06-10 13:51:53 -07:00
Nicolas Gallagher
060d96b42d Fix docs deploy 2017-06-09 16:52:14 -07:00
Nicolas Gallagher
dd5f8cf641 0.0.99 2017-06-09 14:58:30 -07:00
Nicolas Gallagher
7f256c6423 Update documentation examples 2017-06-09 14:55:08 -07:00
Nicolas Gallagher
05069253a1 Add Calculator example app 2017-06-09 14:51:32 -07:00
Nicolas Gallagher
f10ac058b6 Add UIExplorer component for docs 2017-06-09 14:51:12 -07:00
Nicolas Gallagher
6aa2ac1f70 Remove ListView docs 2017-06-09 14:50:03 -07:00
Nicolas Gallagher
79e6dbaab5 Move 'NativeMethods' docs to direct manipulation guide 2017-06-09 14:49:15 -07:00
Nicolas Gallagher
fc86c876e0 Update formatter and linter 2017-06-09 12:59:39 -07:00
Nicolas Gallagher
1f25ef82ae Update jest 2017-06-09 11:56:14 -07:00
Nicolas Gallagher
5b60dcf0ff Update React packages and inline-style-prefixer 2017-06-09 11:53:43 -07:00
Nicolas Gallagher
1cf152e8a0 Update build tools 2017-06-09 11:52:38 -07:00
Nicolas Gallagher
d034a0c6ec [change] Linking.getInitialURL returns initial URL
Close #486
2017-06-09 10:44:32 -07:00
Fabrizio Moscon
33d1cdf193 Fix webpack documentation link 2017-06-09 10:28:30 -07:00
Maxime Thirouin
483a76cb5c Fix incorrect links in View documentation 2017-06-09 15:21:10 +02:00
Nicolas Gallagher
65055028c6 0.0.98 2017-06-07 16:03:26 -07:00
Nicolas Gallagher
93f425e414 [fix] event normalization
Fix #508
2017-06-07 16:02:45 -07:00
Nicolas Gallagher
ce4cc8a946 Remove avoidable vendor code
Updates the 'StyleSheetValidation' and 'ColorPropType' implementations
with the latest from React Native.
2017-06-05 20:06:22 -07:00
Nicolas Gallagher
77fd867421 [fix] correct types
Fix #465
2017-06-05 19:51:34 -07:00
Nicolas Gallagher
22999d7e5b Run lint and test before releasing new versions 2017-06-02 15:29:11 -07:00
Nicolas Gallagher
3c400a662b 0.0.97 2017-06-02 15:27:48 -07:00
Nick
e78ce713cb [fix] TextInput selection for Blink on Android
Close #492
2017-06-01 09:30:22 -07:00
Nicolas Gallagher
70282cb4ca Format 2017-06-01 09:20:07 -07:00
Nicolas Gallagher
7abdb33a1d 0.0.96 2017-06-01 08:51:53 -07:00
Tasveer Singh
a9c7b38df9 [fix] low-level performance tuning
createDOMProps: avoid using default parameters as Babel compiles the
function to calls using 'arguments', which Chrome flags as a deopt.
Replace 'typeof' calls with slightly faster calls to constructor.

onLayout: batch layout measurements in a single requestAnimationFrame.

Close #490
2017-06-01 08:45:40 -07:00
Karan Thakkar
d57fb6407a Fix link to getting started in AppRegistry doc
Fixes #498
2017-06-01 10:50:38 +05:30
Nicolas Gallagher
bcdeda5dab [fix] Flow type checking and annotations
Fixes dozens of Flow errors; adds type annotations; marks more files for
Flow type checking. Fixes a bug in 'AppState'.

15 Flow errors remaining. Several React Native files are still not type
checked (e.g., PanResponder, Touchables)

Ref #465
2017-05-27 10:44:33 -07:00
Nicolas Gallagher
edef737249 Move CONTRIBUTING.md 2017-05-27 08:29:22 -07:00
Nicolas Gallagher
9163b974db Reduce number of dotfiles 2017-05-25 23:10:37 -07:00
Nicolas Gallagher
a388ef3e26 Rename 'examples' to 'docs/storybook'
Also changes several npm script names
2017-05-25 22:22:20 -07:00
Nicolas Gallagher
a84ecefa5d Rename 'performance' to 'benchmarks' 2017-05-25 21:44:01 -07:00
Nicolas Gallagher
54af7e9da2 0.0.95 2017-05-25 13:11:36 -07:00
Peggy Rayzis
be3c78f317 Set up flow config; add third party libdefs 2017-05-25 11:23:58 -07:00
Nicolas Gallagher
6b85f5a22a Use lint-staged to help format & lint before commit 2017-05-25 11:10:21 -07:00
Nicolas Gallagher
875a2c98b3 Use lint-staged to help format & lint before commit 2017-05-25 11:09:17 -07:00
Nicolas Gallagher
6525d9d84a Fix lint errors in 'examples' directory 2017-05-25 11:01:51 -07:00
Nicolas Gallagher
61356a786b Format 'examples' directory 2017-05-24 15:23:13 -07:00
Nicolas Gallagher
864250f34d Format root .js files 2017-05-24 15:21:25 -07:00
Louis Lagrange
7ee570f0ed Add compatibility for BackHandler
Fixes #480
2017-05-22 11:23:59 -07:00
vaukalak
118b64a932 Add docs on platform-specific components 2017-05-22 11:22:02 -07:00
Nicolas Gallagher
3cc1e480a7 Update benchmark dependencies 2017-05-08 14:46:40 +01:00
Nicolas Gallagher
124de7562d Add 'advanced use' and 'style' docs
Fix #450
2017-05-06 16:06:20 +01:00
Nicolas Gallagher
7aef8f04c1 Use class components in benchmarks 2017-05-06 16:06:16 +01:00
Nicolas Gallagher
08a353fbef Update webpack 2017-05-05 10:59:07 -07:00
Nicolas Gallagher
51557d306b Update prettier 2017-05-05 10:58:12 -07:00
Nicolas Gallagher
6b910166b2 Update inline-style-prefixer and fbjs 2017-05-05 10:56:44 -07:00
Nicolas Gallagher
668d389035 Update React devDependencies 2017-05-05 10:51:17 -07:00
周中原
79a6a5a486 Fix presentation of props in 'Button' docs 2017-05-05 10:30:10 -07:00
Nicolas Gallagher
1c37a42566 0.0.94 2017-05-01 12:27:55 -07:00
Nicolas Gallagher
c38369ac0f [fix] RTL style registration and resolution
* Lazy-register RTL variants to generate class names
* Don't RTL-flip translateX
2017-05-01 12:27:38 -07:00
Nicolas Gallagher
03769f7d45 0.0.93 2017-04-29 19:53:45 -07:00
Nicolas Gallagher
eb43a8f3e7 [fix] setNativeProps with RTL layout
Ensure that 'setNativeProps' doesn't try to i18n flip styles that have
already been flipped. This is hacked into the current design.
Registering both RTL and LTR styles is not implemented yet either.
2017-04-29 19:49:59 -07:00
Nicolas Gallagher
cdf13b880d Reorganize 'createReactDOMStyle'
1. Rename 'expandStyle' to 'createReactDOMStyle'
2. Move use of 'i18nStyle' out of 'createReactDOMStyle' to decouple the
   two transformations.
3. Move the style property resolvers into 'createReactDOMStyle'
2017-04-29 19:03:48 -07:00
Nicolas Gallagher
47fad1ef58 [fix] setNativeProps 2017-04-29 18:58:15 -07:00
Nicolas Gallagher
5f69c8e8b8 0.0.92 2017-04-29 12:19:16 -07:00
Nicolas Gallagher
21550db5f2 [fix] stop propagation of ScrollView 'onScroll' event
Fix #440
2017-04-29 12:15:19 -07:00
Nicolas Gallagher
1cae5d55a1 [fix] setNativeProps DOM style copying
The 'style' object of an HTML node is a 'CSSStyleDeclaration'. Use the
'CSSStyleDeclaration' API to copy the inline styles, rather than
treating it like a plain object. This avoids errors that were resulting
from indices and property names being used a key-value pairs in the
resulting style copy.

Fix #460
Ref #454
2017-04-29 11:09:43 -07:00
Nicolas Gallagher
11d23f850a 0.0.91 2017-04-28 15:40:12 -07:00
Nicolas Gallagher
d994a25017 0.0.90 2017-04-28 15:17:44 -07:00
Nicolas Gallagher
756df70154 [fix] check 'transform' style is array before mapping 2017-04-28 15:15:57 -07:00
Nicolas Gallagher
f0b06419f9 Move prefixStyles module 2017-04-27 16:27:45 -07:00
Nicolas Gallagher
60ff75705e [fix] remove stray 'length' property from style object
Fix #454
2017-04-27 15:10:03 -07:00
Nicolas Gallagher
5e8ad67296 0.0.89 2017-04-26 15:12:19 -07:00
Nathan Broadbent
ba24a882be Link to another starter kit example 2017-04-26 15:11:16 -07:00
Nicolas Gallagher
c7686209cd Update prettier 2017-04-26 15:07:44 -07:00
Nicolas Gallagher
f1b281ae32 Update debounce dependency 2017-04-26 15:06:41 -07:00
Nicolas Gallagher
b676fbd5e0 [fix] propTypes removal in production builds
Updates the relevant babel plugin, which now replaces component
propTypes with an empty object, avoiding the majority of potential
runtime errors related to this transform.

Fix #423
2017-04-26 11:05:33 -07:00
Nicolas Gallagher
51aef6c791 0.0.88 2017-04-24 13:28:38 -07:00
Nathan Leung
ae9a9cde5f Fix example webpack config in documentation 2017-04-24 13:21:46 -07:00
Nicolas Gallagher
beb907b180 Rename some variables in StyleRegistry 2017-04-24 13:21:27 -07:00
Nicolas Gallagher
a3362e1f38 [fix] setNativeProps inline styles
Inline styles are preserved when using 'setNativeProps'. Adds unit tests
for the resolution logic required by 'setNativeProps'/'resolveStateful'
in a DOM context.

Fix #439
2017-04-23 21:24:27 -07:00
Nicolas Gallagher
64d2d34367 0.0.87 2017-04-23 13:39:27 -07:00
Nicolas Gallagher
d83cd45b6f [fix] Clipboard browser support
Safari 10.3 supports copying (but apparently not from inputs)
2017-04-23 13:38:51 -07:00
Nicolas Gallagher
227971d22c [add] support for CSS grid properties (experimental)
Allow people to experiment with using CSS grid in react-native. (No
support for shorthand properties.)
2017-04-22 10:34:43 -07:00
Nicolas Gallagher
4822cf4620 [add] support for 'clip' and 'textIndent' styles 2017-04-22 10:06:27 -07:00
Nathan Broadbent
91e4528eac Allow filter property in CSS 2017-04-22 22:56:07 +07:00
Nicolas Gallagher
1ee64d8285 0.0.86 2017-04-21 19:04:23 -07:00
Nicolas Gallagher
66a4c13bf3 [fix] AppState.isSupported -> AppState.isAvailable
React Native exposes AppState support via 'isAvailable'.
2017-04-21 18:47:29 -07:00
Nicolas Gallagher
9012e98ba7 [fix] support 'mailto:' URLs in 'Linking' 2017-04-21 18:29:29 -07:00
Nicolas Gallagher
046e01dfa9 [fix] add AsyncStorage callbacks and tests
Add support for the callback interface and add test coverage.

Fix #399
Close #400
2017-04-21 18:13:14 -07:00
Nicolas Gallagher
6e71e1e058 [fix] attempt to avoid need for 'Array.from' polyfill
Fix #409
2017-04-20 18:04:09 -07:00
Nicolas Gallagher
d5a9f3e779 Add ES module export
Preparation for publishing an ES module build.
Move 'modality' into 'createDOMElement' to ensure it is always initialized.
2017-04-20 17:16:05 -07:00
Nicolas Gallagher
f16f5f21ce [add] WebkitMaskImage style prop
Undocumented supported. Commonly used in border-radius hacks.

Close #326
2017-04-20 15:12:07 -07:00
Nicolas Gallagher
0bb7e67e63 0.0.85 2017-04-20 15:07:56 -07:00
Nicolas Gallagher
c6b54930b6 [add] StatusBar stub component
Fix #425
2017-04-20 15:07:34 -07:00
Nicolas Gallagher
599f1fcaf5 Filter unsupported TextInput props
Fix #385
2017-04-20 14:58:48 -07:00
Nicolas Gallagher
3f7a4e455f [add] support 'outlineColor' style prop
Fix #435
2017-04-20 14:50:14 -07:00
Nicolas Gallagher
1f3e9cc6ee [change] ScrollView as new surface
Fix #405
2017-04-20 13:36:00 -07:00
Nicolas Gallagher
17ed63129f Add a note about accessibilityRole compat 2017-04-20 10:39:34 -07:00
Nicolas Gallagher
769334d04e Update benchmark results 2017-04-20 10:04:33 -07:00
439 changed files with 22489 additions and 10268 deletions

View File

@@ -1,8 +0,0 @@
{
"presets": [
"react-native"
],
"plugins": [
[ "transform-react-remove-prop-types", { "mode": "wrap" } ]
]
}

View File

@@ -1,9 +0,0 @@
# EditorConfig: http://editorconfig.org
root = true
[*]
end_of_line = lf
insert_final_newline = true
indent_style = space
indent_size = 2

View File

@@ -24,7 +24,16 @@
"globals": {
"document": false,
"navigator": false,
"window": false
"window": false,
// Flow global types
"HTMLInputElement": false,
"ReactClass": false,
"ReactComponent": false,
"ReactElement": false,
"ReactPropsChainableTypeChecker": false,
"ReactPropsCheckType": false,
"ReactPropTypes": false,
"SyntheticEvent": false
},
"rules": {
"camelcase": 0,
@@ -47,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,
@@ -120,9 +128,6 @@
// react
"react/display-name": 0,
"react/jsx-handler-names": [2, {
"eventHandlerPrefix": "_handle"
}],
"react/jsx-no-bind": 2,
"react/jsx-no-duplicate-props": 2,
"react/jsx-no-undef": 2,

14
.flowconfig Normal file
View File

@@ -0,0 +1,14 @@
[ignore]
.*/__tests__/.*
.*/benchmarks/.*
.*/docs/.*
.*/node_modules/animated/*
.*/node_modules/babel-plugin-transform-react-remove-prop-types/*
[include]
[libs]
types
[options]
unsafe.enable_getters_and_setters=true

125
.github/CONTRIBUTING.md vendored Normal file
View File

@@ -0,0 +1,125 @@
# Contributing
## Reporting Issues and Asking Questions
Before opening an issue, please search the [issue
tracker](https://github.com/necolas/react-native-web/issues) to make sure your
issue hasn't already been reported.
## Getting started
Visit the [Issue tracker](https://github.com/necolas/react-native-web/issues)
to find a list of open issues that need attention.
Fork, then clone the repo:
```
git clone https://github.com/your-username/react-native-web.git
```
Install dependencies (requires [yarn](https://yarnpkg.com/en/docs/install):
```
yarn
```
## Automated tests
To run flow:
```
yarn flow
```
To run the unit tests:
```
yarn jest
```
…in watch mode:
```
yarn jest:watch
```
To run all automated tests:
```
yarn test
```
## Visual tests
To run the interactive storybook:
```
yarn docs:start
```
To generate a static build of the storybook:
```
yarn docs:build
```
To run the performance benchmarks in a browser (opening `./benchmarks/index.html`):
```
yarn benchmark
```
## Compile and build
To compile the source code to `dist`:
```
yarn compile
```
To create a UMD bundle of the library:
```
yarn build
```
### Pre-commit
To format and lint code before commit:
```
yarn precommit
```
To format and lint the entire project:
```
yarn fmt
yarn lint
```
### New Features
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.
## Pull requests
**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.
After you have submitted your pull request, we'll try to get back to you as
soon as possible. We may suggest some changes or improvements.
Thank you for contributing!

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.

1
.gitignore vendored
View File

@@ -1,3 +1,2 @@
node_modules
dist
dist-examples

View File

@@ -5,4 +5,5 @@ before_script:
- export DISPLAY=:99.0
- sh -e /etc/init.d/xvfb start
script:
- npm run lint
- npm test

View File

@@ -1,88 +0,0 @@
# Contributing
## Reporting Issues and Asking Questions
Before opening an issue, please search the [issue
tracker](https://github.com/necolas/react-native-web/issues) to make sure your
issue hasn't already been reported.
## Development
Visit the [Issue tracker](https://github.com/necolas/react-native-web/issues)
to find a list of open issues that need attention.
Fork, then clone the repo:
```
git clone https://github.com/your-username/react-native-web.git
```
Install dependencies (requires [yarn](https://yarnpkg.com/en/docs/install):
```
yarn
```
Run the examples:
```
npm run examples
```
Run the benchmarks in a browser by opening `./performance/index.html` after running:
```
npm run build:performance
```
### Building
```
npm run build
```
To create a UMD build:
```
npm run build:umd
```
### Testing and Linting
To run the tests:
```
npm run test
```
To continuously watch and run tests, run the following:
```
npm run test:watch
```
To perform only linting, run the following:
```
npm run lint
```
### New Features
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
* 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.
Please try to keep your pull request focused in scope and avoid including unrelated commits.
After you have submitted your pull request, we'll try to get back to you as soon as possible. We may suggest some changes or improvements.
Thank you for contributing!

128
README.md
View File

@@ -3,101 +3,73 @@
[![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. [Read more](#why).
Browse the UI Explorer to see React Native [examples running on
Web](https://necolas.github.io/react-native-web/storybook/). 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:
NOTE: React Native for Web supports React/ReactDOM 15.4, 15.5, or 15.6.
Install in your existing app using `yarn` or `npm`:
```
npm install --save react@15.4 react-dom@15.4 react-native-web
yarn add react@15.6 react-dom@15.6 react-native-web
```
Read the [Getting Started](docs/guides/getting-started.md) guide.
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.
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) and
[react-native-web-starter](https://github.com/grabcode/react-native-web-starter).
```json
{
"plugins": [
"react-native-web/babel"
],
"presets": [
"react-native"
]
}
```
See the [Getting Started](docs/guides/getting-started.md) guide for more details.
## Documentation
The [interactive
documentation](https://necolas.github.io/react-native-web/storybook/) shows all
the supported APIs and Components.
Guides:
* [Getting started](docs/guides/getting-started.md)
* [Style](docs/guides/style.md)
* [Accessibility](docs/guides/accessibility.md)
* [Direct manipulation](docs/guides/direct-manipulation.md)
* [Internationalization](docs/guides/internationalization.md)
* [Advanced use](docs/guides/advanced.md)
* [Known issues](docs/guides/known-issues.md)
* [Style](docs/guides/style.md)
Exported modules:
## Starter kits
* Components
* [`ActivityIndicator`](docs/components/ActivityIndicator.md)
* [`Button`](docs/components/Button.md)
* [`Image`](docs/components/Image.md)
* [`ListView`](docs/components/ListView.md)
* [`ProgressBar`](docs/components/ProgressBar.md)
* [`ScrollView`](docs/components/ScrollView.md)
* [`Switch`](docs/components/Switch.md)
* [`Text`](docs/components/Text.md)
* [`TextInput`](docs/components/TextInput.md)
* [`TouchableHighlight`](http://facebook.github.io/react-native/releases/0.22/docs/touchablehighlight.html) (mirrors React Native)
* [`TouchableOpacity`](http://facebook.github.io/react-native/releases/0.22/docs/touchableopacity.html) (mirrors React Native)
* [`TouchableWithoutFeedback`](docs/components/TouchableWithoutFeedback.md)
* [`View`](docs/components/View.md)
* APIs
* [`Animated`](http://facebook.github.io/react-native/releases/0.20/docs/animated.html) (mirrors React Native)
* [`AppRegistry`](docs/apis/AppRegistry.md)
* [`AppState`](docs/apis/AppState.md)
* [`AsyncStorage`](docs/apis/AsyncStorage.md)
* [`Clipboard`](docs/apis/Clipboard.md)
* [`Dimensions`](docs/apis/Dimensions.md)
* [`I18nManager`](docs/apis/I18nManager.md)
* [`NativeMethods`](docs/apis/NativeMethods.md)
* [`NetInfo`](docs/apis/NetInfo.md)
* [`PanResponder`](http://facebook.github.io/react-native/releases/0.20/docs/panresponder.html#content) (mirrors React Native)
* [`PixelRatio`](docs/apis/PixelRatio.md)
* [`Platform`](docs/apis/Platform.md)
* [`StyleSheet`](docs/apis/StyleSheet.md)
* [`Vibration`](docs/apis/Vibration.md)
<span id="#why"></span>
## Why?
There are many different teams at Twitter building web applications with React.
We want to share React components, libraries, and APIs between teams…much like
the OSS community tries to do. At our scale, this involves dealing with
multiple, inter-related problems including: a common way to handle style,
animation, touch, viewport adaptation, accessibility, themes, RTL layout, and
server-rendering.
This is hard to do with React DOM, as the components are essentially the same
low-level building blocks that the browser provides. However, React Native
avoids, solves, or can solve almost all these problems facing Web teams.
Central to this is React Native's JavaScript style API (not strictly
"CSS-in-JS") which avoids the key [problems with
CSS](https://speakerdeck.com/vjeux/react-css-in-js) by giving up some of the
complexity of CSS.
* [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
@@ -140,11 +112,17 @@ AppRegistry.runApplication('MyApp', { rootTag: document.getElementById('react-ro
## Related projects
* [react-native-web-starter](https://github.com/grabcode/react-native-web-starter)
* [react-native-web-player](https://github.com/dabbott/react-native-web-player)
* [react-primitives](https://github.com/lelandrichardson/react-primitives/)
* [react-sketchapp](https://github.com/airbnb/react-sketchapp)
* [reactxp](https://github.com/microsoft/reactxp)
* [react-web](https://github.com/taobaofed/react-web)
* [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);
}
}
}
};
};

52
benchmarks/README.md Normal file
View File

@@ -0,0 +1,52 @@
# Performance
To run these benchmarks:
```
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
implemented by multiple UI or style libraries. The implementations are not
equivalent in functionality. For example, React Native for Web's stylesheet is
unique in that it also converts React Native styles to DOM styles, has
deterministic resolution, and supports RTL layout.
`react-native-web/stylesheet` is a comparative baseline that implements a
simple `View` without much of React Native's functionality.
## Benchmark results
Typical render timings*: mean ± two standard deviations.
| Implementation | Deep tree (ms) | Wide tree (ms) | Tweets (ms) |
| :--- | ---: | ---: | ---: |
| `css-modules` | `88.83` `±18.63` | `198.79` `±22.98` | |
| `react-native-web/stylesheet@0.0.121` | `91.17` `±19.29` | `209.67` `±32.38` | |
| `react-native-web@0.0.121` | `124.21` `±16.84` | `264.55` `±38.75` | `16.90` `±7.30ms` |
Other libraries
| Implementation | Deep tree (ms) | Wide tree (ms) |
| :--- | ---: | ---: |
| `aphrodite@1.2.3` | `91.73` `±41.63` | `197.72` `±44.90` |
| `styletron@2.5.1` | `94.73` `±37.58` | `201.81` `±57.93` |
| `glamor@2.20.40` | `146.60` `±26.73` | `277.46` `±29.17` |
| `emotion@7.2.2` | `150.79` `±38.29` | `282.18` `±41.79` |
| `react-jss@7.1.0` | `201.83` `±34.65` | `428.61` `±47.8` |
| `reactxp@0.42.1` | `262.69` `±24.14` | `595.20` `±66.17` |
| `styled-components@2.1.2` | `280.59` `±31.77` | `599.00` `±62.99` |
| `styled-components/primitives@2.1.2` | `291.74` `±48.96` | `606.57` `±78.18` |
| `radium@0.19.4` | `563.94` `±69.91` | `1139.18` `±152.59` |
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,10 +1,13 @@
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';
import styledComponentsPrimitives from './src/styled-components-primitives';
import styletron from './src/styletron';
import xp from './src/reactxp';
@@ -13,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),
@@ -25,25 +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)
() => 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());

22
benchmarks/package.json Normal file
View File

@@ -0,0 +1,22 @@
{
"name": "benchmarks",
"private": true,
"dependencies": {
"aphrodite": "^1.2.3",
"classnames": "^2.2.5",
"emotion": "^7.2.2",
"glamor": "^2.20.40",
"marky": "^1.2.0",
"radium": "^0.19.4",
"react-jss": "^7.1.0",
"react-primitives": "^0.4.3",
"reactxp": "^0.42.1",
"styled-components": "^2.1.2",
"styletron-client": "^2.5.7",
"styletron-utils": "^2.5.4"
},
"devDependencies": {
"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

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

View File

@@ -15,4 +15,4 @@ const Box = ({ color, fixed = false, layout = 'column', outer = false, ...other
/>
);
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

@@ -45,4 +45,4 @@ const styles = {
}
};
module.exports = Box;
export default Box;

View File

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

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

View File

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

View File

@@ -45,4 +45,4 @@ const styles = {
})
};
module.exports = Box;
export default Box;

View File

@@ -0,0 +1,30 @@
import styled from 'styled-components/primitives';
const getColor = color => {
switch (color) {
case 0:
return '#222';
case 1:
return '#666';
case 2:
return '#999';
case 3:
return 'blue';
case 4:
return 'orange';
case 5:
return 'red';
default:
return 'transparent';
}
};
const Box = styled.View`
flex-direction: ${props => (props.layout === 'column' ? 'column' : 'row')};
padding: ${props => (props.outer ? '4px' : '0')};
height: ${props => (props.fixed ? '20px' : 'auto')};
width: ${props => (props.fixed ? '20px' : 'auto')};
background-color: ${props => getColor(props.color)};
`;
export default Box;

View File

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

View File

@@ -46,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;
@@ -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'];

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() {

View File

@@ -1,6 +1,7 @@
/* 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>;

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

@@ -2,7 +2,12 @@
import React from 'react';
import { css, StyleSheet } from 'aphrodite';
const View = ({ style, ...other }) => <div {...other} className={css(styles.root, style)} />;
class View extends React.Component {
render() {
const { style, ...other } = this.props;
return <div {...other} className={css(styles.root, style)} />;
}
}
const styles = StyleSheet.create({
root: {
@@ -23,4 +28,4 @@ const styles = StyleSheet.create({
}
});
module.exports = View;
export default View;

View File

@@ -0,0 +1,13 @@
/* eslint-disable react/prop-types */
import classnames from 'classnames';
import React from 'react';
import styles from './styles.css';
class View extends React.Component {
render() {
const props = this.props;
return <div {...props} className={classnames(styles.initial, props.className)} />;
}
}
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

@@ -2,7 +2,12 @@
import { css } from 'glamor';
import React from 'react';
const View = ({ style, ...other }) => <div {...other} className={css(viewStyle, ...style)} />;
class View extends React.Component {
render() {
const { style, ...other } = this.props;
return <div {...other} className={css(viewStyle, ...style)} />;
}
}
const viewStyle = {
alignItems: 'stretch',
@@ -21,4 +26,4 @@ const viewStyle = {
minWidth: 0
};
module.exports = View;
export default View;

View File

@@ -3,9 +3,12 @@ import classnames from 'classnames';
import injectSheet from 'react-jss';
import React from 'react';
const View = ({ classes, className, ...other }) => (
<div {...other} className={classnames(classes.root, className)} />
);
class View extends React.Component {
render() {
const { classes, className, ...other } = this.props;
return <div {...other} className={classnames(classes.root, className)} />;
}
}
const styles = {
root: {
@@ -26,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

@@ -2,11 +2,16 @@
import React from 'react';
import StyleSheet from 'react-native/apis/StyleSheet';
import registry from 'react-native/apis/StyleSheet/registry';
import createDOMProps from 'react-native/modules/createDOMProps';
const View = props => (
<div {...createDOMProps(props, style => registry.resolve([styles.root, style]))} />
);
const emptyObject = {};
class View extends React.Component {
render() {
const { style, ...other } = this.props;
const styleProps = registry.resolve([styles.root, style]) || emptyObject;
return <div {...other} {...styleProps} />;
}
}
const styles = StyleSheet.create({
root: {
@@ -27,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

@@ -6,7 +6,12 @@ import React from 'react';
export const styletron = new Styletron();
const View = ({ style, ...other }) => <div {...other} className={classnames(viewStyle, ...style)} />;
class View extends React.Component {
render() {
const { style, ...other } = this.props;
return <div {...other} className={classnames(viewStyle, ...style)} />;
}
}
const viewStyle = injectStylePrefixed(styletron, {
alignItems: 'stretch',

View File

@@ -23,9 +23,10 @@ const fontSize = {
large: '1.25rem'
};
module.exports = {
const theme = {
colors,
fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Ubuntu, "Helvetica Neue", sans-serif, ' +
fontFamily:
'-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Ubuntu, "Helvetica Neue", sans-serif, ' +
'"Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"', // emoji fonts
fontSize,
lineHeight: 1.3125,
@@ -35,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

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

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,10 +2,41 @@
# 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"
dependencies:
co "^4.6.0"
fast-deep-equal "^0.1.0"
json-schema-traverse "^0.3.0"
json-stable-stringify "^1.0.1"
alphanum-sort@^1.0.1, alphanum-sort@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3"
animated@^0.1.5:
version "0.1.5"
resolved "https://registry.yarnpkg.com/animated/-/animated-0.1.5.tgz#83df8dc443d57abab7b0bb04818b0b655b31c9b9"
dependencies:
invariant "^2.2.0"
normalize-css-color "^1.0.1"
animated@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/animated/-/animated-0.2.0.tgz#1a0e96f097b3fbc5b64d7eddc723bcc0a6f97633"
dependencies:
invariant "^2.2.0"
normalize-css-color "^1.0.1"
ansi-regex@^2.0.0:
version "2.1.1"
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df"
@@ -14,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.0:
version "1.2.0"
resolved "https://artifactory.twitter.biz:443/api/npm/js-virtual/aphrodite/-/aphrodite-1.2.0.tgz#c2f30bd1cdf6a550f4a29a0f1cf22ed10e825764"
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"
@@ -28,7 +65,19 @@ argparse@^1.0.7:
dependencies:
sprintf-js "~1.0.2"
asap@^2.0.3, asap@~2.0.3:
array-find-index@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1"
array-find@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/array-find/-/array-find-1.0.0.tgz#6c8e286d11ed768327f8e62ecee87353ca3e78b8"
asap@^2.0.3, asap@^2.0.5:
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"
@@ -49,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"
@@ -57,9 +117,25 @@ babel-code-frame@^6.11.0:
esutils "^2.0.2"
js-tokens "^3.0.0"
babel-runtime@^6.18.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"
@@ -76,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"
@@ -87,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"
@@ -94,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"
@@ -107,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"
@@ -117,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"
@@ -131,13 +238,17 @@ clone@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.2.tgz#260b7a99ebb1edfe247538175f783243cb19d149"
co@^4.6.0:
version "4.6.0"
resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184"
coa@~1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/coa/-/coa-1.0.1.tgz#7f959346cfc8719e3f7233cd6852854a7c67d8a3"
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:
@@ -181,6 +292,14 @@ core-js@^2.4.0:
version "2.4.1"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.4.1.tgz#4de911e667b0eae9124e34254b53aea6fc618d3e"
create-react-class@^15.6.0:
version "15.6.0"
resolved "https://registry.yarnpkg.com/create-react-class/-/create-react-class-15.6.0.tgz#ab448497c26566e1e29413e883207d57cfe7bed4"
dependencies:
fbjs "^0.8.9"
loose-envify "^1.3.1"
object-assign "^4.1.1"
css-color-keywords@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/css-color-keywords/-/css-color-keywords-1.0.0.tgz#fea2616dc676b2962686b3af8dbdbe180b244e05"
@@ -191,17 +310,18 @@ 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.0:
version "0.28.0"
resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-0.28.0.tgz#417cfa9789f8cde59a30ccbf3e4da7a806889bad"
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"
cssnano ">=2.6.1 <4"
icss-utils "^2.1.0"
loader-utils "^1.0.2"
lodash.camelcase "^4.3.0"
object-assign "^4.0.1"
@@ -210,7 +330,8 @@ css-loader@^0.28.0:
postcss-modules-local-by-default "^1.0.1"
postcss-modules-scope "^1.0.0"
postcss-modules-values "^1.1.0"
source-list-map "^0.1.7"
postcss-value-parser "^3.3.0"
source-list-map "^2.0.0"
css-selector-tokenizer@^0.6.0:
version "0.6.0"
@@ -290,29 +411,69 @@ csso@~2.3.1:
clap "^1.0.9"
source-map "^0.5.3"
debounce@1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/debounce/-/debounce-1.0.2.tgz#503cc674d8d7f737099664fb75ddbd36b9626dc6"
decamelize@^1.1.2:
version "1.2.0"
resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290"
deep-assign@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/deep-assign/-/deep-assign-2.0.0.tgz#ebe06b1f07f08dae597620e3dd1622f371a1c572"
dependencies:
is-obj "^1.0.0"
defined@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693"
deline@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/deline/-/deline-1.0.4.tgz#6c05c87836926e1a1c63e47882f3d2eb2c6f14c9"
electron-to-chromium@^1.2.3:
version "1.2.4"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.2.4.tgz#9751cbea89fa120bf88c226ba41eb8d0b6f1b597"
electron-to-chromium@^1.3.18:
version "1.3.21"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.21.tgz#a967ebdcfe8ed0083fc244d1894022a8e8113ea2"
emojis-list@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389"
emotion-server@^7.2.2:
version "7.2.2"
resolved "https://registry.yarnpkg.com/emotion-server/-/emotion-server-7.2.2.tgz#d1073df1c71ef6fad4ee5e32319deced97b15c6b"
dependencies:
emotion "^7.2.2"
emotion-utils "^7.2.2"
emotion-utils@^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"
@@ -324,13 +485,33 @@ 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"
fastparse@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/fastparse/-/fastparse-1.1.1.tgz#d1e2643b38a94d7583b479060e6c4affc94071f8"
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.12:
version "0.8.14"
resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.14.tgz#d1dbe2be254c35a91e09f31f9cd50a40b2a0ed1c"
dependencies:
core-js "^1.0.0"
isomorphic-fetch "^2.1.1"
loose-envify "^1.0.0"
object-assign "^4.1.0"
promise "^7.1.1"
setimmediate "^1.0.5"
ua-parser-js "^0.7.9"
fbjs@^0.8.5, fbjs@^0.8.9:
version "0.8.12"
resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.12.tgz#10b5d92f76d45575fd63a217d4ea02bea2f8ed04"
dependencies:
core-js "^1.0.0"
isomorphic-fetch "^2.1.1"
@@ -344,17 +525,23 @@ flatten@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.2.tgz#dae46a9d78fbe25292258cc1e780a41d95c03782"
flexibility@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/flexibility/-/flexibility-2.0.1.tgz#ad323aafc40f469ce624286518fc4d7cd72b7c77"
function-bind@^1.0.2:
version "1.1.0"
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.0.tgz#16176714c801798e4e8f2cf7f7529467bb4a5771"
glamor@3.0.0-1:
version "3.0.0-1"
resolved "https://registry.yarnpkg.com/glamor/-/glamor-3.0.0-1.tgz#60f489e96d96c12620803d3677ac26413cb76a95"
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"
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"
@@ -366,6 +553,10 @@ has-flag@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa"
has-flag@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-2.0.0.tgz#e8207af1cc7b30d446cc70b734b5e8be18f88d51"
has@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/has/-/has-1.0.1.tgz#8461733f538b0837c9361e39a9ab9e9704dc2f28"
@@ -392,6 +583,12 @@ icss-replace-symbols@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/icss-replace-symbols/-/icss-replace-symbols-1.0.2.tgz#cb0b6054eb3af6edc9ab1d62d01933e2d4c8bfa5"
icss-utils@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-2.1.0.tgz#83f0a0ec378bf3246178b6c2ad9136f135b1c962"
dependencies:
postcss "^6.0.1"
ieee754@^1.1.4:
version "1.1.8"
resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.8.tgz#be33d40ac10ef1926701f6f08a2d86fbfd1ad3e4"
@@ -415,13 +612,19 @@ 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"
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:
bowser "^1.6.0"
css-in-js-utils "^1.0.3"
invariant@^2.2.0, invariant@^2.2.1:
version "2.2.2"
resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.2.tgz#9e1f56ac0acdb6bf303306f338be3b204ae60360"
dependencies:
loose-envify "^1.0.0"
is-absolute-url@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-2.1.0.tgz#50530dfb84fcc9aa7dbe7852e83a37b93b9f2aa6"
@@ -430,10 +633,14 @@ 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"
is-obj@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f"
is-plain-obj@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e"
@@ -484,74 +691,88 @@ jsesc@~0.5.0:
version "0.5.0"
resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d"
json-schema-traverse@^0.3.0:
version "0.3.1"
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340"
json-stable-stringify@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af"
dependencies:
jsonify "~0.0.0"
json5@^0.5.0:
version "0.5.1"
resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821"
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"
jsonify@~0.0.0:
version "0.0.0"
resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73"
jss-compose@^3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/jss-compose/-/jss-compose-3.0.1.tgz#0ac07f20baf1d523c211016d383dab08dcfe4186"
jss-camel-case@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/jss-camel-case/-/jss-camel-case-5.0.0.tgz#886c1fe56a8a11577454d6a8b4133caa6c1f53a0"
jss-compose@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/jss-compose/-/jss-compose-4.0.0.tgz#f0109e8e8301a2678279301c24523dbc76115b9b"
dependencies:
warning "^3.0.0"
jss-default-unit@^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"
@@ -573,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.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:
@@ -612,6 +833,16 @@ 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"
normalize-range@^0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942"
@@ -629,7 +860,7 @@ num2fraction@^1.2.2:
version "1.2.2"
resolved "https://registry.yarnpkg.com/num2fraction/-/num2fraction-1.2.2.tgz#6f682b6a027a4e9ddfa4564cd2589d1d4e669ede"
object-assign@^4.0.1, object-assign@^4.1.0:
object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
@@ -694,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"
@@ -782,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"
@@ -825,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:
@@ -871,6 +1116,22 @@ postcss@^5.0.10, postcss@^5.0.11, postcss@^5.0.12, postcss@^5.0.13, postcss@^5.0
source-map "^0.5.6"
supports-color "^3.2.3"
postcss@^6.0.1:
version "6.0.3"
resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.3.tgz#b7f565b3d956fbb8565ca7c1e239d0506e427d8b"
dependencies:
chalk "^1.1.3"
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"
@@ -881,11 +1142,12 @@ promise@^7.1.1:
dependencies:
asap "~2.0.3"
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"
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"
q@^1.1.2:
version "1.4.1"
@@ -898,30 +1160,91 @@ 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"
reactxp@^0.34.3:
version "0.34.3"
resolved "https://registry.yarnpkg.com/reactxp/-/reactxp-0.34.3.tgz#6481992e57758ae6ffffbfde3d497527bb495032"
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.116"
resolved "https://registry.yarnpkg.com/react-native-web/-/react-native-web-0.0.116.tgz#e05e376b34617a54d61826e4bc06b0bdbfd3f4b2"
dependencies:
animated "^0.2.0"
array-find-index "^1.0.2"
babel-runtime "^6.23.0"
create-react-class "^15.6.0"
debounce "1.0.2"
deep-assign "^2.0.0"
fbjs "^0.8.12"
hyphenate-style-name "^1.0.2"
inline-style-prefixer "^3.0.6"
normalize-css-color "^1.0.2"
prop-types "^15.5.10"
react-timer-mixin "^0.13.3"
react-primitives@^0.4.3:
version "0.4.3"
resolved "https://registry.yarnpkg.com/react-primitives/-/react-primitives-0.4.3.tgz#4970afda5a32dccf5ea180380e3a0e16192e4b83"
dependencies:
animated "^0.1.5"
asap "^2.0.5"
deline "^1.0.4"
flexibility "^2.0.1"
inline-style-prefixer "^2.0.5"
invariant "^2.2.1"
normalize-css-color "^1.0.1"
prop-types "^15.5.10"
react-native-web "0.0.x"
react-timer-mixin "^0.13.3"
string-hash "^1.1.3"
react-timer-mixin@^0.13.3:
version "0.13.3"
resolved "https://registry.yarnpkg.com/react-timer-mixin/-/react-timer-mixin-0.13.3.tgz#0da8b9f807ec07dc3e854d082c737c65605b3d22"
react@^15.5.4:
version "15.6.1"
resolved "https://registry.yarnpkg.com/react/-/react-15.6.1.tgz#baa8434ec6780bde997cdc380b79cd33b96393df"
dependencies:
create-react-class "^15.6.0"
fbjs "^0.8.9"
loose-envify "^1.1.0"
object-assign "^4.1.0"
prop-types "^15.5.10"
reactxp@^0.42.1:
version "0.42.1"
resolved "https://registry.yarnpkg.com/reactxp/-/reactxp-0.42.1.tgz#1c142a87f0a82a8da94e5c875525952c35a53a17"
dependencies:
"@types/lodash" "^4.14.66"
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:
@@ -947,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"
@@ -972,6 +1295,12 @@ sax@~1.2.1:
version "1.2.2"
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.2.tgz#fd8631a23bc7826bef5d871bdb87378c95647828"
schema-utils@^0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-0.3.0.tgz#f5877222ce3e931edae039f17eb3716e7137f8cf"
dependencies:
ajv "^5.0.0"
setimmediate@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285"
@@ -982,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"
@@ -1000,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"
@@ -1008,35 +1341,36 @@ strip-ansi@^3.0.0:
dependencies:
ansi-regex "^2.0.0"
style-loader@^0.16.1:
version "0.16.1"
resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-0.16.1.tgz#50e325258d4e78421dd9680636b41e8661595d10"
style-loader@^0.18.2:
version "0.18.2"
resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-0.18.2.tgz#cc31459afbcd6d80b7220ee54b291a9fd66ff5eb"
dependencies:
loader-utils "^1.0.2"
schema-utils "^0.3.0"
styled-components@2.0.0-15:
version "2.0.0-15"
resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-2.0.0-15.tgz#77843c9f5267c60a97e28c97719d1ee89ea28be1"
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"
fbjs "^0.8.9"
inline-style-prefixer "^2.0.5"
hoist-non-react-statics "^1.2.0"
is-function "^1.0.1"
is-plain-object "^2.0.1"
prop-types "^15.5.4"
stylis "^2.0.0"
stylis "^3.2.1"
supports-color "^3.2.3"
styletron-client@^2.5.1:
version "2.5.1"
resolved "https://registry.yarnpkg.com/styletron-client/-/styletron-client-2.5.1.tgz#df0b6fd65965b035d2ff58df61b422aa80e23577"
styletron-client@^2.5.7:
version "2.5.7"
resolved "https://registry.yarnpkg.com/styletron-client/-/styletron-client-2.5.7.tgz#104fa4dc564cd3fe78eb92488e5ef9039c9e242f"
dependencies:
styletron-core "^2.5.1"
styletron-core "^2.5.7"
styletron-core@^2.5.1:
version "2.5.1"
resolved "https://registry.yarnpkg.com/styletron-core/-/styletron-core-2.5.1.tgz#bf9e8aebc41461b81fdd22b1062f6e25862286fd"
styletron-core@^2.5.7:
version "2.5.7"
resolved "https://registry.yarnpkg.com/styletron-core/-/styletron-core-2.5.7.tgz#2c4a1fae537b42235462e438c24ab619bbf8993e"
styletron-utils@^2.5.4:
version "2.5.4"
@@ -1044,9 +1378,16 @@ styletron-utils@^2.5.4:
dependencies:
inline-style-prefixer "^2.0.1"
stylis@^2.0.0:
version "2.0.3"
resolved "https://registry.yarnpkg.com/stylis/-/stylis-2.0.3.tgz#054b0ad1f636181664246c103adf506c84b502e7"
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"
@@ -1058,6 +1399,18 @@ supports-color@^3.2.3:
dependencies:
has-flag "^1.0.0"
supports-color@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.0.0.tgz#33a7c680aa512c9d03ef929cacbb974d203d2790"
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"
@@ -1074,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"
@@ -1102,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

@@ -3,8 +3,7 @@
`AppRegistry` is the control point for registering, running, prerendering, and
unmounting all apps. App root components should register themselves with
`AppRegistry.registerComponent`. Apps can be run by invoking
`AppRegistry.runApplication` (see the [client and server rendering
guide](../guides/rendering.md) for more details).
`AppRegistry.runApplication` (see the [getting started guide](../guides/getting-started.md) for more details).
To "stop" an application when a view should be destroyed, call
`AppRegistry.unmountApplicationComponentAtRootTag` with the tag that was passed
@@ -15,8 +14,7 @@ into `runApplication`. These should always be used as a pair.
(web) static **getApplication**(appKey:string, appParameters: object)
Returns the given application element. Use this for server-side rendering.
Return object is of type `{ element: ReactElement; stylesheet: ReactElement }`.
It's recommended that you use `sheetsheet` to render the style sheet in an app
Return object is of type `{ element: ReactElement; stylesheets: [ ReactElement ] }`.
static **registerConfig**(config: Array<AppConfig>)
@@ -42,6 +40,9 @@ Runs the application that was registered under `appKey`. The `appParameters`
must include the `rootTag` into which the application is rendered, and
optionally any `initialProps`.
On web, if the `rootTag` is a sub-section of your application it should be
styled as `position:relative` and given an explicit height.
static **unmountApplicationComponentAtRootTag**(rootTag: HTMLElement)
To "stop" an application when a view should be destroyed, call

View File

@@ -1,42 +0,0 @@
# NativeMethods
React Native for Web provides several methods to directly access the underlying
DOM node. This can be useful in cases when you want to focus a view or measure
its on-screen dimensions, for example.
The methods described are available on most of the default components provided
by React Native for Web. Note, however, that they are *not* available on the
composite components that you define in your own app. For more information, see
[Direct Manipulation](../guides/direct-manipulation.md).
## Methods
**blur**()
Removes focus from an input or view. This is the opposite of `focus()`.
**focus**()
Requests focus for the given input or view. The exact behavior triggered will
depend the type of view.
**measure**(callback: (x, y, width, height, pageX, pageY) => void)
For a given view, `measure` determines the offset relative to the parent view,
width, height, and the offset relative to the viewport. Returns the values via
an async callback.
Note that these measurements are not available until after the rendering has
been completed.
**measureLayout**(relativeToNativeNode: DOMNode, onSuccess: (x, y, width, height) => void)
Like `measure`, but measures the view relative to another view, specified as
`relativeToNativeNode`. This means that the returned `x`, `y` are relative to
the origin `x`, `y` of the ancestor view.
**setNativeProps**(nativeProps: Object)
This function sends props straight to the underlying DOM node. See the [direct
manipulation](../guides/direct-manipulation.md) guide for cases where
`setNativeProps` should be used.

View File

@@ -32,7 +32,7 @@ static **removeEventListener**(eventName: ChangeEventName, handler: Function)
**isConnected**: bool = true
Available on all user agents. Asynchronously fetch a boolean to determine
internet connectivity.
internet connectivity. Use this if you are only interested with whether the device has internet connectivity.
**isConnected.addEventListener**(eventName: ChangeEventName, handler: Function)

View File

@@ -1,9 +1,10 @@
# StyleSheet
The `StyleSheet` abstraction converts predefined styles to (vendor-prefixed)
CSS without requiring a compile-time step. Some styles cannot be resolved
outside of the render loop and are applied as inline styles. Read more about
[how to style your application](../guides/style.md).
CSS without requiring a compile-time step. Styles that cannot be resolved
outside of the render loop (e.g., dynamic positioning) are usually applied as
inline styles. Read more about [how to style your
application](../guides/style.md).
## Methods
@@ -15,9 +16,10 @@ Each key of the object passed to `create` must define a style object.
Flattens an array of styles into a single style object.
**renderToString**: function
(web) **getStyleSheets**: function
Returns a string of the stylesheet for use in server-side rendering.
Returns an array of stylesheets (`{ id, textContent }`). Useful for
compile-time or server-side rendering.
## Properties

View File

@@ -23,7 +23,7 @@ If `true`, disable all interactions for this element.
This function is called on press.
testID: ?string
**testID**: ?string
Used to locate this view in end-to-end tests.

View File

@@ -1,34 +0,0 @@
# ListView
TODO
## Props
[...ScrollView props](./ScrollView.md)
**children**: any
Content to display over the image.
**style**: style
+ ...[View#style](View.md)
## Examples
```js
import React, { Component, PropTypes } from 'react'
import { ListView } from 'react-native'
export default class ListViewExample extends Component {
static propTypes = {}
static defaultProps = {}
render() {
return (
<ListView />
)
}
}
```

View File

@@ -85,6 +85,7 @@ When `false`, the text is not selectable.
+ `textAlign`
+ `textAlignVertical`
+ `textDecorationLine`
+ `textIndent`
+ `textOverflow`
+ `textRendering`
+ `textShadowColor`

View File

@@ -103,8 +103,11 @@ Callback that is called when the text input is focused.
**onKeyPress**: ?function
Callback that is called when a key is pressed. Pressed key value is passed as
an argument to the callback handler. Fires before `onChange` callbacks.
Callback that is called when a key is pressed. This will be called with `{
nativeEvent: { key: keyValue } }` where keyValue is 'Enter` or 'Backspace' for
respective keys and the typed-in character otherwise including ' ' for space.
Modifier keys are also included in the nativeEvent. Fires before onChange
callbacks.
**onSelectionChange**: ?function

View File

@@ -18,7 +18,7 @@ NOTE: `View` will transfer all other props to the rendered HTML element.
Overrides the text that's read by a screen reader when the user interacts
with the element. (This is implemented using `aria-label`.)
See the [Accessibility guide](../guides/accessibility) for more information.
See the [Accessibility guide](../guides/accessibility.md) for more information.
**accessibilityLiveRegion**: ?enum('assertive', 'none', 'polite')
@@ -29,7 +29,7 @@ priority. When regions are specified as `assertive`, assistive technologies
will interrupt and immediately notify the user. (This is implemented using
[`aria-live`](http://www.w3.org/TR/wai-aria/states_and_properties#aria-live).)
See the [Accessibility guide](../guides/accessibility) for more information.
See the [Accessibility guide](../guides/accessibility.md) for more information.
(web) **accessibilityRole**: ?enum(roles)
@@ -38,7 +38,7 @@ in a manner that is consistent with user expectations for similar views of that
type. For example, marking a touchable view with an `accessibilityRole` of
`button`. (This is implemented using [ARIA roles](http://www.w3.org/TR/wai-aria/roles#role_definitions)).
See the [Accessibility guide](../guides/accessibility) for more information.
See the [Accessibility guide](../guides/accessibility.md) for more information.
**accessible**: ?boolean
@@ -47,7 +47,7 @@ focusable) and groups its child content. By default, all the touchable elements
and elements with `accessibilityRole` of `button` and `link` are accessible.
(This is implemented using `tabindex`.)
See the [Accessibility guide](../guides/accessibility) for more information.
See the [Accessibility guide](../guides/accessibility.md) for more information.
**children**: ?element
@@ -69,7 +69,7 @@ A value of `no` will remove the element from the tab flow.
A value of `no-hide-descendants` will hide the element and its children from
assistive technologies. (This is implemented using `aria-hidden`.)
See the [Accessibility guide](../guides/accessibility) for more information.
See the [Accessibility guide](../guides/accessibility.md) for more information.
**onLayout**: ?function
@@ -132,15 +132,15 @@ Controls whether the View can be the target of touch events. The enhanced
`box-none` is the equivalent of:
```css
.box-none { pointer-events: none }
.box-none * { pointer-events: auto }
.box-none { pointer-events: none !important; }
.box-none > * { pointer-events: auto; }
```
`box-only` is the equivalent of:
```css
.box-only { pointer-events: auto }
.box-only * { pointer-events: none }
.box-only { pointer-events: auto !important; }
.box-only > * { pointer-events: none; }
```
**style**: ?style
@@ -158,6 +158,7 @@ Controls whether the View can be the target of touch events. The enhanced
+ `animationTimingFunction`
+ `backfaceVisibility`
+ `backgroundAttachment`
+ `backgroundBlendMode`
+ `backgroundClip`
+ `backgroundColor`
+ `backgroundImage`
@@ -186,16 +187,30 @@ Controls whether the View can be the target of touch events. The enhanced
+ `borderRightWidth`
+ `borderTopWidth`
+ `bottom`
+ `boxShadow`
+ `boxShadow`
+ `boxSizing`
+ `clip`
+ `cursor`
+ `display`
+ `filter`
+ `flex` (number)
+ `flexBasis`
+ `flexDirection`
+ `flexGrow`
+ `flexShrink`
+ `flexWrap`
+ `gridAutoColumns`
+ `gridAutoFlow`
+ `gridAutoRows`
+ `gridColumnEnd`
+ `gridColumnGap`
+ `gridColumnStart`
+ `gridRowEnd`
+ `gridRowGap`
+ `gridRowStart`
+ `gridTemplateColumns`
+ `gridTemplateRows`
+ `gridTemplateAreas`
+ `height`
+ `justifyContent`
+ `left`
@@ -213,6 +228,7 @@ Controls whether the View can be the target of touch events. The enhanced
+ `opacity`
+ `order`
+ `outline`
+ `outlineColor`
+ `overflow`
+ `overflowX`
+ `overflowY`
@@ -227,6 +243,10 @@ Controls whether the View can be the target of touch events. The enhanced
+ `perspectiveOrigin`
+ `position`
+ `right`
+ `shadowColor`
+ `shadowOffset`
+ `shadowOpacity`
+ `shadowRadius`
+ `top`
+ `transform`
+ `transformOrigin`
@@ -260,7 +280,7 @@ Default:
};
```
(See [facebook/css-layout](https://github.com/facebook/css-layout)).
(See [facebook/yoga](https://github.com/facebook/yoga)).
**testID**: ?string

View File

@@ -39,33 +39,41 @@ 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.
readers, you should specify the `accessibilityRole` property. (Note that React
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.

113
docs/guides/advanced.md Normal file
View File

@@ -0,0 +1,113 @@
# Advanced use
## Use with existing React DOM components
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.
In the example below, `Video` will now accept common React Native props such as
`accessibilityLabel`, `accessible`, `style`, and even the Responder event
props.
```js
import { createElement } from 'react-native-web';
const Video = (props) => createElement('video', props);
```
This also works with composite components defined in your existing component
gallery or dependencies ([live example](https://www.webpackbin.com/bins/-KiTSGFw3fB9Szg7quLI)).
```js
import RaisedButton from 'material-ui/RaisedButton';
import { createElement } from 'react-native-web';
import { StyleSheet } from 'react-native';
const CustomButton = (props) => createElement(RaisedButton, {
...props,
style: [ styles.button, props.style ]
});
const styles = StyleSheet.create({
button: {
padding: 20
}
});
```
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.
## Use as a library framework
The React Native (for Web) building blocks can be used to create higher-level
components and abstractions. In the example below, a `styled` function provides
an API inspired by styled-components ([live
example](https://www.webpackbin.com/bins/-KjT9ziwv4O7FDZdvsnX)).
```js
import { createElement } from 'react-native-web';
import { StyleSheet } from 'react-native';
/**
* styled API
*/
const styled = (Component, styler) => {
const isDOMComponent = typeof Component === 'string';
class Styled extends React.Component {
static contextTypes = {
getTheme: React.PropTypes.func
};
render() {
const theme = this.context.getTheme && this.context.getTheme();
const localProps = { ...this.props, theme };
const nextProps = { ...this.props }
const style = typeof styler === 'function' ? styler(localProps) : styler;
nextProps.style = [ style, this.props.style ];
return (
isDOMComponent
? createElement(Component, nextProps)
: <Component {...nextProps} />
);
}
}
return Styled;
}
const styles = StyleSheet.create({
container: {
alignItems: 'center',
backgroundColor: '#2196F3',
flex: 1,
justifyContent: 'center'
}
});
const StyledView = styled(View, styles.container);
```
## Use with react-sketchapp
Use with [react-sketchapp](http://airbnb.io/react-sketchapp/) requires that you
alias `react-native` to `react-sketchapp`. This will allow you to render your
existing React Native components in Sketch. Sketch-specific components like
`Artboard` should be imported from `react-sketchapp`.
If you're using `skpm`, you can rely on an [undocumented
feature](https://github.com/sketch-pm/skpm/blob/master/lib/utils/webpackConfig.js)
which will merge your `webpack.config.js`, `.babelrc`, or `package.json` Babel
config into its internal webpack config. The simplest option may be to use the
[babel-plugin-module-alias](https://www.npmjs.com/package/babel-plugin-module-alias)
and configure it in your `package.json`.

View File

@@ -1,27 +1,68 @@
# Direct manipulation
It is sometimes necessary to make changes directly to a component without using
state/props to trigger a re-render of the entire subtree in the browser, this
is done by directly modifying a DOM node. `setNativeProps` is the React Native
equivalent to setting properties directly on a DOM node. Use direct
manipulation when frequent re-rendering creates a performance bottleneck. Direct
manipulation will not be a tool that you reach for frequently.
React Native for Web provides several methods to directly access the underlying
DOM node. This can be useful when you need to make changes directly to a
component without using state/props to trigger a re-render of the entire
subtree, or when you want to focus a view or measure its on-screen dimensions.
## `setNativeProps` and `shouldComponentUpdate`
The methods described are available on most of the default components provided
by React Native for Web. Note, however, that they are *not* available on the
composite components that you define in your own app.
## Instance methods
**blur**()
Removes focus from an input or view. This is the opposite of `focus()`.
**focus**()
Requests focus for the given input or view. The exact behavior triggered will
depend the type of view.
**measure**(callback: (x, y, width, height, pageX, pageY) => void)
For a given view, `measure` determines the offset relative to the parent view,
width, height, and the offset relative to the viewport. Returns the values via
an async callback.
Note that these measurements are not available until after the rendering has
been completed.
**measureLayout**(relativeToNativeNode: DOMNode, onSuccess: (x, y, width, height) => void)
Like `measure`, but measures the view relative to another view, specified as
`relativeToNativeNode`. This means that the returned `x`, `y` are relative to
the origin `x`, `y` of the ancestor view.
**setNativeProps**(nativeProps: Object)
This function sends props straight to the underlying DOM node. See the [direct
manipulation](../guides/direct-manipulation.md) guide for cases where
`setNativeProps` should be used.
## About `setNativeProps`
`setNativeProps` is the React Native equivalent to setting properties directly
on a DOM node. Use direct manipulation when frequent re-rendering creates a
performance bottleneck. Direct manipulation will not be a tool that you reach
for frequently.
### `setNativeProps` and `shouldComponentUpdate`
`setNativeProps` is imperative and stores state in the native layer (DOM,
UIView, etc.) and not within your React components, which makes your code more
difficult to reason about. Before you use it, try to solve your problem with
`setState` and `shouldComponentUpdate`.
## Avoiding conflicts with the render function
### Avoiding conflicts with the render function
If you update a property that is also managed by the render function, you might
end up with some unpredictable and confusing bugs because anytime the component
re-renders and that property changes, whatever value was previously set from
`setNativeProps` will be completely ignored and overridden.
## Why use `setNativeProps` on Web?
### Why use `setNativeProps` on Web?
Using `setNativeProps` in web-specific code is required when making changes to
`className` or `style`, as these properties are controlled by React Native for
@@ -35,7 +76,7 @@ setOpacityTo(value) {
}
```
## Composite components and `setNativeProps`
### Composite components and `setNativeProps`
Composite components are not backed by a DOM node, so you cannot call
`setNativeProps` on them. Consider this example:
@@ -63,7 +104,7 @@ prop on it and have that work - you would need to pass the style prop down to a
child, unless you are wrapping a native component. Similarly, we are going to
forward `setNativeProps` to a native-backed child component.
## Forward `setNativeProps` to a child
### Forward `setNativeProps` to a child
All we need to do is provide a `setNativeProps` method on our component that
calls `setNativeProps` on the appropriate child with the given arguments.
@@ -86,7 +127,7 @@ class MyButton extends React.Component {
You can now use `MyButton` inside of `TouchableOpacity`!
## `setNativeProps` to clear `TextInput` value
### `setNativeProps` to clear `TextInput` value
Another very common use case of `setNativeProps` is to clear the value of a
`TextInput`. For example, the following code demonstrates clearing the input

View File

@@ -1,13 +1,22 @@
# Getting started
## Webpack and Babel
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 the starter kits listed in the README.)
[Webpack](webpack.js.org) is a popular build tool for web apps. Below is an
It is recommended that your application provide a `Promise` and `Array.from`
polyfill.
## Web packager
[Webpack](https://webpack.js.org) is a popular build tool for web apps. Below is an
example of how to configure a build that uses [Babel](https://babeljs.io/) to
compile your JavaScript for the web.
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
@@ -25,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']
}
}
@@ -54,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`.
@@ -73,9 +82,120 @@ module.exports = {
}
```
Please refer to the Webpack documentation for more information.
To run in development:
## Jest
```
./node_modules/.bin/webpack-dev-server -d --config web/webpack.config.js --inline --hot --colors
```
To build for production:
```
./node_modules/.bin/webpack -p --config web/webpack.config.js
```
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 { Platform } from 'react-native';
const styles = StyleSheet.create({
height: (Platform.OS === 'web') ? 200 : 100,
});
```
More significant platform differences should use platform-specific files (see
the webpack configuration above for resolving `*.web.js` files):
For example, with the following files in your project:
```
MyComponent.android.js
MyComponent.ios.js
MyComponent.web.js
```
And the following import:
```js
import MyComponent from './MyComponent';
```
React Native will automatically import the correct variant for each specific
target platform.
## Testing with Jest
[Jest](https://facebook.github.io/jest/) also needs to map `react-native` to `react-native-web`.
@@ -88,73 +208,3 @@ Please refer to the Webpack documentation for more information.
```
Please refer to the Jest documentation for more information.
## Web-specific code
Minor platform differences can use the `Platform` module.
```js
import { AppRegistry, Platform } from 'react-native'
AppRegistry.registerComponent('MyApp', () => MyApp)
if (Platform.OS === 'web') {
AppRegistry.runApplication('MyApp', {
rootTag: document.getElementById('react-root')
});
}
```
## Client-side rendering
Rendering using `ReactNative`:
```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'))
```
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 introduce `react-native-web`
to an existing web app, but it is not recommended oherwise.
## 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, stylesheet } = AppRegistry.getApplication('App', { initialProps });
const initialHTML = ReactDOMServer.renderToString(element);
```

View File

@@ -1,73 +1,90 @@
# Style
React Native for Web relies on JavaScript to define styles for your
application. This allows you to avoid issues arising from the [7 deadly sins of
CSS](https://speakerdeck.com/vjeux/react-css-in-js):
React Native relies on JavaScript to define and resolve the styles of your
application. React Native for Web implements the React Native style API in a
way that avoids *all* the [problems with CSS at
scale](https://speakerdeck.com/vjeux/react-css-in-js):
1. Global namespace
2. Dependency hell
1. No local variables
2. Implicit dependencies
3. No dead code elimination
4. No code minification
5. No sharing of constants
6. Non-deterministic resolution
7. Lack of isolation
7. No isolation
At the same time, it has several benefits:
1. Simple API and expressive subset of CSS
2. Generates CSS; the minimum required
3. Good runtime performance
4. Support for static and dynamic styles
5. Support for RTL layouts
6. Easy pre-rendering of critical CSS
## Defining styles
Styles should be defined outside of the component:
Styles should be defined outside of the component. Using `StyleSheet.create` is
optional but provides the best performance (by relying on generated CSS
stylesheets). Avoid creating unregistered style objects.
```js
class Example extends React.Component {}
const styles = StyleSheet.create({
heading: {
color: 'gray',
fontSize: '2rem'
},
text: {
color: 'gray',
fontSize: '1.25rem'
marginTop: '1rem',
margin: 10
}
})
```
Using `StyleSheet.create` is optional but provides the best performance
(`style` is resolved to CSS stylesheets). Avoid creating unregistered style
objects.
The attribute names and values are a subset of CSS. See the `style`
documentation of individual components.
See the `style` documentation of individual components for supported properties.
## Using styles
All the React Native components accept a `style` attribute.
All the React Native components accept a `style` property. The value can be a
registered object, a plain object, or an array.
```js
<Text style={styles.text} />
// registered object
<View style={styles.view} />
// plain object
<View style={{ transform: [ { translateX } ] }} />
// array of registered or plain objects
<View style={[ styles.container, this.props.style ]} />
```
A common pattern is to conditionally add style based on a condition:
The array syntax will merge styles from left-to-right as normal JavaScript
objects, and can be used to conditionally apply styles:
```js
// either
<View style={[
styles.base,
styles.container,
this.state.active && styles.active
]} />
```
When styles are registered with `StyleSheet.create`, the return value is a
number and not a style object. This is important for performance optimizations,
but still allows you to merge styles in a deterministic manner at runtime. If
you need access to the underlying style objects you need to use
`StyleSheet.flatten` (but be aware that this is not the optimized path).
## Composing styles
In order to let a call site customize the style of your component children, you
can pass styles around. Use `View.propTypes.style` and `Text.propTypes.style` in
order to make sure only valid styles are being passed.
To let other components customize the style of a component's children you can
expose a prop so styles can be explicitly passed into the component.
```js
class List extends React.Component {
static propTypes = {
style: View.propTypes.style,
elementStyle: View.propTypes.style,
style: ViewPropTypes.style,
elementStyle: ViewPropTypes.style,
}
render() {
@@ -90,56 +107,126 @@ In another file:
You also have much greater control over how styles are composed when compared
to using class names. For example, you may choose to accept a limited subset
of style props in the component's API, and control when they are applied:
of style props in the component's API, and control when they are applied.
```js
class List extends React.Component {
static propTypes = {
children: React.PropTypes.any,
// limit which styles are accepted
style: React.PropTypes.shape({
borderColor: View.propTypes.borderColor,
borderWidth: View.propTypes.borderWidth
})
}
## How styles are resolved
render() {
return (
<View
children={children}
style={[
this.props.style,
// override border-color when scrolling
isScrolling && { borderColor: 'transparent' }
]}
/>
)
}
}
React Native style resolution is deterministic and slightly different from CSS.
In the following HTML/CSS example, the `.margin` selector is defined last in
the CSS and takes precedence over the previous rules, resulting in a margin of
`0, 0, 0, 0`.
```html
<style>
.marginTop { margin-top: 10px; }
.marginBottom { margin-bottom: 20px; }
.margin { margin: 0; }
</style>
<div class="marginTop marginBottom margin"></div>
```
## Media Queries
But in React Native the most *specific* style property takes precedence,
resulting in margins of `10, 0, 20, 0`.
```js
const style = [
{ marginTop: 10 },
{ marginBottom: 20 },
{ margin: 0 }
];
const Box = () => <View style={style} />
```
## Implementation details
React Native for Web transforms React Native styles into React DOM styles. Any
styles defined using `StyleSheet.create` will ultimately be rendered using CSS
class names.
React Native for Web introduced a novel strategy to achieve this. Each rule is
broken down into declarations, properties are expanded to their long-form, and
the resulting key-value pairs are mapped to unique "atomic CSS" class names.
Input:
```js
const Box = () => <View style={styles.box} />
const styles = StyleSheet.create({
box: {
margin: 0
}
});
```
Output:
```html
<style>
.rn-1mnahxq { margin-top: 0px; }
.rn-61z16t { margin-right: 0px; }
.rn-p1pxzi { margin-bottom: 0px; }
.rn-11wrixw { margin-left: 0px; }
</style>
<div class="rn-156q2ks rn-61z16t rn-p1pxzi rn-11wrixw"></div>
```
This ensures that CSS order doesn't impact rendering and CSS rules are
efficiently deduplicated. Rather than the total CSS growing in proportion to
the number of *rules*, it grows in proportion to the number of *unique
declarations*. As a result, the DOM style sheet is only written to when new
unique declarations are defined and it is usually small enough to be
pre-rendered and inlined.
Class names are deterministic, which means that the resulting CSS and HTML is
consistent across builds important for large apps using code-splitting and
deploying incremental updates.
At runtime registered styles are resolved to DOM style props and memoized.
Any dynamic styles that contain declarations previously registered as static
styles can also be converted to CSS class names. Otherwise, they render as
inline styles.
All this allows React Native for Web to support the rich functionality of React
Native styles (including RTL layouts and `setNativeProps`) while providing one
of the [fastest](https://github.com/necolas/react-native-web/blob/master/benchmarks/README.md),
safest, and most efficient styles-in-JavaScript solutions.
## FAQs
### What about Media Queries?
`StyleSheet.create` is a way of defining the styles your application requires;
it does not concern itself with _where_ or _when_ those styles are applied to
elements.
There are various React libraries wrapping JavaScript Media Query API's, e.g.,
Media Queries may not be most appropriate for component-based designs. React
Native provides the `Dimensions` API and `onLayout` props. If you do need Media
Queries, using the `matchMedia` DOM API has the benefit of allowing you to swap
out entire components, not just styles. There are also many React libraries
wrapping JavaScript Media Query API's, e.g.,
[react-media](https://github.com/reacttraining/react-media),
[react-media-queries](https://github.com/bloodyowl/react-media-queries),
[media-query-fascade](https://github.com/tanem/media-query-facade), or
[react-responsive](https://github.com/contra/react-responsive). This has the
benefit of co-locating breakpoint-specific DOM and style changes.
[react-responsive](https://github.com/contra/react-responsive).
## Pseudo-classes and pseudo-elements
### What about pseudo-classes and pseudo-elements?
Pseudo-classes like `:hover` and `:focus` can be implemented with events (e.g.
`onFocus`). Pseudo-elements are not supported; elements should be used instead.
### Reset
### Do I need a CSS reset?
You **do not** need to include a CSS reset or
[normalize.css](https://necolas.github.io/normalize.css/).
No. React Native for Web includes a very small CSS reset that removes unwanted
User Agent styles from (pseudo-)elements beyond the reach of React (e.g.,
`html`, `body`) or inline styles (e.g., `::-moz-focus-inner`). The rest is
handled at the component-level.
React Native for Web includes a very small CSS reset taken from normalize.css.
It removes unwanted User Agent styles from (pseudo-)elements beyond the reach
of React (e.g., `html`, `body`) or inline styles (e.g., `::-moz-focus-inner`).
### What about using Dev Tools?
React Dev Tools supports inspecting and editing of React Native styles. It's
recommended that you rely more on React Dev Tools and live/hot-reloading rather
than inspecting and editing the DOM directly.

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

View File

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

View File

@@ -0,0 +1,23 @@
import { setOptions } from '@storybook/addon-options';
import centered from './decorator-centered';
import { configure, addDecorator } from '@storybook/react';
const context = require.context('../', true, /Screen\.js$/);
addDecorator(centered);
setOptions({
name: 'React Native Web',
url: 'https://necolas.github.io/react-native-web',
goFullScreen: false,
showLeftPanel: true,
showDownPanel: false,
showSearchBox: false,
downPanelInRight: false
});
function loadStories() {
context.keys().forEach(context);
}
configure(loadStories, module);

View File

@@ -0,0 +1,14 @@
import React from 'react';
import { StyleSheet, View } from 'react-native';
const styles = StyleSheet.create({
root: {
minHeight: '100vh',
maxWidth: 680,
marginHorizontal: 'auto'
}
});
export default function(renderStory) {
return <View style={styles.root}>{renderStory()}</View>;
}

View File

@@ -0,0 +1,36 @@
const path = require('path');
const webpack = require('webpack');
module.exports = (storybookBaseConfig, configType) => {
const DEV = configType === 'DEVELOPMENT';
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
})
);
storybookBaseConfig.resolve.alias = {
'react-native': path.join(__dirname, '../../../src/module')
};
return storybookBaseConfig;
};

View File

@@ -0,0 +1,59 @@
/* eslint-disable react/jsx-sort-props */
/**
* @flow
*/
import PropAnimating from './examples/PropAnimating';
import PropColor from './examples/PropColor';
import PropHidesWhenStopped from './examples/PropHidesWhenStopped';
import PropSize from './examples/PropSize';
import React from 'react';
import UIExplorer, { Description, DocItem, Section, storiesOf } from '../../ui-explorer';
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"
typeInfo="?boolean = true"
description="Whether to show the indicator or hide it."
example={{
render: () => <PropAnimating />
}}
/>
<DocItem
name="color"
typeInfo="?color = #1976D2"
description="The foreground color of the spinner."
example={{
render: () => <PropColor />
}}
/>
<DocItem
name="hidesWhenStopped"
typeInfo="?boolean = true"
description="Whether the indicator should hide when not animating."
example={{
render: () => <PropHidesWhenStopped />
}}
/>
<DocItem
name="size"
typeInfo="?enum('small', 'large') | number = 'small'"
description="Size of the indicator. Small has a height of 20px, large has a height of 36px."
example={{
render: () => <PropSize />
}}
/>
</Section>
</UIExplorer>
);
storiesOf('Components', module).add('ActivityIndicator', ActivityIndicatorScreen);

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