super_auto_suggestion_box 1.5.0 copy "super_auto_suggestion_box: ^1.5.0" to clipboard
super_auto_suggestion_box: ^1.5.0 copied to clipboard

Super Auto Suggestion Box is a GeniusLink Flutter package providing a typeahead/combobox with local and remote sources, fuzzy matching, single or multi-select, free-text entry, progressive fallback, i [...]

super_auto_suggestion_box #

style: flutter_lints

super_auto_suggestion_box provides the GeniusLink SuperAutoSuggestionsBox<T>: a themed typeahead / combobox with local and remote sources, fuzzy matching, single- and multi-select, free-text entry, progressive remote fallback, server-side paging, recents, inline create, shadow-hint completion, record binding, read-only/fixable states, advanced search, validation, and bare embedding.

Version 1.5.0 keeps raw T values as the public data model, consolidates suggestion row construction into SuperAutoSuggestionsItem<T>(...), and finishes the Super prefix migration for public presentation/widget classes. The validator still receives the selected raw T?, and onSelectionChanged remains the selection callback for both select and de-select operations.

Every SuperAutoSuggestionsBox<T> requires a SuperAutoSuggestionsSource<T>. Use SuperAutoSuggestionSources.list<T>(values) for a local collection. Initial multi-select values belong to SuperAutoSuggestionsController.initialSelected; query, recents, and multi-select configuration belong to the widget.

SuperAutoSuggestionsItem<T> suggestionBuilder(
  List<T> items,
  int index,
  T element,
)

SuperAutoSuggestionsItem<T> remains public because builders return it, but callers no longer wrap every collection item, fetch result, selected item, recent item, or created item in SuperAutoSuggestionsItem<T>.

Setup #

dependencies:
  super_auto_suggestion_box: ^1.5.0
import 'package:super_auto_suggestion_box/super_auto_suggestion_box.dart';

final typography = SuperTextTheme();

MaterialApp(
  theme: SuperMaterialThemeData.light(
    textTheme: typography,
    primaryTextTheme: typography,
  ),
  darkTheme: SuperMaterialThemeData.dark(
    textTheme: typography,
    primaryTextTheme: typography,
  ),
  localizationsDelegates: const [
        // ...
        SuperAutoSuggestionsTranslation.delegate,
      ],
  supportedLocales:
      SuperAutoSuggestionsTranslation.delegate.supportedLocales,
);

Basic Usage #

final units = ['each', 'box', 'carton'];

SuperAutoSuggestionsItem<String> unitSuggestion(
  List<String> items,
  int index,
  String unit,
) => SuperAutoSuggestionsItem<String>(
  value: unit,
  titleText: unit,
);

final box = SuperAutoSuggestionsController<String>(
  allowFreeText: true,
);

SuperAutoSuggestionsBox<String>(
  controller: box,
  source: SuperAutoSuggestionSources.list<String>(units),
  suggestionBuilder: unitSuggestion,
  hintText: 'Type or pick...',
  onSelectionChanged: (selected) {
    final unit = selected.isEmpty ? null : selected.last;
    // unit is the selected raw String?, or null after de-selection.
  },
);

You can omit the controller, but the source remains required:

SuperAutoSuggestionsBox<String>(
  source: SuperAutoSuggestionSources.list<String>(units),
  suggestionBuilder: unitSuggestion,
  onSelectionChanged: (selected) {},
);

Rich Rows #

Keep domain data raw and derive row metadata in the builder:

final accounts = ['1010', '1020', '4000'];

SuperAutoSuggestionsItem<String> accountSuggestion(
  List<String> items,
  int index,
  String code,
) => SuperAutoSuggestionsItem<String>(
  value: code,
  titleText: switch (code) {
    '1010' => 'Cash on Hand',
    '1020' => 'Bank - Operating',
    '4000' => 'Sales Revenue',
    _ => code,
  },
  descriptionText: 'Account $code',
  trailingText: code == '1020' ? '285,120.50' : null,
  group: code.startsWith('1') ? 'Assets' : 'Income',
  iconData: Icons.account_balance_outlined,
  keywords: [code],
);

Custom rows receive both the raw item and the built suggestion:

SuperAutoSuggestionsBox<String>(
  source: SuperAutoSuggestionSources.list<String>(accounts),
  suggestionBuilder: accountSuggestion,
  itemBuilder: (context, code, suggestion, highlighted) {
    return Text('${suggestion.displayText} ($code)');
  },
);

Custom supporting widgets now use the same constructor. titleText remains the canonical searchable and committed title:

SuperAutoSuggestionsItem<String>(
  value: '1020',
  titleText: 'Bank - Operating',
  description: const Text('1020 - Current Assets'),
  trailing: const Chip(label: Text('Active')),
  icon: const Icon(Icons.account_balance_outlined),
);

