source: trip-planner-front/node_modules/inquirer/lib/prompts/rawlist.js@ 6c1585f

Last change on this file since 6c1585f was 6a3a178, checked in by Ema <ema_spirova@…>, 3 years ago

initial commit

  • Property mode set to 100644
File size: 5.0 KB
Line 
1'use strict';
2/**
3 * `rawlist` type prompt
4 */
5
6const _ = {
7 extend: require('lodash/extend'),
8 isNumber: require('lodash/isNumber'),
9 findIndex: require('lodash/findIndex'),
10};
11const chalk = require('chalk');
12const { map, takeUntil } = require('rxjs/operators');
13const Base = require('./base');
14const Separator = require('../objects/separator');
15const observe = require('../utils/events');
16const Paginator = require('../utils/paginator');
17const incrementListIndex = require('../utils/incrementListIndex');
18
19class RawListPrompt extends Base {
20 constructor(questions, rl, answers) {
21 super(questions, rl, answers);
22
23 if (!this.opt.choices) {
24 this.throwParamError('choices');
25 }
26
27 this.opt.validChoices = this.opt.choices.filter(Separator.exclude);
28
29 this.selected = 0;
30 this.rawDefault = 0;
31
32 _.extend(this.opt, {
33 validate(val) {
34 return val != null;
35 },
36 });
37
38 const def = this.opt.default;
39 if (_.isNumber(def) && def >= 0 && def < this.opt.choices.realLength) {
40 this.selected = def;
41 this.rawDefault = def;
42 } else if (!_.isNumber(def) && def != null) {
43 const index = _.findIndex(
44 this.opt.choices.realChoices,
45 ({ value }) => value === def
46 );
47 const safeIndex = Math.max(index, 0);
48 this.selected = safeIndex;
49 this.rawDefault = safeIndex;
50 }
51
52 // Make sure no default is set (so it won't be printed)
53 this.opt.default = null;
54
55 const shouldLoop = this.opt.loop === undefined ? true : this.opt.loop;
56 this.paginator = new Paginator(undefined, { isInfinite: shouldLoop });
57 }
58
59 /**
60 * Start the Inquiry session
61 * @param {Function} cb Callback when prompt is done
62 * @return {this}
63 */
64
65 _run(cb) {
66 this.done = cb;
67
68 // Once user confirm (enter key)
69 const events = observe(this.rl);
70 const submit = events.line.pipe(map(this.getCurrentValue.bind(this)));
71
72 const validation = this.handleSubmitEvents(submit);
73 validation.success.forEach(this.onEnd.bind(this));
74 validation.error.forEach(this.onError.bind(this));
75
76 events.normalizedUpKey
77 .pipe(takeUntil(validation.success))
78 .forEach(this.onUpKey.bind(this));
79 events.normalizedDownKey
80 .pipe(takeUntil(validation.success))
81 .forEach(this.onDownKey.bind(this));
82 events.keypress
83 .pipe(takeUntil(validation.success))
84 .forEach(this.onKeypress.bind(this));
85 // Init the prompt
86 this.render();
87
88 return this;
89 }
90
91 /**
92 * Render the prompt to screen
93 * @return {RawListPrompt} self
94 */
95
96 render(error) {
97 // Render question
98 let message = this.getQuestion();
99 let bottomContent = '';
100
101 if (this.status === 'answered') {
102 message += chalk.cyan(this.opt.choices.getChoice(this.selected).short);
103 } else {
104 const choicesStr = renderChoices(this.opt.choices, this.selected);
105 message +=
106 '\n' + this.paginator.paginate(choicesStr, this.selected, this.opt.pageSize);
107 message += '\n Answer: ';
108 }
109 message += this.rl.line;
110
111 if (error) {
112 bottomContent = '\n' + chalk.red('>> ') + error;
113 }
114
115 this.screen.render(message, bottomContent);
116 }
117
118 /**
119 * When user press `enter` key
120 */
121
122 getCurrentValue(index) {
123 if (index == null) {
124 index = this.rawDefault;
125 } else if (index === '') {
126 index = this.selected;
127 } else {
128 index -= 1;
129 }
130
131 const choice = this.opt.choices.getChoice(index);
132 return choice ? choice.value : null;
133 }
134
135 onEnd(state) {
136 this.status = 'answered';
137 this.answer = state.value;
138
139 // Re-render prompt
140 this.render();
141
142 this.screen.done();
143 this.done(state.value);
144 }
145
146 onError() {
147 this.render('Please enter a valid index');
148 }
149
150 /**
151 * When user press a key
152 */
153
154 onKeypress() {
155 const index = this.rl.line.length ? Number(this.rl.line) - 1 : 0;
156
157 if (this.opt.choices.getChoice(index)) {
158 this.selected = index;
159 } else {
160 this.selected = undefined;
161 }
162 this.render();
163 }
164
165 /**
166 * When user press up key
167 */
168
169 onUpKey() {
170 this.onArrowKey('up');
171 }
172
173 /**
174 * When user press down key
175 */
176
177 onDownKey() {
178 this.onArrowKey('down');
179 }
180
181 /**
182 * When user press up or down key
183 * @param {String} type Arrow type: up or down
184 */
185
186 onArrowKey(type) {
187 this.selected = incrementListIndex(this.selected, type, this.opt);
188 this.rl.line = String(this.selected + 1);
189 }
190}
191
192/**
193 * Function for rendering list choices
194 * @param {Number} pointer Position of the pointer
195 * @return {String} Rendered content
196 */
197
198function renderChoices(choices, pointer) {
199 let output = '';
200 let separatorOffset = 0;
201
202 choices.forEach((choice, i) => {
203 output += '\n ';
204
205 if (choice.type === 'separator') {
206 separatorOffset++;
207 output += ' ' + choice;
208 return;
209 }
210
211 const index = i - separatorOffset;
212 let display = index + 1 + ') ' + choice.name;
213 if (index === pointer) {
214 display = chalk.cyan(display);
215 }
216
217 output += display;
218 });
219
220 return output;
221}
222
223module.exports = RawListPrompt;
Note: See TracBrowser for help on using the repository browser.