mirror of
https://github.com/morris/vanilla-todo.git
synced 2025-08-20 21:02:10 +02:00
update to ES2020, some refactoring and cleanups
This commit is contained in:
@@ -1,49 +1,56 @@
|
||||
/* global VT */
|
||||
window.VT = window.VT || {};
|
||||
import { AppCollapsible } from './AppCollapsible.js';
|
||||
import { AppFlip } from './AppFlip.js';
|
||||
import { AppFps } from './AppFps.js';
|
||||
import { AppIcon } from './AppIcon.js';
|
||||
import { TodoFrameCustom } from './TodoFrameCustom.js';
|
||||
import { TodoFrameDays } from './TodoFrameDays.js';
|
||||
import { TodoStore } from './TodoStore.js';
|
||||
import { formatDateId } from './util.js';
|
||||
|
||||
VT.TodoApp = function (el) {
|
||||
var state = {
|
||||
export function TodoApp(el) {
|
||||
const state = {
|
||||
items: [],
|
||||
customLists: [],
|
||||
at: VT.formatDateId(new Date()),
|
||||
at: formatDateId(new Date()),
|
||||
customAt: 0,
|
||||
};
|
||||
|
||||
el.innerHTML = [
|
||||
'<header class="app-header">',
|
||||
' <h1 class="title">VANILLA TODO</h1>',
|
||||
' <p class="app-fps"></p>',
|
||||
'</header>',
|
||||
'<div class="todo-frame -days"></div>',
|
||||
'<div class="app-collapsible">',
|
||||
' <p class="bar">',
|
||||
' <button class="app-button -circle toggle"><i class="app-icon" data-id="chevron-up-24"></i></button>',
|
||||
' </p>',
|
||||
' <div class="body">',
|
||||
' <div class="todo-frame -custom"></div>',
|
||||
' </div>',
|
||||
'</div>',
|
||||
'<footer class="app-footer">',
|
||||
' <p>',
|
||||
' VANILLA TODO © 2020 <a href="https://morrisbrodersen.de">Morris Brodersen</a>',
|
||||
' — A case study on viable techniques for vanilla web development.',
|
||||
' <a href="https://github.com/morris/vanilla-todo">About →</a>',
|
||||
' </p>',
|
||||
'</footer>',
|
||||
].join('\n');
|
||||
el.innerHTML = `
|
||||
<header class="app-header">
|
||||
<h1 class="title">VANILLA TODO</h1>
|
||||
<p class="app-fps fps"></p>
|
||||
</header>
|
||||
<div class="todo-frame -days"></div>
|
||||
<div class="app-collapsible">
|
||||
<p class="bar">
|
||||
<button class="app-button -circle toggle"><i class="app-icon" data-id="chevron-up-24"></i></button>
|
||||
</p>
|
||||
<div class="body">
|
||||
<div class="todo-frame -custom"></div>
|
||||
</div>
|
||||
</div>
|
||||
<footer class="app-footer">
|
||||
<p>
|
||||
VANILLA TODO © 2020-2022 <a href="https://morrisbrodersen.de">Morris Brodersen</a>
|
||||
— A case study on viable techniques for vanilla web development.
|
||||
<a href="https://github.com/morris/vanilla-todo">About →</a>
|
||||
</p>
|
||||
</footer>
|
||||
`;
|
||||
|
||||
VT.AppFlip(el, {
|
||||
AppFlip(el, {
|
||||
selector: '.todo-item, .todo-item-input, .todo-day, .todo-custom-list',
|
||||
removeTimeout: 200,
|
||||
});
|
||||
VT.TodoStore(el);
|
||||
|
||||
el.querySelectorAll('.app-collapsible').forEach(VT.AppCollapsible);
|
||||
el.querySelectorAll('.app-icon').forEach(VT.AppIcon);
|
||||
el.querySelectorAll('.app-fps').forEach(VT.AppFps);
|
||||
TodoStore(el);
|
||||
|
||||
VT.TodoFrameDays(el.querySelector('.todo-frame.-days'));
|
||||
VT.TodoFrameCustom(el.querySelector('.todo-frame.-custom'));
|
||||
el.querySelectorAll('.app-collapsible').forEach(AppCollapsible);
|
||||
el.querySelectorAll('.app-icon').forEach(AppIcon);
|
||||
el.querySelectorAll('.app-fps').forEach(AppFps);
|
||||
|
||||
TodoFrameDays(el.querySelector('.todo-frame.-days'));
|
||||
TodoFrameCustom(el.querySelector('.todo-frame.-custom'));
|
||||
|
||||
// each of these events make changes to the HTML to be animated using FLIP
|
||||
// listening to them using "capture" dispatches "beforeFlip" before any changes
|
||||
@@ -53,30 +60,30 @@ VT.TodoApp = function (el) {
|
||||
el.addEventListener('draggableDrop', beforeFlip, true);
|
||||
|
||||
// some necessary work to orchestrate drag & drop with FLIP animations
|
||||
el.addEventListener('draggableStart', function (e) {
|
||||
el.addEventListener('draggableStart', (e) => {
|
||||
e.detail.image.classList.add('_noflip');
|
||||
el.appendChild(e.detail.image);
|
||||
});
|
||||
|
||||
el.addEventListener('draggableCancel', function (e) {
|
||||
el.addEventListener('draggableCancel', (e) => {
|
||||
e.detail.image.classList.remove('_noflip');
|
||||
update();
|
||||
});
|
||||
|
||||
el.addEventListener('draggableDrop', function (e) {
|
||||
el.addEventListener('draggableDrop', (e) => {
|
||||
e.detail.image.classList.remove('_noflip');
|
||||
});
|
||||
|
||||
el.addEventListener('sortableUpdate', function (e) {
|
||||
el.addEventListener('sortableUpdate', (e) => {
|
||||
e.detail.placeholder.classList.add('_noflip');
|
||||
});
|
||||
|
||||
// dispatch "focusOther" .use-focus-other inputs if they are not active
|
||||
// dispatch "focusOther" on .use-focus-other inputs if they are not active
|
||||
// ensures only one edit input is active
|
||||
el.addEventListener('focusin', function (e) {
|
||||
el.addEventListener('focusin', (e) => {
|
||||
if (!e.target.classList.contains('use-focus-other')) return;
|
||||
|
||||
document.querySelectorAll('.use-focus-other').forEach(function (el) {
|
||||
document.querySelectorAll('.use-focus-other').forEach((el) => {
|
||||
if (el === e.target) return;
|
||||
el.dispatchEvent(new CustomEvent('focusOther'));
|
||||
});
|
||||
@@ -85,9 +92,7 @@ VT.TodoApp = function (el) {
|
||||
// listen to the TodoStore's data
|
||||
// this is the main update
|
||||
// everything else is related to drag & drop or FLIP animations
|
||||
el.addEventListener('todoData', function (e) {
|
||||
update(e.detail);
|
||||
});
|
||||
el.addEventListener('todoData', (e) => update(e.detail));
|
||||
|
||||
// dispatch "flip" after HTML changes from these events
|
||||
// this plays the FLIP animations
|
||||
@@ -96,40 +101,27 @@ VT.TodoApp = function (el) {
|
||||
el.addEventListener('draggableCancel', flip);
|
||||
el.addEventListener('draggableDrop', flip);
|
||||
|
||||
el.todoStore.load();
|
||||
el.dispatchEvent(new CustomEvent('loadStore'));
|
||||
|
||||
function update(next) {
|
||||
Object.assign(state, next);
|
||||
|
||||
el.querySelector('.todo-frame.-days').todoFrameDays.update({
|
||||
items: state.items,
|
||||
at: state.at,
|
||||
});
|
||||
el.querySelectorAll('.todo-frame').forEach((el) =>
|
||||
el.dispatchEvent(new CustomEvent('todoData', { detail: state }))
|
||||
);
|
||||
|
||||
el.querySelector('.todo-frame.-custom').todoFrameCustom.update({
|
||||
lists: state.customLists,
|
||||
items: state.items,
|
||||
at: state.customAt,
|
||||
});
|
||||
|
||||
el.querySelectorAll('.app-collapsible').forEach(function (el) {
|
||||
el.appCollapsible.update();
|
||||
});
|
||||
el.querySelectorAll('.app-collapsible').forEach((el) =>
|
||||
el.dispatchEvent(new CustomEvent('collapse'))
|
||||
);
|
||||
}
|
||||
|
||||
function beforeFlip() {
|
||||
el.dispatchEvent(
|
||||
new CustomEvent('beforeFlip', {
|
||||
bubbles: true,
|
||||
})
|
||||
);
|
||||
function beforeFlip(e) {
|
||||
if (e.type === 'todoData' && e.target !== el) return;
|
||||
|
||||
el.dispatchEvent(new CustomEvent('beforeFlip'));
|
||||
}
|
||||
|
||||
function flip() {
|
||||
el.dispatchEvent(
|
||||
new CustomEvent('flip', {
|
||||
bubbles: true,
|
||||
})
|
||||
);
|
||||
el.dispatchEvent(new CustomEvent('flip'));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
Reference in New Issue
Block a user