getBody method

Widget getBody(
  1. bool hasAppBar
)

Implementation

Widget getBody(bool hasAppBar) {
  // ignore safe area is only applicable if we don't have an AppBar
  bool _useSafeArea = !hasAppBar && useSafeArea();
  if (widget._pageModel.menu is SidebarMenu) {
    SidebarMenu sidebarMenu = widget._pageModel.menu as SidebarMenu;

    List<MenuItem> menuItems = sidebarMenu.menuItems;
    List<NavigationRailDestination> navItems = [];
    for (int i = 0; i < menuItems.length; i++) {
      MenuItem item = menuItems[i];
      navItems.add(NavigationRailDestination(
          padding: Utils.getInsets(sidebarMenu.runtimeStyles?['itemPadding']),
          icon: item.icon != null
              ? ensemble.Icon.fromModel(item.icon!)
              : const SizedBox.shrink(),
          label: Text(Utils.translate(item.label ?? '', context))));
    }

    // TODO: consolidate buildWidget into 1 place
    double paddingFromSafeSpace = 15;
    Widget? headerWidget;
    if (sidebarMenu.headerModel != null) {
      headerWidget = _scopeManager.buildWidget(sidebarMenu.headerModel!);
    }
    Widget menuHeader = Column(children: [
      SizedBox(height: paddingFromSafeSpace),
      Container(
        child: headerWidget,
      )
    ]);

    Widget? menuFooter;
    if (sidebarMenu.footerModel != null) {
      // push footer to the bottom of the rail
      menuFooter = Expanded(
        child: Align(
            alignment: Alignment.bottomCenter,
            child: _scopeManager.buildWidget(sidebarMenu.footerModel!)),
      );
    }

    MenuItemDisplay itemDisplay = MenuItemDisplay.values
            .from(sidebarMenu.runtimeStyles?['itemDisplay']) ??
        MenuItemDisplay.stacked;

    // stacked's min gap seems to be 72 regardless of what we set. For side by side optimal min gap is around 40
    // we set this minGap and let user controls with itemPadding
    int minGap = itemDisplay == MenuItemDisplay.sideBySide ? 40 : 72;

    // minExtendedWidth is applicable only for side by side, and should never be below minWidth (or exception)
    int minWidth = Utils.optionalInt(sidebarMenu.runtimeStyles?['minWidth'],
            min: minGap) ??
        200;

    List<Widget> content = [];
    // process menu styles
    Color? menuBackground =
        Utils.getColor(sidebarMenu.runtimeStyles?['backgroundColor']);
    content.add(NavigationRail(
      extended: itemDisplay == MenuItemDisplay.sideBySide ? true : false,
      minExtendedWidth: minWidth.toDouble(),
      minWidth: minGap.toDouble(),
      // this is important for optimal default item spacing
      labelType: itemDisplay != MenuItemDisplay.sideBySide
          ? NavigationRailLabelType.all
          : null,
      backgroundColor: menuBackground,
      leading: menuHeader,
      destinations: navItems,
      trailing: menuFooter,
      selectedIndex: selectedPage,
      onDestinationSelected: (index) =>
          selectNavigationIndex(context, menuItems[index]),
    ));

    // show a divider between the NavigationRail and the content
    Color? borderColor =
        Utils.getColor(widget._pageModel.menu!.runtimeStyles?['borderColor']);
    int? borderWidth = Utils.optionalInt(
        widget._pageModel.menu!.runtimeStyles?['borderWidth']);
    if (borderColor != null || borderWidth != null) {
      content.add(VerticalDivider(
          thickness: (borderWidth ?? 1).toDouble(),
          width: (borderWidth ?? 1).toDouble(),
          color: borderColor));
    }

    // add the bodyWidget
    content.add(Expanded(
        child: SafeArea(
            top: _useSafeArea, bottom: _useSafeArea, child: rootWidget)));
    return DefaultTextStyle.merge(
        style: widget._controller._textStyle?.getTextStyle(),
        maxLines: widget._controller.maxLines,
        child: Row(
            crossAxisAlignment: CrossAxisAlignment.start, children: content));
  }

  return DefaultTextStyle.merge(
      style: widget._controller._textStyle?.getTextStyle(),
      maxLines: widget._controller.maxLines,
      child: SafeArea(
          top: _useSafeArea, bottom: _useSafeArea, child: rootWidget));
}