Skip to content

Commit bcad33f

Browse files
committed
Added attribute maxChip to limit number of chips
1 parent e93fde1 commit bcad33f

File tree

8 files changed

+226
-134
lines changed

8 files changed

+226
-134
lines changed

.idea/libraries/Dart_Packages.xml

+14-6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/workspace.xml

+164-106
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md

+8-1
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,22 @@ Flutter library for building input fields with InputChips as input options.
77
### Installation
88
Follow installation instructions [here](https://pub.dartlang.org/packages/flutter_chips_input#-installing-tab-)
99

10-
### Example
10+
### Import
11+
```dart
12+
import 'package:flutter_chips_input/flutter_chips_input.dart';
1113
```
14+
15+
### Example
16+
#### ChipsInput
17+
```dart
1218
ChipsInput(
1319
initialValue: [
1420
AppProfile('John Doe', '[email protected]', 'https://d2gg9evh47fn9z.cloudfront.net/800px_COLOURBOX4057996.jpg')
1521
],
1622
decoration: InputDecoration(
1723
labelText: "Select People",
1824
),
25+
maxChips: 3,
1926
findSuggestions: (String query) {
2027
if (query.length != 0) {
2128
var lowercaseQuery = query.toLowerCase();
Binary file not shown.

example/ios/Runner.xcodeproj/project.pbxproj

-4
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88

99
/* Begin PBXBuildFile section */
1010
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
11-
2D5378261FAA1A9400D5DBA9 /* flutter_assets in Resources */ = {isa = PBXBuildFile; fileRef = 2D5378251FAA1A9400D5DBA9 /* flutter_assets */; };
1211
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
1312
3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; };
1413
3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
@@ -40,7 +39,6 @@
4039
/* Begin PBXFileReference section */
4140
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
4241
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
43-
2D5378251FAA1A9400D5DBA9 /* flutter_assets */ = {isa = PBXFileReference; lastKnownFileType = folder; name = flutter_assets; path = Flutter/flutter_assets; sourceTree = SOURCE_ROOT; };
4442
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
4543
3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = "<group>"; };
4644
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
@@ -73,7 +71,6 @@
7371
9740EEB11CF90186004384FC /* Flutter */ = {
7472
isa = PBXGroup;
7573
children = (
76-
2D5378251FAA1A9400D5DBA9 /* flutter_assets */,
7774
3B80C3931E831B6300D905FE /* App.framework */,
7875
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
7976
9740EEBA1CF902C7004384FC /* Flutter.framework */,
@@ -190,7 +187,6 @@
190187
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
191188
9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */,
192189
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
193-
2D5378261FAA1A9400D5DBA9 /* flutter_assets in Resources */,
194190
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
195191
);
196192
runOnlyForDeploymentPostprocessing = 0;

example/lib/main.dart

+2-1
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,8 @@ class _MyHomePageState extends State<MyHomePage> {
6767
AppProfile('John Doe', '[email protected]',
6868
'https://d2gg9evh47fn9z.cloudfront.net/800px_COLOURBOX4057996.jpg'),
6969
],
70-
enabled: false,
70+
enabled: true,
71+
maxChips: 2,
7172
decoration: InputDecoration(
7273
// prefixIcon: Icon(Icons.search),
7374
// hintText: formControl.hint,

lib/src/chips_input.dart

+27-12
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ typedef ChipsBuilder<T> = Widget Function(
99
BuildContext context, ChipsInputState<T> state, T data);
1010

1111
class ChipsInput<T> extends StatefulWidget {
12-
const ChipsInput({
12+
ChipsInput({
1313
Key key,
1414
this.initialValue = const [],
1515
this.decoration = const InputDecoration(),
@@ -19,7 +19,9 @@ class ChipsInput<T> extends StatefulWidget {
1919
@required this.findSuggestions,
2020
@required this.onChanged,
2121
this.onChipTapped,
22-
}) : super(key: key);
22+
this.maxChips,
23+
}) : assert(maxChips == null || initialValue.length <= maxChips),
24+
super(key: key);
2325

2426
final InputDecoration decoration;
2527
final bool enabled;
@@ -29,6 +31,7 @@ class ChipsInput<T> extends StatefulWidget {
2931
final ChipsBuilder<T> chipBuilder;
3032
final ChipsBuilder<T> suggestionBuilder;
3133
final List<T> initialValue;
34+
final int maxChips;
3235

3336
@override
3437
ChipsInputState<T> createState() => ChipsInputState<T>();
@@ -62,19 +65,29 @@ class ChipsInputState<T> extends State<ChipsInput<T>>
6265
_initFocusNode();
6366
this._suggestionsBoxController = _SuggestionsBoxController(context);
6467
this._suggestionsStreamController = StreamController<List<T>>.broadcast();
65-
66-
(() async {
67-
await this._initOverlayEntry();
68-
this._focusNode.addListener(_onFocusChanged);
69-
// in case we already missed the focus event
70-
if (this._focusNode.hasFocus) {
71-
this._suggestionsBoxController.open();
72-
}
73-
})();
7468
}
7569

7670
_initFocusNode() {
77-
this._focusNode = widget.enabled ? FocusNode() : AlwaysDisabledFocusNode();
71+
setState(() {
72+
debugPrint("Initializing focus node");
73+
if (widget.enabled) {
74+
if (widget.maxChips == null || _chips.length < widget.maxChips){
75+
this._focusNode = FocusNode();
76+
(() async {
77+
await this._initOverlayEntry();
78+
this._focusNode.addListener(_onFocusChanged);
79+
// in case we already missed the focus event
80+
if (this._focusNode.hasFocus) {
81+
this._suggestionsBoxController.open();
82+
}
83+
})();
84+
}
85+
else
86+
this._focusNode = AlwaysDisabledFocusNode();
87+
} else
88+
this._focusNode = AlwaysDisabledFocusNode();
89+
});
90+
debugPrint(this._focusNode.toString());
7891
}
7992

8093
void _onFocusChanged() {
@@ -160,6 +173,7 @@ class ChipsInputState<T> extends State<ChipsInput<T>>
160173
void selectSuggestion(T data) {
161174
setState(() {
162175
_chips.add(data);
176+
if (widget.maxChips != null) _initFocusNode();
163177
_updateTextInputState();
164178
_suggestions = null;
165179
_suggestionsStreamController.add(_suggestions);
@@ -173,6 +187,7 @@ class ChipsInputState<T> extends State<ChipsInput<T>>
173187
_chips.remove(data);
174188
_updateTextInputState();
175189
});
190+
if (widget.maxChips != null) _initFocusNode();
176191
widget.onChanged(_chips.toList(growable: false));
177192
}
178193
}

pubspec.lock

+11-4
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,13 @@ packages:
6060
url: "https://pub.dartlang.org"
6161
source: hosted
6262
version: "1.6.2"
63+
pedantic:
64+
dependency: transitive
65+
description:
66+
name: pedantic
67+
url: "https://pub.dartlang.org"
68+
source: hosted
69+
version: "1.4.0"
6370
quiver:
6471
dependency: transitive
6572
description:
@@ -78,7 +85,7 @@ packages:
7885
name: source_span
7986
url: "https://pub.dartlang.org"
8087
source: hosted
81-
version: "1.4.1"
88+
version: "1.5.3"
8289
stack_trace:
8390
dependency: transitive
8491
description:
@@ -106,14 +113,14 @@ packages:
106113
name: term_glyph
107114
url: "https://pub.dartlang.org"
108115
source: hosted
109-
version: "1.0.1"
116+
version: "1.1.0"
110117
test_api:
111118
dependency: transitive
112119
description:
113120
name: test_api
114121
url: "https://pub.dartlang.org"
115122
source: hosted
116-
version: "0.2.1"
123+
version: "0.2.2"
117124
typed_data:
118125
dependency: transitive
119126
description:
@@ -129,4 +136,4 @@ packages:
129136
source: hosted
130137
version: "2.0.8"
131138
sdks:
132-
dart: ">=2.0.0 <3.0.0"
139+
dart: ">=2.1.0 <3.0.0"

0 commit comments

Comments
 (0)