Skip to content

Commit c729bf0

Browse files
authored
fix(#44) complex values (#86)
2 parents 2be262b + ca08fb6 commit c729bf0

File tree

2 files changed

+30
-28
lines changed

2 files changed

+30
-28
lines changed

.changeset/olive-birds-brush.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@clack/prompts": patch
3+
---
4+
5+
Support complex value types for `select`, `multiselect` and `groupMultiselect`.

packages/prompts/src/index.ts

Lines changed: 25 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -169,24 +169,21 @@ export const confirm = (opts: ConfirmOptions) => {
169169
};
170170

171171
type Primitive = Readonly<string | boolean | number>;
172-
interface Option<Value extends Primitive> {
173-
value: Value;
174-
label?: string;
175-
hint?: string;
176-
}
177-
export interface SelectOptions<Options extends Option<Value>[], Value extends Primitive> {
172+
173+
type Option<Value> = Value extends Primitive
174+
? { value: Value; label?: string; hint?: string }
175+
: { value: Value; label: string; hint?: string };
176+
177+
export interface SelectOptions<Options extends Option<Value>[], Value> {
178178
message: string;
179179
options: Options;
180-
initialValue?: Options[number]['value'];
180+
initialValue?: Value;
181181
}
182182

183-
export const select = <Options extends Option<Value>[], Value extends Primitive>(
183+
export const select = <Options extends Option<Value>[], Value>(
184184
opts: SelectOptions<Options, Value>
185185
) => {
186-
const opt = (
187-
option: Options[number],
188-
state: 'inactive' | 'active' | 'selected' | 'cancelled'
189-
) => {
186+
const opt = (option: Option<Value>, state: 'inactive' | 'active' | 'selected' | 'cancelled') => {
190187
const label = option.label ?? String(option.value);
191188
if (state === 'active') {
192189
return `${color.green(S_RADIO_ACTIVE)} ${label} ${
@@ -221,14 +218,14 @@ export const select = <Options extends Option<Value>[], Value extends Primitive>
221218
}
222219
}
223220
},
224-
}).prompt() as Promise<Options[number]['value'] | symbol>;
221+
}).prompt() as Promise<Value | symbol>;
225222
};
226223

227224
export const selectKey = <Options extends Option<Value>[], Value extends string>(
228225
opts: SelectOptions<Options, Value>
229226
) => {
230227
const opt = (
231-
option: Options[number],
228+
option: Option<Value>,
232229
state: 'inactive' | 'active' | 'selected' | 'cancelled' = 'inactive'
233230
) => {
234231
const label = option.label ?? String(option.value);
@@ -269,21 +266,21 @@ export const selectKey = <Options extends Option<Value>[], Value extends string>
269266
}
270267
}
271268
},
272-
}).prompt() as Promise<Options[number]['value'] | symbol>;
269+
}).prompt() as Promise<Value | symbol>;
273270
};
274271

275-
export interface MultiSelectOptions<Options extends Option<Value>[], Value extends Primitive> {
272+
export interface MultiSelectOptions<Options extends Option<Value>[], Value> {
276273
message: string;
277274
options: Options;
278-
initialValues?: Options[number]['value'][];
275+
initialValues?: Value[];
279276
required?: boolean;
280-
cursorAt?: Options[number]['value'];
277+
cursorAt?: Value;
281278
}
282-
export const multiselect = <Options extends Option<Value>[], Value extends Primitive>(
279+
export const multiselect = <Options extends Option<Value>[], Value>(
283280
opts: MultiSelectOptions<Options, Value>
284281
) => {
285282
const opt = (
286-
option: Options[number],
283+
option: Option<Value>,
287284
state: 'inactive' | 'active' | 'selected' | 'active-selected' | 'submitted' | 'cancelled'
288285
) => {
289286
const label = option.label ?? String(option.value);
@@ -387,21 +384,21 @@ export const multiselect = <Options extends Option<Value>[], Value extends Primi
387384
}
388385
}
389386
},
390-
}).prompt() as Promise<Options[number]['value'][] | symbol>;
387+
}).prompt() as Promise<Value[] | symbol>;
391388
};
392389

393-
export interface GroupMultiSelectOptions<Options extends Option<Value>[], Value extends Primitive> {
390+
export interface GroupMultiSelectOptions<Options extends Option<Value>[], Value> {
394391
message: string;
395392
options: Record<string, Options>;
396-
initialValues?: Options[number]['value'][];
393+
initialValues?: Value[];
397394
required?: boolean;
398-
cursorAt?: Options[number]['value'];
395+
cursorAt?: Value;
399396
}
400-
export const groupMultiselect = <Options extends Option<Value>[], Value extends Primitive>(
397+
export const groupMultiselect = <Options extends Option<Value>[], Value>(
401398
opts: GroupMultiSelectOptions<Options, Value>
402399
) => {
403400
const opt = (
404-
option: Options[number],
401+
option: Option<Value>,
405402
state:
406403
| 'inactive'
407404
| 'active'
@@ -411,7 +408,7 @@ export const groupMultiselect = <Options extends Option<Value>[], Value extends
411408
| 'group-active-selected'
412409
| 'submitted'
413410
| 'cancelled',
414-
options: Options[number][] = [] as any
411+
options: Option<Value>[] = []
415412
) => {
416413
const label = option.label ?? String(option.value);
417414
const isItem = typeof (option as any).group === 'string';
@@ -531,7 +528,7 @@ export const groupMultiselect = <Options extends Option<Value>[], Value extends
531528
}
532529
}
533530
},
534-
}).prompt() as Promise<Options[number]['value'][] | symbol>;
531+
}).prompt() as Promise<Value[] | symbol>;
535532
};
536533

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

0 commit comments

Comments
 (0)