Skip to main content

SearchChipAppi

A powerful widget for displaying searchable and selectable chips with real-time filtering and form validation support.

Features

  • Real-time Search: Filter chips as you type
  • Single Selection: Select one chip from the list
  • Form Validation: Full form validation support
  • Dynamic Display: Shows chips in list or wrap layout based on search state
  • Read-only Mode: Selected chip becomes read-only with clear option
  • Customizable Styling: Custom text styles and colors
  • Responsive Layout: Adapts to content and screen size
  • Accessibility: Proper focus management and screen reader support

Usage

Basic Search Chip

SearchChipAppi(
widgetKey: GlobalKey<FormFieldState<String>>(),
list: ['Option 1', 'Option 2', 'Option 3', 'Option 4'],
height: 200,
selected: '',
onChanged: (selectedValue) {
print('Selected: $selectedValue');
},
)

Search Chip with Validation

SearchChipAppi(
widgetKey: _categoryKey,
list: categories,
height: 250,
selected: _selectedCategory,
heading: 'Select Category',
mandatory: true,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please select a category';
}
return null;
},
onChanged: (selectedValue) {
setState(() => _selectedCategory = selectedValue);
},
)

Styled Search Chip

SearchChipAppi(
widgetKey: _skillKey,
list: skillsList,
height: 300,
selected: _selectedSkill,
heading: 'Choose Your Skill',
textStyle: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w500,
),
textcolor: Colors.blue,
textsize: 14,
suffixIcon: Icon(Icons.search),
onChanged: (selectedValue) {
_updateSkill(selectedValue);
},
)

Parameters

NameTypeDescriptionDefault
widgetKeyGlobalKey<FormFieldState<String>>Required. Form field key for validation-
listList<String>Required. List of options to display as chips-
heightdoubleRequired. Height of the chip container-
selectedStringRequired. Currently selected value-
onChangedFunction(String)Required. Callback when selection changes-
headingString?Optional heading text above the fieldnull
labelString?Label for the search fieldnull
validatorString? Function(String?)?Validation functionnull
mandatorybool?Whether the field is required (shows asterisk)false
textStyleTextStyle?Style for the search field textnull
textcolorColor?Color for chip textnull
textsizedouble?Font size for chip textnull
suffixIconWidget?Icon to show in the search fieldnull

Behavior

Search Mode

  • When no selection is made, shows a search field
  • As you type, chips are filtered in real-time
  • Shows up to 20 chips initially, then switches to list view
  • Chips are displayed in a wrap layout for better space utilization

Selection Mode

  • Once a chip is selected, the search field becomes read-only
  • Shows the selected value in the field
  • Tap the field to clear selection and return to search mode
  • Selected chip is highlighted with primary color

Layout Modes

  • Wrap Layout: Used when not searching or for initial display
  • List Layout: Used when actively searching for better performance
  • Height Management: Automatically adjusts based on content and search state

Best Practices

  1. List Size: For large lists (>100 items), consider using pagination or virtualization
  2. Height Setting: Set appropriate height based on expected content
  3. Validation: Always provide validation for required fields
  4. Search Hints: Use clear labels and hints for better UX
  5. Performance: The widget automatically optimizes display for large lists
  6. Accessibility: Provide meaningful headings and labels

Examples

Category Selection

SearchChipAppi(
widgetKey: _categoryKey,
list: [
'Technology',
'Healthcare',
'Finance',
'Education',
'Entertainment',
'Sports',
'Travel',
'Food & Dining',
],
height: 200,
selected: _selectedCategory,
heading: 'Select Category',
mandatory: true,
validator: (value) => value?.isEmpty == true ? 'Category is required' : null,
onChanged: (category) {
setState(() => _selectedCategory = category);
_loadSubcategories(category);
},
)

Skills Selection

SearchChipAppi(
widgetKey: _skillKey,
list: [
'Flutter Development',
'React Native',
'iOS Development',
'Android Development',
'Web Development',
'Backend Development',
'UI/UX Design',
'Project Management',
],
height: 250,
selected: _selectedSkill,
heading: 'Primary Skill',
textStyle: TextStyle(
fontSize: 16,
color: Colors.black87,
),
suffixIcon: Icon(Icons.search, color: Colors.grey),
onChanged: (skill) {
setState(() => _selectedSkill = skill);
},
)

Form Integration

Form(
key: _formKey,
child: Column(
children: [
SearchChipAppi(
widgetKey: _industryKey,
list: industries,
height: 200,
selected: _selectedIndustry,
heading: 'Industry',
mandatory: true,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please select an industry';
}
return null;
},
onChanged: (industry) {
setState(() => _selectedIndustry = industry);
},
),
SizedBox(height: 20),
SearchChipAppi(
widgetKey: _experienceKey,
list: experienceLevels,
height: 150,
selected: _selectedExperience,
heading: 'Experience Level',
mandatory: true,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please select experience level';
}
return null;
},
onChanged: (experience) {
setState(() => _selectedExperience = experience);
},
),
SizedBox(height: 30),
ElevatedButton(
onPressed: () {
if (_formKey.currentState!.validate()) {
_submitForm();
}
},
child: Text('Submit'),
),
],
),
)

Large Dataset Example

SearchChipAppi(
widgetKey: _countryKey,
list: allCountries, // Large list of countries
height: 300,
selected: _selectedCountry,
heading: 'Select Country',
label: 'Search countries...',
suffixIcon: Icon(Icons.public),
onChanged: (country) {
setState(() => _selectedCountry = country);
_loadStates(country);
},
)

Custom Styled Example

SearchChipAppi(
widgetKey: _tagKey,
list: availableTags,
height: 180,
selected: _selectedTag,
heading: 'Choose Tag',
textStyle: TextStyle(
fontSize: 14,
fontWeight: FontWeight.w600,
color: Colors.indigo,
),
textcolor: Colors.white,
textsize: 12,
onChanged: (tag) {
_addTag(tag);
},
)

See Also