תיעוד 78
גלריית ממשק למודים
ראו את רכיבי הממשק שמוד של 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 - הצגת קוד ושינויים:
Code - סידור רכיבים:
Box - קבלת קלט:
Button,Inputו-Select - ציור תמונות:
Raster,Svg,Imageו-Client
#הצגת טקסט
שלושה רכיבים שמים מילים על המסך: 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'"] }),
],
})
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',
})
כותרת מצוירת באותיות מודגשות בלי סימני #. קוד בתוך השורה מצויר בצבע בלי הגרשיים ההפוכים שלו. ציטוט מצויר באותיות נטויות עם פס משמאלו.
#Link
Link מצייר תווית ואחריה את כתובת ה-URL שלה:
Link({ href: 'https://code.claude.com/docs', label: 'Claude Code docs' })
הטרמינל מצייר את כתובת ה-URL כטקסט אחרי התווית. אם לחיצה פותחת אותה תלוי בטרמינל של המשתמש.
#הצגת קוד ושינויים
Code מצייר טקסט מקור עם צבעי התחביר של Claude Code עצמו, או diff. בהרחבה של VS Code, Code מציג את source שלו כטקסט רגיל, בלי הצבעים, מספרי השורות או הצללת ה-diff שבצילומי המסך האלה.
#Code
ציינו את language, או העבירו path כדי ש-Claude Code יסיק אותו ממנו. עם startLine, השורות ממוספרות מהמספר הזה:
Code({
language: 'javascript',
startLine: 1,
source: "const name = 'mods'\nconsole.log('hello ' + name)",
})
הצבעים מגיעים מערכת הנושא של המשתמש.
#Code כ-diff
עם format: 'diff', source הוא hunk אחד או יותר של 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.',
})
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 אחרי שיש לו מיקוד. כדי לבחור איזה שדה מקבל את המיקוד כשהחלונית נפתחת, ראו הגדרת מקש קיצור והמיקוד הראשון.
#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 }),
],
})
כפתור שיש לו מיקוד מצויר בצבעים הפוכים. כאן המשתמש לחץ על Tab פעמיים:

#Input
Input הוא שדה טקסט שמחזיק שורה אחת כברירת מחדל ומריץ את onSubmit כשהמשתמש לוחץ Enter:
Input({
key: 'title',
label: 'Title',
placeholder: 'Type a title and press Enter',
value: '',
submitLabel: 'save',
onSubmit: noop,
})בלי מיקוד, השדה מציג את התווית שלו ואת ה-placeholder שלו:

עם מיקוד, התווית נעשית מודגשת, מופיע סמן, ו-submitLabel מוצג אחרי ⏎:

הקלדה מחליפה את ה-placeholder:

הגדירו את rows ל-2 או יותר עבור שדה שמחזיק כמה שורות, כמו הערה או הודעת commit:
Input({
key: 'note',
label: 'Note',
placeholder: 'Write a note',
rows: 4,
onSubmit: noop,
})הטרמינל ואפליקציית Desktop מציירים את השורות. בהרחבה של VS Code, השדה מחזיק שורה אחת. rows דורש את Claude Code v2.1.301 או חדש יותר. בגרסאות קודמות השדה מחזיק שורה אחת.
השדה תופס את מספר השורות שהגדרתם, גם כשהוא ריק, עד לגובה החלונית או הפס שהוא מצויר בהם. בזמן שלשדה יש מיקוד, טקסט ארוך יותר נגלל בתוכו.
- בטרמינל, Enter עדיין שולח. שם, המשתמש מתחיל שורה חדשה על ידי הקלדת לוכסן ואז לחיצה על Enter, או על ידי לחיצה על Shift+Enter במקום שבו אמולטור הטרמינל תומך בזה. אלה אותם מקשים כמו בפרומפט.
- בטרמינל, Up ו-Down זזים בין השורות של השדה. מהשורה הראשונה והאחרונה שלו הם זזים לפקד שלפני או אחרי.
onSubmitו-onInputמקבלים את כל הטקסט כשהשורות שלו מחוברות ב-\n.
#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
},
})כשהוא סגור, הוא מציג את התווית שלו ואת האפשרות הנוכחית:

כשהוא פתוח, הוא מפרט את האפשרויות שלו ומסמן אחת:

אחרי שהמשתמש בוחר אפשרות, הרשימה נסגרת:

