refactor(TabContainer): 抽取通用 Tab 容器组件

- 新增 src/components/TabContainer/ 通用组件
  - 支持受控/非受控模式
  - 支持多种主题预设(blackGold、default、dark、light)
  - 支持自定义主题颜色和样式配置
  - 使用 TypeScript 实现,类型完整
- 重构 CompanyTabs 使用通用 TabContainer
- 删除 CompanyTabs/TabNavigation.js(逻辑迁移到通用组件)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
zdl
2025-12-11 16:59:17 +08:00
parent 13fa91a998
commit a47e0feed8
6 changed files with 362 additions and 109 deletions

View File

@@ -1,55 +0,0 @@
// src/views/Company/components/CompanyTabs/TabNavigation.js
// Tab 导航组件 - 动态渲染 Tab 按钮(黑金主题)
import React from 'react';
import {
TabList,
Tab,
HStack,
Icon,
Text,
} from '@chakra-ui/react';
import { COMPANY_TABS } from '../../constants';
// 黑金主题颜色配置
const THEME_COLORS = {
bg: '#1A202C', // 背景纯黑
selectedBg: '#C9A961', // 选中项金色背景
selectedText: '#FFFFFF', // 选中项白色文字
unselectedText: '#D4AF37', // 未选中项金色
};
/**
* Tab 导航组件(黑金主题)
*/
const TabNavigation = () => {
return (
<TabList py={4} bg={THEME_COLORS.bg} borderTopLeftRadius="16px" borderTopRightRadius="16px">
{COMPANY_TABS.map((tab, index) => (
<Tab
key={tab.key}
color={THEME_COLORS.unselectedText}
borderRadius="full"
px={4}
py={2}
_selected={{
bg: THEME_COLORS.selectedBg,
color: THEME_COLORS.selectedText,
}}
_hover={{
color: THEME_COLORS.selectedText,
}}
mr={index < COMPANY_TABS.length - 1 ? 2 : 0}
>
<HStack spacing={2}>
<Icon as={tab.icon} boxSize="18px" />
<Text fontSize="15px">{tab.name}</Text>
</HStack>
</Tab>
))}
</TabList>
);
};
export default TabNavigation;

View File

@@ -1,17 +1,8 @@
// src/views/Company/components/CompanyTabs/index.js
// Tab 容器组件 - 管理 Tab 切换和内容渲染
// Tab 容器组件 - 使用通用 TabContainer 组件
import React, { useState } from 'react';
import {
Card,
CardBody,
Tabs,
TabPanels,
TabPanel,
Divider,
} from '@chakra-ui/react';
import TabNavigation from './TabNavigation';
import React from 'react';
import TabContainer from '@components/TabContainer';
import { COMPANY_TABS, getTabNameByIndex } from '../../constants';
// 子组件导入Tab 内容组件)
@@ -24,7 +15,6 @@ import DynamicTracking from '../DynamicTracking';
/**
* Tab 组件映射
* key 与 COMPANY_TABS 中的 key 对应
*/
const TAB_COMPONENTS = {
overview: CompanyOverview,
@@ -36,11 +26,25 @@ const TAB_COMPONENTS = {
};
/**
* Tab 容器组件
* 构建 TabContainer 所需的 tabs 配置
* 合并 COMPANY_TABS 和对应的组件
*/
const buildTabsConfig = () => {
return COMPANY_TABS.map((tab) => ({
...tab,
component: TAB_COMPONENTS[tab.key],
}));
};
// 预构建 tabs 配置(避免每次渲染重新计算)
const TABS_CONFIG = buildTabsConfig();
/**
* 公司详情 Tab 容器组件
*
* 功能:
* - 管理 Tab 切换状态
* - 动态渲染 Tab 导航和内容
* - 使用通用 TabContainer 组件
* - 保持黑金主题风格
* - 触发 Tab 变更追踪
*
* @param {Object} props
@@ -48,51 +52,23 @@ const TAB_COMPONENTS = {
* @param {Function} props.onTabChange - Tab 变更回调 (index, tabName, prevIndex) => void
*/
const CompanyTabs = ({ stockCode, onTabChange }) => {
const [currentIndex, setCurrentIndex] = useState(0);
/**
* 处理 Tab 切换
* 转换 tabKey 为 tabName 以保持原有回调格式
*/
const handleTabChange = (index) => {
const handleTabChange = (index, tabKey, prevIndex) => {
const tabName = getTabNameByIndex(index);
// 触发追踪回调
onTabChange?.(index, tabName, currentIndex);
// 更新状态
setCurrentIndex(index);
onTabChange?.(index, tabName, prevIndex);
};
return (
<Card shadow="lg" bg='#1A202C'>
<CardBody p={0}>
<Tabs
isLazy
variant="soft-rounded"
colorScheme="blue"
size="lg"
index={currentIndex}
onChange={handleTabChange}
>
{/* Tab 导航(黑金主题) */}
<TabNavigation />
<Divider />
{/* Tab 内容面板 */}
<TabPanels>
{COMPANY_TABS.map((tab) => {
const Component = TAB_COMPONENTS[tab.key];
return (
<TabPanel key={tab.key} px={0}>
<Component stockCode={stockCode} />
</TabPanel>
);
})}
</TabPanels>
</Tabs>
</CardBody>
</Card>
<TabContainer
tabs={TABS_CONFIG}
componentProps={{ stockCode }}
onTabChange={handleTabChange}
themePreset="blackGold"
borderRadius="16px"
/>
);
};