Skip to content

Commit 811350b

Browse files
Merge pull request #53 from TangibleInc/featuretabswitch-to-controlled-component-for-content
Tab: Content - Switch to controlled component
2 parents cd093fe + 62da9fc commit 811350b

5 files changed

Lines changed: 105 additions & 88 deletions

File tree

assets/build/example.min.js

Lines changed: 24 additions & 24 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

assets/build/index.min.js

Lines changed: 24 additions & 24 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

assets/src/components/base/tab/Tab.jsx

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
1+
import { useState, useEffect } from 'react'
12
import Button from '../button/Button'
23

34
/**
4-
* No logic/state, just to share the CSS/classes
5-
*
65
* <Container>
76
* <Header>
87
* <Title>Content 1</Title>
98
* <Title>Content 2</Title>
109
* <Header>
11-
* <Content>
10+
* <Content isActive={ true }>
1211
* <Row>
1312
* <RowTitle>Content 1</RowTitle>
1413
* </Row>
@@ -20,6 +19,9 @@ import Button from '../button/Button'
2019
* </Row>
2120
* // ...
2221
* <Content>
22+
* <Content isActive={ false }>
23+
* // ...
24+
* <Content>
2325
* <Tabs>
2426
*/
2527

@@ -52,11 +54,22 @@ const Title = props => (
5254
</div>
5355
)
5456

55-
const Content = props => (
56-
<div className={ 'tf-tab-content ' + (props.className ?? '') }>
57-
{ props.children }
58-
</div>
59-
)
57+
const Content = props => {
58+
59+
const [ isActive, setIsActive ] = useState( props.isActive ?? false )
60+
61+
useEffect(() => {
62+
if ( props.isActive !== isActive ) setIsActive( props.isActive )
63+
}, [ props.isActive ])
64+
65+
if ( ! isActive ) return;
66+
67+
return(
68+
<div className={ 'tf-tab-content ' + (props.className ?? '') }>
69+
{ props.children }
70+
</div>
71+
)
72+
}
6073

6174
const Row = props => (
6275
<div className={ 'tf-tab-row ' + (props.className ?? '') }>

assets/src/components/field/tab/Tab.jsx

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,19 +40,22 @@ const Tab = props => {
4040
</Title>
4141
)) }
4242
</Header>
43-
<Content>
44-
{ activeTab &&
45-
<FieldGroup key={ activeTab }
43+
{ tabs && tabs.map((tab, indexTab) => (
44+
<Content
45+
key={ tab.name }
46+
isActive={ tab.name === activeTab }
47+
>
48+
<FieldGroup
4649
{ ...props }
4750
name={ null }
48-
fields={ props.tabs[ activeTab ].fields }
49-
value={ value[ activeTab ] ?? {} }
51+
fields={ tab.fields }
52+
value={ value[ indexTab ] ?? {} }
5053
onChange={ tabValue => setValue({
5154
...value,
52-
[activeTab]: tabValue
55+
[indexTab]: tabValue
5356
}) }
54-
/> }
55-
</Content>
57+
/>
58+
</Content> )) }
5659
</Container>
5760
</>
5861
)

assets/src/components/repeater/layout/tab/Tab.jsx

Lines changed: 25 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useState } from 'react'
1+
import { useState, useLayoutEffect } from 'react'
22
import { renderTitle } from '../../common/helpers'
33

44
import {
@@ -85,29 +85,30 @@ const Tab = ({
8585
</Title>
8686
)) }
8787
</Header>
88-
{ items[ activeItem ] &&
89-
<Content
90-
key={ items[ activeItem ].key ?? activeItem }
91-
className='tf-repeater-tab-content'
92-
>
93-
{ rowFields.map((control, i) => (
94-
<Row key={ control.name ?? i } className='tf-repeater-tab-row'>
95-
{ beforeRow && beforeRow(items[ activeItem ], activeItem, dispatch) }
96-
{ control.type === 'title'
97-
? <RowTitle className='tf-repeater-tab-row-title tf-repeater-tab-row-title-section'>
98-
{ renderItem(control, items[ activeItem ], activeItem) }
99-
</RowTitle>
100-
: <>
101-
<RowLabel className='tf-repeater-tab-row-title'>
102-
{ control.label ?? '' }
103-
</RowLabel>
104-
<RowField className="tf-repeater-tab-item-field">
105-
{ renderItem(control, items[ activeItem ], activeItem) }
106-
</RowField>
107-
</> }
108-
{ afterRow && afterRow(items[ activeItem ], activeItem, dispatch) }
109-
</Row> )) }
110-
</Content> }
88+
{ items && items.map((item, itemIndex) => (
89+
<Content
90+
key={ item.key ?? itemIndex }
91+
isActive={ activeItem === itemIndex }
92+
className='tf-repeater-tab-content'
93+
>
94+
{ rowFields.map((control, i) => (
95+
<Row key={ control.name ?? i } className='tf-repeater-tab-row'>
96+
{ beforeRow && beforeRow(item, itemIndex, dispatch) }
97+
{ control.type === 'title'
98+
? <RowTitle className='tf-repeater-tab-row-title tf-repeater-tab-row-title-section'>
99+
{ renderItem(control, item, itemIndex) }
100+
</RowTitle>
101+
: <>
102+
<RowLabel className='tf-repeater-tab-row-title'>
103+
{ control.label ?? '' }
104+
</RowLabel>
105+
<RowField className="tf-repeater-tab-item-field">
106+
{ renderItem(control, item, itemIndex) }
107+
</RowField>
108+
</> }
109+
{ afterRow && afterRow(item, itemIndex, dispatch) }
110+
</Row> )) }
111+
</Content> )) }
111112
</Container>
112113
)
113114
}

0 commit comments

Comments
 (0)