Skip to content

[FocusTrap] Accept a function in disableRestoreFocus #35307

@m4theushw

Description

@m4theushw

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 mui/mui-x#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.

Metadata

Metadata

Assignees

Labels

scope: focus trapChanges related to the focus trap.type: enhancementIt’s an improvement, but we can’t make up our mind whether it's a bug fix or a new feature.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions