-
Notifications
You must be signed in to change notification settings - Fork 76
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Consistent focus/blur eventing across components #5147
Comments
FindingsDisabled behaviorIt turns out Using Checked behavior
However, focus is delegated to elements with the native Focus methodCalling the ExamplesThis correctly delegates focus to the internal input: customElements.whenDefined("calcite-filter").then(() =>
document.querySelector("calcite-filter").setFocus()); This does as well, but not without the timeout: customElements
.whenDefined("calcite-filter")
.then(() => setTimeout(() => document.querySelector("calcite-filter").focus(), 1000)); This works too: (async () => {
await customElements.whenDefined("calcite-date-picker");
const el = await document
.querySelector("calcite-date-picker")
.componentOnReady();
requestAnimationFrame(() => el.focus());
})(); From https://github.com/Esri/calcite-design-system/pull/9751/files#r1689436792
Next steps
ResourcesHere is a codepen demonstration: https://codepen.io/benesri/pen/PoavMWM Here is the WICG issue where they made that decision: WICG/webcomponents#830 Specifically this snippet from the issue body:
and this comment near the bottom:
Skipped componentsexpand listSelected valueSkipped due to the inconsistency between
Disabled issueIf a "mock disabled" element is first in the flat tree, it will be delegated focus. A lot of our components can have slotted content as the first focusable element.
Nothing to delegate focus toThe components don't need to delegate focus to another element.
|
@geospatialem I moved this to Stalled because a lot of the components need Franco's feedback. But can you please verify the components that have been completed so far when you have time? You can use the
|
@benelan Thanks for the thorough list to work through! I wasn't able to verify the Is there an additional step needed to ensure
|
Taking another look at inline-editable. The rest don't have customElements
.whenDefined("calcite-date-picker")
.then(() => setTimeout(() => document.querySelector("calcite-date-picker").focus(), 1000)); |
This works for inline-editable (async () => {
await customElements.whenDefined("calcite-inline-editable");
const el = await document
.querySelector("calcite-inline-editable")
.componentOnReady();
requestAnimationFrame(() => el.setFocus());
})(); EditThe above code also works with the native |
Awesome, thanks for the insights! ✨ The above components are verified, will await for discussion on the skipped components upon Franco's return. |
…add setFocus method (#6405) **Related Issue:** #5147 ## Summary Adds the public `setFocus` method to the `delegatesFocus` components that didn't have it. See #5147 (comment)
…add setFocus method (#6405) **Related Issue:** #5147 ## Summary Adds the public `setFocus` method to the `delegatesFocus` components that didn't have it. See #5147 (comment)
…add setFocus method (#6438) **Related Issue:** #5147 ## Summary Adds the public `setFocus` method to the `delegatesFocus` components that don't have it. Ref: #5147 (comment)
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 solutionconsult design regarding potential double focus outline
check browsers focusing is consistent, if not weigh options
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.*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
consult design, a11y concerns from having multiple focus targets from
setFocus
calciteComponent.focus/blur()
for shadow-targeted focus/blur orslottedContent.focus/blur()
for light-targeted focus/blurAdditional resources
setFocus
method should focus on the component's first focusable element #5132cc @benelan @geospatialem
The text was updated successfully, but these errors were encountered: