Skip to content

Commit

Permalink
Add todomvc-typescript-react
Browse files Browse the repository at this point in the history
  • Loading branch information
Dane Harnett committed Oct 8, 2020
1 parent 9c20467 commit 655e676
Show file tree
Hide file tree
Showing 20 changed files with 25,432 additions and 0 deletions.
19 changes: 19 additions & 0 deletions todomvc-typescript-react/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<!doctype html>
<html lang="en" data-framework="typescript">
<head>
<meta charset="utf-8">
<title>React • TodoMVC</title>
<link rel="stylesheet" href="node_modules/todomvc-common/base.css">
<link rel="stylesheet" href="node_modules/todomvc-app-css/index.css">
</head>
<body>
<section class="todoapp"></section>
<footer class="info">
<p>Double-click to edit a todo</p>
<p>Created by <a href="http://github.com/remojansen/">Remo H. Jansen</a></p>
<p>Part of <a href="http://todomvc.com">TodoMVC</a></p>
</footer>
<script type="text/javascript" src="node_modules/director/build/director.js"></script>
<script type="text/javascript" src="js/bundle.js"></script>
</body>
</html>
119 changes: 119 additions & 0 deletions todomvc-typescript-react/js/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var React = require("react");
var ReactDOM = require("react-dom");
var todoModel_1 = require("./todoModel");
var footer_1 = require("./footer");
var todoItem_1 = require("./todoItem");
var constants_1 = require("./constants");
var TodoApp = (function (_super) {
__extends(TodoApp, _super);
function TodoApp(props) {
var _this = _super.call(this, props) || this;
_this.state = {
nowShowing: constants_1.ALL_TODOS,
editing: null
};
return _this;
}
TodoApp.prototype.componentDidMount = function () {
var setState = this.setState;
var router = Router({
'/': setState.bind(this, { nowShowing: constants_1.ALL_TODOS }),
'/active': setState.bind(this, { nowShowing: constants_1.ACTIVE_TODOS }),
'/completed': setState.bind(this, { nowShowing: constants_1.COMPLETED_TODOS })
});
router.init('/');
};
TodoApp.prototype.handleNewTodoKeyDown = function (event) {
if (event.keyCode !== constants_1.ENTER_KEY) {
return;
}
event.preventDefault();
var val = ReactDOM.findDOMNode(this.refs["newField"]).value.trim();
if (val) {
this.props.model.addTodo(val);
ReactDOM.findDOMNode(this.refs["newField"]).value = '';
}
};
TodoApp.prototype.toggleAll = function (event) {
var target = event.target;
var checked = target.checked;
this.props.model.toggleAll(checked);
};
TodoApp.prototype.toggle = function (todoToToggle) {
this.props.model.toggle(todoToToggle);
};
TodoApp.prototype.destroy = function (todo) {
this.props.model.destroy(todo);
};
TodoApp.prototype.edit = function (todo) {
this.setState({ editing: todo.id });
};
TodoApp.prototype.save = function (todoToSave, text) {
this.props.model.save(todoToSave, text);
this.setState({ editing: null });
};
TodoApp.prototype.cancel = function () {
this.setState({ editing: null });
};
TodoApp.prototype.clearCompleted = function () {
this.props.model.clearCompleted();
};
TodoApp.prototype.render = function () {
var _this = this;
var footer;
var main;
var todos = this.props.model.todos;
var shownTodos = todos.filter(function (todo) {
switch (_this.state.nowShowing) {
case constants_1.ACTIVE_TODOS:
return !todo.completed;
case constants_1.COMPLETED_TODOS:
return todo.completed;
default:
return true;
}
});
var todoItems = shownTodos.map(function (todo) {
return (React.createElement(todoItem_1.TodoItem, { key: todo.id, todo: todo, onToggle: _this.toggle.bind(_this, todo), onDestroy: _this.destroy.bind(_this, todo), onEdit: _this.edit.bind(_this, todo), editing: _this.state.editing === todo.id, onSave: _this.save.bind(_this, todo), onCancel: function (e) { return _this.cancel(); } }));
});
var activeTodoCount = todos.reduce(function (accum, todo) {
return todo.completed ? accum : accum + 1;
}, 0);
var completedCount = todos.length - activeTodoCount;
if (activeTodoCount || completedCount) {
footer =
React.createElement(footer_1.TodoFooter, { count: activeTodoCount, completedCount: completedCount, nowShowing: this.state.nowShowing, onClearCompleted: function (e) { return _this.clearCompleted(); } });
}
if (todos.length) {
main = (React.createElement("section", { className: "main" },
React.createElement("input", { id: "toggle-all", className: "toggle-all", type: "checkbox", onChange: function (e) { return _this.toggleAll(e); }, checked: activeTodoCount === 0 }),
React.createElement("label", { htmlFor: "toggle-all" }, "Mark all as complete"),
React.createElement("ul", { className: "todo-list" }, todoItems)));
}
return (React.createElement("div", null,
React.createElement("header", { className: "header" },
React.createElement("h1", null, "todos"),
React.createElement("input", { ref: "newField", className: "new-todo", placeholder: "What needs to be done?", onKeyDown: function (e) { return _this.handleNewTodoKeyDown(e); }, autoFocus: true })),
main,
footer));
};
return TodoApp;
}(React.Component));
var model = new todoModel_1.TodoModel('react-todos');
function render() {
ReactDOM.render(React.createElement(TodoApp, { model: model }), document.getElementsByClassName('todoapp')[0]);
}
model.subscribe(render);
render();
187 changes: 187 additions & 0 deletions todomvc-typescript-react/js/app.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
/*jshint quotmark:false */
/*jshint white:false */
/*jshint trailing:false */
/*jshint newcap:false */
/*global React, Router*/

