import * as L from "lonna" ; import { globalScope } from "lonna" ; import { h , mount , ListView } from "../../src/index" ; import itemAddedFromSocketE from "./fake-socket" ; let idCounter = 1 ; type Id = number ; type TodoItem = { name : string ; id : Id ; completed : boolean ; } ; function todoItem ( name , id = idCounter ++ , completed = false ) { return { name , completed , id } ; } const initialItems = [ "learn typescript" , "fix handbrake" ] . map ( s => todoItem ( s ) ) ; type AppEvent = { action : "add" ; name : string ; } | { action : "remove" ; id : Id ; } | { action : "update" ; item : TodoItem ; } ; const appEvents = L . bus < AppEvent > ( ) ; itemAddedFromSocketE . forEach ( name => appEvents . push ( { action : "add" , name } ) ) ; function reducer ( items , event ) { switch ( event . action ) { case "add" : return items . concat ( todoItem ( event . name ) ) ; case "remove" : return items . filter ( i => i . id !== event . id ) ; case "update" : return items . map ( i => i . id === event . item . id ? event . item : i ) ; default : console . warn ( "Unknown event" , event ) ; return items ; } } const allItems = appEvents . pipe ( L . scan ( initialItems , reducer , globalScope ) ) ; const App = ( ) => { return ( < div > < h1 > TODO App < /h1> < ItemList items = { allItems } / > < NewItem /> < JsonView json = { allItems } / > < /div>); } ; const ItemList = ( { items } ) => { return ( < ul > { } < ListView observable = { items } renderObservable = { ( id , item ) => < li > < ItemView id = { id } item = { item } / > < /li>} getKey={item => item.id}/ > < /ul>); } ; const ItemView = ( { id , item } ) => { const itemAtom = L . atom ( item , updated => appEvents . push ( { action : "update" , item : updated } ) ) ; return ( < span > < span className = "name" > < TextInput value = { L . view ( itemAtom , "name" ) } /></span > < Checkbox checked = { L . view ( itemAtom , "completed" ) } /> < a className = "removeItem" onClick = { ( ) => appEvents . push ( { action : "remove" , id } ) } > remove < /a> < /span>); } ; const NewItem = ( ) => { const name = L . atom ( "" ) ; const addNew = ( ) => appEvents . push ( { action : "add" , name : name . get ( ) } ) ; return ( < div className = "newItem" > < TextInput placeholder = "new item name" value = { name } / > < button onClick = { addNew } > Add new item < /button> < /div>); } ; const TextInput = ( props ) => { return < input { ... { type : "text" , onInput : e => { props . value . set ( e . currentTarget . value ) ; } , ... props , value : props . value } } / > ; } ; const Checkbox = ( props ) => { return < input { ... { type : "checkbox" , onInput : e => { props . checked . set ( e . currentTarget . checked ) ; } , ... props , checked : props . checked } } / > ; } ; const JsonView = ( { json } ) => { const s = L . view ( json , st => JSON . stringify ( st , null , 2 ) ) ; return < pre > { s } < /pre>; } ; mount ( < App />, document.getElementById("root")!);