descriptionText, trailingText, and iconData remain available when custom widgets are not needed. Suggestions can also carry an optional Stream? enabledSnapshot alongside the immediate enabled boolean.

Suggestion Sources #

All built-in sources accept raw values and source-specific matching or fetch configuration only. Pass suggestionBuilder to SuperAutoSuggestionsBox; it owns the conversion to SuperAutoSuggestionsItem<T> for both widget-created and external controllers.

final staticSource = SuperAutoSuggestionSources.list<String>(accounts);

final fuzzySource = SuperAutoSuggestionSources.fuzzy<String>(accounts);

final asyncSource = SuperAutoSuggestionSources.async<String>(
  (query) => api.searchAccounts(query), // Future<List<String>>
  initialItems: accounts.take(5).toList(),
);

final hybridSource = SuperAutoSuggestionSources.hybrid<String>(
  initialItems: accounts,
  fetch: (query) => api.searchAccounts(query), // Future<List<String>>
  remoteThreshold: 1,
  remoteMinChars: 2,
);

final remoteFallbackSource = SuperAutoSuggestionSources.remoteFallback<String>(
  initialItems: accounts,
  fetch: (query) => api.searchAccounts(query), // Future<List<String>>
  remoteThreshold: 5,
  remoteMinChars: 1,
);

final pagedSource = SuperAutoSuggestionSources.paged<String>(
  (query, page) async {
    final response = await api.searchAccountsPage(query, page);
    return SuperSuggestionsPage<String>(
      items: response.codes,
      hasMore: response.hasMore,
    );
  },
  resolveFrom: accounts,
);

SuperAutoSuggestionSources.strings(values) is still available for the simple label-equals-value case. The source itself does not take a builder; the widget owns the suggestionBuilder.

Concrete Source Classes #

The factory methods above return these public implementations:

Factory Concrete source
list / strings / fuzzy SuperAutoListSuggestionsSource<T>
async SuperAutoAsyncSuggestionsSource<T>
hybrid SuperAutoHybridSuggestionsSource<T>
remoteFallback SuperAutoRemoteFallbackSuggestionsSource<T>
paged SuperAutoPagedSuggestionsSource<T>

Prefer SuperAutoSuggestionSources for normal construction. Instantiate a concrete source directly only when its public source-specific API is needed. The pre-1.2.0 concrete class names are no longer canonical.

Presentation Widget Names #

The canonical public presentation/widget types now all use the Super prefix: SuperAutoSuggestionsBoxThemeData, SuperAutoSuggestionsBoxFocusedStyle, SuperAutoSuggestionsHighlight, and SuperAutoSuggestionsPanel<T>. Deprecated typedefs preserve the 1.2.x names during migration.

Controller API #

Controller selections, result lists, recents, and callbacks use raw values:

final controller = SuperAutoSuggestionsController<String>(
  initialValue: '1020',
  initialSelected: const ['1010'],
);

controller.selected;          // String?
controller.results;           // List<String>
controller.selectedItems;     // List<String>
controller.selectedValues;    // List<String>, compatibility alias
controller.recents;           // List<String>

controller.select('1010');
controller.toggleSelected('4000');
controller.setSelectedItems(['1010', '4000']);
controller.setRecents(['1020']);
controller.selectByValue('4000');

When using an external controller, provide the source and builder on the widget. The controller owns interaction state, not suggestion data or row presentation:

SuperAutoSuggestionsBox<String>(
  controller: controller,
  source: staticSource,
  suggestionBuilder: accountSuggestion,
  showRecents: true,
  initialRecents: const ['4000'],
  onRecentsChanged: (recentCodes) {},
);

After the controller is attached to an SuperAutoSuggestionsBox, UI metadata is available through the render-facing accessors:

controller.suggestions;            // List<SuperAutoSuggestionsItem<String>>
controller.suggestionAt(0);        // SuperAutoSuggestionsItem<String>
controller.highlightedSuggestion;  // SuperAutoSuggestionsItem<String>?
controller.selectedSuggestion;     // SuperAutoSuggestionsItem<String>?

Selection Callback #

onSelectionChanged fires after every selection mutation. Single-select emits [item] on selection and [] on de-selection; multi-select emits the complete selected list.

SuperAutoSuggestionsBox<String>(
  source: SuperAutoSuggestionSources.list<String>(accounts),
  suggestionBuilder: accountSuggestion,
  multiSelect: true,
  onSelectionChanged: (codes) {},
);

Inline create returns a raw value:

SuperAutoSuggestionsBox<String>(
  source: SuperAutoSuggestionSources.list<String>(vendors),
  suggestionBuilder: vendorSuggestion,
  onCreate: (query) async {
    final vendor = await api.createVendor(query);
    return vendor.id; // raw String
  },
  onSelectionChanged: (vendorIds) {},
);

ERP Input And Validation #

