Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Correctly set focus in FocusTrapZone even if focus event does not bubble #15804

Merged
merged 10 commits into from
Jan 21, 2021

Conversation

taurheim
Copy link
Contributor

@taurheim taurheim commented Nov 2, 2020

Pull request checklist

Description of changes

Currently FocusTrapZone only sets its internal focus state onFocus. In some cases if events do not bubble correctly, only onFocusCapture will be called, causing the FocusTrapZone to get "stuck" at the end and not loop back to the front. See more information in issue #15530

Focus areas to test

FocusTrapZone, Modal dialog usage of FocusTrapZone

@codesandbox-ci
Copy link

codesandbox-ci bot commented Nov 2, 2020

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

Latest deployment of this branch, based on commit 3c74328:

Sandbox Source
Fluent UI Button Configuration
codesandbox-react-template Configuration
codesandbox-react-northstar-template Configuration

@msft-github-bot
Copy link
Contributor

msft-github-bot commented Nov 2, 2020

Perf Analysis

No significant results to display.

All results

Scenario Render type Master Ticks PR Ticks Iterations Status
Avatar mount 858 820 5000
BaseButtonCompat mount 974 947 5000
Breadcrumb mount 41854 41922 5000
Checkbox mount 1564 1608 5000
CheckboxBase mount 1338 1347 5000
ChoiceGroup mount 5026 5064 5000
ComboBox mount 989 964 1000
CommandBar mount 10126 10039 1000
ContextualMenu mount 6062 6176 1000
DefaultButtonCompat mount 1175 1169 5000
DetailsRow mount 3782 3883 5000
DetailsRowFast mount 3747 3802 5000
DetailsRowNoStyles mount 3614 3597 5000
Dialog mount 1496 1486 1000
DocumentCardTitle mount 1756 1799 1000
Dropdown mount 3406 3371 5000
FocusTrapZone mount 1828 1794 5000
FocusZone mount 1827 1837 5000
IconButtonCompat mount 1886 1838 5000
Label mount 351 341 5000
Layer mount 1819 1837 5000
Link mount 476 480 5000
MakeStyles mount 1988 1945 50000
MenuButtonCompat mount 1559 1548 5000
MessageBar mount 2013 2009 5000
Nav mount 3415 3331 1000
OverflowSet mount 1085 1055 5000
Panel mount 1474 1466 1000
Persona mount 861 874 1000
Pivot mount 1478 1428 1000
PrimaryButtonCompat mount 1303 1338 5000
Rating mount 7884 8091 5000
SearchBox mount 1389 1383 5000
Shimmer mount 2725 2662 5000
Slider mount 2006 1967 5000
SpinButton mount 5116 5148 5000
Spinner mount 404 422 5000
SplitButtonCompat mount 3284 3319 5000
Stack mount 524 530 5000
StackWithIntrinsicChildren mount 1555 1529 5000
StackWithTextChildren mount 4819 4745 5000
SwatchColorPicker mount 10520 10682 5000
Tabs mount 1414 1400 1000
TagPicker mount 2924 2944 5000
TeachingBubble mount 11715 11716 5000
Text mount 434 429 5000
TextField mount 1408 1452 5000
ThemeProvider mount 2166 2201 5000
ThemeProvider virtual-rerender 646 667 5000
Toggle mount 833 817 5000
button mount 726 743 5000
buttonNative mount 113 117 5000

Perf Analysis (Fluent)

Perf comparison
Status Scenario Fluent TPI Fabric TPI Ratio Iterations Ticks
🦄 Avatar.Fluent 0.18 0.52 0.35:1 2000 368
🦄 Button.Fluent 0.13 0.21 0.62:1 5000 631
🔧 Checkbox.Fluent 0.66 0.36 1.83:1 1000 662
🎯 Dialog.Fluent 0.17 0.22 0.77:1 5000 856
🔧 Dropdown.Fluent 2.99 0.42 7.12:1 1000 2990
🔧 Icon.Fluent 0.15 0.06 2.5:1 5000 742
🦄 Image.Fluent 0.09 0.13 0.69:1 5000 443
🔧 Slider.Fluent 1.61 0.46 3.5:1 1000 1610
🔧 Text.Fluent 0.08 0.03 2.67:1 5000 409
🦄 Tooltip.Fluent 0.12 0.9 0.13:1 5000 585

🔧 Needs work     🎯 On target     🦄 Amazing

