@flyingrobots/bijou-tui 3.0.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 +1 -5
- package/dist/app-frame-actions.d.ts.map +1 -1
- package/dist/app-frame-actions.js +23 -20
- 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 +106 -100
- package/dist/app-frame-render.js.map +1 -1
- package/dist/app-frame-types.d.ts +10 -1
- package/dist/app-frame-types.d.ts.map +1 -1
- package/dist/app-frame-types.js.map +1 -1
- package/dist/app-frame.d.ts +39 -2
- package/dist/app-frame.d.ts.map +1 -1
- package/dist/app-frame.js +222 -78
- 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/commands.d.ts.map +1 -1
- package/dist/commands.js +11 -3
- package/dist/commands.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 +10 -6
- package/dist/driver.d.ts.map +1 -1
- package/dist/driver.js +18 -17
- package/dist/driver.js.map +1 -1
- package/dist/eventbus.d.ts +5 -0
- package/dist/eventbus.d.ts.map +1 -1
- package/dist/eventbus.js +44 -7
- package/dist/eventbus.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 +19 -17
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +18 -14
- 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 +89 -0
- package/dist/notification.d.ts.map +1 -0
- package/dist/notification.js +821 -0
- package/dist/notification.js.map +1 -0
- package/dist/overlay.d.ts +24 -9
- 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 +79 -68
- 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 +32 -2
- package/dist/types.d.ts.map +1 -1
- 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 +4 -4
- 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
|
@@ -38,7 +38,7 @@ export interface RenderContext<PageModel, Msg> {
|
|
|
38
38
|
}
|
|
39
39
|
/** Output of a layout node render pass. */
|
|
40
40
|
export interface RenderResult {
|
|
41
|
-
readonly
|
|
41
|
+
readonly surface: import('@flyingrobots/bijou').Surface;
|
|
42
42
|
readonly paneRects: ReadonlyMap<string, import('./layout-rect.js').LayoutRect>;
|
|
43
43
|
readonly paneOrder: readonly string[];
|
|
44
44
|
}
|
|
@@ -83,10 +83,18 @@ export type FrameAction = {
|
|
|
83
83
|
type: 'dock-left';
|
|
84
84
|
} | {
|
|
85
85
|
type: 'dock-right';
|
|
86
|
+
} | {
|
|
87
|
+
type: 'runtime-issue';
|
|
88
|
+
issue: RuntimeIssue;
|
|
89
|
+
} | {
|
|
90
|
+
type: 'notification-tick';
|
|
91
|
+
atMs: number;
|
|
86
92
|
} | {
|
|
87
93
|
type: 'transition';
|
|
88
94
|
progress: number;
|
|
89
95
|
generation: number;
|
|
96
|
+
dt: number;
|
|
97
|
+
elapsedMs: number;
|
|
90
98
|
} | {
|
|
91
99
|
type: 'transition-complete';
|
|
92
100
|
generation: number;
|
|
@@ -132,4 +140,5 @@ export declare function emitMsgForPage<Msg>(pageId: string, msg: Msg): Cmd<Msg>;
|
|
|
132
140
|
export declare function wrapCmdForPage<Msg>(pageId: string, cmd: Cmd<Msg>): Cmd<Msg>;
|
|
133
141
|
/** Convert a binding's key combo into a synthetic KeyMsg for dispatch. */
|
|
134
142
|
export declare function comboToMsg(binding: BindingInfo): KeyMsg;
|
|
143
|
+
import type { RuntimeIssue } from './types.js';
|
|
135
144
|
//# sourceMappingURL=app-frame-types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app-frame-types.d.ts","sourceRoot":"","sources":["../src/app-frame-types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC/D,OAAO,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AAE9C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAC7D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAMjD,eAAO,MAAM,cAAc,eAA+B,CAAC;AAC3D,eAAO,MAAM,eAAe,eAAgC,CAAC;AAM7D,2EAA2E;AAC3E,MAAM,WAAW,kBAAkB,CAAC,SAAS,EAAE,GAAG,CAAE,SAAQ,UAAU,CAAC,SAAS,CAAC;IAC/E,QAAQ,CAAC,qBAAqB,CAAC,EAAE,SAAS,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC;CAC/D;AAED,yEAAyE;AACzE,MAAM,WAAW,YAAY,CAAC,GAAG;IAC/B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,kBAAkB,CAAC;IAClC,QAAQ,CAAC,SAAS,CAAC,EAAE,GAAG,CAAC;IACzB,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,WAAW,CAAC,EAAE,WAAW,CAAC;CACpC;AAED,qEAAqE;AACrE,MAAM,WAAW,aAAa,CAAC,SAAS,EAAE,GAAG;IAC3C,QAAQ,CAAC,KAAK,EAAE,kBAAkB,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;IACnD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,aAAa,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3C,QAAQ,CAAC,YAAY,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE;QAAE,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,CAAC;IAC5F,QAAQ,CAAC,UAAU,EAAE,oBAAoB,CAAC;IAC1C,QAAQ,CAAC,SAAS,EAAE,cAAc,CAAC;CACpC;AAED,2CAA2C;AAC3C,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,
|
|
1
|
+
{"version":3,"file":"app-frame-types.d.ts","sourceRoot":"","sources":["../src/app-frame-types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app-frame-types.js","sourceRoot":"","sources":["../src/app-frame-types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAMlC,8EAA8E;AAC9E,UAAU;AACV,8EAA8E;AAE9E,MAAM,CAAC,MAAM,cAAc,GAAG,MAAM,CAAC,oBAAoB,CAAC,CAAC;AAC3D,MAAM,CAAC,MAAM,eAAe,GAAG,MAAM,CAAC,qBAAqB,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"app-frame-types.js","sourceRoot":"","sources":["../src/app-frame-types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAMlC,8EAA8E;AAC9E,UAAU;AACV,8EAA8E;AAE9E,MAAM,CAAC,MAAM,cAAc,GAAG,MAAM,CAAC,oBAAoB,CAAC,CAAC;AAC3D,MAAM,CAAC,MAAM,eAAe,GAAG,MAAM,CAAC,qBAAqB,CAAC,CAAC;AA8F7D,8EAA8E;AAC9E,4BAA4B;AAC5B,8EAA8E;AAE9E,mEAAmE;AACnE,MAAM,UAAU,gBAAgB,CAAC,KAAc;IAC7C,OAAO,OAAO,KAAK,KAAK,QAAQ;WAC3B,KAAK,KAAK,IAAI;WACd,eAAe,IAAI,KAAK;WACvB,KAAwB,CAAC,eAAe,CAAC,KAAK,IAAI,CAAC;AAC3D,CAAC;AAED,qEAAqE;AACrE,MAAM,UAAU,YAAY,CAAC,MAAmB;IAC9C,OAAO;QACL,CAAC,eAAe,CAAC,EAAE,IAAI;QACvB,MAAM;KACP,CAAC;AACJ,CAAC;AAED,yDAAyD;AACzD,MAAM,UAAU,eAAe,CAAM,KAAc;IACjD,OAAO,OAAO,KAAK,KAAK,QAAQ;WAC3B,KAAK,KAAK,IAAI;WACd,cAAc,IAAI,KAAK;WACtB,KAA4B,CAAC,cAAc,CAAC,KAAK,IAAI,CAAC;AAC9D,CAAC;AAED,uDAAuD;AACvD,MAAM,UAAU,WAAW,CAAM,MAAc,EAAE,GAAQ;IACvD,OAAO;QACL,CAAC,cAAc,CAAC,EAAE,IAAI;QACtB,MAAM;QACN,GAAG;KACc,CAAC;AACtB,CAAC;AAED,yEAAyE;AACzE,MAAM,UAAU,OAAO,CAAM,GAAQ;IACnC,OAAO,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,GAAG,CAAC;AACrC,CAAC;AAED,yDAAyD;AACzD,MAAM,UAAU,cAAc,CAAM,MAAc,EAAE,GAAQ;IAC1D,OAAO,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,WAAW,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAC1D,CAAC;AAED,qFAAqF;AACrF,MAAM,UAAU,cAAc,CAAM,MAAc,EAAE,GAAa;IAC/D,OAAO,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE;QAC1B,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,GAAG,CAAmB,CAAC,EAAE,IAAI,CAAC,CAAC;QAC1F,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,KAAK,IAAI;YAAE,OAAO,MAAM,CAAC;QAC3D,OAAO,WAAW,CAAC,MAAM,EAAE,MAAa,CAAC,CAAC;IAC5C,CAAC,CAAC;AACJ,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,UAAU,CAAC,OAAoB;IAC7C,OAAO;QACL,IAAI,EAAE,KAAK;QACX,GAAG,EAAE,OAAO,CAAC,KAAK,CAAC,GAAG;QACtB,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC,IAAI;QACxB,GAAG,EAAE,OAAO,CAAC,KAAK,CAAC,GAAG;QACtB,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,KAAK;KAC3B,CAAC;AACJ,CAAC"}
|
package/dist/app-frame.d.ts
CHANGED
|
@@ -4,9 +4,10 @@
|
|
|
4
4
|
* Provides tabs, pane focus/scroll isolation, shell key handling, help,
|
|
5
5
|
* panel-scoped overlay context, and optional frame-level command palette.
|
|
6
6
|
*/
|
|
7
|
+
import { type OverflowBehavior } from '@flyingrobots/bijou';
|
|
7
8
|
import { type BindingSource } from './help.js';
|
|
8
9
|
import type { KeyMap } from './keybindings.js';
|
|
9
|
-
import type { App, Cmd } from './types.js';
|
|
10
|
+
import type { App, Cmd, KeyMsg } from './types.js';
|
|
10
11
|
import type { Overlay } from './overlay.js';
|
|
11
12
|
import type { TransitionShaderFn } from './transition-shaders.js';
|
|
12
13
|
import { type BuiltinTransition } from './transition-shaders.js';
|
|
@@ -21,6 +22,8 @@ import type { SerializedLayoutState } from './layout-preset.js';
|
|
|
21
22
|
import type { OverflowX } from './focus-area.js';
|
|
22
23
|
import type { Timeline, TimelineState } from './timeline.js';
|
|
23
24
|
import type { ViewOutput } from './view-output.js';
|
|
25
|
+
import { type NotificationPlacement, type NotificationState } from './notification.js';
|
|
26
|
+
import type { FrameAction } from './app-frame-types.js';
|
|
24
27
|
/** Page declaration consumed by {@link createFramedApp}. */
|
|
25
28
|
export interface FramePage<PageModel, Msg> {
|
|
26
29
|
/** Stable page id. */
|
|
@@ -35,6 +38,8 @@ export interface FramePage<PageModel, Msg> {
|
|
|
35
38
|
layout(model: PageModel): FrameLayoutNode;
|
|
36
39
|
/** Optional page keymap. */
|
|
37
40
|
keyMap?: KeyMap<Msg>;
|
|
41
|
+
/** Optional modal keymap. When present, it captures all keys until dismissed. */
|
|
42
|
+
modalKeyMap?: (model: PageModel) => KeyMap<Msg> | undefined;
|
|
38
43
|
/** Optional help source override. */
|
|
39
44
|
helpSource?: BindingSource;
|
|
40
45
|
/** Optional page-scoped command items for command palette listing/execution. */
|
|
@@ -49,7 +54,7 @@ export interface FrameCommandItem<Msg> extends CommandPaletteItem {
|
|
|
49
54
|
export type FrameLayoutNode = {
|
|
50
55
|
readonly kind: 'pane';
|
|
51
56
|
readonly paneId: string;
|
|
52
|
-
/** Pane content
|
|
57
|
+
/** Pane content must be a Surface or LayoutNode. */
|
|
53
58
|
readonly render: (width: number, height: number) => ViewOutput;
|
|
54
59
|
readonly overflowX?: OverflowX;
|
|
55
60
|
} | {
|
|
@@ -82,6 +87,21 @@ export interface FrameOverlayContext<PageModel> {
|
|
|
82
87
|
/** Full-screen bounds. */
|
|
83
88
|
readonly screenRect: LayoutRect;
|
|
84
89
|
}
|
|
90
|
+
/** Configuration for frame-managed runtime notifications. */
|
|
91
|
+
export interface FrameRuntimeNotificationOptions {
|
|
92
|
+
/** Enable routing framework warnings/errors through notifications. Default: true. */
|
|
93
|
+
readonly enabled?: boolean;
|
|
94
|
+
/** Stack placement. Default: 'LOWER_RIGHT'. */
|
|
95
|
+
readonly placement?: NotificationPlacement;
|
|
96
|
+
/** Auto-dismiss delay. Default: 6000ms. */
|
|
97
|
+
readonly durationMs?: number | null;
|
|
98
|
+
/** Render margin from the viewport edge. Default: 1. */
|
|
99
|
+
readonly margin?: number;
|
|
100
|
+
/** Gap between stacked notifications. Default: 1. */
|
|
101
|
+
readonly gap?: number;
|
|
102
|
+
/** Text overflow behavior. Default: 'wrap'. */
|
|
103
|
+
readonly overflow?: OverflowBehavior;
|
|
104
|
+
}
|
|
85
105
|
/** Page transition styles — a built-in name or a custom shader function. */
|
|
86
106
|
export type PageTransition = BuiltinTransition | TransitionShaderFn;
|
|
87
107
|
/** `createFramedApp()` options. */
|
|
@@ -98,10 +118,23 @@ export interface CreateFramedAppOptions<PageModel, Msg> {
|
|
|
98
118
|
readonly initialRows?: number;
|
|
99
119
|
/** Optional global keymap layered above page keymap. */
|
|
100
120
|
readonly globalKeys?: KeyMap<Msg>;
|
|
121
|
+
/** Resolve key conflicts in favor of the frame shell or the active page. Default: 'frame-first'. */
|
|
122
|
+
readonly keyPriority?: 'frame-first' | 'page-first';
|
|
123
|
+
/** Optional override for the short help strip source shown beneath the frame header. */
|
|
124
|
+
readonly helpLineSource?: (args: {
|
|
125
|
+
readonly model: FrameModel<PageModel>;
|
|
126
|
+
readonly activePage: FramePage<PageModel, Msg>;
|
|
127
|
+
readonly frameKeys: KeyMap<FrameAction>;
|
|
128
|
+
readonly globalKeys?: KeyMap<Msg>;
|
|
129
|
+
}) => BindingSource | undefined;
|
|
130
|
+
/** Optional observer that receives every key plus the route that handled it. Returned messages are scoped to the active page. */
|
|
131
|
+
readonly observeKey?: (msg: KeyMsg, route: 'palette' | 'help' | 'frame' | 'global' | 'page' | 'unhandled') => Msg | undefined;
|
|
101
132
|
/** Enable frame-level command palette (`ctrl+p` / `:`). */
|
|
102
133
|
readonly enableCommandPalette?: boolean;
|
|
103
134
|
/** Optional overlay provider (receives pane rects for panel scoping). */
|
|
104
135
|
readonly overlayFactory?: (ctx: FrameOverlayContext<PageModel>) => readonly Overlay[];
|
|
136
|
+
/** Optional runtime warning/error notifications managed by the frame shell. */
|
|
137
|
+
readonly runtimeNotifications?: boolean | FrameRuntimeNotificationOptions;
|
|
105
138
|
/** Optional page transition style. Default: 'none'. */
|
|
106
139
|
readonly transition?: PageTransition;
|
|
107
140
|
/** Transition duration in milliseconds. Default: 300. */
|
|
@@ -186,6 +219,10 @@ export interface FrameModel<PageModel> {
|
|
|
186
219
|
readonly dockStateByPage: Readonly<Record<string, PanelDockState>>;
|
|
187
220
|
/** Per-page split ratio overrides (from layout presets/session restore). */
|
|
188
221
|
readonly splitRatioOverrides: Readonly<Record<string, Readonly<Record<string, number>>>>;
|
|
222
|
+
/** Frame-managed runtime notifications. */
|
|
223
|
+
readonly runtimeNotifications: NotificationState<never>;
|
|
224
|
+
/** Whether the runtime notification tick loop is active. */
|
|
225
|
+
readonly runtimeNotificationLoopActive: boolean;
|
|
189
226
|
}
|
|
190
227
|
/**
|
|
191
228
|
* Create a fully framed TEA app shell.
|
package/dist/app-frame.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app-frame.d.ts","sourceRoot":"","sources":["../src/app-frame.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;
|
|
1
|
+
{"version":3,"file":"app-frame.d.ts","sourceRoot":"","sources":["../src/app-frame.ts"],"names":[],"mappings":"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"}
|
package/dist/app-frame.js
CHANGED
|
@@ -4,20 +4,58 @@
|
|
|
4
4
|
* Provides tabs, pane focus/scroll isolation, shell key handling, help,
|
|
5
5
|
* panel-scoped overlay context, and optional frame-level command palette.
|
|
6
6
|
*/
|
|
7
|
-
import { createSurface,
|
|
7
|
+
import { createSurface, resolveClock, resolveSafeCtx, } from '@flyingrobots/bijou';
|
|
8
8
|
import { helpView } from './help.js';
|
|
9
9
|
import { isKeyMsg, isMouseMsg, isResizeMsg } from './types.js';
|
|
10
|
-
import { modal } from './overlay.js';
|
|
11
|
-
import { fitBlock } from './layout-utils.js';
|
|
10
|
+
import { compositeSurface, modal } from './overlay.js';
|
|
12
11
|
import { commandPalette, commandPaletteKeyMap, } from './command-palette.js';
|
|
13
12
|
import { restoreLayoutState } from './layout-preset.js';
|
|
14
|
-
import {
|
|
13
|
+
import { createNotificationState, dismissNotification, hitTestNotificationStack, notificationsNeedTick, pushNotification, renderNotificationStack, tickNotifications, trimNotificationsToViewport, } from './notification.js';
|
|
14
|
+
import { isFrameScopedMsg, isPageScopedMsg, wrapCmdForPage, emitMsg, emitMsgForPage, wrapFrameMsg, } from './app-frame-types.js';
|
|
15
15
|
import { createFrameKeyMap, frameBodyRect, mergeBindingSources, } from './app-frame-utils.js';
|
|
16
|
-
import {
|
|
17
|
-
import { applyFrameAction, syncPageFrameState, } from './app-frame-actions.js';
|
|
16
|
+
import { resolveHeaderLine, renderHelpLine, renderPageContent, renderMaximizedPane, renderTransition, } from './app-frame-render.js';
|
|
17
|
+
import { applyFrameAction, switchTab, syncPageFrameState, } from './app-frame-actions.js';
|
|
18
18
|
import { handlePaletteKey, openCommandPalette, } from './app-frame-palette.js';
|
|
19
|
-
import { visibleLength } from './viewport.js';
|
|
20
19
|
// ---------------------------------------------------------------------------
|
|
20
|
+
// Frame Notification Helpers
|
|
21
|
+
// ---------------------------------------------------------------------------
|
|
22
|
+
const FRAME_NOTIFICATION_TICK_MS = 40;
|
|
23
|
+
const DEFAULT_FRAME_NOTIFICATION_DURATION_MS = 6_000;
|
|
24
|
+
function resolveFrameNotificationOptions(options) {
|
|
25
|
+
if (options.runtimeNotifications === false) {
|
|
26
|
+
return {
|
|
27
|
+
enabled: false,
|
|
28
|
+
placement: 'LOWER_RIGHT',
|
|
29
|
+
durationMs: DEFAULT_FRAME_NOTIFICATION_DURATION_MS,
|
|
30
|
+
margin: 1,
|
|
31
|
+
gap: 1,
|
|
32
|
+
overflow: 'wrap',
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
const configured = options.runtimeNotifications === true || options.runtimeNotifications == null
|
|
36
|
+
? {}
|
|
37
|
+
: options.runtimeNotifications;
|
|
38
|
+
return {
|
|
39
|
+
enabled: configured.enabled ?? true,
|
|
40
|
+
placement: configured.placement ?? 'LOWER_RIGHT',
|
|
41
|
+
durationMs: configured.durationMs ?? DEFAULT_FRAME_NOTIFICATION_DURATION_MS,
|
|
42
|
+
margin: configured.margin ?? 1,
|
|
43
|
+
gap: configured.gap ?? 1,
|
|
44
|
+
overflow: configured.overflow ?? 'wrap',
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
function createFrameNotificationTickCmd() {
|
|
48
|
+
return async (_emit, caps) => {
|
|
49
|
+
if (!caps.sleep) {
|
|
50
|
+
throw new Error('createFrameNotificationTickCmd requires sleep capability');
|
|
51
|
+
}
|
|
52
|
+
await caps.sleep(FRAME_NOTIFICATION_TICK_MS);
|
|
53
|
+
return wrapFrameMsg({
|
|
54
|
+
type: 'notification-tick',
|
|
55
|
+
atMs: caps.now?.() ?? 0,
|
|
56
|
+
});
|
|
57
|
+
};
|
|
58
|
+
}
|
|
21
59
|
// Factory
|
|
22
60
|
// ---------------------------------------------------------------------------
|
|
23
61
|
/**
|
|
@@ -40,6 +78,7 @@ export function createFramedApp(options) {
|
|
|
40
78
|
throw new Error(`createFramedApp: defaultPageId "${defaultPageId}" not found in pages`);
|
|
41
79
|
}
|
|
42
80
|
const frameKeys = createFrameKeyMap();
|
|
81
|
+
const frameNotificationOptions = resolveFrameNotificationOptions(options);
|
|
43
82
|
const paletteKeys = commandPaletteKeyMap({
|
|
44
83
|
focusNext: { type: 'cp-next' },
|
|
45
84
|
focusPrev: { type: 'cp-prev' },
|
|
@@ -48,6 +87,90 @@ export function createFramedApp(options) {
|
|
|
48
87
|
select: { type: 'cp-select' },
|
|
49
88
|
close: { type: 'cp-close' },
|
|
50
89
|
});
|
|
90
|
+
function withObservedKey(model, cmds, msg, route) {
|
|
91
|
+
const observed = options.observeKey?.(msg, route);
|
|
92
|
+
if (observed === undefined)
|
|
93
|
+
return [...cmds];
|
|
94
|
+
return [emitMsgForPage(model.activePageId, observed), ...cmds];
|
|
95
|
+
}
|
|
96
|
+
function updateTargetPage(model, targetPageId, targetMsg) {
|
|
97
|
+
const targetPage = pagesById.get(targetPageId);
|
|
98
|
+
if (targetPage == null)
|
|
99
|
+
return [model, []];
|
|
100
|
+
const pageModel = model.pageModels[targetPageId];
|
|
101
|
+
const updateResult = targetPage.update(targetMsg, pageModel);
|
|
102
|
+
let nextPageModel = pageModel;
|
|
103
|
+
let cmds = [];
|
|
104
|
+
if (updateResult !== undefined && updateResult !== null) {
|
|
105
|
+
if (Array.isArray(updateResult)) {
|
|
106
|
+
nextPageModel = (updateResult[0] ?? pageModel);
|
|
107
|
+
cmds = (updateResult[1] ?? []);
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
nextPageModel = updateResult;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
const nextModels = { ...model.pageModels, [targetPageId]: nextPageModel };
|
|
114
|
+
const synced = syncPageFrameState({ ...model, pageModels: nextModels }, targetPageId, pagesById);
|
|
115
|
+
const wrappedCmds = Array.isArray(cmds)
|
|
116
|
+
? cmds.map((cmd) => wrapCmdForPage(targetPageId, cmd))
|
|
117
|
+
: [];
|
|
118
|
+
return [synced, wrappedCmds];
|
|
119
|
+
}
|
|
120
|
+
function handleFrameMouse(msg, model) {
|
|
121
|
+
if (model.helpOpen || model.commandPalette != null)
|
|
122
|
+
return [model, []];
|
|
123
|
+
if (msg.action !== 'press' || msg.button !== 'left')
|
|
124
|
+
return undefined;
|
|
125
|
+
if (frameNotificationOptions.enabled) {
|
|
126
|
+
const nowMs = resolveClock(resolveSafeCtx()).now();
|
|
127
|
+
const notificationTarget = hitTestNotificationStack(model.runtimeNotifications, {
|
|
128
|
+
screenWidth: model.columns,
|
|
129
|
+
screenHeight: model.rows,
|
|
130
|
+
margin: frameNotificationOptions.margin,
|
|
131
|
+
gap: frameNotificationOptions.gap,
|
|
132
|
+
ctx: resolveSafeCtx() ?? undefined,
|
|
133
|
+
}, msg.col, msg.row);
|
|
134
|
+
if (notificationTarget?.kind === 'dismiss') {
|
|
135
|
+
return applyFrameNotificationState(model, dismissNotification(model.runtimeNotifications, notificationTarget.item.id, nowMs), nowMs);
|
|
136
|
+
}
|
|
137
|
+
if (notificationTarget != null) {
|
|
138
|
+
return [model, []];
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
if (msg.row === 0) {
|
|
142
|
+
const header = resolveHeaderLine(model, options, pagesById);
|
|
143
|
+
const tab = header.tabTargets.find((target) => msg.col >= target.startCol && msg.col <= target.endCol);
|
|
144
|
+
if (tab != null) {
|
|
145
|
+
const currentIndex = model.pageOrder.indexOf(model.activePageId);
|
|
146
|
+
const nextIndex = model.pageOrder.indexOf(tab.pageId);
|
|
147
|
+
if (currentIndex >= 0 && nextIndex >= 0 && nextIndex !== currentIndex) {
|
|
148
|
+
return switchTab(model, nextIndex - currentIndex, pagesById, options);
|
|
149
|
+
}
|
|
150
|
+
return [model, []];
|
|
151
|
+
}
|
|
152
|
+
return [model, []];
|
|
153
|
+
}
|
|
154
|
+
return undefined;
|
|
155
|
+
}
|
|
156
|
+
function applyFrameNotificationState(model, notifications, nowMs, forceTick = false) {
|
|
157
|
+
const trimmed = trimNotificationsToViewport(notifications, {
|
|
158
|
+
screenWidth: model.columns,
|
|
159
|
+
screenHeight: model.rows,
|
|
160
|
+
margin: frameNotificationOptions.margin,
|
|
161
|
+
gap: frameNotificationOptions.gap,
|
|
162
|
+
}, nowMs);
|
|
163
|
+
const needsTick = notificationsNeedTick(trimmed);
|
|
164
|
+
const nextModel = {
|
|
165
|
+
...model,
|
|
166
|
+
runtimeNotifications: trimmed,
|
|
167
|
+
runtimeNotificationLoopActive: needsTick,
|
|
168
|
+
};
|
|
169
|
+
if (needsTick && (forceTick || !model.runtimeNotificationLoopActive)) {
|
|
170
|
+
return [nextModel, [createFrameNotificationTickCmd()]];
|
|
171
|
+
}
|
|
172
|
+
return [nextModel, []];
|
|
173
|
+
}
|
|
51
174
|
const app = {
|
|
52
175
|
init() {
|
|
53
176
|
const pageModels = {};
|
|
@@ -73,6 +196,8 @@ export function createFramedApp(options) {
|
|
|
73
196
|
maximizedPaneByPage: {},
|
|
74
197
|
dockStateByPage: {},
|
|
75
198
|
splitRatioOverrides: {},
|
|
199
|
+
runtimeNotifications: createNotificationState(),
|
|
200
|
+
runtimeNotificationLoopActive: false,
|
|
76
201
|
};
|
|
77
202
|
for (const pageId of pageOrder) {
|
|
78
203
|
model = syncPageFrameState(model, pageId, pagesById);
|
|
@@ -95,16 +220,31 @@ export function createFramedApp(options) {
|
|
|
95
220
|
update(msg, model) {
|
|
96
221
|
if (isFrameScopedMsg(msg)) {
|
|
97
222
|
const action = msg.action;
|
|
223
|
+
if (action.type === 'runtime-issue') {
|
|
224
|
+
if (!frameNotificationOptions.enabled)
|
|
225
|
+
return [model, []];
|
|
226
|
+
const notifications = pushNotification(model.runtimeNotifications, {
|
|
227
|
+
title: action.issue.level === 'warning' ? 'Framework warning' : 'Runtime error',
|
|
228
|
+
message: action.issue.message,
|
|
229
|
+
variant: 'TOAST',
|
|
230
|
+
tone: action.issue.level === 'warning' ? 'WARNING' : 'ERROR',
|
|
231
|
+
placement: frameNotificationOptions.placement,
|
|
232
|
+
durationMs: frameNotificationOptions.durationMs,
|
|
233
|
+
overflow: frameNotificationOptions.overflow,
|
|
234
|
+
}, action.issue.atMs);
|
|
235
|
+
return applyFrameNotificationState(model, notifications, action.issue.atMs);
|
|
236
|
+
}
|
|
237
|
+
if (action.type === 'notification-tick') {
|
|
238
|
+
const notifications = tickNotifications(model.runtimeNotifications, action.atMs);
|
|
239
|
+
return applyFrameNotificationState(model, notifications, action.atMs, true);
|
|
240
|
+
}
|
|
98
241
|
if (action.type === 'transition') {
|
|
99
242
|
// Ignore stale transition ticks from a previous generation
|
|
100
243
|
if (action.generation !== model.transitionGeneration)
|
|
101
244
|
return [model, []];
|
|
102
|
-
// Advance timeline
|
|
103
|
-
if (model.transitionTimeline && model.transitionTimelineState
|
|
104
|
-
const
|
|
105
|
-
const elapsedSec = Math.max(0, elapsedMs / 1000);
|
|
106
|
-
// Step from init to current elapsed time (tweens are deterministic)
|
|
107
|
-
const state = model.transitionTimeline.step(model.transitionTimeline.init(), elapsedSec);
|
|
245
|
+
// Advance timeline from deterministic pulse deltas.
|
|
246
|
+
if (model.transitionTimeline && model.transitionTimelineState) {
|
|
247
|
+
const state = model.transitionTimeline.step(model.transitionTimelineState, Math.max(0, action.dt));
|
|
108
248
|
const vals = model.transitionTimeline.values(state);
|
|
109
249
|
const progress = Math.min(1, Math.max(0, vals['progress'] ?? action.progress));
|
|
110
250
|
if (model.transitionTimeline.done(state) || progress >= 1) {
|
|
@@ -158,65 +298,77 @@ export function createFramedApp(options) {
|
|
|
158
298
|
}
|
|
159
299
|
if (isKeyMsg(msg)) {
|
|
160
300
|
if (model.commandPalette != null) {
|
|
161
|
-
|
|
301
|
+
const [nextModel, cmds] = handlePaletteKey(msg, model, paletteKeys, options, pagesById);
|
|
302
|
+
return [nextModel, withObservedKey(model, cmds, msg, 'palette')];
|
|
162
303
|
}
|
|
163
304
|
// Help acts as a modal layer when open: only close keys are handled.
|
|
164
305
|
if (model.helpOpen) {
|
|
165
306
|
if (!msg.ctrl && !msg.alt && (msg.key === 'escape' || msg.key === '?')) {
|
|
166
|
-
return [{ ...model, helpOpen: false }, []];
|
|
307
|
+
return [{ ...model, helpOpen: false }, withObservedKey(model, [], msg, 'help')];
|
|
308
|
+
}
|
|
309
|
+
return [model, withObservedKey(model, [], msg, 'help')];
|
|
310
|
+
}
|
|
311
|
+
const activePage = pagesById.get(model.activePageId);
|
|
312
|
+
const activePageModel = model.pageModels[model.activePageId];
|
|
313
|
+
const modalKeyMap = activePage.modalKeyMap?.(activePageModel);
|
|
314
|
+
if (modalKeyMap != null) {
|
|
315
|
+
const modalAction = modalKeyMap.handle(msg);
|
|
316
|
+
if (modalAction !== undefined) {
|
|
317
|
+
return [model, withObservedKey(model, [emitMsgForPage(model.activePageId, modalAction)], msg, 'page')];
|
|
167
318
|
}
|
|
168
|
-
return [model, []];
|
|
319
|
+
return [model, withObservedKey(model, [], msg, 'page')];
|
|
169
320
|
}
|
|
321
|
+
const pageAction = activePage.keyMap?.handle(msg);
|
|
322
|
+
const globalAction = options.globalKeys?.handle(msg);
|
|
170
323
|
const frameAction = frameKeys.handle(msg);
|
|
324
|
+
const keyPriority = options.keyPriority ?? 'frame-first';
|
|
325
|
+
if (keyPriority === 'page-first') {
|
|
326
|
+
if (pageAction !== undefined) {
|
|
327
|
+
return [model, withObservedKey(model, [emitMsgForPage(model.activePageId, pageAction)], msg, 'page')];
|
|
328
|
+
}
|
|
329
|
+
if (globalAction !== undefined) {
|
|
330
|
+
return [model, withObservedKey(model, [emitMsg(globalAction)], msg, 'global')];
|
|
331
|
+
}
|
|
332
|
+
if (frameAction !== undefined) {
|
|
333
|
+
if (frameAction.type === 'open-palette' && options.enableCommandPalette) {
|
|
334
|
+
return [openCommandPalette(model, frameKeys, options, pagesById), withObservedKey(model, [], msg, 'frame')];
|
|
335
|
+
}
|
|
336
|
+
const [nextModel, cmds] = applyFrameAction(frameAction, model, options, pagesById);
|
|
337
|
+
return [nextModel, withObservedKey(model, cmds, msg, 'frame')];
|
|
338
|
+
}
|
|
339
|
+
return [model, withObservedKey(model, [], msg, 'unhandled')];
|
|
340
|
+
}
|
|
171
341
|
if (frameAction !== undefined) {
|
|
172
342
|
// Handle palette opening here since applyFrameAction doesn't have access to palette deps
|
|
173
343
|
if (frameAction.type === 'open-palette' && options.enableCommandPalette) {
|
|
174
|
-
return [openCommandPalette(model, frameKeys, options, pagesById), []];
|
|
344
|
+
return [openCommandPalette(model, frameKeys, options, pagesById), withObservedKey(model, [], msg, 'frame')];
|
|
175
345
|
}
|
|
176
|
-
|
|
346
|
+
const [nextModel, cmds] = applyFrameAction(frameAction, model, options, pagesById);
|
|
347
|
+
return [nextModel, withObservedKey(model, cmds, msg, 'frame')];
|
|
177
348
|
}
|
|
178
|
-
const globalAction = options.globalKeys?.handle(msg);
|
|
179
349
|
if (globalAction !== undefined) {
|
|
180
|
-
return [model, [emitMsg(globalAction)]];
|
|
350
|
+
return [model, withObservedKey(model, [emitMsg(globalAction)], msg, 'global')];
|
|
181
351
|
}
|
|
182
|
-
const activePage = pagesById.get(model.activePageId);
|
|
183
|
-
const pageAction = activePage.keyMap?.handle(msg);
|
|
184
352
|
if (pageAction !== undefined) {
|
|
185
|
-
return [model, [emitMsgForPage(model.activePageId, pageAction)]];
|
|
353
|
+
return [model, withObservedKey(model, [emitMsgForPage(model.activePageId, pageAction)], msg, 'page')];
|
|
186
354
|
}
|
|
187
|
-
return [model, []];
|
|
355
|
+
return [model, withObservedKey(model, [], msg, 'unhandled')];
|
|
188
356
|
}
|
|
189
357
|
if (isMouseMsg(msg)) {
|
|
190
|
-
|
|
358
|
+
const frameResult = handleFrameMouse(msg, model);
|
|
359
|
+
if (frameResult != null)
|
|
360
|
+
return frameResult;
|
|
361
|
+
return updateTargetPage(model, model.activePageId, msg);
|
|
191
362
|
}
|
|
192
363
|
// Custom message path: route to originating page when command messages are scoped.
|
|
193
364
|
const scoped = isPageScopedMsg(msg) ? msg : undefined;
|
|
194
365
|
const targetPageId = scoped?.pageId ?? model.activePageId;
|
|
195
|
-
const targetPage = pagesById.get(targetPageId);
|
|
196
|
-
if (targetPage == null)
|
|
197
|
-
return [model, []];
|
|
198
366
|
const targetMsg = scoped?.msg ?? msg;
|
|
199
|
-
|
|
200
|
-
const updateResult = targetPage.update(targetMsg, pageModel);
|
|
201
|
-
let nextPageModel = pageModel; // Default to current
|
|
202
|
-
let cmds = [];
|
|
203
|
-
if (updateResult !== undefined && updateResult !== null) {
|
|
204
|
-
if (Array.isArray(updateResult)) {
|
|
205
|
-
nextPageModel = (updateResult[0] ?? pageModel);
|
|
206
|
-
cmds = (updateResult[1] ?? []);
|
|
207
|
-
}
|
|
208
|
-
else {
|
|
209
|
-
nextPageModel = updateResult;
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
const nextModels = { ...model.pageModels, [targetPageId]: nextPageModel };
|
|
213
|
-
const synced = syncPageFrameState({ ...model, pageModels: nextModels }, targetPageId, pagesById);
|
|
214
|
-
const wrappedCmds = Array.isArray(cmds) ? cmds.map((cmd) => wrapCmdForPage(targetPageId, cmd)) : [];
|
|
215
|
-
return [synced, wrappedCmds];
|
|
367
|
+
return updateTargetPage(model, targetPageId, targetMsg);
|
|
216
368
|
},
|
|
217
369
|
view(model) {
|
|
218
370
|
const activePage = pagesById.get(model.activePageId);
|
|
219
|
-
const header =
|
|
371
|
+
const header = resolveHeaderLine(model, options, pagesById).surface;
|
|
220
372
|
const helpLine = renderHelpLine(model, frameKeys, options, activePage);
|
|
221
373
|
const bodyRect = frameBodyRect(model.columns, model.rows);
|
|
222
374
|
// Check for maximized pane — if set, render only that pane at full body rect
|
|
@@ -225,16 +377,15 @@ export function createFramedApp(options) {
|
|
|
225
377
|
const activeResult = maximizedPaneId
|
|
226
378
|
? renderMaximizedPane(model.activePageId, model, bodyRect, pagesById, maximizedPaneId)
|
|
227
379
|
: renderPageContent(model.activePageId, model, bodyRect, pagesById);
|
|
228
|
-
let
|
|
380
|
+
let bodySurface = activeResult.surface;
|
|
229
381
|
const activeTransition = model.activeTransition ?? options.transition;
|
|
230
382
|
if (model.previousPageId != null && model.transitionProgress < 1 && activeTransition && activeTransition !== 'none') {
|
|
231
383
|
const ctx = resolveSafeCtx();
|
|
232
384
|
if (ctx) {
|
|
233
385
|
const prevResult = renderPageContent(model.previousPageId, model, bodyRect, pagesById);
|
|
234
|
-
|
|
386
|
+
bodySurface = renderTransition(prevResult.surface, activeResult.surface, activeTransition, model.transitionProgress, bodyRect.width, bodyRect.height, ctx, model.transitionFrame);
|
|
235
387
|
}
|
|
236
388
|
}
|
|
237
|
-
bodyOutput = fitBlock(bodyOutput, bodyRect.width, bodyRect.height).join('\n');
|
|
238
389
|
const overlays = [];
|
|
239
390
|
if (options.overlayFactory != null) {
|
|
240
391
|
overlays.push(...options.overlayFactory({
|
|
@@ -244,6 +395,16 @@ export function createFramedApp(options) {
|
|
|
244
395
|
screenRect: { row: 0, col: 0, width: model.columns, height: model.rows },
|
|
245
396
|
}));
|
|
246
397
|
}
|
|
398
|
+
if (frameNotificationOptions.enabled) {
|
|
399
|
+
const ctx = resolveSafeCtx();
|
|
400
|
+
overlays.push(...renderNotificationStack(model.runtimeNotifications, {
|
|
401
|
+
screenWidth: model.columns,
|
|
402
|
+
screenHeight: model.rows,
|
|
403
|
+
margin: frameNotificationOptions.margin,
|
|
404
|
+
gap: frameNotificationOptions.gap,
|
|
405
|
+
ctx: ctx ?? undefined,
|
|
406
|
+
}));
|
|
407
|
+
}
|
|
247
408
|
if (model.helpOpen) {
|
|
248
409
|
const full = helpView(mergeBindingSources(frameKeys, options.globalKeys, activePage.helpSource ?? activePage.keyMap));
|
|
249
410
|
overlays.push(modal({
|
|
@@ -269,48 +430,31 @@ export function createFramedApp(options) {
|
|
|
269
430
|
return composeFrameSurface({
|
|
270
431
|
width: model.columns,
|
|
271
432
|
height: model.rows,
|
|
272
|
-
header,
|
|
273
|
-
helpLine,
|
|
274
|
-
|
|
433
|
+
headerSurface: header,
|
|
434
|
+
helpLineSurface: helpLine,
|
|
435
|
+
bodySurface,
|
|
275
436
|
bodyRect,
|
|
276
437
|
overlays,
|
|
277
438
|
dimBackground: overlays.length > 0,
|
|
278
439
|
});
|
|
279
440
|
},
|
|
441
|
+
routeRuntimeIssue(issue) {
|
|
442
|
+
if (!frameNotificationOptions.enabled)
|
|
443
|
+
return undefined;
|
|
444
|
+
return wrapFrameMsg({ type: 'runtime-issue', issue });
|
|
445
|
+
},
|
|
280
446
|
};
|
|
281
447
|
return app;
|
|
282
448
|
}
|
|
283
449
|
function composeFrameSurface(options) {
|
|
284
450
|
const frame = createSurface(options.width, options.height);
|
|
285
|
-
frame.blit(
|
|
451
|
+
frame.blit(options.headerSurface, 0, 0);
|
|
286
452
|
if (options.height > 1) {
|
|
287
|
-
frame.blit(
|
|
453
|
+
frame.blit(options.helpLineSurface, 0, 1);
|
|
288
454
|
}
|
|
289
455
|
if (options.bodyRect.width > 0 && options.bodyRect.height > 0) {
|
|
290
|
-
frame.blit(
|
|
291
|
-
}
|
|
292
|
-
if (options.dimBackground) {
|
|
293
|
-
dimSurface(frame);
|
|
456
|
+
frame.blit(options.bodySurface, options.bodyRect.col, options.bodyRect.row);
|
|
294
457
|
}
|
|
295
|
-
|
|
296
|
-
const overlaySurface = parseAnsiToSurface(overlay.content, maxVisibleWidth(overlay.content), overlay.content.split('\n').length);
|
|
297
|
-
frame.blit(overlaySurface, overlay.col, overlay.row);
|
|
298
|
-
}
|
|
299
|
-
return frame;
|
|
300
|
-
}
|
|
301
|
-
function dimSurface(surface) {
|
|
302
|
-
for (let y = 0; y < surface.height; y++) {
|
|
303
|
-
for (let x = 0; x < surface.width; x++) {
|
|
304
|
-
const cell = surface.get(x, y);
|
|
305
|
-
if (cell.empty || cell.char === ' ')
|
|
306
|
-
continue;
|
|
307
|
-
const modifiers = new Set(cell.modifiers ?? []);
|
|
308
|
-
modifiers.add('dim');
|
|
309
|
-
surface.set(x, y, { ...cell, modifiers: Array.from(modifiers) });
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
function maxVisibleWidth(text) {
|
|
314
|
-
return text.split('\n').reduce((max, line) => Math.max(max, visibleLength(line)), 0);
|
|
458
|
+
return compositeSurface(frame, options.overlays, { dim: options.dimBackground });
|
|
315
459
|
}
|
|
316
460
|
//# sourceMappingURL=app-frame.js.map
|