@@ -17,6 +17,7 @@ import 'package:flutter/material.dart';
1717import 'package:flutter_svg/flutter_svg.dart' ;
1818import 'package:ouds_core/components/badge/ouds_badge.dart' ;
1919import 'package:ouds_core/components/common/ouds_icon_status.dart' ;
20+ import 'package:ouds_core/components/navigation/internal/ouds_navigation_bar_indicator_animation.dart' ;
2021import 'package:ouds_core/components/navigation/internal/ouds_navigation_bar_state.dart' ;
2122import 'package:ouds_core/components/navigation/internal/ouds_navigation_bar_status_modifier.dart' ;
2223import 'package:ouds_theme_contract/ouds_theme.dart' ;
@@ -102,10 +103,7 @@ class OudsNavigationBarItem {
102103 height: 26 , //sizeIcon.iconDecorativeExtraSmall,
103104 width: 26 , //sizeIcon.iconDecorativeExtraSmall,
104105 colorFilter: ColorFilter .mode (
105- modifier.getTextIconItemColor (
106- controlState,
107- isSelected,
108- ),
106+ modifier.getTextIconItemColor (controlState, isSelected),
109107 BlendMode .srcIn,
110108 ),
111109 );
@@ -122,19 +120,30 @@ class OudsNavigationBarItem {
122120 }
123121
124122 /// Builds the top indicator shown above the icon when the destination is selected.
125- Container _buildTopIndicatorBar (BuildContext context, OudsBarTokens bar, bool isSelected, OudsNavigationBarControlState controlState) {
126- final navigationBarStatusModifier = OudsNavigationBarStatusModifier (context);
123+ /// Uses an animated indicator that expands from the center when selected and collapses when deselected.
124+ /// Returns SizedBox.shrink() when not selected to avoid taking space.
125+ Widget _buildTopIndicatorBar (
126+ BuildContext context,
127+ OudsBarTokens bar,
128+ bool isSelected,
129+ OudsNavigationBarControlState controlState,
130+ ) {
131+ // Don't show indicator when not selected to avoid taking space
132+ if (! isSelected) {
133+ return SizedBox .shrink ();
134+ }
127135
128- return Container (
129- height: bar.sizeHeightActiveIndicatorCustom, // thickness of the bar
130- width: bar.sizeWidthActiveIndicatorCustomTop, // width of the bar (adjust)
131- decoration: BoxDecoration (
132- color: isSelected ? navigationBarStatusModifier.getIndicatorBarColor (controlState) : Colors .transparent,
133- borderRadius: BorderRadius .horizontal (
134- left: Radius .circular (bar.borderRadiusActiveIndicatorCustomTop),
135- right: Radius .circular (bar.borderRadiusActiveIndicatorCustomTop),
136- ),
137- ),
136+ final navigationBarStatusModifier = OudsNavigationBarStatusModifier (
137+ context,
138+ );
139+
140+ return OudsAnimatedIndicator (
141+ isSelected: isSelected,
142+ color: navigationBarStatusModifier.getIndicatorBarColor (controlState),
143+ thickness: bar.sizeHeightActiveIndicatorCustom,
144+ tabWidth: bar.sizeWidthActiveIndicatorCustomTop,
145+ borderRadius: bar.borderRadiusActiveIndicatorCustomTop,
146+ animationDuration: const Duration (milliseconds: 300 ),
138147 );
139148 }
140149
@@ -164,10 +173,24 @@ class OudsNavigationBarItem {
164173 Flexible (
165174 child: NavigationDestination (
166175 label: label,
167- icon: _buildBadgeIconNavigationDestination (context, icon, modifier, controlState, badge, isSelected: isSelected),
168- selectedIcon: _buildBadgeIconNavigationDestination (context, icon, modifier, controlState, badge, isSelected: isSelected),
176+ icon: _buildBadgeIconNavigationDestination (
177+ context,
178+ icon,
179+ modifier,
180+ controlState,
181+ badge,
182+ isSelected: isSelected,
183+ ),
184+ selectedIcon: _buildBadgeIconNavigationDestination (
185+ context,
186+ icon,
187+ modifier,
188+ controlState,
189+ badge,
190+ isSelected: isSelected,
191+ ),
169192 ),
170- )
193+ ),
171194 ],
172195 );
173196 }
@@ -191,8 +214,22 @@ class OudsNavigationBarItem {
191214
192215 return BottomNavigationBarItem (
193216 label: label,
194- icon: _buildBadgeIconBottomNavigationBarItem (context, icon, modifier, controlState, badge, isSelected: isSelected),
195- activeIcon: _buildBadgeIconBottomNavigationBarItem (context, icon, modifier, controlState, badge, isSelected: isSelected),
217+ icon: _buildBadgeIconBottomNavigationBarItem (
218+ context,
219+ icon,
220+ modifier,
221+ controlState,
222+ badge,
223+ isSelected: isSelected,
224+ ),
225+ activeIcon: _buildBadgeIconBottomNavigationBarItem (
226+ context,
227+ icon,
228+ modifier,
229+ controlState,
230+ badge,
231+ isSelected: isSelected,
232+ ),
196233 );
197234 }
198235
@@ -227,39 +264,29 @@ class OudsNavigationBarItem {
227264 height: 26 , //sizeIcon.iconDecorativeExtraSmall,
228265 width: 26 , //sizeIcon.iconDecorativeExtraSmall,
229266 colorFilter: ColorFilter .mode (
230- modifier.getTextIconItemColor (
231- controlState,
232- isSelected,
233- ),
267+ modifier.getTextIconItemColor (controlState, isSelected),
234268 BlendMode .srcIn,
235269 ),
236270 );
237271
238- return badge != null
239- ? Column (
240- children: [
241- _buildTopIndicatorBar (context, bar, isSelected, controlState),
242- SizedBox (
243- height: 2 ,
244- ),
245- OudsBadge .count (
246- semanticsLabel: badge.contentDescription,
247- label: badge.count.toString (),
248- status: Negative (),
249- size: badge.hasCount ? OudsBadgeSize .medium : OudsBadgeSize .xsmall,
250- child: widgetIcon,
251- ),
252- ],
253- )
254- : Column (
255- children: [
256- _buildTopIndicatorBar (context, bar, isSelected, controlState),
257- SizedBox (
258- height: 2 ,
259- ),
260- widgetIcon,
261- ],
262- );
272+ // Build the children list based on selection state
273+ final children = < Widget > [
274+ _buildTopIndicatorBar (context, bar, isSelected, controlState),
275+ if (isSelected) const SizedBox (height: 2 ),
276+ badge != null
277+ ? OudsBadge .count (
278+ semanticsLabel: badge.contentDescription,
279+ label: badge.count.toString (),
280+ status: Negative (),
281+ size: badge.hasCount
282+ ? OudsBadgeSize .medium
283+ : OudsBadgeSize .xsmall,
284+ child: widgetIcon,
285+ )
286+ : widgetIcon,
287+ ];
288+
289+ return Column (children: children);
263290 }
264291}
265292
0 commit comments