Galleria dell'interfaccia per i mod
Scopri gli elementi dell'interfaccia che un mod di Claude Code può disegnare, come testo, pulsanti, campi, Markdown, codice e diff, con codice di esempio e screenshot del terminale.
Un mod disegna la sua interfaccia a partire da elementi: testo, riquadri, pulsanti, campi e alcuni elementi che formattano il contenuto al posto tuo. Gli esempi qui mostrano il codice che disegna un elemento, e la maggior parte è accompagnata da uno screenshot del risultato in un riquadro del terminale, così puoi scegliere un elemento in base al suo aspetto.
Per capire come funziona il disegno, inizia da Disegnare nell'interfaccia. Per le prop principali e per sapere quali app disegnano ciascun elemento, consulta il riferimento degli elementi. Le dichiarazioni dei tipi elencano tutte le prop.
Prova un esempio
Gli esempi in questa pagina sono frammenti, non mod completi. Ognuno è il codice di un elemento e di tutto ciò che è annidato al suo interno.
Per vedere un esempio nel tuo terminale, crea il piccolo mod seguendo questi passaggi e incollaci l'esempio. Il mod aggiunge un comando /gallery che apre un riquadro e vi disegna l'esempio. Un riquadro è una barra laterale accanto alla trascrizione in un terminale a schermo intero sufficientemente largo, oppure, negli altri casi, un'area delimitata sopra il prompt.
1. Crea il mod
Crea una directory chiamata gallery con le directory .claude-plugin e hooks al suo interno. Crea un mod spiega i file.
Salva il manifest come gallery/.claude-plugin/plugin.json:
{
"name": "gallery",
"version": "0.1.0",
"description": "Opens a pane that draws one sample",
"author": { "name": "Your Name" }
}
Indica il tuo punto di ingresso in gallery/hooks/hooks.json:
{
"modules": ["./register.js"]
}
Salva il codice come gallery/hooks/register.js. Aggiunge un comando /gallery che apre un riquadro e disegna Plain text in quel riquadro:
// Stands in for your own callback in the samples that take one
const noop = () => {}
// The Select sample keeps its choice here
let picked = 'md'
// The Raster sample packs its cells with this function
const DEFAULT_COLOR = 0x01000000
function cellsOf(rows) {
const numbers = rows.flat().flatMap(([char, color]) => [char.codePointAt(0), color, DEFAULT_COLOR])
return new Uint8Array(Uint32Array.from(numbers).buffer).toBase64()
}
export function register(on) {
on('session.start', async ($, e, next) => {
await $.command.register({ name: 'gallery', description: 'Open the sample pane' })
return next(e)
})
on('command.run', { command: 'gallery' }, async ($) => {
await $.ui.open({ id: 'gallery', focus: true, closeOnEscape: true })
return {}
})
on('ui.render', { component: 'Pane' }, async ($, e, next) => {
if (e.requestId !== 'gallery') return next(e)
const { Box, Text, Button, Input, Select, Link, Markdown, Code, Raster, Svg } = $.ui.resolve(e)
// Replace the element after return with a sample
return Text({ children: ['Plain text'] })
})
}
2. Esegui il mod
Nella tua shell, avvia Claude Code dalla directory che contiene gallery:
claude --plugin-dir ./gallery
Al prompt di Claude Code, esegui /gallery. Si apre un riquadro con Plain text al suo interno.
3. Sostituisci con un esempio
Copia un esempio da questa pagina. In register.js, incollalo al posto di Text({ children: ['Plain text'] }), in modo che segua return, e salva il file. Claude Code ricarica il modulo ogni volta che salvi, quindi esegui di nuovo /gallery per vedere il nuovo esempio.
Scegli un elemento
Gli esempi sono raggruppati in base a ciò che vuoi mostrare sullo schermo:
- Mostrare testo:
Text,MarkdowneLink - Mostrare codice e modifiche:
Code - Disporre gli elementi:
Box - Ricevere input:
Button,InputeSelect - Disegnare immagini:
Raster,Svg,ImageeClient
Mostrare testo
Tre elementi mettono parole sullo schermo: Text per uno stile personalizzato, Markdown per contenuti già formattati e Link per un URL.
Text
Text disegna una stringa con gli stili che gli assegni. Questo esempio mostra testo semplice e otto stili, uno per riga:
Box({
flexDirection: 'column',
children: [
Text({ children: ['Plain text'] }),
Text({ bold: true, children: ['bold'] }),
Text({ italic: true, children: ['italic'] }),
Text({ underline: true, children: ['underline'] }),
Text({ strikethrough: true, children: ['strikethrough'] }),
Text({ dimColor: true, children: ['dimColor'] }),
Text({ inverse: true, children: ['inverse'] }),
Text({ color: 'red', children: ["color: 'red'"] }),
Text({ backgroundColor: 'blue', children: ["backgroundColor: 'blue'"] }),
],
})

