package bonsai

  1. Overview
  2. Docs
Legend:
Library
Module
Module type
Parameter
Class
Class type

Overview

The Vdom.Node and Vdom.Attr modules contain primitives for constructing virtual-dom nodes which mirror the browsers DOM API. This is great for users who know exactly what they want the document to contain, but all-things-considered, is a pretty low-level interface.

Bonsai_web.View is - at its core - a higher-level API for building Vdom.*.t, for people who want a button element, and would like to avoid boilerplate for common elements like buttons:

Vdom.Node.button
  ~attr:(Vdom.Attr.on_click (fun _ -> do_thing))
  [ Vdom.Node.text "click me" ]

;; (* vs *)

View.button theme ~on_click:do_thing "click me"

or basic layout primitives:

Vdom.Node.div
  ~attr:(Vdom.Attr.style (Css_gen.flex_container ~direction:`Row ~wrap:`Wrap ()))
  [a; b; c]

;; (* vs *)

View.hbox ~wrap:Wrap [a; b; c]

Theming

Another big focus of the View module is an API for building composable, extendable, and customizable themes. All of the View.* functions which take a View.Theme.t as the first argument are handing over basic "look and feel" decisions to the provided theme. However, themes are extendable by the user of that theme, allowing minor changes like color choices, but also the power to completely override rendering of specific components if necessary.

module Theme : sig ... end
module type Enum = sig ... end

Constants

Themes have a set of associated constants, which can be accessed by the functions in this section. These constants may be overritten by calling Theme.override_constants_temporarily.

module Constants : sig ... end
val constants : Theme.t -> Constants.t

A getter for the constants in a theme.

module Color := Css_gen.Color
module Fg_bg : sig ... end
module Intent : sig ... end

An Intent.t is an indicator to the component that it should render the component differently. Usually this means incorporating the intent-colors as defined by the theme.

val primary_colors : Theme.t -> Fg_bg.t

A getter for the primary colors in a theme.

val extreme_colors : Theme.t -> Fg_bg.t

A getter for the "extreme" colors. Extreme colors mimic the primary colors, but have a higher contrast ratio.

val extreme_primary_border_color : Theme.t -> Color.t
val intent_colors : Theme.t -> Intent.t -> Fg_bg.t

A getter for the colors associated with a particular intent.

type 'a format := ('a, unit, string, Virtual_dom.Vdom.Node.t) Core.format4

Text

The text functions render a <span> of text with optional attributes. textf can be used with format syntax.

val text : ?attrs:Virtual_dom.Vdom.Attr.t list -> string -> Virtual_dom.Vdom.Node.t
val textf : ?attrs:Virtual_dom.Vdom.Attr.t list -> 'a format -> 'a
module Font_style : sig ... end
module Font_size : sig ... end
val themed_text : Theme.t -> ?attrs:Virtual_dom.Vdom.Attr.t list -> ?intent:Intent.t -> ?style:Font_style.t -> ?size:Font_size.t -> string -> Virtual_dom.Vdom.Node.t
val themed_textf : Theme.t -> ?attrs:Virtual_dom.Vdom.Attr.t list -> ?intent:Intent.t -> ?style:Font_style.t -> ?size:Font_size.t -> 'a format -> 'a

Layout

Layout helper functions are used to wrap other vdom nodes inside a container. hbox and vbox both use css "flexbox", for more, read this documentation:

https://css-tricks.com/snippets/css/a-guide-to-flexbox/

The only terminology difference between the css properties and our function arguments is that we refer to "justify-content" as "main_axis_alignment" and "align-items" as "cross_axis_alignment".

Layout helpers do not take a Theme.t as input because themes should not be able to influence a layout explicitly requested by the user.

module Flex : sig ... end
val hbox : ?attrs:Virtual_dom.Vdom.Attr.t list -> ?gap:Css_gen.Length.t -> ?main_axis_alignment:Flex.Main_axis_alignment.t -> ?cross_axis_alignment:Flex.Cross_axis_alignment.t -> ?direction:Flex.Horizontal_dir.t -> Virtual_dom.Vdom.Node.t list -> Virtual_dom.Vdom.Node.t

Builds a flexbox container for elements and lays them out horizontally.

val vbox : ?attrs:Virtual_dom.Vdom.Attr.t list -> ?gap:Css_gen.Length.t -> ?main_axis_alignment:Flex.Main_axis_alignment.t -> ?cross_axis_alignment:Flex.Cross_axis_alignment.t -> ?direction:Flex.Vertical_dir.t -> Virtual_dom.Vdom.Node.t list -> Virtual_dom.Vdom.Node.t

Builds a flexbox container for elements and lays them out vertically.

val hbox_wrap : ?attrs:Virtual_dom.Vdom.Attr.t list -> ?row_gap:Css_gen.Length.t -> ?column_gap:Css_gen.Length.t -> ?main_axis_alignment:Flex.Main_axis_alignment.t -> ?cross_axis_alignment:Flex.Cross_axis_alignment.t -> ?direction:Flex.Horizontal_dir.t -> ?align_content:Flex.Align_content.t -> Virtual_dom.Vdom.Node.t list -> Virtual_dom.Vdom.Node.t

A horizontal flexbox container whose content will wrap onto multiple rows if necessary

