1414 * limitations under the License.
1515 */
1616
17- import { Link , NavLink } from 'react-router-dom'
17+ import { Link , NavLink , useRouteMatch } from 'react-router-dom'
18+ import { motion } from 'framer-motion'
1819
1920import { Tooltip } from '@Common/Tooltip'
2021import { ComponentSizeType } from '@Shared/constants'
2122
22- import { getTabBadge , getTabDescription , getTabIcon , getTabIndicator } from './TabGroup.helpers'
23+ import { getPathnameToMatch , getTabBadge , getTabDescription , getTabIcon , getTabIndicator } from './TabGroup.helpers'
2324import { TabGroupProps , TabProps } from './TabGroup.types'
2425import { getClassNameBySizeMap , tabGroupClassMap } from './TabGroup.utils'
2526
2627import './TabGroup.scss'
2728
29+ const MotionLayoutUnderline = ( {
30+ layoutId,
31+ alignActiveBorderWithContainer,
32+ } : {
33+ layoutId : string
34+ alignActiveBorderWithContainer : boolean
35+ } ) => (
36+ < motion . div
37+ layout = "position"
38+ layoutId = { layoutId }
39+ className = "bcb-5"
40+ style = { { height : 2 , ...( alignActiveBorderWithContainer ? { bottom : - 1 } : { } ) } }
41+ />
42+ )
43+
2844const Tab = ( {
2945 label,
3046 props,
@@ -42,7 +58,13 @@ const Tab = ({
4258 description,
4359 shouldWrapTooltip,
4460 tooltipProps,
45- } : TabProps & Pick < TabGroupProps , 'size' | 'alignActiveBorderWithContainer' | 'hideTopPadding' > ) => {
61+ uniqueGroupId,
62+ } : TabProps &
63+ Pick < TabGroupProps , 'size' | 'alignActiveBorderWithContainer' | 'hideTopPadding' > & { uniqueGroupId : string } ) => {
64+ const { path } = useRouteMatch ( )
65+ const pathToMatch = tabType === 'navLink' || tabType === 'link' ? getPathnameToMatch ( props . to , path ) : ''
66+ const match = useRouteMatch ( pathToMatch )
67+
4668 const { tabClassName, iconClassName, badgeClassName } = getClassNameBySizeMap ( {
4769 hideTopPadding,
4870 alignActiveBorderWithContainer,
@@ -119,11 +141,19 @@ const Tab = ({
119141 }
120142 }
121143
144+ const isTabActive = tabType === 'button' ? active : ! ! match
145+
122146 const renderTabContainer = ( ) => (
123147 < li
124- className = { `tab-group__tab lh-20 ${ active ? 'tab-group__tab--active cb-5 fw-6' : 'cn-9 fw-4' } ${ alignActiveBorderWithContainer ? 'tab-group__tab--align-active-border' : ' '} ${ tabType === 'block' ? 'tab-group__tab--block' : '' } ${ disabled ? 'dc__disabled' : 'cursor' } ` }
148+ className = { `tab-group__tab lh-20 ${ active ? 'cb-5 fw-6' : 'cn-9 fw-4' } ${ tabType === 'block' ? 'tab-group__tab--block' : '' } ${ disabled ? 'dc__disabled' : 'cursor' } ` }
125149 >
126150 { getTabComponent ( ) }
151+ { isTabActive && (
152+ < MotionLayoutUnderline
153+ layoutId = { uniqueGroupId }
154+ alignActiveBorderWithContainer = { alignActiveBorderWithContainer }
155+ />
156+ ) }
127157 </ li >
128158 )
129159
@@ -140,20 +170,26 @@ export const TabGroup = ({
140170 rightComponent,
141171 alignActiveBorderWithContainer,
142172 hideTopPadding,
143- } : TabGroupProps ) => (
144- < div className = "flexbox dc__align-items-center dc__content-space" >
145- < ul role = "tablist" className = { `tab-group flexbox dc__align-items-center p-0 m-0 ${ tabGroupClassMap [ size ] } ` } >
146- { tabs . map ( ( { id, ...resProps } ) => (
147- < Tab
148- key = { id }
149- id = { id }
150- size = { size }
151- alignActiveBorderWithContainer = { alignActiveBorderWithContainer }
152- hideTopPadding = { hideTopPadding }
153- { ...resProps }
154- />
155- ) ) }
156- </ ul >
157- { rightComponent || null }
158- </ div >
159- )
173+ } : TabGroupProps ) => {
174+ // Unique layoutId for motion.div to handle multiple tab groups on same page
175+ const uniqueGroupId = tabs . map ( ( tab ) => tab . label ) . join ( '-' )
176+
177+ return (
178+ < div className = "flexbox dc__align-items-center dc__content-space" >
179+ < ul role = "tablist" className = { `tab-group flexbox dc__align-items-center p-0 m-0 ${ tabGroupClassMap [ size ] } ` } >
180+ { tabs . map ( ( { id, ...resProps } ) => (
181+ < Tab
182+ key = { id }
183+ id = { id }
184+ size = { size }
185+ alignActiveBorderWithContainer = { alignActiveBorderWithContainer }
186+ hideTopPadding = { hideTopPadding }
187+ uniqueGroupId = { uniqueGroupId }
188+ { ...resProps }
189+ />
190+ ) ) }
191+ </ ul >
192+ { rightComponent || null }
193+ </ div >
194+ )
195+ }
0 commit comments