Skip to content

Instantly share code, notes, and snippets.

@Kimserey
Forked from Tarmil/Counter.fs
Created March 21, 2016 09:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Kimserey/fb5e0b3b6a1bdb85d892 to your computer and use it in GitHub Desktop.
Save Kimserey/fb5e0b3b6a1bdb85d892 to your computer and use it in GitHub Desktop.
Port of the first example from https://github.com/evancz/elm-architecture-tutorial to WebSharper; lens-based version
namespace Example1
open WebSharper
open WebSharper.UI.Next
open WebSharper.UI.Next.Html
open WebSharper.UI.Next.Client
[<JavaScript>]
module Counter =
type Model = { first: int; second: int }
let private decrementFirst m = { m with first = m.first - 1 }
let private incrementFirst m = { m with first = m.first + 1 }
let private decrementSecond m = { m with second = m.second - 1 }
let private incrementSecond m = { m with second = m.second + 1 }
let private lensFirst (m: IRef<Model>) =
m.Lens (fun m -> m.first) (fun m x -> { m with first = x })
let private lensSecond (m: IRef<Model>) =
m.Lens (fun m -> m.second) (fun m x -> { m with second = x })
let private countStyle =
Attr.Concat [
Attr.Style "font-size" "20px"
Attr.Style "font-family" "monospace"
Attr.Style "display" "inline-block"
Attr.Style "width" "50px"
Attr.Style "text-align" "center"
]
let Render (model: IRef<Model>) : Doc =
div [
h1 [text "First:"]
buttonAttr [on.click (fun _ _ -> model.Update decrementFirst)] [text "-"]
Doc.IntInputUnchecked [countStyle] (lensFirst model)
buttonAttr [on.click (fun _ _ -> model.Update incrementFirst)] [text "+"]
h1 [text "Second:"]
buttonAttr [on.click (fun _ _ -> model.Update decrementSecond)] [text "-"]
Doc.IntInputUnchecked [countStyle] (lensSecond model)
buttonAttr [on.click (fun _ _ -> model.Update incrementSecond)] [text "+"]
]
:> Doc
namespace Example1
open WebSharper
open WebSharper.JavaScript
open WebSharper.JQuery
open WebSharper.UI.Next
open WebSharper.UI.Next.Client
[<JavaScript>]
module Main =
let Main =
StartApp.Start<Counter.Model> {
Model = { first = 0; second = 0 }
Render = Counter.Render
}
// Straightforward equivalent of Elm's StartApp.Simple
// using `IRef<Model>` to model together Elm's `Signal.Address Action` and `Model`
// and renaming `view` to `Render` to avoid ambiguity with UI.Next's View<'T>
module StartApp
open WebSharper
open WebSharper.JavaScript
open WebSharper.UI.Next
open WebSharper.UI.Next.Client
type App<'Model> =
{
Model : 'Model
Render : IRef<'Model> -> Doc
}
[<JavaScript>]
let Start<'Model> (app: App<'Model>) : unit =
let model = Var.Create app.Model :> IRef<'Model>
app.Render model
|> Doc.RunAppend JS.Document?body
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment