Skip to content

Instantly share code, notes, and snippets.

@simontreny
Last active October 18, 2019 15:38
Show Gist options
  • Save simontreny/9bae573dc7c5ad0c9cb5357f2f26b8ce to your computer and use it in GitHub Desktop.
Save simontreny/9bae573dc7c5ad0c9cb5357f2f26b8ce to your computer and use it in GitHub Desktop.
import React from "react";
import { useObservable } from "./observableHook";
import { todoService } from "./services";
import { Todo, VisibilityFilter } from "./todoService";
export const TodoList = () => {
const todos = useObservable(todoService.todos);
const filter = useObservable(todoService.visibilityFilter);
const visibleTodos = getVisibleTodos(todos, filter);
return (
<div>
<ul>
{visibleTodos.map((todo, index) => (
<TodoItem key={index} todo={todo} index={index} />
))}
</ul>
<p>
Show: <FilterLink filter={VisibilityFilter.SHOW_ALL}>All</FilterLink>,
<FilterLink filter={VisibilityFilter.SHOW_ACTIVE}>Active</FilterLink>,
<FilterLink filter={VisibilityFilter.SHOW_ALL}>Completed</FilterLink>
</p>
</div>
);
};
const TodoItem = ({ todo: { text, completed }, index }: { todo: Todo; index: number }) => {
return (
<li
style={{
textDecoration: completed ? "line-through" : "none",
}}
onClick={() => todoService.toggleTodo(index)}
>
{text}
</li>
);
};
const FilterLink = ({ filter, children }: { filter: VisibilityFilter; children: React.ReactNode }) => {
const activeFilter = useObservable(todoService.visibilityFilter);
const active = filter === activeFilter;
return active ? (
<span>{children}</span>
) : (
<a href="" onClick={() => todoService.setVisibilityFilter(filter)}>
{children}
</a>
);
};
function getVisibleTodos(todos: Todo[], filter: VisibilityFilter): Todo[] {
switch (filter) {
case VisibilityFilter.SHOW_ALL:
return todos;
case VisibilityFilter.SHOW_COMPLETED:
return todos.filter(t => t.completed);
case VisibilityFilter.SHOW_ACTIVE:
return todos.filter(t => !t.completed);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment