diff --git a/packages/flutter/lib/src/material/calendar_date_picker.dart b/packages/flutter/lib/src/material/calendar_date_picker.dart index e39fba6af50..d203a96cadd 100644 --- a/packages/flutter/lib/src/material/calendar_date_picker.dart +++ b/packages/flutter/lib/src/material/calendar_date_picker.dart @@ -409,6 +409,7 @@ class _DatePickerModeToggleButtonState extends State<_DatePickerModeToggleButton label: MaterialLocalizations.of(context).selectYearSemanticsLabel, excludeSemantics: true, button: true, + container: true, child: SizedBox( height: _subHeaderHeight, child: InkWell( diff --git a/packages/flutter/lib/src/material/date_picker.dart b/packages/flutter/lib/src/material/date_picker.dart index 8b5aadbe911..cf75c91d10f 100644 --- a/packages/flutter/lib/src/material/date_picker.dart +++ b/packages/flutter/lib/src/material/date_picker.dart @@ -861,64 +861,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: [ - const SizedBox(height: 16), - help, - const Flexible(child: SizedBox(height: 38)), - Row( - children: [ - 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: [ + const SizedBox(height: 16), + help, + const Flexible(child: SizedBox(height: 38)), + Row( + children: [ + 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: [ - 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: [ + 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, + ), + ), + ], + ), ), ), ); diff --git a/packages/flutter/lib/src/material/input_date_picker_form_field.dart b/packages/flutter/lib/src/material/input_date_picker_form_field.dart index 6341360da68..62210d6d49b 100644 --- a/packages/flutter/lib/src/material/input_date_picker_form_field.dart +++ b/packages/flutter/lib/src/material/input_date_picker_form_field.dart @@ -256,21 +256,24 @@ class _InputDatePickerFormFieldState extends State { ?? 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, ); } } diff --git a/packages/flutter/test/material/date_picker_test.dart b/packages/flutter/test/material/date_picker_test.dart index 177a79800e9..926e4598600 100644 --- a/packages/flutter/test/material/date_picker_test.dart +++ b/packages/flutter/test/material/date_picker_test.dart @@ -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,22 @@ void main() { isFocusable: true, )); - // The semantics of the InputDatePickerFormField are tested in its tests. + expect(tester.getSemantics(find.byType(EditableText)), matchesSemantics( + label: 'Enter Date', + isEnabled: true, + hasEnabledState: true, + 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(