Skip to content
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

Support elements with positive tabindex attributes in single-container traps #974

Merged
merged 4 commits into from
Jun 30, 2023

Conversation

stefcameron
Copy link
Member

@stefcameron stefcameron commented Jun 1, 2023

Fixes #375

ALL existing cypress tests are passing.

The goal is to take the least invasive approach when it comes to enforcing tab order. Let the browser do as much of the work as possible, and only interject when it doesn't do what we expect it to (which is the general theme of focus-trap).

Here's the working demo, including negative tabindex edge case support:

focus-trap-positive-tabindex

DONE:

  • artificially limit the trap to a single container if at least one positive tabindex node is discovered (check for it in updateTabbableNodes()
    • if >1 container && >0 positive tabindex nodes found, then throw Error("trap not supported")
  • handle edge case where MRU focused node had negative tabindex
    • in this case, the browser apparently sets focus on the next element in DOM order, not tabindex order
    • or just ignore this as a rare edge case
  • get rid of DEBUG comments
  • will need to share logic from tabbable about determining tabindex somehow
  • check manually tested examples
  • see if a cypress test can be added for the new positive-tabindex example
  • add changeset
PR Checklist

Please leave this checklist in your PR.

  • Source changes maintain stated browser compatibility.
  • Includes updated docs demo bundle if source/docs code was changed (run npm run demo-bundle in your branch and include the /docs/demo-bundle.js file that gets generated in your PR).
  • Issue being fixed is referenced.
  • Unit test coverage added/updated.
  • E2E (i.e. demos) test coverage added/updated.
    • ⚠️ Non-covered demos (look for // TEST MANUALLY comments here) that can't be fully tested in Cypress have been manually verified.
  • Typings added/updated.
  • Changes do not break SSR:
    • Careful to test typeof document/window !== 'undefined' before using it in code that gets executed on load.
  • README updated (API changes, instructions, etc.).
  • Changes to dependencies explained.
  • Changeset added (run npm run changeset locally to add one, and follow the prompts).
    • EXCEPTION: A Changeset is not required if the change does not affect any of the source files that produce the package bundle. For example, demo changes, tooling changes, test updates, or a new dev-only dependency to run tests more efficiently should not have a Changeset since it will not affect package consumers.

@changeset-bot
Copy link

changeset-bot bot commented Jun 1, 2023

🦋 Changeset detected

Latest commit: e26c3aa

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
focus-trap Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Fixes #375

ALL existing cypress tests are passing.

TODO:

- [ ] get rid of DEBUG comments
- [ ] will need to share logic from tabbable about determining tabindex somehow
- [ ] check manually tested examples
- [ ] see if a cypress test can be added for the new positive-tabindex example
- [ ] add changeset
stefcameron added a commit to focus-trap/tabbable that referenced this pull request Jun 26, 2023
This is needed for focus-trap/focus-trap#974
which will add support for positive tabindexes in focus-trap.
stefcameron added a commit to focus-trap/tabbable that referenced this pull request Jun 26, 2023
This is needed for focus-trap/focus-trap#974
which will add support for positive tabindexes in focus-trap.

Also updates the docs/typings to make them more consistent and fix
some broken links.
stefcameron added a commit to focus-trap/tabbable that referenced this pull request Jun 26, 2023
This is needed for focus-trap/focus-trap#974
which will add support for positive tabindexes in focus-trap.

Also updates the docs/typings to make them more consistent and fix
some broken links.
@stefcameron stefcameron changed the title DRAFT: Support elements with positive tabindex attributes Support elements with positive tabindex attributes in single-container traps Jun 26, 2023
@stefcameron stefcameron marked this pull request as ready for review June 26, 2023 21:12
- focus-trap limited to a single container if at least one positive tabindex
  node is found in any of the containers given to it; an exception is thrown
- handled negative tabindex edge case, setting focus to the next tabbable
  node in DOM order (should be document position, but that would require
  extensive work not worth the effort for this feature)
- Removed all DEBUG comments
- Using new tababble `getTabIndex()` API from tabbable v6.2.0
- Added Cypress test
- Added Changeset
- Manually checked "manual-check" examples
@DaviDevMod
Copy link
Contributor

I made a few adjustments in my fork.
I'm going to reproduce the changes here.

By the way, I noticed this:

const findIndex = function (arr, fn) {

Which can be removed, since tabbable doesn't support IE anymore.
But this change doesn't belong to this PR.

@DaviDevMod
Copy link
Contributor

@stefcameron It looks like I can't review arbitrary lines, eg, I can't review line 516 of index.js to make this suggestion.

So either I open another PR against focus-trap/positive-tabindex or you pull the changes from my fork.

@stefcameron
Copy link
Member Author

@DaviDevMod I think it's because using suggestion in a comment equates to writing directly to a branch. Looks like you made 3 commits in your fork. Might be better to make a PR into this positive-tabindex branch. I should then be able to merge that into this branch/PR, and then the whole into master.

Unless it's just that one suggestion you're wanting to make, in which case I can easily add that myself, but just wondering what's going on there.

@DaviDevMod DaviDevMod mentioned this pull request Jun 27, 2023
DaviDevMod and others added 2 commits June 30, 2023 08:57
* Fix `destinationNode` in case the `target` of the keyboard event has a negative tab index

* Refactor `findNextNavNode`

Simplified the logic a bit and introduced the following condition:

```js
containerGroup.focusableNodes.indexOf(target) >=
  containerGroup.focusableNodes.indexOf(
    containerGroup.lastTabbableNode
  )
```

checking that `target` is either the `lastTabbableNode` in the container or a focusable (and not tabbable) node preceding it in document order.

* Simplify `nextTabbableNode`

* Fix `nextTabbableNode` logic for case in which `node` is not tabbable

* Cache index of `node` within the `focusableNodes` array, in the body of `nextTabbleNode`

* Further simplify `nextTabbableNode`

The logic for the case in which `node` has a negative tab index would work also for non-negative tab indexes.
Distinguishing between the two cases may be more performant in principle, but not enough to justify any added complexity (at least in my opinion).

* Distinguish (again) between `node` with negative and non-negative tab index, in `nextTabbableNode`

This reverts commits 075b58c and f198c2b

* Revert "Refactor `findNextNavNode`"

This reverts commit 91da5ca.
@stefcameron
Copy link
Member Author

@all-contributors add @DaviDevMod for code, bug

@allcontributors
Copy link
Contributor

@stefcameron

I've put up a pull request to add @DaviDevMod! 🎉

@stefcameron stefcameron merged commit 5e2f913 into master Jun 30, 2023
3 checks passed
@stefcameron stefcameron deleted the positive-tabindex branch June 30, 2023 14:35
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.

focus-trap stuck on elements with positive tabIndex
2 participants