46 lines
1.2 KiB
TypeScript
46 lines
1.2 KiB
TypeScript
|
|
import { useEffect, useState } from 'react';
|
||
|
|
|
||
|
|
import { appTabs, type AppTabConfig } from '../../router/tabs';
|
||
|
|
|
||
|
|
interface KeepAliveViewportProps {
|
||
|
|
activeTab: AppTabConfig;
|
||
|
|
}
|
||
|
|
|
||
|
|
export function KeepAliveViewport({ activeTab }: KeepAliveViewportProps) {
|
||
|
|
const [mountedTabIds, setMountedTabIds] = useState<string[]>([activeTab.id]);
|
||
|
|
|
||
|
|
useEffect(() => {
|
||
|
|
const timerId = window.setTimeout(() => {
|
||
|
|
setMountedTabIds((prev) => (prev.includes(activeTab.id) ? prev : [...prev, activeTab.id]));
|
||
|
|
}, 0);
|
||
|
|
return () => window.clearTimeout(timerId);
|
||
|
|
}, [activeTab.id]);
|
||
|
|
|
||
|
|
return (
|
||
|
|
<div className="flex min-h-0 flex-1">
|
||
|
|
{appTabs.map((tab) => {
|
||
|
|
const shouldRender = tab.keepAlive ? mountedTabIds.includes(tab.id) : tab.id === activeTab.id;
|
||
|
|
if (!shouldRender) {
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
|
||
|
|
const TabComponent = tab.component;
|
||
|
|
const isActive = tab.id === activeTab.id;
|
||
|
|
|
||
|
|
return (
|
||
|
|
<div
|
||
|
|
key={tab.id}
|
||
|
|
aria-hidden={!isActive}
|
||
|
|
className={[
|
||
|
|
'min-h-0 flex-1',
|
||
|
|
isActive ? 'flex' : 'hidden',
|
||
|
|
].join(' ')}
|
||
|
|
>
|
||
|
|
<TabComponent />
|
||
|
|
</div>
|
||
|
|
);
|
||
|
|
})}
|
||
|
|
</div>
|
||
|
|
);
|
||
|
|
}
|