(opts: AutocompleteMultiSelectOptions<Value>)
| 304 | * ``` |
| 305 | */ |
| 306 | export const autocompleteMultiselect = <Value>(opts: AutocompleteMultiSelectOptions<Value>) => { |
| 307 | const formatOption = ( |
| 308 | option: Option<Value>, |
| 309 | active: boolean, |
| 310 | selectedValues: Value[], |
| 311 | focusedValue: Value | undefined |
| 312 | ) => { |
| 313 | const isSelected = selectedValues.includes(option.value); |
| 314 | const label = option.label ?? String(option.value ?? ''); |
| 315 | const hint = |
| 316 | option.hint && focusedValue !== undefined && option.value === focusedValue |
| 317 | ? styleText('dim', ` (${option.hint})`) |
| 318 | : ''; |
| 319 | const checkbox = isSelected |
| 320 | ? styleText('green', S_CHECKBOX_SELECTED) |
| 321 | : styleText('dim', S_CHECKBOX_INACTIVE); |
| 322 | |
| 323 | if (option.disabled) { |
| 324 | return `${styleText('gray', S_CHECKBOX_INACTIVE)} ${styleText(['strikethrough', 'gray'], label)}`; |
| 325 | } |
| 326 | if (active) { |
| 327 | return `${checkbox} ${label}${hint}`; |
| 328 | } |
| 329 | return `${checkbox} ${styleText('dim', label)}`; |
| 330 | }; |
| 331 | |
| 332 | // Create text prompt which we'll use as foundation |
| 333 | const prompt = new AutocompletePrompt<Option<Value>>({ |
| 334 | options: opts.options, |
| 335 | multiple: true, |
| 336 | placeholder: opts.placeholder, |
| 337 | filter: |
| 338 | opts.filter ?? |
| 339 | ((search, opt) => { |
| 340 | return getFilteredOption(search, opt); |
| 341 | }), |
| 342 | validate: () => { |
| 343 | if (opts.required && prompt.selectedValues.length === 0) { |
| 344 | return 'Please select at least one item'; |
| 345 | } |
| 346 | return undefined; |
| 347 | }, |
| 348 | initialValue: opts.initialValues, |
| 349 | signal: opts.signal, |
| 350 | input: opts.input, |
| 351 | output: opts.output, |
| 352 | render() { |
| 353 | const hasGuide = opts.withGuide ?? settings.withGuide; |
| 354 | // Title and symbol |
| 355 | const title = `${hasGuide ? `${styleText('gray', S_BAR)}\n` : ''}${symbol(this.state)} ${ |
| 356 | opts.message |
| 357 | }\n`; |
| 358 | |
| 359 | // Selection counter |
| 360 | const userInput = this.userInput; |
| 361 | const placeholder = opts.placeholder; |
| 362 | const showPlaceholder = userInput === '' && placeholder !== undefined; |
| 363 |
no test coverage detected