返回 CodeWhale
ratatui.ts
根目录 / web / lib / content / ratatui.ts
1 import { pickText } from "@/lib/i18n/dictionaries";
2 import type { LocalizedText } from "./vocabulary";
3
4 /** Public explorer copy. Component names, APIs and terminal fixtures stay verbatim. */
5 export interface RatatuiCopy {
6 metaTitle: string;
7 metaDescription: string;
8 title: string;
9 intro: string;
10 searchLabel: string;
11 searchPlaceholder: string;
12 allComponents: string;
13 families: string;
14 componentCount: string;
15 preview: string;
16 code: string;
17 api: string;
18 source: string;
19 profile: string;
20 size: string;
21 play: string;
22 pause: string;
23 reset: string;
24 copy: string;
25 copied: string;
26 copyFailed: string;
27 download: string;
28 openSource: string;
29 install: string;
30 back: string;
31 previous: string;
32 next: string;
33 terminalPreviewLabel: string;
34 emptyTitle: string;
35 emptyDescription: string;
36 clearSearch: string;
37 loading: string;
38 previewError: string;
39 retry: string;
40 usageTitle: string;
41 usageDescription: string;
42 installationTitle: string;
43 installationDescription: string;
44 tryLocally: string;
45 repository: string;
46 viewGuide: string;
47 quality: string;
48 releaseHistory: string;
49 checks: string;
50 fixtureNote: string;
51 motionNote: string;
52 rustVersion: string;
53 license: string;
54 nativeSize: string;
55 resultsLabel: string;
56 share: string;
57 fit: string;
58 actualSize: string;
59 columns: string;
60 renderedPreviewNote: string;
61 fixtureTitle: string;
62 motion: string;
63 motionDescription: string;
64 frame: string;
65 frameCount: string;
66 speed: string;
67 shareCopied: string;
68 projectStatus: string;
69 sourceRevision: string;
70 buildChecks: string;
71 galleryChecks: string;
72 statusNote: string;
73 keyboardHint: string;
74 visibleCount: string;
75 gettingStarted: string;
76 hostNote: string;
77 downloadSvg: string;
78 previewLoading: string;
79 componentNavLabel: string;
80 websiteNote: string;
81 reducedMotionNote: string;
82 tasksTitle: string;
83 tasksDescription: string;
84 use: string;
85 guide: string;
86 runExample: string;
87 relatedMotion: string;
88 recipeNote: string;
89 recipeControls: string;
90 firstAppTitle: string;
91 firstAppDescription: string;
92 existingApp: string;
93 themeNote: string;
94 starterSource: string;
95 stateTitle: string;
96 stateDescription: string;
97 paintTitle: string;
98 paintDescription: string;
99 actionsTitle: string;
100 actionsDescription: string;
101 heroLabel: string;
102 heroAlt: string;
103 heroCaption: string;
104 heroOpenExplorer: string;
105 heroOpenComponent: string;
106 familyPosition: string;
107 }
108
109 export const RATATUI_COPY: Record<keyof RatatuiCopy, LocalizedText> = {
110 metaTitle: { en: "Codewhale Ratatui · Terminal components", zh: "Codewhale Ratatui · 终端组件" },
111 metaDescription: {
112 en: "Explore Codewhale’s reusable Ratatui components. Compare terminal themes and widths, inspect real rendered previews, and use the Rust examples in your app.",
113 zh: "探索 Codewhale 的可复用 Ratatui 组件。比较终端主题和宽度,查看真实渲染预览,并将 Rust 示例用于你的应用。",
114 },
115 title: { en: "Codewhale Ratatui", zh: "Codewhale Ratatui" },
116 intro: {
117 en: "Bring Codewhale’s terminal components into your app. Explore the composer, workbar, ocean, themes and creatures, then take the Rust code with you.",
118 zh: "将 Codewhale 的终端组件用于你的应用。探索输入框、工作栏、海洋、主题与海洋生物,然后带走 Rust 代码。",
119 },
120 searchLabel: { en: "Find a component", zh: "查找组件" },
121 searchPlaceholder: { en: "Search components, APIs or themes…", zh: "搜索组件、API 或主题…" },
122 allComponents: { en: "All components", zh: "全部组件" },
123 families: { en: "Collections", zh: "组件集" },
124 componentCount: { en: "{count} previews", zh: "{count} 个预览" },
125 preview: { en: "Preview", zh: "预览" },
126 code: { en: "Gallery source", zh: "展示源码" },
127 api: { en: "Components used", zh: "使用的组件" },
128 source: { en: "Source", zh: "源码" },
129 profile: { en: "Terminal profile", zh: "终端配置" },
130 size: { en: "Width", zh: "宽度" },
131 play: { en: "Play", zh: "播放" },
132 pause: { en: "Pause", zh: "暂停" },
133 reset: { en: "Restart", zh: "重新开始" },
134 copy: { en: "Copy code", zh: "复制代码" },
135 copied: { en: "Copied", zh: "已复制" },
136 copyFailed: { en: "Select the code to copy it.", zh: "请选择代码后复制。" },
137 download: { en: "Download SVG", zh: "下载 SVG" },
138 openSource: { en: "Open source", zh: "查看源码" },
139 install: { en: "Use in your app", zh: "用于你的应用" },
140 back: { en: "Explore all components", zh: "探索全部组件" },
141 previous: { en: "Previous component", zh: "上一个组件" },
142 next: { en: "Next component", zh: "下一个组件" },
143 terminalPreviewLabel: { en: "Terminal preview of {name}", zh: "{name} 的终端预览" },
144 emptyTitle: { en: "No matching components", zh: "没有匹配的组件" },
145 emptyDescription: { en: "Try a component name, an API such as NativeComposer, or another collection.", zh: "试试组件名称、NativeComposer 等 API,或其他组件集。" },
146 clearSearch: { en: "Clear search", zh: "清除搜索" },
147 loading: { en: "Loading the preview…", zh: "正在加载预览…" },
148 previewError: { en: "The preview could not load. Try again or open its source.", zh: "无法加载预览。请重试或查看源码。" },
149 retry: { en: "Try again", zh: "重试" },
150 usageTitle: { en: "Compose your own terminal", zh: "构建你的终端界面" },
151 usageDescription: {
152 en: "Use a single widget or compose a workspace. Your app owns the state, clock and actions; the library renders the interface.",
153 zh: "使用单个组件,或组合成完整工作区。你的应用管理状态、时钟与操作;组件库负责渲染界面。",
154 },
155 installationTitle: { en: "Start building", zh: "开始构建" },
156 installationDescription: { en: "Add the library to your Cargo.toml. Use your existing backend, or enable Crossterm for a new app.", zh: "将组件库添加到 Cargo.toml。可使用现有终端后端,或为新应用启用 Crossterm。" },
157 tryLocally: { en: "Try the interactive gallery", zh: "试用交互式展示" },
158 repository: { en: "GitHub repository", zh: "GitHub 仓库" },
159 viewGuide: { en: "Terminal view guide", zh: "终端视图指南" },
160 quality: { en: "Quality and compatibility", zh: "质量与兼容性" },
161 releaseHistory: { en: "Release history", zh: "发布历史" },
162 checks: { en: "Latest checks", zh: "最新检查" },
163 fixtureNote: { en: "This source reproduces the gallery preview, including its example data and internal helpers. For public API code you can reuse, choose Use in your app.", zh: "此源码用于重现展示预览,包含示例数据和内部辅助函数。如需复用公开 API 代码,请选择“用于你的应用”。" },
164 motionNote: { en: "Animation uses rendered frames. Your app supplies the clock.", zh: "动画使用实际渲染的帧。时钟由你的应用提供。" },
165 rustVersion: { en: "Rust 1.89+", zh: "Rust 1.89+" },
166 license: { en: "MIT license", zh: "MIT 许可证" },
167 nativeSize: { en: "Native width", zh: "原始宽度" },
168 resultsLabel: { en: "Components matching your search", zh: "匹配搜索的组件" },
169 share: { en: "Open component page", zh: "打开组件页面" },
170 fit: { en: "Fit preview", zh: "适应预览宽度" },
171 actualSize: { en: "Actual size", zh: "实际大小" },
172 columns: { en: "{count} columns", zh: "{count} 列" },
173 renderedPreviewNote: {
174 en: "Rendered by the Rust components with example data. Choose a terminal profile and width to compare their layouts.",
175 zh: "使用示例数据,由 Rust 组件渲染。选择终端配置和宽度,比较不同布局。",
176 },
177 fixtureTitle: { en: "Rendering source", zh: "渲染源码" },
178 motion: { en: "Motion", zh: "动画" },
179 motionDescription: { en: "Watch the rendered frames, or move through them at your own pace.", zh: "播放渲染帧,或按自己的节奏逐帧查看。" },
180 frame: { en: "Frame", zh: "帧" },
181 frameCount: { en: "{count} frames", zh: "{count} 帧" },
182 speed: { en: "Speed", zh: "速度" },
183 shareCopied: { en: "Link copied", zh: "链接已复制" },
184 projectStatus: { en: "Follow the library", zh: "关注组件库" },
185 sourceRevision: { en: "Library source", zh: "组件库源码" },
186 buildChecks: { en: "Library checks", zh: "组件库检查" },
187 galleryChecks: { en: "Gallery checks", zh: "展示检查" },
188 statusNote: { en: "Open the latest checks and releases on GitHub.", zh: "在 GitHub 查看最新检查与发布。" },
189 keyboardHint: { en: "Use the search field and collection links to find a component.", zh: "使用搜索框和组件集链接查找组件。" },
190 visibleCount: { en: "{visible} of {total} previews", zh: "{total} 个预览中的 {visible} 个" },
191 gettingStarted: { en: "Get started", zh: "开始使用" },
192 hostNote: { en: "Your app owns state, timing and actions. Components render into the Ratatui frame you supply.", zh: "你的应用管理状态、时间与操作。组件渲染到你提供的 Ratatui 帧。" },
193 downloadSvg: { en: "Download SVG", zh: "下载 SVG" },
194 previewLoading: { en: "Loading the preview…", zh: "正在加载预览…" },
195 componentNavLabel: { en: "Ratatui component collections", zh: "Ratatui 组件集" },
196 websiteNote: { en: "Part of Codewhale. Built for your Ratatui app.", zh: "来自 Codewhale,用于你的 Ratatui 应用。" },
197 reducedMotionNote: { en: "Playback is paused for reduced motion. You can step through the frames or choose Play.", zh: "已按减少动态效果的偏好暂停播放。你可以逐帧查看或选择播放。" },
198 tasksTitle: { en: "What are you building?", zh: "你想构建什么?" },
199 tasksDescription: { en: "Choose a starting point, or browse every component below.", zh: "选择一个起点,或浏览下方的全部组件。" },
200 use: { en: "Use in your app", zh: "用于你的应用" },
201 guide: { en: "Read the getting-started guide", zh: "阅读入门指南" },
202 runExample: { en: "Run from the cloned library", zh: "在克隆的组件库中运行" },
203 relatedMotion: { en: "Related animation demo", zh: "相关动画示例" },
204 recipeNote: { en: "A public API starting point from the runnable recipes example. Pass your app’s theme and state; adapt the data and layout to your app.", zh: "这是可运行示例中的公开 API 起点。传入应用的主题与状态,并按需调整数据和布局。" },
205 recipeControls: { en: "F1 composer · F2 workbar · F3 water · F4 whale · F5 animated whale. Press m in F5 to compare motion policies; Esc closes.", zh: "F1 输入框 · F2 工作栏 · F3 海洋背景 · F4 鲸鱼 · F5 动态鲸鱼。在 F5 中按 m 比较动画策略;Esc 退出。" },
206 firstAppTitle: { en: "Start with a working app", zh: "从可运行的应用开始" },
207 firstAppDescription: { en: "Type a message, press Enter to echo it, and Esc to exit. The starter connects editable input, the native composer and workbar in one small app.", zh: "输入消息,按 Enter 显示消息,按 Esc 退出。入门示例在一个小应用中连接可编辑输入、原生输入框与工作栏。" },
208 existingApp: { en: "Add to an existing Ratatui app", zh: "添加到现有 Ratatui 应用" },
209 themeNote: { en: "Detect the theme once when your app starts, then pass it to your draw function. Theme::detect().tui() selects the native terminal palette.", zh: "启动时检测一次主题,再传入绘制函数。Theme::detect().tui() 会选择原生终端配色。" },
210 starterSource: { en: "See the complete starter", zh: "查看完整入门示例" },
211 stateTitle: { en: "Keep the state", zh: "保存状态" },
212 stateDescription: { en: "Your app stores drafts, selection, work and a persistent whale Stage.", zh: "应用保存草稿、选中项、工作数据及持续使用的鲸鱼 Stage。" },
213 paintTitle: { en: "Render the view", zh: "渲染视图" },
214 paintDescription: { en: "Components paint the facts you supply into your Ratatui frame.", zh: "组件将你提供的数据绘制到 Ratatui 帧中。" },
215 actionsTitle: { en: "Handle the action", zh: "处理操作" },
216 actionsDescription: { en: "Route input outcomes to your app. Supply elapsed time when motion needs a redraw.", zh: "将输入结果交给应用处理;动画需要重绘时,提供经过的时间。" },
217 heroLabel: { en: "Codewhale terminal, rendered by the library", zh: "由组件库渲染的 Codewhale 终端" },
218 heroAlt: { en: "A Codewhale terminal session: conversation, composer and Tasks workbar over the ocean background", zh: "Codewhale 终端会话:对话、输入框与任务工作栏,背景为海洋" },
219 heroCaption: { en: "Native conversation, composer and Tasks workbar · Underwater truecolor · {width}×{height}", zh: "原生对话、输入框与任务工作栏 · Underwater 真彩色 · {width}×{height}" },
220 heroOpenExplorer: { en: "Open in the explorer", zh: "在组件探索器中打开" },
221 heroOpenComponent: { en: "About this composition", zh: "关于此组合" },
222 familyPosition: { en: "{index} of {count} in this collection", zh: "本组件集中第 {index} 个,共 {count} 个" },
223 };
224
225 /** Use the site's deterministic locale selection rather than page-local copy forks. */
226 export function getRatatuiCopy(locale: string): RatatuiCopy {
227 return Object.fromEntries(
228 Object.entries(RATATUI_COPY).map(([key, text]) => [key, pickText(text, locale)]),
229 ) as unknown as RatatuiCopy;
230 }
231
231 lines TYPESCRIPT