buildDefaultTab<T> static method

Widget buildDefaultTab<T>({
  1. required BuildContext context,
  2. required TTab<T> tab,
  3. required bool isSelected,
  4. required ColorScheme colors,
  5. required GlobalKey<State<StatefulWidget>> tabKey,
  6. required Axis axis,
  7. EdgeInsets? tabPadding,
  8. required double? indicatorWidth,
  9. Color? selectedColor,
  10. Color? unselectedColor,
  11. Color? disabledColor,
  12. Color? indicatorColor,
  13. TTabController<T>? controller,
  14. VoidCallback? onTab,
  15. TTabStyle style = TTabStyle.underline,
})

Builds a default tab widget with standard styling.

Implementation

static Widget buildDefaultTab<T>({
  required BuildContext context,
  required TTab<T> tab,
  required bool isSelected,
  required ColorScheme colors,
  required GlobalKey tabKey,
  required Axis axis,
  EdgeInsets? tabPadding,
  required double? indicatorWidth,
  Color? selectedColor,
  Color? unselectedColor,
  Color? disabledColor,
  Color? indicatorColor,
  TTabController<T>? controller,
  VoidCallback? onTab,
  TTabStyle style = TTabStyle.underline,
}) {
  if (style == TTabStyle.segmented) {
    return _buildSegmentedTab<T>(
      context: context,
      tab: tab,
      isSelected: isSelected,
      colors: colors,
      tabKey: tabKey,
      tabPadding: tabPadding,
      selectedColor: selectedColor,
      unselectedColor: unselectedColor,
      disabledColor: disabledColor,
      onTab: onTab,
    );
  }
  final defaultSelectedColor = selectedColor ?? colors.onPrimaryContainer;
  final defaultUnselectedColor = unselectedColor ?? colors.onSurface;
  final defaultDisabledColor = disabledColor ?? colors.onSurfaceVariant;
  final defaultIndicatorColor = indicatorColor ?? colors.primary;

  final color = tab.isEnabled ? (isSelected ? defaultSelectedColor : defaultUnselectedColor) : defaultDisabledColor;

  final effectiveIndicatorWidth = indicatorWidth ?? 1;
  final indicatorBorder = isSelected
      ? (axis == Axis.horizontal
          ? Border(bottom: BorderSide(color: defaultIndicatorColor, width: effectiveIndicatorWidth))
          : Border(right: BorderSide(color: defaultIndicatorColor, width: effectiveIndicatorWidth)))
      : (axis == Axis.horizontal
          ? Border(bottom: BorderSide(color: Colors.transparent, width: effectiveIndicatorWidth))
          : Border(right: BorderSide(color: Colors.transparent, width: effectiveIndicatorWidth)));

  // For vertical tabs on mobile, show only icons to prevent overflow unless icon is null
  final isMobile = context.isMobile;
  final showTextInVertical = axis == Axis.horizontal || !isMobile || tab.icon == null;

  final content = axis == Axis.horizontal
      ? _buildHorizontalTabContent(
          tab: tab,
          color: color,
          isSelected: isSelected,
          defaultIndicatorColor: defaultIndicatorColor,
          colors: colors,
        )
      : _buildVerticalTabContent(
          tab: tab,
          color: color,
          isSelected: isSelected,
          defaultIndicatorColor: defaultIndicatorColor,
          showText: showTextInVertical,
        );

  return Container(
    key: tabKey,
    decoration: BoxDecoration(border: indicatorBorder),
    child: Material(
      color: Colors.transparent,
      child: InkWell(
        onTap: onTab,
        child: Container(
            // Touch-friendly: horizontal tabs are at least 48dp tall on mobile.
            constraints: BoxConstraints(minHeight: axis == Axis.horizontal && isMobile ? 48 : 0),
            alignment: axis == Axis.vertical
                ? (showTextInVertical ? Alignment.centerLeft : Alignment.center)
                : (isMobile ? Alignment.center : null),
            padding: tabPadding ??
                (axis == Axis.horizontal
                    ? const EdgeInsets.symmetric(vertical: 6, horizontal: 8)
                    : const EdgeInsets.symmetric(vertical: 4, horizontal: 8)),
            child: content),
      ),
    ),
  );
}