Esri / calcite-design-system

A monorepo containing the packages for Esri's Calcite Design System
https://developers.arcgis.com/calcite-design-system/
Other
269 stars 75 forks source link

Modal: Support `initialFocus` option for focusing a specific element when opened. #8073

Open driskull opened 8 months ago

driskull commented 8 months ago

Check existing issues

Description

In rare cases, it may be needed to focus a specific element when a focus trapped component is opened. For example, focusing a username input within a modal rather than the close button by default. This is a convenience to allow users to quickly type in their username/password and should not be done for every scenario.

In order to support this, we should introduce/expose the initialFocus focus-trap option to allow a user to set a specific element or query string to focus when being opened.

Acceptance Criteria

expose initialFocus option as a property on modal

Relevant Info

No response

Which Component

modal

Example Use Case

const modal = document.querySelector("calcite-modal");
modal.initialFocus = document.querySelector("calcite-input");

Priority impact

p2 - want for current milestone

Calcite package

Esri team

ArcGIS Maps SDK for JavaScript

driskull commented 8 months ago

Maybe this isn't necessary as I'm able to workaround this by doing the following:

onCalciteModalOpen={() => {
    requestAnimationFrame(() => {
      this.myEl?.setFocus();
    });
  }}
macandcheese commented 6 months ago

It's come up a few times that a reciprocal functionality could also be useful - a returnFocus option to focus an element of choice on Modal / Sheet close - something different than the invoking element. While the default behavior works most of the time, there have been some cases where devs want focus to be placed elsewhere on close.

As mentioned for initialFocus, there are workarounds, but it might be nice to build in if this request goes forward.

jcfranco commented 2 weeks ago

Maybe this isn't necessary as I'm able to workaround this by doing the following:

onCalciteModalOpen={() => {
    requestAnimationFrame(() => {
      this.myEl?.setFocus();
    });
  }}

This might be a bug due to modal using componentOnReady when opened and the different behavior in the components output target described in this PR.


As mentioned for initialFocus, there are workarounds, but it might be nice to build in if this request goes forward.

Slightly related, but we decided to move away from setting initial focus via setFocus a while back for the following reasons:

Ideally, the focus should be on the first focusable element as defined by a11y guidelines and consistent with how delegatesFocus works.

If we have focusId then there could be UX inconsistencies where developers are determining where to focus first. Ideally, this is handled by the component either by focusing the first element or using a focus trap to do so.

Would the proposed initialFocus behavior go against this?

driskull commented 2 weeks ago

Yeah I agree with your assessment @jcfranco. We shouldn't have to do this.