@flyingrobots/bijou-tui-app 7.2.0 → 8.0.0-rc.1

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 (53) hide show
  1. package/dist/index.d.ts +3 -145
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +2 -436
  4. package/dist/index.js.map +1 -1
  5. package/dist/skeleton-chrome.d.ts +8 -0
  6. package/dist/skeleton-chrome.d.ts.map +1 -0
  7. package/dist/skeleton-chrome.js +39 -0
  8. package/dist/skeleton-chrome.js.map +1 -0
  9. package/dist/skeleton-contract.d.ts +6 -0
  10. package/dist/skeleton-contract.d.ts.map +1 -0
  11. package/dist/skeleton-contract.js +2 -0
  12. package/dist/skeleton-contract.js.map +1 -0
  13. package/dist/skeleton-create.d.ts +12 -0
  14. package/dist/skeleton-create.d.ts.map +1 -0
  15. package/dist/skeleton-create.js +84 -0
  16. package/dist/skeleton-create.js.map +1 -0
  17. package/dist/skeleton-drawer.d.ts +6 -0
  18. package/dist/skeleton-drawer.d.ts.map +1 -0
  19. package/dist/skeleton-drawer.js +50 -0
  20. package/dist/skeleton-drawer.js.map +1 -0
  21. package/dist/skeleton-keys.d.ts +4 -0
  22. package/dist/skeleton-keys.d.ts.map +1 -0
  23. package/dist/skeleton-keys.js +35 -0
  24. package/dist/skeleton-keys.js.map +1 -0
  25. package/dist/skeleton-layout.d.ts +6 -0
  26. package/dist/skeleton-layout.d.ts.map +1 -0
  27. package/dist/skeleton-layout.js +54 -0
  28. package/dist/skeleton-layout.js.map +1 -0
  29. package/dist/skeleton-overlays.d.ts +7 -0
  30. package/dist/skeleton-overlays.d.ts.map +1 -0
  31. package/dist/skeleton-overlays.js +78 -0
  32. package/dist/skeleton-overlays.js.map +1 -0
  33. package/dist/skeleton-page-contract.d.ts +28 -0
  34. package/dist/skeleton-page-contract.d.ts.map +1 -0
  35. package/dist/skeleton-page-contract.js +2 -0
  36. package/dist/skeleton-page-contract.js.map +1 -0
  37. package/dist/skeleton-page.d.ts +13 -0
  38. package/dist/skeleton-page.d.ts.map +1 -0
  39. package/dist/skeleton-page.js +73 -0
  40. package/dist/skeleton-page.js.map +1 -0
  41. package/dist/skeleton-state-contract.d.ts +21 -0
  42. package/dist/skeleton-state-contract.d.ts.map +1 -0
  43. package/dist/skeleton-state-contract.js +2 -0
  44. package/dist/skeleton-state-contract.js.map +1 -0
  45. package/dist/skeleton-tab-contract.d.ts +50 -0
  46. package/dist/skeleton-tab-contract.d.ts.map +1 -0
  47. package/dist/skeleton-tab-contract.js +2 -0
  48. package/dist/skeleton-tab-contract.js.map +1 -0
  49. package/dist/skeleton-theme-contract.d.ts +53 -0
  50. package/dist/skeleton-theme-contract.d.ts.map +1 -0
  51. package/dist/skeleton-theme-contract.js +2 -0
  52. package/dist/skeleton-theme-contract.js.map +1 -0
  53. package/package.json +3 -3
@@ -0,0 +1,39 @@
1
+ import { clipToWidth, statusBar, visibleLength, } from '@flyingrobots/bijou-tui';
2
+ export function renderTabRow(width, tabs, activeTabId, tokens, ctx) {
3
+ const header = tokens?.headerBgToken ?? ctx.theme.theme.surface.primary;
4
+ const active = tokens?.activeTabToken ?? ctx.theme.theme.surface.elevated;
5
+ const inactive = tokens?.inactiveTabToken ?? ctx.theme.theme.surface.secondary;
6
+ const content = tabs
7
+ .map((tab) => style(` ${tab.title} `, tab.id === activeTabId ? active : inactive, ctx))
8
+ .join(style(' | ', header, ctx));
9
+ return fillToWidth(content, width, header, ctx);
10
+ }
11
+ export function renderHeaderRow(width, title, activeTabTitle, tokens, ctx) {
12
+ return styledStatus(` ${title}`, activeTabTitle, width, tokens?.headerBgToken ?? ctx.theme.theme.surface.primary, ctx);
13
+ }
14
+ export function renderSeparatorRow(width, tokens, ctx) {
15
+ const token = tokens?.separatorToken ?? ctx.theme.theme.border.muted;
16
+ return style('─'.repeat(width), token, ctx);
17
+ }
18
+ export function renderFooterStatusRow(width, status, activeTabTitle, tokens, ctx) {
19
+ const token = tokens?.footerStatusToken ?? ctx.theme.theme.surface.secondary;
20
+ return styledStatus(` ${status}`, activeTabTitle, width, token, ctx);
21
+ }
22
+ export function renderFooterControlsRow(width, keyLegend, tokens, ctx) {
23
+ const token = tokens?.footerControlsToken ?? ctx.theme.theme.surface.primary;
24
+ return styledStatus(` ${keyLegend}`, '', width, token, ctx);
25
+ }
26
+ function styledStatus(left, right, width, token, ctx) {
27
+ return style(statusBar({ left, right, width }), token, ctx);
28
+ }
29
+ function fillToWidth(content, width, token, ctx) {
30
+ const clipped = clipToWidth(content, width);
31
+ const visible = visibleLength(clipped);
32
+ return visible >= width
33
+ ? clipped
34
+ : clipped + style(' '.repeat(width - visible), token, ctx);
35
+ }
36
+ function style(text, token, ctx) {
37
+ return text.length === 0 ? '' : ctx.style.styled(token, text);
38
+ }
39
+ //# sourceMappingURL=skeleton-chrome.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skeleton-chrome.js","sourceRoot":"","sources":["../src/skeleton-chrome.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /** Public contract aggregator for the TUI application skeleton. */
2
+ export type { SkeletonOverlayOptions, SkeletonPageConfig, SkeletonPageSpec, } from './skeleton-page-contract.js';
3
+ export type { SkeletonMsg, SkeletonPageModel, } from './skeleton-state-contract.js';
4
+ export type { SkeletonLayoutContext, SkeletonRenderContext, SkeletonStatusContext, SkeletonTab, } from './skeleton-tab-contract.js';
5
+ export type { CreateTuiAppSkeletonOptions, SkeletonThemeTokens, } from './skeleton-theme-contract.js';
6
+ //# sourceMappingURL=skeleton-contract.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skeleton-contract.d.ts","sourceRoot":"","sources":["../src/skeleton-contract.ts"],"names":[],"mappings":"AAAA,mEAAmE;AACnE,YAAY,EACV,sBAAsB,EACtB,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,6BAA6B,CAAC;AACrC,YAAY,EACV,WAAW,EACX,iBAAiB,GAClB,MAAM,8BAA8B,CAAC;AACtC,YAAY,EACV,qBAAqB,EACrB,qBAAqB,EACrB,qBAAqB,EACrB,WAAW,GACZ,MAAM,4BAA4B,CAAC;AACpC,YAAY,EACV,2BAA2B,EAC3B,mBAAmB,GACpB,MAAM,8BAA8B,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=skeleton-contract.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skeleton-contract.js","sourceRoot":"","sources":["../src/skeleton-contract.ts"],"names":[],"mappings":""}
@@ -0,0 +1,12 @@
1
+ import { type FramedApp } from '@flyingrobots/bijou-tui';
2
+ import type { CreateTuiAppSkeletonOptions, SkeletonMsg, SkeletonPageModel } from './skeleton-contract.js';
3
+ /**
4
+ * Create an opinionated full-screen framed application shell.
5
+ *
6
+ * The shell provides a tab bar, header, animated supplemental drawer, framed
7
+ * navigation, quit confirmation, two-line footer, and default drawer/split
8
+ * pages. Use it for multi-view applications that need persistent chrome.
9
+ * Prefer a smaller flow for one-shot prompts or document-style screens.
10
+ */
11
+ export declare function createTuiAppSkeleton(options: CreateTuiAppSkeletonOptions): FramedApp<SkeletonPageModel, SkeletonMsg>;
12
+ //# sourceMappingURL=skeleton-create.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skeleton-create.d.ts","sourceRoot":"","sources":["../src/skeleton-create.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,SAAS,EACf,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EACV,2BAA2B,EAC3B,WAAW,EACX,iBAAiB,EAElB,MAAM,wBAAwB,CAAC;AAkBhC;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,2BAA2B,GACnC,SAAS,CAAC,iBAAiB,EAAE,WAAW,CAAC,CA6E3C"}
@@ -0,0 +1,84 @@
1
+ import { createFramedApp, createKeyMap, } from '@flyingrobots/bijou-tui';
2
+ import { mergeKeyMaps } from './skeleton-keys.js';
3
+ import { layoutFor } from './skeleton-layout.js';
4
+ import { buildSkeletonOverlays } from './skeleton-overlays.js';
5
+ import { buildPageSpecs, createInitialPageModel, pageConfigFor, updateSkeletonPage, } from './skeleton-page.js';
6
+ const DEFAULT_TABS = [
7
+ { id: 'home', title: 'Home' },
8
+ { id: 'split', title: 'Split' },
9
+ ];
10
+ const DEFAULT_KEY_LEGEND = '[ ] pages | o drawer | tab panes | ctrl+p commands | q quit';
11
+ /**
12
+ * Create an opinionated full-screen framed application shell.
13
+ *
14
+ * The shell provides a tab bar, header, animated supplemental drawer, framed
15
+ * navigation, quit confirmation, two-line footer, and default drawer/split
16
+ * pages. Use it for multi-view applications that need persistent chrome.
17
+ * Prefer a smaller flow for one-shot prompts or document-style screens.
18
+ */
19
+ export function createTuiAppSkeleton(options) {
20
+ const tabs = options.tabs ?? DEFAULT_TABS;
21
+ const first = tabs[0];
22
+ if (first === undefined) {
23
+ throw new Error('createTuiAppSkeleton: "tabs" must contain at least one tab');
24
+ }
25
+ const seenTabIds = new Set();
26
+ for (const tab of tabs) {
27
+ if (seenTabIds.has(tab.id)) {
28
+ throw new Error(`createTuiAppSkeleton: duplicate tab id "${tab.id}"`);
29
+ }
30
+ if (tab.render != null && tab.layout != null) {
31
+ throw new Error(`createTuiAppSkeleton: tab "${tab.id}" cannot define both render and layout`);
32
+ }
33
+ seenTabIds.add(tab.id);
34
+ }
35
+ const tabsById = new Map(tabs.map((tab) => [tab.id, tab]));
36
+ const pageSpecs = buildPageSpecs(tabs);
37
+ const pageConfigs = new Map(pageSpecs.map((spec) => [spec.tab.id, pageConfigFor(spec)]));
38
+ const pages = pageSpecs.map((spec) => {
39
+ const config = pageConfigFor(spec);
40
+ return {
41
+ id: spec.tab.id,
42
+ title: spec.tab.title,
43
+ init: () => [createInitialPageModel(config), []],
44
+ update(msg, model) {
45
+ return updateSkeletonPage(msg, model, config);
46
+ },
47
+ layout: (model) => layoutFor(spec, options.ctx, model),
48
+ keyMap: config.hasDrawer
49
+ ? createKeyMap().group('Page', (group) => group.bind('o', 'Toggle drawer', { type: 'toggle-drawer' }))
50
+ : undefined,
51
+ };
52
+ });
53
+ const defaultGlobalKeys = createKeyMap().group('Global', (group) => group
54
+ .bind('q', 'Quit (confirm)', { type: 'request-quit' })
55
+ .bind('ctrl+c', 'Quit (confirm)', { type: 'request-quit' })
56
+ .bind('y', 'Confirm quit', { type: 'confirm-quit' })
57
+ .bind('enter', 'Confirm quit', { type: 'confirm-quit' })
58
+ .bind('n', 'Cancel quit', { type: 'cancel-quit' })
59
+ .bind('escape', 'Cancel quit', { type: 'cancel-quit' }));
60
+ return createFramedApp({
61
+ title: options.title ?? 'App',
62
+ pages,
63
+ defaultPageId: options.defaultTabId != null
64
+ && tabsById.has(options.defaultTabId)
65
+ ? options.defaultTabId
66
+ : first.id,
67
+ bodyTopRows: 2,
68
+ bodyBottomRows: 3,
69
+ globalKeys: mergeKeyMaps(defaultGlobalKeys, options.globalKeys),
70
+ enableCommandPalette: true,
71
+ overlayFactory: (frame) => buildSkeletonOverlays({
72
+ frame,
73
+ tabsById,
74
+ allTabs: tabs,
75
+ pageConfigs,
76
+ title: options.title ?? 'App',
77
+ keyLegend: options.keyLegend ?? DEFAULT_KEY_LEGEND,
78
+ statusMessage: options.statusMessage,
79
+ tokens: options.themeTokens,
80
+ ctx: options.ctx,
81
+ }),
82
+ });
83
+ }
84
+ //# sourceMappingURL=skeleton-create.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skeleton-create.js","sourceRoot":"","sources":["../src/skeleton-create.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { BijouContext } from '@flyingrobots/bijou';
2
+ import { type FrameOverlayContext, type Overlay } from '@flyingrobots/bijou-tui';
3
+ import type { SkeletonPageConfig, SkeletonPageModel, SkeletonThemeTokens } from './skeleton-contract.js';
4
+ /** Render the animated drawer when the active page owns one. */
5
+ export declare function maybeRenderDrawerOverlay(frame: FrameOverlayContext<SkeletonPageModel>, pageConfig: SkeletonPageConfig, width: number, height: number, tokens: SkeletonThemeTokens | undefined, ctx: BijouContext): Overlay | null;
6
+ //# sourceMappingURL=skeleton-drawer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skeleton-drawer.d.ts","sourceRoot":"","sources":["../src/skeleton-drawer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAEL,KAAK,mBAAmB,EACxB,KAAK,OAAO,EACb,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EACV,kBAAkB,EAClB,iBAAiB,EACjB,mBAAmB,EACpB,MAAM,wBAAwB,CAAC;AAGhC,gEAAgE;AAChE,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,mBAAmB,CAAC,iBAAiB,CAAC,EAC7C,UAAU,EAAE,kBAAkB,EAC9B,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,mBAAmB,GAAG,SAAS,EACvC,GAAG,EAAE,YAAY,GAChB,OAAO,GAAG,IAAI,CAgChB"}
@@ -0,0 +1,50 @@
1
+ import { drawer, } from '@flyingrobots/bijou-tui';
2
+ import { clamp01 } from './skeleton-page.js';
3
+ /** Render the animated drawer when the active page owns one. */
4
+ export function maybeRenderDrawerOverlay(frame, pageConfig, width, height, tokens, ctx) {
5
+ if (!pageConfig.hasDrawer)
6
+ return null;
7
+ const progress = clamp01(frame.pageModel.drawerProgress);
8
+ if (progress <= 0.01)
9
+ return null;
10
+ const region = pageConfig.drawerPaneId == null
11
+ ? frame.screenRect
12
+ : (frame.paneRects.get(pageConfig.drawerPaneId) ?? frame.screenRect);
13
+ if (region.width <= 0 || region.height <= 0)
14
+ return null;
15
+ const openWidth = clampInt(Math.max(22, Math.floor(region.width * 0.38)), 0, region.width);
16
+ const animatedWidth = clampInt(Math.round(openWidth * progress), 0, region.width);
17
+ if (animatedWidth < 6)
18
+ return null;
19
+ return drawer({
20
+ anchor: 'right',
21
+ title: 'Drawer',
22
+ content: drawerContent(frame.pageModel),
23
+ width: animatedWidth,
24
+ screenWidth: width,
25
+ screenHeight: height,
26
+ region,
27
+ borderToken: tokens?.drawerBorderToken ?? ctx.theme.theme.border.primary,
28
+ bgToken: tokens?.drawerBgToken ?? ctx.theme.theme.surface.overlay,
29
+ ctx,
30
+ });
31
+ }
32
+ function drawerContent(model) {
33
+ return [
34
+ 'Supplemental drawer',
35
+ '',
36
+ 'Use for side work.',
37
+ 'Keep the main pane active.',
38
+ '',
39
+ `Open: ${model.drawerOpen ? 'yes' : 'no'}`,
40
+ `Width: ${String(Math.round(clamp01(model.drawerProgress) * 100))}%`,
41
+ '',
42
+ 'o toggle drawer',
43
+ '[ / ] switch pages',
44
+ 'q quit (confirm)',
45
+ ].join('\n');
46
+ }
47
+ function clampInt(value, min, max) {
48
+ return Math.max(min, Math.min(max, Math.floor(value)));
49
+ }
50
+ //# sourceMappingURL=skeleton-drawer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skeleton-drawer.js","sourceRoot":"","sources":["../src/skeleton-drawer.ts"],"names":[],"mappings":"AACA,OAAO,EACL,MAAM,GAGP,MAAM,yBAAyB,CAAC;AAMjC,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAE7C,gEAAgE;AAChE,MAAM,UAAU,wBAAwB,CACtC,KAA6C,EAC7C,UAA8B,EAC9B,KAAa,EACb,MAAc,EACd,MAAuC,EACvC,GAAiB;IAEjB,IAAI,CAAC,UAAU,CAAC,SAAS;QAAE,OAAO,IAAI,CAAC;IACvC,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;IACzD,IAAI,QAAQ,IAAI,IAAI;QAAE,OAAO,IAAI,CAAC;IAClC,MAAM,MAAM,GAAG,UAAU,CAAC,YAAY,IAAI,IAAI;QAC5C,CAAC,CAAC,KAAK,CAAC,UAAU;QAClB,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,YAAY,CAAC,IAAI,KAAK,CAAC,UAAU,CAAC,CAAC;IACvE,IAAI,MAAM,CAAC,KAAK,IAAI,CAAC,IAAI,MAAM,CAAC,MAAM,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IACzD,MAAM,SAAS,GAAG,QAAQ,CACxB,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,EAC7C,CAAC,EACD,MAAM,CAAC,KAAK,CACb,CAAC;IACF,MAAM,aAAa,GAAG,QAAQ,CAC5B,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,QAAQ,CAAC,EAChC,CAAC,EACD,MAAM,CAAC,KAAK,CACb,CAAC;IACF,IAAI,aAAa,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IACnC,OAAO,MAAM,CAAC;QACZ,MAAM,EAAE,OAAO;QACf,KAAK,EAAE,QAAQ;QACf,OAAO,EAAE,aAAa,CAAC,KAAK,CAAC,SAAS,CAAC;QACvC,KAAK,EAAE,aAAa;QACpB,WAAW,EAAE,KAAK;QAClB,YAAY,EAAE,MAAM;QACpB,MAAM;QACN,WAAW,EACT,MAAM,EAAE,iBAAiB,IAAI,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO;QAC7D,OAAO,EAAE,MAAM,EAAE,aAAa,IAAI,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO;QACjE,GAAG;KACJ,CAAC,CAAC;AACL,CAAC;AAED,SAAS,aAAa,CAAC,KAAwB;IAC7C,OAAO;QACL,qBAAqB;QACrB,EAAE;QACF,oBAAoB;QACpB,4BAA4B;QAC5B,EAAE;QACF,SAAS,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE;QAC1C,UAAU,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,cAAc,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG;QACpE,EAAE;QACF,wBAAwB;QACxB,uBAAuB;QACvB,yBAAyB;KAC1B,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC;AAED,SAAS,QAAQ,CAAC,KAAa,EAAE,GAAW,EAAE,GAAW;IACvD,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACzD,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { type KeyMap } from '@flyingrobots/bijou-tui';
2
+ /** Merge enabled key bindings without mutating either source map. */
3
+ export declare function mergeKeyMaps<M>(base: KeyMap<M>, extra: KeyMap<M> | undefined): KeyMap<M>;
4
+ //# sourceMappingURL=skeleton-keys.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skeleton-keys.d.ts","sourceRoot":"","sources":["../src/skeleton-keys.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,MAAM,EAEZ,MAAM,yBAAyB,CAAC;AAEjC,qEAAqE;AACrE,wBAAgB,YAAY,CAAC,CAAC,EAC5B,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,EACf,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,SAAS,GAC3B,MAAM,CAAC,CAAC,CAAC,CAMX"}
@@ -0,0 +1,35 @@
1
+ import { createKeyMap, formatKeyCombo, } from '@flyingrobots/bijou-tui';
2
+ /** Merge enabled key bindings without mutating either source map. */
3
+ export function mergeKeyMaps(base, extra) {
4
+ if (extra == null)
5
+ return base;
6
+ const merged = createKeyMap();
7
+ bindMapInto(merged, base);
8
+ bindMapInto(merged, extra);
9
+ return merged;
10
+ }
11
+ function bindMapInto(target, source) {
12
+ for (const binding of source.bindings()) {
13
+ if (!binding.enabled)
14
+ continue;
15
+ const action = source.handle(comboToMsg(binding.combo));
16
+ if (action === undefined)
17
+ continue;
18
+ if (binding.group !== '') {
19
+ target.group(binding.group, (group) => group.bind(formatKeyCombo(binding.combo), binding.description, action));
20
+ }
21
+ else {
22
+ target.bind(formatKeyCombo(binding.combo), binding.description, action);
23
+ }
24
+ }
25
+ }
26
+ function comboToMsg(combo) {
27
+ return {
28
+ type: 'key',
29
+ key: combo.key,
30
+ ctrl: combo.ctrl,
31
+ alt: combo.alt,
32
+ shift: combo.shift,
33
+ };
34
+ }
35
+ //# sourceMappingURL=skeleton-keys.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skeleton-keys.js","sourceRoot":"","sources":["../src/skeleton-keys.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,cAAc,GAIf,MAAM,yBAAyB,CAAC;AAEjC,qEAAqE;AACrE,MAAM,UAAU,YAAY,CAC1B,IAAe,EACf,KAA4B;IAE5B,IAAI,KAAK,IAAI,IAAI;QAAE,OAAO,IAAI,CAAC;IAC/B,MAAM,MAAM,GAAG,YAAY,EAAK,CAAC;IACjC,WAAW,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAC1B,WAAW,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IAC3B,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,WAAW,CAAI,MAAiB,EAAE,MAAiB;IAC1D,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC;QACxC,IAAI,CAAC,OAAO,CAAC,OAAO;YAAE,SAAS;QAC/B,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;QACxD,IAAI,MAAM,KAAK,SAAS;YAAE,SAAS;QACnC,IAAI,OAAO,CAAC,KAAK,KAAK,EAAE,EAAE,CAAC;YACzB,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE,CACpC,KAAK,CAAC,IAAI,CACR,cAAc,CAAC,OAAO,CAAC,KAAK,CAAC,EAC7B,OAAO,CAAC,WAAW,EACnB,MAAM,CACP,CACF,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,IAAI,CACT,cAAc,CAAC,OAAO,CAAC,KAAK,CAAC,EAC7B,OAAO,CAAC,WAAW,EACnB,MAAM,CACP,CAAC;QACJ,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,UAAU,CAAC,KAAe;IACjC,OAAO;QACL,IAAI,EAAE,KAAK;QACX,GAAG,EAAE,KAAK,CAAC,GAAG;QACd,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,GAAG,EAAE,KAAK,CAAC,GAAG;QACd,KAAK,EAAE,KAAK,CAAC,KAAK;KACnB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,6 @@
1
+ import { type BijouContext } from '@flyingrobots/bijou';
2
+ import { type FrameLayoutNode } from '@flyingrobots/bijou-tui';
3
+ import type { SkeletonPageModel, SkeletonPageSpec } from './skeleton-contract.js';
4
+ /** Build the layout tree for a built-in or consumer-owned skeleton page. */
5
+ export declare function layoutFor(spec: SkeletonPageSpec, ctx: BijouContext, model: SkeletonPageModel): FrameLayoutNode;
6
+ //# sourceMappingURL=skeleton-layout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skeleton-layout.d.ts","sourceRoot":"","sources":["../src/skeleton-layout.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,YAAY,EAClB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAEL,KAAK,eAAe,EACrB,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EACV,iBAAiB,EACjB,gBAAgB,EACjB,MAAM,wBAAwB,CAAC;AAMhC,4EAA4E;AAC5E,wBAAgB,SAAS,CACvB,IAAI,EAAE,gBAAgB,EACtB,GAAG,EAAE,YAAY,EACjB,KAAK,EAAE,iBAAiB,GACvB,eAAe,CAwDjB"}
@@ -0,0 +1,54 @@
1
+ import { createSurface, } from '@flyingrobots/bijou';
2
+ import { createSplitPaneState, } from '@flyingrobots/bijou-tui';
3
+ import { drawerPaneId } from './skeleton-page.js';
4
+ import { renderSplitPaneLabelSurface } from './split-pane-surface.js';
5
+ const DEFAULT_SPLIT_RATIO = 1 / 3;
6
+ /** Build the layout tree for a built-in or consumer-owned skeleton page. */
7
+ export function layoutFor(spec, ctx, model) {
8
+ if (spec.tab.layout != null) {
9
+ return spec.tab.layout({ ctx, tab: spec.tab, model });
10
+ }
11
+ if (spec.tab.render != null) {
12
+ const render = spec.tab.render;
13
+ return {
14
+ kind: 'pane',
15
+ paneId: drawerPaneId(spec.tab.id),
16
+ render: (width, height) => render(width, height, {
17
+ ctx,
18
+ tab: spec.tab,
19
+ model,
20
+ }),
21
+ };
22
+ }
23
+ if (spec.kind === 'drawer') {
24
+ return {
25
+ kind: 'pane',
26
+ paneId: drawerPaneId(spec.tab.id),
27
+ render: () => createSurface(0, 0),
28
+ };
29
+ }
30
+ if (spec.kind === 'split') {
31
+ return {
32
+ kind: 'split',
33
+ splitId: `${spec.tab.id}-split`,
34
+ direction: 'row',
35
+ state: createSplitPaneState({ ratio: DEFAULT_SPLIT_RATIO }),
36
+ paneA: {
37
+ kind: 'pane',
38
+ paneId: `${spec.tab.id}-left`,
39
+ render: (width, height) => renderSplitPaneLabelSurface('Primary workspace (1/3)', width, height, ctx),
40
+ },
41
+ paneB: {
42
+ kind: 'pane',
43
+ paneId: `${spec.tab.id}-right`,
44
+ render: (width, height) => renderSplitPaneLabelSurface('Secondary context (2/3)', width, height, ctx),
45
+ },
46
+ };
47
+ }
48
+ return {
49
+ kind: 'pane',
50
+ paneId: drawerPaneId(spec.tab.id),
51
+ render: () => createSurface(0, 0),
52
+ };
53
+ }
54
+ //# sourceMappingURL=skeleton-layout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skeleton-layout.js","sourceRoot":"","sources":["../src/skeleton-layout.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,GAEd,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,oBAAoB,GAErB,MAAM,yBAAyB,CAAC;AAKjC,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,2BAA2B,EAAE,MAAM,yBAAyB,CAAC;AAEtE,MAAM,mBAAmB,GAAG,CAAC,GAAG,CAAC,CAAC;AAElC,4EAA4E;AAC5E,MAAM,UAAU,SAAS,CACvB,IAAsB,EACtB,GAAiB,EACjB,KAAwB;IAExB,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM,IAAI,IAAI,EAAE,CAAC;QAC5B,OAAO,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC;IACxD,CAAC;IACD,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM,IAAI,IAAI,EAAE,CAAC;QAC5B,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC;QAC/B,OAAO;YACL,IAAI,EAAE,MAAM;YACZ,MAAM,EAAE,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YACjC,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE;gBAC/C,GAAG;gBACH,GAAG,EAAE,IAAI,CAAC,GAAG;gBACb,KAAK;aACN,CAAC;SACH,CAAC;IACJ,CAAC;IACD,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC3B,OAAO;YACL,IAAI,EAAE,MAAM;YACZ,MAAM,EAAE,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YACjC,MAAM,EAAE,GAAG,EAAE,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC;SAClC,CAAC;IACJ,CAAC;IACD,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QAC1B,OAAO;YACL,IAAI,EAAE,OAAO;YACb,OAAO,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,QAAQ;YAC/B,SAAS,EAAE,KAAK;YAChB,KAAK,EAAE,oBAAoB,CAAC,EAAE,KAAK,EAAE,mBAAmB,EAAE,CAAC;YAC3D,KAAK,EAAE;gBACL,IAAI,EAAE,MAAM;gBACZ,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,OAAO;gBAC7B,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC,2BAA2B,CACpD,yBAAyB,EACzB,KAAK,EACL,MAAM,EACN,GAAG,CACJ;aACF;YACD,KAAK,EAAE;gBACL,IAAI,EAAE,MAAM;gBACZ,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,QAAQ;gBAC9B,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC,2BAA2B,CACpD,yBAAyB,EACzB,KAAK,EACL,MAAM,EACN,GAAG,CACJ;aACF;SACF,CAAC;IACJ,CAAC;IACD,OAAO;QACL,IAAI,EAAE,MAAM;QACZ,MAAM,EAAE,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QACjC,MAAM,EAAE,GAAG,EAAE,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC;KAClC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,7 @@
1
+ import { type Overlay } from '@flyingrobots/bijou-tui';
2
+ import type { SkeletonOverlayOptions } from './skeleton-contract.js';
3
+ /** Resolve the quit modal width without crossing the terminal's lower bound. */
4
+ export declare function resolveQuitModalWidth(width: number): number;
5
+ /** Assemble the shell overlay stack in terminal z-order. */
6
+ export declare function buildSkeletonOverlays(options: SkeletonOverlayOptions): readonly Overlay[];
7
+ //# sourceMappingURL=skeleton-overlays.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skeleton-overlays.d.ts","sourceRoot":"","sources":["../src/skeleton-overlays.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,OAAO,EACb,MAAM,yBAAyB,CAAC;AAQjC,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAGrE,gFAAgF;AAChF,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE3D;AAED,4DAA4D;AAC5D,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,sBAAsB,GAC9B,SAAS,OAAO,EAAE,CAiEpB"}
@@ -0,0 +1,78 @@
1
+ import { modal, } from '@flyingrobots/bijou-tui';
2
+ import { renderFooterControlsRow, renderFooterStatusRow, renderHeaderRow, renderSeparatorRow, renderTabRow, } from './skeleton-chrome.js';
3
+ import { maybeRenderDrawerOverlay } from './skeleton-drawer.js';
4
+ /** Resolve the quit modal width without crossing the terminal's lower bound. */
5
+ export function resolveQuitModalWidth(width) {
6
+ return Math.max(0, Math.min(56, width - 2, Math.max(20, width - 4)));
7
+ }
8
+ /** Assemble the shell overlay stack in terminal z-order. */
9
+ export function buildSkeletonOverlays(options) {
10
+ const width = Math.max(0, options.frame.screenRect.width);
11
+ const height = Math.max(0, options.frame.screenRect.height);
12
+ if (width <= 0 || height <= 0)
13
+ return [];
14
+ const tab = options.tabsById.get(options.frame.activePageId) ?? options.allTabs[0];
15
+ if (tab == null)
16
+ return [];
17
+ const pageConfig = options.pageConfigs.get(tab.id) ?? { hasDrawer: false };
18
+ const status = typeof options.statusMessage === 'function'
19
+ ? options.statusMessage({
20
+ activeTabId: tab.id,
21
+ activeTabTitle: tab.title,
22
+ })
23
+ : (options.statusMessage ?? `${tab.title} ready`);
24
+ const overlays = [{
25
+ row: 0,
26
+ col: 0,
27
+ content: renderTabRow(width, options.allTabs, tab.id, options.tokens, options.ctx),
28
+ }];
29
+ if (height >= 5) {
30
+ overlays.push({
31
+ row: 1,
32
+ col: 0,
33
+ content: renderHeaderRow(width, options.title, tab.title, options.tokens, options.ctx),
34
+ });
35
+ }
36
+ const drawer = maybeRenderDrawerOverlay(options.frame, pageConfig, width, height, options.tokens, options.ctx);
37
+ if (drawer != null)
38
+ overlays.push(drawer);
39
+ appendFooter(overlays, options, width, height, status, tab.title);
40
+ if (options.frame.pageModel.quitConfirmOpen) {
41
+ overlays.push(modal({
42
+ title: 'Quit App?',
43
+ body: 'Exit this TUI session now?',
44
+ hint: 'Y / Enter confirm • N / Esc cancel',
45
+ width: resolveQuitModalWidth(width),
46
+ screenWidth: width,
47
+ screenHeight: height,
48
+ borderToken: options.tokens?.modalBorderToken ?? options.ctx.theme.theme.border.warning,
49
+ bgToken: options.tokens?.modalBgToken ?? options.ctx.theme.theme.surface.overlay,
50
+ ctx: options.ctx,
51
+ }));
52
+ }
53
+ return overlays;
54
+ }
55
+ function appendFooter(overlays, options, width, height, status, tabTitle) {
56
+ if (height >= 3) {
57
+ if (height >= 4) {
58
+ overlays.push({
59
+ row: height - 3,
60
+ col: 0,
61
+ content: renderSeparatorRow(width, options.tokens, options.ctx),
62
+ });
63
+ }
64
+ overlays.push({
65
+ row: height - 2,
66
+ col: 0,
67
+ content: renderFooterStatusRow(width, status, tabTitle, options.tokens, options.ctx),
68
+ });
69
+ }
70
+ if (height >= 2) {
71
+ overlays.push({
72
+ row: height - 1,
73
+ col: 0,
74
+ content: renderFooterControlsRow(width, options.keyLegend, options.tokens, options.ctx),
75
+ });
76
+ }
77
+ }
78
+ //# sourceMappingURL=skeleton-overlays.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skeleton-overlays.js","sourceRoot":"","sources":["../src/skeleton-overlays.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import type { BijouContext } from '@flyingrobots/bijou';
2
+ import type { FrameOverlayContext } from '@flyingrobots/bijou-tui';
3
+ import type { SkeletonPageModel } from './skeleton-state-contract.js';
4
+ import type { SkeletonStatusContext, SkeletonTab } from './skeleton-tab-contract.js';
5
+ import type { SkeletonThemeTokens } from './skeleton-theme-contract.js';
6
+ /** Per-page configuration derived from the page spec. */
7
+ export interface SkeletonPageConfig {
8
+ readonly hasDrawer: boolean;
9
+ readonly drawerPaneId?: string;
10
+ }
11
+ /** A tab and its resolved built-in layout kind. */
12
+ export interface SkeletonPageSpec {
13
+ readonly tab: SkeletonTab;
14
+ readonly kind: 'drawer' | 'split' | 'empty' | 'custom';
15
+ }
16
+ /** Dependencies needed to assemble shell overlays. */
17
+ export interface SkeletonOverlayOptions {
18
+ readonly frame: FrameOverlayContext<SkeletonPageModel>;
19
+ readonly tabsById: ReadonlyMap<string, SkeletonTab>;
20
+ readonly allTabs: readonly SkeletonTab[];
21
+ readonly pageConfigs: ReadonlyMap<string, SkeletonPageConfig>;
22
+ readonly title: string;
23
+ readonly keyLegend: string;
24
+ readonly statusMessage?: string | ((ctx: SkeletonStatusContext) => string);
25
+ readonly tokens?: SkeletonThemeTokens;
26
+ readonly ctx: BijouContext;
27
+ }
28
+ //# sourceMappingURL=skeleton-page-contract.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skeleton-page-contract.d.ts","sourceRoot":"","sources":["../src/skeleton-page-contract.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACtE,OAAO,KAAK,EACV,qBAAqB,EACrB,WAAW,EACZ,MAAM,4BAA4B,CAAC;AACpC,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAExE,yDAAyD;AACzD,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;CAChC;AAED,mDAAmD;AACnD,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,GAAG,EAAE,WAAW,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,GAAG,OAAO,GAAG,QAAQ,CAAC;CACxD;AAED,sDAAsD;AACtD,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,KAAK,EAAE,mBAAmB,CAAC,iBAAiB,CAAC,CAAC;IACvD,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IACpD,QAAQ,CAAC,OAAO,EAAE,SAAS,WAAW,EAAE,CAAC;IACzC,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;IAC9D,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,GAAG,EAAE,qBAAqB,KAAK,MAAM,CAAC,CAAC;IAC3E,QAAQ,CAAC,MAAM,CAAC,EAAE,mBAAmB,CAAC;IACtC,QAAQ,CAAC,GAAG,EAAE,YAAY,CAAC;CAC5B"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=skeleton-page-contract.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skeleton-page-contract.js","sourceRoot":"","sources":["../src/skeleton-page-contract.ts"],"names":[],"mappings":""}
@@ -0,0 +1,13 @@
1
+ import { type Cmd, type FramePageMsg } from '@flyingrobots/bijou-tui';
2
+ import type { SkeletonMsg, SkeletonPageConfig, SkeletonPageModel, SkeletonPageSpec, SkeletonTab } from './skeleton-contract.js';
3
+ /** Map tabs to built-in or consumer-owned page shapes. */
4
+ export declare function buildPageSpecs(tabs: readonly SkeletonTab[]): readonly SkeletonPageSpec[];
5
+ /** Derive drawer ownership from a page spec. */
6
+ export declare function pageConfigFor(spec: SkeletonPageSpec): SkeletonPageConfig;
7
+ /** Create the initial page-owned shell state. */
8
+ export declare function createInitialPageModel(config: SkeletonPageConfig): SkeletonPageModel;
9
+ /** Apply a skeleton message without taking ownership of host input messages. */
10
+ export declare function updateSkeletonPage(msg: FramePageMsg<SkeletonMsg>, model: SkeletonPageModel, config: SkeletonPageConfig): [SkeletonPageModel, Cmd<SkeletonMsg>[]];
11
+ export declare function drawerPaneId(tabId: string): string;
12
+ export declare function clamp01(value: number): number;
13
+ //# sourceMappingURL=skeleton-page.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skeleton-page.d.ts","sourceRoot":"","sources":["../src/skeleton-page.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,GAAG,EACR,KAAK,YAAY,EAClB,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EACV,WAAW,EACX,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,EAChB,WAAW,EACZ,MAAM,wBAAwB,CAAC;AAEhC,0DAA0D;AAC1D,wBAAgB,cAAc,CAC5B,IAAI,EAAE,SAAS,WAAW,EAAE,GAC3B,SAAS,gBAAgB,EAAE,CAO7B;AAED,gDAAgD;AAChD,wBAAgB,aAAa,CAC3B,IAAI,EAAE,gBAAgB,GACrB,kBAAkB,CAIpB;AAED,iDAAiD;AACjD,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,kBAAkB,GACzB,iBAAiB,CAOnB;AAED,gFAAgF;AAChF,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,YAAY,CAAC,WAAW,CAAC,EAC9B,KAAK,EAAE,iBAAiB,EACxB,MAAM,EAAE,kBAAkB,GACzB,CAAC,iBAAiB,EAAE,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC,CAmCzC;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAElD;AAED,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAG7C"}
@@ -0,0 +1,73 @@
1
+ import { animate, quit, } from '@flyingrobots/bijou-tui';
2
+ /** Map tabs to built-in or consumer-owned page shapes. */
3
+ export function buildPageSpecs(tabs) {
4
+ return tabs.map((tab, index) => ({
5
+ tab,
6
+ kind: tab.render != null || tab.layout != null
7
+ ? 'custom'
8
+ : (index === 0 ? 'drawer' : (index === 1 ? 'split' : 'empty')),
9
+ }));
10
+ }
11
+ /** Derive drawer ownership from a page spec. */
12
+ export function pageConfigFor(spec) {
13
+ return spec.kind === 'drawer'
14
+ ? { hasDrawer: true, drawerPaneId: drawerPaneId(spec.tab.id) }
15
+ : { hasDrawer: false };
16
+ }
17
+ /** Create the initial page-owned shell state. */
18
+ export function createInitialPageModel(config) {
19
+ return {
20
+ ready: true,
21
+ drawerOpen: config.hasDrawer,
22
+ drawerProgress: config.hasDrawer ? 1 : 0,
23
+ quitConfirmOpen: false,
24
+ };
25
+ }
26
+ /** Apply a skeleton message without taking ownership of host input messages. */
27
+ export function updateSkeletonPage(msg, model, config) {
28
+ if (msg.type === 'mouse' || msg.type === 'pulse')
29
+ return [model, []];
30
+ switch (msg.type) {
31
+ case 'request-quit':
32
+ return model.quitConfirmOpen
33
+ ? [model, []]
34
+ : [{ ...model, quitConfirmOpen: true }, []];
35
+ case 'cancel-quit':
36
+ return !model.quitConfirmOpen
37
+ ? [model, []]
38
+ : [{ ...model, quitConfirmOpen: false }, []];
39
+ case 'confirm-quit':
40
+ return !model.quitConfirmOpen
41
+ ? [model, []]
42
+ : [{ ...model, quitConfirmOpen: false }, [quit()]];
43
+ case 'toggle-drawer': {
44
+ if (!config.hasDrawer)
45
+ return [model, []];
46
+ const drawerOpen = !model.drawerOpen;
47
+ return [{ ...model, drawerOpen }, [
48
+ animate({
49
+ from: model.drawerProgress,
50
+ to: drawerOpen ? 1 : 0,
51
+ spring: 'default',
52
+ onFrame: (value) => ({
53
+ type: 'drawer-progress',
54
+ value,
55
+ }),
56
+ }),
57
+ ]];
58
+ }
59
+ case 'drawer-progress':
60
+ return !config.hasDrawer
61
+ ? [model, []]
62
+ : [{ ...model, drawerProgress: clamp01(msg.value) }, []];
63
+ }
64
+ }
65
+ export function drawerPaneId(tabId) {
66
+ return `${tabId}-main`;
67
+ }
68
+ export function clamp01(value) {
69
+ if (!Number.isFinite(value) || value < 0)
70
+ return 0;
71
+ return value > 1 ? 1 : value;
72
+ }
73
+ //# sourceMappingURL=skeleton-page.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skeleton-page.js","sourceRoot":"","sources":["../src/skeleton-page.ts"],"names":[],"mappings":"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"}