@@ -3,10 +3,10 @@ import PropTypes from 'prop-types'
33import React from 'react'
44
55import {
6- ModernAutoControlledComponent as Component ,
76 customPropTypes ,
87 getElementType ,
98 getUnhandledProps ,
9+ useAutoControlledValue ,
1010} from '../../lib'
1111import Grid from '../../collections/Grid/Grid'
1212import GridColumn from '../../collections/Grid/GridColumn'
@@ -18,21 +18,25 @@ import TabPane from './TabPane'
1818 * @see Menu
1919 * @see Segment
2020 */
21- class Tab extends Component {
22- getInitialAutoControlledState ( ) {
23- return { activeIndex : 0 }
21+ const Tab = React . forwardRef ( function ( props , ref ) {
22+ const { grid, menu, panes, menuPosition, renderActiveOnly } = props
23+
24+ const [ activeIndex , setActiveIndex ] = useAutoControlledValue ( {
25+ state : props . activeIndex ,
26+ defaultState : props . defaultActiveIndex ,
27+ initialState : 0 ,
28+ } )
29+
30+ const handleItemClick = ( e , { index } ) => {
31+ _ . invoke ( props , 'onTabChange' , e , { ...props , activeIndex : index } )
32+ setActiveIndex ( index )
2433 }
2534
26- handleItemClick = ( e , { index } ) => {
27- _ . invoke ( this . props , 'onTabChange' , e , { ...this . props , activeIndex : index } )
28- this . setState ( { activeIndex : index } )
29- }
30-
31- renderItems ( ) {
32- const { panes, renderActiveOnly } = this . props
33- const { activeIndex } = this . state
35+ const renderItems = ( ) => {
36+ if ( renderActiveOnly ) {
37+ return _ . invoke ( _ . get ( panes , `[${ activeIndex } ]` ) , 'render' , props )
38+ }
3439
35- if ( renderActiveOnly ) return _ . invoke ( _ . get ( panes , `[${ activeIndex } ]` ) , 'render' , this . props )
3640 return _ . map ( panes , ( { pane } , index ) =>
3741 TabPane . create ( pane , {
3842 overrideProps : {
@@ -42,10 +46,7 @@ class Tab extends Component {
4246 )
4347 }
4448
45- renderMenu ( ) {
46- const { menu, panes, menuPosition } = this . props
47- const { activeIndex } = this . state
48-
49+ const renderMenu = ( ) => {
4950 if ( menu . tabular === true && menuPosition === 'right' ) {
5051 menu . tabular = 'right'
5152 }
@@ -54,55 +55,57 @@ class Tab extends Component {
5455 autoGenerateKey : false ,
5556 overrideProps : {
5657 items : _ . map ( panes , 'menuItem' ) ,
57- onItemClick : this . handleItemClick ,
58+ onItemClick : handleItemClick ,
5859 activeIndex,
5960 } ,
6061 } )
6162 }
6263
63- renderVertical ( menu ) {
64- const { grid, menuPosition } = this . props
64+ const renderVertical = ( menuElement ) => {
6565 const { paneWidth, tabWidth, ...gridProps } = grid
6666
67- const position = menuPosition || ( menu . props . tabular === 'right' && 'right' ) || 'left'
67+ const position = menuPosition || ( menuElement . props . tabular === 'right' && 'right' ) || 'left'
6868
6969 return (
7070 < Grid { ...gridProps } >
7171 { position === 'left' &&
72- GridColumn . create ( { width : tabWidth , children : menu } , { autoGenerateKey : false } ) }
72+ GridColumn . create ( { width : tabWidth , children : menuElement } , { autoGenerateKey : false } ) }
7373 { GridColumn . create (
7474 {
7575 width : paneWidth ,
76- children : this . renderItems ( ) ,
76+ children : renderItems ( ) ,
7777 stretched : true ,
7878 } ,
7979 { autoGenerateKey : false } ,
8080 ) }
8181 { position === 'right' &&
82- GridColumn . create ( { width : tabWidth , children : menu } , { autoGenerateKey : false } ) }
82+ GridColumn . create ( { width : tabWidth , children : menuElement } , { autoGenerateKey : false } ) }
8383 </ Grid >
8484 )
8585 }
8686
87- render ( ) {
88- const menu = this . renderMenu ( )
89- const rest = getUnhandledProps ( Tab , this . props )
90- const ElementType = getElementType ( Tab , this . props )
91-
92- if ( menu . props . vertical ) {
93- return < ElementType { ...rest } > { this . renderVertical ( menu ) } </ ElementType >
94- }
87+ const menuElement = renderMenu ( )
88+ const rest = getUnhandledProps ( Tab , props )
89+ const ElementType = getElementType ( Tab , props )
9590
91+ if ( menuElement . props . vertical ) {
9692 return (
97- < ElementType { ...rest } >
98- { menu . props . attached !== 'bottom' && menu }
99- { this . renderItems ( ) }
100- { menu . props . attached === 'bottom' && menu }
93+ < ElementType { ...rest } ref = { ref } >
94+ { renderVertical ( menuElement ) }
10195 </ ElementType >
10296 )
10397 }
104- }
10598
99+ return (
100+ < ElementType { ...rest } ref = { ref } >
101+ { menuElement . props . attached !== 'bottom' && menuElement }
102+ { renderItems ( ) }
103+ { menuElement . props . attached === 'bottom' && menuElement }
104+ </ ElementType >
105+ )
106+ } )
107+
108+ Tab . displayName = 'Tab'
106109Tab . propTypes = {
107110 /** An element type to render as (string or function). */
108111 as : PropTypes . elementType ,
0 commit comments