elastic / elastic/eui

[Flyout System] EuiFlyout should restore focus to the trigger element on close for all flyout types

Open
#9,365 4 comments 0 reactions 0 assignees View on GitHub
stale-issue
Dominant language
TypeScript
Stars
6.4k
Forks
911
Avg merge
2d 11h
Merged PRs (30d)
65

Description

**Description:**

`EuiFlyout` wraps its content in `EuiFocusTrap`, which has `returnFocus: true` by default. For overlay flyouts, this restores focus to the previously focused element when the flyout unmounts. However, for push flyouts the focus trap is disabled (``), so no automatic focus restoration occurs.

As a result, consumers must manually manage focus restoration using `setTimeout`:

```typescript
const handleCloseFlyout = useCallback(() => {
setIsFlyoutOpen(false);

setTimeout(() => {
triggerRef.current?.focus();
}, 100);
}, []);
```

This is fragile -- it relies on a hardcoded delay -- and it's easy to forget.

### Proposal

The flyout component already captures the previously focused element on mount (`flyoutToggle` ref). It could restore focus to that element in an unmount cleanup effect, independent of the focus trap. This would cover the push flyout case where `returnFocus` doesn't apply, and would be harmlessly redundant for overlay flyouts where `returnFocus` already handles it.

This would let consumers simplify their close handlers to just:

```typescript
const handleCloseFlyout = useCallback(() => {
setIsFlyoutOpen(false);
}, []);
```

**Motivations for this proposal:**
* Works with conditional rendering (fires during React unmount cleanup)
* Works for both overlay and push flyouts
* Requires no new props
* Isn't a breaking change (adds behavior where there was none for push; is harmlessly redundant with returnFocus for overlay)
* Doesn't depend on animations or the state machine at all

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.