Perf tests with no regressions
Scenario Current PR Ticks Baseline Ticks Ratio
AttachmentMinimalPerf.default 193 169 1.14:1
ChatMinimalPerf.default 705 627 1.12:1
ChatDuplicateMessagesPerf.default 407 372 1.09:1
FormMinimalPerf.default 494 454 1.09:1
ButtonMinimalPerf.default 206 191 1.08:1
FlexMinimalPerf.default 335 314 1.07:1
DividerMinimalPerf.default 419 397 1.06:1
AnimationMinimalPerf.default 462 439 1.05:1
CarouselMinimalPerf.default 530 504 1.05:1
GridMinimalPerf.default 416 396 1.05:1
HeaderMinimalPerf.default 435 414 1.05:1
SkeletonMinimalPerf.default 427 407 1.05:1
IconMinimalPerf.default 751 717 1.05:1
ImageMinimalPerf.default 438 423 1.04:1
LayoutMinimalPerf.default 466 450 1.04:1
ListNestedPerf.default 645 620 1.04:1
ListWith60ListItems.default 694 667 1.04:1
PortalMinimalPerf.default 174 168 1.04:1
ReactionMinimalPerf.default 450 434 1.04:1
Icon.Fluent 742 712 1.04:1
Image.Fluent 443 425 1.04:1
Text.Fluent 409 394 1.04:1
AvatarMinimalPerf.default 226 220 1.03:1
BoxMinimalPerf.default 417 406 1.03:1
ButtonSlotsPerf.default 633 615 1.03:1
ListCommonPerf.default 713 693 1.03:1
MenuMinimalPerf.default 939 911 1.03:1
MenuButtonMinimalPerf.default 1731 1678 1.03:1
SplitButtonMinimalPerf.default 4019 3909 1.03:1
TableMinimalPerf.default 470 456 1.03:1
TextAreaMinimalPerf.default 570 551 1.03:1
Dialog.Fluent 856 828 1.03:1
AttachmentSlotsPerf.default 1287 1257 1.02:1
CardMinimalPerf.default 637 626 1.02:1
ChatWithPopoverPerf.default 461 453 1.02:1
DialogMinimalPerf.default 858 840 1.02:1
ListMinimalPerf.default 561 551 1.02:1
LoaderMinimalPerf.default 762 750 1.02:1
RadioGroupMinimalPerf.default 512 501 1.02:1
TextMinimalPerf.default 401 393 1.02:1
TooltipMinimalPerf.default 861 840 1.02:1
TreeMinimalPerf.default 861 840 1.02:1
Checkbox.Fluent 662 651 1.02:1
Slider.Fluent 1610 1580 1.02:1
CheckboxMinimalPerf.default 2924 2909 1.01:1
DatepickerMinimalPerf.default 48952 48364 1.01:1
HeaderSlotsPerf.default 879 868 1.01:1
InputMinimalPerf.default 1344 1337 1.01:1
SegmentMinimalPerf.default 394 390 1.01:1
TableManyItemsPerf.default 2295 2269 1.01:1
ToolbarMinimalPerf.default 1048 1041 1.01:1
Dropdown.Fluent 2990 2950 1.01:1
DropdownManyItemsPerf.default 770 770 1:1
EmbedMinimalPerf.default 4241 4228 1:1
PopupMinimalPerf.default 725 725 1:1
RefMinimalPerf.default 247 246 1:1
SliderMinimalPerf.default 1590 1584 1:1
CustomToolbarPrototype.default 3708 3692 1:1
VideoMinimalPerf.default 691 692 1:1
Avatar.Fluent 368 369 1:1
ButtonOverridesMissPerf.default 1726 1735 0.99:1
ButtonUseCssNestingPerf.default 1111 1121 0.99:1
DropdownMinimalPerf.default 2999 3029 0.99:1
ItemLayoutMinimalPerf.default 1323 1331 0.99:1
ProviderMinimalPerf.default 929 936 0.99:1
Button.Fluent 631 639 0.99:1
Tooltip.Fluent 585 593 0.99:1
ButtonUseCssPerf.default 864 886 0.98:1
LabelMinimalPerf.default 468 479 0.98:1
ProviderMergeThemesPerf.default 1564 1596 0.98:1
StatusMinimalPerf.default 799 812 0.98:1
TreeWith60ListItems.default 186 192 0.97:1
AccordionMinimalPerf.default 170 177 0.96:1
AlertMinimalPerf.default 332 349 0.95:1
RosterPerf.default 1292 1362 0.95:1

@size-auditor
Copy link

size-auditor bot commented Nov 2, 2020

Asset size changes

