[READ-ONLY] Mirror of https://github.com/bombshell-dev/clack. Effortlessly build beautiful command-line apps bomb.sh/docs/clack/basics/getting-started/
cli command-line command-line-app node prompt prompts
5

Configure Feed

Select the types of activity you want to include in your feed.

chore: type

Simon He (Nov 14, 2024, 5:00 PM +0800) 1d855b3b 06e90242

+21 -14
+14 -7
packages/core/src/prompts/search.ts
··· 1 1 import fuzzy from 'fuzzy'; 2 2 import Prompt, { PromptOptions } from './prompt'; 3 - interface SearchOptions<T extends { value: any; label?: string }> 4 - extends PromptOptions<SearchPrompt<T>> { 3 + interface SearchOptions<T extends { value: any; label?: string }, MaxItems extends number> 4 + extends PromptOptions<SearchPrompt<T, MaxItems>> { 5 5 options: T[]; 6 6 initialValue?: T['value']; 7 - maxItems?: number; 7 + maxItems?: MaxItems; 8 8 } 9 9 export default class SearchPrompt< 10 10 T extends { value: any; label?: string; isSelected?: boolean }, 11 + MaxItems extends number, 11 12 > extends Prompt { 12 13 options: T[]; 13 14 valueWithCursor = ''; 14 15 15 16 selectCursor = 0; 16 17 inputCursor = 0; 17 - maxItems = 1; 18 + maxItems: MaxItems; 18 19 selected: T[] = []; 20 + 21 + value: T['value'] | T['value'][] = ''; 19 22 private get _value() { 20 23 return this.options[this.selectCursor]; 21 24 } ··· 24 27 this.value = this._value?.value; 25 28 } 26 29 27 - constructor(opts: SearchOptions<T>) { 30 + constructor(opts: SearchOptions<T, any>) { 28 31 super(opts, false); 29 32 this.options = opts.options; 30 33 this.maxItems = opts.maxItems || 1; ··· 67 70 }); 68 71 69 72 this.on('finalize', () => { 70 - this.value = this.selected.map((item) => item.value); 73 + this.value = this.selected.length 74 + ? this.selected.map((item) => item.value) 75 + : this.maxItems > 1 76 + ? [this.options[this.selectCursor].value] 77 + : this.options[this.selectCursor].value; 71 78 }); 72 79 73 80 this.on('cursor', (key) => { ··· 90 97 this.changeValue(); 91 98 }); 92 99 } 93 - fuzzyFilter(opts: SearchOptions<T>) { 100 + fuzzyFilter(opts: SearchOptions<T, MaxItems>) { 94 101 const fuzzyOptions = fuzzy.filter(this.valueWithCursor, opts.options, { 95 102 extract: ({ label, value }) => label || value, 96 103 });
+7 -7
packages/prompts/src/index.ts
··· 403 403 return this.selected.some((item) => item.value === option.value) 404 404 ? 'selected' 405 405 : i === this.selectCursor 406 - ? 'group-active' 407 - : 'group-inactive'; 406 + ? 'group-active' 407 + : 'group-inactive'; 408 408 } 409 409 if (i === this.selectCursor) { 410 410 return this.selected.some((item) => item.value === option.value) ··· 414 414 return this.selected.some((item) => item.value === option.value) 415 415 ? 'selected' 416 416 : i === this.selectCursor 417 - ? 'active' 418 - : 'inactive'; 417 + ? 'active' 418 + : 'inactive'; 419 419 }; 420 420 return `${title}${color.cyan(S_BAR)}\n${color.cyan(S_INFO)} ${value}\n${color.cyan( 421 421 S_BAR ··· 425 425 } 426 426 } 427 427 }, 428 - }).prompt() as Promise<Value | symbol>; 428 + }).prompt() as Promise<MaxItems extends 1 ? Value | symbol : (Value | symbol)[]>; 429 429 }; 430 430 431 431 export interface MultiSelectOptions<Value> { ··· 819 819 code === 0 820 820 ? color.green(S_STEP_SUBMIT) 821 821 : code === 1 822 - ? color.red(S_STEP_CANCEL) 823 - : color.red(S_STEP_ERROR); 822 + ? color.red(S_STEP_CANCEL) 823 + : color.red(S_STEP_ERROR); 824 824 process.stdout.write(cursor.move(-999, 0)); 825 825 process.stdout.write(erase.down(1)); 826 826 process.stdout.write(`${step} ${_message}\n`);