Commit 9c7b1a25 authored by remojansen's avatar remojansen Committed by Sam Saccone

new app typescript-react

parent 99011a62
......@@ -33,6 +33,7 @@
"examples/angular2/**/*.js",
"examples/polymer/elements/elements.build.js",
"examples/js_of_ocaml/js/*.js",
"examples/typescript-react/js/*.js",
"**/generated/**"
],
"requireSpaceBeforeBlockStatements": true,
......
<!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/todomvc-common/base.js"></script>
<script type="text/javascript" src="node_modules/react/dist/react-with-addons.js"></script>
<script type="text/javascript" src="node_modules/classnames/index.js"></script>
<script type="text/javascript" src="node_modules/director/build/director.js"></script>
<script type="text/javascript" src="js/bundle.js"></script>
</body>
</html>
/*jshint quotmark:false */
/*jshint white:false */
/*jshint trailing:false */
/*jshint newcap:false */
/*global React, Router*/
var __extends = (this && this.__extends) || function (d, b) {
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
/// <reference path="../typings/tsd.d.ts" />
/// <reference path="./interfaces.d.ts"/>
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) {
_super.call(this, props);
this.state = {
nowShowing: constants_1.ALL_TODOS,
editing: null
};
}
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 = React.findDOMNode(this.refs["newField"]).value.trim();
if (val) {
this.props.model.addTodo(val);
React.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", {"className": "toggle-all", "type": "checkbox", "onChange": function (e) { return _this.toggleAll(e); }, "checked": activeTodoCount === 0}), 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() {
React.render(React.createElement(TodoApp, {"model": model}), document.getElementsByClassName('todoapp')[0]);
}
model.subscribe(render);
render();
/*jshint quotmark:false */
/*jshint white:false */
/*jshint trailing:false */
/*jshint newcap:false */
/*global React, Router*/
/// <reference path="../typings/tsd.d.ts" />
/// <reference path="./interfaces.d.ts"/>
declare var Router;
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 = React.findDOMNode<HTMLInputElement>(this.refs["newField"]).value.trim();
if (val) {
this.props.model.addTodo(val);
React.findDOMNode<HTMLInputElement>(this.refs["newField"]).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
className="toggle-all"
type="checkbox"
onChange={ e => this.toggleAll(e) }
checked={activeTodoCount === 0}
/>
<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() {
React.render(
<TodoApp model={model}/>,
document.getElementsByClassName('todoapp')[0]
);
}
model.subscribe(render);
render();
This diff is collapsed.
var ALL_TODOS = 'all';
exports.ALL_TODOS = ALL_TODOS;
var ACTIVE_TODOS = 'active';
exports.ACTIVE_TODOS = ACTIVE_TODOS;
var COMPLETED_TODOS = 'completed';
exports.COMPLETED_TODOS = COMPLETED_TODOS;
var ENTER_KEY = 13;
exports.ENTER_KEY = ENTER_KEY;
var ESCAPE_KEY = 27;
exports.ESCAPE_KEY = ESCAPE_KEY;
const ALL_TODOS = 'all';
const ACTIVE_TODOS = 'active';
const COMPLETED_TODOS = 'completed';
const ENTER_KEY = 13;
const ESCAPE_KEY = 27;
export { ALL_TODOS, ACTIVE_TODOS, COMPLETED_TODOS, ENTER_KEY, ESCAPE_KEY };
/*jshint quotmark:false */
/*jshint white:false */
/*jshint trailing:false */
/*jshint newcap:false */
/*global React */
var __extends = (this && this.__extends) || function (d, b) {
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
/// <reference path="../typings/tsd.d.ts" />
/// <reference path="./interfaces.d.ts"/>
var constants_1 = require("./constants");
var utils_1 = require("./utils");
var TodoFooter = (function (_super) {
__extends(TodoFooter, _super);
function TodoFooter() {
_super.apply(this, arguments);
}
TodoFooter.prototype.render = function () {
var activeTodoWord = utils_1.Utils.pluralize(this.props.count, 'item');
var clearButton = null;
if (this.props.completedCount > 0) {
clearButton = (React.createElement("button", {"className": "clear-completed", "onClick": this.props.onClearCompleted}, "Clear completed"));
}
var nowShowing = this.props.nowShowing;
return (React.createElement("footer", {"className": "footer"}, React.createElement("span", {"className": "todo-count"}, React.createElement("strong", null, this.props.count), " ", activeTodoWord, " left"), React.createElement("ul", {"className": "filters"}, React.createElement("li", null, React.createElement("a", {"href": "#/", "className": classNames({ selected: nowShowing === constants_1.ALL_TODOS })}, "All")), ' ', React.createElement("li", null, React.createElement("a", {"href": "#/active", "className": classNames({ selected: nowShowing === constants_1.ACTIVE_TODOS })}, "Active")), ' ', React.createElement("li", null, React.createElement("a", {"href": "#/completed", "className": classNames({ selected: nowShowing === constants_1.COMPLETED_TODOS })}, "Completed"))), clearButton));
};
return TodoFooter;
})(React.Component);
exports.TodoFooter = TodoFooter;
/*jshint quotmark:false */
/*jshint white:false */
/*jshint trailing:false */
/*jshint newcap:false */
/*global React */
/// <reference path="../typings/tsd.d.ts" />
/// <reference path="./interfaces.d.ts"/>
import { ALL_TODOS, ACTIVE_TODOS, COMPLETED_TODOS } from "./constants";
import { Utils } from "./utils";
class TodoFooter extends React.Component<ITodoFooterProps, {}> {
public render() {
var activeTodoWord = Utils.pluralize(this.props.count, 'item');
var clearButton = null;
if (this.props.completedCount > 0) {
clearButton = (
<button
className="clear-completed"
onClick={this.props.onClearCompleted}>
Clear completed
</button>
);
}
const nowShowing = this.props.nowShowing;
return (
<footer className="footer">
<span className="todo-count">
<strong>{this.props.count}</strong> {activeTodoWord} left
</span>
<ul className="filters">
<li>
<a
href="#/"
className={classNames({selected: nowShowing === ALL_TODOS})}>
All
</a>
</li>
{' '}
<li>
<a
href="#/active"
className={classNames({selected: nowShowing === ACTIVE_TODOS})}>
Active
</a>
</li>
{' '}
<li>
<a
href="#/completed"
className={classNames({selected: nowShowing === COMPLETED_TODOS})}>
Completed
</a>
</li>
</ul>
{clearButton}
</footer>
);
}
}
export { TodoFooter };
interface ITodo {
id: string,
title: string,
completed: boolean
}
interface ITodoItemProps {
key : string,
todo : ITodo;
editing? : boolean;
onSave: (val: any) => void;
onDestroy: () => void;
onEdit: () => void;
onCancel: (event : any) => void;
onToggle: () => void;
}
interface ITodoItemState {
editText : string
}
interface ITodoFooterProps {
completedCount : number;
onClearCompleted : any;
nowShowing : string;
count : number;
}
interface ITodoModel {
key : any;
todos : Array<ITodo>;
onChanges : Array<any>;
subscribe(onChange);
inform();
addTodo(title : string);
toggleAll(checked);
toggle(todoToToggle);
destroy(todo);
save(todoToSave, text);
clearCompleted();
}
interface IAppProps {
model : ITodoModel;
}
interface IAppState {
editing? : string;
nowShowing? : string
}
/*jshint quotmark: false */
/*jshint white: false */
/*jshint trailing: false */
/*jshint newcap: false */
/*global React */
var __extends = (this && this.__extends) || function (d, b) {
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
/// <reference path="../typings/tsd.d.ts" />
/// <reference path="./interfaces.d.ts"/>
var constants_1 = require("./constants");
var TodoItem = (function (_super) {
__extends(TodoItem, _super);
function TodoItem(props) {
_super.call(this, props);
this.state = { editText: this.props.todo.title };
}
TodoItem.prototype.handleSubmit = function (event) {
var val = this.state.editText.trim();
if (val) {
this.props.onSave(val);
this.setState({ editText: val });
}
else {
this.props.onDestroy();
}
};
TodoItem.prototype.handleEdit = function () {
this.props.onEdit();
this.setState({ editText: this.props.todo.title });
};
TodoItem.prototype.handleKeyDown = function (event) {
if (event.keyCode === constants_1.ESCAPE_KEY) {
this.setState({ editText: this.props.todo.title });
this.props.onCancel(event);
}
else if (event.keyCode === constants_1.ENTER_KEY) {
this.handleSubmit(event);
}
};
TodoItem.prototype.handleChange = function (event) {
var input = event.target;
this.setState({ editText: input.value });
};
TodoItem.prototype.shouldComponentUpdate = function (nextProps, nextState) {
return (nextProps.todo !== this.props.todo ||
nextProps.editing !== this.props.editing ||
nextState.editText !== this.state.editText);
};
TodoItem.prototype.componentDidUpdate = function (prevProps) {
if (!prevProps.editing && this.props.editing) {
var node = React.findDOMNode(this.refs["editField"]);
node.focus();
node.setSelectionRange(node.value.length, node.value.length);
}
};
TodoItem.prototype.render = function () {
var _this = this;
return (React.createElement("li", {"className": classNames({
completed: this.props.todo.completed,
editing: this.props.editing
})}, React.createElement("div", {"className": "view"}, React.createElement("input", {"className": "toggle", "type": "checkbox", "checked": this.props.todo.completed, "onChange": this.props.onToggle}), React.createElement("label", {"onDoubleClick": function (e) { return _this.handleEdit(); }}, this.props.todo.title), React.createElement("button", {"className": "destroy", "onClick": this.props.onDestroy})), React.createElement("input", {"ref": "editField", "className": "edit", "value": this.state.editText, "onBlur": function (e) { return _this.handleSubmit(e); }, "onChange": function (e) { return _this.handleChange(e); }, "onKeyDown": function (e) { return _this.handleKeyDown(e); }})));
};
return TodoItem;
})(React.Component);
exports.TodoItem = TodoItem;
/*jshint quotmark: false */
/*jshint white: false */
/*jshint trailing: false */
/*jshint newcap: false */
/*global React */
/// <reference path="../typings/tsd.d.ts" />
/// <reference path="./interfaces.d.ts"/>
import { ENTER_KEY, ESCAPE_KEY } from "./constants";
class TodoItem extends React.Component<ITodoItemProps, ITodoItemState> {
public state : ITodoItemState;
constructor(props : ITodoItemProps){
super(props);
this.state = { editText: this.props.todo.title };
}
public handleSubmit(event : __React.FormEvent) {
var val = this.state.editText.trim();
if (val) {
this.props.onSave(val);
this.setState({editText: val});
} else {
this.props.onDestroy();
}
}
public handleEdit() {
this.props.onEdit();
this.setState({editText: this.props.todo.title});
}
public handleKeyDown(event : __React.KeyboardEvent) {
if (event.keyCode === ESCAPE_KEY) {
this.setState({editText: this.props.todo.title});
this.props.onCancel(event);
} else if (event.keyCode === ENTER_KEY) {
this.handleSubmit(event);
}
}
public handleChange(event : __React.FormEvent) {
var input : any = event.target;
this.setState({ editText : input.value });
}
/**
* This is a completely optional performance enhancement that you can
* implement on any React component. If you were to delete this method
* the app would still work correctly (and still be very performant!), we
* just use it as an example of how little code it takes to get an order
* of magnitude performance improvement.
*/
public shouldComponentUpdate(nextProps : ITodoItemProps, nextState : ITodoItemState) {
return (
nextProps.todo !== this.props.todo ||
nextProps.editing !== this.props.editing ||
nextState.editText !== this.state.editText
);
}
/**
* Safely manipulate the DOM after updating the state when invoking
* `this.props.onEdit()` in the `handleEdit` method above.
* For more info refer to notes at https://facebook.github.io/react/docs/component-api.html#setstate
* and https://facebook.github.io/react/docs/component-specs.html#updating-componentdidupdate
*/
public componentDidUpdate(prevProps : ITodoItemProps) {
if (!prevProps.editing && this.props.editing) {
var node = React.findDOMNode<HTMLInputElement>(this.refs["editField"]);
node.focus();
node.setSelectionRange(node.value.length, node.value.length);
}
}
public render() {
return (
<li className={classNames({
completed: this.props.todo.completed,
editing: this.props.editing
})}>
<div className="view">
<input
className="toggle"
type="checkbox"
checked={this.props.todo.completed}
onChange={this.props.onToggle}
/>
<label onDoubleClick={ e => this.handleEdit() }>
{this.props.todo.title}
</label>
<button className="destroy" onClick={this.props.onDestroy} />
</div>
<input
ref="editField"
className="edit"
value={this.state.editText}
onBlur={ e => this.handleSubmit(e) }
onChange={ e => this.handleChange(e) }
onKeyDown={ e => this.handleKeyDown(e) }
/>
</li>
);
}
}
export { TodoItem };
/*jshint quotmark:false */
/*jshint white:false */
/*jshint trailing:false */
/*jshint newcap:false */
/// <reference path="../typings/tsd.d.ts" />
/// <reference path="./interfaces.d.ts"/>
var utils_1 = require("./utils");
var TodoModel = (function () {
function TodoModel(key) {
this.key = key;
this.todos = utils_1.Utils.store(key);
this.onChanges = [];
}
TodoModel.prototype.subscribe = function (onChange) {
this.onChanges.push(onChange);
};
TodoModel.prototype.inform = function () {
utils_1.Utils.store(this.key, this.todos);
this.onChanges.forEach(function (cb) { cb(); });
};
TodoModel.prototype.addTodo = function (title) {
this.todos = this.todos.concat({
id: utils_1.Utils.uuid(),
title: title,
completed: false
});
this.inform();
};
TodoModel.prototype.toggleAll = function (checked) {
this.todos = this.todos.map(function (todo) {
return utils_1.Utils.extend({}, todo, { completed: checked });
});
this.inform();
};
TodoModel.prototype.toggle = function (todoToToggle) {
this.todos = this.todos.map(function (todo) {
return todo !== todoToToggle ?
todo :
utils_1.Utils.extend({}, todo, { completed: !todo.completed });
});
this.inform();
};
TodoModel.prototype.destroy = function (todo) {
this.todos = this.todos.filter(function (candidate) {
return candidate !== todo;
});
this.inform();
};
TodoModel.prototype.save = function (todoToSave, text) {
this.todos = this.todos.map(function (todo) {
return todo !== todoToSave ? todo : utils_1.Utils.extend({}, todo, { title: text });
});
this.inform();
};
TodoModel.prototype.clearCompleted = function () {
this.todos = this.todos.filter(function (todo) {
return !todo.completed;
});
this.inform();
};
return TodoModel;
})();
exports.TodoModel = TodoModel;
/*jshint quotmark:false */
/*jshint white:false */
/*jshint trailing:false */
/*jshint newcap:false */
/// <reference path="../typings/tsd.d.ts" />
/// <reference path="./interfaces.d.ts"/>
import { Utils } from "./utils";
// Generic "model" object. You can use whatever
// framework you want. For this application it
// may not even be worth separating this logic
// out, but we do this to demonstrate one way to
// separate out parts of your application.
class TodoModel implements ITodoModel {
public key : string;
public todos : Array<ITodo>;
public onChanges : Array<any>;
constructor(key) {
this.key = key;
this.todos = Utils.store(key);
this.onChanges = [];
}
public subscribe(onChange) {
this.onChanges.push(onChange);
}
public inform() {
Utils.store(this.key, this.todos);
this.onChanges.forEach(function (cb) { cb(); });
}
public addTodo(title : string) {
this.todos = this.todos.concat({
id: Utils.uuid(),
title: title,
completed: false
});
this.inform();
}
public toggleAll(checked : Boolean) {
// 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.
this.todos = this.todos.map<ITodo>((todo : ITodo) => {
return Utils.extend({}, todo, {completed: checked});
});
this.inform();
}
public toggle(todoToToggle : ITodo) {
this.todos = this.todos.map<ITodo>((todo : ITodo) => {
return todo !== todoToToggle ?
todo :
Utils.extend({}, todo, {completed: !todo.completed});
});
this.inform();
}
public destroy(todo : ITodo) {
this.todos = this.todos.filter(function (candidate) {
return candidate !== todo;
});
this.inform();
}
public save(todoToSave : ITodo, text : string) {
this.todos = this.todos.map(function (todo) {
return todo !== todoToSave ? todo : Utils.extend({}, todo, {title: text});
});
this.inform();
}
public clearCompleted() {
this.todos = this.todos.filter(function (todo) {
return !todo.completed;
});
this.inform();
}
}
export { TodoModel };
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"moduleResolution": "node",
"isolatedModules": false,
"jsx": "react",
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"declaration": false,
"noImplicitAny": false,
"removeComments": true,
"noLib": false,
"preserveConstEnums": true,
"suppressImplicitAnyIndexErrors": true
},
"filesGlob": [
"**/*.ts",
"**/*.tsx",
"!node_modules/**"
],
"files": [
"constants.ts",
"interfaces.d.ts",
"todoModel.ts",
"utils.ts",
"app.tsx",
"footer.tsx",
"todoItem.tsx"
],
"exclude": []
}
var Utils = (function () {
function Utils() {
}
Utils.uuid = function () {
var i, random;
var uuid = '';
for (i = 0; i < 32; i++) {
random = Math.random() * 16 | 0;
if (i === 8 || i === 12 || i === 16 || i === 20) {
uuid += '-';
}
uuid += (i === 12 ? 4 : (i === 16 ? (random & 3 | 8) : random))
.toString(16);
}
return uuid;
};
Utils.pluralize = function (count, word) {
return count === 1 ? word : word + 's';
};
Utils.store = function (namespace, data) {
if (data) {
return localStorage.setItem(namespace, JSON.stringify(data));
}
var store = localStorage.getItem(namespace);
return (store && JSON.parse(store)) || [];
};
Utils.extend = function () {
var objs = [];
for (var _i = 0; _i < arguments.length; _i++) {
objs[_i - 0] = arguments[_i];
}
var newObj = {};
for (var i = 0; i < objs.length; i++) {
var obj = objs[i];
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
newObj[key] = obj[key];
}
}
}
return newObj;
};
return Utils;
})();
exports.Utils = Utils;
class Utils {
public static uuid() : string {
/*jshint bitwise:false */
var i, random;
var uuid = '';
for (i = 0; i < 32; i++) {
random = Math.random() * 16 | 0;
if (i === 8 || i === 12 || i === 16 || i === 20) {
uuid += '-';
}
uuid += (i === 12 ? 4 : (i === 16 ? (random & 3 | 8) : random))
.toString(16);
}
return uuid;
}
public static pluralize(count: number, word: string) {
return count === 1 ? word : word + 's';
}
public static store(namespace : string, data? : any) {
if (data) {
return localStorage.setItem(namespace, JSON.stringify(data));
}
var store = localStorage.getItem(namespace);
return (store && JSON.parse(store)) || [];
}
public static extend(...objs : any[]) : any {
var newObj = {};
for (var i = 0; i < objs.length; i++) {
var obj = objs[i];
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
newObj[key] = obj[key];
}
}
}
return newObj;
}
}
export { Utils };
/*!
Copyright (c) 2015 Jed Watson.
Licensed under the MIT License (MIT), see
http://jedwatson.github.io/classnames
*/
/* global define */
(function () {
'use strict';
var hasOwn = {}.hasOwnProperty;
function classNames () {
var classes = '';
for (var i = 0; i < arguments.length; i++) {
var arg = arguments[i];
if (!arg) continue;
var argType = typeof arg;
if (argType === 'string' || argType === 'number') {
classes += ' ' + arg;
} else if (Array.isArray(arg)) {
classes += ' ' + classNames.apply(null, arg);
} else if (argType === 'object') {
for (var key in arg) {
if (hasOwn.call(arg, key) && arg[key]) {
classes += ' ' + key;
}
}
}
}
return classes.substr(1);
}
if (typeof module !== 'undefined' && module.exports) {
module.exports = classNames;
} else if (typeof define === 'function' && typeof define.amd === 'object' && define.amd) {
// register as 'classnames', consistent with npm package name
define('classnames', function () {
return classNames;
});
} else {
window.classNames = classNames;
}
}());
html,
body {
margin: 0;
padding: 0;
}
button {
margin: 0;
padding: 0;
border: 0;
background: none;
font-size: 100%;
vertical-align: baseline;
font-family: inherit;
font-weight: inherit;
color: inherit;
-webkit-appearance: none;
appearance: none;
-webkit-font-smoothing: antialiased;
-moz-font-smoothing: antialiased;
font-smoothing: antialiased;
}
body {
font: 14px 'Helvetica Neue', Helvetica, Arial, sans-serif;
line-height: 1.4em;
background: #f5f5f5;
color: #4d4d4d;
min-width: 230px;
max-width: 550px;
margin: 0 auto;
-webkit-font-smoothing: antialiased;
-moz-font-smoothing: antialiased;
font-smoothing: antialiased;
font-weight: 300;
}
button,
input[type="checkbox"] {
outline: none;
}
.hidden {
display: none;
}
.todoapp {
background: #fff;
margin: 130px 0 40px 0;
position: relative;
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2),
0 25px 50px 0 rgba(0, 0, 0, 0.1);
}
.todoapp input::-webkit-input-placeholder {
font-style: italic;
font-weight: 300;
color: #e6e6e6;
}
.todoapp input::-moz-placeholder {
font-style: italic;
font-weight: 300;
color: #e6e6e6;
}
.todoapp input::input-placeholder {
font-style: italic;
font-weight: 300;
color: #e6e6e6;
}
.todoapp h1 {
position: absolute;
top: -155px;
width: 100%;
font-size: 100px;
font-weight: 100;
text-align: center;
color: rgba(175, 47, 47, 0.15);
-webkit-text-rendering: optimizeLegibility;
-moz-text-rendering: optimizeLegibility;
text-rendering: optimizeLegibility;
}
.new-todo,
.edit {
position: relative;
margin: 0;
width: 100%;
font-size: 24px;
font-family: inherit;
font-weight: inherit;
line-height: 1.4em;
border: 0;
outline: none;
color: inherit;
padding: 6px;
border: 1px solid #999;
box-shadow: inset 0 -1px 5px 0 rgba(0, 0, 0, 0.2);
box-sizing: border-box;
-webkit-font-smoothing: antialiased;
-moz-font-smoothing: antialiased;
font-smoothing: antialiased;
}
.new-todo {
padding: 16px 16px 16px 60px;
border: none;
background: rgba(0, 0, 0, 0.003);
box-shadow: inset 0 -2px 1px rgba(0,0,0,0.03);
}
.main {
position: relative;
z-index: 2;
border-top: 1px solid #e6e6e6;
}
label[for='toggle-all'] {
display: none;
}
.toggle-all {
position: absolute;
top: -55px;
left: -12px;
width: 60px;
height: 34px;
text-align: center;
border: none; /* Mobile Safari */
}
.toggle-all:before {
content: '❯';
font-size: 22px;
color: #e6e6e6;
padding: 10px 27px 10px 27px;
}
.toggle-all:checked:before {
color: #737373;
}
.todo-list {
margin: 0;
padding: 0;
list-style: none;
}
.todo-list li {
position: relative;
font-size: 24px;
border-bottom: 1px solid #ededed;
}
.todo-list li:last-child {
border-bottom: none;
}
.todo-list li.editing {
border-bottom: none;
padding: 0;
}
.todo-list li.editing .edit {
display: block;
width: 506px;
padding: 13px 17px 12px 17px;
margin: 0 0 0 43px;
}
.todo-list li.editing .view {
display: none;
}
.todo-list li .toggle {
text-align: center;
width: 40px;
/* auto, since non-WebKit browsers doesn't support input styling */
height: auto;
position: absolute;
top: 0;
bottom: 0;
margin: auto 0;
border: none; /* Mobile Safari */
-webkit-appearance: none;
appearance: none;
}
.todo-list li .toggle:after {
content: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" viewBox="-10 -18 100 135"><circle cx="50" cy="50" r="50" fill="none" stroke="#ededed" stroke-width="3"/></svg>');
}
.todo-list li .toggle:checked:after {
content: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" viewBox="-10 -18 100 135"><circle cx="50" cy="50" r="50" fill="none" stroke="#bddad5" stroke-width="3"/><path fill="#5dc2af" d="M72 25L42 71 27 56l-4 4 20 20 34-52z"/></svg>');
}
.todo-list li label {
white-space: pre;
word-break: break-word;
padding: 15px 60px 15px 15px;
margin-left: 45px;
display: block;
line-height: 1.2;
transition: color 0.4s;
}
.todo-list li.completed label {
color: #d9d9d9;
text-decoration: line-through;
}
.todo-list li .destroy {
display: none;
position: absolute;
top: 0;
right: 10px;
bottom: 0;
width: 40px;
height: 40px;
margin: auto 0;
font-size: 30px;
color: #cc9a9a;
margin-bottom: 11px;
transition: color 0.2s ease-out;
}
.todo-list li .destroy:hover {
color: #af5b5e;
}
.todo-list li .destroy:after {
content: '×';
}
.todo-list li:hover .destroy {
display: block;
}
.todo-list li .edit {
display: none;
}
.todo-list li.editing:last-child {
margin-bottom: -1px;
}
.footer {
color: #777;
padding: 10px 15px;
height: 20px;
text-align: center;
border-top: 1px solid #e6e6e6;
}
.footer:before {
content: '';
position: absolute;
right: 0;
bottom: 0;
left: 0;
height: 50px;
overflow: hidden;
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2),
0 8px 0 -3px #f6f6f6,
0 9px 1px -3px rgba(0, 0, 0, 0.2),
0 16px 0 -6px #f6f6f6,
0 17px 2px -6px rgba(0, 0, 0, 0.2);
}
.todo-count {
float: left;
text-align: left;
}
.todo-count strong {
font-weight: 300;
}
.filters {
margin: 0;
padding: 0;
list-style: none;
position: absolute;
right: 0;
left: 0;
}
.filters li {
display: inline;
}
.filters li a {
color: inherit;
margin: 3px;
padding: 3px 7px;
text-decoration: none;
border: 1px solid transparent;
border-radius: 3px;
}
.filters li a.selected,
.filters li a:hover {
border-color: rgba(175, 47, 47, 0.1);
}
.filters li a.selected {
border-color: rgba(175, 47, 47, 0.2);
}
.clear-completed,
html .clear-completed:active {
float: right;
position: relative;
line-height: 20px;
text-decoration: none;
cursor: pointer;
position: relative;
}
.clear-completed:hover {
text-decoration: underline;
}
.info {
margin: 65px auto 0;
color: #bfbfbf;
font-size: 10px;
text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);
text-align: center;
}
.info p {
line-height: 1;
}
.info a {
color: inherit;
text-decoration: none;
font-weight: 400;
}
.info a:hover {
text-decoration: underline;
}
/*
Hack to remove background from Mobile Safari.
Can't use it globally since it destroys checkboxes in Firefox
*/
@media screen and (-webkit-min-device-pixel-ratio:0) {
.toggle-all,
.todo-list li .toggle {
background: none;
}
.todo-list li .toggle {
height: 40px;
}
.toggle-all {
-webkit-transform: rotate(90deg);
transform: rotate(90deg);
-webkit-appearance: none;
appearance: none;
}
}
@media (max-width: 430px) {
.footer {
height: 50px;
}
.filters {
bottom: 10px;
}
}
hr {
margin: 20px 0;
border: 0;
border-top: 1px dashed #c5c5c5;
border-bottom: 1px dashed #f7f7f7;
}
.learn a {
font-weight: normal;
text-decoration: none;
color: #b83f45;
}
.learn a:hover {
text-decoration: underline;
color: #787e7e;
}
.learn h3,
.learn h4,
.learn h5 {
margin: 10px 0;
font-weight: 500;
line-height: 1.2;
color: #000;
}
.learn h3 {
font-size: 24px;
}
.learn h4 {
font-size: 18px;
}
.learn h5 {
margin-bottom: 0;
font-size: 14px;
}
.learn ul {
padding: 0;
margin: 0 0 30px 25px;
}
.learn li {
line-height: 20px;
}
.learn p {
font-size: 15px;
font-weight: 300;
line-height: 1.3;
margin-top: 0;
margin-bottom: 0;
}
#issue-count {
display: none;
}
.quote {
border: none;
margin: 20px 0 60px 0;
}
.quote p {
font-style: italic;
}
.quote p:before {
content: '“';
font-size: 50px;
opacity: .15;
position: absolute;
top: -20px;
left: 3px;
}
.quote p:after {
content: '”';
font-size: 50px;
opacity: .15;
position: absolute;
bottom: -42px;
right: 3px;
}
.quote footer {
position: absolute;
bottom: -40px;
right: 0;
}
.quote footer img {
border-radius: 3px;
}
.quote footer a {
margin-left: 5px;
vertical-align: middle;
}
.speech-bubble {
position: relative;
padding: 10px;
background: rgba(0, 0, 0, .04);
border-radius: 5px;
}
.speech-bubble:after {
content: '';
position: absolute;
top: 100%;
right: 30px;
border: 13px solid transparent;
border-top-color: rgba(0, 0, 0, .04);
}
.learn-bar > .learn {
position: absolute;
width: 272px;
top: 8px;
left: -300px;
padding: 10px;
border-radius: 5px;
background-color: rgba(255, 255, 255, .6);
transition-property: left;
transition-duration: 500ms;
}
@media (min-width: 899px) {
.learn-bar {
width: auto;
padding-left: 300px;
}
.learn-bar > .learn {
left: 8px;
}
}
/* global _ */
(function () {
'use strict';
/* jshint ignore:start */
// Underscore's Template Module
// Courtesy of underscorejs.org
var _ = (function (_) {
_.defaults = function (object) {
if (!object) {
return object;
}
for (var argsIndex = 1, argsLength = arguments.length; argsIndex < argsLength; argsIndex++) {
var iterable = arguments[argsIndex];
if (iterable) {
for (var key in iterable) {
if (object[key] == null) {
object[key] = iterable[key];
}
}
}
}
return object;
}
// By default, Underscore uses ERB-style template delimiters, change the
// following template settings to use alternative delimiters.
_.templateSettings = {
evaluate : /<%([\s\S]+?)%>/g,
interpolate : /<%=([\s\S]+?)%>/g,
escape : /<%-([\s\S]+?)%>/g
};
// When customizing `templateSettings`, if you don't want to define an
// interpolation, evaluation or escaping regex, we need one that is
// guaranteed not to match.
var noMatch = /(.)^/;
// Certain characters need to be escaped so that they can be put into a
// string literal.
var escapes = {
"'": "'",
'\\': '\\',
'\r': 'r',
'\n': 'n',
'\t': 't',
'\u2028': 'u2028',
'\u2029': 'u2029'
};
var escaper = /\\|'|\r|\n|\t|\u2028|\u2029/g;
// JavaScript micro-templating, similar to John Resig's implementation.
// Underscore templating handles arbitrary delimiters, preserves whitespace,
// and correctly escapes quotes within interpolated code.
_.template = function(text, data, settings) {
var render;
settings = _.defaults({}, settings, _.templateSettings);
// Combine delimiters into one regular expression via alternation.
var matcher = new RegExp([
(settings.escape || noMatch).source,
(settings.interpolate || noMatch).source,
(settings.evaluate || noMatch).source
].join('|') + '|$', 'g');
// Compile the template source, escaping string literals appropriately.
var index = 0;
var source = "__p+='";
text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {
source += text.slice(index, offset)
.replace(escaper, function(match) { return '\\' + escapes[match]; });
if (escape) {
source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
}
if (interpolate) {
source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
}
if (evaluate) {
source += "';\n" + evaluate + "\n__p+='";
}
index = offset + match.length;
return match;
});
source += "';\n";
// If a variable is not specified, place data values in local scope.
if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n';
source = "var __t,__p='',__j=Array.prototype.join," +
"print=function(){__p+=__j.call(arguments,'');};\n" +
source + "return __p;\n";
try {
render = new Function(settings.variable || 'obj', '_', source);
} catch (e) {
e.source = source;
throw e;
}
if (data) return render(data, _);
var template = function(data) {
return render.call(this, data, _);
};
// Provide the compiled function source as a convenience for precompilation.
template.source = 'function(' + (settings.variable || 'obj') + '){\n' + source + '}';
return template;
};
return _;
})({});
if (location.hostname === 'todomvc.com') {
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-31081062-1', 'auto');
ga('send', 'pageview');
}
/* jshint ignore:end */
function redirect() {
if (location.hostname === 'tastejs.github.io') {
location.href = location.href.replace('tastejs.github.io/todomvc', 'todomvc.com');
}
}
function findRoot() {
var base = location.href.indexOf('examples/');
return location.href.substr(0, base);
}
function getFile(file, callback) {
if (!location.host) {
return console.info('Miss the info bar? Run TodoMVC from a server to avoid a cross-origin error.');
}
var xhr = new XMLHttpRequest();
xhr.open('GET', findRoot() + file, true);
xhr.send();
xhr.onload = function () {
if (xhr.status === 200 && callback) {
callback(xhr.responseText);
}
};
}
function Learn(learnJSON, config) {
if (!(this instanceof Learn)) {
return new Learn(learnJSON, config);
}
var template, framework;
if (typeof learnJSON !== 'object') {
try {
learnJSON = JSON.parse(learnJSON);
} catch (e) {
return;
}
}
if (config) {
template = config.template;
framework = config.framework;
}
if (!template && learnJSON.templates) {
template = learnJSON.templates.todomvc;
}
if (!framework && document.querySelector('[data-framework]')) {
framework = document.querySelector('[data-framework]').dataset.framework;
}
this.template = template;
if (learnJSON.backend) {
this.frameworkJSON = learnJSON.backend;
this.frameworkJSON.issueLabel = framework;
this.append({
backend: true
});
} else if (learnJSON[framework]) {
this.frameworkJSON = learnJSON[framework];
this.frameworkJSON.issueLabel = framework;
this.append();
}
this.fetchIssueCount();
}
Learn.prototype.append = function (opts) {
var aside = document.createElement('aside');
aside.innerHTML = _.template(this.template, this.frameworkJSON);
aside.className = 'learn';
if (opts && opts.backend) {
// Remove demo link
var sourceLinks = aside.querySelector('.source-links');
var heading = sourceLinks.firstElementChild;
var sourceLink = sourceLinks.lastElementChild;
// Correct link path
var href = sourceLink.getAttribute('href');
sourceLink.setAttribute('href', href.substr(href.lastIndexOf('http')));
sourceLinks.innerHTML = heading.outerHTML + sourceLink.outerHTML;
} else {
// Localize demo links
var demoLinks = aside.querySelectorAll('.demo-link');
Array.prototype.forEach.call(demoLinks, function (demoLink) {
if (demoLink.getAttribute('href').substr(0, 4) !== 'http') {
demoLink.setAttribute('href', findRoot() + demoLink.getAttribute('href'));
}
});
}
document.body.className = (document.body.className + ' learn-bar').trim();
document.body.insertAdjacentHTML('afterBegin', aside.outerHTML);
};
Learn.prototype.fetchIssueCount = function () {
var issueLink = document.getElementById('issue-count-link');
if (issueLink) {
var url = issueLink.href.replace('https://github.com', 'https://api.github.com/repos');
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.onload = function (e) {
var parsedResponse = JSON.parse(e.target.responseText);
if (parsedResponse instanceof Array) {
var count = parsedResponse.length;
if (count !== 0) {
issueLink.innerHTML = 'This app has ' + count + ' open issues';
document.getElementById('issue-count').style.display = 'inline';
}
}
};
xhr.send();
}
};
redirect();
getFile('learn.json', Learn);
})();
{
"private": true,
"dependencies": {
"classnames": "^2.1.5",
"director": "^1.2.0",
"react": "^0.13.3",
"todomvc-app-css": "^2.0.0",
"todomvc-common": "^1.0.1"
}
}
# TypeScript & React TodoMVC Example
> TypeScript is a language for application-scale JavaScript development. TypeScript is a typed superset of JavaScript that compiles to plain JavaScript. Any browser. Any host. Any OS. Open Source.
> _[TypeScript - typescriptlang.org](http://typescriptlang.org)_
> React is a JavaScript library for creating user interfaces. Its core principles are declarative code, efficiency, and flexibility. Simply specify what your component looks like and React will keep it up-to-date when the underlying data changes.
> _[React - facebook.github.io/react](http://facebook.github.io/react)_
## Learning TypeScript
The [TypeScript website](http://typescriptlang.org) is a great resource for getting started.
Here are some links you may find helpful:
* [Tutorial](http://www.typescriptlang.org/Tutorial)
* [Code Playground](http://www.typescriptlang.org/Playground)
* [Documentation](http://typescript.codeplex.com/documentation)
* [Applications built with TypeScript](http://www.typescriptlang.org/Samples)
* [Blog](http://blogs.msdn.com/b/typescript)
* [Source Code](http://typescript.codeplex.com/sourcecontrol/latest#README.txt)
Articles and guides from the community:
* [Thoughts on TypeScript](http://www.nczonline.net/blog/2012/10/04/thoughts-on-typescript)
* [ScreenCast - Why I Like TypeScript](http://www.leebrimelow.com/why-i-like-typescripts)
Get help from other TypeScript users:
* [TypeScript on StackOverflow](http://stackoverflow.com/questions/tagged/typescript)
* [Forums](http://typescript.codeplex.com/discussions)
* [TypeScript on Twitter](http://twitter.com/typescriptlang)
_If you have other helpful links to share, or find any of the links above no longer work, please [let us know](https://github.com/tastejs/todomvc/issues)._
## Learning React
The [React getting started documentation](http://facebook.github.io/react/docs/getting-started.html) is a great way to get started.
Here are some links you may find helpful:
* [Documentation](http://facebook.github.io/react/docs/getting-started.html)
* [API Reference](http://facebook.github.io/react/docs/reference.html)
* [Blog](http://facebook.github.io/react/blog/)
* [React on GitHub](https://github.com/facebook/react)
* [Support](http://facebook.github.io/react/support.html)
Articles and guides from the community:
* [How is Facebook's React JavaScript library](http://www.quora.com/React-JS-Library/How-is-Facebooks-React-JavaScript-library)
* [React: Under the hood](http://www.quora.com/Pete-Hunt/Posts/React-Under-the-Hood)
Get help from other React users:
* [React on StackOverflow](http://stackoverflow.com/questions/tagged/reactjs)
* [Discussion Forum](https://discuss.reactjs.org/)
_If you have other helpful links to share, or find any of the links above no longer work, please [let us know](https://github.com/tastejs/todomvc/issues)._
## Running
A standalone TypeScript compiler is available on NPM.
npm install typescript
To compile the TypeScript in this project:
# from examples/typescript-react
$ tsc -p js
To be able to run the output JS files in the browser:
# from examples/typescript-react
$ npm install -g browserify
$ browserify js/app.js -o js/bundle.js
To run the app, spin up an HTTP server (e.g. `python -m SimpleHTTPServer`) and visit http://localhost/.../myexample/.
{
"version": "v4",
"repo": "borisyankov/DefinitelyTyped",
"ref": "master",
"path": "typings",
"bundle": "typings/tsd.d.ts",
"installed": {
"react/react.d.ts": {
"commit": "3fc1377ce29dd9670975cb68615edf1b819fc4a5"
},
"classnames/classnames.d.ts": {
"commit": "14ab703f435375194360cdba3abab61afc879c18"
}
}
}
// Type definitions for classnames
// Project: https://github.com/JedWatson/classnames
// Definitions by: Dave Keen <http://www.keendevelopment.ch>, Adi Dahiya <https://github.com/adidahiya>, Jason Killian <https://github.com/JKillian>
// Definitions: https://github.com/borisyankov/DefinitelyTyped
declare type ClassValue = string | number | ClassDictionary | ClassArray;
interface ClassDictionary {
[id: string]: boolean;
}
interface ClassArray extends Array<ClassValue> { }
interface ClassNamesFn {
(...classes: ClassValue[]): string;
}
declare var classNames: ClassNamesFn;
declare module "classnames" {
export = classNames
}
// Type definitions for React v0.13.3 (namespace)
// Project: http://facebook.github.io/react/
// Definitions by: Asana <https://asana.com>, AssureSign <http://www.assuresign.com>, Microsoft <https://microsoft.com>
// Definitions: https://github.com/borisyankov/DefinitelyTyped
/// <reference path="./react.d.ts" />
import React = __React;
declare namespace __React {
//
// React.addons
// ----------------------------------------------------------------------
export module addons {
export var CSSTransitionGroup: CSSTransitionGroup;
export var TransitionGroup: TransitionGroup;
export var LinkedStateMixin: LinkedStateMixin;
export var PureRenderMixin: PureRenderMixin;
export function batchedUpdates<A, B>(
callback: (a: A, b: B) => any, a: A, b: B): void;
export function batchedUpdates<A>(callback: (a: A) => any, a: A): void;
export function batchedUpdates(callback: () => any): void;
// deprecated: use petehunt/react-classset or JedWatson/classnames
export function classSet(cx: { [key: string]: boolean }): string;
export function classSet(...classList: string[]): string;
export function cloneWithProps<P>(
element: DOMElement<P>, props: P): DOMElement<P>;
export function cloneWithProps<P>(
element: ClassicElement<P>, props: P): ClassicElement<P>;
export function cloneWithProps<P>(
element: ReactElement<P>, props: P): ReactElement<P>;
export function createFragment(
object: { [key: string]: ReactNode }): ReactFragment;
export function update(value: any[], spec: UpdateArraySpec): any[];
export function update(value: {}, spec: UpdateSpec): any;
// Development tools
export import Perf = ReactPerf;
export import TestUtils = ReactTestUtils;
}
//
// React.addons (Transitions)
// ----------------------------------------------------------------------
interface TransitionGroupProps {
component?: ReactType;
childFactory?: (child: ReactElement<any>) => ReactElement<any>;
}
interface CSSTransitionGroupProps extends TransitionGroupProps {
transitionName: string;
transitionAppear?: boolean;
transitionEnter?: boolean;
transitionLeave?: boolean;
}
type CSSTransitionGroup = ComponentClass<CSSTransitionGroupProps>;
type TransitionGroup = ComponentClass<TransitionGroupProps>;
//
// React.addons (Mixins)
// ----------------------------------------------------------------------
interface ReactLink<T> {
value: T;
requestChange(newValue: T): void;
}
interface LinkedStateMixin extends Mixin<any, any> {
linkState<T>(key: string): ReactLink<T>;
}
interface PureRenderMixin extends Mixin<any, any> {
}
//
// Reat.addons.update
// ----------------------------------------------------------------------
interface UpdateSpecCommand {
$set?: any;
$merge?: {};
$apply?(value: any): any;
}
interface UpdateSpecPath {
[key: string]: UpdateSpec;
}
type UpdateSpec = UpdateSpecCommand | UpdateSpecPath;
interface UpdateArraySpec extends UpdateSpecCommand {
$push?: any[];
$unshift?: any[];
$splice?: any[][];
}
//
// React.addons.Perf
// ----------------------------------------------------------------------
interface ComponentPerfContext {
current: string;
owner: string;
}
interface NumericPerfContext {
[key: string]: number;
}
interface Measurements {
exclusive: NumericPerfContext;
inclusive: NumericPerfContext;
render: NumericPerfContext;
counts: NumericPerfContext;
writes: NumericPerfContext;
displayNames: {
[key: string]: ComponentPerfContext;
};
totalTime: number;
}
module ReactPerf {
export function start(): void;
export function stop(): void;
export function printInclusive(measurements: Measurements[]): void;
export function printExclusive(measurements: Measurements[]): void;
export function printWasted(measurements: Measurements[]): void;
export function printDOM(measurements: Measurements[]): void;
export function getLastMeasurements(): Measurements[];
}
//
// React.addons.TestUtils
// ----------------------------------------------------------------------
interface MockedComponentClass {
new(): any;
}
module ReactTestUtils {
export import Simulate = ReactSimulate;
export function renderIntoDocument<P>(
element: ReactElement<P>): Component<P, any>;
export function renderIntoDocument<C extends Component<any, any>>(
element: ReactElement<any>): C;
export function mockComponent(
mocked: MockedComponentClass, mockTagName?: string): typeof ReactTestUtils;
export function isElementOfType(
element: ReactElement<any>, type: ReactType): boolean;
export function isTextComponent(instance: Component<any, any>): boolean;
export function isDOMComponent(instance: Component<any, any>): boolean;
export function isCompositeComponent(instance: Component<any, any>): boolean;
export function isCompositeComponentWithType(
instance: Component<any, any>,
type: ComponentClass<any>): boolean;
export function findAllInRenderedTree(
tree: Component<any, any>,
fn: (i: Component<any, any>) => boolean): Component<any, any>;
export function scryRenderedDOMComponentsWithClass(
tree: Component<any, any>,
className: string): DOMComponent<any>[];
export function findRenderedDOMComponentWithClass(
tree: Component<any, any>,
className: string): DOMComponent<any>;
export function scryRenderedDOMComponentsWithTag(
tree: Component<any, any>,
tagName: string): DOMComponent<any>[];
export function findRenderedDOMComponentWithTag(
tree: Component<any, any>,
tagName: string): DOMComponent<any>;
export function scryRenderedComponentsWithType<P>(
tree: Component<any, any>,
type: ComponentClass<P>): Component<P, {}>[];
export function scryRenderedComponentsWithType<C extends Component<any, any>>(
tree: Component<any, any>,
type: ComponentClass<any>): C[];
export function findRenderedComponentWithType<P>(
tree: Component<any, any>,
type: ComponentClass<P>): Component<P, {}>;
export function findRenderedComponentWithType<C extends Component<any, any>>(
tree: Component<any, any>,
type: ComponentClass<any>): C;
export function createRenderer(): ShallowRenderer;
}
interface SyntheticEventData {
altKey?: boolean;
button?: number;
buttons?: number;
clientX?: number;
clientY?: number;
changedTouches?: TouchList;
charCode?: boolean;
clipboardData?: DataTransfer;
ctrlKey?: boolean;
deltaMode?: number;
deltaX?: number;
deltaY?: number;
deltaZ?: number;
detail?: number;
getModifierState?(key: string): boolean;
key?: string;
keyCode?: number;
locale?: string;
location?: number;
metaKey?: boolean;
pageX?: number;
pageY?: number;
relatedTarget?: EventTarget;
repeat?: boolean;
screenX?: number;
screenY?: number;
shiftKey?: boolean;
targetTouches?: TouchList;
touches?: TouchList;
view?: AbstractView;
which?: number;
}
interface EventSimulator {
(element: Element, eventData?: SyntheticEventData): void;
(component: Component<any, any>, eventData?: SyntheticEventData): void;
}
module ReactSimulate {
export var blur: EventSimulator;
export var change: EventSimulator;
export var click: EventSimulator;
export var cut: EventSimulator;
export var doubleClick: EventSimulator;
export var drag: EventSimulator;
export var dragEnd: EventSimulator;
export var dragEnter: EventSimulator;
export var dragExit: EventSimulator;
export var dragLeave: EventSimulator;
export var dragOver: EventSimulator;
export var dragStart: EventSimulator;
export var drop: EventSimulator;
export var focus: EventSimulator;
export var input: EventSimulator;
export var keyDown: EventSimulator;
export var keyPress: EventSimulator;
export var keyUp: EventSimulator;
export var mouseDown: EventSimulator;
export var mouseEnter: EventSimulator;
export var mouseLeave: EventSimulator;
export var mouseMove: EventSimulator;
export var mouseOut: EventSimulator;
export var mouseOver: EventSimulator;
export var mouseUp: EventSimulator;
export var paste: EventSimulator;
export var scroll: EventSimulator;
export var submit: EventSimulator;
export var touchCancel: EventSimulator;
export var touchEnd: EventSimulator;
export var touchMove: EventSimulator;
export var touchStart: EventSimulator;
export var wheel: EventSimulator;
}
class ShallowRenderer {
getRenderOutput<E extends ReactElement<any>>(): E;
getRenderOutput(): ReactElement<any>;
render(element: ReactElement<any>, context?: any): void;
unmount(): void;
}
}
This diff is collapsed.
/// <reference path="react/react-global.d.ts" />
/// <reference path="classnames/classnames.d.ts" />
......@@ -158,6 +158,9 @@
<li>
<a href="examples/typescript-angular/" data-source="http://typescriptlang.org" data-content="An AngularJS + TypeScript implementation of TodoMVC. The only significant difference between this and the vanilla Angular app is that dependency injection is done via annotated constructors, which allows minification of JavaScript.">TypeScript <br>+ AngularJS</a>
</li>
<li>
<a href="examples/typescript-react/" data-source="http://typescriptlang.org" data-content="An TypeScript + React implementation of TodoMVC. TypeScript is a language for application-scale JavaScript development. It offers classes, modules, interfaces and type-checking at compile time to help you build robust components. This examples showcases how to work with TSX files, which allow us to enjoy native JSX support while working with TypeScript.">TypeScript <br>+ React</a>
</li>
<li>
<a href="examples/serenadejs/" data-source="https://github.com/elabs/serenade.js" data-content="Serenade.js is yet another MVC client side JavaScript framework. Why do we indulge in recreating the wheel? We believe that Serenade.js more closely follows the ideas of classical MVC than competing frameworks.">Serenade.js</a>
</li>
......
......@@ -1675,6 +1675,9 @@
}, {
"name": "Scala.js & React",
"url": "examples/scalajs-react"
}, {
"name": "TypeScript & React",
"url": "examples/typescript-react"
}],
"link_groups": [{
"heading": "Official Resources",
......@@ -2093,6 +2096,9 @@
}, {
"name": "TypeScript & Backbone.js",
"url": "examples/typescript-backbone"
}, {
"name": "TypeScript & React",
"url": "examples/typescript-react"
}],
"link_groups": [{
"heading": "Official Resources",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment