2> Fetch the complete documentation index at: https://code.claude.com/docs/llms.txt2> Fetch the complete documentation index at: https://code.claude.com/docs/llms.txt
3> Use this file to discover all available pages before exploring further.3> Use this file to discover all available pages before exploring further.
4 4
5# Mit einem Mod in der Benutzeroberfläche zeichnen5# Mit einem Mod in der Oberfläche zeichnen
6 6
7> Zeichnen Sie Panes, ein Band über der Eingabeaufforderung, Schaltflächen und Textfelder aus einem Claude Code Mod, verarbeiten Sie Drücke und Eingaben, und behalten Sie den Status zwischen Neuzeichnungen und Sitzungen bei.7> Zeichnen Sie mit einem Claude Code Mod Bereiche, ein Band über dem Prompt, Schaltflächen und Textfelder, verarbeiten Sie Tastendrücke und Eingaben, und bewahren Sie den Zustand zwischen Neuzeichnungen und Sitzungen.
8 8
9Ein Mod kann seine eigene Benutzeroberfläche in Claude Code zeichnen und Teile der Benutzeroberfläche ändern, die Claude Code bereits zeichnet. Jeder Ort, an dem ein Mod zeichnen kann, wird als [Render-Site](/docs/de/plugins/mods/reference#render-sites) bezeichnet, z. B. ein Pane, das Band über der Eingabeaufforderung oder der Spinner. Claude Code löst das [`ui.render`](/docs/de/plugins/mods/reference#interface) Ereignis jedes Mal aus, wenn es eine Render-Site zeichnen möchte, und Ihr Hook für dieses Ereignis gibt zurück, was dort gezeichnet werden soll.9Ein Mod kann seine eigene Oberfläche in Claude Code zeichnen und Teile der Oberfläche ändern, die Claude Code bereits zeichnet. Jede Stelle, an der ein Mod zeichnen kann, wird als [Render-Stelle](/docs/de/plugins/mods/reference#render-sites) bezeichnet, etwa ein Bereich, das Band über dem Prompt oder der Spinner. Claude Code löst das Ereignis [`ui.render`](/docs/de/plugins/mods/reference#interface) jedes Mal aus, bevor es eine Render-Stelle zeichnet, und Ihr Hook für dieses Ereignis gibt zurück, was dort gezeichnet werden soll.
10 10
11Diese Karte zeigt, wo ein Mod in einer Terminal-Sitzung zeichnen kann:11Diese Übersicht zeigt, wo ein Mod in einer Terminal-Sitzung zeichnen kann:
12 12
13<img src="https://mintcdn.com/claude-code/dgiVO_Od1X1faduV/images/mods-screen-map.svg?fit=max&auto=format&n=dgiVO_Od1X1faduV&q=85&s=5fda26b6609c62b68c6f9e528c1590ea" className="dark:hidden" alt="Karte einer Claude Code Terminal-Sitzung. Ein Mod kann ein Pane als Seitenleiste auf der rechten Seite hinzufügen, einen Toast oben rechts im Transkript, eine Protokollzeile im Transkript, ein Band über der Eingabeaufforderung und eine Statuszeile unter der Eingabeaufforderung. Ein Mod kann Nachrichten, Tool-Call-Zeilen und den Spinner neu zeichnen. Die Eingabeaufforderung ist Claude Codes eigene." width="600" height="336" data-path="images/mods-screen-map.svg" />13<img src="https://mintcdn.com/claude-code/dgiVO_Od1X1faduV/images/mods-screen-map.svg?fit=max&auto=format&n=dgiVO_Od1X1faduV&q=85&s=5fda26b6609c62b68c6f9e528c1590ea" className="dark:hidden" alt="Übersicht einer Claude Code Terminal-Sitzung. Ein Mod kann einen Bereich als Seitenleiste rechts hinzufügen, einen Toast oben rechts im Transkript, eine Log-Zeile im Transkript, ein Band über dem Prompt und eine Statuszeile unter dem Prompt. Ein Mod kann Nachrichten, Zeilen von Tool-Aufrufen und den Spinner neu zeichnen. Der Prompt gehört Claude Code selbst." width="600" height="336" data-path="images/mods-screen-map.svg" />
14 14
15<img src="https://mintcdn.com/claude-code/dgiVO_Od1X1faduV/images/mods-screen-map-dark.svg?fit=max&auto=format&n=dgiVO_Od1X1faduV&q=85&s=5b4161581a1bd2c0450b0c8b57bc1225" className="hidden dark:block" alt="Karte einer Claude Code Terminal-Sitzung. Ein Mod kann ein Pane als Seitenleiste auf der rechten Seite hinzufügen, einen Toast oben rechts im Transkript, eine Protokollzeile im Transkript, ein Band über der Eingabeaufforderung und eine Statuszeile unter der Eingabeaufforderung. Ein Mod kann Nachrichten, Tool-Call-Zeilen und den Spinner neu zeichnen. Die Eingabeaufforderung ist Claude Codes eigene." width="600" height="336" data-path="images/mods-screen-map-dark.svg" />15<img src="https://mintcdn.com/claude-code/dgiVO_Od1X1faduV/images/mods-screen-map-dark.svg?fit=max&auto=format&n=dgiVO_Od1X1faduV&q=85&s=5b4161581a1bd2c0450b0c8b57bc1225" className="hidden dark:block" alt="Übersicht einer Claude Code Terminal-Sitzung. Ein Mod kann einen Bereich als Seitenleiste rechts hinzufügen, einen Toast oben rechts im Transkript, eine Log-Zeile im Transkript, ein Band über dem Prompt und eine Statuszeile unter dem Prompt. Ein Mod kann Nachrichten, Zeilen von Tool-Aufrufen und den Spinner neu zeichnen. Der Prompt gehört Claude Code selbst." width="600" height="336" data-path="images/mods-screen-map-dark.svg" />
16 16
17In einem schmaleren Terminal sitzt das Pane über der Eingabeaufforderung statt neben dem Transkript.17In einem schmaleren Terminal befindet sich der Bereich über dem Prompt statt neben dem Transkript.
18 18
19Erstellen Sie Ihren [ersten Mod](/docs/de/plugins/mods/create), bevor Sie hier beginnen. Beginnen Sie mit dem durchgearbeiteten Beispiel, das ein Pane mit zwei Registerkarten und einem Zähler erstellt, lesen Sie dann den Abschnitt für jeden Teil, den Sie ändern möchten.19Erstellen Sie Ihren [ersten Mod](/docs/de/plugins/mods/create), bevor Sie hier beginnen. Starten Sie mit dem ausgearbeiteten Beispiel, das einen Bereich mit zwei Tabs und einem Zähler erstellt, und lesen Sie dann den Abschnitt zu jedem Teil, den Sie ändern möchten.
20 20
21<Note>21<Note>
22 Um eine Eigenschaft oder ein Limit nachzuschlagen, siehe die [Referenz](/docs/de/plugins/mods/reference#render-sites).22 Um eine einzelne Prop oder ein Limit nachzuschlagen, lesen Sie die [Referenz](/docs/de/plugins/mods/reference#render-sites).
23</Note>23</Note>
24 24
25<h2 id="build-a-pane-with-tabs">25<h2 id="build-a-pane-with-tabs">
26 Erstellen Sie ein Pane mit Registerkarten26 Einen Bereich mit Tabs erstellen
27</h2>27</h2>
28 28
29In diesem Abschnitt erstellen Sie einen Mod, der einen `/hello-tabs` Befehl hinzufügt, und der Befehl öffnet ein Pane. Ein Pane ist eine Seitenleiste neben dem Transkript in einem breiten Vollbildterminal oder eine gerahmte Region über der Eingabeaufforderung. Dieses Pane zeigt zwei Registerkarten, und die zweite Registerkarte hat eine Schaltfläche, die eins zu einem Zähler addiert. Die Anzahl ist immer noch da, nachdem Sie Claude Code neu starten.29In diesem Abschnitt erstellen Sie einen Mod, der einen Befehl `/hello-tabs` hinzufügt, und der Befehl öffnet einen Bereich. Ein Bereich ist in einem breiten Vollbild-Terminal eine Seitenleiste neben dem Transkript, andernfalls ein umrahmter Bereich oberhalb des Prompts. Dieser Bereich zeigt zwei Tabs, und der zweite Tab enthält eine Schaltfläche, die einen Zähler um eins erhöht. Der Zählerstand bleibt erhalten, nachdem Sie Claude Code neu starten.
30 30
31Der fertige Mod sieht so aus. Die Aufzeichnung öffnet das Pane, wechselt zur zweiten Registerkarte, drückt die Schaltfläche ein paar Mal und kehrt zur ersten Registerkarte zurück:31Der fertige Mod sieht so aus. Die Aufzeichnung öffnet den Bereich, wechselt zum zweiten Tab, drückt die Schaltfläche einige Male und kehrt zum ersten Tab zurück:
32 32
33<Frame>33<Frame>
34 <video autoPlay muted loop playsInline controls className="w-full dark:hidden" src="https://mintcdn.com/claude-code/dgiVO_Od1X1faduV/images/mods-hello-tabs-light.mp4?fit=max&auto=format&n=dgiVO_Od1X1faduV&q=85&s=49d520094d87b5b44bfe50fa49677f06" aria-label="Der Befehl /hello-tabs wird an der Claude Code Eingabeaufforderung eingegeben und ein gerahmtes Pane öffnet sich darüber, mit „1: One" und „2: Two" oben und dem Text „This is the first tab." Die zweite Registerkarte zeigt eine Schaltfläche „Add one" neben „Count: 1", und die Anzahl steigt auf 3. Das Pane kehrt dann zur ersten Registerkarte zurück." data-path="images/mods-hello-tabs-light.mp4" />34 <video autoPlay muted loop playsInline controls className="w-full dark:hidden" src="https://mintcdn.com/claude-code/dgiVO_Od1X1faduV/images/mods-hello-tabs-light.mp4?fit=max&auto=format&n=dgiVO_Od1X1faduV&q=85&s=49d520094d87b5b44bfe50fa49677f06" aria-label="Der Befehl /hello-tabs wird im Prompt von Claude Code eingegeben, und darüber öffnet sich ein umrahmter Bereich mit '1: One' und '2: Two' am oberen Rand und dem Text 'This is the first tab.' Der zweite Tab zeigt eine Schaltfläche 'Add one' neben 'Count: 1', und der Zählerstand steigt auf 3. Anschließend kehrt der Bereich zum ersten Tab zurück." data-path="images/mods-hello-tabs-light.mp4" />
35 35
36 <video autoPlay muted loop playsInline controls className="w-full hidden dark:block" src="https://mintcdn.com/claude-code/dgiVO_Od1X1faduV/images/mods-hello-tabs-dark.mp4?fit=max&auto=format&n=dgiVO_Od1X1faduV&q=85&s=ff7a14d713d6e5d3b0000efa8522ea4b" aria-label="Der Befehl /hello-tabs wird an der Claude Code Eingabeaufforderung eingegeben und ein gerahmtes Pane öffnet sich darüber, mit „1: One" und „2: Two" oben und dem Text „This is the first tab." Die zweite Registerkarte zeigt eine Schaltfläche „Add one" neben „Count: 1", und die Anzahl steigt auf 3. Das Pane kehrt dann zur ersten Registerkarte zurück." data-path="images/mods-hello-tabs-dark.mp4" />36 <video autoPlay muted loop playsInline controls className="w-full hidden dark:block" src="https://mintcdn.com/claude-code/dgiVO_Od1X1faduV/images/mods-hello-tabs-dark.mp4?fit=max&auto=format&n=dgiVO_Od1X1faduV&q=85&s=ff7a14d713d6e5d3b0000efa8522ea4b" aria-label="Der Befehl /hello-tabs wird im Prompt von Claude Code eingegeben, und darüber öffnet sich ein umrahmter Bereich mit '1: One' und '2: Two' am oberen Rand und dem Text 'This is the first tab.' Der zweite Tab zeigt eine Schaltfläche 'Add one' neben 'Count: 1', und der Zählerstand steigt auf 3. Anschließend kehrt der Bereich zum ersten Tab zurück." data-path="images/mods-hello-tabs-dark.mp4" />
37</Frame>37</Frame>
38 38
39Claude Code hat kein integriertes Registerkarten-Element, daher sind die Registerkarten zwei Schaltflächen in einer Reihe. Der Mod verfolgt, welche aktiv ist, und zeichnet den Inhalt dieser Registerkarte unter der Reihe.39Die Tabs sind zwei Schaltflächen in einer Zeile. Der Mod merkt sich, welcher Tab aktiv ist, und zeichnet dessen Inhalt unterhalb der Zeile.
40 40
41<Steps>41<Steps>
42 <Step title="Erstellen Sie das Plugin">42 <Step title="Das Plugin erstellen">
43 Ein Mod ist ein Plugin mit einem Manifest, einer `hooks.json`, die auf Ihren Code verweist, und der Codedatei. [Erstellen Sie einen Mod](/docs/de/plugins/mods/create#write-a-mod-yourself) erklärt jeden. Erstellen Sie ein Verzeichnis namens `hello-tabs` mit `.claude-plugin` und `hooks` Verzeichnissen darin, speichern Sie dann die ersten zwei Dateien.43 Ein Mod ist ein Plugin mit einem Manifest, einer `hooks.json`, die auf Ihren Code verweist, und der Code-Datei. [Einen Mod erstellen](/docs/de/plugins/mods/create#write-a-mod-yourself) erklärt jede davon. Erstellen Sie ein Verzeichnis namens `hello-tabs` mit den Verzeichnissen `.claude-plugin` und `hooks` darin, und speichern Sie dann die ersten beiden Dateien.
44 44
45 Speichern Sie das Manifest als `hello-tabs/.claude-plugin/plugin.json`:45 Speichern Sie das Manifest als `hello-tabs/.claude-plugin/plugin.json`:
46 46
62 ```62 ```
63 </Step>63 </Step>
64 64
65 <Step title="Schreiben Sie den Code">65 <Step title="Den Code schreiben">
66 Der Code führt drei Aufgaben aus, eine in jedem Hook:66 Diese Liste beschreibt, was jeder Hook tut, in der Reihenfolge, in der sie im Code erscheinen:
67 67
68 * Fügt den `/hello-tabs` Befehl hinzu68 * Fügt den Befehl `/hello-tabs` hinzu und lädt den Zählerstand, den eine frühere Sitzung gespeichert hat
69 * Öffnet das Pane, wenn Sie diesen Befehl ausführen69 * Öffnet den Bereich, wenn Sie diesen Befehl ausführen
70 * Zeichnet den Inhalt des Pane: die Reihe von Registerkarten und den Hauptteil der offenen Registerkarte70 * Zeichnet den Inhalt des Bereichs: die Zeile mit den Tabs und den Inhalt des geöffneten Tabs
71 71
72 Zwei Variablen auf Modulebene, `tab` und `count`, halten den Status des Pane.72 Zwei Variablen auf Modulebene, `tab` und `count`, halten den Zustand des Bereichs.
73 73
74 Speichern Sie dies als `hello-tabs/hooks/register.js`:74 Speichern Sie dies als `hello-tabs/hooks/register.js`:
75 75
165 }165 }
166 ```166 ```
167 167
168 Jeder Hook führt auch etwas aus, das der Code nicht deutlich macht:168 Jeder Hook tut außerdem etwas, das der Code nicht deutlich macht:
169 169
170 * **[`session.start`](/docs/de/plugins/mods/reference#session)** liest auch die gespeicherte Anzahl aus [`$.store`](#keep-state), einem Schlüssel-Wert-Speicher, der zwischen Sitzungen bestehen bleibt.170 * **[`session.start`](/docs/de/plugins/mods/reference#session)** liest zusätzlich den gespeicherten Zählerstand aus [`$.store`](#keep-state), einem Key-Value-Speicher, der zwischen Sitzungen erhalten bleibt.
171 * **[`command.run`](/docs/de/plugins/mods/api#add-a-command)** teilt Claude Code nur mit, dass das Pane existiert. Das Öffnen eines Pane zeichnet nichts von selbst: Claude Code löst dann `ui.render` aus, um zu fragen, was darin geht.171 * **[`command.run`](/docs/de/plugins/mods/api#add-a-command)** teilt Claude Code nur mit, dass der Bereich existiert. Das Öffnen eines Bereichs zeichnet für sich genommen nichts: Claude Code löst anschließend `ui.render` aus, um zu erfragen, was hineingehört.
172 * **`ui.render`** gibt den Element-Baum zurück, ein `Box`, das andere Boxen, Text und Schaltflächen enthält, und erstellt ihn jedes Mal aus `tab` und `count` neu.172 * **`ui.render`** gibt den Elementbaum zurück, eine `Box`, die weitere Boxen, Text und Schaltflächen enthält, und baut ihn bei jeder Ausführung erneut aus `tab` und `count` auf.
173 173
174 Das Drücken einer Schaltfläche führt ihren `onPress` Callback aus, der eine Variable ändert und `redraw` aufruft. Claude Code führt dann den `ui.render` Hook erneut aus, und der Hook erstellt einen neuen Baum aus den neuen Werten. Jede interaktive Zeichnung verwendet diesen Render-Zyklus: Ein Callback ändert den Status, und der Hook zeichnet aus dem neuen Status neu.174 Das Drücken einer Schaltfläche führt deren `onPress`-Callback aus, der eine Variable ändert und `redraw` aufruft. Claude Code führt daraufhin den Hook `ui.render` erneut aus, und der Hook baut aus den neuen Werten einen neuen Baum auf. Jede interaktive Darstellung nutzt diesen Render-Zyklus: Ein Callback ändert den Zustand, und der Hook rendert erneut aus dem neuen Zustand.
175 </Step>175 </Step>
176 176
177 <Step title="Öffnen Sie das Pane">177 <Step title="Den Bereich öffnen">
178 Starten Sie Claude Code in Ihrer Shell mit `claude --plugin-dir ./hello-tabs`. Führen Sie an der Claude Code Eingabeaufforderung `/hello-tabs` aus. Ein Pane öffnet sich mit `1: One` und `2: Two` oben. Drücken Sie `2`, dann drücken Sie `a`, die Hotkey für **Add one**, ein paar Mal. Die Anzahl steigt.178 Starten Sie Claude Code in Ihrer Shell mit `claude --plugin-dir ./hello-tabs`. Führen Sie im Prompt von Claude Code `/hello-tabs` aus. Ein Bereich öffnet sich mit `1: One` und `2: Two` am oberen Rand. Drücken Sie `2` und dann einige Male `a`, das Tastenkürzel für **Add one**. Der Zählerstand steigt.
179 </Step>179 </Step>
180 180
181 <Step title="Überprüfen Sie, dass die Anzahl gespeichert wurde">181 <Step title="Prüfen, ob der Zählerstand gespeichert wurde">
182 Drücken Sie Esc, um das Pane zu schließen, und beenden Sie dann die Sitzung. Starten Sie Claude Code in Ihrer Shell erneut mit dem gleichen `claude --plugin-dir ./hello-tabs` Befehl, und führen Sie an der Claude Code Eingabeaufforderung `/hello-tabs` aus. Die Anzahl ist dort, wo Sie sie gelassen haben.182 Drücken Sie Esc, um den Bereich zu schließen, und beenden Sie dann die Sitzung. Starten Sie Claude Code in Ihrer Shell erneut mit demselben Befehl `claude --plugin-dir ./hello-tabs`, und führen Sie im Prompt von Claude Code `/hello-tabs` aus. Der Zählerstand ist dort, wo Sie ihn verlassen haben.
183 183
184 Um die Anzahl zu löschen, lassen Sie den Mod `$.store.delete('count')` aufrufen. [Behalten Sie den Status](#keep-state) behandelt, wie lange jede Art von Wert dauert.184 Um den Zählerstand zurückzusetzen, lassen Sie den Mod `$.store.delete('count')` aufrufen. [Zustand beibehalten](#keep-state) beschreibt, wie lange jede Art von Wert erhalten bleibt.
185 </Step>185 </Step>
186</Steps>186</Steps>
187 187
188<h2 id="pick-where-to-draw">188<h2 id="pick-where-to-draw">
189 Wählen Sie, wo Sie zeichnen möchten189 Wählen Sie, wo gezeichnet wird
190</h2>190</h2>
191 191
192Ein `ui.render` Hook läuft für jede Render-Site, es sei denn, Sie grenzen ihn auf die gewünschte ein. Um die Render-Site auszuwählen, übergeben Sie einen Filter, genannt [Matcher](/docs/de/plugins/mods/events#filter-which-events-a-hook-handles), als zweites Argument an `on`. `{ component: 'Pane' }` führt den Hook nur für Panes aus. Im Hook benennt `e.component` die Site, `e.surface` sagt, welche App zeichnet, und `e.props` enthält die eigenen Daten der Site. Für ein Pane ist `e.requestId` die `id`, mit der Sie es geöffnet haben.192Ein `ui.render`-Hook wird für jede Render-Stelle ausgeführt, sofern Sie ihn nicht auf die Stelle eingrenzen, an der Sie zeichnen möchten. Um die Render-Stelle auszuwählen, übergeben Sie einen Filter, einen sogenannten [Matcher](/docs/de/plugins/mods/events#filter-which-events-a-hook-handles), als zweites Argument an `on`. `{ component: 'Pane' }` führt den Hook nur für Panes aus. Im Hook benennt `e.component` die Stelle, `e.surface` gibt an, welche App zeichnet, und `e.props` enthält die eigenen Daten der Stelle. Bei einem Pane ist `e.requestId` die `id`, mit der Sie es geöffnet haben.
193 193
194Zwei Sites sind leer, bis ein Mod sie ausfüllt, das Pane und das Band. Wählen Sie eine Registerkarte, um zu sehen, was jede ist und wie man darin zeichnet:194Das Pane und das Band sind leer, bis ein Mod sie füllt. Wählen Sie einen Tab aus, um zu sehen, was jedes davon ist und wie Sie darin zeichnen:
195 195
196<Tabs>196<Tabs>
197 <Tab title="Pane">197 <Tab title="Pane">
198 Ein Pane ist eine Seitenleiste neben dem Transkript in einem breiten Vollbildterminal oder eine gerahmte Region über der Eingabeaufforderung. Mit mehreren offenen Panes erhält jedes eine Registerkarte, die seinen Titel anzeigt.198 Ein Pane ist eine Seitenleiste neben dem Transkript in einem breiten Vollbild-Terminal, andernfalls ein umrahmter Bereich über dem Prompt. Wenn mehrere Panes geöffnet sind, erhält jedes einen Tab, der seinen Titel anzeigt.
199 199
200 Ein Pane erscheint, wenn Ihr Mod `$.ui.open` mit einer `id` aufruft, die Sie wählen, wie in `$.ui.open({ id: 'hello-tabs' })`. [Öffnen Sie ein Pane zum richtigen Zeitpunkt](#open-a-pane-at-the-right-time) behandelt die anderen Felder und wann ein Pane auf ein breiteres Terminal wartet.200 Ein Pane erscheint, wenn Ihr Mod `$.ui.open` mit einer von Ihnen gewählten `id` aufruft, etwa `$.ui.open({ id: 'hello-tabs' })`. [Ein Pane zum richtigen Zeitpunkt öffnen](#open-a-pane-at-the-right-time) behandelt die übrigen Felder und wann ein Pane auf ein breiteres Terminal wartet.
201 201
202 Um in Ihrem Pane zu zeichnen, filtern Sie auf `{ component: 'Pane' }` und überprüfen Sie, dass `e.requestId` Ihre `id` ist.202 Um in Ihrem Pane zu zeichnen, filtern Sie auf `{ component: 'Pane' }` und prüfen Sie, ob `e.requestId` Ihre `id` ist.
203 </Tab>203 </Tab>
204 204
205 <Tab title="Band über der Eingabeaufforderung">205 <Tab title="Band über dem Prompt">
206 Das Band ist ein Streifen direkt über der Eingabeaufforderung. Es ist immer da, und jeder Mod teilt es sich.206 Das Band ist ein Streifen direkt über dem Prompt-Eingabefeld. Es ist immer vorhanden, und alle Mods teilen es sich.
207 207
208 Ihr Hook gibt einen Baum zurück, um etwas im Band zu zeigen, oder `next(e)`, um nichts zu zeigen. Ein Baum ersetzt das, was die Mods [nach Ihrem](/docs/de/plugins/mods/events#the-order-mods-run-in) dort zeichnen. Um das Ihre zu behalten, setzen Sie das Ergebnis von `await next(e)` unter die Kinder eines [`Box`](#build-a-tree-from-elements) in Ihrem Baum.208 Ihr Hook gibt einen Baum zurück, um etwas im Band anzuzeigen, oder `next(e)`, um nichts anzuzeigen. Ein Baum ersetzt, was die Mods [nach Ihrem](/docs/de/plugins/mods/events#the-order-mods-run-in) dort zeichnen. Um deren Inhalte zu behalten, fügen Sie das Ergebnis von `await next(e)` unter die Kinder einer [`Box`](#build-a-tree-from-elements) in Ihrem Baum ein.
209 209
210 Um im Band zu zeichnen, filtern Sie auf `{ component: 'AbovePrompt' }`.210 Um im Band zu zeichnen, filtern Sie auf `{ component: 'AbovePrompt' }`.
211 </Tab>211 </Tab>
212</Tabs>212</Tabs>
213 213
214<h3 id="change-what-claude-code-already-draws">214<h3 id="change-what-claude-code-already-draws">
215 Ändern Sie, was Claude Code bereits zeichnet215 Ändern, was Claude Code bereits zeichnet
216</h3>216</h3>
217 217
218Claude Code zeichnet den Großteil seiner Benutzeroberfläche selbst: Nachrichten, Tool-Call-Zeilen, den Spinner und mehr. Jeder dieser Teile ist auch eine Render-Site, daher kann ein Mod ihn umgestalten oder ersetzen. Um einen zu ändern, filtern Sie Ihren `ui.render` Hook auf seinen Namen aus dieser Tabelle:218Claude Code zeichnet den Großteil seiner Oberfläche selbst: Nachrichten, Zeilen für Tool-Aufrufe, den Spinner und mehr. Jeder dieser Teile ist ebenfalls eine Render-Stelle, sodass ein Mod ihn umgestalten oder ersetzen kann. Um einen davon zu ändern, filtern Sie Ihren `ui.render`-Hook auf seinen Namen aus dieser Tabelle:
219 219
220| Site | Was es ist |220| Stelle | Was sie ist |
221| :- | :- |221| :- | :- |
222| `UserMessage`, `AssistantMessage` | Eine Nachricht im Transkript |222| `UserMessage`, `AssistantMessage` | Eine Nachricht im Transkript |
223| `ToolUse`, `ToolResult`, `ToolGroup` | Die Zeile eines Tool-Calls, sein Ergebnis und eine gefaltete Reihe von Calls |223| `ToolUse`, `ToolResult`, `ToolGroup` | Die Zeile eines Tool-Aufrufs, sein Ergebnis und eine eingeklappte Gruppe von Aufrufen |
224| `CommandOutput` | Die Zeile, die ein Befehl gedruckt hat |224| `CommandOutput` | Die Zeile, die ein Befehl ausgegeben hat |
225| `AskUserQuestion` | Der Dialog, den Claude öffnet, um Sie eine Frage zu stellen |225| `AskUserQuestion` | Der Dialog, den Claude öffnet, um Ihnen eine Frage zu stellen |
226| `Spinner`, `ToolProgress`, `TurnDuration` | Statuszeilen für einen Turn: die Zeile, die animiert wird, während Claude arbeitet, eine laufende Tool-Fortschrittszeile und die Zeile, die einen Turn schließt |226| `Spinner`, `ToolProgress`, `TurnDuration` | Statuszeilen für einen Turn: die Zeile, die animiert wird, während Claude arbeitet, die Live-Fortschrittszeile eines laufenden Tools und die Zeile, die einen Turn abschließt |
227| `InfoNotice`, `SessionMode`, `PromptHint` | Statuszeilen unter dem Logo, die Modusbezeichnungen in der Fußzeile und die Hinweiszeile unter der Eingabeaufforderung |227| `InfoNotice`, `SessionMode`, `PromptHint` | Statuszeilen unter dem Logo, die Modus-Bezeichnungen in der Fußzeile und die Hinweiszeile unter dem Prompt |
228 228
229An einer Site, die Claude Code bereits zeichnet, hat Ihr Hook drei Möglichkeiten: ein Detail ändern, die Zeichnung ersetzen oder sie allein lassen. Wählen Sie eine Registerkarte, um jede auf den Spinner angewendet zu sehen. Die Beispiele lesen eine `calls` Variable, die ein anderer Hook zählt, wie im [Tutorial-Mod](/docs/de/plugins/mods/create#write-a-mod-yourself).229An einer Stelle, die Claude Code bereits zeichnet, kann Ihr Hook ein Detail ändern, die Darstellung ersetzen oder sie unverändert lassen. Wählen Sie einen Tab aus, um jede Variante auf den Spinner angewendet zu sehen. Die Beispiele lesen eine Variable `calls`, die ein anderer Hook hochzählt, wie im [Tutorial-Mod](/docs/de/plugins/mods/create#write-a-mod-yourself).
230 230
231<Tabs>231<Tabs>
232 <Tab title="Ändern Sie ein Detail">232 <Tab title="Ein Detail ändern">
233 Um Claude Codes Zeichnung zu behalten und einen Teil davon zu ändern, übergeben Sie `next` eine Kopie des Ereignisses mit geänderten `props`. Dieser Hook ändert den Text nach dem Wort des Spinners:233 Um die Darstellung von Claude Code beizubehalten und nur einen Teil davon zu ändern, übergeben Sie an `next` eine Kopie des Events mit geänderten `props`. Dieser Hook ändert den Text nach dem Wort des Spinners:
234 234
235 ```javascript theme={null}235 ```javascript theme={null}
236 on('ui.render', { component: 'Spinner' }, async ($, e, next) => {236 on('ui.render', { component: 'Spinner' }, async ($, e, next) => {
239 })239 })
240 ```240 ```
241 241
242 Der Spinner behält seine Animation und sein Wort, und Ihr Text folgt dem Wort:242 Der Spinner behält seine Animation und sein Wort, und Ihr Text folgt auf das Wort:
243 243
244 ```text theme={null}244 ```text theme={null}
245 Thinking · tool calls: 2…245 Thinking · tool calls: 2…
246 ```246 ```
247 </Tab>247 </Tab>
248 248
249 <Tab title="Ersetzen Sie die Zeichnung">249 <Tab title="Die Darstellung ersetzen">
250 Um etwas Eigenes an der Stelle des Spinners zu zeichnen, geben Sie einen Baum zurück und rufen Sie `next` nicht auf. Dieser Hook zeichnet eine Textzeile, wo der Spinner wäre:250 Um anstelle der Stelle etwas Eigenes zu zeichnen, geben Sie einen Baum zurück und rufen Sie `next` nicht auf. Dieser Hook zeichnet eine Textzeile dort, wo sonst der Spinner wäre:
251 251
252 ```javascript theme={null}252 ```javascript theme={null}
253 on('ui.render', { component: 'Spinner' }, async ($, e) => {253 on('ui.render', { component: 'Spinner' }, async ($, e) => {
257 })257 })
258 ```258 ```
259 259
260 Während Claude arbeitet, zeigt Ihre Zeile und Claude Codes Spinner nicht:260 Während Claude arbeitet, wird Ihre Zeile angezeigt und der Spinner von Claude Code nicht:
261 261
262 ```text theme={null}262 ```text theme={null}
263 Claude has made 2 tool calls263 Claude has made 2 tool calls
264 ```264 ```
265 </Tab>265 </Tab>
266 266
267 <Tab title="Lassen Sie es allein">267 <Tab title="Unverändert lassen">
268 Um die Site so zu lassen, wie Claude Code sie zeichnet, geben Sie `next(e)` zurück. Ein Hook tut das oft für einige Ereignisse und nicht für andere. Dieser Hook lässt den Spinner allein, bis es einen Call zu zählen gibt:268 Um die Stelle so zu belassen, wie Claude Code sie zeichnet, geben Sie `next(e)` zurück. Ein Hook tut das oft für manche Events und für andere nicht. Dieser Hook lässt den Spinner unverändert, bis es einen Aufruf zu zählen gibt:
269 269
270 ```javascript theme={null}270 ```javascript theme={null}
271 on('ui.render', { component: 'Spinner' }, async ($, e, next) => {271 on('ui.render', { component: 'Spinner' }, async ($, e, next) => {
275 })275 })
276 ```276 ```
277 277
278 Vor dem ersten Tool-Call sieht der Spinner so aus, wie er ohne den Mod aussieht:278 Vor dem ersten Tool-Aufruf sieht der Spinner so aus wie ohne den Mod:
279 279
280 ```text theme={null}280 ```text theme={null}
281 Thinking…281 Thinking…
283 </Tab>283 </Tab>
284</Tabs>284</Tabs>
285 285
286Die Berechtigungsaufforderung ist keine Render-Site, daher kann ein Mod nicht ändern, was sie zeigt. Der Frage-Dialog, `AskUserQuestion`, ist einer, daher kann ein Mod diesen ändern.286An diesen Stellen gibt `next(e)` eine Referenz auf die Darstellung von Claude Code zurück, `{ type: 'engine', ref }`, es sei denn, ein Mod, der nach Ihrem ausgeführt wird, hat einen eigenen Baum zurückgegeben. Um zu ändern, was in dieser Darstellung steht, übergeben Sie an `next` eine Kopie des Events mit anderen Props, wie es der Tab **Ein Detail ändern** tut. Sie können die Referenz unverändert zurückgeben oder sie in einer `Box` neben eigene Elemente setzen:
287 287
288Das Terminal und die Desktop-App lösen nicht alle gleichen Sites aus. `Pane`, `AbovePrompt`, `Spinner` und die Transkript-Sites funktionieren in beiden. Ein paar andere Statuszeilen werden nur im Terminal ausgelöst. Die [Render-Sites-Tabelle](/docs/de/plugins/mods/reference#render-sites) listet auf, wo jede ausgelöst wird.288```javascript theme={null}
289on('ui.render', { component: 'Spinner' }, async ($, e, next) => {
290 const { Box, Text } = $.ui.resolve(e)
291 const theirs = await next(e)
292 return Box({ flexDirection: 'column', children: [theirs, Text({ children: ['under the spinner'] })] })
293})
294```
295
296Während Claude arbeitet, wird der Spinner wie zuvor animiert, und `under the spinner` erscheint darunter.
297
298Die Berechtigungsabfrage ist keine Render-Stelle, daher kann ein Mod nicht ändern, was sie anzeigt. Der Fragedialog `AskUserQuestion` ist eine, sodass ein Mod ihn ändern kann. Ein Baum für den Dialog muss die Referenz genau einmal enthalten, mit Ihren Elementen darüber. Andernfalls zeichnet Claude Code seinen eigenen Dialog.
299
300Das Terminal und die Desktop-App lösen nicht alle dieselben Stellen aus. `Pane`, `AbovePrompt`, `Spinner` und die Transkript-Stellen funktionieren in beiden. Einige andere Statuszeilen werden nur im Terminal ausgelöst. Die [Tabelle der Render-Stellen](/docs/de/plugins/mods/reference#render-sites) listet auf, wo jede davon ausgelöst wird.
289 301
290<h3 id="open-a-pane-at-the-right-time">302<h3 id="open-a-pane-at-the-right-time">
291 Öffnen Sie ein Pane zum richtigen Zeitpunkt303 Ein Pane zum richtigen Zeitpunkt öffnen
292</h3>304</h3>
293 305
294Ein Pane erscheint nur, wenn Ihr Mod es öffnet. Wie und wann Sie es öffnen, entscheidet, ob es den Tastaturfokus erhält, wie viel Platz es anfordert und ob es überhaupt in einem schmalen Terminal angezeigt wird.306Ein Pane erscheint nur, wenn Ihr Mod es öffnet. Wie und wann Sie es öffnen, entscheidet darüber, ob es den Tastaturfokus übernimmt, wie viel Platz es beansprucht und ob es in einem schmalen Terminal überhaupt angezeigt wird.
295 307
296Um ein Pane zu öffnen, rufen Sie [`$.ui.open`](/docs/de/plugins/mods/reference#mods-api-methods) mit einer `id` auf, die Sie wählen. Die `id` ist der Name des Pane: Ihr `ui.render` Hook überprüft sie, und Sie übergeben sie erneut, um das Pane zu schließen.308Um ein Pane zu öffnen, rufen Sie [`$.ui.open`](/docs/de/plugins/mods/reference#mods-api-methods) mit einer von Ihnen gewählten `id` auf. Die `id` ist der Name des Panes: Ihr `ui.render`-Hook prüft darauf, und Sie übergeben sie erneut, um das Pane zu schließen.
297 309
298```javascript theme={null}310```javascript theme={null}
299await $.ui.open({ id: 'hello-tabs', title: 'Hello tabs', focus: true })311await $.ui.open({ id: 'hello-tabs', title: 'Hello tabs', focus: true })
305await $.ui.close({ id: 'hello-tabs' })317await $.ui.close({ id: 'hello-tabs' })
306```318```
307 319
308Neben `id` nimmt `$.ui.open` diese optionalen Felder:320Neben `id` akzeptiert `$.ui.open` diese optionalen Felder:
309 321
310| Feld | Was es tut |322| Feld | Funktion |
311| :- | :- |323| :- | :- |
312| `title` | Die Registerkarte des Pane, wenn mehr als ein Pane offen ist |324| `title` | Die Tab-Beschriftung des Panes, wenn mehr als ein Pane geöffnet ist |
313| `focus` | Fordert [Tastaturfokus](#know-which-keys-your-mod-can-receive) an |325| `focus` | Fordert den [Tastaturfokus](#know-which-keys-your-mod-can-receive) an |
314| `closeOnEscape` | Macht Esc das Pane schließen |326| `closeOnEscape` | Sorgt dafür, dass Esc das Pane schließt |
315| `holdToasts` | Hält Toasts, die kleinen Mitteilungen von [`$.ui.toast`](/docs/de/plugins/mods/api#show-something-without-starting-a-turn), bis das Pane schließt |327| `holdToasts` | Hält Toasts, die kleinen Hinweise von [`$.ui.toast`](/docs/de/plugins/mods/api#show-something-without-starting-a-turn), zurück, bis das Pane geschlossen wird |
316| `rows` | Die Höhe, die angefordert wird, wenn das Pane über der Eingabeaufforderung sitzt. Der Standard ist ein Drittel des Platzes. |328| `rows` | Die anzufordernde Höhe, wenn sich das Pane über dem Prompt befindet. Standardmäßig ein Drittel des Platzes. |
317| `columns` | Die Breite, die angefordert wird, wenn das Pane neben dem Transkript sitzt |329| `columns` | Die anzufordernde Breite, wenn sich das Pane neben dem Transkript befindet |
318 330
319`focus`, `closeOnEscape` und `holdToasts` sind optional und akzeptieren nur `true`. Um eines wegzulassen, lassen Sie es weg. Das Übergeben von `false` wirft einen Fehler wie `ui.open: focus is true or left out`. Um eines davon bedingt zu setzen, fügen Sie das Feld nur hinzu, wenn die Bedingung erfüllt ist. Dieser Aufruf fordert Tastaturfokus nur an, wenn `items` nicht leer ist:331`focus`, `closeOnEscape` und `holdToasts` sind optional und akzeptieren nur `true`. Um eines davon wegzulassen, lassen Sie es aus. Die Übergabe von `false` löst einen Fehler wie `ui.open: focus is true or left out` aus. Um eines davon bedingt zu setzen, fügen Sie das Feld nur hinzu, wenn die Bedingung erfüllt ist. Dieser Aufruf fordert den Tastaturfokus nur an, wenn `items` nicht leer ist:
320 332
321```javascript theme={null}333```javascript theme={null}
322const pane = { id: 'hello-tabs', title: 'Hello tabs' }334const pane = { id: 'hello-tabs', title: 'Hello tabs' }
323await $.ui.open(items.length > 0 ? { ...pane, focus: true } : pane)335await $.ui.open(items.length > 0 ? { ...pane, focus: true } : pane)
324```336```
325 337
326Um einem Befehl zu ermöglichen, das Pane zu öffnen, während Claude arbeitet, fügen Sie `immediate: true` hinzu, wenn Sie den [Befehl registrieren](/docs/de/plugins/mods/api#add-a-command). Ohne ihn wartet ein Befehl, der während eines Turns eingegeben wird, bis der Turn endet.338Damit ein Befehl das Pane öffnen kann, während Claude arbeitet, fügen Sie `immediate: true` hinzu, wenn Sie [den Befehl registrieren](/docs/de/plugins/mods/api#add-a-command). Ohne diese Option wartet ein während eines Turns eingegebener Befehl, bis der Turn endet.
327 339
328<h4 id="when-a-pane-waits-for-a-wider-terminal">340<h4 id="when-a-pane-waits-for-a-wider-terminal">
329 Wenn ein Pane auf ein breiteres Terminal wartet341 Wenn ein Pane auf ein breiteres Terminal wartet
330</h4>342</h4>
331 343
332Ein Pane, das Ihr Mod öffnet, ohne gefragt zu werden, erscheint nicht in einem schmalen Terminal, daher kann es einen kleinen Bildschirm nicht übernehmen. Ob es erscheint, hängt davon ab, was es geöffnet hat:344Ein Pane, das Ihr Mod unaufgefordert öffnet, erscheint nicht in einem schmalen Terminal, damit es keinen kleinen Bildschirm vereinnahmen kann. Ob es erscheint, hängt davon ab, wodurch es geöffnet wurde:
333 345
334* **Geöffnet durch etwas, das der Benutzer getan hat**, z. B. ein Befehl, den er ausgeführt hat, oder eine Schaltfläche, die er gedrückt hat, das Pane erscheint bei jeder Breite346* **Durch eine Aktion des Benutzers geöffnet**, etwa einen ausgeführten Befehl oder eine gedrückte Schaltfläche: Das Pane erscheint bei jeder Breite
335* **Geöffnet durch Ihren Mod, der von selbst handelt**, z. B. von einem Timer oder einem [`turn.start`](/docs/de/plugins/mods/events#follow-a-turn) Hook, das Pane erscheint nur in einem Terminal mit mindestens 144 Spalten Breite. Nachdem der Benutzer dieses Pane einmal selbst geöffnet hat, reichen 110 Spalten aus.347* **Durch Ihren Mod von sich aus geöffnet**, etwa über einen Timer oder einen [`turn.start`](/docs/de/plugins/mods/events#follow-a-turn)-Hook: Das Pane erscheint nur in einem Terminal mit mindestens 144 Spalten Breite. Nachdem der Benutzer dieses Pane einmal selbst geöffnet hat, reichen 110 Spalten aus.
336 348
337Wenn das Pane erscheint, wird `$.ui.open` zu `{ isPlaced: true }` aufgelöst. Wenn das Pane wartet, ist `isPlaced` `false` und `reason` ist ein String, der sagt, warum. Ein wartendes Pane erscheint, wenn der Benutzer es öffnet oder das Terminal verbreitert. Um zu sagen, dass etwas verfügbar ist, ohne ein Pane zu öffnen, rufen Sie `$.ui.toast('Your message')` auf, das eine kleine Mitteilung zeigt, die nach ein paar Sekunden verschwindet.349Wenn das Pane erscheint, wird `$.ui.open` zu `{ isPlaced: true }` aufgelöst. Wenn das Pane wartet, ist `isPlaced` `false`, und `reason` ist ein String, der den Grund angibt. Ein wartendes Pane erscheint, wenn der Benutzer es öffnet oder das Terminal verbreitert. Um mitzuteilen, dass etwas verfügbar ist, ohne ein Pane zu öffnen, rufen Sie `$.ui.toast('Your message')` auf, das eine Toast-Benachrichtigung anzeigt.
338 350
339<h2 id="build-a-tree-from-elements">351<h2 id="build-a-tree-from-elements">
340 Erstellen Sie einen Baum aus Elementen352 Einen Baum aus Elementen erstellen
341</h2>353</h2>
342 354
343Was ein `ui.render` Hook zurückgibt, ist ein Element-Baum: eine Beschreibung dessen, was zu zeichnen ist, bestehend aus Boxen, Text und Steuerelementen, die ineinander verschachtelt sind. Sie beschreiben die Zeichnung, und Claude Code rendert sie im Terminal oder der Desktop-App.355Was ein `ui.render`-Hook zurückgibt, ist ein Elementbaum: eine Beschreibung dessen, was gezeichnet werden soll, bestehend aus Boxen, Text und Steuerelementen, die ineinander verschachtelt sind. Sie beschreiben die Zeichnung, und Claude Code rendert sie im Terminal oder in der Desktop-App.
344 356
345Um die Elemente zu erhalten, rufen Sie `$.ui.resolve(e)` in Ihrem Hook auf, wie in `const { Box, Text, Button } = $.ui.resolve(e)`. Jedes Element ist eine Funktion. Sie übergeben ihr Props, und Sie setzen die Elemente und Strings, die darin gehen, in `children`.357Um die Elemente zu erhalten, rufen Sie in Ihrem Hook `$.ui.resolve(e)` auf, etwa mit `const { Box, Text, Button } = $.ui.resolve(e)`. Jedes Element ist eine Funktion. Sie übergeben ihr Props und legen die Elemente und Strings, die darin enthalten sein sollen, in `children` ab.
346 358
347Die meisten Zeichnungen verwenden vier Elemente. Wählen Sie eine Registerkarte, um jedes zu sehen und wie das Terminal es zeichnet:359Wählen Sie einen Tab aus, um die gängigsten Elemente und ihre Darstellung im Terminal zu sehen:
348 360
349<Tabs>361<Tabs>
350 <Tab title="Text">362 <Tab title="Text">
351 `Text` zeichnet einen String mit optionalem Styling wie `bold` und `color`:363 `Text` zeichnet einen String, optional mit Formatierung wie `bold` und `color`:
352 364
353 ```javascript theme={null}365 ```javascript theme={null}
354 Text({ children: ['This is the first tab.'] })366 Text({ children: ['This is the first tab.'] })
360 </Tab>372 </Tab>
361 373
362 <Tab title="Box">374 <Tab title="Box">
363 `Box` ordnet an, was darin ist, in einer Reihe oder einer Spalte. Diese setzt eine Schaltfläche und eine Textzeile nebeneinander, zwei Spalten auseinander:375 `Box` ordnet seinen Inhalt in einer Zeile oder einer Spalte an. Dieses Beispiel platziert eine Schaltfläche und eine Textzeile nebeneinander, zwei Spalten voneinander entfernt:
364 376
365 ```javascript theme={null}377 ```javascript theme={null}
366 Box({378 Box({
379 </Tab>391 </Tab>
380 392
381 <Tab title="Button">393 <Tab title="Button">
382 `Button` ist ein Steuerelement, das der Benutzer drücken kann. Es führt Ihren `onPress` Callback aus. Mit `plain: true` hat es keine Klammern und zeigt seine Hotkey:394 `Button` ist ein Steuerelement, das der Benutzer drücken kann. Es führt Ihren `onPress`-Callback aus. Mit `plain: true` hat es keine Klammern und zeigt sein Tastenkürzel an:
383 395
384 ```javascript theme={null}396 ```javascript theme={null}
385 Button({ key: 'more', label: 'Add one', onPress: addOne })397 Button({ key: 'more', label: 'Add one', onPress: addOne })
393 </Tab>405 </Tab>
394 406
395 <Tab title="Input">407 <Tab title="Input">
396 `Input` ist ein Textfeld. Es führt Ihren `onSubmit` Callback mit dem Text aus, wenn der Benutzer Enter drückt:408 `Input` ist ein Textfeld. Es führt Ihren `onSubmit`-Callback mit dem Text aus, wenn der Benutzer die Eingabetaste drückt:
397 409
398 ```javascript theme={null}410 ```javascript theme={null}
399 Input({411 Input({
407 ```419 ```
408 420
409 ```text theme={null}421 ```text theme={null}
410 Note: Type a note and press Enter ⏎ add422 Note: Type a note and press Enter
411 ```423 ```
412 </Tab>424 </Tab>
413</Tabs>425</Tabs>
414 426
415Diese Tabelle listet jedes Element auf:427Die [Oberflächengalerie](/docs/de/plugins/mods/gallery) enthält Beispiele und Screenshots der meisten Elemente. Diese Tabelle listet alle Elemente auf:
416 428
417| Element | Was es zeichnet | Wo |429| Element | Was es zeichnet | Wo |
418| :- | :- | :- |430| :- | :- | :- |
419| `Box` | Ein Flex-Container. Nimmt Layout-Props wie `flexDirection`, `columnGap`, `padding`, `borderStyle` und `width`. | Überall |431| `Box` | Einen Flex-Container. Akzeptiert Layout-Props wie `flexDirection`, `columnGap`, `padding`, `borderStyle` und `width`. | Überall |
420| `Text` | Gestylter Text. Nimmt `color`, `bold`, `dimColor`, `italic` und `wrap`. Ein `color` ist ein Theme-Schlüssel oder eine Farbe wie `'red'`. Ein `wrap` ist `'wrap'`, `'truncate'`, `'truncate-start'`, `'truncate-middle'` oder `'truncate-end'`. | Überall |432| `Text` | Formatierten Text. Akzeptiert `color`, `bold`, `dimColor`, `italic` und `wrap`. Eine `color` ist ein Theme-Schlüssel oder eine Farbe wie `'red'`. Ein `wrap` ist `'wrap'`, `'truncate'`, `'truncate-start'`, `'truncate-middle'` oder `'truncate-end'`. | Überall |
421| `Button` | Ein Steuerelement, das `onPress` aufruft | Überall |433| `Button` | Ein Steuerelement, das `onPress` aufruft | Überall |
422| `Link`, `Code`, `Markdown` | Ein Link mit `href` und einem optionalen `label`, ein Codeblock und Text, der so formatiert ist wie Claude's Antworten. `Markdown` nimmt seinen Inhalt in einem `text` Prop, nicht in `children`, und braucht einen `key`, wenn Sie `onLinkPress` übergeben. | Überall |434| `Link`, `Code`, `Markdown` | Einen Link mit `href` und einem optionalen `label`, einen Codeblock und Text, der wie die Antworten von Claude formatiert ist. `Markdown` erhält seinen Inhalt in einer `text`-Prop, nicht in `children`, und benötigt einen `key`, wenn Sie `onLinkPress` übergeben. | Überall |
423| `Input`, `Select` | Ein Textfeld und ein Picker | Terminal, Desktop |435| `Input`, `Select` | Ein Textfeld und ein Dropdown-Menü | Terminal, Desktop |
424| `Svg` | Ein SVG-Dokument | Desktop |436| `Svg` | Ein SVG-Dokument | Desktop |
425| `Client` | Eine Region, die von einer zweiten Datei von Ihnen gezeichnet wird, für Animation und Zeigereingabe. Diese Datei erhält keine Mods API. Sie erreicht Ihre Hooks nur durch das Posten von Daten, die als `ui.message` Ereignis ankommen. | Terminal, Desktop |437| `Client` | Einen Bereich, der von einer zweiten Datei von Ihnen gezeichnet wird, für Animationen und Zeigereingaben. Diese Datei erhält keine Mods-API. Sie erreicht Ihre Hooks nur, indem sie Daten sendet, die als `ui.message`-Event ankommen. | Terminal, Desktop |
426| `Raster`, `Image` | Ein [Gitter von farbigen Zellen](#draw-a-grid-of-colored-cells) und ein Bild | Terminal |438| `Raster`, `Image` | Ein [Raster aus farbigen Zellen](#draw-a-grid-of-colored-cells) und ein Bild | Terminal |
427 439
428Wenn Ihr Modul eine `.tsx` oder `.jsx` Datei ist, können Sie den Baum als JSX schreiben. Destrukturieren Sie die Elemente zuerst aus `$.ui.resolve(e)`, da ein Hooks-Modul keine Element-Globals hat.440Wenn Ihr Modul eine `.tsx`- oder `.jsx`-Datei ist, können Sie den Baum als JSX schreiben. Destrukturieren Sie die Elemente zuerst aus `$.ui.resolve(e)`.
429 441
430Wenn ein Baum ein Element verwendet, das die App nicht hat, ein Prop, das ein Element nicht nimmt, oder ein Kind, wo keines geht, zeichnet Claude Code seine eigene Version der Site.442Wenn ein Baum ein Element verwendet, das die App nicht kennt, eine Prop, die ein Element nicht akzeptiert, oder ein Kind an einer Stelle, an der keines vorgesehen ist, zeichnet Claude Code seine eigene Version der Stelle.
431 443
432In einer Sitzung, die mit `--plugin-dir` gestartet wurde, sagt eine Transkriptzeile so, wie `ui.render (Pane) refused: Text prop "bogusProp" is not allowed; the engine drew its own`. Das [Debug-Protokoll](/docs/de/plugins/mods/troubleshoot#read-the-debug-log) zeichnet es als `ui.render (Pane): a hook returned a tree that does not validate` mit dem gleichen Grund auf. Nichts anderes erscheint in der Sitzung, also wenn eine Zeichnung nicht angezeigt wird, überprüfen Sie diese Zeile oder das Protokoll.444In einer mit `--plugin-dir` gestarteten Sitzung weist eine Zeile im Transkript darauf hin, etwa `ui.render (Pane) refused: Text prop "bogusProp" is not allowed; the engine drew its own`. Das [Debug-Log](/docs/de/plugins/mods/troubleshoot#read-the-debug-log) vermerkt dies als `ui.render (Pane): a hook returned a tree that does not validate` mit derselben Begründung. Sonst erscheint nichts in der Sitzung. Wenn eine Zeichnung also nicht angezeigt wird, prüfen Sie diese Zeile oder das Log.
433 445
434<h3 id="draw-a-grid-of-colored-cells">446<h3 id="draw-a-grid-of-colored-cells">
435 Zeichnen Sie ein Gitter von farbigen Zellen447 Ein Raster aus farbigen Zellen zeichnen
436</h3>448</h3>
437 449
438Für eine Wärmekarte, eine Sparkline oder ein Spielbrett im Terminal zeichnen Sie ein `Raster` und nicht ein `Box` für jede Zelle. Ein `Raster` nimmt einen `key`, seine Größe in `columns` und `rows` und `cells`, die jede Zelle in einen String packt. Jede Zelle sind drei Zahlen: der Code-Punkt des Zeichens, seine Farbe und seine Hintergrundfarbe. Eine Farbe ist eine Hexadezimalzahl mit zwei Ziffern jeweils für Rot, Grün und Blau, wie `0xc62828` für ein Rot oder `0x01000000` für das Standard des Terminals.450Für eine Heatmap, eine Sparkline oder ein Spielbrett im Terminal zeichnen Sie ein einziges `Raster` statt einer `Box` für jede Zelle. Ein `Raster` erhält einen `key`, seine Größe in `columns` und `rows` sowie `cells`, einen Base64-String, der alle Zellen enthält. Jede Zelle besteht aus drei Zahlen: dem Codepoint des Zeichens, seiner Farbe und seiner Hintergrundfarbe. Eine Farbe ist ein 24-Bit-RGB-Wert in hexadezimaler Schreibweise, etwa `0xc62828` für ein Rot. Der Wert `0x01000000`, eins über diesem Bereich, steht für die Standardfarbe des Terminals.
439 451
440Die Desktop-App hat kein `Raster`, also überprüfen Sie `e.surface` und zeichnen Sie dort Text. Dieser Pane-Hauptteil zeichnet eine drei mal zwei Wärmekarte:452Die Desktop-App hat kein `Raster`. Prüfen Sie daher `e.surface` und zeichnen Sie dort Text. Dieser Pane-Inhalt zeichnet eine Heatmap mit drei mal zwei Zellen:
441 453
442```javascript theme={null}454```javascript theme={null}
443// The value that means "use the terminal's default color"455// The value that means "use the terminal's default color"
469})481})
470```482```
471 483
472Im Terminal zeigt das Pane das Gitter:484Im Terminal zeigt der Pane das Raster an:
473 485
474<img src="https://mintcdn.com/claude-code/dgiVO_Od1X1faduV/images/mods-heat-map.svg?fit=max&auto=format&n=dgiVO_Od1X1faduV&q=85&s=b91bcce3bad74bc851149133d4acc5d5" alt="Ein Pane im Terminal, das ein kleines Gitter von farbigen Blöcken enthält, zwei Reihen von drei. Die obere Reihe ist grün, bernsteinfarben und rot. Die untere Reihe ist grün, grün und bernsteinfarben." width="360" height="132" data-path="images/mods-heat-map.svg" />486<img src="https://mintcdn.com/claude-code/dgiVO_Od1X1faduV/images/mods-heat-map.svg?fit=max&auto=format&n=dgiVO_Od1X1faduV&q=85&s=b91bcce3bad74bc851149133d4acc5d5" alt="Ein Pane im Terminal mit einem kleinen Raster aus farbigen Blöcken, zwei Zeilen zu je drei Blöcken. Die obere Zeile ist grün, gelb und rot. Die untere Zeile ist grün, grün und gelb." width="360" height="132" data-path="images/mods-heat-map.svg" />
475 487
476Das `rows` Array ist der Teil, den Sie ändern würden, und `cellsOf` verwandelt es in den gepackten String. Der Hook zeichnet nur in einem Pane, dessen `id` `heat` ist, also öffnen Sie eines mit `$.ui.open({ id: 'heat' })` von einem Befehl, wie das [`hello-tabs` Beispiel](#build-a-pane-with-tabs) sein Pane öffnet.488Das `rows`-Array ist der Teil, den Sie ändern würden, und `cellsOf` wandelt es in den gepackten String um. Der Hook zeichnet nur in einem Pane, dessen `id` `heat` ist. Öffnen Sie daher einen solchen Pane mit `$.ui.open({ id: 'heat' })` aus einem Befehl heraus, so wie das [`hello-tabs`-Beispiel](#build-a-pane-with-tabs) seinen Pane öffnet.
477 489
478Jedes Zeichen muss eine Zelle breit sein. Um ein `Raster`, das bereits auf dem Bildschirm ist, zu animieren, rufen Sie `$.ui.blit` mit der `id` des Pane als `requestId`, dem `key` des `Raster`, der gleichen Größe und neuen Zellen auf. Für dieses Beispiel ist das `$.ui.blit({ requestId: 'heat', key: 'grid', columns: 3, rows: 2, cells: cellsOf(newRows) })`. Es malt dieses eine Element neu, ohne Ihren `ui.render` Hook erneut auszuführen.490Jedes Zeichen muss genau eine Zelle breit sein. Um ein `Raster` zu animieren, das bereits auf dem Bildschirm ist, rufen Sie `$.ui.blit` mit der `id` des Panes als `requestId`, dem `key` des `Raster`, derselben Größe und neuen Zellen auf. Für dieses Beispiel ist das `$.ui.blit({ requestId: 'heat', key: 'grid', columns: 3, rows: 2, cells: cellsOf(newRows) })`. Dadurch wird nur dieses eine Element neu gezeichnet, ohne Ihren `ui.render`-Hook erneut auszuführen.
479 491
480<h2 id="respond-to-presses-and-typing">492<h2 id="respond-to-presses-and-typing">
481 Reagieren Sie auf Drücke und Eingaben493 Auf Tastendrücke und Eingaben reagieren
482</h2>494</h2>
483 495
484Wenn der Benutzer eine Schaltfläche drückt, in ein Feld tippt oder aus einer Liste auswählt, die Ihr Mod gezeichnet hat, ruft Claude Code die Funktion auf, die Sie diesem Steuerelement gegeben haben, und sie läuft in Ihrem Modul. Jedes Steuerelement nimmt seine eigenen Callbacks:496Wenn der Benutzer eine Schaltfläche drückt, in ein Feld tippt oder aus einer Liste auswählt, die Ihr Mod gezeichnet hat, ruft Claude Code den Callback dieses Steuerelements auf, der in Ihrem Modul ausgeführt wird. Jedes Steuerelement nimmt eigene Callbacks entgegen:
485 497
486* **`Button`**: nimmt `onPress(e)`, wobei `e.surface` die App ist, von der der Druck kam498* **`Button`**: nimmt `onPress(e)` entgegen, wobei `e.surface` die App ist, aus der der Tastendruck kam
487* **`Input`**: nimmt `onSubmit(value)` und `onInput(value)`499* **`Input`**: nimmt `onSubmit(value)` und `onInput(value)` entgegen
488* **`Select`**: nimmt `onSelect(value)` mit seinen Auswahlmöglichkeiten in `options`, eine Liste von mindestens einer Auswahlmöglichkeit mit eindeutigen Werten, wie `[{ value: 'sm', label: 'Small' }, { value: 'lg', label: 'Large' }]`500* **`Select`**: nimmt `onSelect(value)` entgegen, mit seinen Auswahlmöglichkeiten in `options`, einer Liste mit mindestens einer Auswahl mit eindeutigen Werten, etwa `[{ value: 'sm', label: 'Small' }, { value: 'lg', label: 'Large' }]`
489 501
490Ein Test drückt oder tippt in ein Steuerelement nach seinem `key`, also geben Sie jedem einen. Jede Verwendung eines Steuerelements löst auch [`ui.press`, `ui.input` oder `ui.select`](/docs/de/plugins/mods/reference#interface) mit dem `key` in `e.element` aus, und ein anderer Mod kann diese Ereignisse hooken. Sein Hook läuft vor Ihrem Callback, daher sieht er, was der Benutzer in Ihren `Input` tippt und kann es ändern oder an Stelle Ihres Callbacks antworten. Die Mods API hat keine Methode, die die Schaltfläche eines anderen Mods drückt.502Ein Test drückt ein Steuerelement oder tippt in es hinein, indem er es über seinen `key` anspricht, geben Sie also jedem Steuerelement einen. Jede Verwendung eines Steuerelements löst außerdem [`ui.press`, `ui.input` oder `ui.select`](/docs/de/plugins/mods/reference#interface) mit dem `key` in `e.element` aus, und ein anderer Mod kann diese Ereignisse verarbeiten. Sein Hook läuft vor Ihrem Callback, sodass er sieht, was der Benutzer in Ihr `Input` eingibt, und es ändern oder anstelle Ihres Callbacks antworten kann. Die Mods-API hat keine Methode, mit der sich die Schaltfläche eines anderen Mods drücken lässt.
491 503
492<h3 id="know-which-keys-your-mod-can-receive">504<h3 id="know-which-keys-your-mod-can-receive">
493 Tastaturfokus und Hotkeys505 Tastaturfokus und Hotkeys
494</h3>506</h3>
495 507
496Ihr Mod liest die Tastatur nie selbst. Der Benutzer drückt eine Taste, Claude Code entscheidet, welches Ihrer Steuerelemente es ist, und der Callback dieses Steuerelements läuft. Abgesehen von einer [Ziffern-Hotkey auf dem Band](/docs/de/plugins/mods/reference#elements) passiert das nur, während Ihr Pane oder Band den Tastaturfokus hat. Der Rest der Zeit gehen Tasten zur Eingabeaufforderung.508Ihr Mod liest die Tastatur nie selbst. Der Benutzer drückt eine Taste, Claude Code entscheidet, für welches Ihrer Steuerelemente sie bestimmt ist, und der Callback dieses Steuerelements wird ausgeführt. Abgesehen von einem [Ziffern-Hotkey auf dem Band](/docs/de/plugins/mods/reference#elements) geschieht das nur, solange Ihr Bereich oder Band den Tastaturfokus hat. Die übrige Zeit gehen Tastendrücke an den Prompt.
497 509
498<h4 id="how-a-pane-gets-keyboard-focus">510<h4 id="how-a-pane-gets-keyboard-focus">
499 Wie ein Pane den Tastaturfokus erhält511 Wie ein Bereich den Tastaturfokus erhält
500</h4>512</h4>
501 513
502Ein Pane erhält den Tastaturfokus auf eine von drei Arten:514Ein Bereich erhält den Tastaturfokus, wenn:
503 515
504* Ihr Mod öffnet es mit `focus: true` von einem Befehl oder einem Druck516* Ihr Mod ihn mit `focus: true` aus einem Befehl oder einem Tastendruck heraus öffnet
505* Der Benutzer drückt Ctrl+X dann Tab517* Der Benutzer Ctrl+X und dann Tab drückt
506* Der Benutzer klickt darauf518* Der Benutzer darauf klickt
507 519
508Claude Code gewährt `focus: true` nur, während die Eingabeaufforderung leer ist und nichts anderes den Tastaturfokus hat. Ein Pane, das sich öffnet, während der Benutzer tippt, nimmt seine Tastenanschläge nicht.520Claude Code gewährt `focus: true` nur, solange der Prompt leer ist und nichts anderes den Tastaturfokus hat. Ein Bereich, der sich öffnet, während der Benutzer tippt, übernimmt dessen Tastenanschläge nicht.
509 521
510<h4 id="what-each-key-does">522<h4 id="what-each-key-does">
511 Was jede Taste tut523 Was jede Taste bewirkt
512</h4>524</h4>
513 525
514Diese Tabelle listet auf, was eine Taste tut, während Ihr Pane oder Band den Tastaturfokus hat:526Diese Tabelle listet auf, was eine Taste bewirkt, während Ihr Bereich oder Band den Tastaturfokus hat:
515 527
516| Taste | Was es tut |528| Taste | Was sie bewirkt |
517| :- | :- |529| :- | :- |
518| Tab | Bewegt sich zum nächsten Steuerelement |530| Tab | Wechselt zum nächsten Steuerelement |
519| Auf und Ab | Bewegen Sie sich zwischen Steuerelementen, während Ihre Zeichnung passt. Wenn das Pane oder Band mehr Reihen hat, als es anzeigen kann, scrollen sie es. |531| Pfeil nach oben und unten | Wechseln zwischen Steuerelementen, solange Ihre Zeichnung hineinpasst. Wenn der Bereich oder das Band mehr Zeilen hat, als angezeigt werden können, scrollen sie ihn. |
520| Enter | Drückt die fokussierte `Button`, sendet die fokussierte `Input` oder wählt in einem `Select` |532| Enter | Drückt den fokussierten `Button`, sendet das fokussierte `Input` ab oder wählt in einem `Select` aus |
521| Die Hotkey einer Schaltfläche | Drückt diese Schaltfläche. Während ein `Input` den Fokus hat, geht jede druckbare Taste zum Feld. |533| Der Hotkey einer Schaltfläche | Drückt diese Schaltfläche. Solange ein `Input` den Fokus hat, geht jede druckbare Taste an das Feld. |
522| Esc | Gibt den Tastaturfokus zur Eingabeaufforderung zurück. Mit `closeOnEscape: true` schließt es auch das Pane. |534| Esc | Gibt den Tastaturfokus an den Prompt zurück. Mit `closeOnEscape: true` schließt sie außerdem den Bereich. |
523 535
524Ein Mod kann Tab oder die Pfeiltasten nicht an etwas anderes binden, daher steuert ein Spiel mit `w`, `a`, `s` und `d`.536Ein Mod kann Tab oder die Pfeiltasten nicht anderweitig belegen, daher steuert ein Spiel mit `w`, `a`, `s` und `d`.
525 537
526<h4 id="set-a-hotkey-and-the-first-focus">538<h4 id="set-a-hotkey-and-the-first-focus">
527 Setzen Sie eine Hotkey und den ersten Fokus539 Einen Hotkey und den ersten Fokus festlegen
528</h4>540</h4>
529 541
530Zwei Props auf einem Steuerelement entscheiden, wie die Tastatur es erreicht:542Diese Props eines Steuerelements bestimmen, wie die Tastatur es erreicht:
531 543
532* **`hotkey`**: um dem Benutzer zu ermöglichen, eine `Button` mit einer Taste zu drücken, geben Sie ihr eine `hotkey` von einer Ziffer oder einem Kleinbuchstaben, wie in `hotkey: 'a'`544* **`hotkey`**: Damit der Benutzer einen `Button` mit einer Taste drücken kann, geben Sie ihm einen `hotkey` aus einer Ziffer oder einem Kleinbuchstaben, wie in `hotkey: 'a'`
533* **`autoFocus`**: um zu wählen, welches Steuerelement den Fokus hat, wenn das Pane sich öffnet, fügen Sie `autoFocus: true` hinzu. Lassen Sie das Prop bei den anderen weg, da Claude Code `autoFocus: false` ablehnt.545* **`autoFocus`**: Um festzulegen, welches Steuerelement beim Öffnen des Bereichs den Fokus hat, fügen Sie ihm `autoFocus: true` hinzu. Die Prop akzeptiert nur `true`, lassen Sie sie also bei den anderen Steuerelementen weg.
534 546
535Wie eine Hotkey angezeigt wird, hängt von der Schaltfläche und der App ab:547Wie ein Hotkey angezeigt wird, hängt von der Schaltfläche und der App ab:
536 548
537| Schaltfläche | Im Terminal | In der Desktop-App |549| Schaltfläche | Im Terminal | In der Desktop-App |
538| :- | :- | :- |550| :- | :- | :- |
539| Mit Klammern, der Standard | `[ Add one ]`, ohne Hotkey angezeigt | Das Label mit einem kleinen Schlüssel daneben |551| Mit Klammern, der Standard | `[ Add one ]`, ohne angezeigten Hotkey | Die Beschriftung mit einer kleinen Taste daneben |
540| Mit `plain: true` | `1: One` | Das Label mit einem kleinen Schlüssel daneben |552| Mit `plain: true` | `1: One` | Die Beschriftung mit einer kleinen Taste daneben |
541 553
542Im Terminal benennen Sie die Taste im Label einer geklammerten Schaltfläche oder verwenden Sie `plain: true`, damit der Benutzer sehen kann, was zu drücken ist. Die [Elements-Referenz](/docs/de/plugins/mods/reference#elements) hat die anderen `Button` Regeln: `action`, Ziffern-Hotkeys auf dem Band und zwei Schaltflächen auf einer Hotkey.554Nennen Sie im Terminal die Taste in der Beschriftung einer Schaltfläche mit Klammern oder verwenden Sie `plain: true`, damit der Benutzer sehen kann, was er drücken muss. Die [Elementreferenz](/docs/de/plugins/mods/reference#elements) enthält die übrigen `Button`-Regeln: `action`, Ziffern-Hotkeys auf dem Band und zwei Schaltflächen auf einem Hotkey.
543 555
544<h3 id="take-typed-input-and-draw-a-row-for-each-item">556<h3 id="take-typed-input-and-draw-a-row-for-each-item">
545 Nehmen Sie eingegebenen Text und zeichnen Sie eine Reihe für jedes Element557 Texteingaben entgegennehmen und für jedes Element eine Zeile zeichnen
546</h3>558</h3>
547 559
548Viele Panes sind ein Textfeld mit einer Liste darunter. Das Beispiel in diesem Abschnitt ist ein Notizen-Pane: Sie tippen eine Notiz und drücken Enter, um sie hinzuzufügen, und jede Notiz hat eine `x` Schaltfläche, die sie löscht. Mit zwei hinzugefügten Notizen zeichnet das Terminal das Pane so:560Viele Bereiche bestehen aus einem Textfeld mit einer Liste darunter. Das Beispiel in diesem Abschnitt ist ein Notizbereich: Sie tippen eine Notiz und drücken Enter, um sie hinzuzufügen, und jede Notiz hat eine `x`-Schaltfläche, die sie löscht. Mit zwei hinzugefügten Notizen zeichnet das Terminal den Bereich so:
549 561
550```text theme={null}562```text theme={null}
551╭──────────────────────────────────────────────────────────╮563╭──────────────────────────────────────────────────────────╮
555╰──────────────────────────────────────────────────────────╯567╰──────────────────────────────────────────────────────────╯
556```568```
557 569
558Das Beispiel verwendet zwei Techniken:570Das Beispiel verwendet diese Techniken:
559 571
560* **Nehmen Sie eingegebenen Text**: ein `Input` ruft `onSubmit(value)` mit dem Text des Feldes auf, wenn der Benutzer Enter drückt, und `onInput(value)` bei jeder Änderung572* **Texteingaben entgegennehmen**: Ein `Input` ruft `onSubmit(value)` mit dem Text des Felds auf, wenn der Benutzer Enter drückt, und `onInput(value)` bei jeder Änderung
561* **Zeichnen Sie eine Liste**: ordnen Sie Ihre Daten einer Reihe jeweils zu, und geben Sie jedem `key` der Reihe seine eigene573* **Eine Liste zeichnen**: Ordnen Sie Ihren Daten jeweils eine Zeile zu und geben Sie der Schaltfläche jeder Zeile einen eigenen `key`
562 574
563Dieser Hook zeichnet den Inhalt des Pane:575Dieser Hook zeichnet den Inhalt des Bereichs:
564 576
565```javascript theme={null}577```javascript theme={null}
566// The list the pane draws578// The list the pane draws
618})630})
619```631```
620 632
621Um das Pane zu versuchen:633So probieren Sie den Bereich aus:
622 634
623* **Fügen Sie eine Notiz hinzu**: tippen Sie eine Zeile und drücken Sie Enter. Die Zeile erscheint als neue Reihe, und das Feld leert sich.635* **Eine Notiz hinzufügen**: Tippen Sie eine Zeile und drücken Sie Enter. Die Zeile erscheint als neue Zeile in der Liste, und das Feld wird geleert.
624* **Löschen Sie eine Notiz**: drücken Sie Tab, bis die `x` Schaltfläche der Notiz den Fokus hat, dann drücken Sie Enter. Das `x` ist das Label der Schaltfläche und keine Hotkey, daher drückt das Tippen des Buchstabens es nicht.636* **Eine Notiz löschen**: Drücken Sie Tab, bis die `x`-Schaltfläche der Notiz den Fokus hat, und drücken Sie dann Enter. Das `x` ist die Beschriftung der Schaltfläche und kein Hotkey, daher wird sie durch Tippen des Buchstabens nicht gedrückt.
625 637
626Jede Änderung folgt dem gleichen Render-Zyklus wie `hello-tabs`: Der Callback ändert `notes`, ruft `redraw` auf und speichert die Liste in `$.store`.638Jede Änderung folgt demselben Render-Zyklus wie `hello-tabs`: Der Callback ändert `notes`, ruft `redraw` auf und speichert die Liste in `$.store`.
627 639
628Das Feld leert sich nach jedem Submit wegen seines `value` Props. `value` ist der Text, den das Feld hält, wenn es gezeichnet wird, und das Tippen des Benutzers ersetzt ihn, bis Ihr Hook das Feld erneut zeichnet. Das Beispiel zeichnet das Feld immer mit `''`.640Das Feld wird nach jedem Absenden wegen seiner `value`-Prop geleert. `value` ist der Text, den das Feld beim Zeichnen enthält, und die Eingaben des Benutzers ersetzen ihn, bis Ihr Hook das Feld erneut zeichnet. Das Beispiel zeichnet das Feld immer mit `''`.
629 641
630Das Beispiel speichert die Notizen und lädt sie nicht. Um sie in der nächsten Sitzung zurückzubringen, lesen Sie sie in einem `session.start` Hook, wie `hello-tabs` `count` liest.642Das Beispiel speichert die Notizen, lädt sie aber nicht. Um sie in der nächsten Sitzung wiederherzustellen, lesen Sie sie in einem `session.start`-Hook ein, so wie `hello-tabs` `count` einliest.
631 643
632Drei Props machen die Zeile des Feldes aus, `Note: Type a note and press Enter ⏎ add`:644Diese Props bilden die Zeile des Felds, `Note: Type a note and press Enter ⏎ add`:
633 645
634| Prop | Im Beispiel | Was es ist |646| Prop | Im Beispiel | Was sie ist |
635| :- | :- | :- |647| :- | :- | :- |
636| `label` | `Note` | Der Text vor dem Feld. Das Terminal zeichnet `: ` danach. |648| `label` | `Note` | Der Text vor dem Feld. Das Terminal zeichnet `: ` dahinter. |
637| `placeholder` | `Type a note and press Enter` | Schwacher Text, der angezeigt wird, während das Feld leer ist |649| `placeholder` | `Type a note and press Enter` | Abgeblendeter Text, der angezeigt wird, solange das Feld leer ist |
638| `submitLabel` | `add` | Das Wort nach `⏎`, das sagt, was Enter tut |650| `submitLabel` | `add` | Das Wort nach `⏎`, das angibt, was Enter bewirkt |
639 651
640Das Absenden eines `Input` startet keinen Turn, es sei denn, Ihr Callback ruft [`$.prompt.submit`](/docs/de/plugins/mods/api#start-a-turn-from-a-background-job) auf.652Das Absenden eines `Input` startet keinen Turn, es sei denn, Ihr Callback ruft [`$.prompt.submit`](/docs/de/plugins/mods/api#start-a-turn-from-a-background-job) auf.
641 653
642<h2 id="redraw-when-something-changes">654<h2 id="redraw-when-something-changes">
643 Zeichnen Sie eine Site neu655 Einen Bereich neu zeichnen
644</h2>656</h2>
645 657
646Eine Zeichnung ist ein Schnappschuss: Sie zeigt, was Ihr `ui.render` Hook das letzte Mal zurückgegeben hat, als der Hook lief. Um etwas Neues zu zeigen, muss der Hook erneut laufen. Claude Code führt ihn für einige Änderungen erneut aus, und Ihr Mod fragt nach dem Rest.658Eine Zeichnung ist eine Momentaufnahme: Sie zeigt, was Ihr `ui.render`-Hook beim letzten Ausführen zurückgegeben hat. Damit etwas Neues angezeigt wird, muss der Hook erneut ausgeführt werden. Claude Code führt ihn bei einigen Änderungen erneut aus, und für die übrigen fordert Ihr Mod dies an.
647 659
648<h3 id="when-claude-code-redraws-without-being-asked">660<h3 id="when-claude-code-redraws-without-being-asked">
649 Wenn Claude Code ohne Aufforderung neu zeichnet661 Wann Claude Code ohne Aufforderung neu zeichnet
650</h3>662</h3>
651 663
652Claude Code führt Ihren `ui.render` Hook erneut aus, wenn sich die Props der Site ändern oder die Breite des Terminals ändert. Es führt den Hook nicht auf einem Timer aus, und es kann nicht sagen, wenn sich eine Variable in Ihrem Modul ändert.664Claude Code führt Ihren `ui.render`-Hook erneut aus, wenn sich die Props des Bereichs oder die Breite des Terminals ändern. Der Hook wird nicht zeitgesteuert ausgeführt, und Claude Code kann nicht erkennen, wann sich eine Variable in Ihrem Modul ändert.
653 665
654<h3 id="redraw-when-your-data-changes">666<h3 id="redraw-when-your-data-changes">
655 Zeichnen Sie neu, wenn sich Ihre Daten ändern667 Neu zeichnen, wenn sich Ihre Daten ändern
656</h3>668</h3>
657 669
658Um Ihre Sites nach Ihren eigenen Datenänderungen erneut zu zeichnen, rufen Sie `$.ui.invalidate('ui.render')` auf. Dieses Pane zählt Drücke. Der Callback der Schaltfläche ändert `count` und fragt dann nach einem Neuzeichnen:670Damit Ihre Bereiche nach einer Änderung Ihrer eigenen Daten neu gezeichnet werden, rufen Sie `$.ui.invalidate('ui.render')` auf. Dieses Panel zählt Tastendrücke. Der Callback der Schaltfläche ändert `count` und fordert dann ein Neuzeichnen an:
659 671
660```javascript theme={null}672```javascript theme={null}
661let count = 0673let count = 0
682})694})
683```695```
684 696
685Jeder Druck erhöht die Zahl im Pane. Das [`hello-tabs` Beispiel](#build-a-pane-with-tabs) wickelt den gleichen Aufruf in seine `redraw` Funktion.697Jeder Druck erhöht die Zahl im Panel. Das [`hello-tabs`-Beispiel](#build-a-pane-with-tabs) kapselt denselben Aufruf in seiner Funktion `redraw`.
686 698
687Ein Wert, den Sie in [`$.state`](#keep-a-value-in-\$-state) halten, braucht den Aufruf nicht, da das Schreiben des Wertes die Sites neu zeichnet, die ihn lesen.699Ein Wert, den Sie in [`$.state`](#keep-a-value-in-\$-state) speichern, benötigt diesen Aufruf nicht, da das Schreiben des Werts die Bereiche neu zeichnet, die ihn lesen.
688 700
689<h3 id="redraw-on-a-timer">701<h3 id="redraw-on-a-timer">
690 Zeichnen Sie auf einem Timer neu702 Zeitgesteuert neu zeichnen
691</h3>703</h3>
692 704
693Um eine Uhr, einen Countdown oder einen Wert von außerhalb der Sitzung aktuell zu halten, zeichnen Sie nach einem Zeitplan neu. Starten Sie einen Timer im `session.start` Hook des Moduls. Wenn das Modul bereits einen hat, wie `hello-tabs`, fügen Sie die [`$.clock.every`](/docs/de/plugins/mods/api#run-work-in-the-background) Zeile hinzu:705Um eine Uhr, einen Countdown oder einen Wert von außerhalb der Sitzung aktuell zu halten, zeichnen Sie nach einem Zeitplan neu. Starten Sie einen Timer im `session.start`-Hook des Moduls. Wenn das Modul bereits einen hat, wie `hello-tabs`, fügen Sie die Zeile mit [`$.clock.every`](/docs/de/plugins/mods/api#run-work-in-the-background) dort hinzu:
694 706
695```javascript theme={null}707```javascript theme={null}
696on('session.start', async ($, e, next) => {708on('session.start', async ($, e, next) => {
700})712})
701```713```
702 714
703Claude Code führt jetzt Ihren `ui.render` Hook einmal pro Sekunde aus. Der Timer stoppt, wenn das Modul neu geladen wird, und die neue Kopie des Moduls startet ihren eigenen.715Claude Code führt Ihren `ui.render`-Hook nun einmal pro Sekunde aus. Der Timer stoppt, wenn das Modul neu geladen wird, und die neue Instanz des Moduls startet ihren eigenen.
704 716
705<h3 id="how-often-a-site-can-redraw">717<h3 id="how-often-a-site-can-redraw">
706 Wie oft eine Site neu gezeichnet werden kann718 Wie oft ein Bereich neu gezeichnet werden kann
707</h3>719</h3>
708 720
709Claude Code begrenzt, wie oft es neu zeichnet, daher kann Ihr Mod `$.ui.invalidate` so oft aufrufen, wie sich seine Daten ändern. Das sichtbare Pane und das Band haben ein höheres Limit als andere Sites, und die [Limits-Tabelle](/docs/de/plugins/mods/reference#limits) hat die Zahlen.721Claude Code drosselt das Neuzeichnen eines Bereichs, sodass Ihr Mod `$.ui.invalidate` so oft aufrufen kann, wie sich seine Daten ändern. Wie oft jeder Bereich neu gezeichnet werden kann, entnehmen Sie der [Tabelle der Grenzwerte](/docs/de/plugins/mods/reference#limits).
710 722
711Aufrufe, die schneller als das Limit kommen, werden in einem Neuzeichnen kombiniert. Dieses Neuzeichnen führt Ihren Hook einmal aus, und der Hook liest Ihre Daten, wie sie in diesem Moment sind, daher zeigt der neueste Wert und die Werte dazwischen nicht. Eine Animation kann nicht schneller als das Limit laufen.723Aufrufe, die schneller als der Grenzwert eintreffen, werden zu einem einzigen Neuzeichnen zusammengefasst. Dieses Neuzeichnen führt Ihren Hook einmal aus, und der Hook liest Ihre Daten in ihrem Zustand zu diesem Zeitpunkt, sodass der neueste Wert angezeigt wird und die Zwischenwerte nicht. Eine Animation kann nicht schneller als der Grenzwert laufen.
712 724
713<h2 id="keep-state">725<h2 id="keep-state">
714 Behalten Sie den Status726 Zustand speichern
715</h2>727</h2>
716 728
717Ein Mod hat drei Orte, um einen Wert zu halten, und sie unterscheiden sich darin, wie lange der Wert dauert: bis das Modul neu geladen wird, bis die Sitzung endet oder von einer Sitzung zur nächsten. Wählen Sie danach, wie lange der Wert dauern muss:729Wo ein Mod einen Wert speichert, bestimmt, wie lange der Wert erhalten bleibt: bis das Modul neu geladen wird, bis die Sitzung endet oder von einer Sitzung zur nächsten. Wählen Sie danach, wie lange der Wert erhalten bleiben muss:
718 730
719| Halten Sie es in | Es dauert bis | Verwenden Sie es für |731| Speichern in | Erhalten bis | Verwenden für |
720| :- | :- | :- |732| :- | :- | :- |
721| Eine Modulebenen-Variable | Das Modul wird neu geladen, was jedes Mal passiert, wenn Sie eine Datei während der Entwicklung speichern | Werte, die Sie verlieren können, wie `tab` in `hello-tabs` |733| Einer Variablen auf Modulebene | Das Modul neu geladen wird, was während der Entwicklung bei jedem Speichern einer Datei geschieht | Werte, deren Verlust Sie in Kauf nehmen können, wie `tab` in `hello-tabs` |
722| `$.state` | Die Sitzung endet oder der Benutzer führt `/clear`, `/resume` oder `/branch` aus | Werte, die eine Zeichnung abhängt, die einen Reload überleben sollten |734| `$.state` | Die Sitzung endet oder der Benutzer `/clear`, `/resume` oder `/branch` ausführt | Werte, von denen eine Darstellung abhängt und die ein Neuladen überstehen sollen |
723| `$.store` | Ihr Mod löscht es oder keine Sitzung liest oder schreibt den Store für [`cleanupPeriodDays`](/docs/de/settings-reference#cleanupperioddays). Der Store ist ein Schlüssel-Wert-Speicher, gespeichert als JSON-Datei Ihres Plugins unter `~/.claude/plugins/store/`. | Einstellungen, Verlauf, alles, das der Benutzer das nächste Mal erwartet zu finden |735| `$.store` | Ihr Mod ihn löscht oder keine Sitzung den Store für [`cleanupPeriodDays`](/docs/de/settings-reference#cleanupperioddays) liest oder schreibt. Der Store ist ein Key-Value-Store, der als eigene JSON-Datei Ihres Plugins unter `~/.claude/plugins/store/` gespeichert wird. | Einstellungen, Verlauf, alles, was der Benutzer beim nächsten Mal wiederfinden möchte |
724 736
725`$.store.get(key)` wird zu dem Wert oder `undefined` aufgelöst, und `$.store.set(key, value)` nimmt jeden JSON-Wert.737`$.store.get(key)` wird zum Wert oder zu `undefined` aufgelöst, und `$.store.set(key, value)` akzeptiert jeden JSON-Wert.
726 738
727<h3 id="keep-a-value-in-state">739<h3 id="keep-a-value-in-$-state">
728 Behalten Sie einen Wert in `$.state`740 Einen Wert in `$.state` speichern
729</h3>741</h3>
730 742
731`$.state` hält Werte für die Länge einer Sitzung, und es zeichnet für Sie neu. Es ist reaktiver Status: ein `ui.render` Hook, der einen Wert liest, abonniert ihn, daher zeichnet Claude Code diese Site jedes Mal neu, wenn Sie den Wert schreiben, und Sie rufen `$.ui.invalidate` nicht auf. Ein Wert in `$.state` überlebt auch ein Reload des Moduls, das eine Variable nicht tut.743`$.state` hält Werte für die Dauer einer Sitzung und zeichnet für Sie neu. Es handelt sich um reaktiven Zustand: Ein `ui.render`-Hook, der einen Wert liest, abonniert ihn, sodass Claude Code diese Stelle jedes Mal neu zeichnet, wenn Sie den Wert schreiben, und Sie `$.ui.invalidate` nicht aufrufen müssen. Ein Wert in `$.state` übersteht außerdem ein Neuladen des Moduls, was eine Variable nicht tut.
732 744
733Um es einzurichten, deklarieren Sie Ihre Werte, zeigen Sie Ihr Manifest auf die Deklaration, dann definieren und verwenden Sie jeden Wert. Die Beispiele verschieben den `count` aus `hello-tabs` in `$.state`.745Zur Einrichtung deklarieren Sie Ihre Werte, verweisen in Ihrem Manifest auf die Deklaration und definieren und verwenden dann jeden Wert. Die Beispiele verschieben `count` aus `hello-tabs` in `$.state`.
734 746
735<h4 id="declare-the-values">747<h4 id="declare-the-values">
736 Deklarieren Sie die Werte748 Die Werte deklarieren
737</h4>749</h4>
738 750
739Deklarieren Sie die Werte in einer Typendatei. Der äußere Schlüssel ist der Name Ihres Plugins, und jeder Eintrag darunter ist ein Wert und sein Typ. Speichern Sie dies als `hello-tabs/types/index.d.ts`:751Deklarieren Sie die Werte in einer Typdeklarationsdatei. Der äußere Schlüssel ist der Name Ihres Plugins, und jeder Eintrag darunter ist ein Wert mit seinem Typ. Speichern Sie dies als `hello-tabs/types/index.d.ts`:
740 752
741```typescript hello-tabs/types/index.d.ts theme={null}753```typescript hello-tabs/types/index.d.ts theme={null}
742declare module 'claude-code' {754declare module 'claude-code' {
750```762```
751 763
752<h4 id="point-the-manifest-at-the-declaration">764<h4 id="point-the-manifest-at-the-declaration">
753 Zeigen Sie das Manifest auf die Deklaration765 Im Manifest auf die Deklaration verweisen
754</h4>766</h4>
755 767
756Um `claude plugin validate` zu lassen, Ihren Code gegen diese Datei zu überprüfen, fügen Sie ein `types` Feld zum Manifest mit seinem Pfad hinzu:768Damit `claude plugin validate` Ihren Code anhand dieser Datei prüfen kann, fügen Sie dem Manifest ein Feld `types` mit ihrem Pfad hinzu:
757 769
758```json hello-tabs/.claude-plugin/plugin.json theme={null}770```json hello-tabs/.claude-plugin/plugin.json theme={null}
759{771{
766```778```
767 779
768<h4 id="define-read-and-write-a-value">780<h4 id="define-read-and-write-a-value">
769 Definieren, lesen und schreiben Sie einen Wert781 Einen Wert definieren, lesen und schreiben
770</h4>782</h4>
771 783
772In Ihrem Modul definieren Sie jeden Wert mit einem Standard, lesen ihn beim Zeichnen und schreiben ihn von einem Callback. `atom` benennt einen Wert und seinen Standard, `read` gibt ihn zurück, und `update` schreibt ihn. Die drei Helfer rufen `$.state.get` und `$.state.set` für Sie auf:784Definieren Sie in Ihrem Modul jeden Wert mit einem Standardwert, lesen Sie ihn beim Zeichnen und schreiben Sie ihn aus einem Callback. `atom` benennt einen Wert und seinen Standardwert, `read` gibt ihn zurück und `update` schreibt ihn. Die drei Hilfsfunktionen rufen `$.state.get` und `$.state.set` für Sie auf:
773 785
774```javascript theme={null}786```javascript theme={null}
775import { atom, read, update } from 'claude-code'787import { atom, read, update } from 'claude-code'
784onPress: () => update($, count, (value) => value + 1)796onPress: () => update($, count, (value) => value + 1)
785```797```
786 798
787Da der `ui.render` Hook `count` gelesen hat, führt Claude Code den Hook jedes Mal erneut aus, wenn die Schaltfläche ihn schreibt.799Da der `ui.render`-Hook `count` gelesen hat, führt Claude Code den Hook jedes Mal erneut aus, wenn die Schaltfläche den Wert schreibt.
788 800
789Drei Regeln gelten für den Code:801Für den Code gelten diese Regeln:
790 802
791* **Schreiben Sie `plugin` und `key` als Literal-Strings**: `claude plugin validate` liest sie aus Ihrer Quelle803* **Schreiben Sie `plugin` und `key` als String-Literale**: `claude plugin validate` liest sie aus Ihrem Quellcode
792* **Deklarieren Sie jeden Wert in der Typendatei**: sonst schlägt die Validierung mit `hello-tabs.count is not declared` fehl804* **Deklarieren Sie jeden Wert in der Typdeklarationsdatei**: Andernfalls schlägt die Validierung mit `hello-tabs.count is not declared` fehl
793* **Schreiben Sie von einem Callback oder einem anderen Ereignis-Hook**: ein `ui.render` Hook kann Status lesen und kann ihn nicht schreiben, daher schreiben Sie von `onPress`, `onSubmit` oder einem Hook für ein anderes Ereignis805* **Schreiben Sie aus einem Callback oder dem Hook eines anderen Events**: Ein `ui.render`-Hook kann Zustand lesen, aber nicht schreiben, schreiben Sie also aus `onPress`, `onSubmit` oder einem Hook für ein anderes Event
794 806
795<h4 id="change-hello-tabs-to-use-state">807<h4 id="change-hello-tabs-to-use-$-state">
796 Ändern Sie `hello-tabs`, um `$.state` zu verwenden808 `hello-tabs` auf `$.state` umstellen
797</h4>809</h4>
798 810
799Um `count` in `hello-tabs` in `$.state` zu verschieben, ändern Sie jede Zeile, die ihn verwendet:811Um `count` in `hello-tabs` nach `$.state` zu verschieben, ändern Sie jede Zeile, die ihn verwendet:
800 812
801* **Am Anfang des Moduls**: fügen Sie die `import` Zeile hinzu, und ersetzen Sie `let count = 0` mit der `atom` Zeile813* **Am Anfang des Moduls**: Fügen Sie die `import`-Zeile hinzu und ersetzen Sie `let count = 0` durch die `atom`-Zeile
802* **Im `ui.render` Hook**: fügen Sie die `read` Zeile vor `tabButton` hinzu, und zeichnen Sie `'Count: ' + n` im `Text`814* **Im `ui.render`-Hook**: Fügen Sie die `read`-Zeile vor `tabButton` hinzu und zeichnen Sie `'Count: ' + n` im `Text`
803* **Im Add one Button**: ersetzen Sie `onPress` mit dem aus [Speichern Sie aus mehr als einer Sitzung](#save-from-more-than-one-session), das die Anzahl speichert sowie schreibt815* **In der Schaltfläche Add one**: Ersetzen Sie `onPress` durch die Variante aus [Aus mehr als einer Sitzung speichern](#save-from-more-than-one-session), die den Zähler sowohl speichert als auch schreibt
804* **Im `session.start` Hook**: ersetzen Sie die zwei Zeilen, die `saved` lesen, mit dem `loadCount` Aufruf aus [Laden Sie einen gespeicherten Wert erneut nach `/clear`](#load-a-saved-value-again-after-clear)816* **Im `session.start`-Hook**: Ersetzen Sie die beiden Zeilen, die `saved` lesen, durch den `loadCount`-Aufruf aus [Einen gespeicherten Wert nach `/clear` erneut laden](#load-a-saved-value-again-after-clear)
805 817
806Behalten Sie `redraw` für die Tab-Schaltflächen, da `tab` immer noch eine Variable ist.818Behalten Sie `redraw` für die Tab-Schaltflächen bei, da `tab` weiterhin eine Variable ist.
807 819
808<h3 id="load-a-saved-value-again-after-clear">820<h3 id="load-a-saved-value-again-after-clear">
809 Laden Sie einen gespeicherten Wert erneut nach `/clear`821 Einen gespeicherten Wert nach `/clear` erneut laden
810</h3>822</h3>
811 823
812Wenn Ihr Mod einen gespeicherten Wert aus `$.store` in `$.state` bei `session.start` kopiert, muss er ihn nach `/clear`, `/resume` oder `/branch` erneut kopieren. Diese Befehle setzen jeden `$.state` Wert auf seinen Standard zurück, und `session.start` wird nicht erneut ausgelöst. [`classic.SessionStart`](/docs/de/plugins/mods/events#hook-the-settings-hook-events) wird nach jedem ausgelöst, mit `e.source` auf `clear`, `resume` oder `fork` gesetzt, daher kopieren Sie den Wert erneut in einem Hook darauf. Sonst zeigt Ihre Zeichnung den Standard, und ein Callback, der den `$.state` Wert speichert, schreibt den Standard über das, was Sie gespeichert haben.824Wenn Ihr Mod bei `session.start` einen gespeicherten Wert aus `$.store` in `$.state` kopiert, muss er ihn nach `/clear`, `/resume` oder `/branch` erneut kopieren. Diese Befehle setzen jeden `$.state`-Wert auf seinen Standardwert zurück, und `session.start` wird nicht erneut ausgelöst. [`classic.SessionStart`](/docs/de/plugins/mods/events#hook-the-settings-hook-events) wird jedoch nach jedem dieser Befehle ausgelöst, wobei `e.source` auf `clear`, `resume` oder `fork` gesetzt ist. Kopieren Sie den Wert daher in einem Hook auf dieses Event erneut. Andernfalls zeigt Ihre Darstellung den Standardwert, und ein Callback, der den `$.state`-Wert speichert, überschreibt Ihren gespeicherten Wert mit dem Standardwert.
813 825
814Dieser Code lädt `count` aus beiden Hooks. Es baut auf der `$.state` Version von `hello-tabs` auf, wo `count` ein Atom ist und `update` importiert wird. Setzen Sie `loadCount` über `register`, und fügen Sie den `loadCount` Aufruf zum `session.start` Hook hinzu, den Sie bereits haben. `classic.SessionStart` wird auch beim Start und nach Verdichtung ausgelöst, was `$.state` nicht zurückgesetzt, daher hält der Filter auf `source` den Hook zu den drei Resets:826Dieser Code lädt `count` aus beiden Hooks. Er baut auf der `$.state`-Version von `hello-tabs` auf, in der `count` ein Atom ist und `update` importiert wird. Platzieren Sie `loadCount` oberhalb von `register` und fügen Sie den `loadCount`-Aufruf dem bereits vorhandenen `session.start`-Hook hinzu. `classic.SessionStart` wird außerdem beim Start und nach der Komprimierung ausgelöst, was `$.state` nicht zurücksetzt, daher beschränkt der Filter auf `source` den Hook auf die drei Zurücksetzungen:
815 827
816```javascript theme={null}828```javascript theme={null}
817// Copy the saved count from $.store into $.state, or 0 if nothing is saved829// Copy the saved count from $.store into $.state, or 0 if nothing is saved
833})845})
834```846```
835 847
836Mit beiden Hooks an Ort und Stelle zeigt das Pane die gespeicherte Anzahl nach `/clear` und nicht `0`, und der nächste Druck von **Add one** addiert zur gespeicherten Anzahl.848Mit beiden Hooks zeigt der Bereich nach `/clear` den gespeicherten Zähler statt `0` an, und der nächste Klick auf **Add one** erhöht den gespeicherten Zähler.
837 849
838`loadCount` schreibt den gespeicherten Wert über den in `$.state`, und `session.start` wird jedes Mal ausgelöst, wenn das Modul neu geladen wird. Um den Store nicht hinter sich zu lassen, speichern Sie bei jeder Änderung, wie die **Add one** Schaltfläche tut.850`loadCount` überschreibt den Wert in `$.state` mit dem gespeicherten Wert, und `session.start` wird bei jedem Neuladen des Moduls erneut ausgelöst. Damit der Store nicht veraltet, speichern Sie bei jeder Änderung, wie es die Schaltfläche **Add one** tut.
839 851
840Um den Reload ohne eine Sitzung zu überprüfen, [testen Sie die Zeichnung nach `/clear`](/docs/de/plugins/mods/test#test-a-drawing-after-clear).852Um das Neuladen ohne Sitzung zu prüfen, [testen Sie die Darstellung nach `/clear`](/docs/de/plugins/mods/test#test-a-drawing-after-clear).
841 853
842<h3 id="save-from-more-than-one-session">854<h3 id="save-from-more-than-one-session">
843 Speichern Sie aus mehr als einer Sitzung855 Aus mehr als einer Sitzung speichern
844</h3>856</h3>
845 857
846Jede Sitzung auf Ihrem Computer, die Ihren Mod ausführt, teilt einen `$.store`. Ein `get` gefolgt von einem `set` ist nicht atomar. Wenn zwei Sitzungen jeweils einen Wert lesen, ihn ändern und zurückschreiben, rennen sie, und der zweite Schreib ersetzt den ersten.858Alle Sitzungen auf Ihrem Rechner, die Ihren Mod ausführen, teilen sich einen `$.store`. Ein `get` gefolgt von einem `set` ist nicht atomar. Wenn zwei Sitzungen jeweils einen Wert lesen, ihn ändern und zurückschreiben, entsteht eine Race Condition, und der zweite Schreibvorgang ersetzt den ersten.
847 859
848Zwei Auswahlmöglichkeiten machen das weniger wahrscheinlich:860Um dies unwahrscheinlicher zu machen:
849 861
850* **Geben Sie jedem Element seinen eigenen Schlüssel**: ein `set` ändert nur seinen eigenen Schlüssel, daher überschreiben Sitzungen, die verschiedene Schlüssel schreiben, sich nicht gegenseitig862* **Geben Sie jedem Element einen eigenen Schlüssel**: Ein `set` ändert nur seinen eigenen Schlüssel, sodass Sitzungen, die unterschiedliche Schlüssel schreiben, sich nicht gegenseitig überschreiben
851* **Lesen Sie erneut direkt vor dem Schreiben**: für einen Wert, den mehrere Sitzungen ändern, `get` den Schlüssel im Callback und erstellen Sie den neuen Wert daraus, nicht aus einer Kopie, die Sie bei `session.start` geladen haben. Ein Schreib einer anderen Sitzung geht immer noch verloren, wenn er zwischen Ihrem `get` und Ihrem `set` landet.863* **Lesen Sie direkt vor dem Schreiben erneut**: Rufen Sie für einen Wert, den mehrere Sitzungen ändern, den Schlüssel im Callback mit `get` ab und bilden Sie den neuen Wert daraus, nicht aus einer Kopie, die Sie bei `session.start` geladen haben. Der Schreibvorgang einer anderen Sitzung geht trotzdem verloren, wenn er zwischen Ihrem `get` und Ihrem `set` stattfindet.
852 864
853Diese Schaltfläche addiert eins zu dem, was der Store jetzt hält, dann aktualisiert die Zeichnung:865Diese Schaltfläche erhöht den aktuellen Wert im Store um eins und aktualisiert dann die Darstellung:
854 866
855```javascript theme={null}867```javascript theme={null}
856onPress: async () => {868onPress: async () => {
862}874}
863```875```
864 876
865Wenn eine zweite Sitzung ihre eigene Schaltfläche drei Mal gedrückt hat, seit diese Sitzung gestartet wurde, zeigt dieser Druck und speichert eine Anzahl, die diese drei enthält.877Wenn eine zweite Sitzung seit dem Start dieser Sitzung dreimal auf ihre eigene Schaltfläche geklickt hat, zeigt und speichert dieser Klick einen Zählerstand, der diese drei einschließt.
866 878
867<h2 id="next-steps">879<h2 id="next-steps">
868 Nächste Schritte880 Nächste Schritte
869</h2>881</h2>
870 882
871* [Reagieren Sie auf Ereignisse](/docs/de/plugins/mods/events): speisen Sie Ihre Zeichnung aus Tool-Calls und Turns883* [Auf Ereignisse reagieren](/docs/de/plugins/mods/events): Versorgen Sie Ihre Zeichnung mit Daten aus Tool-Aufrufen und Turns
872* [Verwenden Sie die Mods API](/docs/de/plugins/mods/api): speisen Sie Ihre Zeichnung aus Timern und Modell-Aufrufen884* [Die Mods-API verwenden](/docs/de/plugins/mods/api): Versorgen Sie Ihre Zeichnung mit Daten aus Timern und Modellaufrufen
873* [Testen Sie eine Zeichnung](/docs/de/plugins/mods/test#test-a-drawing): drücken Sie Ihre Schaltflächen aus einem Test auf mehr als einer Oberfläche885* [Eine Zeichnung testen](/docs/de/plugins/mods/test#test-a-drawing): Betätigen Sie Ihre Schaltflächen aus einem Test heraus, auf mehr als einer Oberfläche
874* [Render-Sites](/docs/de/plugins/mods/reference#render-sites) und [Elemente](/docs/de/plugins/mods/reference#elements): jede Site's Props und jedes Element's Props886* [Render-Stellen](/docs/de/plugins/mods/reference#render-sites) und [Elemente](/docs/de/plugins/mods/reference#elements): die Props jeder Render-Stelle und die Props jedes Elements