完善 脚手架UI
This commit is contained in:
@ -6,7 +6,7 @@ function clearScreen() {
|
||||
}
|
||||
|
||||
export function createStepUI(options) {
|
||||
const { title, getSteps } = options;
|
||||
const { title, getSteps, onStepChange } = options;
|
||||
|
||||
let steps = [];
|
||||
let results = [];
|
||||
@ -19,16 +19,33 @@ export function createStepUI(options) {
|
||||
steps = typeof getSteps === "function" ? getSteps() : getSteps;
|
||||
results = steps.map(s => s.type === "multiselect" ? [...(s.default || [])] : s.default);
|
||||
completed = new Set();
|
||||
// 有默认值的步骤自动标记为已完成
|
||||
steps.forEach((s, i) => {
|
||||
if (s.default && s.default !== "none" && (!Array.isArray(s.default) || s.default.length > 0)) {
|
||||
completed.add(i);
|
||||
}
|
||||
});
|
||||
currentStep = 0;
|
||||
currentOption = 0;
|
||||
resolved = false;
|
||||
}
|
||||
|
||||
function updateSteps(newSteps) {
|
||||
steps = newSteps;
|
||||
// 保留第一个步骤的结果,重置其他步骤为默认值
|
||||
const firstResult = results[0];
|
||||
results = steps.map((s, i) => {
|
||||
if (i === 0) return firstResult;
|
||||
return s.type === "multiselect" ? [...(s.default || [])] : s.default;
|
||||
});
|
||||
if (currentStep >= steps.length) currentStep = steps.length - 1;
|
||||
}
|
||||
|
||||
function renderNav() {
|
||||
const nav = steps.map((step, i) => {
|
||||
if (completed.has(i)) return color.green("☑ " + step.name);
|
||||
if (step.disabled) return color.dim("□ " + step.name);
|
||||
if (i === currentStep) return color.bgCyan(color.black(" " + step.name + " "));
|
||||
return color.dim("□ " + step.name);
|
||||
return color.dim(step.name);
|
||||
});
|
||||
return "← " + nav.join(" ") + " " + color.green("✓Submit") + " →";
|
||||
}
|
||||
@ -81,6 +98,20 @@ export function createStepUI(options) {
|
||||
console.log(renderOptions());
|
||||
}
|
||||
|
||||
function findPrevStep(from) {
|
||||
for (let i = from - 1; i >= 0; i--) {
|
||||
if (!steps[i].disabled) return i;
|
||||
}
|
||||
return from;
|
||||
}
|
||||
|
||||
function findNextStep(from) {
|
||||
for (let i = from + 1; i < steps.length; i++) {
|
||||
if (!steps[i].disabled) return i;
|
||||
}
|
||||
return from;
|
||||
}
|
||||
|
||||
function handleKey(key, resolve) {
|
||||
if (!key || resolved) return;
|
||||
|
||||
@ -89,11 +120,13 @@ export function createStepUI(options) {
|
||||
|
||||
switch (key.name) {
|
||||
case "left":
|
||||
if (currentStep > 0) { currentStep--; currentOption = 0; }
|
||||
const prevStep = findPrevStep(currentStep);
|
||||
if (prevStep !== currentStep) { currentStep = prevStep; currentOption = 0; }
|
||||
render();
|
||||
break;
|
||||
case "right":
|
||||
if (currentStep < steps.length - 1) { currentStep++; currentOption = 0; }
|
||||
const nextStep = findNextStep(currentStep);
|
||||
if (nextStep !== currentStep) { currentStep = nextStep; currentOption = 0; }
|
||||
render();
|
||||
break;
|
||||
case "up":
|
||||
@ -120,6 +153,10 @@ export function createStepUI(options) {
|
||||
results[currentStep] = opt.value;
|
||||
}
|
||||
completed.add(currentStep);
|
||||
if (onStepChange && currentStep === 0) {
|
||||
const newSteps = onStepChange(results[0]);
|
||||
if (newSteps) updateSteps(newSteps);
|
||||
}
|
||||
render();
|
||||
}
|
||||
break;
|
||||
@ -127,7 +164,12 @@ export function createStepUI(options) {
|
||||
if (optCount && step.type === "select") {
|
||||
results[currentStep] = step.options[currentOption].value;
|
||||
completed.add(currentStep);
|
||||
if (currentStep < steps.length - 1) { currentStep++; currentOption = 0; }
|
||||
if (onStepChange && currentStep === 0) {
|
||||
const newSteps = onStepChange(results[0]);
|
||||
if (newSteps) updateSteps(newSteps);
|
||||
}
|
||||
const next = findNextStep(currentStep);
|
||||
if (next !== currentStep) { currentStep = next; currentOption = 0; }
|
||||
render();
|
||||
}
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user