rabbit-tea

TEA web UI framework for MoonBit

TEA
html
UI
web
moon add Yoorkin/rabbit-tea@0.10.11
Download zip
Author
Version
0.10.11
License
Apache-2.0
Last updated
8 months ago
Downloads
4K

Dependencies

README

#Rabbit-TEA

A declarative and functional web UI framework inspired by The Elm Architecture.

#Features

  • Refactor Safety

    By leveraging pattern matching and tagged union, exhaustive checks provide a better refactoring experience. MoonBit helps prevent common runtime errors ensuring more robust and reliable code.

  • Maintainable State

    The state is globally managed, making it easier to maintain the entire application. By utilizing persistent data structures from moonbitlang/core/immut, you can implement advanced features such as undo/redo functionality with ease.

  • Lightweight Runtime

    The generated JavaScript file is 33KB after minified for a project like src/example/counter, including the virtual DOM.

#Basic Example

typealias Int as Model
let model = 0

enum Msg {
Increment
Decrement
}

fn update(msg : Msg, model : Model) -> (Cmd[Msg], Model) {
match msg {
Increment => (none(), model + 1)
Decrement => (none(), model - 1)
}
}

fn view(model : Model) -> Html[Msg] {
div([
h1([text(model.to_string())]),
button(click=Increment, [text("+")]),
button(click=Decrement, [text("-")]),
])
}

fn main {
@tea.startup(model~, update~, view~)
}

For more examples, see rabbit-tea-examples.

#Getting started

To get started, you can use the Rabbit-TEA template.

It also includes instructions for debugging your code with Rabbit-TEA.

#
Cmd

The command type, represents a task that can be executed.

You can define your own command to interoperate Rabbit-Tea with the outside JS world.

Before implementing your own command, check the existing commands in the nav and http packages.

Example

fn delay[M](msg : M, ms : Int) -> Cmd[M] {
Cmd(events => {
set_timeout(() => { events.trigger_update(msg) }, ms)
})
}

extern "js" fn set_timeout(f : () -> Unit, ms : Int) = "(f,ms) => setTimeout(f, ms)"

#
App

type App[Msg, Model]

#
App::dispatch

fn[Msg, Model] App::dispatch(self : App[Msg, Model], msg : Msg) -> Unit

run the update function of the application.

#
application

fn[Model, Msg] application(initialize~ : (
Url
) -> (
Cmd
[Msg], Model), update~ : (Msg, Model) -> (
Cmd
[Msg], Model), view~ : (Model) ->
Html
[Msg], url_changed? : (
Url
) -> Msg, url_request? : (
UrlRequest
) -> Msg, mount? : String) -> Unit

Start the application with initial URL.

  • url_changed is a message that will be passed when the URL is changed by the navigation API in the @browser package.
  • url_request is a message that will be passed when an <a> tag is clicked.
  • initialize will be called when the application is started.

#
attempt

fn[A, E : Error, M] attempt(msg : (Result[A, E]) -> M, f : async () -> A raise E) ->
Cmd
[M]

Create a command that runs an async function and handles errors.

This is similar to perform, but it converts the returned value or thrown error into a Result.

#
batch

Create a command that runs multiple commands.

#
new

fn[Model, Message] new(model~ : Model, update~ : (Message, Model) -> (
Cmd
[Message], Model), view~ : (Model) ->
Html
[Message], mount? : String) -> App[Message, Model]

Start the application.

  • model is the state of your application.
  • view is a way to turn your model into HTML.
  • update a way to update your state based on messages.

These three are the core of the TEA. Rabbit-TEA is highly unstable at this time, but it follows the same pattern as Elm. You can visit https://guide.elm-lang.org/ to get more intuition!

To start the application with router, you can use the application function.

#
new_with_route

fn[Model, Msg] new_with_route(initialize~ : (
Url
) -> (
Cmd
[Msg], Model), update~ : (Msg, Model) -> (
Cmd
[Msg], Model), view~ : (Model) ->
Html
[Msg], url_changed? : (
Url
) -> Msg, url_request? : (
UrlRequest
) -> Msg, mount? : String) -> App[Msg, Model]

#
none

Create a command that does nothing.

#
perform

fn[A, M] perform(msg : (A) -> M, f : async () -> A noraise) ->
Cmd
[M]

Create a command that runs an async function.

The async function f will be called, and the result will be wrapped in a message msg, then trigger another update with this message.

#
startup

fn[Model, Message] startup(model~ : Model, update~ : (Message, Model) -> (
Cmd
[Message], Model), view~ : (Model) ->
Html
[Message], mount? : String) -> Unit

Start the application.

  • model is the state of your application.
  • view is a way to turn your model into HTML.
  • update a way to update your state based on messages.

These three are the core of the TEA. Rabbit-TEA is highly unstable at this time, but it follows the same pattern as Elm. You can visit https://guide.elm-lang.org/ to get more intuition!

To start the application with router, you can use the application function.

#
task

fn[M] task(message : M) ->
Cmd
[M]

Create a command that trigger another update for the given message.

Source Files

Powered by MoonBit

Site sourceReport issuePackagesBuild queueSkillsStatistics

© 2026 mooncakes.io