limn
    ↑↓ ChooseEnter OpenEsc Close
    GitHub

    Components/Overlays

    SuggestionList

    Completions floating over a text input while the user keeps typing: commands after a slash, mentions, file names. Focus stays in the input.

    Native componentGuide source

    Preview

    CodeSource
    fn view(state: &State, palette: ComponentPalette) -> Element {
        let items = state
            .matches
            .iter()
            .map(|command| {
                SuggestionItem::new(format!("complete={}", command.name), &command.name)
                    .icon(command.icon)
                    .description(&command.summary)
            })
            .collect();
        SuggestionList::new(
            TextField::new("prompt", &state.prompt, "Type / for commands", palette).render(),
            "prompt:options",
            items,
            state.selected,
            state.completing,
            "prompt:dismiss",
            palette,
        )
        .render()
    }
    
    fn update(state: &mut State, action: &UiAction) {
        if let UiAction::Clicked { id } = action {
            if id == "prompt:dismiss" {
                state.completing = false;
            } else if let Some(name) = id.strip_prefix("complete=") {
                state.accept(name);
            }
        }
    }

    Examples

    Each one is the library drawing it. Press, type and hover.

    Suggestion list2 / 2
    CodeSource
    row(vec![
        people(cx),
        Button::new("menus-mention=open", "Show", cx.palette).variant(ButtonVariant::Outline).render(),
    ])

    SuggestionList

    Completions floating over a text input while the user keeps typing: commands after a slash, mentions, file names. Focus stays in the input.

    Import

    use limn::{Component, SuggestionItem, SuggestionList};

    Usage

    The list wraps the input it completes, where the input is built. It is controlled, and it does not handle keys: the host moves selected_index on the arrow keys, accepts on Enter and closes on Escape. The list shows that state and reports clicks.

    fn view(state: &State, palette: ComponentPalette) -> Element {
        let items = state
            .matches
            .iter()
            .map(|command| {
                SuggestionItem::new(format!("complete={}", command.name), &command.name)
                    .icon(command.icon)
                    .description(&command.summary)
            })
            .collect();
        SuggestionList::new(
            TextField::new("prompt", &state.prompt, "Type / for commands", palette).render(),
            "prompt:options",
            items,
            state.selected,
            state.completing,
            "prompt:dismiss",
            palette,
        )
        .render()
    }
    
    fn update(state: &mut State, action: &UiAction) {
        if let UiAction::Clicked { id } = action {
            if id == "prompt:dismiss" {
                state.completing = false;
            } else if let Some(name) = id.strip_prefix("complete=") {
                state.accept(name);
            }
        }
    }

    The arguments are the anchor, an ID for the scrolling options, the items, the index of the selected one, whether the list is open, the dismiss ID and the palette. While closed, render returns the anchor alone.

    Items

    SuggestionItem::new("complete=/plan", "/plan")
        .icon(Icon::Plan)
        .description("Describe the steps before editing")
        .section("Commands")

    An item is a label over a description, after an optional icon. section starts a section at that item, with a heading on a row of its own above it: set it on the first item of each group.

    SuggestionItem::new("mention=@ada", "Ada Lovelace")
        .leading(avatar)
        .ink(role_color)
        .detail("ada")

    leading puts an element of the host’s in the icon’s place, such as a person’s avatar 24 across, centered at its own size. ink colors the label, such as in a role’s color; a disabled item stays muted. detail adds a quiet text at the end of the label’s line, such as a handle, and the label is cut before it. An item without a description shows its line in the middle of the row. The platform hears the detail after the description.

    Title, hints and note

    SuggestionList::new(anchor, "options", items, selected, open, "dismiss", palette)
        .title("Commands and templates")
        .hints(vec![Kbd::new("Enter", palette).caption("Accept").render()])
        .note("Results limited")
        .render()

    title is a muted line above the options, hints are elements under them that share a row and stack when the list is narrow, and note is a muted last line.

    Empty

    SuggestionList::new(anchor, "options", Vec::new(), 0, open, "dismiss", palette)
        .empty("No command matches.")
        .render()

    empty is what the list says in place of the options when there are none. The title, hints and note stay.

    Width and placement

    width(available) is the room the host can offer; the list is as wide as that allows, between 160 and 352. placement takes a PopoverPlacement; the list opens above the start of its anchor (TopStart) unless set. Rows are 42 high and at most seven show; the rest scroll, and only the rows in view are built.

    Disabled

    SuggestionItem::new("complete=/deploy", "/deploy").description("No remote configured").disabled()

    A disabled suggestion keeps its row with icon and label in muted ink and reports no click. It does not take the highlight, so the host’s selected_index should step over it.

    Motion

    The list appears and leaves with the motion tokens’ enter_ms and exit_ms. animation_ms(open, close) sets both, for a host that wants it quicker.

    Actions

    ActionWhen
    UiAction::Clicked { id } with an item’s IDThe item is clicked.
    UiAction::Clicked { id } with the dismiss IDThe pointer is pressed outside the list.

    Accessibility

    A suggestion is an item of a list named by its label, with its description said after it. It says whether it is the selected one, the row under the host’s highlight, and a disabled suggestion is there and cannot be used.

    API reference

    The guide covers composition, options and actions. Generate the complete Rust type and builder reference from the checkout:

    cargo doc -p limn --open

    Component API overview · State and actions

    The example is drawn by crates/limn-gallery/src/pages/menus.rs.