Nikolas Rimikis
1 year ago
2 changed files with 149 additions and 0 deletions
@ -0,0 +1,137 @@
|
||||
import 'package:flutter/material.dart'; |
||||
import 'package:neon/neon.dart'; |
||||
import 'package:rxdart/subjects.dart'; |
||||
|
||||
typedef DestinationIconBuilder = Widget Function({Size size, Color color}); |
||||
|
||||
class NeonNavigationDestination { |
||||
const NeonNavigationDestination({ |
||||
required this.label, |
||||
required this.icon, |
||||
this.selectedIcon, |
||||
this.notificationCount, |
||||
}); |
||||
|
||||
final String label; |
||||
final DestinationIconBuilder icon; |
||||
final Widget? selectedIcon; |
||||
final BehaviorSubject<int>? notificationCount; |
||||
} |
||||
|
||||
extension NavigationDestinationExtension on NavigationDestination { |
||||
static NavigationDestination fromNeonDestination(final NeonNavigationDestination neonDestination) => |
||||
NavigationDestination( |
||||
label: neonDestination.label, |
||||
icon: neonDestination.icon(), |
||||
selectedIcon: neonDestination.selectedIcon, |
||||
); |
||||
} |
||||
|
||||
extension NavigationRailDestinationExtension on NavigationRailDestination { |
||||
static NavigationRailDestination fromNeonDestination(final NeonNavigationDestination neonDestination) { |
||||
final iconWIdget = StreamBuilder( |
||||
stream: neonDestination.notificationCount, |
||||
initialData: 0, |
||||
builder: (final context, final snapshot) { |
||||
final colorScheme = Theme.of(context).colorScheme; |
||||
|
||||
final color = snapshot.data! > 0 ? colorScheme.primary : colorScheme.onBackground; |
||||
const size = Size.square(kAvatarSize * 2 / 3); |
||||
|
||||
final icon = Container( |
||||
margin: const EdgeInsets.all(5), |
||||
child: neonDestination.icon(size: size, color: color), |
||||
); |
||||
|
||||
if (snapshot.data! <= 0) { |
||||
return icon; |
||||
} |
||||
|
||||
final notificationIdicator = Builder( |
||||
builder: (final context) { |
||||
final style = TextStyle( |
||||
color: Theme.of(context).colorScheme.primary, |
||||
fontWeight: FontWeight.bold, |
||||
); |
||||
|
||||
return Text( |
||||
snapshot.data!.toString(), |
||||
style: style, |
||||
); |
||||
}, |
||||
); |
||||
|
||||
return Stack( |
||||
alignment: Alignment.bottomRight, |
||||
children: [ |
||||
icon, |
||||
notificationIdicator, |
||||
], |
||||
); |
||||
}, |
||||
); |
||||
|
||||
return NavigationRailDestination( |
||||
label: Text(neonDestination.label), |
||||
icon: iconWIdget, |
||||
selectedIcon: neonDestination.selectedIcon, |
||||
); |
||||
} |
||||
} |
||||
|
||||
extension NavigationDrawerDestinationExtension on NavigationDrawerDestination { |
||||
static NavigationDrawerDestination fromNeonDestination(final NeonNavigationDestination neonDestination) { |
||||
final labelWidget = StreamBuilder( |
||||
stream: neonDestination.notificationCount, |
||||
initialData: 0, |
||||
builder: (final context, final snapshot) { |
||||
final label = Text(neonDestination.label); |
||||
|
||||
if (snapshot.data! <= 0) { |
||||
return label; |
||||
} |
||||
|
||||
final notificationIdicator = Padding( |
||||
padding: const EdgeInsets.only(left: 12, right: 24), |
||||
child: Builder( |
||||
builder: (final context) { |
||||
final style = TextStyle( |
||||
color: Theme.of(context).colorScheme.primary, |
||||
fontWeight: FontWeight.bold, |
||||
fontSize: 14, |
||||
); |
||||
|
||||
return Text( |
||||
snapshot.data!.toString(), |
||||
style: style, |
||||
); |
||||
}, |
||||
), |
||||
); |
||||
|
||||
return Expanded( |
||||
child: Row( |
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween, |
||||
children: [ |
||||
label, |
||||
notificationIdicator, |
||||
], |
||||
), |
||||
); |
||||
}, |
||||
); |
||||
|
||||
return NavigationDrawerDestination( |
||||
label: labelWidget, |
||||
icon: neonDestination.icon(), |
||||
selectedIcon: neonDestination.selectedIcon, |
||||
); |
||||
} |
||||
} |
||||
|
||||
extension TabExtension on Tab { |
||||
static Tab fromNeonDestination(final NeonNavigationDestination neonDestination) => Tab( |
||||
text: neonDestination.label, |
||||
icon: neonDestination.icon(), |
||||
); |
||||
} |
Loading…
Reference in new issue