Filter Pill
Filter pills are used to filter content or selections.
Filter Group
Section titled “Filter Group”The FilterGroup widget manages a set of filter options, supporting multi-selection and individual item colors.
Default Colors
Section titled “Default Colors”By default, the FilterGroup uses the theme’s default colors.
class FilterGroupDefaultExample extends StatefulWidget { @override State<FilterGroupDefaultExample> createState() => _FilterGroupDefaultExampleState();}
class _FilterGroupDefaultExampleState extends State<FilterGroupDefaultExample> { Set<String> _selectedGroup = {'Red', 'Green'};
@override Widget build(BuildContext context) { return FilterGroup<String>( items: [ FilterItem(value: 'Arm', label: const Text('Arm')), FilterItem(value: 'Base', label: const Text('Base')), FilterItem(value: 'Board', label: const Text('Board')), FilterItem(value: 'Sensor', label: const Text('Sensor')), const FilterItem(value: 'Servo', label: Text('Servo')), ], selected: _selectedGroup, onSelectionChanged: (newSelection) { setState(() { _selectedGroup = newSelection; }); }, ); }}Custom Colors
Section titled “Custom Colors”You can customize the color of each item by setting the activeColor property on the FilterItem.
class FilterGroupCustomExample extends StatefulWidget { @override State<FilterGroupCustomExample> createState() => _FilterGroupCustomExampleState();}
class _FilterGroupCustomExampleState extends State<FilterGroupCustomExample> { Set<String> _selectedGroup = {'Red', 'Green'};
@override Widget build(BuildContext context) { final theme = PrimeTheme.of(context); return FilterGroup<String>( items: [ FilterItem(value: 'Red', label: const Text('Red'), activeColor: theme.colorScheme.statusDangerDark), FilterItem(value: 'Orange', label: const Text('Orange'), activeColor: theme.colorScheme.statusWarningDark), FilterItem(value: 'Green', label: const Text('Green'), activeColor: theme.colorScheme.statusSuccessDark), FilterItem(value: 'Blue', label: const Text('Blue'), activeColor: theme.colorScheme.statusInfoDark), const FilterItem(value: 'Purple', label: Text('Purple'), activeColor: Color(0xFF9C27B0)), ], selected: _selectedGroup, onSelectionChanged: (newSelection) { setState(() { _selectedGroup = newSelection; }); }, ); }}Composite
Section titled “Composite”You can compose a FilterGroup with standalone FilterPill widgets to create complex toolbars. For example, you can add a search button next to the filters.
class FilterGroupCompositeExample extends StatefulWidget { @override State<FilterGroupCompositeExample> createState() => _FilterGroupCompositeExampleState();}
class _FilterGroupCompositeExampleState extends State<FilterGroupCompositeExample> { Set<String> _selectedSearch = {'Search'};
@override Widget build(BuildContext context) { return SingleChildScrollView( scrollDirection: Axis.horizontal, child: Row( children: [ FilterPill( label: const Icon(PrimeIcons.magnify), isSelected: _selectedSearch.contains('Search'), // give this pill custom funcitonality, such as search or making a bottom sheet appear. onTap: () => setState(() => _selectedSearch.contains('Search') ? _selectedSearch.remove('Search') : _selectedSearch.add('Search')), ), const SizedBox(width: 8), FilterGroup<String>( items: [ FilterItem(value: 'Arm', label: const Text('Arm')), FilterItem(value: 'Base', label: const Text('Base')), FilterItem(value: 'Board', label: const Text('Board')), FilterItem(value: 'Sensor', label: const Text('Sensor')), FilterItem(value: 'Servo', label: Text('Servo')), ], selected: _selectedSearch, onSelectionChanged: (newSelection) { setState(() { _selectedSearch = newSelection; }); }, ), ], ), ); }}A basic filter pill. Tap to toggle selection state.
class BasicToggleExample extends StatefulWidget { @override State<BasicToggleExample> createState() => _BasicToggleExampleState();}
class _BasicToggleExampleState extends State<BasicToggleExample> { bool _isSelected = false;
@override Widget build(BuildContext context) { return FilterPill( label: Text('Example'), isSelected: _isSelected, onTap: () => setState(() => _isSelected = !_isSelected), ); }}With Icon
Section titled “With Icon”Filter pills can include leading icons or be icon-only.
class IconToggleExample extends StatefulWidget { @override State<IconToggleExample> createState() => _IconToggleExampleState();}
class _IconToggleExampleState extends State<IconToggleExample> { bool _isSelected = false;
@override Widget build(BuildContext context) { return Row( mainAxisSize: MainAxisSize.min, spacing: 16, children: [ FilterPill( label: const Text('With Icon'), leading: const Icon(PrimeIcons.viamFlutter, size: 16), isSelected: _isSelected, onTap: () => setState(() => _isSelected = !_isSelected), ), FilterPill( label: const Icon(PrimeIcons.magnify, size: 20), isSelected: _isSelected, onTap: () => setState(() => _isSelected = !_isSelected), ), ], ); }}