Interface gallery for mods changedplugins/mods/gallery
Nearest release: v2.1.302, published 4 hours before upstream edited the page. Shown because the two are within 24 hours of each other. Nothing here says the release caused the edit.
Upstream edited this page at 16 Oct 2026 21:17 UTC, give or take a minute or two: the time comes from Anthropic’s own sitemap rather than from a commit. This site recorded the change at 20 Oct 2026 18:37 UTC.
Upstream edited
Recorded here
Lines+86added
Lines−118removed
From line
12
where the diff opens
First seen
1 Oct 2026
this site's first read of the page
Recorded edits6to this page, all time
The whole hunk
from line 12, old and new numbered
/
from line 12
1212
1313To see a sample in your own terminal, create the small mod in these steps and paste the sample into it. The mod adds a `/gallery` command that opens a pane and draws the sample there. A [pane](/docs/en/plugins/mods/interface#pick-where-to-draw) is a sidebar beside the transcript in a wide fullscreen terminal, or a framed region above the prompt otherwise.
1414
15<Steps>
16 <Step title="Create the mod">
17 Create a directory named `gallery` with `.claude-plugin` and `hooks` directories inside it. [Create a mod](/docs/en/plugins/mods/create#write-a-mod-yourself) explains the files.
15**1. Create the mod**
1816
19 Save the manifest as `gallery/.claude-plugin/plugin.json`:
17Create a directory named `gallery` with `.claude-plugin` and `hooks` directories inside it. [Create a mod](/docs/en/plugins/mods/create#write-a-mod-yourself) explains the files.
2018
21 ```json gallery/.claude-plugin/plugin.json theme={null}
22 {
23 "name": "gallery",
24 "version": "0.1.0",
25 "description": "Opens a pane that draws one sample",
26 "author": { "name": "Your Name" }
27 }
28 ```
19Save the manifest as `gallery/.claude-plugin/plugin.json`:
2920
30 Name your entry point in `gallery/hooks/hooks.json`:
21```json gallery/.claude-plugin/plugin.json theme={null}
22{
23 "name": "gallery",
24 "version": "0.1.0",
25 "description": "Opens a pane that draws one sample",
26 "author": { "name": "Your Name" }
27}
28```
3129
32 ```json gallery/hooks/hooks.json theme={null}
33 {
34 "modules": ["./register.js"]
35 }
36 ```
30Name your entry point in `gallery/hooks/hooks.json`:
3731
38 Save the code as `gallery/hooks/register.js`. It adds a `/gallery` command that opens a pane, and draws `Plain text` in that pane:
32```json gallery/hooks/hooks.json theme={null}
33{
34 "modules": ["./register.js"]
35}
36```
3937
40 ```javascript gallery/hooks/register.js theme={null}
41 // Stands in for your own callback in the samples that take one
42 const noop = () => {}
43 // The Select sample keeps its choice here
44 let picked = 'md'
38Save the code as `gallery/hooks/register.js`. It adds a `/gallery` command that opens a pane, and draws `Plain text` in that pane:
4539
46 // The Raster sample packs its cells with this function
47 const DEFAULT_COLOR = 0x01000000
48 function cellsOf(rows) {
49 const numbers = rows.flat().flatMap(([char, color]) => [char.codePointAt(0), color, DEFAULT_COLOR])
50 return new Uint8Array(Uint32Array.from(numbers).buffer).toBase64()
51 }
40```javascript gallery/hooks/register.js theme={null}
41// Stands in for your own callback in the samples that take one
42const noop = () => {}
43// The Select sample keeps its choice here
44let picked = 'md'
5245
53 export function register(on) {
54 on('session.start', async ($, e, next) => {
55 await $.command.register({ name: 'gallery', description: 'Open the sample pane' })
56 return next(e)
57 })
46// The Raster sample packs its cells with this function
47const DEFAULT_COLOR = 0x01000000
48function cellsOf(rows) {
49 const numbers = rows.flat().flatMap(([char, color]) => [char.codePointAt(0), color, DEFAULT_COLOR])
50 return new Uint8Array(Uint32Array.from(numbers).buffer).toBase64()
51}
5852
59 on('command.run', { command: 'gallery' }, async ($) => {
60 await $.ui.open({ id: 'gallery', focus: true, closeOnEscape: true })
61 return {}
62 })
53export function register(on) {
54 on('session.start', async ($, e, next) => {
55 await $.command.register({ name: 'gallery', description: 'Open the sample pane' })
56 return next(e)
57 })
6358
64 on('ui.render', { component: 'Pane' }, async ($, e, next) => {
65 if (e.requestId !== 'gallery') return next(e)
66 const { Box, Text, Button, Input, Select, Link, Markdown, Code, Raster, Svg } = $.ui.resolve(e)
67 // Replace the element after return with a sample
68 return Text({ children: ['Plain text'] })
69 })
70 }
71 ```
72 </Step>
59 on('command.run', { command: 'gallery' }, async ($) => {
60 await $.ui.open({ id: 'gallery', focus: true, closeOnEscape: true })
61 return {}
62 })
7363
74 <Step title="Run the mod">
75 In your shell, start Claude Code from the directory that holds `gallery`:
64 on('ui.render', { component: 'Pane' }, async ($, e, next) => {
65 if (e.requestId !== 'gallery') return next(e)
66 const { Box, Text, Button, Input, Select, Link, Markdown, Code, Raster, Svg } = $.ui.resolve(e)
67 // Replace the element after return with a sample
68 return Text({ children: ['Plain text'] })
69 })
70}
71```
7672
77 ```bash theme={null}
78 claude --plugin-dir ./gallery
79 ```
73**2. Run the mod**
8074
81 At the Claude Code prompt, run `/gallery`. A pane opens with `Plain text` in it.
82 </Step>
75In your shell, start Claude Code from the directory that holds `gallery`:
8376
84 <Step title="Swap in a sample">
85 Copy a sample from this page. In `register.js`, paste it over `Text({ children: ['Plain text'] })`, so that it follows `return`, and save the file. Claude Code reloads the module each time you save, so run `/gallery` again to see the new sample.
86 </Step>
87</Steps>
77```bash theme={null}
78claude --plugin-dir ./gallery
79```
8880
81At the Claude Code prompt, run `/gallery`. A pane opens with `Plain text` in it.
82
83**3. Swap in a sample**
84
85Copy a sample from this page. In `register.js`, paste it over `Text({ children: ['Plain text'] })`, so that it follows `return`, and save the file. Claude Code reloads the module each time you save, so run `/gallery` again to see the new sample.
86
8987## Pick an element
9088
9189The samples are grouped by what you want to put on screen:
from line 119
121119})
122120```
123121
124<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="A pane with nine lines of text, each named for its style: plain, bold, italic, underline, strikethrough, dimColor in gray, inverse, color red, and backgroundColor blue." width="1872" height="490" data-path="images/mods-el-text-light.png" />
122
125123
126<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="A pane with nine lines of text, each named for its style: plain, bold, italic, underline, strikethrough, dimColor in gray, inverse, color red, and backgroundColor blue." width="1872" height="490" data-path="images/mods-el-text-dark.png" />
127
128124`dimColor` draws the text in gray. `backgroundColor` fills only as wide as the text.
129125
130126### `Markdown`
from line 133
137133})
138134```
139135
140<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="A pane with a bold heading, Release notes, then a sentence with one bold word and one colored code word, a two-item list, and a quote drawn in italics with a bar on its left." width="1872" height="452" data-path="images/mods-el-markdown-light.png" />
136
141137
142<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="A pane with a bold heading, Release notes, then a sentence with one bold word and one colored code word, a two-item list, and a quote drawn in italics with a bar on its left." width="1872" height="452" data-path="images/mods-el-markdown-dark.png" />
143
144138A heading draws in bold without its `#` marks. Inline code draws in color without its backticks. A quote draws in italics with a bar on its left.
145139
146140### `Link`
from line 145
151145Link({ href: 'https://code.claude.com/docs', label: 'Claude Code docs' })
152146```
153147
154<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="A pane with one line: the label Claude Code docs, then the URL in gray." width="1872" height="186" data-path="images/mods-el-link-light.png" />
148
155149
156<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="A pane with one line: the label Claude Code docs, then the URL in gray." width="1872" height="186" data-path="images/mods-el-link-dark.png" />
157
158150The terminal draws the URL as text after the label. Whether a click opens it depends on the user's terminal.
159151
160152## Show code and changes
from line 165
173165})
174166```
175167
176<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="A pane with two numbered lines of JavaScript in syntax colors." width="1872" height="224" data-path="images/mods-el-code-light.png" />
168
177169
178<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="A pane with two numbered lines of JavaScript in syntax colors." width="1872" height="224" data-path="images/mods-el-code-dark.png" />
179
180170The colors come from the user's theme.
181171
182172### `Code` as a diff
from line 180
190180})
191181```
192182
193<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="A pane with a four-line diff. The removed line is shaded red and the added line green, each with its line number. In the added line, the words that runs code have a stronger shade." width="1872" height="300" data-path="images/mods-el-diff-light.png" />
183
194184
195<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="A pane with a four-line diff. The removed line is shaded red and the added line green, each with its line number. In the added line, the words that runs code have a stronger shade." width="1872" height="300" data-path="images/mods-el-diff-dark.png" />
196
197185Claude Code draws line numbers in place of the `@@` line. Where a removed line and an added line are alike, the words that changed get a stronger shade.
198186
199187## Arrange elements
from line 209
221209})
222210```
223211
224<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="A pane with three words in a row, four columns apart, then a blank row, then a rounded border around one line of text. The border runs the full width of the pane." width="1872" height="338" data-path="images/mods-el-box-light.png" />
212
225213
226<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="A pane with three words in a row, four columns apart, then a blank row, then a rounded border around one line of text. The border runs the full width of the pane." width="1872" height="338" data-path="images/mods-el-box-dark.png" />
227
228214The border stretches to the width of the pane.
229215
230216## Take input
from line 234
248234})
249235```
250236
251<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="A pane with three buttons, one per line: Save in brackets, n: Next without brackets and with the n in color, and Skip in brackets in gray." width="1872" height="262" data-path="images/mods-el-button-light.png" />
237
252238
253<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="A pane with three buttons, one per line: Save in brackets, n: Next without brackets and with the n in color, and Skip in brackets in gray." width="1872" height="262" data-path="images/mods-el-button-dark.png" />
254
255239A button that has the focus draws in inverse video. Here the user has pressed Tab twice:
256240
257<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="The same three buttons, with the second one, n: Next, drawn in inverse video." width="1872" height="262" data-path="images/mods-el-button-plain-focused-light.png" />
241
258242
259<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="The same three buttons, with the second one, n: Next, drawn in inverse video." width="1872" height="262" data-path="images/mods-el-button-plain-focused-dark.png" />
260
261243### `Input`
262244
263245An `Input` is a one-line text field that runs `onSubmit` when the user presses Enter:
from line 257
275257
276258Without the focus, the field shows its label and its placeholder:
277259
278<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="A pane with one line: the label Title, then the placeholder Type a title and press Enter in gray." width="1872" height="186" data-path="images/mods-el-input-light.png" />
260
279261
280<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="A pane with one line: the label Title, then the placeholder Type a title and press Enter in gray." width="1872" height="186" data-path="images/mods-el-input-dark.png" />
281
282262With the focus, the label turns bold, a cursor appears, and the `submitLabel` shows after `⏎`:
283263
284<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="The same field with its label in bold, a block cursor on the first letter of the placeholder, and a return sign followed by the word save." width="1872" height="186" data-path="images/mods-el-input-focused-light.png" />
264
285265
286<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="The same field with its label in bold, a block cursor on the first letter of the placeholder, and a return sign followed by the word save." width="1872" height="186" data-path="images/mods-el-input-focused-dark.png" />
287
288266Typing replaces the placeholder:
289267
290<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="The same field holding the typed letters Rel, followed by the return sign and the word save." width="1872" height="186" data-path="images/mods-el-input-typed-light.png" />
268
291269
292<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="The same field holding the typed letters Rel, followed by the return sign and the word save." width="1872" height="186" data-path="images/mods-el-input-typed-dark.png" />
293
294270### `Select`
295271
296272A `Select` lets the user pick one of several options, and runs `onSelect` with the option's `value`:
from line 289
313289
314290Closed, it shows its label and the current option:
315291
316<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="A pane with one line: the label Format, the current option Markdown, and a small down arrow." width="1872" height="186" data-path="images/mods-el-select-light.png" />
292
317293
318<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="A pane with one line: the label Format, the current option Markdown, and a small down arrow." width="1872" height="186" data-path="images/mods-el-select-dark.png" />
319
320294Open, it lists its options and marks one:
321295
322<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="The picker open, with its three options listed under the label. The second option, HTML, is drawn in inverse video." width="1872" height="300" data-path="images/mods-el-select-moved-light.png" />
296
323297
324<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="The picker open, with its three options listed under the label. The second option, HTML, is drawn in inverse video." width="1872" height="300" data-path="images/mods-el-select-moved-dark.png" />
325
326298After the user picks an option, the list closes:
327299
328<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="The picker closed again, now showing HTML as the current option." width="1872" height="186" data-path="images/mods-el-select-picked-light.png" />
300
329301
330<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="The picker closed again, now showing HTML as the current option." width="1872" height="186" data-path="images/mods-el-select-picked-dark.png" />
331
332302## Draw pictures
333303
334304### `Raster`
from line 317
347317})
348318```
349319
350<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="A pane with a small grid of colored blocks, two rows of three: green, amber, and red, then green, green, and amber." width="1872" height="224" data-path="images/mods-el-raster-light.png" />
351
352<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="A pane with a small grid of colored blocks, two rows of three: green, amber, and red, then green, green, and amber." width="1872" height="224" data-path="images/mods-el-raster-dark.png" />
320
353321
354322A `Raster` rounds each color to a smaller palette, so `0x2e7d32` draws as `#337733`.
355323
No line in this hunk matches that.