SuperAutoSuggestionsBox<T> participates in an enclosing Form through FormField<T>. Its validator receives the selected raw T?, not the query text. Keep a controller when form submission needs to read the selected value. When autovalidateMode is omitted, the box inherits the nearest Form.autovalidateMode before falling back to AutovalidateMode.disabled.

final documentController = SuperAutoSuggestionsController<String>();

Form(
  key: formKey,
  autovalidateMode: AutovalidateMode.onUserInteraction,
  child: SuperAutoSuggestionsBox<String>(
    controller: documentController,
    source: SuperAutoSuggestionSources.list<String>(documentReferences),
    suggestionBuilder: documentSuggestion,
    decoration: const InputDecoration(
      labelText: 'Document Reference',
      helperText: 'Pick a document reference',
    ),
    keyboardType: TextInputType.text,
    inputFormatters: [
      FilteringTextInputFormatter.allow(RegExp(r'[A-Za-z0-9-]')),
      LengthLimitingTextInputFormatter(16),
    ],
    textDirection: TextDirection.ltr,
    textInputAction: TextInputAction.done,
    showShadowHint: true,
    completeShadowHintOnTab: true,
    required: true,
    validator: (value) {
      if (value == null) return null; // `required` handles the empty selection.
      return documentReferences.contains(value)
          ? null
          : 'Pick a document from the list';
    },
    onSelectionChanged: (selected) {},
  ),
);

if (formKey.currentState!.validate()) {
  final savedDocumentReference = documentController.selected;
}

Validation errors surface through the suffix error badge tooltip, matching the GeniusLink form-field convention. For direct form-field access, controller formFieldKey is now GlobalKey<FormFieldState<T>>?.

Use validationPosition to choose where validation appears: ValidationPosition.suffixIcon shows the error badge in the field suffix, ValidationPosition.underBox shows error text under the box, and ValidationPosition.labelTrailing shows the error badge at the end of the label row. When omitted, the box uses SuperFormField.validationPosition; when that is also null, mobile defaults to under-box text and larger screens default to label-trailing badges.

Use helpIcon to add a custom help affordance at the end of the label row:

SuperAutoSuggestionsBox<String>(
  source: SuperAutoSuggestionSources.list<String>(accounts),
  suggestionBuilder: accountSuggestion,
  decoration: const InputDecoration(labelText: 'Posting account'),
  helpIcon: const Tooltip(
    message: 'Used by journal posting and reports.',
    child: Icon(Icons.help_outline_rounded, size: 18),
  ),
);

For keyboard traversal, a single-select field with textInputAction: TextInputAction.next moves focus to the next focusable field immediately after an item is selected. Multi-select fields keep focus in the current suggestions field.

States And Embedding #

  • disabled: dims and blocks interaction.
  • readOnly: blocks interaction but keeps full contrast for posted/review states.
  • allowFixed: shows a lock/unlock action backed by controller.isFixed.
  • advancedSearch: opens a larger search surface with Ctrl/Cmd + F.
  • bare: removes outer chrome for table cells and compact host surfaces.
  • restoreOnBlur: restores the last committed raw value when the user leaves without picking.

Migration #

See migration_1.1.0_to_1.2.0.md for the generic validator, FormField<T> integration, removed callbacks, source-name migrations, localization, TextInputAction.next, and onSelectionChanged behavior. For earlier migrations, see migration_1.0.0_to_1.1.0.md and migration_0.14.0_to_1.0.0.md.

Localization #

The package ships English and Arabic translations using flutter_localizations, intl, and generated intl_utils delegates. Register the package helpers on your app:

MaterialApp(
  localizationsDelegates: const [
        // ...
        SuperAutoSuggestionsTranslation.delegate,
      ],
  supportedLocales:
      SuperAutoSuggestionsTranslation.delegate.supportedLocales,
)

Built-in package strings such as the required-field message, loading/search states, Recent group label, inline-create text, fixed/unfixed tooltips, and Advanced Search chrome follow the active locale. Explicit custom strings passed to the widget continue to take precedence. Registration is optional: when no SuperAutoSuggestionsTranslation is available in the widget tree, package widgets fall back to the built-in English localization.

1
likes
140
points
617
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Super Auto Suggestion Box is a GeniusLink Flutter package providing a typeahead/combobox with local and remote sources, fuzzy matching, single or multi-select, free-text entry, progressive fallback, infinite scroll, recent suggestions, inline creation, shadow-hint completion, record binding, read-only and fixable modes, controller-driven focus/form wiring, advanced search, bare embedding, and shared core theming. Supports light/dark themes, LTR, and RTL.

Homepage
Repository (GitHub)
View/report issues

Topics

#flutter #widget #autocomplete #typeahead #combobox

License

MIT (license)

Dependencies

flutter, flutter_localizations, intl, super_core, super_form_field

More

Packages that depend on super_auto_suggestion_box