1414 * limitations under the License.
1515 */
1616
17- import { Link , NavLink } from 'react-router-dom'
17+ import { useMemo } from 'react'
18+ import { Link , NavLink , useRouteMatch } from 'react-router-dom'
19+ import { motion } from 'framer-motion'
1820
1921import { Tooltip } from '@Common/Tooltip'
2022import { ComponentSizeType } from '@Shared/constants'
2123
22- import { getTabBadge , getTabDescription , getTabIcon , getTabIndicator } from './TabGroup.helpers'
23- import { TabGroupProps , TabProps } from './TabGroup.types'
24+ import { getPathnameToMatch , getTabBadge , getTabDescription , getTabIcon , getTabIndicator } from './TabGroup.helpers'
25+ import { AdditionalTabProps , TabGroupProps , TabProps } from './TabGroup.types'
2426import { getClassNameBySizeMap , tabGroupClassMap } from './TabGroup.utils'
2527
2628import './TabGroup.scss'
2729
30+ const MotionLayoutUnderline = ( { layoutId } : { layoutId : string } ) => (
31+ < motion . div layout = "position" layoutId = { layoutId } className = "underline bcb-5" />
32+ )
33+
2834const Tab = ( {
2935 label,
3036 props,
@@ -33,7 +39,6 @@ const Tab = ({
3339 icon,
3440 size,
3541 badge = null ,
36- alignActiveBorderWithContainer,
3742 hideTopPadding,
3843 showIndicator,
3944 showError,
@@ -42,10 +47,19 @@ const Tab = ({
4247 description,
4348 shouldWrapTooltip,
4449 tooltipProps,
45- } : TabProps & Pick < TabGroupProps , 'size' | 'alignActiveBorderWithContainer' | 'hideTopPadding' > ) => {
50+ uniqueGroupId,
51+ } : TabProps & Pick < TabGroupProps , 'size' | 'hideTopPadding' > & AdditionalTabProps ) => {
52+ const { path } = useRouteMatch ( )
53+ const pathToMatch = tabType === 'navLink' || tabType === 'link' ? getPathnameToMatch ( props . to , path ) : ''
54+
55+ // using match to define if tab is active as useRouteMatch return an object if path is matched otherwise return null/undefined
56+ const match = useRouteMatch ( pathToMatch )
57+
58+ const isTabActive = tabType === 'button' ? active : ! ! match
59+
4660 const { tabClassName, iconClassName, badgeClassName } = getClassNameBySizeMap ( {
4761 hideTopPadding,
48- alignActiveBorderWithContainer ,
62+ isTabActive ,
4963 } ) [ size ]
5064
5165 const onClickHandler = (
@@ -121,9 +135,10 @@ const Tab = ({
121135
122136 const renderTabContainer = ( ) => (
123137 < 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' } ` }
138+ 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' } ` }
125139 >
126140 { getTabComponent ( ) }
141+ { isTabActive && < MotionLayoutUnderline layoutId = { uniqueGroupId } /> }
127142 </ li >
128143 )
129144
@@ -138,22 +153,27 @@ export const TabGroup = ({
138153 tabs = [ ] ,
139154 size = ComponentSizeType . large ,
140155 rightComponent,
141- alignActiveBorderWithContainer,
142156 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- )
157+ } : TabGroupProps ) => {
158+ // Unique layoutId for motion.div to handle multiple tab groups on same page
159+ // Using tab labels so that id remains same on re mount as well
160+ const uniqueGroupId = useMemo ( ( ) => tabs . map ( ( tab ) => tab . label ) . join ( '-' ) , [ ] )
161+
162+ return (
163+ < div className = "flexbox dc__align-items-center dc__content-space" >
164+ < ul role = "tablist" className = { `tab-group flexbox dc__align-items-center p-0 m-0 ${ tabGroupClassMap [ size ] } ` } >
165+ { tabs . map ( ( { id, ...resProps } ) => (
166+ < Tab
167+ key = { id }
168+ id = { id }
169+ size = { size }
170+ hideTopPadding = { hideTopPadding }
171+ uniqueGroupId = { uniqueGroupId }
172+ { ...resProps }
173+ />
174+ ) ) }
175+ </ ul >
176+ { rightComponent || null }
177+ </ div >
178+ )
179+ }
0 commit comments