10 10
11要了解绘制的工作原理,请从[在界面中绘制](/docs/zh-CN/plugins/mods/interface)开始。有关主要 props 以及哪些应用会绘制各个元素,请参阅[元素参考](/docs/zh-CN/plugins/mods/reference#elements)。[类型声明](/docs/zh-CN/plugins/mods/create#get-the-types-for-your-build)列出了所有 props。11要了解绘制的工作原理,请从[在界面中绘制](/docs/zh-CN/plugins/mods/interface)开始。有关主要 props 以及哪些应用会绘制各个元素,请参阅[元素参考](/docs/zh-CN/plugins/mods/reference#elements)。[类型声明](/docs/zh-CN/plugins/mods/create#get-the-types-for-your-build)列出了所有 props。
12 12
13<h2 id="try-a-sample">13## 试用示例
14 试用示例
15</h2>
16 14
17本页的示例是代码片段,而非完整的 mod。每个示例都是一个元素及其内部嵌套内容的代码。15本页的示例是代码片段,而非完整的 mod。每个示例都是一个元素及其内部嵌套内容的代码。
18 16
19要在您自己的终端中查看示例,请按以下步骤创建一个小型 mod,并将示例粘贴进去。该 mod 会添加一个 `/gallery` 命令,用于打开一个窗格并在其中绘制示例。[窗格](/docs/zh-CN/plugins/mods/interface#pick-where-to-draw)在宽屏全屏终端中是会话记录旁边的侧边栏,在其他情况下则是输入框上方带边框的区域。17要在您自己的终端中查看示例,请按以下步骤创建一个小型 mod,并将示例粘贴进去。该 mod 会添加一个 `/gallery` 命令,用于打开一个窗格并在其中绘制示例。[窗格](/docs/zh-CN/plugins/mods/interface#pick-where-to-draw)在宽屏全屏终端中是会话记录旁边的侧边栏,在其他情况下则是输入框上方带边框的区域。
20 18
21<Steps>19**1. 创建 mod**
22 <Step title="创建 mod">
23 创建一个名为 `gallery` 的目录,并在其中创建 `.claude-plugin` 和 `hooks` 目录。[创建 mod](/docs/zh-CN/plugins/mods/create#write-a-mod-yourself) 介绍了这些文件。
24 20
25 将清单保存为 `gallery/.claude-plugin/plugin.json`:21创建一个名为 `gallery` 的目录,并在其中创建 `.claude-plugin` 和 `hooks` 目录。[创建 mod](/docs/zh-CN/plugins/mods/create#write-a-mod-yourself) 介绍了这些文件。
26 22
27 ```json gallery/.claude-plugin/plugin.json theme={null}23将清单保存为 `gallery/.claude-plugin/plugin.json`:
28 {24
25```json gallery/.claude-plugin/plugin.json theme={null}
26{
29 "name": "gallery",27 "name": "gallery",
30 "version": "0.1.0",28 "version": "0.1.0",
31 "description": "Opens a pane that draws one sample",29 "description": "Opens a pane that draws one sample",
32 "author": { "name": "Your Name" }30 "author": { "name": "Your Name" }
33 }31}
34 ```32```
35 33
36 在 `gallery/hooks/hooks.json` 中指定入口文件:34在 `gallery/hooks/hooks.json` 中指定入口文件:
37 35
38 ```json gallery/hooks/hooks.json theme={null}36```json gallery/hooks/hooks.json theme={null}
39 {37{
40 "modules": ["./register.js"]38 "modules": ["./register.js"]
41 }39}
42 ```40```
43 41
44 将代码保存为 `gallery/hooks/register.js`。它会添加一个打开窗格的 `/gallery` 命令,并在该窗格中绘制 `Plain text`:42将代码保存为 `gallery/hooks/register.js`。它会添加一个打开窗格的 `/gallery` 命令,并在该窗格中绘制 `Plain text`:
45 43
46 ```javascript gallery/hooks/register.js theme={null}44```javascript gallery/hooks/register.js theme={null}
47 // Stands in for your own callback in the samples that take one45// Stands in for your own callback in the samples that take one
48 const noop = () => {}46const noop = () => {}
49 // The Select sample keeps its choice here47// The Select sample keeps its choice here
50 let picked = 'md'48let picked = 'md'
51 49
52 // The Raster sample packs its cells with this function50// The Raster sample packs its cells with this function
53 const DEFAULT_COLOR = 0x0100000051const DEFAULT_COLOR = 0x01000000
54 function cellsOf(rows) {52function cellsOf(rows) {
55 const numbers = rows.flat().flatMap(([char, color]) => [char.codePointAt(0), color, DEFAULT_COLOR])53 const numbers = rows.flat().flatMap(([char, color]) => [char.codePointAt(0), color, DEFAULT_COLOR])
56 return new Uint8Array(Uint32Array.from(numbers).buffer).toBase64()54 return new Uint8Array(Uint32Array.from(numbers).buffer).toBase64()
57 }55}
58 56
59 export function register(on) {57export function register(on) {
60 on('session.start', async ($, e, next) => {58 on('session.start', async ($, e, next) => {
61 await $.command.register({ name: 'gallery', description: 'Open the sample pane' })59 await $.command.register({ name: 'gallery', description: 'Open the sample pane' })
62 return next(e)60 return next(e)
73 // Replace the element after return with a sample71 // Replace the element after return with a sample
74 return Text({ children: ['Plain text'] })72 return Text({ children: ['Plain text'] })
75 })73 })
76 }74}
77 ```75```
78 </Step>76
77**2. 运行 mod**
79 78
80 <Step title="运行 mod">79在 shell 中,从包含 `gallery` 的目录启动 Claude Code:
81 在 shell 中,从包含 `gallery` 的目录启动 Claude Code:
82 80
83 ```bash theme={null}81```bash theme={null}
84 claude --plugin-dir ./gallery82claude --plugin-dir ./gallery
85 ```83```
86 84
87 在 Claude Code 输入框中运行 `/gallery`。一个窗格随即打开,其中显示 `Plain text`。85在 Claude Code 输入框中运行 `/gallery`。一个窗格随即打开,其中显示 `Plain text`。
88 </Step>
89 86
90 <Step title="替换为示例">87**3. 替换为示例**
91 从本页复制一个示例。在 `register.js` 中,将其粘贴以替换 `Text({ children: ['Plain text'] })`,使其位于 `return` 之后,然后保存文件。每次保存时 Claude Code 都会重新加载该模块,因此再次运行 `/gallery` 即可查看新示例。
92 </Step>
93</Steps>
94 88
95<h2 id="pick-an-element">89从本页复制一个示例。在 `register.js` 中,将其粘贴以替换 `Text({ children: ['Plain text'] })`,使其位于 `return` 之后,然后保存文件。每次保存时 Claude Code 都会重新加载该模块,因此再次运行 `/gallery` 即可查看新示例。
96 选择元素90
97</h2>91## 选择元素
98 92
99示例按您想在屏幕上显示的内容分组:93示例按您想在屏幕上显示的内容分组:
100 94
104* **[接收输入](#take-input)**:`Button`、`Input` 和 `Select`98* **[接收输入](#take-input)**:`Button`、`Input` 和 `Select`
105* **[绘制图形](#draw-pictures)**:`Raster`、`Svg`、`Image` 和 `Client`99* **[绘制图形](#draw-pictures)**:`Raster`、`Svg`、`Image` 和 `Client`
106 100
107<h2 id="show-text">101## 显示文本
108 显示文本
109</h2>
110 102
111有三个元素可在屏幕上显示文字:`Text` 用于自定义样式,`Markdown` 用于已格式化的内容,`Link` 用于 URL。103有三个元素可在屏幕上显示文字:`Text` 用于自定义样式,`Markdown` 用于已格式化的内容,`Link` 用于 URL。
112 104
113<h3 id="text">105### `Text`
114 `Text`
115</h3>
116 106
117`Text` 使用您指定的样式绘制字符串。此示例显示纯文本和八种样式,每行一种:107`Text` 使用您指定的样式绘制字符串。此示例显示纯文本和八种样式,每行一种:
118 108
133})123})
134```124```
135 125
136<img src="https://mintcdn.com/claude-code/EXkwf0kKMewZsyod/images/mods-el-text-light.png?fit=max&auto=format&n=EXkwf0kKMewZsyod&q=85&s=90724ce3953d9347b61b6a9266fda451" className="dark:hidden" alt="一个包含九行文本的窗格,每行以其样式命名:plain、bold、italic、underline、strikethrough、灰色的 dimColor、inverse、红色的 color 以及蓝色的 backgroundColor。" width="1872" height="490" data-path="images/mods-el-text-light.png" />126
137
138<img src="https://mintcdn.com/claude-code/EXkwf0kKMewZsyod/images/mods-el-text-dark.png?fit=max&auto=format&n=EXkwf0kKMewZsyod&q=85&s=790dd3465e06db0842639d0d8fcbbc96" className="hidden dark:block" alt="一个包含九行文本的窗格,每行以其样式命名:plain、bold、italic、underline、strikethrough、灰色的 dimColor、inverse、红色的 color 以及蓝色的 backgroundColor。" width="1872" height="490" data-path="images/mods-el-text-dark.png" />
139 127
140`dimColor` 以灰色绘制文本。`backgroundColor` 的填充宽度仅与文本相同。128`dimColor` 以灰色绘制文本。`backgroundColor` 的填充宽度仅与文本相同。
141 129
142<h3 id="markdown">130### `Markdown`
143 `Markdown`
144</h3>
145 131
146`Markdown` 按照 Claude 回复的格式来格式化文本。请通过 `text` 而非 `children` 传入内容:132`Markdown` 按照 Claude 回复的格式来格式化文本。请通过 `text` 而非 `children` 传入内容:
147 133
151})137})
152```138```
153 139
154<img src="https://mintcdn.com/claude-code/EXkwf0kKMewZsyod/images/mods-el-markdown-light.png?fit=max&auto=format&n=EXkwf0kKMewZsyod&q=85&s=e40eacc4e3fbe06eb003f4463f552ec1" className="dark:hidden" alt="一个窗格,包含粗体标题 Release notes,随后是一个含有一个粗体词和一个彩色代码词的句子、一个两项列表,以及一段以斜体绘制且左侧带竖线的引用。" width="1872" height="452" data-path="images/mods-el-markdown-light.png" />140
155
156<img src="https://mintcdn.com/claude-code/EXkwf0kKMewZsyod/images/mods-el-markdown-dark.png?fit=max&auto=format&n=EXkwf0kKMewZsyod&q=85&s=2cc342ed0c58e752c425fff3c95a33a6" className="hidden dark:block" alt="一个窗格,包含粗体标题 Release notes,随后是一个含有一个粗体词和一个彩色代码词的句子、一个两项列表,以及一段以斜体绘制且左侧带竖线的引用。" width="1872" height="452" data-path="images/mods-el-markdown-dark.png" />
157 141
158标题以粗体绘制,不显示其 `#` 标记。行内代码以彩色绘制,不显示反引号。引用以斜体绘制,左侧带一条竖线。142标题以粗体绘制,不显示其 `#` 标记。行内代码以彩色绘制,不显示反引号。引用以斜体绘制,左侧带一条竖线。
159 143
160<h3 id="link">144### `Link`
161 `Link`
162</h3>
163 145
164`Link` 绘制一个标签,后跟其 URL:146`Link` 绘制一个标签,后跟其 URL:
165 147
167Link({ href: 'https://code.claude.com/docs', label: 'Claude Code docs' })149Link({ href: 'https://code.claude.com/docs', label: 'Claude Code docs' })
168```150```
169 151
170<img src="https://mintcdn.com/claude-code/EXkwf0kKMewZsyod/images/mods-el-link-light.png?fit=max&auto=format&n=EXkwf0kKMewZsyod&q=85&s=8217bd2dfb561a8ba57023c6d89ea977" className="dark:hidden" alt="一个只有一行的窗格:标签 Claude Code docs,随后是灰色的 URL。" width="1872" height="186" data-path="images/mods-el-link-light.png" />152
171
172<img src="https://mintcdn.com/claude-code/EXkwf0kKMewZsyod/images/mods-el-link-dark.png?fit=max&auto=format&n=EXkwf0kKMewZsyod&q=85&s=cd32f222a7d3530b070f58f5f189a1f8" className="hidden dark:block" alt="一个只有一行的窗格:标签 Claude Code docs,随后是灰色的 URL。" width="1872" height="186" data-path="images/mods-el-link-dark.png" />
173 153
174终端将 URL 作为文本绘制在标签之后。点击能否打开它取决于用户的终端。154终端将 URL 作为文本绘制在标签之后。点击能否打开它取决于用户的终端。
175 155
176<h2 id="show-code-and-changes">156## 显示代码和更改
177 显示代码和更改
178</h2>
179 157
180`Code` 使用 Claude Code 自己的语法配色绘制源代码文本或 diff。在 VS Code 扩展中,`Code` 将其 `source` 显示为纯文本,不带这些截图中的配色、行号或 diff 底纹。158`Code` 使用 Claude Code 自己的语法配色绘制源代码文本或 diff。在 VS Code 扩展中,`Code` 将其 `source` 显示为纯文本,不带这些截图中的配色、行号或 diff 底纹。
181 159
182<h3 id="code">160### `Code`
183 `Code`
184</h3>
185 161
186指定 `language`,或传入 `path` 让 Claude Code 据此推断语言。使用 `startLine` 时,行号从该数字开始:162指定 `language`,或传入 `path` 让 Claude Code 据此推断语言。使用 `startLine` 时,行号从该数字开始:
187 163
193})169})
194```170```
195 171
196<img src="https://mintcdn.com/claude-code/EXkwf0kKMewZsyod/images/mods-el-code-light.png?fit=max&auto=format&n=EXkwf0kKMewZsyod&q=85&s=4e13f5d506d3fdcc59d6d9524f48d2a9" className="dark:hidden" alt="一个窗格,包含两行带行号、语法着色的 JavaScript 代码。" width="1872" height="224" data-path="images/mods-el-code-light.png" />172
197
198<img src="https://mintcdn.com/claude-code/EXkwf0kKMewZsyod/images/mods-el-code-dark.png?fit=max&auto=format&n=EXkwf0kKMewZsyod&q=85&s=59f797371dd91b16b874a382b784b668" className="hidden dark:block" alt="一个窗格,包含两行带行号、语法着色的 JavaScript 代码。" width="1872" height="224" data-path="images/mods-el-code-dark.png" />
199 173
200颜色来自用户的主题。174颜色来自用户的主题。
201 175
202<h3 id="code-as-a-diff">176### 以 diff 形式使用 `Code`
203 以 diff 形式使用 `Code`
204</h3>
205 177
206使用 `format: 'diff'` 时,`source` 是一个或多个 unified diff hunk:178使用 `format: 'diff'` 时,`source` 是一个或多个 unified diff hunk:
207 179
212})184})
213```185```
214 186
215<img src="https://mintcdn.com/claude-code/EXkwf0kKMewZsyod/images/mods-el-diff-light.png?fit=max&auto=format&n=EXkwf0kKMewZsyod&q=85&s=4f12c9f7229ceccd9b4f47479a7235dd" className="dark:hidden" alt="一个包含四行 diff 的窗格。删除的行以红色底纹显示,添加的行以绿色底纹显示,每行都带有行号。在添加的行中,that runs code 这几个词的底纹更深。" width="1872" height="300" data-path="images/mods-el-diff-light.png" />187
216
217<img src="https://mintcdn.com/claude-code/EXkwf0kKMewZsyod/images/mods-el-diff-dark.png?fit=max&auto=format&n=EXkwf0kKMewZsyod&q=85&s=9db96f34381bac8bebc32d41859b8808" className="hidden dark:block" alt="一个包含四行 diff 的窗格。删除的行以红色底纹显示,添加的行以绿色底纹显示,每行都带有行号。在添加的行中,that runs code 这几个词的底纹更深。" width="1872" height="300" data-path="images/mods-el-diff-dark.png" />
218 188
219Claude Code 用行号代替 `@@` 行进行绘制。当删除的行与添加的行相似时,发生变化的词会以更深的底纹显示。189Claude Code 用行号代替 `@@` 行进行绘制。当删除的行与添加的行相似时,发生变化的词会以更深的底纹显示。
220 190
221<h2 id="arrange-elements">191## 排列元素
222 排列元素
223</h2>
224 192
225<h3 id="box">193### `Box`
226 `Box`
227</h3>
228 194
229`Box` 将其内部内容按行或列排布,并可绘制边框。此示例在一个带边框的框上方放置了一行文字:195`Box` 将其内部内容按行或列排布,并可绘制边框。此示例在一个带边框的框上方放置了一行文字:
230 196
247})213})
248```214```
249 215
250<img src="https://mintcdn.com/claude-code/EXkwf0kKMewZsyod/images/mods-el-box-light.png?fit=max&auto=format&n=EXkwf0kKMewZsyod&q=85&s=cb9263bb02f5c8afb6e5b8450e0cdadc" className="dark:hidden" alt="一个窗格,包含一行三个间隔四列的词,然后是一个空行,再然后是围绕一行文本的圆角边框。边框横跨窗格的整个宽度。" width="1872" height="338" data-path="images/mods-el-box-light.png" />216
251
252<img src="https://mintcdn.com/claude-code/EXkwf0kKMewZsyod/images/mods-el-box-dark.png?fit=max&auto=format&n=EXkwf0kKMewZsyod&q=85&s=dae83407af4d667a58717f68f13848e2" className="hidden dark:block" alt="一个窗格,包含一行三个间隔四列的词,然后是一个空行,再然后是围绕一行文本的圆角边框。边框横跨窗格的整个宽度。" width="1872" height="338" data-path="images/mods-el-box-dark.png" />
253 217
254边框会延展至窗格的宽度。218边框会延展至窗格的宽度。
255 219
256<h2 id="take-input">220## 接收输入
257 接收输入
258</h2>
259 221
260`Button`、`Input` 和 `Select` 是控件:用户通过 Tab 键在它们之间移动,并操作获得焦点的那个控件。[键盘焦点和快捷键](/docs/zh-CN/plugins/mods/interface#know-which-keys-your-mod-can-receive)介绍了哪些按键会传递给它们。222`Button`、`Input` 和 `Select` 是控件:用户通过 Tab 键在它们之间移动,并操作获得焦点的那个控件。[键盘焦点和快捷键](/docs/zh-CN/plugins/mods/interface#know-which-keys-your-mod-can-receive)介绍了哪些按键会传递给它们。
261 223
262使用 `focus: true` 打开窗格可为该窗格请求键盘焦点。`Input` 获得焦点后即可接收键入的字母。要选择窗格打开时哪个输入框获得焦点,请参阅[设置快捷键和初始焦点](/docs/zh-CN/plugins/mods/interface#set-a-hotkey-and-the-first-focus)。224使用 `focus: true` 打开窗格可为该窗格请求键盘焦点。`Input` 获得焦点后即可接收键入的字母。要选择窗格打开时哪个输入框获得焦点,请参阅[设置快捷键和初始焦点](/docs/zh-CN/plugins/mods/interface#set-a-hotkey-and-the-first-focus)。
263 225
264<h3 id="button">226### `Button`
265 `Button`
266</h3>
267 227
268按钮会运行 `onPress`。此示例展示了默认形式、带快捷键的 `plain` 按钮,以及一个暗淡的按钮:228按钮会运行 `onPress`。此示例展示了默认形式、带快捷键的 `plain` 按钮,以及一个暗淡的按钮:
269 229
278})238})
279```239```
280 240
281<img src="https://mintcdn.com/claude-code/EXkwf0kKMewZsyod/images/mods-el-button-light.png?fit=max&auto=format&n=EXkwf0kKMewZsyod&q=85&s=8c638c15e12d9736f327dfcaa797b512" className="dark:hidden" alt="一个包含三个按钮的窗格,每行一个:带方括号的 Save,不带方括号且 n 为彩色的 n: Next,以及带方括号的灰色 Skip。" width="1872" height="262" data-path="images/mods-el-button-light.png" />241
282
283<img src="https://mintcdn.com/claude-code/EXkwf0kKMewZsyod/images/mods-el-button-dark.png?fit=max&auto=format&n=EXkwf0kKMewZsyod&q=85&s=6a88a1fe18ba63b050366dcfab14be45" className="hidden dark:block" alt="一个包含三个按钮的窗格,每行一个:带方括号的 Save,不带方括号且 n 为彩色的 n: Next,以及带方括号的灰色 Skip。" width="1872" height="262" data-path="images/mods-el-button-dark.png" />
284 242
285获得焦点的按钮以反色绘制。此处用户已按了两次 Tab:243获得焦点的按钮以反色绘制。此处用户已按了两次 Tab:
286 244
287<img src="https://mintcdn.com/claude-code/EXkwf0kKMewZsyod/images/mods-el-button-plain-focused-light.png?fit=max&auto=format&n=EXkwf0kKMewZsyod&q=85&s=a6224e58d10752a894615047d9824ad9" className="dark:hidden" alt="同样的三个按钮,其中第二个按钮 n: Next 以反色绘制。" width="1872" height="262" data-path="images/mods-el-button-plain-focused-light.png" />245
288 246
289<img src="https://mintcdn.com/claude-code/EXkwf0kKMewZsyod/images/mods-el-button-plain-focused-dark.png?fit=max&auto=format&n=EXkwf0kKMewZsyod&q=85&s=9aeb7145615e77c84e7436180ed69e86" className="hidden dark:block" alt="同样的三个按钮,其中第二个按钮 n: Next 以反色绘制。" width="1872" height="262" data-path="images/mods-el-button-plain-focused-dark.png" />247### `Input`
290
291<h3 id="input">
292 `Input`
293</h3>
294 248
295`Input` 是单行文本输入框,用户按 Enter 时会运行 `onSubmit`:249`Input` 是单行文本输入框,用户按 Enter 时会运行 `onSubmit`:
296 250
307 261
308未获得焦点时,输入框显示其标签和占位文本:262未获得焦点时,输入框显示其标签和占位文本:
309 263
310<img src="https://mintcdn.com/claude-code/EXkwf0kKMewZsyod/images/mods-el-input-light.png?fit=max&auto=format&n=EXkwf0kKMewZsyod&q=85&s=7d580be1aaf5507032e1962b9167d725" className="dark:hidden" alt="一个只有一行的窗格:标签 Title,随后是灰色的占位文本 Type a title and press Enter。" width="1872" height="186" data-path="images/mods-el-input-light.png" />264
311
312<img src="https://mintcdn.com/claude-code/EXkwf0kKMewZsyod/images/mods-el-input-dark.png?fit=max&auto=format&n=EXkwf0kKMewZsyod&q=85&s=9d254a8adc5959ba173717fb45eabd52" className="hidden dark:block" alt="一个只有一行的窗格:标签 Title,随后是灰色的占位文本 Type a title and press Enter。" width="1872" height="186" data-path="images/mods-el-input-dark.png" />
313 265
314获得焦点后,标签变为粗体,出现光标,并在 `⏎` 之后显示 `submitLabel`:266获得焦点后,标签变为粗体,出现光标,并在 `⏎` 之后显示 `submitLabel`:
315 267
316<img src="https://mintcdn.com/claude-code/EXkwf0kKMewZsyod/images/mods-el-input-focused-light.png?fit=max&auto=format&n=EXkwf0kKMewZsyod&q=85&s=dcfcce0174480cc624d06c8521734fe7" className="dark:hidden" alt="同一个输入框,其标签为粗体,占位文本的第一个字母上有一个块状光标,并有一个回车符号,后跟单词 save。" width="1872" height="186" data-path="images/mods-el-input-focused-light.png" />268
317
318<img src="https://mintcdn.com/claude-code/EXkwf0kKMewZsyod/images/mods-el-input-focused-dark.png?fit=max&auto=format&n=EXkwf0kKMewZsyod&q=85&s=2f5cf7d0e5f813983070e883009f528e" className="hidden dark:block" alt="同一个输入框,其标签为粗体,占位文本的第一个字母上有一个块状光标,并有一个回车符号,后跟单词 save。" width="1872" height="186" data-path="images/mods-el-input-focused-dark.png" />
319 269
320键入内容会替换占位文本:270键入内容会替换占位文本:
321 271
322<img src="https://mintcdn.com/claude-code/EXkwf0kKMewZsyod/images/mods-el-input-typed-light.png?fit=max&auto=format&n=EXkwf0kKMewZsyod&q=85&s=4eb6d4443763a21415dad4e426bc747a" className="dark:hidden" alt="同一个输入框,其中包含已键入的字母 Rel,后跟回车符号和单词 save。" width="1872" height="186" data-path="images/mods-el-input-typed-light.png" />272
323 273
324<img src="https://mintcdn.com/claude-code/EXkwf0kKMewZsyod/images/mods-el-input-typed-dark.png?fit=max&auto=format&n=EXkwf0kKMewZsyod&q=85&s=90fbac3c7a47ab26a4fb71401975eac6" className="hidden dark:block" alt="同一个输入框,其中包含已键入的字母 Rel,后跟回车符号和单词 save。" width="1872" height="186" data-path="images/mods-el-input-typed-dark.png" />274### `Select`
325
326<h3 id="select">
327 `Select`
328</h3>
329 275
330`Select` 让用户从多个选项中选择一个,并以该选项的 `value` 运行 `onSelect`:276`Select` 让用户从多个选项中选择一个,并以该选项的 `value` 运行 `onSelect`:
331 277
347 293
348收起时,它显示其标签和当前选项:294收起时,它显示其标签和当前选项:
349 295
350<img src="https://mintcdn.com/claude-code/EXkwf0kKMewZsyod/images/mods-el-select-light.png?fit=max&auto=format&n=EXkwf0kKMewZsyod&q=85&s=4e3b18268ffd87d2cad06442e6d661a9" className="dark:hidden" alt="一个只有一行的窗格:标签 Format、当前选项 Markdown 以及一个小的向下箭头。" width="1872" height="186" data-path="images/mods-el-select-light.png" />296
351
352<img src="https://mintcdn.com/claude-code/EXkwf0kKMewZsyod/images/mods-el-select-dark.png?fit=max&auto=format&n=EXkwf0kKMewZsyod&q=85&s=1e329e6aee748c2dd70e92dbe4960de0" className="hidden dark:block" alt="一个只有一行的窗格:标签 Format、当前选项 Markdown 以及一个小的向下箭头。" width="1872" height="186" data-path="images/mods-el-select-dark.png" />
353 297
354展开时,它列出所有选项并标记其中一个:298展开时,它列出所有选项并标记其中一个:
355 299
356<img src="https://mintcdn.com/claude-code/EXkwf0kKMewZsyod/images/mods-el-select-moved-light.png?fit=max&auto=format&n=EXkwf0kKMewZsyod&q=85&s=deb6ce0a49d213235feedaa79ac658c0" className="dark:hidden" alt="展开的选择器,三个选项列在标签下方。第二个选项 HTML 以反色绘制。" width="1872" height="300" data-path="images/mods-el-select-moved-light.png" />300
357
358<img src="https://mintcdn.com/claude-code/EXkwf0kKMewZsyod/images/mods-el-select-moved-dark.png?fit=max&auto=format&n=EXkwf0kKMewZsyod&q=85&s=d69edeecd4f97dad4bdb39b908e3d98e" className="hidden dark:block" alt="展开的选择器,三个选项列在标签下方。第二个选项 HTML 以反色绘制。" width="1872" height="300" data-path="images/mods-el-select-moved-dark.png" />
359 301
360用户选择一个选项后,列表会收起:302用户选择一个选项后,列表会收起:
361 303
362<img src="https://mintcdn.com/claude-code/EXkwf0kKMewZsyod/images/mods-el-select-picked-light.png?fit=max&auto=format&n=EXkwf0kKMewZsyod&q=85&s=f065ab5bc479868f03088dc736f17097" className="dark:hidden" alt="再次收起的选择器,当前选项显示为 HTML。" width="1872" height="186" data-path="images/mods-el-select-picked-light.png" />304
363 305
364<img src="https://mintcdn.com/claude-code/EXkwf0kKMewZsyod/images/mods-el-select-picked-dark.png?fit=max&auto=format&n=EXkwf0kKMewZsyod&q=85&s=f084630e325825f3831219215a6a595e" className="hidden dark:block" alt="再次收起的选择器,当前选项显示为 HTML。" width="1872" height="186" data-path="images/mods-el-select-picked-dark.png" />306## 绘制图形
365 307
366<h2 id="draw-pictures">308### `Raster`
367 绘制图形
368</h2>
369
370<h3 id="raster">
371 `Raster`
372</h3>
373 309
374`Raster` 是由彩色字符单元格组成的网格,可用于热力图、迷你折线图或游戏棋盘。由终端负责绘制。此示例使用了起始模块中的 `cellsOf` 函数,该函数会将单元格打包成 `Raster` 所需的字符串。[绘制彩色单元格网格](/docs/zh-CN/plugins/mods/interface#draw-a-grid-of-colored-cells)对此进行了说明:310`Raster` 是由彩色字符单元格组成的网格,可用于热力图、迷你折线图或游戏棋盘。由终端负责绘制。此示例使用了起始模块中的 `cellsOf` 函数,该函数会将单元格打包成 `Raster` 所需的字符串。[绘制彩色单元格网格](/docs/zh-CN/plugins/mods/interface#draw-a-grid-of-colored-cells)对此进行了说明:
375 311
385})321})
386```322```
387 323
388<img src="https://mintcdn.com/claude-code/EXkwf0kKMewZsyod/images/mods-el-raster-light.png?fit=max&auto=format&n=EXkwf0kKMewZsyod&q=85&s=5ed719481d3dd45b568bab696e57bf16" className="dark:hidden" alt="一个窗格,包含一个由彩色方块组成的小网格,共两行,每行三个:绿色、琥珀色和红色,然后是绿色、绿色和琥珀色。" width="1872" height="224" data-path="images/mods-el-raster-light.png" />324
389
390<img src="https://mintcdn.com/claude-code/EXkwf0kKMewZsyod/images/mods-el-raster-dark.png?fit=max&auto=format&n=EXkwf0kKMewZsyod&q=85&s=b381f05d4cc99e2abfacb505c77b17f5" className="hidden dark:block" alt="一个窗格,包含一个由彩色方块组成的小网格,共两行,每行三个:绿色、琥珀色和红色,然后是绿色、绿色和琥珀色。" width="1872" height="224" data-path="images/mods-el-raster-dark.png" />
391 325
392`Raster` 会将每种颜色近似到一个较小的调色板,因此 `0x2e7d32` 会绘制为 `#337733`。326`Raster` 会将每种颜色近似到一个较小的调色板,因此 `0x2e7d32` 会绘制为 `#337733`。
393 327
394<h3 id="svg">328### `Svg`
395 `Svg`
396</h3>
397 329
398`Svg` 在 Desktop 应用和 VS Code 扩展中绘制 SVG 文档:330`Svg` 在 Desktop 应用和 VS Code 扩展中绘制 SVG 文档:
399 331
409 341
410在终端中,仅返回 `Svg` 的窗格打开后是空的。要在那里绘制其他内容,请检查 [`e.surface`](/docs/zh-CN/plugins/mods/interface#pick-where-to-draw) 并返回不同的元素树。342在终端中,仅返回 `Svg` 的窗格打开后是空的。要在那里绘制其他内容,请检查 [`e.surface`](/docs/zh-CN/plugins/mods/interface#pick-where-to-draw) 并返回不同的元素树。
411 343
412<h3 id="image-and-client">344### `Image` 和 `Client`
413 `Image` 和 `Client`
414</h3>
415 345
416另有两个元素在此没有示例。`Image` 在终端中绘制 PNG 或原始像素。`Client` 是由您的另一个文件负责绘制的区域,用于动画和指针输入。[元素参考](/docs/zh-CN/plugins/mods/reference#elements)列出了它们的 props。346另有两个元素在此没有示例。`Image` 在终端中绘制 PNG 或原始像素。`Client` 是由您的另一个文件负责绘制的区域,用于动画和指针输入。[元素参考](/docs/zh-CN/plugins/mods/reference#elements)列出了它们的 props。
417 347
423 353
424如果您的 mod 的用户在确实能够绘制这些占位符图像的终端中看到了暗色文本,可以将 [`CLAUDE_CODE_FORCE_TERMINAL_IMAGES`](/docs/zh-CN/env-vars) 设置为 `1`,以跳过检测。在 tmux 或 screen 中这样做并无帮助:`alt` 文本会消失,而 Claude Code 发送图片时不会为 tmux 或 screen 直通对其进行包装。354如果您的 mod 的用户在确实能够绘制这些占位符图像的终端中看到了暗色文本,可以将 [`CLAUDE_CODE_FORCE_TERMINAL_IMAGES`](/docs/zh-CN/env-vars) 设置为 `1`,以跳过检测。在 tmux 或 screen 中这样做并无帮助:`alt` 文本会消失,而 Claude Code 发送图片时不会为 tmux 或 screen 直通对其进行包装。
425 355
426<h2 id="see-where-a-mod-can-draw">356## 了解 mod 可以在哪里绘制
427 了解 mod 可以在哪里绘制
428</h2>
429 357
430这些示例都在窗格中绘制。mod 还可以在其他位置绘制,并可调用 Claude Code 为其显示内容:358这些示例都在窗格中绘制。mod 还可以在其他位置绘制,并可调用 Claude Code 为其显示内容:
431 359
434* **Toast 通知、状态栏和日志行**:[在不开启轮次的情况下显示内容](/docs/zh-CN/plugins/mods/api#show-something-without-starting-a-turn)362* **Toast 通知、状态栏和日志行**:[在不开启轮次的情况下显示内容](/docs/zh-CN/plugins/mods/api#show-something-without-starting-a-turn)
435* **问题对话框**:[暂停工具调用直到用户做出决定](/docs/zh-CN/plugins/mods/events#hold-a-tool-call-until-the-user-decides)363* **问题对话框**:[暂停工具调用直到用户做出决定](/docs/zh-CN/plugins/mods/events#hold-a-tool-call-until-the-user-decides)
436 364
437<h2 id="next-steps">365## 后续步骤
438 后续步骤
439</h2>
440 366
441* [在界面中绘制](/docs/zh-CN/plugins/mods/interface):逐步构建一个带标签页的窗格367* [在界面中绘制](/docs/zh-CN/plugins/mods/interface):逐步构建一个带标签页的窗格
442* [测试绘制结果](/docs/zh-CN/plugins/mods/test#test-a-drawing):在测试中按下您的按钮368* [测试绘制结果](/docs/zh-CN/plugins/mods/test#test-a-drawing):在测试中按下您的按钮