diff --git a/src/components/TodoApp/Todo.tsx b/src/components/TodoApp/Todo.tsx index 9c84f9d..d5eff41 100644 --- a/src/components/TodoApp/Todo.tsx +++ b/src/components/TodoApp/Todo.tsx @@ -1,49 +1,48 @@ -import { memo, useState, useEffect, useReducer } from "react"; +import { memo, useState, useEffect } from "react"; import { tss } from "tss-react"; import { fr } from "@codegouvfr/react-dsfr"; import { Button } from "@codegouvfr/react-dsfr/Button"; import Checkbox from "@mui/material/Checkbox"; import { useEvent } from "tools/useEvent"; import { deepEqual } from "tools/deepEqual"; +import type { TodoItem } from "./type"; +import { assert } from "tsafe/assert"; -export type Todo = { - id: string; +// Todo item but without the id, we don't need it. +export type TodoItemLike = { text: string; isDone: boolean; }; +// Make sure that the type `TodoItemLike` is a subset of `TodoItem` +// This will give us red squiggles if we forget to update `TodoItemLike` when we update `TodoItem` +assert(); + type TodoProps = { className?: string; - todo: Todo; + todo: TodoItemLike; onUpdateTodoText: (text: string) => void; onToggleTodo: () => void; onDeleteTodo: () => void; }; export const Todo = memo((props: TodoProps) => { - const { className, todo, onToggleTodo, onDeleteTodo } = props; - - // NOTE: Make sure it's not stale for when used in the reducer. - // We know it's constant because we also used useListEvent() in the parent component - // but this component is not supposed to be aware of that. - const onUpdateTodoText = useEvent(props.onUpdateTodoText); + const { className, todo, onToggleTodo, onDeleteTodo, onUpdateTodoText } = props; - const [isEditing, setIsEditing] = useReducer((isEditing: boolean, isEditing_new: boolean) => { - if (isEditing_new === isEditing) { - return isEditing; - } + const [text, setText] = useState(todo.text); + const [isEditing, setIsEditing] = useState(false); - if (!isEditing_new) { + const onEditButtonClick = useEvent(() => { + if (isEditing) { onUpdateTodoText(text); + setIsEditing(false); + } else { + setIsEditing(true); } - - return isEditing_new; - }, false); + }); const { classes, cx } = useStyles({ isEditing }); - const [text, setText] = useState(todo.text); - useEffect(() => { setText(todo.text); }, [todo.text]); @@ -58,7 +57,6 @@ export const Todo = memo((props: TodoProps) => { className={cx(fr.cx("fr-input"), classes.input)} value={text} onChange={e => setText(e.target.value)} - onBlur={() => setIsEditing(false)} /> ) : ( {todo.text} @@ -68,7 +66,7 @@ export const Todo = memo((props: TodoProps) => {