cli-menu-kit 0.1.26 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/dist/api.d.ts +23 -5
  2. package/dist/api.js +16 -4
  3. package/dist/component-factories.d.ts +59 -0
  4. package/dist/component-factories.js +141 -0
  5. package/dist/components/display/header-v2.d.ts +13 -0
  6. package/dist/components/display/header-v2.js +43 -0
  7. package/dist/components/display/header.d.ts +40 -0
  8. package/dist/components/display/header.js +331 -18
  9. package/dist/components/display/headers.d.ts +1 -0
  10. package/dist/components/display/headers.js +15 -5
  11. package/dist/components/display/hints-v2.d.ts +10 -0
  12. package/dist/components/display/hints-v2.js +34 -0
  13. package/dist/components/display/hints.d.ts +56 -0
  14. package/dist/components/display/hints.js +81 -0
  15. package/dist/components/display/index.d.ts +4 -1
  16. package/dist/components/display/index.js +17 -1
  17. package/dist/components/display/input-prompt.d.ts +35 -0
  18. package/dist/components/display/input-prompt.js +36 -0
  19. package/dist/components/display/list.d.ts +49 -0
  20. package/dist/components/display/list.js +86 -0
  21. package/dist/components/display/messages.js +5 -5
  22. package/dist/components/display/progress.d.ts +17 -0
  23. package/dist/components/display/progress.js +18 -0
  24. package/dist/components/display/summary.js +72 -10
  25. package/dist/components/display/table.d.ts +44 -0
  26. package/dist/components/display/table.js +108 -0
  27. package/dist/components/inputs/language-input.js +8 -5
  28. package/dist/components/inputs/number-input.js +19 -14
  29. package/dist/components/inputs/text-input.js +50 -13
  30. package/dist/components/menus/boolean-menu.js +34 -20
  31. package/dist/components/menus/checkbox-menu.d.ts +2 -1
  32. package/dist/components/menus/checkbox-menu.js +35 -61
  33. package/dist/components/menus/checkbox-table-menu.d.ts +12 -0
  34. package/dist/components/menus/checkbox-table-menu.js +398 -0
  35. package/dist/components/menus/index.d.ts +1 -0
  36. package/dist/components/menus/index.js +3 -1
  37. package/dist/components/menus/radio-menu-split.d.ts +34 -0
  38. package/dist/components/menus/radio-menu-split.js +258 -0
  39. package/dist/components/menus/radio-menu-v2.d.ts +11 -0
  40. package/dist/components/menus/radio-menu-v2.js +150 -0
  41. package/dist/components/menus/radio-menu.d.ts +2 -1
  42. package/dist/components/menus/radio-menu.js +100 -134
  43. package/dist/components.js +3 -3
  44. package/dist/config/index.d.ts +5 -0
  45. package/dist/config/index.js +21 -0
  46. package/dist/config/language-config.d.ts +73 -0
  47. package/dist/config/language-config.js +157 -0
  48. package/dist/config/user-config.d.ts +83 -0
  49. package/dist/config/user-config.js +185 -0
  50. package/dist/core/colors.d.ts +24 -18
  51. package/dist/core/colors.js +74 -7
  52. package/dist/core/hint-manager.d.ts +29 -0
  53. package/dist/core/hint-manager.js +65 -0
  54. package/dist/core/renderer.d.ts +2 -1
  55. package/dist/core/renderer.js +46 -22
  56. package/dist/core/screen-manager.d.ts +54 -0
  57. package/dist/core/screen-manager.js +119 -0
  58. package/dist/core/state-manager.d.ts +27 -0
  59. package/dist/core/state-manager.js +56 -0
  60. package/dist/core/terminal.d.ts +17 -1
  61. package/dist/core/terminal.js +124 -4
  62. package/dist/core/virtual-scroll.d.ts +65 -0
  63. package/dist/core/virtual-scroll.js +120 -0
  64. package/dist/features/commands.js +23 -22
  65. package/dist/i18n/languages/en.js +4 -1
  66. package/dist/i18n/languages/zh.js +4 -1
  67. package/dist/i18n/registry.d.ts +4 -3
  68. package/dist/i18n/registry.js +12 -4
  69. package/dist/i18n/types.d.ts +3 -0
  70. package/dist/index.d.ts +7 -4
  71. package/dist/index.js +49 -4
  72. package/dist/layout.d.ts +67 -0
  73. package/dist/layout.js +86 -0
  74. package/dist/page-layout.d.ts +123 -0
  75. package/dist/page-layout.js +195 -0
  76. package/dist/types/input.types.d.ts +8 -0
  77. package/dist/types/menu.types.d.ts +61 -5
  78. package/package.json +4 -1
@@ -14,40 +14,41 @@ exports.getAvailableCommands = getAvailableCommands;
14
14
  exports.showCommandHelp = showCommandHelp;
15
15
  const terminal_js_1 = require("../core/terminal.js");
16
16
  const colors_js_1 = require("../core/colors.js");
17
+ const registry_js_1 = require("../i18n/registry.js");
17
18
  /**
18
19
  * Default command registry
19
20
  */
