Table of Contents
- This is a simple TODO APP built with React.
- It was built with handheld device accessibility in mind. Hence the bottom Input field.
- It features dynamic routing and dynamic category using React Router.
- Light, Dark and Auto theme. The auto theme follows system preferences.
- Here's what users can expect from this APP:
- Create Category for different types of tasks.
- Create tasks for the respective category.
- Mark completed task as done.
- Bulk Mark all tasks as done.
- Delete task.
- Bulk delete completed tasks.
- Mark task as important.
- Important tasks get pinned to top.
- Users can visit site_url/Groceries and add tasks directly to a category named Groceries.
- Nice little rewarding animations when a task is completed. 😉
⭐ Head over to the Features section to dive deep into the problems I faced and how I solved them.
🌐 The site is already live at: https://celadon-cactus-42acbb.netlify.app/
OR
🖥️ You can test it on your local machine by following the steps below.
-
Open your projects base folder and launch any terminal of your choice.
-
Run this command:
npm install npm@latest -g
-
Clone the repo
git clone https://github.com/webdevsk/react-todo-app.git
-
Install NPM packages
npm install
-
Run Dev server
npm run dev
Desktop |
Mobile |
-
The input field is placed at the bottom making it is easily reachable on handheld devices.
-
Unlike most other Todo Apps, it featues top to bottom (old to new) layout.
-
As you add new tasks, the newer tasks will appear at the bottom.
-
The page will scroll down automatically to keep newer tasks in focus.
⚒️ Here's a snippet of code on how I solved the scroll issue:
const {tasks, category} = useLoaderData() //Length of the task array before new task is added const prevLength = useRef(tasks.length) useEffect(() => { // Run only when new task is added if (prevLength.current < tasks.length){ window.scrollTo({ left: 0, top: document.body.scrollHeight || document.documentElement.scrollHeight, behavior: "smooth" }) } //Setting new task array length after new task is added prevLength.current = tasks.length }, [tasks])
-
Larger screens
- Side Drawer Menu can stay either Shown or Hidden based on user's preference.
- The shown/hidden state is persisted between browsing sessions.
- Clicking outside the menu will not close it.
-
Smaller screens (1400px or less)
- Side Drawer Menu will always be Hidden unless user opens it.
- Window size is consistently being monitored to check if the window goesbelow 1400px. If so the menu will hide automatically.
- Clicking outside the menu will close it.
⚒️ Here's a snippet of code on how I solved it:
//Initial state. Defaults to false on smaller screens const [open, setOpen] = useState(() => ( window.outerWidth <= 1400 ? false : 'drawerOpen' in localStorage ? true : false )) //Saves state in localStorage useEffect(()=> ( open ? localStorage.setItem('drawerOpen', '1') : localStorage.removeItem('drawerOpen') ), [open]) //Enables overlay on smaller screens. Which blurs outside content and listens to touch events const [overlay, setOverlay] = useState(() => window.outerWidth <= 1400) //Runs on window resize useEffect (()=>{ let currentWindowWidth = window.outerWidth function handleWindowResize(){ //Run only when the horizontal width changes to avoid firing on keyboard popup on touch devices if (window.outerWidth === currentWindowWidth) return currentWindowWidth = window.outerWidth if (window.outerWidth <= 1400){ setOpen(false) setOverlay(true) } else { setOverlay(false) } } window.addEventListener('resize', handleWindowResize) return () => { window.removeEventListener('resize', handleWindowResize) } }, [])
- Click on the "Add new category" button and type your desired name for it.
- Press Enter or click on the ✅ (tick) button.
- You will be redirected to a new page where you can add tasks in this category.
- Visit or Bookmark https://celadon-cactus-42acbb.netlify.app/School
- If you already had tasks in School category, the tasks will be listed.
- If you never had a School category, it will generate a new Category where you can add new tasks.
- You can write any strings in place of "School".
- If you want to add spaces or symbols in category name, rather create it from the Side Drawer Menu instead.
- To save up space in Database/storage, A category won't be stored unless you have atleast 1 task in it.
- Completed all tasks for today? Well, congratulations!!! The "Mark all as completed" button will be handy then.
- No need to clutter the list with already complted tasks. The "Delete All Completed" button will make them go away.
And many more handmade features, animations here and there...
Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated.
If you have a suggestion that would make this better, please fork the repo and create a pull request. You can also simply open an issue with the tag "enhancement". Don't forget to give the project a star! Thanks again!
- Fork the Project
- Create your Feature Branch (
git checkout -b feature/AmazingFeature
) - Commit your Changes (
git commit -m 'Add some AmazingFeature'
) - Push to the Branch (
git push origin feature/AmazingFeature
) - Open a Pull Request
Distributed under the MIT License. See LICENSE.txt
for more information.
Project Link: https://github.com/webdevsk/react-todo-app