Skip to content

Accept tabIndex in the useFocusable hook#1391

Closed
Andarist wants to merge 1 commit into
adobe:mainfrom
Andarist:usefocusable/accept-tabindex
Closed

Accept tabIndex in the useFocusable hook#1391
Andarist wants to merge 1 commit into
adobe:mainfrom
Andarist:usefocusable/accept-tabindex

Conversation

@Andarist
Copy link
Copy Markdown
Contributor

Closes #1384 , cc @ktabors

✅ Pull Request Checklist:

  • Included link to corresponding React Spectrum GitHub Issue.
  • Added/updated unit tests and storybook for this change (for new code or code which already has tests).
  • Filled out test instructions.
  • Updated documentation (if it already exists for this component).
  • Looked at the Accessibility Practices for this feature - Aria Practices

📝 Test Instructions:

yarn test

@Andarist Andarist force-pushed the usefocusable/accept-tabindex branch 2 times, most recently from d6d03cd to 3424028 Compare December 17, 2020 21:45
@Andarist Andarist force-pushed the usefocusable/accept-tabindex branch from 3424028 to 01bfa24 Compare December 17, 2020 21:55
@dannify
Copy link
Copy Markdown
Member

dannify commented Dec 19, 2020

Plus missing tests?! 🤩 Thankyou

Copy link
Copy Markdown
Member

@snowystinger snowystinger left a comment

Choose a reason for hiding this comment

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

Whoa, thanks for adding tests!
I think we're waiting to merge this as we are just wrapping up testing for our next release. So tiny code freeze :)

excludeFromTabOrder?: boolean
excludeFromTabOrder?: boolean,
/** A tabIndex to return. */
tabIndex?: number
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.

This shows that we'll have 2 competing props - excludeFromTabOrder and tabIndex which both "control" the returned tabIndex. I would say this is not ideal - maybe excludeFromTabOrder should be deprecated in the future?

{
...interactions,
tabIndex: props.excludeFromTabOrder && !props.isDisabled ? -1 : undefined
tabIndex: props.tabIndex ?? (props.excludeFromTabOrder && !props.isDisabled ? -1 : undefined)
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.

q: what should happen for {tabIndex: 0, isDisabled: true}?

@devongovett
Copy link
Copy Markdown
Member

We'd like to keep tabIndex out of our component APIs generally to avoid improper usage (e.g. tabIndex > 0). That's why we have the excludeFromTabOrder prop instead.

Most of the the components using useFocusable are already focusable by default (e.g. textfields, radios, etc.), so we don't need to add a tabIndex explicitly. In other cases, the tabIndex is already controlled by something else (e.g. to implement roving tab index pattern).

useFocusable also won't know whether you want to make an element tabbable, focusable, or both without more information. This would essentially be the same as passing a tabIndex manually. We could add tabIndex as a supported option to the useFocusable hook itself rather than other public APIs, but I'm not sure I see the need since you could just apply it to the element directly. Perhaps this should be documented though. Thoughts?

@Andarist
Copy link
Copy Markdown
Contributor Author

We'd like to keep tabIndex out of our component APIs generally to avoid improper usage (e.g. tabIndex > 0).

That doesn't quite avoid the problem though and you also lose validation opportunity the way it's handled right now.

That's why we have the excludeFromTabOrder prop instead.

That's understandable - but if you plan to proceed with this PR then this creates a tiny conflict between excludeFromTabOrder and tabIndex props

Most of the the components using useFocusable are already focusable by default (e.g. textfields, radios, etc.), so we don't need to add a tabIndex explicitly. In other cases, the tabIndex is already controlled by something else (e.g. to implement roving tab index pattern).

Maybe a good opportunity to add dev-only validation for this in the useEffect? 🤔

We could add tabIndex as a supported option to the useFocusable hook itself rather than other public APIs, but I'm not sure I see the need since you could just apply it to the element directly

The slight problem I have with this is that for a consumer it's not obvious that this is different from other props in other hooks that "could just be applied to the element directly".

Perhaps this should be documented though.

That would definitely be an improvement 👍 I probably don't mind this whole case that much as it feels sort of special - but you have a much broader context to assess if that's actually the case. Docs + validation would be nice though - I believe that this (especially validation) would improve the DX greatly.

@Andarist
Copy link
Copy Markdown
Contributor Author

@devongovett any further thoughts on this PR?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

useFocusable doesn't make element focusable

4 participants