Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.

Commit 23a2fa3

Browse files
authored
Reland "Adds API in semanticsconfiguration to decide how to merge chi… (#116895)
* Reland "Adds API in semanticsconfiguration to decide how to merge child semanticsConfigurations (#110730)" This reverts commit 7549925. * makes markNeedsSemanticsUpdate more robust * address comment
1 parent ab47fc3 commit 23a2fa3

File tree

6 files changed

+945
-70
lines changed

6 files changed

+945
-70
lines changed

packages/flutter/lib/src/material/input_decorator.dart

Lines changed: 85 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1329,6 +1329,35 @@ class _RenderDecoration extends RenderBox with SlottedContainerRenderObjectMixin
13291329
return Size.zero;
13301330
}
13311331

1332+
ChildSemanticsConfigurationsResult _childSemanticsConfigurationDelegate(List<SemanticsConfiguration> childConfigs) {
1333+
final ChildSemanticsConfigurationsResultBuilder builder = ChildSemanticsConfigurationsResultBuilder();
1334+
List<SemanticsConfiguration>? prefixMergeGroup;
1335+
List<SemanticsConfiguration>? suffixMergeGroup;
1336+
for (final SemanticsConfiguration childConfig in childConfigs) {
1337+
if (childConfig.tagsChildrenWith(_InputDecoratorState._kPrefixSemanticsTag)) {
1338+
prefixMergeGroup ??= <SemanticsConfiguration>[];
1339+
prefixMergeGroup.add(childConfig);
1340+
} else if (childConfig.tagsChildrenWith(_InputDecoratorState._kSuffixSemanticsTag)) {
1341+
suffixMergeGroup ??= <SemanticsConfiguration>[];
1342+
suffixMergeGroup.add(childConfig);
1343+
} else {
1344+
builder.markAsMergeUp(childConfig);
1345+
}
1346+
}
1347+
if (prefixMergeGroup != null) {
1348+
builder.markAsSiblingMergeGroup(prefixMergeGroup);
1349+
}
1350+
if (suffixMergeGroup != null) {
1351+
builder.markAsSiblingMergeGroup(suffixMergeGroup);
1352+
}
1353+
return builder.build();
1354+
}
1355+
1356+
@override
1357+
void describeSemanticsConfiguration(SemanticsConfiguration config) {
1358+
config.childConfigurationsDelegate = _childSemanticsConfigurationDelegate;
1359+
}
1360+
13321361
@override
13331362
void performLayout() {
13341363
final BoxConstraints constraints = this.constraints;
@@ -1716,12 +1745,16 @@ class _AffixText extends StatelessWidget {
17161745
this.text,
17171746
this.style,
17181747
this.child,
1748+
this.semanticsSortKey,
1749+
required this.semanticsTag,
17191750
});
17201751

17211752
final bool labelIsFloating;
17221753
final String? text;
17231754
final TextStyle? style;
17241755
final Widget? child;
1756+
final SemanticsSortKey? semanticsSortKey;
1757+
final SemanticsTag semanticsTag;
17251758

17261759
@override
17271760
Widget build(BuildContext context) {
@@ -1731,7 +1764,11 @@ class _AffixText extends StatelessWidget {
17311764
duration: _kTransitionDuration,
17321765
curve: _kTransitionCurve,
17331766
opacity: labelIsFloating ? 1.0 : 0.0,
1734-
child: child ?? (text == null ? null : Text(text!, style: style)),
1767+
child: Semantics(
1768+
sortKey: semanticsSortKey,
1769+
tagForChildren: semanticsTag,
1770+
child: child ?? (text == null ? null : Text(text!, style: style)),
1771+
),
17351772
),
17361773
);
17371774
}
@@ -1903,6 +1940,11 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
19031940
late final Animation<double> _floatingLabelAnimation;
19041941
late final AnimationController _shakingLabelController;
19051942
final _InputBorderGap _borderGap = _InputBorderGap();
1943+
static const OrdinalSortKey _kPrefixSemanticsSortOrder = OrdinalSortKey(0);
1944+
static const OrdinalSortKey _kInputSemanticsSortOrder = OrdinalSortKey(1);
1945+
static const OrdinalSortKey _kSuffixSemanticsSortOrder = OrdinalSortKey(2);
1946+
static const SemanticsTag _kPrefixSemanticsTag = SemanticsTag('_InputDecoratorState.prefix');
1947+
static const SemanticsTag _kSuffixSemanticsTag = SemanticsTag('_InputDecoratorState.suffix');
19061948

