changed step names

This commit is contained in:
Micah Godbolt
2019-02-14 10:15:39 -08:00
parent d0d6a788e2
commit 41a79e8883
34 changed files with 16 additions and 14 deletions

9
step1-07/index.html Normal file
View File

@@ -0,0 +1,9 @@
<!DOCTYPE html>
<html>
<link rel="stylesheet" href="./src/style.css" />
<body>
<div id="app"></div>
</body>
</html>

76
step1-07/src/App.tsx Normal file
View File

@@ -0,0 +1,76 @@
import React from "react";
import { TodoFooter } from "./components/TodoFooter";
import { TodoHeader } from "./components/TodoHeader";
import { TodoList } from "./components/TodoList";
export class TodoApp extends React.Component<any, any> {
constructor(props) {
super(props);
this.state = {
inputValue: "",
todos: [],
filter: "all"
};
}
render() {
const { filter, todos, inputValue } = this.state;
return (
<div>
<TodoHeader
onInputChange={this._updateInput}
inputValue={inputValue}
onTodoSubmit={this._addTodo}
onFilterClick={this._updateFilter}
filter={filter}
/>
<TodoList onTodoToggle={this._toggleTodoComplete} todos={todos} filter={filter} />
<TodoFooter onClearClick={this._removeCompletedTodos} todos={todos} />
</div>
);
}
_addTodo = () => {
const { todos, inputValue } = this.state;
const newTodos = [
{
id: todos[0] ? todos[0].id + 1 : 0,
text: inputValue
},
...todos
];
this.setState({
todos: newTodos,
inputValue: ""
});
};
_toggleTodoComplete = (id) => {
this.setState({
todos: this.state.todos.map(todo => {
if (todo.id == id) {todo.completed = !todo.completed}
return todo;
})
})
}
_removeCompletedTodos = () => {
this.setState({
todos: this.state.todos.filter(todo => {
return !todo.completed;
})
})
}
_updateFilter = (filter) => {
this.setState({
filter: filter
})
};
_updateInput = ev => {
this.setState({
inputValue: ev.target.value
});
};
}

View File

@@ -0,0 +1,11 @@
import React from "react";
export const TodoFooter = (props: any) => {
const items = props.todos.filter(todo => !todo.completed)
return (
<footer>
<span> {items.length} items left </span>
<button onClick={props.onClearClick} className="button">Clear Completed</button>
</footer>
);
};

View File

@@ -0,0 +1,21 @@
import React from "react";
export class TodoHeader extends React.Component<any, any> {
render() {
const { filter, inputValue, onInputChange, onTodoSubmit, onFilterClick } = this.props;
return (
<div>
<h1>todos</h1>
<input value={inputValue} onChange={onInputChange} className="textfield" />
<button onClick={onTodoSubmit} className="button add">Add</button>
<div className="filter">
<button onClick={() => onFilterClick('all')} className={filter == "all" ? "active" : ""}>all</button>
<button onClick={() => onFilterClick('active')} className={filter == "active" ? "active" : ""}>active</button>
<button onClick={() => onFilterClick('completed')} className={filter == "completed" ? "active" : ""}>
completed
</button>
</div>
</div>
);
}
}

View File

@@ -0,0 +1,28 @@
import React from 'react';
import { TodoListItem } from './TodoListItem';
export class TodoList extends React.Component<any, any> {
render() {
const { filter, todos, onTodoToggle } = this.props;
let filteredTodos: typeof todos = {};
filteredTodos = todos.filter(todo => {
const matchesActive = filter == 'active' && !todo.completed;
const matchesCompleted = filter == 'completed' && todo.completed;
return filter == 'all' || matchesActive || matchesCompleted;
})
const TodoListItems = filteredTodos.map((todo) => {
return (
<TodoListItem key={todo.id} onTodoToggle={onTodoToggle} {...todo} />
);
})
return (
<ul className="todos">
{TodoListItems}
</ul>
);
}
}

View File

@@ -0,0 +1,15 @@
import React from "react";
export class TodoListItem extends React.Component<any, any> {
render() {
const {text, completed, onTodoToggle, id} = this.props;
return (
<li className="todo">
<label>
<input onClick={() => onTodoToggle(id)} type="checkbox" checked={completed} /> {text}
</label>
</li>
);
}
}

4
step1-07/src/index.tsx Normal file
View File

@@ -0,0 +1,4 @@
import React from "react";
import ReactDOM from "react-dom";
import { TodoApp } from "./App";
ReactDOM.render(<TodoApp />, document.getElementById("app"));

50
step1-07/src/style.css Normal file
View File

@@ -0,0 +1,50 @@
body {
font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
width: 400px;
margin: 20px auto;
}
h1 {
text-align: center;
}
.textfield {
width: 80%;
}
.add {
margin-left: 5%;
}
.button {
border: none;
padding: 5px 10px;
}
.filter {
margin: 10px 0 0;
}
.filter button {
background: transparent;
border: none;
}
.filter .active {
border-bottom: 2px solid blue;
}
.todos {
list-style: none;
padding: 0;
}
footer {
display: flex;
}
footer span {
flex-grow: 1;
}
.hidden {
display: none;
}