@flyingrobots/bijou-tui 4.4.1 → 5.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/README.md +92 -20
- package/dist/app-frame-actions.d.ts.map +1 -1
- package/dist/app-frame-actions.js +2 -0
- package/dist/app-frame-actions.js.map +1 -1
- package/dist/app-frame-i18n.d.ts.map +1 -1
- package/dist/app-frame-i18n.js +49 -0
- package/dist/app-frame-i18n.js.map +1 -1
- package/dist/app-frame-layers.d.ts +11 -1
- package/dist/app-frame-layers.d.ts.map +1 -1
- package/dist/app-frame-layers.js +19 -0
- package/dist/app-frame-layers.js.map +1 -1
- package/dist/app-frame-overlays.d.ts +82 -0
- package/dist/app-frame-overlays.d.ts.map +1 -0
- package/dist/app-frame-overlays.js +480 -0
- package/dist/app-frame-overlays.js.map +1 -0
- package/dist/app-frame-render.js +2 -2
- package/dist/app-frame-render.js.map +1 -1
- package/dist/app-frame-types.d.ts +119 -5
- package/dist/app-frame-types.d.ts.map +1 -1
- package/dist/app-frame-types.js +17 -1
- package/dist/app-frame-types.js.map +1 -1
- package/dist/app-frame-utils.d.ts.map +1 -1
- package/dist/app-frame-utils.js +6 -5
- package/dist/app-frame-utils.js.map +1 -1
- package/dist/app-frame.d.ts +18 -84
- package/dist/app-frame.d.ts.map +1 -1
- package/dist/app-frame.js +377 -625
- package/dist/app-frame.js.map +1 -1
- package/dist/browsable-list.d.ts +12 -0
- package/dist/browsable-list.d.ts.map +1 -1
- package/dist/browsable-list.js +17 -6
- package/dist/browsable-list.js.map +1 -1
- package/dist/canvas.d.ts.map +1 -1
- package/dist/canvas.js +27 -7
- package/dist/canvas.js.map +1 -1
- package/dist/collection-surface.d.ts +8 -0
- package/dist/collection-surface.d.ts.map +1 -1
- package/dist/collection-surface.js +72 -8
- package/dist/collection-surface.js.map +1 -1
- package/dist/css/text-style.d.ts +2 -0
- package/dist/css/text-style.d.ts.map +1 -1
- package/dist/css/text-style.js +18 -8
- package/dist/css/text-style.js.map +1 -1
- package/dist/debug-overlay.d.ts +19 -0
- package/dist/debug-overlay.d.ts.map +1 -0
- package/dist/debug-overlay.js +25 -0
- package/dist/debug-overlay.js.map +1 -0
- package/dist/design-language.d.ts.map +1 -1
- package/dist/design-language.js +4 -5
- package/dist/design-language.js.map +1 -1
- package/dist/driver.d.ts +102 -0
- package/dist/driver.d.ts.map +1 -1
- package/dist/driver.js +259 -19
- package/dist/driver.js.map +1 -1
- package/dist/file-picker.d.ts.map +1 -1
- package/dist/file-picker.js +2 -2
- package/dist/file-picker.js.map +1 -1
- package/dist/flex.d.ts.map +1 -1
- package/dist/flex.js +6 -6
- package/dist/flex.js.map +1 -1
- package/dist/focus-area.d.ts +9 -1
- package/dist/focus-area.d.ts.map +1 -1
- package/dist/focus-area.js +52 -11
- package/dist/focus-area.js.map +1 -1
- package/dist/grid.d.ts +2 -2
- package/dist/grid.d.ts.map +1 -1
- package/dist/grid.js +11 -148
- package/dist/grid.js.map +1 -1
- package/dist/help.d.ts +2 -0
- package/dist/help.d.ts.map +1 -1
- package/dist/help.js +6 -4
- package/dist/help.js.map +1 -1
- package/dist/icon-presentation.d.ts +10 -0
- package/dist/icon-presentation.d.ts.map +1 -0
- package/dist/icon-presentation.js +12 -0
- package/dist/icon-presentation.js.map +1 -0
- package/dist/index.d.ts +14 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -5
- package/dist/index.js.map +1 -1
- package/dist/layout-preset.d.ts +1 -1
- package/dist/layout-preset.d.ts.map +1 -1
- package/dist/motion/reconciler.d.ts +6 -2
- package/dist/motion/reconciler.d.ts.map +1 -1
- package/dist/motion/reconciler.js +40 -10
- package/dist/motion/reconciler.js.map +1 -1
- package/dist/motion/types.d.ts +3 -1
- package/dist/motion/types.d.ts.map +1 -1
- package/dist/navigable-table.d.ts +9 -10
- package/dist/navigable-table.d.ts.map +1 -1
- package/dist/navigable-table.js +33 -14
- package/dist/navigable-table.js.map +1 -1
- package/dist/notification.d.ts +15 -0
- package/dist/notification.d.ts.map +1 -1
- package/dist/notification.js +98 -29
- package/dist/notification.js.map +1 -1
- package/dist/overlay.d.ts.map +1 -1
- package/dist/overlay.js +40 -14
- package/dist/overlay.js.map +1 -1
- package/dist/pager.d.ts +3 -1
- package/dist/pager.d.ts.map +1 -1
- package/dist/pager.js +4 -0
- package/dist/pager.js.map +1 -1
- package/dist/pipeline/middleware/grayscale.d.ts.map +1 -1
- package/dist/pipeline/middleware/grayscale.js +5 -5
- package/dist/pipeline/middleware/grayscale.js.map +1 -1
- package/dist/pipeline/middleware/motion.js +2 -2
- package/dist/pipeline/middleware/motion.js.map +1 -1
- package/dist/pipeline/middleware/surface-shaders.d.ts +37 -0
- package/dist/pipeline/middleware/surface-shaders.d.ts.map +1 -0
- package/dist/pipeline/middleware/surface-shaders.js +164 -0
- package/dist/pipeline/middleware/surface-shaders.js.map +1 -0
- package/dist/pipeline/pipeline.d.ts +29 -1
- package/dist/pipeline/pipeline.d.ts.map +1 -1
- package/dist/pipeline/pipeline.js +86 -23
- package/dist/pipeline/pipeline.js.map +1 -1
- package/dist/runtime.d.ts +19 -0
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +183 -30
- package/dist/runtime.js.map +1 -1
- package/dist/split-pane.d.ts +2 -2
- package/dist/split-pane.d.ts.map +1 -1
- package/dist/split-pane.js +28 -49
- package/dist/split-pane.js.map +1 -1
- package/dist/subapp/mount.d.ts +17 -0
- package/dist/subapp/mount.d.ts.map +1 -1
- package/dist/subapp/mount.js +13 -0
- package/dist/subapp/mount.js.map +1 -1
- package/dist/surface-layout.d.ts +8 -3
- package/dist/surface-layout.d.ts.map +1 -1
- package/dist/surface-layout.js +27 -12
- package/dist/surface-layout.js.map +1 -1
- package/dist/view-output.js +2 -2
- package/dist/view-output.js.map +1 -1
- package/dist/viewport.d.ts +13 -1
- package/dist/viewport.d.ts.map +1 -1
- package/dist/viewport.js +33 -11
- package/dist/viewport.js.map +1 -1
- package/package.json +3 -3
package/dist/split-pane.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* solving for horizontal (`row`) and vertical (`column`) splits.
|
|
6
6
|
*/
|
|
7
7
|
import { fitBlock } from './layout-utils.js';
|
|
8
|
-
import { createSurface, graphemeClusterWidth, graphemeWidth, segmentGraphemes, } from '@flyingrobots/bijou';
|
|
8
|
+
import { createSurface, graphemeClusterWidth, graphemeWidth, sanitizeNonNegativeInt, solveSplitAxisSizes, solveSplitPaneRects, segmentGraphemes, } from '@flyingrobots/bijou';
|
|
9
9
|
import { placeSurface } from './surface-layout.js';
|
|
10
10
|
/**
|
|
11
11
|
* Create split-pane state.
|
|
@@ -32,16 +32,23 @@ export function splitPaneSetRatio(state, ratio) {
|
|
|
32
32
|
* Resize pane A by `delta` main-axis units and derive the new ratio.
|
|
33
33
|
*/
|
|
34
34
|
export function splitPaneResizeBy(state, delta, limits) {
|
|
35
|
-
const
|
|
36
|
-
const
|
|
35
|
+
const safeDelta = Number.isFinite(delta) ? Math.trunc(delta) : 0;
|
|
36
|
+
const dividerSize = sanitizeNonNegativeInt(limits.dividerSize, 1);
|
|
37
|
+
const total = sanitizeNonNegativeInt(limits.total, 0);
|
|
38
|
+
const available = Math.max(0, total - dividerSize);
|
|
37
39
|
if (available <= 0)
|
|
38
40
|
return { ...state, ratio: 0 };
|
|
39
|
-
const minA =
|
|
40
|
-
const minB =
|
|
41
|
-
const
|
|
41
|
+
const minA = sanitizeNonNegativeInt(limits.minA, 0);
|
|
42
|
+
const minB = sanitizeNonNegativeInt(limits.minB, 0);
|
|
43
|
+
const { paneA: currA } = solveSplitAxisSizes({
|
|
44
|
+
available,
|
|
45
|
+
ratio: state.ratio,
|
|
46
|
+
minA,
|
|
47
|
+
minB,
|
|
48
|
+
});
|
|
42
49
|
const maxA = Math.max(0, available - Math.min(minB, available));
|
|
43
50
|
const clampedMinA = Math.min(minA, maxA);
|
|
44
|
-
const nextA = clamp(currA +
|
|
51
|
+
const nextA = clamp(currA + safeDelta, clampedMinA, maxA);
|
|
45
52
|
return { ...state, ratio: nextA / available };
|
|
46
53
|
}
|
|
47
54
|
/**
|
|
@@ -66,27 +73,19 @@ export function splitPaneFocusPrev(state) {
|
|
|
66
73
|
* Solve split-pane geometry for the provided bounds.
|
|
67
74
|
*/
|
|
68
75
|
export function splitPaneLayout(state, options) {
|
|
69
|
-
const
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
return {
|
|
79
|
-
paneA: { row: 0, col: 0, width: a, height },
|
|
80
|
-
divider: { row: 0, col: a, width: dividerSize, height },
|
|
81
|
-
paneB: { row: 0, col: a + dividerSize, width: b, height },
|
|
82
|
-
};
|
|
83
|
-
}
|
|
84
|
-
const available = Math.max(0, height - dividerSize);
|
|
85
|
-
const [a, b] = solveSplit(available, state.ratio, minA, minB);
|
|
76
|
+
const layout = solveSplitPaneRects({
|
|
77
|
+
direction: options.direction,
|
|
78
|
+
width: options.width,
|
|
79
|
+
height: options.height,
|
|
80
|
+
ratio: state.ratio,
|
|
81
|
+
minA: options.minA,
|
|
82
|
+
minB: options.minB,
|
|
83
|
+
dividerSize: options.dividerSize,
|
|
84
|
+
});
|
|
86
85
|
return {
|
|
87
|
-
paneA: { row:
|
|
88
|
-
divider: { row:
|
|
89
|
-
paneB: { row:
|
|
86
|
+
paneA: { row: layout.paneA.y, col: layout.paneA.x, width: layout.paneA.width, height: layout.paneA.height },
|
|
87
|
+
divider: { row: layout.divider.y, col: layout.divider.x, width: layout.divider.width, height: layout.divider.height },
|
|
88
|
+
paneB: { row: layout.paneB.y, col: layout.paneB.x, width: layout.paneB.width, height: layout.paneB.height },
|
|
90
89
|
};
|
|
91
90
|
}
|
|
92
91
|
/**
|
|
@@ -114,8 +113,8 @@ export function splitPane(state, options) {
|
|
|
114
113
|
* Render a split-pane surface.
|
|
115
114
|
*/
|
|
116
115
|
export function splitPaneSurface(state, options) {
|
|
117
|
-
const width =
|
|
118
|
-
const height =
|
|
116
|
+
const width = sanitizeNonNegativeInt(options.width, 0);
|
|
117
|
+
const height = sanitizeNonNegativeInt(options.height, 0);
|
|
119
118
|
if (width === 0 || height === 0)
|
|
120
119
|
return createSurface(0, 0);
|
|
121
120
|
const direction = options.direction ?? 'row';
|
|
@@ -139,26 +138,6 @@ export function splitPaneSurface(state, options) {
|
|
|
139
138
|
}
|
|
140
139
|
return result;
|
|
141
140
|
}
|
|
142
|
-
/** Divide available space between two panes, respecting ratio and minimum constraints. */
|
|
143
|
-
function solveSplit(available, ratio, minA, minB) {
|
|
144
|
-
if (available <= 0)
|
|
145
|
-
return [0, 0];
|
|
146
|
-
// Priority: minB > minA when they conflict (B keeps its minimum first).
|
|
147
|
-
const maxAFromMinB = Math.max(0, available - Math.min(minB, available));
|
|
148
|
-
// A's minimum cannot exceed the maximum that still satisfies B's minimum.
|
|
149
|
-
const clampedMinA = Math.min(minA, maxAFromMinB);
|
|
150
|
-
// Ratio target is clamped to feasible bounds after applying constraints.
|
|
151
|
-
let desiredA = Math.round(clampRatio(ratio) * available);
|
|
152
|
-
desiredA = clamp(desiredA, clampedMinA, maxAFromMinB);
|
|
153
|
-
// Guardrail: if rounding drift undercuts B's minimum, pull A back into range.
|
|
154
|
-
const desiredB = available - desiredA;
|
|
155
|
-
if (desiredB < Math.min(minB, available)) {
|
|
156
|
-
desiredA = Math.max(clampedMinA, available - Math.min(minB, available));
|
|
157
|
-
}
|
|
158
|
-
const a = clamp(desiredA, 0, available);
|
|
159
|
-
const b = Math.max(0, available - a);
|
|
160
|
-
return [a, b];
|
|
161
|
-
}
|
|
162
141
|
/** Normalize a ratio to the 0–1 range, defaulting non-finite values to 0.5. */
|
|
163
142
|
function clampRatio(ratio) {
|
|
164
143
|
if (!Number.isFinite(ratio))
|
package/dist/split-pane.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"split-pane.js","sourceRoot":"","sources":["../src/split-pane.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,EACL,aAAa,EACb,oBAAoB,EACpB,aAAa,EACb,gBAAgB,
|
|
1
|
+
{"version":3,"file":"split-pane.js","sourceRoot":"","sources":["../src/split-pane.ts"],"names":[],"mappings":"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"}
|
package/dist/subapp/mount.d.ts
CHANGED
|
@@ -33,6 +33,13 @@ export interface MountedApp<SubMsg> {
|
|
|
33
33
|
*/
|
|
34
34
|
cmds: Cmd<SubMsg>[];
|
|
35
35
|
}
|
|
36
|
+
export type SubAppAdapterCases<ParentMsg, SubMsg extends {
|
|
37
|
+
readonly type: string;
|
|
38
|
+
}> = {
|
|
39
|
+
readonly [K in SubMsg['type']]: (msg: Extract<SubMsg, {
|
|
40
|
+
type: K;
|
|
41
|
+
}>) => ParentMsg;
|
|
42
|
+
};
|
|
36
43
|
/**
|
|
37
44
|
* Mount a sub-app, returning its rendered surface and any pending commands.
|
|
38
45
|
*
|
|
@@ -45,6 +52,16 @@ export interface MountedApp<SubMsg> {
|
|
|
45
52
|
* @returns A tuple of `[Surface | LayoutNode, mapped Cmds]`.
|
|
46
53
|
*/
|
|
47
54
|
export declare function mount<SubModel, SubMsg, ParentMsg>(app: App<SubModel, SubMsg>, options: MountOptions<SubModel, SubMsg, ParentMsg>): [ViewOutput, Cmd<ParentMsg>[]];
|
|
55
|
+
/**
|
|
56
|
+
* Build an exhaustive discriminant-based sub-app message mapper.
|
|
57
|
+
*
|
|
58
|
+
* The returned function matches the `onMsg` signature expected by
|
|
59
|
+
* `initSubApp()`, `updateSubApp()`, and `mount()`, while TypeScript enforces
|
|
60
|
+
* that every `SubMsg['type']` variant is covered up front.
|
|
61
|
+
*/
|
|
62
|
+
export declare function createSubAppAdapter<ParentMsg, SubMsg extends {
|
|
63
|
+
readonly type: string;
|
|
64
|
+
}>(cases: SubAppAdapterCases<ParentMsg, SubMsg>): (msg: SubMsg) => ParentMsg;
|
|
48
65
|
export interface SubAppOptions<SubMsg, ParentMsg> {
|
|
49
66
|
/** Function to map a sub-app message into a parent message. */
|
|
50
67
|
onMsg: (msg: SubMsg) => ParentMsg;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mount.d.ts","sourceRoot":"","sources":["../../src/subapp/mount.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,GAAG,EAAc,MAAM,aAAa,CAAC;AAExD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAEpD;;;;;;GAMG;AACH,MAAM,WAAW,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS;IACvD,wCAAwC;IACxC,KAAK,EAAE,QAAQ,CAAC;IAChB,+DAA+D;IAC/D,KAAK,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,SAAS,CAAC;IAClC;;;OAGG;IACH,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC,MAAM,CAAC,KAAK,GAAG,CAAC,SAAS,CAAC,CAAC;CAC/C;AAED;;;;;GAKG;AACH,MAAM,WAAW,UAAU,CAAC,MAAM;IAChC,0DAA0D;IAC1D,aAAa,EAAE,UAAU,CAAC;IAC1B;;;OAGG;IACH,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;CACrB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAC/C,GAAG,EAAE,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,EAC1B,OAAO,EAAE,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,CAAC,GACjD,CAAC,UAAU,EAAE,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,CAMhC;AAED,MAAM,WAAW,aAAa,CAAC,MAAM,EAAE,SAAS;IAC9C,+DAA+D;IAC/D,KAAK,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,SAAS,CAAC;IAClC;;;OAGG;IACH,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC,MAAM,CAAC,KAAK,GAAG,CAAC,SAAS,CAAC,CAAC;CAC/C;AAED,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EACpD,GAAG,EAAE,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,EAC1B,OAAO,EAAE,aAAa,CAAC,MAAM,EAAE,SAAS,CAAC,GACxC,CAAC,QAAQ,EAAE,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,CAG9B;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EACtD,GAAG,EAAE,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,EAC1B,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,QAAQ,EACf,OAAO,EAAE,aAAa,CAAC,MAAM,EAAE,SAAS,CAAC,GACxC,CAAC,QAAQ,EAAE,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,CAG9B;AAED;;;;;;GAMG;AACH,wBAAgB,OAAO,CAAC,MAAM,EAAE,SAAS,EACvC,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,EACnB,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,SAAS,GACjC,GAAG,CAAC,SAAS,CAAC,EAAE,CAElB"}
|
|
1
|
+
{"version":3,"file":"mount.d.ts","sourceRoot":"","sources":["../../src/subapp/mount.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,GAAG,EAAc,MAAM,aAAa,CAAC;AAExD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAEpD;;;;;;GAMG;AACH,MAAM,WAAW,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS;IACvD,wCAAwC;IACxC,KAAK,EAAE,QAAQ,CAAC;IAChB,+DAA+D;IAC/D,KAAK,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,SAAS,CAAC;IAClC;;;OAGG;IACH,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC,MAAM,CAAC,KAAK,GAAG,CAAC,SAAS,CAAC,CAAC;CAC/C;AAED;;;;;GAKG;AACH,MAAM,WAAW,UAAU,CAAC,MAAM;IAChC,0DAA0D;IAC1D,aAAa,EAAE,UAAU,CAAC;IAC1B;;;OAGG;IACH,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;CACrB;AAED,MAAM,MAAM,kBAAkB,CAAC,SAAS,EAAE,MAAM,SAAS;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,IAAI;IACpF,QAAQ,EAAE,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,MAAM,EAAE;QAAE,IAAI,EAAE,CAAC,CAAA;KAAE,CAAC,KAAK,SAAS;CACjF,CAAC;AAEF;;;;;;;;;;GAUG;AACH,wBAAgB,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAC/C,GAAG,EAAE,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,EAC1B,OAAO,EAAE,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,CAAC,GACjD,CAAC,UAAU,EAAE,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,CAMhC;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,SAAS;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EACrF,KAAK,EAAE,kBAAkB,CAAC,SAAS,EAAE,MAAM,CAAC,GAC3C,CAAC,GAAG,EAAE,MAAM,KAAK,SAAS,CAK5B;AAED,MAAM,WAAW,aAAa,CAAC,MAAM,EAAE,SAAS;IAC9C,+DAA+D;IAC/D,KAAK,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,SAAS,CAAC;IAClC;;;OAGG;IACH,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC,MAAM,CAAC,KAAK,GAAG,CAAC,SAAS,CAAC,CAAC;CAC/C;AAED,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EACpD,GAAG,EAAE,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,EAC1B,OAAO,EAAE,aAAa,CAAC,MAAM,EAAE,SAAS,CAAC,GACxC,CAAC,QAAQ,EAAE,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,CAG9B;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EACtD,GAAG,EAAE,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,EAC1B,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,QAAQ,EACf,OAAO,EAAE,aAAa,CAAC,MAAM,EAAE,SAAS,CAAC,GACxC,CAAC,QAAQ,EAAE,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,CAG9B;AAED;;;;;;GAMG;AACH,wBAAgB,OAAO,CAAC,MAAM,EAAE,SAAS,EACvC,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,EACnB,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,SAAS,GACjC,GAAG,CAAC,SAAS,CAAC,EAAE,CAElB"}
|
package/dist/subapp/mount.js
CHANGED
|
@@ -15,6 +15,19 @@ export function mount(app, options) {
|
|
|
15
15
|
const surfaceOrNode = app.view(model);
|
|
16
16
|
return [surfaceOrNode, []];
|
|
17
17
|
}
|
|
18
|
+
/**
|
|
19
|
+
* Build an exhaustive discriminant-based sub-app message mapper.
|
|
20
|
+
*
|
|
21
|
+
* The returned function matches the `onMsg` signature expected by
|
|
22
|
+
* `initSubApp()`, `updateSubApp()`, and `mount()`, while TypeScript enforces
|
|
23
|
+
* that every `SubMsg['type']` variant is covered up front.
|
|
24
|
+
*/
|
|
25
|
+
export function createSubAppAdapter(cases) {
|
|
26
|
+
return (msg) => {
|
|
27
|
+
const handler = cases[msg.type];
|
|
28
|
+
return handler(msg);
|
|
29
|
+
};
|
|
30
|
+
}
|
|
18
31
|
export function initSubApp(app, options) {
|
|
19
32
|
const [model, cmds] = app.init();
|
|
20
33
|
return [model, mapSubAppCmds(cmds, options)];
|
package/dist/subapp/mount.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mount.js","sourceRoot":"","sources":["../../src/subapp/mount.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"mount.js","sourceRoot":"","sources":["../../src/subapp/mount.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AA0C3C;;;;;;;;;;GAUG;AACH,MAAM,UAAU,KAAK,CACnB,GAA0B,EAC1B,OAAkD;IAElD,MAAM,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC;IAE1B,MAAM,aAAa,GAAG,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAEtC,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;AAC7B,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,mBAAmB,CACjC,KAA4C;IAE5C,OAAO,CAAC,GAAG,EAAE,EAAE;QACb,MAAM,OAAO,GAAG,KAAK,CAAC,GAAG,CAAC,IAAmD,CAA+B,CAAC;QAC7G,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC;IACtB,CAAC,CAAC;AACJ,CAAC;AAYD,MAAM,UAAU,UAAU,CACxB,GAA0B,EAC1B,OAAyC;IAEzC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;IACjC,OAAO,CAAC,KAAK,EAAE,aAAa,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,YAAY,CAC1B,GAA0B,EAC1B,GAAW,EACX,KAAe,EACf,OAAyC;IAEzC,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IACjD,OAAO,CAAC,SAAS,EAAE,aAAa,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;AACnD,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,OAAO,CACrB,IAAmB,EACnB,MAAkC;IAElC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,YAAY,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC;AACtD,CAAC;AAED,SAAS,aAAa,CACpB,IAAmB,EACnB,OAAyC;IAEzC,IAAI,OAAO,CAAC,MAAM,IAAI,IAAI,EAAE,CAAC;QAC3B,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,MAAO,CAAC,GAAG,CAAC,CAAC,CAAC;IACjD,CAAC;IACD,OAAO,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;AACtC,CAAC;AAED;;GAEG;AACH,SAAS,YAAY,CACnB,GAAgB,EAChB,MAAkC;IAElC,OAAO,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE;QAC1B,8DAA8D;QAC9D,MAAM,UAAU,GAAG,CAAC,MAAc,EAAE,EAAE;YACpC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;QACvB,CAAC,CAAC;QAEF,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;QAE3C,sDAAsD;QACtD,6CAA6C;QAC7C,IAAI,MAAM,KAAK,SAAS;YAAE,OAAO,SAAS,CAAC;QAC3C,IAAI,OAAO,MAAM,KAAK,QAAQ;YAAE,OAAO,MAAoB,CAAC,CAAC,OAAO;QACpE,IAAI,YAAY,CAAC,MAAM,CAAC;YAAE,OAAO,MAAM,CAAC;QACxC,OAAO,MAAM,CAAC,MAAgB,CAAC,CAAC;IAClC,CAAC,CAAC;AACJ,CAAC"}
|
package/dist/surface-layout.d.ts
CHANGED
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
import { type Surface } from '@flyingrobots/bijou';
|
|
2
2
|
import type { PlaceOptions } from './layout.js';
|
|
3
|
+
export type SurfaceContent = string | Surface;
|
|
4
|
+
/**
|
|
5
|
+
* Bridge raw text into surface-land at the composition edge.
|
|
6
|
+
*/
|
|
7
|
+
export declare function contentSurface(content: string): Surface;
|
|
3
8
|
/**
|
|
4
9
|
* Vertical stack for surfaces.
|
|
5
10
|
*/
|
|
6
|
-
export declare function vstackSurface(...
|
|
11
|
+
export declare function vstackSurface(...content: SurfaceContent[]): Surface;
|
|
7
12
|
/**
|
|
8
13
|
* Horizontal stack for surfaces with an optional gap.
|
|
9
14
|
*/
|
|
10
|
-
export declare function hstackSurface(gap: number, ...
|
|
15
|
+
export declare function hstackSurface(gap: number, ...content: SurfaceContent[]): Surface;
|
|
11
16
|
/**
|
|
12
17
|
* Place a surface within a fixed-size rectangle using horizontal and vertical alignment.
|
|
13
18
|
*
|
|
@@ -15,5 +20,5 @@ export declare function hstackSurface(gap: number, ...surfaces: Surface[]): Surf
|
|
|
15
20
|
* region, mirroring the string-based `place()` behavior. When the content is smaller than
|
|
16
21
|
* the target rectangle, it is aligned within the blank result surface.
|
|
17
22
|
*/
|
|
18
|
-
export declare function placeSurface(content:
|
|
23
|
+
export declare function placeSurface(content: SurfaceContent, options: PlaceOptions): Surface;
|
|
19
24
|
//# sourceMappingURL=surface-layout.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"surface-layout.d.ts","sourceRoot":"","sources":["../src/surface-layout.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"surface-layout.d.ts","sourceRoot":"","sources":["../src/surface-layout.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,OAAO,EACb,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,OAAO,CAAC;AAE9C;;GAEG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAKvD;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,GAAG,OAAO,EAAE,cAAc,EAAE,GAAG,OAAO,CAgBnE;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,OAAO,EAAE,cAAc,EAAE,GAAG,OAAO,CAiBhF;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,cAAc,EAAE,OAAO,EAAE,YAAY,GAAG,OAAO,CAkDpF"}
|
package/dist/surface-layout.js
CHANGED
|
@@ -1,8 +1,18 @@
|
|
|
1
|
-
import { createSurface } from '@flyingrobots/bijou';
|
|
1
|
+
import { createSurface, graphemeWidth, parseAnsiToSurface, stripAnsi, } from '@flyingrobots/bijou';
|
|
2
|
+
/**
|
|
3
|
+
* Bridge raw text into surface-land at the composition edge.
|
|
4
|
+
*/
|
|
5
|
+
export function contentSurface(content) {
|
|
6
|
+
const lines = content.split(/\r?\n/);
|
|
7
|
+
const width = Math.max(1, ...lines.map((line) => graphemeWidth(stripAnsi(line))));
|
|
8
|
+
const height = Math.max(1, lines.length);
|
|
9
|
+
return parseAnsiToSurface(content, width, height);
|
|
10
|
+
}
|
|
2
11
|
/**
|
|
3
12
|
* Vertical stack for surfaces.
|
|
4
13
|
*/
|
|
5
|
-
export function vstackSurface(...
|
|
14
|
+
export function vstackSurface(...content) {
|
|
15
|
+
const surfaces = content.map(resolveSurfaceContent);
|
|
6
16
|
if (surfaces.length === 0)
|
|
7
17
|
return createSurface(0, 0);
|
|
8
18
|
const width = Math.max(...surfaces.map(s => s.width));
|
|
@@ -18,7 +28,8 @@ export function vstackSurface(...surfaces) {
|
|
|
18
28
|
/**
|
|
19
29
|
* Horizontal stack for surfaces with an optional gap.
|
|
20
30
|
*/
|
|
21
|
-
export function hstackSurface(gap, ...
|
|
31
|
+
export function hstackSurface(gap, ...content) {
|
|
32
|
+
const surfaces = content.map(resolveSurfaceContent);
|
|
22
33
|
if (surfaces.length === 0)
|
|
23
34
|
return createSurface(0, 0);
|
|
24
35
|
const width = surfaces.reduce((acc, s) => acc + s.width, 0) + (surfaces.length - 1) * gap;
|
|
@@ -40,6 +51,7 @@ export function hstackSurface(gap, ...surfaces) {
|
|
|
40
51
|
* the target rectangle, it is aligned within the blank result surface.
|
|
41
52
|
*/
|
|
42
53
|
export function placeSurface(content, options) {
|
|
54
|
+
const surfaceContent = resolveSurfaceContent(content);
|
|
43
55
|
const width = Math.max(0, Math.floor(options.width));
|
|
44
56
|
const height = Math.max(0, Math.floor(options.height));
|
|
45
57
|
const hAlign = options.hAlign ?? 'left';
|
|
@@ -47,16 +59,16 @@ export function placeSurface(content, options) {
|
|
|
47
59
|
if (width === 0 || height === 0)
|
|
48
60
|
return createSurface(0, 0);
|
|
49
61
|
const result = createSurface(width, height);
|
|
50
|
-
const clipWidth = Math.min(width,
|
|
51
|
-
const clipHeight = Math.min(height,
|
|
62
|
+
const clipWidth = Math.min(width, surfaceContent.width);
|
|
63
|
+
const clipHeight = Math.min(height, surfaceContent.height);
|
|
52
64
|
let col = 0;
|
|
53
|
-
if (
|
|
65
|
+
if (surfaceContent.width < width) {
|
|
54
66
|
switch (hAlign) {
|
|
55
67
|
case 'right':
|
|
56
|
-
col = width -
|
|
68
|
+
col = width - surfaceContent.width;
|
|
57
69
|
break;
|
|
58
70
|
case 'center':
|
|
59
|
-
col = Math.floor((width -
|
|
71
|
+
col = Math.floor((width - surfaceContent.width) / 2);
|
|
60
72
|
break;
|
|
61
73
|
case 'left':
|
|
62
74
|
default:
|
|
@@ -65,13 +77,13 @@ export function placeSurface(content, options) {
|
|
|
65
77
|
}
|
|
66
78
|
}
|
|
67
79
|
let row = 0;
|
|
68
|
-
if (
|
|
80
|
+
if (surfaceContent.height < height) {
|
|
69
81
|
switch (vAlign) {
|
|
70
82
|
case 'bottom':
|
|
71
|
-
row = height -
|
|
83
|
+
row = height - surfaceContent.height;
|
|
72
84
|
break;
|
|
73
85
|
case 'middle':
|
|
74
|
-
row = Math.floor((height -
|
|
86
|
+
row = Math.floor((height - surfaceContent.height) / 2);
|
|
75
87
|
break;
|
|
76
88
|
case 'top':
|
|
77
89
|
default:
|
|
@@ -80,8 +92,11 @@ export function placeSurface(content, options) {
|
|
|
80
92
|
}
|
|
81
93
|
}
|
|
82
94
|
if (clipWidth > 0 && clipHeight > 0) {
|
|
83
|
-
result.blit(
|
|
95
|
+
result.blit(surfaceContent, Math.max(0, col), Math.max(0, row), 0, 0, clipWidth, clipHeight);
|
|
84
96
|
}
|
|
85
97
|
return result;
|
|
86
98
|
}
|
|
99
|
+
function resolveSurfaceContent(content) {
|
|
100
|
+
return typeof content === 'string' ? contentSurface(content) : content;
|
|
101
|
+
}
|
|
87
102
|
//# sourceMappingURL=surface-layout.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"surface-layout.js","sourceRoot":"","sources":["../src/surface-layout.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"surface-layout.js","sourceRoot":"","sources":["../src/surface-layout.ts"],"names":[],"mappings":"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"}
|
package/dist/view-output.js
CHANGED
|
@@ -25,7 +25,7 @@ export function normalizeViewOutputInto(output, size, scratch) {
|
|
|
25
25
|
};
|
|
26
26
|
}
|
|
27
27
|
if (!isLayoutNodeView(output)) {
|
|
28
|
-
throw new Error('Bijou runtime views must return a Surface or LayoutNode. Raw strings are no longer supported; convert them
|
|
28
|
+
throw new Error('Bijou runtime views must return a Surface or LayoutNode. Raw strings are no longer supported; convert them with contentSurface(...), parseAnsiToSurface(...), or stringToSurface(...).');
|
|
29
29
|
}
|
|
30
30
|
const localization = localizeLayout(output);
|
|
31
31
|
const width = Math.max(size.width, localization.width, 0);
|
|
@@ -47,7 +47,7 @@ export function wrapViewOutputAsLayoutRoot(output, _size) {
|
|
|
47
47
|
};
|
|
48
48
|
}
|
|
49
49
|
if (!isLayoutNodeView(output)) {
|
|
50
|
-
throw new Error('Bijou runtime views must return a Surface or LayoutNode. Raw strings are no longer supported; convert them
|
|
50
|
+
throw new Error('Bijou runtime views must return a Surface or LayoutNode. Raw strings are no longer supported; convert them with contentSurface(...), parseAnsiToSurface(...), or stringToSurface(...).');
|
|
51
51
|
}
|
|
52
52
|
return localizeLayoutNode(output).node;
|
|
53
53
|
}
|
package/dist/view-output.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"view-output.js","sourceRoot":"","sources":["../src/view-output.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,GAGd,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,yBAAyB,EAAE,MAAM,0BAA0B,CAAC;AAczG,MAAM,UAAU,aAAa,CAAC,KAAc;IAC1C,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,IAAI,KAAK,CAAC;AACzE,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,KAAc;IAC7C,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,MAAM,IAAI,KAAK,IAAI,UAAU,IAAI,KAAK,CAAC;AAC/F,CAAC;AAED,MAAM,UAAU,mBAAmB,CACjC,MAAkB,EAClB,IAAkB;IAElB,OAAO,uBAAuB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,uBAAuB,CACrC,MAAkB,EAClB,IAAkB,EAClB,OAAiB;IAEjB,IAAI,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC;QAC1B,IAAI,OAAO,IAAI,IAAI,EAAE,CAAC;YACpB,OAAO;gBACL,IAAI,EAAE,SAAS;gBACf,OAAO,EAAE,MAAM;aAChB,CAAC;QACJ,CAAC;QACD,MAAM,OAAO,GAAG,wBAAwB,CACtC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,EACrC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,EACvC,OAAO,CACR,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QAC3B,OAAO;YACL,IAAI,EAAE,SAAS;YACf,OAAO;SACR,CAAC;IACJ,CAAC;IAED,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE,CAAC;QAC9B,MAAM,IAAI,KAAK,CACb,
|
|
1
|
+
{"version":3,"file":"view-output.js","sourceRoot":"","sources":["../src/view-output.ts"],"names":[],"mappings":"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"}
|
package/dist/viewport.d.ts
CHANGED
|
@@ -4,7 +4,9 @@
|
|
|
4
4
|
* Renders a visible window into content that may be larger than the
|
|
5
5
|
* available screen space, with optional scrollbar indicator.
|
|
6
6
|
*/
|
|
7
|
-
import { clipToWidth as coreClipToWidth, type LayoutNode, type Surface } from '@flyingrobots/bijou';
|
|
7
|
+
import { clipToWidth as coreClipToWidth, type Cell, type LayoutNode, type Surface } from '@flyingrobots/bijou';
|
|
8
|
+
/** Scrollbar ownership model for the viewport edge. */
|
|
9
|
+
export type ScrollbarMode = 'gutter' | 'overlay';
|
|
8
10
|
/**
|
|
9
11
|
* Configuration for rendering a scrollable viewport window.
|
|
10
12
|
*/
|
|
@@ -21,6 +23,12 @@ export interface ViewportOptions {
|
|
|
21
23
|
readonly scrollX?: number;
|
|
22
24
|
/** Show a scrollbar track on the right edge. Default: true. */
|
|
23
25
|
readonly showScrollbar?: boolean;
|
|
26
|
+
/** Reserve a gutter column or overlay the rightmost content cell. Default: `'gutter'`. */
|
|
27
|
+
readonly scrollbarMode?: ScrollbarMode;
|
|
28
|
+
/** Character used for the scrollbar track in string rendering. Default: `'│'`. */
|
|
29
|
+
readonly scrollbarTrackChar?: string;
|
|
30
|
+
/** Character used for the scrollbar thumb in string rendering. Default: `'█'`. */
|
|
31
|
+
readonly scrollbarThumbChar?: string;
|
|
24
32
|
}
|
|
25
33
|
/**
|
|
26
34
|
* Configuration for rendering a viewport directly into a Surface.
|
|
@@ -28,6 +36,10 @@ export interface ViewportOptions {
|
|
|
28
36
|
export interface ViewportSurfaceOptions extends Omit<ViewportOptions, 'content'> {
|
|
29
37
|
/** Full content payload, either plain/ANSI text, a pre-rendered surface, or a layout tree. */
|
|
30
38
|
readonly content: ViewportContent;
|
|
39
|
+
/** Cell used for the scrollbar track in surface rendering. */
|
|
40
|
+
readonly scrollbarTrackCell?: Cell;
|
|
41
|
+
/** Cell used for the scrollbar thumb in surface rendering. */
|
|
42
|
+
readonly scrollbarThumbCell?: Cell;
|
|
31
43
|
}
|
|
32
44
|
/** Content payload that can be masked by a viewport. */
|
|
33
45
|
export type ViewportContent = string | Surface | LayoutNode;
|
package/dist/viewport.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"viewport.d.ts","sourceRoot":"","sources":["../src/viewport.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAML,WAAW,IAAI,eAAe,EAC9B,KAAK,UAAU,EACf,KAAK,OAAO,EACb,MAAM,qBAAqB,CAAC;AAO7B;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,4EAA4E;IAC5E,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,8BAA8B;IAC9B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,mEAAmE;IACnE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,+DAA+D;IAC/D,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,mEAAmE;IACnE,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,+DAA+D;IAC/D,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"viewport.d.ts","sourceRoot":"","sources":["../src/viewport.ts"],"names":[],"mappings":"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"}
|
package/dist/viewport.js
CHANGED
|
@@ -186,6 +186,8 @@ export function tokenizeAnsi(str, width) {
|
|
|
186
186
|
const SCROLLBAR_TRACK = '│';
|
|
187
187
|
/** Character used for the scrollbar thumb (filled portion). */
|
|
188
188
|
const SCROLLBAR_THUMB = '█';
|
|
189
|
+
const SCROLLBAR_TRACK_CELL = { char: SCROLLBAR_TRACK, empty: false };
|
|
190
|
+
const SCROLLBAR_THUMB_CELL = { char: SCROLLBAR_THUMB, empty: false };
|
|
189
191
|
/**
|
|
190
192
|
* Render a vertical scrollbar as an array of single-character strings.
|
|
191
193
|
*
|
|
@@ -197,7 +199,7 @@ const SCROLLBAR_THUMB = '█';
|
|
|
197
199
|
* @param scrollY - Current vertical scroll offset.
|
|
198
200
|
* @returns Array of length `viewportHeight`, each element a single scrollbar character.
|
|
199
201
|
*/
|
|
200
|
-
function renderScrollbar(viewportHeight, totalLines, scrollY) {
|
|
202
|
+
function renderScrollbar(viewportHeight, totalLines, scrollY, trackChar = SCROLLBAR_TRACK, thumbChar = SCROLLBAR_THUMB) {
|
|
201
203
|
if (totalLines <= viewportHeight) {
|
|
202
204
|
// No scrolling needed — empty gutter
|
|
203
205
|
return Array.from({ length: viewportHeight }).fill(' ');
|
|
@@ -210,10 +212,25 @@ function renderScrollbar(viewportHeight, totalLines, scrollY) {
|
|
|
210
212
|
const thumbStart = Math.round(scrollFraction * (viewportHeight - thumbSize));
|
|
211
213
|
const bar = [];
|
|
212
214
|
for (let i = 0; i < viewportHeight; i++) {
|
|
213
|
-
bar.push(i >= thumbStart && i < thumbStart + thumbSize ?
|
|
215
|
+
bar.push(i >= thumbStart && i < thumbStart + thumbSize ? thumbChar : trackChar);
|
|
214
216
|
}
|
|
215
217
|
return bar;
|
|
216
218
|
}
|
|
219
|
+
function resolveViewportContentWidth(width, needsScrollbar, scrollbarMode) {
|
|
220
|
+
if (!needsScrollbar)
|
|
221
|
+
return width;
|
|
222
|
+
return scrollbarMode === 'overlay' ? width : Math.max(0, width - 1);
|
|
223
|
+
}
|
|
224
|
+
function overlayScrollbarChar(line, width, railChar) {
|
|
225
|
+
if (width <= 0)
|
|
226
|
+
return '';
|
|
227
|
+
if (width === 1)
|
|
228
|
+
return railChar;
|
|
229
|
+
const prefixWidth = width - 1;
|
|
230
|
+
const prefix = sliceAnsi(line, 0, prefixWidth);
|
|
231
|
+
const prefixVisible = visibleLength(prefix);
|
|
232
|
+
return prefix + ' '.repeat(Math.max(0, prefixWidth - prefixVisible)) + railChar;
|
|
233
|
+
}
|
|
217
234
|
// ---------------------------------------------------------------------------
|
|
218
235
|
// Viewport rendering
|
|
219
236
|
// ---------------------------------------------------------------------------
|
|
@@ -227,14 +244,13 @@ function renderScrollbar(viewportHeight, totalLines, scrollY) {
|
|
|
227
244
|
* @returns Rendered viewport string with lines joined by newlines.
|
|
228
245
|
*/
|
|
229
246
|
export function viewport(options) {
|
|
230
|
-
const { width, height, content, scrollY = 0, scrollX = 0, showScrollbar = true, } = options;
|
|
247
|
+
const { width, height, content, scrollY = 0, scrollX = 0, showScrollbar = true, scrollbarMode = 'gutter', scrollbarTrackChar = SCROLLBAR_TRACK, scrollbarThumbChar = SCROLLBAR_THUMB, } = options;
|
|
231
248
|
const allLines = content.split('\n');
|
|
232
249
|
const totalLines = allLines.length;
|
|
233
250
|
const maxScroll = Math.max(0, totalLines - height);
|
|
234
251
|
const clampedY = Math.max(0, Math.min(scrollY, maxScroll));
|
|
235
|
-
// Content width: leave 1 column for scrollbar if shown and needed
|
|
236
252
|
const needsScrollbar = showScrollbar && totalLines > height;
|
|
237
|
-
const contentWidth =
|
|
253
|
+
const contentWidth = resolveViewportContentWidth(width, needsScrollbar, scrollbarMode);
|
|
238
254
|
// Slice visible window
|
|
239
255
|
const visibleSlice = allLines.slice(clampedY, clampedY + height);
|
|
240
256
|
// Pad to fill viewport height if content is shorter
|
|
@@ -256,8 +272,10 @@ export function viewport(options) {
|
|
|
256
272
|
});
|
|
257
273
|
// Append scrollbar
|
|
258
274
|
if (needsScrollbar) {
|
|
259
|
-
const bar = renderScrollbar(height, totalLines, clampedY);
|
|
260
|
-
return rendered.map((line, i) =>
|
|
275
|
+
const bar = renderScrollbar(height, totalLines, clampedY, scrollbarTrackChar, scrollbarThumbChar);
|
|
276
|
+
return rendered.map((line, i) => (scrollbarMode === 'overlay'
|
|
277
|
+
? overlayScrollbarChar(line, width, bar[i])
|
|
278
|
+
: line + bar[i])).join('\n');
|
|
261
279
|
}
|
|
262
280
|
return rendered.join('\n');
|
|
263
281
|
}
|
|
@@ -273,7 +291,7 @@ export function viewport(options) {
|
|
|
273
291
|
* @returns Surface sized exactly to the requested viewport rectangle.
|
|
274
292
|
*/
|
|
275
293
|
export function viewportSurface(options) {
|
|
276
|
-
const { width, height, content, scrollY = 0, scrollX = 0, showScrollbar = true, } = options;
|
|
294
|
+
const { width, height, content, scrollY = 0, scrollX = 0, showScrollbar = true, scrollbarMode = 'gutter', scrollbarTrackChar = SCROLLBAR_TRACK, scrollbarThumbChar = SCROLLBAR_THUMB, scrollbarTrackCell = SCROLLBAR_TRACK_CELL, scrollbarThumbCell = SCROLLBAR_THUMB_CELL, } = options;
|
|
277
295
|
const safeWidth = Math.max(0, Math.floor(width));
|
|
278
296
|
const safeHeight = Math.max(0, Math.floor(height));
|
|
279
297
|
if (typeof content === 'string') {
|
|
@@ -284,6 +302,9 @@ export function viewportSurface(options) {
|
|
|
284
302
|
scrollY,
|
|
285
303
|
scrollX,
|
|
286
304
|
showScrollbar,
|
|
305
|
+
scrollbarMode,
|
|
306
|
+
scrollbarTrackChar,
|
|
307
|
+
scrollbarThumbChar,
|
|
287
308
|
}), safeWidth, safeHeight);
|
|
288
309
|
}
|
|
289
310
|
const normalizedContent = normalizeViewportContent(content);
|
|
@@ -292,15 +313,16 @@ export function viewportSurface(options) {
|
|
|
292
313
|
const maxScroll = Math.max(0, totalLines - safeHeight);
|
|
293
314
|
const clampedY = Math.max(0, Math.min(scrollY, maxScroll));
|
|
294
315
|
const needsScrollbar = showScrollbar && totalLines > safeHeight;
|
|
295
|
-
const contentWidth =
|
|
316
|
+
const contentWidth = resolveViewportContentWidth(safeWidth, needsScrollbar, scrollbarMode);
|
|
296
317
|
if (contentWidth > 0 && safeHeight > 0) {
|
|
297
318
|
result.blit(normalizedContent, 0, 0, Math.max(0, scrollX), clampedY, contentWidth, safeHeight);
|
|
298
319
|
}
|
|
299
320
|
if (needsScrollbar && safeWidth > 0) {
|
|
300
|
-
const bar = renderScrollbar(safeHeight, totalLines, clampedY);
|
|
321
|
+
const bar = renderScrollbar(safeHeight, totalLines, clampedY, scrollbarTrackChar, scrollbarThumbChar);
|
|
301
322
|
const scrollbarX = safeWidth - 1;
|
|
302
323
|
for (let y = 0; y < safeHeight; y++) {
|
|
303
|
-
|
|
324
|
+
const cell = bar[y] === scrollbarThumbChar ? scrollbarThumbCell : scrollbarTrackCell;
|
|
325
|
+
result.set(scrollbarX, y, { ...cell, char: bar[y], empty: false });
|
|
304
326
|
}
|
|
305
327
|
}
|
|
306
328
|
return result;
|