cli-menu-kit 0.1.23 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) 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/hints-v2.d.ts +10 -0
  8. package/dist/components/display/hints-v2.js +34 -0
  9. package/dist/components/display/hints.d.ts +56 -0
  10. package/dist/components/display/hints.js +81 -0
  11. package/dist/components/display/index.d.ts +3 -0
  12. package/dist/components/display/index.js +15 -1
  13. package/dist/components/display/input-prompt.d.ts +35 -0
  14. package/dist/components/display/input-prompt.js +36 -0
  15. package/dist/components/display/list.d.ts +49 -0
  16. package/dist/components/display/list.js +86 -0
  17. package/dist/components/display/summary.js +119 -15
  18. package/dist/components/display/table.d.ts +42 -0
  19. package/dist/components/display/table.js +107 -0
  20. package/dist/components/menus/boolean-menu.js +2 -1
  21. package/dist/components/menus/checkbox-menu.d.ts +2 -1
  22. package/dist/components/menus/checkbox-menu.js +30 -59
  23. package/dist/components/menus/checkbox-table-menu.d.ts +12 -0
  24. package/dist/components/menus/checkbox-table-menu.js +395 -0
  25. package/dist/components/menus/index.d.ts +1 -0
  26. package/dist/components/menus/index.js +3 -1
  27. package/dist/components/menus/radio-menu-split.d.ts +33 -0
  28. package/dist/components/menus/radio-menu-split.js +248 -0
  29. package/dist/components/menus/radio-menu-v2.d.ts +11 -0
  30. package/dist/components/menus/radio-menu-v2.js +150 -0
  31. package/dist/components/menus/radio-menu.d.ts +2 -1
  32. package/dist/components/menus/radio-menu.js +60 -123
  33. package/dist/core/hint-manager.d.ts +29 -0
  34. package/dist/core/hint-manager.js +65 -0
  35. package/dist/core/renderer.d.ts +2 -1
  36. package/dist/core/renderer.js +22 -6
  37. package/dist/core/screen-manager.d.ts +54 -0
  38. package/dist/core/screen-manager.js +119 -0
  39. package/dist/core/state-manager.d.ts +27 -0
  40. package/dist/core/state-manager.js +56 -0
  41. package/dist/core/terminal.d.ts +4 -1
  42. package/dist/core/terminal.js +37 -4
  43. package/dist/core/virtual-scroll.d.ts +65 -0
  44. package/dist/core/virtual-scroll.js +120 -0
  45. package/dist/i18n/languages/en.js +4 -1
  46. package/dist/i18n/languages/zh.js +4 -1
  47. package/dist/i18n/registry.d.ts +4 -3
  48. package/dist/i18n/registry.js +12 -4
  49. package/dist/i18n/types.d.ts +3 -0
  50. package/dist/index.d.ts +5 -4
  51. package/dist/index.js +30 -4
  52. package/dist/layout.d.ts +68 -0
  53. package/dist/layout.js +134 -0
  54. package/dist/page-layout.d.ts +92 -0
  55. package/dist/page-layout.js +156 -0
  56. package/dist/types/display.types.d.ts +6 -0
  57. package/dist/types/menu.types.d.ts +57 -5
  58. package/package.json +1 -1
  59. package/dist/types/layout.types.d.ts +0 -56
  60. package/dist/types/layout.types.js +0 -36
