-
Notifications
You must be signed in to change notification settings - Fork 4.2k
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
TabPanel: add tabName prop (controlled component) #46704
Conversation
6a1da2d
to
b99bc23
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice enhancement! I just wanted to mention as a heads-up: The disabled tab feature will be landing soon (#46471), so controlled mode also needs to take that into account.
b17c860
to
b586953
Compare
Thanks for the mention. Now that the PR is merged, updated the code to consider disabled tab scenario. |
b586953
to
cc1b99f
Compare
Just linking to this comment that I had made a while ago about
|
cc1b99f
to
be81699
Compare
Flaky tests detected in 4bfaeb9. 🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/6271247960
|
be81699
to
75762b7
Compare
This PR needs a rebase after the fix in #47100 was merged. I can take another look at the code once the rebase has happened :) |
Hey @madhusudhand , are you still able to work on this PR ? |
75762b7
to
47986a4
Compare
Hey @ciampo Updated the component and following are the test scenarios. |
47986a4
to
9064064
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you @madhusudhand for your work here!
It actually looks like there's quite a few scenarios that we'd need to test, especially around:
- the initial tab selection
- the currently selected tab becoming disabled
- the component in general working as expected in controlled and uncontrolled mode alike
Since you've added also a bunch of unit tests (which is great!), I suggest we do the following:
- We open a new PR, where we add the new unit tests to the current implementation of
TabPanel
. Of course, we'll be able only to test the component in uncontrolled mode, but adding those tests separately can help us to certify the behaviour of the component ontrunk
- Once the PR with the unit tests is merged, we can rebase this PR and just make the necessary changes to include the new
tabName
prop and enable controlled mode. We will just need to run the existing tests on the controlled version of the component, and make adjustments if necessary.
I believe that the suggested approach will enable us to move faster and will give us more confidence when merging such changes.
What do folks think?
@@ -9,7 +9,12 @@ import userEvent from '@testing-library/user-event'; | |||
*/ | |||
import TabPanel from '..'; | |||
|
|||
const setupUser = () => userEvent.setup(); | |||
jest.useFakeTimers(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We've been recently working across the codebase to refactor unit tests away from using take timers and act()
call.
That would mean removing the jest.useFakeTimers();
call and the advanceTimers: jest.advanceTimersByTime,
option when setting userEvent
up.
cc @tyxla
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, we use fake timers only when we really have to. That means removing jest.useFakeTimers()
and calling const user = userEvent.setup();
without the advanceTimers
setting.
Here are some PRs where we refactored from fake to real timers if that will help:
expect( panelRenderFunction ).toHaveBeenLastCalledWith( TABS[ 0 ] ); | ||
expect( mockOnSelect ).toHaveBeenLastCalledWith( 'alpha' ); | ||
} ); | ||
describe( 'Uncontrolled mode', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A pattern that we've started to adopt when writing unit tests for components that can be used both in controlled and uncontrolled mode, is to use describe.each
and run the same suite against the controlled and uncontrolled version.
You can see it in action for the ComboboxControl
component:
gutenberg/packages/components/src/combobox-control/test/index.js
Lines 80 to 83 in 56c33cf
describe.each( [ | |
[ 'uncontrolled', ComboboxControl ], | |
[ 'controlled', ControlledComboboxControl ], | |
] )( 'ComboboxControl %s', ( ...modeAndComponent ) => { |
Of course, if there are certain tests that are specifically aimed at one version of the component, they can be added outside of the describe.each
call.
Hey @madhusudhand , do you still have the capacity to work on this? |
@ciampo I would be able to continue the work after 16th Feb. If you have capacity feel free to take it from me. Thanks. |
I put together a draft PR (#48086) that you might use as a base for verifying the current component behaviour on trunk. I'll be AFK for the next week so feel free to pick it up or close it if it doesn't help. |
aa7ed5d
to
af7e02b
Compare
Update: Rebased the PR with unit testes from #48086 and they all are running great. Will push more tests for controlled mode. |
Nice! You can take inspiration from gutenberg/packages/components/src/combobox-control/test/index.tsx Lines 61 to 85 in dc32380
|
af7e02b
to
aa5c09f
Compare
Updated the PR with revised changes and included unit tests for controlled and uncontrolled behaviours. Note: removed |
046c2de
to
4bfaeb9
Compare
Hey @madhusudhand , thank you for continuing the work here! In the past months, we've started working on improving the component:
The plan is to leave Furthermore, these components have quite an opinionated behaviour when uncontrolled around making sure that a tab gets selected even when the currently selected tab becomes disabled / gets removed. When allowing the component to be controlled, we have to ask ourselves how much of that custom behaviour we want to inherit (you can follow the conversation in #53960 ). |
Closing this change. Use the new Tabs component instead. |
What?
Add new prop
selectedTabName
to control the component tab selection programatically.Why?
Currently it is not possible to activate a tab using component props. This allows to activate a tab programatically.
The first usecase for this is to auto select the tab in
style book
based on the selected block in global styles.