UNPKG

@wordpress/components

Version:
105 lines (96 loc) 2.38 kB
/** * External dependencies */ import classnames from 'classnames'; import { partial, noop, find } from 'lodash'; /** * WordPress dependencies */ import { useState, useEffect } from '@wordpress/element'; import { useInstanceId } from '@wordpress/compose'; /** * Internal dependencies */ import { NavigableMenu } from '../navigable-container'; import Button from '../button'; const TabButton = ( { tabId, onClick, children, selected, ...rest } ) => ( <Button role="tab" tabIndex={ selected ? null : -1 } aria-selected={ selected } id={ tabId } onClick={ onClick } { ...rest } > { children } </Button> ); 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( null ); const handleClick = ( tabKey ) => { setSelected( tabKey ); onSelect( tabKey ); }; const onNavigate = ( childIndex, child ) => { child.click(); }; const selectedTab = find( tabs, { name: selected } ); const selectedId = `${ instanceId }-${ selectedTab?.name ?? 'none' }`; useEffect( () => { const newSelectedTab = find( tabs, { name: selected } ); if ( ! newSelectedTab ) { setSelected( initialTabName || ( tabs.length > 0 ? tabs[ 0 ].name : null ) ); } }, [ tabs ] ); 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, } ) } tabId={ `${ instanceId }-${ tab.name }` } aria-controls={ `${ instanceId }-${ tab.name }-view` } selected={ tab.name === selected } key={ tab.name } onClick={ partial( handleClick, tab.name ) } > { tab.title } </TabButton> ) ) } </NavigableMenu> { selectedTab && ( <div key={ selectedId } aria-labelledby={ selectedId } role="tabpanel" id={ `${ selectedId }-view` } className="components-tab-panel__tab-content" > { children( selectedTab ) } </div> ) } </div> ); }