Skip to content

Component

The @std/component module is used for HTML-style components.

It provides component context support for functions that return html.

import { Context } from "@std/component"
fn Button(ctx: Context) html {
return <button>!{ ctx.children.join(" ") }</button>
}

Import Context from @std/component.

import { Context } from "@std/component"

Context is passed to component functions and gives access to component data such as children and bound attributes.

A component is a function that takes a Context and returns html.

import { Context } from "@std/component"
fn Button(ctx: Context) html {
return <button>Click me</button>
}

Function implementations use the return type after the parameter list.

fn Button(ctx: Context) html {
return <button>Button</button>
}

Use -> only when describing a function value type.

let renderer: fn(Context) -> html

Nubo supports HTML values directly in code.

let title = <h1>Hello, World</h1>
println(title)

HTML values can contain nested elements.

let page = <main>
<h1>Hello</h1>
<p>Welcome to Nubo</p>
</main>

Use !{ ... } to interpolate Nubo expressions into HTML.

let name = "Martin"
let heading = <h1>Hello, !{ name }</h1>

Inside a component, interpolation is often used with ctx.children.

import { Context } from "@std/component"
fn Button(ctx: Context) html {
return <button>!{ ctx.children.join(" ") }</button>
}

Use a component with JSX-like syntax.

import { Context } from "@std/component"
fn Button(ctx: Context) html {
return <button>!{ ctx.children.join(" ") }</button>
}
let btn = <Button>Hello</Button>
println(btn)

Components can contain nested HTML children.

import { Context } from "@std/component"
fn Button(ctx: Context) html {
return <button>!{ ctx.children.join(" ") }</button>
}
let btn = <Button><span>Hello, World</span>!</Button>

Use :name="value" to bind a Nubo value as an attribute.

let btn = <button :idn="45">Click</button>

You can also bind a dictionary of attributes with :bind-attrs.

import { Context } from "@std/component"
fn Button(ctx: Context) html {
return <button>!{ ctx.children.join(" ") }</button>
}
let btn = <Button :bind-attrs="{a:'b'}">
<span>Hello, World</span>!
</Button>

HTML values can be accessed like dictionary-like objects.

let btn = <button :idn="45">Click</button>
println(btn["idn"])

Set an attribute by assigning to an index.

let btn = <button :idn="45">Click</button>
btn["ID"] = "new_id"
println(btn["idn"])

Call children() to read the children of an HTML value.

let btn = <button><span>Hello</span>!</button>
println(btn.children())

Children can be strings or html values.

const ch: [](html|string) = []
ch.push("#")
ch.push(<span>Hello, Other</span>)

Use setChildren to replace the children of an HTML value.

let btn = <button>Hello</button>
const ch: [](html|string) = []
ch.push("#")
ch.push(<span>Hello, Other</span>)
btn.setChildren(ch)
println(btn.children())
import { Context } from "@std/component"
fn Button(ctx: Context) html {
println(ctx)
return <button :idn="45">!{ ctx.children.join(" ") }</button>
}
let btn = <Button :bind-attrs="{a:'b'}">
<span>Hello, World</span>!
</Button>
btn["ID"] = "new_id"
println(btn["idn"])
println(btn.children())
const ch: [](html|string) = []
ch.push("#")
ch.push(<span>Hello, Other</span>)
btn.setChildren(ch)
println(btn.children())
FeatureExample
Import contextimport { Context } from "@std/component"
Component functionfn Button(ctx: Context) html { ... }
HTML value<button>Hello</button>
Interpolation!{ value }
Bound attribute<button :idn="45">
Bind attrs dictionary<Button :bind-attrs="{a:'b'}">
Read attributebtn["idn"]
Set attributebtn["ID"] = "new_id"
Read childrenbtn.children()
Replace childrenbtn.setChildren(ch)