moonetui

    A terminal UI toolkit for MoonBit: cell buffer, differential ANSI renderer, incremental key parser, layout, a CSS-like design system, fifty-four widgets, and drivers for terminals, Node, browsers and serial lines.

    tui
    terminal
    terminal-ui
    tui-framework
    cli
    console
    widget
    widgets
    dashboard
    form
    table
    tree
    chart
    slider
    calendar
    pagination
    command-palette
    diff
    hex-dump
    ansi
    truecolor
    escape-sequences
    unicode
    layout
    css
    design-system
    node
    browser
    wasm
    serial
    moonbit
    Download zip
    Version
    0.3.6
    License
    Apache-2.0
    Last updated
    3 hours ago
    Downloads
    98

    #MoonBit Easy Terminal UI Frame

    moonetui · a terminal UI toolkit for MoonBit

    Cell buffer · differential ANSI renderer · incremental key parser · layout · CSS-like design system · 54 widgets · drivers for terminals, Node, browsers and serial lines

    Check and Test Docs mooncakes licence

    #Highlights

    Synchronous coreNo async and no hidden event loop. The host calls one step(): poll, parse, dispatch, lay out, compose, diff, write.
    Differential rendererTwo frames become the spans that changed, and only the escape sequences needed to draw them.
    A CSS-like design systemSelectors over name, id, class and :focus, :hover, :disabled, stacked by specificity and cascade, with inheritance, borders, padding, margins, docks, grid spans and transitions.
    Unicode-awareEvery line is measured in terminal columns over a generated width table: wide CJK, double-width emoji, combining marks.
    Four backendsThe same code and the same test suite on wasm, wasm-gc, js and native.
    Any wireA modern terminal with true colour, a serial-era terminal with eight colours, a browser canvas, or a bare UART with no cursor addressing at all.

    #Quick start

    moon add moonbitstack/moonetui

    moon run --target native src/examples/gallery # every widget and every style, live moon run --target native src/examples/monitor # a complete app: tabs, timers, a command line moon run --target native src/examples/tui # a styled app in a real terminal moon run --target js src/examples/hello # under Node moon run --target native src/examples/uart # whole frames of plain text, as a serial line gets them

    The gallery runs in a browser too: moon build --target js, serve the repository root, and open src/examples/browser/index.html.

    A first application: a list, a field, and a stylesheet that frames the list and thickens the frame while it has focus. It runs on a terminal, so the block below is native only.

    fn main raise {
    let sheet = @design.Stylesheet::new()
    sheet.add(
    @design.Sel::new(name="Header"),
    @design.Styles::new(text=@style.Style::new(bold=true, fg=@style.cyan)),
    )
    sheet.add(@design.Sel::new(classes=["framed"]), @design.Styles::new(border=Round))
    sheet.add(
    @design.Sel::new(classes=["framed"], focus=true),
    @design.Styles::new(border=Heavy),
    )
    let list = @widget.ListView::new(["alpha", "beta", "gamma"])
    let field = @widget.Input::new(placeholder="pick one")
    let line = @layout.Box::new(extent=Cells(1))
    let tree = @app.column(0, [
    @app.leaf(1, @widget.Header::new("moonetui"), box=line, name="Header"),
    @app.leaf(2, list, classes=["framed"]),
    @app.leaf(3, field, box=line),
    @app.leaf(4, @widget.Footer::new([("tab", "next"), ("enter", "choose")]), box=line),
    ])
    let ui = @app.App::new(@native.NativeTty::new(), tree, sheet~)
    ui.start()
    @native.run(() => {
    let alive = ui.step()
    for report in ui.drain() {
    if report is Selected(index~, ..) {
    field.set(list.items()[index])
    ui.refresh()
    }
    }
    alive
    })
    ui.stop()
    }

    Its moon.pkg imports app, design, driver/native, layout, style and widget from moonbitstack/moonetui, and declares supported_targets = "native".

    #The widget inventory

    GroupWidgets
    Text and displayStatic and label(), Header (with a Clock), Footer, Rule, Digits, Sparkline, Progress, LoadingIndicator, Placeholder, Pretty, Link, KeyPanel
    Entry and logsInput, TextArea, Log, RichLog, MaskedInput
    ChoicesSwitch, Checkbox, RadioButton, RadioSet, OptionList, SelectionList, Select, Slider, Calendar
    Navigation and structureButton, ListView, Paginator, Tabs, TabbedContent, Collapsible, Tree, DirectoryTree, ContentSwitcher, StatefulList, StatefulTable
    Data and noticesDataTable, HexView, Diff, Markdown, Tooltip, Toast
    DialogsMessageBox, InputBox, FileDialog
    Menus and commandsMenu, MenuBar, CommandPalette
    Charts and metersChart (lines and scatter), BarChart, Gauge, Scrollbar
    DecorationBlock — a frame, title and padding that wraps any widget

    Each one has its keyboard contract, message shape and tests, and a live demo on the documentation site beside its source.

    #Package map

    PackageWhat it does
    @geomInteger rectangle algebra: Offset, Size, Region, Spacing
    @styleColours (named, indexed, true colour), attributes, palette quantisation, differential SGR
    @stripOne rendered line: styled segments measured in terminal columns
    @eventKeys, mouse reports, paste, resize and focus as plain values
    @inputThe terminal byte stream turned into events
    @compThe compositor: placements to rows, rows to changed spans, spans to escape sequences
    @driverThe seam to a terminal, and a headless terminal for tests
    @vtA virtual terminal: the screen an escape stream draws, for the browser driver, tests and screenshots
    @layoutSizes along an axis, the grid with spans and gutters, and anchored, pivoted placement
    @designRules over name, id, class and state; borders, padding, margins, alignment, docks, offsets, transitions, and the semantic Theme
    @widgetThe widget contract and the inventory
    @appThe widget tree, focus ring, scroll containers, docks, grids, screens, timers and the frame loop
    @driver/native · @driver/node · @driver/webA real terminal through the C library; Node; a canvas in the browser

    #Standards

    • Unicode: rendering is measured in terminal columns over a generated width table.
    • ECMA-48 / ISO 6429: SGR (CSI … m) for attributes, CUP (CSI H) for addressing, ED and EL for erasing.
    • UTF-8: the input decoder is incremental, so a code point split across two reads arrives whole.

    #Tests

    moon check --target all --deny-warn moon build --target all moon test --target all moon fmt && moon info --target all # the diff must stay clean

    653 tests per backend, the same suite on wasm, wasm-gc, js and native, run on Ubuntu, macOS and Windows in CI. Every widget asserts the rows it draws, and every demo draws in a headless application.

    #Licence

    Apache-2.0. See LICENSE.