Views
Ranvier's view layer renders signals, memos and effects as HTML. A view is a template component: a template built once per definition, and a setup function that runs once per mounted instance. Each dynamic part of the template reads the instance and writes one DOM node, attribute or property when the values it reads change; the rest of the tree stays in place.
The same component definition renders in three places:
- In the browser, compiled with Fable, mounted into a DOM element.
- On the server, on .NET or under Node, rendered to an HTML string. See Server rendering.
- Over server HTML, where the client hydrates the server's nodes in place.
A taste
open global.Ranvier
open Ranvier.View
open Ranvier.View.Sugar
type CounterProps = { Start: int; Label: string }
type Counter =
{ Count: Signal<int>; Label: string }
static member Create(_: Setup, props: CounterProps) =
{ Count = createSignal props.Start; Label = props.Label }
static member View =
div (Attrs.className "counter") {
span (Attrs.className "label") { fun c -> c.Label }
button (Attrs.attribute ("type", "button"), Events.onClick (fun c _ -> c.Count.Value <- c.Count.Value + 1)) {
fun c -> string c.Count.Value
}
}
let counter = Component.ofMembers<Counter, _> ()
Create runs once per instance and returns the instance record. View is the template: each fun c -> ... inside it is a binding that reads the instance. A click writes the signal, and the render effect writes the button's text.
Layers and status
| Piece | Package or project | Status |
|---|---|---|
| Template components, server HTML writer | Ranvier.View | Alpha. Compiles for .NET and Fable. |
| Builder sugar (free tags, control flow, declarations) | Ranvier.View (Ranvier.View.Sugar) | Alpha; the primary authoring style. See Sugar. |
| DOM mounting, hydration, document head | Ranvier.View.Dom | Alpha. Runs under Fable. |
Authored views (Program.View, Generated.Html.Program) | Ranvier.View.Dom | Alpha. See Other authoring layers. |
| DOM helper library | src/Fable.Ranvier | Proof of concept, not packaged. See Other authoring layers. |
| anime.js bindings, owners and signals for animations | Fable.Ranvier.Anime | Alpha. Compiles for .NET and Fable. See Animation. |
| Motion template parts | Ranvier.View.Anime | Alpha. See Motion parts. |
| Wire codecs for state transfer | Ranvier.Wire | Preview. See State transfer. |
| Runnable reference | examples/Fable.Ranvier.Playground | Vite app and test suite. |
Pages
- Getting started: a counter, from project setup to a mounted DOM tree.
- Templates and bindings: elements, text, attributes, properties and how bindings re-run.
- Components: the four declaration styles, setup, ids and child components.
- Lists and keyed rows:
forEach,forEachFixedandeach. - Conditional arms:
show,showElse,matchWithandbranch. - Boundaries: pending and error views for async reads.
- Events and hooks: handlers, element references, widgets and lent elements.
- Document head: titles, meta and link entries owned by components.
- Animation: typed anime.js parameters, values, eases, staggers and timelines.
- Owning and driving animations:
own,track,scrub,driveand the motion policy. - Motion parts: enter, exit, FLIP and signal-driven animation in templates.
- Testing and costs: a manual anime clock in tests, and the bundle cost of animation.
- Mounts and lifetimes: mounting, commit modes, failures and disposal.
- Elmish components: an
Mvuloop per component. - Sugar: the free-tag vocabulary, its inference rule and its compile errors.
- Testing views: HTML checks on .NET and DOM checks under Node.
- Other authoring layers:
Program.ViewandFable.Ranvier. - Troubleshooting: error messages and their causes.
- API reference: the modules behind each page.
The Server section covers Server.render, hydration, state transfer, deployment and performance.