@@ -0,0 +1,156 @@
1
+ "use strict";
2
+ /**
3
+ * Page Layout System - Simple Configuration API
4
+ * Architecture: Header + Main Area + Footer
5
+ *
6
+ * This is the simple, configuration-based API that users want.
7
+ * Just pass config objects, no need to create components manually.
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.renderPage = renderPage;
11
+ const api_js_1 = require("./api.js");
12
+ const header_js_1 = require("./components/display/header.js");
13
+ const headers_js_1 = require("./components/display/headers.js");
14
+ /**
15
+ * Render Header
16
+ */
17
+ function renderHeaderSection(config) {
18
+ if (!config || config.type === 'none') {
19
+ return;
20
+ }
21
+ if (config.type === 'simple' && config.text) {
22
+ (0, headers_js_1.renderSimpleHeader)(config.text);
23
+ }
24
+ else if (config.type === 'section' && config.text) {
25
+ // Add extra blank line before section header for spacing between menus
26
+ console.log('');
27
+ (0, headers_js_1.renderSectionHeader)(config.text, config.width || 50);
28
+ }
29
+ else if (config.type === 'full') {
30
+ // Render full header WITHOUT menuTitle
31
+ (0, header_js_1.renderHeader)({
32
+ asciiArt: config.asciiArt || [],
33
+ title: config.title || '',
34
+ description: config.description,
35
+ version: config.version,
36
+ url: config.url,
37
+ menuTitle: undefined // Don't render menuTitle in header
38
+ });
39
+ }
40
+ }
41
+ /**
42
+ * Render Menu Title (separate from header)
43
+ */
44
+ function renderMenuTitle(title) {
45
+ if (title) {
46
+ console.log('');
47
+ console.log(` ${title}`);
48
+ }
49
+ }
50
+ /**
51
+ * Render Main Area
52
+ */
53
+ async function renderMainArea(config, hints) {
54
+ if (config.type === 'menu' && config.menu) {
55
+ // Menu in main area - pass hints from footer
56
+ const result = await api_js_1.menuAPI.radio({
57
+ options: config.menu.options,
58
+ allowLetterKeys: config.menu.allowLetterKeys ?? true,
59
+ allowNumberKeys: config.menu.allowNumberKeys ?? true,
60
+ preserveOnSelect: config.menu.preserveOnSelect ?? true
61
+ }, hints); // Pass hints as second parameter
62
+ return result;
63
+ }
64
+ else if (config.render) {
65
+ // Custom render function
66
+ await config.render();
67
+ return null;
68
+ }
69
+ return null;
70
+ }
71
+ /**
72
+ * Render Footer
73
+ */
74
+ async function renderFooterSection(config, hints) {
75
+ if (!config) {
76
+ return null;
77
+ }
78
+ let result = null;
79
+ // 1. Menu (if present)
80
+ if (config.menu) {
81
+ result = await api_js_1.menuAPI.radio({
82
+ options: config.menu.options,
83
+ allowLetterKeys: config.menu.allowLetterKeys ?? true,
84
+ allowNumberKeys: config.menu.allowNumberKeys ?? true,
85
+ preserveOnSelect: config.menu.preserveOnSelect ?? true
86
+ }, hints || config.hints);
87
+ }
88
+ // 2. Input (if present)
89
+ else if (config.input) {
90
+ result = await api_js_1.inputAPI.text({
91
+ prompt: config.input.prompt,
92
+ defaultValue: config.input.defaultValue,
93
+ allowEmpty: config.input.allowEmpty ?? false
94
+ });
95
+ }
96
+ // 3. Ask (if present)
97
+ else if (config.ask) {
98
+ const askResult = config.ask.horizontal
99
+ ? await api_js_1.menuAPI.booleanH(config.ask.question, config.ask.defaultValue ?? false)
100
+ : await api_js_1.menuAPI.booleanV(config.ask.question, config.ask.defaultValue ?? false);
101
+ result = askResult;
102
+ }
103
+ return result;
104
+ }
105
+ /**
106
+ * Render complete page with simple configuration API
107
+ *
108
+ * @example
109
+ * ```typescript
110
+ * const result = await renderPage({
111
+ * header: {
112
+ * type: 'full',
113
+ * asciiArt: ['...'],
114
+ * title: 'My App',
115
+ * description: 'Description',
116
+ * version: '1.0.0'
117
+ * },
118
+ * mainArea: {
119
+ * type: 'menu',
120
+ * menu: {
121
+ * options: ['Option 1', 'Option 2'],
122
+ * allowLetterKeys: true,
123
+ * allowNumberKeys: true
124
+ * }
125
+ * },
126
+ * footer: {
127
+ * hints: ['↑↓ Navigate', 'Enter Confirm']
128
+ * }
129
+ * });
130
+ * ```
131
+ */
132
+ async function renderPage(config) {
133
+ // 1. Render Header (without menuTitle)
134
+ renderHeaderSection(config.header);
135
+ // 2. Render Menu Title (if provided)
136
+ renderMenuTitle(config.header?.menuTitle);
137
+ // 3. Determine where to render hints
138
+ let mainResult = null;
139
+ if (config.footer?.menu || config.footer?.ask || config.footer?.input) {
140
+ // Footer has interactive element - render main area first, then footer with hints
141
+ if (config.mainArea.type === 'menu' && config.mainArea.menu) {
142
+ mainResult = await renderMainArea(config.mainArea, undefined);
143
+ }
144
+ else if (config.mainArea.render) {
145
+ await config.mainArea.render();
146
+ }
147
+ // Render footer with hints
148
+ const footerResult = await renderFooterSection(config.footer, config.footer.hints);
149
+ return footerResult || mainResult;
150
+ }
151
+ else {
152
+ // Footer has no interactive element - render main area with hints from footer
153
+ mainResult = await renderMainArea(config.mainArea, config.footer?.hints);
154
+ return mainResult;
155
+ }
156
+ }
@@ -55,4 +55,10 @@ export interface SummaryTableConfig {
55
55
  }>;
