Skip to content

Instantly share code, notes, and snippets.

@TyOverby
Created October 30, 2020 23:55
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save TyOverby/e0f7e944d002cdf7144aaf0102d16ed5 to your computer and use it in GitHub Desktop.
open! Core_kernel
open! Bonsai_web
open Bonsai.Let_syntax
open Vdom
module Model = struct
type t = int Int.Map.t [@@deriving sexp, equal]
end
module Action = struct
type t =
| New
| Update of int * int
[@@deriving sexp]
end
let default_model = Int.Map.empty
let apply_action ~inject:_ ~schedule_event:_ model = function
| Action.New -> Map.add_exn model ~key:(Map.length model) ~data:0
| Update (location, diff) ->
Map.update model location ~f:(Option.value_map ~default:0 ~f:(( + ) diff))
;;
let component =
let%sub state =
Bonsai.state_machine0 [%here] (module Model) (module Action) ~default_model ~apply_action
in
return
@@ let%map state, inject = state in
let button text action =
Node.button [ Attr.on_click (fun _ -> inject action) ] [ Node.text text ]
in
let add_button = button "add" New in
let for_each i c =
Node.div [] [ button "-1" (Update (i, -1)); Node.textf "%d" c; button "+1" (Update (i, 1)) ]
in
let counters = state |> Map.data |> List.mapi ~f:for_each in
Node.div [] (add_button :: counters)
;;
let _ = Start.start Start.Result_spec.just_the_view ~bind_to_element_with_id:"app" component
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment