mirror of
https://github.com/siteboon/claudecodeui.git
synced 2026-03-10 08:27:40 +00:00
# Conflicts: # src/App.tsx # src/components/app/MobileNav.tsx # src/components/main-content/view/MainContent.tsx # src/components/main-content/view/subcomponents/MainContentTabSwitcher.tsx # src/components/main-content/view/subcomponents/MainContentTitle.tsx # src/components/settings/view/SettingsMainTabs.tsx
101 lines
3.1 KiB
TypeScript
101 lines
3.1 KiB
TypeScript
import { MessageSquare, Terminal, Folder, GitBranch, ClipboardCheck, type LucideIcon } from 'lucide-react';
|
|
import type { Dispatch, SetStateAction } from 'react';
|
|
import { useTranslation } from 'react-i18next';
|
|
import { Tooltip } from '../../../../shared/view/ui';
|
|
import type { AppTab } from '../../../../types/app';
|
|
import { usePlugins } from '../../../../contexts/PluginsContext';
|
|
import PluginIcon from '../../../plugins/PluginIcon';
|
|
|
|
type MainContentTabSwitcherProps = {
|
|
activeTab: AppTab;
|
|
setActiveTab: Dispatch<SetStateAction<AppTab>>;
|
|
shouldShowTasksTab: boolean;
|
|
};
|
|
|
|
type BuiltInTab = {
|
|
kind: 'builtin';
|
|
id: AppTab;
|
|
labelKey: string;
|
|
icon: LucideIcon;
|
|
};
|
|
|
|
type PluginTab = {
|
|
kind: 'plugin';
|
|
id: AppTab;
|
|
label: string;
|
|
pluginName: string;
|
|
iconFile: string;
|
|
};
|
|
|
|
type TabDefinition = BuiltInTab | PluginTab;
|
|
|
|
const BASE_TABS: BuiltInTab[] = [
|
|
{ kind: 'builtin', id: 'chat', labelKey: 'tabs.chat', icon: MessageSquare },
|
|
{ kind: 'builtin', id: 'shell', labelKey: 'tabs.shell', icon: Terminal },
|
|
{ kind: 'builtin', id: 'files', labelKey: 'tabs.files', icon: Folder },
|
|
{ kind: 'builtin', id: 'git', labelKey: 'tabs.git', icon: GitBranch },
|
|
];
|
|
|
|
const TASKS_TAB: BuiltInTab = {
|
|
kind: 'builtin',
|
|
id: 'tasks',
|
|
labelKey: 'tabs.tasks',
|
|
icon: ClipboardCheck,
|
|
};
|
|
|
|
export default function MainContentTabSwitcher({
|
|
activeTab,
|
|
setActiveTab,
|
|
shouldShowTasksTab,
|
|
}: MainContentTabSwitcherProps) {
|
|
const { t } = useTranslation();
|
|
const { plugins } = usePlugins();
|
|
|
|
const builtInTabs: BuiltInTab[] = shouldShowTasksTab ? [...BASE_TABS, TASKS_TAB] : BASE_TABS;
|
|
|
|
const pluginTabs: PluginTab[] = plugins
|
|
.filter((p) => p.enabled)
|
|
.map((p) => ({
|
|
kind: 'plugin',
|
|
id: `plugin:${p.name}` as AppTab,
|
|
label: p.displayName,
|
|
pluginName: p.name,
|
|
iconFile: p.icon,
|
|
}));
|
|
|
|
const tabs: TabDefinition[] = [...builtInTabs, ...pluginTabs];
|
|
|
|
return (
|
|
<div className="inline-flex items-center gap-[2px] rounded-lg bg-muted/60 p-[3px]">
|
|
{tabs.map((tab) => {
|
|
const isActive = tab.id === activeTab;
|
|
const displayLabel = tab.kind === 'builtin' ? t(tab.labelKey) : tab.label;
|
|
|
|
return (
|
|
<Tooltip key={tab.id} content={displayLabel} position="bottom">
|
|
<button
|
|
onClick={() => setActiveTab(tab.id)}
|
|
className={`relative flex items-center gap-1.5 rounded-md px-2.5 py-[5px] text-sm font-medium transition-all duration-150 ${
|
|
isActive
|
|
? 'bg-background text-foreground shadow-sm'
|
|
: 'text-muted-foreground hover:text-foreground'
|
|
}`}
|
|
>
|
|
{tab.kind === 'builtin' ? (
|
|
<tab.icon className="h-3.5 w-3.5" strokeWidth={isActive ? 2.2 : 1.8} />
|
|
) : (
|
|
<PluginIcon
|
|
pluginName={tab.pluginName}
|
|
iconFile={tab.iconFile}
|
|
className="flex h-3.5 w-3.5 items-center justify-center [&>svg]:h-full [&>svg]:w-full"
|
|
/>
|
|
)}
|
|
<span className="hidden lg:inline">{displayLabel}</span>
|
|
</button>
|
|
</Tooltip>
|
|
);
|
|
})}
|
|
</div>
|
|
);
|
|
}
|