In Tyrian, you describe your view in Scala and the VirtualDom implementation that powers Tyrian (Scala.js Snabbdom) renders that description into HTML.
Here is a simple made up example of the syntax to give you a flavor:
import tyrian.* import tyrian.Html.* import tyrian.CSS enum Msg: case Greet val myStyles = style(CSS.`font-family`("Arial, Helvetica, sans-serif")) val topLine = p(b(text("This is some HTML in bold."))) div(id := "my-container")( div(myStyles)( topLine, p("Hello, world!"), button(onClick(Msg.Greet))("Say hello!") ) )
A vast list of the common HTML tags, attributes, and CSS property types have been generated for you, and effort has gone in to making the experience reasonably pleasant.
The arrangement of tags follows similar approaches by other compiled languages trying to represent HTML:
tag-name(List(attributes, ...))(List(children, ...))
For example, here we have a
span with an attribute and a child element:
span(`class` := "green-box")( p("This is some text.") )
You can omit the attributes and the syntax is valid:
span( p("This is some text.") )
Note that plain text can be declare as
text or just omitted, in other words these are equivalent:
p("some text") p(text("some text"))
To distinguish them from similarly named tags (e.g. the
title attribute and the
title tag…), attributes are declared as
attribute-name := attribute-value, e.g.:
id := "my-container"
Some HTML attributes / properties use Scala reserved words, and so have a variety of encodings to suit all tastes. For example
class is a Scala reserved word and you cannot use it directly, but you can use any of these instead:
`class` cls className _class
Styles are also baked in, albeit it in a slightly crude way, but you will get some IDE support. You can do things like the following:
You can also pull in SVG tags and attributes using:
Many standard CSS terms can be imported using:
If you find we’ve missed a tag or attribute or something, please raise an issue. In the meantime, you can always make your own. Here are just a few made up examples, each of these has numerous constructors for you to explore:
// A 'canvas' tag tag("canvas")(id := "an-id")(Nil) // or Tag("canvas", List(id := "an-id"), Nil) // An attribute attribute("my-attribute", "its-value") // A property property("my-property", "its-value") // Styles style("width", "100px") styles("width" -> "100px", "height" -> "50px") // An event-type attribute onEvent("click", (evt: Tyrian.Event) => Msg.Greet)
Note that everything is stringly typed, and that’s because in HTML everything is stringly typed too! In the generated tags, we’ve added support for things like attributes accepting
Booleans and so on where they have known acceptable input types.
One occasion where you may need to make your own tags or attributes etc., is when Tyrian has an incorrectly declared definition of something or other.
A previous case of this was where the input field
property was incorrectly declared as an
attribute, and so the value wasn’t changed as expected based on model updates.
Effort has gone in to getting these things right, but if you come across any issues, please report them, and the workaround is to re-declare it yourself as above while a fix is produced.