mizchi/tui/vnode does not have a README file

    TuiAttr

    Type alias for luna Attr with TuiEvent and TuiAttrValue

    TuiHandler

    Type alias for luna EventHandler with TuiEvent

    TuiNode

    Type alias for luna Node with TuiEvent and TuiAttrValue

    A11yNode

    pub struct A11yNode {
    id : String
    role :
    Role

    name : String
    rect : A11yRect
    children : Array[A11yNode]
    } derive(
    Debug
    )

    impl Show for A11yNode

    A11yRect

    pub struct A11yRect {
    x : Int
    y : Int
    width : Int
    height : Int
    } derive(
    Debug
    )

    impl Show for A11yRect

    AlignmentValue

    pub(all) enum AlignmentValue {
    Start
    Center
    End
    Stretch
    SpaceBetween
    SpaceAround
    SpaceEvenly
    FlexStart
    FlexEnd
    }

    Alignment value

    AlignmentValue::to_alignment

    Convert to crater Alignment

    AlignmentValue::to_layout_alignment

    Convert to layout Alignment

    BorderValue

    pub(all) enum BorderValue {
    None
    Single
    Double
    Rounded
    Ascii
    }

    Border style

    BorderValue::to_border_chars

    Convert to BorderChars

    BoxProps

    pub struct BoxProps {
    id : String
    direction : DirectionValue
    width : DimensionValue
    height : DimensionValue
    min_width : DimensionValue
    min_height : DimensionValue
    flex_grow : Double
    flex_shrink : Double
    gap : Double
    padding : Double
    padding_x : Double
    padding_y : Double
    margin : Double
    margin_x : Double
    margin_y : Double
    justify : AlignmentValue?
    align : AlignmentValue?
    border : BorderValue
    border_color : ColorValue?
    bg : ColorValue?
    tab_index : Int
    role :
    Role
    ?
    }

    Box properties for type-safe construction

    BoxProps::default

    fn BoxProps::default() -> BoxProps

    BoxProps::to_attrs

    fn BoxProps::to_attrs(self : BoxProps) -> Array[TuiAttrValue]

    Convert BoxProps to typed attributes

    ColorValue

    pub(all) enum ColorValue {
    Transparent
    Named(String)
    Rgb(Int, Int, Int)
    }

    Color value

    ColorValue::to_color

    Convert to Color

    DimensionValue

    pub(all) enum DimensionValue {
    Auto
    Length(Double)
    Percent(Double)
    }

    Dimension value for layout properties

    DimensionValue::to_dimension

    Convert to crater Dimension

    DimensionValue::to_layout_dimension

    Convert to layout Dimension

    DirectionValue

    pub(all) enum DirectionValue {
    Row
    Column
    }

    Flex direction

    DirectionValue::to_flex_direction

    Convert to crater FlexDirection

    DirectionValue::to_layout_flex_direction

    Convert to layout FlexDirection

    DisplayValue

    pub(all) enum DisplayValue {
    Flex
    Grid
    }

    Display value

    DisplayValue::to_display

    Convert to crater Display

    EditConfig

    pub(all) struct EditConfig {
    field_name : String
    on_change : (String) -> Unit
    on_edit_start : () -> Unit?
    on_edit_end : () -> Unit?
    on_force_quit : () -> Unit?
    }

    Configuration for editable input behavior

    FocusContext

    pub struct FocusContext {
    elements : Array[FocusableElement]
    current_index : Int
    }

    Focus context for managing Tab navigation

    FocusContext::clear

    fn FocusContext::clear(self : FocusContext) -> Unit

    Clear all registered elements (call before re-rendering)

    FocusContext::count

    fn FocusContext::count(self : FocusContext) -> Int

    Get the number of focusable elements

    FocusContext::current_focus

    fn FocusContext::current_focus(self : FocusContext) -> String?

    Get the currently focused element id

    FocusContext::focus_by_id

    fn FocusContext::focus_by_id(self : FocusContext, id : String) -> Bool

    Set focus to a specific element by id Returns true if the element was found and focused

    FocusContext::focus_next

    fn FocusContext::focus_next(self : FocusContext) -> String?

    Move focus to the next element (Tab key) Returns the id of the newly focused element, or None if no focusable elements

    FocusContext::focus_prev

    fn FocusContext::focus_prev(self : FocusContext) -> String?

    Move focus to the previous element (Shift+Tab key) Returns the id of the newly focused element, or None if no focusable elements

    FocusContext::focusable_ids

    fn FocusContext::focusable_ids(self : FocusContext) -> Array[String]

    Get all focusable element ids in tab order

    FocusContext::is_focusable

    fn FocusContext::is_focusable(self : FocusContext, id : String) -> Bool

    Check if an element is focusable

    FocusContext::new

    Create a new focus context

    FocusContext::register

    fn FocusContext::register(self : FocusContext, id : String, tab_index : Int) -> Unit

    Register a focusable element Elements are sorted by tab_index when calculating focus order

    FocusableElement

    pub struct FocusableElement {
    id : String
    tab_index : Int
    }

    Focusable element with its tab index and element id

    GridAreaInfo

    pub(all) struct GridAreaInfo {
    column : Int
    row : Int
    column_span : Int
    row_span : Int
    }

    Grid area placement info (package-visible for render_typed.mbt)

    GridAutoFlowValue

    pub(all) enum GridAutoFlowValue {
    Row
    Column
    RowDense
    ColumnDense
    }

    Grid auto-flow value

    GridAutoFlowValue::to_grid_auto_flow

    Convert to crater GridAutoFlow

    InputState

    pub(all) enum InputState {
    Idle
    Focused
    Editing
    Disabled
    }

    Input state for visual feedback

    MouseButton

    pub(all) enum MouseButton {
    Left
    Right
    Middle
    }

    Mouse button

    OverlayEntry

    pub(all) struct OverlayEntry {
    node :
    Node
    [TuiEvent, TuiAttrValue]
    position : PopupPosition
    backdrop : Bool
    shrink : Bool
    }

    PopupPosition

    pub(all) enum PopupPosition {
    Center
    Top
    Bottom
    At(Int, Int)
    }

    RenderContext

    pub struct RenderContext {
    styles : Map[String,
    RenderStyle
    ]
    texts : Map[String, String]
    handlers : Map[String, (TuiEvent) -> Unit]
    roles : Map[String,
    Role
    ]
    id_counter : Int
    area_stack : Array[Map[String, GridAreaInfo]]
    }

    Render context holding styles and handlers

    RenderContext::new

    Create a new render context

    TextProps

    pub struct TextProps {
    content : String
    fg : ColorValue?
    bold : Bool
    underline : Bool
    role :
    Role
    ?
    }

    Text properties

    TextProps::default

    fn TextProps::default(content : String) -> TextProps

    TextProps::to_attrs

    fn TextProps::to_attrs(self : TextProps) -> Array[TuiAttrValue]

    TuiAttrValue

    pub(all) enum TuiAttrValue {
    Direction(DirectionValue)
    Width(DimensionValue)
    Height(DimensionValue)
    MinWidth(DimensionValue)
    MinHeight(DimensionValue)
    FlexGrow(Double)
    FlexShrink(Double)
    Gap(Double)
    Display(DisplayValue)
    GridTemplateColumns(Array[
    TrackSizingFunction
    ])
    GridTemplateRows(Array[
    TrackSizingFunction
    ])
    GridAutoFlow(GridAutoFlowValue)
    GridColumn(Int)
    GridRow(Int)
    GridColumnSpan(Int)
    GridRowSpan(Int)
    GridTemplateAreas(Array[String])
    GridArea(String)
    Padding(Double)
    PaddingX(Double)
    PaddingY(Double)
    Margin(Double)
    MarginX(Double)
    MarginY(Double)
    Justify(AlignmentValue)
    Align(AlignmentValue)
    Border(BorderValue)
    BorderColor(ColorValue)
    Fg(ColorValue)
    Bg(ColorValue)
    Bold(Bool)
    Underline(Bool)
    Id(String)
    TabIndex(Int)
    Role(
    Role
    )
    }

    Typed TUI attribute value Will replace String when luna supports Attr[E, A]

    TuiEvent

    pub(all) enum TuiEvent {
    Click(x~ : Int, y~ : Int, button~ : MouseButton)
    Hover(x~ : Int, y~ : Int, id~ : String)
    Key(key~ : String, modifiers~ : Int)
    }

    TUI Event - passed to event handlers

    TypedRenderContext

    pub struct TypedRenderContext {
    styles : Map[String,
    RenderStyle
    ]
    texts : Map[String, String]
    handlers : Map[String, (TuiEvent) -> Unit]
    roles : Map[String,
    Role
    ]
    id_counter : Int
    area_stack : Array[Map[String, GridAreaInfo]]
    }

    Context for typed rendering

    TypedRenderContext::new

    VNodeApp

    pub struct VNodeApp {
    width : Int
    height : Int
    prev_buffer :
    CharBuffer
    ?
    last_layout :
    Layout
    ?
    overlay_layouts : Array[
    Layout
    ]
    render_ctx : RenderContext
    }

    VNodeApp manages the vnode render loop with diff-based updates

    VNodeApp::a11y_tree

    fn VNodeApp::a11y_tree(self : VNodeApp) -> Array[A11yNode]

    Get accessibility tree from the last render.

    VNodeApp::clear_prev_buffer

    fn VNodeApp::clear_prev_buffer(self : VNodeApp) -> Unit

    Clear the previous buffer to force a full re-render on next render call

    VNodeApp::create_render_effect

    fn VNodeApp::create_render_effect(self : VNodeApp, render_fn : () ->
    Node
    [TuiEvent, TuiAttrValue], output_fn : (String) -> Unit) -> (() -> Unit)

    Create a reactive effect that re-renders when signals change Returns a dispose function

    VNodeApp::dispatch_hover

    fn VNodeApp::dispatch_hover(self : VNodeApp, event :
    MouseEvent
    ) -> String?

    Dispatch hover event - returns hovered component ID on Move/Drag events Also dispatches TuiEvent::Hover to handlers for overlay-aware hit testing

    VNodeApp::dump_a11y_tree

    fn VNodeApp::dump_a11y_tree(self : VNodeApp) -> String

    Debug: dump accessibility tree structure.

    VNodeApp::find_by_id

    fn VNodeApp::find_by_id(self : VNodeApp, id : String) ->
    HitTestResult
    ?

    Find component by ID

    VNodeApp::handle_click

    fn VNodeApp::handle_click(self : VNodeApp, event :
    MouseEvent
    ) -> String?

    Handle a mouse event using the render context's handlers Returns the clicked component ID if found and handler was invoked

    VNodeApp::hit_test

    fn VNodeApp::hit_test(self : VNodeApp, x : Int, y : Int) ->
    HitTestResult
    ?

    Perform hit test at coordinates Checks overlays first (top-most layer) before main layout

    VNodeApp::init_terminal

    fn VNodeApp::init_terminal() -> String

    Initialize terminal (enter alt screen, hide cursor)

    VNodeApp::layout_rects

    Get all layout rects from the last render (absolute coordinates).

    VNodeApp::new

    fn VNodeApp::new(width : Int, height : Int) -> VNodeApp

    VNodeApp::render

    fn VNodeApp::render(self : VNodeApp, root :
    Node
    [TuiEvent, TuiAttrValue]) -> String

    Render a vnode tree to ANSI string

    VNodeApp::render_frame

    fn VNodeApp::render_frame(self : VNodeApp, root :
    Node
    [TuiEvent, TuiAttrValue]) -> String

    Render with cursor hidden and positioned at origin

    VNodeApp::render_frame_with_overlays

    fn VNodeApp::render_frame_with_overlays(self : VNodeApp, main :
    Node
    [TuiEvent, TuiAttrValue], overlays : Array[OverlayEntry]) -> String

    Render with overlays and cursor hidden

    VNodeApp::render_with_overlays

    fn VNodeApp::render_with_overlays(self : VNodeApp, main :
    Node
    [TuiEvent, TuiAttrValue], overlays : Array[OverlayEntry]) -> String

    Render main content with overlay layers on top

    VNodeApp::resize

    fn VNodeApp::resize(self : VNodeApp, width : Int, height : Int) -> Unit

    Resize the render target and force a full redraw on next render.

    VNodeApp::restore_terminal

    fn VNodeApp::restore_terminal() -> String

    Restore terminal (show cursor, leave alt screen)

    attr

    Create a static typed attribute

    attr_dyn

    Create a dynamic typed attribute

    attr_to_string

    fn attr_to_string(attr : TuiAttrValue) -> (String, String)

    Convert TuiAttrValue to (key, value) string pair

    box_node

    Create a box node from typed props

    box_to_crater

    Convert BoxProps directly to crater node (type-safe path)

    build_a11y_tree

    fn build_a11y_tree(layout :
    Layout
    , ctx : RenderContext) -> Array[A11yNode]

    column

    fn column(id? : String, gap? : Double, margin? : Double, margin_x? : Double, margin_y? : Double, padding? : Double, padding_x? : Double, padding_y? : Double, width? : Double, height? : Double, min_width? : Double, min_height? : Double, flex_grow? : Double, justify? : String, align? : String, border? : String, border_color? : String, bg? : String, role? : String, tab_index? : Int, on_click? : (TuiEvent) -> Unit?, children : Array[
    Node
    [TuiEvent, TuiAttrValue]]) ->
    Node
    [TuiEvent, TuiAttrValue]

    Column container (vertical flex)

    component

    Component boundary

    dump_a11y_tree

    fn dump_a11y_tree(nodes : Array[A11yNode]) -> String

    extract_tab_index

    fn extract_tab_index(attrs : Array[(String,
    Attr
    [TuiEvent, TuiAttrValue])]) -> Int?

    Extract tab_index from TuiAttrValue if present

    form_edit_config

    fn form_edit_config(field_name : String, signal :
    Signal
    [String], on_edit_start? : () -> Unit?, on_edit_end? : () -> Unit?, on_force_quit? : () -> Unit?) -> EditConfig

    Helper to create a standard edit config for form fields

    grid

    fn grid(columns? : Array[Double], rows? : Array[Double], areas? : Array[String], auto_flow? : String, id? : String, gap? : Double, padding? : Double, padding_x? : Double, padding_y? : Double, width? : Double, height? : Double, border? : String, border_color? : String, bg? : String, role? : String, tab_index? : Int, children : Array[
    Node
    [TuiEvent, TuiAttrValue]]) ->
    Node
    [TuiEvent, TuiAttrValue]

    Grid container with CSS Grid layout Supports both explicit columns/rows and named areas

    grid_area

    Grid area - place child in a named grid area Used with grid(areas=[...]) for semantic layout

    grid_item

    fn grid_item(column? : Int, row? : Int, column_span? : Int, row_span? : Int, tab_index? : Int, child~ :
    Node
    [TuiEvent, TuiAttrValue]) ->
    Node
    [TuiEvent, TuiAttrValue]

    Grid item with placement control (explicit column/row positioning)

    hspace

    fn hspace(width : Double) ->
    Node
    [TuiEvent, TuiAttrValue]

    Horizontal space with fixed width

    init_vnode_terminal

    fn init_vnode_terminal(width : Int, height : Int, output_fn : (String) -> Unit, mouse? : Bool, raw_mode? : Bool) -> (VNodeApp, () -> Unit)

    Initialize a VNodeApp with terminal setup and return a cleanup function.

    input

    fn input(value : String, id? : String, placeholder? : String, state? : InputState, fg? : String, bg? : String, placeholder_fg? : String, focus_border_color? : String, edit_border_color? : String, disabled_fg? : String, disabled_bg? : String, width? : Double, min_width? : Double, padding_x? : Double, padding_y? : Double) ->
    Node
    [TuiEvent, TuiAttrValue]

    Create an input component

    input_plain

    fn input_plain(value : String, placeholder? : String, state? : InputState, fg? : String, placeholder_fg? : String) ->
    Node
    [TuiEvent, TuiAttrValue]

    Create an input field without border (inline style)

    is_printable_char

    fn is_printable_char(c : Char) -> Bool

    Check if a character is printable (for IME input detection)

    is_printable_string

    fn is_printable_string(s : String) -> Bool

    Check if a string is all printable characters (for IME input detection)

    Create an event handler attribute

    render_overlay_at

    fn render_overlay_at(x : Int, y : Int, node :
    Node
    [TuiEvent, TuiAttrValue]) -> String

    Render a TuiNode as an overlay at specified position Returns ANSI string with cursor positioning commands Each line of the node is rendered at (x + i, y) for i-th line

    render_to_lines

    fn render_to_lines(node :
    Node
    [TuiEvent, TuiAttrValue]) -> Array[String]

    Render a TuiNode to an array of lines Each line is a complete string with ANSI escape codes

    render_vnode_once

    fn render_vnode_once(width : Int, height : Int, root :
    Node
    [TuiEvent, TuiAttrValue]) -> String

    Simple render function for one-shot rendering (no reactivity)

    row

    fn row(id? : String, gap? : Double, margin? : Double, margin_x? : Double, margin_y? : Double, padding? : Double, padding_x? : Double, padding_y? : Double, width? : Double, height? : Double, min_width? : Double, min_height? : Double, flex_grow? : Double, justify? : String, align? : String, border? : String, border_color? : String, bg? : String, role? : String, tab_index? : Int, on_click? : (TuiEvent) -> Unit?, children : Array[
    Node
    [TuiEvent, TuiAttrValue]]) ->
    Node
    [TuiEvent, TuiAttrValue]

    Row container (horizontal flex)

    run_vnode_app

    fn run_vnode_app(width : Int, height : Int, render_fn : () ->
    Node
    [TuiEvent, TuiAttrValue], output_fn : (String) -> Unit) -> (() -> Unit)

    Full-screen vnode app helper: sets up alt screen and handles cleanup

    show

    Conditional rendering

    spacer

    Flexible spacer

    start_edit

    fn start_edit(config : EditConfig, current_value : String, on_complete : () -> Unit, confirm_on_shift_enter? : Bool, esc_cancels? : Bool) -> Unit

    Start editing a field with cooked mode (IME support) This exits alternate screen temporarily for proper IME input confirm_on_shift_enter: if true, Shift+Enter confirms and Enter inserts newline esc_cancels: if false, Esc is ignored

    start_edit_inplace

    fn start_edit_inplace(config : EditConfig, current_value : String, row : Int, col : Int, width : Int, height : Int, multiline : Bool, on_complete : () -> Unit, confirm_on_shift_enter? : Bool, esc_cancels? : Bool, on_lines_change? : (Int) -> Int?, on_completion? : (String, Int) -> String??) -> Unit

    Start editing a field inplace (stays in TUI screen) row/col are 1-indexed ANSI coordinates width/height define the input area (supports multi-line wrapping) multiline: if true, Enter can insert newline when confirm_on_shift_enter is true confirm_on_shift_enter: if true, Shift+Enter confirms esc_cancels: if false, Esc is ignored on_lines_change: optional callback (line_count) -> new_height for dynamic resizing on_completion: optional callback (text, cursor_pos) -> completion_suffix for Tab completion

    start_edit_inplace_in_bounds

    fn start_edit_inplace_in_bounds(config : EditConfig, current_value : String, bounds :
    HitTestResult
    , multiline : Bool, on_complete : () -> Unit, confirm_on_shift_enter? : Bool, esc_cancels? : Bool, border? : Int, on_lines_change? : (Int) -> Int?, on_completion? : (String, Int) -> String??) -> Unit

    Start editing within bounds (HitTestResult) with border adjustment. bounds.x/y are 0-indexed; row/col for ANSI are 1-indexed. on_completion: optional callback (text, cursor_pos) -> completion_suffix for Tab completion

    text

    fn text(content : String, fg? : String, bold? : Bool, underline? : Bool, role? : String) ->
    Node
    [TuiEvent, TuiAttrValue]

    Static text node

    text_dyn

    fn text_dyn(getter : () -> String, fg? : String, bold? : Bool, underline? : Bool, role? : String) ->
    Node
    [TuiEvent, TuiAttrValue]

    Dynamic text node

    text_node

    Create a text node from typed props

    textarea

    fn textarea(value : String, id? : String, placeholder? : String, state? : InputState, rows? : Int, fg? : String, bg? : String, placeholder_fg? : String, focus_border_color? : String, edit_border_color? : String, min_width? : Double, padding_x? : Double, padding_y? : Double) ->
    Node
    [TuiEvent, TuiAttrValue]

    Create a textarea component (multi-line input)

    to_crater_node

    Convert TuiNode to crater Node

    view

    fn view(direction? : String, id? : String, gap? : Double, margin? : Double, margin_x? : Double, margin_y? : Double, padding? : Double, padding_x? : Double, padding_y? : Double, width? : Double, height? : Double, min_width? : Double, min_height? : Double, flex_grow? : Double, justify? : String, align? : String, border? : String, border_color? : String, bg? : String, role? : String, tab_index? : Int, on_click? : (TuiEvent) -> Unit?, children : Array[
    Node
    [TuiEvent, TuiAttrValue]]) ->
    Node
    [TuiEvent, TuiAttrValue]

    Generic view container (flex layout with configurable direction) Default direction is column (React Native style)

    vspace

    fn vspace(height : Double) ->
    Node
    [TuiEvent, TuiAttrValue]

    Vertical space with fixed height