Package: textual-autocomplete
textual-autocompletetextual-autocomplete is a Python library for creating dropdown autocompletion menus in
Textual applications, allowing users to quickly select from a list of suggestions as
they type.textual-autocomplete supportsTextual version 0.11.0and above.Video examplehttps://user-images.githubusercontent.com/5740731/205718330-a9364894-9133-40ca-8249-6e3dcc13f456.movWarningTextual still has a major version number of0, meaning there are still significant API changes happening which can sometimes impact this project.
I'll do my best to keep it compatible with the latest version of Textual, but there may be a slight delay between Textual releases and this library working with said release.QuickstartSimply wrap a TextualInputwidget as follows:fromtextual.appimportComposeResultfromtextual.widgetsimportInputfromtextual_autocompleteimportAutoComplete,Dropdown,DropdownItemdefcompose(self)->ComposeResult:yieldAutoComplete(Input(placeholder="Type to search..."),Dropdown(items=[DropdownItem("Glasgow"),DropdownItem("Edinburgh"),DropdownItem("Aberdeen"),DropdownItem("Dundee"),]),)There are more complete exampleshere.Installationtextual-autocompletecan be installed from PyPI using your favourite dependency
manager.UsageWrapping yourInputAs shown in the quickstart, you can wrap the Textual builtinInputwidget withAutoComplete, and supply aDropdown.
TheAutoCompletemanages communication between theInputand theDropdown.TheDropdownis the widget you see on screen, as you type into the input.TheDropdownItems contain up to 3 columns. All must contain a "main" column, which
is the central column used in the filtering. They can also optionally contain a left and right metadata
column.Supplying data toDropdownYou can supply the data for the dropdown via a list or a callback function.Using a listThe easiest way to use textual-autocomplete is to pass in a list ofDropdownItems,
as shown in the quickstart.Using a callableInstead of passing a list ofDropdownItems, you can supply a callback function
which will be called with the current input state. From this function, you should
return the list ofDropdownItemsyou wish to be displayed.Seeherefor a usage example.Keyboard controlPress the Up/Down arrow keys to navigate.Press Enter to select the item in the dropdown and fill it in.Press Tab to fill in the selected item, and move focus.Press Esc to hide the dropdown.Press the Up/Down arrow keys to force the dropdown to appear.StylingTheDropdownitself can be styled using Textual CSS.For more fine-grained control over styling, you can target the following CSS classes:.autocomplete--highlight-match: the highlighted portion of a matching item.autocomplete--selection-cursor: the item the selection cursor is on.autocomplete--left-column: the left metadata column, if it exists.autocomplete--right-column: the right metadata column, if it existsSince the 3 columns inDropdownItemsupport RichTextobjects, they can be styled dynamically.
Thecustom_meta.pyfile is an example of this, showing how the rightmost column is coloured dynamically based on the city population.Theexamples directorycontains multiple examples of custom styling.MessagesWhen you select an item in the dropdown, anAutoComplete.Selectedevent is emitted.You can declare a handler for this eventon_auto_complete_selected(self, event)to respond
to an item being selected.An item is selected when it's highlighted in the dropdown, and you press Enter or Tab.Pressing Enter simply fills the value in the dropdown, whilst Tab fills the value
and then shifts focus from the input.Other notestextual-autocomplete will create a new layer at runtime on theScreenthat theAutoCompleteis on. TheDropdownwill be rendered on this layer.The position of the dropdown is currently fixedbelowthe value entered into theInput. This means if yourInputis at the bottom of the screen, it's probably not going to be much use for now. I'm happy to discuss or look at PRs that offer a flag for having it float above.There's currently no special handling for when the dropdown meets the right-hand side of the screen.Do not applymarginto theDropdown. The position of the dropdown is updated by applying margin to the top/left of it.There's currently no debouncing support, but I'm happy to discuss or look at PRs for this.There are a few known issues/TODOs in the code, which will later be transferred to GitHub.Test coverage is currently non-existent - sorry!