From 012756bc7c5c97ee75e2cd03e777088257227cc6 Mon Sep 17 00:00:00 2001 From: Paul Kepinski Date: Wed, 15 May 2024 07:24:18 +0200 Subject: [PATCH] Fix(YaruToggleButton): rtl and infinite available space (#896) Fixes #690 --- .../widgets/yaru_toggle_button_layout.dart | 12 +- test/widgets/yaru_toggle_button_test.dart | 258 +++++++++++++++--- 2 files changed, 233 insertions(+), 37 deletions(-) diff --git a/lib/src/widgets/yaru_toggle_button_layout.dart b/lib/src/widgets/yaru_toggle_button_layout.dart index 6b124352b..2395c25d3 100644 --- a/lib/src/widgets/yaru_toggle_button_layout.dart +++ b/lib/src/widgets/yaru_toggle_button_layout.dart @@ -198,9 +198,15 @@ class _YaruRenderToggleButton extends RenderBox ); final titleX = leadingSize.width + horizontalSpacing; - final textConstraints = constraints - .copyWith(maxWidth: constraints.maxWidth - titleX) - .normalize(); + late BoxConstraints textConstraints; + + if (!availableWidth.isInfinite) { + textConstraints = loosened.tighten(width: availableWidth - titleX); + } else { + textConstraints = + constraints.tighten(width: availableWidth - titleX).loosen(); + } + final titleSize = _layoutBox(title, textConstraints); final subtitleSize = _layoutBox(subtitle, textConstraints); diff --git a/test/widgets/yaru_toggle_button_test.dart b/test/widgets/yaru_toggle_button_test.dart index 72ffc470c..05e8b79de 100644 --- a/test/widgets/yaru_toggle_button_test.dart +++ b/test/widgets/yaru_toggle_button_test.dart @@ -8,9 +8,13 @@ void main() { const title = Key('title'); await tester.pumpToggleButton( - const YaruToggleButton( - leading: SizedBox(key: leading, width: 48, height: 48), - title: SizedBox(key: title, width: 128, height: 24), + const Row( + children: [ + YaruToggleButton( + leading: SizedBox(key: leading, width: 48, height: 48), + title: SizedBox(key: title, width: 128, height: 24), + ), + ], ), ); @@ -38,9 +42,13 @@ void main() { const title = Key('title'); await tester.pumpToggleButton( - const YaruToggleButton( - leading: SizedBox(key: leading, width: 24, height: 24), - title: SizedBox(key: title, width: 128, height: 48), + const Row( + children: [ + YaruToggleButton( + leading: SizedBox(key: leading, width: 24, height: 24), + title: SizedBox(key: title, width: 128, height: 48), + ), + ], ), ); @@ -69,10 +77,14 @@ void main() { const subtitle = Key('subtitle'); await tester.pumpToggleButton( - const YaruToggleButton( - leading: SizedBox(key: leading, width: 48, height: 48), - title: SizedBox(key: title, width: 128, height: 24), - subtitle: SizedBox(key: subtitle, width: 192, height: 16), + const Row( + children: [ + YaruToggleButton( + leading: SizedBox(key: leading, width: 48, height: 48), + title: SizedBox(key: title, width: 128, height: 24), + subtitle: SizedBox(key: subtitle, width: 192, height: 16), + ), + ], ), ); @@ -103,14 +115,94 @@ void main() { expect(subtitleRect.height, 16); }); + testWidgets('title expanded', (tester) async { + const leading = Key('leading'); + const title = Key('title'); + + await tester.pumpToggleButton( + const SizedBox( + width: 200, + child: YaruToggleButton( + leading: SizedBox(key: leading, width: 48, height: 48), + title: SizedBox(key: title, height: 24), + ), + ), + ); + + final buttonRect = tester.getRect(find.byType(YaruToggleButton)); + final leadingRect = tester.getRect(find.byKey(leading)); + final titleRect = tester.getRect(find.byKey(title)); + + expect(buttonRect.width, 200); + expect(buttonRect.height, 48); + + expect(leadingRect.left, buttonRect.left); + expect(leadingRect.top, buttonRect.top); + expect(leadingRect.width, 48); + expect(leadingRect.height, 48); + + expect(titleRect.left, greaterThan(leadingRect.right)); + expect(titleRect.center.dy, leadingRect.center.dy); + expect(titleRect.right, buttonRect.right); + expect(titleRect.width, 200 - 8 - 48); + expect(titleRect.height, 24); + }); + + testWidgets('subtitle expanded', (tester) async { + const leading = Key('leading'); + const title = Key('title'); + const subtitle = Key('subtitle'); + + await tester.pumpToggleButton( + const SizedBox( + width: 200, + child: YaruToggleButton( + leading: SizedBox(key: leading, width: 48, height: 48), + title: SizedBox(key: title, height: 24), + subtitle: SizedBox(key: subtitle, height: 16), + ), + ), + ); + + final buttonRect = tester.getRect(find.byType(YaruToggleButton)); + final leadingRect = tester.getRect(find.byKey(leading)); + final titleRect = tester.getRect(find.byKey(title)); + final subtitleRect = tester.getRect(find.byKey(subtitle)); + + expect(buttonRect.width, 200); + expect(buttonRect.height, greaterThan(48)); + + expect(leadingRect.left, buttonRect.left); + expect(leadingRect.top, buttonRect.top); + expect(leadingRect.width, 48); + expect(leadingRect.height, 48); + + expect(titleRect.left, greaterThan(leadingRect.right)); + expect(titleRect.center.dy, leadingRect.center.dy); + expect(titleRect.right, buttonRect.right); + expect(titleRect.width, 200 - 8 - 48); + expect(titleRect.height, 24); + + expect(subtitleRect.left, titleRect.left); + expect(subtitleRect.top, greaterThan(titleRect.bottom)); + expect(subtitleRect.right, buttonRect.right); + expect(subtitleRect.bottom, buttonRect.bottom); + expect(subtitleRect.width, 200 - 8 - 48); + expect(subtitleRect.height, 16); + }); + testWidgets('narrow rtl title', (tester) async { const leading = Key('leading'); const title = Key('title'); await tester.pumpToggleButton( - const YaruToggleButton( - leading: SizedBox(key: leading, width: 48, height: 48), - title: SizedBox(key: title, width: 128, height: 24), + const Row( + children: [ + YaruToggleButton( + leading: SizedBox(key: leading, width: 48, height: 48), + title: SizedBox(key: title, width: 128, height: 24), + ), + ], ), textDirection: TextDirection.rtl, ); @@ -139,9 +231,13 @@ void main() { const title = Key('title'); await tester.pumpToggleButton( - const YaruToggleButton( - leading: SizedBox(key: leading, width: 24, height: 24), - title: SizedBox(key: title, width: 128, height: 48), + const Row( + children: [ + YaruToggleButton( + leading: SizedBox(key: leading, width: 24, height: 24), + title: SizedBox(key: title, width: 128, height: 48), + ), + ], ), textDirection: TextDirection.rtl, ); @@ -171,10 +267,14 @@ void main() { const subtitle = Key('subtitle'); await tester.pumpToggleButton( - const YaruToggleButton( - leading: SizedBox(key: leading, width: 48, height: 48), - title: SizedBox(key: title, width: 128, height: 24), - subtitle: SizedBox(key: subtitle, width: 192, height: 16), + const Row( + children: [ + YaruToggleButton( + leading: SizedBox(key: leading, width: 48, height: 48), + title: SizedBox(key: title, width: 128, height: 24), + subtitle: SizedBox(key: subtitle, width: 192, height: 16), + ), + ], ), textDirection: TextDirection.rtl, ); @@ -206,23 +306,105 @@ void main() { expect(subtitleRect.height, 16); }); - testWidgets('theme spacing', (tester) async { + testWidgets('rtl title expanded', (tester) async { const leading = Key('leading'); const title = Key('title'); - const subtitle = Key('subtitle'); await tester.pumpToggleButton( - const YaruToggleButtonTheme( - data: YaruToggleButtonThemeData( - horizontalSpacing: 24, - verticalSpacing: 12, + const SizedBox( + width: 200, + child: YaruToggleButton( + leading: SizedBox(key: leading, width: 48, height: 48), + title: SizedBox(key: title, height: 24), ), + ), + textDirection: TextDirection.rtl, + ); + + final buttonRect = tester.getRect(find.byType(YaruToggleButton)); + final leadingRect = tester.getRect(find.byKey(leading)); + final titleRect = tester.getRect(find.byKey(title)); + + expect(buttonRect.width, 200); + expect(buttonRect.height, 48); + + expect(leadingRect.right, buttonRect.right); + expect(leadingRect.top, buttonRect.top); + expect(leadingRect.width, 48); + expect(leadingRect.height, 48); + + expect(titleRect.right, lessThan(leadingRect.left)); + expect(titleRect.center.dy, leadingRect.center.dy); + expect(titleRect.left, buttonRect.left); + expect(titleRect.width, 200 - 8 - 48); + expect(titleRect.height, 24); + }); + + testWidgets('rtl subtitle expanded', (tester) async { + const leading = Key('leading'); + const title = Key('title'); + const subtitle = Key('subtitle'); + + await tester.pumpToggleButton( + const SizedBox( + width: 200, child: YaruToggleButton( leading: SizedBox(key: leading, width: 48, height: 48), - title: SizedBox(key: title, width: 128, height: 24), - subtitle: SizedBox(key: subtitle, width: 192, height: 16), + title: SizedBox(key: title, height: 24), + subtitle: SizedBox(key: subtitle, height: 16), ), ), + textDirection: TextDirection.rtl, + ); + + final buttonRect = tester.getRect(find.byType(YaruToggleButton)); + final leadingRect = tester.getRect(find.byKey(leading)); + final titleRect = tester.getRect(find.byKey(title)); + final subtitleRect = tester.getRect(find.byKey(subtitle)); + + expect(buttonRect.width, 200); + expect(buttonRect.height, greaterThan(48)); + + expect(leadingRect.right, buttonRect.right); + expect(leadingRect.top, buttonRect.top); + expect(leadingRect.width, 48); + expect(leadingRect.height, 48); + + expect(titleRect.left, buttonRect.left); + expect(titleRect.center.dy, leadingRect.center.dy); + expect(titleRect.right, lessThan(leadingRect.left)); + expect(titleRect.width, 200 - 8 - 48); + expect(titleRect.height, 24); + + expect(subtitleRect.left, buttonRect.left); + expect(subtitleRect.top, greaterThan(titleRect.bottom)); + expect(subtitleRect.right, lessThan(leadingRect.left)); + expect(subtitleRect.bottom, buttonRect.bottom); + expect(subtitleRect.width, 200 - 8 - 48); + expect(subtitleRect.height, 16); + }); + + testWidgets('theme spacing', (tester) async { + const leading = Key('leading'); + const title = Key('title'); + const subtitle = Key('subtitle'); + + await tester.pumpToggleButton( + const Row( + children: [ + YaruToggleButtonTheme( + data: YaruToggleButtonThemeData( + horizontalSpacing: 24, + verticalSpacing: 12, + ), + child: YaruToggleButton( + leading: SizedBox(key: leading, width: 48, height: 48), + title: SizedBox(key: title, width: 128, height: 24), + subtitle: SizedBox(key: subtitle, width: 192, height: 16), + ), + ), + ], + ), ); final buttonRect = tester.getRect(find.byType(YaruToggleButton)); @@ -257,16 +439,24 @@ void main() { const title = Key('title'); await tester.pumpToggleButton( - const YaruToggleButton( - leading: SizedBox(key: leading, width: 24, height: 24), - title: SizedBox(key: title, width: 96, height: 48), + const Row( + children: [ + YaruToggleButton( + leading: SizedBox(key: leading, width: 24, height: 24), + title: SizedBox(key: title, width: 96, height: 48), + ), + ], ), ); await tester.pumpToggleButton( - const YaruToggleButton( - leading: SizedBox(key: leading, width: 48, height: 48), - title: SizedBox(key: title, width: 128, height: 24), + const Row( + children: [ + YaruToggleButton( + leading: SizedBox(key: leading, width: 48, height: 48), + title: SizedBox(key: title, width: 128, height: 24), + ), + ], ), );