textual icon indicating copy to clipboard operation
textual copied to clipboard

Document Suggester in Input

Open willmcgugan opened this issue 1 year ago • 4 comments

The Input widget docs don't cover Suggesters, other than a reference in the API. It is such a useful feature I think it deserves a section with a simple demo.

willmcgugan avatar Aug 26 '24 18:08 willmcgugan

Yes this is very useful. Also some screenshots with visual examples will be great.

carloshm91 avatar Aug 26 '24 19:08 carloshm91

Could I suggest that something more simple and more generic be considered?

A watcher on input should be able to fire on one of two conditions: any change (key press, paste, cut) or any completion (blur or enter). A watcher should be able to be boolean (just disallow the changes) or return a pair with (optional new value, optional new renderable instead of just rendering the value). This allows for suggesters, regex validation, type ahead, complex highlighting like different parts of a url, complex validation like being sure the part number is in stock, and pretty much every use case.

A Suggester just becomes one of the watchers.

merriam avatar Sep 02 '24 23:09 merriam

Could you share a quick code snippet of what that might look like in a new discussion @merriam? I'm struggling to visualize it.

darrenburns avatar Sep 05 '24 07:09 darrenburns

Hi!

I was exploring the issues page when I found this thread and I came out with an example about a shopping list. At first I was trying to come up with something which used the Suggester instead of the SuggestFromList but I couldn't think of any use case that would fit in a simple example. I also thought that the most common use case would be to use a list as the source of the suggestion anyways.

from textual import on
from textual.app import App, ComposeResult
from textual.suggester import SuggestFromList
from textual.widgets import Input, Label, ListItem, ListView

products = [
    "milk",
    "eggs",
    "bread",
    "butter",
    "cheese",
    "fruits",
    "vegetables",
    "chicken",
]

class ShoppingListApp(App):
    def compose(self) -> ComposeResult:
        yield Input(
            placeholder="Product",
            suggester=SuggestFromList(suggestions=products, case_sensitive=False),
        )
        yield ListView()

    @on(Input.Submitted)
    def add_item_to_list(self, event: Input.Submitted) -> None:
        list_item = ListItem(Label(event.value))
        self.query_one(ListView).mount(list_item)


if __name__ == "__main__":
    app = ShoppingListApp()
    app.run()

dnlzrgz avatar Dec 08 '24 19:12 dnlzrgz