@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
package/docs/api-reference.md
CHANGED
|
@@ -1,273 +1,444 @@
|
|
|
1
1
|
# API Reference
|
|
2
2
|
|
|
3
|
-
Reference for the
|
|
3
|
+
Reference for the public surface published by `@valyrianjs/terminal`. For a guided first project, start with [Getting Started](./getting-started.md). For practical primitive selection, use [Primitive Gallery](./primitive-gallery.md).
|
|
4
4
|
|
|
5
|
-
## Published
|
|
5
|
+
## Published entrypoints
|
|
6
6
|
|
|
7
|
-
###
|
|
7
|
+
### `@valyrianjs/terminal`
|
|
8
8
|
|
|
9
|
-
Main entrypoint
|
|
9
|
+
Main entrypoint for terminal primitives, rendering, sessions, props, payloads, and types.
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
- `mountTerminal()`
|
|
13
|
-
- primitives `Screen`, `Box`, `View`, `Text`, `Input`, `Button`, `ScrollView`, `List`, `Table`, `Row`, `Td`
|
|
14
|
-
- prop, event, node, and session types
|
|
11
|
+
Common imports:
|
|
15
12
|
|
|
16
|
-
|
|
13
|
+
```tsx
|
|
14
|
+
import { Screen, Text, mountTerminal, renderTerminal } from "@valyrianjs/terminal";
|
|
15
|
+
```
|
|
17
16
|
|
|
18
|
-
|
|
17
|
+
### `@valyrianjs/terminal/render`
|
|
19
18
|
|
|
20
|
-
-
|
|
21
|
-
- `renderTerminalNode(node): string`
|
|
22
|
-
- `renderTerminalFrame(node): TerminalFrame`
|
|
19
|
+
Rendering-only subpath for lower-level rendering utilities:
|
|
23
20
|
|
|
24
|
-
|
|
21
|
+
- `renderTerminal(input, context?): string`
|
|
22
|
+
- `renderTerminalNode(node, context?): string`
|
|
23
|
+
- `renderTerminalFrame(node, context?): TerminalFrame`
|
|
25
24
|
|
|
26
|
-
|
|
25
|
+
Use this subpath for rendering-focused integrations that produce output without mounting an interactive session.
|
|
27
26
|
|
|
28
|
-
|
|
27
|
+
## Root exports overview
|
|
29
28
|
|
|
30
|
-
|
|
29
|
+
The root entrypoint exports the public primitives (`Screen`, `Box`, `View`, `Pane`, `Split`, `Fixed`, `Overlay`, `FocusScope`, `Text`, `Input`, `Editor`, `Button`, `List`, `ScrollView`, `LogView`, `Table`, `Row`, and `Td`), the main functions `renderTerminal()` and `mountTerminal()`, public prop and payload types, keymap helpers, and theme helpers.
|
|
31
30
|
|
|
32
|
-
|
|
31
|
+
## Main functions
|
|
33
32
|
|
|
34
|
-
|
|
35
|
-
- layout validation without `stdin` or `stdout`
|
|
36
|
-
- content inspection in non-interactive mode
|
|
33
|
+
### `renderTerminal(input, context?): string`
|
|
37
34
|
|
|
38
|
-
|
|
35
|
+
Resolves the provided terminal tree and returns plain text. Pass `{ cols, rows }` when the root tree uses viewport-dependent primitives such as standalone `Overlay` with `margin` or standalone `Fixed`.
|
|
39
36
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
-
|
|
37
|
+
Use it for:
|
|
38
|
+
|
|
39
|
+
- snapshots
|
|
40
|
+
- static examples
|
|
41
|
+
- non-interactive command output
|
|
42
|
+
- layout checks without session state
|
|
43
|
+
|
|
44
|
+
`context` accepts exact terminal dimensions as positive integers and an optional theme: `{ cols, rows, theme? }`. Mounted sessions infer dimensions from `mountTerminal()` options or the host terminal.
|
|
43
45
|
|
|
44
46
|
### `mountTerminal(input, options?): TerminalSession`
|
|
45
47
|
|
|
46
|
-
|
|
48
|
+
Creates an interactive session around a terminal tree.
|
|
47
49
|
|
|
48
|
-
|
|
50
|
+
The session can:
|
|
49
51
|
|
|
50
|
-
-
|
|
51
|
-
-
|
|
52
|
-
-
|
|
53
|
-
-
|
|
54
|
-
-
|
|
52
|
+
- rerender with `update()`
|
|
53
|
+
- preserve and move focus
|
|
54
|
+
- dispatch keyboard input
|
|
55
|
+
- handle mouse and coordinate interaction
|
|
56
|
+
- use clipboard integration
|
|
57
|
+
- write ANSI diffs to `stdout` in app runtime
|
|
58
|
+
- clean up connected streams with `destroy()`
|
|
55
59
|
|
|
56
60
|
## `TerminalMountOptions`
|
|
57
61
|
|
|
58
|
-
- `
|
|
59
|
-
- `
|
|
60
|
-
- `
|
|
61
|
-
- `
|
|
62
|
+
- `runtime?: "app" | "headless"` - selects real app output or scriptable plain output. Omitted runtime becomes app mode for interactive TTY hosts and headless in non-TTY/CI contexts.
|
|
63
|
+
- `alternateScreen?: boolean` - enters alternate screen mode and restores it on destroy by default. Real interactive app mode enables it by default unless overridden.
|
|
64
|
+
- `hideCursor?: boolean` - hides the terminal cursor and restores it on destroy by default. Real interactive app mode enables it by default unless overridden.
|
|
65
|
+
- `restoreOnDestroy?: boolean` - controls restore behavior for cursor and alternate screen state.
|
|
66
|
+
- `clipboard?: TerminalClipboardAdapter | false` - custom clipboard adapter or disabled external clipboard integration.
|
|
67
|
+
- `cols?: number` - initial terminal width in columns.
|
|
68
|
+
- `rows?: number` - initial terminal height in rows.
|
|
69
|
+
- `stdin?` - input stream with `on("data")`; cleanup and raw-mode methods are optional.
|
|
70
|
+
- `stdout?` - output stream with `write(chunk)`; optional dimensions, resize events, and drain events are used when supported.
|
|
71
|
+
- `theme?` - terminal theme for semantic style spans.
|
|
72
|
+
- `keymap?` - custom key bindings for built-in terminal interaction behavior.
|
|
73
|
+
|
|
74
|
+
If no explicit dimensions or stream dimensions are available, sessions default to `80x24`. Dimensions must be positive integers.
|
|
75
|
+
|
|
76
|
+
`hideCursor` and `restoreOnDestroy` describe cursor and terminal-restore intent for sessions connected to compatible hosts. Cursor restore follows the connected terminal and stream capabilities. Run `bun examples/docs/cursor.tsx`, type text, press `C`, and quit with `Ctrl+C`; or open [`examples/docs/cursor.tsx`](../examples/docs/cursor.tsx).
|
|
77
|
+
|
|
78
|
+
## Keymap helpers
|
|
79
|
+
|
|
80
|
+
- `defaultTerminalKeyBindings` - built-in key bindings for focus traversal, editing, lists, buttons, and scroll views.
|
|
81
|
+
- `createTerminalKeyBindings(bindings?)` - returns a normalized binding list that can extend or replace default behavior.
|
|
82
|
+
- `createResolvedTerminalKeymap(options?)` - creates a keymap object used by sessions.
|
|
83
|
+
- `resolveTerminalKeyBinding(key, context, keymap)` - resolves a normalized key against a context.
|
|
84
|
+
- `validateTerminalKeyBindings(bindings)` - validates key binding shape and rejects ambiguous entries.
|
|
85
|
+
|
|
86
|
+
Use `keymap` in `TerminalMountOptions` when an app needs custom keyboard behavior while keeping predictable focus and primitive events.
|
|
87
|
+
|
|
88
|
+
## Theme helpers
|
|
89
|
+
|
|
90
|
+
- `defaultTerminalTheme` - bundled app-like recipes for common controls.
|
|
91
|
+
- `highContrastTerminalTheme` - alternate recipes with stronger contrast.
|
|
92
|
+
- `mergeTerminalTheme(base, override)` - combines theme recipes and span tokens.
|
|
93
|
+
- `resolveTerminalStyle(style, theme?)` - resolves dot path recipes or inline style objects.
|
|
94
|
+
- `resolveTerminalStyleToken(kind, theme?)` - resolves semantic span tokens for ANSI/plain serialization.
|
|
95
|
+
|
|
96
|
+
Theme recipes belong in `theme.styles`. Use `color`, `background`, padding, and border values with hex colors for normal app styling.
|
|
97
|
+
|
|
98
|
+
## Visual style system
|
|
99
|
+
|
|
100
|
+
`theme.styles` stores named style recipes. A recipe may define color, background, padding, border, and nested visual-state recipes. The renderer applies `theme.styles.<element>.base` automatically to public primitives that have a matching `.base` recipe, before any instance `style`. The bundled default theme uses that rule for app-like core controls such as `button.base`, `button.focus`, `input.base`, `input.focus`, `input.selection`, `list.base`, `list.current`, `list.selected`, `list.hover`, and `list.empty`. Components also resolve recipes by dot path, so `style="panel.queue"` reads `theme.styles.panel.queue`. Inline style objects work too when the style belongs to one component instance.
|
|
101
|
+
|
|
102
|
+
Use `style`, `styles`, and `state` for normal component styling:
|
|
103
|
+
|
|
104
|
+
- `style` sets the base recipe or inline style for the component frame.
|
|
105
|
+
- `styles` maps visual states to dot path recipes or inline style objects.
|
|
106
|
+
- `state` declares app-owned states such as `loading`, `warning`, `success`, `muted`, `expanded`, or `dropTarget`.
|
|
107
|
+
|
|
108
|
+
Renderer-owned states come from the runtime when the renderer has the fact itself. Focus, hover, selection, current rows, and pointer capture fall in this group when the primitive supports them. App-owned state should describe product state that the app already knows. Do not mark a ready button as `loading` or an editable field as `readonly`; that teaches a lie to the UI and then the UI repeats it with confidence.
|
|
109
|
+
|
|
110
|
+
Precedence: the renderer starts with the automatic `<element>.base` recipe when the primitive has one, applies the instance `style`, then applies `styles` entries for current states in stable visual-state order. Geometry fields such as supported padding and border come from the automatic base recipe plus the instance `style` so layout, hitboxes, and cursors stay stable across focus, hover, and pressed state changes. State styles affect the rendered spans after layout; later current states override earlier visual fields when they set the same property. Inline style objects and dot path recipes use the same merge path after resolution.
|
|
111
|
+
|
|
112
|
+
Renderer notes:
|
|
113
|
+
|
|
114
|
+
- Raw ANSI escape control is not the normal public styling API. Use semantic styles and let `ansiOutput()` serialize frames.
|
|
115
|
+
- Layout margin is not supported; use padding, `gap`, `Fixed`, `Split`, or explicit text spacing.
|
|
116
|
+
- The renderer owns terminal frame spans, clipping, focus, and selection; the app owns business state and labels.
|
|
117
|
+
|
|
118
|
+
Run `bun examples/docs/style-system.tsx`, try `Tab`, `Enter`, and `W`, and quit with `Ctrl+C`; or open [`examples/docs/style-system.tsx`](../examples/docs/style-system.tsx). Run `bun examples/docs/theme-colors.tsx`, press `Tab`, and quit with `Ctrl+C`; or open [`examples/docs/theme-colors.tsx`](../examples/docs/theme-colors.tsx).
|
|
119
|
+
|
|
120
|
+
### TerminalStyleSpan
|
|
121
|
+
|
|
122
|
+
`TerminalStyleSpan` is a low-level frame API for renderer integrations and frame serialization. It describes a styled range in a rendered frame and may carry `kind`, coordinates, and `style?` when the renderer resolves an inline style object. App components get their everyday styling surface from semantic styles.
|
|
123
|
+
|
|
124
|
+
Use `style`, `styles`, and `state` for component styling. Use `TerminalStyleSpan` when a low-level frame integration needs styled ranges after render.
|
|
125
|
+
|
|
126
|
+
### Advanced: span serialization tokens
|
|
127
|
+
|
|
128
|
+
`ansiOpen`, `ansiClose`, `plainPrefix`, and `plainSuffix` are low-level fields for trusted renderer integrations that already own frame spans and need exact serialization behavior. Application components get their styling API from semantic styles.
|
|
129
|
+
|
|
130
|
+
Apps should prefer `theme.styles`, `style`, `styles`, `state`, `color`, `background`, and hex colors. Those fields keep styling semantic, portable, and safe for both `output()` and `ansiOutput()`. When a token defines `color`, `background`, or `style`, ANSI serialization uses the resolved style fields before raw ANSI fallback tokens.
|
|
131
|
+
|
|
132
|
+
Token behavior:
|
|
133
|
+
|
|
134
|
+
- `ansiOpen` writes a raw ANSI opening sequence around the span in ANSI output when no `color`, `background`, or `style` field supplies a safer style.
|
|
135
|
+
- `ansiClose` writes the matching raw ANSI close sequence in ANSI output for the same low-level case.
|
|
136
|
+
- `plainPrefix` adds text before the span only in plain output.
|
|
137
|
+
- `plainSuffix` adds text after the span only in plain output.
|
|
138
|
+
|
|
139
|
+
Prefer semantic styles first: `theme.styles`, `style`, `styles`, `state`, hex `color`, and `background` keep output portable across plain and ANSI render paths. Use raw ANSI tokens for trusted low-level integrations that own frame serialization. Keep token input trusted, pair open and close tokens exactly, verify both `output()` and `ansiOutput()`, and document the integration reason when semantic hex style does not cover the serialization requirement.
|
|
140
|
+
|
|
141
|
+
## Layout primitives
|
|
142
|
+
|
|
143
|
+
Use [Primitive Gallery](./primitive-gallery.md) for practical composition examples, including [`examples/docs/primitive-layout-shell.tsx`](../examples/docs/primitive-layout-shell.tsx), [`examples/docs/primitive-input-workbench.tsx`](../examples/docs/primitive-input-workbench.tsx), [`examples/docs/primitive-data-explorer.tsx`](../examples/docs/primitive-data-explorer.tsx), [`examples/docs/primitive-activity-console.tsx`](../examples/docs/primitive-activity-console.tsx), and [`examples/docs/primitive-command-panel.tsx`](../examples/docs/primitive-command-panel.tsx). Run them with `bun examples/docs/primitive-layout-shell.tsx`, `bun examples/docs/primitive-input-workbench.tsx`, `bun examples/docs/primitive-data-explorer.tsx`, `bun examples/docs/primitive-activity-console.tsx`, or `bun examples/docs/primitive-command-panel.tsx`; quit with `Ctrl+C`. Use API Reference for prop-level details.
|
|
62
144
|
|
|
63
|
-
## Layout Primitives
|
|
64
145
|
|
|
65
146
|
### `Screen`
|
|
66
147
|
|
|
67
|
-
|
|
148
|
+
Props:
|
|
68
149
|
|
|
69
150
|
- `title?: string`
|
|
70
151
|
|
|
71
|
-
|
|
152
|
+
Root container. If `title` is present, it renders as the first line. In a mounted session or render call with dimensions, `Screen` passes the available viewport context to children.
|
|
72
153
|
|
|
73
154
|
### `Box`
|
|
74
155
|
|
|
75
|
-
|
|
156
|
+
Props:
|
|
76
157
|
|
|
77
158
|
- `direction?: "row" | "column"`
|
|
78
159
|
- `gap?: number`
|
|
79
|
-
- `padding?: number`
|
|
80
|
-
- `
|
|
160
|
+
- `padding?: number | { x?: number; y?: number; top?: number; right?: number; bottom?: number; left?: number }`
|
|
161
|
+
- `style?: string | TerminalStyleDefinition`
|
|
162
|
+
- `styles?: Partial<Record<TerminalVisualState, string | TerminalStyleDefinition>>`
|
|
163
|
+
- `state?: TerminalVisualState | TerminalVisualState[]`
|
|
81
164
|
- `width?: number`
|
|
82
165
|
- `height?: number`
|
|
166
|
+
- `fill?: boolean`
|
|
83
167
|
- `id?: string`
|
|
84
168
|
- `focusable?: boolean`
|
|
85
169
|
|
|
86
|
-
|
|
170
|
+
Layout container. `Box`, `View`, and `Pane` behave like block elements in a sized context: they use available width by default and keep content height by default, so stacked containers do not all become full-height. Numeric dimensions constrain the final frame and explicit `width` or `height` wins over context defaults. Use `fill` when a surface should consume the full available height as well as width. Put background fill, border, and padding in `style` or a `theme.styles` recipe. Margin is not supported; compose spacing with layout, padding, and explicit text when needed.
|
|
87
171
|
|
|
88
172
|
### `View`
|
|
89
173
|
|
|
90
|
-
`
|
|
174
|
+
Props: layout props from `Box`, plus `role?: string`.
|
|
91
175
|
|
|
92
|
-
|
|
93
|
-
- `role?: string`
|
|
176
|
+
Semantic layout container with the same sizing behavior as `Box`.
|
|
94
177
|
|
|
95
|
-
|
|
178
|
+
### `Pane`
|
|
96
179
|
|
|
97
|
-
|
|
180
|
+
Props: layout props from `Box`.
|
|
98
181
|
|
|
99
|
-
|
|
182
|
+
Named layout boundary for composing terminal regions.
|
|
100
183
|
|
|
101
|
-
|
|
184
|
+
### `Split`
|
|
185
|
+
|
|
186
|
+
Props:
|
|
187
|
+
|
|
188
|
+
- `direction?: "row" | "column"`
|
|
189
|
+
- `width?: number`
|
|
190
|
+
- `height?: number`
|
|
191
|
+
- `fill?: boolean`
|
|
192
|
+
- `sizes?: Array<number | `${number}%` | `${number}fr`>`
|
|
193
|
+
- `breakpoints?: Array<{ maxCols?: number; maxRows?: number; direction?: "row" | "column"; sizes?: TerminalSplitSize[]; gap?: number }>`
|
|
194
|
+
- `gap?: number`
|
|
195
|
+
- `id?: string`
|
|
196
|
+
- `focusable?: boolean`
|
|
197
|
+
|
|
198
|
+
Split layout. Split uses the available render area when width and height are omitted inside a sized context. In `row`, it divides width; in `column`, it divides height. `sizes` may mix absolute numbers, percentages, and `fr` units. Percentages and fractions use the available axis after gaps. Rounding is deterministic: floor the ideal sizes, then give remaining cells to the largest fractional remainders with index order as the tie breaker. Breakpoints are local to the resolved split width and height, and the first matching breakpoint wins. Run `bun examples/docs/responsive-split.tsx`, resize the terminal to change the layout, and quit with `Ctrl+C`; or open [`examples/docs/responsive-split.tsx`](../examples/docs/responsive-split.tsx).
|
|
199
|
+
|
|
200
|
+
## Visual states
|
|
201
|
+
|
|
202
|
+
State families:
|
|
203
|
+
|
|
204
|
+
| Family | States |
|
|
205
|
+
| --- | --- |
|
|
206
|
+
| Common | `focus`, `hover`, `disabled`, `loading` |
|
|
207
|
+
| Activation/controls | `pressed`, `checked`, `unchecked`, `indeterminate` |
|
|
208
|
+
| Selection/navigation | `selected`, `current`, `expanded`, `collapsed` |
|
|
209
|
+
| Entry/text | `invalid`, `valid`, `readonly`, `placeholder`, `selection`, `editing`, `submitted` |
|
|
210
|
+
| Data/content | `empty`, `error`, `warning`, `success`, `muted` |
|
|
211
|
+
| Pointer/capture/composition | `dragging`, `dropTarget`, `capturing` |
|
|
212
|
+
|
|
213
|
+
Buttons, inputs, editors, lists, tables, panes, boxes, overlays, scroll views, log views, and text can use `style`, `styles`, and `state` where the style affects their rendered frame. Use renderer-owned states such as focus or selection when the component knows them, and use `state` for app-owned statuses such as loading, warning, success, dragging, or drop target.
|
|
102
214
|
|
|
103
|
-
|
|
215
|
+
Shared visual props for styled primitives:
|
|
104
216
|
|
|
105
|
-
|
|
217
|
+
- `style?: string | TerminalStyleDefinition` - base style recipe or inline style.
|
|
218
|
+
- `styles?: Partial<Record<TerminalVisualState, string | TerminalStyleDefinition>>` - visual-state style map.
|
|
219
|
+
- `state?: TerminalVisualState | TerminalVisualState[]` - app-owned visual state or states.
|
|
106
220
|
|
|
107
|
-
`
|
|
221
|
+
### `Fixed`
|
|
108
222
|
|
|
109
|
-
|
|
223
|
+
Props:
|
|
110
224
|
|
|
111
|
-
|
|
225
|
+
- `position: "top" | "bottom" | "left" | "right"`
|
|
226
|
+
- `size: number`
|
|
112
227
|
|
|
113
|
-
|
|
228
|
+
Reserves stable rows or columns at a frame edge. When `Fixed` is a direct child of `Screen` or `Pane`, that parent supplies the frame and consumes the fixed region before it lays out the remaining content. When `Fixed` is rendered as the root tree passed directly to `renderTerminal()`, it is viewport-dependent and the render call must pass exact dimensions with `{ cols, rows }`. Mounted sessions get those dimensions from `mountTerminal()` options or the host terminal.
|
|
114
229
|
|
|
115
|
-
`
|
|
230
|
+
### `Overlay`
|
|
116
231
|
|
|
117
|
-
|
|
232
|
+
Props:
|
|
118
233
|
|
|
119
|
-
|
|
234
|
+
- `margin: number | "<number>%" | { x: number | "<number>%"; y: number | "<number>%" }`
|
|
235
|
+
- shared visual props: `style`, `styles`, `state`
|
|
236
|
+
- `trapFocus?: boolean`
|
|
237
|
+
- `id?: string`
|
|
238
|
+
- `focusable?: boolean`
|
|
239
|
+
|
|
240
|
+
Draws a clipped region over the current frame. `margin` sets the distance from the overlay to the frame edges; numbers use cells and percentage strings such as `"10%"` resolve per axis. Use `{ x, y }` when the two axes need different margins. `trapFocus` keeps traversal inside the overlay while it is active.
|
|
241
|
+
|
|
242
|
+
Overlay calculates its size from the available frame, stays centered by its margins, and keeps app routing and pane movement in your app layer.
|
|
243
|
+
|
|
244
|
+
### `FocusScope`
|
|
245
|
+
|
|
246
|
+
Props:
|
|
120
247
|
|
|
121
|
-
|
|
248
|
+
- `active?: boolean`
|
|
122
249
|
|
|
123
|
-
|
|
250
|
+
Bounds sequential focus traversal to descendants when focus is already inside the scope.
|
|
124
251
|
|
|
125
|
-
|
|
252
|
+
### `Text`
|
|
253
|
+
|
|
254
|
+
Props:
|
|
255
|
+
|
|
256
|
+
- `value?: any`
|
|
257
|
+
- shared visual props: `style`, `styles`, `state`
|
|
258
|
+
|
|
259
|
+
Renders `value` or child text. Line breaks are preserved.
|
|
126
260
|
|
|
127
|
-
|
|
261
|
+
### `Table`, `Row`, and `Td`
|
|
128
262
|
|
|
129
|
-
|
|
263
|
+
`Table` composes rows and calculates column widths. `Row` joins cells with `separator?: string`. `Td` supports `padding?: number` and shared visual props: `style`, `styles`, `state`.
|
|
130
264
|
|
|
131
|
-
|
|
265
|
+
## Interactive primitives
|
|
132
266
|
|
|
133
267
|
### `Input`
|
|
134
268
|
|
|
135
|
-
|
|
269
|
+
Props:
|
|
136
270
|
|
|
137
271
|
- `id?: string`
|
|
138
272
|
- `focusable?: boolean`
|
|
139
273
|
- `value?: string`
|
|
140
274
|
- `placeholder?: string`
|
|
275
|
+
- shared visual props: `style`, `styles`, `state`
|
|
141
276
|
- `onchange?(event)`
|
|
142
277
|
- `oninput?(event)`
|
|
143
278
|
- `onsubmit?(event)`
|
|
144
|
-
- `
|
|
145
|
-
|
|
146
|
-
Current interaction support:
|
|
279
|
+
- `oncontextpress?(event)`
|
|
147
280
|
|
|
148
|
-
|
|
149
|
-
- `LEFT`, `RIGHT`, `SHIFT_LEFT`, `SHIFT_RIGHT`
|
|
150
|
-
- `ALT_LEFT`, `ALT_RIGHT`, `HOME`, `END`
|
|
151
|
-
- `CTRL_A`, `CTRL_C`, `CTRL_X`, `CTRL_V`
|
|
152
|
-
- `BACKSPACE`, `DELETE`, character input, and `ENTER`
|
|
153
|
-
|
|
154
|
-
Important payloads:
|
|
281
|
+
Payloads:
|
|
155
282
|
|
|
156
283
|
- `TerminalInputChangeEventPayload` - `{ type: "change" | "input", id, value }`
|
|
157
284
|
- `TerminalInputSubmitEventPayload` - `{ type: "submit", id, value }`
|
|
285
|
+
- `TerminalInputContextPressEventPayload` - `{ type: "contextpress", id, value, cursor, x, y }`
|
|
286
|
+
|
|
287
|
+
Supports single-line editing, cursor movement, selection, copy/cut/paste, deletion, submit, and context press.
|
|
288
|
+
|
|
289
|
+
### `Editor`
|
|
290
|
+
|
|
291
|
+
Props:
|
|
292
|
+
|
|
293
|
+
- `id?: string`
|
|
294
|
+
- `focusable?: boolean`
|
|
295
|
+
- `value?: string`
|
|
296
|
+
- `placeholder?: string`
|
|
297
|
+
- `height?: number`
|
|
298
|
+
- shared visual props: `style`, `styles`, `state`
|
|
299
|
+
- `onchange?(event)`
|
|
300
|
+
- `oninput?(event)`
|
|
301
|
+
- `onsubmit?(event)`
|
|
302
|
+
- `oncancel?(event)`
|
|
303
|
+
|
|
304
|
+
Payloads:
|
|
305
|
+
|
|
306
|
+
- `TerminalEditorChangeEventPayload` - `{ type: "change" | "input", id, value }`
|
|
307
|
+
- `TerminalEditorSubmitEventPayload` - `{ type: "submit", id, value }`
|
|
308
|
+
- `TerminalEditorCancelEventPayload` - `{ type: "cancel", id, value }`
|
|
309
|
+
|
|
310
|
+
Supports multiline editing, submit, cancel, cursor movement, paste, and deletion. Cursor columns use JavaScript string columns rather than a complete terminal-width model.
|
|
158
311
|
|
|
159
312
|
### `Button`
|
|
160
313
|
|
|
161
|
-
|
|
314
|
+
Props:
|
|
162
315
|
|
|
163
316
|
- `id?: string`
|
|
164
317
|
- `focusable?: boolean`
|
|
165
318
|
- `label?: string`
|
|
319
|
+
- shared visual props: `style`, `styles`, `state`
|
|
166
320
|
- `onpress?(event)`
|
|
167
|
-
- `
|
|
168
|
-
- `
|
|
169
|
-
- `onPress?(event)`
|
|
170
|
-
|
|
171
|
-
Current activation paths:
|
|
321
|
+
- `ondoublepress?(event)`
|
|
322
|
+
- `oncontextpress?(event)`
|
|
172
323
|
|
|
173
|
-
|
|
174
|
-
- `session.clickAt(x, y)`
|
|
175
|
-
- `dispatchKey("ENTER")` or `dispatchKey("SPACE")` when focus is on the button
|
|
324
|
+
Payload:
|
|
176
325
|
|
|
177
|
-
|
|
326
|
+
- `TerminalButtonPressEventPayload` - `{ type: "press" | "doublepress" | "contextpress", id }`
|
|
178
327
|
|
|
179
|
-
|
|
328
|
+
Activation paths include focused `ENTER`, focused `SPACE`, `session.click(id)`, and `session.clickAt(x, y)`. A quick second primary mouse press still dispatches the normal activation path and also dispatches `ondoublepress` when present. A secondary mouse press dispatches `oncontextpress`.
|
|
180
329
|
|
|
181
330
|
### `List<T>`
|
|
182
331
|
|
|
183
|
-
|
|
332
|
+
Props:
|
|
184
333
|
|
|
185
334
|
- `id?: string`
|
|
186
335
|
- `focusable?: boolean`
|
|
187
336
|
- `pointerCapture?: boolean`
|
|
188
337
|
- `items?: T[]`
|
|
338
|
+
- `virtualized?: boolean`
|
|
339
|
+
- `itemHeight?: 1`
|
|
340
|
+
- `overscan?: number`
|
|
341
|
+
- shared visual props: `style`, `styles`, `state`
|
|
189
342
|
- `renderItem?(item, index): string`
|
|
190
343
|
- `onchange?(event)`
|
|
191
344
|
- `onpress?(event)`
|
|
345
|
+
- `ondoublepress?(event)`
|
|
346
|
+
- `oncontextpress?(event)`
|
|
192
347
|
- `onhover?(event)`
|
|
193
348
|
- `onrowenter?(event)`
|
|
194
349
|
- `onrowleave?(event)`
|
|
195
350
|
- `oncapturestart?(event)`
|
|
196
351
|
- `oncaptureend?(event)`
|
|
197
352
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
- `UP` and `LEFT` move selection up
|
|
201
|
-
- `DOWN` and `RIGHT` move selection down
|
|
202
|
-
- `ENTER` triggers `onpress`
|
|
203
|
-
- mouse hover exposes row, index, and value
|
|
204
|
-
|
|
205
|
-
Important payloads:
|
|
353
|
+
Payloads:
|
|
206
354
|
|
|
207
355
|
- `TerminalListChangeEventPayload<T>` - `{ type: "change", id, index, value }`
|
|
208
|
-
- `TerminalListPressEventPayload<T>` - `{ type: "press", id, index, value }`
|
|
356
|
+
- `TerminalListPressEventPayload<T>` - `{ type: "press" | "doublepress" | "contextpress", id, index, value }`
|
|
209
357
|
- `TerminalListPointerEventPayload<T>` - `{ type: "hover" | "rowenter" | "rowleave", id, row, index, value, x, y }`
|
|
210
358
|
- `TerminalCaptureEventPayload` - `{ type: "capturestart" | "captureend", id, source, row, x, y }`
|
|
211
359
|
|
|
360
|
+
Supports selection, activation, double press on the same row, context press for the target row, hover payloads, optional virtualization, and pointer capture.
|
|
361
|
+
|
|
212
362
|
### `ScrollView`
|
|
213
363
|
|
|
214
|
-
|
|
364
|
+
Props:
|
|
215
365
|
|
|
216
|
-
- layout props
|
|
366
|
+
- layout props: `direction`, `gap`, `padding`, `width`, `height`, `fill`, `id`, `focusable`, `style`, `styles`, `state`
|
|
217
367
|
- `pointerCapture?: boolean`
|
|
218
368
|
- `highlightRows?: number[]`
|
|
219
369
|
- `onhover?(event)`
|
|
220
370
|
- `onrowenter?(event)`
|
|
221
371
|
- `onrowleave?(event)`
|
|
372
|
+
- `oncontextpress?(event)`
|
|
222
373
|
- `oncapturestart?(event)`
|
|
223
374
|
- `oncaptureend?(event)`
|
|
224
375
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
- `UP` and `DOWN` adjust the vertical offset when it has focus
|
|
228
|
-
- rendering clips visible content based on `height`
|
|
229
|
-
- `highlightRows` marks specific visible rows
|
|
230
|
-
- mouse hover exposes the visible row and rendered text
|
|
231
|
-
|
|
232
|
-
Important payloads:
|
|
376
|
+
Payloads:
|
|
233
377
|
|
|
234
378
|
- `TerminalScrollPointerEventPayload` - `{ type: "hover" | "rowenter" | "rowleave", id, row, value, x, y }`
|
|
379
|
+
- `TerminalScrollContextPressEventPayload` - `{ type: "contextpress", id, row, value, x, y }`
|
|
235
380
|
- `TerminalCaptureEventPayload` - `{ type: "capturestart" | "captureend", id, source, row, x, y }`
|
|
236
381
|
|
|
382
|
+
Clips vertical content and supports keyboard scrolling, highlighted rows, hover payloads, context press for the target visible row, and pointer capture.
|
|
383
|
+
|
|
384
|
+
### `LogView`
|
|
385
|
+
|
|
386
|
+
Props:
|
|
387
|
+
|
|
388
|
+
- layout props: `direction`, `gap`, `padding`, `width`, `height`, `fill`, `id`, `focusable`, `style`, `styles`, `state`
|
|
389
|
+
- `entries?: readonly TerminalLogViewEntry[]`
|
|
390
|
+
- `followTail?: boolean`
|
|
391
|
+
- `emptyText?: string`
|
|
392
|
+
- `renderEntry?(entry, index): string`
|
|
393
|
+
|
|
394
|
+
Entry shape:
|
|
395
|
+
|
|
396
|
+
- `TerminalLogViewEntry` - `{ id: string, content: string }`
|
|
397
|
+
|
|
398
|
+
Renders append-only logs and transcript-like panes. `followTail` keeps the visible frame at the bottom of the rendered entries. Use `followTail` as the `LogView` option for bottom-pinned transcript views while log storage and export stay in the app layer.
|
|
399
|
+
|
|
400
|
+
## Render subpath exports
|
|
401
|
+
|
|
402
|
+
The `@valyrianjs/terminal/render` subpath exports:
|
|
403
|
+
|
|
404
|
+
- `renderTerminal(input, context?): string`
|
|
405
|
+
- `renderTerminalNode(node, context?): string`
|
|
406
|
+
- `renderTerminalFrame(node, context?): TerminalFrame`
|
|
407
|
+
|
|
408
|
+
These functions are useful for render-only integrations that should not import session runtime helpers.
|
|
409
|
+
|
|
237
410
|
## `TerminalSession`
|
|
238
411
|
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
- `update(): string` -
|
|
242
|
-
- `output(): string` - returns the
|
|
243
|
-
- `ansiOutput(): string` - returns the current frame
|
|
244
|
-
- `tree(): TerminalNode[]` -
|
|
245
|
-
- `focus(id: string): boolean` - focuses
|
|
246
|
-
- `focusAt(x: number, y: number): boolean` - focuses by
|
|
247
|
-
- `focusNext(): boolean` - moves focus forward
|
|
248
|
-
- `focusPrev(): boolean` - moves focus backward
|
|
249
|
-
- `dispatchKey(key: string): string` -
|
|
250
|
-
- `click(id?: string): string` - activates the focused button or a
|
|
251
|
-
- `clickAt(x: number, y: number): string` - activates or focuses
|
|
252
|
-
- `clipboard(): string` - returns the
|
|
253
|
-
- `setClipboard(value: string): string` - updates the
|
|
254
|
-
- `selectAll(): string` - selects all content in the focused `Input
|
|
255
|
-
- `destroy(): void` - removes
|
|
256
|
-
|
|
257
|
-
##
|
|
258
|
-
|
|
259
|
-
-
|
|
260
|
-
-
|
|
261
|
-
-
|
|
262
|
-
-
|
|
263
|
-
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
-
|
|
268
|
-
-
|
|
269
|
-
-
|
|
270
|
-
-
|
|
271
|
-
-
|
|
272
|
-
- `TerminalMouseEventType` - `"hover" | "rowenter" | "rowleave"`
|
|
273
|
-
- `TerminalPointerSource` - `"press" | "drag" | "release"`
|
|
412
|
+
- `size(): TerminalSize` - returns `{ cols, rows }`.
|
|
413
|
+
- `resize(cols: number, rows: number): void` - validates and stores a new size, then rerenders.
|
|
414
|
+
- `update(): string` - rerenders and returns plain text.
|
|
415
|
+
- `output(): string` - returns the current plain-text frame.
|
|
416
|
+
- `ansiOutput(): string` - returns the current ANSI frame.
|
|
417
|
+
- `tree(): TerminalNode[]` - returns the current resolved terminal tree.
|
|
418
|
+
- `focus(id: string): boolean` - focuses a node by id.
|
|
419
|
+
- `focusAt(x: number, y: number): boolean` - focuses by coordinates.
|
|
420
|
+
- `focusNext(): boolean` - moves focus forward.
|
|
421
|
+
- `focusPrev(): boolean` - moves focus backward.
|
|
422
|
+
- `dispatchKey(key: string): string` - dispatches a normalized key and returns plain text.
|
|
423
|
+
- `click(id?: string): string` - activates the focused button or a button by id.
|
|
424
|
+
- `clickAt(x: number, y: number): string` - activates or focuses by coordinates.
|
|
425
|
+
- `clipboard(): string` - returns the session clipboard buffer.
|
|
426
|
+
- `setClipboard(value: string): string` - updates the session clipboard buffer and adapter when present.
|
|
427
|
+
- `selectAll(): string` - selects all content in the focused `Input`.
|
|
428
|
+
- `destroy(): void` - removes listeners and restores supported terminal state.
|
|
429
|
+
|
|
430
|
+
## Package scope
|
|
431
|
+
|
|
432
|
+
- Use the package for terminal primitives, rendering, sessions, focus, input, and output.
|
|
433
|
+
- Compose command-palette surfaces with `Overlay`, `FocusScope`, `Input`, `List`, and `Button`.
|
|
434
|
+
- Keep log storage, export, routing, and business rules in your app layer.
|
|
435
|
+
- Use semantic text and styles for rendered content; reserve terminal escape control for documented integration paths.
|
|
436
|
+
- Host features such as resize, mouse input, and modified keys follow the terminal/runtime environment.
|
|
437
|
+
|
|
438
|
+
## Related docs
|
|
439
|
+
|
|
440
|
+
- [Getting Started](./getting-started.md) for the first project.
|
|
441
|
+
- [Core Concepts](./core-concepts.md) for the mental model.
|
|
442
|
+
- [Cookbook](./cookbook.md) for practical recipes.
|
|
443
|
+
- [Interaction Model](./interaction-model.md) for behavior by primitive.
|
|
444
|
+
- [Session Runtime](./session-runtime.md) for host integration.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="640" height="220" viewBox="0 0 640 220" role="img" aria-labelledby="title desc">
|
|
2
|
+
<title id="title">Quick note terminal result</title>
|
|
3
|
+
<desc id="desc">A terminal window with a quick note app, an input hint, and Ctrl+C exit guidance.</desc>
|
|
4
|
+
<rect width="640" height="220" rx="18" fill="#0d1117"/>
|
|
5
|
+
<rect x="24" y="24" width="592" height="172" rx="12" fill="#161b22" stroke="#30363d"/>
|
|
6
|
+
<circle cx="52" cy="52" r="6" fill="#ff7b72"/>
|
|
7
|
+
<circle cx="72" cy="52" r="6" fill="#f2cc60"/>
|
|
8
|
+
<circle cx="92" cy="52" r="6" fill="#56d364"/>
|
|
9
|
+
<text x="44" y="92" fill="#e6edf3" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" font-size="18">Quick note</text>
|
|
10
|
+
<text x="44" y="124" fill="#8b949e" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" font-size="16">Type a note. Ctrl+C: exit.</text>
|
|
11
|
+
<rect x="44" y="144" width="360" height="28" rx="6" fill="#0d1117" stroke="#58a6ff"/>
|
|
12
|
+
<text x="58" y="164" fill="#c9d1d9" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" font-size="15">Write a note</text>
|
|
13
|
+
</svg>
|