import 'package:flutter/material.dart'; import '../about/internal/application/TextType.dart'; import '../utils/Colors.dart'; import 'GlassSurface.dart'; import 'text/Text.dart'; typedef NavEntry = ({IconData icon, String label, VoidCallback onTap}); /// The floating tab bar: the selected tab is a filled night block, the rest /// sit quietly on white. An optional dark action button can sit beside it. class FloatingNav extends StatelessWidget { final List entries; final int selected; final IconData? actionIcon; final VoidCallback? onAction; const FloatingNav({ super.key, required this.entries, required this.selected, this.actionIcon, this.onAction, }); @override Widget build(BuildContext context) { return SafeArea( top: false, child: Padding( padding: const EdgeInsets.fromLTRB(16, 0, 16, 14), child: Row( children: [ Expanded( child: Container( decoration: BoxDecoration( borderRadius: BorderRadius.zero, boxShadow: const [ BoxShadow( color: Color(0x1A1A1F1C), blurRadius: 30, offset: Offset(0, 10), ), ], ), child: GlassSurface( radius: BorderRadius.zero, tint: colorGlassStrong, padding: const EdgeInsets.all(6), child: Row( children: [ for (int index = 0; index < entries.length; index++) Expanded(child: _tab(entries[index], index == selected)), ], ), ), ), ), if (onAction != null) ...[ const SizedBox(width: 10), GestureDetector( onTap: onAction, child: Container( width: 72, height: 72, decoration: BoxDecoration( gradient: const RadialGradient( center: Alignment(-0.3, -0.4), colors: [colorNightGlow, colorNight], ), border: Border.all(color: colorWhite, width: 3), boxShadow: const [ BoxShadow( color: Color(0x331A1F1C), blurRadius: 24, offset: Offset(0, 10), ), ], ), child: Icon(actionIcon, size: 24, color: colorLime), ), ), ], ], ), ), ); } Widget _tab(NavEntry entry, bool active) { return GestureDetector( onTap: entry.onTap, behavior: HitTestBehavior.opaque, child: AnimatedContainer( duration: const Duration(milliseconds: 220), curve: Curves.easeOutCubic, padding: const EdgeInsets.symmetric(vertical: 10), decoration: BoxDecoration( color: active ? colorHeaderBottom : colorWhite.withValues(alpha: 0.0), borderRadius: BorderRadius.zero, boxShadow: active ? const [ BoxShadow( color: Color(0x141A1F1C), blurRadius: 12, offset: Offset(0, 4), ), ] : const [], ), child: Column( mainAxisSize: MainAxisSize.min, children: [ Icon(entry.icon, size: 23, color: active ? colorWhite : colorInkSoft), const SizedBox(height: 4), text(entry.label, 10, active ? TextType.Medium : TextType.Regular, color: active ? colorWhite : colorInkSoft, maxLines: 1), ], ), ), ); } }