Type-safe MoonBit bindings for Preact with virtual DOM, hooks, and CSS-in-JS support (early experimental)
MoonBit bindings for Preact
// Define your component props
struct ContainerProps {} derive(Default)
// Implement JsValueTrait for props
impl @preact.JsValueTrait for ContainerProps with to_value(_self) -> @preact.JsValue {
@preact.JsObject::new().to_value()
}
impl @preact.JsValueTrait for ContainerProps with from_value(
_value : @preact.JsValue,
) -> ContainerProps {
ContainerProps::default()
}
// Create a functional component
fn comp_container(_v : ContainerProps) -> @preact.VirtualNode {
let (counter, set_counter) = @preact.use_state(0.0.to_float())
@preact.div(
id="container",
style=@css.respo_style(
color=Blue,
font_family="Arial",
padding=10.0 |> Px
),
on_click=fn(_) {
println("clicked \{counter}")
set_counter(counter + 1.0)
},
[
@preact.Fragment([Text("Demo: ")]),
Text("Counter \{counter}")
],
)
}
// Render to DOM
fn main {
let window = @dom.window()
let doc = window.document()
let body = doc.body()
let props = ContainerProps::default()
@preact.render(
@preact.component(comp_container, props, []),
body,
)
println("loaded")
}pub type DOMEventimpl Default for ElementAttrs#deprecated("Use `struct T(A)` to declare a newtype and use `.0` access the underlying type instead.")
fn ElementAttrs::inner(self : ElementAttrs) -> Map[String, String]type ElementEventsimpl Default for ElementEventsfn ElementEvents::add(self : ElementEvents, key : String, value : (DOMEvent) -> Unit) -> ElementEventstype JsObjectimpl JsValueTrait for JsObjectlet obj = @tiye/preact.JsObject::new()
let _value = obj.as_value()type JsValuepub struct VirtualElement {
name : String
attrs : ElementAttrs
event : ElementEvents
style : RespoStyle
children : Array[VirtualNode]
}pub(all) enum VirtualNode {
Element(VirtualElement)
Fragment(Array[VirtualNode])
Text(String)
JsNode(JsValue)
}fn a(id? : String, class_name? : String, class_list? : Array[String], attrs? : ElementAttrs, event? : ElementEvents, style? : RespoStyle, children : Array[VirtualNode], innerHTML? : String, href? : String, target? : String, on_click? : (DOMEvent) -> Unit) -> VirtualNodefn article(id? : String, class_name? : String, class_list? : Array[String], attrs? : ElementAttrs, event? : ElementEvents, style? : RespoStyle, children : Array[VirtualNode], innerHTML? : String, on_click? : (DOMEvent) -> Unit) -> VirtualNodefn aside(id? : String, class_name? : String, class_list? : Array[String], attrs? : ElementAttrs, event? : ElementEvents, style? : RespoStyle, children : Array[VirtualNode], innerHTML? : String, on_click? : (DOMEvent) -> Unit) -> VirtualNodefn audio(id? : String, class_name? : String, class_list? : Array[String], attrs? : ElementAttrs, event? : ElementEvents, style? : RespoStyle, children : Array[VirtualNode], src? : String, controls? : Bool, autoplay? : Bool, loop_enabled? : Bool, muted? : Bool, on_play? : (DOMEvent) -> Unit, on_pause? : (DOMEvent) -> Unit) -> VirtualNodefn button(id? : String, class_name? : String, class_list? : Array[String], attrs? : ElementAttrs, event? : ElementEvents, style? : RespoStyle, children : Array[VirtualNode], innerHTML? : String, button_type? : String, disabled? : Bool, on_click? : (DOMEvent) -> Unit) -> VirtualNodefn[T : JsValueTrait] component(f : (T) -> VirtualNode, props : T, children : Array[VirtualNode]) -> VirtualNodestruct ButtonProps {
text : String
disabled : Bool
} derive(Default)
fn my_button(props : ButtonProps) -> VirtualNode {
button(disabled=props.disabled, [Text(props.text)])
}
let node = component(my_button, ButtonProps { text: "Click me", disabled: false }, [])fn create_element(name : String, attrs : ElementAttrs, event : ElementEvents, style~ : RespoStyle, children : Array[VirtualNode]) -> VirtualElement// Create a custom element
let _custom_elem = create_element(
"my-custom-element",
ElementAttrs::new(),
ElementEvents::new(),
style=@css.respo_style(),
[Text("Custom content")]
)fn div(id? : String, class_name? : String, class_list? : Array[String], attrs? : ElementAttrs, event? : ElementEvents, style? : RespoStyle, children : Array[VirtualNode], innerHTML? : String, on_click? : (DOMEvent) -> Unit) -> VirtualNodefn footer(id? : String, class_name? : String, class_list? : Array[String], attrs? : ElementAttrs, event? : ElementEvents, style? : RespoStyle, children : Array[VirtualNode], innerHTML? : String, on_click? : (DOMEvent) -> Unit) -> VirtualNodefn h1(id? : String, class_name? : String, class_list? : Array[String], attrs? : ElementAttrs, event? : ElementEvents, style? : RespoStyle, children : Array[VirtualNode], innerHTML? : String, on_click? : (DOMEvent) -> Unit) -> VirtualNodefn h2(id? : String, class_name? : String, class_list? : Array[String], attrs? : ElementAttrs, event? : ElementEvents, style? : RespoStyle, children : Array[VirtualNode], innerHTML? : String, on_click? : (DOMEvent) -> Unit) -> VirtualNodefn h3(id? : String, class_name? : String, class_list? : Array[String], attrs? : ElementAttrs, event? : ElementEvents, style? : RespoStyle, children : Array[VirtualNode], innerHTML? : String, on_click? : (DOMEvent) -> Unit) -> VirtualNodefn h4(id? : String, class_name? : String, class_list? : Array[String], attrs? : ElementAttrs, event? : ElementEvents, style? : RespoStyle, children : Array[VirtualNode], innerHTML? : String, on_click? : (DOMEvent) -> Unit) -> VirtualNodefn h5(id? : String, class_name? : String, class_list? : Array[String], attrs? : ElementAttrs, event? : ElementEvents, style? : RespoStyle, children : Array[VirtualNode], innerHTML? : String, on_click? : (DOMEvent) -> Unit) -> VirtualNodefn h6(id? : String, class_name? : String, class_list? : Array[String], attrs? : ElementAttrs, event? : ElementEvents, style? : RespoStyle, children : Array[VirtualNode], innerHTML? : String, on_click? : (DOMEvent) -> Unit) -> VirtualNodefn header(id? : String, class_name? : String, class_list? : Array[String], attrs? : ElementAttrs, event? : ElementEvents, style? : RespoStyle, children : Array[VirtualNode], innerHTML? : String, on_click? : (DOMEvent) -> Unit) -> VirtualNodefn img(id? : String, class_name? : String, class_list? : Array[String], attrs? : ElementAttrs, event? : ElementEvents, style? : RespoStyle, src? : String, alt? : String, width? : String, height? : String, on_click? : (DOMEvent) -> Unit, on_load? : (DOMEvent) -> Unit, on_error? : (DOMEvent) -> Unit) -> VirtualNodefn input(id? : String, class_name? : String, class_list? : Array[String], attrs? : ElementAttrs, event? : ElementEvents, style? : RespoStyle, input_type? : String, value? : String, placeholder? : String, disabled? : Bool, on_click? : (DOMEvent) -> Unit, on_change? : (DOMEvent) -> Unit, on_input? : (DOMEvent) -> Unit) -> VirtualNodefn li(id? : String, class_name? : String, class_list? : Array[String], attrs? : ElementAttrs, event? : ElementEvents, style? : RespoStyle, children : Array[VirtualNode], innerHTML? : String, on_click? : (DOMEvent) -> Unit) -> VirtualNodefn nav(id? : String, class_name? : String, class_list? : Array[String], attrs? : ElementAttrs, event? : ElementEvents, style? : RespoStyle, children : Array[VirtualNode], innerHTML? : String, on_click? : (DOMEvent) -> Unit) -> VirtualNodefn ol(id? : String, class_name? : String, class_list? : Array[String], attrs? : ElementAttrs, event? : ElementEvents, style? : RespoStyle, children : Array[VirtualNode], innerHTML? : String, on_click? : (DOMEvent) -> Unit) -> VirtualNodefn option(id? : String, class_name? : String, class_list? : Array[String], attrs? : ElementAttrs, event? : ElementEvents, style? : RespoStyle, children : Array[VirtualNode], innerHTML? : String, value? : String, selected? : Bool, disabled? : Bool) -> VirtualNodefn p(id? : String, class_name? : String, class_list? : Array[String], attrs? : ElementAttrs, event? : ElementEvents, style? : RespoStyle, children : Array[VirtualNode], innerHTML? : String, on_click? : (DOMEvent) -> Unit) -> VirtualNode// Render a virtual element to the document body
let custom_elem = create_element(
"my-custom-element",
ElementAttrs::new(),
ElementEvents::new(),
style=@css.respo_style(),
[Text("Custom content")]
)
render(custom_elem.to_node(), document.body)fn section(id? : String, class_name? : String, class_list? : Array[String], attrs? : ElementAttrs, event? : ElementEvents, style? : RespoStyle, children : Array[VirtualNode], innerHTML? : String, on_click? : (DOMEvent) -> Unit) -> VirtualNodefn select(id? : String, class_name? : String, class_list? : Array[String], attrs? : ElementAttrs, event? : ElementEvents, style? : RespoStyle, children : Array[VirtualNode], value? : String, disabled? : Bool, multiple? : Bool, on_change? : (DOMEvent) -> Unit) -> VirtualNodefn span(id? : String, class_name? : String, class_list? : Array[String], attrs? : ElementAttrs, event? : ElementEvents, style? : RespoStyle, children : Array[VirtualNode], innerHTML? : String, on_click? : (DOMEvent) -> Unit) -> VirtualNodelet _ = span(
class_name="text-bold",
on_click=fn(_e) { println("Clicked!") }, []
)fn textarea(id? : String, class_name? : String, class_list? : Array[String], attrs? : ElementAttrs, event? : ElementEvents, style? : RespoStyle, value? : String, placeholder? : String, rows? : Int, cols? : Int, disabled? : Bool, on_change? : (DOMEvent) -> Unit, on_input? : (DOMEvent) -> Unit) -> VirtualNodefn ul(id? : String, class_name? : String, class_list? : Array[String], attrs? : ElementAttrs, event? : ElementEvents, style? : RespoStyle, children : Array[VirtualNode], innerHTML? : String, on_click? : (DOMEvent) -> Unit) -> VirtualNodefn video(id? : String, class_name? : String, class_list? : Array[String], attrs? : ElementAttrs, event? : ElementEvents, style? : RespoStyle, children : Array[VirtualNode], src? : String, controls? : Bool, autoplay? : Bool, loop_enabled? : Bool, muted? : Bool, width? : String, height? : String, on_click? : (DOMEvent) -> Unit, on_play? : (DOMEvent) -> Unit, on_pause? : (DOMEvent) -> Unit) -> VirtualNodeInstall
Download zipType-safe MoonBit bindings for Preact with virtual DOM, hooks, and CSS-in-JS support (early experimental)