dimColor disegna il testo in grigio. backgroundColor riempie solo la larghezza del testo.
Markdown
Markdown formatta il testo nello stesso modo in cui vengono formattate le risposte di Claude. Passa il contenuto in text, non in children:
Markdown({
text: '## Release notes\n\nThis build has **two** fixes and one `flag`:\n\n- Faster start\n- Fewer prompts\n\n> Quoted text',
})

Un titolo viene disegnato in grassetto senza i simboli #. Il codice inline viene disegnato a colori senza i backtick. Una citazione viene disegnata in corsivo con una barra alla sua sinistra.
Link
Link disegna un'etichetta seguita dal suo URL:
Link({ href: 'https://code.claude.com/docs', label: 'Claude Code docs' })

Il terminale disegna l'URL come testo dopo l'etichetta. Il fatto che un clic lo apra dipende dal terminale dell'utente.
Mostrare codice e modifiche
Code disegna il testo sorgente con i colori di sintassi propri di Claude Code, oppure un diff. Nell'estensione VS Code, Code mostra il suo source come testo semplice, senza i colori, i numeri di riga o l'ombreggiatura del diff visibili in questi screenshot.
Code
Specifica il language, oppure passa un path da cui Claude Code possa dedurlo. Con startLine, le righe vengono numerate a partire da quel numero:
Code({
language: 'javascript',
startLine: 1,
source: "const name = 'mods'\nconsole.log('hello ' + name)",
})

I colori provengono dal tema dell'utente.
Code come diff
Con format: 'diff', source è costituito da uno o più hunk di diff unificato:
Code({
format: 'diff',
source: '@@ -1,3 +1,3 @@\n # Mods\n-A mod is a plugin.\n+A mod is a plugin that runs code.\n Read on.',
})

Claude Code disegna i numeri di riga al posto della riga @@. Quando una riga rimossa e una riga aggiunta sono simili, le parole modificate ricevono un'ombreggiatura più intensa.
Disporre gli elementi
Box
Box dispone ciò che contiene in una riga o in una colonna e può disegnare un bordo. Questo esempio posiziona una riga di parole sopra un riquadro con bordo:
Box({
flexDirection: 'column',
gap: 1,
children: [
Box({
flexDirection: 'row',
columnGap: 4,
children: [Text({ children: ['a row'] }), Text({ children: ['of three'] }), Text({ children: ['items'] })],
}),
Box({
borderStyle: 'round',
paddingX: 1,
children: [Text({ children: ["borderStyle: 'round'"] })],
}),
],
})

Il bordo si estende fino alla larghezza del pannello.
Ricevere input
Button, Input e Select sono controlli: l'utente si sposta tra di essi con Tab e usa quello che ha il focus. Focus della tastiera e tasti di scelta rapida spiega quali tasti li raggiungono.
Apri un pannello con focus: true per richiedere il focus della tastiera per il pannello. Le lettere digitate raggiungono un Input una volta che ha il focus. Per scegliere quale campo ha il focus quando il pannello si apre, consulta Impostare un tasto di scelta rapida e il primo focus.
Button
Un pulsante esegue onPress. Questo esempio mostra la forma predefinita, un pulsante plain con un tasto di scelta rapida e uno attenuato:
Box({
flexDirection: 'column',
children: [
Button({ key: 'save', label: 'Save', onPress: noop }),
Button({ key: 'next', label: 'Next', hotkey: 'n', plain: true, onPress: noop }),
Button({ key: 'skip', label: 'Skip', dimColor: true, onPress: noop }),
],
})

Un pulsante che ha il focus viene disegnato in video inverso. Qui l'utente ha premuto Tab due volte:

Input
Un Input è un campo di testo che esegue onSubmit quando l'utente preme Invio. Contiene una sola riga a meno che tu non gli assegni rows:
Input({
key: 'title',
label: 'Title',
placeholder: 'Type a title and press Enter',
value: '',
submitLabel: 'save',
onSubmit: noop,
})
Senza il focus, il campo mostra la sua etichetta e il suo placeholder:

Con il focus, l'etichetta diventa in grassetto, compare un cursore e il submitLabel viene mostrato dopo ⏎:

La digitazione sostituisce il placeholder:

Aggiungi rows per un campo che contiene più righe, come una nota o un messaggio di commit:
Input({
key: 'note',
label: 'Note',
placeholder: 'Write a note',
rows: 4,
onSubmit: noop,
})
Qualunque cosa contenga, il campo occupa quel numero di righe, fino all'altezza del pannello o della fascia in cui viene disegnato. Il testo più lungo scorre al suo interno.
- Invio continua a inviare. Nel terminale, l'utente inizia una nuova riga digitando una barra rovesciata e poi premendo Invio, oppure premendo Shift+Invio dove l'emulatore di terminale lo supporta. Sono gli stessi tasti del prompt.
- Su e Giù spostano tra le righe del campo. Dalla prima e dall'ultima riga spostano al controllo precedente o successivo.
onSubmiteonInputricevono l'intero testo con le righe unite da\n.
Il terminale e l'app Desktop disegnano le righe. Nell'estensione VS Code, il campo contiene una sola riga.
Select
Un Select consente all'utente di scegliere una tra diverse opzioni ed esegue onSelect con il value dell'opzione:
Select({
key: 'format',
label: 'Format',
value: picked,
options: [
{ value: 'md', label: 'Markdown' },
{ value: 'html', label: 'HTML' },
{ value: 'txt', label: 'Plain text' },
],
onSelect: (value) => {
picked = value
},
})
Da chiuso, mostra la sua etichetta e l'opzione corrente:

Da aperto, elenca le sue opzioni e ne evidenzia una:

Dopo che l'utente ha scelto un'opzione, l'elenco si chiude:

Disegnare immagini
Raster
Un Raster è una griglia di celle di caratteri colorate, per una mappa di calore, una sparkline o una plancia di gioco. Lo disegna il terminale. Questo esempio usa la funzione cellsOf del modulo iniziale, che comprime le celle nella stringa accettata da un Raster. Disegnare una griglia di celle colorate la spiega:
Raster({
key: 'grid',
columns: 3,
rows: 2,
cells: cellsOf([
[['█', 0x2e7d32], ['█', 0xf9a825], ['█', 0xc62828]],
[['█', 0x2e7d32], ['█', 0x2e7d32], ['█', 0xf9a825]],
]),
})

