Tile
Select Tile Group
A group of tiles that allow users to make a selection from a set of options.
For desktop, a select group is generally recommended over this.
1enum Sidebar { recents, home, applications }23class SelectTileGroupExample extends StatelessWidget {4 @override5 Widget build(BuildContext _) => FSelectTileGroup<Sidebar>(6 control: const .managed(initial: {.recents}),7 label: const Text('Sidebar'),8 description: const Text('These will be shown in the sidebar.'),9 children: const [10 .tile(11 title: Text('Recents'),12 suffix: Icon(FIcons.timer),13 value: .recents,14 ),15 .tile(title: Text('Home'), suffix: Icon(FIcons.house), value: .home),16 .tile(17 title: Text('Applications'),18 suffix: Icon(FIcons.appWindowMac),19 value: .applications,20 ),21 ],22 );23}24CLI
To generate and customize this style:
dart run forui style create select-tile-groupUsage
FSelectTileGroup(...)
1FSelectTileGroup<String>(2 style: const .delta(dividerWidth: 1),3 enabled: true,4 divider: .indented,5 children: const [6 .tile(title: Text('Apple'), value: 'apple'),7 .tile(title: Text('Banana'), value: 'banana'),8 .tile(title: Text('Cherry'), value: 'cherry'),9 ],10)FSelectTileGroup.builder(...)
1FSelectTileGroup<String>.builder(2 style: const .delta(dividerWidth: 1),3 enabled: true,4 divider: .indented,5 tileBuilder: (context, index) =>6 FSelectTile(title: Text('Item $index'), value: 'item_$index'),7 count: 10,8)FSelectTile(...)
1FSelectTile<String>(2 style: const .delta(margin: .zero),3 enabled: true,4 value: 'apple',5 title: const Text('Apple'),6 subtitle: const Text('A red fruit'),7 details: const Text(r'$1.99'),8 checkedIcon: const Icon(FIcons.check),9 uncheckedIcon: null,10 suffix: null,11)FSelectTile.suffix(...)
1FSelectTile<String>.suffix(2 style: const .delta(margin: .zero),3 enabled: true,4 value: 'apple',5 title: const Text('Apple'),6 subtitle: const Text('A red fruit'),7 details: const Text(r'$1.99'),8 checkedIcon: const Icon(FIcons.check),9 uncheckedIcon: null,10 prefix: null,11)Examples
Behavior
Scrollable
1enum Sidebar { recents, home, applications }23class ScrollableSelectTileGroupExample extends StatelessWidget {4 @override5 Widget build(BuildContext _) => FSelectTileGroup<Sidebar>(6 control: const .managed(initial: {.recents}),7 label: const Text('Sidebar'),8 description: const Text('These will be shown in the sidebar.'),9 maxHeight: 100,10 children: const [11 .tile(12 title: Text('Recents'),13 suffix: Icon(FIcons.timer),14 value: .recents,15 ),16 .tile(title: Text('Home'), suffix: Icon(FIcons.house), value: .home),17 .tile(18 title: Text('Applications'),19 suffix: Icon(FIcons.appWindowMac),20 value: .applications,21 ),22 ],23 );24}25Lazy Scrollable
1@override2Widget build(BuildContext _) => FSelectTileGroup.builder(3 control: const .managed(initial: {1}),4 label: const Text('Applicable values'),5 maxHeight: 200,6 tileBuilder: (context, index) =>7 .tile(title: Text('Tile $index'), value: index),8);9Multi-value Form
1enum Language { dart, java, rust, python }23class SelectTileGroupMultiValueExample extends StatefulWidget {4 @override5 State<SelectTileGroupMultiValueExample> createState() =>6 _SelectTileGroupMultiValueExampleState();7}89class _SelectTileGroupMultiValueExampleState10 extends State<SelectTileGroupMultiValueExample> {11 final _key = GlobalKey<FormState>();1213 @override14 Widget build(BuildContext _) => Form(15 key: _key,16 child: Column(17 mainAxisAlignment: .center,18 crossAxisAlignment: .start,19 spacing: 20,20 children: [21 FSelectTileGroup<Language>(22 label: const Text('Favorite Languages'),23 description: const Text('Your favorite language.'),24 validator: (values) => (values?.isEmpty ?? true)25 ? 'Please select at least one language.'26 : null,27 children: const [28 .tile(title: Text('Dart'), value: .dart),29 .tile(title: Text('Java'), value: .java),30 .tile(title: Text('Rust'), value: .rust),31 .tile(title: Text('Python'), value: .python),32 ],33 ),34 FButton(35 child: const Text('Save'),36 onPress: () {37 if (!_key.currentState!.validate()) {38 // Handle errors here.39 return;40 }4142 _key.currentState!.save();43 // Do something.44 },45 ),46 ],47 ),48 );49}50Radio Form
1enum Notification { all, direct, nothing }23class SelectTileGroupRadioExample extends StatefulWidget {4 @override5 State<SelectTileGroupRadioExample> createState() =>6 _SelectTileGroupRadioExampleState();7}89class _SelectTileGroupRadioExampleState10 extends State<SelectTileGroupRadioExample> {11 final _key = GlobalKey<FormState>();1213 @override14 Widget build(BuildContext _) => Form(15 key: _key,16 child: Column(17 mainAxisAlignment: .center,18 crossAxisAlignment: .start,19 spacing: 20,20 children: [21 FSelectTileGroup<Notification>(22 control: const .managedRadio(),23 label: const Text('Notifications'),24 description: const Text('Select the notifications.'),25 validator: (values) =>26 values?.isEmpty ?? true ? 'Please select a value.' : null,27 children: const [28 .tile(title: Text('All new messages'), value: .all),29 .tile(title: Text('Direct messages and mentions'), value: .direct),30 .tile(title: Text('Nothing'), value: .nothing),31 ],32 ),33 FButton(34 child: const Text('Save'),35 onPress: () {36 if (!_key.currentState!.validate()) {37 // Handle errors here.38 return;39 }4041 _key.currentState!.save();42 // Do something.43 },44 ),45 ],46 ),47 );48}49Appearance
Custom Icons
1class SelectTileGroupSuffixExample extends StatefulWidget {2 @override3 State<SelectTileGroupSuffixExample> createState() =>4 _SelectTileGroupSuffixExampleState();5}67class _SelectTileGroupSuffixExampleState8 extends State<SelectTileGroupSuffixExample> {9 @override10 Widget build(BuildContext _) => FSelectTileGroup<String>(11 control: const .managedRadio(),12 label: const Text('Settings'),13 children: const [14 FSelectTile.suffix(15 prefix: Icon(FIcons.list),16 title: Text('List View'),17 value: 'List',18 ),19 FSelectTile.suffix(20 prefix: Icon(FIcons.layoutGrid),21 title: Text('Grid View'),22 value: 'Grid',23 ),24 ],25 );26}27Full Divider
1enum Sidebar { recents, home, applications }23class FullDividerSelectTileGroupExample extends StatelessWidget {4 @override5 Widget build(BuildContext _) => FSelectTileGroup<Sidebar>(6 control: const .managed(initial: {.recents}),7 label: const Text('Sidebar'),8 description: const Text('These will be shown in the sidebar.'),9 divider: .full,10 children: const [11 .tile(12 title: Text('Recents'),13 suffix: Icon(FIcons.timer),14 value: .recents,15 ),16 .tile(title: Text('Home'), suffix: Icon(FIcons.house), value: .home),17 .tile(18 title: Text('Applications'),19 suffix: Icon(FIcons.appWindowMac),20 value: .applications,21 ),22 ],23 );24}25No Divider
1enum Sidebar { recents, home, applications }23class NoDividerSelectTileGroupExample extends StatelessWidget {4 @override5 Widget build(BuildContext _) => FSelectTileGroup<Sidebar>(6 control: const .managed(initial: {.recents}),7 label: const Text('Sidebar'),8 description: const Text('These will be shown in the sidebar.'),9 divider: .none,10 children: const [11 .tile(12 title: Text('Recents'),13 suffix: Icon(FIcons.timer),14 value: .recents,15 ),16 .tile(title: Text('Home'), suffix: Icon(FIcons.house), value: .home),17 .tile(18 title: Text('Applications'),19 suffix: Icon(FIcons.appWindowMac),20 value: .applications,21 ),22 ],23 );24}25