├── .gitignore ├── LICENSE ├── README.md ├── package-lock.json ├── package.json ├── postcss.config.js ├── public ├── favicon.ico ├── img │ └── stock-photo.jpg ├── index.html ├── logo192.png ├── logo512.png ├── manifest.json └── robots.txt ├── src ├── App.css ├── App.js ├── App.test.js ├── components │ ├── About.js │ ├── Contact.js │ ├── Header.js │ └── Home.js ├── css │ └── tailwind.css ├── index.css ├── index.js └── logo.svg └── tailwind.config.js /.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 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Billimarie Lubiano Robinson 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # React Tutorials 2 | > Updated: November 11th 2019 3 | 4 | ## Table of Contents 5 | 1. [Tutorial 1: A Simple Website with React, Tailwind CSS, & PostCSS](#tutorial-1) 6 | 1. [Tutorial 2: Adding CSS Transitions](#tutorial-2) 7 | 8 | # Tutorial 1 9 | 10 | Create a simple, multi-page website that watches your CSS changes & refreshes your app, accordingly. 11 | 12 | To view the Medium.com article: [Creating A Simple Website with React, Tailwind CSS, & PostCSS](https://medium.com/clocktwine/creating-a-simple-website-using-react-tailwind-css-postcss-6bbc419ded0c) 13 | 14 | ## What You Need 15 | - Terminal / Command Line 16 | - IDE (I recommend [Atom](https://github.com/atom/atom)) 17 | 18 | ### Versions 19 | - Node: 8.11.3+ 20 | - npm: 6.12.1+ 21 | 22 | ## Getting Started 23 | 24 | ### 1. Initialize your React app using `create-react-app`: 25 | ``` 26 | $ npx create-react-app react-tailwind-site 27 | ``` 28 | 29 | ### 2. Change directories into the app & install `react-router-dom` (for links), `tailwindcss` (for Tailwind CSS), `autoprefixer`, & `postcss-cli` (to watch & reload CSS updates): 30 | ``` 31 | $ cd react-tailwind-site 32 | $ npm install react-router-dom tailwindcss autoprefixer postcss-cli 33 | ``` 34 | 35 | ### 3. Test it out: 36 | ``` 37 | $ npm run start 38 | ``` 39 | A new window should open up (`localhost:3000`) & display the standard new React App screen. 40 | 41 | (Having trouble? See [Troubleshooting](#troubleshooting)). 42 | 43 | ## Setting Up Tailwind 44 | 45 | ### 1. Initialize Tailwind & PostCSS: 46 | ``` 47 | $ npx tailwind init tailwind.config.js 48 | ``` 49 | 50 | ### 2. Create Tailwind.css: 51 | ``` 52 | $ cd src ; mkdir css ; cd css ; touch tailwind.css // Linux 53 | $ cd src & mkdir css & cd css & touch tailwind.css // Windows 54 | ``` 55 | 56 | ### 3. Add to `src/css/tailwind.css`: 57 | ``` 58 | /* Init Tailwind */ 59 | @tailwind base; 60 | 61 | @tailwind components; 62 | 63 | @tailwind utilities; 64 | 65 | /* Custom CSS */ 66 | ``` 67 | 68 | ## Connecting Tailwind & React 69 | 70 | ### 1. Modify your `package.json` with these updated scripts: 71 | ``` 72 | "scripts": { 73 | "build:css": "postcss src/css/tailwind.css -o src/index.css", 74 | "watch:css": "postcss src/css/tailwind.css -o src/index.css -w", 75 | "start": "npm watch:css & react-scripts start", 76 | "build": "npm run build:css && react-scripts build", 77 | "test": "react-scripts test --env=jsdom", 78 | "eject": "react-scripts eject" 79 | } 80 | ``` 81 | 82 | ### 2. Modify `App.js`: 83 | ``` 84 | import './css/tailwind.css'; /* Replacing App.css */ 85 | ``` 86 | 87 | ### 3. Modify `index.js`: 88 | ``` 89 | import './index.css'; /* Replacing App.css */ 90 | ``` 91 | 92 | ### 4. Let's restart the app! 93 | ``` 94 | $ npm run start 95 | ``` 96 | 97 | You should see an updated `localhost:3000` page. 98 | 99 | To test that it's watching your CSS changes, go back to `src/css/tailwind.css` & add a new style under "Custom CSS." Your app should refresh with the changes automatically: 100 | 101 | ![react-tailwind-watching-loop](https://user-images.githubusercontent.com/6895471/68322467-44e2a100-0078-11ea-811e-13f8456cdf5f.gif) 102 | 103 | ## Creating Components 104 | 105 | ### 1. Create a folder called "Components." It should be in your source files (`/src/components/`) 106 | ``` 107 | $ mkdir components 108 | ``` 109 | 110 | ### 2. To start off, let's build a header. 111 | ``` 112 | $ cd src/components ; touch Header.js // Linux 113 | $ cd src/components & touch Header.js // Windows 114 | ``` 115 | 116 | ### 3. In Header.js: 117 | ``` 118 | import React from 'react'; 119 | import { 120 | BrowserRouter as Router, 121 | Switch, 122 | Route, 123 | Link } from 'react-router-dom'; 124 | 125 | const Header = () => ( 126 |
127 |
128 |
129 | Title Goes Here 130 |
131 | 137 |
138 |
139 | ); 140 | export default Header; 141 | ``` 142 | 143 | ### 4. Go to `App.js` and add the following imports 144 | ``` 145 | import { 146 | BrowserRouter as Router, 147 | Switch, 148 | Route, 149 | Link 150 | } from 'react-router-dom'; 151 | import Header from './components/Header.js'; 152 | ``` 153 | 154 | Scroll down and replace the content React automatically generated with the following: 155 | ``` 156 | const App = () => ( 157 | 158 |
159 | 160 | ); 161 | export default App; 162 | ``` 163 | 164 | ### 5. Now that we've made the universal header, let's create the pages for Home, About, & Contact: 165 | ``` 166 | $ touch Home.js About.js Contact.js 167 | ``` 168 | 169 | Open `Home.js` add the following: 170 | 171 | ``` 172 | import React from 'react'; 173 | 174 | const Home = () => ( 175 |

Home

176 | ); 177 | 178 | export default Home; 179 | ``` 180 | 181 | You can reuse this code for your `About.js` and `Contact.js` pages. 182 | 183 | ### 6. Again, back to `App.js` to import your new components: 184 | 185 | ``` 186 | import Home from './components/Home.js'; 187 | import About from './components/About.js'; 188 | import Contact from './components/Contact.js'; 189 | ``` 190 | 191 | Scroll down to modify: 192 | 193 | ``` 194 | 195 |
196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | ``` 211 | 212 | ### 7. Modify `index.js` to activate the router: 213 | ``` 214 | import { BrowserRouter } from 'react-router-dom'; 215 | 216 | ReactDOM.render(, document.getElementById('root')); 217 | ``` 218 | 219 | ### 8. You're all set! Restart the app to see your new changes. 220 | ``` 221 | $ npm run start 222 | ``` 223 | 224 | You should be able to see the new header, and click on each navigation item to take you to a new page: 225 | 226 | ![react-tailwind-links](https://user-images.githubusercontent.com/6895471/68329481-27b4cf00-0086-11ea-93ee-580fcef18c6e.gif) 227 | 228 | ## Complete! 229 | 230 | If you get stuck or have any questions, feel free to send me a message. I'd love to see what you create with this; submit a pull request with your screenshot or link to be added to this GitHub repo. 231 | 232 | ## Troubleshooting 233 | 234 | - If you receive an error about ServiceWorker.js, go to `index.js` and comment it out. (You can also delete the file itself under `src/serviceWorker.js`.) 235 | - Additionally, if you're running Windows, make sure system32 has been added to your PATH (see: [this GitHub issue](https://medium.com/r/?url=https%3A%2F%2Fgithub.com%2Ffacebook%2Fcreate-react-app%2Fissues%2F7061)). 236 | 237 | ([Back to Top](#react-tutorials)) 238 | 239 | # Tutorial 2 240 | 241 | Adding CSS Transitions. 242 | 243 | ## Getting Started 244 | 245 | ### 1. Add `React Transition Group`: 246 | ``` 247 | $ npm install react-transition-group --save-dev 248 | ``` 249 | 250 | ### 2. Import in your chosen view (I picked `Home.js`): 251 | ``` 252 | import { CSSTransition } from 'react-transition-group'; 253 | ``` 254 | 255 | ### 3. Declare new consts: 256 | ``` 257 | const [showVertical, setShowVertical] = useState(true), 258 | [showHorizontal, setShowHorizontal] = useState(false); 259 | ``` 260 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-tailwind-site", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "autoprefixer": "^9.7.1", 7 | "postcss-cli": "^6.1.3", 8 | "react": "^16.11.0", 9 | "react-dom": "^16.11.0", 10 | "react-router-dom": "^5.1.2", 11 | "react-scripts": "3.2.0", 12 | "react-transition-group": "^4.3.0", 13 | "tailwindcss": "^1.1.3" 14 | }, 15 | "scripts": { 16 | "build:css": "postcss src/css/tailwind.css -o src/index.css", 17 | "watch:css": "postcss src/css/tailwind.css -o src/index.css -w", 18 | "start": "npm watch:css & react-scripts start", 19 | "build": "npm run build:css && react-scripts build", 20 | "test": "react-scripts test --env=jsdom", 21 | "eject": "react-scripts eject" 22 | }, 23 | "eslintConfig": { 24 | "extends": "react-app" 25 | }, 26 | "browserslist": { 27 | "production": [ 28 | ">0.2%", 29 | "not dead", 30 | "not op_mini all" 31 | ], 32 | "development": [ 33 | "last 1 chrome version", 34 | "last 1 firefox version", 35 | "last 1 safari version" 36 | ] 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | const tailwindcss = require("tailwindcss"); 2 | 3 | module.exports = { 4 | plugins: [ 5 | tailwindcss("tailwind.config.js"), 6 | require("autoprefixer") 7 | ] 8 | }; 9 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/billimarie/simple-react-tailwind-tutorial/414bc7d3b48785567ea776fbfb1def3853d6d185/public/favicon.ico -------------------------------------------------------------------------------- /public/img/stock-photo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/billimarie/simple-react-tailwind-tutorial/414bc7d3b48785567ea776fbfb1def3853d6d185/public/img/stock-photo.jpg -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 17 | 18 | 27 | React App 28 | 29 | 30 | 31 |
32 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/billimarie/simple-react-tailwind-tutorial/414bc7d3b48785567ea776fbfb1def3853d6d185/public/logo192.png -------------------------------------------------------------------------------- /public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/billimarie/simple-react-tailwind-tutorial/414bc7d3b48785567ea776fbfb1def3853d6d185/public/logo512.png -------------------------------------------------------------------------------- /public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | -------------------------------------------------------------------------------- /src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | 5 | .App-logo { 6 | height: 40vmin; 7 | } 8 | 9 | .App-header { 10 | background-color: #282c34; 11 | min-height: 100vh; 12 | display: flex; 13 | flex-direction: column; 14 | align-items: center; 15 | justify-content: center; 16 | font-size: calc(10px + 2vmin); 17 | color: white; 18 | } 19 | 20 | .App-link { 21 | color: #09d3ac; 22 | } 23 | -------------------------------------------------------------------------------- /src/App.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import './css/tailwind.css'; 3 | 4 | import { 5 | BrowserRouter as Router, 6 | Switch, 7 | Route 8 | } from 'react-router-dom'; 9 | 10 | import Header from './components/Header.js'; 11 | import Home from './components/Home.js'; 12 | import About from './components/About.js'; 13 | import Contact from './components/Contact.js'; 14 | 15 | const App = () => ( 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | ); 33 | 34 | export default App; 35 | -------------------------------------------------------------------------------- /src/App.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import App from './App'; 4 | 5 | it('renders without crashing', () => { 6 | const div = document.createElement('div'); 7 | ReactDOM.render(, div); 8 | ReactDOM.unmountComponentAtNode(div); 9 | }); 10 | -------------------------------------------------------------------------------- /src/components/About.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const About = () => ( 4 |
5 |

About

6 |

Information about your website can go here.

7 |
8 | ); 9 | 10 | export default About; 11 | -------------------------------------------------------------------------------- /src/components/Contact.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Contact = () => ( 4 |
5 |

Contact

6 |

Contact information can go here.

7 |
8 | ); 9 | 10 | export default Contact; 11 | -------------------------------------------------------------------------------- /src/components/Header.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import { Link } from 'react-router-dom'; 4 | 5 | const Header = () => ( 6 |
7 |
8 |
9 | Title Goes Here 10 |
11 | 17 |
18 |
19 | ); 20 | 21 | export default Header; 22 | -------------------------------------------------------------------------------- /src/components/Home.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react'; 2 | import { CSSTransition } from 'react-transition-group'; 3 | 4 | function Home() { 5 | const [showVertical, setShowVertical] = useState(true), 6 | [showHorizontal, setShowHorizontal] = useState(false); 7 | 8 | return ( 9 |
10 |

Home

11 |

This is the homepage.

12 | 13 |
14 | 15 | {showVertical && ( 16 |
setShowHorizontal(true)}> 17 | Woman of color weighing all options. 18 |
19 |

Contemplating Invisible Rocks

20 | #philosophy 21 | #think piece 22 |
23 |
24 | )} 25 | 26 | setShowVertical(false)} 31 | onExited={() => setShowVertical(true)} 32 | > 33 | 34 |
setShowHorizontal(false)}> 35 |
36 |
37 |
38 |
39 |

Contemplating Invisible Rocks

40 |

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptatibus quia, nulla! Maiores et perferendis eaque, exercitationem praesentium nihil.

41 |
42 | #philosophy 43 | #think piece 44 |
45 |
46 |
47 | Woman of color weighing all options. 48 |
49 |

Testing CSS Transitions

50 |

Aug 18

51 |
52 |
53 |
54 |
55 | 56 |
57 | 58 |
59 | 60 |
61 | ); 62 | } 63 | 64 | export default Home; 65 | -------------------------------------------------------------------------------- /src/css/tailwind.css: -------------------------------------------------------------------------------- 1 | 2 | /* Init Tailwind */ 3 | @tailwind base; 4 | 5 | @tailwind components; 6 | 7 | @tailwind utilities; 8 | 9 | /* Custom CSS */ 10 | .App-logo { 11 | width: 300px; 12 | } 13 | 14 | /* Card Hover */ 15 | .card.state-1 { 16 | opacity: 1; 17 | transform: scale(1.0); 18 | transition: opacity 350ms, transform 350ms; 19 | } 20 | .card.state-1:hover { 21 | opacity: .75; 22 | transform: scale(1.025); 23 | transition: opacity 350ms, transform 350ms; 24 | } 25 | /* Card Animation */ 26 | .state-2.enter { 27 | opacity: 0; 28 | transform: scale(0.9); 29 | } 30 | .state-2.enter-active { 31 | opacity: 1; 32 | transform: translateX(0); 33 | transition: opacity 350ms, transform 350ms; 34 | } 35 | .state-2.enter-active p, 36 | .state-2.enter-active h3 { 37 | color: blue; 38 | transition: color 350ms; 39 | } 40 | .state-2.exit-active p, 41 | .state-2.exit-active h3 { 42 | color: red; 43 | transition: color 350ms; 44 | } 45 | .state-2.exit { 46 | opacity: 1; 47 | } 48 | .state-2.exit-active { 49 | opacity: 0; 50 | transform: scale(0.9); 51 | transition: opacity 350ms, transform 350ms; 52 | } 53 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import './index.css'; 4 | import App from './App'; 5 | import { BrowserRouter } from 'react-router-dom'; 6 | 7 | ReactDOM.render( , document.getElementById('root')); 8 | -------------------------------------------------------------------------------- /src/logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tailwind.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | theme: { 3 | extend: {} 4 | }, 5 | variants: {}, 6 | plugins: [] 7 | } 8 | --------------------------------------------------------------------------------