@dealdeploy/skl 0.1.6 → 0.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/skills/opentui/SKILL.md +198 -0
- package/.agents/skills/opentui/references/animation/REFERENCE.md +431 -0
- package/.agents/skills/opentui/references/components/REFERENCE.md +143 -0
- package/.agents/skills/opentui/references/components/code-diff.md +496 -0
- package/.agents/skills/opentui/references/components/containers.md +412 -0
- package/.agents/skills/opentui/references/components/inputs.md +531 -0
- package/.agents/skills/opentui/references/components/text-display.md +384 -0
- package/.agents/skills/opentui/references/core/REFERENCE.md +145 -0
- package/.agents/skills/opentui/references/core/api.md +506 -0
- package/.agents/skills/opentui/references/core/configuration.md +166 -0
- package/.agents/skills/opentui/references/core/gotchas.md +393 -0
- package/.agents/skills/opentui/references/core/patterns.md +448 -0
- package/.agents/skills/opentui/references/keyboard/REFERENCE.md +511 -0
- package/.agents/skills/opentui/references/layout/REFERENCE.md +337 -0
- package/.agents/skills/opentui/references/layout/patterns.md +444 -0
- package/.agents/skills/opentui/references/react/REFERENCE.md +174 -0
- package/.agents/skills/opentui/references/react/api.md +435 -0
- package/.agents/skills/opentui/references/react/configuration.md +301 -0
- package/.agents/skills/opentui/references/react/gotchas.md +443 -0
- package/.agents/skills/opentui/references/react/patterns.md +501 -0
- package/.agents/skills/opentui/references/solid/REFERENCE.md +201 -0
- package/.agents/skills/opentui/references/solid/api.md +543 -0
- package/.agents/skills/opentui/references/solid/configuration.md +315 -0
- package/.agents/skills/opentui/references/solid/gotchas.md +415 -0
- package/.agents/skills/opentui/references/solid/patterns.md +558 -0
- package/.agents/skills/opentui/references/testing/REFERENCE.md +614 -0
- package/.claude/settings.local.json +11 -0
- package/.claude/skills/opentui/SKILL.md +198 -0
- package/.claude/skills/opentui/references/animation/REFERENCE.md +431 -0
- package/.claude/skills/opentui/references/components/REFERENCE.md +143 -0
- package/.claude/skills/opentui/references/components/code-diff.md +496 -0
- package/.claude/skills/opentui/references/components/containers.md +412 -0
- package/.claude/skills/opentui/references/components/inputs.md +531 -0
- package/.claude/skills/opentui/references/components/text-display.md +384 -0
- package/.claude/skills/opentui/references/core/REFERENCE.md +145 -0
- package/.claude/skills/opentui/references/core/api.md +506 -0
- package/.claude/skills/opentui/references/core/configuration.md +166 -0
- package/.claude/skills/opentui/references/core/gotchas.md +393 -0
- package/.claude/skills/opentui/references/core/patterns.md +448 -0
- package/.claude/skills/opentui/references/keyboard/REFERENCE.md +511 -0
- package/.claude/skills/opentui/references/layout/REFERENCE.md +337 -0
- package/.claude/skills/opentui/references/layout/patterns.md +444 -0
- package/.claude/skills/opentui/references/react/REFERENCE.md +174 -0
- package/.claude/skills/opentui/references/react/api.md +435 -0
- package/.claude/skills/opentui/references/react/configuration.md +301 -0
- package/.claude/skills/opentui/references/react/gotchas.md +443 -0
- package/.claude/skills/opentui/references/react/patterns.md +501 -0
- package/.claude/skills/opentui/references/solid/REFERENCE.md +201 -0
- package/.claude/skills/opentui/references/solid/api.md +543 -0
- package/.claude/skills/opentui/references/solid/configuration.md +315 -0
- package/.claude/skills/opentui/references/solid/gotchas.md +415 -0
- package/.claude/skills/opentui/references/solid/patterns.md +558 -0
- package/.claude/skills/opentui/references/testing/REFERENCE.md +614 -0
- package/index.ts +429 -86
- package/package.json +2 -1
- package/update.ts +87 -0
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
# OpenTUI Components
|
|
2
|
+
|
|
3
|
+
Reference for all OpenTUI components, organized by category. Components are available in all three frameworks (Core, React, Solid) with slight API differences.
|
|
4
|
+
|
|
5
|
+
## When to Use
|
|
6
|
+
|
|
7
|
+
Use this reference when you need to find the right component category or compare naming across Core, React, and Solid.
|
|
8
|
+
|
|
9
|
+
## Component Categories
|
|
10
|
+
|
|
11
|
+
| Category | Components | File |
|
|
12
|
+
|----------|------------|------|
|
|
13
|
+
| Text & Display | text, ascii-font, styled text | [text-display.md](./text-display.md) |
|
|
14
|
+
| Containers | box, scrollbox, borders | [containers.md](./containers.md) |
|
|
15
|
+
| Inputs | input, textarea, select, tab-select | [inputs.md](./inputs.md) |
|
|
16
|
+
| Code & Diff | code, line-number, diff, markdown | [code-diff.md](./code-diff.md) |
|
|
17
|
+
|
|
18
|
+
## Component Chooser
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
Need a component?
|
|
22
|
+
├─ Styled text or ASCII art -> text-display.md
|
|
23
|
+
├─ Containers, borders, scrolling -> containers.md
|
|
24
|
+
├─ Forms or input controls -> inputs.md
|
|
25
|
+
└─ Code blocks, diffs, line numbers, markdown -> code-diff.md
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Component Naming
|
|
29
|
+
|
|
30
|
+
Components have different names across frameworks:
|
|
31
|
+
|
|
32
|
+
| Concept | Core (Class) | React (JSX) | Solid (JSX) |
|
|
33
|
+
|---------|--------------|-------------|-------------|
|
|
34
|
+
| Text | `TextRenderable` | `<text>` | `<text>` |
|
|
35
|
+
| Box | `BoxRenderable` | `<box>` | `<box>` |
|
|
36
|
+
| ScrollBox | `ScrollBoxRenderable` | `<scrollbox>` | `<scrollbox>` |
|
|
37
|
+
| Input | `InputRenderable` | `<input>` | `<input>` |
|
|
38
|
+
| Textarea | `TextareaRenderable` | `<textarea>` | `<textarea>` |
|
|
39
|
+
| Select | `SelectRenderable` | `<select>` | `<select>` |
|
|
40
|
+
| Tab Select | `TabSelectRenderable` | `<tab-select>` | `<tab_select>` |
|
|
41
|
+
| ASCII Font | `ASCIIFontRenderable` | `<ascii-font>` | `<ascii_font>` |
|
|
42
|
+
| Code | `CodeRenderable` | `<code>` | `<code>` |
|
|
43
|
+
| Line Number | `LineNumberRenderable` | `<line-number>` | `<line_number>` |
|
|
44
|
+
| Diff | `DiffRenderable` | `<diff>` | `<diff>` |
|
|
45
|
+
| Markdown | `MarkdownRenderable` | `<markdown>` | `<markdown>` |
|
|
46
|
+
|
|
47
|
+
**Note**: Solid uses underscores (`tab_select`) while React uses hyphens (`tab-select`).
|
|
48
|
+
|
|
49
|
+
## Common Properties
|
|
50
|
+
|
|
51
|
+
All components share these layout properties (see [Layout](../layout/REFERENCE.md)):
|
|
52
|
+
|
|
53
|
+
```tsx
|
|
54
|
+
// Positioning
|
|
55
|
+
position="relative" | "absolute"
|
|
56
|
+
left, top, right, bottom
|
|
57
|
+
|
|
58
|
+
// Dimensions
|
|
59
|
+
width, height
|
|
60
|
+
minWidth, maxWidth, minHeight, maxHeight
|
|
61
|
+
|
|
62
|
+
// Flexbox
|
|
63
|
+
flexDirection, flexGrow, flexShrink, flexBasis
|
|
64
|
+
justifyContent, alignItems, alignSelf
|
|
65
|
+
flexWrap, gap
|
|
66
|
+
|
|
67
|
+
// Spacing
|
|
68
|
+
padding, paddingTop, paddingRight, paddingBottom, paddingLeft
|
|
69
|
+
paddingX, paddingY // Axis shorthand (horizontal/vertical)
|
|
70
|
+
margin, marginTop, marginRight, marginBottom, marginLeft
|
|
71
|
+
marginX, marginY // Axis shorthand (horizontal/vertical)
|
|
72
|
+
|
|
73
|
+
// Display
|
|
74
|
+
display="flex" | "none"
|
|
75
|
+
overflow="visible" | "hidden" | "scroll"
|
|
76
|
+
zIndex
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Quick Examples
|
|
80
|
+
|
|
81
|
+
### Core (Imperative)
|
|
82
|
+
|
|
83
|
+
```typescript
|
|
84
|
+
import { createCliRenderer, TextRenderable, BoxRenderable } from "@opentui/core"
|
|
85
|
+
|
|
86
|
+
const renderer = await createCliRenderer()
|
|
87
|
+
|
|
88
|
+
const box = new BoxRenderable(renderer, {
|
|
89
|
+
id: "container",
|
|
90
|
+
border: true,
|
|
91
|
+
padding: 2,
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
const text = new TextRenderable(renderer, {
|
|
95
|
+
id: "greeting",
|
|
96
|
+
content: "Hello!",
|
|
97
|
+
fg: "#00FF00",
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
box.add(text)
|
|
101
|
+
renderer.root.add(box)
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### React
|
|
105
|
+
|
|
106
|
+
```tsx
|
|
107
|
+
import { createCliRenderer } from "@opentui/core"
|
|
108
|
+
import { createRoot } from "@opentui/react"
|
|
109
|
+
|
|
110
|
+
function App() {
|
|
111
|
+
return (
|
|
112
|
+
<box border padding={2}>
|
|
113
|
+
<text fg="#00FF00">Hello!</text>
|
|
114
|
+
</box>
|
|
115
|
+
)
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const renderer = await createCliRenderer()
|
|
119
|
+
createRoot(renderer).render(<App />)
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Solid
|
|
123
|
+
|
|
124
|
+
```tsx
|
|
125
|
+
import { render } from "@opentui/solid"
|
|
126
|
+
|
|
127
|
+
function App() {
|
|
128
|
+
return (
|
|
129
|
+
<box border padding={2}>
|
|
130
|
+
<text fg="#00FF00">Hello!</text>
|
|
131
|
+
</box>
|
|
132
|
+
)
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
render(() => <App />)
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## See Also
|
|
139
|
+
|
|
140
|
+
- [Core API](../core/api.md) - Imperative component classes
|
|
141
|
+
- [React API](../react/api.md) - React component props
|
|
142
|
+
- [Solid API](../solid/api.md) - Solid component props
|
|
143
|
+
- [Layout](../layout/REFERENCE.md) - Layout system details
|
|
@@ -0,0 +1,496 @@
|
|
|
1
|
+
# Code & Diff Components
|
|
2
|
+
|
|
3
|
+
Components for displaying code with syntax highlighting and diffs in OpenTUI.
|
|
4
|
+
|
|
5
|
+
## Code Component
|
|
6
|
+
|
|
7
|
+
Display syntax-highlighted code blocks.
|
|
8
|
+
|
|
9
|
+
### Basic Usage
|
|
10
|
+
|
|
11
|
+
```tsx
|
|
12
|
+
// React
|
|
13
|
+
<code
|
|
14
|
+
code={`function hello() {
|
|
15
|
+
console.log("Hello, World!");
|
|
16
|
+
}`}
|
|
17
|
+
language="typescript"
|
|
18
|
+
/>
|
|
19
|
+
|
|
20
|
+
// Solid
|
|
21
|
+
<code
|
|
22
|
+
code={sourceCode}
|
|
23
|
+
language="javascript"
|
|
24
|
+
/>
|
|
25
|
+
|
|
26
|
+
// Core
|
|
27
|
+
const codeBlock = new CodeRenderable(renderer, {
|
|
28
|
+
id: "code",
|
|
29
|
+
code: sourceCode,
|
|
30
|
+
language: "typescript",
|
|
31
|
+
})
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### Supported Languages
|
|
35
|
+
|
|
36
|
+
OpenTUI uses Tree-sitter for syntax highlighting. Common languages:
|
|
37
|
+
- `typescript`, `javascript`
|
|
38
|
+
- `python`
|
|
39
|
+
- `rust`
|
|
40
|
+
- `go`
|
|
41
|
+
- `json`
|
|
42
|
+
- `html`, `css`
|
|
43
|
+
- `markdown`
|
|
44
|
+
- `bash`, `shell`
|
|
45
|
+
|
|
46
|
+
### Styling
|
|
47
|
+
|
|
48
|
+
```tsx
|
|
49
|
+
<code
|
|
50
|
+
code={sourceCode}
|
|
51
|
+
language="typescript"
|
|
52
|
+
backgroundColor="#1a1a2e"
|
|
53
|
+
showLineNumbers
|
|
54
|
+
/>
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### onHighlight Callback
|
|
58
|
+
|
|
59
|
+
Intercept and modify syntax highlights before rendering:
|
|
60
|
+
|
|
61
|
+
```tsx
|
|
62
|
+
// Core
|
|
63
|
+
const codeBlock = new CodeRenderable(renderer, {
|
|
64
|
+
id: "code",
|
|
65
|
+
code: sourceCode,
|
|
66
|
+
language: "typescript",
|
|
67
|
+
onHighlight: (highlights, context) => {
|
|
68
|
+
// Add custom highlights
|
|
69
|
+
highlights.push([10, 20, "custom.error", {}])
|
|
70
|
+
return highlights
|
|
71
|
+
},
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
// React/Solid
|
|
75
|
+
<code
|
|
76
|
+
code={sourceCode}
|
|
77
|
+
language="typescript"
|
|
78
|
+
onHighlight={(highlights, context) => {
|
|
79
|
+
// context: { content, filetype, syntaxStyle }
|
|
80
|
+
// Modify and return highlights array
|
|
81
|
+
return highlights.filter(h => h[2] !== "comment")
|
|
82
|
+
}}
|
|
83
|
+
/>
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
**Callback signature:**
|
|
87
|
+
- `highlights: SimpleHighlight[]` - Array of `[start, end, scope, metadata]`
|
|
88
|
+
- `context: { content, filetype, syntaxStyle }` - Highlighting context
|
|
89
|
+
- Return modified highlights array or `undefined` to use original
|
|
90
|
+
|
|
91
|
+
Supports async callbacks for fetching additional highlight data.
|
|
92
|
+
|
|
93
|
+
## Line Number Component
|
|
94
|
+
|
|
95
|
+
Code display with line numbers, highlighting, and diagnostics.
|
|
96
|
+
|
|
97
|
+
### Basic Usage
|
|
98
|
+
|
|
99
|
+
```tsx
|
|
100
|
+
// React
|
|
101
|
+
<line-number
|
|
102
|
+
code={sourceCode}
|
|
103
|
+
language="typescript"
|
|
104
|
+
/>
|
|
105
|
+
|
|
106
|
+
// Solid (note underscore)
|
|
107
|
+
<line_number
|
|
108
|
+
code={sourceCode}
|
|
109
|
+
language="typescript"
|
|
110
|
+
/>
|
|
111
|
+
|
|
112
|
+
// Core
|
|
113
|
+
const codeView = new LineNumberRenderable(renderer, {
|
|
114
|
+
id: "code-view",
|
|
115
|
+
code: sourceCode,
|
|
116
|
+
language: "typescript",
|
|
117
|
+
})
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### Line Number Options
|
|
121
|
+
|
|
122
|
+
```tsx
|
|
123
|
+
// React
|
|
124
|
+
<line-number
|
|
125
|
+
code={sourceCode}
|
|
126
|
+
language="typescript"
|
|
127
|
+
startLine={1} // Starting line number
|
|
128
|
+
showLineNumbers={true} // Display line numbers
|
|
129
|
+
/>
|
|
130
|
+
|
|
131
|
+
// Solid
|
|
132
|
+
<line_number
|
|
133
|
+
code={sourceCode}
|
|
134
|
+
language="typescript"
|
|
135
|
+
startLine={1}
|
|
136
|
+
showLineNumbers={true}
|
|
137
|
+
/>
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### Line Highlighting
|
|
141
|
+
|
|
142
|
+
Highlight specific lines:
|
|
143
|
+
|
|
144
|
+
```tsx
|
|
145
|
+
// React
|
|
146
|
+
<line-number
|
|
147
|
+
code={sourceCode}
|
|
148
|
+
language="typescript"
|
|
149
|
+
highlightedLines={[5, 10, 15]} // Highlight these lines
|
|
150
|
+
/>
|
|
151
|
+
|
|
152
|
+
// Solid
|
|
153
|
+
<line_number
|
|
154
|
+
code={sourceCode}
|
|
155
|
+
language="typescript"
|
|
156
|
+
highlightedLines={[5, 10, 15]}
|
|
157
|
+
/>
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### Diagnostics
|
|
161
|
+
|
|
162
|
+
Show errors, warnings, and info on specific lines:
|
|
163
|
+
|
|
164
|
+
```tsx
|
|
165
|
+
// React
|
|
166
|
+
<line-number
|
|
167
|
+
code={sourceCode}
|
|
168
|
+
language="typescript"
|
|
169
|
+
diagnostics={[
|
|
170
|
+
{ line: 3, severity: "error", message: "Unexpected token" },
|
|
171
|
+
{ line: 7, severity: "warning", message: "Unused variable" },
|
|
172
|
+
{ line: 12, severity: "info", message: "Consider using const" },
|
|
173
|
+
]}
|
|
174
|
+
/>
|
|
175
|
+
|
|
176
|
+
// Solid
|
|
177
|
+
<line_number
|
|
178
|
+
code={sourceCode}
|
|
179
|
+
language="typescript"
|
|
180
|
+
diagnostics={[
|
|
181
|
+
{ line: 3, severity: "error", message: "Unexpected token" },
|
|
182
|
+
]}
|
|
183
|
+
/>
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
**Diagnostic severity levels:**
|
|
187
|
+
- `error` - Red indicator
|
|
188
|
+
- `warning` - Yellow indicator
|
|
189
|
+
- `info` - Blue indicator
|
|
190
|
+
- `hint` - Gray indicator
|
|
191
|
+
|
|
192
|
+
### Diff Highlighting
|
|
193
|
+
|
|
194
|
+
Show added/removed lines:
|
|
195
|
+
|
|
196
|
+
```tsx
|
|
197
|
+
<line-number
|
|
198
|
+
code={sourceCode}
|
|
199
|
+
language="typescript"
|
|
200
|
+
addedLines={[5, 6, 7]} // Green background
|
|
201
|
+
removedLines={[10, 11]} // Red background
|
|
202
|
+
/>
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
## Diff Component
|
|
206
|
+
|
|
207
|
+
Unified or split diff viewer with syntax highlighting.
|
|
208
|
+
|
|
209
|
+
### Basic Usage
|
|
210
|
+
|
|
211
|
+
```tsx
|
|
212
|
+
// React
|
|
213
|
+
<diff
|
|
214
|
+
oldCode={originalCode}
|
|
215
|
+
newCode={modifiedCode}
|
|
216
|
+
language="typescript"
|
|
217
|
+
/>
|
|
218
|
+
|
|
219
|
+
// Solid
|
|
220
|
+
<diff
|
|
221
|
+
oldCode={originalCode}
|
|
222
|
+
newCode={modifiedCode}
|
|
223
|
+
language="typescript"
|
|
224
|
+
/>
|
|
225
|
+
|
|
226
|
+
// Core
|
|
227
|
+
const diffView = new DiffRenderable(renderer, {
|
|
228
|
+
id: "diff",
|
|
229
|
+
oldCode: originalCode,
|
|
230
|
+
newCode: modifiedCode,
|
|
231
|
+
language: "typescript",
|
|
232
|
+
})
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
### Display Modes
|
|
236
|
+
|
|
237
|
+
```tsx
|
|
238
|
+
// Unified diff (default)
|
|
239
|
+
<diff
|
|
240
|
+
oldCode={old}
|
|
241
|
+
newCode={new}
|
|
242
|
+
mode="unified"
|
|
243
|
+
/>
|
|
244
|
+
|
|
245
|
+
// Split/side-by-side diff
|
|
246
|
+
<diff
|
|
247
|
+
oldCode={old}
|
|
248
|
+
newCode={new}
|
|
249
|
+
mode="split"
|
|
250
|
+
/>
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
### Options
|
|
254
|
+
|
|
255
|
+
```tsx
|
|
256
|
+
<diff
|
|
257
|
+
oldCode={originalCode}
|
|
258
|
+
newCode={modifiedCode}
|
|
259
|
+
language="typescript"
|
|
260
|
+
mode="unified"
|
|
261
|
+
showLineNumbers
|
|
262
|
+
context={3} // Lines of context around changes
|
|
263
|
+
/>
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
### Styling
|
|
267
|
+
|
|
268
|
+
```tsx
|
|
269
|
+
<diff
|
|
270
|
+
oldCode={old}
|
|
271
|
+
newCode={new}
|
|
272
|
+
addedLineColor="#2d4f2d" // Background for added lines
|
|
273
|
+
removedLineColor="#4f2d2d" // Background for removed lines
|
|
274
|
+
unchangedLineColor="transparent"
|
|
275
|
+
/>
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
## Markdown Component
|
|
279
|
+
|
|
280
|
+
Render markdown content with syntax highlighting for code blocks.
|
|
281
|
+
|
|
282
|
+
### Basic Usage
|
|
283
|
+
|
|
284
|
+
```tsx
|
|
285
|
+
// React
|
|
286
|
+
<markdown
|
|
287
|
+
content={markdownText}
|
|
288
|
+
syntaxStyle={mySyntaxStyle}
|
|
289
|
+
/>
|
|
290
|
+
|
|
291
|
+
// Solid
|
|
292
|
+
<markdown
|
|
293
|
+
content={markdownText}
|
|
294
|
+
syntaxStyle={mySyntaxStyle}
|
|
295
|
+
/>
|
|
296
|
+
|
|
297
|
+
// Core
|
|
298
|
+
import { MarkdownRenderable } from "@opentui/core"
|
|
299
|
+
|
|
300
|
+
const md = new MarkdownRenderable(renderer, {
|
|
301
|
+
id: "markdown",
|
|
302
|
+
content: "# Hello\n\nThis is **markdown**.",
|
|
303
|
+
syntaxStyle: mySyntaxStyle,
|
|
304
|
+
})
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
### Options
|
|
308
|
+
|
|
309
|
+
```tsx
|
|
310
|
+
<markdown
|
|
311
|
+
content={markdownText}
|
|
312
|
+
syntaxStyle={syntaxStyle}
|
|
313
|
+
treeSitterClient={client} // Optional: custom tree-sitter client
|
|
314
|
+
conceal={true} // Hide markdown syntax characters
|
|
315
|
+
streaming={true} // Enable streaming mode for incremental updates
|
|
316
|
+
/>
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
### Custom Node Rendering
|
|
320
|
+
|
|
321
|
+
```tsx
|
|
322
|
+
// Core
|
|
323
|
+
const md = new MarkdownRenderable(renderer, {
|
|
324
|
+
id: "markdown",
|
|
325
|
+
content: "# Custom Heading",
|
|
326
|
+
syntaxStyle,
|
|
327
|
+
renderNode: (node, ctx, defaultRender) => {
|
|
328
|
+
if (node.type === "heading") {
|
|
329
|
+
// Return custom renderable for headings
|
|
330
|
+
return new TextRenderable(ctx, {
|
|
331
|
+
content: `>> ${node.content} <<`,
|
|
332
|
+
})
|
|
333
|
+
}
|
|
334
|
+
return null // Use default rendering
|
|
335
|
+
},
|
|
336
|
+
})
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
### Streaming Mode
|
|
340
|
+
|
|
341
|
+
For real-time content like LLM output:
|
|
342
|
+
|
|
343
|
+
```tsx
|
|
344
|
+
const [content, setContent] = useState("")
|
|
345
|
+
|
|
346
|
+
// Append text as it arrives
|
|
347
|
+
useEffect(() => {
|
|
348
|
+
llmStream.on("token", (token) => {
|
|
349
|
+
setContent(c => c + token)
|
|
350
|
+
})
|
|
351
|
+
}, [])
|
|
352
|
+
|
|
353
|
+
<markdown
|
|
354
|
+
content={content}
|
|
355
|
+
syntaxStyle={syntaxStyle}
|
|
356
|
+
streaming={true} // Optimizes for incremental updates
|
|
357
|
+
/>
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
## Use Cases
|
|
361
|
+
|
|
362
|
+
### Code Editor
|
|
363
|
+
|
|
364
|
+
```tsx
|
|
365
|
+
function CodeEditor() {
|
|
366
|
+
const [code, setCode] = useState(`function hello() {
|
|
367
|
+
console.log("Hello!");
|
|
368
|
+
}`)
|
|
369
|
+
|
|
370
|
+
return (
|
|
371
|
+
<box flexDirection="column" height="100%">
|
|
372
|
+
<box height={1}>
|
|
373
|
+
<text>editor.ts</text>
|
|
374
|
+
</box>
|
|
375
|
+
<textarea
|
|
376
|
+
value={code}
|
|
377
|
+
onChange={setCode}
|
|
378
|
+
language="typescript"
|
|
379
|
+
showLineNumbers
|
|
380
|
+
flexGrow={1}
|
|
381
|
+
focused
|
|
382
|
+
/>
|
|
383
|
+
</box>
|
|
384
|
+
)
|
|
385
|
+
}
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
### Code Review
|
|
389
|
+
|
|
390
|
+
```tsx
|
|
391
|
+
function CodeReview({ oldCode, newCode }) {
|
|
392
|
+
return (
|
|
393
|
+
<box flexDirection="column" height="100%">
|
|
394
|
+
<box height={1} backgroundColor="#333">
|
|
395
|
+
<text>Changes in src/utils.ts</text>
|
|
396
|
+
</box>
|
|
397
|
+
<diff
|
|
398
|
+
oldCode={oldCode}
|
|
399
|
+
newCode={newCode}
|
|
400
|
+
language="typescript"
|
|
401
|
+
mode="split"
|
|
402
|
+
showLineNumbers
|
|
403
|
+
/>
|
|
404
|
+
</box>
|
|
405
|
+
)
|
|
406
|
+
}
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
### Syntax-Highlighted Preview
|
|
410
|
+
|
|
411
|
+
```tsx
|
|
412
|
+
function MarkdownPreview({ content }) {
|
|
413
|
+
// Extract code blocks from markdown
|
|
414
|
+
const codeBlocks = extractCodeBlocks(content)
|
|
415
|
+
|
|
416
|
+
return (
|
|
417
|
+
<scrollbox height={20}>
|
|
418
|
+
{codeBlocks.map((block, i) => (
|
|
419
|
+
<box key={i} marginBottom={1}>
|
|
420
|
+
<code
|
|
421
|
+
code={block.code}
|
|
422
|
+
language={block.language}
|
|
423
|
+
/>
|
|
424
|
+
</box>
|
|
425
|
+
))}
|
|
426
|
+
</scrollbox>
|
|
427
|
+
)
|
|
428
|
+
}
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
### Error Display
|
|
432
|
+
|
|
433
|
+
```tsx
|
|
434
|
+
function ErrorView({ errors, code }) {
|
|
435
|
+
const diagnostics = errors.map(err => ({
|
|
436
|
+
line: err.line,
|
|
437
|
+
severity: "error",
|
|
438
|
+
message: err.message,
|
|
439
|
+
}))
|
|
440
|
+
|
|
441
|
+
return (
|
|
442
|
+
<line-number
|
|
443
|
+
code={code}
|
|
444
|
+
language="typescript"
|
|
445
|
+
diagnostics={diagnostics}
|
|
446
|
+
highlightedLines={errors.map(e => e.line)}
|
|
447
|
+
/>
|
|
448
|
+
)
|
|
449
|
+
}
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
## Gotchas
|
|
453
|
+
|
|
454
|
+
### Solid Uses Underscores
|
|
455
|
+
|
|
456
|
+
```tsx
|
|
457
|
+
// React
|
|
458
|
+
<line-number />
|
|
459
|
+
|
|
460
|
+
// Solid
|
|
461
|
+
<line_number />
|
|
462
|
+
```
|
|
463
|
+
|
|
464
|
+
### Language Required for Highlighting
|
|
465
|
+
|
|
466
|
+
```tsx
|
|
467
|
+
// No highlighting (plain text)
|
|
468
|
+
<code code={text} />
|
|
469
|
+
|
|
470
|
+
// With highlighting
|
|
471
|
+
<code code={text} language="typescript" />
|
|
472
|
+
```
|
|
473
|
+
|
|
474
|
+
### Large Files
|
|
475
|
+
|
|
476
|
+
For very large files, consider:
|
|
477
|
+
- Pagination or virtual scrolling
|
|
478
|
+
- Loading only visible portion
|
|
479
|
+
- Using `scrollbox` wrapper
|
|
480
|
+
|
|
481
|
+
```tsx
|
|
482
|
+
<scrollbox height={30}>
|
|
483
|
+
<line-number
|
|
484
|
+
code={largeFile}
|
|
485
|
+
language="typescript"
|
|
486
|
+
/>
|
|
487
|
+
</scrollbox>
|
|
488
|
+
```
|
|
489
|
+
|
|
490
|
+
### Tree-sitter Loading
|
|
491
|
+
|
|
492
|
+
Syntax highlighting requires Tree-sitter grammars. If highlighting isn't working:
|
|
493
|
+
|
|
494
|
+
1. Check the language is supported
|
|
495
|
+
2. Verify grammars are installed
|
|
496
|
+
3. Check `OTUI_TREE_SITTER_WORKER_PATH` if using custom path
|