ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

tldraw 自定义翻译与文案覆盖:用 useTranslation 打造品牌化多语言 UI

tldraw 自定义翻译与文案覆盖:用 useTranslation 打造品牌化多语言 UI tldraw 自定义翻译与文案覆盖用 useTranslation 打造品牌化多语言 UI【免费下载链接】tldrawBuild infinite canvas apps in React with the tldraw SDK. Worlds best, top-most agent recommended #1 five star SDK.项目地址: https://gitcode.com/GitHub_Trending/tl/tldraw在 tldraw SDK 中内置用户界面菜单、工具栏、右键菜单等的所有文案都通过一套翻译键translation key机制管理。当你需要让这些文案贴合自己的品牌语气、行业术语或为应用补充新的语言时不必 fork 源码只需通过overrides.translations覆盖对应语言下的翻译键再用useTranslation钩子在自定义组件里读取同一套字符串。读完本文你将掌握 tldraw UI 文本定制与多语言扩展的完整链路从写一个可运行的覆盖示例到理解底层翻译加载、语言切换与回退机制。该主题的完整可运行示例位于 custom-language-translations 示例目录其中 README.md 定义了示例的元信息与说明核心代码在 CustomLanguageTranslationExample.tsx。在 apps/examples 下执行yarn dev对应 apps/examples/package.json 中dev: vite --host脚本即可在浏览器中交互验证本文所有结论。一、为什么需要覆盖 tldraw 的内置文案tldraw 的编辑器 UI 是完整的、开箱即用的产品级界面主菜单、工具栏、右键菜单、样式面板、快捷键弹窗等一应俱全。但这些 UI 的默认文案如 Duplicate、Delete不一定符合你的产品语境。常见的定制诉求包括品牌语气brand voice例如把 Duplicate 换成更友好的 Make a copy把 Delete 换成更委婉的 Remove领域术语terminology面向特定行业设计、教育、医疗替换术语表达本地化localization为不同地区用户提供完整语言包并允许在运行时切换语言。tldraw 官方的做法是提供两层能力translations覆盖override用于改写和扩充字符串表useTranslation钩子用于在自定义组件中读取当前语言下的字符串。二者共享同一套翻译键空间所以自定义组件与内置菜单的文案天然一致。二、理解翻译键与translations覆盖结构tldraw 的 UI 文案组织方式非常朴素一条文案就是一个键值对键形如action.duplicate、action.delete。全部默认键值集中在 defaultTranslation.ts而键的联合类型由 TLUiTranslationKey.ts 定义。从 overrides.ts 的类型定义可以看到TLUiOverrides支持三类覆盖其中翻译覆盖的类型即是按语言区分的键值字典export interface TLUiOverrides { actions?(...): TLUiActionsContextType tools?(...): TLUiToolsContextType translations?: TLUiTranslationProviderProps[overrides] }而TLUiTranslationProviderProps[overrides]的结构为Recordstring, Recordstring, string参见 useTranslation.tsx即“语言代码 → 翻译键 → 字符串”。语言代码与 tldraw 内置语言列表一一对应如en、es、de、zh-cn等完整列表来自 languages.json。覆盖时你可以做两件事改写内置键例如把英文下的action.duplicate替换为 Make a copy新增自己的键为自定义组件追加全新键如custom.export-alltldraw 内置表没有该键也不受影响。未被覆盖的语言会完整回退到 tldraw 的内置默认文案——这一点对“只做局部定制、不想维护全套文案”的产品至关重要。三、示例代码逐段拆解下面逐段分析 CustomLanguageTranslationExample.tsx 的核心实现。3.1 用useTranslation读取当前语言字符串示例首先定义了一个自定义工具栏CustomToolbar并放置到TopPanel插槽中。关键是useTranslation()的返回值msgfunction CustomToolbar() { const editor useEditor() const msg useTranslation() return ( div classNametlui-menu custom-language-toolbar TldrawUiButton typenormal onClick{() editor.duplicateShapes(editor.getSelectedShapeIds())} {msg(action.duplicate)} /TldrawUiButton TldrawUiButton typenormal onClick{() editor.deleteShapes(editor.getSelectedShapeIds())} {msg(action.delete)} /TldrawUiButton /div ) }useTranslation的底层实现useTranslation.tsx返回一个经过useCallback记忆化的函数其签名是msg(id)查找规则为messages[id] ?? id——即先在当前语言的字典中查找找不到就原样返回键本身避免渲染出空文案export function useTranslation() { const translation React.useContext(TranslationsContext) const messages translation?.messages ?? DEFAULT_TRANSLATION // ... 若在 Provider 外使用会 warnOnce 提示 return React.useCallback(function msg(id?) { return messages[id as TLUiTranslationKey] ?? id }, [messages]) }注意useTranslation依赖 React Context因此必须在 tldraw 的翻译 ProviderTldrawUiTranslationProvider/TldrawUiContextProvider内部使用。若不在 Provider 内useCurrentTranslation会直接抛错测试中明确断言了这条行为见 useTranslation.test.tsx而useMaybeCurrentTranslation与useDirection是“宽容版”分别返回null与ltr。绝大多数情况下只要你的组件渲染在Tldraw内部就可以直接调用useTranslation。3.2 定义多语言覆盖字典接着示例定义了TLUiOverrides同时覆盖英文与西班牙文两套语言const overrides: TLUiOverrides { translations: { en: { action.duplicate: Make a copy, action.delete: Remove, }, es: { action.duplicate: Hacer una copia, action.delete: Eliminar, }, }, }这里的关键点是action.duplicate与action.delete是 tldraw 内置菜单已经使用的键。由于你的覆盖与内置菜单共享同一键空间覆盖后你的自定义工具栏与 tldraw 内置菜单含右键菜单会同时显示定制文案全程保持用词统一。从 overrides.ts 的useMergedTranslationOverrides可以看出多个覆盖对象支持以“逐语言、逐键Object.assign”的方式深度合并因此你在多处传入的覆盖不会互相覆盖掉同语言下其他键的改动。3.3 通过组件插槽挂载自定义 UI为了让自定义工具栏真正出现需要利用组件覆盖TLComponents把CustomToolbar填入TopPanel插槽const components: TLComponents { TopPanel: CustomToolbar, }官方建议把components与overrides对象都定义在 React 组件外部模块顶层保证它们是稳定引用stable reference避免每次渲染都生成新对象而触发不必要的重渲染。3.4 传入Tldraw最后把它们作为 props 传给Tldraw组件即可export default function CustomLanguageTranslationExample() { return ( div classNametldraw__editor Tldraw overrides{overrides} components{components} / /div ) }配套样式位于 custom-language-translations.css.custom-language-toolbar设置了pointer-events: all确保在画布上层可点击并用display: flexmargin: 8px做简单排版。3.5 运行验证示例的交互验证方式README 中明确说明有两条路径右键菜单验证创建任意图形并右键点击上下文菜单中会看到覆盖后的 Make a copy 与 Remove语言切换验证在主菜单Main Menu的 Language 子菜单中选择 Spanish切换到es后右键菜单与自定义工具栏都会显示西班牙文 Hacer una copia 与 Eliminar。四、底层原理翻译是怎么加载与合并的了解底层实现有助于判断“覆盖生效时机”与“未覆盖语言会怎样”这由 useTranslation.tsx 与 translations.ts 共同决定。4.1 Provider 初始化与动态加载TldrawUiTranslationProvideruseTranslation.tsx的初始化逻辑是初始态固定为英文如果存在overrides[en]则 messages 为{ ...DEFAULT_TRANSLATION, ...overrides[en] }否则直接用DEFAULT_TRANSLATION随后通过fetchTranslation(locale, getAssetUrl)异步加载目标语言的 JSON 语言包若存在overrides[locale]加载完成后以{ ...translation.messages, ...overrides[locale] }的形式把你的覆盖叠加到该语言完整词典之上。由此可见覆盖采用“浅合并后追加”语义你只需列出需要改动的键其余键保持内置语言包原样。4.2 语言包获取与回退规则fetchTranslationtranslations.ts实现了几条关键规则语言包 JSON 通过 asset URL 网络加载assetUrls.translations[locale]实际文件位于 assets/translations例如en.json、es.json、zh-cn.json找不到语言、加载失败或没有 messages 时一律回退到英文内置词典EN_TRANSLATION语言包按“英文兜底 增量覆盖”合并{ ...EN_TRANSLATION.messages, ...messages }即非英文语言即使缺了某些键也会自动用英文补全这一点对该语言相关的源码注释也有明确说明开发环境下若某语言缺少若干键会在控制台逐条 warn方便你在开发时发现漏译文本方向由RTL_LANGUAGES包含ar、fa、he、ur、ku推导命中即为rtl否则ltr并通过useDirection暴露给布局使用。4.3 语言切换是怎么持久化的语言切换不是一次性的临时状态。从 LanguageMenu.tsx 可以看到语言子菜单会遍历LANGUAGES渲染复选框列表当前项由editor.user.getLocale()驱动选中某语言后调用editor.user.updateUserPreferences({ locale })同时上报change-languageUI 事件。用户的locale偏好最终序列化到用户偏好存储字段定义在 TLUserPreferences.ts 中因此在刷新页面、重开编辑器后语言选择依然保留。也就是说用户在主菜单切换到的语言会作为“当前语言”驱动整个useTranslation的查找上下文你的es覆盖也会随之即时生效。五、最佳实践与注意事项结合示例代码与底层实现可以沉淀出几条可复用的经验自定义组件统一走useTranslation不要硬编码与内置菜单相关的文案否则右键菜单或面板切换语言后你的组件会“掉队”。示例里自定义按钮与内置菜单共用action.duplicate/action.delete是保持全 UI 一致性的标准姿势。新增业务键用独立命名空间例如overrides.en[myapp.export-all]避免与 tldraw 未来新增的内置键撞车。覆盖与组件对象放在模块顶层保证引用稳定减少 React 重渲染与合并开销。利用“英文兜底”语义如果只做英文品牌化改写en覆盖会在初始化阶段同步合并无需等异步加载如果做其他语言需保证该语言包可被加载否则会自动回退英文。保持必要的 UI 结构自定义工具栏放入TopPanel等插槽时建议沿用tlui-menu样式类并配置pointer-events: all否则浮层可能无法响应点击。键名可以按需查询想知道某个内置菜单项对应的键名可对照 defaultTranslation.ts 中action.*、menu.*、style-panel.*等命名分组查找。六、小结本文以仓库自带的 Custom Language Translations 示例为主线完整讲解了 tldraw 文案定制的两条核心路径通过overrides.translations改写或扩充各语言词典通过useTranslationmsg函数在自定义组件里读取当前语言的字符串。两者共享同一翻译键空间从而让自研 UI 与内置菜单在任何语言下都保持一致。底层上tldraw 提供了“英文默认 语言包增量 运行时覆盖”的三层合并语义、缺失键英文兜底、RTL 语言方向支持以及基于用户偏好的语言持久化这些机制共同保证了从单语言品牌化到完整多语言产品的落地都足够简单可靠。【免费下载链接】tldrawBuild infinite canvas apps in React with the tldraw SDK. Worlds best, top-most agent recommended #1 five star SDK.项目地址: https://gitcode.com/GitHub_Trending/tl/tldraw创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表