@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.
Files changed (55) hide show
  1. package/.agents/skills/opentui/SKILL.md +198 -0
  2. package/.agents/skills/opentui/references/animation/REFERENCE.md +431 -0
  3. package/.agents/skills/opentui/references/components/REFERENCE.md +143 -0
  4. package/.agents/skills/opentui/references/components/code-diff.md +496 -0
  5. package/.agents/skills/opentui/references/components/containers.md +412 -0
  6. package/.agents/skills/opentui/references/components/inputs.md +531 -0
  7. package/.agents/skills/opentui/references/components/text-display.md +384 -0
  8. package/.agents/skills/opentui/references/core/REFERENCE.md +145 -0
  9. package/.agents/skills/opentui/references/core/api.md +506 -0
  10. package/.agents/skills/opentui/references/core/configuration.md +166 -0
  11. package/.agents/skills/opentui/references/core/gotchas.md +393 -0
  12. package/.agents/skills/opentui/references/core/patterns.md +448 -0
  13. package/.agents/skills/opentui/references/keyboard/REFERENCE.md +511 -0
  14. package/.agents/skills/opentui/references/layout/REFERENCE.md +337 -0
  15. package/.agents/skills/opentui/references/layout/patterns.md +444 -0
  16. package/.agents/skills/opentui/references/react/REFERENCE.md +174 -0
  17. package/.agents/skills/opentui/references/react/api.md +435 -0
  18. package/.agents/skills/opentui/references/react/configuration.md +301 -0
  19. package/.agents/skills/opentui/references/react/gotchas.md +443 -0
  20. package/.agents/skills/opentui/references/react/patterns.md +501 -0
  21. package/.agents/skills/opentui/references/solid/REFERENCE.md +201 -0
  22. package/.agents/skills/opentui/references/solid/api.md +543 -0
  23. package/.agents/skills/opentui/references/solid/configuration.md +315 -0
  24. package/.agents/skills/opentui/references/solid/gotchas.md +415 -0
  25. package/.agents/skills/opentui/references/solid/patterns.md +558 -0
  26. package/.agents/skills/opentui/references/testing/REFERENCE.md +614 -0
  27. package/.claude/skills/opentui/SKILL.md +198 -0
  28. package/.claude/skills/opentui/references/animation/REFERENCE.md +431 -0
  29. package/.claude/skills/opentui/references/components/REFERENCE.md +143 -0
  30. package/.claude/skills/opentui/references/components/code-diff.md +496 -0
  31. package/.claude/skills/opentui/references/components/containers.md +412 -0
  32. package/.claude/skills/opentui/references/components/inputs.md +531 -0
  33. package/.claude/skills/opentui/references/components/text-display.md +384 -0
  34. package/.claude/skills/opentui/references/core/REFERENCE.md +145 -0
  35. package/.claude/skills/opentui/references/core/api.md +506 -0
  36. package/.claude/skills/opentui/references/core/configuration.md +166 -0
  37. package/.claude/skills/opentui/references/core/gotchas.md +393 -0
  38. package/.claude/skills/opentui/references/core/patterns.md +448 -0
  39. package/.claude/skills/opentui/references/keyboard/REFERENCE.md +511 -0
  40. package/.claude/skills/opentui/references/layout/REFERENCE.md +337 -0
  41. package/.claude/skills/opentui/references/layout/patterns.md +444 -0
  42. package/.claude/skills/opentui/references/react/REFERENCE.md +174 -0
  43. package/.claude/skills/opentui/references/react/api.md +435 -0
  44. package/.claude/skills/opentui/references/react/configuration.md +301 -0
  45. package/.claude/skills/opentui/references/react/gotchas.md +443 -0
  46. package/.claude/skills/opentui/references/react/patterns.md +501 -0
  47. package/.claude/skills/opentui/references/solid/REFERENCE.md +201 -0
  48. package/.claude/skills/opentui/references/solid/api.md +543 -0
  49. package/.claude/skills/opentui/references/solid/configuration.md +315 -0
  50. package/.claude/skills/opentui/references/solid/gotchas.md +415 -0
  51. package/.claude/skills/opentui/references/solid/patterns.md +558 -0
  52. package/.claude/skills/opentui/references/testing/REFERENCE.md +614 -0
  53. package/index.ts +169 -38
  54. package/package.json +1 -1
  55. package/update.ts +87 -0
