├── .tool-versions
├── 01-css-in-js
├── after
│ ├── .gitignore
│ ├── next.config.js
│ ├── package-lock.json
│ ├── package.json
│ ├── public
│ │ └── favicon.png
│ └── src
│ │ ├── components
│ │ ├── App.js
│ │ ├── Newsletter.js
│ │ └── index.css
│ │ └── pages
│ │ ├── _app.js
│ │ └── index.js
├── before
│ ├── .gitignore
│ ├── next.config.js
│ ├── package-lock.json
│ ├── package.json
│ ├── public
│ │ └── favicon.png
│ └── src
│ │ ├── components
│ │ ├── App.js
│ │ ├── Newsletter.js
│ │ └── index.css
│ │ └── pages
│ │ ├── _app.js
│ │ └── index.js
└── snippets.css
└── 02-css-modules
├── after
├── .gitignore
├── next.config.js
├── package-lock.json
├── package.json
├── public
│ └── favicon.png
└── src
│ ├── components
│ ├── App.js
│ ├── Newsletter.js
│ ├── Newsletter.module.css
│ └── index.css
│ └── pages
│ ├── _app.js
│ └── index.js
├── before
├── .gitignore
├── next.config.js
├── package-lock.json
├── package.json
├── public
│ └── favicon.png
└── src
│ ├── components
│ ├── App.js
│ ├── Newsletter.js
│ ├── Newsletter.module.css
│ └── index.css
│ └── pages
│ ├── _app.js
│ └── index.js
└── snippets.css
/.tool-versions:
--------------------------------------------------------------------------------
1 | nodejs 19.4.0
2 |
--------------------------------------------------------------------------------
/01-css-in-js/after/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # next.js
12 | /.next/
13 | /out/
14 |
15 | # production
16 | /build
17 |
18 | # misc
19 | .DS_Store
20 | *.pem
21 |
22 | # debug
23 | npm-debug.log*
24 | yarn-debug.log*
25 | yarn-error.log*
26 | .pnpm-debug.log*
27 |
28 | # local env files
29 | .env*.local
30 |
31 | # vercel
32 | .vercel
33 |
--------------------------------------------------------------------------------
/01-css-in-js/after/next.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | const nextConfig = {
3 | reactStrictMode: true,
4 | }
5 |
6 | module.exports = nextConfig
7 |
--------------------------------------------------------------------------------
/01-css-in-js/after/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "01-css-in-js",
3 | "version": "0.1.0",
4 | "lockfileVersion": 3,
5 | "requires": true,
6 | "packages": {
7 | "": {
8 | "name": "01-css-in-js",
9 | "version": "0.1.0",
10 | "dependencies": {
11 | "next": "13.1.4",
12 | "react": "18.2.0",
13 | "react-dom": "18.2.0"
14 | }
15 | },
16 | "node_modules/@next/env": {
17 | "version": "13.1.4",
18 | "resolved": "https://registry.npmjs.org/@next/env/-/env-13.1.4.tgz",
19 | "integrity": "sha512-x7ydhMpi9/xX7yVK+Fw33OuwwQWVZUFRxenK3z89fmPzQZyUk35Ynb+b7JkrhfRhDIFFvvqpzVSXeseSlBAw7A=="
20 | },
21 | "node_modules/@next/swc-android-arm-eabi": {
22 | "version": "13.1.4",
23 | "resolved": "https://registry.npmjs.org/@next/swc-android-arm-eabi/-/swc-android-arm-eabi-13.1.4.tgz",
24 | "integrity": "sha512-5PAchzFst3In6Ml+9APvBj89H29lcPXcUqEYBVv09fWK/V4IuViKc2qOqM9pyPyw7KsqaZPmuqaG595E6jdZLA==",
25 | "cpu": [
26 | "arm"
27 | ],
28 | "optional": true,
29 | "os": [
30 | "android"
31 | ],
32 | "engines": {
33 | "node": ">= 10"
34 | }
35 | },
36 | "node_modules/@next/swc-android-arm64": {
37 | "version": "13.1.4",
38 | "resolved": "https://registry.npmjs.org/@next/swc-android-arm64/-/swc-android-arm64-13.1.4.tgz",
39 | "integrity": "sha512-LCLjjRhsQ5fR9ExzR2fqxuyJe/D4Ct/YkdonVfJfqOfkEpFwUTQDOVo5GrQec4LZDk3zY+o6vZYjXbB0nD9VLA==",
40 | "cpu": [
41 | "arm64"
42 | ],
43 | "optional": true,
44 | "os": [
45 | "android"
46 | ],
47 | "engines": {
48 | "node": ">= 10"
49 | }
50 | },
51 | "node_modules/@next/swc-darwin-arm64": {
52 | "version": "13.1.4",
53 | "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-13.1.4.tgz",
54 | "integrity": "sha512-LSc/tF1FQ1y1SwKiCdGg8IIl7+Csk6nuLcLIyQXs24UNYjXg5+7vUQXqE8y66v/Dq8qFDC9rM61QhpM9ZDftbg==",
55 | "cpu": [
56 | "arm64"
57 | ],
58 | "optional": true,
59 | "os": [
60 | "darwin"
61 | ],
62 | "engines": {
63 | "node": ">= 10"
64 | }
65 | },
66 | "node_modules/@next/swc-darwin-x64": {
67 | "version": "13.1.4",
68 | "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-13.1.4.tgz",
69 | "integrity": "sha512-WoApDo8xfafrNc9+Mz5MwGFKUwbDHsGqLleTGZ8upegwVqDyHsYzqJQudf+loqhV58oGTOqP1eWaHn2J7dijXA==",
70 | "cpu": [
71 | "x64"
72 | ],
73 | "optional": true,
74 | "os": [
75 | "darwin"
76 | ],
77 | "engines": {
78 | "node": ">= 10"
79 | }
80 | },
81 | "node_modules/@next/swc-freebsd-x64": {
82 | "version": "13.1.4",
83 | "resolved": "https://registry.npmjs.org/@next/swc-freebsd-x64/-/swc-freebsd-x64-13.1.4.tgz",
84 | "integrity": "sha512-fqNyeT8G4guN8AHPIoBRhGY2GJg89FyWpuwX4o0Y3vUy/84IGZpNst3paCzaYkQSqQE/AuCpkB7hKxkN7ittXw==",
85 | "cpu": [
86 | "x64"
87 | ],
88 | "optional": true,
89 | "os": [
90 | "freebsd"
91 | ],
92 | "engines": {
93 | "node": ">= 10"
94 | }
95 | },
96 | "node_modules/@next/swc-linux-arm-gnueabihf": {
97 | "version": "13.1.4",
98 | "resolved": "https://registry.npmjs.org/@next/swc-linux-arm-gnueabihf/-/swc-linux-arm-gnueabihf-13.1.4.tgz",
99 | "integrity": "sha512-MEfm8OC1YR9/tYHUzlQsxcSmiuf8XdO7bqh5VtG4pilScjc5I5t+tQgIDgoDGePfh5W99W23hb3s6oCFrt99rw==",
100 | "cpu": [
101 | "arm"
102 | ],
103 | "optional": true,
104 | "os": [
105 | "linux"
106 | ],
107 | "engines": {
108 | "node": ">= 10"
109 | }
110 | },
111 | "node_modules/@next/swc-linux-arm64-gnu": {
112 | "version": "13.1.4",
113 | "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-13.1.4.tgz",
114 | "integrity": "sha512-2wgth/KsuODzW/E7jsRoWdhKmE5oZzXcBPvf9RW+ZpBNvYQkEDlzfLA7n8DtxTU8I4oMas0mdEPdCWXrSNnVZw==",
115 | "cpu": [
116 | "arm64"
117 | ],
118 | "optional": true,
119 | "os": [
120 | "linux"
121 | ],
122 | "engines": {
123 | "node": ">= 10"
124 | }
125 | },
126 | "node_modules/@next/swc-linux-arm64-musl": {
127 | "version": "13.1.4",
128 | "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-13.1.4.tgz",
129 | "integrity": "sha512-GdWhCRljsT7rNEElEsdu4RRppd+XaQOX1IJslsh/+HU6LsJGUE8tXpa68yJjCsHZHifkbdZNeCr5SYdsN6CbAA==",
130 | "cpu": [
131 | "arm64"
132 | ],
133 | "optional": true,
134 | "os": [
135 | "linux"
136 | ],
137 | "engines": {
138 | "node": ">= 10"
139 | }
140 | },
141 | "node_modules/@next/swc-linux-x64-gnu": {
142 | "version": "13.1.4",
143 | "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-13.1.4.tgz",
144 | "integrity": "sha512-Rsk/ojwYqMskN2eo5hUSVe7UuMV/aSjmrmJ0BCFGFPfBY9sPgmYj/oXlDDN0y5lJD9acPuiBjknLWgnOnx5JIA==",
145 | "cpu": [
146 | "x64"
147 | ],
148 | "optional": true,
149 | "os": [
150 | "linux"
151 | ],
152 | "engines": {
153 | "node": ">= 10"
154 | }
155 | },
156 | "node_modules/@next/swc-linux-x64-musl": {
157 | "version": "13.1.4",
158 | "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-13.1.4.tgz",
159 | "integrity": "sha512-gKSVPozedA2gpA+vggYnAqpDuzWFed2oxFeXxHw0aW2ALdAZswAinn1ZwXEQ5fHnVguxjZhH0+2nBxpMdF8p5Q==",
160 | "cpu": [
161 | "x64"
162 | ],
163 | "optional": true,
164 | "os": [
165 | "linux"
166 | ],
167 | "engines": {
168 | "node": ">= 10"
169 | }
170 | },
171 | "node_modules/@next/swc-win32-arm64-msvc": {
172 | "version": "13.1.4",
173 | "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-13.1.4.tgz",
174 | "integrity": "sha512-+kAXIIVb7Q4LCKmi7dn9qVlG1XUf3Chgj5Rwl0rAP4WBV2TnJIgsOEC24G1Mm3jjif+qXm7SJS9YZ9Yg3Y8sSQ==",
175 | "cpu": [
176 | "arm64"
177 | ],
178 | "optional": true,
179 | "os": [
180 | "win32"
181 | ],
182 | "engines": {
183 | "node": ">= 10"
184 | }
185 | },
186 | "node_modules/@next/swc-win32-ia32-msvc": {
187 | "version": "13.1.4",
188 | "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-13.1.4.tgz",
189 | "integrity": "sha512-EsfzAFBVaw1zg1FzlLMgRaTX/DKY+EnAvJ6mCIJMGeSOPIj4Oy6xF2yEQ3VaRkwFpAafHJH6JNB/CGrdKFCMXw==",
190 | "cpu": [
191 | "ia32"
192 | ],
193 | "optional": true,
194 | "os": [
195 | "win32"
196 | ],
197 | "engines": {
198 | "node": ">= 10"
199 | }
200 | },
201 | "node_modules/@next/swc-win32-x64-msvc": {
202 | "version": "13.1.4",
203 | "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.1.4.tgz",
204 | "integrity": "sha512-bygNjmnq+F9NqJXh7OfhJgqu6LGU29GNKQYVyZkxY/h5K0WWUvAE/VL+TdyMwbvQr9KByx5XLwORwetLxXCo4g==",
205 | "cpu": [
206 | "x64"
207 | ],
208 | "optional": true,
209 | "os": [
210 | "win32"
211 | ],
212 | "engines": {
213 | "node": ">= 10"
214 | }
215 | },
216 | "node_modules/@swc/helpers": {
217 | "version": "0.4.14",
218 | "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.4.14.tgz",
219 | "integrity": "sha512-4C7nX/dvpzB7za4Ql9K81xK3HPxCpHMgwTZVyf+9JQ6VUbn9jjZVN7/Nkdz/Ugzs2CSjqnL/UPXroiVBVHUWUw==",
220 | "dependencies": {
221 | "tslib": "^2.4.0"
222 | }
223 | },
224 | "node_modules/caniuse-lite": {
225 | "version": "1.0.30001447",
226 | "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001447.tgz",
227 | "integrity": "sha512-bdKU1BQDPeEXe9A39xJnGtY0uRq/z5osrnXUw0TcK+EYno45Y+U7QU9HhHEyzvMDffpYadFXi3idnSNkcwLkTw==",
228 | "funding": [
229 | {
230 | "type": "opencollective",
231 | "url": "https://opencollective.com/browserslist"
232 | },
233 | {
234 | "type": "tidelift",
235 | "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
236 | }
237 | ]
238 | },
239 | "node_modules/client-only": {
240 | "version": "0.0.1",
241 | "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz",
242 | "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA=="
243 | },
244 | "node_modules/js-tokens": {
245 | "version": "4.0.0",
246 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
247 | "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
248 | },
249 | "node_modules/loose-envify": {
250 | "version": "1.4.0",
251 | "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
252 | "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
253 | "dependencies": {
254 | "js-tokens": "^3.0.0 || ^4.0.0"
255 | },
256 | "bin": {
257 | "loose-envify": "cli.js"
258 | }
259 | },
260 | "node_modules/nanoid": {
261 | "version": "3.3.4",
262 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz",
263 | "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==",
264 | "bin": {
265 | "nanoid": "bin/nanoid.cjs"
266 | },
267 | "engines": {
268 | "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
269 | }
270 | },
271 | "node_modules/next": {
272 | "version": "13.1.4",
273 | "resolved": "https://registry.npmjs.org/next/-/next-13.1.4.tgz",
274 | "integrity": "sha512-g0oBUU+tcOPKbXTVdsDO2adc6wd/ggqauHHysPQJxuIKqZ+fwICGJht0C5D5V0A/77eQDF5EFwNdAHkFvBDsog==",
275 | "dependencies": {
276 | "@next/env": "13.1.4",
277 | "@swc/helpers": "0.4.14",
278 | "caniuse-lite": "^1.0.30001406",
279 | "postcss": "8.4.14",
280 | "styled-jsx": "5.1.1"
281 | },
282 | "bin": {
283 | "next": "dist/bin/next"
284 | },
285 | "engines": {
286 | "node": ">=14.6.0"
287 | },
288 | "optionalDependencies": {
289 | "@next/swc-android-arm-eabi": "13.1.4",
290 | "@next/swc-android-arm64": "13.1.4",
291 | "@next/swc-darwin-arm64": "13.1.4",
292 | "@next/swc-darwin-x64": "13.1.4",
293 | "@next/swc-freebsd-x64": "13.1.4",
294 | "@next/swc-linux-arm-gnueabihf": "13.1.4",
295 | "@next/swc-linux-arm64-gnu": "13.1.4",
296 | "@next/swc-linux-arm64-musl": "13.1.4",
297 | "@next/swc-linux-x64-gnu": "13.1.4",
298 | "@next/swc-linux-x64-musl": "13.1.4",
299 | "@next/swc-win32-arm64-msvc": "13.1.4",
300 | "@next/swc-win32-ia32-msvc": "13.1.4",
301 | "@next/swc-win32-x64-msvc": "13.1.4"
302 | },
303 | "peerDependencies": {
304 | "fibers": ">= 3.1.0",
305 | "node-sass": "^6.0.0 || ^7.0.0",
306 | "react": "^18.2.0",
307 | "react-dom": "^18.2.0",
308 | "sass": "^1.3.0"
309 | },
310 | "peerDependenciesMeta": {
311 | "fibers": {
312 | "optional": true
313 | },
314 | "node-sass": {
315 | "optional": true
316 | },
317 | "sass": {
318 | "optional": true
319 | }
320 | }
321 | },
322 | "node_modules/picocolors": {
323 | "version": "1.0.0",
324 | "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
325 | "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ=="
326 | },
327 | "node_modules/postcss": {
328 | "version": "8.4.14",
329 | "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.14.tgz",
330 | "integrity": "sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig==",
331 | "funding": [
332 | {
333 | "type": "opencollective",
334 | "url": "https://opencollective.com/postcss/"
335 | },
336 | {
337 | "type": "tidelift",
338 | "url": "https://tidelift.com/funding/github/npm/postcss"
339 | }
340 | ],
341 | "dependencies": {
342 | "nanoid": "^3.3.4",
343 | "picocolors": "^1.0.0",
344 | "source-map-js": "^1.0.2"
345 | },
346 | "engines": {
347 | "node": "^10 || ^12 || >=14"
348 | }
349 | },
350 | "node_modules/react": {
351 | "version": "18.2.0",
352 | "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz",
353 | "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==",
354 | "dependencies": {
355 | "loose-envify": "^1.1.0"
356 | },
357 | "engines": {
358 | "node": ">=0.10.0"
359 | }
360 | },
361 | "node_modules/react-dom": {
362 | "version": "18.2.0",
363 | "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz",
364 | "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==",
365 | "dependencies": {
366 | "loose-envify": "^1.1.0",
367 | "scheduler": "^0.23.0"
368 | },
369 | "peerDependencies": {
370 | "react": "^18.2.0"
371 | }
372 | },
373 | "node_modules/scheduler": {
374 | "version": "0.23.0",
375 | "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz",
376 | "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==",
377 | "dependencies": {
378 | "loose-envify": "^1.1.0"
379 | }
380 | },
381 | "node_modules/source-map-js": {
382 | "version": "1.0.2",
383 | "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
384 | "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
385 | "engines": {
386 | "node": ">=0.10.0"
387 | }
388 | },
389 | "node_modules/styled-jsx": {
390 | "version": "5.1.1",
391 | "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.1.tgz",
392 | "integrity": "sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==",
393 | "dependencies": {
394 | "client-only": "0.0.1"
395 | },
396 | "engines": {
397 | "node": ">= 12.0.0"
398 | },
399 | "peerDependencies": {
400 | "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0"
401 | },
402 | "peerDependenciesMeta": {
403 | "@babel/core": {
404 | "optional": true
405 | },
406 | "babel-plugin-macros": {
407 | "optional": true
408 | }
409 | }
410 | },
411 | "node_modules/tslib": {
412 | "version": "2.4.1",
413 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz",
414 | "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA=="
415 | }
416 | }
417 | }
418 |
--------------------------------------------------------------------------------
/01-css-in-js/after/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "01-css-in-js",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "dev": "next dev",
7 | "build": "next build",
8 | "start": "next start"
9 | },
10 | "dependencies": {
11 | "next": "13.1.4",
12 | "react": "18.2.0",
13 | "react-dom": "18.2.0"
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/01-css-in-js/after/public/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jaketrent/styling-react-components/cdcae8c2ab0dd85f3d110a2eba56c523e6eff795/01-css-in-js/after/public/favicon.png
--------------------------------------------------------------------------------
/01-css-in-js/after/src/components/App.js:
--------------------------------------------------------------------------------
1 | import Head from 'next/head'
2 |
3 | import Newsletter from "./Newsletter.js";
4 |
5 | function App() {
6 | return (
7 |
8 |
9 |
10 |
CSS-in-JS Example
11 |
12 |
13 |
20 |
21 | );
22 | }
23 |
24 | export default App;
25 |
--------------------------------------------------------------------------------
/01-css-in-js/after/src/components/Newsletter.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | const color = {
4 | spectrum1: "#ff598a",
5 | spectrum2: "#de56e8",
6 | spectrum3: "#b36bff",
7 | spectrum4: "#5b56e8",
8 | spectrum5: "#5e9fff",
9 | };
10 |
11 | export default function Newsletter() {
12 | const [email, setEmail] = React.useState("");
13 | const emailPartsCount = countEmailParts(email);
14 | return (
15 |
16 |
17 | {Array.from(Array(5)).map((_, i) => (
18 |
19 | ))}
20 |
21 |
22 | Get the newsletter
23 |
24 | setEmail(evt.target.value)}
29 | />
30 | = 5}>Sign up
31 |
32 | );
33 | }
34 |
35 | function Container(props) {
36 | return (
37 |
38 | {props.children}
39 |
56 |
57 | );
58 | }
59 |
60 | function Header(props) {
61 | return (
62 |
63 | {props.children}
64 |
78 |
79 | );
80 | }
81 |
82 | function Email(props) {
83 | return (
84 | <>
85 |
86 |
104 | >
105 | );
106 | }
107 |
108 | function Submit(props) {
109 | return (
110 |
157 | );
158 | }
159 |
160 | function Spectrum(props) {
161 | return (
162 |
163 | {props.children}
164 |
178 |
179 | );
180 | }
181 |
182 | function Bar(props) {
183 | return (
184 |
185 |
224 |
225 | );
226 | }
227 |
228 | function countEmailParts(email) {
229 | if (/@.+\..{2,}$/.test(email)) {
230 | return 5;
231 | } else if (/@.+\..?$/.test(email)) {
232 | return 4;
233 | } else if (/@.+$/.test(email)) {
234 | return 3;
235 | } else if (/@/.test(email)) {
236 | return 2;
237 | } else if (/.+/.test(email)) {
238 | return 1;
239 | } else {
240 | return 0;
241 | }
242 | }
243 |
--------------------------------------------------------------------------------
/01-css-in-js/after/src/components/index.css:
--------------------------------------------------------------------------------
1 | * {
2 | box-sizing: border-box;
3 | }
4 | body {
5 | margin: 0;
6 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
7 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
8 | sans-serif;
9 | -webkit-font-smoothing: antialiased;
10 | -moz-osx-font-smoothing: grayscale;
11 | background: #070222;
12 | color: #fff;
13 | font-size: 18px;
14 | }
15 |
--------------------------------------------------------------------------------
/01-css-in-js/after/src/pages/_app.js:
--------------------------------------------------------------------------------
1 | import '../components/index.css'
2 |
3 | export default function App({ Component, pageProps }) {
4 | return
5 | }
6 |
--------------------------------------------------------------------------------
/01-css-in-js/after/src/pages/index.js:
--------------------------------------------------------------------------------
1 | import App from "../components/App.js";
2 |
3 | export default function Home() {
4 | return ;
5 | }
6 |
--------------------------------------------------------------------------------
/01-css-in-js/before/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # next.js
12 | /.next/
13 | /out/
14 |
15 | # production
16 | /build
17 |
18 | # misc
19 | .DS_Store
20 | *.pem
21 |
22 | # debug
23 | npm-debug.log*
24 | yarn-debug.log*
25 | yarn-error.log*
26 | .pnpm-debug.log*
27 |
28 | # local env files
29 | .env*.local
30 |
31 | # vercel
32 | .vercel
33 |
--------------------------------------------------------------------------------
/01-css-in-js/before/next.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | const nextConfig = {
3 | reactStrictMode: true,
4 | }
5 |
6 | module.exports = nextConfig
7 |
--------------------------------------------------------------------------------
/01-css-in-js/before/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "01-css-in-js",
3 | "version": "0.1.0",
4 | "lockfileVersion": 3,
5 | "requires": true,
6 | "packages": {
7 | "": {
8 | "name": "01-css-in-js",
9 | "version": "0.1.0",
10 | "dependencies": {
11 | "next": "13.1.4",
12 | "react": "18.2.0",
13 | "react-dom": "18.2.0"
14 | }
15 | },
16 | "node_modules/@next/env": {
17 | "version": "13.1.4",
18 | "resolved": "https://registry.npmjs.org/@next/env/-/env-13.1.4.tgz",
19 | "integrity": "sha512-x7ydhMpi9/xX7yVK+Fw33OuwwQWVZUFRxenK3z89fmPzQZyUk35Ynb+b7JkrhfRhDIFFvvqpzVSXeseSlBAw7A=="
20 | },
21 | "node_modules/@next/swc-android-arm-eabi": {
22 | "version": "13.1.4",
23 | "resolved": "https://registry.npmjs.org/@next/swc-android-arm-eabi/-/swc-android-arm-eabi-13.1.4.tgz",
24 | "integrity": "sha512-5PAchzFst3In6Ml+9APvBj89H29lcPXcUqEYBVv09fWK/V4IuViKc2qOqM9pyPyw7KsqaZPmuqaG595E6jdZLA==",
25 | "cpu": [
26 | "arm"
27 | ],
28 | "optional": true,
29 | "os": [
30 | "android"
31 | ],
32 | "engines": {
33 | "node": ">= 10"
34 | }
35 | },
36 | "node_modules/@next/swc-android-arm64": {
37 | "version": "13.1.4",
38 | "resolved": "https://registry.npmjs.org/@next/swc-android-arm64/-/swc-android-arm64-13.1.4.tgz",
39 | "integrity": "sha512-LCLjjRhsQ5fR9ExzR2fqxuyJe/D4Ct/YkdonVfJfqOfkEpFwUTQDOVo5GrQec4LZDk3zY+o6vZYjXbB0nD9VLA==",
40 | "cpu": [
41 | "arm64"
42 | ],
43 | "optional": true,
44 | "os": [
45 | "android"
46 | ],
47 | "engines": {
48 | "node": ">= 10"
49 | }
50 | },
51 | "node_modules/@next/swc-darwin-arm64": {
52 | "version": "13.1.4",
53 | "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-13.1.4.tgz",
54 | "integrity": "sha512-LSc/tF1FQ1y1SwKiCdGg8IIl7+Csk6nuLcLIyQXs24UNYjXg5+7vUQXqE8y66v/Dq8qFDC9rM61QhpM9ZDftbg==",
55 | "cpu": [
56 | "arm64"
57 | ],
58 | "optional": true,
59 | "os": [
60 | "darwin"
61 | ],
62 | "engines": {
63 | "node": ">= 10"
64 | }
65 | },
66 | "node_modules/@next/swc-darwin-x64": {
67 | "version": "13.1.4",
68 | "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-13.1.4.tgz",
69 | "integrity": "sha512-WoApDo8xfafrNc9+Mz5MwGFKUwbDHsGqLleTGZ8upegwVqDyHsYzqJQudf+loqhV58oGTOqP1eWaHn2J7dijXA==",
70 | "cpu": [
71 | "x64"
72 | ],
73 | "optional": true,
74 | "os": [
75 | "darwin"
76 | ],
77 | "engines": {
78 | "node": ">= 10"
79 | }
80 | },
81 | "node_modules/@next/swc-freebsd-x64": {
82 | "version": "13.1.4",
83 | "resolved": "https://registry.npmjs.org/@next/swc-freebsd-x64/-/swc-freebsd-x64-13.1.4.tgz",
84 | "integrity": "sha512-fqNyeT8G4guN8AHPIoBRhGY2GJg89FyWpuwX4o0Y3vUy/84IGZpNst3paCzaYkQSqQE/AuCpkB7hKxkN7ittXw==",
85 | "cpu": [
86 | "x64"
87 | ],
88 | "optional": true,
89 | "os": [
90 | "freebsd"
91 | ],
92 | "engines": {
93 | "node": ">= 10"
94 | }
95 | },
96 | "node_modules/@next/swc-linux-arm-gnueabihf": {
97 | "version": "13.1.4",
98 | "resolved": "https://registry.npmjs.org/@next/swc-linux-arm-gnueabihf/-/swc-linux-arm-gnueabihf-13.1.4.tgz",
99 | "integrity": "sha512-MEfm8OC1YR9/tYHUzlQsxcSmiuf8XdO7bqh5VtG4pilScjc5I5t+tQgIDgoDGePfh5W99W23hb3s6oCFrt99rw==",
100 | "cpu": [
101 | "arm"
102 | ],
103 | "optional": true,
104 | "os": [
105 | "linux"
106 | ],
107 | "engines": {
108 | "node": ">= 10"
109 | }
110 | },
111 | "node_modules/@next/swc-linux-arm64-gnu": {
112 | "version": "13.1.4",
113 | "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-13.1.4.tgz",
114 | "integrity": "sha512-2wgth/KsuODzW/E7jsRoWdhKmE5oZzXcBPvf9RW+ZpBNvYQkEDlzfLA7n8DtxTU8I4oMas0mdEPdCWXrSNnVZw==",
115 | "cpu": [
116 | "arm64"
117 | ],
118 | "optional": true,
119 | "os": [
120 | "linux"
121 | ],
122 | "engines": {
123 | "node": ">= 10"
124 | }
125 | },
126 | "node_modules/@next/swc-linux-arm64-musl": {
127 | "version": "13.1.4",
128 | "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-13.1.4.tgz",
129 | "integrity": "sha512-GdWhCRljsT7rNEElEsdu4RRppd+XaQOX1IJslsh/+HU6LsJGUE8tXpa68yJjCsHZHifkbdZNeCr5SYdsN6CbAA==",
130 | "cpu": [
131 | "arm64"
132 | ],
133 | "optional": true,
134 | "os": [
135 | "linux"
136 | ],
137 | "engines": {
138 | "node": ">= 10"
139 | }
140 | },
141 | "node_modules/@next/swc-linux-x64-gnu": {
142 | "version": "13.1.4",
143 | "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-13.1.4.tgz",
144 | "integrity": "sha512-Rsk/ojwYqMskN2eo5hUSVe7UuMV/aSjmrmJ0BCFGFPfBY9sPgmYj/oXlDDN0y5lJD9acPuiBjknLWgnOnx5JIA==",
145 | "cpu": [
146 | "x64"
147 | ],
148 | "optional": true,
149 | "os": [
150 | "linux"
151 | ],
152 | "engines": {
153 | "node": ">= 10"
154 | }
155 | },
156 | "node_modules/@next/swc-linux-x64-musl": {
157 | "version": "13.1.4",
158 | "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-13.1.4.tgz",
159 | "integrity": "sha512-gKSVPozedA2gpA+vggYnAqpDuzWFed2oxFeXxHw0aW2ALdAZswAinn1ZwXEQ5fHnVguxjZhH0+2nBxpMdF8p5Q==",
160 | "cpu": [
161 | "x64"
162 | ],
163 | "optional": true,
164 | "os": [
165 | "linux"
166 | ],
167 | "engines": {
168 | "node": ">= 10"
169 | }
170 | },
171 | "node_modules/@next/swc-win32-arm64-msvc": {
172 | "version": "13.1.4",
173 | "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-13.1.4.tgz",
174 | "integrity": "sha512-+kAXIIVb7Q4LCKmi7dn9qVlG1XUf3Chgj5Rwl0rAP4WBV2TnJIgsOEC24G1Mm3jjif+qXm7SJS9YZ9Yg3Y8sSQ==",
175 | "cpu": [
176 | "arm64"
177 | ],
178 | "optional": true,
179 | "os": [
180 | "win32"
181 | ],
182 | "engines": {
183 | "node": ">= 10"
184 | }
185 | },
186 | "node_modules/@next/swc-win32-ia32-msvc": {
187 | "version": "13.1.4",
188 | "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-13.1.4.tgz",
189 | "integrity": "sha512-EsfzAFBVaw1zg1FzlLMgRaTX/DKY+EnAvJ6mCIJMGeSOPIj4Oy6xF2yEQ3VaRkwFpAafHJH6JNB/CGrdKFCMXw==",
190 | "cpu": [
191 | "ia32"
192 | ],
193 | "optional": true,
194 | "os": [
195 | "win32"
196 | ],
197 | "engines": {
198 | "node": ">= 10"
199 | }
200 | },
201 | "node_modules/@next/swc-win32-x64-msvc": {
202 | "version": "13.1.4",
203 | "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.1.4.tgz",
204 | "integrity": "sha512-bygNjmnq+F9NqJXh7OfhJgqu6LGU29GNKQYVyZkxY/h5K0WWUvAE/VL+TdyMwbvQr9KByx5XLwORwetLxXCo4g==",
205 | "cpu": [
206 | "x64"
207 | ],
208 | "optional": true,
209 | "os": [
210 | "win32"
211 | ],
212 | "engines": {
213 | "node": ">= 10"
214 | }
215 | },
216 | "node_modules/@swc/helpers": {
217 | "version": "0.4.14",
218 | "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.4.14.tgz",
219 | "integrity": "sha512-4C7nX/dvpzB7za4Ql9K81xK3HPxCpHMgwTZVyf+9JQ6VUbn9jjZVN7/Nkdz/Ugzs2CSjqnL/UPXroiVBVHUWUw==",
220 | "dependencies": {
221 | "tslib": "^2.4.0"
222 | }
223 | },
224 | "node_modules/caniuse-lite": {
225 | "version": "1.0.30001447",
226 | "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001447.tgz",
227 | "integrity": "sha512-bdKU1BQDPeEXe9A39xJnGtY0uRq/z5osrnXUw0TcK+EYno45Y+U7QU9HhHEyzvMDffpYadFXi3idnSNkcwLkTw==",
228 | "funding": [
229 | {
230 | "type": "opencollective",
231 | "url": "https://opencollective.com/browserslist"
232 | },
233 | {
234 | "type": "tidelift",
235 | "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
236 | }
237 | ]
238 | },
239 | "node_modules/client-only": {
240 | "version": "0.0.1",
241 | "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz",
242 | "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA=="
243 | },
244 | "node_modules/js-tokens": {
245 | "version": "4.0.0",
246 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
247 | "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
248 | },
249 | "node_modules/loose-envify": {
250 | "version": "1.4.0",
251 | "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
252 | "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
253 | "dependencies": {
254 | "js-tokens": "^3.0.0 || ^4.0.0"
255 | },
256 | "bin": {
257 | "loose-envify": "cli.js"
258 | }
259 | },
260 | "node_modules/nanoid": {
261 | "version": "3.3.4",
262 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz",
263 | "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==",
264 | "bin": {
265 | "nanoid": "bin/nanoid.cjs"
266 | },
267 | "engines": {
268 | "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
269 | }
270 | },
271 | "node_modules/next": {
272 | "version": "13.1.4",
273 | "resolved": "https://registry.npmjs.org/next/-/next-13.1.4.tgz",
274 | "integrity": "sha512-g0oBUU+tcOPKbXTVdsDO2adc6wd/ggqauHHysPQJxuIKqZ+fwICGJht0C5D5V0A/77eQDF5EFwNdAHkFvBDsog==",
275 | "dependencies": {
276 | "@next/env": "13.1.4",
277 | "@swc/helpers": "0.4.14",
278 | "caniuse-lite": "^1.0.30001406",
279 | "postcss": "8.4.14",
280 | "styled-jsx": "5.1.1"
281 | },
282 | "bin": {
283 | "next": "dist/bin/next"
284 | },
285 | "engines": {
286 | "node": ">=14.6.0"
287 | },
288 | "optionalDependencies": {
289 | "@next/swc-android-arm-eabi": "13.1.4",
290 | "@next/swc-android-arm64": "13.1.4",
291 | "@next/swc-darwin-arm64": "13.1.4",
292 | "@next/swc-darwin-x64": "13.1.4",
293 | "@next/swc-freebsd-x64": "13.1.4",
294 | "@next/swc-linux-arm-gnueabihf": "13.1.4",
295 | "@next/swc-linux-arm64-gnu": "13.1.4",
296 | "@next/swc-linux-arm64-musl": "13.1.4",
297 | "@next/swc-linux-x64-gnu": "13.1.4",
298 | "@next/swc-linux-x64-musl": "13.1.4",
299 | "@next/swc-win32-arm64-msvc": "13.1.4",
300 | "@next/swc-win32-ia32-msvc": "13.1.4",
301 | "@next/swc-win32-x64-msvc": "13.1.4"
302 | },
303 | "peerDependencies": {
304 | "fibers": ">= 3.1.0",
305 | "node-sass": "^6.0.0 || ^7.0.0",
306 | "react": "^18.2.0",
307 | "react-dom": "^18.2.0",
308 | "sass": "^1.3.0"
309 | },
310 | "peerDependenciesMeta": {
311 | "fibers": {
312 | "optional": true
313 | },
314 | "node-sass": {
315 | "optional": true
316 | },
317 | "sass": {
318 | "optional": true
319 | }
320 | }
321 | },
322 | "node_modules/picocolors": {
323 | "version": "1.0.0",
324 | "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
325 | "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ=="
326 | },
327 | "node_modules/postcss": {
328 | "version": "8.4.14",
329 | "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.14.tgz",
330 | "integrity": "sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig==",
331 | "funding": [
332 | {
333 | "type": "opencollective",
334 | "url": "https://opencollective.com/postcss/"
335 | },
336 | {
337 | "type": "tidelift",
338 | "url": "https://tidelift.com/funding/github/npm/postcss"
339 | }
340 | ],
341 | "dependencies": {
342 | "nanoid": "^3.3.4",
343 | "picocolors": "^1.0.0",
344 | "source-map-js": "^1.0.2"
345 | },
346 | "engines": {
347 | "node": "^10 || ^12 || >=14"
348 | }
349 | },
350 | "node_modules/react": {
351 | "version": "18.2.0",
352 | "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz",
353 | "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==",
354 | "dependencies": {
355 | "loose-envify": "^1.1.0"
356 | },
357 | "engines": {
358 | "node": ">=0.10.0"
359 | }
360 | },
361 | "node_modules/react-dom": {
362 | "version": "18.2.0",
363 | "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz",
364 | "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==",
365 | "dependencies": {
366 | "loose-envify": "^1.1.0",
367 | "scheduler": "^0.23.0"
368 | },
369 | "peerDependencies": {
370 | "react": "^18.2.0"
371 | }
372 | },
373 | "node_modules/scheduler": {
374 | "version": "0.23.0",
375 | "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz",
376 | "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==",
377 | "dependencies": {
378 | "loose-envify": "^1.1.0"
379 | }
380 | },
381 | "node_modules/source-map-js": {
382 | "version": "1.0.2",
383 | "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
384 | "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
385 | "engines": {
386 | "node": ">=0.10.0"
387 | }
388 | },
389 | "node_modules/styled-jsx": {
390 | "version": "5.1.1",
391 | "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.1.tgz",
392 | "integrity": "sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==",
393 | "dependencies": {
394 | "client-only": "0.0.1"
395 | },
396 | "engines": {
397 | "node": ">= 12.0.0"
398 | },
399 | "peerDependencies": {
400 | "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0"
401 | },
402 | "peerDependenciesMeta": {
403 | "@babel/core": {
404 | "optional": true
405 | },
406 | "babel-plugin-macros": {
407 | "optional": true
408 | }
409 | }
410 | },
411 | "node_modules/tslib": {
412 | "version": "2.4.1",
413 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz",
414 | "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA=="
415 | }
416 | }
417 | }
418 |
--------------------------------------------------------------------------------
/01-css-in-js/before/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "01-css-in-js",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "dev": "next dev",
7 | "build": "next build",
8 | "start": "next start"
9 | },
10 | "dependencies": {
11 | "next": "13.1.4",
12 | "react": "18.2.0",
13 | "react-dom": "18.2.0"
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/01-css-in-js/before/public/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jaketrent/styling-react-components/cdcae8c2ab0dd85f3d110a2eba56c523e6eff795/01-css-in-js/before/public/favicon.png
--------------------------------------------------------------------------------
/01-css-in-js/before/src/components/App.js:
--------------------------------------------------------------------------------
1 | import Head from 'next/head'
2 |
3 | import Newsletter from "./Newsletter.js";
4 |
5 | function App() {
6 | return (
7 |
8 |
9 |
10 |
CSS-in-JS Example
11 |
12 |
13 |
20 |
21 | );
22 | }
23 |
24 | export default App;
25 |
--------------------------------------------------------------------------------
/01-css-in-js/before/src/components/Newsletter.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | const color = {
4 | spectrum1: "#ff598a",
5 | spectrum2: "#de56e8",
6 | spectrum3: "#b36bff",
7 | spectrum4: "#5b56e8",
8 | spectrum5: "#5e9fff",
9 | };
10 |
11 | export default function Newsletter() {
12 | const [email, setEmail] = React.useState("");
13 | const emailPartsCount = countEmailParts(email);
14 | return (
15 |
16 |
17 | {Array.from(Array(5)).map((_, i) => (
18 |
19 | ))}
20 |
21 |
22 | Get the newsletter
23 |
24 | setEmail(evt.target.value)}
29 | />
30 | = 5}>Sign up
31 |
32 | );
33 | }
34 |
35 | function Container(props) {
36 | return (
37 |
38 | {props.children}
39 |
51 |
52 | );
53 | }
54 |
55 | function Header(props) {
56 | return (
57 |
58 | {props.children}
59 |
71 |
72 | );
73 | }
74 |
75 | function Email(props) {
76 | return (
77 | <>
78 |
79 |
94 | >
95 | );
96 | }
97 |
98 | function Submit(props) {
99 | return (
100 |
141 | );
142 | }
143 |
144 | function Spectrum(props) {
145 | return (
146 |
147 | {props.children}
148 |
162 |
163 | );
164 | }
165 |
166 | function Bar(props) {
167 | return (
168 |
169 |
200 |
201 | );
202 | }
203 |
204 | function countEmailParts(email) {
205 | if (/@.+\..{2,}$/.test(email)) {
206 | return 5;
207 | } else if (/@.+\..?$/.test(email)) {
208 | return 4;
209 | } else if (/@.+$/.test(email)) {
210 | return 3;
211 | } else if (/@/.test(email)) {
212 | return 2;
213 | } else if (/.+/.test(email)) {
214 | return 1;
215 | } else {
216 | return 0;
217 | }
218 | }
219 |
--------------------------------------------------------------------------------
/01-css-in-js/before/src/components/index.css:
--------------------------------------------------------------------------------
1 | * {
2 | box-sizing: border-box;
3 | }
4 | body {
5 | margin: 0;
6 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
7 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
8 | sans-serif;
9 | -webkit-font-smoothing: antialiased;
10 | -moz-osx-font-smoothing: grayscale;
11 | background: #070222;
12 | color: #fff;
13 | font-size: 18px;
14 | }
15 |
--------------------------------------------------------------------------------
/01-css-in-js/before/src/pages/_app.js:
--------------------------------------------------------------------------------
1 | import '../components/index.css'
2 |
3 | export default function App({ Component, pageProps }) {
4 | return
5 | }
6 |
--------------------------------------------------------------------------------
/01-css-in-js/before/src/pages/index.js:
--------------------------------------------------------------------------------
1 | import App from '../components/App.js'
2 |
3 | export default function Home() {
4 | return
5 | }
6 |
--------------------------------------------------------------------------------
/01-css-in-js/snippets.css:
--------------------------------------------------------------------------------
1 | /* 1-1 */
2 | @media (min-width: 800px) {
3 | section {
4 | font-size: 2.25em;
5 | max-width: 700px;
6 | }
7 | }
8 |
9 | /* 1-2 */
10 | header :global(h2) {
11 | margin: 0 0 0.5em 0;
12 | }
13 |
14 | /* 1-3 */
15 | input:focus {
16 | outline: 2px solid #fff;
17 | outline-offset: 0.15em;
18 | }
19 |
20 | /* 1-4 */
21 | height: ${props.active ? "auto" : "0"};
22 | width: ${props.active ? "auto" : "0"};
23 | font-size: ${props.active ? "1em" : "0"};
24 | padding: ${props.active ? "0.25em 1em" : "0"};
25 |
26 |
27 | /* 1-4 alternate */
28 | ${props.active
29 | ? `
30 | height: auto;
31 | width: auto;
32 | font-size: 1em;
33 | padding: 0.25em 1em;
34 | `
35 | : `
36 | height: 0;
37 | width: 0;
38 | font-size: 0;
39 | padding: 0;
40 | `}
41 |
42 | /* 1-5 */
43 | ${props.active
44 | ? `etc...`
45 | : ''}
46 |
47 | /* 1-6 */
48 | height: ${props.active ? "100%" : "0.5em"};
49 |
50 | /* 1-7 */
51 | animation: jitter 350ms ease-out infinite alternate;
52 |
53 | @keyframes jitter {
54 | 0% {
55 | transform: scaleY(1);
56 | }
57 | 100% {
58 | transform: scaleY(0.9);
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/02-css-modules/after/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # next.js
12 | /.next/
13 | /out/
14 |
15 | # production
16 | /build
17 |
18 | # misc
19 | .DS_Store
20 | *.pem
21 |
22 | # debug
23 | npm-debug.log*
24 | yarn-debug.log*
25 | yarn-error.log*
26 | .pnpm-debug.log*
27 |
28 | # local env files
29 | .env*.local
30 |
31 | # vercel
32 | .vercel
33 |
--------------------------------------------------------------------------------
/02-css-modules/after/next.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | const nextConfig = {
3 | reactStrictMode: true,
4 | }
5 |
6 | module.exports = nextConfig
7 |
--------------------------------------------------------------------------------
/02-css-modules/after/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "01-css-in-js",
3 | "version": "0.1.0",
4 | "lockfileVersion": 3,
5 | "requires": true,
6 | "packages": {
7 | "": {
8 | "name": "01-css-in-js",
9 | "version": "0.1.0",
10 | "dependencies": {
11 | "next": "13.1.4",
12 | "react": "18.2.0",
13 | "react-dom": "18.2.0"
14 | }
15 | },
16 | "node_modules/@next/env": {
17 | "version": "13.1.4",
18 | "resolved": "https://registry.npmjs.org/@next/env/-/env-13.1.4.tgz",
19 | "integrity": "sha512-x7ydhMpi9/xX7yVK+Fw33OuwwQWVZUFRxenK3z89fmPzQZyUk35Ynb+b7JkrhfRhDIFFvvqpzVSXeseSlBAw7A=="
20 | },
21 | "node_modules/@next/swc-android-arm-eabi": {
22 | "version": "13.1.4",
23 | "resolved": "https://registry.npmjs.org/@next/swc-android-arm-eabi/-/swc-android-arm-eabi-13.1.4.tgz",
24 | "integrity": "sha512-5PAchzFst3In6Ml+9APvBj89H29lcPXcUqEYBVv09fWK/V4IuViKc2qOqM9pyPyw7KsqaZPmuqaG595E6jdZLA==",
25 | "cpu": [
26 | "arm"
27 | ],
28 | "optional": true,
29 | "os": [
30 | "android"
31 | ],
32 | "engines": {
33 | "node": ">= 10"
34 | }
35 | },
36 | "node_modules/@next/swc-android-arm64": {
37 | "version": "13.1.4",
38 | "resolved": "https://registry.npmjs.org/@next/swc-android-arm64/-/swc-android-arm64-13.1.4.tgz",
39 | "integrity": "sha512-LCLjjRhsQ5fR9ExzR2fqxuyJe/D4Ct/YkdonVfJfqOfkEpFwUTQDOVo5GrQec4LZDk3zY+o6vZYjXbB0nD9VLA==",
40 | "cpu": [
41 | "arm64"
42 | ],
43 | "optional": true,
44 | "os": [
45 | "android"
46 | ],
47 | "engines": {
48 | "node": ">= 10"
49 | }
50 | },
51 | "node_modules/@next/swc-darwin-arm64": {
52 | "version": "13.1.4",
53 | "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-13.1.4.tgz",
54 | "integrity": "sha512-LSc/tF1FQ1y1SwKiCdGg8IIl7+Csk6nuLcLIyQXs24UNYjXg5+7vUQXqE8y66v/Dq8qFDC9rM61QhpM9ZDftbg==",
55 | "cpu": [
56 | "arm64"
57 | ],
58 | "optional": true,
59 | "os": [
60 | "darwin"
61 | ],
62 | "engines": {
63 | "node": ">= 10"
64 | }
65 | },
66 | "node_modules/@next/swc-darwin-x64": {
67 | "version": "13.1.4",
68 | "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-13.1.4.tgz",
69 | "integrity": "sha512-WoApDo8xfafrNc9+Mz5MwGFKUwbDHsGqLleTGZ8upegwVqDyHsYzqJQudf+loqhV58oGTOqP1eWaHn2J7dijXA==",
70 | "cpu": [
71 | "x64"
72 | ],
73 | "optional": true,
74 | "os": [
75 | "darwin"
76 | ],
77 | "engines": {
78 | "node": ">= 10"
79 | }
80 | },
81 | "node_modules/@next/swc-freebsd-x64": {
82 | "version": "13.1.4",
83 | "resolved": "https://registry.npmjs.org/@next/swc-freebsd-x64/-/swc-freebsd-x64-13.1.4.tgz",
84 | "integrity": "sha512-fqNyeT8G4guN8AHPIoBRhGY2GJg89FyWpuwX4o0Y3vUy/84IGZpNst3paCzaYkQSqQE/AuCpkB7hKxkN7ittXw==",
85 | "cpu": [
86 | "x64"
87 | ],
88 | "optional": true,
89 | "os": [
90 | "freebsd"
91 | ],
92 | "engines": {
93 | "node": ">= 10"
94 | }
95 | },
96 | "node_modules/@next/swc-linux-arm-gnueabihf": {
97 | "version": "13.1.4",
98 | "resolved": "https://registry.npmjs.org/@next/swc-linux-arm-gnueabihf/-/swc-linux-arm-gnueabihf-13.1.4.tgz",
99 | "integrity": "sha512-MEfm8OC1YR9/tYHUzlQsxcSmiuf8XdO7bqh5VtG4pilScjc5I5t+tQgIDgoDGePfh5W99W23hb3s6oCFrt99rw==",
100 | "cpu": [
101 | "arm"
102 | ],
103 | "optional": true,
104 | "os": [
105 | "linux"
106 | ],
107 | "engines": {
108 | "node": ">= 10"
109 | }
110 | },
111 | "node_modules/@next/swc-linux-arm64-gnu": {
112 | "version": "13.1.4",
113 | "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-13.1.4.tgz",
114 | "integrity": "sha512-2wgth/KsuODzW/E7jsRoWdhKmE5oZzXcBPvf9RW+ZpBNvYQkEDlzfLA7n8DtxTU8I4oMas0mdEPdCWXrSNnVZw==",
115 | "cpu": [
116 | "arm64"
117 | ],
118 | "optional": true,
119 | "os": [
120 | "linux"
121 | ],
122 | "engines": {
123 | "node": ">= 10"
124 | }
125 | },
126 | "node_modules/@next/swc-linux-arm64-musl": {
127 | "version": "13.1.4",
128 | "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-13.1.4.tgz",
129 | "integrity": "sha512-GdWhCRljsT7rNEElEsdu4RRppd+XaQOX1IJslsh/+HU6LsJGUE8tXpa68yJjCsHZHifkbdZNeCr5SYdsN6CbAA==",
130 | "cpu": [
131 | "arm64"
132 | ],
133 | "optional": true,
134 | "os": [
135 | "linux"
136 | ],
137 | "engines": {
138 | "node": ">= 10"
139 | }
140 | },
141 | "node_modules/@next/swc-linux-x64-gnu": {
142 | "version": "13.1.4",
143 | "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-13.1.4.tgz",
144 | "integrity": "sha512-Rsk/ojwYqMskN2eo5hUSVe7UuMV/aSjmrmJ0BCFGFPfBY9sPgmYj/oXlDDN0y5lJD9acPuiBjknLWgnOnx5JIA==",
145 | "cpu": [
146 | "x64"
147 | ],
148 | "optional": true,
149 | "os": [
150 | "linux"
151 | ],
152 | "engines": {
153 | "node": ">= 10"
154 | }
155 | },
156 | "node_modules/@next/swc-linux-x64-musl": {
157 | "version": "13.1.4",
158 | "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-13.1.4.tgz",
159 | "integrity": "sha512-gKSVPozedA2gpA+vggYnAqpDuzWFed2oxFeXxHw0aW2ALdAZswAinn1ZwXEQ5fHnVguxjZhH0+2nBxpMdF8p5Q==",
160 | "cpu": [
161 | "x64"
162 | ],
163 | "optional": true,
164 | "os": [
165 | "linux"
166 | ],
167 | "engines": {
168 | "node": ">= 10"
169 | }
170 | },
171 | "node_modules/@next/swc-win32-arm64-msvc": {
172 | "version": "13.1.4",
173 | "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-13.1.4.tgz",
174 | "integrity": "sha512-+kAXIIVb7Q4LCKmi7dn9qVlG1XUf3Chgj5Rwl0rAP4WBV2TnJIgsOEC24G1Mm3jjif+qXm7SJS9YZ9Yg3Y8sSQ==",
175 | "cpu": [
176 | "arm64"
177 | ],
178 | "optional": true,
179 | "os": [
180 | "win32"
181 | ],
182 | "engines": {
183 | "node": ">= 10"
184 | }
185 | },
186 | "node_modules/@next/swc-win32-ia32-msvc": {
187 | "version": "13.1.4",
188 | "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-13.1.4.tgz",
189 | "integrity": "sha512-EsfzAFBVaw1zg1FzlLMgRaTX/DKY+EnAvJ6mCIJMGeSOPIj4Oy6xF2yEQ3VaRkwFpAafHJH6JNB/CGrdKFCMXw==",
190 | "cpu": [
191 | "ia32"
192 | ],
193 | "optional": true,
194 | "os": [
195 | "win32"
196 | ],
197 | "engines": {
198 | "node": ">= 10"
199 | }
200 | },
201 | "node_modules/@next/swc-win32-x64-msvc": {
202 | "version": "13.1.4",
203 | "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.1.4.tgz",
204 | "integrity": "sha512-bygNjmnq+F9NqJXh7OfhJgqu6LGU29GNKQYVyZkxY/h5K0WWUvAE/VL+TdyMwbvQr9KByx5XLwORwetLxXCo4g==",
205 | "cpu": [
206 | "x64"
207 | ],
208 | "optional": true,
209 | "os": [
210 | "win32"
211 | ],
212 | "engines": {
213 | "node": ">= 10"
214 | }
215 | },
216 | "node_modules/@swc/helpers": {
217 | "version": "0.4.14",
218 | "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.4.14.tgz",
219 | "integrity": "sha512-4C7nX/dvpzB7za4Ql9K81xK3HPxCpHMgwTZVyf+9JQ6VUbn9jjZVN7/Nkdz/Ugzs2CSjqnL/UPXroiVBVHUWUw==",
220 | "dependencies": {
221 | "tslib": "^2.4.0"
222 | }
223 | },
224 | "node_modules/caniuse-lite": {
225 | "version": "1.0.30001447",
226 | "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001447.tgz",
227 | "integrity": "sha512-bdKU1BQDPeEXe9A39xJnGtY0uRq/z5osrnXUw0TcK+EYno45Y+U7QU9HhHEyzvMDffpYadFXi3idnSNkcwLkTw==",
228 | "funding": [
229 | {
230 | "type": "opencollective",
231 | "url": "https://opencollective.com/browserslist"
232 | },
233 | {
234 | "type": "tidelift",
235 | "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
236 | }
237 | ]
238 | },
239 | "node_modules/client-only": {
240 | "version": "0.0.1",
241 | "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz",
242 | "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA=="
243 | },
244 | "node_modules/js-tokens": {
245 | "version": "4.0.0",
246 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
247 | "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
248 | },
249 | "node_modules/loose-envify": {
250 | "version": "1.4.0",
251 | "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
252 | "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
253 | "dependencies": {
254 | "js-tokens": "^3.0.0 || ^4.0.0"
255 | },
256 | "bin": {
257 | "loose-envify": "cli.js"
258 | }
259 | },
260 | "node_modules/nanoid": {
261 | "version": "3.3.4",
262 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz",
263 | "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==",
264 | "bin": {
265 | "nanoid": "bin/nanoid.cjs"
266 | },
267 | "engines": {
268 | "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
269 | }
270 | },
271 | "node_modules/next": {
272 | "version": "13.1.4",
273 | "resolved": "https://registry.npmjs.org/next/-/next-13.1.4.tgz",
274 | "integrity": "sha512-g0oBUU+tcOPKbXTVdsDO2adc6wd/ggqauHHysPQJxuIKqZ+fwICGJht0C5D5V0A/77eQDF5EFwNdAHkFvBDsog==",
275 | "dependencies": {
276 | "@next/env": "13.1.4",
277 | "@swc/helpers": "0.4.14",
278 | "caniuse-lite": "^1.0.30001406",
279 | "postcss": "8.4.14",
280 | "styled-jsx": "5.1.1"
281 | },
282 | "bin": {
283 | "next": "dist/bin/next"
284 | },
285 | "engines": {
286 | "node": ">=14.6.0"
287 | },
288 | "optionalDependencies": {
289 | "@next/swc-android-arm-eabi": "13.1.4",
290 | "@next/swc-android-arm64": "13.1.4",
291 | "@next/swc-darwin-arm64": "13.1.4",
292 | "@next/swc-darwin-x64": "13.1.4",
293 | "@next/swc-freebsd-x64": "13.1.4",
294 | "@next/swc-linux-arm-gnueabihf": "13.1.4",
295 | "@next/swc-linux-arm64-gnu": "13.1.4",
296 | "@next/swc-linux-arm64-musl": "13.1.4",
297 | "@next/swc-linux-x64-gnu": "13.1.4",
298 | "@next/swc-linux-x64-musl": "13.1.4",
299 | "@next/swc-win32-arm64-msvc": "13.1.4",
300 | "@next/swc-win32-ia32-msvc": "13.1.4",
301 | "@next/swc-win32-x64-msvc": "13.1.4"
302 | },
303 | "peerDependencies": {
304 | "fibers": ">= 3.1.0",
305 | "node-sass": "^6.0.0 || ^7.0.0",
306 | "react": "^18.2.0",
307 | "react-dom": "^18.2.0",
308 | "sass": "^1.3.0"
309 | },
310 | "peerDependenciesMeta": {
311 | "fibers": {
312 | "optional": true
313 | },
314 | "node-sass": {
315 | "optional": true
316 | },
317 | "sass": {
318 | "optional": true
319 | }
320 | }
321 | },
322 | "node_modules/picocolors": {
323 | "version": "1.0.0",
324 | "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
325 | "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ=="
326 | },
327 | "node_modules/postcss": {
328 | "version": "8.4.14",
329 | "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.14.tgz",
330 | "integrity": "sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig==",
331 | "funding": [
332 | {
333 | "type": "opencollective",
334 | "url": "https://opencollective.com/postcss/"
335 | },
336 | {
337 | "type": "tidelift",
338 | "url": "https://tidelift.com/funding/github/npm/postcss"
339 | }
340 | ],
341 | "dependencies": {
342 | "nanoid": "^3.3.4",
343 | "picocolors": "^1.0.0",
344 | "source-map-js": "^1.0.2"
345 | },
346 | "engines": {
347 | "node": "^10 || ^12 || >=14"
348 | }
349 | },
350 | "node_modules/react": {
351 | "version": "18.2.0",
352 | "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz",
353 | "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==",
354 | "dependencies": {
355 | "loose-envify": "^1.1.0"
356 | },
357 | "engines": {
358 | "node": ">=0.10.0"
359 | }
360 | },
361 | "node_modules/react-dom": {
362 | "version": "18.2.0",
363 | "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz",
364 | "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==",
365 | "dependencies": {
366 | "loose-envify": "^1.1.0",
367 | "scheduler": "^0.23.0"
368 | },
369 | "peerDependencies": {
370 | "react": "^18.2.0"
371 | }
372 | },
373 | "node_modules/scheduler": {
374 | "version": "0.23.0",
375 | "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz",
376 | "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==",
377 | "dependencies": {
378 | "loose-envify": "^1.1.0"
379 | }
380 | },
381 | "node_modules/source-map-js": {
382 | "version": "1.0.2",
383 | "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
384 | "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
385 | "engines": {
386 | "node": ">=0.10.0"
387 | }
388 | },
389 | "node_modules/styled-jsx": {
390 | "version": "5.1.1",
391 | "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.1.tgz",
392 | "integrity": "sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==",
393 | "dependencies": {
394 | "client-only": "0.0.1"
395 | },
396 | "engines": {
397 | "node": ">= 12.0.0"
398 | },
399 | "peerDependencies": {
400 | "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0"
401 | },
402 | "peerDependenciesMeta": {
403 | "@babel/core": {
404 | "optional": true
405 | },
406 | "babel-plugin-macros": {
407 | "optional": true
408 | }
409 | }
410 | },
411 | "node_modules/tslib": {
412 | "version": "2.4.1",
413 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz",
414 | "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA=="
415 | }
416 | }
417 | }
418 |
--------------------------------------------------------------------------------
/02-css-modules/after/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "01-css-in-js",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "dev": "next dev",
7 | "build": "next build",
8 | "start": "next start"
9 | },
10 | "dependencies": {
11 | "next": "13.1.4",
12 | "react": "18.2.0",
13 | "react-dom": "18.2.0"
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/02-css-modules/after/public/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jaketrent/styling-react-components/cdcae8c2ab0dd85f3d110a2eba56c523e6eff795/02-css-modules/after/public/favicon.png
--------------------------------------------------------------------------------
/02-css-modules/after/src/components/App.js:
--------------------------------------------------------------------------------
1 | import Head from "next/head";
2 |
3 | import Newsletter from "./Newsletter.js";
4 |
5 | function App() {
6 | return (
7 |
8 |
9 |
10 |
CSS Modules Example
11 |
12 |
13 |
14 | );
15 | }
16 |
17 | export default App;
18 |
--------------------------------------------------------------------------------
/02-css-modules/after/src/components/Newsletter.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | import css from "./Newsletter.module.css";
4 |
5 | export default function Newsletter() {
6 | const [email, setEmail] = React.useState("");
7 | const emailPartsCount = countEmailParts(email);
8 | return (
9 |
10 |
11 | {Array.from(Array(5)).map((_, i) => (
12 |
13 | ))}
14 |
15 |
16 | Get the newsletter
17 |
18 | setEmail(evt.target.value)}
23 | />
24 | = 5}>Sign up
25 |
26 | );
27 | }
28 |
29 | function Container(props) {
30 | return ;
31 | }
32 |
33 | function Header(props) {
34 | return ;
35 | }
36 |
37 | function Email(props) {
38 | return ;
39 | }
40 |
41 | function Submit(props) {
42 | return (
43 |
46 | );
47 | }
48 |
49 | function Spectrum(props) {
50 | return (
51 |
52 | {props.children}
53 |
54 | );
55 | }
56 |
57 | function Bar(props) {
58 | return ;
59 | }
60 |
61 | function countEmailParts(email) {
62 | if (/@.+\..{2,}$/.test(email)) {
63 | return 5;
64 | } else if (/@.+\..?$/.test(email)) {
65 | return 4;
66 | } else if (/@.+$/.test(email)) {
67 | return 3;
68 | } else if (/@/.test(email)) {
69 | return 2;
70 | } else if (/.+/.test(email)) {
71 | return 1;
72 | } else {
73 | return 0;
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/02-css-modules/after/src/components/Newsletter.module.css:
--------------------------------------------------------------------------------
1 | .container {
2 | --spectrum1: #ff598a;
3 | --spectrum2: #de56e8;
4 | --spectrum3: #b36bff;
5 | --spectrum4: #5b56e8;
6 | --spectrum5: #5e9fff;
7 |
8 | position: relative;
9 | max-width: 100%;
10 | font-size: 1.25em;
11 | padding: 1em 1em 2em 1em;
12 | background: #2b283d;
13 | }
14 | @media (min-width: 800px) {
15 | .container {
16 | font-size: 2.25em;
17 | max-width: 700px;
18 | }
19 | }
20 |
21 | .header {
22 | position: relative;
23 | z-index: 1;
24 | text-transform: uppercase;
25 | font-size: 0.85em;
26 | text-shadow: 0 3px 2px #000;
27 | }
28 | .header h2 {
29 | margin: 0 0 0.5em 0;
30 | }
31 |
32 | .email {
33 | position: relative;
34 | height: 2em;
35 | line-height: 2em;
36 | font-size: 0.85em;
37 | padding: 0 0.5em;
38 | width: 100%;
39 | margin: 0.15em;
40 | border: 1px solid black;
41 | }
42 | .email:focus {
43 | outline: 2px solid #fff;
44 | outline-offset: 0.15em;
45 | }
46 |
47 | .submit {
48 | position: absolute;
49 | bottom: 0;
50 | left: 50%;
51 | z-index: 1;
52 | overflow: hidden;
53 | margin: 0;
54 | background: transparent;
55 | color: #070222;
56 | background: #fff;
57 | font-weight: bold;
58 | border: 0;
59 | cursor: pointer;
60 | text-transform: uppercase;
61 | transition: all 300ms;
62 | height: 0;
63 | width: 0;
64 | font-size: 0;
65 | translate: -50%;
66 | rotate: 45deg;
67 | padding: 0;
68 | border-bottom: 0;
69 | outline: none;
70 | }
71 | .submitActive {
72 | composes: submit;
73 | height: auto;
74 | width: auto;
75 | font-size: 1em;
76 | translate: -50% 50%;
77 | rotate: -5deg;
78 | padding: 0.25em 1em;
79 | border-bottom: 3px solid var(--spectrum5);
80 | }
81 | .submitActive:focus {
82 | outline: 2px solid #fff;
83 | outline-offset: 4px;
84 | }
85 | .submitActive:focus,
86 | .submitActive:hover {
87 | border-bottom-color: var(--spectrum1);
88 | rotate: 0deg;
89 | scale: 1.2;
90 | }
91 |
92 | .spectrum {
93 | position: absolute;
94 | top: 0;
95 | bottom: 0;
96 | left: 0;
97 | width: 100%;
98 | display: flex;
99 | align-items: flex-end;
100 | pointer-events: none;
101 | }
102 |
103 | .bar {
104 | height: 0.5em;
105 | animation: jitter 350ms ease-out infinite alternate;
106 | width: 20%;
107 | transform-origin: bottom;
108 | transition: all 1s;
109 | }
110 | .barActive {
111 | composes: bar;
112 | height: 100%;
113 | }
114 | .bar:nth-child(1n) {
115 | background: var(--spectrum1);
116 | animation-delay: 0;
117 | }
118 | .bar:nth-child(2n) {
119 | background: var(--spectrum2);
120 | animation-delay: 50ms;
121 | }
122 | .bar:nth-child(3n) {
123 | background: var(--spectrum3);
124 | animation-delay: 100ms;
125 | }
126 | .bar:nth-child(4n) {
127 | background: var(--spectrum4);
128 | animation-delay: 150ms;
129 | }
130 | .bar:nth-child(5n) {
131 | background: var(--spectrum5);
132 | animation-delay: 200ms;
133 | }
134 | @keyframes jitter {
135 | 0% {
136 | transform: scaleY(1);
137 | }
138 | 100% {
139 | transform: scaleY(0.9);
140 | }
141 | }
142 |
--------------------------------------------------------------------------------
/02-css-modules/after/src/components/index.css:
--------------------------------------------------------------------------------
1 | * {
2 | box-sizing: border-box;
3 | }
4 | body {
5 | margin: 0;
6 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
7 | "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
8 | sans-serif;
9 | -webkit-font-smoothing: antialiased;
10 | -moz-osx-font-smoothing: grayscale;
11 | background: #070222;
12 | color: #fff;
13 | font-size: 18px;
14 | }
15 |
16 | .app__newsletter {
17 | display: flex;
18 | justify-content: center;
19 | padding: 4rem 0;
20 | }
21 |
--------------------------------------------------------------------------------
/02-css-modules/after/src/pages/_app.js:
--------------------------------------------------------------------------------
1 | import '../components/index.css'
2 |
3 | export default function App({ Component, pageProps }) {
4 | return
5 | }
6 |
--------------------------------------------------------------------------------
/02-css-modules/after/src/pages/index.js:
--------------------------------------------------------------------------------
1 | import App from '../components/App.js'
2 |
3 | export default function Home() {
4 | return
5 | }
6 |
--------------------------------------------------------------------------------
/02-css-modules/before/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # next.js
12 | /.next/
13 | /out/
14 |
15 | # production
16 | /build
17 |
18 | # misc
19 | .DS_Store
20 | *.pem
21 |
22 | # debug
23 | npm-debug.log*
24 | yarn-debug.log*
25 | yarn-error.log*
26 | .pnpm-debug.log*
27 |
28 | # local env files
29 | .env*.local
30 |
31 | # vercel
32 | .vercel
33 |
--------------------------------------------------------------------------------
/02-css-modules/before/next.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | const nextConfig = {
3 | reactStrictMode: true,
4 | }
5 |
6 | module.exports = nextConfig
7 |
--------------------------------------------------------------------------------
/02-css-modules/before/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "01-css-in-js",
3 | "version": "0.1.0",
4 | "lockfileVersion": 3,
5 | "requires": true,
6 | "packages": {
7 | "": {
8 | "name": "01-css-in-js",
9 | "version": "0.1.0",
10 | "dependencies": {
11 | "next": "13.1.4",
12 | "react": "18.2.0",
13 | "react-dom": "18.2.0"
14 | }
15 | },
16 | "node_modules/@next/env": {
17 | "version": "13.1.4",
18 | "resolved": "https://registry.npmjs.org/@next/env/-/env-13.1.4.tgz",
19 | "integrity": "sha512-x7ydhMpi9/xX7yVK+Fw33OuwwQWVZUFRxenK3z89fmPzQZyUk35Ynb+b7JkrhfRhDIFFvvqpzVSXeseSlBAw7A=="
20 | },
21 | "node_modules/@next/swc-android-arm-eabi": {
22 | "version": "13.1.4",
23 | "resolved": "https://registry.npmjs.org/@next/swc-android-arm-eabi/-/swc-android-arm-eabi-13.1.4.tgz",
24 | "integrity": "sha512-5PAchzFst3In6Ml+9APvBj89H29lcPXcUqEYBVv09fWK/V4IuViKc2qOqM9pyPyw7KsqaZPmuqaG595E6jdZLA==",
25 | "cpu": [
26 | "arm"
27 | ],
28 | "optional": true,
29 | "os": [
30 | "android"
31 | ],
32 | "engines": {
33 | "node": ">= 10"
34 | }
35 | },
36 | "node_modules/@next/swc-android-arm64": {
37 | "version": "13.1.4",
38 | "resolved": "https://registry.npmjs.org/@next/swc-android-arm64/-/swc-android-arm64-13.1.4.tgz",
39 | "integrity": "sha512-LCLjjRhsQ5fR9ExzR2fqxuyJe/D4Ct/YkdonVfJfqOfkEpFwUTQDOVo5GrQec4LZDk3zY+o6vZYjXbB0nD9VLA==",
40 | "cpu": [
41 | "arm64"
42 | ],
43 | "optional": true,
44 | "os": [
45 | "android"
46 | ],
47 | "engines": {
48 | "node": ">= 10"
49 | }
50 | },
51 | "node_modules/@next/swc-darwin-arm64": {
52 | "version": "13.1.4",
53 | "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-13.1.4.tgz",
54 | "integrity": "sha512-LSc/tF1FQ1y1SwKiCdGg8IIl7+Csk6nuLcLIyQXs24UNYjXg5+7vUQXqE8y66v/Dq8qFDC9rM61QhpM9ZDftbg==",
55 | "cpu": [
56 | "arm64"
57 | ],
58 | "optional": true,
59 | "os": [
60 | "darwin"
61 | ],
62 | "engines": {
63 | "node": ">= 10"
64 | }
65 | },
66 | "node_modules/@next/swc-darwin-x64": {
67 | "version": "13.1.4",
68 | "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-13.1.4.tgz",
69 | "integrity": "sha512-WoApDo8xfafrNc9+Mz5MwGFKUwbDHsGqLleTGZ8upegwVqDyHsYzqJQudf+loqhV58oGTOqP1eWaHn2J7dijXA==",
70 | "cpu": [
71 | "x64"
72 | ],
73 | "optional": true,
74 | "os": [
75 | "darwin"
76 | ],
77 | "engines": {
78 | "node": ">= 10"
79 | }
80 | },
81 | "node_modules/@next/swc-freebsd-x64": {
82 | "version": "13.1.4",
83 | "resolved": "https://registry.npmjs.org/@next/swc-freebsd-x64/-/swc-freebsd-x64-13.1.4.tgz",
84 | "integrity": "sha512-fqNyeT8G4guN8AHPIoBRhGY2GJg89FyWpuwX4o0Y3vUy/84IGZpNst3paCzaYkQSqQE/AuCpkB7hKxkN7ittXw==",
85 | "cpu": [
86 | "x64"
87 | ],
88 | "optional": true,
89 | "os": [
90 | "freebsd"
91 | ],
92 | "engines": {
93 | "node": ">= 10"
94 | }
95 | },
96 | "node_modules/@next/swc-linux-arm-gnueabihf": {
97 | "version": "13.1.4",
98 | "resolved": "https://registry.npmjs.org/@next/swc-linux-arm-gnueabihf/-/swc-linux-arm-gnueabihf-13.1.4.tgz",
99 | "integrity": "sha512-MEfm8OC1YR9/tYHUzlQsxcSmiuf8XdO7bqh5VtG4pilScjc5I5t+tQgIDgoDGePfh5W99W23hb3s6oCFrt99rw==",
100 | "cpu": [
101 | "arm"
102 | ],
103 | "optional": true,
104 | "os": [
105 | "linux"
106 | ],
107 | "engines": {
108 | "node": ">= 10"
109 | }
110 | },
111 | "node_modules/@next/swc-linux-arm64-gnu": {
112 | "version": "13.1.4",
113 | "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-13.1.4.tgz",
114 | "integrity": "sha512-2wgth/KsuODzW/E7jsRoWdhKmE5oZzXcBPvf9RW+ZpBNvYQkEDlzfLA7n8DtxTU8I4oMas0mdEPdCWXrSNnVZw==",
115 | "cpu": [
116 | "arm64"
117 | ],
118 | "optional": true,
119 | "os": [
120 | "linux"
121 | ],
122 | "engines": {
123 | "node": ">= 10"
124 | }
125 | },
126 | "node_modules/@next/swc-linux-arm64-musl": {
127 | "version": "13.1.4",
128 | "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-13.1.4.tgz",
129 | "integrity": "sha512-GdWhCRljsT7rNEElEsdu4RRppd+XaQOX1IJslsh/+HU6LsJGUE8tXpa68yJjCsHZHifkbdZNeCr5SYdsN6CbAA==",
130 | "cpu": [
131 | "arm64"
132 | ],
133 | "optional": true,
134 | "os": [
135 | "linux"
136 | ],
137 | "engines": {
138 | "node": ">= 10"
139 | }
140 | },
141 | "node_modules/@next/swc-linux-x64-gnu": {
142 | "version": "13.1.4",
143 | "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-13.1.4.tgz",
144 | "integrity": "sha512-Rsk/ojwYqMskN2eo5hUSVe7UuMV/aSjmrmJ0BCFGFPfBY9sPgmYj/oXlDDN0y5lJD9acPuiBjknLWgnOnx5JIA==",
145 | "cpu": [
146 | "x64"
147 | ],
148 | "optional": true,
149 | "os": [
150 | "linux"
151 | ],
152 | "engines": {
153 | "node": ">= 10"
154 | }
155 | },
156 | "node_modules/@next/swc-linux-x64-musl": {
157 | "version": "13.1.4",
158 | "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-13.1.4.tgz",
159 | "integrity": "sha512-gKSVPozedA2gpA+vggYnAqpDuzWFed2oxFeXxHw0aW2ALdAZswAinn1ZwXEQ5fHnVguxjZhH0+2nBxpMdF8p5Q==",
160 | "cpu": [
161 | "x64"
162 | ],
163 | "optional": true,
164 | "os": [
165 | "linux"
166 | ],
167 | "engines": {
168 | "node": ">= 10"
169 | }
170 | },
171 | "node_modules/@next/swc-win32-arm64-msvc": {
172 | "version": "13.1.4",
173 | "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-13.1.4.tgz",
174 | "integrity": "sha512-+kAXIIVb7Q4LCKmi7dn9qVlG1XUf3Chgj5Rwl0rAP4WBV2TnJIgsOEC24G1Mm3jjif+qXm7SJS9YZ9Yg3Y8sSQ==",
175 | "cpu": [
176 | "arm64"
177 | ],
178 | "optional": true,
179 | "os": [
180 | "win32"
181 | ],
182 | "engines": {
183 | "node": ">= 10"
184 | }
185 | },
186 | "node_modules/@next/swc-win32-ia32-msvc": {
187 | "version": "13.1.4",
188 | "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-13.1.4.tgz",
189 | "integrity": "sha512-EsfzAFBVaw1zg1FzlLMgRaTX/DKY+EnAvJ6mCIJMGeSOPIj4Oy6xF2yEQ3VaRkwFpAafHJH6JNB/CGrdKFCMXw==",
190 | "cpu": [
191 | "ia32"
192 | ],
193 | "optional": true,
194 | "os": [
195 | "win32"
196 | ],
197 | "engines": {
198 | "node": ">= 10"
199 | }
200 | },
201 | "node_modules/@next/swc-win32-x64-msvc": {
202 | "version": "13.1.4",
203 | "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.1.4.tgz",
204 | "integrity": "sha512-bygNjmnq+F9NqJXh7OfhJgqu6LGU29GNKQYVyZkxY/h5K0WWUvAE/VL+TdyMwbvQr9KByx5XLwORwetLxXCo4g==",
205 | "cpu": [
206 | "x64"
207 | ],
208 | "optional": true,
209 | "os": [
210 | "win32"
211 | ],
212 | "engines": {
213 | "node": ">= 10"
214 | }
215 | },
216 | "node_modules/@swc/helpers": {
217 | "version": "0.4.14",
218 | "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.4.14.tgz",
219 | "integrity": "sha512-4C7nX/dvpzB7za4Ql9K81xK3HPxCpHMgwTZVyf+9JQ6VUbn9jjZVN7/Nkdz/Ugzs2CSjqnL/UPXroiVBVHUWUw==",
220 | "dependencies": {
221 | "tslib": "^2.4.0"
222 | }
223 | },
224 | "node_modules/caniuse-lite": {
225 | "version": "1.0.30001447",
226 | "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001447.tgz",
227 | "integrity": "sha512-bdKU1BQDPeEXe9A39xJnGtY0uRq/z5osrnXUw0TcK+EYno45Y+U7QU9HhHEyzvMDffpYadFXi3idnSNkcwLkTw==",
228 | "funding": [
229 | {
230 | "type": "opencollective",
231 | "url": "https://opencollective.com/browserslist"
232 | },
233 | {
234 | "type": "tidelift",
235 | "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
236 | }
237 | ]
238 | },
239 | "node_modules/client-only": {
240 | "version": "0.0.1",
241 | "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz",
242 | "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA=="
243 | },
244 | "node_modules/js-tokens": {
245 | "version": "4.0.0",
246 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
247 | "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
248 | },
249 | "node_modules/loose-envify": {
250 | "version": "1.4.0",
251 | "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
252 | "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
253 | "dependencies": {
254 | "js-tokens": "^3.0.0 || ^4.0.0"
255 | },
256 | "bin": {
257 | "loose-envify": "cli.js"
258 | }
259 | },
260 | "node_modules/nanoid": {
261 | "version": "3.3.4",
262 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz",
263 | "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==",
264 | "bin": {
265 | "nanoid": "bin/nanoid.cjs"
266 | },
267 | "engines": {
268 | "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
269 | }
270 | },
271 | "node_modules/next": {
272 | "version": "13.1.4",
273 | "resolved": "https://registry.npmjs.org/next/-/next-13.1.4.tgz",
274 | "integrity": "sha512-g0oBUU+tcOPKbXTVdsDO2adc6wd/ggqauHHysPQJxuIKqZ+fwICGJht0C5D5V0A/77eQDF5EFwNdAHkFvBDsog==",
275 | "dependencies": {
276 | "@next/env": "13.1.4",
277 | "@swc/helpers": "0.4.14",
278 | "caniuse-lite": "^1.0.30001406",
279 | "postcss": "8.4.14",
280 | "styled-jsx": "5.1.1"
281 | },
282 | "bin": {
283 | "next": "dist/bin/next"
284 | },
285 | "engines": {
286 | "node": ">=14.6.0"
287 | },
288 | "optionalDependencies": {
289 | "@next/swc-android-arm-eabi": "13.1.4",
290 | "@next/swc-android-arm64": "13.1.4",
291 | "@next/swc-darwin-arm64": "13.1.4",
292 | "@next/swc-darwin-x64": "13.1.4",
293 | "@next/swc-freebsd-x64": "13.1.4",
294 | "@next/swc-linux-arm-gnueabihf": "13.1.4",
295 | "@next/swc-linux-arm64-gnu": "13.1.4",
296 | "@next/swc-linux-arm64-musl": "13.1.4",
297 | "@next/swc-linux-x64-gnu": "13.1.4",
298 | "@next/swc-linux-x64-musl": "13.1.4",
299 | "@next/swc-win32-arm64-msvc": "13.1.4",
300 | "@next/swc-win32-ia32-msvc": "13.1.4",
301 | "@next/swc-win32-x64-msvc": "13.1.4"
302 | },
303 | "peerDependencies": {
304 | "fibers": ">= 3.1.0",
305 | "node-sass": "^6.0.0 || ^7.0.0",
306 | "react": "^18.2.0",
307 | "react-dom": "^18.2.0",
308 | "sass": "^1.3.0"
309 | },
310 | "peerDependenciesMeta": {
311 | "fibers": {
312 | "optional": true
313 | },
314 | "node-sass": {
315 | "optional": true
316 | },
317 | "sass": {
318 | "optional": true
319 | }
320 | }
321 | },
322 | "node_modules/picocolors": {
323 | "version": "1.0.0",
324 | "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
325 | "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ=="
326 | },
327 | "node_modules/postcss": {
328 | "version": "8.4.14",
329 | "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.14.tgz",
330 | "integrity": "sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig==",
331 | "funding": [
332 | {
333 | "type": "opencollective",
334 | "url": "https://opencollective.com/postcss/"
335 | },
336 | {
337 | "type": "tidelift",
338 | "url": "https://tidelift.com/funding/github/npm/postcss"
339 | }
340 | ],
341 | "dependencies": {
342 | "nanoid": "^3.3.4",
343 | "picocolors": "^1.0.0",
344 | "source-map-js": "^1.0.2"
345 | },
346 | "engines": {
347 | "node": "^10 || ^12 || >=14"
348 | }
349 | },
350 | "node_modules/react": {
351 | "version": "18.2.0",
352 | "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz",
353 | "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==",
354 | "dependencies": {
355 | "loose-envify": "^1.1.0"
356 | },
357 | "engines": {
358 | "node": ">=0.10.0"
359 | }
360 | },
361 | "node_modules/react-dom": {
362 | "version": "18.2.0",
363 | "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz",
364 | "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==",
365 | "dependencies": {
366 | "loose-envify": "^1.1.0",
367 | "scheduler": "^0.23.0"
368 | },
369 | "peerDependencies": {
370 | "react": "^18.2.0"
371 | }
372 | },
373 | "node_modules/scheduler": {
374 | "version": "0.23.0",
375 | "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz",
376 | "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==",
377 | "dependencies": {
378 | "loose-envify": "^1.1.0"
379 | }
380 | },
381 | "node_modules/source-map-js": {
382 | "version": "1.0.2",
383 | "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
384 | "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
385 | "engines": {
386 | "node": ">=0.10.0"
387 | }
388 | },
389 | "node_modules/styled-jsx": {
390 | "version": "5.1.1",
391 | "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.1.tgz",
392 | "integrity": "sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==",
393 | "dependencies": {
394 | "client-only": "0.0.1"
395 | },
396 | "engines": {
397 | "node": ">= 12.0.0"
398 | },
399 | "peerDependencies": {
400 | "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0"
401 | },
402 | "peerDependenciesMeta": {
403 | "@babel/core": {
404 | "optional": true
405 | },
406 | "babel-plugin-macros": {
407 | "optional": true
408 | }
409 | }
410 | },
411 | "node_modules/tslib": {
412 | "version": "2.4.1",
413 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz",
414 | "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA=="
415 | }
416 | }
417 | }
418 |
--------------------------------------------------------------------------------
/02-css-modules/before/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "01-css-in-js",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "dev": "next dev",
7 | "build": "next build",
8 | "start": "next start"
9 | },
10 | "dependencies": {
11 | "next": "13.1.4",
12 | "react": "18.2.0",
13 | "react-dom": "18.2.0"
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/02-css-modules/before/public/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jaketrent/styling-react-components/cdcae8c2ab0dd85f3d110a2eba56c523e6eff795/02-css-modules/before/public/favicon.png
--------------------------------------------------------------------------------
/02-css-modules/before/src/components/App.js:
--------------------------------------------------------------------------------
1 | import Head from "next/head";
2 |
3 | import Newsletter from "./Newsletter.js";
4 |
5 | function App() {
6 | return (
7 |
8 |
9 |
10 |
CSS Modules Example
11 |
12 |
13 |
14 | );
15 | }
16 |
17 | export default App;
18 |
--------------------------------------------------------------------------------
/02-css-modules/before/src/components/Newsletter.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | import css from "./Newsletter.module.css";
4 |
5 | export default function Newsletter() {
6 | const [email, setEmail] = React.useState("");
7 | const emailPartsCount = countEmailParts(email);
8 | return (
9 |
10 |
11 | {Array.from(Array(5)).map((_, i) => (
12 |
13 | ))}
14 |
15 |
16 | Get the newsletter
17 |
18 | setEmail(evt.target.value)}
23 | />
24 | = 5}>Sign up
25 |
26 | );
27 | }
28 |
29 | function Container(props) {
30 | return ;
31 | }
32 |
33 | function Header(props) {
34 | return ;
35 | }
36 |
37 | function Email(props) {
38 | return ;
39 | }
40 |
41 | function Submit(props) {
42 | return ;
43 | }
44 |
45 | function Spectrum(props) {
46 | return (
47 |
48 | {props.children}
49 |
50 | );
51 | }
52 |
53 | function Bar(props) {
54 | return ;
55 | }
56 |
57 | function countEmailParts(email) {
58 | if (/@.+\..{2,}$/.test(email)) {
59 | return 5;
60 | } else if (/@.+\..?$/.test(email)) {
61 | return 4;
62 | } else if (/@.+$/.test(email)) {
63 | return 3;
64 | } else if (/@/.test(email)) {
65 | return 2;
66 | } else if (/.+/.test(email)) {
67 | return 1;
68 | } else {
69 | return 0;
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/02-css-modules/before/src/components/Newsletter.module.css:
--------------------------------------------------------------------------------
1 | .container {
2 | --spectrum1: #ff598a;
3 | --spectrum2: #de56e8;
4 | --spectrum3: #b36bff;
5 | --spectrum4: #5b56e8;
6 | --spectrum5: #5e9fff;
7 |
8 | position: relative;
9 | max-width: 100%;
10 | font-size: 1.25em;
11 | padding: 1em 1em 2em 1em;
12 | background: #2b283d;
13 | }
14 | /* 1-1 */
15 |
16 | .header {
17 | position: relative;
18 | z-index: 1;
19 | text-transform: uppercase;
20 | font-size: 0.85em;
21 | text-shadow: 0 3px 2px #000;
22 | }
23 | /* 1-2 */
24 |
25 | .email {
26 | position: relative;
27 | height: 2em;
28 | line-height: 2em;
29 | font-size: 0.85em;
30 | padding: 0 0.5em;
31 | width: 100%;
32 | margin: 0.15em;
33 | border: 1px solid black;
34 | }
35 | /* 1-3 */
36 |
37 | .submit {
38 | position: absolute;
39 | bottom: 0;
40 | left: 50%;
41 | z-index: 1;
42 | overflow: hidden;
43 | margin: 0;
44 | background: transparent;
45 | color: #070222;
46 | background: #fff;
47 | font-weight: bold;
48 | border: 0;
49 | cursor: pointer;
50 | text-transform: uppercase;
51 | transition: all 300ms;
52 | height: 0;
53 | width: 0;
54 | font-size: 0;
55 | translate: -50%;
56 | rotate: 45deg;
57 | padding: 0;
58 | border-bottom: 0;
59 | outline: none;
60 | }
61 | /* 1-4 */
62 |
63 | .spectrum {
64 | position: absolute;
65 | top: 0;
66 | bottom: 0;
67 | left: 0;
68 | width: 100%;
69 | display: flex;
70 | align-items: flex-end;
71 | pointer-events: none;
72 | }
73 |
74 | .bar {
75 | height: 0.5em;
76 | /* 1-7 */
77 | width: 20%;
78 | transform-origin: bottom;
79 | transition: all 1s;
80 | }
81 | /* 1-6 */
82 | .bar:nth-child(1n) {
83 | background: var(--spectrum1);
84 | animation-delay: 0;
85 | }
86 | .bar:nth-child(2n) {
87 | background: var(--spectrum2);
88 | animation-delay: 50ms;
89 | }
90 | .bar:nth-child(3n) {
91 | background: var(--spectrum3);
92 | animation-delay: 100ms;
93 | }
94 | .bar:nth-child(4n) {
95 | background: var(--spectrum4);
96 | animation-delay: 150ms;
97 | }
98 | .bar:nth-child(5n) {
99 | background: var(--spectrum5);
100 | animation-delay: 200ms;
101 | }
102 |
--------------------------------------------------------------------------------
/02-css-modules/before/src/components/index.css:
--------------------------------------------------------------------------------
1 | * {
2 | box-sizing: border-box;
3 | }
4 | body {
5 | margin: 0;
6 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
7 | "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
8 | sans-serif;
9 | -webkit-font-smoothing: antialiased;
10 | -moz-osx-font-smoothing: grayscale;
11 | background: #070222;
12 | color: #fff;
13 | font-size: 18px;
14 | }
15 |
16 | .app__newsletter {
17 | display: flex;
18 | justify-content: center;
19 | padding: 4rem 0;
20 | }
21 |
--------------------------------------------------------------------------------
/02-css-modules/before/src/pages/_app.js:
--------------------------------------------------------------------------------
1 | import '../components/index.css'
2 |
3 | export default function App({ Component, pageProps }) {
4 | return
5 | }
6 |
--------------------------------------------------------------------------------
/02-css-modules/before/src/pages/index.js:
--------------------------------------------------------------------------------
1 | import App from '../components/App.js'
2 |
3 | export default function Home() {
4 | return
5 | }
6 |
--------------------------------------------------------------------------------
/02-css-modules/snippets.css:
--------------------------------------------------------------------------------
1 | /* 1-1 */
2 | @media (min-width: 800px) {
3 | section {
4 | font-size: 2.25em;
5 | max-width: 700px;
6 | }
7 | }
8 |
9 | /* 1-2 */
10 | .header h2 {
11 | margin: 0 0 0.5em 0;
12 | }
13 |
14 | /* 1-3 */
15 | .email:focus {
16 | outline: 2px solid #fff;
17 | outline-offset: 0.15em;
18 | }
19 |
20 | /* 1-4 */
21 | /*