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

Fix issues with SpinButton revealed by eslint-plugin-react-hooks #15431

Merged

Conversation

czearing
Copy link
Collaborator

@czearing czearing commented Oct 8, 2020

Pull request checklist

Description of changes

1. Updating react-internal SpinButton to handle onChange.
2. Resolving issues revealed by eslint-plugin-react-hooks. #14480
3. Updating react-internal SpinButton.stateful.example.tsx to show the usage of onChange.
4. Adding a forwardRef to SpinButton.

Focus areas to test

SpinButton

@msft-github-bot
Copy link
Contributor

Thanks for submitting this change, but due to work currently in progress to prepare master for our version 8 beta release, we're asking contributors to either wait a couple weeks to submit changes (if it's not urgent) or submit to the new 7.0 branch (if it's urgent). See #15222 for more details. Thank you for your contribution and understanding!

@msft-github-bot
Copy link
Contributor

msft-github-bot commented Oct 8, 2020

Perf Analysis

No significant results to display.

All results

Scenario Render type Master Ticks PR Ticks Iterations Status
Avatar mount 851 850 5000
BaseButtonCompat mount 927 932 5000
Breadcrumb mount 40365 40668 5000
Checkbox mount 1577 1529 5000
CheckboxBase mount 1320 1300 5000
ChoiceGroup mount 4713 4818 5000
ComboBox mount 958 947 1000
CommandBar mount 9731 9781 1000
ContextualMenu mount 5905 5958 1000
DefaultButtonCompat mount 1148 1158 5000
DetailsRow mount 3653 3647 5000
DetailsRowFast mount 3709 3716 5000
DetailsRowNoStyles mount 3528 3541 5000
Dialog mount 1451 1444 1000
DocumentCardTitle mount 1736 1722 1000
Dropdown mount 3322 3303 5000
FocusTrapZone mount 1795 1740 5000
FocusZone mount 1823 1782 5000
IconButtonCompat mount 1827 1830 5000
Label mount 336 337 5000
Layer mount 1750 1782 5000
Link mount 473 476 5000
MenuButtonCompat mount 1538 1538 5000
MessageBar mount 1982 1965 5000
Nav mount 3267 3266 1000
OverflowSet mount 1032 1025 5000
Panel mount 1429 1374 1000
Persona mount 849 861 1000
Pivot mount 1430 1388 1000
PrimaryButtonCompat mount 1285 1336 5000
Rating mount 7771 7797 5000
SearchBox mount 1349 1359 5000
Shimmer mount 2604 2667 5000
Slider mount 1887 1935 5000
SpinButton mount 5037 5001 5000
Spinner mount 402 400 5000
SplitButtonCompat mount 3255 3187 5000
Stack mount 505 504 5000
StackWithIntrinsicChildren mount 1501 1527 5000
StackWithTextChildren mount 4653 4620 5000
SwatchColorPicker mount 10135 10127 5000
Tabs mount 1417 1393 1000
TagPicker mount 2840 2846 5000
TeachingBubble mount 11328 11399 5000
Text mount 409 425 5000
TextField mount 1440 1392 5000
ThemeProvider mount 2083 2079 5000
ThemeProvider virtual-rerender 631 631 5000
Toggle mount 784 799 5000
button mount 669 669 5000
buttonNative mount 109 103 5000

Perf Analysis (Fluent)

Perf comparison
Status Scenario Fluent TPI Fabric TPI Ratio Iterations Ticks
🎯 Avatar.Fluent 0.49 0.51 0.96:1 2000 979
🦄 Button.Fluent 0.12 0.25 0.48:1 5000 624
🔧 Checkbox.Fluent 0.66 0.35 1.89:1 1000 658
🎯 Dialog.Fluent 0.17 0.21 0.81:1 5000 845
🔧 Dropdown.Fluent 2.87 0.41 7:1 1000 2870
🔧 Icon.Fluent 0.15 0.06 2.5:1 5000 762
🦄 Image.Fluent 0.08 0.13 0.62:1 5000 423
🔧 Slider.Fluent 1.54 0.44 3.5:1 1000 1536
🔧 Text.Fluent 0.08 0.03 2.67:1 5000 390
🦄 Tooltip.Fluent 0.12 0.87 0.14:1 5000 576

🔧 Needs work     🎯 On target     🦄 Amazing

Perf tests with no regressions
Scenario Current PR Ticks Baseline Ticks Ratio
FormMinimalPerf.default 496 444 1.12:1
ReactionMinimalPerf.default 474 436 1.09:1
RefMinimalPerf.default 252 231 1.09:1
ChatDuplicateMessagesPerf.default 457 423 1.08:1
RadioGroupMinimalPerf.default 495 460 1.08:1
ChatWithPopoverPerf.default 483 450 1.07:1
FlexMinimalPerf.default 340 319 1.07:1
PortalMinimalPerf.default 171 160 1.07:1
TableMinimalPerf.default 463 432 1.07:1
Avatar.Fluent 979 918 1.07:1
BoxMinimalPerf.default 412 389 1.06:1
Checkbox.Fluent 658 622 1.06:1
AvatarMinimalPerf.default 519 495 1.05:1
ButtonMinimalPerf.default 199 190 1.05:1
PopupMinimalPerf.default 732 698 1.05:1
Tooltip.Fluent 576 549 1.05:1
CarouselMinimalPerf.default 488 471 1.04:1
DividerMinimalPerf.default 420 405 1.04:1
HeaderMinimalPerf.default 425 408 1.04:1
HeaderSlotsPerf.default 868 838 1.04:1
ImageMinimalPerf.default 434 419 1.04:1
SegmentMinimalPerf.default 404 389 1.04:1
TextAreaMinimalPerf.default 561 538 1.04:1
Dialog.Fluent 845 816 1.04:1
AnimationMinimalPerf.default 431 417 1.03:1
LabelMinimalPerf.default 461 446 1.03:1
ListMinimalPerf.default 537 520 1.03:1
IconMinimalPerf.default 723 702 1.03:1
TextMinimalPerf.default 383 373 1.03:1
TreeMinimalPerf.default 837 809 1.03:1
Button.Fluent 624 603 1.03:1
Text.Fluent 390 377 1.03:1
AttachmentSlotsPerf.default 1176 1151 1.02:1
ButtonUseCssNestingPerf.default 1122 1097 1.02:1
CardMinimalPerf.default 617 604 1.02:1
ChatMinimalPerf.default 663 647 1.02:1
DialogMinimalPerf.default 817 801 1.02:1
GridMinimalPerf.default 395 386 1.02:1
ListCommonPerf.default 709 693 1.02:1
ListNestedPerf.default 623 613 1.02:1
SkeletonMinimalPerf.default 458 449 1.02:1
SliderMinimalPerf.default 1564 1527 1.02:1
StatusMinimalPerf.default 787 772 1.02:1
TreeWith60ListItems.default 225 220 1.02:1
VideoMinimalPerf.default 684 673 1.02:1
Icon.Fluent 762 750 1.02:1
Slider.Fluent 1536 1506 1.02:1
ButtonOverridesMissPerf.default 1701 1678 1.01:1
MenuButtonMinimalPerf.default 1638 1623 1.01:1
ProviderMergeThemesPerf.default 1988 1974 1.01:1
SplitButtonMinimalPerf.default 3892 3845 1.01:1
Image.Fluent 423 419 1.01:1
ButtonSlotsPerf.default 622 622 1:1
DatepickerMinimalPerf.default 47115 47118 1:1
DropdownManyItemsPerf.default 771 771 1:1
EmbedMinimalPerf.default 4154 4139 1:1
InputMinimalPerf.default 1300 1306 1:1
ItemLayoutMinimalPerf.default 1364 1364 1:1
ListWith60ListItems.default 930 930 1:1
LoaderMinimalPerf.default 738 735 1:1
MenuMinimalPerf.default 905 903 1:1
TableManyItemsPerf.default 2295 2305 1:1
CustomToolbarPrototype.default 3758 3740 1:1
ToolbarMinimalPerf.default 1005 1007 1:1
AccordionMinimalPerf.default 166 168 0.99:1
ButtonUseCssPerf.default 847 858 0.99:1
CheckboxMinimalPerf.default 2835 2857 0.99:1
DropdownMinimalPerf.default 2896 2914 0.99:1
LayoutMinimalPerf.default 431 436 0.99:1
ProviderMinimalPerf.default 980 986 0.99:1
Dropdown.Fluent 2870 2899 0.99:1
AttachmentMinimalPerf.default 169 175 0.97:1
AlertMinimalPerf.default 318 330 0.96:1
TooltipMinimalPerf.default 812 844 0.96:1

@codesandbox-ci
Copy link

codesandbox-ci bot commented Oct 8, 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 34c4ff0:

Sandbox Source
Fluent UI Button Configuration

@size-auditor
Copy link

size-auditor bot commented Oct 8, 2020

Asset size changes

Project Bundle Baseline Size New Size Difference
office-ui-fabric-react fluentui-react-SpinButton 182.212 kB 180.407 kB BelowBaseline     -1.805 kB

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

Baseline commit: e295779659b7466bd3e7e15bbc975cccb648549f (build)

Copy link
Member

@ecraig12345 ecraig12345 left a comment

Choose a reason for hiding this comment

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

Please wait on merging this until I can take a look again--I remember from the previous version of this that I had quite a bit of feedback, but I need to get some other things with v8 done ASAP and don't have time right away to review this in detail, sorry. :(

@msft-github-bot
Copy link
Contributor

This pull request has been automatically marked as stale because it was marked as requiring author feedback but has not had any activity for 7 days. It will be closed if no further activity occurs within 5 days of this comment. Thank you for your contributions to Fluent UI!

# Conflicts:
#	packages/react-examples/src/react/__snapshots__/SpinButton.Stateful.Example.tsx.shot
#	packages/react-internal/etc/react-internal.api.md
#	packages/react-internal/src/components/SpinButton/SpinButton.base.tsx
#	packages/react-internal/src/components/SpinButton/SpinButton.types.ts
@czearing czearing closed this Oct 30, 2020
@czearing czearing reopened this Oct 30, 2020
@behowell
Copy link
Contributor

Hi @czearing, I wanted to check if you are still planning to go forward with this PR?

It looks like it's waiting for review from @ecraig12345.

@ecraig12345 ecraig12345 changed the title Updating react-internal SpinButton to handle onChange Fix issues with SpinButton revealed by eslint-plugin-react-hooks Nov 22, 2020
@ecraig12345
Copy link
Member

ecraig12345 commented Nov 22, 2020

After thinking about this and reading back through the great (and long) discussion on #5326, I think we should go ahead with the functionality fixes in this PR but revert the onChange addition for now. (But definitely get it done before the v8 release still!)

Correctly implementing onChange has a lot of nuances which weren't covered here: mainly that we should only call it on "commit" rather than on every keystroke, plus lots of edge cases. See https://hackmd.io/cLn40UjfT_KOM6r4yi2CUQ for a full proposed spec. If the proposal seems good, either I can work on it (hopefully this week) or @czearing you can give it a try if you have time.

Based on all that, I pushed some updates doing the following:

  • Revert onChange addition for now
  • Add a test for the case of pressing up/down arrow key or button twice
  • Revert my previous example changes (see Condense SpinButton examples and improve names and styling #16040 instead)
  • Improve default handling
  • Simplify calculation of initial value, last valid value, and precision
  • Changed isFocused to use useState instead of useBoolean since the convenience callbacks are not actually needed in this case
  • Add helpers in test to reduce duplicate code (makes adding more coverage easier)
  • Fix a bug where lastValidValue was not being updated after stepping (and add a test)
  • Fix a bug with spinning by mouse: the updateValue callback was capturing a stale value of value and reusing it for subsequent calls (added a test for this)
  • Move initialStepDelay and stepDelay to file-level constants since they never change, and simplify the signature of updateValue so that the correct step delay is automatically used.

At this point the functionality issues should be fixed and I'm going to approve, but @dzearing should probably take a look as well so I'm not reviewing (partially) my own code. 😆

@ecraig12345
Copy link
Member

I should also have said, thank you so much @czearing for all your work on this and other changes, and SO sorry for not reviewing sooner!!

@kazuki
Copy link

kazuki commented Nov 29, 2020

In controlledValue mode, setValue(elementValue) in handleInputChange doesn't work.
As a result, if input by the keyboard, the value will not be reflected correctly.

@ecraig12345
Copy link
Member

@kazuki The controlled SpinButton isn't working quite properly yet. I'll be fixing that in another PR this week.

@ecraig12345 ecraig12345 merged commit 6210af1 into microsoft:master Nov 30, 2020
@msft-github-bot
Copy link
Contributor

🎉@fluentui/react-internal@v8.0.0-beta.20 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
9 participants