Description
Overview
Currently, developers have to rely on focusin
/focusout
(composable + bubbling) from component internals or using, internal, blur/focus events for a few components.†
The goal for this effort is to provide a general solution for focus/blur events given that these events are commonly used and expected in many web development scenarios.
Also for consideration, setFocus
has introduced a pattern that can lead to inconsistent focus behavior. Existing usage should be revisited to see if we can consolidate in favor of consistency (one focus pattern to rule them all).
† In general, this works but leads to boilerplate code as focusin
/focusout
fires when you move between elements inside a component and would need to check where focus lies when handling the event.
Tasks
-
determine if
delegatesFocus
is a viable solution-
consult design regarding potential double focus outline
- Design suggests hidding the focus ring on the host and only displaying it on the element it delegates focus to. a11y agrees with the recommendation
- ** Note I haven't seen any double focus rings yet, it may have been a quirk that is worked out now**
-
check browsers focusing is consistent, if not weigh options
- As usual, browsers behave differently when it comes to focus (example). However, since
delegatesFocus
is a web standard, I think we will have better consistency than we would if we try to jerry-rig up our own solution. Once we get it set up in the code we can do more browser testing, but all the browsers have adopted the pattern and are reletaively consistent, based on my research.*
- As usual, browsers behave differently when it comes to focus (example). However, since
-
check that focus/blur events will behave as expected for both light/shadow DOM content (if so, we use these and drop our internal focus/blur events)
-
confirm dev expectations light/shadow DOM content focus/blur (e.g., blurring slotted content not emitting blur on custom element) - https://codepen.io/jcfranco/pen/ZExMgwx?editors=1000
-
check if https://www.npmjs.com/package/delegates-focus-polyfill will fit the bill since Safari 14 doesn't support it
- Safari 16 released so we don't need the polyfill
-
-
consult design, a11y concerns from having multiple focus targets from
setFocus
- if keeping single focusable target, we should consider promoting
calciteComponent.focus/blur()
for shadow-targeted focus/blur orslottedContent.focus/blur()
for light-targeted focus/blur
- if keeping single focusable target, we should consider promoting
Additional resources
- Should delegatesFocus use the flat tree? whatwg/html#7207
- Focus delegation from shadow host should not behave like sequential focus navigation WICG/webcomponents#830 (comment)
- Epic:
setFocus
method should focus on the component's first focusable element #5132 - See if using ShadowRoot.delegatesFocus allows us to call .focus on any focusable calcite component #3626