Appearance
To-Do List Example
examplejs
import { ToDoList } from './components/ToDoList.js'
const initialTasks = [
{ title: 'Make to-do list', completed: true },
{ title: 'Hit the gym', completed: false }
]
ToDoList(initialTasks).paint('#to-do-list')
js
import { component, state, template } from 'paintor'
const tasks = state([])
const newTask = { title: '', completed: false }
function addTask() {
if (!newTask.title) {
alert('You must write a title for your new task!')
}
else {
tasks.push({ ...newTask })
}
}
function deleteTask(task) {
tasks.splice(getTaskIndex(task), 1)
}
function getTaskIndex(task) {
return tasks.indexOf(task)
}
function toggleCompleted(task) {
task.completed = !task.completed
}
const todoHeader = template(({ h3, span, div, input, button }) => {
h3('Tasks ', span(() => `(${tasks.length})`)),
div({ class: 'header' },
input(
{
type: 'text',
placeholder: 'New Task...',
onKeyUp: (event) => {
newTask.title = event.target.value
}
}
),
button({ onClick: addTask }, 'Add')
)
})
const taskItem = (task) => template(({ li, button }) => {
li({
class: () => (task.completed ? 'completed' : ''),
onClick: () => toggleCompleted(task)
},
task.title,
button(
{
onClick: () => deleteTask(task)
},
'\u00D7'
)
)
})
const todoTasks = template(({ ul, forEach }) => {
ul(
forEach(tasks, taskItem)
)
})
const ToDoList = (initialTasks) => {
// Push the initial tasks into the state
for (const initialTask of initialTasks) {
tasks.push(initialTask)
}
// Create and return the component
return component(
todoHeader,
todoTasks
)
}
export { ToDoList }
css
#to-do-list {
color: black;
& h3 {
margin: 0;
color: deepskyblue;
font-weight: bold;
}
& .header {
padding: 1rem;
background: deepskyblue;
& input {
float: left;
width: 75%;
padding: 0.3rem;
background: white;
color: black;
&::placeholder {
color: gray
}
}
& button {
width: 25%;
padding: 0.3rem;
background: #d9d9d9;
text-align: center;
color: #555;
&:hover {
background: #ccc;
}
}
}
& ul {
list-style-type: none;
margin: 0;
padding: 0;
& li {
position: relative;
user-select: none;
margin: 0;
padding: 0.3rem;
background: #eee;
cursor: pointer;
&:nth-child(odd) {
background: #f9f9f9;
}
&:hover {
background: #ddd;
}
& button {
position: absolute;
right: 0;
top: 0;
padding: 0.3rem 0.6rem;
background: transparent;
border: none;
font-size: larger;
&:hover {
background: deepskyblue;
}
}
&.completed {
background: #888;
text-decoration: line-through;
}
}
}
}
html
<div id="to-do-list"></div>