halkyon_ui's FoldingTabs: the tab row under the app bar's title at the top, scrolling away with the content, the chosen tab's name then small under the title, which, tapped, scrolls back up to the row, as Strava's. Learn's Profile (Profile, Statistics) is built on it, and Train's Profile in tabs: Progress (your body, the last 12 weeks, this year), Days, and Plans where the device doesn't record. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
123 lines
3.7 KiB
Dart
123 lines
3.7 KiB
Dart
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:halkyon_ui/halkyon_ui.dart';
|
|
import 'package:material_ui/material_ui.dart';
|
|
|
|
import '../support/test_app.dart';
|
|
|
|
void main() {
|
|
Widget list(String name) => ListView(
|
|
children: [
|
|
for (var i = 0; i < 40; i++)
|
|
SizedBox(height: 60, child: Text('$name $i')),
|
|
],
|
|
);
|
|
|
|
Future<void> show(WidgetTester tester) async {
|
|
tester.view.physicalSize = const Size(400, 800);
|
|
tester.view.devicePixelRatio = 1;
|
|
addTearDown(tester.view.reset);
|
|
await tester.pumpWidget(
|
|
testApp(
|
|
FoldingTabs(
|
|
title: 'Profile',
|
|
actions: const [Icon(Icons.settings)],
|
|
tabs: [
|
|
FoldingTab(label: 'Progress', body: list('Progress')),
|
|
FoldingTab(label: 'Days', body: list('Day')),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
/// The texts in the app bar.
|
|
Finder inBar(String text) =>
|
|
find.descendant(of: find.byType(AppBar), matching: find.text(text));
|
|
|
|
bool tabRowShows(WidgetTester tester) {
|
|
final row = find.byType(TabBar);
|
|
return row.evaluate().isNotEmpty &&
|
|
tester.getRect(row).bottom >
|
|
tester.getRect(find.byType(AppBar)).bottom + 1;
|
|
}
|
|
|
|
testWidgets('at the top, the tabs show under the title, which stands alone', (
|
|
tester,
|
|
) async {
|
|
await show(tester);
|
|
|
|
expect(inBar('Profile'), findsOneWidget);
|
|
expect(tabRowShows(tester), isTrue);
|
|
expect(inBar('Progress'), findsNothing);
|
|
expect(find.text('Progress 0'), findsOneWidget);
|
|
});
|
|
|
|
testWidgets('scrolled down, the tabs go and the chosen one shows small '
|
|
'under the title', (tester) async {
|
|
await show(tester);
|
|
|
|
await tester.drag(find.text('Progress 3'), const Offset(0, -400));
|
|
await tester.pumpAndSettle();
|
|
|
|
expect(tabRowShows(tester), isFalse);
|
|
expect(inBar('Profile'), findsOneWidget);
|
|
expect(inBar('Progress'), findsOneWidget);
|
|
});
|
|
|
|
testWidgets('scrolled a little, the title stays alone', (tester) async {
|
|
await show(tester);
|
|
|
|
await tester.drag(find.text('Progress 3'), const Offset(0, -10));
|
|
await tester.pumpAndSettle();
|
|
|
|
expect(tabRowShows(tester), isTrue);
|
|
expect(inBar('Progress'), findsNothing);
|
|
});
|
|
|
|
testWidgets('scrolled back up, the tabs come back and the title stands '
|
|
'alone again', (tester) async {
|
|
await show(tester);
|
|
await tester.drag(find.text('Progress 3'), const Offset(0, -400));
|
|
await tester.pumpAndSettle();
|
|
|
|
await tester.drag(find.text('Progress 8'), const Offset(0, 2000));
|
|
await tester.pumpAndSettle();
|
|
|
|
expect(tabRowShows(tester), isTrue);
|
|
expect(inBar('Progress'), findsNothing);
|
|
});
|
|
|
|
testWidgets('the small name follows the tab swiped to', (tester) async {
|
|
await show(tester);
|
|
await tester.drag(find.text('Progress 3'), const Offset(0, -400));
|
|
await tester.pumpAndSettle();
|
|
|
|
await tester.fling(find.text('Progress 8'), const Offset(-300, 0), 1000);
|
|
await tester.pumpAndSettle();
|
|
|
|
expect(find.text('Day 0'), findsOneWidget);
|
|
expect(inBar('Days'), findsOneWidget);
|
|
expect(inBar('Progress'), findsNothing);
|
|
});
|
|
|
|
testWidgets('the folded title tapped brings the tabs back', (tester) async {
|
|
await show(tester);
|
|
await tester.drag(find.text('Progress 3'), const Offset(0, -400));
|
|
await tester.pumpAndSettle();
|
|
|
|
await tester.tap(inBar('Profile'));
|
|
await tester.pumpAndSettle();
|
|
|
|
expect(tabRowShows(tester), isTrue);
|
|
expect(inBar('Progress'), findsNothing);
|
|
});
|
|
|
|
testWidgets('a tab tapped shows its content', (tester) async {
|
|
await show(tester);
|
|
|
|
await tester.tap(find.widgetWithText(Tab, 'Days'));
|
|
await tester.pumpAndSettle();
|
|
|
|
expect(find.text('Day 0'), findsOneWidget);
|
|
});
|
|
}
|