mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Adds tooltip to semantics node (#87684)
This commit is contained in:
parent
ec6481bed8
commit
2ebc7bee9c
@ -698,7 +698,7 @@ class TooltipState extends State<Tooltip> with SingleTickerProviderStateMixin {
|
||||
_enableFeedback = widget.enableFeedback ?? tooltipTheme.enableFeedback ?? _defaultEnableFeedback;
|
||||
|
||||
Widget result = Semantics(
|
||||
label: _excludeFromSemantics
|
||||
tooltip: _excludeFromSemantics
|
||||
? null
|
||||
: _tooltipMessage,
|
||||
child: widget.child,
|
||||
|
||||
@ -3859,6 +3859,7 @@ class RenderSemanticsAnnotations extends RenderProxyBox {
|
||||
AttributedString? attributedIncreasedValue,
|
||||
AttributedString? attributedDecreasedValue,
|
||||
AttributedString? attributedHint,
|
||||
String? tooltip,
|
||||
SemanticsHintOverrides? hintOverrides,
|
||||
TextDirection? textDirection,
|
||||
SemanticsSortKey? sortKey,
|
||||
@ -3917,6 +3918,7 @@ class RenderSemanticsAnnotations extends RenderProxyBox {
|
||||
_attributedIncreasedValue = attributedIncreasedValue,
|
||||
_attributedDecreasedValue = attributedDecreasedValue,
|
||||
_attributedHint = attributedHint,
|
||||
_tooltip = tooltip,
|
||||
_hintOverrides = hintOverrides,
|
||||
_textDirection = textDirection,
|
||||
_sortKey = sortKey,
|
||||
@ -4311,6 +4313,18 @@ class RenderSemanticsAnnotations extends RenderProxyBox {
|
||||
markNeedsSemanticsUpdate();
|
||||
}
|
||||
|
||||
/// If non-null, sets the [SemanticsNode.tooltip] semantic to the given value.
|
||||
///
|
||||
/// The reading direction is given by [textDirection].
|
||||
String? get tooltip => _tooltip;
|
||||
String? _tooltip;
|
||||
set tooltip(String? value) {
|
||||
if (_tooltip == value)
|
||||
return;
|
||||
_tooltip = value;
|
||||
markNeedsSemanticsUpdate();
|
||||
}
|
||||
|
||||
/// If non-null, sets the [SemanticsConfiguration.hintOverrides] to the given value.
|
||||
SemanticsHintOverrides? get hintOverrides => _hintOverrides;
|
||||
SemanticsHintOverrides? _hintOverrides;
|
||||
@ -4843,6 +4857,8 @@ class RenderSemanticsAnnotations extends RenderProxyBox {
|
||||
config.attributedDecreasedValue = attributedDecreasedValue!;
|
||||
if (attributedHint != null)
|
||||
config.attributedHint = attributedHint!;
|
||||
if (tooltip != null)
|
||||
config.tooltip = tooltip!;
|
||||
if (hintOverrides != null && hintOverrides!.isNotEmpty)
|
||||
config.hintOverrides = hintOverrides;
|
||||
if (scopesRoute != null)
|
||||
|
||||
@ -316,6 +316,7 @@ class SemanticsData with Diagnosticable {
|
||||
required this.attributedIncreasedValue,
|
||||
required this.attributedDecreasedValue,
|
||||
required this.attributedHint,
|
||||
required this.tooltip,
|
||||
required this.textDirection,
|
||||
required this.rect,
|
||||
required this.elevation,
|
||||
@ -339,6 +340,7 @@ class SemanticsData with Diagnosticable {
|
||||
assert(attributedDecreasedValue != null),
|
||||
assert(attributedIncreasedValue != null),
|
||||
assert(attributedHint != null),
|
||||
assert(tooltip == '' || textDirection != null, 'A SemanticsData object with tooltip "$tooltip" had a null textDirection.'),
|
||||
assert(attributedLabel.string == '' || textDirection != null, 'A SemanticsData object with label "${attributedLabel.string}" had a null textDirection.'),
|
||||
assert(attributedValue.string == '' || textDirection != null, 'A SemanticsData object with value "${attributedValue.string}" had a null textDirection.'),
|
||||
assert(attributedDecreasedValue.string == '' || textDirection != null, 'A SemanticsData object with decreasedValue "${attributedDecreasedValue.string}" had a null textDirection.'),
|
||||
@ -429,6 +431,11 @@ class SemanticsData with Diagnosticable {
|
||||
/// See also [hint], which exposes just the raw text.
|
||||
final AttributedString attributedHint;
|
||||
|
||||
/// A textual description of the widget's tooltip.
|
||||
///
|
||||
/// The reading direction is given by [textDirection].
|
||||
final String tooltip;
|
||||
|
||||
/// The reading direction for the text in [label], [value],
|
||||
/// [increasedValue], [decreasedValue], and [hint].
|
||||
final TextDirection? textDirection;
|
||||
@ -587,6 +594,7 @@ class SemanticsData with Diagnosticable {
|
||||
properties.add(AttributedStringProperty('increasedValue', attributedIncreasedValue));
|
||||
properties.add(AttributedStringProperty('decreasedValue', attributedDecreasedValue));
|
||||
properties.add(AttributedStringProperty('hint', attributedHint));
|
||||
properties.add(StringProperty('tooltip', tooltip, defaultValue: ''));
|
||||
properties.add(EnumProperty<TextDirection>('textDirection', textDirection, defaultValue: null));
|
||||
if (textSelection?.isValid ?? false)
|
||||
properties.add(MessageProperty('textSelection', '[${textSelection!.start}, ${textSelection!.end}]'));
|
||||
@ -610,6 +618,7 @@ class SemanticsData with Diagnosticable {
|
||||
&& other.attributedIncreasedValue == attributedIncreasedValue
|
||||
&& other.attributedDecreasedValue == attributedDecreasedValue
|
||||
&& other.attributedHint == attributedHint
|
||||
&& other.tooltip == tooltip
|
||||
&& other.textDirection == textDirection
|
||||
&& other.rect == rect
|
||||
&& setEquals(other.tags, tags)
|
||||
@ -637,6 +646,7 @@ class SemanticsData with Diagnosticable {
|
||||
attributedIncreasedValue,
|
||||
attributedDecreasedValue,
|
||||
attributedHint,
|
||||
tooltip,
|
||||
textDirection,
|
||||
rect,
|
||||
tags,
|
||||
@ -648,8 +658,8 @@ class SemanticsData with Diagnosticable {
|
||||
scrollExtentMin,
|
||||
platformViewId,
|
||||
maxValueLength,
|
||||
currentValueLength,
|
||||
Object.hash(
|
||||
currentValueLength,
|
||||
transform,
|
||||
elevation,
|
||||
thickness,
|
||||
@ -785,6 +795,7 @@ class SemanticsProperties extends DiagnosticableTree {
|
||||
this.decreasedValue,
|
||||
this.attributedDecreasedValue,
|
||||
this.hint,
|
||||
this.tooltip,
|
||||
this.attributedHint,
|
||||
this.hintOverrides,
|
||||
this.textDirection,
|
||||
@ -1178,6 +1189,16 @@ class SemanticsProperties extends DiagnosticableTree {
|
||||
/// * [hint] for a plain string version of this property.
|
||||
final AttributedString? attributedHint;
|
||||
|
||||
/// Provides a textual description of the widget's tooltip.
|
||||
///
|
||||
/// In Android, this property sets the `AccessibilityNodeInfo.setTooltipText`.
|
||||
/// In iOS, this property is appended to the end of the
|
||||
/// `UIAccessibilityElement.accessibilityLabel`.
|
||||
///
|
||||
/// If a [tooltip] is provided, there must either by an ambient
|
||||
/// [Directionality] or an explicit [textDirection] should be provided.
|
||||
final String? tooltip;
|
||||
|
||||
/// Provides hint values which override the default hints on supported
|
||||
/// platforms.
|
||||
///
|
||||
@ -1469,6 +1490,7 @@ class SemanticsProperties extends DiagnosticableTree {
|
||||
properties.add(AttributedStringProperty('attributedDecreasedValue', attributedDecreasedValue, defaultValue: null));
|
||||
properties.add(StringProperty('hint', hint, defaultValue: null));
|
||||
properties.add(AttributedStringProperty('attributedHint', attributedHint, defaultValue: null));
|
||||
properties.add(StringProperty('tooltip', tooltip));
|
||||
properties.add(EnumProperty<TextDirection>('textDirection', textDirection, defaultValue: null));
|
||||
properties.add(DiagnosticsProperty<SemanticsSortKey>('sortKey', sortKey, defaultValue: null));
|
||||
properties.add(DiagnosticsProperty<SemanticsHintOverrides>('hintOverrides', hintOverrides, defaultValue: null));
|
||||
@ -1898,6 +1920,7 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
|
||||
|| _attributedValue != config.attributedValue
|
||||
|| _attributedIncreasedValue != config.attributedIncreasedValue
|
||||
|| _attributedDecreasedValue != config.attributedDecreasedValue
|
||||
|| _tooltip != config.tooltip
|
||||
|| _flags != config._flags
|
||||
|| _textDirection != config.textDirection
|
||||
|| _sortKey != config._sortKey
|
||||
@ -2027,6 +2050,12 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
|
||||
AttributedString get attributedHint => _attributedHint;
|
||||
AttributedString _attributedHint = _kEmptyConfig.attributedHint;
|
||||
|
||||
/// A textual description of the widget's tooltip.
|
||||
///
|
||||
/// The reading direction is given by [textDirection].
|
||||
String get tooltip => _tooltip;
|
||||
String _tooltip = _kEmptyConfig.tooltip;
|
||||
|
||||
/// The elevation along the z-axis at which the [rect] of this [SemanticsNode]
|
||||
/// is located above its parent.
|
||||
///
|
||||
@ -2235,6 +2264,7 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
|
||||
_attributedIncreasedValue = config.attributedIncreasedValue;
|
||||
_attributedDecreasedValue = config.attributedDecreasedValue;
|
||||
_attributedHint = config.attributedHint;
|
||||
_tooltip = config.tooltip;
|
||||
_hintOverrides = config.hintOverrides;
|
||||
_elevation = config.elevation;
|
||||
_thickness = config.thickness;
|
||||
@ -2282,6 +2312,7 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
|
||||
AttributedString attributedIncreasedValue = _attributedIncreasedValue;
|
||||
AttributedString attributedDecreasedValue = _attributedDecreasedValue;
|
||||
AttributedString attributedHint = _attributedHint;
|
||||
String tooltip = _tooltip;
|
||||
TextDirection? textDirection = _textDirection;
|
||||
Set<SemanticsTag>? mergedTags = tags == null ? null : Set<SemanticsTag>.of(tags!);
|
||||
TextSelection? textSelection = _textSelection;
|
||||
@ -2336,6 +2367,8 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
|
||||
attributedIncreasedValue = node._attributedIncreasedValue;
|
||||
if (attributedDecreasedValue == null || attributedDecreasedValue.string == '')
|
||||
attributedDecreasedValue = node._attributedDecreasedValue;
|
||||
if (tooltip == '')
|
||||
tooltip = node._tooltip;
|
||||
if (node.tags != null) {
|
||||
mergedTags ??= <SemanticsTag>{};
|
||||
mergedTags!.addAll(node.tags!);
|
||||
@ -2385,6 +2418,7 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
|
||||
attributedIncreasedValue: attributedIncreasedValue,
|
||||
attributedDecreasedValue: attributedDecreasedValue,
|
||||
attributedHint: attributedHint,
|
||||
tooltip: tooltip,
|
||||
textDirection: textDirection,
|
||||
rect: rect,
|
||||
transform: transform,
|
||||
@ -2457,6 +2491,7 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
|
||||
decreasedValueAttributes: data.attributedDecreasedValue.attributes,
|
||||
hint: data.attributedHint.string,
|
||||
hintAttributes: data.attributedHint.attributes,
|
||||
tooltip: data.tooltip,
|
||||
textDirection: data.textDirection,
|
||||
textSelectionBase: data.textSelection != null ? data.textSelection!.baseOffset : -1,
|
||||
textSelectionExtent: data.textSelection != null ? data.textSelection!.extentOffset : -1,
|
||||
@ -2595,6 +2630,7 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
|
||||
properties.add(AttributedStringProperty('increasedValue', _attributedIncreasedValue));
|
||||
properties.add(AttributedStringProperty('decreasedValue', _attributedDecreasedValue));
|
||||
properties.add(AttributedStringProperty('hint', _attributedHint));
|
||||
properties.add(StringProperty('tooltip', _tooltip, defaultValue: ''));
|
||||
properties.add(EnumProperty<TextDirection>('textDirection', _textDirection, defaultValue: null));
|
||||
properties.add(DiagnosticsProperty<SemanticsSortKey>('sortKey', sortKey, defaultValue: null));
|
||||
if (_textSelection?.isValid ?? false)
|
||||
@ -3955,6 +3991,16 @@ class SemanticsConfiguration {
|
||||
_hasBeenAnnotated = true;
|
||||
}
|
||||
|
||||
/// A textual description of the widget's tooltip.
|
||||
///
|
||||
/// The reading direction is given by [textDirection].
|
||||
String get tooltip => _tooltip;
|
||||
String _tooltip = '';
|
||||
set tooltip(String tooltip) {
|
||||
_tooltip = tooltip;
|
||||
_hasBeenAnnotated = true;
|
||||
}
|
||||
|
||||
/// Provides hint values which override the default hints on supported
|
||||
/// platforms.
|
||||
SemanticsHintOverrides? get hintOverrides => _hintOverrides;
|
||||
@ -4420,6 +4466,8 @@ class SemanticsConfiguration {
|
||||
otherAttributedString: child._attributedHint,
|
||||
otherTextDirection: child.textDirection,
|
||||
);
|
||||
if (_tooltip == '')
|
||||
_tooltip = child._tooltip;
|
||||
|
||||
_thickness = math.max(_thickness, child._thickness + child._elevation);
|
||||
|
||||
@ -4442,6 +4490,7 @@ class SemanticsConfiguration {
|
||||
.._attributedDecreasedValue = _attributedDecreasedValue
|
||||
.._attributedHint = _attributedHint
|
||||
.._hintOverrides = _hintOverrides
|
||||
.._tooltip = _tooltip
|
||||
.._elevation = _elevation
|
||||
.._thickness = _thickness
|
||||
.._flags = _flags
|
||||
|
||||
@ -6695,6 +6695,7 @@ class Semantics extends SingleChildRenderObjectWidget {
|
||||
AttributedString? attributedDecreasedValue,
|
||||
String? hint,
|
||||
AttributedString? attributedHint,
|
||||
String? tooltip,
|
||||
String? onTapHint,
|
||||
String? onLongPressHint,
|
||||
TextDirection? textDirection,
|
||||
@ -6759,6 +6760,7 @@ class Semantics extends SingleChildRenderObjectWidget {
|
||||
attributedDecreasedValue: attributedDecreasedValue,
|
||||
hint: hint,
|
||||
attributedHint: attributedHint,
|
||||
tooltip: tooltip,
|
||||
textDirection: textDirection,
|
||||
sortKey: sortKey,
|
||||
tagForChildren: tagForChildren,
|
||||
@ -6901,6 +6903,7 @@ class Semantics extends SingleChildRenderObjectWidget {
|
||||
attributedIncreasedValue: _effectiveAttributedIncreasedValue,
|
||||
attributedDecreasedValue: _effectiveAttributedDecreasedValue,
|
||||
attributedHint: _effectiveAttributedHint,
|
||||
tooltip: properties.tooltip,
|
||||
hintOverrides: properties.hintOverrides,
|
||||
textDirection: _getTextDirection(context),
|
||||
sortKey: properties.sortKey,
|
||||
@ -6936,7 +6939,8 @@ class Semantics extends SingleChildRenderObjectWidget {
|
||||
final bool containsText = properties.attributedLabel != null ||
|
||||
properties.label != null ||
|
||||
properties.value != null ||
|
||||
properties.hint != null;
|
||||
properties.hint != null ||
|
||||
properties.tooltip != null;
|
||||
|
||||
if (!containsText)
|
||||
return null;
|
||||
@ -6977,6 +6981,7 @@ class Semantics extends SingleChildRenderObjectWidget {
|
||||
..attributedIncreasedValue = _effectiveAttributedIncreasedValue
|
||||
..attributedDecreasedValue = _effectiveAttributedDecreasedValue
|
||||
..attributedHint = _effectiveAttributedHint
|
||||
..tooltip = properties.tooltip
|
||||
..hintOverrides = properties.hintOverrides
|
||||
..namesRoute = properties.namesRoute
|
||||
..textDirection = _getTextDirection(context)
|
||||
|
||||
@ -281,27 +281,33 @@ class _SemanticsDebuggerPainter extends CustomPainter {
|
||||
|
||||
assert(data.attributedLabel != null);
|
||||
final String message;
|
||||
if (data.attributedLabel.string.isEmpty) {
|
||||
final String tooltipAndLabel = <String>[
|
||||
if (data.tooltip.isNotEmpty)
|
||||
data.tooltip,
|
||||
if (data.attributedLabel.string.isNotEmpty)
|
||||
data.attributedLabel.string,
|
||||
].join('\n');
|
||||
if (tooltipAndLabel.isEmpty) {
|
||||
message = annotations.join('; ');
|
||||
} else {
|
||||
final String label;
|
||||
final String effectivelabel;
|
||||
if (data.textDirection == null) {
|
||||
label = '${Unicode.FSI}${data.attributedLabel.string}${Unicode.PDI}';
|
||||
effectivelabel = '${Unicode.FSI}$tooltipAndLabel${Unicode.PDI}';
|
||||
annotations.insert(0, 'MISSING TEXT DIRECTION');
|
||||
} else {
|
||||
switch (data.textDirection!) {
|
||||
case TextDirection.rtl:
|
||||
label = '${Unicode.RLI}${data.attributedLabel.string}${Unicode.PDF}';
|
||||
effectivelabel = '${Unicode.RLI}$tooltipAndLabel${Unicode.PDF}';
|
||||
break;
|
||||
case TextDirection.ltr:
|
||||
label = data.attributedLabel.string;
|
||||
effectivelabel = tooltipAndLabel;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (annotations.isEmpty) {
|
||||
message = label;
|
||||
message = effectivelabel;
|
||||
} else {
|
||||
message = '$label (${annotations.join('; ')})';
|
||||
message = '$effectivelabel (${annotations.join('; ')})';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -154,7 +154,7 @@ void main() {
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(tester.getSemantics(find.byType(BackButton)), matchesSemantics(
|
||||
label: 'Back',
|
||||
tooltip: 'Back',
|
||||
isButton: true,
|
||||
hasEnabledState: true,
|
||||
isEnabled: true,
|
||||
|
||||
@ -649,7 +649,7 @@ void main() {
|
||||
|
||||
// Prev/Next month buttons.
|
||||
expect(tester.getSemantics(previousMonthIcon), matchesSemantics(
|
||||
label: 'Previous month',
|
||||
tooltip: 'Previous month',
|
||||
isButton: true,
|
||||
hasTapAction: true,
|
||||
isEnabled: true,
|
||||
@ -657,7 +657,7 @@ void main() {
|
||||
isFocusable: true,
|
||||
));
|
||||
expect(tester.getSemantics(nextMonthIcon), matchesSemantics(
|
||||
label: 'Next month',
|
||||
tooltip: 'Next month',
|
||||
isButton: true,
|
||||
hasTapAction: true,
|
||||
isEnabled: true,
|
||||
|
||||
@ -1964,7 +1964,7 @@ void main() {
|
||||
],
|
||||
children: <TestSemantics>[
|
||||
TestSemantics(
|
||||
label: 'Delete',
|
||||
tooltip: 'Delete',
|
||||
actions: <SemanticsAction>[SemanticsAction.tap],
|
||||
textDirection: TextDirection.ltr,
|
||||
flags: <SemanticsFlag>[
|
||||
|
||||
@ -817,7 +817,7 @@ void main() {
|
||||
|
||||
// Input mode toggle button
|
||||
expect(tester.getSemantics(switchToInputIcon), matchesSemantics(
|
||||
label: 'Switch to input',
|
||||
tooltip: 'Switch to input',
|
||||
isButton: true,
|
||||
hasTapAction: true,
|
||||
isEnabled: true,
|
||||
@ -860,7 +860,7 @@ void main() {
|
||||
|
||||
// Input mode toggle button
|
||||
expect(tester.getSemantics(switchToCalendarIcon), matchesSemantics(
|
||||
label: 'Switch to calendar',
|
||||
tooltip: 'Switch to calendar',
|
||||
isButton: true,
|
||||
hasTapAction: true,
|
||||
isEnabled: true,
|
||||
|
||||
@ -670,7 +670,7 @@ void main() {
|
||||
semantics.dispose();
|
||||
});
|
||||
|
||||
testWidgets('Tooltip is used as semantics label', (WidgetTester tester) async {
|
||||
testWidgets('Tooltip is used as semantics tooltip', (WidgetTester tester) async {
|
||||
final SemanticsTester semantics = SemanticsTester(tester);
|
||||
|
||||
await tester.pumpWidget(
|
||||
@ -697,7 +697,7 @@ void main() {
|
||||
],
|
||||
children: <TestSemantics>[
|
||||
TestSemantics(
|
||||
label: 'Add Photo',
|
||||
tooltip: 'Add Photo',
|
||||
actions: <SemanticsAction>[
|
||||
SemanticsAction.tap,
|
||||
],
|
||||
|
||||
@ -616,7 +616,7 @@ void main() {
|
||||
SemanticsFlag.isFocusable,
|
||||
],
|
||||
actions: <SemanticsAction>[SemanticsAction.tap],
|
||||
label: 'Back',
|
||||
tooltip: 'Back',
|
||||
textDirection: TextDirection.ltr,
|
||||
),
|
||||
TestSemantics(
|
||||
|
||||
@ -1263,7 +1263,7 @@ void main() {
|
||||
children: <TestSemantics>[
|
||||
TestSemantics.rootChild(
|
||||
id: 1,
|
||||
label: 'TIP',
|
||||
tooltip: 'TIP',
|
||||
textDirection: TextDirection.ltr,
|
||||
),
|
||||
],
|
||||
@ -1462,7 +1462,8 @@ void main() {
|
||||
flags: <SemanticsFlag>[SemanticsFlag.scopesRoute],
|
||||
children: <TestSemantics>[
|
||||
TestSemantics(
|
||||
label: 'Foo\nBar',
|
||||
tooltip: 'Foo',
|
||||
label: 'Bar',
|
||||
textDirection: TextDirection.ltr,
|
||||
),
|
||||
],
|
||||
|
||||
@ -1066,7 +1066,8 @@ void main() {
|
||||
flags: <SemanticsFlag>[SemanticsFlag.scopesRoute],
|
||||
children: <TestSemantics>[
|
||||
TestSemantics(
|
||||
label: 'Foo\nBar',
|
||||
tooltip: 'Foo',
|
||||
label: 'Bar',
|
||||
textDirection: TextDirection.ltr,
|
||||
),
|
||||
],
|
||||
@ -1108,7 +1109,8 @@ void main() {
|
||||
flags: <SemanticsFlag>[SemanticsFlag.scopesRoute],
|
||||
children: <TestSemantics>[
|
||||
TestSemantics(
|
||||
label: 'Foo\nBar',
|
||||
tooltip: 'Foo',
|
||||
label: 'Bar',
|
||||
textDirection: TextDirection.ltr,
|
||||
),
|
||||
],
|
||||
|
||||
@ -561,6 +561,7 @@ void main() {
|
||||
' increasedValue: ""\n'
|
||||
' decreasedValue: ""\n'
|
||||
' hint: ""\n'
|
||||
' tooltip: ""\n'
|
||||
' textDirection: null\n'
|
||||
' sortKey: null\n'
|
||||
' platformViewId: null\n'
|
||||
@ -659,6 +660,7 @@ void main() {
|
||||
' increasedValue: ""\n'
|
||||
' decreasedValue: ""\n'
|
||||
' hint: ""\n'
|
||||
' tooltip: ""\n'
|
||||
' textDirection: null\n'
|
||||
' sortKey: null\n'
|
||||
' platformViewId: null\n'
|
||||
|
||||
@ -158,7 +158,8 @@ void main() {
|
||||
'properties: SemanticsProperties, '
|
||||
'attributedLabel: "label" [SpellOutStringAttribute(TextRange(start: 0, end: 5))], '
|
||||
'attributedValue: "value" [LocaleStringAttribute(TextRange(start: 0, end: 5), en-MX)], '
|
||||
'attributedHint: "hint" [SpellOutStringAttribute(TextRange(start: 1, end: 2))]' // ignore: missing_whitespace_between_adjacent_strings
|
||||
'attributedHint: "hint" [SpellOutStringAttribute(TextRange(start: 1, end: 2))], '
|
||||
'tooltip: null'// ignore: missing_whitespace_between_adjacent_strings
|
||||
')',
|
||||
);
|
||||
|
||||
|
||||
@ -61,6 +61,34 @@ void main() {
|
||||
semantics.dispose();
|
||||
}, semanticsEnabled: false);
|
||||
|
||||
testWidgets('Semantics tooltip', (WidgetTester tester) async {
|
||||
final SemanticsTester semantics = SemanticsTester(tester);
|
||||
|
||||
final TestSemantics expectedSemantics = TestSemantics.root(
|
||||
children: <TestSemantics>[
|
||||
TestSemantics.rootChild(
|
||||
tooltip: 'test1',
|
||||
textDirection: TextDirection.ltr,
|
||||
),
|
||||
],
|
||||
);
|
||||
|
||||
await tester.pumpWidget(
|
||||
Semantics(
|
||||
tooltip: 'test1',
|
||||
textDirection: TextDirection.ltr,
|
||||
),
|
||||
);
|
||||
|
||||
expect(semantics, hasSemantics(
|
||||
expectedSemantics,
|
||||
ignoreTransform: true,
|
||||
ignoreRect: true,
|
||||
ignoreId: true,
|
||||
));
|
||||
semantics.dispose();
|
||||
});
|
||||
|
||||
testWidgets('Detach and reattach assert', (WidgetTester tester) async {
|
||||
final SemanticsTester semantics = SemanticsTester(tester);
|
||||
final GlobalKey key = GlobalKey();
|
||||
|
||||
@ -39,6 +39,7 @@ class TestSemantics {
|
||||
this.actions = 0,
|
||||
this.label = '',
|
||||
this.value = '',
|
||||
this.tooltip = '',
|
||||
this.increasedValue = '',
|
||||
this.decreasedValue = '',
|
||||
this.hint = '',
|
||||
@ -72,6 +73,7 @@ class TestSemantics {
|
||||
this.increasedValue = '',
|
||||
this.decreasedValue = '',
|
||||
this.hint = '',
|
||||
this.tooltip = '',
|
||||
this.textDirection,
|
||||
this.transform,
|
||||
this.textSelection,
|
||||
@ -110,6 +112,7 @@ class TestSemantics {
|
||||
this.label = '',
|
||||
this.hint = '',
|
||||
this.value = '',
|
||||
this.tooltip = '',
|
||||
this.increasedValue = '',
|
||||
this.decreasedValue = '',
|
||||
this.textDirection,
|
||||
@ -176,6 +179,9 @@ class TestSemantics {
|
||||
/// performed on this node.
|
||||
final String hint;
|
||||
|
||||
/// A textual tooltip of this node.
|
||||
final String tooltip;
|
||||
|
||||
/// The reading direction of the [label].
|
||||
///
|
||||
/// Even if this is not set, the [hasSemantics] matcher will verify that if a
|
||||
@ -292,6 +298,8 @@ class TestSemantics {
|
||||
return fail('expected node id $id to have decreasedValue "$decreasedValue" but found value "${nodeData.decreasedValue}".');
|
||||
if (hint != nodeData.hint)
|
||||
return fail('expected node id $id to have hint "$hint" but found hint "${nodeData.hint}".');
|
||||
if (tooltip != nodeData.tooltip)
|
||||
return fail('expected node id $id to have tooltip "$tooltip" but found hint "${nodeData.tooltip}".');
|
||||
if (textDirection != null && textDirection != nodeData.textDirection)
|
||||
return fail('expected node id $id to have textDirection "$textDirection" but found "${nodeData.textDirection}".');
|
||||
if ((nodeData.label != '' || nodeData.value != '' || nodeData.hint != '' || node.increasedValue != '' || node.decreasedValue != '') && nodeData.textDirection == null)
|
||||
@ -365,6 +373,8 @@ class TestSemantics {
|
||||
buf.writeln("$indent decreasedValue: '$decreasedValue',");
|
||||
if (hint != null && hint != '')
|
||||
buf.writeln("$indent hint: '$hint',");
|
||||
if (tooltip != null && tooltip != '')
|
||||
buf.writeln("$indent tooltip: '$tooltip',");
|
||||
if (textDirection != null)
|
||||
buf.writeln('$indent textDirection: $textDirection,');
|
||||
if (textSelection?.isValid ?? false)
|
||||
|
||||
@ -228,7 +228,7 @@ class LabeledTapTargetGuideline extends AccessibilityGuideline {
|
||||
!data.hasAction(ui.SemanticsAction.tap)) {
|
||||
return result;
|
||||
}
|
||||
if (data.label == null || data.label.isEmpty) {
|
||||
if ((data.label == null || data.label.isEmpty) && (data.tooltip == null || data.tooltip.isEmpty)) {
|
||||
result += Evaluation.fail(
|
||||
'$node: expected tappable node to have semantic label, '
|
||||
'but none was found.\n',
|
||||
|
||||
@ -494,6 +494,7 @@ Matcher matchesSemantics({
|
||||
String? increasedValue,
|
||||
AttributedString? attributedIncreasedValue,
|
||||
String? decreasedValue,
|
||||
String? tooltip,
|
||||
AttributedString? attributedDecreasedValue,
|
||||
TextDirection? textDirection,
|
||||
Rect? rect,
|
||||
@ -625,6 +626,7 @@ Matcher matchesSemantics({
|
||||
value: value,
|
||||
attributedValue: attributedValue,
|
||||
increasedValue: increasedValue,
|
||||
tooltip: tooltip,
|
||||
attributedIncreasedValue: attributedIncreasedValue,
|
||||
decreasedValue: decreasedValue,
|
||||
attributedDecreasedValue: attributedDecreasedValue,
|
||||
@ -1783,6 +1785,7 @@ class _MatchesSemanticsData extends Matcher {
|
||||
this.attributedIncreasedValue,
|
||||
this.decreasedValue,
|
||||
this.attributedDecreasedValue,
|
||||
this.tooltip,
|
||||
this.flags,
|
||||
this.actions,
|
||||
this.textDirection,
|
||||
@ -1808,6 +1811,7 @@ class _MatchesSemanticsData extends Matcher {
|
||||
final AttributedString? attributedIncreasedValue;
|
||||
final String? decreasedValue;
|
||||
final AttributedString? attributedDecreasedValue;
|
||||
final String? tooltip;
|
||||
final SemanticsHintOverrides? hintOverrides;
|
||||
final List<SemanticsAction>? actions;
|
||||
final List<CustomSemanticsAction>? customActions;
|
||||
@ -1845,6 +1849,8 @@ class _MatchesSemanticsData extends Matcher {
|
||||
description.add(' with decreasedValue: $decreasedValue ');
|
||||
if (attributedDecreasedValue != null)
|
||||
description.add(' with attributedDecreasedValue: $attributedDecreasedValue');
|
||||
if (tooltip != null)
|
||||
description.add(' with tooltip: $tooltip');
|
||||
if (actions != null)
|
||||
description.add(' with actions: ').addDescriptionOf(actions);
|
||||
if (flags != null)
|
||||
@ -1942,6 +1948,8 @@ class _MatchesSemanticsData extends Matcher {
|
||||
return failWithDescription(
|
||||
matchState, 'attributedDecreasedValue was: ${data.attributedDecreasedValue}');
|
||||
}
|
||||
if (tooltip != null && tooltip != data.tooltip)
|
||||
return failWithDescription(matchState, 'tooltip was: ${data.tooltip}');
|
||||
if (textDirection != null && textDirection != data.textDirection)
|
||||
return failWithDescription(matchState, 'textDirection was: $textDirection');
|
||||
if (rect != null && rect != data.rect)
|
||||
|
||||
@ -566,6 +566,7 @@ void main() {
|
||||
attributedValue: AttributedString('c'),
|
||||
attributedDecreasedValue: AttributedString('d'),
|
||||
attributedHint: AttributedString('e'),
|
||||
tooltip: 'f',
|
||||
textDirection: TextDirection.ltr,
|
||||
rect: const Rect.fromLTRB(0.0, 0.0, 10.0, 10.0),
|
||||
elevation: 3.0,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user