@@ -0,0 +1,531 @@
1
+ # Input Components
2
+
3
+ Components for user input in OpenTUI.
4
+
5
+ ## Input Component
6
+
7
+ Single-line text input field.
8
+
9
+ ### Basic Usage
10
+
11
+ ```tsx
12
+ // React
13
+ <input
14
+ value={value}
15
+ onChange={(newValue) => setValue(newValue)}
16
+ placeholder="Enter text..."
17
+ focused
18
+ />
19
+
20
+ // Solid
21
+ <input
22
+ value={value()}
23
+ onInput={(newValue) => setValue(newValue)}
24
+ placeholder="Enter text..."
25
+ focused
26
+ />
27
+
28
+ // Core
29
+ const input = new InputRenderable(renderer, {
30
+ id: "name",
31
+ placeholder: "Enter text...",
32
+ })
33
+ input.on(InputRenderableEvents.CHANGE, (value) => {
34
+ console.log("Value:", value)
35
+ })
36
+ input.focus()
37
+ ```
38
+
39
+ ### Styling
40
+
41
+ ```tsx
42
+ <input
43
+ width={30}
44
+ backgroundColor="#1a1a1a"
45
+ textColor="#FFFFFF"
46
+ cursorColor="#00FF00"
47
+ focusedBackgroundColor="#2a2a2a"
48
+ placeholderColor="#666666"
49
+ />
50
+ ```
51
+
52
+ ### Events
53
+
54
+ ```tsx
55
+ // React
56
+ <input
57
+ onChange={(value) => console.log("Changed:", value)}
58
+ onFocus={() => console.log("Focused")}
59
+ onBlur={() => console.log("Blurred")}
60
+ />
61
+
62
+ // Core
63
+ input.on(InputRenderableEvents.CHANGE, (value) => {})
64
+ input.on(InputRenderableEvents.FOCUS, () => {})
65
+ input.on(InputRenderableEvents.BLUR, () => {})
66
+ ```
67
+
68
+ ### Controlled Input
69
+
70
+ ```tsx
71
+ // React
72
+ function ControlledInput() {
73
+ const [value, setValue] = useState("")
74
+
75
+ return (
76
+ <input
77
+ value={value}
78
+ onChange={setValue}
79
+ focused
80
+ />
81
+ )
82
+ }
83
+
84
+ // Solid
85
+ function ControlledInput() {
86
+ const [value, setValue] = createSignal("")
87
+
88
+ return (
89
+ <input
90
+ value={value()}
91
+ onInput={setValue}
92
+ focused
93
+ />
94
+ )
95
+ }
96
+ ```
97
+
98
+ ## Textarea Component
99
+
100
+ Multi-line text input field.
101
+
102
+ ### Basic Usage
103
+
104
+ ```tsx
105
+ // React
106
+ <textarea
107
+ value={text}
108
+ onChange={(newText) => setText(newText)}
109
+ placeholder="Enter multiple lines..."
110
+ width={40}
111
+ height={10}
112
+ focused
113
+ />
114
+
115
+ // Solid
116
+ <textarea
117
+ value={text()}
118
+ onInput={(newText) => setText(newText)}
119
+ placeholder="Enter multiple lines..."
120
+ width={40}
121
+ height={10}
122
+ focused
123
+ />
124
+
125
+ // Core
126
+ const textarea = new TextareaRenderable(renderer, {
127
+ id: "editor",
128
+ width: 40,
129
+ height: 10,
130
+ placeholder: "Enter text...",
131
+ })
132
+ ```
133
+
134
+ ### Features
135
+
136
+ ```tsx
137
+ <textarea
138
+ showLineNumbers // Display line numbers
139
+ wrapText // Wrap long lines
140
+ readOnly // Disable editing
141
+ tabSize={2} // Tab character width
142
+ />
143
+ ```
144
+
145
+ ### Syntax Highlighting
146
+
147
+ ```tsx
148
+ <textarea
149
+ language="typescript"
150
+ value={code}
151
+ onChange={setCode}
152
+ />
153
+ ```
154
+
155
+ ## Select Component
156
+
157
+ List selection for choosing from options.
158
+
159
+ ### Basic Usage
160
+
161
+ ```tsx
162
+ // React
163
+ <select
164
+ options={[
165
+ { name: "Option 1", description: "First option", value: "1" },
166
+ { name: "Option 2", description: "Second option", value: "2" },
167
+ { name: "Option 3", description: "Third option", value: "3" },
168
+ ]}
169
+ onSelect={(index, option) => {
170
+ console.log("Selected:", option.name) // Called when Enter is pressed
171
+ }}
172
+ focused
173
+ />
174
+
175
+ // Solid
176
+ <select
177
+ options={[
178
+ { name: "Option 1", description: "First option", value: "1" },
179
+ { name: "Option 2", description: "Second option", value: "2" },
180
+ ]}
181
+ onSelect={(index, option) => {
182
+ console.log("Selected:", option.name) // Called when Enter is pressed
183
+ }}
184
+ focused
185
+ />
186
+
187
+ // Core
188
+ const select = new SelectRenderable(renderer, {
189
+ id: "menu",
190
+ options: [
191
+ { name: "Option 1", description: "First option", value: "1" },
192
+ { name: "Option 2", description: "Second option", value: "2" },
193
+ ],
194
+ })
195
+ select.on(SelectRenderableEvents.ITEM_SELECTED, (index, option) => {
196
+ console.log("Selected:", option.name) // Called when Enter is pressed
197
+ })
198
+ select.focus()
199
+ ```
200
+
201
+ ### Option Format
202
+
203
+ ```typescript
204
+ interface SelectOption {
205
+ name: string // Display text
206
+ description?: string // Optional description shown below
207
+ value?: any // Associated value
208
+ }
209
+ ```
210
+
211
+ ### Styling
212
+
213
+ ```tsx
214
+ <select
215
+ height={8} // Visible height
216
+ selectedIndex={0} // Initially selected
217
+ showScrollIndicator // Show scroll arrows
218
+ selectedBackgroundColor="#333"
219
+ selectedTextColor="#fff"
220
+ highlightBackgroundColor="#444"
221
+ />
222
+ ```
223
+
224
+ ### Navigation
225
+
226
+ Default keybindings:
227
+ - `Up` / `k` - Move up
228
+ - `Down` / `j` - Move down
229
+ - `Enter` - Select item
230
+
231
+ ### Events
232
+
233
+ **Important**: `onSelect` and `onChange` serve different purposes:
234
+
235
+ | Event | Trigger | Use Case |
236
+ |-------|---------|----------|
237
+ | `onSelect` | **Enter key pressed** - user confirms selection | Perform action with selected item |
238
+ | `onChange` | **Arrow keys** - user navigates list | Preview, update UI as user browses |
239
+
240
+ ```tsx
241
+ // React/Solid
242
+ <select
243
+ onSelect={(index, option) => {
244
+ // Called when Enter is pressed - selection confirmed
245
+ console.log("User selected:", option.name)
246
+ performAction(option)
247
+ }}
248
+ onChange={(index, option) => {
249
+ // Called when navigating with arrow keys
250
+ console.log("Browsing:", option.name)
251
+ showPreview(option)
252
+ }}
253
+ />
254
+
255
+ // Core
256
+ select.on(SelectRenderableEvents.ITEM_SELECTED, (index, option) => {
257
+ // Called when Enter is pressed
258
+ })
259
+ select.on(SelectRenderableEvents.SELECTION_CHANGED, (index, option) => {
260
+ // Called when navigating with arrow keys
261
+ })
262
+ ```
263
+
264
+ ## Tab Select Component
265
+
266
+ Horizontal tab-based selection.
267
+
268
+ ### Basic Usage
269
+
270
+ ```tsx
271
+ // React
272
+ <tab-select
273
+ options={[
274
+ { name: "Home", description: "Dashboard view" },
275
+ { name: "Settings", description: "Configuration" },
276
+ { name: "Help", description: "Documentation" },
277
+ ]}
278
+ onSelect={(index, option) => {
279
+ console.log("Tab selected:", option.name) // Called when Enter is pressed
280
+ }}
281
+ focused
282
+ />
283
+
284
+ // Solid (note underscore)
285
+ <tab_select
286
+ options={[
287
+ { name: "Home", description: "Dashboard view" },
288
+ { name: "Settings", description: "Configuration" },
289
+ ]}
290
+ onSelect={(index, option) => {
291
+ console.log("Tab selected:", option.name) // Called when Enter is pressed
292
+ }}
293
+ focused
294
+ />
295
+
296
+ // Core
297
+ const tabs = new TabSelectRenderable(renderer, {
298
+ id: "tabs",
299
+ options: [...],
300
+ tabWidth: 20,
301
+ })
302
+ tabs.on(TabSelectRenderableEvents.ITEM_SELECTED, (index, option) => {
303
+ console.log("Tab selected:", option.name) // Called when Enter is pressed
304
+ })
305
+ tabs.focus()
306
+ ```
307
+
308
+ ### Events
309
+
310
+ Same pattern as Select - `onSelect` for Enter key, `onChange` for navigation:
311
+
312
+ ```tsx
313
+ <tab-select
314
+ onSelect={(index, option) => {
315
+ // Called when Enter is pressed - switch to tab
316
+ setActiveTab(index)
317
+ }}
318
+ onChange={(index, option) => {
319
+ // Called when navigating with arrow keys
320
+ showTabPreview(option)
321
+ }}
322
+ />
323
+ ```
324
+
325
+ ### Styling
326
+
327
+ ```tsx
328
+ // React
329
+ <tab-select
330
+ tabWidth={20} // Width of each tab
331
+ selectedIndex={0} // Initially selected tab
332
+ />
333
+
334
+ // Solid
335
+ <tab_select
336
+ tabWidth={20}
337
+ selectedIndex={0}
338
+ />
339
+ ```
340
+
341
+ ### Navigation
342
+
343
+ Default keybindings:
344
+ - `Left` / `[` - Previous tab
345
+ - `Right` / `]` - Next tab
346
+ - `Enter` - Select tab
347
+
348
+ ## Focus Management
349
+
350
+ ### Single Focused Input
351
+
352
+ ```tsx
353
+ function SingleInput() {
354
+ return <input placeholder="I'm focused" focused />
355
+ }
356
+ ```
357
+
358
+ ### Multiple Inputs with Focus State
359
+
360
+ ```tsx
361
+ // React
362
+ function Form() {
363
+ const [focusIndex, setFocusIndex] = useState(0)
364
+ const fields = ["name", "email", "message"]
365
+
366
+ useKeyboard((key) => {
367
+ if (key.name === "tab") {
368
+ setFocusIndex(i => (i + 1) % fields.length)
369
+ }
370
+ })
371
+
372
+ return (
373
+ <box flexDirection="column" gap={1}>
374
+ {fields.map((field, i) => (
375
+ <input
376
+ key={field}
377
+ placeholder={`Enter ${field}`}
378
+ focused={i === focusIndex}
379
+ />
380
+ ))}
381
+ </box>
382
+ )
383
+ }
384
+ ```
385
+
386
+ ### Focus Methods (Core)
387
+
388
+ ```typescript
389
+ input.focus() // Give focus
390
+ input.blur() // Remove focus
391
+ input.isFocused() // Check focus state
392
+ ```
393
+
394
+ ## Form Patterns
395
+
396
+ ### Login Form
397
+
398
+ ```tsx
399
+ function LoginForm() {
400
+ const [username, setUsername] = useState("")
401
+ const [password, setPassword] = useState("")
402
+ const [focusField, setFocusField] = useState<"username" | "password">("username")
403
+
404
+ useKeyboard((key) => {
405
+ if (key.name === "tab") {
406
+ setFocusField(f => f === "username" ? "password" : "username")
407
+ }
408
+ if (key.name === "enter") {
409
+ handleLogin()
410
+ }
411
+ })
412
+
413
+ return (
414
+ <box flexDirection="column" gap={1} border padding={2}>
415
+ <box flexDirection="row" gap={1}>
416
+ <text>Username:</text>
417
+ <input
418
+ value={username}
419
+ onChange={setUsername}
420
+ focused={focusField === "username"}
421
+ width={20}
422
+ />
423
+ </box>
424
+ <box flexDirection="row" gap={1}>
425
+ <text>Password:</text>
426
+ <input
427
+ value={password}
428
+ onChange={setPassword}
429
+ focused={focusField === "password"}
430
+ width={20}
431
+ />
432
+ </box>
433
+ </box>
434
+ )
435
+ }
436
+ ```
437
+
438
+ ### Search with Results
439
+
440
+ ```tsx
441
+ function SearchableList({ items, onItemSelected }) {
442
+ const [query, setQuery] = useState("")
443
+ const [focusSearch, setFocusSearch] = useState(true)
444
+ const [preview, setPreview] = useState(null)
445
+
446
+ const filtered = items.filter(item =>
447
+ item.toLowerCase().includes(query.toLowerCase())
448
+ )
449
+
450
+ useKeyboard((key) => {
451
+ if (key.name === "tab") {
452
+ setFocusSearch(f => !f)
453
+ }
454
+ })
455
+
456
+ return (
457
+ <box flexDirection="column">
458
+ <input
459
+ value={query}
460
+ onChange={setQuery}
461
+ placeholder="Search..."
462
+ focused={focusSearch}
463
+ />
464
+ <select
465
+ options={filtered.map(item => ({ name: item }))}
466
+ focused={!focusSearch}
467
+ height={10}
468
+ onSelect={(index, option) => {
469
+ // Enter pressed - confirm selection
470
+ onItemSelected(option)
471
+ }}
472
+ onChange={(index, option) => {
473
+ // Navigating - show preview
474
+ setPreview(option)
475
+ }}
476
+ />
477
+ </box>
478
+ )
479
+ }
480
+ ```
481
+
482
+ ## Gotchas
483
+
484
+ ### Focus Required
485
+
486
+ Inputs must be focused to receive keyboard input:
487
+
488
+ ```tsx
489
+ // WRONG - won't receive input
490
+ <input placeholder="Type here" />
491
+
492
+ // CORRECT
493
+ <input placeholder="Type here" focused />
494
+ ```
495
+
496
+ ### Select Options Format
497
+
498
+ Options must be objects with `name` property:
499
+
500
+ ```tsx
501
+ // WRONG
502
+ <select options={["a", "b", "c"]} />
503
+
504
+ // CORRECT
505
+ <select options={[
506
+ { name: "A", description: "Option A" },
507
+ { name: "B", description: "Option B" },
508
+ ]} />
509
+ ```
510
+
511
+ ### Solid Uses Underscores
512
+
513
+ ```tsx
514
+ // React
515
+ <tab-select />
516
+
517
+ // Solid
518
+ <tab_select />
519
+ ```
520
+
521
+ ### Value vs onInput (Solid)
522
+
523
+ Solid uses `onInput` instead of `onChange`:
524
+
525
+ ```tsx
526
+ // React
527
+ <input value={value} onChange={setValue} />
528
+
529
+ // Solid
530
+ <input value={value()} onInput={setValue} />
531
+ ```