Here you can see in the demo we've got it working so that you can add a new task and instantly start typing. Notice that if you cancel, it will remove the element. That requires special handling.

When we add the new task in App.js, we set a special attribute isNew on the task. Then, in the Task.js, we default to editing if this attribute is present. The result is that an editable input appears by default. You'll notice that when we cancelEdit, we check if the task isNew, if it is, then we call the destroy function. This is because the task already exists in the array, and if someone is canceling a task that was never supposed to be created in the first place, we want to destroy it.

We ensure that we set isNew: false onSave since it is no longer new at that point.

Your mission

Completing tasks.

Menu
Lesson 19/20
import { useState } from "react";
import styled from "styled-components";
import Button, { IconButton } from "./Button";

const TaskName = styled.div``;

const TaskInput = styled.input``;

const TaskRow = styled.div`
  display: grid; 
  grid-template-columns: 1fr 100px; 
  gap: 5px; 
  margin: 10px 0px; 
  width: 100%;   
`;

const RowActions = styled.div`
  display: grid; 
  grid-template-columns: 1fr 1fr; 
  gap: 4px; 
`;

function Task({ task, onSave, onDestroy }) {
  const [editing, setEditing] = useState(task.isNew);
  const [name, setName] = useState(task.name);

  function saveEdit() {
    onSave({
      ...task,
      isNew: false,
      name,
    });
    setEditing(!editing);
  }

  function cancelEdit() {
    if (task.isNew) {
      onDestroy(task.id);
      return;
    }
    setName(task.name);
    setEditing(false);
  }

  function editName({ target: { value } }) {
    setName(value);
  }

  return (
    <TaskRow>
      {editing ? (
        <TaskInput placeholder={name} autoFocus onChange={editName} />
      ) : (
        <TaskName> {name} </TaskName>
      )}
      <RowActions>
        {editing ? (
          <>
            <Button onClick={saveEdit}> Save </Button>
            <Button onClick={cancelEdit}> Cancel </Button>
          </>
        ) : (
          <>
            <IconButton onClick={() => setEditing(true)}> ✏️ </IconButton>
            <IconButton onClick={() => onDestroy(task.id)}> 🗑️ </IconButton>
          </>
        )}
      </RowActions>
    </TaskRow>
  );
}

export default Task;