44 * This source code is licensed under the MIT license found in the
55 * LICENSE file in the root directory of this source tree.
66 */
7- import React from 'react' ;
7+ import React , {
8+ startTransition ,
9+ useId ,
10+ unstable_ViewTransition as ViewTransition ,
11+ unstable_addTransitionType as addTransitionType ,
12+ } from 'react' ;
813import clsx from 'clsx' ;
914
1015export default function TabbedWindow ( {
@@ -16,6 +21,16 @@ export default function TabbedWindow({
1621 activeTab : string ;
1722 onTabChange : ( tab : string ) => void ;
1823} ) : React . ReactElement {
24+ const id = useId ( ) ;
25+ const transitionName = `tab-highlight-${ id } ` ;
26+
27+ const handleTabChange = ( tab : string ) : void => {
28+ startTransition ( ( ) => {
29+ addTransitionType ( 'tab' ) ;
30+ onTabChange ( tab ) ;
31+ } ) ;
32+ } ;
33+
1934 return (
2035 < div className = "flex flex-col h-full max-w-full" >
2136 < div className = "flex p-2 flex-shrink-0" >
@@ -24,13 +39,22 @@ export default function TabbedWindow({
2439 return (
2540 < button
2641 key = { tab }
27- onClick = { ( ) => onTabChange ( tab ) }
42+ onClick = { ( ) => handleTabChange ( tab ) }
2843 className = { clsx (
29- 'active:scale-95 transition-transform py-1.5 px-1.5 xs:px-3 sm:px-4 rounded-full text-sm' ,
30- ! isActive && 'hover:bg-primary/5' ,
31- isActive && 'bg-highlight text-link' ,
44+ 'transition-transform py-1.5 px-1.5 xs:px-3 sm:px-4 rounded-full text-sm relative' ,
45+ isActive ? 'text-link' : 'hover:bg-primary/5' ,
3246 ) } >
33- { tab }
47+ { isActive && (
48+ < ViewTransition
49+ name = { transitionName }
50+ share = { { tab : 'tab-highlight' } }
51+ update = { { default : 'none' } } >
52+ < div className = "absolute inset-0 bg-highlight rounded-full" />
53+ </ ViewTransition >
54+ ) }
55+ < ViewTransition update = { { tab : 'tab-text' , default : 'none' } } >
56+ < span className = "relative z-1" > { tab } </ span >
57+ </ ViewTransition >
3458 </ button >
3559 ) ;
3660 } ) }
0 commit comments