@valyrianjs/terminal 0.1.1 → 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/README.md +105 -55
- package/dist/ansi.d.ts +20 -4
- package/dist/ansi.d.ts.map +1 -1
- package/dist/ansi.js +171 -47
- package/dist/ansi.js.map +1 -1
- package/dist/editor-state.d.ts +22 -0
- package/dist/editor-state.d.ts.map +1 -0
- package/dist/editor-state.js +110 -0
- package/dist/editor-state.js.map +1 -0
- package/dist/events.d.ts +1 -4
- package/dist/events.d.ts.map +1 -1
- package/dist/events.js +15 -38
- package/dist/events.js.map +1 -1
- package/dist/index.d.ts +5 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/keymap.d.ts +7 -0
- package/dist/keymap.d.ts.map +1 -0
- package/dist/keymap.js +133 -0
- package/dist/keymap.js.map +1 -0
- package/dist/layout.d.ts +10 -1
- package/dist/layout.d.ts.map +1 -1
- package/dist/layout.js +97 -7
- package/dist/layout.js.map +1 -1
- package/dist/mouse.d.ts +1 -0
- package/dist/mouse.d.ts.map +1 -1
- package/dist/mouse.js +24 -1
- package/dist/mouse.js.map +1 -1
- package/dist/output-writer.d.ts +9 -0
- package/dist/output-writer.d.ts.map +1 -0
- package/dist/output-writer.js +79 -0
- package/dist/output-writer.js.map +1 -0
- package/dist/paste.d.ts +7 -0
- package/dist/paste.d.ts.map +1 -0
- package/dist/paste.js +18 -0
- package/dist/paste.js.map +1 -0
- package/dist/primitives.d.ts +15 -3
- package/dist/primitives.d.ts.map +1 -1
- package/dist/primitives.js +9 -1
- package/dist/primitives.js.map +1 -1
- package/dist/render.d.ts +9 -4
- package/dist/render.d.ts.map +1 -1
- package/dist/render.js +923 -68
- package/dist/render.js.map +1 -1
- package/dist/runtime.d.ts +29 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +209 -0
- package/dist/runtime.js.map +1 -0
- package/dist/scheduler.d.ts +8 -0
- package/dist/scheduler.d.ts.map +1 -0
- package/dist/scheduler.js +24 -0
- package/dist/scheduler.js.map +1 -0
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +858 -199
- package/dist/session.js.map +1 -1
- package/dist/stream-log.d.ts +40 -0
- package/dist/stream-log.d.ts.map +1 -0
- package/dist/stream-log.js +73 -0
- package/dist/stream-log.js.map +1 -0
- package/dist/text.d.ts +3 -0
- package/dist/text.d.ts.map +1 -0
- package/dist/text.js +19 -0
- package/dist/text.js.map +1 -0
- package/dist/theme.d.ts +7 -0
- package/dist/theme.d.ts.map +1 -0
- package/dist/theme.js +254 -0
- package/dist/theme.js.map +1 -0
- package/dist/tree.d.ts +2 -0
- package/dist/tree.d.ts.map +1 -1
- package/dist/tree.js +42 -1
- package/dist/tree.js.map +1 -1
- package/dist/types.d.ts +203 -24
- package/dist/types.d.ts.map +1 -1
- package/docs/api-reference.md +313 -142
- package/docs/assets/quick-note.svg +13 -0
- package/docs/cookbook.md +296 -201
- package/docs/core-concepts.md +143 -55
- package/docs/getting-started.md +209 -90
- package/docs/interaction-model.md +98 -54
- package/docs/primitive-gallery.md +370 -0
- package/docs/session-runtime.md +131 -362
- package/docs/valyrian-modules.md +3196 -0
- package/llms-full.txt +5377 -0
- package/package.json +21 -8
- package/src/ansi.ts +269 -0
- package/src/clipboard.ts +76 -0
- package/src/editor-state.ts +162 -0
- package/src/events.ts +163 -0
- package/src/index.ts +95 -0
- package/src/keymap.ts +151 -0
- package/src/layout.ts +282 -0
- package/src/mouse.ts +68 -0
- package/src/output-writer.ts +93 -0
- package/src/paste.ts +23 -0
- package/src/primitives.ts +55 -0
- package/src/render.ts +1204 -0
- package/src/runtime.ts +267 -0
- package/src/scheduler.ts +33 -0
- package/src/session.ts +1408 -0
- package/src/stream-log.ts +96 -0
- package/src/text.ts +20 -0
- package/src/theme.ts +263 -0
- package/src/tree.ts +169 -0
- package/src/types.ts +541 -0
- package/tsconfig.json +4 -7
- package/docs/local-demo.md +0 -28
|
@@ -1,115 +1,159 @@
|
|
|
1
1
|
# Interaction Model
|
|
2
2
|
|
|
3
|
-
This guide
|
|
3
|
+
This guide explains how interactive primitives receive input and report events. For lifecycle and stream details, see [Session Runtime](./session-runtime.md).
|
|
4
4
|
|
|
5
5
|
## Shared rules
|
|
6
6
|
|
|
7
|
-
- `
|
|
8
|
-
- `
|
|
9
|
-
-
|
|
10
|
-
-
|
|
7
|
+
- Interactive nodes need stable `id` values for programmatic focus, click, and coordinate lookup.
|
|
8
|
+
- `Tab` moves to the next focusable node; `Shift+Tab` moves back.
|
|
9
|
+
- `focusAt(x, y)` and `clickAt(x, y)` use hitboxes from the current rendered frame.
|
|
10
|
+
- Components report events to your handlers; your app owns the resulting state changes.
|
|
11
|
+
- Connected streams, mouse input, clipboard integration, and modified keys follow terminal and runtime capabilities.
|
|
11
12
|
|
|
12
|
-
##
|
|
13
|
+
## Input events
|
|
13
14
|
|
|
14
|
-
`
|
|
15
|
+
Keyboard dispatch uses normalized key names such as `ENTER`, `TAB`, `SHIFT_TAB`, `LEFT`, `RIGHT`, `CTRL_V`, and single-character strings. When a session is connected to `stdin`, terminal input is parsed and routed to the focused primitive.
|
|
15
16
|
|
|
16
|
-
|
|
17
|
+
Pasted text is treated as text input for the focused primitive. Do not treat pasted strings or key sequences as terminal control instructions inside rendered content.
|
|
17
18
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
-
|
|
23
|
-
- `
|
|
24
|
-
-
|
|
25
|
-
- `
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
19
|
+
## Focus and ids
|
|
20
|
+
|
|
21
|
+
Focus is session state. The session can:
|
|
22
|
+
|
|
23
|
+
- focus by id with `focus(id)`
|
|
24
|
+
- move sequentially with `focusNext()` and `focusPrev()`
|
|
25
|
+
- dispatch keys to the focused primitive with `dispatchKey(key)`
|
|
26
|
+
- resolve coordinates with `focusAt(x, y)` and `clickAt(x, y)`
|
|
27
|
+
|
|
28
|
+
`FocusScope` bounds sequential focus traversal to a local group when focus is already inside that active scope. `Overlay trapFocus` keeps traversal inside an overlay-like region while the overlay is present. These primitives help compose popovers and lightweight dialog surfaces while routing and command execution stay in the app layer.
|
|
29
|
+
|
|
30
|
+
## Component interaction
|
|
31
|
+
|
|
32
|
+
### `Input`
|
|
33
|
+
|
|
34
|
+
`Input` is a single-line editing primitive.
|
|
35
|
+
|
|
36
|
+
Supported behavior includes:
|
|
37
|
+
|
|
38
|
+
- character insertion
|
|
39
|
+
- `ENTER` submit
|
|
40
|
+
- cursor movement with `LEFT`, `RIGHT`, `HOME`, and `END`
|
|
41
|
+
- selection with `SHIFT_LEFT`, `SHIFT_RIGHT`, and `CTRL_A`
|
|
42
|
+
- copy, cut, and paste through `CTRL_C`, `CTRL_X`, and `CTRL_V`
|
|
43
|
+
- deletion with `BACKSPACE` and `DELETE`
|
|
44
|
+
- context press through pointer context input
|
|
45
|
+
|
|
46
|
+
Main handlers:
|
|
47
|
+
|
|
48
|
+
- `onchange`
|
|
49
|
+
- `oninput`
|
|
50
|
+
- `onsubmit`
|
|
51
|
+
- `oncontextpress`
|
|
52
|
+
|
|
53
|
+
### `Editor`
|
|
54
|
+
|
|
55
|
+
`Editor` is a multiline editing primitive.
|
|
56
|
+
|
|
57
|
+
Supported behavior includes:
|
|
58
|
+
|
|
59
|
+
- character insertion
|
|
60
|
+
- `SHIFT_ENTER` newline when the terminal reports that modified key
|
|
61
|
+
- `ENTER` submit
|
|
62
|
+
- `ESCAPE` cancel
|
|
63
|
+
- line and cursor movement with arrow keys, `HOME`, and `END`
|
|
64
|
+
- paste through `CTRL_V` or terminal paste input
|
|
65
|
+
- deletion with `BACKSPACE` and `DELETE`
|
|
29
66
|
|
|
30
67
|
Main handlers:
|
|
31
68
|
|
|
32
69
|
- `onchange`
|
|
33
70
|
- `oninput`
|
|
34
71
|
- `onsubmit`
|
|
35
|
-
- `
|
|
72
|
+
- `oncancel`
|
|
36
73
|
|
|
37
|
-
|
|
74
|
+
Cursor positions use JavaScript string columns for deterministic common-text editing. Keep specialized grapheme-width handling in app-level formatting when a workflow needs exact terminal cell width for complex character sequences.
|
|
75
|
+
|
|
76
|
+
### `Button`
|
|
38
77
|
|
|
39
78
|
`Button` represents a discrete action.
|
|
40
79
|
|
|
41
|
-
|
|
80
|
+
Activation paths:
|
|
42
81
|
|
|
43
|
-
-
|
|
44
|
-
-
|
|
45
|
-
-
|
|
82
|
+
- `ENTER` or `SPACE` when focused
|
|
83
|
+
- `session.click(id)`
|
|
84
|
+
- `session.clickAt(x, y)` when the coordinate lands on the button
|
|
46
85
|
|
|
47
86
|
Main handlers:
|
|
48
87
|
|
|
49
88
|
- `onpress`
|
|
50
|
-
- `
|
|
51
|
-
- `
|
|
52
|
-
|
|
89
|
+
- `ondoublepress`
|
|
90
|
+
- `oncontextpress`
|
|
91
|
+
|
|
92
|
+
A quick second primary mouse press keeps the normal activation behavior and also emits `ondoublepress` when the handler exists. A secondary mouse press emits `oncontextpress`.
|
|
53
93
|
|
|
54
|
-
|
|
94
|
+
### `List`
|
|
55
95
|
|
|
56
96
|
`List` models row selection and activation.
|
|
57
97
|
|
|
58
|
-
|
|
98
|
+
Supported behavior includes:
|
|
59
99
|
|
|
60
|
-
- `
|
|
61
|
-
- `
|
|
62
|
-
- `
|
|
63
|
-
- mouse hover
|
|
100
|
+
- `UP` and `LEFT` move selection up
|
|
101
|
+
- `DOWN` and `RIGHT` move selection down
|
|
102
|
+
- `ENTER` activates the selected row
|
|
103
|
+
- mouse hover reports row details when mouse input is connected
|
|
104
|
+
- quick primary mouse presses on the same row emit `ondoublepress`
|
|
105
|
+
- secondary mouse presses emit `oncontextpress` for the target row
|
|
64
106
|
|
|
65
107
|
Main handlers:
|
|
66
108
|
|
|
67
109
|
- `onchange`
|
|
68
110
|
- `onpress`
|
|
111
|
+
- `ondoublepress`
|
|
112
|
+
- `oncontextpress`
|
|
69
113
|
- `onhover`
|
|
70
114
|
- `onrowenter`
|
|
71
115
|
- `onrowleave`
|
|
72
116
|
- `oncapturestart`
|
|
73
117
|
- `oncaptureend`
|
|
74
118
|
|
|
75
|
-
|
|
119
|
+
`pointerCapture` lets a list keep drag interaction even when the pointer leaves the initial hitbox.
|
|
76
120
|
|
|
77
|
-
|
|
121
|
+
### `ScrollView`
|
|
78
122
|
|
|
79
123
|
`ScrollView` clips vertical content and exposes viewport-based interaction.
|
|
80
124
|
|
|
81
|
-
|
|
125
|
+
Supported behavior includes:
|
|
82
126
|
|
|
83
|
-
- `
|
|
84
|
-
- `
|
|
85
|
-
- `
|
|
86
|
-
-
|
|
87
|
-
-
|
|
127
|
+
- `UP` and `DOWN` scrolling when focused
|
|
128
|
+
- `height` as the visible viewport
|
|
129
|
+
- `highlightRows` for marking visible rows
|
|
130
|
+
- mouse hover details when mouse input is connected
|
|
131
|
+
- context press reports the target visible row
|
|
88
132
|
|
|
89
133
|
Main handlers:
|
|
90
134
|
|
|
91
135
|
- `onhover`
|
|
92
136
|
- `onrowenter`
|
|
93
137
|
- `onrowleave`
|
|
138
|
+
- `oncontextpress`
|
|
94
139
|
- `oncapturestart`
|
|
95
140
|
- `oncaptureend`
|
|
96
141
|
|
|
97
|
-
|
|
142
|
+
`pointerCapture` lets a scroll view keep drag interaction even when the pointer leaves the viewport.
|
|
98
143
|
|
|
99
|
-
## Mouse and pointer
|
|
144
|
+
## Mouse and pointer behavior
|
|
100
145
|
|
|
101
|
-
When
|
|
146
|
+
When a connected session receives supported SGR mouse input:
|
|
102
147
|
|
|
103
|
-
-
|
|
104
|
-
-
|
|
105
|
-
-
|
|
106
|
-
-
|
|
148
|
+
- press focuses or activates the matching hitbox
|
|
149
|
+
- drag extends input selection or updates list/scroll hover
|
|
150
|
+
- release ends capture when capture is active
|
|
151
|
+
- wheel input maps to vertical navigation
|
|
107
152
|
|
|
108
|
-
|
|
153
|
+
Mouse behavior follows supported terminal input sequences and the active session connection. Keep a keyboard path for important actions.
|
|
109
154
|
|
|
110
155
|
## Where to go next
|
|
111
156
|
|
|
112
|
-
-
|
|
113
|
-
-
|
|
114
|
-
-
|
|
115
|
-
- `docs/api-reference.md` for quick lookup of props, payloads, and types
|
|
157
|
+
- [Cookbook](./cookbook.md) for recipes that combine primitives.
|
|
158
|
+
- [Session Runtime](./session-runtime.md) for streams, clipboard adapters, mouse input, and cleanup.
|
|
159
|
+
- [API Reference](./api-reference.md) for props and event payloads.
|
|
@@ -0,0 +1,370 @@
|
|
|
1
|
+
# Primitive Gallery
|
|
2
|
+
|
|
3
|
+
Build complete terminal interfaces from focused primitives.
|
|
4
|
+
|
|
5
|
+
Use this gallery to choose primitives, see their main props, and compose terminal mini apps. The gallery teaches what each primitive does and how it fits with the others. Use API Reference for prop-level details.
|
|
6
|
+
|
|
7
|
+
| Primitive | Use it for | Demo |
|
|
8
|
+
| --- | --- | --- |
|
|
9
|
+
| `Screen` | the top-level surface of a terminal app | [`examples/docs/primitive-layout-shell.tsx`](../examples/docs/primitive-layout-shell.tsx) |
|
|
10
|
+
| `Text` | copy that should render as terminal text | [`examples/docs/primitive-layout-shell.tsx`](../examples/docs/primitive-layout-shell.tsx) |
|
|
11
|
+
| `Box` | small surfaces, cards, and stacked sections | [`examples/docs/primitive-layout-shell.tsx`](../examples/docs/primitive-layout-shell.tsx) |
|
|
12
|
+
| `View` | named regions that help app code describe purpose | [`examples/docs/primitive-layout-shell.tsx`](../examples/docs/primitive-layout-shell.tsx) |
|
|
13
|
+
| `Pane` | sidebars, detail panels, and app sections | [`examples/docs/primitive-layout-shell.tsx`](../examples/docs/primitive-layout-shell.tsx) |
|
|
14
|
+
| `Split` | resizable app shells and master/detail layouts | [`examples/docs/primitive-layout-shell.tsx`](../examples/docs/primitive-layout-shell.tsx) |
|
|
15
|
+
| `Fixed` | headers, footers, rails, and persistent status bars | [`examples/docs/primitive-layout-shell.tsx`](../examples/docs/primitive-layout-shell.tsx) |
|
|
16
|
+
| `Input` | names, filters, prompts, and short commands | [`examples/docs/primitive-input-workbench.tsx`](../examples/docs/primitive-input-workbench.tsx) |
|
|
17
|
+
| `Editor` | notes, descriptions, and longer messages | [`examples/docs/primitive-input-workbench.tsx`](../examples/docs/primitive-input-workbench.tsx) |
|
|
18
|
+
| `Button` | save actions, confirmations, command triggers, and app actions | [`examples/docs/primitive-input-workbench.tsx`](../examples/docs/primitive-input-workbench.tsx) |
|
|
19
|
+
| `FocusScope` | forms, panels, and overlays where Tab should stay within a focused area | [`examples/docs/primitive-input-workbench.tsx`](../examples/docs/primitive-input-workbench.tsx) |
|
|
20
|
+
| `List` | menus, choosers, command lists, and item browsers | [`examples/docs/primitive-data-explorer.tsx`](../examples/docs/primitive-data-explorer.tsx) |
|
|
21
|
+
| `Table` | compact data detail and aligned text pairs | [`examples/docs/primitive-data-explorer.tsx`](../examples/docs/primitive-data-explorer.tsx) |
|
|
22
|
+
| `Row` | one record line inside a `Table` | [`examples/docs/primitive-data-explorer.tsx`](../examples/docs/primitive-data-explorer.tsx) |
|
|
23
|
+
| `Td` | styled or padded data cells | [`examples/docs/primitive-data-explorer.tsx`](../examples/docs/primitive-data-explorer.tsx) |
|
|
24
|
+
| `ScrollView` | long instructions, timelines, and scrollable panels | [`examples/docs/primitive-activity-console.tsx`](../examples/docs/primitive-activity-console.tsx) |
|
|
25
|
+
| `LogView` | activity feeds, status streams, and event output | [`examples/docs/primitive-activity-console.tsx`](../examples/docs/primitive-activity-console.tsx) |
|
|
26
|
+
| `Overlay` | command panels, dialogs, palettes, and focused chooser surfaces | [`examples/docs/primitive-command-panel.tsx`](../examples/docs/primitive-command-panel.tsx) |
|
|
27
|
+
|
|
28
|
+
## Start with the shell
|
|
29
|
+
|
|
30
|
+
Use `Screen` and `Text` to establish the app root and clear terminal copy.
|
|
31
|
+
|
|
32
|
+
### `Screen`
|
|
33
|
+
|
|
34
|
+
Use `Screen` as the top-level surface for a terminal app.
|
|
35
|
+
|
|
36
|
+
**What it is:** A screen root that gives the terminal tree a title and viewport context.
|
|
37
|
+
**Use it for:** the top-level surface of a terminal app.
|
|
38
|
+
**Core props:** `title`, `id`, `focusable`.
|
|
39
|
+
|
|
40
|
+
**Minimal example:**
|
|
41
|
+
|
|
42
|
+
```tsx
|
|
43
|
+
<Screen title="Desk"><Text>Ready</Text></Screen>
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
**Complete demo:** [`examples/docs/primitive-layout-shell.tsx`](../examples/docs/primitive-layout-shell.tsx). Run it with `bun examples/docs/primitive-layout-shell.tsx` and quit with `Ctrl+C`.
|
|
47
|
+
|
|
48
|
+
### `Text`
|
|
49
|
+
|
|
50
|
+
Use `Text` for labels, status lines, and short terminal copy.
|
|
51
|
+
|
|
52
|
+
**What it is:** A text node for labels, status lines, and short messages.
|
|
53
|
+
**Use it for:** copy that should render as terminal text.
|
|
54
|
+
**Core props:** `value`, `style`, `styles`, `state`.
|
|
55
|
+
|
|
56
|
+
**Minimal example:**
|
|
57
|
+
|
|
58
|
+
```tsx
|
|
59
|
+
<Text>Status: ready</Text>
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
**Complete demo:** [`examples/docs/primitive-layout-shell.tsx`](../examples/docs/primitive-layout-shell.tsx). Run it with `bun examples/docs/primitive-layout-shell.tsx` and quit with `Ctrl+C`.
|
|
63
|
+
|
|
64
|
+
## Compose layout surfaces
|
|
65
|
+
|
|
66
|
+
Use `Split` to compose responsive rows and columns, then fill each region with `Pane`, `Box`, or `View`.
|
|
67
|
+
|
|
68
|
+
### `Box`
|
|
69
|
+
|
|
70
|
+
Use `Box` for cards, stacked sections, and grouped content.
|
|
71
|
+
|
|
72
|
+
**What it is:** A layout container for grouped content.
|
|
73
|
+
**Use it for:** small surfaces, cards, and stacked sections.
|
|
74
|
+
**Core props:** `direction`, `gap`, `padding`, `width`, `height`, `fill`, `style`.
|
|
75
|
+
|
|
76
|
+
**Minimal example:**
|
|
77
|
+
|
|
78
|
+
```tsx
|
|
79
|
+
<Box direction="column" gap={1}><Text>Summary</Text></Box>
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
**Complete demo:** [`examples/docs/primitive-layout-shell.tsx`](../examples/docs/primitive-layout-shell.tsx). Run it with `bun examples/docs/primitive-layout-shell.tsx` and quit with `Ctrl+C`.
|
|
83
|
+
|
|
84
|
+
### `View`
|
|
85
|
+
|
|
86
|
+
Use `View` to name semantic regions in your terminal layout.
|
|
87
|
+
|
|
88
|
+
**What it is:** A semantic layout container with the same layout behavior as `Box`.
|
|
89
|
+
**Use it for:** named regions that help app code describe purpose.
|
|
90
|
+
**Core props:** `role`, plus Box layout props.
|
|
91
|
+
|
|
92
|
+
**Minimal example:**
|
|
93
|
+
|
|
94
|
+
```tsx
|
|
95
|
+
<View role="main"><Text>Work area</Text></View>
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
**Complete demo:** [`examples/docs/primitive-layout-shell.tsx`](../examples/docs/primitive-layout-shell.tsx). Run it with `bun examples/docs/primitive-layout-shell.tsx` and quit with `Ctrl+C`.
|
|
99
|
+
|
|
100
|
+
### `Pane`
|
|
101
|
+
|
|
102
|
+
Use `Pane` for sidebars, detail panels, and app sections.
|
|
103
|
+
|
|
104
|
+
**What it is:** A layout boundary for a terminal region.
|
|
105
|
+
**Use it for:** sidebars, detail panels, and app sections.
|
|
106
|
+
**Core props:** `direction`, `gap`, `padding`, `fill`, `style`, `id`, `focusable`.
|
|
107
|
+
|
|
108
|
+
**Minimal example:**
|
|
109
|
+
|
|
110
|
+
```tsx
|
|
111
|
+
<Pane style={{ background: "#111827" }}><Text>Inbox</Text></Pane>
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
**Complete demo:** [`examples/docs/primitive-layout-shell.tsx`](../examples/docs/primitive-layout-shell.tsx). Run it with `bun examples/docs/primitive-layout-shell.tsx` and quit with `Ctrl+C`.
|
|
115
|
+
|
|
116
|
+
### `Split`
|
|
117
|
+
|
|
118
|
+
Use `Split` for resizable shells and master/detail layouts.
|
|
119
|
+
|
|
120
|
+
**What it is:** A split layout primitive for rows and columns.
|
|
121
|
+
**Use it for:** resizable app shells and master/detail layouts.
|
|
122
|
+
**Core props:** `direction`, `sizes`, `breakpoints`, `gap`, `width`, `height`, `fill`.
|
|
123
|
+
|
|
124
|
+
**Minimal example:**
|
|
125
|
+
|
|
126
|
+
```tsx
|
|
127
|
+
<Split sizes={["30%", "1fr"]}><Pane><Text>List</Text></Pane><Pane><Text>Detail</Text></Pane></Split>
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
**Complete demo:** [`examples/docs/primitive-layout-shell.tsx`](../examples/docs/primitive-layout-shell.tsx). Run it with `bun examples/docs/primitive-layout-shell.tsx` and quit with `Ctrl+C`.
|
|
131
|
+
|
|
132
|
+
### `Fixed`
|
|
133
|
+
|
|
134
|
+
Use `Fixed` for headers, footers, rails, and persistent status bars.
|
|
135
|
+
|
|
136
|
+
**What it is:** A reserved region attached to an edge of a parent frame.
|
|
137
|
+
**Use it for:** headers, footers, rails, and persistent status bars.
|
|
138
|
+
**Core props:** `position`, `size`.
|
|
139
|
+
|
|
140
|
+
Inside `Screen` or `Pane`, `Fixed` uses the parent frame. If you pass a standalone `Fixed` root to `renderTerminal()`, pass `{ cols, rows }` so it has a viewport.
|
|
141
|
+
|
|
142
|
+
**Minimal example:**
|
|
143
|
+
|
|
144
|
+
```tsx
|
|
145
|
+
<Screen>
|
|
146
|
+
<Fixed position="bottom" size={1}><Text>Ctrl+C: quit</Text></Fixed>
|
|
147
|
+
<Pane><Text>Work area</Text></Pane>
|
|
148
|
+
</Screen>
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
**Complete demo:** [`examples/docs/primitive-layout-shell.tsx`](../examples/docs/primitive-layout-shell.tsx). Run it with `bun examples/docs/primitive-layout-shell.tsx` and quit with `Ctrl+C`.
|
|
152
|
+
|
|
153
|
+
## Collect input
|
|
154
|
+
|
|
155
|
+
Use `Input`, `Editor`, `Button`, and `FocusScope` to collect intent and move it into app state.
|
|
156
|
+
|
|
157
|
+
### `Input`
|
|
158
|
+
|
|
159
|
+
Use `Input` for names, filters, prompts, and short commands.
|
|
160
|
+
|
|
161
|
+
**What it is:** A single-line editable field.
|
|
162
|
+
**Use it for:** names, filters, prompts, and short commands.
|
|
163
|
+
**Core props:** `id`, `value`, `placeholder`, `onchange`, `oninput`, `onsubmit`, `oncontextpress`.
|
|
164
|
+
|
|
165
|
+
**Minimal example:**
|
|
166
|
+
|
|
167
|
+
```tsx
|
|
168
|
+
<Input id="name" value={name} placeholder="Name" onchange={(event) => { name = event.value; }} />
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
**Complete demo:** [`examples/docs/primitive-input-workbench.tsx`](../examples/docs/primitive-input-workbench.tsx). Run it with `bun examples/docs/primitive-input-workbench.tsx` and quit with `Ctrl+C`.
|
|
172
|
+
|
|
173
|
+
### `Editor`
|
|
174
|
+
|
|
175
|
+
Use `Editor` for notes, descriptions, and longer messages.
|
|
176
|
+
|
|
177
|
+
**What it is:** A multi-line editable field.
|
|
178
|
+
**Use it for:** notes, descriptions, and longer messages.
|
|
179
|
+
**Core props:** `id`, `value`, `placeholder`, `height`, `onchange`, `oninput`, `onsubmit`, `oncancel`.
|
|
180
|
+
|
|
181
|
+
**Minimal example:**
|
|
182
|
+
|
|
183
|
+
```tsx
|
|
184
|
+
<Editor id="details" height={4} value={details} onchange={(event) => { details = event.value; }} />
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
**Complete demo:** [`examples/docs/primitive-input-workbench.tsx`](../examples/docs/primitive-input-workbench.tsx). Run it with `bun examples/docs/primitive-input-workbench.tsx` and quit with `Ctrl+C`.
|
|
188
|
+
|
|
189
|
+
### `Button`
|
|
190
|
+
|
|
191
|
+
Use `Button` for save actions, confirmations, command triggers, and app actions.
|
|
192
|
+
|
|
193
|
+
**What it is:** A focusable action control.
|
|
194
|
+
**Use it for:** save actions, confirmations, command triggers, and app actions.
|
|
195
|
+
**Core props:** `id`, `label`, `onpress`, `ondoublepress`, `oncontextpress`, `style`, `styles`, `state`.
|
|
196
|
+
|
|
197
|
+
**Minimal example:**
|
|
198
|
+
|
|
199
|
+
```tsx
|
|
200
|
+
<Button id="save" onpress={() => save()}>Save</Button>
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
**Complete demo:** [`examples/docs/primitive-input-workbench.tsx`](../examples/docs/primitive-input-workbench.tsx). Run it with `bun examples/docs/primitive-input-workbench.tsx` and quit with `Ctrl+C`.
|
|
204
|
+
|
|
205
|
+
### `FocusScope`
|
|
206
|
+
|
|
207
|
+
Use `FocusScope` to keep input, lists, and actions together inside a panel.
|
|
208
|
+
|
|
209
|
+
**What it is:** A focus boundary for a local group.
|
|
210
|
+
**Use it for:** forms, panels, and overlays where Tab should stay within a focused area.
|
|
211
|
+
**Core props:** `active`.
|
|
212
|
+
|
|
213
|
+
**Minimal example:**
|
|
214
|
+
|
|
215
|
+
```tsx
|
|
216
|
+
<FocusScope><Input id="query" /><Button id="run">Run</Button></FocusScope>
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
**Complete demo:** [`examples/docs/primitive-input-workbench.tsx`](../examples/docs/primitive-input-workbench.tsx). Run it with `bun examples/docs/primitive-input-workbench.tsx` and quit with `Ctrl+C`.
|
|
220
|
+
|
|
221
|
+
## Navigate collections
|
|
222
|
+
|
|
223
|
+
Use `List` for selection and `Table`, `Row`, and `Td` for compact detail views.
|
|
224
|
+
|
|
225
|
+
### `List`
|
|
226
|
+
|
|
227
|
+
Use `List` for menus, choosers, command lists, and item browsers.
|
|
228
|
+
|
|
229
|
+
**What it is:** A focusable collection control with selection and press events.
|
|
230
|
+
**Use it for:** menus, choosers, command lists, and item browsers.
|
|
231
|
+
**Core props:** `id`, `items`, `renderItem`, `virtualized`, `onchange`, `onpress`, `ondoublepress`, `oncontextpress`.
|
|
232
|
+
|
|
233
|
+
**Minimal example:**
|
|
234
|
+
|
|
235
|
+
```tsx
|
|
236
|
+
<List id="menu" items={["Inbox", "Done"]} onchange={(event) => { selected = event.value; }} />
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
**Complete demo:** [`examples/docs/primitive-data-explorer.tsx`](../examples/docs/primitive-data-explorer.tsx). Run it with `bun examples/docs/primitive-data-explorer.tsx` and quit with `Ctrl+C`.
|
|
240
|
+
|
|
241
|
+
### `Table`
|
|
242
|
+
|
|
243
|
+
Use `Table` for compact data detail and aligned text pairs.
|
|
244
|
+
|
|
245
|
+
**What it is:** A table container for rows and cells.
|
|
246
|
+
**Use it for:** compact data detail and aligned text pairs.
|
|
247
|
+
**Core props:** `v-for` when Valyrian loop helpers fit your app.
|
|
248
|
+
|
|
249
|
+
**Minimal example:**
|
|
250
|
+
|
|
251
|
+
```tsx
|
|
252
|
+
<Table><Row><Td><Text>Name</Text></Td><Td><Text>Ada</Text></Td></Row></Table>
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
**Complete demo:** [`examples/docs/primitive-data-explorer.tsx`](../examples/docs/primitive-data-explorer.tsx). Run it with `bun examples/docs/primitive-data-explorer.tsx` and quit with `Ctrl+C`.
|
|
256
|
+
|
|
257
|
+
### `Row`
|
|
258
|
+
|
|
259
|
+
Use `Row` for one record line inside a `Table`.
|
|
260
|
+
|
|
261
|
+
**What it is:** A table row that separates child cells.
|
|
262
|
+
**Use it for:** one record line inside a `Table`.
|
|
263
|
+
**Core props:** `separator`.
|
|
264
|
+
|
|
265
|
+
**Minimal example:**
|
|
266
|
+
|
|
267
|
+
```tsx
|
|
268
|
+
<Row separator=" "><Td><Text>Status</Text></Td><Td><Text>Ready</Text></Td></Row>
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
**Complete demo:** [`examples/docs/primitive-data-explorer.tsx`](../examples/docs/primitive-data-explorer.tsx). Run it with `bun examples/docs/primitive-data-explorer.tsx` and quit with `Ctrl+C`.
|
|
272
|
+
|
|
273
|
+
### `Td`
|
|
274
|
+
|
|
275
|
+
Use `Td` for styled or padded data cells.
|
|
276
|
+
|
|
277
|
+
**What it is:** A table cell that can carry padding and styles.
|
|
278
|
+
**Use it for:** styled or padded data cells.
|
|
279
|
+
**Core props:** `padding`, `style`, `styles`, `state`.
|
|
280
|
+
|
|
281
|
+
**Minimal example:**
|
|
282
|
+
|
|
283
|
+
```tsx
|
|
284
|
+
<Td padding={{ x: 1 }}><Text>Ready</Text></Td>
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
**Complete demo:** [`examples/docs/primitive-data-explorer.tsx`](../examples/docs/primitive-data-explorer.tsx). Run it with `bun examples/docs/primitive-data-explorer.tsx` and quit with `Ctrl+C`.
|
|
288
|
+
|
|
289
|
+
## Show scrollable activity
|
|
290
|
+
|
|
291
|
+
Use `ScrollView` and `LogView` when content grows past the visible region.
|
|
292
|
+
|
|
293
|
+
### `ScrollView`
|
|
294
|
+
|
|
295
|
+
Use `ScrollView` for long instructions, timelines, and scrollable panels.
|
|
296
|
+
|
|
297
|
+
**What it is:** A bounded viewport for child content.
|
|
298
|
+
**Use it for:** long instructions, timelines, and scrollable panels.
|
|
299
|
+
**Core props:** `id`, `height`, `highlightRows`, `pointerCapture`, `oncontextpress`, row pointer events.
|
|
300
|
+
|
|
301
|
+
**Minimal example:**
|
|
302
|
+
|
|
303
|
+
```tsx
|
|
304
|
+
<ScrollView id="activity" height={6}><Text>One</Text><Text>Two</Text></ScrollView>
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
**Complete demo:** [`examples/docs/primitive-activity-console.tsx`](../examples/docs/primitive-activity-console.tsx). Run it with `bun examples/docs/primitive-activity-console.tsx` and quit with `Ctrl+C`.
|
|
308
|
+
|
|
309
|
+
### `LogView`
|
|
310
|
+
|
|
311
|
+
Use `LogView` for activity feeds, status streams, and event output.
|
|
312
|
+
|
|
313
|
+
**What it is:** A log renderer for growing activity streams.
|
|
314
|
+
**Use it for:** activity feeds, status streams, and event output.
|
|
315
|
+
**Core props:** `entries`, `followTail`, `emptyText`, `renderEntry`.
|
|
316
|
+
|
|
317
|
+
**Minimal example:**
|
|
318
|
+
|
|
319
|
+
```tsx
|
|
320
|
+
<LogView entries={[{ id: "1", content: "ready" }]} followTail />
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
**Complete demo:** [`examples/docs/primitive-activity-console.tsx`](../examples/docs/primitive-activity-console.tsx). Run it with `bun examples/docs/primitive-activity-console.tsx` and quit with `Ctrl+C`.
|
|
324
|
+
|
|
325
|
+
## Layer focused panels
|
|
326
|
+
|
|
327
|
+
Use `Overlay` with `FocusScope` to place a focused chooser over the current screen.
|
|
328
|
+
|
|
329
|
+
### `Overlay`
|
|
330
|
+
|
|
331
|
+
Use `Overlay` for command panels, dialogs, palettes, and focused chooser surfaces.
|
|
332
|
+
|
|
333
|
+
**What it is:** A positioned layer over the current frame.
|
|
334
|
+
**Use it for:** command panels, dialogs, palettes, and focused chooser surfaces.
|
|
335
|
+
**Core props:** `id`, `margin`, `trapFocus`, `style`. `margin` is required and accepts a number, a percentage string, or `{ x, y }` with number or percentage-string values. When `Overlay` is the root passed to `renderTerminal()`, pass exact `{ cols, rows }` as the second argument so margin can resolve against terminal dimensions.
|
|
336
|
+
|
|
337
|
+
**Minimal example:**
|
|
338
|
+
|
|
339
|
+
```tsx
|
|
340
|
+
<Overlay margin={{ x: 4, y: 2 }} trapFocus><Text>Command Panel</Text></Overlay>
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
**Complete demo:** [`examples/docs/primitive-command-panel.tsx`](../examples/docs/primitive-command-panel.tsx). Run it with `bun examples/docs/primitive-command-panel.tsx` and quit with `Ctrl+C`.
|
|
344
|
+
|
|
345
|
+
### `FocusScope`
|
|
346
|
+
|
|
347
|
+
Use `FocusScope` to keep input, lists, and actions together inside a panel.
|
|
348
|
+
|
|
349
|
+
**What it is:** A focus boundary that pairs well with overlay content.
|
|
350
|
+
**Use it for:** keeping input, lists, and actions together inside a panel.
|
|
351
|
+
**Core props:** `active`.
|
|
352
|
+
|
|
353
|
+
**Minimal example:**
|
|
354
|
+
|
|
355
|
+
```tsx
|
|
356
|
+
<Overlay margin={{ x: 2, y: 2 }} trapFocus><FocusScope><Input id="query" /><List id="commands" items={commands} /></FocusScope></Overlay>
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
**Complete demo:** [`examples/docs/primitive-command-panel.tsx`](../examples/docs/primitive-command-panel.tsx). Run it with `bun examples/docs/primitive-command-panel.tsx` and quit with `Ctrl+C`.
|
|
360
|
+
|
|
361
|
+
## Primitive map
|
|
362
|
+
|
|
363
|
+
- Shell: `Screen`, `Text`.
|
|
364
|
+
- Layout: `Box`, `View`, `Pane`, `Split`, `Fixed`.
|
|
365
|
+
- Input: `Input`, `Editor`, `Button`, `FocusScope`.
|
|
366
|
+
- Collections: `List`, `Table`, `Row`, `Td`.
|
|
367
|
+
- Activity: `ScrollView`, `LogView`.
|
|
368
|
+
- Layers: `Overlay`, `FocusScope`.
|
|
369
|
+
|
|
370
|
+
Start with a shell, divide the screen into layout regions, add input or navigation, then layer focused panels when a local task needs priority. Use API Reference for prop-level details: [`docs/api-reference.md`](./api-reference.md).
|