diff --git a/lib/flutter_chips_input.dart b/lib/flutter_chips_input.dart index 3b2efd4b..cb2eb33b 100644 --- a/lib/flutter_chips_input.dart +++ b/lib/flutter_chips_input.dart @@ -1,3 +1,9 @@ +/// Provides a form input using chips with optional text completion. +/// +/// The primary widget of this library, `ChipsInput`, appears as a text field +/// which may contain multiple chips based on user input. It offers suggestions +/// based on user input as well as programmatic control over adding and removing +/// chips. library flutter_chips_input; export './src/chips_input.dart'; diff --git a/lib/src/chips_input.dart b/lib/src/chips_input.dart index 9d153f10..7e844cdd 100644 --- a/lib/src/chips_input.dart +++ b/lib/src/chips_input.dart @@ -8,8 +8,10 @@ import 'package:flutter/foundation.dart' show kIsWeb; import 'suggestions_box_controller.dart'; import 'text_cursor.dart'; +/// Return zero or more values that match the user input. typedef ChipsInputSuggestions = FutureOr> Function(String query); -typedef ChipSelected = void Function(T data, bool selected); + +/// Return a widget to represent the given value. typedef ChipsBuilder = Widget Function( BuildContext context, ChipsInputState state, T data); @@ -27,6 +29,17 @@ extension on TextEditingValue { int get replacementCharactersCount => replacementCharacters.length; } +/// Text field that may contain multiple input chips. +/// +/// Renders as a text field which will contain chips based on selections made by +/// the user. Through the use of `findSuggestions()` and `suggestionBuilder()` +/// the textual input from the user will be converted into a list of matching +/// chips from which the user may select. +/// +/// The `chipBuilder()` is used build widgets to represent the selected values. +/// +/// See the `ChipsInputState` class for functions to add and remove chips from +/// the widget in a programmatic fashion. class ChipsInput extends StatefulWidget { const ChipsInput({ Key? key, @@ -60,36 +73,93 @@ class ChipsInput extends StatefulWidget { super(key: key); final InputDecoration decoration; + + /// The style to be applied to the chip's label. final TextStyle? textStyle; + + /// If false, prevents editing of the values. final bool enabled; + + /// Function for producing suggested values based on text input. final ChipsInputSuggestions findSuggestions; + + /// Invoked any time chips are added, edited, or removed. final ValueChanged> onChanged; + + /// Function to produce a widget to show in the input field. final ChipsBuilder chipBuilder; + + /// Function to produce a widget to show in the suggestions overlay. final ChipsBuilder suggestionBuilder; + + /// List of inital values, if any. final List initialValue; + + /// Maximum number of chips to allow in the field. final int? maxChips; + + /// Maximum height for the suggestions overlay. final double? suggestionsBoxMaxHeight; + + /// Specify type of information for which to optimize the input control. final TextInputType inputType; + + /// How overflowing text should be handled. final TextOverflow textOverflow; + + /// Whether to hide the text being edited (e.g., for passwords). final bool obscureText; + + /// Whether to enable autocorrection. final bool autocorrect; + + /// What text to display in the text input control's action button. final String? actionLabel; + + /// What kind of action to request for the action button on the IME. final TextInputAction inputAction; + + /// The appearance of the keyboard. final Brightness keyboardAppearance; + + /// Whether this text field should focus itself if nothing else is already + /// focused. final bool autofocus; + + /// Scroll the parent to make the input field visible, if true. final bool ensureVisible; + + /// If true, allow editing a chip value. final bool allowChipEditing; + + /// Passed to `Material` as the `elevation` value for the overlay. final double suggestionsBoxElevation; + + /// Decoration for the suggestions overlay. final BoxDecoration suggestionsBoxDecoration; + + /// Defines the keyboard focus for this widget. final FocusNode? focusNode; + + /// Set of values to suggest when field first receives focus. final List? initialSuggestions; + + /// If true, show the keyboard when the field receives the focus. final bool showKeyboard; + + /// Configures how the platform keyboard will select an uppercase or lowercase + /// keyboard. final TextCapitalization textCapitalization; @override ChipsInputState createState() => ChipsInputState(); } +/// Represents the state of the chips input widget. +/// +/// You may use the `selectSuggestion()` and `deleteChip()` functions to add or +/// remove chips from the input field. This can be used when combining +/// `ChipsInput` with other widgets, such as a drop-down selector. class ChipsInputState extends State> with TextInputClient { Set _chips = {}; List? _suggestions; @@ -194,7 +264,7 @@ class ChipsInputState extends State> with TextInputClient { renderBoxOffset.dy - size.height; var suggestionBoxHeight = max(topAvailableSpace, bottomAvailableSpace); - if (null != widget.suggestionsBoxMaxHeight) { + if (widget.suggestionsBoxMaxHeight != null) { suggestionBoxHeight = min(suggestionBoxHeight, widget.suggestionsBoxMaxHeight!); } @@ -254,6 +324,7 @@ class ChipsInputState extends State> with TextInputClient { ); } + /// Add the provided value to the list of values in the widget. void selectSuggestion(T data) { if (!_hasReachedMaxChips) { setState(() => _chips = _chips..add(data)); @@ -275,6 +346,7 @@ class ChipsInputState extends State> with TextInputClient { } } + /// Remove the chip that represents the given value, if any. void deleteChip(T data) { if (widget.enabled) { setState(() => _chips.remove(data)); diff --git a/lib/src/suggestions_box_controller.dart b/lib/src/suggestions_box_controller.dart index 157d55eb..d2b3fec1 100644 --- a/lib/src/suggestions_box_controller.dart +++ b/lib/src/suggestions_box_controller.dart @@ -19,7 +19,6 @@ class SuggestionsBoxController { } void close() { - // debugPrint("Closing suggestion box"); if (!_isOpened) return; assert(overlayEntry != null); overlayEntry!.remove();