3 const Select = require('./select');
5 const highlight = (input, color) => {
6 let val = input.toLowerCase();
8 let s = str.toLowerCase();
9 let i = s.indexOf(val);
10 let colored = color(str.slice(i, i + val.length));
11 return i >= 0 ? str.slice(0, i) + colored + str.slice(i + val.length) : str;
15 class AutoComplete extends Select {
16 constructor(options) {
22 this.state.cursor += n;
26 return this.append(ch);
30 return this.options.multiple ? super.space(ch) : this.append(ch);
34 let { cursor, input } = this.state;
35 this.input = input.slice(0, cursor) + ch + input.slice(cursor);
37 return this.complete();
41 let { cursor, input } = this.state;
42 if (!input) return this.alert();
43 this.input = input.slice(0, cursor - 1) + input.slice(cursor);
45 return this.complete();
49 let { cursor, input } = this.state;
50 if (input[cursor] === void 0) return this.alert();
51 this.input = `${input}`.slice(0, cursor) + `${input}`.slice(cursor + 1);
52 return this.complete();
56 return this.append(ch);
60 this.completing = true;
61 this.choices = await this.suggest(this.input, this.state._choices);
62 this.state.limit = void 0; // allow getter/setter to reset limit
63 this.index = Math.min(Math.max(this.visible.length - 1, 0), this.index);
65 this.completing = false;
68 suggest(input = this.input, choices = this.state._choices) {
69 if (typeof this.options.suggest === 'function') {
70 return this.options.suggest.call(this, input, choices);
72 let str = input.toLowerCase();
73 return choices.filter(ch => ch.message.toLowerCase().includes(str));
81 if (!this.focused) return this.input;
82 if (this.options.multiple && this.state.submitted) {
83 return this.selected.map(ch => this.styles.primary(ch.message)).join(', ');
85 if (this.state.submitted) {
86 let value = this.value = this.input = this.focused.value;
87 return this.styles.primary(value);
93 if (this.state.status !== 'pending') return super.render();
94 let style = this.options.highlight
95 ? this.options.highlight.bind(this)
96 : this.styles.placeholder;
98 let color = highlight(this.input, style);
99 let choices = this.choices;
100 this.choices = choices.map(ch => ({ ...ch, message: color(ch.message) }));
101 await super.render();
102 this.choices = choices;
106 if (this.options.multiple) {
107 this.value = this.selected.map(ch => ch.name);
109 return super.submit();
113 module.exports = AutoComplete;