library google_nav_bar; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; class GNav extends StatefulWidget { const GNav({ Key? key, this.tabs, this.selectedIndex = 0, this.onTabChange, this.gap, this.padding, this.activeColor, this.color, this.rippleColor, this.hoverColor, this.backgroundColor, this.tabBackgroundColor, this.tabBorderRadius, this.iconSize, this.textStyle, this.curve, this.tabMargin, this.debug, this.duration, this.tabBorder, this.tabActiveBorder, this.tabShadow, this.haptic, this.tabBackgroundGradient, this.mainAxisAlignment = MainAxisAlignment.spaceBetween, }) : super(key: key); final List? tabs; final int selectedIndex; final Function? onTabChange; final double? gap; final double? tabBorderRadius; final double? iconSize; final Color? activeColor; final Color? backgroundColor; final Color? tabBackgroundColor; final Color? color; final Color? rippleColor; final Color? hoverColor; final EdgeInsetsGeometry? padding; final EdgeInsetsGeometry? tabMargin; final TextStyle? textStyle; final Duration? duration; final Curve? curve; final bool? debug; final bool? haptic; final Border? tabBorder; final Border? tabActiveBorder; final List? tabShadow; final Gradient? tabBackgroundGradient; final MainAxisAlignment mainAxisAlignment; @override State createState() => _GNavState(); } class _GNavState extends State { int? selectedIndex; bool clickable = true; @override void initState() { super.initState(); } @override Widget build(BuildContext context) { debugPrint( '${(_GNavState).toString()} - build with index ${widget.selectedIndex}', ); selectedIndex = widget.selectedIndex; return Container( color: widget.backgroundColor ?? Colors.transparent, child: Row( mainAxisAlignment: widget.mainAxisAlignment, children: widget.tabs! .map( (t) => GButton( key: t.key, border: t.border ?? widget.tabBorder, activeBorder: t.activeBorder ?? widget.tabActiveBorder, borderRadius: t.borderRadius as bool? ?? widget.tabBorderRadius != null ? BorderRadius.all( Radius.circular(widget.tabBorderRadius!), ) : const BorderRadius.all(Radius.circular(100.0)), debug: widget.debug ?? false, margin: t.margin ?? widget.tabMargin, active: selectedIndex == widget.tabs!.indexOf(t), gap: t.gap ?? widget.gap, iconActiveColor: t.iconActiveColor ?? widget.activeColor, iconColor: t.iconColor ?? widget.color, iconSize: t.iconSize ?? widget.iconSize, textColor: t.textColor ?? widget.activeColor, rippleColor: t.rippleColor ?? widget.rippleColor ?? Colors.transparent, hoverColor: t.hoverColor ?? widget.hoverColor ?? Colors.transparent, padding: t.padding ?? widget.padding, icon: t.icon, haptic: widget.haptic ?? true, leading: t.leading, curve: widget.curve ?? Curves.easeInCubic, backgroundGradient: t.backgroundGradient ?? widget.tabBackgroundGradient, backgroundColor: t.backgroundColor ?? widget.tabBackgroundColor ?? Colors.transparent, duration: widget.duration ?? const Duration(milliseconds: 500), onPressed: () { widget.onTabChange!(widget.tabs!.indexOf(t)); }, ), ) .toList(), ), ); } } class GButton extends StatefulWidget { final bool? active; final bool? debug; final bool? haptic; final double? gap; final Color? iconColor; final Color? rippleColor; final Color? hoverColor; final Color? iconActiveColor; final Color? textColor; final EdgeInsetsGeometry? padding; final EdgeInsetsGeometry? margin; final TextStyle? textStyle; final double? iconSize; final Function? onPressed; final String text; final IconData? icon; final Color? backgroundColor; final Duration? duration; final Curve? curve; final Gradient? backgroundGradient; final Widget? leading; final BorderRadius? borderRadius; final Border? border; final Border? activeBorder; final List? shadow; final String? semanticLabel; const GButton({ Key? key, this.active, this.haptic, this.backgroundColor, this.icon, this.iconColor, this.rippleColor, this.hoverColor, this.iconActiveColor, this.text = '', this.textColor, this.padding, this.margin, this.duration, this.debug, this.gap, this.curve, this.textStyle, this.iconSize, this.leading, this.onPressed, this.backgroundGradient, this.borderRadius, this.border, this.activeBorder, this.shadow, this.semanticLabel, }) : super(key: key); @override State createState() => _GButtonState(); } class _GButtonState extends State { @override Widget build(BuildContext context) { return Semantics( label: widget.semanticLabel ?? widget.text, child: Button( borderRadius: widget.borderRadius, border: widget.border, activeBorder: widget.activeBorder, shadow: widget.shadow, debug: widget.debug, duration: widget.duration, iconSize: widget.iconSize, active: widget.active, onPressed: () { if (widget.haptic!) HapticFeedback.selectionClick(); widget.onPressed!(); }, padding: widget.padding, margin: widget.margin, gap: widget.gap, color: widget.backgroundColor, rippleColor: widget.rippleColor, hoverColor: widget.hoverColor, gradient: widget.backgroundGradient, curve: widget.curve, leading: widget.leading, iconActiveColor: widget.iconActiveColor, iconColor: widget.iconColor, icon: widget.icon, ), ); } } class Button extends StatefulWidget { const Button({ Key? key, this.icon, this.iconSize, this.leading, this.iconActiveColor, this.iconColor, this.text, this.gap = 0, this.color, this.rippleColor, this.hoverColor, this.onPressed, this.duration, this.curve, this.padding = const EdgeInsets.all(25), this.margin = const EdgeInsets.all(0), this.active = false, this.debug, this.gradient, this.borderRadius = const BorderRadius.all(Radius.circular(100.0)), this.border, this.activeBorder, this.shadow, }) : super(key: key); final IconData? icon; final double? iconSize; final Text? text; final Widget? leading; final Color? iconActiveColor; final Color? iconColor; final Color? color; final Color? rippleColor; final Color? hoverColor; final double? gap; final bool? active; final bool? debug; final VoidCallback? onPressed; final EdgeInsetsGeometry? padding; final EdgeInsetsGeometry? margin; final Duration? duration; final Curve? curve; final Gradient? gradient; final BorderRadius? borderRadius; final Border? border; final Border? activeBorder; final List? shadow; @override State