Skip to content

Commit

Permalink
Format with prettier
Browse files Browse the repository at this point in the history
  • Loading branch information
1Marc committed Sep 12, 2022
1 parent b1d2750 commit fbc1c98
Show file tree
Hide file tree
Showing 9 changed files with 201 additions and 150 deletions.
4 changes: 2 additions & 2 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ trim_trailing_whitespace = true
insert_final_newline = true

[package.json]
indent_style = space
indent_size = 2
indent_style = tab
indent_size = 4

[*.md]
trim_trailing_whitespace = false
3 changes: 3 additions & 0 deletions .prettier
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"indent_style": "tab"
}
35 changes: 16 additions & 19 deletions css/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ button {
}

body {
font: 14px 'Helvetica Neue', Helvetica, Arial, sans-serif;
font: 14px "Helvetica Neue", Helvetica, Arial, sans-serif;
line-height: 1.4em;
background: #f5f5f5;
color: #111111;
Expand All @@ -45,8 +45,7 @@ body {
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);
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 {
Expand Down Expand Up @@ -103,7 +102,7 @@ body {
height: 65px;
border: none;
background: rgba(0, 0, 0, 0.003);
box-shadow: inset 0 -2px 1px rgba(0,0,0,0.03);
box-shadow: inset 0 -2px 1px rgba(0, 0, 0, 0.03);
}

.main {
Expand Down Expand Up @@ -135,7 +134,7 @@ body {
}

.toggle-all + label:before {
content: '❯';
content: "❯";
display: inline-block;
font-size: 22px;
color: #949494;
Expand Down Expand Up @@ -203,13 +202,13 @@ body {
Firefox requires `#` to be escaped - https://bugzilla.mozilla.org/show_bug.cgi?id=922433
IE and Edge requires *everything* to be escaped to render, so we do that instead of just the `#` - https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/7157459/
*/
background-image: url('data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2240%22%20height%3D%2240%22%20viewBox%3D%22-10%20-18%20100%20135%22%3E%3Ccircle%20cx%3D%2250%22%20cy%3D%2250%22%20r%3D%2250%22%20fill%3D%22none%22%20stroke%3D%22%23949494%22%20stroke-width%3D%223%22/%3E%3C/svg%3E');
background-image: url("data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2240%22%20height%3D%2240%22%20viewBox%3D%22-10%20-18%20100%20135%22%3E%3Ccircle%20cx%3D%2250%22%20cy%3D%2250%22%20r%3D%2250%22%20fill%3D%22none%22%20stroke%3D%22%23949494%22%20stroke-width%3D%223%22/%3E%3C/svg%3E");
background-repeat: no-repeat;
background-position: center left;
}

.todo-list li .toggle:checked + label {
background-image: url('data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2240%22%20height%3D%2240%22%20viewBox%3D%22-10%20-18%20100%20135%22%3E%3Ccircle%20cx%3D%2250%22%20cy%3D%2250%22%20r%3D%2250%22%20fill%3D%22none%22%20stroke%3D%22%2359A193%22%20stroke-width%3D%223%22%2F%3E%3Cpath%20fill%3D%22%233EA390%22%20d%3D%22M72%2025L42%2071%2027%2056l-4%204%2020%2020%2034-52z%22%2F%3E%3C%2Fsvg%3E');
background-image: url("data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2240%22%20height%3D%2240%22%20viewBox%3D%22-10%20-18%20100%20135%22%3E%3Ccircle%20cx%3D%2250%22%20cy%3D%2250%22%20r%3D%2250%22%20fill%3D%22none%22%20stroke%3D%22%2359A193%22%20stroke-width%3D%223%22%2F%3E%3Cpath%20fill%3D%22%233EA390%22%20d%3D%22M72%2025L42%2071%2027%2056l-4%204%2020%2020%2034-52z%22%2F%3E%3C%2Fsvg%3E");
}

.todo-list li label {
Expand Down Expand Up @@ -243,11 +242,11 @@ body {

.todo-list li .destroy:hover,
.todo-list li .destroy:focus {
color: #C18585;
color: #c18585;
}

.todo-list li .destroy:after {
content: '×';
content: "×";
display: block;
height: 100%;
line-height: 1.1;
Expand All @@ -274,18 +273,16 @@ body {
}

.footer:before {
content: '';
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);
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 {
Expand Down Expand Up @@ -320,11 +317,11 @@ body {
}

.filters li a:hover {
border-color: #DB7676;
border-color: #db7676;
}

.filters li a.selected {
border-color: #CE4646;
border-color: #ce4646;
}

.clear-completed,
Expand Down Expand Up @@ -366,7 +363,7 @@ html .clear-completed:active {
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) {
@media screen and (-webkit-min-device-pixel-ratio: 0) {
.toggle-all,
.todo-list li .toggle {
background: none;
Expand All @@ -390,6 +387,6 @@ html .clear-completed:active {
:focus,
.toggle:focus + label,
.toggle-all:focus + label {
box-shadow: 0 0 2px 2px #CF7D7D;
box-shadow: 0 0 2px 2px #cf7d7d;
outline: 0;
}
15 changes: 12 additions & 3 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,21 @@ <h1>todos</h1>
</header>
<!-- This section should be hidden by default and shown when there are todos -->
<section class="main" data-todo="main">
<input id="toggle-all" class="toggle-all" type="checkbox" data-todo="toggle-all" />
<input
id="toggle-all"
class="toggle-all"
type="checkbox"
data-todo="toggle-all"
/>
<label for="toggle-all">Mark all as complete</label>
<ul class="todo-list" data-todo="list"></ul>
</section>
<!-- This footer should be hidden by default and shown when there are todos -->
<footer class="footer" data-todo="footer">
<!-- This should be `0 items left` by default -->
<span class="todo-count" data-todo="count"><strong>0</strong> items left</span>
<span class="todo-count" data-todo="count"
><strong>0</strong> items left</span
>
<!-- Remove this if you don't implement routing -->
<ul class="filters" data-todo="filters">
<li>
Expand All @@ -41,7 +48,9 @@ <h1>todos</h1>
</li>
</ul>
<!-- Hidden if no completed items are left ↓ -->
<button class="clear-completed" data-todo="clear-completed">Clear completed</button>
<button class="clear-completed" data-todo="clear-completed">
Clear completed
</button>
</footer>
</section>
<footer class="info">
Expand Down
125 changes: 76 additions & 49 deletions js/app.js
Original file line number Diff line number Diff line change
@@ -1,94 +1,121 @@
import { delegate, getURLHash, insertHTML, emptyElement } from './helpers.js';
import { TodoStore } from './store.js';
import { delegate, getURLHash, insertHTML, emptyElement } from "./helpers.js";
import { TodoStore } from "./store.js";

const Todos = new TodoStore('todo-vanillajs-2022');
const Todos = new TodoStore("todo-vanillajs-2022");

const App = {
$: {
input: document.querySelector('[data-todo="new"]'),
toggleAll: document.querySelector('[data-todo="toggle-all"]'),
clear: document.querySelector('[data-todo="clear-completed"]'),
list: document.querySelector('[data-todo="list"]'),
count: document.querySelector('[data-todo="count"]'),
setActiveFilter: filter => {
document.querySelectorAll('[data-todo="filters"] a').forEach(el => el.classList.remove('selected')),
document.querySelector(`[data-todo="filters"] [href="#/${filter}"]`).classList.add('selected');
input: document.querySelector('[data-todo="new"]'),
toggleAll: document.querySelector('[data-todo="toggle-all"]'),
clear: document.querySelector('[data-todo="clear-completed"]'),
list: document.querySelector('[data-todo="list"]'),
count: document.querySelector('[data-todo="count"]'),
setActiveFilter: (filter) => {
document
.querySelectorAll('[data-todo="filters"] a')
.forEach((el) => el.classList.remove("selected")),
document
.querySelector(`[data-todo="filters"] [href="#/${filter}"]`)
.classList.add("selected");
},
showMain: show =>
document.querySelector('[data-todo="main"]').style.display = show ? 'block': 'none',
showClear: show =>
document.querySelector('[data-todo="clear-completed"]').style.display = show ? 'block': 'none',
showFooter: show =>
document.querySelector('[data-todo="main"]').style.display = show ? 'block': 'none',
displayCount: count => {
showMain: (show) =>
(document.querySelector('[data-todo="main"]').style.display = show
? "block"
: "none"),
showClear: (show) =>
(document.querySelector('[data-todo="clear-completed"]').style.display =
show ? "block" : "none"),
showFooter: (show) =>
(document.querySelector('[data-todo="main"]').style.display = show
? "block"
: "none"),
displayCount: (count) => {
emptyElement(App.$.count);
insertHTML(App.$.count, `
insertHTML(
App.$.count,
`
<strong>${count}</strong>
${count === 1 ? 'item' : 'items'} left
`);
}
${count === 1 ? "item" : "items"} left
`
);
},
},
init() {
Todos.addEventListener('save', App.render);
Todos.addEventListener("save", App.render);
App.filter = getURLHash();
window.addEventListener('hashchange', () => {
window.addEventListener("hashchange", () => {
App.filter = getURLHash();
App.render();
});
App.$.input.addEventListener('keyup', e => {
if (e.key === 'Enter' && e.target.value.length) {
Todos.add({ title: e.target.value, completed: false, id: "id_" + Date.now() })
App.$.input.value = '';
App.$.input.addEventListener("keyup", (e) => {
if (e.key === "Enter" && e.target.value.length) {
Todos.add({
title: e.target.value,
completed: false,
id: "id_" + Date.now(),
});
App.$.input.value = "";
}
});
App.$.toggleAll.addEventListener('click', e => {
App.$.toggleAll.addEventListener("click", (e) => {
Todos.toggleAll();
});
App.$.clear.addEventListener('click', e => {
App.$.clear.addEventListener("click", (e) => {
Todos.clearCompleted();
});
App.bindTodoEvents();
App.render();
},
todoEvent(event, selector, handler) {
delegate(App.$.list, selector, event, e => {
let $el = e.target.closest('[data-id]');
delegate(App.$.list, selector, event, (e) => {
let $el = e.target.closest("[data-id]");
handler(Todos.get($el.dataset.id), $el, e);
});
},
bindTodoEvents() {
App.todoEvent('click', '[data-todo="destroy"]', todo => Todos.remove(todo));
App.todoEvent('click', '[data-todo="toggle"]', todo => Todos.toggle(todo));
App.todoEvent('dblclick', '[data-todo="label"]', (_, $li) => {
$li.classList.add('editing');
App.todoEvent("click", '[data-todo="destroy"]', (todo) =>
Todos.remove(todo)
);
App.todoEvent("click", '[data-todo="toggle"]', (todo) =>
Todos.toggle(todo)
);
App.todoEvent("dblclick", '[data-todo="label"]', (_, $li) => {
$li.classList.add("editing");
$li.querySelector('[data-todo="edit"]').focus();
});
App.todoEvent('keyup', '[data-todo="edit"]', (todo, $li, e) => {
App.todoEvent("keyup", '[data-todo="edit"]', (todo, $li, e) => {
let $input = $li.querySelector('[data-todo="edit"]');
if (e.key === 'Enter' && $input.value)
if (e.key === "Enter" && $input.value)
Todos.update({ ...todo, title: $input.value });
if (e.key === 'Escape') {
if (e.key === "Escape") {
$input.value = todo.title;
App.render();
}
});
App.todoEvent('blur', '[data-todo="edit"]', (todo, $li, e) => {
App.todoEvent("blur", '[data-todo="edit"]', (todo, $li, e) => {
const title = $li.querySelector('[data-todo="edit"]').value;
Todos.update({ ...todo, title });
});
},
createTodoItem(todo) {
const li = document.createElement('li');
const li = document.createElement("li");
li.dataset.id = todo.id;
if (todo.completed) { li.classList.add('completed'); }
insertHTML(li, `
if (todo.completed) {
li.classList.add("completed");
}
insertHTML(
li,
`
<div class="view">
<input data-todo="toggle" class="toggle" type="checkbox" ${todo.completed ? 'checked' : ''}>
<input data-todo="toggle" class="toggle" type="checkbox" ${
todo.completed ? "checked" : ""
}>
<label data-todo="label"></label>
<button class="destroy" data-todo="destroy"></button>
</div>
<input class="edit" data-todo="edit">
`);
`
);
li.querySelector('[data-todo="label"]').textContent = todo.title;
li.querySelector('[data-todo="edit"]').value = todo.title;
return li;
Expand All @@ -97,15 +124,15 @@ const App = {
const count = Todos.all().length;
App.$.setActiveFilter(App.filter);
emptyElement(App.$.list);
Todos.all(App.filter).forEach(todo => {
App.$.list.appendChild( App.createTodoItem(todo) );
Todos.all(App.filter).forEach((todo) => {
App.$.list.appendChild(App.createTodoItem(todo));
});
App.$.showMain(count);
App.$.showFooter(count);
App.$.showClear(Todos.hasCompleted());
App.$.toggleAll.checked = Todos.isAllCompleted();
App.$.displayCount(Todos.all('active').length);
}
App.$.displayCount(Todos.all("active").length);
},
};

App.init();
20 changes: 10 additions & 10 deletions js/helpers.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
export const getURLHash = () => document.location.hash.replace(/^#\//, '');
export const getURLHash = () => document.location.hash.replace(/^#\//, "");

export const delegate = (el, selector, event, handler) => {
el.addEventListener(event, e => {
if (e.target.matches(selector)) handler(e, el);
});
}
el.addEventListener(event, (e) => {
if (e.target.matches(selector)) handler(e, el);
});
};

export const insertHTML = (el, markup) => {
el.insertAdjacentHTML('afterbegin', markup);
}
el.insertAdjacentHTML("afterbegin", markup);
};

export const emptyElement = el => {
while (el.hasChildNodes()) {
export const emptyElement = (el) => {
while (el.hasChildNodes()) {
el.removeChild(el.lastChild);
}
}
};
Loading

0 comments on commit fbc1c98

Please sign in to comment.