@nmakarov/cli-toolkit 0.68.0 → 0.69.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/dist/cli-runner.cjs +21 -17
- package/dist/cli-runner.cjs.map +1 -1
- package/dist/cli-runner.js +21 -17
- package/dist/cli-runner.js.map +1 -1
- package/dist/index.cjs +21 -17
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +21 -17
- package/dist/index.js.map +1 -1
- package/dist/init.cjs +21 -17
- package/dist/init.cjs.map +1 -1
- package/dist/init.js +21 -17
- package/dist/init.js.map +1 -1
- package/dist/screen.cjs +19 -16
- package/dist/screen.cjs.map +1 -1
- package/dist/screen.js +19 -16
- package/dist/screen.js.map +1 -1
- package/package.json +1 -1
package/dist/screen.js
CHANGED
|
@@ -914,6 +914,8 @@ function InputField({ prompt, value, onChange: _onChange, onSubmit: _onSubmit })
|
|
|
914
914
|
import { useState as useState3, useEffect as useEffect2, useMemo, useRef as useRef2, createElement as createElement2 } from "react";
|
|
915
915
|
import { Box as Box4, Text as Text5 } from "ink";
|
|
916
916
|
var h5 = createElement2;
|
|
917
|
+
var BAR_THUMB = "#";
|
|
918
|
+
var BAR_TRACK = "|";
|
|
917
919
|
function wrapTextLines(text, cols) {
|
|
918
920
|
const w = Math.max(1, Math.floor(Number(cols) || 1));
|
|
919
921
|
const out = [];
|
|
@@ -942,7 +944,7 @@ function scrollbarGlyphs(viewportRows, totalLines, scrollTop) {
|
|
|
942
944
|
const thumbStart = maxScroll === 0 ? 0 : Math.round(s / maxScroll * travel);
|
|
943
945
|
const glyphs = [];
|
|
944
946
|
for (let i = 0; i < view; i++) {
|
|
945
|
-
glyphs.push(i >= thumbStart && i < thumbStart + thumbSize ?
|
|
947
|
+
glyphs.push(i >= thumbStart && i < thumbStart + thumbSize ? BAR_THUMB : BAR_TRACK);
|
|
946
948
|
}
|
|
947
949
|
return glyphs;
|
|
948
950
|
}
|
|
@@ -974,20 +976,19 @@ function ScrollableText({
|
|
|
974
976
|
}) {
|
|
975
977
|
const [scrollTop, setScrollTop] = useState3(0);
|
|
976
978
|
const [, bump] = useState3(0);
|
|
977
|
-
const termCols = process.stdout.columns || 80;
|
|
978
979
|
const termRows = process.stdout.rows || 24;
|
|
979
980
|
const viewportRows = Math.max(
|
|
980
981
|
4,
|
|
981
982
|
maxHeight != null ? Math.floor(maxHeight) : Math.max(8, termRows - 8)
|
|
982
983
|
);
|
|
983
|
-
const
|
|
984
|
-
const
|
|
984
|
+
const contentCols = Math.max(20, getScreenWidth() - 4);
|
|
985
|
+
const barCols = showScrollbar ? 1 : 0;
|
|
986
|
+
const textWidth = Math.max(8, contentCols - barCols);
|
|
985
987
|
const allLines = useMemo(() => {
|
|
986
988
|
if (Array.isArray(linesProp)) return linesProp.map((l) => String(l ?? ""));
|
|
987
|
-
return wrap ? wrapTextLines(text,
|
|
988
|
-
}, [linesProp, text, wrap,
|
|
989
|
+
return wrap ? wrapTextLines(text, textWidth) : String(text ?? "").split("\n");
|
|
990
|
+
}, [linesProp, text, wrap, textWidth]);
|
|
989
991
|
const needsBar = showScrollbar && allLines.length > viewportRows;
|
|
990
|
-
const textWidth = Math.max(8, termCols - (needsBar ? 1 : 0));
|
|
991
992
|
const maxScroll = Math.max(0, allLines.length - viewportRows);
|
|
992
993
|
const clamped = Math.min(Math.max(0, scrollTop), maxScroll);
|
|
993
994
|
const visible = allLines.slice(clamped, clamped + viewportRows);
|
|
@@ -1027,22 +1028,24 @@ function ScrollableText({
|
|
|
1027
1028
|
const status = allLines.length === 0 ? "empty" : `lines ${clamped + 1}-${Math.min(clamped + visible.length, allLines.length)} of ${allLines.length}` + (needsBar ? " \xB7 \u2325\u2191/\u2193 or PgUp/Dn page" : "");
|
|
1028
1029
|
const rowNodes = visible.map((line, i) => {
|
|
1029
1030
|
const body = padEndVisible(line, textWidth);
|
|
1030
|
-
const glyph = bar ? bar[i] ?? "
|
|
1031
|
+
const glyph = bar ? bar[i] ?? BAR_TRACK : showScrollbar ? " " : "";
|
|
1032
|
+
const isThumb = glyph === BAR_THUMB;
|
|
1031
1033
|
return h5(
|
|
1032
|
-
|
|
1033
|
-
{ key: `L${clamped + i}
|
|
1034
|
-
|
|
1035
|
-
glyph ? h5(Text5, { color:
|
|
1034
|
+
Text5,
|
|
1035
|
+
{ key: `L${clamped + i}` },
|
|
1036
|
+
body,
|
|
1037
|
+
glyph ? h5(Text5, { color: isThumb ? "cyan" : "gray" }, glyph) : null
|
|
1036
1038
|
);
|
|
1037
1039
|
});
|
|
1038
1040
|
if (bar && visible.length < viewportRows) {
|
|
1039
1041
|
for (let i = visible.length; i < viewportRows; i++) {
|
|
1042
|
+
const glyph = bar[i] ?? BAR_TRACK;
|
|
1040
1043
|
rowNodes.push(
|
|
1041
1044
|
h5(
|
|
1042
|
-
|
|
1043
|
-
{ key: `pad${i}
|
|
1044
|
-
|
|
1045
|
-
h5(Text5, { color:
|
|
1045
|
+
Text5,
|
|
1046
|
+
{ key: `pad${i}` },
|
|
1047
|
+
padEndVisible("", textWidth),
|
|
1048
|
+
h5(Text5, { color: glyph === BAR_THUMB ? "cyan" : "gray" }, glyph)
|
|
1046
1049
|
)
|
|
1047
1050
|
);
|
|
1048
1051
|
}
|
package/dist/screen.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/screen/index.js","../src/screen/screens.js","../src/screen/components.js","../src/screen/list-components.js","../src/screen/key-bindings.js","../src/screen/ui-elements.js","../src/screen/scrollable-text.js","../src/screen/utils.js","../src/screen/footer-builder.js"],"sourcesContent":["/**\n * Screen System - Action-based architecture\n * Converted from legacy/screenSystem/src\n */\n\n// Re-export React and React hooks (encapsulated)\nimport React, { useState, useEffect, useLayoutEffect, useRef, useMemo, useCallback, memo, createElement } from \"react\";\nexport { React, useState, useEffect, useLayoutEffect, useRef, useMemo, useCallback, memo };\nexport { createElement as h };\n\n// Re-export Ink components (encapsulated)\nexport { Box, Text, useInput } from \"ink\";\n\n// Screen functions\nexport {\n showScreen,\n showListScreen,\n showMultiColumnListScreen,\n showMultiColumnListWithPreviewScreen,\n // Backward compatibility aliases\n showMenuScreen,\n showWordGridScreen\n} from \"./screens.js\";\n\n// Reusable components\nexport { MultiColumnListComponent, MultiColumnListWithPreviewComponent, ListComponent } from \"./list-components.js\";\nexport { ScreenContainer, ScreenRow, ScreenTitle, ScreenBody, ScreenFooter, ScreenDivider } from \"./components.js\";\nexport { ListItem, TextBlock, Divider, GridCell, InputField } from \"./ui-elements.js\";\nexport { ScrollableText, wrapTextLines, scrollbarGlyphs } from \"./scrollable-text.js\";\nexport {\n bindingIdentity,\n bindingMatchesInput,\n formatBindingKey,\n} from \"./key-bindings.js\";\n\n// Utilities\nexport { buildBreadcrumb, buildDetailBreadcrumb } from \"./utils.js\";\nexport { buildFooter, FooterPresets, organizeFooterMessages } from \"./footer-builder.js\";\n\n// For CommonJS compatibility: pre-load ESM dependencies\nlet loadPromise = null;\nexport async function load() {\n if (loadPromise) return loadPromise;\n loadPromise = Promise.all([\n import(\"react\"),\n import(\"ink\")\n ]).then(() => {}) ;\n return loadPromise;\n}\n// Auto-load in ESM, but CJS users should call load() explicitly\nif (typeof window === \"undefined\") {\n load().catch(() => {\n // Ignore errors during auto-load, user can call load() explicitly\n });\n}\n","/**\n * Screen System - Action-based architecture\n */\n\nimport { useState, createElement as h } from \"react\";\nimport { render, useInput, Text } from \"ink\";\nimport { ScreenContainer, ScreenRow, ScreenTitle, ScreenDivider, ScreenFooter } from \"./components.js\";\nimport { MultiColumnListComponent, MultiColumnListWithPreviewComponent, ListComponent } from \"./list-components.js\";\nimport {\n bindingIdentity,\n bindingMatchesInput,\n formatBindingKey,\n} from \"./key-bindings.js\";\n\n// Types\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n/**\n * Group key bindings by caption for footer display\n */\nexport function groupKeyBindings(bindings) {\n const groups = {};\n\n // Filter out disabled bindings\n const enabledBindings = bindings.filter(b => b.enabled !== false);\n\n enabledBindings.forEach(binding => {\n const caption = typeof binding.caption === \"string\" ? binding.caption : \"\";\n if (!groups[caption]) {\n groups[caption] = {\n keys: [],\n caption: caption,\n order: binding.order || 999\n };\n }\n groups[caption].keys.push(formatBindingKey(binding));\n });\n\n return Object.values(groups);\n}\n\n/**\n * Format key bindings for footer (returns array of strings/components)\n */\nexport function formatKeyBindings(bindings, mode = \"long\") {\n // Resolve function captions\n const resolvedBindings = bindings.map(binding => {\n let resolvedCaption = binding.caption;\n\n // If caption is a function, call it\n if (typeof binding.caption === \"function\") {\n resolvedCaption = binding.caption();\n }\n\n return {\n ...binding,\n resolvedCaption\n };\n });\n\n const groups = groupKeyBindings(resolvedBindings.map(b => ({\n ...b,\n caption: typeof b.resolvedCaption === \"string\" ? b.resolvedCaption : \"\"\n })));\n\n // Sort by order\n groups.sort((a, b) => a.order - b.order);\n\n const items = [];\n\n groups.forEach(group => {\n // Check if any binding in this group has a component/custom caption\n const bindingWithCustom = resolvedBindings.find(b =>\n group.keys.includes(b.key) && typeof b.resolvedCaption !== \"string\"\n );\n\n if (bindingWithCustom && bindingWithCustom.resolvedCaption) {\n // Use the full custom display (component or complex structure)\n items.push(bindingWithCustom.resolvedCaption );\n } else {\n // Standard format with string caption\n const keyStr = formatKeys(group.keys);\n\n if (mode === \"long\") {\n items.push(`${keyStr} to ${group.caption}`);\n } else {\n items.push(keyStr);\n }\n }\n });\n\n return items;\n}\n\n/**\n * Format keys for display\n */\nexport function formatKeys(keys) {\n // `keys` may already be display labels (from groupKeyBindings) or raw key names.\n const keyMap = {\n escape: \"esc\",\n leftArrow: \"←\",\n rightArrow: \"→\",\n upArrow: \"↑\",\n downArrow: \"↓\",\n return: \"enter\",\n pageUp: \"PgUp\",\n pageDown: \"PgDn\",\n };\n\n return keys.map((k) => keyMap[k] || k).join(\"/\");\n}\n\n/**\n * Show screen with action-based architecture\n */\nexport async function showScreen(config) {\n const {\n title,\n onRender,\n parentData = {}\n } = config;\n\n\n return new Promise((resolve) => {\n // eslint-disable-next-line prefer-const\n let instance;\n\n // Persistent collections (closure variables survive re-renders)\n const keyBindings = [];\n const actions = {};\n const customFooterItems = [];\n let renderResult = null;\n let initialized = false;\n\n const Screen = () => {\n const [, setUpdateCounter] = useState(0);\n\n // Initialize defaults only once\n if (!initialized) {\n const defaultBindings = [\n { key: \"escape\", caption: \"go back\", action: \"back\", protected: true, order: 1 },\n { key: \"leftArrow\", caption: \"go back\", action: \"back\", protected: false, order: 1 }\n // Note: 'select' is not a default - components add it if needed\n ];\n\n // Add defaults\n defaultBindings.forEach(binding => {\n keyBindings.push(binding);\n });\n\n // Default actions\n actions.back = () => {\n cleanup(null);\n };\n\n initialized = true;\n }\n\n // Context for onRender\n const context = {\n setAction: (actionName, handlerFn) => {\n actions[actionName] = handlerFn;\n },\n\n setKeyBinding: (bindingOrBindings) => {\n // Support both single object and array\n const bindingsToSet = Array.isArray(bindingOrBindings) ? bindingOrBindings : [bindingOrBindings];\n\n bindingsToSet.forEach(binding => {\n const id = bindingIdentity(binding);\n const existingIndex = keyBindings.findIndex(\n (b) => bindingIdentity(b) === id,\n );\n\n if (existingIndex >= 0) {\n const existing = keyBindings[existingIndex];\n\n // Can't override protected keys\n if (existing.protected) {\n console.warn(`Cannot override protected key: ${binding.key}`);\n return;\n }\n\n // Replace binding (keep original order if not specified)\n keyBindings[existingIndex] = {\n ...existing,\n ...binding,\n order: binding.order !== undefined ? binding.order : existing.order,\n enabled: binding.enabled !== undefined ? binding.enabled : (existing.enabled !== undefined ? existing.enabled : true)\n };\n } else {\n // Add new binding\n keyBindings.push({\n protected: false,\n order: 999,\n enabled: true,\n ...binding\n });\n }\n });\n },\n\n updateKeyBinding: (keyName, updates) => {\n // Prefer identity match when updates carry modifiers; else first key name.\n const id =\n updates && (updates.meta != null || updates.ctrl != null || updates.shift != null)\n ? bindingIdentity({ key: keyName, ...updates })\n : null;\n const index = keyBindings.findIndex((b) =>\n id ? bindingIdentity(b) === id : b.key === keyName,\n );\n if (index >= 0) {\n // Update only specified properties\n keyBindings[index] = {\n ...keyBindings[index],\n ...updates\n };\n }\n },\n\n removeKeyBinding: (keyNameOrBinding) => {\n const index =\n typeof keyNameOrBinding === \"object\" && keyNameOrBinding\n ? keyBindings.findIndex(\n (b) => bindingIdentity(b) === bindingIdentity(keyNameOrBinding),\n )\n : keyBindings.findIndex((b) => b.key === keyNameOrBinding);\n if (index >= 0) {\n if (keyBindings[index].protected) {\n console.warn(`Cannot remove protected key: ${keyNameOrBinding}`);\n return;\n }\n keyBindings.splice(index, 1);\n }\n },\n\n addFooter: (item) => {\n customFooterItems.push(item);\n },\n\n clearFooter: () => {\n customFooterItems.length = 0;\n },\n\n setFooter: (items) => {\n customFooterItems.length = 0;\n const itemsArray = Array.isArray(items) ? items : [items];\n customFooterItems.push(...itemsArray);\n },\n\n update: () => {\n setUpdateCounter(c => c + 1);\n },\n\n goBack: () => {\n if (actions.back) {\n actions.back();\n }\n },\n\n close: (result) => {\n cleanup(result);\n },\n\n parentData\n };\n\n // Call onRender once to let component set up\n if (!renderResult) {\n renderResult = onRender(context);\n }\n\n // Handle input - dispatch to actions\n useInput((input, key) => {\n // Check Ctrl+C for exit\n if (key.ctrl && input === \"c\") {\n cleanup(null);\n process.exit(0);\n return;\n }\n\n // Find matching key binding\n let matchedBinding = null;\n\n for (const binding of keyBindings) {\n if (binding.enabled === false) continue;\n if (!bindingMatchesInput(binding, input, key)) continue;\n if (binding.condition && !binding.condition(context)) continue;\n\n matchedBinding = binding;\n break;\n }\n\n if (matchedBinding && actions[matchedBinding.action]) {\n // Execute action\n actions[matchedBinding.action]({\n input,\n key,\n binding: matchedBinding\n });\n\n // If action returns a value, might be used for something\n // For now, actions manage their own state via closures\n }\n });\n\n // Build footer\n const footerLines = [];\n\n // Add key bindings (returns array of strings/components)\n const bindingItems = formatKeyBindings(keyBindings, \"long\");\n\n if (bindingItems.length > 0) {\n // Build a single line with all binding items separated by \", \"\n const bindingsLine = [];\n bindingItems.forEach((item, idx) => {\n if (idx > 0) {\n bindingsLine.push(\", \");\n }\n bindingsLine.push(item);\n });\n\n // If all items are strings, join them; otherwise create a Box\n const allStrings = bindingItems.every(item => typeof item === \"string\");\n if (allStrings) {\n footerLines.push(bindingsLine.join(\"\"));\n } else {\n // Mixed strings and components - wrap all strings in Text components\n const wrappedBindingsLine = bindingsLine.map(item => \n typeof item === \"string\" ? h(Text, {}, item) : item\n );\n footerLines.push(wrappedBindingsLine);\n }\n }\n\n // Add custom footer items\n customFooterItems.forEach(item => {\n if (typeof item === \"string\") {\n footerLines.push(item);\n } else {\n footerLines.push(item);\n }\n });\n\n return h(ScreenContainer, {},\n h(ScreenTitle, { text: title }),\n h(ScreenDivider),\n h(ScreenRow, {}, h(Text, {}, \" \")),\n renderResult,\n h(ScreenRow, {}, h(Text, {}, \" \")),\n h(ScreenDivider),\n h(ScreenFooter, { lines: footerLines })\n );\n };\n\n const cleanup = (result) => {\n if (instance) instance.unmount();\n setTimeout(() => resolve(result), 50);\n };\n\n instance = render(h(Screen));\n });\n}\n\n/**\n * Helper: Show list screen (single column menu)\n */\nexport async function showListScreen(config) {\n const { title, items, onSelect, onEscape, parentData, initialSelectedIndex = 0, renderItem, getTitle, sortable, maxHeight, sortHighlightStyle, selectionMarker } = config;\n\n return showScreen({\n title,\n parentData,\n onRender: (ctx) => {\n // Shared state ref\n const selectedIndexRef = { current: initialSelectedIndex };\n\n // Set up select action at screen level\n ctx.setAction(\"select\", () => {\n const selected = items[selectedIndexRef.current];\n if (onSelect) {\n const result = onSelect(selected.value, selectedIndexRef.current);\n ctx.close(result);\n }\n });\n\n // Set up back action if provided\n if (onEscape) {\n ctx.setAction(\"back\", () => {\n const result = onEscape(selectedIndexRef.current);\n ctx.close(result);\n });\n }\n\n // Add select key binding\n ctx.setKeyBinding({ key: \"return\", caption: \"select\", action: \"select\", order: 2 });\n\n // Return the component (it will set up its own navigation actions and bindings)\n return h(ListComponent, { items, ctx, selectedIndexRef, renderItem, getTitle, sortable, maxHeight, sortHighlightStyle, selectionMarker });\n }\n });\n}\n\n/**\n * Helper: Show multi-column list screen (grid layout)\n */\nexport async function showMultiColumnListScreen(config) {\n const { title, items, onSelect, onEscape, parentData, initialSelectedIndex = 0 } = config;\n\n return showScreen({\n title,\n parentData,\n onRender: (ctx) => {\n // Shared state ref\n const selectedIndexRef = { current: initialSelectedIndex };\n\n // Set up select action at screen level\n ctx.setAction(\"select\", () => {\n const selected = items[selectedIndexRef.current];\n if (onSelect) {\n const result = onSelect(selected, selectedIndexRef.current);\n ctx.close(result);\n }\n });\n\n // Set up back action if provided\n if (onEscape) {\n ctx.setAction(\"back\", () => {\n const result = onEscape(selectedIndexRef.current);\n ctx.close(result);\n });\n }\n\n // Add select key binding\n ctx.setKeyBinding({ key: \"return\", caption: \"select\", action: \"select\", order: 2 });\n\n // Return the component (it will set up its own navigation actions and bindings)\n return h(MultiColumnListComponent, { items, ctx, selectedIndexRef });\n }\n });\n}\n\n/**\n * Helper: Show multi-column list with preview panel below\n */\nexport async function showMultiColumnListWithPreviewScreen(config) {\n const { title, items, getPreviewContent, onSelect, onEscape, parentData, initialSelectedIndex = 0 } = config;\n\n return showScreen({\n title,\n parentData,\n onRender: (ctx) => {\n // Shared state ref\n const selectedIndexRef = { current: initialSelectedIndex };\n\n // Set up select action at screen level\n ctx.setAction(\"select\", () => {\n const selected = items[selectedIndexRef.current];\n if (onSelect) {\n const result = onSelect(selected, selectedIndexRef.current);\n ctx.close(result);\n }\n });\n\n // Set up back action if provided\n if (onEscape) {\n ctx.setAction(\"back\", () => {\n const result = onEscape(selectedIndexRef.current);\n ctx.close(result);\n });\n }\n\n // Add select key binding\n ctx.setKeyBinding({ key: \"return\", caption: \"select\", action: \"select\", order: 2 });\n\n // Return the component (it will set up its own navigation actions and bindings)\n return h(MultiColumnListWithPreviewComponent, { items, getPreviewContent, ctx, selectedIndexRef });\n }\n });\n}\n\n// Backward compatibility aliases\nexport const showMenuScreen = showListScreen;\nexport const showWordGridScreen = showMultiColumnListScreen;\n","/**\n * Core screen layout components\n */\n\nimport { createElement as h } from \"react\";\nimport { Box, Text } from \"ink\";\n\n/**\n * Get screen width for borders\n * @param maxWidth - Optional max width (null = no limit)\n */\nexport function getScreenWidth(maxWidth = null) {\n const terminalWidth = process.stdout.columns || 80;\n // Leave some margin for borders and padding\n const availableWidth = Math.max(20, terminalWidth - 4);\n return maxWidth ? Math.min(availableWidth, maxWidth) : availableWidth;\n}\n\n// Types\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n/**\n * Screen Container - uses Ink's built-in borderStyle for proper text wrapping\n */\nexport function ScreenContainer({ children }) {\n const width = getScreenWidth();\n\n return h(Box, {\n flexDirection: \"column\",\n marginTop: 1,\n borderStyle: \"single\",\n borderColor: \"cyan\",\n paddingX: 1,\n width: width // Use the calculated width directly\n }, children);\n}\n\n/**\n * Screen row - just a wrapper for spacing, borders handled by container\n */\nexport function ScreenRow({ children }) {\n return h(Box, { flexDirection: \"column\" }, children);\n}\n\n/**\n * Screen Title - first line inside container (left-aligned, breadcrumb-style)\n */\nexport function ScreenTitle({ text }) {\n return h(ScreenRow, {},\n h(Text, { bold: true, color: \"cyan\" }, text)\n );\n}\n\n/**\n * Horizontal divider line\n */\nexport function ScreenDivider({ width }) {\n const dividerWidth = width || (getScreenWidth() - 4); // Account for border and padding\n return h(Text, { color: \"cyan\", dimColor: true }, \"─\".repeat(dividerWidth));\n}\n\n/**\n * Screen Body - main content area\n */\nexport function ScreenBody({ children, alignItems = \"flex-start\" }) {\n return h(Box, { flexDirection: \"column\", alignItems }, children);\n}\n\n/**\n * Screen Footer - bottom area with key bindings and status\n * \n * @example\n * <ScreenFooter lines={[\"esc to go back\", \"enter to select\"]} />\n * \n * @example\n * <ScreenFooter \n * lines={[\"esc to go back\", \"enter to select\"]} \n * textStyle={{ color: \"white\" }}\n * />\n * \n * @example\n * <ScreenFooter \n * lines={[\"esc to go back\", \"enter to select\"]} \n * textStyle={{ dimColor: false, color: \"green\" }}\n * />\n */\nexport function ScreenFooter({ lines, textStyle }) {\n const defaultTextStyle = {\n dimColor: true,\n color: \"white\"\n };\n \n const finalTextStyle = { ...defaultTextStyle, ...textStyle };\n\n // Flatten nested arrays and ensure all items are properly wrapped\n const flattenAndWrap = (items, keyPrefix = \"\") => {\n const result = [];\n let keyIndex = 0;\n\n items.forEach((item, index) => {\n if (Array.isArray(item)) {\n // Handle nested arrays\n const nested = flattenAndWrap(item, `${keyPrefix}-${index}`);\n result.push(...nested);\n } else if (typeof item === \"string\") {\n // Wrap strings in Text components\n result.push(\n h(Text, { key: `${keyPrefix}-${keyIndex++}`, ...finalTextStyle }, item)\n );\n } else {\n // JSX elements - add key if missing\n const element = item ;\n if (element.key === null || element.key === undefined) {\n result.push(\n h(Text, { key: `${keyPrefix}-${keyIndex++}`, ...finalTextStyle }, element)\n );\n } else {\n result.push(element);\n }\n }\n });\n\n return result;\n };\n\n const wrappedItems = flattenAndWrap(lines);\n\n return h(Box, { flexDirection: \"column\" },\n h(Box, { flexDirection: \"row\" }, ...wrappedItems)\n );\n}","/**\n * Reusable screen components for V2 architecture\n */\n\nimport React, { useState, useEffect, useRef, createElement } from \"react\";\nimport { Box, Text } from \"ink\";\nimport { ScreenRow, ScreenDivider } from \"./components.js\";\n\nconst h = createElement;\n\n// TODO: Define proper context type interface\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n/**\n * Multi-column list component\n * Handles its own navigation, actions, and key bindings\n */\nexport function MultiColumnListComponent({ items, ctx, selectedIndexRef }) {\n const [, forceUpdate] = useState({});\n\n // Calculate layout\n const termWidth = (process.stdout.columns || 80) - 8;\n const maxItemLength = Math.max(...items.map(w => w.length));\n const columnWidth = maxItemLength + 3;\n const columns = Math.max(1, Math.floor(termWidth / columnWidth));\n const itemsPerColumn = Math.ceil(items.length / columns);\n\n // Set up actions in useEffect (runs once)\n useEffect(() => {\n ctx.setAction(\"moveUp\", () => {\n selectedIndexRef.current = Math.max(0, selectedIndexRef.current - 1);\n forceUpdate({});\n });\n\n ctx.setAction(\"moveDown\", () => {\n selectedIndexRef.current = Math.min(items.length - 1, selectedIndexRef.current + 1);\n forceUpdate({});\n });\n\n ctx.setAction(\"moveLeft\", () => {\n if (selectedIndexRef.current === 0) {\n ctx.goBack();\n } else {\n selectedIndexRef.current = Math.max(0, selectedIndexRef.current - itemsPerColumn);\n forceUpdate({});\n }\n });\n\n ctx.setAction(\"moveRight\", () => {\n selectedIndexRef.current = Math.min(items.length - 1, selectedIndexRef.current + itemsPerColumn);\n forceUpdate({});\n });\n\n // Set up key bindings\n ctx.setKeyBinding([\n { key: \"leftArrow\", caption: \"navigate\", action: \"moveLeft\", order: 0 },\n { key: \"rightArrow\", caption: \"navigate\", action: \"moveRight\", order: 0 },\n { key: \"upArrow\", caption: \"navigate\", action: \"moveUp\", order: 0 },\n { key: \"downArrow\", caption: \"navigate\", action: \"moveDown\", order: 0 }\n ]);\n\n // Add footer\n ctx.addFooter(`Total: ${items.length} items`);\n }, []);\n\n const selectedIndex = selectedIndexRef.current;\n\n // Build grid\n const rows = [];\n for (let row = 0; row < itemsPerColumn; row++) {\n const cols = [];\n for (let col = 0; col < columns; col++) {\n const index = col * itemsPerColumn + row;\n if (index < items.length) {\n const isSelected = index === selectedIndex;\n cols.push(\n h(Box, { key: index, width: columnWidth },\n h(Text, {\n color: isSelected ? \"black\" : \"white\",\n backgroundColor: isSelected ? \"cyan\" : undefined,\n bold: isSelected\n }, items[index].padEnd(maxItemLength))\n )\n );\n }\n }\n rows.push(\n h(ScreenRow, { key: row, children: h(Box, { flexDirection: \"row\" }, ...cols) })\n );\n }\n\n return h(Box, { flexDirection: \"column\" }, ...rows);\n}\n\n/**\n * Multi-column list with preview panel component\n * Shows selected item details below the list\n */\nexport function MultiColumnListWithPreviewComponent({\n items,\n getPreviewContent,\n ctx,\n selectedIndexRef\n}) {\n const [, forceUpdate] = useState({});\n\n // Calculate layout\n const termWidth = (process.stdout.columns || 80) - 8;\n const maxItemLength = Math.max(...items.map(w => w.length));\n const columnWidth = maxItemLength + 3;\n const columns = Math.max(1, Math.floor(termWidth / columnWidth));\n const itemsPerColumn = Math.ceil(items.length / columns);\n\n // Set up actions in useEffect (runs once)\n useEffect(() => {\n ctx.setAction(\"moveUp\", () => {\n selectedIndexRef.current = Math.max(0, selectedIndexRef.current - 1);\n forceUpdate({});\n });\n\n ctx.setAction(\"moveDown\", () => {\n selectedIndexRef.current = Math.min(items.length - 1, selectedIndexRef.current + 1);\n forceUpdate({});\n });\n\n ctx.setAction(\"moveLeft\", () => {\n if (selectedIndexRef.current === 0) {\n ctx.goBack();\n } else {\n selectedIndexRef.current = Math.max(0, selectedIndexRef.current - itemsPerColumn);\n forceUpdate({});\n }\n });\n\n ctx.setAction(\"moveRight\", () => {\n selectedIndexRef.current = Math.min(items.length - 1, selectedIndexRef.current + itemsPerColumn);\n forceUpdate({});\n });\n\n // Set up key bindings\n ctx.setKeyBinding([\n { key: \"leftArrow\", caption: \"navigate\", action: \"moveLeft\", order: 0 },\n { key: \"rightArrow\", caption: \"navigate\", action: \"moveRight\", order: 0 },\n { key: \"upArrow\", caption: \"navigate\", action: \"moveUp\", order: 0 },\n { key: \"downArrow\", caption: \"navigate\", action: \"moveDown\", order: 0 }\n ]);\n\n // Add footer\n ctx.addFooter(`Total: ${items.length} items`);\n }, []);\n\n const selectedIndex = selectedIndexRef.current;\n const selectedItem = items[selectedIndex];\n\n // Build grid\n const rows = [];\n for (let row = 0; row < itemsPerColumn; row++) {\n const cols = [];\n for (let col = 0; col < columns; col++) {\n const index = col * itemsPerColumn + row;\n if (index < items.length) {\n const isSelected = index === selectedIndex;\n cols.push(\n h(Box, { key: index, width: columnWidth },\n h(Text, {\n color: isSelected ? \"black\" : \"white\",\n backgroundColor: isSelected ? \"cyan\" : undefined,\n bold: isSelected\n }, items[index].padEnd(maxItemLength))\n )\n );\n }\n }\n rows.push(\n h(ScreenRow, { key: row, children: h(Box, { flexDirection: \"row\" }, ...cols) })\n );\n }\n\n // Get preview content for selected item\n const previewContent = getPreviewContent ? getPreviewContent(selectedItem) : selectedItem;\n\n const previewRows = [];\n if (typeof previewContent === \"string\") {\n previewRows.push(h(ScreenRow, { key: \"preview-string\", children: h(Text, { bold: true }, previewContent) }));\n } else if (typeof previewContent === \"object\" && !React.isValidElement(previewContent) && previewContent !== null) {\n Object.entries(previewContent).forEach(([key, value], idx) => {\n previewRows.push(h(ScreenRow, { key: `preview-${key}-${idx}`, children: h(Text, {}, `${key}: ${value}`) }));\n });\n } else if (React.isValidElement(previewContent)) {\n previewRows.push(h(ScreenRow, { key: \"preview-element\", children: previewContent }));\n }\n\n return h(Box, { flexDirection: \"column\" },\n ...rows,\n h(ScreenRow, { key: \"spacer-1\", children: h(Text, {}, \" \") }),\n h(ScreenDivider, { key: \"divider\" }),\n h(ScreenRow, { key: \"spacer-2\", children: h(Text, {}, \" \") }),\n ...previewRows\n );\n}\n\n/**\n * Single-column list component\n * Simple vertical menu with optional sorting\n */\nexport function ListComponent({ items, ctx, selectedIndexRef, renderItem, getTitle, sortable = false, maxHeight, sortHighlightStyle, selectionMarker = \" \", onSelectionChange }) {\n const [, forceUpdate] = useState({});\n const [sortOrder, setSortOrder] = useState(\"none\");\n const [scrollOffset, setScrollOffset] = useState(0);\n \n // Use refs to store current scroll values to avoid stale closures\n const scrollStateRef = useRef({ scrollOffset: 0, maxHeight: 0, totalItems: 0 });\n const itemsRef = useRef(items);\n itemsRef.current = items;\n\n // Default getTitle - returns item if string, otherwise item.title\n const defaultGetTitle = (item) => {\n return getTitle ? getTitle(item) : (typeof item.value === \"string\" ? item.value : (item.value?.title || item.name));\n };\n\n // Get title for sorting\n const titleGetter = getTitle || defaultGetTitle;\n\n // Apply sorting if enabled\n const displayItems = sortable && sortOrder !== \"none\" ? [...items].sort((a, b) => {\n const titleA = titleGetter(a).toLowerCase();\n const titleB = titleGetter(b).toLowerCase();\n if (sortOrder === \"asc\") {\n return titleA < titleB ? -1 : titleA > titleB ? 1 : 0;\n } else {\n return titleA > titleB ? -1 : titleA < titleB ? 1 : 0;\n }\n }) : items;\n\n const displayItemsRef = useRef(displayItems);\n displayItemsRef.current = displayItems;\n\n // Calculate scrolling\n const effectiveMaxHeight = maxHeight || displayItems.length;\n const _canScroll = displayItems.length > effectiveMaxHeight;\n const maxScrollOffset = Math.max(0, displayItems.length - effectiveMaxHeight);\n \n // Ensure scroll offset is within bounds\n const clampedScrollOffset = Math.min(Math.max(0, scrollOffset), maxScrollOffset);\n \n // Get visible items\n const visibleItems = displayItems.slice(clampedScrollOffset, clampedScrollOffset + effectiveMaxHeight);\n \n // Check if we can scroll up/down\n const canScrollUp = clampedScrollOffset > 0;\n const canScrollDown = clampedScrollOffset < maxScrollOffset;\n \n // Update scroll state ref with current values\n scrollStateRef.current = { scrollOffset, maxHeight: effectiveMaxHeight, totalItems: displayItems.length };\n \n\n const onSelectionChangeRef = useRef(onSelectionChange);\n onSelectionChangeRef.current = onSelectionChange;\n\n // Set up actions in useEffect (runs once)\n useEffect(() => {\n ctx.setAction(\"moveUp\", () => {\n const newIndex = Math.max(0, selectedIndexRef.current - 1);\n selectedIndexRef.current = newIndex;\n const list = displayItemsRef.current;\n onSelectionChangeRef.current?.(newIndex, list[newIndex]);\n\n // Auto-scroll to keep selected item visible\n const { scrollOffset: currentScrollOffset, maxHeight: currentMaxHeight, totalItems } = scrollStateRef.current;\n const currentMaxScrollOffset = Math.max(0, totalItems - currentMaxHeight);\n const currentClampedScrollOffset = Math.min(Math.max(0, currentScrollOffset), currentMaxScrollOffset);\n\n if (newIndex < currentClampedScrollOffset) {\n setScrollOffset(newIndex);\n }\n\n forceUpdate({});\n });\n\n ctx.setAction(\"moveDown\", () => {\n const currentItems = displayItemsRef.current;\n const maxIndex = Math.max(0, currentItems.length - 1);\n const newIndex = Math.min(maxIndex, selectedIndexRef.current + 1);\n selectedIndexRef.current = newIndex;\n onSelectionChangeRef.current?.(newIndex, currentItems[newIndex]);\n\n // Auto-scroll to keep selected item visible\n const { scrollOffset: currentScrollOffset, maxHeight: currentMaxHeight, totalItems } = scrollStateRef.current;\n const currentMaxScrollOffset = Math.max(0, totalItems - currentMaxHeight);\n const currentClampedScrollOffset = Math.min(Math.max(0, currentScrollOffset), currentMaxScrollOffset);\n\n if (newIndex >= currentClampedScrollOffset + currentMaxHeight) {\n setScrollOffset(newIndex - currentMaxHeight + 1);\n }\n\n forceUpdate({});\n });\n\n // Add scroll actions for arrow clicks\n ctx.setAction(\"scrollUp\", () => {\n const { scrollOffset: currentScrollOffset } = scrollStateRef.current;\n const newScrollOffset = Math.max(0, currentScrollOffset - 1);\n setScrollOffset(newScrollOffset);\n forceUpdate({});\n });\n\n ctx.setAction(\"scrollDown\", () => {\n const { scrollOffset: currentScrollOffset, maxHeight: currentMaxHeight, totalItems } = scrollStateRef.current;\n const currentMaxScrollOffset = Math.max(0, totalItems - currentMaxHeight);\n const newScrollOffset = Math.min(currentMaxScrollOffset, currentScrollOffset + 1);\n setScrollOffset(newScrollOffset);\n forceUpdate({});\n });\n\n // Set up sort action if sortable\n if (sortable) {\n ctx.setAction(\"toggleSort\", () => {\n const nextSort = \n sortOrder === \"none\" ? \"asc\" : \n sortOrder === \"asc\" ? \"desc\" : \"none\";\n \n // Store the currently selected item from the current display items\n const currentSelectedItem = displayItemsRef.current[selectedIndexRef.current];\n \n setSortOrder(nextSort);\n \n // Calculate the new sorted items\n const newSortedItems = nextSort !== \"none\" ? [...itemsRef.current].sort((a, b) => {\n const titleA = titleGetter(a).toLowerCase();\n const titleB = titleGetter(b).toLowerCase();\n if (nextSort === \"asc\") {\n return titleA < titleB ? -1 : titleA > titleB ? 1 : 0;\n } else {\n return titleA > titleB ? -1 : titleA < titleB ? 1 : 0;\n }\n }) : itemsRef.current;\n \n // Find the new index of the selected item in the new sorted list\n const newIndex = newSortedItems.findIndex(item => item === currentSelectedItem);\n if (newIndex !== -1) {\n selectedIndexRef.current = newIndex;\n // Set scroll position to show the selected item at the top\n setScrollOffset(newIndex);\n } else {\n // Fallback: if item not found, select first item\n selectedIndexRef.current = 0;\n setScrollOffset(0);\n }\n \n forceUpdate({});\n });\n\n // Default highlight style (green background, black text, bold)\n const defaultHighlightStyle = {\n color: \"black\",\n backgroundColor: \"green\", \n bold: true\n };\n const highlightStyle = { ...defaultHighlightStyle, ...sortHighlightStyle };\n\n // Create caption that includes sort status\n const sortCaption = () => {\n if (sortOrder === \"none\") {\n return h(Text, {}, \"s to toggle sort\");\n } else {\n const sortLabel = sortOrder === \"asc\" ? \"ASC\" : \"DESC\";\n return h(Text, {}, \n \"s to toggle \",\n h(Text, { color: \"white\", bold: true }, \"sort\"),\n \" \",\n h(Text, highlightStyle, ` ${sortLabel} `)\n );\n }\n };\n\n // Update key bindings with sort\n ctx.setKeyBinding([\n { key: \"upArrow\", caption: \"navigate\", action: \"moveUp\", order: 0 },\n { key: \"downArrow\", caption: \"navigate\", action: \"moveDown\", order: 0 },\n { \n key: \"s\", \n caption: sortCaption,\n action: \"toggleSort\", \n order: 5 \n }\n ]);\n\n // Force update to show the new caption in footer\n ctx.update();\n } else {\n // No sorting\n ctx.setKeyBinding([\n { key: \"upArrow\", caption: \"navigate\", action: \"moveUp\", order: 0 },\n { key: \"downArrow\", caption: \"navigate\", action: \"moveDown\", order: 0 }\n ]);\n }\n }, [sortOrder, sortable]);\n\n const selectedIndex = selectedIndexRef.current;\n \n\n // Default renderer with static scroll indicators for debugging\n const defaultRenderItem = (item, isSelected, displayIndex, actualIndex) => {\n const isFirstVisible = displayIndex === 0;\n const isLastVisible = displayIndex === visibleItems.length - 1;\n \n // Build prefix with arrows and selection marker\n let arrowPrefix = \"\";\n let selectionPrefix = \"\";\n \n // Only show arrows when scrolling is actually needed and available\n if (isFirstVisible && canScrollUp) {\n arrowPrefix = \"↑ \";\n } else if (isLastVisible && canScrollDown) {\n arrowPrefix = \"↓ \";\n } else {\n // No arrow, but reserve the same space\n arrowPrefix = \" \";\n }\n \n // Always reserve space for selection marker (pad with spaces if not selected)\n if (isSelected) {\n selectionPrefix = selectionMarker;\n } else {\n // Pad with spaces to match the length of the selection marker\n selectionPrefix = \" \".repeat(selectionMarker.length);\n }\n \n return h(Box, { flexDirection: \"row\" },\n // Arrow (clickable if functional, not highlighted)\n h(Text, { \n key: `arrow-${actualIndex}`,\n color: \"white\"\n }, arrowPrefix),\n // Selection marker space (always same width, not highlighted) \n h(Text, { key: `marker-${actualIndex}`, color: \"white\" }, selectionPrefix),\n // Item name (highlighted if selected)\n h(Text, {\n key: `name-${actualIndex}`,\n color: isSelected ? \"black\" : \"white\",\n backgroundColor: isSelected ? \"cyan\" : undefined,\n bold: isSelected\n }, item.name)\n );\n };\n\n // Use custom renderer if provided, otherwise use default\n const itemRenderer = renderItem || defaultRenderItem;\n\n // Render visible menu items with scroll indicators\n return h(Box, { flexDirection: \"column\" },\n ...visibleItems.map((item, displayIndex) => {\n const actualIndex = clampedScrollOffset + displayIndex;\n const isSelected = actualIndex === selectedIndex;\n \n // If using custom renderer, wrap it with scroll indicators\n if (renderItem) {\n const isFirstVisible = displayIndex === 0;\n const isLastVisible = displayIndex === visibleItems.length - 1;\n \n // Build prefix with arrows and selection marker\n let arrowPrefix = \"\";\n let selectionPrefix = \"\";\n \n // Only show arrows when scrolling is actually needed and available\n if (isFirstVisible && canScrollUp) {\n arrowPrefix = \"↑ \";\n } else if (isLastVisible && canScrollDown) {\n arrowPrefix = \"↓ \";\n } else {\n // No arrow, but reserve the same space\n arrowPrefix = \" \";\n }\n \n // Always reserve space for selection marker (pad with spaces if not selected)\n if (isSelected) {\n selectionPrefix = selectionMarker;\n } else {\n // Pad with spaces to match the length of the selection marker\n selectionPrefix = \" \".repeat(selectionMarker.length);\n }\n \n return h(ScreenRow, {\n key: `item-${actualIndex}`,\n children: h(Box, { flexDirection: \"row\" },\n // Arrow (clickable if functional, not highlighted)\n h(Text, { \n key: `arrow-${actualIndex}`,\n color: \"white\"\n }, arrowPrefix),\n // Selection marker space (always same width, not highlighted) \n h(Text, { key: `marker-${actualIndex}`, color: \"white\" }, selectionPrefix),\n // Custom rendered content\n renderItem(item, isSelected, displayIndex)\n )\n });\n } else {\n // Use default renderer (which already includes scroll indicators)\n return h(ScreenRow, {\n key: `item-${actualIndex}`,\n children: itemRenderer(item, isSelected, displayIndex, actualIndex)\n });\n }\n })\n );\n}\n","/**\n * Key-binding helpers for showScreen (matching + footer labels).\n *\n * Bindings may set `meta` / `ctrl` / `shift` booleans. Plain bindings (flags\n * omitted) do not match when that modifier is held, so `↑` and `⌥↑` can coexist.\n */\n\n/**\n * Stable identity for replace/remove (key + modifiers).\n * @param {{ key: string, meta?: boolean, ctrl?: boolean, shift?: boolean }} b\n */\nexport function bindingIdentity(b) {\n return [\n String(b?.key ?? \"\"),\n b?.meta ? \"m\" : \"\",\n b?.ctrl ? \"c\" : \"\",\n b?.shift ? \"s\" : \"\",\n ].join(\"|\");\n}\n\n/**\n * @param {{ key: string, meta?: boolean, ctrl?: boolean, shift?: boolean }} binding\n * @param {string} input\n * @param {import(\"ink\").Key} key\n */\nexport function bindingMatchesInput(binding, input, key) {\n if (!binding?.key) return false;\n\n let keyMatches = false;\n if (key?.[binding.key]) {\n keyMatches = true;\n } else if (input === binding.key) {\n keyMatches = true;\n } else if (key?.name === binding.key) {\n keyMatches = true;\n }\n if (!keyMatches) return false;\n\n // Explicit true → require; explicit false → forbid; omitted → forbid if pressed\n // (so plain upArrow does not fire for meta+up).\n const modOk = (flag, pressed) => {\n if (flag === true) return !!pressed;\n if (flag === false) return !pressed;\n return !pressed;\n };\n\n // shift is often used with letters; for arrows we still treat omitted as \"any\"\n // only for shift — meta/ctrl are the page-jump modifiers we care about.\n if (!modOk(binding.meta, key?.meta)) return false;\n if (!modOk(binding.ctrl, key?.ctrl)) return false;\n if (binding.shift !== undefined && !!key?.shift !== !!binding.shift) return false;\n\n return true;\n}\n\nconst KEY_LABELS = {\n escape: \"esc\",\n leftArrow: \"←\",\n rightArrow: \"→\",\n upArrow: \"↑\",\n downArrow: \"↓\",\n return: \"enter\",\n pageUp: \"PgUp\",\n pageDown: \"PgDn\",\n};\n\n/**\n * Human label for one binding (modifiers + key), e.g. `⌥↑`, `^↓`, `PgUp`.\n * @param {{ key: string, meta?: boolean, ctrl?: boolean, shift?: boolean }} binding\n */\nexport function formatBindingKey(binding) {\n let label = KEY_LABELS[binding.key] || binding.key;\n if (binding.shift) label = `⇧${label}`;\n if (binding.ctrl) label = `^${label}`;\n // ink `meta` is Option/Alt on macOS (⌘ is usually eaten by the terminal).\n if (binding.meta) label = `⌥${label}`;\n return label;\n}\n","/**\n * Reusable UI elements for the screen system\n */\n\nimport { createElement as h } from \"react\";\nimport { Box, Text } from \"ink\";\n\n// Types\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n/**\n * List item component\n */\nexport function ListItem({ \n children, \n isSelected = false, \n color = \"white\", \n backgroundColor, \n bold = false, \n dimColor = false \n}) {\n return h(Box, {},\n h(Text, {\n color: isSelected ? backgroundColor || \"green\" : color,\n backgroundColor: isSelected ? color : backgroundColor,\n bold: isSelected || bold,\n dimColor: !isSelected && dimColor\n }, children)\n );\n}\n\n/**\n * Text block component with customizable styling\n */\nexport function TextBlock({ \n text, \n color = \"white\", \n dimmed = false, \n bold = false, \n maxWidth: _maxWidth \n}) {\n return h(Box, {},\n h(Text, { \n color, \n dimColor: dimmed, \n bold \n }, text)\n );\n}\n\n/**\n * Horizontal divider\n */\nexport function Divider({ character = \"─\", width = 80 }) {\n return h(Box, { marginY: 1 },\n h(Text, { dimColor: true }, character.repeat(width))\n );\n}\n\n/**\n * Grid cell component\n */\nexport function GridCell({ \n children, \n width, \n color = \"white\", \n backgroundColor, \n bold = false, \n dimColor = false, \n align = \"left\" \n}) {\n return h(Box, { width },\n h(Text, {\n color,\n backgroundColor,\n bold,\n dimColor,\n textAlign: align\n }, children)\n );\n}\n\n/**\n * Input field component\n */\nexport function InputField({ prompt, value, onChange: _onChange, onSubmit: _onSubmit }) {\n return h(Box, { flexDirection: \"column\" },\n h(Text, {}, prompt),\n h(Box, { marginTop: 1 },\n h(Text, { color: \"cyan\" }, \" > \", value, \"_\")\n )\n );\n}","/**\n * ScrollableText — wrap long text, line/page scroll, proportional scrollbar.\n *\n * h(ScrollableText, { ctx, text: json, bindKeys: true })\n *\n * Keys (when bindKeys):\n * ↑/↓ — one line\n * ⌥↑/↓ ^↑/↓ — one page (ink `meta` ≈ Option/Alt; ⌘ often never reaches the TTY)\n * PgUp/PgDn — one page\n */\n\nimport { useState, useEffect, useMemo, useRef, createElement } from \"react\";\nimport { Box, Text } from \"ink\";\n\nconst h = createElement;\n\n/**\n * Hard-wrap text to `cols` (keeps empty lines).\n * @param {string} text\n * @param {number} cols\n * @returns {string[]}\n */\nexport function wrapTextLines(text, cols) {\n const w = Math.max(1, Math.floor(Number(cols) || 1));\n const out = [];\n for (const raw of String(text ?? \"\").split(\"\\n\")) {\n if (raw.length === 0) {\n out.push(\"\");\n continue;\n }\n let rest = raw;\n while (rest.length > w) {\n out.push(rest.slice(0, w));\n rest = rest.slice(w);\n }\n if (rest.length > 0) out.push(rest);\n }\n return out;\n}\n\n/**\n * Proportional scrollbar glyphs for a viewport.\n * @returns {string[]|null} one glyph per viewport row, or null when no overflow\n */\nexport function scrollbarGlyphs(viewportRows, totalLines, scrollTop) {\n const view = Math.max(1, Math.floor(viewportRows));\n const total = Math.max(0, Math.floor(totalLines));\n if (total <= view) return null;\n\n const maxScroll = total - view;\n const thumbSize = Math.max(1, Math.round((view / total) * view));\n const travel = Math.max(0, view - thumbSize);\n const s = Math.min(Math.max(0, Math.floor(scrollTop)), maxScroll);\n const thumbStart = maxScroll === 0 ? 0 : Math.round((s / maxScroll) * travel);\n\n const glyphs = [];\n for (let i = 0; i < view; i++) {\n glyphs.push(i >= thumbStart && i < thumbStart + thumbSize ? \"█\" : \"│\");\n }\n return glyphs;\n}\n\nfunction padEndVisible(s, w) {\n const t = String(s ?? \"\");\n if (t.length >= w) return t.slice(0, w);\n return t + \" \".repeat(w - t.length);\n}\n\nconst SCROLL_KEYS = [\n { key: \"upArrow\", caption: \"scroll\", action: \"scrollUp\", order: 0 },\n { key: \"downArrow\", caption: \"scroll\", action: \"scrollDown\", order: 0 },\n { key: \"upArrow\", meta: true, caption: \"page\", action: \"pageUp\", order: 0 },\n { key: \"downArrow\", meta: true, caption: \"page\", action: \"pageDown\", order: 0 },\n { key: \"upArrow\", ctrl: true, caption: \"page\", action: \"pageUp\", order: 0 },\n { key: \"downArrow\", ctrl: true, caption: \"page\", action: \"pageDown\", order: 0 },\n { key: \"pageUp\", caption: \"page\", action: \"pageUp\", order: 0 },\n { key: \"pageDown\", caption: \"page\", action: \"pageDown\", order: 0 },\n];\n\n/**\n * @param {{\n * ctx: object,\n * text?: string,\n * lines?: string[],\n * maxHeight?: number,\n * wrap?: boolean,\n * showScrollbar?: boolean,\n * showStatus?: boolean,\n * bindKeys?: boolean,\n * header?: unknown,\n * }} props\n */\nexport function ScrollableText({\n ctx,\n text = \"\",\n lines: linesProp,\n maxHeight,\n wrap = true,\n showScrollbar = true,\n showStatus = true,\n bindKeys = true,\n header = null,\n}) {\n const [scrollTop, setScrollTop] = useState(0);\n const [, bump] = useState(0);\n\n const termCols = process.stdout.columns || 80;\n const termRows = process.stdout.rows || 24;\n const viewportRows = Math.max(\n 4,\n maxHeight != null ? Math.floor(maxHeight) : Math.max(8, termRows - 8),\n );\n\n // Reserve 1 col for the bar when we might need it; recompute after wrap.\n const provisionalBar = showScrollbar ? 1 : 0;\n const wrapCols = Math.max(8, termCols - provisionalBar);\n\n const allLines = useMemo(() => {\n if (Array.isArray(linesProp)) return linesProp.map((l) => String(l ?? \"\"));\n return wrap ? wrapTextLines(text, wrapCols) : String(text ?? \"\").split(\"\\n\");\n }, [linesProp, text, wrap, wrapCols]);\n\n const needsBar = showScrollbar && allLines.length > viewportRows;\n const textWidth = Math.max(8, termCols - (needsBar ? 1 : 0));\n const maxScroll = Math.max(0, allLines.length - viewportRows);\n const clamped = Math.min(Math.max(0, scrollTop), maxScroll);\n const visible = allLines.slice(clamped, clamped + viewportRows);\n const bar = needsBar ? scrollbarGlyphs(viewportRows, allLines.length, clamped) : null;\n\n useEffect(() => {\n setScrollTop((s) => Math.min(s, maxScroll));\n }, [maxScroll]);\n\n const maxScrollRef = useRef(maxScroll);\n const pageSizeRef = useRef(viewportRows);\n maxScrollRef.current = maxScroll;\n pageSizeRef.current = viewportRows;\n\n useEffect(() => {\n if (!ctx || !bindKeys) return undefined;\n\n ctx.setKeyBinding(SCROLL_KEYS);\n\n ctx.setAction(\"scrollUp\", () => {\n setScrollTop((s) => Math.max(0, s - 1));\n bump((n) => n + 1);\n ctx.update?.();\n });\n ctx.setAction(\"scrollDown\", () => {\n setScrollTop((s) => Math.min(maxScrollRef.current, s + 1));\n bump((n) => n + 1);\n ctx.update?.();\n });\n ctx.setAction(\"pageUp\", () => {\n setScrollTop((s) => Math.max(0, s - pageSizeRef.current));\n bump((n) => n + 1);\n ctx.update?.();\n });\n ctx.setAction(\"pageDown\", () => {\n setScrollTop((s) => Math.min(maxScrollRef.current, s + pageSizeRef.current));\n bump((n) => n + 1);\n ctx.update?.();\n });\n\n return undefined;\n }, [ctx, bindKeys]);\n\n const status =\n allLines.length === 0\n ? \"empty\"\n : `lines ${clamped + 1}-${Math.min(clamped + visible.length, allLines.length)} of ${allLines.length}` +\n (needsBar ? \" · ⌥↑/↓ or PgUp/Dn page\" : \"\");\n\n const rowNodes = visible.map((line, i) => {\n const body = padEndVisible(line, textWidth);\n const glyph = bar ? bar[i] ?? \"│\" : \"\";\n return h(\n Box,\n { key: `L${clamped + i}`, flexDirection: \"row\" },\n h(Text, {}, body),\n glyph\n ? h(Text, { color: bar[i] === \"█\" ? \"cyan\" : \"gray\" }, glyph)\n : null,\n );\n });\n\n // Pad short final page so the scrollbar track stays full height.\n if (bar && visible.length < viewportRows) {\n for (let i = visible.length; i < viewportRows; i++) {\n rowNodes.push(\n h(\n Box,\n { key: `pad${i}`, flexDirection: \"row\" },\n h(Text, {}, padEndVisible(\"\", textWidth)),\n h(Text, { color: bar[i] === \"█\" ? \"cyan\" : \"gray\" }, bar[i] ?? \"│\"),\n ),\n );\n }\n }\n\n return h(\n Box,\n { flexDirection: \"column\" },\n header == null\n ? null\n : typeof header === \"string\"\n ? h(Text, { color: \"gray\" }, header)\n : header,\n showStatus ? h(Text, { color: \"gray\" }, status) : null,\n ...rowNodes,\n );\n}\n","/**\n * Utility functions for Screen System\n */\n\n/**\n * Build breadcrumb-style title\n * @param parts - Parts of the breadcrumb path\n * @returns Formatted breadcrumb\n *\n * Examples:\n * buildBreadcrumb(['Menu']) → 'Menu'\n * buildBreadcrumb(['Menu', 'Info']) → '← Info'\n * buildBreadcrumb(['Menu', 'Words', 'nefarious']) → '← Words ← nefarious'\n */\nexport function buildBreadcrumb(parts) {\n if (parts.length === 0) return \"\";\n if (parts.length === 1) return parts[0];\n\n // Skip first part (root), add arrows with spaces to rest\n return parts.slice(1).map(part => `← ${part}`).join(\" \");\n}\n\n/**\n * Create multi-line breadcrumb with details\n * @param path - Navigation path\n * @param suffix - Additional suffix (e.g., 'Details')\n * @returns Formatted breadcrumb with suffix\n *\n * Example:\n * buildDetailBreadcrumb(['Menu', 'Words', 'nefarious'], 'Details')\n * → '← Words ← nefarious Details'\n */\nexport function buildDetailBreadcrumb(path, suffix = \"\") {\n if (path.length <= 1) {\n return suffix ? `← ${suffix}` : path[0] || \"\";\n }\n\n const breadcrumb = buildBreadcrumb(path);\n return suffix ? `${breadcrumb} ${suffix}` : breadcrumb;\n}\n","/**\n * Footer builder - composes footer messages from multiple sources\n */\n\n\n\n\n\n\n\n\n\n/**\n * Build footer lines from multiple message sources\n *\n * @param config - Footer configuration object\n * @returns Array of footer lines\n */\nexport function buildFooter(config = {}) {\n const {\n navigation = null,\n actions = null,\n info = null,\n escape = \"Esc to go back\",\n custom = null\n } = config;\n\n const lines = [];\n\n // Build main help line (navigation + actions + escape)\n const mainParts = [];\n\n if (navigation) {\n mainParts.push(navigation);\n }\n\n if (actions) {\n mainParts.push(actions);\n }\n\n if (escape) {\n mainParts.push(escape);\n }\n\n if (mainParts.length > 0) {\n lines.push(mainParts.join(\", \"));\n }\n\n // Add info line if present\n if (info) {\n const infoLines = Array.isArray(info) ? info : [info];\n lines.push(...infoLines);\n }\n\n // Add custom lines if present\n if (custom) {\n const customLines = Array.isArray(custom) ? custom : [custom];\n lines.push(...customLines);\n }\n\n return lines;\n}\n\n/**\n * Predefined footer configurations for common screen types\n */\nexport const FooterPresets = {\n /**\n * Menu screen footer\n */\n menu: (customInfo = null) => buildFooter({\n navigation: \"↑/↓ to navigate\",\n actions: \"Enter to select\",\n escape: \"Esc to go back\",\n info: customInfo\n }),\n\n /**\n * Word grid footer\n */\n wordGrid: (totalWords) => buildFooter({\n navigation: \"↑↓←→ to navigate\",\n actions: \"Enter to select\",\n escape: \"Esc to go back\",\n info: `Total: ${totalWords} words`\n }),\n\n /**\n * Text input footer\n */\n textInput: () => buildFooter({\n actions: \"Type and press Enter to submit\",\n escape: \"Esc to cancel\"\n }),\n\n /**\n * Info/static screen footer\n */\n info: () => buildFooter({\n escape: \"Esc to continue\"\n }),\n\n /**\n * Main menu footer (escape exits)\n */\n mainMenu: () => buildFooter({\n navigation: \"↑/↓ to navigate\",\n actions: \"Enter to select\",\n escape: \"Esc to exit\"\n }),\n\n /**\n * Action menu footer (for word cards, etc.)\n */\n actionMenu: (hasAudio = false) => {\n const parts = buildFooter({\n navigation: \"↑/↓ to navigate\",\n actions: \"Enter to select\",\n escape: \"Esc to go back\"\n });\n\n if (hasAudio) {\n parts.push(\"Audio available\");\n }\n\n return parts;\n }\n};\n\n/**\n * Combine multiple footer messages into organized lines\n * Smart grouping of related messages\n *\n * @param messages - Individual footer messages\n * @returns Organized footer lines\n */\nexport function organizeFooterMessages(messages) {\n if (!messages || messages.length === 0) {\n return [\"Esc to go back\"];\n }\n\n // Group similar messages\n const navigation = messages.filter(m => m.includes(\"↑\") || m.includes(\"↓\") || m.includes(\"←\") || m.includes(\"→\"));\n const actions = messages.filter(m => m.includes(\"Enter\") || m.includes(\"select\") || m.includes(\"submit\"));\n const escape = messages.filter(m => m.includes(\"Esc\"));\n const others = messages.filter(m =>\n !navigation.includes(m) &&\n !actions.includes(m) &&\n !escape.includes(m)\n );\n\n const lines = [];\n\n // Combine navigation, actions, and escape on one line\n const mainLine = [...navigation, ...actions, ...escape].join(\", \");\n if (mainLine) lines.push(mainLine);\n\n // Add other messages as separate lines\n lines.push(...others);\n\n return lines;\n}\n"],"mappings":"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","names":["React","useState","useEffect","useRef","useMemo","createElement","Box","Text","useInput","useState","h","Text","Box","Text","h","Box","Text","useState","h","Text","h","Box","Text","useState","useEffect","useRef","createElement","Box","Text","h"]}
|
|
1
|
+
{"version":3,"sources":["../src/screen/index.js","../src/screen/screens.js","../src/screen/components.js","../src/screen/list-components.js","../src/screen/key-bindings.js","../src/screen/ui-elements.js","../src/screen/scrollable-text.js","../src/screen/utils.js","../src/screen/footer-builder.js"],"sourcesContent":["/**\n * Screen System - Action-based architecture\n * Converted from legacy/screenSystem/src\n */\n\n// Re-export React and React hooks (encapsulated)\nimport React, { useState, useEffect, useLayoutEffect, useRef, useMemo, useCallback, memo, createElement } from \"react\";\nexport { React, useState, useEffect, useLayoutEffect, useRef, useMemo, useCallback, memo };\nexport { createElement as h };\n\n// Re-export Ink components (encapsulated)\nexport { Box, Text, useInput } from \"ink\";\n\n// Screen functions\nexport {\n showScreen,\n showListScreen,\n showMultiColumnListScreen,\n showMultiColumnListWithPreviewScreen,\n // Backward compatibility aliases\n showMenuScreen,\n showWordGridScreen\n} from \"./screens.js\";\n\n// Reusable components\nexport { MultiColumnListComponent, MultiColumnListWithPreviewComponent, ListComponent } from \"./list-components.js\";\nexport { ScreenContainer, ScreenRow, ScreenTitle, ScreenBody, ScreenFooter, ScreenDivider } from \"./components.js\";\nexport { ListItem, TextBlock, Divider, GridCell, InputField } from \"./ui-elements.js\";\nexport { ScrollableText, wrapTextLines, scrollbarGlyphs } from \"./scrollable-text.js\";\nexport {\n bindingIdentity,\n bindingMatchesInput,\n formatBindingKey,\n} from \"./key-bindings.js\";\n\n// Utilities\nexport { buildBreadcrumb, buildDetailBreadcrumb } from \"./utils.js\";\nexport { buildFooter, FooterPresets, organizeFooterMessages } from \"./footer-builder.js\";\n\n// For CommonJS compatibility: pre-load ESM dependencies\nlet loadPromise = null;\nexport async function load() {\n if (loadPromise) return loadPromise;\n loadPromise = Promise.all([\n import(\"react\"),\n import(\"ink\")\n ]).then(() => {}) ;\n return loadPromise;\n}\n// Auto-load in ESM, but CJS users should call load() explicitly\nif (typeof window === \"undefined\") {\n load().catch(() => {\n // Ignore errors during auto-load, user can call load() explicitly\n });\n}\n","/**\n * Screen System - Action-based architecture\n */\n\nimport { useState, createElement as h } from \"react\";\nimport { render, useInput, Text } from \"ink\";\nimport { ScreenContainer, ScreenRow, ScreenTitle, ScreenDivider, ScreenFooter } from \"./components.js\";\nimport { MultiColumnListComponent, MultiColumnListWithPreviewComponent, ListComponent } from \"./list-components.js\";\nimport {\n bindingIdentity,\n bindingMatchesInput,\n formatBindingKey,\n} from \"./key-bindings.js\";\n\n// Types\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n/**\n * Group key bindings by caption for footer display\n */\nexport function groupKeyBindings(bindings) {\n const groups = {};\n\n // Filter out disabled bindings\n const enabledBindings = bindings.filter(b => b.enabled !== false);\n\n enabledBindings.forEach(binding => {\n const caption = typeof binding.caption === \"string\" ? binding.caption : \"\";\n if (!groups[caption]) {\n groups[caption] = {\n keys: [],\n caption: caption,\n order: binding.order || 999\n };\n }\n groups[caption].keys.push(formatBindingKey(binding));\n });\n\n return Object.values(groups);\n}\n\n/**\n * Format key bindings for footer (returns array of strings/components)\n */\nexport function formatKeyBindings(bindings, mode = \"long\") {\n // Resolve function captions\n const resolvedBindings = bindings.map(binding => {\n let resolvedCaption = binding.caption;\n\n // If caption is a function, call it\n if (typeof binding.caption === \"function\") {\n resolvedCaption = binding.caption();\n }\n\n return {\n ...binding,\n resolvedCaption\n };\n });\n\n const groups = groupKeyBindings(resolvedBindings.map(b => ({\n ...b,\n caption: typeof b.resolvedCaption === \"string\" ? b.resolvedCaption : \"\"\n })));\n\n // Sort by order\n groups.sort((a, b) => a.order - b.order);\n\n const items = [];\n\n groups.forEach(group => {\n // Check if any binding in this group has a component/custom caption\n const bindingWithCustom = resolvedBindings.find(b =>\n group.keys.includes(b.key) && typeof b.resolvedCaption !== \"string\"\n );\n\n if (bindingWithCustom && bindingWithCustom.resolvedCaption) {\n // Use the full custom display (component or complex structure)\n items.push(bindingWithCustom.resolvedCaption );\n } else {\n // Standard format with string caption\n const keyStr = formatKeys(group.keys);\n\n if (mode === \"long\") {\n items.push(`${keyStr} to ${group.caption}`);\n } else {\n items.push(keyStr);\n }\n }\n });\n\n return items;\n}\n\n/**\n * Format keys for display\n */\nexport function formatKeys(keys) {\n // `keys` may already be display labels (from groupKeyBindings) or raw key names.\n const keyMap = {\n escape: \"esc\",\n leftArrow: \"←\",\n rightArrow: \"→\",\n upArrow: \"↑\",\n downArrow: \"↓\",\n return: \"enter\",\n pageUp: \"PgUp\",\n pageDown: \"PgDn\",\n };\n\n return keys.map((k) => keyMap[k] || k).join(\"/\");\n}\n\n/**\n * Show screen with action-based architecture\n */\nexport async function showScreen(config) {\n const {\n title,\n onRender,\n parentData = {}\n } = config;\n\n\n return new Promise((resolve) => {\n // eslint-disable-next-line prefer-const\n let instance;\n\n // Persistent collections (closure variables survive re-renders)\n const keyBindings = [];\n const actions = {};\n const customFooterItems = [];\n let renderResult = null;\n let initialized = false;\n\n const Screen = () => {\n const [, setUpdateCounter] = useState(0);\n\n // Initialize defaults only once\n if (!initialized) {\n const defaultBindings = [\n { key: \"escape\", caption: \"go back\", action: \"back\", protected: true, order: 1 },\n { key: \"leftArrow\", caption: \"go back\", action: \"back\", protected: false, order: 1 }\n // Note: 'select' is not a default - components add it if needed\n ];\n\n // Add defaults\n defaultBindings.forEach(binding => {\n keyBindings.push(binding);\n });\n\n // Default actions\n actions.back = () => {\n cleanup(null);\n };\n\n initialized = true;\n }\n\n // Context for onRender\n const context = {\n setAction: (actionName, handlerFn) => {\n actions[actionName] = handlerFn;\n },\n\n setKeyBinding: (bindingOrBindings) => {\n // Support both single object and array\n const bindingsToSet = Array.isArray(bindingOrBindings) ? bindingOrBindings : [bindingOrBindings];\n\n bindingsToSet.forEach(binding => {\n const id = bindingIdentity(binding);\n const existingIndex = keyBindings.findIndex(\n (b) => bindingIdentity(b) === id,\n );\n\n if (existingIndex >= 0) {\n const existing = keyBindings[existingIndex];\n\n // Can't override protected keys\n if (existing.protected) {\n console.warn(`Cannot override protected key: ${binding.key}`);\n return;\n }\n\n // Replace binding (keep original order if not specified)\n keyBindings[existingIndex] = {\n ...existing,\n ...binding,\n order: binding.order !== undefined ? binding.order : existing.order,\n enabled: binding.enabled !== undefined ? binding.enabled : (existing.enabled !== undefined ? existing.enabled : true)\n };\n } else {\n // Add new binding\n keyBindings.push({\n protected: false,\n order: 999,\n enabled: true,\n ...binding\n });\n }\n });\n },\n\n updateKeyBinding: (keyName, updates) => {\n // Prefer identity match when updates carry modifiers; else first key name.\n const id =\n updates && (updates.meta != null || updates.ctrl != null || updates.shift != null)\n ? bindingIdentity({ key: keyName, ...updates })\n : null;\n const index = keyBindings.findIndex((b) =>\n id ? bindingIdentity(b) === id : b.key === keyName,\n );\n if (index >= 0) {\n // Update only specified properties\n keyBindings[index] = {\n ...keyBindings[index],\n ...updates\n };\n }\n },\n\n removeKeyBinding: (keyNameOrBinding) => {\n const index =\n typeof keyNameOrBinding === \"object\" && keyNameOrBinding\n ? keyBindings.findIndex(\n (b) => bindingIdentity(b) === bindingIdentity(keyNameOrBinding),\n )\n : keyBindings.findIndex((b) => b.key === keyNameOrBinding);\n if (index >= 0) {\n if (keyBindings[index].protected) {\n console.warn(`Cannot remove protected key: ${keyNameOrBinding}`);\n return;\n }\n keyBindings.splice(index, 1);\n }\n },\n\n addFooter: (item) => {\n customFooterItems.push(item);\n },\n\n clearFooter: () => {\n customFooterItems.length = 0;\n },\n\n setFooter: (items) => {\n customFooterItems.length = 0;\n const itemsArray = Array.isArray(items) ? items : [items];\n customFooterItems.push(...itemsArray);\n },\n\n update: () => {\n setUpdateCounter(c => c + 1);\n },\n\n goBack: () => {\n if (actions.back) {\n actions.back();\n }\n },\n\n close: (result) => {\n cleanup(result);\n },\n\n parentData\n };\n\n // Call onRender once to let component set up\n if (!renderResult) {\n renderResult = onRender(context);\n }\n\n // Handle input - dispatch to actions\n useInput((input, key) => {\n // Check Ctrl+C for exit\n if (key.ctrl && input === \"c\") {\n cleanup(null);\n process.exit(0);\n return;\n }\n\n // Find matching key binding\n let matchedBinding = null;\n\n for (const binding of keyBindings) {\n if (binding.enabled === false) continue;\n if (!bindingMatchesInput(binding, input, key)) continue;\n if (binding.condition && !binding.condition(context)) continue;\n\n matchedBinding = binding;\n break;\n }\n\n if (matchedBinding && actions[matchedBinding.action]) {\n // Execute action\n actions[matchedBinding.action]({\n input,\n key,\n binding: matchedBinding\n });\n\n // If action returns a value, might be used for something\n // For now, actions manage their own state via closures\n }\n });\n\n // Build footer\n const footerLines = [];\n\n // Add key bindings (returns array of strings/components)\n const bindingItems = formatKeyBindings(keyBindings, \"long\");\n\n if (bindingItems.length > 0) {\n // Build a single line with all binding items separated by \", \"\n const bindingsLine = [];\n bindingItems.forEach((item, idx) => {\n if (idx > 0) {\n bindingsLine.push(\", \");\n }\n bindingsLine.push(item);\n });\n\n // If all items are strings, join them; otherwise create a Box\n const allStrings = bindingItems.every(item => typeof item === \"string\");\n if (allStrings) {\n footerLines.push(bindingsLine.join(\"\"));\n } else {\n // Mixed strings and components - wrap all strings in Text components\n const wrappedBindingsLine = bindingsLine.map(item => \n typeof item === \"string\" ? h(Text, {}, item) : item\n );\n footerLines.push(wrappedBindingsLine);\n }\n }\n\n // Add custom footer items\n customFooterItems.forEach(item => {\n if (typeof item === \"string\") {\n footerLines.push(item);\n } else {\n footerLines.push(item);\n }\n });\n\n return h(ScreenContainer, {},\n h(ScreenTitle, { text: title }),\n h(ScreenDivider),\n h(ScreenRow, {}, h(Text, {}, \" \")),\n renderResult,\n h(ScreenRow, {}, h(Text, {}, \" \")),\n h(ScreenDivider),\n h(ScreenFooter, { lines: footerLines })\n );\n };\n\n const cleanup = (result) => {\n if (instance) instance.unmount();\n setTimeout(() => resolve(result), 50);\n };\n\n instance = render(h(Screen));\n });\n}\n\n/**\n * Helper: Show list screen (single column menu)\n */\nexport async function showListScreen(config) {\n const { title, items, onSelect, onEscape, parentData, initialSelectedIndex = 0, renderItem, getTitle, sortable, maxHeight, sortHighlightStyle, selectionMarker } = config;\n\n return showScreen({\n title,\n parentData,\n onRender: (ctx) => {\n // Shared state ref\n const selectedIndexRef = { current: initialSelectedIndex };\n\n // Set up select action at screen level\n ctx.setAction(\"select\", () => {\n const selected = items[selectedIndexRef.current];\n if (onSelect) {\n const result = onSelect(selected.value, selectedIndexRef.current);\n ctx.close(result);\n }\n });\n\n // Set up back action if provided\n if (onEscape) {\n ctx.setAction(\"back\", () => {\n const result = onEscape(selectedIndexRef.current);\n ctx.close(result);\n });\n }\n\n // Add select key binding\n ctx.setKeyBinding({ key: \"return\", caption: \"select\", action: \"select\", order: 2 });\n\n // Return the component (it will set up its own navigation actions and bindings)\n return h(ListComponent, { items, ctx, selectedIndexRef, renderItem, getTitle, sortable, maxHeight, sortHighlightStyle, selectionMarker });\n }\n });\n}\n\n/**\n * Helper: Show multi-column list screen (grid layout)\n */\nexport async function showMultiColumnListScreen(config) {\n const { title, items, onSelect, onEscape, parentData, initialSelectedIndex = 0 } = config;\n\n return showScreen({\n title,\n parentData,\n onRender: (ctx) => {\n // Shared state ref\n const selectedIndexRef = { current: initialSelectedIndex };\n\n // Set up select action at screen level\n ctx.setAction(\"select\", () => {\n const selected = items[selectedIndexRef.current];\n if (onSelect) {\n const result = onSelect(selected, selectedIndexRef.current);\n ctx.close(result);\n }\n });\n\n // Set up back action if provided\n if (onEscape) {\n ctx.setAction(\"back\", () => {\n const result = onEscape(selectedIndexRef.current);\n ctx.close(result);\n });\n }\n\n // Add select key binding\n ctx.setKeyBinding({ key: \"return\", caption: \"select\", action: \"select\", order: 2 });\n\n // Return the component (it will set up its own navigation actions and bindings)\n return h(MultiColumnListComponent, { items, ctx, selectedIndexRef });\n }\n });\n}\n\n/**\n * Helper: Show multi-column list with preview panel below\n */\nexport async function showMultiColumnListWithPreviewScreen(config) {\n const { title, items, getPreviewContent, onSelect, onEscape, parentData, initialSelectedIndex = 0 } = config;\n\n return showScreen({\n title,\n parentData,\n onRender: (ctx) => {\n // Shared state ref\n const selectedIndexRef = { current: initialSelectedIndex };\n\n // Set up select action at screen level\n ctx.setAction(\"select\", () => {\n const selected = items[selectedIndexRef.current];\n if (onSelect) {\n const result = onSelect(selected, selectedIndexRef.current);\n ctx.close(result);\n }\n });\n\n // Set up back action if provided\n if (onEscape) {\n ctx.setAction(\"back\", () => {\n const result = onEscape(selectedIndexRef.current);\n ctx.close(result);\n });\n }\n\n // Add select key binding\n ctx.setKeyBinding({ key: \"return\", caption: \"select\", action: \"select\", order: 2 });\n\n // Return the component (it will set up its own navigation actions and bindings)\n return h(MultiColumnListWithPreviewComponent, { items, getPreviewContent, ctx, selectedIndexRef });\n }\n });\n}\n\n// Backward compatibility aliases\nexport const showMenuScreen = showListScreen;\nexport const showWordGridScreen = showMultiColumnListScreen;\n","/**\n * Core screen layout components\n */\n\nimport { createElement as h } from \"react\";\nimport { Box, Text } from \"ink\";\n\n/**\n * Get screen width for borders\n * @param maxWidth - Optional max width (null = no limit)\n */\nexport function getScreenWidth(maxWidth = null) {\n const terminalWidth = process.stdout.columns || 80;\n // Leave some margin for borders and padding\n const availableWidth = Math.max(20, terminalWidth - 4);\n return maxWidth ? Math.min(availableWidth, maxWidth) : availableWidth;\n}\n\n// Types\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n/**\n * Screen Container - uses Ink's built-in borderStyle for proper text wrapping\n */\nexport function ScreenContainer({ children }) {\n const width = getScreenWidth();\n\n return h(Box, {\n flexDirection: \"column\",\n marginTop: 1,\n borderStyle: \"single\",\n borderColor: \"cyan\",\n paddingX: 1,\n width: width // Use the calculated width directly\n }, children);\n}\n\n/**\n * Screen row - just a wrapper for spacing, borders handled by container\n */\nexport function ScreenRow({ children }) {\n return h(Box, { flexDirection: \"column\" }, children);\n}\n\n/**\n * Screen Title - first line inside container (left-aligned, breadcrumb-style)\n */\nexport function ScreenTitle({ text }) {\n return h(ScreenRow, {},\n h(Text, { bold: true, color: \"cyan\" }, text)\n );\n}\n\n/**\n * Horizontal divider line\n */\nexport function ScreenDivider({ width }) {\n const dividerWidth = width || (getScreenWidth() - 4); // Account for border and padding\n return h(Text, { color: \"cyan\", dimColor: true }, \"─\".repeat(dividerWidth));\n}\n\n/**\n * Screen Body - main content area\n */\nexport function ScreenBody({ children, alignItems = \"flex-start\" }) {\n return h(Box, { flexDirection: \"column\", alignItems }, children);\n}\n\n/**\n * Screen Footer - bottom area with key bindings and status\n * \n * @example\n * <ScreenFooter lines={[\"esc to go back\", \"enter to select\"]} />\n * \n * @example\n * <ScreenFooter \n * lines={[\"esc to go back\", \"enter to select\"]} \n * textStyle={{ color: \"white\" }}\n * />\n * \n * @example\n * <ScreenFooter \n * lines={[\"esc to go back\", \"enter to select\"]} \n * textStyle={{ dimColor: false, color: \"green\" }}\n * />\n */\nexport function ScreenFooter({ lines, textStyle }) {\n const defaultTextStyle = {\n dimColor: true,\n color: \"white\"\n };\n \n const finalTextStyle = { ...defaultTextStyle, ...textStyle };\n\n // Flatten nested arrays and ensure all items are properly wrapped\n const flattenAndWrap = (items, keyPrefix = \"\") => {\n const result = [];\n let keyIndex = 0;\n\n items.forEach((item, index) => {\n if (Array.isArray(item)) {\n // Handle nested arrays\n const nested = flattenAndWrap(item, `${keyPrefix}-${index}`);\n result.push(...nested);\n } else if (typeof item === \"string\") {\n // Wrap strings in Text components\n result.push(\n h(Text, { key: `${keyPrefix}-${keyIndex++}`, ...finalTextStyle }, item)\n );\n } else {\n // JSX elements - add key if missing\n const element = item ;\n if (element.key === null || element.key === undefined) {\n result.push(\n h(Text, { key: `${keyPrefix}-${keyIndex++}`, ...finalTextStyle }, element)\n );\n } else {\n result.push(element);\n }\n }\n });\n\n return result;\n };\n\n const wrappedItems = flattenAndWrap(lines);\n\n return h(Box, { flexDirection: \"column\" },\n h(Box, { flexDirection: \"row\" }, ...wrappedItems)\n );\n}","/**\n * Reusable screen components for V2 architecture\n */\n\nimport React, { useState, useEffect, useRef, createElement } from \"react\";\nimport { Box, Text } from \"ink\";\nimport { ScreenRow, ScreenDivider } from \"./components.js\";\n\nconst h = createElement;\n\n// TODO: Define proper context type interface\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n/**\n * Multi-column list component\n * Handles its own navigation, actions, and key bindings\n */\nexport function MultiColumnListComponent({ items, ctx, selectedIndexRef }) {\n const [, forceUpdate] = useState({});\n\n // Calculate layout\n const termWidth = (process.stdout.columns || 80) - 8;\n const maxItemLength = Math.max(...items.map(w => w.length));\n const columnWidth = maxItemLength + 3;\n const columns = Math.max(1, Math.floor(termWidth / columnWidth));\n const itemsPerColumn = Math.ceil(items.length / columns);\n\n // Set up actions in useEffect (runs once)\n useEffect(() => {\n ctx.setAction(\"moveUp\", () => {\n selectedIndexRef.current = Math.max(0, selectedIndexRef.current - 1);\n forceUpdate({});\n });\n\n ctx.setAction(\"moveDown\", () => {\n selectedIndexRef.current = Math.min(items.length - 1, selectedIndexRef.current + 1);\n forceUpdate({});\n });\n\n ctx.setAction(\"moveLeft\", () => {\n if (selectedIndexRef.current === 0) {\n ctx.goBack();\n } else {\n selectedIndexRef.current = Math.max(0, selectedIndexRef.current - itemsPerColumn);\n forceUpdate({});\n }\n });\n\n ctx.setAction(\"moveRight\", () => {\n selectedIndexRef.current = Math.min(items.length - 1, selectedIndexRef.current + itemsPerColumn);\n forceUpdate({});\n });\n\n // Set up key bindings\n ctx.setKeyBinding([\n { key: \"leftArrow\", caption: \"navigate\", action: \"moveLeft\", order: 0 },\n { key: \"rightArrow\", caption: \"navigate\", action: \"moveRight\", order: 0 },\n { key: \"upArrow\", caption: \"navigate\", action: \"moveUp\", order: 0 },\n { key: \"downArrow\", caption: \"navigate\", action: \"moveDown\", order: 0 }\n ]);\n\n // Add footer\n ctx.addFooter(`Total: ${items.length} items`);\n }, []);\n\n const selectedIndex = selectedIndexRef.current;\n\n // Build grid\n const rows = [];\n for (let row = 0; row < itemsPerColumn; row++) {\n const cols = [];\n for (let col = 0; col < columns; col++) {\n const index = col * itemsPerColumn + row;\n if (index < items.length) {\n const isSelected = index === selectedIndex;\n cols.push(\n h(Box, { key: index, width: columnWidth },\n h(Text, {\n color: isSelected ? \"black\" : \"white\",\n backgroundColor: isSelected ? \"cyan\" : undefined,\n bold: isSelected\n }, items[index].padEnd(maxItemLength))\n )\n );\n }\n }\n rows.push(\n h(ScreenRow, { key: row, children: h(Box, { flexDirection: \"row\" }, ...cols) })\n );\n }\n\n return h(Box, { flexDirection: \"column\" }, ...rows);\n}\n\n/**\n * Multi-column list with preview panel component\n * Shows selected item details below the list\n */\nexport function MultiColumnListWithPreviewComponent({\n items,\n getPreviewContent,\n ctx,\n selectedIndexRef\n}) {\n const [, forceUpdate] = useState({});\n\n // Calculate layout\n const termWidth = (process.stdout.columns || 80) - 8;\n const maxItemLength = Math.max(...items.map(w => w.length));\n const columnWidth = maxItemLength + 3;\n const columns = Math.max(1, Math.floor(termWidth / columnWidth));\n const itemsPerColumn = Math.ceil(items.length / columns);\n\n // Set up actions in useEffect (runs once)\n useEffect(() => {\n ctx.setAction(\"moveUp\", () => {\n selectedIndexRef.current = Math.max(0, selectedIndexRef.current - 1);\n forceUpdate({});\n });\n\n ctx.setAction(\"moveDown\", () => {\n selectedIndexRef.current = Math.min(items.length - 1, selectedIndexRef.current + 1);\n forceUpdate({});\n });\n\n ctx.setAction(\"moveLeft\", () => {\n if (selectedIndexRef.current === 0) {\n ctx.goBack();\n } else {\n selectedIndexRef.current = Math.max(0, selectedIndexRef.current - itemsPerColumn);\n forceUpdate({});\n }\n });\n\n ctx.setAction(\"moveRight\", () => {\n selectedIndexRef.current = Math.min(items.length - 1, selectedIndexRef.current + itemsPerColumn);\n forceUpdate({});\n });\n\n // Set up key bindings\n ctx.setKeyBinding([\n { key: \"leftArrow\", caption: \"navigate\", action: \"moveLeft\", order: 0 },\n { key: \"rightArrow\", caption: \"navigate\", action: \"moveRight\", order: 0 },\n { key: \"upArrow\", caption: \"navigate\", action: \"moveUp\", order: 0 },\n { key: \"downArrow\", caption: \"navigate\", action: \"moveDown\", order: 0 }\n ]);\n\n // Add footer\n ctx.addFooter(`Total: ${items.length} items`);\n }, []);\n\n const selectedIndex = selectedIndexRef.current;\n const selectedItem = items[selectedIndex];\n\n // Build grid\n const rows = [];\n for (let row = 0; row < itemsPerColumn; row++) {\n const cols = [];\n for (let col = 0; col < columns; col++) {\n const index = col * itemsPerColumn + row;\n if (index < items.length) {\n const isSelected = index === selectedIndex;\n cols.push(\n h(Box, { key: index, width: columnWidth },\n h(Text, {\n color: isSelected ? \"black\" : \"white\",\n backgroundColor: isSelected ? \"cyan\" : undefined,\n bold: isSelected\n }, items[index].padEnd(maxItemLength))\n )\n );\n }\n }\n rows.push(\n h(ScreenRow, { key: row, children: h(Box, { flexDirection: \"row\" }, ...cols) })\n );\n }\n\n // Get preview content for selected item\n const previewContent = getPreviewContent ? getPreviewContent(selectedItem) : selectedItem;\n\n const previewRows = [];\n if (typeof previewContent === \"string\") {\n previewRows.push(h(ScreenRow, { key: \"preview-string\", children: h(Text, { bold: true }, previewContent) }));\n } else if (typeof previewContent === \"object\" && !React.isValidElement(previewContent) && previewContent !== null) {\n Object.entries(previewContent).forEach(([key, value], idx) => {\n previewRows.push(h(ScreenRow, { key: `preview-${key}-${idx}`, children: h(Text, {}, `${key}: ${value}`) }));\n });\n } else if (React.isValidElement(previewContent)) {\n previewRows.push(h(ScreenRow, { key: \"preview-element\", children: previewContent }));\n }\n\n return h(Box, { flexDirection: \"column\" },\n ...rows,\n h(ScreenRow, { key: \"spacer-1\", children: h(Text, {}, \" \") }),\n h(ScreenDivider, { key: \"divider\" }),\n h(ScreenRow, { key: \"spacer-2\", children: h(Text, {}, \" \") }),\n ...previewRows\n );\n}\n\n/**\n * Single-column list component\n * Simple vertical menu with optional sorting\n */\nexport function ListComponent({ items, ctx, selectedIndexRef, renderItem, getTitle, sortable = false, maxHeight, sortHighlightStyle, selectionMarker = \" \", onSelectionChange }) {\n const [, forceUpdate] = useState({});\n const [sortOrder, setSortOrder] = useState(\"none\");\n const [scrollOffset, setScrollOffset] = useState(0);\n \n // Use refs to store current scroll values to avoid stale closures\n const scrollStateRef = useRef({ scrollOffset: 0, maxHeight: 0, totalItems: 0 });\n const itemsRef = useRef(items);\n itemsRef.current = items;\n\n // Default getTitle - returns item if string, otherwise item.title\n const defaultGetTitle = (item) => {\n return getTitle ? getTitle(item) : (typeof item.value === \"string\" ? item.value : (item.value?.title || item.name));\n };\n\n // Get title for sorting\n const titleGetter = getTitle || defaultGetTitle;\n\n // Apply sorting if enabled\n const displayItems = sortable && sortOrder !== \"none\" ? [...items].sort((a, b) => {\n const titleA = titleGetter(a).toLowerCase();\n const titleB = titleGetter(b).toLowerCase();\n if (sortOrder === \"asc\") {\n return titleA < titleB ? -1 : titleA > titleB ? 1 : 0;\n } else {\n return titleA > titleB ? -1 : titleA < titleB ? 1 : 0;\n }\n }) : items;\n\n const displayItemsRef = useRef(displayItems);\n displayItemsRef.current = displayItems;\n\n // Calculate scrolling\n const effectiveMaxHeight = maxHeight || displayItems.length;\n const _canScroll = displayItems.length > effectiveMaxHeight;\n const maxScrollOffset = Math.max(0, displayItems.length - effectiveMaxHeight);\n \n // Ensure scroll offset is within bounds\n const clampedScrollOffset = Math.min(Math.max(0, scrollOffset), maxScrollOffset);\n \n // Get visible items\n const visibleItems = displayItems.slice(clampedScrollOffset, clampedScrollOffset + effectiveMaxHeight);\n \n // Check if we can scroll up/down\n const canScrollUp = clampedScrollOffset > 0;\n const canScrollDown = clampedScrollOffset < maxScrollOffset;\n \n // Update scroll state ref with current values\n scrollStateRef.current = { scrollOffset, maxHeight: effectiveMaxHeight, totalItems: displayItems.length };\n \n\n const onSelectionChangeRef = useRef(onSelectionChange);\n onSelectionChangeRef.current = onSelectionChange;\n\n // Set up actions in useEffect (runs once)\n useEffect(() => {\n ctx.setAction(\"moveUp\", () => {\n const newIndex = Math.max(0, selectedIndexRef.current - 1);\n selectedIndexRef.current = newIndex;\n const list = displayItemsRef.current;\n onSelectionChangeRef.current?.(newIndex, list[newIndex]);\n\n // Auto-scroll to keep selected item visible\n const { scrollOffset: currentScrollOffset, maxHeight: currentMaxHeight, totalItems } = scrollStateRef.current;\n const currentMaxScrollOffset = Math.max(0, totalItems - currentMaxHeight);\n const currentClampedScrollOffset = Math.min(Math.max(0, currentScrollOffset), currentMaxScrollOffset);\n\n if (newIndex < currentClampedScrollOffset) {\n setScrollOffset(newIndex);\n }\n\n forceUpdate({});\n });\n\n ctx.setAction(\"moveDown\", () => {\n const currentItems = displayItemsRef.current;\n const maxIndex = Math.max(0, currentItems.length - 1);\n const newIndex = Math.min(maxIndex, selectedIndexRef.current + 1);\n selectedIndexRef.current = newIndex;\n onSelectionChangeRef.current?.(newIndex, currentItems[newIndex]);\n\n // Auto-scroll to keep selected item visible\n const { scrollOffset: currentScrollOffset, maxHeight: currentMaxHeight, totalItems } = scrollStateRef.current;\n const currentMaxScrollOffset = Math.max(0, totalItems - currentMaxHeight);\n const currentClampedScrollOffset = Math.min(Math.max(0, currentScrollOffset), currentMaxScrollOffset);\n\n if (newIndex >= currentClampedScrollOffset + currentMaxHeight) {\n setScrollOffset(newIndex - currentMaxHeight + 1);\n }\n\n forceUpdate({});\n });\n\n // Add scroll actions for arrow clicks\n ctx.setAction(\"scrollUp\", () => {\n const { scrollOffset: currentScrollOffset } = scrollStateRef.current;\n const newScrollOffset = Math.max(0, currentScrollOffset - 1);\n setScrollOffset(newScrollOffset);\n forceUpdate({});\n });\n\n ctx.setAction(\"scrollDown\", () => {\n const { scrollOffset: currentScrollOffset, maxHeight: currentMaxHeight, totalItems } = scrollStateRef.current;\n const currentMaxScrollOffset = Math.max(0, totalItems - currentMaxHeight);\n const newScrollOffset = Math.min(currentMaxScrollOffset, currentScrollOffset + 1);\n setScrollOffset(newScrollOffset);\n forceUpdate({});\n });\n\n // Set up sort action if sortable\n if (sortable) {\n ctx.setAction(\"toggleSort\", () => {\n const nextSort = \n sortOrder === \"none\" ? \"asc\" : \n sortOrder === \"asc\" ? \"desc\" : \"none\";\n \n // Store the currently selected item from the current display items\n const currentSelectedItem = displayItemsRef.current[selectedIndexRef.current];\n \n setSortOrder(nextSort);\n \n // Calculate the new sorted items\n const newSortedItems = nextSort !== \"none\" ? [...itemsRef.current].sort((a, b) => {\n const titleA = titleGetter(a).toLowerCase();\n const titleB = titleGetter(b).toLowerCase();\n if (nextSort === \"asc\") {\n return titleA < titleB ? -1 : titleA > titleB ? 1 : 0;\n } else {\n return titleA > titleB ? -1 : titleA < titleB ? 1 : 0;\n }\n }) : itemsRef.current;\n \n // Find the new index of the selected item in the new sorted list\n const newIndex = newSortedItems.findIndex(item => item === currentSelectedItem);\n if (newIndex !== -1) {\n selectedIndexRef.current = newIndex;\n // Set scroll position to show the selected item at the top\n setScrollOffset(newIndex);\n } else {\n // Fallback: if item not found, select first item\n selectedIndexRef.current = 0;\n setScrollOffset(0);\n }\n \n forceUpdate({});\n });\n\n // Default highlight style (green background, black text, bold)\n const defaultHighlightStyle = {\n color: \"black\",\n backgroundColor: \"green\", \n bold: true\n };\n const highlightStyle = { ...defaultHighlightStyle, ...sortHighlightStyle };\n\n // Create caption that includes sort status\n const sortCaption = () => {\n if (sortOrder === \"none\") {\n return h(Text, {}, \"s to toggle sort\");\n } else {\n const sortLabel = sortOrder === \"asc\" ? \"ASC\" : \"DESC\";\n return h(Text, {}, \n \"s to toggle \",\n h(Text, { color: \"white\", bold: true }, \"sort\"),\n \" \",\n h(Text, highlightStyle, ` ${sortLabel} `)\n );\n }\n };\n\n // Update key bindings with sort\n ctx.setKeyBinding([\n { key: \"upArrow\", caption: \"navigate\", action: \"moveUp\", order: 0 },\n { key: \"downArrow\", caption: \"navigate\", action: \"moveDown\", order: 0 },\n { \n key: \"s\", \n caption: sortCaption,\n action: \"toggleSort\", \n order: 5 \n }\n ]);\n\n // Force update to show the new caption in footer\n ctx.update();\n } else {\n // No sorting\n ctx.setKeyBinding([\n { key: \"upArrow\", caption: \"navigate\", action: \"moveUp\", order: 0 },\n { key: \"downArrow\", caption: \"navigate\", action: \"moveDown\", order: 0 }\n ]);\n }\n }, [sortOrder, sortable]);\n\n const selectedIndex = selectedIndexRef.current;\n \n\n // Default renderer with static scroll indicators for debugging\n const defaultRenderItem = (item, isSelected, displayIndex, actualIndex) => {\n const isFirstVisible = displayIndex === 0;\n const isLastVisible = displayIndex === visibleItems.length - 1;\n \n // Build prefix with arrows and selection marker\n let arrowPrefix = \"\";\n let selectionPrefix = \"\";\n \n // Only show arrows when scrolling is actually needed and available\n if (isFirstVisible && canScrollUp) {\n arrowPrefix = \"↑ \";\n } else if (isLastVisible && canScrollDown) {\n arrowPrefix = \"↓ \";\n } else {\n // No arrow, but reserve the same space\n arrowPrefix = \" \";\n }\n \n // Always reserve space for selection marker (pad with spaces if not selected)\n if (isSelected) {\n selectionPrefix = selectionMarker;\n } else {\n // Pad with spaces to match the length of the selection marker\n selectionPrefix = \" \".repeat(selectionMarker.length);\n }\n \n return h(Box, { flexDirection: \"row\" },\n // Arrow (clickable if functional, not highlighted)\n h(Text, { \n key: `arrow-${actualIndex}`,\n color: \"white\"\n }, arrowPrefix),\n // Selection marker space (always same width, not highlighted) \n h(Text, { key: `marker-${actualIndex}`, color: \"white\" }, selectionPrefix),\n // Item name (highlighted if selected)\n h(Text, {\n key: `name-${actualIndex}`,\n color: isSelected ? \"black\" : \"white\",\n backgroundColor: isSelected ? \"cyan\" : undefined,\n bold: isSelected\n }, item.name)\n );\n };\n\n // Use custom renderer if provided, otherwise use default\n const itemRenderer = renderItem || defaultRenderItem;\n\n // Render visible menu items with scroll indicators\n return h(Box, { flexDirection: \"column\" },\n ...visibleItems.map((item, displayIndex) => {\n const actualIndex = clampedScrollOffset + displayIndex;\n const isSelected = actualIndex === selectedIndex;\n \n // If using custom renderer, wrap it with scroll indicators\n if (renderItem) {\n const isFirstVisible = displayIndex === 0;\n const isLastVisible = displayIndex === visibleItems.length - 1;\n \n // Build prefix with arrows and selection marker\n let arrowPrefix = \"\";\n let selectionPrefix = \"\";\n \n // Only show arrows when scrolling is actually needed and available\n if (isFirstVisible && canScrollUp) {\n arrowPrefix = \"↑ \";\n } else if (isLastVisible && canScrollDown) {\n arrowPrefix = \"↓ \";\n } else {\n // No arrow, but reserve the same space\n arrowPrefix = \" \";\n }\n \n // Always reserve space for selection marker (pad with spaces if not selected)\n if (isSelected) {\n selectionPrefix = selectionMarker;\n } else {\n // Pad with spaces to match the length of the selection marker\n selectionPrefix = \" \".repeat(selectionMarker.length);\n }\n \n return h(ScreenRow, {\n key: `item-${actualIndex}`,\n children: h(Box, { flexDirection: \"row\" },\n // Arrow (clickable if functional, not highlighted)\n h(Text, { \n key: `arrow-${actualIndex}`,\n color: \"white\"\n }, arrowPrefix),\n // Selection marker space (always same width, not highlighted) \n h(Text, { key: `marker-${actualIndex}`, color: \"white\" }, selectionPrefix),\n // Custom rendered content\n renderItem(item, isSelected, displayIndex)\n )\n });\n } else {\n // Use default renderer (which already includes scroll indicators)\n return h(ScreenRow, {\n key: `item-${actualIndex}`,\n children: itemRenderer(item, isSelected, displayIndex, actualIndex)\n });\n }\n })\n );\n}\n","/**\n * Key-binding helpers for showScreen (matching + footer labels).\n *\n * Bindings may set `meta` / `ctrl` / `shift` booleans. Plain bindings (flags\n * omitted) do not match when that modifier is held, so `↑` and `⌥↑` can coexist.\n */\n\n/**\n * Stable identity for replace/remove (key + modifiers).\n * @param {{ key: string, meta?: boolean, ctrl?: boolean, shift?: boolean }} b\n */\nexport function bindingIdentity(b) {\n return [\n String(b?.key ?? \"\"),\n b?.meta ? \"m\" : \"\",\n b?.ctrl ? \"c\" : \"\",\n b?.shift ? \"s\" : \"\",\n ].join(\"|\");\n}\n\n/**\n * @param {{ key: string, meta?: boolean, ctrl?: boolean, shift?: boolean }} binding\n * @param {string} input\n * @param {import(\"ink\").Key} key\n */\nexport function bindingMatchesInput(binding, input, key) {\n if (!binding?.key) return false;\n\n let keyMatches = false;\n if (key?.[binding.key]) {\n keyMatches = true;\n } else if (input === binding.key) {\n keyMatches = true;\n } else if (key?.name === binding.key) {\n keyMatches = true;\n }\n if (!keyMatches) return false;\n\n // Explicit true → require; explicit false → forbid; omitted → forbid if pressed\n // (so plain upArrow does not fire for meta+up).\n const modOk = (flag, pressed) => {\n if (flag === true) return !!pressed;\n if (flag === false) return !pressed;\n return !pressed;\n };\n\n // shift is often used with letters; for arrows we still treat omitted as \"any\"\n // only for shift — meta/ctrl are the page-jump modifiers we care about.\n if (!modOk(binding.meta, key?.meta)) return false;\n if (!modOk(binding.ctrl, key?.ctrl)) return false;\n if (binding.shift !== undefined && !!key?.shift !== !!binding.shift) return false;\n\n return true;\n}\n\nconst KEY_LABELS = {\n escape: \"esc\",\n leftArrow: \"←\",\n rightArrow: \"→\",\n upArrow: \"↑\",\n downArrow: \"↓\",\n return: \"enter\",\n pageUp: \"PgUp\",\n pageDown: \"PgDn\",\n};\n\n/**\n * Human label for one binding (modifiers + key), e.g. `⌥↑`, `^↓`, `PgUp`.\n * @param {{ key: string, meta?: boolean, ctrl?: boolean, shift?: boolean }} binding\n */\nexport function formatBindingKey(binding) {\n let label = KEY_LABELS[binding.key] || binding.key;\n if (binding.shift) label = `⇧${label}`;\n if (binding.ctrl) label = `^${label}`;\n // ink `meta` is Option/Alt on macOS (⌘ is usually eaten by the terminal).\n if (binding.meta) label = `⌥${label}`;\n return label;\n}\n","/**\n * Reusable UI elements for the screen system\n */\n\nimport { createElement as h } from \"react\";\nimport { Box, Text } from \"ink\";\n\n// Types\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n/**\n * List item component\n */\nexport function ListItem({ \n children, \n isSelected = false, \n color = \"white\", \n backgroundColor, \n bold = false, \n dimColor = false \n}) {\n return h(Box, {},\n h(Text, {\n color: isSelected ? backgroundColor || \"green\" : color,\n backgroundColor: isSelected ? color : backgroundColor,\n bold: isSelected || bold,\n dimColor: !isSelected && dimColor\n }, children)\n );\n}\n\n/**\n * Text block component with customizable styling\n */\nexport function TextBlock({ \n text, \n color = \"white\", \n dimmed = false, \n bold = false, \n maxWidth: _maxWidth \n}) {\n return h(Box, {},\n h(Text, { \n color, \n dimColor: dimmed, \n bold \n }, text)\n );\n}\n\n/**\n * Horizontal divider\n */\nexport function Divider({ character = \"─\", width = 80 }) {\n return h(Box, { marginY: 1 },\n h(Text, { dimColor: true }, character.repeat(width))\n );\n}\n\n/**\n * Grid cell component\n */\nexport function GridCell({ \n children, \n width, \n color = \"white\", \n backgroundColor, \n bold = false, \n dimColor = false, \n align = \"left\" \n}) {\n return h(Box, { width },\n h(Text, {\n color,\n backgroundColor,\n bold,\n dimColor,\n textAlign: align\n }, children)\n );\n}\n\n/**\n * Input field component\n */\nexport function InputField({ prompt, value, onChange: _onChange, onSubmit: _onSubmit }) {\n return h(Box, { flexDirection: \"column\" },\n h(Text, {}, prompt),\n h(Box, { marginTop: 1 },\n h(Text, { color: \"cyan\" }, \" > \", value, \"_\")\n )\n );\n}","/**\n * ScrollableText — wrap long text, line/page scroll, proportional scrollbar.\n *\n * h(ScrollableText, { ctx, text: json, bindKeys: true })\n *\n * Keys (when bindKeys):\n * ↑/↓ — one line\n * ⌥↑/↓ ^↑/↓ — one page (ink `meta` ≈ Option/Alt; ⌘ often never reaches the TTY)\n * PgUp/PgDn — one page\n */\n\nimport { useState, useEffect, useMemo, useRef, createElement } from \"react\";\nimport { Box, Text } from \"ink\";\nimport { getScreenWidth } from \"./components.js\";\n\nconst h = createElement;\n\n/** ASCII-only: full-block `█` is often double-width in terminals and forces a wrap. */\nconst BAR_THUMB = \"#\";\nconst BAR_TRACK = \"|\";\n\n/**\n * Hard-wrap text to `cols` (keeps empty lines).\n * @param {string} text\n * @param {number} cols\n * @returns {string[]}\n */\nexport function wrapTextLines(text, cols) {\n const w = Math.max(1, Math.floor(Number(cols) || 1));\n const out = [];\n for (const raw of String(text ?? \"\").split(\"\\n\")) {\n if (raw.length === 0) {\n out.push(\"\");\n continue;\n }\n let rest = raw;\n while (rest.length > w) {\n out.push(rest.slice(0, w));\n rest = rest.slice(w);\n }\n if (rest.length > 0) out.push(rest);\n }\n return out;\n}\n\n/**\n * Proportional scrollbar glyphs for a viewport.\n * @returns {string[]|null} one glyph per viewport row, or null when no overflow\n */\nexport function scrollbarGlyphs(viewportRows, totalLines, scrollTop) {\n const view = Math.max(1, Math.floor(viewportRows));\n const total = Math.max(0, Math.floor(totalLines));\n if (total <= view) return null;\n\n const maxScroll = total - view;\n const thumbSize = Math.max(1, Math.round((view / total) * view));\n const travel = Math.max(0, view - thumbSize);\n const s = Math.min(Math.max(0, Math.floor(scrollTop)), maxScroll);\n const thumbStart = maxScroll === 0 ? 0 : Math.round((s / maxScroll) * travel);\n\n const glyphs = [];\n for (let i = 0; i < view; i++) {\n glyphs.push(i >= thumbStart && i < thumbStart + thumbSize ? BAR_THUMB : BAR_TRACK);\n }\n return glyphs;\n}\n\nfunction padEndVisible(s, w) {\n const t = String(s ?? \"\");\n if (t.length >= w) return t.slice(0, w);\n return t + \" \".repeat(w - t.length);\n}\n\nconst SCROLL_KEYS = [\n { key: \"upArrow\", caption: \"scroll\", action: \"scrollUp\", order: 0 },\n { key: \"downArrow\", caption: \"scroll\", action: \"scrollDown\", order: 0 },\n { key: \"upArrow\", meta: true, caption: \"page\", action: \"pageUp\", order: 0 },\n { key: \"downArrow\", meta: true, caption: \"page\", action: \"pageDown\", order: 0 },\n { key: \"upArrow\", ctrl: true, caption: \"page\", action: \"pageUp\", order: 0 },\n { key: \"downArrow\", ctrl: true, caption: \"page\", action: \"pageDown\", order: 0 },\n { key: \"pageUp\", caption: \"page\", action: \"pageUp\", order: 0 },\n { key: \"pageDown\", caption: \"page\", action: \"pageDown\", order: 0 },\n];\n\n/**\n * @param {{\n * ctx: object,\n * text?: string,\n * lines?: string[],\n * maxHeight?: number,\n * wrap?: boolean,\n * showScrollbar?: boolean,\n * showStatus?: boolean,\n * bindKeys?: boolean,\n * header?: unknown,\n * }} props\n */\nexport function ScrollableText({\n ctx,\n text = \"\",\n lines: linesProp,\n maxHeight,\n wrap = true,\n showScrollbar = true,\n showStatus = true,\n bindKeys = true,\n header = null,\n}) {\n const [scrollTop, setScrollTop] = useState(0);\n const [, bump] = useState(0);\n\n const termRows = process.stdout.rows || 24;\n const viewportRows = Math.max(\n 4,\n maxHeight != null ? Math.floor(maxHeight) : Math.max(8, termRows - 8),\n );\n\n // Match ScreenContainer inner width: container is term-4, minus border+paddingX → term-8\n // (same heuristic as ListComponent / ScreenDivider).\n const contentCols = Math.max(20, getScreenWidth() - 4);\n // Always reserve the bar column when enabled so wrap width does not jump when overflow starts.\n const barCols = showScrollbar ? 1 : 0;\n const textWidth = Math.max(8, contentCols - barCols);\n\n const allLines = useMemo(() => {\n if (Array.isArray(linesProp)) return linesProp.map((l) => String(l ?? \"\"));\n return wrap ? wrapTextLines(text, textWidth) : String(text ?? \"\").split(\"\\n\");\n }, [linesProp, text, wrap, textWidth]);\n\n const needsBar = showScrollbar && allLines.length > viewportRows;\n const maxScroll = Math.max(0, allLines.length - viewportRows);\n const clamped = Math.min(Math.max(0, scrollTop), maxScroll);\n const visible = allLines.slice(clamped, clamped + viewportRows);\n const bar = needsBar ? scrollbarGlyphs(viewportRows, allLines.length, clamped) : null;\n\n useEffect(() => {\n setScrollTop((s) => Math.min(s, maxScroll));\n }, [maxScroll]);\n\n const maxScrollRef = useRef(maxScroll);\n const pageSizeRef = useRef(viewportRows);\n maxScrollRef.current = maxScroll;\n pageSizeRef.current = viewportRows;\n\n useEffect(() => {\n if (!ctx || !bindKeys) return undefined;\n\n ctx.setKeyBinding(SCROLL_KEYS);\n\n ctx.setAction(\"scrollUp\", () => {\n setScrollTop((s) => Math.max(0, s - 1));\n bump((n) => n + 1);\n ctx.update?.();\n });\n ctx.setAction(\"scrollDown\", () => {\n setScrollTop((s) => Math.min(maxScrollRef.current, s + 1));\n bump((n) => n + 1);\n ctx.update?.();\n });\n ctx.setAction(\"pageUp\", () => {\n setScrollTop((s) => Math.max(0, s - pageSizeRef.current));\n bump((n) => n + 1);\n ctx.update?.();\n });\n ctx.setAction(\"pageDown\", () => {\n setScrollTop((s) => Math.min(maxScrollRef.current, s + pageSizeRef.current));\n bump((n) => n + 1);\n ctx.update?.();\n });\n\n return undefined;\n }, [ctx, bindKeys]);\n\n const status =\n allLines.length === 0\n ? \"empty\"\n : `lines ${clamped + 1}-${Math.min(clamped + visible.length, allLines.length)} of ${allLines.length}` +\n (needsBar ? \" · ⌥↑/↓ or PgUp/Dn page\" : \"\");\n\n // Single Text per row (not a row Box): avoids yoga width surprises; ASCII bar is 1 cell.\n const rowNodes = visible.map((line, i) => {\n const body = padEndVisible(line, textWidth);\n const glyph = bar ? bar[i] ?? BAR_TRACK : showScrollbar ? \" \" : \"\";\n const isThumb = glyph === BAR_THUMB;\n return h(\n Text,\n { key: `L${clamped + i}` },\n body,\n glyph\n ? h(Text, { color: isThumb ? \"cyan\" : \"gray\" }, glyph)\n : null,\n );\n });\n\n // Pad short final page so the scrollbar track stays full height.\n if (bar && visible.length < viewportRows) {\n for (let i = visible.length; i < viewportRows; i++) {\n const glyph = bar[i] ?? BAR_TRACK;\n rowNodes.push(\n h(\n Text,\n { key: `pad${i}` },\n padEndVisible(\"\", textWidth),\n h(Text, { color: glyph === BAR_THUMB ? \"cyan\" : \"gray\" }, glyph),\n ),\n );\n }\n }\n\n return h(\n Box,\n { flexDirection: \"column\" },\n header == null\n ? null\n : typeof header === \"string\"\n ? h(Text, { color: \"gray\" }, header)\n : header,\n showStatus ? h(Text, { color: \"gray\" }, status) : null,\n ...rowNodes,\n );\n}\n","/**\n * Utility functions for Screen System\n */\n\n/**\n * Build breadcrumb-style title\n * @param parts - Parts of the breadcrumb path\n * @returns Formatted breadcrumb\n *\n * Examples:\n * buildBreadcrumb(['Menu']) → 'Menu'\n * buildBreadcrumb(['Menu', 'Info']) → '← Info'\n * buildBreadcrumb(['Menu', 'Words', 'nefarious']) → '← Words ← nefarious'\n */\nexport function buildBreadcrumb(parts) {\n if (parts.length === 0) return \"\";\n if (parts.length === 1) return parts[0];\n\n // Skip first part (root), add arrows with spaces to rest\n return parts.slice(1).map(part => `← ${part}`).join(\" \");\n}\n\n/**\n * Create multi-line breadcrumb with details\n * @param path - Navigation path\n * @param suffix - Additional suffix (e.g., 'Details')\n * @returns Formatted breadcrumb with suffix\n *\n * Example:\n * buildDetailBreadcrumb(['Menu', 'Words', 'nefarious'], 'Details')\n * → '← Words ← nefarious Details'\n */\nexport function buildDetailBreadcrumb(path, suffix = \"\") {\n if (path.length <= 1) {\n return suffix ? `← ${suffix}` : path[0] || \"\";\n }\n\n const breadcrumb = buildBreadcrumb(path);\n return suffix ? `${breadcrumb} ${suffix}` : breadcrumb;\n}\n","/**\n * Footer builder - composes footer messages from multiple sources\n */\n\n\n\n\n\n\n\n\n\n/**\n * Build footer lines from multiple message sources\n *\n * @param config - Footer configuration object\n * @returns Array of footer lines\n */\nexport function buildFooter(config = {}) {\n const {\n navigation = null,\n actions = null,\n info = null,\n escape = \"Esc to go back\",\n custom = null\n } = config;\n\n const lines = [];\n\n // Build main help line (navigation + actions + escape)\n const mainParts = [];\n\n if (navigation) {\n mainParts.push(navigation);\n }\n\n if (actions) {\n mainParts.push(actions);\n }\n\n if (escape) {\n mainParts.push(escape);\n }\n\n if (mainParts.length > 0) {\n lines.push(mainParts.join(\", \"));\n }\n\n // Add info line if present\n if (info) {\n const infoLines = Array.isArray(info) ? info : [info];\n lines.push(...infoLines);\n }\n\n // Add custom lines if present\n if (custom) {\n const customLines = Array.isArray(custom) ? custom : [custom];\n lines.push(...customLines);\n }\n\n return lines;\n}\n\n/**\n * Predefined footer configurations for common screen types\n */\nexport const FooterPresets = {\n /**\n * Menu screen footer\n */\n menu: (customInfo = null) => buildFooter({\n navigation: \"↑/↓ to navigate\",\n actions: \"Enter to select\",\n escape: \"Esc to go back\",\n info: customInfo\n }),\n\n /**\n * Word grid footer\n */\n wordGrid: (totalWords) => buildFooter({\n navigation: \"↑↓←→ to navigate\",\n actions: \"Enter to select\",\n escape: \"Esc to go back\",\n info: `Total: ${totalWords} words`\n }),\n\n /**\n * Text input footer\n */\n textInput: () => buildFooter({\n actions: \"Type and press Enter to submit\",\n escape: \"Esc to cancel\"\n }),\n\n /**\n * Info/static screen footer\n */\n info: () => buildFooter({\n escape: \"Esc to continue\"\n }),\n\n /**\n * Main menu footer (escape exits)\n */\n mainMenu: () => buildFooter({\n navigation: \"↑/↓ to navigate\",\n actions: \"Enter to select\",\n escape: \"Esc to exit\"\n }),\n\n /**\n * Action menu footer (for word cards, etc.)\n */\n actionMenu: (hasAudio = false) => {\n const parts = buildFooter({\n navigation: \"↑/↓ to navigate\",\n actions: \"Enter to select\",\n escape: \"Esc to go back\"\n });\n\n if (hasAudio) {\n parts.push(\"Audio available\");\n }\n\n return parts;\n }\n};\n\n/**\n * Combine multiple footer messages into organized lines\n * Smart grouping of related messages\n *\n * @param messages - Individual footer messages\n * @returns Organized footer lines\n */\nexport function organizeFooterMessages(messages) {\n if (!messages || messages.length === 0) {\n return [\"Esc to go back\"];\n }\n\n // Group similar messages\n const navigation = messages.filter(m => m.includes(\"↑\") || m.includes(\"↓\") || m.includes(\"←\") || m.includes(\"→\"));\n const actions = messages.filter(m => m.includes(\"Enter\") || m.includes(\"select\") || m.includes(\"submit\"));\n const escape = messages.filter(m => m.includes(\"Esc\"));\n const others = messages.filter(m =>\n !navigation.includes(m) &&\n !actions.includes(m) &&\n !escape.includes(m)\n );\n\n const lines = [];\n\n // Combine navigation, actions, and escape on one line\n const mainLine = [...navigation, ...actions, ...escape].join(\", \");\n if (mainLine) lines.push(mainLine);\n\n // Add other messages as separate lines\n lines.push(...others);\n\n return lines;\n}\n"],"mappings":"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","names":["React","useState","useEffect","useRef","useMemo","createElement","Box","Text","useInput","useState","h","Text","Box","Text","h","Box","Text","useState","h","Text","h","Box","Text","useState","useEffect","useRef","createElement","Box","Text","h","createElement","useState","useEffect","useRef","Text","Box"]}
|