Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
56563f13b3 | ||
|
|
0a08879d70 | ||
|
|
b890969b1e | ||
|
|
3bc5b180b1 | ||
|
|
5fbe29903b | ||
|
|
7cc3ba99e0 | ||
|
|
77167b02ee | ||
|
|
aed1c76576 | ||
|
|
8187e9153c | ||
|
|
c98a6fbde1 | ||
|
|
e1032e1d09 | ||
|
|
0c2f3fe145 | ||
|
|
329f059ba9 | ||
|
|
2d8ec5eca7 | ||
|
|
6edb671e2d | ||
|
|
6d78b75a10 | ||
|
|
a0c3b426de | ||
|
|
9576657b57 | ||
|
|
dd9bbb4bca | ||
|
|
57adecc36e | ||
|
|
5526533f51 | ||
|
|
626f828d54 | ||
|
|
a8f11d7115 | ||
|
|
074069e465 | ||
|
|
2b7dd4650f | ||
|
|
162d12cfa4 | ||
|
|
504fa60168 | ||
|
|
0203f87ea3 | ||
|
|
2f6e7336cb | ||
|
|
19f922aa80 | ||
|
|
480b5c9e2e | ||
|
|
da7ac11c53 | ||
|
|
4f87ec5ce7 | ||
|
|
8d65367fbc | ||
|
|
54026024cc | ||
|
|
2d2252cd50 | ||
|
|
245a5b8e8c | ||
|
|
36c1064033 | ||
|
|
27a67c2434 | ||
|
|
5f8c0613fe | ||
|
|
8497b5a66f | ||
|
|
65a3c07cfe | ||
|
|
371aeceb72 | ||
|
|
072390ec5c | ||
|
|
9aefd6bd6e | ||
|
|
fe0143eb20 | ||
|
|
4382c0e8f4 | ||
|
|
88e0bbc469 | ||
|
|
a57353b2b4 | ||
|
|
75df3b537a | ||
|
|
9ba4697f02 | ||
|
|
a008704b51 | ||
|
|
eb248e0b58 | ||
|
|
8c5626cd87 | ||
|
|
94671df753 | ||
|
|
bb708769d4 | ||
|
|
ed0ca71be0 | ||
|
|
127b3292c1 | ||
|
|
8cc7f7f99a | ||
|
|
af8a6a44b2 | ||
|
|
4b420cc095 | ||
|
|
52abc759ff | ||
|
|
f3a165db4f | ||
|
|
eab390aecb | ||
|
|
f8f68176d5 | ||
|
|
8d07df4a22 | ||
|
|
3643c127a8 | ||
|
|
677f96c60e | ||
|
|
320a9207f4 | ||
|
|
934e7b9afd | ||
|
|
d2f82b1dfd | ||
|
|
f128269da7 | ||
|
|
c27e5198e2 | ||
|
|
debca6d24f | ||
|
|
2cd02d94ff | ||
|
|
46c6cde947 | ||
|
|
6debfce374 | ||
|
|
6f17dba39b | ||
|
|
4b28a847e6 | ||
|
|
3bfa90e433 | ||
|
|
febc03a38b | ||
|
|
a0168a8c62 | ||
|
|
c1f90c1ecf | ||
|
|
5f91d404e1 | ||
|
|
5de0796126 | ||
|
|
ed9b8c8b3b | ||
|
|
1ca1a44a07 | ||
|
|
b888e8db40 | ||
|
|
0b5952a454 | ||
|
|
ee82a195f7 | ||
|
|
81fdf3e532 | ||
|
|
16ddb1962a | ||
|
|
059e605e49 | ||
|
|
cf617640f3 | ||
|
|
dd7945ae37 | ||
|
|
cc96962e3d | ||
|
|
ec82ffa52b | ||
|
|
c5c25c15ea | ||
|
|
24689006ab | ||
|
|
e76e60f88d | ||
|
|
5a2d2007a4 | ||
|
|
d9bd445940 | ||
|
|
b4100b8332 | ||
|
|
966a3bbc66 | ||
|
|
5fc2d67ee5 | ||
|
|
d64ac20119 | ||
|
|
0f3ea9fb8c | ||
|
|
f4c7bb1103 | ||
|
|
1aa29ceaf2 | ||
|
|
9c32a7a940 | ||
|
|
ade571065e | ||
|
|
3d0cd480d2 | ||
|
|
deaef94471 | ||
|
|
26c4be62c8 | ||
|
|
b18d73b568 | ||
|
|
291c8ff9ec | ||
|
|
51596f8674 | ||
|
|
ede5fa7b39 | ||
|
|
67746fea2f | ||
|
|
621a2c486f | ||
|
|
76a9baaf2f | ||
|
|
e0e6fbfa8c | ||
|
|
3b7bffa2a1 | ||
|
|
a4e64196bc | ||
|
|
65692b7235 | ||
|
|
8d1e02b8bd | ||
|
|
869ff92dbc | ||
|
|
bce7b9c638 | ||
|
|
65713992c4 | ||
|
|
12d5f0d6f4 | ||
|
|
f0dd9fb358 | ||
|
|
261f9434e5 | ||
|
|
8460db57bc | ||
|
|
ca38908423 | ||
|
|
3388d8fe79 | ||
|
|
9eb5151bd2 | ||
|
|
9d96d00163 | ||
|
|
758ec76cb6 | ||
|
|
05b17a811e | ||
|
|
5786a05e9e | ||
|
|
324d154cf7 | ||
|
|
5153ce0a03 | ||
|
|
3be2b1d966 | ||
|
|
0623371814 | ||
|
|
76e37c4423 | ||
|
|
8bd1cb8cce | ||
|
|
91c8362176 | ||
|
|
decf35c271 | ||
|
|
3f5fcadbd5 | ||
|
|
96277ca3f5 | ||
|
|
0f14933948 | ||
|
|
dc01ecbc98 | ||
|
|
5c0805b071 | ||
|
|
a2c51b3b28 | ||
|
|
e9735556f6 | ||
|
|
fa07736ee1 | ||
|
|
f5d68f6ecb | ||
|
|
bc28a35bda | ||
|
|
7bfc1baf7f | ||
|
|
abce124198 | ||
|
|
5cad2e9370 | ||
|
|
c084793e91 | ||
|
|
41a88c3eb1 | ||
|
|
f552495e7f | ||
|
|
7232b1bbc7 | ||
|
|
672b77f355 | ||
|
|
c9f5d229db | ||
|
|
12492d8d94 | ||
|
|
b9dc29bcb3 | ||
|
|
eeb0adca43 | ||
|
|
28fb229266 | ||
|
|
4daca092d2 | ||
|
|
0487c55c25 | ||
|
|
1d072076db | ||
|
|
7750db05e6 | ||
|
|
08d1bc8c9f | ||
|
|
cfcf604b3d | ||
|
|
309326db2e | ||
|
|
c483db1b88 | ||
|
|
abdd0e09b3 | ||
|
|
a86e6b76fb | ||
|
|
f83675d191 | ||
|
|
39230000de | ||
|
|
1e1efce69b | ||
|
|
70624dc347 | ||
|
|
eb402d8c7d | ||
|
|
5ebe0ed717 | ||
|
|
a5e9f83a0a | ||
|
|
57a6a02dff | ||
|
|
0d636a017d | ||
|
|
4d817245f7 | ||
|
|
e2d9ddce4c | ||
|
|
48af214216 | ||
|
|
2fe1ac2a83 | ||
|
|
2424a215e0 | ||
|
|
f5d8e4d6e0 | ||
|
|
68f1a223fb | ||
|
|
51ccdfa36a | ||
|
|
e163df3567 | ||
|
|
a303a42e28 | ||
|
|
2afeb8fbe6 | ||
|
|
56059e92df | ||
|
|
5d20b9065d | ||
|
|
fd4e75644f | ||
|
|
6e2e02ab08 | ||
|
|
f309540f69 | ||
|
|
b489c9aa43 | ||
|
|
5b5cadeb30 | ||
|
|
59b974eafb | ||
|
|
50d5f86bf8 | ||
|
|
c1a0a72275 | ||
|
|
94caefa9c2 | ||
|
|
b82ac9bf07 | ||
|
|
e21fb91786 | ||
|
|
0f5190e9f3 | ||
|
|
331e4a96e9 | ||
|
|
2d66e10ec4 | ||
|
|
3aec8ee72d | ||
|
|
205a2c0bfc | ||
|
|
2ddf3d942d | ||
|
|
a91f44d7fd | ||
|
|
6e9ceaa348 | ||
|
|
6cd0709bc0 | ||
|
|
3cef3010e6 | ||
|
|
1d452f3e4d | ||
|
|
c933087567 | ||
|
|
9edad17a15 | ||
|
|
ffa7dbcbf1 | ||
|
|
a8211e32d2 | ||
|
|
deba13f698 | ||
|
|
3309f6da80 | ||
|
|
554f23276b | ||
|
|
aefdf82cdc | ||
|
|
327f84b967 | ||
|
|
48548fedbf | ||
|
|
0d981c06de | ||
|
|
8463625bd9 | ||
|
|
a6ff11f1d2 | ||
|
|
d4eac3ddca | ||
|
|
d8f43105ed | ||
|
|
f165bbaf4e | ||
|
|
222594cb44 | ||
|
|
274769fd8c | ||
|
|
9f81d6726c | ||
|
|
01deb0b03d | ||
|
|
257bbb5255 | ||
|
|
bb883bfb61 | ||
|
|
eab7b00cee | ||
|
|
47e1d1aef8 | ||
|
|
18452940f0 | ||
|
|
afdeefc864 | ||
|
|
6a4b83c16f | ||
|
|
c63992437b | ||
|
|
44ce9194a2 | ||
|
|
3e21f39a77 | ||
|
|
e9f69bc2e4 | ||
|
|
e3ed572c01 | ||
|
|
e2a2472af4 | ||
|
|
5222be0edf | ||
|
|
0b5e229ed2 | ||
|
|
129d1548a8 | ||
|
|
bc56eb1439 | ||
|
|
5a918227f2 | ||
|
|
95d1fd142e | ||
|
|
3e79838a31 | ||
|
|
ee8b50c955 | ||
|
|
4a93d23af2 | ||
|
|
d858d0c4e0 | ||
|
|
f41663a2df | ||
|
|
1fb26d4319 | ||
|
|
b807c51bbe | ||
|
|
53fb5b6cee | ||
|
|
407eb4ce85 | ||
|
|
41dd6fe6ea | ||
|
|
b10a1549c6 | ||
|
|
c627600ef3 | ||
|
|
f2b3057a7c | ||
|
|
90b80e375c | ||
|
|
cf22111cee | ||
|
|
8a272bc873 | ||
|
|
d8a13ec3d5 | ||
|
|
4bfeeaa90d | ||
|
|
60c8abcc70 | ||
|
|
4b16e4d550 | ||
|
|
fc9150c674 | ||
|
|
de13b59dd2 | ||
|
|
37636fc59a | ||
|
|
0f32bea634 | ||
|
|
809a2dc1d6 | ||
|
|
8416691719 | ||
|
|
d6de865236 | ||
|
|
e073fdc4c7 | ||
|
|
dfa43f0ce5 | ||
|
|
95b9dd3a88 | ||
|
|
e0ea046092 | ||
|
|
87ce2d635b | ||
|
|
f1b22e87f1 | ||
|
|
127f7095dc | ||
|
|
068f396c9b | ||
|
|
b812b0ee2e | ||
|
|
e964e741ef | ||
|
|
5164aa290b | ||
|
|
7d19ff3dcb | ||
|
|
f53c95c743 | ||
|
|
7fcd85cc53 | ||
|
|
7a806f6d89 | ||
|
|
379444515b | ||
|
|
f502e17cc7 | ||
|
|
757d6d204a | ||
|
|
1d852624fd | ||
|
|
62b7920b9d | ||
|
|
3cff9be3d1 | ||
|
|
3b83853713 | ||
|
|
842ce51099 | ||
|
|
9649e7cc8d | ||
|
|
58a403d3c8 | ||
|
|
18e6094cab | ||
|
|
33e62f71f4 | ||
|
|
b7253dc604 | ||
|
|
01911e5e06 | ||
|
|
09bb761b25 | ||
|
|
2eb401a496 | ||
|
|
7996c32211 | ||
|
|
2c5290946b | ||
|
|
d178e27939 | ||
|
|
f9abb5aae2 | ||
|
|
0e5422f36c | ||
|
|
c3d194d1f8 | ||
|
|
f69e33e6a8 | ||
|
|
aca76c75dd | ||
|
|
f1bd1cbc94 | ||
|
|
53222f0dda | ||
|
|
5f0317291b | ||
|
|
ea5276ed24 | ||
|
|
c8373d2ad6 | ||
|
|
bf7e2a85d0 | ||
|
|
d10e4dbf0f | ||
|
|
a1612a7dd2 | ||
|
|
000ab1139f | ||
|
|
81dd9c27ea | ||
|
|
4499f28c1d | ||
|
|
ef5cec4f08 | ||
|
|
7c87952e43 | ||
|
|
1b06e41c83 | ||
|
|
accf6f12e4 | ||
|
|
e01f90784f | ||
|
|
710d29efae | ||
|
|
9e4af68d91 | ||
|
|
10ffe170c2 | ||
|
|
3fa3963465 | ||
|
|
aefb3d3628 | ||
|
|
a803e3217e | ||
|
|
03dccfbf71 | ||
|
|
064dafa618 | ||
|
|
9c8ba9502c | ||
|
|
19a8eff668 | ||
|
|
9d19829742 | ||
|
|
6fea7c2846 | ||
|
|
fea2db42fd | ||
|
|
b34892eb80 | ||
|
|
e06af51cf9 | ||
|
|
a671c58189 | ||
|
|
93bbc6482d | ||
|
|
bb7aa500d7 | ||
|
|
cec5360f1b | ||
|
|
49b55804b1 | ||
|
|
8dd1256c25 | ||
|
|
280347d66a | ||
|
|
214c47ed76 | ||
|
|
75b220d6ce | ||
|
|
4e33b801ca | ||
|
|
1e5f22dc9c | ||
|
|
35aa9f3b97 | ||
|
|
4d3c3e625e | ||
|
|
961c1eb429 | ||
|
|
4f904b5d68 | ||
|
|
98ab7581a5 | ||
|
|
85cb35c514 | ||
|
|
9c73e2ff7a | ||
|
|
9c5fe3612d | ||
|
|
151ddd9e42 | ||
|
|
6e2f07fb81 | ||
|
|
9105b22925 | ||
|
|
e54e452026 | ||
|
|
bf7497a418 | ||
|
|
270e09d46e | ||
|
|
725053acfe | ||
|
|
6213950334 | ||
|
|
95dc38929c | ||
|
|
0d91b93aba | ||
|
|
72f7a1be6f | ||
|
|
5db42643cf | ||
|
|
e3afc4efd8 | ||
|
|
f2d65ea85b | ||
|
|
f3dd07531c | ||
|
|
4a262e0f2b | ||
|
|
c28d33f3a2 | ||
|
|
c4389c006f | ||
|
|
b56717ede9 | ||
|
|
3c78aa6d25 | ||
|
|
61c648d564 | ||
|
|
82a774e92b | ||
|
|
fc23d0c40d | ||
|
|
4a5f12aa29 | ||
|
|
c43e93d1b4 | ||
|
|
2771fc4c52 | ||
|
|
77a0cf27f2 | ||
|
|
5ec60effea | ||
|
|
326a66ba07 | ||
|
|
4b82673484 | ||
|
|
ab9a87c33a | ||
|
|
fca16fbe40 | ||
|
|
fa4c570d33 | ||
|
|
81ad713f5f | ||
|
|
36f76e5893 | ||
|
|
f74efc13ed | ||
|
|
b362072c83 | ||
|
|
2cb634bb0b | ||
|
|
9f94dd457a | ||
|
|
72694a722e | ||
|
|
09236ccbe7 | ||
|
|
28b9a6f69e | ||
|
|
902ffbbfb8 | ||
|
|
5006eca4a8 | ||
|
|
70feab9d50 | ||
|
|
915540d237 | ||
|
|
64c00dcd7a | ||
|
|
ba433be886 | ||
|
|
94e2e51876 | ||
|
|
548549ea9f | ||
|
|
19ddbac113 | ||
|
|
04fa09afef | ||
|
|
5d4140c513 | ||
|
|
7a23651ee1 | ||
|
|
d30ada61f0 | ||
|
|
9799c215cb | ||
|
|
3e8604d5d8 | ||
|
|
2e9d156fad | ||
|
|
c3e75393ab | ||
|
|
74f8055692 | ||
|
|
d1a82c4af1 | ||
|
|
a43987309d | ||
|
|
52f599a080 | ||
|
|
34c2157b66 | ||
|
|
ebd046ae21 | ||
|
|
a8cb47e011 | ||
|
|
9936a2406d | ||
|
|
691a1dafd1 | ||
|
|
0c61b49f0a | ||
|
|
b34a85f4da | ||
|
|
a65bbe14d3 | ||
|
|
be2cabc3f8 | ||
|
|
eb06659711 | ||
|
|
6357931b61 | ||
|
|
875ab073ea | ||
|
|
0d153562be | ||
|
|
31b63ade13 | ||
|
|
509e9c96e2 | ||
|
|
e1ce646275 | ||
|
|
e5f7200213 | ||
|
|
9f07b9a2b6 | ||
|
|
d5943b0e47 | ||
|
|
90dd7a13f0 | ||
|
|
d1b14ef062 | ||
|
|
47315af069 | ||
|
|
01151f8c7a | ||
|
|
4beef5bec3 | ||
|
|
9c4b9973f9 | ||
|
|
f732e46581 | ||
|
|
2cbcfcea88 | ||
|
|
2b916f3cef | ||
|
|
98a00f4840 | ||
|
|
b54594e42b | ||
|
|
f6d058dfea | ||
|
|
7fa08e5c3f | ||
|
|
9229eadff0 | ||
|
|
4f464962a0 | ||
|
|
ea959af850 | ||
|
|
72b50dc32d | ||
|
|
8e70c7f003 | ||
|
|
54c21ac651 | ||
|
|
ffaf16283f | ||
|
|
40a043109d | ||
|
|
86c815f1d4 | ||
|
|
572157d14b | ||
|
|
fc059857e2 | ||
|
|
10bb054b62 | ||
|
|
23909cd6f6 | ||
|
|
e1f53c043c | ||
|
|
1419941f8e | ||
|
|
8a5fa6cb3a | ||
|
|
bda7f7389a | ||
|
|
a2578fed3c | ||
|
|
233f80d6c2 | ||
|
|
7ce8cd7222 | ||
|
|
fd2cb763df | ||
|
|
04fe80b7a0 | ||
|
|
7d4b1877ae | ||
|
|
9b162d7659 | ||
|
|
21b98b23c9 | ||
|
|
bb07817023 | ||
|
|
b5c1cd7918 | ||
|
|
4b5b952c32 | ||
|
|
bfbc280fb4 | ||
|
|
c66b1c64b5 | ||
|
|
a886e4c66b | ||
|
|
57513fd24a | ||
|
|
2829be7de6 | ||
|
|
0d0b4c947b | ||
|
|
b3e0a702a7 | ||
|
|
98521eb16e | ||
|
|
f21e79d5e1 | ||
|
|
0ffb2d36eb | ||
|
|
a251316a5f | ||
|
|
bb141e3a3c | ||
|
|
1b7699f671 | ||
|
|
90022023c9 | ||
|
|
5c01b1e1a0 | ||
|
|
566ca9e58d | ||
|
|
b770310555 | ||
|
|
d56ff42596 | ||
|
|
c928d9495b | ||
|
|
c27defee7b | ||
|
|
3c541ca540 | ||
|
|
66d3f3c616 | ||
|
|
b57a14d07c | ||
|
|
b13e2e8c2e | ||
|
|
02db374e50 | ||
|
|
fe2155e238 | ||
|
|
3325e8f768 | ||
|
|
0f2d8e662e | ||
|
|
65027e8e29 | ||
|
|
3955236b0f | ||
|
|
652ffa28b2 | ||
|
|
c065d98112 | ||
|
|
c045c566e9 | ||
|
|
ca791dfe6f | ||
|
|
7e70ee2e03 | ||
|
|
b4cd019f39 | ||
|
|
f5ad9c2103 | ||
|
|
aba148061f | ||
|
|
fe9af98a28 | ||
|
|
60b56455c4 | ||
|
|
e37e794ccf | ||
|
|
93d3cc135d | ||
|
|
c1d7c0df47 | ||
|
|
16cb41a24e | ||
|
|
4fdeed0214 | ||
|
|
88cfc1aaa6 | ||
|
|
3441847aa1 | ||
|
|
66e32dc406 | ||
|
|
4e650f05d1 | ||
|
|
a97a866570 | ||
|
|
00e85cbc85 | ||
|
|
1d1386e735 | ||
|
|
13be9454cc | ||
|
|
54825b304a | ||
|
|
b45e2ed7ed | ||
|
|
d0cb80c072 | ||
|
|
4886b3dc57 | ||
|
|
d161640f52 | ||
|
|
5aa27586f0 | ||
|
|
7a8398b956 | ||
|
|
212bd2250c | ||
|
|
44c587e828 | ||
|
|
776dc97437 | ||
|
|
5418cdf071 | ||
|
|
14fef6474d | ||
|
|
d7ddff7554 | ||
|
|
301c01260d | ||
|
|
4e6f48c650 | ||
|
|
5af8849aa4 | ||
|
|
eee630827a | ||
|
|
5a206d2fee | ||
|
|
82ca3364c6 | ||
|
|
e5ba0f388b | ||
|
|
97bf9a6b4d | ||
|
|
cae410bda0 | ||
|
|
e3225f3403 | ||
|
|
7d184adf1a | ||
|
|
9f22f67599 | ||
|
|
555236865b | ||
|
|
cf6ff3f815 | ||
|
|
454b5f3c0b | ||
|
|
c953aa7e0b | ||
|
|
7196445cc6 | ||
|
|
8708c35702 | ||
|
|
73b032ab87 | ||
|
|
19e32399b0 | ||
|
|
de020b44c9 | ||
|
|
1461e4a17e | ||
|
|
951b5f9517 | ||
|
|
843e181542 | ||
|
|
29e49bdb91 | ||
|
|
fe7edf0860 | ||
|
|
1cca4fb769 | ||
|
|
3ec3312c7c | ||
|
|
e3e60983e6 | ||
|
|
7159a4e947 | ||
|
|
7963add0d5 | ||
|
|
5e71d352a6 | ||
|
|
f383bf2b83 | ||
|
|
99bc08cf61 | ||
|
|
3c5b4b0a9f | ||
|
|
ffe80fa10a |
@@ -9,11 +9,10 @@
|
||||
|
||||
# Ignore react-tools where there are overlaps, but don't ignore anything that
|
||||
# react-native relies on
|
||||
.*/node_modules/react-tools/src/vendor/core/ExecutionEnvironment.js
|
||||
.*/node_modules/react-tools/src/browser/eventPlugins/ResponderEventPlugin.js
|
||||
.*/node_modules/react-tools/src/browser/ui/React.js
|
||||
.*/node_modules/react-tools/src/core/ReactInstanceHandles.js
|
||||
.*/node_modules/react-tools/src/event/EventPropagators.js
|
||||
.*/node_modules/react-tools/src/React.js
|
||||
.*/node_modules/react-tools/src/renderers/shared/event/EventPropagators.js
|
||||
.*/node_modules/react-tools/src/renderers/shared/event/eventPlugins/ResponderEventPlugin.js
|
||||
.*/node_modules/react-tools/src/shared/vendor/core/ExecutionEnvironment.js
|
||||
|
||||
# Ignore commoner tests
|
||||
.*/node_modules/commoner/test/.*
|
||||
@@ -36,13 +35,15 @@ Examples/UIExplorer/ImageMocks.js
|
||||
[options]
|
||||
module.system=haste
|
||||
|
||||
munge_underscores=true
|
||||
|
||||
suppress_type=$FlowIssue
|
||||
suppress_type=$FlowFixMe
|
||||
suppress_type=$FixMe
|
||||
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(1[0-2]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(1[0-2]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)? #[0-9]+
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(1[0-4]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(1[0-4]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)? #[0-9]+
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy
|
||||
|
||||
[version]
|
||||
0.12.0
|
||||
0.14.0
|
||||
|
||||
@@ -25,6 +25,13 @@ project.xcworkspace
|
||||
# OS X
|
||||
.DS_Store
|
||||
|
||||
# Android/IJ
|
||||
.idea
|
||||
.gradle
|
||||
local.properties
|
||||
*.iml
|
||||
|
||||
# Node
|
||||
node_modules
|
||||
*.log
|
||||
.nvm
|
||||
|
||||
@@ -10,19 +10,19 @@ cache:
|
||||
before_install:
|
||||
- brew update
|
||||
install:
|
||||
- brew reinstall flow xctool nvm
|
||||
- brew reinstall xctool nvm
|
||||
- rm -Rf `node -p "require('os').tmpDir()"`/jest_preprocess_cache
|
||||
- npm install -g flow-bin@`node -p "require('fs').readFileSync('.flowconfig', 'utf8').split('[version]')[1].trim()"`
|
||||
- mkdir -p .nvm
|
||||
- cp $(brew --prefix nvm)/nvm-exec .nvm/
|
||||
- export NVM_DIR=.nvm
|
||||
- export NVM_DIR="$PWD/.nvm"
|
||||
- source $(brew --prefix nvm)/nvm.sh
|
||||
- nvm install v0.10
|
||||
- nvm install iojs-v2
|
||||
- nvm use iojs-v2
|
||||
- npm config set spin=false
|
||||
- npm install
|
||||
|
||||
script:
|
||||
- |
|
||||
nvm use v0.10
|
||||
|
||||
if [ "$TEST_TYPE" = objc ]
|
||||
then
|
||||
|
||||
@@ -37,7 +37,7 @@ script:
|
||||
then
|
||||
|
||||
cd website
|
||||
npm install
|
||||
$(which npm) install
|
||||
./setup.sh
|
||||
if [ "$TRAVIS_PULL_REQUEST" = false ] && [ "$TRAVIS_BRANCH" = master ]; then
|
||||
# Automatically publish the website
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
|
||||
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
|
||||
1461632D1AC3E23900C2F5AD /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1461632C1AC3E22900C2F5AD /* libReact.a */; };
|
||||
58C1E40E1ACF54E9006D1A47 /* libRCTAnimationExperimental.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 58C1E40B1ACF54B4006D1A47 /* libRCTAnimationExperimental.a */; };
|
||||
5F82F1781B85785200FAE87E /* libRCTWebSocket.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5F82F1771B85784500FAE87E /* libRCTWebSocket.a */; };
|
||||
832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 832341B51AAA6A8300B99B32 /* libRCTText.a */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
@@ -24,12 +24,12 @@
|
||||
remoteGlobalIDString = 83CBBA2E1A601D0E00E9B192;
|
||||
remoteInfo = React;
|
||||
};
|
||||
58C1E40A1ACF54B4006D1A47 /* PBXContainerItemProxy */ = {
|
||||
5F82F1761B85784500FAE87E /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 13ACB66C1AC2113500FF4204 /* RCTAnimationExperimental.xcodeproj */;
|
||||
containerPortal = 5F82F1721B85784500FAE87E /* RCTWebSocket.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 134814201AA4EA6300B7C361;
|
||||
remoteInfo = RCTAnimationExperimental;
|
||||
remoteGlobalIDString = 3C86DF461ADF2C930047B81A;
|
||||
remoteInfo = RCTWebSocket;
|
||||
};
|
||||
832341B41AAA6A8300B99B32 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
@@ -41,7 +41,6 @@
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
13ACB66C1AC2113500FF4204 /* RCTAnimationExperimental.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTAnimationExperimental.xcodeproj; path = ../../Libraries/Animation/RCTAnimationExperimental.xcodeproj; sourceTree = "<group>"; };
|
||||
13B07F961A680F5B00A75B9A /* 2048.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = 2048.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = 2048/AppDelegate.h; sourceTree = "<group>"; };
|
||||
13B07FB01A68108700A75B9A /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = 2048/AppDelegate.m; sourceTree = "<group>"; };
|
||||
@@ -50,6 +49,7 @@
|
||||
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = 2048/Info.plist; sourceTree = "<group>"; };
|
||||
13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = 2048/main.m; sourceTree = "<group>"; };
|
||||
146163271AC3E22900C2F5AD /* React.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = React.xcodeproj; path = ../../React/React.xcodeproj; sourceTree = "<group>"; };
|
||||
5F82F1721B85784500FAE87E /* RCTWebSocket.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTWebSocket.xcodeproj; path = ../../Libraries/WebSocket/RCTWebSocket.xcodeproj; sourceTree = "<group>"; };
|
||||
832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = ../../Libraries/Text/RCTText.xcodeproj; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
@@ -58,8 +58,8 @@
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
5F82F1781B85785200FAE87E /* libRCTWebSocket.a in Frameworks */,
|
||||
1461632D1AC3E23900C2F5AD /* libReact.a in Frameworks */,
|
||||
58C1E40E1ACF54E9006D1A47 /* libRCTAnimationExperimental.a in Frameworks */,
|
||||
832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
@@ -88,10 +88,10 @@
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
58C1E4071ACF54B4006D1A47 /* Products */ = {
|
||||
5F82F1731B85784500FAE87E /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
58C1E40B1ACF54B4006D1A47 /* libRCTAnimationExperimental.a */,
|
||||
5F82F1771B85784500FAE87E /* libRCTWebSocket.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
@@ -99,9 +99,9 @@
|
||||
832341AE1AAA6A7D00B99B32 /* Libraries */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
5F82F1721B85784500FAE87E /* RCTWebSocket.xcodeproj */,
|
||||
146163271AC3E22900C2F5AD /* React.xcodeproj */,
|
||||
832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */,
|
||||
13ACB66C1AC2113500FF4204 /* RCTAnimationExperimental.xcodeproj */,
|
||||
);
|
||||
name = Libraries;
|
||||
sourceTree = "<group>";
|
||||
@@ -174,14 +174,14 @@
|
||||
productRefGroup = 83CBBA001A601CBA00E9B192 /* Products */;
|
||||
projectDirPath = "";
|
||||
projectReferences = (
|
||||
{
|
||||
ProductGroup = 58C1E4071ACF54B4006D1A47 /* Products */;
|
||||
ProjectRef = 13ACB66C1AC2113500FF4204 /* RCTAnimationExperimental.xcodeproj */;
|
||||
},
|
||||
{
|
||||
ProductGroup = 832341B11AAA6A8300B99B32 /* Products */;
|
||||
ProjectRef = 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */;
|
||||
},
|
||||
{
|
||||
ProductGroup = 5F82F1731B85784500FAE87E /* Products */;
|
||||
ProjectRef = 5F82F1721B85784500FAE87E /* RCTWebSocket.xcodeproj */;
|
||||
},
|
||||
{
|
||||
ProductGroup = 146163281AC3E22900C2F5AD /* Products */;
|
||||
ProjectRef = 146163271AC3E22900C2F5AD /* React.xcodeproj */;
|
||||
@@ -202,11 +202,11 @@
|
||||
remoteRef = 1461632B1AC3E22900C2F5AD /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
58C1E40B1ACF54B4006D1A47 /* libRCTAnimationExperimental.a */ = {
|
||||
5F82F1771B85784500FAE87E /* libRCTWebSocket.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libRCTAnimationExperimental.a;
|
||||
remoteRef = 58C1E40A1ACF54B4006D1A47 /* PBXContainerItemProxy */;
|
||||
path = libRCTWebSocket.a;
|
||||
remoteRef = 5F82F1761B85784500FAE87E /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
832341B51AAA6A8300B99B32 /* libRCTText.a */ = {
|
||||
@@ -266,10 +266,7 @@
|
||||
);
|
||||
INFOPLIST_FILE = "$(SRCROOT)/2048/Info.plist";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
LIBRARY_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"/Users/sahrens/src/fbobjc-hg/Libraries/FBReactKit/js/react-native-github/Libraries/Animation/build/Debug-iphoneos",
|
||||
);
|
||||
LIBRARY_SEARCH_PATHS = "$(inherited)";
|
||||
OTHER_LDFLAGS = "-ObjC";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.facebook.$(PRODUCT_NAME:rfc1034identifier)";
|
||||
PRODUCT_NAME = 2048;
|
||||
@@ -287,10 +284,7 @@
|
||||
);
|
||||
INFOPLIST_FILE = "$(SRCROOT)/2048/Info.plist";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
LIBRARY_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"/Users/sahrens/src/fbobjc-hg/Libraries/FBReactKit/js/react-native-github/Libraries/Animation/build/Debug-iphoneos",
|
||||
);
|
||||
LIBRARY_SEARCH_PATHS = "$(inherited)";
|
||||
OTHER_LDFLAGS = "-ObjC";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.facebook.$(PRODUCT_NAME:rfc1034identifier)";
|
||||
PRODUCT_NAME = 2048;
|
||||
|
||||
@@ -52,6 +52,7 @@
|
||||
|
||||
RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
|
||||
moduleName:@"Game2048"
|
||||
initialProperties:nil
|
||||
launchOptions:launchOptions];
|
||||
|
||||
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
|
||||
|
||||
@@ -24,7 +24,7 @@ var {
|
||||
View,
|
||||
} = React;
|
||||
|
||||
var AnimationExperimental = require('AnimationExperimental');
|
||||
var Animated = require('Animated');
|
||||
var GameBoard = require('GameBoard');
|
||||
var TouchableBounce = require('TouchableBounce');
|
||||
|
||||
@@ -53,58 +53,58 @@ class Board extends React.Component {
|
||||
}
|
||||
|
||||
class Tile extends React.Component {
|
||||
static _getPosition(index): number {
|
||||
return BOARD_PADDING + (index * (CELL_SIZE + CELL_MARGIN * 2) + CELL_MARGIN);
|
||||
}
|
||||
|
||||
constructor(props: {}) {
|
||||
super(props);
|
||||
|
||||
var tile = this.props.tile;
|
||||
|
||||
this.state = {
|
||||
opacity: new Animated.Value(0),
|
||||
top: new Animated.Value(Tile._getPosition(tile.toRow())),
|
||||
left: new Animated.Value(Tile._getPosition(tile.toColumn())),
|
||||
};
|
||||
}
|
||||
|
||||
calculateOffset(): {top: number; left: number; opacity: number} {
|
||||
var tile = this.props.tile;
|
||||
|
||||
var pos = (i) => {
|
||||
return BOARD_PADDING + (i * (CELL_SIZE + CELL_MARGIN * 2) + CELL_MARGIN);
|
||||
};
|
||||
|
||||
var animationPosition = (i) => {
|
||||
return pos(i) + (CELL_SIZE / 2);
|
||||
};
|
||||
|
||||
var offset = {
|
||||
top: pos(tile.toRow()),
|
||||
left: pos(tile.toColumn()),
|
||||
opacity: 1,
|
||||
top: this.state.top,
|
||||
left: this.state.left,
|
||||
opacity: this.state.opacity,
|
||||
};
|
||||
|
||||
if (tile.isNew()) {
|
||||
offset.opacity = 0;
|
||||
} else {
|
||||
var point = {
|
||||
x: animationPosition(tile.toColumn()),
|
||||
y: animationPosition(tile.toRow()),
|
||||
};
|
||||
AnimationExperimental.startAnimation({
|
||||
node: this.refs['this'],
|
||||
Animated.timing(this.state.opacity, {
|
||||
duration: 100,
|
||||
easing: 'easeInOutQuad',
|
||||
property: 'position',
|
||||
toValue: point,
|
||||
});
|
||||
toValue: 1,
|
||||
}).start();
|
||||
} else {
|
||||
Animated.parallel([
|
||||
Animated.timing(offset.top, {
|
||||
duration: 100,
|
||||
toValue: Tile._getPosition(tile.toRow()),
|
||||
}),
|
||||
Animated.timing(offset.left, {
|
||||
duration: 100,
|
||||
toValue: Tile._getPosition(tile.toColumn()),
|
||||
}),
|
||||
]).start();
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
AnimationExperimental.startAnimation({
|
||||
node: this.refs['this'],
|
||||
duration: 100,
|
||||
easing: 'easeInOutQuad',
|
||||
property: 'opacity',
|
||||
toValue: 1,
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
var tile = this.props.tile;
|
||||
|
||||
var tileStyles = [
|
||||
styles.tile,
|
||||
styles['tile' + tile.value],
|
||||
this.calculateOffset()
|
||||
this.calculateOffset(),
|
||||
];
|
||||
|
||||
var textStyles = [
|
||||
@@ -115,9 +115,9 @@ class Tile extends React.Component {
|
||||
];
|
||||
|
||||
return (
|
||||
<View ref="this" style={tileStyles}>
|
||||
<Animated.View style={tileStyles}>
|
||||
<Text style={textStyles}>{tile.value}</Text>
|
||||
</View>
|
||||
</Animated.View>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -136,10 +136,8 @@ class GameEndOverlay extends React.Component {
|
||||
return (
|
||||
<View style={styles.overlay}>
|
||||
<Text style={styles.overlayMessage}>{message}</Text>
|
||||
<TouchableBounce onPress={this.props.onRestart}>
|
||||
<View style={styles.tryAgain}>
|
||||
<Text style={styles.tryAgainText}>Try Again?</Text>
|
||||
</View>
|
||||
<TouchableBounce onPress={this.props.onRestart} style={styles.tryAgain}>
|
||||
<Text style={styles.tryAgainText}>Try Again?</Text>
|
||||
</TouchableBounce>
|
||||
</View>
|
||||
);
|
||||
|
||||
@@ -37,14 +37,14 @@
|
||||
* on the same Wi-Fi network.
|
||||
*/
|
||||
|
||||
jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/Examples/Movies/MoviesApp.includeRequire.runModule.bundle"];
|
||||
jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/Examples/Movies/MoviesApp.ios.includeRequire.runModule.bundle"];
|
||||
|
||||
/**
|
||||
* OPTION 2
|
||||
* Load from pre-bundled file on disk. To re-generate the static bundle, `cd`
|
||||
* to your Xcode project folder in the terminal, and run
|
||||
*
|
||||
* $ curl 'http://localhost:8081/Examples/Movies/MoviesApp.includeRequire.runModule.bundle' -o main.jsbundle
|
||||
* $ curl 'http://localhost:8081/Examples/Movies/MoviesApp.ios.includeRequire.runModule.bundle' -o main.jsbundle
|
||||
*
|
||||
* then add the `main.jsbundle` file to your project and uncomment this line:
|
||||
*/
|
||||
@@ -53,6 +53,7 @@
|
||||
|
||||
RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
|
||||
moduleName:@"MoviesApp"
|
||||
initialProperties:nil
|
||||
launchOptions:launchOptions];
|
||||
|
||||
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* @providesModule MoviesApp
|
||||
* @flow
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var React = require('react-native');
|
||||
var {
|
||||
AppRegistry,
|
||||
BackAndroid,
|
||||
Navigator,
|
||||
StyleSheet,
|
||||
ToolbarAndroid,
|
||||
View,
|
||||
} = React;
|
||||
|
||||
var MovieScreen = require('./MovieScreen');
|
||||
var SearchScreen = require('./SearchScreen');
|
||||
|
||||
var _navigator;
|
||||
BackAndroid.addEventListener('hardwareBackPress', () => {
|
||||
if (_navigator && _navigator.getCurrentRoutes().length > 1) {
|
||||
_navigator.pop();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
var RouteMapper = function(route, navigationOperations, onComponentRef) {
|
||||
_navigator = navigationOperations;
|
||||
if (route.name === 'search') {
|
||||
return (
|
||||
<SearchScreen navigator={navigationOperations} />
|
||||
);
|
||||
} else if (route.name === 'movie') {
|
||||
return (
|
||||
<View style={{flex: 1}}>
|
||||
<ToolbarAndroid
|
||||
actions={[]}
|
||||
navIcon={require('image!android_back_white')}
|
||||
onIconClicked={navigationOperations.pop}
|
||||
style={styles.toolbar}
|
||||
titleColor="white"
|
||||
title={route.movie.title} />
|
||||
<MovieScreen
|
||||
style={{flex: 1}}
|
||||
navigator={navigationOperations}
|
||||
movie={route.movie}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
var MoviesApp = React.createClass({
|
||||
render: function() {
|
||||
var initialRoute = {name: 'search'};
|
||||
return (
|
||||
<Navigator
|
||||
style={styles.container}
|
||||
initialRoute={initialRoute}
|
||||
configureScene={() => Navigator.SceneConfigs.FadeAndroid}
|
||||
renderScene={RouteMapper}
|
||||
/>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
backgroundColor: 'white',
|
||||
},
|
||||
toolbar: {
|
||||
backgroundColor: '#a9a9a9',
|
||||
height: 56,
|
||||
},
|
||||
});
|
||||
|
||||
AppRegistry.registerComponent('MoviesApp', () => MoviesApp);
|
||||
|
||||
module.exports = MoviesApp;
|
||||
@@ -0,0 +1,104 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* @providesModule SearchBar
|
||||
* @flow
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var React = require('react-native');
|
||||
var {
|
||||
Image,
|
||||
Platform,
|
||||
ProgressBarAndroid,
|
||||
TextInput,
|
||||
StyleSheet,
|
||||
TouchableNativeFeedback,
|
||||
View,
|
||||
} = React;
|
||||
|
||||
var IS_RIPPLE_EFFECT_SUPPORTED = Platform.Version >= 21;
|
||||
|
||||
var SearchBar = React.createClass({
|
||||
render: function() {
|
||||
var loadingView;
|
||||
if (this.props.isLoading) {
|
||||
loadingView = (
|
||||
<ProgressBarAndroid
|
||||
styleAttr="Large"
|
||||
style={styles.spinner}
|
||||
/>
|
||||
);
|
||||
} else {
|
||||
loadingView = <View style={styles.spinner} />;
|
||||
}
|
||||
var background = IS_RIPPLE_EFFECT_SUPPORTED ?
|
||||
TouchableNativeFeedback.SelectableBackgroundBorderless() :
|
||||
TouchableNativeFeedback.SelectableBackground();
|
||||
return (
|
||||
<View style={styles.searchBar}>
|
||||
<TouchableNativeFeedback
|
||||
background={background}
|
||||
onPress={() => this.refs.input && this.refs.input.focus()}>
|
||||
<View>
|
||||
<Image
|
||||
source={require('image!android_search_white')}
|
||||
style={styles.icon}
|
||||
/>
|
||||
</View>
|
||||
</TouchableNativeFeedback>
|
||||
<TextInput
|
||||
ref="input"
|
||||
autoCapitalize="none"
|
||||
autoCorrect={false}
|
||||
autoFocus={true}
|
||||
onChange={this.props.onSearchChange}
|
||||
placeholder="Search a movie..."
|
||||
placeholderTextColor="rgba(255, 255, 255, 0.5)"
|
||||
onFocus={this.props.onFocus}
|
||||
style={styles.searchBarInput}
|
||||
/>
|
||||
{loadingView}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var styles = StyleSheet.create({
|
||||
searchBar: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
backgroundColor: '#a9a9a9',
|
||||
height: 56,
|
||||
},
|
||||
searchBarInput: {
|
||||
flex: 1,
|
||||
fontSize: 20,
|
||||
fontWeight: 'bold',
|
||||
color: 'white',
|
||||
height: 50,
|
||||
padding: 0,
|
||||
backgroundColor: 'transparent'
|
||||
},
|
||||
spinner: {
|
||||
width: 30,
|
||||
height: 30,
|
||||
},
|
||||
icon: {
|
||||
width: 24,
|
||||
height: 24,
|
||||
marginHorizontal: 8,
|
||||
},
|
||||
});
|
||||
|
||||
module.exports = SearchBar;
|
||||
@@ -26,6 +26,8 @@ var {
|
||||
} = React;
|
||||
var TimerMixin = require('react-timer-mixin');
|
||||
|
||||
var invariant = require('invariant');
|
||||
|
||||
var MovieCell = require('./MovieCell');
|
||||
var MovieScreen = require('./MovieScreen');
|
||||
|
||||
@@ -73,18 +75,16 @@ var SearchScreen = React.createClass({
|
||||
this.searchMovies('');
|
||||
},
|
||||
|
||||
_urlForQueryAndPage: function(query: string, pageNumber: ?number): string {
|
||||
_urlForQueryAndPage: function(query: string, pageNumber: number): string {
|
||||
var apiKey = API_KEYS[this.state.queryNumber % API_KEYS.length];
|
||||
if (query) {
|
||||
return (
|
||||
// $FlowFixMe(>=0.13.0) - pageNumber may be null or undefined
|
||||
API_URL + 'movies.json?apikey=' + apiKey + '&q=' +
|
||||
encodeURIComponent(query) + '&page_limit=20&page=' + pageNumber
|
||||
);
|
||||
} else {
|
||||
// With no query, load latest movies
|
||||
return (
|
||||
// $FlowFixMe(>=0.13.0) - pageNumber may be null or undefined
|
||||
API_URL + 'lists/movies/in_theaters.json?apikey=' + apiKey +
|
||||
'&page_limit=20&page=' + pageNumber
|
||||
);
|
||||
@@ -176,6 +176,7 @@ var SearchScreen = React.createClass({
|
||||
});
|
||||
|
||||
var page = resultsCache.nextPageNumberForQuery[query];
|
||||
invariant(page != null, 'Next page number for "%s" is missing', query);
|
||||
fetch(this._urlForQueryAndPage(query, page))
|
||||
.then((response) => response.json())
|
||||
.catch((error) => {
|
||||
@@ -261,6 +262,7 @@ var SearchScreen = React.createClass({
|
||||
) {
|
||||
return (
|
||||
<MovieCell
|
||||
key={movie.id}
|
||||
onSelect={() => this.selectMovie(movie)}
|
||||
onHighlight={() => highlightRowFunc(sectionID, rowID)}
|
||||
onUnhighlight={() => highlightRowFunc(null, null)}
|
||||
@@ -306,7 +308,7 @@ var NoMovies = React.createClass({
|
||||
render: function() {
|
||||
var text = '';
|
||||
if (this.props.filter) {
|
||||
text = `No results for “${this.props.filter}”`;
|
||||
text = `No results for "${this.props.filter}"`;
|
||||
} else if (!this.props.isLoading) {
|
||||
// If we're looking at the latest movies, aren't currently loading, and
|
||||
// still have no results, show a message
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
apply plugin: 'com.android.application'
|
||||
|
||||
android {
|
||||
compileSdkVersion 22
|
||||
buildToolsVersion "23.0.1"
|
||||
|
||||
defaultConfig {
|
||||
applicationId "com.facebook.react.movies"
|
||||
minSdkVersion 16
|
||||
targetSdkVersion 22
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
ndk {
|
||||
abiFilters "armeabi-v7a", "x86"
|
||||
}
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile fileTree(dir: 'libs', include: ['*.jar'])
|
||||
compile 'com.android.support:appcompat-v7:22.2.0'
|
||||
|
||||
// Depend on pre-built React Native
|
||||
compile 'com.facebook.react:react-native:0.11.+'
|
||||
|
||||
// Depend on React Native source.
|
||||
// This is useful for testing your changes when working on React Native.
|
||||
// compile project(':ReactAndroid')
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
# Add project specific ProGuard rules here.
|
||||
# By default, the flags in this file are appended to flags specified
|
||||
# in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt
|
||||
# You can edit the include path and order by changing the proguardFiles
|
||||
# directive in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# Add any project specific keep options here:
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
||||
@@ -0,0 +1,21 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.facebook.react.movies">
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:label="@string/app_name"
|
||||
android:icon="@drawable/rotten_tomatoes_icon"
|
||||
android:theme="@style/AppTheme">
|
||||
<activity
|
||||
android:name=".MoviesActivity">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
@@ -0,0 +1,89 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.facebook.react.movies;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.view.KeyEvent;
|
||||
|
||||
import com.facebook.react.LifecycleState;
|
||||
import com.facebook.react.ReactInstanceManager;
|
||||
import com.facebook.react.ReactRootView;
|
||||
import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler;
|
||||
import com.facebook.react.shell.MainReactPackage;
|
||||
|
||||
public class MoviesActivity extends Activity implements DefaultHardwareBackBtnHandler {
|
||||
|
||||
private ReactInstanceManager mReactInstanceManager;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_main);
|
||||
|
||||
mReactInstanceManager = ReactInstanceManager.builder()
|
||||
.setApplication(getApplication())
|
||||
.setBundleAssetName("MoviesApp.android.bundle")
|
||||
.setJSMainModuleName("Examples/Movies/MoviesApp.android")
|
||||
.addPackage(new MainReactPackage())
|
||||
.setUseDeveloperSupport(true)
|
||||
.setInitialLifecycleState(LifecycleState.RESUMED)
|
||||
.build();
|
||||
|
||||
((ReactRootView) findViewById(R.id.react_root_view))
|
||||
.startReactApplication(mReactInstanceManager, "MoviesApp", null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onKeyUp(int keyCode, KeyEvent event) {
|
||||
if (keyCode == KeyEvent.KEYCODE_MENU && mReactInstanceManager != null) {
|
||||
mReactInstanceManager.showDevOptionsDialog();
|
||||
return true;
|
||||
}
|
||||
return super.onKeyUp(keyCode, event);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
|
||||
if (mReactInstanceManager != null) {
|
||||
mReactInstanceManager.onPause();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
|
||||
if (mReactInstanceManager != null) {
|
||||
mReactInstanceManager.onResume(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
if (mReactInstanceManager != null) {
|
||||
mReactInstanceManager.onBackPressed();
|
||||
} else {
|
||||
super.onBackPressed();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invokeDefaultOnBackPressed() {
|
||||
super.onBackPressed();
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 237 B |
|
After Width: | Height: | Size: 575 B |
|
After Width: | Height: | Size: 190 B |
|
After Width: | Height: | Size: 337 B |
|
After Width: | Height: | Size: 266 B |
|
After Width: | Height: | Size: 581 B |
|
After Width: | Height: | Size: 337 B |
|
After Width: | Height: | Size: 930 B |
|
After Width: | Height: | Size: 57 KiB |
@@ -0,0 +1,12 @@
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".MoviesApp">
|
||||
|
||||
<com.facebook.react.ReactRootView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:id="@+id/react_root_view"/>
|
||||
|
||||
</RelativeLayout>
|
||||
@@ -0,0 +1,3 @@
|
||||
<resources>
|
||||
<string name="app_name">MoviesApp</string>
|
||||
</resources>
|
||||
@@ -0,0 +1,8 @@
|
||||
<resources>
|
||||
|
||||
<!-- Base application theme. -->
|
||||
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
|
||||
<!-- Customize your theme here. -->
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
@@ -9,11 +9,11 @@
|
||||
|
||||
# Ignore react-tools where there are overlaps, but don't ignore anything that
|
||||
# react-native relies on
|
||||
.*/node_modules/react-tools/src/vendor/core/ExecutionEnvironment.js
|
||||
.*/node_modules/react-tools/src/browser/eventPlugins/ResponderEventPlugin.js
|
||||
.*/node_modules/react-tools/src/browser/ui/React.js
|
||||
.*/node_modules/react-tools/src/core/ReactInstanceHandles.js
|
||||
.*/node_modules/react-tools/src/event/EventPropagators.js
|
||||
.*/node_modules/react-tools/src/React.js
|
||||
.*/node_modules/react-tools/src/renderers/shared/event/EventPropagators.js
|
||||
.*/node_modules/react-tools/src/renderers/shared/event/eventPlugins/ResponderEventPlugin.js
|
||||
.*/node_modules/react-tools/src/shared/vendor/core/ExecutionEnvironment.js
|
||||
|
||||
|
||||
# Ignore commoner tests
|
||||
.*/node_modules/commoner/test/.*
|
||||
@@ -32,5 +32,15 @@ node_modules/react-native/Libraries/react-native/react-native-interface.js
|
||||
[options]
|
||||
module.system=haste
|
||||
|
||||
munge_underscores=true
|
||||
|
||||
suppress_type=$FlowIssue
|
||||
suppress_type=$FlowFixMe
|
||||
suppress_type=$FixMe
|
||||
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(1[0-4]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(1[0-4]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)? #[0-9]+
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy
|
||||
|
||||
[version]
|
||||
0.12.0
|
||||
0.14.0
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
{}
|
||||
@@ -0,0 +1,35 @@
|
||||
apply plugin: 'com.android.application'
|
||||
|
||||
android {
|
||||
compileSdkVersion 23
|
||||
buildToolsVersion "23.0.1"
|
||||
|
||||
defaultConfig {
|
||||
applicationId "com.facebook.react.sample"
|
||||
minSdkVersion 16
|
||||
targetSdkVersion 22
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
ndk {
|
||||
abiFilters "armeabi-v7a", "x86"
|
||||
}
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile fileTree(dir: 'libs', include: ['*.jar'])
|
||||
compile 'com.android.support:appcompat-v7:23.0.0'
|
||||
|
||||
// Depend on pre-built React Native
|
||||
compile 'com.facebook.react:react-native:0.11.+'
|
||||
|
||||
// Depend on React Native source.
|
||||
// This is useful for testing your changes when working on React Native.
|
||||
// compile project(':ReactAndroid')
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
# Add project specific ProGuard rules here.
|
||||
# By default, the flags in this file are appended to flags specified
|
||||
# in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt
|
||||
# You can edit the include path and order by changing the proguardFiles
|
||||
# directive in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# Add any project specific keep options here:
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
||||
@@ -0,0 +1,21 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.facebook.react.sample">
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:label="@string/app_name"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:theme="@style/AppTheme">
|
||||
<activity
|
||||
android:name=".MainActivity">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
@@ -0,0 +1,88 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.facebook.react.sample;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.view.KeyEvent;
|
||||
|
||||
import com.facebook.react.LifecycleState;
|
||||
import com.facebook.react.ReactInstanceManager;
|
||||
import com.facebook.react.ReactRootView;
|
||||
import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler;
|
||||
import com.facebook.react.shell.MainReactPackage;
|
||||
import com.facebook.soloader.SoLoader;
|
||||
|
||||
public class MainActivity extends Activity implements DefaultHardwareBackBtnHandler {
|
||||
|
||||
private ReactInstanceManager mReactInstanceManager;
|
||||
private ReactRootView mReactRootView;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
SoLoader.init(this, false);
|
||||
mReactRootView = new ReactRootView(this);
|
||||
|
||||
mReactInstanceManager = ReactInstanceManager.builder()
|
||||
.setApplication(getApplication())
|
||||
.setBundleAssetName("index.android.bundle")
|
||||
.setJSMainModuleName("Examples/SampleApp/index.android")
|
||||
.addPackage(new MainReactPackage())
|
||||
.setUseDeveloperSupport(BuildConfig.DEBUG)
|
||||
.setInitialLifecycleState(LifecycleState.RESUMED)
|
||||
.build();
|
||||
|
||||
mReactRootView.startReactApplication(
|
||||
mReactInstanceManager,
|
||||
"SampleApp",
|
||||
null);
|
||||
|
||||
setContentView(mReactRootView);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onKeyUp(int keyCode, KeyEvent event) {
|
||||
if (keyCode == KeyEvent.KEYCODE_MENU && mReactInstanceManager != null) {
|
||||
mReactInstanceManager.showDevOptionsDialog();
|
||||
return true;
|
||||
}
|
||||
return super.onKeyUp(keyCode, event);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invokeDefaultOnBackPressed() {
|
||||
super.onBackPressed();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
|
||||
if (mReactInstanceManager != null) {
|
||||
mReactInstanceManager.onPause();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
|
||||
if (mReactInstanceManager != null) {
|
||||
mReactInstanceManager.onResume(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 3.3 KiB |
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 4.7 KiB |
|
After Width: | Height: | Size: 7.5 KiB |
@@ -0,0 +1,3 @@
|
||||
<resources>
|
||||
<string name="app_name">SampleApp</string>
|
||||
</resources>
|
||||
@@ -0,0 +1,8 @@
|
||||
<resources>
|
||||
|
||||
<!-- Base application theme. -->
|
||||
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
|
||||
<!-- Customize your theme here. -->
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
@@ -106,27 +106,27 @@
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
008F07F21AC5B25A0029DE68 /* main.jsbundle */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = main.jsbundle; path = iOS/main.jsbundle; sourceTree = "<group>"; };
|
||||
00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTActionSheet.xcodeproj; path = ../../Libraries/ActionSheetIOS/RCTActionSheet.xcodeproj; sourceTree = "<group>"; };
|
||||
00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTGeolocation.xcodeproj; path = ../../Libraries/Geolocation/RCTGeolocation.xcodeproj; sourceTree = "<group>"; };
|
||||
00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTImage.xcodeproj; path = ../../Libraries/Image/RCTImage.xcodeproj; sourceTree = "<group>"; };
|
||||
00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTNetwork.xcodeproj; path = ../../Libraries/Network/RCTNetwork.xcodeproj; sourceTree = "<group>"; };
|
||||
00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTVibration.xcodeproj; path = ../../Libraries/Vibration/RCTVibration.xcodeproj; sourceTree = "<group>"; };
|
||||
008F07F21AC5B25A0029DE68 /* main.jsbundle */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = main.jsbundle; sourceTree = "<group>"; };
|
||||
00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTActionSheet.xcodeproj; path = ../../../Libraries/ActionSheetIOS/RCTActionSheet.xcodeproj; sourceTree = "<group>"; };
|
||||
00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTGeolocation.xcodeproj; path = ../../../Libraries/Geolocation/RCTGeolocation.xcodeproj; sourceTree = "<group>"; };
|
||||
00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTImage.xcodeproj; path = ../../../Libraries/Image/RCTImage.xcodeproj; sourceTree = "<group>"; };
|
||||
00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTNetwork.xcodeproj; path = ../../../Libraries/Network/RCTNetwork.xcodeproj; sourceTree = "<group>"; };
|
||||
00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTVibration.xcodeproj; path = ../../../Libraries/Vibration/RCTVibration.xcodeproj; sourceTree = "<group>"; };
|
||||
00E356EE1AD99517003FC87E /* SampleAppTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SampleAppTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
00E356F11AD99517003FC87E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
00E356F21AD99517003FC87E /* SampleAppTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SampleAppTests.m; sourceTree = "<group>"; };
|
||||
139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTSettings.xcodeproj; path = ../../Libraries/Settings/RCTSettings.xcodeproj; sourceTree = "<group>"; };
|
||||
139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTWebSocket.xcodeproj; path = ../../Libraries/WebSocket/RCTWebSocket.xcodeproj; sourceTree = "<group>"; };
|
||||
139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTSettings.xcodeproj; path = ../../../Libraries/Settings/RCTSettings.xcodeproj; sourceTree = "<group>"; };
|
||||
139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTWebSocket.xcodeproj; path = ../../../Libraries/WebSocket/RCTWebSocket.xcodeproj; sourceTree = "<group>"; };
|
||||
13B07F961A680F5B00A75B9A /* SampleApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SampleApp.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = iOS/AppDelegate.h; sourceTree = "<group>"; };
|
||||
13B07FB01A68108700A75B9A /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = iOS/AppDelegate.m; sourceTree = "<group>"; };
|
||||
13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
|
||||
13B07FB01A68108700A75B9A /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
|
||||
13B07FB21A68108700A75B9A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = "<group>"; };
|
||||
13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = iOS/Images.xcassets; sourceTree = "<group>"; };
|
||||
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = iOS/Info.plist; sourceTree = "<group>"; };
|
||||
13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = iOS/main.m; sourceTree = "<group>"; };
|
||||
146833FF1AC3E56700842450 /* React.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = React.xcodeproj; path = ../../React/React.xcodeproj; sourceTree = "<group>"; };
|
||||
78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTLinking.xcodeproj; path = ../../Libraries/LinkingIOS/RCTLinking.xcodeproj; sourceTree = "<group>"; };
|
||||
832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = ../../Libraries/Text/RCTText.xcodeproj; sourceTree = "<group>"; };
|
||||
13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
|
||||
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
|
||||
146833FF1AC3E56700842450 /* React.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = React.xcodeproj; path = ../../../React/React.xcodeproj; sourceTree = "<group>"; };
|
||||
78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTLinking.xcodeproj; path = ../../../Libraries/LinkingIOS/RCTLinking.xcodeproj; sourceTree = "<group>"; };
|
||||
832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = ../../../Libraries/Text/RCTText.xcodeproj; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
@@ -233,15 +233,15 @@
|
||||
13B07FAE1A68108700A75B9A /* SampleApp */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
008F07F21AC5B25A0029DE68 /* main.jsbundle */,
|
||||
13B07FAF1A68108700A75B9A /* AppDelegate.h */,
|
||||
13B07FB01A68108700A75B9A /* AppDelegate.m */,
|
||||
13B07FB51A68108700A75B9A /* Images.xcassets */,
|
||||
13B07FB61A68108700A75B9A /* Info.plist */,
|
||||
13B07FB11A68108700A75B9A /* LaunchScreen.xib */,
|
||||
008F07F21AC5B25A0029DE68 /* main.jsbundle */,
|
||||
13B07FB71A68108700A75B9A /* main.m */,
|
||||
);
|
||||
name = SampleApp;
|
||||
path = SampleApp;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
146834001AC3E56700842450 /* Products */ = {
|
||||
@@ -289,8 +289,8 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
13B07FAE1A68108700A75B9A /* SampleApp */,
|
||||
832341AE1AAA6A7D00B99B32 /* Libraries */,
|
||||
00E356EF1AD99517003FC87E /* SampleAppTests */,
|
||||
832341AE1AAA6A7D00B99B32 /* Libraries */,
|
||||
83CBBA001A601CBA00E9B192 /* Products */,
|
||||
);
|
||||
indentWidth = 2;
|
||||
@@ -548,7 +548,6 @@
|
||||
13B07FB21A68108700A75B9A /* Base */,
|
||||
);
|
||||
name = LaunchScreen.xib;
|
||||
path = iOS;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXVariantGroup section */
|
||||
@@ -566,6 +565,11 @@
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
||||
"$(SRCROOT)/../../../React/**",
|
||||
);
|
||||
INFOPLIST_FILE = SampleAppTests/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.2;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
@@ -583,6 +587,11 @@
|
||||
"$(SDKROOT)/Developer/Library/Frameworks",
|
||||
"$(inherited)",
|
||||
);
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
||||
"$(SRCROOT)/../../../React/**",
|
||||
);
|
||||
INFOPLIST_FILE = SampleAppTests/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.2;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
@@ -598,9 +607,9 @@
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
||||
"$(SRCROOT)/../../React/**",
|
||||
"$(SRCROOT)/../../../React/**",
|
||||
);
|
||||
INFOPLIST_FILE = "iOS/Info.plist";
|
||||
INFOPLIST_FILE = "$(SRCROOT)/SampleApp/Info.plist";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
OTHER_LDFLAGS = "-ObjC";
|
||||
PRODUCT_NAME = SampleApp;
|
||||
@@ -614,9 +623,9 @@
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
||||
"$(SRCROOT)/../../React/**",
|
||||
"$(SRCROOT)/../../../React/**",
|
||||
);
|
||||
INFOPLIST_FILE = "iOS/Info.plist";
|
||||
INFOPLIST_FILE = "$(SRCROOT)/SampleApp/Info.plist";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
OTHER_LDFLAGS = "-ObjC";
|
||||
PRODUCT_NAME = SampleApp;
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0620"
|
||||
LastUpgradeVersion = "0630"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
@@ -0,0 +1,61 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
#import "AppDelegate.h"
|
||||
|
||||
#import "RCTRootView.h"
|
||||
|
||||
@implementation AppDelegate
|
||||
|
||||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
|
||||
{
|
||||
NSURL *jsCodeLocation;
|
||||
|
||||
/**
|
||||
* Loading JavaScript code - uncomment the one you want.
|
||||
*
|
||||
* OPTION 1
|
||||
* Load from development server. Start the server from the repository root:
|
||||
*
|
||||
* $ npm start
|
||||
*
|
||||
* To run on device, change `localhost` to the IP address of your computer
|
||||
* (you can get this by typing `ifconfig` into the terminal and selecting the
|
||||
* `inet` value under `en0:`) and make sure your computer and iOS device are
|
||||
* on the same Wi-Fi network.
|
||||
*/
|
||||
|
||||
jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/Examples/SampleApp/index.ios.bundle"];
|
||||
|
||||
/**
|
||||
* OPTION 2
|
||||
* Load from pre-bundled file on disk. To re-generate the static bundle
|
||||
* from the root of your project directory, run
|
||||
*
|
||||
* $ react-native bundle --minify
|
||||
*
|
||||
* see http://facebook.github.io/react-native/docs/runningondevice.html
|
||||
*/
|
||||
|
||||
// jsCodeLocation = [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
|
||||
|
||||
RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
|
||||
moduleName:@"SampleApp"
|
||||
initialProperties:nil
|
||||
launchOptions:launchOptions];
|
||||
|
||||
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
|
||||
UIViewController *rootViewController = [UIViewController new];
|
||||
rootViewController.view = rootView;
|
||||
self.window.rootViewController = rootViewController;
|
||||
[self.window makeKeyAndVisible];
|
||||
return YES;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="7702" systemVersion="14D136" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="6751" systemVersion="14C1510" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES">
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="7701"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6736"/>
|
||||
<capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
@@ -10,8 +10,7 @@
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <XCTest/XCTest.h>
|
||||
|
||||
#import "RCTAssert.h"
|
||||
#import "RCTRedBox.h"
|
||||
#import "RCTLog.h"
|
||||
#import "RCTRootView.h"
|
||||
|
||||
#define TIMEOUT_SECONDS 240
|
||||
@@ -23,7 +22,6 @@
|
||||
|
||||
@implementation SampleAppTests
|
||||
|
||||
|
||||
- (BOOL)findSubviewInView:(UIView *)view matching:(BOOL(^)(UIView *view))test
|
||||
{
|
||||
if (test(view)) {
|
||||
@@ -37,18 +35,23 @@
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (void)testRendersWelcomeScreen {
|
||||
- (void)testRendersWelcomeScreen
|
||||
{
|
||||
UIViewController *vc = [[[[UIApplication sharedApplication] delegate] window] rootViewController];
|
||||
NSDate *date = [NSDate dateWithTimeIntervalSinceNow:TIMEOUT_SECONDS];
|
||||
BOOL foundElement = NO;
|
||||
NSString *redboxError = nil;
|
||||
|
||||
__block NSString *redboxError = nil;
|
||||
RCTSetLogFunction(^(RCTLogLevel level, NSString *fileName, NSNumber *lineNumber, NSString *message) {
|
||||
if (level >= RCTLogLevelError) {
|
||||
redboxError = message;
|
||||
}
|
||||
});
|
||||
|
||||
while ([date timeIntervalSinceNow] > 0 && !foundElement && !redboxError) {
|
||||
[[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
|
||||
[[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
|
||||
|
||||
redboxError = [[RCTRedBox sharedInstance] currentErrorMessage];
|
||||
|
||||
foundElement = [self findSubviewInView:vc.view matching:^BOOL(UIView *view) {
|
||||
if ([view.accessibilityLabel isEqualToString:TEXT_TO_LOOK_FOR]) {
|
||||
return YES;
|
||||
@@ -57,6 +60,8 @@
|
||||
}];
|
||||
}
|
||||
|
||||
RCTSetLogFunction(RCTDefaultLogFunction);
|
||||
|
||||
XCTAssertNil(redboxError, @"RedBox error: %@", redboxError);
|
||||
XCTAssertTrue(foundElement, @"Couldn't find element with text '%@' in %d seconds", TEXT_TO_LOOK_FOR, TIMEOUT_SECONDS);
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/**
|
||||
* Sample React Native App
|
||||
* https://github.com/facebook/react-native
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var React = require('react-native');
|
||||
var {
|
||||
AppRegistry,
|
||||
StyleSheet,
|
||||
Text,
|
||||
View,
|
||||
} = React;
|
||||
|
||||
var SampleApp = React.createClass({
|
||||
render: function() {
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<Text style={styles.welcome}>
|
||||
Welcome to React Native!
|
||||
</Text>
|
||||
<Text style={styles.instructions}>
|
||||
To get started, edit index.android.js
|
||||
</Text>
|
||||
<Text style={styles.instructions}>
|
||||
Shake or press menu button for dev menu
|
||||
</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
backgroundColor: '#F5FCFF',
|
||||
},
|
||||
welcome: {
|
||||
fontSize: 20,
|
||||
textAlign: 'center',
|
||||
margin: 10,
|
||||
},
|
||||
instructions: {
|
||||
textAlign: 'center',
|
||||
color: '#333333',
|
||||
marginBottom: 5,
|
||||
},
|
||||
});
|
||||
|
||||
AppRegistry.registerComponent('SampleApp', () => SampleApp);
|
||||
@@ -14,6 +14,8 @@
|
||||
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
|
||||
144C5F691AC3E5E300B004E7 /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 144C5F681AC3E5D800B004E7 /* libReact.a */; };
|
||||
58C572511AA6229D00CDF9C8 /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 58C5724D1AA6224400CDF9C8 /* libRCTText.a */; };
|
||||
5FF8942E1B85571A007731BE /* libRCTWebSocket.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5FF8942D1B8556F8007731BE /* libRCTWebSocket.a */; };
|
||||
832044981B492C2500E297FC /* libRCTSettings.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 832044951B492C1E00E297FC /* libRCTSettings.a */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
@@ -38,6 +40,20 @@
|
||||
remoteGlobalIDString = 58B5119B1A9E6C1200147676;
|
||||
remoteInfo = RCTText;
|
||||
};
|
||||
5FF8942C1B8556F8007731BE /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 5FF894281B8556F8007731BE /* RCTWebSocket.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 3C86DF461ADF2C930047B81A;
|
||||
remoteInfo = RCTWebSocket;
|
||||
};
|
||||
832044941B492C1E00E297FC /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 8320448F1B492C1E00E297FC /* RCTSettings.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 134814201AA4EA6300B7C361;
|
||||
remoteInfo = RCTSettings;
|
||||
};
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
@@ -51,6 +67,8 @@
|
||||
13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = TicTacToe/main.m; sourceTree = "<group>"; };
|
||||
144C5F631AC3E5D800B004E7 /* React.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = React.xcodeproj; path = ../../React/React.xcodeproj; sourceTree = "<group>"; };
|
||||
587650DA1A9EB0DB008B8F17 /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = ../../Libraries/Text/RCTText.xcodeproj; sourceTree = "<group>"; };
|
||||
5FF894281B8556F8007731BE /* RCTWebSocket.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTWebSocket.xcodeproj; path = ../../Libraries/WebSocket/RCTWebSocket.xcodeproj; sourceTree = "<group>"; };
|
||||
8320448F1B492C1E00E297FC /* RCTSettings.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTSettings.xcodeproj; path = ../../Libraries/Settings/RCTSettings.xcodeproj; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
@@ -58,9 +76,11 @@
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
5FF8942E1B85571A007731BE /* libRCTWebSocket.a in Frameworks */,
|
||||
144C5F691AC3E5E300B004E7 /* libReact.a in Frameworks */,
|
||||
1341803E1AA91802003F314A /* libRCTImage.a in Frameworks */,
|
||||
58C572511AA6229D00CDF9C8 /* libRCTText.a in Frameworks */,
|
||||
832044981B492C2500E297FC /* libRCTSettings.a in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -99,8 +119,10 @@
|
||||
58C572071AA6126D00CDF9C8 /* Libraries */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
5FF894281B8556F8007731BE /* RCTWebSocket.xcodeproj */,
|
||||
144C5F631AC3E5D800B004E7 /* React.xcodeproj */,
|
||||
134180381AA917ED003F314A /* RCTImage.xcodeproj */,
|
||||
8320448F1B492C1E00E297FC /* RCTSettings.xcodeproj */,
|
||||
587650DA1A9EB0DB008B8F17 /* RCTText.xcodeproj */,
|
||||
);
|
||||
name = Libraries;
|
||||
@@ -114,6 +136,22 @@
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
5FF894291B8556F8007731BE /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
5FF8942D1B8556F8007731BE /* libRCTWebSocket.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
832044901B492C1E00E297FC /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
832044951B492C1E00E297FC /* libRCTSettings.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
83CBB9F61A601CBA00E9B192 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@@ -178,10 +216,18 @@
|
||||
ProductGroup = 134180391AA917ED003F314A /* Products */;
|
||||
ProjectRef = 134180381AA917ED003F314A /* RCTImage.xcodeproj */;
|
||||
},
|
||||
{
|
||||
ProductGroup = 832044901B492C1E00E297FC /* Products */;
|
||||
ProjectRef = 8320448F1B492C1E00E297FC /* RCTSettings.xcodeproj */;
|
||||
},
|
||||
{
|
||||
ProductGroup = 58C572481AA6224300CDF9C8 /* Products */;
|
||||
ProjectRef = 587650DA1A9EB0DB008B8F17 /* RCTText.xcodeproj */;
|
||||
},
|
||||
{
|
||||
ProductGroup = 5FF894291B8556F8007731BE /* Products */;
|
||||
ProjectRef = 5FF894281B8556F8007731BE /* RCTWebSocket.xcodeproj */;
|
||||
},
|
||||
{
|
||||
ProductGroup = 144C5F641AC3E5D800B004E7 /* Products */;
|
||||
ProjectRef = 144C5F631AC3E5D800B004E7 /* React.xcodeproj */;
|
||||
@@ -216,6 +262,20 @@
|
||||
remoteRef = 58C5724C1AA6224400CDF9C8 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
5FF8942D1B8556F8007731BE /* libRCTWebSocket.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libRCTWebSocket.a;
|
||||
remoteRef = 5FF8942C1B8556F8007731BE /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
832044951B492C1E00E297FC /* libRCTSettings.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libRCTSettings.a;
|
||||
remoteRef = 832044941B492C1E00E297FC /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
/* End PBXReferenceProxy section */
|
||||
|
||||
/* Begin PBXResourcesBuildPhase section */
|
||||
|
||||
@@ -52,6 +52,7 @@
|
||||
|
||||
RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
|
||||
moduleName:@"TicTacToeApp"
|
||||
initialProperties:nil
|
||||
launchOptions:launchOptions];
|
||||
|
||||
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
var React = require('react-native');
|
||||
var {
|
||||
AppRegistry,
|
||||
Image,
|
||||
StyleSheet,
|
||||
Text,
|
||||
TouchableHighlight,
|
||||
@@ -118,17 +117,6 @@ var Cell = React.createClass({
|
||||
}
|
||||
},
|
||||
|
||||
imageStyle() {
|
||||
switch (this.props.player) {
|
||||
case 1:
|
||||
return styles.imageX;
|
||||
case 2:
|
||||
return styles.imageO;
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
},
|
||||
|
||||
textContents() {
|
||||
switch (this.props.player) {
|
||||
case 1:
|
||||
@@ -140,17 +128,6 @@ var Cell = React.createClass({
|
||||
}
|
||||
},
|
||||
|
||||
imageContents() {
|
||||
switch (this.props.player) {
|
||||
case 1:
|
||||
return 'http://www.picgifs.com/alphabets/alphabets/children-5/alphabets-children-5-277623.gif';
|
||||
case 2:
|
||||
return 'http://www.picgifs.com/alphabets/alphabets/children-5/alphabets-children-5-730492.gif';
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
},
|
||||
|
||||
render() {
|
||||
return (
|
||||
<TouchableHighlight
|
||||
@@ -158,7 +135,9 @@ var Cell = React.createClass({
|
||||
underlayColor="transparent"
|
||||
activeOpacity={0.5}>
|
||||
<View style={[styles.cell, this.cellStyle()]}>
|
||||
<Image source={{uri: this.imageContents()}} style={this.imageStyle()}/>
|
||||
<Text style={[styles.cellText, this.textStyle()]}>
|
||||
{this.textContents()}
|
||||
</Text>
|
||||
</View>
|
||||
</TouchableHighlight>
|
||||
);
|
||||
@@ -304,17 +283,6 @@ var styles = StyleSheet.create({
|
||||
color: '#b9dc2f',
|
||||
},
|
||||
|
||||
// CELL IMAGE
|
||||
|
||||
imageX: {
|
||||
width: 34,
|
||||
height: 42,
|
||||
},
|
||||
imageO: {
|
||||
width: 45,
|
||||
height: 41,
|
||||
},
|
||||
|
||||
// GAME OVER
|
||||
|
||||
overlay: {
|
||||
|
||||
@@ -0,0 +1,213 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var React = require('react-native');
|
||||
var {
|
||||
StyleSheet,
|
||||
Text,
|
||||
View,
|
||||
ToastAndroid,
|
||||
TouchableWithoutFeedback,
|
||||
} = React;
|
||||
|
||||
var UIExplorerBlock = require('./UIExplorerBlock');
|
||||
var UIExplorerPage = require('./UIExplorerPage');
|
||||
|
||||
var importantForAccessibilityValues = ['auto', 'yes', 'no', 'no-hide-descendants'];
|
||||
|
||||
var AccessibilityAndroidExample = React.createClass({
|
||||
|
||||
statics: {
|
||||
title: 'Accessibility',
|
||||
description: 'Examples of using Accessibility API.',
|
||||
},
|
||||
|
||||
getInitialState: function() {
|
||||
return {
|
||||
count: 0,
|
||||
backgroundImportantForAcc: 0,
|
||||
forgroundImportantForAcc: 0,
|
||||
};
|
||||
},
|
||||
|
||||
_addOne: function() {
|
||||
this.setState({
|
||||
count: ++this.state.count,
|
||||
});
|
||||
},
|
||||
|
||||
_changeBackgroundImportantForAcc: function() {
|
||||
this.setState({
|
||||
backgroundImportantForAcc: (this.state.backgroundImportantForAcc + 1) % 4,
|
||||
});
|
||||
},
|
||||
|
||||
_changeForgroundImportantForAcc: function() {
|
||||
this.setState({
|
||||
forgroundImportantForAcc: (this.state.forgroundImportantForAcc + 1) % 4,
|
||||
});
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return (
|
||||
<UIExplorerPage title={'Accessibility'}>
|
||||
|
||||
<UIExplorerBlock title="Nonaccessible view with TextViews">
|
||||
<View>
|
||||
<Text style={{color: 'green',}}>
|
||||
This is
|
||||
</Text>
|
||||
<Text style={{color: 'blue'}}>
|
||||
nontouchable normal view.
|
||||
</Text>
|
||||
</View>
|
||||
</UIExplorerBlock>
|
||||
|
||||
<UIExplorerBlock title="Accessible view with TextViews wihout label">
|
||||
<View accessible={true}>
|
||||
<Text style={{color: 'green',}}>
|
||||
This is
|
||||
</Text>
|
||||
<Text style={{color: 'blue'}}>
|
||||
nontouchable accessible view without label.
|
||||
</Text>
|
||||
</View>
|
||||
</UIExplorerBlock>
|
||||
|
||||
<UIExplorerBlock title="Accessible view with TextViews with label">
|
||||
<View accessible={true}
|
||||
accessibilityLabel="I have label, so I read it instead of embedded text.">
|
||||
<Text style={{color: 'green',}}>
|
||||
This is
|
||||
</Text>
|
||||
<Text style={{color: 'blue'}}>
|
||||
nontouchable accessible view with label.
|
||||
</Text>
|
||||
</View>
|
||||
</UIExplorerBlock>
|
||||
|
||||
<UIExplorerBlock title="Touchable with component type = button">
|
||||
<TouchableWithoutFeedback
|
||||
onPress={() => ToastAndroid.show('Toasts work by default', ToastAndroid.SHORT)}
|
||||
accessibilityComponentType="button">
|
||||
<View style={styles.embedded}>
|
||||
<Text>Click me</Text>
|
||||
<Text>Or not</Text>
|
||||
</View>
|
||||
</TouchableWithoutFeedback>
|
||||
</UIExplorerBlock>
|
||||
|
||||
<UIExplorerBlock title="LiveRegion">
|
||||
<TouchableWithoutFeedback onPress={this._addOne}>
|
||||
<View style={styles.embedded}>
|
||||
<Text>Click me</Text>
|
||||
</View>
|
||||
</TouchableWithoutFeedback>
|
||||
<Text accessibilityLiveRegion="polite">
|
||||
Clicked {this.state.count} times
|
||||
</Text>
|
||||
</UIExplorerBlock>
|
||||
|
||||
<UIExplorerBlock title="Overlapping views and importantForAccessibility property">
|
||||
<View style={styles.container}>
|
||||
<View
|
||||
style={{
|
||||
position: 'absolute',
|
||||
left: 10,
|
||||
top: 10,
|
||||
right: 10,
|
||||
height: 100,
|
||||
backgroundColor: 'green'}}
|
||||
accessible={true}
|
||||
accessibilityLabel="First layout"
|
||||
importantForAccessibility={
|
||||
importantForAccessibilityValues[this.state.backgroundImportantForAcc]}>
|
||||
<View accessible={true}>
|
||||
<Text style={{fontSize: 25}}>
|
||||
Hello
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
<View
|
||||
style={{
|
||||
position: 'absolute',
|
||||
left: 10,
|
||||
top: 25,
|
||||
right: 10,
|
||||
height: 110,
|
||||
backgroundColor: 'yellow', opacity: 0.5}}
|
||||
accessible={true}
|
||||
accessibilityLabel="Second layout"
|
||||
importantForAccessibility={
|
||||
importantForAccessibilityValues[this.state.forgroundImportantForAcc]}>
|
||||
<View accessible={true}>
|
||||
<Text style={{fontSize: 20}}>
|
||||
world
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
<TouchableWithoutFeedback onPress={this._changeBackgroundImportantForAcc}>
|
||||
<View style={styles.embedded}>
|
||||
<Text>
|
||||
Change importantForAccessibility for background layout.
|
||||
</Text>
|
||||
</View>
|
||||
</TouchableWithoutFeedback>
|
||||
<View accessible={true}>
|
||||
<Text>
|
||||
Background layout importantForAccessibility
|
||||
</Text>
|
||||
<Text>
|
||||
{importantForAccessibilityValues[this.state.backgroundImportantForAcc]}
|
||||
</Text>
|
||||
</View>
|
||||
<TouchableWithoutFeedback onPress={this._changeForgroundImportantForAcc}>
|
||||
<View style={styles.embedded}>
|
||||
<Text>
|
||||
Change importantForAccessibility for forground layout.
|
||||
</Text>
|
||||
</View>
|
||||
</TouchableWithoutFeedback>
|
||||
<View accessible={true}>
|
||||
<Text>
|
||||
Forground layout importantForAccessibility
|
||||
</Text>
|
||||
<Text>
|
||||
{importantForAccessibilityValues[this.state.forgroundImportantForAcc]}
|
||||
</Text>
|
||||
</View>
|
||||
</UIExplorerBlock>
|
||||
|
||||
</UIExplorerPage>
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
var styles = StyleSheet.create({
|
||||
embedded: {
|
||||
backgroundColor: 'yellow',
|
||||
padding:10,
|
||||
},
|
||||
container: {
|
||||
flex: 1,
|
||||
backgroundColor: 'white',
|
||||
padding: 10,
|
||||
height:150,
|
||||
},
|
||||
});
|
||||
|
||||
module.exports = AccessibilityAndroidExample;
|
||||
@@ -0,0 +1,256 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var React = require('react-native');
|
||||
var {
|
||||
StyleSheet,
|
||||
Text,
|
||||
View,
|
||||
TouchableWithoutFeedback,
|
||||
} = React;
|
||||
var ToastAndroid = require('ToastAndroid');
|
||||
var AccessibilityInfo = require('AccessibilityInfo');
|
||||
|
||||
var UIExplorerBlock = require('./UIExplorerBlock');
|
||||
var UIExplorerPage = require('./UIExplorerPage');
|
||||
|
||||
var importantForAccessibilityValues = ['auto', 'yes', 'no', 'no-hide-descendants'];
|
||||
|
||||
var AccessibilityAndroidExample = React.createClass({
|
||||
|
||||
statics: {
|
||||
title: 'Accessibility',
|
||||
description: 'Examples of using Accessibility API.',
|
||||
},
|
||||
|
||||
getInitialState: function() {
|
||||
return {
|
||||
count: 0,
|
||||
talkbackEnabled: false,
|
||||
backgroundImportantForAcc: 0,
|
||||
forgroundImportantForAcc: 0,
|
||||
};
|
||||
},
|
||||
|
||||
componentDidMount: function() {
|
||||
AccessibilityInfo.addEventListener(
|
||||
'change',
|
||||
this._handleTouchExplorationChange
|
||||
);
|
||||
AccessibilityInfo.fetch().done((enabled) => {
|
||||
this.setState({
|
||||
count: this.state.count,
|
||||
talkbackEnabled: enabled}); }
|
||||
);
|
||||
},
|
||||
|
||||
componentWillUnmount: function() {
|
||||
AccessibilityInfo.removeEventListener(
|
||||
'change',
|
||||
this._handleTouchExplorationChange
|
||||
);
|
||||
},
|
||||
|
||||
_handleTouchExplorationChange: function(isEnabled) {
|
||||
this.setState({
|
||||
count: this.state.count,
|
||||
talkbackEnabled: isEnabled,
|
||||
});
|
||||
},
|
||||
|
||||
_showAccessibilityToast: function() {
|
||||
var text = 'TouchExploration is ' + (this.state.talkbackEnabled ? 'enabled' : 'disabled');
|
||||
ToastAndroid.show(text, ToastAndroid.SHORT);
|
||||
},
|
||||
|
||||
_addOne: function() {
|
||||
this.setState({
|
||||
count: ++this.state.count,
|
||||
talkbackEnabled: this.state.talkbackEnabled,
|
||||
});
|
||||
},
|
||||
|
||||
_changeBackgroundImportantForAcc: function() {
|
||||
this.setState({
|
||||
backgroundImportantForAcc: (this.state.backgroundImportantForAcc + 1) % 4,
|
||||
});
|
||||
},
|
||||
|
||||
_changeForgroundImportantForAcc: function() {
|
||||
this.setState({
|
||||
forgroundImportantForAcc: (this.state.forgroundImportantForAcc + 1) % 4,
|
||||
});
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return (
|
||||
<UIExplorerPage title={'Accessibility'}>
|
||||
|
||||
<UIExplorerBlock title="Nonaccessible view with TextViews">
|
||||
<View>
|
||||
<Text style={{color: 'green',}}>
|
||||
This is
|
||||
</Text>
|
||||
<Text style={{color: 'blue'}}>
|
||||
nontouchable normal view.
|
||||
</Text>
|
||||
</View>
|
||||
</UIExplorerBlock>
|
||||
|
||||
<UIExplorerBlock title="Accessible view with TextViews wihout label">
|
||||
<View accessible={true}>
|
||||
<Text style={{color: 'green',}}>
|
||||
This is
|
||||
</Text>
|
||||
<Text style={{color: 'blue'}}>
|
||||
nontouchable accessible view without label.
|
||||
</Text>
|
||||
</View>
|
||||
</UIExplorerBlock>
|
||||
|
||||
<UIExplorerBlock title="Accessible view with TextViews with label">
|
||||
<View accessible={true}
|
||||
accessibilityLabel="I have label, so I read it instead of embedded text.">
|
||||
<Text style={{color: 'green',}}>
|
||||
This is
|
||||
</Text>
|
||||
<Text style={{color: 'blue'}}>
|
||||
nontouchable accessible view with label.
|
||||
</Text>
|
||||
</View>
|
||||
</UIExplorerBlock>
|
||||
|
||||
<UIExplorerBlock title="Touchable with component type = button">
|
||||
<TouchableWithoutFeedback
|
||||
onPress={() => ToastAndroid.show('Toasts work by default', ToastAndroid.SHORT)}>
|
||||
<View style={styles.embedded} accessibilityComponentType="button">
|
||||
<Text>Click me</Text>
|
||||
<Text>Or not</Text>
|
||||
</View>
|
||||
</TouchableWithoutFeedback>
|
||||
</UIExplorerBlock>
|
||||
|
||||
<UIExplorerBlock title="LiveRegion">
|
||||
<TouchableWithoutFeedback onPress={this._addOne}>
|
||||
<View style={styles.embedded} accessibilityComponentType="button">
|
||||
<Text>Click me</Text>
|
||||
</View>
|
||||
</TouchableWithoutFeedback>
|
||||
<Text accessibilityLiveRegion="polite">
|
||||
Clicked {this.state.count} times
|
||||
</Text>
|
||||
</UIExplorerBlock>
|
||||
|
||||
<UIExplorerBlock title="Check if TouchExploration is enabled">
|
||||
<TouchableWithoutFeedback onPress={this._showAccessibilityToast}>
|
||||
<View style={styles.embedded}>
|
||||
<Text>
|
||||
Click to check TouchExploration
|
||||
</Text>
|
||||
</View>
|
||||
</TouchableWithoutFeedback>
|
||||
</UIExplorerBlock>
|
||||
|
||||
<UIExplorerBlock title="Overlapping views and importantForAccessibility property">
|
||||
<View style={styles.container}>
|
||||
<View
|
||||
style={{
|
||||
position: 'absolute',
|
||||
left: 10,
|
||||
top: 10,
|
||||
right: 10,
|
||||
height: 100,
|
||||
backgroundColor: 'green'}}
|
||||
accessible={true}
|
||||
accessibilityLabel="First layout"
|
||||
importantForAccessibility={
|
||||
importantForAccessibilityValues[this.state.backgroundImportantForAcc]}>
|
||||
<View accessible={true}>
|
||||
<Text style={{fontSize: 25}}>
|
||||
Hello
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
<View
|
||||
style={{
|
||||
position: 'absolute',
|
||||
left: 10,
|
||||
top: 25,
|
||||
right: 10,
|
||||
height: 110,
|
||||
backgroundColor: 'yellow', opacity: 0.5}}
|
||||
accessible={true}
|
||||
accessibilityLabel="Second layout"
|
||||
importantForAccessibility={
|
||||
importantForAccessibilityValues[this.state.forgroundImportantForAcc]}>
|
||||
<View accessible={true}>
|
||||
<Text style={{fontSize: 20}}>
|
||||
world
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
<TouchableWithoutFeedback onPress={this._changeBackgroundImportantForAcc}>
|
||||
<View style={styles.embedded}>
|
||||
<Text>
|
||||
Change importantForAccessibility for background layout.
|
||||
</Text>
|
||||
</View>
|
||||
</TouchableWithoutFeedback>
|
||||
<View accessible={true}>
|
||||
<Text>
|
||||
Background layout importantForAccessibility
|
||||
</Text>
|
||||
<Text>
|
||||
{importantForAccessibilityValues[this.state.backgroundImportantForAcc]}
|
||||
</Text>
|
||||
</View>
|
||||
<TouchableWithoutFeedback onPress={this._changeForgroundImportantForAcc}>
|
||||
<View style={styles.embedded}>
|
||||
<Text>
|
||||
Change importantForAccessibility for forground layout.
|
||||
</Text>
|
||||
</View>
|
||||
</TouchableWithoutFeedback>
|
||||
<View accessible={true}>
|
||||
<Text>
|
||||
Forground layout importantForAccessibility
|
||||
</Text>
|
||||
<Text>
|
||||
{importantForAccessibilityValues[this.state.forgroundImportantForAcc]}
|
||||
</Text>
|
||||
</View>
|
||||
</UIExplorerBlock>
|
||||
|
||||
</UIExplorerPage>
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
var styles = StyleSheet.create({
|
||||
embedded: {
|
||||
backgroundColor: 'yellow',
|
||||
padding:10,
|
||||
},
|
||||
container: {
|
||||
flex: 1,
|
||||
backgroundColor: 'white',
|
||||
padding: 10,
|
||||
height:150,
|
||||
},
|
||||
});
|
||||
|
||||
module.exports = AccessibilityAndroidExample;
|
||||
@@ -17,11 +17,12 @@
|
||||
|
||||
var React = require('react-native');
|
||||
var {
|
||||
ActionSheetIOS,
|
||||
StyleSheet,
|
||||
Text,
|
||||
View,
|
||||
} = React;
|
||||
var ActionSheetIOS = require('ActionSheetIOS');
|
||||
|
||||
var BUTTONS = [
|
||||
'Button Index: 0',
|
||||
'Button Index: 1',
|
||||
|
||||
@@ -15,10 +15,9 @@
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var AdSupportIOS = require('AdSupportIOS');
|
||||
|
||||
var React = require('react-native');
|
||||
var {
|
||||
AdSupportIOS,
|
||||
StyleSheet,
|
||||
Text,
|
||||
View,
|
||||
|
||||
@@ -0,0 +1,321 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* @providesModule AnExApp
|
||||
* @flow
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var React = require('react-native');
|
||||
var {
|
||||
Animated,
|
||||
LayoutAnimation,
|
||||
PanResponder,
|
||||
StyleSheet,
|
||||
View,
|
||||
} = React;
|
||||
|
||||
var AnExSet = require('AnExSet');
|
||||
|
||||
var CIRCLE_SIZE = 80;
|
||||
var CIRCLE_MARGIN = 18;
|
||||
var NUM_CIRCLES = 30;
|
||||
|
||||
class Circle extends React.Component {
|
||||
_onLongPress: () => void;
|
||||
_toggleIsActive: () => void;
|
||||
constructor(props: Object): void {
|
||||
super();
|
||||
this._onLongPress = this._onLongPress.bind(this);
|
||||
this._toggleIsActive = this._toggleIsActive.bind(this);
|
||||
this.state = {
|
||||
isActive: false,
|
||||
pan: new Animated.ValueXY(), // Vectors reduce boilerplate. (step1: uncomment)
|
||||
pop: new Animated.Value(0), // Initial value. (step2a: uncomment)
|
||||
};
|
||||
}
|
||||
|
||||
_onLongPress(): void {
|
||||
var config = {tension: 40, friction: 3};
|
||||
this.state.pan.addListener((value) => { // Async listener for state changes (step1: uncomment)
|
||||
this.props.onMove && this.props.onMove(value);
|
||||
});
|
||||
Animated.spring(this.state.pop, {
|
||||
toValue: 1, // Pop to larger size. (step2b: uncomment)
|
||||
...config, // Reuse config for convenient consistency (step2b: uncomment)
|
||||
}).start();
|
||||
this.setState({panResponder: PanResponder.create({
|
||||
onPanResponderMove: Animated.event([
|
||||
null, // native event - ignore (step1: uncomment)
|
||||
{dx: this.state.pan.x, dy: this.state.pan.y}, // links pan to gestureState (step1: uncomment)
|
||||
]),
|
||||
onPanResponderRelease: (e, gestureState) => {
|
||||
LayoutAnimation.easeInEaseOut(); // @flowfixme animates layout update as one batch (step3: uncomment)
|
||||
Animated.spring(this.state.pop, {
|
||||
toValue: 0, // Pop back to 0 (step2c: uncomment)
|
||||
...config,
|
||||
}).start();
|
||||
this.setState({panResponder: undefined});
|
||||
this.props.onMove && this.props.onMove({
|
||||
x: gestureState.dx + this.props.restLayout.x,
|
||||
y: gestureState.dy + this.props.restLayout.y,
|
||||
});
|
||||
this.props.onDeactivate();
|
||||
},
|
||||
})}, () => {
|
||||
this.props.onActivate();
|
||||
});
|
||||
}
|
||||
|
||||
render(): ReactElement {
|
||||
if (this.state.panResponder) {
|
||||
var handlers = this.state.panResponder.panHandlers;
|
||||
var dragStyle = { // Used to position while dragging
|
||||
position: 'absolute', // Hoist out of layout (step1: uncomment)
|
||||
...this.state.pan.getLayout(), // Convenience converter (step1: uncomment)
|
||||
};
|
||||
} else {
|
||||
handlers = {
|
||||
onStartShouldSetResponder: () => !this.state.isActive,
|
||||
onResponderGrant: () => {
|
||||
this.state.pan.setValue({x: 0, y: 0}); // reset (step1: uncomment)
|
||||
this.state.pan.setOffset(this.props.restLayout); // offset from onLayout (step1: uncomment)
|
||||
this.longTimer = setTimeout(this._onLongPress, 300);
|
||||
},
|
||||
onResponderRelease: () => {
|
||||
if (!this.state.panResponder) {
|
||||
clearTimeout(this.longTimer);
|
||||
this._toggleIsActive();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
var animatedStyle: Object = {
|
||||
shadowOpacity: this.state.pop, // no need for interpolation (step2d: uncomment)
|
||||
transform: [
|
||||
{scale: this.state.pop.interpolate({
|
||||
inputRange: [0, 1],
|
||||
outputRange: [1, 1.3] // scale up from 1 to 1.3 (step2d: uncomment)
|
||||
})},
|
||||
],
|
||||
};
|
||||
var openVal = this.props.openVal;
|
||||
if (this.props.dummy) {
|
||||
animatedStyle.opacity = 0;
|
||||
} else if (this.state.isActive) {
|
||||
var innerOpenStyle = [styles.open, { // (step4: uncomment)
|
||||
left: openVal.interpolate({inputRange: [0, 1], outputRange: [this.props.restLayout.x, 0]}),
|
||||
top: openVal.interpolate({inputRange: [0, 1], outputRange: [this.props.restLayout.y, 0]}),
|
||||
width: openVal.interpolate({inputRange: [0, 1], outputRange: [CIRCLE_SIZE, this.props.containerLayout.width]}),
|
||||
height: openVal.interpolate({inputRange: [0, 1], outputRange: [CIRCLE_SIZE, this.props.containerLayout.height]}),
|
||||
margin: openVal.interpolate({inputRange: [0, 1], outputRange: [CIRCLE_MARGIN, 0]}),
|
||||
borderRadius: openVal.interpolate({inputRange: [-0.15, 0, 0.5, 1], outputRange: [0, CIRCLE_SIZE / 2, CIRCLE_SIZE * 1.3, 0]}),
|
||||
}];
|
||||
}
|
||||
return (
|
||||
<Animated.View
|
||||
onLayout={this.props.onLayout}
|
||||
style={[styles.dragView, dragStyle, animatedStyle, this.state.isActive ? styles.open : null]}
|
||||
{...handlers}>
|
||||
<Animated.View style={[styles.circle, innerOpenStyle]}>
|
||||
<AnExSet
|
||||
containerLayout={this.props.containerLayout}
|
||||
id={this.props.id}
|
||||
isActive={this.state.isActive}
|
||||
openVal={this.props.openVal}
|
||||
onDismiss={this._toggleIsActive}
|
||||
/>
|
||||
</Animated.View>
|
||||
</Animated.View>
|
||||
);
|
||||
}
|
||||
_toggleIsActive(velocity) {
|
||||
var config = {tension: 30, friction: 7};
|
||||
if (this.state.isActive) {
|
||||
Animated.spring(this.props.openVal, {toValue: 0, ...config}).start(() => { // (step4: uncomment)
|
||||
this.setState({isActive: false}, this.props.onDeactivate);
|
||||
}); // (step4: uncomment)
|
||||
} else {
|
||||
this.props.onActivate();
|
||||
this.setState({isActive: true, panResponder: undefined}, () => {
|
||||
// this.props.openVal.setValue(1); // (step4: comment)
|
||||
Animated.spring(this.props.openVal, {toValue: 1, ...config}).start(); // (step4: uncomment)
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class AnExApp extends React.Component {
|
||||
_onMove: (position: Point) => void;
|
||||
constructor(props: any): void {
|
||||
super(props);
|
||||
var keys = [];
|
||||
for (var idx = 0; idx < NUM_CIRCLES; idx++) {
|
||||
keys.push('E' + idx);
|
||||
}
|
||||
this.state = {
|
||||
keys,
|
||||
restLayouts: [],
|
||||
openVal: new Animated.Value(0),
|
||||
};
|
||||
this._onMove = this._onMove.bind(this);
|
||||
}
|
||||
|
||||
render(): ReactElement {
|
||||
var circles = this.state.keys.map((key, idx) => {
|
||||
if (key === this.state.activeKey) {
|
||||
return <Circle key={key + 'd'} dummy={true} />;
|
||||
} else {
|
||||
if (!this.state.restLayouts[idx]) {
|
||||
var onLayout = function(index, e) {
|
||||
var layout = e.nativeEvent.layout;
|
||||
this.setState((state) => {
|
||||
state.restLayouts[index] = layout;
|
||||
return state;
|
||||
});
|
||||
}.bind(this, idx);
|
||||
}
|
||||
return (
|
||||
<Circle
|
||||
key={key}
|
||||
id={key}
|
||||
openVal={this.state.openVal}
|
||||
onLayout={onLayout}
|
||||
restLayout={this.state.restLayouts[idx]}
|
||||
onActivate={this.setState.bind(this, {
|
||||
activeKey: key,
|
||||
activeInitialLayout: this.state.restLayouts[idx],
|
||||
})}
|
||||
/>
|
||||
);
|
||||
}
|
||||
});
|
||||
if (this.state.activeKey) {
|
||||
circles.push(
|
||||
<Animated.View key="dark" style={[styles.darkening, {opacity: this.state.openVal}]} />
|
||||
);
|
||||
circles.push(
|
||||
<Circle
|
||||
openVal={this.state.openVal}
|
||||
key={this.state.activeKey}
|
||||
id={this.state.activeKey}
|
||||
restLayout={this.state.activeInitialLayout}
|
||||
containerLayout={this.state.layout}
|
||||
onMove={this._onMove}
|
||||
onDeactivate={() => { this.setState({activeKey: undefined}); }}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<View style={styles.grid} onLayout={(e) => this.setState({layout: e.nativeEvent.layout})}>
|
||||
{circles}
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
_onMove(position: Point): void {
|
||||
var newKeys = moveToClosest(this.state, position);
|
||||
if (newKeys !== this.state.keys) {
|
||||
LayoutAnimation.easeInEaseOut(); // animates layout update as one batch (step3: uncomment)
|
||||
this.setState({keys: newKeys});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type Point = {x: number, y: number};
|
||||
function distance(p1: Point, p2: Point): number {
|
||||
var dx = p1.x - p2.x;
|
||||
var dy = p1.y - p2.y;
|
||||
return dx * dx + dy * dy;
|
||||
}
|
||||
|
||||
function moveToClosest({activeKey, keys, restLayouts}, position) {
|
||||
var activeIdx = -1;
|
||||
var closestIdx = activeIdx;
|
||||
var minDist = Infinity;
|
||||
var newKeys = [];
|
||||
keys.forEach((key, idx) => {
|
||||
var dist = distance(position, restLayouts[idx]);
|
||||
if (key === activeKey) {
|
||||
idx = activeIdx;
|
||||
} else {
|
||||
newKeys.push(key);
|
||||
}
|
||||
if (dist < minDist) {
|
||||
minDist = dist;
|
||||
closestIdx = idx;
|
||||
}
|
||||
});
|
||||
if (closestIdx === activeIdx) {
|
||||
return keys; // nothing changed
|
||||
} else {
|
||||
newKeys.splice(closestIdx, 0, activeKey);
|
||||
return newKeys;
|
||||
}
|
||||
}
|
||||
|
||||
AnExApp.title = 'Animated - Gratuitous App';
|
||||
AnExApp.description = 'Bunch of Animations - tap a circle to ' +
|
||||
'open a view with more animations, or longPress and drag to reorder circles.';
|
||||
|
||||
var styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
paddingTop: 64, // push content below nav bar
|
||||
},
|
||||
grid: {
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
flexDirection: 'row',
|
||||
flexWrap: 'wrap',
|
||||
backgroundColor: 'transparent',
|
||||
},
|
||||
circle: {
|
||||
width: CIRCLE_SIZE,
|
||||
height: CIRCLE_SIZE,
|
||||
borderRadius: CIRCLE_SIZE / 2,
|
||||
borderWidth: 1,
|
||||
borderColor: 'black',
|
||||
margin: CIRCLE_MARGIN,
|
||||
overflow: 'hidden',
|
||||
},
|
||||
dragView: {
|
||||
shadowRadius: 10,
|
||||
shadowColor: 'rgba(0,0,0,0.7)',
|
||||
shadowOffset: {height: 8},
|
||||
alignSelf: 'flex-start',
|
||||
backgroundColor: 'transparent',
|
||||
},
|
||||
open: {
|
||||
position: 'absolute',
|
||||
left: 0,
|
||||
top: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
width: undefined, // unset value from styles.circle
|
||||
height: undefined, // unset value from styles.circle
|
||||
borderRadius: 0, // unset value from styles.circle
|
||||
},
|
||||
darkening: {
|
||||
backgroundColor: 'black',
|
||||
position: 'absolute',
|
||||
left: 0,
|
||||
top: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
},
|
||||
});
|
||||
|
||||
module.exports = AnExApp;
|
||||
@@ -0,0 +1,162 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* @providesModule AnExBobble
|
||||
* @flow
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var React = require('react-native');
|
||||
var {
|
||||
Animated,
|
||||
Image,
|
||||
PanResponder,
|
||||
StyleSheet,
|
||||
View,
|
||||
} = React;
|
||||
|
||||
var NUM_BOBBLES = 5;
|
||||
var RAD_EACH = Math.PI / 2 / (NUM_BOBBLES - 2);
|
||||
var RADIUS = 160;
|
||||
var BOBBLE_SPOTS = [...Array(NUM_BOBBLES)].map((_, i) => { // static positions
|
||||
return i === 0 ? {x: 0, y: 0} : { // first bobble is the selector
|
||||
x: -Math.cos(RAD_EACH * (i - 1)) * RADIUS,
|
||||
y: -Math.sin(RAD_EACH * (i - 1)) * RADIUS,
|
||||
};
|
||||
});
|
||||
|
||||
class AnExBobble extends React.Component {
|
||||
constructor(props: Object) {
|
||||
super(props);
|
||||
this.state = {};
|
||||
this.state.bobbles = BOBBLE_SPOTS.map((_, i) => {
|
||||
return new Animated.ValueXY();
|
||||
});
|
||||
this.state.selectedBobble = null;
|
||||
var bobblePanListener = (e, gestureState) => { // async events => change selection
|
||||
var newSelected = computeNewSelected(gestureState);
|
||||
if (this.state.selectedBobble !== newSelected) {
|
||||
if (this.state.selectedBobble !== null) {
|
||||
var restSpot = BOBBLE_SPOTS[this.state.selectedBobble];
|
||||
Animated.spring(this.state.bobbles[this.state.selectedBobble], {
|
||||
toValue: restSpot, // return previously selected bobble to rest position
|
||||
}).start();
|
||||
}
|
||||
if (newSelected !== null && newSelected !== 0) {
|
||||
Animated.spring(this.state.bobbles[newSelected], {
|
||||
toValue: this.state.bobbles[0], // newly selected should track the selector
|
||||
}).start();
|
||||
}
|
||||
this.state.selectedBobble = newSelected;
|
||||
}
|
||||
};
|
||||
var releaseBobble = () => {
|
||||
this.state.bobbles.forEach((bobble, i) => {
|
||||
Animated.spring(bobble, {
|
||||
toValue: {x: 0, y: 0} // all bobbles return to zero
|
||||
}).start();
|
||||
});
|
||||
};
|
||||
this.state.bobbleResponder = PanResponder.create({
|
||||
onStartShouldSetPanResponder: () => true,
|
||||
onPanResponderGrant: () => {
|
||||
BOBBLE_SPOTS.forEach((spot, idx) => {
|
||||
Animated.spring(this.state.bobbles[idx], {
|
||||
toValue: spot, // spring each bobble to its spot
|
||||
friction: 3, // less friction => bouncier
|
||||
}).start();
|
||||
});
|
||||
},
|
||||
onPanResponderMove: Animated.event(
|
||||
[ null, {dx: this.state.bobbles[0].x, dy: this.state.bobbles[0].y} ],
|
||||
{listener: bobblePanListener} // async state changes with arbitrary logic
|
||||
),
|
||||
onPanResponderRelease: releaseBobble,
|
||||
onPanResponderTerminate: releaseBobble,
|
||||
});
|
||||
}
|
||||
|
||||
render(): ReactElement {
|
||||
return (
|
||||
<View style={styles.bobbleContainer}>
|
||||
{this.state.bobbles.map((_, i) => {
|
||||
var j = this.state.bobbles.length - i - 1; // reverse so lead on top
|
||||
var handlers = j > 0 ? {} : this.state.bobbleResponder.panHandlers;
|
||||
return (
|
||||
<Animated.Image
|
||||
{...handlers}
|
||||
source={{uri: BOBBLE_IMGS[j]}}
|
||||
style={[styles.circle, {
|
||||
backgroundColor: randColor(), // re-renders are obvious
|
||||
transform: this.state.bobbles[j].getTranslateTransform(), // simple conversion
|
||||
}]}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
var styles = StyleSheet.create({
|
||||
circle: {
|
||||
position: 'absolute',
|
||||
height: 60,
|
||||
width: 60,
|
||||
borderRadius: 30,
|
||||
borderWidth: 0.5,
|
||||
},
|
||||
bobbleContainer: {
|
||||
top: -68,
|
||||
paddingRight: 66,
|
||||
flexDirection: 'row',
|
||||
flex: 1,
|
||||
justifyContent: 'flex-end',
|
||||
backgroundColor: 'transparent',
|
||||
},
|
||||
});
|
||||
|
||||
function computeNewSelected(
|
||||
gestureState: Object,
|
||||
): ?number {
|
||||
var {dx, dy} = gestureState;
|
||||
var minDist = Infinity;
|
||||
var newSelected = null;
|
||||
var pointRadius = Math.sqrt(dx * dx + dy * dy);
|
||||
if (Math.abs(RADIUS - pointRadius) < 80) {
|
||||
BOBBLE_SPOTS.forEach((spot, idx) => {
|
||||
var delta = {x: spot.x - dx, y: spot.y - dy};
|
||||
var dist = delta.x * delta.x + delta.y * delta.y;
|
||||
if (dist < minDist) {
|
||||
minDist = dist;
|
||||
newSelected = idx;
|
||||
}
|
||||
});
|
||||
}
|
||||
return newSelected;
|
||||
}
|
||||
|
||||
function randColor(): string {
|
||||
var colors = [0,1,2].map(() => Math.floor(Math.random() * 150 + 100));
|
||||
return 'rgb(' + colors.join(',') + ')';
|
||||
}
|
||||
|
||||
var BOBBLE_IMGS = [
|
||||
'https://scontent-sea1-1.xx.fbcdn.net/hphotos-xpf1/t39.1997-6/10173489_272703316237267_1025826781_n.png',
|
||||
'https://scontent-sea1-1.xx.fbcdn.net/hphotos-xaf1/l/t39.1997-6/p240x240/851578_631487400212668_2087073502_n.png',
|
||||
'https://scontent-sea1-1.xx.fbcdn.net/hphotos-xaf1/t39.1997-6/p240x240/851583_654446917903722_178118452_n.png',
|
||||
'https://scontent-sea1-1.xx.fbcdn.net/hphotos-xaf1/t39.1997-6/p240x240/851565_641023175913294_875343096_n.png',
|
||||
'https://scontent-sea1-1.xx.fbcdn.net/hphotos-xaf1/t39.1997-6/851562_575284782557566_1188781517_n.png',
|
||||
];
|
||||
|
||||
module.exports = AnExBobble;
|
||||
@@ -0,0 +1,114 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* @providesModule AnExChained
|
||||
* @flow
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var React = require('react-native');
|
||||
var {
|
||||
Animated,
|
||||
Image,
|
||||
PanResponder,
|
||||
StyleSheet,
|
||||
View,
|
||||
} = React;
|
||||
|
||||
class AnExChained extends React.Component {
|
||||
constructor(props: Object) {
|
||||
super(props);
|
||||
this.state = {
|
||||
stickers: [new Animated.ValueXY()], // 1 leader
|
||||
};
|
||||
var stickerConfig = {tension: 2, friction: 3}; // soft spring
|
||||
for (var i = 0; i < 4; i++) { // 4 followers
|
||||
var sticker = new Animated.ValueXY();
|
||||
Animated.spring(sticker, {
|
||||
...stickerConfig,
|
||||
toValue: this.state.stickers[i], // Animated toValue's are tracked
|
||||
}).start();
|
||||
this.state.stickers.push(sticker); // push on the followers
|
||||
}
|
||||
var releaseChain = (e, gestureState) => {
|
||||
this.state.stickers[0].flattenOffset(); // merges offset into value and resets
|
||||
Animated.sequence([ // spring to start after decay finishes
|
||||
Animated.decay(this.state.stickers[0], { // coast to a stop
|
||||
velocity: {x: gestureState.vx, y: gestureState.vy},
|
||||
deceleration: 0.997,
|
||||
}),
|
||||
Animated.spring(this.state.stickers[0], {
|
||||
toValue: {x: 0, y: 0} // return to start
|
||||
}),
|
||||
]).start();
|
||||
};
|
||||
this.state.chainResponder = PanResponder.create({
|
||||
onStartShouldSetPanResponder: () => true,
|
||||
onPanResponderGrant: () => {
|
||||
this.state.stickers[0].stopAnimation((value) => {
|
||||
this.state.stickers[0].setOffset(value); // start where sticker animated to
|
||||
this.state.stickers[0].setValue({x: 0, y: 0}); // avoid flicker before next event
|
||||
});
|
||||
},
|
||||
onPanResponderMove: Animated.event(
|
||||
[null, {dx: this.state.stickers[0].x, dy: this.state.stickers[0].y}] // map gesture to leader
|
||||
),
|
||||
onPanResponderRelease: releaseChain,
|
||||
onPanResponderTerminate: releaseChain,
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<View style={styles.chained}>
|
||||
{this.state.stickers.map((_, i) => {
|
||||
var j = this.state.stickers.length - i - 1; // reverse so leader is on top
|
||||
var handlers = (j === 0) ? this.state.chainResponder.panHandlers : {};
|
||||
return (
|
||||
<Animated.Image
|
||||
{...handlers}
|
||||
source={{uri: CHAIN_IMGS[j]}}
|
||||
style={[styles.sticker, {
|
||||
transform: this.state.stickers[j].getTranslateTransform(), // simple conversion
|
||||
}]}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
var styles = StyleSheet.create({
|
||||
chained: {
|
||||
alignSelf: 'flex-end',
|
||||
top: -160,
|
||||
right: 126
|
||||
},
|
||||
sticker: {
|
||||
position: 'absolute',
|
||||
height: 120,
|
||||
width: 120,
|
||||
backgroundColor: 'transparent',
|
||||
},
|
||||
});
|
||||
|
||||
var CHAIN_IMGS = [
|
||||
'https://scontent-sea1-1.xx.fbcdn.net/hphotos-xpf1/t39.1997-6/p160x160/10574705_1529175770666007_724328156_n.png',
|
||||
'https://fbcdn-dragon-a.akamaihd.net/hphotos-ak-xfa1/t39.1997-6/p160x160/851575_392309884199657_1917957497_n.png',
|
||||
'https://fbcdn-dragon-a.akamaihd.net/hphotos-ak-xfa1/t39.1997-6/p160x160/851567_555288911225630_1628791128_n.png',
|
||||
'https://scontent-sea1-1.xx.fbcdn.net/hphotos-xfa1/t39.1997-6/p160x160/851583_531111513625557_903469595_n.png',
|
||||
'https://scontent-sea1-1.xx.fbcdn.net/hphotos-xpa1/t39.1997-6/p160x160/851577_510515972354399_2147096990_n.png',
|
||||
];
|
||||
|
||||
module.exports = AnExChained;
|
||||
@@ -0,0 +1,115 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* @providesModule AnExScroll
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var React = require('react-native');
|
||||
var {
|
||||
Animated,
|
||||
Image,
|
||||
ScrollView,
|
||||
StyleSheet,
|
||||
Text,
|
||||
View,
|
||||
} = React;
|
||||
|
||||
class AnExScroll extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
scrollX: new Animated.Value(0),
|
||||
};
|
||||
}
|
||||
|
||||
render() {
|
||||
var width = this.props.panelWidth;
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<ScrollView
|
||||
automaticallyAdjustContentInsets={false}
|
||||
scrollEventThrottle={16 /* get all events */ }
|
||||
onScroll={Animated.event(
|
||||
[{nativeEvent: {contentOffset: {x: this.state.scrollX}}}] // nested event mapping
|
||||
)}
|
||||
contentContainerStyle={{flex: 1, padding: 10}}
|
||||
pagingEnabled={true}
|
||||
horizontal={true}>
|
||||
<View style={[styles.page, {width}]}>
|
||||
<Image
|
||||
style={{width: 180, height: 180}}
|
||||
source={HAWK_PIC}
|
||||
/>
|
||||
<Text style={styles.text}>
|
||||
{'I\'ll find something to put here.'}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={[styles.page, {width}]}>
|
||||
<Text style={styles.text}>{'And here.'}</Text>
|
||||
</View>
|
||||
<View style={[styles.page, {width}]}>
|
||||
<Text>{'But not here.'}</Text>
|
||||
</View>
|
||||
</ScrollView>
|
||||
<Animated.Image
|
||||
pointerEvents="none"
|
||||
style={[styles.bunny, {transform: [
|
||||
{translateX: this.state.scrollX.interpolate({
|
||||
inputRange: [0, width, 2 * width],
|
||||
outputRange: [0, 0, width / 3]}), // multi-part ranges
|
||||
extrapolate: 'clamp'}, // default is 'extend'
|
||||
{translateY: this.state.scrollX.interpolate({
|
||||
inputRange: [0, width, 2 * width],
|
||||
outputRange: [0, -200, -260]}),
|
||||
extrapolate: 'clamp'},
|
||||
{scale: this.state.scrollX.interpolate({
|
||||
inputRange: [0, width, 2 * width],
|
||||
outputRange: [0.5, 0.5, 2]}),
|
||||
extrapolate: 'clamp'},
|
||||
]}]}
|
||||
source={BUNNY_PIC}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
var styles = StyleSheet.create({
|
||||
container: {
|
||||
backgroundColor: 'transparent',
|
||||
flex: 1,
|
||||
},
|
||||
text: {
|
||||
padding: 4,
|
||||
paddingBottom: 10,
|
||||
fontWeight: 'bold',
|
||||
fontSize: 18,
|
||||
backgroundColor: 'transparent',
|
||||
},
|
||||
bunny: {
|
||||
backgroundColor: 'transparent',
|
||||
position: 'absolute',
|
||||
height: 160,
|
||||
width: 160,
|
||||
},
|
||||
page: {
|
||||
alignItems: 'center',
|
||||
justifyContent: 'flex-end',
|
||||
},
|
||||
});
|
||||
|
||||
var HAWK_PIC = {uri: 'https://scontent-sea1-1.xx.fbcdn.net/hphotos-xfa1/t39.1997-6/10734304_1562225620659674_837511701_n.png'};
|
||||
var BUNNY_PIC = {uri: 'https://scontent-sea1-1.xx.fbcdn.net/hphotos-xaf1/t39.1997-6/851564_531111380292237_1898871086_n.png'};
|
||||
|
||||
module.exports = AnExScroll;
|
||||
@@ -0,0 +1,150 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* @providesModule AnExSet
|
||||
* @flow
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var React = require('react-native');
|
||||
var {
|
||||
Animated,
|
||||
PanResponder,
|
||||
StyleSheet,
|
||||
Text,
|
||||
View,
|
||||
} = React;
|
||||
|
||||
var AnExBobble = require('./AnExBobble');
|
||||
var AnExChained = require('./AnExChained');
|
||||
var AnExScroll = require('./AnExScroll');
|
||||
var AnExTilt = require('./AnExTilt');
|
||||
|
||||
class AnExSet extends React.Component {
|
||||
constructor(props: Object) {
|
||||
super(props);
|
||||
function randColor() {
|
||||
var colors = [0,1,2].map(() => Math.floor(Math.random() * 150 + 100));
|
||||
return 'rgb(' + colors.join(',') + ')';
|
||||
}
|
||||
this.state = {
|
||||
closeColor: randColor(),
|
||||
openColor: randColor(),
|
||||
};
|
||||
}
|
||||
render(): ReactElement {
|
||||
var backgroundColor = this.props.openVal ?
|
||||
this.props.openVal.interpolate({
|
||||
inputRange: [0, 1],
|
||||
outputRange: [
|
||||
this.state.closeColor, // interpolates color strings
|
||||
this.state.openColor
|
||||
],
|
||||
}) :
|
||||
this.state.closeColor;
|
||||
var panelWidth = this.props.containerLayout && this.props.containerLayout.width || 320;
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<Animated.View
|
||||
style={[styles.header, { backgroundColor }]}
|
||||
{...this.state.dismissResponder.panHandlers}>
|
||||
<Text style={[styles.text, styles.headerText]}>
|
||||
{this.props.id}
|
||||
</Text>
|
||||
</Animated.View>
|
||||
{this.props.isActive &&
|
||||
<View style={styles.stream}>
|
||||
<View style={styles.card}>
|
||||
<Text style={styles.text}>
|
||||
July 2nd
|
||||
</Text>
|
||||
<AnExTilt isActive={this.props.isActive} />
|
||||
<AnExBobble />
|
||||
</View>
|
||||
<AnExScroll panelWidth={panelWidth}/>
|
||||
<AnExChained />
|
||||
</View>
|
||||
}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
componentWillMount() {
|
||||
this.state.dismissY = new Animated.Value(0);
|
||||
this.state.dismissResponder = PanResponder.create({
|
||||
onStartShouldSetPanResponder: () => this.props.isActive,
|
||||
onPanResponderGrant: () => {
|
||||
Animated.spring(this.props.openVal, { // Animated value passed in.
|
||||
toValue: this.state.dismissY.interpolate({ // Track dismiss gesture
|
||||
inputRange: [0, 300], // and interpolate pixel distance
|
||||
outputRange: [1, 0], // to a fraction.
|
||||
})
|
||||
}).start();
|
||||
},
|
||||
onPanResponderMove: Animated.event(
|
||||
[null, {dy: this.state.dismissY}] // track pan gesture
|
||||
),
|
||||
onPanResponderRelease: (e, gestureState) => {
|
||||
if (gestureState.dy > 100) {
|
||||
this.props.onDismiss(gestureState.vy); // delegates dismiss action to parent
|
||||
} else {
|
||||
Animated.spring(this.props.openVal, {
|
||||
toValue: 1, // animate back open if released early
|
||||
}).start();
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
var styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
},
|
||||
header: {
|
||||
alignItems: 'center',
|
||||
paddingTop: 18,
|
||||
height: 90,
|
||||
},
|
||||
stream: {
|
||||
flex: 1,
|
||||
backgroundColor: 'rgb(230, 230, 230)',
|
||||
},
|
||||
card: {
|
||||
margin: 8,
|
||||
padding: 8,
|
||||
borderRadius: 6,
|
||||
backgroundColor: 'white',
|
||||
shadowRadius: 2,
|
||||
shadowColor: 'black',
|
||||
shadowOpacity: 0.2,
|
||||
shadowOffset: {height: 0.5},
|
||||
},
|
||||
text: {
|
||||
padding: 4,
|
||||
paddingBottom: 10,
|
||||
fontWeight: 'bold',
|
||||
fontSize: 18,
|
||||
backgroundColor: 'transparent',
|
||||
},
|
||||
headerText: {
|
||||
fontSize: 25,
|
||||
color: 'white',
|
||||
shadowRadius: 3,
|
||||
shadowColor: 'black',
|
||||
shadowOpacity: 1,
|
||||
shadowOffset: {height: 1},
|
||||
},
|
||||
});
|
||||
|
||||
module.exports = AnExSet;
|
||||
@@ -0,0 +1,107 @@
|
||||
<br /><br />
|
||||
# React Native: Animated
|
||||
|
||||
ReactEurope 2015, Paris - Spencer Ahrens - Facebook
|
||||
|
||||
<br /><br />
|
||||
|
||||
## Fluid Interactions
|
||||
|
||||
- People expect smooth, delightful experiences
|
||||
- Complex interactions are hard
|
||||
- Common patterns can be optimized
|
||||
|
||||
<br /><br />
|
||||
|
||||
|
||||
## Declarative Interactions
|
||||
|
||||
- Wire up inputs (events) to outputs (props) + transforms (springs, easing, etc.)
|
||||
- Arbitrary code can define/update this config
|
||||
- Config can be serialized -> native/main thread
|
||||
- No refs or lifecycle to worry about
|
||||
|
||||
<br /><br />
|
||||
|
||||
|
||||
## var { Animated } = require('react-native');
|
||||
|
||||
- New library soon to be released for React Native
|
||||
- 100% JS implementation -> X-Platform
|
||||
- Per-platform native optimizations planned
|
||||
- This talk -> usage examples, not implementation
|
||||
|
||||
<br /><br />
|
||||
|
||||
|
||||
## Gratuitous Animation Demo App
|
||||
|
||||
- Layout uses `flexWrap: 'wrap'`
|
||||
- longPress -> drag to reorder
|
||||
- Tap to open example sets
|
||||
|
||||
<br /><br />
|
||||
|
||||
## Gratuitous Animation Codez
|
||||
|
||||
- Step 1: 2D tracking pan gesture
|
||||
- Step 2: Simple pop-out spring on select
|
||||
- Step 3: Animate grid reordering with `LayoutAnimation`
|
||||
- Step 4: Opening animation
|
||||
|
||||
<br /><br />
|
||||
|
||||
## Animation Example Set
|
||||
|
||||
- `Animated.Value` `this.props.open` passed in from parent
|
||||
- `interpolate` works with string "shapes," e.g. `'rgb(0, 0, 255)'`, `'45deg'`
|
||||
- Examples easily composed as separate components
|
||||
- Dismissing tracks interpolated gesture
|
||||
- Custom release logic
|
||||
|
||||
<br /><br />
|
||||
|
||||
|
||||
## Tilting Photo
|
||||
|
||||
- Pan -> translateX * 2, rotate, opacity (via tracking)
|
||||
- Gesture release triggers separate animations
|
||||
- `addListener` for async, arbitrary logic on animation progress
|
||||
- `interpolate` easily creates parallax and other effects
|
||||
|
||||
<br /><br />
|
||||
|
||||
## Bobbles
|
||||
|
||||
- Static positions defined
|
||||
- Listens to events to maybe change selection
|
||||
- Springs previous selection back
|
||||
- New selection tracks selector
|
||||
- `getTranslateTransform` adds convenience
|
||||
|
||||
<br /><br />
|
||||
|
||||
## Chained
|
||||
|
||||
- Classic "Chat Heads" animation
|
||||
- Each sticker tracks the one before it with a soft spring
|
||||
- `decay` maintains gesture velocity, followed by `spring` to home
|
||||
- `stopAnimation` provides the last value for `setOffset`
|
||||
|
||||
<br /><br />
|
||||
|
||||
## Scrolling
|
||||
|
||||
- `Animated.event` can track all sorts of stuff
|
||||
- Multi-part ranges and extrapolation options
|
||||
- Transforms decompose into ordered components
|
||||
|
||||
<br /><br />
|
||||
|
||||
# React Native: Animated
|
||||
|
||||
- Landing soon in master (days)
|
||||
- GitHub: @vjeux, @sahrens
|
||||
- Questions?
|
||||
|
||||
<br />
|
||||
@@ -0,0 +1,139 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* @providesModule AnExTilt
|
||||
* @flow
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var React = require('react-native');
|
||||
var {
|
||||
Animated,
|
||||
Image,
|
||||
PanResponder,
|
||||
StyleSheet,
|
||||
View,
|
||||
} = React;
|
||||
|
||||
class AnExTilt extends React.Component {
|
||||
constructor(props: Object) {
|
||||
super(props);
|
||||
this.state = {
|
||||
panX: new Animated.Value(0),
|
||||
opacity: new Animated.Value(1),
|
||||
burns: new Animated.Value(1.15),
|
||||
};
|
||||
this.state.tiltPanResponder = PanResponder.create({
|
||||
onStartShouldSetPanResponder: () => true,
|
||||
onPanResponderGrant: () => {
|
||||
Animated.timing(this.state.opacity, {
|
||||
toValue: this.state.panX.interpolate({
|
||||
inputRange: [-300, 0, 300], // pan is in pixels
|
||||
outputRange: [0, 1, 0], // goes to zero at both edges
|
||||
}),
|
||||
duration: 0, // direct tracking
|
||||
}).start();
|
||||
},
|
||||
onPanResponderMove: Animated.event(
|
||||
[null, {dx: this.state.panX}] // panX is linked to the gesture
|
||||
),
|
||||
onPanResponderRelease: (e, gestureState) => {
|
||||
var toValue = 0;
|
||||
if (gestureState.dx > 100) {
|
||||
toValue = 500;
|
||||
} else if (gestureState.dx < -100) {
|
||||
toValue = -500;
|
||||
}
|
||||
Animated.spring(this.state.panX, {
|
||||
toValue, // animate back to center or off screen
|
||||
velocity: gestureState.vx, // maintain gesture velocity
|
||||
tension: 10,
|
||||
friction: 3,
|
||||
}).start();
|
||||
this.state.panX.removeAllListeners();
|
||||
var id = this.state.panX.addListener(({value}) => { // listen until offscreen
|
||||
if (Math.abs(value) > 400) {
|
||||
this.state.panX.removeListener(id); // offscreen, so stop listening
|
||||
Animated.timing(this.state.opacity, {
|
||||
toValue: 1, // Fade back in. This unlinks it from tracking this.state.panX
|
||||
}).start();
|
||||
this.state.panX.setValue(0); // Note: stops the spring animation
|
||||
toValue !== 0 && this._startBurnsZoom();
|
||||
}
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
_startBurnsZoom() {
|
||||
this.state.burns.setValue(1); // reset to beginning
|
||||
Animated.decay(this.state.burns, {
|
||||
velocity: 1, // sublte zoom
|
||||
deceleration: 0.9999, // slow decay
|
||||
}).start();
|
||||
}
|
||||
|
||||
componentWillMount() {
|
||||
this._startBurnsZoom();
|
||||
}
|
||||
|
||||
render(): ReactElement {
|
||||
return (
|
||||
<Animated.View
|
||||
{...this.state.tiltPanResponder.panHandlers}
|
||||
style={[styles.tilt, {
|
||||
opacity: this.state.opacity,
|
||||
transform: [
|
||||
{rotate: this.state.panX.interpolate({
|
||||
inputRange: [-320, 320],
|
||||
outputRange: ['-15deg', '15deg']})}, // interpolate string "shapes"
|
||||
{translateX: this.state.panX},
|
||||
],
|
||||
}]}>
|
||||
<Animated.Image
|
||||
pointerEvents="none"
|
||||
style={{
|
||||
flex: 1,
|
||||
transform: [
|
||||
{translateX: this.state.panX.interpolate({
|
||||
inputRange: [-3, 3], // small range is extended by default
|
||||
outputRange: [2, -2]}) // parallax
|
||||
},
|
||||
{scale: this.state.burns.interpolate({
|
||||
inputRange: [1, 3000],
|
||||
outputRange: [1, 1.25]}) // simple multiplier
|
||||
},
|
||||
],
|
||||
}}
|
||||
source={NATURE_IMAGE}
|
||||
/>
|
||||
</Animated.View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
var styles = StyleSheet.create({
|
||||
tilt: {
|
||||
overflow: 'hidden',
|
||||
height: 200,
|
||||
marginBottom: 4,
|
||||
backgroundColor: 'rgb(130, 130, 255)',
|
||||
borderColor: 'rgba(0, 0, 0, 0.2)',
|
||||
borderWidth: 1,
|
||||
borderRadius: 20,
|
||||
},
|
||||
});
|
||||
|
||||
var NATURE_IMAGE = {uri: 'http://www.deshow.net/d/file/travel/2009-04/scenic-beauty-of-nature-photography-2-504-4.jpg'};
|
||||
|
||||
module.exports = AnExTilt;
|
||||
@@ -0,0 +1,98 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* @flow
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var React = require('react-native');
|
||||
var {
|
||||
Image,
|
||||
StyleSheet,
|
||||
View,
|
||||
ScrollView
|
||||
} = React;
|
||||
|
||||
var AssetScaledImageExample = React.createClass({
|
||||
|
||||
getInitialState() {
|
||||
return {
|
||||
asset: this.props.asset
|
||||
};
|
||||
},
|
||||
|
||||
render() {
|
||||
var image = this.state.asset.node.image;
|
||||
return (
|
||||
<ScrollView>
|
||||
<View style={styles.row}>
|
||||
<Image source={image} style={styles.imageWide}/>
|
||||
</View>
|
||||
<View style={styles.row}>
|
||||
<Image source={image} style={styles.imageThumb}/>
|
||||
<Image source={image} style={styles.imageThumb}/>
|
||||
<Image source={image} style={styles.imageThumb}/>
|
||||
</View>
|
||||
<View style={styles.row}>
|
||||
<Image source={image} style={styles.imageT1}/>
|
||||
<Image source={image} style={styles.imageT2}/>
|
||||
</View>
|
||||
</ScrollView>
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
var styles = StyleSheet.create({
|
||||
row: {
|
||||
padding: 5,
|
||||
flex: 1,
|
||||
flexDirection: 'row',
|
||||
alignSelf: 'center',
|
||||
},
|
||||
textColumn: {
|
||||
flex: 1,
|
||||
flexDirection: 'column',
|
||||
},
|
||||
imageWide: {
|
||||
borderWidth: 1,
|
||||
borderColor: 'black',
|
||||
width: 320,
|
||||
height: 240,
|
||||
margin: 5,
|
||||
},
|
||||
imageThumb: {
|
||||
borderWidth: 1,
|
||||
borderColor: 'black',
|
||||
width: 100,
|
||||
height: 100,
|
||||
margin: 5,
|
||||
},
|
||||
imageT1: {
|
||||
borderWidth: 1,
|
||||
borderColor: 'black',
|
||||
width: 212,
|
||||
height: 320,
|
||||
margin: 5,
|
||||
},
|
||||
imageT2: {
|
||||
borderWidth: 1,
|
||||
borderColor: 'black',
|
||||
width: 100,
|
||||
height: 320,
|
||||
margin: 5,
|
||||
},
|
||||
});
|
||||
|
||||
exports.title = '<AssetScaledImageExample>';
|
||||
exports.description = 'Example component that displays the automatic scaling capabilities of the <Image /> tag';
|
||||
module.exports = AssetScaledImageExample;
|
||||
@@ -29,18 +29,23 @@ var COLORS = ['red', 'orange', 'yellow', 'green', 'blue'];
|
||||
|
||||
var BasicStorageExample = React.createClass({
|
||||
componentDidMount() {
|
||||
AsyncStorage.getItem(STORAGE_KEY)
|
||||
.then((value) => {
|
||||
if (value !== null){
|
||||
this.setState({selectedValue: value});
|
||||
this._appendMessage('Recovered selection from disk: ' + value);
|
||||
} else {
|
||||
this._appendMessage('Initialized with no selection on disk.');
|
||||
}
|
||||
})
|
||||
.catch((error) => this._appendMessage('AsyncStorage error: ' + error.message))
|
||||
.done();
|
||||
this._loadInitialState().done();
|
||||
},
|
||||
|
||||
async _loadInitialState() {
|
||||
try {
|
||||
var value = await AsyncStorage.getItem(STORAGE_KEY);
|
||||
if (value !== null){
|
||||
this.setState({selectedValue: value});
|
||||
this._appendMessage('Recovered selection from disk: ' + value);
|
||||
} else {
|
||||
this._appendMessage('Initialized with no selection on disk.');
|
||||
}
|
||||
} catch (error) {
|
||||
this._appendMessage('AsyncStorage error: ' + error.message);
|
||||
}
|
||||
},
|
||||
|
||||
getInitialState() {
|
||||
return {
|
||||
selectedValue: COLORS[0],
|
||||
@@ -80,19 +85,23 @@ var BasicStorageExample = React.createClass({
|
||||
);
|
||||
},
|
||||
|
||||
_onValueChange(selectedValue) {
|
||||
async _onValueChange(selectedValue) {
|
||||
this.setState({selectedValue});
|
||||
AsyncStorage.setItem(STORAGE_KEY, selectedValue)
|
||||
.then(() => this._appendMessage('Saved selection to disk: ' + selectedValue))
|
||||
.catch((error) => this._appendMessage('AsyncStorage error: ' + error.message))
|
||||
.done();
|
||||
try {
|
||||
await AsyncStorage.setItem(STORAGE_KEY, selectedValue);
|
||||
this._appendMessage('Saved selection to disk: ' + selectedValue);
|
||||
} catch (error) {
|
||||
this._appendMessage('AsyncStorage error: ' + error.message);
|
||||
}
|
||||
},
|
||||
|
||||
_removeStorage() {
|
||||
AsyncStorage.removeItem(STORAGE_KEY)
|
||||
.then(() => this._appendMessage('Selection removed from disk.'))
|
||||
.catch((error) => { this._appendMessage('AsyncStorage error: ' + error.message) })
|
||||
.done();
|
||||
async _removeStorage() {
|
||||
try {
|
||||
await AsyncStorage.removeItem(STORAGE_KEY);
|
||||
this._appendMessage('Selection removed from disk.');
|
||||
} catch (error) {
|
||||
this._appendMessage('AsyncStorage error: ' + error.message);
|
||||
}
|
||||
},
|
||||
|
||||
_appendMessage(message) {
|
||||
|
||||
@@ -24,9 +24,11 @@ var {
|
||||
SwitchIOS,
|
||||
Text,
|
||||
View,
|
||||
TouchableOpacity
|
||||
} = React;
|
||||
|
||||
var CameraRollView = require('./CameraRollView.ios');
|
||||
var AssetScaledImageExampleView = require('./AssetScaledImageExample');
|
||||
|
||||
var CAMERA_ROLL_VIEW = 'camera_roll_view';
|
||||
|
||||
@@ -54,7 +56,7 @@ var CameraRollExample = React.createClass({
|
||||
<Text>{'Group Type: ' + this.state.groupTypes}</Text>
|
||||
<CameraRollView
|
||||
ref={CAMERA_ROLL_VIEW}
|
||||
batchSize={5}
|
||||
batchSize={20}
|
||||
groupTypes={this.state.groupTypes}
|
||||
renderImage={this._renderImage}
|
||||
/>
|
||||
@@ -62,24 +64,35 @@ var CameraRollExample = React.createClass({
|
||||
);
|
||||
},
|
||||
|
||||
loadAsset(asset){
|
||||
this.props.navigator.push({
|
||||
title: 'Camera Roll Image',
|
||||
component: AssetScaledImageExampleView,
|
||||
backButtonTitle: 'Back',
|
||||
passProps: { asset: asset },
|
||||
});
|
||||
},
|
||||
|
||||
_renderImage(asset) {
|
||||
var imageSize = this.state.bigImages ? 150 : 75;
|
||||
var imageStyle = [styles.image, {width: imageSize, height: imageSize}];
|
||||
var location = asset.node.location.longitude ?
|
||||
JSON.stringify(asset.node.location) : 'Unknown location';
|
||||
return (
|
||||
<View key={asset} style={styles.row}>
|
||||
<Image
|
||||
source={asset.node.image}
|
||||
style={imageStyle}
|
||||
/>
|
||||
<View style={styles.info}>
|
||||
<Text style={styles.url}>{asset.node.image.uri}</Text>
|
||||
<Text>{location}</Text>
|
||||
<Text>{asset.node.group_name}</Text>
|
||||
<Text>{new Date(asset.node.timestamp).toString()}</Text>
|
||||
<TouchableOpacity onPress={ this.loadAsset.bind( this, asset ) }>
|
||||
<View key={asset} style={styles.row}>
|
||||
<Image
|
||||
source={asset.node.image}
|
||||
style={imageStyle}
|
||||
/>
|
||||
<View style={styles.info}>
|
||||
<Text style={styles.url}>{asset.node.image.uri}</Text>
|
||||
<Text>{location}</Text>
|
||||
<Text>{asset.node.group_name}</Text>
|
||||
<Text>{new Date(asset.node.timestamp).toString()}</Text>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
);
|
||||
},
|
||||
|
||||
@@ -115,7 +128,7 @@ var styles = StyleSheet.create({
|
||||
},
|
||||
});
|
||||
|
||||
exports.title = '<CameraRollView>';
|
||||
exports.title = 'Camera Roll';
|
||||
exports.description = 'Example component that uses CameraRoll to list user\'s photos';
|
||||
exports.examples = [
|
||||
{
|
||||
|
||||
@@ -0,0 +1,305 @@
|
||||
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* @flow
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var React = require('react-native');
|
||||
var {
|
||||
CameraRoll,
|
||||
Image,
|
||||
NativeModules,
|
||||
ScrollView,
|
||||
StyleSheet,
|
||||
Text,
|
||||
TouchableHighlight,
|
||||
View,
|
||||
} = React;
|
||||
var ImageEditingManager = NativeModules.ImageEditingManager;
|
||||
var RCTScrollViewConsts = NativeModules.UIManager.RCTScrollView.Constants;
|
||||
|
||||
var PAGE_SIZE = 20;
|
||||
|
||||
type ImageOffset = {
|
||||
x: number;
|
||||
y: number;
|
||||
};
|
||||
|
||||
type ImageSize = {
|
||||
width: number;
|
||||
height: number;
|
||||
};
|
||||
|
||||
type TransformData = {
|
||||
offset: ImageOffset;
|
||||
size: ImageSize;
|
||||
}
|
||||
|
||||
class SquareImageCropper extends React.Component {
|
||||
_isMounted: boolean;
|
||||
_transformData: TransformData;
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this._isMounted = true;
|
||||
this.state = {
|
||||
randomPhoto: null,
|
||||
measuredSize: null,
|
||||
croppedImageURI: null,
|
||||
cropError: null,
|
||||
};
|
||||
this._fetchRandomPhoto();
|
||||
}
|
||||
|
||||
_fetchRandomPhoto() {
|
||||
CameraRoll.getPhotos(
|
||||
{first: PAGE_SIZE},
|
||||
(data) => {
|
||||
if (!this._isMounted) {
|
||||
return;
|
||||
}
|
||||
var edges = data.edges;
|
||||
var edge = edges[Math.floor(Math.random() * edges.length)];
|
||||
var randomPhoto = edge && edge.node && edge.node.image;
|
||||
if (randomPhoto) {
|
||||
this.setState({randomPhoto});
|
||||
}
|
||||
},
|
||||
(error) => undefined
|
||||
);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this._isMounted = false;
|
||||
}
|
||||
|
||||
render() {
|
||||
if (!this.state.measuredSize) {
|
||||
return (
|
||||
<View
|
||||
style={styles.container}
|
||||
onLayout={(event) => {
|
||||
var measuredWidth = event.nativeEvent.layout.width;
|
||||
if (!measuredWidth) {
|
||||
return;
|
||||
}
|
||||
this.setState({
|
||||
measuredSize: {width: measuredWidth, height: measuredWidth},
|
||||
});
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
if (!this.state.croppedImageURI) {
|
||||
return this._renderImageCropper();
|
||||
}
|
||||
return this._renderCroppedImage();
|
||||
}
|
||||
|
||||
_renderImageCropper() {
|
||||
if (!this.state.randomPhoto) {
|
||||
return (
|
||||
<View style={styles.container} />
|
||||
);
|
||||
}
|
||||
var error = null;
|
||||
if (this.state.cropError) {
|
||||
error = (
|
||||
<Text>{this.state.cropError.message}</Text>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<Text>Drag the image within the square to crop:</Text>
|
||||
<ImageCropper
|
||||
image={this.state.randomPhoto}
|
||||
size={this.state.measuredSize}
|
||||
style={[styles.imageCropper, this.state.measuredSize]}
|
||||
onTransformDataChange={(data) => this._transformData = data}
|
||||
/>
|
||||
<TouchableHighlight
|
||||
style={styles.cropButtonTouchable}
|
||||
onPress={this._crop.bind(this)}>
|
||||
<View style={styles.cropButton}>
|
||||
<Text style={styles.cropButtonLabel}>
|
||||
Crop
|
||||
</Text>
|
||||
</View>
|
||||
</TouchableHighlight>
|
||||
{error}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
_renderCroppedImage() {
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<Text>Here is the cropped image:</Text>
|
||||
<Image
|
||||
source={{uri: this.state.croppedImageURI}}
|
||||
style={[styles.imageCropper, this.state.measuredSize]}
|
||||
/>
|
||||
<TouchableHighlight
|
||||
style={styles.cropButtonTouchable}
|
||||
onPress={this._reset.bind(this)}>
|
||||
<View style={styles.cropButton}>
|
||||
<Text style={styles.cropButtonLabel}>
|
||||
Try again
|
||||
</Text>
|
||||
</View>
|
||||
</TouchableHighlight>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
_crop() {
|
||||
ImageEditingManager.cropImage(
|
||||
this.state.randomPhoto.uri,
|
||||
this._transformData,
|
||||
(croppedImageURI) => this.setState({croppedImageURI}),
|
||||
(cropError) => this.setState({cropError})
|
||||
);
|
||||
}
|
||||
|
||||
_reset() {
|
||||
this.setState({
|
||||
randomPhoto: null,
|
||||
croppedImageURI: null,
|
||||
cropError: null,
|
||||
});
|
||||
this._fetchRandomPhoto();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class ImageCropper extends React.Component {
|
||||
_scaledImageSize: ImageSize;
|
||||
_contentOffset: ImageOffset;
|
||||
|
||||
componentWillMount() {
|
||||
// Scale an image to the minimum size that is large enough to completely
|
||||
// fill the crop box.
|
||||
var widthRatio = this.props.image.width / this.props.size.width;
|
||||
var heightRatio = this.props.image.height / this.props.size.height;
|
||||
if (widthRatio < heightRatio) {
|
||||
this._scaledImageSize = {
|
||||
width: this.props.size.width,
|
||||
height: this.props.image.height / widthRatio,
|
||||
};
|
||||
} else {
|
||||
this._scaledImageSize = {
|
||||
width: this.props.image.width / heightRatio,
|
||||
height: this.props.size.height,
|
||||
};
|
||||
}
|
||||
this._contentOffset = {
|
||||
x: (this._scaledImageSize.width - this.props.size.width) / 2,
|
||||
y: (this._scaledImageSize.height - this.props.size.height) / 2,
|
||||
};
|
||||
this._updateTransformData(
|
||||
this._contentOffset,
|
||||
this._scaledImageSize,
|
||||
this.props.size
|
||||
);
|
||||
}
|
||||
|
||||
_onScroll(event) {
|
||||
this._updateTransformData(
|
||||
event.nativeEvent.contentOffset,
|
||||
event.nativeEvent.contentSize,
|
||||
event.nativeEvent.layoutMeasurement
|
||||
);
|
||||
}
|
||||
|
||||
_updateTransformData(offset, scaledImageSize, croppedImageSize) {
|
||||
var offsetRatioX = offset.x / scaledImageSize.width;
|
||||
var offsetRatioY = offset.y / scaledImageSize.height;
|
||||
var sizeRatioX = croppedImageSize.width / scaledImageSize.width;
|
||||
var sizeRatioY = croppedImageSize.height / scaledImageSize.height;
|
||||
|
||||
this.props.onTransformDataChange && this.props.onTransformDataChange({
|
||||
offset: {
|
||||
x: this.props.image.width * offsetRatioX,
|
||||
y: this.props.image.height * offsetRatioY,
|
||||
},
|
||||
size: {
|
||||
width: this.props.image.width * sizeRatioX,
|
||||
height: this.props.image.height * sizeRatioY,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
var decelerationRate =
|
||||
RCTScrollViewConsts && RCTScrollViewConsts.DecelerationRate ?
|
||||
RCTScrollViewConsts.DecelerationRate.Fast :
|
||||
0;
|
||||
|
||||
return (
|
||||
<ScrollView
|
||||
alwaysBounceVertical={true}
|
||||
automaticallyAdjustContentInsets={false}
|
||||
contentOffset={this._contentOffset}
|
||||
decelerationRate={decelerationRate}
|
||||
horizontal={true}
|
||||
maximumZoomScale={3.0}
|
||||
onMomentumScrollEnd={this._onScroll.bind(this)}
|
||||
onScrollEndDrag={this._onScroll.bind(this)}
|
||||
showsHorizontalScrollIndicator={false}
|
||||
showsVerticalScrollIndicator={false}
|
||||
style={this.props.style}
|
||||
scrollEventThrottle={16}>
|
||||
<Image source={this.props.image} style={this._scaledImageSize} />
|
||||
</ScrollView>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
exports.framework = 'React';
|
||||
exports.title = 'ImageEditingManager';
|
||||
exports.description = 'Cropping and scaling with ImageEditingManager';
|
||||
exports.examples = [{
|
||||
title: 'Image Cropping',
|
||||
render() {
|
||||
return <SquareImageCropper/>;
|
||||
}
|
||||
}];
|
||||
|
||||
var styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
alignSelf: 'stretch',
|
||||
},
|
||||
imageCropper: {
|
||||
alignSelf: 'center',
|
||||
marginTop: 12,
|
||||
},
|
||||
cropButtonTouchable: {
|
||||
alignSelf: 'center',
|
||||
marginTop: 12,
|
||||
},
|
||||
cropButton: {
|
||||
padding: 12,
|
||||
backgroundColor: 'blue',
|
||||
borderRadius: 4,
|
||||
},
|
||||
cropButtonLabel: {
|
||||
color: 'white',
|
||||
fontSize: 16,
|
||||
fontWeight: '500',
|
||||
},
|
||||
});
|
||||
@@ -21,10 +21,41 @@ var {
|
||||
StyleSheet,
|
||||
Text,
|
||||
View,
|
||||
ActivityIndicatorIOS
|
||||
} = React;
|
||||
|
||||
var ImageCapInsetsExample = require('./ImageCapInsetsExample');
|
||||
|
||||
var NetworkImageExample = React.createClass({
|
||||
watchID: (null: ?number),
|
||||
|
||||
getInitialState: function() {
|
||||
return {
|
||||
error: false,
|
||||
loading: false,
|
||||
progress: 0
|
||||
};
|
||||
},
|
||||
render: function() {
|
||||
var loader = this.state.loading ?
|
||||
<View style={styles.progress}>
|
||||
<Text>{this.state.progress}%</Text>
|
||||
<ActivityIndicatorIOS style={{marginLeft:5}}/>
|
||||
</View> : null;
|
||||
return this.state.error ?
|
||||
<Text>{this.state.error}</Text> :
|
||||
<Image
|
||||
source={this.props.source}
|
||||
style={[styles.base, {overflow: 'visible'}]}
|
||||
onLoadStart={(e) => this.setState({loading: true})}
|
||||
onError={(e) => this.setState({error: e.nativeEvent.error, loading: false})}
|
||||
onProgress={(e) => this.setState({progress: Math.round(100 * e.nativeEvent.loaded / e.nativeEvent.total)})}
|
||||
onLoad={() => this.setState({loading: false, error: false})}>
|
||||
{loader}
|
||||
</Image>;
|
||||
}
|
||||
});
|
||||
|
||||
exports.displayName = (undefined: ?string);
|
||||
exports.framework = 'React';
|
||||
exports.title = '<Image>';
|
||||
@@ -59,6 +90,22 @@ exports.examples = [
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'Error Handler',
|
||||
render: function() {
|
||||
return (
|
||||
<NetworkImageExample source={{uri: 'http://TYPO_ERROR_facebook.github.io/react/img/logo_og.png'}} />
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'Image Download Progress',
|
||||
render: function() {
|
||||
return (
|
||||
<NetworkImageExample source={{uri: 'http://facebook.github.io/origami/public/images/blog-hero.jpg?r=1'}}/>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'Border Color',
|
||||
render: function() {
|
||||
@@ -194,23 +241,46 @@ exports.examples = [
|
||||
'pixels to the tint color.',
|
||||
render: function() {
|
||||
return (
|
||||
<View style={styles.horizontal}>
|
||||
<Image
|
||||
source={require('image!uie_thumb_normal')}
|
||||
style={[styles.icon, {tintColor: 'blue' }]}
|
||||
/>
|
||||
<Image
|
||||
source={require('image!uie_thumb_normal')}
|
||||
style={[styles.icon, styles.leftMargin, {tintColor: 'green' }]}
|
||||
/>
|
||||
<Image
|
||||
source={require('image!uie_thumb_normal')}
|
||||
style={[styles.icon, styles.leftMargin, {tintColor: 'red' }]}
|
||||
/>
|
||||
<Image
|
||||
source={require('image!uie_thumb_normal')}
|
||||
style={[styles.icon, styles.leftMargin, {tintColor: 'black' }]}
|
||||
/>
|
||||
<View>
|
||||
<View style={styles.horizontal}>
|
||||
<Image
|
||||
source={require('image!uie_thumb_normal')}
|
||||
style={[styles.icon, {tintColor: '#5ac8fa' }]}
|
||||
/>
|
||||
<Image
|
||||
source={require('image!uie_thumb_normal')}
|
||||
style={[styles.icon, styles.leftMargin, {tintColor: '#4cd964' }]}
|
||||
/>
|
||||
<Image
|
||||
source={require('image!uie_thumb_normal')}
|
||||
style={[styles.icon, styles.leftMargin, {tintColor: '#ff2d55' }]}
|
||||
/>
|
||||
<Image
|
||||
source={require('image!uie_thumb_normal')}
|
||||
style={[styles.icon, styles.leftMargin, {tintColor: '#8e8e93' }]}
|
||||
/>
|
||||
</View>
|
||||
<Text style={styles.sectionText}>
|
||||
It also works with downloaded images:
|
||||
</Text>
|
||||
<View style={styles.horizontal}>
|
||||
<Image
|
||||
source={smallImage}
|
||||
style={[styles.base, {tintColor: '#5ac8fa' }]}
|
||||
/>
|
||||
<Image
|
||||
source={smallImage}
|
||||
style={[styles.base, styles.leftMargin, {tintColor: '#4cd964' }]}
|
||||
/>
|
||||
<Image
|
||||
source={smallImage}
|
||||
style={[styles.base, styles.leftMargin, {tintColor: '#ff2d55' }]}
|
||||
/>
|
||||
<Image
|
||||
source={smallImage}
|
||||
style={[styles.base, styles.leftMargin, {tintColor: '#8e8e93' }]}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
},
|
||||
@@ -270,19 +340,28 @@ exports.examples = [
|
||||
];
|
||||
|
||||
var fullImage = {uri: 'http://facebook.github.io/react/img/logo_og.png'};
|
||||
var smallImage = {uri: 'http://facebook.github.io/react/img/logo_small.png'};
|
||||
var smallImage = {uri: 'http://facebook.github.io/react/img/logo_small_2x.png'};
|
||||
|
||||
var styles = StyleSheet.create({
|
||||
base: {
|
||||
width: 38,
|
||||
height: 38,
|
||||
},
|
||||
progress: {
|
||||
flex: 1,
|
||||
alignItems: 'center',
|
||||
flexDirection: 'row',
|
||||
width: 100
|
||||
},
|
||||
leftMargin: {
|
||||
marginLeft: 10,
|
||||
},
|
||||
background: {
|
||||
backgroundColor: '#222222'
|
||||
},
|
||||
sectionText: {
|
||||
marginVertical: 6,
|
||||
},
|
||||
nestedText: {
|
||||
marginLeft: 12,
|
||||
marginTop: 20,
|
||||
|
||||
@@ -15,37 +15,37 @@
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
/* $FlowIssue #7387208 - There's a flow bug preventing this type from flowing
|
||||
* into a proptype shape */
|
||||
declare module 'image!story-background' {
|
||||
/* $FlowIssue #7387208 - There's a flow bug preventing this type from flowing
|
||||
* into a proptype shape */
|
||||
declare var uri: string;
|
||||
declare var isStatic: boolean;
|
||||
}
|
||||
|
||||
/* $FlowIssue #7387208 - There's a flow bug preventing this type from flowing
|
||||
* into a proptype shape */
|
||||
declare module 'image!uie_comment_highlighted' {
|
||||
/* $FlowIssue #7387208 - There's a flow bug preventing this type from flowing
|
||||
* into a proptype shape */
|
||||
declare var uri: string;
|
||||
declare var isStatic: boolean;
|
||||
}
|
||||
|
||||
/* $FlowIssue #7387208 - There's a flow bug preventing this type from flowing
|
||||
* into a proptype shape */
|
||||
declare module 'image!uie_comment_normal' {
|
||||
/* $FlowIssue #7387208 - There's a flow bug preventing this type from flowing
|
||||
* into a proptype shape */
|
||||
declare var uri: string;
|
||||
declare var isStatic: boolean;
|
||||
}
|
||||
|
||||
/* $FlowIssue #7387208 - There's a flow bug preventing this type from flowing
|
||||
* into a proptype shape */
|
||||
declare module 'image!uie_thumb_normal' {
|
||||
/* $FlowIssue #7387208 - There's a flow bug preventing this type from flowing
|
||||
* into a proptype shape */
|
||||
declare var uri: string;
|
||||
declare var isStatic: boolean;
|
||||
}
|
||||
|
||||
/* $FlowIssue #7387208 - There's a flow bug preventing this type from flowing
|
||||
* into a proptype shape */
|
||||
declare module 'image!uie_thumb_selected' {
|
||||
/* $FlowIssue #7387208 - There's a flow bug preventing this type from flowing
|
||||
* into a proptype shape */
|
||||
declare var uri: string;
|
||||
declare var isStatic: boolean;
|
||||
}
|
||||
|
||||
@@ -49,8 +49,7 @@ var LayoutEventExample = React.createClass({
|
||||
() => {
|
||||
console.log('layout animation done.');
|
||||
this.addWrapText();
|
||||
},
|
||||
(error) => { throw new Error(JSON.stringify(error)); }
|
||||
}
|
||||
);
|
||||
this.setState({
|
||||
viewStyle: {
|
||||
@@ -139,11 +138,11 @@ var styles = StyleSheet.create({
|
||||
},
|
||||
});
|
||||
|
||||
exports.title = 'onLayout';
|
||||
exports.title = 'Layout Events';
|
||||
exports.description = 'Layout events can be used to measure view size and position.';
|
||||
exports.examples = [
|
||||
{
|
||||
title: 'onLayout',
|
||||
title: 'LayoutEventExample',
|
||||
render: function(): ReactElement {
|
||||
return <LayoutEventExample />;
|
||||
},
|
||||
|
||||
@@ -62,8 +62,11 @@ var CircleBlock = React.createClass({
|
||||
var LayoutExample = React.createClass({
|
||||
statics: {
|
||||
title: 'Layout - Flexbox',
|
||||
description: 'Examples of using the flexbox API to layout views.'
|
||||
description: 'Examples of using the flexbox API to layout views.',
|
||||
},
|
||||
|
||||
displayName: 'LayoutExample',
|
||||
|
||||
render: function() {
|
||||
return (
|
||||
<UIExplorerPage title={this.props.navigator ? null : 'Layout'}>
|
||||
|
||||
@@ -0,0 +1,149 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* @flow
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var React = require('react-native');
|
||||
var {
|
||||
Image,
|
||||
ListView,
|
||||
TouchableHighlight,
|
||||
StyleSheet,
|
||||
Text,
|
||||
View,
|
||||
} = React;
|
||||
|
||||
var THUMB_URLS = [
|
||||
'https://fbcdn-dragon-a.akamaihd.net/hphotos-ak-ash3/t39.1997/p128x128/851549_767334479959628_274486868_n.png',
|
||||
'https://fbcdn-dragon-a.akamaihd.net/hphotos-ak-prn1/t39.1997/p128x128/851561_767334496626293_1958532586_n.png',
|
||||
'https://fbcdn-dragon-a.akamaihd.net/hphotos-ak-ash3/t39.1997/p128x128/851579_767334503292959_179092627_n.png',
|
||||
'https://fbcdn-dragon-a.akamaihd.net/hphotos-ak-prn1/t39.1997/p128x128/851589_767334513292958_1747022277_n.png',
|
||||
'https://fbcdn-dragon-a.akamaihd.net/hphotos-ak-prn1/t39.1997/p128x128/851563_767334559959620_1193692107_n.png',
|
||||
'https://fbcdn-dragon-a.akamaihd.net/hphotos-ak-prn1/t39.1997/p128x128/851593_767334566626286_1953955109_n.png',
|
||||
'https://fbcdn-dragon-a.akamaihd.net/hphotos-ak-prn1/t39.1997/p128x128/851591_767334523292957_797560749_n.png',
|
||||
'https://fbcdn-dragon-a.akamaihd.net/hphotos-ak-prn1/t39.1997/p128x128/851567_767334529959623_843148472_n.png',
|
||||
'https://fbcdn-dragon-a.akamaihd.net/hphotos-ak-prn1/t39.1997/p128x128/851548_767334489959627_794462220_n.png',
|
||||
'https://fbcdn-dragon-a.akamaihd.net/hphotos-ak-prn1/t39.1997/p128x128/851575_767334539959622_441598241_n.png',
|
||||
'https://fbcdn-dragon-a.akamaihd.net/hphotos-ak-ash3/t39.1997/p128x128/851573_767334549959621_534583464_n.png',
|
||||
'https://fbcdn-dragon-a.akamaihd.net/hphotos-ak-prn1/t39.1997/p128x128/851583_767334573292952_1519550680_n.png',
|
||||
];
|
||||
|
||||
var ListViewGridLayoutExample = React.createClass({
|
||||
|
||||
statics: {
|
||||
title: '<ListView> - Grid Layout',
|
||||
description: 'Flexbox grid layout.'
|
||||
},
|
||||
|
||||
getInitialState: function() {
|
||||
var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
|
||||
return {
|
||||
dataSource: ds.cloneWithRows(this._genRows({})),
|
||||
};
|
||||
},
|
||||
|
||||
_pressData: ({}: {[key: number]: boolean}),
|
||||
|
||||
componentWillMount: function() {
|
||||
this._pressData = {};
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return (
|
||||
// ListView wraps ScrollView and so takes on its properties.
|
||||
// With that in mind you can use the ScrollView's contentContainerStyle prop to style the items.
|
||||
<ListView
|
||||
contentContainerStyle={styles.list}
|
||||
dataSource={this.state.dataSource}
|
||||
renderRow={this._renderRow}
|
||||
/>
|
||||
);
|
||||
},
|
||||
|
||||
_renderRow: function(rowData: string, sectionID: number, rowID: number) {
|
||||
var rowHash = Math.abs(hashCode(rowData));
|
||||
var imgSource = {
|
||||
uri: THUMB_URLS[rowHash % THUMB_URLS.length],
|
||||
};
|
||||
return (
|
||||
<TouchableHighlight onPress={() => this._pressRow(rowID)} underlayColor="transparent">
|
||||
<View>
|
||||
<View style={styles.row}>
|
||||
<Image style={styles.thumb} source={imgSource} />
|
||||
<Text style={styles.text}>
|
||||
{rowData}
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
</TouchableHighlight>
|
||||
);
|
||||
},
|
||||
|
||||
_genRows: function(pressData: {[key: number]: boolean}): Array<string> {
|
||||
var dataBlob = [];
|
||||
for (var ii = 0; ii < 100; ii++) {
|
||||
var pressedText = pressData[ii] ? ' (X)' : '';
|
||||
dataBlob.push('Cell ' + ii + pressedText);
|
||||
}
|
||||
return dataBlob;
|
||||
},
|
||||
|
||||
_pressRow: function(rowID: number) {
|
||||
this._pressData[rowID] = !this._pressData[rowID];
|
||||
this.setState({dataSource: this.state.dataSource.cloneWithRows(
|
||||
this._genRows(this._pressData)
|
||||
)});
|
||||
},
|
||||
});
|
||||
|
||||
/* eslint no-bitwise: 0 */
|
||||
var hashCode = function(str) {
|
||||
var hash = 15;
|
||||
for (var ii = str.length - 1; ii >= 0; ii--) {
|
||||
hash = ((hash << 5) - hash) + str.charCodeAt(ii);
|
||||
}
|
||||
return hash;
|
||||
};
|
||||
|
||||
var styles = StyleSheet.create({
|
||||
list: {
|
||||
justifyContent: 'space-around',
|
||||
flexDirection: 'row',
|
||||
flexWrap: 'wrap'
|
||||
},
|
||||
row: {
|
||||
justifyContent: 'center',
|
||||
padding: 5,
|
||||
margin: 3,
|
||||
width: 100,
|
||||
height: 100,
|
||||
backgroundColor: '#F6F6F6',
|
||||
alignItems: 'center',
|
||||
borderWidth: 1,
|
||||
borderRadius: 5,
|
||||
borderColor: '#CCC'
|
||||
},
|
||||
thumb: {
|
||||
width: 64,
|
||||
height: 64
|
||||
},
|
||||
text: {
|
||||
flex: 1,
|
||||
marginTop: 5,
|
||||
fontWeight: 'bold'
|
||||
},
|
||||
});
|
||||
|
||||
module.exports = ListViewGridLayoutExample;
|
||||
@@ -48,19 +48,19 @@ var Thumb = React.createClass({
|
||||
},
|
||||
render: function() {
|
||||
return (
|
||||
<TouchableOpacity onPress={this._onPressThumb}>
|
||||
<View style={[styles.buttonContents, {flexDirection: this.state.dir}]}>
|
||||
<Image style={styles.img} source={{uri: THUMB_URLS[this.state.thumbIndex]}} />
|
||||
<Image style={styles.img} source={{uri: THUMB_URLS[this.state.thumbIndex]}} />
|
||||
<Image style={styles.img} source={{uri: THUMB_URLS[this.state.thumbIndex]}} />
|
||||
{this.state.dir === 'column' ?
|
||||
<Text>
|
||||
Oooo, look at this new text! So awesome it may just be crazy.
|
||||
Let me keep typing here so it wraps at least one line.
|
||||
</Text> :
|
||||
<Text />
|
||||
}
|
||||
</View>
|
||||
<TouchableOpacity
|
||||
onPress={this._onPressThumb}
|
||||
style={[styles.buttonContents, {flexDirection: this.state.dir}]}>
|
||||
<Image style={styles.img} source={{uri: THUMB_URLS[this.state.thumbIndex]}} />
|
||||
<Image style={styles.img} source={{uri: THUMB_URLS[this.state.thumbIndex]}} />
|
||||
<Image style={styles.img} source={{uri: THUMB_URLS[this.state.thumbIndex]}} />
|
||||
{this.state.dir === 'column' ?
|
||||
<Text>
|
||||
Oooo, look at this new text! So awesome it may just be crazy.
|
||||
Let me keep typing here so it wraps at least one line.
|
||||
</Text> :
|
||||
<Text />
|
||||
}
|
||||
</TouchableOpacity>
|
||||
);
|
||||
}
|
||||
@@ -127,14 +127,12 @@ var ListViewPagingExample = React.createClass({
|
||||
<View><Text style={styles.text}>1 Like</Text></View> :
|
||||
null;
|
||||
return (
|
||||
<TouchableOpacity onPress={this._onPressHeader}>
|
||||
<View style={styles.header}>
|
||||
{headerLikeText}
|
||||
<View>
|
||||
<Text style={styles.text}>
|
||||
Table Header (click me)
|
||||
</Text>
|
||||
</View>
|
||||
<TouchableOpacity onPress={this._onPressHeader} style={styles.header}>
|
||||
{headerLikeText}
|
||||
<View>
|
||||
<Text style={styles.text}>
|
||||
Table Header (click me)
|
||||
</Text>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
);
|
||||
@@ -212,6 +210,7 @@ var styles = StyleSheet.create({
|
||||
width: 64,
|
||||
height: 64,
|
||||
marginHorizontal: 10,
|
||||
backgroundColor: 'transparent',
|
||||
},
|
||||
section: {
|
||||
flexDirection: 'column',
|
||||
|
||||
@@ -16,9 +16,9 @@
|
||||
'use strict';
|
||||
|
||||
var React = require('react-native');
|
||||
var StyleSheet = require('StyleSheet');
|
||||
var {
|
||||
MapView,
|
||||
StyleSheet,
|
||||
Text,
|
||||
TextInput,
|
||||
View,
|
||||
|
||||
@@ -0,0 +1,172 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* @flow
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var React = require('react-native');
|
||||
var {
|
||||
Modal,
|
||||
StyleSheet,
|
||||
SwitchIOS,
|
||||
Text,
|
||||
TouchableHighlight,
|
||||
View,
|
||||
} = React;
|
||||
|
||||
exports.displayName = (undefined: ?string);
|
||||
exports.framework = 'React';
|
||||
exports.title = '<Modal>';
|
||||
exports.description = 'Component for presenting modal views.';
|
||||
|
||||
var Button = React.createClass({
|
||||
getInitialState() {
|
||||
return {
|
||||
active: false,
|
||||
};
|
||||
},
|
||||
|
||||
_onHighlight() {
|
||||
this.setState({active: true});
|
||||
},
|
||||
|
||||
_onUnhighlight() {
|
||||
this.setState({active: false});
|
||||
},
|
||||
|
||||
render() {
|
||||
var colorStyle = {
|
||||
color: this.state.active ? '#fff' : '#000',
|
||||
};
|
||||
return (
|
||||
<TouchableHighlight
|
||||
onHideUnderlay={this._onUnhighlight}
|
||||
onPress={this.props.onPress}
|
||||
onShowUnderlay={this._onHighlight}
|
||||
style={[styles.button, this.props.style]}
|
||||
underlayColor="#a9d9d4">
|
||||
<Text style={[styles.buttonText, colorStyle]}>{this.props.children}</Text>
|
||||
</TouchableHighlight>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var ModalExample = React.createClass({
|
||||
getInitialState() {
|
||||
return {
|
||||
animated: true,
|
||||
modalVisible: false,
|
||||
transparent: false,
|
||||
};
|
||||
},
|
||||
|
||||
_setModalVisible(visible) {
|
||||
this.setState({modalVisible: visible});
|
||||
},
|
||||
|
||||
_toggleAnimated() {
|
||||
this.setState({animated: !this.state.animated});
|
||||
},
|
||||
|
||||
_toggleTransparent() {
|
||||
this.setState({transparent: !this.state.transparent});
|
||||
},
|
||||
|
||||
render() {
|
||||
var modalBackgroundStyle = {
|
||||
backgroundColor: this.state.transparent ? 'rgba(0, 0, 0, 0.5)' : '#f5fcff',
|
||||
};
|
||||
var innerContainerTransparentStyle = this.state.transparent
|
||||
? {backgroundColor: '#fff', padding: 20}
|
||||
: null;
|
||||
|
||||
return (
|
||||
<View>
|
||||
<Modal
|
||||
animated={this.state.animated}
|
||||
transparent={this.state.transparent}
|
||||
visible={this.state.modalVisible}>
|
||||
<View style={[styles.container, modalBackgroundStyle]}>
|
||||
<View style={[styles.innerContainer, innerContainerTransparentStyle]}>
|
||||
<Text>This modal was presented {this.state.animated ? 'with' : 'without'} animation.</Text>
|
||||
<Button
|
||||
onPress={this._setModalVisible.bind(this, false)}
|
||||
style={styles.modalButton}>
|
||||
Close
|
||||
</Button>
|
||||
</View>
|
||||
</View>
|
||||
</Modal>
|
||||
|
||||
<View style={styles.row}>
|
||||
<Text style={styles.rowTitle}>Animated</Text>
|
||||
<SwitchIOS value={this.state.animated} onValueChange={this._toggleAnimated} />
|
||||
</View>
|
||||
|
||||
<View style={styles.row}>
|
||||
<Text style={styles.rowTitle}>Transparent</Text>
|
||||
<SwitchIOS value={this.state.transparent} onValueChange={this._toggleTransparent} />
|
||||
</View>
|
||||
|
||||
<Button onPress={this._setModalVisible.bind(this, true)}>
|
||||
Present
|
||||
</Button>
|
||||
</View>
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
exports.examples = [
|
||||
{
|
||||
title: 'Modal Presentation',
|
||||
description: 'Modals can be presented with or without animation',
|
||||
render: () => <ModalExample />,
|
||||
},
|
||||
];
|
||||
|
||||
var styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
padding: 20,
|
||||
},
|
||||
innerContainer: {
|
||||
borderRadius: 10,
|
||||
},
|
||||
row: {
|
||||
alignItems: 'center',
|
||||
flex: 1,
|
||||
flexDirection: 'row',
|
||||
marginBottom: 20,
|
||||
},
|
||||
rowTitle: {
|
||||
flex: 1,
|
||||
fontWeight: 'bold',
|
||||
},
|
||||
button: {
|
||||
borderRadius: 5,
|
||||
flex: 1,
|
||||
height: 44,
|
||||
justifyContent: 'center',
|
||||
overflow: 'hidden',
|
||||
},
|
||||
buttonText: {
|
||||
fontSize: 18,
|
||||
margin: 5,
|
||||
textAlign: 'center',
|
||||
},
|
||||
modalButton: {
|
||||
marginTop: 10,
|
||||
},
|
||||
});
|
||||
@@ -55,26 +55,24 @@ var BreadcrumbNavSample = React.createClass({
|
||||
return (
|
||||
<TouchableOpacity
|
||||
onPress={() => navigator.push(_getRandomRoute())}>
|
||||
<View>
|
||||
<Text style={styles.titleText}>{route.title}</Text>
|
||||
</View>
|
||||
<Text style={styles.titleText}>{route.title}</Text>
|
||||
</TouchableOpacity>
|
||||
);
|
||||
},
|
||||
iconForRoute: function(route, navigator) {
|
||||
return (
|
||||
<TouchableOpacity onPress={() => {
|
||||
navigator.popToRoute(route);
|
||||
}}>
|
||||
<View style={styles.crumbIconPlaceholder} />
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity
|
||||
onPress={() => { navigator.popToRoute(route); }}
|
||||
style={styles.crumbIconPlaceholder}
|
||||
/>
|
||||
);
|
||||
},
|
||||
separatorForRoute: function(route, navigator) {
|
||||
return (
|
||||
<TouchableOpacity onPress={navigator.pop}>
|
||||
<View style={styles.crumbSeparatorPlaceholder} />
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity
|
||||
onPress={navigator.pop}
|
||||
style={styles.crumbSeparatorPlaceholder}
|
||||
/>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -51,12 +51,11 @@ var NavigationBarRouteMapper = {
|
||||
var previousRoute = navState.routeStack[index - 1];
|
||||
return (
|
||||
<TouchableOpacity
|
||||
onPress={() => navigator.pop()}>
|
||||
<View style={styles.navBarLeftButton}>
|
||||
<Text style={[styles.navBarText, styles.navBarButtonText]}>
|
||||
{previousRoute.title}
|
||||
</Text>
|
||||
</View>
|
||||
onPress={() => navigator.pop()}
|
||||
style={styles.navBarLeftButton}>
|
||||
<Text style={[styles.navBarText, styles.navBarButtonText]}>
|
||||
{previousRoute.title}
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
);
|
||||
},
|
||||
@@ -64,12 +63,11 @@ var NavigationBarRouteMapper = {
|
||||
RightButton: function(route, navigator, index, navState) {
|
||||
return (
|
||||
<TouchableOpacity
|
||||
onPress={() => navigator.push(newRandomRoute())}>
|
||||
<View style={styles.navBarRightButton}>
|
||||
<Text style={[styles.navBarText, styles.navBarButtonText]}>
|
||||
Next
|
||||
</Text>
|
||||
</View>
|
||||
onPress={() => navigator.push(newRandomRoute())}
|
||||
style={styles.navBarRightButton}>
|
||||
<Text style={[styles.navBarText, styles.navBarButtonText]}>
|
||||
Next
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
);
|
||||
},
|
||||
|
||||
@@ -66,6 +66,7 @@ var NavigatorIOSColors = React.createClass({
|
||||
tintColor="#FFFFFF"
|
||||
barTintColor="#183E63"
|
||||
titleTextColor="#FFFFFF"
|
||||
translucent="true"
|
||||
/>
|
||||
);
|
||||
},
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* @flow
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var ProgressBar = require('ProgressBarAndroid');
|
||||
var React = require('React');
|
||||
var UIExplorerBlock = require('UIExplorerBlock');
|
||||
var UIExplorerPage = require('UIExplorerPage');
|
||||
|
||||
var ProgressBarAndroidExample = React.createClass({
|
||||
|
||||
statics: {
|
||||
title: '<ProgressBarAndroid>',
|
||||
description: 'Visual indicator of progress of some operation. ' +
|
||||
'Shows either a cyclic animation or a horizontal bar.',
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return (
|
||||
<UIExplorerPage title="ProgressBar Examples">
|
||||
<UIExplorerBlock title="Default ProgressBar">
|
||||
<ProgressBar />
|
||||
</UIExplorerBlock>
|
||||
|
||||
<UIExplorerBlock title="Small ProgressBar">
|
||||
<ProgressBar styleAttr="Small" />
|
||||
</UIExplorerBlock>
|
||||
|
||||
<UIExplorerBlock title="Large ProgressBar">
|
||||
<ProgressBar styleAttr="Large" />
|
||||
</UIExplorerBlock>
|
||||
|
||||
<UIExplorerBlock title="Inverse ProgressBar">
|
||||
<ProgressBar styleAttr="Inverse" />
|
||||
</UIExplorerBlock>
|
||||
|
||||
<UIExplorerBlock title="Small Inverse ProgressBar">
|
||||
<ProgressBar styleAttr="SmallInverse" />
|
||||
</UIExplorerBlock>
|
||||
|
||||
<UIExplorerBlock title="Large Inverse ProgressBar">
|
||||
<ProgressBar styleAttr="LargeInverse" />
|
||||
</UIExplorerBlock>
|
||||
</UIExplorerPage>
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
module.exports = ProgressBarAndroidExample;
|
||||
@@ -0,0 +1,83 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* @flow
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var React = require('react-native');
|
||||
var {
|
||||
ScrollView,
|
||||
StyleSheet,
|
||||
Text,
|
||||
TouchableOpacity
|
||||
} = React;
|
||||
|
||||
var NUM_ITEMS = 20;
|
||||
|
||||
var ScrollViewSimpleExample = React.createClass({
|
||||
statics: {
|
||||
title: '<ScrollView>',
|
||||
description: 'Component that enables scrolling through child components.'
|
||||
},
|
||||
|
||||
makeItems: function(nItems: number, styles): Array<any> {
|
||||
var items = [];
|
||||
for (var i = 0; i < nItems; i++) {
|
||||
items[i] = (
|
||||
<TouchableOpacity key={i} style={styles}>
|
||||
<Text>{'Item ' + i}</Text>
|
||||
</TouchableOpacity>
|
||||
);
|
||||
}
|
||||
return items;
|
||||
},
|
||||
|
||||
render: function() {
|
||||
// One of the items is a horizontal scroll view
|
||||
var items = this.makeItems(NUM_ITEMS, styles.itemWrapper);
|
||||
items[4] = (
|
||||
<ScrollView key={'scrollView'} horizontal={true}>
|
||||
{this.makeItems(NUM_ITEMS, [styles.itemWrapper, styles.horizontalItemWrapper])}
|
||||
</ScrollView>
|
||||
);
|
||||
|
||||
var verticalScrollView = (
|
||||
<ScrollView style={styles.verticalScrollView}>
|
||||
{items}
|
||||
</ScrollView>
|
||||
);
|
||||
|
||||
return verticalScrollView;
|
||||
}
|
||||
});
|
||||
|
||||
var styles = StyleSheet.create({
|
||||
verticalScrollView: {
|
||||
margin: 10,
|
||||
},
|
||||
itemWrapper: {
|
||||
backgroundColor: '#dddddd',
|
||||
alignItems: 'center',
|
||||
borderRadius: 5,
|
||||
borderWidth: 5,
|
||||
borderColor: '#a52a2a',
|
||||
padding: 30,
|
||||
margin: 5,
|
||||
},
|
||||
horizontalItemWrapper: {
|
||||
padding: 50
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = ScrollViewSimpleExample;
|
||||
@@ -118,7 +118,7 @@ var EventSegmentedControlExample = React.createClass({
|
||||
|
||||
_onChange(event) {
|
||||
this.setState({
|
||||
selectedIndex: event.nativeEvent.selectedIndex,
|
||||
selectedIndex: event.nativeEvent.selectedSegmentIndex,
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
@@ -83,6 +83,26 @@ exports.examples = [{
|
||||
</View>
|
||||
);
|
||||
},
|
||||
}, {
|
||||
title: 'Status Bar Network Activity Indicator',
|
||||
render() {
|
||||
return (
|
||||
<View>
|
||||
<TouchableHighlight style={styles.wrapper}
|
||||
onPress={() => StatusBarIOS.setNetworkActivityIndicatorVisible(true)}>
|
||||
<View style={styles.button}>
|
||||
<Text>setNetworkActivityIndicatorVisible(true)</Text>
|
||||
</View>
|
||||
</TouchableHighlight>
|
||||
<TouchableHighlight style={styles.wrapper}
|
||||
onPress={() => StatusBarIOS.setNetworkActivityIndicatorVisible(false)}>
|
||||
<View style={styles.button}>
|
||||
<Text>setNetworkActivityIndicatorVisible(false)</Text>
|
||||
</View>
|
||||
</TouchableHighlight>
|
||||
</View>
|
||||
);
|
||||
},
|
||||
}];
|
||||
|
||||
var styles = StyleSheet.create({
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var React = require('React');
|
||||
|
||||
var SwitchAndroid = require('SwitchAndroid');
|
||||
var Text = require('Text');
|
||||
var UIExplorerBlock = require('UIExplorerBlock');
|
||||
var UIExplorerPage = require('UIExplorerPage');
|
||||
|
||||
var SwitchAndroidExample = React.createClass({
|
||||
statics: {
|
||||
title: '<SwitchAndroid>',
|
||||
description: 'Standard Android two-state toggle component'
|
||||
},
|
||||
|
||||
getInitialState : function() {
|
||||
return {
|
||||
trueSwitchIsOn: true,
|
||||
falseSwitchIsOn: false,
|
||||
colorTrueSwitchIsOn: true,
|
||||
colorFalseSwitchIsOn: false,
|
||||
eventSwitchIsOn: false,
|
||||
};
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return (
|
||||
<UIExplorerPage title="<SwitchAndroid>">
|
||||
<UIExplorerBlock title="Switches can be set to true or false">
|
||||
<SwitchAndroid
|
||||
onValueChange={(value) => this.setState({falseSwitchIsOn: value})}
|
||||
style={{marginBottom: 10}}
|
||||
value={this.state.falseSwitchIsOn} />
|
||||
<SwitchAndroid
|
||||
onValueChange={(value) => this.setState({trueSwitchIsOn: value})}
|
||||
value={this.state.trueSwitchIsOn} />
|
||||
</UIExplorerBlock>
|
||||
<UIExplorerBlock title="Switches can be disabled">
|
||||
<SwitchAndroid
|
||||
disabled={true}
|
||||
style={{marginBottom: 10}}
|
||||
value={true} />
|
||||
<SwitchAndroid
|
||||
disabled={true}
|
||||
value={false} />
|
||||
</UIExplorerBlock>
|
||||
<UIExplorerBlock title="Change events can be detected">
|
||||
<SwitchAndroid
|
||||
onValueChange={(value) => this.setState({eventSwitchIsOn: value})}
|
||||
style={{marginBottom: 10}}
|
||||
value={this.state.eventSwitchIsOn} />
|
||||
<SwitchAndroid
|
||||
onValueChange={(value) => this.setState({eventSwitchIsOn: value})}
|
||||
style={{marginBottom: 10}}
|
||||
value={this.state.eventSwitchIsOn} />
|
||||
<Text>{this.state.eventSwitchIsOn ? "On" : "Off"}</Text>
|
||||
</UIExplorerBlock>
|
||||
<UIExplorerBlock title="Switches are controlled components">
|
||||
<SwitchAndroid />
|
||||
<SwitchAndroid value={true} />
|
||||
</UIExplorerBlock>
|
||||
</UIExplorerPage>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = SwitchAndroidExample;
|
||||
@@ -23,12 +23,16 @@ var {
|
||||
View,
|
||||
} = React;
|
||||
|
||||
var base64Icon = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEsAAABLCAQAAACSR7JhAAADtUlEQVR4Ac3YA2Bj6QLH0XPT1Fzbtm29tW3btm3bfLZtv7e2ObZnms7d8Uw098tuetPzrxv8wiISrtVudrG2JXQZ4VOv+qUfmqCGGl1mqLhoA52oZlb0mrjsnhKpgeUNEs91Z0pd1kvihA3ULGVHiQO2narKSHKkEMulm9VgUyE60s1aWoMQUbpZOWE+kaqs4eLEjdIlZTcFZB0ndc1+lhB1lZrIuk5P2aib1NBpZaL+JaOGIt0ls47SKzLC7CqrlGF6RZ09HGoNy1lYl2aRSWL5GuzqWU1KafRdoRp0iOQEiDzgZPnG6DbldcomadViflnl/cL93tOoVbsOLVM2jylvdWjXolWX1hmfZbGR/wjypDjFLSZIRov09BgYmtUqPQPlQrPapecLgTIy0jMgPKtTeob2zWtrGH3xvjUkPCtNg/tm1rjwrMa+mdUkPd3hWbH0jArPGiU9ufCsNNWFZ40wpwn+62/66R2RUtoso1OB34tnLOcy7YB1fUdc9e0q3yru8PGM773vXsuZ5YIZX+5xmHwHGVvlrGPN6ZSiP1smOsMMde40wKv2VmwPPVXNut4sVpUreZiLBHi0qln/VQeI/LTMYXpsJtFiclUN+5HVZazim+Ky+7sAvxWnvjXrJFneVtLWLyPJu9K3cXLWeOlbMTlrIelbMDlrLenrjEQOtIF+fuI9xRp9ZBFp6+b6WT8RrxEpdK64BuvHgDk+vUy+b5hYk6zfyfs051gRoNO1usU12WWRWL73/MMEy9pMi9qIrR4ZpV16Rrvduxazmy1FSvuFXRkqTnE7m2kdb5U8xGjLw/spRr1uTov4uOgQE+0N/DvFrG/Jt7i/FzwxbA9kDanhf2w+t4V97G8lrT7wc08aA2QNUkuTfW/KimT01wdlfK4yEw030VfT0RtZbzjeMprNq8m8tnSTASrTLti64oBNdpmMQm0eEwvfPwRbUBywG5TzjPCsdwk3IeAXjQblLCoXnDVeoAz6SfJNk5TTzytCNZk/POtTSV40NwOFWzw86wNJRpubpXsn60NJFlHeqlYRbslqZm2jnEZ3qcSKgm0kTli3zZVS7y/iivZTweYXJ26Y+RTbV1zh3hYkgyFGSTKPfRVbRqWWVReaxYeSLarYv1Qqsmh1s95S7G+eEWK0f3jYKTbV6bOwepjfhtafsvUsqrQvrGC8YhmnO9cSCk3yuY984F1vesdHYhWJ5FvASlacshUsajFt2mUM9pqzvKGcyNJW0arTKN1GGGzQlH0tXwLDgQTurS8eIQAAAABJRU5ErkJggg==';
|
||||
|
||||
var TabBarExample = React.createClass({
|
||||
statics: {
|
||||
title: '<TabBarIOS>',
|
||||
description: 'Tab-based navigation.'
|
||||
description: 'Tab-based navigation.',
|
||||
},
|
||||
|
||||
displayName: 'TabBarExample',
|
||||
|
||||
getInitialState: function() {
|
||||
return {
|
||||
selectedTab: 'redTab',
|
||||
@@ -37,11 +41,11 @@ var TabBarExample = React.createClass({
|
||||
};
|
||||
},
|
||||
|
||||
_renderContent: function(color: string, pageText: string) {
|
||||
_renderContent: function(color: string, pageText: string, num?: number) {
|
||||
return (
|
||||
<View style={[styles.tabContent, {backgroundColor: color}]}>
|
||||
<Text style={styles.tabText}>{pageText}</Text>
|
||||
<Text style={styles.tabText}>{this.state.presses} re-renders of the More tab</Text>
|
||||
<Text style={styles.tabText}>{num} re-renders of the {pageText}</Text>
|
||||
</View>
|
||||
);
|
||||
},
|
||||
@@ -49,10 +53,11 @@ var TabBarExample = React.createClass({
|
||||
render: function() {
|
||||
return (
|
||||
<TabBarIOS
|
||||
tintColor="black"
|
||||
barTintColor="#3abeff">
|
||||
tintColor="white"
|
||||
barTintColor="darkslateblue">
|
||||
<TabBarIOS.Item
|
||||
title="Blue Tab"
|
||||
icon={{uri: base64Icon, scale: 3}}
|
||||
selected={this.state.selectedTab === 'blueTab'}
|
||||
onPress={() => {
|
||||
this.setState({
|
||||
@@ -71,7 +76,7 @@ var TabBarExample = React.createClass({
|
||||
notifCount: this.state.notifCount + 1,
|
||||
});
|
||||
}}>
|
||||
{this._renderContent('#783E33', 'Red Tab')}
|
||||
{this._renderContent('#783E33', 'Red Tab', this.state.notifCount)}
|
||||
</TabBarIOS.Item>
|
||||
<TabBarIOS.Item
|
||||
systemIcon="more"
|
||||
@@ -82,7 +87,7 @@ var TabBarExample = React.createClass({
|
||||
presses: this.state.presses + 1
|
||||
});
|
||||
}}>
|
||||
{this._renderContent('#21551C', 'Green Tab')}
|
||||
{this._renderContent('#21551C', 'Green Tab', this.state.presses)}
|
||||
</TabBarIOS.Item>
|
||||
</TabBarIOS>
|
||||
);
|
||||
|
||||
@@ -0,0 +1,349 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* @flow
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var React = require('react-native');
|
||||
var {
|
||||
StyleSheet,
|
||||
Text,
|
||||
View,
|
||||
} = React;
|
||||
var UIExplorerBlock = require('./UIExplorerBlock');
|
||||
var UIExplorerPage = require('./UIExplorerPage');
|
||||
|
||||
var Entity = React.createClass({
|
||||
render: function() {
|
||||
return (
|
||||
<Text style={{fontWeight: 'bold', color: '#527fe4'}}>
|
||||
{this.props.children}
|
||||
</Text>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var AttributeToggler = React.createClass({
|
||||
getInitialState: function() {
|
||||
return {fontWeight: 'bold', fontSize: 15};
|
||||
},
|
||||
toggleWeight: function() {
|
||||
this.setState({
|
||||
fontWeight: this.state.fontWeight === 'bold' ? 'normal' : 'bold'
|
||||
});
|
||||
},
|
||||
increaseSize: function() {
|
||||
this.setState({
|
||||
fontSize: this.state.fontSize + 1
|
||||
});
|
||||
},
|
||||
render: function() {
|
||||
var curStyle = {fontWeight: this.state.fontWeight, fontSize: this.state.fontSize};
|
||||
return (
|
||||
<View>
|
||||
<Text style={curStyle}>
|
||||
Tap the controls below to change attributes.
|
||||
</Text>
|
||||
<Text>
|
||||
<Text>See how it will even work on <Text style={curStyle}>this nested text</Text></Text>
|
||||
</Text>
|
||||
<Text>
|
||||
<Text onPress={this.toggleWeight}>Toggle Weight</Text>
|
||||
{' (with highlight onPress)'}
|
||||
</Text>
|
||||
<Text onPress={this.increaseSize} suppressHighlighting={true}>
|
||||
Increase Size (suppressHighlighting true)
|
||||
</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var TextExample = React.createClass({
|
||||
statics: {
|
||||
title: '<Text>',
|
||||
description: 'Base component for rendering styled text.',
|
||||
},
|
||||
render: function() {
|
||||
return (
|
||||
<UIExplorerPage title="<Text>">
|
||||
<UIExplorerBlock title="Wrap">
|
||||
<Text>
|
||||
The text should wrap if it goes on multiple lines.
|
||||
See, this is going to the next line.
|
||||
</Text>
|
||||
</UIExplorerBlock>
|
||||
<UIExplorerBlock title="Padding">
|
||||
<Text style={{padding: 10}}>
|
||||
This text is indented by 10px padding on all sides.
|
||||
</Text>
|
||||
</UIExplorerBlock>
|
||||
<UIExplorerBlock title="Font Family">
|
||||
<Text style={{fontFamily: 'sans-serif'}}>
|
||||
Sans-Serif
|
||||
</Text>
|
||||
<Text style={{fontFamily: 'sans-serif', fontWeight: 'bold'}}>
|
||||
Sans-Serif Bold
|
||||
</Text>
|
||||
<Text style={{fontFamily: 'serif'}}>
|
||||
Serif
|
||||
</Text>
|
||||
<Text style={{fontFamily: 'serif', fontWeight: 'bold'}}>
|
||||
Serif Bold
|
||||
</Text>
|
||||
<Text style={{fontFamily: 'monospace'}}>
|
||||
Monospace
|
||||
</Text>
|
||||
<Text style={{fontFamily: 'monospace', fontWeight: 'bold'}}>
|
||||
Monospace Bold (After 5.0)
|
||||
</Text>
|
||||
</UIExplorerBlock>
|
||||
<UIExplorerBlock title="Android Material Design fonts">
|
||||
<View style={{flexDirection: 'row', alignItems: 'flex-start'}}>
|
||||
<View style={{flex: 1}}>
|
||||
<Text style={{fontFamily: 'sans-serif'}}>
|
||||
Roboto Regular
|
||||
</Text>
|
||||
<Text style={{fontFamily: 'sans-serif', fontStyle: 'italic'}}>
|
||||
Roboto Italic
|
||||
</Text>
|
||||
<Text style={{fontFamily: 'sans-serif', fontWeight: 'bold'}}>
|
||||
Roboto Bold
|
||||
</Text>
|
||||
<Text style={{fontFamily: 'sans-serif', fontStyle: 'italic', fontWeight: 'bold'}}>
|
||||
Roboto Bold Italic
|
||||
</Text>
|
||||
<Text style={{fontFamily: 'sans-serif-light'}}>
|
||||
Roboto Light
|
||||
</Text>
|
||||
<Text style={{fontFamily: 'sans-serif-light', fontStyle: 'italic'}}>
|
||||
Roboto Light Italic
|
||||
</Text>
|
||||
<Text style={{fontFamily: 'sans-serif-thin'}}>
|
||||
Roboto Thin (After 4.2)
|
||||
</Text>
|
||||
<Text style={{fontFamily: 'sans-serif-thin', fontStyle: 'italic'}}>
|
||||
Roboto Thin Italic (After 4.2)
|
||||
</Text>
|
||||
<Text style={{fontFamily: 'sans-serif-condensed'}}>
|
||||
Roboto Condensed
|
||||
</Text>
|
||||
<Text style={{fontFamily: 'sans-serif-condensed', fontStyle: 'italic'}}>
|
||||
Roboto Condensed Italic
|
||||
</Text>
|
||||
<Text style={{fontFamily: 'sans-serif-condensed', fontWeight: 'bold'}}>
|
||||
Roboto Condensed Bold
|
||||
</Text>
|
||||
<Text style={{
|
||||
fontFamily: 'sans-serif-condensed',
|
||||
fontStyle: 'italic',
|
||||
fontWeight: 'bold'}}>
|
||||
Roboto Condensed Bold Italic
|
||||
</Text>
|
||||
<Text style={{fontFamily: 'sans-serif-medium'}}>
|
||||
Roboto Medium (After 5.0)
|
||||
</Text>
|
||||
<Text style={{fontFamily: 'sans-serif-medium', fontStyle: 'italic'}}>
|
||||
Roboto Medium Italic (After 5.0)
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
</UIExplorerBlock>
|
||||
<UIExplorerBlock title="Font Size">
|
||||
<Text style={{fontSize: 23}}>
|
||||
Size 23
|
||||
</Text>
|
||||
<Text style={{fontSize: 8}}>
|
||||
Size 8
|
||||
</Text>
|
||||
</UIExplorerBlock>
|
||||
<UIExplorerBlock title="Color">
|
||||
<Text style={{color: 'red'}}>
|
||||
Red color
|
||||
</Text>
|
||||
<Text style={{color: 'blue'}}>
|
||||
Blue color
|
||||
</Text>
|
||||
</UIExplorerBlock>
|
||||
<UIExplorerBlock title="Font Weight">
|
||||
<Text style={{fontWeight: 'bold'}}>
|
||||
Move fast and be bold
|
||||
</Text>
|
||||
<Text style={{fontWeight: 'normal'}}>
|
||||
Move fast and be bold
|
||||
</Text>
|
||||
</UIExplorerBlock>
|
||||
<UIExplorerBlock title="Font Style">
|
||||
<Text style={{fontStyle: 'italic'}}>
|
||||
Move fast and be bold
|
||||
</Text>
|
||||
<Text style={{fontStyle: 'normal'}}>
|
||||
Move fast and be bold
|
||||
</Text>
|
||||
</UIExplorerBlock>
|
||||
<UIExplorerBlock title="Font Style and Weight">
|
||||
<Text style={{fontStyle: 'italic', fontWeight: 'bold'}}>
|
||||
Move fast and be bold
|
||||
</Text>
|
||||
</UIExplorerBlock>
|
||||
<UIExplorerBlock title="Nested">
|
||||
<Text onPress={() => console.log('1st')}>
|
||||
(Normal text,
|
||||
<Text style={{fontWeight: 'bold'}} onPress={() => console.log('2nd')}>
|
||||
(and bold
|
||||
<Text style={{fontStyle: 'italic', fontSize: 11, color: '#527fe4'}} onPress={() => console.log('3rd')}>
|
||||
(and tiny bold italic blue
|
||||
<Text style={{fontWeight: 'normal', fontStyle: 'normal'}} onPress={() => console.log('4th')}>
|
||||
(and tiny normal blue)
|
||||
</Text>
|
||||
)
|
||||
</Text>
|
||||
)
|
||||
</Text>
|
||||
)
|
||||
</Text>
|
||||
<Text style={{fontFamily: 'serif'}} onPress={() => console.log('1st')}>
|
||||
(Serif
|
||||
<Text style={{fontStyle: 'italic', fontWeight: 'bold'}} onPress={() => console.log('2nd')}>
|
||||
(Serif Bold Italic
|
||||
<Text
|
||||
style={{fontFamily: 'monospace', fontStyle: 'normal', fontWeight: 'normal'}}
|
||||
onPress={() => console.log('3rd')}>
|
||||
(Monospace Normal
|
||||
<Text
|
||||
style={{fontFamily: 'sans-serif', fontWeight: 'bold'}}
|
||||
onPress={() => console.log('4th')}>
|
||||
(Sans-Serif Bold
|
||||
<Text style={{fontWeight: 'normal'}} onPress={() => console.log('5th')}>
|
||||
(and Sans-Serif Normal)
|
||||
</Text>
|
||||
)
|
||||
</Text>
|
||||
)
|
||||
</Text>
|
||||
)
|
||||
</Text>
|
||||
)
|
||||
</Text>
|
||||
<Text style={{fontSize: 12}}>
|
||||
<Entity>Entity Name</Entity>
|
||||
</Text>
|
||||
</UIExplorerBlock>
|
||||
<UIExplorerBlock title="Text Align">
|
||||
<Text>
|
||||
auto (default) - english LTR
|
||||
</Text>
|
||||
<Text>
|
||||
أحب اللغة العربية auto (default) - arabic RTL
|
||||
</Text>
|
||||
<Text style={{textAlign: 'left'}}>
|
||||
left left left left left left left left left left left left left left left
|
||||
</Text>
|
||||
<Text style={{textAlign: 'center'}}>
|
||||
center center center center center center center center center center center
|
||||
</Text>
|
||||
<Text style={{textAlign: 'right'}}>
|
||||
right right right right right right right right right right right right right
|
||||
</Text>
|
||||
</UIExplorerBlock>
|
||||
<UIExplorerBlock title="Unicode">
|
||||
<View style={{flex: 1}}>
|
||||
<View style={{flexDirection: 'row'}}>
|
||||
<Text style={{backgroundColor: 'red'}}>
|
||||
星际争霸是世界上最好的游戏。
|
||||
</Text>
|
||||
</View>
|
||||
<View style={{flex: 1}}>
|
||||
<Text style={{backgroundColor: 'red'}}>
|
||||
星际争霸是世界上最好的游戏。
|
||||
</Text>
|
||||
</View>
|
||||
<View style={{flex: 1, alignItems: 'center'}}>
|
||||
<Text style={{backgroundColor: 'red'}}>
|
||||
星际争霸是世界上最好的游戏。
|
||||
</Text>
|
||||
</View>
|
||||
<View style={{flex: 1}}>
|
||||
<Text style={{backgroundColor: 'red'}}>
|
||||
星际争霸是世界上最好的游戏。星际争霸是世界上最好的游戏。星际争霸是世界上最好的游戏。星际争霸是世界上最好的游戏。
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
</UIExplorerBlock>
|
||||
<UIExplorerBlock title="Spaces">
|
||||
<Text>
|
||||
A {'generated'} {' '} {'string'} and some spaces
|
||||
</Text>
|
||||
</UIExplorerBlock>
|
||||
<UIExplorerBlock title="Line Height">
|
||||
<Text style={{lineHeight: 35}}>
|
||||
Holisticly formulate inexpensive ideas before best-of-breed benefits. <Text style={{fontSize: 20}}>Continually</Text> expedite magnetic potentialities rather than client-focused interfaces.
|
||||
</Text>
|
||||
</UIExplorerBlock>
|
||||
<UIExplorerBlock title="Empty Text">
|
||||
<Text />
|
||||
</UIExplorerBlock>
|
||||
<UIExplorerBlock title="Toggling Attributes">
|
||||
<AttributeToggler />
|
||||
</UIExplorerBlock>
|
||||
<UIExplorerBlock title="backgroundColor attribute">
|
||||
<Text style={{backgroundColor: '#ffaaaa'}}>
|
||||
Red background,
|
||||
<Text style={{backgroundColor: '#aaaaff'}}>
|
||||
{' '}blue background,
|
||||
<Text>
|
||||
{' '}inherited blue background,
|
||||
<Text style={{backgroundColor: '#aaffaa'}}>
|
||||
{' '}nested green background.
|
||||
</Text>
|
||||
</Text>
|
||||
</Text>
|
||||
</Text>
|
||||
</UIExplorerBlock>
|
||||
<UIExplorerBlock title="containerBackgroundColor attribute">
|
||||
<View style={{flexDirection: 'row', height: 85}}>
|
||||
<View style={{backgroundColor: '#ffaaaa', width: 150}} />
|
||||
<View style={{backgroundColor: '#aaaaff', width: 150}} />
|
||||
</View>
|
||||
<Text style={[styles.backgroundColorText, {top: -80}]}>
|
||||
Default containerBackgroundColor (inherited) + backgroundColor wash
|
||||
</Text>
|
||||
<Text style={[styles.backgroundColorText, {top: -70, backgroundColor: 'transparent'}]}>
|
||||
{"containerBackgroundColor: 'transparent' + backgroundColor wash"}
|
||||
</Text>
|
||||
</UIExplorerBlock>
|
||||
<UIExplorerBlock title="numberOfLines attribute">
|
||||
<Text numberOfLines={1}>
|
||||
Maximum of one line no matter now much I write here. If I keep writing it{"'"}ll just truncate after one line
|
||||
</Text>
|
||||
<Text numberOfLines={2} style={{marginTop: 20}}>
|
||||
Maximum of two lines no matter now much I write here. If I keep writing it{"'"}ll just truncate after two lines
|
||||
</Text>
|
||||
<Text style={{marginTop: 20}}>
|
||||
No maximum lines specified no matter now much I write here. If I keep writing it{"'"}ll just keep going and going
|
||||
</Text>
|
||||
</UIExplorerBlock>
|
||||
</UIExplorerPage>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var styles = StyleSheet.create({
|
||||
backgroundColorText: {
|
||||
left: 5,
|
||||
backgroundColor: 'rgba(100, 100, 100, 0.3)'
|
||||
},
|
||||
});
|
||||
|
||||
module.exports = TextExample;
|
||||
@@ -185,6 +185,44 @@ exports.examples = [
|
||||
</View>
|
||||
);
|
||||
},
|
||||
}, {
|
||||
title: 'Text Decoration',
|
||||
render: function() {
|
||||
return (
|
||||
<View>
|
||||
<Text style={{textDecorationLine: 'underline', textDecorationStyle: 'solid'}}>
|
||||
Solid underline
|
||||
</Text>
|
||||
<Text style={{textDecorationLine: 'underline', textDecorationStyle: 'double', textDecorationColor: '#ff0000'}}>
|
||||
Double underline with custom color
|
||||
</Text>
|
||||
<Text style={{textDecorationLine: 'underline', textDecorationStyle: 'dashed', textDecorationColor: '#9CDC40'}}>
|
||||
Dashed underline with custom color
|
||||
</Text>
|
||||
<Text style={{textDecorationLine: 'underline', textDecorationStyle: 'dotted', textDecorationColor: 'blue'}}>
|
||||
Dotted underline with custom color
|
||||
</Text>
|
||||
<Text style={{textDecorationLine: 'none'}}>
|
||||
None textDecoration
|
||||
</Text>
|
||||
<Text style={{textDecorationLine: 'line-through', textDecorationStyle: 'solid'}}>
|
||||
Solid line-through
|
||||
</Text>
|
||||
<Text style={{textDecorationLine: 'line-through', textDecorationStyle: 'double', textDecorationColor: '#ff0000'}}>
|
||||
Double line-through with custom color
|
||||
</Text>
|
||||
<Text style={{textDecorationLine: 'line-through', textDecorationStyle: 'dashed', textDecorationColor: '#9CDC40'}}>
|
||||
Dashed line-through with custom color
|
||||
</Text>
|
||||
<Text style={{textDecorationLine: 'line-through', textDecorationStyle: 'dotted', textDecorationColor: 'blue'}}>
|
||||
Dotted line-through with custom color
|
||||
</Text>
|
||||
<Text style={{textDecorationLine: 'underline line-through'}}>
|
||||
Both underline and line-through
|
||||
</Text>
|
||||
</View>
|
||||
);
|
||||
},
|
||||
}, {
|
||||
title: 'Nested',
|
||||
description: 'Nested text components will inherit the styles of their ' +
|
||||
@@ -231,7 +269,7 @@ exports.examples = [
|
||||
right right right right right right right right right right right right right
|
||||
</Text>
|
||||
<Text style={{textAlign: 'justify'}}>
|
||||
justify: this text component's contents are laid out with "textAlign: justify"
|
||||
justify: this text component{"'"}s contents are laid out with "textAlign: justify"
|
||||
and as you can see all of the lines except the last one span the
|
||||
available width of the parent container.
|
||||
</Text>
|
||||
@@ -331,6 +369,34 @@ exports.examples = [
|
||||
</View>
|
||||
);
|
||||
},
|
||||
}, {
|
||||
title: 'Text highlighting (tap the link to see highlight)',
|
||||
render: function() {
|
||||
return (
|
||||
<View>
|
||||
<Text>Lorem ipsum dolor sit amet, <Text suppressHighlighting={false} style={{backgroundColor: 'white', textDecorationLine: 'underline', color: 'blue'}} onPress={() => null}>consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud</Text> exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</Text>
|
||||
</View>
|
||||
);
|
||||
},
|
||||
}, {
|
||||
title: 'allowFontScaling attribute',
|
||||
render: function() {
|
||||
return (
|
||||
<View>
|
||||
<Text>
|
||||
By default, text will respect Text Size accessibility setting on iOS.
|
||||
It means that all font sizes will be increased or descreased depending on the value of Text Size setting in
|
||||
{" "}<Text style={{fontWeight: 'bold'}}>Settings.app - Display & Brightness - Text Size</Text>
|
||||
</Text>
|
||||
<Text style={{marginTop: 10}}>
|
||||
You can disable scaling for your Text component by passing {"\""}allowFontScaling={"{"}false{"}\""} prop.
|
||||
</Text>
|
||||
<Text allowFontScaling={false} style={{marginTop: 20}}>
|
||||
This text will not scale.
|
||||
</Text>
|
||||
</View>
|
||||
);
|
||||
},
|
||||
}];
|
||||
|
||||
var styles = StyleSheet.create({
|
||||
|
||||
@@ -0,0 +1,316 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* @flow
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var React = require('react-native');
|
||||
var {
|
||||
Text,
|
||||
TextInput,
|
||||
View,
|
||||
StyleSheet,
|
||||
} = React;
|
||||
|
||||
var TextEventsExample = React.createClass({
|
||||
getInitialState: function() {
|
||||
return {
|
||||
curText: '<No Event>',
|
||||
prevText: '<No Event>',
|
||||
prev2Text: '<No Event>',
|
||||
};
|
||||
},
|
||||
|
||||
updateText: function(text) {
|
||||
this.setState((state) => {
|
||||
return {
|
||||
curText: text,
|
||||
prevText: state.curText,
|
||||
prev2Text: state.prevText,
|
||||
};
|
||||
});
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return (
|
||||
<View>
|
||||
<TextInput
|
||||
autoCapitalize="none"
|
||||
placeholder="Enter text to see events"
|
||||
autoCorrect={false}
|
||||
onFocus={() => this.updateText('onFocus')}
|
||||
onBlur={() => this.updateText('onBlur')}
|
||||
onChange={(event) => this.updateText(
|
||||
'onChange text: ' + event.nativeEvent.text
|
||||
)}
|
||||
onEndEditing={(event) => this.updateText(
|
||||
'onEndEditing text: ' + event.nativeEvent.text
|
||||
)}
|
||||
onSubmitEditing={(event) => this.updateText(
|
||||
'onSubmitEditing text: ' + event.nativeEvent.text
|
||||
)}
|
||||
style={styles.singleLine}
|
||||
/>
|
||||
<Text style={styles.eventLabel}>
|
||||
{this.state.curText}{'\n'}
|
||||
(prev: {this.state.prevText}){'\n'}
|
||||
(prev2: {this.state.prev2Text})
|
||||
</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
class RewriteExample extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {text: ''};
|
||||
}
|
||||
render() {
|
||||
return (
|
||||
<TextInput
|
||||
onChangeText={(text) => {
|
||||
text = text.replace(/ /g, '_');
|
||||
this.setState({text});
|
||||
}}
|
||||
style={styles.singleLine}
|
||||
value={this.state.text}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
var styles = StyleSheet.create({
|
||||
multiline: {
|
||||
height: 60,
|
||||
fontSize: 16,
|
||||
padding: 4,
|
||||
marginBottom: 10,
|
||||
},
|
||||
eventLabel: {
|
||||
margin: 3,
|
||||
fontSize: 12,
|
||||
},
|
||||
singleLine: {
|
||||
fontSize: 16,
|
||||
padding: 4,
|
||||
},
|
||||
singleLineWithHeightTextInput: {
|
||||
height: 30,
|
||||
},
|
||||
});
|
||||
|
||||
exports.title = '<TextInput>';
|
||||
exports.description = 'Single and multi-line text inputs.';
|
||||
exports.examples = [
|
||||
{
|
||||
title: 'Auto-focus',
|
||||
render: function() {
|
||||
return <TextInput autoFocus={true} style={styles.singleLine} />;
|
||||
}
|
||||
},
|
||||
{
|
||||
title: "Live Re-Write (<sp> -> '_')",
|
||||
render: function() {
|
||||
return <RewriteExample />;
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Auto-capitalize',
|
||||
render: function() {
|
||||
var autoCapitalizeTypes = [
|
||||
'none',
|
||||
'sentences',
|
||||
'words',
|
||||
'characters',
|
||||
];
|
||||
var examples = autoCapitalizeTypes.map((type) => {
|
||||
return (
|
||||
<TextInput
|
||||
autoCapitalize={type}
|
||||
placeholder={'autoCapitalize: ' + type}
|
||||
style={styles.singleLine}
|
||||
/>
|
||||
);
|
||||
});
|
||||
return <View>{examples}</View>;
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Auto-correct',
|
||||
render: function() {
|
||||
return (
|
||||
<View>
|
||||
<TextInput
|
||||
autoCorrect={true}
|
||||
placeholder="This has autoCorrect"
|
||||
style={styles.singleLine}
|
||||
/>
|
||||
<TextInput
|
||||
autoCorrect={false}
|
||||
placeholder="This does not have autoCorrect"
|
||||
style={styles.singleLine}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Keyboard types',
|
||||
render: function() {
|
||||
var keyboardTypes = [
|
||||
'default',
|
||||
'email-address',
|
||||
'numeric',
|
||||
];
|
||||
var examples = keyboardTypes.map((type) => {
|
||||
return (
|
||||
<TextInput
|
||||
keyboardType={type}
|
||||
placeholder={'keyboardType: ' + type}
|
||||
style={styles.singleLine}
|
||||
/>
|
||||
);
|
||||
});
|
||||
return <View>{examples}</View>;
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Event handling',
|
||||
render: function(): ReactElement { return <TextEventsExample />; },
|
||||
},
|
||||
{
|
||||
title: 'Colors and text inputs',
|
||||
render: function() {
|
||||
return (
|
||||
<View>
|
||||
<TextInput
|
||||
style={[styles.singleLine]}
|
||||
defaultValue="Default color text"
|
||||
/>
|
||||
<TextInput
|
||||
style={[styles.singleLine, {color: 'green'}]}
|
||||
defaultValue="Green Text"
|
||||
/>
|
||||
<TextInput
|
||||
placeholder="Default placeholder text color"
|
||||
style={styles.singleLine}
|
||||
/>
|
||||
<TextInput
|
||||
placeholder="Red placeholder text color"
|
||||
placeholderTextColor="red"
|
||||
style={styles.singleLine}
|
||||
/>
|
||||
<TextInput
|
||||
placeholder="Default underline color"
|
||||
style={styles.singleLine}
|
||||
/>
|
||||
<TextInput
|
||||
placeholder="Blue underline color"
|
||||
style={styles.singleLine}
|
||||
underlineColorAndroid="blue"
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Text input, themes and heights',
|
||||
render: function() {
|
||||
return (
|
||||
<TextInput
|
||||
placeholder="If you set height, beware of padding set from themes"
|
||||
style={[styles.singleLineWithHeightTextInput]}
|
||||
/>
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Passwords',
|
||||
render: function() {
|
||||
return (
|
||||
<TextInput
|
||||
defaultValue="iloveturtles"
|
||||
password={true}
|
||||
style={styles.singleLine}
|
||||
/>
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Editable',
|
||||
render: function() {
|
||||
return (
|
||||
<TextInput
|
||||
defaultValue="Can't touch this! (>'-')> ^(' - ')^ <('-'<) (>'-')> ^(' - ')^"
|
||||
editable={false}
|
||||
style={styles.singleLine}
|
||||
/>
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Multiline',
|
||||
render: function() {
|
||||
return (
|
||||
<View>
|
||||
<TextInput
|
||||
autoCorrect={true}
|
||||
placeholder="multiline, aligned top-left"
|
||||
placeholderTextColor="red"
|
||||
multiline={true}
|
||||
textAlign="start"
|
||||
textAlignVertical="top"
|
||||
style={styles.multiline}
|
||||
/>
|
||||
<TextInput
|
||||
autoCorrect={true}
|
||||
placeholder="multiline, aligned center"
|
||||
placeholderTextColor="green"
|
||||
multiline={true}
|
||||
textAlign="center"
|
||||
textAlignVertical="center"
|
||||
style={[styles.multiline]}
|
||||
/>
|
||||
<TextInput
|
||||
autoCorrect={true}
|
||||
multiline={true}
|
||||
textAlign="end"
|
||||
textAlignVertical="bottom"
|
||||
style={[styles.multiline, {color: 'blue'}]}>
|
||||
<Text style={styles.multiline}>multiline with children, aligned bottom-right</Text>
|
||||
</TextInput>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Fixed number of lines',
|
||||
platform: 'android',
|
||||
render: function() {
|
||||
return (
|
||||
<View>
|
||||
<TextInput numberOfLines={2}
|
||||
multiline={true}
|
||||
placeholder="Two line input"
|
||||
/>
|
||||
<TextInput numberOfLines={5}
|
||||
multiline={true}
|
||||
placeholder="Five line input"
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
},
|
||||
];
|
||||
@@ -33,7 +33,7 @@ var WithLabel = React.createClass({
|
||||
{this.props.children}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
var TextEventsExample = React.createClass({
|
||||
@@ -41,13 +41,17 @@ var TextEventsExample = React.createClass({
|
||||
return {
|
||||
curText: '<No Event>',
|
||||
prevText: '<No Event>',
|
||||
prev2Text: '<No Event>',
|
||||
};
|
||||
},
|
||||
|
||||
updateText: function(text) {
|
||||
this.setState({
|
||||
curText: text,
|
||||
prevText: this.state.curText,
|
||||
this.setState((state) => {
|
||||
return {
|
||||
curText: text,
|
||||
prevText: state.curText,
|
||||
prev2Text: state.prevText,
|
||||
};
|
||||
});
|
||||
},
|
||||
|
||||
@@ -73,13 +77,43 @@ var TextEventsExample = React.createClass({
|
||||
/>
|
||||
<Text style={styles.eventLabel}>
|
||||
{this.state.curText}{'\n'}
|
||||
(prev: {this.state.prevText})
|
||||
(prev: {this.state.prevText}){'\n'}
|
||||
(prev2: {this.state.prev2Text})
|
||||
</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
class RewriteExample extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {text: ''};
|
||||
}
|
||||
render() {
|
||||
var limit = 20;
|
||||
var remainder = limit - this.state.text.length;
|
||||
var remainderColor = remainder > 5 ? 'blue' : 'red';
|
||||
return (
|
||||
<View style={styles.rewriteContainer}>
|
||||
<TextInput
|
||||
multiline={false}
|
||||
maxLength={limit}
|
||||
onChangeText={(text) => {
|
||||
text = text.replace(/ /g, '_');
|
||||
this.setState({text});
|
||||
}}
|
||||
style={styles.default}
|
||||
value={this.state.text}
|
||||
/>
|
||||
<Text style={[styles.remainder, {color: remainderColor}]}>
|
||||
{remainder}
|
||||
</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
var styles = StyleSheet.create({
|
||||
page: {
|
||||
paddingBottom: 300,
|
||||
@@ -125,12 +159,19 @@ var styles = StyleSheet.create({
|
||||
flex: 1,
|
||||
},
|
||||
label: {
|
||||
width: 120,
|
||||
justifyContent: 'flex-end',
|
||||
flexDirection: 'row',
|
||||
width: 115,
|
||||
alignItems: 'flex-end',
|
||||
marginRight: 10,
|
||||
paddingTop: 2,
|
||||
},
|
||||
rewriteContainer: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
},
|
||||
remainder: {
|
||||
textAlign: 'right',
|
||||
width: 24,
|
||||
},
|
||||
});
|
||||
|
||||
exports.displayName = (undefined: ?string);
|
||||
@@ -143,6 +184,12 @@ exports.examples = [
|
||||
return <TextInput autoFocus={true} style={styles.default} />;
|
||||
}
|
||||
},
|
||||
{
|
||||
title: "Live Re-Write (<sp> -> '_') + maxLength",
|
||||
render: function() {
|
||||
return <RewriteExample />;
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Auto-capitalize',
|
||||
render: function() {
|
||||
@@ -268,7 +315,7 @@ exports.examples = [
|
||||
return (
|
||||
<View>
|
||||
<WithLabel label="true">
|
||||
<TextInput password={true} style={styles.default} value="abc" />
|
||||
<TextInput password={true} style={styles.default} defaultValue="abc" />
|
||||
</WithLabel>
|
||||
</View>
|
||||
);
|
||||
@@ -276,7 +323,7 @@ exports.examples = [
|
||||
},
|
||||
{
|
||||
title: 'Event handling',
|
||||
render: function(): ReactElement { return <TextEventsExample /> },
|
||||
render: function(): ReactElement { return <TextEventsExample />; },
|
||||
},
|
||||
{
|
||||
title: 'Colored input text',
|
||||
@@ -285,11 +332,11 @@ exports.examples = [
|
||||
<View>
|
||||
<TextInput
|
||||
style={[styles.default, {color: 'blue'}]}
|
||||
value="Blue"
|
||||
defaultValue="Blue"
|
||||
/>
|
||||
<TextInput
|
||||
style={[styles.default, {color: 'green'}]}
|
||||
value="Green"
|
||||
defaultValue="Green"
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
@@ -336,7 +383,7 @@ exports.examples = [
|
||||
<WithLabel label="clearTextOnFocus">
|
||||
<TextInput
|
||||
placeholder="text is cleared on focus"
|
||||
value="text is cleared on focus"
|
||||
defaultValue="text is cleared on focus"
|
||||
style={styles.default}
|
||||
clearTextOnFocus={true}
|
||||
/>
|
||||
@@ -344,7 +391,7 @@ exports.examples = [
|
||||
<WithLabel label="selectTextOnFocus">
|
||||
<TextInput
|
||||
placeholder="text is selected on focus"
|
||||
value="text is selected on focus"
|
||||
defaultValue="text is selected on focus"
|
||||
style={styles.default}
|
||||
selectTextOnFocus={true}
|
||||
/>
|
||||
@@ -364,7 +411,7 @@ exports.examples = [
|
||||
style={styles.multiline}
|
||||
/>
|
||||
<TextInput
|
||||
placeholder="mutliline text input with font styles and placeholder"
|
||||
placeholder="multiline text input with font styles and placeholder"
|
||||
multiline={true}
|
||||
clearTextOnFocus={true}
|
||||
autoCorrect={true}
|
||||
@@ -374,7 +421,7 @@ exports.examples = [
|
||||
style={[styles.multiline, styles.multilineWithFontStyles]}
|
||||
/>
|
||||
<TextInput
|
||||
placeholder="uneditable mutliline text input"
|
||||
placeholder="uneditable multiline text input"
|
||||
editable={false}
|
||||
multiline={true}
|
||||
style={styles.multiline}
|
||||
@@ -0,0 +1,68 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* @flow
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var React = require('react-native');
|
||||
var {
|
||||
StyleSheet,
|
||||
Text,
|
||||
ToastAndroid,
|
||||
TouchableWithoutFeedback
|
||||
} = React;
|
||||
|
||||
var UIExplorerBlock = require('UIExplorerBlock');
|
||||
var UIExplorerPage = require('UIExplorerPage');
|
||||
|
||||
var ToastExample = React.createClass({
|
||||
|
||||
statics: {
|
||||
title: 'Toast Example',
|
||||
description: 'Toast Example',
|
||||
},
|
||||
|
||||
getInitialState: function() {
|
||||
return {};
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return (
|
||||
<UIExplorerPage title="ToastAndroid">
|
||||
<UIExplorerBlock title="Simple toast">
|
||||
<TouchableWithoutFeedback
|
||||
onPress={() =>
|
||||
ToastAndroid.show('This is a toast with short duration', ToastAndroid.SHORT)}>
|
||||
<Text style={styles.text}>Click me.</Text>
|
||||
</TouchableWithoutFeedback>
|
||||
</UIExplorerBlock>
|
||||
<UIExplorerBlock title="Toast with long duration">
|
||||
<TouchableWithoutFeedback
|
||||
onPress={() =>
|
||||
ToastAndroid.show('This is a toast with long duration', ToastAndroid.LONG)}>
|
||||
<Text style={styles.text}>Click me too.</Text>
|
||||
</TouchableWithoutFeedback>
|
||||
</UIExplorerBlock>
|
||||
</UIExplorerPage>
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
var styles = StyleSheet.create({
|
||||
text: {
|
||||
color: 'black',
|
||||
},
|
||||
});
|
||||
|
||||
module.exports = ToastExample;
|
||||
@@ -0,0 +1,119 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* @flow
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var React = require('react-native');
|
||||
var {
|
||||
StyleSheet,
|
||||
Text,
|
||||
View,
|
||||
} = React;
|
||||
var UIExplorerBlock = require('./UIExplorerBlock');
|
||||
var UIExplorerPage = require('./UIExplorerPage');
|
||||
|
||||
var SwitchAndroid = require('SwitchAndroid');
|
||||
var ToolbarAndroid = require('ToolbarAndroid');
|
||||
|
||||
var ToolbarAndroidExample = React.createClass({
|
||||
statics: {
|
||||
title: '<ToolbarAndroid>',
|
||||
description: 'Examples of using the Android toolbar.'
|
||||
},
|
||||
getInitialState: function() {
|
||||
return {
|
||||
actionText: 'Example app with toolbar component',
|
||||
toolbarSwitch: false,
|
||||
colorProps: {
|
||||
titleColor: '#3b5998',
|
||||
subtitleColor: '#6a7180',
|
||||
},
|
||||
};
|
||||
},
|
||||
render: function() {
|
||||
return (
|
||||
<UIExplorerPage title="<ToolbarAndroid>">
|
||||
<UIExplorerBlock title="Toolbar with title/subtitle and actions">
|
||||
<ToolbarAndroid
|
||||
actions={toolbarActions}
|
||||
navIcon={require('image!ic_menu_black_24dp')}
|
||||
onActionSelected={this._onActionSelected}
|
||||
onIconClicked={() => this.setState({actionText: 'Icon clicked'})}
|
||||
style={styles.toolbar}
|
||||
subtitle={this.state.actionText}
|
||||
title="Toolbar" />
|
||||
<Text>{this.state.actionText}</Text>
|
||||
</UIExplorerBlock>
|
||||
<UIExplorerBlock title="Toolbar with logo & custom title view (a View with Switch+Text)">
|
||||
<ToolbarAndroid
|
||||
logo={require('image!launcher_icon')}
|
||||
style={styles.toolbar}>
|
||||
<View style={{height: 56, flexDirection: 'row', alignItems: 'center'}}>
|
||||
<SwitchAndroid
|
||||
value={this.state.toolbarSwitch}
|
||||
onValueChange={(value) => this.setState({'toolbarSwitch': value})} />
|
||||
<Text>{'\'Tis but a switch'}</Text>
|
||||
</View>
|
||||
</ToolbarAndroid>
|
||||
</UIExplorerBlock>
|
||||
<UIExplorerBlock title="Toolbar with no icon">
|
||||
<ToolbarAndroid
|
||||
actions={toolbarActions}
|
||||
style={styles.toolbar}
|
||||
subtitle="There be no icon here" />
|
||||
</UIExplorerBlock>
|
||||
<UIExplorerBlock title="Toolbar with navIcon & logo, no title">
|
||||
<ToolbarAndroid
|
||||
actions={toolbarActions}
|
||||
logo={require('image!launcher_icon')}
|
||||
navIcon={require('image!ic_menu_black_24dp')}
|
||||
style={styles.toolbar} />
|
||||
</UIExplorerBlock>
|
||||
<UIExplorerBlock title="Toolbar with custom title colors">
|
||||
<ToolbarAndroid
|
||||
navIcon={require('image!ic_menu_black_24dp')}
|
||||
onIconClicked={() => this.setState({colorProps: {}})}
|
||||
title="Wow, such toolbar"
|
||||
style={styles.toolbar}
|
||||
subtitle="Much native"
|
||||
{...this.state.colorProps} />
|
||||
<Text>
|
||||
Touch the icon to reset the custom colors to the default (theme-provided) ones.
|
||||
</Text>
|
||||
</UIExplorerBlock>
|
||||
</UIExplorerPage>
|
||||
);
|
||||
},
|
||||
_onActionSelected: function(position) {
|
||||
this.setState({
|
||||
actionText: 'Selected ' + toolbarActions[position].title,
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
var toolbarActions = [
|
||||
{title: 'Create', icon: require('image!ic_create_black_48dp'), show: 'always'},
|
||||
{title: 'Filter'},
|
||||
{title: 'Settings', icon: require('image!ic_settings_black_48dp'), show: 'always'},
|
||||
];
|
||||
|
||||
var styles = StyleSheet.create({
|
||||
toolbar: {
|
||||
backgroundColor: '#e9eaed',
|
||||
height: 56,
|
||||
},
|
||||
});
|
||||
|
||||
module.exports = ToolbarAndroidExample;
|
||||
@@ -27,6 +27,7 @@ var {
|
||||
} = React;
|
||||
|
||||
exports.displayName = (undefined: ?string);
|
||||
exports.description = 'Touchable and onPress examples';
|
||||
exports.title = '<Touchable*> and onPress';
|
||||
exports.examples = [
|
||||
{
|
||||
@@ -130,10 +131,11 @@ var TouchableFeedbackEvents = React.createClass({
|
||||
},
|
||||
render: function() {
|
||||
return (
|
||||
<View>
|
||||
<View testID="touchable_feedback_events">
|
||||
<View style={[styles.row, {justifyContent: 'center'}]}>
|
||||
<TouchableOpacity
|
||||
style={styles.wrapper}
|
||||
testID="touchable_feedback_events_button"
|
||||
onPress={() => this._appendEvent('press')}
|
||||
onPressIn={() => this._appendEvent('pressIn')}
|
||||
onPressOut={() => this._appendEvent('pressOut')}
|
||||
@@ -143,7 +145,7 @@ var TouchableFeedbackEvents = React.createClass({
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
<View style={styles.eventLogBox}>
|
||||
<View testID="touchable_feedback_events_console" style={styles.eventLogBox}>
|
||||
{this.state.eventLog.map((e, ii) => <Text key={ii}>{e}</Text>)}
|
||||
</View>
|
||||
</View>
|
||||
@@ -165,10 +167,11 @@ var TouchableDelayEvents = React.createClass({
|
||||
},
|
||||
render: function() {
|
||||
return (
|
||||
<View>
|
||||
<View testID="touchable_delay_events">
|
||||
<View style={[styles.row, {justifyContent: 'center'}]}>
|
||||
<TouchableOpacity
|
||||
style={styles.wrapper}
|
||||
testID="touchable_delay_events_button"
|
||||
onPress={() => this._appendEvent('press')}
|
||||
delayPressIn={400}
|
||||
onPressIn={() => this._appendEvent('pressIn - 400ms delay')}
|
||||
@@ -181,7 +184,7 @@ var TouchableDelayEvents = React.createClass({
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
<View style={styles.eventLogBox}>
|
||||
<View style={styles.eventLogBox} testID="touchable_delay_events_console">
|
||||
{this.state.eventLog.map((e, ii) => <Text key={ii}>{e}</Text>)}
|
||||
</View>
|
||||
</View>
|
||||
|
||||
@@ -1,59 +1,85 @@
|
||||
/**
|
||||
* Copyright 2004-present Facebook. All Rights Reserved.
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* @providesModule TransformExample
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var React = require('React');
|
||||
|
||||
var StyleSheet = require('StyleSheet');
|
||||
var TimerMixin = require('react-timer-mixin');
|
||||
var UIExplorerBlock = require('UIExplorerBlock');
|
||||
var UIExplorerPage = require('UIExplorerPage');
|
||||
var View = require('View');
|
||||
|
||||
var TransformExample = React.createClass({
|
||||
|
||||
mixins: [TimerMixin],
|
||||
var React = require('react-native');
|
||||
var {
|
||||
Animated,
|
||||
StyleSheet,
|
||||
Text,
|
||||
View,
|
||||
} = React;
|
||||
|
||||
var Flip = React.createClass({
|
||||
getInitialState() {
|
||||
return {
|
||||
interval: this.setInterval(this._update, 800),
|
||||
pulse: false,
|
||||
theta: new Animated.Value(45),
|
||||
};
|
||||
},
|
||||
|
||||
componentDidMount() {
|
||||
this._animate();
|
||||
},
|
||||
|
||||
_animate() {
|
||||
this.state.theta.setValue(0);
|
||||
Animated.timing(this.state.theta, {
|
||||
toValue: 360,
|
||||
duration: 5000,
|
||||
}).start(this._animate);
|
||||
},
|
||||
|
||||
render() {
|
||||
return (
|
||||
<UIExplorerPage title="Transforms">
|
||||
<UIExplorerBlock title="foo bar">
|
||||
<View style={{height: 500}}>
|
||||
<View style={styles.box1} />
|
||||
<View style={styles.box2} />
|
||||
<View style={styles.box3step1} />
|
||||
<View style={styles.box3step2} />
|
||||
<View style={styles.box3step3} />
|
||||
<View style={styles.box4} />
|
||||
<View style={[
|
||||
styles.box5,
|
||||
this.state.pulse ? styles.box5Transform : null
|
||||
]} />
|
||||
</View>
|
||||
</UIExplorerBlock>
|
||||
</UIExplorerPage>
|
||||
<View style={styles.flipCardContainer}>
|
||||
<Animated.View style={[
|
||||
styles.flipCard,
|
||||
{transform: [
|
||||
{perspective: 850},
|
||||
{rotateX: this.state.theta.interpolate({
|
||||
inputRange: [0, 180],
|
||||
outputRange: ['0deg', '180deg']
|
||||
})},
|
||||
]}]}>
|
||||
<Text style={styles.flipText}>
|
||||
This text is flipping great.
|
||||
</Text>
|
||||
</Animated.View>
|
||||
<Animated.View style={[styles.flipCard, {
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
backgroundColor: 'red',
|
||||
transform: [
|
||||
{perspective: 850},
|
||||
{rotateX: this.state.theta.interpolate({
|
||||
inputRange: [0, 180],
|
||||
outputRange: ['180deg', '360deg']
|
||||
})},
|
||||
]}]}>
|
||||
<Text style={styles.flipText}>
|
||||
On the flip side...
|
||||
</Text>
|
||||
</Animated.View>
|
||||
</View>
|
||||
);
|
||||
},
|
||||
|
||||
_update() {
|
||||
this.setState({
|
||||
pulse: !this.state.pulse,
|
||||
});
|
||||
},
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
var styles = StyleSheet.create({
|
||||
container: {
|
||||
height: 500,
|
||||
},
|
||||
box1: {
|
||||
left: 0,
|
||||
backgroundColor: 'green',
|
||||
@@ -86,7 +112,7 @@ var styles = StyleSheet.create({
|
||||
},
|
||||
box3step1: {
|
||||
left: 0,
|
||||
backgroundColor: '#ffb6c1', // lightpink
|
||||
backgroundColor: 'lightpink',
|
||||
height: 50,
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
@@ -97,7 +123,7 @@ var styles = StyleSheet.create({
|
||||
},
|
||||
box3step2: {
|
||||
left: 0,
|
||||
backgroundColor: '#ff69b4', //hotpink
|
||||
backgroundColor: 'hotpink',
|
||||
height: 50,
|
||||
opacity: 0.5,
|
||||
position: 'absolute',
|
||||
@@ -111,7 +137,7 @@ var styles = StyleSheet.create({
|
||||
},
|
||||
box3step3: {
|
||||
left: 0,
|
||||
backgroundColor: '#ff1493', // deeppink
|
||||
backgroundColor: 'deeppink',
|
||||
height: 50,
|
||||
opacity: 0.5,
|
||||
position: 'absolute',
|
||||
@@ -127,7 +153,7 @@ var styles = StyleSheet.create({
|
||||
},
|
||||
box4: {
|
||||
left: 0,
|
||||
backgroundColor: '#ff8c00', // darkorange
|
||||
backgroundColor: 'darkorange',
|
||||
height: 50,
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
@@ -139,7 +165,7 @@ var styles = StyleSheet.create({
|
||||
width: 100,
|
||||
},
|
||||
box5: {
|
||||
backgroundColor: '#800000', // maroon
|
||||
backgroundColor: 'maroon',
|
||||
height: 50,
|
||||
position: 'absolute',
|
||||
right: 0,
|
||||
@@ -153,7 +179,110 @@ var styles = StyleSheet.create({
|
||||
{scale: 2},
|
||||
],
|
||||
},
|
||||
flipCardContainer: {
|
||||
marginVertical: 40,
|
||||
flex: 1,
|
||||
alignSelf: 'center',
|
||||
},
|
||||
flipCard: {
|
||||
width: 200,
|
||||
height: 200,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
backgroundColor: 'blue',
|
||||
backfaceVisibility: 'hidden',
|
||||
},
|
||||
flipText: {
|
||||
width: 90,
|
||||
fontSize: 20,
|
||||
color: 'white',
|
||||
fontWeight: 'bold',
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
module.exports = TransformExample;
|
||||
exports.title = 'Transforms';
|
||||
exports.description = 'View transforms';
|
||||
exports.examples = [
|
||||
{
|
||||
title: 'Perspective',
|
||||
description: 'perspective: 850, rotateX: Animated.timing(0 -> 360)',
|
||||
render(): ReactElement { return <Flip />; }
|
||||
},
|
||||
{
|
||||
title: 'Translate, Rotate, Scale',
|
||||
description: "translateX: 100, translateY: 50, rotate: '30deg', scaleX: 2, scaleY: 2",
|
||||
render() {
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<View style={styles.box1} />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Scale, Translate, Rotate, ',
|
||||
description: "scaleX: 2, scaleY: 2, translateX: 100, translateY: 50, rotate: '30deg'",
|
||||
render() {
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<View style={styles.box2} />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Rotate',
|
||||
description: "rotate: '30deg'",
|
||||
render() {
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<View style={styles.box3step1} />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Rotate, Scale',
|
||||
description: "rotate: '30deg', scaleX: 2, scaleY: 2",
|
||||
render() {
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<View style={styles.box3step2} />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Rotate, Scale, Translate ',
|
||||
description: "rotate: '30deg', scaleX: 2, scaleY: 2, translateX: 100, translateY: 50",
|
||||
render() {
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<View style={styles.box3step3} />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Translate, Scale, Rotate',
|
||||
description: "translate: [200, 350], scale: 2.5, rotate: '-0.2rad'",
|
||||
render() {
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<View style={styles.box4} />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Translate, Rotate, Scale',
|
||||
description: "translate: [-50, 35], rotate: '50deg', scale: 2",
|
||||
render() {
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<View style={[styles.box5, styles.box5Transform]} />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
@@ -7,19 +7,25 @@
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
1300627F1B59179B0043FE5A /* RCTGzipTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 1300627E1B59179B0043FE5A /* RCTGzipTests.m */; };
|
||||
13417FE91AA91432003F314A /* libRCTImage.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 13417FE81AA91428003F314A /* libRCTImage.a */; };
|
||||
134180011AA9153C003F314A /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 13417FEF1AA914B8003F314A /* libRCTText.a */; };
|
||||
1341802C1AA9178B003F314A /* libRCTNetwork.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1341802B1AA91779003F314A /* libRCTNetwork.a */; };
|
||||
134454601AAFCABD003F0779 /* libRCTAdSupport.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1344545A1AAFCAAE003F0779 /* libRCTAdSupport.a */; };
|
||||
134A8A2A1AACED7A00945AAE /* libRCTGeolocation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 134A8A251AACED6A00945AAE /* libRCTGeolocation.a */; };
|
||||
138D6A171B53CD440074A87E /* RCTCacheTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 138D6A151B53CD440074A87E /* RCTCacheTests.m */; };
|
||||
138D6A181B53CD440074A87E /* RCTShadowViewTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 138D6A161B53CD440074A87E /* RCTShadowViewTests.m */; };
|
||||
1393D0381B68CD1300E1B601 /* RCTModuleMethodTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 1393D0371B68CD1300E1B601 /* RCTModuleMethodTests.m */; };
|
||||
139FDEDB1B0651FB00C62182 /* libRCTWebSocket.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 139FDED91B0651EA00C62182 /* libRCTWebSocket.a */; };
|
||||
13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; };
|
||||
13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB11A68108700A75B9A /* LaunchScreen.xib */; };
|
||||
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
|
||||
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
|
||||
141FC1211B222EBB004D5FFB /* IntegrationTestsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 141FC1201B222EBB004D5FFB /* IntegrationTestsTests.m */; };
|
||||
143BC5A11B21E45C00462512 /* UIExplorerIntegrationTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 143BC5A01B21E45C00462512 /* UIExplorerIntegrationTests.m */; };
|
||||
144D21241B2204C5006DB32B /* RCTClippingTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 144D21231B2204C5006DB32B /* RCTClippingTests.m */; };
|
||||
13DB03481B5D2ED500C27245 /* RCTJSONTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 13DB03471B5D2ED500C27245 /* RCTJSONTests.m */; };
|
||||
13DF61B61B67A45000EDB188 /* RCTMethodArgumentTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 13DF61B51B67A45000EDB188 /* RCTMethodArgumentTests.m */; };
|
||||
141FC1211B222EBB004D5FFB /* IntegrationTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 141FC1201B222EBB004D5FFB /* IntegrationTests.m */; };
|
||||
143BC5A11B21E45C00462512 /* UIExplorerSnapshotTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 143BC5A01B21E45C00462512 /* UIExplorerSnapshotTests.m */; };
|
||||
144D21241B2204C5006DB32B /* RCTImageUtilTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 144D21231B2204C5006DB32B /* RCTImageUtilTests.m */; };
|
||||
147CED4C1AB3532B00DA3E4C /* libRCTActionSheet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 147CED4B1AB34F8C00DA3E4C /* libRCTActionSheet.a */; };
|
||||
1497CFAC1B21F5E400C1F8F2 /* RCTAllocationTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 1497CFA41B21F5E400C1F8F2 /* RCTAllocationTests.m */; };
|
||||
1497CFAD1B21F5E400C1F8F2 /* RCTBridgeTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 1497CFA51B21F5E400C1F8F2 /* RCTBridgeTests.m */; };
|
||||
@@ -47,6 +53,8 @@
|
||||
14DC67F41AB71881001358AB /* libRCTPushNotification.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 14DC67F11AB71876001358AB /* libRCTPushNotification.a */; };
|
||||
3578590A1B28D2CF00341EDB /* libRCTLinking.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 357859011B28D2C500341EDB /* libRCTLinking.a */; };
|
||||
834C36EC1AF8DED70019C93C /* libRCTSettings.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 834C36D21AF8DA610019C93C /* libRCTSettings.a */; };
|
||||
83636F8F1B53F22C009F943E /* RCTUIManagerScenarioTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 83636F8E1B53F22C009F943E /* RCTUIManagerScenarioTests.m */; };
|
||||
83A936C81B7E0F08005B9C36 /* RCTConvert_UIColorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 83A936C71B7E0F08005B9C36 /* RCTConvert_UIColorTests.m */; };
|
||||
D85B829E1AB6D5D7003F4FE2 /* libRCTVibration.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D85B829C1AB6D5CE003F4FE2 /* libRCTVibration.a */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
@@ -153,11 +161,15 @@
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
004D289E1AAF61C70097A701 /* UIExplorerUnitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = UIExplorerUnitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
1300627E1B59179B0043FE5A /* RCTGzipTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTGzipTests.m; sourceTree = "<group>"; };
|
||||
13417FE31AA91428003F314A /* RCTImage.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTImage.xcodeproj; path = ../../Libraries/Image/RCTImage.xcodeproj; sourceTree = "<group>"; };
|
||||
13417FEA1AA914B8003F314A /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = ../../Libraries/Text/RCTText.xcodeproj; sourceTree = "<group>"; };
|
||||
134180261AA91779003F314A /* RCTNetwork.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTNetwork.xcodeproj; path = ../../Libraries/Network/RCTNetwork.xcodeproj; sourceTree = "<group>"; };
|
||||
134454551AAFCAAE003F0779 /* RCTAdSupport.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTAdSupport.xcodeproj; path = ../../Libraries/AdSupport/RCTAdSupport.xcodeproj; sourceTree = "<group>"; };
|
||||
134A8A201AACED6A00945AAE /* RCTGeolocation.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTGeolocation.xcodeproj; path = ../../Libraries/Geolocation/RCTGeolocation.xcodeproj; sourceTree = "<group>"; };
|
||||
138D6A151B53CD440074A87E /* RCTCacheTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTCacheTests.m; sourceTree = "<group>"; };
|
||||
138D6A161B53CD440074A87E /* RCTShadowViewTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTShadowViewTests.m; sourceTree = "<group>"; };
|
||||
1393D0371B68CD1300E1B601 /* RCTModuleMethodTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTModuleMethodTests.m; sourceTree = "<group>"; };
|
||||
139FDECA1B0651EA00C62182 /* RCTWebSocket.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTWebSocket.xcodeproj; path = ../../Libraries/WebSocket/RCTWebSocket.xcodeproj; sourceTree = "<group>"; };
|
||||
13B07F961A680F5B00A75B9A /* UIExplorer.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = UIExplorer.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = UIExplorer/AppDelegate.h; sourceTree = "<group>"; };
|
||||
@@ -167,7 +179,9 @@
|
||||
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = UIExplorer/Info.plist; sourceTree = "<group>"; };
|
||||
13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = UIExplorer/main.m; sourceTree = "<group>"; };
|
||||
13CC9D481AEED2B90020D1C2 /* RCTSettings.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTSettings.xcodeproj; path = ../../Libraries/Settings/RCTSettings.xcodeproj; sourceTree = "<group>"; };
|
||||
141FC1201B222EBB004D5FFB /* IntegrationTestsTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IntegrationTestsTests.m; sourceTree = "<group>"; };
|
||||
13DB03471B5D2ED500C27245 /* RCTJSONTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTJSONTests.m; sourceTree = "<group>"; };
|
||||
13DF61B51B67A45000EDB188 /* RCTMethodArgumentTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTMethodArgumentTests.m; sourceTree = "<group>"; };
|
||||
141FC1201B222EBB004D5FFB /* IntegrationTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IntegrationTests.m; sourceTree = "<group>"; };
|
||||
143BC57E1B21E18100462512 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
143BC5811B21E18100462512 /* testLayoutExampleSnapshot_1@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "testLayoutExampleSnapshot_1@2x.png"; sourceTree = "<group>"; };
|
||||
143BC5821B21E18100462512 /* testSliderExampleSnapshot_1@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "testSliderExampleSnapshot_1@2x.png"; sourceTree = "<group>"; };
|
||||
@@ -177,8 +191,8 @@
|
||||
143BC5861B21E18100462512 /* testViewExampleSnapshot_1@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "testViewExampleSnapshot_1@2x.png"; sourceTree = "<group>"; };
|
||||
143BC5951B21E3E100462512 /* UIExplorerIntegrationTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = UIExplorerIntegrationTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
143BC5981B21E3E100462512 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
143BC5A01B21E45C00462512 /* UIExplorerIntegrationTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIExplorerIntegrationTests.m; sourceTree = "<group>"; };
|
||||
144D21231B2204C5006DB32B /* RCTClippingTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTClippingTests.m; sourceTree = "<group>"; };
|
||||
143BC5A01B21E45C00462512 /* UIExplorerSnapshotTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIExplorerSnapshotTests.m; sourceTree = "<group>"; };
|
||||
144D21231B2204C5006DB32B /* RCTImageUtilTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTImageUtilTests.m; sourceTree = "<group>"; };
|
||||
1497CFA41B21F5E400C1F8F2 /* RCTAllocationTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTAllocationTests.m; sourceTree = "<group>"; };
|
||||
1497CFA51B21F5E400C1F8F2 /* RCTBridgeTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTBridgeTests.m; sourceTree = "<group>"; };
|
||||
1497CFA61B21F5E400C1F8F2 /* RCTContextExecutorTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTContextExecutorTests.m; sourceTree = "<group>"; };
|
||||
@@ -202,6 +216,8 @@
|
||||
14E0EEC81AB118F7000DECC3 /* RCTActionSheet.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTActionSheet.xcodeproj; path = ../../Libraries/ActionSheetIOS/RCTActionSheet.xcodeproj; sourceTree = "<group>"; };
|
||||
357858F81B28D2C400341EDB /* RCTLinking.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTLinking.xcodeproj; path = ../../Libraries/LinkingIOS/RCTLinking.xcodeproj; sourceTree = "<group>"; };
|
||||
58005BE41ABA80530062E044 /* RCTTest.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTTest.xcodeproj; path = ../../Libraries/RCTTest/RCTTest.xcodeproj; sourceTree = "<group>"; };
|
||||
83636F8E1B53F22C009F943E /* RCTUIManagerScenarioTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTUIManagerScenarioTests.m; sourceTree = "<group>"; };
|
||||
83A936C71B7E0F08005B9C36 /* RCTConvert_UIColorTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTConvert_UIColorTests.m; sourceTree = "<group>"; };
|
||||
D85B82911AB6D5CE003F4FE2 /* RCTVibration.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTVibration.xcodeproj; path = ../../Libraries/Vibration/RCTVibration.xcodeproj; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
@@ -342,11 +358,18 @@
|
||||
children = (
|
||||
1497CFA41B21F5E400C1F8F2 /* RCTAllocationTests.m */,
|
||||
1497CFA51B21F5E400C1F8F2 /* RCTBridgeTests.m */,
|
||||
144D21231B2204C5006DB32B /* RCTClippingTests.m */,
|
||||
138D6A151B53CD440074A87E /* RCTCacheTests.m */,
|
||||
1497CFA61B21F5E400C1F8F2 /* RCTContextExecutorTests.m */,
|
||||
1497CFA71B21F5E400C1F8F2 /* RCTConvert_NSURLTests.m */,
|
||||
83A936C71B7E0F08005B9C36 /* RCTConvert_UIColorTests.m */,
|
||||
1497CFA81B21F5E400C1F8F2 /* RCTConvert_UIFontTests.m */,
|
||||
1497CFA91B21F5E400C1F8F2 /* RCTEventDispatcherTests.m */,
|
||||
1300627E1B59179B0043FE5A /* RCTGzipTests.m */,
|
||||
144D21231B2204C5006DB32B /* RCTImageUtilTests.m */,
|
||||
13DB03471B5D2ED500C27245 /* RCTJSONTests.m */,
|
||||
13DF61B51B67A45000EDB188 /* RCTMethodArgumentTests.m */,
|
||||
1393D0371B68CD1300E1B601 /* RCTModuleMethodTests.m */,
|
||||
138D6A161B53CD440074A87E /* RCTShadowViewTests.m */,
|
||||
1497CFAA1B21F5E400C1F8F2 /* RCTSparseArrayTests.m */,
|
||||
1497CFAB1B21F5E400C1F8F2 /* RCTUIManagerTests.m */,
|
||||
143BC57E1B21E18100462512 /* Info.plist */,
|
||||
@@ -381,8 +404,9 @@
|
||||
143BC5961B21E3E100462512 /* UIExplorerIntegrationTests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
141FC1201B222EBB004D5FFB /* IntegrationTestsTests.m */,
|
||||
143BC5A01B21E45C00462512 /* UIExplorerIntegrationTests.m */,
|
||||
141FC1201B222EBB004D5FFB /* IntegrationTests.m */,
|
||||
143BC5A01B21E45C00462512 /* UIExplorerSnapshotTests.m */,
|
||||
83636F8E1B53F22C009F943E /* RCTUIManagerScenarioTests.m */,
|
||||
143BC5971B21E3E100462512 /* Supporting Files */,
|
||||
);
|
||||
path = UIExplorerIntegrationTests;
|
||||
@@ -772,14 +796,21 @@
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
1497CFB01B21F5E400C1F8F2 /* RCTConvert_UIFontTests.m in Sources */,
|
||||
144D21241B2204C5006DB32B /* RCTClippingTests.m in Sources */,
|
||||
144D21241B2204C5006DB32B /* RCTImageUtilTests.m in Sources */,
|
||||
1393D0381B68CD1300E1B601 /* RCTModuleMethodTests.m in Sources */,
|
||||
1497CFB21B21F5E400C1F8F2 /* RCTSparseArrayTests.m in Sources */,
|
||||
1300627F1B59179B0043FE5A /* RCTGzipTests.m in Sources */,
|
||||
1497CFAF1B21F5E400C1F8F2 /* RCTConvert_NSURLTests.m in Sources */,
|
||||
1497CFAE1B21F5E400C1F8F2 /* RCTContextExecutorTests.m in Sources */,
|
||||
1497CFAD1B21F5E400C1F8F2 /* RCTBridgeTests.m in Sources */,
|
||||
1497CFB11B21F5E400C1F8F2 /* RCTEventDispatcherTests.m in Sources */,
|
||||
1497CFB31B21F5E400C1F8F2 /* RCTUIManagerTests.m in Sources */,
|
||||
138D6A171B53CD440074A87E /* RCTCacheTests.m in Sources */,
|
||||
13DB03481B5D2ED500C27245 /* RCTJSONTests.m in Sources */,
|
||||
1497CFAC1B21F5E400C1F8F2 /* RCTAllocationTests.m in Sources */,
|
||||
83A936C81B7E0F08005B9C36 /* RCTConvert_UIColorTests.m in Sources */,
|
||||
13DF61B61B67A45000EDB188 /* RCTMethodArgumentTests.m in Sources */,
|
||||
138D6A181B53CD440074A87E /* RCTShadowViewTests.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -796,8 +827,9 @@
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
141FC1211B222EBB004D5FFB /* IntegrationTestsTests.m in Sources */,
|
||||
143BC5A11B21E45C00462512 /* UIExplorerIntegrationTests.m in Sources */,
|
||||
141FC1211B222EBB004D5FFB /* IntegrationTests.m in Sources */,
|
||||
83636F8F1B53F22C009F943E /* RCTUIManagerScenarioTests.m in Sources */,
|
||||
143BC5A11B21E45C00462512 /* UIExplorerSnapshotTests.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -1014,9 +1046,11 @@
|
||||
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
|
||||
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES;
|
||||
GCC_WARN_MULTIPLE_DEFINITION_TYPES_FOR_SELECTOR = YES;
|
||||
GCC_WARN_SHADOW = YES;
|
||||
GCC_WARN_STRICT_SELECTOR_MATCH = YES;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
@@ -1028,6 +1062,7 @@
|
||||
"$(inherited)",
|
||||
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
||||
"$(SRCROOT)/../../React/**",
|
||||
"$(SRCROOT)/../../Libraries/**",
|
||||
);
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
@@ -1068,9 +1103,11 @@
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
|
||||
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES;
|
||||
GCC_WARN_MULTIPLE_DEFINITION_TYPES_FOR_SELECTOR = YES;
|
||||
GCC_WARN_SHADOW = YES;
|
||||
GCC_WARN_STRICT_SELECTOR_MATCH = YES;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
@@ -1082,6 +1119,7 @@
|
||||
"$(inherited)",
|
||||
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
||||
"$(SRCROOT)/../../React/**",
|
||||
"$(SRCROOT)/../../Libraries/**",
|
||||
);
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
|
||||
@@ -14,56 +14,77 @@
|
||||
|
||||
#import "AppDelegate.h"
|
||||
|
||||
#import "RCTBridge.h"
|
||||
#import "RCTJavaScriptLoader.h"
|
||||
#import "RCTRootView.h"
|
||||
|
||||
@interface AppDelegate() <RCTBridgeDelegate>
|
||||
|
||||
@end
|
||||
|
||||
@implementation AppDelegate
|
||||
|
||||
- (BOOL)application:(__unused UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
|
||||
{
|
||||
NSURL *jsCodeLocation;
|
||||
RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self
|
||||
launchOptions:launchOptions];
|
||||
|
||||
/**
|
||||
* Loading JavaScript code - uncomment the one you want.
|
||||
*
|
||||
* OPTION 1
|
||||
* Load from development server. Start the server from the repository root:
|
||||
*
|
||||
* $ npm start
|
||||
*
|
||||
* To run on device, change `localhost` to the IP address of your computer
|
||||
* (you can get this by typing `ifconfig` into the terminal and selecting the
|
||||
* `inet` value under `en0:`) and make sure your computer and iOS device are
|
||||
* on the same Wi-Fi network.
|
||||
*/
|
||||
|
||||
jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/Examples/UIExplorer/UIExplorerApp.ios.includeRequire.runModule.bundle?dev=true"];
|
||||
|
||||
/**
|
||||
* OPTION 2
|
||||
* Load from pre-bundled file on disk. To re-generate the static bundle, `cd`
|
||||
* to your Xcode project folder and run
|
||||
*
|
||||
* $ curl 'http://localhost:8081/Examples/UIExplorer/UIExplorerApp.includeRequire.runModule.bundle' -o main.jsbundle
|
||||
*
|
||||
* then add the `main.jsbundle` file to your project and uncomment this line:
|
||||
*/
|
||||
|
||||
// jsCodeLocation = [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
|
||||
|
||||
#if RUNNING_ON_CI
|
||||
jsCodeLocation = [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
|
||||
#endif
|
||||
|
||||
RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
|
||||
moduleName:@"UIExplorerApp"
|
||||
launchOptions:launchOptions];
|
||||
RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge
|
||||
moduleName:@"UIExplorerApp"
|
||||
initialProperties:nil];
|
||||
|
||||
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
|
||||
UIViewController *rootViewController = [[UIViewController alloc] init];
|
||||
UIViewController *rootViewController = [UIViewController new];
|
||||
rootViewController.view = rootView;
|
||||
self.window.rootViewController = rootViewController;
|
||||
[self.window makeKeyAndVisible];
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (NSURL *)sourceURLForBridge:(__unused RCTBridge *)bridge
|
||||
{
|
||||
NSURL *sourceURL;
|
||||
|
||||
/**
|
||||
* Loading JavaScript code - uncomment the one you want.
|
||||
*
|
||||
* OPTION 1
|
||||
* Load from development server. Start the server from the repository root:
|
||||
*
|
||||
* $ npm start
|
||||
*
|
||||
* To run on device, change `localhost` to the IP address of your computer
|
||||
* (you can get this by typing `ifconfig` into the terminal and selecting the
|
||||
* `inet` value under `en0:`) and make sure your computer and iOS device are
|
||||
* on the same Wi-Fi network.
|
||||
*/
|
||||
|
||||
sourceURL = [NSURL URLWithString:@"http://localhost:8081/Examples/UIExplorer/UIExplorerApp.ios.includeRequire.runModule.bundle?dev=true"];
|
||||
|
||||
/**
|
||||
* OPTION 2
|
||||
* Load from pre-bundled file on disk. To re-generate the static bundle, `cd`
|
||||
* to your Xcode project folder and run
|
||||
*
|
||||
* $ curl 'http://localhost:8081/Examples/UIExplorer/UIExplorerApp.ios.includeRequire.runModule.bundle' -o main.jsbundle
|
||||
*
|
||||
* then add the `main.jsbundle` file to your project and uncomment this line:
|
||||
*/
|
||||
|
||||
// sourceURL = [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
|
||||
|
||||
#if RUNNING_ON_CI
|
||||
sourceURL = [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
|
||||
#endif
|
||||
|
||||
return sourceURL;
|
||||
}
|
||||
|
||||
- (void)loadSourceForBridge:(RCTBridge *)bridge
|
||||
withBlock:(RCTSourceLoadBlock)loadCallback
|
||||
{
|
||||
[RCTJavaScriptLoader loadBundleAtURL:[self sourceURLForBridge:bridge]
|
||||
onComplete:loadCallback];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x",
|
||||
"filename" : "uie_thumb_big.png"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 6.6 KiB |
@@ -17,33 +17,43 @@
|
||||
'use strict';
|
||||
|
||||
var React = require('react-native');
|
||||
var Dimensions = require('Dimensions');
|
||||
var DrawerLayoutAndroid = require('DrawerLayoutAndroid');
|
||||
var ToolbarAndroid = require('ToolbarAndroid');
|
||||
var UIExplorerList = require('./UIExplorerList');
|
||||
var {
|
||||
AppRegistry,
|
||||
BackAndroid,
|
||||
Dimensions,
|
||||
DrawerLayoutAndroid,
|
||||
StyleSheet,
|
||||
ToolbarAndroid,
|
||||
View,
|
||||
} = React;
|
||||
var UIExplorerList = require('./UIExplorerList.android');
|
||||
|
||||
var DRAWER_WIDTH_LEFT = 56;
|
||||
|
||||
var UIExplorerApp = React.createClass({
|
||||
|
||||
getInitialState: function() {
|
||||
return {
|
||||
example: {
|
||||
title: 'UIExplorer',
|
||||
component: this._renderHome(),
|
||||
},
|
||||
example: this._getUIExplorerHome(),
|
||||
};
|
||||
},
|
||||
|
||||
_getUIExplorerHome: function() {
|
||||
return {
|
||||
title: 'UIExplorer',
|
||||
component: this._renderHome(),
|
||||
};
|
||||
},
|
||||
|
||||
componentWillMount: function() {
|
||||
BackAndroid.addEventListener('hardwareBackPress', this._handleBackButtonPress);
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return (
|
||||
<DrawerLayoutAndroid
|
||||
drawerPosition={DrawerLayoutAndroid.positions.Left}
|
||||
drawerWidth={Dimensions.get('window').width - DRAWER_WIDTH_LEFT}
|
||||
keyboardDismissMode="on-drag"
|
||||
ref={(drawer) => { this.drawer = drawer; }}
|
||||
renderNavigationView={this._renderNavigationView}>
|
||||
{this._renderNavigation()}
|
||||
@@ -62,14 +72,11 @@ var UIExplorerApp = React.createClass({
|
||||
|
||||
onSelectExample: function(example) {
|
||||
this.drawer.closeDrawer();
|
||||
if (example.title === 'UIExplorer') {
|
||||
example.component = this._renderHome();
|
||||
if (example.title === this._getUIExplorerHome().title) {
|
||||
example = this._getUIExplorerHome();
|
||||
}
|
||||
this.setState({
|
||||
example: {
|
||||
title: example.title,
|
||||
component: example.component,
|
||||
},
|
||||
example: example,
|
||||
});
|
||||
},
|
||||
|
||||
@@ -103,16 +110,16 @@ var UIExplorerApp = React.createClass({
|
||||
);
|
||||
},
|
||||
|
||||
_handleBackButtonPress: function() {
|
||||
if (this.state.example.title !== this._getUIExplorerHome().title) {
|
||||
this.onSelectExample(this._getUIExplorerHome());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
});
|
||||
|
||||
var styles = StyleSheet.create({
|
||||
messageText: {
|
||||
fontSize: 17,
|
||||
fontWeight: '500',
|
||||
padding: 15,
|
||||
marginTop: 50,
|
||||
marginLeft: 15,
|
||||
},
|
||||
container: {
|
||||
flex: 1,
|
||||
},
|
||||
@@ -122,4 +129,6 @@ var styles = StyleSheet.create({
|
||||
},
|
||||
});
|
||||
|
||||
AppRegistry.registerComponent('UIExplorerApp', () => UIExplorerApp);
|
||||
|
||||
module.exports = UIExplorerApp;
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
'use strict';
|
||||
|
||||
var React = require('react-native');
|
||||
var UIExplorerList = require('./UIExplorerList');
|
||||
var UIExplorerList = require('./UIExplorerList.ios');
|
||||
var {
|
||||
AppRegistry,
|
||||
NavigatorIOS,
|
||||
@@ -43,22 +43,23 @@ var UIExplorerApp = React.createClass({
|
||||
/>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<NavigatorIOS
|
||||
style={styles.container}
|
||||
initialRoute={{
|
||||
title: 'UIExplorer',
|
||||
component: UIExplorerList,
|
||||
passProps: {
|
||||
onExternalExampleRequested: (example) => {
|
||||
this.setState({ openExternalExample: example, });
|
||||
},
|
||||
}
|
||||
}}
|
||||
itemWrapperStyle={styles.itemWrapper}
|
||||
tintColor="#008888"
|
||||
/>
|
||||
);
|
||||
|
||||
return (
|
||||
<NavigatorIOS
|
||||
style={styles.container}
|
||||
initialRoute={{
|
||||
title: 'UIExplorer',
|
||||
component: UIExplorerList,
|
||||
passProps: {
|
||||
onExternalExampleRequested: (example) => {
|
||||
this.setState({ openExternalExample: example, });
|
||||
},
|
||||
}
|
||||
}}
|
||||
itemWrapperStyle={styles.itemWrapper}
|
||||
tintColor="#008888"
|
||||
/>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -14,11 +14,11 @@
|
||||
|
||||
#import "RCTAssert.h"
|
||||
|
||||
@interface IntegrationTestsTests : XCTestCase
|
||||
@interface IntegrationTests : XCTestCase
|
||||
|
||||
@end
|
||||
|
||||
@implementation IntegrationTestsTests
|
||||
@implementation IntegrationTests
|
||||
{
|
||||
RCTTestRunner *_runner;
|
||||
}
|
||||
@@ -26,12 +26,12 @@
|
||||
- (void)setUp
|
||||
{
|
||||
#if __LP64__
|
||||
RCTAssert(false, @"Tests should be run on 32-bit device simulators (e.g. iPhone 5)");
|
||||
RCTAssert(NO, @"Tests should be run on 32-bit device simulators (e.g. iPhone 5)");
|
||||
#endif
|
||||
|
||||
NSOperatingSystemVersion version = [[NSProcessInfo processInfo] operatingSystemVersion];
|
||||
RCTAssert(version.majorVersion == 8 || version.minorVersion == 3, @"Tests should be run on iOS 8.3, found %zd.%zd.%zd", version.majorVersion, version.minorVersion, version.patchVersion);
|
||||
_runner = RCTInitRunnerForApp(@"Examples/UIExplorer/UIExplorerIntegrationTests/js/IntegrationTestsApp");
|
||||
NSOperatingSystemVersion version = [NSProcessInfo processInfo].operatingSystemVersion;
|
||||
RCTAssert(version.majorVersion == 8 || version.minorVersion >= 3, @"Tests should be run on iOS 8.3+, found %zd.%zd.%zd", version.majorVersion, version.minorVersion, version.patchVersion);
|
||||
_runner = RCTInitRunnerForApp(@"Examples/UIExplorer/UIExplorerIntegrationTests/js/IntegrationTestsApp", nil);
|
||||
}
|
||||
|
||||
#pragma mark Logic Tests
|
||||