Skip to content

Instantly share code, notes, and snippets.

@donabrams
Last active October 4, 2015 19:10
Show Gist options
  • Select an option

  • Save donabrams/3913bf7635f95f80397b to your computer and use it in GitHub Desktop.

Select an option

Save donabrams/3913bf7635f95f80397b to your computer and use it in GitHub Desktop.
Ember TodoMVC quasi port to React
// This Page Component would normally be auto-generated from a template
class TodoPage extends Component {
render() {
let bootstrap = `
var Todos = require('Todos');
// really, we use redux for injecting/setting up initialProps and tying in action handlers
var element = React.createElement(Todos, {});
React.render(element, getElementById('app'));
`;
return (
<html lang="en">
<head>
<meta charset="utf-8"/>
<title>React.js • TodoMVC</title>
<link rel="stylesheet" href="node_modules/todomvc-common/base.css"/>
<link rel="stylesheet" href="node_modules/todomvc-app-css/index.css"/>
<script src="bundle.js"/>
</head>
<body>
<div id="app"/>
<script dangerouslySetInnerHTML={{__html: bootstrap}}/>
</body>
</html>
);
}
}
// We'd normally get this from a designer with a note about the 'selected' class in one hardcoded filter
// 'onClick' and classnames may or may not bein there, depending on the tech-savviness of the designers.
class Todos extends Component {
render() {
let {items, itemLabel, remaining, curFilter, completed, clearCompleted, filterDisplayedTodos} = this.props;
return (
<section id="todoapp">
<header id="header">
<h1>todos</h1>
<input id="new-todo" type="text" value={newTitle} onClick={createTodo} placeholder="What needs to be done?"/>
</header>
<TodoList {...this.props}/>
<footer display-if={items.length} id="footer">
<span id="todo-count"><strong>{{remaining.length}}</strong> {itemName(remaining)} left</span>
<ul id="filters">
<li>
<a href="#all" onClick={filterDisplayedTodos('all')} className={classnames({'selected': curFilter === 'all'})}>All</a>
</li>
<li>
<a href="#active" onClick={filterDisplayedTodos('active')} className={classnames({'selected': curFilter === 'active'})}>Active</a>
</li>
<li>
<a href="#completed" onClick={filterDisplayedTodos('completed')} className={classnames({'selected': curFilter === 'completed'})}>Completed</a>
</li>
</ul>
<button display-if={completed.length} id="clear-completed" onClick={clearCompleted}>Clear completed</button>
</footer>
</section>
);
}
}
class TodoList extends Component {
render() {
let {items, canToggle, allTodos, itemActions} = this.props;
return (
<section display-if={items && items.length} id="main">
<input display-if={canToggle} type="checkbox" id="toggle-all" checked={allTodos.allAreDone}/>
<ul id="todo-list">
{items.map((item)=> (
<TodoItem key={item.id} {...item} {...itemActions}/>
))}
</ul>
</section>
);
}
}
class TodoItem extends Component {
render() {
let {id, completed, editing, bufferedTitle, title, doneEditing, handleInput, editTodo, removeTodo} = this.props;
return (
<li className={classnames({'isCompleted': completed}, {'isEditing': editing})}>
<input display-if={editing} type="text" className="edit" value={bufferedTitle} onFocusOut={doneEditing(id)} onKeyDown={handleInput(id)}/>
<span display-if={!editing}>
<input type="checkbox" className="toggle" checked={completed}/>
<label onDoubleClick={editTodo(id)}>{title}</label>
<button onClick={removeTodo(id)} className="destroy"></button>
</span>
</li>
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment