Compare commits

..

355 Commits

Author SHA1 Message Date
Kyle Fang
7b021c56f0 feat: add logbox functions 2020-10-31 14:41:16 +08:00
Nicolas Gallagher
6624a70cca 0.14.7 2020-10-30 10:52:37 -07:00
Nicolas Gallagher
5806b249dd [fix] Use browser expansion of 'flex' style
Fix #1792
2020-10-30 10:47:32 -07:00
Nicolas Gallagher
1048f7ce3e 0.14.6 2020-10-29 17:14:39 -07:00
Nicolas Gallagher
18f5a33c0d [fix] Don't require mocking window.matchMedia in jest
For people who don't mock unsupported DOM APIs for jsdom in their jest setup.

Fix #1789
2020-10-29 17:13:47 -07:00
Nicolas Gallagher
07e578edb8 [fix] ResponderSystem negotiation logic
This fixes a bug in the negotiation logic that caused a cycle of
terminate->grant events to be sent to the current responder during a pointer
move. The root cause was using an incorrect event path in the calculation of
the lowest common ancestor's index. The fix is to ensure that the event path
stored with the current responder is pruned to begin with the node that is the
current responder (rather than any child responders it may have contained).
2020-10-29 17:13:46 -07:00
Nicolas Gallagher
d2e6c29e25 [fix] Pan interactions should cancel 'click' events on the target
If a pan interaction has taken place, it is not expected that 'click' events
occur on the target element when the pointer is released (as was occuring with
mouse pointers). This patch cancels any 'click' that occurs within the pan
target's subtree, within 250ms of the pan gesture ending.

Fix #1788
2020-10-29 17:13:42 -07:00
Nicolas Gallagher
03897d32be [fix] Disabled pressables should propagate 'click' events
If a pressable is disabled it should not prevent the propagation of native
'click' events, unless the underlying DOM node has an 'aria-role' of 'button'.
This emulates the native '<button>' behavior.

Fix #1781
2020-10-29 15:57:35 -07:00
Nicolas Gallagher
b8fddcf6b1 0.14.5 2020-10-27 11:06:27 -07:00
Charlie Croom
d9c755dff0 [fix] Enter key handling for components explicitly given accessible prop
Close #1783
2020-10-27 10:54:24 -07:00
burakgormek
63c39454de [fix] Pressable disabled cursor state
Close #1782
2020-10-27 10:54:18 -07:00
Nicolas Gallagher
89be8a9f8b Fix ViewProps import path
This error was not surfaced by Flow locally but surfaced in CI.
2020-10-22 12:28:17 -07:00
Nicolas Gallagher
b4e53e8cd3 0.14.4 2020-10-22 11:00:02 -07:00
Charlie Croom
cea4172efb [fix] Prevent onClick being called when certain roles are disabled
Fix #1779
Close #1780
2020-10-22 10:56:40 -07:00
Charlie Croom
a2d72ee89c [fix] Avoid usePlatformMethods excess ref creation
Close #1777
2020-10-22 10:35:13 -07:00
Nicolas Gallagher
2428b6c6fc 0.14.3 2020-10-19 16:02:22 -07:00
Nicolas Gallagher
0aa77685aa [fix] Add matrix transform style
Remove the deprecated 'transformMatrix' style prop and support 'matrix' and
'matrix3d' in the 'transform' prop.

Fix #1771
2020-10-19 15:50:02 -07:00
Nicolas Gallagher
663458713c 0.14.2 2020-10-16 12:57:49 -07:00
TikiTDO
3118315140 [fix] Remove 'collapsable' prop from createAnimatedComponent
This is an Android-only prop that has no platform guard in React Native. The
web has a native 'collapsable' prop that React DOM complains about when it is
not a string value.

Close #1767
2020-10-16 12:55:51 -07:00
Charlie Croom
09c2f1975b [fix] Prevent constant Image reloading when source given as an object
Close #1770
2020-10-16 12:55:48 -07:00
Charlie Croom
18d5d449a7 [fix] Callback ref less on Views by making classList constant
Close #1766
2020-10-16 12:33:58 -07:00
Nicolas Gallagher
933bd138ce 0.14.1 2020-10-12 13:41:20 -07:00
Nicolas Gallagher
c2019a9881 [fix] Pressable cursor and touch-action styles
Also add unit tests for Pressable.

Fix #1764
2020-10-12 13:37:42 -07:00
Nicolas Gallagher
78174d7b48 0.14.0 2020-10-09 12:59:41 -07:00
Nicolas Gallagher
38fd574984 [add] Pressable support for hover state
This patch ports the 'useHover' hook to React Native for Web, providing hover
state that is scoped to a pressable and does not bubble to ancestor pressables.
This behavior aligns with the behavior of the focus and press states.

Fix #1708
2020-10-09 11:35:36 -07:00
Nicolas Gallagher
5b7a6bc30a Move hooks into 'modules' directory 2020-10-09 11:35:35 -07:00
James Ward
d97a1ca567 [add] Modal component
This adds support for the React Native Modal on web.

The app content is hidden from screen readers by setting the aria-modal flag on
the modal. This focus is trapped within the modal, both when attempting to
focus elsewhere using the mouse as well as when attempting to focus elsewhere
using the keyboard. A built-in "Escape to close" mechanism is been implemented
that calls 'onRequestClose' for the active modal.

Close #1646
Fix #1020
2020-10-09 11:32:31 -07:00
Nicolas Gallagher
6bd41a622a Remove react-dom vendor directory 2020-10-09 11:32:30 -07:00
Nicolas Gallagher
108366a724 [change] Default flex-basis value of Views
React Native has an implementation of flexbox that does not quite follow the
W3C spec for flexbox. Previously, React Native for Web attempted to replicate
the React Native rendering by setting flexBasis to 0%. However, this created
its own problems where views could collapse down to 0px in height on the web.
This patch relies sets the default flexBasis back to 'auto'. This will cause
different rendering inconsistencies with React Native, which can be addressed
by making changes to existing React Native styles. And ultimately, it is up to
Yoga to correct its flexbox implementation.

Fix #1640
Fix #1604
Fix #1264
Close #1265
2020-10-09 11:32:30 -07:00
Nicolas Gallagher
bf2e10d482 0.13.18 2020-10-09 11:17:09 -07:00
Mark Lawlor
faf7fa3374 [fix] skip ResizeObserver warning during SSR
Close #1762
2020-10-09 11:14:00 -07:00
Nicolas Gallagher
df14c7278a 0.13.17 2020-10-08 12:29:11 -07:00
Nicolas Gallagher
b15e8784c4 Add unit tests for ref imperative methods 2020-10-08 12:27:15 -07:00
Nicolas Gallagher
583e16fa8d Memoize refs
Refs can be memoized following the fix in the previous commit.

Fix #1755
Fix #1665
2020-10-07 15:28:34 -07:00
Nicolas Gallagher
b4322734a2 [fix] Order of ref merging
Ensure internal refs are called before the forwardedRef. This ensures that the
DOM element mutation performed by usePlatformMethods occurs before user-space
refs are called.

Ref #1749
2020-10-07 15:28:33 -07:00
Nicolas Gallagher
bdcb4de7dc 0.13.16 2020-10-06 11:41:31 -07:00
Nicolas Gallagher
d8ee51e326 [fix] CSS scrollbarWidth
The previous code wasn't inserting the W3C rule because it had the same selector as the rule for proprietary styles. However, the Firefox value isn't supported anymore, and the Edge value is unnecessary as Edge uses Blink now. This patch removes the non-WebKit fallback styles for this property.

Fix #1760
2020-10-06 11:38:17 -07:00
Nicolas Gallagher
aad0c88cea 0.13.15 2020-10-05 15:38:06 -07:00
Nicolas Gallagher
6d04e7243e [fix] Don't propagate click or contextmenu events on disabled elements
This patch fixes the PressResponder to avoid propagating click and contextmenu
events in all circumstances. It also prevents click propagating for focusable
elements that are disabled, mirroring the behavior of native buttons when
disabled.

Fix #1757
2020-10-05 15:33:50 -07:00
Julian Hundeloh
ba5e9e3079 [add] AccessibilityInfo isReduceMotionEnabled
Close #1754
2020-10-05 14:51:41 -07:00
Shobhit Chittora
06d3cadf05 Update docs suggested preset to metro-react-native-babel-preset
Updating the document as `babel-preset-react-native` is deprecated in favor for
`metro-react-native-babel-preset`. More info here -
https://www.npmjs.com/package/babel-preset-react-native.

Close #1751
2020-10-05 14:48:38 -07:00
Nicolas Gallagher
72bfe499c5 Add to View tests 2020-10-05 14:28:27 -07:00
Nicolas Gallagher
92ac1f94c5 Add to Text tests 2020-10-05 13:20:28 -07:00
Nicolas Gallagher
5edba02319 Add to Image tests 2020-10-05 13:16:13 -07:00
Nicolas Gallagher
2276e17310 Add to CheckBox tests 2020-10-05 13:16:12 -07:00
Nicolas Gallagher
222fa3490e Add to Button tests 2020-10-05 13:16:11 -07:00
Nicolas Gallagher
0fb3036f31 Add to ActivityIndicator tests 2020-10-05 13:16:11 -07:00
Nicolas Gallagher
7bc6fc8347 0.13.14 2020-09-24 13:39:37 -07:00
Nicolas Gallagher
c60417ab34 [fix] Revert ref memoization
Memoizing refs caused unexpected regressions in some class component patterns.
The memoization is being reverted for now.

Fix #1749
2020-09-24 13:26:21 -07:00
Nicolas Gallagher
af0d80a808 0.13.13 2020-09-21 15:56:18 -07:00
Richard Lindhout
12e91a35a4 [fix] nested Text selection
Allow text to be made selectable within a text node that is not selectable.

Close #1742
2020-09-21 15:49:27 -07:00
Nicolas Gallagher
376ccc31b1 [fix] Optimize ref merging
Close #1746
Fix #1665
2020-09-21 14:04:14 -07:00
Hossein Mohammadi
4a70300b08 Remove unnecessary code from setValueForStyles
Close #1734
2020-09-11 10:27:52 -07:00
Nicolas Gallagher
7ab04987f0 Fix compressed-size build script 2020-09-09 16:08:56 -07:00
Nicolas Gallagher
f52a9bcfd2 Add compressed-size action
Reports minified + gzipped size of modules
2020-09-09 13:46:23 -07:00
Nicolas Gallagher
74acb21aa8 0.13.12 2020-09-09 11:57:58 -07:00
Nicolas Gallagher
1e1236597a [fix] Image SSR hydration warnings
React doesn't currently provide an API for defining SSR-safe IDs, so we have to
suppress the hydration warnings that occur.

The 'useOpaqueIdentifier' hook is intended to support this use case but is not
currently a public API and development has been paused.
https://github.com/facebook/react/pull/17322.

