mui / mui/material-ui

[FocusTrap] Accept a function in `disableRestoreFocus`

Open
#35,307 2 comments 0 reactions 1 assignee View on GitHub

@mnajdova is already working on this.

Since Dec 13, 2022.

scope: focus trap type: enhancement
Dominant language
JavaScript
Stars
99.1k
Forks
32.5k
Avg merge
2d 17h
Merged PRs (30d)
106

Description

Summary 💡

Currently, disableRestoreFocus only accepts a boolean. My proposal is to also accept a function, which will be called every time that the prop is checked. The function must return a boolean.

Examples 🌈

Usage:

<FocusTrap
  disableRestoreFocus={() => document.activeElement.className.id === '...'}
/>

Implementation:

diff --git a/packages/mui-base/src/FocusTrap/FocusTrap.js b/packages/mui-base/src/FocusTrap/FocusTrap.js
index c03dd7cc57..056736d222 100644
--- a/packages/mui-base/src/FocusTrap/FocusTrap.js
+++ b/packages/mui-base/src/FocusTrap/FocusTrap.js
@@ -176,7 +176,9 @@ function FocusTrap(props) {
 
     return () => {
       // restoreLastFocus()
-      if (!disableRestoreFocus) {
+      const canRestoreFocus =
+        typeof disableRestoreFocus === 'function' ? disableRestoreFocus() : disableRestoreFocus;
+      if (!canRestoreFocus) {
         // In IE11 it is possible for document.activeElement to be null resulting
         // in nodeToRestore.current being null.
         // Not all elements in IE11 have a focus method.
Motivation 🔦

This idea came to my mind as a proper solution for https://github.com/mui/mui-x/issues/7044. In the DataGrid, clicking in the filter button of the toolbar opens a panel based on FocusTrap. If a DateRangePicker is added to the toolbar, when the user opens the filter panel and immediately clicks the picker input, the FocusTrap tries to focus the filter button again, which closes the calendar. Having a way to conditionally disable the focus restore logic, without requiring a 2nd render to update the disableRestoreFocus prop, would be much more easier to solve this kind of problem. If a function is accepted, we can disable the focus restore logic when document.activeElement is already an element from the toolbar.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.