SpyBara
Go Premium

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

This page contains 435 additions and 0 deletions.

2026
Fri 2 13:00

Галерея элементов интерфейса для модов

Посмотрите, какие элементы интерфейса может отрисовывать мод Claude Code: текст, кнопки, поля, Markdown, код и diff, — с примерами кода и снимками экрана терминала.

Мод строит свой интерфейс из элементов: текста, блоков, кнопок, полей и нескольких элементов, которые форматируют содержимое за вас. Примеры на этой странице показывают код, отрисовывающий элемент, и к большинству из них приложен снимок экрана с результатом на панели терминала, поэтому элемент можно выбрать по его внешнему виду.

Чтобы разобраться, как работает отрисовка, начните с раздела Отрисовка в интерфейсе. Основные свойства элементов и приложения, которые отрисовывают каждый из них, описаны в справочнике по элементам. В объявлениях типов перечислены все свойства.

Попробуйте пример

Примеры на этой странице — это фрагменты, а не готовые моды. Каждый из них — код одного элемента и всего, что в него вложено.

Чтобы посмотреть пример в своём терминале, создайте небольшой мод, следуя этим шагам, и вставьте в него пример. Мод добавляет команду /gallery, которая открывает панель и отрисовывает в ней пример. Панель — это боковая область рядом с транскриптом в широком полноэкранном терминале, а в остальных случаях — область в рамке над промптом.

1

Создайте мод

Создайте каталог gallery, а внутри него — каталоги .claude-plugin и hooks. Назначение файлов объясняется в разделе Создание мода.

Сохраните манифест как gallery/.claude-plugin/plugin.json:

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

Укажите точку входа в gallery/hooks/hooks.json:

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

Сохраните код как gallery/hooks/register.js. Он добавляет команду /gallery, которая открывает панель, и отрисовывает в ней Plain text:

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

Запустите мод

В оболочке запустите Claude Code из каталога, содержащего gallery:

claude --plugin-dir ./gallery

В промпте Claude Code выполните /gallery. Откроется панель с текстом Plain text.

3

Подставьте пример

Скопируйте пример с этой страницы. В register.js вставьте его вместо Text({ children: ['Plain text'] }), чтобы он шёл после return, и сохраните файл. Claude Code перезагружает модуль при каждом сохранении, поэтому снова выполните /gallery, чтобы увидеть новый пример.

Выберите элемент

Примеры сгруппированы по тому, что вы хотите вывести на экран:

Вывод текста

Текст на экран выводят три элемента: Text — с вашим собственным оформлением, Markdown — для уже отформатированного содержимого и Link — для URL.

`Text`

Text отрисовывает строку с заданными вами стилями. В этом примере каждому стилю соответствует одна строка:

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'"] }),
  ],
})
Панель с девятью строками текста, каждая из которых названа по своему стилю: обычный, bold, italic, underline, strikethrough, dimColor серым цветом, inverse, color red и backgroundColor blue. Панель с девятью строками текста, каждая из которых названа по своему стилю: обычный, bold, italic, underline, strikethrough, dimColor серым цветом, inverse, color red и backgroundColor blue.

dimColor отрисовывает текст серым цветом. backgroundColor заливает фон только по ширине текста.

`Markdown`

Markdown форматирует текст так же, как форматируются ответы Claude. Передавайте содержимое в text, а не в 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',
})
Панель с жирным заголовком Release notes, затем предложение с одним жирным словом и одним цветным словом кода, список из двух пунктов и цитата курсивом с чертой слева. Панель с жирным заголовком Release notes, затем предложение с одним жирным словом и одним цветным словом кода, список из двух пунктов и цитата курсивом с чертой слева.

Заголовок отрисовывается жирным шрифтом без знаков #. Встроенный код отрисовывается цветом без обратных кавычек. Цитата отрисовывается курсивом с чертой слева.

Link отрисовывает подпись, а за ней — её URL:

Link({ href: 'https://code.claude.com/docs', label: 'Claude Code docs' })
Панель с одной строкой: подпись Claude Code docs, а затем URL серым цветом. Панель с одной строкой: подпись Claude Code docs, а затем URL серым цветом.

Терминал отрисовывает URL как текст после подписи. Откроется ли он по щелчку, зависит от терминала пользователя.

Вывод кода и изменений

Code отрисовывает исходный текст с подсветкой синтаксиса в цветах самого Claude Code или diff.

`Code`

Укажите язык в language или передайте path, чтобы Claude Code определил язык по нему. С startLine строки нумеруются начиная с этого числа:

Code({
  language: 'javascript',
  startLine: 1,
  source: "const name = 'mods'\nconsole.log('hello ' + name)",
})
Панель с двумя пронумерованными строками JavaScript с подсветкой синтаксиса. Панель с двумя пронумерованными строками JavaScript с подсветкой синтаксиса.

Цвета берутся из темы пользователя.

`Code` в виде diff

С format: 'diff' в source передаются один или несколько фрагментов (hunks) в формате unified diff:

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.',
})
Панель с diff из четырёх строк. Удалённая строка подсвечена красным, добавленная — зелёным, у каждой указан номер строки. В добавленной строке слова that runs code подсвечены ярче. Панель с diff из четырёх строк. Удалённая строка подсвечена красным, добавленная — зелёным, у каждой указан номер строки. В добавленной строке слова that runs code подсвечены ярче.

Вместо строки @@ Claude Code отрисовывает номера строк. Если удалённая и добавленная строки похожи, изменившиеся слова подсвечиваются ярче.

