问题描述
官方文档声明 Text 原语(原语节点)支持 letterSpacing 和 wordSpacing。但是该功能似乎不可用,问题贯穿了从底层的 测量算法 到中间的 样式解析 再到上层的 业务组件封装 的完整链路。
代码分析
1. 底层:测量函数忽略(measureText)
measureText 实现忽略: 在 src/utils/measure-text.ts 中,逻辑只解构了 fontFamily, fontSize, fontWeight, lineHeight,完全忽略了 letterSpacing 和 wordSpacing。
- 调用链路截断:
src/utils/text.ts 中的 updateTextElement 在调用 measureText 时,显式解构并过滤了样式属性,直接丢弃了这两个属性。
2.中间层: 样式解析不一致
3.顶层:业务组件透传阻断
虽然原子组件 ItemLabel/ItemValue /ItemDes支持透传 TextProps,但在 SimpleItem、BadgeCard 等业务组件中,并没有开放接口来配置内部文本的间距,也没有将letterSpacing和wordSpacing透传给文本节点。
4.总结:文本属性支持情况对比表
| 层级 |
问题 |
letterSpacing |
wordSpacing |
底层 (measureText) |
测量忽略间距属性 |
❌ 不支持 |
❌ 不支持 |
中间层 (text.ts getTextStyle) |
px 后缀处理 |
✅ 有处理 |
❌ 无处理 |
中间层 (composites/text.ts) |
渲染白名单 |
✅ 已包含 |
❌ 缺失 |
原语层 (jsx Text) |
属性透传 |
✅ 正确 |
✅ 正确 |
| 业务组件层 |
接口暴露 |
❌ 未暴露 |
❌ 未暴露 |
建议方案
Step 1: 修复核心渲染与测量 (Core Fix)
Step 2: 修复组件层数据流 (Component Fix)
Step 3:性能优化 (Performance Optimization - 可选)
备注: 我已经准备好了一套本地实现LRU的方案。
如果维护者同意,我愿意参与第一步(核心修复)和第三步(性能优化)。
问题描述
官方文档声明
Text原语(原语节点)支持 letterSpacing 和 wordSpacing。但是该功能似乎不可用,问题贯穿了从底层的 测量算法 到中间的 样式解析 再到上层的 业务组件封装 的完整链路。代码分析
1. 底层:测量函数忽略(measureText)
measureText实现忽略: 在src/utils/measure-text.ts中,逻辑只解构了fontFamily,fontSize,fontWeight,lineHeight,完全忽略了letterSpacing和wordSpacing。src/utils/text.ts中的updateTextElement在调用measureText时,显式解构并过滤了样式属性,直接丢弃了这两个属性。2.中间层: 样式解析不一致
渲染属性白名单缺失:在
src/renderer/composites/text.ts的getTextAttributes函数中,使用了白名单机制提取 SVG 属性。'letter-spacing',但漏掉了'word-spacing'。wordSpacing,它也会在最终生成 SVGforeignObject内容时被剥离,无法渲染出视觉效果。在
src/utils/text.ts中的getTextStyle函数对letterSpacing做了处理,加上了px,但是没有对wordSpacing做处理。3.顶层:业务组件透传阻断
虽然原子组件
ItemLabel/ItemValue/ItemDes支持透传TextProps,但在SimpleItem、BadgeCard等业务组件中,并没有开放接口来配置内部文本的间距,也没有将letterSpacing和wordSpacing透传给文本节点。4.总结:文本属性支持情况对比表
measureText)text.ts getTextStyle)composites/text.ts)jsx Text)建议方案
Step 1: 修复核心渲染与测量 (Core Fix)
measureText: 升级函数签名,支持传入letterSpacing和wordSpacing。utils/text.ts: 在updateTextElement中正确透传这两个属性给测量函数。并且在getTextStyle函数中添加对wordSpacing的处理。renderer/composites/text.ts: 在getTextAttributes的白名单数组中添加'word-spacing'。Step 2: 修复组件层数据流 (Component Fix)
SimpleItem等组件,允许通过 props (如labelStyle) 传入间距属性,并将其透传给内部的ItemLabel/ItemDesc。Step 3:性能优化 (Performance Optimization - 可选)
measureText在每次调用时都会触发 Canvas/DOM 测量,而没有任何缓存机制。我建议引入 LRU (Least Recently Used) 缓存机制(例如通过项目现有的flru库实现)。如果维护者同意,我愿意参与第一步(核心修复)和第三步(性能优化)。