#ציור תמונות
#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 ובתוסף 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>',
})בטרמינל, חלונית שמחזירה רק Svg נפתחת ריקה. כדי לצייר שם משהו אחר, בדקו את e.surface והחזירו עץ אחר.
#Image ו-Client
לשני רכיבים נוספים אין דוגמה כאן. Image מצייר PNG או פיקסלים גולמיים בטרמינל. Client הוא אזור שקובץ שני שלכם מצייר, לאנימציה ולקלט מצביע. הפניית הרכיבים מפרטת את ה-props שלהם.
Image מצויר כתמונה בטרמינלים האלה:
- kitty 0.28 או חדש יותר
- Ghostty
- iTerm2 3.5 או חדש יותר. ציור ב-iTerm2 דורש Claude Code v2.1.305 או חדש יותר.
בכל טרמינל אחר, המשתמש רואה את טקסט alt של Image, מעומעם, במקום התמונה. כתבו טקסט alt שעומד בפני עצמו, כי הוא מוצג גם במקרים האלה, בין היתר:
- GNU screen: סשן שרץ בתוך screen, בכל טרמינל.
- tmux: סשן שרץ בתוך tmux וחסרה לו דרישה לציור בתוך tmux.
- סשנים ברקע: כל סשן רקע, מכל טרמינל שממנו הוא מחובר.
- iTerm2 מחוץ לעיבוד במסך מלא: ב-iTerm2 התמונה מצוירת רק תחת עיבוד במסך מלא, ולא בזמן ש-
CLAUDE_CODE_ALT_SCREEN_FULL_REPAINTמוגדר ל-1. כדי לראות את התמונה, הריצו/tui fullscreenבשורת Claude Code והשאירו את המשתנה לא מוגדר. - מקור של נתיב קובץ ב-iTerm2 או ב-tmux: ב-iTerm2 ובתוך tmux,
Imageש-sourceשלו מצייןfileמציג את טקסטaltבמקום התמונה. אם למוד שלכם יש משתמשי iTerm2 או tmux, העבירו את התמונה כ-base64 ב-source.pngאו ב-source.rgbaבמקום כנתיב ב-source.file.
אם משתמשי המוד שלכם רואים את הטקסט המעומעם בטרמינל שמצייר תמונות של פרוטוקול הגרפיקה של kitty עם מצייני מקום של Unicode, הם יכולים להגדיר את CLAUDE_CODE_FORCE_TERMINAL_IMAGES ל-1. אין להגדיר אותו בתוך GNU screen, בתוך tmux ישן מ-3.3, בחלון קופץ של tmux, או כש-allow-passthrough של tmux כבוי. שם אין תמונה, ומופיעה תיבה במקום טקסט alt.
#ציור Image בתוך tmux
אם Image מציג את טקסט alt שלו בתוך tmux, בדקו את הדרישות האלה יחד עם מקרים אחרים של טקסט alt, כמו סשן רקע:
- Claude Code v2.1.310 או חדש יותר
- tmux 3.3 או חדש יותר
- Claude Code רץ בחלונית tmux, לא בחלון קופץ של tmux
- tmux רץ בתוך kitty 0.28 או חדש יותר, Ghostty, או iTerm2 3.5 או חדש יותר
- אפשרויות tmux
focus-eventsו-allow-passthroughהןon. בתוך kitty או Ghostty,allow-passthroughיכול להיות גםall. - בתוך iTerm2, tmux רץ בלי
-CC, עיבוד במסך מלא פעיל, ו-CLAUDE_CODE_ALT_SCREEN_FULL_REPAINTלא מוגדר. - בתוך iTerm2, חלון tmux אינו גדול מחלון iTerm2. כדי לבדוק, הריצו
tmux display-message -p '#{window_bigger}'בחלון tmux הזה. אם הוא מדפיס1, התאימו את חלון tmux, ואז הפעילו מחדש את Claude Code. - מחבר המוד מעביר את התמונה כבתים של
pngאוrgba, לא כנתיבfile. אם אתם משתמשים במוד שלא כתבתם ושאר הדרישות מתקיימות, בקשו מהמחבר לבדוק את הדרישה הזו.
לכל אפשרות tmux שעדיין לא מוגדרת כנדרש, הריצו את הפקודה שלה במעטפת:
tmux set -g allow-passthrough on
tmux set -g focus-events onאחר כך התנתקו מ-tmux, התחברו שוב, והפעילו מחדש את Claude Code. הפעילו אותו מחדש בכל פעם שאתם מתחברים ל-tmux מטרמינל אחר. כדי לשמור את שתי האפשרויות גם אחרי הפעלה מחדש של שרת tmux, הוסיפו את שתי השורות גם ל-~/.tmux.conf.
#איפה מוד יכול לצייר
כל הדוגמאות מציירות בחלונית. מוד יכול גם לצייר במקומות אחרים, ולקרוא ל-Claude Code להציג משהו בשבילו:
- חלונית ו-band: בחירה איפה לצייר
- השורות של Claude Code עצמו, כמו ה-spinner: שינוי מה ש-Claude Code כבר מצייר
- Toast, שורת סטטוס ושורת לוג: הצגת משהו בלי להתחיל תור
- תיבת שאלה: החזקת קריאת כלי עד שהמשתמש מחליט
#הצעדים הבאים
- ציור בממשק: בניית חלונית עם לשוניות, צעד אחר צעד
- בדיקת ציור: לחיצה על הכפתורים שלכם מתוך בדיקה
- הפניית רכיבים: ה-
propsהעיקריים של כל רכיב והאפליקציות שמציירות אותו