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
@@ -0,0 +1,185 @@
1
+ "use strict";
2
+ /**
3
+ * User Configuration System for CLI Menu Kit
4
+ * Provides persistent user preferences
5
+ */
6
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
7
+ if (k2 === undefined) k2 = k;
8
+ var desc = Object.getOwnPropertyDescriptor(m, k);
9
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
10
+ desc = { enumerable: true, get: function() { return m[k]; } };
11
+ }
12
+ Object.defineProperty(o, k2, desc);
13
+ }) : (function(o, m, k, k2) {
14
+ if (k2 === undefined) k2 = k;
15
+ o[k2] = m[k];
16
+ }));
17
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
18
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
19
+ }) : function(o, v) {
20
+ o["default"] = v;
21
+ });
22
+ var __importStar = (this && this.__importStar) || (function () {
23
+ var ownKeys = function(o) {
24
+ ownKeys = Object.getOwnPropertyNames || function (o) {
25
+ var ar = [];
26
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
27
+ return ar;
28
+ };
29
+ return ownKeys(o);
30
+ };
31
+ return function (mod) {
32
+ if (mod && mod.__esModule) return mod;
33
+ var result = {};
34
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
35
+ __setModuleDefault(result, mod);
36
+ return result;
37
+ };
38
+ })();
39
+ Object.defineProperty(exports, "__esModule", { value: true });
40
+ exports.initConfig = initConfig;
41
+ exports.getConfigManager = getConfigManager;
42
+ exports.loadConfig = loadConfig;
43
+ exports.saveConfig = saveConfig;
44
+ exports.getConfig = getConfig;
45
+ exports.setConfig = setConfig;
46
+ exports.resetConfig = resetConfig;
47
+ const fs = __importStar(require("fs"));
48
+ const path = __importStar(require("path"));
49
+ const os = __importStar(require("os"));
50
+ class ConfigManager {
51
+ constructor(options) {
52
+ this.appName = options.appName;
53
+ this.configFileName = options.configFileName || 'config.json';
54
+ this.defaults = options.defaults || {};
55
+ // Set config directory
56
+ this.configDir = path.join(os.homedir(), `.${this.appName}`);
57
+ this.configPath = path.join(this.configDir, this.configFileName);
58
+ // Ensure config directory exists
59
+ this.ensureConfigDir();
60
+ }
61
+ /**
62
+ * Ensure config directory exists
63
+ */
64
+ ensureConfigDir() {
65
+ if (!fs.existsSync(this.configDir)) {
66
+ fs.mkdirSync(this.configDir, { recursive: true });
67
+ }
68
+ }
69
+ /**
70
+ * Load configuration
71
+ */
72
+ load() {
73
+ if (!fs.existsSync(this.configPath)) {
74
+ return { ...this.defaults };
75
+ }
76
+ try {
77
+ const content = fs.readFileSync(this.configPath, 'utf8');
78
+ const config = JSON.parse(content);
79
+ return { ...this.defaults, ...config };
80
+ }
81
+ catch (error) {
82
+ console.error('Failed to load config:', error);
83
+ return { ...this.defaults };
84
+ }
85
+ }
86
+ /**
87
+ * Save configuration
88
+ */
89
+ save(config) {
90
+ const currentConfig = this.load();
91
+ const newConfig = {
92
+ ...currentConfig,
93
+ ...config,
94
+ updated_at: new Date().toISOString()
95
+ };
96
+ try {
97
+ fs.writeFileSync(this.configPath, JSON.stringify(newConfig, null, 2), 'utf8');
98
+ }
99
+ catch (error) {
100
+ console.error('Failed to save config:', error);
101
+ throw error;
102
+ }
103
+ }
104
+ /**
105
+ * Get a specific config value
106
+ */
107
+ get(key) {
108
+ const config = this.load();
109
+ return config[key];
110
+ }
111
+ /**
112
+ * Set a specific config value
113
+ */
114
+ set(key, value) {
115
+ this.save({ [key]: value });
116
+ }
117
+ /**
118
+ * Reset configuration to defaults
119
+ */
120
+ reset() {
121
+ if (fs.existsSync(this.configPath)) {
122
+ fs.unlinkSync(this.configPath);
123
+ }
124
+ }
125
+ /**
126
+ * Get config file path
127
+ */
128
+ getConfigPath() {
129
+ return this.configPath;
130
+ }
131
+ /**
132
+ * Get config directory path
133
+ */
134
+ getConfigDir() {
135
+ return this.configDir;
136
+ }
137
+ }
138
+ // Global config manager instance
139
+ let globalConfigManager = null;
140
+ /**
141
+ * Initialize config manager
142
+ */
143
+ function initConfig(options) {
144
+ globalConfigManager = new ConfigManager(options);
145
+ return globalConfigManager;
146
+ }
147
+ /**
148
+ * Get global config manager
149
+ */
150
+ function getConfigManager() {
151
+ if (!globalConfigManager) {
152
+ throw new Error('Config manager not initialized. Call initConfig() first.');
153
+ }
154
+ return globalConfigManager;
155
+ }
156
+ /**
157
+ * Load configuration
158
+ */
159
+ function loadConfig() {
160
+ return getConfigManager().load();
161
+ }
162
+ /**
163
+ * Save configuration
164
+ */
165
+ function saveConfig(config) {
166
+ getConfigManager().save(config);
167
+ }
168
+ /**
169
+ * Get config value
170
+ */
171
+ function getConfig(key) {
172
+ return getConfigManager().get(key);
173
+ }
174
+ /**
175
+ * Set config value
176
+ */
177
+ function setConfig(key, value) {
178
+ getConfigManager().set(key, value);
179
+ }
180
+ /**
181
+ * Reset configuration
182
+ */
183
+ function resetConfig() {
184
+ getConfigManager().reset();
185
+ }
@@ -44,19 +44,21 @@ export declare const colors: {
44
44
  * Defines consistent colors for different levels of information
45
45
  */
46
46
  export declare const defaultUIColors: {
47
- readonly primary: "\u001B[36m";
48
- readonly accent: "\u001B[34m";
47
+ readonly primary: "\u001B[0m";
48
+ readonly accent: "\u001B[0m";
49
49
  readonly textPrimary: "\u001B[0m";
50
50
  readonly textSecondary: "\u001B[2m";
51
51
  readonly textMuted: "\u001B[90m";
52
52
  readonly success: "\u001B[32m";
53
53
  readonly error: "\u001B[31m";
54
54
  readonly warning: "\u001B[33m";
55
- readonly info: "\u001B[34m";
56
- readonly cursor: "\u001B[36m";
57
- readonly selected: "\u001B[32m";
55
+ readonly info: "\u001B[0m";
56
+ readonly cursor: "\u001B[0m";
57
+ readonly selected: "\u001B[0m";
58
+ readonly highlightBg: "";
59
+ readonly highlightText: "\u001B[0m";
58
60
  readonly disabled: "\u001B[2m";
59
- readonly border: "\u001B[36m";
61
+ readonly border: "\u001B[90m";
60
62
  readonly separator: "\u001B[2m";
61
63
  readonly prefix: "\u001B[2m";
62
64
  };
@@ -64,19 +66,21 @@ export declare const defaultUIColors: {
64
66
  * Get current UI colors
65
67
  */
66
68
  export declare function getUIColors(): {
67
- primary: "\u001B[36m";
68
- accent: "\u001B[34m";
69
+ primary: "\u001B[0m";
70
+ accent: "\u001B[0m";
69
71
  textPrimary: "\u001B[0m";
70
72
  textSecondary: "\u001B[2m";
71
73
  textMuted: "\u001B[90m";
72
74
  success: "\u001B[32m";
73
75
  error: "\u001B[31m";
74
76
  warning: "\u001B[33m";
75
- info: "\u001B[34m";
76
- cursor: "\u001B[36m";
77
- selected: "\u001B[32m";
77
+ info: "\u001B[0m";
78
+ cursor: "\u001B[0m";
79
+ selected: "\u001B[0m";
80
+ highlightBg: "";
81
+ highlightText: "\u001B[0m";
78
82
  disabled: "\u001B[2m";
79
- border: "\u001B[36m";
83
+ border: "\u001B[90m";
80
84
  separator: "\u001B[2m";
81
85
  prefix: "\u001B[2m";
82
86
  };
@@ -93,19 +97,21 @@ export declare function resetUIColors(): void;
93
97
  * UI colors accessor (always returns current colors)
94
98
  */
95
99
  export declare const uiColors: {
96
- readonly primary: "\u001B[36m";
97
- readonly accent: "\u001B[34m";
100
+ readonly primary: "\u001B[0m";
101
+ readonly accent: "\u001B[0m";
98
102
  readonly textPrimary: "\u001B[0m";
99
103
  readonly textSecondary: "\u001B[2m";
100
104
  readonly textMuted: "\u001B[90m";
101
105
  readonly success: "\u001B[32m";
102
106
  readonly error: "\u001B[31m";
103
107
  readonly warning: "\u001B[33m";
104
- readonly info: "\u001B[34m";
105
- readonly cursor: "\u001B[36m";
106
- readonly selected: "\u001B[32m";
108
+ readonly info: "\u001B[0m";
109
+ readonly cursor: "\u001B[0m";
110
+ readonly selected: "\u001B[0m";
111
+ readonly highlightBg: "";
112
+ readonly highlightText: "\u001B[0m";
107
113
  readonly disabled: "\u001B[2m";
108
- readonly border: "\u001B[36m";
114
+ readonly border: "\u001B[90m";
109
115
  readonly separator: "\u001B[2m";
110
116
  readonly prefix: "\u001B[2m";
111
117
  };
@@ -59,8 +59,8 @@ exports.colors = {
59
59
  */
60
60
  exports.defaultUIColors = {
61
61
  // Primary elements
62
- primary: exports.colors.cyan, // Main interactive elements, highlights
63
- accent: exports.colors.blue, // Secondary highlights, links
62
+ primary: exports.colors.reset, // Main interactive elements, follows terminal foreground
63
+ accent: exports.colors.reset, // Secondary highlights, follows terminal foreground
64
64
  // Text hierarchy
65
65
  textPrimary: exports.colors.reset, // Main text (black/default)
66
66
  textSecondary: exports.colors.dim, // Descriptions, hints, less important text
@@ -69,13 +69,15 @@ exports.defaultUIColors = {
69
69
  success: exports.colors.green, // Success states, confirmations
70
70
  error: exports.colors.red, // Errors, warnings, exit
71
71
  warning: exports.colors.yellow, // Warnings, cautions
72
- info: exports.colors.blue, // Informational messages
72
+ info: exports.colors.reset, // Informational messages
73
73
  // Interactive elements
74
- cursor: exports.colors.cyan, // Cursor indicator
75
- selected: exports.colors.green, // Selected items
74
+ cursor: exports.colors.reset, // Cursor indicator
75
+ selected: exports.colors.reset, // Selected items
76
+ highlightBg: '', // Optional background block for highlighted option
77
+ highlightText: exports.colors.reset, // Text color when highlightBg is used
76
78
  disabled: exports.colors.dim, // Disabled/inactive items
77
79
  // Structural elements
78
- border: exports.colors.cyan, // Borders, frames
80
+ border: exports.colors.brightBlack, // Borders, frames
79
81
  separator: exports.colors.dim, // Separators, dividers
80
82
  prefix: exports.colors.dim // Number/letter prefixes
81
83
  };
@@ -118,6 +120,18 @@ exports.uiColors = new Proxy({}, {
118
120
  * Supports basic 8 colors and bright variants
119
121
  */
120
122
  function parseColorToRGB(colorCode) {
123
+ const trueColorMatch = /^\x1b\[38;2;(\d{1,3});(\d{1,3});(\d{1,3})m$/.exec(colorCode);
124
+ if (trueColorMatch) {
125
+ return {
126
+ r: Math.max(0, Math.min(255, Number.parseInt(trueColorMatch[1], 10))),
127
+ g: Math.max(0, Math.min(255, Number.parseInt(trueColorMatch[2], 10))),
128
+ b: Math.max(0, Math.min(255, Number.parseInt(trueColorMatch[3], 10)))
129
+ };
130
+ }
131
+ const ansi256Match = /^\x1b\[38;5;(\d{1,3})m$/.exec(colorCode);
132
+ if (ansi256Match) {
133
+ return ansi256ToRgb(Math.max(0, Math.min(255, Number.parseInt(ansi256Match[1], 10))));
134
+ }
121
135
  // Map of ANSI codes to approximate RGB values
122
136
  const colorMap = {
123
137
  '\x1b[30m': { r: 0, g: 0, b: 0 }, // black
@@ -139,6 +153,48 @@ function parseColorToRGB(colorCode) {
139
153
  };
140
154
  return colorMap[colorCode] || { r: 170, g: 170, b: 170 };
141
155
  }
156
+ function detectColorMode(colorCode) {
157
+ if (/^\x1b\[38;2;\d{1,3};\d{1,3};\d{1,3}m$/.test(colorCode)) {
158
+ return 'truecolor';
159
+ }
160
+ if (/^\x1b\[38;5;\d{1,3}m$/.test(colorCode)) {
161
+ return 'ansi256';
162
+ }
163
+ return 'ansi16';
164
+ }
165
+ function ansi256ToRgb(code) {
166
+ if (code < 16) {
167
+ const ansi16Map = [
168
+ { r: 0, g: 0, b: 0 }, // 0 black
169
+ { r: 170, g: 0, b: 0 }, // 1 red
170
+ { r: 0, g: 170, b: 0 }, // 2 green
171
+ { r: 170, g: 85, b: 0 }, // 3 yellow
172
+ { r: 0, g: 0, b: 170 }, // 4 blue
173
+ { r: 170, g: 0, b: 170 }, // 5 magenta
174
+ { r: 0, g: 170, b: 170 }, // 6 cyan
175
+ { r: 170, g: 170, b: 170 }, // 7 white
176
+ { r: 85, g: 85, b: 85 }, // 8 bright black
177
+ { r: 255, g: 85, b: 85 }, // 9 bright red
178
+ { r: 85, g: 255, b: 85 }, // 10 bright green
179
+ { r: 255, g: 255, b: 85 }, // 11 bright yellow
180
+ { r: 85, g: 85, b: 255 }, // 12 bright blue
181
+ { r: 255, g: 85, b: 255 }, // 13 bright magenta
182
+ { r: 85, g: 255, b: 255 }, // 14 bright cyan
183
+ { r: 255, g: 255, b: 255 } // 15 bright white
184
+ ];
185
+ return ansi16Map[code];
186
+ }
187
+ if (code >= 16 && code <= 231) {
188
+ const n = code - 16;
189
+ const r = Math.floor(n / 36);
190
+ const g = Math.floor((n % 36) / 6);
191
+ const b = n % 6;
192
+ const steps = [0, 95, 135, 175, 215, 255];
193
+ return { r: steps[r], g: steps[g], b: steps[b] };
194
+ }
195
+ const gray = 8 + (code - 232) * 10;
196
+ return { r: gray, g: gray, b: gray };
197
+ }
142
198
  /**
143
199
  * Convert RGB to ANSI 256-color code
144
200
  */
@@ -147,6 +203,12 @@ function rgbToAnsi256(r, g, b) {
147
203
  const code = 16 + 36 * Math.round(r / 255 * 5) + 6 * Math.round(g / 255 * 5) + Math.round(b / 255 * 5);
148
204
  return `\x1b[38;5;${code}m`;
149
205
  }
206
+ function rgbToAnsiTrueColor(r, g, b) {
207
+ const rr = Math.max(0, Math.min(255, Math.round(r)));
208
+ const gg = Math.max(0, Math.min(255, Math.round(g)));
209
+ const bb = Math.max(0, Math.min(255, Math.round(b)));
210
+ return `\x1b[38;2;${rr};${gg};${bb}m`;
211
+ }
150
212
  /**
151
213
  * Interpolate between two RGB colors
152
214
  */
@@ -171,11 +233,16 @@ function createGradient(startColor, endColor, steps) {
171
233
  return [startColor];
172
234
  const start = parseColorToRGB(startColor);
173
235
  const end = parseColorToRGB(endColor);
236
+ const startMode = detectColorMode(startColor);
237
+ const endMode = detectColorMode(endColor);
238
+ const outputMode = startMode === 'truecolor' && endMode === 'truecolor' ? 'truecolor' : 'ansi256';
174
239
  const gradient = [];
175
240
  for (let i = 0; i < steps; i++) {
176
241
  const factor = i / (steps - 1);
177
242
  const rgb = interpolateRGB(start, end, factor);
178
- gradient.push(rgbToAnsi256(rgb.r, rgb.g, rgb.b));
243
+ gradient.push(outputMode === 'truecolor'
244
+ ? rgbToAnsiTrueColor(rgb.r, rgb.g, rgb.b)
245
+ : rgbToAnsi256(rgb.r, rgb.g, rgb.b));
179
246
  }
180
247
  return gradient;
181
248
  }
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Hint Manager - Manages hints from multiple components with priority
3
+ *
4
+ * Allows multiple components to set hints with different priorities.
5
+ * The highest priority hint is displayed.
6
+ */
7
+ import { EventEmitter } from 'events';
8
+ export declare class HintManager extends EventEmitter {
9
+ private entries;
10
+ /**
11
+ * Set a hint with a token and priority
12
+ * @param token - Unique identifier for this hint source
13
+ * @param text - Hint text to display
14
+ * @param priority - Higher priority hints are displayed first (default: 0)
15
+ */
16
+ set(token: string, text: string, priority?: number): void;
17
+ /**
18
+ * Clear a hint by token
19
+ */
20
+ clear(token: string): void;
21
+ /**
22
+ * Get the current highest priority hint
23
+ */
24
+ current(): string;
25
+ /**
26
+ * Clear all hints
27
+ */
28
+ clearAll(): void;
29
+ }
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+ /**
3
+ * Hint Manager - Manages hints from multiple components with priority
4
+ *
5
+ * Allows multiple components to set hints with different priorities.
6
+ * The highest priority hint is displayed.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.HintManager = void 0;
10
+ const events_1 = require("events");
11
+ class HintManager extends events_1.EventEmitter {
12
+ constructor() {
13
+ super(...arguments);
14
+ this.entries = new Map();
15
+ }
16
+ /**
17
+ * Set a hint with a token and priority
18
+ * @param token - Unique identifier for this hint source
19
+ * @param text - Hint text to display
20
+ * @param priority - Higher priority hints are displayed first (default: 0)
21
+ */
22
+ set(token, text, priority = 0) {
23
+ this.entries.set(token, {
24
+ text,
25
+ priority,
26
+ timestamp: Date.now()
27
+ });
28
+ this.emit('change', this.current());
29
+ }
30
+ /**
31
+ * Clear a hint by token
32
+ */
33
+ clear(token) {
34
+ if (this.entries.delete(token)) {
35
+ this.emit('change', this.current());
36
+ }
37
+ }
38
+ /**
39
+ * Get the current highest priority hint
40
+ */
41
+ current() {
42
+ const list = Array.from(this.entries.values());
43
+ if (list.length === 0) {
44
+ return '';
45
+ }
46
+ // Sort by priority (descending), then by timestamp (most recent first)
47
+ list.sort((a, b) => {
48
+ if (b.priority !== a.priority) {
49
+ return b.priority - a.priority;
50
+ }
51
+ return b.timestamp - a.timestamp;
52
+ });
53
+ return list[0].text;
54
+ }
55
+ /**
56
+ * Clear all hints
57
+ */
58
+ clearAll() {
59
+ if (this.entries.size > 0) {
60
+ this.entries.clear();
61
+ this.emit('change', '');
62
+ }
63
+ }
64
+ }
65
+ exports.HintManager = HintManager;
@@ -43,8 +43,9 @@ export declare function renderSeparator(char?: string, width?: number): void;
43
43
  * Render a section label (menu grouping)
44
44
  * @param label - Label text (optional)
45
45
  * @param width - Total width of the separator (default: 30)
46
+ * @param align - Alignment of the label (default: 'center')
46
47
  */
47
- export declare function renderSectionLabel(label?: string, width?: number): void;
48
+ export declare function renderSectionLabel(label?: string, width?: number, align?: 'left' | 'center' | 'right'): void;
48
49
  /**
49
50
  * Render a message with icon
50
51
  * @param type - Message type (success, error, warning, info, question)
@@ -69,14 +69,23 @@ function renderOption(text, isSelected, isHighlighted, prefix) {
69
69
  const parts = text.split(' - ');
70
70
  const mainText = parts[0];
71
71
  const description = parts.length > 1 ? parts.slice(1).join(' - ') : '';
72
+ const hasHighlightBlock = Boolean(colors_js_1.uiColors.highlightBg);
73
+ const blockLead = hasHighlightBlock ? ' ' : '';
72
74
  if (isHighlighted) {
73
- line += `${colors_js_1.uiColors.primary}${colors_js_1.colors.bold}${mainText}${colors_js_1.colors.reset}`;
74
- if (description) {
75
- line += ` ${colors_js_1.uiColors.textSecondary}- ${description}${colors_js_1.colors.reset}`;
75
+ if (hasHighlightBlock) {
76
+ const highlightText = colors_js_1.uiColors.highlightText || colors_js_1.uiColors.textPrimary;
77
+ const mergedText = description ? `${mainText} - ${description}` : mainText;
78
+ line += `${colors_js_1.uiColors.highlightBg}${highlightText}${colors_js_1.colors.bold}${blockLead}${mergedText} ${colors_js_1.colors.reset}`;
79
+ }
80
+ else {
81
+ line += `${colors_js_1.uiColors.primary}${colors_js_1.colors.bold}${mainText}${colors_js_1.colors.reset}`;
82
+ if (description) {
83
+ line += ` ${colors_js_1.uiColors.textSecondary}- ${description}${colors_js_1.colors.reset}`;
84
+ }
76
85
  }
77
86
  }
78
87
  else {
79
- line += `${colors_js_1.colors.bold}${mainText}${colors_js_1.colors.reset}`;
88
+ line += `${colors_js_1.uiColors.textPrimary}${colors_js_1.colors.bold}${blockLead}${mainText}${colors_js_1.colors.reset}`;
80
89
  if (description) {
81
90
  line += ` ${colors_js_1.uiColors.textSecondary}- ${description}${colors_js_1.colors.reset}`;
82
91
  }
@@ -90,12 +99,12 @@ function renderOption(text, isSelected, isHighlighted, prefix) {
90
99
  * @param showCursor - Whether to show cursor
91
100
  */
92
101
  function renderInputPrompt(prompt, value, showCursor = false) {
93
- let line = ` ${prompt} `;
102
+ let line = ` ${colors_js_1.uiColors.textPrimary}${prompt}${colors_js_1.colors.reset} `;
94
103
  if (value) {
95
- line += `${colors_js_1.colors.cyan}${value}${colors_js_1.colors.reset}`;
104
+ line += `${colors_js_1.uiColors.primary}${value}${colors_js_1.colors.reset}`;
96
105
  }
97
106
  if (showCursor) {
98
- line += `${colors_js_1.colors.cyan}_${colors_js_1.colors.reset}`;
107
+ line += `${colors_js_1.uiColors.primary}_${colors_js_1.colors.reset}`;
99
108
  }
100
109
  (0, terminal_js_1.writeLine)(line);
101
110
  }
@@ -135,17 +144,32 @@ function renderSeparator(char = '─', width) {
135
144
  * Render a section label (menu grouping)
136
145
  * @param label - Label text (optional)
137
146
  * @param width - Total width of the separator (default: 30)
147
+ * @param align - Alignment of the label (default: 'center')
138
148
  */
139
- function renderSectionLabel(label, width = 30) {
149
+ function renderSectionLabel(label, width = 30, align = 'center') {
140
150
  if (label) {
141
- const totalWidth = width; // Use configured width
142
- const padding = 2; // Spaces around label
151
+ const totalWidth = width;
143
152
  const labelWithPadding = ` ${label} `;
144
153
  const labelLength = labelWithPadding.length;
145
154
  const dashesTotal = totalWidth - labelLength;
146
- const dashesLeft = Math.floor(dashesTotal / 2);
147
- const dashesRight = dashesTotal - dashesLeft;
148
- const line = ` ${colors_js_1.uiColors.separator}${'─'.repeat(dashesLeft)}${labelWithPadding}${'─'.repeat(dashesRight)}${colors_js_1.colors.reset}`;
155
+ let dashesLeft;
156
+ let dashesRight;
157
+ switch (align) {
158
+ case 'left':
159
+ dashesLeft = 0;
160
+ dashesRight = dashesTotal;
161
+ break;
162
+ case 'right':
163
+ dashesLeft = dashesTotal;
164
+ dashesRight = 0;
165
+ break;
166
+ case 'center':
167
+ default:
168
+ dashesLeft = Math.floor(dashesTotal / 2);
169
+ dashesRight = dashesTotal - dashesLeft;
170
+ break;
171
+ }
172
+ const line = ` ${colors_js_1.uiColors.primary}${colors_js_1.colors.bold}${'─'.repeat(dashesLeft)}${labelWithPadding}${'─'.repeat(dashesRight)}${colors_js_1.colors.reset}`;
149
173
  (0, terminal_js_1.writeLine)(line);
150
174
  }
151
175
  else {
@@ -163,23 +187,23 @@ function renderMessage(type, message) {
163
187
  switch (type) {
164
188
  case 'success':
165
189
  icon = '✓';
166
- color = colors_js_1.colors.green;
190
+ color = colors_js_1.uiColors.success;
167
191
  break;
168
192
  case 'error':
169
193
  icon = '✗';
170
- color = colors_js_1.colors.red;
194
+ color = colors_js_1.uiColors.error;
171
195
  break;
172
196
  case 'warning':
173
197
  icon = '⚠';
174
- color = colors_js_1.colors.yellow;
198
+ color = colors_js_1.uiColors.warning;
175
199
  break;
176
200
  case 'info':
177
201
  icon = 'ℹ';
178
- color = colors_js_1.colors.blue;
202
+ color = colors_js_1.uiColors.info;
179
203
  break;
180
204
  case 'question':
181
205
  icon = '?';
182
- color = colors_js_1.colors.yellow;
206
+ color = colors_js_1.uiColors.warning;
183
207
  break;
184
208
  }
185
209
  (0, terminal_js_1.writeLine)(`${color}${icon}${colors_js_1.colors.reset} ${message}`);
@@ -193,16 +217,16 @@ function renderProgress(steps, currentStep) {
193
217
  const parts = [];
194
218
  steps.forEach((step, index) => {
195
219
  if (index === currentStep) {
196
- parts.push(`${colors_js_1.colors.cyan}${step}${colors_js_1.colors.reset}`);
220
+ parts.push(`${colors_js_1.uiColors.primary}${step}${colors_js_1.colors.reset}`);
197
221
  }
198
222
  else if (index < currentStep) {
199
- parts.push(step);
223
+ parts.push(`${colors_js_1.uiColors.textPrimary}${step}${colors_js_1.colors.reset}`);
200
224
  }
201
225
  else {
202
- parts.push(`${colors_js_1.colors.dim}${step}${colors_js_1.colors.reset}`);
226
+ parts.push(`${colors_js_1.uiColors.textSecondary}${step}${colors_js_1.colors.reset}`);
203
227
  }
204
228
  });
205
- (0, terminal_js_1.writeLine)(` ${parts.join(` ${colors_js_1.colors.dim}→${colors_js_1.colors.reset} `)}`);
229
+ (0, terminal_js_1.writeLine)(` ${parts.join(` ${colors_js_1.uiColors.textSecondary}→${colors_js_1.colors.reset} `)}`);
206
230
  }
207
231
  /**
208
232
  * Render a box with content