-
Notifications
You must be signed in to change notification settings - Fork 28.8k
Improve chip semantics #17927
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve chip semantics #17927
Conversation
@@ -1145,4 +1147,73 @@ void main() { | |||
expect(materialBox, paints..path(color: customTheme.disabledColor)); | |||
expect(labelStyle.style.color, equals(Colors.black.withAlpha(0xde))); | |||
}); | |||
|
|||
testWidgets('Chip semantics', (WidgetTester tester) async { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add some more tests? Would be good to have one that correctly shows that the flag for selected is only present when onSelected is passed in. Similarly, we should ensure that SemanticsFlag.hasEnabledState is not present when the chip is not enable-able.
/cc @gspencergoog as the expert on chips. |
Updated the semantic behavior so that hasEnabledState is present if either callback is present. Added some more tests too |
final SemanticsTester semanticsTester = new SemanticsTester(tester); | ||
|
||
await tester.pumpWidget(new MaterialApp( | ||
home: const Material( | ||
child: const Chip( | ||
child: const RawChip( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why this switch to RawChip here and below?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since every other chip just passes values to RawChip it seems like the better place to test semantics
return new Semantics( | ||
container: true, | ||
selected: widget.selected, | ||
enabled: widget.onPressed != null ? widget.isEnabled : null, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You also need to check if "onSelected" is non-null, since either onPressed or onSelected can be set. What I think you really want is to check the "canTap" accessor.
return new Semantics( | ||
container: true, | ||
selected: widget.selected, | ||
enabled: (widget.onPressed != null || widget.onSelected != null) ? widget.isEnabled : null, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think what you really want is "canTap" here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
Not sure if it makes sense to call out a chip as "disabled", will follow up tomorrow |
Since we'll need to anyway, I've increase the min touch target area to 48x48 making this into a breaking change. This doesn't effect the delete button when TalkBack is off... I'm not sure if that is okay. |
), | ||
), | ||
), | ||
), | ||
); | ||
result = new ConstrainedBox( | ||
constraints: const BoxConstraints(minWidth: 48.0, minHeight: 48.0), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This might cause problems when we get to building an input field with chips in it (think GMail "To:" field): This is going to mean that we have to do interesting things to align the Chip bottom to the baseline of the text, since we'll have to know what the offset to the bottom of the chip is inside this constrained box.
Is there a case for making this expansion optional for Chips that are embedded in other widgets? Also, is the Material spec just not conformant to this 48x48 requirement at all?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems that the visual sizes dictated by the material spec are not directly related to the minimum touch target sizes. It is also complicated by the fact that material widgets exist for android and web/desktop and each has different requirements.
If we need to change the behavior based on the parent, then we could make the additional constraints configurable based on whether the chip is used stand-alone. gmail absorbs the chip semantics of the to:
field into the input box, for example
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
configurable via an input
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about our users who want to violate GAR to get the look they want? Sure, they shouldn't, but people shouldn't speed on the highway either. I think the constraints should be an input to the chip, and by default they're min 48x48.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good, I added a new property which users can pass their own value to, or null to remove entirely.
It's too bad we can't have the touch target use up padding outside the chip if it exists. At least then we wouldn't have touch targets adding padding if there was already padding. |
I'm sure you're aware, but you should follow the "breaking changes" process before submitting this, since it will mess up layouts. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
/// An interface defining the base attributes for a material design chip. | ||
/// | ||
/// Chips are compact elements that represent an attribute, text, entity, or | ||
/// action. | ||
/// | ||
/// The defaults mentioned in the documentation for each attribute are what | ||
/// the implementing classes typically use for defaults (but this class doesn't | ||
/// provide or enforce them). | ||
/// provide or enforce them).f |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove "f"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
@@ -99,6 +101,13 @@ abstract class ChipAttributes { | |||
/// By default, this is 4 logical pixels at the beginning and the end of the | |||
/// label, and zero on top and bottom. | |||
EdgeInsetsGeometry get labelPadding; | |||
|
|||
/// Constraints used to increase the gesture detector size without increasing | |||
/// the visible material of the chip. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe note that this increases layout size?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
Closing in favor of #18369 |
Initial work towards chip accessibility (#16964).