| 41 | }; |
| 42 | |
| 43 | export const multiselect = <Value>(opts: MultiSelectOptions<Value>) => { |
| 44 | const opt = ( |
| 45 | option: Option<Value>, |
| 46 | state: |
| 47 | | 'inactive' |
| 48 | | 'active' |
| 49 | | 'selected' |
| 50 | | 'active-selected' |
| 51 | | 'submitted' |
| 52 | | 'cancelled' |
| 53 | | 'disabled' |
| 54 | ) => { |
| 55 | const label = option.label ?? String(option.value); |
| 56 | if (state === 'disabled') { |
| 57 | return `${styleText('gray', S_CHECKBOX_INACTIVE)} ${computeLabel(label, (str) => styleText(['strikethrough', 'gray'], str))}${ |
| 58 | option.hint ? ` ${styleText('dim', `(${option.hint ?? 'disabled'})`)}` : '' |
| 59 | }`; |
| 60 | } |
| 61 | if (state === 'active') { |
| 62 | return `${styleText('cyan', S_CHECKBOX_ACTIVE)} ${label}${ |
| 63 | option.hint ? ` ${styleText('dim', `(${option.hint})`)}` : '' |
| 64 | }`; |
| 65 | } |
| 66 | if (state === 'selected') { |
| 67 | return `${styleText('green', S_CHECKBOX_SELECTED)} ${computeLabel(label, (text) => styleText('dim', text))}${ |
| 68 | option.hint ? ` ${styleText('dim', `(${option.hint})`)}` : '' |
| 69 | }`; |
| 70 | } |
| 71 | if (state === 'cancelled') { |
| 72 | return `${computeLabel(label, (text) => styleText(['strikethrough', 'dim'], text))}`; |
| 73 | } |
| 74 | if (state === 'active-selected') { |
| 75 | return `${styleText('green', S_CHECKBOX_SELECTED)} ${label}${ |
| 76 | option.hint ? ` ${styleText('dim', `(${option.hint})`)}` : '' |
| 77 | }`; |
| 78 | } |
| 79 | if (state === 'submitted') { |
| 80 | return `${computeLabel(label, (text) => styleText('dim', text))}`; |
| 81 | } |
| 82 | return `${styleText('dim', S_CHECKBOX_INACTIVE)} ${computeLabel(label, (text) => styleText('dim', text))}`; |
| 83 | }; |
| 84 | const required = opts.required ?? true; |
| 85 | const showInstructions = opts.showInstructions ?? true; |
| 86 | |
| 87 | return new MultiSelectPrompt({ |
| 88 | options: opts.options, |
| 89 | signal: opts.signal, |
| 90 | input: opts.input, |
| 91 | output: opts.output, |
| 92 | initialValues: opts.initialValues, |
| 93 | required, |
| 94 | cursorAt: opts.cursorAt, |
| 95 | validate(selected: Value[] | undefined) { |
| 96 | if (required && (selected === undefined || selected.length === 0)) |
| 97 | return `Please select at least one option.\n${styleText( |
| 98 | 'reset', |
| 99 | styleText( |
| 100 | 'dim', |