prompt-choices
Advanced tools
Comparing version 0.3.2 to 0.4.0
172
index.js
'use strict'; | ||
var toggleArray = require('toggle-array'); | ||
var Separator = require('choices-separator'); | ||
var debug = require('debug')('prompt-choices'); | ||
var Choice = require('./lib/choice'); | ||
var utils = require('./lib/utils'); | ||
var Move = require('./lib/move'); | ||
@@ -19,9 +19,13 @@ /** | ||
function Choices(choices, answers) { | ||
function Choices(choices, options) { | ||
debug('initializing from <%s>', __filename); | ||
if (utils.isObject(choices) && choices.isChoices) { | ||
return choices; | ||
} | ||
this.options = options || {}; | ||
utils.define(this, 'isChoices', true); | ||
utils.define(this, 'answers', answers || {}); | ||
this.original = utils.arrayify(choices).slice(); | ||
utils.define(this, 'answers', this.options.answers || {}); | ||
this.paginator = new utils.Paginator(this.options); | ||
this.original = utils.clone(choices); | ||
this.choices = []; | ||
this.keymap = {}; | ||
@@ -34,2 +38,30 @@ this.items = []; | ||
/** | ||
* Render the current choices. | ||
* | ||
* @param {Number} `position` Cursor position | ||
* @param {Object} `options` | ||
* @return {String} | ||
* @api public | ||
*/ | ||
Choices.prototype.render = function(position, options) { | ||
var opts = utils.extend({}, this.options, options); | ||
var len = this.choices.length; | ||
var num = opts.limit || 7; | ||
var idx = -1; | ||
var buf = ''; | ||
position = position || 0; | ||
while (++idx < len) { | ||
buf += this.choices[idx].render(position); | ||
} | ||
var str = '\n' + buf.replace(/\n$/, ''); | ||
if (len > num && opts.paginate) { | ||
return this.paginator.paginate(str, position, num); | ||
} | ||
return str; | ||
}; | ||
/** | ||
* Add an array of normalized `choice` objects to the `choices` array. This | ||
@@ -50,3 +82,3 @@ * method is called in the constructor, but it can also be used to add | ||
var idx = -1; | ||
var i = 0; | ||
while (++idx < len) { | ||
@@ -56,12 +88,18 @@ var choice = choices[idx]; | ||
if (!choice.isSeparator) { | ||
choice = new Separator(choice.line); | ||
choice = new utils.Separator(choice.line); | ||
} | ||
} else if (choice.disabled) { | ||
choice = this.choice(choice); | ||
} else { | ||
choice = this.choice(choice); | ||
var key = choice.key || choice.name; | ||
this.keymap[key] = choice; | ||
this.keys.push(key); | ||
choice.index = i; | ||
i++; | ||
this.keymap[choice.key] = choice; | ||
this.keys.push(choice.key); | ||
this.items.push(choice); | ||
} | ||
// push normalized "choice" object onto array | ||
this.push(choice); | ||
this.choices.push(choice); | ||
} | ||
@@ -82,3 +120,3 @@ }; | ||
Choices.prototype.choice = function(choice) { | ||
return new Choice(choice, this.answers); | ||
return new Choice(choice, this.options); | ||
}; | ||
@@ -98,3 +136,3 @@ | ||
Choices.prototype.separator = function(separator, options) { | ||
return new Separator(separator, options); | ||
return new utils.Separator(separator, options); | ||
}; | ||
@@ -114,8 +152,6 @@ | ||
Choices.prototype.getChoice = function(idx) { | ||
if (utils.isNumber(idx) && idx !== ' ') { | ||
return this.realChoices[idx]; | ||
} | ||
if (typeof idx === 'string') { | ||
return this.keymap[idx]; | ||
idx = this.getIndex(idx); | ||
} | ||
return this.items[idx]; | ||
}; | ||
@@ -135,3 +171,3 @@ | ||
Choices.prototype.getIndex = function(key) { | ||
if (utils.isNumber(key) && key !== -1 && key < this.realLength) { | ||
if (utils.isNumber(key) && key !== -1 && key < this.items.length) { | ||
return key; | ||
@@ -174,3 +210,3 @@ } | ||
Choices.prototype.enable = function(idx) { | ||
this.getChoice(idx).checked = true; | ||
this.getChoice(idx).enable('checked'); | ||
return this; | ||
@@ -190,3 +226,3 @@ }; | ||
Choices.prototype.disable = function(idx) { | ||
this.getChoice(idx).checked = false; | ||
this.getChoice(idx).disable('checked'); | ||
return this; | ||
@@ -196,21 +232,8 @@ }; | ||
/** | ||
* Enable the choice at the given `index`, and disable all other choices. | ||
* | ||
* ```js | ||
* choices.toggleChoices(1); | ||
* ``` | ||
* @param {Number} `idx` The index of the choice to toggle. | ||
* @api public | ||
*/ | ||
Choices.prototype.toggleChoices = function(idx) { | ||
toggleArray(this.items, 'checked', idx); | ||
return this; | ||
}; | ||
/** | ||
* Toggle the choice at the given `idx`. | ||
* | ||
* ```js | ||
* choices.toggleChoice(1); | ||
* choices.toggle(1); | ||
* // radio mode | ||
* choices.toggle(1, true); | ||
* ``` | ||
@@ -221,5 +244,8 @@ * @param {Number} `idx` The index of the choice to toggle. | ||
Choices.prototype.toggleChoice = function(idx) { | ||
var checked = this.getChoice(idx).checked; | ||
this.getChoice(idx).checked = !checked; | ||
Choices.prototype.toggle = function(idx, radio) { | ||
if (radio) { | ||
utils.toggleArray(this.items, 'checked', idx); | ||
} else { | ||
this.items[idx].toggle(); | ||
} | ||
return this; | ||
@@ -237,3 +263,3 @@ }; | ||
Choices.prototype.where = function(val) { | ||
return this.realChoices.filter(function(choice) { | ||
return this.items.filter(function(choice) { | ||
if (typeof val === 'function') { | ||
@@ -273,3 +299,3 @@ return val(choice); | ||
Choices.prototype.pluck = function(key) { | ||
return this.realChoices.map(function(choice) { | ||
return this.items.map(function(choice) { | ||
return choice[key]; | ||
@@ -295,17 +321,2 @@ }); | ||
Choices.prototype.push = function() { | ||
var choices = utils.flatten([].slice.call(arguments)); | ||
var len = choices.length; | ||
var idx = -1; | ||
while (++idx < len) { | ||
var choice = choices[idx]; | ||
this.items.push(new Choice(choice)); | ||
if (choice.type !== 'separator') { | ||
this.realChoices.push(choice); | ||
} | ||
} | ||
return this.items; | ||
}; | ||
/** | ||
@@ -317,46 +328,33 @@ * Getter for getting the length of the collection. | ||
Object.defineProperty(Choices.prototype, 'length', { | ||
Object.defineProperty(Choices.prototype, 'checked', { | ||
set: function() { | ||
throw new Error('.length is a getter and cannot be defined'); | ||
throw new Error('.checked is a getter and cannot be defined'); | ||
}, | ||
get: function() { | ||
return this.items.length; | ||
return this.items.reduce(function(acc, choice) { | ||
if (choice.checked === true) { | ||
acc.push(choice.value); | ||
} | ||
return acc; | ||
}, []); | ||
} | ||
}); | ||
/** | ||
* Getter for getting all non-separator choices from the collection. | ||
* @name .realChoices | ||
* @api public | ||
*/ | ||
Object.defineProperty(Choices.prototype, 'realChoices', { | ||
Object.defineProperty(Choices.prototype, 'length', { | ||
set: function() { | ||
throw new Error('.realChoices is a getter and cannot be defined'); | ||
throw new Error('.length is a getter and cannot be defined'); | ||
}, | ||
get: function() { | ||
var choices = []; | ||
var idx = -1; | ||
while (++idx < this.length) { | ||
var choice = this.items[idx]; | ||
if (choice.type !== 'separator' && !choice.disabled) { | ||
choices.push(choice); | ||
} | ||
} | ||
return choices; | ||
return this.items.length; | ||
} | ||
}); | ||
/** | ||
* Getter for getting the length of the collection excluding non-separator choices. | ||
* @name .realLength | ||
* @api public | ||
*/ | ||
Object.defineProperty(Choices.prototype, 'realLength', { | ||
set: function() { | ||
throw new Error('.realLength is a getter and cannot be defined'); | ||
Object.defineProperty(Choices.prototype, 'move', { | ||
set: function(move) { | ||
utils.define(this, '_move', move); | ||
}, | ||
get: function() { | ||
return this.realChoices.length; | ||
if (this._move) return this._move; | ||
utils.define(this, '_move', new Move(this, this.options)); | ||
return this._move; | ||
} | ||
@@ -376,3 +374,3 @@ }); | ||
Choices.Separator = Separator; | ||
Choices.Separator = utils.Separator; | ||
@@ -379,0 +377,0 @@ /** |
'use strict'; | ||
var util = require('util'); | ||
var log = require('log-utils'); | ||
var radio = require('radio-symbol'); | ||
var utils = require('./utils'); | ||
@@ -12,11 +13,9 @@ | ||
function Choice(choice, answers) { | ||
function Choice(choice, options) { | ||
if (typeof choice === 'string') { | ||
choice = { name: choice }; | ||
} | ||
if (!utils.isObject(choice)) { | ||
throw new TypeError('expected choice to be a string or object'); | ||
} | ||
if (choice.type === 'separator' || choice.isSeparator) { | ||
@@ -26,10 +25,24 @@ choice.isSeparator = true; | ||
} | ||
if (choice.isChoice || choice instanceof Choice) { | ||
return choice; | ||
} | ||
this.initChoice(choice, options); | ||
} | ||
/** | ||
* Initialize choice. | ||
* @param {Object} `choice` | ||
* @param {Object} `options` | ||
*/ | ||
Choice.prototype.initChoice = function(choice, options) { | ||
utils.define(this, 'isChoice', true); | ||
this.name = null; | ||
this.short = null; | ||
this.value = null; | ||
this.disabled = false; | ||
this.checked = false; | ||
utils.define(this, 'position', 0); | ||
utils.define(this, 'index', 0); | ||
utils.define(this, 'options', options || {}); | ||
@@ -39,12 +52,110 @@ utils.extend(this, choice); | ||
this.value = choice.hasOwnProperty('value') ? choice.value : choice.name; | ||
this.short = this.alias = (choice.short || choice.name); | ||
this.short = choice.short || choice.name; | ||
utils.define(this, 'key', this.key || this.short); | ||
if (typeof choice.disabled === 'function') { | ||
this.disabled = !!choice.disabled.call(this, answers); | ||
} else { | ||
this.disabled = !!choice.disabled; | ||
if (!this.options.hasOwnProperty('pointer')) { | ||
this.options.pointer = log.cyan(utils.pointer(this.options)); | ||
} | ||
}; | ||
Choice.prototype.render = function(idx) { | ||
if (this.type === 'separator') { | ||
return this.value || ' ---\n'; | ||
} | ||
this.position = idx; | ||
return this.line; | ||
}; | ||
Choice.prototype.toggle = function() { | ||
this.checked = !this.checked; | ||
return this; | ||
}; | ||
Choice.prototype.enable = function(prop) { | ||
utils.set(this, prop, true); | ||
return this; | ||
}; | ||
Choice.prototype.disable = function(prop) { | ||
utils.set(this, prop, false); | ||
return this; | ||
}; | ||
Choice.prototype.format = function(str) { | ||
if (typeof this.options.format === 'function') { | ||
str = this.options.format.call(this, str); | ||
} | ||
return this.disabled ? log.gray(str) : str; | ||
}; | ||
Object.defineProperty(Choice.prototype, 'prefix', { | ||
set: function(val) { | ||
utils.define(this, '_pointer', val); | ||
}, | ||
get: function() { | ||
var val = typeof this._pointer === 'string' ? this._pointer : this.options.pointer; | ||
return this.position === this.index ? val : ' '; | ||
} | ||
}); | ||
Object.defineProperty(Choice.prototype, 'symbol', { | ||
set: function() { | ||
throw new Error('.symbol is a getter and cannot be defined'); | ||
}, | ||
get: function() { | ||
if (typeof this.options.symbol === 'string') { | ||
return this.options.symbol; | ||
} | ||
return this.disabled ? radio.disabled : (this.checked ? radio.on : radio.off); | ||
} | ||
}); | ||
/** | ||
* Getter for getting the line to render for a choice | ||
* @name .line | ||
* @api public | ||
*/ | ||
Object.defineProperty(Choice.prototype, 'line', { | ||
set: function() { | ||
throw new Error('.line is a getter and cannot be defined'); | ||
}, | ||
get: function() { | ||
var val = this.value; | ||
if (typeof this.disabled === 'string') { | ||
this._pointer = ' '; | ||
val += ` (${this.disabled})`; | ||
} else if (this.disabled === true) { | ||
this._pointer = ' '; | ||
val += ` (Disabled)`; | ||
} | ||
return this.prefix + this.symbol + ' ' + this.format(val) + '\n'; | ||
} | ||
}); | ||
/** | ||
* Getter for getting the line to render for a choice | ||
* @name .line | ||
* @api public | ||
*/ | ||
Object.defineProperty(Choice.prototype, 'disabled', { | ||
enumerable: true, | ||
set: function(disabled) { | ||
utils.define(this, '_disabled', disabled); | ||
}, | ||
get: function() { | ||
if (typeof this._disabled === 'function') { | ||
return this._disabled.call(this, this.options.answers); | ||
} | ||
return this._disabled; | ||
} | ||
}); | ||
function disabled(choice) { | ||
var symbol = process.platform === 'win32' ? ' (×) ' : ' ⓧ '; | ||
return log.dim(symbol + choice.name + ' (' + (choice.disabled || 'Disabled') + ')'); | ||
} | ||
/** | ||
* Expose Choice | ||
@@ -51,0 +162,0 @@ */ |
@@ -13,7 +13,29 @@ 'use strict'; | ||
require('arr-flatten', 'flatten'); | ||
require('clone-deep', 'clone'); | ||
require('choices-separator', 'Separator'); | ||
require('define-property', 'define'); | ||
require('extend-shallow', 'extend'); | ||
require('isobject', 'isObject'); | ||
require('terminal-paginator', 'Paginator'); | ||
require('toggle-array'); | ||
require('set-value', 'set'); | ||
require = fn; | ||
// todo: see if there is a better option for linux | ||
utils.pointer = function(options) { | ||
if (options && typeof options.pointer === 'string') { | ||
return options.pointer.trim(); | ||
} | ||
var small = options && options.small; | ||
switch(process.platform) { | ||
case 'win32': | ||
return small ? '»' : '>'; | ||
case 'linux': | ||
return small ? '‣' : '‣'; | ||
default: { | ||
return small ? '›' : '❯'; | ||
} | ||
} | ||
}; | ||
/** | ||
@@ -20,0 +42,0 @@ * Returns true if `val` is a number (also ensures that val |
{ | ||
"name": "prompt-choices", | ||
"description": "Create an array of multiple choice objects for use in prompts.", | ||
"version": "0.3.2", | ||
"version": "0.4.0", | ||
"homepage": "https://github.com/enquirer/prompt-choices", | ||
@@ -14,5 +14,3 @@ "author": "Jon Schlinkert (https://github.com/jonschlinkert)", | ||
"index.js", | ||
"lib", | ||
"LICENSE", | ||
"README.md" | ||
"lib" | ||
], | ||
@@ -28,8 +26,14 @@ "main": "index.js", | ||
"arr-flatten": "^1.0.1", | ||
"choices-separator": "^0.1.0", | ||
"choices-separator": "^0.1.2", | ||
"clone-deep": "^0.2.4", | ||
"debug": "^2.2.0", | ||
"define-property": "^0.2.5", | ||
"extend-shallow": "^2.0.1", | ||
"is-number": "^2.1.0", | ||
"is-number": "^3.0.0", | ||
"isobject": "^2.1.0", | ||
"lazy-cache": "^2.0.1", | ||
"log-utils": "^0.2.1", | ||
"radio-symbol": "^0.2.1", | ||
"set-value": "^0.4.0", | ||
"terminal-paginator": "^0.2.0", | ||
"toggle-array": "^0.1.0" | ||
@@ -41,3 +45,3 @@ }, | ||
"gulp-format-md": "^0.1.10", | ||
"gulp-istanbul": "^1.1.0", | ||
"gulp-istanbul": "^1.1.1", | ||
"gulp-mocha": "^3.0.1", | ||
@@ -44,0 +48,0 @@ "gulp-unused": "^0.2.0", |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
23083
7
541
14
+ Addedclone-deep@^0.2.4
+ Addeddebug@^2.2.0
+ Addedlog-utils@^0.2.1
+ Addedradio-symbol@^0.2.1
+ Addedset-value@^0.4.0
+ Addedterminal-paginator@^0.2.0
+ Addedansi-bgblack@0.1.1(transitive)
+ Addedansi-bgblue@0.1.1(transitive)
+ Addedansi-bgcyan@0.1.1(transitive)
+ Addedansi-bggreen@0.1.1(transitive)
+ Addedansi-bgmagenta@0.1.1(transitive)
+ Addedansi-bgred@0.1.1(transitive)
+ Addedansi-bgwhite@0.1.1(transitive)
+ Addedansi-bgyellow@0.1.1(transitive)
+ Addedansi-black@0.1.1(transitive)
+ Addedansi-blue@0.1.1(transitive)
+ Addedansi-bold@0.1.1(transitive)
+ Addedansi-colors@0.2.0(transitive)
+ Addedansi-cyan@0.1.1(transitive)
+ Addedansi-dim@0.1.1(transitive)
+ Addedansi-green@0.1.1(transitive)
+ Addedansi-grey@0.1.1(transitive)
+ Addedansi-hidden@0.1.1(transitive)
+ Addedansi-inverse@0.1.1(transitive)
+ Addedansi-italic@0.1.1(transitive)
+ Addedansi-magenta@0.1.1(transitive)
+ Addedansi-red@0.1.1(transitive)
+ Addedansi-reset@0.1.1(transitive)
+ Addedansi-strikethrough@0.1.1(transitive)
+ Addedansi-underline@0.1.1(transitive)
+ Addedansi-white@0.1.1(transitive)
+ Addedansi-yellow@0.1.1(transitive)
+ Addedclone-deep@0.2.4(transitive)
+ Addederror-symbol@0.1.0(transitive)
+ Addedfor-in@0.1.81.0.2(transitive)
+ Addedfor-own@0.1.5(transitive)
+ Addedinfo-symbol@0.1.0(transitive)
+ Addedis-number@3.0.0(transitive)
+ Addedis-plain-object@2.0.4(transitive)
+ Addedis-windows@1.0.2(transitive)
+ Addedisobject@3.0.1(transitive)
+ Addedkind-of@2.0.1(transitive)
+ Addedlazy-cache@0.2.71.0.4(transitive)
+ Addedlog-ok@0.1.1(transitive)
+ Addedlog-utils@0.2.1(transitive)
+ Addedmixin-object@2.0.1(transitive)
+ Addedradio-symbol@0.2.3(transitive)
+ Addedset-value@0.4.3(transitive)
+ Addedshallow-clone@0.1.2(transitive)
+ Addedsuccess-symbol@0.1.0(transitive)
+ Addedterminal-paginator@0.2.2(transitive)
+ Addedtime-stamp@1.1.0(transitive)
+ Addedwarning-symbol@0.1.0(transitive)
- Removedis-number@2.1.0(transitive)
Updatedchoices-separator@^0.1.2
Updatedis-number@^3.0.0