| 11 | } |
| 12 | |
| 13 | export const selectKey = <Value extends string>(opts: SelectKeyOptions<Value>) => { |
| 14 | const opt = ( |
| 15 | option: Option<Value>, |
| 16 | state: 'inactive' | 'active' | 'selected' | 'cancelled' = 'inactive' |
| 17 | ) => { |
| 18 | const label = option.label ?? String(option.value); |
| 19 | if (state === 'selected') { |
| 20 | return `${styleText('dim', label)}`; |
| 21 | } |
| 22 | if (state === 'cancelled') { |
| 23 | return `${styleText(['strikethrough', 'dim'], label)}`; |
| 24 | } |
| 25 | if (state === 'active') { |
| 26 | return `${styleText(['bgCyan', 'gray'], ` ${option.value} `)} ${label}${ |
| 27 | option.hint ? ` ${styleText('dim', `(${option.hint})`)}` : '' |
| 28 | }`; |
| 29 | } |
| 30 | return `${styleText(['gray', 'bgWhite', 'inverse'], ` ${option.value} `)} ${label}${ |
| 31 | option.hint ? ` ${styleText('dim', `(${option.hint})`)}` : '' |
| 32 | }`; |
| 33 | }; |
| 34 | |
| 35 | return new SelectKeyPrompt({ |
| 36 | options: opts.options, |
| 37 | signal: opts.signal, |
| 38 | input: opts.input, |
| 39 | output: opts.output, |
| 40 | initialValue: opts.initialValue, |
| 41 | caseSensitive: opts.caseSensitive, |
| 42 | render() { |
| 43 | const hasGuide = opts.withGuide ?? settings.withGuide; |
| 44 | const title = `${hasGuide ? `${styleText('gray', S_BAR)}\n` : ''}${symbol(this.state)} ${opts.message}\n`; |
| 45 | |
| 46 | switch (this.state) { |
| 47 | case 'submit': { |
| 48 | const submitPrefix = hasGuide ? `${styleText('gray', S_BAR)} ` : ''; |
| 49 | const selectedOption = |
| 50 | this.options.find((opt) => opt.value === this.value) ?? opts.options[0]; |
| 51 | const wrapped = wrapTextWithPrefix( |
| 52 | opts.output, |
| 53 | opt(selectedOption, 'selected'), |
| 54 | submitPrefix |
| 55 | ); |
| 56 | return `${title}${wrapped}`; |
| 57 | } |
| 58 | case 'cancel': { |
| 59 | const cancelPrefix = hasGuide ? `${styleText('gray', S_BAR)} ` : ''; |
| 60 | const wrapped = wrapTextWithPrefix( |
| 61 | opts.output, |
| 62 | opt(this.options[0], 'cancelled'), |
| 63 | cancelPrefix |
| 64 | ); |
| 65 | return `${title}${wrapped}${hasGuide ? `\n${styleText('gray', S_BAR)}` : ''}`; |
| 66 | } |
| 67 | default: { |
| 68 | const defaultPrefix = hasGuide ? `${styleText('cyan', S_BAR)} ` : ''; |
| 69 | const defaultPrefixEnd = hasGuide ? styleText('cyan', S_BAR_END) : ''; |
| 70 | const wrapped = this.options |