Skip to main content

Tyrian Integration

forms4s is designed to be framework-agnostic, but it comes with Tyrian integration out of the box.

Usage

"org.business4s" %% "forms4s-tyrian" % "0.1.0"
case class MyModel(form: FormElementState)

enum MyMsg {
case FormUpdate(msg: FormElementUpdate)
case NoOp
}

object TyrianExample extends TyrianIOApp[MyMsg, MyModel] {

val myForm: FormElement = ???

def init(flags: Map[String, String]): (MyModel, Cmd[IO, MyMsg]) = {
(MyModel(FormElementState.empty(myForm)), Cmd.None)
}

def update(model: MyModel): MyMsg => (MyModel, Cmd[IO, MyMsg]) = {
case MyMsg.FormUpdate(msg) => (MyModel(model.form.update(msg)), Cmd.None)
case MyMsg.NoOp => (model, Cmd.None)
}

val renderer: FormRenderer = ???
def view(model: MyModel): Html[MyMsg] =
renderer.renderForm(model.form).map(update => MyMsg.FormUpdate(update))

def subscriptions(model: MyModel): Sub[IO, MyMsg] = Sub.None
def router: Location => MyMsg = _ => MyMsg.NoOp

}

The FormRenderer

The FormRenderer trait defines the interface for rendering form elements.

For most usages one of the following renderers should be enough

  • BulmaFormRenderer - Renders forms compatible with the Bulma CSS framework
  • BootstrapFormRenderer - Renders forms compatible with the Bootstrap CSS framework
  • RawFormRenderer - Renders forms using no classes but only semantic HTML. That HTML is optimized to be compatible with Pico CSS framework.

Customizing Form Renderers

If you need to customize form rendering, you have two options:

  1. For small modifications, you can extend one of the existing renderers and override specific methods to customize their behavior
  2. For completely custom rendering, you can implement the FormRenderer trait from scratch to have full control over the rendering process. In such a case check existing renderers for inspiration.