20
21
  const defaultCommands = {
21
22
  quit: {
22
23
  handler: () => {
23
- (0, terminal_js_1.writeLine)('\n👋 再见!');
24
+ (0, terminal_js_1.writeLine)(`\n${(0, registry_js_1.t)('messages.goodbye')}`);
24
25
  process.exit(0);
25
26
  },
26
- description: '退出应用程序'
27
+ descriptionKey: 'commands.quit'
27
28
  },
28
29
  help: {
29
30
  handler: () => {
30
- (0, terminal_js_1.writeLine)('\n可用命令:');
31
- Object.entries(defaultCommands).forEach(([cmd, { description }]) => {
32
- (0, terminal_js_1.writeLine)(` ${colors_js_1.colors.cyan}/${cmd}${colors_js_1.colors.reset} - ${description}`);
31
+ (0, terminal_js_1.writeLine)(`\n${(0, registry_js_1.t)('commands.availableCommands')}:`);
32
+ Object.entries(defaultCommands).forEach(([cmd, { descriptionKey }]) => {
33
+ (0, terminal_js_1.writeLine)(` ${colors_js_1.uiColors.primary}/${cmd}${colors_js_1.colors.reset} - ${(0, registry_js_1.t)(descriptionKey)}`);
33
34
  });
34
35
  (0, terminal_js_1.writeLine)('');
35
36
  return false; // Don't exit, continue
36
37
  },
37
- description: '显示帮助信息'
38
+ descriptionKey: 'commands.help'
38
39
  },
39
40
  clear: {
40
41
  handler: () => {
41
42
  (0, terminal_js_1.clearScreen)();
42
43
  return false; // Don't exit, continue
43
44
  },
44
- description: '清除屏幕'
45
+ descriptionKey: 'commands.clear'
45
46
  },
46
47
  back: {
47
48
  handler: () => {
48
49
  return true; // Signal to go back
49
50
  },
50
- description: '返回上一级菜单'
51
+ descriptionKey: 'commands.back'
51
52
  }
52
53
  };
53
54
  /**
@@ -61,7 +62,7 @@ let customCommands = {};
61
62
  * @param description - Command description
62
63
  */
63
64
  function registerCommand(command, handler, description) {
64
- customCommands[command.toLowerCase()] = { handler, description };
65
+ customCommands[command.toLowerCase()] = { handler, descriptionKey: description };
65
66
  }
66
67
  /**
67
68
  * Unregister a custom command
@@ -120,8 +121,8 @@ function handleCommand(input) {
120
121
  return result === undefined ? false : result;
121
122
  }
122
123
  // Unknown command
123
- (0, terminal_js_1.writeLine)(`${colors_js_1.colors.red}✗ 未知命令: /${command}${colors_js_1.colors.reset}`);
124
- (0, terminal_js_1.writeLine)(`${colors_js_1.colors.dim}输入 /help 查看可用命令${colors_js_1.colors.reset}\n`);
124
+ (0, terminal_js_1.writeLine)(`${colors_js_1.uiColors.error}✗ ${(0, registry_js_1.t)('messages.unknownCommand')}: /${command}${colors_js_1.colors.reset}`);
125
+ (0, terminal_js_1.writeLine)(`${colors_js_1.uiColors.textSecondary}${(0, registry_js_1.t)('messages.helpPrompt')}${colors_js_1.colors.reset}\n`);
125
126
  return false;
126
127
  }
127
128
  /**
@@ -131,12 +132,12 @@ function handleCommand(input) {
131
132
  function getAvailableCommands() {
132
133
  const commands = [];
133
134
  // Add default commands
134
- Object.entries(defaultCommands).forEach(([cmd, { description }]) => {
135
- commands.push({ command: cmd, description });
135
+ Object.entries(defaultCommands).forEach(([cmd, { descriptionKey }]) => {
136
+ commands.push({ command: cmd, description: (0, registry_js_1.t)(descriptionKey) });
136
137
  });
137
138
  // Add custom commands
138
- Object.entries(customCommands).forEach(([cmd, { description }]) => {
139
- commands.push({ command: cmd, description });
139
+ Object.entries(customCommands).forEach(([cmd, { descriptionKey }]) => {
140
+ commands.push({ command: cmd, description: descriptionKey });
140
141
  });
141
142
  return commands;
142
143
  }
@@ -144,17 +145,17 @@ function getAvailableCommands() {
144
145
  * Show help for all commands
145
146
  */
146
147
  function showCommandHelp() {
147
- (0, terminal_js_1.writeLine)('\n可用命令:');
148
+ (0, terminal_js_1.writeLine)(`\n${(0, registry_js_1.t)('commands.availableCommands')}:`);
148
149
  // Show default commands
149
- (0, terminal_js_1.writeLine)(`\n${colors_js_1.colors.cyan}默认命令:${colors_js_1.colors.reset}`);
150
- Object.entries(defaultCommands).forEach(([cmd, { description }]) => {
151
- (0, terminal_js_1.writeLine)(` ${colors_js_1.colors.cyan}/${cmd}${colors_js_1.colors.reset} - ${description}`);
150
+ (0, terminal_js_1.writeLine)(`\n${colors_js_1.uiColors.primary}${(0, registry_js_1.t)('commands.defaultCommands')}:${colors_js_1.colors.reset}`);
151
+ Object.entries(defaultCommands).forEach(([cmd, { descriptionKey }]) => {
152
+ (0, terminal_js_1.writeLine)(` ${colors_js_1.uiColors.primary}/${cmd}${colors_js_1.colors.reset} - ${(0, registry_js_1.t)(descriptionKey)}`);
152
153
  });
153
154
  // Show custom commands if any
154
155
  if (Object.keys(customCommands).length > 0) {
155
- (0, terminal_js_1.writeLine)(`\n${colors_js_1.colors.cyan}自定义命令:${colors_js_1.colors.reset}`);
156
- Object.entries(customCommands).forEach(([cmd, { description }]) => {
157
- (0, terminal_js_1.writeLine)(` ${colors_js_1.colors.cyan}/${cmd}${colors_js_1.colors.reset} - ${description}`);
156
+ (0, terminal_js_1.writeLine)(`\n${colors_js_1.uiColors.primary}${(0, registry_js_1.t)('commands.customCommands')}:${colors_js_1.colors.reset}`);
157
+ Object.entries(customCommands).forEach(([cmd, { descriptionKey }]) => {
158
+ (0, terminal_js_1.writeLine)(` ${colors_js_1.uiColors.primary}/${cmd}${colors_js_1.colors.reset} - ${descriptionKey}`);
158
159
  });
159
160
  }
160
161
  (0, terminal_js_1.writeLine)('');
@@ -9,7 +9,10 @@ exports.en = {
9
9
  selectPrompt: 'Enter option or use ↑↓ to select, press Enter to confirm',
10
10
  multiSelectPrompt: 'Space to toggle, Enter to confirm',
11
11
  confirmPrompt: 'Press Enter to confirm',
12
- selectedCount: 'selected'
12
+ selectedCount: 'selected',
13
+ yes: 'Yes',
14
+ no: 'No',
15
+ scrollIndicator: 'Item {current}/{total} | ↑↓ Scroll for more'
13
16
  },
14
17
  hints: {
15
18
  arrows: '↑↓ Arrow keys',
@@ -9,7 +9,10 @@ exports.zh = {
9
9
  selectPrompt: '输入选项或用↑↓选择,回车确认',
10
10
  multiSelectPrompt: '空格选中/取消,回车确认',
11
11
  confirmPrompt: '回车确认',
12
- selectedCount: '项已选'
12
+ selectedCount: '项已选',
13
+ yes: '是',
14
+ no: '否',
15
+ scrollIndicator: '第 {current}/{total} 项 | ↑↓ 滚动查看更多'
13
16
  },
14
17
  hints: {
15
18
  arrows: '↑↓ 方向键',
@@ -13,11 +13,12 @@ export declare function getCurrentLanguage(): LanguageCode;
13
13
  */
14
14
  export declare function setLanguage(lang: LanguageCode): void;
15
15
  /**
16
- * Get translation for a key path
16
+ * Get translation for a key path with optional parameter substitution
17
17
  * @param keyPath - Dot-separated key path (e.g., 'menus.selectPrompt')
18
- * @returns Translated string
18
+ * @param params - Optional parameters for string interpolation (e.g., { current: '1', total: '10' })
19
+ * @returns Translated string with parameters substituted
19
20
  */
20
- export declare function t(keyPath: string): string;
21
+ export declare function t(keyPath: string, params?: Record<string, string>): string;
21
22
  /**
22
23
  * Register a new language
23
24
  * @param code - Language code
@@ -39,11 +39,12 @@ function setLanguage(lang) {
39
39
  registry.current = lang;
40
40
  }
41
41
  /**
42
- * Get translation for a key path
42
+ * Get translation for a key path with optional parameter substitution
43
43
  * @param keyPath - Dot-separated key path (e.g., 'menus.selectPrompt')
44
- * @returns Translated string
44
+ * @param params - Optional parameters for string interpolation (e.g., { current: '1', total: '10' })
45
+ * @returns Translated string with parameters substituted
45
46
  */
46
- function t(keyPath) {
47
+ function t(keyPath, params) {
47
48
  const keys = keyPath.split('.');
48
49
  const langMap = registry.languages[registry.current];
49
50
  let value = langMap;
@@ -56,7 +57,14 @@ function t(keyPath) {
56
57
  return keyPath; // Return key path as fallback
57
58
  }
58
59
  }
59
- return typeof value === 'string' ? value : keyPath;
60
+ let result = typeof value === 'string' ? value : keyPath;
61
+ // Substitute parameters if provided
62
+ if (params) {
63
+ for (const [key, val] of Object.entries(params)) {
64
+ result = result.replace(new RegExp(`\\{${key}\\}`, 'g'), val);
65
+ }
66
+ }
67
+ return result;
60
68
  }
61
69
  /**
62
70
  * Register a new language
@@ -14,6 +14,9 @@ export interface LanguageMap {
14
14
  multiSelectPrompt: string;
15
15
  confirmPrompt: string;
16
16
  selectedCount: string;
17
+ yes: string;
18
+ no: string;
19
+ scrollIndicator: string;
17
20
  };
18
21
  hints: {
19
22
  arrows: string;
package/dist/index.d.ts CHANGED
@@ -4,20 +4,23 @@
4
4
  */
5
5
  export { menuAPI as menu, inputAPI as input, wizardAPI as wizard } from './api.js';
6
6
  export { default } from './api.js';
7
- export { showRadioMenu, showCheckboxMenu, showBooleanMenu } from './components/menus/index.js';
7
+ export { renderPage, type PageLayoutConfig, type HeaderConfig as PageHeaderConfig, type MainAreaConfig, type FooterConfig } from './page-layout.js';
8
+ export { createFullHeaderComponent, createSimpleHeaderComponent, createSectionHeaderComponent, createHintsComponent, createTableComponent, createListComponent, createSummaryTableComponent, createRadioMenuComponent, createInputPromptComponent } from './component-factories.js';
9
+ export { showRadioMenu, showCheckboxMenu, showCheckboxTableMenu, showBooleanMenu } from './components/menus/index.js';
8
10
  export { showTextInput, showNumberInput, showLanguageSelector, showModifyField } from './components/inputs/index.js';
9
- export { renderSimpleHeader, renderSectionHeader, renderAsciiHeader, createSimpleHeader, createSectionHeader, createAsciiHeader, renderProgressIndicator, renderStageHeader, renderStageSeparator, createProgressIndicator, createStageHeader, createStageSeparator, renderMessage, showSuccess, showError, showWarning, showInfo, showQuestion, createMessage, renderSummaryTable, createSummaryTable, createSimpleSummary, renderHeader, type HeaderConfig } from './components/display/index.js';
11
+ export { renderSimpleHeader, renderSectionHeader, renderAsciiHeader, createSimpleHeader, createSectionHeader, createAsciiHeader, renderProgressIndicator, renderStageHeader, renderStageSeparator, createProgressIndicator, createStageHeader, createStageSeparator, renderProgressCheckmark, createProgressCheckmark, renderMessage, showSuccess, showError, showWarning, showInfo, showQuestion, createMessage, renderSummaryTable, createSummaryTable, createSimpleSummary, renderHeader, type HeaderConfig, renderHintsComponent, createHints, generateMenuHints, generateInputHints, HintTypes, type HintsConfig, renderTable, createTable, type TableConfig, type TableColumn, renderList, createList, createBulletList, createNumberedList, type ListConfig, type ListItem } from './components/display/index.js';
10
12
  export { runWizard, createWizard, WizardConfig, WizardStep, WizardResult } from './features/wizard.js';
11
13
  export { registerCommand, unregisterCommand, clearCustomCommands, isCommand, parseCommand, handleCommand, getAvailableCommands, showCommandHelp } from './features/commands.js';
12
14
  export { getCurrentLanguage, setLanguage, t, registerLanguage, getAvailableLanguages, getCurrentLanguageMap } from './i18n/registry.js';
15
+ export { initConfig, getConfigManager, loadConfig, saveConfig, getConfig, setConfig, resetConfig, type UserConfig, type ConfigOptions } from './config/user-config.js';
16
+ export { initLanguages, loadLanguagesFromFile, getLanguageManager, getSupportedLanguages, getLanguageConfig, getDefaultLanguage, getCLILanguageCode, type LanguageConfig, type LanguagesConfig } from './config/language-config.js';
13
17
  export { colors, uiColors, defaultUIColors, getUIColors, setUIColors, resetUIColors, createGradient, applyGradient, colorize } from './core/colors.js';
14
- export type { MenuLayout, LayoutElement, LayoutVisibility, LayoutSpacing } from './types/layout.types.js';
15
18
  export type { MenuOption, BaseMenuConfig, RadioMenuConfig, CheckboxMenuConfig, BooleanMenuConfig, RadioMenuResult, CheckboxMenuResult, BooleanMenuResult } from './types/menu.types.js';
16
19
  export type { BaseInputConfig, TextInputConfig, NumberInputConfig, LanguageSelectorConfig, ModifyFieldConfig, TextInputResult, NumberInputResult, LanguageSelectorResult, ModifyFieldResult } from './types/input.types.js';
17
20
  export type { HeaderType, SimpleHeaderConfig, AsciiHeaderConfig, ProgressConfig, MessageType, MessageConfig, SummaryTableConfig } from './types/display.types.js';
18
21
  export type { LanguageCode, LanguageMap, I18nRegistry } from './i18n/types.js';
19
22
  export { KEY_CODES } from './core/keyboard.js';
20
- export { LAYOUT_PRESETS } from './types/layout.types.js';
23
+ export { calculateVirtualScroll, type VirtualScrollOptions, type VirtualScrollResult } from './core/virtual-scroll.js';
21
24
  export * from './types';
22
25
  export * from './components';
23
26
  export * from './menu-core';
package/dist/index.js CHANGED
@@ -21,8 +21,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
21
21
  return (mod && mod.__esModule) ? mod : { "default": mod };
22
22
  };
23
23
  Object.defineProperty(exports, "__esModule", { value: true });
24
- exports.getCurrentLanguageMap = exports.getAvailableLanguages = exports.registerLanguage = exports.t = exports.setLanguage = exports.getCurrentLanguage = exports.showCommandHelp = exports.getAvailableCommands = exports.handleCommand = exports.parseCommand = exports.isCommand = exports.clearCustomCommands = exports.unregisterCommand = exports.registerCommand = exports.createWizard = exports.runWizard = exports.renderHeader = exports.createSimpleSummary = exports.createSummaryTable = exports.renderSummaryTable = exports.createMessage = exports.showQuestion = exports.showInfo = exports.showWarning = exports.showError = exports.showSuccess = exports.renderMessage = exports.createStageSeparator = exports.createStageHeader = exports.createProgressIndicator = exports.renderStageSeparator = exports.renderStageHeader = exports.renderProgressIndicator = exports.createAsciiHeader = exports.createSectionHeader = exports.createSimpleHeader = exports.renderAsciiHeader = exports.renderSectionHeader = exports.renderSimpleHeader = exports.showModifyField = exports.showLanguageSelector = exports.showNumberInput = exports.showTextInput = exports.showBooleanMenu = exports.showCheckboxMenu = exports.showRadioMenu = exports.default = exports.wizard = exports.input = exports.menu = void 0;
25
- exports.LAYOUT_PRESETS = exports.KEY_CODES = exports.colorize = exports.applyGradient = exports.createGradient = exports.resetUIColors = exports.setUIColors = exports.getUIColors = exports.defaultUIColors = exports.uiColors = exports.colors = void 0;
24
+ exports.generateMenuHints = exports.createHints = exports.renderHintsComponent = exports.renderHeader = exports.createSimpleSummary = exports.createSummaryTable = exports.renderSummaryTable = exports.createMessage = exports.showQuestion = exports.showInfo = exports.showWarning = exports.showError = exports.showSuccess = exports.renderMessage = exports.createProgressCheckmark = exports.renderProgressCheckmark = exports.createStageSeparator = exports.createStageHeader = exports.createProgressIndicator = exports.renderStageSeparator = exports.renderStageHeader = exports.renderProgressIndicator = exports.createAsciiHeader = exports.createSectionHeader = exports.createSimpleHeader = exports.renderAsciiHeader = exports.renderSectionHeader = exports.renderSimpleHeader = exports.showModifyField = exports.showLanguageSelector = exports.showNumberInput = exports.showTextInput = exports.showBooleanMenu = exports.showCheckboxTableMenu = exports.showCheckboxMenu = exports.showRadioMenu = exports.createInputPromptComponent = exports.createRadioMenuComponent = exports.createSummaryTableComponent = exports.createListComponent = exports.createTableComponent = exports.createHintsComponent = exports.createSectionHeaderComponent = exports.createSimpleHeaderComponent = exports.createFullHeaderComponent = exports.renderPage = exports.default = exports.wizard = exports.input = exports.menu = void 0;
25
+ exports.calculateVirtualScroll = exports.KEY_CODES = exports.colorize = exports.applyGradient = exports.createGradient = exports.resetUIColors = exports.setUIColors = exports.getUIColors = exports.defaultUIColors = exports.uiColors = exports.colors = exports.getCLILanguageCode = exports.getDefaultLanguage = exports.getLanguageConfig = exports.getSupportedLanguages = exports.getLanguageManager = exports.loadLanguagesFromFile = exports.initLanguages = exports.resetConfig = exports.setConfig = exports.getConfig = exports.saveConfig = exports.loadConfig = exports.getConfigManager = exports.initConfig = exports.getCurrentLanguageMap = exports.getAvailableLanguages = exports.registerLanguage = exports.t = exports.setLanguage = exports.getCurrentLanguage = exports.showCommandHelp = exports.getAvailableCommands = exports.handleCommand = exports.parseCommand = exports.isCommand = exports.clearCustomCommands = exports.unregisterCommand = exports.registerCommand = exports.createWizard = exports.runWizard = exports.createNumberedList = exports.createBulletList = exports.createList = exports.renderList = exports.createTable = exports.renderTable = exports.HintTypes = exports.generateInputHints = void 0;
26
26
  // Export unified API
27
27
  var api_js_1 = require("./api.js");
28
28
  Object.defineProperty(exports, "menu", { enumerable: true, get: function () { return api_js_1.menuAPI; } });
@@ -30,10 +30,25 @@ Object.defineProperty(exports, "input", { enumerable: true, get: function () { r
30
30
  Object.defineProperty(exports, "wizard", { enumerable: true, get: function () { return api_js_1.wizardAPI; } });
31
31
  var api_js_2 = require("./api.js");
32
32
  Object.defineProperty(exports, "default", { enumerable: true, get: function () { return __importDefault(api_js_2).default; } });
33
+ // Export Page Layout (Simple Configuration API)
34
+ var page_layout_js_1 = require("./page-layout.js");
35
+ Object.defineProperty(exports, "renderPage", { enumerable: true, get: function () { return page_layout_js_1.renderPage; } });
36
+ // Export Component Factories (Legacy - for backward compatibility)
37
+ var component_factories_js_1 = require("./component-factories.js");
38
+ Object.defineProperty(exports, "createFullHeaderComponent", { enumerable: true, get: function () { return component_factories_js_1.createFullHeaderComponent; } });
39
+ Object.defineProperty(exports, "createSimpleHeaderComponent", { enumerable: true, get: function () { return component_factories_js_1.createSimpleHeaderComponent; } });
40
+ Object.defineProperty(exports, "createSectionHeaderComponent", { enumerable: true, get: function () { return component_factories_js_1.createSectionHeaderComponent; } });
41
+ Object.defineProperty(exports, "createHintsComponent", { enumerable: true, get: function () { return component_factories_js_1.createHintsComponent; } });
42
+ Object.defineProperty(exports, "createTableComponent", { enumerable: true, get: function () { return component_factories_js_1.createTableComponent; } });
43
+ Object.defineProperty(exports, "createListComponent", { enumerable: true, get: function () { return component_factories_js_1.createListComponent; } });
44
+ Object.defineProperty(exports, "createSummaryTableComponent", { enumerable: true, get: function () { return component_factories_js_1.createSummaryTableComponent; } });
45
+ Object.defineProperty(exports, "createRadioMenuComponent", { enumerable: true, get: function () { return component_factories_js_1.createRadioMenuComponent; } });
46
+ Object.defineProperty(exports, "createInputPromptComponent", { enumerable: true, get: function () { return component_factories_js_1.createInputPromptComponent; } });
33
47
  // Export menu components
34
48
  var index_js_1 = require("./components/menus/index.js");
35
49
  Object.defineProperty(exports, "showRadioMenu", { enumerable: true, get: function () { return index_js_1.showRadioMenu; } });
36
50
  Object.defineProperty(exports, "showCheckboxMenu", { enumerable: true, get: function () { return index_js_1.showCheckboxMenu; } });
51
+ Object.defineProperty(exports, "showCheckboxTableMenu", { enumerable: true, get: function () { return index_js_1.showCheckboxTableMenu; } });
37
52
  Object.defineProperty(exports, "showBooleanMenu", { enumerable: true, get: function () { return index_js_1.showBooleanMenu; } });
38
53
  // Export input components
39
54
  var index_js_2 = require("./components/inputs/index.js");
@@ -55,6 +70,8 @@ Object.defineProperty(exports, "renderStageSeparator", { enumerable: true, get:
55
70
  Object.defineProperty(exports, "createProgressIndicator", { enumerable: true, get: function () { return index_js_3.createProgressIndicator; } });
56
71
  Object.defineProperty(exports, "createStageHeader", { enumerable: true, get: function () { return index_js_3.createStageHeader; } });
57
72
  Object.defineProperty(exports, "createStageSeparator", { enumerable: true, get: function () { return index_js_3.createStageSeparator; } });
73
+ Object.defineProperty(exports, "renderProgressCheckmark", { enumerable: true, get: function () { return index_js_3.renderProgressCheckmark; } });
74
+ Object.defineProperty(exports, "createProgressCheckmark", { enumerable: true, get: function () { return index_js_3.createProgressCheckmark; } });
58
75
  Object.defineProperty(exports, "renderMessage", { enumerable: true, get: function () { return index_js_3.renderMessage; } });
59
76
  Object.defineProperty(exports, "showSuccess", { enumerable: true, get: function () { return index_js_3.showSuccess; } });
60
77
  Object.defineProperty(exports, "showError", { enumerable: true, get: function () { return index_js_3.showError; } });
@@ -66,6 +83,17 @@ Object.defineProperty(exports, "renderSummaryTable", { enumerable: true, get: fu
66
83
  Object.defineProperty(exports, "createSummaryTable", { enumerable: true, get: function () { return index_js_3.createSummaryTable; } });
67
84
  Object.defineProperty(exports, "createSimpleSummary", { enumerable: true, get: function () { return index_js_3.createSimpleSummary; } });
68
85
  Object.defineProperty(exports, "renderHeader", { enumerable: true, get: function () { return index_js_3.renderHeader; } });
86
+ Object.defineProperty(exports, "renderHintsComponent", { enumerable: true, get: function () { return index_js_3.renderHintsComponent; } });
87
+ Object.defineProperty(exports, "createHints", { enumerable: true, get: function () { return index_js_3.createHints; } });
88
+ Object.defineProperty(exports, "generateMenuHints", { enumerable: true, get: function () { return index_js_3.generateMenuHints; } });
89
+ Object.defineProperty(exports, "generateInputHints", { enumerable: true, get: function () { return index_js_3.generateInputHints; } });
90
+ Object.defineProperty(exports, "HintTypes", { enumerable: true, get: function () { return index_js_3.HintTypes; } });
91
+ Object.defineProperty(exports, "renderTable", { enumerable: true, get: function () { return index_js_3.renderTable; } });
92
+ Object.defineProperty(exports, "createTable", { enumerable: true, get: function () { return index_js_3.createTable; } });
93
+ Object.defineProperty(exports, "renderList", { enumerable: true, get: function () { return index_js_3.renderList; } });
94
+ Object.defineProperty(exports, "createList", { enumerable: true, get: function () { return index_js_3.createList; } });
95
+ Object.defineProperty(exports, "createBulletList", { enumerable: true, get: function () { return index_js_3.createBulletList; } });
96
+ Object.defineProperty(exports, "createNumberedList", { enumerable: true, get: function () { return index_js_3.createNumberedList; } });
69
97
  // Export features
70
98
  var wizard_js_1 = require("./features/wizard.js");
71
99
  Object.defineProperty(exports, "runWizard", { enumerable: true, get: function () { return wizard_js_1.runWizard; } });
@@ -87,6 +115,23 @@ Object.defineProperty(exports, "t", { enumerable: true, get: function () { retur
87
115
  Object.defineProperty(exports, "registerLanguage", { enumerable: true, get: function () { return registry_js_1.registerLanguage; } });
88
116
  Object.defineProperty(exports, "getAvailableLanguages", { enumerable: true, get: function () { return registry_js_1.getAvailableLanguages; } });
89
117
  Object.defineProperty(exports, "getCurrentLanguageMap", { enumerable: true, get: function () { return registry_js_1.getCurrentLanguageMap; } });
118
+ // Export configuration system
119
+ var user_config_js_1 = require("./config/user-config.js");
120
+ Object.defineProperty(exports, "initConfig", { enumerable: true, get: function () { return user_config_js_1.initConfig; } });
121
+ Object.defineProperty(exports, "getConfigManager", { enumerable: true, get: function () { return user_config_js_1.getConfigManager; } });
122
+ Object.defineProperty(exports, "loadConfig", { enumerable: true, get: function () { return user_config_js_1.loadConfig; } });
123
+ Object.defineProperty(exports, "saveConfig", { enumerable: true, get: function () { return user_config_js_1.saveConfig; } });
124
+ Object.defineProperty(exports, "getConfig", { enumerable: true, get: function () { return user_config_js_1.getConfig; } });
125
+ Object.defineProperty(exports, "setConfig", { enumerable: true, get: function () { return user_config_js_1.setConfig; } });
126
+ Object.defineProperty(exports, "resetConfig", { enumerable: true, get: function () { return user_config_js_1.resetConfig; } });
127
+ var language_config_js_1 = require("./config/language-config.js");
128
+ Object.defineProperty(exports, "initLanguages", { enumerable: true, get: function () { return language_config_js_1.initLanguages; } });
129
+ Object.defineProperty(exports, "loadLanguagesFromFile", { enumerable: true, get: function () { return language_config_js_1.loadLanguagesFromFile; } });
130
+ Object.defineProperty(exports, "getLanguageManager", { enumerable: true, get: function () { return language_config_js_1.getLanguageManager; } });
131
+ Object.defineProperty(exports, "getSupportedLanguages", { enumerable: true, get: function () { return language_config_js_1.getSupportedLanguages; } });
132
+ Object.defineProperty(exports, "getLanguageConfig", { enumerable: true, get: function () { return language_config_js_1.getLanguageConfig; } });
133
+ Object.defineProperty(exports, "getDefaultLanguage", { enumerable: true, get: function () { return language_config_js_1.getDefaultLanguage; } });
134
+ Object.defineProperty(exports, "getCLILanguageCode", { enumerable: true, get: function () { return language_config_js_1.getCLILanguageCode; } });
90
135
  // Export color configuration
91
136
  var colors_js_1 = require("./core/colors.js");
92
137
  Object.defineProperty(exports, "colors", { enumerable: true, get: function () { return colors_js_1.colors; } });
@@ -101,8 +146,8 @@ Object.defineProperty(exports, "colorize", { enumerable: true, get: function ()
101
146
  // Export core utilities (for advanced users)
102
147
  var keyboard_js_1 = require("./core/keyboard.js");
103
148
  Object.defineProperty(exports, "KEY_CODES", { enumerable: true, get: function () { return keyboard_js_1.KEY_CODES; } });
104
- var layout_types_js_1 = require("./types/layout.types.js");
105
- Object.defineProperty(exports, "LAYOUT_PRESETS", { enumerable: true, get: function () { return layout_types_js_1.LAYOUT_PRESETS; } });
149
+ var virtual_scroll_js_1 = require("./core/virtual-scroll.js");
150
+ Object.defineProperty(exports, "calculateVirtualScroll", { enumerable: true, get: function () { return virtual_scroll_js_1.calculateVirtualScroll; } });
106
151
  // Legacy exports (for backward compatibility)
107
152
  __exportStar(require("./types"), exports);
108
153
  __exportStar(require("./components"), exports);
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Page Layout System
3
+ * 通用页面布局:Header + Main Area + Footer
4
+ */
5
+ /**
6
+ * Header 配置
7
+ */
8
+ export interface HeaderConfig {
9
+ type: 'simple' | 'section' | 'none';
10
+ text?: string;
11
+ width?: number;
12
+ }
13
+ /**
14
+ * Main Area 配置
15
+ */
16
+ export interface MainAreaConfig {
17
+ type: 'menu' | 'display' | 'interactive';
18
+ render: () => void | Promise<void>;
19
+ }
20
+ /**
21
+ * Footer 配置
22
+ */
23
+ export interface FooterConfig {
24
+ menu?: {
25
+ options: string[];
26
+ allowLetterKeys?: boolean;
27
+ allowNumberKeys?: boolean;
28
+ };
29
+ input?: {
30
+ prompt: string;
31
+ defaultValue?: string;
32
+ allowEmpty?: boolean;
33
+ };
34
+ ask?: {
35
+ question: string;
36
+ defaultValue?: boolean;
37
+ horizontal?: boolean;
38
+ };
39
+ hints?: string[];
40
+ }
41
+ /**
42
+ * 完整页面布局配置
43
+ */
44
+ export interface PageLayoutConfig {
45
+ header?: HeaderConfig;
46
+ mainArea: MainAreaConfig;
47
+ footer?: FooterConfig;
48
+ }
49
+ /**
50
+ * 渲染完整页面
51
+ *
52
+ * @example
53
+ * ```typescript
54
+ * const result = await renderPage({
55
+ * header: { type: 'simple', text: 'My Page' },
56
+ * mainArea: {
57
+ * type: 'display',
58
+ * render: () => console.log('Content')
59
+ * },
60
+ * footer: {
61
+ * menu: { options: ['1. Save', 'b. Back'] },
62
+ * hints: ['↑↓ Navigate Enter Confirm']
63
+ * }
64
+ * });
65
+ * ```
66
+ */
67
+ export declare function renderPage(config: PageLayoutConfig): Promise<any>;
package/dist/layout.js ADDED
@@ -0,0 +1,86 @@
1
+ "use strict";
2
+ /**
3
+ * Page Layout System
4
+ * 通用页面布局:Header + Main Area + Footer
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.renderPage = renderPage;
8
+ const api_js_1 = require("./api.js");
9
+ const headers_js_1 = require("./components/display/headers.js");
10
+ /**
11
+ * 渲染 Header
12
+ */
13
+ function renderHeader(config) {
14
+ if (!config || config.type === 'none') {
15
+ return;
16
+ }
17
+ if (config.type === 'simple' && config.text) {
18
+ (0, headers_js_1.renderSimpleHeader)(config.text);
19
+ }
20
+ else if (config.type === 'section' && config.text) {
21
+ (0, headers_js_1.renderSectionHeader)(config.text, config.width || 50);
22
+ }
23
+ }
24
+ /**
25
+ * 渲染 Footer
26
+ * 返回用户的选择/输入结果
27
+ */
28
+ async function renderFooter(config) {
29
+ if (!config) {
30
+ return null;
31
+ }
32
+ let result = null;
33
+ // 1. Menu (如果有)
34
+ if (config.menu) {
35
+ result = await api_js_1.menuAPI.radio({
36
+ options: config.menu.options,
37
+ allowLetterKeys: config.menu.allowLetterKeys ?? true,
38
+ allowNumberKeys: config.menu.allowNumberKeys ?? true,
39
+ hints: config.hints,
40
+ preserveOnSelect: true
41
+ });
42
+ }
43
+ // 2. Input (如果有)
44
+ else if (config.input) {
45
+ result = await api_js_1.inputAPI.text({
46
+ prompt: config.input.prompt,
47
+ defaultValue: config.input.defaultValue,
48
+ allowEmpty: config.input.allowEmpty ?? false
49
+ });
50
+ }
51
+ // 3. Ask (如果有 - 通常在 Menu 或 Input 之后)
52
+ if (config.ask) {
53
+ const askResult = config.ask.horizontal
54
+ ? await api_js_1.menuAPI.booleanH(config.ask.question, config.ask.defaultValue ?? false)
55
+ : await api_js_1.menuAPI.booleanV(config.ask.question, config.ask.defaultValue ?? false);
56
+ return { ...result, confirmed: askResult };
57
+ }
58
+ return result;
59
+ }
60
+ /**
61
+ * 渲染完整页面
62
+ *
63
+ * @example
64
+ * ```typescript
65
+ * const result = await renderPage({
66
+ * header: { type: 'simple', text: 'My Page' },
67
+ * mainArea: {
68
+ * type: 'display',
69
+ * render: () => console.log('Content')
70
+ * },
71
+ * footer: {
72
+ * menu: { options: ['1. Save', 'b. Back'] },
73
+ * hints: ['↑↓ Navigate Enter Confirm']
74
+ * }
75
+ * });
76
+ * ```
77
+ */
78
+ async function renderPage(config) {
79
+ // 1. Render Header
80
+ renderHeader(config.header);
81
+ // 2. Render Main Area
82
+ await config.mainArea.render();
83
+ // 3. Render Footer
84
+ const footerResult = await renderFooter(config.footer);
85
+ return footerResult;
86
+ }
@@ -0,0 +1,123 @@
1
+ /**
2
+ * Page Layout System - Simple Configuration API
3
+ * Architecture: Header + Main Area + Footer
4
+ *
5
+ * This is the simple, configuration-based API that users want.
6
+ * Just pass config objects, no need to create components manually.
7
+ */
8
+ /**
9
+ * Header configuration
10
+ */
11
+ export interface HeaderConfig {
12
+ type: 'simple' | 'section' | 'full' | 'none';
13
+ topBlankLines?: number;
14
+ text?: string;
15
+ width?: number;
16
+ asciiArt?: string[];
17
+ figletText?: string;
18
+ figletFont?: string;
19
+ figletSize?: 'small' | 'medium' | 'large';
20
+ figletScale?: number;
21
+ boxWidth?: number;
22
+ showBoxBorder?: boolean;
23
+ fillBox?: boolean;
24
+ fillBoxColor?: string;
25
+ fillBoxGradientStart?: string;
26
+ fillBoxGradientEnd?: string;
27
+ title?: string;
28
+ titleColor?: string;
29
+ titleGradientStart?: string;
30
+ titleGradientEnd?: string;
31
+ description?: string;
32
+ descriptionColor?: string;
33
+ descriptionGradientStart?: string;
34
+ descriptionGradientEnd?: string;
35
+ asciiArtColor?: string;
36
+ version?: string;
37
+ url?: string;
38
+ menuTitle?: string;
39
+ asciiArtGradientStart?: string;
40
+ asciiArtGradientEnd?: string;
41
+ }
42
+ /**
43
+ * Main Area configuration
44
+ */
45
+ export interface MainAreaConfig {
46
+ type: 'menu' | 'display' | 'interactive';
47
+ menu?: {
48
+ options: any[];
49
+ allowLetterKeys?: boolean;
50
+ allowNumberKeys?: boolean;
51
+ preserveOnSelect?: boolean;
52
+ preserveOnExit?: boolean;
53
+ onExit?: () => void;
54
+ };
55
+ render?: () => void | Promise<void>;
56
+ }
57
+ /**
58
+ * Footer configuration
59
+ */
60
+ export interface FooterConfig {
61
+ menu?: {
62
+ options: any[];
63
+ allowLetterKeys?: boolean;
64
+ allowNumberKeys?: boolean;
65
+ preserveOnSelect?: boolean;
66
+ preserveOnExit?: boolean;
67
+ onExit?: () => void;
68
+ };
69
+ ask?: {
70
+ question: string;
71
+ helperText?: string;
72
+ defaultValue?: boolean;
73
+ horizontal?: boolean;
74
+ preserveOnSelect?: boolean;
75
+ preserveOnExit?: boolean;
76
+ onExit?: () => void;
77
+ };
78
+ input?: {
79
+ prompt: string;
80
+ defaultValue?: string;
81
+ allowEmpty?: boolean;
82
+ lang?: 'zh' | 'en';
83
+ preserveOnExit?: boolean;
84
+ onExit?: () => void;
85
+ };
86
+ hints?: string[];
87
+ }
88
+ /**
89
+ * Complete page layout configuration
90
+ */
91
+ export interface PageLayoutConfig {
92
+ header?: HeaderConfig;
93
+ mainArea: MainAreaConfig;
94
+ footer?: FooterConfig;
95
+ }
96
+ /**
97
+ * Render complete page with simple configuration API
98
+ *
99
+ * @example
100
+ * ```typescript
101
+ * const result = await renderPage({
102
+ * header: {
103
+ * type: 'full',
104
+ * asciiArt: ['...'],
105
+ * title: 'My App',
106
+ * description: 'Description',
107
+ * version: '1.0.0'
108
+ * },
109
+ * mainArea: {
110
+ * type: 'menu',
111
+ * menu: {
112
+ * options: ['Option 1', 'Option 2'],
113
+ * allowLetterKeys: true,
114
+ * allowNumberKeys: true
115
+ * }
116
+ * },
117
+ * footer: {
118
+ * hints: ['↑↓ Navigate', 'Enter Confirm']
119
+ * }
120
+ * });
121
+ * ```
122
+ */
123
+ export declare function renderPage(config: PageLayoutConfig): Promise<any>;