44 KeyboardEvent ,
55 ReactElement ,
66 useContext ,
7+ useEffect ,
78 useLayoutEffect ,
89 useMemo ,
910 useRef ,
@@ -81,26 +82,13 @@ const TabsContent = styled.div`
8182const ScrollableTabsList = styled . div < {
8283 enabled : boolean ;
8384 iconPosition : TabsPropsType [ "iconPosition" ] ;
84- translateScroll : number ;
8585} > `
8686 display: flex;
87- ${ ( { enabled, translateScroll } ) =>
88- enabled ? `transform: translateX(${ translateScroll } px)` : "transform: translateX(0px)" } ;
8987 transition: all 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms;
9088 height: ${ ( { iconPosition } ) => ( iconPosition === "top" ? "72px" : "var(--height-xxl)" ) } ;
9189` ;
9290
93- const DxcTabs = ( {
94- activeTabIndex,
95- children,
96- defaultActiveTabIndex,
97- iconPosition = "left" ,
98- margin,
99- onTabClick,
100- onTabHover,
101- tabIndex = 0 ,
102- tabs,
103- } : TabsPropsType ) => {
91+ const DxcTabs = ( { children, iconPosition = "left" , margin, tabIndex = 0 } : TabsPropsType ) => {
10492 const childrenArray : ReactElement < TabProps > [ ] = useMemo (
10593 ( ) => Children . toArray ( children ) as ReactElement < TabProps > [ ] ,
10694 [ children ]
@@ -117,12 +105,11 @@ const DxcTabs = ({
117105
118106 return isValidElement ( initialActiveTab ) ? ( initialActiveTab . props . label ?? initialActiveTab . props . tabId ) : "" ;
119107 } ) ;
120- const [ countClick , setCountClick ] = useState ( 0 ) ;
121108 const [ innerFocusIndex , setInnerFocusIndex ] = useState < number | null > ( null ) ;
122109 const [ scrollLeftEnabled , setScrollLeftEnabled ] = useState ( false ) ;
123110 const [ scrollRightEnabled , setScrollRightEnabled ] = useState ( true ) ;
124- const [ translateScroll , setTranslateScroll ] = useState ( 0 ) ;
125111 const [ totalTabsWidth , setTotalTabsWidth ] = useState ( 0 ) ;
112+ const refTabListContainer = useRef < HTMLDivElement | null > ( null ) ;
126113 const refTabList = useRef < HTMLDivElement | null > ( null ) ;
127114 const translatedLabels = useContext ( HalstackLanguageContext ) ;
128115 const viewWidth = useWidth ( refTabList . current ) ;
@@ -138,52 +125,51 @@ const DxcTabs = ({
138125 } ;
139126 } , [ activeTabId , childrenArray , iconPosition , innerFocusIndex , tabIndex ] ) ;
140127
128+ const scrollLimitCheck = ( ) => {
129+ const container = refTabListContainer . current ;
130+ if ( container ) {
131+ const currentScroll = container . scrollLeft ;
132+ const scrollingLength = container . scrollWidth - container . offsetWidth ;
133+ const startingScroll = currentScroll <= 1 ;
134+ const endScroll = currentScroll >= scrollingLength - 1 ;
135+
136+ setScrollLeftEnabled ( ! startingScroll ) ;
137+ setScrollRightEnabled ( ! endScroll ) ;
138+ }
139+ } ;
140+
141141 const scrollLeft = ( ) => {
142- const offsetHeight = refTabList ?. current ?. offsetHeight ?? 0 ;
143- let moveX = 0 ;
144- if ( countClick <= offsetHeight ) {
145- moveX = 0 ;
146- setScrollLeftEnabled ( false ) ;
147- setScrollRightEnabled ( true ) ;
148- } else {
149- moveX = countClick - offsetHeight * 2 ;
150- setScrollRightEnabled ( true ) ;
151- setScrollLeftEnabled ( true ) ;
142+ if ( refTabListContainer . current ) {
143+ refTabListContainer . current . scrollLeft -= 100 ;
144+ scrollLimitCheck ( ) ;
152145 }
153- setTranslateScroll ( - moveX ) ;
154- setCountClick ( moveX ) ;
155146 } ;
156147
157148 const scrollRight = ( ) => {
158- const offsetHeight = refTabList ?. current ?. offsetHeight ?? 0 ;
159- let moveX = 0 ;
160- if ( countClick + offsetHeight >= totalTabsWidth ) {
161- moveX = totalTabsWidth - offsetHeight ;
162- setScrollRightEnabled ( false ) ;
163- setScrollLeftEnabled ( true ) ;
164- } else {
165- moveX = countClick + offsetHeight * 2 ;
166- setScrollLeftEnabled ( true ) ;
167- setScrollRightEnabled ( true ) ;
149+ if ( refTabListContainer . current ) {
150+ refTabListContainer . current . scrollLeft += 100 ;
151+ scrollLimitCheck ( ) ;
168152 }
169- setTranslateScroll ( - moveX ) ;
170- setCountClick ( moveX ) ;
171153 } ;
172154
173155 const handleOnKeyDown = ( event : KeyboardEvent < HTMLDivElement > ) => {
174156 const activeTab = childrenArray . findIndex (
175157 ( child : ReactElement ) => ( child . props . label ?? child . props . tabId ) === activeTabId
176158 ) ;
159+ let index ;
177160 switch ( event . key ) {
178161 case "Left" :
179162 case "ArrowLeft" :
180163 event . preventDefault ( ) ;
181- setInnerFocusIndex ( getPreviousTabIndex ( childrenArray , innerFocusIndex === null ? activeTab : innerFocusIndex ) ) ;
164+ index = getPreviousTabIndex ( childrenArray , innerFocusIndex === null ? activeTab : innerFocusIndex ) ;
165+ setInnerFocusIndex ( index ) ;
166+
182167 break ;
183168 case "Right" :
184169 case "ArrowRight" :
185170 event . preventDefault ( ) ;
186- setInnerFocusIndex ( getNextTabIndex ( childrenArray , innerFocusIndex === null ? activeTab : innerFocusIndex ) ) ;
171+ index = getNextTabIndex ( childrenArray , innerFocusIndex === null ? activeTab : innerFocusIndex ) ;
172+ setInnerFocusIndex ( index ) ;
187173 break ;
188174 case "Tab" :
189175 if ( activeTab !== innerFocusIndex ) {
@@ -193,18 +179,25 @@ const DxcTabs = ({
193179 default :
194180 break ;
195181 }
182+ setTimeout ( ( ) => {
183+ scrollLimitCheck ( ) ;
184+ } , 0 ) ;
196185 } ;
197186
198- useLayoutEffect ( ( ) => {
187+ useEffect ( ( ) => {
199188 if ( refTabList . current )
200189 setTotalTabsWidth ( ( ) => {
201190 let total = 0 ;
202- refTabList . current ?. querySelectorAll ( '[role="tab"]' ) . forEach ( ( tab ) => {
191+ refTabList . current ?. querySelectorAll ( '[role="tab"]' ) . forEach ( ( tab , index ) => {
192+ if ( tab . ariaSelected === "true" && viewWidth && viewWidth < totalTabsWidth ) {
193+ setInnerFocusIndex ( index ) ;
194+ }
203195 total += ( tab as HTMLElement ) . offsetWidth ;
204196 } ) ;
205197 return total ;
206198 } ) ;
207- } , [ ] ) ;
199+ scrollLimitCheck ( ) ;
200+ } , [ viewWidth , totalTabsWidth ] ) ;
208201
209202 return (
210203 < >
@@ -221,14 +214,13 @@ const DxcTabs = ({
221214 < DxcIcon icon = "keyboard_arrow_left" />
222215 </ ScrollIndicatorButton >
223216 ) }
224- < TabsContent >
217+ < TabsContent ref = { refTabListContainer } >
225218 < ScrollableTabsList
226219 enabled = { viewWidth < totalTabsWidth }
227220 iconPosition = { iconPosition }
228221 onKeyDown = { handleOnKeyDown }
229222 ref = { refTabList }
230223 role = "tablist"
231- translateScroll = { translateScroll }
232224 >
233225 < TabsContext . Provider value = { contextValue } > { children } </ TabsContext . Provider >
234226 </ ScrollableTabsList >
0 commit comments