Sign in

    preact

    Type-safe MoonBit bindings for Preact with virtual DOM, hooks, and CSS-in-JS support (early experimental)

    preact
    binding
    Download zip
    Author
    Version
    0.0.1-a1
    License
    Apache-2.0
    Last updated
    last year
    Downloads
    41

    #tiye/preact

    MoonBit bindings for Preact

    ⚠️ Early Development Warning: This library is in a very early stage of development. The API is unstable and may change frequently. This is a hobby project and should not be used in production environments.

    #Quick Start

    Here's a simple example of how to use this library:

    // 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")
    }

    #Features

    • Type-safe virtual DOM construction
    • React-style hooks (useState)
    • CSS-in-JS styling support
    • Event handling
    • Component composition

    #Project Status

    This is an experimental hobby project exploring MoonBit bindings for Preact. The API is subject to frequent changes and breaking updates. Use at your own risk!

    #License

    Apache 2.0

    CastJsValueTrait

    pub(open) trait CastJsValueTrait {
    to_js_value(Self) -> JsValue = _
    }

    JsValueTrait

    pub(open) trait JsValueTrait {
    to_value(Self) -> JsValue
    from_value(JsValue) -> Self
    }

    impl JsValueTrait for Int

    StateValue

    pub trait StateValue {
    to_value(Self) -> JsValue
    from_value(JsValue) -> Self
    }

    impl StateValue for Int
    impl StateValue for Float

    DOMEvent

    pub type DOMEvent

    DOMEvent::to_js_any_value

    fn DOMEvent::to_js_any_value(self : DOMEvent) -> JsValue

    ElementAttrs

    pub type ElementAttrs Map[String, String]

    ElementAttrs::add

    fn ElementAttrs::add(self : ElementAttrs, key : String, value : String) -> ElementAttrs

    ElementAttrs::inner

    #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]
    Convert newtype to its underlying type, automatically derived.

    ElementAttrs::new

    ElementAttrs::set

    fn ElementAttrs::set(self : ElementAttrs, key : String, value : String) -> Unit

    ElementEvents

    type ElementEvents

    ElementEvents::add

    fn ElementEvents::add(self : ElementEvents, key : String, value : (DOMEvent) -> Unit) -> ElementEvents

    ElementEvents::new

    ElementEvents::set

    fn ElementEvents::set(self : ElementEvents, key : String, value : (DOMEvent) -> Unit) -> Unit

    ElementEvents::to_js_value

    fn ElementEvents::to_js_value(self : ElementEvents) -> JsValue

    JsArray

    pub type JsArray

    JsArray::as_value

    fn JsArray::as_value(self : JsArray) -> JsValue

    JsArray::new

    fn JsArray::new() -> JsArray

    JsArray::op_get

    fn JsArray::op_get(self : JsArray, index : Int) -> JsValue

    JsArray::op_set

    fn JsArray::op_set(self : JsArray, index : Int, value : JsValue) -> Unit

    JsArray::to_string

    fn JsArray::to_string(self : JsArray) -> String

    JsObject

    type JsObject

    JsObject::as_value

    fn JsObject::as_value(self : JsObject) -> JsValue

    Converts a JavaScript object to a JavaScript value.

    Parameters:

    • self : The JavaScript object to convert.

    Returns a JsValue representing the same object.

    Example:

    let obj = @tiye/preact.JsObject::new()
    let _value = obj.as_value()

    JsObject::get

    fn JsObject::get(self : JsObject, key : String) -> JsValue

    JsObject::new

    fn JsObject::new() -> JsObject

    JsValue

    type JsValue

    JsValue::from_object

    fn JsValue::from_object(value : JsObject) -> JsValue

    VirtualElement

    pub struct VirtualElement {
    name : String
    attrs : ElementAttrs
    event : ElementEvents
    style :
    RespoStyle

    children : Array[VirtualNode]
    }

    Represents a virtual DOM element with all its properties and children.

    This structure encapsulates all the information needed to create and manage a DOM element in the virtual DOM tree, including its tag name, attributes, event handlers, styles, and child nodes.

    VirtualElement::to_node

    VirtualNode

    pub(all) enum VirtualNode {
    Element(VirtualElement)
    Fragment(Array[VirtualNode])
    Text(String)
    JsNode(JsValue)
    }

    Represents a virtual DOM node in the Preact rendering system.

    This is the core type for building virtual DOM trees. Each variant represents a different kind of node that can be rendered to the actual DOM.

    VirtualNode::to_js_value

    fn VirtualNode::to_js_value(self : VirtualNode) -> 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) -> VirtualNode

    Creates an a element with the specified attributes, event handlers, and children.

    Returns a virtual DOM node representing an a element.

    article

    fn 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) -> VirtualNode

    Creates an article element with the specified attributes, event handlers, and children.

    Returns a virtual DOM node representing an article element.

    aside

    fn 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) -> VirtualNode

    Creates an aside element with the specified attributes, event handlers, and children.

    Returns a virtual DOM node representing an aside element.

    audio

    fn 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) -> VirtualNode

    Creates an audio element with the specified attributes, event handlers, and audio properties.

    Returns a virtual DOM node representing an audio element.

    button

    fn 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) -> VirtualNode

    Creates a button element with the specified attributes, event handlers, and children.

    Returns a virtual DOM node representing a button element.

    component

    fn[T : JsValueTrait] component(f : (T) -> VirtualNode, props : T, children : Array[VirtualNode]) -> VirtualNode

    Creates a component virtual node from a function, props, and children.

    This bridges MoonBit component functions with Preact's rendering system, enabling type-safe component creation with strongly-typed props.

    Example

    struct 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 }, [])

    console_log2

    fn console_log2(msg : String, v : JsValue) -> Unit

    create_element

    fn create_element(name : String, attrs : ElementAttrs, event : ElementEvents, style~ :
    RespoStyle
    , children : Array[VirtualNode]) -> VirtualElement
    /// Creates a virtual DOM element with the specified properties.

    This is the internal implementation used by built-in element functions like div, span, etc. It can also be used to create custom HTML elements that are not provided by the library.

    Parameters

    • name: HTML tag name (e.g., "div", "span", "custom-element")
    • attrs: Element attributes
    • event: Event handlers
    • style: CSS styles
    • children: Child virtual nodes

    Example

    // Create a custom element
    let _custom_elem = create_element(
    "my-custom-element",
    ElementAttrs::new(),
    ElementEvents::new(),
    style=@css.respo_style(),
    [Text("Custom content")]
    )

    div

    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) -> VirtualNode

    fn 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) -> VirtualNode

    Creates a footer element with the specified attributes, event handlers, and children.

    Returns a virtual DOM node representing a footer element.

    fn 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) -> VirtualNode

    Creates an h1 element with the specified attributes, event handlers, and children.

    Returns a virtual DOM node representing an h1 element.

    fn 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) -> VirtualNode

    Creates an h2 element with the specified attributes, event handlers, and children.

    Returns a virtual DOM node representing an h2 element.

    fn 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) -> VirtualNode

    Creates an h3 element with the specified attributes, event handlers, and children.

    Returns a virtual DOM node representing an h3 element.

    fn 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) -> VirtualNode

    Creates an h4 element with the specified attributes, event handlers, and children.

    Returns a virtual DOM node representing an h4 element.

    fn 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) -> VirtualNode

    Creates an h5 element with the specified attributes, event handlers, and children.

    Returns a virtual DOM node representing an h5 element.

    fn 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) -> VirtualNode

    Creates an h6 element with the specified attributes, event handlers, and children.

    Returns a virtual DOM node representing an h6 element.

    fn 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) -> VirtualNode

    Creates a header element with the specified attributes, event handlers, and children.

    Returns a virtual DOM node representing a header element.

    img

    fn 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) -> VirtualNode

    Creates an img element with the specified attributes, event handlers, and image properties.

    Returns a virtual DOM node representing an img element.

    input

    fn 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) -> VirtualNode

    Creates an input element with the specified attributes, event handlers, and properties.

    Returns a virtual DOM node representing an input element.

    fn 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) -> VirtualNode

    Creates a li (list item) element with the specified attributes, event handlers, and children.

    Returns a virtual DOM node representing a li element.

    fn 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) -> VirtualNode

    Creates a nav element with the specified attributes, event handlers, and children.

    Returns a virtual DOM node representing a nav element.

    fn 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) -> VirtualNode

    Creates an ol (ordered list) element with the specified attributes, event handlers, and children.

    Returns a virtual DOM node representing an ol element.

    option

    fn 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) -> VirtualNode

    Creates an option element with the specified attributes and properties.

    Returns a virtual DOM node representing an option element.

    fn 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

    Creates a p element with the specified attributes, event handlers, and children.

    Returns a virtual DOM node representing a p element.

    render

    fn render(vdom : VirtualNode, parent :
    Element
    ) -> Unit

    Renders a virtual DOM node to the specified parent element.

    This function takes a virtual DOM node and a parent DOM element, then uses the Preact rendering engine to render the virtual node as a real DOM element within the parent.

    Parameters

    • vdom: The virtual DOM node to render.
    • parent: The parent DOM element where the rendered node will be appended.

    Example

    // 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)

    section

    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) -> VirtualNode

    Creates a section element with the specified attributes, event handlers, and children.

    Returns a virtual DOM node representing a section element.

    select

    fn 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) -> VirtualNode

    Creates a select element with the specified attributes, event handlers, and children.

    Returns a virtual DOM node representing a select element.

    span

    fn 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) -> VirtualNode

    Creates a span element with the specified attributes, event handlers, and children.

    Returns a virtual DOM node representing a span element.

    Example:

    let _ = span(
    class_name="text-bold",
    on_click=fn(_e) { println("Clicked!") }, []
    )

    textarea

    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) -> VirtualNode

    Creates a textarea element with the specified attributes, event handlers, and properties.

    Returns a virtual DOM node representing a textarea element.

    fn 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) -> VirtualNode

    Creates a ul (unordered list) element with the specified attributes, event handlers, and children.

    Returns a virtual DOM node representing a ul element.

    use_state

    fn[T : StateValue] use_state(initial : T) -> (T, (T) -> Unit)

    video

    fn 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) -> VirtualNode

    Creates a video element with the specified attributes, event handlers, and video properties.

    Returns a virtual DOM node representing a video element.