Sign in

    luna_components

    Headless + styled UI components (WAI-ARIA APG patterns) for Luna UI

    luna
    components
    apg
    headless
    ui
    Download zip
    Author
    Version
    0.22.3
    License
    MIT
    Last updated
    5 months ago
    Downloads
    126

    #luna_components

    Headless + styled UI components for Luna UI following the WAI-ARIA APG patterns.

    Status: experimental.

    #Layout

    PathRole
    src/Top-level components (one file per pattern)
    src/aria/ARIA attribute primitives
    src/headless/Logic-only state machines (no DOM styling)
    src/styled/Default-styled wrappers over headless
    src/apg/APG-pattern reference scaffolding

    #Install

    // moon.mod.json { "deps": { "mizchi/luna": "0.20.0", "mizchi/luna_components": "0.20.0" } }

    #Examples

    The APG playground (examples/apg-playground/) is the canonical demo and ships with the live deploy at https://luna-examples.mizchi.workers.dev/apg-playground/.

    #Luna Components

    APG (ARIA Authoring Practices Guide) 準拠のアクセシブルなUIコンポーネント。

    #パッケージ構成

    src/components/ ├── headless/ # ヘッドレスコンポーネント (mizchi/luna/components/headless) │ ├── aria.mbt # ARIA属性ヘルパー │ ├── helpers.mbt # イベントハンドラー等 │ └── switch.mbt # ヘッドレスSwitch ├── default/ # スタイル付きコンポーネント (mizchi/luna/components/default) │ ├── switch.mbt # デフォルトSwitch │ ├── theme.mbt # CSS抽出API │ └── themes/ # CSSファイル │ ├── switch.css │ └── index.css └── *.mbt # 既存コンポーネント (mizchi/luna/components)

    #使い方

    #ヘッドレス(CSS framework agnostic)

    Tailwind CSS など任意のCSSフレームワークと組み合わせて使用:

    import mizchi/luna/components/headless as @headless

    fn my_switch() -> @luna.Node[@js.Any] {
    let on = @signal.signal(false)
    let props = @headless.use_switch(on, aria_label="Enable feature")

    @luna.h("button",
    props.attrs + [
    ("class", @luna.attr_static("relative inline-flex h-6 w-11 rounded-full bg-gray-200")),
    ],
    [
    @luna.h("span", [
    ("class", @luna.attr_static("inline-block h-4 w-4 rounded-full bg-white")),
    ], []),
    ]
    )
    }

    #デフォルトスタイル付き

    すぐに使えるスタイル付きコンポーネント:

    import mizchi/luna/components/default as @default

    fn my_switch() -> @luna.Node[@js.Any] {
    let on = @signal.signal(true)
    @default.switch(on, aria_label="Enable notifications", [@luna.text("Notifications")])
    }

    CSS を <link> で読み込む:

    <link rel="stylesheet" href="path/to/themes/index.css">

    または MoonBit から CSS を抽出:

    // 全コンポーネントのCSS
    let css = @default.generate_theme_css()

    // 個別コンポーネント
    let switch_css = @default.switch_css()

    // CSS Variables 付き
    let full_theme = @default.generate_full_theme()

    #CSS Variables

    デフォルトテーマはCSS Variablesでカスタマイズ可能:

    :root { --switch-track-off: #d1d5db; --switch-track-on: #3b82f6; --accent: #3b82f6; }

    #BEM クラス名規約

    デフォルトコンポーネントは BEM 命名規則を使用:

    • .switch - ルート要素
    • .switch__track - トラック
    • .switch__thumb - スライドするつまみ
    • .switch__icon - アイコン
    • .switch__label - ラベル

    #Data 属性

    状態に応じてdata属性が付与され、CSSセレクタで使用可能:

    • [data-state="on"] / [data-state="off"] - 状態
    • [data-disabled] - 無効状態

    .switch[data-state="on"] .switch__track { background: var(--switch-track-on); }

    AccordionItem

    pub(all) struct AccordionItem[E] {
    id : String
    heading : String
    level : Int
    content : Array[
    Node
    [E, String]]
    }

    Accordion item data

    AlertType

    pub(all) enum AlertType {
    Info
    Success
    Warning
    Error
    }

    Alert severity levels

    AutocompleteType

    pub(all) enum AutocompleteType {
    None
    List
    Both
    Inline
    }

    Autocomplete behavior
    pub(all) struct BreadcrumbItem {
    href : String
    label : String
    current : Bool
    }

    Breadcrumb item data

    ButtonType

    pub(all) enum ButtonType {
    Button
    Submit
    Reset
    }

    Button type variants

    CheckboxState

    pub(all) enum CheckboxState {
    Checked
    Unchecked
    Mixed
    }

    Checkbox state

    ComboboxOption

    pub(all) struct ComboboxOption {
    id : String
    label : String
    disabled : Bool
    }

    Combobox option data

    KeyCode

    pub(all) enum KeyCode {
    Enter
    Space
    ArrowUp
    ArrowDown
    ArrowLeft
    ArrowRight
    Home
    End
    Tab
    Escape
    } derive(Eq,
    Debug
    )

    Common key codes for keyboard navigation
    impl Show for KeyCode

    KeyCode::from_string

    fn KeyCode::from_string(key : String) -> KeyCode?

    LinkTarget

    pub(all) enum LinkTarget {
    Self_
    Blank
    Parent
    Top
    }

    Link target behavior

    ListboxOption

    pub(all) struct ListboxOption {
    value : String
    label : String
    disabled : Bool
    }

    Listbox option data
    pub(all) struct MenuItem {
    id : String
    label : String
    disabled : Bool
    }

    Menu item data

    PopupType

    pub(all) enum PopupType {
    Menu
    Listbox
    Tree
    Grid
    Dialog
    }

    Menu button popup type

    RadioOption

    pub(all) struct RadioOption[E] {
    value : String
    label : Array[
    Node
    [E, String]]
    disabled : Bool
    }

    Radio option data

    SliderOrientation

    pub(all) enum SliderOrientation {
    Horizontal
    Vertical
    }

    Slider orientation

    SortDirection

    pub(all) enum SortDirection {
    None
    Ascending
    Descending
    }

    Sort direction for sortable columns

    TabItem

    pub(all) struct TabItem[E] {
    id : String
    label : String
    panel : Array[
    Node
    [E, String]]
    }

    Tab item data for building tabs

    TableColumn

    pub(all) struct TableColumn {
    id : String
    label : String
    sortable : Bool
    header_scope : String
    }

    Column definition

    TableRow

    pub(all) struct TableRow {
    id : String
    cells : Array[String]
    disabled : Bool
    }

    Row definition for data tables

    TabsOrientation

    pub(all) enum TabsOrientation {
    Horizontal
    Vertical
    }

    Tabs orientation

    ToggleState

    pub(all) enum ToggleState {
    Pressed
    NotPressed
    }

    Toggle button state

    ToolbarItemDef

    pub(all) struct ToolbarItemDef {
    id : String
    label : String
    toggle : Bool
    disabled : Bool
    }

    Toolbar item definition

    ToolbarOrientation

    pub(all) enum ToolbarOrientation {
    Horizontal
    Vertical
    }

    Toolbar orientation

    TreeNode

    pub(all) struct TreeNode {
    id : String
    label : String
    children : Array[TreeNode]
    disabled : Bool
    }

    Tree node data structure

    accordion

    fn[E] accordion(items : Array[AccordionItem[E]], expanded_index : Int, use_regions? : Bool) ->
    Node
    [E, String]

    Build a complete accordion from items. Only one panel can be expanded at a time (single-select mode).

    Parameters:
    • items: Array of AccordionItem
    • expanded_index: Index of currently expanded item (-1 for all collapsed)
    • use_regions: Whether to add role="region" to panels

    accordion_dyn

    fn[E] accordion_dyn(items : Array[AccordionItem[E]], expanded_index :
    Signal
    [Int], use_regions? : Bool) ->
    Node
    [E, String]

    Build a dynamic accordion with signal-based expanded index. This is the recommended way to create accordions with reactive state.

    Parameters:
    • items: Array of AccordionItem
    • expanded_index: Signal containing the currently expanded item index (-1 for all collapsed)
    • use_regions: Whether to add role="region" to panels

    accordion_header

    fn[E] accordion_header(id : String, expanded : Bool, controls : String, level? : Int, on_click? :
    EventHandler
    [E], on_keydown? :
    EventHandler
    [E], children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create an accordion header button.

    Parameters:
    • id: Button ID
    • expanded: Whether the panel is expanded
    • controls: ID of the controlled panel
    • level: Heading level (1-6)
    • on_click: Click handler to toggle
    • on_keydown: Keydown handler (for arrow key navigation)
    • children: Header content

    accordion_header_computed

    fn[E] accordion_header_computed(id : String, expanded : () -> Bool, controls : String, level? : Int, on_click? :
    EventHandler
    [E], on_keydown? :
    EventHandler
    [E], children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a dynamic accordion header with computed expanded state (accepts getter function). Useful for derived accordion states.

    accordion_header_dyn

    fn[E] accordion_header_dyn(id : String, expanded :
    Signal
    [Bool], controls : String, level? : Int, on_click? :
    EventHandler
    [E], on_keydown? :
    EventHandler
    [E], children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a dynamic accordion header with signal-based expanded state.

    accordion_interactive

    fn accordion_interactive(id : String, items : Array[AccordionItem[
    Any
    ]], expanded_index :
    Signal
    [Int], use_regions? : Bool) ->
    Node
    [
    Any
    , String]

    Create a complete interactive accordion with keyboard navigation.

    Features:
    • Arrow key navigation between headers
    • Home/End navigation
    • Enter/Space toggles panel
    • Single-select mode (one panel open at a time)

    Parameters:
    • id: Accordion container ID
    • items: Array of AccordionItem
    • expanded_index: Signal for currently expanded item (-1 for all collapsed)
    • use_regions: Whether to use role="region" on panels

    accordion_item

    fn[E] accordion_item(id : String, heading : String, level? : Int, content : Array[
    Node
    [E, String]]) -> AccordionItem[E]

    Create an accordion item

    accordion_multi

    fn[E] accordion_multi(items : Array[AccordionItem[E]], expanded_ids : Array[String], use_regions? : Bool) ->
    Node
    [E, String]

    Build a multi-select accordion where multiple panels can be open.

    Parameters:
    • items: Array of AccordionItem
    • expanded_ids: Array of expanded item IDs
    • use_regions: Whether to add role="region" to panels

    accordion_panel

    fn[E] accordion_panel(id : String, labelledby : String, hidden : Bool, use_region? : Bool, children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create an accordion panel.

    Parameters:
    • id: Panel ID (referenced by header's aria-controls)
    • labelledby: ID of the header button
    • hidden: Whether the panel is hidden
    • use_region: Whether to use role="region" (recommended for <= 6 panels)
    • children: Panel content

    accordion_panel_computed

    fn[E] accordion_panel_computed(id : String, labelledby : String, visible : () -> Bool, use_region? : Bool, children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a accordion panel with computed visibility (accepts getter function).

    accordion_panel_dyn

    fn[E] accordion_panel_dyn(id : String, labelledby : String, visible :
    Signal
    [Bool], use_region? : Bool, children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a dynamic accordion panel with signal-based visibility.

    alert

    fn[E] alert(type_? : AlertType, aria_label? : String, children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create an accessible alert element. Alerts are automatically announced by screen readers when they appear.

    Parameters:
    • type_: Alert severity type (optional, for styling)
    • aria_label: Accessible label (optional)
    • children: Alert content

    Example:
    alert([@luna.text("Your changes have been saved.")]) alert(type_=Error, [@luna.text("Invalid email address.")])

    alert_dialog

    fn[E] alert_dialog(aria_label? : String, aria_labelledby? : String, aria_describedby? : String, open : Bool, on_keydown? :
    EventHandler
    [E], children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create an alert dialog (interrupting dialog for important messages). Uses role="alertdialog" for urgent messages that require user action.

    Parameters:
    • aria_label: Accessible label
    • aria_labelledby: ID of title element
    • aria_describedby: ID of description element (recommended)
    • open: Whether the dialog is open
    • on_keydown: Keydown handler (for Escape key to close)
    • children: Dialog content

    alert_dialog_dyn

    fn[E] alert_dialog_dyn(aria_label? : String, aria_labelledby? : String, aria_describedby? : String, open :
    Signal
    [Bool], on_keydown? :
    EventHandler
    [E], children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a dynamic alert dialog with signal-based open state.

    alert_live

    fn[E] alert_live(type_? : AlertType, aria_live? : String, children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create an alert with live region for dynamic updates. Use when alert content will be updated dynamically.

    Parameters:
    • type_: Alert severity type
    • aria_live: Live region politeness (default: "assertive")
    • children: Alert content

    arrow_direction

    fn arrow_direction(key : String) -> Int

    Get direction from arrow key (-1 for up/left, 1 for down/right, 0 for other)

    aside

    fn[E] aside(aria_label? : String, children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a complementary landmark (sidebar/aside). Supporting content that complements the main content. Implicit for element.

    Parameters:
    • aria_label: Accessible label (recommended)
    • children: Complementary content

    auto_id

    fn auto_id(prefix : String) -> String

    Generate a unique ID with a given prefix. Useful for automatically creating IDs for tabs, panels, etc.
    test {
    let id1 = @luna_components.auto_id("tab")
    let id2 = @luna_components.auto_id("tab")
    assert_true(id1 != id2)
    }
    fn[E] banner(aria_label? : String, children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a banner landmark (site header). Use at top of page for site-oriented content like logo, site name, search. Implicit for when not nested in article/section.

    Parameters:
    • aria_label: Accessible label (optional, use when multiple banners exist)
    • children: Header content

    bool_to_aria

    fn bool_to_aria(value : Bool) -> String

    Boolean to ARIA string conversion
    fn[E] breadcrumb(aria_label? : String, separator? : String, items : Array[BreadcrumbItem]) ->
    Node
    [E, String]

    Create a breadcrumb navigation.

    Parameters:
    • aria_label: Accessible label (default: "Breadcrumb")
    • separator: Separator between items (default: "/")
    • items: Breadcrumb items
    fn[E] breadcrumb_from_path(base_path : String, segments : Array[(String, String)], current_label : String) ->
    Node
    [E, String]

    Create a simple breadcrumb from path segments.

    Parameters:
    • base_path: Base path (e.g., "/docs")
    • segments: Path segments (e.g., ["Getting Started", "Installation"])
    • current_label: Label for current page
    fn breadcrumb_item(href : String, label : String, current? : Bool) -> BreadcrumbItem

    Create a breadcrumb item

    button

    fn[E] button(type_? : ButtonType, disabled? : Bool, aria_label? : String, aria_describedby? : String, on_click? :
    EventHandler
    [E], on_keydown? :
    EventHandler
    [E], children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create an accessible button using native element.

    Parameters:
    • type_: Button type (default: Button)
    • disabled: Whether the button is disabled
    • aria_label: Accessible label (optional, for icon-only buttons)
    • aria_describedby: ID of element describing the button
    • on_click: Click handler
    • on_keydown: Keydown handler (for custom keyboard interactions)
    • children: Child nodes (button content)

    Example:
    button([@luna.text("Save")]) button(disabled=true, [@luna.text("Disabled")])

    caption

    fn[E] caption(id? : String, children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a table caption.

    checkbox

    fn[E] checkbox(checked : CheckboxState, disabled? : Bool, aria_label? : String, aria_labelledby? : String, on_click? :
    EventHandler
    [E], on_keydown? :
    EventHandler
    [E], children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create an accessible checkbox.

    Parameters:
    • checked: Checkbox state
    • disabled: Whether disabled
    • aria_label: Accessible label
    • aria_labelledby: ID of labelling element
    • on_click: Click handler
    • on_keydown: Keydown handler (for Space key toggle)
    • children: Checkbox label content

    checkbox_computed

    fn[E] checkbox_computed(checked : () -> CheckboxState, disabled? : Bool, aria_label? : String, on_click? :
    EventHandler
    [E], on_keydown? :
    EventHandler
    [E], children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a checkbox with computed state (accepts getter function). Useful for derived checkbox states.

    checkbox_dyn

    fn[E] checkbox_dyn(checked :
    Signal
    [CheckboxState], disabled? : Bool, aria_label? : String, on_click? :
    EventHandler
    [E], on_keydown? :
    EventHandler
    [E], children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a dynamic checkbox with signal-based state.

    checkbox_group

    fn[E] checkbox_group(aria_label? : String, aria_labelledby? : String, children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a checkbox group with role="group".

    checkbox_native

    fn[E] checkbox_native(name : String, checked : Bool, disabled? : Bool, id? : String, children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a native HTML checkbox input with label.

    clamp_index

    fn clamp_index(current : Int, direction : Int, length : Int) -> Int

    Calculate next index for list navigation without wrapping (clamped)

    combobox_input

    fn[E] combobox_input(id : String, listbox_id : String, expanded : Bool, value : String, autocomplete? : AutocompleteType, aria_label? : String, aria_labelledby? : String, active_descendant? : String, on_input? :
    EventHandler
    [E], on_keydown? :
    EventHandler
    [E], on_focus? :
    EventHandler
    [E], on_blur? :
    EventHandler
    [E]) ->
    Node
    [E, String]

    Create a combobox input element.

    Parameters:
    • id: Input ID
    • listbox_id: ID of the associated listbox
    • expanded: Whether listbox is visible
    • value: Current input value
    • autocomplete: Autocomplete behavior
    • aria_label: Accessible label
    • aria_labelledby: ID of labelling element
    • active_descendant: ID of the currently active option
    • on_input: Input handler
    • on_keydown: Keydown handler
    • on_focus: Focus handler
    • on_blur: Blur handler

    combobox_input_dyn

    fn[E] combobox_input_dyn(id : String, listbox_id : String, expanded :
    Signal
    [Bool], value :
    Signal
    [String], autocomplete? : AutocompleteType, aria_label? : String, active_descendant :
    Signal
    [String], on_input? :
    EventHandler
    [E], on_keydown? :
    EventHandler
    [E], on_focus? :
    EventHandler
    [E], on_blur? :
    EventHandler
    [E]) ->
    Node
    [E, String]

    Create a dynamic combobox input with signal-based state.

    combobox_interactive

    fn combobox_interactive(id : String, options : Array[ComboboxOption], placeholder? : String, aria_label? : String, on_select : (ComboboxOption) -> Unit) ->
    Node
    [
    Any
    , String]

    Create a complete interactive combobox with filtering.

    Parameters:
    • id: Base ID for the component
    • options: Available options
    • placeholder: Placeholder text for input
    • aria_label: Accessible label
    • on_select: Called when an option is selected

    combobox_listbox

    fn[E] combobox_listbox(id : String, labelled_by : String, visible : Bool, children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a combobox listbox container.

    Parameters:
    • id: Listbox ID
    • labelled_by: ID of the element that labels this listbox
    • visible: Whether listbox is visible
    • children: Option elements

    combobox_listbox_dyn

    fn[E] combobox_listbox_dyn(id : String, labelled_by : String, visible :
    Signal
    [Bool], children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a dynamic combobox listbox with signal-based visibility.

    combobox_option

    fn combobox_option(id : String, label : String, disabled? : Bool) -> ComboboxOption

    Create a combobox option

    combobox_option_dyn

    fn[E] combobox_option_dyn(id : String, option_id : String, active_id :
    Signal
    [String], disabled? : Bool, on_click? :
    EventHandler
    [E], children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a dynamic combobox option with signal-based selection.

    combobox_option_el

    fn[E] combobox_option_el(id : String, selected : Bool, disabled? : Bool, on_click? :
    EventHandler
    [E], children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a combobox option element.

    Parameters:
    • id: Option ID
    • selected: Whether this option is the active descendant
    • disabled: Whether option is disabled
    • on_click: Click handler
    • children: Option content

    combobox_select_only

    fn combobox_select_only(id : String, options : Array[ComboboxOption], initial_value? : String, aria_label? : String, on_select : (ComboboxOption) -> Unit) ->
    Node
    [
    Any
    , String]

    Create a select-only combobox (no text input filtering). This is useful when options should not be filtered by typing.

    confirm_dialog

    fn confirm_dialog(id : String, title : String, message : String, confirm_label? : String, cancel_label? : String, open :
    Signal
    [Bool], on_confirm : () -> Unit, on_cancel : () -> Unit) ->
    Node
    [
    Any
    , String]

    Create a confirmation dialog (common Alert Dialog use case). Returns a fragment with backdrop and dialog.

    Parameters:
    • id: Base ID for the dialog
    • title: Dialog title
    • message: Confirmation message
    • confirm_label: Label for confirm button (default: "OK")
    • cancel_label: Label for cancel button (default: "Cancel")
    • open: Signal controlling visibility
    • on_confirm: Called when user confirms
    • on_cancel: Called when user cancels

    contentinfo

    fn[E] contentinfo(aria_label? : String, children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a contentinfo landmark (site footer). Contains information about the parent document (copyright, privacy, etc.). Implicit for when not nested in article/section.

    Parameters:
    • aria_label: Accessible label (optional)
    • children: Footer content

    dialog

    fn[E] dialog(aria_label? : String, aria_labelledby? : String, aria_describedby? : String, open : Bool, on_keydown? :
    EventHandler
    [E], children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a modal dialog container.

    Parameters:
    • aria_label: Accessible label for the dialog
    • aria_labelledby: ID of the title element
    • aria_describedby: ID of the description element
    • open: Whether the dialog is currently open
    • on_keydown: Keydown handler (for Escape key to close)
    • children: Dialog content

    Example:
    dialog( aria_labelledby="dialog-title", open=true, [ h2(id="dialog-title", [text("Confirm")]), p([text("Are you sure?")]), button([text("Yes")]), button([text("No")]) ] )

    dialog_backdrop

    fn[E] dialog_backdrop(on_click? :
    EventHandler
    [E], children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a dialog backdrop/overlay. Used to visually obscure content behind the dialog.

    dialog_dyn

    fn[E] dialog_dyn(aria_label? : String, aria_labelledby? : String, aria_describedby? : String, open :
    Signal
    [Bool], on_keydown? :
    EventHandler
    [E], children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a dynamic dialog with signal-based open state.

    dialog_interactive

    fn dialog_interactive(id : String, aria_label? : String, aria_labelledby? : String, aria_describedby? : String, open :
    Signal
    [Bool], on_close : () -> Unit, children : Array[
    Node
    [
    Any
    , String]]) ->
    Node
    [
    Any
    , String]

    Create a complete interactive modal dialog with focus management.

    Features:
    • Focus trap (Tab/Shift+Tab cycles within dialog)
    • Escape key closes dialog
    • Focus moves to first element on open
    • Focus returns to trigger on close

    Parameters:
    • id: Dialog element ID
    • aria_label: Accessible label
    • aria_labelledby: ID of title element
    • open: Signal controlling visibility
    • on_close: Called when dialog should close
    • trigger_ref: Reference to store trigger element for focus restoration
    • children: Dialog content

    dialog_native

    fn[E] dialog_native(id? : String, aria_labelledby? : String, open : Bool, children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a native HTML dialog element. Uses element for better browser support and behavior.

    disclosure

    fn[E] disclosure(id : String, expanded : Bool, button_content : Array[
    Node
    [E, String]], panel_content : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a complete disclosure component.

    Parameters:
    • id: Base ID for the disclosure
    • expanded: Whether expanded
    • button_content: Content for the button
    • panel_content: Content for the panel

    disclosure_button

    fn[E] disclosure_button(id? : String, expanded : Bool, controls : String, on_click? :
    EventHandler
    [E], on_keydown? :
    EventHandler
    [E], children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a disclosure button.

    Parameters:
    • id: Button ID
    • expanded: Whether content is visible
    • controls: ID of controlled content element
    • on_click: Click handler
    • on_keydown: Keydown handler (for Enter/Space toggle)
    • children: Button content

    disclosure_button_computed

    fn[E] disclosure_button_computed(id? : String, expanded : () -> Bool, controls : String, on_click? :
    EventHandler
    [E], on_keydown? :
    EventHandler
    [E], children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a disclosure button with computed state (accepts getter function). Useful for derived disclosure states.

    disclosure_button_dyn

    fn[E] disclosure_button_dyn(id? : String, expanded :
    Signal
    [Bool], controls : String, on_click? :
    EventHandler
    [E], on_keydown? :
    EventHandler
    [E], children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a dynamic disclosure button with signal-based state.

    disclosure_content

    fn[E] disclosure_content(id : String, hidden : Bool, children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create disclosure content panel.

    Parameters:
    • id: Content ID (referenced by button's aria-controls)
    • hidden: Whether content is hidden
    • children: Content

    disclosure_content_computed

    fn[E] disclosure_content_computed(id : String, visible : () -> Bool, children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create disclosure content with computed visibility (accepts getter function).

    disclosure_content_dyn

    fn[E] disclosure_content_dyn(id : String, visible :
    Signal
    [Bool], children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a dynamic disclosure content with signal-based visibility.

    disclosure_dyn

    fn[E] disclosure_dyn(id : String, expanded :
    Signal
    [Bool], button_content : Array[
    Node
    [E, String]], panel_content : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a dynamic disclosure component with signal-based state. This is the recommended way to create disclosures with reactive state.

    Parameters:
    • id: Base ID for the disclosure
    • expanded: Signal containing the expanded state
    • button_content: Content for the button
    • panel_content: Content for the panel

    find_node

    fn find_node(nodes : Array[TreeNode], target_id : String) -> TreeNode?

    Find a node by ID

    find_parent_id

    fn find_parent_id(nodes : Array[TreeNode], target_id : String, parent_id : String?) -> String?

    Find parent ID for a node

    flatten_visible_nodes

    fn flatten_visible_nodes(nodes : Array[TreeNode], expanded : Map[String, Bool]) -> Array[String]

    Flatten tree nodes into a list of visible node IDs for navigation. Only includes expanded nodes' children.

    focus_dialog

    fn focus_dialog(dialog_id : String) -> Unit

    Focus the dialog container itself. Useful when there are no focusable elements inside.

    focus_first_in_dialog

    fn focus_first_in_dialog(dialog_id : String) -> Unit

    Focus the first focusable element inside the dialog. Call this when the dialog opens.

    form_landmark

    fn[E] form_landmark(aria_label? : String, aria_labelledby? : String, children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a form landmark. A form becomes a landmark when it has an accessible name.

    Parameters:
    • aria_label: Accessible label (required for form to be a landmark)
    • aria_labelledby: ID of labelling element (alternative to aria_label)
    • children: Form content

    has_children

    fn has_children(node : TreeNode) -> Bool

    Check if a node has children

    is_arrow_key

    fn is_arrow_key(key : String) -> Bool

    Check if a key is an arrow key

    is_horizontal_arrow

    fn is_horizontal_arrow(key : String) -> Bool

    Check if a key is a horizontal arrow key

    is_toggle_key

    fn is_toggle_key(key : String) -> Bool

    Check if a key is a toggle key (Space or Enter)

    is_vertical_arrow

    fn is_vertical_arrow(key : String) -> Bool

    Check if a key is a vertical arrow key

    key_matches

    fn key_matches(key : String, code : KeyCode) -> Bool

    Check if a key matches a KeyCode
    fn[E] link(href : String, target? : LinkTarget, aria_label? : String, aria_describedby? : String, disabled? : Bool, children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create an accessible link using native element. This is the recommended approach per APG guidelines.

    Parameters:
    • href: URL to navigate to
    • target: Link target (default: Self_)
    • aria_label: Accessible label (optional, for icon-only links)
    • aria_describedby: ID of element describing the link (optional)
    • disabled: Whether the link is disabled (optional)
    • children: Child nodes (link text/content)

    Example:
    link("https://example.com", [@luna.text("Visit Example")]) link("/about", target=Blank, [@luna.text("About (new tab)")])
    fn[E] link_button(on_click :
    EventHandler
    [E], aria_label? : String, children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a link-styled button (for actions that look like links). Uses role="link" on a span/button element. Use this when you need link appearance but button semantics.

    Parameters:
    • on_click: Click handler
    • aria_label: Accessible label (optional)
    • children: Child nodes

    Keyboard Interaction:
    • Enter: Activates the link action
    • Space: Activates the link action (when focused)

    listbox

    fn[E] listbox(aria_label? : String, aria_labelledby? : String, multiselectable? : Bool, on_keydown? :
    EventHandler
    [E], children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a listbox container.

    Parameters:
    • aria_label: Accessible label
    • aria_labelledby: ID of labelling element
    • multiselectable: Whether multiple options can be selected
    • on_keydown: Keydown handler (for arrow key navigation, type-ahead)
    • children: Option elements

    listbox_from_options

    fn[E] listbox_from_options(options : Array[ListboxOption], selected_value : String, aria_label? : String) ->
    Node
    [E, String]

    Build a complete listbox from options.

    listbox_multi

    fn[E] listbox_multi(options : Array[ListboxOption], selected_values : Array[String], aria_label? : String) ->
    Node
    [E, String]

    Build a multi-select listbox.

    listbox_option

    fn listbox_option(value : String, label : String, disabled? : Bool) -> ListboxOption

    Create a listbox option

    main_content

    fn[E] main_content(children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a main landmark. Contains the primary content of the page. There should be only one main landmark per page. Implicit for element.

    Parameters:
    • children: Main content

    make_accordion_keydown_handler

    fn make_accordion_keydown_handler(header_ids : Array[String], current_index : Int, on_toggle? : () -> Unit) ->
    EventHandler
    [
    Any
    ]

    Create a keyboard handler for accordion header navigation.

    APG keyboard support:
    • ArrowDown: Move focus to next header
    • ArrowUp: Move focus to previous header
    • Home: Move focus to first header
    • End: Move focus to last header
    • Enter/Space: Toggle panel (handled by browser for button)

    Parameters:
    • header_ids: Array of header button IDs
    • current_index: Index of the current header
    • on_toggle: Optional callback when Enter/Space is pressed

    make_combobox_handler

    fn make_combobox_handler(is_open : () -> Bool, filtered_options : () -> Array[ComboboxOption], current_index : () -> Int, open_listbox : () -> Unit, close_listbox : () -> Unit, set_index : (Int) -> Unit, on_select : (ComboboxOption) -> Unit) ->
    EventHandler
    [
    Any
    ]

    Create a combobox keyboard handler. Handles arrow navigation, Enter selection, Escape to close.

    make_dialog_keydown_handler

    fn make_dialog_keydown_handler(dialog_id : String, on_close : () -> Unit) ->
    EventHandler
    [
    Any
    ]

    Create a keydown handler for dialog with focus trap and Escape support.

    Parameters:
    • dialog_id: ID of the dialog element
    • on_close: Callback when Escape is pressed

    Handles:
    • Escape: Calls on_close
    • Tab: Moves focus to next element, wrapping at end
    • Shift+Tab: Moves focus to previous element, wrapping at start

    make_escape_handler

    fn make_escape_handler(on_escape : () -> Unit) ->
    EventHandler
    [
    Any
    ]

    Create an escape key handler

    make_horizontal_nav_handler

    fn make_horizontal_nav_handler(current_index : () -> Int, length : Int, on_change : (Int) -> Unit, wrap? : Bool, support_home_end? : Bool) ->
    EventHandler
    [
    Any
    ]

    Create a horizontal arrow key handler for tabs/sliders
    • ArrowLeft: move to previous
    • ArrowRight: move to next
    • Home: move to first (optional)
    • End: move to last (optional)

    make_menu_button_handler

    fn make_menu_button_handler(is_open : () -> Bool, open_menu : () -> Unit, close_menu : () -> Unit, focus_first : () -> Unit, focus_last : () -> Unit) ->
    EventHandler
    [
    Any
    ]

    Create a menu button keyboard handler for the trigger button. Handles Enter, Space, ArrowDown, ArrowUp to open menu.

    make_menu_nav_handler

    fn make_menu_nav_handler(current_index : () -> Int, item_count : Int, on_select : (Int) -> Unit, close_menu : () -> Unit, on_activate : (Int) -> Unit) ->
    EventHandler
    [
    Any
    ]

    Create a menu keyboard handler for menu items. Handles arrow navigation, Enter/Space activation, Escape to close.

    make_radio_keydown_handler

    fn make_radio_keydown_handler(options : Array[RadioOption[
    Any
    ]], radio_ids : Array[String], current_index : Int, on_select : (Int) -> Unit) ->
    EventHandler
    [
    Any
    ]

    Create a keyboard handler for radio group with arrow navigation.

    APG keyboard support:
    • ArrowDown/ArrowRight: Move to next and select (wraps)
    • ArrowUp/ArrowLeft: Move to previous and select (wraps)
    • Home: Move to first and select
    • End: Move to last and select
    • Space: Select focused radio

    Parameters:
    • options: Array of radio options
    • radio_ids: Array of radio element IDs
    • current_index: Index of the current radio
    • on_select: Callback to select a value by index

    make_slider_drag_handler

    fn make_slider_drag_handler(min : Double, max : Double, step : Double, on_change : (Double) -> Unit) ->
    EventHandler
    [
    Any
    ]

    Create a slider mousedown handler that enables drag tracking Sets up document-level mousemove/mouseup listeners for smooth dragging

    make_slider_handler

    fn make_slider_handler(current_value : () -> Double, min : Double, max : Double, step : Double, on_change : (Double) -> Unit, large_step? : Double) ->
    EventHandler
    [
    Any
    ]

    Create a slider keyboard handler
    • ArrowUp/Right: increase by step
    • ArrowDown/Left: decrease by step
    • Home: set to min
    • End: set to max
    • PageUp: increase by large step (optional)
    • PageDown: decrease by large step (optional)

    make_sort_handler

    fn make_sort_handler(column_id : String, current_sort_column : () -> String, current_sort_direction : () -> SortDirection, on_sort : (String, SortDirection) -> Unit) ->
    EventHandler
    [
    Any
    ]

    Create a sortable table header click handler. Toggles between ascending, descending, and none.

    make_spinbutton_handler

    fn make_spinbutton_handler(current_value : () -> Double, min : Double?, max : Double?, step : Double, on_change : (Double) -> Unit, large_step? : Double) ->
    EventHandler
    [
    Any
    ]

    Create a spinbutton keyboard handler. Handles Up/Down arrows, Home/End, PageUp/PageDown.

    make_spinbutton_input_handler

    fn make_spinbutton_input_handler(min : Double?, max : Double?, on_change : (Double) -> Unit, fallback_value : () -> Double) ->
    EventHandler
    [
    Any
    ]

    Create a spinbutton input handler for text input. Validates and clamps input to min/max bounds.

    make_switch_handler

    fn make_switch_handler(on_toggle : () -> Unit) ->
    EventHandler
    [
    Any
    ]

    Create a keyboard handler for switch that supports Space and Enter.

    APG requires:
    • Space: Toggle switch state
    • Enter: Toggle switch state

    Parameters:
    • on_toggle: Called when switch should toggle

    make_table_handler

    fn make_table_handler(row_count : Int, col_count : Int, current_row : () -> Int, current_col : () -> Int, on_change : (Int, Int) -> Unit, focus_cell : (Int, Int) -> Unit, page_size? : Int) ->
    EventHandler
    [
    Any
    ]

    Create a table keyboard handler for grid navigation. Handles arrow keys, Home/End, PageUp/PageDown.

    make_toggle_handler

    fn make_toggle_handler(on_toggle : () -> Unit) ->
    EventHandler
    [
    Any
    ]

    Create a toggle handler that responds to Space and Enter keys

    make_toolbar_handler

    fn make_toolbar_handler(current_index : () -> Int, item_count : Int, on_change : (Int) -> Unit, orientation : ToolbarOrientation, focus_item : (Int) -> Unit) ->
    EventHandler
    [
    Any
    ]

    Create a toolbar keyboard handler. Handles arrow navigation, Home/End.

    Parameters:
    • current_index: Function returning current focused index
    • item_count: Total number of focusable items
    • on_change: Called with new index when focus changes
    • orientation: Toolbar orientation
    • focus_item: Function to focus item at index

    make_tooltip_keydown_handler

    fn make_tooltip_keydown_handler(on_close : () -> Unit) ->
    EventHandler
    [
    Any
    ]

    Create a keydown handler for tooltip that supports Escape key.

    APG keyboard support:
    • Escape: Close the tooltip

    Parameters:
    • on_close: Called when Escape is pressed

    make_tree_handler

    fn make_tree_handler(nodes : Array[TreeNode], focused_id :
    Signal
    [String], expanded :
    Signal
    [Map[String, Bool]], selected :
    Signal
    [String], on_activate : (String) -> Unit) ->
    EventHandler
    [
    Any
    ]

    Create tree view keyboard handler.

    make_vertical_nav_handler

    fn make_vertical_nav_handler(current_index : () -> Int, length : Int, on_change : (Int) -> Unit, wrap? : Bool, support_home_end? : Bool) ->
    EventHandler
    [
    Any
    ]

    Create a vertical arrow key handler for radio groups/listboxes
    • ArrowUp: move to previous
    • ArrowDown: move to next
    • Home: move to first (optional)
    • End: move to last (optional)
    fn[E] menu(id : String, labelled_by : String, visible : Bool, children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a menu container.

    Parameters:
    • id: Menu ID (referenced by button's aria-controls)
    • labelled_by: ID of the button that labels this menu
    • visible: Whether menu is visible
    • children: Menu items
    fn[E] menu_button(popup_type : PopupType, expanded : Bool, controls? : String, aria_label? : String, on_click? :
    EventHandler
    [E], on_keydown? :
    EventHandler
    [E], children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a menu button (button that opens a popup).

    Parameters:
    • popup_type: Type of popup this button controls
    • expanded: Whether the popup is currently open
    • controls: ID of the popup element
    • aria_label: Accessible label
    • on_click: Click handler
    • on_keydown: Keydown handler (for arrow key navigation, Escape, etc.)
    • children: Child nodes

    Example:
    menu_button(Menu, false, controls="dropdown", [@luna.text("Options")])
    fn[E] menu_button_dyn(popup_type : PopupType, expanded :
    Signal
    [Bool], controls? : String, aria_label? : String, on_click? :
    EventHandler
    [E], on_keydown? :
    EventHandler
    [E], children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Dynamic menu button with signal-based expanded state.
    fn menu_button_interactive(id : String, items : Array[MenuItem], on_select : (String) -> Unit, button_content : Array[
    Node
    [
    Any
    , String]]) ->
    Node
    [
    Any
    , String]

    Create a complete interactive menu button with keyboard support.

    Parameters:
    • id: Base ID for the component
    • items: Menu items
    • on_select: Called when an item is selected
    • button_content: Content for the trigger button
    fn[E] menu_dyn(id : String, labelled_by : String, visible :
    Signal
    [Bool], children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a dynamic menu with signal-based visibility.
    fn menu_item(id : String, label : String, disabled? : Bool) -> MenuItem

    Create a menu item
    fn[E] menu_trigger(id : String, expanded : Bool, menu_id : String, aria_label? : String, on_click? :
    EventHandler
    [E], on_keydown? :
    EventHandler
    [E], children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a menu button trigger with ID. Uses existing menu_button from button.mbt internally.

    Parameters:
    • id: Button ID
    • expanded: Whether menu is open
    • menu_id: ID of the menu element
    • aria_label: Accessible label
    • on_click: Click handler
    • on_keydown: Keydown handler
    • children: Button content
    fn[E] menu_trigger_dyn(id : String, expanded :
    Signal
    [Bool], menu_id : String, aria_label? : String, on_click? :
    EventHandler
    [E], on_keydown? :
    EventHandler
    [E], children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a dynamic menu trigger with signal-based state.
    fn[E] menuitem(id? : String, selected : Bool, disabled? : Bool, on_click? :
    EventHandler
    [E], on_keydown? :
    EventHandler
    [E], children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a menu item element.

    Parameters:
    • id: Item ID
    • selected: Whether this item has focus (tabindex=0)
    • disabled: Whether item is disabled
    • on_click: Click handler
    • on_keydown: Keydown handler
    • children: Item content
    fn[E] menuitem_dyn(id? : String, selected_index :
    Signal
    [Int], index : Int, disabled? : Bool, on_click? :
    EventHandler
    [E], on_keydown? :
    EventHandler
    [E], children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a dynamic menu item with signal-based selection.

    meter

    fn[E] meter(value : Double, min? : Double, max? : Double, aria_label? : String, aria_labelledby? : String, aria_valuetext? : String, children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create an accessible meter element.

    Parameters:
    • value: Current value (aria-valuenow)
    • min: Minimum value (aria-valuemin), default 0
    • max: Maximum value (aria-valuemax), default 100
    • aria_label: Accessible label (required if no aria_labelledby)
    • aria_labelledby: ID of labelling element
    • aria_valuetext: Human-readable value (e.g., "50% (6 hours) remaining")
    • children: Visual representation of the meter

    Example:
    meter(75.0, aria_label="Battery level", []) meter(50.0, aria_valuetext="50% (6 hours) remaining", aria_label="Battery", [])

    meter_dyn

    fn[E] meter_dyn(value :
    Signal
    [Double], min? : Double, max? : Double, aria_label? : String, aria_valuetext_fn? : (Double) -> String, children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a dynamic meter with signal-based value. Automatically updates aria-valuenow when the signal changes.

    Parameters:
    • value: Signal containing current value
    • min: Minimum value (default 0)
    • max: Maximum value (default 100)
    • aria_label: Accessible label
    • aria_valuetext_fn: Function to generate aria-valuetext from current value
    • children: Visual representation

    meter_native

    fn[E] meter_native(value : Double, min? : Double, max? : Double, low? : Double, high? : Double, optimum? : Double, aria_label? : String, children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a meter using the native HTML element. Native meter has better browser support but limited styling options.

    Parameters:
    • value: Current value
    • min: Minimum value (default 0)
    • max: Maximum value (default 100)
    • low: Low threshold (values below are considered low)
    • high: High threshold (values above are considered high)
    • optimum: Optimal value
    • aria_label: Accessible label
    • children: Fallback content for browsers without meter support
    fn[E] modal(aria_label? : String, aria_labelledby? : String, open : Bool, on_backdrop_click? :
    EventHandler
    [E], children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a complete dialog with backdrop. Wraps dialog content with backdrop for modal behavior.
    fn[E] nav(aria_label? : String, children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a navigation landmark. Use for major navigation blocks. Implicit for element.

    Parameters:
    • aria_label: Accessible label (required when multiple nav landmarks exist)
    • children: Navigation links

    Example:
    nav(aria_label="Main navigation", [link("/", [text("Home")]), ...])

    optgroup

    fn[E] optgroup(aria_label : String, children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create an option group.

    option

    fn[E] option(value : String, selected : Bool, disabled? : Bool, children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a listbox option.

    Parameters:
    • value: Option value
    • selected: Whether selected
    • disabled: Whether disabled
    • children: Option content

    option_dyn

    fn[E] option_dyn(value : String, selected_values :
    Signal
    [Array[String]], disabled? : Bool, children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a dynamic option with signal-based selection.

    page_layout

    fn[E] page_layout(header? : Array[
    Node
    [E, String]], nav_content? : Array[
    Node
    [E, String]], main_children : Array[
    Node
    [E, String]], aside_content? : Array[
    Node
    [E, String]], footer_content? : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a page layout with standard landmarks structure. Provides a complete accessible page structure.

    Parameters:
    • header: Banner content (optional)
    • nav: Navigation content (optional)
    • main_content: Main content (required)
    • aside_content: Complementary content (optional)
    • footer: Contentinfo content (optional)

    Example:
    page_layout( header=[text("Site Name")], nav=[link("/", [text("Home")])], main_content=[text("Welcome")], footer=[text("© 2024")] )

    radio

    fn[E] radio(value : String, checked : Bool, disabled? : Bool, on_click? :
    EventHandler
    [E], on_keydown? :
    EventHandler
    [E], children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a single radio button.

    Parameters:
    • value: Radio value
    • checked: Whether this radio is checked
    • disabled: Whether this radio is disabled
    • on_click: Click handler
    • on_keydown: Keydown handler (for arrow key navigation)
    • children: Radio label content

    radio_computed

    fn[E] radio_computed(value : String, checked : () -> Bool, disabled? : Bool, on_click? :
    EventHandler
    [E], on_keydown? :
    EventHandler
    [E], children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a radio with computed checked state (accepts getter function). Useful for derived radio states.

    radio_dyn

    fn[E] radio_dyn(value : String, selected_value :
    Signal
    [String], disabled? : Bool, on_click? :
    EventHandler
    [E], on_keydown? :
    EventHandler
    [E], children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a dynamic radio with signal-based checked state.

    radio_group

    fn[E] radio_group(name : String, options : Array[RadioOption[E]], selected_value : String, aria_label? : String) ->
    Node
    [E, String]

    Build a complete radio group from options.

    Parameters:
    • name: Group name (for form submission)
    • options: Array of RadioOption
    • selected_value: Currently selected value
    • aria_label: Accessible label for the group

    radio_native

    fn[E] radio_native(name : String, value : String, checked : Bool, disabled? : Bool, id? : String, children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a native radio input with label. Uses HTML native radio for better form integration.

    radio_option

    fn[E] radio_option(value : String, label : Array[
    Node
    [E, String]], disabled? : Bool) -> RadioOption[E]

    Create a radio option

    radiogroup

    fn[E] radiogroup(aria_label? : String, aria_labelledby? : String, children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a radio group container.

    Parameters:
    • aria_label: Accessible label for the group
    • aria_labelledby: ID of labelling element
    • children: Radio buttons (use radio() to create)

    radiogroup_interactive

    fn radiogroup_interactive(id : String, name : String, options : Array[RadioOption[
    Any
    ]], selected :
    Signal
    [String], aria_label? : String) ->
    Node
    [
    Any
    , String]

    Create a complete interactive radio group with keyboard navigation.

    Features:
    • Arrow key navigation (wraps)
    • Home/End navigation
    • Space selects
    • Roving tabindex

    Parameters:
    • id: Group container ID
    • name: Form field name
    • options: Array of RadioOption
    • selected: Signal for currently selected value
    • aria_label: Accessible label

    region

    fn[E] region(aria_label? : String, aria_labelledby? : String, children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a region landmark. A generic landmark that requires an accessible name. Use with aria-label or aria-labelledby.

    Parameters:
    • aria_label: Accessible label (required)
    • aria_labelledby: ID of labelling element (alternative to aria_label)
    • children: Region content

    Example:
    region(aria_label="Quick Stats", [text("...")])

    reset_id_counter

    fn reset_id_counter() -> Unit

    Reset the ID counter (useful for testing)

    restore_focus

    fn restore_focus(element :
    Any
    ) -> Unit

    Restore focus to a previously stored element. Call this when the dialog closes.
    fn[E] search(aria_label? : String, children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a search landmark. Contains search functionality. Use element (HTML5.2+) or role="search" on a form.

    Parameters:
    • aria_label: Accessible label (recommended when multiple search regions)
    • children: Search form content

    search_role

    fn[E] search_role(aria_label? : String, children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a search landmark using role attribute (fallback for older browsers).

    Parameters:
    • aria_label: Accessible label
    • children: Search form content

    simple_table

    fn[E] simple_table(id : String, caption_text? : String, headers : Array[String], rows : Array[Array[String]]) ->
    Node
    [E, String]

    Create a simple static table with caption.

    Parameters:
    • id: Table ID
    • caption_text: Caption text
    • headers: Header labels
    • rows: Array of row data (each row is an array of cell strings)

    slider

    fn[E] slider(value : Double, min? : Double, max? : Double, step? : Double, orientation? : SliderOrientation, aria_label? : String, aria_labelledby? : String, aria_valuetext? : String, on_keydown? :
    EventHandler
    [E], children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create an accessible slider.

    Parameters:
    • value: Current value
    • min: Minimum value (default: 0)
    • max: Maximum value (default: 100)
    • step: Step increment (optional, for data attribute)
    • orientation: Slider orientation
    • aria_label: Accessible label
    • aria_labelledby: ID of labelling element
    • aria_valuetext: Human-readable value
    • on_keydown: Keydown handler (for arrow key value changes)
    • children: Visual slider content

    slider_dyn

    fn[E] slider_dyn(value :
    Signal
    [Double], min? : Double, max? : Double, orientation? : SliderOrientation, aria_label? : String, aria_valuetext_fn? : (Double) -> String, on_keydown? :
    EventHandler
    [E], children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a dynamic slider with signal-based value.

    slider_interactive

    fn slider_interactive(value :
    Signal
    [Double], min? : Double, max? : Double, step? : Double, large_step? : Double, orientation? : SliderOrientation, aria_label? : String, aria_valuetext_fn? : (Double) -> String, children : Array[
    Node
    [
    Any
    , String]]) ->
    Node
    [
    Any
    , String]

    Create a slider with full keyboard and mouse support. Includes arrow key navigation, Home/End for min/max, PageUp/PageDown for large steps. Also supports click-to-position for mouse interaction.

    Parameters:
    • value: Signal containing the current value
    • min: Minimum value (default: 0)
    • max: Maximum value (default: 100)
    • step: Step increment (default: 1)
    • large_step: Large step for PageUp/PageDown (default: step * 10)
    • orientation: Slider orientation
    • aria_label: Accessible label
    • aria_valuetext_fn: Function to convert value to human-readable text
    • children: Visual slider content

    slider_native

    fn[E] slider_native(name : String, value : Double, min? : Double, max? : Double, step? : Double, aria_label? : String, id? : String) ->
    Node
    [E, String]

    Create a native HTML range input.

    spinbutton

    fn[E] spinbutton(value : Double, min? : Double, max? : Double, step? : Double, aria_label? : String, aria_labelledby? : String, aria_valuetext? : String, disabled? : Bool, is_readonly? : Bool, on_keydown? :
    EventHandler
    [E], on_input? :
    EventHandler
    [E]) ->
    Node
    [E, String]

    Create a basic spinbutton.

    Parameters:
    • value: Current numeric value
    • min: Minimum value (optional)
    • max: Maximum value (optional)
    • step: Step increment (default: 1)
    • aria_label: Accessible label
    • aria_labelledby: ID of labelling element
    • aria_valuetext: Human-readable value text
    • disabled: Whether the spinbutton is disabled
    • is_readonly: Whether the spinbutton is read-only
    • on_keydown: Keydown handler
    • on_input: Input handler for text changes

    spinbutton_dyn

    fn[E] spinbutton_dyn(value :
    Signal
    [Double], min? : Double, max? : Double, aria_label? : String, aria_valuetext_fn? : (Double) -> String, on_keydown? :
    EventHandler
    [E], on_input? :
    EventHandler
    [E]) ->
    Node
    [E, String]

    Create a dynamic spinbutton with signal-based value.

    spinbutton_interactive

    fn spinbutton_interactive(value :
    Signal
    [Double], min? : Double, max? : Double, step? : Double, large_step? : Double, aria_label? : String, aria_valuetext_fn? : (Double) -> String) ->
    Node
    [
    Any
    , String]

    Create a complete interactive spinbutton with increment/decrement buttons.

    Parameters:
    • value: Signal containing the current value
    • min: Minimum value
    • max: Maximum value
    • step: Step increment (default: 1)
    • large_step: Large step for PageUp/PageDown (default: step * 10)
    • aria_label: Accessible label
    • aria_valuetext_fn: Function to convert value to human-readable text

    spinbutton_native

    fn[E] spinbutton_native(name : String, value : Double, min? : Double, max? : Double, step? : Double, aria_label? : String, id? : String) ->
    Node
    [E, String]

    Create a native HTML number input. This is the simplest option when custom styling is not needed.

    status

    fn[E] status(type_? : AlertType, children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create an inline alert (status message). Uses role="status" for less urgent messages that don't require immediate attention. Screen readers announce these during a pause in user activity.

    Parameters:
    • type_: Alert type for styling
    • children: Alert content

    store_active_element

    fn store_active_element() ->
    Any

    Store the currently focused element for later restoration. Call this before opening the dialog.

    switch

    fn[E] switch(on : Bool, disabled? : Bool, aria_label? : String, aria_labelledby? : String, on_click? :
    EventHandler
    [E], on_keydown? :
    EventHandler
    [E], children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create an accessible switch.

    Parameters:
    • on: Whether the switch is on
    • disabled: Whether disabled
    • aria_label: Accessible label (should NOT change with state)
    • aria_labelledby: ID of labelling element
    • on_click: Click handler
    • on_keydown: Keydown handler (for Space/Enter toggle)
    • children: Switch label content

    switch_computed

    fn[E] switch_computed(on : () -> Bool, disabled? : Bool, aria_label? : String, on_click? :
    EventHandler
    [E], on_keydown? :
    EventHandler
    [E], children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a switch with computed state (accepts getter function). Useful for derived switch states.

    switch_dyn

    fn[E] switch_dyn(on :
    Signal
    [Bool], disabled? : Bool, aria_label? : String, on_click? :
    EventHandler
    [E], on_keydown? :
    EventHandler
    [E], children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a dynamic switch with signal-based state.

    switch_group

    fn[E] switch_group(aria_label? : String, children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a switch group.

    switch_interactive

    fn switch_interactive(on :
    Signal
    [Bool], disabled? : Bool, aria_label? : String, children : Array[
    Node
    [
    Any
    , String]]) ->
    Node
    [
    Any
    , String]

    Create a complete interactive switch with built-in keyboard support.

    Features:
    • Space and Enter toggle state
    • Click toggles state
    • Proper ARIA attributes

    Parameters:
    • on: Signal controlling switch state
    • disabled: Whether disabled
    • aria_label: Accessible label
    • children: Switch label content

    switch_native

    fn[E] switch_native(name : String, on : Bool, disabled? : Bool, id? : String, children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a switch using native checkbox with role="switch".

    tab

    fn[E] tab(id : String, selected : Bool, controls : String, on_click? :
    EventHandler
    [E], on_keydown? :
    EventHandler
    [E], children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a single tab button.

    Parameters:
    • id: Tab ID (used for aria-controls on the tab and id on the panel)
    • selected: Whether this tab is currently selected
    • controls: ID of the associated tabpanel
    • on_click: Click handler to activate the tab
    • on_keydown: Keydown handler (for arrow key navigation)
    • children: Tab label content

    tab_computed

    fn[E] tab_computed(id : String, selected : () -> Bool, controls : String, on_click? :
    EventHandler
    [E], on_keydown? :
    EventHandler
    [E], children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a tab with computed selected state (accepts getter function). This is useful when the selected state is derived from another signal. Example: tab_computed(id, fn() { active_tab.get() == 0 }, controls, children)

    tab_dyn

    fn[E] tab_dyn(id : String, selected :
    Signal
    [Bool], controls : String, on_click? :
    EventHandler
    [E], on_keydown? :
    EventHandler
    [E], children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a dynamic tab with signal-based selected state.

    tab_item

    fn[E] tab_item(id : String, label : String, panel : Array[
    Node
    [E, String]]) -> TabItem[E]

    Create a tab item

    table

    fn[E] table(id? : String, aria_label? : String, aria_labelledby? : String, aria_describedby? : String, children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a table container element.

    Parameters:
    • id: Table ID
    • aria_label: Accessible label
    • aria_labelledby: ID of labelling element
    • aria_describedby: ID of description element
    • children: Table content (thead, tbody, etc.)

    table_column

    fn table_column(id : String, label : String, sortable? : Bool) -> TableColumn

    Create a column definition

    table_interactive

    fn table_interactive(id : String, columns : Array[TableColumn], rows : Array[TableRow], aria_label? : String, selectable? : Bool, on_row_select? : (String) -> Unit, on_sort? : (String, SortDirection) -> Unit) ->
    Node
    [
    Any
    , String]

    Create a complete interactive data table.

    Parameters:
    • id: Table ID
    • columns: Column definitions
    • rows: Row data
    • aria_label: Accessible label
    • selectable: Whether rows are selectable
    • sortable: Whether columns are sortable
    • on_row_select: Called when a row is selected
    • on_sort: Called when sort changes

    table_row

    fn table_row(id : String, cells : Array[String], disabled? : Bool) -> TableRow

    Create a row definition

    tablist

    fn[E] tablist(aria_label? : String, orientation? : TabsOrientation, children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a complete tablist container.

    Parameters:
    • aria_label: Accessible label for the tab list
    • orientation: Horizontal or Vertical (default: Horizontal)
    • children: Tab buttons (use tab() to create)

    tabpanel

    fn[E] tabpanel(id : String, labelledby : String, hidden : Bool, children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a tabpanel.

    Parameters:
    • id: Panel ID (referenced by tab's aria-controls)
    • labelledby: ID of the associated tab (for aria-labelledby)
    • hidden: Whether the panel is hidden
    • children: Panel content

    tabpanel_computed

    fn[E] tabpanel_computed(id : String, labelledby : String, visible : () -> Bool, children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a tabpanel with computed visibility (accepts getter function). Uses style display instead of hidden attribute for proper visibility control.

    tabpanel_dyn

    fn[E] tabpanel_dyn(id : String, labelledby : String, visible :
    Signal
    [Bool], children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a dynamic tabpanel with signal-based visibility.

    tabs

    fn[E] tabs(items : Array[TabItem[E]], selected_index : Int, aria_label? : String, orientation? : TabsOrientation) ->
    Node
    [E, String]

    Build a complete tabs component from tab items. This is a convenience function that creates the full structure.

    Parameters:
    • items: Array of TabItem containing tab data
    • selected_index: Index of the currently selected tab
    • aria_label: Accessible label for the tabs
    • orientation: Tabs orientation

    tabs_dyn

    fn[E] tabs_dyn(items : Array[TabItem[E]], selected_index :
    Signal
    [Int], aria_label? : String, orientation? : TabsOrientation) ->
    Node
    [E, String]

    Build a dynamic tabs component with signal-based selection. This is the recommended way to create tabs with reactive state.

    Parameters:
    • items: Array of TabItem containing tab data
    • selected_index: Signal containing the currently selected tab index
    • aria_label: Accessible label for the tabs
    • orientation: Tabs orientation

    tabs_interactive

    fn tabs_interactive(items : Array[TabItem[
    Any
    ]], selected_index :
    Signal
    [Int], aria_label? : String, orientation? : TabsOrientation) ->
    Node
    [
    Any
    , String]

    Build a dynamic tabs component with full keyboard support. Includes arrow key navigation, Home/End support.

    Parameters:
    • items: Array of TabItem containing tab data
    • selected_index: Signal containing the currently selected tab index
    • aria_label: Accessible label for the tabs
    • orientation: Tabs orientation (affects which arrow keys to use)

    tbody

    fn[E] tbody(children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a table body section.
    fn[E] td(id? : String, headers? : String, children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a data cell.

    Parameters:
    • id: Cell ID
    • headers: Space-separated list of header IDs
    • children: Cell content

    tfoot

    fn[E] tfoot(children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a table footer section.
    fn[E] th(id? : String, scope? : String, sort? : SortDirection, on_click? :
    EventHandler
    [E], children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a column header cell.

    Parameters:
    • id: Header ID
    • scope: Scope (col, row, colgroup, rowgroup)
    • sort: Sort direction (for sortable columns)
    • on_click: Click handler (for sortable columns)
    • children: Header content

    th_dyn

    fn[E] th_dyn(id : String, scope : String, sort_column :
    Signal
    [String], sort_direction :
    Signal
    [SortDirection], on_click? :
    EventHandler
    [E], children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a dynamic column header with signal-based sort state.

    thead

    fn[E] thead(children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a table head section.

    toggle_button

    fn[E] toggle_button(pressed : ToggleState, disabled? : Bool, aria_label? : String, on_click? :
    EventHandler
    [E], on_keydown? :
    EventHandler
    [E], children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create an accessible toggle button. Toggle buttons have aria-pressed state.

    Parameters:
    • pressed: Current toggle state
    • disabled: Whether the button is disabled
    • aria_label: Accessible label
    • on_click: Click handler (should toggle the state)
    • on_keydown: Keydown handler (for custom keyboard interactions)
    • children: Child nodes (button content - should NOT change based on state)

    Note: The label should remain constant. Use aria-pressed to convey state.

    Example:
    toggle_button(Pressed, [@luna.text("Mute")])

    toggle_button_dyn

    fn[E] toggle_button_dyn(pressed :
    Signal
    [Bool], disabled? : Bool, aria_label? : String, on_click? :
    EventHandler
    [E], on_keydown? :
    EventHandler
    [E], children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Dynamic toggle button with signal-based pressed state. Uses dynamic aria-pressed attribute.

    toolbar

    fn[E] toolbar(aria_label? : String, aria_labelledby? : String, orientation? : ToolbarOrientation, children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a toolbar container.

    Parameters:
    • aria_label: Accessible label
    • aria_labelledby: ID of labelling element
    • orientation: Toolbar orientation (default: horizontal)
    • children: Toolbar items

    toolbar_interactive

    fn toolbar_interactive(id : String, items : Array[ToolbarItemDef], pressed_states :
    Signal
    [Map[String, Bool]], orientation? : ToolbarOrientation, aria_label? : String, on_item_click : (String, Bool) -> Unit) ->
    Node
    [
    Any
    , String]

    Create an interactive toolbar with keyboard navigation.

    Parameters:
    • id: Base ID for the toolbar
    • items: Array of toolbar item definitions
    • pressed_states: Signal containing map of item ID to pressed state
    • orientation: Toolbar orientation (default: horizontal)
    • aria_label: Accessible label
    • on_item_click: Called when an item is clicked (id, is_toggle)

    toolbar_item

    fn[E] toolbar_item(selected : Bool, pressed? : Bool, disabled? : Bool, on_click? :
    EventHandler
    [E], on_keydown? :
    EventHandler
    [E], children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a toolbar item (button).

    Parameters:
    • selected: Whether this item has tabindex=0 (roving tabindex)
    • pressed: For toggle buttons, the pressed state
    • disabled: Whether the item is disabled
    • on_click: Click handler
    • on_keydown: Keydown handler
    • children: Button content

    toolbar_item_def

    fn toolbar_item_def(id : String, label : String, toggle? : Bool, disabled? : Bool) -> ToolbarItemDef

    Create a toolbar item definition

    toolbar_item_dyn

    fn[E] toolbar_item_dyn(focused_index :
    Signal
    [Int], index : Int, pressed? : Bool, disabled? : Bool, on_click? :
    EventHandler
    [E], on_keydown? :
    EventHandler
    [E], children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a dynamic toolbar item with signal-based selection.

    toolbar_separator

    fn[E] toolbar_separator(orientation? : ToolbarOrientation) ->
    Node
    [E, String]

    Create a toolbar separator. Separators are purely visual and don't receive focus.

    tooltip

    fn[E] tooltip(id : String, children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a tooltip element.

    Parameters:
    • id: Tooltip ID (required, used for aria-describedby on trigger)
    • children: Tooltip content

    tooltip_dyn

    fn[E] tooltip_dyn(id : String, visible :
    Signal
    [Bool], children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a dynamic tooltip with signal-based visibility.

    tooltip_interactive

    fn tooltip_interactive(id : String, trigger_tag? : String, trigger_content : Array[
    Node
    [
    Any
    , String]], tooltip_content : Array[
    Node
    [
    Any
    , String]]) ->
    Node
    [
    Any
    , String]

    Create a complete interactive tooltip with focus/hover behavior.

    Features:
    • Shows on focus/mouseenter
    • Hides on blur/mouseleave
    • Escape key closes tooltip
    • Proper aria-describedby management

    Parameters:
    • id: Base ID
    • trigger_tag: Tag for trigger element (default: "button")
    • trigger_content: Content for trigger
    • tooltip_content: Content for tooltip

    tooltip_popup

    fn[E] tooltip_popup(id : String, visible : Bool, children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a tooltip that can be shown/hidden.

    Parameters:
    • id: Tooltip ID
    • visible: Whether tooltip is visible
    • children: Tooltip content

    tooltip_trigger

    fn[E] tooltip_trigger(tooltip_id : String, tag? : String, children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a trigger element that references a tooltip. Adds aria-describedby to the trigger.

    Parameters:
    • tooltip_id: ID of the tooltip element
    • tag: HTML tag for the trigger (default: "button")
    • children: Trigger content

    tooltip_with_trigger

    fn[E] tooltip_with_trigger(id : String, trigger_content : Array[
    Node
    [E, String]], tooltip_content : Array[
    Node
    [E, String]], visible : Bool) ->
    Node
    [E, String]

    Create a complete tooltip with trigger.

    Parameters:
    • id: Base ID for the tooltip
    • trigger_content: Content for the trigger element
    • tooltip_content: Content for the tooltip
    • visible: Whether tooltip is visible
    fn[E] tr(id? : String, selected? : Bool, on_click? :
    EventHandler
    [E], on_keydown? :
    EventHandler
    [E], children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a table row element.

    Parameters:
    • id: Row ID
    • selected: Whether row is selected
    • on_click: Click handler
    • on_keydown: Keydown handler
    • children: Cell elements

    tr_dyn

    fn[E] tr_dyn(id : String, selected_row :
    Signal
    [String], on_click? :
    EventHandler
    [E], on_keydown? :
    EventHandler
    [E], children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a dynamic table row with signal-based selection.

    tree

    fn[E] tree(id? : String, aria_label? : String, aria_labelledby? : String, multiselectable? : Bool, children : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create the tree container.

    Parameters:
    • id: Tree ID
    • aria_label: Accessible label
    • aria_labelledby: ID of labelling element
    • multiselectable: Whether multiple items can be selected
    • children: Tree items

    tree_interactive

    fn tree_interactive(id : String, nodes : Array[TreeNode], aria_label? : String, on_select : (String) -> Unit) ->
    Node
    [
    Any
    , String]

    Create a complete interactive tree view.

    Parameters:
    • id: Tree ID
    • nodes: Tree node data
    • aria_label: Accessible label
    • on_select: Called when a node is selected

    tree_node

    fn tree_node(id : String, label : String, children? : Array[TreeNode], disabled? : Bool) -> TreeNode

    Create a tree node

    treeitem

    fn[E] treeitem(id? : String, selected : Bool, expanded? : Bool, has_children : Bool, focused : Bool, disabled? : Bool, on_click? :
    EventHandler
    [E], on_keydown? :
    EventHandler
    [E], label_content : Array[
    Node
    [E, String]], children? : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a tree item (leaf node or branch node).

    Parameters:
    • id: Item ID
    • selected: Whether the item is selected
    • expanded: Whether the item is expanded (for parent nodes)
    • has_children: Whether this is a parent node
    • focused: Whether this item has tabindex=0
    • disabled: Whether the item is disabled
    • on_click: Click handler
    • on_keydown: Keydown handler
    • label_content: Content for the label
    • children: Child nodes (for parent nodes)

    treeitem_dyn

    fn[E] treeitem_dyn(id? : String, selected :
    Signal
    [String], item_id : String, expanded? :
    Signal
    [Map[String, Bool]], has_children : Bool, focused_id :
    Signal
    [String], disabled? : Bool, on_click? :
    EventHandler
    [E], on_keydown? :
    EventHandler
    [E], label_content : Array[
    Node
    [E, String]], children? : Array[
    Node
    [E, String]]) ->
    Node
    [E, String]

    Create a dynamic tree item with signal-based state.

    wrap_index

    fn wrap_index(current : Int, direction : Int, length : Int) -> Int

    Calculate next index for list navigation with wrapping