Tutorial
In this exercise you will build a simple but interactive TodoApp which demonstrates the following features:
- A dashboard with the list of existing tasks
- Adding, removing, editing, and completing tasks
- Managing labels and assigning them to tasks
For this tutorial you will use the Bower distribution of Grommet. Get Started page provides instructions on installing Grommet using Bower.
If you want to skip this step-by-step tutorial, you can download the full version of this exercise from Github.
TodoApp Dashboard
In this section you will create the main page for the TodoApp: the Dashboard. It includes a summary of the existing tasks in a Donut component and the current list of tasks.
Create a new HTML file on your computer and copy and paste the following code:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Todo App</title>
<link href="http://fonts.googleapis.com/css?family=Source+Sans+Pro:400italic,400,700" rel="stylesheet" type="text/css">
<link href="bower_components/grommet/css/grommet-hpe.min.css" rel="stylesheet" type="text/css">
<script src="bower_components/react/react.js"></script>
<script src="bower_components/react/JSXTransformer.js"></script>
<script src="bower_components/grommet/grommet.min.js"></script>
</head>
<body>
<div id="content"></div>
<script type="text/jsx">
function getLabel(label, count, colorIndex) {'{'}
return {'{'}
"label": label,
"value": count,
"units": count > 1 ? "Tasks" : 'Task',
"colorIndex": colorIndex
{'}'};
{'}'}
var TodoAppDashboard = React.createClass({'{'}
render: function () {'{'}
var tasksMap = {'{'}
error: 0,
ok: 0,
warning: 0
{'}'};
var items = this.props.tasks.map(function(task) {'{'}
tasksMap[task.type] += 1;
return (
<tr>
<td><Grommet.Icons.Status value={'{'}task.type{'}'} small={'{'}true{'}'} /></td>
<td>{'{'}task.item{'}'}</td>
</tr>
);
{'}'});
return (
<Grommet.Tiles>
<Grommet.Tile>
<Grommet.Section centered={'{'}true{'}'}>
<Grommet.Donut series={'{'}[
getLabel('Fix Now', tasksMap.error, "error"),
getLabel('Remember', tasksMap.warning, "warning"),
getLabel('Enjoy', tasksMap.ok, "ok")
]{'}'}/>
</Grommet.Section>
</Grommet.Tile>
<Grommet.Tile>
<Grommet.Header><h3>My Tasks:</h3></Grommet.Header>
<Grommet.Table>
<tbody>
{'{'}items{'}'}
</tbody>
</Grommet.Table>
</Grommet.Tile>
</Grommet.Tiles>
);
{'}'}
{'}'});
var App = React.createClass({'{'}
getInitialState: function() {'{'}
return {'{'}
tasks: [
{'{'}
type: 'error',
item: 'The coffee pot needs to be cleaned.'
{'}'},
{'{'}
type: 'ok',
item: 'It\'s going to be a sunny day tomorrow.'
{'}'},
{'{'}
type: 'warning',
item: 'Don\'t forget your anniversary in two weeks.'
{'}'},
{'{'}
type: 'warning',
item: 'Pay my late bills.'
{'}'},
{'{'}
type: 'ok',
item: 'Go to the Sharks game tomorrow.'
{'}'},
{'{'}
type: 'ok',
item: 'Go to Santa Cruz, it\'s summer time.'
{'}'},
]
{'}'};
{'}'},
render: function() {'{'}
return (
<Grommet.App centered={'{'}false{'}'}>
<Grommet.Header primary={'{'}true{'}'}>
<Grommet.Title>Todo App</Grommet.Title>
</Grommet.Header>
<TodoAppDashboard tasks={'{'}this.state.tasks{'}'} />
</Grommet.App>
);
{'}'}
{'}'});
var element = document.getElementById('content');
React.render(React.createElement(App), element);
</script>
</body>
</html>
If you open this HTML file in your browser you should see the following:
In the head tag of this markup React, JSXTransformer, and Grommet are loaded. Check out the Architecture page if you're curious to understand better about Grommet technology stack.
The body tag has two main containers. The content div where React will load the Grommet components, and the script tag with the dashboard code in JSX format that will be further compiled by JSXTransformer.
The best way to understand this script tag is by reading it from the bottom to the top. The last line of the script renders App component inside the main container. This component has a set of tasks as the initial state where 6 samples tasks are already provided (you'll remove that later in this exercise). The render function of this component loads the Grommet App with a Header (including the Title) and the TodoAppDashboard as the body. The TodoAppDashboard component has the set of tasks as a property and the render function includes two main Tiles. The first Tile is the Donut with the summary of the current tasks, and the second one is the actual list of tasks displayed in a simple table.