mirror of
https://github.com/flutter/flutter
synced 2024-08-24 18:36:03 +00:00
[a11y] Fix date picker cannot focus on the edit field (#143117)
fixes: [DatePicker edit field](https://github.com/flutter/flutter/issues/143116) https://b.corp.google.com/issues/322173632
This commit is contained in:
parent
3f09b23338
commit
846719ecaf
|
@ -394,6 +394,7 @@ class _DatePickerModeToggleButtonState extends State<_DatePickerModeToggleButton
|
|||
label: MaterialLocalizations.of(context).selectYearSemanticsLabel,
|
||||
excludeSemantics: true,
|
||||
button: true,
|
||||
container: true,
|
||||
child: SizedBox(
|
||||
height: _subHeaderHeight,
|
||||
child: InkWell(
|
||||
|
|
|
@ -867,64 +867,76 @@ class _DatePickerHeader extends StatelessWidget {
|
|||
|
||||
switch (orientation) {
|
||||
case Orientation.portrait:
|
||||
return SizedBox(
|
||||
height: _datePickerHeaderPortraitHeight,
|
||||
child: Material(
|
||||
color: backgroundColor,
|
||||
child: Padding(
|
||||
padding: const EdgeInsetsDirectional.only(
|
||||
start: 24,
|
||||
end: 12,
|
||||
bottom: 12,
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
const SizedBox(height: 16),
|
||||
help,
|
||||
const Flexible(child: SizedBox(height: 38)),
|
||||
Row(
|
||||
children: <Widget>[
|
||||
Expanded(child: title),
|
||||
if (entryModeButton != null)
|
||||
entryModeButton!,
|
||||
],
|
||||
),
|
||||
],
|
||||
return Semantics(
|
||||
container: true,
|
||||
child: SizedBox(
|
||||
height: _datePickerHeaderPortraitHeight,
|
||||
child: Material(
|
||||
color: backgroundColor,
|
||||
child: Padding(
|
||||
padding: const EdgeInsetsDirectional.only(
|
||||
start: 24,
|
||||
end: 12,
|
||||
bottom: 12,
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
const SizedBox(height: 16),
|
||||
help,
|
||||
const Flexible(child: SizedBox(height: 38)),
|
||||
Row(
|
||||
children: <Widget>[
|
||||
Expanded(child: title),
|
||||
if (entryModeButton != null)
|
||||
Semantics(
|
||||
container: true,
|
||||
child: entryModeButton,
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
case Orientation.landscape:
|
||||
return SizedBox(
|
||||
width: _datePickerHeaderLandscapeWidth,
|
||||
child: Material(
|
||||
color: backgroundColor,
|
||||
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(
|
||||
return Semantics(
|
||||
container: true,
|
||||
child:SizedBox(
|
||||
width: _datePickerHeaderLandscapeWidth,
|
||||
child: Material(
|
||||
color: backgroundColor,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
const SizedBox(height: 16),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: _headerPaddingLandscape,
|
||||
),
|
||||
child: title,
|
||||
child: help,
|
||||
),
|
||||
),
|
||||
if (entryModeButton != null)
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 4),
|
||||
child: entryModeButton,
|
||||
SizedBox(height: isShort ? 16 : 56),
|
||||
Expanded(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: _headerPaddingLandscape,
|
||||
),
|
||||
child: title,
|
||||
),
|
||||
),
|
||||
],
|
||||
if (entryModeButton != null)
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 4),
|
||||
child: Semantics(
|
||||
container: true,
|
||||
child: entryModeButton,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
|
|
@ -256,21 +256,25 @@ class _InputDatePickerFormFieldState extends State<InputDatePickerFormField> {
|
|||
?? theme.inputDecorationTheme.border
|
||||
?? (useMaterial3 ? const OutlineInputBorder() : const UnderlineInputBorder());
|
||||
|
||||
return TextFormField(
|
||||
decoration: InputDecoration(
|
||||
hintText: widget.fieldHintText ?? localizations.dateHelpText,
|
||||
labelText: widget.fieldLabelText ?? localizations.dateInputLabel,
|
||||
).applyDefaults(inputTheme
|
||||
.merge(datePickerTheme.inputDecorationTheme)
|
||||
.copyWith(border: effectiveInputBorder),
|
||||
return Semantics(
|
||||
container: true,
|
||||
child: TextFormField(
|
||||
decoration: InputDecoration(
|
||||
hintText: widget.fieldHintText ?? localizations.dateHelpText,
|
||||
labelText: widget.fieldLabelText ?? localizations.dateInputLabel,
|
||||
).applyDefaults(
|
||||
inputTheme
|
||||
.merge(datePickerTheme.inputDecorationTheme)
|
||||
.copyWith(border: effectiveInputBorder),
|
||||
),
|
||||
validator: _validateDate,
|
||||
keyboardType: widget.keyboardType ?? TextInputType.datetime,
|
||||
onSaved: _handleSaved,
|
||||
onFieldSubmitted: _handleSubmitted,
|
||||
autofocus: widget.autofocus,
|
||||
controller: _controller,
|
||||
focusNode: widget.focusNode,
|
||||
),
|
||||
validator: _validateDate,
|
||||
keyboardType: widget.keyboardType ?? TextInputType.datetime,
|
||||
onSaved: _handleSaved,
|
||||
onFieldSubmitted: _handleSubmitted,
|
||||
autofocus: widget.autofocus,
|
||||
controller: _controller,
|
||||
focusNode: widget.focusNode,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ import 'package:flutter/foundation.dart';
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import '../widgets/clipboard_utils.dart';
|
||||
|
||||
void main() {
|
||||
TestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
@ -1577,6 +1578,13 @@ void main() {
|
|||
});
|
||||
|
||||
testWidgets('input mode', (WidgetTester tester) async {
|
||||
// Fill the clipboard so that the Paste option is available in the text
|
||||
// selection menu.
|
||||
final MockClipboard mockClipboard = MockClipboard();
|
||||
tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, mockClipboard.handleMethodCall);
|
||||
await Clipboard.setData(const ClipboardData(text: 'Clipboard data'));
|
||||
addTearDown(() => tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, null));
|
||||
|
||||
final SemanticsHandle semantics = tester.ensureSemantics();
|
||||
|
||||
initialEntryMode = DatePickerEntryMode.input;
|
||||
|
@ -1596,7 +1604,20 @@ void main() {
|
|||
isFocusable: true,
|
||||
));
|
||||
|
||||
// The semantics of the InputDatePickerFormField are tested in its tests.
|
||||
expect(tester.getSemantics(find.byType(EditableText)), matchesSemantics(
|
||||
label: 'Enter Date',
|
||||
isTextField: true,
|
||||
isFocused: true,
|
||||
value: '01/15/2016',
|
||||
hasTapAction: true,
|
||||
hasSetTextAction: true,
|
||||
hasSetSelectionAction: true,
|
||||
hasCopyAction: true,
|
||||
hasCutAction: true,
|
||||
hasPasteAction: true,
|
||||
hasMoveCursorBackwardByCharacterAction: true,
|
||||
hasMoveCursorBackwardByWordAction: true,
|
||||
));
|
||||
|
||||
// Ok/Cancel buttons
|
||||
expect(tester.getSemantics(find.text('OK')), matchesSemantics(
|
||||
|
|
Loading…
Reference in a new issue