SpyBara
Go Premium

plugins/mods/gallery.md 2026-10-01 23:59 UTC to 2026-10-02 16:57 UTC

This page contains 435 additions and 0 deletions.

2026
Fri 2 18:59

Galeria de interface para mods

Veja os elementos de interface que um mod do Claude Code pode desenhar, como texto, botões, campos, Markdown, código e diffs, com código de exemplo e capturas de tela do terminal.

Um mod desenha sua interface a partir de elementos: texto, caixas, botões, campos e alguns que formatam o conteúdo para você. Os exemplos aqui mostram o código que desenha um elemento, e a maioria vem com uma captura de tela do resultado em um painel do terminal, para que você possa escolher um elemento pela aparência.

Para aprender como o desenho funciona, comece com Desenhar na interface. Para as principais props e quais aplicativos desenham cada elemento, consulte a referência de elementos. As declarações de tipo listam todas as props.

Experimentar um exemplo

Os exemplos nesta página são trechos, não mods inteiros. Cada um é o código de um elemento e de tudo o que está aninhado dentro dele.

Para ver um exemplo no seu próprio terminal, crie o pequeno mod destas etapas e cole o exemplo nele. O mod adiciona um comando /gallery que abre um painel e desenha o exemplo ali. Um painel é uma barra lateral ao lado da transcrição em um terminal largo em tela cheia, ou, caso contrário, uma região emoldurada acima do prompt.

1

Criar o mod

Crie um diretório chamado gallery com os diretórios .claude-plugin e hooks dentro dele. Criar um mod explica os arquivos.

Salve o manifesto como gallery/.claude-plugin/plugin.json:

{
"name": "gallery",
"version": "0.1.0",
"description": "Opens a pane that draws one sample",
"author": { "name": "Your Name" }
}

Indique seu ponto de entrada em gallery/hooks/hooks.json:

{
"modules": ["./register.js"]
}

Salve o código como gallery/hooks/register.js. Ele adiciona um comando /gallery que abre um painel e desenha Plain text nesse painel:

// 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

Executar o mod

No seu shell, inicie o Claude Code a partir do diretório que contém gallery:

claude --plugin-dir ./gallery

No prompt do Claude Code, execute /gallery. Um painel é aberto com Plain text nele.

3

Trocar por um exemplo

Copie um exemplo desta página. Em register.js, cole-o sobre Text({ children: ['Plain text'] }), de modo que ele venha depois de return, e salve o arquivo. O Claude Code recarrega o módulo cada vez que você salva, então execute /gallery novamente para ver o novo exemplo.

Escolher um elemento

Os exemplos estão agrupados pelo que você quer colocar na tela:

Mostrar texto

Três elementos colocam palavras na tela: Text para o seu próprio estilo, Markdown para conteúdo já formatado e Link para uma URL.

`Text`

Text desenha uma string com os estilos que você fornece. Este exemplo mostra uma linha para cada estilo:

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'"] }),
  ],
})
Um painel com nove linhas de texto, cada uma nomeada pelo seu estilo: simples, negrito, itálico, sublinhado, tachado, dimColor em cinza, inverso, cor vermelha e backgroundColor azul. Um painel com nove linhas de texto, cada uma nomeada pelo seu estilo: simples, negrito, itálico, sublinhado, tachado, dimColor em cinza, inverso, cor vermelha e backgroundColor azul.

dimColor desenha o texto em cinza. backgroundColor preenche apenas a largura do texto.

`Markdown`

Markdown formata o texto da mesma forma que as respostas do Claude são formatadas. Passe o conteúdo em text, não em 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',
})
Um painel com um título em negrito, Release notes, depois uma frase com uma palavra em negrito e uma palavra de código colorida, uma lista de dois itens e uma citação desenhada em itálico com uma barra à esquerda. Um painel com um título em negrito, Release notes, depois uma frase com uma palavra em negrito e uma palavra de código colorida, uma lista de dois itens e uma citação desenhada em itálico com uma barra à esquerda.

Um título é desenhado em negrito sem suas marcas #. O código inline é desenhado em cor sem seus acentos graves. Uma citação é desenhada em itálico com uma barra à esquerda.

Link desenha um rótulo seguido de sua URL:

Link({ href: 'https://code.claude.com/docs', label: 'Claude Code docs' })
Um painel com uma linha: o rótulo Claude Code docs, depois a URL em cinza. Um painel com uma linha: o rótulo Claude Code docs, depois a URL em cinza.

O terminal desenha a URL como texto após o rótulo. Se um clique a abre ou não depende do terminal do usuário.

Mostrar código e alterações

Code desenha texto-fonte com as próprias cores de sintaxe do Claude Code, ou um diff.

`Code`

Indique a language, ou passe um path para que o Claude Code a deduza. Com startLine, as linhas são numeradas a partir desse número:

Code({
  language: 'javascript',
  startLine: 1,
  source: "const name = 'mods'\nconsole.log('hello ' + name)",
})
Um painel com duas linhas numeradas de JavaScript em cores de sintaxe. Um painel com duas linhas numeradas de JavaScript em cores de sintaxe.

As cores vêm do tema do usuário.

`Code` como diff

Com format: 'diff', source é um ou mais hunks de diff unificado:

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.',
})
Um painel com um diff de quatro linhas. A linha removida está sombreada em vermelho e a linha adicionada em verde, cada uma com seu número de linha. Na linha adicionada, as palavras that runs code têm uma sombra mais forte. Um painel com um diff de quatro linhas. A linha removida está sombreada em vermelho e a linha adicionada em verde, cada uma com seu número de linha. Na linha adicionada, as palavras that runs code têm uma sombra mais forte.