Un Raster arrotonda ogni colore a una tavolozza più ridotta, quindi 0x2e7d32 viene disegnato come #337733.
Svg
Un Svg disegna un documento SVG nell'app Desktop e nell'estensione VS Code:
Svg({
alt: 'Three bars of rising height',
width: 120,
height: 60,
source:
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 120 60"><rect x="10" y="40" width="20" height="20" fill="#2e7d32"/><rect x="50" y="25" width="20" height="35" fill="#f9a825"/><rect x="90" y="5" width="20" height="55" fill="#c62828"/></svg>',
})
Nel terminale, un riquadro che restituisce solo un Svg si apre vuoto. Per disegnare qualcos'altro lì, controlla e.surface e restituisci un albero diverso.
Image e Client
Altri due elementi non hanno un esempio qui. Image disegna un PNG o pixel grezzi nel terminale. Client è una regione disegnata da un tuo secondo file, per animazioni e input del puntatore. Il riferimento degli elementi elenca le loro prop.
Un Image viene disegnato come immagine in questi terminali:
- kitty 0.28 o successivo
- Ghostty
- iTerm2 3.5 o successivo. Il disegno in iTerm2 richiede Claude Code v2.1.305 o successivo.
In qualsiasi altro terminale, l'utente vede il testo alt dell'Image, attenuato, al posto dell'immagine. Scrivi un testo alt che si regga da solo, perché viene mostrato anche in questi casi, tra gli altri:
- GNU screen: una sessione eseguita all'interno di screen, in qualsiasi terminale.
- tmux: una sessione eseguita all'interno di tmux che non soddisfa un requisito per disegnare all'interno di tmux.
- Sessioni in background: ogni sessione in background, qualunque sia il terminale da cui è collegata.
- iTerm2 al di fuori del rendering a schermo intero: in iTerm2 l'immagine viene disegnata solo con il rendering a schermo intero, e non mentre
CLAUDE_CODE_ALT_SCREEN_FULL_REPAINTè impostata su1. Per vedere l'immagine, esegui/tui fullscreennel prompt di Claude Code e lascia quella variabile non impostata. - Un percorso di file come sorgente in iTerm2 o tmux: in iTerm2 e all'interno di tmux, un
Imagela cuisourceindica unfilemostra il testoaltal posto dell'immagine. Se il tuo mod ha utenti iTerm2 o tmux, passa l'immagine in base64 insource.pngosource.rgbaanziché come percorso insource.file.
Se gli utenti del tuo mod vedono il testo attenuato in un terminale che disegna immagini del protocollo grafico di kitty con segnaposto Unicode, possono impostare CLAUDE_CODE_FORCE_TERMINAL_IMAGES su 1. Non dovrebbero impostarla all'interno di GNU screen, all'interno di tmux precedente alla 3.3, in un popup di tmux o con l'opzione allow-passthrough di tmux disattivata. In questi casi non vedono alcuna immagine e compare un riquadro al posto del testo alt.
Disegnare un Image all'interno di tmux
Se un Image mostra il suo testo alt all'interno di tmux, verifica questi requisiti insieme agli altri casi del testo alt, come una sessione in background:
- Claude Code v2.1.310 o successivo
- tmux 3.3 o successivo
- Claude Code viene eseguito in un riquadro di tmux, non in un popup di tmux
- tmux viene eseguito all'interno di kitty 0.28 o successivo, Ghostty o iTerm2 3.5 o successivo
- Le opzioni di tmux
focus-eventseallow-passthroughsono impostate suon. All'interno di kitty o Ghostty,allow-passthroughpuò anche essereall. - All'interno di iTerm2, tmux viene eseguito senza
-CC, il rendering a schermo intero è attivo eCLAUDE_CODE_ALT_SCREEN_FULL_REPAINTnon è impostata. - All'interno di iTerm2, la finestra di tmux non è più grande della finestra di iTerm2. Per verificarlo, esegui
tmux display-message -p '#{window_bigger}'in quella finestra di tmux. Se stampa1, adatta la finestra di tmux, poi riavvia Claude Code. - L'autore del mod passa l'immagine come byte
pngorgba, non come percorsofile. Se usi un mod che non hai scritto tu e gli altri requisiti sono soddisfatti, chiedi al suo autore di verificare questo.
Per ogni opzione di tmux che non è già impostata come richiesto, esegui il relativo comando nella tua shell:
tmux set -g allow-passthrough on
tmux set -g focus-events on
Poi scollegati da tmux, ricollegati e riavvia Claude Code. Riavvialo di nuovo ogni volta che colleghi tmux da un terminale diverso. Per mantenere entrambe le opzioni tra i riavvii del server tmux, aggiungi entrambe le righe anche a ~/.tmux.conf.
Scopri dove un mod può disegnare
Gli esempi disegnano tutti in un pannello. Un mod può anche disegnare in altri punti e chiamare Claude Code perché mostri qualcosa al posto suo:
- Pannello e banda: Scegli dove disegnare
- Le righe di Claude Code stesso, come lo spinner: Modifica ciò che Claude Code disegna già
- Toast, riga di stato e riga di log: Mostra qualcosa senza avviare un turno
- Finestra di dialogo con domanda: Trattieni una chiamata a uno strumento finché l'utente non decide
Passaggi successivi
- Disegna nell'interfaccia: crea un pannello con schede, passo dopo passo
- Testa un disegno: premi i tuoi pulsanti da un test
- Riferimento agli elementi: le prop principali di ogni elemento e le app che lo disegnano