qwikifiers / qwik-ui

Qwik's Headless and styled component library
https://qwikui.com
MIT License
631 stars 144 forks source link

Qwik's handling of preventDefault makes it difficult to create accessible behavior for keyboard events #92

Closed shiroinegai closed 7 months ago

shiroinegai commented 1 year ago

This problem surfaced in trying to re-create native Select behavior.

Native Tab behavior on a select element activates the currently focused option and moves to the next tabbable element, usually the next form input element. As we have re-implemented the Select component without using native elements in favor of better styling capability, additional keyboard event listeners have to be implemented for accessibility.

However, Qwik currently only works with preventDefault as an attribute to an element like so:

<button preventDefault:onKeyUp>
</button>

and the following does not work:

<button onKeyUp$={(e) => {
    if (e.key === 'Tab') {
        e.preventDefault()
    }
}}>
</button>

This means that in order for us to recreate native Tab behavior for a Select component, we would have to set preventDefault on the element, and then re-implement existing behavior like Enter or Space to activate the element. This is potentially extra tedium or would clash with what users may expect when using Qwik UI in the future to compose their own components.

tleperou commented 1 year ago

Interesting thought @shiroinegai you put in here.

Indeed; taking over the accessibility of the native Select if a tough challenge.

Many states have to be taken in account:

I presume there're browsers and devices (e.g screen reader) specific behaviours as well to consider.

So, here're my thoughts: the closer to the native, the happier integration.

I suggest to explore

Aligned with both the native a11y support and devices native controls, that approach handles with no effort the states of disabled, selected, required and focused.

Additional considerations

I'm happy to give a shot on this one!

maiieul commented 7 months ago

I think this can be closed since we have sync$ now.

cc @thejackshelton