/// <reference path="./interfaces.d.ts"/>

declare var Router;
import * as React from "react";
import * as ReactDOM from "react-dom";
import { TodoModel } from "./todoModel";
import { TodoFooter } from "./footer";
import { TodoItem } from "./todoItem";
import { ALL_TODOS, ACTIVE_TODOS, COMPLETED_TODOS, ENTER_KEY } from "./constants";

class TodoApp extends React.Component<IAppProps, IAppState> {

public state : IAppState;

constructor(props : IAppProps) {
super(props);
this.state = {
nowShowing: ALL_TODOS,
editing: null
};
}

public componentDidMount() {
var setState = this.setState;
var router = Router({
'/': setState.bind(this, {nowShowing: ALL_TODOS}),
'/active': setState.bind(this, {nowShowing: ACTIVE_TODOS}),
'/completed': setState.bind(this, {nowShowing: COMPLETED_TODOS})
});
router.init('/');
}

public handleNewTodoKeyDown(event : React.KeyboardEvent) {
if (event.keyCode !== ENTER_KEY) {
return;
}

event.preventDefault();

var val = (ReactDOM.findDOMNode(this.refs["newField"]) as HTMLInputElement).value.trim();

if (val) {
this.props.model.addTodo(val);
(ReactDOM.findDOMNode(this.refs["newField"]) as HTMLInputElement).value = '';
}
}

public toggleAll(event : React.FormEvent) {
var target : any = event.target;
var checked = target.checked;
this.props.model.toggleAll(checked);
}

public toggle(todoToToggle : ITodo) {
this.props.model.toggle(todoToToggle);
}

public destroy(todo : ITodo) {
this.props.model.destroy(todo);
}

public edit(todo : ITodo) {
this.setState({editing: todo.id});
}

public save(todoToSave : ITodo, text : String) {
this.props.model.save(todoToSave, text);
this.setState({editing: null});
}

public cancel() {
this.setState({editing: null});
}

public clearCompleted() {
this.props.model.clearCompleted();
}

public render() {
var footer;
var main;
const todos = this.props.model.todos;

var shownTodos = todos.filter((todo) => {
switch (this.state.nowShowing) {
case ACTIVE_TODOS:
return !todo.completed;
case COMPLETED_TODOS:
return todo.completed;
default:
return true;
}
});

var todoItems = shownTodos.map((todo) => {
return (
<TodoItem
key={todo.id}
todo={todo}
onToggle={this.toggle.bind(this, todo)}
onDestroy={this.destroy.bind(this, todo)}
onEdit={this.edit.bind(this, todo)}
editing={this.state.editing === todo.id}
onSave={this.save.bind(this, todo)}
onCancel={ e => this.cancel() }
/>
);
});

// Note: It's usually better to use immutable data structures since they're
// easier to reason about and React works very well with them. That's why
// we use map(), filter() and reduce() everywhere instead of mutating the
// array or todo items themselves.
var activeTodoCount = todos.reduce(function (accum, todo) {
return todo.completed ? accum : accum + 1;
}, 0);

var completedCount = todos.length - activeTodoCount;

if (activeTodoCount || completedCount) {
footer =
<TodoFooter
count={activeTodoCount}
completedCount={completedCount}
nowShowing={this.state.nowShowing}
onClearCompleted={ e=> this.clearCompleted() }
/>;
}

if (todos.length) {
main = (
<section className="main">
<input
id="toggle-all"
className="toggle-all"
type="checkbox"
onChange={ e => this.toggleAll(e) }
checked={activeTodoCount === 0}
/>
<label
htmlFor="toggle-all"
>
Mark all as complete
</label>
<ul className="todo-list">
{todoItems}
</ul>
</section>
);
}

return (
<div>
<header className="header">
<h1>todos</h1>
<input
ref="newField"
className="new-todo"
placeholder="What needs to be done?"
onKeyDown={ e => this.handleNewTodoKeyDown(e) }
autoFocus={true}
/>
</header>
{main}
{footer}
</div>
);
}
}

var model = new TodoModel('react-todos');

function render() {
ReactDOM.render(
<TodoApp model={model}/>,
document.getElementsByClassName('todoapp')[0]
);
}

model.subscribe(render);
render();
Loading

0 comments on commit 655e676

Please sign in to comment.