feat(Calendar): 新增公共日历组件 BaseCalendar
This commit is contained in:
269
src/components/Calendar/BaseCalendar.tsx
Normal file
269
src/components/Calendar/BaseCalendar.tsx
Normal file
@@ -0,0 +1,269 @@
|
|||||||
|
/**
|
||||||
|
* BaseCalendar - 基础日历组件
|
||||||
|
* 封装 Ant Design Calendar,提供统一的黑金主题和接口
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React, { useCallback } from 'react';
|
||||||
|
import { Calendar, ConfigProvider, Button } from 'antd';
|
||||||
|
import type { CalendarProps } from 'antd';
|
||||||
|
import { LeftOutlined, RightOutlined } from '@ant-design/icons';
|
||||||
|
import type { Dayjs } from 'dayjs';
|
||||||
|
import dayjs from 'dayjs';
|
||||||
|
import 'dayjs/locale/zh-cn';
|
||||||
|
import zhCN from 'antd/locale/zh_CN';
|
||||||
|
import { Box, HStack, Text } from '@chakra-ui/react';
|
||||||
|
import { CALENDAR_THEME, CALENDAR_COLORS, CALENDAR_STYLES } from './theme';
|
||||||
|
|
||||||
|
dayjs.locale('zh-cn');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 单元格渲染信息
|
||||||
|
*/
|
||||||
|
export interface CellRenderInfo {
|
||||||
|
type: 'date' | 'month';
|
||||||
|
isToday: boolean;
|
||||||
|
isCurrentMonth: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BaseCalendar Props
|
||||||
|
*/
|
||||||
|
export interface BaseCalendarProps {
|
||||||
|
/** 当前选中日期 */
|
||||||
|
value?: Dayjs;
|
||||||
|
/** 日期变化回调(月份切换等) */
|
||||||
|
onChange?: (date: Dayjs) => void;
|
||||||
|
/** 日期选择回调(点击日期) */
|
||||||
|
onSelect?: (date: Dayjs) => void;
|
||||||
|
/** 自定义单元格内容渲染 */
|
||||||
|
cellRender?: (date: Dayjs, info: CellRenderInfo) => React.ReactNode;
|
||||||
|
/** 日历高度 */
|
||||||
|
height?: string | number;
|
||||||
|
/** 是否显示工具栏 */
|
||||||
|
showToolbar?: boolean;
|
||||||
|
/** 工具栏标题格式 */
|
||||||
|
titleFormat?: string;
|
||||||
|
/** 额外的 className */
|
||||||
|
className?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 默认工具栏组件
|
||||||
|
*/
|
||||||
|
const CalendarToolbar: React.FC<{
|
||||||
|
value: Dayjs;
|
||||||
|
onChange: (date: Dayjs) => void;
|
||||||
|
titleFormat?: string;
|
||||||
|
}> = ({ value, onChange, titleFormat = 'YYYY年M月' }) => {
|
||||||
|
const handlePrev = () => onChange(value.subtract(1, 'month'));
|
||||||
|
const handleNext = () => onChange(value.add(1, 'month'));
|
||||||
|
const handleToday = () => onChange(dayjs());
|
||||||
|
|
||||||
|
return (
|
||||||
|
<HStack justify="flex-start" mb={4} px={2} spacing={4}>
|
||||||
|
<HStack spacing={2}>
|
||||||
|
<Button
|
||||||
|
type="primary"
|
||||||
|
icon={<LeftOutlined />}
|
||||||
|
onClick={handlePrev}
|
||||||
|
style={{
|
||||||
|
backgroundColor: CALENDAR_STYLES.toolbar.buttonBg,
|
||||||
|
borderColor: CALENDAR_STYLES.toolbar.buttonBg,
|
||||||
|
color: CALENDAR_STYLES.toolbar.buttonColor,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
type="primary"
|
||||||
|
icon={<RightOutlined />}
|
||||||
|
onClick={handleNext}
|
||||||
|
style={{
|
||||||
|
backgroundColor: CALENDAR_STYLES.toolbar.buttonBg,
|
||||||
|
borderColor: CALENDAR_STYLES.toolbar.buttonBg,
|
||||||
|
color: CALENDAR_STYLES.toolbar.buttonColor,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
type="primary"
|
||||||
|
onClick={handleToday}
|
||||||
|
style={{
|
||||||
|
backgroundColor: CALENDAR_STYLES.toolbar.buttonBg,
|
||||||
|
borderColor: CALENDAR_STYLES.toolbar.buttonBg,
|
||||||
|
color: CALENDAR_STYLES.toolbar.buttonColor,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
今天
|
||||||
|
</Button>
|
||||||
|
</HStack>
|
||||||
|
<Text
|
||||||
|
fontSize={{ base: 'lg', md: 'xl' }}
|
||||||
|
fontWeight="700"
|
||||||
|
bgGradient={`linear(135deg, ${CALENDAR_COLORS.gold.primary} 0%, #F5E6A3 100%)`}
|
||||||
|
bgClip="text"
|
||||||
|
>
|
||||||
|
{value.format(titleFormat)}
|
||||||
|
</Text>
|
||||||
|
</HStack>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BaseCalendar 组件
|
||||||
|
*/
|
||||||
|
export const BaseCalendar: React.FC<BaseCalendarProps> = ({
|
||||||
|
value,
|
||||||
|
onChange,
|
||||||
|
onSelect,
|
||||||
|
cellRender,
|
||||||
|
height = '100%',
|
||||||
|
showToolbar = true,
|
||||||
|
titleFormat = 'YYYY年M月',
|
||||||
|
className,
|
||||||
|
}) => {
|
||||||
|
const [currentValue, setCurrentValue] = React.useState<Dayjs>(value || dayjs());
|
||||||
|
|
||||||
|
// 同步外部 value
|
||||||
|
React.useEffect(() => {
|
||||||
|
if (value) {
|
||||||
|
setCurrentValue(value);
|
||||||
|
}
|
||||||
|
}, [value]);
|
||||||
|
|
||||||
|
// 处理日期变化
|
||||||
|
const handleChange = useCallback((date: Dayjs) => {
|
||||||
|
setCurrentValue(date);
|
||||||
|
onChange?.(date);
|
||||||
|
}, [onChange]);
|
||||||
|
|
||||||
|
// 处理日期选择(只在点击日期时触发,不在切换面板时触发)
|
||||||
|
const handleSelect: CalendarProps<Dayjs>['onSelect'] = useCallback((date: Dayjs, selectInfo) => {
|
||||||
|
// selectInfo.source: 'date' 表示点击日期,'month' 表示切换月份面板
|
||||||
|
// 只在点击日期时触发 onSelect
|
||||||
|
if (selectInfo.source === 'date') {
|
||||||
|
setCurrentValue(date);
|
||||||
|
onSelect?.(date);
|
||||||
|
}
|
||||||
|
}, [onSelect]);
|
||||||
|
|
||||||
|
// 自定义单元格渲染
|
||||||
|
const fullCellRender = useCallback((date: Dayjs) => {
|
||||||
|
const isToday = date.isSame(dayjs(), 'day');
|
||||||
|
const isCurrentMonth = date.isSame(currentValue, 'month');
|
||||||
|
|
||||||
|
const info: CellRenderInfo = {
|
||||||
|
type: 'date',
|
||||||
|
isToday,
|
||||||
|
isCurrentMonth,
|
||||||
|
};
|
||||||
|
|
||||||
|
// 基础日期单元格样式
|
||||||
|
const cellStyle: React.CSSProperties = {
|
||||||
|
minHeight: CALENDAR_STYLES.cell.minHeight,
|
||||||
|
padding: CALENDAR_STYLES.cell.padding,
|
||||||
|
borderRadius: '8px',
|
||||||
|
transition: 'all 0.2s ease',
|
||||||
|
cursor: 'pointer',
|
||||||
|
...(isToday ? {
|
||||||
|
backgroundColor: CALENDAR_STYLES.today.bg,
|
||||||
|
border: CALENDAR_STYLES.today.border,
|
||||||
|
} : {}),
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
style={cellStyle}
|
||||||
|
className="base-calendar-cell"
|
||||||
|
>
|
||||||
|
{/* 日期数字 */}
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
textAlign: 'center',
|
||||||
|
fontSize: '14px',
|
||||||
|
fontWeight: isToday ? 700 : 600,
|
||||||
|
color: isToday
|
||||||
|
? CALENDAR_COLORS.gold.primary
|
||||||
|
: isCurrentMonth
|
||||||
|
? '#FFFFFF' // 纯白色,更亮
|
||||||
|
: 'rgba(255, 255, 255, 0.4)',
|
||||||
|
marginBottom: '4px',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{date.date()}
|
||||||
|
</div>
|
||||||
|
{/* 自定义内容 */}
|
||||||
|
{cellRender?.(date, info)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}, [currentValue, cellRender]);
|
||||||
|
|
||||||
|
// 隐藏默认 header
|
||||||
|
const headerRender = useCallback((): React.ReactNode => null, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box height={height} className={className}>
|
||||||
|
<ConfigProvider theme={CALENDAR_THEME} locale={zhCN}>
|
||||||
|
{showToolbar && (
|
||||||
|
<CalendarToolbar
|
||||||
|
value={currentValue}
|
||||||
|
onChange={handleChange}
|
||||||
|
titleFormat={titleFormat}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
<Box
|
||||||
|
height={showToolbar ? 'calc(100% - 60px)' : '100%'}
|
||||||
|
sx={{
|
||||||
|
// 日历整体样式
|
||||||
|
'.ant-picker-calendar': {
|
||||||
|
bg: 'transparent',
|
||||||
|
},
|
||||||
|
'.ant-picker-panel': {
|
||||||
|
bg: 'transparent',
|
||||||
|
border: 'none',
|
||||||
|
},
|
||||||
|
// 星期头 - 居中显示
|
||||||
|
'.ant-picker-content thead th': {
|
||||||
|
color: `${CALENDAR_COLORS.gold.primary} !important`,
|
||||||
|
fontWeight: '600 !important',
|
||||||
|
fontSize: '14px',
|
||||||
|
padding: '8px 0',
|
||||||
|
textAlign: 'center !important',
|
||||||
|
},
|
||||||
|
// 日期单元格
|
||||||
|
'.ant-picker-cell': {
|
||||||
|
padding: '2px',
|
||||||
|
},
|
||||||
|
'.ant-picker-cell-inner': {
|
||||||
|
width: '100%',
|
||||||
|
height: '100%',
|
||||||
|
},
|
||||||
|
// 非当前月份
|
||||||
|
'.ant-picker-cell-in-view': {
|
||||||
|
opacity: 1,
|
||||||
|
},
|
||||||
|
'.ant-picker-cell:not(.ant-picker-cell-in-view)': {
|
||||||
|
opacity: 0.5,
|
||||||
|
},
|
||||||
|
// hover 效果
|
||||||
|
'.base-calendar-cell:hover': {
|
||||||
|
bg: 'rgba(212, 175, 55, 0.1)',
|
||||||
|
},
|
||||||
|
// 选中状态
|
||||||
|
'.ant-picker-cell-selected .base-calendar-cell': {
|
||||||
|
bg: 'rgba(212, 175, 55, 0.15)',
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Calendar
|
||||||
|
fullscreen={true}
|
||||||
|
value={currentValue}
|
||||||
|
onChange={handleChange}
|
||||||
|
onSelect={handleSelect}
|
||||||
|
fullCellRender={fullCellRender}
|
||||||
|
headerRender={headerRender}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
</ConfigProvider>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default BaseCalendar;
|
||||||
142
src/components/Calendar/CalendarEventBlock.tsx
Normal file
142
src/components/Calendar/CalendarEventBlock.tsx
Normal file
@@ -0,0 +1,142 @@
|
|||||||
|
/**
|
||||||
|
* CalendarEventBlock - 日历事件块组件
|
||||||
|
* 用于在日历单元格中显示事件列表,支持多种事件类型和 "更多" 折叠
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React, { useMemo } from 'react';
|
||||||
|
import { HStack, Text, Badge, VStack, Box } from '@chakra-ui/react';
|
||||||
|
import { CALENDAR_COLORS } from './theme';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 事件类型定义
|
||||||
|
*/
|
||||||
|
export type EventType = 'news' | 'report' | 'plan' | 'review' | 'system' | 'priceUp' | 'priceDown';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 日历事件接口
|
||||||
|
*/
|
||||||
|
export interface CalendarEvent {
|
||||||
|
id: string | number;
|
||||||
|
type: EventType;
|
||||||
|
title: string;
|
||||||
|
date: string;
|
||||||
|
count?: number;
|
||||||
|
data?: unknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 事件块 Props
|
||||||
|
*/
|
||||||
|
interface CalendarEventBlockProps {
|
||||||
|
events: CalendarEvent[];
|
||||||
|
maxDisplay?: number;
|
||||||
|
onEventClick?: (event: CalendarEvent) => void;
|
||||||
|
onMoreClick?: (events: CalendarEvent[]) => void;
|
||||||
|
compact?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 事件类型配置
|
||||||
|
*/
|
||||||
|
const EVENT_CONFIG: Record<EventType, { label: string; color: string; emoji?: string }> = {
|
||||||
|
news: { label: '新闻', color: CALENDAR_COLORS.events.news, emoji: '📰' },
|
||||||
|
report: { label: '研报', color: CALENDAR_COLORS.events.report, emoji: '📊' },
|
||||||
|
plan: { label: '计划', color: CALENDAR_COLORS.events.plan },
|
||||||
|
review: { label: '复盘', color: CALENDAR_COLORS.events.review },
|
||||||
|
system: { label: '系统', color: CALENDAR_COLORS.events.system },
|
||||||
|
priceUp: { label: '涨', color: CALENDAR_COLORS.events.priceUp, emoji: '🔥' },
|
||||||
|
priceDown: { label: '跌', color: CALENDAR_COLORS.events.priceDown },
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 单个事件行组件
|
||||||
|
*/
|
||||||
|
const EventLine: React.FC<{
|
||||||
|
event: CalendarEvent;
|
||||||
|
compact?: boolean;
|
||||||
|
onClick?: () => void;
|
||||||
|
}> = ({ event, compact, onClick }) => {
|
||||||
|
const config = EVENT_CONFIG[event.type] || { label: event.type, color: '#888' };
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box
|
||||||
|
fontSize={compact ? '9px' : '10px'}
|
||||||
|
color={config.color}
|
||||||
|
cursor="pointer"
|
||||||
|
px={1}
|
||||||
|
py={0.5}
|
||||||
|
borderRadius="sm"
|
||||||
|
_hover={{ bg: 'rgba(255, 255, 255, 0.1)' }}
|
||||||
|
w="100%"
|
||||||
|
overflow="hidden"
|
||||||
|
textAlign="left"
|
||||||
|
onClick={(e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
onClick?.();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{/* 格式:计划:年末布局XX+1 */}
|
||||||
|
<Text fontWeight="600" fontSize={compact ? '9px' : '10px'} isTruncated>
|
||||||
|
{config.emoji ? `${config.emoji} ` : ''}{config.label}:{event.title || ''}
|
||||||
|
{(event.count ?? 0) > 1 && <Text as="span" color={config.color}>+{(event.count ?? 1) - 1}</Text>}
|
||||||
|
</Text>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 日历事件块组件
|
||||||
|
*/
|
||||||
|
export const CalendarEventBlock: React.FC<CalendarEventBlockProps> = ({
|
||||||
|
events,
|
||||||
|
maxDisplay = 3,
|
||||||
|
onEventClick,
|
||||||
|
onMoreClick,
|
||||||
|
compact = false,
|
||||||
|
}) => {
|
||||||
|
// 计算显示的事件和剩余事件
|
||||||
|
const { displayEvents, remainingCount, remainingEvents } = useMemo(() => {
|
||||||
|
if (events.length <= maxDisplay) {
|
||||||
|
return { displayEvents: events, remainingCount: 0, remainingEvents: [] };
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
displayEvents: events.slice(0, maxDisplay),
|
||||||
|
remainingCount: events.length - maxDisplay,
|
||||||
|
remainingEvents: events.slice(maxDisplay),
|
||||||
|
};
|
||||||
|
}, [events, maxDisplay]);
|
||||||
|
|
||||||
|
if (events.length === 0) return null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<VStack spacing={0} align="stretch" w="100%">
|
||||||
|
{displayEvents.map((event) => (
|
||||||
|
<EventLine
|
||||||
|
key={event.id}
|
||||||
|
event={event}
|
||||||
|
compact={compact}
|
||||||
|
onClick={() => onEventClick?.(event)}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
{remainingCount > 0 && (
|
||||||
|
<Box
|
||||||
|
fontSize="9px"
|
||||||
|
color={CALENDAR_COLORS.text.secondary}
|
||||||
|
cursor="pointer"
|
||||||
|
px={1}
|
||||||
|
py={0.5}
|
||||||
|
borderRadius="sm"
|
||||||
|
_hover={{ bg: 'rgba(255, 255, 255, 0.1)' }}
|
||||||
|
onClick={(e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
onMoreClick?.(remainingEvents);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Text>+{remainingCount} 更多</Text>
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
</VStack>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default CalendarEventBlock;
|
||||||
19
src/components/Calendar/index.ts
Normal file
19
src/components/Calendar/index.ts
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
/**
|
||||||
|
* Calendar 公共组件库
|
||||||
|
* 统一的日历组件,基于 Ant Design Calendar + 黑金主题
|
||||||
|
*/
|
||||||
|
|
||||||
|
// 基础日历组件
|
||||||
|
export { BaseCalendar } from './BaseCalendar';
|
||||||
|
export type { BaseCalendarProps, CellRenderInfo } from './BaseCalendar';
|
||||||
|
|
||||||
|
// 事件块组件
|
||||||
|
export { CalendarEventBlock } from './CalendarEventBlock';
|
||||||
|
export type { CalendarEvent, EventType } from './CalendarEventBlock';
|
||||||
|
|
||||||
|
// 主题配置
|
||||||
|
export {
|
||||||
|
CALENDAR_THEME,
|
||||||
|
CALENDAR_COLORS,
|
||||||
|
CALENDAR_STYLES,
|
||||||
|
} from './theme';
|
||||||
111
src/components/Calendar/theme.ts
Normal file
111
src/components/Calendar/theme.ts
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
/**
|
||||||
|
* Calendar 黑金主题配置
|
||||||
|
* 统一的 Ant Design Calendar 主题,用于所有日历组件
|
||||||
|
*/
|
||||||
|
|
||||||
|
import type { ThemeConfig } from 'antd';
|
||||||
|
|
||||||
|
// 黑金主题色值
|
||||||
|
export const CALENDAR_COLORS = {
|
||||||
|
// 主色
|
||||||
|
gold: {
|
||||||
|
primary: '#D4AF37',
|
||||||
|
secondary: '#B8960C',
|
||||||
|
gradient: 'linear-gradient(135deg, #D4AF37 0%, #F5E6A3 100%)',
|
||||||
|
},
|
||||||
|
// 背景色
|
||||||
|
bg: {
|
||||||
|
deep: '#0A0A14',
|
||||||
|
primary: '#0F0F1A',
|
||||||
|
elevated: '#1A1A2E',
|
||||||
|
surface: '#252540',
|
||||||
|
},
|
||||||
|
// 边框色
|
||||||
|
border: {
|
||||||
|
subtle: 'rgba(212, 175, 55, 0.1)',
|
||||||
|
default: 'rgba(212, 175, 55, 0.2)',
|
||||||
|
emphasis: 'rgba(212, 175, 55, 0.4)',
|
||||||
|
},
|
||||||
|
// 文字色
|
||||||
|
text: {
|
||||||
|
primary: 'rgba(255, 255, 255, 0.95)',
|
||||||
|
secondary: 'rgba(255, 255, 255, 0.6)',
|
||||||
|
muted: 'rgba(255, 255, 255, 0.4)',
|
||||||
|
},
|
||||||
|
// 事件类型颜色
|
||||||
|
events: {
|
||||||
|
news: '#9F7AEA', // 紫色 - 新闻
|
||||||
|
report: '#805AD5', // 深紫 - 研报
|
||||||
|
plan: '#D4AF37', // 金色 - 计划
|
||||||
|
review: '#10B981', // 绿色 - 复盘
|
||||||
|
system: '#3B82F6', // 蓝色 - 系统事件
|
||||||
|
priceUp: '#FC8181', // 红色 - 上涨
|
||||||
|
priceDown: '#68D391', // 绿色 - 下跌
|
||||||
|
},
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ant Design Calendar 黑金主题配置
|
||||||
|
*/
|
||||||
|
export const CALENDAR_THEME: ThemeConfig = {
|
||||||
|
token: {
|
||||||
|
// 基础色
|
||||||
|
colorBgContainer: 'transparent',
|
||||||
|
colorBgElevated: CALENDAR_COLORS.bg.elevated,
|
||||||
|
colorText: CALENDAR_COLORS.text.primary,
|
||||||
|
colorTextSecondary: CALENDAR_COLORS.text.secondary,
|
||||||
|
colorTextTertiary: CALENDAR_COLORS.text.muted,
|
||||||
|
colorTextHeading: CALENDAR_COLORS.gold.primary,
|
||||||
|
|
||||||
|
// 边框
|
||||||
|
colorBorder: CALENDAR_COLORS.border.default,
|
||||||
|
colorBorderSecondary: CALENDAR_COLORS.border.subtle,
|
||||||
|
|
||||||
|
// 主色
|
||||||
|
colorPrimary: CALENDAR_COLORS.gold.primary,
|
||||||
|
colorPrimaryHover: CALENDAR_COLORS.gold.secondary,
|
||||||
|
colorPrimaryActive: CALENDAR_COLORS.gold.secondary,
|
||||||
|
|
||||||
|
// 链接色
|
||||||
|
colorLink: CALENDAR_COLORS.gold.primary,
|
||||||
|
colorLinkHover: CALENDAR_COLORS.gold.secondary,
|
||||||
|
|
||||||
|
// 圆角
|
||||||
|
borderRadius: 8,
|
||||||
|
borderRadiusLG: 12,
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
Calendar: {
|
||||||
|
// 日历整体背景
|
||||||
|
fullBg: 'transparent',
|
||||||
|
fullPanelBg: 'transparent',
|
||||||
|
|
||||||
|
// 选中项背景
|
||||||
|
itemActiveBg: 'rgba(212, 175, 55, 0.15)',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 日历样式常量(用于内联样式或 CSS-in-JS)
|
||||||
|
*/
|
||||||
|
export const CALENDAR_STYLES = {
|
||||||
|
// 今天高亮
|
||||||
|
today: {
|
||||||
|
bg: 'rgba(212, 175, 55, 0.1)',
|
||||||
|
border: `2px solid ${CALENDAR_COLORS.gold.primary}`,
|
||||||
|
},
|
||||||
|
// 日期单元格
|
||||||
|
cell: {
|
||||||
|
minHeight: '85px',
|
||||||
|
padding: '4px',
|
||||||
|
},
|
||||||
|
// 工具栏
|
||||||
|
toolbar: {
|
||||||
|
buttonBg: CALENDAR_COLORS.gold.primary,
|
||||||
|
buttonColor: CALENDAR_COLORS.bg.deep,
|
||||||
|
buttonHoverBg: CALENDAR_COLORS.gold.secondary,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default CALENDAR_THEME;
|
||||||
Reference in New Issue
Block a user