@flyingrobots/bijou-tui 3.1.0 → 4.0.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/LICENSE +159 -21
- package/README.md +181 -32
- package/dist/app-frame-actions.d.ts.map +1 -1
- package/dist/app-frame-actions.js +4 -5
- package/dist/app-frame-actions.js.map +1 -1
- package/dist/app-frame-render.d.ts +17 -11
- package/dist/app-frame-render.d.ts.map +1 -1
- package/dist/app-frame-render.js +100 -99
- package/dist/app-frame-render.js.map +1 -1
- package/dist/app-frame-types.d.ts +1 -1
- package/dist/app-frame-types.d.ts.map +1 -1
- package/dist/app-frame.d.ts +3 -1
- package/dist/app-frame.d.ts.map +1 -1
- package/dist/app-frame.js +89 -61
- package/dist/app-frame.js.map +1 -1
- package/dist/browsable-list.d.ts +20 -1
- package/dist/browsable-list.d.ts.map +1 -1
- package/dist/browsable-list.js +38 -10
- package/dist/browsable-list.js.map +1 -1
- package/dist/command-palette.d.ts +17 -1
- package/dist/command-palette.d.ts.map +1 -1
- package/dist/command-palette.js +45 -20
- package/dist/command-palette.js.map +1 -1
- package/dist/css/text-style.d.ts +2 -1
- package/dist/css/text-style.d.ts.map +1 -1
- package/dist/css/text-style.js +33 -0
- package/dist/css/text-style.js.map +1 -1
- package/dist/design-language.d.ts +49 -0
- package/dist/design-language.d.ts.map +1 -0
- package/dist/design-language.js +70 -0
- package/dist/design-language.js.map +1 -0
- package/dist/driver.d.ts +6 -1
- package/dist/driver.d.ts.map +1 -1
- package/dist/driver.js +3 -0
- package/dist/driver.js.map +1 -1
- package/dist/file-picker.d.ts +19 -1
- package/dist/file-picker.d.ts.map +1 -1
- package/dist/file-picker.js +47 -20
- package/dist/file-picker.js.map +1 -1
- package/dist/flex.d.ts +35 -1
- package/dist/flex.d.ts.map +1 -1
- package/dist/flex.js +127 -1
- package/dist/flex.js.map +1 -1
- package/dist/focus-area.d.ts +13 -1
- package/dist/focus-area.d.ts.map +1 -1
- package/dist/focus-area.js +89 -12
- package/dist/focus-area.js.map +1 -1
- package/dist/grid.d.ts +10 -0
- package/dist/grid.d.ts.map +1 -1
- package/dist/grid.js +25 -0
- package/dist/grid.js.map +1 -1
- package/dist/help.d.ts +41 -0
- package/dist/help.d.ts.map +1 -1
- package/dist/help.js +50 -0
- package/dist/help.js.map +1 -1
- package/dist/index.d.ts +17 -16
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +17 -15
- package/dist/index.js.map +1 -1
- package/dist/layout-node-surface.d.ts +9 -0
- package/dist/layout-node-surface.d.ts.map +1 -0
- package/dist/layout-node-surface.js +42 -0
- package/dist/layout-node-surface.js.map +1 -0
- package/dist/navigable-table.d.ts +16 -1
- package/dist/navigable-table.d.ts.map +1 -1
- package/dist/navigable-table.js +32 -1
- package/dist/navigable-table.js.map +1 -1
- package/dist/notification.d.ts +16 -0
- package/dist/notification.d.ts.map +1 -1
- package/dist/notification.js +163 -35
- package/dist/notification.js.map +1 -1
- package/dist/overlay.d.ts +21 -8
- package/dist/overlay.d.ts.map +1 -1
- package/dist/overlay.js +236 -138
- package/dist/overlay.js.map +1 -1
- package/dist/pager.d.ts +16 -0
- package/dist/pager.d.ts.map +1 -1
- package/dist/pager.js +61 -1
- package/dist/pager.js.map +1 -1
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +6 -12
- package/dist/runtime.js.map +1 -1
- package/dist/split-pane.d.ts +12 -1
- package/dist/split-pane.d.ts.map +1 -1
- package/dist/split-pane.js +31 -1
- package/dist/split-pane.js.map +1 -1
- package/dist/status-bar.d.ts +12 -0
- package/dist/status-bar.d.ts.map +1 -1
- package/dist/status-bar.js +45 -16
- package/dist/status-bar.js.map +1 -1
- package/dist/surface-layout.d.ts +19 -0
- package/dist/surface-layout.d.ts.map +1 -0
- package/dist/surface-layout.js +87 -0
- package/dist/surface-layout.js.map +1 -0
- package/dist/transition-shaders.d.ts +10 -8
- package/dist/transition-shaders.d.ts.map +1 -1
- package/dist/transition-shaders.js +65 -19
- package/dist/transition-shaders.js.map +1 -1
- package/dist/types.d.ts +2 -2
- package/dist/view-output.d.ts +4 -4
- package/dist/view-output.d.ts.map +1 -1
- package/dist/view-output.js +24 -26
- package/dist/view-output.js.map +1 -1
- package/dist/viewport.d.ts +30 -1
- package/dist/viewport.d.ts.map +1 -1
- package/dist/viewport.js +77 -1
- package/dist/viewport.js.map +1 -1
- package/package.json +3 -3
- package/dist/layout-v3.d.ts +0 -10
- package/dist/layout-v3.d.ts.map +0 -1
- package/dist/layout-v3.js +0 -35
- package/dist/layout-v3.js.map +0 -1
package/LICENSE
CHANGED
|
@@ -1,21 +1,159 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
1
|
+
Apache License
|
|
2
|
+
Version 2.0, January 2004
|
|
3
|
+
http://www.apache.org/licenses/
|
|
4
|
+
|
|
5
|
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
6
|
+
|
|
7
|
+
1. Definitions.
|
|
8
|
+
|
|
9
|
+
"License" shall mean the terms and conditions for use, reproduction, and
|
|
10
|
+
distribution as defined by Sections 1 through 9 of this document.
|
|
11
|
+
|
|
12
|
+
"Licensor" shall mean the copyright owner or entity authorized by the copyright
|
|
13
|
+
owner that is granting the License.
|
|
14
|
+
|
|
15
|
+
"Legal Entity" shall mean the union of the acting entity and all other entities
|
|
16
|
+
that control, are controlled by, or are under common control with that entity.
|
|
17
|
+
For the purposes of this definition, "control" means (i) the power, direct or
|
|
18
|
+
indirect, to cause the direction or management of such entity, whether by
|
|
19
|
+
contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
20
|
+
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
21
|
+
|
|
22
|
+
"You" (or "Your") shall mean an individual or Legal Entity exercising
|
|
23
|
+
permissions granted by this License.
|
|
24
|
+
|
|
25
|
+
"Source" form shall mean the preferred form for making modifications, including
|
|
26
|
+
but not limited to software source code, documentation source, and configuration
|
|
27
|
+
files.
|
|
28
|
+
|
|
29
|
+
"Object" form shall mean any form resulting from mechanical transformation or
|
|
30
|
+
translation of a Source form, including but not limited to compiled object code,
|
|
31
|
+
generated documentation, and conversions to other media types.
|
|
32
|
+
|
|
33
|
+
"Work" shall mean the work of authorship, whether in Source or Object form, made
|
|
34
|
+
available under the License, as indicated by a copyright notice that is included
|
|
35
|
+
in or attached to the work (an example is provided in the Appendix below).
|
|
36
|
+
|
|
37
|
+
"Derivative Works" shall mean any work, whether in Source or Object form, that
|
|
38
|
+
is based on (or derived from) the Work and for which the editorial revisions,
|
|
39
|
+
annotations, elaborations, or other modifications represent, as a whole, an
|
|
40
|
+
original work of authorship. For the purposes of this License, Derivative Works
|
|
41
|
+
shall not include works that remain separable from, or merely link (or bind by
|
|
42
|
+
name) to the interfaces of, the Work and Derivative Works thereof.
|
|
43
|
+
|
|
44
|
+
"Contribution" shall mean any work of authorship, including the original version
|
|
45
|
+
of the Work and any modifications or additions to that Work or Derivative Works
|
|
46
|
+
thereof, that is intentionally submitted to Licensor for inclusion in the Work
|
|
47
|
+
by the copyright owner or by an individual or Legal Entity authorized to submit
|
|
48
|
+
on behalf of the copyright owner. For the purposes of this definition,
|
|
49
|
+
"submitted" means any form of electronic, verbal, or written communication sent
|
|
50
|
+
to the Licensor or its representatives, including but not limited to
|
|
51
|
+
communication on electronic mailing lists, source code control systems, and
|
|
52
|
+
issue tracking systems that are managed by, or on behalf of, the Licensor for
|
|
53
|
+
the purpose of discussing and improving the Work, but excluding communication
|
|
54
|
+
that is conspicuously marked or otherwise designated in writing by the copyright
|
|
55
|
+
owner as "Not a Contribution."
|
|
56
|
+
|
|
57
|
+
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf
|
|
58
|
+
of whom a Contribution has been received by Licensor and subsequently
|
|
59
|
+
incorporated within the Work.
|
|
60
|
+
|
|
61
|
+
2. Grant of Copyright License. Subject to the terms and conditions of this
|
|
62
|
+
License, each Contributor hereby grants to You a perpetual, worldwide,
|
|
63
|
+
non-exclusive, no-charge, royalty-free, irrevocable copyright license to
|
|
64
|
+
reproduce, prepare Derivative Works of, publicly display, publicly perform,
|
|
65
|
+
sublicense, and distribute the Work and such Derivative Works in Source or
|
|
66
|
+
Object form.
|
|
67
|
+
|
|
68
|
+
3. Grant of Patent License. Subject to the terms and conditions of this License,
|
|
69
|
+
each Contributor hereby grants to You a perpetual, worldwide, non-exclusive,
|
|
70
|
+
no-charge, royalty-free, irrevocable (except as stated in this section) patent
|
|
71
|
+
license to make, have made, use, offer to sell, sell, import, and otherwise
|
|
72
|
+
transfer the Work, where such license applies only to those patent claims
|
|
73
|
+
licensable by such Contributor that are necessarily infringed by their
|
|
74
|
+
Contribution(s) alone or by combination of their Contribution(s) with the Work
|
|
75
|
+
to which such Contribution(s) was submitted. If You institute patent litigation
|
|
76
|
+
against any entity (including a cross-claim or counterclaim in a lawsuit)
|
|
77
|
+
alleging that the Work or a Contribution incorporated within the Work
|
|
78
|
+
constitutes direct or contributory patent infringement, then any patent licenses
|
|
79
|
+
granted to You under this License for that Work shall terminate as of the date
|
|
80
|
+
such litigation is filed.
|
|
81
|
+
|
|
82
|
+
4. Redistribution. You may reproduce and distribute copies of the Work or
|
|
83
|
+
Derivative Works thereof in any medium, with or without modifications, and in
|
|
84
|
+
Source or Object form, provided that You meet the following conditions:
|
|
85
|
+
|
|
86
|
+
(a) You must give any other recipients of the Work or Derivative Works a copy of
|
|
87
|
+
this License; and
|
|
88
|
+
|
|
89
|
+
(b) You must cause any modified files to carry prominent notices stating that You
|
|
90
|
+
changed the files; and
|
|
91
|
+
|
|
92
|
+
(c) You must retain, in the Source form of any Derivative Works that You
|
|
93
|
+
distribute, all copyright, patent, trademark, and attribution notices from the
|
|
94
|
+
Source form of the Work, excluding those notices that do not pertain to any part
|
|
95
|
+
of the Derivative Works; and
|
|
96
|
+
|
|
97
|
+
(d) If the Work includes a "NOTICE" text file as part of its distribution, then
|
|
98
|
+
any Derivative Works that You distribute must include a readable copy of the
|
|
99
|
+
attribution notices contained within such NOTICE file, excluding those notices
|
|
100
|
+
that do not pertain to any part of the Derivative Works, in at least one of the
|
|
101
|
+
following places: within a NOTICE text file distributed as part of the
|
|
102
|
+
Derivative Works; within the Source form or documentation, if provided along
|
|
103
|
+
with the Derivative Works; or, within a display generated by the Derivative
|
|
104
|
+
Works, if and wherever such third-party notices normally appear. The contents of
|
|
105
|
+
the NOTICE file are for informational purposes only and do not modify the
|
|
106
|
+
License. You may add Your own attribution notices within Derivative Works that
|
|
107
|
+
You distribute, alongside or as an addendum to the NOTICE text from the Work,
|
|
108
|
+
provided that such additional attribution notices cannot be construed as
|
|
109
|
+
modifying the License.
|
|
110
|
+
|
|
111
|
+
You may add Your own copyright statement to Your modifications and may provide
|
|
112
|
+
additional or different license terms and conditions for use, reproduction, or
|
|
113
|
+
distribution of Your modifications, or for any such Derivative Works as a whole,
|
|
114
|
+
provided Your use, reproduction, and distribution of the Work otherwise complies
|
|
115
|
+
with the conditions stated in this License.
|
|
116
|
+
|
|
117
|
+
5. Submission of Contributions. Unless You explicitly state otherwise, any
|
|
118
|
+
Contribution intentionally submitted for inclusion in the Work by You to the
|
|
119
|
+
Licensor shall be under the terms and conditions of this License, without any
|
|
120
|
+
additional terms or conditions. Notwithstanding the above, nothing herein shall
|
|
121
|
+
supersede or modify the terms of any separate license agreement you may have
|
|
122
|
+
executed with Licensor regarding such Contributions.
|
|
123
|
+
|
|
124
|
+
6. Trademarks. This License does not grant permission to use the trade names,
|
|
125
|
+
trademarks, service marks, or product names of the Licensor, except as required
|
|
126
|
+
for reasonable and customary use in describing the origin of the Work and
|
|
127
|
+
reproducing the content of the NOTICE file.
|
|
128
|
+
|
|
129
|
+
7. Disclaimer of Warranty. Unless required by applicable law or agreed to in
|
|
130
|
+
writing, Licensor provides the Work (and each Contributor provides its
|
|
131
|
+
Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
132
|
+
KIND, either express or implied, including, without limitation, any warranties
|
|
133
|
+
or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
134
|
+
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
135
|
+
appropriateness of using or redistributing the Work and assume any risks
|
|
136
|
+
associated with Your exercise of permissions under this License.
|
|
137
|
+
|
|
138
|
+
8. Limitation of Liability. In no event and under no legal theory, whether in
|
|
139
|
+
tort (including negligence), contract, or otherwise, unless required by
|
|
140
|
+
applicable law (such as deliberate and grossly negligent acts) or agreed to in
|
|
141
|
+
writing, shall any Contributor be liable to You for damages, including any
|
|
142
|
+
direct, indirect, special, incidental, or consequential damages of any
|
|
143
|
+
character arising as a result of this License or out of the use or inability to
|
|
144
|
+
use the Work (including but not limited to damages for loss of goodwill, work
|
|
145
|
+
stoppage, computer failure or malfunction, or any and all other commercial
|
|
146
|
+
damages or losses), even if such Contributor has been advised of the
|
|
147
|
+
possibility of such damages.
|
|
148
|
+
|
|
149
|
+
9. Accepting Warranty or Additional Liability. While redistributing the Work or
|
|
150
|
+
Derivative Works thereof, You may choose to offer, and charge a fee for,
|
|
151
|
+
acceptance of support, warranty, indemnity, or other liability obligations
|
|
152
|
+
and/or rights consistent with this License. However, in accepting such
|
|
153
|
+
obligations, You may act only on Your own behalf and on Your sole
|
|
154
|
+
responsibility, not on behalf of any other Contributor, and only if You agree to
|
|
155
|
+
indemnify, defend, and hold each Contributor harmless for any liability incurred
|
|
156
|
+
by, or claims asserted against, such Contributor by reason of your accepting any
|
|
157
|
+
such warranty or additional liability.
|
|
158
|
+
|
|
159
|
+
END OF TERMS AND CONDITIONS
|
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@ The high-fidelity TEA runtime for Bijou.
|
|
|
9
9
|
The TUI package has been completely overhauled in v3.0.0 to operate as a true graphics engine.
|
|
10
10
|
|
|
11
11
|
### 🌟 What's New
|
|
12
|
-
- **
|
|
12
|
+
- **Pure view contract:** `App.view` and framed pane renderers now speak `ViewOutput` (`Surface | LayoutNode`).
|
|
13
13
|
- **Programmable Rendering Pipeline:** The TEA `view` output is now processed through a 5-stage middleware pipeline (`Layout -> Paint -> PostProcess -> Diff -> Output`). Add custom fragment shaders or logging middleware effortlessly.
|
|
14
14
|
- **Fractal TEA (Sub-Apps):** Compose nested apps with `initSubApp()`, `updateSubApp()`, `mount()`, and `mapCmds()` instead of flattening everything into one update loop.
|
|
15
15
|
- **Bijou CSS (BCSS):** Style supported V3 surface components and frame shell regions with type/class/id selectors, `var()` token lookups, and terminal-aware media queries (`@media (width < 80)`). This is not yet a global cascade across arbitrary layout nodes.
|
|
@@ -22,7 +22,7 @@ The TUI package has been completely overhauled in v3.0.0 to operate as a true gr
|
|
|
22
22
|
npm install @flyingrobots/bijou@3.0.0 @flyingrobots/bijou-node@3.0.0 @flyingrobots/bijou-tui@3.0.0
|
|
23
23
|
```
|
|
24
24
|
|
|
25
|
-
If you are upgrading an existing app, see [`../../docs/
|
|
25
|
+
If you are upgrading an existing app, see [`../../docs/MIGRATING_TO_V4.md`](../../docs/MIGRATING_TO_V4.md).
|
|
26
26
|
|
|
27
27
|
## Quick Start (V3 Sub-App Composition)
|
|
28
28
|
|
|
@@ -73,6 +73,7 @@ run(app);
|
|
|
73
73
|
|
|
74
74
|
```typescript
|
|
75
75
|
import { initDefaultContext } from '@flyingrobots/bijou-node';
|
|
76
|
+
import { stringToSurface } from '@flyingrobots/bijou';
|
|
76
77
|
import { run, quit, type App, isKeyMsg } from '@flyingrobots/bijou-tui';
|
|
77
78
|
|
|
78
79
|
initDefaultContext();
|
|
@@ -91,7 +92,11 @@ const app: App<Model> = {
|
|
|
91
92
|
return [model, []];
|
|
92
93
|
},
|
|
93
94
|
|
|
94
|
-
view: (model) =>
|
|
95
|
+
view: (model) => {
|
|
96
|
+
const text = `Count: ${model.count}\n\nPress +/- to change, q to quit`;
|
|
97
|
+
const lines = text.split('\n');
|
|
98
|
+
return stringToSurface(text, Math.max(1, ...lines.map((line) => line.length)), lines.length);
|
|
99
|
+
},
|
|
95
100
|
};
|
|
96
101
|
|
|
97
102
|
run(app);
|
|
@@ -116,6 +121,37 @@ In non-interactive modes, there is no normal interactive event loop.
|
|
|
116
121
|
- **App shell**: `createFramedApp()` for tabs/help/chrome/pane-focus boilerplate with optional command palette.
|
|
117
122
|
- **Stateful building blocks**: navigable table, browsable list, file picker, focus area, and DAG pane with vim-friendly keymaps.
|
|
118
123
|
|
|
124
|
+
## Choosing Component Families
|
|
125
|
+
|
|
126
|
+
### Overlays and interruption
|
|
127
|
+
|
|
128
|
+
- Use `toast()` when you are composing a single transient overlay directly.
|
|
129
|
+
- Use the notification system when the app needs stacking, placement, actions, routing, or history.
|
|
130
|
+
- Use `drawer()` when the user should keep the main surface visible while working in supplemental detail.
|
|
131
|
+
- Use `modal()` when background shortcuts and pointer actions should be blocked.
|
|
132
|
+
- Use `tooltip()` only for tiny local explanation, not for decisions or scrollable content.
|
|
133
|
+
- If the overlay needs embedded component surfaces or multiple real rows, keep it on the structured `Surface` path with `compositeSurface()`.
|
|
134
|
+
|
|
135
|
+
### Collection interaction
|
|
136
|
+
|
|
137
|
+
- Use core `table()` or `tableSurface()` for passive comparison.
|
|
138
|
+
- Use `navigableTable()` when row/cell focus and keyboard traversal are the real job.
|
|
139
|
+
- Use `browsableList()` when the content is one-dimensional and description-led rather than grid-oriented.
|
|
140
|
+
- Use `commandPaletteSurface()` when the outcome is an action or navigation target, not a stored form value.
|
|
141
|
+
- If users are really choosing persisted values, keep that work in core `select()` / `filter()` / `multiselect()` instead of turning the palette into a value picker.
|
|
142
|
+
|
|
143
|
+
### Shell and workspace layout
|
|
144
|
+
|
|
145
|
+
- Use `createFramedApp()` when the app has multiple destinations, overlays, and workspace state that should be standardized.
|
|
146
|
+
- Use `splitPane()` when the user benefits from primary-versus-secondary context or side-by-side comparison.
|
|
147
|
+
- Use `grid()` when multiple stable regions deserve simultaneous visibility.
|
|
148
|
+
- Use `statusBarSurface()` when shell chrome already lives on the structured `Surface` path; keep `statusBar()` for explicit text output.
|
|
149
|
+
- Use `helpShortSurface()` or `helpViewSurface()` when shortcut guidance stays inside the rich shell; keep `helpShort()` / `helpView()` for explicit text output.
|
|
150
|
+
- Use `commandPaletteSurface()` for action discovery and navigation inside the shell, not as a substitute value picker.
|
|
151
|
+
- Use notifications for events and follow-up, not as a replacement for the status rail.
|
|
152
|
+
- Keep status rails concise and global; explanatory text belongs in the page, not in shell chrome.
|
|
153
|
+
- Mouse is enhancement, not baseline. Overlay layers should consume pointer input before shell chrome or page content, and every click target should mirror an existing keyboard path.
|
|
154
|
+
|
|
119
155
|
## Animation
|
|
120
156
|
|
|
121
157
|
### Spring Physics
|
|
@@ -174,6 +210,25 @@ const fired = tl.firedCallbacks(prev, tlState); // ['onReady']
|
|
|
174
210
|
|
|
175
211
|
Position syntax: `'<'` (parallel), `'+=N'` (gap), `'-=N'` (overlap), `'<+=N'` (offset from previous start), absolute ms, `'label'`, `'label+=N'`.
|
|
176
212
|
|
|
213
|
+
## Transition Shaders
|
|
214
|
+
|
|
215
|
+
Custom page transitions are surface-native in v4. Shader functions decide whether each cell shows the previous page or next page, and may optionally provide override data for that cell.
|
|
216
|
+
|
|
217
|
+
```typescript
|
|
218
|
+
import { type TransitionShaderFn } from '@flyingrobots/bijou-tui';
|
|
219
|
+
|
|
220
|
+
const shimmer: TransitionShaderFn = ({ progress, x, width }) => {
|
|
221
|
+
const edge = Math.floor(progress * width);
|
|
222
|
+
if (x < edge) return { showNext: true };
|
|
223
|
+
if (x === edge) return { showNext: false, overrideChar: '░', overrideRole: 'marker' };
|
|
224
|
+
return { showNext: false };
|
|
225
|
+
};
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
Use `overrideChar` when the base cell styling should stay intact, `overrideCell` when the shader needs full fg/bg/modifier control, and `overrideRole` to tell combinators whether an override is ambient (`'decoration'`) or positional (`'marker'`).
|
|
229
|
+
|
|
230
|
+
Use transition shaders to reinforce workspace change, not as default spectacle. If the effect makes the new page harder to read or hides state meaning that should remain explicit in static or accessible modes, it is the wrong transition.
|
|
231
|
+
|
|
177
232
|
## Layout
|
|
178
233
|
|
|
179
234
|
### Flexbox
|
|
@@ -200,32 +255,55 @@ Children can be **render functions** `(width, height) => string` — they receiv
|
|
|
200
255
|
### Viewport
|
|
201
256
|
|
|
202
257
|
```typescript
|
|
203
|
-
import {
|
|
258
|
+
import { viewportSurface, createScrollStateForContent, scrollBy, pageDown } from '@flyingrobots/bijou-tui';
|
|
259
|
+
import { boxSurface } from '@flyingrobots/bijou';
|
|
204
260
|
|
|
205
|
-
|
|
261
|
+
const content = boxSurface(longText, { width: 72 });
|
|
262
|
+
let scroll = createScrollStateForContent(content, viewportHeight);
|
|
206
263
|
|
|
207
|
-
//
|
|
208
|
-
const view =
|
|
264
|
+
// Mask the content to a visible window with scrollbar
|
|
265
|
+
const view = viewportSurface({ width: 60, height: 20, content, scrollY: scroll.y });
|
|
209
266
|
|
|
210
267
|
// Handle scroll keys
|
|
211
268
|
scroll = scrollBy(scroll, 1); // down one line
|
|
212
269
|
scroll = pageDown(scroll); // down one page
|
|
213
270
|
```
|
|
214
271
|
|
|
272
|
+
Treat `viewportSurface()` as the canonical scroll mask for rich TUI composition. Keep `viewport()` for explicit text-lowering paths.
|
|
273
|
+
|
|
215
274
|
### Basic Layout
|
|
216
275
|
|
|
217
276
|
```typescript
|
|
218
|
-
import {
|
|
277
|
+
import {
|
|
278
|
+
hstack,
|
|
279
|
+
hstackSurface,
|
|
280
|
+
place,
|
|
281
|
+
placeSurface,
|
|
282
|
+
vstack,
|
|
283
|
+
vstackSurface,
|
|
284
|
+
} from '@flyingrobots/bijou-tui';
|
|
219
285
|
|
|
220
|
-
vstack(header, content, footer);
|
|
221
|
-
hstack(2, leftPanel, rightPanel);
|
|
286
|
+
vstack(header, content, footer); // explicit text-lowering path
|
|
287
|
+
hstack(2, leftPanel, rightPanel); // explicit text-lowering path
|
|
288
|
+
place('Title', { width: 20, height: 3 }); // text placement
|
|
289
|
+
|
|
290
|
+
vstackSurface(headerSurface, bodySurface); // structured surface stack
|
|
291
|
+
hstackSurface(2, navSurface, mainSurface); // structured horizontal stack
|
|
292
|
+
placeSurface(dialogSurface, { // structured placement/alignment
|
|
293
|
+
width: cols,
|
|
294
|
+
height: rows,
|
|
295
|
+
hAlign: 'center',
|
|
296
|
+
vAlign: 'middle',
|
|
297
|
+
});
|
|
222
298
|
```
|
|
223
299
|
|
|
300
|
+
Prefer `vstackSurface()` / `hstackSurface()` / `placeSurface()` when the view is already composed from `Surface` values. Keep `vstack()` / `hstack()` / `place()` for explicit text composition or lowering paths.
|
|
301
|
+
|
|
224
302
|
### Split Pane
|
|
225
303
|
|
|
226
304
|
```typescript
|
|
227
305
|
import {
|
|
228
|
-
createSplitPaneState,
|
|
306
|
+
createSplitPaneState, splitPaneSurface, splitPaneResizeBy, splitPaneFocusNext,
|
|
229
307
|
} from '@flyingrobots/bijou-tui';
|
|
230
308
|
|
|
231
309
|
let state = createSplitPaneState({ ratio: 0.35 });
|
|
@@ -235,7 +313,7 @@ state = splitPaneResizeBy(state, 2, { total: cols, minA: 16, minB: 16 });
|
|
|
235
313
|
state = splitPaneFocusNext(state);
|
|
236
314
|
|
|
237
315
|
// in view:
|
|
238
|
-
const output =
|
|
316
|
+
const output = splitPaneSurface(state, {
|
|
239
317
|
direction: 'row',
|
|
240
318
|
width: cols,
|
|
241
319
|
height: rows,
|
|
@@ -246,12 +324,14 @@ const output = splitPane(state, {
|
|
|
246
324
|
});
|
|
247
325
|
```
|
|
248
326
|
|
|
327
|
+
Prefer `splitPaneSurface()` when the panes are already structured `Surface` views. Keep `splitPane()` for explicit text composition or lowering paths.
|
|
328
|
+
|
|
249
329
|
### Grid
|
|
250
330
|
|
|
251
331
|
```typescript
|
|
252
|
-
import {
|
|
332
|
+
import { gridSurface } from '@flyingrobots/bijou-tui';
|
|
253
333
|
|
|
254
|
-
const output =
|
|
334
|
+
const output = gridSurface({
|
|
255
335
|
width: cols,
|
|
256
336
|
height: rows,
|
|
257
337
|
columns: [24, '1fr'],
|
|
@@ -271,6 +351,8 @@ const output = grid({
|
|
|
271
351
|
});
|
|
272
352
|
```
|
|
273
353
|
|
|
354
|
+
Prefer `gridSurface()` when the regions are already structured `Surface` views. Keep `grid()` for explicit text composition or lowering paths.
|
|
355
|
+
|
|
274
356
|
## Resize Handling
|
|
275
357
|
|
|
276
358
|
Terminal resize events are dispatched automatically as `ResizeMsg`:
|
|
@@ -341,11 +423,21 @@ kb.enable('Quit');
|
|
|
341
423
|
Auto-generate help text from registered bindings:
|
|
342
424
|
|
|
343
425
|
```typescript
|
|
344
|
-
import {
|
|
426
|
+
import {
|
|
427
|
+
helpView,
|
|
428
|
+
helpViewSurface,
|
|
429
|
+
helpShort,
|
|
430
|
+
helpShortSurface,
|
|
431
|
+
helpFor,
|
|
432
|
+
helpForSurface,
|
|
433
|
+
} from '@flyingrobots/bijou-tui';
|
|
345
434
|
|
|
346
|
-
helpView(kb);
|
|
347
|
-
helpShort(kb);
|
|
348
|
-
helpFor(kb, 'Nav');
|
|
435
|
+
helpView(kb); // full grouped multi-line help
|
|
436
|
+
helpShort(kb); // "q Quit • ? Help • Ctrl+c Force quit • j Down • k Up"
|
|
437
|
+
helpFor(kb, 'Nav'); // only Navigation group
|
|
438
|
+
helpShortSurface(kb, { width: 48 }); // shell hint that stays on the Surface path
|
|
439
|
+
helpViewSurface(kb, { width: 48 }); // grouped help as a Surface
|
|
440
|
+
helpForSurface(kb, 'Nav', { width: 48 });
|
|
349
441
|
```
|
|
350
442
|
|
|
351
443
|
### Input Stack
|
|
@@ -377,7 +469,7 @@ stack.remove(modalId);
|
|
|
377
469
|
Paint overlays (modals, toasts) on top of existing content:
|
|
378
470
|
|
|
379
471
|
```typescript
|
|
380
|
-
import {
|
|
472
|
+
import { compositeSurface, modal, toast } from '@flyingrobots/bijou-tui';
|
|
381
473
|
|
|
382
474
|
// Create a centered dialog
|
|
383
475
|
const dialog = modal({
|
|
@@ -398,12 +490,17 @@ const notification = toast({
|
|
|
398
490
|
});
|
|
399
491
|
|
|
400
492
|
// Paint overlays onto background content
|
|
401
|
-
const output =
|
|
493
|
+
const output = compositeSurface(backgroundSurface, [dialog, notification], { dim: true });
|
|
402
494
|
```
|
|
403
495
|
|
|
404
|
-
Each overlay
|
|
496
|
+
Each overlay now exposes both `surface` and `content` forms. Prefer `compositeSurface()` when your app is already on the surface-native path. Keep the string-oriented `composite()` path for explicit lowering boundaries, not as the default mental model. The `dim` option fades the background with ANSI dim.
|
|
497
|
+
|
|
498
|
+
`modal().body`, `modal().hint`, `drawer().content`, and `tooltip().content` accept either plain strings or structured `Surface` content. Use surfaces when the overlay needs real rows, embedded component surfaces, or richer composition inside the interrupting layer.
|
|
499
|
+
|
|
500
|
+
Reach for `toast()` when the app is composing a one-off overlay directly. Reach for the notification system when stacking, actions, routing, or history matter. The notification lab in `examples/notifications` is the canonical higher-level example.
|
|
405
501
|
|
|
406
502
|
`drawer()` now supports `left`/`right`/`top`/`bottom` anchors and optional `region` mounting for panel-scoped overlays.
|
|
503
|
+
Use `drawer()` when the user should keep the main task visible while consulting or editing supplemental context. Use `modal()` when the user must stop and decide. Use `tooltip()` only for tiny local explanation, not for commands or scrollable content.
|
|
407
504
|
|
|
408
505
|
## App Frame
|
|
409
506
|
|
|
@@ -414,10 +511,17 @@ Each overlay is a `{ content, row, col }` object. `composite()` splices them ont
|
|
|
414
511
|
- frame help (`?`) and optional command palette (`ctrl+p` / `:`)
|
|
415
512
|
- overlay factory with pane rects for panel-scoped drawers/modals
|
|
416
513
|
|
|
417
|
-
Pane renderers
|
|
514
|
+
Pane renderers return a `Surface` or a `LayoutNode`. The shell normalizes those outputs into the framed scroll/focus path for you.
|
|
418
515
|
|
|
419
516
|
See `examples/release-workbench/main.ts` for the canonical shell demo and `examples/app-frame/main.ts` for a compact focused example.
|
|
420
517
|
|
|
518
|
+
Shell role split matters:
|
|
519
|
+
|
|
520
|
+
- `statusBarSurface()` communicates concise global state
|
|
521
|
+
- `helpShortSurface()` / `helpViewSurface()` teach shortcuts and scope
|
|
522
|
+
- `commandPaletteSurface()` handles action discovery and navigation
|
|
523
|
+
- notifications surface events and follow-up
|
|
524
|
+
|
|
421
525
|
## Building Blocks
|
|
422
526
|
|
|
423
527
|
Reusable stateful components that follow the TEA state + pure transformers + sync render + convenience keymap pattern:
|
|
@@ -426,55 +530,100 @@ Reusable stateful components that follow the TEA state + pure transformers + syn
|
|
|
426
530
|
|
|
427
531
|
```typescript
|
|
428
532
|
import {
|
|
429
|
-
createNavigableTableState, navigableTable, navTableFocusNext,
|
|
533
|
+
createNavigableTableState, navigableTable, navigableTableSurface, navTableFocusNext,
|
|
430
534
|
navTableKeyMap, helpShort,
|
|
431
535
|
} from '@flyingrobots/bijou-tui';
|
|
432
536
|
|
|
433
537
|
const state = createNavigableTableState({ columns, rows, height: 10 });
|
|
434
|
-
const
|
|
538
|
+
const textOutput = navigableTable(state, { ctx });
|
|
539
|
+
const surfaceOutput = navigableTableSurface(state, { ctx });
|
|
435
540
|
const next = navTableFocusNext(state);
|
|
436
541
|
```
|
|
437
542
|
|
|
543
|
+
Use `navigableTableSurface()` when the user should actively traverse a table inside a rich TUI surface. Keep `navigableTable()` for explicit text lowering. If the job is still passive comparison, prefer core `table()` or `tableSurface()` and keep the interaction layer simpler.
|
|
544
|
+
|
|
438
545
|
### Browsable List
|
|
439
546
|
|
|
440
547
|
```typescript
|
|
441
548
|
import {
|
|
442
|
-
createBrowsableListState, browsableList, listFocusNext,
|
|
549
|
+
createBrowsableListState, browsableList, browsableListSurface, listFocusNext,
|
|
443
550
|
browsableListKeyMap,
|
|
444
551
|
} from '@flyingrobots/bijou-tui';
|
|
445
552
|
|
|
446
553
|
const state = createBrowsableListState({ items, height: 10 });
|
|
447
|
-
const
|
|
554
|
+
const textOutput = browsableList(state);
|
|
555
|
+
const surfaceOutput = browsableListSurface(state, { width: 40 });
|
|
448
556
|
```
|
|
449
557
|
|
|
558
|
+
Use `browsableListSurface()` when the list belongs inside a rich TUI region and should share viewport masking semantics with pagers and focus areas. Keep `browsableList()` for explicit text lowering.
|
|
559
|
+
|
|
450
560
|
### File Picker
|
|
451
561
|
|
|
452
562
|
```typescript
|
|
453
563
|
import {
|
|
454
|
-
createFilePickerState, filePicker, fpFocusNext, fpEnter, fpBack,
|
|
564
|
+
createFilePickerState, filePicker, filePickerSurface, fpFocusNext, fpEnter, fpBack,
|
|
455
565
|
filePickerKeyMap,
|
|
456
566
|
} from '@flyingrobots/bijou-tui';
|
|
457
567
|
import { nodeIO } from '@flyingrobots/bijou-node';
|
|
458
568
|
|
|
459
569
|
const io = nodeIO();
|
|
460
570
|
const state = createFilePickerState({ cwd: process.cwd(), io, height: 15 });
|
|
461
|
-
const
|
|
571
|
+
const textOutput = filePicker(state);
|
|
572
|
+
const surfaceOutput = filePickerSurface(state, { width: 60 });
|
|
573
|
+
```
|
|
574
|
+
|
|
575
|
+
Use `filePickerSurface()` when the browser lives inside a rich TUI pane and should inherit shared viewport masking semantics. Keep `filePicker()` for explicit text lowering.
|
|
576
|
+
|
|
577
|
+
### Command Palette
|
|
578
|
+
|
|
579
|
+
```typescript
|
|
580
|
+
import {
|
|
581
|
+
createCommandPaletteState, commandPalette, commandPaletteSurface,
|
|
582
|
+
cpFilter, commandPaletteKeyMap,
|
|
583
|
+
} from '@flyingrobots/bijou-tui';
|
|
584
|
+
|
|
585
|
+
const state = createCommandPaletteState(items, 8);
|
|
586
|
+
const textOutput = commandPalette(state, { width: 60 });
|
|
587
|
+
const surfaceOutput = commandPaletteSurface(state, { width: 60, ctx });
|
|
588
|
+
```
|
|
589
|
+
|
|
590
|
+
Use `commandPaletteSurface()` when the palette is part of a structured shell or overlay and should share viewport masking semantics. Keep `commandPalette()` for explicit text lowering.
|
|
591
|
+
|
|
592
|
+
### Pager
|
|
593
|
+
|
|
594
|
+
```typescript
|
|
595
|
+
import {
|
|
596
|
+
createPagerStateForSurface,
|
|
597
|
+
pagerSurface,
|
|
598
|
+
pagerScrollBy,
|
|
599
|
+
} from '@flyingrobots/bijou-tui';
|
|
600
|
+
|
|
601
|
+
const state = createPagerStateForSurface(contentSurface, { width: 60, height: 20 });
|
|
602
|
+
const output = pagerSurface(contentSurface, state);
|
|
462
603
|
```
|
|
463
604
|
|
|
464
605
|
### Focus Area
|
|
465
606
|
|
|
466
607
|
```typescript
|
|
467
608
|
import {
|
|
468
|
-
|
|
609
|
+
createFocusAreaStateForSurface, focusAreaScrollBy, focusAreaSurface,
|
|
469
610
|
focusAreaKeyMap,
|
|
470
611
|
} from '@flyingrobots/bijou-tui';
|
|
471
612
|
|
|
472
|
-
const state =
|
|
473
|
-
|
|
613
|
+
const state = createFocusAreaStateForSurface(contentSurface, {
|
|
614
|
+
width: 60,
|
|
615
|
+
height: 20,
|
|
616
|
+
overflowX: 'scroll',
|
|
617
|
+
});
|
|
618
|
+
const output = focusAreaSurface(contentSurface, state, { focused: true, ctx });
|
|
474
619
|
```
|
|
475
620
|
|
|
621
|
+
If the pane is still intentionally text-composed, `createFocusAreaState()` + `focusArea()` remain the explicit lowering path.
|
|
622
|
+
|
|
476
623
|
### DAG Pane
|
|
477
624
|
|
|
625
|
+
Use `dagPane()` when graph inspection is an active task and the user needs keyboard-owned selection, path highlighting, and scroll control. Keep plain `dag()` in `@flyingrobots/bijou` for passive graph explanation, and move to `dagSlice()` or `dagStats()` when a focused fragment or structural summary would be more honest than a full interactive graph.
|
|
626
|
+
|
|
478
627
|
```typescript
|
|
479
628
|
import {
|
|
480
629
|
createDagPaneState, dagPane, dagPaneSelectChild,
|
|
@@ -495,7 +644,7 @@ All building blocks include `*KeyMap()` factories for preconfigured vim-style ke
|
|
|
495
644
|
|
|
496
645
|
## License
|
|
497
646
|
|
|
498
|
-
|
|
647
|
+
Apache-2.0
|
|
499
648
|
|
|
500
649
|
---
|
|
501
650
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app-frame-actions.d.ts","sourceRoot":"","sources":["../src/app-frame-actions.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,sBAAsB,EAAmB,MAAM,gBAAgB,CAAC;AACzF,OAAO,KAAK,EACV,kBAAkB,EAClB,WAAW,EACZ,MAAM,sBAAsB,CAAC;AAE9B,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAoCrD,yGAAyG;AACzG,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,GAAG,EAC7C,MAAM,EAAE,WAAW,EACnB,KAAK,EAAE,kBAAkB,CAAC,SAAS,EAAE,GAAG,CAAC,EACzC,OAAO,EAAE,sBAAsB,CAAC,SAAS,EAAE,GAAG,CAAC,EAC/C,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC,GAChD,CAAC,kBAAkB,CAAC,SAAS,EAAE,GAAG,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CA6ClD;AAED,mFAAmF;AACnF,wBAAgB,SAAS,CAAC,SAAS,EAAE,GAAG,EACtC,KAAK,EAAE,kBAAkB,CAAC,SAAS,EAAE,GAAG,CAAC,EACzC,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC,EACjD,OAAO,EAAE,sBAAsB,CAAC,SAAS,EAAE,GAAG,CAAC,GAC9C,CAAC,kBAAkB,CAAC,SAAS,EAAE,GAAG,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAqDlD;AAED,2EAA2E;AAC3E,wBAAgB,SAAS,CAAC,SAAS,EAAE,GAAG,EACtC,KAAK,EAAE,kBAAkB,CAAC,SAAS,EAAE,GAAG,CAAC,EACzC,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC,GAChD,kBAAkB,CAAC,SAAS,EAAE,GAAG,CAAC,CAkBpC;AAED,2DAA2D;AAC3D,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,GAAG,EAC9C,KAAK,EAAE,kBAAkB,CAAC,SAAS,EAAE,GAAG,CAAC,EACzC,MAAM,EAAE,OAAO,CACb,WAAW,EACX;IAAE,IAAI,EAAE,WAAW,GAAG,aAAa,GAAG,SAAS,GAAG,WAAW,GAAG,KAAK,GAAG,QAAQ,GAAG,aAAa,GAAG,cAAc,CAAA;CAAE,CACpH,EACD,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC,GAChD,kBAAkB,CAAC,SAAS,EAAE,GAAG,CAAC,
|
|
1
|
+
{"version":3,"file":"app-frame-actions.d.ts","sourceRoot":"","sources":["../src/app-frame-actions.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,11 +7,11 @@
|
|
|
7
7
|
import { wrapFrameMsg } from './app-frame-types.js';
|
|
8
8
|
import { createPanelVisibilityState, createPanelMaximizeState, toggleMinimized, restorePane, isMinimized, toggleMaximize, } from './panel-state.js';
|
|
9
9
|
import { createPanelDockState, movePaneInContainer, resolveChildOrder, findPaneContainer, } from './panel-dock.js';
|
|
10
|
-
import {
|
|
10
|
+
import { createFocusAreaStateForSurface, focusAreaScrollBy, focusAreaScrollByX, focusAreaScrollToBottom, focusAreaScrollToTop, focusAreaPageDown, focusAreaPageUp, focusAreaScrollTo, focusAreaScrollToX, } from './focus-area.js';
|
|
11
11
|
import { timeline } from './timeline.js';
|
|
12
12
|
import { EASINGS } from './spring.js';
|
|
13
13
|
import { collectPaneIds, assertUniquePaneIds, findPaneNode, frameBodyRect, } from './app-frame-utils.js';
|
|
14
|
-
import {
|
|
14
|
+
import { framePaneOutputToSurface, renderFrameNode } from './app-frame-render.js';
|
|
15
15
|
/** Dispatch a frame-level action (tab switch, pane cycle, scroll, palette, help toggle, transitions). */
|
|
16
16
|
export function applyFrameAction(action, model, options, pagesById) {
|
|
17
17
|
switch (action.type) {
|
|
@@ -151,9 +151,8 @@ export function scrollFocusedPane(model, action, pagesById) {
|
|
|
151
151
|
const paneNode = findPaneNode(layoutTree, focusedPaneId);
|
|
152
152
|
if (paneNode == null)
|
|
153
153
|
return model;
|
|
154
|
-
const
|
|
155
|
-
let state =
|
|
156
|
-
content,
|
|
154
|
+
const contentSurface = framePaneOutputToSurface(paneNode.render(paneRect.width, paneRect.height), paneRect.width, paneRect.height);
|
|
155
|
+
let state = createFocusAreaStateForSurface(contentSurface, {
|
|
157
156
|
width: paneRect.width,
|
|
158
157
|
height: paneRect.height,
|
|
159
158
|
overflowX: paneNode.overflowX ?? 'hidden',
|