component rendering library
Rondo is available in Hex and can be installed as:
- Add rondo your list of dependencies in
mix.exs:
defdepsdo[{:rondo,"~> 0.1.0"}]endStart by creating a store
defmoduleMyApp.Storedodefstruct[stores: %{}]defimplRondo.State.Storedodefmount(%{stores: stores}=store,%{props: initial,type: :ephemeral}=descriptor)dostores=Map.put_new(stores,descriptor,initial){Map.get(stores,descriptor),%{store|stores: stores}}enddefhandle_info(store,_info)dostoreenddefhandle_action(store,descriptor,update_fn)do{prev,store}=mount(store,descriptor)value=update_fn.(prev)stores=Map.put(store.stores,descriptor,value){:ok,%{store|stores: stores}}enddefencode(%{stores: stores})dostores|>:erlang.term_to_binary()|>Base.url_encode64()enddefdecode_into(store,bin)dostores=bin|>Base.url_decode64!()|>:erlang.binary_to_term()%{store|stores: stores}endendendNow define an action with an affordance (in jsonschema format)
defmoduleMyApp.Action.Incrementdodefaffordance(_props)do%{"type"=>["integer","null"]}enddefaction(_props,state,input)dostate+(input||0)endendAnd a component to use the action
defmoduleMyApp.ComponentdouseRondo.ComponentaliasMyApp.Action.Incrementdefstate(_props,_context)do%{counter: create_store(0)}enddefrender(%{counter: counter})doel("Text",%{"increment"=>ref([:counter])|>action(Increment)},[counter])endendWe can now render the app
# Set up our store and appstore=%MyApp.Store{}app=Rondo.create_application(MyApp.Component)# Perform the initial render{app,store}=Rondo.render(app,store)# Assert that the counter is initialized and being sent as the first child{:ok,0}=Rondo.Test.fetch_path(app,[0])# We need to get the action ref to submit a form{:ok,%{props: %{"increment"=>%{ref: action_ref}}}}=Rondo.Test.fetch_path(app,[])# If we submit an invalid action it should let us know{:invalid,errors,app,store}=Rondo.submit_action(app,store,action_ref,"Invalid type")# We now submit a valid action and it goes through{:ok,app,store}=Rondo.submit_action(app,store,action_ref,1)# Trigger a render{app,store}=Rondo.render(app,store)# We now have the incremented value!{:ok,1}=Rondo.Test.fetch_path(app,[0])