feat(shell): Material 3 Expressive's shorter navigation bar on phones
The navigation bar below medium windows becomes Material 3 Expressive's flexible one, which Flutter's Material library doesn't have yet: 64 dp high instead of 80, the label of the tab in view in the secondary colour (the tokens of Compose's ShortNavigationBar). Its pill stays Flutter's, 64 dp wide rather than 56, as Flutter fixes it. A trial for review, on its own branch, beside the floating one. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MMm7usAo6q9ZZRoPkWjoxi Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
parent
95a26eb803
commit
f4c502f128
2 changed files with 52 additions and 4 deletions
|
|
@ -4,9 +4,37 @@ import 'package:halkyon_learn_flutter/src/core/theme/theme_extras.dart';
|
|||
import 'package:material_ui/material_ui.dart';
|
||||
|
||||
/// The app's theme for [brightness]: Material 3 with a hand-authored colour
|
||||
/// scheme, the app's own fonts ([appFontFamily]), [ThemeExtras], and the
|
||||
/// current style of progress indicators.
|
||||
ThemeData appTheme(Brightness brightness) => ThemeData(
|
||||
/// scheme, the app's own fonts ([appFontFamily]), [ThemeExtras], the
|
||||
/// current style of progress indicators, and Material 3 Expressive's
|
||||
/// shorter navigation bar.
|
||||
ThemeData appTheme(Brightness brightness) {
|
||||
final theme = _baseTheme(brightness);
|
||||
return theme.copyWith(navigationBarTheme: _flexibleNavigationBar(theme));
|
||||
}
|
||||
|
||||
/// Material 3 Expressive's flexible navigation bar, which Flutter's Material
|
||||
/// library doesn't have yet (checked with v1.6.0): 64 dp high instead of 80,
|
||||
/// the label of the tab in view in the secondary colour (the tokens of
|
||||
/// Compose's `ShortNavigationBar`). Its pill stays Flutter's, 64 dp wide
|
||||
/// rather than the 56 dp the tokens give, as Flutter fixes it.
|
||||
NavigationBarThemeData _flexibleNavigationBar(ThemeData theme) {
|
||||
final scheme = theme.colorScheme;
|
||||
final label = theme.textTheme.labelMedium;
|
||||
return NavigationBarThemeData(
|
||||
height: 64,
|
||||
labelTextStyle: WidgetStateProperty.resolveWith(
|
||||
(states) => label?.copyWith(
|
||||
color: states.contains(WidgetState.disabled)
|
||||
? scheme.onSurfaceVariant.withValues(alpha: 0.38)
|
||||
: states.contains(WidgetState.selected)
|
||||
? scheme.secondary
|
||||
: scheme.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
ThemeData _baseTheme(Brightness brightness) => ThemeData(
|
||||
useMaterial3: true,
|
||||
fontFamily: appFontFamily,
|
||||
fontFamilyFallback: appFontFallback,
|
||||
|
|
|
|||
|
|
@ -118,6 +118,26 @@ void main() {
|
|||
expect(find.byType(NavigationRail), findsNothing);
|
||||
});
|
||||
|
||||
testWidgets("the navigation bar is Material 3 Expressive's shorter one, "
|
||||
'the label of the tab in view in the secondary colour', (tester) async {
|
||||
await showApp(tester, width: 400);
|
||||
|
||||
expect(tester.getSize(find.byType(NavigationBar)).height, 64);
|
||||
final scheme = Theme.of(tester.element(find.byType(NavigationBar)))
|
||||
.colorScheme;
|
||||
Color? colorOf(String label) {
|
||||
final text = find.descendant(
|
||||
of: find.byType(NavigationBar),
|
||||
matching: find.text(label),
|
||||
);
|
||||
return tester.widget<Text>(text).style?.color ??
|
||||
DefaultTextStyle.of(tester.element(text)).style.color;
|
||||
}
|
||||
|
||||
expect(colorOf('Home'), scheme.secondary);
|
||||
expect(colorOf('Library'), scheme.onSurfaceVariant);
|
||||
});
|
||||
|
||||
testWidgets("a studyset's note keeps the tabs beside it", (tester) async {
|
||||
tester.view.physicalSize = const Size(1200, 900);
|
||||
tester.view.devicePixelRatio = 1;
|
||||
|
|
|
|||
Loading…
Reference in a new issue