19071949
@override
19081950
void initState() {
@@ -2227,22 +2269,42 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
22272269
),
22282270
);
22292271

2230-
final Widget? prefix = decoration.prefix == null && decoration.prefixText == null ? null :
2231-
_AffixText(
2232-
labelIsFloating: widget._labelShouldWithdraw,
2233-
text: decoration.prefixText,
2234-
style: MaterialStateProperty.resolveAs(decoration.prefixStyle, materialState) ?? hintStyle,
2235-
child: decoration.prefix,
2236-
);
2237-
2238-
final Widget? suffix = decoration.suffix == null && decoration.suffixText == null ? null :
2239-
_AffixText(
2240-
labelIsFloating: widget._labelShouldWithdraw,
2241-
text: decoration.suffixText,
2242-
style: MaterialStateProperty.resolveAs(decoration.suffixStyle, materialState) ?? hintStyle,
2243-
child: decoration.suffix,
2272+
final bool hasPrefix = decoration.prefix != null || decoration.prefixText != null;
2273+
final bool hasSuffix = decoration.suffix != null || decoration.suffixText != null;
2274+
2275+
Widget? input = widget.child;
2276+
// If at least two out of the three are visible, it needs semantics sort
2277+
// order.
2278+
final bool needsSemanticsSortOrder = widget._labelShouldWithdraw && (input != null ? (hasPrefix || hasSuffix) : (hasPrefix && hasSuffix));
2279+
2280+
final Widget? prefix = hasPrefix
2281+
? _AffixText(
2282+
labelIsFloating: widget._labelShouldWithdraw,
2283+
text: decoration.prefixText,
2284+
style: MaterialStateProperty.resolveAs(decoration.prefixStyle, materialState) ?? hintStyle,
2285+
semanticsSortKey: needsSemanticsSortOrder ? _kPrefixSemanticsSortOrder : null,
2286+
semanticsTag: _kPrefixSemanticsTag,
2287+
child: decoration.prefix,
2288+
)
2289+
: null;
2290+
2291+
final Widget? suffix = hasSuffix
2292+
? _AffixText(
2293+
labelIsFloating: widget._labelShouldWithdraw,
2294+
text: decoration.suffixText,
2295+
style: MaterialStateProperty.resolveAs(decoration.suffixStyle, materialState) ?? hintStyle,
2296+
semanticsSortKey: needsSemanticsSortOrder ? _kSuffixSemanticsSortOrder : null,
2297+
semanticsTag: _kSuffixSemanticsTag,
2298+
child: decoration.suffix,
2299+
)
2300+
: null;
2301+
2302+
if (input != null && needsSemanticsSortOrder) {
2303+
input = Semantics(
2304+
sortKey: _kInputSemanticsSortOrder,
2305+
child: input,
22442306
);
2245-
2307+
}
22462308

22472309
final bool decorationIsDense = decoration.isDense ?? false;
22482310
final double iconSize = decorationIsDense ? 18.0 : 24.0;
@@ -2281,7 +2343,9 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
22812343
color: _getPrefixIconColor(themeData, defaults),
22822344
size: iconSize,
22832345
),
2284-
child: decoration.prefixIcon!,
2346+
child: Semantics(
2347+
child: decoration.prefixIcon,
2348+
),
22852349
),
22862350
),
22872351
),
@@ -2306,7 +2370,9 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
23062370
color: _getSuffixIconColor(themeData, defaults),
23072371
size: iconSize,
23082372
),
2309-
child: decoration.suffixIcon!,
2373+
child: Semantics(
2374+
child: decoration.suffixIcon,
2375+
),
23102376
),
23112377
),
23122378
),
@@ -2383,7 +2449,7 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
23832449
isDense: decoration.isDense,
23842450
visualDensity: themeData.visualDensity,
23852451
icon: icon,
2386-
input: widget.child,
2452+
input: input,
23872453
label: label,
23882454
hint: hint,
23892455
prefix: prefix,

0 commit comments

Comments
 (0)