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

Allow setting selected tab in TabPanel component #27371

Closed
ecgan opened this issue Nov 30, 2020 · 3 comments
Closed

Allow setting selected tab in TabPanel component #27371

ecgan opened this issue Nov 30, 2020 · 3 comments
Labels
Needs Technical Feedback Needs testing from a developer perspective. [Package] Components /packages/components [Type] Enhancement A suggestion for improvement. [Type] New API New API to be used by plugin developers or package users.

Comments

@ecgan
Copy link
Contributor

ecgan commented Nov 30, 2020

Is your feature request related to a problem? Please describe.

In TabPanel, We have a way to get the selected tab via onSelect, but we can't programmatically set a tab.

Describe the solution you'd like

TabPanel should have a prop like selected so that we can programmatically set the active selected tab if we want. Essentially this means that we will be able to use TabPanel as uncontrolled or controlled component.

Describe alternatives you've considered

Nil.

@mapk mapk added [Type] Enhancement A suggestion for improvement. [Type] New API New API to be used by plugin developers or package users. Needs Technical Feedback Needs testing from a developer perspective. labels Dec 1, 2020
@kraftner
Copy link

I'd like to add a use case to emphasize the importance of this:

I'd like to use the TabPanel to create a Tabs block. InnerBlocks would be the tabpanels. Since one can reorder them using the BlockMover there would also be the need to change the active tab.

@kraftner
Copy link

Reading through the source code I had an idea for a possible workaround for now.

Selecting the active tab is based on the name of the tab:

selected={ tab.name === selected }

So, if you, like me are not actually trying to select a different tab, but move the position of the currently active tab while keeping it active all you need to to is change the order of the elements in the tabs array as long as the active tab keeps its name.

This actually sounds like a clean approach to me.


If you actually need to move to a different active tab that also has a different name I've got another idea. It's a bit hacky, but might be okay as a temporary workaround:

On any change of the tabs definition the component tries to find the name of the currently active tab and ensures it is still active. This is actually what makes the behavior described above work.

useEffect( () => {
const newSelectedTab = find( tabs, { name: selected } );
if ( ! newSelectedTab ) {
setSelected(
initialTabName || ( tabs.length > 0 ? tabs[ 0 ].name : null )
);
}
}, [ tabs ] );

We can use this to our advantage in two ways:

Swap the names of the currently active tab and the tab to be active next.

The result is pretty much the same as described at the top of this comment. The component only cares about tab names, not about content.

Append or prepend a counter or a random string to all tab names (or at least the currently active) and set the initialTabName prop to the name of the tab we want so set as the new active tab.

Changing the name of the currently active tab will make the component look for a no longer existing tab name falling back to the initialTabName prop.


While this works for now I still hope that the TabPanel will be extended in the future to make this possible without messing with the tab names.

@mirka
Copy link
Member

mirka commented Feb 14, 2024

Closed by #53960

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Needs Technical Feedback Needs testing from a developer perspective. [Package] Components /packages/components [Type] Enhancement A suggestion for improvement. [Type] New API New API to be used by plugin developers or package users.
Projects
Status: Done 🎉
Development

No branches or pull requests

4 participants