Project Bundle Baseline Size New Size Difference
office-ui-fabric-react fluentui-react-Panel 189.298 kB 189.248 kB BelowBaseline     -50 bytes
office-ui-fabric-react fluentui-react-Callout 79.255 kB 79.205 kB BelowBaseline     -50 bytes
office-ui-fabric-react fluentui-react-TeachingBubble 193.505 kB 193.455 kB BelowBaseline     -50 bytes
office-ui-fabric-react fluentui-react-Coachmark 87.908 kB 87.858 kB BelowBaseline     -50 bytes
office-ui-fabric-react fluentui-react-Dropdown 220.093 kB 220.043 kB BelowBaseline     -50 bytes
office-ui-fabric-react fluentui-react-HoverCard 91.886 kB 91.836 kB BelowBaseline     -50 bytes
office-ui-fabric-react fluentui-react-DatePicker 171.177 kB 171.127 kB BelowBaseline     -50 bytes
office-ui-fabric-react fluentui-react-Dialog 198.582 kB 198.532 kB BelowBaseline     -50 bytes
office-ui-fabric-react fluentui-react-FocusTrapZone 15.576 kB 15.526 kB BelowBaseline     -50 bytes
office-ui-fabric-react fluentui-react-Modal 90.297 kB 90.247 kB BelowBaseline     -50 bytes

ExceedsTolerance Over Tolerance (1024 B) ExceedsBaseline Over Baseline BelowBaseline Below Baseline New New Deleted  Removed 1 kB = 1000 B

Baseline commit: d820d6ee1aafcd0a1669ba5bc139db8ab0663a92 (build)

@layershifter
Copy link
Member

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 3 pipeline(s).

@layershifter
Copy link
Member

@taurheim it seems that there failing unit tests due this change. Can you please check?

@taurheim
Copy link
Contributor Author

taurheim commented Jan 7, 2021

Hi @layershifter, one of the errors in the build is "ERROR: there is an invalid change type detected @fluentui-react-internal-2020-11-02-08-54-48-taurheim-focustrap-onfocus.json: "patch" is not a valid change type"

Based on the documentation here, patch should be a valid change type, right? Can you help me understand what I need to do to run a passing build?

Edit: I've fixed the UT that was breaking. I had to learn a bit about how JS handles event delegation - onFocusCapture gets called before onFocus which was causing issues in onBumperFocus since it expects to be the called before onFocus. Instead I've just made onBumperFocus set internal "focused" state to true, since that should happen due to bubbling anyway. This change should have no effect on existing functionality, but there may still be an issue in preact since internalState.hasFocus never gets set to false without bubbling.

@taurheim taurheim changed the title Set focus to true onFocusCapture in FocusTrapZone Correctly set focus in FocusTrapZone even if focus event does not bubble Jan 7, 2021
@layershifter
Copy link
Member

@taurheim I think that now it's "type": "prerelease",. Can you please remove a change file and try to run yarn change again?

@taurheim
Copy link
Contributor Author

taurheim commented Jan 7, 2021

If someone more familiar with FocusTrapZone could take another look at this change that would be great -- to make sure I've covered everything I had to make another change, moving the code that was previously run onBlur to run onBlurCapture. This means that it will be run before blur is called on the target element. Similarly to the other change (setting internal state on bumper focus), it is necessary for cases where onBlur and onFocus do not bubble (see #15530 for more explanation). I don't see any issues with this change but there may be repercussions I haven't considered and want to make sure I'm not breaking a key scenario here :)

@layershifter
Copy link
Member

@dzearing can you please check this one?

Copy link
Contributor

@xugao xugao left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The updates LGTM. The build failed due to some snapshots not update-to-date. I will approve once resolved!

@taurheim
Copy link
Contributor Author

I've fixed the tests - apologies for all the commits, I was having trouble getting a full test run to finish on my local machine :(

@xugao
Copy link
Contributor

xugao commented Jan 21, 2021

@taurheim - I will go ahead help merge this PR. for the change to be published for v7, could you also make the same fix in 7,0 branch?

@xugao xugao merged commit 3edcbb8 into microsoft:master Jan 21, 2021
@taurheim taurheim deleted the taurheim/focustrap-onfocus branch January 21, 2021 03:31
@taurheim taurheim restored the taurheim/focustrap-onfocus branch January 21, 2021 03:31
@msft-fluent-ui-bot
Copy link
Collaborator

🎉@fluentui/react-internal@v8.0.0-beta.35 has been released which incorporates this pull request.:tada:

Handy links:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

FocusTrapZone does not tab properly when using preact
7 participants