gale/app.js

45 lines
1.3 KiB
JavaScript
Raw Normal View History

2025-02-13 14:27:41 -05:00
const {DOM} = Gale({
Button: {
padding: "20px",
background: "orange",
".Inner": {
fontSize: "10rem"
2025-02-12 16:09:59 -05:00
}
},
2025-02-13 14:27:41 -05:00
Outline: {
border: "2px solid orange"
}
2025-02-12 16:09:59 -05:00
});
2025-02-13 14:27:41 -05:00
2025-02-19 17:01:11 -05:00
/** @typedef {{done:boolean, text:string}} Todo */
2025-02-12 16:57:41 -05:00
2025-02-19 17:01:11 -05:00
/** @type {<T extends object>(obj:T, key:string)=>T} */
const Store =(obj, key)=> {
const recall = localStorage.getItem(key);
const store = vanX.reactive(recall ? JSON.parse(recall) : obj);
van.derive(() => localStorage.setItem(key, JSON.stringify(vanX.compact(store))));
return store;
}
2025-02-12 16:57:41 -05:00
2025-02-19 17:01:11 -05:00
const items = Store({
pending:"",
todos:/** @type {Todo[]}*/([])
}, "Todos?");
const {div, input, button, del, span, a} = van.tags;
const TodoList = () => {
const inputDom = input({type: "text", value:()=>items.pending, oninput(){items.pending = this.value}});
return div(
()=>div(items.pending),
inputDom, DOM.button.Outline.Button({onclick: () => items.todos.push({text: inputDom.value, done: false})}, "Add"),
vanX.list(div, items.todos, ({val: v}, deleter) => div(
input({type: "checkbox", checked: () => v.done, onclick: e => v.done = e.target.checked}),
() => (v.done ? del : span)(v.text),
a({onclick: deleter}, "❌"),
)),
)
}
van.add(document.body, TodoList());