theKashey / vue-focus-lock

It is a trap! A lock for a Focus. A11y util for scoping a focus.
MIT License
138 stars 14 forks source link

Q: Combined lock targets OR prevent focus from element #2

Open rijkvanzanten opened 6 years ago

rijkvanzanten commented 6 years ago

Heya! Thanks for your awesome work ❤️

I was wondering on your thoughts on the following:

I have a "basic" webpage layout like like follows:

-------------------------------
| header                      |
-------------------------------
| main              |  aside  |
|                   |         | 
|                   |         |
|                   |         |
|                   |         |

On small screens, the aside gets hidden to the side and the header contains a button to toggle it on and off. When the aside is active, the main content get's grayed out and overlayed with the aside.

I was wondering if it's possible using (the current version of) this plugin to lock the focus in both the header and aside, seeing the header stays in view and contains the on-off toggle for the aside.

(An alternative for me that would work too in this example would be locking the focus out of an element, so the element and it's children get "skipped" when tabbing.)

theKashey commented 6 years ago

This is not supported right now, but in the future it will be possible to create a "focus-lock-group" and being able to tab from one "lock" to "another". ETA 1-2 weeks

rijkvanzanten commented 6 years ago

That is awesome! Exactly what I'm looking for 😄

Anyway I can help out? Lemme know!

theKashey commented 6 years ago

Yep, you could. I am not good at Vue, and as the time passes react-focus-lock continues to evolve, as long vue-focus-lock - not, even if 90% of everything is in framework independent focus-lock.

Few things have to be ported from react version:

Literally it just a copy-paste-n-test, but I've never we able to do it :(

PS: Lets keep this issue open.

rijkvanzanten commented 6 years ago

I will see what I can do (tomorrow)! I have some experience in both React and Vue, so I should be able to match the two.

Is there anything in the React version that you rather have merged into the "core" focus-lock?

PS: Lets keep this issue open.

(Wrong button 😅)

theKashey commented 6 years ago

Is there anything in the React version that you rather have merged into the "core" focus-lock?.

might be the activateTrap function, which combines together all the pieces. It is also the right place to implement the feature you are asking for - observed has to be converted into array of traps, and next underlying logic could do it's job properly.

The main problem here is to provide that array, not to handle it. For react implementation I am just going to use singletone(ok, global) variable to store all the Traps, merged together by groupName (active traps only, using a global is ok, it is better than `document.querySelectorAll('[lockGroup=name]').

How would you do this in Vue?

rijkvanzanten commented 6 years ago

it is better than `document.querySelectorAll('[lockGroup=name]').

I have been thinking about, and to me it doesn't sound like that bad of a solution actually!

I think both the Vue and React plugins could rely on the dom-focus-lock repo, with the React and Vue plugins only providing a little bit syntactic sugar:

Dom:

<div class="focus-lock" data-group="group"></div>

Vue:

<focus-lock :group="group" />

React:

<FocusLock group="group" />

The Vue/React plugins would render the same divs, meaning the base JS can do it's work the same way across implementations.

This way, the dom package can get the array by document.querySelectorAll('.focus-lock[group]')

Thoughts on this?

theKashey commented 6 years ago

yeah, it could be the most transparent solution, and then it will be possible to combine vue+react+dom solutions on one page. Still a case sometimes.

theKashey commented 6 years ago

Let me inject the necessary patches into focus-lock, then you will only have to land some attributes on vue-focus-lock.

rijkvanzanten commented 6 years ago

Awesome!

theKashey commented 6 years ago

Scattered focus support just landed on react-focus-lock. The steps to make it work for vue:

  1. Get focus-lock 0.2.0
  2. Set the attribute on trap
    import {constants} from 'focus-lock';
    //and add an attribute on observed node
  3. Enjoy.

activateTrap were left out of focus-lock as long it includes code, relative to React implementation - portals.