Skip to content

feat(cdk/interactivity-checker) add config parameter to isFocusable #19594

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

Merged
merged 1 commit into from
Jun 29, 2020

Conversation

vanessanschmitt
Copy link
Collaborator

@vanessanschmitt vanessanschmitt commented Jun 10, 2020

Adds config object to isFocusable so that it can optionally return true
even when an element is invisible. Example use case: call isFocusable
with ignoreVisibility=true to find a focusable element within a
collapsed element. If isFocusable returns true, expand the collapsed
element and focus the focusable element.

Fixes #6468.

@googlebot googlebot added the cla: yes PR author has agreed to Google's Contributor License Agreement label Jun 10, 2020
Copy link
Member

@devversion devversion left a comment

Choose a reason for hiding this comment

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

LGTM. When you get a chance, could you please add the concrete use-case example to the commit message? Thanks!

@devversion devversion added lgtm target: minor This PR is targeted for the next minor release labels Jun 10, 2020
* @returns Whether the element is focusable.
*/
isFocusable(element: HTMLElement): boolean {
isFocusable(element: HTMLElement, includeDisabled = false, includeInvisible = false): boolean {
Copy link
Member

Choose a reason for hiding this comment

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

I generally try to avoid public APIs that use a boolean flag argument:
https://martinfowler.com/bliki/FlagArgument.html

I would prefer to make isPotentiallyFocusable with a more descriptive name, though I'm having a hard time coming up with one. Maybe isPotentiallyFocusable really is the best thing with just good JsDoc.

cc @devversion @crisbeto @andrewseguin @mmalerba ideas?

If we don't have any alternates, I'm good with just making isPotentiallyFocusable public.

Copy link
Member

@devversion devversion Jun 10, 2020

Choose a reason for hiding this comment

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

I'd need to think more about other good names, but if we can't come up with one: I'd personally be hesitant in naming this isPotentiallyFocusable as it seems to signify an even worse API design than using a flag argument here. The use of potentially is extremely ambiguous and it's never clear what it is actually referring to, unless someone dives into the description of the function or adds a good comment at call position.

Personally, I'd prefer option parameters here, as those avoid the ambiguity of flag arguments (which drive Martin Fowler's paper), and also avoid the ambiguity of potentially. e.g.

checker.isFocusable(element, {ignoreDisabled: true});

To be clear: If we could find a good name, then I'd also prefer this over the option parameters (as I agree with the Fowler's post about flag arguments), but if not, then I'd consider the above as a more convenient/ and clear API than the exposure of isPotentiallyFocusable.

Choose a reason for hiding this comment

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

I asked my team for name suggestions for isPotentiallyFocusable. Someone suggested "isFocusableElementType", which seemed nice and descriptive, but overlooks the fact that certain attributes (contenteditable, tabindex) can also make a non-focusable type potentially focusable. Maybe "hasFocusableTypeOrAttributes"?

The option parameters sound like a good backup!

Copy link
Contributor

Choose a reason for hiding this comment

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

Do we actually care about all of the combinations here? ((true,true), (true,false), (false,true), (false,false)) or just the (true,true) and (false,false)?

I actually prefer the flagbag if we care about all of the combinations, otherwise maybe:

  • isCurrentlyFocusable
  • isFocusableWhenNotDisabled
  • isFocusableWhenVisible
  • isFoucsableWhenVisibleAndNotDisabled
    ^-- bleh, so wordy

Choose a reason for hiding this comment

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

We care about the default (false, false), and for my use case I care about (false, true) because I want to include invisible elements but not disabled ones. I just added the includeDisabled flag to be consistent, but I don't actually need that flag, nor can I think of any cases off the top of my head where it would be needed.

Copy link
Member

Choose a reason for hiding this comment

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

Slept on it, some fresh ideas:

  • hasFocusableIdentity
  • hasFocusableQualities
  • supportsFocus
  • supportsInteraction
  • isInteractive
  • readyToMakeAStageDebut

Copy link
Contributor

Choose a reason for hiding this comment

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

I find those kind of vague compared to the ones I suggested, I wouldn't know what they do just by looking at them. And I also still like the flagbag, Martin Fowler aside

Copy link
Contributor

Choose a reason for hiding this comment

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

I agree that adding "potentially" is too vague. I think using an optional object parameter containing booleans would be my preference, since it makes it more explicit from the caller code as well as making it easier to modify later

Copy link
Member

Choose a reason for hiding this comment

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

Ack- I think the config object with the options is the consensus (though I did prefer supportsFocus myself).

So it has been decided!

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Updated with the crowd favorite config object!

@vanessanschmitt vanessanschmitt force-pushed the focusable branch 2 times, most recently from a64abc5 to 17d4355 Compare June 12, 2020 18:21
Copy link
Member

@jelbourn jelbourn left a comment

Choose a reason for hiding this comment

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

LGTM

@jelbourn jelbourn added action: merge The PR is ready for merge by the caretaker merge: fix commit message When the PR is merged, rewrites/fixups of the commit messages are needed labels Jun 12, 2020
Adds config object to isFocusable so that it can optionally return true
even when an element is invisible. Example use case: call isFocusable
with ignoreVisibility=true to find a focusable element within a
collapsed element. If isFocusable returns true, expand the collapsed
element and focus the focusable element.

Fixes angular#6468.
Copy link
Member

@devversion devversion left a comment

Choose a reason for hiding this comment

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

Awesome. LGTM!

@vanessanschmitt vanessanschmitt changed the title feat(cdk/interactivity-checker) isFocusable optionally includes invisible/disabled elements feat(cdk/interactivity-checker) add config parameter to isFocusable Jun 22, 2020
@vanessanschmitt
Copy link
Collaborator Author

vanessanschmitt commented Jun 22, 2020

@jelbourn Do you think this one could be merged soon? It seems like we can be fairly confident it won't break google3 since it just added an optional parameter, and I was hoping to use it for a small a11y feature. I saw it got tagged with "commit message fixup". Let me know if there's anything I can do to help clean that up!

@mmalerba mmalerba added G This is is related to a Google internal issue P2 The issue is important to a large percentage of users, with a workaround labels Jun 23, 2020
@mmalerba
Copy link
Contributor

I marked it P2 to bump it up the caretaker's priority queue. The commit message fixup thing is just a note to the caretaker to change the message when they go to merge it, nothing you need to address.

@vanessanschmitt
Copy link
Collaborator Author

Thank you!!

@jelbourn jelbourn merged commit 51137b6 into angular:master Jun 29, 2020
@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Jul 30, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
action: merge The PR is ready for merge by the caretaker cla: yes PR author has agreed to Google's Contributor License Agreement G This is is related to a Google internal issue merge: fix commit message When the PR is merged, rewrites/fixups of the commit messages are needed P2 The issue is important to a large percentage of users, with a workaround target: minor This PR is targeted for the next minor release
Projects
None yet
Development

Successfully merging this pull request may close these issues.

(Angular/CDK) Expose more methods from interactivity-checker
7 participants