11import { ChevronLeft , ChevronRight , Table , X } from 'lucide-react'
2- import React from 'react'
3- import { useEffect , useRef , useState } from 'react'
2+ import { type ReactNode , useEffect , useRef , useState } from 'react'
43
5- import { cn } from '../lib/utils'
6- import { Button } from '../ui/button'
4+ import { cn } from '../../../../shared/ lib/utils'
5+ import { Button } from '../../../../shared/ ui/button'
76
87export interface Tab {
98 id : string
@@ -16,10 +15,18 @@ interface TableTabsProps {
1615 activeTab : string
1716 onSelectTab : ( id : string ) => void
1817 onCloseTab : ( id : string ) => void
19- children : React . ReactNode
18+ renderTab ?: ( tab : Tab , defaultTab : ReactNode ) => ReactNode
19+ children : ReactNode
2020}
2121
22- export function TableTabs ( { tabs, activeTab, onSelectTab, onCloseTab, children } : TableTabsProps ) {
22+ export function TableTabs ( {
23+ tabs,
24+ activeTab,
25+ onSelectTab,
26+ onCloseTab,
27+ renderTab,
28+ children
29+ } : TableTabsProps ) {
2330 const tabsRef = useRef < HTMLDivElement > ( null )
2431 const [ showScrollButtons , setShowScrollButtons ] = useState ( false )
2532
@@ -61,38 +68,42 @@ export function TableTabs({ tabs, activeTab, onSelectTab, onCloseTab, children }
6168 ) }
6269
6370 < div ref = { tabsRef } className = "scrollbar-none flex flex-1 overflow-x-auto" >
64- { tabs . map ( tab => (
65- < button
66- key = { tab . id }
67- type = "button"
68- className = { cn (
69- 'group border-border flex shrink-0 items-center gap-2 border-r px-4 py-2 text-sm transition-colors' ,
70- activeTab === tab . id
71- ? 'bg-background text-foreground'
72- : 'bg-card text-muted-foreground hover:bg-secondary hover:text-foreground'
73- ) }
74- onClick = { ( ) => onSelectTab ( tab . id ) }
75- >
76- < Table className = "text-primary h-4 w-4" />
77- < span className = "max-w-32 truncate" > { tab . name } </ span >
71+ { tabs . map ( tab => {
72+ const defaultTab = (
7873 < button
74+ key = { tab . id }
7975 type = "button"
8076 className = { cn (
81- 'ml-1 rounded p-0.5 transition-colors' ,
82- 'text-muted-foreground hover:bg-secondary hover:text-foreground' ,
83- 'opacity-0 group-hover:opacity-100' ,
84- activeTab === tab . id && 'opacity-100 '
77+ 'group border-border flex shrink-0 items-center gap-2 border-r px-4 py-2 text-sm transition-colors select-none ' ,
78+ activeTab === tab . id
79+ ? 'bg-background text-foreground'
80+ : 'bg-card text-muted-foreground hover:bg-secondary hover:text-foreground '
8581 ) }
86- onClick = { e => {
87- e . stopPropagation ( )
88- onCloseTab ( tab . id )
89- } }
82+ onClick = { ( ) => onSelectTab ( tab . id ) }
9083 >
91- < X className = "h-3.5 w-3.5" />
92- < span className = "sr-only" > Close tab</ span >
84+ < Table className = "text-primary h-4 w-4" />
85+ < span className = "max-w-32 truncate" > { tab . name } </ span >
86+
87+ < button
88+ type = "button"
89+ className = { cn (
90+ 'ml-1 rounded p-0.5 transition-colors' ,
91+ 'text-muted-foreground hover:bg-secondary hover:text-foreground' ,
92+ 'opacity-0 group-hover:opacity-100' ,
93+ activeTab === tab . id && 'opacity-100'
94+ ) }
95+ onClick = { e => {
96+ e . stopPropagation ( )
97+ onCloseTab ( tab . id )
98+ } }
99+ >
100+ < X className = "h-3.5 w-3.5" />
101+ </ button >
93102 </ button >
94- </ button >
95- ) ) }
103+ )
104+
105+ return renderTab ? renderTab ( tab , defaultTab ) : defaultTab
106+ } ) }
96107 </ div >
97108
98109 { showScrollButtons && (
@@ -103,7 +114,6 @@ export function TableTabs({ tabs, activeTab, onSelectTab, onCloseTab, children }
103114 onClick = { ( ) => scroll ( 'right' ) }
104115 >
105116 < ChevronRight className = "h-4 w-4" />
106- < span className = "sr-only" > Scroll right</ span >
107117 </ Button >
108118 ) }
109119 </ div >
0 commit comments