Close #1375
2020-09-09 11:56:50 -07:00
SaltyWater
e9d81afbd4 [fix] Forward scroll end event to ScrollView onScroll handler
Close #1728
2020-09-09 11:43:53 -07:00
Nicolas Gallagher
9ed9231b04 0.13.11 2020-09-08 12:33:37 -07:00
Nicolas Gallagher
d5ab3770c0 [fix] PressResponder keyboard edge-case
Fixes the state-machine logic for the press responder when focus is moved away
from the target element during a 'keydown' event.
2020-09-08 12:32:00 -07:00
Nicolas Gallagher
397de88137 0.13.10 2020-09-08 11:24:19 -07:00
Nicolas Gallagher
bb8a1b1455 [fix] ScrollView scrollEventThrottle logic
Fix #1726
2020-09-08 11:22:35 -07:00
dependabot[bot]
214b296c11 Bump bin-links from 1.1.3 to 1.1.8
Bumps [bin-links](https://github.com/npm/bin-links) from 1.1.3 to 1.1.8.
- [Release notes](https://github.com/npm/bin-links/releases)
- [Changelog](https://github.com/npm/bin-links/blob/v1.1.8/CHANGELOG.md)
- [Commits](https://github.com/npm/bin-links/compare/v1.1.3...v1.1.8)

Signed-off-by: dependabot[bot] <support@github.com>
2020-09-08 11:02:38 -07:00
dependabot[bot]
a7df78afbe Bump markdown-to-jsx from 6.10.3 to 6.11.4
Bumps [markdown-to-jsx](https://github.com/probablyup/markdown-to-jsx) from 6.10.3 to 6.11.4.
- [Release notes](https://github.com/probablyup/markdown-to-jsx/releases)
- [Commits](https://github.com/probablyup/markdown-to-jsx/compare/6.10.3...6.11.4)

Signed-off-by: dependabot[bot] <support@github.com>
2020-09-08 11:02:25 -07:00
Harrison Mendonça
c6425a0048 [fix] Add event parameter to Image onLoad callback
Close #1723
2020-09-08 11:01:29 -07:00
Nicolas Gallagher
8add92f776 0.13.9 2020-08-25 12:05:29 -07:00
Nicolas Gallagher
9a0acc5464 [fix] Layout of nested Text elements
Remove the 'dir=auto' attribute from nested Text elements as this can cause
browsers to produce broken text layouts.

Fix #1714
2020-08-25 12:04:08 -07:00
Nicolas Gallagher
a31c4c65d0 [fix] Remove Animated 'useNativeDriver' warning
Fix #1693
2020-08-25 11:12:29 -07:00
Colby Stauss
834bd5b98b [fix] Animated getScrollableNode check
Close #1695
Fix #1680
2020-08-25 11:10:10 -07:00
Nicolas Gallagher
de2a66c694 [fix] ResponderEvent touch identifier normalization
Move the touch identifier normalization into the ResponderEvent creation. This ensures that the identifier is consistent throughout. If application code reads an identifier from a touch object it can be used to find that touch in the `touchBank` array.

Fix #1716
2020-08-25 10:58:39 -07:00
Richard Lindhout
9ed0c407a9 [fix] TextInput keyboardType for 'numeric' and 'decimal'
Don't rely on native restrictions and validations for these keyboardType
values, as developers often want custom presentation (e.g., comma separators)
and custom validation.

Fix #1705
Fix #1438
Fix #1280
Close #1709
2020-08-21 11:00:21 -07:00
H3RSKO
7a8a70b948 Fix typo in README
Close #1706
2020-08-21 10:42:22 -07:00
Nicolas Gallagher
67a3d78799 0.13.8 2020-08-17 11:32:37 -07:00
Nicolas Gallagher
77bdb9086e [fix] Avoid needing to memoize onLayout callbacks
If 'onLayout' is an inline function, it could cause the DOM node to enter a
cycle of being observed/unobserved with the result that 'onLayout' was
constantly called.

Fix #1704
2020-08-17 11:10:53 -07:00
Nicolas Gallagher
7fc17d01cc 0.13.7 2020-08-12 10:58:28 -07:00
Evan Bacon
b8283245cf [fix] check for window availability in ResponderSystem
Close #1699
2020-08-12 10:50:11 -07:00
Nicolas Gallagher
75c5a90563 0.13.6 2020-08-10 14:13:13 -07:00
Nicolas Gallagher
3233d0ffe9 [fix] Responder negotiation between siblings
There should be responder negotiation between siblings if there is no common ancestor connected to the responder system. Instead the current responder should continue to receive events. This was only occuring for mouse events during mousemove, as the target can change during the course of the movement.
2020-08-10 13:26:13 -07:00
Nicolas Gallagher
251cdfb220 0.13.5 2020-08-03 14:10:51 -07:00
Nicolas Gallagher
7c46a3667e [fix] update System font stack
Remove system-ui as it has rendering issues for certain OS/language combinations.
See https://phabricator.wikimedia.org/T175877

Fix #1638
2020-08-03 14:09:57 -07:00
Nicolas Gallagher
5a15dcae66 [fix] Dimensions doesn't debounce change listener
Fix #1662
2020-08-03 13:46:47 -07:00
Nicolas Gallagher
af0ae004ff [fix] Image forwards ViewProps
Close #1637
2020-08-03 13:44:27 -07:00
Ryoga Kitagawa
08f722ac86 [fix] ScrollView forwards dataSet
Close #1675
2020-08-03 13:43:44 -07:00
dependabot[bot]
6bf69c0015 Bump elliptic from 6.4.1 to 6.5.3
Bumps [elliptic](https://github.com/indutny/elliptic) from 6.4.1 to 6.5.3.
- [Release notes](https://github.com/indutny/elliptic/releases)
- [Commits](https://github.com/indutny/elliptic/compare/v6.4.1...v6.5.3)

Signed-off-by: dependabot[bot] <support@github.com>
2020-07-30 11:22:01 -07:00
dependabot[bot]
28f51fa492 Bump lodash from 4.17.15 to 4.17.19
Bumps [lodash](https://github.com/lodash/lodash) from 4.17.15 to 4.17.19.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.15...4.17.19)

Signed-off-by: dependabot[bot] <support@github.com>
2020-07-30 11:21:40 -07:00
Nicolas Gallagher
5426762ed4 0.13.4 2020-07-20 12:26:49 -07:00
Nicolas Gallagher
10de987785 [fix] usePlatformMethods guard against null hostNode
Fix #1679
2020-07-20 12:22:17 -07:00
Nicolas Gallagher
72638d028b 0.13.3 2020-07-07 14:43:10 -07:00
Colby Stauss
097cd31a90 [fix] Image tintColor updates
Fix #1319
Close #1664
2020-07-07 14:40:45 -07:00
Nicolas Gallagher
96dcce0261 0.13.2 2020-07-07 11:45:46 -07:00
Nicolas Gallagher
1497bb4d72 [fix] TouchableWithoutFeedback child ref
Fix #1663
2020-07-07 11:35:54 -07:00
dependabot[bot]
99e6d7137f Bump websocket-extensions from 0.1.3 to 0.1.4
Bumps [websocket-extensions](https://github.com/faye/websocket-extensions-node) from 0.1.3 to 0.1.4.
- [Release notes](https://github.com/faye/websocket-extensions-node/releases)
- [Changelog](https://github.com/faye/websocket-extensions-node/blob/master/CHANGELOG.md)
- [Commits](https://github.com/faye/websocket-extensions-node/compare/0.1.3...0.1.4)

Signed-off-by: dependabot[bot] <support@github.com>
2020-07-01 10:59:24 -07:00
Nicolas Gallagher
8c391604ba 0.13.1 2020-06-29 12:20:51 -07:00
Nicolas Gallagher
7ef070195b [fix] setNativeProps and pointerEvent prop
The pointerEvent prop is converted into a DOM style property and needs to be
accounted for by setNativeProps.

Close #1656
Fix #1655
2020-06-29 10:58:34 -07:00
Nicolas Gallagher
728e20ff1f [fix] jest preset
Fix #1654
2020-06-29 09:59:17 -07:00
Nicolas Gallagher
824cca1972 0.13.0 2020-06-26 15:16:53 -07:00
Nicolas Gallagher
cfe36d780e Minimal update of Animated
Ref #1576
2020-06-26 14:51:55 -07:00
Nicolas Gallagher
5dda71c2a6 [change] Remove 'accessibilityRelationship'; add 'dataSet'
Remove the 'accessibilityRelationship' prop which is not part of React Native.
The general approach to supporting ARIA-like accessibility APIs in React Native
needs revisiting and it will be easier to stop going down this path.

This patch also reverts the "unstable_ariaSet" change, and renames
"unstable_dataSet" to "dataSet". Avoiding another breaking change to
accessibility props will ease upgrading for now.
2020-06-26 14:51:55 -07:00
Nicolas Gallagher
972317c17c PressResponder fix invariant edge case
If keyup events fall through to a "pressable" element that is not the responder
(e.g., a keydown in a modal closes the modal) it should not attempt to
transition the state.

Also replace invariant with console.error to allow the app to recover if
unexpected signals occur.
2020-06-26 14:51:54 -07:00
Nicolas Gallagher
0901be6e5c [fix] TextInput onKeyPress and onSubmitEditing events
onKeyPress forwards the synthetic keydown event.
onSubmitEditing is only called if IME composition is not in progress.

Fix #1332
2020-06-26 14:51:53 -07:00
Nicolas Gallagher
52f903229e Minor cleanup of StyleSheet 2020-06-26 14:51:52 -07:00
Nicolas Gallagher
3230713d6b [change] Remove support for microdata props
Microdata was removed from the HTML spec and most browsers.
2020-06-26 14:51:52 -07:00
Nicolas Gallagher
53dd03d83b Fix PressResponder click prevention logic 2020-06-26 14:51:51 -07:00
Nicolas Gallagher
c2d4fd6d77 Fix TextInput onSelectionChange logic 2020-06-26 14:51:51 -07:00
Nicolas Gallagher
fc78cb06fd Fix updates to opacity in TouchableOpacity 2020-06-26 14:51:50 -07:00
liorJuice
cd9be22947 [fix] Clipboard copy edge-case
Make sure clipboard works even if global CSS is affecting user text selection.

Fix #1559
2020-06-26 14:51:50 -07:00
Jaap Frolich
324995ec2b [add] Appearance module
Close #1597
2020-06-26 14:51:50 -07:00
Nicolas Gallagher
cecacbc3ac Add eslint-plugin-flowtype 2020-06-26 14:51:49 -07:00
Nicolas Gallagher
ff6109ec1c Update README and docs 2020-06-26 14:51:49 -07:00
Nicolas Gallagher
aa647567ad [change] Remove hitSlop
Rely on the native behavior of browsers to provide hitslop for touch on
interactive elements.

Fix 1609
2020-06-26 14:51:48 -07:00
Nicolas Gallagher
e9933b107a Adjust keyboard onClick shim 2020-06-26 14:51:48 -07:00
Nicolas Gallagher
4b4163f630 [add] AccessibilityInfo API update
Close #1574
2020-06-26 14:51:47 -07:00
Nicolas Gallagher
ac945761e6 [fix] Add getNativeScrollRef to FlatList
Fix #1560
Close #1563
2020-06-26 14:51:47 -07:00
Nicolas Gallagher
7ab3cf0d42 [change] Remove scrollWithoutAnimationTo from ScrollView
Remove this API which was previously deprecated.
2020-06-26 14:51:47 -07:00
Nicolas Gallagher
37ff6b4888 Reorganize usePressEvents and PressResponder 2020-06-26 14:51:46 -07:00
Nicolas Gallagher
cf7d5e9b07 [fix] forwarding of refs and props
Fixes a performance regression in prop forwarding by reintroducing prop filtering.
Fixes ref forwarding to host components, mutating the host node to add imperative APIs.
2020-06-26 14:51:45 -07:00
Nicolas Gallagher
0ffbf66b1a [change] Remove TabBarIOS and TimePickerAndroid exports
These modules have been removed from React Native
2020-06-26 14:51:45 -07:00
Nicolas Gallagher
a7da67cd09 Reorganize internal modules 2020-06-26 14:51:45 -07:00
Nicolas Gallagher
603adc46ab Alternative PanResponder API 2020-06-26 14:51:44 -07:00
Nicolas Gallagher
88f5dedffd [change] Add Pressable and replace Touchables
Port and rewrite "Pressability" from React Native as "PressResponder". This
integrates a press target with the responder system on web. It avoids
performing layout measurement during gestures by eschewing React Native's
iOS-like UX in favor of expected Web UX: a press target will look pressed until
the pointer is released, even if the pointer has moved outside the bounding
rect of the target.

The PressResponder is used to reimplement the existing Touchables. It's
expected that they will eventually be removed in favor of Pressable.

Fix #1583
Fix #1564
Fix #1534
Fix #1419
Fix #1219
Fix #1166
2020-06-26 14:51:43 -07:00
Nicolas Gallagher
7e724b279d Remove enzyme 2020-06-26 14:51:42 -07:00
Nicolas Gallagher
204c432f66 [change] Text and View onClick handling
Makes `onClick` part of the stable props API. In the future this will be used
to implement `onPress` in the Touchables/Pressables. Special handling of click
for keyboards is performed in `createElement`. At the moment, `Text` still
includes the `onPress` prop, which will only be called if `onClick` is not also
being used. In the future `Text` (in React Native) should remove the Touchable
props from its API.
2020-06-26 14:51:41 -07:00
Nicolas Gallagher
66751502a3 [change] Replace the ResponderEventPlugin
Replaces the ResponderEventPlugin with useResponderEvents hook.

Also removes the event "normalization" of mouse, touch, and click events.
These events are not part of the responder system and will no longer be
modified from what ReactDOM dispatches.

Fix #1589
Fix #1568
Fix #1571
Fix #829
Fix #693
2020-06-26 14:51:40 -07:00
Nicolas Gallagher
4146b16a68 Add PanResponder examples to docs 2020-06-05 11:53:48 -07:00
Nicolas Gallagher
fe013b30dc Add dom-event-testing-libary as a private package
This is copied from facebook/react with various fixes applied (which I'll push
upstream at a later date). Necessary for testing the Responder Event System
rewrite.
2020-06-05 11:53:47 -07:00
Nicolas Gallagher
fa6e269832 Add missing imports to docs mdx files 2020-06-02 10:57:38 -07:00
Nicolas Gallagher
ee1cb490d6 Fix optional value flow types 2020-06-02 10:57:37 -07:00
Nicolas Gallagher
f4e8b6b194 [change] modernize Image
Rewrite Image to use function components and hooks.

Fix #1322
2020-06-02 10:57:36 -07:00
Nicolas Gallagher
7e616f6d46 Fix props table for docs
Stop using the built-in Props table from Storybook (which wasn't working.)
2020-06-02 10:57:36 -07:00
Nicolas Gallagher
8952eccf86 [change] Explicitly forward props and introduce unstable_{ariaSet,dataSet}
Rather than filtering props, they are explicitly forwarded in each component.
This makes it easier to see exactly which props are being forwarded to host
components by each React Native component. Two new props - `unstable_ariaSet`
and `unstable_dataSet` - are introduced to avoid iterating over props to find
`aria` and `data` props.

The `accessibilityValue` prop is also implemented.
2020-06-02 10:57:35 -07:00
Nicolas Gallagher
654f65e3e0 [change] modernize TextInput
Rewrite TextInput to use function components and hooks.
Rewrite the unit tests to replace enzyme with testing-library.

Fix #1339
2020-06-02 10:55:51 -07:00
Nicolas Gallagher
d94a14dc8c [change] RefreshControl, StatusBar, YellowBox as function components 2020-06-02 10:55:50 -07:00
Nicolas Gallagher
8d37fde5ee [change] modernize Picker
Rewrite Picker to use function components and hooks.
Rewrite the tests to replace enzyme with testing-library.
2020-06-02 10:55:50 -07:00
Nicolas Gallagher
fdf53df301 [change] modernize CheckBox
Rewrite CheckBox to use function components and hooks.
Rewrite the tests to replace enzyme with testing-library.
2020-06-02 10:55:49 -07:00
Nicolas Gallagher
999c2ad122 [change] modernize ActivityIndicator
Rewrite ActivityIndicator to use function components and hooks.
Rewrite the tests to replace enzyme with testing-library.
2020-06-02 10:55:49 -07:00
Nicolas Gallagher
35236a3cc2 [change] modernize Text
Rewrite Text to use function components and hooks.
2020-06-02 10:55:48 -07:00
Nicolas Gallagher
2724ca0293 Add eslint-plugin-react-hooks 2020-06-02 10:55:48 -07:00
Nicolas Gallagher
fc443c5abd [change] modernize View
Rewrite View to use function components and hooks.

The 'usePlatformMethods' hook also fixes a bug in the class-based
implementation of 'setNativeProps' which was unable to correctly merge its
styles with those provided via the component API. In the future,
'setNativeProps' will be removed from React Native anyway.

See (3) in #1136 for more context.
2020-06-02 10:55:47 -07:00
Nicolas Gallagher
7d440c74f4 [change] modernize Switch
Rewrite Switch to use function components and hooks.
Rewrite the tests to replace enzyme with testing-library.
2020-06-02 10:55:47 -07:00
Nicolas Gallagher
ebc3882661 [change] modernize ScrollViewBase
Rewrite ScrollViewBase to use function components and hooks.
Rewrite the tests to replace enzyme with testing-library.
2020-06-02 10:55:46 -07:00
Nicolas Gallagher
b28d2a8214 [fix] SafeAreaView types 2020-06-02 10:55:46 -07:00
Nicolas Gallagher
94ecc46ece [change] modernize ProgressBar
Rewrite ProgressBar to use function components and hooks.
Rewrite the tests to replace enzyme with testing-library.
2020-06-02 10:55:45 -07:00
Nicolas Gallagher
5b40b9d6aa [change] modernize ImageBackground
Rewrite ImageBackground to use function components and hooks.
Rewrite the tests to replace enzyme with testing-library.
2020-06-02 10:55:45 -07:00
Nicolas Gallagher
840a2e91d4 [change] modernize Button
Rewrite Button to use function components.
Rewrite the tests to replace enzyme with testing-library.
2020-06-02 10:55:44 -07:00
Nicolas Gallagher
96d8649197 [change] modernize AppRegistry
Rewrite AppRegistry to use function components and hooks.
Rewrite the tests to replace enzyme with testing-library.
2020-06-02 10:55:44 -07:00
Nicolas Gallagher
a2cccaf528 [change] Add usePlatformMethods to implement instance methods
A hook equivalent for implementing "native methods" on refs to elements backed
by function components.
2020-06-02 10:55:43 -07:00
Nicolas Gallagher
51ac083d56 [change] Add useElementLayout hook to implement onLayout callback
A hook equivalent for implementing onLayout in function components.  Removes
the fallback to using window resize events. A ResizeObserver polyfill is now
requires to use the `onLayout` prop.
2020-06-02 10:55:43 -07:00
Nicolas Gallagher
9dbe17fa6a 0.12.3 2020-06-02 10:51:45 -07:00
Nicolas Gallagher
f4a481bb4f [fix] Allow 'lang' attribute to be forwarded to DOM nodes 2020-06-02 10:38:35 -07:00
Nicolas Gallagher
5287044f40 0.12.2 2020-02-24 14:08:31 -08:00
Vladimir Guguiev
92737d33f4 [fix] Prevent injectEventPluginsByName throwing when re-evaluating code
Close #1539
2020-02-24 13:53:23 -08:00
editkid
18427aae50 [fix] Avoid use of Object.values
Improve compatibility with older browsers (without polyfilling)

Close #1541
2020-02-24 13:30:05 -08:00
Evan Bacon
a7ab961d95 [fix] Image support for variable resolution images
Renders the asset scale which is closest to the window scale. Requires bundler integration.

Close #1456

Co-authored-by: David Calhoun <dpcalhoun@gmail.com>
2020-02-10 11:17:14 -08:00
Nicolas Gallagher
c8b73fa4e4 0.12.1 2020-02-06 13:39:50 -08:00
Nicolas Gallagher
3d53273fe7 Update internal paths to docs 2020-02-06 13:38:38 -08:00
Nicolas Gallagher
5b7f584f19 [fix] View filtering of accessibility props 2020-02-06 11:27:31 -08:00
Nicolas Gallagher
88c664fa0f Update dependencies for 'benchmarks' package 2020-01-30 17:11:13 -08:00
Nicolas Gallagher
dff62b3af6 Update jest dependencies 2020-01-30 17:01:07 -08:00
Nicolas Gallagher
032279e5f7 Update dependencies for 'docs' package 2020-01-30 16:54:01 -08:00
Nicolas Gallagher
d30d65b29d Update babel dependencies 2020-01-30 16:45:07 -08:00
Nicolas Gallagher
dee418bb93 0.12.0 2020-01-24 14:24:35 -08:00
Brandon Ros
1cc7e6cbf4 Fix bad invariant import path 2020-01-10 15:55:40 -08:00
Nicolas Gallagher
16c0109df6 Replace invariant with console.error in View
Jest dumps the invariant error to the console when unit tests run, which is
both annoying and more likely to cause unwanted error to go unnoticed. We're
also moving away from using 'invariant' in React. This patch replaces the
invariant with a call to 'console.error', which won't crash an app that is
using raw text nodes as View children, but it's better than nothing.
2019-12-21 16:58:14 +00:00
Nicolas Gallagher
287251a06a [change] Remove 'placeholderTextColor' from 'createElement' props
TextInput converts the 'placeholderTextColor' prop to a style.
2019-12-21 16:57:11 +00:00
Nicolas Gallagher
e670e8135b [fix] TextInput forwards placeholderTextColor
Fix a bug introduced by 924e891f58

Ref #1512
2019-12-20 23:30:37 +00:00
Nicolas Gallagher
e22f0bebb3 [fix] ScrollView disabling of scroll
Make sure 'scrollEnabled={false}' works on desktop browsers and no longer
relies on using 'e.preventDefault()'.

Fix #1491
2019-12-20 19:30:09 +00:00
luis filipe
f16c2c45ea [fix] ScrollView scrollEventThrottle development warning check
Close #1498
2019-12-20 19:24:41 +00:00
Nicolas Gallagher
fc033a3161 [add] TextInput disabled prop
Add support for disabling TextInput elements

Fix #1036
2019-12-20 19:18:01 +00:00
Greg Westneat
8fa9fc5cc5 Update README link for Docz
Close #1504
2019-12-19 22:35:30 +00:00
Nicolas Gallagher
e0412acb94 [add] Allow style scrollbarWidth 'thin' value
Close #1499
2019-12-19 16:59:06 +00:00
ecreeth
0b31a8b096 Refactor import and export in react-native-web entry file
Close #1509
2019-12-19 11:04:41 +00:00
Nicolas Gallagher
b10711bddd [fix] TextInput autoComplete behavior
Fix 'autoComplete' behavior now that Chrome has fixed broken behavior for 'off'.
Add fallback support for React Native's 'autoCompleteType' prop.

Close #1404
2019-12-18 22:31:45 +00:00
Chris Drackett
5334a4f0d8 [fix] TextInput remove default browser margin
Close #1458
2019-12-18 22:24:37 +00:00
Maxime Thirouin
df1b62cd45 [add] useWindowDimensions hook
Add the 'useWindowDimensions' hook from React Native

Close #1487
2019-12-18 16:53:07 +00:00
Max Thirouin
4763cc71c6 Document reasoning behind hairlineWidth value
Close #1488
2019-12-18 16:33:36 +00:00
Nicolas Gallagher
aa8593ba97 [change] Switch prop 'trackColor' support
Remove support for legacy React Native props and add support for the
'trackColor' object. Retains support for the web-only equivalents as I think
this API is preferable to the one in React Native, both in terms of flexibility
and performance (no inline objects).

Fix #1382
2019-12-18 16:22:54 +00:00
Nicolas Gallagher
3c9cc66264 Update storybook dependencies 2019-12-18 14:52:03 +00:00
Nicolas Gallagher
1ad1693039 [change] Remove PropTypes exports and internal use
Removes the following deprecated exports: `ColorPropType`,
`EdgeInsetsPropType`, `PointPropType`, `TextPropTypes`, and `ViewPropTypes`.

Remove all use of `prop-types` in the implementations of components. Flow types
are used instead, so there will no longer be runtime warnings related to props.

NOTE: Removes support for `className` prop.

Fix #1383
Close #1477
Close #1474
Close #1489
2019-12-18 12:40:31 +00:00
Nicolas Gallagher
924e891f58 Update babel-plugin-tester 2019-11-15 14:21:16 -08:00
dependabot[bot]
fced06aeaa Bump js-yaml from 3.12.0 to 3.13.1
Bumps [js-yaml](https://github.com/nodeca/js-yaml) from 3.12.0 to 3.13.1.
- [Release notes](https://github.com/nodeca/js-yaml/releases)
- [Changelog](https://github.com/nodeca/js-yaml/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nodeca/js-yaml/compare/3.12.0...3.13.1)

Close #1479

Signed-off-by: dependabot[bot] <support@github.com>
2019-11-13 16:29:19 -08:00
dependabot[bot]
21d60a3e9a Bump lodash from 4.17.11 to 4.17.15
Bumps [lodash](https://github.com/lodash/lodash) from 4.17.11 to 4.17.15.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.11...4.17.15)

Close #1478

Signed-off-by: dependabot[bot] <support@github.com>
2019-11-13 16:28:38 -08:00
dependabot[bot]
f4ff2e8891 Bump mixin-deep from 1.3.1 to 1.3.2
Bumps [mixin-deep](https://github.com/jonschlinkert/mixin-deep) from 1.3.1 to 1.3.2.
- [Release notes](https://github.com/jonschlinkert/mixin-deep/releases)
- [Commits](https://github.com/jonschlinkert/mixin-deep/compare/1.3.1...1.3.2)

Close #1468

Signed-off-by: dependabot[bot] <support@github.com>
2019-11-13 16:28:01 -08:00
Nicolas Gallagher
f43ce41f0d Update README 2019-11-13 11:30:31 -08:00
Nicolas Gallagher
afb8d3b7fb [change] Configure hydration using AppRegistry.runApplication()
Client-side hydration of server-rendered HTML now requires that `hydrate` is explicitly set in the `appParams` passed to `AppRegistry.runApplication()`.

Fix #1374
2019-11-12 16:54:51 -08:00
Nicolas Gallagher
e4ed0fd3c8 [fix] ScrollResponder componentWillMount -> UNSAFE_componentWillMount 2019-11-12 15:36:10 -08:00
Nicolas Gallagher
297cda7901 Rewrite interactive documentation
Consolidate all docs within the latest storybook

Ref #1172
2019-11-12 15:19:48 -08:00
Nicolas Gallagher
8cf00a5c5a Update inline-style-prefixer and misc deps 2019-11-12 14:42:58 -08:00
Nicolas Gallagher
3fd90b9252 Update flow to 0.109
Add $FlowFixMe to vendor code that produces flow errors
2019-11-12 14:42:57 -08:00
Nicolas Gallagher
9e7c37128e Update 'benchmarks' dependencies 2019-11-12 14:42:54 -08:00
Nicolas Gallagher
41e6dca1e3 Update linter and formatter tools 2019-10-08 13:06:20 -07:00
Nicolas Gallagher
02a3640f95 Update test tools 2019-10-08 13:06:17 -07:00
Nicolas Gallagher
290a2a76ce Update babel build tools 2019-10-08 13:04:10 -07:00
Nicolas Gallagher
1b3c31ff6a Run prettier across codebase
Close #1444
2019-10-07 14:26:24 -07:00
Nicolas Gallagher
d4b9f35d33 [change] createElement -> unstable_createElement
Rename the 'createElement' export to reflect its unstable status.

Fix #1385
2019-10-07 14:20:49 -07:00
Nicolas Gallagher
3ac0b96498 [change] Update Touchable components
Reference RN 0.60 implementations with web-specific fixes

Ref #1172
Fix #1105
2019-10-07 14:01:05 -07:00
Nicolas Gallagher
33f1c3566c [add] forwardedRef prop to View and Text
Ref #1172
2019-10-04 11:37:26 -07:00
Nicolas Gallagher
d57fb6eb01 [change] accessibilityRelationship and accessibilityState props
Adds the accessibilityState and accessibilityRelationship object props that map
to ARIA props.

Removes the accessibilityStates array prop that is not compatible with web
accessibility services.

Ref #1172
2019-10-04 11:37:26 -07:00
Nicolas Gallagher
ae94551ac5 [change] Remove accessibilityTraits and accessibilityComponentType props
These props are deprecated in React Native and replaced by accessibilityRole

Ref #1352
2019-10-04 11:37:25 -07:00
Nicolas Gallagher
1af0218d26 Remove unused 'shadowSpread' prop type
Close #1357
2019-10-04 11:37:25 -07:00
Nicolas Gallagher
d554d83727 [change] Text uses createContext
Replaces the legacy 'contextTypes' API.
Removes 'enzyme' from related tests. Back to recording DOM snapshots.

Close #1248
Ref #1172
2019-10-04 11:37:25 -07:00
Nicolas Gallagher
25dd43e960 [change] Update vendor code
* FlatList
* SectionList
* VirtualizedList
* VirtualizedSectionList
2019-10-04 11:37:22 -07:00
Nicolas Gallagher
c4a2a6d4a3 Update to flow-bin@0.98 2019-10-04 11:07:09 -07:00
Nicolas Gallagher
ad674e4b4f [add] Platform.isTesting 2019-10-04 11:07:09 -07:00
Nicolas Gallagher
304e8a83ab [change] Update Animated
react-native@v0.60.0-rc.3

Fix #1378
Fix #1325
Close #1306
2019-10-04 11:07:09 -07:00
Nicolas Gallagher
ac71506610 [change] Remove WebView
Ref #1352
Ref https://github.com/facebook/react-native/issues/23313
2019-10-04 11:07:09 -07:00
Nicolas Gallagher
847870e4b3 [change] Remove ViewPagerAndroid
Ref #1352
Ref https://github.com/facebook/react-native/issues/23313
2019-10-04 11:07:09 -07:00
Nicolas Gallagher
845c2726b2 [change] Remove VibrationIOS
Ref #1352
Ref https://github.com/facebook/react-native/issues/23313
2019-10-04 11:07:09 -07:00
Nicolas Gallagher
9d76d58891 [change] Remove ToolbarAndroid
Ref #1352
Ref https://github.com/facebook/react-native/issues/23313
2019-10-04 11:07:09 -07:00
Nicolas Gallagher
f54c957199 [change] Remove SwipeableListView
Ref #1352
Ref https://github.com/facebook/react-native/issues/23313
2019-10-04 11:07:09 -07:00
Nicolas Gallagher
425102c16e [change] Remove StatusBarIOS
Ref #1352
Ref https://github.com/facebook/react-native/issues/23313
2019-10-04 11:07:08 -07:00
Nicolas Gallagher
0c350d2678 [change] Remove SnapshotViewIOS
Ref #1352
Ref https://github.com/facebook/react-native/issues/23313
2019-10-04 11:07:08 -07:00
Nicolas Gallagher
eaa24ae91d [change] Remove Slider
Ref #1352
Ref https://github.com/facebook/react-native/issues/23313
2019-10-04 11:07:08 -07:00
Nicolas Gallagher
24801cb5da [change] Remove SegmentedControlIOS
Ref #1352
Ref https://github.com/facebook/react-native/issues/23313
2019-10-04 11:07:08 -07:00
Nicolas Gallagher
41e4f05eb0 [change] Remove PushNotificationIOS
Ref #1352
Ref https://github.com/facebook/react-native/issues/23313
2019-10-04 11:07:08 -07:00
Nicolas Gallagher
72ede16c9c [change] Remove ProgressBarAndroid and ProgressViewIOS
Ref #1352
Ref https://github.com/facebook/react-native/issues/23313
2019-10-04 11:07:08 -07:00
Nicolas Gallagher
7ec9b075a1 [change] Remove PickerIOS
Ref #1352
Ref https://github.com/facebook/react-native/issues/23313
2019-10-04 11:07:08 -07:00
Nicolas Gallagher
89bc074327 [change] Remove NetInfo
Ref #1352
Ref https://github.com/facebook/react-native/issues/23313
2019-10-04 11:07:08 -07:00
Nicolas Gallagher
add0e0cb7e [change] Remove NavigatorIOS
Ref #1352
Ref https://github.com/facebook/react-native/issues/23313
2019-10-04 11:07:08 -07:00
Nicolas Gallagher
8900cea576 [change] Remove MaskedViewIOS
Ref #1352
Ref https://github.com/facebook/react-native/issues/23313
2019-10-04 11:07:08 -07:00
Nicolas Gallagher
6c682bbb92 [change] Remove ListView
Ref #1352
Ref https://github.com/facebook/react-native/issues/23313
2019-10-04 11:07:08 -07:00
Nicolas Gallagher
ece4e95d4d [change] Remove ImageStore
Ref #1352
Ref https://github.com/facebook/react-native/issues/23313
2019-10-04 11:07:08 -07:00
Nicolas Gallagher
f9eadc10d2 [change] Remove ImagePickerIOS
Ref #1352
Ref https://github.com/facebook/react-native/issues/23313
2019-10-04 11:07:08 -07:00
Nicolas Gallagher
cc5a5d7d27 [change] Remove ImageEditor
Ref #1352
Ref https://github.com/facebook/react-native/issues/23313
2019-10-04 11:07:08 -07:00
Nicolas Gallagher
800f24466e [change] Remove DatePickerAndroid and DatePickerIOS
Ref #1352
Ref https://github.com/facebook/react-native/issues/23313
2019-10-04 11:07:08 -07:00
Nicolas Gallagher
5a12430b50 [change] Remove CameraRoll
Ref #1352
Ref https://github.com/facebook/react-native/issues/23313
2019-10-04 11:07:08 -07:00
Nicolas Gallagher
fbdbfa5484 [change] Remove AsyncStorage
Ref #1352
Ref https://github.com/react-native-community/async-storage/issues/52
Ref https://github.com/facebook/react-native/issues/23313
2019-10-04 11:07:08 -07:00
Nicolas Gallagher
920211b998 [change] Remove AlertIOS
Ref #1352
Ref https://github.com/facebook/react-native/issues/23313
2019-10-04 11:07:08 -07:00
Nicolas Gallagher
c0c7a18aca [change] Remove ActionSheetIOS
Ref #1352
Ref https://github.com/facebook/react-native/issues/23313
2019-10-04 11:07:08 -07:00
Marnus Weststrate
250ee3c234 [fix] Only inject ResponderEventPlugin client-side
Close #1434
Fix #1433
2019-09-30 10:49:41 -07:00
John Rees
6ce88e6db0 Fix docs link to create-react-app
Close #1440
2019-09-30 10:49:24 -07:00
Nicolas Gallagher
e810f1fd2b 0.11.7 2019-08-16 13:15:07 -07:00
Quentin Woivré
d2e8d616e2 [fix] Support for native scroll-width style
Close #1418
2019-08-16 13:09:30 -07:00
Nicolas Gallagher
1cce9a1668 0.11.6 2019-08-09 11:51:16 -07:00
Giuseppe Gurgone
96a23c1c21 [fix] StyleSheet hydration with single quotes in attribute selectors
Edge uses single quotes for attribute selectors.

Fix #1317
Close #1415
2019-08-09 11:23:50 -07:00
Charlie Croom
ebbade3a6f [fix] TextInput support for 'returnKeyType'
Close #1413

Co-authored-by: Nicolas Gallagher <nicolasgallagher@gmail.com>
2019-08-09 11:21:17 -07:00
Pawel Borkowski
ef770d4bd1 [fix] Add support for browsers that implement scrollbar-width
Close #1395
2019-08-09 11:08:55 -07:00
Bruno Lemos
a7ddd7b9ac [fix] SafeAreaView ref supports setNativeProps
https://github.com/facebook/react-native/pull/24589

Close #1407
2019-08-09 11:01:08 -07:00
Evan Bacon
8f5e7d4e14 [fix] Export DeviceEventEmitter
Close #1402
2019-08-09 10:58:30 -07:00
Nicolas Gallagher
45f94eb43d 0.11.5 2019-07-02 14:06:34 -07:00
Nicolas Gallagher
5092be40ac Fix RNTester Image examples
The 'resizeMode' static no longer exists.

Fix #1360
Close #1387
2019-07-02 13:23:44 -07:00
Evan Bacon
b144992f51 [fix] Add enum types to interaction prop types
Close #1358
2019-07-02 13:23:44 -07:00
Nicolas Gallagher
9d5a41c702 [fix] Don't stringify application params
Close #1365
2019-07-02 13:17:53 -07:00
Evan Bacon
11d00ff111 [add] SafeAreaView support for iOS 11 CSS constant
Close #1359
2019-07-02 13:09:59 -07:00
Ross Williams
8908db7690 [fix] InteractionManager runAfterInteractions resolve
Close #1355
InteractionManager runAfterInteractions does not resolve its promise unless the function is provided with a callback. Using promises, the user of the library should not need to provide a callback. This update adds an else case when there is no callback to call the Promise's resolve function without arguments.
2019-07-02 12:56:17 -07:00
Giuseppe Gurgone
29146fe5bc [fix] StyleSheet group sorting
Close #1356
2019-07-02 12:54:42 -07:00
Nicolas Gallagher
33dc3cb018 0.11.4 2019-05-21 14:17:21 -07:00
Nicolas Gallagher
4f5de8d016 [fix] typo in ScrollView prevents hiding scrollbars 2019-05-21 14:14:23 -07:00
Nicolas Gallagher
cddc2e346b 0.11.3 2019-05-21 12:21:08 -07:00
Evan Bacon
fa09df8b59 [fix] ScrollView support for hiding scroll indicators
Implements 'showsHorizontalScrollIndicator' and 'showVerticalScrollIndicator' by polyfilling the 'scrollbar-width' property from the draft CSS spec for scrollbars. Scrollbars can only be shown for both or neither axis.

Close #1307

Co-authored-by: Nicolas Gallagher <nicolasgallagher@gmail.com>
2019-05-21 11:02:38 -07:00
Nicolas Gallagher
be5106f5d3 [fix] textDecoration{Color,Line,Style} styles
Attempting to fallback to CSS2 text-decoration is not reliable for inline
styles. This patch assumes CSS3 text-decoration support when server-rendering,
and uses CSS.supports to check for runtime support. When CSS3 support is
available the long-form properties are preserved.

Fix #1312
2019-05-15 17:33:53 -07:00
Charlie Croom
37ca236d09 [fix] Image displays defaultSource until source load completes
This fixes an issue that would cause the defaultSource to be removed as soon as
the source beings to load. The original intent was to support progressive
JPEGs. However, in cases where a defaultSource has been provided, we should
respect the intent to display it until the primary source is ready to
immediately replace the defaultSource.

Close #1345
2019-05-15 16:17:00 -07:00
Charlie Croom
950bfd039c [add] Image.queryCache API
Image.queryCache is a React Native method that allows the user to see
if a given uri is in the cache. It specifies three return options:
disk, memory or both. Choosing both seemed most appropriate since
we don't really know and can't confirm.

The way Image is implemented, if RNW thinks the image might already
be loaded, it displays it immediately. Otherwise there can be a flash
of a frame. In some scenarios, if the user chooses to preload and then
make an Image element, it would still flash. By adding it to the cache,
we can prevent that.

Close #1344
2019-05-15 15:41:05 -07:00
Nicolas Gallagher
39d2e18ccf [fix] Text accessibilityRole propTypes warning
Close #1320
2019-05-15 11:23:24 -07:00
Nicolas Gallagher
e9f68e380b [fix] Avoid using Object.values
Not everyone is polyfilling older environments

Fix #1334
2019-05-15 11:22:02 -07:00
Doug Miller
2ce434e8f8 [fix] Babel plugin rewrite for main index require
Recently the default export was removed from react-native-web. In some
scenarios it is possible to still get to this import path which does not work
anymore. Removing the `.default` fixes commonjs imports from index.

Close #1341
2019-05-15 11:05:35 -07:00
Janic Duplessis
3eeda686b1 [fix] Prevent maxFontSizeMultiplier prop forwarding to DOM
Close #1313
2019-05-15 10:59:36 -07:00
MoOx
70e3ea8b57 Add documentation for Node.js module aliasing
Close #1315
2019-05-15 10:57:51 -07:00
ashbhir
cc99391f9d [fix] Text default border style
Close #1335
2019-05-15 10:45:05 -07:00
Yukiya Nakagawa
27713bd8cc Fix docs typo
Close #1297
2019-05-15 10:44:31 -07:00
Nicolas Gallagher
801937748b 0.11.2 2019-03-22 10:02:44 -07:00
Nicolas Gallagher
9cbe387d9f [fix] CSS insertion in Edge browser
Edge browser throws `HierarchyRequestError` while inserting CSS rules into CSS
Media Queries. Therefore, a different mechanism is required to control CSS
order. This patch tracks the starting index of each group of CSS rules in the
DOM style sheet.

Fix #1300
Close #1302
2019-03-22 09:58:18 -07:00
Nicolas Gallagher
c1459d7b21 Remove '!important' check from setValueForStyles
'!important' styles are no longer used internally and are not supported in the
public API.
2019-03-19 10:32:59 -07:00
Mathieu Acthernoene
36dacb2052 [change] Update flow-bin to 0.95.1
Fix related type errors

Close #1269

Co-authored-by: Nicolas Gallagher <nicolasgallagher@gmail.com>
2019-03-18 13:00:05 -07:00
Nicolas Gallagher
b732cec83e Fix copyright headers 2019-03-18 11:13:17 -07:00
Nicolas Gallagher
ad78fc7a38 0.11.1 2019-03-15 14:08:24 -07:00
Nicolas Gallagher
33e54c755b [fix] StyleSheet SSR of classic CSS
Hack something together to get classic CSS going through the same pathway as
the rest of the styles. This gets classic CSS showing up in the SSR CSS output.

Fix #1286
2019-03-15 10:20:56 -07:00
Paul Armstrong
74a36a2a4e [fix] Jest preset module export
Export the preset as a module so that paths can be resolved relative to a Jest
config file.

Close #1290
2019-03-15 10:07:56 -07:00
Nicolas Gallagher
8d1f5afead Fix website Image examples
Remove use of 'resizeMode' static, which is no longer supported.
2019-03-14 14:20:25 -07:00
Nicolas Gallagher
763e2d4001 0.11.0 2019-03-12 17:45:10 -07:00
Nicolas Gallagher
f507410ab4 [fix] Schema prop types
Ref 34427897f3
2019-03-12 17:43:22 -07:00
Nicolas Gallagher
97372d7e4c Update benchmark results for 0.11.0 2019-03-12 17:30:10 -07:00
Nicolas Gallagher
9872c97169 Remove whitespace from CSS rules
Minimizes bytes from CSS code that might be inlined in the head of the document
during SSR.
2019-03-12 13:53:48 -07:00
Nicolas Gallagher
d50f6304dc [change] Add className prop deprecation warning
View and Text will not support the 'className' prop in a future release.

Fix #1146
2019-03-12 13:00:57 -07:00
Nicolas Gallagher
330895534d [change] CSS class prefix 'rn' -> 'r' 2019-03-12 13:00:57 -07:00
Nicolas Gallagher
0e302a50d2 [change] Refactor style resolver
Minor refactor of the style resolver to convert it to a factory function.
2019-03-12 13:00:57 -07:00
Nicolas Gallagher
f048d848a1 [change] Replace outline with outline{Color,Style,Width} styles
Rather than mix shortform and longform properties, the 'outline' property is
removed in favour of the longform properties. Support for `outlineOffset` is
also included.

Fix #1255
Close #1256
2019-03-12 13:00:57 -07:00
Nicolas Gallagher
c68b532696 [change] StyleSheet validation
Stop relying on React internals and propTypes validation.
2019-03-12 13:00:57 -07:00
Nicolas Gallagher
d4417e93a3 [change] Use classic CSS in View, Text, etc., implementations
The CSS base styles for certain primitives are implemented using classic CSS to
reduce browser layout times and better support 'null' values in
StyleSheet-defined styles. Combined with the previous patch this reduces the
benchmark layout times by about 30%.

Ref #1136
Fix #1044
Fix #1223
Fix #13
2019-03-12 13:00:57 -07:00
Nicolas Gallagher
9f860b8dfc [change] StyleSheet: compile styles directly to CSS
Introduces a centralized compiler for "atomic" and "classic" CSS output. The
"classic" compiler is for internal use only and offers no CSS safety
guarantees. The "atomic compiler is used to implement the public-facing
StyleSheet API.

The atomic compiler now maps the React style declarations, rather than CSS
style declarations, to CSS rules. This avoids having to convert React styles to
CSS styles before being able to lookup classNames. And it reduces the number of
CSS rules needed by each DOM element.

Before:

    { paddingHorizontal: 0; }
        ↓
    .paddingLeft-0 { padding-left: 0; }
    .paddingRight-0 { padding-right: 0; }

After:

    { paddingHorizontal: 0; }
        ↓
    .paddingHorizontal-0 { padding-left: 0; padding-right: 0 }

Overview of previous StyleSheet resolver:

1. Localise styles
2. Transform to CSS styles
3. Expand short-form properties
4a. Lookup Atomic CSS for each declaration
4b. Compile Atomic CSS for each static declaration
  i. Vendor prefix
  ii. Insert CSS rules
4c. Create inline style for each dynamic-only declaration
  i. Vendor prefix

Overview of new StyleSheet design:

1. Localise styles
2a. Lookup Atomic CSS for each declaration
2b. Compile Atomic CSS for each static declarations
  i. Transform to CSS styles
  ii. Expand short-form properties
  iii. Vendor prefix
  iiii. Insert CSS rules
2c. Create inline style for each dynamic-only declaration
  i. Transform to CSS styles
  ii. Expand short-form properties
  iii. Vendor prefix

Ref #1136
2019-03-12 13:00:57 -07:00
Nicolas Gallagher
29be779f77 [change] CSS insertion by OrderedCSSStyleSheet
`OrderedCSSStyleSheet` can be used to control the order in which CSS rules are
inserted. This feature is necessary to support the combined use of Classic CSS
and Atomic CSS. It also makes it possible to control the order of Atomic CSS
rules, which is necessary to correctly resolve style conflicts (e.g., between
'margin' and 'marginHorizontal') without expanding short-form properties to
long-form properties.

Ref #1136
2019-03-12 13:00:57 -07:00
Evan Bacon
2a418bed0c [change] Organize unimplemented modules in directories
Creates a {path}/index.js for each module that has no web
implementation. This enables the babel preset to rewrite all paths and
prevent apps from bundling unused modules.

Fix #1281
Close #1282
2019-03-11 21:13:16 -07:00
Nicolas Gallagher
5e9449e893 Update benchmark libraries 2019-03-11 20:17:29 -07:00
Alec Winograd
67979b7282 [add] TextInput support for "onContentSizeChange"
Fix #793
Close #1226
2019-03-11 14:14:13 -07:00
Nicolas Gallagher
3d3ea9aeed [change] Remove ART export
Anticipate the removal of ART from React Native core:
https://github.com/facebook/react-native/issues/23313

Simplifies dependencies and builds for web apps.

Close #1251
2019-03-11 13:33:49 -07:00
Nicolas Gallagher
69bd0f631d [change] Remove default ES Module export
Remove the default export that was provided for compatibility with legacy
imports of React Native CommonJS modules. These patterns are no longer
supported:

```
import ReactNative from 'react-native';
const ReactNative = require('react-native');
```

Fix #1258
Close #1277
2019-03-11 13:12:24 -07:00
Evan Bacon
9ce2b5bf0c [fix] NativeEventEmitter implementation
Close #1275
2019-03-08 13:06:19 -08:00
Hiroki Sato
cf7b020c5d [fix] set textShadow if only blur and color provided
Mirrors a recent fix to React Native.

Close #1182
2019-03-08 12:42:36 -08:00
Nicolas Gallagher
49edcb291e [change] remove 'resizeMode' static from 'Image'
Use strings instead of the 'Image.resizeMode' static. Corresponding change in React Native:

https://github.com/facebook/react-native/commit/870775e
2019-03-08 12:40:59 -08:00
Nicolas Gallagher
6a84d74185 0.10.1 2019-03-07 11:32:33 -08:00
Nicolas Gallagher
282cb34054 Fix npm publish errors 2019-03-07 11:31:50 -08:00
Wyatt Greenway
421cb095f7 [fix] PickerItem cyclic dependency
Close #1270
2019-03-07 11:06:48 -08:00
Nicolas Gallagher
0c08ba3a7d [fix] Text support for accessibilityRole="none"
Fix #1262
2019-03-07 11:02:57 -08:00
Nicolas Gallagher
e4c3a21c42 [fix] TextInput autoComplete="off"
Browsers treat autoComplete "off" as "on". The fix is to provide the browser
with an unrecognized value so that it doesn't attempt to auto-fill the input.

Fix #1249
2019-03-07 10:58:27 -08:00
Nicolas Gallagher
34427897f3 [add] Support for Schema prop types
View and Text forward Schema prop types to host DOM node.
https://schema.org/docs/gs.html

Fix #1247
2019-03-07 10:50:34 -08:00
Dan Alloway
63868b492d Fix project scripts in Windows environments
Close #1252
2019-03-01 14:49:55 -08:00
Nicolas Gallagher
8ce5750d34 0.10.0 2019-01-30 14:13:58 -08:00
Nicolas Gallagher
eb77062608 Remove unnecessary snapshot tests
Remove snapshots that were unnecessarily recording generated CSS output.
2019-01-22 18:48:29 -08:00
Nicolas Gallagher
b6fc6f228e Add new Text render benchmark 2019-01-22 18:48:29 -08:00
Nicolas Gallagher
6c725357ff Add a note about referrer tracking 2019-01-22 18:48:29 -08:00
atp
dce5b7321d [add] Text support for wordBreak style
Close #1200
2019-01-22 18:48:29 -08:00
Nicolas Gallagher
52ca784680 Use default array sort function 2019-01-22 18:48:29 -08:00
Nicolas Gallagher
244b0e4425 Don't print AppRegistry message in unit tests 2019-01-22 18:48:29 -08:00
Nicolas Gallagher
21c3931b69 [fix] use getBoundingClientRect to measure layout
Fix #1037
Fix #1151
2019-01-22 18:48:29 -08:00
Nicolas Gallagher
e696e637bd [add] support backdropFilter style
Close #1070
2019-01-22 18:48:29 -08:00
Nicolas Gallagher
b62a7bf44d Update webpack for examples 2019-01-22 18:48:29 -08:00
Nicolas Gallagher
69d1da4560 Update eslint 2019-01-22 18:48:29 -08:00
Nicolas Gallagher
8925bf76af [change] implement TextInput without e.which
e.which is considered deprecated and should be replaced with e.key.

Fix #1190
Close #1193
2019-01-22 18:48:28 -08:00
Nicolas Gallagher
77d4bd8a97 [change] Compile using Babel 7
Fix #1170
Close #1205
Close #1191
2019-01-22 18:48:28 -08:00
Nicolas Gallagher
4040151ee6 [add] support for accessibilityRole and accessibilityStates
React Native 0.57 introduced 'accessibilityRole' and
'accessibilityStates' as cross-platform accessibility APIs to replace
'accessibilityComponentType' and 'accessibilityTraits' for Android and
iOS.

React Native for Web has supported the 'accessibilityRole' for a while.
This patch maps some of the values defined in React Native to web
equivalents, and continues to allow a larger selection of roles for web
apps. It also adds support for 'accessibilityStates', mapping values to
ARIA states with boolean values and expanding support beyond 'disabled'
and 'selected'.

Fix #1112
Close #1113
2019-01-22 18:48:25 -08:00
Nicolas Gallagher
000b92e707 0.9.13 2018-12-31 17:31:46 -08:00
Nicolas Gallagher
d5f5dbccdb [fix] inline-style-prefixer API update
Fix #1217
2018-12-31 17:22:05 -08:00
Nicolas Gallagher
79456d5920 0.9.12 2018-12-31 10:34:04 -08:00
Nicolas Gallagher
2d1e303a6a [fix] ScrollView with stickyHeaderIndices regression
A ScrollView with stickyHeaderIndices would not render children that
weren't sticky.

Fixes 1e202b6bd5
2018-12-31 10:26:33 -08:00
Nicolas Gallagher
209ff1fa40 0.9.11 2018-12-31 08:23:58 -08:00
Nicolas Gallagher
34d8160a43 [fix] CSS animation insertion for Android 5.1 HuaWei browser
Inserting unprefixed CSS keyframes rules causes a `SYNTAX_ERR: DOM Exception
12` error in Android 5.1. A similar issue with inserting rules containing
vendor-prefixed pseudo-selectors was patched by wrapping rule in `@media all
{}` blocks. This patch removes the media query wrapper from keyframe animations
(as it doesn't prevent the error) and relies on `CSSStyleSheet::insertRule`
being called within a try-catch block.

Fix #1199
Close #1210
2018-12-31 07:47:52 -08:00
Nicolas Gallagher
ada5651be2 Don't minify local benchmarks build 2018-12-24 13:35:21 +00:00
Nicolas Gallagher
9fe9d3c68a Update react-native-web dependencies 2018-12-24 13:03:49 +00:00
krister
1e202b6bd5 [add] ScrollView support for pagingEnabled
Available in browsers that support CSS snappoints.

Fix #1057
Close #1212

Co-authored-by: Nicolas Gallagher <nicolasgallagher@gmail.com>
2018-12-23 18:05:29 +00:00
Robert Sayre
2b77bfd853 [fix] improve style resolver performance
Script time in the benchmark was profiled by adding `console.profile` around
the timings for script time. The call to Array.join in the resolve function
stood out. Since the code already iterates over the array it can run slightly
faster by building the cache key in that loop instead.

Close #1213
2018-12-23 15:07:48 +00:00
Nicolas Gallagher
d0ac55aa4f Update benchmarks dependencies 2018-12-21 21:33:43 +00:00
Nicolas Gallagher
66dd1bd9ef Remove glamor and radium from benchmarks
Glamor is unmaintained. Radium is extremely slow. There is no need to compare
against these libraries.
2018-12-21 21:20:30 +00:00
Nicolas Gallagher
6add18c6f0 0.9.10 2018-12-21 21:04:26 +00:00
krister
30d7c31b65 [fix] ScrollView smooth scrolling
Rely on the `element.scroll()` programmatic API when available (or polyfilled).

Fix #1203
Fix #1173
Close #1208
2018-12-21 20:57:25 +00:00
Raibima Putra
f7e6b43422 Fix docs typo
Close #1209
2018-12-21 20:46:29 +00:00
Nicolas Gallagher
4b3f6efb21 Support style inspection in production 2018-12-10 17:01:23 -08:00
Nicolas Gallagher
85e098deec 0.9.9 2018-12-05 14:46:11 -08:00
Nicolas Gallagher
c949b0145a [fix] TextInput onKeyPress supports Escape key
Fix #1189
2018-11-27 12:15:59 -08:00
Charlie Croom
86b4cf5a51 [add] scaleZ and scale3d style transforms
Web-specific additions similar to the web-specific additions to `translate` styles.

Close #1184
2018-11-27 11:53:04 -08:00
Giuseppe
1b7ce4eec6 [fix] Fix regression in modality refactor
Fixes https://github.com/necolas/react-native-web/pull/1169#issuecomment-440590544

And removes the focus ring for press-after-keyboard edge cases.

Close #1186

Co-authored-by: Nicolas Gallagher <nicolasgallagher@gmail.com>
2018-11-27 11:52:46 -08:00
Nicolas Gallagher
8c8978ff76 0.9.8 2018-11-15 21:40:18 -08:00
Nicolas Gallagher
513b5de881 Partially revert d841db2337
The modification to VirtualizedList is not required now that ScrollView wraps
sticky header items in a View.
2018-11-15 10:26:49 -08:00
Julian Hundeloh
145f80409d [fix] ScrollView dependency on 'style' forwarding for sticky headers
Not every item that may be rendered by a ScrollView will forward 'style', so cloning the item element is not safe. Instead, we can wrap the item in a 'View' and apply the styles for the sticky header to this element.

Close #1175
2018-11-15 10:24:54 -08:00
Julian Hundeloh
6d92cc5ec3 [fix] ListView section error when missing renderHeader
Close #1174
2018-11-15 10:11:54 -08:00
Nicolas Gallagher
ec6458c09d Update some links in README 2018-11-15 10:09:14 -08:00
James Munro
a84c2ac95e Add DataCamp to companies using react-native-web in production
Close #1176
2018-11-15 10:07:26 -08:00
Nicolas Gallagher
75db0e9183 0.9.7 2018-11-12 17:53:16 -08:00
Giuseppe Gurgone
4b9a5fd8b4 [fix] modality performance
Inserting and deleting the CSS ':focus' rule triggers styles recalculation for the
entire DOM tree which results in performance degradation on focus and makes the
keyboard very slow to open in Safari iOS.

This commit fixes the issue by picking up the upstream changes to the W3C
focus-visible polyfill. A class name is applied to elements when they receive
focus via keyboard. The related CSS rule is inserted only once into the style
sheet. This performs much better since the browser needs to recalculate styles
only for the focused element and its small subtree.

Fix #1155
Close #1169
2018-11-12 15:54:07 -08:00
Nicolas Gallagher
b6be677db9 [fix] ref.focus() should focus any element type
Ensure that programmatic focus can be moved to any element. Each
instance of a primitive component type (e.g., `View`, `Text`, etc.)
includes a `focus` method. However, on the web only certain elements can
receive programmatic focus by default: those that can also receive
keyboard focus, e.g., `a`, `button`, `input`, etc. All other element
types must set `tabIndex="-1"` in order to be programmatically focusable
without also being focusable via keyboard or mouse.

Fix #1099
2018-11-10 12:03:44 -08:00
Nicolas Gallagher
91c9457392 Remove reference to create-react-native-app
Close #1167
2018-11-10 11:23:04 -08:00
Nicolas Gallagher
006d315a1a Add example Next.js recipes 2018-11-10 11:07:54 -08:00
Nicolas Gallagher
220eb79357 Fix UIExplorer headings accessibility 2018-11-10 11:05:49 -08:00
Murtaza Raja
5db9a765b0 Fix README install command typo
Close #1163
2018-11-04 18:39:23 -08:00
Nicolas Gallagher
931d666fcc 0.9.6 2018-11-01 12:29:18 -07:00
hushicai
40c433c6df [fix] only call 'getBoundingClientRect' if nativeEvent.location{X,Y} is accessed
Calculating the `location{X,Y}` values for events requires a call to
`getBoundingClientRect`. To prevent unnecessary performance costs, these values
are implemented as getters and will only make the DOM API call when accessed in
application code.

Close #1157
2018-11-01 09:06:10 -07:00
hushicai
9888c2a3c6 [fix] scrolling of nested ScrollViews
Use of 'pan-x' and 'pan-y' on ScrollView prevents the browser handling
scrolling of a parent ScrollView that is scrollable along the other axis.

Fix #1160
Close #1161
2018-11-01 09:01:29 -07:00
Nicolas Gallagher
3fa18becc7 0.9.5 2018-10-29 18:04:02 -07:00
Nicolas Gallagher
aafeb0adad [fix] RTL support for 'transitionProperty' style
The 'transitionProperty' value can be any property and this patch processes
those values in the same way as properties.

Fix #1131
2018-10-29 13:20:09 -07:00
Nicolas Gallagher
89468b7d6e 0.9.4 2018-10-22 20:06:58 -07:00
Nicolas Gallagher
f66af5e04d Update Gatsby plugin link 2018-10-22 20:03:49 -07:00
Mo Kouli
2363524fa7 [fix] process.env.NODE -> process.env.NODE_ENV
Close #1145
2018-10-22 19:14:04 -07:00
Charlie Croom
5855e55615 [fix] cache Clipboard.isAvailable() value
Fix #1149
Close #1150
2018-10-22 19:10:56 -07:00
Charlie Croom
5033e12d18 Add nativeID to View supported props filter
Close #1147
2018-10-22 18:18:53 -07:00
Nicolas Gallagher
d6e8530f4d 0.9.3 2018-10-11 17:40:41 -07:00
Charlie Croom
ad188a7ad6 [fix] Memory leak in applyLayout registry
Remove component instances from the layout registry when umounting views
that are using ResizeObserver.

Fix #1133
Close #1134
2018-10-11 17:35:04 -07:00
Nicolas Gallagher
bfaeae904e [add] View/Text prop nativeID
Maps the View and Text prop 'nativeID' to DOM 'id' as these are
equivalent.  Enables declarative use of various 'aria-*' properties that
require ID references.

Ref #1116
Close #1130
2018-10-11 17:33:08 -07:00
912 changed files with 41062 additions and 53098 deletions

View File

@@ -1,5 +0,0 @@
{
"presets": [
"./scripts/babel/preset"
]
}

View File

@@ -1,4 +1,11 @@
{
"settings": {
"react": {
"pragma": "React",
"version": "16.6",
"flowVersion": "0.109.0" // Flow version
}
},
// babel parser to support ES6/7 features
"parser": "babel-eslint",
"parserOptions": {
@@ -10,31 +17,24 @@
"sourceType": "module"
},
"extends": [
"plugin:flowtype/recommended",
"prettier",
"prettier/react"
],
"plugins": [
"flowtype",
"promise",
"react"
"react",
"react-hooks"
],
"env": {
"browser": true,
"es6": true,
"jest": true,
"node": true
},
"globals": {
"document": false,
"navigator": false,
"window": false,
// Flow global types,
"$Enum": false,
"HTMLInputElement": false,
"ReactClass": false,
"ReactComponent": false,
"ReactElement": false,
"ReactPropsChainableTypeChecker": false,
"ReactPropsCheckType": false,
"ReactPropTypes": false,
"SyntheticEvent": false
},
"rules": {
"camelcase": 0,
@@ -57,7 +57,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,
@@ -125,12 +124,16 @@
"valid-typeof": 2,
"yoda": [2, "never"],
// flow
"flowtype/generic-spacing": 0,
"flowtype/space-after-type-colon": 0,
// promise
"promise/param-names": 2,
// react
"react/display-name": 0,
"react/jsx-no-bind": 2,
"react/jsx-no-bind": 0,
"react/jsx-no-duplicate-props": 2,
"react/jsx-no-undef": 2,
"react/jsx-pascal-case": 2,
@@ -144,11 +147,15 @@
"react/no-string-refs": 2,
"react/no-unknown-property": 2,
"react/prefer-es6-class": 2,
"react/prop-types": 2,
"react/prop-types": 0,
"react/react-in-jsx-scope": 0,
"react/self-closing-comp": 2,
"react/sort-comp": 0,
"react/sort-prop-types": 2,
"react/wrap-multilines": 0
"react/wrap-multilines": 0,
// react-hooks
"react-hooks/rules-of-hooks": "error",
"react-hooks/exhaustive-deps": "warn"
}
}

View File

@@ -1,11 +1,10 @@
[version]
^0.63.0
^0.109.0
[ignore]
<PROJECT_ROOT>/.*/__tests__/.*
<PROJECT_ROOT>/packages/.*/dist/.*
<PROJECT_ROOT>/packages/examples/.*
<PROJECT_ROOT>/packages/website/.*
<PROJECT_ROOT>/packages/docs/.*
.*/node_modules/babel-plugin-transform-react-remove-prop-types/*
[include]
@@ -15,3 +14,7 @@
[options]
suppress_type=$FlowIssue
suppress_type=$FlowFixMe
suppress_type=$FlowFixMeProps
suppress_type=$FlowFixMeState

View File

@@ -70,15 +70,16 @@ yarn compile
yarn compile --watch
```
## Website and visual tests
## Documentation and visual tests
To run the interactive storybook:
```
yarn website
yarn docs
```
When you're also making changes to the 'react-native-web' source files, run this command in another process:
When you're also making changes to the 'react-native-web' source files, run this
command in another process:
```
yarn compile --watch

13
.github/workflows/compressed-size.yml vendored Normal file
View File

@@ -0,0 +1,13 @@
name: compressed-size
on: [pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: necolas/compressed-size-action@master
with:
build-script: "compile"
exclude: "./packages/react-native-web/dist/cjs/{index.js,**/*.js}"
pattern: "./packages/react-native-web/dist/{index.js,**/*.js}"
repo-token: "${{ secrets.GITHUB_TOKEN }}"

View File

@@ -1,7 +1,7 @@
language: node_js
node_js:
- "8"
- "10"
before_install:
# Install Yarn

1
.watchmanconfig Normal file
View File

@@ -0,0 +1 @@
{}

111
README.md
View File

@@ -2,12 +2,10 @@
[![npm version][package-badge]][package-url] [![Build Status][ci-badge]][ci-url] [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://reactjs.org/docs/how-to-contribute.html#your-first-pull-request)
**Compatibility: React Native 0.55**.
**Compatibility: React Native >= 0.63**.
"React Native for Web" makes it possible to run [React
Native][react-native-url] components and APIs on the web using React DOM. Check
out the live demo of the [React Native examples][examples-url] running on the
web.
Native][react-native-url] components and APIs on the web using React DOM.
* **High-quality web interfaces**: makes it easy to
create [fast](https://github.com/necolas/react-native-web/blob/master/packages/benchmarks/README.md),
@@ -22,72 +20,59 @@ develop new components for native and web without rewriting existing code.
React Native for Web can also render to HTML and critical CSS on the server
using Node.js.
Who is using React Native in production web apps?
[Twitter](https://mobile.twitter.com), [Major League
Soccer](https://matchcenter.mlssoccer.com),
[Flipkart](https://www.flipkart.com/), Uber, [The
Times](https://github.com/newsuk/times-components).
Who is using React Native for Web in production?
[Twitter](https://mobile.twitter.com),
[Expo](https://docs.expo.io/workflow/web/),
[Major League Soccer](https://matchcenter.mlssoccer.com),
[Flipkart](https://twitter.com/naqvitalha/status/969577892991549440),
[Uber](https://www.youtube.com/watch?v=RV9rxrNIxnY),
[The Times](https://github.com/newsuk/times-components),
[DataCamp](https://www.datacamp.com/community/tech/porting-practice-to-web-part1).
Browser support: Chrome, Firefox, Edge, Safari 7+, IE 10+.
Components and APIs deprecated in React Native are not supported by React Native for Web.
## Quick start
The easiest way to get started is to edit this
[CodeSandbox](https://codesandbox.io/s/q4qymyp2l6) template (or
[Glitch](https://glitch.com/edit/#!/react-native)). You dont need to install
anything to try it out.
For installation and configuration details please read the [getting
started](https://github.com/necolas/react-native-web/blob/master/docs/guides/getting-started.md)
guide.
[CodeSandbox](https://codesandbox.io/s/q4qymyp2l6) template. You dont need to
install anything to try it out.
## Documentation
Please refer to the [React Native documentation][react-native-url] for the
overall API, design details, and information about the [Gesture Responder
system](https://facebook.github.io/react-native/docs/gesture-responder-system.html)
and [animations](https://facebook.github.io/react-native/docs/animations.html).
The [documentation app](https://necolas.github.com/react-native-web/docs) covers
installation, configuration, APIs, and guides.
Some components and APIs are extended with additional features for the web. And
in a few cases, features present for Android or iOS are missing on the web.
These differences are documented [on the website][website-url].
The [React Native documentation][react-native-url] contains more information
about the [Gesture Responder
system](https://facebook.github.io/react-native/docs/gesture-responder-system.html),
[animations](https://facebook.github.io/react-native/docs/animations.html), and
other design details.
### Guides
## Libraries and integrations
These guides provide a detailed look at using React Native to create accessible
web experiences. Certain web-specific patterns are documented in the "web
recipes" guide.
List of React Native packages with known web compatibility:
* [Getting started](https://github.com/necolas/react-native-web/blob/master/docs/guides/getting-started.md)
* [Client-side rendering](https://github.com/necolas/react-native-web/blob/master/docs/guides/client-side-rendering.md)
* [Server-side rendering](https://github.com/necolas/react-native-web/blob/master/docs/guides/server-side-rendering.md)
* [Style](https://github.com/necolas/react-native-web/blob/master/docs/guides/style.md)
* [Accessibility](https://github.com/necolas/react-native-web/blob/master/docs/guides/accessibility.md)
* [Internationalization](https://github.com/necolas/react-native-web/blob/master/docs/guides/internationalization.md)
* [Direct manipulation](https://github.com/necolas/react-native-web/blob/master/docs/guides/direct-manipulation.md)
* [Web recipes](https://github.com/necolas/react-native-web/blob/master/docs/guides/web-recipes.md)
* [Multi-platform apps](https://github.com/necolas/react-native-web/blob/master/docs/guides/multi-platform-apps.md)
* [Experimental / unstable use](https://github.com/necolas/react-native-web/blob/master/docs/guides/advanced.md)
## Integrations
* [React Native Directory](https://reactnative.directory/?web=true)
Examples of using React Native for Web with other web tools:
* [Docz](https://github.com/pedronauck/docz-plugin-react-native)
* [Gatsby](https://github.com/gatsbyjs/gatsby/tree/master/examples/using-react-native-web)
* [Docz](https://github.com/doczjs/docz/tree/master/examples/react-native)
* [Gatsby](https://github.com/slorber/gatsby-plugin-react-native-web)
* [Next.js](https://github.com/zeit/next.js/tree/master/examples/with-react-native-web)
(and [example recipes](https://gist.github.com/necolas/f9034091723f1b279be86c7429eb0c96))
* [Phenomic](https://github.com/phenomic/phenomic/tree/master/examples/react-native-web-app)
* [Razzle](https://github.com/jaredpalmer/razzle/tree/master/examples/with-react-native-web)
* [Storybook](https://github.com/necolas/react-native-web/tree/master/packages/website/storybook/.storybook)
* [Storybook](https://github.com/necolas/react-native-web/tree/master/packages/docs/)
* [Styleguidist](https://github.com/styleguidist/react-styleguidist/tree/master/examples/react-native)
## Examples
Check out all the [React Native examples][examples-url] ([source
code](https://github.com/necolas/react-native-web/blob/master/packages/examples)).
There are more examples [on the website][website-url] ([source
code](https://github.com/necolas/react-native-web/blob/master/packages/website)).
And here is a simple example to get you started:
And here is a simple example to get you started. The documentation includes
interactive examples and the [source
code](https://github.com/necolas/react-native-web/blob/master/packages/docs) is
also available.
```js
import React from 'react';
@@ -120,34 +105,30 @@ Native. This allows the app to be rendered to web and native platforms.
## Compatibility with React Native
React Native v0.55
React Native v0.60
### Components
| Name | Status | Notes |
| :----------------------- | :----- | :---- |
| ActivityIndicator | ✓ | |
| ART | ✓ | |
| Button | ✓ | |
| CheckBox | ✓ | |
| FlatList | ✓ | |
| Image | ✓ | Missing multiple sources ([#515](https://github.com/necolas/react-native-web/issues/515)) and HTTP headers ([#1019](https://github.com/necolas/react-native-web/issues/1019)). |
| ImageBackground | ✓ | |
| KeyboardAvoidingView | (✓) | Mock. No equivalent web APIs. |
| ListView | ✓ | |
| Modal | ✘ | Not started ([#1020](https://github.com/necolas/react-native-web/issues/1020)). |
| Modal | ✓ | |
| Picker | ✓ | |
| Pressable | ✓ | |
| RefreshControl | ✘ | Not started ([#1027](https://github.com/necolas/react-native-web/issues/1027)). |
| SafeAreaView | ✓ | |
| ScrollView | ✓ | Missing momentum scroll events ([#1021](https://github.com/necolas/react-native-web/issues/1021)) and `pagingEnabled` ([#1057](https://github.com/necolas/react-native-web/issues/1057)). |
| ScrollView | ✓ | Missing momentum scroll events ([#1021](https://github.com/necolas/react-native-web/issues/1021)). |
| SectionList | ✓ | |
| Slider | ✘ | Not started ([#1022](https://github.com/necolas/react-native-web/issues/1022)). |
| StatusBar | (✓) | Mock. No equivalent web APIs. |
| SwipeableFlatList | ✓ | |
| SwipeableListView | ✓ | |
| Switch | ✓ | |
| Text | ✓ | Missing `onLongPress` ([#1011](https://github.com/necolas/react-native-web/issues/1011)) and `numberOfLines` ([#13](https://github.com/necolas/react-native-web/issues/13)) support. |
| TextInput | ✓ | Missing `onContentSizeChange` ([#793](https://github.com/necolas/react-native-web/issues/793)), rich text features ([#1023](https://github.com/necolas/react-native-web/issues/1023)), and auto-expanding behaviour ([#795](https://github.com/necolas/react-native-web/issues/795)). |
| Text | ✓ | Missing `onLongPress` ([#1011](https://github.com/necolas/react-native-web/issues/1011)) support. |
| TextInput | ✓ | Missing rich text features ([#1023](https://github.com/necolas/react-native-web/issues/1023)), and auto-expanding behaviour ([#795](https://github.com/necolas/react-native-web/issues/795)). |
| Touchable | ✓ | Includes additional support for mouse and keyboard interactions. |
| TouchableHighlight | ✓ | |
| TouchableNativeFeedback | ✘ | Not started ([#1024](https://github.com/necolas/react-native-web/issues/1024)). |
@@ -155,7 +136,6 @@ React Native v0.55
| TouchableWithoutFeedback | ✓ | |
| View | ✓ | |
| VirtualizedList | ✓ | |
| WebView | ✘ | Not started ([1025](https://github.com/necolas/react-native-web/issues/1025)). |
| YellowBox | (✓) | Mock. No YellowBox functionality. |
### Modules
@@ -165,21 +145,16 @@ React Native v0.55
| AccessibilityInfo | (✓) | Mock. No equivalent web APIs. |
| Alert | ✘ | Not started ([#1026](https://github.com/necolas/react-native-web/issues/1026)). |
| Animated | ✓ | Missing `useNativeDriver` support. |
| Appearance | ✓ | |
| AppRegistry | ✓ | Includes additional support for server rendering with `getApplication`. |
| AppState | ✓ | |
| AsyncStorage | ✓ | |
| BackHandler | (✓) | Mock. No equivalent web APIs. |
| CameraRoll | ✘ | No equivalent web APIs. |
| Clipboard | ✓ | |
| ColorPropType | ✓ | |
| DeviceInfo | (✓) | Limited information. |
| Dimensions | ✓ | |
| Easing | ✓ | |
| EdgeInsetsPropType | ✓ | |
| Geolocation | ✓ | |
| I18nManager | ✓ | Includes additional support for runtime switch to RTL. |
| ImageEditor | ✘ | No equivalent web APIs. |
| ImageStore | ✘ | No equivalent web APIs. |
| InteractionManager | (✓) | |
| Keyboard | (✓) | Mock. |
| LayoutAnimation | (✓) | Missing translation to web animations. |
@@ -187,18 +162,16 @@ React Native v0.55
| NativeEventEmitter | ✓ | |
| NativeMethodsMixin | ✓ | |
| NativeModules | (✓) | Mocked. Missing ability to load native modules. |
| NetInfo | ✓ | Missing functionality to detect expensive connections as there are no equivalent web APIs. |
| PanResponder | ✓ | |
| PixelRatio | ✓ | |
| Platform | ✓ | |
| PointPropType | ✓ | |
| Settings | ✘ | No equivalent web APIs. |
| Share | ✓ | Only available over HTTPS. Read about the [Web Share API](https://wicg.github.io/web-share/). |
| StyleSheet | ✓ | |
| TextPropTypes | ✓ | |
| UIManager | ✓ | |
| Vibration | ✓ | |
| ViewPropTypes | ✓ | |
| useColorScheme | ✓ | |
| useWindowDimensions | ✓ | |
## Contributing
@@ -237,8 +210,6 @@ MIT license.
[package-url]: https://yarnpkg.com/en/package/react-native-web
[ci-badge]: https://travis-ci.org/necolas/react-native-web.svg?branch=master
[ci-url]: https://travis-ci.org/necolas/react-native-web
[examples-url]: https://necolas.github.io/react-native-web/examples/
[website-url]: https://necolas.github.io/react-native-web/storybook/
[react-native-url]: https://facebook.github.io/react-native/
[contributing-url]: https://github.com/necolas/react-native-web/blob/master/.github/CONTRIBUTING.md
[good-first-issue-url]: https://github.com/necolas/react-native-web/labels/good%20first%20issue

7
babel.config.js Normal file
View File

@@ -0,0 +1,7 @@
module.exports = function(api) {
api.cache(true);
return {
presets: ['./scripts/babel/preset']
};
};

View File

@@ -1,63 +1,65 @@
{
"private": true,
"version": "0.9.2",
"name": "react-native-web-monorepo",
"version": "0.14.7",
"name": "monorepo",
"scripts": {
"clean": "del ./packages/*/dist",
"clean": "del-cli ./packages/*/dist",
"compile": "npm-run-all clean -p \"compile:* -- {@}\" --",
"compile:commonjs": "cd packages/react-native-web && BABEL_ENV=commonjs babel src --out-dir dist/cjs --ignore \"**/__tests__\"",
"compile:es": "cd packages/react-native-web && babel src --out-dir dist --ignore \"**/__tests__\"",
"compile:commonjs": "cd packages/react-native-web && cross-env BABEL_ENV=commonjs babel --root-mode upward src --out-dir dist/cjs --ignore \"**/__tests__\"",
"compile:es": "cd packages/react-native-web && babel --root-mode upward src --out-dir dist --ignore \"**/__tests__\"",
"benchmarks": "cd packages/benchmarks && yarn build",
"benchmarks:release": "cd packages/benchmarks && yarn release",
"examples": "cd packages/examples && yarn build",
"examples:release": "cd packages/examples && yarn release",
"website": "cd packages/website && yarn start",
"website:release": "cd packages/website && yarn release",
"docs": "cd packages/docs && yarn start",
"docs:release": "cd packages/docs && yarn release",
"flow": "flow",
"fmt": "prettier --write \"**/*.js\"",
"jest": "BABEL_ENV=commonjs jest --config ./scripts/jest/config.js",
"jest": "jest --config ./scripts/jest/config.js",
"lint": "yarn lint:check --fix",
"lint:check": "eslint packages scripts",
"precommit": "lint-staged",
"prerelease": "yarn test && yarn compile && yarn compile:commonjs",
"release": "node ./scripts/release/publish.js",
"postrelease": "yarn benchmarks:release && yarn examples:release && yarn website:release",
"postrelease": "yarn benchmarks:release && yarn docs:release",
"test": "yarn flow && yarn lint:check && yarn jest --runInBand"
},
"devDependencies": {
"babel-cli": "^6.26.0",
"babel-core": "^6.26.0",
"babel-eslint": "^8.2.3",
"babel-loader": "^7.1.2",
"babel-plugin-add-module-exports": "^0.2.1",
"babel-plugin-transform-class-properties": "^6.24.1",
"babel-plugin-transform-object-rest-spread": "^6.26.0",
"babel-plugin-transform-react-remove-prop-types": "^0.4.10",
"babel-preset-env": "^1.6.1",
"babel-preset-flow": "^6.23.0",
"babel-preset-react": "^6.24.1",
"babel-preset-react-native": "^4.0.0",
"caniuse-api": "^2.0.0",
"del-cli": "^1.1.0",
"enzyme": "^3.6.0",
"enzyme-adapter-react-16": "^1.5.0",
"enzyme-to-json": "^3.3.3",
"eslint": "^4.19.1",
"eslint-config-prettier": "^2.9.0",
"eslint-plugin-promise": "^3.7.0",
"eslint-plugin-react": "^7.7.0",
"flow-bin": "^0.63.1",
"glob": "^7.1.2",
"husky": "^0.14.3",
"jest": "^22.4.3",
"jest-canvas-mock": "^1.0.2",
"lint-staged": "^7.1.0",
"@babel/cli": "^7.8.4",
"@babel/core": "^7.8.4",
"@babel/plugin-proposal-class-properties": "^7.8.3",
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.8.3",
"@babel/plugin-proposal-object-rest-spread": "^7.8.3",
"@babel/plugin-transform-runtime": "^7.8.3",
"@babel/preset-env": "^7.8.4",
"@babel/preset-flow": "^7.8.3",
"@babel/preset-react": "^7.8.3",
"@testing-library/react": "^9.3.0",
"babel-eslint": "^10.0.3",
"babel-jest": "^25.1.0",
"babel-loader": "^8.0.6",
"babel-plugin-add-module-exports": "^1.0.2",
"babel-plugin-transform-react-remove-prop-types": "^0.4.24",
"caniuse-api": "^3.0.0",
"cross-env": "^6.0.3",
"del-cli": "^3.0.0",
"eslint": "^6.5.1",
"eslint-config-prettier": "^6.4.0",
"eslint-plugin-flowtype": "^4.7.0",
"eslint-plugin-promise": "^4.2.1",
"eslint-plugin-react": "^7.16.0",
"eslint-plugin-react-hooks": "^2.3.0",
"flow-bin": "^0.109.0",
"glob": "^7.1.4",
"husky": "^3.0.8",
"inline-style-prefixer": "^5.1.0",
"jest": "^25.1.0",
"jest-canvas-mock": "^2.2.0",
"lint-staged": "^9.4.2",
"metro-react-native-babel-preset": "^0.56.0",
"npm-run-all": "^4.1.3",
"prettier": "^1.12.1",
"react": "^16.5.1",
"react-art": "^16.5.1",
"react-dom": "^16.5.1",
"react-test-renderer": "^16.5.1"
"prettier": "^1.18.2",
"react": "^16.10.2",
"react-dom": "^16.10.2",
"react-test-renderer": "^16.10.2"
},
"workspaces": [
"packages/*"

View File

@@ -1,10 +1,14 @@
{
"publishConfig": {
"registry": "https://registry.npmjs.org/"
},
"name": "babel-plugin-react-native-web",
"version": "0.9.2",
"version": "0.14.7",
"description": "Babel plugin for React Native for Web",
"main": "index.js",
"devDependencies": {
"babel-plugin-tester": "^5.0.0"
"babel-core": "^6.26.3",
"babel-plugin-tester": "^7.0.4"
},
"author": "Nicolas Gallagher",
"license": "MIT",

View File

@@ -3,30 +3,28 @@
exports[`Rewrite react-native to react-native-web export from "react-native": export from "react-native" 1`] = `
"
export { View } from 'react-native';
export { ColorPropType, StyleSheet, Text, createElement } from 'react-native';
export { StyleSheet, Text, unstable_createElement } from 'react-native';
↓ ↓ ↓ ↓ ↓ ↓
export { default as View } from 'react-native-web/dist/exports/View';
export { default as ColorPropType } from 'react-native-web/dist/exports/ColorPropType';
export { default as StyleSheet } from 'react-native-web/dist/exports/StyleSheet';
export { default as Text } from 'react-native-web/dist/exports/Text';
export { default as createElement } from 'react-native-web/dist/exports/createElement';
export { default as unstable_createElement } from 'react-native-web/dist/exports/createElement';
"
`;
exports[`Rewrite react-native to react-native-web export from "react-native-web": export from "react-native-web" 1`] = `
"
export { View } from 'react-native-web';
export { ColorPropType, StyleSheet, Text, createElement } from 'react-native-web';
export { StyleSheet, Text, unstable_createElement } from 'react-native-web';
↓ ↓ ↓ ↓ ↓ ↓
export { default as View } from 'react-native-web/dist/exports/View';
export { default as ColorPropType } from 'react-native-web/dist/exports/ColorPropType';
export { default as StyleSheet } from 'react-native-web/dist/exports/StyleSheet';
export { default as Text } from 'react-native-web/dist/exports/Text';
export { default as createElement } from 'react-native-web/dist/exports/createElement';
export { default as unstable_createElement } from 'react-native-web/dist/exports/createElement';
"
`;
@@ -34,7 +32,7 @@ exports[`Rewrite react-native to react-native-web import from "native-native": i
"
import ReactNative from 'react-native';
import { View } from 'react-native';
import { Invalid, View as MyView, ViewPropTypes } from 'react-native';
import { Invalid, View as MyView } from 'react-native';
import * as ReactNativeModules from 'react-native';
↓ ↓ ↓ ↓ ↓ ↓
@@ -43,7 +41,6 @@ import ReactNative from 'react-native-web/dist/index';
import View from 'react-native-web/dist/exports/View';
import { Invalid } from 'react-native-web/dist/index';
import MyView from 'react-native-web/dist/exports/View';
import ViewPropTypes from 'react-native-web/dist/exports/ViewPropTypes';
import * as ReactNativeModules from 'react-native-web/dist/index';
"
`;
@@ -52,7 +49,7 @@ exports[`Rewrite react-native to react-native-web import from "native-native": i
"
import ReactNative from 'react-native';
import { View } from 'react-native';
import { Invalid, View as MyView, ViewPropTypes } from 'react-native';
import { Invalid, View as MyView } from 'react-native';
import * as ReactNativeModules from 'react-native';
↓ ↓ ↓ ↓ ↓ ↓
@@ -61,21 +58,19 @@ import ReactNative from 'react-native-web/dist/cjs/index';
import View from 'react-native-web/dist/cjs/exports/View';
import { Invalid } from 'react-native-web/dist/cjs/index';
import MyView from 'react-native-web/dist/cjs/exports/View';
import ViewPropTypes from 'react-native-web/dist/cjs/exports/ViewPropTypes';
import * as ReactNativeModules from 'react-native-web/dist/cjs/index';
"
`;
exports[`Rewrite react-native to react-native-web import from "react-native-web": import from "react-native-web" 1`] = `
"
import { createElement } from 'react-native-web';
import { ColorPropType, StyleSheet, View, TouchableOpacity, processColor } from 'react-native-web';
import { unstable_createElement } from 'react-native-web';
import { StyleSheet, View, TouchableOpacity, processColor } from 'react-native-web';
import * as ReactNativeModules from 'react-native-web';
↓ ↓ ↓ ↓ ↓ ↓
import createElement from 'react-native-web/dist/exports/createElement';
import ColorPropType from 'react-native-web/dist/exports/ColorPropType';
import unstable_createElement from 'react-native-web/dist/exports/createElement';
import StyleSheet from 'react-native-web/dist/exports/StyleSheet';
import View from 'react-native-web/dist/exports/View';
import TouchableOpacity from 'react-native-web/dist/exports/TouchableOpacity';
@@ -92,7 +87,7 @@ const { StyleSheet, TouchableOpacity } = require('react-native');
↓ ↓ ↓ ↓ ↓ ↓
const ReactNative = require('react-native-web/dist/index').default;
const ReactNative = require('react-native-web/dist/index');
const View = require('react-native-web/dist/exports/View').default;
@@ -110,7 +105,7 @@ const { StyleSheet, TouchableOpacity } = require('react-native');
↓ ↓ ↓ ↓ ↓ ↓
const ReactNative = require('react-native-web/dist/cjs/index').default;
const ReactNative = require('react-native-web/dist/cjs/index');
const View = require('react-native-web/dist/cjs/exports/View').default;
@@ -123,16 +118,14 @@ const TouchableOpacity = require('react-native-web/dist/cjs/exports/TouchableOpa
exports[`Rewrite react-native to react-native-web require "react-native-web": require "react-native-web" 1`] = `
"
const ReactNative = require('react-native-web');
const { createElement } = require('react-native-web');
const { ColorPropType, StyleSheet, View, TouchableOpacity, processColor } = require('react-native-web');
const { unstable_createElement } = require('react-native-web');
const { StyleSheet, View, TouchableOpacity, processColor } = require('react-native-web');
↓ ↓ ↓ ↓ ↓ ↓
const ReactNative = require('react-native-web/dist/index').default;
const ReactNative = require('react-native-web/dist/index');
const createElement = require('react-native-web/dist/exports/createElement').default;
const ColorPropType = require('react-native-web/dist/exports/ColorPropType').default;
const unstable_createElement = require('react-native-web/dist/exports/createElement').default;
const StyleSheet = require('react-native-web/dist/exports/StyleSheet').default;

View File

@@ -7,7 +7,7 @@ const tests = [
title: 'import from "native-native"',
code: `import ReactNative from 'react-native';
import { View } from 'react-native';
import { Invalid, View as MyView, ViewPropTypes } from 'react-native';
import { Invalid, View as MyView } from 'react-native';
import * as ReactNativeModules from 'react-native';`,
snapshot: true
},
@@ -15,28 +15,28 @@ import * as ReactNativeModules from 'react-native';`,
title: 'import from "native-native"',
code: `import ReactNative from 'react-native';
import { View } from 'react-native';
import { Invalid, View as MyView, ViewPropTypes } from 'react-native';
import { Invalid, View as MyView } from 'react-native';
import * as ReactNativeModules from 'react-native';`,
snapshot: true,
pluginOptions: { commonjs: true }
},
{
title: 'import from "react-native-web"',
code: `import { createElement } from 'react-native-web';
import { ColorPropType, StyleSheet, View, TouchableOpacity, processColor } from 'react-native-web';
code: `import { unstable_createElement } from 'react-native-web';
import { StyleSheet, View, TouchableOpacity, processColor } from 'react-native-web';
import * as ReactNativeModules from 'react-native-web';`,
snapshot: true
},
{
title: 'export from "react-native"',
code: `export { View } from 'react-native';
export { ColorPropType, StyleSheet, Text, createElement } from 'react-native';`,
export { StyleSheet, Text, unstable_createElement } from 'react-native';`,
snapshot: true
},
{
title: 'export from "react-native-web"',
code: `export { View } from 'react-native-web';
export { ColorPropType, StyleSheet, Text, createElement } from 'react-native-web';`,
export { StyleSheet, Text, unstable_createElement } from 'react-native-web';`,
snapshot: true
},
{
@@ -57,13 +57,20 @@ const { StyleSheet, TouchableOpacity } = require('react-native');`,
{
title: 'require "react-native-web"',
code: `const ReactNative = require('react-native-web');
const { createElement } = require('react-native-web');
const { ColorPropType, StyleSheet, View, TouchableOpacity, processColor } = require('react-native-web');`,
const { unstable_createElement } = require('react-native-web');
const { StyleSheet, View, TouchableOpacity, processColor } = require('react-native-web');`,
snapshot: true
}
];
pluginTester({
babelOptions: {
generatorOpts: {
jsescOption: {
quotes: 'single'
}
}
},
plugin,
tests
});

View File

@@ -4,10 +4,11 @@ const isCommonJS = opts => opts.commonjs === true;
const getDistLocation = (importName, opts) => {
const format = isCommonJS(opts) ? 'cjs/' : '';
if (importName === 'index') {
const internalName = importName === 'unstable_createElement' ? 'createElement' : importName;
if (internalName === 'index') {
return `react-native-web/dist/${format}index`;
} else if (importName && moduleMap[importName]) {
return `react-native-web/dist/${format}exports/${importName}`;
} else if (internalName && moduleMap[internalName]) {
return `react-native-web/dist/${format}exports/${internalName}`;
}
};
@@ -118,12 +119,9 @@ module.exports = function({ types: t }) {
const importIndex = t.variableDeclaration(path.node.kind, [
t.variableDeclarator(
t.identifier(name),
t.memberExpression(
t.callExpression(t.identifier('require'), [
t.stringLiteral(getDistLocation('index', state.opts))
]),
t.identifier('default')
)
t.callExpression(t.identifier('require'), [
t.stringLiteral(getDistLocation('index', state.opts))
])
)
]);

View File

@@ -1,56 +1,56 @@
// THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT.
module.exports = {
ART: true,
AccessibilityInfo: true,
ActivityIndicator: true,
Alert: true,
Animated: true,
AppRegistry: true,
AppState: true,
AsyncStorage: true,
Appearance: true,
BackHandler: true,
Button: true,
CheckBox: true,
Clipboard: true,
ColorPropType: true,
DeviceEventEmitter: true,
DeviceInfo: true,
Dimensions: true,
DrawerLayoutAndroid: true,
Easing: true,
EdgeInsetsPropType: true,
FlatList: true,
I18nManager: true,
Image: true,
ImageBackground: true,
InputAccessoryView: true,
InteractionManager: true,
Keyboard: true,
KeyboardAvoidingView: true,
LayoutAnimation: true,
Linking: true,
ListView: true,
LogBox: true,
Modal: true,
NativeEventEmitter: true,
NativeModules: true,
NetInfo: true,
PanResponder: true,
PermissionsAndroid: true,
Picker: true,
PixelRatio: true,
Platform: true,
PointPropType: true,
Pressable: true,
ProgressBar: true,
RefreshControl: true,
SafeAreaView: true,
ScrollView: true,
SectionList: true,
Settings: true,
Share: true,
Slider: true,
StatusBar: true,
StyleSheet: true,
SwipeableFlatList: true,
SwipeableListView: true,
Switch: true,
Systrace: true,
TVEventHandler: true,
Text: true,
TextInput: true,
TextPropTypes: true,
ToastAndroid: true,
Touchable: true,
TouchableHighlight: true,
TouchableNativeFeedback: true,
@@ -59,12 +59,13 @@ module.exports = {
UIManager: true,
Vibration: true,
View: true,
ViewPropTypes: true,
VirtualizedList: true,
YellowBox: true,
createElement: true,
findNodeHandle: true,
processColor: true,
render: true,
unmountComponentAtNode: true
unmountComponentAtNode: true,
useColorScheme: true,
useWindowDimensions: true
};

View File

@@ -47,24 +47,24 @@ included.
### MacBook Pro (2011)
MacBook Pro (13-inch, Early 2011); 2.3 GHz Intel Core i5; 8 GB 1333 MHz DDR3 RAM. Google Chrome 63.
MacBook Pro (13-inch, Early 2011); 2.3 GHz Intel Core i5; 8 GB 1333 MHz DDR3 RAM. Google Chrome 72.
Typical render timings: mean ± standard deviations.
| Implementation | Mount deep tree (ms) | Mount wide tree (ms) | Dynamic update (ms) |
| :--- | ---: | ---: | ---: |
| `css-modules` | `30.19` `±04.84` | `38.25` `±04.85` | - |
| `react-native-web@0.4.0` | `36.40` `±04.98` | `51.28` `±05.58` | `19.36` `±02.56` |
| `inline-styles` | `64.12` `±07.69` | `94.49` `±11.34` | `09.84` `±02.36` |
| `css-modules` | `23.41` `±03.06` | `35.38` `±06.41` | - |
| `react-native-web@0.11.0` | `28.37` `±04.39` | `41.50` `±05.75` | `23.13` `±03.51` |
| `inline-styles` | `66.19` `±06.31` | `104.22` `±10.22` | `09.96` `±02.76` |
### Moto G4
Moto G4 (Android 7); Octa-core (4x1.5 GHz & 4x1.2 Ghz); 2 GB RAM. Google Chrome 63.
Moto G4 (Android 7); Octa-core (4x1.5 GHz & 4x1.2 Ghz); 2 GB RAM. Google Chrome 72.
Typical render timings: mean ± standard deviations.
| Implementation | Mount deep tree (ms) | Mount wide tree (ms) | Dynamic update (ms) |
| :--- | ---: | ---: | ---: |
| `css-modules` | `98.24` 20.26` | `143.75` 25.50` | - |
| `react-native-web@0.4.0` | `131.46` `±18.96` | `174.70` `±14.88` | `60.87` `±06.32` |
| `inline-styles` | `184.58` 26.23` | `273.86` `±26.23` | `30.28` `±07.44` |
| `css-modules` | `71.33` 09.68` | `101.36` 12.36` | - |
| `react-native-web@0.11.0` | `83.65` `±12.40` | `123.59` `±14.40` | `75.41` `±07.74` |
| `inline-styles` | `188.35` 17.69` | `282.35` `±22.48` | `28.10` `±06.87` |

View File

@@ -1,37 +1,33 @@
{
"private": true,
"name": "benchmarks",
"version": "0.9.2",
"version": "0.14.7",
"scripts": {
"build": "mkdir -p dist && cp -f index.html dist/index.html && ./node_modules/.bin/webpack-cli --config ./webpack.config.js",
"release": "yarn build && git checkout gh-pages && rm -rf ../../benchmarks && mv dist ../../benchmarks && git add -A && git commit -m \"Benchmarks deploy\" && git push origin gh-pages && git checkout -"
"release": "NODE_ENV=production yarn build && git checkout gh-pages && rm -rf ../../benchmarks && mv dist ../../benchmarks && git add -A && git commit -m \"Benchmarks deploy\" && git push origin gh-pages && git checkout -"
},
"dependencies": {
"aphrodite": "^2.2.2",
"aphrodite": "^2.4.0",
"classnames": "^2.2.6",
"d3-scale-chromatic": "^1.3.0",
"emotion": "^9.2.4",
"fela": "^6.1.9",
"glamor": "2.20.40",
"radium": "^0.24.0",
"react": "^16.5.1",
"react-dom": "^16.5.1",
"react-fela": "^7.3.1",
"react-jss": "^8.6.1",
"react-native-web": "0.9.2",
"reactxp": "^1.3.0",
"styled-components": "^3.3.3",
"styled-jsx": "^2.2.7",
"styletron-engine-atomic": "^1.0.5",
"styletron-react": "^4.3.1"
"d3-scale-chromatic": "^1.5.0",
"emotion": "^10.0.27",
"fela": "^11.0.2",
"react-fela": "^11.0.2",
"react-jss": "^10.0.4",
"react-native-web": "0.14.7",
"reactxp": "^2.0.0",
"styled-components": "^5.0.0",
"styled-jsx": "^3.2.4",
"styletron-engine-atomic": "^1.4.4",
"styletron-react": "^5.2.6"
},
"devDependencies": {
"babel-plugin-react-native-web": "0.9.2",
"css-loader": "^1.0.0",
"style-loader": "^0.21.0",
"url-loader": "^1.0.1",
"webpack": "^4.15.1",
"webpack-bundle-analyzer": "^2.13.1",
"webpack-cli": "^3.0.8"
"babel-plugin-react-native-web": "0.14.7",
"css-loader": "^3.4.2",
"style-loader": "^1.1.3",
"url-loader": "^3.0.0",
"webpack": "^4.41.5",
"webpack-bundle-analyzer": "^3.6.0",
"webpack-cli": "^3.3.10"
}
}

View File

@@ -1,5 +1,3 @@
/* eslint-disable react/prop-types */
import Benchmark from './Benchmark';
import { Picker, StyleSheet, ScrollView, TouchableOpacity, View } from 'react-native';
import React, { Component } from 'react';

View File

@@ -2,12 +2,11 @@
* The MIT License (MIT)
* Copyright (c) 2017 Paul Armstrong
* https://github.com/paularmstrong/react-component-benchmark
* @flow
*/
/* global $Values */
/**
* @flow
*/
import * as Timing from './timing';
import React, { Component } from 'react';
import { getMean, getMedian, getStdDev } from './math';

View File

@@ -1,21 +1,9 @@
import { ColorPropType, StyleSheet, TouchableHighlight, Text } from 'react-native';
import { StyleSheet, TouchableHighlight, Text } from 'react-native';
import React, { Component } from 'react';
import { bool, func, string } from 'prop-types';
export default class Button extends Component<*> {
static displayName = '@app/Button';
static propTypes = {
accessibilityLabel: string,
color: ColorPropType,
disabled: bool,
onPress: func.isRequired,
style: TouchableHighlight.propTypes.style,
testID: string,
textStyle: Text.propTypes.style,
title: string.isRequired
};
render() {
const {
accessibilityLabel,

View File

@@ -1,5 +1,5 @@
import React, { Fragment } from 'react';
import { createElement, StyleSheet, Text } from 'react-native';
import { unstable_createElement as createElement, StyleSheet } from 'react-native';
const styles = StyleSheet.create({
root: {
@@ -18,16 +18,16 @@ const createIcon = children => {
createElement(
'svg',
{
style: StyleSheet.compose(styles.root, props.style),
style: StyleSheet.compose(
styles.root,
props.style
),
width: 24,
height: 24,
viewBox: '0 0 24 24'
},
children
);
Icon.propTypes = {
style: Text.propTypes.style
};
return Icon;
};

View File

@@ -1,15 +1,8 @@
import { colors } from './theme';
import { element } from 'prop-types';
import React, { Component } from 'react';
import { StyleSheet, View } from 'react-native';
export default class Layout extends Component {
static propTypes = {
actionPanel: element,
listPanel: element,
viewPanel: element
};
state = {
widescreen: false
};

View File

@@ -1,4 +1,5 @@
/* eslint-disable react/prop-types */
/* @noflow */
import Text from './Text';
import { StyleSheet, View } from 'react-native';
import React, { Fragment } from 'react';

View File

@@ -1,8 +1,6 @@
/* eslint-disable react/prop-types */
import { bool } from 'prop-types';
import React from 'react';
import { StyleSheet, Text } from 'react-native';
import { bool } from 'prop-types';
import { colors } from './theme';
class AppText extends React.Component {

View File

@@ -1,5 +1,4 @@
import { BenchmarkType } from '../app/Benchmark';
import { number, object } from 'prop-types';
import React from 'react';
import { interpolatePurples, interpolateBuPu, interpolateRdPu } from 'd3-scale-chromatic';
@@ -10,15 +9,6 @@ class SierpinskiTriangle extends React.Component {
static benchmarkType = BenchmarkType.UPDATE;
static propTypes = {
components: object,
depth: number,
renderCount: number,
s: number,
x: number,
y: number
};
static defaultProps = {
depth: 0,
renderCount: 0
@@ -45,7 +35,7 @@ class SierpinskiTriangle extends React.Component {
}
// introduce randomness to ensure that repeated runs don't produce the same colors
const color = fn(renderCount * Math.random() / 20);
const color = fn((renderCount * Math.random()) / 20);
return (
<Dot color={color} size={targetSize} x={x - targetSize / 2} y={y - targetSize / 2} />
);

View File

@@ -0,0 +1,36 @@
import { BenchmarkType } from '../app/Benchmark';
import React, { Component } from 'react';
class TextTree extends Component {
static displayName = 'TextTree';
static benchmarkType = BenchmarkType.MOUNT;
render() {
const { breadth, components, depth, id, wrap } = this.props;
const { TextBox } = components;
let result = (
<TextBox children={'TextBox ${id % 3}'} color={id % 3} outer>
{depth === 0 && <TextBox children={'Depth 0'} color={(id % 3) + 3} />}
{depth !== 0 &&
Array.from({ length: breadth }).map((el, i) => (
<TextTree
breadth={breadth}
components={components}
depth={depth - 1}
id={i}
key={i}
wrap={wrap}
/>
))}
</TextBox>
);
for (let i = 0; i < wrap; i++) {
result = <TextBox>{result}</TextBox>;
}
return result;
}
}
export default TextTree;

View File

@@ -1,5 +1,4 @@
import { BenchmarkType } from '../app/Benchmark';
import { number, object } from 'prop-types';
import React, { Component } from 'react';
class Tree extends Component {
@@ -7,21 +6,13 @@ class Tree extends Component {
static benchmarkType = BenchmarkType.MOUNT;
static propTypes = {
breadth: number.isRequired,
components: object,
depth: number.isRequired,
id: number.isRequired,
wrap: number.isRequired
};
render() {
const { breadth, components, depth, id, wrap } = this.props;
const { Box } = components;
let result = (
<Box color={id % 3} layout={depth % 2 === 0 ? 'column' : 'row'} outer>
{depth === 0 && <Box color={id % 3 + 3} fixed />}
{depth === 0 && <Box color={(id % 3) + 3} fixed />}
{depth !== 0 &&
Array.from({ length: breadth }).map((el, i) => (
<Tree

View File

@@ -1,3 +1,5 @@
/* @noflow */
import { type Component } from 'react';
import packageJson from '../package.json';
@@ -8,6 +10,7 @@ type ComponentsType = {
Box: Component,
Dot: Component,
Provider: Component,
TextBox: Component,
View: Component
};

View File

@@ -1,4 +1,3 @@
/* eslint-disable react/prop-types */
import React from 'react';
import View from './View';
import { StyleSheet } from 'aphrodite';

View File

@@ -1,4 +1,3 @@
/* eslint-disable react/prop-types */
import React from 'react';
import { css, StyleSheet } from 'aphrodite';

View File

@@ -1,4 +1,3 @@
/* eslint-disable react/prop-types */
import classnames from 'classnames';
import React from 'react';
import View from './View';

View File

@@ -1,4 +1,3 @@
/* eslint-disable react/prop-types */
import classnames from 'classnames';
import React from 'react';
import styles from './view-styles.css';

View File

@@ -1,4 +1,3 @@
/* eslint-disable react/prop-types */
import React from 'react';
import View from './View';

View File

@@ -1,4 +1,3 @@
/* eslint-disable react/prop-types */
import React from 'react';
import { css } from 'emotion';

View File

@@ -1,4 +1,3 @@
/* eslint-disable react/prop-types */
import { css } from 'emotion';
import React from 'react';

View File

@@ -1,49 +0,0 @@
/* eslint-disable react/prop-types */
import React from 'react';
import View from './View';
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: {
alignSelf: 'flex-start',
padding: 4
},
row: {
flexDirection: 'row'
},
color0: {
backgroundColor: '#14171A'
},
color1: {
backgroundColor: '#AAB8C2'
},
color2: {
backgroundColor: '#E6ECF0'
},
color3: {
backgroundColor: '#FFAD1F'
},
color4: {
backgroundColor: '#F45D22'
},
color5: {
backgroundColor: '#E0245E'
},
fixed: {
width: 6,
height: 6
}
};
export default Box;

View File

@@ -1,33 +0,0 @@
/* eslint-disable react/prop-types */
import React from 'react';
import { css } from 'glamor';
const Dot = ({ size, x, y, children, color }) => (
<div
className={css(styles.root, {
borderBottomColor: color,
borderRightWidth: `${size / 2}px`,
borderBottomWidth: `${size / 2}px`,
borderLeftWidth: `${size / 2}px`,
marginLeft: `${x}px`,
marginTop: `${y}px`
})}
>
{children}
</div>
);
const styles = {
root: {
position: 'absolute',
cursor: 'pointer',
width: 0,
height: 0,
borderColor: 'transparent',
borderStyle: 'solid',
borderTopWidth: 0,
transform: 'translate(50%, 50%)'
}
};
export default Dot;

View File

@@ -1,2 +0,0 @@
import View from './View';
export default View;

View File

@@ -1,29 +0,0 @@
/* eslint-disable react/prop-types */
import { css } from 'glamor';
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

@@ -1,11 +0,0 @@
import Box from './Box';
import Dot from './Dot';
import Provider from './Provider';
import View from './View';
export default {
Box,
Dot,
Provider,
View
};

View File

@@ -1,4 +1,3 @@
/* eslint-disable react/prop-types */
import React from 'react';
import View from './View';

View File

@@ -1,4 +1,3 @@
/* eslint-disable react/prop-types */
import React from 'react';
const Dot = ({ size, x, y, children, color }) => (

View File

@@ -1,4 +1,3 @@
/* eslint-disable react/prop-types */
import React from 'react';
const compose = (s1, s2) => {
@@ -12,7 +11,15 @@ const compose = (s1, s2) => {
class View extends React.Component {
render() {
const { style, ...other } = this.props;
return <div {...other} style={compose(viewStyle, style)} />;
return (
<div
{...other}
style={compose(
viewStyle,
style
)}
/>
);
}
}

View File

@@ -1,50 +0,0 @@
/* eslint-disable react/prop-types */
import Radium from 'radium';
import React from 'react';
import View from './View';
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: {
alignSelf: 'flex-start',
padding: 4
},
row: {
flexDirection: 'row'
},
color0: {
backgroundColor: '#14171A'
},
color1: {
backgroundColor: '#AAB8C2'
},
color2: {
backgroundColor: '#E6ECF0'
},
color3: {
backgroundColor: '#FFAD1F'
},
color4: {
backgroundColor: '#F45D22'
},
color5: {
backgroundColor: '#E0245E'
},
fixed: {
width: 6,
height: 6
}
};
export default Radium(Box);

View File

@@ -1,36 +0,0 @@
/* eslint-disable react/prop-types */
import Radium from 'radium';
import React from 'react';
const Dot = ({ size, x, y, children, color }) => (
<div
style={[
styles.root,
{
borderBottomColor: color,
borderRightWidth: `${size / 2}px`,
borderBottomWidth: `${size / 2}px`,
borderLeftWidth: `${size / 2}px`,
marginLeft: `${x}px`,
marginTop: `${y}px`
}
]}
>
{children}
</div>
);
const styles = {
root: {
position: 'absolute',
cursor: 'pointer',
width: 0,
height: 0,
borderColor: 'transparent',
borderStyle: 'solid',
borderTopWidth: 0,
transform: 'translate(50%, 50%)'
}
};
export default Radium(Dot);

View File

@@ -1,2 +0,0 @@
import View from './View';
export default View;

View File

@@ -1,31 +0,0 @@
/* 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

@@ -1,11 +0,0 @@
import Box from './Box';
import Dot from './Dot';
import Provider from './Provider';
import View from './View';
export default {
Box,
Dot,
Provider,
View
};

View File

@@ -1,4 +1,3 @@
/* eslint-disable react/prop-types */
import { createComponent } from 'react-fela';
const Dot = createComponent(

View File

@@ -1,4 +1,3 @@
/* eslint-disable react/prop-types */
import React from 'react';
import { createRenderer } from 'fela';
import { Provider as FelaProvider } from 'react-fela';

View File

@@ -1,4 +1,3 @@
/* eslint-disable react/prop-types */
import { createComponent } from 'react-fela';
const View = createComponent(

View File

@@ -1,4 +1,3 @@
/* eslint-disable react/prop-types */
import classnames from 'classnames';
import injectSheet from 'react-jss';
import React from 'react';

View File

@@ -1,4 +1,3 @@
/* eslint-disable react/prop-types */
import injectSheet from 'react-jss';
import React from 'react';

View File

@@ -1,4 +1,3 @@
/* eslint-disable react/prop-types */
import classnames from 'classnames';
import injectSheet from 'react-jss';
import React from 'react';

View File

@@ -1,4 +1,3 @@
/* eslint-disable react/prop-types */
import React from 'react';
import { StyleSheet, View } from 'react-native';

View File

@@ -1,5 +1,4 @@
/* eslint-disable react/prop-types */
import { createElement, StyleSheet } from 'react-native';
import { unstable_createElement as createElement, StyleSheet } from 'react-native';
const Dot = ({ size, x, y, children, color }) =>
createElement('div', {

View File

@@ -0,0 +1,38 @@
import React from 'react';
import { StyleSheet, Text } from 'react-native';
const TextBox = ({ color, outer = false, ...other }) => (
<Text {...other} style={[styles.root, styles[`color${color}`], outer && styles.outer]} />
);
const styles = StyleSheet.create({
root: {
color: 'white'
},
outer: {
fontStyle: 'italic'
},
row: {
flexDirection: 'row'
},
color0: {
color: '#14171A'
},
color1: {
color: '#AAB8C2'
},
color2: {
color: '#E6ECF0'
},
color3: {
color: '#FFAD1F'
},
color4: {
color: '#F45D22'
},
color5: {
color: '#E0245E'
}
});
export default TextBox;

View File

@@ -1,108 +0,0 @@
import PropTypes from 'prop-types';
import theme from './theme';
import React, { PureComponent } from 'react';
import { StyleSheet, Text } from 'react-native';
class AppText extends PureComponent {
static displayName = 'AppText';
static propTypes = {
align: PropTypes.oneOf(['center', 'left', 'right']),
color: PropTypes.oneOf(['blue', 'deepGray', 'normal', 'red', 'white']),
fontStyle: PropTypes.oneOf(['normal', 'italic']),
size: PropTypes.oneOf(['small', 'normal', 'large']),
uppercase: PropTypes.bool,
weight: PropTypes.oneOf(['normal', 'bold'])
};
render() {
const { align, color, fontStyle, size, uppercase, weight, ...other } = this.props;
const style = [
styles.root,
align && alignStyles[align],
color && colorStyles[color],
fontStyle && fontStyles[fontStyle],
size && sizeStyles[size],
weight && weightStyles[weight],
uppercase === true && styles.uppercase
];
return <Text {...other} style={style} />;
}
}
const styles = StyleSheet.create({
root: {
fontFamily: theme.fontFamily,
fontSize: theme.fontSize.normal,
fontWeight: 'normal',
lineHeight: theme.createLength(theme.lineHeight),
wordWrap: 'break-word'
},
uppercase: {
textTransform: 'uppercase'
}
});
const alignStyles = StyleSheet.create({
center: {
textAlign: 'center'
},
left: {
textAlign: 'left'
},
right: {
textAlign: 'right'
}
});
const colorStyles = StyleSheet.create({
blue: {
color: theme.colors.blue
},
deepGray: {
color: theme.colors.deepGray
},
normal: {
color: theme.colors.textBlack
},
red: {
color: theme.colors.red
},
white: {
color: theme.colors.white
}
});
const fontStyles = StyleSheet.create({
normal: {
fontStyle: 'normal'
},
italic: {
fontStyle: 'italic'
}
});
const sizeStyles = StyleSheet.create({
small: {
fontSize: theme.fontSize.small
},
normal: {
fontSize: theme.fontSize.normal
},
large: {
fontSize: theme.fontSize.large
}
});
const weightStyles = StyleSheet.create({
normal: {
fontWeight: '400'
},
bold: {
fontWeight: 'bold'
}
});
export default AppText;

View File

@@ -1,41 +0,0 @@
import PropTypes from 'prop-types';
import React, { PureComponent } from 'react';
import { StyleSheet, View, ViewPropTypes } from 'react-native';
class AspectRatio extends PureComponent {
static displayName = 'AspectRatio';
static propTypes = {
children: PropTypes.any,
ratio: PropTypes.number,
style: ViewPropTypes.style
};
static defaultProps = {
ratio: 1
};
render() {
const { children, ratio, style } = this.props;
const percentage = 100 / ratio;
return (
<View style={[styles.root, style]}>
<View style={[styles.shim, { paddingBottom: `${percentage}%` }]} />
<View style={StyleSheet.absoluteFill}>{children}</View>
</View>
);
}
}
const styles = StyleSheet.create({
root: {
overflow: 'hidden'
},
shim: {
display: 'block',
width: '100%'
}
});
export default AspectRatio;

View File

@@ -1,53 +0,0 @@
import PropTypes from 'prop-types';
import { StyleSheet, View, ViewPropTypes } from 'react-native';
import React, { Component } from 'react';
import theme from './theme';
class GridView extends Component {
static displayName = 'GridView';
static propTypes = {
children: PropTypes.node,
hasGap: PropTypes.bool,
style: ViewPropTypes.style
};
render() {
const { children, hasGap, style, ...other } = this.props;
return (
<View {...other} style={[style, styles.root, hasGap && styles.hasGap]}>
{React.Children.map(children, child => {
return (
child &&
React.cloneElement(child, {
style: [child.props.style, styles.column, hasGap && styles.hasGapColumn]
})
);
})}
</View>
);
}
}
const styles = StyleSheet.create({
root: {
flexDirection: 'row'
},
/**
* 1. Distribute all space (rather than extra space)
* 2. Prevent wide content from forcing wider flex columns
*/
column: {
flexBasis: 0, // 1
minWidth: 0 // 2
},
hasGap: {
marginHorizontal: theme.createLength(theme.spaceX * -0.5, 'rem')
},
hasGapColumn: {
marginHorizontal: theme.createLength(theme.spaceX * 0.5, 'rem')
}
});
export default GridView;

View File

@@ -1,20 +0,0 @@
/* eslint-disable react/prop-types */
import { createElement } from 'react-native';
import React from 'react';
import styles from './styles';
const IconDirectMessage = props =>
createElement('svg', {
children: (
<g>
<path d="M43.34 14H12.66L28 27.946z" />
<path d="M51.392 14.789L30.018 34.22c-.009.008-.028.006-.039.012-.563.5-1.266.768-1.98.768-.72 0-1.442-.258-2.017-.78L4.609 14.79A3.957 3.957 0 0 0 3 18v37a1.998 1.998 0 0 0 2 2c.464 0 .924-.162 1.292-.473L19 46h30c2.243 0 4-1.757 4-4V18a3.96 3.96 0 0 0-1.608-3.211z" />
</g>
),
style: [styles.icon, props.style],
viewBox: '0 0 56 72'
});
IconDirectMessage.metadata = { height: 72, width: 56 };
export default IconDirectMessage;

View File

@@ -1,19 +0,0 @@
/* eslint-disable react/prop-types */
import { createElement } from 'react-native';
import React from 'react';
import styles from './styles';
const IconHeart = props =>
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" />
</g>
),
style: [styles.icon, props.style],
viewBox: '0 0 54 72'
});
IconHeart.metadata = { height: 72, width: 54 };
export default IconHeart;

View File

@@ -1,19 +0,0 @@
/* eslint-disable react/prop-types */
import { createElement } from 'react-native';
import React from 'react';
import styles from './styles';
const IconReply = props =>
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" />
</g>
),
style: [styles.icon, props.style],
viewBox: '0 0 62 72'
});
IconReply.metadata = { height: 72, width: 62 };
export default IconReply;

View File

@@ -1,19 +0,0 @@
/* eslint-disable react/prop-types */
import { createElement } from 'react-native';
import React from 'react';
import styles from './styles';
const IconRetweet = props =>
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" />
</g>
),
style: [styles.icon, props.style],
viewBox: '0 0 74 72'
});
IconRetweet.metadata = { height: 72, width: 74 };
export default IconRetweet;

View File

@@ -1,78 +0,0 @@
import IconReply from './IconReply';
import IconHeart from './IconHeart';
import IconRetweet from './IconRetweet';
import IconDirectMessage from './IconDirectMessage';
import PropTypes from 'prop-types';
import React from 'react';
import theme from './theme';
import { Text, View, ViewPropTypes, StyleSheet } from 'react-native';
const getIcon = (icon, highlighted) => {
switch (icon) {
case 'like':
return <IconHeart />;
case 'reply':
return <IconReply />;
case 'retweet':
return <IconRetweet />;
case 'directMessage':
return <IconDirectMessage />;
default:
return null;
}
};
export default class TweetAction extends React.Component {
static displayName = 'TweetAction';
static propTypes = {
count: PropTypes.number,
displayMode: PropTypes.oneOf(['like', 'reply', 'retweet', 'directMessage']),
highlighted: PropTypes.bool,
onPress: PropTypes.func,
style: ViewPropTypes.style
};
render() {
const { count, displayMode, highlighted, onPress, style } = this.props;
return (
<View accessibilityRole="button" onPress={onPress} style={[styles.root, style]}>
<Text
style={[
styles.inner,
displayMode === 'like' && highlighted && styles.likedColor,
displayMode === 'retweet' && highlighted && styles.retweetedColor
]}
>
{getIcon(displayMode, highlighted)}
{count > 0 ? <Text style={styles.count}>{count}</Text> : null}
</Text>
</View>
);
}
}
const styles = StyleSheet.create({
root: {
minHeight: theme.createLength(theme.lineHeight, 'rem'),
overflow: 'visible',
userSelect: 'none',
whiteSpace: 'nowrap'
},
inner: {
alignItems: 'center',
color: theme.colors.deepGray,
display: 'flex',
flexDirection: 'row'
},
count: {
marginLeft: '0.25em'
},
retweetedColor: {
color: theme.colors.green
},
likedColor: {
color: theme.colors.red
}
});

View File

@@ -1,52 +0,0 @@
import PropTypes from 'prop-types';
import TweetAction from './TweetAction';
import { View, ViewPropTypes, StyleSheet } from 'react-native';
import React, { PureComponent } from 'react';
const actionNames = ['reply', 'retweet', 'like', 'directMessage'];
export default class TweetActionsBar extends PureComponent {
static propTypes = {
actions: PropTypes.arrayOf(
PropTypes.shape({
count: PropTypes.number,
label: PropTypes.string,
highlighted: PropTypes.bool,
name: PropTypes.oneOf(actionNames).isRequired,
onPress: PropTypes.func
})
),
style: ViewPropTypes.style
};
render() {
const { actions, style } = this.props;
/* eslint-disable react/jsx-handler-names */
return (
<View style={[styles.root, style]}>
{actions.map((action, i) => (
<TweetAction
accessibilityLabel={actions.label}
count={action.count}
displayMode={action.name}
highlighted={action.highlighted}
key={i}
onPress={action.onPress}
style={styles.action}
/>
))}
</View>
);
}
}
const styles = StyleSheet.create({
root: {
flexDirection: 'row'
},
action: {
display: 'block',
marginRight: '10%'
}
});

View File

@@ -1,29 +0,0 @@
import AppText from './AppText';
import React from 'react';
import TweetTextPart from './TweetTextPart';
import { array, number, string } from 'prop-types';
class TweetText extends React.Component {
static displayName = 'TweetText';
static propTypes = {
displayMode: TweetTextPart.propTypes.displayMode,
lang: string,
numberOfLines: number,
textParts: array.isRequired
};
render() {
const { displayMode, lang, numberOfLines, textParts, ...other } = this.props;
return (
<AppText {...other} lang={lang} numberOfLines={numberOfLines}>
{textParts.map((part, i) => (
<TweetTextPart displayMode={displayMode} key={i} part={part} />
))}
</AppText>
);
}
}
export default TweetText;

View File

@@ -1,113 +0,0 @@
/* eslint-disable react/prop-types */
import { Image, StyleSheet, Text } from 'react-native';
import PropTypes from 'prop-types';
import React from 'react';
import theme from './theme';
const createTextEntity = ({ part }) => <Text>{`${part.prefix}${part.text}`}</Text>;
const createTwemojiEntity = ({ part }) => (
<Image
accessibilityLabel={part.text}
draggable={false}
source={{ uri: part.emoji }}
style={styles.twemoji}
/>
);
// @mention, #hashtag, $cashtag
const createSymbolEntity = ({ displayMode, part }) => {
const links = displayMode === 'links';
return (
<Text accessibilityRole={links ? 'link' : null} href={part.url} style={[links && styles.link]}>
{`${part.prefix}${part.text}`}
</Text>
);
};
// internal links
const createLinkEntity = ({ displayMode, part }) => {
const { displayUrl, linkRelation, url } = part;
const links = displayMode === 'links';
return (
<Text
accessibilityRole={links ? 'link' : null}
href={url}
rel={links ? linkRelation : null}
style={[links && styles.link]}
>
{displayUrl}
</Text>
);
};
// external links
const createExternalLinkEntity = ({ displayMode, part }) => {
const { displayUrl, linkRelation, url } = part;
const links = displayMode === 'links';
return (
<Text
accessibilityRole={links ? 'link' : null}
href={url}
rel={links ? linkRelation : null}
style={[links && styles.link]}
target="_blank"
>
{displayUrl}
</Text>
);
};
class TweetTextPart extends React.Component {
static displayName = 'TweetTextPart';
static propTypes = {
displayMode: PropTypes.oneOf(['links', 'no-links']),
part: PropTypes.object
};
static defaultProps = {
displayMode: 'links'
};
render() {
let renderer;
const { isEmoji, isEntity, isHashtag, isMention, isMedia, isUrl } = this.props.part;
if (isEmoji || isEntity || isUrl || isMedia) {
if (isUrl) {
renderer = createExternalLinkEntity;
} else if (isHashtag || isMention) {
renderer = createSymbolEntity;
} else if (isEmoji) {
renderer = createTwemojiEntity;
} else {
renderer = createLinkEntity;
}
} else {
renderer = createTextEntity;
}
return renderer(this.props);
}
}
const styles = StyleSheet.create({
link: {
color: theme.colors.blue,
textDecorationLine: 'none',
unicodeBidi: 'embed'
},
twemoji: {
display: 'inline-block',
height: '1.25em',
width: '1.25em',
paddingRight: '0.05em',
paddingLeft: '0.1em',
textAlignVertical: '-0.2em'
}
});
export default TweetTextPart;

View File

@@ -1,65 +0,0 @@
import AspectRatio from './AspectRatio';
import PropTypes from 'prop-types';
import { Image, StyleSheet, ViewPropTypes } from 'react-native';
import React, { PureComponent } from 'react';
import theme from './theme';
class UserAvatar extends PureComponent {
static displayName = 'UserAvatar';
static propTypes = {
accessibilityLabel: PropTypes.string,
circle: PropTypes.bool,
style: ViewPropTypes.style,
uri: PropTypes.string
};
static defaultProps = {
circle: false
};
render() {
const { accessibilityLabel, circle, style, uri } = this.props;
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}
</AspectRatio>
);
}
_handleLoad = () => {
this._imageRef && this._imageRef.setNativeProps(nativeProps);
};
_setImageRef = component => {
this._imageRef = component;
};
}
const nativeProps = { style: { backgroundColor: '#fff' } };
const styles = StyleSheet.create({
root: {
borderRadius: '0.35rem'
},
circle: {
borderRadius: '9999px'
},
image: {
backgroundColor: theme.colors.fadedGray,
display: 'block',
height: '100%',
width: '100%'
}
});
export default UserAvatar;

View File

@@ -1,52 +0,0 @@
import AppText from './AppText';
import PropTypes from 'prop-types';
import { StyleSheet, ViewPropTypes } from 'react-native';
import React, { PureComponent } from 'react';
class UserNames extends PureComponent {
static displayName = 'UserNames';
static propTypes = {
fullName: PropTypes.string,
layout: PropTypes.oneOf(['nowrap', 'stack']),
onPress: PropTypes.func,
screenName: PropTypes.string,
style: ViewPropTypes.style
};
static defaultProps = {
layout: 'nowrap'
};
render() {
const { fullName, layout, onPress, screenName, style, ...other } = this.props;
return (
<AppText
{...other}
color="deepGray"
numberOfLines={layout === 'nowrap' ? 1 : null}
onPress={onPress}
style={[styles.root, style]}
>
<AppText color="normal" weight="bold">
{fullName}
</AppText>
{layout === 'stack' ? ' \u000A' : ' '}
<AppText color="deepGray" style={styles.screenName}>{`@${screenName}`}</AppText>
</AppText>
);
}
}
const styles = StyleSheet.create({
root: {
display: 'inline-block'
},
screenName: {
unicodeBidi: 'embed',
writingDirection: 'ltr'
}
});
export default UserNames;

View File

@@ -1,144 +0,0 @@
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 } from 'react';
import theme from './theme';
export class Tweet extends Component {
static displayName = 'Tweet';
static propTypes = {
tweet: PropTypes.object.isRequired
};
render() {
const { tweet } = this.props;
const { id, lang, media, textParts, timestamp, user } = tweet;
const { fullName, profileImageUrl, screenName } = user;
return (
<View accessibilityRole="article" accessible style={styles.root}>
<GridView hasGap>
<View style={styles.avatarColumn}>
<View
accessibilityRole="link"
accessible
href={`/${screenName}`}
style={styles.avatarLink}
>
<UserAvatar style={styles.avatar} uri={profileImageUrl} />
</View>
</View>
<View style={styles.bodyColumn}>
<View style={styles.body}>
<View style={styles.row}>
<Text
accessibilityRole="link"
children={timestamp}
href={`/${screenName}/status/${id}`}
style={styles.timestamp}
/>
<UserNames fullName={fullName} screenName={screenName} />
</View>
<View accessibilityRole="heading" aria-level="4">
<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}
</View>
<TweetActionsBar
actions={[
{ name: 'reply', label: 'Reply' },
{
name: 'retweet',
label: 'Retweet',
count: tweet.retweet_count,
highlighted: tweet.retweeted
},
{
name: 'like',
label: 'Like',
count: tweet.favorite_count,
highlighted: tweet.favorited
},
{ name: 'directMessage', label: 'Direct Message' }
]}
style={styles.actionBar}
/>
</View>
</GridView>
</View>
);
}
}
const styles = StyleSheet.create({
root: {
paddingVertical: theme.createLength(theme.spaceY * 0.75, 'rem'),
paddingHorizontal: theme.createLength(theme.spaceX, 'rem')
},
avatarColumn: {
flexGrow: 1,
minWidth: 32
},
bodyColumn: {
flexGrow: 7
},
row: {
flexDirection: 'row',
justifyContent: 'space-between'
},
avatarLink: {
display: 'block',
flexShrink: 1,
flexGrow: 0,
width: '100%'
},
avatar: {
width: '100%'
},
body: {
marginTop: '-0.15rem'
},
timestamp: {
color: theme.colors.deepGray,
marginLeft: theme.createLength(theme.spaceX, 'rem'),
order: 1,
textDecorationLine: 'none',
whiteSpace: 'nowrap'
},
actionBar: {
marginTop: theme.createLength(theme.spaceY * 0.5, 'rem')
},
richContent: {
borderRadius: '0.35rem',
marginTop: theme.createLength(theme.spaceY * 0.5, 'rem'),
overflow: 'hidden'
},
media: {
...StyleSheet.absoluteFillObject,
margin: 'auto',
width: 'auto',
height: 'auto'
}
});
export default Tweet;

View File

@@ -1,15 +0,0 @@
import { StyleSheet } from 'react-native';
const styles = StyleSheet.create({
icon: {
display: 'inline-block',
fill: 'currentcolor',
height: '1.25em',
maxWidth: '100%',
position: 'relative',
userSelect: 'none',
textAlignVertical: 'text-bottom'
}
});
export default styles;

View File

@@ -1,40 +0,0 @@
const colors = {
blue: '#1B95E0',
lightBlue: '#71C9F8',
green: '#17BF63',
orange: '#F45D22',
purple: '#794BC4',
red: '#E0245E',
white: '#FFFFFF',
yellow: '#FFAD1F',
deepGray: '#657786',
fadedGray: '#E6ECF0',
faintGray: '#F5F8FA',
gray: '#AAB8C2',
lightGray: '#CCD6DD',
textBlack: '#14171A'
};
const fontSize = {
root: '14px',
// font scale
small: '0.85rem',
normal: '1rem',
large: '1.25rem'
};
const theme = {
colors,
fontFamily:
'-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Ubuntu, "Helvetica Neue", sans-serif, ' +
'"Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"', // emoji fonts
fontSize,
lineHeight: 1.3125,
spaceX: 0.6,
spaceY: 1.3125,
createLength(num, unit) {
return `${num}${unit}`;
}
};
export default theme;

View File

@@ -1,11 +1,13 @@
import Box from './Box';
import Dot from './Dot';
import Provider from './Provider';
import TextBox from './TextBox';
import { View } from 'react-native';
export default {
Box,
Dot,
Provider,
TextBox,
View
};

View File

@@ -1,4 +1,3 @@
/* eslint-disable react/prop-types */
import React from 'react';
import { Styles, View } from 'reactxp';

View File

@@ -1,4 +1,3 @@
/* eslint-disable react/prop-types */
import React from 'react';
import { Styles, View } from 'reactxp';

View File

@@ -1,4 +1,3 @@
/* eslint-disable react/prop-types */
import React from 'react';
import { object } from 'prop-types';
import { View } from 'reactxp';

View File

@@ -1,4 +1,3 @@
/* eslint-disable react/prop-types */
import styled from 'styled-components';
import View from './View';

View File

@@ -1,4 +1,3 @@
/* eslint-disable react/prop-types */
import classnames from 'classnames';
import React from 'react';
import View from './View';

View File

@@ -1,4 +1,3 @@
/* eslint-disable react/prop-types */
import React from 'react';
import View from './View';

View File

@@ -1,4 +1,3 @@
/* eslint-disable react/prop-types */
import React from 'react';
class View extends React.Component {

View File

@@ -1,4 +1,3 @@
/* eslint-disable react/prop-types */
import { withStyle } from 'styletron-react';
import View from './View';

View File

@@ -1,4 +1,3 @@
/* eslint-disable react/prop-types */
import { styled } from 'styletron-react';
const Dot = styled('div', ({ size, x, y, children, color }) => ({

View File

@@ -1,4 +1,3 @@
/* eslint-disable react/prop-types */
import React from 'react';
import { Client as Styletron } from 'styletron-engine-atomic';
import { Provider as StyletronProvider } from 'styletron-react';

View File

@@ -1,4 +1,3 @@
/* eslint-disable react/prop-types */
import { styled } from 'styletron-react';
const View = styled('div', ({ style }) => ({

View File

@@ -1,5 +1,6 @@
import App from './app/App';
import impl from './impl';
import TextTree from './cases/TextTree';
import Tree from './cases/Tree';
import SierpinskiTriangle from './cases/SierpinskiTriangle';
@@ -50,6 +51,13 @@ const tests = {
},
Provider: components.Provider,
sampleCount: 100
})),
'Mount text tree': createTestBlock(components => ({
benchmarkType: 'mount',
Component: TextTree,
getComponentProps: () => ({ breadth: 6, components, depth: 3, id: 0, wrap: 2 }),
Provider: components.Provider,
sampleCount: 50
}))
};

View File

@@ -12,6 +12,9 @@ module.exports = {
path: path.resolve(appDirectory, 'dist'),
filename: 'bundle.js'
},
optimization: {
minimize: process.env.NODE_ENV === 'production'
},
module: {
rules: [
{
@@ -20,7 +23,11 @@ module.exports = {
'style-loader',
{
loader: 'css-loader',
options: { modules: true, localIdentName: '[hash:base64:8]' }
options: {
modules: {
localIdentName: '[hash:base64:8]'
}
}
}
]
},
@@ -31,7 +38,7 @@ module.exports = {
loader: 'babel-loader',
options: {
cacheDirectory: false,
presets: babelPreset,
presets: [babelPreset],
plugins: ['styled-jsx/babel']
}
}

View File

@@ -0,0 +1,20 @@
const path = require('path');
const webpack = require('webpack');
module.exports = async ({ config, mode }) => {
config.module.rules.push({
test: /\.(gif|jpe?g|png|svg)$/,
use: {
loader: 'url-loader',
options: { name: '[name].[ext]' }
}
});
config.resolve.extensions = ['.web.js', '.js', '.json', '.web.jsx', '.jsx'];
config.resolve.alias = {
'react-native': 'react-native-web'
};
return config;
};

View File

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

View File

@@ -0,0 +1,48 @@
import { create } from '@storybook/theming';
// import centered from './decorator-centered';
import { addParameters, configure, addDecorator } from '@storybook/react';
// Option defaults:
addParameters({
options: {
storySort: (a, b) => {
const sectionA = a[1].id.split('-')[0];
const sectionB = b[1].id.split('-')[0];
return sectionB.localeCompare(sectionA);
},
theme: create({
base: 'light',
brandTitle: 'React Native for Web',
brandUrl: 'https://necolas.github.io/react-native-web'
// To control appearance:
// brandImage: 'http://url.of/some.svg',
}),
/**
* regex for finding the hierarchy separator
* @example:
* null - turn off hierarchy
* /\// - split by `/`
* /\./ - split by `.`
* /\/|\./ - split by `/` or `.`
* @type {Regex}
*/
hierarchySeparator: /\/|\./,
/**
* regex for finding the hierarchy root separator
* @example:
* null - turn off multiple hierarchy roots
* /\|/ - split by `|`
* @type {Regex}
*/
hierarchyRootSeparator: /\|/,
panelPosition: 'bottom'
}
});
// addDecorator(centered);
const context = require.context('../src', true, /\.stories\.(js|mdx)$/);
configure(context, module);

View File

@@ -3,9 +3,7 @@ import { StyleSheet, View } from 'react-native';
const styles = StyleSheet.create({
root: {
minHeight: '100vh',
maxWidth: 680,
marginHorizontal: 'auto'
maxWidth: '100%'
}
});

View File

@@ -0,0 +1,10 @@
module.exports = [
{
name: '@storybook/addon-docs/preset',
options: {
configureJSX: true,
babelOptions: {},
sourceLoaderOptions: null
}
}
];

View File

@@ -0,0 +1,7 @@
module.exports = function(api) {
api.cache(true);
return {
presets: ['module:metro-react-native-babel-preset'],
plugins: ['react-native-web']
};
};

View File

@@ -0,0 +1,23 @@
{
"private": true,
"name": "docs",
"version": "0.14.7",
"scripts": {
"build": "build-storybook --docs -o ./dist -c ./.storybook",
"start": "start-storybook --docs -p 9001 -c ./.storybook",
"release": "yarn build && git checkout gh-pages && rm -rf ../../docs && mv dist ../../docs && git add -A && git commit -m \"Deploy documentation\" && git push origin gh-pages && git checkout -"
},
"dependencies": {
"@storybook/addon-docs": "^5.3.9",
"@storybook/addon-options": "^5.3.9",
"@storybook/cli": "^5.3.9",
"@storybook/react": "^5.3.9",
"@storybook/theming": "^5.3.9",
"react-native-web": "0.14.7"
},
"devDependencies": {
"babel-plugin-react-native-web": "0.14.7",
"url-loader": "^3.0.0",
"webpack": "^4.41.5"
}
}

View File

@@ -0,0 +1,109 @@
import { Meta, Props } from '@storybook/addon-docs/blocks';
<Meta title="APIs|AppRegistry" />
# AppRegistry
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`.
## Methods
### getAppKeys()
Returns an array of all registered app keys
```js
const appKeys = AppRegistry.getAppKeys();
```
### getApplication(appKey, appParams)
A web-only method for server-side rendering to HTML and CSS. It returns an
object containing the given application's element and a function to get styles
once the element is rendered.
Additional props can be passed to the `getStyleElement` function, e.g., your CSP
policy may require a `nonce` to be set on style elements.
```js
const appKey = 'MyApp';
const appParams = { ... };
const { element, getStyleElement } = AppRegistry.getApplication(appKey, appParams);
```
### registerComponent(appKey, getComponent)
Register a component provider under the given appKey.
```js
const appKey = 'MyApp';
const getComponent = () => App;
AppRegistry.registerComponent(appKey, getComponent)
```
### registerConfig(config)
Register multiple applications. AppConfig type is:
```js
type AppConfig = {
appKey: string;
component: ComponentProvider;
run?: function
}
const config = [{
appKey: 'FirstApp',
component: () => FirstApp
}, {
appKey: 'SecondApp',
component: () => SecondApp
}];
AppRegistry.registerConfig(config)
```
### registerRunnable(appKey, run)
Register a custom render function for an application. The function will receive
the `appParameters` passed to `runApplication`.
```js
AppRegistry.registerRunnable('MyApp', (appParams) => { ... });
```
### runApplication(appKey, appParams)
Runs the application that was registered under `appKey`. The `appParameters`
must include the `rootTag` into which the application is rendered, and
optionally any `initialProps` or render callback. If the client should hydrate
server-rendered HTML, set `hydrate` to `true`.
```js
AppRegistry.runApplication('MyApp', {
callback: () => { console.log('React rendering has finished') },
hydrate: true,
initialProps: {},
rootTag: document.getElementById('react-root'),
})
```
### setComponentProviderInstrumentationHook(componentProvider)
```js
type setComponentProviderInstrumentationHook = (componentProvider: func) => Component;
```
### setWrapperComponentProvider(appParams)
```js
type setWrapperComponentProvider = (appParameters: object) => Component;
```
### unmountApplicationComponentAtRootTag(rootTag)
To "stop" an application when a view should be destroyed, call
`AppRegistry.unmountApplicationComponentAtRootTag` with the `rootTag` that was passed
into `runApplication`.

View File

@@ -0,0 +1,6 @@
export default {
title: 'APIs|AppState',
includeStories: []
};
export { default as stateChanges } from './examples/StateChanges';

View File

@@ -0,0 +1,46 @@
import { Meta, Props, Preview, Story } from '@storybook/addon-docs/blocks';
import * as Stories from './AppState.stories.js';
<Meta title="APIs|AppState" />
# AppState
AppState can tell you if the app is in the foreground or background, and notify
you when the state changes. States: `active` (the app is running in the
foreground), `background` (the app is running in the background, i.e., the user
has not focused the app's tab).
## Properties
### isAvailable
Determines whether the browser environment supports `AppState`.
### currentState
Returns the current state of the app: "active" or "background".
## Methods
### addEventListener(type, handler)
Add a handler to AppState changes by listening to the `change` event type and
providing the handler. The handler is called with the app state value.
```js
AppState.addEventListener('change', (currentState) => {});
```
### removeEventListener(type, handler)
Remove a handler by passing the `change` event type and the handler.
AppState.removeEventListener('change', handler);
## Example
<Preview withSource='none'>
<Story name="stateChanges">
<Stories.stateChanges />
</Story>
</Preview>

View File

@@ -0,0 +1,32 @@
import React from 'react';
import { AppState, Text, View } from 'react-native';
export default function StateChanges() {
const [state, updateState] = React.useState({
active: 0,
background: 0,
currentState: AppState.currentState
});
React.useEffect(() => {
const handleChange = nextState => {
updateState(previousState => ({
...previousState,
[nextState]: previousState[nextState] + 1
}));
};
AppState.addEventListener('change', handleChange);
return () => {
AppState.removeEventListener('change', handleChange);
};
}, []);
return (
<View>
<Text>Active count: {state.active}</Text>
<Text>Background count: {state.background}</Text>
<Text>Current state is: {state.currentState}</Text>
</View>
);
}

View File

@@ -0,0 +1,63 @@
import { Meta, Preview } from '@storybook/addon-docs/blocks';
import * as Stories from './examples';
<Meta title="APIs|Appearance" />
# Appearance
The Appearance module exposes information about the user's appearance
preferences, such as their preferred color scheme (light or dark). In
`react-native-web` this is achieved using the `prefers-color-scheme` media query.
## Methods
### getColorScheme()
You can use the Appearance module to determine if the user prefers a dark color
scheme:
```js
const colorScheme = Appearance.getColorScheme();
if (colorScheme === 'dark') {
// Use dark color scheme
}
```
Although the color scheme is available immediately, this may change (e.g.
scheduled color scheme change at sunrise or sunset). Any rendering logic or
styles that depend on the user preferred color scheme should try to call this
function on every render, rather than caching the value.
## Hooks
### useColorScheme
The `useColorScheme` React hook provides and subscribes to color scheme updates
from the Appearance module. The return value indicates the current user
preferred color scheme. The value may be updated later, either through direct
user action (e.g. theme selection in device settings) or on a schedule (e.g.
light and dark themes that follow the day/night cycle).
Supported color schemes:
- `'light'`: The user prefers a light color theme.
- `'dark'`: The user prefers a dark color theme.
- `null`: The user has not indicated a preferred color theme.
```js
import * as React from 'react';
import { Text, useColorScheme } from 'react-native';
const MyComponent = () => {
const colorScheme = useColorScheme();
return <Text>Your color scheme is: {colorScheme}</Text>;
};
```
This produces:
<Preview withSource="none">
<Story name="colorScheme">
<Stories.colorSchemeText />
</Story>
</Preview>

View File

@@ -0,0 +1,7 @@
import * as React from 'react';
import { Text, useColorScheme } from 'react-native';
export default function ColorSchemeText() {
const colorScheme = useColorScheme();
return <Text>Your color scheme is: {colorScheme}</Text>;
}

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