You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							190 lines
						
					
					
						
							5.0 KiB
						
					
					
				
			
		
		
	
	
							190 lines
						
					
					
						
							5.0 KiB
						
					
					
				'use strict'; | 
						|
 | 
						|
const color = require('kleur'); | 
						|
 | 
						|
const Prompt = require('./prompt'); | 
						|
 | 
						|
const _require = require('../util'), | 
						|
      style = _require.style, | 
						|
      clear = _require.clear, | 
						|
      figures = _require.figures, | 
						|
      wrap = _require.wrap, | 
						|
      entriesToDisplay = _require.entriesToDisplay; | 
						|
 | 
						|
const _require2 = require('sisteransi'), | 
						|
      cursor = _require2.cursor; | 
						|
/** | 
						|
 * SelectPrompt Base Element | 
						|
 * @param {Object} opts Options | 
						|
 * @param {String} opts.message Message | 
						|
 * @param {Array} opts.choices Array of choice objects | 
						|
 * @param {String} [opts.hint] Hint to display | 
						|
 * @param {Number} [opts.initial] Index of default value | 
						|
 * @param {Stream} [opts.stdin] The Readable stream to listen to | 
						|
 * @param {Stream} [opts.stdout] The Writable stream to write readline data to | 
						|
 * @param {Number} [opts.optionsPerPage=10] Max options to display at once | 
						|
 */ | 
						|
 | 
						|
 | 
						|
