Skip to content

Commit

Permalink
Use React hooks for TabPanel component (#22906)
Browse files Browse the repository at this point in the history
* Use React hooks for TabPanel component

* Use hook for instanceId

* Fix instanceId and use template literals

Co-authored-by: Patrick Villanueva <[email protected]>
  • Loading branch information
pkvillanueva and Patrick Villanueva authored Jun 5, 2020
1 parent 7390563 commit 4bfcda9
Showing 1 changed file with 59 additions and 77 deletions.
136 changes: 59 additions & 77 deletions packages/components/src/tab-panel/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import { partial, noop, find } from 'lodash';
/**
* WordPress dependencies
*/
import { Component } from '@wordpress/element';
import { withInstanceId } from '@wordpress/compose';
import { useState } from '@wordpress/element';
import { useInstanceId } from '@wordpress/compose';

/**
* Internal dependencies
Expand All @@ -29,87 +29,69 @@ const TabButton = ( { tabId, onClick, children, selected, ...rest } ) => (
</Button>
);

class TabPanel extends Component {
constructor() {
super( ...arguments );
const { tabs, initialTabName } = this.props;
export default function TabPanel( {
className,
children,
tabs,
initialTabName,
orientation = 'horizontal',
activeClass = 'is-active',
onSelect = noop,
} ) {
const instanceId = useInstanceId( TabPanel, 'tab-panel' );
const [ selected, setSelected ] = useState(
initialTabName || ( tabs.length > 0 ? tabs[ 0 ].name : null )
);

this.handleClick = this.handleClick.bind( this );
this.onNavigate = this.onNavigate.bind( this );

this.state = {
selected:
initialTabName || ( tabs.length > 0 ? tabs[ 0 ].name : null ),
};
}

handleClick( tabKey ) {
const { onSelect = noop } = this.props;
this.setState( {
selected: tabKey,
} );
const handleClick = ( tabKey ) => {
setSelected( tabKey );
onSelect( tabKey );
}
};

onNavigate( childIndex, child ) {
const onNavigate = ( childIndex, child ) => {
child.click();
}

render() {
const { selected } = this.state;
const {
activeClass = 'is-active',
className,
instanceId,
orientation = 'horizontal',
tabs,
} = this.props;
};

const selectedTab = find( tabs, { name: selected } );
const selectedId = instanceId + '-' + selectedTab.name;
const selectedTab = find( tabs, { name: selected } );
const selectedId = `${ instanceId }-${ selectedTab.name }`;

return (
<div className={ className }>
<NavigableMenu
role="tablist"
orientation={ orientation }
onNavigate={ this.onNavigate }
className="components-tab-panel__tabs"
>
{ tabs.map( ( tab ) => (
<TabButton
className={ classnames(
'components-tab-panel__tabs-item',
tab.className,
{
[ activeClass ]: tab.name === selected,
}
) }
tabId={ instanceId + '-' + tab.name }
aria-controls={
instanceId + '-' + tab.name + '-view'
return (
<div className={ className }>
<NavigableMenu
role="tablist"
orientation={ orientation }
onNavigate={ onNavigate }
className="components-tab-panel__tabs"
>
{ tabs.map( ( tab ) => (
<TabButton
className={ classnames(
'components-tab-panel__tabs-item',
tab.className,
{
[ activeClass ]: tab.name === selected,
}
selected={ tab.name === selected }
key={ tab.name }
onClick={ partial( this.handleClick, tab.name ) }
>
{ tab.title }
</TabButton>
) ) }
</NavigableMenu>
{ selectedTab && (
<div
aria-labelledby={ selectedId }
role="tabpanel"
id={ selectedId + '-view' }
className="components-tab-panel__tab-content"
) }
tabId={ `${ instanceId }-${ tab.name }` }
aria-controls={ `${ instanceId }-${ tab.name }-view` }
selected={ tab.name === selected }
key={ tab.name }
onClick={ partial( handleClick, tab.name ) }
>
{ this.props.children( selectedTab ) }
</div>
) }
</div>
);
}
{ tab.title }
</TabButton>
) ) }
</NavigableMenu>
{ selectedTab && (
<div
aria-labelledby={ selectedId }
role="tabpanel"
id={ `${ selectedId }-view` }
className="components-tab-panel__tab-content"
>
{ children( selectedTab ) }
</div>
) }
</div>
);
}

export default withInstanceId( TabPanel );

0 comments on commit 4bfcda9

Please sign in to comment.