├── .gitignore
├── CNAME
├── README.md
├── favicon.png
├── fonts
├── DroidSerif-Bold.ttf
├── DroidSerif-BoldItalic.ttf
├── DroidSerif-Italic.ttf
├── DroidSerif.ttf
├── Montserrat-Bold.ttf
└── Montserrat-Regular.ttf
├── ie.js
├── img
├── autumn.jpg
├── chevron-right.png
├── close-icon.svg
├── github.svg
├── icon-arrow-white.svg
├── icon-arrow.svg
├── icon.medium.svg
├── icon.twitter.svg
├── img.frank.png
├── img.frank@2x.png
├── ir_logo.png
├── ir_logo.svg
├── ir_logo@2x.png
├── jonmajor.png
├── logo-square.png
├── logo.png
├── logo@2x.png
├── long-arrow-right.svg
├── menu-icon.svg
├── newsletter-illustration.svg
├── purple-cloud.png
├── purple-cloud@2x.png
├── sponsor-demo.png
└── voting.png
├── index.html
├── issues.html
├── issues
├── 2015
│ ├── 01-05-2015.html
│ ├── 01-12-2015.html
│ ├── 02-08-2015.html
│ ├── 05-10-2015.html
│ ├── 06-07-2015.html
│ ├── 07-06-2015.html
│ ├── 07-09-2015.html
│ ├── 08-05-2015.html
│ ├── 10-08-2015.html
│ ├── 13-06-2015.html
│ ├── 13-10-2015.html
│ ├── 13-12-2015.html
│ ├── 14-07-2015.html
│ ├── 15-05-2015.html
│ ├── 16-08-2015.html
│ ├── 18-09-2015.html
│ ├── 19-10-2015.html
│ ├── 22-05-2015.html
│ ├── 22-06-2015.html
│ ├── 22-11-2015.html
│ ├── 23-04-2015.html
│ ├── 26-07-2015.html
│ ├── 27-09-2015.html
│ ├── 27-10-2015.html
│ ├── 28-06-2015.html
│ ├── 30-08-2015.html
│ └── 31-05-2015.html
├── 2016
│ ├── 01-07-2016.html
│ ├── 02-12-2016.html
│ ├── 07-08-2016.html
│ ├── 10-01-2016.html
│ ├── 14-02-2016.html
│ ├── 18-11-2016.html
│ ├── 19-10-2016.html
│ ├── 20-12-2016.html
│ ├── 21-03-2016.html
│ ├── 21-04-2016.html
│ └── 22-01-2016.html
├── 2017
│ ├── 05-12-2017.html
│ ├── 06-04-2017.html
│ ├── 06-10-2017.html
│ ├── 07-09-2017.html
│ ├── 08-01-2017.html
│ ├── 14-02-2017.html
│ ├── 17-05-2017.html
│ ├── 18-08-2017.html
│ ├── 20-03-2017.html
│ ├── 27-02-2017.html
│ ├── 28-06-2017.html
│ ├── 29-04-2017.html
│ ├── 30-01-2017.html
│ ├── 31-05-2017.html
│ ├── 31-07-2017.html
│ └── 31-10-2017.html
├── 2018
│ ├── 02-09-2018.html
│ ├── 03-21-2018.html
│ ├── 04-03-2018.html
│ ├── 04-18-2018.html
│ ├── 05-01-2018.html
│ ├── 05-15-2018.html
│ ├── 05-29-2018.html
│ ├── 06-12-2018.html
│ ├── 06-26-2018.html
│ ├── 07-17-2018.html
│ ├── 07-31-2018.html
│ ├── 08-21-2018.html
│ ├── 09-04-2018.html
│ ├── 09-18-2018.html
│ ├── 10-02-2018.html
│ ├── 10-16-2018.html
│ ├── 11-06-2018.html
│ ├── 11-20-2018.html
│ ├── 12-04-2018.html
│ └── 12-18-2018.html
├── 2019
│ ├── 01-01-2019.html
│ ├── 01-15-2019.html
│ ├── 02-05-2019.html
│ ├── 02-19-2019.html
│ ├── 03-05-2019.html
│ ├── 03-19-2019.html
│ ├── 04-02-2019.html
│ ├── 04-16-2019.html
│ ├── 05-07-2019.html
│ ├── 05-21-2019.html
│ ├── 06-04-2019.html
│ ├── 06-18-2019.html
│ ├── 07-02-2019.html
│ ├── 07-16-2019.html
│ ├── 08-06-2019.html
│ ├── 08-20-2019.html
│ ├── 09-03-2019.html
│ ├── 09-17-2019.html
│ ├── 10-01-2019.html
│ ├── 10-15-2019.html
│ ├── 11-05-2019.html
│ ├── 11-19-2019.html
│ ├── 12-03-2019.html
│ └── 12-17-2019.html
├── 2020
│ ├── 01-07-2020.html
│ ├── 01-21-2020.html
│ ├── 02-04-2020.html
│ ├── 02-18-2020.html
│ ├── 03-03-2020.html
│ ├── 03-17-2020.html
│ ├── 04-07-2020.html
│ ├── 04-21-2020.html
│ ├── 05-05-2020.html
│ ├── 05-19-2020.html
│ ├── 06-02-2020.html
│ ├── 06-16-2020.html
│ ├── 07-07-2020.html
│ ├── 07-21-2020.html
│ ├── 08-04-2020.html
│ ├── 08-18-2020.html
│ ├── 09-01-2020.html
│ ├── 09-15-2020.html
│ ├── 10-06-2020.html
│ ├── 10-20-2020.html
│ ├── 11-03-2020.html
│ ├── 11-17-2020.html
│ ├── 12-01-2020.html
│ └── 12-15-2020.html
├── 2021
│ ├── 01-05-2021.html
│ ├── 01-19-2021.html
│ ├── 02-02-2021.html
│ ├── 02-16-2021.html
│ ├── 04-06-2021.html
│ ├── 04-20-2021.html
│ ├── 05-04-2021.html
│ ├── 05-18-2021.html
│ ├── 06-01-2021.html
│ ├── 06-15-2021.html
│ ├── 07-06-2021.html
│ ├── 07-20-2021.html
│ ├── 08-04-2021.html
│ ├── 08-17-2021.html
│ ├── 09-07-2021.html
│ ├── 09-21-2021.html
│ ├── 10-05-2021.html
│ ├── 10-19-2021.html
│ ├── 11-02-2021.html
│ ├── 11-16-2021.html
│ ├── 12-07-2021.html
│ └── 12-28-2021.html
├── 2022
│ ├── 01-18-2022.html
│ ├── 02-01-2022.html
│ ├── 02-15-2022.html
│ └── 03-01-2022.html
└── newsletter.js
├── newsletter.css
├── newsletter.js
├── normalize.css
├── package.json
├── sponsor-package.pdf
├── sponsor.css
├── sponsor.html
├── sponsorPage.js
├── src
└── sponsorPage.js
├── static.json
├── suggest-article.html
└── yarn.lock
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 |
--------------------------------------------------------------------------------
/CNAME:
--------------------------------------------------------------------------------
1 | reactnative.cc
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # react-native-newsletter
2 |
3 | Free summary of React Native news, articles, libraries, apps, and
4 | more, published twice a month (or very nearly) ... curated by Jon Major Condon
5 | ([@jonmajorc](https://twitter.com/jonmajorc)).
6 |
7 | This repo is no longer actively maintained, but the newsletter itself is going strong!
8 |
9 | ## [Sign up here!](https://reactnativenewsletter.com/)
10 |
11 | ## [Past Issues](https://reactnativenewsletter.com/past-issues)
12 |
--------------------------------------------------------------------------------
/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ReactNativeNews/react-native-newsletter/93016f62af32d97cc009f991d4f7c3c7155a4f26/favicon.png
--------------------------------------------------------------------------------
/fonts/DroidSerif-Bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ReactNativeNews/react-native-newsletter/93016f62af32d97cc009f991d4f7c3c7155a4f26/fonts/DroidSerif-Bold.ttf
--------------------------------------------------------------------------------
/fonts/DroidSerif-BoldItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ReactNativeNews/react-native-newsletter/93016f62af32d97cc009f991d4f7c3c7155a4f26/fonts/DroidSerif-BoldItalic.ttf
--------------------------------------------------------------------------------
/fonts/DroidSerif-Italic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ReactNativeNews/react-native-newsletter/93016f62af32d97cc009f991d4f7c3c7155a4f26/fonts/DroidSerif-Italic.ttf
--------------------------------------------------------------------------------
/fonts/DroidSerif.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ReactNativeNews/react-native-newsletter/93016f62af32d97cc009f991d4f7c3c7155a4f26/fonts/DroidSerif.ttf
--------------------------------------------------------------------------------
/fonts/Montserrat-Bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ReactNativeNews/react-native-newsletter/93016f62af32d97cc009f991d4f7c3c7155a4f26/fonts/Montserrat-Bold.ttf
--------------------------------------------------------------------------------
/fonts/Montserrat-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ReactNativeNews/react-native-newsletter/93016f62af32d97cc009f991d4f7c3c7155a4f26/fonts/Montserrat-Regular.ttf
--------------------------------------------------------------------------------
/ie.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | // Patch IE's javascript support
3 | // https://stackoverflow.com/questions/2790001/fixing-javascript-array-functions-in-internet-explorer-indexof-foreach-etc
4 |
5 | // Add ECMA262-5 method binding if not supported natively
6 | //
7 | if (!('bind' in Function.prototype)) {
8 | Function.prototype.bind = function (owner) {
9 | var that = this;
10 | if (arguments.length <= 1) {
11 | return function () {
12 | return that.apply(owner, arguments);
13 | };
14 | } else {
15 | var args = Array.prototype.slice.call(arguments, 1);
16 | return function () {
17 | return that.apply(owner, arguments.length === 0 ? args : args.concat(Array.prototype.slice.call(arguments)));
18 | };
19 | }
20 | };
21 | }
22 |
23 | // Add ECMA262-5 string trim if not supported natively
24 | //
25 | if (!('trim' in String.prototype)) {
26 | String.prototype.trim = function () {
27 | return this.replace(/^\s+/, '').replace(/\s+$/, '');
28 | };
29 | }
30 |
31 | // Add ECMA262-5 Array methods if not supported natively
32 | //
33 | if (!('indexOf' in Array.prototype)) {
34 | Array.prototype.indexOf = function (find, i /*opt*/) {
35 | if (i === undefined) i = 0;
36 | if (i < 0) i += this.length;
37 | if (i < 0) i = 0;
38 | for (var n = this.length; i < n; i++)
39 | if (i in this && this[i] === find)
40 | return i;
41 | return -1;
42 | };
43 | }
44 | if (!('lastIndexOf' in Array.prototype)) {
45 | Array.prototype.lastIndexOf = function (find, i /*opt*/) {
46 | if (i === undefined) i = this.length - 1;
47 | if (i < 0) i += this.length;
48 | if (i > this.length - 1) i = this.length - 1;
49 | for (i++; i-- > 0;) /* i++ because from-argument is sadly inclusive */
50 | if (i in this && this[i] === find)
51 | return i;
52 | return -1;
53 | };
54 | }
55 | if (!('forEach' in Array.prototype)) {
56 | Array.prototype.forEach = function (action, that /*opt*/) {
57 | for (var i = 0, n = this.length; i < n; i++)
58 | if (i in this)
59 | action.call(that, this[i], i, this);
60 | };
61 | }
62 | if (!('forEach' in NodeList.prototype)) {
63 | NodeList.prototype.forEach = function (action, that /*opt*/) {
64 | for (var i = 0, n = this.length; i < n; i++)
65 | if (i in this)
66 | action.call(that, this[i], i, this);
67 | };
68 | }
69 | if (!('map' in Array.prototype)) {
70 | Array.prototype.map = function (mapper, that /*opt*/) {
71 | var other = new Array(this.length);
72 | for (var i = 0, n = this.length; i < n; i++)
73 | if (i in this)
74 | other[i] = mapper.call(that, this[i], i, this);
75 | return other;
76 | };
77 | }
78 | if (!('filter' in Array.prototype)) {
79 | Array.prototype.filter = function (filter, that /*opt*/) {
80 | var other = [], v;
81 | for (var i = 0, n = this.length; i < n; i++)
82 | if (i in this && filter.call(that, v = this[i], i, this))
83 | other.push(v);
84 | return other;
85 | };
86 | }
87 | if (!('every' in Array.prototype)) {
88 | Array.prototype.every = function (tester, that /*opt*/) {
89 | for (var i = 0, n = this.length; i < n; i++)
90 | if (i in this && !tester.call(that, this[i], i, this))
91 | return false;
92 | return true;
93 | };
94 | }
95 | if (!('some' in Array.prototype)) {
96 | Array.prototype.some = function (tester, that /*opt*/) {
97 | for (var i = 0, n = this.length; i < n; i++)
98 | if (i in this && tester.call(that, this[i], i, this))
99 | return true;
100 | return false;
101 | };
102 | }
--------------------------------------------------------------------------------
/img/autumn.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ReactNativeNews/react-native-newsletter/93016f62af32d97cc009f991d4f7c3c7155a4f26/img/autumn.jpg
--------------------------------------------------------------------------------
/img/chevron-right.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ReactNativeNews/react-native-newsletter/93016f62af32d97cc009f991d4f7c3c7155a4f26/img/chevron-right.png
--------------------------------------------------------------------------------
/img/close-icon.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | times
5 | Created with Sketch.
6 |
7 |
10 |
--------------------------------------------------------------------------------
/img/github.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/img/icon-arrow-white.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 | icon-arrow
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/img/icon-arrow.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 | icon-arrow
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/img/icon.medium.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/img/icon.twitter.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/img/img.frank.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ReactNativeNews/react-native-newsletter/93016f62af32d97cc009f991d4f7c3c7155a4f26/img/img.frank.png
--------------------------------------------------------------------------------
/img/img.frank@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ReactNativeNews/react-native-newsletter/93016f62af32d97cc009f991d4f7c3c7155a4f26/img/img.frank@2x.png
--------------------------------------------------------------------------------
/img/ir_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ReactNativeNews/react-native-newsletter/93016f62af32d97cc009f991d4f7c3c7155a4f26/img/ir_logo.png
--------------------------------------------------------------------------------
/img/ir_logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 | Infinite Red Logo Light
4 | Created with Sketch.
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/img/ir_logo@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ReactNativeNews/react-native-newsletter/93016f62af32d97cc009f991d4f7c3c7155a4f26/img/ir_logo@2x.png
--------------------------------------------------------------------------------
/img/jonmajor.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ReactNativeNews/react-native-newsletter/93016f62af32d97cc009f991d4f7c3c7155a4f26/img/jonmajor.png
--------------------------------------------------------------------------------
/img/logo-square.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ReactNativeNews/react-native-newsletter/93016f62af32d97cc009f991d4f7c3c7155a4f26/img/logo-square.png
--------------------------------------------------------------------------------
/img/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ReactNativeNews/react-native-newsletter/93016f62af32d97cc009f991d4f7c3c7155a4f26/img/logo.png
--------------------------------------------------------------------------------
/img/logo@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ReactNativeNews/react-native-newsletter/93016f62af32d97cc009f991d4f7c3c7155a4f26/img/logo@2x.png
--------------------------------------------------------------------------------
/img/long-arrow-right.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/img/menu-icon.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | menu-icon
5 | Created with Sketch.
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/img/newsletter-illustration.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/img/purple-cloud.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ReactNativeNews/react-native-newsletter/93016f62af32d97cc009f991d4f7c3c7155a4f26/img/purple-cloud.png
--------------------------------------------------------------------------------
/img/purple-cloud@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ReactNativeNews/react-native-newsletter/93016f62af32d97cc009f991d4f7c3c7155a4f26/img/purple-cloud@2x.png
--------------------------------------------------------------------------------
/img/sponsor-demo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ReactNativeNews/react-native-newsletter/93016f62af32d97cc009f991d4f7c3c7155a4f26/img/sponsor-demo.png
--------------------------------------------------------------------------------
/img/voting.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ReactNativeNews/react-native-newsletter/93016f62af32d97cc009f991d4f7c3c7155a4f26/img/voting.png
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
9 |
18 |
19 |
20 |
21 |
25 |
26 | React Native Newsletter
27 |
28 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
We have a new website!
46 |
47 | The React Native Newsletter has a new home on the web! Head on over to
48 | our new website
49 | for new issues, article suggestions, and more.
50 |
51 |
52 |
53 | Visit the new site
54 |
55 |
56 |
57 |
58 |
76 |
77 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
121 |
122 |
123 |
124 | A curated, fun to read newsletter all about React Native
125 |
126 |
127 | Free bi-weekly summary of React Native news, articles, libraries,
128 | apps, and more!
129 |
130 |
131 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
Jon Major Condon, Editor-in-Chief
166 |
Jon Major specializes in React Native at Infinite Red.
167 |
175 |
176 |
177 |
178 |
184 |
185 |
186 |
187 |
188 |
189 |
--------------------------------------------------------------------------------
/issues.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
9 |
18 |
19 |
20 |
21 |
25 |
26 | React Native Newsletter
27 |
28 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
We have a new website!
45 |
46 | The React Native Newsletter has a new home on the web! Head on over to
47 | our new website
48 | for past issues, sponsorship opportunities, and more.
49 |
50 |
51 |
52 | Visit the new site
53 |
54 |
55 |
56 |
57 |
78 |
79 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
123 |
124 |
125 |
126 |
945 |
946 |
947 |
948 |
949 |
950 |
951 |
952 |
953 |
Jon Major Condon, Editor-in-Chief
954 |
Jon Major is a Senior Software Engineer at Infinite Red.
955 |
963 |
964 |
965 |
966 |
972 |
973 |
974 |
975 |
976 |
977 |
--------------------------------------------------------------------------------
/issues/2015/14-07-2015.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | React Native Newsletter
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 | Special San Francisco edition! Well special for me anyways because I live in Vancouver, Canada, but I am in San Francisco helping out some A1 folks (I learned the term "A1" yesterday and had to UrbanDictionary it) on a React Native project. Also special because it's coming out a Tuesday, wow! A late edition! And shorter than usual! Fancy.
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 | Top News
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
130 |
131 |
132 |
133 |
134 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 | Docs for "Animated" are up
148 |
149 | I know I'm really milking this one, but I can't emphasize enough how fantastic I think this library is. Click through to read the docs!
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
182 |
183 |
184 |
185 |
186 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 | All ReactEurope presentations up on YouTube
200 |
201 | Watch, learn, be happy. A big :clap: for all of the presenters, thank you for sharing your knowledge with us!
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 | Highlights from Issues and Pull Requests
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 | Add Image progress examples to UIExplorer
243 |
244 | @unknownexception spent a good amount of time pushing his Image loading progress events that were included in the 0.8.0-rc release, and followed that up promptly with some examples for UIExplorer to ensure that people know how to use it.
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
259 |
260 |
261 |
262 |
263 |
264 |
265 |
266 |
267 | Expose rotate x, y, z transforms by @chirag04
268 |
269 | This pull request is one in a series that adds support for 3d transforms to style. Very cool stuff when used in conjunction with the Animated api especially. Thanks @chirag04!
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 |
279 |
280 |
281 |
282 |
283 |
284 |
285 |
286 |
287 |
288 |
289 |
290 |
291 |
292 | App Extension support by @yusefnapora
293 |
294 | This adds workarounds for the code that was preventing React from compiling when linked against an iOS App Extension target. Some iOS APIs are unavailable to App Extensions, and Xcode's static analysis will catch attempts to use methods that have been flagged as unavailable.
295 |
296 | Learn more about app extensions.
297 |
298 |
299 |
300 |
301 |
302 |
303 |
304 |
305 |
306 |
307 |
308 |
309 |
310 |
311 |
312 |
313 |
314 |
315 |
316 |
317 |
318 | Highlights from the community
319 |
320 |
321 |
322 |
323 |
324 |
325 |
326 |
327 |
328 |
329 |
330 |
331 |
332 |
333 |
334 |
335 |
336 |
337 |
338 | react-router has a React Native branch
339 |
340 | @tylermcginnis33 there's a branch, soon as 1.0 ships we'll make it happen, it kinda works right now iirc
341 |
342 | Currently, this branch aims to incorporate navigation history. It will be interesting to see how it integrates with Navigator
- which works great but could be even more powerful if it were declarative.
343 |
344 | Check out the branch.
345 |
346 |
347 |
348 |
349 |
350 |
351 |
352 |
353 |
354 |
359 |
360 |
361 |
362 |
363 |
364 |
365 |
366 |
367 | Exploring Dynamic Layout in Sketch
368 |
369 | An interesting experiment that uses React Native's css-layout library to prototype interfaces in Sketch. Seems like a good middle ground between developers and designers, and a good way to get more familiar with React Native's subset of supported CSS declarations.
370 |
371 |
372 |
373 |
374 |
375 |
376 |
377 |
378 |
379 |
380 |
381 |
382 |
383 |
384 |
385 |
386 |
387 |
388 |
389 |
390 |
391 |
392 | syrusakbary/react-native-refresher
393 |
394 | If the demo gifs are any indication, this looks to be the best pull-to-refresh library out there at the moment. Animations look smooth and it has a clean API, so check it out!
395 |
396 |
397 |
398 |
399 |
400 |
401 |
402 |
403 |
404 |
409 |
410 |
411 |
412 |
413 |
414 |
415 |
416 |
417 | johanneslumpe/react-native-gesture-recognizers
418 |
419 | Library built on last week's blog post about gesture recognition in React Native - it's implemented using ES7 decorators, which are basically like macros that wrap a component in some other component to layer on functionality. Think onions. But components. Component-onions. Maybe that's why the syntax is @decoratorName. @ is pretty onion-like.
420 |
421 | So yeah, onions aside, check it out if you need custom gesture recognition like pinch, or are interested to see how a decorator-based API can work in React Native. Also johanneslumpe is just a cool human being, so respect.
422 |
423 |
424 |
425 |
426 |
427 |
428 |
429 |
430 |
431 |
432 |
433 |
434 |
435 |
436 |
437 |
438 |
439 |
440 |
441 |
442 |
443 |
444 | exponentjs/react-native-scrollable-decorator
445 |
446 | Speaking of onions/decorators, check this other decorator library from the fine exponent duo of @ide and @ccheever. With a @scrollable dusted on top of your component declaration, your component is given the same external api (eg: scrollTo) as a ScrollView.
447 |
448 |
449 |
450 |
451 |
452 |
453 |
454 |
455 |
456 |
461 |
462 |
463 |
464 |
465 |
466 |
467 |
468 |
469 | nulrich/RCTAutoComplete
470 |
471 | The only thing better than completing something is autocompleting something. PSA: try to stay away from using RCT
for your module prefixes. I get it, I'm a hypocrite because in react-native-video I use RCTVideo
. Or am I? Kind of but not so much because this was actually
472 |
473 |
474 |
475 |
476 |
477 |
478 |
479 |
480 |
481 |
482 |
483 |
484 |
485 |
486 |
487 |
488 |
489 |
490 |
491 |
492 |
493 |
494 |
495 |
496 | That's
500 | it for now! Ping me on Twitter @notbrent
501 | if you have anything that you would like
502 | me to share next week.
503 |
504 |
505 | If you're reading
506 | this on the web, you can subscribe to
507 | get this delivered weekly to your email here!
509 |
510 |
511 |
512 |
513 |
514 |
515 |
516 |
517 |
518 |
519 |
520 |
521 |
522 |
523 |
524 |
525 |
526 |
527 |
528 |
529 |
530 |
531 |
532 |
533 |
534 |
535 | Collect and curate content easily for brilliant newsletters. Try Goodbits for free!
536 |
537 |
538 |
539 |
540 |
541 |
542 |
543 |
544 |
545 |
546 |
547 |
548 |
549 |
550 |
551 |
552 |
607 |
608 |
609 |
610 |
611 |
612 |
613 |
614 |
--------------------------------------------------------------------------------
/issues/newsletter.js:
--------------------------------------------------------------------------------
1 | $(function() {
2 | $('a').attr('target', '_blank');
3 | var $headerImage = $('[alt="Logo for React Native Newsletter"]');
4 | $headerImage.click(function() {
5 | window.location.href = 'http://reactnative.cc';
6 | });
7 |
8 | $headerImage.css('cursor', 'pointer');
9 | });
10 |
--------------------------------------------------------------------------------
/newsletter.css:
--------------------------------------------------------------------------------
1 | /**
2 | * Fonts
3 | */
4 | @font-face {
5 | font-family: 'Droid Serif';
6 | src: url('/fonts/DroidSerif.ttf');
7 | font-style: normal;
8 | }
9 |
10 | @font-face {
11 | font-family: 'Droid Serif';
12 | src: url('/fonts/DroidSerif-Italic.ttf');
13 | font-style: italic;
14 | }
15 |
16 | @font-face {
17 | font-family: 'Montserrat';
18 | src: url('/fonts/Montserrat-Regular.ttf');
19 | }
20 |
21 | /**
22 | * Typography
23 | */
24 |
25 | /**
26 | * Icons
27 | */
28 |
29 | .icon {
30 | display: inline-block;
31 | width: 18px;
32 | height: 16px;
33 | background-repeat: no-repeat;
34 | }
35 |
36 | .icon.twitter {
37 | background-image: url(/img/icon.twitter.svg);
38 | }
39 |
40 | .icon.medium {
41 | background-image: url(/img/icon.medium.svg);
42 | }
43 |
44 | .icon.github {
45 | background-image: url(/img/github.svg);
46 | }
47 |
48 | .icon.arrow-right {
49 | background-image: url(/img/icon-arrow.svg);
50 | margin-top: 2px
51 | }
52 |
53 | /**
54 | * Forms
55 | */
56 |
57 | input {
58 | -webkit-appearance: none;
59 | color: #8f7e94;
60 | font-size: 15px;
61 | text-align: left;
62 | width: 393px;
63 | outline: none;
64 | background-color: white;
65 | border-radius: 32.5px;
66 | width: 300px;
67 | padding: 19px 30px 19px 30px;
68 | border: 2px solid #fff;
69 | display: block;
70 | margin-top: 23px;
71 | }
72 |
73 | .input-field {
74 | display: flex;
75 | flex-flow: row wrap;
76 | }
77 |
78 | .captcha-field {
79 | display: flex;
80 | align-self: center;
81 | padding-top: 100px;
82 | padding-left: 5px;
83 | }
84 |
85 | .input-field span {
86 | display: none;
87 | font-size: 13px;
88 | font-family: 'Droid Serif', serif;
89 | font-style: italic;
90 | line-height: 35px;
91 | text-align: left;
92 | }
93 |
94 | .input-field .addon {
95 | width: 50px;
96 | height: 61px;
97 | border-top-right-radius: 32.5px;
98 | border-bottom-right-radius: 32.5px;
99 | background-color: #fff;
100 | background-image: url(/img/long-arrow-right.svg);
101 | background-repeat: no-repeat;
102 | background-position: right 20px center;
103 | border-top: 2px solid #fff;
104 | border-right: 2px solid #fff;
105 | border-bottom: 2px solid #fff;
106 | border-left: none;
107 | outline: none;
108 | }
109 |
110 | .input-field .addon:hover {
111 | cursor: pointer;
112 | }
113 |
114 | .input-field.error .addon {
115 | border-color: #e73536;
116 | }
117 |
118 | .input-field.error input {
119 | border-color: #e73536;
120 | }
121 |
122 | .input-field.error span {
123 | display: block;
124 | color: #e73536;
125 | margin-left: 30px;
126 | width: 100%;
127 | }
128 |
129 | .email-input {
130 | margin-top: 71px;
131 | }
132 |
133 | .email-input input {
134 | margin-top: 0;
135 | border-right: none;
136 | border-top-right-radius: 0%;
137 | border-bottom-right-radius: 0%;
138 | width: 280px;
139 | }
140 |
141 | /**
142 | * Styles
143 | */
144 |
145 | html,
146 | body {
147 | background: linear-gradient(
148 | 143.43deg,
149 | #1f0232 0%,
150 | rgba(100, 11, 86, 0.99) 100%
151 | );
152 | min-height: 100%;
153 | min-width: 100%;
154 | height: auto;
155 | }
156 |
157 | body {
158 | font-family: 'Montserrat', sans-serif;
159 | color: #fff;
160 | }
161 |
162 | h1 {
163 | font-size: 46px;
164 | font-weight: bold;
165 | line-height: 56px;
166 | margin-bottom: 23px;
167 | letter-spacing: 1px;
168 | }
169 |
170 | h2 {
171 | font-size: 20px;
172 | font-style: italic;
173 | font-weight: normal;
174 | line-height: 35px;
175 | }
176 |
177 | h2,
178 | p {
179 | color: #caabcb;
180 | font-family: 'Droid Serif', serif;
181 | }
182 |
183 | ul {
184 | list-style-type: none;
185 | padding: 0;
186 | }
187 |
188 | ul li {
189 | display: inline-block;
190 | }
191 |
192 | .container {
193 | background-image: url(/img/purple-cloud.png);
194 | background-position: bottom right;
195 | background-repeat: no-repeat;
196 | background-size: 60% 100%;
197 | min-height: 1000px;
198 | }
199 |
200 | main {
201 | display: block;
202 | position: relative;
203 | margin: 0 auto;
204 | z-index: 999;
205 | min-height: calc(100vh - 60px);
206 | display: grid;
207 | padding: 30px;
208 | max-width: 1440px;
209 | grid-template-columns: 1fr;
210 | grid-template-rows: 56px 1fr 87px;
211 | grid-template-areas: 'top' 'mid' 'bot';
212 | }
213 |
214 | header {
215 | grid-area: top;
216 | }
217 |
218 | .banner {
219 | background-color: #783460;
220 | padding: 20px 30px;
221 | display: flex;
222 | align-items: center;
223 | justify-content: space-between;
224 | }
225 |
226 | .banner h1 {
227 | font-size: 16px;
228 | line-height: 20px;
229 | margin: 0;
230 | }
231 |
232 | .banner-about {
233 | max-width: 670px;
234 | margin-right: 16px;
235 | }
236 |
237 | .banner-about span, .banner-about a, .banner a {
238 | font-weight: normal;
239 | color: #fff;
240 | font-size: 13px;
241 | line-height: 19px;
242 | }
243 |
244 | .banner-about span.about {
245 | margin-top: 5px;
246 | display: inline-block;
247 | }
248 |
249 | .banner-about span.about, .banner-about a {
250 | color: #fff;
251 | font-size: 13px;
252 | }
253 |
254 | .banner .banner-cta {
255 | display: flex;
256 | width: 224px;
257 | height: 60px;
258 | align-items: center;
259 | justify-content: center;
260 | padding:0 16px;
261 | color: #783460;
262 | background-color: #fff;
263 | text-decoration: none;
264 | }
265 |
266 | .banner .banner-cta .cta {
267 | font-size: 16px;
268 | font-weight: 600;
269 | margin-right: 16px
270 | }
271 |
272 |
273 | nav.desktop,
274 | nav.mobile {
275 | padding: 0 30px;
276 | display: flex;
277 | align-items: center;
278 | justify-content: space-between;
279 | }
280 |
281 | nav a {
282 | color: #928699;
283 | font-size: 13px;
284 | line-height: 16px;
285 | text-decoration: none;
286 | margin-right: 30px;
287 | }
288 |
289 | nav a:hover {
290 | color: #b6abbd;
291 | }
292 |
293 | nav a#logo {
294 | display: block;
295 | width: 56px;
296 | height: 56px;
297 | background-image: url('/img/logo.png');
298 | background-repeat: no-repeat;
299 | background-size: cover;
300 | }
301 |
302 | nav.mobile a#logo {
303 | width: 48px;
304 | height: 48px;
305 | }
306 |
307 | nav a#open-menu {
308 | display: block;
309 | width: 35px;
310 | height: 35px;
311 | background-image: url('/img/menu-icon.svg');
312 | background-repeat: no-repeat;
313 | margin: 0;
314 | }
315 |
316 | nav.desktop ul,
317 | nav.mobile ul {
318 | display: flex;
319 | align-items: center;
320 | }
321 |
322 | nav.desktop .social {
323 | align-self: right;
324 | }
325 |
326 | nav.desktop .social li {
327 | margin-right: 20px;
328 | }
329 |
330 | nav.desktop .social li a {
331 | margin: 0;
332 | }
333 |
334 | nav.mobile {
335 | display: none;
336 | }
337 |
338 | nav.menu {
339 | position: absolute;
340 | visibility: hidden;
341 | opacity: 0;
342 | background-color: #2d0838;
343 | top: 0;
344 | left: 0;
345 | height: calc(100vh - 60px);
346 | width: 100%;
347 | z-index: 0;
348 | display: grid;
349 | grid-template-rows: 30px 70% 55px;
350 | grid-template-columns: 1fr;
351 | padding: 30px 0;
352 | transition-property: opacity, visibility;
353 | transition-duration: 0.25s;
354 | transition-timing-function: ease-in-out;
355 | }
356 |
357 | nav.menu.open {
358 | visibility: visible;
359 | opacity: 1;
360 | z-index: 0;
361 | }
362 |
363 | nav.menu .close-wrapper {
364 | display: flex;
365 | align-items: flex-end;
366 | justify-content: flex-end;
367 | }
368 |
369 | nav.menu .close-wrapper .close {
370 | align-self: right;
371 | display: block;
372 | background-image: url('/img/close-icon.svg');
373 | background-repeat: no-repeat;
374 | width: 30px;
375 | height: 30px;
376 | }
377 |
378 | nav.menu ul {
379 | padding: 0 30px;
380 | }
381 |
382 | nav.menu li {
383 | margin-top: 40px;
384 | display: block;
385 | }
386 |
387 | nav.menu li a {
388 | color: #fff;
389 | font-size: 26px;
390 | line-height: 32px;
391 | }
392 |
393 | nav.menu ul.social li {
394 | display: inline;
395 | }
396 |
397 | nav.menu ul.social li a {
398 | height: 25px;
399 | width: 30px;
400 | background-size: cover;
401 | }
402 |
403 | /**
404 | * Suggest An Article
405 | */
406 |
407 | .suggest-article {
408 | position: fixed;
409 | visibility: hidden;
410 | opacity: 0;
411 | z-index: 1001;
412 | top: 0;
413 | left: 0;
414 | width: 100%;
415 | min-height: 100vh;
416 | background-color: #2d0838;
417 | display: grid;
418 | grid-template-rows: 127px 1fr;
419 | grid-template-columns: 1fr;
420 | text-align: center;
421 | transition-property: opacity, visibility;
422 | transition-duration: 0.25s;
423 | transition-timing-function: ease-in-out;
424 | }
425 |
426 | .suggest-article.open {
427 | visibility: visible;
428 | opacity: 1;
429 | }
430 |
431 | .suggest-article .close-wrapper {
432 | display: flex;
433 | align-items: flex-end;
434 | justify-content: flex-end;
435 | padding: 40px 72px;
436 | }
437 |
438 | .suggest-article .close-wrapper a.close {
439 | color: #fff;
440 | font-size: 14px;
441 | text-decoration: none;
442 | background-image: url('/img/close-icon.svg');
443 | background-repeat: no-repeat;
444 | background-position: top right;
445 | background-size: 16px 16px;
446 | padding-right: 25px;
447 | }
448 |
449 | .suggest-article h1,
450 | .suggest-article h2 {
451 | width: 85%;
452 | margin-left: auto;
453 | margin-right: auto;
454 | }
455 |
456 | .suggest-article form {
457 | width: 390px;
458 | margin: 55px auto;
459 | }
460 |
461 | .suggest-article input {
462 | margin-left: auto;
463 | margin-right: auto;
464 | }
465 |
466 | .suggest-article button {
467 | margin-top: 55px;
468 | background-image: url('/img/chevron-right.png');
469 | background-repeat: no-repeat;
470 | background-size: 25px 25px;
471 | background-position: center center;
472 | border: none;
473 | width: 48px;
474 | height: 48px;
475 | background-color: #e73536;
476 | border-radius: 50%;
477 | }
478 |
479 | /**
480 | * Content
481 | */
482 |
483 | .content {
484 | -ms-grid-columns: 1fr 1fr;
485 | -ms-grid-rows: minmax(min-content, calc(100vh - 250px));
486 | grid-area: mid;
487 | grid-template-areas: 'left right';
488 | grid-template-columns: 1fr 1fr;
489 | grid-template-rows: 1fr;
490 | min-height: 900px;
491 | height: 100%;
492 | }
493 |
494 | .hideable {
495 | display: none !important;
496 | }
497 |
498 | .content #splash {
499 | padding-top: 163px;
500 | padding-left: 65px;
501 | }
502 |
503 | .content #splash h1 {
504 | width: 579px;
505 | }
506 |
507 | .content #splash h2 {
508 | width: 509px;
509 | }
510 |
511 | .content #illustration {
512 | -ms-grid-column: 2;
513 | grid-area: right;
514 | background-image: url(/img/newsletter-illustration.svg);
515 | background-repeat: no-repeat;
516 | background-position: center 66px;
517 | padding: 30px;
518 | height: 725px;
519 | }
520 |
521 | .past-issues-container {
522 | width: 100%;
523 | display: flex;
524 | align-items: left;
525 | justify-content: space-around;
526 | margin-bottom: 30px;
527 | }
528 |
529 | .past-issues-header {
530 | width: 100%;
531 | display: flex;
532 | flex-flow: row wrap;
533 | align-items: left;
534 | justify-content: left;
535 | margin-bottom: 30px;
536 | }
537 |
538 | .recent-past-issues {
539 | display: grid;
540 | grid-template-columns: auto auto auto auto auto;
541 | padding-bottom: 4em;
542 | padding-left: 1em;
543 | }
544 |
545 | .recent-past-issues a {
546 | font-size: 18px;
547 | padding: 4px;
548 | font-size: 22px;
549 | text-align: left;
550 | color: #928699;
551 | text-decoration: none;
552 | }
553 |
554 | .recent-past-issues a:hover {
555 | color: #fff;
556 | }
557 |
558 | .past-issues {
559 | min-width: 200px;
560 | /* width: 33%; */
561 | }
562 |
563 | .past-issues li {
564 | display: block;
565 | font-size: 18px;
566 | }
567 |
568 | .past-issues li a {
569 | color: #928699;
570 | text-decoration: none;
571 | }
572 |
573 | .past-issues-header li a {
574 | color: #928699;
575 | text-decoration: none;
576 | margin: 8px;
577 | display: block;
578 | font-size: 22px;
579 | }
580 |
581 | .past-issues li a:hover {
582 | color: #fff;
583 | }
584 |
585 | /**
586 | * Footer
587 | */
588 | footer {
589 | grid-area: bot;
590 | }
591 |
592 | footer .bio h1,
593 | footer .bio p {
594 | margin: 0;
595 | padding: 0;
596 | line-height: 1em;
597 | font-size: 14px;
598 | align-self: left;
599 | }
600 |
601 | footer .bio h1 {
602 | line-height: 35px;
603 | }
604 |
605 | footer .bio p {
606 | line-height: 20px;
607 | }
608 |
609 | footer .bio .photo {
610 | flex: 1;
611 | height: 87px;
612 | width: 52px;
613 | align-self: left;
614 | background-image: url(/img/jonmajor.png);
615 | background-repeat: no-repeat;
616 | background-size: contain;
617 | margin-right: 24px;
618 | float: left;
619 | }
620 |
621 | footer .bio .details {
622 | float: left;
623 | }
624 |
625 | footer .sponsor {
626 | float: right;
627 | width: 120px;
628 | height: 74px;
629 | }
630 |
631 | footer .sponsor h1 {
632 | font-size: 12px;
633 | font-weight: normal;
634 | letter-spacing: 2px;
635 | text-transform: uppercase;
636 | line-height: 1em;
637 | margin-bottom: 16px;
638 | }
639 |
640 | footer .sponsor .logo {
641 | display: block;
642 | height: 50px;
643 | width: 99px;
644 | background-image: url(/img/ir_logo.svg);
645 | background-repeat: no-repeat;
646 | margin: 0 auto;
647 | }
648 |
649 | footer .social li {
650 | margin-right: 15px;
651 | }
652 |
653 | /**
654 | * Mobile overrides
655 | */
656 | @media screen and (max-width: 1229px) {
657 | .content {
658 | grid-template-columns: 1fr;
659 | }
660 |
661 | .content #illustration {
662 | display: none;
663 | }
664 | }
665 |
666 | @media screen and (max-width: 730px) {
667 | main {
668 | grid-template-rows: 56px 1fr 300px;
669 | }
670 |
671 | .container {
672 | background: none;
673 | }
674 |
675 | .suggest-article {
676 | position: absolute;
677 | grid-template-rows: 90px 1fr;
678 | height: 1115px;
679 | }
680 |
681 | .suggest-article .close-wrapper {
682 | padding: 30px;
683 | }
684 |
685 | .suggest-article .close-wrapper a.close {
686 | display: block;
687 | font-size: 0;
688 | height: 30px;
689 | width: 30px;
690 | background-size: 30px 30px;
691 | padding: 0;
692 | }
693 |
694 | .suggest-article form {
695 | width: 315px;
696 | }
697 |
698 | .suggest-article input {
699 | width: 250px;
700 | }
701 |
702 | .content {
703 | min-height: 750px;
704 | width: 100%;
705 | display: block;
706 | grid-template-columns: none;
707 | grid-template-rows: none;
708 | }
709 |
710 | .content #splash {
711 | padding-top: 50px;
712 | padding-left: 0;
713 | }
714 |
715 | .content #splash h1,
716 | .content #splash h2 {
717 | width: auto;
718 | }
719 |
720 | .email-input input {
721 | max-width: 250px;
722 | width: calc(100% - 115px);
723 | }
724 |
725 | footer {
726 | clear: both;
727 | }
728 |
729 | footer .bio h1 {
730 | line-height: 3.5em;
731 | }
732 |
733 | footer .bio p {
734 | font-size: 13px;
735 | }
736 |
737 | footer .bio .photo {
738 | display: block;
739 | float: none;
740 | height: 52px;
741 | }
742 |
743 | footer .bio .details {
744 | display: block;
745 | float: none;
746 | }
747 |
748 | footer .bio .social {
749 | padding: 0;
750 | margin-top: 20px;
751 | }
752 |
753 | footer .sponsor-wrap {
754 | display: flex;
755 | align-items: center;
756 | justify-content: center;
757 | float: none;
758 | margin-top: 50pt;
759 | }
760 | }
761 |
762 | @media screen and (max-width: 700px) {
763 | nav.desktop {
764 | display: none;
765 | }
766 |
767 | nav.mobile {
768 | display: flex;
769 | }
770 |
771 | .banner {
772 | flex-direction: column;
773 | align-items: flex-start;
774 | padding: 40px 30px 30px;
775 | margin-bottom: 24px;
776 | }
777 |
778 | .banner-about {
779 | max-width: 355px;
780 | margin-bottom: 30px;
781 | }
782 |
783 | .banner h1 {
784 | font-size: 20px;
785 | }
786 | }
787 |
788 | @media screen and (max-width: 414px) {
789 | .content #splash {
790 | padding: 0;
791 | }
792 | }
793 |
--------------------------------------------------------------------------------
/newsletter.js:
--------------------------------------------------------------------------------
1 | // See https://stackoverflow.com/questions/46155/how-can-you-validate-an-email-address-in-javascript
2 | function validateEmail (email) {
3 | var re = /^(([^<>()[\]\\.,:\s@\"]+(\.[^<>()[\]\\.,:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
4 | return re.test(email)
5 | }
6 |
7 | function enableScroll () {
8 | ['html', 'body'].forEach(function (selector) {
9 | document.querySelector(selector).style = ''
10 | })
11 | }
12 |
13 | function disableScroll () {
14 | ['html', 'body'].forEach(function (selector) {
15 | document.querySelector(selector).style = 'position: fixed; height: 100vh; overflow: hidden;'
16 | })
17 | }
18 |
19 | function displayError (element) {
20 | element.classList.add('error')
21 | }
22 |
23 | function hideError (element) {
24 | element.classList.remove('error')
25 | }
26 |
27 | window.onload = function () {
28 | // Subscribe Form
29 | var subscribeForm = document.querySelector('.subscribe-form form')
30 | var emailWrapper = document.querySelector('.email-input')
31 | var emailInput = document.querySelector('.email-input input')
32 |
33 | if (subscribeForm !== null) {
34 | subscribeForm.addEventListener('submit', function (event) {
35 | event.preventDefault()
36 |
37 | if (validateEmail(emailInput.value)) {
38 | emailWrapper.className = 'input-field email-input'
39 | subscribeForm.submit()
40 | } else {
41 | emailWrapper.className = 'input-field email-input error'
42 | }
43 | })
44 | }
45 |
46 | // Mobile navigation
47 | var openNav = document.querySelector('#open-menu')
48 | var closeNav = document.querySelector('nav.menu .close')
49 | var menu = document.querySelector('nav.menu')
50 | var content = document.querySelector(`section.content`)
51 |
52 | openNav.addEventListener('click', function (event) {
53 | event.preventDefault()
54 | window.scrollTo(0, 0)
55 | menu.classList.add('open')
56 | content.classList.add('hideable')
57 | disableScroll()
58 | })
59 |
60 | closeNav.addEventListener('click', function (event) {
61 | event.preventDefault()
62 | menu.classList.remove('open')
63 | content.classList.remove('hideable')
64 | enableScroll()
65 | })
66 |
67 | // Suggest an Article Modal
68 | var openSuggest = document.querySelectorAll('.open-suggest-article')
69 | var closeSuggest = document.querySelector('.suggest-article .close')
70 | var suggest = document.querySelector('.suggest-article')
71 |
72 | openSuggest.forEach(function (element) {
73 | element.addEventListener('click', function (event) {
74 | event.preventDefault()
75 | suggest.classList.add('open')
76 | enableScroll()
77 | })
78 | })
79 |
80 | closeSuggest.addEventListener('click', function (event) {
81 | event.preventDefault()
82 | window.scrollTo(0, 0)
83 | suggest.classList.remove('open')
84 |
85 | if (menu.classList.contains('open')) {
86 | disableScroll()
87 | } else {
88 | enableScroll()
89 | }
90 | })
91 |
92 | // Suggest an Article Form
93 | var suggestForm = document.querySelector('.suggest-article form')
94 | var suggestName = document.querySelector('.suggest-article input[name="name"]')
95 | var suggestEmail = document.querySelector('.suggest-article input[name="email"]')
96 | var suggestUrl = document.querySelector('.suggest-article input[name="url"]')
97 |
98 | suggestForm.addEventListener('submit', function (event) {
99 | event.preventDefault()
100 | var errors = []
101 |
102 | if (suggestName.value.length === 0) {
103 | displayError(suggestName.parentElement)
104 | errors = errors.concat('name')
105 | } else {
106 | hideError(suggestName.parentElement)
107 | }
108 |
109 | if (!validateEmail(suggestEmail.value)) {
110 | displayError(suggestEmail.parentElement)
111 | errors = errors.concat('email')
112 | } else {
113 | hideError(suggestEmail.parentElement)
114 | }
115 |
116 | if (suggestUrl.value.length < 5) {
117 | displayError(suggestUrl.parentElement)
118 | errors = errors.concat('url')
119 | } else {
120 | hideError(suggestUrl.parentElement)
121 | }
122 |
123 | if (errors.length === 0) {
124 | suggestForm.submit()
125 | }
126 | })
127 | }
128 |
129 |
--------------------------------------------------------------------------------
/normalize.css:
--------------------------------------------------------------------------------
1 | /*! normalize.css v7.0.0 | MIT License | github.com/necolas/normalize.css */
2 |
3 | /* Document
4 | ========================================================================== */
5 |
6 | /**
7 | * 1. Correct the line height in all browsers.
8 | * 2. Prevent adjustments of font size after orientation changes in
9 | * IE on Windows Phone and in iOS.
10 | */
11 |
12 | html {
13 | line-height: 1.15; /* 1 */
14 | -ms-text-size-adjust: 100%; /* 2 */
15 | -webkit-text-size-adjust: 100%; /* 2 */
16 | }
17 |
18 | /* Sections
19 | ========================================================================== */
20 |
21 | /**
22 | * Remove the margin in all browsers (opinionated).
23 | */
24 |
25 | body {
26 | margin: 0;
27 | }
28 |
29 | /**
30 | * Add the correct display in IE 9-.
31 | */
32 |
33 | article,
34 | aside,
35 | footer,
36 | header,
37 | nav,
38 | section {
39 | display: block;
40 | }
41 |
42 | /**
43 | * Correct the font size and margin on `h1` elements within `section` and
44 | * `article` contexts in Chrome, Firefox, and Safari.
45 | */
46 |
47 | h1 {
48 | font-size: 2em;
49 | margin: 0.67em 0;
50 | }
51 |
52 | /* Grouping content
53 | ========================================================================== */
54 |
55 | /**
56 | * Add the correct display in IE 9-.
57 | * 1. Add the correct display in IE.
58 | */
59 |
60 | figcaption,
61 | figure,
62 | main {
63 | /* 1 */
64 | display: block;
65 | }
66 |
67 | /**
68 | * Add the correct margin in IE 8.
69 | */
70 |
71 | figure {
72 | margin: 1em 40px;
73 | }
74 |
75 | /**
76 | * 1. Add the correct box sizing in Firefox.
77 | * 2. Show the overflow in Edge and IE.
78 | */
79 |
80 | hr {
81 | box-sizing: content-box; /* 1 */
82 | height: 0; /* 1 */
83 | overflow: visible; /* 2 */
84 | }
85 |
86 | /**
87 | * 1. Correct the inheritance and scaling of font size in all browsers.
88 | * 2. Correct the odd `em` font sizing in all browsers.
89 | */
90 |
91 | pre {
92 | font-family: monospace, monospace; /* 1 */
93 | font-size: 1em; /* 2 */
94 | }
95 |
96 | /* Text-level semantics
97 | ========================================================================== */
98 |
99 | /**
100 | * 1. Remove the gray background on active links in IE 10.
101 | * 2. Remove gaps in links underline in iOS 8+ and Safari 8+.
102 | */
103 |
104 | a {
105 | background-color: transparent; /* 1 */
106 | -webkit-text-decoration-skip: objects; /* 2 */
107 | }
108 |
109 | /**
110 | * 1. Remove the bottom border in Chrome 57- and Firefox 39-.
111 | * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
112 | */
113 |
114 | abbr[title] {
115 | border-bottom: none; /* 1 */
116 | text-decoration: underline; /* 2 */
117 | text-decoration: underline dotted; /* 2 */
118 | }
119 |
120 | /**
121 | * Prevent the duplicate application of `bolder` by the next rule in Safari 6.
122 | */
123 |
124 | b,
125 | strong {
126 | font-weight: inherit;
127 | }
128 |
129 | /**
130 | * Add the correct font weight in Chrome, Edge, and Safari.
131 | */
132 |
133 | b,
134 | strong {
135 | font-weight: bolder;
136 | }
137 |
138 | /**
139 | * 1. Correct the inheritance and scaling of font size in all browsers.
140 | * 2. Correct the odd `em` font sizing in all browsers.
141 | */
142 |
143 | code,
144 | kbd,
145 | samp {
146 | font-family: monospace, monospace; /* 1 */
147 | font-size: 1em; /* 2 */
148 | }
149 |
150 | /**
151 | * Add the correct font style in Android 4.3-.
152 | */
153 |
154 | dfn {
155 | font-style: italic;
156 | }
157 |
158 | /**
159 | * Add the correct background and color in IE 9-.
160 | */
161 |
162 | mark {
163 | background-color: #ff0;
164 | color: #000;
165 | }
166 |
167 | /**
168 | * Add the correct font size in all browsers.
169 | */
170 |
171 | small {
172 | font-size: 80%;
173 | }
174 |
175 | /**
176 | * Prevent `sub` and `sup` elements from affecting the line height in
177 | * all browsers.
178 | */
179 |
180 | sub,
181 | sup {
182 | font-size: 75%;
183 | line-height: 0;
184 | position: relative;
185 | vertical-align: baseline;
186 | }
187 |
188 | sub {
189 | bottom: -0.25em;
190 | }
191 |
192 | sup {
193 | top: -0.5em;
194 | }
195 |
196 | /* Embedded content
197 | ========================================================================== */
198 |
199 | /**
200 | * Add the correct display in IE 9-.
201 | */
202 |
203 | audio,
204 | video {
205 | display: inline-block;
206 | }
207 |
208 | /**
209 | * Add the correct display in iOS 4-7.
210 | */
211 |
212 | audio:not([controls]) {
213 | display: none;
214 | height: 0;
215 | }
216 |
217 | /**
218 | * Remove the border on images inside links in IE 10-.
219 | */
220 |
221 | img {
222 | border-style: none;
223 | }
224 |
225 | /**
226 | * Hide the overflow in IE.
227 | */
228 |
229 | svg:not(:root) {
230 | overflow: hidden;
231 | }
232 |
233 | /* Forms
234 | ========================================================================== */
235 |
236 | /**
237 | * 1. Change the font styles in all browsers (opinionated).
238 | * 2. Remove the margin in Firefox and Safari.
239 | */
240 |
241 | button,
242 | input,
243 | optgroup,
244 | select,
245 | textarea {
246 | font-family: sans-serif; /* 1 */
247 | font-size: 100%; /* 1 */
248 | line-height: 1.15; /* 1 */
249 | margin: 0; /* 2 */
250 | }
251 |
252 | /**
253 | * Show the overflow in IE.
254 | * 1. Show the overflow in Edge.
255 | */
256 |
257 | button,
258 | input {
259 | /* 1 */
260 | overflow: visible;
261 | }
262 |
263 | /**
264 | * Remove the inheritance of text transform in Edge, Firefox, and IE.
265 | * 1. Remove the inheritance of text transform in Firefox.
266 | */
267 |
268 | button,
269 | select {
270 | /* 1 */
271 | text-transform: none;
272 | }
273 |
274 | /**
275 | * 1. Prevent a WebKit bug where (2) destroys native `audio` and `video`
276 | * controls in Android 4.
277 | * 2. Correct the inability to style clickable types in iOS and Safari.
278 | */
279 |
280 | button,
281 | html [type="button"], /* 1 */
282 | [type="reset"],
283 | [type="submit"] {
284 | -webkit-appearance: button; /* 2 */
285 | }
286 |
287 | /**
288 | * Remove the inner border and padding in Firefox.
289 | */
290 |
291 | button::-moz-focus-inner,
292 | [type="button"]::-moz-focus-inner,
293 | [type="reset"]::-moz-focus-inner,
294 | [type="submit"]::-moz-focus-inner {
295 | border-style: none;
296 | padding: 0;
297 | }
298 |
299 | /**
300 | * Restore the focus styles unset by the previous rule.
301 | */
302 |
303 | button:-moz-focusring,
304 | [type="button"]:-moz-focusring,
305 | [type="reset"]:-moz-focusring,
306 | [type="submit"]:-moz-focusring {
307 | outline: 1px dotted ButtonText;
308 | }
309 |
310 | /**
311 | * Correct the padding in Firefox.
312 | */
313 |
314 | fieldset {
315 | padding: 0.35em 0.75em 0.625em;
316 | }
317 |
318 | /**
319 | * 1. Correct the text wrapping in Edge and IE.
320 | * 2. Correct the color inheritance from `fieldset` elements in IE.
321 | * 3. Remove the padding so developers are not caught out when they zero out
322 | * `fieldset` elements in all browsers.
323 | */
324 |
325 | legend {
326 | box-sizing: border-box; /* 1 */
327 | color: inherit; /* 2 */
328 | display: table; /* 1 */
329 | max-width: 100%; /* 1 */
330 | padding: 0; /* 3 */
331 | white-space: normal; /* 1 */
332 | }
333 |
334 | /**
335 | * 1. Add the correct display in IE 9-.
336 | * 2. Add the correct vertical alignment in Chrome, Firefox, and Opera.
337 | */
338 |
339 | progress {
340 | display: inline-block; /* 1 */
341 | vertical-align: baseline; /* 2 */
342 | }
343 |
344 | /**
345 | * Remove the default vertical scrollbar in IE.
346 | */
347 |
348 | textarea {
349 | overflow: auto;
350 | }
351 |
352 | /**
353 | * 1. Add the correct box sizing in IE 10-.
354 | * 2. Remove the padding in IE 10-.
355 | */
356 |
357 | [type="checkbox"],
358 | [type="radio"] {
359 | box-sizing: border-box; /* 1 */
360 | padding: 0; /* 2 */
361 | }
362 |
363 | /**
364 | * Correct the cursor style of increment and decrement buttons in Chrome.
365 | */
366 |
367 | [type="number"]::-webkit-inner-spin-button,
368 | [type="number"]::-webkit-outer-spin-button {
369 | height: auto;
370 | }
371 |
372 | /**
373 | * 1. Correct the odd appearance in Chrome and Safari.
374 | * 2. Correct the outline style in Safari.
375 | */
376 |
377 | [type="search"] {
378 | -webkit-appearance: textfield; /* 1 */
379 | outline-offset: -2px; /* 2 */
380 | }
381 |
382 | /**
383 | * Remove the inner padding and cancel buttons in Chrome and Safari on macOS.
384 | */
385 |
386 | [type="search"]::-webkit-search-cancel-button,
387 | [type="search"]::-webkit-search-decoration {
388 | -webkit-appearance: none;
389 | }
390 |
391 | /**
392 | * 1. Correct the inability to style clickable types in iOS and Safari.
393 | * 2. Change font properties to `inherit` in Safari.
394 | */
395 |
396 | ::-webkit-file-upload-button {
397 | -webkit-appearance: button; /* 1 */
398 | font: inherit; /* 2 */
399 | }
400 |
401 | /* Interactive
402 | ========================================================================== */
403 |
404 | /*
405 | * Add the correct display in IE 9-.
406 | * 1. Add the correct display in Edge, IE, and Firefox.
407 | */
408 |
409 | details, /* 1 */
410 | menu {
411 | display: block;
412 | }
413 |
414 | /*
415 | * Add the correct display in all browsers.
416 | */
417 |
418 | summary {
419 | display: list-item;
420 | }
421 |
422 | /* Scripting
423 | ========================================================================== */
424 |
425 | /**
426 | * Add the correct display in IE 9-.
427 | */
428 |
429 | canvas {
430 | display: inline-block;
431 | }
432 |
433 | /**
434 | * Add the correct display in IE.
435 | */
436 |
437 | template {
438 | display: none;
439 | }
440 |
441 | /* Hidden
442 | ========================================================================== */
443 |
444 | /**
445 | * Add the correct display in IE 10-.
446 | */
447 |
448 | [hidden] {
449 | display: none;
450 | }
451 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-native-newsletter",
3 | "version": "1.0.0",
4 | "description": "Free bi-weekly summary of React Native news, articles, issues & pull requests, libraries and apps curated by Jon Major Condon ([@jonmajorc](https://twitter.com/jonmajorc)).",
5 | "main": "ie.js",
6 | "dependencies": {
7 | "babel-cli": "^6.26.0",
8 | "babel-preset-react-app": "^3.1.2"
9 | },
10 | "devDependencies": {},
11 | "scripts": {
12 | "test": "echo \"Error: no test specified\" && exit 1"
13 | },
14 | "repository": {
15 | "type": "git",
16 | "url": "git+https://github.com/ReactNativeNews/react-native-newsletter.git"
17 | },
18 | "keywords": [],
19 | "author": "",
20 | "license": "ISC",
21 | "bugs": {
22 | "url": "https://github.com/ReactNativeNews/react-native-newsletter/issues"
23 | },
24 | "homepage": "https://github.com/ReactNativeNews/react-native-newsletter#readme"
25 | }
26 |
--------------------------------------------------------------------------------
/sponsor-package.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ReactNativeNews/react-native-newsletter/93016f62af32d97cc009f991d4f7c3c7155a4f26/sponsor-package.pdf
--------------------------------------------------------------------------------
/sponsor.css:
--------------------------------------------------------------------------------
1 | /**
2 | * Fonts
3 | */
4 | @font-face {
5 | font-family: 'Droid Serif';
6 | src: url('/fonts/DroidSerif.ttf');
7 | font-style: normal;
8 | }
9 |
10 | @font-face {
11 | font-family: 'Droid Serif';
12 | src: url('/fonts/DroidSerif-Italic.ttf');
13 | font-style: italic;
14 | }
15 |
16 | @font-face {
17 | font-family: 'Montserrat';
18 | src: url('/fonts/Montserrat-Regular.ttf');
19 | }
20 |
21 | /**
22 | * Typography
23 | */
24 |
25 | /**
26 | * Icons
27 | */
28 |
29 | .icon {
30 | display: inline-block;
31 | width: 18px;
32 | height: 16px;
33 | background-repeat: no-repeat;
34 | }
35 |
36 | .icon.twitter {
37 | background-image: url(/img/icon.twitter.svg);
38 | }
39 |
40 | .icon.medium {
41 | background-image: url(/img/icon.medium.svg);
42 | }
43 |
44 | .icon.github {
45 | background-image: url(/img/github.svg);
46 | }
47 |
48 | .icon.arrow-right {
49 | background-image: url(/img/icon-arrow.svg);
50 | margin-top: 2px;
51 | }
52 |
53 | .icon.arrow-right-white {
54 | background-image: url(/img/icon-arrow-white.svg);
55 | }
56 |
57 | /**
58 | * Forms
59 | */
60 |
61 | input {
62 | -webkit-appearance: none;
63 | color: #8f7e94;
64 | font-size: 15px;
65 | text-align: left;
66 | width: 393px;
67 | outline: none;
68 | background-color: white;
69 | border-radius: 32.5px;
70 | width: 300px;
71 | padding: 19px 30px 19px 30px;
72 | border: 2px solid #fff;
73 | display: block;
74 | margin-top: 23px;
75 | }
76 |
77 | .input-field {
78 | display: flex;
79 | flex-flow: row wrap;
80 | }
81 |
82 | .captcha-field {
83 | display: flex;
84 | align-self: center;
85 | padding-top: 100px;
86 | padding-left: 5px;
87 | }
88 |
89 | .input-field span {
90 | display: none;
91 | font-size: 13px;
92 | font-family: 'Droid Serif', serif;
93 | font-style: italic;
94 | line-height: 35px;
95 | text-align: left;
96 | }
97 |
98 | .input-field .addon {
99 | width: 50px;
100 | height: 61px;
101 | border-top-right-radius: 32.5px;
102 | border-bottom-right-radius: 32.5px;
103 | background-color: #fff;
104 | background-image: url(/img/long-arrow-right.svg);
105 | background-repeat: no-repeat;
106 | background-position: right 20px center;
107 | border-top: 2px solid #fff;
108 | border-right: 2px solid #fff;
109 | border-bottom: 2px solid #fff;
110 | border-left: none;
111 | outline: none;
112 | }
113 |
114 | .input-field .addon:hover {
115 | cursor: pointer;
116 | }
117 |
118 | .input-field.error .addon {
119 | border-color: #e73536;
120 | }
121 |
122 | .input-field.error input {
123 | border-color: #e73536;
124 | }
125 |
126 | .input-field.error span {
127 | display: block;
128 | color: #e73536;
129 | margin-left: 30px;
130 | width: 100%;
131 | }
132 |
133 | .email-input {
134 | margin-top: 71px;
135 | }
136 |
137 | .email-input input {
138 | margin-top: 0;
139 | border-right: none;
140 | border-top-right-radius: 0%;
141 | border-bottom-right-radius: 0%;
142 | width: 280px;
143 | }
144 |
145 | /**
146 | * Styles
147 | */
148 |
149 | html,
150 | body {
151 | background: linear-gradient(
152 | 143.43deg,
153 | #1f0232 0%,
154 | rgba(100, 11, 86, 0.99) 100%
155 | );
156 | min-height: 100%;
157 | min-width: 100%;
158 | height: auto;
159 | }
160 |
161 | body {
162 | font-family: 'Montserrat', sans-serif;
163 | color: #fff;
164 | margin: 0;
165 | }
166 |
167 | h1 {
168 | font-size: 46px;
169 | font-weight: bold;
170 | line-height: 56px;
171 | margin-bottom: 23px;
172 | }
173 |
174 | h2 {
175 | font-size: 30px;
176 | /* font-style: italic; */
177 | font-weight: normal;
178 | line-height: 35px;
179 | }
180 |
181 | h5 {
182 | color: red;
183 | }
184 |
185 | p {
186 | color: #caabcb;
187 | font-family: 'Droid Serif', serif;
188 | margin: 0 10em 2em 10em;
189 | font-size: 18px;
190 | text-align: center;
191 | line-height: 1.6;
192 | }
193 |
194 | article ul {
195 | margin: 0 10em 2em 10em;
196 | }
197 |
198 | article ul li {
199 | color: #caabcb;
200 | font-family: 'Droid Serif', serif;
201 | font-size: 18px;
202 | line-height: 3.5;
203 | }
204 | article img {
205 | width: 1000px;
206 | }
207 |
208 | .rates-container {
209 | margin: auto;
210 | margin-bottom: 50px;
211 | width: 50%;
212 | flex: 1;
213 | display: flex;
214 | padding: 20px;
215 | background-color: white;
216 | }
217 |
218 | .rate {
219 | width: 33.33%;
220 | }
221 |
222 | .rate-title {
223 | color: #d14435;
224 | text-align: center;
225 | font-size: 46px;
226 | font-weight: bold;
227 | }
228 |
229 | .rate-subtitle {
230 | text-align: center;
231 | width: 100%;
232 | color: #d14435;
233 | font-size: 14px;
234 | font-weight: bold;
235 | }
236 |
237 | .required-info-header {
238 | background-color: #992020;
239 | font-size: 100px;
240 | }
241 |
242 | .required-info-container {
243 | margin: auto;
244 | margin-bottom: 5em;
245 | width: 50%;
246 | display: flex;
247 | flex-direction: column;
248 | align-items: center;
249 | padding: 20px;
250 | background-color: white;
251 | }
252 |
253 | .required-info-container ul {
254 | background-color: #2d0838;
255 | width: 80%;
256 | padding: 1em 0 1em 4em;
257 | }
258 |
259 | .required-info-container h3 {
260 | display: flex;
261 | align-self: center;
262 | color: #d14435;
263 | font-size: 20px;
264 | margin-bottom: 30px;
265 | text-decoration: underline;
266 | }
267 |
268 | .center-wrapper {
269 | margin: auto;
270 | margin-bottom: 1em;
271 | display: flex;
272 | flex-direction: column;
273 | align-items: center;
274 | }
275 |
276 | .sponsor-image {
277 | width: 60%;
278 | height: 100%;
279 | margin-bottom: 5em;
280 | }
281 |
282 | .root a:link {
283 | color: #d14435;
284 | }
285 | .root a:visited {
286 | color: #2d0838;
287 | text-decoration: underline;
288 | cursor: auto;
289 | }
290 |
291 | .container {
292 | background-image: url(/img/purple-cloud.png);
293 | background-position: bottom right;
294 | background-repeat: no-repeat;
295 | background-size: 60% 100%;
296 | min-height: 1000px;
297 | }
298 |
299 | main {
300 | display: block;
301 | position: relative;
302 | margin: 0 auto;
303 | z-index: 999;
304 | min-height: calc(100vh - 60px);
305 | display: grid;
306 | padding: 30px;
307 | max-width: 1440px;
308 | grid-template-columns: 1fr;
309 | grid-template-rows: 56px 1fr 87px;
310 | grid-template-areas: 'top' 'mid' 'bot';
311 | }
312 |
313 | header {
314 | grid-area: top;
315 | }
316 |
317 | .banner {
318 | background-color: #783460;
319 | padding: 20px 30px;
320 | display: flex;
321 | align-items: center;
322 | justify-content: space-between;
323 | }
324 |
325 | .banner h1 {
326 | font-size: 16px;
327 | line-height: 20px;
328 | margin: 0;
329 | }
330 |
331 | .banner-about {
332 | max-width: 670px;
333 | margin-right: 16px;
334 | }
335 |
336 | .banner-about span, .banner-about a, .banner a {
337 | font-weight: normal;
338 | color: #fff;
339 | font-size: 13px;
340 | line-height: 19px;
341 | }
342 |
343 | .banner-about span.about {
344 | margin-top: 5px;
345 | display: inline-block;
346 | }
347 |
348 | .banner-about span.about, .banner-about a {
349 | color: #fff;
350 | font-size: 13px;
351 | }
352 |
353 | .banner .banner-cta {
354 | display: flex;
355 | width: 224px;
356 | height: 60px;
357 | align-items: center;
358 | justify-content: center;
359 | padding:0 16px;
360 | color: #783460;
361 | background-color: #fff;
362 | text-decoration: none;
363 | }
364 |
365 | .banner .banner-cta .cta {
366 | font-size: 16px;
367 | font-weight: 600;
368 | margin-right: 16px
369 | }
370 |
371 | nav.desktop,
372 | nav.mobile {
373 | padding: 0 30px;
374 | display: flex;
375 | align-items: center;
376 | justify-content: space-between;
377 | }
378 |
379 | nav a {
380 | color: #928699;
381 | font-size: 13px;
382 | line-height: 16px;
383 | text-decoration: none;
384 | margin-right: 30px;
385 | }
386 |
387 | nav a:hover {
388 | color: #b6abbd;
389 | }
390 |
391 | nav a#logo {
392 | display: block;
393 | width: 56px;
394 | height: 56px;
395 | background-image: url('/img/logo.png');
396 | background-repeat: no-repeat;
397 | background-size: cover;
398 | }
399 |
400 | nav.mobile a#logo {
401 | width: 48px;
402 | height: 48px;
403 | }
404 |
405 | nav a#open-menu {
406 | display: block;
407 | width: 35px;
408 | height: 35px;
409 | background-image: url('/img/menu-icon.svg');
410 | background-repeat: no-repeat;
411 | margin: 0;
412 | }
413 |
414 | nav.desktop ul,
415 | nav.mobile ul {
416 | display: flex;
417 | align-items: center;
418 | }
419 |
420 | nav.desktop .social {
421 | align-self: right;
422 | }
423 |
424 | nav.desktop .social li {
425 | margin-right: 20px;
426 | }
427 |
428 | nav.desktop .social li a {
429 | margin: 0;
430 | }
431 |
432 | nav.mobile {
433 | display: none;
434 | }
435 | nav ul {
436 | list-style-type: none;
437 | padding: 0;
438 | }
439 |
440 | nav li {
441 | display: inline-block;
442 | }
443 |
444 | nav.menu {
445 | position: absolute;
446 | visibility: hidden;
447 | opacity: 0;
448 | background-color: #2d0838;
449 | top: 0;
450 | left: 0;
451 | height: calc(100vh - 60px);
452 | width: 100%;
453 | z-index: 0;
454 | display: grid;
455 | grid-template-rows: 30px 70% 55px;
456 | grid-template-columns: 1fr;
457 | padding: 30px 0;
458 | transition-property: opacity, visibility;
459 | transition-duration: 0.25s;
460 | transition-timing-function: ease-in-out;
461 | }
462 |
463 | nav.menu.open {
464 | visibility: visible;
465 | opacity: 1;
466 | z-index: 0;
467 | }
468 |
469 | nav.menu .close-wrapper {
470 | display: flex;
471 | align-items: flex-end;
472 | justify-content: flex-end;
473 | }
474 |
475 | nav.menu .close-wrapper .close {
476 | display: block;
477 | background-image: url('/img/close-icon.svg');
478 | background-repeat: no-repeat;
479 | width: 30px;
480 | height: 30px;
481 | }
482 |
483 | nav.menu ul {
484 | padding: 0 30px;
485 | }
486 |
487 | nav.menu li {
488 | margin-top: 40px;
489 | display: block;
490 | }
491 |
492 | nav.menu li a {
493 | color: #fff;
494 | font-size: 26px;
495 | line-height: 32px;
496 | }
497 |
498 | nav.menu ul.social li {
499 | display: inline;
500 | }
501 |
502 | nav.menu ul.social li a {
503 | height: 25px;
504 | width: 30px;
505 | background-size: cover;
506 | }
507 |
508 | /**
509 | * New Site Message
510 | */
511 |
512 | section.new-site-message {
513 | display: flex;
514 | flex-direction: column;
515 | justify-content: flex-start;
516 | max-width: 563px;
517 | }
518 |
519 | section.new-site-message h1 {
520 | font-size: 32px;
521 | line-height: 1.18;
522 | margin: 0 0 24px 0;
523 | width: 410px
524 | }
525 |
526 | section.new-site-message p {
527 | text-align: left;
528 | color: #fff;
529 | font-family: 'Montserrat';
530 | margin: 0 0 16px 0;
531 | font-size: 16px;
532 | line-height: 1.5;
533 | }
534 |
535 | section.new-site-message p a {
536 | color: #fff;
537 | }
538 |
539 | section.new-site-message p.new-site-cta a {
540 | margin-top: 38px;
541 | color: #fff;
542 | text-decoration: none;
543 | display: flex;
544 | align-items: center;
545 | }
546 |
547 | p a .new-site-cta-message {
548 | margin-left: 10px;
549 | text-decoration: underline;
550 | font-weight: bold !important;
551 | }
552 |
553 | /**
554 | * Suggest An Article
555 | */
556 |
557 | .suggest-article {
558 | position: fixed;
559 | visibility: hidden;
560 | opacity: 0;
561 | z-index: 1001;
562 | top: 0;
563 | left: 0;
564 | width: 100%;
565 | min-height: 100vh;
566 | background-color: #2d0838;
567 | display: grid;
568 | grid-template-rows: 127px 1fr;
569 | grid-template-columns: 1fr;
570 | text-align: center;
571 | transition-property: opacity, visibility;
572 | transition-duration: 0.25s;
573 | transition-timing-function: ease-in-out;
574 | }
575 |
576 | .suggest-article.open {
577 | visibility: visible;
578 | opacity: 1;
579 | }
580 |
581 | .suggest-article .close-wrapper {
582 | display: flex;
583 | align-items: flex-end;
584 | justify-content: flex-end;
585 | padding: 40px 72px;
586 | }
587 |
588 | .suggest-article .close-wrapper a.close {
589 | color: #fff;
590 | font-size: 14px;
591 | text-decoration: none;
592 | background-image: url('/img/close-icon.svg');
593 | background-repeat: no-repeat;
594 | background-position: top right;
595 | background-size: 16px 16px;
596 | padding-right: 25px;
597 | }
598 |
599 | .suggest-article h1,
600 | .suggest-article h2 {
601 | width: 85%;
602 | margin-left: auto;
603 | margin-right: auto;
604 | }
605 |
606 | .suggest-article form {
607 | width: 390px;
608 | margin: 55px auto;
609 | }
610 |
611 | .suggest-article input {
612 | margin-left: auto;
613 | margin-right: auto;
614 | }
615 |
616 | .suggest-article button {
617 | margin-top: 55px;
618 | background-image: url('/img/chevron-right.png');
619 | background-repeat: no-repeat;
620 | background-size: 25px 25px;
621 | background-position: center center;
622 | border: none;
623 | width: 48px;
624 | height: 48px;
625 | background-color: #e73536;
626 | border-radius: 50%;
627 | }
628 |
629 | /**
630 | * Content
631 | */
632 |
633 | .content {
634 | -ms-grid-columns: 1fr 1fr;
635 | -ms-grid-rows: minmax(min-content, calc(100vh - 250px));
636 | grid-area: mid;
637 | display: flex;
638 | justify-content: center;
639 | }
640 |
641 | .content #splash {
642 | padding-top: 163px;
643 | padding-left: 65px;
644 | }
645 |
646 | .content #splash h1 {
647 | width: 579px;
648 | }
649 |
650 | .content #splash h2 {
651 | width: 509px;
652 | }
653 |
654 | .content #illustration {
655 | -ms-grid-column: 2;
656 | grid-area: right;
657 | background-image: url(/img/newsletter-illustration.svg);
658 | background-repeat: no-repeat;
659 | background-position: center 66px;
660 | padding: 30px;
661 | height: 725px;
662 | }
663 |
664 | .past-issues-container {
665 | width: 100%;
666 | display: flex;
667 | align-items: left;
668 | justify-content: space-around;
669 | margin-bottom: 30px;
670 | }
671 |
672 | .past-issues-header {
673 | width: 100%;
674 | display: flex;
675 | flex-flow: row wrap;
676 | align-items: left;
677 | justify-content: left;
678 | margin-bottom: 30px;
679 | }
680 |
681 | .past-issues {
682 | min-width: 200px;
683 | /* width: 33%; */
684 | }
685 |
686 | .past-issues li {
687 | display: block;
688 | font-size: 18px;
689 | }
690 |
691 | .past-issues li a {
692 | color: #928699;
693 | text-decoration: none;
694 | }
695 |
696 | .past-issues-header li a {
697 | color: #928699;
698 | text-decoration: none;
699 | margin: 8px;
700 | display: block;
701 | font-size: 22px;
702 | }
703 |
704 | .past-issues li a:hover {
705 | color: #fff;
706 | }
707 |
708 | /**
709 | * Footer
710 | */
711 |
712 | footer {
713 | grid-area: bot;
714 | }
715 |
716 | footer .bio h1 {
717 | margin: 0;
718 | padding: 0;
719 | line-height: 1em;
720 | font-size: 14px;
721 | align-self: left;
722 | }
723 |
724 | footer .bio p {
725 | margin: 15px 0 0 0;
726 | padding: 0;
727 | line-height: 1em;
728 | font-size: 14px;
729 | align-self: left;
730 | /* right: 20px; */
731 | /* background-color: #992020; */
732 | }
733 |
734 | footer .bio .photo {
735 | flex: 1;
736 | height: 87px;
737 | width: 52px;
738 | align-self: left;
739 | background-image: url(/img/jonmajor.png);
740 | background-repeat: no-repeat;
741 | background-size: contain;
742 | margin-right: 24px;
743 | float: left;
744 | }
745 |
746 | footer .bio .details {
747 | float: left;
748 | }
749 |
750 | footer .sponsor {
751 | float: right;
752 | width: 120px;
753 | height: 74px;
754 | }
755 |
756 | footer .sponsor h1 {
757 | font-size: 12px;
758 | font-weight: normal;
759 | letter-spacing: 2px;
760 | text-transform: uppercase;
761 | line-height: 1em;
762 | margin-bottom: 16px;
763 | }
764 |
765 | footer .sponsor p {
766 | font-size: 12px;
767 | font-weight: normal;
768 | letter-spacing: 2px;
769 | text-transform: uppercase;
770 | line-height: 1em;
771 | margin-bottom: 16px;
772 | }
773 |
774 | footer .sponsor .logo {
775 | display: block;
776 | height: 50px;
777 | width: 99px;
778 | background-image: url(/img/ir_logo.svg);
779 | background-repeat: no-repeat;
780 | margin: 0 auto;
781 | }
782 |
783 | footer .social li {
784 | margin-right: 15px;
785 | }
786 |
787 | /**
788 | * Mobile overrides
789 | */
790 | @media screen and (max-width: 1229px) {
791 | .content {
792 | grid-template-columns: 1fr;
793 | }
794 |
795 | .content #illustration {
796 | display: none;
797 | }
798 | }
799 |
800 | @media screen and (max-width: 730px) {
801 | main {
802 | grid-template-rows: 56px 1fr 300px;
803 | }
804 |
805 | .container {
806 | background: none;
807 | }
808 |
809 | .suggest-article {
810 | position: absolute;
811 | grid-template-rows: 90px 1fr;
812 | height: 1115px;
813 | }
814 |
815 | .suggest-article .close-wrapper {
816 | padding: 30px;
817 | }
818 |
819 | .suggest-article .close-wrapper a.close {
820 | display: block;
821 | font-size: 0;
822 | height: 30px;
823 | width: 30px;
824 | background-size: 30px 30px;
825 | padding: 0;
826 | }
827 |
828 | .suggest-article form {
829 | width: 315px;
830 | }
831 |
832 | .suggest-article input {
833 | width: 250px;
834 | }
835 |
836 | .content {
837 | min-height: 750px;
838 | width: 100%;
839 | display: block;
840 | grid-template-columns: none;
841 | grid-template-rows: none;
842 | }
843 |
844 | .content #splash {
845 | padding-top: 50px;
846 | padding-left: 0;
847 | }
848 |
849 | .content #splash h1,
850 | .content #splash h2 {
851 | width: auto;
852 | }
853 |
854 | .email-input input {
855 | max-width: 250px;
856 | width: calc(100% - 115px);
857 | }
858 |
859 | footer {
860 | clear: both;
861 | }
862 |
863 | footer .bio h1 {
864 | line-height: 3.5em;
865 | }
866 |
867 | footer .bio .photo {
868 | display: block;
869 | float: none;
870 | height: 52px;
871 | }
872 |
873 | footer .bio .social {
874 | padding: 0;
875 | margin-top: 20px;
876 | display: flex;
877 | flex-direction: row;
878 | background-color: #992020;
879 | }
880 |
881 | footer .sponsor-wrap {
882 | display: flex;
883 | align-items: center;
884 | justify-content: center;
885 | float: none;
886 | margin-top: 50pt;
887 | }
888 | }
889 |
890 | @media screen and (max-width: 700px) {
891 | nav.desktop {
892 | display: none;
893 | }
894 |
895 | nav.mobile {
896 | display: flex;
897 | }
898 |
899 | .banner {
900 | flex-direction: column;
901 | align-items: flex-start;
902 | padding: 40px 30px 30px;
903 | margin-bottom: 24px;
904 | }
905 |
906 | .banner-about {
907 | max-width: 355px;
908 | margin-bottom: 30px;
909 | }
910 |
911 | .banner h1 {
912 | font-size: 20px;
913 | }
914 | }
915 |
916 | @media screen and (max-width: 414px) {
917 | .content #splash {
918 | padding: 0;
919 | }
920 | }
921 |
--------------------------------------------------------------------------------
/sponsor.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
9 |
18 |
19 |
20 |
24 |
25 | React Native Newsletter
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
We have a new website!
41 |
42 | The React Native Newsletter has a new home on the web! Head on over to
43 | our new website
44 | for new issues, article suggestions, and more.
45 |
46 |
47 |
48 | Visit the new site
49 |
50 |
51 |
52 |
53 |
64 |
65 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
109 |
110 |
111 |
112 | You can find this page on our new site
113 | Many of our pages have moved! Article suggestions have moved to a new website.
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
Jon Major Condon, Editor-in-Chief
122 |
Jon Major specializes in React Native at Infinite Red.
123 |
131 |
132 |
133 |
134 |
140 |
141 |
142 |
143 |
147 |
151 |
152 |
153 |
154 |
155 |
--------------------------------------------------------------------------------
/sponsorPage.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | function SponsorPage() {
4 | function renderStats() {
5 | return React.createElement(
6 | "div",
7 | { "class": "rates-container" },
8 | React.createElement(
9 | "div",
10 | { "class": "rate" },
11 | React.createElement(
12 | "div",
13 | { "class": "rate-title" },
14 | "11.5+ k"
15 | ),
16 | React.createElement(
17 | "div",
18 | { "class": "rate-subtitle" },
19 | "SUBSCRIBERS"
20 | )
21 | ),
22 | React.createElement(
23 | "div",
24 | { "class": "rate" },
25 | React.createElement(
26 | "div",
27 | { "class": "rate-title" },
28 | "30%"
29 | ),
30 | React.createElement(
31 | "div",
32 | { "class": "rate-subtitle" },
33 | "OPEN RATE"
34 | )
35 | ),
36 | React.createElement(
37 | "div",
38 | { "class": "rate" },
39 | React.createElement(
40 | "div",
41 | { "class": "rate-title" },
42 | "10%"
43 | ),
44 | React.createElement(
45 | "div",
46 | { "class": "rate-subtitle" },
47 | "CLICK THRU RATE"
48 | )
49 | )
50 | );
51 | }
52 |
53 | function renderRequiredInfo() {
54 | return React.createElement(
55 | "div",
56 | { "class": "required-info-container" },
57 | React.createElement(
58 | "h3",
59 | null,
60 | "Sponsorship Required Information & Assets"
61 | ),
62 | React.createElement(
63 | "ul",
64 | null,
65 | React.createElement(
66 | "li",
67 | null,
68 | "1 Image (1200x900px, png or jpg)"
69 | ),
70 | React.createElement(
71 | "li",
72 | null,
73 | "Title (20 words max)"
74 | ),
75 | React.createElement(
76 | "li",
77 | null,
78 | "Description (75 words max)"
79 | ),
80 | React.createElement(
81 | "li",
82 | null,
83 | "URL Link (will link on image and title)"
84 | ),
85 | React.createElement(
86 | "li",
87 | null,
88 | "Content should be tasteful and appropriate"
89 | ),
90 | React.createElement(
91 | "li",
92 | null,
93 | "Provide all information one week before sponsored issue date"
94 | )
95 | )
96 | );
97 | }
98 |
99 | return React.createElement(
100 | "div",
101 | { "class": "root" },
102 | React.createElement(
103 | "div",
104 | { "class": "center-wrapper" },
105 | React.createElement(
106 | "h2",
107 | null,
108 | "Why sponsor the React Native Newsletter?"
109 | )
110 | ),
111 | React.createElement(
112 | "p",
113 | null,
114 | "Sponsoring the newsletter not only gets your company in front of many high quality React Native developers, but it also helps support the continuing curation and editing of the newsletter."
115 | ),
116 | renderStats(),
117 | React.createElement(
118 | "ul",
119 | null,
120 | React.createElement(
121 | "li",
122 | null,
123 | "There are four sponsorships available per issue available on a first-come, first-serve basis."
124 | ),
125 | React.createElement(
126 | "li",
127 | null,
128 | "Sponsorships are $250/issue and must be paid for in-full upfront - credit cards and PayPal are payment options."
129 | ),
130 | React.createElement(
131 | "li",
132 | null,
133 | "Sponsorships do not have to be consecutive."
134 | ),
135 | React.createElement(
136 | "li",
137 | null,
138 | "Desired dates must be listed at time of purchase and approved by Infinite Red."
139 | )
140 | ),
141 | React.createElement("br", null),
142 | React.createElement(
143 | "div",
144 | { "class": "center-wrapper" },
145 | React.createElement(
146 | "h2",
147 | null,
148 | "Example Sponsorship"
149 | ),
150 | React.createElement("img", { "class": "sponsor-image", src: "../img/sponsor-demo.png" })
151 | ),
152 | React.createElement(
153 | "div",
154 | { "class": "center-wrapper" },
155 | React.createElement(
156 | "h2",
157 | null,
158 | "Complete this Form to Sponsor the Newsletter"
159 | )
160 | ),
161 | React.createElement(
162 | "div",
163 | { "class": "center-wrapper" },
164 | React.createElement(
165 | "iframe",
166 | {
167 | src: "https://docs.google.com/forms/d/e/1FAIpQLScqz4Wpdkd2hpNsA2isEnGNR311XNEh1HAmPzUXL99BDBzv2Q/viewform?embedded=true",
168 | width: "640",
169 | height: "1000",
170 | frameborder: "0",
171 | marginheight: "0",
172 | marginwidth: "0"
173 | },
174 | "Loading\u2026"
175 | )
176 | ),
177 | React.createElement("div", { style: { height: 50 } })
178 | );
179 | }
180 | var domContainer = document.querySelector("#sponsor_page_content");
181 | ReactDOM.render(React.createElement(SponsorPage, null), domContainer);
--------------------------------------------------------------------------------
/src/sponsorPage.js:
--------------------------------------------------------------------------------
1 | "use strict"
2 |
3 | function SponsorPage() {
4 | function renderStats() {
5 | return (
6 |
7 |
8 |
11.5+ k
9 |
SUBSCRIBERS
10 |
11 |
12 |
30%
13 |
OPEN RATE
14 |
15 |
16 |
10%
17 |
CLICK THRU RATE
18 |
19 |
20 | )
21 | }
22 |
23 | function renderRequiredInfo() {
24 | return (
25 |
26 |
Sponsorship Required Information & Assets
27 |
28 | 1 Image (1200x900px, png or jpg)
29 | Title (20 words max)
30 | Description (75 words max)
31 | URL Link (will link on image and title)
32 | Content should be tasteful and appropriate
33 | Provide all information one week before sponsored issue date
34 |
35 |
36 | )
37 | }
38 |
39 | return (
40 |
41 |
42 |
Why sponsor the React Native Newsletter?
43 |
44 |
45 | Sponsoring the newsletter not only gets your company in front of many high quality React Native developers, but it also helps
46 | support the continuing curation and editing of the newsletter.
47 |
48 | {renderStats()}
49 |
50 | There are four sponsorships available per issue available on a first-come, first-serve basis.
51 | Sponsorships are $250/issue and must be paid for in-full upfront - credit cards and PayPal are payment options.
52 | Sponsorships do not have to be consecutive.
53 | Desired dates must be listed at time of purchase and approved by Infinite Red.
54 |
55 |
56 |
57 |
Example Sponsorship
58 |
59 |
60 | {/* {renderRequiredInfo()} */}
61 |
62 |
Complete this Form to Sponsor the Newsletter
63 |
64 |
65 |
75 |
76 |
77 | {/*
78 | Email us with any questions or to inquire
79 | about a sponsorship.
80 |
*/}
81 |
82 | )
83 | }
84 | let domContainer = document.querySelector("#sponsor_page_content")
85 | ReactDOM.render( , domContainer)
86 |
--------------------------------------------------------------------------------
/static.json:
--------------------------------------------------------------------------------
1 | {
2 | "root": "."
3 | }
--------------------------------------------------------------------------------
/suggest-article.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
9 |
18 |
19 |
20 |
24 |
25 | React Native Newsletter
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
We have a new website!
42 |
43 | The React Native Newsletter has a new home on the web! Head on over to
44 | our new website
45 | for past issues, sponsorship opportunities, and more.
46 |
47 |
48 |
49 | Visit the new site
50 |
51 |
52 |
53 |
54 |
74 |
75 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
117 |
118 |
119 |
132 |
133 |
134 |
135 |
136 |
137 |
Jon Major Condon, Editor-in-Chief
138 |
Jon Major specializes in React Native at Infinite Red.
139 |
140 |
141 |
142 |
148 |
149 |
150 |
151 |
155 |
159 |
160 |
161 |
162 |
163 |
--------------------------------------------------------------------------------