Fable.Form
Fable.Form copied to clipboard
Explore if Fable.Form can be used with React hooks
In theory, it should be possible to make Fable.Form works outside of Elmish.
The base package of Fable.Form don't have a dependency on Elmish only the view does to get access to Dispatch
which is used to send the new form representation.
I think it should be possible to make Fable.Form support both Elmish and Hooks.
@MangelMaxime
I am playing around with Fable form trying to implement it with only React .
I managed to use React.useReducer
as a update function which also gives me a Dispatch
, only thing is that an update function used by useReducer needs to be pure so no Cmd
commands after changing the model.
This is what i have sofar
type Values = {
Email : string
Password : string
RememberMe : bool
}
type Model = Form.View.Model<Values>
type Message =
| FormChanged of Model
| LogIn of string * string * bool
let evolve (model : Model) = function
| FormChanged newModel -> newModel
| LogIn (email, password, rememberMe) ->
{ model with State = Form.View.Success "You have logged in successfully" }
let initialState () =
{
Email = ""
Password = ""
RememberMe = false
}
|> Form.View.idle
let form =
let emailField =
Form.textField {
Parser = fun v ->
if v.Contains("@") then Ok v
else Error "Invalid email address, Email address must contain a @ symbol"
Value = fun v -> v.Email
Update = fun newValue values -> { values with Email = newValue }
Error = fun _ -> None
Attributes = {
Label = "Email"
Placeholder = "Enter your email address"
HtmlAttributes = [ ]
}
}
let passwordField =
Form.passwordField {
Parser = Ok
Value = fun v -> v.Password
Update = fun newValue values -> { values with Password = newValue }
Error = fun _ -> None
Attributes = {
Label = "Password"
Placeholder = "Enter your password"
HtmlAttributes = [ prop.className "w" ]
}
}
let rememberMe =
Form.checkboxField {
Parser = Ok
Value = fun v -> v.RememberMe
Update = fun newValue values -> { values with RememberMe = newValue }
Error = fun _ -> None
Attributes = { Text = "Remember me" }
}
let onSubmit = fun email password rememberMe -> LogIn (email, password, rememberMe)
Form.succeed onSubmit
|> Form.append emailField
|> Form.append passwordField
|> Form.append rememberMe
type Component =
[<ReactComponent>]
static member LogInForm () =
let model, dispatch = React.useReducer (evolve, initialState ())
Form.View.asHtml
{
Dispatch = dispatch
OnChange = FormChanged
Action = Form.View.Action.SubmitOnly "Sign in"
Validation = Form.View.ValidateOnSubmit
}
form
model
@Dewald844
Hello,
thank you for the example, this is plus to have for people who want to avoid to use useElmish
hooks.
My idea is to go one step farther and remove Elmish as a dependency of Fable.Form. This will require a few changes internally and to the exposed API but I hope to be able to focus on it soon once I am done upgrading another OSS project of mine.