Svelte has built in state management tools so no need to bring in a library like Vuex or Redux.
import { writable } from "svelte/store";
import { v4 as uuid } from "uuid";
export interface TodoItem {
id?: string;
name: string;
done: boolean;
}
const initialTodos: TodoItem[] = [
{
id: uuid(),
name: "Initial Todo",
done: false,
},
];
const { subscribe, update } = writable(initialTodos);
export function addTodoItem(item: TodoItem) {
const itemWithId: TodoItem = {
...item,
id: uuid(),
};
update((todos) => {
return [...todos, itemWithId];
});
}
export function updateTodoItem(item: TodoItem) {
update((todos) => todos.map((todo) => (todo.id === item.id ? item : todo)));
}
export function removeTodoItem(id: string) {
update((todos) => todos.filter((todo) => todo.id !== id));
}
export default { subscribe };
Not realistic because this is a single component, but showcases how this works:
<script lang="ts">
import todoItems, { addTodoItem, removeTodoItem } from "./store/todoItems";
export let name: string;
let todoInput: string | null = null;
function handleAdd() {
addTodoItem({
name: todoInput,
done: false,
});
todoInput = null;
}
function handleRemove(id: string) {
removeTodoItem(id);
}
</script>
<main>
<h1>Hello {name}!</h1>
{#each $todoItems as todoItem}
<div class="todo-item">
<p class="todo-controls">{todoItem.name}</p>
<button class="todo-controls" on:click={() => handleRemove(todoItem.id)}> Remove </button>
</div>
{/each}
<div>
<form action="javascript:void">
<input type="text" bind:value={todoInput} />
<input type="submit" on:click={handleAdd} value="Ok" />
</form>
</div>
</main>
<style>
main {
text-align: center;
padding: 1em;
max-width: 240px;
margin: 0 auto;
}
h1 {
color: #ff3e00;
text-transform: uppercase;
font-size: 4em;
font-weight: 100;
}
.todo-controls {
display: inline-block;
}
@media (min-width: 640px) {
main {
max-width: none;
}
}
</style>