Navigation
Sidebar
A sidebar widget that provides an opinionated layout for navigation on the side of the screen.
A sidebar is typically used with FScaffold. Usage of FScaffold can be found here.
1@override2Widget build(BuildContext context) => FScaffold(3 sidebar: FSidebar(4 header: Padding(5 padding: const .symmetric(horizontal: 16),6 child: Column(7 crossAxisAlignment: .start,8 children: [9 Padding(10 padding: const .fromLTRB(16, 8, 16, 16),11 child: SvgPicture.network(12 context.theme.colors.brightness == .light13 ? 'https://forui.dev/light_logo.svg'14 : 'https://forui.dev/dark_logo.svg',15 height: 24,16 colorFilter: ColorFilter.mode(17 context.theme.colors.foreground,18 .srcIn,19 ),20 ),21 ),22 const FDivider(style: .delta(padding: .zero)),23 ],24 ),25 ),26 footer: Padding(27 padding: const .symmetric(horizontal: 16),28 child: FCard.raw(29 child: Padding(30 padding: const .symmetric(vertical: 12, horizontal: 16),31 child: Row(32 spacing: 10,33 children: [34 FAvatar.raw(35 child: Icon(36 FIcons.userRound,37 size: 18,38 color: context.theme.colors.mutedForeground,39 ),40 ),41 Expanded(42 child: Column(43 crossAxisAlignment: .start,44 spacing: 2,45 children: [46 Text(47 'Dash',48 style: context.theme.typography.sm.copyWith(49 fontWeight: .bold,50 color: context.theme.colors.foreground,51 ),52 overflow: .ellipsis,53 ),54 Text(55 'dash@forui.dev',56 style: context.theme.typography.xs.copyWith(57 color: context.theme.colors.mutedForeground,58 ),59 overflow: .ellipsis,60 ),61 ],62 ),63 ),64 ],65 ),66 ),67 ),68 ),69 children: [70 FSidebarGroup(71 label: const Text('Overview'),72 children: [73 FSidebarItem(74 icon: const Icon(FIcons.school),75 label: const Text('Getting Started'),76 initiallyExpanded: true,77 onPress: () {},78 children: [79 FSidebarItem(80 label: const Text('Installation'),81 selected: true,82 onPress: () {},83 ),84 FSidebarItem(label: const Text('Themes'), onPress: () {}),85 FSidebarItem(label: const Text('Typography'), onPress: () {}),86 ],87 ),88 FSidebarItem(89 icon: const Icon(FIcons.code),90 label: const Text('API Reference'),91 onPress: () {},92 ),93 FSidebarItem(94 icon: const Icon(FIcons.box),95 label: const Text('Pub Dev'),96 onPress: () {},97 ),98 ],99 ),100 FSidebarGroup(101 action: const Icon(FIcons.plus),102 onActionPress: () {},103 label: const Text('Widgets'),104 children: [105 FSidebarItem(106 icon: const Icon(FIcons.circleSlash),107 label: const Text('Divider'),108 onPress: () {},109 ),110 FSidebarItem(111 icon: const Icon(FIcons.scaling),112 label: const Text('Resizable'),113 onPress: () {},114 ),115 FSidebarItem(116 icon: const Icon(FIcons.layoutDashboard),117 label: const Text('Scaffold'),118 onPress: () {},119 ),120 ],121 ),122 ],123 ),124 child: Padding(125 padding: const .symmetric(vertical: 14),126 child: Column(127 crossAxisAlignment: .start,128 spacing: 12,129 children: [130 FBreadcrumb(131 children: [132 FBreadcrumbItem(onPress: () {}, child: const Text('Forui')),133 FBreadcrumbItem.collapsed(134 menu: [135 FItemGroup(136 children: [137 FItem(title: const Text('Documentation'), onPress: () {}),138 FItem(title: const Text('Themes'), onPress: () {}),139 ],140 ),141 ],142 ),143 FBreadcrumbItem(onPress: () {}, child: const Text('Overview')),144 const FBreadcrumbItem(current: true, child: Text('Installation')),145 ],146 ),147 Expanded(148 child: Container(149 decoration: BoxDecoration(150 color: context.theme.colors.muted,151 borderRadius: context.theme.style.borderRadius,152 ),153 ),154 ),155 Expanded(156 flex: 3,157 child: Container(158 decoration: BoxDecoration(159 color: context.theme.colors.muted,160 borderRadius: context.theme.style.borderRadius,161 ),162 ),163 ),164 ],165 ),166 ),167);168CLI
To generate and customize this style:
dart run forui style create sidebarAnatomy
This segment describes the anatomy of the various elements of a sidebar.
FSidebar
The widget that provides an opinionated layout on the side of the screen. The widget has the following sections:
| Name | Parameter | Position | Optional |
|---|---|---|---|
| header | header | sticky | Yes |
| content | child/children | scrollable | No |
| footer | footer | sticky | Yes |
FSidebarGroup
A widget that is used to group several FSidebarItems.
FSidebarItem
Represents an item on the sidebar. May be nested in FSidebarItem.children to create nested items.
Usage
FSidebar(...)
1FSidebar(2 style: const .delta(headerPadding: .fromLTRB(0, 16, 0, 0)),3 header: const Text('Header'),4 children: [5 FSidebarGroup(6 label: const Text('Navigation'),7 children: [8 FSidebarItem(9 icon: const Icon(FIcons.house),10 label: const Text('Home'),11 onPress: () {},12 ),13 FSidebarItem(14 icon: const Icon(FIcons.settings),15 label: const Text('Settings'),16 onPress: () {},17 ),18 ],19 ),20 ],21 footer: const Text('Footer'),22)FSidebar.builder(...)
1FSidebar.builder(2 style: const .delta(headerPadding: .fromLTRB(0, 16, 0, 0)),3 header: const Text('Header'),4 itemBuilder: (context, index) =>5 FSidebarItem(label: Text('Item $index'), onPress: () {}),6 itemCount: 10,7 footer: const Text('Footer'),8)FSidebar.raw(...)
1FSidebar.raw(2 style: const .delta(headerPadding: .fromLTRB(0, 16, 0, 0)),3 header: const Text('Header'),4 child: ListView(5 children: [FSidebarItem(label: const Text('Custom Item'), onPress: () {})],6 ),7 footer: const Text('Footer'),8)FSidebarGroup(...)
1FSidebarGroup(2 style: const .delta(padding: .symmetric(horizontal: 8)),3 label: const Text('Navigation'),4 action: const Icon(FIcons.plus),5 children: [6 FSidebarItem(label: const Text('Home'), onPress: () {}),7 FSidebarItem(label: const Text('Settings'), onPress: () {}),8 ],9)FSidebarItem(...)
1FSidebarItem(2 style: const .delta(padding: .symmetric(horizontal: 8)),3 selected: false,4 initiallyExpanded: false,5 icon: const Icon(FIcons.house),6 label: const Text('Home'),7 children: [8 FSidebarItem(label: const Text('Nested Item 1'), onPress: () {}),9 FSidebarItem(label: const Text('Nested Item 2'), onPress: () {}),10 ],11)Examples
Sheet Sidebar
Suited for devices with limited screen space.
1@override2Widget build(BuildContext context) => Center(3 child: FButton(4 child: const Text('Open Sidebar'),5 onPress: () => showFSheet(6 context: context,7 side: .ltr,8 builder: (context) => DecoratedBox(9 decoration: BoxDecoration(color: context.theme.colors.background),10 child: FSidebar(11 style: const .delta(12 constraints: BoxConstraints(minWidth: 300, maxWidth: 300),13 ),14 header: Padding(15 padding: const .symmetric(horizontal: 16),16 child: Column(17 crossAxisAlignment: .start,18 children: [19 Padding(20 padding: const .fromLTRB(16, 8, 16, 16),21 child: SvgPicture.network(22 context.theme.colors.brightness == .light23 ? 'https://forui.dev/light_logo.svg'24 : 'https://forui.dev/dark_logo.svg',25 height: 24,26 colorFilter: ColorFilter.mode(27 context.theme.colors.foreground,28 .srcIn,29 ),30 ),31 ),32 const FDivider(style: .delta(padding: .zero)),33 ],34 ),35 ),36 footer: Padding(37 padding: const .symmetric(horizontal: 16),38 child: FCard.raw(39 child: Padding(40 padding: const .symmetric(vertical: 12, horizontal: 16),41 child: Row(42 spacing: 10,43 children: [44 FAvatar.raw(45 child: Icon(46 FIcons.userRound,47 size: 18,48 color: context.theme.colors.mutedForeground,49 ),50 ),51 Expanded(52 child: Column(53 crossAxisAlignment: .start,54 spacing: 2,55 children: [56 Text(57 'Dash',58 style: context.theme.typography.sm.copyWith(59 fontWeight: .bold,60 color: context.theme.colors.foreground,61 ),62 overflow: .ellipsis,63 ),64 Text(65 'dash@forui.dev',66 style: context.theme.typography.xs.copyWith(67 color: context.theme.colors.mutedForeground,68 ),69 overflow: .ellipsis,70 ),71 ],72 ),73 ),74 ],75 ),76 ),77 ),78 ),79 children: [80 FSidebarGroup(81 label: const Text('Overview'),82 children: [83 FSidebarItem(84 icon: const Icon(FIcons.school),85 label: const Text('Getting Started'),86 initiallyExpanded: true,87 onPress: () {},88 children: [89 FSidebarItem(90 label: const Text('Installation'),91 selected: true,92 onPress: () {},93 ),94 FSidebarItem(label: const Text('Themes'), onPress: () {}),95 FSidebarItem(96 label: const Text('Typography'),97 onPress: () {},98 ),99 ],100 ),101 FSidebarItem(102 icon: const Icon(FIcons.code),103 label: const Text('API Reference'),104 onPress: () {},105 ),106 FSidebarItem(107 icon: const Icon(FIcons.box),108 label: const Text('Pub Dev'),109 onPress: () {},110 ),111 ],112 ),113 FSidebarGroup(114 action: const Icon(FIcons.plus),115 onActionPress: () {},116 label: const Text('Widgets'),117 children: [118 FSidebarItem(119 icon: const Icon(FIcons.circleSlash),120 label: const Text('Divider'),121 onPress: () {},122 ),123 FSidebarItem(124 icon: const Icon(FIcons.scaling),125 label: const Text('Resizable'),126 onPress: () {},127 ),128 FSidebarItem(129 icon: const Icon(FIcons.layoutDashboard),130 label: const Text('Scaffold'),131 onPress: () {},132 ),133 ],134 ),135 ],136 ),137 ),138 ),139 ),140);141Custom Width
1@override2Widget build(BuildContext _) => FSidebar(3 style: const .delta(4 constraints: BoxConstraints(minWidth: 500, maxWidth: 500),5 ),6 children: [7 FSidebarGroup(8 children: [9 FSidebarItem(10 icon: const Icon(FIcons.layoutDashboard),11 label: const Text('Dashboard'),12 selected: true,13 onPress: () {},14 ),15 FSidebarItem(16 icon: const Icon(FIcons.chartLine),17 label: const Text('Analytics'),18 onPress: () {},19 ),20 FSidebarItem(21 icon: const Icon(FIcons.chartBar),22 label: const Text('Reports'),23 initiallyExpanded: true,24 children: [25 FSidebarItem(label: const Text('Daily'), onPress: () {}),26 FSidebarItem(label: const Text('Weekly'), onPress: () {}),27 FSidebarItem(label: const Text('Monthly'), onPress: () {}),28 ],29 ),30 ],31 ),32 ],33);34Nested FSidebarItem
1@override2Widget build(BuildContext _) => FSidebar(3 style: const .delta(4 constraints: BoxConstraints(minWidth: 300, maxWidth: 300),5 ),6 children: [7 FSidebarGroup(8 children: [9 FSidebarItem(10 icon: const Icon(FIcons.userRound),11 label: const Text('Account'),12 initiallyExpanded: true,13 children: [14 FSidebarItem(15 label: const Text('Profile'),16 children: [17 FSidebarItem(18 label: const Text('Personal Info'),19 onPress: () {},20 ),21 FSidebarItem(label: const Text('Preferences'), onPress: () {}),22 ],23 ),24 FSidebarItem(25 label: const Text('Security'),26 initiallyExpanded: true,27 children: [28 FSidebarItem(29 label: const Text('Password'),30 initiallyExpanded: true,31 children: [32 FSidebarItem(33 label: const Text('Change Password'),34 onPress: () {},35 ),36 FSidebarItem(37 label: const Text('Password History'),38 onPress: () {},39 ),40 ],41 ),42 FSidebarItem(43 label: const Text('Two-Factor Authentication'),44 onPress: () {},45 ),46 FSidebarItem(47 label: const Text('Device History'),48 onPress: () {},49 ),50 ],51 ),52 FSidebarItem(label: const Text('Notifications'), onPress: () {}),53 ],54 ),55 FSidebarItem(56 icon: const Icon(FIcons.palette),57 label: const Text('Appearance'),58 onPress: () {},59 ),60 FSidebarItem(61 icon: const Icon(FIcons.settings),62 label: const Text('System'),63 onPress: () {},64 ),65 ],66 ),67 ],68);69