Comments (11)
I agree with @scottfr, currently, even $(":tabbable") selector of jquery-ui doesn't support web components. So it would be great if we can add support for it (of course only in the case where "mode" is open).
It would be interesting to find an approach to this problem. For me personally a solution can work, where I iterate over the DOM nodes and an API could tell me, whether that Node is tabbable or not.
from tabbable.
Unfortunately current solution is not enough as Tabbable code doesn't deal with the concept of shadow dom at all.
This is what needs to be solved as far as I can see:
Query shadow roots
- locate elements with shadow roots
- query internal shadow doms recursively and insert potential nested elements in the correct order into the candidate list
- reorder slotted elements by their slot position and make sure to test them by their slot ancestor instead of parentElement
- sort light/shadow dom separately by tab index (need to check what happens with slotted light dom elements)
The problem is that as far as I know, there is no CSS selector to query elements that has a shadow root. That means that a search needs to iterate on every element to check for .shadowRoot
property and then query it internally. We could provide an attribute to mark elements with shadow root (e.g. data-tabbable-root
), and a utility function to search and mark such elements, allowing a user to mark them themselves or run the function as needed.
edit: we can also offer an option to specify custom element names to simplify the search (in case you know the element list in your application).
Filter elements within shadow dom
parentElement
of top level elements in a shadow root is null - need this to figure out if an element is displayed (maybeparentNode.host
)- when searching for other radio elements with no containing form, the fallback should be to the shadow root and not the document (if one exist)
other
- shadow root elements with
delegatesFocus: true
are probably positive for isTabbable/isFocusable, but might need to be excluded from tabbable/focusable list (always or only when they have internal focusable content?)
No matter the solution, currently Tabbable is tested with jsdom and implementing this without testing in a real browser is problematic.
from tabbable.
https://stackoverflow.com/a/54119840
Found this, maybe helpful.
from tabbable.
For me personally a solution can work, where I iterate over the DOM nodes and an API could tell me, whether that Node is tabbable or not.
This library does now have isTabbable()
and isFocusable()
APIs that might help.
from tabbable.
The approach we followed was BFS traversal of the tree if there is a shadow root element. We used jQuery $(:tabbable)
selector on each element to find if it is tabbable or not and pushed it in array if it is a tabbable element. After that we compared the index of current focused element to the next tabbable element in array. and transfer the focus there. If it was the last, then we started on first array element.
It used a lot of computation. But we needed that feature in our project. There was no visible delay for user.
from tabbable.
BFS traversal of the tree if there is a shadow root element
That is what I was suggesting, but I wouldn't run this by default for every tabbable/focusable call as not all users use shadow-dom (at list not in the current major version, maybe with a flag that can be flipped in the future).
There was no visible delay
That depends on the size and complexity of the DOM you have, the device your code is running on, and how frequent you run your checks.
from tabbable.
Yes we can give a flag.
Your point about performance issue is correct. But our application was fairly complex (around 80k lines of DOM code scanned), mostly run on PCs, and we didn't use it frequently. So for our use case it was perfect.
from tabbable.
@LohitakshTrehan did you handle slotted elements in your implementation?
from tabbable.
No we didnt add any support for slotted elements at that time as we were not using them. Slotted elements are present out in the light-dom, so can be scanned easily even using jQuery $(:tabbable)
. But determining their position with respect to their parent in DOM can be tricky. Even I have to try it, before confirming.
from tabbable.
The problem is that as far as I know, there is no CSS selector to query elements that has a shadow root. That means that a search needs to iterate on every element to check for
.shadowRoot
property and then query it internally. We could provide an attribute to mark elements with shadow root (e.g.data-tabbable-root
), and a utility function to search and mark such elements, allowing a user to mark them themselves or run the function as needed.
@idoros Thanks for the proposal/ideas. I like your idea of supporting a custom data-tabbable-root
attribute which we can add to our CSS queries to find all open shadow DOMs we'd need to scan. Providing a utility function to scan the DOM and add this attribute to any node with an open (element.shadowRoot !== null
) shadow would be nice-to-have, could be added in the future if necessary.
You clearly have more experience with the shadow DOM than I do. I'm trying my best to catch-up, but relying on your knowledge to implement something that will make sense.
Slotted elements are a challenge, but what you're proposing sounds right. We could immediately start today by excluding from the order any elements we find to be tabbable if they have a slot
attribute, which would take care of both open and closed shadow DOMs. We should then find them again when we introspect the shadow DOM they belong to (if it's open), and insert them in the right order WRT to their position within the shadow DOM as opposed to light DOM.
from tabbable.
FYI, tabbable@beta
has support for shadow DOM. Check it out! Also in focus-trap@beta
.
from tabbable.
Related Issues (20)
- element.matches not working in ie 11. HOT 5
- Scroll containers HOT 3
- isTabbableRadio doesn't properly escape query selectors HOT 4
- Use @testing-library/dom and Jest for tests HOT 3
- Add code coverage badge to the README HOT 5
- Restore actual browser testing with Cypress HOT 8
- support inert attribute HOT 13
- Exclude form elements in `:disabled` fieldset HOT 2
- Optimizing displayCheck: 'full' HOT 9
- Bug: isDisabledFromFieldset doesn't check the top-most disabled <fieldset> HOT 3
- Safari: Object passed in getCheckedRadio is not iterable, causing a for loop error HOT 2
- v5.3.0 breaks literally all of our usage of `tabbable` 😅 when called on a node not attached to the document HOT 40
- [MAJOR] isHidden should exclude detached nodes by default
- Firefox throws an error when checking disabled on non button element HOT 4
- IE support broken in v5.3.2+ HOT 1
- tabbable breaks when processing an element with a "scope" attribute HOT 6
- jest error Your focus-trap must have at least one container with at least one tabbable node in it at all times HOT 2
- Can't make it work testing with tabbable mocked HOT 7
- jsdom issue: 'slot):not([inert]' is not a valid selector HOT 7
- Remove nwsapi v2.2.2 override once bug is fixed
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from tabbable.