优化卡死的问题
This commit is contained in:
152
lib/scaffold/ui.js
Normal file
152
lib/scaffold/ui.js
Normal file
@ -0,0 +1,152 @@
|
||||
import color from "picocolors";
|
||||
import { initKeypress, onKey, stopKeypress } from "../keyboard.js";
|
||||
import { createStepUI } from "../utils/stepui.js";
|
||||
import { frontendSteps } from "./config.js";
|
||||
|
||||
function clearScreen() {
|
||||
process.stdout.write('\x1Bc');
|
||||
}
|
||||
|
||||
function strWidth(str) {
|
||||
let width = 0;
|
||||
for (const char of str) {
|
||||
width += char.charCodeAt(0) > 127 ? 2 : 1;
|
||||
}
|
||||
return width;
|
||||
}
|
||||
|
||||
function padEnd(str, width) {
|
||||
return str + " ".repeat(Math.max(0, width - strWidth(str)));
|
||||
}
|
||||
|
||||
// 网格选择器
|
||||
export async function gridSelect(items, title) {
|
||||
let current = 0;
|
||||
let resolved = false;
|
||||
const termWidth = process.stdout.columns || 80;
|
||||
const cols = Math.min(3, items.length);
|
||||
const colWidth = 20;
|
||||
const rows = Math.ceil(items.length / cols);
|
||||
const totalWidth = cols * colWidth;
|
||||
const pad = " ".repeat(Math.max(0, Math.floor((termWidth - totalWidth) / 2)));
|
||||
|
||||
function render() {
|
||||
clearScreen();
|
||||
console.log("");
|
||||
const titlePad = " ".repeat(Math.max(0, Math.floor((termWidth - strWidth(title) - 4) / 2)));
|
||||
console.log(titlePad + color.bgMagenta(color.white(` ${title} `)));
|
||||
console.log("");
|
||||
console.log(pad + color.dim("↑ ↓ ← → 选择 | Enter 确认 | Esc 返回"));
|
||||
console.log("\n");
|
||||
|
||||
for (let row = 0; row < rows; row++) {
|
||||
let line = "";
|
||||
let descLine = "";
|
||||
|
||||
for (let col = 0; col < cols; col++) {
|
||||
const idx = row * cols + col;
|
||||
if (idx < items.length) {
|
||||
const item = items[idx];
|
||||
const isSelected = idx === current;
|
||||
|
||||
if (isSelected) {
|
||||
line += color.cyan("[" + item.name + "]");
|
||||
} else {
|
||||
line += " " + item.name + " ";
|
||||
}
|
||||
line += " ".repeat(colWidth - strWidth(item.name) - 2);
|
||||
descLine += padEnd(item.desc || "", colWidth);
|
||||
}
|
||||
}
|
||||
|
||||
console.log(pad + line);
|
||||
console.log(pad + color.dim(descLine));
|
||||
console.log("\n");
|
||||
}
|
||||
}
|
||||
|
||||
return new Promise(resolve => {
|
||||
initKeypress();
|
||||
render();
|
||||
|
||||
onKey((str, key) => {
|
||||
if (!key || resolved) return;
|
||||
|
||||
const row = Math.floor(current / cols);
|
||||
const col = current % cols;
|
||||
|
||||
switch (key.name) {
|
||||
case "up":
|
||||
if (row > 0) { current -= cols; render(); }
|
||||
break;
|
||||
case "down":
|
||||
if (row < rows - 1 && current + cols < items.length) { current += cols; render(); }
|
||||
break;
|
||||
case "left":
|
||||
if (col > 0) { current--; render(); }
|
||||
break;
|
||||
case "right":
|
||||
if (col < cols - 1 && current < items.length - 1) { current++; render(); }
|
||||
break;
|
||||
case "return":
|
||||
resolved = true;
|
||||
stopKeypress();
|
||||
setImmediate(() => resolve({ action: "select", item: items[current] }));
|
||||
break;
|
||||
case "escape":
|
||||
resolved = true;
|
||||
stopKeypress();
|
||||
setImmediate(() => resolve({ action: "back" }));
|
||||
break;
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// 创建组件配置UI
|
||||
export function createComponentUI(frameworkName) {
|
||||
return createStepUI({
|
||||
title: `${frameworkName} - 组件配置`,
|
||||
getSteps: () => frontendSteps
|
||||
});
|
||||
}
|
||||
|
||||
// 解析配置结果
|
||||
export function formatResults(results) {
|
||||
const stepNames = frontendSteps.map(s => s.name);
|
||||
const summary = [];
|
||||
|
||||
results.forEach((val, i) => {
|
||||
if (Array.isArray(val) && val.length > 0) {
|
||||
summary.push(`${stepNames[i]}: ${val.join(", ")}`);
|
||||
} else if (val && val !== "none") {
|
||||
summary.push(`${stepNames[i]}: ${val}`);
|
||||
}
|
||||
});
|
||||
|
||||
return summary.length ? summary : ["未选择任何组件"];
|
||||
}
|
||||
|
||||
// 等待按键
|
||||
export async function waitKey(message = "按任意键返回") {
|
||||
console.log(color.dim(`\n${message}`));
|
||||
|
||||
return new Promise(resolve => {
|
||||
initKeypress();
|
||||
onKey(() => {
|
||||
stopKeypress();
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// 显示占位信息
|
||||
export function showPlaceholder(framework) {
|
||||
clearScreen();
|
||||
console.log("");
|
||||
console.log(color.bgGreen(color.black(" 配置完成 ")));
|
||||
console.log("");
|
||||
console.log(color.cyan("框架: ") + framework.name);
|
||||
console.log("");
|
||||
console.log(color.yellow("功能开发中,敬请期待..."));
|
||||
}
|
||||
Reference in New Issue
Block a user