@@ -3276,6 +3276,105 @@ void main() {
3276
3276
);
3277
3277
}, skip: kIsWeb && ! isCanvasKit); // https://github.com/flutter/flutter/issues/99933
3278
3278
3279
+ testWidgetsWithLeakTracking ('NavigationRail indicator renders properly when text direction is rtl' , (WidgetTester tester) async {
3280
+ // This is a regression test for https://github.com/flutter/flutter/issues/134361.
3281
+ await tester.pumpWidget (_buildWidget (
3282
+ NavigationRail (
3283
+ selectedIndex: 1 ,
3284
+ extended: true ,
3285
+ destinations: const < NavigationRailDestination > [
3286
+ NavigationRailDestination (
3287
+ icon: Icon (Icons .favorite_border),
3288
+ selectedIcon: Icon (Icons .favorite),
3289
+ label: Text ('ABC' ),
3290
+ ),
3291
+ NavigationRailDestination (
3292
+ icon: Icon (Icons .bookmark_border),
3293
+ selectedIcon: Icon (Icons .bookmark),
3294
+ label: Text ('DEF' ),
3295
+ ),
3296
+ ],
3297
+ ),
3298
+ isRTL: true ,
3299
+ ));
3300
+
3301
+ // Hover the first destination.
3302
+ final TestGesture gesture = await tester.createGesture (kind: PointerDeviceKind .mouse);
3303
+ await gesture.addPointer ();
3304
+ await gesture.moveTo (tester.getCenter (find.byIcon (Icons .favorite_border)));
3305
+ await tester.pumpAndSettle ();
3306
+
3307
+ final RenderObject inkFeatures = tester.allRenderObjects.firstWhere ((RenderObject object) => object.runtimeType.toString () == '_RenderInkFeatures' );
3308
+
3309
+ // Default values from M3 specification.
3310
+ const double railMinExtendedWidth = 256.0 ;
3311
+ const double indicatorHeight = 32.0 ;
3312
+ const double destinationWidth = 72.0 ;
3313
+ const double destinationHorizontalPadding = 8.0 ;
3314
+ const double indicatorWidth = destinationWidth - 2 * destinationHorizontalPadding; // 56.0
3315
+ const double verticalSpacer = 8.0 ;
3316
+ const double verticalDestinationSpacingM3 = 12.0 ;
3317
+
3318
+ // The navigation rail width is the default one because labels are short.
3319
+ final double railWidth = tester.getSize (find.byType (NavigationRail )).width;
3320
+ expect (railWidth, railMinExtendedWidth);
3321
+
3322
+ // Expected indicator position.
3323
+ final double indicatorLeft = railWidth - (destinationWidth - destinationHorizontalPadding / 2 );
3324
+ final double indicatorRight = indicatorLeft + indicatorWidth;
3325
+ final Rect indicatorRect = Rect .fromLTRB (
3326
+ indicatorLeft,
3327
+ verticalDestinationSpacingM3 / 2 ,
3328
+ indicatorRight,
3329
+ verticalDestinationSpacingM3 / 2 + indicatorHeight,
3330
+ );
3331
+ final Rect includedRect = indicatorRect;
3332
+ final Rect excludedRect = includedRect.inflate (10 );
3333
+
3334
+ // Compute the vertical position for the selected destination (the one with 'bookmark' icon).
3335
+ const double destinationHeight = indicatorHeight + verticalDestinationSpacingM3;
3336
+ const double secondDestinationVerticalOffset = verticalSpacer + destinationHeight;
3337
+ const double secondIndicatorVerticalOffset = secondDestinationVerticalOffset + verticalDestinationSpacingM3 / 2 ;
3338
+ const double secondDestinationHorizontalOffset = 800 - railMinExtendedWidth; // RTL.
3339
+
3340
+ expect (
3341
+ inkFeatures,
3342
+ paints
3343
+ ..clipPath (
3344
+ pathMatcher: isPathThat (
3345
+ includes: < Offset > [
3346
+ includedRect.centerLeft,
3347
+ includedRect.topCenter,
3348
+ includedRect.centerRight,
3349
+ includedRect.bottomCenter,
3350
+ ],
3351
+ excludes: < Offset > [
3352
+ excludedRect.centerLeft,
3353
+ excludedRect.topCenter,
3354
+ excludedRect.centerRight,
3355
+ excludedRect.bottomCenter,
3356
+ ],
3357
+ ),
3358
+ )
3359
+ // Hover highlight for the hovered destination (the one with 'favorite' icon).
3360
+ ..rect (
3361
+ rect: indicatorRect,
3362
+ color: const Color (0x0a6750a4 ),
3363
+ )
3364
+ // Indicator for the selected destination (the one with 'bookmark' icon).
3365
+ ..rrect (
3366
+ rrect: RRect .fromLTRBR (
3367
+ secondDestinationHorizontalOffset + indicatorLeft,
3368
+ secondIndicatorVerticalOffset,
3369
+ secondDestinationHorizontalOffset + indicatorRight,
3370
+ secondIndicatorVerticalOffset + indicatorHeight,
3371
+ const Radius .circular (16 ),
3372
+ ),
3373
+ color: const Color (0xffe8def8 ),
3374
+ ),
3375
+ );
3376
+ }, skip: kIsWeb && ! isCanvasKit); // https://github.com/flutter/flutter/issues/99933
3377
+
3279
3378
testWidgetsWithLeakTracking ('NavigationRail indicator scale transform' , (WidgetTester tester) async {
3280
3379
int selectedIndex = 0 ;
3281
3380
Future <void > buildWidget () async {
0 commit comments