Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

Cover image for How to Build a Todo app with Svelte!
Avneesh Agarwal
Avneesh Agarwal

Posted on • Originally published atblog.avneesh.tech

     

How to Build a Todo app with Svelte!

Demo

Video demo

Setup

Create app

npx degit sveltejs/template svelte-todo-app
Enter fullscreen modeExit fullscreen mode

cd into the folder-

cd svelte-todo-app
Enter fullscreen modeExit fullscreen mode

Install dependencies

npm install # npmyarn install # yarn
Enter fullscreen modeExit fullscreen mode

Start app

npm run dev # npmyarn dev # yarn
Enter fullscreen modeExit fullscreen mode

Cleanup

I don't want the default stylings, so I will replace the stylings inglobals.css with this-

* {  margin: 0;}body {  margin: 0;  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",    "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",    sans-serif;  -webkit-font-smoothing: antialiased;  -moz-osx-font-smoothing: grayscale;}code {  font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New",    monospace;}
Enter fullscreen modeExit fullscreen mode

Building the container

InApp. svelte let's create the starter code for our app.

<script></script><main></main><style>  .container {    display: flex;    flex-direction: column;    align-items: center;    min-height: 90vh;    background: #222e50      url(https://images.unsplash.com/photo-1579546929518-9e396f3cc809?ixid=MXwxMjA3fDB8MHxzZWFyY2h8N3x8Z3JhZGllbnR8ZW58MHx8MHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=60)      no-repeat;    background-size: cover;    padding-top: 10vh;  }</style>
Enter fullscreen modeExit fullscreen mode

Building the form to submit Todos

Inside our main container, add a form component with input and button-

<main>  <div>    <form on:submit|preventDefault={addTodo}>      <input        bind:value={newItem}        type="task"               placeholder="Enter Todo"      />      <button>+</button>    </form>  </div></main>
Enter fullscreen modeExit fullscreen mode

We need to create the following things now-

  • A variable to store the input value

  • AaddTodo function for adding the todos.

So in the script tag add the following-

  let newItem = "";  let todoList = [];  function addTodo() {    if (newItem !== "") {      todoList = [        ...todoList,        {          task: newItem,          completed: false,        },      ];      newItem = "";    }    console.log(todoList);  }
Enter fullscreen modeExit fullscreen mode

Styling

Now let's style our submit button and the input. Inside the styles, tag add this-

.todos__input {    background-color: inherit;    border: none;    box-shadow: none;    text-decoration: none;    font-size: 1.2rem;    border-bottom: 1px solid black;    margin-top: 15px;    outline: none;    width: 500px;  }  .todos__button {    background-color: inherit;    border: none;    box-shadow: none;    font-size: 1.2rem;    cursor: pointer;  }
Enter fullscreen modeExit fullscreen mode

If we now add an item, it will add the item to the list and console log it.

Rendering the todos

In React like we have a map function, we do it through#each in Svelte

 {#each todoList as item, index}      <div>        <span>{item.task}</span>      </div>    {/each}
Enter fullscreen modeExit fullscreen mode

Styling the todos

 .todo {    display: flex;    padding: 20px;    border-radius: 20px;    box-shadow: 0 0 15px rgb(0 0 0 / 20%);    background-color: hsla(0, 0%, 100%, 0.2);    -webkit-backdrop-filter: blur(25px);    backdrop-filter: blur(25px);    width: inherit;    margin-top: 15px;    font-size: 1.2rem;    justify-content: space-between;    align-items: center;  }
Enter fullscreen modeExit fullscreen mode

This will give the todos a glassmorphic look 🤩

image.png

Adding a header for the todos

The to-do list and the inputs look kinda clumsy, so let's add a header there-

After the form component add this h2 tag-

<h2>Todos</h2>
Enter fullscreen modeExit fullscreen mode

The stylings for this header-

 .todos__listHeader {    text-align: center;    padding: 20px;    border-radius: 20px;    box-shadow: 0 0 15px rgb(0 0 0 / 20%);    background-color: hsla(0, 0%, 100%, 0.2);    -webkit-backdrop-filter: blur(25px);    backdrop-filter: blur(25px);    margin: 15px 0px 25px 0px;    font-size: 1.2rem;  }
Enter fullscreen modeExit fullscreen mode

Now we have got a pretty good separation there.

image.png

Creating the complete and delete functionality

We are going to use icons for delete and complete, so let's get the icons first.

  • CreateIcons. svelte file in the src directory. Add the following piece of code, for the icons. Feel free to change the icons :) -
<script>  export let name;  export let width = "1.5rem";  export let height = "1.5rem";  export let focusable = false;  let icons = [    {      box: 24,      name: "check-mark",      svg: `<svg focusable="false" viewBox="0 0 24 24" aria-hidden="true"><path d="M19.77 4.93l1.4 1.4L8.43 19.07l-5.6-5.6 1.4-1.4 4.2 4.2L19.77 4.93m0-2.83L8.43 13.44l-4.2-4.2L0 13.47l8.43 8.43L24 6.33 19.77 2.1z"></path></svg>`,    },    {      box: 32,      name: "delete",      svg: `<svg focusable="false" viewBox="0 0 24 24" aria-hidden="true"><path d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM8 9h8v10H8V9zm7.5-5l-1-1h-5l-1 1H5v2h14V4h-3.5z"></path></svg>`,    },  ];  let displayIcon = icons.find((e) => e.name === name);</script><svg  class={$$props.class}  {focusable}  {width}  {height}  viewBox="0 0 {displayIcon.box} {displayIcon.box}">{@html displayIcon.svg}</svg>
Enter fullscreen modeExit fullscreen mode

Show the icons

Inside the todo, I will add a div with two buttons that have the icons as follows-

{#each todoList as item, index}  <div>    <span>{item.task}</span>    <div>      <button               on:click={() => (item.completed = !item.completed)}      >        <Icons name="check-mark" />      </button>      <button on:click={() => removeFromList(index)}>        <Icons name="delete" />      </button>    </div>  </div>{/each}
Enter fullscreen modeExit fullscreen mode

Import the icons like this-

import Icons from "./Icons.svelte";
Enter fullscreen modeExit fullscreen mode

Creating the delete function-

 function removeFromList(index) {    todoList.splice(index, 1);    todoList = todoList;  }
Enter fullscreen modeExit fullscreen mode

Styling the buttons

Add the following styles to get a beautiful icon button-

 .icon__button {    background-color: transparent;    border: none;    box-shadow: none;    font-size: 1.2rem;    cursor: pointer;    color: rgba(0, 0, 0, 0.54);  }  .icon {    background: rgba(0, 0, 0, 0.54);  }
Enter fullscreen modeExit fullscreen mode

Striking the Text

Add this optional class to the item. task span, so if the item is completed then it will add the class-

 <span          class={`todo__text ${item.completed ? "todo__checked--strike" : ""}`}          >{item.task}</span        >
Enter fullscreen modeExit fullscreen mode

Now, we need to add the styles to strike it-

  .todo__checked--strike {    text-decoration: line-through;  }
Enter fullscreen modeExit fullscreen mode

This function takes an argument ofindex and splices the todoList to remove the item.

We have successfully built a to-do app in Svelte! 🥳🎉

To extend your knowledge about svelte check out this video byJames Q Quick where he will show you how to create a todo app with Sveltekit and tailwind CSS!

%[https://youtu.be/]

Useful links

Github Repository

Demo

James' channel

Connect with Me

Top comments(7)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss
CollapseExpand
 
cjsmocjsmo profile image
Charlie J Smotherman
  • Location
    Seattle WA
  • Work
    Worlds Greatest GrandPa at Looking for work
  • Joined

Are your todo' lost when you close the app or do they persist until you open the app again?

CollapseExpand
 
avneesh0612 profile image
Avneesh Agarwal
I am a fullstack web developer. I love to make beautiful websites and also teach others how to make them by writing blogs.

Yeah, I haven't implemented localstorage in this one :)

CollapseExpand
 
cjsmocjsmo profile image
Charlie J Smotherman
  • Location
    Seattle WA
  • Work
    Worlds Greatest GrandPa at Looking for work
  • Joined

If I remember correctly (and I dont always do) the stock demo app you get when you

npm init svelte@next

Has a persistent todo list example you may want to take some inspiration from.

Looks good other wise

Happy coding

Thread Thread
 
avneesh0612 profile image
Avneesh Agarwal
I am a fullstack web developer. I love to make beautiful websites and also teach others how to make them by writing blogs.

Um, I didn't know you can generate like that and I know how to add that feature but wanted to keep this tutorial simple. Thanks for understanding :)

Thread Thread
 
cjsmocjsmo profile image
Charlie J Smotherman
  • Location
    Seattle WA
  • Work
    Worlds Greatest GrandPa at Looking for work
  • Joined

👍

CollapseExpand
 
zippcodder profile image
Deon Rich
Fullstack Software Engineer interested in all things tech, and always looking for somthing new to learn!
  • Location
    San José, Costa Rica
  • Joined

Nice article!

CollapseExpand
 
avneesh0612 profile image
Avneesh Agarwal
I am a fullstack web developer. I love to make beautiful websites and also teach others how to make them by writing blogs.

Thanks!

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

I am a fullstack web developer. I love to make beautiful websites and also teach others how to make them by writing blogs.
  • Location
    India
  • Joined

More fromAvneesh Agarwal

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp