import type { ThemeConfig } from "antd"; import { theme as antdTheme } from "antd"; // 主操作、普通选择和开关是不同交互语义,必须各自维护成对的背景/前景色。 const controlTheme = { light: { solidBg: "#171717", solidHoverBg: "#303030", solidActiveBg: "#404040", solidFg: "#ffffff", checkBg: "#171717", checkHoverBg: "#303030", checkActiveBg: "#404040", checkFg: "#ffffff", switchCheckedBg: "#171717", switchCheckedHoverBg: "#303030", switchCheckedHandle: "#ffffff", selectedBg: "rgba(17, 17, 17, 0.09)", selectedHoverBg: "rgba(17, 17, 17, 0.13)", selectedActiveBg: "rgba(17, 17, 17, 0.16)", selectedFg: "#171717", controlSurface: "#ffffff", controlBorder: "rgba(17, 17, 17, 0.18)", controlDisabledBg: "rgba(17, 17, 17, 0.05)", controlDisabledFg: "rgba(17, 17, 17, 0.36)", controlFocus: "rgba(17, 17, 17, 0.24)", switchOffBg: "rgba(17, 17, 17, 0.22)", switchOffHoverBg: "rgba(17, 17, 17, 0.3)", switchOffHandle: "#ffffff", menuBg: "#f5f5f5", menuText: "#171717", selectActiveBg: "rgba(17, 17, 17, 0.035)", selectSelectedBg: "rgba(17, 17, 17, 0.065)", selectText: "#171717", tableSelectedBg: "rgba(17, 17, 17, 0.05)", tableSelectedHoverBg: "rgba(17, 17, 17, 0.08)", }, dark: { solidBg: "#f5f5f5", solidHoverBg: "#ffffff", solidActiveBg: "#e5e5e5", solidFg: "#171717", checkBg: "#f5f5f5", checkHoverBg: "#ffffff", checkActiveBg: "#e5e5e5", checkFg: "#131313", switchCheckedBg: "#f5f5f5", switchCheckedHoverBg: "#ffffff", switchCheckedHandle: "#131313", selectedBg: "rgba(255, 255, 255, 0.12)", selectedHoverBg: "rgba(255, 255, 255, 0.16)", selectedActiveBg: "rgba(255, 255, 255, 0.2)", selectedFg: "#f5f5f5", controlSurface: "rgba(255, 255, 255, 0.035)", controlBorder: "rgba(255, 255, 255, 0.24)", controlDisabledBg: "rgba(255, 255, 255, 0.06)", controlDisabledFg: "rgba(255, 255, 255, 0.38)", controlFocus: "rgba(255, 255, 255, 0.24)", switchOffBg: "rgba(255, 255, 255, 0.22)", switchOffHoverBg: "rgba(255, 255, 255, 0.3)", switchOffHandle: "#f5f5f5", menuBg: "#262626", menuText: "#fafafa", selectActiveBg: "rgba(255, 255, 255, 0.055)", selectSelectedBg: "rgba(255, 255, 255, 0.09)", selectText: "#fafafa", tableSelectedBg: "rgba(255, 255, 255, 0.08)", tableSelectedHoverBg: "rgba(255, 255, 255, 0.12)", }, }; export function getAntThemeConfig(dark: boolean): ThemeConfig { const color = dark ? controlTheme.dark : controlTheme.light; // 浮层背景必须不透明(0.96 会透出下层内容);与侧栏切换器等自定义浮层的实底背景保持一致 const elevatedBackground = dark ? "rgba(31, 31, 32, 1)" : "rgba(255, 255, 255, 1)"; const subtleBackground = dark ? "rgba(255, 255, 255, 0.055)" : "rgba(17, 17, 17, 0.035)"; const interactiveBorder = dark ? "rgba(255, 255, 255, 0.18)" : "rgba(17, 17, 17, 0.18)"; // 黑白主题使用边框表达焦点,避免输入控件周围出现蓝紫色光圈。 const focusShadow = "none"; return { algorithm: dark ? antdTheme.darkAlgorithm : antdTheme.defaultAlgorithm, cssVar: { key: dark ? "infinite-canvas-dark" : "infinite-canvas-light" }, token: { colorPrimary: color.solidBg, colorPrimaryHover: color.solidHoverBg, colorPrimaryActive: color.solidActiveBg, colorPrimaryBg: color.selectedBg, colorPrimaryBgHover: color.selectedHoverBg, colorInfo: color.solidBg, colorLink: color.solidBg, colorLinkHover: color.solidHoverBg, colorLinkActive: color.solidActiveBg, colorTextLightSolid: color.solidFg, colorBgElevated: elevatedBackground, colorBorderSecondary: dark ? "rgba(255, 255, 255, 0.1)" : "rgba(17, 17, 17, 0.09)", boxShadowSecondary: dark ? "0 24px 72px rgba(0, 0, 0, 0.48)" : "0 22px 64px rgba(15, 23, 42, 0.14)", borderRadius: 6, borderRadiusLG: 8, borderRadiusSM: 5, controlHeight: 36, controlHeightLG: 42, controlHeightSM: 30, fontSize: 13, fontSizeSM: 12, motionDurationFast: "0.12s", motionDurationMid: "0.18s", motionDurationSlow: "0.24s", }, components: { Button: { primaryShadow: "none", fontWeight: 500, paddingInline: 14, paddingInlineLG: 16, paddingInlineSM: 10, colorPrimary: color.solidBg, colorPrimaryHover: color.solidHoverBg, colorPrimaryActive: color.solidActiveBg, primaryColor: color.solidFg, defaultBg: "transparent", defaultColor: color.selectedFg, defaultBorderColor: color.controlBorder, defaultHoverBg: color.selectedBg, defaultHoverColor: color.selectedFg, defaultHoverBorderColor: color.controlBorder, defaultActiveBg: color.selectedHoverBg, defaultActiveColor: color.selectedFg, defaultActiveBorderColor: color.controlBorder, }, Input: { paddingInline: 11, activeBg: elevatedBackground, hoverBg: elevatedBackground, activeBorderColor: interactiveBorder, hoverBorderColor: interactiveBorder, activeShadow: focusShadow, }, InputNumber: { activeBg: elevatedBackground, hoverBg: elevatedBackground, activeBorderColor: interactiveBorder, hoverBorderColor: interactiveBorder, activeShadow: focusShadow, }, Switch: { handleBg: color.switchOffHandle, handleShadow: dark ? "0 1px 4px rgba(0, 0, 0, 0.42)" : "0 1px 2px rgba(0, 0, 0, 0.2)", colorPrimary: color.switchCheckedBg, colorPrimaryActive: color.switchCheckedBg, colorPrimaryHover: color.switchCheckedHoverBg, colorTextQuaternary: color.switchOffBg, colorTextTertiary: color.switchOffHoverBg, controlOutline: color.controlFocus, }, Checkbox: { colorBgContainer: color.controlSurface, colorBgContainerDisabled: color.controlDisabledBg, colorBorder: color.controlBorder, colorPrimary: color.checkBg, colorPrimaryActive: color.checkActiveBg, colorPrimaryHover: color.checkHoverBg, controlOutline: color.controlFocus, }, Radio: { radioSize: 16, dotSize: 6, buttonBg: color.controlSurface, buttonCheckedBg: color.selectedBg, buttonCheckedBgDisabled: color.controlDisabledBg, buttonCheckedColorDisabled: color.controlDisabledFg, buttonSolidCheckedColor: color.checkFg, buttonSolidCheckedActiveBg: color.checkActiveBg, buttonSolidCheckedBg: color.checkBg, buttonSolidCheckedHoverBg: color.checkHoverBg, colorBgContainer: color.controlSurface, colorBgContainerDisabled: color.controlDisabledBg, colorBorder: color.controlBorder, colorPrimary: color.checkBg, colorPrimaryActive: color.checkActiveBg, colorPrimaryHover: color.checkHoverBg, controlOutline: color.controlFocus, }, Menu: { itemActiveBg: color.menuBg, itemHoverBg: color.menuBg, itemSelectedBg: color.menuBg, itemSelectedColor: color.menuText, darkItemHoverBg: controlTheme.dark.menuBg, darkItemSelectedBg: controlTheme.dark.menuBg, darkItemSelectedColor: controlTheme.dark.menuText, }, Select: { selectorBg: elevatedBackground, optionHeight: 36, optionPadding: "8px 10px", multipleItemHeight: 24, activeBorderColor: interactiveBorder, hoverBorderColor: interactiveBorder, activeOutlineColor: "transparent", optionActiveBg: color.selectActiveBg, optionSelectedBg: color.selectSelectedBg, optionSelectedColor: color.selectText, }, Table: { headerBg: subtleBackground, headerColor: dark ? "rgba(250, 250, 250, 0.62)" : "rgba(23, 23, 23, 0.58)", headerBorderRadius: 0, rowHoverBg: dark ? "rgba(255, 255, 255, 0.035)" : "rgba(17, 17, 17, 0.025)", borderColor: dark ? "rgba(255, 255, 255, 0.08)" : "rgba(17, 17, 17, 0.075)", cellPaddingBlockMD: 13, cellPaddingInlineMD: 14, rowSelectedBg: color.tableSelectedBg, rowSelectedHoverBg: color.tableSelectedHoverBg, }, Pagination: { itemBg: "transparent", itemLinkBg: "transparent", itemActiveBg: color.solidBg, itemActiveColor: color.solidFg, itemActiveColorHover: color.solidFg, }, Segmented: { trackBg: subtleBackground, trackPadding: 3, itemColor: color.controlDisabledFg, itemHoverColor: color.selectedFg, itemHoverBg: color.selectedBg, itemActiveBg: color.selectedActiveBg, itemSelectedBg: color.selectedBg, itemSelectedColor: color.selectedFg, }, Modal: { headerBg: "transparent", contentBg: elevatedBackground, footerBg: "transparent", titleFontSize: 16, }, Form: { itemMarginBottom: 18, labelFontSize: 12, verticalLabelPadding: "0 0 6px", }, Dropdown: { paddingBlock: 6, }, Skeleton: { gradientFromColor: dark ? "rgba(255, 255, 255, 0.055)" : "rgba(15, 23, 42, 0.055)", gradientToColor: dark ? "rgba(255, 255, 255, 0.11)" : "rgba(15, 23, 42, 0.1)", }, Card: { headerBg: "transparent", headerFontSize: 15, bodyPadding: 18, }, }, }; } /** * 管理后台使用更高密度的控件节奏;只在 AdminShell 内挂载,避免改变创作端的视觉契约。 */ export function getAdminAntThemeConfig(dark: boolean): ThemeConfig { const base = getAntThemeConfig(dark); const mutedForeground = dark ? "rgba(250, 250, 250, 0.58)" : "rgba(23, 23, 23, 0.58)"; return { ...base, token: { ...base.token, borderRadius: 6, borderRadiusLG: 8, colorBgContainer: "var(--color-surface)", colorBorder: "var(--color-border)", fontFamily: "var(--font-sans)", padding: 12, paddingSM: 8, fontSize: 13, }, components: { ...base.components, Card: { ...base.components?.Card, boxShadow: "none", boxShadowTertiary: "none", }, Drawer: { ...base.components?.Drawer, colorBgElevated: "var(--color-surface)", }, Form: { ...base.components?.Form, itemMarginBottom: 16, }, Menu: { ...base.components?.Menu, itemHeight: 34, itemSelectedBg: "transparent", }, Table: { ...base.components?.Table, cellPaddingBlock: 8, cellPaddingBlockMD: 8, cellPaddingBlockSM: 6, cellPaddingInline: 12, cellPaddingInlineMD: 12, cellPaddingInlineSM: 8, headerBg: "transparent", headerColor: mutedForeground, headerSplitColor: "transparent", borderColor: "var(--color-border)", }, }, }; }