feat(theme): 重构主题系统,新增 glass-pill 按钮样式
- ThemeConfig 接口扩展至 60+ 语义化属性 - 新增深浅主题预设 (glassPill overrides) - button-group 支持 glass-pill 样式变体 - 默认主题改为浅色 - 移除 toolbar 容器硬编码定位 - 统一组件 CSS 变量命名规范 - 暂时隐藏下拉箭头
This commit is contained in:
@@ -1,51 +1,237 @@
|
||||
import { ThemeConfig } from './types';
|
||||
|
||||
/**
|
||||
* 深色主题 (默认)
|
||||
* Tailwind CSS Color Palette Reference (for maintainers)
|
||||
*
|
||||
* Slate: #f8fafc #f1f5f9 #e2e8f0 #cbd5e1 #94a3b8 #64748b #475569 #334155 #1e293b #0f172a
|
||||
* Blue: #eff6ff #dbeafe #bfdbfe #93c5fd #60a5fa #3b82f6 #2563eb #1d4ed8 #1e40af #1e3a8a
|
||||
* Green: #f0fdf4 #dcfce7 #bbf7d0 #86efac #4ade80 #22c55e #16a34a #15803d #166534 #14532d
|
||||
* Amber: #fffbeb #fef3c7 #fde68a #fcd34d #fbbf24 #f59e0b #d97706 #b45309 #92400e #78350f
|
||||
* Red: #fef2f2 #fee2e2 #fecaca #fca5a5 #f87171 #ef4444 #dc2626 #b91c1c #991b1b #7f1d1d
|
||||
* Cyan: #ecfeff #cffafe #a5f3fc #67e8f9 #22d3ee #06b6d4 #0891b2 #0e7490 #155e75 #164e63
|
||||
*/
|
||||
export const darkTheme: ThemeConfig = {
|
||||
name: 'dark',
|
||||
primary: '#0078d4',
|
||||
primaryHover: '#0063b1',
|
||||
|
||||
// 修改:背景色统一为浅灰,不再跟随深色模式变黑
|
||||
background: '#f5f5f5',
|
||||
panelBackground: 'rgba(30, 30, 30, 0.9)',
|
||||
|
||||
textPrimary: '#ffffff',
|
||||
textSecondary: '#cccccc',
|
||||
|
||||
border: '#444444',
|
||||
|
||||
icon: '#cccccc',
|
||||
iconActive: '#ffffff',
|
||||
|
||||
componentBackground: 'transparent',
|
||||
componentHover: '#4e4d4dff',
|
||||
componentActive: 'rgba(255, 255, 255, 0.1)'
|
||||
};
|
||||
|
||||
/**
|
||||
* 浅色主题
|
||||
*/
|
||||
export const lightTheme: ThemeConfig = {
|
||||
name: 'light',
|
||||
primary: '#0078d4',
|
||||
primaryHover: '#106ebe',
|
||||
|
||||
// 统一为浅灰
|
||||
background: '#f5f5f5',
|
||||
panelBackground: '#ffffff',
|
||||
primary: '#2563eb',
|
||||
primaryHover: '#1d4ed8',
|
||||
primaryActive: '#1e40af',
|
||||
primarySubtle: 'rgba(37, 99, 235, 0.1)',
|
||||
|
||||
textPrimary: '#333333',
|
||||
textSecondary: '#666666',
|
||||
success: '#16a34a',
|
||||
successHover: '#15803d',
|
||||
successSubtle: 'rgba(22, 163, 74, 0.1)',
|
||||
|
||||
border: '#e0e0e0',
|
||||
warning: '#d97706',
|
||||
warningHover: '#b45309',
|
||||
warningSubtle: 'rgba(217, 119, 6, 0.1)',
|
||||
|
||||
icon: '#555555',
|
||||
iconActive: '#0078d4',
|
||||
danger: '#dc2626',
|
||||
dangerHover: '#b91c1c',
|
||||
dangerSubtle: 'rgba(220, 38, 38, 0.1)',
|
||||
|
||||
componentBackground: 'transparent',
|
||||
componentHover: '#f0f0f0',
|
||||
componentActive: '#e0e0e0'
|
||||
};
|
||||
info: '#0891b2',
|
||||
infoHover: '#0e7490',
|
||||
infoSubtle: 'rgba(8, 145, 178, 0.1)',
|
||||
|
||||
bgBase: '#f8fafc',
|
||||
bgElevated: '#ffffff',
|
||||
bgOverlay: 'rgba(255, 255, 255, 0.98)',
|
||||
bgInset: '#f1f5f9',
|
||||
bgGlass: 'rgba(255, 255, 255, 0.8)',
|
||||
bgGlassBlur: '24px',
|
||||
|
||||
textPrimary: '#0f172a',
|
||||
textSecondary: '#475569',
|
||||
textTertiary: '#94a3b8',
|
||||
textDisabled: '#cbd5e1',
|
||||
textInverse: '#ffffff',
|
||||
textLink: '#2563eb',
|
||||
textLinkHover: '#1d4ed8',
|
||||
|
||||
iconDefault: '#64748b',
|
||||
iconHover: '#334155',
|
||||
iconActive: '#2563eb',
|
||||
iconDisabled: '#cbd5e1',
|
||||
iconInverse: '#ffffff',
|
||||
|
||||
borderDefault: '#e2e8f0',
|
||||
borderSubtle: '#f1f5f9',
|
||||
borderStrong: '#cbd5e1',
|
||||
borderDisabled: '#f1f5f9',
|
||||
divider: '#e2e8f0',
|
||||
|
||||
componentBg: 'transparent',
|
||||
componentBgHover: 'rgba(15, 23, 42, 0.04)',
|
||||
componentBgActive: 'rgba(15, 23, 42, 0.08)',
|
||||
componentBgSelected: 'rgba(37, 99, 235, 0.08)',
|
||||
componentBgDisabled: '#f8fafc',
|
||||
|
||||
focusRing: 'rgba(37, 99, 235, 0.5)',
|
||||
focusRingOffset: '#ffffff',
|
||||
selectionBg: 'rgba(37, 99, 235, 0.15)',
|
||||
selectionText: '#0f172a',
|
||||
|
||||
shadowSm: '0 2px 8px rgba(0, 0, 0, 0.1), 0 4px 12px rgba(0, 0, 0, 0.08)',
|
||||
shadowMd: '0 4px 12px rgba(0, 0, 0, 0.12), 0 6px 20px rgba(0, 0, 0, 0.1)',
|
||||
shadowLg: '0 10px 25px rgba(0, 0, 0, 0.15), 0 6px 10px rgba(0, 0, 0, 0.1)',
|
||||
shadowXl: '0 20px 40px rgba(0, 0, 0, 0.2), 0 10px 15px rgba(0, 0, 0, 0.1)',
|
||||
shadowGlow: '0 2px 8px rgba(59, 130, 246, 0.3), 0 4px 16px rgba(59, 130, 246, 0.2)',
|
||||
|
||||
scrollbarTrack: '#f1f5f9',
|
||||
scrollbarThumb: '#cbd5e1',
|
||||
scrollbarThumbHover: '#94a3b8',
|
||||
|
||||
overrides: {
|
||||
dialog: {
|
||||
headerBg: '#f8fafc',
|
||||
},
|
||||
toolbar: {
|
||||
bg: 'rgba(255, 255, 255, 0.9)',
|
||||
buttonBg: 'rgba(255, 255, 255, 0.95)',
|
||||
buttonBgHover: '#ffffff',
|
||||
buttonBgActive: '#2563eb',
|
||||
},
|
||||
glassPill: {
|
||||
sectionBg: 'rgba(255, 255, 255, 0.8)',
|
||||
sectionBorder: 'rgba(226, 232, 240, 0.5)',
|
||||
sectionShadow: '0 4px 24px rgba(0, 0, 0, 0.06)',
|
||||
btnBg: 'rgba(255, 255, 255, 0.9)',
|
||||
btnBorder: 'rgba(203, 213, 225, 0.6)',
|
||||
btnShadow: '0 2px 8px rgba(0, 0, 0, 0.1), 0 4px 12px rgba(0, 0, 0, 0.08)',
|
||||
btnBgHover: '#ffffff',
|
||||
btnShadowHover: '0 4px 12px rgba(0, 0, 0, 0.12), 0 6px 20px rgba(0, 0, 0, 0.1)',
|
||||
iconColor: '#334155',
|
||||
iconColorHover: '#1e293b',
|
||||
},
|
||||
input: {
|
||||
bg: '#ffffff',
|
||||
bgFocus: '#ffffff',
|
||||
placeholder: '#94a3b8',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export const darkTheme: ThemeConfig = {
|
||||
name: 'dark',
|
||||
|
||||
primary: '#3b82f6',
|
||||
primaryHover: '#60a5fa',
|
||||
primaryActive: '#2563eb',
|
||||
primarySubtle: 'rgba(59, 130, 246, 0.15)',
|
||||
|
||||
success: '#22c55e',
|
||||
successHover: '#4ade80',
|
||||
successSubtle: 'rgba(34, 197, 94, 0.15)',
|
||||
|
||||
warning: '#f59e0b',
|
||||
warningHover: '#fbbf24',
|
||||
warningSubtle: 'rgba(245, 158, 11, 0.15)',
|
||||
|
||||
danger: '#ef4444',
|
||||
dangerHover: '#f87171',
|
||||
dangerSubtle: 'rgba(239, 68, 68, 0.15)',
|
||||
|
||||
info: '#06b6d4',
|
||||
infoHover: '#22d3ee',
|
||||
infoSubtle: 'rgba(6, 182, 212, 0.15)',
|
||||
|
||||
bgBase: '#152232',
|
||||
bgElevated: '#1f2d3e',
|
||||
bgOverlay: 'rgba(21, 34, 50, 0.98)',
|
||||
bgInset: '#152232',
|
||||
bgGlass: 'rgba(21, 34, 50, 0.85)',
|
||||
bgGlassBlur: '24px',
|
||||
|
||||
textPrimary: '#ffffff',
|
||||
textSecondary: '#94a3b8',
|
||||
textTertiary: '#64748b',
|
||||
textDisabled: '#475569',
|
||||
textInverse: '#152232',
|
||||
textLink: '#60a5fa',
|
||||
textLinkHover: '#93c5fd',
|
||||
|
||||
iconDefault: '#ffffff',
|
||||
iconHover: '#ffffff',
|
||||
iconActive: '#3b82f6',
|
||||
iconDisabled: '#475569',
|
||||
iconInverse: '#152232',
|
||||
|
||||
borderDefault: 'rgba(51, 65, 85, 0.5)',
|
||||
borderSubtle: 'rgba(51, 65, 85, 0.5)',
|
||||
borderStrong: '#475569',
|
||||
borderDisabled: '#1e293b',
|
||||
divider: '#334155',
|
||||
|
||||
componentBg: 'transparent',
|
||||
componentBgHover: 'rgba(248, 250, 252, 0.06)',
|
||||
componentBgActive: 'rgba(248, 250, 252, 0.1)',
|
||||
componentBgSelected: 'rgba(59, 130, 246, 0.2)',
|
||||
componentBgDisabled: '#1e293b',
|
||||
|
||||
focusRing: 'rgba(59, 130, 246, 0.5)',
|
||||
focusRingOffset: '#1e293b',
|
||||
selectionBg: 'rgba(59, 130, 246, 0.3)',
|
||||
selectionText: '#f8fafc',
|
||||
|
||||
shadowSm: '0 2px 8px rgba(0, 0, 0, 0.4), 0 4px 12px rgba(0, 0, 0, 0.3)',
|
||||
shadowMd: '0 4px 12px rgba(0, 0, 0, 0.5), 0 6px 20px rgba(0, 0, 0, 0.4)',
|
||||
shadowLg: '0 10px 25px rgba(0, 0, 0, 0.6), 0 6px 10px rgba(0, 0, 0, 0.4)',
|
||||
shadowXl: '0 20px 40px rgba(0, 0, 0, 0.7), 0 10px 15px rgba(0, 0, 0, 0.5)',
|
||||
shadowGlow: '0 2px 8px rgba(59, 130, 246, 0.4), 0 4px 16px rgba(59, 130, 246, 0.25)',
|
||||
|
||||
scrollbarTrack: '#1e293b',
|
||||
scrollbarThumb: '#475569',
|
||||
scrollbarThumbHover: '#64748b',
|
||||
|
||||
overrides: {
|
||||
dialog: {
|
||||
headerBg: '#0f172a',
|
||||
},
|
||||
toolbar: {
|
||||
bg: 'rgba(30, 41, 59, 0.9)',
|
||||
buttonBg: 'rgba(51, 65, 85, 0.6)',
|
||||
buttonBgHover: 'rgba(71, 85, 105, 0.7)',
|
||||
buttonBgActive: '#3b82f6',
|
||||
},
|
||||
glassPill: {
|
||||
sectionBg: 'rgba(30, 41, 59, 0.8)',
|
||||
sectionBorder: 'rgba(51, 65, 85, 0.5)',
|
||||
sectionShadow: '0 4px 24px rgba(0, 0, 0, 0.15)',
|
||||
btnBg: 'rgba(51, 65, 85, 0.5)',
|
||||
btnBorder: 'rgba(71, 85, 105, 0.4)',
|
||||
btnShadow: '0 2px 8px rgba(0, 0, 0, 0.25), 0 4px 12px rgba(0, 0, 0, 0.2)',
|
||||
btnBgHover: 'rgba(71, 85, 105, 0.6)',
|
||||
btnShadowHover: '0 4px 12px rgba(0, 0, 0, 0.3), 0 6px 20px rgba(0, 0, 0, 0.25)',
|
||||
iconColor: '#e2e8f0',
|
||||
iconColorHover: '#f8fafc',
|
||||
},
|
||||
input: {
|
||||
bg: '#0f172a',
|
||||
bgFocus: '#1e293b',
|
||||
placeholder: '#64748b',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export function createThemeFromPartial(base: ThemeConfig, partial: Partial<ThemeConfig>): ThemeConfig {
|
||||
return {
|
||||
...base,
|
||||
...partial,
|
||||
overrides: {
|
||||
...base.overrides,
|
||||
...partial.overrides,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export function getThemeByName(name: string): ThemeConfig {
|
||||
switch (name) {
|
||||
case 'light':
|
||||
return lightTheme;
|
||||
case 'dark':
|
||||
default:
|
||||
return darkTheme;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,43 +1,407 @@
|
||||
/**
|
||||
* 全局主题配置接口
|
||||
* 定义系统通用的语义化颜色
|
||||
* BIM Engine SDK - Unified Theme System
|
||||
*
|
||||
* Design Principles:
|
||||
* 1. Semantic naming - colors describe PURPOSE, not appearance
|
||||
* 2. Hierarchical structure - organized by category for scalability
|
||||
* 3. Complete coverage - all UI states and component needs
|
||||
* 4. Accessibility - ensures proper contrast ratios
|
||||
* 5. Glassmorphism support - includes transparency and blur values
|
||||
*
|
||||
* Color Palette Reference: Tailwind CSS (slate, blue, red, green, amber)
|
||||
*/
|
||||
|
||||
// ============================================================================
|
||||
// Color Primitives (for reference, not exported directly)
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* Semantic Color Token
|
||||
* Represents a single color value with optional transparency
|
||||
*/
|
||||
type ColorToken = string;
|
||||
|
||||
/**
|
||||
* Shadow Token
|
||||
* CSS box-shadow value
|
||||
*/
|
||||
type ShadowToken = string;
|
||||
|
||||
/**
|
||||
* Blur Token
|
||||
* CSS backdrop-filter blur value (e.g., '24px')
|
||||
*/
|
||||
type BlurToken = string;
|
||||
|
||||
// ============================================================================
|
||||
// Theme Configuration Interface
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* Complete Theme Configuration Interface
|
||||
*
|
||||
* All colors use semantic naming to describe their purpose.
|
||||
* Components should map these to their internal CSS variables.
|
||||
*/
|
||||
export interface ThemeConfig {
|
||||
/** 主题名称 */
|
||||
// =========================================================================
|
||||
// Meta
|
||||
// =========================================================================
|
||||
|
||||
/** Theme identifier: 'dark' | 'light' | custom name */
|
||||
name: string;
|
||||
|
||||
/** 品牌色/主色 */
|
||||
primary: string;
|
||||
/** 主色悬停/激活态 */
|
||||
primaryHover: string;
|
||||
|
||||
/** 基础背景色 (应用整体背景) */
|
||||
background: string;
|
||||
/** 面板背景色 (工具栏、弹窗背景) */
|
||||
panelBackground: string;
|
||||
// =========================================================================
|
||||
// Brand / Primary Colors
|
||||
// =========================================================================
|
||||
|
||||
/** 主要文字颜色 */
|
||||
textPrimary: string;
|
||||
/** 次要文字颜色 */
|
||||
textSecondary: string;
|
||||
/** Primary brand color - used for key actions, links, active states */
|
||||
primary: ColorToken;
|
||||
/** Primary color on hover */
|
||||
primaryHover: ColorToken;
|
||||
/** Primary color when pressed/active */
|
||||
primaryActive: ColorToken;
|
||||
/** Subtle primary for backgrounds (e.g., selected row) */
|
||||
primarySubtle: ColorToken;
|
||||
|
||||
// =========================================================================
|
||||
// Status / Semantic Colors
|
||||
// =========================================================================
|
||||
|
||||
/** 边框/分割线颜色 */
|
||||
border: string;
|
||||
/** Success color - confirmations, completed states */
|
||||
success: ColorToken;
|
||||
/** Success color on hover */
|
||||
successHover: ColorToken;
|
||||
/** Subtle success for backgrounds */
|
||||
successSubtle: ColorToken;
|
||||
|
||||
/** Warning color - caution, pending states */
|
||||
warning: ColorToken;
|
||||
/** Warning color on hover */
|
||||
warningHover: ColorToken;
|
||||
/** Subtle warning for backgrounds */
|
||||
warningSubtle: ColorToken;
|
||||
|
||||
/** Danger/Error color - destructive actions, errors */
|
||||
danger: ColorToken;
|
||||
/** Danger color on hover */
|
||||
dangerHover: ColorToken;
|
||||
/** Subtle danger for backgrounds */
|
||||
dangerSubtle: ColorToken;
|
||||
|
||||
/** Info color - informational states */
|
||||
info: ColorToken;
|
||||
/** Info color on hover */
|
||||
infoHover: ColorToken;
|
||||
/** Subtle info for backgrounds */
|
||||
infoSubtle: ColorToken;
|
||||
|
||||
// =========================================================================
|
||||
// Background Colors (Layered System)
|
||||
// =========================================================================
|
||||
|
||||
/** 图标默认颜色 */
|
||||
icon: string;
|
||||
/** 图标激活颜色 */
|
||||
iconActive: string;
|
||||
/** Base/canvas background - the deepest layer (app background) */
|
||||
bgBase: ColorToken;
|
||||
/** Elevated surface - panels, cards, dialogs floating above base */
|
||||
bgElevated: ColorToken;
|
||||
/** Overlay background - modals, dropdowns, popovers */
|
||||
bgOverlay: ColorToken;
|
||||
/** Inset/recessed background - inputs, wells, sunken areas */
|
||||
bgInset: ColorToken;
|
||||
|
||||
/** 交互组件背景 (如按钮默认背景) */
|
||||
componentBackground: string;
|
||||
/** 交互组件悬停背景 */
|
||||
componentHover: string;
|
||||
/** 交互组件激活背景 */
|
||||
componentActive: string;
|
||||
/**
|
||||
* Glassmorphism surface - semi-transparent with blur
|
||||
* Used for floating toolbars, modern panels
|
||||
*/
|
||||
bgGlass: ColorToken;
|
||||
/** Glassmorphism blur amount */
|
||||
bgGlassBlur: BlurToken;
|
||||
|
||||
// =========================================================================
|
||||
// Text Colors
|
||||
// =========================================================================
|
||||
|
||||
/** Primary text - headings, body text, high emphasis */
|
||||
textPrimary: ColorToken;
|
||||
/** Secondary text - descriptions, labels, medium emphasis */
|
||||
textSecondary: ColorToken;
|
||||
/** Tertiary text - placeholders, hints, low emphasis */
|
||||
textTertiary: ColorToken;
|
||||
/** Disabled text - inactive elements */
|
||||
textDisabled: ColorToken;
|
||||
/** Inverted text - text on primary/dark backgrounds */
|
||||
textInverse: ColorToken;
|
||||
/** Link text color */
|
||||
textLink: ColorToken;
|
||||
/** Link text on hover */
|
||||
textLinkHover: ColorToken;
|
||||
|
||||
// =========================================================================
|
||||
// Icon Colors
|
||||
// =========================================================================
|
||||
|
||||
/** Default icon color */
|
||||
iconDefault: ColorToken;
|
||||
/** Icon on hover */
|
||||
iconHover: ColorToken;
|
||||
/** Active/selected icon */
|
||||
iconActive: ColorToken;
|
||||
/** Disabled icon */
|
||||
iconDisabled: ColorToken;
|
||||
/** Inverted icon (on colored backgrounds) */
|
||||
iconInverse: ColorToken;
|
||||
|
||||
// =========================================================================
|
||||
// Border / Divider Colors
|
||||
// =========================================================================
|
||||
|
||||
/** Default border - inputs, cards, containers */
|
||||
borderDefault: ColorToken;
|
||||
/** Subtle border - dividers, separators */
|
||||
borderSubtle: ColorToken;
|
||||
/** Strong border - focus rings, emphasis */
|
||||
borderStrong: ColorToken;
|
||||
/** Disabled border */
|
||||
borderDisabled: ColorToken;
|
||||
|
||||
/** Divider color - horizontal/vertical separators */
|
||||
divider: ColorToken;
|
||||
|
||||
// =========================================================================
|
||||
// Interactive Component States
|
||||
// =========================================================================
|
||||
|
||||
/**
|
||||
* Component Background States
|
||||
* Used for buttons, list items, interactive elements
|
||||
*/
|
||||
|
||||
/** Default component background (often transparent) */
|
||||
componentBg: ColorToken;
|
||||
/** Component background on hover */
|
||||
componentBgHover: ColorToken;
|
||||
/** Component background when pressed */
|
||||
componentBgActive: ColorToken;
|
||||
/** Component background when selected */
|
||||
componentBgSelected: ColorToken;
|
||||
/** Disabled component background */
|
||||
componentBgDisabled: ColorToken;
|
||||
|
||||
// =========================================================================
|
||||
// Focus / Selection States
|
||||
// =========================================================================
|
||||
|
||||
/** Focus ring color */
|
||||
focusRing: ColorToken;
|
||||
/** Focus ring offset color (for contrast) */
|
||||
focusRingOffset: ColorToken;
|
||||
|
||||
/** Selection background (text selection, highlighted items) */
|
||||
selectionBg: ColorToken;
|
||||
/** Selection text color */
|
||||
selectionText: ColorToken;
|
||||
|
||||
// =========================================================================
|
||||
// Shadows
|
||||
// =========================================================================
|
||||
|
||||
/** Small shadow - subtle elevation (buttons, small cards) */
|
||||
shadowSm: ShadowToken;
|
||||
/** Medium shadow - moderate elevation (dropdowns, popovers) */
|
||||
shadowMd: ShadowToken;
|
||||
/** Large shadow - high elevation (modals, dialogs) */
|
||||
shadowLg: ShadowToken;
|
||||
/** Extra large shadow - maximum elevation */
|
||||
shadowXl: ShadowToken;
|
||||
|
||||
/** Glow shadow for active/highlighted elements */
|
||||
shadowGlow: ShadowToken;
|
||||
|
||||
// =========================================================================
|
||||
// Scrollbar Colors
|
||||
// =========================================================================
|
||||
|
||||
/** Scrollbar track background */
|
||||
scrollbarTrack: ColorToken;
|
||||
/** Scrollbar thumb */
|
||||
scrollbarThumb: ColorToken;
|
||||
/** Scrollbar thumb on hover */
|
||||
scrollbarThumbHover: ColorToken;
|
||||
|
||||
// =========================================================================
|
||||
// Specific Component Overrides (Optional)
|
||||
// These allow fine-grained control when semantic tokens aren't enough
|
||||
// =========================================================================
|
||||
|
||||
/**
|
||||
* Component-specific overrides
|
||||
* Only define these when absolutely necessary
|
||||
*/
|
||||
overrides?: {
|
||||
/** Dialog specific colors */
|
||||
dialog?: {
|
||||
headerBg?: ColorToken;
|
||||
footerBg?: ColorToken;
|
||||
};
|
||||
/** Toolbar specific colors */
|
||||
toolbar?: {
|
||||
bg?: ColorToken;
|
||||
buttonBg?: ColorToken;
|
||||
buttonBgHover?: ColorToken;
|
||||
buttonBgActive?: ColorToken;
|
||||
};
|
||||
/** Input specific colors */
|
||||
input?: {
|
||||
bg?: ColorToken;
|
||||
bgFocus?: ColorToken;
|
||||
placeholder?: ColorToken;
|
||||
};
|
||||
/** Glass-pill button group specific colors */
|
||||
glassPill?: {
|
||||
sectionBg?: ColorToken;
|
||||
sectionBorder?: ColorToken;
|
||||
sectionShadow?: ShadowToken;
|
||||
btnBg?: ColorToken;
|
||||
btnBorder?: ColorToken;
|
||||
btnShadow?: ShadowToken;
|
||||
btnBgHover?: ColorToken;
|
||||
btnShadowHover?: ShadowToken;
|
||||
iconColor?: ColorToken;
|
||||
iconColorHover?: ColorToken;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 主题类型定义
|
||||
* Partial theme config for customization
|
||||
* Allows users to override only specific tokens
|
||||
*/
|
||||
export type PartialThemeConfig = Partial<ThemeConfig> & { name: string };
|
||||
|
||||
/**
|
||||
* Theme type definition
|
||||
*/
|
||||
export type ThemeType = 'dark' | 'light' | 'custom';
|
||||
|
||||
// ============================================================================
|
||||
// CSS Variable Mapping
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* CSS Variable Name Mapping
|
||||
*
|
||||
* All CSS variables follow the pattern: --bim-{category}-{property}
|
||||
*
|
||||
* Categories:
|
||||
* - primary, success, warning, danger, info (semantic colors)
|
||||
* - bg (backgrounds)
|
||||
* - text (typography)
|
||||
* - icon (iconography)
|
||||
* - border (borders)
|
||||
* - component (interactive states)
|
||||
* - shadow (elevation)
|
||||
* - focus (focus states)
|
||||
* - scrollbar (scrollbar styling)
|
||||
*/
|
||||
export const CSS_VAR_MAP: Record<keyof Omit<ThemeConfig, 'name' | 'overrides'>, string> = {
|
||||
// Primary
|
||||
primary: '--bim-primary',
|
||||
primaryHover: '--bim-primary-hover',
|
||||
primaryActive: '--bim-primary-active',
|
||||
primarySubtle: '--bim-primary-subtle',
|
||||
|
||||
// Success
|
||||
success: '--bim-success',
|
||||
successHover: '--bim-success-hover',
|
||||
successSubtle: '--bim-success-subtle',
|
||||
|
||||
// Warning
|
||||
warning: '--bim-warning',
|
||||
warningHover: '--bim-warning-hover',
|
||||
warningSubtle: '--bim-warning-subtle',
|
||||
|
||||
// Danger
|
||||
danger: '--bim-danger',
|
||||
dangerHover: '--bim-danger-hover',
|
||||
dangerSubtle: '--bim-danger-subtle',
|
||||
|
||||
// Info
|
||||
info: '--bim-info',
|
||||
infoHover: '--bim-info-hover',
|
||||
infoSubtle: '--bim-info-subtle',
|
||||
|
||||
// Backgrounds
|
||||
bgBase: '--bim-bg-base',
|
||||
bgElevated: '--bim-bg-elevated',
|
||||
bgOverlay: '--bim-bg-overlay',
|
||||
bgInset: '--bim-bg-inset',
|
||||
bgGlass: '--bim-bg-glass',
|
||||
bgGlassBlur: '--bim-bg-glass-blur',
|
||||
|
||||
// Text
|
||||
textPrimary: '--bim-text-primary',
|
||||
textSecondary: '--bim-text-secondary',
|
||||
textTertiary: '--bim-text-tertiary',
|
||||
textDisabled: '--bim-text-disabled',
|
||||
textInverse: '--bim-text-inverse',
|
||||
textLink: '--bim-text-link',
|
||||
textLinkHover: '--bim-text-link-hover',
|
||||
|
||||
// Icons
|
||||
iconDefault: '--bim-icon-default',
|
||||
iconHover: '--bim-icon-hover',
|
||||
iconActive: '--bim-icon-active',
|
||||
iconDisabled: '--bim-icon-disabled',
|
||||
iconInverse: '--bim-icon-inverse',
|
||||
|
||||
// Borders
|
||||
borderDefault: '--bim-border-default',
|
||||
borderSubtle: '--bim-border-subtle',
|
||||
borderStrong: '--bim-border-strong',
|
||||
borderDisabled: '--bim-border-disabled',
|
||||
divider: '--bim-divider',
|
||||
|
||||
// Components
|
||||
componentBg: '--bim-component-bg',
|
||||
componentBgHover: '--bim-component-bg-hover',
|
||||
componentBgActive: '--bim-component-bg-active',
|
||||
componentBgSelected: '--bim-component-bg-selected',
|
||||
componentBgDisabled: '--bim-component-bg-disabled',
|
||||
|
||||
// Focus
|
||||
focusRing: '--bim-focus-ring',
|
||||
focusRingOffset: '--bim-focus-ring-offset',
|
||||
selectionBg: '--bim-selection-bg',
|
||||
selectionText: '--bim-selection-text',
|
||||
|
||||
// Shadows
|
||||
shadowSm: '--bim-shadow-sm',
|
||||
shadowMd: '--bim-shadow-md',
|
||||
shadowLg: '--bim-shadow-lg',
|
||||
shadowXl: '--bim-shadow-xl',
|
||||
shadowGlow: '--bim-shadow-glow',
|
||||
|
||||
// Scrollbar
|
||||
scrollbarTrack: '--bim-scrollbar-track',
|
||||
scrollbarThumb: '--bim-scrollbar-thumb',
|
||||
scrollbarThumbHover: '--bim-scrollbar-thumb-hover',
|
||||
};
|
||||
|
||||
// ============================================================================
|
||||
// Legacy Compatibility Mapping
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* Maps old ThemeConfig properties to new ones
|
||||
* Used for backward compatibility during migration
|
||||
*/
|
||||
export interface LegacyThemeMapping {
|
||||
/** Old property name -> New property name */
|
||||
background: 'bgBase';
|
||||
panelBackground: 'bgElevated';
|
||||
border: 'borderDefault';
|
||||
icon: 'iconDefault';
|
||||
componentBackground: 'componentBg';
|
||||
componentHover: 'componentBgHover';
|
||||
componentActive: 'componentBgActive';
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user