readMultiChoice static method
Implementation
static List<String> readMultiChoice(
String message,
List<String> options, {
List<String> selected = const [],
CappColors color = CappColors.none,
bool required = false,
}) {
int selectedIndex = 0;
List<bool> checked = List.filled(options.length, false);
for (var i = 0; i < options.length; i++) {
var option = options[i];
checked[i] = selected.contains(option);
}
void render([int input = -1]) {
// Clear the console
clear();
write(message, CappColors.info, true);
for (var i = 0; i < options.length; i++) {
final checkbox = checked[i] ? '[x]' : '[ ]';
final prefix = (i == selectedIndex) ? '> ' : ' ';
if ((i == selectedIndex)) {
write('$prefix$checkbox ${options[i]}', color);
} else {
write('$prefix$checkbox ${options[i]}', CappColors.none);
}
}
write(
'\n\nUse Arrow Keys to navigate, Space to toggle, Enter to confirm.',
color,
);
}
render();
// stdin.lineMode = false;
// stdin.echoMode = false;
try {
while (true) {
var input = console.readKey();
//if (input.controlChar == ControlCharacter.escape) {
// Arrow key sequence starts with ESC (27)
if (input.controlChar == ControlCharacter.arrowUp) {
// Arrow Up
selectedIndex = (selectedIndex - 1) % options.length;
if (selectedIndex < 0) selectedIndex += options.length;
} else if (input.controlChar == ControlCharacter.arrowDown) {
// Arrow Down
selectedIndex = (selectedIndex + 1) % options.length;
} else if (input.char == " ") {
// Space key
checked[selectedIndex] = !checked[selectedIndex];
} else if (input.controlChar == ControlCharacter.escape ||
input.controlChar == ControlCharacter.enter) {
// Enter key
break;
}
render(int.tryParse(input.char) ?? -1);
}
} finally {
// stdin.lineMode = true;
// stdin.echoMode = true;
}
var res = [
for (var i = 0; i < options.length; i++)
if (checked[i]) options[i]
];
if (required && res.isEmpty) {
return readMultiChoice(
message + "\n\n * At least one option is required!",
options,
selected: [],
color: color,
required: required,
);
}
return res;
}