56
56
  }>;
57
57
  width?: number;
58
+ colors?: {
59
+ title?: string;
60
+ sectionHeader?: string;
61
+ key?: string;
62
+ value?: string;
63
+ };
58
64
  }
@@ -1,7 +1,6 @@
1
1
  /**
2
2
  * Menu component types for CLI Menu Kit
3
3
  */
4
- import { MenuLayout } from './layout.types.js';
5
4
  /**
6
5
  * Menu option (can be string, object with label, or section header)
7
6
  */
@@ -20,10 +19,6 @@ export interface BaseMenuConfig {
20
19
  title?: string;
21
20
  /** Input prompt text */
22
21
  prompt?: string;
23
- /** Hint texts to display */
24
- hints?: string[];
25
- /** Layout configuration */
26
- layout?: MenuLayout;
27
22
  /** Color for highlighted items */
28
23
  highlightColor?: string;
29
24
  /** Goodbye message function */
@@ -90,3 +85,60 @@ export interface CheckboxMenuResult {
90
85
  values: string[];
91
86
  }
92
87
  export type BooleanMenuResult = boolean;
88
+ /**
89
+ * Checkbox table menu configuration
90
+ * Combines checkbox selection with table display
91
+ */
92
+ export interface CheckboxTableMenuConfig extends BaseMenuConfig {
93
+ /** Table columns definition */
94
+ columns: Array<{
95
+ header: string;
96
+ key: string;
97
+ width?: number;
98
+ align?: 'left' | 'center' | 'right';
99
+ }>;
100
+ /** Data rows (each row is an object with column keys) */
101
+ data: Record<string, any>[];
102
+ /** Optional: Key to use as unique identifier (default: index) */
103
+ idKey?: string;
104
+ /** Default selected row indices or IDs */
105
+ defaultSelected?: (number | string)[];
106
+ /** Minimum selections required */
107
+ minSelections?: number;
108
+ /** Maximum selections allowed */
109
+ maxSelections?: number;
110
+ /** Allow select all */
111
+ allowSelectAll?: boolean;
112
+ /** Allow invert selection */
113
+ allowInvert?: boolean;
114
+ /** Show table borders (default: false for checkbox menu style) */
115
+ showBorders?: boolean;
116
+ /** Show header separator (default: true) */
117
+ showHeaderSeparator?: boolean;
118
+ /** Phase/group separators (for grouping rows) */
119
+ separators?: Array<{
120
+ /** Insert before this row index */
121
+ beforeIndex: number;
122
+ /** Separator label */
123
+ label: string;
124
+ /** Optional description shown below the separator */
125
+ description?: string;
126
+ }>;
127
+ /** Separator label and description alignment (default: 'center') */
128
+ separatorAlign?: 'left' | 'center' | 'right';
129
+ /** Column width calculation mode */
130
+ widthMode?: 'auto' | 'fixed';
131
+ /** Checkbox column width (default: 4) */
132
+ checkboxWidth?: number;
133
+ }
134
+ /**
135
+ * Checkbox table menu result
136
+ */
137
+ export interface CheckboxTableMenuResult {
138
+ /** Selected row indices */
139
+ indices: number[];
140
+ /** Selected row data objects */
141
+ rows: Record<string, any>[];
142
+ /** Selected IDs (if idKey is provided) */
143
+ ids?: (string | number)[];
144
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cli-menu-kit",
3
- "version": "0.1.23",
3
+ "version": "0.2.0",
4
4
  "description": "A lightweight, customizable CLI menu system with keyboard shortcuts and real-time rendering",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -1,56 +0,0 @@
1
- /**
2
- * Layout system types for CLI Menu Kit
3
- * Defines how components are composed and rendered
4
- */
5
- /**
6
- * Layout element types that can be arranged
7
- */
8
- export type LayoutElement = 'header' | 'options' | 'input' | 'hints' | 'progress';
9
- /**
10
- * Visibility configuration for layout elements
11
- */
12
- export interface LayoutVisibility {
13
- header?: boolean;
14
- input?: boolean;
15
- hints?: boolean;
16
- progress?: boolean;
17
- }
18
- /**
19
- * Spacing configuration for layout elements
20
- * Values represent number of blank lines
21
- */
22
- export interface LayoutSpacing {
23
- beforeHeader?: number;
24
- afterHeader?: number;
25
- beforeOptions?: number;
26
- afterOptions?: number;
27
- beforeInput?: number;
28
- afterInput?: number;
29
- beforeHints?: number;
30
- beforeProgress?: number;
31
- afterProgress?: number;
32
- }
33
- /**
34
- * Complete menu layout configuration
35
- */
36
- export interface MenuLayout {
37
- /** Order in which elements are rendered */
38
- order: LayoutElement[];
39
- /** Which elements are visible */
40
- visible: LayoutVisibility;
41
- /** Spacing between elements */
42
- spacing?: LayoutSpacing;
43
- }
44
- /**
45
- * Preset layout configurations
46
- */
47
- export declare const LAYOUT_PRESETS: {
48
- /** Main menu with header */
49
- MAIN_MENU: MenuLayout;
50
- /** Sub menu without header */
51
- SUB_MENU: MenuLayout;
52
- /** Wizard step with progress indicator */
53
- WIZARD_STEP: MenuLayout;
54
- /** Minimal layout (options only) */
55
- MINIMAL: MenuLayout;
56
- };
@@ -1,36 +0,0 @@
1
- "use strict";
2
- /**
3
- * Layout system types for CLI Menu Kit
4
- * Defines how components are composed and rendered
5
- */
6
- Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.LAYOUT_PRESETS = void 0;
8
- /**
9
- * Preset layout configurations
10
- */
11
- exports.LAYOUT_PRESETS = {
12
- /** Main menu with header */
13
- MAIN_MENU: {
14
- order: ['header', 'options', 'input', 'hints'],
15
- visible: { header: true, input: true, hints: true },
16
- spacing: { afterHeader: 1, afterOptions: 1, beforeHints: 1 }
17
- },
18
- /** Sub menu without header */
19
- SUB_MENU: {
20
- order: ['options', 'input', 'hints'],
21
- visible: { header: false, input: true, hints: true },
22
- spacing: { afterOptions: 1, beforeHints: 1 }
23
- },
24
- /** Wizard step with progress indicator */
25
- WIZARD_STEP: {
26
- order: ['header', 'progress', 'options', 'input', 'hints'],
27
- visible: { header: true, progress: true, input: true, hints: true },
28
- spacing: { afterHeader: 1, afterProgress: 1, afterOptions: 1, beforeHints: 1 }
29
- },
30
- /** Minimal layout (options only) */
31
- MINIMAL: {
32
- order: ['options'],
33
- visible: { header: false, input: false, hints: false },
34
- spacing: {}
35
- }
36
- };