Skip to content

Commit

Permalink
Fix: support for default option (robin-rpr#9)
Browse files Browse the repository at this point in the history
This changeset adds support for the default option (as a value, not as a
function), updates the examples to showcase the default option, and also
brings Yarn up to its stable version.
  • Loading branch information
Juanc1to committed Jul 22, 2022
1 parent a998d56 commit 37d0d34
Show file tree
Hide file tree
Showing 8 changed files with 1,392 additions and 493 deletions.
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
dist/
node_modules
.DS_Store

.pnp.*
.yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/sdks
!.yarn/versions
783 changes: 783 additions & 0 deletions .yarn/releases/yarn-3.2.2.cjs

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions .yarnrc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
nodeLinker: node-modules

yarnPath: .yarn/releases/yarn-3.2.2.cjs
36 changes: 18 additions & 18 deletions examples/basic.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,22 @@ const inquirer = require("inquirer");
inquirer.registerPrompt("search-list", require("../dist"));

inquirer
.prompt([
{
type: "search-list",
message: "Select topping",
name: "topping",
choices: ["Hame", "Ham", "Ground Meat", "Bacon", "Mozzarella", "Bottle"],
validate: function(answer) {
if (answer === 'Bottle') {
return `Whoops, ${answer} is not a real topping.`;
}
return true;
},
default: 'Ham',
.prompt([
{
type: "search-list",
message: "Select topping",
name: "topping",
choices: ["Hame", "Ham", "Ground Meat", "Bacon", "Mozzarella", "Bottle"],
validate: function(answer) {
if (answer === 'Bottle') {
return `Whoops, ${answer} is not a real topping.`;
}
])
.then(function(answers) {
console.log(JSON.stringify(answers, null, " "));
})
.catch(e => console.log(e));
return true;
},
default: 'Bacon',
}
])
.then(function(answers) {
console.log(JSON.stringify(answers, null, " "));
})
.catch(e => console.log(e));
46 changes: 27 additions & 19 deletions examples/objects.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,25 +12,33 @@ const toppings = [
{title: "Bottle", usage: "Drinks"},
{title: "Mozzarella", usage: "Pizza"},
{title: "Rum", usage: "Party"},
]
];

inquirer
.prompt([
{
type: "search-list",
message: "Select topping",
name: "topping",
choices: toppings.map(topping => ({name: topping.title, value: topping })),
validate: function(answer) {
if (answer.name === 'Bottle') {
return `Whoops, ${answer.name} is not a real topping.`;
}
return true;
},
default: 'Ham',
.prompt([
{
type: "search-list",
message: "Select topping",
name: "topping",
choices: toppings.map(function (topping, index) {
return {
name: topping.title,
value: index,
};
}),
filter: function (input) {
return toppings[input];
},
validate: function(answer) {
if (answer.title === 'Bottle') {
return `Whoops, ${answer.title} is not a real topping.`;
}
])
.then(function(answers) {
console.log(JSON.stringify(answers, null, " "));
})
.catch(e => console.log(e));
return true;
},
default: 4, // With .title === 'Ham'
},
])
.then(function(answers) {
console.log(JSON.stringify(answers, null, " "));
})
.catch(e => console.log(e));
146 changes: 55 additions & 91 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ function renderChoices(renderRow: Renderer, choices: Item[], pointer: number) {

class SearchBox extends Base {
private pointer: number = 0;
private defaultValue: any = undefined;
private selected: string | undefined = '';
// @ts-ignore
private done: (state: any) => void;
Expand All @@ -65,6 +66,7 @@ class SearchBox extends Base {
constructor(...params: Inquirer.Question[]) {
super(...params);
const { choices, renderRow, filterRow } = this.opt;
this.defaultValue = this.opt.default;

if (!choices) {
this.throwParamError('choices');
Expand All @@ -73,96 +75,20 @@ class SearchBox extends Base {
renderRow ? this.renderRow = renderRow : this.renderRow = defaultRenderRow;
filterRow ? this.filterRow = filterRow : this.filterRow = defaultFilterRow;

const ob = this;
this.filterList = this.list = choices
.filter(() => true) // fix slice is not a function
.map((item, id) => ({ ...item, id }));
.map(function (item, id) {
if (item.value === ob.defaultValue) {
ob.pointer = id;
}
return {
...item,
id,
};
});
}

render(error?: string) {
// Render question
var message = this.getQuestion();
var bottomContent = "";
const tip = chalk.dim("(Press <enter> to submit)");

// Render choices or answer depending on the state
if (this.status === "answered") {
message += chalk.cyan(this.selected ? this.selected : '');
} else {
message += `${tip} ${this.rl.line}`;
const choicesStr = renderChoices(this.renderRow, this.filterList, this.pointer);
bottomContent = this.paginator.paginate(
choicesStr,
this.pointer,
this.opt.pageSize
);
}

if (error) {
bottomContent = chalk.red(">> ") + error;
}

this.screen.render(message, bottomContent);
}

filterChoices() {
this.filterList = this.list.filter((choice) => this.filterRow(choice, this.rl.line));
}

onDownKey() {
const len = this.filterList.length;
this.pointer = this.pointer < len - 1 ? this.pointer + 1 : 0;
this.render();
}

onUpKey() {
const len = this.filterList.length;
this.pointer = this.pointer > 0 ? this.pointer - 1 : len - 1;
this.render();
}

onAllKey() {
this.render();
}

onEnd(state: any) {
this.status = "answered";
if(this.getCurrentItemName()) {
this.selected = this.getCurrentItemName()
}
// Rerender prompt (and clean subline error)
this.render();

this.screen.done();
this.done(state.value);
}

onError(state: any) {
this.render(state.isValid);
}

onKeyPress() {
this.pointer = 0;
this.filterChoices();
this.render();
}

getCurrentItem() {
if(this.filterList.length) {
return this.filterList[this.pointer]
} else {
return this.list[this.pointer]
}

this.filterList = this.list = choices
.filter(() => true) // fix slice is not a function
.map((item, id) => ({ ...item, id }));
// init default value
const index = this.filterList.findIndex((e) => {
return e.name === this.opt.default;
});
this.pointer = index > -1 ? index : 0;
}

render(error?: string) {
// Render question
var message = this.getQuestion();
Expand All @@ -174,8 +100,16 @@ class SearchBox extends Base {
message += chalk.cyan(this.selected ? this.selected : '');
} else {
message += `${tip} ${this.rl.line}`;
const choicesStr = renderChoices(this.filterList, this.pointer);
bottomContent = this.paginator.paginate(choicesStr, this.pointer, this.opt.pageSize);
const choicesStr = renderChoices(
this.renderRow,
this.filterList,
this.pointer,
);
bottomContent = this.paginator.paginate(
choicesStr,
this.pointer,
this.opt.pageSize,
);
}

if (error) {
Expand All @@ -190,8 +124,20 @@ class SearchBox extends Base {
extract: (el: Item) => el.name,
};

this.filterList = fuzzy.filter(this.rl.line, this.list, options).map((el) => el.original);
// 记录输入值
// was:
//this.filterList = this.list.filter((choice) => this.filterRow(choice, this.rl.line));
// TODO: evaluate these two different approaches.
const ob = this;
this.filterList = fuzzy.filter(this.rl.line, this.list, options).map(
function (el, index) {
if (el.original.value === ob.defaultValue) {
ob.pointer = index;
}
return el.original;
}
);
// 记录输入值: "record input value"? Ah, I think to allow providing an
// input that is not one of the available options.
this.userInput = this.rl.line;
}

Expand Down Expand Up @@ -237,7 +183,25 @@ class SearchBox extends Base {
if (this.filterList.length) {
return this.filterList[this.pointer];
}
return { value: this.userInput, name: this.userInput, short: this.userInput, disabled: false };
// other version:
//return this.list[this.pointer];
// TODO: evaluate these two different approaches
return {
value: this.userInput,
name: this.userInput,
short: this.userInput,
disabled: false,
};

// TODO: also, what's all this unreachable code?
/*this.filterList = this.list = choices
.filter(() => true) // fix slice is not a function
.map((item, id) => ({ ...item, id }));
// init default value
const index = this.filterList.findIndex((e) => {
return e.name === this.opt.default;
});
this.pointer = index > -1 ? index : 0;*/
}

getCurrentItemValue() {
Expand Down
Loading

0 comments on commit 37d0d34

Please sign in to comment.