@dealdeploy/skl 0.1.7 → 0.2.0
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/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 +169 -38
- package/package.json +1 -1
- package/update.ts +87 -0
|
@@ -0,0 +1,412 @@
|
|
|
1
|
+
# Container Components
|
|
2
|
+
|
|
3
|
+
Components for grouping and organizing content in OpenTUI.
|
|
4
|
+
|
|
5
|
+
## Box Component
|
|
6
|
+
|
|
7
|
+
The primary container component with borders, backgrounds, and layout capabilities.
|
|
8
|
+
|
|
9
|
+
### Basic Usage
|
|
10
|
+
|
|
11
|
+
```tsx
|
|
12
|
+
// React/Solid
|
|
13
|
+
<box>
|
|
14
|
+
<text>Content inside box</text>
|
|
15
|
+
</box>
|
|
16
|
+
|
|
17
|
+
// Core
|
|
18
|
+
const box = new BoxRenderable(renderer, {
|
|
19
|
+
id: "container",
|
|
20
|
+
})
|
|
21
|
+
box.add(child)
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
### Borders
|
|
25
|
+
|
|
26
|
+
```tsx
|
|
27
|
+
<box border>
|
|
28
|
+
Simple border
|
|
29
|
+
</box>
|
|
30
|
+
|
|
31
|
+
<box
|
|
32
|
+
border
|
|
33
|
+
borderStyle="single" // single | double | rounded | bold | none
|
|
34
|
+
borderColor="#FFFFFF"
|
|
35
|
+
>
|
|
36
|
+
Styled border
|
|
37
|
+
</box>
|
|
38
|
+
|
|
39
|
+
// Individual borders
|
|
40
|
+
<box
|
|
41
|
+
borderTop
|
|
42
|
+
borderBottom
|
|
43
|
+
borderLeft={false}
|
|
44
|
+
borderRight={false}
|
|
45
|
+
>
|
|
46
|
+
Top and bottom only
|
|
47
|
+
</box>
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
**Border Styles:**
|
|
51
|
+
|
|
52
|
+
| Style | Appearance |
|
|
53
|
+
|-------|------------|
|
|
54
|
+
| `single` | `┌─┐│ │└─┘` |
|
|
55
|
+
| `double` | `╔═╗║ ║╚═╝` |
|
|
56
|
+
| `rounded` | `╭─╮│ │╰─╯` |
|
|
57
|
+
| `bold` | `┏━┓┃ ┃┗━┛` |
|
|
58
|
+
|
|
59
|
+
### Title
|
|
60
|
+
|
|
61
|
+
```tsx
|
|
62
|
+
<box
|
|
63
|
+
border
|
|
64
|
+
title="Settings"
|
|
65
|
+
titleAlignment="center" // left | center | right
|
|
66
|
+
>
|
|
67
|
+
Panel content
|
|
68
|
+
</box>
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Background
|
|
72
|
+
|
|
73
|
+
```tsx
|
|
74
|
+
<box backgroundColor="#1a1a2e">
|
|
75
|
+
Dark background
|
|
76
|
+
</box>
|
|
77
|
+
|
|
78
|
+
<box backgroundColor="transparent">
|
|
79
|
+
No background
|
|
80
|
+
</box>
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Layout
|
|
84
|
+
|
|
85
|
+
Boxes are flex containers by default:
|
|
86
|
+
|
|
87
|
+
```tsx
|
|
88
|
+
<box
|
|
89
|
+
flexDirection="row" // row | column | row-reverse | column-reverse
|
|
90
|
+
justifyContent="center" // flex-start | flex-end | center | space-between | space-around
|
|
91
|
+
alignItems="center" // flex-start | flex-end | center | stretch | baseline
|
|
92
|
+
gap={2} // Space between children
|
|
93
|
+
>
|
|
94
|
+
<text>Item 1</text>
|
|
95
|
+
<text>Item 2</text>
|
|
96
|
+
</box>
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### Spacing
|
|
100
|
+
|
|
101
|
+
```tsx
|
|
102
|
+
<box
|
|
103
|
+
padding={2} // All sides
|
|
104
|
+
paddingTop={1}
|
|
105
|
+
paddingRight={2}
|
|
106
|
+
paddingBottom={1}
|
|
107
|
+
paddingLeft={2}
|
|
108
|
+
paddingX={2} // Horizontal (left + right)
|
|
109
|
+
paddingY={1} // Vertical (top + bottom)
|
|
110
|
+
margin={1}
|
|
111
|
+
marginTop={1}
|
|
112
|
+
marginX={2} // Horizontal (left + right)
|
|
113
|
+
marginY={1} // Vertical (top + bottom)
|
|
114
|
+
>
|
|
115
|
+
Spaced content
|
|
116
|
+
</box>
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### Dimensions
|
|
120
|
+
|
|
121
|
+
```tsx
|
|
122
|
+
<box
|
|
123
|
+
width={40} // Fixed width
|
|
124
|
+
height={10} // Fixed height
|
|
125
|
+
width="50%" // Percentage of parent
|
|
126
|
+
minWidth={20} // Minimum width
|
|
127
|
+
maxWidth={80} // Maximum width
|
|
128
|
+
flexGrow={1} // Grow to fill space
|
|
129
|
+
>
|
|
130
|
+
Sized box
|
|
131
|
+
</box>
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### Mouse Events
|
|
135
|
+
|
|
136
|
+
```tsx
|
|
137
|
+
<box
|
|
138
|
+
onMouseDown={(event) => {
|
|
139
|
+
console.log("Clicked at:", event.x, event.y)
|
|
140
|
+
}}
|
|
141
|
+
onMouseUp={(event) => {}}
|
|
142
|
+
onMouseMove={(event) => {}}
|
|
143
|
+
>
|
|
144
|
+
Clickable box
|
|
145
|
+
</box>
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### Focusable Boxes
|
|
149
|
+
|
|
150
|
+
By default, Box elements are not focusable. Set the `focusable` prop to enable focus behavior:
|
|
151
|
+
|
|
152
|
+
```tsx
|
|
153
|
+
// Make a box focusable - it can receive focus via mouse click
|
|
154
|
+
<box focusable border>
|
|
155
|
+
<text>Click to focus</text>
|
|
156
|
+
</box>
|
|
157
|
+
|
|
158
|
+
// Controlled focus state
|
|
159
|
+
const [focused, setFocused] = useState(false)
|
|
160
|
+
|
|
161
|
+
<box
|
|
162
|
+
focusable
|
|
163
|
+
focused={focused}
|
|
164
|
+
border
|
|
165
|
+
borderColor={focused ? "#00ff00" : "#888"}
|
|
166
|
+
>
|
|
167
|
+
<text>{focused ? "Focused!" : "Not focused"}</text>
|
|
168
|
+
</box>
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
When a focusable Box is clicked, focus bubbles up from the click target to the nearest focusable parent. Use `event.preventDefault()` in `onMouseDown` to prevent auto-focus.
|
|
172
|
+
|
|
173
|
+
## ScrollBox Component
|
|
174
|
+
|
|
175
|
+
A scrollable container for content that exceeds the viewport.
|
|
176
|
+
|
|
177
|
+
### Basic Usage
|
|
178
|
+
|
|
179
|
+
```tsx
|
|
180
|
+
// React
|
|
181
|
+
<scrollbox height={10}>
|
|
182
|
+
{items.map((item, i) => (
|
|
183
|
+
<text key={i}>{item}</text>
|
|
184
|
+
))}
|
|
185
|
+
</scrollbox>
|
|
186
|
+
|
|
187
|
+
// Solid
|
|
188
|
+
<scrollbox height={10}>
|
|
189
|
+
<For each={items()}>
|
|
190
|
+
{(item) => <text>{item}</text>}
|
|
191
|
+
</For>
|
|
192
|
+
</scrollbox>
|
|
193
|
+
|
|
194
|
+
// Core
|
|
195
|
+
const scrollbox = new ScrollBoxRenderable(renderer, {
|
|
196
|
+
id: "list",
|
|
197
|
+
height: 10,
|
|
198
|
+
})
|
|
199
|
+
items.forEach(item => {
|
|
200
|
+
scrollbox.add(new TextRenderable(renderer, { content: item }))
|
|
201
|
+
})
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
### Focus for Keyboard Scrolling
|
|
205
|
+
|
|
206
|
+
```tsx
|
|
207
|
+
<scrollbox focused height={20}>
|
|
208
|
+
{/* Use arrow keys to scroll */}
|
|
209
|
+
</scrollbox>
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### Scrollbar Styling
|
|
213
|
+
|
|
214
|
+
```tsx
|
|
215
|
+
// React
|
|
216
|
+
<scrollbox
|
|
217
|
+
style={{
|
|
218
|
+
rootOptions: {
|
|
219
|
+
backgroundColor: "#24283b",
|
|
220
|
+
},
|
|
221
|
+
wrapperOptions: {
|
|
222
|
+
backgroundColor: "#1f2335",
|
|
223
|
+
},
|
|
224
|
+
viewportOptions: {
|
|
225
|
+
backgroundColor: "#1a1b26",
|
|
226
|
+
},
|
|
227
|
+
contentOptions: {
|
|
228
|
+
backgroundColor: "#16161e",
|
|
229
|
+
},
|
|
230
|
+
scrollbarOptions: {
|
|
231
|
+
showArrows: true,
|
|
232
|
+
trackOptions: {
|
|
233
|
+
foregroundColor: "#7aa2f7",
|
|
234
|
+
backgroundColor: "#414868",
|
|
235
|
+
},
|
|
236
|
+
},
|
|
237
|
+
}}
|
|
238
|
+
>
|
|
239
|
+
{content}
|
|
240
|
+
</scrollbox>
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
### Scroll Position (Core)
|
|
244
|
+
|
|
245
|
+
```typescript
|
|
246
|
+
const scrollbox = new ScrollBoxRenderable(renderer, {
|
|
247
|
+
id: "list",
|
|
248
|
+
height: 20,
|
|
249
|
+
})
|
|
250
|
+
|
|
251
|
+
// Scroll programmatically
|
|
252
|
+
scrollbox.scrollTo(0) // Scroll to top
|
|
253
|
+
scrollbox.scrollTo(100) // Scroll to position
|
|
254
|
+
scrollbox.scrollBy(10) // Scroll relative
|
|
255
|
+
scrollbox.scrollToBottom() // Scroll to end
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
## Composition Patterns
|
|
259
|
+
|
|
260
|
+
### Card Component
|
|
261
|
+
|
|
262
|
+
```tsx
|
|
263
|
+
function Card({ title, children }) {
|
|
264
|
+
return (
|
|
265
|
+
<box
|
|
266
|
+
border
|
|
267
|
+
borderStyle="rounded"
|
|
268
|
+
padding={2}
|
|
269
|
+
marginBottom={1}
|
|
270
|
+
>
|
|
271
|
+
{title && (
|
|
272
|
+
<text fg="#00FFFF" bold>
|
|
273
|
+
{title}
|
|
274
|
+
</text>
|
|
275
|
+
)}
|
|
276
|
+
<box marginTop={title ? 1 : 0}>
|
|
277
|
+
{children}
|
|
278
|
+
</box>
|
|
279
|
+
</box>
|
|
280
|
+
)
|
|
281
|
+
}
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
### Panel Component
|
|
285
|
+
|
|
286
|
+
```tsx
|
|
287
|
+
function Panel({ title, children, width = 40 }) {
|
|
288
|
+
return (
|
|
289
|
+
<box
|
|
290
|
+
border
|
|
291
|
+
borderStyle="double"
|
|
292
|
+
width={width}
|
|
293
|
+
backgroundColor="#1a1a2e"
|
|
294
|
+
>
|
|
295
|
+
{title && (
|
|
296
|
+
<box
|
|
297
|
+
borderBottom
|
|
298
|
+
padding={1}
|
|
299
|
+
backgroundColor="#2a2a4e"
|
|
300
|
+
>
|
|
301
|
+
<text bold>{title}</text>
|
|
302
|
+
</box>
|
|
303
|
+
)}
|
|
304
|
+
<box padding={2}>
|
|
305
|
+
{children}
|
|
306
|
+
</box>
|
|
307
|
+
</box>
|
|
308
|
+
)
|
|
309
|
+
}
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
### List Container
|
|
313
|
+
|
|
314
|
+
```tsx
|
|
315
|
+
function List({ items, renderItem }) {
|
|
316
|
+
return (
|
|
317
|
+
<scrollbox height={15} focused>
|
|
318
|
+
{items.map((item, i) => (
|
|
319
|
+
<box
|
|
320
|
+
key={i}
|
|
321
|
+
padding={1}
|
|
322
|
+
backgroundColor={i % 2 === 0 ? "#222" : "#333"}
|
|
323
|
+
>
|
|
324
|
+
{renderItem(item, i)}
|
|
325
|
+
</box>
|
|
326
|
+
))}
|
|
327
|
+
</scrollbox>
|
|
328
|
+
)
|
|
329
|
+
}
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
## Nesting Containers
|
|
333
|
+
|
|
334
|
+
```tsx
|
|
335
|
+
<box flexDirection="column" height="100%">
|
|
336
|
+
{/* Header */}
|
|
337
|
+
<box height={3} border>
|
|
338
|
+
<text>Header</text>
|
|
339
|
+
</box>
|
|
340
|
+
|
|
341
|
+
{/* Main area with sidebar */}
|
|
342
|
+
<box flexDirection="row" flexGrow={1}>
|
|
343
|
+
<box width={20} border>
|
|
344
|
+
<text>Sidebar</text>
|
|
345
|
+
</box>
|
|
346
|
+
<box flexGrow={1}>
|
|
347
|
+
<scrollbox height="100%">
|
|
348
|
+
{/* Scrollable content */}
|
|
349
|
+
</scrollbox>
|
|
350
|
+
</box>
|
|
351
|
+
</box>
|
|
352
|
+
|
|
353
|
+
{/* Footer */}
|
|
354
|
+
<box height={1}>
|
|
355
|
+
<text>Footer</text>
|
|
356
|
+
</box>
|
|
357
|
+
</box>
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
## Gotchas
|
|
361
|
+
|
|
362
|
+
### Percentage Dimensions Need Parent Size
|
|
363
|
+
|
|
364
|
+
```tsx
|
|
365
|
+
// WRONG - parent has no explicit size
|
|
366
|
+
<box>
|
|
367
|
+
<box width="50%">Won't work</box>
|
|
368
|
+
</box>
|
|
369
|
+
|
|
370
|
+
// CORRECT
|
|
371
|
+
<box width="100%">
|
|
372
|
+
<box width="50%">Works</box>
|
|
373
|
+
</box>
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
### FlexGrow Needs Sized Parent
|
|
377
|
+
|
|
378
|
+
```tsx
|
|
379
|
+
// WRONG
|
|
380
|
+
<box>
|
|
381
|
+
<box flexGrow={1}>Won't grow</box>
|
|
382
|
+
</box>
|
|
383
|
+
|
|
384
|
+
// CORRECT
|
|
385
|
+
<box height="100%">
|
|
386
|
+
<box flexGrow={1}>Will grow</box>
|
|
387
|
+
</box>
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
### ScrollBox Needs Height
|
|
391
|
+
|
|
392
|
+
```tsx
|
|
393
|
+
// WRONG - no height constraint
|
|
394
|
+
<scrollbox>
|
|
395
|
+
{items}
|
|
396
|
+
</scrollbox>
|
|
397
|
+
|
|
398
|
+
// CORRECT
|
|
399
|
+
<scrollbox height={20}>
|
|
400
|
+
{items}
|
|
401
|
+
</scrollbox>
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
### Borders Add to Size
|
|
405
|
+
|
|
406
|
+
Borders take up space inside the box:
|
|
407
|
+
|
|
408
|
+
```tsx
|
|
409
|
+
<box width={10} border>
|
|
410
|
+
{/* Inner content area is 8 chars (10 - 2 for borders) */}
|
|
411
|
+
</box>
|
|
412
|
+
```
|