Skip to content

Improve chip semantics#17927

Closed
jonahwilliams wants to merge 9 commits into
flutter:masterfrom
jonahwilliams:a11y_16964
Closed

Improve chip semantics#17927
jonahwilliams wants to merge 9 commits into
flutter:masterfrom
jonahwilliams:a11y_16964

Conversation

@jonahwilliams

Copy link
Copy Markdown
Contributor

Initial work towards chip accessibility (#16964).

  • Ensure that a chip is always focusable.
  • Ensure that the enabled/checked state is communicated.
  • Allows delete to be activated by double tapping an a11y focused chip.

@jonahwilliams jonahwilliams requested a review from goderbauer May 29, 2018 21:32
expect(labelStyle.style.color, equals(Colors.black.withAlpha(0xde)));
});

testWidgets('Chip semantics', (WidgetTester tester) async {

Copy link
Copy Markdown
Member

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.

@goderbauer

Copy link
Copy Markdown
Member

/cc @gspencergoog as the expert on chips.

@jonahwilliams

Copy link
Copy Markdown
Contributor Author

Updated the semantic behavior so that hasEnabledState is present if either callback is present. Added some more tests too

await tester.pumpWidget(new MaterialApp(
home: const Material(
child: const Chip(
child: const RawChip(

Copy link
Copy Markdown
Member

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?

Copy link
Copy Markdown
Contributor Author

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,

Copy link
Copy Markdown
Contributor

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,

Copy link
Copy Markdown
Contributor

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.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@jonahwilliams

Copy link
Copy Markdown
Contributor Author

Not sure if it makes sense to call out a chip as "disabled", will follow up tomorrow

@jonahwilliams

jonahwilliams commented Jun 1, 2018

Copy link
Copy Markdown
Contributor Author

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),

Copy link
Copy Markdown
Contributor

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?

Copy link
Copy Markdown
Contributor Author

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

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

configurable via an input

Copy link
Copy Markdown
Contributor

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.

Copy link
Copy Markdown
Contributor Author

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.

@jonahwilliams

Copy link
Copy Markdown
Contributor Author

For reference here are the results for the a11y scanner without any changes. Each box is a touch-target too small warning (except the icons).

@gspencergoog

Copy link
Copy Markdown
Contributor

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.

@gspencergoog

Copy link
Copy Markdown
Contributor

32384589-a60f0e74-c078-11e7-9bc1-e5b5287aea9d

@gspencergoog

Copy link
Copy Markdown
Contributor

I'm sure you're aware, but you should follow the "breaking changes" process before submitting this, since it will mess up layouts.

@goderbauer goderbauer left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

/// 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

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove "f"?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

EdgeInsetsGeometry get labelPadding;

/// Constraints used to increase the gesture detector size without increasing
/// the visible material of the chip.

Copy link
Copy Markdown
Member

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?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@jonahwilliams

Copy link
Copy Markdown
Contributor Author

Closing in favor of #18369

@github-actions github-actions Bot locked as resolved and limited conversation to collaborators Aug 10, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants