Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added TodoTools and Footer components
- Loading branch information
Nicolas Goutay
committed
Feb 27, 2016
1 parent
cc97354
commit 237dbc3
Showing
4 changed files
with
119 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import React from 'react'; | ||
|
||
export default React.createClass({ | ||
render: function () { | ||
return <footer className="info"> | ||
<p>Double-click to edit a todo</p> | ||
<p>Written by <a href="https://twitter.com/phacks">@phacks</a></p> | ||
<p>Part of <a href="http://todomvc.com">TodoMVC</a></p> | ||
</footer> | ||
} | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,28 @@ | ||
import React from 'react'; | ||
import TodoList from './TodoList' | ||
import TodoHeader from './TodoHeader' | ||
import TodoTools from './TodoTools' | ||
import Footer from './Footer' | ||
|
||
export default React.createClass({ | ||
getNbActiveItems: function () { | ||
if (this.props.todos) { | ||
const activeItems = this.props.todos.filter( | ||
(item) => item.get('status') === 'active' | ||
); | ||
return activeItems.size; | ||
} | ||
return 0; | ||
}, | ||
render: function () { | ||
return <div> | ||
<section className="todoapp"> | ||
<TodoHeader /> | ||
<TodoList todos={this.props.todos} filter={this.props.filter} /> | ||
<TodoTools filter={this.props.filter} | ||
nbActiveItems={this.getNbActiveItems()} /> | ||
</section> | ||
<Footer /> | ||
</div> | ||
} | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
import React from 'react'; | ||
import PureRenderMixin from 'react-addons-pure-render-mixin'; | ||
import classNames from 'classnames'; | ||
|
||
export default React.createClass({ | ||
mixins: [PureRenderMixin], | ||
getNbItemsLeft: function () { | ||
return this.props.nbActiveItems || 0; | ||
}, | ||
isSelected: function (filter) { | ||
return this.props.selectedFilter === filter || false; | ||
}, | ||
setSelectedClass: function (filter) { | ||
return classNames({'selected': this.props.filter === filter}); | ||
}, | ||
render: function () { | ||
return <footer className="footer"> | ||
<span className="todo-count"> | ||
<strong>{this.getNbItemsLeft()}</strong> items left | ||
</span> | ||
<ul className="filters"> | ||
<li> | ||
<a href="#" | ||
onClick={() => this.props.changeFilter('all')} | ||
className={this.setSelectedClass('all')}> | ||
All | ||
</a> | ||
</li> | ||
<li> | ||
<a href="#" | ||
onClick={() => this.props.changeFilter('active')} | ||
className={this.setSelectedClass('active')}> | ||
Active | ||
</a> | ||
</li> | ||
<li> | ||
<a href="#" | ||
onClick={() => this.props.changeFilter('completed')} | ||
className={this.setSelectedClass('completed')}> | ||
Completed | ||
</a> | ||
</li> | ||
</ul> | ||
<button className="clear-completed" | ||
onClick={this.props.clearCompleted}> | ||
Clear completed | ||
</button> | ||
</footer> | ||
} | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import React from 'react'; | ||
import TestUtils from 'react-addons-test-utils'; | ||
import TodoTools from '../../src/components/TodoTools'; | ||
import {expect} from 'chai'; | ||
|
||
const {renderIntoDocument, | ||
scryRenderedDOMComponentsWithTag, | ||
Simulate} = TestUtils; | ||
|
||
describe('TodoTools', () => { | ||
it('displays the number of items left', () => { | ||
const nbActiveItems = 3; | ||
const component = renderIntoDocument( | ||
<TodoTools nbActiveItems={nbActiveItems} /> | ||
); | ||
const tools = scryRenderedDOMComponentsWithTag(component, 'footer'); | ||
|
||
expect(tools[0].textContent).to.contain('3'); | ||
}); | ||
|
||
it('Highlights the active filter', () => { | ||
const filter = 'active'; | ||
const component = renderIntoDocument( | ||
<TodoTools filter={filter} /> | ||
); | ||
const filters = scryRenderedDOMComponentsWithTag(component, 'a'); | ||
|
||
expect(filters[0].classList.contains('selected')).to.equal(false); | ||
expect(filters[1].classList.contains('selected')).to.equal(true); | ||
expect(filters[2].classList.contains('selected')).to.equal(false); | ||
}); | ||
|
||
it('calls a callback when the user clicks on Clear Completed buttons', () => { | ||
var cleared = false | ||
const clearCompleted = () => cleared = true; | ||
const component = renderIntoDocument( | ||
<TodoTools clearCompleted={clearCompleted} /> | ||
); | ||
const buttons = scryRenderedDOMComponentsWithTag(component, 'button'); | ||
Simulate.click(buttons[0]); | ||
|
||
expect(cleared).to.equal(true); | ||
}); | ||
}); |