DirectSurface UIDirectSurface UI
开始使用
文档/API 参考

Theme API 参考

Theme API 负责颜色、字体、尺寸、组件状态和主题切换。业务系统应通过主题 token 调整视觉,而不是在每个组件里硬编码颜色。

主题对象

核心导出:

  • ThemeData
  • Color
  • ThemeMetricKey
  • ImGuiLightTheme
  • ImGuiDarkTheme
  • MedicalCompactLightTheme
  • ModernCompactLightTheme
  • DefaultFontFamily
  • DefaultMonoFontFamily
  • createTheme
  • freezeTheme
  • resolveThemeTypography / resolveThemeMotion / resolveThemeElevation
  • resolveThemeEditor / resolveThemeChart / resolveThemeSyntax
  • validateTheme / contrastRatio / resolveContrastText / resolveSelectionText

ThemeData 是组件绘制的主题输入。浅色、深色、医疗紧凑和现代紧凑主题都通过统一主题机制传入。

ModernCompactLightTheme 面向高密度桌面业务界面:13px 基础字号、28px 普通控件、29px 数据行、30px 表头和小圆角。它通过色阶、边框、状态反馈和浮层层级体现现代感,不通过放大控件或增加留白降低信息密度。

颜色工具

核心导出:

  • rgba
  • lerpColor
  • colorToCSS
  • haveSameThemeMetrics

颜色工具用于主题计算和绘制辅助。业务组件优先使用主题色,不要在组件中散落不可维护的十六进制颜色。

组件样式 token

常用导出:

  • BorderBackground
  • ButtonVariant
  • CardVariant
  • BadgeAppearance
  • BadgeStatus
  • ItemContainerAppearance
  • ItemContainerStyleOverrides
  • StatusBarTextTone
  • WindowChromeStyleTokens
  • mergeItemContainerStyle
  • deriveWindowChromeStyle

所有 derive*Style()、对应的 *StyleTokens 类型、contrastRatio()resolveContrastText()resolveSelectionText() 都由 ds-ui 包入口公开导出。业务代码不应从 src/theme/component_styles 或构建产物内部路径导入。

这些 token 用于统一 hover、selected、disabled、readonly、focus 等状态。TreeView、Dropdown、GridView 等通用动作状态应保持一致的对比度和语义。

字体就绪

核心导出:

  • DirectSurfaceFontFamily
  • loadDirectSurfaceFonts

Canvas 文本绘制依赖字体可用性。DirectSurfaceFontFamily 指向当前默认主题字体族;loadDirectSurfaceFonts() 不会主动加载框架内置字体,它会等待当前 document.fonts.ready 并清理文本测量缓存,避免首屏测量和绘制出现偏差。若业务使用自定义字体,应由宿主应用自行声明或加载字体资源。

主题切换建议

主题切换时应做到:

  • 更新应用主题。
  • 触发必要的布局和绘制。
  • 不改变业务状态。
  • 不重建大文档或大表格数据。
  • 保持 popup、tooltip、窗口和浮层样式一致。

医疗业务建议

医疗系统通常需要较高信息密度和可读性。主题应保证:

  • 表格 hover 和 selected 有足够对比度。
  • placeholder 与真实值颜色可区分。
  • 搜索命中和当前命中可区分。
  • 拖选背景和反色文字可读。
  • 留痕、批注和审计状态不过度抢占视线。

主题组合与不可变约定

推荐通过 createTheme(base, overrides) 创建业务主题。该函数会复制并合并嵌套设计系统层,再深度冻结新主题;不会冻结或修改调用方传入的 baseoverrides、颜色对象或数组:

import { createTheme, ImGuiLightTheme, rgba } from 'ds-ui' export const ModernLightTheme = createTheme(ImGuiLightTheme, {  frameRounding: 4,  controlHeight: 28,  dataRowHeight: 29,  typography: {    titleFontSize: 15,    secondaryFontSize: 12,  },  motion: {    fastDuration: 100,    normalDuration: 160,  },  chart: {    negative: rgba(185, 28, 28),  },})

ThemeData 当前支持以下可选设计系统层:

  • typography:正文、标题、辅助文字和等宽字体。
  • motion:快速、普通和慢速过渡时长;设置为 0 可关闭对应过渡。
  • elevation:Modal/Drawer 遮罩、窗口阴影和卡片阴影。
  • editor:编辑器选择、搜索命中和当前搜索命中。
  • chart:完整序列色板、负值色和性能时间线辅助色。
  • syntax:字符串、数字、布尔、函数、类型和元信息颜色。

框架按主题值而不是对象引用判断变化。值相同的新对象不会重复触发布局;颜色变化只触发重绘,字体和尺寸变化才触发布局。默认主题和 createTheme() 生成的主题均为深度冻结对象。

通用选中态使用 selectionBg / selectionStrongtextOnSelection。组件应通过 resolveSelectionText(theme, actualBackground) 获取实际前景色,不应把浅色选择背景直接搭配 textOnAccent

发布自定义主题前应执行 validateTheme(theme)。返回的问题包含字段路径、error/warning 严重级别和说明,当前会检查关键文字、主操作、危险操作、选中态和焦点的对比度,也会检查 hover/active 区分、颜色通道、图表色板、字体和关键密度尺寸。空的 chart.series 会被报告为错误;组件绘制时仍会安全回退到语义色板,避免产生无效颜色。

运行时切换

通过 Application.run(..., { theme }) 传入的显式主题会持续优先于主窗口的 resolveWindowTheme()。运行后可以调用:

import { ImGuiLightTheme } from 'ds-ui' host.setTheme(ImGuiLightTheme)host.useMainWindowTheme()

setTheme() 设置显式运行时主题;useMainWindowTheme() 恢复由主窗口提供主题。组件样式派生函数和对应 Token 类型均从 ds-ui 包入口导出,无需内部路径导入。