Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve Thoth.Elmish.FormBuilder docs #8

Open
MangelMaxime opened this issue Nov 8, 2019 · 1 comment
Open

Improve Thoth.Elmish.FormBuilder docs #8

MangelMaxime opened this issue Nov 8, 2019 · 1 comment

Comments

@MangelMaxime
Copy link
Contributor

Issue by nojaf
Thursday Jan 10, 2019 at 13:23 GMT
Originally opened as MangelMaxime/Thoth#116


I've created my own FormComponent for Thoth.Elmish.FormBuilder.

namespace nojaf.FormInputs

open Thoth.Elmish.FormBuilder
open Thoth.Elmish.FormBuilder.Types
open Thoth.Json
open Fable.Helpers.React
open Fable.Helpers.React.Props

[<RequireQualifiedAccess>]
module ColorPicker =

    type Msg =
        | ChangeRed of int
        | ChangeGreen of int
        | ChangeBlue of int
        interface IFieldMsg

    type Validator = State -> ValidationState

    type State =
        { Label : string
          Red: int
          Green: int
          Blue: int
          Name : string }

        member this.Value() = sprintf "rgb(%i,%i,%i)" this.Red this.Green this.Blue

    let private init (state: FieldState) =
        state, FormCmd.none

    let private toJson (state : FieldState) =   
        let state : State = state :?> State
        state.Name, Encode.string (state.Value())

    let private update (msg : FieldMsg) (state : FieldState) =
        // Cast the received message into it's real type
        let msg = msg :?> Msg
        // Cast the received state into it's real type
        let state = state :?> State

        match msg with
        | ChangeBlue blue ->
            { state with Blue = blue }
            |> box, FormCmd.none
        | ChangeRed red ->
            { state with Red = red }
            |> box, FormCmd.none
        | ChangeGreen green ->
            { state with Green = green }
            |> box, FormCmd.none

    let private view (state: FieldState) (dispatch: IFieldMsg -> unit) =
        let state : State = state :?> State
        let changeValue msg (ev: Fable.Import.React.FormEvent) =
            let value = ev.Value |> (int)
            dispatch (msg value)
        
        div [] [
            label [ Class "label"; HtmlFor state.Name ] [ str state.Label ]
            div [] [
                strong [] [str "R"]
                input [Type "range"; Min 0; Max 255; Value state.Red; OnChange (changeValue Msg.ChangeRed)]
            ]
            div [] [
                strong [] [str "G"]
                input [Type "range"; Min 0; Max 255; Value state.Green; OnChange (changeValue Msg.ChangeGreen)]
            ]
            div [] [
                strong [] [str "B"]
                input [Type "range"; Min 0; Max 255; Value state.Blue; OnChange (changeValue Msg.ChangeBlue)]
            ]
            div [Style [CSSProp.BackgroundColor (state.Value()); CSSProp.Width 100; CSSProp.Height 100; CSSProp.MarginTop 30; CSSProp.MarginBottom 30]] []
        ]

    let config : FieldConfig =
        { View = view
          Update = update
          Init = init
          Validate = id
          IsValid =  fun _ -> true
          ToJson = toJson
          SetError = fun s _ -> s }

    type ColorPicker private (state: State) =
        static member Create(name: string) =
            ColorPicker 
                { Label = ""
                  Red = 0
                  Green = 0
                  Blue = 0
                  Name = name }
        member __.WithDefaultView () : FieldBuilder =
            { Type = "nojaf-color-picker"
              State = state
              Name = state.Name
              Config = config }
        member __.WithLabel (label : string) =
            ColorPicker { state with Label = label }

When reading the docs while making I think in general it would help if api docs showed the structure of the types as well. Perhaps something similar to how fake does this.

At some points I was a bit confused is this my own type or a FormBuilder type?

The sample State was also a bit confusing. Do I really need all these properties?

@MangelMaxime
Copy link
Contributor Author

Comment by MangelMaxime
Thursday Jan 10, 2019 at 14:18 GMT


About the sample State, yes you need all these properties for a generic input.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant