@flyingrobots/bijou-tui 1.7.0 → 2.1.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.
Files changed (57) hide show
  1. package/dist/app-frame-actions.d.ts +37 -0
  2. package/dist/app-frame-actions.d.ts.map +1 -0
  3. package/dist/app-frame-actions.js +313 -0
  4. package/dist/app-frame-actions.js.map +1 -0
  5. package/dist/app-frame-palette.d.ts +16 -0
  6. package/dist/app-frame-palette.d.ts.map +1 -0
  7. package/dist/app-frame-palette.js +158 -0
  8. package/dist/app-frame-palette.js.map +1 -0
  9. package/dist/app-frame-render.d.ts +37 -0
  10. package/dist/app-frame-render.d.ts.map +1 -0
  11. package/dist/app-frame-render.js +277 -0
  12. package/dist/app-frame-render.js.map +1 -0
  13. package/dist/app-frame-types.d.ts +135 -0
  14. package/dist/app-frame-types.d.ts.map +1 -0
  15. package/dist/app-frame-types.js +72 -0
  16. package/dist/app-frame-types.js.map +1 -0
  17. package/dist/app-frame-utils.d.ts +37 -0
  18. package/dist/app-frame-utils.d.ts.map +1 -0
  19. package/dist/app-frame-utils.js +141 -0
  20. package/dist/app-frame-utils.js.map +1 -0
  21. package/dist/app-frame.d.ts +20 -4
  22. package/dist/app-frame.d.ts.map +1 -1
  23. package/dist/app-frame.js +52 -747
  24. package/dist/app-frame.js.map +1 -1
  25. package/dist/eventbus.d.ts +5 -0
  26. package/dist/eventbus.d.ts.map +1 -1
  27. package/dist/eventbus.js +17 -3
  28. package/dist/eventbus.js.map +1 -1
  29. package/dist/index.d.ts +4 -1
  30. package/dist/index.d.ts.map +1 -1
  31. package/dist/index.js +17 -1
  32. package/dist/index.js.map +1 -1
  33. package/dist/layout-preset.d.ts +81 -0
  34. package/dist/layout-preset.d.ts.map +1 -0
  35. package/dist/layout-preset.js +107 -0
  36. package/dist/layout-preset.js.map +1 -0
  37. package/dist/panel-dock.d.ts +52 -0
  38. package/dist/panel-dock.d.ts.map +1 -0
  39. package/dist/panel-dock.js +112 -0
  40. package/dist/panel-dock.js.map +1 -0
  41. package/dist/panel-state.d.ts +30 -0
  42. package/dist/panel-state.d.ts.map +1 -0
  43. package/dist/panel-state.js +50 -0
  44. package/dist/panel-state.js.map +1 -0
  45. package/dist/screen.d.ts +2 -5
  46. package/dist/screen.d.ts.map +1 -1
  47. package/dist/screen.js +2 -4
  48. package/dist/screen.js.map +1 -1
  49. package/dist/split-pane.d.ts +5 -0
  50. package/dist/split-pane.d.ts.map +1 -1
  51. package/dist/split-pane.js +6 -8
  52. package/dist/split-pane.js.map +1 -1
  53. package/dist/transition-shaders.d.ts +101 -3
  54. package/dist/transition-shaders.d.ts.map +1 -1
  55. package/dist/transition-shaders.js +281 -6
  56. package/dist/transition-shaders.js.map +1 -1
  57. package/package.json +3 -3
@@ -0,0 +1,37 @@
1
+ /**
2
+ * State reducers for `app-frame.ts`.
3
+ *
4
+ * Tab switching, pane cycling, scroll actions, minimize/maximize/dock,
5
+ * page frame state sync, and transition tick command.
6
+ */
7
+ import type { FramePage, CreateFramedAppOptions } from './app-frame.js';
8
+ import type { InternalFrameModel, FrameAction } from './app-frame-types.js';
9
+ import type { Cmd } from './types.js';
10
+ import type { DockDirection } from './panel-dock.js';
11
+ /** Dispatch a frame-level action (tab switch, pane cycle, scroll, palette, help toggle, transitions). */
12
+ export declare function applyFrameAction<PageModel, Msg>(action: FrameAction, model: InternalFrameModel<PageModel, Msg>, options: CreateFramedAppOptions<PageModel, Msg>, pagesById: Map<string, FramePage<PageModel, Msg>>): [InternalFrameModel<PageModel, Msg>, Cmd<Msg>[]];
13
+ /** Cycle the active tab by `delta` positions, optionally starting a transition. */
14
+ export declare function switchTab<PageModel, Msg>(model: InternalFrameModel<PageModel, Msg>, delta: number, pagesById: Map<string, FramePage<PageModel, Msg>>, options: CreateFramedAppOptions<PageModel, Msg>): [InternalFrameModel<PageModel, Msg>, Cmd<Msg>[]];
15
+ /** Move focus to the next or previous pane in the active page's layout. */
16
+ export declare function cyclePane<PageModel, Msg>(model: InternalFrameModel<PageModel, Msg>, delta: number, pagesById: Map<string, FramePage<PageModel, Msg>>): InternalFrameModel<PageModel, Msg>;
17
+ /** Apply a scroll action to the currently focused pane. */
18
+ export declare function scrollFocusedPane<PageModel, Msg>(model: InternalFrameModel<PageModel, Msg>, action: Extract<FrameAction, {
19
+ type: 'scroll-up' | 'scroll-down' | 'page-up' | 'page-down' | 'top' | 'bottom' | 'scroll-left' | 'scroll-right';
20
+ }>, pagesById: Map<string, FramePage<PageModel, Msg>>): InternalFrameModel<PageModel, Msg>;
21
+ /** Toggle minimize on the focused pane of the active page. */
22
+ export declare function applyToggleMinimize<PageModel, Msg>(model: InternalFrameModel<PageModel, Msg>, pagesById: Map<string, FramePage<PageModel, Msg>>): InternalFrameModel<PageModel, Msg>;
23
+ /** Toggle maximize on the focused pane of the active page. */
24
+ export declare function applyToggleMaximize<PageModel, Msg>(model: InternalFrameModel<PageModel, Msg>, _pagesById: Map<string, FramePage<PageModel, Msg>>): InternalFrameModel<PageModel, Msg>;
25
+ /** Move the focused pane within its container in the given direction. */
26
+ export declare function applyDockMove<PageModel, Msg>(model: InternalFrameModel<PageModel, Msg>, direction: DockDirection, pagesById: Map<string, FramePage<PageModel, Msg>>): InternalFrameModel<PageModel, Msg>;
27
+ /** Reconcile pane IDs, scroll offsets, and focus for a page after init, tab switches, or window resizes. */
28
+ export declare function syncPageFrameState<PageModel, Msg>(model: InternalFrameModel<PageModel, Msg>, pageId: string, pagesById: Map<string, FramePage<PageModel, Msg>>): InternalFrameModel<PageModel, Msg>;
29
+ /**
30
+ * Create a TEA command that drives transition re-renders via `setInterval`.
31
+ *
32
+ * Each tick emits a frame-scoped 'transition' message. The actual progress
33
+ * is computed from wall-clock time in the update handler, not from the
34
+ * interval count. The interval just schedules re-renders.
35
+ */
36
+ export declare function createTransitionTickCmd<Msg>(durationMs: number, generation: number): Cmd<Msg>;
37
+ //# sourceMappingURL=app-frame-actions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-frame-actions.d.ts","sourceRoot":"","sources":["../src/app-frame-actions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,313 @@
1
+ /**
2
+ * State reducers for `app-frame.ts`.
3
+ *
4
+ * Tab switching, pane cycling, scroll actions, minimize/maximize/dock,
5
+ * page frame state sync, and transition tick command.
6
+ */
7
+ import { wrapFrameMsg } from './app-frame-types.js';
8
+ import { createPanelVisibilityState, createPanelMaximizeState, toggleMinimized, restorePane, isMinimized, toggleMaximize, } from './panel-state.js';
9
+ import { createPanelDockState, movePaneInContainer, resolveChildOrder, findPaneContainer, } from './panel-dock.js';
10
+ import { createFocusAreaState, focusAreaScrollBy, focusAreaScrollByX, focusAreaScrollToBottom, focusAreaScrollToTop, focusAreaPageDown, focusAreaPageUp, focusAreaScrollTo, focusAreaScrollToX, } from './focus-area.js';
11
+ import { timeline } from './timeline.js';
12
+ import { EASINGS } from './spring.js';
13
+ import { collectPaneIds, assertUniquePaneIds, findPaneNode, frameBodyRect, } from './app-frame-utils.js';
14
+ import { renderFrameNode } from './app-frame-render.js';
15
+ /** Dispatch a frame-level action (tab switch, pane cycle, scroll, palette, help toggle, transitions). */
16
+ export function applyFrameAction(action, model, options, pagesById) {
17
+ switch (action.type) {
18
+ case 'toggle-help':
19
+ return [{ ...model, helpOpen: !model.helpOpen }, []];
20
+ case 'prev-tab':
21
+ return switchTab(model, -1, pagesById, options);
22
+ case 'next-tab':
23
+ return switchTab(model, 1, pagesById, options);
24
+ case 'next-pane':
25
+ return [cyclePane(model, 1, pagesById), []];
26
+ case 'prev-pane':
27
+ return [cyclePane(model, -1, pagesById), []];
28
+ case 'open-palette':
29
+ // Palette opening is gated by `enableCommandPalette` and handled in the
30
+ // key-handler path of app-frame.ts → openCommandPalette(). This no-op
31
+ // covers the recursive case (e.g., a palette frame-action entry that
32
+ // would re-trigger open-palette while the palette is already open).
33
+ return [model, []];
34
+ case 'toggle-minimize':
35
+ return [applyToggleMinimize(model, pagesById), []];
36
+ case 'toggle-maximize':
37
+ return [applyToggleMaximize(model, pagesById), []];
38
+ case 'dock-up':
39
+ case 'dock-down':
40
+ case 'dock-left':
41
+ case 'dock-right': {
42
+ const dir = action.type.replace('dock-', '');
43
+ return [applyDockMove(model, dir, pagesById), []];
44
+ }
45
+ case 'scroll-up':
46
+ case 'scroll-down':
47
+ case 'page-up':
48
+ case 'page-down':
49
+ case 'top':
50
+ case 'bottom':
51
+ case 'scroll-left':
52
+ case 'scroll-right':
53
+ return [scrollFocusedPane(model, action, pagesById), []];
54
+ case 'transition':
55
+ case 'transition-complete':
56
+ return [model, []];
57
+ }
58
+ }
59
+ /** Cycle the active tab by `delta` positions, optionally starting a transition. */
60
+ export function switchTab(model, delta, pagesById, options) {
61
+ const idx = model.pageOrder.indexOf(model.activePageId);
62
+ if (idx < 0)
63
+ return [model, []];
64
+ const nextIdx = (idx + delta + model.pageOrder.length) % model.pageOrder.length;
65
+ const nextId = model.pageOrder[nextIdx];
66
+ if (nextId === model.activePageId)
67
+ return [model, []];
68
+ const activePageModel = model.pageModels[model.activePageId];
69
+ const activeTransition = options.transitionOverride
70
+ ? options.transitionOverride(activePageModel)
71
+ : options.transition;
72
+ const hasTransition = activeTransition != null && activeTransition !== 'none';
73
+ const nextGeneration = model.transitionGeneration + 1;
74
+ // Use the user-supplied timeline if provided, otherwise build a default.
75
+ // The timeline MUST contain a 'progress' track (0 → 1).
76
+ const tl = hasTransition
77
+ ? (options.transitionTimeline ?? timeline()
78
+ .add('progress', {
79
+ type: 'tween',
80
+ from: 0,
81
+ to: 1,
82
+ duration: options.transitionDuration ?? 300,
83
+ ease: EASINGS.easeInOutCubic,
84
+ })
85
+ .build())
86
+ : undefined;
87
+ const durationMs = tl?.estimatedDurationMs ?? options.transitionDuration ?? 300;
88
+ const nextModel = syncPageFrameState({
89
+ ...model,
90
+ activePageId: nextId,
91
+ previousPageId: model.activePageId,
92
+ activeTransition,
93
+ transitionProgress: hasTransition ? 0 : 1,
94
+ transitionGeneration: nextGeneration,
95
+ transitionFrame: 0,
96
+ transitionStartMs: hasTransition ? Date.now() : undefined,
97
+ transitionTimeline: tl,
98
+ transitionTimelineState: tl?.init(),
99
+ }, nextId, pagesById);
100
+ if (hasTransition) {
101
+ // Schedule render ticks at ~60fps for the duration of the transition.
102
+ // Each tick advances the timeline using wall-clock elapsed time.
103
+ const cmd = createTransitionTickCmd(durationMs, nextGeneration);
104
+ return [nextModel, [cmd]];
105
+ }
106
+ return [nextModel, []];
107
+ }
108
+ /** Move focus to the next or previous pane in the active page's layout. */
109
+ export function cyclePane(model, delta, pagesById) {
110
+ const page = pagesById.get(model.activePageId);
111
+ const paneIds = collectPaneIds(page.layout(model.pageModels[model.activePageId]));
112
+ if (paneIds.length === 0)
113
+ return model;
114
+ const curr = model.focusedPaneByPage[model.activePageId];
115
+ const idx = curr == null ? 0 : paneIds.indexOf(curr);
116
+ const nextIdx = idx < 0
117
+ ? 0
118
+ : (idx + delta + paneIds.length) % paneIds.length;
119
+ const next = paneIds[nextIdx];
120
+ return {
121
+ ...model,
122
+ focusedPaneByPage: {
123
+ ...model.focusedPaneByPage,
124
+ [model.activePageId]: next,
125
+ },
126
+ };
127
+ }
128
+ /** Apply a scroll action to the currently focused pane. */
129
+ export function scrollFocusedPane(model, action, pagesById) {
130
+ const pageId = model.activePageId;
131
+ const focusedPaneId = model.focusedPaneByPage[pageId];
132
+ if (focusedPaneId == null)
133
+ return model;
134
+ const page = pagesById.get(pageId);
135
+ const layoutTree = page.layout(model.pageModels[pageId]);
136
+ const bodyRect = frameBodyRect(model.columns, model.rows);
137
+ const resolved = renderFrameNode(layoutTree, bodyRect, {
138
+ model,
139
+ pageId,
140
+ focusedPaneId,
141
+ scrollByPane: model.scrollByPage[pageId] ?? {},
142
+ visibility: model.minimizedByPage[pageId] ?? createPanelVisibilityState(),
143
+ dockState: model.dockStateByPage[pageId] ?? createPanelDockState(),
144
+ });
145
+ const paneRect = resolved.paneRects.get(focusedPaneId);
146
+ if (paneRect == null || paneRect.width <= 0 || paneRect.height <= 0)
147
+ return model;
148
+ const paneNode = findPaneNode(layoutTree, focusedPaneId);
149
+ if (paneNode == null)
150
+ return model;
151
+ const content = paneNode.render(paneRect.width, paneRect.height);
152
+ let state = createFocusAreaState({
153
+ content,
154
+ width: paneRect.width,
155
+ height: paneRect.height,
156
+ overflowX: paneNode.overflowX ?? 'hidden',
157
+ });
158
+ const prior = model.scrollByPage[pageId]?.[focusedPaneId] ?? { x: 0, y: 0 };
159
+ state = focusAreaScrollTo(state, prior.y);
160
+ state = focusAreaScrollToX(state, prior.x);
161
+ switch (action.type) {
162
+ case 'scroll-up':
163
+ state = focusAreaScrollBy(state, -1);
164
+ break;
165
+ case 'scroll-down':
166
+ state = focusAreaScrollBy(state, 1);
167
+ break;
168
+ case 'page-up':
169
+ state = focusAreaPageUp(state);
170
+ break;
171
+ case 'page-down':
172
+ state = focusAreaPageDown(state);
173
+ break;
174
+ case 'top':
175
+ state = focusAreaScrollToTop(state);
176
+ break;
177
+ case 'bottom':
178
+ state = focusAreaScrollToBottom(state);
179
+ break;
180
+ case 'scroll-left':
181
+ state = focusAreaScrollByX(state, -1);
182
+ break;
183
+ case 'scroll-right':
184
+ state = focusAreaScrollByX(state, 1);
185
+ break;
186
+ }
187
+ const pageScroll = model.scrollByPage[pageId] ?? {};
188
+ return {
189
+ ...model,
190
+ scrollByPage: {
191
+ ...model.scrollByPage,
192
+ [pageId]: {
193
+ ...pageScroll,
194
+ [focusedPaneId]: { x: state.scroll.x, y: state.scroll.y },
195
+ },
196
+ },
197
+ };
198
+ }
199
+ /** Toggle minimize on the focused pane of the active page. */
200
+ export function applyToggleMinimize(model, pagesById) {
201
+ const pageId = model.activePageId;
202
+ const focusedPaneId = model.focusedPaneByPage[pageId];
203
+ if (focusedPaneId == null)
204
+ return model;
205
+ const page = pagesById.get(pageId);
206
+ const allPaneIds = collectPaneIds(page.layout(model.pageModels[pageId]));
207
+ const current = model.minimizedByPage[pageId] ?? createPanelVisibilityState();
208
+ const next = toggleMinimized(current, focusedPaneId, allPaneIds);
209
+ // If we just minimized the focused pane, move focus to a non-minimized sibling
210
+ let newFocused = focusedPaneId;
211
+ if (isMinimized(next, focusedPaneId)) {
212
+ const visible = allPaneIds.filter((id) => !isMinimized(next, id));
213
+ newFocused = visible[0] ?? focusedPaneId;
214
+ }
215
+ return {
216
+ ...model,
217
+ minimizedByPage: { ...model.minimizedByPage, [pageId]: next },
218
+ focusedPaneByPage: { ...model.focusedPaneByPage, [pageId]: newFocused },
219
+ };
220
+ }
221
+ /** Toggle maximize on the focused pane of the active page. */
222
+ export function applyToggleMaximize(model, _pagesById) {
223
+ const pageId = model.activePageId;
224
+ const focusedPaneId = model.focusedPaneByPage[pageId];
225
+ if (focusedPaneId == null)
226
+ return model;
227
+ const current = model.maximizedPaneByPage[pageId] ?? createPanelMaximizeState();
228
+ const next = toggleMaximize(current, focusedPaneId);
229
+ // If maximizing a minimized pane, restore it first
230
+ let visibility = model.minimizedByPage[pageId] ?? createPanelVisibilityState();
231
+ if (next.maximizedPaneId && isMinimized(visibility, next.maximizedPaneId)) {
232
+ visibility = restorePane(visibility, next.maximizedPaneId);
233
+ }
234
+ return {
235
+ ...model,
236
+ maximizedPaneByPage: { ...model.maximizedPaneByPage, [pageId]: next },
237
+ minimizedByPage: { ...model.minimizedByPage, [pageId]: visibility },
238
+ };
239
+ }
240
+ /** Move the focused pane within its container in the given direction. */
241
+ export function applyDockMove(model, direction, pagesById) {
242
+ const pageId = model.activePageId;
243
+ const focusedPaneId = model.focusedPaneByPage[pageId];
244
+ if (focusedPaneId == null)
245
+ return model;
246
+ const page = pagesById.get(pageId);
247
+ const layoutTree = page.layout(model.pageModels[pageId]);
248
+ const container = findPaneContainer(layoutTree, focusedPaneId);
249
+ if (container == null)
250
+ return model;
251
+ const dockState = model.dockStateByPage[pageId] ?? createPanelDockState();
252
+ const currentOrder = resolveChildOrder(dockState, container.containerId, container.childIds);
253
+ const next = movePaneInContainer(dockState, container.containerId, focusedPaneId, direction, currentOrder);
254
+ return {
255
+ ...model,
256
+ dockStateByPage: { ...model.dockStateByPage, [pageId]: next },
257
+ };
258
+ }
259
+ /** Reconcile pane IDs, scroll offsets, and focus for a page after init, tab switches, or window resizes. */
260
+ export function syncPageFrameState(model, pageId, pagesById) {
261
+ const page = pagesById.get(pageId);
262
+ const paneIds = collectPaneIds(page.layout(model.pageModels[pageId]));
263
+ assertUniquePaneIds(paneIds, `page "${pageId}" layout`);
264
+ const prevScroll = model.scrollByPage[pageId] ?? {};
265
+ const nextScroll = {};
266
+ for (const paneId of paneIds) {
267
+ nextScroll[paneId] = prevScroll[paneId] ?? { x: 0, y: 0 };
268
+ }
269
+ const prevFocused = model.focusedPaneByPage[pageId];
270
+ const focused = prevFocused != null && paneIds.includes(prevFocused)
271
+ ? prevFocused
272
+ : paneIds[0];
273
+ return {
274
+ ...model,
275
+ focusedPaneByPage: {
276
+ ...model.focusedPaneByPage,
277
+ [pageId]: focused,
278
+ },
279
+ scrollByPage: {
280
+ ...model.scrollByPage,
281
+ [pageId]: nextScroll,
282
+ },
283
+ };
284
+ }
285
+ /**
286
+ * Create a TEA command that drives transition re-renders via `setInterval`.
287
+ *
288
+ * Each tick emits a frame-scoped 'transition' message. The actual progress
289
+ * is computed from wall-clock time in the update handler, not from the
290
+ * interval count. The interval just schedules re-renders.
291
+ */
292
+ export function createTransitionTickCmd(durationMs, generation) {
293
+ return (emit) => new Promise((resolve) => {
294
+ if (durationMs <= 0) {
295
+ emit(wrapFrameMsg({ type: 'transition-complete', generation }));
296
+ resolve();
297
+ return;
298
+ }
299
+ const startMs = Date.now();
300
+ const intervalMs = Math.round(1000 / 60);
301
+ const id = setInterval(() => {
302
+ const elapsed = Date.now() - startMs;
303
+ const rawProgress = Math.min(1, elapsed / durationMs);
304
+ emit(wrapFrameMsg({ type: 'transition', progress: rawProgress, generation }));
305
+ if (rawProgress >= 1) {
306
+ clearInterval(id);
307
+ emit(wrapFrameMsg({ type: 'transition-complete', generation }));
308
+ resolve();
309
+ }
310
+ }, intervalMs);
311
+ });
312
+ }
313
+ //# sourceMappingURL=app-frame-actions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-frame-actions.js","sourceRoot":"","sources":["../src/app-frame-actions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Command palette integration for `app-frame.ts`.
3
+ *
4
+ * Handles palette key routing, entry building, and palette state management.
5
+ */
6
+ import type { FramePage, CreateFramedAppOptions } from './app-frame.js';
7
+ import type { InternalFrameModel, FrameAction, PaletteAction, PaletteEntry } from './app-frame-types.js';
8
+ import type { Cmd, KeyMsg } from './types.js';
9
+ import type { KeyMap } from './keybindings.js';
10
+ /** Route a key press through the command palette, returning updated model and commands. */
11
+ export declare function handlePaletteKey<PageModel, Msg>(msg: KeyMsg, model: InternalFrameModel<PageModel, Msg>, paletteKeys: KeyMap<PaletteAction>, options: CreateFramedAppOptions<PageModel, Msg>, pagesById: Map<string, FramePage<PageModel, Msg>>): [InternalFrameModel<PageModel, Msg>, Cmd<Msg>[]];
12
+ /** Initialize the command palette with entries from frame, global, page key maps, and custom page command items. */
13
+ export declare function openCommandPalette<PageModel, Msg>(model: InternalFrameModel<PageModel, Msg>, frameKeys: KeyMap<FrameAction>, options: CreateFramedAppOptions<PageModel, Msg>, pagesById: Map<string, FramePage<PageModel, Msg>>): InternalFrameModel<PageModel, Msg>;
14
+ /** Collect all available commands from frame, global, page, and custom sources. */
15
+ export declare function buildPaletteEntries<PageModel, Msg>(model: InternalFrameModel<PageModel, Msg>, frameKeys: KeyMap<FrameAction>, options: CreateFramedAppOptions<PageModel, Msg>, pagesById: Map<string, FramePage<PageModel, Msg>>): readonly PaletteEntry<Msg>[];
16
+ //# sourceMappingURL=app-frame-palette.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-frame-palette.d.ts","sourceRoot":"","sources":["../src/app-frame-palette.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AACxE,OAAO,KAAK,EACV,kBAAkB,EAClB,WAAW,EACX,aAAa,EACb,YAAY,EACb,MAAM,sBAAsB,CAAC;AAG9B,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAY/C,2FAA2F;AAC3F,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,GAAG,EAC7C,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,kBAAkB,CAAC,SAAS,EAAE,GAAG,CAAC,EACzC,WAAW,EAAE,MAAM,CAAC,aAAa,CAAC,EAClC,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,CA4DlD;AAED,oHAAoH;AACpH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,GAAG,EAC/C,KAAK,EAAE,kBAAkB,CAAC,SAAS,EAAE,GAAG,CAAC,EACzC,SAAS,EAAE,MAAM,CAAC,WAAW,CAAC,EAC9B,OAAO,EAAE,sBAAsB,CAAC,SAAS,EAAE,GAAG,CAAC,EAC/C,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC,GAChD,kBAAkB,CAAC,SAAS,EAAE,GAAG,CAAC,CAQpC;AAED,mFAAmF;AACnF,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,GAAG,EAChD,KAAK,EAAE,kBAAkB,CAAC,SAAS,EAAE,GAAG,CAAC,EACzC,SAAS,EAAE,MAAM,CAAC,WAAW,CAAC,EAC9B,OAAO,EAAE,sBAAsB,CAAC,SAAS,EAAE,GAAG,CAAC,EAC/C,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC,GAChD,SAAS,YAAY,CAAC,GAAG,CAAC,EAAE,CA+E9B"}
@@ -0,0 +1,158 @@
1
+ /**
2
+ * Command palette integration for `app-frame.ts`.
3
+ *
4
+ * Handles palette key routing, entry building, and palette state management.
5
+ */
6
+ import { comboToMsg, emitMsg, emitMsgForPage } from './app-frame-types.js';
7
+ import { applyFrameAction } from './app-frame-actions.js';
8
+ import { formatKeyCombo } from './keybindings.js';
9
+ import { createCommandPaletteState, cpFilter, cpFocusNext, cpFocusPrev, cpPageDown, cpPageUp, cpSelectedItem, } from './command-palette.js';
10
+ /** Route a key press through the command palette, returning updated model and commands. */
11
+ export function handlePaletteKey(msg, model, paletteKeys, options, pagesById) {
12
+ const cp = model.commandPalette;
13
+ const action = paletteKeys.handle(msg);
14
+ if (action != null) {
15
+ switch (action.type) {
16
+ case 'cp-next':
17
+ return [{ ...model, commandPalette: cpFocusNext(cp) }, []];
18
+ case 'cp-prev':
19
+ return [{ ...model, commandPalette: cpFocusPrev(cp) }, []];
20
+ case 'cp-page-down':
21
+ return [{ ...model, commandPalette: cpPageDown(cp) }, []];
22
+ case 'cp-page-up':
23
+ return [{ ...model, commandPalette: cpPageUp(cp) }, []];
24
+ case 'cp-close':
25
+ return [{ ...model, commandPalette: undefined, commandPaletteEntries: undefined }, []];
26
+ case 'cp-select': {
27
+ const selected = cpSelectedItem(cp);
28
+ if (selected == null) {
29
+ return [{ ...model, commandPalette: undefined, commandPaletteEntries: undefined }, []];
30
+ }
31
+ const entry = model.commandPaletteEntries?.find((x) => x.id === selected.id);
32
+ if (entry?.frameAction != null) {
33
+ const closed = { ...model, commandPalette: undefined, commandPaletteEntries: undefined };
34
+ return applyFrameAction(entry.frameAction, closed, options, pagesById);
35
+ }
36
+ if (entry?.msgAction !== undefined) {
37
+ const cmd = entry.targetPageId != null
38
+ ? emitMsgForPage(entry.targetPageId, entry.msgAction)
39
+ : emitMsg(entry.msgAction);
40
+ return [{
41
+ ...model,
42
+ commandPalette: undefined,
43
+ commandPaletteEntries: undefined,
44
+ }, [cmd]];
45
+ }
46
+ return [{ ...model, commandPalette: undefined, commandPaletteEntries: undefined }, []];
47
+ }
48
+ }
49
+ }
50
+ if (msg.key === 'backspace') {
51
+ const next = cpFilter(cp, cp.query.slice(0, -1));
52
+ return [{ ...model, commandPalette: next }, []];
53
+ }
54
+ if (msg.ctrl && msg.key === 'c') {
55
+ return [{ ...model, commandPalette: undefined, commandPaletteEntries: undefined }, []];
56
+ }
57
+ if (!msg.ctrl && !msg.alt && !msg.shift && msg.key === 'q' && cp.query.length === 0) {
58
+ return [{ ...model, commandPalette: undefined, commandPaletteEntries: undefined }, []];
59
+ }
60
+ if (!msg.ctrl && !msg.alt && msg.key.length === 1) {
61
+ const next = cpFilter(cp, cp.query + msg.key);
62
+ return [{ ...model, commandPalette: next }, []];
63
+ }
64
+ return [model, []];
65
+ }
66
+ /** Initialize the command palette with entries from frame, global, page key maps, and custom page command items. */
67
+ export function openCommandPalette(model, frameKeys, options, pagesById) {
68
+ const entries = buildPaletteEntries(model, frameKeys, options, pagesById);
69
+ const items = entries.map((x) => x.item);
70
+ return {
71
+ ...model,
72
+ commandPalette: createCommandPaletteState(items, Math.max(5, Math.min(10, model.rows - 8))),
73
+ commandPaletteEntries: entries,
74
+ };
75
+ }
76
+ /** Collect all available commands from frame, global, page, and custom sources. */
77
+ export function buildPaletteEntries(model, frameKeys, options, pagesById) {
78
+ const entries = [];
79
+ let seq = 0;
80
+ for (const b of frameKeys.bindings()) {
81
+ if (!b.enabled)
82
+ continue;
83
+ const action = frameKeys.handle(comboToMsg(b));
84
+ if (action === undefined)
85
+ continue;
86
+ const id = `frame:${seq++}`;
87
+ entries.push({
88
+ id,
89
+ item: {
90
+ id,
91
+ label: b.description,
92
+ category: 'Frame',
93
+ shortcut: formatKeyCombo(b.combo),
94
+ },
95
+ frameAction: action,
96
+ });
97
+ }
98
+ const global = options.globalKeys;
99
+ if (global != null) {
100
+ for (const b of global.bindings()) {
101
+ if (!b.enabled)
102
+ continue;
103
+ const action = global.handle(comboToMsg(b));
104
+ if (action === undefined)
105
+ continue;
106
+ const id = `global:${seq++}`;
107
+ entries.push({
108
+ id,
109
+ item: {
110
+ id,
111
+ label: b.description,
112
+ category: 'Global',
113
+ shortcut: formatKeyCombo(b.combo),
114
+ },
115
+ msgAction: action,
116
+ });
117
+ }
118
+ }
119
+ const page = pagesById.get(model.activePageId);
120
+ if (page.keyMap != null) {
121
+ for (const b of page.keyMap.bindings()) {
122
+ if (!b.enabled)
123
+ continue;
124
+ const action = page.keyMap.handle(comboToMsg(b));
125
+ if (action === undefined)
126
+ continue;
127
+ const id = `page:${seq++}`;
128
+ entries.push({
129
+ id,
130
+ item: {
131
+ id,
132
+ label: b.description,
133
+ category: page.title,
134
+ shortcut: formatKeyCombo(b.combo),
135
+ },
136
+ msgAction: action,
137
+ targetPageId: model.activePageId,
138
+ });
139
+ }
140
+ }
141
+ if (page.commandItems != null) {
142
+ for (const item of page.commandItems(model.pageModels[model.activePageId])) {
143
+ const id = `custom:${seq++}`;
144
+ entries.push({
145
+ id,
146
+ item: {
147
+ ...item,
148
+ id,
149
+ category: item.category ?? page.title,
150
+ },
151
+ msgAction: item.action,
152
+ targetPageId: model.activePageId,
153
+ });
154
+ }
155
+ }
156
+ return entries;
157
+ }
158
+ //# sourceMappingURL=app-frame-palette.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-frame-palette.js","sourceRoot":"","sources":["../src/app-frame-palette.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Layout rendering for `app-frame.ts`.
3
+ *
4
+ * Recursive tree renderer, page content, maximized pane, header/help lines,
5
+ * transition shader, and string-to-grid tokenization.
6
+ */
7
+ import { type BijouContext } from '@flyingrobots/bijou';
8
+ import type { FrameLayoutNode, FramePage, CreateFramedAppOptions } from './app-frame.js';
9
+ import type { InternalFrameModel, RenderContext, RenderResult, FrameAction } from './app-frame-types.js';
10
+ import type { LayoutRect } from './layout-rect.js';
11
+ import type { PageTransition } from './app-frame.js';
12
+ import type { KeyMap } from './keybindings.js';
13
+ /** Recursively render a layout tree node (pane, split, or grid) into a rect. */
14
+ export declare function renderFrameNode<PageModel, Msg>(node: FrameLayoutNode, rect: LayoutRect, ctx: RenderContext<PageModel, Msg>): RenderResult;
15
+ /** Render a placeholder for a grid area that has no matching cell definition. */
16
+ export declare function renderMissingGridCell(areaName: string, rect: LayoutRect): RenderResult;
17
+ /** Render a page's layout tree within the frame body rect. */
18
+ export declare function renderPageContent<PageModel, Msg>(pageId: string, model: InternalFrameModel<PageModel, Msg>, bodyRect: LayoutRect, pagesById: Map<string, FramePage<PageModel, Msg>>): RenderResult;
19
+ /** Render only the maximized pane at the full body rect. */
20
+ export declare function renderMaximizedPane<PageModel, Msg>(pageId: string, model: InternalFrameModel<PageModel, Msg>, bodyRect: LayoutRect, pagesById: Map<string, FramePage<PageModel, Msg>>, maximizedPaneId: string): RenderResult;
21
+ /** Render the top header line showing the app title and tab bar. */
22
+ export declare function renderHeaderLine<PageModel, Msg>(model: InternalFrameModel<PageModel, Msg>, options: CreateFramedAppOptions<PageModel, Msg>, pagesById: Map<string, FramePage<PageModel, Msg>>): string;
23
+ /** Render the bottom status line showing mode, focused pane, and key hints. */
24
+ export declare function renderHelpLine<PageModel, Msg>(model: InternalFrameModel<PageModel, Msg>, frameKeys: KeyMap<FrameAction>, options: CreateFramedAppOptions<PageModel, Msg>, activePage: FramePage<PageModel, Msg>): string;
25
+ /**
26
+ * Split a styled multiline string into a 2D grid of single-column characters.
27
+ * Each cell is a fully-styled string (including resets).
28
+ */
29
+ export declare function stringToGrid(str: string, width: number, height: number): string[][];
30
+ /**
31
+ * Apply a transition shader to blend between the previous and next page views.
32
+ *
33
+ * @param frame - Monotonic frame counter passed to shaders for temporal effects
34
+ * (glitch flickering, static noise). Defaults to 0 for stateless shaders.
35
+ */
36
+ export declare function renderTransition(prev: string, next: string, style: PageTransition, progress: number, width: number, height: number, ctx: BijouContext, frame?: number): string;
37
+ //# sourceMappingURL=app-frame-render.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-frame-render.d.ts","sourceRoot":"","sources":["../src/app-frame-render.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAkB,KAAK,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxE,OAAO,KAAK,EAAE,eAAe,EAAE,SAAS,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AACzF,OAAO,KAAK,EAAE,kBAAkB,EAAE,aAAa,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACzG,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAerD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAU/C,gFAAgF;AAChF,wBAAgB,eAAe,CAAC,SAAS,EAAE,GAAG,EAC5C,IAAI,EAAE,eAAe,EACrB,IAAI,EAAE,UAAU,EAChB,GAAG,EAAE,aAAa,CAAC,SAAS,EAAE,GAAG,CAAC,GACjC,YAAY,CAyJd;AAED,iFAAiF;AACjF,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,YAAY,CAMtF;AAED,8DAA8D;AAC9D,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,GAAG,EAC9C,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,kBAAkB,CAAC,SAAS,EAAE,GAAG,CAAC,EACzC,QAAQ,EAAE,UAAU,EACpB,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC,GAChD,YAAY,CAYd;AAED,4DAA4D;AAC5D,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,GAAG,EAChD,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,kBAAkB,CAAC,SAAS,EAAE,GAAG,CAAC,EACzC,QAAQ,EAAE,UAAU,EACpB,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC,EACjD,eAAe,EAAE,MAAM,GACtB,YAAY,CA2Bd;AAED,oEAAoE;AACpE,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,GAAG,EAC7C,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,MAAM,CAQR;AAED,+EAA+E;AAC/E,wBAAgB,cAAc,CAAC,SAAS,EAAE,GAAG,EAC3C,KAAK,EAAE,kBAAkB,CAAC,SAAS,EAAE,GAAG,CAAC,EACzC,SAAS,EAAE,MAAM,CAAC,WAAW,CAAC,EAC9B,OAAO,EAAE,sBAAsB,CAAC,SAAS,EAAE,GAAG,CAAC,EAC/C,UAAU,EAAE,SAAS,CAAC,SAAS,EAAE,GAAG,CAAC,GACpC,MAAM,CAmBR;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,EAAE,CASnF;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,cAAc,EACrB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,YAAY,EACjB,KAAK,SAAI,GACR,MAAM,CA8BR"}