Crate webatui

Source
Expand description

Run your TUI apps in the browser!

Webatui is a glue crate for running Ratatui-based TUI apps in the broswer with the help of Yew. Currently, this crate is centered around transforming the text-based displays that ratatui generates into HTML DOM-elements. Some interactivity is supported, like hyperlinks, on-click callbacks, and scrolling (both on mobile devices and with a mouse); however, webatui is not a fully interactive terminal yet. Many things, such as cursor location, editing text, etc, are not supported. Other things, like getting keyboard inputs, are possible via the web-sys crate, but there is no direct ability to setup and configure this, yet.

Many of the web-specific details have been abstracted away so that porting existing apps is as easy as possible. To get started, create a struct that will hold your app’s logic, implement the TerminalApp trait for it, and run the run_tui function with an instance of your app.

use ratatui::{prelude::*, widgets::*};
use webatui::prelude::*;

#[derive(PartialEq, Clone)]
struct MyApp {
  title: String,
}

impl TerminalApp for MyApp {
    // This simple app does not update
    type Message = ();

    // This simple app does not update
    fn update(&mut self, _: TermContext<'_, Self>, _: Self::Message) -> bool { false }

    fn render(&self, area: Rect, frame: &mut Frame<'_>) {
        let para = Paragraph::new(self.title.as_str());
        frame.render_widget(para, area);
    }
}

let my_app = MyApp { title: "Hello WWW!".into() };
run_tui(my_app)

Webatui closely follows Yew’s flow for creating and rendering an app. Once create, an app can be updated via a message (which might be generated by a callback). After the app processes its update, it returns whether or not it needs to be re-rendered. The rendering process is split into two sub-steps (the main difference between webataui and yew). In the first step, the app renders widgets into the Terminal. Once rendered and flushed, the YewBackend converts the text into a series of spans. These spans are then used during the next sub-step, hydration. Hydration allows an app to attach additional data that can’t be passed via a widget, namely callbacks and hyperlinks. To mark a stylible element as “in need of hydration”, add the HYDRATION modifier to its style or use the to_hydrate method available via the NeedsHydration trait. Once all the necessary spans have been hydrated, those spans are composed into a series of HTML <pre> tags and rendered into the DOM.

A note about hydration: When a widget is rendered, the YewBackend gets it character-by-character. This limits the backend’s ability to create blocks that need hydrated. So, a multi-line widget will be split into a series of dehydrated spans that will be hydrated individually.

Modules§

backend
Contains the terminal backend that transforms the text rendered from ratatui widgets into HTML.
prelude
Common includes needed when working with this crate.

Structs§

TermContext
A wrapper around Yew’s Context that is passed to methods like TerminalApp::update.
WebTermProps
In the public API because of the component impl of WebTerminal
WebTerminal
A container for a TUI app that renders to HTML.

Enums§

ScrollMotion
The direction that a user has scrolled
WebTermMessage
The message type generated by callbacks and sent to the WebTerminal.

Traits§

TerminalApp
The core user-facing abstraction of this crate. A terminal app is a type that can be wrapped by a WebTerminal and be displayed by Yew.

Functions§

run_tui
Launches the rendering process using the given app state.