diff --git a/src/App.tsx b/src/App.tsx index e95b7b7ec..87f25a1c2 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -6,8 +6,6 @@ export const App: React.FC = () => { return (
-

todos

-
diff --git a/src/components/Content.tsx b/src/components/Content.tsx index e3b42455d..86fd338ba 100644 --- a/src/components/Content.tsx +++ b/src/components/Content.tsx @@ -7,7 +7,6 @@ import { TodosContext } from '../context/TodosContex'; export const Content: React.FC = () => { const { todos, setTodos } = useContext(TodosContext); - const [focused, setFocused] = useState(true); const [visibleTodos, setVisibleTodos] = useState(todos); useEffect(() => { @@ -27,18 +26,21 @@ export const Content: React.FC = () => { }, [todos]); return ( -
-
- - - - {todos.length > 0 && ( -
+ <> +

todos

+ +
+
+ + + + {todos.length > 0 && ( +
+ ); }; diff --git a/src/components/Footer.tsx b/src/components/Footer.tsx index 8e9bbd3d1..2405edacd 100644 --- a/src/components/Footer.tsx +++ b/src/components/Footer.tsx @@ -7,14 +7,9 @@ import { Todo } from '../types/Todo'; type Props = { visibleTodos: Todo[]; setVisibleTodos: (vilteredTodos: Todo[]) => void; - setFocused: (value: boolean) => void; }; -export const Footer: React.FC = ({ - visibleTodos, - setVisibleTodos, - setFocused, -}) => { +export const Footer: React.FC = ({ visibleTodos, setVisibleTodos }) => { const { todos, setTodos } = useContext(TodosContext); const [selectedFilter, setSelectedFilter] = useState(Filter.All); @@ -54,12 +49,7 @@ export const Footer: React.FC = ({ }; const clearFunction = () => { - const completedTodos = todos - .filter(todo => todo.completed) - .map(todo => todo.id); - - setTodos(todos.filter(todo => !completedTodos.includes(todo.id))); - setFocused(true); + setTodos(todos.filter(t => !t.completed)); }; const setFilter = (filter: Filter) => { diff --git a/src/components/Header.tsx b/src/components/Header.tsx index 0656fa7c0..f6a26f1f4 100644 --- a/src/components/Header.tsx +++ b/src/components/Header.tsx @@ -1,20 +1,9 @@ -import React, { - useCallback, - useContext, - useEffect, - useRef, - useState, -} from 'react'; +import React, { useContext, useEffect, useRef, useState } from 'react'; import { TodosContext } from '../context/TodosContex'; import classNames from 'classnames'; import { Todo } from '../types/Todo'; -type Props = { - focused: boolean; - setFocused: (value: boolean) => void; -}; - -export const Header: React.FC = ({ focused, setFocused }) => { +export const Header: React.FC = () => { const { todos, setTodos } = useContext(TodosContext); const [title, setTitle] = useState(''); @@ -22,32 +11,17 @@ export const Header: React.FC = ({ focused, setFocused }) => { const inputRef = useRef(null); useEffect(() => { - if (inputRef.current && focused) { + if (inputRef.current) { inputRef.current.focus(); } - }, [focused]); + }, [todos]); - const checkActiveTodos = useCallback((): boolean => { + const checkActiveTodos = (): boolean => { if (todos.length > 0) { return todos.every(todo => todo.completed); } return false; - }, [todos]); - - const onInputChange = (event: React.ChangeEvent) => { - event.preventDefault(); - setTitle(event.target.value); - }; - - const addTodo = (todoTitle: string) => { - const newTodo: Todo = { - id: +new Date(), - title: todoTitle, - completed: false, - }; - - setTodos([...todos, newTodo]); }; const onSubmit = (event: React.FormEvent) => { @@ -55,12 +29,18 @@ export const Header: React.FC = ({ focused, setFocused }) => { const normalizedTitle = title.trim(); - if (normalizedTitle.length > 0) { - addTodo(normalizedTitle); - setTitle(''); - } else { + if (!normalizedTitle) { return; } + + const newTodo: Todo = { + id: +new Date(), + title: normalizedTitle, + completed: false, + }; + + setTodos([...todos, newTodo]); + setTitle(''); }; const toggleAll = () => { @@ -72,7 +52,6 @@ export const Header: React.FC = ({ focused, setFocused }) => { })); setTodos(toggledTodos); - setFocused(true); }; return ( @@ -88,15 +67,12 @@ export const Header: React.FC = ({ focused, setFocused }) => { /> )} -
onSubmit(event)} - onBlur={() => setFocused(false)} - > + onSubmit(event)}> onInputChange(event)} + onChange={event => setTitle(event.target.value)} type="text" className="todoapp__new-todo" placeholder="What needs to be done?" diff --git a/src/components/TodoItem.tsx b/src/components/TodoItem.tsx index 32bfb0587..57027a63c 100644 --- a/src/components/TodoItem.tsx +++ b/src/components/TodoItem.tsx @@ -7,20 +7,18 @@ import { TodosContext } from '../context/TodosContex'; type Props = { todo: Todo; - setFocused: (value: boolean) => void; }; -export const TodoItem: React.FC = ({ todo, setFocused }) => { +export const TodoItem: React.FC = ({ todo }) => { const { todos, setTodos } = useContext(TodosContext); const [onEdit, setOnEdit] = useState(false); const [title, setTitle] = useState(todo.title); const todoInputRef = useRef(null); - const normalizedTitle = title.trim(); useEffect(() => { - if (onEdit && todoInputRef.current) { + if (todoInputRef.current) { todoInputRef.current.focus(); } }, [onEdit]); @@ -32,32 +30,12 @@ export const TodoItem: React.FC = ({ todo, setFocused }) => { } }; - const onInputChange = (event: React.ChangeEvent) => { - event.preventDefault(); - - setTitle(event.target.value); - }; - const updateTodo = (updatedTodo: Todo) => { - const newTodos = [...todos]; - - const index = todos.findIndex( - currentTodo => currentTodo.id === updatedTodo.id, - ); - - newTodos.splice(index, 1, updatedTodo); - - setFocused(true); - setTodos(newTodos); - }; - - const deleteTodo = () => { - setTodos(todos.filter(currentTodo => currentTodo.id !== todo.id)); + setTodos(todos.map(t => (t.id === updatedTodo.id ? updatedTodo : t))); }; const onDelete = () => { - deleteTodo(); - setFocused(true); + setTodos(todos.filter(currentTodo => currentTodo.id !== todo.id)); }; const statusChange = () => { @@ -66,22 +44,17 @@ export const TodoItem: React.FC = ({ todo, setFocused }) => { const onSubmit = (event?: React.FormEvent) => { event?.preventDefault(); + setOnEdit(false); - if (normalizedTitle.length === 0) { - deleteTodo(); - - return; - } + const normalizedTitle = title.trim(); - if (normalizedTitle === todo.title) { - setTitle(normalizedTitle); - setOnEdit(false); + if (!normalizedTitle) { + onDelete(); return; } - updateTodo({ ...todo, title: title }); - setOnEdit(false); + updateTodo({ ...todo, title: normalizedTitle }); }; return ( @@ -122,7 +95,7 @@ export const TodoItem: React.FC = ({ todo, setFocused }) => { ref={todoInputRef} value={title} onChange={event => { - onInputChange(event); + setTitle(event.target.value); }} onBlur={() => onSubmit()} onKeyUp={event => handleKeyUp(event)} diff --git a/src/components/TodoList.tsx b/src/components/TodoList.tsx index 3b74926d1..036cde44c 100644 --- a/src/components/TodoList.tsx +++ b/src/components/TodoList.tsx @@ -3,14 +3,13 @@ import { Todo } from '../types/Todo'; type Props = { visibleTodos: Todo[]; - setFocused: (value: boolean) => void; }; -export const TodoList: React.FC = ({ visibleTodos, setFocused }) => { +export const TodoList: React.FC = ({ visibleTodos }) => { return (
{visibleTodos.map(todo => ( - + ))}
); diff --git a/src/styles/todoapp.scss b/src/styles/todoapp.scss index e289a9458..2f9ee48e9 100644 --- a/src/styles/todoapp.scss +++ b/src/styles/todoapp.scss @@ -1,3 +1,7 @@ +* { + box-sizing: border-box; +} + .todoapp { font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 24px;