feat: tab bar
This commit is contained in:
@@ -13,40 +13,42 @@ export default function TabBar() {
|
||||
if (visible.length === 0) return null
|
||||
|
||||
return (
|
||||
<div className="flex items-end bg-dark-900 border-b border-slate-700/40 px-2 gap-0.5 pt-1 shrink-0">
|
||||
{visible.map(({ path, label, icon: Icon }) => {
|
||||
const isActive = location.pathname === path || location.pathname.startsWith(path + '/')
|
||||
return (
|
||||
<button
|
||||
key={path}
|
||||
onClick={() => navigate(path)}
|
||||
className={clsx(
|
||||
'group flex items-center gap-1.5 px-3 py-1.5 text-xs rounded-t border border-b-0 transition-all -mb-px select-none whitespace-nowrap',
|
||||
isActive
|
||||
? 'bg-dark-800 border-slate-600/50 text-slate-200 font-medium z-10'
|
||||
: 'bg-transparent border-transparent text-slate-500 hover:text-slate-300 hover:bg-dark-800/40 hover:border-slate-700/40'
|
||||
)}
|
||||
>
|
||||
<Icon size={11} className="shrink-0" />
|
||||
<span>{label}</span>
|
||||
<span
|
||||
role="button"
|
||||
tabIndex={-1}
|
||||
onClick={e => {
|
||||
e.stopPropagation()
|
||||
const remaining = visible.filter(m => m.path !== path)
|
||||
forgetRoute(path)
|
||||
if (isActive && remaining.length > 0) {
|
||||
navigate(remaining[remaining.length - 1].path)
|
||||
}
|
||||
}}
|
||||
className="ml-1.5 opacity-0 group-hover:opacity-100 text-slate-600 hover:text-white rounded hover:bg-slate-600/40 p-0.5 transition-opacity leading-none"
|
||||
<div className="flex items-end bg-dark-900 border-b border-slate-700/40 overflow-x-auto shrink-0 scrollbar-none">
|
||||
<div className="flex items-end gap-0.5 px-2 pt-1 min-w-max">
|
||||
{visible.map(({ path, label, icon: Icon }) => {
|
||||
const isActive = location.pathname === path || location.pathname.startsWith(path + '/')
|
||||
return (
|
||||
<button
|
||||
key={path}
|
||||
onClick={() => navigate(path)}
|
||||
className={clsx(
|
||||
'group flex items-center gap-1.5 px-2.5 py-1.5 text-xs rounded-t border border-b-0 transition-all -mb-px select-none shrink-0',
|
||||
isActive
|
||||
? 'bg-dark-800 border-slate-600/50 text-slate-200 font-medium z-10'
|
||||
: 'bg-transparent border-transparent text-slate-500 hover:text-slate-300 hover:bg-dark-800/40 hover:border-slate-700/40'
|
||||
)}
|
||||
>
|
||||
<X size={9} />
|
||||
</span>
|
||||
</button>
|
||||
)
|
||||
})}
|
||||
<Icon size={11} className="shrink-0" />
|
||||
<span className="max-w-24 truncate">{label}</span>
|
||||
<span
|
||||
role="button"
|
||||
tabIndex={-1}
|
||||
onClick={e => {
|
||||
e.stopPropagation()
|
||||
const remaining = visible.filter(m => m.path !== path)
|
||||
forgetRoute(path)
|
||||
if (isActive && remaining.length > 0) {
|
||||
navigate(remaining[remaining.length - 1].path)
|
||||
}
|
||||
}}
|
||||
className="ml-1 opacity-0 group-hover:opacity-100 text-slate-600 hover:text-white rounded hover:bg-slate-600/40 p-0.5 transition-opacity leading-none"
|
||||
>
|
||||
<X size={9} />
|
||||
</span>
|
||||
</button>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user