class SelectPrompt extends Prompt { | 
						|
  constructor(opts = {}) { | 
						|
    super(opts); | 
						|
    this.msg = opts.message; | 
						|
    this.hint = opts.hint || '- Use arrow-keys. Return to submit.'; | 
						|
    this.warn = opts.warn || '- This option is disabled'; | 
						|
    this.cursor = opts.initial || 0; | 
						|
    this.choices = opts.choices.map((ch, idx) => { | 
						|
      if (typeof ch === 'string') ch = { | 
						|
        title: ch, | 
						|
        value: idx | 
						|
      }; | 
						|
      return { | 
						|
        title: ch && (ch.title || ch.value || ch), | 
						|
        value: ch && (ch.value === undefined ? idx : ch.value), | 
						|
        description: ch && ch.description, | 
						|
        selected: ch && ch.selected, | 
						|
        disabled: ch && ch.disabled | 
						|
      }; | 
						|
    }); | 
						|
    this.optionsPerPage = opts.optionsPerPage || 10; | 
						|
    this.value = (this.choices[this.cursor] || {}).value; | 
						|
    this.clear = clear('', this.out.columns); | 
						|
    this.render(); | 
						|
  } | 
						|
 | 
						|
  moveCursor(n) { | 
						|
    this.cursor = n; | 
						|
    this.value = this.choices[n].value; | 
						|
    this.fire(); | 
						|
  } | 
						|
 | 
						|
  reset() { | 
						|
    this.moveCursor(0); | 
						|
    this.fire(); | 
						|
    this.render(); | 
						|
  } | 
						|
 | 
						|
  exit() { | 
						|
    this.abort(); | 
						|
  } | 
						|
 | 
						|
  abort() { | 
						|
    this.done = this.aborted = true; | 
						|
    this.fire(); | 
						|
    this.render(); | 
						|
    this.out.write('\n'); | 
						|
    this.close(); | 
						|
  } | 
						|
 | 
						|
  submit() { | 
						|
    if (!this.selection.disabled) { | 
						|
      this.done = true; | 
						|
      this.aborted = false; | 
						|
      this.fire(); | 
						|
      this.render(); | 
						|
      this.out.write('\n'); | 
						|
      this.close(); | 
						|
    } else this.bell(); | 
						|
  } | 
						|
 | 
						|
  first() { | 
						|
    this.moveCursor(0); | 
						|
    this.render(); | 
						|
  } | 
						|
 | 
						|
  last() { | 
						|
    this.moveCursor(this.choices.length - 1); | 
						|
    this.render(); | 
						|
  } | 
						|
 | 
						|
  up() { | 
						|
    if (this.cursor === 0) { | 
						|
      this.moveCursor(this.choices.length - 1); | 
						|
    } else { | 
						|
      this.moveCursor(this.cursor - 1); | 
						|
    } | 
						|
 | 
						|
    this.render(); | 
						|
  } | 
						|
 | 
						|
  down() { | 
						|
    if (this.cursor === this.choices.length - 1) { | 
						|
      this.moveCursor(0); | 
						|
    } else { | 
						|
      this.moveCursor(this.cursor + 1); | 
						|
    } | 
						|
 | 
						|
    this.render(); | 
						|
  } | 
						|
 | 
						|
  next() { | 
						|
    this.moveCursor((this.cursor + 1) % this.choices.length); | 
						|
    this.render(); | 
						|
  } | 
						|
 | 
						|
  _(c, key) { | 
						|
    if (c === ' ') return this.submit(); | 
						|
  } | 
						|
 | 
						|
  get selection() { | 
						|
    return this.choices[this.cursor]; | 
						|
  } | 
						|
 | 
						|
  render() { | 
						|
    if (this.closed) return; | 
						|
    if (this.firstRender) this.out.write(cursor.hide);else this.out.write(clear(this.outputText, this.out.columns)); | 
						|
    super.render(); | 
						|
 | 
						|
    let _entriesToDisplay = entriesToDisplay(this.cursor, this.choices.length, this.optionsPerPage), | 
						|
        startIndex = _entriesToDisplay.startIndex, | 
						|
        endIndex = _entriesToDisplay.endIndex; // Print prompt | 
						|
 | 
						|
 | 
						|
    this.outputText = [style.symbol(this.done, this.aborted), color.bold(this.msg), style.delimiter(false), this.done ? this.selection.title : this.selection.disabled ? color.yellow(this.warn) : color.gray(this.hint)].join(' '); // Print choices | 
						|
 | 
						|
    if (!this.done) { | 
						|
      this.outputText += '\n'; | 
						|
 | 
						|
      for (let i = startIndex; i < endIndex; i++) { | 
						|
        let title, | 
						|
            prefix, | 
						|
            desc = '', | 
						|
            v = this.choices[i]; // Determine whether to display "more choices" indicators | 
						|
 | 
						|
        if (i === startIndex && startIndex > 0) { | 
						|
          prefix = figures.arrowUp; | 
						|
        } else if (i === endIndex - 1 && endIndex < this.choices.length) { | 
						|
          prefix = figures.arrowDown; | 
						|
        } else { | 
						|
          prefix = ' '; | 
						|
        } | 
						|
 | 
						|
        if (v.disabled) { | 
						|
          title = this.cursor === i ? color.gray().underline(v.title) : color.strikethrough().gray(v.title); | 
						|
          prefix = (this.cursor === i ? color.bold().gray(figures.pointer) + ' ' : '  ') + prefix; | 
						|
        } else { | 
						|
          title = this.cursor === i ? color.cyan().underline(v.title) : v.title; | 
						|
          prefix = (this.cursor === i ? color.cyan(figures.pointer) + ' ' : '  ') + prefix; | 
						|
 | 
						|
          if (v.description && this.cursor === i) { | 
						|
            desc = ` - ${v.description}`; | 
						|
 | 
						|
            if (prefix.length + title.length + desc.length >= this.out.columns || v.description.split(/\r?\n/).length > 1) { | 
						|
              desc = '\n' + wrap(v.description, { | 
						|
                margin: 3, | 
						|
                width: this.out.columns | 
						|
              }); | 
						|
            } | 
						|
          } | 
						|
        } | 
						|
 | 
						|
        this.outputText += `${prefix} ${title}${color.gray(desc)}\n`; | 
						|
      } | 
						|
    } | 
						|
 | 
						|
    this.out.write(this.outputText); | 
						|
  } | 
						|
 | 
						|
} | 
						|
 | 
						|
module.exports = SelectPrompt; |