Jack Miller
Jack Miller

Reputation: 7657

Fabric React and CSS transform translateX

I noticed strange behavior of Microsoft Fabric React. The problem happens when a button is moved into view using CSS hover in combination with transform: translateX() and this button creates a Fabric Panel. The problem: When the panel is closed, the hover state seems to be restored (by Fabric React?), even though the mouse has long moved out of the hover area.

Check out this CodePen which isolates and reproduces the problem.

As screenshots:

No hover:

enter image description here

Hover:

enter image description here

After coming back from panel (mouse outside of hover area):

enter image description here

I expected the last screenshot actually to be identical to the first one but I cannot figure out what is going wrong. So my question: What is messing up the hover effect?

Note: I created another snippet which also creates an overlay but without using Fabric's Panel. The problem does not occur there. So is it a bug in Fabric React?

Upvotes: 0

Views: 152

Answers (1)

Jack Miller
Jack Miller

Reputation: 7657

I determined that the problem is the following:

When Fabric React closes the overlay, it restores the focus of the HTML element that was active before the panel was opened. This behavior is buried deep into the Fabric code*. I guess, that this is in general the right thing to do. But in when the focused button is only visible due to a hover effect, the browser has understandably a hard time focusing it. It can be reproduced by entering $("#open-button").focus() in the JS console of the provided Codepen.

My solution: Steal the button's focus before it is clicked and before the panel is opened:

const activeElement = document.activeElement as HTMLElement;
activeElement && activeElement.blur && activeElement.blur();

Only then:

this.setState({ show: true });

* Diff that would disable setting the focus when coming back (but that is surely not what you want! I only added this snippet to show how well this behavior is integrated):

    diff --git "a/office-ui-fabric-react.umd.pretty.js" "b/office-ui-fabric-react.umd.pretty.js"
    index 28df7f6b..d1ca320d 100644
    --- "a/office-ui-fabric-react.umd.pretty.js"
    +++ "b/office-ui-fabric-react.umd.pretty.js"
    @@ -4537,7 +4537,7 @@ and limitations under the License.
                     Or = e;
                     var t = ie(e);
                     t && t.requestAnimationFrame(function () {
    -                    Or && Or.focus(), Or = void 0
                     })
                 }
             }
    @@ -24254,6 +24254,7 @@ and limitations under the License.
                         return v.createElement(Cl, m({}, b), v.createElement(Xa, {
                             role: "dialog",
                             "aria-modal": "true",
    +                        shouldRestoreFocus: false,
                             ariaLabelledBy: j ? W : void 0,
                             onDismiss: this.dismiss,
                             className: Y.hiddenPanel

Upvotes: 1

Related Questions