[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: update demo

Simon He (Nov 14, 2024, 3:50 PM +0800) 06e90242 ecde766e

+43 -11
+5
examples/basic/index.ts
··· 11 11 12 12 const project = await p.group( 13 13 { 14 + search: () => 15 + p.search({ 16 + message: "What's your gender?", 17 + options: [{ value: 'male' }, { value: 'female' }], 18 + }), 14 19 path: () => 15 20 p.text({ 16 21 message: 'Where should we create your project?',
+1 -1
packages/core/src/index.ts
··· 4 4 export { default as PasswordPrompt } from './prompts/password'; 5 5 export { default as Prompt, isCancel } from './prompts/prompt'; 6 6 export type { State } from './prompts/prompt'; 7 + export { default as SearchPrompt } from './prompts/search'; 7 8 export { default as SelectPrompt } from './prompts/select'; 8 9 export { default as SelectKeyPrompt } from './prompts/select-key'; 9 10 export { default as TextPrompt } from './prompts/text'; 10 - export { default as SearchPrompt } from './prompts/search'; 11 11 export { block } from './utils';
+1 -1
packages/core/src/prompts/search.ts
··· 1 - import Prompt, { PromptOptions } from './prompt'; 2 1 import fuzzy from 'fuzzy'; 2 + import Prompt, { PromptOptions } from './prompt'; 3 3 interface SearchOptions<T extends { value: any; label?: string }> 4 4 extends PromptOptions<SearchPrompt<T>> { 5 5 options: T[];
+36 -9
packages/prompts/src/index.ts
··· 5 5 isCancel, 6 6 MultiSelectPrompt, 7 7 PasswordPrompt, 8 + SearchPrompt, 8 9 SelectKeyPrompt, 9 10 SelectPrompt, 10 11 State, 11 - TextPrompt, 12 - SearchPrompt, 13 - } from '@clack/core'; 12 + TextPrompt 13 + } from '@simon_he/clack-core'; 14 14 import isUnicodeSupported from 'is-unicode-supported'; 15 15 import color from 'picocolors'; 16 16 import { cursor, erase } from 'sisteransi'; 17 17 18 - export { isCancel } from '@clack/core'; 18 + export { isCancel } from '@simon_he/clack-core'; 19 19 20 20 const unicode = isUnicodeSupported(); 21 21 const s = (c: string, fallback: string) => (unicode ? c : fallback); ··· 321 321 export const search = <Value, MaxItems extends number>(opts: SearchOptions<Value, MaxItems>) => { 322 322 const opt = ( 323 323 option: Option<Value>, 324 - state: 'inactive' | 'active' | 'selected' | 'active-selected' | 'submitted' | 'cancelled' 324 + state: 325 + | 'inactive' 326 + | 'active' 327 + | 'group-active' 328 + | 'group-inactive' 329 + | 'selected' 330 + | 'active-selected' 331 + | 'submitted' 332 + | 'cancelled' 325 333 ) => { 326 334 const label = option.label ?? String(option.value); 327 - if (state === 'active') { 335 + if (state === 'group-active') { 328 336 return `${color.cyan(S_CHECKBOX_ACTIVE)} ${label} ${ 329 337 option.hint ? color.dim(`(${option.hint})`) : '' 330 338 }`; ··· 336 344 return `${color.green(S_CHECKBOX_SELECTED)} ${label} ${ 337 345 option.hint ? color.dim(`(${option.hint})`) : '' 338 346 }`; 347 + } else if (state === 'active') { 348 + return `${color.green(S_RADIO_ACTIVE)} ${label} ${ 349 + option.hint ? color.dim(`(${option.hint})`) : '' 350 + }`; 351 + } else if (state === 'group-inactive') { 352 + return `${color.dim(S_CHECKBOX_INACTIVE)} ${color.dim(label)}`; 339 353 } else if (state === 'submitted') { 340 354 return `${color.dim(label)}`; 341 355 } 342 - return `${color.dim(S_CHECKBOX_INACTIVE)} ${color.dim(label)}`; 356 + return `${color.dim(S_RADIO_INACTIVE)} ${color.dim(label)}`; 343 357 }; 344 358 345 359 return new SearchPrompt({ ··· 368 382 return `${title}${color.gray(S_BAR)} ${opt( 369 383 { 370 384 label: 371 - this.selected.map((item) => item.label).join(', ') || 372 - this.options[this.selectCursor].label, 385 + this.selected.map((item) => item.label || item.value).join(', ') || 386 + this.options[this.selectCursor].label || 387 + this.options[this.selectCursor].value, 373 388 } as Option<Value>, 374 389 'selected' 375 390 )}`; ··· 379 394 )}`; 380 395 default: { 381 396 let getStatus = (option: Option<Value>, i: number) => { 397 + if (this.maxItems > 1) { 398 + if (i === this.selectCursor) { 399 + return this.selected.some((item) => item.value === option.value) 400 + ? 'active-selected' 401 + : 'group-active'; 402 + } 403 + return this.selected.some((item) => item.value === option.value) 404 + ? 'selected' 405 + : i === this.selectCursor 406 + ? 'group-active' 407 + : 'group-inactive'; 408 + } 382 409 if (i === this.selectCursor) { 383 410 return this.selected.some((item) => item.value === option.value) 384 411 ? 'active-selected'