Git Product home page Git Product logo

Comments (11)

LohitakshTrehan avatar LohitakshTrehan commented on June 27, 2024 2

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.

idoros avatar idoros commented on June 27, 2024 1

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 (maybe parentNode.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.

LohitakshTrehan avatar LohitakshTrehan commented on June 27, 2024 1

https://stackoverflow.com/a/54119840
Found this, maybe helpful.

from tabbable.

stefcameron avatar stefcameron commented on June 27, 2024

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.

LohitakshTrehan avatar LohitakshTrehan commented on June 27, 2024

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.

idoros avatar idoros commented on June 27, 2024

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.

LohitakshTrehan avatar LohitakshTrehan commented on June 27, 2024

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.

idoros avatar idoros commented on June 27, 2024

@LohitakshTrehan did you handle slotted elements in your implementation?

from tabbable.

LohitakshTrehan avatar LohitakshTrehan commented on June 27, 2024

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.

stefcameron avatar stefcameron commented on June 27, 2024

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.

stefcameron avatar stefcameron commented on June 27, 2024

FYI, tabbable@beta has support for shadow DOM. Check it out! Also in focus-trap@beta.

from tabbable.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.