ComboBox
ComboBox combines a single-line editor with suggestions. It owns transient popup/highlight state; your application owns the complete TextEditingValue and the suggestion list.
Separate typing from selection
Section titled “Separate typing from selection”#include <huxerui/huxerui.h>
#include <cstddef>#include <string>#include <vector>
using namespace huxerui;
[[huxerui::composable]]View CityField() { auto value = UseState(TextEditingValue::FromText("")); const std::vector<std::string> cities{"Berlin", "Kyoto", "Lisbon"}; return ComboBox(value, cities) .Label("City") .OnChanged([value](const TextEditingValue& next) { value = next; }) .OnSelected([value](std::size_t, const TextEditingValue& next) { value = next; });}Typing emits OnChanged. Accepting a suggestion emits OnSelected(index, next_value) without also emitting OnChanged; handle both paths. Preserve the proposed selection and composition instead of reconstructing text-only values.
Supply the suggestions appropriate to the current query. The example deliberately offers a fixed short list; filtering, remote search, cancellation, and result ordering belong to the application.
Project domain items
Section titled “Project domain items”ComboBox(value, suggestions, text_factory, content_factory) separates the accepted string from row presentation. The text factory returns the item’s editable text; the content factory returns its row View. Give changing rows stable keys and keep row content free of competing interactive controls.
Declared by <huxerui/view.h>. The value accepts TextEditingValue or State<TextEditingValue>. Suggestions are an input range: read a State-held collection in composition and pass the collection, not a second editor-owned data store.
- Field configuration:
Label,Placeholder,LeadingIcon,TrailingIcon,Variant,Align,MaxLength,Validation, andInputConfiguration. EmptyContent(factory)supplies content when there are no suggestions.OnSubmitted(void())handles submission when it is not accepting an active suggestion.OnExpandedChanged(bool)observes popup changes; it is not a controlled visibility property.ComboBoxStyleowns theme appearance.
This is a single-line, non-secure editor. IME composition takes precedence over suggestion acceptance; do not intercept Enter blindly. For multiline or secure input use TextField; for a non-editable value use Select.
Configuration signatures
Section titled “Configuration signatures”| Operation | Accepted value and behavior |
|---|---|
Label, Placeholder |
StringVariant, including direct string resources. |
LeadingIcon, TrailingIcon |
ImageVariant; the trailing icon is decorative, not a separate action. |
Variant |
TextFieldVariant::Standard, Filled, or Outlined. |
Align |
TextAlign within the editable viewport. |
MaxLength |
std::size_t, counted in grapheme clusters for direct edits. |
Validation |
Complete ValidationResult; does not filter suggestions. |
InputConfiguration |
Complete TextInputConfiguration; multiline, secure, read-only, and newline-action settings are rejected. |
EmptyContent |
Nonempty std::function<View()> producing non-interactive empty-state content. |
Plain string-like suggestion ranges and initializer_list<StringVariant> use built-in text rows. Domain ranges use (value, range, text_factory, content_factory); the text factory must produce a StringVariant-compatible value and the content factory a View. Both forms accept a TextEditingValue or State-held value. Suggestion rows must not contain independent interactive controls.
Events, async suggestions, and empty results
Section titled “Events, async suggestions, and empty results”OnChanged takes const TextEditingValue&; OnSelected takes std::size_t and const TextEditingValue&; OnSubmitted takes no arguments; OnExpandedChanged takes bool. Every callback runs on the UI thread and is bound to the current declaration. Popup visibility/highlight belongs to the component, so ExpandedChanged is an observation rather than a setter to feed back.
For server suggestions, update the complete editing value immediately, cancel the old search through TaskScope, and publish results only for the current query. An empty suggestion list is valid; provide EmptyContent if an open result surface should explain “No matches.” Do not replace an in-progress IME composition with a suggestion simply because a request completed.
Field and popup styling
Section titled “Field and popup styling”The editor uses TextFieldStyle, including the chosen variant, caret, and validation. ComboBoxStyle owns only the popup: popup_background, foreground, active_item_background, item_padding, popup_padding, popup_shadow, minimum_item_height, maximum_popup_height, popup_corner_radii, and item_indication. The height limit bounds scrolling; it does not truncate the suggestion collection.

