├── .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
{props.children}
; 31 | } 32 | 33 | function Header(props) { 34 | return
{props.children}
; 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
{props.children}
; 31 | } 32 | 33 | function Header(props) { 34 | return
{props.children}
; 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 | /*