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: .value(.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.md,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.md,161 ),162 ),163 ),164 ],165 ),166 ),167);168CLI
To generate a specific style for customization:
Anatomy
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: .value(.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: .value(.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: .value(.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: .value(.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: .value(.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 variant: .outline,5 size: .sm,6 mainAxisSize: .min,7 child: const Text('Open Sidebar'),8 onPress: () => showFSheet(9 context: context,10 side: .ltr,11 builder: (context) => DecoratedBox(12 decoration: BoxDecoration(color: context.theme.colors.background),13 child: FSidebar(14 style: const .delta(15 constraints: BoxConstraints(minWidth: 300, maxWidth: 300),16 ),17 header: Padding(18 padding: const .symmetric(horizontal: 16),19 child: Column(20 crossAxisAlignment: .start,21 children: [22 Padding(23 padding: const .fromLTRB(16, 8, 16, 16),24 child: SvgPicture.network(25 context.theme.colors.brightness == .light26 ? 'https://forui.dev/light_logo.svg'27 : 'https://forui.dev/dark_logo.svg',28 height: 24,29 colorFilter: ColorFilter.mode(30 context.theme.colors.foreground,31 .srcIn,32 ),33 ),34 ),35 const FDivider(style: .delta(padding: .value(.zero))),36 ],37 ),38 ),39 footer: Padding(40 padding: const .symmetric(horizontal: 16),41 child: FCard.raw(42 child: Padding(43 padding: const .symmetric(vertical: 12, horizontal: 16),44 child: Row(45 spacing: 10,46 children: [47 FAvatar.raw(48 child: Icon(49 FIcons.userRound,50 size: 18,51 color: context.theme.colors.mutedForeground,52 ),53 ),54 Expanded(55 child: Column(56 crossAxisAlignment: .start,57 spacing: 2,58 children: [59 Text(60 'Dash',61 style: context.theme.typography.sm.copyWith(62 fontWeight: .bold,63 color: context.theme.colors.foreground,64 ),65 overflow: .ellipsis,66 ),67 Text(68 'dash@forui.dev',69 style: context.theme.typography.xs.copyWith(70 color: context.theme.colors.mutedForeground,71 ),72 overflow: .ellipsis,73 ),74 ],75 ),76 ),77 ],78 ),79 ),80 ),81 ),82 children: [83 FSidebarGroup(84 label: const Text('Overview'),85 children: [86 FSidebarItem(87 icon: const Icon(FIcons.school),88 label: const Text('Getting Started'),89 initiallyExpanded: true,90 onPress: () {},91 children: [92 FSidebarItem(93 label: const Text('Installation'),94 selected: true,95 onPress: () {},96 ),97 FSidebarItem(label: const Text('Themes'), onPress: () {}),98 FSidebarItem(99 label: const Text('Typography'),100 onPress: () {},101 ),102 ],103 ),104 FSidebarItem(105 icon: const Icon(FIcons.code),106 label: const Text('API Reference'),107 onPress: () {},108 ),109 FSidebarItem(110 icon: const Icon(FIcons.box),111 label: const Text('Pub Dev'),112 onPress: () {},113 ),114 ],115 ),116 FSidebarGroup(117 action: const Icon(FIcons.plus),118 onActionPress: () {},119 label: const Text('Widgets'),120 children: [121 FSidebarItem(122 icon: const Icon(FIcons.circleSlash),123 label: const Text('Divider'),124 onPress: () {},125 ),126 FSidebarItem(127 icon: const Icon(FIcons.scaling),128 label: const Text('Resizable'),129 onPress: () {},130 ),131 FSidebarItem(132 icon: const Icon(FIcons.layoutDashboard),133 label: const Text('Scaffold'),134 onPress: () {},135 ),136 ],137 ),138 ],139 ),140 ),141 ),142 ),143);144Custom 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