O Claude Code desenha números de linha no lugar da linha @@. Onde uma linha removida e uma linha adicionada são parecidas, as palavras que mudaram recebem uma sombra mais forte.

Organizar elementos

`Box`

Box dispõe o que está dentro dele em uma linha ou em uma coluna, e pode desenhar uma borda. Este exemplo coloca uma linha de palavras acima de uma caixa com borda:

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'"] })],
    }),
  ],
})
Um painel com três palavras em uma linha, separadas por quatro colunas, depois uma linha em branco, depois uma borda arredondada em torno de uma linha de texto. A borda ocupa toda a largura do painel. Um painel com três palavras em uma linha, separadas por quatro colunas, depois uma linha em branco, depois uma borda arredondada em torno de uma linha de texto. A borda ocupa toda a largura do painel.

A borda se estende até a largura do painel.

Receber entrada

Button, Input e Select são controles: o usuário se move entre eles com Tab e usa aquele que tem o foco. Foco do teclado e teclas de atalho explica quais teclas chegam até eles.

Abrir um painel com focus: true dá ao painel o foco do teclado. As letras digitadas chegam a um Input assim que ele tem o foco, então adicione autoFocus: true a um campo que deve receber a digitação assim que o painel abrir.

`Button`

Um botão executa onPress. Este exemplo mostra a forma padrão, um botão plain com uma tecla de atalho e um esmaecido:

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 }),
  ],
})
Um painel com três botões, um por linha: Save entre colchetes, n: Next sem colchetes e com o n em cor, e Skip entre colchetes em cinza. Um painel com três botões, um por linha: Save entre colchetes, n: Next sem colchetes e com o n em cor, e Skip entre colchetes em cinza.

Um botão que tem o foco é desenhado em vídeo inverso. Aqui o usuário pressionou Tab duas vezes:

Os mesmos três botões, com o segundo, n: Next, desenhado em vídeo inverso. Os mesmos três botões, com o segundo, n: Next, desenhado em vídeo inverso.

`Input`

Um Input é um campo de texto de uma linha que executa onSubmit quando o usuário pressiona Enter:

Input({
  key: 'title',
  label: 'Title',
  placeholder: 'Type a title and press Enter',
  value: '',
  submitLabel: 'save',
  onSubmit: noop,
})

Sem o foco, o campo mostra seu rótulo e seu placeholder:

Um painel com uma linha: o rótulo Title, depois o placeholder Type a title and press Enter em cinza. Um painel com uma linha: o rótulo Title, depois o placeholder Type a title and press Enter em cinza.

Com o foco, o rótulo fica em negrito, um cursor aparece e o submitLabel é exibido após ⏎:

O mesmo campo com seu rótulo em negrito, um cursor de bloco na primeira letra do placeholder e um sinal de retorno seguido da palavra save. O mesmo campo com seu rótulo em negrito, um cursor de bloco na primeira letra do placeholder e um sinal de retorno seguido da palavra save.

Digitar substitui o placeholder:

O mesmo campo contendo as letras digitadas Rel, seguidas do sinal de retorno e da palavra save. O mesmo campo contendo as letras digitadas Rel, seguidas do sinal de retorno e da palavra save.

`Select`

Um Select permite que o usuário escolha uma entre várias opções e executa onSelect com o value da opção:

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
  },
})

Fechado, ele mostra seu rótulo e a opção atual:

Um painel com uma linha: o rótulo Format, a opção atual Markdown e uma pequena seta para baixo. Um painel com uma linha: o rótulo Format, a opção atual Markdown e uma pequena seta para baixo.

Aberto, ele lista suas opções e marca uma:

O seletor aberto, com suas três opções listadas abaixo do rótulo. A segunda opção, HTML, é desenhada em vídeo inverso. O seletor aberto, com suas três opções listadas abaixo do rótulo. A segunda opção, HTML, é desenhada em vídeo inverso.

Depois que o usuário escolhe uma opção, a lista se fecha:

O seletor fechado novamente, agora mostrando HTML como a opção atual. O seletor fechado novamente, agora mostrando HTML como a opção atual.

Desenhar imagens

`Raster`

Um Raster é uma grade de células de caracteres coloridas, para um mapa de calor, um sparkline ou um tabuleiro de jogo. O terminal o desenha. Este exemplo usa a função cellsOf do módulo inicial, que empacota as células na string que um Raster recebe. Desenhar uma grade de células coloridas explica isso:

Raster({
  key: 'grid',
  columns: 3,
  rows: 2,
  cells: cellsOf([
    [['█', 0x2e7d32], ['█', 0xf9a825], ['█', 0xc62828]],
    [['█', 0x2e7d32], ['█', 0x2e7d32], ['█', 0xf9a825]],
  ]),
})
Um painel com uma pequena grade de blocos coloridos, duas linhas de três: verde, âmbar e vermelho, depois verde, verde e âmbar. Um painel com uma pequena grade de blocos coloridos, duas linhas de três: verde, âmbar e vermelho, depois verde, verde e âmbar.

Um Raster arredonda cada cor para uma paleta menor, então 0x2e7d32 é desenhado como #337733.

`Svg`

Um Svg desenha um documento SVG no aplicativo Desktop:

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>',
})

No terminal, um painel que retorna apenas um Svg abre vazio. Para desenhar outra coisa ali, verifique e.surface e retorne uma árvore diferente.

`Image` e `Client`

Mais dois elementos não têm exemplo aqui. Image desenha um PNG ou pixels brutos no terminal. Client é uma região que um segundo arquivo seu desenha, para animação e entrada de ponteiro. A referência de elementos lista suas props.

Ver onde um mod pode desenhar

Todos os exemplos desenham em um painel. Um mod também pode desenhar em outros lugares e chamar o Claude Code para mostrar algo por ele:

Próximos passos