-
Notifications
You must be signed in to change notification settings - Fork 28.5k
Fix Chip delete button semantic bounds #168310
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
base: master
Are you sure you want to change the base?
Fix Chip delete button semantic bounds #168310
Conversation
width: kMinInteractiveDimension, | ||
height: kMinInteractiveDimension, |
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 is not always this though, based on the MaterialTapTargetSize and VisualDensity, it could be a different rect correct?
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 hesitated on this because it is not clear from the Material spec that the tap target size should change based on visual density.
But you're right: it is preferable to follow what is done in most of the Flutter Material widget.
I updated he PR, using the same logic than several Flutter widgets (radio, checkbox). Which means tap target size defaults to:
- 48x48 on mobile
- 32x32 on desktop
For reference, see
flutter/packages/flutter/lib/src/material/checkbox.dart
Lines 519 to 529 in c02d22d
Size size = switch (effectiveMaterialTapTargetSize) { | |
MaterialTapTargetSize.padded => const Size( | |
kMinInteractiveDimension, | |
kMinInteractiveDimension, | |
), | |
MaterialTapTargetSize.shrinkWrap => const Size( | |
kMinInteractiveDimension - 8.0, | |
kMinInteractiveDimension - 8.0, | |
), | |
}; | |
size += effectiveVisualDensity.baseSizeAdjustment; |
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 am also a bit torn at this, according to material guide there are no exception. and the WCAG has lower limit of 44px. the only guideline that allows for a smaller sizes are google internal guideline (only googler can see, tldr: for web/desktop, prefer 48 pixel but must > 24 pixel), but I think we should just go with 48px so that we don't get into trouble when fulfilling public guideline.
I think the logic of smaller size in different mode originate from
https://github.com/flutter/flutter/pull/18369/files. cc @jonahwilliams , Do you have any insight on how the smaller size are picked?
@override | ||
Rect get semanticBounds => Rect.fromCenter( | ||
center: paintBounds.center, | ||
width: kMinInteractiveDimension, |
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 if the paint size is larger than kMinInteractiveDimension already? maybe this should be a math.min between the actual size and the interactive 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.
Good point, thanks. 🙏
Do you mean math.max instead of math.min? (using the paint size when it is larger than kMinInteractiveDimension).
…e larger than kMinInteractiveDimension
bf68169
to
80e1fd6
Compare
return Semantics( | ||
container: true, | ||
button: true, | ||
|
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.
Just after we actually call _buildDeleteIcon, some similar logic is used. we should ensure the semantic size is consistent, since it is also used for custom hit testing. This is why the hit test area is ok with the right tap target size and visual density, but the semantic bounds did not reflect that.
The constraints that are similarly computed are down near the use of _ChipRedirectingHitDetectionWidget. Maybe we can consolidate the similar logic to compute before we call _buildDeleteIcon, and just pass the size to the method?
@@ -6167,6 +6167,96 @@ void main() { | |||
SystemMouseCursors.forbidden, | |||
); | |||
}); | |||
|
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.
To ensure the custom hit test and the semantic bounds match up and we haven't regressed anything, can you add a test where the delete button is larger than 48x48 - if that is possible? I am less familiar with this widget, and it is surprisingly complex. :)
@@ -2425,6 +2433,55 @@ bool _hitIsOnDeleteIcon({ | |||
}; | |||
} | |||
|
|||
class _DeleteButtonSemantic extends SingleChildRenderObjectWidget { |
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.
nit: should probably name something like ensureMinSemanticsSize
Description
This PR fixes Chip's delete icon semantic tap target.
Chip implementation extends the hit area of the delete icon but it did not expand the semantic bounds.
Before
After
Related Issue
Fixes Chip delete button tap target does not meet platform recommended tap target size
Tests
Adds 1 test.