super_tag_editor 1.0.1
super_tag_editor: ^1.0.1 copied to clipboard
A Flutter widget for editing and managing tags with auto-suggestions and Material-like behavior. Designed to feel natural with Gmail-style tag inputs.
π·οΈ Super Tag Editor #
A Flutter widget for editing and managing tags with a Material-style input experience.
Designed to act and feel like the standard TextField, but with additional features such as:
- π Suggestions box
- β Validation support
- π§± Customizable tag builder
- β‘ Debounced input and throttled callbacks

π Installation #
Add this line to your pubspec.yaml:
dependencies:
super_tag_editor: ^0.4.1
Then run:
flutter pub get
Import it:
import 'package:super_tag_editor/tag_editor.dart';
π§© Basic Usage #
TagEditor(
length: values.length,
delimiters: [',', ' '],
hasAddButton: true,
inputDecoration: const InputDecoration(
border: InputBorder.none,
hintText: 'Enter tags...',
),
onTagChanged: (newValue) {
setState(() {
values.add(newValue);
});
},
tagBuilder: (context, index) => _Chip(
index: index,
label: values[index],
onDeleted: onDelete,
),
suggestionBuilder: (context, state, data) => ListTile(
key: ObjectKey(data),
title: Text(data),
onTap: () {
state.selectSuggestion(data);
},
),
suggestionsBoxElevation: 10,
findSuggestions: (String query) {
// Example: implement your own search logic
return [];
},
)
π§± Custom Tag Builder #
You can customize how each tag looks by providing your own widget.
Below is an example using a Material Chip:
class _Chip extends StatelessWidget {
const _Chip({
required this.label,
required this.onDeleted,
required this.index,
});
final String label;
final ValueChanged<int> onDeleted;
final int index;
@override
Widget build(BuildContext context) {
return Chip(
labelPadding: const EdgeInsets.only(left: 8.0),
label: Text(label),
deleteIcon: const Icon(Icons.close, size: 18),
onDeleted: () => onDeleted(index),
);
}
}
π‘ Advanced Features #
| Feature | Description |
|---|---|
findSuggestions |
Returns async or sync list of suggestions. |
suggestionBuilder |
Custom widget builder for each suggestion item. |
onTagChanged |
Called whenever a new tag is added. |
onDeleteTagAction |
Callback when a tag is removed. |
debounce_throttle |
Built-in support for throttled input changes. |
pointer_interceptor |
Prevents UI overlaps with web platform overlays. |
π§ͺ Example App #
A complete working example is available under the example/ directory:
cd example
flutter run
Example preview:
import 'package:flutter/material.dart';
import 'package:super_tag_editor/tag_editor.dart';
void main() => runApp(const TagEditorExampleApp());
class TagEditorExampleApp extends StatefulWidget {
const TagEditorExampleApp({super.key});
@override
State<TagEditorExampleApp> createState() => _TagEditorExampleAppState();
}
class _TagEditorExampleAppState extends State<TagEditorExampleApp> {
final List<String> values = [];
void onDelete(int index) {
setState(() => values.removeAt(index));
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text('Super Tag Editor Example')),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: TagEditor(
length: values.length,
delimiters: [',', ' '],
hasAddButton: true,
inputDecoration: const InputDecoration(
border: InputBorder.none,
hintText: 'Enter tags...',
),
onTagChanged: (newValue) {
setState(() => values.add(newValue));
},
tagBuilder: (context, index) => _Chip(
index: index,
label: values[index],
onDeleted: onDelete,
),
suggestionBuilder: (context, state, data) => ListTile(
key: ObjectKey(data),
title: Text(data),
onTap: () => state.selectSuggestion(data),
),
suggestionsBoxElevation: 10,
findSuggestions: (String query) {
return ['flutter', 'dart', 'widget', 'state']
.where((tag) => tag.contains(query.toLowerCase()))
.toList();
},
),
),
),
);
}
}
class _Chip extends StatelessWidget {
const _Chip({
required this.label,
required this.onDeleted,
required this.index,
});
final String label;
final ValueChanged<int> onDeleted;
final int index;
@override
Widget build(BuildContext context) {
return Chip(
labelPadding: const EdgeInsets.only(left: 8.0),
label: Text(label),
deleteIcon: const Icon(Icons.close, size: 18),
onDeleted: () => onDeleted(index),
);
}
}
π§ Maintainer #
Developed and maintained by Dat X.
If you find this package helpful, please consider giving it a β on GitHub!
π License #
This project is licensed under the MIT License.
π§ Links #
π¬ βSuper Tag Editor makes handling tag inputs in Flutter effortless β it feels native, flexible, and intuitive.β
