flutter_autocomplete 0.0.1
flutter_autocomplete: ^0.0.1 copied to clipboard
A reusable Flutter Autocomplete widget inspired by MUI's React Autocomplete.
flutter_autocomplete #
flutter_autocomplete is a mobile-first autocomplete package for Flutter.
The package focuses on:
- focused constructors instead of one giant widget API
- chip-based multiple selection that works with the virtual keyboard
- visual grouping that stays separate from selection logic
- creatable flows that generate typed values instead of selecting raw text
- no physical keyboard navigation
- no desktop shortcut handling
- no virtualized lists
Installation #
dependencies:
flutter_autocomplete: ^0.0.1
import 'package:flutter_autocomplete/flutter_autocomplete.dart';
Quick Start #
AutocompleteField<String>.single(
options: const ['Apple', 'Banana', 'Cherry'],
getOptionLabel: (option) => option,
decoration: const InputDecoration(
labelText: 'Fruit',
border: OutlineInputBorder(),
),
)
Validation #
All constructors integrate with Flutter Form and expose the standard form
hooks for their selection shape:
- single-value modes use
String? Function(T? value)? validator - multiple-value modes use
String? Function(List<T> values)? validator - all modes support
onSavedandautovalidateMode
final formKey = GlobalKey<FormState>();
Form(
key: formKey,
child: AutocompleteField<String>.multiple(
options: const ['Apple', 'Banana', 'Cherry'],
getOptionLabel: (option) => option,
validator: (values) {
if (values == null || values.isEmpty) {
return 'Pick at least one fruit';
}
return null;
},
decoration: const InputDecoration(
labelText: 'Fruits',
border: OutlineInputBorder(),
),
),
)
Constructor Guide #
All modes are exposed through explicit constructors:
AutocompleteField.single<T>()AutocompleteField.multiple<T>()AutocompleteField.async<T>()AutocompleteField.asyncMultiple<T>()
Mode Comparison #
| Constructor | Selection | Data Source | Creation |
|---|---|---|---|
single |
one value | sync list | optional via creatableConfig |
multiple |
many values | sync list | optional via creatableConfig |
async |
one value | async loader | optional via creatableConfig |
asyncMultiple |
many values | async loader | optional via creatableConfig |
Examples #
Single Select #
AutocompleteField<Movie>.single(
options: movies,
value: selectedMovie,
onChanged: (movie) => setState(() => selectedMovie = movie),
getOptionLabel: (movie) => movie.title,
decoration: const InputDecoration(
labelText: 'Movie',
border: OutlineInputBorder(),
),
)
Multiple Select #
AutocompleteField<String>.multiple(
options: const ['Apple', 'Banana', 'Cherry', 'Dragonfruit'],
values: selectedFruits,
onChanged: (values) => setState(() => selectedFruits = values),
getOptionLabel: (option) => option,
decoration: const InputDecoration(
labelText: 'Fruits',
border: OutlineInputBorder(),
),
)
Async #
AutocompleteField<String>.async(
asyncConfig: AutocompleteAsyncConfig(
optionsBuilder: repository.searchCities,
debounceDuration: const Duration(milliseconds: 250),
minQueryLength: 2,
),
getOptionLabel: (option) => option,
decoration: const InputDecoration(
labelText: 'City',
border: OutlineInputBorder(),
),
)
Grouping #
Grouping changes popup rendering only. It does not change selection, equality, or stored values.
AutocompleteField<City>.single(
options: cities,
getOptionLabel: (city) => city.name,
groupingConfig: AutocompleteGroupingConfig<City>(
groupBy: (city) => city.country,
sortGroups: true,
stickyHeaders: true,
),
)
Creatable rows are rendered outside groups, so the synthetic create action stays distinct from grouped options.
Custom Filtering #
AutocompleteField<Movie>.single(
options: movies,
getOptionLabel: (movie) => movie.title,
filterConfig: AutocompleteFilterConfig<Movie>(
matchFrom: AutocompleteMatchFrom.start,
limit: 20,
stringify: (movie) => '${movie.title} ${movie.director}',
),
)
When async results are already filtered by the server, provide filterOptions and return the input list unchanged.
Custom Rendering #
AutocompleteField<String>.multiple(
options: const ['Apple', 'Banana', 'Cherry'],
getOptionLabel: (option) => option,
renderingConfig: AutocompleteRenderingConfig<String>(
optionBuilder: (context, option) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 14),
child: Row(
children: [
Expanded(child: Text(option.label)),
if (option.isSelected) const Icon(Icons.check, size: 18),
],
),
);
},
),
)
Theming #
The package intentionally leans on Flutter theming primitives:
- use
InputDecorationfor the field container and labels - use
AutocompletePopupConfigfor popup size and surface styling - use
AutocompleteChipConfigfor chip spacing, limits, and delete affordances - use
AutocompleteRenderingConfigwhen you need fully custom rows or chips
AutocompleteChipConfig also supports focused-state tag limiting and capped
chip/input area growth:
limitTagsWhenFocusedkeepslimitTagsapplied while typingshowHiddenCountChipcontrols the+Nsummary indicatormaxInputAreaHeightenables internal scrolling past a height limit
Accessibility Notes #
- The package uses Flutter text field, chip, and tap semantics instead of web ARIA roles.
- Group headers are visual only.
- Creatable rows are explicit actions, not implicit raw-text selections.
- Validation errors render through the field
InputDecoration. - Keyboard shortcuts and arrow-key navigation are intentionally unsupported.
Mobile Behavior Notes #
- Tapping the field focuses the input.
- Tapping an option selects it.
- Tapping a creatable row creates a new typed value and selects it.
- Tapping outside the field closes the popup.
- The package is designed for virtual-keyboard-first layouts.
Layout Notes #
Multiple mode uses:
InputDecoratoras the outer field container- a
Wrapfor chips and the text input - a borderless inner
TextField
This allows:
- vertical growth instead of overflow
- label floating based on focus, chips, and input text
- tap-anywhere focusing
- mobile-friendly chip entry without
prefixorprefixIcon
No Keyboard Support #
This package does not implement:
- physical keyboard shortcuts
- arrow key navigation
- enter or escape handling
- home or end handling
- desktop-specific interaction patterns
- virtualized option rendering