/** * TabPanelContainer - Tab 面板通用容器组件 * * 提供统一的: * - Loading 状态处理 * - VStack 布局 * - 免责声明(可选) * * @example * ```tsx * * * * ``` */ import React, { memo } from 'react'; import { VStack, Center, Spinner, Text, Box } from '@chakra-ui/react'; // 默认免责声明文案 const DEFAULT_DISCLAIMER = '免责声明:本内容由AI模型基于新闻、公告、研报等公开信息自动分析和生成,未经许可严禁转载。所有内容仅供参考,不构成任何投资建议,请投资者注意风险,独立审慎决策。'; export interface TabPanelContainerProps { /** 是否处于加载状态 */ loading?: boolean; /** 加载状态显示的文案 */ loadingMessage?: string; /** 加载状态高度 */ loadingHeight?: string; /** 自定义骨架屏组件,优先于默认 Spinner */ skeleton?: React.ReactNode; /** 子组件间距,默认 6 */ spacing?: number; /** 内边距,默认 4 */ padding?: number; /** 是否显示免责声明,默认 false */ showDisclaimer?: boolean; /** 自定义免责声明文案 */ disclaimerText?: string; /** 子组件 */ children: React.ReactNode; } /** * 加载状态组件 */ const LoadingState: React.FC<{ message: string; height: string }> = ({ message, height, }) => (
{message}
); /** * 免责声明组件 */ const DisclaimerText: React.FC<{ text: string }> = ({ text }) => ( {text} ); /** * Tab 面板通用容器 */ const TabPanelContainer: React.FC = memo( ({ loading = false, loadingMessage = '加载中...', loadingHeight = '200px', skeleton, spacing = 6, padding = 4, showDisclaimer = false, disclaimerText = DEFAULT_DISCLAIMER, children, }) => { if (loading) { // 如果提供了自定义骨架屏,使用骨架屏;否则使用默认 Spinner if (skeleton) { return <>{skeleton}; } return ; } return ( {children} {showDisclaimer && } ); } ); TabPanelContainer.displayName = 'TabPanelContainer'; export default TabPanelContainer;