gale/app.js

76 lines
1.7 KiB
JavaScript

const {DOM} = Gale({
Button: {
padding: "20px",
background: "orange",
".Inner": {
fontSize: "10rem"
}
},
Outline: {
border: "2px solid orange"
},
Window:{
height: "100vh",
border: "2px solid black",
display: "flex",
flexDirection: "row",
alignItems: "end",
justifyContent: "center",
gap: "10px"
},
Ability:{
width: "50px",
height: "50px",
background: "red",
transition: "all 0.4s",
":hover":{
transform:"scale(1.1)"
}
}
});
/** @typedef {{done:boolean, text:string}} Todo */
/** @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;
}
const UI =()=>
{
return DOM.div.Window(
DOM.div.Ability(),
DOM.div.Ability(),
DOM.div.Ability(),
)
}
van.add(document.body, UI());
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}, "❌"),
)),
)
}