Skip to content

Commit

Permalink
fix(#44) complex values (#86)
Browse files Browse the repository at this point in the history
  • Loading branch information
natemoo-re committed Feb 26, 2023
2 parents 2be262b + ca08fb6 commit c729bf0
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 28 deletions.
5 changes: 5 additions & 0 deletions .changeset/olive-birds-brush.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@clack/prompts": patch
---

Support complex value types for `select`, `multiselect` and `groupMultiselect`.
53 changes: 25 additions & 28 deletions packages/prompts/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -169,24 +169,21 @@ export const confirm = (opts: ConfirmOptions) => {
};

type Primitive = Readonly<string | boolean | number>;
interface Option<Value extends Primitive> {
value: Value;
label?: string;
hint?: string;
}
export interface SelectOptions<Options extends Option<Value>[], Value extends Primitive> {

type Option<Value> = Value extends Primitive
? { value: Value; label?: string; hint?: string }
: { value: Value; label: string; hint?: string };

export interface SelectOptions<Options extends Option<Value>[], Value> {
message: string;
options: Options;
initialValue?: Options[number]['value'];
initialValue?: Value;
}

export const select = <Options extends Option<Value>[], Value extends Primitive>(
export const select = <Options extends Option<Value>[], Value>(
opts: SelectOptions<Options, Value>
) => {
const opt = (
option: Options[number],
state: 'inactive' | 'active' | 'selected' | 'cancelled'
) => {
const opt = (option: Option<Value>, state: 'inactive' | 'active' | 'selected' | 'cancelled') => {
const label = option.label ?? String(option.value);
if (state === 'active') {
return `${color.green(S_RADIO_ACTIVE)} ${label} ${
Expand Down Expand Up @@ -221,14 +218,14 @@ export const select = <Options extends Option<Value>[], Value extends Primitive>
}
}
},
}).prompt() as Promise<Options[number]['value'] | symbol>;
}).prompt() as Promise<Value | symbol>;
};

export const selectKey = <Options extends Option<Value>[], Value extends string>(
opts: SelectOptions<Options, Value>
) => {
const opt = (
option: Options[number],
option: Option<Value>,
state: 'inactive' | 'active' | 'selected' | 'cancelled' = 'inactive'
) => {
const label = option.label ?? String(option.value);
Expand Down Expand Up @@ -269,21 +266,21 @@ export const selectKey = <Options extends Option<Value>[], Value extends string>
}
}
},
}).prompt() as Promise<Options[number]['value'] | symbol>;
}).prompt() as Promise<Value | symbol>;
};

export interface MultiSelectOptions<Options extends Option<Value>[], Value extends Primitive> {
export interface MultiSelectOptions<Options extends Option<Value>[], Value> {
message: string;
options: Options;
initialValues?: Options[number]['value'][];
initialValues?: Value[];
required?: boolean;
cursorAt?: Options[number]['value'];
cursorAt?: Value;
}
export const multiselect = <Options extends Option<Value>[], Value extends Primitive>(
export const multiselect = <Options extends Option<Value>[], Value>(
opts: MultiSelectOptions<Options, Value>
) => {
const opt = (
option: Options[number],
option: Option<Value>,
state: 'inactive' | 'active' | 'selected' | 'active-selected' | 'submitted' | 'cancelled'
) => {
const label = option.label ?? String(option.value);
Expand Down Expand Up @@ -387,21 +384,21 @@ export const multiselect = <Options extends Option<Value>[], Value extends Primi
}
}
},
}).prompt() as Promise<Options[number]['value'][] | symbol>;
}).prompt() as Promise<Value[] | symbol>;
};

export interface GroupMultiSelectOptions<Options extends Option<Value>[], Value extends Primitive> {
export interface GroupMultiSelectOptions<Options extends Option<Value>[], Value> {
message: string;
options: Record<string, Options>;
initialValues?: Options[number]['value'][];
initialValues?: Value[];
required?: boolean;
cursorAt?: Options[number]['value'];
cursorAt?: Value;
}
export const groupMultiselect = <Options extends Option<Value>[], Value extends Primitive>(
export const groupMultiselect = <Options extends Option<Value>[], Value>(
opts: GroupMultiSelectOptions<Options, Value>
) => {
const opt = (
option: Options[number],
option: Option<Value>,
state:
| 'inactive'
| 'active'
Expand All @@ -411,7 +408,7 @@ export const groupMultiselect = <Options extends Option<Value>[], Value extends
| 'group-active-selected'
| 'submitted'
| 'cancelled',
options: Options[number][] = [] as any
options: Option<Value>[] = []
) => {
const label = option.label ?? String(option.value);
const isItem = typeof (option as any).group === 'string';
Expand Down Expand Up @@ -531,7 +528,7 @@ export const groupMultiselect = <Options extends Option<Value>[], Value extends
}
}
},
}).prompt() as Promise<Options[number]['value'][] | symbol>;
}).prompt() as Promise<Value[] | symbol>;
};

const strip = (str: string) => str.replace(ansiRegex(), '');
Expand Down

0 comments on commit c729bf0

Please sign in to comment.