val vbox_wrap : ?attrs:Virtual_dom.Vdom.Attr.t list -> ?row_gap:Css_gen.Length.t -> ?column_gap:Css_gen.Length.t -> ?main_axis_alignment:Flex.Main_axis_alignment.t -> ?cross_axis_alignment:Flex.Cross_axis_alignment.t -> ?direction:Flex.Vertical_dir.t -> ?align_content:Flex.Align_content.t -> Virtual_dom.Vdom.Node.t list -> Virtual_dom.Vdom.Node.t

A vertical flexbox container whose content will wrap onto multiple columns if necessary

Interactive Elements

These node constructors are for elements that the user interacts with.

val button : Theme.t -> ?attrs:Virtual_dom.Vdom.Attr.t list -> ?disabled:bool -> ?intent:Intent.t -> ?tooltip:string -> on_click:unit Virtual_dom.Vdom.Effect.t -> string -> Virtual_dom.Vdom.Node.t

Builds a basic button with text for a label.

Optional and named arguments:

  • attr, if provided, will be attached to the topmost button element.
  • disabled defaults to false. If provided (and set to true), the button will be marked as disabled and will be unclickable.
  • intent is used by the theme to color and style the button to indicate the intent of the button.
  • tooltip is used to display some text near the button when hovered.
  • on_click contains an effect to schedule when the button is clicked

The unnamed string parameter is used as the label for the button

val button' : Theme.t -> ?attrs:Virtual_dom.Vdom.Attr.t list -> ?disabled:bool -> ?intent:Intent.t -> ?tooltip:string -> on_click:unit Virtual_dom.Vdom.Effect.t -> Virtual_dom.Vdom.Node.t list -> Virtual_dom.Vdom.Node.t

Same as button but the contents of the button are specified as a list of vdom nodes instead of as a string

module Tooltip_direction : sig ... end
val tooltip : Theme.t -> ?container_attr:Virtual_dom.Vdom.Attr.t -> ?tooltip_attr:Virtual_dom.Vdom.Attr.t -> ?direction:Tooltip_direction.t -> tooltip:string -> string -> Virtual_dom.Vdom.Node.t

Tooltips can be used to provide more information to a user when they hover over an element.

tooltip' is just like tooltip except that it allows both the tooltip and the wrapped element to be arbitrary vdom nodes instead of just string

val tabs : Theme.t -> ?attrs:Virtual_dom.Vdom.Attr.t list -> ?per_tab_attr:('a -> is_active:bool -> Virtual_dom.Vdom.Attr.t) -> equal:('a -> 'a -> bool) -> on_change:(from:'a -> to_:'a -> unit Virtual_dom.Vdom.Effect.t) -> active:'a -> ('a * Virtual_dom.Vdom.Node.t) list -> Virtual_dom.Vdom.Node.t

Builds a horizontally-aligned grouping of tabs, keyed on an item representing the tab, with one of those items serving to indicate the currently active tab.

val tabs_enum : Theme.t -> ?attrs:Virtual_dom.Vdom.Attr.t list -> ?per_tab_attr:('a -> is_active:bool -> Virtual_dom.Vdom.Attr.t) -> ?tab_to_vdom:('a -> Virtual_dom.Vdom.Node.t) -> (module Enum with type t = 'a) -> on_change:(from:'a -> to_:'a -> unit Virtual_dom.Vdom.Effect.t) -> active:'a -> Virtual_dom.Vdom.Node.t

A helper function for tabs where the items representing the tabs are enumerable

val devbar : Theme.t -> ?attrs:Virtual_dom.Vdom.Attr.t list -> ?count:int -> ?intent:Intent.t -> string -> Virtual_dom.Vdom.Node.t

A devbar is the attention-catching bar across the top of an app to indicate that the user isn't on a production instance of the application.

module Card_title_kind : sig ... end
val card : Theme.t -> ?container_attr:Virtual_dom.Vdom.Attr.t -> ?title_attr:Virtual_dom.Vdom.Attr.t -> ?content_attr:Virtual_dom.Vdom.Attr.t -> ?intent:Intent.t -> ?title:string -> ?title_kind:Constants.Card_title_kind.t -> ?on_click:unit Virtual_dom.Vdom.Effect.t -> string -> Virtual_dom.Vdom.Node.t

A "card" is a way of highlighting important messages, and to also bring some structure/sense of hierarchy to your app. This component is the conceptual equivalent of "paper" in other UI component frameworks/toolkits.

val card' : Theme.t -> ?container_attr:Virtual_dom.Vdom.Attr.t -> ?title_attr:Virtual_dom.Vdom.Attr.t -> ?content_attr:Virtual_dom.Vdom.Attr.t -> ?intent:Intent.t -> ?title:Virtual_dom.Vdom.Node.t list -> ?title_kind:Constants.Card_title_kind.t -> ?on_click:unit Virtual_dom.Vdom.Effect.t -> Virtual_dom.Vdom.Node.t list -> Virtual_dom.Vdom.Node.t
module Table : sig ... end

A module for building tables

module For_components : sig ... end
module App : sig ... end
module Expert : sig ... end
module Raw : sig ... end

The Raw module contains helper functions for building vdom nodes that have styling pulled from a theme, but rely on the user to properly structure and organize the nodes manually. You probably shouldn't use these APIs if the standard functions are sufficient

OCaml

Innovation. Community. Security.