Spaces:
Runtime error
Runtime error
; | |
const ArrayPrompt = require('../types/array'); | |
const utils = require('../utils'); | |
class SelectPrompt extends ArrayPrompt { | |
constructor(options) { | |
super(options); | |
this.emptyError = this.options.emptyError || 'No items were selected'; | |
} | |
async dispatch(s, key) { | |
if (this.multiple) { | |
return this[key.name] ? await this[key.name](s, key) : await super.dispatch(s, key); | |
} | |
this.alert(); | |
} | |
separator() { | |
if (this.options.separator) return super.separator(); | |
let sep = this.styles.muted(this.symbols.ellipsis); | |
return this.state.submitted ? super.separator() : sep; | |
} | |
pointer(choice, i) { | |
return (!this.multiple || this.options.pointer) ? super.pointer(choice, i) : ''; | |
} | |
indicator(choice, i) { | |
return this.multiple ? super.indicator(choice, i) : ''; | |
} | |
choiceMessage(choice, i) { | |
let message = this.resolve(choice.message, this.state, choice, i); | |
if (choice.role === 'heading' && !utils.hasColor(message)) { | |
message = this.styles.strong(message); | |
} | |
return this.resolve(message, this.state, choice, i); | |
} | |
choiceSeparator() { | |
return ':'; | |
} | |
async renderChoice(choice, i) { | |
await this.onChoice(choice, i); | |
let focused = this.index === i; | |
let pointer = await this.pointer(choice, i); | |
let check = await this.indicator(choice, i) + (choice.pad || ''); | |
let hint = await this.resolve(choice.hint, this.state, choice, i); | |
if (hint && !utils.hasColor(hint)) { | |
hint = this.styles.muted(hint); | |
} | |
let ind = this.indent(choice); | |
let msg = await this.choiceMessage(choice, i); | |
let line = () => [this.margin[3], ind + pointer + check, msg, this.margin[1], hint].filter(Boolean).join(' '); | |
if (choice.role === 'heading') { | |
return line(); | |
} | |
if (choice.disabled) { | |
if (!utils.hasColor(msg)) { | |
msg = this.styles.disabled(msg); | |
} | |
return line(); | |
} | |
if (focused) { | |
msg = this.styles.em(msg); | |
} | |
return line(); | |
} | |
async renderChoices() { | |
if (this.state.loading === 'choices') { | |
return this.styles.warning('Loading choices'); | |
} | |
if (this.state.submitted) return ''; | |
let choices = this.visible.map(async(ch, i) => await this.renderChoice(ch, i)); | |
let visible = await Promise.all(choices); | |
if (!visible.length) visible.push(this.styles.danger('No matching choices')); | |
let result = this.margin[0] + visible.join('\n'); | |
let header; | |
if (this.options.choicesHeader) { | |
header = await this.resolve(this.options.choicesHeader, this.state); | |
} | |
return [header, result].filter(Boolean).join('\n'); | |
} | |
format() { | |
if (!this.state.submitted || this.state.cancelled) return ''; | |
if (Array.isArray(this.selected)) { | |
return this.selected.map(choice => this.styles.primary(choice.name)).join(', '); | |
} | |
return this.styles.primary(this.selected.name); | |
} | |
async render() { | |
let { submitted, size } = this.state; | |
let prompt = ''; | |
let header = await this.header(); | |
let prefix = await this.prefix(); | |
let separator = await this.separator(); | |
let message = await this.message(); | |
if (this.options.promptLine !== false) { | |
prompt = [prefix, message, separator, ''].join(' '); | |
this.state.prompt = prompt; | |
} | |
let output = await this.format(); | |
let help = (await this.error()) || (await this.hint()); | |
let body = await this.renderChoices(); | |
let footer = await this.footer(); | |
if (output) prompt += output; | |
if (help && !prompt.includes(help)) prompt += ' ' + help; | |
if (submitted && !output && !body.trim() && this.multiple && this.emptyError != null) { | |
prompt += this.styles.danger(this.emptyError); | |
} | |
this.clear(size); | |
this.write([header, prompt, body, footer].filter(Boolean).join('\n')); | |
this.write(this.margin[2]); | |
this.restore(); | |
} | |
} | |
module.exports = SelectPrompt; | |