Fluentui: Layer: Capture events leak out of Layer when !eventBubblingEnabled

Created on 12 Sep 2018  路  6Comments  路  Source: microsoft/fluentui

  • __Package version(s)__: 6.66.0

Priorities and help requested:

Requested priority: (High)

Products/sites affected: office-online, really anyone who has splitButtons

Describe the issue:

After the Layer change to use Portals, any capture handler will now be called if something inside of the portal fires an event (e.g. the capture handlers are getting higher priority than the in the filterEvent handlers in dispatchListeners array inside of executeDispatchesInOrder in react).

Here simple repro steps for splitButtons (codepen: https://codepen.io/jspurlin/pen/eLMLYm):

  1. Open the ContextualMenu of the splitButton (via mouse or keyboard)
  2. Attempt to arrow around controls

Actual behavior:

Focus is still on the splitButton

Expected behavior:

Focus to be in the ContextualMenu

Additional Notes:

This breaks accessibility for splitButtons, but the larger issues is now any capture handlers will fire, potentially resulting in unexpected/broken behavior

Not sure the best approach to keep any of the "parent" capture events from firing when Portals are involved...

Accessibility Type

All 6 comments

@JasonGore , FYI, I'm fixing the splitButton specific issue with #6330 but this issue is tracking the larger item around capture handlers

Thanks for the fix! This looks like an extension of the onMouseEnter/onMouseLeave behavior that was a known change. I'll review our components for focus usage.

Note, it's not just going to be focus but any capture handlers

Yeah this appears to be similar to onMouseEnter events.. since capture events trickle down, they aren't really leaking out of Portal. Portals causes these events to more accurately respect virtual DOM hierarchy so they traverse down through content towards the portaled elements. I'll check all capture handlers and create a wiki page to capture all of this.

I did an analysis of all of Fabric's capture handler usage and didn't find any other actionable fixes. Please review and let me know what you think. I've also created a Portals wiki page covering known behavior and who is affected.

@jspurlin If you agree, could you close? Thanks!

Component | Notes | Status
-- | -- | --
BaseButton | Fixed by Jeremy. | fixed
ContextualMenu | Capture handler is within portal with other components so its behavior is the same pre-portal vs. post-portal. | resolved
FocusTrapZone | Uses of FTZ within Fabric components are grouped within portal with other components so its behavior is the same pre-portal vs. post-portal. Custom usage of trapping portal components should be responsibility of consumer. | resolved
FocusZone | Uses window capture listeners and its behavior doesn't differ pre-portal vs. post-portal change. | resolved
KeytipLayer | Contains portaled elements in BaseButton, ComboBox, ContextualMenu, Dropdown. Uses window capture listeners and its behavior doesn't differ pre-portal vs. post-portal change. | resolved
SearchBox | Cannot contain portal components. | resolved
TooltipHost | Previously fixed. | fixed
SelectionZone | Theoretically could contain portal components but I could not find any regressive behavior, even with portal children. I don't think it's good to introduce portal-specific behavior that isn't warranted. Decided to leave as-is unless regressions are found. | resolved

@JasonGore , thanks for doing a pass and while there may be regressions in consumers implementations (if they are using capture handlers) the out-of-box components have not regressed.

I'm going to go ahead and close this. If it crops up as a larger issue later it can be readdressed from a potential "general fix" perspective

Was this page helpful?
0 / 5 - 0 ratings