Unverified Commit 913e21e4 authored by Darren Austin's avatar Darren Austin Committed by GitHub

First pass at keyboard navigation for the Material Date Picker (#59279)

parent 0093c6a4
......@@ -8,6 +8,7 @@ import 'package:flutter/widgets.dart';
import '../color_scheme.dart';
import '../icon_button.dart';
import '../material.dart';
import '../text_theme.dart';
import '../theme.dart';
......@@ -127,69 +128,65 @@ class DatePickerHeader extends StatelessWidget {
switch (orientation) {
case Orientation.portrait:
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
height: _datePickerHeaderPortraitHeight,
color: primarySurfaceColor,
padding: const EdgeInsetsDirectional.only(
start: 24,
end: 12,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
const SizedBox(height: 16),
Flexible(child: help),
const SizedBox(height: 38),
Row(
children: <Widget>[
Expanded(child: title),
icon,
],
),
],
),
),
],
);
return SizedBox(
height: _datePickerHeaderPortraitHeight,
child: Material(
color: primarySurfaceColor,
child: Padding(
padding: const EdgeInsetsDirectional.only(
start: 24,
end: 12,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
const SizedBox(height: 16),
Flexible(child: help),
const SizedBox(height: 38),
Row(
children: <Widget>[
Expanded(child: title),
icon,
],
),
],
),
),
),
);
case Orientation.landscape:
return Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
width: _datePickerHeaderLandscapeWidth,
color: primarySurfaceColor,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
const SizedBox(height: 16),
Padding(
return SizedBox(
width: _datePickerHeaderLandscapeWidth,
child: Material(
color: primarySurfaceColor,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
const SizedBox(height: 16),
Padding(
padding: const EdgeInsets.symmetric(
horizontal: _headerPaddingLandscape,
),
child: help,
),
SizedBox(height: isShort ? 16 : 56),
Expanded(
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: _headerPaddingLandscape,
),
child: help,
child: title,
),
SizedBox(height: isShort ? 16 : 56),
Expanded(
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: _headerPaddingLandscape,
),
child: title,
),
),
Padding(
padding: const EdgeInsets.symmetric(
horizontal: 4,
),
child: icon,
),
Padding(
padding: const EdgeInsets.symmetric(
horizontal: 4,
),
],
),
child: icon,
),
],
),
],
),
);
}
return null;
......
......@@ -803,8 +803,7 @@ void main() {
await prepareDatePicker(tester, (Future<DateTime> date) async {
// Header
expect(
tester.getSemantics(find.text('SELECT DATE')), matchesSemantics(
expect(tester.getSemantics(find.text('SELECT DATE')), matchesSemantics(
label: 'SELECT DATE\nFri, Jan 15',
));
......@@ -819,8 +818,7 @@ void main() {
));
// Year mode drop down button
expect(
tester.getSemantics(find.text('January 2016')), matchesSemantics(
expect(tester.getSemantics(find.text('January 2016')), matchesSemantics(
label: 'Select year',
isButton: true,
));
......@@ -983,7 +981,6 @@ void main() {
hasEnabledState: true,
isFocusable: true,
));
});
semantics.dispose();
......@@ -1107,6 +1104,63 @@ void main() {
});
});
group('Keyboard navigation', () {
testWidgets('Can toggle to calendar entry mode', (WidgetTester tester) async {
await prepareDatePicker(tester, (Future<DateTime> date) async {
expect(find.byType(TextField), findsNothing);
// Navigate to the entry toggle button and activate it
await tester.sendKeyEvent(LogicalKeyboardKey.tab);
await tester.sendKeyEvent(LogicalKeyboardKey.tab);
await tester.sendKeyEvent(LogicalKeyboardKey.tab);
await tester.sendKeyEvent(LogicalKeyboardKey.tab);
await tester.sendKeyEvent(LogicalKeyboardKey.space);
await tester.pumpAndSettle();
// Should be in the input mode
expect(find.byType(TextField), findsOneWidget);
});
});
testWidgets('Can toggle to year mode', (WidgetTester tester) async {
await prepareDatePicker(tester, (Future<DateTime> date) async {
expect(find.text('2016'), findsNothing);
// Navigate to the year selector and activate it
await tester.sendKeyEvent(LogicalKeyboardKey.tab);
await tester.sendKeyEvent(LogicalKeyboardKey.space);
await tester.pumpAndSettle();
// The years should be visible
expect(find.text('2016'), findsOneWidget);
});
});
testWidgets('Can navigate next/previous months', (WidgetTester tester) async {
await prepareDatePicker(tester, (Future<DateTime> date) async {
expect(find.text('January 2016'), findsOneWidget);
// Navigate to the previous month button and activate it twice
await tester.sendKeyEvent(LogicalKeyboardKey.tab);
await tester.sendKeyEvent(LogicalKeyboardKey.tab);
await tester.sendKeyEvent(LogicalKeyboardKey.space);
await tester.pumpAndSettle();
await tester.sendKeyEvent(LogicalKeyboardKey.space);
await tester.pumpAndSettle();
// Should be showing Nov 2015
expect(find.text('November 2015'), findsOneWidget);
// Navigate to the next month button and activate it four times
await tester.sendKeyEvent(LogicalKeyboardKey.tab);
await tester.sendKeyEvent(LogicalKeyboardKey.space);
await tester.pumpAndSettle();
await tester.sendKeyEvent(LogicalKeyboardKey.space);
await tester.pumpAndSettle();
await tester.sendKeyEvent(LogicalKeyboardKey.space);
await tester.pumpAndSettle();
await tester.sendKeyEvent(LogicalKeyboardKey.space);
await tester.pumpAndSettle();
// Should be on Mar 2016
expect(find.text('March 2016'), findsOneWidget);
});
});
});
group('Screen configurations', () {
// Test various combinations of screen sizes, orientations and text scales
// to ensure the layout doesn't overflow and cause an exception to be thrown.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment