mirror of
https://github.com/zhigang1992/react-native-web.git
synced 2026-03-31 22:42:37 +08:00
Compare commits
355 Commits
0.9.2
...
feat/logbo
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7b021c56f0 | ||
|
|
6624a70cca | ||
|
|
5806b249dd | ||
|
|
1048f7ce3e | ||
|
|
18f5a33c0d | ||
|
|
07e578edb8 | ||
|
|
d2e6c29e25 | ||
|
|
03897d32be | ||
|
|
b8fddcf6b1 | ||
|
|
d9c755dff0 | ||
|
|
63c39454de | ||
|
|
89be8a9f8b | ||
|
|
b4e53e8cd3 | ||
|
|
cea4172efb | ||
|
|
a2d72ee89c | ||
|
|
2428b6c6fc | ||
|
|
0aa77685aa | ||
|
|
663458713c | ||
|
|
3118315140 | ||
|
|
09c2f1975b | ||
|
|
18d5d449a7 | ||
|
|
933bd138ce | ||
|
|
c2019a9881 | ||
|
|
78174d7b48 | ||
|
|
38fd574984 | ||
|
|
5b7a6bc30a | ||
|
|
d97a1ca567 | ||
|
|
6bd41a622a | ||
|
|
108366a724 | ||
|
|
bf2e10d482 | ||
|
|
faf7fa3374 | ||
|
|
df14c7278a | ||
|
|
b15e8784c4 | ||
|
|
583e16fa8d | ||
|
|
b4322734a2 | ||
|
|
bdcb4de7dc | ||
|
|
d8ee51e326 | ||
|
|
aad0c88cea | ||
|
|
6d04e7243e | ||
|
|
ba5e9e3079 | ||
|
|
06d3cadf05 | ||
|
|
72bfe499c5 | ||
|
|
92ac1f94c5 | ||
|
|
5edba02319 | ||
|
|
2276e17310 | ||
|
|
222fa3490e | ||
|
|
0fb3036f31 | ||
|
|
7bc6fc8347 | ||
|
|
c60417ab34 | ||
|
|
af0d80a808 | ||
|
|
12e91a35a4 | ||
|
|
376ccc31b1 | ||
|
|
4a70300b08 | ||
|
|
7ab04987f0 | ||
|
|
f52a9bcfd2 | ||
|
|
74acb21aa8 | ||
|
|
1e1236597a | ||
|
|
e9d81afbd4 | ||
|
|
9ed9231b04 | ||
|
|
d5ab3770c0 | ||
|
|
397de88137 | ||
|
|
bb8a1b1455 | ||
|
|
214b296c11 | ||
|
|
a7df78afbe | ||
|
|
c6425a0048 | ||
|
|
8add92f776 | ||
|
|
9a0acc5464 | ||
|
|
a31c4c65d0 | ||
|
|
834bd5b98b | ||
|
|
de2a66c694 | ||
|
|
9ed0c407a9 | ||
|
|
7a8a70b948 | ||
|
|
67a3d78799 | ||
|
|
77bdb9086e | ||
|
|
7fc17d01cc | ||
|
|
b8283245cf | ||
|
|
75c5a90563 | ||
|
|
3233d0ffe9 | ||
|
|
251cdfb220 | ||
|
|
7c46a3667e | ||
|
|
5a15dcae66 | ||
|
|
af0ae004ff | ||
|
|
08f722ac86 | ||
|
|
6bf69c0015 | ||
|
|
28f51fa492 | ||
|
|
5426762ed4 | ||
|
|
10de987785 | ||
|
|
72638d028b | ||
|
|
097cd31a90 | ||
|
|
96dcce0261 | ||
|
|
1497bb4d72 | ||
|
|
99e6d7137f | ||
|
|
8c391604ba | ||
|
|
7ef070195b | ||
|
|
728e20ff1f | ||
|
|
824cca1972 | ||
|
|
cfe36d780e | ||
|
|
5dda71c2a6 | ||
|
|
972317c17c | ||
|
|
0901be6e5c | ||
|
|
52f903229e | ||
|
|
3230713d6b | ||
|
|
53dd03d83b | ||
|
|
c2d4fd6d77 | ||
|
|
fc78cb06fd | ||
|
|
cd9be22947 | ||
|
|
324995ec2b | ||
|
|
cecacbc3ac | ||
|
|
ff6109ec1c | ||
|
|
aa647567ad | ||
|
|
e9933b107a | ||
|
|
4b4163f630 | ||
|
|
ac945761e6 | ||
|
|
7ab3cf0d42 | ||
|
|
37ff6b4888 | ||
|
|
cf7d5e9b07 | ||
|
|
0ffbf66b1a | ||
|
|
a7da67cd09 | ||
|
|
603adc46ab | ||
|
|
88f5dedffd | ||
|
|
7e724b279d | ||
|
|
204c432f66 | ||
|
|
66751502a3 | ||
|
|
4146b16a68 | ||
|
|
fe013b30dc | ||
|
|
fa6e269832 | ||
|
|
ee1cb490d6 | ||
|
|
f4e8b6b194 | ||
|
|
7e616f6d46 | ||
|
|
8952eccf86 | ||
|
|
654f65e3e0 | ||
|
|
d94a14dc8c | ||
|
|
8d37fde5ee | ||
|
|
fdf53df301 | ||
|
|
999c2ad122 | ||
|
|
35236a3cc2 | ||
|
|
2724ca0293 | ||
|
|
fc443c5abd | ||
|
|
7d440c74f4 | ||
|
|
ebc3882661 | ||
|
|
b28d2a8214 | ||
|
|
94ecc46ece | ||
|
|
5b40b9d6aa | ||
|
|
840a2e91d4 | ||
|
|
96d8649197 | ||
|
|
a2cccaf528 | ||
|
|
51ac083d56 | ||
|
|
9dbe17fa6a | ||
|
|
f4a481bb4f | ||
|
|
5287044f40 | ||
|
|
92737d33f4 | ||
|
|
18427aae50 | ||
|
|
a7ab961d95 | ||
|
|
c8b73fa4e4 | ||
|
|
3d53273fe7 | ||
|
|
5b7f584f19 | ||
|
|
88c664fa0f | ||
|
|
dff62b3af6 | ||
|
|
032279e5f7 | ||
|
|
d30d65b29d | ||
|
|
dee418bb93 | ||
|
|
1cc7e6cbf4 | ||
|
|
16c0109df6 | ||
|
|
287251a06a | ||
|
|
e670e8135b | ||
|
|
e22f0bebb3 | ||
|
|
f16c2c45ea | ||
|
|
fc033a3161 | ||
|
|
8fa9fc5cc5 | ||
|
|
e0412acb94 | ||
|
|
0b31a8b096 | ||
|
|
b10711bddd | ||
|
|
5334a4f0d8 | ||
|
|
df1b62cd45 | ||
|
|
4763cc71c6 | ||
|
|
aa8593ba97 | ||
|
|
3c9cc66264 | ||
|
|
1ad1693039 | ||
|
|
924e891f58 | ||
|
|
fced06aeaa | ||
|
|
21d60a3e9a | ||
|
|
f4ff2e8891 | ||
|
|
f43ce41f0d | ||
|
|
afb8d3b7fb | ||
|
|
e4ed0fd3c8 | ||
|
|
297cda7901 | ||
|
|
8cf00a5c5a | ||
|
|
3fd90b9252 | ||
|
|
9e7c37128e | ||
|
|
41e6dca1e3 | ||
|
|
02a3640f95 | ||
|
|
290a2a76ce | ||
|
|
1b3c31ff6a | ||
|
|
d4b9f35d33 | ||
|
|
3ac0b96498 | ||
|
|
33f1c3566c | ||
|
|
d57fb6eb01 | ||
|
|
ae94551ac5 | ||
|
|
1af0218d26 | ||
|
|
d554d83727 | ||
|
|
25dd43e960 | ||
|
|
c4a2a6d4a3 | ||
|
|
ad674e4b4f | ||
|
|
304e8a83ab | ||
|
|
ac71506610 | ||
|
|
847870e4b3 | ||
|
|
845c2726b2 | ||
|
|
9d76d58891 | ||
|
|
f54c957199 | ||
|
|
425102c16e | ||
|
|
0c350d2678 | ||
|
|
eaa24ae91d | ||
|
|
24801cb5da | ||
|
|
41e4f05eb0 | ||
|
|
72ede16c9c | ||
|
|
7ec9b075a1 | ||
|
|
89bc074327 | ||
|
|
add0e0cb7e | ||
|
|
8900cea576 | ||
|
|
6c682bbb92 | ||
|
|
ece4e95d4d | ||
|
|
f9eadc10d2 | ||
|
|
cc5a5d7d27 | ||
|
|
800f24466e | ||
|
|
5a12430b50 | ||
|
|
fbdbfa5484 | ||
|
|
920211b998 | ||
|
|
c0c7a18aca | ||
|
|
250ee3c234 | ||
|
|
6ce88e6db0 | ||
|
|
e810f1fd2b | ||
|
|
d2e8d616e2 | ||
|
|
1cce9a1668 | ||
|
|
96a23c1c21 | ||
|
|
ebbade3a6f | ||
|
|
ef770d4bd1 | ||
|
|
a7ddd7b9ac | ||
|
|
8f5e7d4e14 | ||
|
|
45f94eb43d | ||
|
|
5092be40ac | ||
|
|
b144992f51 | ||
|
|
9d5a41c702 | ||
|
|
11d00ff111 | ||
|
|
8908db7690 | ||
|
|
29146fe5bc | ||
|
|
33dc3cb018 | ||
|
|
4f5de8d016 | ||
|
|
cddc2e346b | ||
|
|
fa09df8b59 | ||
|
|
be5106f5d3 | ||
|
|
37ca236d09 | ||
|
|
950bfd039c | ||
|
|
39d2e18ccf | ||
|
|
e9f68e380b | ||
|
|
2ce434e8f8 | ||
|
|
3eeda686b1 | ||
|
|
70e3ea8b57 | ||
|
|
cc99391f9d | ||
|
|
27713bd8cc | ||
|
|
801937748b | ||
|
|
9cbe387d9f | ||
|
|
c1459d7b21 | ||
|
|
36dacb2052 | ||
|
|
b732cec83e | ||
|
|
ad78fc7a38 | ||
|
|
33e54c755b | ||
|
|
74a36a2a4e | ||
|
|
8d1f5afead | ||
|
|
763e2d4001 | ||
|
|
f507410ab4 | ||
|
|
97372d7e4c | ||
|
|
9872c97169 | ||
|
|
d50f6304dc | ||
|
|
330895534d | ||
|
|
0e302a50d2 | ||
|
|
f048d848a1 | ||
|
|
c68b532696 | ||
|
|
d4417e93a3 | ||
|
|
9f860b8dfc | ||
|
|
29be779f77 | ||
|
|
2a418bed0c | ||
|
|
5e9449e893 | ||
|
|
67979b7282 | ||
|
|
3d3ea9aeed | ||
|
|
69bd0f631d | ||
|
|
9ce2b5bf0c | ||
|
|
cf7b020c5d | ||
|
|
49edcb291e | ||
|
|
6a84d74185 | ||
|
|
282cb34054 | ||
|
|
421cb095f7 | ||
|
|
0c08ba3a7d | ||
|
|
e4c3a21c42 | ||
|
|
34427897f3 | ||
|
|
63868b492d | ||
|
|
8ce5750d34 | ||
|
|
eb77062608 | ||
|
|
b6fc6f228e | ||
|
|
6c725357ff | ||
|
|
dce5b7321d | ||
|
|
52ca784680 | ||
|
|
244b0e4425 | ||
|
|
21c3931b69 | ||
|
|
e696e637bd | ||
|
|
b62a7bf44d | ||
|
|
69d1da4560 | ||
|
|
8925bf76af | ||
|
|
77d4bd8a97 | ||
|
|
4040151ee6 | ||
|
|
000b92e707 | ||
|
|
d5f5dbccdb | ||
|
|
79456d5920 | ||
|
|
2d1e303a6a | ||
|
|
209ff1fa40 | ||
|
|
34d8160a43 | ||
|
|
ada5651be2 | ||
|
|
9fe9d3c68a | ||
|
|
1e202b6bd5 | ||
|
|
2b77bfd853 | ||
|
|
d0ac55aa4f | ||
|
|
66dd1bd9ef | ||
|
|
6add18c6f0 | ||
|
|
30d7c31b65 | ||
|
|
f7e6b43422 | ||
|
|
4b3f6efb21 | ||
|
|
85e098deec | ||
|
|
c949b0145a | ||
|
|
86b4cf5a51 | ||
|
|
1b7ce4eec6 | ||
|
|
8c8978ff76 | ||
|
|
513b5de881 | ||
|
|
145f80409d | ||
|
|
6d92cc5ec3 | ||
|
|
ec6458c09d | ||
|
|
a84c2ac95e | ||
|
|
75db0e9183 | ||
|
|
4b9a5fd8b4 | ||
|
|
b6be677db9 | ||
|
|
91c9457392 | ||
|
|
006d315a1a | ||
|
|
220eb79357 | ||
|
|
5db9a765b0 | ||
|
|
931d666fcc | ||
|
|
40c433c6df | ||
|
|
9888c2a3c6 | ||
|
|
3fa18becc7 | ||
|
|
aafeb0adad | ||
|
|
89468b7d6e | ||
|
|
f66af5e04d | ||
|
|
2363524fa7 | ||
|
|
5855e55615 | ||
|
|
5033e12d18 | ||
|
|
d6e8530f4d | ||
|
|
ad188a7ad6 | ||
|
|
bfaeae904e |
43
.eslintrc
43
.eslintrc
@@ -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"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
7
.github/CONTRIBUTING.md
vendored
7
.github/CONTRIBUTING.md
vendored
@@ -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
13
.github/workflows/compressed-size.yml
vendored
Normal 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 }}"
|
||||
@@ -1,7 +1,7 @@
|
||||
language: node_js
|
||||
|
||||
node_js:
|
||||
- "8"
|
||||
- "10"
|
||||
|
||||
before_install:
|
||||
# Install Yarn
|
||||
|
||||
1
.watchmanconfig
Normal file
1
.watchmanconfig
Normal file
@@ -0,0 +1 @@
|
||||
{}
|
||||
111
README.md
111
README.md
@@ -2,12 +2,10 @@
|
||||
|
||||
[![npm version][package-badge]][package-url] [![Build Status][ci-badge]][ci-url] [](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 don’t 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 don’t 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
7
babel.config.js
Normal file
@@ -0,0 +1,7 @@
|
||||
module.exports = function(api) {
|
||||
api.cache(true);
|
||||
|
||||
return {
|
||||
presets: ['./scripts/babel/preset']
|
||||
};
|
||||
};
|
||||
88
package.json
88
package.json
@@ -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/*"
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
});
|
||||
|
||||
@@ -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))
|
||||
])
|
||||
)
|
||||
]);
|
||||
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
@@ -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` |
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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} />
|
||||
);
|
||||
|
||||
36
packages/benchmarks/src/cases/TextTree.js
Normal file
36
packages/benchmarks/src/cases/TextTree.js
Normal 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;
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
/* eslint-disable react/prop-types */
|
||||
import React from 'react';
|
||||
import View from './View';
|
||||
import { StyleSheet } from 'aphrodite';
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
/* eslint-disable react/prop-types */
|
||||
import React from 'react';
|
||||
import { css, StyleSheet } from 'aphrodite';
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
/* eslint-disable react/prop-types */
|
||||
import classnames from 'classnames';
|
||||
import React from 'react';
|
||||
import View from './View';
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
/* eslint-disable react/prop-types */
|
||||
import classnames from 'classnames';
|
||||
import React from 'react';
|
||||
import styles from './view-styles.css';
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
/* eslint-disable react/prop-types */
|
||||
import React from 'react';
|
||||
import View from './View';
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
/* eslint-disable react/prop-types */
|
||||
import React from 'react';
|
||||
import { css } from 'emotion';
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
/* eslint-disable react/prop-types */
|
||||
import { css } from 'emotion';
|
||||
import React from 'react';
|
||||
|
||||
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -1,2 +0,0 @@
|
||||
import View from './View';
|
||||
export default View;
|
||||
@@ -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;
|
||||
@@ -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
|
||||
};
|
||||
@@ -1,4 +1,3 @@
|
||||
/* eslint-disable react/prop-types */
|
||||
import React from 'react';
|
||||
import View from './View';
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
/* eslint-disable react/prop-types */
|
||||
import React from 'react';
|
||||
|
||||
const Dot = ({ size, x, y, children, color }) => (
|
||||
|
||||
@@ -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
|
||||
)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
@@ -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);
|
||||
@@ -1,2 +0,0 @@
|
||||
import View from './View';
|
||||
export default View;
|
||||
@@ -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);
|
||||
@@ -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
|
||||
};
|
||||
@@ -1,4 +1,3 @@
|
||||
/* eslint-disable react/prop-types */
|
||||
import { createComponent } from 'react-fela';
|
||||
|
||||
const Dot = createComponent(
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
/* eslint-disable react/prop-types */
|
||||
import React from 'react';
|
||||
import { createRenderer } from 'fela';
|
||||
import { Provider as FelaProvider } from 'react-fela';
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
/* eslint-disable react/prop-types */
|
||||
import { createComponent } from 'react-fela';
|
||||
|
||||
const View = createComponent(
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
/* eslint-disable react/prop-types */
|
||||
import classnames from 'classnames';
|
||||
import injectSheet from 'react-jss';
|
||||
import React from 'react';
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
/* eslint-disable react/prop-types */
|
||||
import injectSheet from 'react-jss';
|
||||
import React from 'react';
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
/* eslint-disable react/prop-types */
|
||||
import classnames from 'classnames';
|
||||
import injectSheet from 'react-jss';
|
||||
import React from 'react';
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
/* eslint-disable react/prop-types */
|
||||
import React from 'react';
|
||||
import { StyleSheet, View } from 'react-native';
|
||||
|
||||
|
||||
@@ -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', {
|
||||
|
||||
38
packages/benchmarks/src/implementations/react-native-web/TextBox.js
vendored
Normal file
38
packages/benchmarks/src/implementations/react-native-web/TextBox.js
vendored
Normal 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;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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
|
||||
}
|
||||
});
|
||||
@@ -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%'
|
||||
}
|
||||
});
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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
|
||||
};
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
/* eslint-disable react/prop-types */
|
||||
import React from 'react';
|
||||
import { Styles, View } from 'reactxp';
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
/* eslint-disable react/prop-types */
|
||||
import React from 'react';
|
||||
import { Styles, View } from 'reactxp';
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
/* eslint-disable react/prop-types */
|
||||
import React from 'react';
|
||||
import { object } from 'prop-types';
|
||||
import { View } from 'reactxp';
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
/* eslint-disable react/prop-types */
|
||||
import styled from 'styled-components';
|
||||
import View from './View';
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
/* eslint-disable react/prop-types */
|
||||
import classnames from 'classnames';
|
||||
import React from 'react';
|
||||
import View from './View';
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
/* eslint-disable react/prop-types */
|
||||
import React from 'react';
|
||||
import View from './View';
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
/* eslint-disable react/prop-types */
|
||||
import React from 'react';
|
||||
|
||||
class View extends React.Component {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
/* eslint-disable react/prop-types */
|
||||
import { withStyle } from 'styletron-react';
|
||||
import View from './View';
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
/* eslint-disable react/prop-types */
|
||||
import { styled } from 'styletron-react';
|
||||
|
||||
const Dot = styled('div', ({ size, x, y, children, color }) => ({
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
/* eslint-disable react/prop-types */
|
||||
import { styled } from 'styletron-react';
|
||||
|
||||
const View = styled('div', ({ style }) => ({
|
||||
|
||||
@@ -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
|
||||
}))
|
||||
};
|
||||
|
||||
|
||||
@@ -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']
|
||||
}
|
||||
}
|
||||
|
||||
20
packages/docs/.storybook/_webpack.config.js
Normal file
20
packages/docs/.storybook/_webpack.config.js
Normal 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;
|
||||
};
|
||||
1
packages/docs/.storybook/addons.js
Normal file
1
packages/docs/.storybook/addons.js
Normal file
@@ -0,0 +1 @@
|
||||
// import '@storybook/addon-options/register';
|
||||
48
packages/docs/.storybook/config.js
Normal file
48
packages/docs/.storybook/config.js
Normal 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);
|
||||
@@ -3,9 +3,7 @@ import { StyleSheet, View } from 'react-native';
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
root: {
|
||||
minHeight: '100vh',
|
||||
maxWidth: 680,
|
||||
marginHorizontal: 'auto'
|
||||
maxWidth: '100%'
|
||||
}
|
||||
});
|
||||
|
||||
10
packages/docs/.storybook/presets.js
Normal file
10
packages/docs/.storybook/presets.js
Normal file
@@ -0,0 +1,10 @@
|
||||
module.exports = [
|
||||
{
|
||||
name: '@storybook/addon-docs/preset',
|
||||
options: {
|
||||
configureJSX: true,
|
||||
babelOptions: {},
|
||||
sourceLoaderOptions: null
|
||||
}
|
||||
}
|
||||
];
|
||||
7
packages/docs/babel.config.js
Normal file
7
packages/docs/babel.config.js
Normal file
@@ -0,0 +1,7 @@
|
||||
module.exports = function(api) {
|
||||
api.cache(true);
|
||||
return {
|
||||
presets: ['module:metro-react-native-babel-preset'],
|
||||
plugins: ['react-native-web']
|
||||
};
|
||||
};
|
||||
23
packages/docs/package.json
Normal file
23
packages/docs/package.json
Normal 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"
|
||||
}
|
||||
}
|
||||
109
packages/docs/src/apis/AppRegistry/AppRegistry.stories.mdx
Normal file
109
packages/docs/src/apis/AppRegistry/AppRegistry.stories.mdx
Normal 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`.
|
||||
6
packages/docs/src/apis/AppState/AppState.stories.js
Normal file
6
packages/docs/src/apis/AppState/AppState.stories.js
Normal file
@@ -0,0 +1,6 @@
|
||||
export default {
|
||||
title: 'APIs|AppState',
|
||||
includeStories: []
|
||||
};
|
||||
|
||||
export { default as stateChanges } from './examples/StateChanges';
|
||||
46
packages/docs/src/apis/AppState/AppState.stories.mdx
Normal file
46
packages/docs/src/apis/AppState/AppState.stories.mdx
Normal 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>
|
||||
32
packages/docs/src/apis/AppState/examples/StateChanges.js
Normal file
32
packages/docs/src/apis/AppState/examples/StateChanges.js
Normal 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>
|
||||
);
|
||||
}
|
||||
63
packages/docs/src/apis/Appearance/Appearance.stories.mdx
Normal file
63
packages/docs/src/apis/Appearance/Appearance.stories.mdx
Normal 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>
|
||||
@@ -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
Reference in New Issue
Block a user