├── .gitignore ├── README.md ├── package-lock.json ├── package.json ├── public ├── favicon.ico ├── index.html └── manifest.json └── src ├── Components ├── App.jsx ├── Note.jsx └── __tests__ │ ├── App.test.js │ └── Note.test.js ├── SCSS ├── App.scss └── _colours.scss └── index.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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # React Hooks - Todo List. 3 | 4 | This is a demo project. 5 | 6 | install - `$ yarn install` 7 | 8 | start - `$ yarn run start` 9 | 10 | test - `$ yarn run test` 11 | 12 | build - `$ yarn run build` 13 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-demo", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "acorn": "^7.1.1", 7 | "kind-of": "^6.0.3", 8 | "minimist": "^1.2.5", 9 | "node-sass": "^4.14.1", 10 | "react": "^16.13.1", 11 | "react-dom": "^16.13.1", 12 | "react-scripts": "^3.4.1", 13 | "set-value": "^3.0.2" 14 | }, 15 | "scripts": { 16 | "start": "react-scripts start", 17 | "build": "react-scripts build", 18 | "test": "react-scripts test", 19 | "eject": "react-scripts eject" 20 | }, 21 | "eslintConfig": { 22 | "extends": "react-app" 23 | }, 24 | "browserslist": [ 25 | ">0.2%", 26 | "not dead", 27 | "not ie <= 11", 28 | "not op_mini all" 29 | ], 30 | "devDependencies": {} 31 | } 32 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jeanrauwers/React-hooks-todo-list/5249a3602ae7f5267f869226eaf06c348b9e0867/public/favicon.ico -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 10 | 11 | 15 | 16 | 25 | React demo 26 | 27 | 28 | 29 |
30 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /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 | "start_url": ".", 12 | "display": "standalone", 13 | "theme_color": "#000000", 14 | "background_color": "#ffffff" 15 | } 16 | -------------------------------------------------------------------------------- /src/Components/App.jsx: -------------------------------------------------------------------------------- 1 | import React, { useState, useEffect, useRef } from "react"; 2 | import "../SCSS/App.scss"; 3 | import Note from "./Note"; 4 | 5 | const App = () => { 6 | const [isEditing, setEditing] = useState(false); 7 | const inputRef = useRef(); 8 | const [inputValue, setInputValue] = useState(""); 9 | const [notes, setNotes] = useState([]); 10 | 11 | useEffect(() => { 12 | inputRef.current.focus(); 13 | }, [isEditing]); 14 | 15 | const updateNoteText = event => { 16 | setInputValue(event.target.value); 17 | }; 18 | 19 | const handleKeyPress = e => { 20 | if (e.key === "Enter") { 21 | addTask(); 22 | } 23 | }; 24 | 25 | const addTask = () => { 26 | if (!inputValue.replace(/\s/, "").length) { 27 | return; 28 | } 29 | 30 | const newNotesArray = [...notes, inputValue]; 31 | setNotes(newNotesArray); 32 | setInputValue(""); 33 | }; 34 | 35 | const deleteTask = index => { 36 | const notesArray = [...notes]; 37 | notesArray.splice(index, 1); 38 | setNotes(notesArray); 39 | }; 40 | 41 | return ( 42 | <> 43 |
React Hooks - TODO List Tutorial
44 |
45 |
46 | + 47 |
48 | 56 | {notes.map((item, index) => ( 57 | deleteTask(index)} 60 | key={`task${index}`} 61 | /> 62 | ))} 63 |
64 | 65 | ); 66 | }; 67 | 68 | export default App; 69 | -------------------------------------------------------------------------------- /src/Components/Note.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | const Note = props => { 4 | const { item, ...restProps } = props; 5 | 6 | return ( 7 |
8 | {item || ""} 9 |
10 | ); 11 | }; 12 | 13 | export default Note; 14 | -------------------------------------------------------------------------------- /src/Components/__tests__/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 | 11 | 12 | -------------------------------------------------------------------------------- /src/Components/__tests__/Note.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import Note from '../Note'; 4 | 5 | it('renders without crashing', () => { 6 | const div = document.createElement('div'); 7 | ReactDOM.render(, div); 8 | ReactDOM.unmountComponentAtNode(div); 9 | }); 10 | -------------------------------------------------------------------------------- /src/SCSS/App.scss: -------------------------------------------------------------------------------- 1 | @import "./colours"; 2 | 3 | * { 4 | margin: 0px; 5 | box-sizing: border-box; 6 | } 7 | html, 8 | body { 9 | width: 100%; 10 | height: 100%; 11 | } 12 | body { 13 | background: $background; 14 | } 15 | #root { 16 | width: 100%; 17 | height: 100%; 18 | } 19 | .container { 20 | padding-bottom: 1%; 21 | max-width: 95%; 22 | } 23 | .header { 24 | font-size: 22px; 25 | font-weight: bold; 26 | font-style: italic; 27 | color: $background; 28 | background: $header; 29 | padding: 40px; 30 | } 31 | .note { 32 | font-weight: bold; 33 | color: $blue; 34 | padding: 40px; 35 | margin: 20px; 36 | background: #fff; 37 | border: solid 1px #e9e9e9; 38 | cursor: pointer; 39 | box-shadow: 0px 0px 14px 0px rgba(0, 0, 0, 0.1); 40 | -webkit-box-shadow: 0px 0px 14px 0px rgba(0, 0, 0, 0.1); 41 | -moz-box-shadow: 0px 0px 14px 0px rgba(0, 0, 0, 0.1); 42 | transition: transform 0.2s ease; 43 | } 44 | .note:hover { 45 | transform: scale(1.02); 46 | } 47 | .btn { 48 | position: fixed; 49 | z-index: 1; 50 | right: 40px; 51 | bottom: 40px; 52 | width: 80px; 53 | height: 80px; 54 | border-radius: 100%; 55 | text-align: center; 56 | line-height: 80px; 57 | font-size: 28px; 58 | font-weight: bold; 59 | color: $background; 60 | background: $blue; 61 | cursor: pointer; 62 | box-shadow: 0px 0px 11px 0px rgba(0, 0, 0, 0.8); 63 | -webkit-box-shadow: 0px 0px 11px 0px rgba(0, 0, 0, 0.8); 64 | -moz-box-shadow: 0px 0px 11px 0px rgba(0, 0, 0, 0.8); 65 | transition: transform 0.06s ease; 66 | } 67 | .btn:hover { 68 | transform: scale(1.2); 69 | } 70 | .textInput { 71 | position: fixed; 72 | bottom: 0; 73 | width: 100%; 74 | height: 80px; 75 | line-height: 80px; 76 | padding: 0 20px; 77 | border: none; 78 | outline: none; 79 | background: $header; 80 | font-size: 16px; 81 | color: $background; 82 | } 83 | -------------------------------------------------------------------------------- /src/SCSS/_colours.scss: -------------------------------------------------------------------------------- 1 | $header: #028fac; 2 | $blue: #222222; 3 | $background: #f1f1f1; 4 | $gray: #e9e9e9; 5 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import App from './Components/App'; 4 | 5 | ReactDOM.render(, document.getElementById('root')); 6 | --------------------------------------------------------------------------------