Sidebar

In this page we will go in depth into how the Sidebar works in FlexDash. At first glance it might feel overwhelming, but in reality it is a simple structure, the only reason it can look confusing is because the layout is repetitive and the widget tree can get cluttered. Once you break it down into smaller pieces, it becomes very easy to understand and modify.

If you prefer to keep things clean, you can even delete the entire default sidebar and rebuild it from scratch to maintain a fresh widget tree (just make sure to keep a backup copy of the original sidebar component in case you need to reference it later).


The Sidebar Component

The sidebar is a reusable component called Sidebar (yes, the name says it all 😅). It is used both in the web layout and inside the mobile drawer, meaning that any changes you make inside this component will automatically reflect across the whole app. This makes it very easy to maintain without having to edit each page individually.


General Structure

To understand the structure of the sidebar, the first recommendation is to collapse all widgets in the widget tree. This way you can see the high-level layout clearly.

  • The root container defines the background color and width of the sidebar.

  • The width changes depending on the app state sidebarExpanded:

    • true → 240px wide

    • false → 110px wide

  • Inside this container there is a Row with two elements:

    1. The main column containing the sidebar content.

    2. A decorative vertical divider on the right.


Logo Section

At the very top of the sidebar’s scrollable column you will find the platform logo. This logo is wrapped inside a conditional builder, which at first might look confusing but is actually straightforward once you understand the logic:

  • The logo changes depending on two things:

    1. Whether the sidebar is expanded or collapsed.

    2. Whether the sidebar is locked in dark mode (darSidebar = true) or follows the app’s active theme (light/dark).

👉 If you want to simplify things, you can remove the default logo logic and replace it with your own logo + conditions. For example, you might only care about expanded vs collapsed state, or about dark/light mode. Alternatively, you can follow the structure provided in the template and just replace the logo assets in each conditional builder (recommended only if you want to keep your project as dynamic as the original template).


The next section is a column that holds the main menus of your project. There are two types of content inside this section:

  1. Collapsible Menus (Accordion style)

  2. Standalone Pages (Non-collapsible items)

Collapsible Menus

Each collapsible menu is itself a separate component. For example, look at the component called Pages to see how these accordions are built.

They are composed of two main parts:

  1. Accordion Header

    • Placed inside a Row.

    • Triggers an action to update the app state with the name of the accordion currently opened.

  2. Subpages List

    • Wrapped inside a Container with conditional visibility.

    • Subpages are only shown if:

      • The expanded section in the app state matches the correct accordion.

      • The sidebar is expanded.

Each subpage is wrapped in a MouseRegion to enable hover effects (changing colors when the mouse is over them). Additionally, each item has conditional colors to visually highlight both the hover state and the currently active page.


Non-Collapsible Menus

In addition to the collapsible menus, the sidebar also contains non-collapsible menu sections, which are organized inside simple columns. These sections are more straightforward compared to the accordion-type menus, but they follow a similar logic in terms of interactivity and style.

A good reference to understand this structure is the “Public Profiles” section. To avoid confusion when exploring the widget tree, collapse everything else and focus only on this column.

Structure Overview

Each page entry inside these sections follows a consistent structure:

  1. Mouse Region

    • Each page item is wrapped in a Mouse Region.

    • This is used to handle hover effects, allowing the item’s background and text color to change when the cursor passes over it.

  2. Container

    • Inside the Mouse Region, each page item is placed within a Container.

    • This Container holds the navigation action that routes the user to the corresponding page when clicked.

  3. Text Element

    • The page name is displayed here.

    • The text styling contains conditional logic that reacts to:

      • Whether the item is currently hovered.

      • Whether the page is the active page in the app.

    • Thanks to this, the correct colors are shown based on both user interaction and the current page context.

Section Titles

Each non-collapsible menu column also starts with a section title (for example: “Public Profiles”). This title helps group the pages logically, making the sidebar easier to navigate and organize.


circle-exclamation

⚠️ Important Note

Highlighting the Active Page in the Sidebar

To show which item in the sidebar is currently active (highlighted), FlexDash uses a simple comparison of names. The mechanism relies on storing the name of the current page inside the global AppState variable currentPageName.

Step 1: Setting the Active Page Name

Inside each page of your project, add an action that runs when the page is loaded.

  • This action should set the AppState variable currentPageName to the name of the page.

  • Example: On the Dashboard page, set currentPageName = "Dashboard".

This ensures that whenever a user lands on the page (no matter how they arrived there), the AppState will always reflect the correct active page.


Step 2: Sidebar Highlighting Logic

In the sidebar, each menu item checks the value of currentPageName:

  • If the value matches the item’s assigned page name → apply the highlighted color.

  • Otherwise → use the default styling.

You can use any of the existing sidebar items in the template as a reference, then copy and paste the same logic into your own items. Just replace the page name being compared with the correct one from your project.


Example Logic

  • currentPageName == "Dashboard" → Highlight the Dashboard menu item.

  • currentPageName == "Home" → Highlight the Home menu item.


circle-info

⚠️ Important Note

You might wonder why the page name is not set in the sidebar’s navigation action (inside the Container that navigates to the page). The reason is simple:

Users can reach a page without clicking the sidebar, for example:

  • Through a navigation flow elsewhere in your app.

  • By following a shared link that takes them directly to a specific page.

If the AppState were updated only when navigating from the sidebar, those cases would fail. By setting the AppState on page load, you guarantee that no matter how the user arrives, the correct item will always be highlighted in the sidebar.

Using the Sidebar in Mobile (Drawer Version)

FlexDash includes a mobile-friendly version of the sidebar using a Drawer. This allows users to open and close the sidebar from the header when the app is viewed on smaller screens.


Step 1: Insert the Drawer

  1. Go to the root of the page.

  2. Insert a Drawer widget.

  3. Set its width to 240px and elevation to 10px to maintain consistency across all pages.

  4. Inside the Drawer, place the Sidebar component.


Step 2: Connect the Drawer to the Header

Each page’s header includes a parameter that accepts an action. To enable the Drawer on mobile:

  • Pass the action that opens the Drawer to the header.

  • The header already contains the logic needed to handle opening the Drawer, so no further setup is required.

You can review any page in the template as a reference to understand how the Drawer is used.


Why Not Use a Custom Dialog?

You might be wondering why the Drawer is used individually in every page instead of creating a reusable custom dialog. The reasons are:

  • Safe Area issue: On mobile, a custom dialog does not occupy the full screen, leaving unwanted spaces at the top and bottom.

  • No drag-to-close: Custom dialogs cannot be closed by dragging, which feels unnatural for a sidebar on mobile.

  • Drawer limitation in FlutterFlow: FlutterFlow does not allow creating a reusable Drawer, so the only solution is to insert it manually in every page.

By following the steps above, your sidebar will work smoothly on mobile devices with the correct behavior and styling.

Last updated