diff --git a/app.js b/app.js index 025ba73..87b4e2d 100644 --- a/app.js +++ b/app.js @@ -12,8 +12,34 @@ const {DOM} = Gale({ }); -const el = DOM.a.Button.Outline({onclick(){console.log("clicked!")}}, "Click!"); -console.log(el); +/** @typedef {{done:boolean, text:string}} Todo */ +/** @type {(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; +} -van.add(document.body, el, DOM.h1.Outline["Button.Inner"]("title")); \ No newline at end of file +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()); \ No newline at end of file diff --git a/gale.js b/gale.js index 742b4aa..302da8f 100644 --- a/gale.js +++ b/gale.js @@ -27,7 +27,7 @@ const Tier=(selector, obj)=> let i = 0; /** @type {Gale.CreateSheet} */ -const Gale = (sheet)=> +globalThis.Gale =sheet=> { const id = i ? "_"+i : ""; i++; diff --git a/index.html b/index.html index 1f7546e..2eeec3b 100644 --- a/index.html +++ b/index.html @@ -1,12 +1,23 @@ - - - - Document - - - - - - + + + + Document + + + + + + + + \ No newline at end of file diff --git a/proxy.js b/proxy.js new file mode 100644 index 0000000..40d355e --- /dev/null +++ b/proxy.js @@ -0,0 +1,32 @@ +const person = van.state({name:"seth", age:41}); +console.log(Object.hasOwn(person, "rawVal")); + +/** @type {(obj:T, key:string)=>T} */ +const Deep =(obj, key)=> +{ + const proxInner =(context, key)=> new Proxy({}, { + get(_, prop) + { + const path = key+" . "+prop; + console.log(path, "accessed!"); + const value = context[key]; + + return proxInner(value, path); + } + }); + + const proxOuter = new Proxy({}, { + get(_, prop) + { + return proxInner(obj, prop); + }, + set(_, prop, val) + { + obj[prop] = val; + } + }); + + return proxOuter; +} + +export default Deep; \ No newline at end of file diff --git a/proxy.test.ts b/proxy.test.ts new file mode 100644 index 0000000..e3323f2 --- /dev/null +++ b/proxy.test.ts @@ -0,0 +1,9 @@ +import * as assert from "jsr:@std/assert"; +import Deep from "./proxy.js"; + +Deno.test("proxy", ()=>{ + + const d1 = Deep({name:"seth", age:41, tags:[]}, "p1"); + const dig = d1.name.other; + const dig2 = dig.so.deep; +}); \ No newline at end of file diff --git a/types.d.ts b/types.d.ts index 6c8d594..5440e9a 100644 --- a/types.d.ts +++ b/types.d.ts @@ -62,7 +62,10 @@ declare global readonly noreactive: (obj: T) => T readonly stateFields: (obj: T) => VanX.StateOf readonly raw: (obj: T) => T - readonly list: (container: (() => ElementType) | ElementType, items: T,itemFunc: (v: Van.State>, deleter: () => void, k: VanX.KeyType) => Node) => ElementType + readonly list: ( + container: (() => ElementType) | ElementType, + items: T,itemFunc: (v: Van.State>, deleter: () => void, k: VanX.KeyType) => Node + ) => ElementType readonly replace: (obj: T, replacement: VanX.ReplacementFunc | T) => T readonly compact: (obj: T) => T };