@@ -3117,6 +3117,9 @@ void main() {
3117
3117
const double destinationWidth = 72.0 ;
3118
3118
const double destinationHorizontalPadding = 8.0 ;
3119
3119
const double indicatorWidth = destinationWidth - 2 * destinationHorizontalPadding; // 56.0
3120
+ const double verticalSpacer = 8.0 ;
3121
+ const double verticalIconLabelSpacing = 4.0 ;
3122
+ const double verticalDestinationSpacing = 12.0 ;
3120
3123
3121
3124
// The navigation rail width is larger than default because of the first destination long label.
3122
3125
final double railWidth = tester.getSize (find.byType (NavigationRail )).width;
@@ -3128,6 +3131,12 @@ void main() {
3128
3131
final Rect includedRect = indicatorRect;
3129
3132
final Rect excludedRect = includedRect.inflate (10 );
3130
3133
3134
+ // Compute the vertical position for the selected destination (the one with 'bookmark' icon).
3135
+ const double labelHeight = 16 ; // fontSize is 12 and height is 1.3.
3136
+ const double destinationHeight = indicatorHeight + verticalIconLabelSpacing + labelHeight + verticalDestinationSpacing;
3137
+ const double secondDestinationVerticalOffset = verticalSpacer + destinationHeight;
3138
+ const double secondIndicatorVerticalOffset = secondDestinationVerticalOffset;
3139
+
3131
3140
expect (
3132
3141
inkFeatures,
3133
3142
paints
@@ -3152,7 +3161,116 @@ void main() {
3152
3161
color: const Color (0x0a6750a4 ),
3153
3162
)
3154
3163
..rrect (
3155
- rrect: RRect .fromLTRBR (indicatorLeft, 72.0 , indicatorRight, 104.0 , const Radius .circular (16 )),
3164
+ rrect: RRect .fromLTRBR (
3165
+ indicatorLeft,
3166
+ secondIndicatorVerticalOffset,
3167
+ indicatorRight,
3168
+ secondIndicatorVerticalOffset + indicatorHeight,
3169
+ const Radius .circular (16 ),
3170
+ ),
3171
+ color: const Color (0xffe8def8 ),
3172
+ ),
3173
+ );
3174
+ }, skip: kIsWeb && ! isCanvasKit); // https://github.com/flutter/flutter/issues/99933
3175
+
3176
+ testWidgetsWithLeakTracking ('NavigationRail indicator renders properly with large icon' , (WidgetTester tester) async {
3177
+ // This is a regression test for https://github.com/flutter/flutter/issues/133799.
3178
+ const double iconSize = 50 ;
3179
+ await _pumpNavigationRail (
3180
+ tester,
3181
+ navigationRailTheme: const NavigationRailThemeData (
3182
+ selectedIconTheme: IconThemeData (size: iconSize),
3183
+ unselectedIconTheme: IconThemeData (size: iconSize),
3184
+ ),
3185
+ navigationRail: NavigationRail (
3186
+ selectedIndex: 1 ,
3187
+ destinations: const < NavigationRailDestination > [
3188
+ NavigationRailDestination (
3189
+ icon: Icon (Icons .favorite_border),
3190
+ selectedIcon: Icon (Icons .favorite),
3191
+ label: Text ('ABC' ),
3192
+ ),
3193
+ NavigationRailDestination (
3194
+ icon: Icon (Icons .bookmark_border),
3195
+ selectedIcon: Icon (Icons .bookmark),
3196
+ label: Text ('DEF' ),
3197
+ ),
3198
+ ],
3199
+ labelType: NavigationRailLabelType .all,
3200
+ ),
3201
+ );
3202
+
3203
+ // Hover the first destination.
3204
+ final TestGesture gesture = await tester.createGesture (kind: PointerDeviceKind .mouse);
3205
+ await gesture.addPointer ();
3206
+ await gesture.moveTo (tester.getCenter (find.byIcon (Icons .favorite_border)));
3207
+ await tester.pumpAndSettle ();
3208
+
3209
+ final RenderObject inkFeatures = tester.allRenderObjects.firstWhere ((RenderObject object) => object.runtimeType.toString () == '_RenderInkFeatures' );
3210
+
3211
+ // Default values from M3 specification.
3212
+ const double railMinWidth = 80.0 ;
3213
+ const double indicatorHeight = 32.0 ;
3214
+ const double destinationWidth = 72.0 ;
3215
+ const double destinationHorizontalPadding = 8.0 ;
3216
+ const double indicatorWidth = destinationWidth - 2 * destinationHorizontalPadding; // 56.0
3217
+ const double verticalSpacer = 8.0 ;
3218
+ const double verticalIconLabelSpacing = 4.0 ;
3219
+ const double verticalDestinationSpacing = 12.0 ;
3220
+
3221
+ // The navigation rail width is the default one because labels are short.
3222
+ final double railWidth = tester.getSize (find.byType (NavigationRail )).width;
3223
+ expect (railWidth, railMinWidth);
3224
+
3225
+ // Expected indicator position.
3226
+ final double indicatorLeft = (railWidth - indicatorWidth) / 2 ;
3227
+ final double indicatorRight = (railWidth + indicatorWidth) / 2 ;
3228
+ const double indicatorTop = (iconSize - indicatorHeight) / 2 ;
3229
+ const double indicatorBottom = (iconSize + indicatorHeight) / 2 ;
3230
+ final Rect indicatorRect = Rect .fromLTRB (indicatorLeft, indicatorTop, indicatorRight, indicatorBottom);
3231
+ final Rect includedRect = indicatorRect;
3232
+ final Rect excludedRect = includedRect.inflate (10 );
3233
+
3234
+ // Compute the vertical position for the selected destination (the one with 'bookmark' icon).
3235
+ const double labelHeight = 16 ; // fontSize is 12 and height is 1.3.
3236
+ const double destinationHeight = iconSize + verticalIconLabelSpacing + labelHeight + verticalDestinationSpacing;
3237
+ const double secondDestinationVerticalOffset = verticalSpacer + destinationHeight;
3238
+ const double indicatorOffset = (iconSize - indicatorHeight) / 2 ;
3239
+ const double secondIndicatorVerticalOffset = secondDestinationVerticalOffset + indicatorOffset;
3240
+
3241
+ expect (
3242
+ inkFeatures,
3243
+ paints
3244
+ ..clipPath (
3245
+ pathMatcher: isPathThat (
3246
+ includes: < Offset > [
3247
+ includedRect.centerLeft,
3248
+ includedRect.topCenter,
3249
+ includedRect.centerRight,
3250
+ includedRect.bottomCenter,
3251
+ ],
3252
+ excludes: < Offset > [
3253
+ excludedRect.centerLeft,
3254
+ excludedRect.topCenter,
3255
+ excludedRect.centerRight,
3256
+ excludedRect.bottomCenter,
3257
+ ],
3258
+ ),
3259
+ )
3260
+ // Hover highlight for the hovered destination (the one with 'favorite' icon).
3261
+ ..rect (
3262
+ rect: indicatorRect,
3263
+ color: const Color (0x0a6750a4 ),
3264
+ )
3265
+ // Indicator for the selected destination (the one with 'bookmark' icon).
3266
+ ..rrect (
3267
+ rrect: RRect .fromLTRBR (
3268
+ indicatorLeft,
3269
+ secondIndicatorVerticalOffset,
3270
+ indicatorRight,
3271
+ secondIndicatorVerticalOffset + indicatorHeight,
3272
+ const Radius .circular (16 ),
3273
+ ),
3156
3274
color: const Color (0xffe8def8 ),
3157
3275
),
3158
3276
);
@@ -5228,10 +5346,14 @@ Future<void> _pumpNavigationRail(
5228
5346
double textScaleFactor = 1.0 ,
5229
5347
required NavigationRail navigationRail,
5230
5348
bool useMaterial3 = true ,
5349
+ NavigationRailThemeData ? navigationRailTheme,
5231
5350
}) async {
5232
5351
await tester.pumpWidget (
5233
5352
MaterialApp (
5234
- theme: ThemeData (useMaterial3: useMaterial3),
5353
+ theme: ThemeData (
5354
+ useMaterial3: useMaterial3,
5355
+ navigationRailTheme: navigationRailTheme,
5356
+ ),
5235
5357
home: Builder (
5236
5358
builder: (BuildContext context) {
5237
5359
return MediaQuery (
0 commit comments