Set current tab on a Gutenberg TabPanel component from outside that component

I’m using the TabPanel component provided with Gutenberg to display some tabs. I’d like a button within one of the tabs to change the currently visible tab to another one and I can’t work out how.

var el = wp.element.createElement;
var Component = wp.element.Component;
var Fragment = wp.element.Fragment;
var Button = wp.components.Button;
var TabPanel = wp.components.TabPanel;

function getEditComponent( blockName, blockTitle ) {
    return class extends Component {
        renderTab( tab ) {
            if ( 'show' === tab.name ) {
                return this.getPlotWidget();
            } else if ( 'edit' === tab.name ) {
                return this.getEditorWidget();
            }
        }

        doStuff() {
            // does some unrelated stuff...
        }

        getPlotWidget() {
            // returns a component...
        }

        getEditorWidget() {
            const { attributes } = this.props;
            const { script } = attributes;

            return el(
                Fragment,
                {},
                el(
                    'textarea',
                    {
                        name: 'textarea1',
                        value: script,
                    }
                ),
                el(
                    Button,
                    {
                        onClick: () => {
                            this.doStuff();
                        }
                    },
                    __( 'Run', 'my-textdomain' )
                )
            );
        }

        render() {
            return el(
                TabPanel,
                {
                    tabs: [
                        {
                            name: 'show',
                            title: __( 'Show', 'my-textdomain' ),
                        },
                        {
                            name: 'edit',
                            title: __( 'Edit', 'my-textdomain' ),
                        },
                    ],
                },
                ( tab ) => {
                    return this.renderTab( tab );
                }
            );
        }
    };
};

The tab panel is only created when the render function is called, so I guess one way to set the tab would be to persist it in the edit component’s state, but this seems like it goes against the style of React/Gutenberg where objects are cheap to generate on-the-fly.

I could also store a property like this.currentTab which contains the current tab name, then in the tab panel use this property to determine the tab to show. This would require me to trigger a render from the button’s onClick callback (how do you even do this?).

0

Leave a Comment