Компоновка элементов

`Box`

Box располагает своё содержимое в строку или в столбец и может отрисовывать рамку. В этом примере над блоком в рамке размещается строка слов:

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'"] })],
    }),
  ],
})
Панель с тремя словами в строку на расстоянии четырёх столбцов друг от друга, затем пустая строка, затем скруглённая рамка вокруг одной строки текста. Рамка занимает всю ширину панели. Панель с тремя словами в строку на расстоянии четырёх столбцов друг от друга, затем пустая строка, затем скруглённая рамка вокруг одной строки текста. Рамка занимает всю ширину панели.

Рамка растягивается на всю ширину панели.

Ввод данных

Button, Input и Select — это элементы управления: пользователь переходит между ними клавишей Tab и работает с тем, на котором находится фокус. Какие клавиши до них доходят, описано в разделе Фокус клавиатуры и горячие клавиши.

Если открыть панель с focus: true, она получит фокус клавиатуры. Вводимые буквы попадают в Input, только когда на нём фокус, поэтому добавьте autoFocus: true к полю, которое должно принимать ввод сразу после открытия панели.

`Button`

Кнопка вызывает onPress. В этом примере показаны кнопка по умолчанию, кнопка plain с горячей клавишей и приглушённая кнопка:

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 }),
  ],
})
Панель с тремя кнопками, по одной в строке: Save в скобках, n: Next без скобок с цветной буквой n и Skip в скобках серым цветом. Панель с тремя кнопками, по одной в строке: Save в скобках, n: Next без скобок с цветной буквой n и Skip в скобках серым цветом.

Кнопка с фокусом отрисовывается в инверсных цветах. Здесь пользователь дважды нажал Tab:

Те же три кнопки, вторая из которых, n: Next, отрисована в инверсных цветах. Те же три кнопки, вторая из которых, n: Next, отрисована в инверсных цветах.

`Input`

Input — это однострочное текстовое поле, которое вызывает onSubmit, когда пользователь нажимает Enter:

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

Без фокуса поле показывает подпись и текст-заполнитель:

Панель с одной строкой: подпись Title, затем текст-заполнитель Type a title and press Enter серым цветом. Панель с одной строкой: подпись Title, затем текст-заполнитель Type a title and press Enter серым цветом.

С фокусом подпись становится жирной, появляется курсор, а после ⏎ отображается submitLabel:

То же поле с жирной подписью, блочным курсором на первой букве текста-заполнителя и знаком возврата, за которым следует слово save. То же поле с жирной подписью, блочным курсором на первой букве текста-заполнителя и знаком возврата, за которым следует слово save.

Ввод заменяет текст-заполнитель:

То же поле с введёнными буквами Rel, за которыми следуют знак возврата и слово save. То же поле с введёнными буквами Rel, за которыми следуют знак возврата и слово save.

`Select`

Select позволяет пользователю выбрать один из нескольких вариантов и вызывает onSelect со значением value выбранного варианта:

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

В закрытом состоянии он показывает подпись и текущий вариант:

Панель с одной строкой: подпись Format, текущий вариант Markdown и маленькая стрелка вниз. Панель с одной строкой: подпись Format, текущий вариант Markdown и маленькая стрелка вниз.

В открытом состоянии он показывает список вариантов и выделяет один из них:

Открытый список выбора с тремя вариантами под подписью. Второй вариант, HTML, отрисован в инверсных цветах. Открытый список выбора с тремя вариантами под подписью. Второй вариант, HTML, отрисован в инверсных цветах.

После того как пользователь выберет вариант, список закрывается:

Список выбора снова закрыт, и текущим вариантом теперь показан HTML. Список выбора снова закрыт, и текущим вариантом теперь показан HTML.

Рисование изображений

`Raster`

Raster — это сетка цветных символьных ячеек для тепловой карты, спарклайна или игрового поля. Его отрисовывает терминал. В этом примере используется функция cellsOf из начального модуля, которая упаковывает ячейки в строку, принимаемую Raster. Подробнее см. в разделе Отрисовка сетки цветных ячеек:

Raster({
  key: 'grid',
  columns: 3,
  rows: 2,
  cells: cellsOf([
    [['█', 0x2e7d32], ['█', 0xf9a825], ['█', 0xc62828]],
    [['█', 0x2e7d32], ['█', 0x2e7d32], ['█', 0xf9a825]],
  ]),
})
Панель с небольшой сеткой цветных блоков в две строки по три: зелёный, янтарный и красный, затем зелёный, зелёный и янтарный. Панель с небольшой сеткой цветных блоков в две строки по три: зелёный, янтарный и красный, затем зелёный, зелёный и янтарный.

Raster округляет каждый цвет до более ограниченной палитры, поэтому 0x2e7d32 отрисовывается как #337733.

`Svg`

Svg отрисовывает SVG-документ в приложении 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>',
})

В терминале панель, которая возвращает только Svg, открывается пустой. Чтобы отрисовать там что-то другое, проверьте e.surface и верните другое дерево.

`Image` и `Client`

Для ещё двух элементов примеров здесь нет. Image отрисовывает PNG или необработанные пиксели в терминале. Client — это область, которую отрисовывает ваш второй файл, для анимации и ввода указателем. Их свойства перечислены в справочнике по элементам.

Где ещё может отрисовывать мод

Все примеры отрисовываются на панели. Мод также может отрисовывать в других местах и вызывать Claude Code, чтобы тот что-то показал за него:

Дальнейшие шаги